summaryrefslogtreecommitdiff
path: root/sw/source/uibase
diff options
context:
space:
mode:
authorJustin Luth <justin.luth@collabora.com>2023-04-26 13:29:25 -0400
committerMiklos Vajna <vmiklos@collabora.com>2023-04-28 08:08:06 +0200
commit21fad629e72791f6cc1791fdba858bf52b9bfeff (patch)
tree0352ed38b87dfd1a5a24258c4c73007c814b711a /sw/source/uibase
parentd4cf5814146e375805df98eafba2baf321b9b005 (diff)
tdf#86630 sw page number wizard: mirror right/left
If the user puts the page numbers on the left or right side of the page, they usually want that mirrored on even and odd pages. This got rather tricky, but in the end I have enough safeguards that it seems to work logically and stablely. So I think it is ready to be submitted. Change-Id: I321e575cd9f6718579ffee99f1258bffe26581f2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151152 Reviewed-by: Justin Luth <jluth@mail.com> Tested-by: Jenkins
Diffstat (limited to 'sw/source/uibase')
-rw-r--r--sw/source/uibase/inc/pagenumberdlg.hxx2
-rw-r--r--sw/source/uibase/shells/textfld.cxx103
2 files changed, 102 insertions, 3 deletions
diff --git a/sw/source/uibase/inc/pagenumberdlg.hxx b/sw/source/uibase/inc/pagenumberdlg.hxx
index 5e093b5a924f..b5dccd93127a 100644
--- a/sw/source/uibase/inc/pagenumberdlg.hxx
+++ b/sw/source/uibase/inc/pagenumberdlg.hxx
@@ -31,6 +31,7 @@ class SwPageNumberDlg final : public SfxDialogController
std::unique_ptr<weld::Button> m_xCancel;
std::unique_ptr<weld::ComboBox> m_xPageNumberPosition;
std::unique_ptr<weld::ComboBox> m_xPageNumberAlignment;
+ std::unique_ptr<weld::CheckButton> m_xMirrorOnEvenPages;
std::unique_ptr<SvxPageNumberListBox> m_xPageNumberTypeLB;
std::unique_ptr<weld::Image> m_xPreviewImage;
@@ -50,6 +51,7 @@ public:
SwPageNumberDlg(weld::Window* pParent);
int GetPageNumberPosition() const { return m_aPageNumberPosition; }
int GetPageNumberAlignment() const { return m_aPageNumberAlignment; }
+ bool GetMirrorOnEvenPages();
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 766d5e03c0a2..eb21afce0482 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -1052,6 +1052,8 @@ FIELD_INSERT:
const SwPageDesc& rDesc = rSh.GetPageDesc(nPageDescIndex);
const bool bHeaderAlreadyOn = rDesc.GetMaster().GetHeader().IsActive();
const bool bFooterAlreadyOn = rDesc.GetMaster().GetFooter().IsActive();
+ const bool bIsSinglePage = rDesc.GetFollow() != &rDesc;
+ const size_t nMirrorPagesNeeded = rDesc.IsFirstShared() ? 2 : 3;
SvxPageItem aPageItem(SID_ATTR_PAGE);
aPageItem.SetNumType(pDlg->GetPageNumberType());
@@ -1066,10 +1068,76 @@ FIELD_INSERT:
else if (!bHeader && !bFooterAlreadyOn)
rSh.ChangeHeaderOrFooter(rDesc.GetName(), false, /*On=*/true, /*Warn=*/false);
- if (bHeader)
- rSh.GotoHeaderText();
+ const bool bCreateMirror = !bIsSinglePage && pDlg->GetMirrorOnEvenPages()
+ && nMirrorPagesNeeded <= rSh.GetPageCnt();
+ if (bCreateMirror)
+ {
+ // Use different left/right header/footer
+ if ((bHeader && rDesc.IsHeaderShared()) || (!bHeader && rDesc.IsFooterShared()))
+ {
+ SwPageDesc rNewDesc(rSh.GetPageDesc(nPageDescIndex));
+
+ if (bHeader)
+ rNewDesc.ChgHeaderShare(false);
+ else
+ rNewDesc.ChgFooterShare(false);
+
+ rSh.ChgPageDesc(nPageDescIndex, rNewDesc);
+ }
+ }
+
+ // Go to the header or footer insert position
+ bool bInHF = false;
+ bool bSkipMirror = true;
+ size_t nEvenPage = 0;
+ if (bCreateMirror)
+ {
+ // There are enough pages that there probably is a valid odd page.
+ // However, that is not guaranteed: perhaps the page style switched,
+ // or a blank page was forced, or some other complexity.
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true);
+ if (bInHF)
+ {
+ // Remember valid EVEN page. Mirror it if also a valid ODD or FIRST page
+ nEvenPage = rSh.GetVirtPageNum();
+ assert (nEvenPage && "couldn't find page number. Use a bool instead");
+ }
+
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/false);
+ if (bInHF && nEvenPage)
+ {
+ // Even though the cursor may be on a FIRST page,
+ // the user requested mirrored pages, and we have both ODD and EVEN,
+ // so set page numbers on these two pages, and leave FIRST alone.
+ bSkipMirror = false;
+ }
+ if (!bInHF)
+ {
+ // no ODD page, look for FIRST page
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, false, /*First=*/true);
+ if (bInHF && nEvenPage)
+ {
+ // Unlikely but valid situation: EVEN and FIRST pages, but no ODD page.
+ // In this case, the first header gets the specified page number
+ // and the even header is mirrored, with an empty odd header,
+ // as the user (somewhat) requested.
+ bSkipMirror = false;
+ }
+ }
+ assert((bInHF || nEvenPage) && "Impossible - why couldn't the move happen?");
+ assert((bInHF || nEvenPage == rSh.GetVirtPageNum()) && "Unexpected move");
+ }
else
- rSh.GotoFooterText();
+ {
+ // CurrFrame is lost when mirror is created. Goto*Text crashes if no CurrFrame
+ assert(rSh.GetCurrFrame()); // not guaranteed, but normally assumed
+
+ if (bHeader)
+ bInHF = rSh.GotoHeaderText();
+ else
+ bInHF = rSh.GotoFooterText();
+ assert(bInHF && "shouldn't have a problem going to text when no mirroring");
+ }
SwTextNode* pTextNode = rSh.GetCursor()->GetPoint()->GetNode().GetTextNode();
@@ -1114,6 +1182,35 @@ FIELD_INSERT:
OUString(), OUString(), SVX_NUM_PAGEDESC);
aMgr.InsertField(aData);
+ // Mirror on the even pages
+ if (!bSkipMirror && bCreateMirror
+ && rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true))
+ {
+ assert(nEvenPage && "what? no even page and yet we got here?");
+ pTextNode = rSh.GetCursor()->GetPoint()->GetNode().GetTextNode();
+
+ // Insert new line if there is already text in header/footer
+ if (pTextNode && !pTextNode->GetText().isEmpty())
+ {
+ rDoc->getIDocumentContentOperations().SplitNode(
+ *rSh.GetCursor()->GetPoint(), false);
+ // Go back to start of header/footer
+ rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true);
+ }
+
+ // mirror the adjustment
+ assert(pDlg->GetPageNumberAlignment() != 1 && "cannot have Center and bMirror");
+ SvxAdjust eAdjust = SvxAdjust::Left;
+ if (!pDlg->GetPageNumberAlignment())
+ eAdjust = SvxAdjust::Right;
+ SvxAdjustItem aMirrorAdjustItem(eAdjust, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aMirrorAdjustItem);
+
+ // Insert page number
+ SwFieldMgr aEvenMgr(pShell);
+ aEvenMgr.InsertField(aData);
+ }
+
rSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
rSh.EndAllAction();
rSh.LockView(false);