From 1e033fe1f270e7a76cb8821af9ceb1c096403442 Mon Sep 17 00:00:00 2001 From: Dennis Francis Date: Mon, 11 Oct 2021 16:27:57 +0530 Subject: calc: revert changes in autoinput This is a combination of 4 commits. Revert "autocomplete: allow cycling through possible matches" This reverts commit 299227ad81d4a44556fda8cca7b8b79219ba7e6c. Revert "tdf#142214: autoinput: remove search/entry count limits" This reverts commit ebff4e5181b102e5184277f57fda32fcce60431f. Revert "tdf#142214: unit-tests for new behaviour of auto-complete" This reverts commit 06c360d4d27ab0dadfdcd5f9d4f0c87288d3cb75. Revert "tdf#142214: show autocompletion only if there is..." This reverts commit f8039c6d645acb015a6c4e45000bbfd1311bfea3. Change-Id: Ief45d79d3a0ffac79d57e590c984d09aa9c38fc5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123381 Tested-by: Jenkins Reviewed-by: Ilmari Lauhakangas Reviewed-by: Jan Holesovsky --- sc/inc/column.hxx | 2 +- sc/inc/document.hxx | 2 +- sc/inc/table.hxx | 2 +- sc/qa/unit/tiledrendering/tiledrendering.cxx | 66 ---------------------------- sc/source/core/data/column3.cxx | 54 ++++++++++++++++------- sc/source/core/data/documen3.cxx | 8 ++-- sc/source/core/data/table3.cxx | 4 +- sc/source/ui/app/inputhdl.cxx | 44 +++++++------------ sc/source/ui/view/gridwin.cxx | 2 +- 9 files changed, 64 insertions(+), 120 deletions(-) (limited to 'sc') diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 72527a76cd9e..07b8f061bd88 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -538,7 +538,7 @@ public: sc::ColumnBlockConstPosition& rBlockPos, SCROW nStartRow, SCROW nEndRow, ScFilterEntries& rFilterEntries, bool bFiltering ); - bool GetDataEntries( SCROW nRow, std::set& rStrings) const; + bool GetDataEntries( SCROW nRow, std::set& rStrings, bool bLimit ) const; void UpdateInsertTabAbs(SCTAB nNewPos); bool TestTabRefAbs(SCTAB nTable) const; diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 7c798cf08674..61770da26d71 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -2095,7 +2095,7 @@ public: ScFilterEntries& rFilterEntries ); void GetDataEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, - std::vector& rStrings, bool bValidation = false ); + std::vector& rStrings, bool bLimit = false ); void GetFormulaEntries( ScTypedCaseStrSet& rStrings ); bool HasAutoFilter( SCCOL nCol, SCROW nRow, SCTAB nTab ); diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index c3ba8d112e9d..a4e41a7bc318 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -963,7 +963,7 @@ public: void GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, ScFilterEntries& rFilterEntries, bool bFiltering = false); void GetFilteredFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, ScFilterEntries& rFilterEntries, bool bFiltering ); [[nodiscard]] - bool GetDataEntries(SCCOL nCol, SCROW nRow, std::set& rStrings); + bool GetDataEntries(SCCOL nCol, SCROW nRow, std::set& rStrings, bool bLimit); bool HasColHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const; bool HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const; diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx index 8a722c2b8a29..ed35b29e7a63 100644 --- a/sc/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx @@ -47,7 +47,6 @@ #include #include #include -#include using namespace css; @@ -114,7 +113,6 @@ public: void testSpellOnlineRenderParameter(); void testPasteIntoWrapTextCell(); void testSortAscendingDescending(); - void testAutoInputExactMatch(); void testMoveShapeHandle(); void testEditCursorBounds(); void testTextSelectionBounds(); @@ -166,7 +164,6 @@ public: CPPUNIT_TEST(testSpellOnlineRenderParameter); CPPUNIT_TEST(testPasteIntoWrapTextCell); CPPUNIT_TEST(testSortAscendingDescending); - CPPUNIT_TEST(testAutoInputExactMatch); CPPUNIT_TEST(testMoveShapeHandle); CPPUNIT_TEST(testEditCursorBounds); CPPUNIT_TEST(testTextSelectionBounds); @@ -2634,69 +2631,6 @@ void ScTiledRenderingTest::testSortAscendingDescending() CPPUNIT_ASSERT_EQUAL(OString("rows"), aView.m_sInvalidateSheetGeometry); } -void lcl_typeCharsInCell(const std::string& aStr, SCCOL nCol, SCROW nRow, ScTabViewShell* pView, ScModelObj* pModelObj) -{ - pView->SetCursor(nCol, nRow); - for (const char& cChar : aStr) - { - pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, cChar, 0); - pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, cChar, 0); - Scheduler::ProcessEventsToIdle(); - } - pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::RETURN); - pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN); - Scheduler::ProcessEventsToIdle(); -} - -void ScTiledRenderingTest::testAutoInputExactMatch() -{ - comphelper::LibreOfficeKit::setActive(); - - ScModelObj* pModelObj = createDoc("empty.ods"); - CPPUNIT_ASSERT(pModelObj); - ScTabViewShell* pView = dynamic_cast(SfxViewShell::Current()); - CPPUNIT_ASSERT(pView); - ScDocument* pDoc = pModelObj->GetDocument(); - - pDoc->SetString(ScAddress(0, 1, 0), "Simple"); // A2 - pDoc->SetString(ScAddress(0, 2, 0), "Simple"); // A3 - pDoc->SetString(ScAddress(0, 3, 0), "Sing"); // A4 - ScFieldEditEngine& rEE = pDoc->GetEditEngine(); - rEE.SetText("Case"); - pDoc->SetEditText(ScAddress(0, 4, 0), rEE.CreateTextObject()); // A5 - pDoc->SetString(ScAddress(0, 5, 0), "Time"); // A6 - pDoc->SetString(ScAddress(0, 6, 0), "Castle"); // A7 - - ScAddress aA8(0, 7, 0); - lcl_typeCharsInCell("S", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "S" in A8 - // Should not autocomplete as there are multiple matches starting with "S". - CPPUNIT_ASSERT_EQUAL_MESSAGE("1: A8 should have just S (should not autocomplete)", OUString("S"), pDoc->GetString(aA8)); - - lcl_typeCharsInCell("Si", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "Si" in A8 - // Should not autocomplete as there are multiple matches starting with "Si". - CPPUNIT_ASSERT_EQUAL_MESSAGE("2: A8 should not autocomplete", OUString("Si"), pDoc->GetString(aA8)); - - lcl_typeCharsInCell("Sim", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "Sim" in A8 - // Should autocomplete to "Simple" which is the only match. - CPPUNIT_ASSERT_EQUAL_MESSAGE("3: A8 should autocomplete", OUString("Simple"), pDoc->GetString(aA8)); - - lcl_typeCharsInCell("Sin", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "Sin" in A8 - // Should autocomplete to "Sing" which is the only match. - CPPUNIT_ASSERT_EQUAL_MESSAGE("4: A8 should autocomplete", OUString("Sing"), pDoc->GetString(aA8)); - - lcl_typeCharsInCell("Cas", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "Cas" in A8 - // Should not autocomplete as there are multiple matches starting with "Cas". - CPPUNIT_ASSERT_EQUAL_MESSAGE("5: A8 should not autocomplete", OUString("Cas"), pDoc->GetString(aA8)); - - lcl_typeCharsInCell("Cast", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "Cast" in A8 - // Should autocomplete to "Castle" which is the only match. - CPPUNIT_ASSERT_EQUAL_MESSAGE("6: A8 should autocomplete", OUString("Castle"), pDoc->GetString(aA8)); - - lcl_typeCharsInCell("T", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "T" in A8 - // Should autocomplete to "Time" which is the only match. - CPPUNIT_ASSERT_EQUAL_MESSAGE("7: A8 should autocomplete", OUString("Time"), pDoc->GetString(aA8)); -} - void ScTiledRenderingTest::testEditCursorBounds() { comphelper::LibreOfficeKit::setActive(); diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 72f5d3448fd6..3f30bbe326ab 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -2739,8 +2739,14 @@ public: } // GetDataEntries - Strings from continuous Section around nRow + +// DATENT_MAX - max. number of entries in list for auto entry +// DATENT_SEARCH - max. number of cells that get transparent - new: only count Strings +#define DATENT_MAX 200 +#define DATENT_SEARCH 2000 + bool ScColumn::GetDataEntries( - SCROW nStartRow, std::set& rStrings) const + SCROW nStartRow, std::set& rStrings, bool bLimit ) const { // Start at the specified row position, and collect all string values // going upward and downward directions in parallel. The start position @@ -2762,30 +2768,44 @@ bool ScColumn::GetDataEntries( bMoveDown = aItrDown.next(); // Find the next string cell position. bool bFound = false; - while (bMoveUp) + size_t nCellsSearched = 0; + while (bMoveUp || bMoveDown) { - // Get the current string and move up. - OUString aStr = aItrUp.get(); - if (!aStr.isEmpty()) + if (bMoveUp) { - if (rStrings.insert(ScTypedStrData(aStr)).second) + // Get the current string and move up. + OUString aStr = aItrUp.get(); + if (!aStr.isEmpty()) + { + bool bInserted = rStrings.insert(ScTypedStrData(aStr)).second; + if (bInserted && bLimit && rStrings.size() >= DATENT_MAX) + return true; // Maximum reached bFound = true; - } + } - bMoveUp = aItrUp.prev(); - } + if (bLimit && ++nCellsSearched >= DATENT_SEARCH) + return bFound; // max search cell count reached. - while (bMoveDown) - { - // Get the current string and move down. - OUString aStr = aItrDown.get(); - if (!aStr.isEmpty()) + bMoveUp = aItrUp.prev(); + } + + if (bMoveDown) { - if (rStrings.insert(ScTypedStrData(aStr)).second) + // Get the current string and move down. + OUString aStr = aItrDown.get(); + if (!aStr.isEmpty()) + { + bool bInserted = rStrings.insert(ScTypedStrData(aStr)).second; + if (bInserted && bLimit && rStrings.size() >= DATENT_MAX) + return true; // Maximum reached bFound = true; - } + } + + if (bLimit && ++nCellsSearched >= DATENT_SEARCH) + return bFound; // max search cell count reached. - bMoveDown = aItrDown.next(); + bMoveDown = aItrDown.next(); + } } return bFound; diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 6ab518566663..92c721fa48ca 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -1624,12 +1624,12 @@ void ScDocument::GetFilterEntriesArea( */ void ScDocument::GetDataEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, - std::vector& rStrings, bool bValidation ) + std::vector& rStrings, bool bLimit ) { - if( bValidation ) + if( !bLimit ) { /* Try to generate the list from list validation. This part is skipped, - if bValidation==false, because in that case this function is called to get + if bLimit==true, because in that case this function is called to get cell values for auto completion on input. */ sal_uInt32 nValidation = GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA )->GetValue(); if( nValidation ) @@ -1652,7 +1652,7 @@ void ScDocument::GetDataEntries( return; std::set aStrings; - if (maTabs[nTab]->GetDataEntries(nCol, nRow, aStrings)) + if (maTabs[nTab]->GetDataEntries(nCol, nRow, aStrings, bLimit)) { rStrings.insert(rStrings.end(), aStrings.begin(), aStrings.end()); sortAndRemoveDuplicates(rStrings, true/*bCaseSens*/); diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 14a9c7f35884..d315de4768cb 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -3802,9 +3802,9 @@ void ScTable::GetFilteredFilterEntries( } } -bool ScTable::GetDataEntries(SCCOL nCol, SCROW nRow, std::set& rStrings) +bool ScTable::GetDataEntries(SCCOL nCol, SCROW nRow, std::set& rStrings, bool bLimit) { - return aCol[nCol].GetDataEntries( nRow, rStrings); + return aCol[nCol].GetDataEntries( nRow, rStrings, bLimit ); } sal_uLong ScTable::GetCellCount() const diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index a8bf4a39e8f9..f3f672d23d42 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -163,13 +163,10 @@ OUString getExactMatch(const ScTypedCaseStrSet& rDataSet, const OUString& rStrin ScTypedCaseStrSet::const_iterator findTextAll( const ScTypedCaseStrSet& rDataSet, ScTypedCaseStrSet::const_iterator const & itPos, - const OUString& rStart, ::std::vector< OUString > &rResultVec, bool bBack, size_t nMax = 0) + const OUString& rStart, ::std::vector< OUString > &rResultVec, bool bBack) { rResultVec.clear(); // clear contents - if (!rDataSet.size()) - return rDataSet.end(); - size_t nCount = 0; ScTypedCaseStrSet::const_iterator retit; if ( bBack ) // Backwards @@ -220,8 +217,6 @@ ScTypedCaseStrSet::const_iterator findTextAll( std::advance(retit, nPos); } ++nCount; - if (nMax > 0 && nCount >= nMax) - break; } } else // Forwards @@ -254,8 +249,6 @@ ScTypedCaseStrSet::const_iterator findTextAll( if ( nCount == 0 ) retit = it; // remember first match iterator ++nCount; - if (nMax > 0 && nCount >= nMax) - break; } } @@ -1941,7 +1934,7 @@ void ScInputHandler::GetColData() std::vector aEntries; rDoc.GetDataEntries( - aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aEntries); + aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aEntries, true); if (!aEntries.empty()) pColumnData->insert(aEntries.begin(), aEntries.end()); @@ -1970,26 +1963,12 @@ void ScInputHandler::UseColData() // When typing if (aText.isEmpty()) return; - std::vector< OUString > aResultVec; OUString aNew; miAutoPosColumn = pColumnData->end(); - miAutoPosColumn = findTextAll(*pColumnData, miAutoPosColumn, aText, aResultVec, false, 2); - bool bShowCompletion = (aResultVec.size() == 1); - bUseTab = (aResultVec.size() == 2); - if (bUseTab) - { - // Allow cycling through possible matches using shortcut. - // Make miAutoPosColumn invalid so that Ctrl+TAB provides the first matching one. - miAutoPosColumn = pColumnData->end(); - aAutoSearch = aText; - return; - } - - if (!bShowCompletion) + miAutoPosColumn = findText(*pColumnData, miAutoPosColumn, aText, aNew, false); + if (miAutoPosColumn == pColumnData->end()) return; - assert(miAutoPosColumn != pColumnData->end()); - aNew = aResultVec[0]; // Strings can contain line endings (e.g. due to dBase import), // which would result in multiple paragraphs here, which is not desirable. //! Then GetExactMatch doesn't work either @@ -2019,6 +1998,17 @@ void ScInputHandler::UseColData() // When typing } aAutoSearch = aText; // To keep searching - nAutoPos is set + + if (aText.getLength() == aNew.getLength()) + { + // If the inserted text is found, consume TAB only if there's more coming + OUString aDummy; + ScTypedCaseStrSet::const_iterator itNextPos = + findText(*pColumnData, miAutoPosColumn, aText, aDummy, false); + bUseTab = itNextPos != pColumnData->end(); + } + else + bUseTab = true; } void ScInputHandler::NextAutoEntry( bool bBack ) @@ -2026,7 +2016,7 @@ void ScInputHandler::NextAutoEntry( bool bBack ) EditView* pActiveView = pTopView ? pTopView : pTableView; if ( pActiveView && pColumnData ) { - if (!aAutoSearch.isEmpty()) + if (miAutoPosColumn != pColumnData->end() && !aAutoSearch.isEmpty()) { // Is the selection still valid (could be changed via the mouse)? ESelection aSel = pActiveView->GetSelection(); @@ -3658,7 +3648,7 @@ bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, bool bStartEdit /* = false NextFormulaEntry( bShift ); bUsed = true; } - else if (pColumnData && bUseTab) + else if (pColumnData && bUseTab && miAutoPosColumn != pColumnData->end()) { // Iterate through AutoInput entries NextAutoEntry( bShift ); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 7e08369f8c43..c5382ef2747b 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -1224,7 +1224,7 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) bool bEmpty = false; std::vector aStrings; // case sensitive // Fill List - rDoc.GetDataEntries(nCol, nRow, nTab, aStrings, true /* bValidation */); + rDoc.GetDataEntries(nCol, nRow, nTab, aStrings); if (aStrings.empty()) bEmpty = true; -- cgit