bump product version to 6.3.0.0.beta1
[LibreOffice.git] / cui / source / tabpages / chardlg.cxx
blobd1340a4463b37d58bf87f80a8949cf37287629b8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <editeng/unolingu.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/idle.hxx>
23 #include <unotools/pathoptions.hxx>
24 #include <svtools/ctrltool.hxx>
25 #include <sfx2/printer.hxx>
26 #include <sfx2/objsh.hxx>
27 #include <sfx2/viewsh.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <svx/dialogs.hrc>
31 #include <svx/svxids.hrc>
32 #include <svx/ucsubset.hxx>
33 #include <svtools/unitconv.hxx>
34 #include <svl/languageoptions.hxx>
35 #include <svx/xtable.hxx>
36 #include <chardlg.hxx>
37 #include <editeng/fontitem.hxx>
38 #include <editeng/postitem.hxx>
39 #include <editeng/udlnitem.hxx>
40 #include <editeng/crossedoutitem.hxx>
41 #include <editeng/contouritem.hxx>
42 #include <editeng/langitem.hxx>
43 #include <editeng/wghtitem.hxx>
44 #include <editeng/fhgtitem.hxx>
45 #include <editeng/shdditem.hxx>
46 #include <editeng/escapementitem.hxx>
47 #include <editeng/wrlmitem.hxx>
48 #include <editeng/cmapitem.hxx>
49 #include <editeng/kernitem.hxx>
50 #include <editeng/blinkitem.hxx>
51 #include <editeng/flstitem.hxx>
52 #include <editeng/autokernitem.hxx>
53 #include <editeng/brushitem.hxx>
54 #include <editeng/colritem.hxx>
55 #include <svx/drawitem.hxx>
56 #include <svx/dlgutil.hxx>
57 #include <dialmgr.hxx>
58 #include <sfx2/htmlmode.hxx>
59 #include <cui/cuicharmap.hxx>
60 #include "chardlg.h"
61 #include <editeng/emphasismarkitem.hxx>
62 #include <editeng/charreliefitem.hxx>
63 #include <editeng/twolinesitem.hxx>
64 #include <editeng/charhiddenitem.hxx>
65 #include <svl/stritem.hxx>
66 #include <editeng/charscaleitem.hxx>
67 #include <editeng/charrotateitem.hxx>
68 #include <officecfg/Office/Common.hxx>
69 #include <svx/svxdlg.hxx>
70 #include <strings.hrc>
71 #include <twolines.hrc>
72 #include <svl/intitem.hxx>
73 #include <sfx2/request.hxx>
74 #include <svx/flagsdef.hxx>
75 #include <FontFeaturesDialog.hxx>
76 #include <sal/log.hxx>
77 #include <osl/diagnose.h>
79 using namespace ::com::sun::star;
81 // static ----------------------------------------------------------------
83 const sal_uInt16 SvxCharNamePage::pNameRanges[] =
85 SID_ATTR_CHAR_FONT,
86 SID_ATTR_CHAR_WEIGHT,
87 SID_ATTR_CHAR_FONTHEIGHT,
88 SID_ATTR_CHAR_FONTHEIGHT,
89 SID_ATTR_CHAR_COLOR,
90 SID_ATTR_CHAR_COLOR,
91 SID_ATTR_CHAR_LANGUAGE,
92 SID_ATTR_CHAR_LANGUAGE,
93 SID_ATTR_CHAR_CJK_FONT,
94 SID_ATTR_CHAR_CJK_WEIGHT,
95 SID_ATTR_CHAR_CTL_FONT,
96 SID_ATTR_CHAR_CTL_WEIGHT,
100 const sal_uInt16 SvxCharEffectsPage::pEffectsRanges[] =
102 SID_ATTR_CHAR_SHADOWED,
103 SID_ATTR_CHAR_UNDERLINE,
104 SID_ATTR_CHAR_COLOR,
105 SID_ATTR_CHAR_COLOR,
106 SID_ATTR_CHAR_CASEMAP,
107 SID_ATTR_CHAR_CASEMAP,
108 SID_ATTR_FLASH,
109 SID_ATTR_FLASH,
110 SID_ATTR_CHAR_EMPHASISMARK,
111 SID_ATTR_CHAR_EMPHASISMARK,
112 SID_ATTR_CHAR_RELIEF,
113 SID_ATTR_CHAR_RELIEF,
114 SID_ATTR_CHAR_HIDDEN,
115 SID_ATTR_CHAR_HIDDEN,
116 SID_ATTR_CHAR_OVERLINE,
117 SID_ATTR_CHAR_OVERLINE,
121 const sal_uInt16 SvxCharPositionPage::pPositionRanges[] =
123 SID_ATTR_CHAR_KERNING,
124 SID_ATTR_CHAR_KERNING,
125 SID_ATTR_CHAR_ESCAPEMENT,
126 SID_ATTR_CHAR_ESCAPEMENT,
127 SID_ATTR_CHAR_AUTOKERN,
128 SID_ATTR_CHAR_AUTOKERN,
129 SID_ATTR_CHAR_ROTATED,
130 SID_ATTR_CHAR_SCALEWIDTH,
131 SID_ATTR_CHAR_WIDTH_FIT_TO_LINE,
132 SID_ATTR_CHAR_WIDTH_FIT_TO_LINE,
136 const sal_uInt16 SvxCharTwoLinesPage::pTwoLinesRanges[] =
138 SID_ATTR_CHAR_TWO_LINES,
139 SID_ATTR_CHAR_TWO_LINES,
143 // C-Function ------------------------------------------------------------
145 static bool StateToAttr( TriState aState )
147 return ( TRISTATE_TRUE == aState );
150 namespace
152 void setPrevFontEscapement(SvxFont& _rFont,sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
154 _rFont.SetPropr( nProp );
155 _rFont.SetProprRel( nEscProp );
156 _rFont.SetEscapement( nEsc );
160 inline SvxFont& SvxCharBasePage::GetPreviewFont()
162 return m_aPreviewWin.GetFont();
165 inline SvxFont& SvxCharBasePage::GetPreviewCJKFont()
167 return m_aPreviewWin.GetCJKFont();
170 inline SvxFont& SvxCharBasePage::GetPreviewCTLFont()
172 return m_aPreviewWin.GetCTLFont();
175 SvxCharBasePage::SvxCharBasePage(TabPageParent pParent, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet& rItemset)
176 : SfxTabPage(pParent, rUIXMLDescription, rID, &rItemset)
177 , m_bPreviewBackgroundToCharacter( false )
181 SvxCharBasePage::~SvxCharBasePage()
185 void SvxCharBasePage::ActivatePage(const SfxItemSet& rSet)
187 m_aPreviewWin.SetFromItemSet(rSet, m_bPreviewBackgroundToCharacter);
190 void SvxCharBasePage::SetPrevFontWidthScale( const SfxItemSet& rSet )
192 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
193 if (rSet.GetItemState(nWhich)>=SfxItemState::DEFAULT)
195 const SvxCharScaleWidthItem &rItem = static_cast<const SvxCharScaleWidthItem&>( rSet.Get( nWhich ) );
196 m_aPreviewWin.SetFontWidthScale(rItem.GetValue());
200 void SvxCharBasePage::SetPrevFontEscapement( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
202 setPrevFontEscapement(GetPreviewFont(),nProp,nEscProp,nEsc);
203 setPrevFontEscapement(GetPreviewCJKFont(),nProp,nEscProp,nEsc);
204 setPrevFontEscapement(GetPreviewCTLFont(),nProp,nEscProp,nEsc);
205 m_aPreviewWin.Invalidate();
209 // SvxCharNamePage_Impl --------------------------------------------------
211 struct SvxCharNamePage_Impl
213 Idle m_aUpdateIdle;
214 OUString m_aNoStyleText;
215 std::unique_ptr<FontList> m_pFontList;
216 int m_nExtraEntryPos;
217 bool m_bInSearchMode;
219 SvxCharNamePage_Impl()
220 : m_nExtraEntryPos(std::numeric_limits<int>::max())
221 , m_bInSearchMode(false)
224 m_aUpdateIdle.SetPriority( TaskPriority::LOWEST );
228 // class SvxCharNamePage -------------------------------------------------
230 SvxCharNamePage::SvxCharNamePage(TabPageParent pParent, const SfxItemSet& rInSet)
231 : SvxCharBasePage(pParent, "cui/ui/charnamepage.ui", "CharNamePage", rInSet)
232 , m_pImpl(new SvxCharNamePage_Impl)
233 , m_xEastFrame(m_xBuilder->weld_widget("asian"))
234 , m_xEastFontNameFT(m_xBuilder->weld_label("eastfontnameft"))
235 , m_xEastFontNameLB(m_xBuilder->weld_combo_box("eastfontnamelb"))
236 , m_xEastFontStyleFT(m_xBuilder->weld_label("eaststyleft"))
237 , m_xEastFontStyleLB(new SvtFontStyleBox(m_xBuilder->weld_combo_box("eaststylelb")))
238 , m_xEastFontSizeFT(m_xBuilder->weld_label("eastsizeft"))
239 , m_xEastFontSizeLB(new SvtFontSizeBox(m_xBuilder->weld_combo_box("eastsizelb")))
240 , m_xEastFontLanguageFT(m_xBuilder->weld_label("eastlangft"))
241 , m_xEastFontLanguageLB(new LanguageBox(m_xBuilder->weld_combo_box("eastlanglb")))
242 , m_xEastFontTypeFT(m_xBuilder->weld_label("eastfontinfo"))
243 , m_xEastFontFeaturesButton(m_xBuilder->weld_button("east_features_button"))
244 , m_xCTLFrame(m_xBuilder->weld_widget("ctl"))
245 , m_xCTLFontNameFT(m_xBuilder->weld_label("ctlfontnameft"))
246 , m_xCTLFontNameLB(m_xBuilder->weld_combo_box("ctlfontnamelb"))
247 , m_xCTLFontStyleFT(m_xBuilder->weld_label("ctlstyleft"))
248 , m_xCTLFontStyleLB(new SvtFontStyleBox(m_xBuilder->weld_combo_box("ctlstylelb")))
249 , m_xCTLFontSizeFT(m_xBuilder->weld_label("ctlsizeft"))
250 , m_xCTLFontSizeLB(new SvtFontSizeBox(m_xBuilder->weld_combo_box("ctlsizelb")))
251 , m_xCTLFontLanguageFT(m_xBuilder->weld_label("ctllangft"))
252 , m_xCTLFontLanguageLB(new LanguageBox(m_xBuilder->weld_combo_box("ctllanglb")))
253 , m_xCTLFontTypeFT(m_xBuilder->weld_label("ctlfontinfo"))
254 , m_xCTLFontFeaturesButton(m_xBuilder->weld_button("ctl_features_button"))
256 m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
257 #ifdef IOS
258 m_xPreviewWin->hide();
259 #endif
260 m_pImpl->m_aNoStyleText = CuiResId( RID_SVXSTR_CHARNAME_NOSTYLE );
262 SvtLanguageOptions aLanguageOptions;
263 bool bShowCJK = aLanguageOptions.IsCJKFontEnabled();
264 bool bShowCTL = aLanguageOptions.IsCTLFontEnabled();
265 bool bShowNonWestern = bShowCJK || bShowCTL;
267 if (bShowNonWestern)
269 m_xWestFrame = m_xBuilder->weld_widget("western");
270 m_xWestFontNameFT = m_xBuilder->weld_label("westfontnameft-cjk");
271 m_xWestFontNameLB = m_xBuilder->weld_combo_box("westfontnamelb-cjk");
272 m_xWestFontStyleFT = m_xBuilder->weld_label("weststyleft-cjk");
273 m_xWestFontSizeFT = m_xBuilder->weld_label("westsizeft-cjk");
275 m_xWestFontStyleLB.reset(new SvtFontStyleBox(m_xBuilder->weld_combo_box("weststylelb-cjk")));
276 m_xWestFontSizeLB.reset(new SvtFontSizeBox(m_xBuilder->weld_combo_box("westsizelb-cjk")));
278 m_xWestFontLanguageFT = m_xBuilder->weld_label("westlangft-cjk");
279 m_xWestFontLanguageLB.reset(new LanguageBox(m_xBuilder->weld_combo_box("westlanglb-cjk")));
280 m_xWestFontTypeFT = m_xBuilder->weld_label("westfontinfo-cjk");
282 m_xWestFontFeaturesButton = m_xBuilder->weld_button("west_features_button-cjk");
284 else
286 m_xWestFrame = m_xBuilder->weld_widget("simple");
287 m_xWestFontNameFT = m_xBuilder->weld_label("westfontnameft-nocjk");
288 m_xWestFontStyleFT = m_xBuilder->weld_label("weststyleft-nocjk");
289 m_xWestFontSizeFT = m_xBuilder->weld_label("westsizeft-nocjk");
291 m_xWestFontLanguageFT = m_xBuilder->weld_label("westlangft-nocjk");
292 m_xWestFontLanguageLB.reset(new LanguageBox(m_xBuilder->weld_combo_box("westlanglb-nocjk")));
293 m_xWestFontTypeFT = m_xBuilder->weld_label("westfontinfo-nocjk");
295 m_xWestFontFeaturesButton = m_xBuilder->weld_button("west_features_button-nocjk");
297 std::unique_ptr<weld::EntryTreeView> xWestFontNameLB = m_xBuilder->weld_entry_tree_view("namegrid", "westfontname-nocjk", "westfontnamelb-nocjk");
298 std::unique_ptr<weld::EntryTreeView> xWestFontStyleLB = m_xBuilder->weld_entry_tree_view("stylegrid", "weststyle-nocjk", "weststylelb-nocjk");
299 std::unique_ptr<weld::EntryTreeView> xWestFontSizeLB = m_xBuilder->weld_entry_tree_view("sizegrid", "westsize-nocjk", "westsizelb-nocjk");
301 // 7 lines in the treeview
302 xWestFontNameLB->set_height_request_by_rows(7);
303 xWestFontStyleLB->set_height_request_by_rows(7);
304 xWestFontSizeLB->set_height_request_by_rows(7);
306 m_xWestFontNameLB = std::move(xWestFontNameLB);
307 m_xWestFontStyleLB.reset(new SvtFontStyleBox(std::move(xWestFontStyleLB)));
308 m_xWestFontSizeLB.reset(new SvtFontSizeBox(std::move(xWestFontSizeLB)));
311 //In MacOSX the standard dialogs name font-name, font-style as
312 //Family, Typeface
313 //In GNOME the standard dialogs name font-name, font-style as
314 //Family, Style
315 //In Windows the standard dialogs name font-name, font-style as
316 //Font, Style
317 #ifdef _WIN32
318 OUString sFontFamilyString(CuiResId(RID_SVXSTR_CHARNAME_FONT));
319 #else
320 OUString sFontFamilyString(CuiResId(RID_SVXSTR_CHARNAME_FAMILY));
321 #endif
322 m_xWestFontNameFT->set_label(sFontFamilyString);
323 m_xEastFontNameFT->set_label(sFontFamilyString);
324 m_xCTLFontNameFT->set_label(sFontFamilyString);
326 #ifdef MACOSX
327 OUString sFontStyleString(CuiResId(RID_SVXSTR_CHARNAME_TYPEFACE));
328 #else
329 OUString sFontStyleString(CuiResId(RID_SVXSTR_CHARNAME_STYLE));
330 #endif
331 m_xWestFontStyleFT->set_label(sFontStyleString);
332 m_xEastFontStyleFT->set_label(sFontStyleString);
333 m_xCTLFontStyleFT->set_label(sFontStyleString);
335 m_xWestFrame->show();
336 m_xEastFrame->set_visible(bShowCJK);
337 m_xCTLFrame->set_visible(bShowCTL);
339 m_xWestFontLanguageLB->SetLanguageList(SvxLanguageListFlags::WESTERN, true, false, true);
340 m_xEastFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CJK, true, false, true);
341 m_xCTLFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CTL, true, false, true);
343 Initialize();
346 SvxCharNamePage::~SvxCharNamePage()
348 disposeOnce();
351 void SvxCharNamePage::dispose()
353 m_pImpl.reset();
354 m_xCTLFontStyleLB.reset();
355 m_xEastFontLanguageLB.reset();
356 m_xWestFontStyleLB.reset();
357 m_xCTLFontSizeLB.reset();
358 m_xEastFontSizeLB.reset();
359 m_xWestFontSizeLB.reset();
360 m_xWestFontLanguageLB.reset();
361 m_xPreviewWin.reset();
362 m_xCTLFontLanguageLB.reset();
363 m_xEastFontLanguageLB.reset();
364 SvxCharBasePage::dispose();
367 void SvxCharNamePage::Initialize()
369 // to handle the changes of the other pages
370 SetExchangeSupport();
372 Link<weld::ComboBox&,void> aLink = LINK(this, SvxCharNamePage, FontModifyComboBoxHdl_Impl);
373 m_xWestFontNameLB->connect_changed(aLink);
374 m_xWestFontStyleLB->connect_changed(aLink);
375 m_xWestFontSizeLB->connect_changed(aLink);
376 m_xWestFontLanguageLB->connect_changed(aLink);
378 m_xWestFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
380 m_xEastFontNameLB->connect_changed(aLink);
381 m_xEastFontStyleLB->connect_changed(aLink);
382 m_xEastFontSizeLB->connect_changed(aLink);
383 m_xEastFontLanguageLB->connect_changed(aLink);
384 m_xEastFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
386 m_xCTLFontNameLB->connect_changed(aLink);
387 m_xCTLFontStyleLB->connect_changed(aLink);
388 m_xCTLFontSizeLB->connect_changed(aLink);
389 m_xCTLFontLanguageLB->connect_changed(aLink);
390 m_xCTLFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
392 m_pImpl->m_aUpdateIdle.SetInvokeHandler( LINK( this, SvxCharNamePage, UpdateHdl_Impl ) );
395 const FontList* SvxCharNamePage::GetFontList() const
397 if ( !m_pImpl->m_pFontList )
399 SfxObjectShell* pDocSh = SfxObjectShell::Current();
401 /* #110771# SvxFontListItem::GetFontList can return NULL */
402 if ( pDocSh )
404 const SfxPoolItem* pItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST );
405 if ( pItem != nullptr )
407 DBG_ASSERT(nullptr != static_cast<const SvxFontListItem*>(pItem)->GetFontList(),
408 "Where is the font list?");
409 m_pImpl->m_pFontList = static_cast<const SvxFontListItem*>(pItem )->GetFontList()->Clone();
412 if(!m_pImpl->m_pFontList)
414 m_pImpl->m_pFontList.reset(new FontList( Application::GetDefaultDevice() ));
418 return m_pImpl->m_pFontList.get();
422 namespace
424 FontMetric calcFontMetrics( SvxFont& _rFont,
425 SvxCharNamePage const * _pPage,
426 const weld::ComboBox* _pFontNameLB,
427 const SvtFontStyleBox* _pFontStyleLB,
428 const SvtFontSizeBox* _pFontSizeLB,
429 const LanguageBox* _pLanguageLB,
430 const FontList* _pFontList,
431 sal_uInt16 _nFontWhich,
432 sal_uInt16 _nFontHeightWhich)
434 Size aSize = _rFont.GetFontSize();
435 aSize.setWidth( 0 );
436 FontMetric aFontMetrics;
437 OUString sFontName(_pFontNameLB->get_active_text());
438 bool bFontAvailable = _pFontList->IsAvailable( sFontName );
439 if (bFontAvailable || _pFontNameLB->get_value_changed_from_saved())
440 aFontMetrics = _pFontList->Get(sFontName, _pFontStyleLB->get_active_text());
441 else
443 //get the font from itemset
444 SfxItemState eState = _pPage->GetItemSet().GetItemState( _nFontWhich );
445 if ( eState >= SfxItemState::DEFAULT )
447 const SvxFontItem* pFontItem = static_cast<const SvxFontItem*>(&( _pPage->GetItemSet().Get( _nFontWhich ) ));
448 aFontMetrics.SetFamilyName(pFontItem->GetFamilyName());
449 aFontMetrics.SetStyleName(pFontItem->GetStyleName());
450 aFontMetrics.SetFamily(pFontItem->GetFamily());
451 aFontMetrics.SetPitch(pFontItem->GetPitch());
452 aFontMetrics.SetCharSet(pFontItem->GetCharSet());
455 if ( _pFontSizeLB->IsRelative() )
457 DBG_ASSERT( _pPage->GetItemSet().GetParent(), "No parent set" );
458 const SvxFontHeightItem& rOldItem = static_cast<const SvxFontHeightItem&>(_pPage->GetItemSet().GetParent()->Get( _nFontHeightWhich ));
460 // old value, scaled
461 long nHeight;
462 if ( _pFontSizeLB->IsPtRelative() )
463 nHeight = rOldItem.GetHeight() + PointToTwips( static_cast<long>(_pFontSizeLB->get_value() / 10) );
464 else
465 nHeight = static_cast<long>(rOldItem.GetHeight() * _pFontSizeLB->get_value() / 100);
467 // conversion twips for the example-window
468 aSize.setHeight(
469 ItemToControl( nHeight, _pPage->GetItemSet().GetPool()->GetMetric( _nFontHeightWhich ), FieldUnit::TWIP ) );
471 else if ( !_pFontSizeLB->get_active_text().isEmpty() )
472 aSize.setHeight( PointToTwips( static_cast<long>(_pFontSizeLB->get_value() / 10) ) );
473 else
474 aSize.setHeight( 200 ); // default 10pt
475 aFontMetrics.SetFontSize( aSize );
477 _rFont.SetLanguage(_pLanguageLB->get_active_id());
479 _rFont.SetFamily( aFontMetrics.GetFamilyType() );
480 _rFont.SetFamilyName( aFontMetrics.GetFamilyName() );
481 _rFont.SetStyleName( aFontMetrics.GetStyleName() );
482 _rFont.SetPitch( aFontMetrics.GetPitch() );
483 _rFont.SetCharSet( aFontMetrics.GetCharSet() );
484 _rFont.SetWeight( aFontMetrics.GetWeight() );
485 _rFont.SetItalic( aFontMetrics.GetItalic() );
486 _rFont.SetFontSize( aFontMetrics.GetFontSize() );
488 return aFontMetrics;
493 void SvxCharNamePage::UpdatePreview_Impl()
495 SvxFont& rFont = GetPreviewFont();
496 SvxFont& rCJKFont = GetPreviewCJKFont();
497 SvxFont& rCTLFont = GetPreviewCTLFont();
498 // Font
499 const FontList* pFontList = GetFontList();
501 FontMetric aWestFontMetric = calcFontMetrics(rFont, this, m_xWestFontNameLB.get(),
502 m_xWestFontStyleLB.get(), m_xWestFontSizeLB.get(), m_xWestFontLanguageLB.get(),
503 pFontList, GetWhich(SID_ATTR_CHAR_FONT),
504 GetWhich(SID_ATTR_CHAR_FONTHEIGHT));
506 m_xWestFontTypeFT->set_label(pFontList->GetFontMapText(aWestFontMetric));
508 FontMetric aEastFontMetric = calcFontMetrics(rCJKFont, this, m_xEastFontNameLB.get(),
509 m_xEastFontStyleLB.get(), m_xEastFontSizeLB.get(), m_xEastFontLanguageLB.get(),
510 pFontList, GetWhich(SID_ATTR_CHAR_CJK_FONT),
511 GetWhich(SID_ATTR_CHAR_CJK_FONTHEIGHT));
513 m_xEastFontTypeFT->set_label(pFontList->GetFontMapText(aEastFontMetric));
515 FontMetric aCTLFontMetric = calcFontMetrics(rCTLFont,
516 this, m_xCTLFontNameLB.get(), m_xCTLFontStyleLB.get(), m_xCTLFontSizeLB.get(),
517 m_xCTLFontLanguageLB.get(), pFontList, GetWhich(SID_ATTR_CHAR_CTL_FONT),
518 GetWhich(SID_ATTR_CHAR_CTL_FONTHEIGHT));
520 m_xCTLFontTypeFT->set_label(pFontList->GetFontMapText(aCTLFontMetric));
522 m_aPreviewWin.Invalidate();
525 void SvxCharNamePage::FillStyleBox_Impl(const weld::Widget& rNameBox)
527 const FontList* pFontList = GetFontList();
528 DBG_ASSERT( pFontList, "no fontlist" );
530 SvtFontStyleBox* pStyleBox = nullptr;
531 OUString sFontName;
533 if (m_xWestFontNameLB.get() == &rNameBox)
535 pStyleBox = m_xWestFontStyleLB.get();
536 sFontName = m_xWestFontNameLB->get_active_text();
538 else if (m_xEastFontNameLB.get() == &rNameBox)
540 pStyleBox = m_xEastFontStyleLB.get();
541 sFontName = m_xEastFontStyleLB->get_active_text();
543 else if (m_xCTLFontNameLB.get() == &rNameBox)
545 pStyleBox = m_xCTLFontStyleLB.get();
546 sFontName = m_xCTLFontNameLB->get_active_text();
548 else
550 SAL_WARN( "cui.tabpages", "invalid font name box" );
551 return;
554 pStyleBox->Fill(sFontName, pFontList);
556 if ( m_pImpl->m_bInSearchMode )
558 // additional entries for the search:
559 // "not bold" and "not italic"
560 OUString aEntry = m_pImpl->m_aNoStyleText;
561 const sal_Char sS[] = "%1";
562 aEntry = aEntry.replaceFirst( sS, pFontList->GetBoldStr() );
563 m_pImpl->m_nExtraEntryPos = pStyleBox->get_count();
564 pStyleBox->append_text( aEntry );
565 aEntry = m_pImpl->m_aNoStyleText;
566 aEntry = aEntry.replaceFirst( sS, pFontList->GetItalicStr() );
567 pStyleBox->append_text(aEntry);
571 void SvxCharNamePage::FillSizeBox_Impl(const weld::Widget& rNameBox)
573 const FontList* pFontList = GetFontList();
574 DBG_ASSERT( pFontList, "no fontlist" );
576 SvtFontStyleBox* pStyleBox = nullptr;
577 SvtFontSizeBox* pSizeBox = nullptr;
578 OUString sFontName;
580 if (m_xWestFontNameLB.get() == &rNameBox)
582 pStyleBox = m_xWestFontStyleLB.get();
583 pSizeBox = m_xWestFontSizeLB.get();
584 sFontName = m_xWestFontNameLB->get_active_text();
586 else if (m_xEastFontNameLB.get() == &rNameBox)
588 pStyleBox = m_xEastFontStyleLB.get();
589 pSizeBox = m_xEastFontSizeLB.get();
590 sFontName = m_xEastFontNameLB->get_active_text();
592 else if (m_xCTLFontNameLB.get() == &rNameBox)
594 pStyleBox = m_xCTLFontStyleLB.get();
595 pSizeBox = m_xCTLFontSizeLB.get();
596 sFontName = m_xCTLFontNameLB->get_active_text();
598 else
600 SAL_WARN( "cui.tabpages", "invalid font name box" );
601 return;
604 FontMetric _aFontMetric(pFontList->Get(sFontName, pStyleBox->get_active_text()));
605 pSizeBox->Fill( &_aFontMetric, pFontList );
608 namespace
610 void FillFontNames(weld::ComboBox& rBox, const FontList& rList)
612 // insert fonts
613 sal_uInt16 nFontCount = rList.GetFontNameCount();
614 std::vector<weld::ComboBoxEntry> aVector;
615 aVector.reserve(nFontCount);
616 for (sal_uInt16 i = 0; i < nFontCount; ++i)
618 const FontMetric& rFontMetric = rList.GetFontName(i);
619 aVector.emplace_back(rFontMetric.GetFamilyName());
621 rBox.insert_vector(aVector, false);
625 void SvxCharNamePage::Reset_Impl( const SfxItemSet& rSet, LanguageGroup eLangGrp )
627 weld::ComboBox* pNameBox = nullptr;
628 weld::Label* pStyleLabel = nullptr;
629 SvtFontStyleBox* pStyleBox = nullptr;
630 weld::Label* pSizeLabel = nullptr;
631 SvtFontSizeBox* pSizeBox = nullptr;
632 weld::Label* pLangFT = nullptr;
633 LanguageBox* pLangBox = nullptr;
634 sal_uInt16 nWhich = 0;
636 switch ( eLangGrp )
638 case Western :
639 pNameBox = m_xWestFontNameLB.get();
640 pStyleLabel = m_xWestFontStyleFT.get();
641 pStyleBox = m_xWestFontStyleLB.get();
642 pSizeLabel = m_xWestFontSizeFT.get();
643 pSizeBox = m_xWestFontSizeLB.get();
644 pLangFT = m_xWestFontLanguageFT.get();
645 pLangBox = m_xWestFontLanguageLB.get();
646 nWhich = GetWhich( SID_ATTR_CHAR_FONT );
647 break;
649 case Asian :
650 pNameBox = m_xEastFontNameLB.get();
651 pStyleLabel = m_xEastFontStyleFT.get();
652 pStyleBox = m_xEastFontStyleLB.get();
653 pSizeLabel = m_xEastFontSizeFT.get();
654 pSizeBox = m_xEastFontSizeLB.get();
655 pLangFT = m_xEastFontLanguageFT.get();
656 pLangBox = m_xEastFontLanguageLB.get();
657 nWhich = GetWhich( SID_ATTR_CHAR_CJK_FONT );
658 break;
660 case Ctl :
661 pNameBox = m_xCTLFontNameLB.get();
662 pStyleLabel = m_xCTLFontStyleFT.get();
663 pStyleBox = m_xCTLFontStyleLB.get();
664 pSizeLabel = m_xCTLFontSizeFT.get();
665 pSizeBox = m_xCTLFontSizeLB.get();
666 pLangFT = m_xCTLFontLanguageFT.get();
667 pLangBox = m_xCTLFontLanguageLB.get();
668 nWhich = GetWhich( SID_ATTR_CHAR_CTL_FONT );
669 break;
672 const FontList* pFontList = GetFontList();
673 FillFontNames(*pNameBox, *pFontList);
675 const SvxFontItem* pFontItem = nullptr;
676 SfxItemState eState = rSet.GetItemState( nWhich );
678 if ( eState >= SfxItemState::DEFAULT )
680 pFontItem = static_cast<const SvxFontItem*>(&( rSet.Get( nWhich ) ));
681 const OUString &rName = pFontItem->GetFamilyName();
682 int nIndex = pNameBox->find_text(rName);
683 pNameBox->set_active(nIndex);
684 // tdf#122992 if it didn't exist in the list, set the entry text to it anyway
685 if (nIndex == -1)
686 pNameBox->set_entry_text(rName);
688 else
690 pNameBox->set_active_text( OUString() );
693 FillStyleBox_Impl(*pNameBox);
695 bool bStyle = false;
696 bool bStyleAvailable = true;
697 FontItalic eItalic = ITALIC_NONE;
698 FontWeight eWeight = WEIGHT_NORMAL;
699 switch ( eLangGrp )
701 case Western : nWhich = GetWhich( SID_ATTR_CHAR_POSTURE ); break;
702 case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_POSTURE ); break;
703 case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_POSTURE ); break;
705 eState = rSet.GetItemState( nWhich );
707 if ( eState >= SfxItemState::DEFAULT )
709 const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(rSet.Get( nWhich ));
710 eItalic = rItem.GetValue();
711 bStyle = true;
713 bStyleAvailable = bStyleAvailable && (eState >= SfxItemState::DONTCARE);
715 switch ( eLangGrp )
717 case Western : nWhich = GetWhich( SID_ATTR_CHAR_WEIGHT ); break;
718 case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_WEIGHT ); break;
719 case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_WEIGHT ); break;
721 eState = rSet.GetItemState( nWhich );
723 if ( eState >= SfxItemState::DEFAULT )
725 const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(rSet.Get( nWhich ));
726 eWeight = rItem.GetValue();
728 else
729 bStyle = false;
730 bStyleAvailable = bStyleAvailable && (eState >= SfxItemState::DONTCARE);
732 // currently chosen font
733 if ( bStyle && pFontItem )
735 FontMetric aFontMetric = pFontList->Get( pFontItem->GetFamilyName(), eWeight, eItalic );
736 pStyleBox->set_active_text( pFontList->GetStyleName( aFontMetric ) );
738 else if ( !m_pImpl->m_bInSearchMode || !bStyle )
740 pStyleBox->set_active_text( OUString() );
742 else if ( bStyle )
744 FontMetric aFontMetric = pFontList->Get( OUString(), eWeight, eItalic );
745 pStyleBox->set_active_text( pFontList->GetStyleName( aFontMetric ) );
747 if (!bStyleAvailable)
749 pStyleBox->set_sensitive(false);
750 pStyleLabel->set_sensitive(false);
753 FillSizeBox_Impl(*pNameBox);
754 switch ( eLangGrp )
756 case Western : nWhich = GetWhich( SID_ATTR_CHAR_FONTHEIGHT ); break;
757 case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT ); break;
758 case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT ); break;
760 eState = rSet.GetItemState( nWhich );
762 if ( pSizeBox->IsRelativeMode() )
764 MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
765 const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich ));
767 if( rItem.GetProp() != 100 || MapUnit::MapRelative != rItem.GetPropUnit() )
769 bool bPtRel = MapUnit::MapPoint == rItem.GetPropUnit();
770 pSizeBox->SetPtRelative( bPtRel );
771 pSizeBox->set_value( bPtRel ? static_cast<short>(rItem.GetProp()) * 10 : rItem.GetProp() );
773 else
775 pSizeBox->SetRelative(false);
776 pSizeBox->set_value( CalcToPoint( rItem.GetHeight(), eUnit, 10 ) );
779 else if ( eState >= SfxItemState::DEFAULT )
781 MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
782 const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich ));
783 pSizeBox->set_value( CalcToPoint( rItem.GetHeight(), eUnit, 10 ) );
785 else
787 pSizeBox->set_active_text( OUString() );
788 if ( eState <= SfxItemState::READONLY )
790 pSizeBox->set_sensitive(false);
791 pSizeLabel->set_sensitive(false);
795 switch ( eLangGrp )
797 case Western : nWhich = GetWhich( SID_ATTR_CHAR_LANGUAGE ); break;
798 case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_LANGUAGE ); break;
799 case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_LANGUAGE ); break;
801 pLangBox->set_active(-1);
802 eState = rSet.GetItemState( nWhich );
804 switch ( eState )
806 case SfxItemState::UNKNOWN:
807 pLangFT->hide();
808 pLangBox->hide();
809 break;
811 case SfxItemState::DISABLED:
812 case SfxItemState::READONLY:
813 pLangFT->set_sensitive(false);
814 pLangBox->set_sensitive(false);
815 break;
817 case SfxItemState::DEFAULT:
818 case SfxItemState::SET:
820 const SvxLanguageItem& rItem = static_cast<const SvxLanguageItem&>(rSet.Get( nWhich ));
821 LanguageType eLangType = rItem.GetValue();
822 DBG_ASSERT( eLangType != LANGUAGE_SYSTEM, "LANGUAGE_SYSTEM not allowed" );
823 if (eLangType != LANGUAGE_DONTKNOW)
824 pLangBox->set_active_id(eLangType);
825 break;
827 case SfxItemState::DONTCARE:
828 break;
831 OUString sMapText(pFontList->GetFontMapText(
832 pFontList->Get(pNameBox->get_active_text(), pStyleBox->get_active_text())));
834 switch (eLangGrp)
836 case Western:
837 m_xWestFontTypeFT->set_label(sMapText);
838 break;
839 case Asian:
840 m_xEastFontTypeFT->set_label(sMapText);
841 break;
842 case Ctl:
843 m_xCTLFontTypeFT->set_label(sMapText);
844 break;
847 // save these settings
848 pNameBox->save_value();
849 pStyleBox->save_value();
850 pSizeBox->save_value();
851 pLangBox->save_active_id();
854 bool SvxCharNamePage::FillItemSet_Impl( SfxItemSet& rSet, LanguageGroup eLangGrp )
856 bool bModified = false;
858 weld::ComboBox* pNameBox = nullptr;
859 SvtFontStyleBox* pStyleBox = nullptr;
860 SvtFontSizeBox* pSizeBox = nullptr;
861 LanguageBox* pLangBox = nullptr;
862 sal_uInt16 nWhich = 0;
863 sal_uInt16 nSlot = 0;
865 switch ( eLangGrp )
867 case Western :
868 pNameBox = m_xWestFontNameLB.get();
869 pStyleBox = m_xWestFontStyleLB.get();
870 pSizeBox = m_xWestFontSizeLB.get();
871 pLangBox = m_xWestFontLanguageLB.get();
872 nSlot = SID_ATTR_CHAR_FONT;
873 break;
875 case Asian :
876 pNameBox = m_xEastFontNameLB.get();
877 pStyleBox = m_xEastFontStyleLB.get();
878 pSizeBox = m_xEastFontSizeLB.get();
879 pLangBox = m_xEastFontLanguageLB.get();
880 nSlot = SID_ATTR_CHAR_CJK_FONT;
881 break;
883 case Ctl :
884 pNameBox = m_xCTLFontNameLB.get();
885 pStyleBox = m_xCTLFontStyleLB.get();
886 pSizeBox = m_xCTLFontSizeLB.get();
887 pLangBox = m_xCTLFontLanguageLB.get();
888 nSlot = SID_ATTR_CHAR_CTL_FONT;
889 break;
892 nWhich = GetWhich( nSlot );
893 const SfxPoolItem* pItem = nullptr;
894 const SfxItemSet& rOldSet = GetItemSet();
895 const SfxPoolItem* pOld = nullptr;
897 const SfxItemSet* pExampleSet = GetDialogExampleSet();
899 bool bChanged = true;
900 const OUString& rFontName = pNameBox->get_active_text();
901 const FontList* pFontList = GetFontList();
902 OUString aStyleBoxText = pStyleBox->get_active_text();
903 int nEntryPos = pStyleBox->find_text(aStyleBoxText);
904 if (nEntryPos >= m_pImpl->m_nExtraEntryPos)
905 aStyleBoxText.clear();
906 FontMetric aInfo( pFontList->Get( rFontName, aStyleBoxText ) );
907 SvxFontItem aFontItem( aInfo.GetFamilyType(), aInfo.GetFamilyName(), aInfo.GetStyleName(),
908 aInfo.GetPitch(), aInfo.GetCharSet(), nWhich );
909 pOld = GetOldItem( rSet, nSlot );
911 if ( pOld )
913 const SvxFontItem& rItem = *static_cast<const SvxFontItem*>(pOld);
915 if ( rItem.GetFamilyName() == aFontItem.GetFamilyName() )
916 bChanged = false;
919 if ( !bChanged )
920 bChanged = pNameBox->get_saved_value().isEmpty();
922 if ( !bChanged && pExampleSet &&
923 pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
924 static_cast<const SvxFontItem*>(pItem)->GetFamilyName() != aFontItem.GetFamilyName() )
925 bChanged = true;
927 if ( bChanged && !rFontName.isEmpty() )
929 rSet.Put( aFontItem );
930 bModified = true;
932 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
933 rSet.ClearItem( nWhich );
936 bChanged = true;
937 switch ( eLangGrp )
939 case Western : nSlot = SID_ATTR_CHAR_WEIGHT; break;
940 case Asian : nSlot = SID_ATTR_CHAR_CJK_WEIGHT; break;
941 case Ctl : nSlot = SID_ATTR_CHAR_CTL_WEIGHT; break;
943 nWhich = GetWhich( nSlot );
944 FontWeight eWeight = aInfo.GetWeight();
945 if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
946 eWeight = WEIGHT_NORMAL;
947 SvxWeightItem aWeightItem( eWeight, nWhich );
948 pOld = GetOldItem( rSet, nSlot );
950 if ( pOld )
952 const SvxWeightItem& rItem = *static_cast<const SvxWeightItem*>(pOld);
954 if ( rItem.GetValue() == aWeightItem.GetValue() )
955 bChanged = false;
958 if ( !bChanged )
960 bChanged = pStyleBox->get_saved_value().isEmpty();
962 if ( m_pImpl->m_bInSearchMode && bChanged &&
963 aInfo.GetWeight() == WEIGHT_NORMAL && aInfo.GetItalic() != ITALIC_NONE )
964 bChanged = true;
967 if ( !bChanged && pExampleSet &&
968 pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
969 static_cast<const SvxWeightItem*>(pItem)->GetValue() != aWeightItem.GetValue() )
970 bChanged = true;
972 if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
973 bChanged = ( nEntryPos == m_pImpl->m_nExtraEntryPos );
975 OUString aText( pStyleBox->get_active_text() ); // Tristate, then text empty
977 if ( bChanged && !aText.isEmpty() )
979 rSet.Put( aWeightItem );
980 bModified = true;
982 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
983 rSet.InvalidateItem(nWhich);
985 bChanged = true;
986 switch ( eLangGrp )
988 case Western : nSlot = SID_ATTR_CHAR_POSTURE; break;
989 case Asian : nSlot = SID_ATTR_CHAR_CJK_POSTURE; break;
990 case Ctl : nSlot = SID_ATTR_CHAR_CTL_POSTURE; break;
992 nWhich = GetWhich( nSlot );
993 FontItalic eItalic = aInfo.GetItalic();
994 if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
995 eItalic = ITALIC_NONE;
996 SvxPostureItem aPostureItem( eItalic, nWhich );
997 pOld = GetOldItem( rSet, nSlot );
999 if ( pOld )
1001 const SvxPostureItem& rItem = *static_cast<const SvxPostureItem*>(pOld);
1003 if ( rItem.GetValue() == aPostureItem.GetValue() )
1004 bChanged = false;
1007 if ( !bChanged )
1009 bChanged = pStyleBox->get_saved_value().isEmpty();
1011 if ( m_pImpl->m_bInSearchMode && bChanged &&
1012 aInfo.GetItalic() == ITALIC_NONE && aInfo.GetWeight() != WEIGHT_NORMAL )
1013 bChanged = false;
1016 if ( !bChanged && pExampleSet &&
1017 pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
1018 static_cast<const SvxPostureItem*>(pItem)->GetValue() != aPostureItem.GetValue() )
1019 bChanged = true;
1021 if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
1022 bChanged = ( nEntryPos == ( m_pImpl->m_nExtraEntryPos + 1 ) );
1024 if ( bChanged && !aText.isEmpty() )
1026 rSet.Put( aPostureItem );
1027 bModified = true;
1029 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
1030 rSet.InvalidateItem(nWhich);
1032 // FontSize
1033 long nSize = pSizeBox->get_value();
1035 if ( pSizeBox->get_active_text().isEmpty() ) // GetValue() returns the min-value
1036 nSize = 0;
1037 long nSavedSize = pSizeBox->get_saved_value();
1038 const bool bRel = pSizeBox->IsRelative();
1040 switch ( eLangGrp )
1042 case Western : nSlot = SID_ATTR_CHAR_FONTHEIGHT; break;
1043 case Asian : nSlot = SID_ATTR_CHAR_CJK_FONTHEIGHT; break;
1044 case Ctl : nSlot = SID_ATTR_CHAR_CTL_FONTHEIGHT; break;
1046 nWhich = GetWhich( nSlot );
1047 const SvxFontHeightItem* pOldHeight = static_cast<const SvxFontHeightItem*>(GetOldItem( rSet, nSlot ));
1048 bChanged = ( nSize != nSavedSize );
1050 if ( !bChanged && pExampleSet &&
1051 pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET )
1053 float fSize = static_cast<float>(nSize) / 10;
1054 long nVal = CalcToUnit( fSize, rSet.GetPool()->GetMetric( nWhich ) );
1055 if ( static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() != static_cast<sal_uInt32>(nVal) )
1056 bChanged = true;
1059 if ( bChanged || !pOldHeight ||
1060 bRel != ( MapUnit::MapRelative != pOldHeight->GetPropUnit() || 100 != pOldHeight->GetProp() ) )
1062 MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
1063 if ( pSizeBox->IsRelative() )
1065 DBG_ASSERT( GetItemSet().GetParent(), "No parent set" );
1066 const SvxFontHeightItem& rOldItem =
1067 static_cast<const SvxFontHeightItem&>(GetItemSet().GetParent()->Get( nWhich ));
1069 SvxFontHeightItem aHeight( 240, 100, nWhich );
1070 if ( pSizeBox->IsPtRelative() )
1071 aHeight.SetHeight( rOldItem.GetHeight(), static_cast<sal_uInt16>( nSize / 10 ), MapUnit::MapPoint, eUnit );
1072 else
1073 aHeight.SetHeight( rOldItem.GetHeight(), static_cast<sal_uInt16>(nSize) );
1074 rSet.Put( aHeight );
1076 else
1078 float fSize = static_cast<float>(nSize) / 10;
1079 rSet.Put( SvxFontHeightItem( CalcToUnit( fSize, eUnit ), 100, nWhich ) );
1081 bModified = true;
1083 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
1084 rSet.InvalidateItem(nWhich);
1086 bChanged = true;
1087 switch ( eLangGrp )
1089 case Western : nSlot = SID_ATTR_CHAR_LANGUAGE; break;
1090 case Asian : nSlot = SID_ATTR_CHAR_CJK_LANGUAGE; break;
1091 case Ctl : nSlot = SID_ATTR_CHAR_CTL_LANGUAGE; break;
1093 nWhich = GetWhich( nSlot );
1094 pOld = GetOldItem( rSet, nSlot );
1096 // For language list boxes acting as ComboBox, check for, add and select an
1097 // edited entry.
1098 if (pLangBox == m_xWestFontLanguageLB.get())
1100 switch (pLangBox->GetEditedAndValid())
1102 case LanguageBox::EditedAndValid::No:
1103 ; // nothing to do
1104 break;
1105 case LanguageBox::EditedAndValid::Valid:
1107 const int nPos = pLangBox->SaveEditedAsEntry();
1108 if (nPos != -1)
1109 pLangBox->set_active(nPos);
1111 break;
1112 case LanguageBox::EditedAndValid::Invalid:
1113 pLangBox->set_active_id(pLangBox->get_saved_active_id());
1114 break;
1118 int nLangPos = pLangBox->get_active();
1119 LanguageType eLangType = pLangBox->get_active_id();
1121 if (pOld)
1123 const SvxLanguageItem& rItem = *static_cast<const SvxLanguageItem*>(pOld);
1124 if (nLangPos == -1 || eLangType == rItem.GetValue())
1125 bChanged = false;
1128 if (!bChanged)
1129 bChanged = pLangBox->get_active_id_changed_from_saved();
1131 if (bChanged && nLangPos != -1)
1133 rSet.Put(SvxLanguageItem(eLangType, nWhich));
1134 bModified = true;
1136 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
1137 rSet.InvalidateItem(nWhich);
1139 return bModified;
1142 IMPL_LINK_NOARG(SvxCharNamePage, UpdateHdl_Impl, Timer *, void)
1144 UpdatePreview_Impl();
1147 IMPL_LINK(SvxCharNamePage, FontModifyComboBoxHdl_Impl, weld::ComboBox&, rBox, void)
1149 FontModifyHdl_Impl(rBox);
1152 IMPL_LINK(SvxCharNamePage, FontModifyEditHdl_Impl, weld::Entry&, rBox, void)
1154 FontModifyHdl_Impl(rBox);
1157 IMPL_LINK(SvxCharNamePage, FontFeatureButtonClicked, weld::Button&, rButton, void)
1159 OUString sFontName;
1160 weld::ComboBox* pNameBox = nullptr;
1162 if (&rButton == m_xWestFontFeaturesButton.get())
1164 pNameBox = m_xWestFontNameLB.get();
1165 sFontName = GetPreviewFont().GetFamilyName();
1167 else if (&rButton == m_xEastFontFeaturesButton.get())
1169 pNameBox = m_xEastFontNameLB.get();
1170 sFontName = GetPreviewCJKFont().GetFamilyName();
1172 else if (&rButton == m_xCTLFontFeaturesButton.get())
1174 pNameBox = m_xCTLFontNameLB.get();
1175 sFontName = GetPreviewCTLFont().GetFamilyName();
1178 if (!sFontName.isEmpty() && pNameBox)
1180 cui::FontFeaturesDialog aDialog(GetDialogFrameWeld(), sFontName);
1181 if (aDialog.run() == RET_OK)
1183 pNameBox->set_entry_text(aDialog.getResultFontName());
1184 UpdatePreview_Impl();
1189 void SvxCharNamePage::FontModifyHdl_Impl(const weld::Widget& rNameBox)
1191 m_pImpl->m_aUpdateIdle.Start();
1193 if (m_xWestFontNameLB.get() == &rNameBox || m_xEastFontNameLB.get() == &rNameBox || m_xCTLFontNameLB.get() == &rNameBox)
1195 FillStyleBox_Impl(rNameBox);
1196 FillSizeBox_Impl(rNameBox);
1200 void SvxCharNamePage::ActivatePage( const SfxItemSet& rSet )
1202 SvxCharBasePage::ActivatePage( rSet );
1204 UpdatePreview_Impl(); // instead of asynchronous calling in ctor
1207 DeactivateRC SvxCharNamePage::DeactivatePage( SfxItemSet* _pSet )
1209 if ( _pSet )
1210 FillItemSet( _pSet );
1211 return DeactivateRC::LeavePage;
1214 VclPtr<SfxTabPage> SvxCharNamePage::Create(TabPageParent pParent, const SfxItemSet* rSet)
1216 return VclPtr<SvxCharNamePage>::Create(pParent, *rSet );
1219 void SvxCharNamePage::Reset( const SfxItemSet* rSet )
1221 Reset_Impl( *rSet, Western );
1222 Reset_Impl( *rSet, Asian );
1223 Reset_Impl( *rSet, Ctl );
1225 SetPrevFontWidthScale( *rSet );
1226 UpdatePreview_Impl();
1229 void SvxCharNamePage::ChangesApplied()
1231 m_xWestFontNameLB->save_value();
1232 m_xWestFontStyleLB->save_value();
1233 m_xWestFontSizeLB->save_value();
1234 m_xWestFontLanguageLB->save_active_id();
1235 m_xEastFontNameLB->save_value();
1236 m_xEastFontStyleLB->save_value();
1237 m_xEastFontSizeLB->save_value();
1238 m_xEastFontLanguageLB->save_active_id();
1239 m_xCTLFontNameLB->save_value();
1240 m_xCTLFontStyleLB->save_value();
1241 m_xCTLFontSizeLB->save_value();
1242 m_xCTLFontLanguageLB->save_active_id();
1245 bool SvxCharNamePage::FillItemSet( SfxItemSet* rSet )
1247 bool bModified = FillItemSet_Impl( *rSet, Western );
1248 bModified |= FillItemSet_Impl( *rSet, Asian );
1249 bModified |= FillItemSet_Impl( *rSet, Ctl );
1250 return bModified;
1253 void SvxCharNamePage::SetFontList( const SvxFontListItem& rItem )
1255 m_pImpl->m_pFontList = rItem.GetFontList()->Clone();
1258 namespace
1260 void enableRelativeMode( SvxCharNamePage const * _pPage, SvtFontSizeBox* _pFontSizeLB, sal_uInt16 _nHeightWhich )
1262 _pFontSizeLB->EnableRelativeMode( 5, 995 ); // min 5%, max 995%, step 5
1264 const SvxFontHeightItem& rHeightItem =
1265 static_cast<const SvxFontHeightItem&>(_pPage->GetItemSet().GetParent()->Get( _nHeightWhich ));
1266 MapUnit eUnit = _pPage->GetItemSet().GetPool()->GetMetric( _nHeightWhich );
1267 short nCurHeight =
1268 static_cast< short >( CalcToPoint( rHeightItem.GetHeight(), eUnit, 1 ) * 10 );
1270 // based on the current height:
1271 // - negative until minimum of 2 pt
1272 // - positive until maximum of 999 pt
1273 _pFontSizeLB->EnablePtRelativeMode( sal::static_int_cast< short >(-(nCurHeight - 20)), (9999 - nCurHeight) );
1277 void SvxCharNamePage::EnableRelativeMode()
1279 DBG_ASSERT( GetItemSet().GetParent(), "RelativeMode, but no ParentSet!" );
1280 enableRelativeMode(this,m_xWestFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_FONTHEIGHT ));
1281 enableRelativeMode(this,m_xEastFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT ));
1282 enableRelativeMode(this,m_xCTLFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT ));
1285 void SvxCharNamePage::EnableSearchMode()
1287 m_pImpl->m_bInSearchMode = true;
1290 void SvxCharNamePage::DisableControls( sal_uInt16 nDisable )
1292 if ( DISABLE_LANGUAGE & nDisable )
1294 if ( m_xWestFontLanguageFT ) m_xWestFontLanguageFT->set_sensitive(false);
1295 if ( m_xWestFontLanguageLB ) m_xWestFontLanguageLB->set_sensitive(false);
1296 if ( m_xEastFontLanguageFT ) m_xEastFontLanguageFT->set_sensitive(false);
1297 if ( m_xEastFontLanguageLB ) m_xEastFontLanguageLB->set_sensitive(false);
1298 if ( m_xCTLFontLanguageFT ) m_xCTLFontLanguageFT->set_sensitive(false);
1299 if ( m_xCTLFontLanguageLB ) m_xCTLFontLanguageLB->set_sensitive(false);
1302 if ( DISABLE_HIDE_LANGUAGE & nDisable )
1304 if ( m_xWestFontLanguageFT ) m_xWestFontLanguageFT->hide();
1305 if ( m_xWestFontLanguageLB ) m_xWestFontLanguageLB->hide();
1306 if ( m_xEastFontLanguageFT ) m_xEastFontLanguageFT->hide();
1307 if ( m_xEastFontLanguageLB ) m_xEastFontLanguageLB->hide();
1308 if ( m_xCTLFontLanguageFT ) m_xCTLFontLanguageFT->hide();
1309 if ( m_xCTLFontLanguageLB ) m_xCTLFontLanguageLB->hide();
1313 void SvxCharNamePage::PageCreated(const SfxAllItemSet& aSet)
1315 const SvxFontListItem* pFontListItem = aSet.GetItem<SvxFontListItem>(SID_ATTR_CHAR_FONTLIST, false);
1316 const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
1317 const SfxUInt16Item* pDisalbeItem = aSet.GetItem<SfxUInt16Item>(SID_DISABLE_CTL, false);
1318 if (pFontListItem)
1319 SetFontList(*pFontListItem);
1321 if (pFlagItem)
1323 sal_uInt32 nFlags=pFlagItem->GetValue();
1324 if ( ( nFlags & SVX_RELATIVE_MODE ) == SVX_RELATIVE_MODE )
1325 EnableRelativeMode();
1326 if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
1327 // the writer uses SID_ATTR_BRUSH as font background
1328 m_bPreviewBackgroundToCharacter = true;
1330 if (pDisalbeItem)
1331 DisableControls(pDisalbeItem->GetValue());
1333 // class SvxCharEffectsPage ----------------------------------------------
1335 SvxCharEffectsPage::SvxCharEffectsPage(TabPageParent pParent, const SfxItemSet& rInSet)
1336 : SvxCharBasePage(pParent, "cui/ui/effectspage.ui", "EffectsPage", rInSet)
1337 , m_bOrigFontColor(false)
1338 , m_bNewFontColor(false)
1339 , m_bEnableNoneFontColor(false)
1340 , m_bUnderlineColorDisabled(false)
1341 , m_xFontColorFT(m_xBuilder->weld_label("fontcolorft"))
1342 , m_xFontColorLB(new ColorListBox(m_xBuilder->weld_menu_button("fontcolorlb"), pParent.GetFrameWeld()))
1343 , m_xEffectsFT(m_xBuilder->weld_label("effectsft"))
1344 , m_xEffectsLB(m_xBuilder->weld_combo_box("effectslb"))
1345 , m_xReliefFT(m_xBuilder->weld_label("reliefft"))
1346 , m_xReliefLB(m_xBuilder->weld_combo_box("relieflb"))
1347 , m_xOutlineBtn(m_xBuilder->weld_check_button("outlinecb"))
1348 , m_xShadowBtn(m_xBuilder->weld_check_button("shadowcb"))
1349 , m_xBlinkingBtn(m_xBuilder->weld_check_button("blinkingcb"))
1350 , m_xHiddenBtn(m_xBuilder->weld_check_button("hiddencb"))
1351 , m_xOverlineLB(m_xBuilder->weld_combo_box("overlinelb"))
1352 , m_xOverlineColorFT(m_xBuilder->weld_label("overlinecolorft"))
1353 , m_xOverlineColorLB(new ColorListBox(m_xBuilder->weld_menu_button("overlinecolorlb"), pParent.GetFrameWeld()))
1354 , m_xStrikeoutLB(m_xBuilder->weld_combo_box("strikeoutlb"))
1355 , m_xUnderlineLB(m_xBuilder->weld_combo_box("underlinelb"))
1356 , m_xUnderlineColorFT(m_xBuilder->weld_label("underlinecolorft"))
1357 , m_xUnderlineColorLB(new ColorListBox(m_xBuilder->weld_menu_button("underlinecolorlb"), pParent.GetFrameWeld()))
1358 , m_xIndividualWordsBtn(m_xBuilder->weld_check_button("individualwordscb"))
1359 , m_xEmphasisFT(m_xBuilder->weld_label("emphasisft"))
1360 , m_xEmphasisLB(m_xBuilder->weld_combo_box("emphasislb"))
1361 , m_xPositionFT(m_xBuilder->weld_label("positionft"))
1362 , m_xPositionLB(m_xBuilder->weld_combo_box("positionlb"))
1363 , m_xA11yWarningFT(m_xBuilder->weld_label("a11ywarning"))
1365 m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
1366 #ifdef IOS
1367 m_xPreviewWin->hide();
1368 #endif
1369 m_xFontColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
1370 m_xOverlineColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
1371 m_xUnderlineColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
1372 Initialize();
1375 void SvxCharEffectsPage::EnableNoneFontColor()
1377 m_xFontColorLB->SetSlotId(SID_ATTR_CHAR_COLOR, true);
1378 m_bEnableNoneFontColor = true;
1381 Color SvxCharEffectsPage::GetPreviewFontColor(const Color& rColor) const
1383 if (rColor == COL_AUTO)
1384 return COL_BLACK;
1385 if (m_bEnableNoneFontColor && rColor == COL_NONE_COLOR)
1386 return COL_BLACK;
1387 return rColor;
1390 SvxCharEffectsPage::~SvxCharEffectsPage()
1392 disposeOnce();
1395 void SvxCharEffectsPage::dispose()
1397 m_xUnderlineColorLB.reset();
1398 m_xOverlineColorLB.reset();
1399 m_xFontColorLB.reset();
1400 SvxCharBasePage::dispose();
1403 void SvxCharEffectsPage::Initialize()
1405 // to handle the changes of the other pages
1406 SetExchangeSupport();
1408 // HTML-Mode
1409 const SfxPoolItem* pItem;
1410 SfxObjectShell* pShell;
1411 if ( SfxItemState::SET == GetItemSet().GetItemState( SID_HTML_MODE, false, &pItem ) ||
1412 ( nullptr != ( pShell = SfxObjectShell::Current() ) &&
1413 nullptr != ( pItem = pShell->GetItem( SID_HTML_MODE ) ) ) )
1415 m_nHtmlMode = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
1416 if ( ( m_nHtmlMode & HTMLMODE_ON ) == HTMLMODE_ON )
1418 //!!! hide some controls please
1422 m_xFontColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
1424 // handler
1425 Link<weld::ComboBox&,void> aLink = LINK( this, SvxCharEffectsPage, SelectListBoxHdl_Impl );
1426 m_xUnderlineLB->connect_changed( aLink );
1427 m_xUnderlineColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
1428 m_xOverlineLB->connect_changed( aLink );
1429 m_xOverlineColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
1430 m_xStrikeoutLB->connect_changed( aLink );
1431 m_xEmphasisLB->connect_changed( aLink );
1432 m_xPositionLB->connect_changed( aLink );
1433 m_xEffectsLB->connect_changed( aLink );
1434 m_xReliefLB->connect_changed( aLink );
1436 m_xUnderlineLB->set_active( 0 );
1437 m_xOverlineLB->set_active( 0 );
1438 m_xStrikeoutLB->set_active( 0 );
1439 m_xEmphasisLB->set_active( 0 );
1440 m_xPositionLB->set_active( 0 );
1441 SelectHdl_Impl(nullptr);
1442 SelectHdl_Impl(m_xEmphasisLB.get());
1444 m_xEffectsLB->set_active( 0 );
1446 m_xIndividualWordsBtn->connect_toggled(LINK(this, SvxCharEffectsPage, CbClickHdl_Impl));
1447 Link<weld::ToggleButton&,void> aLink2 = LINK(this, SvxCharEffectsPage, TristClickHdl_Impl);
1448 m_xOutlineBtn->connect_toggled(aLink2);
1449 m_xShadowBtn->connect_toggled(aLink2);
1451 if ( !SvtLanguageOptions().IsAsianTypographyEnabled() )
1453 m_xEmphasisFT->hide();
1454 m_xEmphasisLB->hide();
1455 m_xPositionFT->hide();
1456 m_xPositionLB->hide();
1459 m_xA11yWarningFT->set_visible(officecfg::Office::Common::Accessibility::IsAutomaticFontColor::get());
1462 void SvxCharEffectsPage::UpdatePreview_Impl()
1464 SvxFont& rFont = GetPreviewFont();
1465 SvxFont& rCJKFont = GetPreviewCJKFont();
1466 SvxFont& rCTLFont = GetPreviewCTLFont();
1468 const Color& rSelectedColor = m_xFontColorLB->GetSelectEntryColor();
1469 rFont.SetColor(GetPreviewFontColor(rSelectedColor));
1470 rCJKFont.SetColor(GetPreviewFontColor(rSelectedColor));
1471 rCTLFont.SetColor(GetPreviewFontColor(rSelectedColor));
1473 FontLineStyle eUnderline = static_cast<FontLineStyle>(m_xUnderlineLB->get_active_id().toInt32());
1474 FontLineStyle eOverline = static_cast<FontLineStyle>(m_xOverlineLB->get_active_id().toInt32());
1475 FontStrikeout eStrikeout = static_cast<FontStrikeout>(m_xStrikeoutLB->get_active_id().toInt32());
1476 rFont.SetUnderline( eUnderline );
1477 rCJKFont.SetUnderline( eUnderline );
1478 rCTLFont.SetUnderline( eUnderline );
1479 m_aPreviewWin.SetTextLineColor( m_xUnderlineColorLB->GetSelectEntryColor() );
1480 rFont.SetOverline( eOverline );
1481 rCJKFont.SetOverline( eOverline );
1482 rCTLFont.SetOverline( eOverline );
1483 m_aPreviewWin.SetOverlineColor( m_xOverlineColorLB->GetSelectEntryColor() );
1484 rFont.SetStrikeout( eStrikeout );
1485 rCJKFont.SetStrikeout( eStrikeout );
1486 rCTLFont.SetStrikeout( eStrikeout );
1488 auto nEmphasis = m_xEmphasisLB->get_active();
1489 if (nEmphasis != -1)
1491 bool bUnder = (CHRDLG_POSITION_UNDER == m_xPositionLB->get_active_id().toInt32());
1492 FontEmphasisMark eMark = static_cast<FontEmphasisMark>(nEmphasis);
1493 eMark |= bUnder ? FontEmphasisMark::PosBelow : FontEmphasisMark::PosAbove;
1494 rFont.SetEmphasisMark( eMark );
1495 rCJKFont.SetEmphasisMark( eMark );
1496 rCTLFont.SetEmphasisMark( eMark );
1499 auto nRelief = m_xReliefLB->get_active();
1500 if (nRelief != -1)
1502 rFont.SetRelief( static_cast<FontRelief>(nRelief) );
1503 rCJKFont.SetRelief( static_cast<FontRelief>(nRelief) );
1504 rCTLFont.SetRelief( static_cast<FontRelief>(nRelief) );
1507 rFont.SetOutline( StateToAttr( m_xOutlineBtn->get_state() ) );
1508 rCJKFont.SetOutline( rFont.IsOutline() );
1509 rCTLFont.SetOutline( rFont.IsOutline() );
1511 rFont.SetShadow( StateToAttr( m_xShadowBtn->get_state() ) );
1512 rCJKFont.SetShadow( rFont.IsShadow() );
1513 rCTLFont.SetShadow( rFont.IsShadow() );
1515 auto nCapsPos = m_xEffectsLB->get_active();
1516 if (nCapsPos != -1)
1518 SvxCaseMap eCaps = static_cast<SvxCaseMap>(nCapsPos);
1519 rFont.SetCaseMap( eCaps );
1520 rCJKFont.SetCaseMap( eCaps );
1521 // #i78474# small caps do not exist in CTL fonts
1522 rCTLFont.SetCaseMap( eCaps == SvxCaseMap::SmallCaps ? SvxCaseMap::NotMapped : eCaps );
1525 bool bWordLine = m_xIndividualWordsBtn->get_active();
1526 rFont.SetWordLineMode( bWordLine );
1527 rCJKFont.SetWordLineMode( bWordLine );
1528 rCTLFont.SetWordLineMode( bWordLine );
1530 m_aPreviewWin.Invalidate();
1533 void SvxCharEffectsPage::SetCaseMap_Impl( SvxCaseMap eCaseMap )
1535 if ( SvxCaseMap::End > eCaseMap )
1536 m_xEffectsLB->set_active(
1537 sal::static_int_cast< sal_Int32 >( eCaseMap ) );
1538 else
1540 // not mapped
1541 m_xEffectsLB->set_active(-1);
1544 UpdatePreview_Impl();
1547 void SvxCharEffectsPage::ResetColor_Impl( const SfxItemSet& rSet )
1549 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
1550 SfxItemState eState = rSet.GetItemState( nWhich );
1552 m_bOrigFontColor = false;
1553 switch ( eState )
1555 case SfxItemState::UNKNOWN:
1556 m_xFontColorFT->hide();
1557 m_xFontColorLB->hide();
1558 break;
1560 case SfxItemState::DISABLED:
1561 case SfxItemState::READONLY:
1562 m_xFontColorFT->set_sensitive(false);
1563 m_xFontColorLB->set_sensitive(false);
1564 break;
1566 case SfxItemState::DONTCARE:
1567 //Related: tdf#106080 if there is no font color, then allow "none"
1568 //as a color so the listbox can display that state.
1569 EnableNoneFontColor();
1570 m_xFontColorLB->SetNoSelection();
1571 break;
1573 case SfxItemState::DEFAULT:
1574 case SfxItemState::SET:
1576 SvxFont& rFont = GetPreviewFont();
1577 SvxFont& rCJKFont = GetPreviewCJKFont();
1578 SvxFont& rCTLFont = GetPreviewCTLFont();
1580 const SvxColorItem& rItem = static_cast<const SvxColorItem&>(rSet.Get( nWhich ));
1581 Color aColor = rItem.GetValue();
1582 rFont.SetColor(GetPreviewFontColor(aColor));
1583 rCJKFont.SetColor(GetPreviewFontColor(aColor));
1584 rCTLFont.SetColor(GetPreviewFontColor(aColor));
1586 m_aPreviewWin.Invalidate();
1588 m_xFontColorLB->SelectEntry(aColor);
1590 m_aOrigFontColor = aColor;
1591 m_bOrigFontColor = true;
1592 break;
1595 m_bNewFontColor = false;
1598 bool SvxCharEffectsPage::FillItemSetColor_Impl( SfxItemSet& rSet )
1600 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
1601 const SfxItemSet& rOldSet = GetItemSet();
1603 Color aSelectedColor;
1604 bool bChanged = m_bNewFontColor;
1606 if (bChanged)
1608 aSelectedColor = m_xFontColorLB->GetSelectEntryColor();
1609 if (m_bOrigFontColor)
1610 bChanged = aSelectedColor != m_aOrigFontColor;
1611 if (m_bEnableNoneFontColor && bChanged && aSelectedColor == COL_NONE_COLOR)
1612 bChanged = false;
1615 if (bChanged)
1616 rSet.Put( SvxColorItem( aSelectedColor, nWhich ) );
1617 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
1618 rSet.InvalidateItem(nWhich);
1620 return bChanged;
1623 IMPL_LINK( SvxCharEffectsPage, SelectListBoxHdl_Impl, weld::ComboBox&, rBox, void )
1625 SelectHdl_Impl(&rBox);
1628 void SvxCharEffectsPage::SelectHdl_Impl(const weld::ComboBox* pBox)
1630 if (m_xEmphasisLB.get() == pBox)
1632 auto nEPos = m_xEmphasisLB->get_active();
1633 bool bEnable = nEPos > 0;
1634 m_xPositionFT->set_sensitive( bEnable );
1635 m_xPositionLB->set_sensitive( bEnable );
1637 else if (m_xReliefLB.get() == pBox)
1639 bool bEnable = ( pBox->get_active() == 0 );
1640 m_xOutlineBtn->set_sensitive( bEnable );
1641 m_xShadowBtn->set_sensitive( bEnable );
1643 else if (m_xPositionLB.get() != pBox)
1645 bool bUEnable = false;
1646 if (!m_bUnderlineColorDisabled)
1648 auto nUPos = m_xUnderlineLB->get_active();
1649 bUEnable = nUPos > 0;
1650 m_xUnderlineColorFT->set_sensitive(bUEnable);
1651 m_xUnderlineColorLB->set_sensitive(bUEnable);
1654 auto nOPos = m_xOverlineLB->get_active();
1655 bool bOEnable = nOPos > 0;
1656 m_xOverlineColorFT->set_sensitive(bOEnable);
1657 m_xOverlineColorLB->set_sensitive(bOEnable);
1659 auto nSPos = m_xStrikeoutLB->get_active();
1660 m_xIndividualWordsBtn->set_sensitive( bUEnable || bOEnable || nSPos > 0);
1662 UpdatePreview_Impl();
1665 IMPL_LINK_NOARG(SvxCharEffectsPage, UpdatePreview_Impl, weld::ComboBox&, void)
1667 bool bEnable = ( ( m_xUnderlineLB->get_active() > 0 ) ||
1668 ( m_xOverlineLB->get_active() > 0 ) ||
1669 ( m_xStrikeoutLB->get_active() > 0 ) );
1670 m_xIndividualWordsBtn->set_sensitive( bEnable );
1672 UpdatePreview_Impl();
1675 IMPL_LINK_NOARG(SvxCharEffectsPage, CbClickHdl_Impl, weld::ToggleButton&, void)
1677 UpdatePreview_Impl();
1680 IMPL_LINK_NOARG(SvxCharEffectsPage, TristClickHdl_Impl, weld::ToggleButton&, void)
1682 UpdatePreview_Impl();
1685 IMPL_LINK(SvxCharEffectsPage, ColorBoxSelectHdl_Impl, ColorListBox&, rBox, void)
1687 if (m_xFontColorLB.get() == &rBox)
1688 m_bNewFontColor = true;
1689 UpdatePreview_Impl();
1692 DeactivateRC SvxCharEffectsPage::DeactivatePage( SfxItemSet* _pSet )
1694 if ( _pSet )
1695 FillItemSet( _pSet );
1696 return DeactivateRC::LeavePage;
1699 VclPtr<SfxTabPage> SvxCharEffectsPage::Create( TabPageParent pParent, const SfxItemSet* rSet )
1701 return VclPtr<SvxCharEffectsPage>::Create( pParent, *rSet );
1704 void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
1706 SvxFont& rFont = GetPreviewFont();
1707 SvxFont& rCJKFont = GetPreviewCJKFont();
1708 SvxFont& rCTLFont = GetPreviewCTLFont();
1710 bool bEnable = false;
1712 // Underline
1713 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_UNDERLINE );
1714 rFont.SetUnderline( LINESTYLE_NONE );
1715 rCJKFont.SetUnderline( LINESTYLE_NONE );
1716 rCTLFont.SetUnderline( LINESTYLE_NONE );
1718 m_xUnderlineLB->set_active( 0 );
1719 SfxItemState eState = rSet->GetItemState( nWhich );
1721 if ( eState >= SfxItemState::DONTCARE )
1723 if ( eState == SfxItemState::DONTCARE )
1724 m_xUnderlineLB->set_active(-1);
1725 else
1727 const SvxUnderlineItem& rItem = static_cast<const SvxUnderlineItem&>(rSet->Get( nWhich ));
1728 FontLineStyle eUnderline = rItem.GetValue();
1729 rFont.SetUnderline( eUnderline );
1730 rCJKFont.SetUnderline( eUnderline );
1731 rCTLFont.SetUnderline( eUnderline );
1733 if ( eUnderline != LINESTYLE_NONE )
1735 auto nPos = m_xUnderlineLB->find_id(OUString::number(eUnderline));
1736 if (nPos != -1)
1738 m_xUnderlineLB->set_active(nPos);
1739 bEnable = true;
1741 Color aColor = rItem.GetColor();
1742 m_xUnderlineColorLB->SelectEntry(aColor);
1744 else
1746 m_xUnderlineColorLB->SelectEntry(COL_AUTO);
1747 m_xUnderlineColorLB->set_sensitive(false);
1752 // Overline
1753 nWhich = GetWhich( SID_ATTR_CHAR_OVERLINE );
1754 rFont.SetOverline( LINESTYLE_NONE );
1755 rCJKFont.SetOverline( LINESTYLE_NONE );
1756 rCTLFont.SetOverline( LINESTYLE_NONE );
1758 m_xOverlineLB->set_active( 0 );
1759 eState = rSet->GetItemState( nWhich );
1761 if ( eState >= SfxItemState::DONTCARE )
1763 if ( eState == SfxItemState::DONTCARE )
1764 m_xOverlineLB->set_active(-1);
1765 else
1767 const SvxOverlineItem& rItem = static_cast<const SvxOverlineItem&>(rSet->Get( nWhich ));
1768 FontLineStyle eOverline = rItem.GetValue();
1769 rFont.SetOverline( eOverline );
1770 rCJKFont.SetOverline( eOverline );
1771 rCTLFont.SetOverline( eOverline );
1773 if ( eOverline != LINESTYLE_NONE )
1775 auto nPos = m_xOverlineLB->find_id(OUString::number(eOverline));
1776 if (nPos != -1)
1778 m_xOverlineLB->set_active(nPos);
1779 bEnable = true;
1781 Color aColor = rItem.GetColor();
1782 m_xOverlineColorLB->SelectEntry(aColor);
1784 else
1786 m_xOverlineColorLB->SelectEntry(COL_AUTO);
1787 m_xOverlineColorLB->set_sensitive(false);
1792 // Strikeout
1793 nWhich = GetWhich( SID_ATTR_CHAR_STRIKEOUT );
1794 rFont.SetStrikeout( STRIKEOUT_NONE );
1795 rCJKFont.SetStrikeout( STRIKEOUT_NONE );
1796 rCTLFont.SetStrikeout( STRIKEOUT_NONE );
1798 m_xStrikeoutLB->set_active( 0 );
1799 eState = rSet->GetItemState( nWhich );
1801 if ( eState >= SfxItemState::DONTCARE )
1803 if ( eState == SfxItemState::DONTCARE )
1804 m_xStrikeoutLB->set_active(-1);
1805 else
1807 const SvxCrossedOutItem& rItem = static_cast<const SvxCrossedOutItem&>(rSet->Get( nWhich ));
1808 FontStrikeout eStrikeout = rItem.GetValue();
1809 rFont.SetStrikeout( eStrikeout );
1810 rCJKFont.SetStrikeout( eStrikeout );
1811 rCTLFont.SetStrikeout( eStrikeout );
1813 if ( eStrikeout != STRIKEOUT_NONE )
1815 auto nPos = m_xStrikeoutLB->find_id(OUString::number(eStrikeout));
1816 if (nPos != -1)
1818 m_xStrikeoutLB->set_active(nPos);
1819 bEnable = true;
1825 // WordLineMode
1826 nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
1827 eState = rSet->GetItemState( nWhich );
1829 switch ( eState )
1831 case SfxItemState::UNKNOWN:
1832 m_xIndividualWordsBtn->hide();
1833 break;
1835 case SfxItemState::DISABLED:
1836 case SfxItemState::READONLY:
1837 m_xIndividualWordsBtn->set_sensitive(false);
1838 break;
1840 case SfxItemState::DONTCARE:
1841 m_xIndividualWordsBtn->set_state( TRISTATE_INDET );
1842 break;
1844 case SfxItemState::DEFAULT:
1845 case SfxItemState::SET:
1847 const SvxWordLineModeItem& rItem = static_cast<const SvxWordLineModeItem&>(rSet->Get( nWhich ));
1848 rFont.SetWordLineMode( rItem.GetValue() );
1849 rCJKFont.SetWordLineMode( rItem.GetValue() );
1850 rCTLFont.SetWordLineMode( rItem.GetValue() );
1852 m_xIndividualWordsBtn->set_active(rItem.GetValue());
1853 m_xIndividualWordsBtn->set_sensitive(bEnable);
1854 break;
1858 // Emphasis
1859 nWhich = GetWhich( SID_ATTR_CHAR_EMPHASISMARK );
1860 eState = rSet->GetItemState( nWhich );
1862 if ( eState >= SfxItemState::DEFAULT )
1864 const SvxEmphasisMarkItem& rItem = static_cast<const SvxEmphasisMarkItem&>(rSet->Get( nWhich ));
1865 FontEmphasisMark eMark = rItem.GetEmphasisMark();
1866 rFont.SetEmphasisMark( eMark );
1867 rCJKFont.SetEmphasisMark( eMark );
1868 rCTLFont.SetEmphasisMark( eMark );
1870 m_xEmphasisLB->set_active( static_cast<sal_Int32>(FontEmphasisMark( eMark & FontEmphasisMark::Style )) );
1871 eMark &= ~FontEmphasisMark::Style;
1872 int nEntryData = ( eMark == FontEmphasisMark::PosAbove )
1873 ? CHRDLG_POSITION_OVER
1874 : ( eMark == FontEmphasisMark::PosBelow ) ? CHRDLG_POSITION_UNDER : 0;
1876 auto nPos = m_xPositionLB->find_id(OUString::number(nEntryData));
1877 if (nPos != -1)
1878 m_xPositionLB->set_active(nPos);
1880 else if ( eState == SfxItemState::DONTCARE )
1881 m_xEmphasisLB->set_active(-1);
1882 else if ( eState == SfxItemState::UNKNOWN )
1884 m_xEmphasisFT->hide();
1885 m_xEmphasisLB->hide();
1887 else // SfxItemState::DISABLED or SfxItemState::READONLY
1889 m_xEmphasisFT->set_sensitive(false);
1890 m_xEmphasisLB->set_sensitive(false);
1893 // the select handler for the underline/overline/strikeout list boxes
1894 SelectHdl_Impl(m_xUnderlineLB.get());
1896 // the select handler for the emphasis listbox
1897 SelectHdl_Impl(m_xEmphasisLB.get());
1899 // Effects
1900 SvxCaseMap eCaseMap = SvxCaseMap::End;
1901 nWhich = GetWhich( SID_ATTR_CHAR_CASEMAP );
1902 eState = rSet->GetItemState( nWhich );
1903 switch ( eState )
1905 case SfxItemState::UNKNOWN:
1906 m_xEffectsFT->hide();
1907 m_xEffectsLB->hide();
1908 break;
1910 case SfxItemState::DISABLED:
1911 case SfxItemState::READONLY:
1912 m_xEffectsFT->set_sensitive(false);
1913 m_xEffectsLB->set_sensitive(false);
1914 break;
1916 case SfxItemState::DONTCARE:
1917 m_xEffectsLB->set_active(-1);
1918 break;
1920 case SfxItemState::DEFAULT:
1921 case SfxItemState::SET:
1923 const SvxCaseMapItem& rItem = static_cast<const SvxCaseMapItem&>(rSet->Get( nWhich ));
1924 eCaseMap = rItem.GetValue();
1925 break;
1928 SetCaseMap_Impl( eCaseMap );
1930 //Relief
1931 nWhich = GetWhich(SID_ATTR_CHAR_RELIEF);
1932 eState = rSet->GetItemState( nWhich );
1933 switch ( eState )
1935 case SfxItemState::UNKNOWN:
1936 m_xReliefFT->hide();
1937 m_xReliefLB->hide();
1938 break;
1940 case SfxItemState::DISABLED:
1941 case SfxItemState::READONLY:
1942 m_xReliefFT->set_sensitive(false);
1943 m_xReliefLB->set_sensitive(false);
1944 break;
1946 case SfxItemState::DONTCARE:
1947 m_xReliefLB->set_active(-1);
1948 break;
1950 case SfxItemState::DEFAULT:
1951 case SfxItemState::SET:
1953 const SvxCharReliefItem& rItem = static_cast<const SvxCharReliefItem&>(rSet->Get( nWhich ));
1954 m_xReliefLB->set_active(static_cast<sal_Int32>(rItem.GetValue()));
1955 SelectHdl_Impl(m_xReliefLB.get());
1956 break;
1960 // Outline
1961 nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
1962 eState = rSet->GetItemState( nWhich );
1963 switch ( eState )
1965 case SfxItemState::UNKNOWN:
1966 m_xOutlineBtn->hide();
1967 break;
1969 case SfxItemState::DISABLED:
1970 case SfxItemState::READONLY:
1971 m_xOutlineBtn->set_sensitive(false);
1972 break;
1974 case SfxItemState::DONTCARE:
1975 m_xOutlineBtn->set_state(TRISTATE_INDET);
1976 break;
1978 case SfxItemState::DEFAULT:
1979 case SfxItemState::SET:
1981 const SvxContourItem& rItem = static_cast<const SvxContourItem&>(rSet->Get( nWhich ));
1982 m_xOutlineBtn->set_state(static_cast<TriState>(rItem.GetValue()));
1983 break;
1987 // Shadow
1988 nWhich = GetWhich( SID_ATTR_CHAR_SHADOWED );
1989 eState = rSet->GetItemState( nWhich );
1991 switch ( eState )
1993 case SfxItemState::UNKNOWN:
1994 m_xShadowBtn->hide();
1995 break;
1997 case SfxItemState::DISABLED:
1998 case SfxItemState::READONLY:
1999 m_xShadowBtn->set_sensitive(false);
2000 break;
2002 case SfxItemState::DONTCARE:
2003 m_xShadowBtn->set_state( TRISTATE_INDET );
2004 break;
2006 case SfxItemState::DEFAULT:
2007 case SfxItemState::SET:
2009 const SvxShadowedItem& rItem = static_cast<const SvxShadowedItem&>(rSet->Get( nWhich ));
2010 m_xShadowBtn->set_state( static_cast<TriState>(rItem.GetValue()) );
2011 break;
2015 // Blinking
2016 nWhich = GetWhich( SID_ATTR_FLASH );
2017 eState = rSet->GetItemState( nWhich );
2019 switch ( eState )
2021 case SfxItemState::UNKNOWN:
2022 m_xBlinkingBtn->hide();
2023 break;
2025 case SfxItemState::DISABLED:
2026 case SfxItemState::READONLY:
2027 m_xBlinkingBtn->set_sensitive(false);
2028 break;
2030 case SfxItemState::DONTCARE:
2031 m_xBlinkingBtn->set_state( TRISTATE_INDET );
2032 break;
2034 case SfxItemState::DEFAULT:
2035 case SfxItemState::SET:
2037 const SvxBlinkItem& rItem = static_cast<const SvxBlinkItem&>(rSet->Get( nWhich ));
2038 m_xBlinkingBtn->set_state( static_cast<TriState>(rItem.GetValue()) );
2039 break;
2042 // Hidden
2043 nWhich = GetWhich( SID_ATTR_CHAR_HIDDEN );
2044 eState = rSet->GetItemState( nWhich );
2046 switch ( eState )
2048 case SfxItemState::UNKNOWN:
2049 m_xHiddenBtn->hide();
2050 break;
2052 case SfxItemState::DISABLED:
2053 case SfxItemState::READONLY:
2054 m_xHiddenBtn->set_sensitive(false);
2055 break;
2057 case SfxItemState::DONTCARE:
2058 m_xHiddenBtn->set_state(TRISTATE_INDET);
2059 break;
2061 case SfxItemState::DEFAULT:
2062 case SfxItemState::SET:
2064 const SvxCharHiddenItem& rItem = static_cast<const SvxCharHiddenItem&>(rSet->Get( nWhich ));
2065 m_xHiddenBtn->set_state(static_cast<TriState>(rItem.GetValue()));
2066 break;
2070 SetPrevFontWidthScale( *rSet );
2071 ResetColor_Impl( *rSet );
2073 // preview update
2074 m_aPreviewWin.Invalidate();
2076 // save this settings
2077 ChangesApplied();
2080 void SvxCharEffectsPage::ChangesApplied()
2082 m_xUnderlineLB->save_value();
2083 m_xOverlineLB->save_value();
2084 m_xStrikeoutLB->save_value();
2085 m_xIndividualWordsBtn->save_state();
2086 m_xEmphasisLB->save_value();
2087 m_xPositionLB->save_value();
2088 m_xEffectsLB->save_value();
2089 m_xReliefLB->save_value();
2090 m_xOutlineBtn->save_state();
2091 m_xShadowBtn->save_state();
2092 m_xBlinkingBtn->save_state();
2093 m_xHiddenBtn->save_state();
2096 bool SvxCharEffectsPage::FillItemSet( SfxItemSet* rSet )
2098 const SfxPoolItem* pOld = nullptr;
2099 const SfxItemSet& rOldSet = GetItemSet();
2100 bool bModified = false;
2101 bool bChanged = true;
2103 // Underline
2104 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_UNDERLINE );
2105 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_UNDERLINE );
2106 auto nPos = m_xUnderlineLB->get_active();
2107 FontLineStyle eUnder = static_cast<FontLineStyle>(m_xUnderlineLB->get_active_id().toInt32());
2109 if ( pOld )
2111 //! if there are different underline styles in the selection the
2112 //! item-state in the 'rOldSet' will be invalid. In this case
2113 //! changing the underline style will be allowed if a style is
2114 //! selected in the listbox.
2115 bool bAllowChg = nPos != -1 &&
2116 SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
2118 const SvxUnderlineItem& rItem = *static_cast<const SvxUnderlineItem*>(pOld);
2119 if ( rItem.GetValue() == eUnder &&
2120 ( LINESTYLE_NONE == eUnder || rItem.GetColor() == m_xUnderlineColorLB->GetSelectEntryColor() ) &&
2121 ! bAllowChg )
2122 bChanged = false;
2125 if ( bChanged )
2127 SvxUnderlineItem aNewItem( eUnder, nWhich );
2128 aNewItem.SetColor( m_xUnderlineColorLB->GetSelectEntryColor() );
2129 rSet->Put( aNewItem );
2130 bModified = true;
2132 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2133 rSet->InvalidateItem(nWhich);
2135 bChanged = true;
2137 // Overline
2138 nWhich = GetWhich( SID_ATTR_CHAR_OVERLINE );
2139 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_OVERLINE );
2140 nPos = m_xOverlineLB->get_active();
2141 FontLineStyle eOver = static_cast<FontLineStyle>(m_xOverlineLB->get_active_id().toInt32());
2143 if ( pOld )
2145 //! if there are different underline styles in the selection the
2146 //! item-state in the 'rOldSet' will be invalid. In this case
2147 //! changing the underline style will be allowed if a style is
2148 //! selected in the listbox.
2149 bool bAllowChg = nPos != -1 &&
2150 SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
2152 const SvxOverlineItem& rItem = *static_cast<const SvxOverlineItem*>(pOld);
2153 if ( rItem.GetValue() == eOver &&
2154 ( LINESTYLE_NONE == eOver || rItem.GetColor() == m_xOverlineColorLB->GetSelectEntryColor() ) &&
2155 ! bAllowChg )
2156 bChanged = false;
2159 if ( bChanged )
2161 SvxOverlineItem aNewItem( eOver, nWhich );
2162 aNewItem.SetColor( m_xOverlineColorLB->GetSelectEntryColor() );
2163 rSet->Put( aNewItem );
2164 bModified = true;
2166 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2167 rSet->InvalidateItem(nWhich);
2169 bChanged = true;
2171 // Strikeout
2172 nWhich = GetWhich( SID_ATTR_CHAR_STRIKEOUT );
2173 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_STRIKEOUT );
2174 nPos = m_xStrikeoutLB->get_active();
2175 FontStrikeout eStrike = static_cast<FontStrikeout>(m_xStrikeoutLB->get_active_id().toInt32());
2177 if ( pOld )
2179 //! if there are different strikeout styles in the selection the
2180 //! item-state in the 'rOldSet' will be invalid. In this case
2181 //! changing the strikeout style will be allowed if a style is
2182 //! selected in the listbox.
2183 bool bAllowChg = nPos != -1 &&
2184 SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
2186 const SvxCrossedOutItem& rItem = *static_cast<const SvxCrossedOutItem*>(pOld);
2187 if ( !m_xStrikeoutLB->get_sensitive()
2188 || (rItem.GetValue() == eStrike && !bAllowChg) )
2189 bChanged = false;
2192 if ( bChanged )
2194 rSet->Put( SvxCrossedOutItem( eStrike, nWhich ) );
2195 bModified = true;
2197 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2198 rSet->InvalidateItem(nWhich);
2200 bChanged = true;
2202 // Individual words
2203 nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
2204 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_WORDLINEMODE );
2206 if ( pOld )
2208 const SvxWordLineModeItem& rItem = *static_cast<const SvxWordLineModeItem*>(pOld);
2209 if ( rItem.GetValue() == m_xIndividualWordsBtn->get_active() )
2210 bChanged = false;
2213 if ( rOldSet.GetItemState( nWhich ) == SfxItemState::DONTCARE &&
2214 ! m_xIndividualWordsBtn->get_state_changed_from_saved() )
2215 bChanged = false;
2217 if ( bChanged )
2219 rSet->Put( SvxWordLineModeItem( m_xIndividualWordsBtn->get_active(), nWhich ) );
2220 bModified = true;
2222 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2223 rSet->InvalidateItem(nWhich);
2225 bChanged = true;
2227 // Emphasis
2228 nWhich = GetWhich( SID_ATTR_CHAR_EMPHASISMARK );
2229 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_EMPHASISMARK );
2230 int nMarkPos = m_xEmphasisLB->get_active();
2231 OUString sMarkPos = m_xEmphasisLB->get_active_text();
2232 OUString sPosPos = m_xPositionLB->get_active_text();
2233 FontEmphasisMark eMark = static_cast<FontEmphasisMark>(nMarkPos);
2234 if (m_xPositionLB->get_sensitive())
2236 eMark |= (CHRDLG_POSITION_UNDER == m_xPositionLB->get_active_id().toInt32())
2237 ? FontEmphasisMark::PosBelow : FontEmphasisMark::PosAbove;
2240 if ( pOld )
2242 if( rOldSet.GetItemState( nWhich ) != SfxItemState::DONTCARE )
2244 const SvxEmphasisMarkItem& rItem = *static_cast<const SvxEmphasisMarkItem*>(pOld);
2245 if ( rItem.GetEmphasisMark() == eMark )
2246 bChanged = false;
2250 if (rOldSet.GetItemState( nWhich ) == SfxItemState::DONTCARE &&
2251 m_xEmphasisLB->get_saved_value() == sMarkPos && m_xPositionLB->get_saved_value() == sPosPos)
2253 bChanged = false;
2256 if (bChanged)
2258 rSet->Put( SvxEmphasisMarkItem( eMark, nWhich ) );
2259 bModified = true;
2261 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2262 rSet->InvalidateItem(nWhich);
2264 bChanged = true;
2266 // Effects
2267 nWhich = GetWhich( SID_ATTR_CHAR_CASEMAP );
2268 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CASEMAP );
2269 SvxCaseMap eCaseMap = SvxCaseMap::NotMapped;
2270 bool bChecked = false;
2271 auto nCapsPos = m_xEffectsLB->get_active();
2272 if (nCapsPos != -1)
2274 eCaseMap = static_cast<SvxCaseMap>(nCapsPos);
2275 bChecked = true;
2278 if ( pOld )
2280 //! if there are different effect styles in the selection the
2281 //! item-state in the 'rOldSet' will be invalid. In this case
2282 //! changing the effect style will be allowed if a style is
2283 //! selected in the listbox.
2284 bool bAllowChg = nPos != -1 &&
2285 SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
2287 const SvxCaseMapItem& rItem = *static_cast<const SvxCaseMapItem*>(pOld);
2288 if ( rItem.GetValue() == eCaseMap && !bAllowChg )
2289 bChanged = false;
2292 if ( bChanged && bChecked )
2294 rSet->Put( SvxCaseMapItem( eCaseMap, nWhich ) );
2295 bModified = true;
2297 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2298 rSet->InvalidateItem(nWhich);
2300 bChanged = true;
2302 //Relief
2303 nWhich = GetWhich(SID_ATTR_CHAR_RELIEF);
2304 if (m_xReliefLB->get_value_changed_from_saved())
2306 m_xReliefLB->save_value();
2307 SvxCharReliefItem aRelief(static_cast<FontRelief>(m_xReliefLB->get_active()), nWhich);
2308 rSet->Put(aRelief);
2311 // Outline
2312 const SfxItemSet* pExampleSet = GetDialogExampleSet();
2313 nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
2314 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CONTOUR );
2315 TriState eState = m_xOutlineBtn->get_state();
2316 const SfxPoolItem* pItem;
2318 if ( pOld )
2320 const SvxContourItem& rItem = *static_cast<const SvxContourItem*>(pOld);
2321 if ( rItem.GetValue() == StateToAttr( eState ) && m_xOutlineBtn->get_saved_state() == eState )
2322 bChanged = false;
2325 if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
2326 !StateToAttr( eState ) && static_cast<const SvxContourItem*>(pItem)->GetValue() )
2327 bChanged = true;
2329 if ( bChanged && eState != TRISTATE_INDET )
2331 rSet->Put( SvxContourItem( StateToAttr( eState ), nWhich ) );
2332 bModified = true;
2334 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2335 rSet->InvalidateItem(nWhich);
2337 bChanged = true;
2339 // Shadow
2340 nWhich = GetWhich( SID_ATTR_CHAR_SHADOWED );
2341 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_SHADOWED );
2342 eState = m_xShadowBtn->get_state();
2344 if ( pOld )
2346 const SvxShadowedItem& rItem = *static_cast<const SvxShadowedItem*>(pOld);
2347 if ( rItem.GetValue() == StateToAttr( eState ) && m_xShadowBtn->get_saved_state() == eState )
2348 bChanged = false;
2351 if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
2352 !StateToAttr( eState ) && static_cast<const SvxShadowedItem*>(pItem)->GetValue() )
2353 bChanged = true;
2355 if ( bChanged && eState != TRISTATE_INDET )
2357 rSet->Put( SvxShadowedItem( StateToAttr( eState ), nWhich ) );
2358 bModified = true;
2360 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2361 rSet->InvalidateItem(nWhich);
2363 bChanged = true;
2365 // Blinking
2366 nWhich = GetWhich( SID_ATTR_FLASH );
2367 pOld = GetOldItem( *rSet, SID_ATTR_FLASH );
2368 eState = m_xBlinkingBtn->get_state();
2370 if ( pOld )
2372 const SvxBlinkItem& rItem = *static_cast<const SvxBlinkItem*>(pOld);
2373 if ( rItem.GetValue() == StateToAttr( eState ) && m_xBlinkingBtn->get_saved_state() == eState )
2374 bChanged = false;
2377 if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
2378 !StateToAttr( eState ) && static_cast<const SvxBlinkItem*>(pItem)->GetValue() )
2379 bChanged = true;
2381 if ( bChanged && eState != TRISTATE_INDET )
2383 rSet->Put( SvxBlinkItem( StateToAttr( eState ), nWhich ) );
2384 bModified = true;
2386 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2387 rSet->InvalidateItem(nWhich);
2389 // Hidden
2390 nWhich = GetWhich( SID_ATTR_CHAR_HIDDEN );
2391 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_HIDDEN );
2392 eState = m_xHiddenBtn->get_state();
2393 bChanged = true;
2395 if ( pOld )
2397 const SvxCharHiddenItem& rItem = *static_cast<const SvxCharHiddenItem*>(pOld);
2398 if ( rItem.GetValue() == StateToAttr( eState ) && m_xHiddenBtn->get_saved_state() == eState )
2399 bChanged = false;
2402 if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
2403 !StateToAttr( eState ) && static_cast<const SvxCharHiddenItem*>(pItem)->GetValue() )
2404 bChanged = true;
2406 if ( bChanged && eState != TRISTATE_INDET )
2408 rSet->Put( SvxCharHiddenItem( StateToAttr( eState ), nWhich ) );
2409 bModified = true;
2411 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2412 rSet->InvalidateItem(nWhich);
2414 bModified |= FillItemSetColor_Impl( *rSet );
2416 return bModified;
2419 void SvxCharEffectsPage::DisableControls( sal_uInt16 nDisable )
2421 if ( ( DISABLE_CASEMAP & nDisable ) == DISABLE_CASEMAP )
2423 m_xEffectsFT->set_sensitive(false);
2424 m_xEffectsLB->set_sensitive(false);
2427 if ( ( DISABLE_WORDLINE & nDisable ) == DISABLE_WORDLINE )
2428 m_xIndividualWordsBtn->set_sensitive(false);
2430 if ( ( DISABLE_BLINK & nDisable ) == DISABLE_BLINK )
2431 m_xBlinkingBtn->set_sensitive(false);
2433 if ( ( DISABLE_UNDERLINE_COLOR & nDisable ) == DISABLE_UNDERLINE_COLOR )
2435 // disable the controls
2436 m_xUnderlineColorFT->set_sensitive(false);
2437 m_xUnderlineColorLB->set_sensitive(false);
2438 m_bUnderlineColorDisabled = true;
2442 void SvxCharEffectsPage::PageCreated(const SfxAllItemSet& aSet)
2444 const SfxUInt16Item* pDisableCtlItem = aSet.GetItem<SfxUInt16Item>(SID_DISABLE_CTL, false);
2445 const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
2446 if (pDisableCtlItem)
2447 DisableControls(pDisableCtlItem->GetValue());
2449 if (pFlagItem)
2451 sal_uInt32 nFlags=pFlagItem->GetValue();
2452 if ( ( nFlags & SVX_ENABLE_FLASH ) == SVX_ENABLE_FLASH )
2453 m_xBlinkingBtn->show();
2454 if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
2455 // the writer uses SID_ATTR_BRUSH as font background
2456 m_bPreviewBackgroundToCharacter = true;
2460 // class SvxCharPositionPage ---------------------------------------------
2462 SvxCharPositionPage::SvxCharPositionPage(TabPageParent pParent, const SfxItemSet& rInSet)
2463 : SvxCharBasePage(pParent, "cui/ui/positionpage.ui", "PositionPage", rInSet)
2464 , m_nSuperEsc(short(DFLT_ESC_SUPER))
2465 , m_nSubEsc(short(DFLT_ESC_SUB))
2466 , m_nScaleWidthItemSetVal(100)
2467 , m_nScaleWidthInitialVal(100)
2468 , m_nSuperProp(sal_uInt8(DFLT_ESC_PROP))
2469 , m_nSubProp(sal_uInt8(DFLT_ESC_PROP))
2470 , m_xHighPosBtn(m_xBuilder->weld_radio_button("superscript"))
2471 , m_xNormalPosBtn(m_xBuilder->weld_radio_button("normal"))
2472 , m_xLowPosBtn(m_xBuilder->weld_radio_button("subscript"))
2473 , m_xHighLowFT(m_xBuilder->weld_label("raiselower"))
2474 , m_xHighLowMF(m_xBuilder->weld_metric_spin_button("raiselowersb", FieldUnit::PERCENT))
2475 , m_xHighLowRB(m_xBuilder->weld_check_button("automatic"))
2476 , m_xFontSizeFT(m_xBuilder->weld_label("relativefontsize"))
2477 , m_xFontSizeMF(m_xBuilder->weld_metric_spin_button("fontsizesb", FieldUnit::PERCENT))
2478 , m_xRotationContainer(m_xBuilder->weld_widget("rotationcontainer"))
2479 , m_xScalingFT(m_xBuilder->weld_label("scale"))
2480 , m_xScalingAndRotationFT(m_xBuilder->weld_label("rotateandscale"))
2481 , m_x0degRB(m_xBuilder->weld_radio_button("0deg"))
2482 , m_x90degRB(m_xBuilder->weld_radio_button("90deg"))
2483 , m_x270degRB(m_xBuilder->weld_radio_button("270deg"))
2484 , m_xFitToLineCB(m_xBuilder->weld_check_button("fittoline"))
2485 , m_xScaleWidthMF(m_xBuilder->weld_metric_spin_button("scalewidthsb", FieldUnit::PERCENT))
2486 , m_xKerningMF(m_xBuilder->weld_metric_spin_button("kerningsb", FieldUnit::POINT))
2487 , m_xPairKerningBtn(m_xBuilder->weld_check_button("pairkerning"))
2489 m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
2490 #ifdef IOS
2491 m_xPreviewWin->hide();
2492 #endif
2493 Initialize();
2496 SvxCharPositionPage::~SvxCharPositionPage()
2501 void SvxCharPositionPage::Initialize()
2503 // to handle the changes of the other pages
2504 SetExchangeSupport();
2506 GetPreviewFont().SetFontSize( Size( 0, 240 ) );
2507 GetPreviewCJKFont().SetFontSize( Size( 0, 240 ) );
2508 GetPreviewCTLFont().SetFontSize( Size( 0, 240 ) );
2510 m_xNormalPosBtn->set_active(true);
2511 PositionHdl_Impl(*m_xNormalPosBtn);
2513 Link<weld::ToggleButton&,void> aLink2 = LINK(this, SvxCharPositionPage, PositionHdl_Impl);
2514 m_xHighPosBtn->connect_toggled(aLink2);
2515 m_xNormalPosBtn->connect_toggled(aLink2);
2516 m_xLowPosBtn->connect_toggled(aLink2);
2518 aLink2 = LINK( this, SvxCharPositionPage, RotationHdl_Impl );
2519 m_x0degRB->connect_toggled(aLink2);
2520 m_x90degRB->connect_toggled(aLink2);
2521 m_x270degRB->connect_toggled(aLink2);
2523 Link<weld::MetricSpinButton&,void> aLink3 = LINK(this, SvxCharPositionPage, ValueChangedHdl_Impl);
2524 m_xHighLowMF->connect_value_changed(aLink3);
2525 m_xFontSizeMF->connect_value_changed(aLink3);
2527 m_xHighLowRB->connect_toggled(LINK(this, SvxCharPositionPage, AutoPositionHdl_Impl));
2528 m_xFitToLineCB->connect_toggled(LINK(this, SvxCharPositionPage, FitToLineHdl_Impl));
2529 m_xKerningMF->connect_value_changed(LINK(this, SvxCharPositionPage, KerningModifyHdl_Impl));
2530 m_xScaleWidthMF->connect_value_changed(LINK(this, SvxCharPositionPage, ScaleWidthModifyHdl_Impl));
2533 void SvxCharPositionPage::UpdatePreview_Impl( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
2535 SetPrevFontEscapement( nProp, nEscProp, nEsc );
2539 void SvxCharPositionPage::SetEscapement_Impl( SvxEscapement nEsc )
2541 SvxEscapementItem aEscItm( nEsc, SID_ATTR_CHAR_ESCAPEMENT );
2543 if ( SvxEscapement::Superscript == nEsc )
2545 aEscItm.GetEsc() = m_nSuperEsc;
2546 aEscItm.GetProportionalHeight() = m_nSuperProp;
2548 else if ( SvxEscapement::Subscript == nEsc )
2550 aEscItm.GetEsc() = m_nSubEsc;
2551 aEscItm.GetProportionalHeight() = m_nSubProp;
2554 short nFac = aEscItm.GetEsc() < 0 ? -1 : 1;
2556 m_xHighLowMF->set_value(aEscItm.GetEsc() * nFac, FieldUnit::PERCENT);
2557 m_xFontSizeMF->set_value(aEscItm.GetProportionalHeight(), FieldUnit::PERCENT);
2559 if ( SvxEscapement::Off == nEsc )
2561 m_xHighLowFT->set_sensitive(false);
2562 m_xHighLowMF->set_sensitive(false);
2563 m_xFontSizeFT->set_sensitive(false);
2564 m_xFontSizeMF->set_sensitive(false);
2565 m_xHighLowRB->set_sensitive(false);
2567 else
2569 m_xFontSizeFT->set_sensitive(true);
2570 m_xFontSizeMF->set_sensitive(true);
2571 m_xHighLowRB->set_sensitive(true);
2573 if (!m_xHighLowRB->get_active())
2575 m_xHighLowFT->set_sensitive(true);
2576 m_xHighLowMF->set_sensitive(true);
2578 else
2579 AutoPositionHdl_Impl(*m_xHighLowRB);
2582 UpdatePreview_Impl( 100, aEscItm.GetProportionalHeight(), aEscItm.GetEsc() );
2586 IMPL_LINK_NOARG(SvxCharPositionPage, PositionHdl_Impl, weld::ToggleButton&, void)
2588 SvxEscapement nEsc = SvxEscapement::Off; // also when pBtn == NULL
2590 if (m_xHighPosBtn->get_active())
2591 nEsc = SvxEscapement::Superscript;
2592 else if (m_xLowPosBtn->get_active())
2593 nEsc = SvxEscapement::Subscript;
2595 SetEscapement_Impl( nEsc );
2598 IMPL_LINK_NOARG(SvxCharPositionPage, RotationHdl_Impl, weld::ToggleButton&, void)
2600 bool bEnable = false;
2601 if (m_x90degRB->get_active() || m_x270degRB->get_active())
2602 bEnable = true;
2603 else
2604 OSL_ENSURE(m_x0degRB->get_active(), "unexpected button");
2605 m_xFitToLineCB->set_sensitive(bEnable);
2608 void SvxCharPositionPage::FontModifyHdl_Impl()
2610 sal_uInt8 nEscProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
2611 short nEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT));
2612 nEsc *= m_xLowPosBtn->get_active() ? -1 : 1;
2613 UpdatePreview_Impl( 100, nEscProp, nEsc );
2616 IMPL_LINK(SvxCharPositionPage, AutoPositionHdl_Impl, weld::ToggleButton&, rBox, void)
2618 if (rBox.get_active())
2620 m_xHighLowFT->set_sensitive(false);
2621 m_xHighLowMF->set_sensitive(false);
2623 else
2624 PositionHdl_Impl(m_xHighPosBtn->get_active() ? *m_xHighPosBtn
2625 : m_xLowPosBtn->get_active() ? *m_xLowPosBtn
2626 : *m_xNormalPosBtn);
2629 IMPL_LINK_NOARG(SvxCharPositionPage, FitToLineHdl_Impl, weld::ToggleButton&, void)
2631 sal_uInt16 nVal = m_nScaleWidthInitialVal;
2632 if (m_xFitToLineCB->get_active())
2633 nVal = m_nScaleWidthItemSetVal;
2634 m_xScaleWidthMF->set_value(nVal, FieldUnit::PERCENT);
2635 m_aPreviewWin.SetFontWidthScale( nVal );
2638 IMPL_LINK_NOARG(SvxCharPositionPage, KerningModifyHdl_Impl, weld::MetricSpinButton&, void)
2640 long nVal = static_cast<long>(m_xKerningMF->get_value(FieldUnit::POINT));
2641 nVal = LogicToLogic( nVal, MapUnit::MapPoint, MapUnit::MapTwip );
2642 long nKern = static_cast<short>(m_xKerningMF->denormalize(nVal));
2644 SvxFont& rFont = GetPreviewFont();
2645 SvxFont& rCJKFont = GetPreviewCJKFont();
2646 SvxFont& rCTLFont = GetPreviewCTLFont();
2648 rFont.SetFixKerning( static_cast<short>(nKern) );
2649 rCJKFont.SetFixKerning( static_cast<short>(nKern) );
2650 rCTLFont.SetFixKerning( static_cast<short>(nKern) );
2651 m_aPreviewWin.Invalidate();
2654 IMPL_LINK(SvxCharPositionPage, ValueChangedHdl_Impl, weld::MetricSpinButton&, rField, void)
2656 bool bHigh = m_xHighPosBtn->get_active();
2657 bool bLow = m_xLowPosBtn->get_active();
2658 DBG_ASSERT( bHigh || bLow, "normal position is not valid" );
2660 if (m_xHighLowMF.get() == &rField)
2662 if ( bLow )
2663 m_nSubEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT)) * -1;
2664 else
2665 m_nSuperEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT));
2667 else if (m_xFontSizeMF.get() == &rField)
2669 if ( bLow )
2670 m_nSubProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
2671 else
2672 m_nSuperProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
2675 FontModifyHdl_Impl();
2678 IMPL_LINK_NOARG(SvxCharPositionPage, ScaleWidthModifyHdl_Impl, weld::MetricSpinButton&, void)
2680 m_aPreviewWin.SetFontWidthScale(sal_uInt16(m_xScaleWidthMF->get_value(FieldUnit::PERCENT)));
2683 DeactivateRC SvxCharPositionPage::DeactivatePage( SfxItemSet* _pSet )
2685 if ( _pSet )
2686 FillItemSet( _pSet );
2687 return DeactivateRC::LeavePage;
2690 VclPtr<SfxTabPage> SvxCharPositionPage::Create(TabPageParent pParent, const SfxItemSet* rSet)
2692 return VclPtr<SvxCharPositionPage>::Create(pParent, *rSet);
2695 void SvxCharPositionPage::Reset( const SfxItemSet* rSet )
2697 OUString sUser = GetUserData();
2699 if ( !sUser.isEmpty() )
2701 sal_Int32 nIdx {0};
2702 m_nSuperEsc = static_cast<short>(sUser.getToken( 0, ';', nIdx ).toInt32());
2703 m_nSubEsc = static_cast<short>(sUser.getToken( 0, ';', nIdx ).toInt32());
2704 m_nSuperProp = static_cast<sal_uInt8>(sUser.getToken( 0, ';', nIdx ).toInt32());
2705 m_nSubProp = static_cast<sal_uInt8>(sUser.getToken( 0, ';', nIdx ).toInt32());
2707 // tdf#120412 up to 14400% (eg. 1584 pt with 11 pt letters)
2708 m_xHighLowMF->set_max(14400, FieldUnit::PERCENT);
2710 //fdo#75307 validate all the entries and discard all of them if any are
2711 //out of range
2712 bool bValid = true;
2713 if (m_nSuperEsc < m_xHighLowMF->get_min(FieldUnit::PERCENT) || m_nSuperEsc > m_xHighLowMF->get_max(FieldUnit::PERCENT))
2714 bValid = false;
2715 if (m_nSubEsc*-1 < m_xHighLowMF->get_min(FieldUnit::PERCENT) || m_nSubEsc*-1 > m_xHighLowMF->get_max(FieldUnit::PERCENT))
2716 bValid = false;
2717 if (m_nSuperProp < m_xFontSizeMF->get_min(FieldUnit::PERCENT) || m_nSuperProp > m_xFontSizeMF->get_max(FieldUnit::PERCENT))
2718 bValid = false;
2719 if (m_nSubProp < m_xFontSizeMF->get_min(FieldUnit::PERCENT) || m_nSubProp > m_xFontSizeMF->get_max(FieldUnit::PERCENT))
2720 bValid = false;
2722 if (!bValid)
2724 m_nSuperEsc = DFLT_ESC_SUPER;
2725 m_nSubEsc = DFLT_ESC_SUB;
2726 m_nSuperProp = DFLT_ESC_PROP;
2727 m_nSubProp = DFLT_ESC_PROP;
2731 short nEsc = 0;
2732 sal_uInt8 nEscProp = 100;
2734 m_xHighLowFT->set_sensitive(false);
2735 m_xHighLowMF->set_sensitive(false);
2736 m_xFontSizeFT->set_sensitive(false);
2737 m_xFontSizeMF->set_sensitive(false);
2739 SvxFont& rFont = GetPreviewFont();
2740 SvxFont& rCJKFont = GetPreviewCJKFont();
2741 SvxFont& rCTLFont = GetPreviewCTLFont();
2742 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_ESCAPEMENT );
2744 if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
2746 const SvxEscapementItem& rItem = static_cast<const SvxEscapementItem&>(rSet->Get( nWhich ));
2747 nEsc = rItem.GetEsc();
2748 nEscProp = rItem.GetProportionalHeight();
2750 if ( nEsc != 0 )
2752 m_xHighLowFT->set_sensitive(true);
2753 m_xHighLowMF->set_sensitive(true);
2754 m_xFontSizeFT->set_sensitive(true);
2755 m_xFontSizeMF->set_sensitive(true);
2757 short nFac;
2758 bool bAutomatic(false);
2760 if ( nEsc > 0 )
2762 nFac = 1;
2763 m_xHighPosBtn->set_active(true);
2764 if ( nEsc == DFLT_ESC_AUTO_SUPER )
2766 nEsc = DFLT_ESC_SUPER;
2767 bAutomatic = true;
2770 else
2772 nFac = -1;
2773 m_xLowPosBtn->set_active(true);
2774 if ( nEsc == DFLT_ESC_AUTO_SUB )
2776 nEsc = DFLT_ESC_SUB;
2777 bAutomatic = true;
2780 if (!m_xHighLowRB->get_sensitive())
2782 m_xHighLowRB->set_sensitive(true);
2784 m_xHighLowRB->set_active(bAutomatic);
2786 if (m_xHighLowRB->get_active())
2788 m_xHighLowFT->set_sensitive(false);
2789 m_xHighLowMF->set_sensitive(false);
2791 m_xHighLowMF->set_value(m_xHighLowMF->normalize(nFac * nEsc), FieldUnit::PERCENT);
2793 else
2795 m_xNormalPosBtn->set_active(true);
2796 m_xHighLowRB->set_active(true);
2797 PositionHdl_Impl(*m_xNormalPosBtn);
2799 //the height has to be set after the handler is called to keep the value also if the escapement is zero
2800 m_xFontSizeMF->set_value(m_xFontSizeMF->normalize(nEscProp), FieldUnit::PERCENT);
2802 else
2804 m_xHighPosBtn->set_active(false);
2805 m_xNormalPosBtn->set_active(false);
2806 m_xLowPosBtn->set_active(false);
2809 // set BspFont
2810 SetPrevFontEscapement( 100, nEscProp, nEsc );
2812 // Kerning
2813 nWhich = GetWhich( SID_ATTR_CHAR_KERNING );
2815 if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
2817 const SvxKerningItem& rItem = static_cast<const SvxKerningItem&>(rSet->Get( nWhich ));
2818 MapUnit eUnit = rSet->GetPool()->GetMetric( nWhich );
2819 long nBig = static_cast<long>(m_xKerningMF->normalize( static_cast<long>(rItem.GetValue()) ));
2820 long nKerning = LogicToLogic( nBig, eUnit, MapUnit::MapPoint );
2822 // set Kerning at the Font, convert into Twips before
2823 long nKern = LogicToLogic( rItem.GetValue(), eUnit, MapUnit::MapTwip );
2824 rFont.SetFixKerning( static_cast<short>(nKern) );
2825 rCJKFont.SetFixKerning( static_cast<short>(nKern) );
2826 rCTLFont.SetFixKerning( static_cast<short>(nKern) );
2828 //the attribute value must be displayed also if it's above the maximum allowed value
2829 long nVal = static_cast<long>(m_xKerningMF->get_max(FieldUnit::POINT));
2830 if(nVal < nKerning)
2831 m_xKerningMF->set_max(nKerning, FieldUnit::POINT);
2832 m_xKerningMF->set_value(nKerning, FieldUnit::POINT);
2834 else
2835 m_xKerningMF->set_text(OUString());
2837 // Pair kerning
2838 nWhich = GetWhich( SID_ATTR_CHAR_AUTOKERN );
2840 if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
2842 const SvxAutoKernItem& rItem = static_cast<const SvxAutoKernItem&>(rSet->Get( nWhich ));
2843 m_xPairKerningBtn->set_active(rItem.GetValue());
2845 else
2846 m_xPairKerningBtn->set_active(false);
2848 // Scale Width
2849 nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
2850 if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
2852 const SvxCharScaleWidthItem& rItem = static_cast<const SvxCharScaleWidthItem&>( rSet->Get( nWhich ) );
2853 m_nScaleWidthInitialVal = rItem.GetValue();
2854 m_xScaleWidthMF->set_value(m_nScaleWidthInitialVal, FieldUnit::PERCENT);
2856 else
2857 m_xScaleWidthMF->set_value(100, FieldUnit::PERCENT);
2859 nWhich = GetWhich( SID_ATTR_CHAR_WIDTH_FIT_TO_LINE );
2860 if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
2861 m_nScaleWidthItemSetVal = static_cast<const SfxUInt16Item&>( rSet->Get( nWhich )).GetValue();
2863 // Rotation
2864 nWhich = GetWhich( SID_ATTR_CHAR_ROTATED );
2865 SfxItemState eState = rSet->GetItemState( nWhich );
2866 if( SfxItemState::UNKNOWN == eState )
2868 m_xRotationContainer->hide();
2869 m_xScalingAndRotationFT->hide();
2870 m_xScalingFT->show();
2872 else
2874 m_xRotationContainer->show();
2875 m_xScalingAndRotationFT->show();
2876 m_xScalingFT->hide();
2878 if( eState >= SfxItemState::DEFAULT )
2880 const SvxCharRotateItem& rItem =
2881 static_cast<const SvxCharRotateItem&>( rSet->Get( nWhich ));
2882 if (rItem.IsBottomToTop())
2883 m_x90degRB->set_active(true);
2884 else if (rItem.IsTopToBottom())
2885 m_x270degRB->set_active(true);
2886 else
2888 DBG_ASSERT( 0 == rItem.GetValue(), "incorrect value" );
2889 m_x0degRB->set_active(true);
2891 m_xFitToLineCB->set_active(rItem.IsFitToLine());
2893 else
2895 if( eState == SfxItemState::DONTCARE )
2897 m_x0degRB->set_active(false);
2898 m_x90degRB->set_active(false);
2899 m_x270degRB->set_active(false);
2901 else
2902 m_x0degRB->set_active(true);
2904 m_xFitToLineCB->set_active(false);
2906 m_xFitToLineCB->set_sensitive(!m_x0degRB->get_active());
2908 // is this value set?
2909 if( SfxItemState::UNKNOWN == rSet->GetItemState( GetWhich(
2910 SID_ATTR_CHAR_WIDTH_FIT_TO_LINE ) ))
2911 m_xFitToLineCB->hide();
2913 ChangesApplied();
2916 void SvxCharPositionPage::ChangesApplied()
2918 m_xHighPosBtn->save_state();
2919 m_xNormalPosBtn->save_state();
2920 m_xLowPosBtn->save_state();
2921 m_xHighLowRB->save_state();
2922 m_x0degRB->save_state();
2923 m_x90degRB->save_state();
2924 m_x270degRB->save_state();
2925 m_xFitToLineCB->save_state();
2926 m_xScaleWidthMF->save_value();
2927 m_xKerningMF->save_value();
2928 m_xPairKerningBtn->save_state();
2931 bool SvxCharPositionPage::FillItemSet( SfxItemSet* rSet )
2933 // Position (high, normal or low)
2934 const SfxItemSet& rOldSet = GetItemSet();
2935 bool bModified = false, bChanged = true;
2936 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_ESCAPEMENT );
2937 const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_ESCAPEMENT );
2938 const bool bHigh = m_xHighPosBtn->get_active();
2939 short nEsc;
2940 sal_uInt8 nEscProp;
2942 if (bHigh || m_xLowPosBtn->get_active())
2944 if (m_xHighLowRB->get_active())
2945 nEsc = bHigh ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB;
2946 else
2948 nEsc = static_cast<short>(m_xHighLowMF->denormalize(m_xHighLowMF->get_value(FieldUnit::PERCENT)));
2949 nEsc *= (bHigh ? 1 : -1);
2951 nEscProp = static_cast<sal_uInt8>(m_xFontSizeMF->denormalize(m_xFontSizeMF->get_value(FieldUnit::PERCENT)));
2953 else
2955 nEsc = 0;
2956 nEscProp = 100;
2959 if ( pOld )
2961 const SvxEscapementItem& rItem = *static_cast<const SvxEscapementItem*>(pOld);
2962 if (rItem.GetEsc() == nEsc && rItem.GetProportionalHeight() == nEscProp)
2963 bChanged = false;
2966 if ( !bChanged && !m_xHighPosBtn->get_saved_state() &&
2967 !m_xNormalPosBtn->get_saved_state() && !m_xLowPosBtn->get_saved_state() )
2968 bChanged = true;
2970 if ( bChanged &&
2971 ( m_xHighPosBtn->get_active() || m_xNormalPosBtn->get_active() || m_xLowPosBtn->get_active() ) )
2973 rSet->Put( SvxEscapementItem( nEsc, nEscProp, nWhich ) );
2974 bModified = true;
2976 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
2977 rSet->InvalidateItem(nWhich);
2979 bChanged = true;
2981 // Kerning
2982 nWhich = GetWhich( SID_ATTR_CHAR_KERNING );
2983 pOld = GetOldItem( *rSet, SID_ATTR_CHAR_KERNING );
2984 short nKerning = 0;
2985 MapUnit eUnit = rSet->GetPool()->GetMetric( nWhich );
2987 long nTmp = static_cast<long>(m_xKerningMF->get_value(FieldUnit::POINT));
2988 long nVal = LogicToLogic( nTmp, MapUnit::MapPoint, eUnit );
2989 nKerning = static_cast<short>(m_xKerningMF->denormalize( nVal ));
2991 SfxItemState eOldKernState = rOldSet.GetItemState( nWhich, false );
2992 if ( pOld )
2994 const SvxKerningItem& rItem = *static_cast<const SvxKerningItem*>(pOld);
2995 if ( (eOldKernState >= SfxItemState::DEFAULT || m_xKerningMF->get_text().isEmpty()) && rItem.GetValue() == nKerning )
2996 bChanged = false;
2999 if ( bChanged )
3001 rSet->Put( SvxKerningItem( nKerning, nWhich ) );
3002 bModified = true;
3004 else if ( SfxItemState::DEFAULT == eOldKernState )
3005 rSet->InvalidateItem(nWhich);
3007 // Pair-Kerning
3008 nWhich = GetWhich( SID_ATTR_CHAR_AUTOKERN );
3010 if (m_xPairKerningBtn->get_state_changed_from_saved())
3012 rSet->Put( SvxAutoKernItem( m_xPairKerningBtn->get_active(), nWhich ) );
3013 bModified = true;
3015 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
3016 rSet->InvalidateItem(nWhich);
3018 // Scale Width
3019 nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
3020 if (m_xScaleWidthMF->get_value_changed_from_saved())
3022 rSet->Put(SvxCharScaleWidthItem(static_cast<sal_uInt16>(m_xScaleWidthMF->get_value(FieldUnit::PERCENT)), nWhich));
3023 bModified = true;
3025 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
3026 rSet->InvalidateItem(nWhich);
3028 // Rotation
3029 nWhich = GetWhich( SID_ATTR_CHAR_ROTATED );
3030 if ( m_x0degRB->get_state_changed_from_saved() ||
3031 m_x90degRB->get_state_changed_from_saved() ||
3032 m_x270degRB->get_state_changed_from_saved() ||
3033 m_xFitToLineCB->get_state_changed_from_saved() )
3035 SvxCharRotateItem aItem( 0, m_xFitToLineCB->get_active(), nWhich );
3036 if (m_x90degRB->get_active())
3037 aItem.SetBottomToTop();
3038 else if (m_x270degRB->get_active())
3039 aItem.SetTopToBottom();
3040 rSet->Put( aItem );
3041 bModified = true;
3043 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
3044 rSet->InvalidateItem(nWhich);
3046 return bModified;
3050 void SvxCharPositionPage::FillUserData()
3052 const OUString cTok( ";" );
3054 OUString sUser = OUString::number( m_nSuperEsc ) + cTok +
3055 OUString::number( m_nSubEsc ) + cTok +
3056 OUString::number( m_nSuperProp ) + cTok +
3057 OUString::number( m_nSubProp );
3058 SetUserData( sUser );
3062 void SvxCharPositionPage::PageCreated(const SfxAllItemSet& aSet)
3064 const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
3065 if (pFlagItem)
3067 sal_uInt32 nFlags=pFlagItem->GetValue();
3068 if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
3069 // the writer uses SID_ATTR_BRUSH as font background
3070 m_bPreviewBackgroundToCharacter = true;
3073 // class SvxCharTwoLinesPage ------------------------------------------------
3075 SvxCharTwoLinesPage::SvxCharTwoLinesPage(TabPageParent pParent, const SfxItemSet& rInSet)
3076 : SvxCharBasePage(pParent, "cui/ui/twolinespage.ui", "TwoLinesPage", rInSet)
3077 , m_nStartBracketPosition( 0 )
3078 , m_nEndBracketPosition( 0 )
3079 , m_xTwoLinesBtn(m_xBuilder->weld_check_button("twolines"))
3080 , m_xEnclosingFrame(m_xBuilder->weld_widget("enclosing"))
3081 , m_xStartBracketLB(m_xBuilder->weld_tree_view("startbracket"))
3082 , m_xEndBracketLB(m_xBuilder->weld_tree_view("endbracket"))
3084 for (size_t i = 0; i < SAL_N_ELEMENTS(TWOLINE_OPEN); ++i)
3085 m_xStartBracketLB->append(OUString::number(TWOLINE_OPEN[i].second), CuiResId(TWOLINE_OPEN[i].first));
3086 for (size_t i = 0; i < SAL_N_ELEMENTS(TWOLINE_CLOSE); ++i)
3087 m_xEndBracketLB->append(OUString::number(TWOLINE_CLOSE[i].second), CuiResId(TWOLINE_CLOSE[i].first));
3089 m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
3090 #ifdef IOS
3091 m_xPreviewWin->hide();
3092 #endif
3093 Initialize();
3096 SvxCharTwoLinesPage::~SvxCharTwoLinesPage()
3100 void SvxCharTwoLinesPage::Initialize()
3102 m_xTwoLinesBtn->set_active(false);
3103 TwoLinesHdl_Impl(*m_xTwoLinesBtn);
3105 m_xTwoLinesBtn->connect_toggled(LINK(this, SvxCharTwoLinesPage, TwoLinesHdl_Impl));
3107 Link<weld::TreeView&,void> aLink = LINK(this, SvxCharTwoLinesPage, CharacterMapHdl_Impl);
3108 m_xStartBracketLB->connect_changed(aLink);
3109 m_xEndBracketLB->connect_changed(aLink);
3111 SvxFont& rFont = GetPreviewFont();
3112 SvxFont& rCJKFont = GetPreviewCJKFont();
3113 SvxFont& rCTLFont = GetPreviewCTLFont();
3114 rFont.SetFontSize( Size( 0, 220 ) );
3115 rCJKFont.SetFontSize( Size( 0, 220 ) );
3116 rCTLFont.SetFontSize( Size( 0, 220 ) );
3119 void SvxCharTwoLinesPage::SelectCharacter(weld::TreeView* pBox)
3121 bool bStart = pBox == m_xStartBracketLB.get();
3122 SvxCharacterMap aDlg(GetFrameWeld(), nullptr, nullptr);
3123 aDlg.DisableFontSelection();
3125 if (aDlg.run() == RET_OK)
3127 sal_Unicode cChar = static_cast<sal_Unicode>(aDlg.GetChar());
3128 SetBracket( cChar, bStart );
3130 else
3132 pBox->select(bStart ? m_nStartBracketPosition : m_nEndBracketPosition);
3137 void SvxCharTwoLinesPage::SetBracket( sal_Unicode cBracket, bool bStart )
3139 int nEntryPos = 0;
3140 weld::TreeView* pBox = bStart ? m_xStartBracketLB.get() : m_xEndBracketLB.get();
3141 if (cBracket == 0)
3142 pBox->select(0);
3143 else
3145 bool bFound = false;
3146 for (int i = 1; i < pBox->n_children(); ++i)
3148 if (pBox->get_id(i).toInt32() != CHRDLG_ENCLOSE_SPECIAL_CHAR)
3150 const sal_Unicode cChar = pBox->get_text(i)[0];
3151 if (cChar == cBracket)
3153 pBox->select(i);
3154 nEntryPos = i;
3155 bFound = true;
3156 break;
3161 if (!bFound)
3163 pBox->append_text(OUString(cBracket));
3164 nEntryPos = pBox->n_children() - 1;
3165 pBox->select(nEntryPos);
3168 if (bStart)
3169 m_nStartBracketPosition = nEntryPos;
3170 else
3171 m_nEndBracketPosition = nEntryPos;
3174 IMPL_LINK_NOARG(SvxCharTwoLinesPage, TwoLinesHdl_Impl, weld::ToggleButton&, void)
3176 bool bChecked = m_xTwoLinesBtn->get_active();
3177 m_xEnclosingFrame->set_sensitive(bChecked);
3178 UpdatePreview_Impl();
3181 IMPL_LINK(SvxCharTwoLinesPage, CharacterMapHdl_Impl, weld::TreeView&, rBox, void)
3183 int nPos = rBox.get_selected_index();
3184 if (rBox.get_id(nPos).toInt32() == CHRDLG_ENCLOSE_SPECIAL_CHAR)
3185 SelectCharacter( &rBox );
3186 else
3188 bool bStart = &rBox == m_xStartBracketLB.get();
3189 if (bStart)
3190 m_nStartBracketPosition = nPos;
3191 else
3192 m_nEndBracketPosition = nPos;
3194 UpdatePreview_Impl();
3197 void SvxCharTwoLinesPage::ActivatePage( const SfxItemSet& rSet )
3199 SvxCharBasePage::ActivatePage(rSet);
3202 DeactivateRC SvxCharTwoLinesPage::DeactivatePage( SfxItemSet* _pSet )
3204 if ( _pSet )
3205 FillItemSet( _pSet );
3206 return DeactivateRC::LeavePage;
3209 VclPtr<SfxTabPage> SvxCharTwoLinesPage::Create(TabPageParent pParent, const SfxItemSet* rSet)
3211 return VclPtr<SvxCharTwoLinesPage>::Create(pParent, *rSet);
3214 void SvxCharTwoLinesPage::Reset( const SfxItemSet* rSet )
3216 m_xTwoLinesBtn->set_active(false);
3217 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
3218 SfxItemState eState = rSet->GetItemState( nWhich );
3220 if ( eState >= SfxItemState::DONTCARE )
3222 const SvxTwoLinesItem& rItem = static_cast<const SvxTwoLinesItem&>(rSet->Get( nWhich ));
3223 m_xTwoLinesBtn->set_active(rItem.GetValue());
3225 if ( rItem.GetValue() )
3227 SetBracket( rItem.GetStartBracket(), true );
3228 SetBracket( rItem.GetEndBracket(), false );
3231 TwoLinesHdl_Impl(*m_xTwoLinesBtn);
3233 SetPrevFontWidthScale( *rSet );
3236 bool SvxCharTwoLinesPage::FillItemSet( SfxItemSet* rSet )
3238 const SfxItemSet& rOldSet = GetItemSet();
3239 bool bModified = false, bChanged = true;
3240 sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
3241 const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_TWO_LINES );
3242 bool bOn = m_xTwoLinesBtn->get_active();
3243 sal_Unicode cStart = ( bOn && m_xStartBracketLB->get_selected_index() > 0 )
3244 ? m_xStartBracketLB->get_selected_text()[0] : 0;
3245 sal_Unicode cEnd = ( bOn && m_xEndBracketLB->get_selected_index() > 0 )
3246 ? m_xEndBracketLB->get_selected_text()[0] : 0;
3248 if ( pOld )
3250 const SvxTwoLinesItem& rItem = *static_cast<const SvxTwoLinesItem*>(pOld);
3251 if ( rItem.GetValue() == bOn &&
3252 ( !bOn || ( rItem.GetStartBracket() == cStart && rItem.GetEndBracket() == cEnd ) ) )
3253 bChanged = false;
3256 if ( bChanged )
3258 rSet->Put( SvxTwoLinesItem( bOn, cStart, cEnd, nWhich ) );
3259 bModified = true;
3261 else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
3262 rSet->InvalidateItem(nWhich);
3264 return bModified;
3267 void SvxCharTwoLinesPage::UpdatePreview_Impl()
3269 sal_Unicode cStart = m_xStartBracketLB->get_selected_index() > 0
3270 ? m_xStartBracketLB->get_selected_text()[0] : 0;
3271 sal_Unicode cEnd = m_xEndBracketLB->get_selected_index() > 0
3272 ? m_xEndBracketLB->get_selected_text()[0] : 0;
3273 m_aPreviewWin.SetBrackets(cStart, cEnd);
3274 m_aPreviewWin.SetTwoLines(m_xTwoLinesBtn->get_active());
3275 m_aPreviewWin.Invalidate();
3278 void SvxCharTwoLinesPage::PageCreated(const SfxAllItemSet& aSet)
3280 const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
3281 if (pFlagItem)
3283 sal_uInt32 nFlags=pFlagItem->GetValue();
3284 if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
3285 // the writer uses SID_ATTR_BRUSH as font background
3286 m_bPreviewBackgroundToCharacter = true;
3290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */