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 <vcl/svapp.hxx>
21 #include <vcl/idle.hxx>
22 #include <svtools/ctrltool.hxx>
23 #include <sfx2/objsh.hxx>
24 #include <svx/svxids.hrc>
25 #include <svtools/unitconv.hxx>
26 #include <svl/cjkoptions.hxx>
27 #include <svl/ctloptions.hxx>
28 #include <chardlg.hxx>
29 #include <editeng/fontitem.hxx>
30 #include <editeng/postitem.hxx>
31 #include <editeng/udlnitem.hxx>
32 #include <editeng/crossedoutitem.hxx>
33 #include <editeng/contouritem.hxx>
34 #include <editeng/langitem.hxx>
35 #include <editeng/wghtitem.hxx>
36 #include <editeng/fhgtitem.hxx>
37 #include <editeng/shdditem.hxx>
38 #include <editeng/escapementitem.hxx>
39 #include <editeng/wrlmitem.hxx>
40 #include <editeng/cmapitem.hxx>
41 #include <editeng/kernitem.hxx>
42 #include <editeng/flstitem.hxx>
43 #include <editeng/autokernitem.hxx>
44 #include <editeng/colritem.hxx>
45 #include <dialmgr.hxx>
46 #include <sfx2/htmlmode.hxx>
47 #include <cui/cuicharmap.hxx>
49 #include <editeng/emphasismarkitem.hxx>
50 #include <editeng/charreliefitem.hxx>
51 #include <editeng/twolinesitem.hxx>
52 #include <editeng/charhiddenitem.hxx>
53 #include <editeng/charscaleitem.hxx>
54 #include <editeng/charrotateitem.hxx>
55 #include <officecfg/Office/Common.hxx>
56 #include <strings.hrc>
57 #include <twolines.hrc>
58 #include <svl/intitem.hxx>
59 #include <svx/flagsdef.hxx>
60 #include <FontFeatures.hxx>
61 #include <FontFeaturesDialog.hxx>
62 #include <sal/log.hxx>
63 #include <osl/diagnose.h>
64 #include <o3tl/unit_conversion.hxx>
65 #include <o3tl/string_view.hxx>
67 using namespace ::com::sun::star
;
69 // static ----------------------------------------------------------------
71 const WhichRangesContainer
SvxCharNamePage::pNameRanges(svl::Items
<
72 SID_ATTR_CHAR_FONT
, SID_ATTR_CHAR_WEIGHT
,
73 SID_ATTR_CHAR_FONTHEIGHT
, SID_ATTR_CHAR_FONTHEIGHT
,
74 SID_ATTR_CHAR_COLOR
, SID_ATTR_CHAR_COLOR
,
75 SID_ATTR_CHAR_LANGUAGE
, SID_ATTR_CHAR_LANGUAGE
,
76 SID_ATTR_CHAR_CJK_FONT
, SID_ATTR_CHAR_CJK_WEIGHT
,
77 SID_ATTR_CHAR_CTL_FONT
, SID_ATTR_CHAR_CTL_WEIGHT
80 const WhichRangesContainer
SvxCharEffectsPage::pEffectsRanges(svl::Items
<
81 SID_ATTR_CHAR_SHADOWED
, SID_ATTR_CHAR_UNDERLINE
,
82 SID_ATTR_CHAR_COLOR
, SID_ATTR_CHAR_COLOR
,
83 SID_ATTR_CHAR_CASEMAP
, SID_ATTR_CHAR_CASEMAP
,
84 SID_ATTR_FLASH
, SID_ATTR_FLASH
,
85 SID_ATTR_CHAR_EMPHASISMARK
, SID_ATTR_CHAR_EMPHASISMARK
,
86 SID_ATTR_CHAR_RELIEF
, SID_ATTR_CHAR_RELIEF
,
87 SID_ATTR_CHAR_HIDDEN
, SID_ATTR_CHAR_HIDDEN
,
88 SID_ATTR_CHAR_OVERLINE
, SID_ATTR_CHAR_OVERLINE
91 const WhichRangesContainer
SvxCharPositionPage::pPositionRanges(svl::Items
<
92 SID_ATTR_CHAR_KERNING
, SID_ATTR_CHAR_KERNING
,
93 SID_ATTR_CHAR_ESCAPEMENT
, SID_ATTR_CHAR_ESCAPEMENT
,
94 SID_ATTR_CHAR_AUTOKERN
, SID_ATTR_CHAR_AUTOKERN
,
95 SID_ATTR_CHAR_ROTATED
, SID_ATTR_CHAR_SCALEWIDTH
,
96 SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
, SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
99 const WhichRangesContainer
SvxCharTwoLinesPage::pTwoLinesRanges(svl::Items
<
100 SID_ATTR_CHAR_TWO_LINES
, SID_ATTR_CHAR_TWO_LINES
103 // C-Function ------------------------------------------------------------
105 static bool StateToAttr( TriState aState
)
107 return ( TRISTATE_TRUE
== aState
);
112 void setPrevFontEscapement(SvxFont
& _rFont
,sal_uInt8 nProp
, sal_uInt8 nEscProp
, short nEsc
)
114 _rFont
.SetPropr( nProp
);
115 _rFont
.SetProprRel( nEscProp
);
116 _rFont
.SetEscapement( nEsc
);
120 inline SvxFont
& SvxCharBasePage::GetPreviewFont()
122 return m_aPreviewWin
.GetFont();
125 inline SvxFont
& SvxCharBasePage::GetPreviewCJKFont()
127 return m_aPreviewWin
.GetCJKFont();
130 inline SvxFont
& SvxCharBasePage::GetPreviewCTLFont()
132 return m_aPreviewWin
.GetCTLFont();
135 SvxCharBasePage::SvxCharBasePage(weld::Container
* pPage
, weld::DialogController
* pController
, const OUString
& rUIXMLDescription
, const OUString
& rID
, const SfxItemSet
& rItemset
)
136 : SfxTabPage(pPage
, pController
, rUIXMLDescription
, rID
, &rItemset
)
137 , m_bPreviewBackgroundToCharacter( false )
141 SvxCharBasePage::~SvxCharBasePage()
145 void SvxCharBasePage::ActivatePage(const SfxItemSet
& rSet
)
147 m_aPreviewWin
.SetFromItemSet(rSet
, m_bPreviewBackgroundToCharacter
);
150 void SvxCharBasePage::SetPrevFontWidthScale( const SfxItemSet
& rSet
)
152 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_SCALEWIDTH
);
153 if (rSet
.GetItemState(nWhich
)>=SfxItemState::DEFAULT
)
155 const SvxCharScaleWidthItem
&rItem
= static_cast<const SvxCharScaleWidthItem
&>( rSet
.Get( nWhich
) );
156 m_aPreviewWin
.SetFontWidthScale(rItem
.GetValue());
160 void SvxCharBasePage::SetPrevFontEscapement( sal_uInt8 nProp
, sal_uInt8 nEscProp
, short nEsc
)
162 setPrevFontEscapement(GetPreviewFont(),nProp
,nEscProp
,nEsc
);
163 setPrevFontEscapement(GetPreviewCJKFont(),nProp
,nEscProp
,nEsc
);
164 setPrevFontEscapement(GetPreviewCTLFont(),nProp
,nEscProp
,nEsc
);
165 m_aPreviewWin
.Invalidate();
169 // SvxCharNamePage_Impl --------------------------------------------------
171 struct SvxCharNamePage_Impl
173 Idle m_aUpdateIdle
{ "cui SvxCharNamePage_Impl m_aUpdateIdle" };
174 OUString m_aNoStyleText
;
175 std::unique_ptr
<FontList
> m_pFontList
;
176 int m_nExtraEntryPos
;
177 bool m_bInSearchMode
;
179 SvxCharNamePage_Impl()
180 : m_nExtraEntryPos(std::numeric_limits
<int>::max())
181 , m_bInSearchMode(false)
184 m_aUpdateIdle
.SetPriority( TaskPriority::LOWEST
);
188 // class SvxCharNamePage -------------------------------------------------
190 SvxCharNamePage::SvxCharNamePage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rInSet
)
191 : SvxCharBasePage(pPage
, pController
, "cui/ui/charnamepage.ui", "CharNamePage", rInSet
)
192 , m_pImpl(new SvxCharNamePage_Impl
)
194 , m_xWestern(m_xBuilder
->weld_notebook("nbWestern"))
195 , m_xWestFontNameFT(m_xBuilder
->weld_label("lbWestFontname"))
196 , m_xWestFontStyleFT(m_xBuilder
->weld_label("lbWestStyle"))
197 , m_xWestFontStyleLB(new FontStyleBox(m_xBuilder
->weld_combo_box("cbWestStyle")))
198 , m_xWestFontSizeFT(m_xBuilder
->weld_label("lbWestSize"))
199 , m_xWestFontSizeLB(new FontSizeBox(m_xBuilder
->weld_combo_box("cbWestSize")))
200 , m_xWestFontLanguageFT(m_xBuilder
->weld_label("lbWestLanguage"))
201 , m_xWestFontLanguageLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box("cbWestLanguage")))
202 , m_xWestFontFeaturesButton(m_xBuilder
->weld_button("btnWestFeatures"))
203 , m_xWestFontTypeFT(m_xBuilder
->weld_label("lbWestFontinfo"))
204 , m_xCJK_CTL(m_xBuilder
->weld_notebook("nbCJKCTL"))
206 , m_xEastFontNameFT(m_xBuilder
->weld_label("lbCJKFontname"))
207 , m_xEastFontStyleFT(m_xBuilder
->weld_label("lbCJKStyle"))
208 , m_xEastFontStyleLB(new FontStyleBox(m_xBuilder
->weld_combo_box("cbCJKStyle")))
209 , m_xEastFontSizeFT(m_xBuilder
->weld_label("lbCJKSize"))
210 , m_xEastFontSizeLB(new FontSizeBox(m_xBuilder
->weld_combo_box("cbCJKSize")))
211 , m_xEastFontLanguageFT(m_xBuilder
->weld_label("lbCJKLanguage"))
212 , m_xEastFontLanguageLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box("cbCJKLanguage")))
213 , m_xEastFontFeaturesButton(m_xBuilder
->weld_button("btnCJKFeatures"))
214 , m_xEastFontTypeFT(m_xBuilder
->weld_label("lbCJKFontinfo"))
216 , m_xCTLFontNameFT(m_xBuilder
->weld_label("lbCTLFontname"))
218 , m_xCTLFontStyleFT(m_xBuilder
->weld_label("lbCTLStyle"))
219 , m_xCTLFontStyleLB(new FontStyleBox(m_xBuilder
->weld_combo_box("cbCTLStyle")))
220 , m_xCTLFontSizeFT(m_xBuilder
->weld_label("lbCTLSize"))
221 , m_xCTLFontSizeLB(new FontSizeBox(m_xBuilder
->weld_combo_box("cbCTLSize")))
222 , m_xCTLFontLanguageFT(m_xBuilder
->weld_label("lbCTLLanguage"))
223 , m_xCTLFontLanguageLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box("cbCTLLanguage")))
224 , m_xCTLFontFeaturesButton(m_xBuilder
->weld_button("btnCTLFeatures"))
225 , m_xCTLFontTypeFT(m_xBuilder
->weld_label("lbCTLFontinfo"))
227 , m_xVDev(*Application::GetDefaultDevice(), DeviceFormat::WITH_ALPHA
)
229 m_xPreviewWin
.reset(new weld::CustomWeld(*m_xBuilder
, "preview", m_aPreviewWin
));
231 m_xPreviewWin
->hide();
233 m_pImpl
->m_aNoStyleText
= CuiResId( RID_CUISTR_CHARNAME_NOSTYLE
);
235 std::unique_ptr
<weld::EntryTreeView
> xWestFontName
= m_xBuilder
->weld_entry_tree_view("gdWestern", "edWestFontName", "trWestFontName");
236 std::unique_ptr
<weld::EntryTreeView
> xCJKFontName
= m_xBuilder
->weld_entry_tree_view("gdCJK", "edCJKFontName", "trCJKFontName");
237 std::unique_ptr
<weld::EntryTreeView
> xCTLFontName
= m_xBuilder
->weld_entry_tree_view("gdCTL", "edCTLFontName", "trCTLFontName");
239 // 7 lines in the treeview
240 xWestFontName
->set_height_request_by_rows(7);
241 xCJKFontName
->set_height_request_by_rows(7);
242 xCTLFontName
->set_height_request_by_rows(7);
244 m_xWestFontNameLB
= std::move(xWestFontName
);
245 m_xEastFontNameLB
= std::move(xCJKFontName
);
246 m_xCTLFontNameLB
= std::move(xCTLFontName
);
248 bool bShowCJK
= SvtCJKOptions::IsCJKFontEnabled();
249 bool bShowCTL
= SvtCTLOptions::IsCTLFontEnabled();
250 bool bShowNonWestern
= bShowCJK
|| bShowCTL
;
251 if (!bShowNonWestern
)
254 m_xWestern
->set_show_tabs(false); //hide single tab in case of Western only
256 else if (!bShowCJK
) m_xCJK_CTL
->remove_page("nbCJK");
257 else if (!bShowCTL
) m_xCJK_CTL
->remove_page("nbCTL");
260 //In MacOSX the standard dialogs name font-name, font-style as
262 //In GNOME the standard dialogs name font-name, font-style as
264 //In Windows the standard dialogs name font-name, font-style as
267 OUString
sFontFamilyString(CuiResId(RID_CUISTR_CHARNAME_FONT
));
269 OUString
sFontFamilyString(CuiResId(RID_CUISTR_CHARNAME_FAMILY
));
271 m_xWestFontNameFT
->set_label(sFontFamilyString
);
272 m_xCTLFontNameFT
->set_label(sFontFamilyString
);
273 m_xEastFontNameFT
->set_label(sFontFamilyString
);
276 OUString
sFontStyleString(CuiResId(RID_CUISTR_CHARNAME_TYPEFACE
));
278 OUString
sFontStyleString(CuiResId(RID_CUISTR_CHARNAME_STYLE
));
280 m_xWestFontStyleFT
->set_label(sFontStyleString
);
281 m_xEastFontStyleFT
->set_label(sFontStyleString
);
282 m_xCTLFontStyleFT
->set_label(sFontStyleString
);
284 m_xWestFontLanguageLB
->SetLanguageList(SvxLanguageListFlags::WESTERN
, true, false, true, true,
285 LANGUAGE_SYSTEM
, css::i18n::ScriptType::LATIN
);
286 m_xEastFontLanguageLB
->SetLanguageList(SvxLanguageListFlags::CJK
, true, false, true, true,
287 LANGUAGE_SYSTEM
, css::i18n::ScriptType::ASIAN
);
288 m_xCTLFontLanguageLB
->SetLanguageList(SvxLanguageListFlags::CTL
, true, false, true, true,
289 LANGUAGE_SYSTEM
, css::i18n::ScriptType::COMPLEX
);
290 int nVisibleChars
= 15;
291 // read-only combobox / HasEntry asserts on set_width_char()
292 m_xWestFontLanguageLB
->set_width_chars(nVisibleChars
);
293 m_xEastFontLanguageLB
->set_width_chars(nVisibleChars
);
294 m_xCTLFontLanguageLB
->set_width_chars(nVisibleChars
);
299 SvxCharNamePage::~SvxCharNamePage()
302 m_xCTLFontStyleLB
.reset();
303 m_xEastFontLanguageLB
.reset();
304 m_xWestFontStyleLB
.reset();
305 m_xCTLFontSizeLB
.reset();
306 m_xEastFontSizeLB
.reset();
307 m_xWestFontSizeLB
.reset();
308 m_xWestFontLanguageLB
.reset();
309 m_xPreviewWin
.reset();
310 m_xCTLFontLanguageLB
.reset();
311 m_xEastFontLanguageLB
.reset();
314 void SvxCharNamePage::Initialize()
316 // to handle the changes of the other pages
317 SetExchangeSupport();
319 Link
<weld::ComboBox
&,void> aLink
= LINK(this, SvxCharNamePage
, FontModifyComboBoxHdl_Impl
);
320 m_xWestFontNameLB
->connect_changed(aLink
);
321 m_xWestFontStyleLB
->connect_changed(aLink
);
322 m_xWestFontSizeLB
->connect_changed(aLink
);
323 m_xWestFontLanguageLB
->connect_changed(aLink
);
325 m_xWestFontFeaturesButton
->connect_clicked(LINK(this, SvxCharNamePage
, FontFeatureButtonClicked
));
327 m_xEastFontNameLB
->connect_changed(aLink
);
328 m_xEastFontStyleLB
->connect_changed(aLink
);
329 m_xEastFontSizeLB
->connect_changed(aLink
);
330 m_xEastFontLanguageLB
->connect_changed(aLink
);
331 m_xEastFontFeaturesButton
->connect_clicked(LINK(this, SvxCharNamePage
, FontFeatureButtonClicked
));
333 m_xCTLFontNameLB
->connect_changed(aLink
);
334 m_xCTLFontStyleLB
->connect_changed(aLink
);
335 m_xCTLFontSizeLB
->connect_changed(aLink
);
336 m_xCTLFontLanguageLB
->connect_changed(aLink
);
337 m_xCTLFontFeaturesButton
->connect_clicked(LINK(this, SvxCharNamePage
, FontFeatureButtonClicked
));
339 m_pImpl
->m_aUpdateIdle
.SetInvokeHandler( LINK( this, SvxCharNamePage
, UpdateHdl_Impl
) );
342 const FontList
* SvxCharNamePage::GetFontList() const
344 if ( !m_pImpl
->m_pFontList
)
346 /* #110771# SvxFontListItem::GetFontList can return NULL */
347 if (SfxObjectShell
* pDocSh
= SfxObjectShell::Current())
349 const SfxPoolItem
* pItem
= pDocSh
->GetItem( SID_ATTR_CHAR_FONTLIST
);
350 if ( pItem
!= nullptr )
352 DBG_ASSERT(nullptr != static_cast<const SvxFontListItem
*>(pItem
)->GetFontList(),
353 "Where is the font list?");
354 m_pImpl
->m_pFontList
= static_cast<const SvxFontListItem
*>(pItem
)->GetFontList()->Clone();
357 if(!m_pImpl
->m_pFontList
)
359 m_pImpl
->m_pFontList
.reset(new FontList( Application::GetDefaultDevice() ));
363 return m_pImpl
->m_pFontList
.get();
369 FontMetric
calcFontMetrics( SvxFont
& _rFont
,
370 SvxCharNamePage
const * _pPage
,
371 const weld::ComboBox
* _pFontNameLB
,
372 const FontStyleBox
* _pFontStyleLB
,
373 const FontSizeBox
* _pFontSizeLB
,
374 const SvxLanguageBox
* _pLanguageLB
,
375 const FontList
* _pFontList
,
376 sal_uInt16 _nFontWhich
,
377 sal_uInt16 _nFontHeightWhich
)
379 Size aSize
= _rFont
.GetFontSize();
381 FontMetric aFontMetrics
;
382 OUString
sFontName(_pFontNameLB
->get_active_text());
383 bool bFontAvailable
= _pFontList
->IsAvailable( sFontName
);
384 if (bFontAvailable
|| _pFontNameLB
->get_value_changed_from_saved())
385 aFontMetrics
= _pFontList
->Get(sFontName
, _pFontStyleLB
->get_active_text());
388 //get the font from itemset
389 SfxItemState eState
= _pPage
->GetItemSet().GetItemState( _nFontWhich
);
390 if ( eState
>= SfxItemState::DEFAULT
)
392 const SvxFontItem
* pFontItem
= static_cast<const SvxFontItem
*>(&( _pPage
->GetItemSet().Get( _nFontWhich
) ));
393 aFontMetrics
.SetFamilyName(pFontItem
->GetFamilyName());
394 aFontMetrics
.SetStyleName(pFontItem
->GetStyleName());
395 aFontMetrics
.SetFamily(pFontItem
->GetFamily());
396 aFontMetrics
.SetPitch(pFontItem
->GetPitch());
397 aFontMetrics
.SetCharSet(pFontItem
->GetCharSet());
400 if ( _pFontSizeLB
->IsRelative() )
402 DBG_ASSERT( _pPage
->GetItemSet().GetParent(), "No parent set" );
403 const SvxFontHeightItem
& rOldItem
= static_cast<const SvxFontHeightItem
&>(_pPage
->GetItemSet().GetParent()->Get( _nFontHeightWhich
));
407 if ( _pFontSizeLB
->IsPtRelative() )
408 nHeight
= rOldItem
.GetHeight()
409 + o3tl::convert(_pFontSizeLB
->get_value(), o3tl::Length::pt
,
410 o3tl::Length::twip
) / 10;
412 nHeight
= static_cast<tools::Long
>(rOldItem
.GetHeight() * _pFontSizeLB
->get_value() / 100);
414 // conversion twips for the example-window
416 ItemToControl( nHeight
, _pPage
->GetItemSet().GetPool()->GetMetric( _nFontHeightWhich
), FieldUnit::TWIP
) );
418 else if ( !_pFontSizeLB
->get_active_text().isEmpty() )
419 aSize
.setHeight(o3tl::convert(_pFontSizeLB
->get_value(), o3tl::Length::pt
,
420 o3tl::Length::twip
) / 10);
422 aSize
.setHeight( 200 ); // default 10pt
423 aFontMetrics
.SetFontSize( aSize
);
425 _rFont
.SetLanguage(_pLanguageLB
->get_active_id());
427 _rFont
.SetFamily( aFontMetrics
.GetFamilyType() );
428 _rFont
.SetFamilyName( aFontMetrics
.GetFamilyName() );
429 _rFont
.SetStyleName( aFontMetrics
.GetStyleName() );
430 _rFont
.SetPitch( aFontMetrics
.GetPitch() );
431 _rFont
.SetCharSet( aFontMetrics
.GetCharSet() );
432 _rFont
.SetWeight( aFontMetrics
.GetWeight() );
433 _rFont
.SetItalic( aFontMetrics
.GetItalic() );
434 _rFont
.SetFontSize( aFontMetrics
.GetFontSize() );
441 void SvxCharNamePage::UpdatePreview_Impl()
443 SvxFont
& rFont
= GetPreviewFont();
444 SvxFont
& rCJKFont
= GetPreviewCJKFont();
445 SvxFont
& rCTLFont
= GetPreviewCTLFont();
447 const FontList
* pFontList
= GetFontList();
449 FontMetric aWestFontMetric
= calcFontMetrics(rFont
, this, m_xWestFontNameLB
.get(),
450 m_xWestFontStyleLB
.get(), m_xWestFontSizeLB
.get(), m_xWestFontLanguageLB
.get(),
451 pFontList
, GetWhich(SID_ATTR_CHAR_FONT
),
452 GetWhich(SID_ATTR_CHAR_FONTHEIGHT
));
454 m_xWestFontTypeFT
->set_label(pFontList
->GetFontMapText(aWestFontMetric
));
456 FontMetric aEastFontMetric
= calcFontMetrics(rCJKFont
, this, m_xEastFontNameLB
.get(),
457 m_xEastFontStyleLB
.get(), m_xEastFontSizeLB
.get(), m_xEastFontLanguageLB
.get(),
458 pFontList
, GetWhich(SID_ATTR_CHAR_CJK_FONT
),
459 GetWhich(SID_ATTR_CHAR_CJK_FONTHEIGHT
));
461 m_xEastFontTypeFT
->set_label(pFontList
->GetFontMapText(aEastFontMetric
));
463 FontMetric aCTLFontMetric
= calcFontMetrics(rCTLFont
,
464 this, m_xCTLFontNameLB
.get(), m_xCTLFontStyleLB
.get(), m_xCTLFontSizeLB
.get(),
465 m_xCTLFontLanguageLB
.get(), pFontList
, GetWhich(SID_ATTR_CHAR_CTL_FONT
),
466 GetWhich(SID_ATTR_CHAR_CTL_FONTHEIGHT
));
468 m_xCTLFontTypeFT
->set_label(pFontList
->GetFontMapText(aCTLFontMetric
));
470 m_aPreviewWin
.Invalidate();
472 void SvxCharNamePage::EnableFeatureButton(const weld::Widget
& rNameBox
)
475 weld::Button
* pButton
= nullptr;
476 if (m_xWestFontNameLB
.get() == &rNameBox
)
478 sFontName
= m_xWestFontNameLB
->get_active_text();
479 pButton
= m_xWestFontFeaturesButton
.get();
481 else if (m_xEastFontNameLB
.get() == &rNameBox
)
483 sFontName
= m_xEastFontNameLB
->get_active_text();
484 pButton
=m_xEastFontFeaturesButton
.get();
486 else if (m_xCTLFontNameLB
.get() == &rNameBox
)
488 sFontName
= m_xCTLFontNameLB
->get_active_text();
489 pButton
= m_xCTLFontFeaturesButton
.get();
493 SAL_WARN( "cui.tabpages", "invalid font name box" );
497 bool bEnable
= !getFontFeatureList(sFontName
, *m_xVDev
).empty();
499 pButton
->set_sensitive(bEnable
);
502 void SvxCharNamePage::FillStyleBox_Impl(const weld::Widget
& rNameBox
)
504 const FontList
* pFontList
= GetFontList();
505 DBG_ASSERT( pFontList
, "no fontlist" );
507 FontStyleBox
* pStyleBox
= nullptr;
510 if (m_xWestFontNameLB
.get() == &rNameBox
)
512 pStyleBox
= m_xWestFontStyleLB
.get();
513 sFontName
= m_xWestFontNameLB
->get_active_text();
515 else if (m_xEastFontNameLB
.get() == &rNameBox
)
517 pStyleBox
= m_xEastFontStyleLB
.get();
518 sFontName
= m_xEastFontStyleLB
->get_active_text();
520 else if (m_xCTLFontNameLB
.get() == &rNameBox
)
522 pStyleBox
= m_xCTLFontStyleLB
.get();
523 sFontName
= m_xCTLFontNameLB
->get_active_text();
527 SAL_WARN( "cui.tabpages", "invalid font name box" );
531 pStyleBox
->Fill(sFontName
, pFontList
);
533 if ( !m_pImpl
->m_bInSearchMode
)
536 // additional entries for the search:
537 // "not bold" and "not italic"
538 OUString aEntry
= m_pImpl
->m_aNoStyleText
;
539 const char sS
[] = "%1";
540 aEntry
= aEntry
.replaceFirst( sS
, pFontList
->GetBoldStr() );
541 m_pImpl
->m_nExtraEntryPos
= pStyleBox
->get_count();
542 pStyleBox
->append_text( aEntry
);
543 aEntry
= m_pImpl
->m_aNoStyleText
;
544 aEntry
= aEntry
.replaceFirst( sS
, pFontList
->GetItalicStr() );
545 pStyleBox
->append_text(aEntry
);
548 void SvxCharNamePage::FillSizeBox_Impl(const weld::Widget
& rNameBox
)
550 const FontList
* pFontList
= GetFontList();
551 DBG_ASSERT( pFontList
, "no fontlist" );
553 FontSizeBox
* pSizeBox
= nullptr;
555 if (m_xWestFontNameLB
.get() == &rNameBox
)
557 pSizeBox
= m_xWestFontSizeLB
.get();
559 else if (m_xEastFontNameLB
.get() == &rNameBox
)
561 pSizeBox
= m_xEastFontSizeLB
.get();
563 else if (m_xCTLFontNameLB
.get() == &rNameBox
)
565 pSizeBox
= m_xCTLFontSizeLB
.get();
569 SAL_WARN( "cui.tabpages", "invalid font name box" );
573 pSizeBox
->Fill( pFontList
);
578 void FillFontNames(weld::ComboBox
& rBox
, const FontList
& rList
)
581 sal_uInt16 nFontCount
= rList
.GetFontNameCount();
582 std::vector
<weld::ComboBoxEntry
> aVector
;
583 aVector
.reserve(nFontCount
);
584 for (sal_uInt16 i
= 0; i
< nFontCount
; ++i
)
586 const FontMetric
& rFontMetric
= rList
.GetFontName(i
);
587 aVector
.emplace_back(rFontMetric
.GetFamilyName());
589 rBox
.insert_vector(aVector
, false);
593 void SvxCharNamePage::Reset_Impl( const SfxItemSet
& rSet
, LanguageGroup eLangGrp
)
595 weld::ComboBox
* pNameBox
= nullptr;
596 weld::Label
* pStyleLabel
= nullptr;
597 FontStyleBox
* pStyleBox
= nullptr;
598 weld::Label
* pSizeLabel
= nullptr;
599 FontSizeBox
* pSizeBox
= nullptr;
600 weld::Label
* pLangFT
= nullptr;
601 SvxLanguageBox
* pLangBox
= nullptr;
602 sal_uInt16 nWhich
= 0;
607 pNameBox
= m_xWestFontNameLB
.get();
608 pStyleLabel
= m_xWestFontStyleFT
.get();
609 pStyleBox
= m_xWestFontStyleLB
.get();
610 pSizeLabel
= m_xWestFontSizeFT
.get();
611 pSizeBox
= m_xWestFontSizeLB
.get();
612 pLangFT
= m_xWestFontLanguageFT
.get();
613 pLangBox
= m_xWestFontLanguageLB
.get();
614 nWhich
= GetWhich( SID_ATTR_CHAR_FONT
);
618 pNameBox
= m_xEastFontNameLB
.get();
619 pStyleLabel
= m_xEastFontStyleFT
.get();
620 pStyleBox
= m_xEastFontStyleLB
.get();
621 pSizeLabel
= m_xEastFontSizeFT
.get();
622 pSizeBox
= m_xEastFontSizeLB
.get();
623 pLangFT
= m_xEastFontLanguageFT
.get();
624 pLangBox
= m_xEastFontLanguageLB
.get();
625 nWhich
= GetWhich( SID_ATTR_CHAR_CJK_FONT
);
629 pNameBox
= m_xCTLFontNameLB
.get();
630 pStyleLabel
= m_xCTLFontStyleFT
.get();
631 pStyleBox
= m_xCTLFontStyleLB
.get();
632 pSizeLabel
= m_xCTLFontSizeFT
.get();
633 pSizeBox
= m_xCTLFontSizeLB
.get();
634 pLangFT
= m_xCTLFontLanguageFT
.get();
635 pLangBox
= m_xCTLFontLanguageLB
.get();
636 nWhich
= GetWhich( SID_ATTR_CHAR_CTL_FONT
);
640 const FontList
* pFontList
= GetFontList();
641 FillFontNames(*pNameBox
, *pFontList
);
643 const SvxFontItem
* pFontItem
= nullptr;
644 SfxItemState eState
= rSet
.GetItemState( nWhich
);
646 if ( eState
>= SfxItemState::DEFAULT
)
648 pFontItem
= static_cast<const SvxFontItem
*>(&( rSet
.Get( nWhich
) ));
649 const OUString
&rName
= pFontItem
->GetFamilyName();
650 int nIndex
= pNameBox
->find_text(rName
);
651 pNameBox
->set_active(nIndex
);
652 // tdf#122992 if it didn't exist in the list, set the entry text to it anyway
654 pNameBox
->set_entry_text(rName
);
658 pNameBox
->set_active_text( OUString() );
661 FillStyleBox_Impl(*pNameBox
);
664 bool bStyleAvailable
= true;
665 FontItalic eItalic
= ITALIC_NONE
;
666 FontWeight eWeight
= WEIGHT_NORMAL
;
669 case Western
: nWhich
= GetWhich( SID_ATTR_CHAR_POSTURE
); break;
670 case Asian
: nWhich
= GetWhich( SID_ATTR_CHAR_CJK_POSTURE
); break;
671 case Ctl
: nWhich
= GetWhich( SID_ATTR_CHAR_CTL_POSTURE
); break;
673 eState
= rSet
.GetItemState( nWhich
);
675 if ( eState
>= SfxItemState::DEFAULT
)
677 const SvxPostureItem
& rItem
= static_cast<const SvxPostureItem
&>(rSet
.Get( nWhich
));
678 eItalic
= rItem
.GetValue();
681 bStyleAvailable
= bStyleAvailable
&& (eState
>= SfxItemState::DONTCARE
);
685 case Western
: nWhich
= GetWhich( SID_ATTR_CHAR_WEIGHT
); break;
686 case Asian
: nWhich
= GetWhich( SID_ATTR_CHAR_CJK_WEIGHT
); break;
687 case Ctl
: nWhich
= GetWhich( SID_ATTR_CHAR_CTL_WEIGHT
); break;
689 eState
= rSet
.GetItemState( nWhich
);
691 if ( eState
>= SfxItemState::DEFAULT
)
693 const SvxWeightItem
& rItem
= static_cast<const SvxWeightItem
&>(rSet
.Get( nWhich
));
694 eWeight
= rItem
.GetValue();
698 bStyleAvailable
= bStyleAvailable
&& (eState
>= SfxItemState::DONTCARE
);
700 // currently chosen font
701 if ( bStyle
&& pFontItem
)
703 FontMetric aFontMetric
= pFontList
->Get( pFontItem
->GetFamilyName(), eWeight
, eItalic
);
704 pStyleBox
->set_active_text( pFontList
->GetStyleName( aFontMetric
) );
706 else if ( !m_pImpl
->m_bInSearchMode
|| !bStyle
)
708 pStyleBox
->set_active_text( OUString() );
712 FontMetric aFontMetric
= pFontList
->Get( OUString(), eWeight
, eItalic
);
713 pStyleBox
->set_active_text( pFontList
->GetStyleName( aFontMetric
) );
715 if (!bStyleAvailable
)
717 pStyleBox
->set_sensitive(false);
718 pStyleLabel
->set_sensitive(false);
721 FillSizeBox_Impl(*pNameBox
);
724 case Western
: nWhich
= GetWhich( SID_ATTR_CHAR_FONTHEIGHT
); break;
725 case Asian
: nWhich
= GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT
); break;
726 case Ctl
: nWhich
= GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT
); break;
728 eState
= rSet
.GetItemState( nWhich
);
730 if ( pSizeBox
->IsRelativeMode() )
732 MapUnit eUnit
= rSet
.GetPool()->GetMetric( nWhich
);
733 const SvxFontHeightItem
& rItem
= static_cast<const SvxFontHeightItem
&>(rSet
.Get( nWhich
));
735 if( rItem
.GetProp() != 100 || MapUnit::MapRelative
!= rItem
.GetPropUnit() )
737 bool bPtRel
= MapUnit::MapPoint
== rItem
.GetPropUnit();
738 pSizeBox
->SetPtRelative( bPtRel
);
739 pSizeBox
->set_value( bPtRel
? static_cast<short>(rItem
.GetProp()) * 10 : rItem
.GetProp() );
743 pSizeBox
->SetRelative(false);
744 pSizeBox
->set_value( CalcToPoint( rItem
.GetHeight(), eUnit
, 10 ) );
747 else if ( eState
>= SfxItemState::DEFAULT
)
749 MapUnit eUnit
= rSet
.GetPool()->GetMetric( nWhich
);
750 const SvxFontHeightItem
& rItem
= static_cast<const SvxFontHeightItem
&>(rSet
.Get( nWhich
));
751 pSizeBox
->set_value( CalcToPoint( rItem
.GetHeight(), eUnit
, 10 ) );
755 pSizeBox
->set_active_or_entry_text(OUString());
756 if ( eState
<= SfxItemState::DISABLED
)
758 pSizeBox
->set_sensitive(false);
759 pSizeLabel
->set_sensitive(false);
765 case Western
: nWhich
= GetWhich( SID_ATTR_CHAR_LANGUAGE
); break;
766 case Asian
: nWhich
= GetWhich( SID_ATTR_CHAR_CJK_LANGUAGE
); break;
767 case Ctl
: nWhich
= GetWhich( SID_ATTR_CHAR_CTL_LANGUAGE
); break;
769 pLangBox
->set_active(-1);
770 eState
= rSet
.GetItemState( nWhich
);
774 case SfxItemState::UNKNOWN
:
779 case SfxItemState::DISABLED
:
780 pLangFT
->set_sensitive(false);
781 pLangBox
->set_sensitive(false);
784 case SfxItemState::DEFAULT
:
785 case SfxItemState::SET
:
787 const SvxLanguageItem
& rItem
= static_cast<const SvxLanguageItem
&>(rSet
.Get( nWhich
));
788 LanguageType eLangType
= rItem
.GetValue();
789 DBG_ASSERT( eLangType
!= LANGUAGE_SYSTEM
, "LANGUAGE_SYSTEM not allowed" );
790 if (eLangType
!= LANGUAGE_DONTKNOW
)
791 pLangBox
->set_active_id(eLangType
);
794 case SfxItemState::DONTCARE
:
798 OUString
sMapText(pFontList
->GetFontMapText(
799 pFontList
->Get(pNameBox
->get_active_text(), pStyleBox
->get_active_text())));
804 m_xWestFontTypeFT
->set_label(sMapText
);
807 m_xEastFontTypeFT
->set_label(sMapText
);
810 m_xCTLFontTypeFT
->set_label(sMapText
);
814 EnableFeatureButton(*pNameBox
);
816 // save these settings
817 pNameBox
->save_value();
818 pStyleBox
->save_value();
819 pSizeBox
->save_value();
820 pLangBox
->save_active_id();
823 bool SvxCharNamePage::FillItemSet_Impl( SfxItemSet
& rSet
, LanguageGroup eLangGrp
)
825 bool bModified
= false;
827 weld::ComboBox
* pNameBox
= nullptr;
828 FontStyleBox
* pStyleBox
= nullptr;
829 FontSizeBox
* pSizeBox
= nullptr;
830 SvxLanguageBox
* pLangBox
= nullptr;
831 sal_uInt16 nWhich
= 0;
832 sal_uInt16 nSlot
= 0;
837 pNameBox
= m_xWestFontNameLB
.get();
838 pStyleBox
= m_xWestFontStyleLB
.get();
839 pSizeBox
= m_xWestFontSizeLB
.get();
840 pLangBox
= m_xWestFontLanguageLB
.get();
841 nSlot
= SID_ATTR_CHAR_FONT
;
845 pNameBox
= m_xEastFontNameLB
.get();
846 pStyleBox
= m_xEastFontStyleLB
.get();
847 pSizeBox
= m_xEastFontSizeLB
.get();
848 pLangBox
= m_xEastFontLanguageLB
.get();
849 nSlot
= SID_ATTR_CHAR_CJK_FONT
;
853 pNameBox
= m_xCTLFontNameLB
.get();
854 pStyleBox
= m_xCTLFontStyleLB
.get();
855 pSizeBox
= m_xCTLFontSizeLB
.get();
856 pLangBox
= m_xCTLFontLanguageLB
.get();
857 nSlot
= SID_ATTR_CHAR_CTL_FONT
;
861 nWhich
= GetWhich( nSlot
);
862 const SfxPoolItem
* pItem
= nullptr;
863 const SfxItemSet
& rOldSet
= GetItemSet();
864 const SfxPoolItem
* pOld
= nullptr;
866 const SfxItemSet
* pExampleSet
= GetDialogExampleSet();
868 bool bChanged
= true;
869 const OUString
& rFontName
= pNameBox
->get_active_text();
870 const FontList
* pFontList
= GetFontList();
871 OUString aStyleBoxText
= pStyleBox
->get_active_text();
872 int nEntryPos
= pStyleBox
->find_text(aStyleBoxText
);
873 if (nEntryPos
>= m_pImpl
->m_nExtraEntryPos
)
874 aStyleBoxText
.clear();
875 FontMetric
aInfo( pFontList
->Get( rFontName
, aStyleBoxText
) );
876 SvxFontItem
aFontItem( aInfo
.GetFamilyType(), aInfo
.GetFamilyName(), aInfo
.GetStyleName(),
877 aInfo
.GetPitch(), aInfo
.GetCharSet(), nWhich
);
878 pOld
= GetOldItem( rSet
, nSlot
);
882 const SvxFontItem
& rItem
= *static_cast<const SvxFontItem
*>(pOld
);
884 if ( rItem
.GetFamilyName() == aFontItem
.GetFamilyName() )
889 bChanged
= pNameBox
->get_saved_value().isEmpty();
891 if ( !bChanged
&& pExampleSet
&&
892 pExampleSet
->GetItemState( nWhich
, false, &pItem
) == SfxItemState::SET
&&
893 static_cast<const SvxFontItem
*>(pItem
)->GetFamilyName() != aFontItem
.GetFamilyName() )
896 if ( bChanged
&& !rFontName
.isEmpty() )
898 rSet
.Put( aFontItem
);
901 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
902 rSet
.ClearItem( nWhich
);
908 case Western
: nSlot
= SID_ATTR_CHAR_WEIGHT
; break;
909 case Asian
: nSlot
= SID_ATTR_CHAR_CJK_WEIGHT
; break;
910 case Ctl
: nSlot
= SID_ATTR_CHAR_CTL_WEIGHT
; break;
912 nWhich
= GetWhich( nSlot
);
913 FontWeight eWeight
= aInfo
.GetWeight();
914 if ( nEntryPos
>= m_pImpl
->m_nExtraEntryPos
)
915 eWeight
= WEIGHT_NORMAL
;
916 SvxWeightItem
aWeightItem( eWeight
, nWhich
);
917 pOld
= GetOldItem( rSet
, nSlot
);
921 const SvxWeightItem
& rItem
= *static_cast<const SvxWeightItem
*>(pOld
);
923 if ( rItem
.GetValue() == aWeightItem
.GetValue() )
929 bChanged
= pStyleBox
->get_saved_value().isEmpty();
931 if ( m_pImpl
->m_bInSearchMode
&& bChanged
&&
932 aInfo
.GetWeight() == WEIGHT_NORMAL
&& aInfo
.GetItalic() != ITALIC_NONE
)
936 if ( !bChanged
&& pExampleSet
&&
937 pExampleSet
->GetItemState( nWhich
, false, &pItem
) == SfxItemState::SET
&&
938 static_cast<const SvxWeightItem
*>(pItem
)->GetValue() != aWeightItem
.GetValue() )
941 if ( nEntryPos
>= m_pImpl
->m_nExtraEntryPos
)
942 bChanged
= ( nEntryPos
== m_pImpl
->m_nExtraEntryPos
);
944 OUString
aText( pStyleBox
->get_active_text() ); // Tristate, then text empty
946 if ( bChanged
&& !aText
.isEmpty() )
948 rSet
.Put( aWeightItem
);
951 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
952 rSet
.InvalidateItem(nWhich
);
957 case Western
: nSlot
= SID_ATTR_CHAR_POSTURE
; break;
958 case Asian
: nSlot
= SID_ATTR_CHAR_CJK_POSTURE
; break;
959 case Ctl
: nSlot
= SID_ATTR_CHAR_CTL_POSTURE
; break;
961 nWhich
= GetWhich( nSlot
);
962 FontItalic eItalic
= aInfo
.GetItalic();
963 if ( nEntryPos
>= m_pImpl
->m_nExtraEntryPos
)
964 eItalic
= ITALIC_NONE
;
965 SvxPostureItem
aPostureItem( eItalic
, nWhich
);
966 pOld
= GetOldItem( rSet
, nSlot
);
970 const SvxPostureItem
& rItem
= *static_cast<const SvxPostureItem
*>(pOld
);
972 if ( rItem
.GetValue() == aPostureItem
.GetValue() )
978 bChanged
= pStyleBox
->get_saved_value().isEmpty();
980 if ( m_pImpl
->m_bInSearchMode
&& bChanged
&&
981 aInfo
.GetItalic() == ITALIC_NONE
&& aInfo
.GetWeight() != WEIGHT_NORMAL
)
985 if ( !bChanged
&& pExampleSet
&&
986 pExampleSet
->GetItemState( nWhich
, false, &pItem
) == SfxItemState::SET
&&
987 static_cast<const SvxPostureItem
*>(pItem
)->GetValue() != aPostureItem
.GetValue() )
990 if ( nEntryPos
>= m_pImpl
->m_nExtraEntryPos
)
991 bChanged
= ( nEntryPos
== ( m_pImpl
->m_nExtraEntryPos
+ 1 ) );
993 if ( bChanged
&& !aText
.isEmpty() )
995 rSet
.Put( aPostureItem
);
998 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
999 rSet
.InvalidateItem(nWhich
);
1002 tools::Long nSize
= pSizeBox
->get_value();
1004 if ( pSizeBox
->get_active_text().isEmpty() ) // GetValue() returns the min-value
1006 tools::Long nSavedSize
= pSizeBox
->get_saved_value();
1007 const bool bRel
= pSizeBox
->IsRelative();
1011 case Western
: nSlot
= SID_ATTR_CHAR_FONTHEIGHT
; break;
1012 case Asian
: nSlot
= SID_ATTR_CHAR_CJK_FONTHEIGHT
; break;
1013 case Ctl
: nSlot
= SID_ATTR_CHAR_CTL_FONTHEIGHT
; break;
1015 nWhich
= GetWhich( nSlot
);
1016 const SvxFontHeightItem
* pOldHeight
= static_cast<const SvxFontHeightItem
*>(GetOldItem( rSet
, nSlot
));
1017 bChanged
= ( nSize
!= nSavedSize
);
1019 if ( !bChanged
&& pExampleSet
&&
1020 pExampleSet
->GetItemState( nWhich
, false, &pItem
) == SfxItemState::SET
)
1022 float fSize
= static_cast<float>(nSize
) / 10;
1023 tools::Long nVal
= CalcToUnit( fSize
, rSet
.GetPool()->GetMetric( nWhich
) );
1024 if ( static_cast<const SvxFontHeightItem
*>(pItem
)->GetHeight() != static_cast<sal_uInt32
>(nVal
) )
1028 if ( bChanged
|| !pOldHeight
||
1029 bRel
!= ( MapUnit::MapRelative
!= pOldHeight
->GetPropUnit() || 100 != pOldHeight
->GetProp() ) )
1031 MapUnit eUnit
= rSet
.GetPool()->GetMetric( nWhich
);
1032 if ( pSizeBox
->IsRelative() )
1034 DBG_ASSERT( GetItemSet().GetParent(), "No parent set" );
1035 const SvxFontHeightItem
& rOldItem
=
1036 static_cast<const SvxFontHeightItem
&>(GetItemSet().GetParent()->Get( nWhich
));
1038 SvxFontHeightItem
aHeight( 240, 100, nWhich
);
1039 if ( pSizeBox
->IsPtRelative() )
1040 aHeight
.SetHeight( rOldItem
.GetHeight(), static_cast<sal_uInt16
>( nSize
/ 10 ), MapUnit::MapPoint
, eUnit
);
1042 aHeight
.SetHeight( rOldItem
.GetHeight(), static_cast<sal_uInt16
>(nSize
) );
1043 rSet
.Put( aHeight
);
1047 float fSize
= static_cast<float>(nSize
) / 10;
1048 rSet
.Put( SvxFontHeightItem( CalcToUnit( fSize
, eUnit
), 100, nWhich
) );
1052 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
1053 rSet
.InvalidateItem(nWhich
);
1058 case Western
: nSlot
= SID_ATTR_CHAR_LANGUAGE
; break;
1059 case Asian
: nSlot
= SID_ATTR_CHAR_CJK_LANGUAGE
; break;
1060 case Ctl
: nSlot
= SID_ATTR_CHAR_CTL_LANGUAGE
; break;
1063 // For language list boxes acting as ComboBox, check for, add and select an
1065 switch (pLangBox
->GetEditedAndValid())
1067 case SvxLanguageBox::EditedAndValid::No
:
1070 case SvxLanguageBox::EditedAndValid::Valid
:
1072 SvxLanguageBox
* ppBoxes
[3]
1073 = {m_xWestFontLanguageLB
.get(), m_xEastFontLanguageLB
.get(), m_xCTLFontLanguageLB
.get()};
1074 SvxLanguageBox
* pBox
= pLangBox
->SaveEditedAsEntry(ppBoxes
);
1075 if (pBox
!= pLangBox
)
1077 // Get item from corresponding slot.
1078 if (pBox
== m_xWestFontLanguageLB
.get())
1079 nSlot
= SID_ATTR_CHAR_LANGUAGE
;
1080 else if (pBox
== m_xEastFontLanguageLB
.get())
1081 nSlot
= SID_ATTR_CHAR_CJK_LANGUAGE
;
1082 else if (pBox
== m_xCTLFontLanguageLB
.get())
1083 nSlot
= SID_ATTR_CHAR_CTL_LANGUAGE
;
1088 case SvxLanguageBox::EditedAndValid::Invalid
:
1089 pLangBox
->set_active_id(pLangBox
->get_saved_active_id());
1093 nWhich
= GetWhich( nSlot
);
1094 pOld
= GetOldItem( rSet
, nSlot
);
1096 int nLangPos
= pLangBox
->get_active();
1097 LanguageType eLangType
= pLangBox
->get_active_id();
1101 const SvxLanguageItem
& rItem
= *static_cast<const SvxLanguageItem
*>(pOld
);
1102 if (nLangPos
== -1 || eLangType
== rItem
.GetValue())
1107 bChanged
= pLangBox
->get_active_id_changed_from_saved();
1109 if (bChanged
&& nLangPos
!= -1)
1111 rSet
.Put(SvxLanguageItem(eLangType
, nWhich
));
1114 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
1115 rSet
.InvalidateItem(nWhich
);
1120 IMPL_LINK_NOARG(SvxCharNamePage
, UpdateHdl_Impl
, Timer
*, void)
1122 UpdatePreview_Impl();
1125 IMPL_LINK(SvxCharNamePage
, FontModifyComboBoxHdl_Impl
, weld::ComboBox
&, rBox
, void)
1127 FontModifyHdl_Impl(rBox
);
1130 IMPL_LINK(SvxCharNamePage
, FontFeatureButtonClicked
, weld::Button
&, rButton
, void)
1133 weld::ComboBox
* pNameBox
= nullptr;
1135 if (&rButton
== m_xWestFontFeaturesButton
.get())
1137 pNameBox
= m_xWestFontNameLB
.get();
1138 sFontName
= GetPreviewFont().GetFamilyName();
1140 else if (&rButton
== m_xEastFontFeaturesButton
.get())
1142 pNameBox
= m_xEastFontNameLB
.get();
1143 sFontName
= GetPreviewCJKFont().GetFamilyName();
1145 else if (&rButton
== m_xCTLFontFeaturesButton
.get())
1147 pNameBox
= m_xCTLFontNameLB
.get();
1148 sFontName
= GetPreviewCTLFont().GetFamilyName();
1151 if (!sFontName
.isEmpty() && pNameBox
)
1153 cui::FontFeaturesDialog
aDialog(GetFrameWeld(), sFontName
);
1154 if (aDialog
.run() == RET_OK
)
1156 pNameBox
->set_entry_text(aDialog
.getResultFontName());
1157 UpdatePreview_Impl();
1162 void SvxCharNamePage::FontModifyHdl_Impl(const weld::Widget
& rNameBox
)
1164 m_pImpl
->m_aUpdateIdle
.Start();
1166 if (m_xWestFontNameLB
.get() == &rNameBox
|| m_xEastFontNameLB
.get() == &rNameBox
|| m_xCTLFontNameLB
.get() == &rNameBox
)
1168 FillStyleBox_Impl(rNameBox
);
1169 FillSizeBox_Impl(rNameBox
);
1170 EnableFeatureButton(rNameBox
);
1174 void SvxCharNamePage::ActivatePage( const SfxItemSet
& rSet
)
1176 SvxCharBasePage::ActivatePage( rSet
);
1178 UpdatePreview_Impl(); // instead of asynchronous calling in ctor
1181 DeactivateRC
SvxCharNamePage::DeactivatePage( SfxItemSet
* _pSet
)
1184 FillItemSet( _pSet
);
1185 return DeactivateRC::LeavePage
;
1188 std::unique_ptr
<SfxTabPage
> SvxCharNamePage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
1190 return std::make_unique
<SvxCharNamePage
>(pPage
, pController
, *rSet
);
1193 void SvxCharNamePage::Reset( const SfxItemSet
* rSet
)
1195 Reset_Impl( *rSet
, Western
);
1196 Reset_Impl( *rSet
, Asian
);
1197 Reset_Impl( *rSet
, Ctl
);
1199 SetPrevFontWidthScale( *rSet
);
1200 UpdatePreview_Impl();
1203 void SvxCharNamePage::ChangesApplied()
1205 m_xWestFontNameLB
->save_value();
1206 m_xWestFontStyleLB
->save_value();
1207 m_xWestFontSizeLB
->save_value();
1208 m_xWestFontLanguageLB
->save_active_id();
1209 m_xEastFontNameLB
->save_value();
1210 m_xEastFontStyleLB
->save_value();
1211 m_xEastFontSizeLB
->save_value();
1212 m_xEastFontLanguageLB
->save_active_id();
1213 m_xCTLFontNameLB
->save_value();
1214 m_xCTLFontStyleLB
->save_value();
1215 m_xCTLFontSizeLB
->save_value();
1216 m_xCTLFontLanguageLB
->save_active_id();
1219 bool SvxCharNamePage::FillItemSet( SfxItemSet
* rSet
)
1221 bool bModified
= FillItemSet_Impl( *rSet
, Western
);
1222 bModified
|= FillItemSet_Impl( *rSet
, Asian
);
1223 bModified
|= FillItemSet_Impl( *rSet
, Ctl
);
1227 void SvxCharNamePage::SetFontList( const SvxFontListItem
& rItem
)
1229 m_pImpl
->m_pFontList
= rItem
.GetFontList()->Clone();
1234 void enableRelativeMode( SvxCharNamePage
const * _pPage
, FontSizeBox
* _pFontSizeLB
, sal_uInt16 _nHeightWhich
)
1236 _pFontSizeLB
->EnableRelativeMode( 5, 995 ); // min 5%, max 995%, step 5
1238 const SvxFontHeightItem
& rHeightItem
=
1239 static_cast<const SvxFontHeightItem
&>(_pPage
->GetItemSet().GetParent()->Get( _nHeightWhich
));
1240 MapUnit eUnit
= _pPage
->GetItemSet().GetPool()->GetMetric( _nHeightWhich
);
1242 static_cast< short >( CalcToPoint( rHeightItem
.GetHeight(), eUnit
, 1 ) * 10 );
1244 // based on the current height:
1245 // - negative until minimum of 2 pt
1246 // - positive until maximum of 999 pt
1247 _pFontSizeLB
->EnablePtRelativeMode( sal::static_int_cast
< short >(-(nCurHeight
- 20)), (9999 - nCurHeight
) );
1251 void SvxCharNamePage::EnableRelativeMode()
1253 DBG_ASSERT( GetItemSet().GetParent(), "RelativeMode, but no ParentSet!" );
1254 enableRelativeMode(this,m_xWestFontSizeLB
.get(),GetWhich( SID_ATTR_CHAR_FONTHEIGHT
));
1255 enableRelativeMode(this,m_xEastFontSizeLB
.get(),GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT
));
1256 enableRelativeMode(this,m_xCTLFontSizeLB
.get(),GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT
));
1259 void SvxCharNamePage::EnableSearchMode()
1261 m_pImpl
->m_bInSearchMode
= true;
1264 void SvxCharNamePage::DisableControls( sal_uInt16 nDisable
)
1266 if ( DISABLE_HIDE_LANGUAGE
& nDisable
)
1268 if ( m_xWestFontLanguageFT
) m_xWestFontLanguageFT
->hide();
1269 if ( m_xWestFontLanguageLB
) m_xWestFontLanguageLB
->hide();
1270 if ( m_xEastFontLanguageFT
) m_xEastFontLanguageFT
->hide();
1271 if ( m_xEastFontLanguageLB
) m_xEastFontLanguageLB
->hide();
1272 if ( m_xCTLFontLanguageFT
) m_xCTLFontLanguageFT
->hide();
1273 if ( m_xCTLFontLanguageLB
) m_xCTLFontLanguageLB
->hide();
1277 void SvxCharNamePage::PageCreated(const SfxAllItemSet
& aSet
)
1279 const SvxFontListItem
* pFontListItem
= aSet
.GetItem
<SvxFontListItem
>(SID_ATTR_CHAR_FONTLIST
, false);
1280 const SfxUInt32Item
* pFlagItem
= aSet
.GetItem
<SfxUInt32Item
>(SID_FLAG_TYPE
, false);
1281 const SfxUInt16Item
* pDisableItem
= aSet
.GetItem
<SfxUInt16Item
>(SID_DISABLE_CTL
, false);
1283 SetFontList(*pFontListItem
);
1287 sal_uInt32 nFlags
=pFlagItem
->GetValue();
1288 if ( ( nFlags
& SVX_RELATIVE_MODE
) == SVX_RELATIVE_MODE
)
1289 EnableRelativeMode();
1290 if ( ( nFlags
& SVX_PREVIEW_CHARACTER
) == SVX_PREVIEW_CHARACTER
)
1291 // the writer uses SID_ATTR_BRUSH as font background
1292 m_bPreviewBackgroundToCharacter
= true;
1295 DisableControls(pDisableItem
->GetValue());
1297 // class SvxCharEffectsPage ----------------------------------------------
1299 SvxCharEffectsPage::SvxCharEffectsPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rInSet
)
1300 : SvxCharBasePage(pPage
, pController
, "cui/ui/effectspage.ui", "EffectsPage", rInSet
)
1301 , m_bOrigFontColor(false)
1302 , m_bNewFontColor(false)
1303 , m_bEnableNoneFontColor(false)
1304 , m_xFontColorFT(m_xBuilder
->weld_label("fontcolorft"))
1305 , m_xFontColorLB(new ColorListBox(m_xBuilder
->weld_menu_button("fontcolorlb"),
1306 [this]{ return GetDialogController()->getDialog(); }))
1307 , m_xFontTransparencyFT(m_xBuilder
->weld_label("fonttransparencyft"))
1308 , m_xFontTransparencyMtr(
1309 m_xBuilder
->weld_metric_spin_button("fonttransparencymtr", FieldUnit::PERCENT
))
1310 , m_xEffectsFT(m_xBuilder
->weld_label("effectsft"))
1311 , m_xEffectsLB(m_xBuilder
->weld_combo_box("effectslb"))
1312 , m_xReliefFT(m_xBuilder
->weld_label("reliefft"))
1313 , m_xReliefLB(m_xBuilder
->weld_combo_box("relieflb"))
1314 , m_xOutlineBtn(m_xBuilder
->weld_check_button("outlinecb"))
1315 , m_xShadowBtn(m_xBuilder
->weld_check_button("shadowcb"))
1316 , m_xHiddenBtn(m_xBuilder
->weld_check_button("hiddencb"))
1317 , m_xOverlineLB(m_xBuilder
->weld_combo_box("overlinelb"))
1318 , m_xOverlineColorFT(m_xBuilder
->weld_label("overlinecolorft"))
1319 , m_xOverlineColorLB(new ColorListBox(m_xBuilder
->weld_menu_button("overlinecolorlb"),
1320 [this]{ return GetDialogController()->getDialog(); }))
1321 , m_xStrikeoutLB(m_xBuilder
->weld_combo_box("strikeoutlb"))
1322 , m_xUnderlineLB(m_xBuilder
->weld_combo_box("underlinelb"))
1323 , m_xUnderlineColorFT(m_xBuilder
->weld_label("underlinecolorft"))
1324 , m_xUnderlineColorLB(new ColorListBox(m_xBuilder
->weld_menu_button("underlinecolorlb"),
1325 [this]{ return GetDialogController()->getDialog(); }))
1326 , m_xIndividualWordsBtn(m_xBuilder
->weld_check_button("individualwordscb"))
1327 , m_xEmphasisFT(m_xBuilder
->weld_label("emphasisft"))
1328 , m_xEmphasisLB(m_xBuilder
->weld_combo_box("emphasislb"))
1329 , m_xPositionFT(m_xBuilder
->weld_label("positionft"))
1330 , m_xPositionLB(m_xBuilder
->weld_combo_box("positionlb"))
1331 , m_xA11yWarningFT(m_xBuilder
->weld_label("a11ywarning"))
1333 m_xPreviewWin
.reset(new weld::CustomWeld(*m_xBuilder
, "preview", m_aPreviewWin
));
1335 m_xPreviewWin
->hide();
1337 m_xFontColorLB
->SetSlotId(SID_ATTR_CHAR_COLOR
);
1338 m_xOverlineColorLB
->SetSlotId(SID_ATTR_CHAR_COLOR
);
1339 m_xUnderlineColorLB
->SetSlotId(SID_ATTR_CHAR_COLOR
);
1343 void SvxCharEffectsPage::EnableNoneFontColor()
1345 m_xFontColorLB
->SetSlotId(SID_ATTR_CHAR_COLOR
, true);
1346 m_bEnableNoneFontColor
= true;
1349 SvxCharEffectsPage::~SvxCharEffectsPage()
1351 m_xUnderlineColorLB
.reset();
1352 m_xOverlineColorLB
.reset();
1353 m_xFontTransparencyMtr
.reset();
1354 m_xFontColorLB
.reset();
1357 void SvxCharEffectsPage::Initialize()
1359 // to handle the changes of the other pages
1360 SetExchangeSupport();
1363 const SfxUInt16Item
* pHtmlModeItem
= GetItemSet().GetItemIfSet( SID_HTML_MODE
, false );
1364 if ( !pHtmlModeItem
)
1366 if (SfxObjectShell
* pShell
= SfxObjectShell::Current())
1367 pHtmlModeItem
= pShell
->GetItem( SID_HTML_MODE
);
1371 m_nHtmlMode
= pHtmlModeItem
->GetValue();
1372 if ( ( m_nHtmlMode
& HTMLMODE_ON
) == HTMLMODE_ON
)
1374 //!!! hide some controls please
1378 m_xFontColorLB
->SetSelectHdl(LINK(this, SvxCharEffectsPage
, ColorBoxSelectHdl_Impl
));
1379 m_xFontTransparencyMtr
->connect_value_changed(
1380 LINK(this, SvxCharEffectsPage
, ModifyFontTransparencyHdl_Impl
));
1383 Link
<weld::ComboBox
&,void> aLink
= LINK( this, SvxCharEffectsPage
, SelectListBoxHdl_Impl
);
1384 m_xUnderlineLB
->connect_changed( aLink
);
1385 m_xUnderlineColorLB
->SetSelectHdl(LINK(this, SvxCharEffectsPage
, ColorBoxSelectHdl_Impl
));
1386 m_xOverlineLB
->connect_changed( aLink
);
1387 m_xOverlineColorLB
->SetSelectHdl(LINK(this, SvxCharEffectsPage
, ColorBoxSelectHdl_Impl
));
1388 m_xStrikeoutLB
->connect_changed( aLink
);
1389 m_xEmphasisLB
->connect_changed( aLink
);
1390 m_xPositionLB
->connect_changed( aLink
);
1391 m_xEffectsLB
->connect_changed( aLink
);
1392 m_xReliefLB
->connect_changed( aLink
);
1394 m_xUnderlineLB
->set_active( 0 );
1395 m_xOverlineLB
->set_active( 0 );
1396 m_xStrikeoutLB
->set_active( 0 );
1397 m_xEmphasisLB
->set_active( 0 );
1398 m_xPositionLB
->set_active( 0 );
1399 SelectHdl_Impl(nullptr);
1400 SelectHdl_Impl(m_xEmphasisLB
.get());
1402 m_xEffectsLB
->set_active( 0 );
1404 m_xHiddenBtn
->connect_toggled(LINK(this, SvxCharEffectsPage
, HiddenBtnClickHdl
));
1405 m_xIndividualWordsBtn
->connect_toggled(LINK(this, SvxCharEffectsPage
, CbClickHdl_Impl
));
1406 m_xOutlineBtn
->connect_toggled(LINK(this, SvxCharEffectsPage
, OutlineBtnClickHdl
));
1407 m_xShadowBtn
->connect_toggled(LINK(this, SvxCharEffectsPage
, ShadowBtnClickHdl
));
1409 if ( !SvtCJKOptions::IsAsianTypographyEnabled() )
1411 m_xEmphasisFT
->hide();
1412 m_xEmphasisLB
->hide();
1413 m_xPositionFT
->hide();
1414 m_xPositionLB
->hide();
1417 m_xA11yWarningFT
->set_visible(officecfg::Office::Common::Accessibility::IsAutomaticFontColor::get());
1420 void SvxCharEffectsPage::UpdatePreview_Impl()
1422 SvxFont
& rFont
= GetPreviewFont();
1423 SvxFont
& rCJKFont
= GetPreviewCJKFont();
1424 SvxFont
& rCTLFont
= GetPreviewCTLFont();
1426 const Color
& rSelectedColor
= m_xFontColorLB
->GetSelectEntryColor();
1427 rFont
.SetColor(rSelectedColor
);
1428 rCJKFont
.SetColor(rSelectedColor
);
1429 rCTLFont
.SetColor(rSelectedColor
);
1430 m_aPreviewWin
.AutoCorrectFontColor(); // handle color COL_AUTO
1432 FontLineStyle eUnderline
= static_cast<FontLineStyle
>(m_xUnderlineLB
->get_active_id().toInt32());
1433 FontLineStyle eOverline
= static_cast<FontLineStyle
>(m_xOverlineLB
->get_active_id().toInt32());
1434 FontStrikeout eStrikeout
= static_cast<FontStrikeout
>(m_xStrikeoutLB
->get_active_id().toInt32());
1435 rFont
.SetUnderline( eUnderline
);
1436 rCJKFont
.SetUnderline( eUnderline
);
1437 rCTLFont
.SetUnderline( eUnderline
);
1438 m_aPreviewWin
.SetTextLineColor( m_xUnderlineColorLB
->GetSelectEntryColor() );
1439 rFont
.SetOverline( eOverline
);
1440 rCJKFont
.SetOverline( eOverline
);
1441 rCTLFont
.SetOverline( eOverline
);
1442 m_aPreviewWin
.SetOverlineColor( m_xOverlineColorLB
->GetSelectEntryColor() );
1443 rFont
.SetStrikeout( eStrikeout
);
1444 rCJKFont
.SetStrikeout( eStrikeout
);
1445 rCTLFont
.SetStrikeout( eStrikeout
);
1447 auto nEmphasis
= m_xEmphasisLB
->get_active();
1448 if (nEmphasis
!= -1)
1450 bool bUnder
= (CHRDLG_POSITION_UNDER
== m_xPositionLB
->get_active_id().toInt32());
1451 FontEmphasisMark eMark
= static_cast<FontEmphasisMark
>(nEmphasis
);
1452 eMark
|= bUnder
? FontEmphasisMark::PosBelow
: FontEmphasisMark::PosAbove
;
1453 rFont
.SetEmphasisMark( eMark
);
1454 rCJKFont
.SetEmphasisMark( eMark
);
1455 rCTLFont
.SetEmphasisMark( eMark
);
1458 auto nRelief
= m_xReliefLB
->get_active();
1461 rFont
.SetRelief( static_cast<FontRelief
>(nRelief
) );
1462 rCJKFont
.SetRelief( static_cast<FontRelief
>(nRelief
) );
1463 rCTLFont
.SetRelief( static_cast<FontRelief
>(nRelief
) );
1466 rFont
.SetOutline( StateToAttr( m_xOutlineBtn
->get_state() ) );
1467 rCJKFont
.SetOutline( rFont
.IsOutline() );
1468 rCTLFont
.SetOutline( rFont
.IsOutline() );
1470 rFont
.SetShadow( StateToAttr( m_xShadowBtn
->get_state() ) );
1471 rCJKFont
.SetShadow( rFont
.IsShadow() );
1472 rCTLFont
.SetShadow( rFont
.IsShadow() );
1474 auto nCapsPos
= m_xEffectsLB
->get_active();
1477 SvxCaseMap eCaps
= static_cast<SvxCaseMap
>(nCapsPos
);
1478 rFont
.SetCaseMap( eCaps
);
1479 rCJKFont
.SetCaseMap( eCaps
);
1480 // #i78474# small caps do not exist in CTL fonts
1481 rCTLFont
.SetCaseMap( eCaps
== SvxCaseMap::SmallCaps
? SvxCaseMap::NotMapped
: eCaps
);
1484 bool bWordLine
= StateToAttr( m_xIndividualWordsBtn
->get_state() );
1485 rFont
.SetWordLineMode( bWordLine
);
1486 rCJKFont
.SetWordLineMode( bWordLine
);
1487 rCTLFont
.SetWordLineMode( bWordLine
);
1489 m_aPreviewWin
.Invalidate();
1492 void SvxCharEffectsPage::SetCaseMap_Impl( SvxCaseMap eCaseMap
)
1494 if ( SvxCaseMap::End
> eCaseMap
)
1495 m_xEffectsLB
->set_active(
1496 sal::static_int_cast
< sal_Int32
>( eCaseMap
) );
1500 m_xEffectsLB
->set_active(-1);
1503 UpdatePreview_Impl();
1506 void SvxCharEffectsPage::ResetColor_Impl( const SfxItemSet
& rSet
)
1508 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_COLOR
);
1509 SfxItemState eState
= rSet
.GetItemState( nWhich
);
1511 m_bOrigFontColor
= false;
1514 case SfxItemState::UNKNOWN
:
1515 m_xFontColorFT
->hide();
1516 m_xFontColorLB
->hide();
1519 case SfxItemState::DISABLED
:
1520 m_xFontColorFT
->set_sensitive(false);
1521 m_xFontColorLB
->set_sensitive(false);
1524 case SfxItemState::DONTCARE
:
1525 //Related: tdf#106080 if there is no font color, then allow "none"
1526 //as a color so the listbox can display that state.
1527 EnableNoneFontColor();
1528 m_xFontColorLB
->SetNoSelection();
1531 case SfxItemState::DEFAULT
:
1532 case SfxItemState::SET
:
1534 SvxFont
& rFont
= GetPreviewFont();
1535 SvxFont
& rCJKFont
= GetPreviewCJKFont();
1536 SvxFont
& rCTLFont
= GetPreviewCTLFont();
1538 const SvxColorItem
& rItem
= static_cast<const SvxColorItem
&>(rSet
.Get( nWhich
));
1539 Color aColor
= rItem
.GetValue();
1540 rFont
.SetColor(aColor
);
1541 rCJKFont
.SetColor(aColor
);
1542 rCTLFont
.SetColor(aColor
);
1543 m_aPreviewWin
.AutoCorrectFontColor(); // handle color COL_AUTO
1545 m_aPreviewWin
.Invalidate();
1547 Color aRGBColor
= aColor
;
1548 if (aRGBColor
.IsTransparent() && aColor
!= COL_AUTO
)
1550 aRGBColor
.SetAlpha(255);
1552 m_xFontColorLB
->SelectEntry(aRGBColor
);
1554 if (m_xFontTransparencyMtr
->get_visible() && aColor
!= COL_AUTO
)
1556 double fTransparency
= (255 - aColor
.GetAlpha()) * 100.0 / 255;
1557 m_xFontTransparencyMtr
->set_value(basegfx::fround(fTransparency
),
1558 FieldUnit::PERCENT
);
1561 m_aOrigFontColor
= aColor
;
1562 m_bOrigFontColor
= true;
1566 m_bNewFontColor
= false;
1569 bool SvxCharEffectsPage::FillItemSetColor_Impl( SfxItemSet
& rSet
)
1571 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_COLOR
);
1572 const SfxItemSet
& rOldSet
= GetItemSet();
1574 NamedColor aSelectedColor
;
1575 bool bChanged
= m_bNewFontColor
;
1579 aSelectedColor
= m_xFontColorLB
->GetSelectedEntryThemedColor();
1581 if (m_xFontTransparencyMtr
->get_value_changed_from_saved())
1583 double fTransparency
1584 = m_xFontTransparencyMtr
->get_value(FieldUnit::PERCENT
) * 255.0 / 100;
1585 aSelectedColor
.m_aColor
.SetAlpha(255 - static_cast<sal_uInt8
>(basegfx::fround(fTransparency
)));
1588 if (m_bOrigFontColor
)
1589 bChanged
= aSelectedColor
.m_aColor
!= m_aOrigFontColor
;
1590 if (m_bEnableNoneFontColor
&& bChanged
&& aSelectedColor
.m_aColor
== COL_NONE_COLOR
)
1596 SvxColorItem
aItem( aSelectedColor
.m_aColor
, nWhich
);
1598 // The color was picked from the theme palette, remember its index.
1599 model::ThemeColorType eType
= model::convertToThemeColorType(aSelectedColor
.m_nThemeIndex
);
1600 if (eType
!= model::ThemeColorType::Unknown
)
1602 model::ComplexColor aComplexColor
;
1603 aComplexColor
.setSchemeColor(eType
);
1604 aComplexColor
.addTransformation({model::TransformationType::LumMod
, aSelectedColor
.m_nLumMod
});
1605 aComplexColor
.addTransformation({model::TransformationType::LumOff
, aSelectedColor
.m_nLumOff
});
1606 aItem
.setComplexColor(aComplexColor
);
1611 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
1612 rSet
.InvalidateItem(nWhich
);
1617 IMPL_LINK( SvxCharEffectsPage
, SelectListBoxHdl_Impl
, weld::ComboBox
&, rBox
, void )
1619 SelectHdl_Impl(&rBox
);
1622 void SvxCharEffectsPage::SelectHdl_Impl(const weld::ComboBox
* pBox
)
1624 if (m_xEmphasisLB
.get() == pBox
)
1626 auto nEPos
= m_xEmphasisLB
->get_active();
1627 bool bEnable
= nEPos
> 0;
1628 m_xPositionFT
->set_sensitive( bEnable
);
1629 m_xPositionLB
->set_sensitive( bEnable
);
1631 else if (m_xReliefLB
.get() == pBox
)
1633 bool bEnable
= ( pBox
->get_active() == 0 );
1634 m_xOutlineBtn
->set_sensitive( bEnable
);
1635 m_xShadowBtn
->set_sensitive( bEnable
);
1637 else if (m_xPositionLB
.get() != pBox
)
1639 auto nUPos
= m_xUnderlineLB
->get_active();
1640 bool bUEnable
= nUPos
> 0;
1641 m_xUnderlineColorFT
->set_sensitive(bUEnable
);
1642 m_xUnderlineColorLB
->set_sensitive(bUEnable
);
1644 auto nOPos
= m_xOverlineLB
->get_active();
1645 bool bOEnable
= nOPos
> 0;
1646 m_xOverlineColorFT
->set_sensitive(bOEnable
);
1647 m_xOverlineColorLB
->set_sensitive(bOEnable
);
1649 auto nSPos
= m_xStrikeoutLB
->get_active();
1650 m_xIndividualWordsBtn
->set_sensitive( bUEnable
|| bOEnable
|| nSPos
> 0);
1652 UpdatePreview_Impl();
1655 IMPL_LINK(SvxCharEffectsPage
, CbClickHdl_Impl
, weld::Toggleable
&, rToggle
, void)
1657 m_aIndividualWordsState
.ButtonToggled(rToggle
);
1658 UpdatePreview_Impl();
1659 UpdatePreview_Impl();
1662 IMPL_LINK(SvxCharEffectsPage
, ColorBoxSelectHdl_Impl
, ColorListBox
&, rBox
, void)
1664 if (m_xFontColorLB
.get() == &rBox
)
1665 m_bNewFontColor
= true;
1666 UpdatePreview_Impl();
1669 IMPL_LINK_NOARG(SvxCharEffectsPage
, ModifyFontTransparencyHdl_Impl
, weld::MetricSpinButton
&, void)
1671 m_bNewFontColor
= true;
1674 DeactivateRC
SvxCharEffectsPage::DeactivatePage( SfxItemSet
* _pSet
)
1677 FillItemSet( _pSet
);
1678 return DeactivateRC::LeavePage
;
1681 std::unique_ptr
<SfxTabPage
> SvxCharEffectsPage::Create( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
1683 return std::make_unique
<SvxCharEffectsPage
>( pPage
, pController
, *rSet
);
1686 void SvxCharEffectsPage::Reset( const SfxItemSet
* rSet
)
1688 SvxFont
& rFont
= GetPreviewFont();
1689 SvxFont
& rCJKFont
= GetPreviewCJKFont();
1690 SvxFont
& rCTLFont
= GetPreviewCTLFont();
1692 bool bEnable
= false;
1695 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_UNDERLINE
);
1696 rFont
.SetUnderline( LINESTYLE_NONE
);
1697 rCJKFont
.SetUnderline( LINESTYLE_NONE
);
1698 rCTLFont
.SetUnderline( LINESTYLE_NONE
);
1700 m_xUnderlineLB
->set_active( 0 );
1701 SfxItemState eState
= rSet
->GetItemState( nWhich
);
1703 if ( eState
>= SfxItemState::DONTCARE
)
1705 if ( eState
== SfxItemState::DONTCARE
)
1706 m_xUnderlineLB
->set_active(-1);
1709 const SvxUnderlineItem
& rItem
= static_cast<const SvxUnderlineItem
&>(rSet
->Get( nWhich
));
1710 FontLineStyle eUnderline
= rItem
.GetValue();
1711 rFont
.SetUnderline( eUnderline
);
1712 rCJKFont
.SetUnderline( eUnderline
);
1713 rCTLFont
.SetUnderline( eUnderline
);
1715 if ( eUnderline
!= LINESTYLE_NONE
)
1717 auto nPos
= m_xUnderlineLB
->find_id(OUString::number(eUnderline
));
1720 m_xUnderlineLB
->set_active(nPos
);
1723 Color aColor
= rItem
.GetColor();
1724 m_xUnderlineColorLB
->SelectEntry(aColor
);
1728 m_xUnderlineColorLB
->SelectEntry(COL_AUTO
);
1729 m_xUnderlineColorLB
->set_sensitive(false);
1735 nWhich
= GetWhich( SID_ATTR_CHAR_OVERLINE
);
1736 rFont
.SetOverline( LINESTYLE_NONE
);
1737 rCJKFont
.SetOverline( LINESTYLE_NONE
);
1738 rCTLFont
.SetOverline( LINESTYLE_NONE
);
1740 m_xOverlineLB
->set_active( 0 );
1741 eState
= rSet
->GetItemState( nWhich
);
1743 if ( eState
>= SfxItemState::DONTCARE
)
1745 if ( eState
== SfxItemState::DONTCARE
)
1746 m_xOverlineLB
->set_active(-1);
1749 const SvxOverlineItem
& rItem
= static_cast<const SvxOverlineItem
&>(rSet
->Get( nWhich
));
1750 FontLineStyle eOverline
= rItem
.GetValue();
1751 rFont
.SetOverline( eOverline
);
1752 rCJKFont
.SetOverline( eOverline
);
1753 rCTLFont
.SetOverline( eOverline
);
1755 if ( eOverline
!= LINESTYLE_NONE
)
1757 auto nPos
= m_xOverlineLB
->find_id(OUString::number(eOverline
));
1760 m_xOverlineLB
->set_active(nPos
);
1763 Color aColor
= rItem
.GetColor();
1764 m_xOverlineColorLB
->SelectEntry(aColor
);
1768 m_xOverlineColorLB
->SelectEntry(COL_AUTO
);
1769 m_xOverlineColorLB
->set_sensitive(false);
1775 nWhich
= GetWhich( SID_ATTR_CHAR_STRIKEOUT
);
1776 rFont
.SetStrikeout( STRIKEOUT_NONE
);
1777 rCJKFont
.SetStrikeout( STRIKEOUT_NONE
);
1778 rCTLFont
.SetStrikeout( STRIKEOUT_NONE
);
1780 m_xStrikeoutLB
->set_active( 0 );
1781 eState
= rSet
->GetItemState( nWhich
);
1783 if ( eState
>= SfxItemState::DONTCARE
)
1785 if ( eState
== SfxItemState::DONTCARE
)
1786 m_xStrikeoutLB
->set_active(-1);
1789 const SvxCrossedOutItem
& rItem
= static_cast<const SvxCrossedOutItem
&>(rSet
->Get( nWhich
));
1790 FontStrikeout eStrikeout
= rItem
.GetValue();
1791 rFont
.SetStrikeout( eStrikeout
);
1792 rCJKFont
.SetStrikeout( eStrikeout
);
1793 rCTLFont
.SetStrikeout( eStrikeout
);
1795 if ( eStrikeout
!= STRIKEOUT_NONE
)
1797 auto nPos
= m_xStrikeoutLB
->find_id(OUString::number(eStrikeout
));
1800 m_xStrikeoutLB
->set_active(nPos
);
1808 nWhich
= GetWhich( SID_ATTR_CHAR_WORDLINEMODE
);
1809 eState
= rSet
->GetItemState( nWhich
);
1813 case SfxItemState::UNKNOWN
:
1814 m_aIndividualWordsState
.bTriStateEnabled
= false;
1815 m_xIndividualWordsBtn
->hide();
1818 case SfxItemState::DISABLED
:
1819 m_aIndividualWordsState
.bTriStateEnabled
= false;
1820 m_xIndividualWordsBtn
->set_sensitive(false);
1823 case SfxItemState::DONTCARE
:
1824 m_aIndividualWordsState
.bTriStateEnabled
= true;
1825 m_xIndividualWordsBtn
->set_state( TRISTATE_INDET
);
1828 case SfxItemState::DEFAULT
:
1829 case SfxItemState::SET
:
1831 const SvxWordLineModeItem
& rItem
= static_cast<const SvxWordLineModeItem
&>(rSet
->Get( nWhich
));
1832 rFont
.SetWordLineMode( rItem
.GetValue() );
1833 rCJKFont
.SetWordLineMode( rItem
.GetValue() );
1834 rCTLFont
.SetWordLineMode( rItem
.GetValue() );
1836 m_aIndividualWordsState
.bTriStateEnabled
= false;
1837 m_xIndividualWordsBtn
->set_active(rItem
.GetValue());
1838 m_xIndividualWordsBtn
->set_sensitive(bEnable
);
1844 nWhich
= GetWhich( SID_ATTR_CHAR_EMPHASISMARK
);
1845 eState
= rSet
->GetItemState( nWhich
);
1847 if ( eState
>= SfxItemState::DEFAULT
)
1849 const SvxEmphasisMarkItem
& rItem
= static_cast<const SvxEmphasisMarkItem
&>(rSet
->Get( nWhich
));
1850 FontEmphasisMark eMark
= rItem
.GetEmphasisMark();
1851 rFont
.SetEmphasisMark( eMark
);
1852 rCJKFont
.SetEmphasisMark( eMark
);
1853 rCTLFont
.SetEmphasisMark( eMark
);
1855 m_xEmphasisLB
->set_active( static_cast<sal_Int32
>(FontEmphasisMark( eMark
& FontEmphasisMark::Style
)) );
1856 eMark
&= ~FontEmphasisMark::Style
;
1857 int nEntryData
= ( eMark
== FontEmphasisMark::PosAbove
)
1858 ? CHRDLG_POSITION_OVER
1859 : ( eMark
== FontEmphasisMark::PosBelow
) ? CHRDLG_POSITION_UNDER
: 0;
1861 auto nPos
= m_xPositionLB
->find_id(OUString::number(nEntryData
));
1863 m_xPositionLB
->set_active(nPos
);
1865 else if ( eState
== SfxItemState::DONTCARE
)
1866 m_xEmphasisLB
->set_active(-1);
1867 else if ( eState
== SfxItemState::UNKNOWN
)
1869 m_xEmphasisFT
->hide();
1870 m_xEmphasisLB
->hide();
1872 else // SfxItemState::DISABLED
1874 m_xEmphasisFT
->set_sensitive(false);
1875 m_xEmphasisLB
->set_sensitive(false);
1878 // the select handler for the underline/overline/strikeout list boxes
1879 SelectHdl_Impl(m_xUnderlineLB
.get());
1881 // the select handler for the emphasis listbox
1882 SelectHdl_Impl(m_xEmphasisLB
.get());
1885 SvxCaseMap eCaseMap
= SvxCaseMap::End
;
1886 nWhich
= GetWhich( SID_ATTR_CHAR_CASEMAP
);
1887 eState
= rSet
->GetItemState( nWhich
);
1890 case SfxItemState::UNKNOWN
:
1891 m_xEffectsFT
->hide();
1892 m_xEffectsLB
->hide();
1895 case SfxItemState::DISABLED
:
1896 m_xEffectsFT
->set_sensitive(false);
1897 m_xEffectsLB
->set_sensitive(false);
1900 case SfxItemState::DONTCARE
:
1901 m_xEffectsLB
->set_active(-1);
1904 case SfxItemState::DEFAULT
:
1905 case SfxItemState::SET
:
1907 const SvxCaseMapItem
& rItem
= static_cast<const SvxCaseMapItem
&>(rSet
->Get( nWhich
));
1908 eCaseMap
= rItem
.GetValue();
1912 SetCaseMap_Impl( eCaseMap
);
1915 nWhich
= GetWhich(SID_ATTR_CHAR_RELIEF
);
1916 eState
= rSet
->GetItemState( nWhich
);
1919 case SfxItemState::UNKNOWN
:
1920 m_xReliefFT
->hide();
1921 m_xReliefLB
->hide();
1924 case SfxItemState::DISABLED
:
1925 m_xReliefFT
->set_sensitive(false);
1926 m_xReliefLB
->set_sensitive(false);
1929 case SfxItemState::DONTCARE
:
1930 m_xReliefLB
->set_active(-1);
1933 case SfxItemState::DEFAULT
:
1934 case SfxItemState::SET
:
1936 const SvxCharReliefItem
& rItem
= static_cast<const SvxCharReliefItem
&>(rSet
->Get( nWhich
));
1937 m_xReliefLB
->set_active(static_cast<sal_Int32
>(rItem
.GetValue()));
1938 SelectHdl_Impl(m_xReliefLB
.get());
1944 nWhich
= GetWhich( SID_ATTR_CHAR_CONTOUR
);
1945 eState
= rSet
->GetItemState( nWhich
);
1948 case SfxItemState::UNKNOWN
:
1949 m_aOutlineState
.bTriStateEnabled
= false;
1950 m_xOutlineBtn
->hide();
1953 case SfxItemState::DISABLED
:
1954 m_aOutlineState
.bTriStateEnabled
= false;
1955 m_xOutlineBtn
->set_sensitive(false);
1958 case SfxItemState::DONTCARE
:
1959 m_aOutlineState
.bTriStateEnabled
= true;
1960 m_xOutlineBtn
->set_state(TRISTATE_INDET
);
1963 case SfxItemState::DEFAULT
:
1964 case SfxItemState::SET
:
1966 const SvxContourItem
& rItem
= static_cast<const SvxContourItem
&>(rSet
->Get( nWhich
));
1967 m_aOutlineState
.bTriStateEnabled
= false;
1968 m_xOutlineBtn
->set_state(static_cast<TriState
>(rItem
.GetValue()));
1974 nWhich
= GetWhich( SID_ATTR_CHAR_SHADOWED
);
1975 eState
= rSet
->GetItemState( nWhich
);
1979 case SfxItemState::UNKNOWN
:
1980 m_aShadowState
.bTriStateEnabled
= false;
1981 m_xShadowBtn
->hide();
1984 case SfxItemState::DISABLED
:
1985 m_aShadowState
.bTriStateEnabled
= false;
1986 m_xShadowBtn
->set_sensitive(false);
1989 case SfxItemState::DONTCARE
:
1990 m_aShadowState
.bTriStateEnabled
= true;
1991 m_xShadowBtn
->set_state( TRISTATE_INDET
);
1994 case SfxItemState::DEFAULT
:
1995 case SfxItemState::SET
:
1997 const SvxShadowedItem
& rItem
= static_cast<const SvxShadowedItem
&>(rSet
->Get( nWhich
));
1998 m_aShadowState
.bTriStateEnabled
= false;
1999 m_xShadowBtn
->set_state( static_cast<TriState
>(rItem
.GetValue()) );
2005 nWhich
= GetWhich( SID_ATTR_CHAR_HIDDEN
);
2006 eState
= rSet
->GetItemState( nWhich
);
2010 case SfxItemState::UNKNOWN
:
2011 m_aHiddenState
.bTriStateEnabled
= false;
2012 m_xHiddenBtn
->hide();
2015 case SfxItemState::DISABLED
:
2016 m_aHiddenState
.bTriStateEnabled
= false;
2017 m_xHiddenBtn
->set_sensitive(false);
2020 case SfxItemState::DONTCARE
:
2021 m_aHiddenState
.bTriStateEnabled
= true;
2022 m_xHiddenBtn
->set_state(TRISTATE_INDET
);
2025 case SfxItemState::DEFAULT
:
2026 case SfxItemState::SET
:
2028 const SvxCharHiddenItem
& rItem
= static_cast<const SvxCharHiddenItem
&>(rSet
->Get( nWhich
));
2029 m_aHiddenState
.bTriStateEnabled
= false;
2030 m_xHiddenBtn
->set_state(static_cast<TriState
>(rItem
.GetValue()));
2035 SetPrevFontWidthScale( *rSet
);
2036 ResetColor_Impl( *rSet
);
2039 m_aPreviewWin
.Invalidate();
2041 // save this settings
2045 IMPL_LINK(SvxCharEffectsPage
, HiddenBtnClickHdl
, weld::Toggleable
&, rToggle
, void)
2047 m_aHiddenState
.ButtonToggled(rToggle
);
2050 IMPL_LINK(SvxCharEffectsPage
, OutlineBtnClickHdl
, weld::Toggleable
&, rToggle
, void)
2052 m_aOutlineState
.ButtonToggled(rToggle
);
2053 UpdatePreview_Impl();
2056 IMPL_LINK(SvxCharEffectsPage
, ShadowBtnClickHdl
, weld::Toggleable
&, rToggle
, void)
2058 m_aShadowState
.ButtonToggled(rToggle
);
2059 UpdatePreview_Impl();
2062 void SvxCharEffectsPage::ChangesApplied()
2064 m_xUnderlineLB
->save_value();
2065 m_xOverlineLB
->save_value();
2066 m_xStrikeoutLB
->save_value();
2067 m_xIndividualWordsBtn
->save_state();
2068 m_xEmphasisLB
->save_value();
2069 m_xPositionLB
->save_value();
2070 m_xEffectsLB
->save_value();
2071 m_xReliefLB
->save_value();
2072 m_xOutlineBtn
->save_state();
2073 m_xShadowBtn
->save_state();
2074 m_xHiddenBtn
->save_state();
2075 m_xFontTransparencyMtr
->save_value();
2078 bool SvxCharEffectsPage::FillItemSet( SfxItemSet
* rSet
)
2080 const SfxPoolItem
* pOld
= nullptr;
2081 const SfxItemSet
& rOldSet
= GetItemSet();
2082 bool bModified
= false;
2083 bool bChanged
= true;
2086 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_UNDERLINE
);
2087 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_UNDERLINE
);
2088 auto nPos
= m_xUnderlineLB
->get_active();
2089 FontLineStyle eUnder
= static_cast<FontLineStyle
>(m_xUnderlineLB
->get_active_id().toInt32());
2093 //! if there are different underline styles in the selection the
2094 //! item-state in the 'rOldSet' will be invalid. In this case
2095 //! changing the underline style will be allowed if a style is
2096 //! selected in the listbox.
2097 bool bAllowChange
= nPos
!= -1 &&
2098 SfxItemState::DEFAULT
> rOldSet
.GetItemState( nWhich
);
2100 const SvxUnderlineItem
& rItem
= *static_cast<const SvxUnderlineItem
*>(pOld
);
2101 if (rItem
.GetValue() == eUnder
&&
2102 (LINESTYLE_NONE
== eUnder
|| (rItem
.GetColor() == m_xUnderlineColorLB
->GetSelectEntryColor() &&
2103 rItem
.getComplexColor() == m_xUnderlineColorLB
->GetSelectedEntry().getComplexColor())) &&
2112 SvxUnderlineItem
aNewItem( eUnder
, nWhich
);
2113 auto aNamedColor
= m_xUnderlineColorLB
->GetSelectedEntry();
2114 aNewItem
.SetColor(aNamedColor
.m_aColor
);
2115 aNewItem
.setComplexColor(aNamedColor
.getComplexColor());
2116 rSet
->Put(aNewItem
);
2119 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2120 rSet
->InvalidateItem(nWhich
);
2125 nWhich
= GetWhich( SID_ATTR_CHAR_OVERLINE
);
2126 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_OVERLINE
);
2127 nPos
= m_xOverlineLB
->get_active();
2128 FontLineStyle eOver
= static_cast<FontLineStyle
>(m_xOverlineLB
->get_active_id().toInt32());
2132 //! if there are different underline styles in the selection the
2133 //! item-state in the 'rOldSet' will be invalid. In this case
2134 //! changing the underline style will be allowed if a style is
2135 //! selected in the listbox.
2136 bool bAllowChange
= nPos
!= -1 &&
2137 SfxItemState::DEFAULT
> rOldSet
.GetItemState( nWhich
);
2139 const SvxOverlineItem
& rItem
= *static_cast<const SvxOverlineItem
*>(pOld
);
2140 if (rItem
.GetValue() == eOver
&&
2141 (LINESTYLE_NONE
== eOver
|| (rItem
.GetColor() == m_xOverlineColorLB
->GetSelectEntryColor() &&
2142 rItem
.getComplexColor() == m_xOverlineColorLB
->GetSelectedEntry().getComplexColor())) &&
2151 SvxOverlineItem
aNewItem( eOver
, nWhich
);
2152 auto aNamedColor
= m_xOverlineColorLB
->GetSelectedEntry();
2153 aNewItem
.SetColor(aNamedColor
.m_aColor
);
2154 aNewItem
.setComplexColor(aNamedColor
.getComplexColor());
2155 rSet
->Put(aNewItem
);
2158 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2159 rSet
->InvalidateItem(nWhich
);
2164 nWhich
= GetWhich( SID_ATTR_CHAR_STRIKEOUT
);
2165 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_STRIKEOUT
);
2166 nPos
= m_xStrikeoutLB
->get_active();
2167 FontStrikeout eStrike
= static_cast<FontStrikeout
>(m_xStrikeoutLB
->get_active_id().toInt32());
2171 //! if there are different strikeout styles in the selection the
2172 //! item-state in the 'rOldSet' will be invalid. In this case
2173 //! changing the strikeout style will be allowed if a style is
2174 //! selected in the listbox.
2175 bool bAllowChg
= nPos
!= -1 &&
2176 SfxItemState::DEFAULT
> rOldSet
.GetItemState( nWhich
);
2178 const SvxCrossedOutItem
& rItem
= *static_cast<const SvxCrossedOutItem
*>(pOld
);
2179 if ( !m_xStrikeoutLB
->get_sensitive()
2180 || (rItem
.GetValue() == eStrike
&& !bAllowChg
) )
2186 rSet
->Put( SvxCrossedOutItem( eStrike
, nWhich
) );
2189 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2190 rSet
->InvalidateItem(nWhich
);
2195 const SfxItemSet
* pExampleSet
= GetDialogExampleSet();
2196 nWhich
= GetWhich( SID_ATTR_CHAR_WORDLINEMODE
);
2197 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_WORDLINEMODE
);
2198 TriState eState
= m_xIndividualWordsBtn
->get_state();
2199 const SfxPoolItem
* pItem
;
2203 const SvxWordLineModeItem
& rItem
= *static_cast<const SvxWordLineModeItem
*>(pOld
);
2204 if ( rItem
.GetValue() == StateToAttr( eState
) && m_xIndividualWordsBtn
->get_saved_state() == eState
)
2208 if ( !bChanged
&& pExampleSet
&& pExampleSet
->GetItemState( nWhich
, false, &pItem
) == SfxItemState::SET
&&
2209 !StateToAttr( eState
) && static_cast<const SvxWordLineModeItem
*>(pItem
)->GetValue() )
2212 if ( bChanged
&& eState
!= TRISTATE_INDET
)
2214 rSet
->Put( SvxWordLineModeItem( StateToAttr( eState
), nWhich
) );
2217 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2218 rSet
->InvalidateItem(nWhich
);
2223 nWhich
= GetWhich( SID_ATTR_CHAR_EMPHASISMARK
);
2224 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_EMPHASISMARK
);
2225 int nMarkPos
= m_xEmphasisLB
->get_active();
2226 OUString sMarkPos
= m_xEmphasisLB
->get_active_text();
2227 OUString sPosPos
= m_xPositionLB
->get_active_text();
2228 FontEmphasisMark eMark
= static_cast<FontEmphasisMark
>(nMarkPos
);
2229 if (m_xPositionLB
->get_sensitive())
2231 eMark
|= (CHRDLG_POSITION_UNDER
== m_xPositionLB
->get_active_id().toInt32())
2232 ? FontEmphasisMark::PosBelow
: FontEmphasisMark::PosAbove
;
2237 if( rOldSet
.GetItemState( nWhich
) != SfxItemState::DONTCARE
)
2239 const SvxEmphasisMarkItem
& rItem
= *static_cast<const SvxEmphasisMarkItem
*>(pOld
);
2240 if ( rItem
.GetEmphasisMark() == eMark
)
2245 if (rOldSet
.GetItemState( nWhich
) == SfxItemState::DONTCARE
&&
2246 m_xEmphasisLB
->get_saved_value() == sMarkPos
&& m_xPositionLB
->get_saved_value() == sPosPos
)
2253 rSet
->Put( SvxEmphasisMarkItem( eMark
, TypedWhichId
<SvxEmphasisMarkItem
>(nWhich
) ) );
2256 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2257 rSet
->InvalidateItem(nWhich
);
2262 nWhich
= GetWhich( SID_ATTR_CHAR_CASEMAP
);
2263 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_CASEMAP
);
2264 SvxCaseMap eCaseMap
= SvxCaseMap::NotMapped
;
2265 bool bChecked
= false;
2266 auto nCapsPos
= m_xEffectsLB
->get_active();
2269 eCaseMap
= static_cast<SvxCaseMap
>(nCapsPos
);
2275 //! if there are different effect styles in the selection the
2276 //! item-state in the 'rOldSet' will be invalid. In this case
2277 //! changing the effect style will be allowed if a style is
2278 //! selected in the listbox.
2279 bool bAllowChg
= nPos
!= -1 &&
2280 SfxItemState::DEFAULT
> rOldSet
.GetItemState( nWhich
);
2282 const SvxCaseMapItem
& rItem
= *static_cast<const SvxCaseMapItem
*>(pOld
);
2283 if ( rItem
.GetValue() == eCaseMap
&& !bAllowChg
)
2287 if ( bChanged
&& bChecked
)
2289 rSet
->Put( SvxCaseMapItem( eCaseMap
, nWhich
) );
2292 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2293 rSet
->InvalidateItem(nWhich
);
2298 nWhich
= GetWhich(SID_ATTR_CHAR_RELIEF
);
2299 if (m_xReliefLB
->get_value_changed_from_saved())
2301 m_xReliefLB
->save_value();
2302 SvxCharReliefItem
aRelief(static_cast<FontRelief
>(m_xReliefLB
->get_active()), nWhich
);
2307 nWhich
= GetWhich( SID_ATTR_CHAR_CONTOUR
);
2308 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_CONTOUR
);
2309 eState
= m_xOutlineBtn
->get_state();
2313 const SvxContourItem
& rItem
= *static_cast<const SvxContourItem
*>(pOld
);
2314 if ( rItem
.GetValue() == StateToAttr( eState
) && m_xOutlineBtn
->get_saved_state() == eState
)
2318 if ( !bChanged
&& pExampleSet
&& pExampleSet
->GetItemState( nWhich
, false, &pItem
) == SfxItemState::SET
&&
2319 !StateToAttr( eState
) && static_cast<const SvxContourItem
*>(pItem
)->GetValue() )
2322 if ( bChanged
&& eState
!= TRISTATE_INDET
)
2324 rSet
->Put( SvxContourItem( StateToAttr( eState
), nWhich
) );
2327 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2328 rSet
->InvalidateItem(nWhich
);
2333 nWhich
= GetWhich( SID_ATTR_CHAR_SHADOWED
);
2334 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_SHADOWED
);
2335 eState
= m_xShadowBtn
->get_state();
2339 const SvxShadowedItem
& rItem
= *static_cast<const SvxShadowedItem
*>(pOld
);
2340 if ( rItem
.GetValue() == StateToAttr( eState
) && m_xShadowBtn
->get_saved_state() == eState
)
2344 if ( !bChanged
&& pExampleSet
&& pExampleSet
->GetItemState( nWhich
, false, &pItem
) == SfxItemState::SET
&&
2345 !StateToAttr( eState
) && static_cast<const SvxShadowedItem
*>(pItem
)->GetValue() )
2348 if ( bChanged
&& eState
!= TRISTATE_INDET
)
2350 rSet
->Put( SvxShadowedItem( StateToAttr( eState
), nWhich
) );
2353 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2354 rSet
->InvalidateItem(nWhich
);
2359 nWhich
= GetWhich( SID_ATTR_CHAR_HIDDEN
);
2360 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_HIDDEN
);
2361 eState
= m_xHiddenBtn
->get_state();
2366 const SvxCharHiddenItem
& rItem
= *static_cast<const SvxCharHiddenItem
*>(pOld
);
2367 if ( rItem
.GetValue() == StateToAttr( eState
) && m_xHiddenBtn
->get_saved_state() == eState
)
2371 if ( !bChanged
&& pExampleSet
&& pExampleSet
->GetItemState( nWhich
, false, &pItem
) == SfxItemState::SET
&&
2372 !StateToAttr( eState
) && static_cast<const SvxCharHiddenItem
*>(pItem
)->GetValue() )
2375 if ( bChanged
&& eState
!= TRISTATE_INDET
)
2377 rSet
->Put( SvxCharHiddenItem( StateToAttr( eState
), nWhich
) );
2380 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2381 rSet
->InvalidateItem(nWhich
);
2383 bModified
|= FillItemSetColor_Impl( *rSet
);
2388 void SvxCharEffectsPage::DisableControls( sal_uInt16 nDisable
)
2390 if ( ( DISABLE_CASEMAP
& nDisable
) == DISABLE_CASEMAP
)
2392 m_xEffectsFT
->set_sensitive(false);
2393 m_xEffectsLB
->set_sensitive(false);
2397 void SvxCharEffectsPage::PageCreated(const SfxAllItemSet
& aSet
)
2399 const SfxUInt16Item
* pDisableCtlItem
= aSet
.GetItem
<SfxUInt16Item
>(SID_DISABLE_CTL
, false);
2400 const SfxUInt32Item
* pFlagItem
= aSet
.GetItem
<SfxUInt32Item
>(SID_FLAG_TYPE
, false);
2401 if (pDisableCtlItem
)
2402 DisableControls(pDisableCtlItem
->GetValue());
2404 sal_uInt32 nFlags
= pFlagItem
? pFlagItem
->GetValue() : 0;
2405 if ( ( nFlags
& SVX_PREVIEW_CHARACTER
) == SVX_PREVIEW_CHARACTER
)
2406 // the writer uses SID_ATTR_BRUSH as font background
2407 m_bPreviewBackgroundToCharacter
= true;
2408 if ((nFlags
& SVX_ENABLE_CHAR_TRANSPARENCY
) != SVX_ENABLE_CHAR_TRANSPARENCY
)
2410 // Only show these in case client code explicitly wants this.
2411 m_xFontTransparencyFT
->hide();
2412 m_xFontTransparencyMtr
->hide();
2416 // class SvxCharPositionPage ---------------------------------------------
2418 SvxCharPositionPage::SvxCharPositionPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rInSet
)
2419 : SvxCharBasePage(pPage
, pController
, "cui/ui/positionpage.ui", "PositionPage", rInSet
)
2420 , m_nSuperEsc(short(DFLT_ESC_SUPER
))
2421 , m_nSubEsc(short(DFLT_ESC_SUB
))
2422 , m_nScaleWidthItemSetVal(100)
2423 , m_nScaleWidthInitialVal(100)
2424 , m_nSuperProp(sal_uInt8(DFLT_ESC_PROP
))
2425 , m_nSubProp(sal_uInt8(DFLT_ESC_PROP
))
2426 , m_xHighPosBtn(m_xBuilder
->weld_radio_button("superscript"))
2427 , m_xNormalPosBtn(m_xBuilder
->weld_radio_button("normal"))
2428 , m_xLowPosBtn(m_xBuilder
->weld_radio_button("subscript"))
2429 , m_xHighLowFT(m_xBuilder
->weld_label("raiselower"))
2430 , m_xHighLowMF(m_xBuilder
->weld_metric_spin_button("raiselowersb", FieldUnit::PERCENT
))
2431 , m_xHighLowRB(m_xBuilder
->weld_check_button("automatic"))
2432 , m_xFontSizeFT(m_xBuilder
->weld_label("relativefontsize"))
2433 , m_xFontSizeMF(m_xBuilder
->weld_metric_spin_button("fontsizesb", FieldUnit::PERCENT
))
2434 , m_xRotationContainer(m_xBuilder
->weld_widget("rotationcontainer"))
2435 , m_xScalingFT(m_xBuilder
->weld_label("scale"))
2436 , m_xScalingAndRotationFT(m_xBuilder
->weld_label("rotateandscale"))
2437 , m_x0degRB(m_xBuilder
->weld_radio_button("0deg"))
2438 , m_x90degRB(m_xBuilder
->weld_radio_button("90deg"))
2439 , m_x270degRB(m_xBuilder
->weld_radio_button("270deg"))
2440 , m_xFitToLineCB(m_xBuilder
->weld_check_button("fittoline"))
2441 , m_xScaleWidthMF(m_xBuilder
->weld_metric_spin_button("scalewidthsb", FieldUnit::PERCENT
))
2442 , m_xKerningMF(m_xBuilder
->weld_metric_spin_button("kerningsb", FieldUnit::POINT
))
2443 , m_xPairKerningBtn(m_xBuilder
->weld_check_button("pairkerning"))
2445 m_xPreviewWin
.reset(new weld::CustomWeld(*m_xBuilder
, "preview", m_aPreviewWin
));
2447 m_xPreviewWin
->hide();
2452 SvxCharPositionPage::~SvxCharPositionPage()
2457 void SvxCharPositionPage::Initialize()
2459 // to handle the changes of the other pages
2460 SetExchangeSupport();
2462 GetPreviewFont().SetFontSize( Size( 0, 240 ) );
2463 GetPreviewCJKFont().SetFontSize( Size( 0, 240 ) );
2464 GetPreviewCTLFont().SetFontSize( Size( 0, 240 ) );
2466 m_xNormalPosBtn
->set_active(true);
2467 PositionHdl_Impl(*m_xNormalPosBtn
);
2469 Link
<weld::Toggleable
&,void> aLink2
= LINK(this, SvxCharPositionPage
, PositionHdl_Impl
);
2470 m_xHighPosBtn
->connect_toggled(aLink2
);
2471 m_xNormalPosBtn
->connect_toggled(aLink2
);
2472 m_xLowPosBtn
->connect_toggled(aLink2
);
2474 aLink2
= LINK( this, SvxCharPositionPage
, RotationHdl_Impl
);
2475 m_x0degRB
->connect_toggled(aLink2
);
2476 m_x90degRB
->connect_toggled(aLink2
);
2477 m_x270degRB
->connect_toggled(aLink2
);
2479 Link
<weld::MetricSpinButton
&,void> aLink3
= LINK(this, SvxCharPositionPage
, ValueChangedHdl_Impl
);
2480 m_xHighLowMF
->connect_value_changed(aLink3
);
2481 m_xFontSizeMF
->connect_value_changed(aLink3
);
2483 m_xHighLowRB
->connect_toggled(LINK(this, SvxCharPositionPage
, AutoPositionHdl_Impl
));
2484 m_xFitToLineCB
->connect_toggled(LINK(this, SvxCharPositionPage
, FitToLineHdl_Impl
));
2485 m_xKerningMF
->connect_value_changed(LINK(this, SvxCharPositionPage
, KerningModifyHdl_Impl
));
2486 m_xScaleWidthMF
->connect_value_changed(LINK(this, SvxCharPositionPage
, ScaleWidthModifyHdl_Impl
));
2489 void SvxCharPositionPage::UpdatePreview_Impl( sal_uInt8 nProp
, sal_uInt8 nEscProp
, short nEsc
)
2491 SetPrevFontEscapement( nProp
, nEscProp
, nEsc
);
2495 void SvxCharPositionPage::SetEscapement_Impl( SvxEscapement nEsc
)
2497 SvxEscapementItem
aEscItm( nEsc
, SID_ATTR_CHAR_ESCAPEMENT
);
2499 if ( SvxEscapement::Superscript
== nEsc
)
2501 aEscItm
.GetEsc() = m_nSuperEsc
;
2502 aEscItm
.GetProportionalHeight() = m_nSuperProp
;
2504 else if ( SvxEscapement::Subscript
== nEsc
)
2506 aEscItm
.GetEsc() = m_nSubEsc
;
2507 aEscItm
.GetProportionalHeight() = m_nSubProp
;
2510 short nFac
= aEscItm
.GetEsc() < 0 ? -1 : 1;
2512 m_xHighLowMF
->set_value(aEscItm
.GetEsc() * nFac
, FieldUnit::PERCENT
);
2513 m_xFontSizeMF
->set_value(aEscItm
.GetProportionalHeight(), FieldUnit::PERCENT
);
2515 if ( SvxEscapement::Off
== nEsc
)
2517 m_xHighLowFT
->set_sensitive(false);
2518 m_xHighLowMF
->set_sensitive(false);
2519 m_xFontSizeFT
->set_sensitive(false);
2520 m_xFontSizeMF
->set_sensitive(false);
2521 m_xHighLowRB
->set_sensitive(false);
2525 m_xFontSizeFT
->set_sensitive(true);
2526 m_xFontSizeMF
->set_sensitive(true);
2527 m_xHighLowRB
->set_sensitive(true);
2529 if (!m_xHighLowRB
->get_active())
2531 m_xHighLowFT
->set_sensitive(true);
2532 m_xHighLowMF
->set_sensitive(true);
2535 AutoPositionHdl_Impl(*m_xHighLowRB
);
2538 UpdatePreview_Impl( 100, aEscItm
.GetProportionalHeight(), aEscItm
.GetEsc() );
2542 IMPL_LINK_NOARG(SvxCharPositionPage
, PositionHdl_Impl
, weld::Toggleable
&, void)
2544 SvxEscapement nEsc
= SvxEscapement::Off
; // also when pBtn == NULL
2546 if (m_xHighPosBtn
->get_active())
2547 nEsc
= SvxEscapement::Superscript
;
2548 else if (m_xLowPosBtn
->get_active())
2549 nEsc
= SvxEscapement::Subscript
;
2551 SetEscapement_Impl( nEsc
);
2554 IMPL_LINK_NOARG(SvxCharPositionPage
, RotationHdl_Impl
, weld::Toggleable
&, void)
2556 bool bEnable
= false;
2557 if (m_x90degRB
->get_active() || m_x270degRB
->get_active())
2560 OSL_ENSURE(m_x0degRB
->get_active(), "unexpected button");
2561 m_xFitToLineCB
->set_sensitive(bEnable
);
2564 void SvxCharPositionPage::FontModifyHdl_Impl()
2566 sal_uInt8 nEscProp
= static_cast<sal_uInt8
>(m_xFontSizeMF
->get_value(FieldUnit::PERCENT
));
2567 short nEsc
= static_cast<short>(m_xHighLowMF
->get_value(FieldUnit::PERCENT
));
2568 nEsc
*= m_xLowPosBtn
->get_active() ? -1 : 1;
2569 UpdatePreview_Impl( 100, nEscProp
, nEsc
);
2572 IMPL_LINK(SvxCharPositionPage
, AutoPositionHdl_Impl
, weld::Toggleable
&, rBox
, void)
2574 if (rBox
.get_active())
2576 m_xHighLowFT
->set_sensitive(false);
2577 m_xHighLowMF
->set_sensitive(false);
2580 PositionHdl_Impl(m_xHighPosBtn
->get_active() ? *m_xHighPosBtn
2581 : m_xLowPosBtn
->get_active() ? *m_xLowPosBtn
2582 : *m_xNormalPosBtn
);
2585 IMPL_LINK_NOARG(SvxCharPositionPage
, FitToLineHdl_Impl
, weld::Toggleable
&, void)
2587 sal_uInt16 nVal
= m_nScaleWidthInitialVal
;
2588 if (m_xFitToLineCB
->get_active())
2589 nVal
= m_nScaleWidthItemSetVal
;
2590 m_xScaleWidthMF
->set_value(nVal
, FieldUnit::PERCENT
);
2591 m_aPreviewWin
.SetFontWidthScale( nVal
);
2594 IMPL_LINK_NOARG(SvxCharPositionPage
, KerningModifyHdl_Impl
, weld::MetricSpinButton
&, void)
2596 tools::Long nVal
= static_cast<tools::Long
>(m_xKerningMF
->get_value(FieldUnit::POINT
));
2597 nVal
= o3tl::convert(nVal
, o3tl::Length::pt
, o3tl::Length::twip
);
2599 tools::Long nKern
= static_cast<short>(m_xKerningMF
->denormalize(nVal
));
2601 SvxFont
& rFont
= GetPreviewFont();
2602 SvxFont
& rCJKFont
= GetPreviewCJKFont();
2603 SvxFont
& rCTLFont
= GetPreviewCTLFont();
2605 rFont
.SetFixKerning( static_cast<short>(nKern
) );
2606 rCJKFont
.SetFixKerning( static_cast<short>(nKern
) );
2607 rCTLFont
.SetFixKerning( static_cast<short>(nKern
) );
2608 m_aPreviewWin
.Invalidate();
2611 IMPL_LINK(SvxCharPositionPage
, ValueChangedHdl_Impl
, weld::MetricSpinButton
&, rField
, void)
2613 bool bHigh
= m_xHighPosBtn
->get_active();
2614 bool bLow
= m_xLowPosBtn
->get_active();
2615 DBG_ASSERT( bHigh
|| bLow
, "normal position is not valid" );
2617 if (m_xHighLowMF
.get() == &rField
)
2620 m_nSubEsc
= static_cast<short>(m_xHighLowMF
->get_value(FieldUnit::PERCENT
)) * -1;
2622 m_nSuperEsc
= static_cast<short>(m_xHighLowMF
->get_value(FieldUnit::PERCENT
));
2624 else if (m_xFontSizeMF
.get() == &rField
)
2627 m_nSubProp
= static_cast<sal_uInt8
>(m_xFontSizeMF
->get_value(FieldUnit::PERCENT
));
2629 m_nSuperProp
= static_cast<sal_uInt8
>(m_xFontSizeMF
->get_value(FieldUnit::PERCENT
));
2632 FontModifyHdl_Impl();
2635 IMPL_LINK_NOARG(SvxCharPositionPage
, ScaleWidthModifyHdl_Impl
, weld::MetricSpinButton
&, void)
2637 m_aPreviewWin
.SetFontWidthScale(sal_uInt16(m_xScaleWidthMF
->get_value(FieldUnit::PERCENT
)));
2640 DeactivateRC
SvxCharPositionPage::DeactivatePage( SfxItemSet
* _pSet
)
2643 FillItemSet( _pSet
);
2644 return DeactivateRC::LeavePage
;
2647 std::unique_ptr
<SfxTabPage
> SvxCharPositionPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
2649 return std::make_unique
<SvxCharPositionPage
>(pPage
, pController
, *rSet
);
2652 void SvxCharPositionPage::Reset( const SfxItemSet
* rSet
)
2654 OUString sUser
= GetUserData();
2656 if ( !sUser
.isEmpty() )
2659 m_nSuperEsc
= static_cast<short>(o3tl::toInt32(o3tl::getToken(sUser
, 0, ';', nIdx
)));
2660 m_nSubEsc
= static_cast<short>(o3tl::toInt32(o3tl::getToken(sUser
, 0, ';', nIdx
)));
2661 m_nSuperProp
= static_cast<sal_uInt8
>(o3tl::toInt32(o3tl::getToken(sUser
, 0, ';', nIdx
)));
2662 m_nSubProp
= static_cast<sal_uInt8
>(o3tl::toInt32(o3tl::getToken(sUser
, 0, ';', nIdx
)));
2664 m_xHighLowMF
->set_max(MAX_ESC_POS
, FieldUnit::PERCENT
);
2666 //fdo#75307 validate all the entries and discard all of them if any are
2669 if (m_nSuperEsc
< m_xHighLowMF
->get_min(FieldUnit::PERCENT
) || m_nSuperEsc
> m_xHighLowMF
->get_max(FieldUnit::PERCENT
))
2671 if (m_nSubEsc
*-1 < m_xHighLowMF
->get_min(FieldUnit::PERCENT
) || m_nSubEsc
*-1 > m_xHighLowMF
->get_max(FieldUnit::PERCENT
))
2673 if (m_nSuperProp
< m_xFontSizeMF
->get_min(FieldUnit::PERCENT
) || m_nSuperProp
> m_xFontSizeMF
->get_max(FieldUnit::PERCENT
))
2675 if (m_nSubProp
< m_xFontSizeMF
->get_min(FieldUnit::PERCENT
) || m_nSubProp
> m_xFontSizeMF
->get_max(FieldUnit::PERCENT
))
2680 m_nSuperEsc
= DFLT_ESC_SUPER
;
2681 m_nSubEsc
= DFLT_ESC_SUB
;
2682 m_nSuperProp
= DFLT_ESC_PROP
;
2683 m_nSubProp
= DFLT_ESC_PROP
;
2688 sal_uInt8 nEscProp
= 100;
2690 m_xHighLowFT
->set_sensitive(false);
2691 m_xHighLowMF
->set_sensitive(false);
2692 m_xFontSizeFT
->set_sensitive(false);
2693 m_xFontSizeMF
->set_sensitive(false);
2695 SvxFont
& rFont
= GetPreviewFont();
2696 SvxFont
& rCJKFont
= GetPreviewCJKFont();
2697 SvxFont
& rCTLFont
= GetPreviewCTLFont();
2698 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_ESCAPEMENT
);
2700 if ( rSet
->GetItemState( nWhich
) >= SfxItemState::DEFAULT
)
2702 const SvxEscapementItem
& rItem
= static_cast<const SvxEscapementItem
&>(rSet
->Get( nWhich
));
2703 nEsc
= rItem
.GetEsc();
2704 nEscProp
= rItem
.GetProportionalHeight();
2708 m_xHighLowFT
->set_sensitive(true);
2709 m_xHighLowMF
->set_sensitive(true);
2710 m_xFontSizeFT
->set_sensitive(true);
2711 m_xFontSizeMF
->set_sensitive(true);
2714 bool bAutomatic(false);
2719 m_xHighPosBtn
->set_active(true);
2720 if ( nEsc
== DFLT_ESC_AUTO_SUPER
)
2722 nEsc
= .8 * (100 - nEscProp
); //approximation of actual percentage used
2729 m_xLowPosBtn
->set_active(true);
2730 if ( nEsc
== DFLT_ESC_AUTO_SUB
)
2732 nEsc
= .2 * -(100 - nEscProp
); //approximation of actual percentage used
2736 if (!m_xHighLowRB
->get_sensitive())
2738 m_xHighLowRB
->set_sensitive(true);
2740 m_xHighLowRB
->set_active(bAutomatic
);
2742 if (m_xHighLowRB
->get_active())
2744 m_xHighLowFT
->set_sensitive(false);
2745 m_xHighLowMF
->set_sensitive(false);
2747 m_xHighLowMF
->set_value(m_xHighLowMF
->normalize(nFac
* nEsc
), FieldUnit::PERCENT
);
2751 m_xNormalPosBtn
->set_active(true);
2752 m_xHighLowRB
->set_active(true);
2753 PositionHdl_Impl(*m_xNormalPosBtn
);
2755 //the height has to be set after the handler is called to keep the value also if the escapement is zero
2756 m_xFontSizeMF
->set_value(m_xFontSizeMF
->normalize(nEscProp
), FieldUnit::PERCENT
);
2760 m_xHighPosBtn
->set_active(false);
2761 m_xNormalPosBtn
->set_active(false);
2762 m_xLowPosBtn
->set_active(false);
2766 SetPrevFontEscapement( 100, nEscProp
, nEsc
);
2769 nWhich
= GetWhich( SID_ATTR_CHAR_KERNING
);
2771 if ( rSet
->GetItemState( nWhich
) >= SfxItemState::DEFAULT
)
2773 const SvxKerningItem
& rItem
= static_cast<const SvxKerningItem
&>(rSet
->Get( nWhich
));
2774 MapUnit eUnit
= rSet
->GetPool()->GetMetric( nWhich
);
2775 tools::Long nBig
= static_cast<tools::Long
>(m_xKerningMF
->normalize( static_cast<tools::Long
>(rItem
.GetValue()) ));
2776 tools::Long nKerning
= OutputDevice::LogicToLogic(nBig
, eUnit
, MapUnit::MapPoint
);
2778 // set Kerning at the Font, convert into Twips before
2779 tools::Long nKern
= OutputDevice::LogicToLogic(rItem
.GetValue(), eUnit
, MapUnit::MapTwip
);
2780 rFont
.SetFixKerning( static_cast<short>(nKern
) );
2781 rCJKFont
.SetFixKerning( static_cast<short>(nKern
) );
2782 rCTLFont
.SetFixKerning( static_cast<short>(nKern
) );
2784 //the attribute value must be displayed also if it's above/below the maximum allowed value
2785 tools::Long nVal
= static_cast<tools::Long
>(m_xKerningMF
->get_max(FieldUnit::POINT
));
2787 m_xKerningMF
->set_max(nKerning
, FieldUnit::POINT
);
2788 nVal
= static_cast<tools::Long
>(m_xKerningMF
->get_min(FieldUnit::POINT
));
2789 if (nVal
> nKerning
)
2790 m_xKerningMF
->set_min(nKerning
, FieldUnit::POINT
);
2791 m_xKerningMF
->set_value(nKerning
, FieldUnit::POINT
);
2794 m_xKerningMF
->set_text(OUString());
2797 nWhich
= GetWhich( SID_ATTR_CHAR_AUTOKERN
);
2799 if ( rSet
->GetItemState( nWhich
) >= SfxItemState::DEFAULT
)
2801 const SvxAutoKernItem
& rItem
= static_cast<const SvxAutoKernItem
&>(rSet
->Get( nWhich
));
2802 m_xPairKerningBtn
->set_active(rItem
.GetValue());
2805 m_xPairKerningBtn
->set_active(false);
2808 nWhich
= GetWhich( SID_ATTR_CHAR_SCALEWIDTH
);
2809 if ( rSet
->GetItemState( nWhich
) >= SfxItemState::DEFAULT
)
2811 const SvxCharScaleWidthItem
& rItem
= static_cast<const SvxCharScaleWidthItem
&>( rSet
->Get( nWhich
) );
2812 m_nScaleWidthInitialVal
= rItem
.GetValue();
2813 m_xScaleWidthMF
->set_value(m_nScaleWidthInitialVal
, FieldUnit::PERCENT
);
2816 m_xScaleWidthMF
->set_value(100, FieldUnit::PERCENT
);
2818 if ( rSet
->GetItemState( SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
) >= SfxItemState::DEFAULT
)
2819 m_nScaleWidthItemSetVal
= rSet
->Get( SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
).GetValue();
2822 nWhich
= GetWhich( SID_ATTR_CHAR_ROTATED
);
2823 SfxItemState eState
= rSet
->GetItemState( nWhich
);
2824 if( SfxItemState::UNKNOWN
== eState
)
2826 m_xRotationContainer
->hide();
2827 m_xScalingAndRotationFT
->hide();
2828 m_xScalingFT
->show();
2832 m_xRotationContainer
->show();
2833 m_xScalingAndRotationFT
->show();
2834 m_xScalingFT
->hide();
2836 if( eState
>= SfxItemState::DEFAULT
)
2838 const SvxCharRotateItem
& rItem
=
2839 static_cast<const SvxCharRotateItem
&>( rSet
->Get( nWhich
));
2840 if (rItem
.IsBottomToTop())
2841 m_x90degRB
->set_active(true);
2842 else if (rItem
.IsTopToBottom())
2843 m_x270degRB
->set_active(true);
2846 DBG_ASSERT( 0_deg10
== rItem
.GetValue(), "incorrect value" );
2847 m_x0degRB
->set_active(true);
2849 m_xFitToLineCB
->set_active(rItem
.IsFitToLine());
2853 if( eState
== SfxItemState::DONTCARE
)
2855 m_x0degRB
->set_active(false);
2856 m_x90degRB
->set_active(false);
2857 m_x270degRB
->set_active(false);
2860 m_x0degRB
->set_active(true);
2862 m_xFitToLineCB
->set_active(false);
2864 m_xFitToLineCB
->set_sensitive(!m_x0degRB
->get_active());
2866 // is this value set?
2867 if( SfxItemState::UNKNOWN
== rSet
->GetItemState(
2868 SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
))
2869 m_xFitToLineCB
->hide();
2874 void SvxCharPositionPage::ChangesApplied()
2876 m_xHighPosBtn
->save_state();
2877 m_xNormalPosBtn
->save_state();
2878 m_xLowPosBtn
->save_state();
2879 m_xHighLowRB
->save_state();
2880 m_x0degRB
->save_state();
2881 m_x90degRB
->save_state();
2882 m_x270degRB
->save_state();
2883 m_xFitToLineCB
->save_state();
2884 m_xScaleWidthMF
->save_value();
2885 m_xKerningMF
->save_value();
2886 m_xPairKerningBtn
->save_state();
2889 bool SvxCharPositionPage::FillItemSet( SfxItemSet
* rSet
)
2891 // Position (high, normal or low)
2892 const SfxItemSet
& rOldSet
= GetItemSet();
2893 bool bModified
= false, bChanged
= true;
2894 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_ESCAPEMENT
);
2895 const SfxPoolItem
* pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_ESCAPEMENT
);
2896 const bool bHigh
= m_xHighPosBtn
->get_active();
2900 if (bHigh
|| m_xLowPosBtn
->get_active())
2902 if (m_xHighLowRB
->get_active())
2903 nEsc
= bHigh
? DFLT_ESC_AUTO_SUPER
: DFLT_ESC_AUTO_SUB
;
2906 nEsc
= static_cast<short>(m_xHighLowMF
->denormalize(m_xHighLowMF
->get_value(FieldUnit::PERCENT
)));
2907 nEsc
*= (bHigh
? 1 : -1);
2909 nEscProp
= static_cast<sal_uInt8
>(m_xFontSizeMF
->denormalize(m_xFontSizeMF
->get_value(FieldUnit::PERCENT
)));
2919 const SvxEscapementItem
& rItem
= *static_cast<const SvxEscapementItem
*>(pOld
);
2920 if (rItem
.GetEsc() == nEsc
&& rItem
.GetProportionalHeight() == nEscProp
)
2924 if ( !bChanged
&& !m_xHighPosBtn
->get_saved_state() &&
2925 !m_xNormalPosBtn
->get_saved_state() && !m_xLowPosBtn
->get_saved_state() )
2929 ( m_xHighPosBtn
->get_active() || m_xNormalPosBtn
->get_active() || m_xLowPosBtn
->get_active() ) )
2931 rSet
->Put( SvxEscapementItem( nEsc
, nEscProp
, nWhich
) );
2934 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2935 rSet
->InvalidateItem(nWhich
);
2940 nWhich
= GetWhich( SID_ATTR_CHAR_KERNING
);
2941 pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_KERNING
);
2943 MapUnit eUnit
= rSet
->GetPool()->GetMetric( nWhich
);
2945 tools::Long nTmp
= static_cast<tools::Long
>(m_xKerningMF
->get_value(FieldUnit::POINT
));
2946 tools::Long nVal
= OutputDevice::LogicToLogic(nTmp
, MapUnit::MapPoint
, eUnit
);
2947 nKerning
= static_cast<short>(m_xKerningMF
->denormalize( nVal
));
2949 SfxItemState eOldKernState
= rOldSet
.GetItemState( nWhich
, false );
2952 const SvxKerningItem
& rItem
= *static_cast<const SvxKerningItem
*>(pOld
);
2953 if ( (eOldKernState
>= SfxItemState::DEFAULT
|| m_xKerningMF
->get_text().isEmpty()) && rItem
.GetValue() == nKerning
)
2959 rSet
->Put( SvxKerningItem( nKerning
, nWhich
) );
2962 else if ( SfxItemState::DEFAULT
== eOldKernState
)
2963 rSet
->InvalidateItem(nWhich
);
2966 nWhich
= GetWhich( SID_ATTR_CHAR_AUTOKERN
);
2968 if (m_xPairKerningBtn
->get_state_changed_from_saved())
2970 rSet
->Put( SvxAutoKernItem( m_xPairKerningBtn
->get_active(), nWhich
) );
2973 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2974 rSet
->InvalidateItem(nWhich
);
2977 nWhich
= GetWhich( SID_ATTR_CHAR_SCALEWIDTH
);
2978 if (m_xScaleWidthMF
->get_value_changed_from_saved())
2980 rSet
->Put(SvxCharScaleWidthItem(static_cast<sal_uInt16
>(m_xScaleWidthMF
->get_value(FieldUnit::PERCENT
)), TypedWhichId
<SvxCharScaleWidthItem
>(nWhich
)));
2983 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
2984 rSet
->InvalidateItem(nWhich
);
2987 nWhich
= GetWhich( SID_ATTR_CHAR_ROTATED
);
2988 if ( m_x0degRB
->get_state_changed_from_saved() ||
2989 m_x90degRB
->get_state_changed_from_saved() ||
2990 m_x270degRB
->get_state_changed_from_saved() ||
2991 m_xFitToLineCB
->get_state_changed_from_saved() )
2993 SvxCharRotateItem
aItem( 0_deg10
, m_xFitToLineCB
->get_active(), TypedWhichId
<SvxCharRotateItem
>(nWhich
) );
2994 if (m_x90degRB
->get_active())
2995 aItem
.SetBottomToTop();
2996 else if (m_x270degRB
->get_active())
2997 aItem
.SetTopToBottom();
3001 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
3002 rSet
->InvalidateItem(nWhich
);
3008 void SvxCharPositionPage::FillUserData()
3010 static const OUStringLiteral
cTok( u
";" );
3012 OUString sUser
= OUString::number( m_nSuperEsc
) + cTok
+
3013 OUString::number( m_nSubEsc
) + cTok
+
3014 OUString::number( m_nSuperProp
) + cTok
+
3015 OUString::number( m_nSubProp
);
3016 SetUserData( sUser
);
3020 void SvxCharPositionPage::PageCreated(const SfxAllItemSet
& aSet
)
3022 const SfxUInt32Item
* pFlagItem
= aSet
.GetItem
<SfxUInt32Item
>(SID_FLAG_TYPE
, false);
3025 sal_uInt32 nFlags
=pFlagItem
->GetValue();
3026 if ( ( nFlags
& SVX_PREVIEW_CHARACTER
) == SVX_PREVIEW_CHARACTER
)
3027 // the writer uses SID_ATTR_BRUSH as font background
3028 m_bPreviewBackgroundToCharacter
= true;
3031 // class SvxCharTwoLinesPage ------------------------------------------------
3033 SvxCharTwoLinesPage::SvxCharTwoLinesPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rInSet
)
3034 : SvxCharBasePage(pPage
, pController
, "cui/ui/twolinespage.ui", "TwoLinesPage", rInSet
)
3035 , m_nStartBracketPosition( 0 )
3036 , m_nEndBracketPosition( 0 )
3037 , m_xTwoLinesBtn(m_xBuilder
->weld_check_button("twolines"))
3038 , m_xEnclosingFrame(m_xBuilder
->weld_widget("enclosing"))
3039 , m_xStartBracketLB(m_xBuilder
->weld_tree_view("startbracket"))
3040 , m_xEndBracketLB(m_xBuilder
->weld_tree_view("endbracket"))
3042 for (size_t i
= 0; i
< std::size(TWOLINE_OPEN
); ++i
)
3043 m_xStartBracketLB
->append(OUString::number(TWOLINE_OPEN
[i
].second
), CuiResId(TWOLINE_OPEN
[i
].first
));
3044 for (size_t i
= 0; i
< std::size(TWOLINE_CLOSE
); ++i
)
3045 m_xEndBracketLB
->append(OUString::number(TWOLINE_CLOSE
[i
].second
), CuiResId(TWOLINE_CLOSE
[i
].first
));
3047 m_xPreviewWin
.reset(new weld::CustomWeld(*m_xBuilder
, "preview", m_aPreviewWin
));
3049 m_xPreviewWin
->hide();
3054 SvxCharTwoLinesPage::~SvxCharTwoLinesPage()
3058 void SvxCharTwoLinesPage::Initialize()
3060 m_xTwoLinesBtn
->set_active(false);
3061 TwoLinesHdl_Impl(*m_xTwoLinesBtn
);
3063 m_xTwoLinesBtn
->connect_toggled(LINK(this, SvxCharTwoLinesPage
, TwoLinesHdl_Impl
));
3065 Link
<weld::TreeView
&,void> aLink
= LINK(this, SvxCharTwoLinesPage
, CharacterMapHdl_Impl
);
3066 m_xStartBracketLB
->connect_changed(aLink
);
3067 m_xEndBracketLB
->connect_changed(aLink
);
3069 SvxFont
& rFont
= GetPreviewFont();
3070 SvxFont
& rCJKFont
= GetPreviewCJKFont();
3071 SvxFont
& rCTLFont
= GetPreviewCTLFont();
3072 rFont
.SetFontSize( Size( 0, 220 ) );
3073 rCJKFont
.SetFontSize( Size( 0, 220 ) );
3074 rCTLFont
.SetFontSize( Size( 0, 220 ) );
3077 void SvxCharTwoLinesPage::SelectCharacter(weld::TreeView
* pBox
)
3079 bool bStart
= pBox
== m_xStartBracketLB
.get();
3080 SvxCharacterMap
aDlg(GetFrameWeld(), nullptr, nullptr);
3081 aDlg
.DisableFontSelection();
3083 if (aDlg
.run() == RET_OK
)
3085 sal_Unicode cChar
= static_cast<sal_Unicode
>(aDlg
.GetChar());
3086 SetBracket( cChar
, bStart
);
3090 pBox
->select(bStart
? m_nStartBracketPosition
: m_nEndBracketPosition
);
3095 void SvxCharTwoLinesPage::SetBracket( sal_Unicode cBracket
, bool bStart
)
3098 weld::TreeView
* pBox
= bStart
? m_xStartBracketLB
.get() : m_xEndBracketLB
.get();
3103 bool bFound
= false;
3104 for (int i
= 1; i
< pBox
->n_children(); ++i
)
3106 if (pBox
->get_id(i
).toInt32() != CHRDLG_ENCLOSE_SPECIAL_CHAR
)
3108 const sal_Unicode cChar
= pBox
->get_text(i
)[0];
3109 if (cChar
== cBracket
)
3121 pBox
->append_text(OUString(cBracket
));
3122 nEntryPos
= pBox
->n_children() - 1;
3123 pBox
->select(nEntryPos
);
3127 m_nStartBracketPosition
= nEntryPos
;
3129 m_nEndBracketPosition
= nEntryPos
;
3132 IMPL_LINK_NOARG(SvxCharTwoLinesPage
, TwoLinesHdl_Impl
, weld::Toggleable
&, void)
3134 bool bChecked
= m_xTwoLinesBtn
->get_active();
3135 m_xEnclosingFrame
->set_sensitive(bChecked
);
3136 UpdatePreview_Impl();
3139 IMPL_LINK(SvxCharTwoLinesPage
, CharacterMapHdl_Impl
, weld::TreeView
&, rBox
, void)
3141 int nPos
= rBox
.get_selected_index();
3142 if (rBox
.get_id(nPos
).toInt32() == CHRDLG_ENCLOSE_SPECIAL_CHAR
)
3143 SelectCharacter( &rBox
);
3146 bool bStart
= &rBox
== m_xStartBracketLB
.get();
3148 m_nStartBracketPosition
= nPos
;
3150 m_nEndBracketPosition
= nPos
;
3152 UpdatePreview_Impl();
3155 void SvxCharTwoLinesPage::ActivatePage( const SfxItemSet
& rSet
)
3157 SvxCharBasePage::ActivatePage(rSet
);
3160 DeactivateRC
SvxCharTwoLinesPage::DeactivatePage( SfxItemSet
* _pSet
)
3163 FillItemSet( _pSet
);
3164 return DeactivateRC::LeavePage
;
3167 std::unique_ptr
<SfxTabPage
> SvxCharTwoLinesPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
3169 return std::make_unique
<SvxCharTwoLinesPage
>(pPage
, pController
, *rSet
);
3172 void SvxCharTwoLinesPage::Reset( const SfxItemSet
* rSet
)
3174 m_xTwoLinesBtn
->set_active(false);
3175 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_TWO_LINES
);
3176 SfxItemState eState
= rSet
->GetItemState( nWhich
);
3178 if ( eState
>= SfxItemState::DONTCARE
)
3180 const SvxTwoLinesItem
& rItem
= static_cast<const SvxTwoLinesItem
&>(rSet
->Get( nWhich
));
3181 m_xTwoLinesBtn
->set_active(rItem
.GetValue());
3183 if ( rItem
.GetValue() )
3185 SetBracket( rItem
.GetStartBracket(), true );
3186 SetBracket( rItem
.GetEndBracket(), false );
3189 TwoLinesHdl_Impl(*m_xTwoLinesBtn
);
3191 SetPrevFontWidthScale( *rSet
);
3194 bool SvxCharTwoLinesPage::FillItemSet( SfxItemSet
* rSet
)
3196 const SfxItemSet
& rOldSet
= GetItemSet();
3197 bool bModified
= false, bChanged
= true;
3198 sal_uInt16 nWhich
= GetWhich( SID_ATTR_CHAR_TWO_LINES
);
3199 const SfxPoolItem
* pOld
= GetOldItem( *rSet
, SID_ATTR_CHAR_TWO_LINES
);
3200 bool bOn
= m_xTwoLinesBtn
->get_active();
3201 sal_Unicode cStart
= ( bOn
&& m_xStartBracketLB
->get_selected_index() > 0 )
3202 ? m_xStartBracketLB
->get_selected_text()[0] : 0;
3203 sal_Unicode cEnd
= ( bOn
&& m_xEndBracketLB
->get_selected_index() > 0 )
3204 ? m_xEndBracketLB
->get_selected_text()[0] : 0;
3208 const SvxTwoLinesItem
& rItem
= *static_cast<const SvxTwoLinesItem
*>(pOld
);
3209 if ( rItem
.GetValue() == bOn
&&
3210 ( !bOn
|| ( rItem
.GetStartBracket() == cStart
&& rItem
.GetEndBracket() == cEnd
) ) )
3216 rSet
->Put( SvxTwoLinesItem( bOn
, cStart
, cEnd
, nWhich
) );
3219 else if ( SfxItemState::DEFAULT
== rOldSet
.GetItemState( nWhich
, false ) )
3220 rSet
->InvalidateItem(nWhich
);
3225 void SvxCharTwoLinesPage::UpdatePreview_Impl()
3227 sal_Unicode cStart
= m_xStartBracketLB
->get_selected_index() > 0
3228 ? m_xStartBracketLB
->get_selected_text()[0] : 0;
3229 sal_Unicode cEnd
= m_xEndBracketLB
->get_selected_index() > 0
3230 ? m_xEndBracketLB
->get_selected_text()[0] : 0;
3231 m_aPreviewWin
.SetBrackets(cStart
, cEnd
);
3232 m_aPreviewWin
.SetTwoLines(m_xTwoLinesBtn
->get_active());
3233 m_aPreviewWin
.Invalidate();
3236 void SvxCharTwoLinesPage::PageCreated(const SfxAllItemSet
& aSet
)
3238 const SfxUInt32Item
* pFlagItem
= aSet
.GetItem
<SfxUInt32Item
>(SID_FLAG_TYPE
, false);
3241 sal_uInt32 nFlags
=pFlagItem
->GetValue();
3242 if ( ( nFlags
& SVX_PREVIEW_CHARACTER
) == SVX_PREVIEW_CHARACTER
)
3243 // the writer uses SID_ATTR_BRUSH as font background
3244 m_bPreviewBackgroundToCharacter
= true;
3248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */