sd/source/ui/dlg/navigatr.cxx             |    2 
 sd/source/ui/dlg/sdtreelb.cxx             |  104 ++++++++++++++++++++-------
 sd/uiconfig/simpress/ui/navigatorpanel.ui |  113 +++++++++++++++---------------
 3 files changed, 139 insertions(+), 80 deletions(-)

New commits:
commit 1b031eb1ba6c529ce67ff8f471afee414d64a098
Author:     Jim Raykowski <rayk...@gmail.com>
AuthorDate: Tue Nov 8 23:49:27 2022 -0900
Commit:     Jim Raykowski <rayk...@gmail.com>
CommitDate: Mon Nov 21 09:41:41 2022 +0100

    tdf#145359 related: SdNavigator dnd
    
    This is an enhancement patch that provides drag and drop capability
    within the Navigator page object tree to allow arranging object
    navigation order and grouping of objects.
    
    Change-Id: I76996cd909765fb3503cf077566bec267b7705e2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142640
    Tested-by: Jenkins
    Reviewed-by: Jim Raykowski <rayk...@gmail.com>

diff --git a/sd/source/ui/dlg/navigatr.cxx b/sd/source/ui/dlg/navigatr.cxx
index 98883e79999b..cdc2db1f5a81 100644
--- a/sd/source/ui/dlg/navigatr.cxx
+++ b/sd/source/ui/dlg/navigatr.cxx
@@ -808,7 +808,7 @@ void 
SdNavigatorControllerItem::StateChangedAtToolBoxControl( sal_uInt16 nSId,
     if (nState & NavState::TableUpdate)
     {
         // InitTlb; is initiated by Slot
-        if (maUpdateRequest)
+        if (maUpdateRequest && 
!pNavigatorWin->GetObjects().get_treeview().has_focus())
             maUpdateRequest();
     }
 }
diff --git a/sd/source/ui/dlg/sdtreelb.cxx b/sd/source/ui/dlg/sdtreelb.cxx
index 8a9002ac6c38..a90a76adbee2 100644
--- a/sd/source/ui/dlg/sdtreelb.cxx
+++ b/sd/source/ui/dlg/sdtreelb.cxx
@@ -379,8 +379,8 @@ namespace
 
         std::unique_ptr<weld::TreeIter> 
xSourceParent(rTreeView.make_iterator(xSource.get()));
         bool bSourceHasParent = rTreeView.iter_parent(*xSourceParent);
-        // level 1 objects only
-        if (!bSourceHasParent || rTreeView.get_iter_depth(*xSourceParent))
+        // disallow root drag
+        if (!bSourceHasParent)
             return false;
 
         SdrObject* pSourceObject = 
weld::fromId<SdrObject*>(rTreeView.get_id(*xSource));
@@ -495,20 +495,36 @@ sal_Int8 SdPageObjsTLVDropTarget::AcceptDrop(const 
AcceptDropEvent& rEvt)
     if (!m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), true))
         return DND_ACTION_NONE;
 
+    // disallow when root is drop target
+    if (m_rTreeView.get_iter_depth(*xTarget) == 0)
+        return DND_ACTION_NONE;
+
+    // disallow if there is no source entry selected
     std::unique_ptr<weld::TreeIter> xSource(m_rTreeView.make_iterator());
     if (!m_rTreeView.get_selected(xSource.get()))
         return DND_ACTION_NONE;
 
-    std::unique_ptr<weld::TreeIter> 
xTargetParent(m_rTreeView.make_iterator(xTarget.get()));
-    while (m_rTreeView.get_iter_depth(*xTargetParent))
-        m_rTreeView.iter_parent(*xTargetParent);
+    // disallow when root is source
+    if (m_rTreeView.get_iter_depth(*xSource) == 0)
+        return DND_ACTION_NONE;
 
-    std::unique_ptr<weld::TreeIter> 
xSourceParent(m_rTreeView.make_iterator(xSource.get()));
-    while (m_rTreeView.get_iter_depth(*xSourceParent))
-        m_rTreeView.iter_parent(*xSourceParent);
+    // disallow when the source is the parent or ancestoral parent of the 
target
+    std::unique_ptr<weld::TreeIter> 
xTargetParent(m_rTreeView.make_iterator(xTarget.get()));
+    while (m_rTreeView.get_iter_depth(*xTargetParent) > 1)
+    {
+        if (!m_rTreeView.iter_parent(*xTargetParent) ||
+                m_rTreeView.iter_compare(*xSource, *xTargetParent) == 0)
+            return DND_ACTION_NONE;
+    }
 
