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
36
37#define DEFAULT_LINE_SPACING 200
38#define FIX_DIST_DEF 283
39#define LINESPACE_1 100
40#define LINESPACE_15 150
41#define LINESPACE_2 200
42#define LINESPACE_115 115
43
44// values of the mxLineDist listbox
45#define LLINESPACE_1 0
46#define LLINESPACE_115 1
47#define LLINESPACE_15 2
48#define LLINESPACE_2 3
49#define LLINESPACE_PROP 4
50#define LLINESPACE_MIN 5
51#define LLINESPACE_DURCH 6
52#define LLINESPACE_FIX 7
53
54#define MIN_FIXED_DISTANCE 28
55
56using namespace svx;
57
58ParaLineSpacingControl::ParaLineSpacingControl(SvxLineSpacingToolBoxControl* pControl, weld::Widget* pParent)
59 : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/paralinespacingcontrol.ui", "ParaLineSpacingControl")
60 , mxControl(pControl)
61 , meLNSpaceUnit(MapUnit::Map100thMM)
62 , mxSpacing1Button(m_xBuilder->weld_button("spacing_1"))
63 , mxSpacing115Button(m_xBuilder->weld_button("spacing_115"))
64 , mxSpacing15Button(m_xBuilder->weld_button("spacing_15"))
65 , mxSpacing2Button(m_xBuilder->weld_button("spacing_2"))
66 , mxLineDist(m_xBuilder->weld_combo_box("line_dist"))
67 , mxLineDistLabel(m_xBuilder->weld_label("value_label"))
68 , mxLineDistAtPercentBox(m_xBuilder->weld_metric_spin_button("percent_box", FieldUnit::PERCENT))
69 , mxLineDistAtMetricBox(m_xBuilder->weld_metric_spin_button("metric_box", FieldUnit::CM))
70 , mpActLineDistFld(mxLineDistAtPercentBox.get())
71{
72 Link<weld::Button&,void> aLink = LINK(this, ParaLineSpacingControl, PredefinedValuesHandler);
73 mxSpacing1Button->connect_clicked(aLink);
74 mxSpacing115Button->connect_clicked(aLink);
75 mxSpacing15Button->connect_clicked(aLink);
76 mxSpacing2Button->connect_clicked(aLink);
77
78 Link<weld::ComboBox&,void> aLink3 = LINK( this, ParaLineSpacingControl, LineSPDistHdl_Impl );
79 mxLineDist->connect_changed(aLink3);
81
82 Link<weld::MetricSpinButton&,void> aLink2 = LINK( this, ParaLineSpacingControl, LineSPDistAtHdl_Impl );
83 mxLineDistAtPercentBox->connect_value_changed( aLink2 );
84 mxLineDistAtMetricBox->connect_value_changed( aLink2 );
85
86 FieldUnit eUnit = FieldUnit::INCH;
87 const SfxUInt16Item* pItem = nullptr;
89 if (pCurrent && pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_METRIC, pItem) >= SfxItemState::DEFAULT)
90 eUnit = static_cast<FieldUnit>(pItem->GetValue());
91 else
93
95
96 Initialize();
97}
98
100{
101 switch (mxLineDist->get_active())
102 {
103 case LLINESPACE_1:
104 mxSpacing1Button->grab_focus();
105 break;
106 case LLINESPACE_115:
107 mxSpacing115Button->grab_focus();
108 break;
109 case LLINESPACE_15:
110 mxSpacing15Button->grab_focus();
111 break;
112 case LLINESPACE_2:
113 mxSpacing2Button->grab_focus();
114 break;
115 default:
116 mxLineDist->grab_focus();
117 break;
118 }
119}
120
122{
123}
124
126{
127 const SvxLineSpacingItem* pItem(nullptr);
129 const bool bItemStateSet(nullptr != pCurrent);
130 const SfxItemState eState(bItemStateSet
131 ? pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PARA_LINESPACE, pItem)
132 : SfxItemState::DEFAULT);
133
134 mxLineDist->set_sensitive(true);
135
136 if( bItemStateSet && (eState == SfxItemState::DEFAULT || eState == SfxItemState::SET) )
137 {
138 const SvxLineSpacingItem* currSPItem = pItem;
139 // It seems draw/impress and writer require different MapUnit values for fixed line spacing
140 // metric values to be correctly calculated.
141 MapUnit eUnit = MapUnit::Map100thMM; // works for draw/impress
143 == "com.sun.star.text.TextDocument")
144 eUnit = MapUnit::MapTwip; // works for writer
145 meLNSpaceUnit = eUnit;
146
147 switch( currSPItem->GetLineSpaceRule() )
148 {
149 case SvxLineSpaceRule::Auto:
150 {
151 SvxInterLineSpaceRule eInter = currSPItem->GetInterLineSpaceRule();
152
153 switch( eInter )
154 {
155 case SvxInterLineSpaceRule::Off:
157 break;
158
159 case SvxInterLineSpaceRule::Prop:
160 {
161 if ( LINESPACE_1 == currSPItem->GetPropLineSpace() )
162 {
164 }
165 else if ( LINESPACE_115 == currSPItem->GetPropLineSpace() )
166 {
168 }
169 else if ( LINESPACE_15 == currSPItem->GetPropLineSpace() )
170 {
172 }
173 else if ( LINESPACE_2 == currSPItem->GetPropLineSpace() )
174 {
176 }
177 else
178 {
180 mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(currSPItem->GetPropLineSpace()), FieldUnit::PERCENT);
181 }
182 }
183 break;
184
185 case SvxInterLineSpaceRule::Fix:
186 {
189 }
190 break;
191 default:
192 break;
193 }
194 }
195 break;
196 case SvxLineSpaceRule::Fix:
197 {
199 SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit);
200 }
201 break;
202
203 case SvxLineSpaceRule::Min:
204 {
206 SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit);
207 }
208 break;
209 default:
210 break;
211 }
212 }
213 else if( bItemStateSet && eState == SfxItemState::DISABLED )
214 {
215 mxLineDist->set_sensitive(false);
216 mxLineDistLabel->set_sensitive(false);
219
220 }
221 else // !bItemStateSet || eState == SfxItemState::DONTCARE || eState == SfxItemState::UNKNOWN
222 {
223 mxLineDistLabel->set_sensitive(false);
226 mxLineDist->set_active(-1);
227 }
228
229 mxLineDist->save_value();
230}
231
233{
234 switch (mxLineDist->get_active())
235 {
236 case LLINESPACE_1:
237 case LLINESPACE_115:
238 case LLINESPACE_15:
239 case LLINESPACE_2:
241 mxLineDistAtMetricBox->hide();
242 else
244
245 mxLineDistLabel->set_sensitive(false);
249 break;
250
251 case LLINESPACE_DURCH:
253
255 mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
256
257 if (mxLineDistAtMetricBox->get_text().isEmpty())
258 mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::NONE);
259
260 mxLineDistLabel->set_sensitive(true);
263 break;
264
265 case LLINESPACE_MIN:
267
269 mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
270
271 if (mxLineDistAtMetricBox->get_text().isEmpty())
272 mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::TWIP);
273
274 mxLineDistLabel->set_sensitive(true);
277 break;
278
279 case LLINESPACE_PROP:
280 mxLineDistAtMetricBox->hide();
281
283
284 if (mxLineDistAtPercentBox->get_text().isEmpty())
285 mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(100), FieldUnit::TWIP);
286
287 mxLineDistLabel->set_sensitive(true);
290 break;
291
292 case LLINESPACE_FIX:
294
296 sal_Int64 nTemp = mxLineDistAtMetricBox->get_value(FieldUnit::NONE);
297 mxLineDistAtMetricBox->set_min(mxLineDistAtMetricBox->normalize(MIN_FIXED_DISTANCE), FieldUnit::TWIP);
298
299 if (mxLineDistAtMetricBox->get_value(FieldUnit::NONE) != nTemp)
301
302 mxLineDistLabel->set_sensitive(true);
305 break;
306 }
307}
308
310{
311 mxLineDist->set_active(nPos);
313}
314
316{
317 UpdateMetricFields();
318 ExecuteLineSpace();
319}
320
322{
323 ExecuteLineSpace();
324}
325
327{
328 mxLineDist->save_value();
329
330 SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE);
331 const sal_Int32 nPos = mxLineDist->get_active();
332
333 switch ( nPos )
334 {
335 case LLINESPACE_1:
336 case LLINESPACE_115:
337 case LLINESPACE_15:
338 case LLINESPACE_2:
339 SetLineSpace(aSpacing, nPos);
340 break;
341
342 case LLINESPACE_PROP:
343 SetLineSpace(aSpacing, nPos, mxLineDistAtPercentBox->denormalize(static_cast<tools::Long>(mxLineDistAtPercentBox->get_value(FieldUnit::PERCENT))));
344 break;
345
346 case LLINESPACE_MIN:
347 case LLINESPACE_DURCH:
348 case LLINESPACE_FIX:
350 break;
351
352 default:
353 break;
354 }
355
356 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
357 {
358 pViewFrm->GetBindings().GetDispatcher()->ExecuteList(
359 SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing });
360 }
361}
362
363void ParaLineSpacingControl::SetLineSpace(SvxLineSpacingItem& rLineSpace, sal_Int32 eSpace, tools::Long lValue)
364{
365 switch ( eSpace )
366 {
367 case LLINESPACE_1:
368 rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
369 rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
370 break;
371
372 case LLINESPACE_115:
373 rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
374 rLineSpace.SetPropLineSpace( LINESPACE_115 );
375 break;
376
377 case LLINESPACE_15:
378 rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
379 rLineSpace.SetPropLineSpace( LINESPACE_15 );
380 break;
381
382 case LLINESPACE_2:
383 rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
384 rLineSpace.SetPropLineSpace( LINESPACE_2 );
385 break;
386
387 case LLINESPACE_PROP:
388 rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
389 rLineSpace.SetPropLineSpace( static_cast<sal_uInt16>(lValue) );
390 break;
391
392 case LLINESPACE_MIN:
393 rLineSpace.SetLineHeight( static_cast<sal_uInt16>(lValue) );
394 rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
395 break;
396
397 case LLINESPACE_DURCH:
398 rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
399 rLineSpace.SetInterLineSpace( static_cast<sal_uInt16>(lValue) );
400 break;
401
402 case LLINESPACE_FIX:
403 rLineSpace.SetLineHeight(static_cast<sal_uInt16>(lValue));
404 rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Fix );
405 rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
406 break;
407 }
408}
409
410IMPL_LINK(ParaLineSpacingControl, PredefinedValuesHandler, weld::Button&, rControl, void)
411{
412 if (&rControl == mxSpacing1Button.get())
413 {
414 ExecuteLineSpacing(LLINESPACE_1);
415 }
416 else if (&rControl == mxSpacing115Button.get())
417 {
418 ExecuteLineSpacing(LLINESPACE_115);
419 }
420 else if (&rControl == mxSpacing15Button.get())
421 {
422 ExecuteLineSpacing(LLINESPACE_15);
423 }
424 else if (&rControl == mxSpacing2Button.get())
425 {
426 ExecuteLineSpacing(LLINESPACE_2);
427 }
428}
429
431{
432 SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE);
433
434 SetLineSpace(aSpacing, nEntry);
435
436 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
437 {
438 pViewFrm->GetBindings().GetDispatcher()->ExecuteList(
439 SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing });
440 }
441
442 // close when the user used the buttons
443 mxControl->EndPopupMode();
444}
445
446/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define LLINESPACE_PROP
#define LINESPACE_15
#define LLINESPACE_15
#define FIX_DIST_DEF
#define MIN_FIXED_DISTANCE
#define LLINESPACE_DURCH
#define LLINESPACE_1
#define LINESPACE_115
#define LINESPACE_1
#define LLINESPACE_115
#define LINESPACE_2
#define LLINESPACE_2
#define LLINESPACE_MIN
#define LLINESPACE_FIX
#define DEFAULT_LINE_SPACING
sal_uInt16 GetValue() const
SfxDispatcher * GetDispatcher() const
SfxItemState QueryState(sal_uInt16 nSID, const SfxPoolItem *&rpState)
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
static FieldUnit GetCurrentFieldUnit()
static SAL_WARN_UNUSED_RESULT SfxViewFrame * Current()
SfxBindings & GetBindings()
SfxFrame & GetFrame() const
void SetPropLineSpace(const sal_uInt16 nProp)
void SetInterLineSpaceRule(SvxInterLineSpaceRule e)
sal_uInt16 GetPropLineSpace() const
SvxInterLineSpaceRule GetInterLineSpaceRule() const
SvxLineSpaceRule GetLineSpaceRule() const
sal_uInt16 GetLineHeight() const
void SetLineSpaceRule(SvxLineSpaceRule e)
void SetLineHeight(const sal_uInt16 nHeight)
short GetInterLineSpace() const
void SetInterLineSpace(const short nSpace)
std::unique_ptr< weld::Button > mxSpacing1Button
void SelectEntryPos(sal_Int32 nPos)
Set the entry and update the metric fields.
weld::MetricSpinButton * mpActLineDistFld
void Initialize()
Setup the widgets with values from the document.
std::unique_ptr< weld::Button > mxSpacing115Button
virtual void GrabFocus() override
std::unique_ptr< weld::ComboBox > mxLineDist
std::unique_ptr< weld::Label > mxLineDistLabel
std::unique_ptr< weld::MetricSpinButton > mxLineDistAtMetricBox
void ExecuteLineSpace()
Take the values from the widgets, and update the paragraph accordingly.
std::unique_ptr< weld::Button > mxSpacing2Button
std::unique_ptr< weld::Button > mxSpacing15Button
rtl::Reference< SvxLineSpacingToolBoxControl > mxControl
void ExecuteLineSpacing(sal_Int32 aEntry)
For the buttons - set the values, and close the popup.
std::unique_ptr< weld::MetricSpinButton > mxLineDistAtPercentBox
void UpdateMetricFields()
Set mpActlineDistFld and visibility of mpLineDist* fields according to what is just selected.
static void SetLineSpace(SvxLineSpacingItem &rLineSpace, sal_Int32 eSpace, tools::Long lValue=0)
Set one particular value.
void set_text(const OUString &rText)
void set_sensitive(bool sensitive)
FieldUnit
sal_uInt16 nPos
MapUnit
IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::Toggleable &, rBox, void)
IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet *, void)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
OUString GetModuleIdentifier(const Reference< frame::XFrame > &rxFrame)
SfxItemState
SvxInterLineSpaceRule
SVT_DLLPUBLIC sal_Int64 GetCoreValue(const weld::MetricSpinButton &rField, MapUnit eUnit)
SVT_DLLPUBLIC void SetMetricValue(weld::MetricSpinButton &rField, sal_Int64 nCoreValue, MapUnit eUnit)
SVT_DLLPUBLIC void SetFieldUnit(weld::MetricSpinButton &rCtrl, FieldUnit eUnit, bool bAll=false)
constexpr OUStringLiteral PERCENT(u"Percent")