Line data Source code
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 :
20 : #include "ParaLineSpacingControl.hxx"
21 :
22 : #include <editeng/editids.hrc>
23 : #include <editeng/kernitem.hxx>
24 : #include <editeng/lspcitem.hxx>
25 : #include <sfx2/dispatch.hxx>
26 : #include <svtools/unitconv.hxx>
27 :
28 : #define DEFAULT_LINE_SPACING 200
29 : #define FIX_DIST_DEF 283
30 : #define LINESPACE_1 100
31 : #define LINESPACE_15 150
32 : #define LINESPACE_2 200
33 : #define LINESPACE_115 115
34 :
35 : // values of the mpLineDist listbox
36 : #define LLINESPACE_1 0
37 : #define LLINESPACE_15 1
38 : #define LLINESPACE_2 2
39 : #define LLINESPACE_PROP 3
40 : #define LLINESPACE_MIN 4
41 : #define LLINESPACE_DURCH 5
42 : #define LLINESPACE_FIX 6
43 :
44 : // special case; should not conflict with the mpLinDist values
45 : #define LLINESPACE_115 7
46 :
47 : #define MIN_FIXED_DISTANCE 28
48 :
49 : using namespace svx;
50 :
51 0 : ParaLineSpacingControl::ParaLineSpacingControl(sal_uInt16 nId)
52 0 : : SfxPopupWindow(nId, "ParaLineSpacingControl", "svx/ui/paralinespacingcontrol.ui")
53 : {
54 0 : mpSpacing1Button = get<PushButton>("spacing_1");
55 0 : mpSpacing115Button = get<PushButton>("spacing_115");
56 0 : mpSpacing15Button = get<PushButton>("spacing_15");
57 0 : mpSpacing2Button = get<PushButton>("spacing_2");
58 :
59 0 : mpLineDist = get<ListBox>("line_dist");
60 :
61 0 : mpLineDistLabel = get<FixedText>("value_label");
62 0 : mpLineDistAtPercentBox = get<MetricField>("percent_box");
63 0 : mpLineDistAtMetricBox = get<MetricField>("metric_box");
64 :
65 0 : mpActLineDistFld = mpLineDistAtPercentBox.get();
66 :
67 0 : meLNSpaceUnit = SFX_MAPUNIT_100TH_MM;
68 :
69 0 : Link<> aLink = LINK(this, ParaLineSpacingControl, PredefinedValuesHandler);
70 0 : mpSpacing1Button->SetClickHdl(aLink);
71 0 : mpSpacing115Button->SetClickHdl(aLink);
72 0 : mpSpacing15Button->SetClickHdl(aLink);
73 0 : mpSpacing2Button->SetClickHdl(aLink);
74 :
75 0 : aLink = LINK( this, ParaLineSpacingControl, LineSPDistHdl_Impl );
76 0 : mpLineDist->SetSelectHdl(aLink);
77 0 : SelectEntryPos(LLINESPACE_1);
78 :
79 0 : aLink = LINK( this, ParaLineSpacingControl, LineSPDistAtHdl_Impl );
80 0 : mpLineDistAtPercentBox->SetModifyHdl( aLink );
81 0 : mpLineDistAtMetricBox->SetModifyHdl( aLink );
82 :
83 0 : FieldUnit eUnit = FUNIT_INCH;
84 0 : const SfxPoolItem* pItem = NULL;
85 0 : if (SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_METRIC, pItem) >= SfxItemState::DEFAULT)
86 0 : eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
87 : else
88 0 : eUnit = SfxModule::GetCurrentFieldUnit();
89 :
90 0 : SetFieldUnit(*mpLineDistAtMetricBox, eUnit);
91 :
92 0 : Initialize();
93 0 : }
94 :
95 0 : ParaLineSpacingControl::~ParaLineSpacingControl()
96 : {
97 0 : disposeOnce();
98 0 : }
99 :
100 0 : void ParaLineSpacingControl::dispose()
101 : {
102 0 : mpActLineDistFld.clear();
103 0 : mpSpacing1Button.clear();
104 0 : mpSpacing115Button.clear();
105 0 : mpSpacing15Button.clear();
106 0 : mpSpacing2Button.clear();
107 0 : mpLineDist.clear();
108 0 : mpLineDistLabel.clear();
109 0 : mpLineDistAtPercentBox.clear();
110 0 : mpLineDistAtMetricBox.clear();
111 0 : SfxPopupWindow::dispose();
112 0 : }
113 :
114 0 : void ParaLineSpacingControl::Initialize()
115 : {
116 : const SfxPoolItem* pItem;
117 0 : SfxItemState eState = SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PARA_LINESPACE, pItem);
118 :
119 0 : const SvxLineSpacingItem* currSPItem = static_cast<const SvxLineSpacingItem*>(pItem);
120 :
121 0 : mpLineDist->Enable();
122 :
123 0 : if( eState >= SfxItemState::DEFAULT )
124 : {
125 0 : SfxMapUnit eUnit = SFX_MAPUNIT_100TH_MM;
126 0 : meLNSpaceUnit = eUnit;
127 :
128 0 : switch( currSPItem->GetLineSpaceRule() )
129 : {
130 : case SVX_LINE_SPACE_AUTO:
131 : {
132 0 : SvxInterLineSpace eInter = currSPItem->GetInterLineSpaceRule();
133 :
134 0 : switch( eInter )
135 : {
136 : case SVX_INTER_LINE_SPACE_OFF:
137 0 : SelectEntryPos(LLINESPACE_1);
138 0 : break;
139 :
140 : case SVX_INTER_LINE_SPACE_PROP:
141 : {
142 0 : if ( LINESPACE_1 == currSPItem->GetPropLineSpace() )
143 : {
144 0 : SelectEntryPos(LLINESPACE_1);
145 : }
146 0 : else if ( LINESPACE_15 == currSPItem->GetPropLineSpace() )
147 : {
148 0 : SelectEntryPos(LLINESPACE_15);
149 : }
150 0 : else if ( LINESPACE_2 == currSPItem->GetPropLineSpace() )
151 : {
152 0 : SelectEntryPos(LLINESPACE_2);
153 : }
154 : else
155 : {
156 0 : SelectEntryPos(LLINESPACE_PROP);
157 0 : mpLineDistAtPercentBox->SetValue(mpLineDistAtPercentBox->Normalize(currSPItem->GetPropLineSpace()));
158 : }
159 : }
160 0 : break;
161 :
162 : case SVX_INTER_LINE_SPACE_FIX:
163 : {
164 0 : SelectEntryPos(LLINESPACE_DURCH);
165 0 : SetMetricValue(*mpLineDistAtMetricBox, currSPItem->GetInterLineSpace(), eUnit);
166 : }
167 0 : break;
168 : default:
169 0 : break;
170 : }
171 : }
172 0 : break;
173 : case SVX_LINE_SPACE_FIX:
174 : {
175 0 : SelectEntryPos(LLINESPACE_FIX);
176 0 : SetMetricValue(*mpLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit);
177 : }
178 0 : break;
179 :
180 : case SVX_LINE_SPACE_MIN:
181 : {
182 0 : SelectEntryPos(LLINESPACE_MIN);
183 0 : SetMetricValue(*mpLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit);
184 : }
185 0 : break;
186 : default:
187 0 : break;
188 : }
189 : }
190 0 : else if( eState == SfxItemState::DISABLED )
191 : {
192 0 : mpLineDist->Disable();
193 0 : mpLineDistLabel->Disable();
194 0 : mpActLineDistFld->Disable();
195 0 : mpActLineDistFld->SetText("");
196 :
197 : }
198 : else
199 : {
200 0 : mpLineDistLabel->Disable();
201 0 : mpActLineDistFld->Disable();
202 0 : mpActLineDistFld->SetText("");
203 0 : mpLineDist->SetNoSelection();
204 : }
205 :
206 0 : mpLineDist->SaveValue();
207 :
208 : /* TODO
209 : const sal_uInt16 uCount = mpLineDist->GetEntryCount();
210 : if( uCount == LLINESPACE_FIX + 1 )
211 : {
212 : switch (currentContext.GetCombinedContext_DI())
213 : {
214 : case CombinedEnumContext(Application_DrawImpress, Context_Table):
215 : case CombinedEnumContext(Application_DrawImpress, Context_DrawText):
216 : case CombinedEnumContext(Application_DrawImpress, Context_Draw):
217 : case CombinedEnumContext(Application_DrawImpress, Context_TextObject):
218 : case CombinedEnumContext(Application_DrawImpress, Context_Graphic):
219 : case CombinedEnumContext(Application_Calc, Context_DrawText):
220 : case CombinedEnumContext(Application_WriterVariants, Context_DrawText):
221 : case CombinedEnumContext(Application_WriterVariants, Context_Annotation):
222 : {
223 : mpLineDist->RemoveEntry(LLINESPACE_FIX);
224 : }
225 : }
226 : }
227 : else if( uCount == LLINESPACE_FIX)
228 : {
229 : switch (currentContext.GetCombinedContext_DI())
230 : {
231 : case CombinedEnumContext(Application_WriterVariants, Context_Default):
232 : case CombinedEnumContext(Application_WriterVariants, Context_Text):
233 : case CombinedEnumContext(Application_WriterVariants, Context_Table):
234 : {
235 : mpLineDist->InsertEntry(OUString("Fixed"), LLINESPACE_FIX);
236 : }
237 : }
238 : }
239 : */
240 0 : }
241 :
242 0 : void ParaLineSpacingControl::UpdateMetricFields()
243 : {
244 0 : switch (mpLineDist->GetSelectEntryPos())
245 : {
246 : case LLINESPACE_1:
247 : case LLINESPACE_15:
248 : case LLINESPACE_2:
249 0 : if (mpActLineDistFld == mpLineDistAtPercentBox)
250 0 : mpLineDistAtMetricBox->Hide();
251 : else
252 0 : mpLineDistAtPercentBox->Hide();
253 :
254 0 : mpLineDistLabel->Disable();
255 0 : mpActLineDistFld->Show();
256 0 : mpActLineDistFld->Disable();
257 0 : mpActLineDistFld->SetText("");
258 0 : break;
259 :
260 : case LLINESPACE_DURCH:
261 0 : mpLineDistAtPercentBox->Hide();
262 :
263 0 : mpActLineDistFld = mpLineDistAtMetricBox.get();
264 0 : mpLineDistAtMetricBox->SetMin(0);
265 :
266 0 : if (mpLineDistAtMetricBox->GetText().isEmpty())
267 0 : mpLineDistAtMetricBox->SetValue(mpLineDistAtMetricBox->Normalize(0));
268 :
269 0 : mpLineDistLabel->Enable();
270 0 : mpActLineDistFld->Show();
271 0 : mpActLineDistFld->Enable();
272 0 : break;
273 :
274 : case LLINESPACE_MIN:
275 0 : mpLineDistAtPercentBox->Hide();
276 :
277 0 : mpActLineDistFld = mpLineDistAtMetricBox.get();
278 0 : mpLineDistAtMetricBox->SetMin(0);
279 :
280 0 : if (mpLineDistAtMetricBox->GetText().isEmpty())
281 0 : mpLineDistAtMetricBox->SetValue(mpLineDistAtMetricBox->Normalize(0), FUNIT_TWIP);
282 :
283 0 : mpLineDistLabel->Enable();
284 0 : mpActLineDistFld->Show();
285 0 : mpActLineDistFld->Enable();
286 0 : break;
287 :
288 : case LLINESPACE_PROP:
289 0 : mpLineDistAtMetricBox->Hide();
290 :
291 0 : mpActLineDistFld = mpLineDistAtPercentBox.get();
292 :
293 0 : if (mpLineDistAtPercentBox->GetText().isEmpty())
294 0 : mpLineDistAtPercentBox->SetValue(mpLineDistAtPercentBox->Normalize(100), FUNIT_TWIP);
295 :
296 0 : mpLineDistLabel->Enable();
297 0 : mpActLineDistFld->Show();
298 0 : mpActLineDistFld->Enable();
299 0 : break;
300 :
301 : case LLINESPACE_FIX:
302 0 : mpLineDistAtPercentBox->Hide();
303 :
304 0 : mpActLineDistFld = mpLineDistAtMetricBox.get();
305 0 : sal_Int64 nTemp = mpLineDistAtMetricBox->GetValue();
306 0 : mpLineDistAtMetricBox->SetMin(mpLineDistAtMetricBox->Normalize(MIN_FIXED_DISTANCE), FUNIT_TWIP);
307 :
308 0 : if (mpLineDistAtMetricBox->GetValue() != nTemp)
309 0 : SetMetricValue(*mpLineDistAtMetricBox, FIX_DIST_DEF, SFX_MAPUNIT_TWIP);
310 :
311 0 : mpLineDistLabel->Enable();
312 0 : mpActLineDistFld->Show();
313 0 : mpActLineDistFld->Enable();
314 0 : break;
315 : }
316 0 : }
317 :
318 0 : void ParaLineSpacingControl::SelectEntryPos(sal_Int32 nPos)
319 : {
320 0 : mpLineDist->SelectEntryPos(nPos);
321 0 : UpdateMetricFields();
322 0 : }
323 :
324 0 : IMPL_LINK(ParaLineSpacingControl, LineSPDistHdl_Impl, ListBox*, /*pBox*/)
325 : {
326 0 : UpdateMetricFields();
327 0 : ExecuteLineSpace();
328 0 : return 0;
329 : }
330 :
331 0 : IMPL_LINK_NOARG( ParaLineSpacingControl, LineSPDistAtHdl_Impl )
332 : {
333 0 : ExecuteLineSpace();
334 0 : return 0L;
335 : }
336 :
337 0 : void ParaLineSpacingControl::ExecuteLineSpace()
338 : {
339 0 : mpLineDist->SaveValue();
340 :
341 0 : SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE);
342 0 : sal_uInt16 nPos = mpLineDist->GetSelectEntryPos();
343 :
344 0 : switch ( nPos )
345 : {
346 : case LLINESPACE_1:
347 : case LLINESPACE_15:
348 : case LLINESPACE_2:
349 0 : SetLineSpace(aSpacing, nPos);
350 0 : break;
351 :
352 : case LLINESPACE_PROP:
353 0 : SetLineSpace(aSpacing, nPos, mpLineDistAtPercentBox->Denormalize((long)mpLineDistAtPercentBox->GetValue()));
354 0 : break;
355 :
356 : case LLINESPACE_MIN:
357 : case LLINESPACE_DURCH:
358 : case LLINESPACE_FIX:
359 0 : SetLineSpace(aSpacing, nPos, GetCoreValue(*mpLineDistAtMetricBox, meLNSpaceUnit));
360 0 : break;
361 :
362 : default:
363 0 : break;
364 : }
365 :
366 0 : SfxViewFrame::Current()->GetBindings().GetDispatcher()->Execute(
367 0 : SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, &aSpacing, 0L);
368 0 : }
369 :
370 0 : void ParaLineSpacingControl::SetLineSpace(SvxLineSpacingItem& rLineSpace, int eSpace, long lValue)
371 : {
372 0 : switch ( eSpace )
373 : {
374 : case LLINESPACE_1:
375 0 : rLineSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
376 0 : rLineSpace.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
377 0 : break;
378 :
379 : case LLINESPACE_15:
380 0 : rLineSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
381 0 : rLineSpace.SetPropLineSpace( LINESPACE_15 );
382 0 : break;
383 :
384 : case LLINESPACE_2:
385 0 : rLineSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
386 0 : rLineSpace.SetPropLineSpace( LINESPACE_2 );
387 0 : break;
388 :
389 : case LLINESPACE_PROP:
390 0 : rLineSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
391 0 : rLineSpace.SetPropLineSpace( (sal_uInt8)lValue );
392 0 : break;
393 :
394 : case LLINESPACE_MIN:
395 0 : rLineSpace.SetLineHeight( (sal_uInt16)lValue );
396 0 : rLineSpace.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
397 0 : break;
398 :
399 : case LLINESPACE_DURCH:
400 0 : rLineSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
401 0 : rLineSpace.SetInterLineSpace( (sal_uInt16)lValue );
402 0 : break;
403 :
404 : case LLINESPACE_FIX:
405 0 : rLineSpace.SetLineHeight((sal_uInt16)lValue);
406 0 : rLineSpace.GetLineSpaceRule() = SVX_LINE_SPACE_FIX;
407 0 : rLineSpace.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
408 0 : break;
409 : }
410 0 : }
411 :
412 0 : IMPL_LINK(ParaLineSpacingControl, PredefinedValuesHandler, void *, pControl)
413 : {
414 0 : if (pControl == mpSpacing1Button)
415 : {
416 0 : ExecuteLineSpacing(LLINESPACE_1);
417 : }
418 0 : else if (pControl == mpSpacing115Button)
419 : {
420 0 : ExecuteLineSpacing(LLINESPACE_115);
421 : }
422 0 : else if (pControl == mpSpacing15Button)
423 : {
424 0 : ExecuteLineSpacing(LLINESPACE_15);
425 : }
426 0 : else if (pControl == mpSpacing2Button)
427 : {
428 0 : ExecuteLineSpacing(LLINESPACE_2);
429 : }
430 :
431 0 : return 0;
432 : }
433 :
434 0 : void ParaLineSpacingControl::ExecuteLineSpacing(sal_uInt16 nEntry)
435 : {
436 0 : SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE);
437 :
438 : // special-case the 1.15 line spacing
439 0 : if (nEntry == LLINESPACE_115)
440 0 : SetLineSpace(aSpacing, LLINESPACE_PROP, mpLineDistAtPercentBox->Denormalize(LINESPACE_115));
441 : else
442 0 : SetLineSpace(aSpacing, nEntry);
443 :
444 0 : SfxViewFrame::Current()->GetBindings().GetDispatcher()->Execute(
445 0 : SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, &aSpacing, 0L);
446 :
447 : // close when the user used the buttons
448 0 : EndPopupMode();
449 390 : }
450 :
451 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|