summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Raykowski <raykowj@gmail.com>2020-08-23 09:49:45 -0800
committerJim Raykowski <raykowj@gmail.com>2020-09-30 22:24:39 +0200
commitdda71436b8594fb0669b3ac06c02a3997a0674be (patch)
treea8b6b7a9b4c132029b9de593d6537fbedd737961
parent4ef541855237f6d7bb06cab7a659dfc9a6dd800a (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.cxx207
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());