LibreOffice Module svx (master)  1
TextCharacterSpacingControl.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 <sfx2/bindings.hxx>
21 #include <unotools/viewoptions.hxx>
22 #include <editeng/editids.hrc>
23 #include <editeng/kernitem.hxx>
24 #include <sfx2/app.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/viewfrm.hxx>
28 #include <svl/itempool.hxx>
29 #include <helpids.h>
30 
31 #include <com/sun/star/beans/NamedValue.hpp>
32 
33 #define SPACING_VERY_TIGHT -30
34 #define SPACING_TIGHT -15
35 #define SPACING_NORMAL 0
36 #define SPACING_LOOSE 30
37 #define SPACING_VERY_LOOSE 60
38 
39 namespace svx {
40 
42  : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/textcharacterspacingcontrol.ui", "TextCharacterSpacingControl")
43  , mnCustomKern(0)
44  , mnLastCus(SPACING_NOCUSTOM)
45  , mxEditKerning(m_xBuilder->weld_metric_spin_button("kerning", FieldUnit::POINT))
46  , mxTight(m_xBuilder->weld_button("tight"))
47  , mxVeryTight(m_xBuilder->weld_button("very_tight"))
48  , mxNormal(m_xBuilder->weld_button("normal"))
49  , mxLoose(m_xBuilder->weld_button("loose"))
50  , mxVeryLoose(m_xBuilder->weld_button("very_loose"))
51  , mxLastCustom(m_xBuilder->weld_button("last_custom"))
52  , mxControl(pControl)
53 {
54  mxEditKerning->connect_value_changed(LINK(this, TextCharacterSpacingControl, KerningModifyHdl));
55  mxEditKerning->set_help_id(HID_SPACING_MB_KERN);
56 
57  Link<weld::Button&,void> aLink = LINK(this, TextCharacterSpacingControl, PredefinedValuesHdl);
58  mxNormal->connect_clicked(aLink);
59  mxVeryTight->connect_clicked(aLink);
60  mxTight->connect_clicked(aLink);
61  mxVeryLoose->connect_clicked(aLink);
62  mxLoose->connect_clicked(aLink);
63  mxLastCustom->connect_clicked(aLink);
64 
65  Initialize();
66 }
67 
69 {
70  mxVeryTight->grab_focus();
71 }
72 
74 {
76  {
77  SvtViewOptions aWinOpt(EViewType::Window, SIDEBAR_SPACING_GLOBAL_VALUE);
78  css::uno::Sequence<css::beans::NamedValue> aSeq
79  { { "Spacing", css::uno::makeAny(OUString::number(mnCustomKern)) } };
80  aWinOpt.SetUserData(aSeq);
81  }
82 }
83 
85 {
86  const SfxPoolItem* pItem;
87  SfxItemState eState = SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_CHAR_KERNING, pItem);
88 
89  const SvxKerningItem* pKerningItem = static_cast<const SvxKerningItem*>(pItem);
90  long nKerning = 0;
91 
92  if(pKerningItem)
93  nKerning = pKerningItem->GetValue();
94 
95  SvtViewOptions aWinOpt(EViewType::Window, SIDEBAR_SPACING_GLOBAL_VALUE);
96  if(aWinOpt.Exists())
97  {
98  css::uno::Sequence<css::beans::NamedValue> aSeq = aWinOpt.GetUserData();
99  OUString aTmp;
100  if(aSeq.hasElements())
101  aSeq[0].Value >>= aTmp;
102 
103  OUString aWinData(aTmp);
104  mnCustomKern = aWinData.toInt32();
106  }
107  else
108  {
110  }
111 
112  if(eState >= SfxItemState::DEFAULT)
113  {
114  MapUnit eUnit = GetCoreMetric();
115  MapUnit eOrgUnit = eUnit;
116  long nBig = mxEditKerning->normalize(nKerning);
117  nKerning = OutputDevice::LogicToLogic(nBig, eOrgUnit, MapUnit::MapPoint);
118  mxEditKerning->set_value(nKerning, FieldUnit::NONE);
119  }
120  else if(SfxItemState::DISABLED == eState)
121  {
122  mxEditKerning->set_text(OUString());
123  mxEditKerning->set_sensitive(false);
124  }
125  else
126  {
127  mxEditKerning->set_text(OUString());
128  mxEditKerning->set_sensitive(false);
129  }
130 }
131 
133 {
134  MapUnit eUnit = GetCoreMetric();
135 
136  long nSign = (nValue < 0) ? -1 : 1;
137  nValue = nValue * nSign;
138 
139  long nVal = OutputDevice::LogicToLogic(nValue, MapUnit::MapPoint, eUnit);
140  short nKern = (nValue == 0) ? 0 : static_cast<short>(mxEditKerning->denormalize(nVal));
141 
142  SvxKerningItem aKernItem(nSign * nKern, SID_ATTR_CHAR_KERNING);
143 
144  SfxViewFrame::Current()->GetBindings().GetDispatcher()->ExecuteList(SID_ATTR_CHAR_KERNING,
145  SfxCallMode::RECORD, { &aKernItem });
146 
147  if (bClose)
148  mxControl->EndPopupMode();
149 }
150 
151 IMPL_LINK(TextCharacterSpacingControl, PredefinedValuesHdl, weld::Button&, rControl, void)
152 {
153  mnLastCus = SPACING_CLOSE_BY_CLICK_ICON;
154 
155  if (&rControl == mxNormal.get())
156  {
157  ExecuteCharacterSpacing(SPACING_NORMAL);
158  }
159  else if (&rControl == mxVeryTight.get())
160  {
161  ExecuteCharacterSpacing(SPACING_VERY_TIGHT);
162  }
163  else if (&rControl == mxTight.get())
164  {
165  ExecuteCharacterSpacing(SPACING_TIGHT);
166  }
167  else if (&rControl == mxVeryLoose.get())
168  {
169  ExecuteCharacterSpacing(SPACING_VERY_LOOSE);
170  }
171  else if (&rControl == mxLoose.get())
172  {
173  ExecuteCharacterSpacing(SPACING_LOOSE);
174  }
175  else if (&rControl == mxLastCustom.get())
176  {
177  ExecuteCharacterSpacing(mnCustomKern);
178  }
179 }
180 
182 {
183  mnLastCus = SPACING_CLOSE_BY_CUS_EDIT;
184  mnCustomKern = mxEditKerning->get_value(FieldUnit::NONE);
185 
186  ExecuteCharacterSpacing(mnCustomKern, false);
187 }
188 
190 {
191  SfxItemPool &rPool = SfxGetpApp()->GetPool();
192  sal_uInt16 nWhich = rPool.GetWhich(SID_ATTR_CHAR_KERNING);
193  return rPool.GetMetric(nWhich);
194 }
195 
196 } // end of namespace svx
197 
198 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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 * >())
css::uno::Sequence< css::beans::NamedValue > GetUserData() const
FieldUnit
std::unique_ptr< weld::Button > mxVeryTight
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
#define SIDEBAR_SPACING_GLOBAL_VALUE
#define SPACING_LOOSE
std::unique_ptr< weld::Button > mxVeryLoose
#define HID_SPACING_MB_KERN
Definition: helpids.h:42
SfxApplication * SfxGetpApp()
Value
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
rtl::Reference< TextCharacterSpacingPopup > mxControl
std::unique_ptr< weld::Button > mxLoose
std::unique_ptr< weld::Button > mxNormal
SfxItemPool & GetPool() const
IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet *, void)
#define SPACING_TIGHT
#define SPACING_CLOSE_BY_CLICK_ICON
SfxBindings & GetBindings()
std::unique_ptr< weld::Button > mxLastCustom
void SetUserData(const css::uno::Sequence< css::beans::NamedValue > &lData)
#define SPACING_NOCUSTOM
IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::ToggleButton &, rBox, void)
SfxItemState QueryState(sal_uInt16 nSID, const SfxPoolItem *&rpState)
#define SPACING_VERY_LOOSE
static SfxViewFrame * Current()
SfxItemState
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
#define SPACING_CLOSE_BY_CUS_EDIT
bool Exists() const
Sequence< sal_Int8 > aSeq
SfxDispatcher * GetDispatcher() const
std::unique_ptr< weld::Button > mxTight
MapUnit
#define SPACING_NORMAL
void ExecuteCharacterSpacing(long nValue, bool bClose=true)
std::unique_ptr< weld::MetricSpinButton > mxEditKerning
TextCharacterSpacingControl(TextCharacterSpacingPopup *pControl, weld::Widget *pParent)
#define SPACING_VERY_TIGHT
sal_Int16 nValue
Definition: fmsrccfg.cxx:81