android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / ui / misc / titlepage.cxx
blob4308c8db246dfc811417946daf3e7c5232726111
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <view.hxx>
11 #include <swmodule.hxx>
12 #include <wrtsh.hxx>
13 #include <poolfmt.hxx>
14 #include <docsh.hxx>
16 #include <titlepage.hxx>
17 #include <fmtpdsc.hxx>
18 #include <pagedesc.hxx>
20 namespace
22 bool lcl_GetPageDesc(SwWrtShell& rSh, sal_uInt16 &rPageNo, std::unique_ptr<const SwFormatPageDesc>* ppPageFormatDesc)
24 bool bRet = false;
25 SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC> aSet(rSh.GetAttrPool());
26 if (rSh.GetCurAttr(aSet))
28 if (const SwFormatPageDesc* pDescItem = aSet.GetItemIfSet( RES_PAGEDESC ))
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;
38 return bRet;
41 void lcl_ChangePage(SwWrtShell& rSh, sal_uInt16 nNewNumber, const SwPageDesc *pNewDesc)
43 const size_t nCurIdx = rSh.GetCurPageDesc();
44 const SwPageDesc &rCurrentDesc = rSh.GetPageDesc(nCurIdx);
46 std::unique_ptr<const SwFormatPageDesc> pPageFormatDesc;
47 sal_uInt16 nDontCare;
48 lcl_GetPageDesc(rSh, nDontCare, &pPageFormatDesc);
50 // If we want a new number then set it, otherwise reuse the existing one
51 sal_uInt16 nPgNo = 0;
52 if (nNewNumber)
54 // -1: Allow special case to prevent inheriting re-numbering from the existing page.
55 nPgNo = nNewNumber == SAL_MAX_UINT16 ? 0 : nNewNumber;
57 else if (pPageFormatDesc)
59 ::std::optional<sal_uInt16> oNumOffset = pPageFormatDesc->GetNumOffset();
60 if (oNumOffset)
61 nPgNo = *oNumOffset;
64 // If we want a new descriptor then set it, otherwise reuse the existing one
65 if (pNewDesc || nPgNo)
67 SwFormatPageDesc aPageFormatDesc(pNewDesc ? pNewDesc : &rCurrentDesc);
68 if (nPgNo) aPageFormatDesc.SetNumOffset(nPgNo);
69 rSh.SetAttrItem(aPageFormatDesc);
73 void lcl_PushCursor(SwWrtShell& rSh)
75 rSh.LockView(true);
76 rSh.StartAllAction();
77 rSh.SwCursorShell::Push();
80 void lcl_PopCursor(SwWrtShell& rSh)
82 rSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
83 rSh.EndAllAction();
84 rSh.LockView(false);
87 sal_uInt16 lcl_GetCurrentPage(const SwWrtShell& rSh)
89 OUString sDummy;
90 sal_uInt16 nPhyNum=1, nVirtNum=1;
91 rSh.GetPageNumber(0, true, nPhyNum, nVirtNum, sDummy);
92 return nPhyNum;
95 bool lcl_GotoPage(SwWrtShell& rSh, const sal_uInt16 nStartingPage, sal_uInt16 nOffset = 0)
97 rSh.GotoPage(nStartingPage, /*bRecord=*/false);
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;
104 if (nCurrentPage != nStartingPage)
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);
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;
115 // Now that we have the correct starting point, move to the correct offset.
116 while (nOffset--)
117 rSh.SttNxtPg();
118 return true;
120 } // namespace
123 * Only include the Index page in the list if the page count implies one
124 * to reduce confusing things
126 void SwTitlePageDlg::FillList()
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)
135 m_xPagePropertiesLB->append_text(mpNormalDesc->GetName());
136 m_xPagePropertiesLB->set_active(0);
139 sal_uInt16 SwTitlePageDlg::GetInsertPosition() const
141 sal_uInt16 nPage = 1;
142 if (m_xPageStartNF->get_sensitive())
143 nPage = m_xPageStartNF->get_value();
144 return nPage;
147 SwTitlePageDlg::SwTitlePageDlg(weld::Window *pParent)
148 : SfxDialogController(pParent, "modules/swriter/ui/titlepage.ui", "DLG_TITLEPAGE")
149 , mpTitleDesc(nullptr)
150 , mpIndexDesc(nullptr)
151 , mpNormalDesc(nullptr)
152 , m_xUseExistingPagesRB(m_xBuilder->weld_radio_button("RB_USE_EXISTING_PAGES"))
153 , m_xPageCountNF(m_xBuilder->weld_spin_button("NF_PAGE_COUNT"))
154 , m_xDocumentStartRB(m_xBuilder->weld_radio_button("RB_DOCUMENT_START"))
155 , m_xPageStartRB(m_xBuilder->weld_radio_button("RB_PAGE_START"))
156 , m_xPageStartNF(m_xBuilder->weld_spin_button("NF_PAGE_START"))
157 , m_xRestartNumberingCB(m_xBuilder->weld_check_button("CB_RESTART_NUMBERING"))
158 , m_xRestartNumberingNF(m_xBuilder->weld_spin_button("NF_RESTART_NUMBERING"))
159 , m_xSetPageNumberCB(m_xBuilder->weld_check_button("CB_SET_PAGE_NUMBER"))
160 , m_xSetPageNumberNF(m_xBuilder->weld_spin_button("NF_SET_PAGE_NUMBER"))
161 , m_xPagePropertiesLB(m_xBuilder->weld_combo_box("LB_PAGE_PROPERTIES"))
162 , m_xPagePropertiesPB(m_xBuilder->weld_button("PB_PAGE_PROPERTIES"))
163 , m_xOkPB(m_xBuilder->weld_button("ok"))
165 SwView* pView = GetActiveView();
166 if (!pView)
167 return;
168 SwWrtShell& rWrtShell = pView->GetWrtShell();
170 m_xOkPB->connect_clicked(LINK(this, SwTitlePageDlg, OKHdl));
171 m_xRestartNumberingCB->connect_toggled(LINK(this, SwTitlePageDlg, RestartNumberingHdl));
172 m_xSetPageNumberCB->connect_toggled(LINK(this, SwTitlePageDlg, SetPageNumberHdl));
173 m_xPageStartNF->set_max(rWrtShell.GetPageCnt() + 1);
175 sal_uInt16 nSetPage = 1;
176 sal_uInt16 nResetPage = 1;
177 sal_uInt16 nTitlePages = 1;
178 lcl_PushCursor(rWrtShell);
180 SwView& rView = rWrtShell.GetView();
181 rView.InvalidateRulerPos();
183 bool bMaybeResetNumbering = false;
185 mpTitleDesc = rWrtShell.GetPageDescFromPool(RES_POOLPAGE_FIRST);
186 mpIndexDesc = rWrtShell.GetPageDescFromPool(RES_POOLPAGE_REGISTER);
187 mpNormalDesc = rWrtShell.GetPageDescFromPool(RES_POOLPAGE_STANDARD);
189 rWrtShell.StartOfSection();
190 if (lcl_GetPageDesc(rWrtShell, nSetPage, &mpPageFormatDesc))
192 if (mpPageFormatDesc->GetPageDesc() == mpTitleDesc)
194 while (rWrtShell.SttNxtPg())
196 const size_t nCurIdx = rWrtShell.GetCurPageDesc();
197 const SwPageDesc& rPageDesc = rWrtShell.GetPageDesc(nCurIdx);
199 if (mpIndexDesc != &rPageDesc)
201 mpNormalDesc = &rPageDesc;
202 bMaybeResetNumbering = lcl_GetPageDesc(rWrtShell, nResetPage, nullptr);
203 break;
205 ++nTitlePages;
209 lcl_PopCursor(rWrtShell);
211 m_xUseExistingPagesRB->set_active(true);
212 m_xPageCountNF->set_value(nTitlePages);
213 m_xPageCountNF->connect_value_changed(LINK(this, SwTitlePageDlg, ValueChangeHdl));
215 m_xDocumentStartRB->set_active(true);
216 m_xPageStartNF->set_sensitive(false);
217 m_xPageStartNF->set_value(lcl_GetCurrentPage(rWrtShell));
218 Link<weld::Toggleable&,void> aStartPageHdl = LINK(this, SwTitlePageDlg, StartPageHdl);
219 m_xDocumentStartRB->connect_toggled(aStartPageHdl);
220 m_xPageStartRB->connect_toggled(aStartPageHdl);
222 m_xRestartNumberingNF->set_value(nResetPage);
223 if (bMaybeResetNumbering && nResetPage > 0)
225 m_xRestartNumberingCB->set_active(true);
227 m_xRestartNumberingNF->set_sensitive(m_xRestartNumberingCB->get_active());
229 m_xSetPageNumberNF->set_value(nSetPage);
230 if (nSetPage > 1)
231 m_xSetPageNumberCB->set_active(true);
232 m_xSetPageNumberNF->set_sensitive(m_xSetPageNumberCB->get_active());
234 FillList();
235 m_xPagePropertiesPB->connect_clicked(LINK(this, SwTitlePageDlg, EditHdl));
238 IMPL_LINK_NOARG(SwTitlePageDlg, ValueChangeHdl, weld::SpinButton&, void)
240 if (m_xPageCountNF->get_value() == 1 || m_xPageCountNF->get_value() == 2)
241 FillList();
244 IMPL_LINK_NOARG(SwTitlePageDlg, RestartNumberingHdl, weld::Toggleable&, void)
246 m_xRestartNumberingNF->set_sensitive(m_xRestartNumberingCB->get_active());
249 IMPL_LINK_NOARG(SwTitlePageDlg, SetPageNumberHdl, weld::Toggleable&, void)
251 m_xSetPageNumberNF->set_sensitive(m_xSetPageNumberCB->get_active());
254 IMPL_LINK_NOARG(SwTitlePageDlg, StartPageHdl, weld::Toggleable&, void)
256 m_xPageStartNF->set_sensitive(m_xPageStartRB->get_active());
259 SwTitlePageDlg::~SwTitlePageDlg()
263 IMPL_LINK_NOARG(SwTitlePageDlg, EditHdl, weld::Button&, void)
265 SwView* pView = GetActiveView();
266 if (!pView)
267 return;
268 SwWrtShell& rWrtShell = pView->GetWrtShell();
269 SwView& rView = rWrtShell.GetView();
270 rView.GetDocShell()->FormatPage(getDialog(), m_xPagePropertiesLB->get_active_text(), "page", rWrtShell);
271 rView.InvalidateRulerPos();
274 IMPL_LINK_NOARG(SwTitlePageDlg, OKHdl, weld::Button&, void)
276 SwView* pView = GetActiveView();
277 if (!pView)
278 return;
279 SwWrtShell& rWrtShell = pView->GetWrtShell();
280 lcl_PushCursor(rWrtShell);
282 rWrtShell.StartUndo();
284 SwFormatPageDesc aTitleDesc(mpTitleDesc);
286 if (m_xSetPageNumberCB->get_active())
287 aTitleDesc.SetNumOffset(m_xSetPageNumberNF->get_value());
288 else if (mpPageFormatDesc)
289 aTitleDesc.SetNumOffset(mpPageFormatDesc->GetNumOffset());
291 sal_uInt16 nNumTitlePages = m_xPageCountNF->get_value();
292 if (!m_xUseExistingPagesRB->get_active())
294 // Assuming that a failure to GotoPage means the end of the document,
295 // insert new pages after the last page.
296 if (!lcl_GotoPage(rWrtShell, GetInsertPosition()))
298 rWrtShell.EndPg();
299 // Add one more page as a content page to follow the new title pages.
300 rWrtShell.InsertPageBreak();
302 for (sal_uInt16 nI = 0; nI < nNumTitlePages; ++nI)
303 rWrtShell.InsertPageBreak();
304 // In order to be able to access these new pages, the layout needs to be recalculated first.
305 rWrtShell.CalcLayout();
308 if (lcl_GotoPage(rWrtShell, GetInsertPosition()))
310 rWrtShell.SetAttrItem(aTitleDesc);
311 for (sal_uInt16 nI = 1; nI < nNumTitlePages; ++nI)
313 if (rWrtShell.SttNxtPg())
314 lcl_ChangePage(rWrtShell, SAL_MAX_UINT16, mpIndexDesc);
318 if ((m_xRestartNumberingCB->get_active() || nNumTitlePages > 1)
319 && lcl_GotoPage(rWrtShell, GetInsertPosition(), nNumTitlePages))
321 sal_uInt16 nPgNo
322 = m_xRestartNumberingCB->get_active() ? m_xRestartNumberingNF->get_value() : 0;
323 const SwPageDesc* pNewDesc = nNumTitlePages > 1 ? mpNormalDesc : nullptr;
324 lcl_ChangePage(rWrtShell, nPgNo, pNewDesc);
327 rWrtShell.EndUndo();
328 lcl_PopCursor(rWrtShell);
329 if (!m_xUseExistingPagesRB->get_active())
330 lcl_GotoPage(rWrtShell, GetInsertPosition());
331 m_xDialog->response(RET_OK);
334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */