sc/source/ui/cctrl/checklistmenu.cxx |   70 +++++++++++++++++++++++++++++------
 sc/source/ui/inc/checklistmenu.hxx   |    2 -
 2 files changed, 60 insertions(+), 12 deletions(-)

New commits:
commit 6be916fdacd2b07c4d64759d17a3cd54ffd55e95
Author:     Sahil Gautam <[email protected]>
AuthorDate: Thu Dec 4 22:57:47 2025 +0530
Commit:     Michael Stahl <[email protected]>
CommitDate: Fri Dec 12 12:35:01 2025 +0100

    Related tdf#167395: Add comments, make variable names readable
    
    Change-Id: I3774e68549a86757912a78df6807aa11f8b3b97e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195064
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit a034a2bce6d4cf5bb6de850c4d4367f91a8a9300)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195459
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/source/ui/cctrl/checklistmenu.cxx 
b/sc/source/ui/cctrl/checklistmenu.cxx
index 9d3501080a9a..6cad6816a342 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -808,8 +808,14 @@ IMPL_LINK(ScCheckListMenuControl, ButtonHdl, 
weld::Button&, rBtn, void)
 
 namespace
 {
+    /*
+     * calc autofilter has a "[x] Lock" checkbox. when the user clicks on this 
lock
+     * checkbox, the selected entries are marked. then various functions 
calling
+     * `insertMember` (this function) check the lock checkbox state and pass 
that
+     * as `lockMarkedMember`.
+     */
     void insertMember(weld::TreeView& rView, const weld::TreeIter& rIter,
-                      const ScCheckListMember& rMember, bool bChecked, bool 
bLock = false)
+                      const ScCheckListMember& rMember, bool bChecked, bool 
bLockMarkedMember = false)
     {
         OUString aLabel = rMember.maName;
         if (aLabel.isEmpty())
@@ -817,14 +823,20 @@ namespace
         rView.set_toggle(rIter, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
         rView.set_text(rIter, aLabel, 0);
 
-        if (bLock)
+        if (bLockMarkedMember)
             rView.set_sensitive(rIter, !rMember.mbHiddenByOtherFilter && 
!rMember.mbMarked);
         else
             rView.set_sensitive(rIter, !rMember.mbHiddenByOtherFilter);
     }
 
+    /*
+     * when we lock some selection in autofilter and search
+     * for something, we expect the locked entries to be included in the search
+     * results irrespective of whether the entries match the search criteria or
+     * not. `bIncludeMarkedMembers` just does that.
+     */
     void loadSearchedMembers(std::vector<int>& rSearchedMembers, 
std::vector<ScCheckListMember>& rMembers,
-                             const OUString& rSearchText, bool bLock=false)
+                             const OUString& rSearchText, bool 
bIncludeMarkedMembers=false)
     {
         const OUString aSearchText = ScGlobal::getCharClass().lowercase( 
rSearchText );
 
@@ -840,11 +852,18 @@ namespace
 
             if (!bPartialMatch)
                 continue;
-            if (!bLock || (!rMembers[i].mbMarked && 
!rMembers[i].mbHiddenByOtherFilter))
+
+            /*
+             * in case marked members are to be included, we include
+             * them at the end because we can see in the functions which call
+             * this function that the marked members will be disabled anyways
+             * if lock is checked.
+             */
+            if (!bIncludeMarkedMembers || (!rMembers[i].mbMarked && 
!rMembers[i].mbHiddenByOtherFilter))
                 rSearchedMembers.push_back(i);
         }
 
-        if (bLock)
+        if (bIncludeMarkedMembers)
             for (size_t i = 0; i < rMembers.size(); ++i)
                 if (rMembers[i].mbMarked && !rMembers[i].mbHiddenByOtherFilter)
                     rSearchedMembers.push_back(i);
@@ -857,7 +876,9 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, LockCheckedHdl, 
weld::Toggleable&, void)
     bool bLockCheckedEntries = mxChkLockChecked->get_active();
 
     // go over the members visible in the popup, and remember which one is
-    // checked, and which one is not by setting mbMarked to true;
+    // checked, and which one is not by setting `mbMarked` to `true`; by 
default
+    // `mbMarked` is `false`, we clear all the marks when lock is unchecked, 
see
+    // at the end of this callback.
     mpChecks->all_foreach([this](weld::TreeIter& rEntry){
         if (mpChecks->get_toggle(rEntry) == TRISTATE_TRUE)
         {
@@ -886,7 +907,18 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, LockCheckedHdl, 
weld::Toggleable&, void)
     OUString aSearchText = mxEdSearch->get_text();
     if (aSearchText.isEmpty())
     {
-        initMembers(-1, !mxChkLockChecked->get_active());
+        /*
+         * when we click on lock, all the checked entries are marked and
+         * this `true` tells `initMembers` to check only the currently
+         * checked entries.
+         *
+         * when lock is unchecked we want that the entries which were locked
+         * and checked now become unlocked and checked so that we can select
+         * or deselect more entries, still we want only the marked (selected)
+         * entries to remain selected, thus this `true` is valid even in the
+         * uncheck case.
+         */
+        initMembers(-1, true);
     }
     else
     {
@@ -1018,8 +1050,13 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, 
SearchEditTimeoutHdl, Timer*, void)
 
         mpChecks->thaw();
 
+        /*
+         * here we pass the lock state to tell `initMembers` to preserve 
selection
+         * if lock is checked. this is for the case when the user has some 
entries
+         * locked and is now searching for more entries.
+         */
         if (bSearchTextEmpty)
-            nSelCount = initMembers();
+            nSelCount = initMembers(-1, mxChkLockChecked->get_active());
         else
         {
             std::vector<int> aShownIndexes;
@@ -1028,6 +1065,13 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, 
SearchEditTimeoutHdl, Timer*, void)
             // tdf#122419 insert in the fastest order, this might be backwards.
             mpChecks->bulk_insert_for_each(aShownIndexes.size(), [this, 
&aShownIndexes, &nSelCount](weld::TreeIter& rIter, int i) {
                 size_t nIndex = aShownIndexes[i];
+                /*
+                 * here we pass `true` for `bChecked` because we want the 
searched entries to be selected
+                 * by default and at the same time the last parameter tells it 
to keep the previously
+                 * selected members locked. since we mark/unmark entries only 
in the callback
+                 * `LockCheckedHdl`, consecutive searches don't change which 
entries are marked and which
+                 * aren't.
+                 */
                 insertMember(*mpChecks, rIter, maMembers[nIndex], true, 
mxChkLockChecked->get_active());
                 ++nSelCount;
             }, nullptr, &aFixedWidths);
@@ -1488,7 +1532,7 @@ IMPL_LINK(ScCheckListMenuControl, KeyInputHdl, const 
KeyEvent&, rKEvt, bool)
     return false;
 }
 
-size_t ScCheckListMenuControl::initMembers(int nMaxMemberWidth, bool bUnlock)
+size_t ScCheckListMenuControl::initMembers(int nMaxMemberWidth, bool 
bCheckMarkedEntries)
 {
     size_t n = maMembers.size();
     size_t nEnableMember = std::count_if(maMembers.begin(), maMembers.end(),
@@ -1504,9 +1548,13 @@ size_t ScCheckListMenuControl::initMembers(int 
nMaxMemberWidth, bool bUnlock)
         // tdf#134038 insert in the fastest order, this might be backwards so 
only do it for
         // the !mbHasDates case where no entry depends on another to exist 
before getting
         // inserted. We cannot retain pre-existing treeview content, only 
clear and fill it.
-        mpChecks->bulk_insert_for_each(n, [this, &nVisMemCount, 
&bUnlock](weld::TreeIter& rIter, int i) {
+        mpChecks->bulk_insert_for_each(n, [this, &nVisMemCount, 
&bCheckMarkedEntries](weld::TreeIter& rIter, int i) {
             assert(!maMembers[i].mbDate);
-            bool bCheck = ((mxChkLockChecked->get_active() || bUnlock) ? 
maMembers[i].mbMarked : maMembers[i].mbVisible);
+            bool bCheck = (bCheckMarkedEntries ? maMembers[i].mbMarked : 
maMembers[i].mbVisible);
+            /*
+             * `bCheckMarkedEntries` isn't used for locking/unlocking as we 
check the lock
+             * button state for that in the `insertMember` calls.
+             */
             insertMember(*mpChecks, rIter, maMembers[i], bCheck, 
mxChkLockChecked->get_active());
 
             if (bCheck)
diff --git a/sc/source/ui/inc/checklistmenu.hxx 
b/sc/source/ui/inc/checklistmenu.hxx
index 5fd00b673b31..d0d055627668 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -152,7 +152,7 @@ public:
     void addMember(const OUString& rName, const double nVal, bool bVisible, 
bool bHiddenByOtherFilter,
                    bool bValue = false);
     void clearMembers();
-    size_t initMembers(int nMaxMemberWidth = -1, bool bUnlock=false);
+    size_t initMembers(int nMaxMemberWidth = -1, bool bCheckMarkedEntries = 
false);
     void setConfig(const Config& rConfig);
 
     bool isAllSelected() const;

Reply via email to