summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Luth <jluth@mail.com>2024-06-21 10:42:08 -0400
committerAndras Timar <andras.timar@collabora.com>2024-07-03 15:40:45 +0200
commit4e7ac2acefc8cedf95be03d3145b6ef2e6027767 (patch)
tree63acf91be048be2d5ff27631af856e6f69bd52d7
parent574d5ce168cd0f628a361cd0689039daf8b82387 (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.hxx1
-rw-r--r--sw/source/ui/dialog/swdlgfact.cxx5
-rw-r--r--sw/source/ui/dialog/swdlgfact.hxx1
-rw-r--r--sw/source/ui/misc/pagenumberdlg.cxx12
-rw-r--r--sw/source/uibase/inc/pagenumberdlg.hxx6
-rw-r--r--sw/source/uibase/shells/textfld.cxx73
-rw-r--r--sw/uiconfig/swriter/ui/pagenumberdlg.ui26
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>