1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sfx2/app.hxx>
23 #include <hintids.hxx>
24 #include <swtypes.hxx>
25 #include <globals.hrc>
26 #include <svx/colorbox.hxx>
27 #include <svx/xtable.hxx>
28 #include <svx/svxids.hrc>
30 #include <editeng/sizeitem.hxx>
31 #include <editeng/lrspitem.hxx>
32 #include <editeng/ulspitem.hxx>
33 #include <editeng/boxitem.hxx>
34 #include <editeng/frmdiritem.hxx>
35 #include <svx/ruler.hxx>
37 #include <tgrditem.hxx>
41 #include <uiitems.hxx>
42 #include <swmodule.hxx>
45 SwTextGridPage::SwTextGridPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
&rSet
)
46 : SfxTabPage(pPage
, pController
, "modules/swriter/ui/textgridpage.ui", "TextGridPage", &rSet
)
48 , m_bRubyUserValue(false)
49 , m_aPageSize(MM50
, MM50
)
51 , m_bSquaredMode(false)
52 , m_bHRulerChanged(false)
53 , m_bVRulerChanged(false)
54 , m_xNoGridRB(m_xBuilder
->weld_radio_button("radioRB_NOGRID"))
55 , m_xLinesGridRB(m_xBuilder
->weld_radio_button("radioRB_LINESGRID"))
56 , m_xCharsGridRB(m_xBuilder
->weld_radio_button("radioRB_CHARSGRID"))
57 , m_xSnapToCharsCB(m_xBuilder
->weld_check_button("checkCB_SNAPTOCHARS"))
58 , m_xExampleWN(new weld::CustomWeld(*m_xBuilder
, "drawingareaWN_EXAMPLE", m_aExampleWN
))
59 , m_xLayoutFL(m_xBuilder
->weld_widget("frameFL_LAYOUT"))
60 , m_xLinesPerPageNF(m_xBuilder
->weld_spin_button("spinNF_LINESPERPAGE"))
61 , m_xLinesRangeFT(m_xBuilder
->weld_label("labelFT_LINERANGE"))
62 , m_xTextSizeMF(m_xBuilder
->weld_metric_spin_button("spinMF_TEXTSIZE", FieldUnit::POINT
))
63 , m_xCharsPerLineFT(m_xBuilder
->weld_label("labelFT_CHARSPERLINE"))
64 , m_xCharsPerLineNF(m_xBuilder
->weld_spin_button("spinNF_CHARSPERLINE"))
65 , m_xCharsRangeFT(m_xBuilder
->weld_label("labelFT_CHARRANGE"))
66 , m_xCharWidthFT(m_xBuilder
->weld_label("labelFT_CHARWIDTH"))
67 , m_xCharWidthMF(m_xBuilder
->weld_metric_spin_button("spinMF_CHARWIDTH", FieldUnit::POINT
))
68 , m_xRubySizeFT(m_xBuilder
->weld_label("labelFT_RUBYSIZE"))
69 , m_xRubySizeMF(m_xBuilder
->weld_metric_spin_button("spinMF_RUBYSIZE", FieldUnit::POINT
))
70 , m_xRubyBelowCB(m_xBuilder
->weld_check_button("checkCB_RUBYBELOW"))
71 , m_xDisplayFL(m_xBuilder
->weld_widget("frameFL_DISPLAY"))
72 , m_xDisplayCB(m_xBuilder
->weld_check_button("checkCB_DISPLAY"))
73 , m_xPrintCB(m_xBuilder
->weld_check_button("checkCB_PRINT"))
74 , m_xColorLB(new ColorListBox(m_xBuilder
->weld_menu_button("listLB_COLOR"), pController
->getDialog()))
76 Link
<weld::SpinButton
&,void> aLink
= LINK(this, SwTextGridPage
, CharorLineChangedHdl
);
77 m_xCharsPerLineNF
->connect_value_changed(aLink
);
78 m_xLinesPerPageNF
->connect_value_changed(aLink
);
80 Link
<weld::MetricSpinButton
&,void> aSizeLink
= LINK(this, SwTextGridPage
, TextSizeChangedHdl
);
81 m_xTextSizeMF
->connect_value_changed(aSizeLink
);
82 m_xRubySizeMF
->connect_value_changed(aSizeLink
);
83 m_xCharWidthMF
->connect_value_changed(aSizeLink
);
85 Link
<weld::ToggleButton
&,void> aGridTypeHdl
= LINK(this, SwTextGridPage
, GridTypeHdl
);
86 m_xNoGridRB
->connect_toggled(aGridTypeHdl
);
87 m_xLinesGridRB
->connect_toggled(aGridTypeHdl
);
88 m_xCharsGridRB
->connect_toggled(aGridTypeHdl
);
90 m_xColorLB
->SetSelectHdl(LINK(this, SwTextGridPage
, ColorModifyHdl
));
91 m_xPrintCB
->connect_toggled(LINK(this, SwTextGridPage
, GridModifyClickHdl
));
92 m_xRubyBelowCB
->connect_toggled(LINK(this, SwTextGridPage
, GridModifyClickHdl
));
94 m_xDisplayCB
->connect_toggled(LINK(this, SwTextGridPage
, DisplayGridHdl
));
96 //Get the default paper mode
97 SwView
*pView
= ::GetActiveView();
100 SwWrtShell
* pSh
= pView
->GetWrtShellPtr();
103 m_bSquaredMode
= pSh
->GetDoc()->IsSquaredPageMode();
109 m_xRubySizeFT
->show();
110 m_xRubySizeMF
->show();
111 m_xRubyBelowCB
->show();
112 m_xSnapToCharsCB
->hide();
113 m_xCharWidthFT
->hide();
114 m_xCharWidthMF
->hide();
118 m_xRubySizeFT
->hide();
119 m_xRubySizeMF
->hide();
120 m_xRubyBelowCB
->hide();
121 m_xSnapToCharsCB
->show();
122 m_xCharWidthFT
->show();
123 m_xCharWidthMF
->show();
127 SwTextGridPage::~SwTextGridPage()
132 std::unique_ptr
<SfxTabPage
> SwTextGridPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
*rSet
)
134 return std::make_unique
<SwTextGridPage
>(pPage
, pController
, *rSet
);
137 bool SwTextGridPage::FillItemSet(SfxItemSet
*rSet
)
140 if (m_xNoGridRB
->get_state_changed_from_saved() ||
141 m_xLinesGridRB
->get_state_changed_from_saved() ||
142 m_xLinesPerPageNF
->get_value_changed_from_saved() ||
143 m_xTextSizeMF
->get_value_changed_from_saved() ||
144 m_xCharsPerLineNF
->get_value_changed_from_saved() ||
145 m_xSnapToCharsCB
->get_state_changed_from_saved() ||
146 m_xRubySizeMF
->get_value_changed_from_saved() ||
147 m_xCharWidthMF
->get_value_changed_from_saved() ||
148 m_xRubyBelowCB
->get_state_changed_from_saved() ||
149 m_xDisplayCB
->get_state_changed_from_saved() ||
150 m_xPrintCB
->get_state_changed_from_saved() ||
151 m_xColorLB
->IsValueChangedFromSaved())
157 // draw ticks of ruler
158 SwView
* pView
= ::GetActiveView();
159 if ( m_bHRulerChanged
)
160 pView
->GetHRuler().DrawTicks();
161 if ( m_bVRulerChanged
)
162 pView
->GetVRuler().DrawTicks();
166 void SwTextGridPage::Reset(const SfxItemSet
*rSet
)
168 sal_Int32 nLinesPerPage
= 0;
170 if(SfxItemState::DEFAULT
<= rSet
->GetItemState(RES_TEXTGRID
))
172 const SwTextGridItem
& rGridItem
= rSet
->Get(RES_TEXTGRID
);
173 weld::RadioButton
* pButton
= nullptr;
174 switch(rGridItem
.GetGridType())
176 case GRID_NONE
: pButton
= m_xNoGridRB
.get(); break;
177 case GRID_LINES_ONLY
: pButton
= m_xLinesGridRB
.get(); break;
178 default: pButton
= m_xCharsGridRB
.get();
180 pButton
->set_active(true);
181 m_xDisplayCB
->set_active(rGridItem
.IsDisplayGrid());
182 GridTypeHdl(*pButton
);
183 m_xSnapToCharsCB
->set_active(rGridItem
.IsSnapToChars());
184 nLinesPerPage
= rGridItem
.GetLines();
186 SetLinesOrCharsRanges(*m_xLinesRangeFT
, m_xLinesPerPageNF
->get_max());
187 m_nRubyUserValue
= rGridItem
.GetBaseHeight();
188 m_bRubyUserValue
= true;
189 m_xTextSizeMF
->set_value(m_xTextSizeMF
->normalize(m_nRubyUserValue
), FieldUnit::TWIP
);
190 m_xRubySizeMF
->set_value(m_xRubySizeMF
->normalize(rGridItem
.GetRubyHeight()), FieldUnit::TWIP
);
191 m_xCharWidthMF
->set_value(m_xCharWidthMF
->normalize(rGridItem
.GetBaseWidth()), FieldUnit::TWIP
);
192 m_xRubyBelowCB
->set_active(rGridItem
.IsRubyTextBelow());
193 m_xPrintCB
->set_active(rGridItem
.IsPrintGrid());
194 m_xColorLB
->SelectEntry(rGridItem
.GetColor());
196 UpdatePageSize(*rSet
);
198 if (nLinesPerPage
> 0)
199 m_xLinesPerPageNF
->set_value(nLinesPerPage
);
201 m_xNoGridRB
->save_state();
202 m_xLinesGridRB
->save_state();
203 m_xSnapToCharsCB
->save_state();
204 m_xLinesPerPageNF
->save_value();
205 m_xTextSizeMF
->save_value();
206 m_xCharsPerLineNF
->save_value();
207 m_xRubySizeMF
->save_value();
208 m_xCharWidthMF
->save_value();
209 m_xRubyBelowCB
->save_state();
210 m_xDisplayCB
->save_state();
211 m_xPrintCB
->save_state();
212 m_xColorLB
->SaveValue();
215 void SwTextGridPage::ActivatePage( const SfxItemSet
& rSet
)
218 m_aExampleWN
.UpdateExample(rSet
);
219 UpdatePageSize(rSet
);
221 m_aExampleWN
.Invalidate();
224 DeactivateRC
SwTextGridPage::DeactivatePage( SfxItemSet
* )
226 return DeactivateRC::LeavePage
;
229 void SwTextGridPage::PutGridItem(SfxItemSet
& rSet
)
231 SwTextGridItem aGridItem
;
232 aGridItem
.SetGridType(m_xNoGridRB
->get_active() ? GRID_NONE
:
233 m_xLinesGridRB
->get_active() ? GRID_LINES_ONLY
: GRID_LINES_CHARS
);
234 aGridItem
.SetSnapToChars(m_xSnapToCharsCB
->get_active());
235 aGridItem
.SetLines( static_cast< sal_uInt16
>(m_xLinesPerPageNF
->get_value()) );
236 aGridItem
.SetBaseHeight( static_cast< sal_uInt16
>(
237 m_bRubyUserValue
? m_nRubyUserValue
:
238 m_xTextSizeMF
->denormalize(m_xTextSizeMF
->get_value(FieldUnit::TWIP
))) );
239 aGridItem
.SetRubyHeight( static_cast< sal_uInt16
>(m_xRubySizeMF
->denormalize(m_xRubySizeMF
->get_value(FieldUnit::TWIP
))) );
240 aGridItem
.SetBaseWidth( static_cast< sal_uInt16
>(m_xCharWidthMF
->denormalize(m_xCharWidthMF
->get_value(FieldUnit::TWIP
))) );
241 aGridItem
.SetRubyTextBelow(m_xRubyBelowCB
->get_active());
242 aGridItem
.SetSquaredMode(m_bSquaredMode
);
243 aGridItem
.SetDisplayGrid(m_xDisplayCB
->get_active());
244 aGridItem
.SetPrintGrid(m_xPrintCB
->get_active());
245 aGridItem
.SetColor(m_xColorLB
->GetSelectEntryColor());
248 SwView
* pView
= ::GetActiveView();
249 if ( aGridItem
.GetGridType() != GRID_NONE
)
251 if ( aGridItem
.GetGridType() == GRID_LINES_CHARS
)
253 m_bHRulerChanged
= true;
255 m_bVRulerChanged
= true;
256 pView
->GetHRuler().SetCharWidth(static_cast<long>(m_xCharWidthMF
->get_value(FieldUnit::TWIP
)/56.7));
257 pView
->GetVRuler().SetLineHeight(static_cast<long>(m_xTextSizeMF
->get_value(FieldUnit::TWIP
)/56.7));
261 void SwTextGridPage::UpdatePageSize(const SfxItemSet
& rSet
)
263 if( SfxItemState::UNKNOWN
!= rSet
.GetItemState( RES_FRAMEDIR
))
265 const SvxFrameDirectionItem
& rDirItem
=
266 rSet
.Get(RES_FRAMEDIR
);
267 m_bVertical
= rDirItem
.GetValue() == SvxFrameDirection::Vertical_RL_TB
||
268 rDirItem
.GetValue() == SvxFrameDirection::Vertical_LR_TB
;
271 if( SfxItemState::SET
!= rSet
.GetItemState( SID_ATTR_PAGE_SIZE
))
274 const SvxSizeItem
& rSize
= rSet
.Get(SID_ATTR_PAGE_SIZE
);
275 const SvxLRSpaceItem
& rLRSpace
= rSet
.Get( RES_LR_SPACE
);
276 const SvxULSpaceItem
& rULSpace
= rSet
.Get( RES_UL_SPACE
);
277 const SvxBoxItem
& rBox
= rSet
.Get(RES_BOX
);
278 sal_Int32 nDistanceLR
= rLRSpace
.GetLeft() + rLRSpace
.GetRight();
279 sal_Int32 nDistanceUL
= rULSpace
.GetUpper() + rULSpace
.GetLower();
281 sal_Int32 nValue1
= rSize
.GetSize().Height() - nDistanceUL
-
282 rBox
.GetDistance(SvxBoxItemLine::TOP
) -
283 rBox
.GetDistance(SvxBoxItemLine::BOTTOM
);
284 sal_Int32 nValue2
= rSize
.GetSize().Width() - nDistanceLR
-
285 rBox
.GetDistance(SvxBoxItemLine::LEFT
) -
286 rBox
.GetDistance(SvxBoxItemLine::RIGHT
);
289 m_aPageSize
.setWidth( nValue1
);
290 m_aPageSize
.setHeight( nValue2
);
294 m_aPageSize
.setWidth( nValue2
);
295 m_aPageSize
.setHeight( nValue1
);
298 sal_Int32 nTextSize
= static_cast< sal_Int32
>(m_bRubyUserValue
?
300 m_xTextSizeMF
->denormalize(m_xTextSizeMF
->get_value(FieldUnit::TWIP
)));
302 if ( m_bSquaredMode
)
304 sal_Int32 nCharsPerLine
= m_aPageSize
.Width() / nTextSize
;
305 m_xCharsPerLineNF
->set_max(nCharsPerLine
);
306 m_xCharsPerLineNF
->set_value(nCharsPerLine
);
307 m_xLinesPerPageNF
->set_max(m_aPageSize
.Height() /
308 ( m_xTextSizeMF
->denormalize(m_xTextSizeMF
->get_value(FieldUnit::TWIP
)) +
309 m_xRubySizeMF
->denormalize(m_xRubySizeMF
->get_value(FieldUnit::TWIP
))));
310 SetLinesOrCharsRanges( *m_xCharsRangeFT
, m_xCharsPerLineNF
->get_max() );
311 SetLinesOrCharsRanges( *m_xLinesRangeFT
, m_xLinesPerPageNF
->get_max() );
315 sal_Int32 nTextWidth
= static_cast< sal_Int32
>(m_xCharWidthMF
->denormalize(m_xCharWidthMF
->get_value(FieldUnit::TWIP
)));
316 m_xLinesPerPageNF
->set_value(m_aPageSize
.Height() / nTextSize
);
318 m_xCharsPerLineNF
->set_value(m_aPageSize
.Width() / nTextWidth
);
320 m_xCharsPerLineNF
->set_value(45);
321 SetLinesOrCharsRanges( *m_xCharsRangeFT
, m_xCharsPerLineNF
->get_max() );
322 SetLinesOrCharsRanges( *m_xLinesRangeFT
, m_xLinesPerPageNF
->get_max() );
326 void SwTextGridPage::SetLinesOrCharsRanges(weld::Label
& rField
, const sal_Int32 nValue
)
328 OUString aFieldStr
= "( 1 -" + OUString::number(nValue
) + " )";
329 rField
.set_label(aFieldStr
);
332 const sal_uInt16
* SwTextGridPage::GetRanges()
334 static const sal_uInt16 aPageRg
[] = {
335 RES_TEXTGRID
, RES_TEXTGRID
,
340 IMPL_LINK(SwTextGridPage
, CharorLineChangedHdl
, weld::SpinButton
&, rField
, void)
343 if ( m_bSquaredMode
)
345 if (m_xCharsPerLineNF
.get() == &rField
)
347 auto nValue
= m_xCharsPerLineNF
->get_value();
348 assert(nValue
&& "div-by-zero");
349 auto nWidth
= m_aPageSize
.Width() / nValue
;
350 m_xTextSizeMF
->set_value(m_xTextSizeMF
->normalize(nWidth
), FieldUnit::TWIP
);
351 //prevent rounding errors in the MetricField by saving the used value
352 m_nRubyUserValue
= nWidth
;
353 m_bRubyUserValue
= true;
356 //set maximum line per page
358 sal_Int32 nMaxLines
= static_cast< sal_Int32
>(m_aPageSize
.Height() /
359 ( m_xTextSizeMF
->denormalize(m_xTextSizeMF
->get_value(FieldUnit::TWIP
)) +
360 m_xRubySizeMF
->denormalize(m_xRubySizeMF
->get_value(FieldUnit::TWIP
))));
361 m_xLinesPerPageNF
->set_max(nMaxLines
);
363 SetLinesOrCharsRanges( *m_xLinesRangeFT
, m_xLinesPerPageNF
->get_max() );
364 SetLinesOrCharsRanges( *m_xCharsRangeFT
, m_xCharsPerLineNF
->get_max() );
368 if (m_xLinesPerPageNF
.get() == &rField
)
370 auto nValue
= m_xLinesPerPageNF
->get_value();
371 assert(nValue
&& "div-by-zero");
372 auto nHeight
= m_aPageSize
.Height() / nValue
;
373 m_xTextSizeMF
->set_value(m_xTextSizeMF
->normalize(nHeight
), FieldUnit::TWIP
);
374 m_xRubySizeMF
->set_value(0, FieldUnit::TWIP
);
375 SetLinesOrCharsRanges( *m_xLinesRangeFT
, m_xLinesPerPageNF
->get_max() );
377 m_nRubyUserValue
= nHeight
;
378 m_bRubyUserValue
= true;
380 else if (m_xCharsPerLineNF
.get() == &rField
)
382 auto nValue
= m_xCharsPerLineNF
->get_value();
383 assert(nValue
&& "div-by-zero");
384 auto nWidth
= m_aPageSize
.Width() / nValue
;
385 m_xCharWidthMF
->set_value(m_xCharWidthMF
->normalize(nWidth
), FieldUnit::TWIP
);
386 SetLinesOrCharsRanges( *m_xCharsRangeFT
, m_xCharsPerLineNF
->get_max() );
392 IMPL_LINK(SwTextGridPage
, TextSizeChangedHdl
, weld::MetricSpinButton
&, rField
, void)
397 if (m_xTextSizeMF
.get() == &rField
)
399 m_bRubyUserValue
= false;
401 // fdo#50941: set maximum characters per line
402 sal_Int32 nTextSize
= static_cast< sal_Int32
>(m_xTextSizeMF
->denormalize(m_xTextSizeMF
->get_value(FieldUnit::TWIP
)));
405 sal_Int32 nMaxChars
= m_aPageSize
.Width() / nTextSize
;
406 m_xCharsPerLineNF
->set_value(nMaxChars
);
407 m_xCharsPerLineNF
->set_max(nMaxChars
);
408 SetLinesOrCharsRanges( *m_xCharsRangeFT
, m_xCharsPerLineNF
->get_max() );
411 //set maximum line per page
413 sal_Int32 nMaxLines
= static_cast< sal_Int32
>(m_aPageSize
.Height() /
414 ( m_xTextSizeMF
->denormalize(m_xTextSizeMF
->get_value(FieldUnit::TWIP
)) +
415 m_xRubySizeMF
->denormalize(m_xRubySizeMF
->get_value(FieldUnit::TWIP
))));
416 m_xLinesPerPageNF
->set_max(nMaxLines
);
417 SetLinesOrCharsRanges( *m_xLinesRangeFT
, m_xLinesPerPageNF
->get_max() );
422 if (m_xTextSizeMF
.get() == &rField
)
424 sal_Int32 nTextSize
= static_cast< sal_Int32
>(m_xTextSizeMF
->denormalize(m_xTextSizeMF
->get_value(FieldUnit::TWIP
)));
425 m_xLinesPerPageNF
->set_value(m_aPageSize
.Height() / nTextSize
);
426 m_bRubyUserValue
= false;
427 SetLinesOrCharsRanges( *m_xLinesRangeFT
, m_xLinesPerPageNF
->get_max() );
429 else if (m_xCharWidthMF
.get() == &rField
)
431 sal_Int32 nTextWidth
= static_cast< sal_Int32
>(m_xCharWidthMF
->denormalize(m_xCharWidthMF
->get_value(FieldUnit::TWIP
)));
432 sal_Int32 nMaxChar
= 45 ;
434 nMaxChar
= m_aPageSize
.Width() / nTextWidth
;
435 m_xCharsPerLineNF
->set_value( nMaxChar
);
436 SetLinesOrCharsRanges( *m_xCharsRangeFT
, m_xCharsPerLineNF
->get_max() );
438 //rubySize is disabled
443 IMPL_LINK(SwTextGridPage
, GridTypeHdl
, weld::ToggleButton
&, rButton
, void)
445 bool bEnable
= m_xNoGridRB
.get() != &rButton
;
446 m_xLayoutFL
->set_sensitive(bEnable
);
447 m_xDisplayFL
->set_sensitive(bEnable
);
451 DisplayGridHdl(*m_xDisplayCB
);
453 bEnable
= m_xCharsGridRB
.get() == &rButton
;
454 m_xSnapToCharsCB
->set_sensitive(bEnable
);
456 bEnable
= m_xLinesGridRB
.get() == &rButton
;
457 if (bEnable
&& !m_bSquaredMode
)
459 m_xCharsPerLineFT
->set_sensitive(false);
460 m_xCharsPerLineNF
->set_sensitive(false);
461 m_xCharsRangeFT
->set_sensitive(false);
462 m_xCharWidthFT
->set_sensitive(false);
463 m_xCharWidthMF
->set_sensitive(false);
469 IMPL_LINK_NOARG(SwTextGridPage
, DisplayGridHdl
, weld::ToggleButton
&, void)
471 bool bChecked
= m_xDisplayCB
->get_active();
472 m_xPrintCB
->set_sensitive(bChecked
);
473 m_xPrintCB
->set_active(bChecked
);
476 IMPL_LINK_NOARG(SwTextGridPage
, GridModifyClickHdl
, weld::ToggleButton
&, void)
481 IMPL_LINK_NOARG(SwTextGridPage
, ColorModifyHdl
, ColorListBox
&, void)
486 void SwTextGridPage::GridModifyHdl()
488 const SfxItemSet
& rOldSet
= GetItemSet();
489 SfxItemSet
aSet(rOldSet
);
490 const SfxItemSet
* pExSet
= GetDialogExampleSet();
494 m_aExampleWN
.UpdateExample(aSet
);
497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */