sw/inc/swabstdlg.hxx                    |    1 
 sw/source/ui/dialog/swdlgfact.cxx       |    5 +
 sw/source/ui/dialog/swdlgfact.hxx       |    1 
 sw/source/ui/misc/pagenumberdlg.cxx     |    7 ++
 sw/source/uibase/inc/pagenumberdlg.hxx  |    2 
 sw/source/uibase/shells/textfld.cxx     |  100 +++++++++++++++++++++++---------
 sw/source/uibase/wrtsh/wrtsh1.cxx       |    1 
 sw/uiconfig/swriter/ui/pagenumberdlg.ui |   26 +++++++-
 8 files changed, 114 insertions(+), 29 deletions(-)

New commits:
commit 800cccaeb191a900de8c96dfb0d56a9089b016d8
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Mon May 1 10:57:25 2023 -0400
Commit:     Justin Luth <jl...@mail.com>
CommitDate: Thu May 18 18:06:15 2023 +0200

    tdf#86630 sw page number wizard: try avoid copying bookmarks
    
    Each time the pagedesc is changed, it makes extra copies
    for undo purposes. That really messes up unique bookmark names.
    
    So, consolidate all the page description changes,
    and make the change in one big batch.
    
    I like this better anyway, because now it doesn't
    look like all kinds of magic incantations.
    This is now straight forward programming,
    and consolidates three separate calls to adjust the page style.
    
    Change-Id: Ib200a1f6ba810fdf0111c9909679e3f80d573230
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151243
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151905
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/sw/source/uibase/shells/textfld.cxx 
b/sw/source/uibase/shells/textfld.cxx
index 30d346b5b31a..2a68219774ba 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -56,12 +56,15 @@
 #include <doc.hxx>
 #include <PostItMgr.hxx>
 #include <swmodule.hxx>
+
+#include <editeng/ulspitem.hxx>
 #include <xmloff/odffields.hxx>
 #include <IDocumentContentOperations.hxx>
 #include <IDocumentRedlineAccess.hxx>
 #include <IDocumentUndoRedo.hxx>
 #include <svl/zforlist.hxx>
 #include <svl/zformat.hxx>
+#include <svx/xfillit0.hxx>
 #include <svx/pageitem.hxx>
 #include <comphelper/sequenceashashmap.hxx>
 #include <IMark.hxx>
@@ -1030,10 +1033,8 @@ FIELD_INSERT:
                 pFact->CreateSwPageNumberDlg(GetView().GetFrameWeld()));
         auto pShell = GetShellPtr();
 
-        const SvxPageItem* pPageItem;
-        rSh.GetView().GetDispatcher().QueryState(SID_ATTR_PAGE, pPageItem);
-        if (pPageItem)
-            pDlg->SetPageNumberType(pPageItem->GetNumType());
+        const SwPageDesc& rCurrDesc = rSh.GetPageDesc(rSh.GetCurPageDesc());
+        pDlg->SetPageNumberType(rCurrDesc.GetNumType().GetNumberingType());
 
         pDlg->StartExecuteAsync([pShell, &rSh, pDlg](int nResult) {
             if ( nResult == RET_OK )
@@ -1066,23 +1067,47 @@ FIELD_INSERT:
                     
rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum);
                 }
 
-                SvxPageItem aPageItem(SID_ATTR_PAGE);
-                aPageItem.SetNumType(pDlg->GetPageNumberType());
-                // Might as well turn on margin mirroring too - if appropriate
-                if (!bHeaderAlreadyOn && !bFooterAlreadyOn && !bIsSinglePage
-                    && pDlg->GetMirrorOnEvenPages() && (rDesc.GetUseOn() & 
UseOnPage::All))
+                SwPageDesc aNewDesc(rDesc);
+                bool bChangePageDesc = false;
+                if (pDlg->GetPageNumberType() != 
aNewDesc.GetNumType().GetNumberingType())
                 {
-                    aPageItem.SetPageUsage(SvxPageUsage::Mirror);
+                    bChangePageDesc = true;
+                    SvxNumberType aNewType(rDesc.GetNumType());
+                    aNewType.SetNumberingType(pDlg->GetPageNumberType());
+                    aNewDesc.SetNumType(aNewType);
                 }
