diff options
-rw-r--r-- | sd/source/ui/dlg/navigatr.cxx | 96 | ||||
-rw-r--r-- | sd/source/ui/dlg/sdtreelb.cxx | 46 | ||||
-rw-r--r-- | sd/source/ui/inc/navigatr.hxx | 1 | ||||
-rw-r--r-- | sd/source/ui/inc/sdtreelb.hxx | 24 | ||||
-rw-r--r-- | vcl/source/treelist/uiobject.cxx | 2 |
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(); } } |