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 
33 #include <ParaLineSpacingPopup.hxx>
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  const bool bItemStateSet(nullptr != pCurrent);
128  const SfxItemState eState(bItemStateSet
129  ? pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PARA_LINESPACE, pItem)
130  : SfxItemState::DEFAULT);
131 
132  mxLineDist->set_sensitive(true);
133 
134  if( bItemStateSet && (eState == SfxItemState::DEFAULT || eState == SfxItemState::SET) )
135  {
136  const SvxLineSpacingItem* currSPItem = static_cast<const SvxLineSpacingItem*>(pItem);
137  MapUnit eUnit = pCurrent->GetPool().GetMetric(currSPItem->Which());
138  meLNSpaceUnit = eUnit;
139 
140  switch( currSPItem->GetLineSpaceRule() )
141  {
142  case SvxLineSpaceRule::Auto:
143  {
144  SvxInterLineSpaceRule eInter = currSPItem->GetInterLineSpaceRule();
145 
146  switch( eInter )
147  {
148  case SvxInterLineSpaceRule::Off:
150  break;
151 
152  case SvxInterLineSpaceRule::Prop:
153  {
154  if ( LINESPACE_1 == currSPItem->GetPropLineSpace() )
155  {
157  }
158  else if ( LINESPACE_115 == currSPItem->GetPropLineSpace() )
159  {
161  }
162  else if ( LINESPACE_15 == currSPItem->GetPropLineSpace() )
163  {
165  }
166  else if ( LINESPACE_2 == currSPItem->GetPropLineSpace() )
167  {
169  }
170  else
171  {
173  mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(currSPItem->GetPropLineSpace()), FieldUnit::PERCENT);
174  }
175  }
176  break;
177 
178  case SvxInterLineSpaceRule::Fix:
179  {
182  }
183  break;
184  default:
185  break;
186  }
187  }
188  break;
189  case SvxLineSpaceRule::Fix:
190  {
192  SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit);
193  }
194  break;
195 
196  case SvxLineSpaceRule::Min:
197  {
199  SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit);
200  }
201  break;
202  default:
203  break;
204  }
205  }
206  else if( bItemStateSet && eState == SfxItemState::DISABLED )
207  {
208  mxLineDist->set_sensitive(false);
209  mxLineDistLabel->set_sensitive(false);
212 
213  }
214  else // !bItemStateSet || eState == SfxItemState::DONTCARE || eState == SfxItemState::UNKNOWN
215  {
216  mxLineDistLabel->set_sensitive(false);
219  mxLineDist->set_active(-1);
220  }
221 
222  mxLineDist->save_value();
223 }
224 
226 {
227  switch (mxLineDist->get_active())
228  {
229  case LLINESPACE_1:
230  case LLINESPACE_115:
231  case LLINESPACE_15:
232  case LLINESPACE_2:
234  mxLineDistAtMetricBox->hide();
235  else
236  mxLineDistAtPercentBox->hide();
237 
238  mxLineDistLabel->set_sensitive(false);
242  break;
243 
244  case LLINESPACE_DURCH:
245  mxLineDistAtPercentBox->hide();
246 
248  mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
249 
250  if (mxLineDistAtMetricBox->get_text().isEmpty())
251  mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::NONE);
252 
253  mxLineDistLabel->set_sensitive(true);
256  break;
257 
258  case LLINESPACE_MIN:
259  mxLineDistAtPercentBox->hide();
260 
262  mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
263 
264  if (mxLineDistAtMetricBox->get_text().isEmpty())
265  mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::TWIP);
266 
267  mxLineDistLabel->set_sensitive(true);
270  break;
271 
272  case LLINESPACE_PROP:
273  mxLineDistAtMetricBox->hide();
274 
276 
277  if (mxLineDistAtPercentBox->get_text().isEmpty())
278  mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(100), FieldUnit::TWIP);
279 
280  mxLineDistLabel->set_sensitive(true);
283  break;
284 
285  case LLINESPACE_FIX:
286  mxLineDistAtPercentBox->hide();
287 
289  sal_Int64 nTemp = mxLineDistAtMetricBox->get_value(FieldUnit::NONE);
290  mxLineDistAtMetricBox->set_min(mxLineDistAtMetricBox->normalize(MIN_FIXED_DISTANCE), FieldUnit::TWIP);
291 
292  if (mxLineDistAtMetricBox->get_value(FieldUnit::NONE) != nTemp)
294 
295  mxLineDistLabel->set_sensitive(true);
298  break;
299  }
300 }
301 
303 {
304  mxLineDist->set_active(nPos);
306 }
307 
309 {
310  UpdateMetricFields();
311  ExecuteLineSpace();
312 }
313 
315 {
316  ExecuteLineSpace();
317 }
318 
320 {
321  mxLineDist->save_value();
322 
323  SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE);
324  const sal_Int32 nPos = mxLineDist->get_active();
325 
326  switch ( nPos )
327  {
328  case LLINESPACE_1:
329  case LLINESPACE_115:
330  case LLINESPACE_15:
331  case LLINESPACE_2:
332  SetLineSpace(aSpacing, nPos);
333  break;
334 
335  case LLINESPACE_PROP:
336  SetLineSpace(aSpacing, nPos, mxLineDistAtPercentBox->denormalize(static_cast<tools::Long>(mxLineDistAtPercentBox->get_value(FieldUnit::PERCENT))));
337  break;
338 
339  case LLINESPACE_MIN:
340  case LLINESPACE_DURCH:
341  case LLINESPACE_FIX:
343  break;
344 
345  default:
346  break;
347  }
348 
350  SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing });
351 }
352 
353 void ParaLineSpacingControl::SetLineSpace(SvxLineSpacingItem& rLineSpace, sal_Int32 eSpace, tools::Long lValue)
354 {
355  switch ( eSpace )
356  {
357  case LLINESPACE_1:
358  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
359  rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
360  break;
361 
362  case LLINESPACE_115:
363  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
364  rLineSpace.SetPropLineSpace( LINESPACE_115 );
365  break;
366 
367  case LLINESPACE_15:
368  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
369  rLineSpace.SetPropLineSpace( LINESPACE_15 );
370  break;
371 
372  case LLINESPACE_2:
373  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
374  rLineSpace.SetPropLineSpace( LINESPACE_2 );
375  break;
376 
377  case LLINESPACE_PROP:
378  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
379  rLineSpace.SetPropLineSpace( static_cast<sal_uInt16>(lValue) );
380  break;
381 
382  case LLINESPACE_MIN:
383  rLineSpace.SetLineHeight( static_cast<sal_uInt16>(lValue) );
384  rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
385  break;
386 
387  case LLINESPACE_DURCH:
388  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
389  rLineSpace.SetInterLineSpace( static_cast<sal_uInt16>(lValue) );
390  break;
391 
392  case LLINESPACE_FIX:
393  rLineSpace.SetLineHeight(static_cast<sal_uInt16>(lValue));
394  rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Fix );
395  rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
396  break;
397  }
398 }
399 
400 IMPL_LINK(ParaLineSpacingControl, PredefinedValuesHandler, weld::Button&, rControl, void)
401 {
402  if (&rControl == mxSpacing1Button.get())
403  {
404  ExecuteLineSpacing(LLINESPACE_1);
405  }
406  else if (&rControl == mxSpacing115Button.get())
407  {
408  ExecuteLineSpacing(LLINESPACE_115);
409  }
410  else if (&rControl == mxSpacing15Button.get())
411  {
412  ExecuteLineSpacing(LLINESPACE_15);
413  }
414  else if (&rControl == mxSpacing2Button.get())
415  {
416  ExecuteLineSpacing(LLINESPACE_2);
417  }
418 }
419 
421 {
422  SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE);
423 
424  SetLineSpace(aSpacing, nEntry);
425 
427  SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing });
428 
429  // close when the user used the buttons
430  mxControl->EndPopupMode();
431 }
432 
433 /* 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
IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::Toggleable &, rBox, void)
#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
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