From ba68e6dd7ad99ef2a2720f327813d13550b98966 Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Fri, 4 Nov 2016 20:19:12 +0000 Subject: 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 Tested-by: Michael Meeks --- sc/source/ui/dialogs/searchresults.cxx | 83 +++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 12 deletions(-) (limited to 'sc/source/ui/dialogs') 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("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 mpLabel; + VclPtr mpList; + public: + ListWrapper(const VclPtr &pList, + const VclPtr &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 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; } -- cgit