-                rSh.GetView().GetDispatcher().ExecuteList(SID_ATTR_PAGE,
-                                                          SfxCallMode::API | 
SfxCallMode::SYNCHRON,
-                                                          { &aPageItem });
 
                 // Insert header/footer
-                if (bHeader && !bHeaderAlreadyOn)
-                    rSh.ChangeHeaderOrFooter(rDesc.GetName(), bHeader, 
/*On=*/true, /*Warn=*/false);
-                else if (!bHeader && !bFooterAlreadyOn)
-                    rSh.ChangeHeaderOrFooter(rDesc.GetName(), false, 
/*On=*/true, /*Warn=*/false);
+                if ((bHeader && !bHeaderAlreadyOn) || (!bHeader && 
!bFooterAlreadyOn))
+                {
+                    bChangePageDesc = true;
+                    SwFrameFormat &rMaster = aNewDesc.GetMaster();
+                    if (bHeader)
+                        rMaster.SetFormatAttr(SwFormatHeader(/*On=*/true));
+                    else
+                        rMaster.SetFormatAttr(SwFormatFooter(/*On=*/true));
+
+                    // Init copied from ChangeHeaderOrFooter: keep in sync
+                    constexpr tools::Long constTwips_5mm = o3tl::toTwips(5, 
o3tl::Length::mm);
+                    const SvxULSpaceItem aUL(bHeader ? 0 : constTwips_5mm,
+                                             bHeader ? constTwips_5mm : 0,
+                                             RES_UL_SPACE);
+                    const XFillStyleItem aFill(drawing::FillStyle_NONE);
+                    SwFrameFormat& rFormat
+                        = bHeader
+                              ? 
const_cast<SwFrameFormat&>(*rMaster.GetHeader().GetHeaderFormat())
+                              : 
const_cast<SwFrameFormat&>(*rMaster.GetFooter().GetFooterFormat());
+                    rFormat.SetFormatAttr(aUL);
+                    rFormat.SetFormatAttr(aFill);
+
+                    // Might as well turn on margin mirroring too - if 
appropriate
+                    if (pDlg->GetMirrorOnEvenPages() && !bHeaderAlreadyOn && 
!bFooterAlreadyOn
+                        && !bIsSinglePage
+                        && (aNewDesc.ReadUseOn() & UseOnPage::Mirror) == 
UseOnPage::All)
+                    {
+                        aNewDesc.WriteUseOn(rDesc.ReadUseOn() | 
UseOnPage::Mirror);
+                    }
+                }
 
                 const bool bCreateMirror = !bIsSinglePage && 
pDlg->GetMirrorOnEvenPages()
                     && nMirrorPagesNeeded <= rSh.GetPageCnt();
@@ -1091,17 +1116,17 @@ FIELD_INSERT:
                     // Use different left/right header/footer
                     if ((bHeader && rDesc.IsHeaderShared()) || (!bHeader && 
rDesc.IsFooterShared()))
                     {
-                        SwPageDesc rNewDesc(rSh.GetPageDesc(nPageDescIndex));
-
+                        bChangePageDesc = true;
                         if (bHeader)
-                            rNewDesc.ChgHeaderShare(false);
+                            aNewDesc.ChgHeaderShare(/*Share=*/false);
                         else
-                            rNewDesc.ChgFooterShare(false);
-
-                        rSh.ChgPageDesc(nPageDescIndex, rNewDesc);
+                            aNewDesc.ChgFooterShare(/*Share=*/false);
                     }
                 }
 
