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>