-    // can only drop within the same page
-    if (m_rTreeView.iter_compare(*xTargetParent, *xSourceParent) != 0)
+    // disallow drop when source and target are not within the same page
+    std::unique_ptr<weld::TreeIter> 
xSourcePage(m_rTreeView.make_iterator(xSource.get()));
+    std::unique_ptr<weld::TreeIter> 
xTargetPage(m_rTreeView.make_iterator(xTarget.get()));
+    while (m_rTreeView.get_iter_depth(*xTargetPage))
+        m_rTreeView.iter_parent(*xTargetPage);
+    while (m_rTreeView.get_iter_depth(*xSourcePage))
+        m_rTreeView.iter_parent(*xSourcePage);
+    if (m_rTreeView.iter_compare(*xTargetPage, *xSourcePage) != 0)
         return DND_ACTION_NONE;
 
     return DND_ACTION_MOVE;
@@ -529,35 +545,73 @@ sal_Int8 SdPageObjsTLVDropTarget::ExecuteDrop( const 
ExecuteDropEvent& rEvt )
         return DND_ACTION_NONE;
 
     std::unique_ptr<weld::TreeIter> xTarget(m_rTreeView.make_iterator());
-    if (!m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), true))
+    if (!m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), 
false))
         return DND_ACTION_NONE;
-    int nTargetPos = m_rTreeView.get_iter_index_in_parent(*xTarget) + 1;
+
+    auto nIterCompare = m_rTreeView.iter_compare(*xSource, *xTarget);
+    if (nIterCompare == 0)
+    {
+        // drop position is the same as source position
+        return DND_ACTION_NONE;
+    }
 
     SdrObject* pTargetObject = 
weld::fromId<SdrObject*>(m_rTreeView.get_id(*xTarget));
     SdrObject* pSourceObject = 
weld::fromId<SdrObject*>(m_rTreeView.get_id(*xSource));
     if (pSourceObject == reinterpret_cast<SdrObject*>(1))
         pSourceObject = nullptr;
+    if (pTargetObject == reinterpret_cast<SdrObject*>(1))
+        pTargetObject = nullptr;
 
     if (pTargetObject != nullptr && pSourceObject != nullptr)
     {
         SdrPage* pObjectList = pSourceObject->getSdrPageFromSdrObject();
-        if (pObjectList != nullptr)
-        {
-            sal_uInt32 nNewPosition;
-            if (pTargetObject == reinterpret_cast<SdrObject*>(1))
-            {
-                nNewPosition = 0;
-                nTargetPos = 0;
-            }
-            else
-                nNewPosition = pTargetObject->GetNavigationPosition() + 1;
-            pObjectList->SetObjectNavigationPosition(*pSourceObject, 
nNewPosition);
-        }
 
         std::unique_ptr<weld::TreeIter> 
xSourceParent(m_rTreeView.make_iterator(xSource.get()));
         m_rTreeView.iter_parent(*xSourceParent);
+        std::unique_ptr<weld::TreeIter> 
xTargetParent(m_rTreeView.make_iterator(xTarget.get()));
+        m_rTreeView.iter_parent(*xTargetParent);
+
+        int nTargetPos = m_rTreeView.get_iter_index_in_parent(*xTarget);
+
+        // Make the tree view what the model will be when it is changed below.
+        m_rTreeView.move_subtree(*xSource, xTargetParent.get(), nTargetPos);
+        m_rTreeView.iter_previous_sibling(*xTarget);
+        m_rTreeView.set_cursor(*xTarget);
+
+        if (m_rTreeView.iter_compare(*xSourceParent, *xTargetParent) == 0 && 
nIterCompare < 0)
+            nTargetPos = m_rTreeView.get_iter_index_in_parent(*xTarget);
+
+        // Remove the source object from soure parent list and insert it in 
the target parent list.
+        SdrObject* pSourceParentObject = 
weld::fromId<SdrObject*>(m_rTreeView.get_id(*xSourceParent));
+        SdrObject* pTargetParentObject = 
weld::fromId<SdrObject*>(m_rTreeView.get_id(*xTargetParent));
+
+        // Presumably there is need for a hard reference to hold on to the 
removed object so it is
+        // guaranteed to be valid for insert back into an object list.
+        rtl::Reference<SdrObject> rSourceObject;
+
+        // remove object
+        if (pSourceParentObject == reinterpret_cast<SdrObject*>(1))
+        {
+            rSourceObject = 
pObjectList->NbcRemoveObject(pSourceObject->GetOrdNum());
+        }
+        else
+        {
+            SdrObjList* pList = pSourceParentObject->GetSubList();
+            rSourceObject = pList->NbcRemoveObject(pSourceObject->GetOrdNum());
+        }
 
-        m_rTreeView.move_subtree(*xSource, xSourceParent.get(), nTargetPos);
+        // insert object
+        if (pTargetParentObject == reinterpret_cast<SdrObject*>(1))
+        {
+            pObjectList->NbcInsertObject(rSourceObject.get());
+            pObjectList->SetObjectNavigationPosition(*rSourceObject, 
nTargetPos);
+        }
+        else
+        {
+            SdrObjList* pList = pTargetParentObject->GetSubList();
+            pList->NbcInsertObject(rSourceObject.get(), nTargetPos);
+            pList->SetObjectNavigationPosition(*rSourceObject, nTargetPos);
+        }
     }
 
     return DND_ACTION_NONE;
