officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu |    8 
 sw/inc/cmdid.h                                                      |    1 
 sw/inc/strings.hrc                                                  |    2 
 sw/inc/view.hxx                                                     |    6 
 sw/sdi/_viewsh.sdi                                                  |    4 
 sw/sdi/swriter.sdi                                                  |   17 +
 sw/source/uibase/inc/wrtsh.hxx                                      |    2 
 sw/source/uibase/uiview/view2.cxx                                   |   74 
+++++
 sw/source/uibase/wrtsh/wrtsh1.cxx                                   |   58 ++++
 sw/uiconfig/swriter/ui/numberinput.ui                               |  132 
++++++++++
 10 files changed, 303 insertions(+), 1 deletion(-)

New commits:
commit 5f72a041c0160e4067ca931a9cec711b84b558f4
Author:     Jim Raykowski <rayk...@gmail.com>
AuthorDate: Sat Oct 22 09:12:55 2022 -0800
Commit:     Jim Raykowski <rayk...@gmail.com>
CommitDate: Fri Oct 28 02:10:26 2022 +0200

    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 <rayk...@gmail.com>

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>

Reply via email to