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>
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
39namespace 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));
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 tools::Long nKerning = mxEditKerning->get_value(FieldUnit::NONE);
71 switch (nKerning)
72 {
74 mxVeryTight->grab_focus();
75 break;
76 case SPACING_TIGHT:
77 mxTight->grab_focus();
78 break;
79 case SPACING_NORMAL:
80 mxNormal->grab_focus();
81 break;
82 case SPACING_LOOSE:
83 mxLoose->grab_focus();
84 break;
86 mxVeryLoose->grab_focus();
87 break;
88 default:
89 if (nKerning == mnCustomKern)
90 mxLastCustom->grab_focus();
91 else
92 mxEditKerning->grab_focus();
93 }
94}
95
97{
99 {
100 SvtViewOptions aWinOpt(EViewType::Window, SIDEBAR_SPACING_GLOBAL_VALUE);
101 css::uno::Sequence<css::beans::NamedValue> aSeq
102 { { "Spacing", css::uno::Any(OUString::number(mnCustomKern)) } };
103 aWinOpt.SetUserData(aSeq);
104 }
105}
106
108{
109 const SvxKerningItem* pKerningItem(nullptr);
111 SfxItemState eState = pViewFrm ? pViewFrm->GetBindings().GetDispatcher()->QueryState(SID_ATTR_CHAR_KERNING, pKerningItem) : SfxItemState::UNKNOWN;
112
113 tools::Long nKerning = 0;
114
115 if (pKerningItem)
116 nKerning = pKerningItem->GetValue();
117
118 SvtViewOptions aWinOpt(EViewType::Window, SIDEBAR_SPACING_GLOBAL_VALUE);
119 if(aWinOpt.Exists())
120 {
121 css::uno::Sequence<css::beans::NamedValue> aSeq = aWinOpt.GetUserData();
122 OUString aTmp;
123 if(aSeq.hasElements())
124 aSeq[0].Value >>= aTmp;
125
126 OUString aWinData(aTmp);
127 mnCustomKern = aWinData.toInt32();
129 }
130 else
131 {
133 }
134
135 if(eState >= SfxItemState::DEFAULT)
136 {
137 MapUnit eUnit = GetCoreMetric();
138 MapUnit eOrgUnit = eUnit;
139 tools::Long nBig = mxEditKerning->normalize(nKerning);
140 nKerning = OutputDevice::LogicToLogic(nBig, eOrgUnit, MapUnit::MapPoint);
141 mxEditKerning->set_value(nKerning, FieldUnit::NONE);
142 }
143 else if(SfxItemState::DISABLED == eState)
144 {
145 mxEditKerning->set_text(OUString());
146 mxEditKerning->set_sensitive(false);
147 }
148 else
149 {
150 mxEditKerning->set_text(OUString());
151 mxEditKerning->set_sensitive(false);
152 }
153}
154
156{
157 MapUnit eUnit = GetCoreMetric();
158
159 tools::Long nSign = (nValue < 0) ? -1 : 1;
160 nValue = nValue * nSign;
161
162 tools::Long nVal = OutputDevice::LogicToLogic(nValue, MapUnit::MapPoint, eUnit);
163 short nKern = (nValue == 0) ? 0 : static_cast<short>(mxEditKerning->denormalize(nVal));
164
165 SvxKerningItem aKernItem(nSign * nKern, SID_ATTR_CHAR_KERNING);
166
167 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
168 {
169 pViewFrm->GetBindings().GetDispatcher()->ExecuteList(SID_ATTR_CHAR_KERNING,
170 SfxCallMode::RECORD, { &aKernItem });
171 }
172
173 if (bClose)
174 mxControl->EndPopupMode();
175}
176
177IMPL_LINK(TextCharacterSpacingControl, PredefinedValuesHdl, weld::Button&, rControl, void)
178{
179 mnLastCus = SPACING_CLOSE_BY_CLICK_ICON;
180
181 if (&rControl == mxNormal.get())
182 {
183 ExecuteCharacterSpacing(SPACING_NORMAL);
184 }
185 else if (&rControl == mxVeryTight.get())
186 {
187 ExecuteCharacterSpacing(SPACING_VERY_TIGHT);
188 }
189 else if (&rControl == mxTight.get())
190 {
191 ExecuteCharacterSpacing(SPACING_TIGHT);
192 }
193 else if (&rControl == mxVeryLoose.get())
194 {
195 ExecuteCharacterSpacing(SPACING_VERY_LOOSE);
196 }
197 else if (&rControl == mxLoose.get())
198 {
199 ExecuteCharacterSpacing(SPACING_LOOSE);
200 }
201 else if (&rControl == mxLastCustom.get())
202 {
203 ExecuteCharacterSpacing(mnCustomKern);
204 }
205}
206
208{
209 mnLastCus = SPACING_CLOSE_BY_CUS_EDIT;
210 mnCustomKern = mxEditKerning->get_value(FieldUnit::NONE);
211
212 ExecuteCharacterSpacing(mnCustomKern, false);
213}
214
216{
217 SfxItemPool &rPool = SfxGetpApp()->GetPool();
218 sal_uInt16 nWhich = rPool.GetWhich(SID_ATTR_CHAR_KERNING);
219 return rPool.GetMetric(nWhich);
220}
221
222} // end of namespace svx
223
224/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define SPACING_LOOSE
#define SPACING_VERY_TIGHT
#define SPACING_NORMAL
#define SPACING_VERY_LOOSE
#define SPACING_TIGHT
#define SPACING_CLOSE_BY_CLICK_ICON
#define SPACING_NOCUSTOM
#define SPACING_CLOSE_BY_CUS_EDIT
SfxApplication * SfxGetpApp()
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
SfxDispatcher * GetDispatcher() const
SfxItemState QueryState(sal_uInt16 nSID, const SfxPoolItem *&rpState)
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
SfxItemPool & GetPool() const
static SAL_WARN_UNUSED_RESULT SfxViewFrame * Current()
SfxBindings & GetBindings()
void SetUserData(const css::uno::Sequence< css::beans::NamedValue > &lData)
css::uno::Sequence< css::beans::NamedValue > GetUserData() const
bool Exists() const
std::unique_ptr< weld::Button > mxVeryLoose
std::unique_ptr< weld::MetricSpinButton > mxEditKerning
void ExecuteCharacterSpacing(tools::Long nValue, bool bClose=true)
TextCharacterSpacingControl(TextCharacterSpacingPopup *pControl, weld::Widget *pParent)
std::unique_ptr< weld::Button > mxTight
rtl::Reference< TextCharacterSpacingPopup > mxControl
std::unique_ptr< weld::Button > mxLastCustom
std::unique_ptr< weld::Button > mxNormal
std::unique_ptr< weld::Button > mxVeryTight
std::unique_ptr< weld::Button > mxLoose
FieldUnit
sal_Int16 nValue
Definition: fmsrccfg.cxx:81
constexpr OUStringLiteral HID_SPACING_MB_KERN
Definition: helpids.h:44
Sequence< sal_Int8 > aSeq
MapUnit
IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::Toggleable &, rBox, void)
constexpr OUStringLiteral SIDEBAR_SPACING_GLOBAL_VALUE
IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet *, void)
long Long
SfxItemState