summaryrefslogtreecommitdiff
path: root/sd
diff options
context:
space:
mode:
authorJim Raykowski <raykowj@gmail.com>2022-11-08 23:49:27 -0900
committerJim Raykowski <raykowj@gmail.com>2022-11-21 09:41:41 +0100
commit1b031eb1ba6c529ce67ff8f471afee414d64a098 (patch)
treee0b4c202e7ebe40aeef38c30be7dfb05bafddc2b /sd
parentd5f29872f5a149fc7905cdf340215c07af0d4da8 (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>
Diffstat (limited to 'sd')
-rw-r--r--sd/source/ui/dlg/navigatr.cxx2
-rw-r--r--sd/source/ui/dlg/sdtreelb.cxx104
-rw-r--r--sd/uiconfig/simpress/ui/navigatorpanel.ui113
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>