summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Francis <dennis.francis@collabora.com>2021-05-03 16:17:05 +0530
committerAndras Timar <andras.timar@collabora.com>2021-05-12 10:51:49 +0200
commit31ab160dddf8d551dad8730fd3e1776986a64333 (patch)
tree6c061f244832f5fbd7f6e2c0a12347eb7ef0cb25
parent8d1415a70c40d63d4b7873e608a386744276c2e0 (diff)
autocomplete from superblock of str/edittext
Change-Id: Ibf73284971652c5cbd9874d81ded4a1f0cbb4e94 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115131 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--sc/inc/column.hxx1
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/table.hxx2
-rw-r--r--sc/source/core/data/column3.cxx108
-rw-r--r--sc/source/core/data/documen3.cxx24
-rw-r--r--sc/source/core/data/table3.cxx5
-rw-r--r--sc/source/ui/app/inputhdl.cxx4
7 files changed, 142 insertions, 4 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 64485ccd5f2c..bbf9bce9be73 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -537,6 +537,7 @@ public:
sc::ColumnBlockConstPosition& rBlockPos, SCROW nStartRow, SCROW nEndRow,
ScFilterEntries& rFilterEntries );
+ bool GetStringBlockEntries(SCROW nCursorRow, std::set<ScTypedStrData>& rStrings) const;
bool GetDataEntries( SCROW nRow, std::set<ScTypedStrData>& rStrings, bool bLimit ) const;
void UpdateInsertTabAbs(SCTAB nNewPos);
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 4d385e97d0c9..aefdd253467c 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -2060,6 +2060,8 @@ public:
SCTAB nTab, bool bCaseSens,
ScFilterEntries& rFilterEntries );
+ void GetStringBlockEntries( SCCOL nCursorCol, SCROW nCursorRow, SCTAB nTab,
+ std::vector<ScTypedStrData>& rStrings) const;
void GetDataEntries( SCCOL nCol, SCROW nRow, SCTAB nTab,
std::vector<ScTypedStrData>& rStrings, bool bLimit = false );
void GetFormulaEntries( ScTypedCaseStrSet& rStrings );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 8fa962081a05..437ee058f640 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -948,6 +948,8 @@ public:
void GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, ScFilterEntries& rFilterEntries );
void GetFilteredFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, ScFilterEntries& rFilterEntries );
[[nodiscard]]
+ bool GetStringBlockEntries(SCCOL nCursorCol, SCROW nCursorRow, std::set<ScTypedStrData>& rStrings) const;
+ [[nodiscard]]
bool GetDataEntries(SCCOL nCol, SCROW nRow, std::set<ScTypedStrData>& rStrings, bool bLimit);
bool HasColHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const;
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 90a0dcec43aa..4d21dd698beb 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2525,6 +2525,7 @@ namespace {
*/
class StrCellIterator
{
+protected:
typedef std::pair<sc::CellStoreType::const_iterator,size_t> PosType;
PosType maPos;
sc::CellStoreType::const_iterator const miBeg;
@@ -2641,6 +2642,113 @@ public:
}
};
+/**
+ * Iterate over only over the super-block of string and edit-text blocks.
+ */
+class StrCellBlockIterator: public StrCellIterator
+{
+public:
+ StrCellBlockIterator(const sc::CellStoreType& rCells, SCROW nStart, const ScDocument* pDoc) :
+ StrCellIterator(rCells, nStart, pDoc)
+ {
+ }
+
+ bool prev()
+ {
+ // Don't go up anymore as we're on non-string block.
+ if (!has())
+ return false;
+
+ // We are in a string block.
+ if (maPos.second > 0)
+ {
+ // Move back one cell in the same block.
+ --maPos.second;
+ }
+ else
+ {
+ if (maPos.first == miBeg)
+ return false;
+
+ // Move to the last cell of the previous block.
+ --maPos.first;
+ maPos.second = maPos.first->size - 1;
+ // Reached non-string block.
+ if (!has())
+ return false;
+ }
+ return true;
+ }
+
+ bool next()
+ {
+ // Don't go down anymore as we're on non-string block.
+ if (!has())
+ return false;
+
+ // We are in a string block.
+ ++maPos.second;
+ if (maPos.second >= maPos.first->size)
+ {
+ // Move to the next block.
+ ++maPos.first;
+ if (maPos.first == miEnd)
+ return false;
+
+ maPos.second = 0;
+ // Reached non-string block.
+ if (!has())
+ return false;
+ }
+ return true;
+ }
+
+};
+
+}
+
+// Get a set of strings from super-block of string and edit-text blocks.
+// This used for computing auto-complete entries in input handler.
+bool ScColumn::GetStringBlockEntries(SCROW nCursorRow, std::set<ScTypedStrData>& rStrings) const
+{
+ // Start at the specified row position, and collect all string values
+ // going upward and downward directions in parallel. The cursor position
+ // cell must be skipped.
+
+ StrCellBlockIterator aItrUp(maCells, nCursorRow-1, GetDoc());
+ StrCellBlockIterator aItrDown(maCells, nCursorRow+1, GetDoc());
+
+ bool bMoveUp = aItrUp.valid() && aItrUp.has();
+ bool bMoveDown = aItrDown.valid() && aItrDown.has();
+ bool bFound = false;
+ OUString aStr;
+
+ while (bMoveUp || bMoveDown)
+ {
+ if (bMoveUp)
+ {
+ aStr = aItrUp.get();
+ if (!aStr.isEmpty())
+ {
+ if (rStrings.insert(ScTypedStrData(aStr)).second)
+ bFound = true;
+ }
+ bMoveUp = aItrUp.prev();
+ }
+
+ if (bMoveDown)
+ {
+ aStr = aItrDown.get();
+ if (!aStr.isEmpty())
+ {
+ if (rStrings.insert(ScTypedStrData(aStr)).second)
+ bFound = true;
+ }
+ bMoveDown = aItrDown.next();
+ }
+ }
+
+ return bFound;
}
// GetDataEntries - Strings from continuous Section around nRow
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 783bac66f2fd..3a588b81fab7 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -1578,6 +1578,27 @@ void ScDocument::GetFilterEntriesArea(
}
/**
+ * Get entries for computing auto-complete entries in input handler (no numbers/formulas)
+ */
+void ScDocument::GetStringBlockEntries(
+ SCCOL nCursorCol, SCROW nCursorRow, SCTAB nTab,
+ std::vector<ScTypedStrData>& rStrings) const
+{
+ if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()))
+ return;
+
+ if (!maTabs[nTab])
+ return;
+
+ std::set<ScTypedStrData> aStrings;
+ if (maTabs[nTab]->GetStringBlockEntries(nCursorCol, nCursorRow, aStrings))
+ {
+ rStrings.insert(rStrings.end(), aStrings.begin(), aStrings.end());
+ sortAndRemoveDuplicates(rStrings, true/*bCaseSens*/);
+ }
+}
+
+/**
* Entries for selection list listbox (no numbers/formulas)
*/
void ScDocument::GetDataEntries(
@@ -1587,8 +1608,7 @@ void ScDocument::GetDataEntries(
if( !bLimit )
{
/* Try to generate the list from list validation. This part is skipped,
- if bLimit==true, because in that case this function is called to get
- cell values for auto completion on input. */
+ if bLimit==true. */
sal_uInt32 nValidation = GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA )->GetValue();
if( nValidation )
{
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index c27c73fb88e1..926429e90fc1 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -3477,6 +3477,11 @@ void ScTable::GetFilteredFilterEntries(
}
}
+bool ScTable::GetStringBlockEntries(SCCOL nCursorCol, SCROW nCursorRow, std::set<ScTypedStrData>& rStrings) const
+{
+ return aCol[nCursorCol].GetStringBlockEntries(nCursorRow, rStrings);
+}
+
bool ScTable::GetDataEntries(SCCOL nCol, SCROW nRow, std::set<ScTypedStrData>& rStrings, bool bLimit)
{
return aCol[nCol].GetDataEntries( nRow, rStrings, bLimit );
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index e7c68c0ad302..1df722b95c9f 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -1913,8 +1913,8 @@ void ScInputHandler::GetColData()
pColumnData.reset( new ScTypedCaseStrSet );
std::vector<ScTypedStrData> aEntries;
- rDoc.GetDataEntries(
- aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aEntries, true);
+ rDoc.GetStringBlockEntries(
+ aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aEntries);
if (!aEntries.empty())
pColumnData->insert(aEntries.begin(), aEntries.end());