bump product version to 5.0.4.1
[LibreOffice.git] / starmath / source / dialog.cxx
blob840c2a7baf0073f4c7374bf1df07f99ec145fdd9
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 "tools/rcid.h"
21 #include <comphelper/string.hxx>
22 #include <svl/eitem.hxx>
23 #include <svl/intitem.hxx>
24 #include <svl/stritem.hxx>
25 #include <sfx2/app.hxx>
26 #include <vcl/builderfactory.hxx>
27 #include <vcl/layout.hxx>
28 #include <vcl/msgbox.hxx>
29 #include <svtools/ctrltool.hxx>
30 #include <sfx2/printer.hxx>
31 #include <vcl/help.hxx>
32 #include <vcl/waitobj.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/wall.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/sfx.hrc>
37 #include <osl/diagnose.h>
38 #include <svx/ucsubset.hxx>
40 #include "dialog.hxx"
41 #include "starmath.hrc"
42 #include "config.hxx"
43 #include "smmod.hxx"
44 #include "symbol.hxx"
45 #include "view.hxx"
46 #include "document.hxx"
47 #include "unomodel.hxx"
50 namespace
53 void lclGetSettingColors(Color& rBackgroundColor, Color& rTextColor)
55 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
56 if (rStyleSettings.GetHighContrastMode())
58 rBackgroundColor = rStyleSettings.GetFieldColor().GetColor();
59 rTextColor = rStyleSettings.GetFieldTextColor().GetColor();
61 else
63 rBackgroundColor = COL_WHITE;
64 rTextColor = COL_BLACK;
68 } // end anonymous namespace
70 // Since it's better to set/query the FontStyle via its attributes rather
71 // than via the StyleName we create a way to translate
72 // Attribute <-> StyleName
74 class SmFontStyles
76 OUString aNormal;
77 OUString aBold;
78 OUString aItalic;
79 OUString aBoldItalic;
80 OUString aEmpty;
82 public:
83 SmFontStyles();
85 static sal_uInt16 GetCount() { return 4; }
86 const OUString& GetStyleName(const vcl::Font& rFont) const;
87 const OUString& GetStyleName(sal_uInt16 nIdx) const;
90 SmFontStyles::SmFontStyles() :
91 aNormal (ResId(RID_FONTREGULAR, *SM_MOD()->GetResMgr())),
92 aBold (ResId(RID_FONTBOLD, *SM_MOD()->GetResMgr())),
93 aItalic (ResId(RID_FONTITALIC, *SM_MOD()->GetResMgr()))
96 aBoldItalic = aBold;
97 aBoldItalic += ", ";
98 aBoldItalic += aItalic;
101 const OUString& SmFontStyles::GetStyleName(const vcl::Font& rFont) const
103 //! compare also SmSpecialNode::Prepare
104 bool bBold = IsBold( rFont ),
105 bItalic = IsItalic( rFont );
107 if (bBold && bItalic)
108 return aBoldItalic;
109 else if (bItalic)
110 return aItalic;
111 else if (bBold)
112 return aBold;
113 return aNormal;
116 const OUString& SmFontStyles::GetStyleName( sal_uInt16 nIdx ) const
118 // 0 = "normal", 1 = "italic",
119 // 2 = "bold", 3 = "bold italic"
121 #if OSL_DEBUG_LEVEL > 1
122 OSL_ENSURE( nIdx < GetCount(), "index out of range" );
123 #endif
124 switch (nIdx)
126 case 0 : return aNormal;
127 case 1 : return aItalic;
128 case 2 : return aBold;
129 case 3 : return aBoldItalic;
131 return aEmpty;
134 const SmFontStyles & GetFontStyles()
136 static const SmFontStyles aImpl;
137 return aImpl;
140 void SetFontStyle(const OUString &rStyleName, vcl::Font &rFont)
142 // Find index related to StyleName. For an empty StyleName it's assumed to be
143 // 0 (neither bold nor italic).
144 sal_uInt16 nIndex = 0;
145 if (!rStyleName.isEmpty())
147 sal_uInt16 i;
148 const SmFontStyles &rStyles = GetFontStyles();
149 for (i = 0; i < SmFontStyles::GetCount(); ++i)
150 if (rStyleName == rStyles.GetStyleName(i))
151 break;
152 #if OSL_DEBUG_LEVEL > 1
153 OSL_ENSURE(i < rStyles.GetCount(), "style-name unknown");
154 #endif
155 nIndex = i;
158 rFont.SetItalic((nIndex & 0x1) ? ITALIC_NORMAL : ITALIC_NONE);
159 rFont.SetWeight((nIndex & 0x2) ? WEIGHT_BOLD : WEIGHT_NORMAL);
162 IMPL_LINK( SmPrintOptionsTabPage, SizeButtonClickHdl, Button *,/*pButton*/ )
164 m_pZoom->Enable(m_pSizeZoomed->IsChecked());
165 return 0;
168 SmPrintOptionsTabPage::SmPrintOptionsTabPage(vcl::Window* pParent, const SfxItemSet& rOptions)
169 : SfxTabPage(pParent, "SmathSettings", "modules/smath/ui/smathsettings.ui", &rOptions)
171 get( m_pTitle, "title");
172 get( m_pText, "text");
173 get( m_pFrame, "frame");
174 get( m_pSizeNormal, "sizenormal");
175 get( m_pSizeScaled, "sizescaled");
176 get( m_pSizeZoomed, "sizezoomed");
177 get( m_pZoom, "zoom");
178 get( m_pNoRightSpaces, "norightspaces");
179 get( m_pSaveOnlyUsedSymbols, "saveonlyusedsymbols");
181 m_pSizeNormal->SetClickHdl(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
182 m_pSizeScaled->SetClickHdl(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
183 m_pSizeZoomed->SetClickHdl(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
185 Reset(&rOptions);
188 SmPrintOptionsTabPage::~SmPrintOptionsTabPage()
190 disposeOnce();
193 void SmPrintOptionsTabPage::dispose()
195 m_pTitle.clear();
196 m_pText.clear();
197 m_pFrame.clear();
198 m_pSizeNormal.clear();
199 m_pSizeScaled.clear();
200 m_pSizeZoomed.clear();
201 m_pZoom.clear();
202 m_pNoRightSpaces.clear();
203 m_pSaveOnlyUsedSymbols.clear();
204 SfxTabPage::dispose();
208 bool SmPrintOptionsTabPage::FillItemSet(SfxItemSet* rSet)
210 sal_uInt16 nPrintSize;
211 if (m_pSizeNormal->IsChecked())
212 nPrintSize = PRINT_SIZE_NORMAL;
213 else if (m_pSizeScaled->IsChecked())
214 nPrintSize = PRINT_SIZE_SCALED;
215 else
216 nPrintSize = PRINT_SIZE_ZOOMED;
218 rSet->Put(SfxUInt16Item(GetWhich(SID_PRINTSIZE), (sal_uInt16) nPrintSize));
219 rSet->Put(SfxUInt16Item(GetWhich(SID_PRINTZOOM), (sal_uInt16) m_pZoom->GetValue()));
220 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTTITLE), m_pTitle->IsChecked()));
221 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTTEXT), m_pText->IsChecked()));
222 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTFRAME), m_pFrame->IsChecked()));
223 rSet->Put(SfxBoolItem(GetWhich(SID_NO_RIGHT_SPACES), m_pNoRightSpaces->IsChecked()));
224 rSet->Put(SfxBoolItem(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS), m_pSaveOnlyUsedSymbols->IsChecked()));
226 return true;
230 void SmPrintOptionsTabPage::Reset(const SfxItemSet* rSet)
232 SmPrintSize ePrintSize = (SmPrintSize)static_cast<const SfxUInt16Item &>(rSet->Get(GetWhich(SID_PRINTSIZE))).GetValue();
234 m_pSizeNormal->Check(ePrintSize == PRINT_SIZE_NORMAL);
235 m_pSizeScaled->Check(ePrintSize == PRINT_SIZE_SCALED);
236 m_pSizeZoomed->Check(ePrintSize == PRINT_SIZE_ZOOMED);
238 m_pZoom->Enable(m_pSizeZoomed->IsChecked());
240 m_pZoom->SetValue(static_cast<const SfxUInt16Item &>(rSet->Get(GetWhich(SID_PRINTZOOM))).GetValue());
242 m_pTitle->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_PRINTTITLE))).GetValue());
243 m_pText->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_PRINTTEXT))).GetValue());
244 m_pFrame->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_PRINTFRAME))).GetValue());
245 m_pNoRightSpaces->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_NO_RIGHT_SPACES))).GetValue());
246 m_pSaveOnlyUsedSymbols->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS))).GetValue());
249 VclPtr<SfxTabPage> SmPrintOptionsTabPage::Create(vcl::Window* pWindow, const SfxItemSet& rSet)
251 return VclPtr<SmPrintOptionsTabPage>::Create(pWindow, rSet).get();
254 void SmShowFont::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
256 Window::Paint(rRenderContext, rRect);
258 Color aBackColor;
259 Color aTextColor;
260 lclGetSettingColors(aBackColor, aTextColor);
262 rRenderContext.SetBackground(Wallpaper(aBackColor));
264 vcl::Font aFont(maFont);
265 aFont.SetSize(Size(0, 24 * rRenderContext.GetDPIScaleFactor()));
266 aFont.SetAlign(ALIGN_TOP);
267 rRenderContext.SetFont(aFont);
268 rRenderContext.SetTextColor(aTextColor);
270 OUString sText(rRenderContext.GetFont().GetName());
271 Size aTextSize(rRenderContext.GetTextWidth(sText), rRenderContext.GetTextHeight());
273 rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
274 (rRenderContext.GetOutputSize().Height() - aTextSize.Height()) / 2), sText);
277 VCL_BUILDER_DECL_FACTORY(SmShowFont)
279 WinBits nWinStyle = 0;
281 OString sBorder = VclBuilder::extractCustomProperty(rMap);
282 if (!sBorder.isEmpty())
283 nWinStyle |= WB_BORDER;
285 rRet = VclPtr<SmShowFont>::Create(pParent, nWinStyle);
288 Size SmShowFont::GetOptimalSize() const
290 return LogicToPixel(Size(111 , 31), MapMode(MAP_APPFONT));
293 void SmShowFont::SetFont(const vcl::Font& rFont)
295 maFont = rFont;
296 Invalidate();
299 IMPL_LINK( SmFontDialog, FontSelectHdl, ComboBox *, pComboBox )
301 maFont.SetName(pComboBox->GetText());
302 m_pShowFont->SetFont(maFont);
303 return 0;
306 IMPL_LINK( SmFontDialog, FontModifyHdl, ComboBox *, pComboBox )
308 // if font is available in list then use it
309 sal_Int32 nPos = pComboBox->GetEntryPos( pComboBox->GetText() );
310 if (COMBOBOX_ENTRY_NOTFOUND != nPos)
312 FontSelectHdl( pComboBox );
314 return 0;
317 IMPL_LINK( SmFontDialog, AttrChangeHdl, CheckBox *, /*pCheckBox*/ )
319 if (m_pBoldCheckBox->IsChecked())
320 maFont.SetWeight(FontWeight(WEIGHT_BOLD));
321 else
322 maFont.SetWeight(FontWeight(WEIGHT_NORMAL));
324 if (m_pItalicCheckBox->IsChecked())
325 maFont.SetItalic(ITALIC_NORMAL);
326 else
327 maFont.SetItalic(ITALIC_NONE);
329 m_pShowFont->SetFont(maFont);
330 return 0;
333 void SmFontDialog::SetFont(const vcl::Font &rFont)
335 maFont = rFont;
337 m_pFontBox->SetText(maFont.GetName());
338 m_pBoldCheckBox->Check(IsBold(maFont));
339 m_pItalicCheckBox->Check(IsItalic(maFont));
340 m_pShowFont->SetFont(maFont);
343 SmFontDialog::SmFontDialog(vcl::Window * pParent, OutputDevice *pFntListDevice, bool bHideCheckboxes)
344 : ModalDialog(pParent, "FontDialog", "modules/smath/ui/fontdialog.ui")
346 get(m_pFontBox, "font");
347 m_pFontBox->set_height_request(8 * m_pFontBox->GetTextHeight());
348 get(m_pAttrFrame, "attrframe");
349 get(m_pBoldCheckBox, "bold");
350 get(m_pItalicCheckBox, "italic");
351 get(m_pShowFont, "preview");
354 WaitObject aWait( this );
356 FontList aFontList( pFntListDevice );
358 sal_uInt16 nCount = aFontList.GetFontNameCount();
359 for (sal_uInt16 i = 0; i < nCount; ++i)
361 m_pFontBox->InsertEntry( aFontList.GetFontName(i).GetName() );
363 maFont.SetSize(Size(0, 24));
364 maFont.SetWeight(WEIGHT_NORMAL);
365 maFont.SetItalic(ITALIC_NONE);
366 maFont.SetFamily(FAMILY_DONTKNOW);
367 maFont.SetPitch(PITCH_DONTKNOW);
368 maFont.SetCharSet(RTL_TEXTENCODING_DONTKNOW);
369 maFont.SetTransparent(true);
371 // preview like controls should have a 2D look
372 m_pShowFont->SetBorderStyle( WindowBorderStyle::MONO );
375 m_pFontBox->SetSelectHdl(LINK(this, SmFontDialog, FontSelectHdl));
376 m_pFontBox->SetModifyHdl(LINK(this, SmFontDialog, FontModifyHdl));
377 m_pBoldCheckBox->SetClickHdl(LINK(this, SmFontDialog, AttrChangeHdl));
378 m_pItalicCheckBox->SetClickHdl(LINK(this, SmFontDialog, AttrChangeHdl));
380 if (bHideCheckboxes)
382 m_pBoldCheckBox->Check( false );
383 m_pBoldCheckBox->Enable( false );
384 m_pItalicCheckBox->Check( false );
385 m_pItalicCheckBox->Enable( false );
386 m_pAttrFrame->Show(false);
390 SmFontDialog::~SmFontDialog()
392 disposeOnce();
395 void SmFontDialog::dispose()
397 m_pFontBox.clear();
398 m_pAttrFrame.clear();
399 m_pBoldCheckBox.clear();
400 m_pItalicCheckBox.clear();
401 m_pShowFont.clear();
402 ModalDialog::dispose();
405 void SmFontDialog::DataChanged( const DataChangedEvent& rDCEvt )
407 if (rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
408 m_pShowFont->Invalidate();
410 ModalDialog::DataChanged( rDCEvt );
413 class SaveDefaultsQuery : public MessageDialog
415 public:
416 explicit SaveDefaultsQuery(vcl::Window *pParent)
417 : MessageDialog(pParent, "SaveDefaultsDialog",
418 "modules/smath/ui/savedefaultsdialog.ui")
423 IMPL_LINK( SmFontSizeDialog, DefaultButtonClickHdl, Button *, /*pButton*/ )
425 if (ScopedVclPtr<SaveDefaultsQuery>::Create(this)->Execute() == RET_YES)
427 SmModule *pp = SM_MOD();
428 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
429 WriteTo( aFmt );
430 pp->GetConfig()->SetStandardFormat( aFmt );
432 return 0;
435 SmFontSizeDialog::SmFontSizeDialog(vcl::Window * pParent)
436 : ModalDialog(pParent, "FontSizeDialog", "modules/smath/ui/fontsizedialog.ui")
438 get(m_pTextSize, "spinB_text");
439 get(m_pIndexSize, "spinB_index");
440 get(m_pFunctionSize, "spinB_function");
441 get(m_pOperatorSize, "spinB_operator");
442 get(m_pBorderSize, "spinB_limit");
443 get(m_pBaseSize, "spinB_baseSize");
444 get(m_pDefaultButton, "default");
446 m_pDefaultButton->SetClickHdl(LINK(this, SmFontSizeDialog, DefaultButtonClickHdl));
449 SmFontSizeDialog::~SmFontSizeDialog()
451 disposeOnce();
454 void SmFontSizeDialog::dispose()
456 m_pBaseSize.clear();
457 m_pTextSize.clear();
458 m_pIndexSize.clear();
459 m_pFunctionSize.clear();
460 m_pOperatorSize.clear();
461 m_pBorderSize.clear();
462 m_pDefaultButton.clear();
463 ModalDialog::dispose();
467 void SmFontSizeDialog::ReadFrom(const SmFormat &rFormat)
469 //! aufpassen: richtig runden!
470 m_pBaseSize->SetValue( SmRoundFraction(
471 Sm100th_mmToPts( rFormat.GetBaseSize().Height() ) ) );
473 m_pTextSize->SetValue( rFormat.GetRelSize(SIZ_TEXT) );
474 m_pIndexSize->SetValue( rFormat.GetRelSize(SIZ_INDEX) );
475 m_pFunctionSize->SetValue( rFormat.GetRelSize(SIZ_FUNCTION) );
476 m_pOperatorSize->SetValue( rFormat.GetRelSize(SIZ_OPERATOR) );
477 m_pBorderSize->SetValue( rFormat.GetRelSize(SIZ_LIMITS) );
481 void SmFontSizeDialog::WriteTo(SmFormat &rFormat) const
483 rFormat.SetBaseSize( Size(0, SmPtsTo100th_mm( static_cast< long >(m_pBaseSize->GetValue()))) );
485 rFormat.SetRelSize(SIZ_TEXT, (sal_uInt16) m_pTextSize->GetValue());
486 rFormat.SetRelSize(SIZ_INDEX, (sal_uInt16) m_pIndexSize->GetValue());
487 rFormat.SetRelSize(SIZ_FUNCTION, (sal_uInt16) m_pFunctionSize->GetValue());
488 rFormat.SetRelSize(SIZ_OPERATOR, (sal_uInt16) m_pOperatorSize->GetValue());
489 rFormat.SetRelSize(SIZ_LIMITS, (sal_uInt16) m_pBorderSize->GetValue());
491 const Size aTmp (rFormat.GetBaseSize());
492 for (sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++)
493 rFormat.SetFontSize(i, aTmp);
495 rFormat.RequestApplyChanges();
498 IMPL_LINK( SmFontTypeDialog, MenuSelectHdl, Menu *, pMenu )
500 SmFontPickListBox *pActiveListBox;
502 bool bHideCheckboxes = false;
503 switch (pMenu->GetCurItemId())
505 case 1: pActiveListBox = m_pVariableFont; break;
506 case 2: pActiveListBox = m_pFunctionFont; break;
507 case 3: pActiveListBox = m_pNumberFont; break;
508 case 4: pActiveListBox = m_pTextFont; break;
509 case 5: pActiveListBox = m_pSerifFont; bHideCheckboxes = true; break;
510 case 6: pActiveListBox = m_pSansFont; bHideCheckboxes = true; break;
511 case 7: pActiveListBox = m_pFixedFont; bHideCheckboxes = true; break;
512 default:pActiveListBox = NULL;
515 if (pActiveListBox)
517 ScopedVclPtrInstance<SmFontDialog> pFontDialog(this, pFontListDev, bHideCheckboxes);
519 pActiveListBox->WriteTo(*pFontDialog);
520 if (pFontDialog->Execute() == RET_OK)
521 pActiveListBox->ReadFrom(*pFontDialog);
523 return 0;
527 IMPL_LINK( SmFontTypeDialog, DefaultButtonClickHdl, Button *, /*pButton*/ )
529 if (ScopedVclPtr<SaveDefaultsQuery>::Create(this)->Execute() == RET_YES)
531 SmModule *pp = SM_MOD();
532 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
533 WriteTo( aFmt );
534 pp->GetConfig()->SetStandardFormat( aFmt, true );
536 return 0;
539 SmFontTypeDialog::SmFontTypeDialog(vcl::Window * pParent, OutputDevice *pFntListDevice)
540 : ModalDialog(pParent, "FontsDialog", "modules/smath/ui/fonttypedialog.ui"),
541 pFontListDev (pFntListDevice)
543 get(m_pVariableFont, "variableCB");
544 get(m_pFunctionFont, "functionCB");
545 get(m_pNumberFont, "numberCB");
546 get(m_pTextFont, "textCB");
547 get(m_pSerifFont, "serifCB");
548 get(m_pSansFont, "sansCB");
549 get(m_pFixedFont, "fixedCB");
550 get(m_pMenuButton, "modify");
551 get(m_pDefaultButton, "default");
553 m_pDefaultButton->SetClickHdl(LINK(this, SmFontTypeDialog, DefaultButtonClickHdl));
555 m_pMenuButton->GetPopupMenu()->SetSelectHdl(LINK(this, SmFontTypeDialog, MenuSelectHdl));
558 SmFontTypeDialog::~SmFontTypeDialog()
560 disposeOnce();
563 void SmFontTypeDialog::dispose()
565 m_pVariableFont.clear();
566 m_pFunctionFont.clear();
567 m_pNumberFont.clear();
568 m_pTextFont.clear();
569 m_pSerifFont.clear();
570 m_pSansFont.clear();
571 m_pFixedFont.clear();
572 m_pMenuButton.clear();
573 m_pDefaultButton.clear();
574 ModalDialog::dispose();
577 void SmFontTypeDialog::ReadFrom(const SmFormat &rFormat)
579 SmModule *pp = SM_MOD();
581 *m_pVariableFont = pp->GetConfig()->GetFontPickList(FNT_VARIABLE);
582 *m_pFunctionFont = pp->GetConfig()->GetFontPickList(FNT_FUNCTION);
583 *m_pNumberFont = pp->GetConfig()->GetFontPickList(FNT_NUMBER);
584 *m_pTextFont = pp->GetConfig()->GetFontPickList(FNT_TEXT);
585 *m_pSerifFont = pp->GetConfig()->GetFontPickList(FNT_SERIF);
586 *m_pSansFont = pp->GetConfig()->GetFontPickList(FNT_SANS);
587 *m_pFixedFont = pp->GetConfig()->GetFontPickList(FNT_FIXED);
589 m_pVariableFont->Insert( rFormat.GetFont(FNT_VARIABLE) );
590 m_pFunctionFont->Insert( rFormat.GetFont(FNT_FUNCTION) );
591 m_pNumberFont->Insert( rFormat.GetFont(FNT_NUMBER) );
592 m_pTextFont->Insert( rFormat.GetFont(FNT_TEXT) );
593 m_pSerifFont->Insert( rFormat.GetFont(FNT_SERIF) );
594 m_pSansFont->Insert( rFormat.GetFont(FNT_SANS) );
595 m_pFixedFont->Insert( rFormat.GetFont(FNT_FIXED) );
599 void SmFontTypeDialog::WriteTo(SmFormat &rFormat) const
601 SmModule *pp = SM_MOD();
603 pp->GetConfig()->GetFontPickList(FNT_VARIABLE) = *m_pVariableFont;
604 pp->GetConfig()->GetFontPickList(FNT_FUNCTION) = *m_pFunctionFont;
605 pp->GetConfig()->GetFontPickList(FNT_NUMBER) = *m_pNumberFont;
606 pp->GetConfig()->GetFontPickList(FNT_TEXT) = *m_pTextFont;
607 pp->GetConfig()->GetFontPickList(FNT_SERIF) = *m_pSerifFont;
608 pp->GetConfig()->GetFontPickList(FNT_SANS) = *m_pSansFont;
609 pp->GetConfig()->GetFontPickList(FNT_FIXED) = *m_pFixedFont;
611 rFormat.SetFont( FNT_VARIABLE, m_pVariableFont->Get(0) );
612 rFormat.SetFont( FNT_FUNCTION, m_pFunctionFont->Get(0) );
613 rFormat.SetFont( FNT_NUMBER, m_pNumberFont->Get(0) );
614 rFormat.SetFont( FNT_TEXT, m_pTextFont->Get(0) );
615 rFormat.SetFont( FNT_SERIF, m_pSerifFont->Get(0) );
616 rFormat.SetFont( FNT_SANS, m_pSansFont->Get(0) );
617 rFormat.SetFont( FNT_FIXED, m_pFixedFont->Get(0) );
619 rFormat.RequestApplyChanges();
622 /**************************************************************************/
624 struct FieldMinMax
626 sal_uInt16 nMin, nMax;
629 // Data for min and max values of the 4 metric fields
630 // for each of the 10 categories
631 static const FieldMinMax pMinMaxData[10][4] =
633 // 0
634 {{ 0, 200 }, { 0, 200 }, { 0, 100 }, { 0, 0 }},
635 // 1
636 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
637 // 2
638 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
639 // 3
640 {{ 0, 100 }, { 1, 100 }, { 0, 0 }, { 0, 0 }},
641 // 4
642 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
643 // 5
644 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 100 }},
645 // 6
646 {{ 0, 300 }, { 0, 300 }, { 0, 0 }, { 0, 0 }},
647 // 7
648 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
649 // 8
650 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
651 // 9
652 {{ 0, 10000 }, { 0, 10000 }, { 0, 10000 }, { 0, 10000 }}
655 SmCategoryDesc::SmCategoryDesc(VclBuilderContainer& rBuilder, sal_uInt16 nCategoryIdx)
657 ++nCategoryIdx;
658 FixedText* pTitle = rBuilder.get<FixedText>(OString::number(nCategoryIdx)+"title");
659 if (pTitle)
661 Name = pTitle->GetText();
663 for (int i = 0; i < 4; ++i)
665 FixedText* pLabel = rBuilder.get<FixedText>(OString::number(nCategoryIdx)+"label"+OString::number(i+1));
667 if (pLabel)
669 Strings [i] = new OUString(pLabel->GetText());
670 FixedImage* pImage = rBuilder.get<FixedImage>(OString::number(nCategoryIdx)+"image"+OString::number(i+1));
671 Graphics [i] = new Image(pImage->GetImage());
673 else
675 Strings [i] = 0;
676 Graphics [i] = 0;
679 const FieldMinMax& rMinMax = pMinMaxData[ nCategoryIdx-1 ][i];
680 Value[i] = Minimum[i] = rMinMax.nMin;
681 Maximum[i] = rMinMax.nMax;
685 SmCategoryDesc::~SmCategoryDesc()
687 for (int i = 0; i < 4; ++i)
689 delete Strings [i];
690 delete Graphics [i];
694 /**************************************************************************/
696 IMPL_LINK( SmDistanceDialog, GetFocusHdl, Control *, pControl )
698 if (Categories[nActiveCategory])
700 sal_uInt16 i;
702 if (pControl == m_pMetricField1)
703 i = 0;
704 else if (pControl == m_pMetricField2)
705 i = 1;
706 else if (pControl == m_pMetricField3)
707 i = 2;
708 else if (pControl == m_pMetricField4)
709 i = 3;
710 else
711 return 0;
712 m_pBitmap->SetImage(*(Categories[nActiveCategory]->GetGraphic(i)));
714 return 0;
717 IMPL_LINK( SmDistanceDialog, MenuSelectHdl, Menu *, pMenu )
719 SetCategory(pMenu->GetCurItemId() - 1);
720 return 0;
724 IMPL_LINK( SmDistanceDialog, DefaultButtonClickHdl, Button *, /*pButton*/ )
726 if (ScopedVclPtr<SaveDefaultsQuery>::Create(this)->Execute() == RET_YES)
728 SmModule *pp = SM_MOD();
729 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
730 WriteTo( aFmt );
731 pp->GetConfig()->SetStandardFormat( aFmt );
733 return 0;
736 IMPL_LINK( SmDistanceDialog, CheckBoxClickHdl, CheckBox *, pCheckBox )
738 if (pCheckBox == m_pCheckBox1)
740 m_pCheckBox1->Toggle();
742 bool bChecked = m_pCheckBox1->IsChecked();
743 m_pFixedText4->Enable( bChecked );
744 m_pMetricField4->Enable( bChecked );
746 return 0;
750 void SmDistanceDialog::SetHelpId(MetricField &rField, const OString& sHelpId)
752 const OUString aEmptyText;
754 rField.SetHelpId(sHelpId);
755 rField.SetHelpText(aEmptyText);
757 // since MetricField inherits from SpinField which has a sub Edit field
758 // (which is actually the one we modify) we have to set the help-id
759 // for it too.
760 Edit *pSubEdit = rField.GetSubEdit();
761 if (pSubEdit)
763 pSubEdit->SetHelpId(sHelpId);
764 pSubEdit->SetHelpText(aEmptyText);
769 void SmDistanceDialog::SetCategory(sal_uInt16 nCategory)
771 #if OSL_DEBUG_LEVEL > 1
772 OSL_ENSURE(/*0 <= nCategory &&*/ nCategory < NOCATEGORIES,
773 "Sm: wrong category number in SmDistanceDialog");
774 #endif
776 // array to convert category- and metricfield-number in help ids.
777 // 0 is used in case of unused combinations.
778 #if OSL_DEBUG_LEVEL > 1
779 OSL_ENSURE(NOCATEGORIES == 10, "Sm : array doesn't fit into the number of categories");
780 #endif
781 static const char * aCatMf2Hid[10][4] =
783 { HID_SMA_DEFAULT_DIST, HID_SMA_LINE_DIST, HID_SMA_ROOT_DIST, 0 },
784 { HID_SMA_SUP_DIST, HID_SMA_SUB_DIST , 0, 0 },
785 { HID_SMA_NUMERATOR_DIST, HID_SMA_DENOMINATOR_DIST, 0, 0 },
786 { HID_SMA_FRACLINE_EXCWIDTH, HID_SMA_FRACLINE_LINEWIDTH, 0, 0 },
787 { HID_SMA_UPPERLIMIT_DIST, HID_SMA_LOWERLIMIT_DIST, 0, 0 },
788 { HID_SMA_BRACKET_EXCHEIGHT, HID_SMA_BRACKET_DIST, 0, HID_SMA_BRACKET_EXCHEIGHT2 },
789 { HID_SMA_MATRIXROW_DIST, HID_SMA_MATRIXCOL_DIST, 0, 0 },
790 { HID_SMA_ATTRIBUT_DIST, HID_SMA_INTERATTRIBUT_DIST, 0, 0 },
791 { HID_SMA_OPERATOR_EXCHEIGHT, HID_SMA_OPERATOR_DIST, 0, 0 },
792 { HID_SMA_LEFTBORDER_DIST, HID_SMA_RIGHTBORDER_DIST, HID_SMA_UPPERBORDER_DIST, HID_SMA_LOWERBORDER_DIST }
795 // array to help iterate over the controls
796 vcl::Window * const aWin[4][2] =
798 { m_pFixedText1, m_pMetricField1 },
799 { m_pFixedText2, m_pMetricField2 },
800 { m_pFixedText3, m_pMetricField3 },
801 { m_pFixedText4, m_pMetricField4 }
804 SmCategoryDesc *pCat;
806 // remember the (maybe new) settings of the active SmCategoryDesc
807 // before switching to the new one
808 if (nActiveCategory != CATEGORY_NONE)
810 pCat = Categories[nActiveCategory];
811 pCat->SetValue(0, (sal_uInt16) m_pMetricField1->GetValue());
812 pCat->SetValue(1, (sal_uInt16) m_pMetricField2->GetValue());
813 pCat->SetValue(2, (sal_uInt16) m_pMetricField3->GetValue());
814 pCat->SetValue(3, (sal_uInt16) m_pMetricField4->GetValue());
816 if (nActiveCategory == 5)
817 bScaleAllBrackets = m_pCheckBox1->IsChecked();
819 m_pMenuButton->GetPopupMenu()->CheckItem(nActiveCategory + 1, false);
822 // activation/deactivation of the associated controls depending on the chosen category
823 bool bActive;
824 for (sal_uInt16 i = 0; i < 4; i++)
826 FixedText *pFT = static_cast<FixedText *> ( aWin[i][0] );
827 MetricField *pMF = static_cast<MetricField *>( aWin[i][1] );
829 // To determine which Controls should be active, the existence
830 // of an associated HelpID is checked
831 bActive = aCatMf2Hid[nCategory][i] != 0;
833 pFT->Show(bActive);
834 pFT->Enable(bActive);
835 pMF->Show(bActive);
836 pMF->Enable(bActive);
838 // set measurement unit and number of decimal places
839 FieldUnit eUnit;
840 sal_uInt16 nDigits;
841 if (nCategory < 9)
843 eUnit = FUNIT_PERCENT;
844 nDigits = 0;
846 else
848 eUnit = FUNIT_100TH_MM;
849 nDigits = 2;
851 pMF->SetUnit(eUnit); // changes the value
852 pMF->SetDecimalDigits(nDigits);
854 if (bActive)
856 pCat = Categories[nCategory];
857 pFT->SetText(*pCat->GetString(i));
859 pMF->SetMin(pCat->GetMinimum(i));
860 pMF->SetMax(pCat->GetMaximum(i));
861 pMF->SetValue(pCat->GetValue(i));
863 SetHelpId(*pMF, aCatMf2Hid[nCategory][i]);
866 // activate the CheckBox and the associated MetricField if we're dealing with the brackets menu
867 bActive = nCategory == 5;
868 m_pCheckBox1->Show(bActive);
869 m_pCheckBox1->Enable(bActive);
870 if (bActive)
872 m_pCheckBox1->Check( bScaleAllBrackets );
874 bool bChecked = m_pCheckBox1->IsChecked();
875 m_pFixedText4->Enable( bChecked );
876 m_pMetricField4->Enable( bChecked );
879 m_pMenuButton->GetPopupMenu()->CheckItem(nCategory + 1, true);
880 m_pFrame->set_label(Categories[nCategory]->GetName());
882 nActiveCategory = nCategory;
884 m_pMetricField1->GrabFocus();
885 Invalidate();
886 Update();
890 SmDistanceDialog::SmDistanceDialog(vcl::Window *pParent)
891 : ModalDialog(pParent, "SpacingDialog",
892 "modules/smath/ui/spacingdialog.ui")
894 get(m_pFrame, "template");
895 get(m_pFixedText1, "label1");
896 get(m_pMetricField1, "spinbutton1");
897 get(m_pFixedText2, "label2");
898 get(m_pMetricField2, "spinbutton2");
899 get(m_pFixedText3, "label3");
900 get(m_pMetricField3, "spinbutton3");
901 get(m_pCheckBox1, "checkbutton");
902 get(m_pFixedText4, "label4");
903 get(m_pMetricField4, "spinbutton4");
904 get(m_pMenuButton, "category");
905 get(m_pDefaultButton, "default");
906 get(m_pBitmap, "image");
908 for (sal_uInt16 i = 0; i < NOCATEGORIES; ++i)
909 Categories[i] = new SmCategoryDesc(*this, i);
910 nActiveCategory = CATEGORY_NONE;
911 bScaleAllBrackets = false;
913 // preview like controls should have a 2D look
914 m_pBitmap->SetBorderStyle( WindowBorderStyle::MONO );
916 m_pMetricField1->SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
917 m_pMetricField2->SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
918 m_pMetricField3->SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
919 m_pMetricField4->SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
920 m_pCheckBox1->SetClickHdl(LINK(this, SmDistanceDialog, CheckBoxClickHdl));
922 m_pMenuButton->GetPopupMenu()->SetSelectHdl(LINK(this, SmDistanceDialog, MenuSelectHdl));
924 m_pDefaultButton->SetClickHdl(LINK(this, SmDistanceDialog, DefaultButtonClickHdl));
928 SmDistanceDialog::~SmDistanceDialog()
930 disposeOnce();
933 void SmDistanceDialog::dispose()
935 for (int i = 0; i < NOCATEGORIES; i++)
936 DELETEZ(Categories[i]);
937 m_pFrame.clear();
938 m_pFixedText1.clear();
939 m_pMetricField1.clear();
940 m_pFixedText2.clear();
941 m_pMetricField2.clear();
942 m_pFixedText3.clear();
943 m_pMetricField3.clear();
944 m_pCheckBox1.clear();
945 m_pFixedText4.clear();
946 m_pMetricField4.clear();
947 m_pMenuButton.clear();
948 m_pDefaultButton.clear();
949 m_pBitmap.clear();
950 ModalDialog::dispose();
953 void SmDistanceDialog::DataChanged( const DataChangedEvent &rEvt )
955 ModalDialog::DataChanged( rEvt );
958 void SmDistanceDialog::ReadFrom(const SmFormat &rFormat)
960 Categories[0]->SetValue(0, rFormat.GetDistance(DIS_HORIZONTAL));
961 Categories[0]->SetValue(1, rFormat.GetDistance(DIS_VERTICAL));
962 Categories[0]->SetValue(2, rFormat.GetDistance(DIS_ROOT));
963 Categories[1]->SetValue(0, rFormat.GetDistance(DIS_SUPERSCRIPT));
964 Categories[1]->SetValue(1, rFormat.GetDistance(DIS_SUBSCRIPT));
965 Categories[2]->SetValue(0, rFormat.GetDistance(DIS_NUMERATOR));
966 Categories[2]->SetValue(1, rFormat.GetDistance(DIS_DENOMINATOR));
967 Categories[3]->SetValue(0, rFormat.GetDistance(DIS_FRACTION));
968 Categories[3]->SetValue(1, rFormat.GetDistance(DIS_STROKEWIDTH));
969 Categories[4]->SetValue(0, rFormat.GetDistance(DIS_UPPERLIMIT));
970 Categories[4]->SetValue(1, rFormat.GetDistance(DIS_LOWERLIMIT));
971 Categories[5]->SetValue(0, rFormat.GetDistance(DIS_BRACKETSIZE));
972 Categories[5]->SetValue(1, rFormat.GetDistance(DIS_BRACKETSPACE));
973 Categories[5]->SetValue(3, rFormat.GetDistance(DIS_NORMALBRACKETSIZE));
974 Categories[6]->SetValue(0, rFormat.GetDistance(DIS_MATRIXROW));
975 Categories[6]->SetValue(1, rFormat.GetDistance(DIS_MATRIXCOL));
976 Categories[7]->SetValue(0, rFormat.GetDistance(DIS_ORNAMENTSIZE));
977 Categories[7]->SetValue(1, rFormat.GetDistance(DIS_ORNAMENTSPACE));
978 Categories[8]->SetValue(0, rFormat.GetDistance(DIS_OPERATORSIZE));
979 Categories[8]->SetValue(1, rFormat.GetDistance(DIS_OPERATORSPACE));
980 Categories[9]->SetValue(0, rFormat.GetDistance(DIS_LEFTSPACE));
981 Categories[9]->SetValue(1, rFormat.GetDistance(DIS_RIGHTSPACE));
982 Categories[9]->SetValue(2, rFormat.GetDistance(DIS_TOPSPACE));
983 Categories[9]->SetValue(3, rFormat.GetDistance(DIS_BOTTOMSPACE));
985 bScaleAllBrackets = rFormat.IsScaleNormalBrackets();
987 // force update (even of category 0) by setting nActiveCategory to a
988 // non-existent category number
989 nActiveCategory = CATEGORY_NONE;
990 SetCategory(0);
994 void SmDistanceDialog::WriteTo(SmFormat &rFormat) /*const*/
996 // TODO can they actually be different?
997 // if that's not the case 'const' could be used above!
998 SetCategory(nActiveCategory);
1000 rFormat.SetDistance( DIS_HORIZONTAL, Categories[0]->GetValue(0) );
1001 rFormat.SetDistance( DIS_VERTICAL, Categories[0]->GetValue(1) );
1002 rFormat.SetDistance( DIS_ROOT, Categories[0]->GetValue(2) );
1003 rFormat.SetDistance( DIS_SUPERSCRIPT, Categories[1]->GetValue(0) );
1004 rFormat.SetDistance( DIS_SUBSCRIPT, Categories[1]->GetValue(1) );
1005 rFormat.SetDistance( DIS_NUMERATOR, Categories[2]->GetValue(0) );
1006 rFormat.SetDistance( DIS_DENOMINATOR, Categories[2]->GetValue(1) );
1007 rFormat.SetDistance( DIS_FRACTION, Categories[3]->GetValue(0) );
1008 rFormat.SetDistance( DIS_STROKEWIDTH, Categories[3]->GetValue(1) );
1009 rFormat.SetDistance( DIS_UPPERLIMIT, Categories[4]->GetValue(0) );
1010 rFormat.SetDistance( DIS_LOWERLIMIT, Categories[4]->GetValue(1) );
1011 rFormat.SetDistance( DIS_BRACKETSIZE, Categories[5]->GetValue(0) );
1012 rFormat.SetDistance( DIS_BRACKETSPACE, Categories[5]->GetValue(1) );
1013 rFormat.SetDistance( DIS_MATRIXROW, Categories[6]->GetValue(0) );
1014 rFormat.SetDistance( DIS_MATRIXCOL, Categories[6]->GetValue(1) );
1015 rFormat.SetDistance( DIS_ORNAMENTSIZE, Categories[7]->GetValue(0) );
1016 rFormat.SetDistance( DIS_ORNAMENTSPACE, Categories[7]->GetValue(1) );
1017 rFormat.SetDistance( DIS_OPERATORSIZE, Categories[8]->GetValue(0) );
1018 rFormat.SetDistance( DIS_OPERATORSPACE, Categories[8]->GetValue(1) );
1019 rFormat.SetDistance( DIS_LEFTSPACE, Categories[9]->GetValue(0) );
1020 rFormat.SetDistance( DIS_RIGHTSPACE, Categories[9]->GetValue(1) );
1021 rFormat.SetDistance( DIS_TOPSPACE, Categories[9]->GetValue(2) );
1022 rFormat.SetDistance( DIS_BOTTOMSPACE, Categories[9]->GetValue(3) );
1023 rFormat.SetDistance( DIS_NORMALBRACKETSIZE, Categories[5]->GetValue(3) );
1025 rFormat.SetScaleNormalBrackets( bScaleAllBrackets );
1027 rFormat.RequestApplyChanges();
1030 IMPL_LINK( SmAlignDialog, DefaultButtonClickHdl, Button *, /*pButton*/ )
1032 if (ScopedVclPtr<SaveDefaultsQuery>::Create(this)->Execute() == RET_YES)
1034 SmModule *pp = SM_MOD();
1035 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
1036 WriteTo( aFmt );
1037 pp->GetConfig()->SetStandardFormat( aFmt );
1039 return 0;
1042 SmAlignDialog::SmAlignDialog(vcl::Window * pParent)
1043 : ModalDialog(pParent, "AlignmentDialog",
1044 "modules/smath/ui/alignmentdialog.ui")
1046 get(m_pLeft, "left");
1047 get(m_pCenter, "center");
1048 get(m_pRight, "right");
1049 get(m_pDefaultButton, "default");
1050 m_pDefaultButton->SetClickHdl(LINK(this, SmAlignDialog, DefaultButtonClickHdl));
1053 SmAlignDialog::~SmAlignDialog()
1055 disposeOnce();
1058 void SmAlignDialog::dispose()
1060 m_pLeft.clear();
1061 m_pCenter.clear();
1062 m_pRight.clear();
1063 m_pDefaultButton.clear();
1064 ModalDialog::dispose();
1067 void SmAlignDialog::ReadFrom(const SmFormat &rFormat)
1069 switch (rFormat.GetHorAlign())
1071 case AlignLeft:
1072 m_pLeft->Check(true);
1073 m_pCenter->Check(false);
1074 m_pRight->Check(false);
1075 break;
1077 case AlignCenter:
1078 m_pLeft->Check(false);
1079 m_pCenter->Check(true);
1080 m_pRight->Check(false);
1081 break;
1083 case AlignRight:
1084 m_pLeft->Check(false);
1085 m_pCenter->Check(false);
1086 m_pRight->Check(true);
1087 break;
1092 void SmAlignDialog::WriteTo(SmFormat &rFormat) const
1094 if (m_pLeft->IsChecked())
1095 rFormat.SetHorAlign(AlignLeft);
1096 else if (m_pRight->IsChecked())
1097 rFormat.SetHorAlign(AlignRight);
1098 else
1099 rFormat.SetHorAlign(AlignCenter);
1101 rFormat.RequestApplyChanges();
1105 SmShowSymbolSetWindow::SmShowSymbolSetWindow(vcl::Window *pParent, WinBits nStyle)
1106 : Control(pParent, nStyle)
1107 , m_pVScrollBar(0)
1108 , nLen(0)
1109 , nRows(0)
1110 , nColumns(0)
1111 , nXOffset(0)
1112 , nYOffset(0)
1113 , nSelectSymbol(SYMBOL_NONE)
1117 SmShowSymbolSetWindow::~SmShowSymbolSetWindow()
1119 disposeOnce();
1122 void SmShowSymbolSetWindow::dispose()
1124 m_pVScrollBar.clear();
1125 Control::dispose();
1128 Point SmShowSymbolSetWindow::OffsetPoint(const Point &rPoint) const
1130 return Point(rPoint.X() + nXOffset, rPoint.Y() + nYOffset);
1133 void SmShowSymbolSetWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
1135 Color aBackgroundColor;
1136 Color aTextColor;
1137 lclGetSettingColors(aBackgroundColor, aTextColor);
1139 rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
1140 rRenderContext.SetTextColor(aTextColor);
1142 rRenderContext.Push(PushFlags::MAPMODE);
1144 // set MapUnit for which 'nLen' has been calculated
1145 rRenderContext.SetMapMode(MapMode(MAP_PIXEL));
1147 sal_uInt16 v = sal::static_int_cast< sal_uInt16 >((m_pVScrollBar->GetThumbPos() * nColumns));
1148 size_t nSymbols = aSymbolSet.size();
1150 Color aTxtColor(rRenderContext.GetTextColor());
1151 for (sal_uInt16 i = v; i < nSymbols ; i++)
1153 SmSym aSymbol(*aSymbolSet[i]);
1154 vcl::Font aFont(aSymbol.GetFace());
1155 aFont.SetAlign(ALIGN_TOP);
1157 // taking a FontSize which is a bit smaller (compared to nLen) in order to have a buffer
1158 // (hopefully enough for left and right, too)
1159 aFont.SetSize(Size(0, nLen - (nLen / 3)));
1160 rRenderContext.SetFont(aFont);
1161 // keep text color
1162 rRenderContext.SetTextColor(aTxtColor);
1164 int nIV = i - v;
1165 sal_UCS4 cChar = aSymbol.GetCharacter();
1166 OUString aText(&cChar, 1);
1167 Size aSize(rRenderContext.GetTextWidth( aText ), rRenderContext.GetTextHeight());
1169 Point aPoint((nIV % nColumns) * nLen + (nLen - aSize.Width()) / 2,
1170 (nIV / nColumns) * nLen + (nLen - aSize.Height()) / 2);
1172 rRenderContext.DrawText(OffsetPoint(aPoint), aText);
1175 if (nSelectSymbol != SYMBOL_NONE)
1177 Point aPoint(((nSelectSymbol - v) % nColumns) * nLen,
1178 ((nSelectSymbol - v) / nColumns) * nLen);
1180 Invert(Rectangle(OffsetPoint(aPoint), Size(nLen, nLen)));
1184 rRenderContext.Pop();
1188 void SmShowSymbolSetWindow::MouseButtonDown(const MouseEvent& rMEvt)
1190 GrabFocus();
1192 Size aOutputSize(nColumns * nLen, nRows * nLen);
1193 Point aPoint(rMEvt.GetPosPixel());
1194 aPoint.X() -= nXOffset;
1195 aPoint.Y() -= nYOffset;
1197 if (rMEvt.IsLeft() && Rectangle(Point(0, 0), aOutputSize).IsInside(rMEvt.GetPosPixel()))
1199 long nPos = (aPoint.Y() / nLen) * nColumns + (aPoint.X() / nLen) +
1200 m_pVScrollBar->GetThumbPos() * nColumns;
1201 SelectSymbol( sal::static_int_cast< sal_uInt16 >(nPos) );
1203 aSelectHdlLink.Call(this);
1205 if (rMEvt.GetClicks() > 1)
1206 aDblClickHdlLink.Call(this);
1211 void SmShowSymbolSetWindow::KeyInput(const KeyEvent& rKEvt)
1213 sal_uInt16 n = nSelectSymbol;
1215 if (n != SYMBOL_NONE)
1217 switch (rKEvt.GetKeyCode().GetCode())
1219 case KEY_DOWN: n = n + nColumns; break;
1220 case KEY_UP: n = n - nColumns; break;
1221 case KEY_LEFT: n -= 1; break;
1222 case KEY_RIGHT: n += 1; break;
1223 case KEY_HOME: n = 0; break;
1224 case KEY_END: n = static_cast< sal_uInt16 >(aSymbolSet.size() - 1); break;
1225 case KEY_PAGEUP: n -= nColumns * nRows; break;
1226 case KEY_PAGEDOWN: n += nColumns * nRows; break;
1228 default:
1229 Control::KeyInput(rKEvt);
1230 return;
1233 else
1234 n = 0;
1236 if (n >= aSymbolSet.size())
1237 n = nSelectSymbol;
1239 // adjust scrollbar
1240 if ((n < (sal_uInt16) (m_pVScrollBar->GetThumbPos() * nColumns)) ||
1241 (n >= (sal_uInt16) ((m_pVScrollBar->GetThumbPos() + nRows) * nColumns)))
1243 m_pVScrollBar->SetThumbPos(n / nColumns);
1244 Invalidate();
1245 Update();
1248 SelectSymbol(n);
1249 aSelectHdlLink.Call(this);
1252 void SmShowSymbolSetWindow::setScrollbar(ScrollBar *pVScrollBar)
1254 m_pVScrollBar = pVScrollBar;
1255 m_pVScrollBar->Enable(false);
1256 m_pVScrollBar->Show();
1257 m_pVScrollBar->SetScrollHdl(LINK(this, SmShowSymbolSetWindow, ScrollHdl));
1260 SmShowSymbolSet::SmShowSymbolSet(vcl::Window *pParent)
1261 : VclHBox(pParent, false, 6)
1262 , aSymbolWindow(VclPtr<SmShowSymbolSetWindow>::Create(this, WB_TABSTOP))
1263 , aVScrollBar(VclPtr<ScrollBar>::Create(this, WinBits(WB_VSCROLL)))
1265 aSymbolWindow->set_hexpand(true);
1266 aSymbolWindow->set_vexpand(true);
1267 aSymbolWindow->setScrollbar(aVScrollBar.get());
1268 aSymbolWindow->calccols();
1269 aSymbolWindow->Show();
1272 SmShowSymbolSet::~SmShowSymbolSet()
1274 disposeOnce();
1277 void SmShowSymbolSet::dispose()
1279 aSymbolWindow.disposeAndClear();
1280 aVScrollBar.disposeAndClear();
1281 VclHBox::dispose();
1284 VCL_BUILDER_FACTORY(SmShowSymbolSet)
1286 void SmShowSymbolSetWindow::calccols()
1288 // Height of 16pt in pixels (matching 'aOutputSize')
1289 nLen = LogicToPixel(Size(0, 16), MapMode(MAP_POINT)).Height();
1291 Size aOutputSize = GetOutputSizePixel();
1293 nColumns = aOutputSize.Width() / nLen;
1294 if (nColumns > 2 && nColumns % 2 != 0)
1295 --nColumns;
1296 nRows = aOutputSize.Height() / nLen;
1297 nColumns = std::max<long>(1, nColumns);
1298 nRows = std::max<long>(1, nRows);
1300 nXOffset = (aOutputSize.Width() - (nColumns * nLen)) / 2;
1301 nYOffset = (aOutputSize.Height() - (nRows * nLen)) / 2;
1303 SetScrollBarRange();
1306 Size SmShowSymbolSetWindow::GetOptimalSize() const
1308 vcl::Window *pParent = GetParent();
1309 return Size(pParent->approximate_char_width() * 24, pParent->GetTextHeight() * 8);
1312 void SmShowSymbolSetWindow::SetSymbolSet(const SymbolPtrVec_t& rSymbolSet)
1314 aSymbolSet = rSymbolSet;
1316 SetScrollBarRange();
1319 void SmShowSymbolSetWindow::SetScrollBarRange()
1321 if (aSymbolSet.size() > static_cast<size_t>(nColumns * nRows))
1323 m_pVScrollBar->SetRange(Range(0, ((aSymbolSet.size() + (nColumns - 1)) / nColumns) - nRows));
1324 m_pVScrollBar->Enable(true);
1326 else
1328 m_pVScrollBar->SetRange(Range(0,0));
1329 m_pVScrollBar->Enable (false);
1332 Invalidate();
1335 void SmShowSymbolSetWindow::SelectSymbol(sal_uInt16 nSymbol)
1337 int v = (int) (m_pVScrollBar->GetThumbPos() * nColumns);
1339 if (nSelectSymbol != SYMBOL_NONE)
1340 Invalidate(Rectangle(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
1341 ((nSelectSymbol - v) / nColumns) * nLen)),
1342 Size(nLen, nLen)));
1344 if (nSymbol < aSymbolSet.size())
1345 nSelectSymbol = nSymbol;
1347 if (aSymbolSet.empty())
1348 nSelectSymbol = SYMBOL_NONE;
1350 if (nSelectSymbol != SYMBOL_NONE)
1351 Invalidate(Rectangle(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
1352 ((nSelectSymbol - v) / nColumns) * nLen)),
1353 Size(nLen, nLen)));
1355 Update();
1358 void SmShowSymbolSetWindow::Resize()
1360 Control::Resize();
1361 calccols();
1364 IMPL_LINK( SmShowSymbolSetWindow, ScrollHdl, ScrollBar*, /*pScrollBar*/)
1366 Invalidate();
1367 return 0;
1370 VCL_BUILDER_DECL_FACTORY(SmShowSymbol)
1372 WinBits nWinStyle = 0;
1374 OString sBorder = VclBuilder::extractCustomProperty(rMap);
1375 if (!sBorder.isEmpty())
1376 nWinStyle |= WB_BORDER;
1378 rRet = VclPtr<SmShowSymbol>::Create(pParent, nWinStyle);
1381 void SmShowSymbol::Resize()
1383 Control::Resize();
1384 Invalidate();
1387 void SmShowSymbol::ApplySettings(vcl::RenderContext& /*rRenderContext*/ )
1391 void SmShowSymbol::setFontSize(vcl::Font &rFont) const
1393 rFont.SetSize(Size(0, GetOutputSize().Height() - GetOutputSize().Height() / 3));
1396 void SmShowSymbol::Paint(vcl::RenderContext& rRenderContext, const Rectangle &rRect)
1398 Control::Paint(rRenderContext, rRect);
1400 Color aBackgroundColor;
1401 Color aTextColor;
1402 lclGetSettingColors(aBackgroundColor, aTextColor);
1403 SetBackground(Wallpaper(aBackgroundColor));
1404 SetTextColor(aTextColor);
1406 vcl::Font aFont(rRenderContext.GetFont());
1407 setFontSize(aFont);
1408 rRenderContext.SetFont(aFont);
1410 const OUString &rText = GetText();
1411 Size aTextSize(rRenderContext.GetTextWidth(rText), rRenderContext.GetTextHeight());
1413 rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
1414 (rRenderContext.GetOutputSize().Height() * 7 / 10)), rText);
1417 void SmShowSymbol::MouseButtonDown(const MouseEvent& rMEvt)
1419 if (rMEvt.GetClicks() > 1)
1420 aDblClickHdlLink.Call(this);
1421 else
1422 Control::MouseButtonDown (rMEvt);
1425 void SmShowSymbol::SetSymbol(const SmSym *pSymbol)
1427 if (pSymbol)
1429 vcl::Font aFont (pSymbol->GetFace());
1430 setFontSize(aFont);
1431 aFont.SetAlign(ALIGN_BASELINE);
1432 SetFont(aFont);
1434 sal_UCS4 cChar = pSymbol->GetCharacter();
1435 OUString aText(&cChar, 1);
1436 SetText( aText );
1439 // 'Invalidate' fills the background with the background color.
1440 // If a NULL pointer has been passed that's already enough to clear the display
1441 Invalidate();
1447 void SmSymbolDialog::FillSymbolSets(bool bDeleteText)
1448 // populate the entries of possible SymbolsSets in the dialog with
1449 // current values of the SymbolSet manager but selects none of those
1451 m_pSymbolSets->Clear();
1452 if (bDeleteText)
1453 m_pSymbolSets->SetNoSelection();
1455 std::set< OUString > aSybolSetNames( rSymbolMgr.GetSymbolSetNames() );
1456 std::set< OUString >::const_iterator aIt( aSybolSetNames.begin() );
1457 for ( ; aIt != aSybolSetNames.end(); ++aIt)
1458 m_pSymbolSets->InsertEntry( *aIt );
1462 IMPL_LINK_NOARG( SmSymbolDialog, SymbolSetChangeHdl )
1464 SelectSymbolSet(m_pSymbolSets->GetSelectEntry());
1465 return 0;
1469 IMPL_LINK_NOARG( SmSymbolDialog, SymbolChangeHdl )
1471 SelectSymbol(m_pSymbolSetDisplay->GetSelectSymbol());
1472 return 0;
1475 IMPL_LINK_NOARG(SmSymbolDialog, EditClickHdl)
1477 ScopedVclPtrInstance<SmSymDefineDialog> pDialog(this, pFontListDev, rSymbolMgr);
1479 // set current symbol and SymbolSet for the new dialog
1480 const OUString aSymSetName (m_pSymbolSets->GetSelectEntry()),
1481 aSymName (m_pSymbolName->GetText());
1482 pDialog->SelectOldSymbolSet(aSymSetName);
1483 pDialog->SelectOldSymbol(aSymName);
1484 pDialog->SelectSymbolSet(aSymSetName);
1485 pDialog->SelectSymbol(aSymName);
1487 // remember old SymbolSet
1488 OUString aOldSymbolSet (m_pSymbolSets->GetSelectEntry());
1490 sal_uInt16 nSymPos = GetSelectedSymbol();
1492 // adapt dialog to data of the SymbolSet manager, which might have changed
1493 if (pDialog->Execute() == RET_OK && rSymbolMgr.IsModified())
1495 rSymbolMgr.Save();
1496 FillSymbolSets();
1499 // if the old SymbolSet doesn't exist anymore, go to the first one SymbolSet (if one exists)
1500 if (!SelectSymbolSet(aOldSymbolSet) && m_pSymbolSets->GetEntryCount() > 0)
1501 SelectSymbolSet(m_pSymbolSets->GetEntry(0));
1502 else
1504 // just update display of current symbol set
1505 assert(aSymSetName == aSymSetName); //unexpected change in symbol set name
1506 aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
1507 m_pSymbolSetDisplay->SetSymbolSet( aSymbolSet );
1510 if (nSymPos >= aSymbolSet.size())
1511 nSymPos = static_cast< sal_uInt16 >(aSymbolSet.size()) - 1;
1512 SelectSymbol( nSymPos );
1514 return 0;
1518 IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl )
1520 GetClickHdl(m_pGetBtn);
1521 EndDialog(RET_OK);
1522 return 0;
1526 IMPL_LINK_NOARG( SmSymbolDialog, GetClickHdl )
1528 const SmSym *pSym = GetSymbol();
1529 if (pSym)
1531 OUStringBuffer aText;
1532 aText.append('%').append(pSym->GetName()).append(' ');
1534 rViewSh.GetViewFrame()->GetDispatcher()->Execute(
1535 SID_INSERTSYMBOL, SfxCallMode::RECORD,
1536 new SfxStringItem(SID_INSERTSYMBOL, aText.makeStringAndClear()), 0L);
1539 return 0;
1543 SmSymbolDialog::SmSymbolDialog(vcl::Window *pParent, OutputDevice *pFntListDevice,
1544 SmSymbolManager &rMgr, SmViewShell &rViewShell)
1545 : ModalDialog(pParent, "CatalogDialog",
1546 "modules/smath/ui/catalogdialog.ui")
1550 rViewSh (rViewShell),
1551 rSymbolMgr (rMgr),
1552 pFontListDev (pFntListDevice)
1554 get(m_pSymbolSets, "symbolset");
1555 m_pSymbolSets->SetStyle(m_pSymbolSets->GetStyle()|WB_SORT);
1556 get(m_pSymbolName, "symbolname");
1557 get(m_pGetBtn, "insert");
1558 get(m_pEditBtn, "edit");
1559 get(m_pSymbolSetDisplay, "symbolsetdisplay");
1560 get(m_pSymbolDisplay, "preview");
1562 aSymbolSetName.clear();
1563 aSymbolSet.clear();
1564 FillSymbolSets();
1565 if (m_pSymbolSets->GetEntryCount() > 0)
1566 SelectSymbolSet(m_pSymbolSets->GetEntry(0));
1568 // preview like controls should have a 2D look
1569 m_pSymbolDisplay->SetBorderStyle( WindowBorderStyle::MONO );
1571 m_pSymbolSets->SetSelectHdl(LINK(this, SmSymbolDialog, SymbolSetChangeHdl));
1572 m_pSymbolSetDisplay->SetSelectHdl(LINK(this, SmSymbolDialog, SymbolChangeHdl));
1573 m_pSymbolSetDisplay->SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl));
1574 m_pSymbolDisplay->SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl));
1575 m_pEditBtn->SetClickHdl(LINK(this, SmSymbolDialog, EditClickHdl));
1576 m_pGetBtn->SetClickHdl(LINK(this, SmSymbolDialog, GetClickHdl));
1579 SmSymbolDialog::~SmSymbolDialog()
1581 disposeOnce();
1584 void SmSymbolDialog::dispose()
1586 m_pSymbolSets.clear();
1587 m_pSymbolSetDisplay.clear();
1588 m_pSymbolName.clear();
1589 m_pSymbolDisplay.clear();
1590 m_pGetBtn.clear();
1591 m_pEditBtn.clear();
1592 ModalDialog::dispose();
1595 void SmSymbolDialog::DataChanged( const DataChangedEvent& rDCEvt )
1597 if (rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
1599 m_pSymbolDisplay->Invalidate();
1600 m_pSymbolSetDisplay->Invalidate();
1603 ModalDialog::DataChanged( rDCEvt );
1606 bool SmSymbolDialog::SelectSymbolSet(const OUString &rSymbolSetName)
1608 bool bRet = false;
1609 sal_Int32 nPos = m_pSymbolSets->GetEntryPos(rSymbolSetName);
1611 aSymbolSetName.clear();
1612 aSymbolSet.clear();
1613 if (nPos != LISTBOX_ENTRY_NOTFOUND)
1615 m_pSymbolSets->SelectEntryPos(nPos);
1617 aSymbolSetName = rSymbolSetName;
1618 aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
1620 // sort symbols by Unicode position (useful for displaying Greek characters alphabetically)
1621 std::sort( aSymbolSet.begin(), aSymbolSet.end(), lt_SmSymPtr() );
1623 m_pSymbolSetDisplay->SetSymbolSet( aSymbolSet );
1624 if (aSymbolSet.size() > 0)
1625 SelectSymbol(0);
1627 bRet = true;
1629 else
1630 m_pSymbolSets->SetNoSelection();
1632 return bRet;
1635 void SmSymbolDialog::SelectSymbol(sal_uInt16 nSymbolNo)
1637 const SmSym *pSym = NULL;
1638 if (!aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size()))
1639 pSym = aSymbolSet[ nSymbolNo ];
1641 m_pSymbolSetDisplay->SelectSymbol(nSymbolNo);
1642 m_pSymbolDisplay->SetSymbol(pSym);
1643 m_pSymbolName->SetText(pSym ? pSym->GetName() : OUString());
1646 const SmSym* SmSymbolDialog::GetSymbol() const
1648 sal_uInt16 nSymbolNo = m_pSymbolSetDisplay->GetSelectSymbol();
1649 bool bValid = !aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size());
1650 return bValid ? aSymbolSet[ nSymbolNo ] : NULL;
1653 VCL_BUILDER_DECL_FACTORY(SmShowChar)
1655 WinBits nWinStyle = 0;
1657 OString sBorder = VclBuilder::extractCustomProperty(rMap);
1658 if (!sBorder.isEmpty())
1659 nWinStyle |= WB_BORDER;
1661 rRet = VclPtr<SmShowChar>::Create(pParent, nWinStyle);
1664 void SmShowChar::Paint(vcl::RenderContext& rRenderContext, const Rectangle &rRect)
1666 Control::Paint(rRenderContext, rRect);
1668 OUString aText( GetText() );
1669 if (!aText.isEmpty())
1671 #if OSL_DEBUG_LEVEL > 1
1672 sal_Int32 nPos = 0;
1673 sal_UCS4 cChar = aText.iterateCodePoints( &nPos );
1674 (void) cChar;
1675 #endif
1676 Size aTextSize(rRenderContext.GetTextWidth(aText), rRenderContext.GetTextHeight());
1678 rRenderContext.DrawText(Point((GetOutputSize().Width() - aTextSize.Width()) / 2,
1679 (GetOutputSize().Height() * 7/10)), aText);
1684 void SmShowChar::SetSymbol( const SmSym *pSym )
1686 if (pSym)
1687 SetSymbol( pSym->GetCharacter(), pSym->GetFace() );
1691 void SmShowChar::SetSymbol( sal_UCS4 cChar, const vcl::Font &rFont )
1693 vcl::Font aFont( rFont );
1694 aFont.SetSize( Size(0, GetOutputSize().Height() - GetOutputSize().Height() / 3) );
1695 aFont.SetAlign(ALIGN_BASELINE);
1696 SetFont(aFont);
1697 aFont.SetTransparent(true);
1699 OUString aText(&cChar, 1);
1700 SetText( aText );
1702 Invalidate();
1705 void SmShowChar::Resize()
1707 Control::Resize();
1708 const OUString &rText = GetText();
1709 if (rText.isEmpty())
1710 return;
1711 sal_Int32 nStrIndex = 0;
1712 sal_UCS4 cChar = rText.iterateCodePoints(&nStrIndex);
1713 SetSymbol(cChar, GetFont()); //force recalculation of size
1716 void SmSymDefineDialog::FillSymbols(ComboBox &rComboBox, bool bDeleteText)
1718 #if OSL_DEBUG_LEVEL > 1
1719 OSL_ENSURE(&rComboBox == pOldSymbols || &rComboBox == pSymbols,
1720 "Sm : wrong ComboBox");
1721 #endif
1723 rComboBox.Clear();
1724 if (bDeleteText)
1725 rComboBox.SetText(OUString());
1727 ComboBox &rBox = &rComboBox == pOldSymbols ? *pOldSymbolSets : *pSymbolSets;
1728 SymbolPtrVec_t aSymSet( aSymbolMgrCopy.GetSymbolSet( rBox.GetText() ) );
1729 for (size_t i = 0; i < aSymSet.size(); ++i)
1730 rComboBox.InsertEntry( aSymSet[i]->GetName() );
1734 void SmSymDefineDialog::FillSymbolSets(ComboBox &rComboBox, bool bDeleteText)
1736 #if OSL_DEBUG_LEVEL > 1
1737 OSL_ENSURE(&rComboBox == pOldSymbolSets || &rComboBox == pSymbolSets,
1738 "Sm : falsche ComboBox");
1739 #endif
1741 rComboBox.Clear();
1742 if (bDeleteText)
1743 rComboBox.SetText(OUString());
1745 const std::set< OUString > aSymbolSetNames( aSymbolMgrCopy.GetSymbolSetNames() );
1746 std::set< OUString >::const_iterator aIt( aSymbolSetNames.begin() );
1747 for ( ; aIt != aSymbolSetNames.end(); ++aIt)
1748 rComboBox.InsertEntry( *aIt );
1752 void SmSymDefineDialog::FillFonts(bool bDelete)
1754 pFonts->Clear();
1755 if (bDelete)
1756 pFonts->SetNoSelection();
1758 // Include all fonts of FontList into the font list.
1759 // If there are duplicates, only include one entry of each font since the style will be
1760 // already selected using the FontStyleBox.
1761 if (pFontList)
1763 sal_uInt16 nCount = pFontList->GetFontNameCount();
1764 for (sal_uInt16 i = 0; i < nCount; i++)
1765 pFonts->InsertEntry( pFontList->GetFontName(i).GetName() );
1770 void SmSymDefineDialog::FillStyles(bool bDeleteText)
1772 pStyles->Clear();
1773 if (bDeleteText)
1774 pStyles->SetText(OUString());
1776 OUString aText (pFonts->GetSelectEntry());
1777 if (!aText.isEmpty())
1779 // use own StyleNames
1780 const SmFontStyles &rStyles = GetFontStyles();
1781 for (sal_uInt16 i = 0; i < SmFontStyles::GetCount(); i++)
1782 pStyles->InsertEntry( rStyles.GetStyleName(i) );
1784 #if OSL_DEBUG_LEVEL > 1
1785 OSL_ENSURE(pStyles->GetEntryCount() > 0, "Sm : no styles available");
1786 #endif
1787 pStyles->SetText( pStyles->GetEntry(0) );
1792 SmSym * SmSymDefineDialog::GetSymbol(const ComboBox &rComboBox)
1794 #if OSL_DEBUG_LEVEL > 1
1795 OSL_ENSURE(&rComboBox == pOldSymbols || &rComboBox == pSymbols,
1796 "Sm : wrong combobox");
1797 #endif
1798 return aSymbolMgrCopy.GetSymbolByName(rComboBox.GetText());
1802 IMPL_LINK( SmSymDefineDialog, OldSymbolChangeHdl, ComboBox *, pComboBox )
1804 (void) pComboBox;
1805 #if OSL_DEBUG_LEVEL > 1
1806 OSL_ENSURE(pComboBox == pOldSymbols, "Sm : wrong argument");
1807 #endif
1808 SelectSymbol(*pOldSymbols, pOldSymbols->GetText(), false);
1809 return 0;
1813 IMPL_LINK( SmSymDefineDialog, OldSymbolSetChangeHdl, ComboBox *, pComboBox )
1815 (void) pComboBox;
1816 #if OSL_DEBUG_LEVEL > 1
1817 OSL_ENSURE(pComboBox == pOldSymbolSets, "Sm : wrong argument");
1818 #endif
1819 SelectSymbolSet(*pOldSymbolSets, pOldSymbolSets->GetText(), false);
1820 return 0;
1824 IMPL_LINK( SmSymDefineDialog, ModifyHdl, ComboBox *, pComboBox )
1826 // remember cursor position for later restoring of it
1827 Selection aSelection (pComboBox->GetSelection());
1829 if (pComboBox == pSymbols)
1830 SelectSymbol(*pSymbols, pSymbols->GetText(), false);
1831 else if (pComboBox == pSymbolSets)
1832 SelectSymbolSet(*pSymbolSets, pSymbolSets->GetText(), false);
1833 else if (pComboBox == pOldSymbols)
1834 // allow only names from the list
1835 SelectSymbol(*pOldSymbols, pOldSymbols->GetText(), true);
1836 else if (pComboBox == pOldSymbolSets)
1837 // allow only names from the list
1838 SelectSymbolSet(*pOldSymbolSets, pOldSymbolSets->GetText(), true);
1839 else if (pComboBox == pStyles)
1840 // allow only names from the list (that's the case here anyway)
1841 SelectStyle(pStyles->GetText(), true);
1842 else
1843 SAL_WARN("starmath", "wrong combobox argument");
1845 pComboBox->SetSelection(aSelection);
1847 UpdateButtons();
1849 return 0;
1853 IMPL_LINK( SmSymDefineDialog, FontChangeHdl, ListBox *, pListBox )
1855 (void) pListBox;
1856 #if OSL_DEBUG_LEVEL > 1
1857 OSL_ENSURE(pListBox == pFonts, "Sm : wrong argument");
1858 #endif
1860 SelectFont(pFonts->GetSelectEntry());
1861 return 0;
1865 IMPL_LINK( SmSymDefineDialog, SubsetChangeHdl, ListBox *, pListBox )
1867 (void) pListBox;
1868 sal_Int32 nPos = pFontsSubsetLB->GetSelectEntryPos();
1869 if (LISTBOX_ENTRY_NOTFOUND != nPos)
1871 const Subset* pSubset = static_cast<const Subset*> (pFontsSubsetLB->GetEntryData( nPos ));
1872 if (pSubset)
1874 pCharsetDisplay->SelectCharacter( pSubset->GetRangeMin() );
1877 return 0;
1881 IMPL_LINK( SmSymDefineDialog, StyleChangeHdl, ComboBox *, pComboBox )
1883 (void) pComboBox;
1884 #if OSL_DEBUG_LEVEL > 1
1885 OSL_ENSURE(pComboBox == pStyles, "Sm : falsches Argument");
1886 #endif
1888 SelectStyle(pStyles->GetText());
1889 return 0;
1893 IMPL_LINK_NOARG(SmSymDefineDialog, CharHighlightHdl)
1895 sal_UCS4 cChar = pCharsetDisplay->GetSelectCharacter();
1897 #if OSL_DEBUG_LEVEL > 1
1898 OSL_ENSURE( pSubsetMap, "SubsetMap missing" );
1899 #endif
1900 if (pSubsetMap)
1902 const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
1903 if (pSubset)
1904 pFontsSubsetLB->SelectEntry( pSubset->GetName() );
1905 else
1906 pFontsSubsetLB->SetNoSelection();
1909 pSymbolDisplay->SetSymbol( cChar, pCharsetDisplay->GetFont() );
1911 UpdateButtons();
1913 // display Unicode position as symbol name while iterating over characters
1914 const OUString aHex(OUString::number(cChar, 16 ).toAsciiUpperCase());
1915 const OUString aPattern( (aHex.getLength() > 4) ? OUString("Ux000000") : OUString("Ux0000") );
1916 OUString aUnicodePos( aPattern.copy( 0, aPattern.getLength() - aHex.getLength() ) );
1917 aUnicodePos += aHex;
1918 pSymbols->SetText( aUnicodePos );
1919 pSymbolName->SetText( aUnicodePos );
1921 return 0;
1925 IMPL_LINK( SmSymDefineDialog, AddClickHdl, Button *, pButton )
1927 (void) pButton;
1928 #if OSL_DEBUG_LEVEL > 1
1929 OSL_ENSURE(pButton == pAddBtn, "Sm : wrong argument");
1930 OSL_ENSURE(pAddBtn->IsEnabled(), "Sm : requirements met ??");
1931 #endif
1933 // add symbol
1934 const SmSym aNewSymbol( pSymbols->GetText(), pCharsetDisplay->GetFont(),
1935 pCharsetDisplay->GetSelectCharacter(), pSymbolSets->GetText() );
1936 //OSL_ENSURE( aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == NULL, "symbol already exists" );
1937 aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol );
1939 // update display of new symbol
1940 pSymbolDisplay->SetSymbol( &aNewSymbol );
1941 pSymbolName->SetText( aNewSymbol.GetName() );
1942 pSymbolSetName->SetText( aNewSymbol.GetSymbolSetName() );
1944 // update list box entries
1945 FillSymbolSets(*pOldSymbolSets, false);
1946 FillSymbolSets(*pSymbolSets, false);
1947 FillSymbols(*pOldSymbols ,false);
1948 FillSymbols(*pSymbols ,false);
1950 UpdateButtons();
1952 return 0;
1956 IMPL_LINK( SmSymDefineDialog, ChangeClickHdl, Button *, pButton )
1958 (void) pButton;
1959 #if OSL_DEBUG_LEVEL > 1
1960 OSL_ENSURE(pButton == pChangeBtn, "Sm : wrong argument");
1961 OSL_ENSURE(pChangeBtn->IsEnabled(), "Sm : requirements met ??");
1962 #endif
1964 // get new Sybol to use
1965 //! get font from symbol-disp lay since charset-display does not keep
1966 //! the bold attribute.
1967 const SmSym aNewSymbol( pSymbols->GetText(), pCharsetDisplay->GetFont(),
1968 pCharsetDisplay->GetSelectCharacter(), pSymbolSets->GetText() );
1970 // remove old symbol if the name was changed then add new one
1971 const bool bNameChanged = pOldSymbols->GetText() != pSymbols->GetText();
1972 if (bNameChanged)
1973 aSymbolMgrCopy.RemoveSymbol( pOldSymbols->GetText() );
1974 aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol, true );
1976 // clear display for original symbol if necessary
1977 if (bNameChanged)
1978 SetOrigSymbol(NULL, OUString());
1980 // update display of new symbol
1981 pSymbolDisplay->SetSymbol( &aNewSymbol );
1982 pSymbolName->SetText( aNewSymbol.GetName() );
1983 pSymbolSetName->SetText( aNewSymbol.GetSymbolSetName() );
1985 // update list box entries
1986 FillSymbolSets(*pOldSymbolSets, false);
1987 FillSymbolSets(*pSymbolSets, false);
1988 FillSymbols(*pOldSymbols ,false);
1989 FillSymbols(*pSymbols ,false);
1991 UpdateButtons();
1993 return 0;
1997 IMPL_LINK( SmSymDefineDialog, DeleteClickHdl, Button *, pButton )
1999 (void) pButton;
2000 #if OSL_DEBUG_LEVEL > 1
2001 OSL_ENSURE(pButton == pDeleteBtn, "Sm : wrong argument");
2002 OSL_ENSURE(pDeleteBtn->IsEnabled(), "Sm : requirements met ??");
2003 #endif
2005 if (pOrigSymbol)
2007 aSymbolMgrCopy.RemoveSymbol( pOrigSymbol->GetName() );
2009 // clear display for original symbol
2010 SetOrigSymbol(NULL, OUString());
2012 // update list box entries
2013 FillSymbolSets(*pOldSymbolSets, false);
2014 FillSymbolSets(*pSymbolSets, false);
2015 FillSymbols(*pOldSymbols ,false);
2016 FillSymbols(*pSymbols ,false);
2019 UpdateButtons();
2021 return 0;
2025 void SmSymDefineDialog::UpdateButtons()
2027 bool bAdd = false,
2028 bChange = false,
2029 bDelete = false;
2030 OUString aTmpSymbolName (pSymbols->GetText()),
2031 aTmpSymbolSetName (pSymbolSets->GetText());
2033 if (aTmpSymbolName.getLength() > 0 && aTmpSymbolSetName.getLength() > 0)
2035 // are all settings equal?
2036 //! (Font-, Style- und SymbolSet name comparison is not case sensitive)
2037 bool bEqual = pOrigSymbol
2038 && aTmpSymbolSetName.equalsIgnoreAsciiCase(pOldSymbolSetName->GetText())
2039 && aTmpSymbolName.equals(pOrigSymbol->GetName())
2040 && pFonts->GetSelectEntry().equalsIgnoreAsciiCase(
2041 pOrigSymbol->GetFace().GetName())
2042 && pStyles->GetText().equalsIgnoreAsciiCase(
2043 GetFontStyles().GetStyleName(pOrigSymbol->GetFace()))
2044 && pCharsetDisplay->GetSelectCharacter() == pOrigSymbol->GetCharacter();
2046 // only add it if there isn't already a symbol with the same name
2047 bAdd = aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == NULL;
2049 // only delete it if all settings are equal
2050 bDelete = bool(pOrigSymbol);
2052 // only change it if the old symbol exists and the new one is different
2053 bChange = pOrigSymbol && !bEqual;
2056 pAddBtn ->Enable(bAdd);
2057 pChangeBtn->Enable(bChange);
2058 pDeleteBtn->Enable(bDelete);
2061 SmSymDefineDialog::SmSymDefineDialog(vcl::Window * pParent,
2062 OutputDevice *pFntListDevice, SmSymbolManager &rMgr) :
2063 ModalDialog (pParent, "EditSymbols", "modules/smath/ui/symdefinedialog.ui"),
2064 rSymbolMgr (rMgr),
2065 pOrigSymbol (),
2066 pSubsetMap (),
2067 pFontList (NULL)
2069 get(pOldSymbols, "oldSymbols");
2070 get(pOldSymbolSets, "oldSymbolSets");
2071 get(pCharsetDisplay, "charsetDisplay");
2072 get(pSymbols, "symbols");
2073 get(pSymbolSets, "symbolSets");
2074 get(pFonts, "fonts");
2075 get(pFontsSubsetLB, "fontsSubsetLB");
2076 get(pStyles, "styles");
2077 get(pOldSymbolName, "oldSymbolName");
2078 get(pOldSymbolDisplay, "oldSymbolDisplay");
2079 get(pOldSymbolSetName, "oldSymbolSetName");
2080 get(pSymbolName, "symbolName");
2081 get(pSymbolDisplay, "symbolDisplay");
2082 get(pSymbolSetName, "symbolSetName");
2083 get(pAddBtn, "add");
2084 get(pChangeBtn, "modify");
2085 get(pDeleteBtn, "delete");
2087 pFontList = new FontList( pFntListDevice );
2089 // auto completion is troublesome since that symbols character also gets automatically selected in the
2090 // display and if the user previously selected a character to define/redefine that one this is bad
2091 pOldSymbols->EnableAutocomplete( false, true );
2092 pSymbols->EnableAutocomplete( false, true );
2094 FillFonts();
2095 if (pFonts->GetEntryCount() > 0)
2096 SelectFont(pFonts->GetEntry(0));
2098 SetSymbolSetManager(rSymbolMgr);
2100 pOldSymbols ->SetSelectHdl(LINK(this, SmSymDefineDialog, OldSymbolChangeHdl));
2101 pOldSymbolSets ->SetSelectHdl(LINK(this, SmSymDefineDialog, OldSymbolSetChangeHdl));
2102 pSymbolSets ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2103 pOldSymbolSets ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2104 pSymbols ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2105 pOldSymbols ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2106 pStyles ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2107 pFonts ->SetSelectHdl(LINK(this, SmSymDefineDialog, FontChangeHdl));
2108 pFontsSubsetLB ->SetSelectHdl(LINK(this, SmSymDefineDialog, SubsetChangeHdl));
2109 pStyles ->SetSelectHdl(LINK(this, SmSymDefineDialog, StyleChangeHdl));
2110 pAddBtn ->SetClickHdl (LINK(this, SmSymDefineDialog, AddClickHdl));
2111 pChangeBtn ->SetClickHdl (LINK(this, SmSymDefineDialog, ChangeClickHdl));
2112 pDeleteBtn ->SetClickHdl (LINK(this, SmSymDefineDialog, DeleteClickHdl));
2113 pCharsetDisplay ->SetHighlightHdl( LINK( this, SmSymDefineDialog, CharHighlightHdl ) );
2115 // preview like controls should have a 2D look
2116 pOldSymbolDisplay->SetBorderStyle( WindowBorderStyle::MONO );
2117 pSymbolDisplay ->SetBorderStyle( WindowBorderStyle::MONO );
2121 SmSymDefineDialog::~SmSymDefineDialog()
2123 disposeOnce();
2126 void SmSymDefineDialog::dispose()
2128 pSubsetMap.reset();
2129 pOrigSymbol.reset();
2130 pOldSymbols.clear();
2131 pOldSymbolSets.clear();
2132 pCharsetDisplay.clear();
2133 pSymbols.clear();
2134 pSymbolSets.clear();
2135 pFonts.clear();
2136 pFontsSubsetLB.clear();
2137 pStyles.clear();
2138 pOldSymbolName.clear();
2139 pOldSymbolDisplay.clear();
2140 pOldSymbolSetName.clear();
2141 pSymbolName.clear();
2142 pSymbolDisplay.clear();
2143 pSymbolSetName.clear();
2144 pAddBtn.clear();
2145 pChangeBtn.clear();
2146 pDeleteBtn.clear();
2147 ModalDialog::dispose();
2150 void SmSymDefineDialog::DataChanged( const DataChangedEvent& rDCEvt )
2152 if (rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
2154 Invalidate();
2156 ModalDialog::DataChanged( rDCEvt );
2160 short SmSymDefineDialog::Execute()
2162 short nResult = ModalDialog::Execute();
2164 // apply changes if dialog was closed by clicking OK
2165 if (aSymbolMgrCopy.IsModified() && nResult == RET_OK)
2166 rSymbolMgr = aSymbolMgrCopy;
2168 return nResult;
2172 void SmSymDefineDialog::SetSymbolSetManager(const SmSymbolManager &rMgr)
2174 aSymbolMgrCopy = rMgr;
2176 // Set the modified flag of the copy to false so that
2177 // we can check later on if anything has been changed
2178 aSymbolMgrCopy.SetModified(false);
2180 FillSymbolSets(*pOldSymbolSets);
2181 if (pOldSymbolSets->GetEntryCount() > 0)
2182 SelectSymbolSet(pOldSymbolSets->GetEntry(0));
2183 FillSymbolSets(*pSymbolSets);
2184 if (pSymbolSets->GetEntryCount() > 0)
2185 SelectSymbolSet(pSymbolSets->GetEntry(0));
2186 FillSymbols(*pOldSymbols);
2187 if (pOldSymbols->GetEntryCount() > 0)
2188 SelectSymbol(pOldSymbols->GetEntry(0));
2189 FillSymbols(*pSymbols);
2190 if (pSymbols->GetEntryCount() > 0)
2191 SelectSymbol(pSymbols->GetEntry(0));
2193 UpdateButtons();
2197 bool SmSymDefineDialog::SelectSymbolSet(ComboBox &rComboBox,
2198 const OUString &rSymbolSetName, bool bDeleteText)
2200 #if OSL_DEBUG_LEVEL > 1
2201 OSL_ENSURE(&rComboBox == pOldSymbolSets || &rComboBox == pSymbolSets,
2202 "Sm : wrong ComboBox");
2203 #endif
2205 // trim SymbolName (no leading and trailing blanks)
2206 OUString aNormName (rSymbolSetName);
2207 aNormName = comphelper::string::stripStart(aNormName, ' ');
2208 aNormName = comphelper::string::stripEnd(aNormName, ' ');
2209 // and remove possible deviations within the input
2210 rComboBox.SetText(aNormName);
2212 bool bRet = false;
2213 sal_Int32 nPos = rComboBox.GetEntryPos(aNormName);
2215 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
2217 rComboBox.SetText(rComboBox.GetEntry(nPos));
2218 bRet = true;
2220 else if (bDeleteText)
2221 rComboBox.SetText(OUString());
2223 bool bIsOld = &rComboBox == pOldSymbolSets;
2225 // setting the SymbolSet name at the associated display
2226 FixedText &rFT = bIsOld ? *pOldSymbolSetName : *pSymbolSetName;
2227 rFT.SetText(rComboBox.GetText());
2229 // set the symbol name which belongs to the SymbolSet at the associated combobox
2230 ComboBox &rCB = bIsOld ? *pOldSymbols : *pSymbols;
2231 FillSymbols(rCB, false);
2233 // display a valid respectively no symbol when changing the SymbolSets
2234 if (bIsOld)
2236 OUString aTmpOldSymbolName;
2237 if (pOldSymbols->GetEntryCount() > 0)
2238 aTmpOldSymbolName = pOldSymbols->GetEntry(0);
2239 SelectSymbol(*pOldSymbols, aTmpOldSymbolName, true);
2242 UpdateButtons();
2244 return bRet;
2248 void SmSymDefineDialog::SetOrigSymbol(const SmSym *pSymbol,
2249 const OUString &rSymbolSetName)
2251 // clear old symbol
2252 pOrigSymbol.reset();
2254 OUString aSymName,
2255 aSymSetName;
2256 if (pSymbol)
2258 // set new symbol
2259 pOrigSymbol.reset(new SmSym( *pSymbol ));
2261 aSymName = pSymbol->GetName();
2262 aSymSetName = rSymbolSetName;
2263 pOldSymbolDisplay->SetSymbol( pSymbol );
2265 else
2266 { // delete displayed symbols
2267 pOldSymbolDisplay->SetText(OUString());
2268 pOldSymbolDisplay->Invalidate();
2270 pOldSymbolName->SetText(aSymName);
2271 pOldSymbolSetName->SetText(aSymSetName);
2275 bool SmSymDefineDialog::SelectSymbol(ComboBox &rComboBox,
2276 const OUString &rSymbolName, bool bDeleteText)
2278 #if OSL_DEBUG_LEVEL > 1
2279 OSL_ENSURE(&rComboBox == pOldSymbols || &rComboBox == pSymbols,
2280 "Sm : wrong ComboBox");
2281 #endif
2283 // trim SymbolName (no blanks)
2284 OUString aNormName(comphelper::string::remove(rSymbolName, ' '));
2285 // and remove possible deviations within the input
2286 rComboBox.SetText(aNormName);
2288 bool bRet = false;
2289 sal_Int32 nPos = rComboBox.GetEntryPos(aNormName);
2291 bool bIsOld = &rComboBox == pOldSymbols;
2293 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
2295 rComboBox.SetText(rComboBox.GetEntry(nPos));
2297 if (!bIsOld)
2299 const SmSym *pSymbol = GetSymbol(*pSymbols);
2300 if (pSymbol)
2302 // choose font and style accordingly
2303 const vcl::Font &rFont = pSymbol->GetFace();
2304 SelectFont(rFont.GetName(), false);
2305 SelectStyle(GetFontStyles().GetStyleName(rFont), false);
2307 // Since setting the Font via the Style name of the SymbolFonts doesn't
2308 // work really well (e.g. it can be empty even though the font itself is
2309 // bold or italic) we're manually setting the Font with respect to the Symbol
2310 pCharsetDisplay->SetFont(rFont);
2311 pSymbolDisplay->SetFont(rFont);
2313 // select associated character
2314 SelectChar(pSymbol->GetCharacter());
2316 // since SelectChar will also set the unicode point as text in the
2317 // symbols box, we have to set the symbol name again to get that one displayed
2318 pSymbols->SetText( pSymbol->GetName() );
2322 bRet = true;
2324 else if (bDeleteText)
2325 rComboBox.SetText(OUString());
2327 if (bIsOld)
2329 // if there's a change of the old symbol, show only the available ones, otherwise show none
2330 const SmSym *pOldSymbol = NULL;
2331 OUString aTmpOldSymbolSetName;
2332 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
2334 pOldSymbol = aSymbolMgrCopy.GetSymbolByName(aNormName);
2335 aTmpOldSymbolSetName = pOldSymbolSets->GetText();
2337 SetOrigSymbol(pOldSymbol, aTmpOldSymbolSetName);
2339 else
2340 pSymbolName->SetText(rComboBox.GetText());
2342 UpdateButtons();
2344 return bRet;
2348 void SmSymDefineDialog::SetFont(const OUString &rFontName, const OUString &rStyleName)
2350 // get Font (FontInfo) matching name and style
2351 vcl::FontInfo aFI;
2352 if (pFontList)
2353 aFI = pFontList->Get(rFontName, WEIGHT_NORMAL, ITALIC_NONE);
2354 SetFontStyle(rStyleName, aFI);
2356 pCharsetDisplay->SetFont(aFI);
2357 pSymbolDisplay->SetFont(aFI);
2359 // update subset listbox for new font's unicode subsets
2360 FontCharMapPtr pFontCharMap;
2361 pCharsetDisplay->GetFontCharMap( pFontCharMap );
2362 pSubsetMap.reset(new SubsetMap( pFontCharMap ));
2364 pFontsSubsetLB->Clear();
2365 bool bFirst = true;
2366 const Subset* pSubset;
2367 while( NULL != (pSubset = pSubsetMap->GetNextSubset( bFirst )) )
2369 sal_uInt16 nPos = pFontsSubsetLB->InsertEntry( pSubset->GetName());
2370 pFontsSubsetLB->SetEntryData( nPos, (void *) pSubset );
2371 // subset must live at least as long as the selected font !!!
2372 if( bFirst )
2373 pFontsSubsetLB->SelectEntryPos( nPos );
2374 bFirst = false;
2376 if( bFirst )
2377 pFontsSubsetLB->SetNoSelection();
2378 pFontsSubsetLB->Enable( !bFirst );
2380 pFontCharMap = 0;
2384 bool SmSymDefineDialog::SelectFont(const OUString &rFontName, bool bApplyFont)
2386 bool bRet = false;
2387 sal_Int32 nPos = pFonts->GetEntryPos(rFontName);
2389 if (nPos != LISTBOX_ENTRY_NOTFOUND)
2391 pFonts->SelectEntryPos(nPos);
2392 if (pStyles->GetEntryCount() > 0)
2393 SelectStyle(pStyles->GetEntry(0));
2394 if (bApplyFont)
2396 SetFont(pFonts->GetSelectEntry(), pStyles->GetText());
2397 bRet = true;
2398 pSymbolDisplay->SetSymbol( pCharsetDisplay->GetSelectCharacter(), pCharsetDisplay->GetFont() );
2400 bRet = true;
2402 else
2403 pFonts->SetNoSelection();
2404 FillStyles();
2406 UpdateButtons();
2408 return bRet;
2412 bool SmSymDefineDialog::SelectStyle(const OUString &rStyleName, bool bApplyFont)
2414 bool bRet = false;
2415 sal_Int32 nPos = pStyles->GetEntryPos(rStyleName);
2417 // if the style is not available take the first available one (if existent)
2418 if (nPos == COMBOBOX_ENTRY_NOTFOUND && pStyles->GetEntryCount() > 0)
2419 nPos = 0;
2421 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
2423 pStyles->SetText(pStyles->GetEntry(nPos));
2424 if (bApplyFont)
2426 SetFont(pFonts->GetSelectEntry(), pStyles->GetText());
2427 bRet = true;
2428 pSymbolDisplay->SetSymbol( pCharsetDisplay->GetSelectCharacter(), pCharsetDisplay->GetFont() );
2430 bRet = true;
2432 else
2433 pStyles->SetText(OUString());
2435 UpdateButtons();
2437 return bRet;
2441 void SmSymDefineDialog::SelectChar(sal_Unicode cChar)
2443 pCharsetDisplay->SelectCharacter( cChar );
2444 pSymbolDisplay->SetSymbol( cChar, pCharsetDisplay->GetFont() );
2446 UpdateButtons();
2450 /**************************************************************************/
2452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */