From 94891dce760817686600f3a8d25e5eb735a1a133 Mon Sep 17 00:00:00 2001 From: Jim Raykowski Date: Tue, 28 May 2024 13:19:44 -0800 Subject: [PATCH] tdf#160817 SwNavigator expose main functions for selected entry Replaces the headings/outline move action buttons in the tools area with a toolbar to expose the main functions for the selected entry in the content tree. Change-Id: Iedb5b53375088a159d640fb986bfcf9376fa2072 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168174 Tested-by: Jenkins Reviewed-by: Jim Raykowski --- icon-themes/breeze/links.txt | 1 + icon-themes/colibre/links.txt | 1 + icon-themes/elementary/links.txt | 1 + icon-themes/karasa_jaga/links.txt | 1 + icon-themes/sifr/links.txt | 1 + icon-themes/sukapura/links.txt | 1 + .../openoffice/Office/UI/WriterCommands.xcu | 11 + sw/inc/strings.hrc | 2 + sw/qa/uitest/navigator/movechapterupdown.py | 44 +- sw/qa/uitest/navigator/tdf151051.py | 4 +- sw/qa/uitest/navigator/tdf154212.py | 8 +- sw/source/uibase/inc/conttree.hxx | 6 +- sw/source/uibase/inc/navipi.hxx | 12 + sw/source/uibase/utlui/content.cxx | 332 +++++-- sw/source/uibase/utlui/navipi.cxx | 199 +++- sw/uiconfig/swriter/ui/navigatorpanel.ui | 874 ++++++++++++++++-- 16 files changed, 1313 insertions(+), 185 deletions(-) diff --git a/icon-themes/breeze/links.txt b/icon-themes/breeze/links.txt index 23ba813b7107..03d969ae0e0d 100644 --- a/icon-themes/breeze/links.txt +++ b/icon-themes/breeze/links.txt @@ -30,6 +30,7 @@ chart2/res/selectrange.png formula/res/refinp1.png # cmd # ============================================== +cmd/sc_endnotedialog.png cmd/sc_footnotedialog.png # Add cmd/32/adddatefield.png cmd/32/datefield.png diff --git a/icon-themes/colibre/links.txt b/icon-themes/colibre/links.txt index ede4f262cddb..f7fa0cc05107 100644 --- a/icon-themes/colibre/links.txt +++ b/icon-themes/colibre/links.txt @@ -47,6 +47,7 @@ cmd/sc_insertmenulegend.png cmd/sc_legend.png # cmd # ============================================== +cmd/sc_endnotedialog.png cmd/sc_footnotedialog.png # Add cmd/32/adddatefield.png cmd/32/datefield.png diff --git a/icon-themes/elementary/links.txt b/icon-themes/elementary/links.txt index 0c320f04ccbe..cc35e834f5e9 100644 --- a/icon-themes/elementary/links.txt +++ b/icon-themes/elementary/links.txt @@ -52,6 +52,7 @@ cmd/sc_toggleaxisdescr.png cmd/sc_helplinesvisible.png # cmd # ============================================== +cmd/sc_endnotedialog.png cmd/sc_footnotedialog.png # Add cmd/32/adddatefield.png cmd/32/datefield.png diff --git a/icon-themes/karasa_jaga/links.txt b/icon-themes/karasa_jaga/links.txt index d71263a1f279..f360ac6c3ad7 100644 --- a/icon-themes/karasa_jaga/links.txt +++ b/icon-themes/karasa_jaga/links.txt @@ -1283,6 +1283,7 @@ cmd/sc_editregion.png cmd/sc_insertsection.png cmd/sc_editselectmenu.png cmd/sc_selecttables.png cmd/sc_ellipse.png cmd/sc_basicshapes.ellipse.png cmd/sc_ellipsetoolbox.png cmd/sc_basicshapes.ellipse.png +cmd/sc_endnotedialog.png cmd/sc_footnotedialog.png cmd/sc_exitsearch.png cmd/sc_closepreview.png cmd/sc_exportasgraphic.png cmd/sc_graphic.png cmd/sc_exportasmenu.png cmd/sc_exportto.png diff --git a/icon-themes/sifr/links.txt b/icon-themes/sifr/links.txt index 5733722da4cb..ae5e9021ca37 100644 --- a/icon-themes/sifr/links.txt +++ b/icon-themes/sifr/links.txt @@ -57,6 +57,7 @@ cmd/sc_insertmenulegend.png cmd/sc_legend.png # cmd # ============================================== +cmd/sc_endnotedialog.png cmd/sc_footnotedialog.png # Add cmd/32/adddatefield.png cmd/32/datefield.png diff --git a/icon-themes/sukapura/links.txt b/icon-themes/sukapura/links.txt index 9552ccb3dbf5..5bcf699978bd 100644 --- a/icon-themes/sukapura/links.txt +++ b/icon-themes/sukapura/links.txt @@ -60,6 +60,7 @@ cmd/sc_insertmenulegend.png cmd/sc_legend.png # cmd # ============================================== +cmd/sc_endnotedialog.png cmd/sc_footnotedialog.png # Add cmd/32/adddatefield.png cmd/32/datefield.png diff --git a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu index c0fdc8887338..9ae5f1021926 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu @@ -1550,6 +1550,17 @@ 1 + + + ~Footnote/Endnote Settings... + + + .uno:FootnoteDialog + + + 1 + + ~Footnote/Endnote Settings... diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc index 3a70a42cd0bd..97b7b4545054 100644 --- a/sw/inc/strings.hrc +++ b/sw/inc/strings.hrc @@ -717,6 +717,8 @@ #define STR_NEW_FILE NC_("STR_NEW_FILE", "New Document") #define STR_INSERT_TEXT NC_("STR_INSERT_TEXT", "Text") #define STR_DELETE NC_("STR_DELETE", "Delete") +#define STR_DELETE_CONTENT_TYPE NC_("STR_DELETE_CONTENT_TYPE", "Delete All %1") +#define STR_DELETE_CONTENT NC_("STR_DELETE_CONTENT", "Delete %1") #define STR_DELETE_ENTRY NC_("STR_DELETE_ENTRY", "~Delete") #define STR_UPDATE_SEL NC_("STR_UPDATE_SEL", "Selection") #define STR_UPDATE_INDEX NC_("STR_UPDATE_INDEX", "Indexes") diff --git a/sw/qa/uitest/navigator/movechapterupdown.py b/sw/qa/uitest/navigator/movechapterupdown.py index 0b4c7ef5f540..d90400ef89b8 100644 --- a/sw/qa/uitest/navigator/movechapterupdown.py +++ b/sw/qa/uitest/navigator/movechapterupdown.py @@ -62,8 +62,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter up' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "4"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "2"})) # Expected chapter order: # 2. Two (H1) @@ -104,8 +104,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter down' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "5"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "3"})) # Expected chapter order is the original order xNavigatorPanelContentTreeHeadings = xNavigatorPanelContentTree.getChild('0') @@ -146,8 +146,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter down' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "5"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "3"})) # Expected chapter order: # 1. One (H1) @@ -188,8 +188,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter up' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "4"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "2"})) # Expected chapter order is the original order xNavigatorPanelContentTreeHeadings = xNavigatorPanelContentTree.getChild('0') @@ -231,8 +231,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter up' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "4"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "2"})) # Expected chapter order: # 1. One H1 @@ -275,8 +275,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter down' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "5"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "3"})) # Expected chapter order: # 1. One H1 @@ -327,13 +327,13 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter up' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "4"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "2"})) # Click on the 'Move chapter up' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "4"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "2"})) # Expected chapter order: # 1. One H1 @@ -384,8 +384,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter down' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "5"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "3"})) # Expected chapter order is the original order xNavigatorPanelContentTreeHeadings = xNavigatorPanelContentTree.getChild('0') @@ -427,8 +427,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter up' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "4"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "2"})) # Expected chapter order: # 1.1. One_A (H2) @@ -470,8 +470,8 @@ class movechapterupdown(UITestCase): # Click on the 'Move chapter down' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "5"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "3"})) # Expected chapter order is the original order xNavigatorPanelContentTreeHeadings = xNavigatorPanelContentTree.getChild('0') diff --git a/sw/qa/uitest/navigator/tdf151051.py b/sw/qa/uitest/navigator/tdf151051.py index 03889c7f49fb..2005a85414da 100644 --- a/sw/qa/uitest/navigator/tdf151051.py +++ b/sw/qa/uitest/navigator/tdf151051.py @@ -41,8 +41,8 @@ class tdf151051(UITestCase): self.assertEqual('0', get_state_as_dict(xChild)['Children']) xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBar = xNavigatorPanel.getChild("content6") - xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "2"})) # 'promote' button + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "0"})) # 'promote' button xHeadings = xContentTree.getChild('0') xHeadings.executeAction("EXPAND", tuple()) diff --git a/sw/qa/uitest/navigator/tdf154212.py b/sw/qa/uitest/navigator/tdf154212.py index 00a39a73b980..0aaa8e04b23f 100644 --- a/sw/qa/uitest/navigator/tdf154212.py +++ b/sw/qa/uitest/navigator/tdf154212.py @@ -48,8 +48,8 @@ class tdf154212(UITestCase): # click on the 'move chapter down' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "5"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "3"})) self.ui_test.wait_until_property_is_updated(xNavigatorPanelContentTree, "SelectEntryText", "MOVE THIS Heading level 2") @@ -62,8 +62,8 @@ class tdf154212(UITestCase): # click on the 'move chapter up' button in the Navigator tool box xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") - xToolBarContent6 = xNavigatorPanel.getChild("content6") - xToolBarContent6.executeAction("CLICK", mkPropertyValues({"POS": "4"})) + xToolBar = xNavigatorPanel.getChild("HeadingsContentFunctionButtonsToolbar") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "2"})) self.ui_test.wait_until_property_is_updated(xNavigatorPanelContentTree, "SelectEntryText", "MOVE THIS Heading level 2") diff --git a/sw/source/uibase/inc/conttree.hxx b/sw/source/uibase/inc/conttree.hxx index 824de8022505..a06ef17c1bdf 100644 --- a/sw/source/uibase/inc/conttree.hxx +++ b/sw/source/uibase/inc/conttree.hxx @@ -88,6 +88,8 @@ public: /** TreeListBox for content indicator */ class SwContentTree final : public SfxListener { + friend class SwNavigationPI; + std::unique_ptr m_xTreeView; SwContentTreeDropTarget m_aDropTargetHelper; SwNavigationPI* m_pDialog; @@ -203,6 +205,8 @@ class SwContentTree final : public SfxListener bool IsDeletable(const SwContent* pContent); void DeleteAllContentOfEntryContentType(const weld::TreeIter& rEntry); + bool IsSelectedEntryCurrentDocCursorPosition(const weld::TreeIter& rEntry); + /** Expand - Remember the state for content types */ DECL_LINK(ExpandHdl, const weld::TreeIter&, bool); /** Collapse - Remember the state for content types. */ @@ -270,7 +274,7 @@ public: const SwWrtShell* GetActiveWrtShell() const {return m_pActiveShell;} SwWrtShell* GetHiddenWrtShell() {return m_pHiddenShell;} - void Select(); + void UpdateContentFunctionsToolbar(); void UpdateTracking(); void SelectOutlinesWithSelection(); diff --git a/sw/source/uibase/inc/navipi.hxx b/sw/source/uibase/inc/navipi.hxx index ff0731621b87..a90cbc667169 100644 --- a/sw/source/uibase/inc/navipi.hxx +++ b/sw/source/uibase/inc/navipi.hxx @@ -51,6 +51,8 @@ class SwNavigationPI final : public PanelLayout ::sfx2::sidebar::ControllerItem m_aPageStats; ::sfx2::sidebar::ControllerItem m_aNavElement; + css::uno::Reference m_xFrame; + std::unique_ptr m_xContent1ToolBox; std::unique_ptr m_xContent2ToolBox; std::unique_ptr m_xContent3ToolBox; @@ -89,6 +91,16 @@ class SwNavigationPI final : public PanelLayout weld::ComboBox* m_pNavigateByComboBox; + std::unique_ptr m_xHeadingsContentFunctionsToolbar; + std::unique_ptr m_xDeleteFunctionToolbar; + std::unordered_map> m_aContentTypeUnoToolbarMap; + std::unordered_map> m_aContentTypeToolbarUnoDispatcherMap; + std::unordered_map> m_aContentUnoToolbarMap; + std::unordered_map> m_aContentToolbarUnoDispatcherMap; + void InitContentFunctionsToolbar(); + void UpdateContentFunctionsToolbar(); + DECL_LINK(ContentFunctionsToolbarSelectHdl, const OUString&, void ); + bool IsZoomedIn() const {return m_bIsZoomedIn;} void ZoomOut(); void ZoomIn(); diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index dbaed5258a8c..b3e35752dde6 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -3043,9 +3043,9 @@ void SwContentTree::Display( bool bActive ) // set_cursor unselects all entries, makes passed entry visible, and selects it m_xTreeView->set_cursor(*xSelEntry); } - } - Select(); + UpdateContentFunctionsToolbar(); + } if (!m_bIgnoreDocChange && GetEntryCount() == nOldEntryCount) { @@ -3723,7 +3723,7 @@ void SwContentTree::Notify(SfxBroadcaster & rBC, SfxHint const& rHint) if (m_xTreeView->get_cursor(xEntry.get())) { m_xTreeView->select(*xEntry); - Select(); + UpdateContentFunctionsToolbar(); } else m_xTreeView->unselect_all(); @@ -4038,7 +4038,7 @@ static void lcl_SelectByContentTypeAndAddress(SwContentTree* pThis, weld::TreeVi if (!ptr) { rContentTree.set_cursor(-1); - pThis->Select(); + pThis->UpdateContentFunctionsToolbar(); return; } @@ -4058,7 +4058,7 @@ static void lcl_SelectByContentTypeAndAddress(SwContentTree* pThis, weld::TreeVi if (!bFoundEntry) { rContentTree.set_cursor(-1); - pThis->Select(); + pThis->UpdateContentFunctionsToolbar(); return; } @@ -4115,14 +4115,14 @@ static void lcl_SelectByContentTypeAndAddress(SwContentTree* pThis, weld::TreeVi { // unselect all entries and make passed entry visible and selected rContentTree.set_cursor(*xIter); - pThis->Select(); + pThis->UpdateContentFunctionsToolbar(); } return; } } rContentTree.set_cursor(-1); - pThis->Select(); + pThis->UpdateContentFunctionsToolbar(); return; } @@ -4155,14 +4155,15 @@ static void lcl_SelectByContentTypeAndName(SwContentTree* pThis, weld::TreeView& { // unselect all entries and make passed entry visible and selected rContentTree.set_cursor(*xIter); - pThis->Select(); + pThis->UpdateContentFunctionsToolbar(); } break; } } } -static void lcl_SelectDrawObjectByName(weld::TreeView& rContentTree, std::u16string_view rName) +static void lcl_SelectDrawObjectByName(SwContentTree* pThis, weld::TreeView& rContentTree, + std::u16string_view rName) { if (rName.empty()) return; @@ -4184,6 +4185,7 @@ static void lcl_SelectDrawObjectByName(weld::TreeView& rContentTree, std::u16str { rContentTree.select(*xIter); rContentTree.scroll_to_row(*xIter); + pThis->UpdateContentFunctionsToolbar(); } break; } @@ -4324,15 +4326,15 @@ void SwContentTree::UpdateTracking() SdrObject* pSelected = pSdrView->GetMarkedObjectList().GetMark(nIdx)->GetMarkedSdrObj(); OUString aName(pSelected->GetName()); if (!aName.isEmpty()) - lcl_SelectDrawObjectByName(*m_xTreeView, aName); + lcl_SelectDrawObjectByName(this, *m_xTreeView, aName); } } else { // clear treeview selections m_xTreeView->unselect_all(); + UpdateContentFunctionsToolbar(); } - Select(); } return; } @@ -4494,7 +4496,7 @@ void SwContentTree::UpdateTracking() } // unselect all entries, make pEntry visible, and select m_xTreeView->set_cursor(rEntry); - Select(); + UpdateContentFunctionsToolbar(); // tdf#149279 show at least two outline entries before the set cursor entry std::unique_ptr xIter(m_xTreeView->make_iterator(&rEntry)); @@ -4584,10 +4586,265 @@ void SwContentTree::UpdateTracking() { m_xTreeView->unselect_all(); m_xTreeView->set_cursor(-1); - Select(); + UpdateContentFunctionsToolbar(); } } +static bool lcl_IsSelectedCompareByContentTypeAndAddress(const weld::TreeIter& rEntry, + weld::TreeView& rContentTree, + ContentTypeId eContentType, + const void* ptr) +{ + if (!ptr) + return false; + + std::unique_ptr xIter(rContentTree.make_iterator()); + + // find content type entry + bool bFoundEntry = rContentTree.get_iter_first(*xIter); + while (bFoundEntry) + { + assert(dynamic_cast(weld::fromId(rContentTree.get_id(*xIter)))); + SwContentType* pContentType = weld::fromId(rContentTree.get_id(*xIter)); + if (eContentType == pContentType->GetType()) + break; + bFoundEntry = rContentTree.iter_next_sibling(*xIter); + } + + if (!bFoundEntry) + return false; + + // find content type content entry and compare it to the passed entry + const void* p = nullptr; + while (rContentTree.iter_next(*xIter) && lcl_IsContent(*xIter, rContentTree)) + { + assert(dynamic_cast(weld::fromId(rContentTree.get_id(*xIter)))); + SwContent* pContent = weld::fromId(rContentTree.get_id(*xIter)); + switch (eContentType) + { + case ContentTypeId::FOOTNOTE: + case ContentTypeId::ENDNOTE: + { + assert(dynamic_cast(static_cast(pContent))); + SwTextFootnoteContent* pCnt = static_cast(pContent); + p = pCnt->GetTextFootnote(); + break; + } + case ContentTypeId::URLFIELD: + { + assert(dynamic_cast(static_cast(pContent))); + SwURLFieldContent* pCnt = static_cast(pContent); + p = static_cast(pCnt->GetINetAttr()); + break; + } + case ContentTypeId::TEXTFIELD: + { + assert(dynamic_cast(static_cast(pContent))); + SwTextFieldContent* pCnt = static_cast(pContent); + p = pCnt->GetFormatField()->GetField(); + break; + } + case ContentTypeId::POSTIT: + { + assert(dynamic_cast(static_cast(pContent))); + SwPostItContent* pCnt = static_cast(pContent); + p = pCnt->GetPostIt()->GetField(); + break; + } + case ContentTypeId::INDEX: + { + assert(dynamic_cast(static_cast(pContent))); + SwTOXBaseContent* pCnt = static_cast(pContent); + p = pCnt->GetTOXBase(); + break; + } + default: + break; + } + if (ptr == p) + return rContentTree.iter_compare(*xIter, rEntry) == 0; + } + return false; +} + +static bool lcl_IsSelectedCompareByContentTypeAndName(const weld::TreeIter& rEntry, + weld::TreeView& rContentTree, + ContentTypeId eContentType, + std::u16string_view rName) +{ + std::unique_ptr xIter(rContentTree.make_iterator()); + + // find content type entry + bool bFoundEntry = rContentTree.get_iter_first(*xIter); + while (bFoundEntry) + { + assert(dynamic_cast(weld::fromId(rContentTree.get_id(*xIter)))); + SwContentType* pContentType = weld::fromId(rContentTree.get_id(*xIter)); + if (eContentType == pContentType->GetType()) + break; + bFoundEntry = rContentTree.iter_next_sibling(*xIter); + } + + if (!bFoundEntry) + return false; + + // find content type content entry and compare it to the passed entry + while (rContentTree.iter_next(*xIter)) + { + if (rName == rContentTree.get_text(*xIter)) + { + if (rContentTree.iter_compare(*xIter, rEntry) == 0) + return true; + } + } + return false; +} + +bool SwContentTree::IsSelectedEntryCurrentDocCursorPosition(const weld::TreeIter& rEntry) +{ + if (State::HIDDEN == m_eState || !m_pActiveShell) + return false; + + // table + if (m_pActiveShell->IsCursorInTable()) + { + return lcl_IsSelectedCompareByContentTypeAndName( + rEntry, *m_xTreeView, ContentTypeId::TABLE, + m_pActiveShell->GetTableFormat()->GetName()); + } + // graphic, frame, and ole + if (m_pActiveShell->GetSelectionType() + & (SelectionType::Graphic | SelectionType::Frame | SelectionType::Ole)) + { + ContentTypeId eContentTypeId; + if (m_pActiveShell->GetSelectionType() == SelectionType::Graphic) + eContentTypeId = ContentTypeId::GRAPHIC; + else if (m_pActiveShell->GetSelectionType() == SelectionType::Frame) + eContentTypeId = ContentTypeId::FRAME; + else if (m_pActiveShell->GetSelectionType() == SelectionType::Ole) + eContentTypeId = ContentTypeId::OLE; + else // to quiet compiler warning/error + return false; + return lcl_IsSelectedCompareByContentTypeAndName(rEntry, *m_xTreeView, eContentTypeId, + m_pActiveShell->GetFlyName()); + } + // hyperlinks + // not in ToxContent tdf#148312 <- does this apply here? + if (const SwSection* pSection = m_pActiveShell->GetCurrSection(); + !pSection || (pSection && pSection->GetType() != SectionType::ToxContent)) + { + if (SwContentAtPos aContentAtPos(IsAttrAtPos::InetAttr); + m_pActiveShell->GetContentAtPos(m_pActiveShell->GetCursorDocPos(), aContentAtPos)) + { + // Because hyperlink item names do not need to be unique, finding the corresponding + // item in the tree by name may result in incorrect selection. Find the item in the + // tree by comparing the SwTextINetFormat pointer at the document cursor position to + // that stored in the item SwURLFieldContent. + return lcl_IsSelectedCompareByContentTypeAndAddress( + rEntry, *m_xTreeView, ContentTypeId::URLFIELD, aContentAtPos.pFndTextAttr); + } + } + // references + if (SwContentAtPos aContentAtPos(IsAttrAtPos::RefMark); + m_pActiveShell->GetContentAtPos(m_pActiveShell->GetCursorDocPos(), aContentAtPos) + && aContentAtPos.pFndTextAttr) + { + const SwFormatRefMark& rRefMark = aContentAtPos.pFndTextAttr->GetRefMark(); + return lcl_IsSelectedCompareByContentTypeAndName( + rEntry, *m_xTreeView, ContentTypeId::REFERENCE, rRefMark.GetRefName()); + } + // indexes + if (const SwTOXBase* pTOXBase = m_pActiveShell->GetCurTOX()) + { + return lcl_IsSelectedCompareByContentTypeAndAddress(rEntry, *m_xTreeView, + ContentTypeId::INDEX, pTOXBase); + // alternatively: + // return lcl_IsSelectedCompareByContentTypeAndName(rEntry, *m_xTreeView, + // ContentTypeId::INDEX, + // pTOX->GetTOXName()); + } + // fields, comments + if (SwField* pField = m_pActiveShell->GetCurField()) + { + ContentTypeId eContentTypeId = pField->GetTypeId() == SwFieldTypesEnum::Postit + ? ContentTypeId::POSTIT + : ContentTypeId::TEXTFIELD; + return lcl_IsSelectedCompareByContentTypeAndAddress(rEntry, *m_xTreeView, eContentTypeId, + pField); + } + // drawing + if (m_pActiveShell->GetSelectionType() + & (SelectionType::DrawObject | SelectionType::DrawObjectEditMode | SelectionType::DbForm)) + { + SdrView* pSdrView = m_pActiveShell->GetDrawView(); + if (!pSdrView) + return false; + // ONLY CHECKS FIRST MARKED OBJECT + for (size_t nIdx = 0; nIdx < pSdrView->GetMarkedObjectList().GetMarkCount(); nIdx++) + { + SdrObject* pObject = pSdrView->GetMarkedObjectList().GetMark(nIdx)->GetMarkedSdrObj(); + if (lcl_IsSelectedCompareByContentTypeAndName( + rEntry, *m_xTreeView, ContentTypeId::DRAWOBJECT, pObject->GetName())) + return true; + } + return false; + } + // footnotes and endnotes + if (SwContentAtPos aContentAtPos(IsAttrAtPos::Ftn); + m_pActiveShell->GetContentAtPos(m_pActiveShell->GetCursorDocPos(), aContentAtPos) + && aContentAtPos.pFndTextAttr) + { + ContentTypeId eContentTypeId = aContentAtPos.pFndTextAttr->GetFootnote().IsEndNote() + ? ContentTypeId::ENDNOTE + : ContentTypeId::FOOTNOTE; + return lcl_IsSelectedCompareByContentTypeAndAddress(rEntry, *m_xTreeView, eContentTypeId, + aContentAtPos.pFndTextAttr); + } + // section + if (const SwSection* pSection = m_pActiveShell->GetCurrSection()) + { + return lcl_IsSelectedCompareByContentTypeAndName( + rEntry, *m_xTreeView, ContentTypeId::REGION, pSection->GetSectionName()); + } + // bookmark (unsure about this) + if (m_pActiveShell->GetSelectionType() & SelectionType::Text) + { + SwPaM* pCursor = m_pActiveShell->GetCursor(); + IDocumentMarkAccess* const pMarkAccess = m_pActiveShell->getIDocumentMarkAccess(); + IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin(); + if (pCursor && ppBookmark != pMarkAccess->getBookmarksEnd()) + { + OUString sBookmarkName; + SwPosition* pCursorPoint = pCursor->GetPoint(); + while (ppBookmark != pMarkAccess->getBookmarksEnd()) + { + if (lcl_IsUiVisibleBookmark(*ppBookmark) + && *pCursorPoint >= (*ppBookmark)->GetMarkStart() + && *pCursorPoint <= (*ppBookmark)->GetMarkEnd()) + { + sBookmarkName = (*ppBookmark)->GetName(); + // keep previously selected bookmark instead + // of selecting a different bookmark inside of it + if (sBookmarkName == m_sSelectedItem) + return lcl_IsSelectedCompareByContentTypeAndName( + rEntry, *m_xTreeView, ContentTypeId::BOOKMARK, sBookmarkName); + } + else if (!sBookmarkName.isEmpty() && *pCursorPoint < (*ppBookmark)->GetMarkStart()) + { + // don't search a different bookmark inside the + // previous one, if the starting position of the next bookmarks + // is after the cursor position (assuming that the + // bookmark iterator jumps inside the same text by positions) + return lcl_IsSelectedCompareByContentTypeAndName( + rEntry, *m_xTreeView, ContentTypeId::BOOKMARK, sBookmarkName); + } + ++ppBookmark; + } + } + } + return false; +} + void SwContentTree::SelectOutlinesWithSelection() { SwCursor* pFirstCursor = m_pActiveShell->GetCursor(); @@ -4639,7 +4896,7 @@ void SwContentTree::SelectOutlinesWithSelection() }); } - Select(); + UpdateContentFunctionsToolbar(); } void SwContentTree::MoveOutline(SwOutlineNodes::size_type nTargetPos) @@ -5034,17 +5291,6 @@ IMPL_LINK(SwContentTree, QueryTooltipHdl, const weld::TreeIter&, rEntry, OUStrin void SwContentTree::ExecuteContextMenuAction(const OUString& rSelectedPopupEntry) { - - if(rSelectedPopupEntry == "showcomments") - { - m_pActiveShell->GetView().GetViewFrame().GetDispatcher()->Execute(SID_TOGGLE_NOTES); - return; - } - if(rSelectedPopupEntry == "showresolvedcomments") - { - m_pActiveShell->GetView().GetViewFrame().GetDispatcher()->Execute(SID_TOGGLE_RESOLVED_NOTES); - return; - } if (rSelectedPopupEntry == "copy") { CopyOutlineSelections(); @@ -5477,7 +5723,7 @@ IMPL_LINK_NOARG(SwContentTree, SelectHdl, weld::TreeView&, void) ContentDoubleClickHdl(*m_xTreeView); grab_focus(); } - Select(); + UpdateContentFunctionsToolbar(); if (m_bIsRoot) return; // Select the content type in the Navigate By control @@ -5489,32 +5735,11 @@ IMPL_LINK_NOARG(SwContentTree, SelectHdl, weld::TreeView&, void) m_pDialog->SelectNavigateByContentType(m_xTreeView->get_text(*xEntry)); } -// Here the buttons for moving outlines are en-/disabled. -// The buttons for moving outlines are disabled when the Navigator is in "Zoom" mode or when -// the document is in read-only mode or when the outline content is displayed alphabetically -// sorted or when the selected entry is not outline content. -void SwContentTree::Select() +void SwContentTree::UpdateContentFunctionsToolbar() { SwNavigationPI* pNavi = GetParentWindow(); - - bool bEnable = false; - - if (!pNavi->IsZoomedIn() && !m_bIsLastReadOnly) - { - std::unique_ptr xEntry(m_xTreeView->make_iterator()); - if (m_xTreeView->get_selected(xEntry.get()) && lcl_IsContent(*xEntry, *m_xTreeView)) - { - const SwContentType* pCntType = - weld::fromId(m_xTreeView->get_id(*xEntry))->GetParent(); - if (pCntType->GetType() == ContentTypeId::OUTLINE && !pCntType->IsAlphabeticSort()) - bEnable = true; - } - } - - pNavi->m_xContent6ToolBox->set_item_sensitive(u"chapterup"_ustr, bEnable); - pNavi->m_xContent6ToolBox->set_item_sensitive(u"chapterdown"_ustr, bEnable); - pNavi->m_xContent6ToolBox->set_item_sensitive(u"promote"_ustr, bEnable); - pNavi->m_xContent6ToolBox->set_item_sensitive(u"demote"_ustr, bEnable); + if (pNavi) + pNavi->UpdateContentFunctionsToolbar(); } void SwContentTree::SetRootType(ContentTypeId nType) @@ -6308,8 +6533,7 @@ void SwContentTree::GotoContent(const SwContent* pCnt) if(m_pActiveShell->GotoINetAttr( *static_cast(pCnt)->GetINetAttr() )) { - m_pActiveShell->Right( SwCursorSkipMode::Chars, true, 1, false); - m_pActiveShell->SwCursorShell::SelectTextAttr( RES_TXTATR_INETFMT, true ); + m_pActiveShell->Right(SwCursorSkipMode::Chars, false, 1, false); } } break; @@ -6391,6 +6615,8 @@ void SwContentTree::GotoContent(const SwContent* pCnt) rView.SetVisArea(aPoint); } } + + UpdateContentFunctionsToolbar(); } NaviContentBookmark::NaviContentBookmark() : @@ -6449,7 +6675,7 @@ void SwContentTree::SelectContentType(std::u16string_view rContentTypeName) if (m_xTreeView->get_text(*xIter) == rContentTypeName) { m_xTreeView->set_cursor(*xIter); - Select(); + UpdateContentFunctionsToolbar(); break; } } while (m_xTreeView->iter_next_sibling(*xIter)); diff --git a/sw/source/uibase/utlui/navipi.cxx b/sw/source/uibase/utlui/navipi.cxx index 7db3f3d8c2df..4db946c53e5f 100644 --- a/sw/source/uibase/utlui/navipi.cxx +++ b/sw/source/uibase/utlui/navipi.cxx @@ -51,6 +51,9 @@ #include +#include +#include + using namespace ::com::sun::star::uno; using namespace ::com::sun::star::frame; @@ -273,23 +276,12 @@ IMPL_LINK(SwNavigationPI, ToolBoxSelectHdl, const OUString&, rCommand, void) { rSh.GetView().GetViewFrame().GetDispatcher()->Execute(FN_SET_REMINDER, SfxCallMode::ASYNCHRON); } - else if (rCommand == "chapterdown" || - rCommand == "movedown" || - rCommand == "chapterup" || + else if (rCommand == "movedown" || rCommand == "moveup" || - rCommand == "promote" || - rCommand == "demote" || rCommand == "edit") { if (IsGlobalMode()) m_xGlobalTree->ExecCommand(rCommand); - else - { - // Standard: sublevels are taken - // do not take sublevels with Ctrl - bool bOutlineWithChildren = (KEY_MOD1 != m_xContent6ToolBox->get_modifier_state()); - m_xContentTree->ExecCommand(rCommand, bOutlineWithChildren); - } } else if (rCommand == "contenttoggle" || rCommand == "globaltoggle") { @@ -371,7 +363,7 @@ void SwNavigationPI::ZoomOut() pNav->SetMinOutputSizePixel(aOptimalSize); pNav->SetOutputSizePixel(aNewSize); - m_xContentTree->Select(); // Enable toolbox + m_xContentTree->UpdateContentFunctionsToolbar(); // Enable toolbox m_pConfig->SetSmall(false); m_xContent6ToolBox->set_item_active(u"listbox"_ustr, true); } @@ -400,7 +392,7 @@ void SwNavigationPI::ZoomIn() pNav->SetMinOutputSizePixel(aOptimalSize); pNav->SetOutputSizePixel(aNewSize); - m_xContentTree->Select(); // Enable toolbox + m_xContentTree->UpdateContentFunctionsToolbar(); // Enable toolbox m_pConfig->SetSmall(true); m_xContent6ToolBox->set_item_active(u"listbox"_ustr, false); @@ -426,6 +418,7 @@ SwNavigationPI::SwNavigationPI(weld::Widget* pParent, , m_aDocFullName(SID_DOCFULLNAME, *_pBindings, *this) , m_aPageStats(FN_STAT_PAGE, *_pBindings, *this) , m_aNavElement(FN_NAV_ELEMENT, *_pBindings, *this) + , m_xFrame(rxFrame) , m_xContent1ToolBox(m_xBuilder->weld_toolbar(u"content1"_ustr)) , m_xContent2ToolBox(m_xBuilder->weld_toolbar(u"content2"_ustr)) , m_xContent3ToolBox(m_xBuilder->weld_toolbar(u"content3"_ustr)) @@ -454,6 +447,8 @@ SwNavigationPI::SwNavigationPI(weld::Widget* pParent, , m_bIsZoomedIn(false) , m_bGlobalMode(false) { + InitContentFunctionsToolbar(); + m_xContainer->connect_container_focus_changed(LINK(this, SwNavigationPI, SetFocusChildHdl)); Reference xController = @@ -585,6 +580,182 @@ SwNavigationPI::SwNavigationPI(weld::Widget* pParent, } } +void SwNavigationPI::InitContentFunctionsToolbar() +{ + m_xHeadingsContentFunctionsToolbar + = m_xBuilder->weld_toolbar("HeadingsContentFunctionButtonsToolbar"); + m_xDeleteFunctionToolbar = m_xBuilder->weld_toolbar("DeleteFunctionButtonToolbar"); + + const OUString sContentTypes[] + = { "Headings", "Tables", "Frames", "Images", "OLEobjects", + "Bookmarks", "Sections", "Hyperlinks", "References", "Indexes", + "Comments", "Drawingobjects", "Fields", "Footnotes", "Endnotes" }; + + for (ContentTypeId eContentTypeId : o3tl::enumrange()) + { + if (eContentTypeId == ContentTypeId::OUTLINE) + continue; + m_aContentTypeUnoToolbarMap[eContentTypeId] = m_xBuilder->weld_toolbar( + sContentTypes[static_cast(eContentTypeId)] + "ContentTypeUnoToolbar"); + m_aContentTypeToolbarUnoDispatcherMap[eContentTypeId] + = std::make_unique(*m_aContentTypeUnoToolbarMap[eContentTypeId], + *m_xBuilder, m_xFrame); + m_aContentUnoToolbarMap[eContentTypeId] = m_xBuilder->weld_toolbar( + sContentTypes[static_cast(eContentTypeId)] + "ContentUnoToolbar"); + m_aContentToolbarUnoDispatcherMap[eContentTypeId] = std::make_unique( + *m_aContentUnoToolbarMap[eContentTypeId], *m_xBuilder, m_xFrame); + } + + Link aLink + = LINK(this,SwNavigationPI, ContentFunctionsToolbarSelectHdl); + m_xHeadingsContentFunctionsToolbar->connect_clicked(aLink); + m_xDeleteFunctionToolbar->connect_clicked(aLink); +} + +namespace +{ +bool lcl_ToolbarHasItemWithIdent(weld::Toolbar& rToolbar, std::u16string_view rIdent) +{ + for (auto i = 0; i < rToolbar.get_n_items(); i++) + { + if (rToolbar.get_item_ident(i) == rIdent) + return true; + } + return false; +} +} + +void SwNavigationPI::UpdateContentFunctionsToolbar() +{ + m_xHeadingsContentFunctionsToolbar->hide(); + for (ContentTypeId eContentTypeId : o3tl::enumrange()) + { + if (eContentTypeId == ContentTypeId::OUTLINE) + continue; + m_aContentTypeUnoToolbarMap[eContentTypeId]->hide(); + m_aContentUnoToolbarMap[eContentTypeId]->hide(); + } + m_xDeleteFunctionToolbar->hide(); + + weld::TreeView& rTreeView = m_xContentTree->get_widget(); + + if (IsZoomedIn() || !rTreeView.is_visible()) + return; + + std::unique_ptr xEntry(rTreeView.make_iterator()); + if (!rTreeView.get_selected(xEntry.get())) + return; + + bool bUseDeleteFunctionsToolbar = true; + OUString aContentTypeName; // used in creation of delete button tooltip + + const bool bContentType + = weld::fromId(rTreeView.get_id(*xEntry))->GetTypeId() == 1; + + if (bContentType) + { + const SwContentType* pContentType = weld::fromId(rTreeView.get_id(*xEntry)); + + aContentTypeName = pContentType->GetName(); + + ContentTypeId eContentTypeId = pContentType->GetType(); + if (eContentTypeId == ContentTypeId::OUTLINE) + return; + weld::Toolbar& rContentTypeToolbar = *m_aContentTypeUnoToolbarMap[eContentTypeId]; + if (rContentTypeToolbar.get_n_items()) + { + if (eContentTypeId == ContentTypeId::POSTIT) + { + // prefer .uno:DeleteAllNotes over delete functions toolbar + bUseDeleteFunctionsToolbar + = !lcl_ToolbarHasItemWithIdent(rContentTypeToolbar, u".uno:DeleteAllNotes"); + } + rContentTypeToolbar.show(); + } + } + else + { + const SwContentType* pContentType + = weld::fromId(rTreeView.get_id(*xEntry))->GetParent(); + + aContentTypeName = pContentType->GetSingleName(); + + ContentTypeId eContentTypeId = pContentType->GetType(); + if (eContentTypeId == ContentTypeId::OUTLINE) + { + m_xHeadingsContentFunctionsToolbar->show(); + } + else if (m_xContentTree->IsSelectedEntryCurrentDocCursorPosition(*xEntry)) + { + weld::Toolbar& rContentTypeToolbar = *m_aContentUnoToolbarMap[eContentTypeId]; + if (rContentTypeToolbar.get_n_items()) + { + if (eContentTypeId == ContentTypeId::TABLE) + { + // prefer .uno:DeleteTable over delete functions toolbar + bUseDeleteFunctionsToolbar + = !lcl_ToolbarHasItemWithIdent(rContentTypeToolbar, u".uno:DeleteTable"); + } + else if (eContentTypeId == ContentTypeId::INDEX) + { + // prefer .uno:RemoveTableOf over delete functions toolbar + bUseDeleteFunctionsToolbar + = !lcl_ToolbarHasItemWithIdent(rContentTypeToolbar, u".uno:RemoveTableOf"); + } + rContentTypeToolbar.show(); + } + } + } + + if (bUseDeleteFunctionsToolbar && m_xContentTree->IsDeletable(*xEntry)) + { + OUString sToolTip = SwResId(bContentType ? STR_DELETE_CONTENT_TYPE : STR_DELETE_CONTENT); + sToolTip = sToolTip.replaceFirst("%1", aContentTypeName); + m_xDeleteFunctionToolbar->set_item_tooltip_text("delete", sToolTip); + m_xDeleteFunctionToolbar->show(); + } +} + +IMPL_LINK(SwNavigationPI, ContentFunctionsToolbarSelectHdl, const OUString&, rCommand, void) +{ + weld::TreeView& rTreeView = m_xContentTree->get_widget(); + + std::unique_ptr xEntry(rTreeView.make_iterator()); + if (!rTreeView.get_selected(xEntry.get())) + return; + + const bool bContentEntry + = weld::fromId(rTreeView.get_id(*xEntry))->GetTypeId() == 0; + + if (bContentEntry) + { + SwContent* pContent = weld::fromId(rTreeView.get_id(*xEntry)); + if (pContent) + m_xContentTree->GotoContent(pContent); + } + + if (rCommand == "chapterdown" || rCommand == "chapterup" || rCommand == "promote" + || rCommand == "demote") + { + // Get MouseModifier for Outline-Move + // Standard: sublevels are taken + // do not take sublevels with Ctrl + bool bOutlineWithChildren = (KEY_MOD1 != m_xContent6ToolBox->get_modifier_state()); + m_xContentTree->ExecCommand(rCommand, bOutlineWithChildren); + } + else if (rCommand == "delete") + { + if (!bContentEntry) + { + m_xContentTree->DeleteAllContentOfEntryContentType(*xEntry); + } + else + { + m_xContentTree->EditEntry(*xEntry, EditEntryMode::DELETE); + } + } +} + weld::Window* SwNavigationPI::GetFrameWeld() const { if (m_xNavigatorDlg) diff --git a/sw/uiconfig/swriter/ui/navigatorpanel.ui b/sw/uiconfig/swriter/ui/navigatorpanel.ui index afb588a7a65d..5598ef1d938d 100644 --- a/sw/uiconfig/swriter/ui/navigatorpanel.ui +++ b/sw/uiconfig/swriter/ui/navigatorpanel.ui @@ -515,116 +515,812 @@ False True - 2 + 1 - + True - True - icons + False - + True - False - List Box On/Off - sw/res/sc20233.png - - - List Box On/Off - Shows or hides the Navigator list. + True + start + start + icons + + + True + False + List Box On/Off + sw/res/sc20233.png + + + List Box On/Off + Shows or hides the Navigator list. + + + + False + False + + + + + True + False + + + False + False + False - False + True + 0 - + True False - - - False - False - - - - - True - False - False - Promote Outline Level - sw/res/sc20172.png - - - Promote Outline Level - Increases the outline level of the selected heading, and the headings that occur below the heading, by one. To only increase the outline level of the selected heading, hold down Ctrl, and then click this icon. + + + True + True + start + start + icons + False + + + True + False + Promote Outline Level + start + start + sw/res/sc20172.png + + + False + False + + + + + True + False + Demote Outline Level + start + start + sw/res/sc20173.png + + + False + False + + + + + True + False + Move Heading Up + start + start + sw/res/sc20174.png + + + False + False + + + + + True + False + Move Heading Down + start + start + sw/res/sc20171.png + + + False + False + + + + False + True + 0 + + + + + True + True + start + start + icons + False + + + False + True + 1 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + True + False + start + start + + + False + False + + + + + True + False + start + start + + + False + False + + + + + False + True + 2 + + + + + True + True + start + start + icons + False + + + False + True + 3 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 4 + + + + + True + True + start + start + icons + False + + + False + True + 5 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 6 + + + + + True + True + start + start + icons + False + + + False + True + 7 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 8 + + + + + True + True + start + start + icons + False + + + False + True + 9 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 10 + + + + + True + True + start + start + icons + False + + + False + True + 11 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 12 + + + + + True + True + start + start + icons + False + + + False + True + 13 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + True + False + start + start + + + False + False + + + + + False + True + 14 + + + + + True + True + start + start + icons + False + + + False + True + 15 + + + + + True + True + start + start + icons + False + + + False + True + 16 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 17 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + True + False + start + start + + + False + False + + + + + False + True + 18 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 19 + + + + + True + True + start + start + icons + False + + + False + True + 20 + + + + + True + True + start + start + icons + False + + + False + True + 21 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 22 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 23 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 24 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 25 + + + + + True + True + start + start + icons + False + + + False + True + 26 + + + + + True + True + start + start + icons + False + + + True + False + start + start + + + False + False + + + + + False + True + 27 + + + + + True + True + start + start + icons + False + + + False + True + 28 + + + + + True + True + start + start + icons + False + + + True + False + Delete + start + start + cmd/sc_delete.png + + + False + False + + + + + False + True + 29 + False - False - - - - - True - False - False - Demote Outline Level - sw/res/sc20173.png - - - Demote Outline Level - Decreases the outline level of the selected heading, and the headings that occur below the heading, by one. To only decrease the outline level of the selected heading, hold down Ctrl, and then click this icon. - - - - - False - False - - - - - True - False - False - Move Heading Up - sw/res/sc20174.png - - - Move Heading Up - Moves the selected heading, and the text below the heading, up one heading position in the Navigator and in the document. To move only the selected heading and not the text associated with the heading, hold down Ctrl, and then click this icon. - - - - - False - False - - - - - True - False - False - Move Heading Down - sw/res/sc20171.png - - - Move Heading Down - Moves the selected heading, and the text below the heading, down one heading position in the Navigator and in the document. To move only the selected heading and not the text associated with the heading, hold down Ctrl, and then click this icon. - - - - - False - False + True + 1