diff options
author | Jim Raykowski <raykowj@gmail.com> | 2022-10-22 09:12:55 -0800 |
---|---|---|
committer | Jim Raykowski <raykowj@gmail.com> | 2022-10-28 02:10:26 +0200 |
commit | 5f72a041c0160e4067ca931a9cec711b84b558f4 (patch) | |
tree | a780748c637f437ad2b209fe45b7291a54cce692 | |
parent | 02db1642c9ce4394f4f85755c4a0a831e547e4fb (diff) |
tdf#142446 Show outline content up to a given outline level
This enhancement provides means to hide outline paragraphs and their
so called outline content for outline levels greater than a given
outline level. This can be done whether or not outline folding is
enabled.
Change-Id: I2769b8f39ef2bc11e03cae07c234cf345104567e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141678
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
-rw-r--r-- | officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu | 8 | ||||
-rw-r--r-- | sw/inc/cmdid.h | 1 | ||||
-rw-r--r-- | sw/inc/strings.hrc | 2 | ||||
-rw-r--r-- | sw/inc/view.hxx | 6 | ||||
-rw-r--r-- | sw/sdi/_viewsh.sdi | 4 | ||||
-rw-r--r-- | sw/sdi/swriter.sdi | 17 | ||||
-rw-r--r-- | sw/source/uibase/inc/wrtsh.hxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/uiview/view2.cxx | 74 | ||||
-rw-r--r-- | sw/source/uibase/wrtsh/wrtsh1.cxx | 58 | ||||
-rw-r--r-- | sw/uiconfig/swriter/ui/numberinput.ui | 132 |
10 files changed, 303 insertions, 1 deletions
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu index 1c20f951bf1d..43890c198d0f 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu @@ -414,6 +414,14 @@ <value>1</value> </prop> </node> + <node oor:name=".uno:OutlineLevelsShown" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Show outline-content to level...</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> <node oor:name=".uno:ShowChangesInMargin" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">Show tracked deletions in margin</value> diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index d98d72ce56b5..5475184a5d2c 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -198,6 +198,7 @@ class SwUINumRuleItem; #define FN_SET_TRACKED_CHANGES_IN_TEXT (FN_VIEW + 67) /* Show tracked deletions and insertions in text */ #define FN_SET_TRACKED_DELETIONS_IN_MARGIN (FN_VIEW + 68) /* Show final text (deletions in margin) */ #define FN_SET_TRACKED_INSERTIONS_IN_MARGIN (FN_VIEW + 69) /* Show original text (insertions in margin) */ +#define FN_OUTLINE_LEVELS_SHOWN (FN_VIEW + 70) // Region: Insert #define FN_INSERT_BOOKMARK (FN_INSERT + 2 ) /* Bookmark */ diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc index e1859f1432d0..94b06835ecf3 100644 --- a/sw/inc/strings.hrc +++ b/sw/inc/strings.hrc @@ -678,6 +678,8 @@ #define STR_OUTLINE_CONTENT_VISIBILITY_TOGGLE NC_("STR_OUTLINE_CONTENT_VISIBILITY_TOGGLE", "Toggle") #define STR_OUTLINE_CONTENT_VISIBILITY_SHOW_ALL NC_("STR_OUTLINE_CONTENT_VISIBILITY_SHOW_ALL", "Unfold All") #define STR_OUTLINE_CONTENT_VISIBILITY_HIDE_ALL NC_("STR_OUTLINE_CONTENT_VISIBILITY_HIDE_ALL", "Fold All") +#define STR_OUTLINE_LEVELS_SHOWN_TITLE NC_("STR_OUTLINE_LEVELS_SHOWN_TITLE", "Show Outline Content to Level") +#define STR_OUTLINE_LEVELS_SHOWN_SPIN_LABEL NC_("STR_OUTLINE_LEVELS_SHOWN_SPIN_LABEL", "Level (1 - 10)") #define STR_EXPANDALL NC_("STR_EXPANDALL", "Expand All") #define STR_COLLAPSEALL NC_("STR_COLLAPSEALL", "Collapse All") diff --git a/sw/inc/view.hxx b/sw/inc/view.hxx index 45d38b0cf231..c2d3772b7578 100644 --- a/sw/inc/view.hxx +++ b/sw/inc/view.hxx @@ -265,6 +265,9 @@ class SW_DLLPUBLIC SwView: public SfxViewShell SwTwips m_nLOKPageUpDownOffset; SelectCycle m_aSelectCycle; + + int m_nMaxOutlineLevelShown = 10; + // methods for searching // set search context SAL_DLLPRIVATE bool SearchAndWrap(bool bApi); @@ -644,6 +647,9 @@ public: void UpdateDocStats(); + void SetMaxOutlineLevelShown(int nLevel) {m_nMaxOutlineLevelShown = nLevel;} + int GetMaxOutlineLevelShown() const {return m_nMaxOutlineLevelShown;} + // methods for printing SAL_DLLPRIVATE virtual SfxPrinter* GetPrinter( bool bCreate = false ) override; SAL_DLLPRIVATE virtual bool HasPrintOptionsPage() const override; diff --git a/sw/sdi/_viewsh.sdi b/sw/sdi/_viewsh.sdi index 7129c7cd99d4..b9fded634561 100644 --- a/sw/sdi/_viewsh.sdi +++ b/sw/sdi/_viewsh.sdi @@ -33,6 +33,10 @@ interface BaseTextEditView ExecMethod = Execute ; StateMethod = GetState ; ] + FN_OUTLINE_LEVELS_SHOWN + [ + ExecMethod = Execute; + ] SID_REFRESH_VIEW // status(final|play) [ ExecMethod = Execute ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index 044feca164f3..90c4a2b2b864 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -8363,3 +8363,20 @@ SfxUInt32Item TableColumWidth SID_ATTR_TABLE_COLUMN_WIDTH ToolBoxConfig = FALSE, GroupId = SfxGroupId::Table; ] + +SfxVoidItem OutlineLevelsShown FN_OUTLINE_LEVELS_SHOWN +() +[ + AutoUpdate = FALSE, + FastCall = TRUE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::View; +] diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx index 316e0b511a29..ebc255d3b05e 100644 --- a/sw/source/uibase/inc/wrtsh.hxx +++ b/sw/source/uibase/inc/wrtsh.hxx @@ -506,6 +506,8 @@ typedef bool (SwWrtShell::*FNSimpleMove)(); void InvalidateOutlineContentVisibility(); bool GetAttrOutlineContentVisible(const size_t nPos); + void MakeOutlineLevelsVisible(const int nLevel); + std::optional<OString> getLOKPayload(int nType, int nViewId) const; private: diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx index 86d414a80cc8..0c56882e5eac 100644 --- a/sw/source/uibase/uiview/view2.cxx +++ b/sw/source/uibase/uiview/view2.cxx @@ -88,6 +88,7 @@ #include <IDocumentSettingAccess.hxx> #include <IDocumentDrawModelAccess.hxx> #include <IDocumentStatistics.hxx> +#include <IDocumentOutlineNodes.hxx> #include <wrtsh.hxx> #include <viewopt.hxx> #include <basesh.hxx> @@ -155,6 +156,8 @@ #include <svx/srchdlg.hxx> #include <o3tl/string_view.hxx> +#include <strings.hrc> + const char sStatusDelim[] = " : "; using namespace sfx2; @@ -169,6 +172,62 @@ using namespace ::com::sun::star::container; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::ui::dialogs; +namespace { + +class SwNumberInputDlg : public SfxDialogController +{ +private: + std::unique_ptr<weld::Label> m_xLabel1; + std::unique_ptr<weld::SpinButton> m_xSpinButton; + std::unique_ptr<weld::Label> m_xLabel2; + std::unique_ptr<weld::Button> m_xOKButton; + + DECL_LINK(InputModifiedHdl, weld::Entry&, void); +public: + SwNumberInputDlg(weld::Window* pParent, const OUString& rTitle, + const OUString& rLabel1, const sal_Int64 nValue, const sal_Int64 min, const sal_Int64 max, + OUString rLabel2 = OUString()) + : SfxDialogController(pParent, "modules/swriter/ui/numberinput.ui", "NumberInputDialog") + , m_xLabel1(m_xBuilder->weld_label("label1")) + , m_xSpinButton(m_xBuilder->weld_spin_button("spinbutton")) + , m_xLabel2(m_xBuilder->weld_label("label2")) + , m_xOKButton(m_xBuilder->weld_button("ok")) + { + m_xDialog->set_title(rTitle); + m_xLabel1->set_label(rLabel1); + m_xSpinButton->set_value(nValue); + m_xSpinButton->set_range(min, max); + m_xSpinButton->set_position(-1); + m_xSpinButton->select_region(0, -1); + m_xSpinButton->connect_changed(LINK(this, SwNumberInputDlg, InputModifiedHdl)); + rLabel2.isEmpty() ? m_xLabel2->hide() : m_xLabel2->set_label(rLabel2); + } + + auto GetNumber() + { + return m_xSpinButton->get_text().toInt32(); + } +}; + +IMPL_LINK_NOARG(SwNumberInputDlg, InputModifiedHdl, weld::Entry&, void) +{ + m_xOKButton->set_sensitive(!m_xSpinButton->get_text().isEmpty()); + if (!m_xOKButton->get_sensitive()) + return; + + auto nValue = m_xSpinButton->get_text().toInt32(); + if (nValue <= m_xSpinButton->get_min()) + m_xSpinButton->set_value(m_xSpinButton->get_min()); + else if (nValue > m_xSpinButton->get_max()) + m_xSpinButton->set_value(m_xSpinButton->get_max()); + else + m_xSpinButton->set_value(nValue); + + m_xSpinButton->set_position(-1); +} + +} + static void lcl_SetAllTextToDefaultLanguage( SwWrtShell &rWrtSh, sal_uInt16 nWhichId ) { if (!(nWhichId == RES_CHRATR_LANGUAGE || @@ -1271,6 +1330,21 @@ void SwView::Execute(SfxRequest &rReq) lcl_SetAllTextToDefaultLanguage( *m_pWrtShell, RES_CHRATR_CJK_LANGUAGE ); } break; + case FN_OUTLINE_LEVELS_SHOWN: + { + SwWrtShell& rSh = GetWrtShell(); + int nOutlineLevel = -1; + auto nOutlinePos = rSh.GetOutlinePos(); + if (nOutlinePos != SwOutlineNodes::npos) + nOutlineLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos); + SwNumberInputDlg aDlg(GetViewFrame()->GetFrameWeld(), + SwResId(STR_OUTLINE_LEVELS_SHOWN_TITLE), + SwResId(STR_OUTLINE_LEVELS_SHOWN_SPIN_LABEL), + nOutlineLevel + 1, 1, 10); + if (aDlg.run() == RET_OK) + rSh.MakeOutlineLevelsVisible(aDlg.GetNumber()); + } + break; case FN_TOGGLE_OUTLINE_CONTENT_VISIBILITY: { m_pWrtShell->EnterStdMode(); diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx index 8bbdb869e539..9bf10af5ce2a 100644 --- a/sw/source/uibase/wrtsh/wrtsh1.cxx +++ b/sw/source/uibase/wrtsh/wrtsh1.cxx @@ -2358,6 +2358,60 @@ bool SwWrtShell::IsOutlineContentVisible(const size_t nPos) return true; } +void SwWrtShell::MakeOutlineLevelsVisible(const int nLevel) +{ + m_rView.SetMaxOutlineLevelShown(nLevel); + + bool bDocChanged = false; + + const SwNodes& rNodes = GetNodes(); + const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds(); + + StartAction(); + for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNodes.size(); ++nPos) + { + SwNode* pNode = rOutlineNodes[nPos]; + auto nOutlineLevel = pNode->GetTextNode()->GetAttrOutlineLevel(); + if ( nOutlineLevel > nLevel) + { + // MakeOutlineContentVisible(nPos, false) sets the outline node outline content + // visible attribute false so it needs restored to true if it was true. + bool bOutlineContentVisible = false; + pNode->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisible); + MakeOutlineContentVisible(nPos, false); + pNode->GetTextNode()->DelFrames(GetLayout()); + if (bOutlineContentVisible) + pNode->GetTextNode()->SetAttrOutlineContentVisible(true); + bDocChanged = true; + } + else + { + if (!pNode->GetTextNode()->getLayoutFrame(GetLayout())) + { + SwNodeIndex aIdx(*pNode, +1); + { + // MakeAllOutlineContentTemporarilyVisible in this scope! Don't place at the + // start of the function. Placed there will restore content to what it was + // was at that point when the function exits. + MakeAllOutlineContentTemporarilyVisible a(GetDoc()); + MakeFrames(GetDoc(), *pNode, aIdx.GetNode()); + } + bool bVisible = true; + if (GetViewOptions()->IsShowOutlineContentVisibilityButton()) + pNode->GetTextNode()->GetAttrOutlineContentVisible(bVisible); + if (bVisible) + MakeOutlineContentVisible(nPos, true); + bDocChanged = true; + } + } + } + EndAction(); + + // Broadcast DocChanged if document layout has changed so the Navigator will be updated. + if (bDocChanged) + GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged)); +} + void SwWrtShell::MakeOutlineContentVisible(const size_t nPos, bool bMakeVisible) { const SwNodes& rNodes = GetNodes(); @@ -2374,9 +2428,11 @@ void SwWrtShell::MakeOutlineContentVisible(const size_t nPos, bool bMakeVisible) { // get the last outline node to include (iPos) int nLevel = pSttNd->GetTextNode()->GetAttrOutlineLevel(); + int nMaxOutlineLevelShown = m_rView.GetMaxOutlineLevelShown(); SwOutlineNodes::size_type iPos = nPos; while (++iPos < rOutlineNodes.size() && - rOutlineNodes[iPos]->GetTextNode()->GetAttrOutlineLevel() > nLevel); + rOutlineNodes[iPos]->GetTextNode()->GetAttrOutlineLevel() > nLevel && + rOutlineNodes[iPos]->GetTextNode()->GetAttrOutlineLevel() <= nMaxOutlineLevelShown); // get the correct end node // the outline node may be in frames, headers, footers special section of doc model diff --git a/sw/uiconfig/swriter/ui/numberinput.ui b/sw/uiconfig/swriter/ui/numberinput.ui new file mode 100644 index 000000000000..1fdab56c7270 --- /dev/null +++ b/sw/uiconfig/swriter/ui/numberinput.ui @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.38.2 --> +<interface domain="sw"> + <requires lib="gtk+" version="3.20"/> + <object class="GtkAdjustment" id="adjustment1"> + <property name="upper">100</property> + <property name="step-increment">1</property> + <property name="page-increment">10</property> + </object> + <object class="GtkDialog" id="NumberInputDialog"> + <property name="can-focus">False</property> + <property name="border-width">6</property> + <property name="modal">True</property> + <property name="default-width">0</property> + <property name="default-height">0</property> + <property name="type-hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area1"> + <property name="can-focus">False</property> + <property name="layout-style">end</property> + <child> + <object class="GtkButton" id="ok"> + <property name="label" translatable="yes" context="stock">_OK</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="can-default">True</property> + <property name="has-default">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="cancel"> + <property name="label" translatable="yes" context="stock">_Cancel</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">2</property> + </packing> + </child> + <child> + <!-- n-columns=2 n-rows=1 --> + <object class="GtkGrid" id="grid1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-start">5</property> + <property name="margin-end">5</property> + <property name="margin-top">5</property> + <property name="margin-bottom">5</property> + <property name="row-spacing">6</property> + <property name="column-spacing">6</property> + <child> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="stringinput|name">label1</property> + <property name="use-underline">True</property> + <property name="xalign">0</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spinbutton"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="max-length">2</property> + <property name="width-chars">2</property> + <property name="adjustment">adjustment1</property> + <property name="activates_default">True</property> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="stringinput|name">label2</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-5">ok</action-widget> + <action-widget response="-6">cancel</action-widget> + </action-widgets> + </object> +</interface> |