LibreOffice Module sw (master) 1
titlepage.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <view.hxx>
11#include <swmodule.hxx>
12#include <wrtsh.hxx>
13#include <poolfmt.hxx>
14#include <docsh.hxx>
15
16#include <titlepage.hxx>
17#include <fmtpdsc.hxx>
18#include <pagedesc.hxx>
19
20namespace
21{
22 bool lcl_GetPageDesc(SwWrtShell& rSh, sal_uInt16 &rPageNo, std::unique_ptr<const SwFormatPageDesc>* ppPageFormatDesc)
23 {
24 bool bRet = false;
26 if (rSh.GetCurAttr(aSet))
27 {
28 if (const SwFormatPageDesc* pDescItem = aSet.GetItemIfSet( RES_PAGEDESC ))
29 {
30 ::std::optional<sal_uInt16> oNumOffset = pDescItem->GetNumOffset();
31 if (oNumOffset)
32 rPageNo = *oNumOffset;
33 if (ppPageFormatDesc)
34 ppPageFormatDesc->reset(static_cast<const SwFormatPageDesc *>(pDescItem->Clone()));
35 bRet = true;
36 }
37 }
38 return bRet;
39 }
40
41 void lcl_ChangePage(SwWrtShell& rSh, sal_uInt16 nNewNumber, const SwPageDesc *pNewDesc)
42 {
43 const size_t nCurIdx = rSh.GetCurPageDesc();
44 const SwPageDesc &rCurrentDesc = rSh.GetPageDesc(nCurIdx);
45
46 std::unique_ptr<const SwFormatPageDesc> pPageFormatDesc;
47 sal_uInt16 nDontCare;
48 lcl_GetPageDesc(rSh, nDontCare, &pPageFormatDesc);
49
50 // If we want a new number then set it, otherwise reuse the existing one
51 sal_uInt16 nPgNo = 0;
52 if (nNewNumber)
53 {
54 // -1: Allow special case to prevent inheriting re-numbering from the existing page.
55 nPgNo = nNewNumber == SAL_MAX_UINT16 ? 0 : nNewNumber;
56 }
57 else if (pPageFormatDesc)
58 {
59 ::std::optional<sal_uInt16> oNumOffset = pPageFormatDesc->GetNumOffset();
60 if (oNumOffset)
61 nPgNo = *oNumOffset;
62 }
63
64 // If we want a new descriptor then set it, otherwise reuse the existing one
65 if (pNewDesc || nPgNo)
66 {
67 SwFormatPageDesc aPageFormatDesc(pNewDesc ? pNewDesc : &rCurrentDesc);
68 if (nPgNo) aPageFormatDesc.SetNumOffset(nPgNo);
69 rSh.SetAttrItem(aPageFormatDesc);
70 }
71 }
72
73 void lcl_PushCursor(SwWrtShell& rSh)
74 {
75 rSh.LockView(true);
76 rSh.StartAllAction();
77 rSh.SwCursorShell::Push();
78 }
79
80 void lcl_PopCursor(SwWrtShell& rSh)
81 {
82 rSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
83 rSh.EndAllAction();
84 rSh.LockView(false);
85 }
86
87 sal_uInt16 lcl_GetCurrentPage(const SwWrtShell& rSh)
88 {
89 OUString sDummy;
90 sal_uInt16 nPhyNum=1, nVirtNum=1;
91 rSh.GetPageNumber(0, true, nPhyNum, nVirtNum, sDummy);
92 return nPhyNum;
93 }
94
95bool lcl_GotoPage(SwWrtShell& rSh, const sal_uInt16 nStartingPage, sal_uInt16 nOffset = 0)
96{
97 rSh.GotoPage(nStartingPage, /*bRecord=*/false);
98
99 sal_uInt16 nCurrentPage = lcl_GetCurrentPage(rSh);
100 // return false if at document end (unless that was the requested destination)
101 if (nCurrentPage == rSh.GetPageCnt())
102 return nCurrentPage == nStartingPage + nOffset;
103
104 if (nCurrentPage != nStartingPage)
105 {
106 assert(nStartingPage != 1 && "Physical page 1 couldn't be found/moved to?");
107 // Probably there is an auto-inserted blank page to handle odd/even, which Goto doesn't understand.
108 rSh.GotoPage(nStartingPage + 1, /*bRecord=*/false);
109
110 nCurrentPage = lcl_GetCurrentPage(rSh);
111 assert(nCurrentPage == nStartingPage + 1 && "Impossible, since unknown goes to last page");
112 if (nCurrentPage != nStartingPage + 1)
113 return false;
114 }
115 // Now that we have the correct starting point, move to the correct offset.
116 while (nOffset--)
117 rSh.SttNxtPg();
118 return true;
119}
120} // namespace
121
122/*
123 * Only include the Index page in the list if the page count implies one
124 * to reduce confusing things
125 */
127{
128 sal_uInt16 nTitlePages = m_xPageCountNF->get_value();
129 m_xPagePropertiesLB->clear();
130 if (mpTitleDesc)
131 m_xPagePropertiesLB->append_text(mpTitleDesc->GetName());
132 if (nTitlePages > 1 && mpIndexDesc)
133 m_xPagePropertiesLB->append_text(mpIndexDesc->GetName());
134 if (mpNormalDesc)
136 m_xPagePropertiesLB->set_active(0);
137}
138
140{
141 sal_uInt16 nPage = 1;
142 if (m_xPageStartNF->get_sensitive())
143 nPage = m_xPageStartNF->get_value();
144 return nPage;
145}
146
148 : SfxDialogController(pParent, "modules/swriter/ui/titlepage.ui", "DLG_TITLEPAGE")
149 , mrSh(*::GetActiveView()->GetWrtShellPtr())
150 , m_xUseExistingPagesRB(m_xBuilder->weld_radio_button("RB_USE_EXISTING_PAGES"))
151 , m_xPageCountNF(m_xBuilder->weld_spin_button("NF_PAGE_COUNT"))
152 , m_xDocumentStartRB(m_xBuilder->weld_radio_button("RB_DOCUMENT_START"))
153 , m_xPageStartRB(m_xBuilder->weld_radio_button("RB_PAGE_START"))
154 , m_xPageStartNF(m_xBuilder->weld_spin_button("NF_PAGE_START"))
155 , m_xRestartNumberingCB(m_xBuilder->weld_check_button("CB_RESTART_NUMBERING"))
156 , m_xRestartNumberingNF(m_xBuilder->weld_spin_button("NF_RESTART_NUMBERING"))
157 , m_xSetPageNumberCB(m_xBuilder->weld_check_button("CB_SET_PAGE_NUMBER"))
158 , m_xSetPageNumberNF(m_xBuilder->weld_spin_button("NF_SET_PAGE_NUMBER"))
159 , m_xPagePropertiesLB(m_xBuilder->weld_combo_box("LB_PAGE_PROPERTIES"))
160 , m_xPagePropertiesPB(m_xBuilder->weld_button("PB_PAGE_PROPERTIES"))
161 , m_xOkPB(m_xBuilder->weld_button("ok"))
162{
163 m_xOkPB->connect_clicked(LINK(this, SwTitlePageDlg, OKHdl));
164 m_xRestartNumberingCB->connect_toggled(LINK(this, SwTitlePageDlg, RestartNumberingHdl));
165 m_xSetPageNumberCB->connect_toggled(LINK(this, SwTitlePageDlg, SetPageNumberHdl));
166 m_xPageStartNF->set_max(mrSh.GetPageCnt() + 1);
167
168 sal_uInt16 nSetPage = 1;
169 sal_uInt16 nResetPage = 1;
170 sal_uInt16 nTitlePages = 1;
171 lcl_PushCursor(mrSh);
172
173 SwView& rView = mrSh.GetView();
174 rView.InvalidateRulerPos();
175
176 bool bMaybeResetNumbering = false;
177
181
183 if (lcl_GetPageDesc(mrSh, nSetPage, &mpPageFormatDesc))
184 {
185 if (mpPageFormatDesc->GetPageDesc() == mpTitleDesc)
186 {
187 while (mrSh.SttNxtPg())
188 {
189 const size_t nCurIdx = mrSh.GetCurPageDesc();
190 const SwPageDesc& rPageDesc = mrSh.GetPageDesc(nCurIdx);
191
192 if (mpIndexDesc != &rPageDesc)
193 {
194 mpNormalDesc = &rPageDesc;
195 bMaybeResetNumbering = lcl_GetPageDesc(mrSh, nResetPage, nullptr);
196 break;
197 }
198 ++nTitlePages;
199 }
200 }
201 }
202 lcl_PopCursor(mrSh);
203
204 m_xUseExistingPagesRB->set_active(true);
205 m_xPageCountNF->set_value(nTitlePages);
206 m_xPageCountNF->connect_value_changed(LINK(this, SwTitlePageDlg, ValueChangeHdl));
207
208 m_xDocumentStartRB->set_active(true);
209 m_xPageStartNF->set_sensitive(false);
210 m_xPageStartNF->set_value(lcl_GetCurrentPage(mrSh));
211 Link<weld::Toggleable&,void> aStartPageHdl = LINK(this, SwTitlePageDlg, StartPageHdl);
212 m_xDocumentStartRB->connect_toggled(aStartPageHdl);
213 m_xPageStartRB->connect_toggled(aStartPageHdl);
214
215 m_xRestartNumberingNF->set_value(nResetPage);
216 if (bMaybeResetNumbering && nResetPage > 0)
217 {
218 m_xRestartNumberingCB->set_active(true);
219 }
220 m_xRestartNumberingNF->set_sensitive(m_xRestartNumberingCB->get_active());
221
222 m_xSetPageNumberNF->set_value(nSetPage);
223 if (nSetPage > 1)
224 m_xSetPageNumberCB->set_active(true);
225 m_xSetPageNumberNF->set_sensitive(m_xSetPageNumberCB->get_active());
226
227 FillList();
228 m_xPagePropertiesPB->connect_clicked(LINK(this, SwTitlePageDlg, EditHdl));
229}
230
232{
233 if (m_xPageCountNF->get_value() == 1 || m_xPageCountNF->get_value() == 2)
234 FillList();
235}
236
238{
239 m_xRestartNumberingNF->set_sensitive(m_xRestartNumberingCB->get_active());
240}
241
243{
244 m_xSetPageNumberNF->set_sensitive(m_xSetPageNumberCB->get_active());
245}
246
248{
249 m_xPageStartNF->set_sensitive(m_xPageStartRB->get_active());
250}
251
253{
254}
255
257{
258 SwView& rView = mrSh.GetView();
259 rView.GetDocShell()->FormatPage(getDialog(), m_xPagePropertiesLB->get_active_text(), "page", mrSh);
260 rView.InvalidateRulerPos();
261}
262
264{
265 lcl_PushCursor(mrSh);
266
267 mrSh.StartUndo();
268
269 SwFormatPageDesc aTitleDesc(mpTitleDesc);
270
271 if (m_xSetPageNumberCB->get_active())
272 aTitleDesc.SetNumOffset(m_xSetPageNumberNF->get_value());
273 else if (mpPageFormatDesc)
274 aTitleDesc.SetNumOffset(mpPageFormatDesc->GetNumOffset());
275
276 sal_uInt16 nNumTitlePages = m_xPageCountNF->get_value();
277 if (!m_xUseExistingPagesRB->get_active())
278 {
279 // Assuming that a failure to GotoPage means the end of the document,
280 // insert new pages after the last page.
281 if (!lcl_GotoPage(mrSh, GetInsertPosition()))
282 {
283 mrSh.EndPg();
284 // Add one more page as a content page to follow the new title pages.
285 mrSh.InsertPageBreak();
286 }
287 for (sal_uInt16 nI = 0; nI < nNumTitlePages; ++nI)
288 mrSh.InsertPageBreak();
289 // In order to be able to access these new pages, the layout needs to be recalculated first.
290 mrSh.CalcLayout();
291 }
292
293 if (lcl_GotoPage(mrSh, GetInsertPosition()))
294 {
295 mrSh.SetAttrItem(aTitleDesc);
296 for (sal_uInt16 nI = 1; nI < nNumTitlePages; ++nI)
297 {
298 if (mrSh.SttNxtPg())
299 lcl_ChangePage(mrSh, SAL_MAX_UINT16, mpIndexDesc);
300 }
301 }
302
303 if ((m_xRestartNumberingCB->get_active() || nNumTitlePages > 1)
304 && lcl_GotoPage(mrSh, GetInsertPosition(), nNumTitlePages))
305 {
306 sal_uInt16 nPgNo
307 = m_xRestartNumberingCB->get_active() ? m_xRestartNumberingNF->get_value() : 0;
308 const SwPageDesc* pNewDesc = nNumTitlePages > 1 ? mpNormalDesc : nullptr;
309 lcl_ChangePage(mrSh, nPgNo, pNewDesc);
310 }
311
312 mrSh.EndUndo();
313 lcl_PopCursor(mrSh);
314 if (!m_xUseExistingPagesRB->get_active())
315 lcl_GotoPage(mrSh, GetInsertPosition());
316 m_xDialog->response(RET_OK);
317}
318
319/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XExecutableDialog > m_xDialog
sal_uInt16 GetPageCnt()
Definition: crsrsh.cxx:1291
void FormatPage(weld::Window *pDialogParent, const OUString &rPage, const OString &rPageId, SwWrtShell &rActShell, SfxRequest *pRequest=nullptr)
Show page style format dialog.
Definition: docst.cxx:1633
bool GetCurAttr(SfxItemSet &, const bool bMergeIndentValuesOfNumRule=false) const
Definition: edattr.cxx:171
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
void SetAttrItem(const SfxPoolItem &, SetAttrMode nFlags=SetAttrMode::DEFAULT, const bool bParagraphSetting=false)
Definition: edatmisc.cxx:98
SwPageDesc * GetPageDescFromPool(sal_uInt16 nId)
Definition: edfmt.cxx:132
void EndAllAction()
Definition: edws.cxx:97
size_t GetCurPageDesc(const bool bCalcFrame=true) const
Definition: fedesc.cxx:167
const SwPageDesc & GetPageDesc(size_t i) const
Definition: fedesc.cxx:126
sal_uInt16 GetPageNumber(const Point &rPoint) const
Page number of the page containing Point, O if no page.
Definition: fews.cxx:185
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:36
void SetNumOffset(const ::std::optional< sal_uInt16 > &oNum)
Definition: fmtpdsc.hxx:65
const OUString & GetName() const
Definition: pagedesc.hxx:196
std::unique_ptr< weld::RadioButton > m_xDocumentStartRB
Definition: titlepage.hxx:37
std::unique_ptr< weld::SpinButton > m_xPageStartNF
Definition: titlepage.hxx:39
const SwPageDesc * mpIndexDesc
Definition: titlepage.hxx:32
std::unique_ptr< weld::RadioButton > m_xUseExistingPagesRB
Definition: titlepage.hxx:35
std::unique_ptr< weld::ComboBox > m_xPagePropertiesLB
Definition: titlepage.hxx:44
SwWrtShell & mrSh
Definition: titlepage.hxx:27
virtual ~SwTitlePageDlg() override
Definition: titlepage.cxx:252
SwTitlePageDlg(weld::Window *pParent)
Definition: titlepage.cxx:147
sal_uInt16 GetInsertPosition() const
Definition: titlepage.cxx:139
std::unique_ptr< weld::SpinButton > m_xRestartNumberingNF
Definition: titlepage.hxx:41
std::unique_ptr< weld::CheckButton > m_xSetPageNumberCB
Definition: titlepage.hxx:42
std::unique_ptr< weld::SpinButton > m_xSetPageNumberNF
Definition: titlepage.hxx:43
std::unique_ptr< weld::CheckButton > m_xRestartNumberingCB
Definition: titlepage.hxx:40
std::unique_ptr< const SwFormatPageDesc > mpPageFormatDesc
Definition: titlepage.hxx:29
std::unique_ptr< weld::RadioButton > m_xPageStartRB
Definition: titlepage.hxx:38
SwPageDesc * mpTitleDesc
Definition: titlepage.hxx:31
const SwPageDesc * mpNormalDesc
Definition: titlepage.hxx:33
std::unique_ptr< weld::Button > m_xPagePropertiesPB
Definition: titlepage.hxx:45
std::unique_ptr< weld::Button > m_xOkPB
Definition: titlepage.hxx:46
std::unique_ptr< weld::SpinButton > m_xPageCountNF
Definition: titlepage.hxx:36
void LockView(bool b)
Definition: viewsh.hxx:472
const SfxItemPool & GetAttrPool() const
Definition: viewsh.hxx:624
Definition: view.hxx:146
SwDocShell * GetDocShell()
Definition: view.cxx:1160
void InvalidateRulerPos()
Definition: viewport.cxx:107
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
bool GotoPage(sal_uInt16 nPage, bool bRecord)
Definition: move.cxx:573
bool SttNxtPg(bool bSelect=false)
Definition: move.cxx:320
bool StartOfSection(bool bSelect=false)
Definition: move.cxx:308
const SwView & GetView() const
Definition: wrtsh.hxx:443
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
@ RES_POOLPAGE_REGISTER
Index.
Definition: poolfmt.hxx:175
@ RES_POOLPAGE_FIRST
First page.
Definition: poolfmt.hxx:171
@ RES_POOLPAGE_STANDARD
Standard page.
Definition: poolfmt.hxx:170
SwView * GetActiveView()
Definition: swmodul1.cxx:116
IMPL_LINK_NOARG(SwTitlePageDlg, ValueChangeHdl, weld::SpinButton &, void)
Definition: titlepage.cxx:231
#define SAL_MAX_UINT16
static SwPageDesc * lcl_GetPageDesc(SwDoc *pDoc, const uno::Any &aValue)
Definition: unosett.cxx:222
RET_OK