LibreOffice Module sw (master)  1
PageFormatPanel.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  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 #include <sal/config.h>
20 #include <sal/log.hxx>
21 #include <swtypes.hxx>
22 #include <svl/intitem.hxx>
23 #include <editeng/sizeitem.hxx>
24 #include <editeng/paperinf.hxx>
25 #include <svx/dlgutil.hxx>
26 #include <svx/rulritem.hxx>
27 #include <svx/svdtrans.hxx>
28 #include "PageFormatPanel.hxx"
29 #include "PageMarginUtils.hxx"
30 #include <sfx2/dispatch.hxx>
31 #include <sfx2/bindings.hxx>
32 #include <sfx2/module.hxx>
33 #include <sfx2/objsh.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #include <pageformatpanel.hrc>
36 #include <cmdid.h>
39 #include <vcl/settings.hxx>
40 #include <vcl/svapp.hxx>
41 
42 #include <com/sun/star/lang/IllegalArgumentException.hpp>
43 
44 namespace sw::sidebar{
45 
46 std::unique_ptr<PanelLayout> PageFormatPanel::Create(
47  weld::Widget* pParent,
48  SfxBindings* pBindings)
49 {
50  if( pParent == nullptr )
51  throw ::com::sun::star::lang::IllegalArgumentException("no parent window given to PageFormatPanel::Create", nullptr, 0);
52 
53  return std::make_unique<PageFormatPanel>(pParent, pBindings);
54 }
55 
57 {
58  auto nSelected = mxMarginSelectBox->get_active();
59  mxMarginSelectBox->clear();
60 
62  if (IsInch(meFUnit))
63  {
64  OUString sSuffix = weld::MetricSpinButton::MetricToString(FieldUnit::INCH);
65  for (size_t i = 0; i < SAL_N_ELEMENTS(RID_PAGEFORMATPANEL_MARGINS_INCH); ++i)
66  {
67  OUString sStr = rLocaleData.getNum(RID_PAGEFORMATPANEL_MARGINS_INCH[i].second, 2, true, false) + sSuffix;
68  mxMarginSelectBox->append_text(SwResId(RID_PAGEFORMATPANEL_MARGINS_INCH[i].first).replaceFirst("%1", sStr));
69  }
70  }
71  else
72  {
73  OUString sSuffix = weld::MetricSpinButton::MetricToString(FieldUnit::CM);
74  for (size_t i = 0; i < SAL_N_ELEMENTS(RID_PAGEFORMATPANEL_MARGINS_CM); ++i)
75  {
76  OUString sStr = rLocaleData.getNum(RID_PAGEFORMATPANEL_MARGINS_CM[i].second, 2, true, false) + " " + sSuffix;
77  mxMarginSelectBox->append_text(SwResId(RID_PAGEFORMATPANEL_MARGINS_CM[i].first).replaceFirst("%1", sStr));
78  }
79  }
80  mxMarginSelectBox->set_active(nSelected);
81 }
82 
84  PanelLayout(pParent, "PageFormatPanel", "modules/swriter/ui/pageformatpanel.ui"),
85  mpBindings( pBindings ),
86  mxPaperSizeBox(new SvxPaperSizeListBox(m_xBuilder->weld_combo_box("papersize"))),
87  mxPaperWidth(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("paperwidth", FieldUnit::CM))),
88  mxPaperHeight(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("paperheight", FieldUnit::CM))),
89  mxPaperOrientation(m_xBuilder->weld_combo_box("paperorientation")),
90  mxMarginSelectBox(m_xBuilder->weld_combo_box("marginLB")),
91  mxCustomEntry(m_xBuilder->weld_label("customlabel")),
92  maPaperSizeController(SID_ATTR_PAGE_SIZE, *pBindings, *this),
93  maPaperOrientationController(SID_ATTR_PAGE, *pBindings, *this),
94  maMetricController(SID_ATTR_METRIC, *pBindings,*this),
95  maSwPageLRControl(SID_ATTR_PAGE_LRSPACE, *pBindings, *this),
96  maSwPageULControl(SID_ATTR_PAGE_ULSPACE, *pBindings, *this),
97  mpPageItem( new SvxPageItem(SID_ATTR_PAGE) ),
98  mpPageLRMarginItem( new SvxLongLRSpaceItem( 0, 0, SID_ATTR_PAGE_LRSPACE ) ),
99  mpPageULMarginItem( new SvxLongULSpaceItem( 0, 0, SID_ATTR_PAGE_ULSPACE ) ),
100  meFUnit(GetModuleFieldUnit()),
101  meUnit(),
102  aCustomEntry()
103 {
104  Initialize();
105 }
106 
108 {
109  mxPaperSizeBox.reset();
110  mxPaperWidth.reset();
111  mxPaperHeight.reset();
112  mxPaperOrientation.reset();
113  mxMarginSelectBox.reset();
114  mxCustomEntry.reset();
115 
121  mpPageULMarginItem.reset();
122  mpPageLRMarginItem.reset();
123  mpPageItem.reset();
124 }
125 
127 {
128  mxPaperSizeBox->FillPaperSizeEntries( PaperSizeApp::Std );
131  mxPaperWidth->SetFieldUnit(meFUnit);
132  mxPaperHeight->SetFieldUnit(meFUnit);
134  aCustomEntry = mxCustomEntry->get_label();
135 
136  const SvtOptionsDrawinglayer aDrawinglayerOpt;
137  mxPaperWidth->set_max(mxPaperWidth->normalize(aDrawinglayerOpt.GetMaximumPaperWidth()), FieldUnit::CM);
138  mxPaperHeight->set_max(mxPaperHeight->normalize(aDrawinglayerOpt.GetMaximumPaperHeight()), FieldUnit::CM);
139 
140  mxPaperSizeBox->connect_changed( LINK(this, PageFormatPanel, PaperFormatModifyHdl ));
141  mxPaperOrientation->connect_changed( LINK(this, PageFormatPanel, PaperFormatModifyHdl ));
142  mxPaperHeight->connect_value_changed( LINK(this, PageFormatPanel, PaperSizeModifyHdl ));
143  mxPaperWidth->connect_value_changed( LINK(this, PageFormatPanel, PaperSizeModifyHdl ));
144  mxMarginSelectBox->connect_changed( LINK(this, PageFormatPanel, PaperModifyMarginHdl));
145 
146  mpBindings->Update(SID_ATTR_METRIC);
147  mpBindings->Update(SID_ATTR_PAGE);
148  mpBindings->Update(SID_ATTR_PAGE_SIZE);
149  mpBindings->Update(SID_ATTR_PAGE_LRSPACE);
150  mpBindings->Update(SID_ATTR_PAGE_ULSPACE);
151 
152  UpdateMarginBox();
153 }
154 
156  const sal_uInt16 nSId,
157  const SfxItemState eState,
158  const SfxPoolItem* pState)
159 {
160  switch(nSId)
161  {
162  case SID_ATTR_PAGE_SIZE:
163  {
164  const SvxSizeItem* pSizeItem = nullptr;
165  if (eState >= SfxItemState::DEFAULT)
166  pSizeItem = dynamic_cast< const SvxSizeItem* >(pState);
167  if (pSizeItem)
168  {
169  Size aPaperSize = pSizeItem->GetSize();
170 
171  mxPaperWidth->set_value(mxPaperWidth->normalize(aPaperSize.Width()), FieldUnit::TWIP);
172  mxPaperHeight->set_value(mxPaperHeight->normalize(aPaperSize.Height()), FieldUnit::TWIP);
173 
174  if(mxPaperOrientation->get_active() == 1)
175  Swap(aPaperSize);
176 
177  Paper ePaper = SvxPaperInfo::GetSvxPaper(aPaperSize, meUnit);
178  mxPaperSizeBox->set_active_id( ePaper );
179  }
180  }
181  break;
182  case SID_ATTR_METRIC:
183  {
185  FieldUnit eFUnit = GetCurrentUnit(eState, pState);
186  if (eFUnit != meFUnit)
187  {
188  meFUnit = eFUnit;
189  mxPaperHeight->SetFieldUnit(meFUnit);
190  mxPaperWidth->SetFieldUnit(meFUnit);
192  UpdateMarginBox();
193  }
194  }
195  break;
196  case SID_ATTR_PAGE:
197  {
198  if ( eState >= SfxItemState::DEFAULT &&
199  dynamic_cast< const SvxPageItem *>( pState ) )
200  {
201  mpPageItem.reset( static_cast<SvxPageItem*>(pState->Clone()) );
202  if ( mpPageItem->IsLandscape() )
203  mxPaperOrientation->set_active(1);
204  else
205  mxPaperOrientation->set_active(0);
206  }
207  }
208  break;
209  case SID_ATTR_PAGE_LRSPACE:
210  {
211  if ( eState >= SfxItemState::DEFAULT &&
212  dynamic_cast< const SvxLongLRSpaceItem *>( pState ) )
213  {
214  mpPageLRMarginItem.reset( static_cast<SvxLongLRSpaceItem*>(pState->Clone()) );
215  UpdateMarginBox();
216  }
217  }
218  break;
219  case SID_ATTR_PAGE_ULSPACE:
220  {
221  if ( eState >= SfxItemState::DEFAULT &&
222  dynamic_cast< const SvxLongULSpaceItem *>( pState ) )
223  {
224  mpPageULMarginItem.reset( static_cast<SvxLongULSpaceItem*>(pState->Clone()) );
225  UpdateMarginBox();
226  }
227  }
228  break;
229  default:
230  break;
231  }
232 }
233 
234 IMPL_LINK_NOARG(PageFormatPanel, PaperFormatModifyHdl, weld::ComboBox&, void)
235 {
236  Paper ePaper = mxPaperSizeBox->get_active_id();
237  Size aSize;
238 
239  if(ePaper!=PAPER_USER)
240  aSize = SvxPaperInfo::GetPaperSize(ePaper, meUnit);
241  else
242  aSize = Size(mxPaperWidth->GetCoreValue(meUnit), mxPaperHeight->GetCoreValue(meUnit));
243 
244  if (mxPaperOrientation->get_active() == 1 || ePaper==PAPER_USER)
245  Swap(aSize);
246 
247  mpPageItem->SetLandscape(mxPaperOrientation->get_active() == 1);
248  SvxSizeItem aSizeItem(SID_ATTR_PAGE_SIZE, aSize);
249  mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_SIZE, SfxCallMode::RECORD, { &aSizeItem, mpPageItem.get() });
250 }
251 
253 {
254  Size aSize(mxPaperWidth->GetCoreValue(meUnit), mxPaperHeight->GetCoreValue(meUnit));
255  SvxSizeItem aSizeItem(SID_ATTR_PAGE_SIZE, aSize);
256  mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_SIZE, SfxCallMode::RECORD, { &aSizeItem });
257 }
258 
259 IMPL_LINK_NOARG(PageFormatPanel, PaperModifyMarginHdl, weld::ComboBox&, void)
260 {
261  bool bMirrored = false;
262  bool bApplyNewPageMargins = true;
263  switch (mxMarginSelectBox->get_active())
264  {
265  case 0:
266  SetNone(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored);
267  break;
268  case 1:
269  SetNarrow(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored);
270  break;
271  case 2:
272  SetModerate(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored);
273  break;
274  case 3:
275  SetNormal075(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored);
276  break;
277  case 4:
278  SetNormal100(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored);
279  break;
280  case 5:
281  SetNormal125(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored);
282  break;
283  case 6:
284  SetWide(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored);
285  break;
286  case 7:
287  SetMirrored(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored);
288  break;
289  default:
290  bApplyNewPageMargins = false;
291  break;
292  }
293 
294  if(bApplyNewPageMargins)
295  {
296  ExecuteMarginLRChange( mnPageLeftMargin, mnPageRightMargin );
297  ExecuteMarginULChange( mnPageTopMargin, mnPageBottomMargin );
298  if(bMirrored != (mpPageItem->GetPageUsage() == SvxPageUsage::Mirror))
299  {
300  mpPageItem->SetPageUsage( bMirrored ? SvxPageUsage::Mirror : SvxPageUsage::All );
301  mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_PAGE,
302  SfxCallMode::RECORD, { mpPageItem.get() });
303  }
304  }
305 }
306 
308 {
309  FieldUnit eUnit = FieldUnit::NONE;
310 
311  if ( pState && eState >= SfxItemState::DEFAULT )
312  eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pState)->GetValue());
313  else
314  {
316  SfxObjectShell* pSh = nullptr;
317  if ( pFrame )
318  pSh = pFrame->GetObjectShell();
319  if ( pSh )
320  {
321  SfxModule* pModule = pSh->GetModule();
322  if ( pModule )
323  {
324  const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC );
325  if ( pItem )
326  eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
327  }
328  else
329  {
330  SAL_WARN("sw.ui", "GetModuleFieldUnit(): no module found");
331  }
332  }
333  }
334 
335  return eUnit;
336 }
337 
338 void PageFormatPanel::ExecuteMarginLRChange( const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin )
339 {
340  mpPageLRMarginItem->SetLeft( nPageLeftMargin );
341  mpPageLRMarginItem->SetRight( nPageRightMargin );
342  mpBindings->GetDispatcher()->ExecuteList( SID_ATTR_PAGE_LRSPACE, SfxCallMode::RECORD, { mpPageLRMarginItem.get() });
343 }
344 
345 void PageFormatPanel::ExecuteMarginULChange(const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin)
346 {
347  mpPageULMarginItem->SetUpper( nPageTopMargin );
348  mpPageULMarginItem->SetLower( nPageBottomMargin );
349  mpBindings->GetDispatcher()->ExecuteList( SID_ATTR_PAGE_ULSPACE, SfxCallMode::RECORD, { mpPageULMarginItem.get() });
350 }
351 
353 {
356  mnPageTopMargin = mpPageULMarginItem->GetUpper();
358 
359  int nCustomEntry = mxMarginSelectBox->find_text(aCustomEntry);
360 
361  bool bMirrored = (mpPageItem->GetPageUsage() == SvxPageUsage::Mirror);
363  {
364  mxMarginSelectBox->set_active(0);
365  if (nCustomEntry != -1)
366  mxMarginSelectBox->remove(nCustomEntry);
367  }
369  {
370  mxMarginSelectBox->set_active(1);
371  if (nCustomEntry != -1)
372  mxMarginSelectBox->remove(nCustomEntry);
373  }
375  {
376  mxMarginSelectBox->set_active(2);
377  if (nCustomEntry != -1)
378  mxMarginSelectBox->remove(nCustomEntry);
379  }
381  {
382  mxMarginSelectBox->set_active(3);
383  if (nCustomEntry != -1)
384  mxMarginSelectBox->remove(nCustomEntry);
385  }
387  {
388  mxMarginSelectBox->set_active(4);
389  if (nCustomEntry != -1)
390  mxMarginSelectBox->remove(nCustomEntry);
391  }
393  {
394  mxMarginSelectBox->set_active(5);
395  if (nCustomEntry != -1)
396  mxMarginSelectBox->remove(nCustomEntry);
397  }
399  {
400  mxMarginSelectBox->set_active(6);
401  if (nCustomEntry != -1)
402  mxMarginSelectBox->remove(nCustomEntry);
403  }
405  {
406  mxMarginSelectBox->set_active(7);
407  if (nCustomEntry != -1)
408  mxMarginSelectBox->remove(nCustomEntry);
409  }
410  else
411  {
412  if (nCustomEntry == -1)
413  mxMarginSelectBox->append_text(aCustomEntry);
414  mxMarginSelectBox->set_active_text(aCustomEntry);
415  }
416 }
417 
418 }
419 
420 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetMirrored(tools::Long &nPageLeftMargin, tools::Long &nPageRightMargin, tools::Long &nPageTopMargin, tools::Long &nPageBottomMargin, bool &bMirrored)
::sfx2::sidebar::ControllerItem maPaperOrientationController
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
FieldUnit
const LocaleDataWrapper & GetLocaleDataWrapper() const
std::unique_ptr< weld::ComboBox > mxMarginSelectBox
bool IsNormal125(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin, const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin, bool bMirrored)
Size & Swap(Size &rSize)
virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, const SfxPoolItem *pState) override
std::string GetValue
::sfx2::sidebar::ControllerItem maSwPageLRControl
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
void SetNormal075(tools::Long &nPageLeftMargin, tools::Long &nPageRightMargin, tools::Long &nPageTopMargin, tools::Long &nPageBottomMargin, bool &bMirrored)
long Long
bool IsNormal075(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin, const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin, bool bMirrored)
static const AllSettings & GetSettings()
MapUnit GetCoreMetric() const
virtual SfxObjectShell * GetObjectShell() override
PageFormatPanel(weld::Widget *pParent, SfxBindings *pBindings)
static OUString MetricToString(FieldUnit rUnit)
sal_uInt32 GetMaximumPaperWidth() const
FieldUnit GetModuleFieldUnit(const SfxItemSet &rSet)
constexpr tools::Long Width() const
SfxModule * GetModule() const
bool IsNarrow(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin, const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin, bool bMirrored)
::sfx2::sidebar::ControllerItem maSwPageULControl
OUString sSuffix
static FieldUnit GetCurrentUnit(SfxItemState eState, const SfxPoolItem *pState)
static std::unique_ptr< PanelLayout > Create(weld::Widget *pParent, SfxBindings *pBindings)
bool IsModerate(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin, const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin, bool bMirrored)
#define SAL_N_ELEMENTS(arr)
std::unique_ptr< SvxRelativeField > mxPaperWidth
void SetModerate(tools::Long &nPageLeftMargin, tools::Long &nPageRightMargin, tools::Long &nPageTopMargin, tools::Long &nPageBottomMargin, bool &bMirrored)
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
int i
bool IsWide(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin, const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin, bool bMirrored)
virtual void dispose()
std::unique_ptr< SvxRelativeField > mxPaperHeight
bool IsNormal100(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin, const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin, bool bMirrored)
void SetWide(tools::Long &nPageLeftMargin, tools::Long &nPageRightMargin, tools::Long &nPageTopMargin, tools::Long &nPageBottomMargin, bool &bMirrored)
void SetNormal125(tools::Long &nPageLeftMargin, tools::Long &nPageRightMargin, tools::Long &nPageTopMargin, tools::Long &nPageBottomMargin, bool &bMirrored)
std::unique_ptr< SvxPageItem > mpPageItem
Paper
std::unique_ptr< SvxLongLRSpaceItem > mpPageLRMarginItem
static Size GetPaperSize(Paper ePaper, MapUnit eUnit=MapUnit::MapTwip)
OUString SwResId(const char *pId)
Definition: swmodule.cxx:166
bool IsMirrored(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin, const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin, bool bMirrored)
IMPL_LINK_NOARG(PageColumnControl, MoreButtonClickHdl_Impl, weld::Button &, void)
void ExecuteMarginULChange(const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin)
::sfx2::sidebar::ControllerItem maMetricController
void ExecuteMarginLRChange(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin)
void SetNormal100(tools::Long &nPageLeftMargin, tools::Long &nPageRightMargin, tools::Long &nPageTopMargin, tools::Long &nPageBottomMargin, bool &bMirrored)
void Update(sal_uInt16 nId)
sal_uInt32 GetMaximumPaperHeight() const
PAPER_USER
static SfxViewFrame * Current()
void SetNone(tools::Long &nPageLeftMargin, tools::Long &nPageRightMargin, tools::Long &nPageTopMargin, tools::Long &nPageBottomMargin, bool &bMirrored)
SfxItemState
constexpr tools::Long Height() const
std::unique_ptr< SvxLongULSpaceItem > mpPageULMarginItem
std::unique_ptr< weld::ComboBox > mxPaperOrientation
virtual ~PageFormatPanel() override
std::unique_ptr< SvxPaperSizeListBox > mxPaperSizeBox
bool IsInch(MapUnit eU)
SfxDispatcher * GetDispatcher() const
void SetNarrow(tools::Long &nPageLeftMargin, tools::Long &nPageRightMargin, tools::Long &nPageTopMargin, tools::Long &nPageBottomMargin, bool &bMirrored)
bool IsNone(const tools::Long nPageLeftMargin, const tools::Long nPageRightMargin, const tools::Long nPageTopMargin, const tools::Long nPageBottomMargin, bool bMirrored)
#define SAL_WARN(area, stream)
OUString getNum(sal_Int64 nNumber, sal_uInt16 nDecimals, bool bUseThousandSep=true, bool bTrailingZeros=true) const
::sfx2::sidebar::ControllerItem maPaperSizeController
std::unique_ptr< weld::Label > mxCustomEntry
constexpr OUStringLiteral first
void SetFallbackCoreMetric(MapUnit eFallback)
const Size & GetSize() const
static Paper GetSvxPaper(const Size &rSize, MapUnit eUnit)