[Libreoffice-commits] core.git: 2 commits - sw/source

Michael Stahl mstahl at redhat.com
Wed Nov 30 14:11:24 UTC 2016


 sw/source/uibase/utlui/content.cxx |   88 +++++++++++++++++++++++++++++--------
 1 file changed, 70 insertions(+), 18 deletions(-)

New commits:
commit bf7b5ee0c8a552625b80a7a57c32fe05ee756f7a
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Nov 30 14:54:14 2016 +0100

    rhbz#1122096 tdf#54834: sw navigator: multi-selection of outline entries
    
    * SwContentTree::ToggleToRoot(): allow multi-selection iff outline root
      is displayed
    * SwContentTree::ExecCommand(): handle outline operations for multiple
      selected entries; since it's not possible to prevent selecting both
      parent & child, try to ignore selected children in that case
    * add Undo bracketing
    * rename misleading "bModifier" variable which was actually true without
      the Ctrl key
    * regarding SwContentTree::KeyInput(), the KEY_RETURN causes the view to
      jump to the entry, and KEY_DELETE is not possible for outline entries,
      and KEY_SPACE is only for drawing objects, so no need for handling
      multi-selection here
    * it probably doesn't make sense to handle multi selection in the
      context menu but it appears that the context menu for outline entries
      is already quite borked even going back to OOo times
    
    Change-Id: Ib324065e5fe827796e0f202f01ab9c3e33c47ec5

diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index 32afae2..0d4e3b0 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -1891,10 +1891,15 @@ void SwContentTree::ToggleToRoot()
             m_nRootType = pCntType->GetType();
             m_bIsRoot = true;
             Display(State::HIDDEN != m_eState);
+            if (m_nRootType == ContentTypeId::OUTLINE)
+            {
+                SetSelectionMode(SelectionMode::Multiple);
+            }
         }
     }
     else
     {
+        SetSelectionMode(SelectionMode::Single);
         m_nRootType = ContentTypeId::UNKNOWN;
         m_bIsRoot = false;
         FindActiveTypeAndRemoveUserData();
@@ -2234,7 +2239,9 @@ void SwContentTree::Notify(SfxBroadcaster & rBC, SfxHint const& rHint)
     }
 }
 
-void SwContentTree::ExecCommand(const OUString& rCmd, bool bModifier)
+
+
+void SwContentTree::ExecCommand(const OUString& rCmd, bool bOutlineWithChildren)
 {
     const bool bUp = rCmd == "up";
     const bool bUpDown = bUp || rCmd == "down";
@@ -2252,40 +2259,80 @@ void SwContentTree::ExecCommand(const OUString& rCmd, bool bModifier)
     SwWrtShell *const pShell = GetWrtShell();
     sal_Int8 nActOutlineLevel = m_nOutlineLevel;
     sal_uInt16 nActPos = pShell->GetOutlinePos(nActOutlineLevel);
-    SvTreeListEntry* pFirstEntry = FirstSelected();
-    if (pFirstEntry && lcl_IsContent(pFirstEntry))
+
+    std::vector<SvTreeListEntry*> selected;
+    for (SvTreeListEntry * pEntry = FirstSelected(); pEntry; pEntry = NextSelected(pEntry))
     {
-        assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pFirstEntry->GetUserData())));
-        if ((m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE) ||
-            static_cast<SwContent*>(pFirstEntry->GetUserData())->GetParent()->GetType()
-                                        ==  ContentTypeId::OUTLINE)
+        // it's possible to select the root node too which is a really bad idea
+        bool bSkip = lcl_IsContentType(pEntry);
+        // filter out children of selected parents so they don't get promoted
+        // or moved twice (except if there is Ctrl modifier, since in that
+        // case children are re-parented)
+        if ((bLeftRight || bOutlineWithChildren) && !selected.empty())
+        {
+            for (auto pParent = GetParent(pEntry); pParent; pParent = GetParent(pParent))
+            {
+                if (selected.back() == pParent)
+                {
+                    bSkip = true;
+                    break;
+                }
+            }
+        }
+        if (!bSkip)
         {
-            nActPos = static_cast<SwOutlineContent*>(pFirstEntry->GetUserData())->GetPos();
+            selected.push_back(pEntry);
         }
     }
-    if (nActPos < USHRT_MAX && (!bUpDown || pShell->IsOutlineMovable(nActPos)))
+    if (bUpDown && !bUp)
+    {   // to move down, start at the end!
+        std::reverse(selected.begin(), selected.end());
+    }
+
+    bool bStartedAction = false;
+    for (auto pCurrentEntry : selected)
     {
-        pShell->StartAllAction();
+        if (pCurrentEntry && lcl_IsContent(pCurrentEntry))
+        {
+            assert(dynamic_cast<SwContent*>(static_cast<SwTypeNumber*>(pCurrentEntry->GetUserData())));
+            if ((m_bIsRoot && m_nRootType == ContentTypeId::OUTLINE) ||
+                static_cast<SwContent*>(pCurrentEntry->GetUserData())->GetParent()->GetType()
+                                            ==  ContentTypeId::OUTLINE)
+            {
+                nActPos = static_cast<SwOutlineContent*>(pCurrentEntry->GetUserData())->GetPos();
+            }
+        }
+        if (nActPos == USHRT_MAX || (bUpDown && !pShell->IsOutlineMovable(nActPos)))
+        {
+            continue;
+        }
+
+        if (!bStartedAction)
+        {
+            pShell->StartAllAction();
+            pShell->StartUndo(bLeftRight ? UNDO_OUTLINE_LR : UNDO_OUTLINE_UD);
+            bStartedAction = true;
+        }
         pShell->GotoOutline( nActPos); // If text selection != box selection
         pShell->Push();
-        pShell->MakeOutlineSel(nActPos, nActPos, bModifier);
+        pShell->MakeOutlineSel(nActPos, nActPos, bOutlineWithChildren);
         if (bUpDown)
         {
             short nDir = bUp ? -1 : 1;
-            if (!bModifier && ((nDir == -1 && nActPos > 0) ||
+            if (!bOutlineWithChildren && ((nDir == -1 && nActPos > 0) ||
                                (nDir == 1 && nActPos < GetEntryCount() - 2)))
             {
                 pShell->MoveOutlinePara( nDir );
                 // Set cursor back to the current position
                 pShell->GotoOutline( nActPos + nDir);
             }
-            else if (bModifier && pFirstEntry)
+            else if (bOutlineWithChildren && pCurrentEntry)
             {
                 sal_uInt16 nActEndPos = nActPos;
-                SvTreeListEntry* pEntry = pFirstEntry;
-                assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pFirstEntry->GetUserData())));
+                SvTreeListEntry* pEntry = pCurrentEntry;
+                assert(dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pCurrentEntry->GetUserData())));
                 const auto nActLevel = static_cast<SwOutlineContent*>(
-                        pFirstEntry->GetUserData())->GetOutlineLevel();
+                        pCurrentEntry->GetUserData())->GetOutlineLevel();
                 pEntry = Next(pEntry);
                 while (pEntry && CTYPE_CNT ==
                     static_cast<SwTypeNumber*>(pEntry->GetUserData())->GetTypeId())
@@ -2331,7 +2378,7 @@ void SwContentTree::ExecCommand(const OUString& rCmd, bool bModifier)
                 else
                 {
                     sal_uInt16 nDest = nActPos;
-                    pEntry = pFirstEntry;
+                    pEntry = pCurrentEntry;
                     while (pEntry && nDest)
                     {
                         nDest--;
@@ -2362,6 +2409,11 @@ void SwContentTree::ExecCommand(const OUString& rCmd, bool bModifier)
 
         pShell->ClearMark();
         pShell->Pop(false); // Cursor is now back at the current heading.
+    }
+
+    if (bStartedAction)
+    {
+        pShell->EndUndo();
         pShell->EndAllAction();
         if (m_aActiveContentArr[ContentTypeId::OUTLINE])
             m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate();
commit f0ab10bb89baeaaa796c0bdfd125f3e5a2417ca2
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Nov 30 13:55:09 2016 +0100

    sw: incorrect assertion in SwContentTree::RequestingChildren()
    
    Change-Id: I627c99d0540265f34612ac430d4df281acc7e6cd

diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index bbc7162..32afae2 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -1328,7 +1328,7 @@ void SwContentTree::RequestingChildren( SvTreeListEntry* pParent )
                                     )
                                 {
                                     pChild = Prev(pChild);
-                                    assert(!pChild || dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pChild->GetUserData())));
+                                    assert(!pChild || dynamic_cast<SwTypeNumber*>(static_cast<SwTypeNumber*>(pChild->GetUserData())));
                                 }
                                 if(pChild)
                                     pChild = InsertEntry(sEntry, pChild,


More information about the Libreoffice-commits mailing list