diff options
author | Jim Raykowski <raykowj@gmail.com> | 2022-11-08 23:49:27 -0900 |
---|---|---|
committer | Jim Raykowski <raykowj@gmail.com> | 2022-11-21 09:41:41 +0100 |
commit | 1b031eb1ba6c529ce67ff8f471afee414d64a098 (patch) | |
tree | e0b4c202e7ebe40aeef38c30be7dfb05bafddc2b | |
parent | d5f29872f5a149fc7905cdf340215c07af0d4da8 (diff) |
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 <raykowj@gmail.com>
-rw-r--r-- | sd/source/ui/dlg/navigatr.cxx | 2 | ||||
-rw-r--r-- | sd/source/ui/dlg/sdtreelb.cxx | 104 | ||||
-rw-r--r-- | sd/uiconfig/simpress/ui/navigatorpanel.ui | 113 |
3 files changed, 139 insertions, 80 deletions
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> |