[Libreoffice-commits] core.git: sc/source

Jean-Sebastien Bevilacqua realitix at gmail.com
Wed May 31 11:18:46 UTC 2017


 sc/source/ui/cctrl/checklistmenu.cxx |   26 ++++++++++++++++++++++----
 sc/source/ui/inc/checklistmenu.hxx   |    2 ++
 2 files changed, 24 insertions(+), 4 deletions(-)

New commits:
commit 511fb8e80d298d42f5c45e7410bf64f2a25b441e
Author: Jean-Sebastien Bevilacqua <realitix at gmail.com>
Date:   Wed May 31 10:59:42 2017 +0200

    tdf#108259 Enable autofilter with many different values
    
    When you create an autofilter on a column which contains many different
    values, you will have problems.
    
    First of all, if you exceed 65535 values, you will enter in an infinite
    loop because a uint16 is incremented for each value, and after 65535,
    you restart to 0.
    
    Secondly, the algorithm executes a double loop in O(n2) to determine
    checked values, it's too long. Instead of that, all checked values can be
    determined before.
    
    This patch is graciously offered by Linagora.
    
    Change-Id: Idc4500f6a496ae789aae11eb0e183aee157daa20
    Reviewed-on: https://gerrit.libreoffice.org/38269
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
    Tested-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index d3ed848145da..ee51abb9f8a8 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -1141,8 +1141,8 @@ void ScCheckListMenuWindow::setAllMemberState(bool bSet)
     {
         if (!(*itr))
         {
-            sal_uInt16 nCount = maChecks->GetEntryCount();
-            for( sal_uInt16 i = 0; i < nCount; ++i)
+            sal_uInt32 nCount = maChecks->GetEntryCount();
+            for( sal_uInt32 i = 0; i < nCount; ++i)
             {
                 SvTreeListEntry* pEntry = maChecks->GetEntry(i);
                 if (!pEntry)
@@ -1620,7 +1620,7 @@ ScCheckListBox::ScCheckListBox( vcl::Window* pParent )
 
 SvTreeListEntry* ScCheckListBox::FindEntry( SvTreeListEntry* pParent, const OUString& sNode )
 {
-    sal_uInt16 nRootPos = 0;
+    sal_uInt32 nRootPos = 0;
     SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : GetEntry( nRootPos );
     while ( pEntry )
     {
@@ -1639,6 +1639,23 @@ void ScCheckListBox::Init()
     SetNodeDefaultImages();
 }
 
+std::unordered_set<OUString, OUStringHash> ScCheckListBox::GetAllChecked()
+{
+    std::unordered_set<OUString, OUStringHash> results(0);
+    sal_uInt32 nRootPos = 0;
+    SvTreeListEntry* pEntry = GetEntry(nRootPos);
+    while (pEntry)
+    {
+        if (GetCheckButtonState(pEntry) == SvButtonState::Checked)
+        {
+            results.insert(GetEntryText(pEntry));
+        }
+        pEntry = GetEntry(++nRootPos);
+    }
+
+    return results;
+}
+
 bool ScCheckListBox::IsChecked( const OUString& sName, SvTreeListEntry* pParent )
 {
     SvTreeListEntry* pEntry = FindEntry( pParent, sName );
@@ -1907,6 +1924,7 @@ bool ScCheckListMenuWindow::isAllSelected() const
 void ScCheckListMenuWindow::getResult(ResultType& rResult)
 {
     ResultType aResult;
+    std::unordered_set<OUString, OUStringHash> checkeds = maChecks->GetAllChecked();
     size_t n = maMembers.size();
     for (size_t i = 0; i < n; ++i)
     {
@@ -1915,7 +1933,7 @@ void ScCheckListMenuWindow::getResult(ResultType& rResult)
             OUString aLabel = maMembers[i].maName;
             if (aLabel.isEmpty())
                 aLabel = ScGlobal::GetRscString(STR_EMPTYDATA);
-            bool bState =  maChecks->IsChecked( aLabel,  maMembers[i].mpParent );
+            bool bState = checkeds.find(aLabel) != checkeds.end();
             ResultEntry aResultEntry;
             aResultEntry.bValid = bState;
             if ( maMembers[i].mbDate )
diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx
index 9c1a1f3fd07f..7bae3853e82e 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -19,6 +19,7 @@
 #include <svx/checklbx.hxx>
 
 #include <memory>
+#include <unordered_set>
 #include <unordered_map>
 #include <map>
 
@@ -239,6 +240,7 @@ class ScCheckListBox : public SvTreeListBox
     void CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck );
     void CheckEntry( SvTreeListEntry* pEntry, bool bCheck );
     SvTreeListEntry* ShowCheckEntry( const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true );
+    std::unordered_set<OUString, OUStringHash> GetAllChecked();
     bool IsChecked( const OUString& sName, SvTreeListEntry* pParent );
     SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
     sal_uInt16 GetCheckedEntryCount() const;


More information about the Libreoffice-commits mailing list