diff --git a/sd/uiconfig/simpress/ui/navigatorpanel.ui 
b/sd/uiconfig/simpress/ui/navigatorpanel.ui
index 98d22dfc8fec..1059f7e9ad74 100644
--- a/sd/uiconfig/simpress/ui/navigatorpanel.ui
+++ b/sd/uiconfig/simpress/ui/navigatorpanel.ui
@@ -1,33 +1,33 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.36.0 -->
+<!-- Generated with glade 3.40.0 -->
 <interface domain="sd">
   <requires lib="gtk+" version="3.20"/>
   <object class="GtkMenu" id="dragmodemenu">
     <property name="visible">True</property>
-    <property name="can_focus">False</property>
+    <property name="can-focus">False</property>
     <child>
       <object class="GtkRadioMenuItem" id="1">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can-focus">False</property>
         <property name="label" translatable="yes" 
context="navigatorpanelSTR_DRAGTYPE_URL">Insert as Hyperlink</property>
-        <property name="draw_as_radio">True</property>
+        <property name="draw-as-radio">True</property>
       </object>
     </child>
     <child>
       <object class="GtkRadioMenuItem" id="2">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can-focus">False</property>
         <property name="label" translatable="yes" 
context="navigatorpanel|STR_DRAGTYPE_LINK">Insert as Link</property>
-        <property name="draw_as_radio">True</property>
+        <property name="draw-as-radio">True</property>
         <property name="group">1</property>
       </object>
     </child>
     <child>
       <object class="GtkRadioMenuItem" id="3">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can-focus">False</property>
         <property name="label" translatable="yes" 
context="navigatorpanel|STR_DRAGTYPE_EMBEDDED">Insert as Copy</property>
-        <property name="draw_as_radio">True</property>
+        <property name="draw-as-radio">True</property>
         <property name="group">1</property>
       </object>
     </child>
@@ -45,24 +45,24 @@
   <!-- n-columns=1 n-rows=1 -->
   <object class="GtkGrid" id="NavigatorPanel">
     <property name="visible">True</property>
-    <property name="can_focus">False</property>
+    <property name="can-focus">False</property>
     <property name="hexpand">True</property>
     <property name="vexpand">True</property>
-    <property name="border_width">6</property>
+    <property name="border-width">6</property>
     <child>
-      <!-- n-columns=1 n-rows=1 -->
+      <!-- n-columns=1 n-rows=3 -->
       <object class="GtkGrid">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can-focus">False</property>
         <property name="hexpand">True</property>
         <property name="vexpand">True</property>
-        <property name="row_spacing">3</property>
-        <property name="column_spacing">6</property>
+        <property name="row-spacing">3</property>
+        <property name="column-spacing">6</property>
         <child>
           <object class="GtkComboBoxText" id="documents">
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="tooltip_text" translatable="yes" 
context="navigatorpanel|documents|tooltip_text">Document</property>
+            <property name="can-focus">False</property>
+            <property name="tooltip-text" translatable="yes" 
context="navigatorpanel|documents|tooltip_text">Document</property>
             <child internal-child="accessible">
               <object class="AtkObject" id="documents-atkobject">
                 <property name="AtkObject::accessible-name" translatable="yes" 
