diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2016-11-04 20:19:12 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2016-11-07 13:37:41 +0000 |
commit | ba68e6dd7ad99ef2a2720f327813d13550b98966 (patch) | |
tree | 7d1cf2f42b2d1232a6ad856c54b5f8efcda22a11 /sc | |
parent | 0a3eaf9f67f5e66ca0ae0c38cc4d85e07795b9f4 (diff) |
tdf#92160 - sc: limit search results to 1000 entries.
Very large replace results give huge space consumption in the
display widget, and are of dubious usefulness.
Change-Id: Ib8ad01a673ea52976befaf958f8f695aca2190ae
Reviewed-on: https://gerrit.libreoffice.org/30574
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/ui/dialogs/searchresults.cxx | 83 | ||||
-rw-r--r-- | sc/source/ui/inc/searchresults.hxx | 1 | ||||
-rw-r--r-- | sc/uiconfig/scalc/ui/searchresults.ui | 7 |
3 files changed, 79 insertions, 12 deletions
diff --git a/sc/source/ui/dialogs/searchresults.cxx b/sc/source/ui/dialogs/searchresults.cxx index 3cd86fac9b8b..c61584354469 100644 --- a/sc/source/ui/dialogs/searchresults.cxx +++ b/sc/source/ui/dialogs/searchresults.cxx @@ -26,6 +26,8 @@ SearchResultsDlg::SearchResultsDlg( SfxBindings* _pBindings, vcl::Window* pParen ModelessDialog(pParent, "SearchResultsDialog", "modules/scalc/ui/searchresults.ui"), mpBindings(_pBindings), mpDoc(nullptr) { + get(mpLabel, "skipped"); + SvSimpleTableContainer *pContainer = get<SvSimpleTableContainer>("results"); Size aControlSize(150, 120); aControlSize = pContainer->LogicToPixel(aControlSize, MapUnit::MapAppFont); @@ -47,18 +49,76 @@ SearchResultsDlg::~SearchResultsDlg() void SearchResultsDlg::dispose() { mpList.disposeAndClear(); + mpLabel.disposeAndClear(); ModelessDialog::dispose(); } +namespace +{ + class ListWrapper { + size_t mnCount; + const size_t mnMaximum; + OUStringBuffer maName; + VclPtr<FixedText> mpLabel; + VclPtr<SvSimpleTable> mpList; + public: + ListWrapper(const VclPtr<SvSimpleTable> &pList, + const VclPtr<FixedText> &pLabel) : + mnCount(0), + mnMaximum(1000), + mpLabel(pLabel), + mpList(pList) + { + mpList->Clear(); + mpList->SetUpdateMode(false); + } + void Insert(const OUString &aTabName, + const ScAddress &rPos, + formula::FormulaGrammar::AddressConvention eConvention, + const OUString &aText) + { + if (mnCount++ < mnMaximum) + { + maName.append(aTabName); + maName.append("\t"); + maName.append(rPos.Format(ScRefFlags::ADDR_ABS, + nullptr, eConvention)); + maName.append("\t"); + maName.append(aText); + mpList->InsertEntry(maName.makeStringAndClear()); + } + } + void Update() + { + if (mnCount > mnMaximum) + { + if (mpLabel) + { + size_t nSkipped = mnCount - mnMaximum; + OUString aSkipped(mpLabel->GetText()); + mpList->InsertEntry( + aSkipped.replaceFirst("$1", OUString::number(nSkipped))); + } + } + mpList->SetUpdateMode(true); + } + }; +} + void SearchResultsDlg::FillResults( ScDocument* pDoc, const ScRangeList &rMatchedRanges, bool bCellNotes ) { - mpList->Clear(); - mpList->SetUpdateMode(false); + ListWrapper aList(mpList, mpLabel); std::vector<OUString> aTabNames = pDoc->GetAllTableNames(); SCTAB nTabCount = aTabNames.size(); + + // tdf#92160 - too many results blow the widget's mind + size_t nMatchMax = rMatchedRanges.size(); + if (nMatchMax > 1000) + nMatchMax = 1000; + if (bCellNotes) { - for (size_t i = 0, n = rMatchedRanges.size(); i < n; ++i) + for (size_t i = 0, n = nMatchMax; i < n; ++i) { /* TODO: a CellNotes iterator would come handy and migt speed * things up a little, though we only loop through the @@ -77,10 +137,9 @@ void SearchResultsDlg::FillResults( ScDocument* pDoc, const ScRangeList &rMatche { const ScPostIt* pNote = pDoc->GetNote( aPos); if (pNote) - { - OUString aPosStr = aPos.Format(ScRefFlags::ADDR_ABS, nullptr, pDoc->GetAddressConvention()); - mpList->InsertEntry(aTabNames[aPos.Tab()] + "\t" + aPosStr + "\t" + pNote->GetText()); - } + aList.Insert(aTabNames[aPos.Tab()], aPos, + pDoc->GetAddressConvention(), + pNote->GetText()); } } } @@ -88,7 +147,7 @@ void SearchResultsDlg::FillResults( ScDocument* pDoc, const ScRangeList &rMatche } else { - for (size_t i = 0, n = rMatchedRanges.size(); i < n; ++i) + for (size_t i = 0, n = nMatchMax; i < n; ++i) { ScCellIterator aIter(pDoc, *rMatchedRanges[i]); for (bool bHas = aIter.first(); bHas; bHas = aIter.next()) @@ -98,13 +157,13 @@ void SearchResultsDlg::FillResults( ScDocument* pDoc, const ScRangeList &rMatche // Out-of-bound sheet index. continue; - OUString aPosStr = aPos.Format(ScRefFlags::ADDR_ABS, nullptr, pDoc->GetAddressConvention()); - mpList->InsertEntry(aTabNames[aPos.Tab()] + "\t" + aPosStr + "\t" + pDoc->GetString(aPos)); + aList.Insert(aTabNames[aPos.Tab()], aPos, + pDoc->GetAddressConvention(), + pDoc->GetString(aPos)); } } } - mpList->SetUpdateMode(true); - + aList.Update(); mpDoc = pDoc; } diff --git a/sc/source/ui/inc/searchresults.hxx b/sc/source/ui/inc/searchresults.hxx index bdc109e0f2e6..e545f6eb746b 100644 --- a/sc/source/ui/inc/searchresults.hxx +++ b/sc/source/ui/inc/searchresults.hxx @@ -23,6 +23,7 @@ namespace sc { class SearchResultsDlg : public ModelessDialog { VclPtr<SvSimpleTable> mpList; + VclPtr<FixedText> mpLabel; SfxBindings* mpBindings; ScDocument* mpDoc; diff --git a/sc/uiconfig/scalc/ui/searchresults.ui b/sc/uiconfig/scalc/ui/searchresults.ui index c39408aa2a31..9ae863770ba7 100644 --- a/sc/uiconfig/scalc/ui/searchresults.ui +++ b/sc/uiconfig/scalc/ui/searchresults.ui @@ -53,6 +53,13 @@ <property name="position">1</property> </packing> </child> + <child> + <object class="GtkLabel" id="skipped"> + <property name="visible">False</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">skipped $1 ...</property> + </object> + </child> </object> </child> <action-widgets> |