diff options
author | Jim Raykowski <raykowj@gmail.com> | 2020-08-23 09:49:45 -0800 |
---|---|---|
committer | Jim Raykowski <raykowj@gmail.com> | 2020-09-30 22:24:39 +0200 |
commit | dda71436b8594fb0669b3ac06c02a3997a0674be (patch) | |
tree | a8b6b7a9b4c132029b9de593d6537fbedd737961 | |
parent | 4ef541855237f6d7bb06cab7a659dfc9a6dd800a (diff) |
tdf#95378 Writer Navigator document content tracking
This patch adds document content tracking for tables, frames, images,
OLE objects and drawing objects.
Change-Id: I99af15d2da9f4f97d8702b5a9cad4fc21b676166
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101253
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
-rw-r--r-- | sw/source/uibase/utlui/content.cxx | 207 |
1 files changed, 151 insertions, 56 deletions
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 88f9f0979919..ba62299111fd 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -1882,11 +1882,8 @@ IMPL_LINK_NOARG(SwContentTree, ContentDoubleClickHdl, weld::TreeView&, bool) SwContent* pCnt = reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xEntry).toInt64()); assert(pCnt && "no UserData"); GotoContent(pCnt); - const ContentTypeId nActType = pCnt->GetParent()->GetType(); - if (nActType == ContentTypeId::FRAME) - m_pActiveShell->EnterStdMode(); // fdo#36308 don't expand outlines on double-click - bConsumed = nActType == ContentTypeId::OUTLINE; + bConsumed = pCnt->GetParent()->GetType() == ContentTypeId::OUTLINE; } } @@ -3087,6 +3084,42 @@ void SwContentTree::HideTree() m_xTreeView->hide(); } +static void lcl_SelectByContentTypeAndName(SwContentTree* pThis, weld::TreeView& rContentTree, + const OUString& rContentTypeName, const OUString& rName) +{ + if (!rName.isEmpty()) + { + // find content type entry + std::unique_ptr<weld::TreeIter> xIter(rContentTree.make_iterator()); + bool bFoundEntry = rContentTree.get_iter_first(*xIter); + while (bFoundEntry && rContentTypeName != rContentTree.get_text(*xIter)) + bFoundEntry = rContentTree.iter_next_sibling(*xIter); + // find content type content entry and select it + if (bFoundEntry) + { + rContentTree.expand_row(*xIter); // assure content type entry is expanded + while (rContentTree.iter_next(*xIter) && lcl_IsContent(*xIter, rContentTree)) + { + if (rName == rContentTree.get_text(*xIter)) + { + // get first selected for comparison + std::unique_ptr<weld::TreeIter> xFirstSelected(rContentTree.make_iterator()); + if (!rContentTree.get_selected(xFirstSelected.get())) + xFirstSelected.reset(); + if (rContentTree.count_selected_rows() != 1 || + rContentTree.iter_compare(*xIter, *xFirstSelected) != 0) + { + // unselect all entries and make passed entry visible and selected + rContentTree.set_cursor(*xIter); + pThis->Select(); + } + break; + } + } + } + } +} + /** No idle with focus or while dragging */ IMPL_LINK_NOARG(SwContentTree, TimerUpdate, Timer *, void) { @@ -3136,72 +3169,131 @@ void SwContentTree::UpdateTracking() if (State::HIDDEN == m_eState) return; - // track document outline position at cursor - if (m_nOutlineTracking == 3) // no outline tracking - return; - - const SwOutlineNodes::size_type nActPos = GetWrtShell()->GetOutlinePos(MAXLEVEL); // find out where the cursor is - if (nActPos == SwOutlineNodes::npos) + // m_bIgnoreViewChange is set on delete + if (m_bIgnoreViewChange) + { + m_bIgnoreViewChange = false; return; + } - // only track if selection is already an outline - std::unique_ptr<weld::TreeIter> xFirstSelected(m_xTreeView->make_iterator()); - if (!m_xTreeView->get_selected(xFirstSelected.get())) - xFirstSelected.reset(); - if (xFirstSelected && lcl_IsContent(*xFirstSelected, *m_xTreeView) && - reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xFirstSelected).toInt64())->GetParent()->GetType() != ContentTypeId::OUTLINE) + // drawing + if ((m_pActiveShell->GetSelectionType() & (SelectionType::DrawObject | + SelectionType::DrawObjectEditMode)) && + !(m_bIsRoot && m_nRootType != ContentTypeId::DRAWOBJECT)) + { + SdrView* pSdrView = m_pActiveShell->GetDrawView(); + if(pSdrView && 1 == pSdrView->GetMarkedObjectCount()) + { + SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(0); + OUString aName(pSelected->GetName()); + lcl_SelectByContentTypeAndName(this, *m_xTreeView, + SwResId(STR_CONTENT_TYPE_DRAWOBJECT), aName); + } return; - if (xFirstSelected && lcl_IsContentType(*xFirstSelected, *m_xTreeView) && - reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xFirstSelected).toInt64())->GetType() != ContentTypeId::OUTLINE) + } + // graphic, frame, and ole + OUString aContentTypeName; + if (m_pActiveShell->GetSelectionType() == SelectionType::Graphic && + !(m_bIsRoot && m_nRootType != ContentTypeId::GRAPHIC)) + aContentTypeName = SwResId(STR_CONTENT_TYPE_GRAPHIC); + else if (m_pActiveShell->GetSelectionType() == SelectionType::Frame && + !(m_bIsRoot && m_nRootType != ContentTypeId::FRAME)) + aContentTypeName = SwResId(STR_CONTENT_TYPE_FRAME); + else if (m_pActiveShell->GetSelectionType() == SelectionType::Ole && + !(m_bIsRoot && m_nRootType != ContentTypeId::OLE)) + aContentTypeName = SwResId(STR_CONTENT_TYPE_OLE); + if (!aContentTypeName.isEmpty()) + { + OUString aName(m_pActiveShell->GetFlyName()); + lcl_SelectByContentTypeAndName(this, *m_xTreeView, aContentTypeName, aName); return; - - int nSelectedRows = m_xTreeView->count_selected_rows(); - - // find the outline in the tree and select it - m_xTreeView->all_foreach([this, nSelectedRows, nActPos, &xFirstSelected](weld::TreeIter& rEntry){ - bool bRet = false; - - if (lcl_IsContent(rEntry, *m_xTreeView) && - reinterpret_cast<SwContent*>(m_xTreeView->get_id(rEntry).toInt64())->GetParent()->GetType() == ContentTypeId::OUTLINE) + } + // table + if (m_pActiveShell->IsCursorInTable() && + !(m_bIsRoot && m_nRootType != ContentTypeId::TABLE)) + { + if(m_pActiveShell->GetTableFormat()) { - // might have been scrolled out of view by the user so leave it that way - if (reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(rEntry).toInt64())->GetOutlinePos() == nActPos) + OUString aName = m_pActiveShell->GetTableFormat()->GetName(); + lcl_SelectByContentTypeAndName(this, *m_xTreeView, SwResId(STR_CONTENT_TYPE_TABLE), + aName); + } + return; + } + // outline + // find out where the cursor is + const SwOutlineNodes::size_type nActPos = GetWrtShell()->GetOutlinePos(MAXLEVEL); + if (!((m_bIsRoot && m_nRootType != ContentTypeId::OUTLINE) || + m_nOutlineTracking == 3 || nActPos == SwOutlineNodes::npos)) + { + // assure outline content type is expanded + // this assumes outline content type is first in treeview + std::unique_ptr<weld::TreeIter> xFirstEntry(m_xTreeView->make_iterator()); + m_xTreeView->get_iter_first(*xFirstEntry); + m_xTreeView->expand_row(*xFirstEntry); + + m_xTreeView->all_foreach([this, nActPos](weld::TreeIter& rEntry){ + bool bRet = false; + if (lcl_IsContent(rEntry, *m_xTreeView) && reinterpret_cast<SwContent*>( + m_xTreeView->get_id(rEntry).toInt64())->GetParent()->GetType() == + ContentTypeId::OUTLINE) { - // only select if not already selected or tree has multiple entries selected - if (nSelectedRows != 1 || m_xTreeView->iter_compare(rEntry, *xFirstSelected) != 0) + if (reinterpret_cast<SwOutlineContent*>( + m_xTreeView->get_id(rEntry).toInt64())->GetOutlinePos() == nActPos) { - if (m_nOutlineTracking == 2) // focused outline tracking + std::unique_ptr<weld::TreeIter> xFirstSelected( + m_xTreeView->make_iterator()); + if (!m_xTreeView->get_selected(xFirstSelected.get())) + xFirstSelected.reset(); + // only select if not already selected or tree has multiple entries selected + if (m_xTreeView->count_selected_rows() != 1 || + m_xTreeView->iter_compare(rEntry, *xFirstSelected) != 0) { - // collapse to children of root node - std::unique_ptr<weld::TreeIter> xChildEntry(m_xTreeView->make_iterator()); - if (m_xTreeView->get_iter_first(*xChildEntry) && m_xTreeView->iter_children(*xChildEntry)) + if (m_nOutlineTracking == 2) // focused outline tracking { - do + // collapse to children of root node + std::unique_ptr<weld::TreeIter> xChildEntry( + m_xTreeView->make_iterator()); + if (m_xTreeView->get_iter_first(*xChildEntry) && + m_xTreeView->iter_children(*xChildEntry)) { - if (reinterpret_cast<SwContent*>(m_xTreeView->get_id(*xChildEntry).toInt64())->GetParent()->GetType() == ContentTypeId::OUTLINE) - m_xTreeView->collapse_row(*xChildEntry); - else - break; + do + { + if (reinterpret_cast<SwContent*>( + m_xTreeView->get_id(*xChildEntry).toInt64())-> + GetParent()->GetType() == ContentTypeId::OUTLINE) + m_xTreeView->collapse_row(*xChildEntry); + else + break; + } + while (m_xTreeView->iter_next(*xChildEntry)); } - while (m_xTreeView->iter_next(*xChildEntry)); } + // unselect all entries, make pEntry visible, and select + m_xTreeView->set_cursor(rEntry); + Select(); } - m_xTreeView->set_cursor(rEntry); // unselect all entries, make pEntry visible, and select - Select(); + bRet = true; } - bRet = true; } - } - else - { - // use of this break assumes outline content type is first in tree - if (lcl_IsContentType(rEntry, *m_xTreeView) && - reinterpret_cast<SwContentType*>(m_xTreeView->get_id(rEntry).toInt64())->GetType() != ContentTypeId::OUTLINE) - bRet = true; - } - - return bRet; - }); + else + { + // use of this break assumes outline content type is first in tree + if (lcl_IsContentType(rEntry, *m_xTreeView) && + reinterpret_cast<SwContentType*>( + m_xTreeView->get_id(rEntry).toInt64())->GetType() != + ContentTypeId::OUTLINE) + bRet = true; + } + return bRet; + }); + } + else + { + // clear treeview selections + m_xTreeView->unselect_all(); + Select(); + } } void SwContentTree::SelectOutlinesWithSelection() @@ -3940,6 +4032,9 @@ void SwContentTree::EditEntry(const weld::TreeIter& rEntry, EditEntryMode nMode) const ContentTypeId nType = pCnt->GetParent()->GetType(); sal_uInt16 nSlot = 0; + if(EditEntryMode::DELETE == nMode) + m_bIgnoreViewChange = true; + uno::Reference< container::XNameAccess > xNameAccess, xSecond, xThird; switch(nType) { @@ -4134,7 +4229,7 @@ void SwContentTree::EditEntry(const weld::TreeIter& rEntry, EditEntryMode nMode) } if(nSlot) m_pActiveShell->GetView().GetViewFrame()-> - GetDispatcher()->Execute(nSlot, SfxCallMode::ASYNCHRON); + GetDispatcher()->Execute(nSlot, SfxCallMode::SYNCHRON); else if(xNameAccess.is()) { uno::Any aObj = xNameAccess->getByName(pCnt->GetName()); |