diff options
author | Justin Luth <jluth@mail.com> | 2024-06-21 10:42:08 -0400 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2024-07-03 15:40:45 +0200 |
commit | 4e7ac2acefc8cedf95be03d3145b6ef2e6027767 (patch) | |
tree | 63acf91be048be2d5ff27631af856e6f69bd52d7 | |
parent | 574d5ce168cd0f628a361cd0689039daf8b82387 (diff) |
tdf#161646 sw page number wizard: fit into existing margins
Often page numbers are inserted when a document is finished,
and at that point it would be annoying to repaginate everything,
so offer this option of trying to fit the page number
into the existing margins.
I was tempted to enable it by default,
except that it would then mismatch any pages
that had header/footers created via other methods.
Problem:
-how to know which font is really needed: western, CTL, CJK?
This patch depends on NFC b7fce2b26ee4ba585544457adc742807a2129d2c
Change-Id: I285a99f8e2f12c87a8bdee20a9c86a1d79f80dd0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169827
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Justin Luth <jluth@mail.com>
-rw-r--r-- | sw/inc/swabstdlg.hxx | 1 | ||||
-rw-r--r-- | sw/source/ui/dialog/swdlgfact.cxx | 5 | ||||
-rw-r--r-- | sw/source/ui/dialog/swdlgfact.hxx | 1 | ||||
-rw-r--r-- | sw/source/ui/misc/pagenumberdlg.cxx | 12 | ||||
-rw-r--r-- | sw/source/uibase/inc/pagenumberdlg.hxx | 6 | ||||
-rw-r--r-- | sw/source/uibase/shells/textfld.cxx | 73 | ||||
-rw-r--r-- | sw/uiconfig/swriter/ui/pagenumberdlg.ui | 26 |
7 files changed, 117 insertions, 7 deletions
diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx index a9ceb855b337..1f147255d6d8 100644 --- a/sw/inc/swabstdlg.hxx +++ b/sw/inc/swabstdlg.hxx @@ -240,6 +240,7 @@ public: virtual int GetPageNumberAlignment() const = 0; virtual bool GetMirrorOnEvenPages() const = 0; virtual bool GetIncludePageTotal() const = 0; + virtual bool GetFitIntoExistingMargins() 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 c70608b6f46a..8155bf7a825d 100644 --- a/sw/source/ui/dialog/swdlgfact.cxx +++ b/sw/source/ui/dialog/swdlgfact.cxx @@ -703,6 +703,11 @@ bool AbstractSwPageNumberDlg_Impl::GetIncludePageTotal() const return m_xDlg->GetIncludePageTotal(); } +bool AbstractSwPageNumberDlg_Impl::GetFitIntoExistingMargins() const +{ + return m_xDlg->GetFitIntoExistingMargins(); +} + 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 5dc47327daa5..6fb220ed1e41 100644 --- a/sw/source/ui/dialog/swdlgfact.hxx +++ b/sw/source/ui/dialog/swdlgfact.hxx @@ -168,6 +168,7 @@ public: virtual int GetPageNumberAlignment() const override; bool GetMirrorOnEvenPages() const override; bool GetIncludePageTotal() const override; + bool GetFitIntoExistingMargins() 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 fe965d69db19..09d7bfc3390f 100644 --- a/sw/source/ui/misc/pagenumberdlg.cxx +++ b/sw/source/ui/misc/pagenumberdlg.cxx @@ -33,6 +33,8 @@ SwPageNumberDlg::SwPageNumberDlg(weld::Window* pParent) , 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_xFitIntoExistingMargins( + m_xBuilder->weld_check_button(u"fitintoexistingmarginsCheckbox"_ustr)) , m_xPageNumberTypeLB(new SvxPageNumberListBox(m_xBuilder->weld_combo_box("numfmtlb"))) , m_xPreviewImage(m_xBuilder->weld_image("previewImage")) , m_aPageNumberPosition(1) // bottom @@ -47,6 +49,7 @@ SwPageNumberDlg::SwPageNumberDlg(weld::Window* pParent) m_xMirrorOnEvenPages->set_sensitive(false); m_xMirrorOnEvenPages->set_state(TRISTATE_TRUE); m_xIncludePageTotal->set_state(TRISTATE_FALSE); + m_xFitIntoExistingMargins->set_state(TRISTATE_FALSE); SvxNumOptionsTabPageHelper::GetI18nNumbering(m_xPageNumberTypeLB->get_widget(), ::std::numeric_limits<sal_uInt16>::max()); m_xPageNumberTypeLB->connect_changed(LINK(this, SwPageNumberDlg, NumberTypeSelectHdl)); @@ -83,17 +86,22 @@ IMPL_LINK_NOARG(SwPageNumberDlg, IncludePageTotalChangeHdl, weld::Toggleable&, v updateImage(); } -bool SwPageNumberDlg::GetMirrorOnEvenPages() +bool SwPageNumberDlg::GetMirrorOnEvenPages() const { return m_xMirrorOnEvenPages->get_sensitive() && m_xMirrorOnEvenPages->get_state() == TRISTATE_TRUE; } -bool SwPageNumberDlg::GetIncludePageTotal() +bool SwPageNumberDlg::GetIncludePageTotal() const { return m_xIncludePageTotal->get_state() == TRISTATE_TRUE; } +bool SwPageNumberDlg::GetFitIntoExistingMargins() const +{ + return m_xFitIntoExistingMargins->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 169c9209dbf5..f097509b5a68 100644 --- a/sw/source/uibase/inc/pagenumberdlg.hxx +++ b/sw/source/uibase/inc/pagenumberdlg.hxx @@ -33,6 +33,7 @@ class SwPageNumberDlg final : public SfxDialogController std::unique_ptr<weld::ComboBox> m_xPageNumberAlignment; std::unique_ptr<weld::CheckButton> m_xMirrorOnEvenPages; std::unique_ptr<weld::CheckButton> m_xIncludePageTotal; + std::unique_ptr<weld::CheckButton> m_xFitIntoExistingMargins; std::unique_ptr<SvxPageNumberListBox> m_xPageNumberTypeLB; std::unique_ptr<weld::Image> m_xPreviewImage; @@ -53,8 +54,9 @@ public: SwPageNumberDlg(weld::Window* pParent); int GetPageNumberPosition() const { return m_aPageNumberPosition; } int GetPageNumberAlignment() const { return m_aPageNumberAlignment; } - bool GetMirrorOnEvenPages(); - bool GetIncludePageTotal(); + bool GetMirrorOnEvenPages() const; + bool GetIncludePageTotal() const; + bool GetFitIntoExistingMargins() const; 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 2707579230b7..6e3ff742cf20 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -37,10 +37,15 @@ #include <svx/hlnkitem.hxx> #include <svx/svxdlg.hxx> #include <osl/diagnose.h> +#include <charatr.hxx> +#include <fmtfsize.hxx> #include <fmthdft.hxx> #include <fmtinfmt.hxx> #include <fldwrap.hxx> +#include <frmatr.hxx> +#include <hfspacingitem.hxx> #include <redline.hxx> +#include <swfont.hxx> #include <view.hxx> #include <viewopt.hxx> #include <wrtsh.hxx> @@ -59,9 +64,9 @@ #include <svtools/strings.hrc> #include <svtools/svtresid.hxx> -#include <editeng/ulspitem.hxx> #include <xmloff/odffields.hxx> #include <IDocumentContentOperations.hxx> +#include <IDocumentLayoutAccess.hxx> #include <IDocumentRedlineAccess.hxx> #include <IDocumentUndoRedo.hxx> #include <svl/zforlist.hxx> @@ -1141,6 +1146,72 @@ FIELD_INSERT: rFormat.SetFormatAttr(aUL); rFormat.SetFormatAttr(aFill); + if (pDlg->GetFitIntoExistingMargins()) + { + SvxULSpaceItem aPageUL(aNewDesc.GetMaster().GetULSpace()); + tools::Long nPageMargin = bHeader ? aPageUL.GetUpper() : aPageUL.GetLower(); + + // most printers can't print to paper edge - use arbitrary ~14pt as minimum + if (nPageMargin > constTwips_5mm) + { + // reduce existing margin by the "Spacing" + nPageMargin -= constTwips_5mm; + + // also reduce by the "Height" (as calculated from the font) + tools::Long nFontHeight = constTwips_5mm; // appropriate for 12pt font + const OutputDevice* pOutDev = Application::GetDefaultDevice(); + const SwViewShell* pViewSh + = rDoc.getIDocumentLayoutAccess().GetCurrentViewShell(); + OUString sParaStyle(bHeader ? "Header" : "Footer"); + SwTextFormatColl* pStyle = rDoc.FindTextFormatCollByName(sParaStyle); + if (pStyle && pOutDev) + { + SwFont aFont( + &pStyle->GetAttrSet(), /*IDocumentSettingAccess=*/nullptr); + + // sledgehammer approach: since the in-use-font (Latin/CTL/CKJ) + // is not known, use the tallest of the three just to ensure fit. + sal_uInt16 nHeight = aFont.GetHeight(pViewSh, *pOutDev); // Latin + + aFont.SetActual(SwFontScript::CTL); + nHeight = std::max(nHeight, aFont.GetHeight(pViewSh, *pOutDev)); + + aFont.SetActual(SwFontScript::CJK); + nFontHeight = std::max(nHeight, aFont.GetHeight(pViewSh, *pOutDev)); + + // Spacing: above and below paragraph + const SvxULSpaceItem& rParaStyleUL = pStyle->GetULSpace(); + nFontHeight += rParaStyleUL.GetUpper() + rParaStyleUL.GetLower(); + + // Border padding: top and bottom + const SvxBoxItem rBorders = pStyle->GetBox(); + nFontHeight += rBorders.CalcLineSpace(SvxBoxItemLine::TOP, true); + nFontHeight += rBorders.CalcLineSpace(SvxBoxItemLine::BOTTOM, true); + } + nPageMargin -= nFontHeight; + + nPageMargin = std::max(nPageMargin, constTwips_5mm); + if (bHeader) + aPageUL.SetUpper(nPageMargin); + else + aPageUL.SetLower(nPageMargin); + aNewDesc.GetMaster().SetFormatAttr(aPageUL); + + // force aggressively calculated font height as minimum to ensure + // effective margin stays the same (instead of getting smaller) + SwFormatFrameSize aSize(rFormat.GetFrameSize()); + aSize.SetHeightSizeType(SwFrameSize::Minimum); + // frame size property includes both Spacing + Height + aSize.SetHeight(constTwips_5mm + nFontHeight); + rFormat.SetFormatAttr(aSize); + + // in case the calculated font height isn't actually large enough, + // eat into spacing first before pushing into the content area. + rFormat.SetFormatAttr(SwHeaderAndFooterEatSpacingItem( + RES_HEADER_FOOTER_EAT_SPACING, true)); + } + } + // Might as well turn on margin mirroring too - if appropriate if (pDlg->GetMirrorOnEvenPages() && !bHeaderAlreadyOn && !bFooterAlreadyOn && !bIsSinglePage diff --git a/sw/uiconfig/swriter/ui/pagenumberdlg.ui b/sw/uiconfig/swriter/ui/pagenumberdlg.ui index f014545da429..e876594c05c5 100644 --- a/sw/uiconfig/swriter/ui/pagenumberdlg.ui +++ b/sw/uiconfig/swriter/ui/pagenumberdlg.ui @@ -212,6 +212,28 @@ </packing> </child> <child> + <object class="GtkCheckButton" id="fitintoexistingmarginsCheckbox"> + <property name="label" translatable="yes" context="pagenumberdlg|fitintoexistingmarginsCheckbox">Fit into existing margins</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="fitintoexistingmarginsCheckbox-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="pagenumberdlg|extended_tip|fitintoexistingmarginsCheckbox">Reduce the margin so that adding the page number will not change the page layout</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">6</property> + </packing> + </child> + <child> <object class="GtkLabel" id="numfmtLabel"> <property name="visible">True</property> <property name="can-focus">False</property> @@ -232,7 +254,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">6</property> + <property name="position">7</property> </packing> </child> <child> @@ -251,7 +273,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">7</property> + <property name="position">8</property> </packing> </child> </object> |