context="navigatorpanel|documents-atkobject">Active Window</property>
@@ -71,30 +71,29 @@
             </child>
           </object>
           <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">2</property>
+            <property name="left-attach">0</property>
+            <property name="top-attach">2</property>
           </packing>
         </child>
         <child>
           <object class="GtkScrolledWindow">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
+            <property name="can-focus">True</property>
             <property name="hexpand">True</property>
             <property name="vexpand">True</property>
-            <property name="shadow_type">in</property>
+            <property name="shadow-type">in</property>
             <child>
               <object class="GtkTreeView" id="tree">
-                <property name="width_request">-1</property>
+                <property name="width-request">-1</property>
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">True</property>
                 <property name="hexpand">True</property>
                 <property name="vexpand">True</property>
                 <property name="model">liststore2</property>
-                <property name="headers_visible">False</property>
+                <property name="headers-visible">False</property>
                 <property name="reorderable">True</property>
-                <property name="search_column">1</property>
-                <property name="enable_tree_lines">True</property>
+                <property name="search-column">1</property>
                 <child internal-child="selection">
                   <object class="GtkTreeSelection" id="Macro Library 
List-selection11"/>
                 </child>
@@ -125,22 +124,23 @@
             </child>
           </object>
           <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">1</property>
+            <property name="left-attach">0</property>
+            <property name="top-attach">1</property>
           </packing>
         </child>
         <child>
           <object class="GtkToolbar" id="toolbox">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
+            <property name="can-focus">True</property>
             <property name="hexpand">True</property>
-            <property name="toolbar_style">icons</property>
+            <property name="toolbar-style">icons</property>
             <property name="icon_size">2</property>
             <child>
               <object class="GtkToolButton" id="first">
                 <property name="visible">True</property>
-                <property name="tooltip_text" translatable="yes" 
context="navigatorpanel|first|tooltip_text">First Slide</property>
-                <property name="icon_name">sd/res/nv03.png</property>
+                <property name="can-focus">False</property>
+                <property name="tooltip-text" translatable="yes" 
context="navigatorpanel|first|tooltip_text">First Slide</property>
+                <property name="icon-name">sd/res/nv03.png</property>
                 <child internal-child="accessible">
                   <object class="AtkObject" id="first-atkobject">
                     <property name="AtkObject::accessible-description" 
translatable="yes" context="navigatorpanel|extended_tip|first">Jumps to the 
first page.</property>
@@ -155,8 +155,9 @@
             <child>
               <object class="GtkToolButton" id="previous">
                 <property name="visible">True</property>
-                <property name="tooltip_text" translatable="yes" 
context="navigatorpanel|previous|tooltip_text">Previous Slide</property>
-                <property name="icon_name">sd/res/nv04.png</property>
+                <property name="can-focus">False</property>
+                <property name="tooltip-text" translatable="yes" 
context="navigatorpanel|previous|tooltip_text">Previous Slide</property>
+                <property name="icon-name">sd/res/nv04.png</property>
                 <child internal-child="accessible">
                   <object class="AtkObject" id="previous-atkobject">
                     <property name="AtkObject::accessible-description" 
translatable="yes" context="navigatorpanel|extended_tip|previous">Moves back 
one page.</property>
@@ -171,8 +172,9 @@
             <child>
               <object class="GtkToolButton" id="next">
                 <property name="visible">True</property>
-                <property name="tooltip_text" translatable="yes" 
context="navigatorpanel|next|tooltip_text">Next Slide</property>
-                <property name="icon_name">sd/res/nv05.png</property>
+                <property name="can-focus">False</property>
+                <property name="tooltip-text" translatable="yes" 
context="navigatorpanel|next|tooltip_text">Next Slide</property>
+                <property name="icon-name">sd/res/nv05.png</property>
                 <child internal-child="accessible">
                   <object class="AtkObject" id="next-atkobject">
                     <property name="AtkObject::accessible-description" 
translatable="yes" context="navigatorpanel|extended_tip|next">Move forward one 
page.</property>
@@ -187,8 +189,9 @@
             <child>
               <object class="GtkToolButton" id="last">
                 <property name="visible">True</property>