+                if (bChangePageDesc)
+                    rSh.ChgPageDesc(nPageDescIndex, aNewDesc);
+
                 // Go to the header or footer insert position
                 bool bInHF = false;
                 bool bSkipMirror = true;
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx 
b/sw/source/uibase/wrtsh/wrtsh1.cxx
index b4e8b882da4e..4b9e12fa561b 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -2193,6 +2193,7 @@ void SwWrtShell::ChangeHeaderOrFooter(
                     rMaster.SetFormatAttr( SwFormatFooter( bOn ));
                 if( bOn )
                 {
+                    // keep in sync with FN_PGNUMBER_WIZARD
                     constexpr tools::Long constTwips_5mm = o3tl::toTwips(5, 
o3tl::Length::mm);
                     SvxULSpaceItem aUL(bHeader ? 0 : constTwips_5mm, bHeader ? 
constTwips_5mm : 0, RES_UL_SPACE );
                     SwFrameFormat* pFormat = bHeader ?
commit d466b9603b4917f1d4a8fdc702a8ed69f0ced8ae
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Fri Apr 28 13:38:13 2023 -0400
Commit:     Justin Luth <jl...@mail.com>
CommitDate: Thu May 18 18:06:00 2023 +0200

    tdf#86630 sw page number wizard: add page total
    
    This is a squashed commit,
    including 00e2e3210da57c138bd998481a89760b8c7a0e47
        tdf#86630 sw page number wizard: use '/' for page total
    
    1 / 3 is the format of the output.
    Not totally clear, but it is at least not in English,
    and I'm fairly certain I've seen this format used numerous times.
    
    At least everything is there, and all the user needs to do is
    modify the / to be whatever they want.
    
    I checked to see if by some miracle localedata had a specification
    for "X of Y" but it doesn't.
    
    Change-Id: Iae1e74e612ec449f72086b3f5a5e32713fee4d27
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151173
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151904
    Tested-by: Justin Luth <jl...@mail.com>

diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx
index 994360eca166..bfac9ea7d289 100644
--- a/sw/inc/swabstdlg.hxx
+++ b/sw/inc/swabstdlg.hxx
@@ -239,6 +239,7 @@ public:
     virtual int GetPageNumberPosition() const = 0;
     virtual int GetPageNumberAlignment() const = 0;
     virtual bool GetMirrorOnEvenPages() const = 0;
+    virtual bool GetIncludePageTotal() const = 0;
     virtual SvxNumType GetPageNumberType() const = 0;
     virtual void SetPageNumberType(SvxNumType nSet) = 0;
 };
diff --git a/sw/source/ui/dialog/swdlgfact.cxx 
b/sw/source/ui/dialog/swdlgfact.cxx
index abd947a9340d..f9e05b3f0d35 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -647,6 +647,11 @@ bool AbstractSwPageNumberDlg_Impl::GetMirrorOnEvenPages() 
const
     return m_xDlg->GetMirrorOnEvenPages();
 }
 
+bool AbstractSwPageNumberDlg_Impl::GetIncludePageTotal() const
+{
+    return m_xDlg->GetIncludePageTotal();
+}
+
 SvxNumType AbstractSwPageNumberDlg_Impl::GetPageNumberType() const
 {
     return m_xDlg->GetPageNumberType();
diff --git a/sw/source/ui/dialog/swdlgfact.hxx 
b/sw/source/ui/dialog/swdlgfact.hxx
index 691b6127b204..359af1bc2e31 100644
--- a/sw/source/ui/dialog/swdlgfact.hxx
+++ b/sw/source/ui/dialog/swdlgfact.hxx
@@ -166,6 +166,7 @@ public:
     virtual int GetPageNumberPosition() const override;
     virtual int GetPageNumberAlignment() const override;
     bool GetMirrorOnEvenPages() const override;
+    bool GetIncludePageTotal() const override;
     SvxNumType GetPageNumberType() const override;
     void SetPageNumberType(SvxNumType nSet) override;
 };
diff --git a/sw/source/ui/misc/pagenumberdlg.cxx 
b/sw/source/ui/misc/pagenumberdlg.cxx
index fa757ed2212d..1b1c4a98f579 100644
--- a/sw/source/ui/misc/pagenumberdlg.cxx
+++ b/sw/source/ui/misc/pagenumberdlg.cxx
@@ -31,6 +31,7 @@ SwPageNumberDlg::SwPageNumberDlg(weld::Window* pParent)
     , m_xPageNumberPosition(m_xBuilder->weld_combo_box("positionCombo"))
     , m_xPageNumberAlignment(m_xBuilder->weld_combo_box("alignmentCombo"))
     , m_xMirrorOnEvenPages(m_xBuilder->weld_check_button("mirrorCheckbox"))
