LibreOffice Module svx (master)  1
ParaLineSpacingControl.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 
21 
22 #include <editeng/editids.hrc>
23 #include <editeng/lspcitem.hxx>
24 #include <sfx2/dispatch.hxx>
25 #include <sfx2/module.hxx>
26 #include <sfx2/sfxsids.hrc>
27 #include <sfx2/viewfrm.hxx>
28 #include <svtools/unitconv.hxx>
29 
30 #include <svl/intitem.hxx>
31 #include <svl/itempool.hxx>
32 
34 
35 #define DEFAULT_LINE_SPACING 200
36 #define FIX_DIST_DEF 283
37 #define LINESPACE_1 100
38 #define LINESPACE_15 150
39 #define LINESPACE_2 200
40 #define LINESPACE_115 115
41 
42 // values of the mxLineDist listbox
43 #define LLINESPACE_1 0
44 #define LLINESPACE_115 1
45 #define LLINESPACE_15 2
46 #define LLINESPACE_2 3
47 #define LLINESPACE_PROP 4
48 #define LLINESPACE_MIN 5
49 #define LLINESPACE_DURCH 6
50 #define LLINESPACE_FIX 7
51 
52 #define MIN_FIXED_DISTANCE 28
53 
54 using namespace svx;
55 
57  : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/paralinespacingcontrol.ui", "ParaLineSpacingControl")
58  , mxControl(pControl)
59  , meLNSpaceUnit(MapUnit::Map100thMM)
60  , mxSpacing1Button(m_xBuilder->weld_button("spacing_1"))
61  , mxSpacing115Button(m_xBuilder->weld_button("spacing_115"))
62  , mxSpacing15Button(m_xBuilder->weld_button("spacing_15"))
63  , mxSpacing2Button(m_xBuilder->weld_button("spacing_2"))
64  , mxLineDist(m_xBuilder->weld_combo_box("line_dist"))
65  , mxLineDistLabel(m_xBuilder->weld_label("value_label"))
66  , mxLineDistAtPercentBox(m_xBuilder->weld_metric_spin_button("percent_box", FieldUnit::PERCENT))
67  , mxLineDistAtMetricBox(m_xBuilder->weld_metric_spin_button("metric_box", FieldUnit::CM))
68  , mpActLineDistFld(mxLineDistAtPercentBox.get())
69 {
70  Link<weld::Button&,void> aLink = LINK(this, ParaLineSpacingControl, PredefinedValuesHandler);
71  mxSpacing1Button->connect_clicked(aLink);
72  mxSpacing115Button->connect_clicked(aLink);
73  mxSpacing15Button->connect_clicked(aLink);
74  mxSpacing2Button->connect_clicked(aLink);
75 
76  Link<weld::ComboBox&,void> aLink3 = LINK( this, ParaLineSpacingControl, LineSPDistHdl_Impl );
77  mxLineDist->connect_changed(aLink3);
79 
80  Link<weld::MetricSpinButton&,void> aLink2 = LINK( this, ParaLineSpacingControl, LineSPDistAtHdl_Impl );
81  mxLineDistAtPercentBox->connect_value_changed( aLink2 );
82  mxLineDistAtMetricBox->connect_value_changed( aLink2 );
83 
84  FieldUnit eUnit = FieldUnit::INCH;
85  const SfxPoolItem* pItem = nullptr;
86  SfxViewFrame* pCurrent = SfxViewFrame::Current();
87  if (pCurrent && pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_METRIC, pItem) >= SfxItemState::DEFAULT)
88  eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
89  else
91 
93 
94  Initialize();
95 }
96 
98 {
99  switch (mxLineDist->get_active())
100  {
101  case LLINESPACE_1:
102  mxSpacing1Button->grab_focus();
103  break;
104  case LLINESPACE_115:
105  mxSpacing115Button->grab_focus();
106  break;
107  case LLINESPACE_15:
108  mxSpacing15Button->grab_focus();
109  break;
110  case LLINESPACE_2:
111  mxSpacing2Button->grab_focus();
112  break;
113  default:
114  mxLineDist->grab_focus();
115  break;
116  }
117 }
118 
120 {
121 }
122 
124 {
125  const SfxPoolItem* pItem(nullptr);
126  SfxViewFrame* pCurrent = SfxViewFrame::Current();
127  SfxItemState eState = pCurrent ? pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PARA_LINESPACE, pItem) : SfxItemState::UNKNOWN;
128 
129  const SvxLineSpacingItem* currSPItem = static_cast<const SvxLineSpacingItem*>(pItem);
130 
131  mxLineDist->set_sensitive(true);
132 
133  if( eState >= SfxItemState::DEFAULT )
134  {
135  MapUnit eUnit = pCurrent->GetPool().GetMetric(currSPItem->Which());
136  meLNSpaceUnit = eUnit;
137 
138  switch( currSPItem->GetLineSpaceRule() )
139  {
140  case SvxLineSpaceRule::Auto:
141  {
142  SvxInterLineSpaceRule eInter = currSPItem->GetInterLineSpaceRule();
143 
144  switch( eInter )
145  {
146  case SvxInterLineSpaceRule::Off:
148  break;
149 
150  case SvxInterLineSpaceRule::Prop:
151  {
152  if ( LINESPACE_1 == currSPItem->GetPropLineSpace() )
153  {
155  }
156  else if ( LINESPACE_115 == currSPItem->GetPropLineSpace() )
157  {
159  }
160  else if ( LINESPACE_15 == currSPItem->GetPropLineSpace() )
161  {
163  }
164  else if ( LINESPACE_2 == currSPItem->GetPropLineSpace() )
165  {
167  }
168  else
169  {
171  mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(currSPItem->GetPropLineSpace()), FieldUnit::PERCENT);
172  }
173  }
174  break;
175 
176  case SvxInterLineSpaceRule::Fix:
177  {
180  }
181  break;
182  default:
183  break;
184  }
185  }
186  break;
187  case SvxLineSpaceRule::Fix:
188  {
190  SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit);
191  }
192  break;
193 
194  case SvxLineSpaceRule::Min:
195  {
197  SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit);
198  }
199  break;
200  default:
201  break;
202  }
203  }
204  else if( eState == SfxItemState::DISABLED )
205  {
206  mxLineDist->set_sensitive(false);
207  mxLineDistLabel->set_sensitive(false);
210 
211  }
212  else
213  {
214  mxLineDistLabel->set_sensitive(false);
217  mxLineDist->set_active(-1);
218  }
219 
220  mxLineDist->save_value();
221 }
222 
224 {
225  switch (mxLineDist->get_active())
226  {
227  case LLINESPACE_1:
228  case LLINESPACE_115:
229  case LLINESPACE_15:
230  case LLINESPACE_2:
232  mxLineDistAtMetricBox->hide();
233  else
234  mxLineDistAtPercentBox->hide();
235 
236  mxLineDistLabel->set_sensitive(false);
240  break;
241 
242  case LLINESPACE_DURCH:
243  mxLineDistAtPercentBox->hide();
244 
246  mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
247 
248  if (mxLineDistAtMetricBox->get_text().isEmpty())
249  mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::NONE);
250 
251  mxLineDistLabel->set_sensitive(true);
254  break;
255 
256  case LLINESPACE_MIN:
257  mxLineDistAtPercentBox->hide();
258 
260  mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
261 
262  if (mxLineDistAtMetricBox->get_text().isEmpty())
263  mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::TWIP);
264 
265  mxLineDistLabel->set_sensitive(true);
268  break;
269 
270  case LLINESPACE_PROP:
271  mxLineDistAtMetricBox->hide();
272 
274 
275  if (mxLineDistAtPercentBox->get_text().isEmpty())
276  mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(100), FieldUnit::TWIP);
277 
278  mxLineDistLabel->set_sensitive(true);
281  break;
282 
283  case LLINESPACE_FIX:
284  mxLineDistAtPercentBox->hide();
285 
287  sal_Int64 nTemp = mxLineDistAtMetricBox->get_value(FieldUnit::NONE);
288  mxLineDistAtMetricBox->set_min(mxLineDistAtMetricBox->normalize(MIN_FIXED_DISTANCE), FieldUnit::TWIP);
289 
290  if (mxLineDistAtMetricBox->get_value(FieldUnit::NONE) != nTemp)
292 
293  mxLineDistLabel->set_sensitive(true);
296  break;
297  }
298 }
299 
301 {
302  mxLineDist->set_active(nPos);
304 }
305 
307 {
308  UpdateMetricFields();
309  ExecuteLineSpace();
310 }
311 
313 {
314  ExecuteLineSpace();
315 }
316 
318 {
319  mxLineDist->save_value();
320 
321  SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE);
322  const sal_Int32 nPos = mxLineDist->get_active();
323 
324  switch ( nPos )
325  {
326  case LLINESPACE_1:
327  case LLINESPACE_115:
328  case LLINESPACE_15:
329  case LLINESPACE_2:
330  SetLineSpace(aSpacing, nPos);
331  break;
332 
333  case LLINESPACE_PROP:
334  SetLineSpace(aSpacing, nPos, mxLineDistAtPercentBox->denormalize(static_cast<tools::Long>(mxLineDistAtPercentBox->get_value(FieldUnit::PERCENT))));
335  break;
336 
337  case LLINESPACE_MIN:
338  case LLINESPACE_DURCH:
339  case LLINESPACE_FIX:
341  break;
342 
343  default:
344  break;
345  }
346 
348  SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing });
349 }
350 
351 void ParaLineSpacingControl::SetLineSpace(SvxLineSpacingItem& rLineSpace, sal_Int32 eSpace, tools::Long lValue)
352 {
353  switch ( eSpace )
354  {
355  case LLINESPACE_1:
356  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
357  rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
358  break;
359 
360  case LLINESPACE_115:
361  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
362  rLineSpace.SetPropLineSpace( LINESPACE_115 );
363  break;
364 
365  case LLINESPACE_15:
366  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
367  rLineSpace.SetPropLineSpace( LINESPACE_15 );
368  break;
369 
370  case LLINESPACE_2:
371  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
372  rLineSpace.SetPropLineSpace( LINESPACE_2 );
373  break;
374 
375  case LLINESPACE_PROP:
376  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
377  rLineSpace.SetPropLineSpace( static_cast<sal_uInt16>(lValue) );
378  break;
379 
380  case LLINESPACE_MIN:
381  rLineSpace.SetLineHeight( static_cast<sal_uInt16>(lValue) );
382  rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
383  break;
384 
385  case LLINESPACE_DURCH:
386  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
387  rLineSpace.SetInterLineSpace( static_cast<sal_uInt16>(lValue) );
388  break;
389 
390  case LLINESPACE_FIX:
391  rLineSpace.SetLineHeight(static_cast<sal_uInt16>(lValue));
392  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Fix );
393  rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
394  break;
395  }
396 }
397 
398 IMPL_LINK(ParaLineSpacingControl, PredefinedValuesHandler, weld::Button&, rControl, void)
399 {
400  if (&rControl == mxSpacing1Button.get())
401  {
402  ExecuteLineSpacing(LLINESPACE_1);
403  }
404  else if (&rControl == mxSpacing115Button.get())
405  {
406  ExecuteLineSpacing(LLINESPACE_115);
407  }
408  else if (&rControl == mxSpacing15Button.get())
409  {
410  ExecuteLineSpacing(LLINESPACE_15);
411  }
412  else if (&rControl == mxSpacing2Button.get())
413  {
414  ExecuteLineSpacing(LLINESPACE_2);
415  }
416 }
417 
419 {
420  SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE);
421 
422  SetLineSpace(aSpacing, nEntry);
423 
425  SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing });
426 
427  // close when the user used the buttons
428  mxControl->EndPopupMode();
429 }
430 
431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
#define FIX_DIST_DEF
std::unique_ptr< weld::MetricSpinButton > mxLineDistAtMetricBox
void SetFieldUnit(weld::MetricSpinButton &rField, FieldUnit eUnit, bool bAll)
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 * >())
ParaLineSpacingControl(SvxLineSpacingToolBoxControl *pControl, weld::Widget *pParent)
FieldUnit
void ExecuteLineSpacing(sal_Int32 aEntry)
For the buttons - set the values, and close the popup.
#define LLINESPACE_1
sal_uInt16 GetPropLineSpace() const
void SetInterLineSpace(const short nSpace)
std::unique_ptr< weld::Button > mxSpacing115Button
long Long
#define LLINESPACE_15
constexpr OUStringLiteral PERCENT(u"Percent")
static FieldUnit GetCurrentFieldUnit()
void SetLineSpaceRule(SvxLineSpaceRule e)
#define LINESPACE_15
SvxInterLineSpaceRule
SvxLineSpaceRule GetLineSpaceRule() const
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
sal_uInt16 GetLineHeight() const
void SetPropLineSpace(const sal_uInt16 nProp)
std::unique_ptr< weld::MetricSpinButton > mxLineDistAtPercentBox
#define LINESPACE_115
static void SetLineSpace(SvxLineSpacingItem &rLineSpace, sal_Int32 eSpace, tools::Long lValue=0)
Set one particular value.
void ExecuteLineSpace()
Take the values from the widgets, and update the paragraph accordingly.
SfxItemPool & GetPool() const
IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet *, void)
void set_text(const OUString &rText)
#define MIN_FIXED_DISTANCE
#define DEFAULT_LINE_SPACING
#define LINESPACE_2
#define LLINESPACE_DURCH
#define LINESPACE_1
std::unique_ptr< weld::Button > mxSpacing2Button
SfxBindings & GetBindings()
void UpdateMetricFields()
Set mpActlineDistFld and visibility of mpLineDist* fields according to what is just selected...
#define LLINESPACE_FIX
int GetCoreValue(const weld::MetricSpinButton &rField, MapUnit eUnit)
void Initialize()
Setup the widgets with values from the document.
#define LLINESPACE_MIN
SvxInterLineSpaceRule GetInterLineSpaceRule() const
IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::ToggleButton &, rBox, void)
SfxItemState QueryState(sal_uInt16 nSID, const SfxPoolItem *&rpState)
#define LLINESPACE_2
std::unique_ptr< weld::Button > mxSpacing1Button
void SetMetricValue(weld::MetricSpinButton &rField, int nCoreValue, MapUnit eUnit)
short GetInterLineSpace() const
rtl::Reference< SvxLineSpacingToolBoxControl > mxControl
void SetInterLineSpaceRule(SvxInterLineSpaceRule e)
static SfxViewFrame * Current()
SfxItemState
std::unique_ptr< weld::Button > mxSpacing15Button
void SetLineHeight(const sal_uInt16 nHeight)
std::unique_ptr< weld::ComboBox > mxLineDist
void set_sensitive(bool sensitive)
virtual void GrabFocus() override
SfxDispatcher * GetDispatcher() const
MapUnit
weld::MetricSpinButton * mpActLineDistFld
#define LLINESPACE_PROP
void SelectEntryPos(sal_Int32 nPos)
Set the entry and update the metric fields.
std::unique_ptr< weld::Label > mxLineDistLabel
#define LLINESPACE_115
sal_uInt16 nPos