-                <property name="tooltip_text" translatable="yes" 
context="navigatorpanel|last|tooltip_text">Last Slide</property>
-                <property name="icon_name">sd/res/nv06.png</property>
+                <property name="can-focus">False</property>
+                <property name="tooltip-text" translatable="yes" 
context="navigatorpanel|last|tooltip_text">Last Slide</property>
+                <property name="icon-name">sd/res/nv06.png</property>
                 <child internal-child="accessible">
                   <object class="AtkObject" id="last-atkobject">
                     <property name="AtkObject::accessible-description" 
translatable="yes" context="navigatorpanel|extended_tip|last">Jumps to the last 
page.</property>
@@ -203,7 +206,7 @@
             <child>
               <object class="GtkSeparatorToolItem" id="separator">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can-focus">False</property>
                 <property name="halign">end</property>
                 <property name="hexpand">True</property>
               </object>
@@ -215,8 +218,9 @@
             <child>
               <object class="GtkMenuToolButton" id="dragmode">
                 <property name="visible">True</property>
-                <property name="tooltip_text" translatable="yes" 
context="navigatorpanel|dragmode|tooltip_text">Drag Mode</property>
-                <property name="icon_name">sd/res/nv09.png</property>
+                <property name="can-focus">False</property>
+                <property name="tooltip-text" translatable="yes" 
context="navigatorpanel|dragmode|tooltip_text">Drag Mode</property>
+                <property name="icon-name">sd/res/nv09.png</property>
                 <child internal-child="accessible">
                   <object class="AtkObject" id="dragmode-atkobject">
                     <property name="AtkObject::accessible-description" 
translatable="yes" context="navigatorpanel|extended_tip|dragmode">Drag and drop 
slides and named objects into the active slide.</property>
@@ -231,8 +235,9 @@
             <child>
               <object class="GtkMenuToolButton" id="shapes">
                 <property name="visible">True</property>
-                <property name="tooltip_text" translatable="yes" 
context="navigatorpanel|shapes|tooltip_text">Show Shapes</property>
-                <property name="icon_name">sd/res/graphic.png</property>
+                <property name="can-focus">False</property>
+                <property name="tooltip-text" translatable="yes" 
context="navigatorpanel|shapes|tooltip_text">Show Shapes</property>
+                <property name="icon-name">sd/res/graphic.png</property>
                 <child internal-child="accessible">
                   <object class="AtkObject" id="shapes-atkobject">
                     <property name="AtkObject::accessible-description" 
translatable="yes" context="navigatorpanel|extended_tip|shapes">In the submenu 
you can choose to display a list of all shapes or only the named shapes. Use 
drag-and-drop in the list to reorder the shapes. When you set the focus to a 
slide and press the Tab key, the next shape in the defined order is 
selected.</property>
@@ -246,14 +251,14 @@
             </child>
           </object>
           <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">0</property>
+            <property name="left-attach">0</property>
+            <property name="top-attach">0</property>
           </packing>
         </child>
       </object>
       <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">0</property>
+        <property name="left-attach">0</property>
+        <property name="top-attach">0</property>
       </packing>
     </child>
     <child internal-child="accessible">
@@ -264,23 +269,23 @@
   </object>
   <object class="GtkMenu" id="shapemenu">
     <property name="visible">True</property>
-    <property name="can_focus">False</property>
+    <property name="can-focus">False</property>
     <child>
       <object class="GtkRadioMenuItem" id="named">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can-focus">False</property>
         <property name="label" translatable="yes" 
context="navigatorpanel|STR_NAVIGATOR_SHOW_NAMED_SHAPES">Named shapes</property>
-        <property name="use_underline">True</property>
-        <property name="draw_as_radio">True</property>
+        <property name="use-underline">True</property>
+        <property name="draw-as-radio">True</property>
       </object>
     </child>
     <child>
       <object class="GtkRadioMenuItem" id="all">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can-focus">False</property>
         <property name="label" translatable="yes" 
context="navigatorpanel|STR_NAVIGATOR_SHOW_ALL_SHAPES">All shapes</property>
-        <property name="use_underline">True</property>
-        <property name="draw_as_radio">True</property>
+        <property name="use-underline">True</property>
+        <property name="draw-as-radio">True</property>
         <property name="group">named</property>
       </object>
     </child>

Reply via email to