+    , m_xIncludePageTotal(m_xBuilder->weld_check_button("pagetotalCheckbox"))
     , m_xPageNumberTypeLB(new 
SvxPageNumberListBox(m_xBuilder->weld_combo_box("numfmtlb")))
     , m_xPreviewImage(m_xBuilder->weld_image("previewImage"))
     , m_aPageNumberPosition(1) // bottom
@@ -44,6 +45,7 @@ SwPageNumberDlg::SwPageNumberDlg(weld::Window* pParent)
     m_xPageNumberAlignment->set_active(m_aPageNumberAlignment);
     m_xMirrorOnEvenPages->set_sensitive(false);
     m_xMirrorOnEvenPages->set_state(TRISTATE_TRUE);
+    m_xIncludePageTotal->set_state(TRISTATE_FALSE);
     
SvxNumOptionsTabPageHelper::GetI18nNumbering(m_xPageNumberTypeLB->get_widget(),
                                                  
::std::numeric_limits<sal_uInt16>::max());
     m_xPageNumberTypeLB->connect_changed(LINK(this, SwPageNumberDlg, 
NumberTypeSelectHdl));
@@ -85,6 +87,11 @@ bool SwPageNumberDlg::GetMirrorOnEvenPages()
            && m_xMirrorOnEvenPages->get_state() == TRISTATE_TRUE;
 }
 
+bool SwPageNumberDlg::GetIncludePageTotal()
+{
+    return m_xIncludePageTotal->get_state() == TRISTATE_TRUE;
+}
+
 void SwPageNumberDlg::SetPageNumberType(SvxNumType nSet)
 {
     m_nPageNumberType = nSet;
diff --git a/sw/source/uibase/inc/pagenumberdlg.hxx 
b/sw/source/uibase/inc/pagenumberdlg.hxx
index 77baf43ab498..298ab975d1f2 100644
--- a/sw/source/uibase/inc/pagenumberdlg.hxx
+++ b/sw/source/uibase/inc/pagenumberdlg.hxx
@@ -32,6 +32,7 @@ class SwPageNumberDlg : public SfxDialogController
     std::unique_ptr<weld::ComboBox> m_xPageNumberPosition;
     std::unique_ptr<weld::ComboBox> m_xPageNumberAlignment;
     std::unique_ptr<weld::CheckButton> m_xMirrorOnEvenPages;
+    std::unique_ptr<weld::CheckButton> m_xIncludePageTotal;
     std::unique_ptr<SvxPageNumberListBox> m_xPageNumberTypeLB;
 
     std::unique_ptr<weld::Image> m_xPreviewImage;
@@ -53,6 +54,7 @@ public:
     int GetPageNumberPosition() const { return m_aPageNumberPosition; }
     int GetPageNumberAlignment() const { return m_aPageNumberAlignment; }
     bool GetMirrorOnEvenPages();
+    bool GetIncludePageTotal();
     SvxNumType GetPageNumberType() const { return m_nPageNumberType; }
     void SetPageNumberType(SvxNumType nSet);
 };
diff --git a/sw/source/uibase/shells/textfld.cxx 
b/sw/source/uibase/shells/textfld.cxx
index f50918838c33..30d346b5b31a 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -1201,16 +1201,27 @@ FIELD_INSERT:
                     }
                 }
 
