summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sd/source/ui/dlg/navigatr.cxx96
-rw-r--r--sd/source/ui/dlg/sdtreelb.cxx46
-rw-r--r--sd/source/ui/inc/navigatr.hxx1
-rw-r--r--sd/source/ui/inc/sdtreelb.hxx24
-rw-r--r--vcl/source/treelist/uiobject.cxx2
5 files changed, 126 insertions, 43 deletions
diff --git a/sd/source/ui/dlg/navigatr.cxx b/sd/source/ui/dlg/navigatr.cxx
index 6aca8fd0f2fb..162b3011a23d 100644
--- a/sd/source/ui/dlg/navigatr.cxx
+++ b/sd/source/ui/dlg/navigatr.cxx
@@ -67,6 +67,7 @@ SdNavigatorWin::SdNavigatorWin(weld::Widget* pParent, SfxBindings* pInBindings,
mxTlbObjects->connect_row_activated(LINK(this, SdNavigatorWin, ClickObjectHdl));
mxTlbObjects->set_selection_mode(SelectionMode::Multiple);
+ mxTlbObjects->connect_mouse_release(LINK(this, SdNavigatorWin, MouseReleaseHdl));
mxToolbox->connect_clicked(LINK(this, SdNavigatorWin, SelectToolboxHdl));
mxToolbox->connect_menu_toggled(LINK(this, SdNavigatorWin, DropdownClickToolBoxHdl));
@@ -232,6 +233,11 @@ SdPageObjsTLV& SdNavigatorWin::GetObjects()
return *mxTlbObjects;
}
+IMPL_STATIC_LINK_NOARG(SdNavigatorWin, MouseReleaseHdl, const MouseEvent&, bool)
+{
+ return true;
+}
+
IMPL_LINK(SdNavigatorWin, SelectToolboxHdl, const OString&, rCommand, void)
{
PageJump ePage = PAGE_NONE;
@@ -291,14 +297,80 @@ IMPL_LINK_NOARG(SdNavigatorWin, ClickObjectHdl, weld::TreeView&, bool)
// if it is the active window, we jump to the page
if( pInfo && pInfo->IsActive() )
{
- OUString aStr(mxTlbObjects->get_selected_text());
+ OUString aStr(mxTlbObjects->get_cursor_text());
if( !aStr.isEmpty() )
{
- SfxStringItem aItem( SID_NAVIGATOR_OBJECT, aStr );
- mpBindings->GetDispatcher()->ExecuteList(
- SID_NAVIGATOR_OBJECT,
- SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem });
+ sd::DrawDocShell* pDocShell = pInfo->mpDocShell;
+ if (!pDocShell)
+ return false;
+ sd::ViewShell* pViewShell = pDocShell->GetViewShell();
+ if (!pViewShell)
+ return false;
+ SdrView* pDrawView = pViewShell->GetDrawView();
+ if (!pDrawView)
+ return false;
+
+ // Save the selected tree entries re-mark the objects in the view after navigation.
+ auto vSelectedEntryIds = mxTlbObjects->GetSelectedEntryIds();
+
+ // Page entries in the tree have id value 1. Object entries have id value of
+ // the address of the pointer to the object.
+ const auto& rCursorEntryId = mxTlbObjects->get_cursor_id();
+ auto nCursorEntryId = rCursorEntryId.toInt64();
+ SdrObject* pCursorEntryObject = weld::fromId<SdrObject*>(rCursorEntryId);
+
+ bool bIsCursorEntrySelected(std::find(vSelectedEntryIds.begin(),
+ vSelectedEntryIds.end(),
+ rCursorEntryId) != vSelectedEntryIds.end());
+
+ if (bIsCursorEntrySelected)
+ {
+ // Set a temporary name, if need be, so the object can be navigated to.
+ bool bCursorEntryObjectHasEmptyName = false;
+ if (nCursorEntryId != 1 && pCursorEntryObject
+ && pCursorEntryObject->GetName().isEmpty())
+ {
+ bCursorEntryObjectHasEmptyName = true;
+ bool bUndo = pCursorEntryObject->getSdrModelFromSdrObject().IsUndoEnabled();
+ pCursorEntryObject->getSdrModelFromSdrObject().EnableUndo(false);
+ pCursorEntryObject->SetName(aStr, false);
+ pCursorEntryObject->getSdrModelFromSdrObject().EnableUndo(bUndo);
+ }
+
+ // All objects are unmarked when navigating to an object.
+ SfxStringItem aItem(SID_NAVIGATOR_OBJECT, aStr);
+ mpBindings->GetDispatcher()->ExecuteList(SID_NAVIGATOR_OBJECT,
+ SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem });
+
+ if (bCursorEntryObjectHasEmptyName)
+ {
+ bool bUndo = pCursorEntryObject->getSdrModelFromSdrObject().IsUndoEnabled();
+ pCursorEntryObject->getSdrModelFromSdrObject().EnableUndo(false);
+ pCursorEntryObject->SetName(OUString(), false);
+ pCursorEntryObject->getSdrModelFromSdrObject().EnableUndo(bUndo);
+ }
+
+ // re-mark the objects
+ if (bIsCursorEntrySelected)
+ {
+ // Mark the objects in the view that are selected in the Navigator tree.
+ for (auto& rEntryId: vSelectedEntryIds)
+ {
+ if (rEntryId != "1")
+ {
+ SdrObject* pEntryObject = weld::fromId<SdrObject*>(rEntryId);
+ if (pEntryObject)
+ pDrawView->MarkObj(pEntryObject, pDrawView->GetSdrPageView());
+ }
+ }
+ }
+ }
+ else if (nCursorEntryId != 1 && pCursorEntryObject)
+ {
+ // unmark
+ pDrawView->MarkObj(pCursorEntryObject, pDrawView->GetSdrPageView(), true);
+ }
// moved here from SetGetFocusHdl. Reset the
// focus only if something has been selected in the
@@ -316,17 +388,9 @@ IMPL_LINK_NOARG(SdNavigatorWin, ClickObjectHdl, weld::TreeView&, bool)
// still the slide sorter. Explicitly try to grab the draw
// shell focus, so follow-up operations work with the object
// and not with the whole slide.
- sd::DrawDocShell* pDocShell = pInfo->mpDocShell;
- if (pDocShell)
- {
- sd::ViewShell* pViewShell = pDocShell->GetViewShell();
- if (pViewShell)
- {
- vcl::Window* pWindow = pViewShell->GetActiveWindow();
- if (pWindow)
- pWindow->GrabFocus();
- }
- }
+ vcl::Window* pWindow = pViewShell->GetActiveWindow();
+ if (pWindow)
+ pWindow->GrabFocus();
if (!mxTlbObjects->IsNavigationGrabsFocus())
// This is the case when keyboard navigation inside the
diff --git a/sd/source/ui/dlg/sdtreelb.cxx b/sd/source/ui/dlg/sdtreelb.cxx
index 3e86c4bc2376..d63b1cf13645 100644
--- a/sd/source/ui/dlg/sdtreelb.cxx
+++ b/sd/source/ui/dlg/sdtreelb.cxx
@@ -304,7 +304,9 @@ IMPL_LINK(SdPageObjsTLV, KeyInputHdl, const KeyEvent&, rKEvt, bool)
else
m_xTreeView->expand_row(*xCursor);
}
+ m_bNavigationGrabsFocus = true;
m_aRowActivatedHdl.Call(*m_xTreeView);
+ m_bNavigationGrabsFocus = false;
return true;
}
return m_aKeyPressHdl.Call(rKEvt);
@@ -319,6 +321,9 @@ IMPL_LINK(SdPageObjsTLV, MousePressHdl, const MouseEvent&, rMEvt, bool)
IMPL_LINK_NOARG(SdPageObjsTLV, MouseReleaseHdl, const MouseEvent&, bool)
{
+ if (m_aMouseReleaseHdl.IsSet() && m_aMouseReleaseHdl.Call(MouseEvent()))
+ return false;
+
m_bSelectionHandlerNavigates = false;
m_bNavigationGrabsFocus = true;
return false;
@@ -666,7 +671,7 @@ IMPL_LINK_NOARG(SdPageObjsTLV, RowActivatedHdl, weld::TreeView&, bool)
Application::RemoveUserEvent(m_nRowActivateEventId);
// post the event to process row activate after mouse press event
m_nRowActivateEventId = Application::PostUserEvent(LINK(this, SdPageObjsTLV, AsyncRowActivatedHdl));
- return true;
+ return false;
}
IMPL_LINK_NOARG(SdPageObjsTLV, AsyncSelectHdl, void*, void)
@@ -689,30 +694,7 @@ void SdPageObjsTLV::Select()
m_aChangeHdl.Call(*m_xTreeView);
if (m_bSelectionHandlerNavigates)
- {
- // Page items in the tree are given user data value 1.
- // Drawing object items are given user data value of the object pointer they represent.
- sal_Int64 nUserData = m_xTreeView->get_selected_id().toInt64();
- if (nUserData != 1)
- {
- SdrObject* pObject = reinterpret_cast<SdrObject*>(nUserData);
- if (pObject && pObject->GetName().isEmpty())
- {
- const bool bUndo = pObject->getSdrModelFromSdrObject().IsUndoEnabled();
- pObject->getSdrModelFromSdrObject().EnableUndo(false);
- pObject->SetName(m_xTreeView->get_selected_text(), false);
- pObject->getSdrModelFromSdrObject().EnableUndo(bUndo);
- m_aRowActivatedHdl.Call(*m_xTreeView);
- pObject->getSdrModelFromSdrObject().EnableUndo(false);
- pObject->SetName(OUString(), false);
- pObject->getSdrModelFromSdrObject().EnableUndo(bUndo);
- }
- else
- m_aRowActivatedHdl.Call(*m_xTreeView);
- }
- else
- m_aRowActivatedHdl.Call(*m_xTreeView);
- }
+ m_aRowActivatedHdl.Call(*m_xTreeView);
if (!m_pNavigator)
{
@@ -724,7 +706,7 @@ void SdPageObjsTLV::Select()
OUString aURL = INetURLObject(pDocShell->GetMedium()->GetPhysicalName(), INetProtocol::File).GetMainURL(INetURLObject::DecodeMechanism::NONE);
NavigatorDragType eDragType = m_pNavigator->GetNavigatorDragType();
- OUString sSelectedEntry = m_xTreeView->get_selected_text();
+ OUString sSelectedEntry = get_cursor_text(); // what about multiple selections?
aURL += "#" + sSelectedEntry;
INetBookmark aBookmark(aURL, sSelectedEntry);
@@ -791,6 +773,18 @@ std::vector<OUString> SdPageObjsTLV::GetSelectEntryList(const int nDepth) const
return aEntries;
}
+std::vector<OUString> SdPageObjsTLV::GetSelectedEntryIds() const
+{
+ std::vector<OUString> vEntryIds;
+
+ m_xTreeView->selected_foreach([this, &vEntryIds](weld::TreeIter& rEntry){
+ vEntryIds.push_back(m_xTreeView->get_id(rEntry));
+ return false;
+ });
+
+ return vEntryIds;
+}
+
/**
* Checks if it is a draw file and opens the BookmarkDoc depending of
* the provided Docs
diff --git a/sd/source/ui/inc/navigatr.hxx b/sd/source/ui/inc/navigatr.hxx
index 7eeb2551a778..f0b7d1fca5e8 100644
--- a/sd/source/ui/inc/navigatr.hxx
+++ b/sd/source/ui/inc/navigatr.hxx
@@ -158,6 +158,7 @@ private:
DECL_DLLPRIVATE_LINK( MenuSelectHdl, const OString&, void );
DECL_DLLPRIVATE_LINK( ShapeFilterCallback, const OString&, void );
DECL_DLLPRIVATE_LINK( KeyInputHdl, const KeyEvent&, bool );
+ DECL_DLLPRIVATE_STATIC_LINK(SdNavigatorWin, MouseReleaseHdl, const MouseEvent&, bool);
void SetDragImage();
diff --git a/sd/source/ui/inc/sdtreelb.hxx b/sd/source/ui/inc/sdtreelb.hxx
index 84432f180834..38a797519654 100644
--- a/sd/source/ui/inc/sdtreelb.hxx
+++ b/sd/source/ui/inc/sdtreelb.hxx
@@ -105,6 +105,7 @@ private:
Link<weld::TreeView&, void> m_aChangeHdl;
Link<weld::TreeView&, bool> m_aRowActivatedHdl;
Link<const KeyEvent&, bool> m_aKeyPressHdl;
+ Link<const MouseEvent&, bool> m_aMouseReleaseHdl;
/** Return the name of the object. When the object has no user supplied
name and the bCreate flag is <TRUE/> then a name is created
@@ -216,6 +217,11 @@ public:
m_aKeyPressHdl = rLink;
}
+ void connect_mouse_release(const Link<const MouseEvent&, bool>& rLink)
+ {
+ m_aMouseReleaseHdl = rLink;
+ }
+
bool HasSelectedChildren(std::u16string_view rName);
bool SelectEntry(std::u16string_view rName);
void SelectEntry(const SdrObject* pObj);
@@ -265,6 +271,22 @@ public:
m_xTreeView->unselect_all();
}
+ OUString get_cursor_text() const
+ {
+ std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
+ if (m_xTreeView->get_cursor(xIter.get()))
+ return m_xTreeView->get_text(*xIter);
+ return OUString();
+ }
+
+ OUString get_cursor_id() const
+ {
+ std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
+ if (m_xTreeView->get_cursor(xIter.get()))
+ return m_xTreeView->get_id(*xIter);
+ return OUString();
+ }
+
void SetViewFrame(const SfxViewFrame* pViewFrame);
void Fill(const SdDrawDocument*, bool bAllPages, const OUString& rDocName);
@@ -324,6 +346,8 @@ public:
std::vector<OUString> GetSelectEntryList(const int nDepth) const;
+ std::vector<OUString> GetSelectedEntryIds() const;
+
SdDrawDocument* GetBookmarkDoc(SfxMedium* pMedium = nullptr);
bool IsLinkableSelected() const { return m_bLinkableSelected; }
diff --git a/vcl/source/treelist/uiobject.cxx b/vcl/source/treelist/uiobject.cxx
index 89d92808c3fb..4ab051a868e1 100644
--- a/vcl/source/treelist/uiobject.cxx
+++ b/vcl/source/treelist/uiobject.cxx
@@ -157,7 +157,7 @@ void TreeListEntryUIObject::execute(const OUString& rAction, const StringMap& /*
}
else if (rAction == "DOUBLECLICK")
{
- mxTreeList->Select(mpEntry);
+ mxTreeList->SetCurEntry(mpEntry);
mxTreeList->DoubleClickHdl();
}
}