+                sal_Int32 nStartContentIndex = 
rSh.GetCursor()->Start()->GetContentIndex();
+                assert(!nStartContentIndex && "earlier split node if not 
empty, but not zero?");
+
                 // Insert page number
                 SwFieldMgr aMgr(pShell);
                 SwInsertField_Data aData(SwFieldTypesEnum::PageNumber, 0,
                             OUString(), OUString(), SVX_NUM_PAGEDESC);
                 aMgr.InsertField(aData);
+                if (pDlg->GetIncludePageTotal())
+                {
+                    
rDoc->getIDocumentContentOperations().InsertString(*rSh.GetCursor(), " / ");
+                    SwInsertField_Data 
aPageTotalData(SwFieldTypesEnum::DocumentStatistics, DS_PAGE,
+                                                      OUString(), OUString(), 
SVX_NUM_PAGEDESC);
+                    aMgr.InsertField(aPageTotalData);
+                }
 
+                // Mark inserted fields with a bookmark - so it can be 
found/removed if re-run
                 SwPaM aNewBookmarkPaM(*rSh.GetCursor()->Start());
                 aNewBookmarkPaM.SetMark();
-                rSh.GetCursor()->Left(1);
-                *aNewBookmarkPaM.Start() = *rSh.GetCursor()->Start();
+                assert(aNewBookmarkPaM.GetPointContentNode() && "only 
SetContent on content node");
+                aNewBookmarkPaM.Start()->SetContent(nStartContentIndex);
                 rIDMA.makeMark(aNewBookmarkPaM,
                                sBookmarkName + 
OUString::number(rSh.GetVirtPageNum()),
                                IDocumentMarkAccess::MarkType::BOOKMARK,
@@ -1247,14 +1258,24 @@ FIELD_INSERT:
                     SvxAdjustItem aMirrorAdjustItem(eAdjust, 
RES_PARATR_ADJUST);
                     rSh.SetAttrItem(aMirrorAdjustItem);
 
+                    nStartContentIndex = 
rSh.GetCursor()->Start()->GetContentIndex();
+
                     // Insert page number
                     SwFieldMgr aEvenMgr(pShell);
                     aEvenMgr.InsertField(aData);
+                    if (pDlg->GetIncludePageTotal())
+                    {
+                        
rDoc->getIDocumentContentOperations().InsertString(*rSh.GetCursor(), " / ");
+                        SwInsertField_Data 
aPageTotalData(SwFieldTypesEnum::DocumentStatistics,
+                                                          DS_PAGE, OUString(), 
OUString(),
+                                                          SVX_NUM_PAGEDESC);
+                        aMgr.InsertField(aPageTotalData);
+                    }
 
+                    // Mark inserted fields with a bookmark - so it can be 
found/removed if re-run
                     SwPaM aNewEvenBookmarkPaM(*rSh.GetCursor()->Start());
                     aNewEvenBookmarkPaM.SetMark();
-                    rSh.GetCursor()->Left(1);
-                    *aNewEvenBookmarkPaM.Start() = *rSh.GetCursor()->Start();
+                    
aNewEvenBookmarkPaM.Start()->SetContent(nStartContentIndex);
                     rIDMA.makeMark(aNewEvenBookmarkPaM,
                                    sBookmarkName + 
OUString::number(rSh.GetVirtPageNum()),
                                    IDocumentMarkAccess::MarkType::BOOKMARK,
diff --git a/sw/uiconfig/swriter/ui/pagenumberdlg.ui 
b/sw/uiconfig/swriter/ui/pagenumberdlg.ui
index 49a89e1fd98d..dba145a4c403 100644
--- a/sw/uiconfig/swriter/ui/pagenumberdlg.ui
+++ b/sw/uiconfig/swriter/ui/pagenumberdlg.ui
@@ -172,6 +172,28 @@
                     <property name="position">4</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkCheckButton" id="pagetotalCheckbox">
+                    <property name="label" translatable="yes" 
context="pagenumberdlg|pagetotalCheckbox">Include page total</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="receives-default">False</property>
+                    <property name="margin-start">18</property>
+                    <property name="margin-top">3</property>
+                    <property name="use-underline">True</property>
+                    <property name="draw-indicator">True</property>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" 
id="pagetotalCheckbox-atkobject">
+                        <property name="AtkObject::accessible-description" 
translatable="yes" context="pagenumberdlg|extended_tip|pagetotalCheckbox">Also 
insert the total number of pages</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">5</property>
+                  </packing>
+                </child>
                 <child>
                   <object class="GtkLabel" id="numfmtLabel">
                     <property name="visible">True</property>
@@ -193,7 +215,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">5</property>
+                    <property name="position">6</property>
                   </packing>
                 </child>
                 <child>
@@ -212,7 +234,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">6</property>
+                    <property name="position">7</property>
                   </packing>
                 </child>
               </object>

Reply via email to