build fix
[LibreOffice.git] / starmath / source / dialog.cxx
blob3dd2f9191adbbc4c754c52e9083c88c0601ef541
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 <sal/config.h>
22 #include <cassert>
24 #include "tools/rcid.h"
25 #include <comphelper/string.hxx>
26 #include <svl/eitem.hxx>
27 #include <svl/intitem.hxx>
28 #include <svl/stritem.hxx>
29 #include <sfx2/app.hxx>
30 #include <vcl/builderfactory.hxx>
31 #include <vcl/layout.hxx>
32 #include <vcl/msgbox.hxx>
33 #include <svtools/ctrltool.hxx>
34 #include <sfx2/printer.hxx>
35 #include <vcl/help.hxx>
36 #include <vcl/waitobj.hxx>
37 #include <vcl/settings.hxx>
38 #include <vcl/wall.hxx>
39 #include <vcl/fontcharmap.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/sfx.hrc>
42 #include <osl/diagnose.h>
43 #include <svx/ucsubset.hxx>
45 #include "dialog.hxx"
46 #include "starmath.hrc"
47 #include "cfgitem.hxx"
48 #include "smmod.hxx"
49 #include "symbol.hxx"
50 #include "view.hxx"
51 #include "document.hxx"
52 #include "unomodel.hxx"
54 #include <algorithm>
56 namespace
59 void lclGetSettingColors(Color& rBackgroundColor, Color& rTextColor)
61 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
62 if (rStyleSettings.GetHighContrastMode())
64 rBackgroundColor = rStyleSettings.GetFieldColor().GetColor();
65 rTextColor = rStyleSettings.GetFieldTextColor().GetColor();
67 else
69 rBackgroundColor = COL_WHITE;
70 rTextColor = COL_BLACK;
74 } // end anonymous namespace
76 // Since it's better to set/query the FontStyle via its attributes rather
77 // than via the StyleName we create a way to translate
78 // Attribute <-> StyleName
80 class SmFontStyles
82 OUString aNormal;
83 OUString aBold;
84 OUString aItalic;
85 OUString aBoldItalic;
87 public:
88 SmFontStyles();
90 static sal_uInt16 GetCount() { return 4; }
91 const OUString& GetStyleName(const vcl::Font& rFont) const;
92 const OUString& GetStyleName(sal_uInt16 nIdx) const;
95 SmFontStyles::SmFontStyles() :
96 aNormal (ResId(RID_FONTREGULAR, *SM_MOD()->GetResMgr())),
97 aBold (ResId(RID_FONTBOLD, *SM_MOD()->GetResMgr())),
98 aItalic (ResId(RID_FONTITALIC, *SM_MOD()->GetResMgr()))
101 aBoldItalic = aBold;
102 aBoldItalic += ", ";
103 aBoldItalic += aItalic;
106 const OUString& SmFontStyles::GetStyleName(const vcl::Font& rFont) const
108 //! compare also SmSpecialNode::Prepare
109 bool bBold = IsBold( rFont ),
110 bItalic = IsItalic( rFont );
112 if (bBold && bItalic)
113 return aBoldItalic;
114 else if (bItalic)
115 return aItalic;
116 else if (bBold)
117 return aBold;
118 return aNormal;
121 const OUString& SmFontStyles::GetStyleName( sal_uInt16 nIdx ) const
123 // 0 = "normal", 1 = "italic",
124 // 2 = "bold", 3 = "bold italic"
126 assert( nIdx < GetCount() );
127 switch (nIdx)
129 case 0 : return aNormal;
130 case 1 : return aItalic;
131 case 2 : return aBold;
132 default: /*case 3:*/ return aBoldItalic;
136 const SmFontStyles & GetFontStyles()
138 static const SmFontStyles aImpl;
139 return aImpl;
142 void SetFontStyle(const OUString &rStyleName, vcl::Font &rFont)
144 // Find index related to StyleName. For an empty StyleName it's assumed to be
145 // 0 (neither bold nor italic).
146 sal_uInt16 nIndex = 0;
147 if (!rStyleName.isEmpty())
149 sal_uInt16 i;
150 const SmFontStyles &rStyles = GetFontStyles();
151 for (i = 0; i < SmFontStyles::GetCount(); ++i)
152 if (rStyleName == rStyles.GetStyleName(i))
153 break;
154 assert(i < SmFontStyles::GetCount() && "style-name unknown");
155 nIndex = i;
158 rFont.SetItalic((nIndex & 0x1) ? ITALIC_NORMAL : ITALIC_NONE);
159 rFont.SetWeight((nIndex & 0x2) ? WEIGHT_BOLD : WEIGHT_NORMAL);
162 IMPL_LINK_NOARG( SmPrintOptionsTabPage, SizeButtonClickHdl, Button *, void )
164 m_pZoom->Enable(m_pSizeZoomed->IsChecked());
167 SmPrintOptionsTabPage::SmPrintOptionsTabPage(vcl::Window* pParent, const SfxItemSet& rOptions)
168 : SfxTabPage(pParent, "SmathSettings", "modules/smath/ui/smathsettings.ui", &rOptions)
170 get( m_pTitle, "title");
171 get( m_pText, "text");
172 get( m_pFrame, "frame");
173 get( m_pSizeNormal, "sizenormal");
174 get( m_pSizeScaled, "sizescaled");
175 get( m_pSizeZoomed, "sizezoomed");
176 get( m_pZoom, "zoom");
177 get( m_pNoRightSpaces, "norightspaces");
178 get( m_pSaveOnlyUsedSymbols, "saveonlyusedsymbols");
179 get( m_pAutoCloseBrackets, "autoclosebrackets");
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 m_pAutoCloseBrackets.clear();
205 SfxTabPage::dispose();
209 bool SmPrintOptionsTabPage::FillItemSet(SfxItemSet* rSet)
211 sal_uInt16 nPrintSize;
212 if (m_pSizeNormal->IsChecked())
213 nPrintSize = PRINT_SIZE_NORMAL;
214 else if (m_pSizeScaled->IsChecked())
215 nPrintSize = PRINT_SIZE_SCALED;
216 else
217 nPrintSize = PRINT_SIZE_ZOOMED;
219 rSet->Put(SfxUInt16Item(GetWhich(SID_PRINTSIZE), nPrintSize));
220 rSet->Put(SfxUInt16Item(GetWhich(SID_PRINTZOOM), sal::static_int_cast<sal_uInt16>(m_pZoom->GetValue())));
221 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTTITLE), m_pTitle->IsChecked()));
222 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTTEXT), m_pText->IsChecked()));
223 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTFRAME), m_pFrame->IsChecked()));
224 rSet->Put(SfxBoolItem(GetWhich(SID_NO_RIGHT_SPACES), m_pNoRightSpaces->IsChecked()));
225 rSet->Put(SfxBoolItem(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS), m_pSaveOnlyUsedSymbols->IsChecked()));
226 rSet->Put(SfxBoolItem(GetWhich(SID_AUTO_CLOSE_BRACKETS), m_pAutoCloseBrackets->IsChecked()));
228 return true;
232 void SmPrintOptionsTabPage::Reset(const SfxItemSet* rSet)
234 SmPrintSize ePrintSize = static_cast<SmPrintSize>(static_cast<const SfxUInt16Item &>(rSet->Get(GetWhich(SID_PRINTSIZE))).GetValue());
236 m_pSizeNormal->Check(ePrintSize == PRINT_SIZE_NORMAL);
237 m_pSizeScaled->Check(ePrintSize == PRINT_SIZE_SCALED);
238 m_pSizeZoomed->Check(ePrintSize == PRINT_SIZE_ZOOMED);
240 m_pZoom->Enable(m_pSizeZoomed->IsChecked());
242 m_pZoom->SetValue(static_cast<const SfxUInt16Item &>(rSet->Get(GetWhich(SID_PRINTZOOM))).GetValue());
244 m_pTitle->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_PRINTTITLE))).GetValue());
245 m_pText->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_PRINTTEXT))).GetValue());
246 m_pFrame->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_PRINTFRAME))).GetValue());
247 m_pNoRightSpaces->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_NO_RIGHT_SPACES))).GetValue());
248 m_pSaveOnlyUsedSymbols->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS))).GetValue());
249 m_pAutoCloseBrackets->Check(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_AUTO_CLOSE_BRACKETS))).GetValue());
252 VclPtr<SfxTabPage> SmPrintOptionsTabPage::Create(vcl::Window* pWindow, const SfxItemSet& rSet)
254 return VclPtr<SmPrintOptionsTabPage>::Create(pWindow, rSet).get();
257 void SmShowFont::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
259 Window::Paint(rRenderContext, rRect);
261 Color aBackColor;
262 Color aTextColor;
263 lclGetSettingColors(aBackColor, aTextColor);
265 rRenderContext.SetBackground(Wallpaper(aBackColor));
267 vcl::Font aFont(maFont);
268 aFont.SetFontSize(Size(0, 24 * rRenderContext.GetDPIScaleFactor()));
269 aFont.SetAlignment(ALIGN_TOP);
270 rRenderContext.SetFont(aFont);
271 rRenderContext.SetTextColor(aTextColor);
273 OUString sText(rRenderContext.GetFont().GetFamilyName());
274 Size aTextSize(rRenderContext.GetTextWidth(sText), rRenderContext.GetTextHeight());
276 rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
277 (rRenderContext.GetOutputSize().Height() - aTextSize.Height()) / 2), sText);
280 VCL_BUILDER_FACTORY_CONSTRUCTOR(SmShowFont, 0)
282 Size SmShowFont::GetOptimalSize() const
284 return LogicToPixel(Size(111 , 31), MapMode(MapUnit::MapAppFont));
287 void SmShowFont::SetFont(const vcl::Font& rFont)
289 maFont = rFont;
290 Invalidate();
293 IMPL_LINK( SmFontDialog, FontSelectHdl, ComboBox&, rComboBox, void )
295 maFont.SetFamilyName(rComboBox.GetText());
296 m_pShowFont->SetFont(maFont);
299 IMPL_LINK( SmFontDialog, FontModifyHdl, Edit&, rEdit, void )
301 ComboBox& rComboBox = static_cast<ComboBox&>(rEdit);
302 // if font is available in list then use it
303 sal_Int32 nPos = rComboBox.GetEntryPos( rComboBox.GetText() );
304 if (COMBOBOX_ENTRY_NOTFOUND != nPos)
306 FontSelectHdl( rComboBox );
310 IMPL_LINK_NOARG( SmFontDialog, AttrChangeHdl, Button*, void )
312 if (m_pBoldCheckBox->IsChecked())
313 maFont.SetWeight(FontWeight(WEIGHT_BOLD));
314 else
315 maFont.SetWeight(FontWeight(WEIGHT_NORMAL));
317 if (m_pItalicCheckBox->IsChecked())
318 maFont.SetItalic(ITALIC_NORMAL);
319 else
320 maFont.SetItalic(ITALIC_NONE);
322 m_pShowFont->SetFont(maFont);
325 void SmFontDialog::SetFont(const vcl::Font &rFont)
327 maFont = rFont;
329 m_pFontBox->SetText(maFont.GetFamilyName());
330 m_pBoldCheckBox->Check(IsBold(maFont));
331 m_pItalicCheckBox->Check(IsItalic(maFont));
332 m_pShowFont->SetFont(maFont);
335 SmFontDialog::SmFontDialog(vcl::Window * pParent, OutputDevice *pFntListDevice, bool bHideCheckboxes)
336 : ModalDialog(pParent, "FontDialog", "modules/smath/ui/fontdialog.ui")
338 get(m_pFontBox, "font");
339 m_pFontBox->set_height_request(8 * m_pFontBox->GetTextHeight());
340 get(m_pAttrFrame, "attrframe");
341 get(m_pBoldCheckBox, "bold");
342 get(m_pItalicCheckBox, "italic");
343 get(m_pShowFont, "preview");
346 WaitObject aWait( this );
348 FontList aFontList( pFntListDevice );
350 sal_uInt16 nCount = aFontList.GetFontNameCount();
351 for (sal_uInt16 i = 0; i < nCount; ++i)
353 m_pFontBox->InsertEntry( aFontList.GetFontName(i).GetFamilyName() );
355 maFont.SetFontSize(Size(0, 24));
356 maFont.SetWeight(WEIGHT_NORMAL);
357 maFont.SetItalic(ITALIC_NONE);
358 maFont.SetFamily(FAMILY_DONTKNOW);
359 maFont.SetPitch(PITCH_DONTKNOW);
360 maFont.SetCharSet(RTL_TEXTENCODING_DONTKNOW);
361 maFont.SetTransparent(true);
363 // preview like controls should have a 2D look
364 m_pShowFont->SetBorderStyle( WindowBorderStyle::MONO );
367 m_pFontBox->SetSelectHdl(LINK(this, SmFontDialog, FontSelectHdl));
368 m_pFontBox->SetModifyHdl(LINK(this, SmFontDialog, FontModifyHdl));
369 m_pBoldCheckBox->SetClickHdl(LINK(this, SmFontDialog, AttrChangeHdl));
370 m_pItalicCheckBox->SetClickHdl(LINK(this, SmFontDialog, AttrChangeHdl));
372 if (bHideCheckboxes)
374 m_pBoldCheckBox->Check( false );
375 m_pBoldCheckBox->Enable( false );
376 m_pItalicCheckBox->Check( false );
377 m_pItalicCheckBox->Enable( false );
378 m_pAttrFrame->Show(false);
382 SmFontDialog::~SmFontDialog()
384 disposeOnce();
387 void SmFontDialog::dispose()
389 m_pFontBox.clear();
390 m_pAttrFrame.clear();
391 m_pBoldCheckBox.clear();
392 m_pItalicCheckBox.clear();
393 m_pShowFont.clear();
394 ModalDialog::dispose();
397 void SmFontDialog::DataChanged( const DataChangedEvent& rDCEvt )
399 if (rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
400 m_pShowFont->Invalidate();
402 ModalDialog::DataChanged( rDCEvt );
405 class SaveDefaultsQuery : public MessageDialog
407 public:
408 explicit SaveDefaultsQuery(vcl::Window *pParent)
409 : MessageDialog(pParent, "SaveDefaultsDialog",
410 "modules/smath/ui/savedefaultsdialog.ui")
415 IMPL_LINK_NOARG( SmFontSizeDialog, DefaultButtonClickHdl, Button *, void )
417 if (ScopedVclPtrInstance<SaveDefaultsQuery>(this)->Execute() == RET_YES)
419 SmModule *pp = SM_MOD();
420 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
421 WriteTo( aFmt );
422 pp->GetConfig()->SetStandardFormat( aFmt );
426 SmFontSizeDialog::SmFontSizeDialog(vcl::Window * pParent)
427 : ModalDialog(pParent, "FontSizeDialog", "modules/smath/ui/fontsizedialog.ui")
429 get(m_pTextSize, "spinB_text");
430 get(m_pIndexSize, "spinB_index");
431 get(m_pFunctionSize, "spinB_function");
432 get(m_pOperatorSize, "spinB_operator");
433 get(m_pBorderSize, "spinB_limit");
434 get(m_pBaseSize, "spinB_baseSize");
435 get(m_pDefaultButton, "default");
437 m_pDefaultButton->SetClickHdl(LINK(this, SmFontSizeDialog, DefaultButtonClickHdl));
440 SmFontSizeDialog::~SmFontSizeDialog()
442 disposeOnce();
445 void SmFontSizeDialog::dispose()
447 m_pBaseSize.clear();
448 m_pTextSize.clear();
449 m_pIndexSize.clear();
450 m_pFunctionSize.clear();
451 m_pOperatorSize.clear();
452 m_pBorderSize.clear();
453 m_pDefaultButton.clear();
454 ModalDialog::dispose();
458 void SmFontSizeDialog::ReadFrom(const SmFormat &rFormat)
460 //! aufpassen: richtig runden!
461 m_pBaseSize->SetValue( SmRoundFraction(
462 Sm100th_mmToPts( rFormat.GetBaseSize().Height() ) ) );
464 m_pTextSize->SetValue( rFormat.GetRelSize(SIZ_TEXT) );
465 m_pIndexSize->SetValue( rFormat.GetRelSize(SIZ_INDEX) );
466 m_pFunctionSize->SetValue( rFormat.GetRelSize(SIZ_FUNCTION) );
467 m_pOperatorSize->SetValue( rFormat.GetRelSize(SIZ_OPERATOR) );
468 m_pBorderSize->SetValue( rFormat.GetRelSize(SIZ_LIMITS) );
472 void SmFontSizeDialog::WriteTo(SmFormat &rFormat) const
474 rFormat.SetBaseSize( Size(0, SmPtsTo100th_mm( static_cast< long >(m_pBaseSize->GetValue()))) );
476 rFormat.SetRelSize(SIZ_TEXT, sal::static_int_cast<sal_uInt16>(m_pTextSize->GetValue()));
477 rFormat.SetRelSize(SIZ_INDEX, sal::static_int_cast<sal_uInt16>(m_pIndexSize->GetValue()));
478 rFormat.SetRelSize(SIZ_FUNCTION, sal::static_int_cast<sal_uInt16>(m_pFunctionSize->GetValue()));
479 rFormat.SetRelSize(SIZ_OPERATOR, sal::static_int_cast<sal_uInt16>(m_pOperatorSize->GetValue()));
480 rFormat.SetRelSize(SIZ_LIMITS, sal::static_int_cast<sal_uInt16>(m_pBorderSize->GetValue()));
482 const Size aTmp (rFormat.GetBaseSize());
483 for (sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++)
484 rFormat.SetFontSize(i, aTmp);
486 rFormat.RequestApplyChanges();
489 IMPL_LINK( SmFontTypeDialog, MenuSelectHdl, Menu *, pMenu, bool )
491 SmFontPickListBox *pActiveListBox;
493 bool bHideCheckboxes = false;
494 switch (pMenu->GetCurItemId())
496 case 1: pActiveListBox = m_pVariableFont; break;
497 case 2: pActiveListBox = m_pFunctionFont; break;
498 case 3: pActiveListBox = m_pNumberFont; break;
499 case 4: pActiveListBox = m_pTextFont; break;
500 case 5: pActiveListBox = m_pSerifFont; bHideCheckboxes = true; break;
501 case 6: pActiveListBox = m_pSansFont; bHideCheckboxes = true; break;
502 case 7: pActiveListBox = m_pFixedFont; bHideCheckboxes = true; break;
503 default:pActiveListBox = nullptr;
506 if (pActiveListBox)
508 ScopedVclPtrInstance<SmFontDialog> pFontDialog(this, pFontListDev, bHideCheckboxes);
510 pActiveListBox->WriteTo(*pFontDialog);
511 if (pFontDialog->Execute() == RET_OK)
512 pActiveListBox->ReadFrom(*pFontDialog);
514 return false;
517 IMPL_LINK_NOARG( SmFontTypeDialog, DefaultButtonClickHdl, Button *, void )
519 if (ScopedVclPtrInstance<SaveDefaultsQuery>(this)->Execute() == RET_YES)
521 SmModule *pp = SM_MOD();
522 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
523 WriteTo( aFmt );
524 pp->GetConfig()->SetStandardFormat( aFmt, true );
528 SmFontTypeDialog::SmFontTypeDialog(vcl::Window * pParent, OutputDevice *pFntListDevice)
529 : ModalDialog(pParent, "FontsDialog", "modules/smath/ui/fonttypedialog.ui"),
530 pFontListDev (pFntListDevice)
532 get(m_pVariableFont, "variableCB");
533 get(m_pFunctionFont, "functionCB");
534 get(m_pNumberFont, "numberCB");
535 get(m_pTextFont, "textCB");
536 get(m_pSerifFont, "serifCB");
537 get(m_pSansFont, "sansCB");
538 get(m_pFixedFont, "fixedCB");
539 get(m_pMenuButton, "modify");
540 get(m_pDefaultButton, "default");
542 m_pDefaultButton->SetClickHdl(LINK(this, SmFontTypeDialog, DefaultButtonClickHdl));
544 m_pMenuButton->GetPopupMenu()->SetSelectHdl(LINK(this, SmFontTypeDialog, MenuSelectHdl));
547 SmFontTypeDialog::~SmFontTypeDialog()
549 disposeOnce();
552 void SmFontTypeDialog::dispose()
554 m_pVariableFont.clear();
555 m_pFunctionFont.clear();
556 m_pNumberFont.clear();
557 m_pTextFont.clear();
558 m_pSerifFont.clear();
559 m_pSansFont.clear();
560 m_pFixedFont.clear();
561 m_pMenuButton.clear();
562 m_pDefaultButton.clear();
563 pFontListDev.clear();
564 ModalDialog::dispose();
567 void SmFontTypeDialog::ReadFrom(const SmFormat &rFormat)
569 SmModule *pp = SM_MOD();
571 *m_pVariableFont = pp->GetConfig()->GetFontPickList(FNT_VARIABLE);
572 *m_pFunctionFont = pp->GetConfig()->GetFontPickList(FNT_FUNCTION);
573 *m_pNumberFont = pp->GetConfig()->GetFontPickList(FNT_NUMBER);
574 *m_pTextFont = pp->GetConfig()->GetFontPickList(FNT_TEXT);
575 *m_pSerifFont = pp->GetConfig()->GetFontPickList(FNT_SERIF);
576 *m_pSansFont = pp->GetConfig()->GetFontPickList(FNT_SANS);
577 *m_pFixedFont = pp->GetConfig()->GetFontPickList(FNT_FIXED);
579 m_pVariableFont->Insert( rFormat.GetFont(FNT_VARIABLE) );
580 m_pFunctionFont->Insert( rFormat.GetFont(FNT_FUNCTION) );
581 m_pNumberFont->Insert( rFormat.GetFont(FNT_NUMBER) );
582 m_pTextFont->Insert( rFormat.GetFont(FNT_TEXT) );
583 m_pSerifFont->Insert( rFormat.GetFont(FNT_SERIF) );
584 m_pSansFont->Insert( rFormat.GetFont(FNT_SANS) );
585 m_pFixedFont->Insert( rFormat.GetFont(FNT_FIXED) );
589 void SmFontTypeDialog::WriteTo(SmFormat &rFormat) const
591 SmModule *pp = SM_MOD();
593 pp->GetConfig()->GetFontPickList(FNT_VARIABLE) = *m_pVariableFont;
594 pp->GetConfig()->GetFontPickList(FNT_FUNCTION) = *m_pFunctionFont;
595 pp->GetConfig()->GetFontPickList(FNT_NUMBER) = *m_pNumberFont;
596 pp->GetConfig()->GetFontPickList(FNT_TEXT) = *m_pTextFont;
597 pp->GetConfig()->GetFontPickList(FNT_SERIF) = *m_pSerifFont;
598 pp->GetConfig()->GetFontPickList(FNT_SANS) = *m_pSansFont;
599 pp->GetConfig()->GetFontPickList(FNT_FIXED) = *m_pFixedFont;
601 rFormat.SetFont( FNT_VARIABLE, m_pVariableFont->Get() );
602 rFormat.SetFont( FNT_FUNCTION, m_pFunctionFont->Get() );
603 rFormat.SetFont( FNT_NUMBER, m_pNumberFont->Get() );
604 rFormat.SetFont( FNT_TEXT, m_pTextFont->Get() );
605 rFormat.SetFont( FNT_SERIF, m_pSerifFont->Get() );
606 rFormat.SetFont( FNT_SANS, m_pSansFont->Get() );
607 rFormat.SetFont( FNT_FIXED, m_pFixedFont->Get() );
609 rFormat.RequestApplyChanges();
612 /**************************************************************************/
614 struct FieldMinMax
616 sal_uInt16 nMin, nMax;
619 // Data for min and max values of the 4 metric fields
620 // for each of the 10 categories
621 static const FieldMinMax pMinMaxData[10][4] =
623 // 0
624 {{ 0, 200 }, { 0, 200 }, { 0, 100 }, { 0, 0 }},
625 // 1
626 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
627 // 2
628 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
629 // 3
630 {{ 0, 100 }, { 1, 100 }, { 0, 0 }, { 0, 0 }},
631 // 4
632 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
633 // 5
634 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 100 }},
635 // 6
636 {{ 0, 300 }, { 0, 300 }, { 0, 0 }, { 0, 0 }},
637 // 7
638 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
639 // 8
640 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
641 // 9
642 {{ 0, 10000 }, { 0, 10000 }, { 0, 10000 }, { 0, 10000 }}
645 SmCategoryDesc::SmCategoryDesc(VclBuilderContainer& rBuilder, sal_uInt16 nCategoryIdx)
647 ++nCategoryIdx;
648 FixedText* pTitle = rBuilder.get<FixedText>(OString::number(nCategoryIdx)+"title");
649 if (pTitle)
651 Name = pTitle->GetText();
653 for (int i = 0; i < 4; ++i)
655 FixedText* pLabel = rBuilder.get<FixedText>(OString::number(nCategoryIdx)+"label"+OString::number(i+1));
657 if (pLabel)
659 Strings [i] = new OUString(pLabel->GetText());
660 FixedImage* pImage = rBuilder.get<FixedImage>(OString::number(nCategoryIdx)+"image"+OString::number(i+1));
661 Graphics [i] = new Image(pImage->GetImage());
663 else
665 Strings [i] = nullptr;
666 Graphics [i] = nullptr;
669 const FieldMinMax& rMinMax = pMinMaxData[ nCategoryIdx-1 ][i];
670 Value[i] = Minimum[i] = rMinMax.nMin;
671 Maximum[i] = rMinMax.nMax;
675 SmCategoryDesc::~SmCategoryDesc()
677 for (int i = 0; i < 4; ++i)
679 delete Strings [i];
680 delete Graphics [i];
684 /**************************************************************************/
686 IMPL_LINK( SmDistanceDialog, GetFocusHdl, Control&, rControl, void )
688 if (Categories[nActiveCategory])
690 sal_uInt16 i;
692 if (&rControl == m_pMetricField1)
693 i = 0;
694 else if (&rControl == m_pMetricField2)
695 i = 1;
696 else if (&rControl == m_pMetricField3)
697 i = 2;
698 else if (&rControl == m_pMetricField4)
699 i = 3;
700 else
701 return;
702 m_pBitmap->SetImage(*(Categories[nActiveCategory]->GetGraphic(i)));
706 IMPL_LINK( SmDistanceDialog, MenuSelectHdl, Menu *, pMenu, bool )
708 SetCategory(pMenu->GetCurItemId() - 1);
709 return false;
713 IMPL_LINK_NOARG( SmDistanceDialog, DefaultButtonClickHdl, Button *, void )
715 if (ScopedVclPtrInstance<SaveDefaultsQuery>(this)->Execute() == RET_YES)
717 SmModule *pp = SM_MOD();
718 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
719 WriteTo( aFmt );
720 pp->GetConfig()->SetStandardFormat( aFmt );
724 IMPL_LINK( SmDistanceDialog, CheckBoxClickHdl, Button *, pCheckBox, void )
726 if (pCheckBox == m_pCheckBox1)
728 m_pCheckBox1->Toggle();
730 bool bChecked = m_pCheckBox1->IsChecked();
731 m_pFixedText4->Enable( bChecked );
732 m_pMetricField4->Enable( bChecked );
737 void SmDistanceDialog::SetHelpId(MetricField &rField, const OString& sHelpId)
739 const OUString aEmptyText;
741 rField.SetHelpId(sHelpId);
742 rField.SetHelpText(aEmptyText);
744 // since MetricField inherits from SpinField which has a sub Edit field
745 // (which is actually the one we modify) we have to set the help-id
746 // for it too.
747 Edit *pSubEdit = rField.GetSubEdit();
748 if (pSubEdit)
750 pSubEdit->SetHelpId(sHelpId);
751 pSubEdit->SetHelpText(aEmptyText);
756 void SmDistanceDialog::SetCategory(sal_uInt16 nCategory)
758 assert(nCategory < NOCATEGORIES && "Sm: wrong category number in SmDistanceDialog");
760 // array to convert category- and metricfield-number in help ids.
761 // 0 is used in case of unused combinations.
762 assert(NOCATEGORIES == 10 && "Sm : array doesn't fit into the number of categories");
763 static const char * aCatMf2Hid[10][4] =
765 { HID_SMA_DEFAULT_DIST, HID_SMA_LINE_DIST, HID_SMA_ROOT_DIST, nullptr },
766 { HID_SMA_SUP_DIST, HID_SMA_SUB_DIST , nullptr, nullptr },
767 { HID_SMA_NUMERATOR_DIST, HID_SMA_DENOMINATOR_DIST, nullptr, nullptr },
768 { HID_SMA_FRACLINE_EXCWIDTH, HID_SMA_FRACLINE_LINEWIDTH, nullptr, nullptr },
769 { HID_SMA_UPPERLIMIT_DIST, HID_SMA_LOWERLIMIT_DIST, nullptr, nullptr },
770 { HID_SMA_BRACKET_EXCHEIGHT, HID_SMA_BRACKET_DIST, nullptr, HID_SMA_BRACKET_EXCHEIGHT2 },
771 { HID_SMA_MATRIXROW_DIST, HID_SMA_MATRIXCOL_DIST, nullptr, nullptr },
772 { HID_SMA_ATTRIBUT_DIST, HID_SMA_INTERATTRIBUT_DIST, nullptr, nullptr },
773 { HID_SMA_OPERATOR_EXCHEIGHT, HID_SMA_OPERATOR_DIST, nullptr, nullptr },
774 { HID_SMA_LEFTBORDER_DIST, HID_SMA_RIGHTBORDER_DIST, HID_SMA_UPPERBORDER_DIST, HID_SMA_LOWERBORDER_DIST }
777 // array to help iterate over the controls
778 vcl::Window * const aWin[4][2] =
780 { m_pFixedText1, m_pMetricField1 },
781 { m_pFixedText2, m_pMetricField2 },
782 { m_pFixedText3, m_pMetricField3 },
783 { m_pFixedText4, m_pMetricField4 }
786 SmCategoryDesc *pCat;
788 // remember the (maybe new) settings of the active SmCategoryDesc
789 // before switching to the new one
790 if (nActiveCategory != CATEGORY_NONE)
792 pCat = Categories[nActiveCategory];
793 pCat->SetValue(0, sal::static_int_cast<sal_uInt16>(m_pMetricField1->GetValue()));
794 pCat->SetValue(1, sal::static_int_cast<sal_uInt16>(m_pMetricField2->GetValue()));
795 pCat->SetValue(2, sal::static_int_cast<sal_uInt16>(m_pMetricField3->GetValue()));
796 pCat->SetValue(3, sal::static_int_cast<sal_uInt16>(m_pMetricField4->GetValue()));
798 if (nActiveCategory == 5)
799 bScaleAllBrackets = m_pCheckBox1->IsChecked();
801 m_pMenuButton->GetPopupMenu()->CheckItem(nActiveCategory + 1, false);
804 // activation/deactivation of the associated controls depending on the chosen category
805 bool bActive;
806 for (sal_uInt16 i = 0; i < 4; i++)
808 FixedText *pFT = static_cast<FixedText *> ( aWin[i][0] );
809 MetricField *pMF = static_cast<MetricField *>( aWin[i][1] );
811 // To determine which Controls should be active, the existence
812 // of an associated HelpID is checked
813 bActive = aCatMf2Hid[nCategory][i] != nullptr;
815 pFT->Show(bActive);
816 pFT->Enable(bActive);
817 pMF->Show(bActive);
818 pMF->Enable(bActive);
820 // set measurement unit and number of decimal places
821 FieldUnit eUnit;
822 sal_uInt16 nDigits;
823 if (nCategory < 9)
825 eUnit = FUNIT_PERCENT;
826 nDigits = 0;
828 else
830 eUnit = FUNIT_100TH_MM;
831 nDigits = 2;
833 pMF->SetUnit(eUnit); // changes the value
834 pMF->SetDecimalDigits(nDigits);
836 if (bActive)
838 pCat = Categories[nCategory];
839 pFT->SetText(*pCat->GetString(i));
841 pMF->SetMin(pCat->GetMinimum(i));
842 pMF->SetMax(pCat->GetMaximum(i));
843 pMF->SetValue(pCat->GetValue(i));
845 SetHelpId(*pMF, aCatMf2Hid[nCategory][i]);
848 // activate the CheckBox and the associated MetricField if we're dealing with the brackets menu
849 bActive = nCategory == 5;
850 m_pCheckBox1->Show(bActive);
851 m_pCheckBox1->Enable(bActive);
852 if (bActive)
854 m_pCheckBox1->Check( bScaleAllBrackets );
856 bool bChecked = m_pCheckBox1->IsChecked();
857 m_pFixedText4->Enable( bChecked );
858 m_pMetricField4->Enable( bChecked );
861 m_pMenuButton->GetPopupMenu()->CheckItem(nCategory + 1);
862 m_pFrame->set_label(Categories[nCategory]->GetName());
864 nActiveCategory = nCategory;
866 m_pMetricField1->GrabFocus();
867 Invalidate();
868 Update();
872 SmDistanceDialog::SmDistanceDialog(vcl::Window *pParent)
873 : ModalDialog(pParent, "SpacingDialog",
874 "modules/smath/ui/spacingdialog.ui")
876 get(m_pFrame, "template");
877 get(m_pFixedText1, "label1");
878 get(m_pMetricField1, "spinbutton1");
879 get(m_pFixedText2, "label2");
880 get(m_pMetricField2, "spinbutton2");
881 get(m_pFixedText3, "label3");
882 get(m_pMetricField3, "spinbutton3");
883 get(m_pCheckBox1, "checkbutton");
884 get(m_pFixedText4, "label4");
885 get(m_pMetricField4, "spinbutton4");
886 get(m_pMenuButton, "category");
887 get(m_pDefaultButton, "default");
888 get(m_pBitmap, "image");
890 for (sal_uInt16 i = 0; i < NOCATEGORIES; ++i)
891 Categories[i] = new SmCategoryDesc(*this, i);
892 nActiveCategory = CATEGORY_NONE;
893 bScaleAllBrackets = false;
895 // preview like controls should have a 2D look
896 m_pBitmap->SetBorderStyle( WindowBorderStyle::MONO );
898 m_pMetricField1->SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
899 m_pMetricField2->SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
900 m_pMetricField3->SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
901 m_pMetricField4->SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
902 m_pCheckBox1->SetClickHdl(LINK(this, SmDistanceDialog, CheckBoxClickHdl));
904 m_pMenuButton->GetPopupMenu()->SetSelectHdl(LINK(this, SmDistanceDialog, MenuSelectHdl));
906 m_pDefaultButton->SetClickHdl(LINK(this, SmDistanceDialog, DefaultButtonClickHdl));
910 SmDistanceDialog::~SmDistanceDialog()
912 disposeOnce();
915 void SmDistanceDialog::dispose()
917 for (SmCategoryDesc* & rpDesc : Categories)
918 DELETEZ(rpDesc);
919 m_pFrame.clear();
920 m_pFixedText1.clear();
921 m_pMetricField1.clear();
922 m_pFixedText2.clear();
923 m_pMetricField2.clear();
924 m_pFixedText3.clear();
925 m_pMetricField3.clear();
926 m_pCheckBox1.clear();
927 m_pFixedText4.clear();
928 m_pMetricField4.clear();
929 m_pMenuButton.clear();
930 m_pDefaultButton.clear();
931 m_pBitmap.clear();
932 ModalDialog::dispose();
935 void SmDistanceDialog::ReadFrom(const SmFormat &rFormat)
937 Categories[0]->SetValue(0, rFormat.GetDistance(DIS_HORIZONTAL));
938 Categories[0]->SetValue(1, rFormat.GetDistance(DIS_VERTICAL));
939 Categories[0]->SetValue(2, rFormat.GetDistance(DIS_ROOT));
940 Categories[1]->SetValue(0, rFormat.GetDistance(DIS_SUPERSCRIPT));
941 Categories[1]->SetValue(1, rFormat.GetDistance(DIS_SUBSCRIPT));
942 Categories[2]->SetValue(0, rFormat.GetDistance(DIS_NUMERATOR));
943 Categories[2]->SetValue(1, rFormat.GetDistance(DIS_DENOMINATOR));
944 Categories[3]->SetValue(0, rFormat.GetDistance(DIS_FRACTION));
945 Categories[3]->SetValue(1, rFormat.GetDistance(DIS_STROKEWIDTH));
946 Categories[4]->SetValue(0, rFormat.GetDistance(DIS_UPPERLIMIT));
947 Categories[4]->SetValue(1, rFormat.GetDistance(DIS_LOWERLIMIT));
948 Categories[5]->SetValue(0, rFormat.GetDistance(DIS_BRACKETSIZE));
949 Categories[5]->SetValue(1, rFormat.GetDistance(DIS_BRACKETSPACE));
950 Categories[5]->SetValue(3, rFormat.GetDistance(DIS_NORMALBRACKETSIZE));
951 Categories[6]->SetValue(0, rFormat.GetDistance(DIS_MATRIXROW));
952 Categories[6]->SetValue(1, rFormat.GetDistance(DIS_MATRIXCOL));
953 Categories[7]->SetValue(0, rFormat.GetDistance(DIS_ORNAMENTSIZE));
954 Categories[7]->SetValue(1, rFormat.GetDistance(DIS_ORNAMENTSPACE));
955 Categories[8]->SetValue(0, rFormat.GetDistance(DIS_OPERATORSIZE));
956 Categories[8]->SetValue(1, rFormat.GetDistance(DIS_OPERATORSPACE));
957 Categories[9]->SetValue(0, rFormat.GetDistance(DIS_LEFTSPACE));
958 Categories[9]->SetValue(1, rFormat.GetDistance(DIS_RIGHTSPACE));
959 Categories[9]->SetValue(2, rFormat.GetDistance(DIS_TOPSPACE));
960 Categories[9]->SetValue(3, rFormat.GetDistance(DIS_BOTTOMSPACE));
962 bScaleAllBrackets = rFormat.IsScaleNormalBrackets();
964 // force update (even of category 0) by setting nActiveCategory to a
965 // non-existent category number
966 nActiveCategory = CATEGORY_NONE;
967 SetCategory(0);
971 void SmDistanceDialog::WriteTo(SmFormat &rFormat) /*const*/
973 // TODO can they actually be different?
974 // if that's not the case 'const' could be used above!
975 SetCategory(nActiveCategory);
977 rFormat.SetDistance( DIS_HORIZONTAL, Categories[0]->GetValue(0) );
978 rFormat.SetDistance( DIS_VERTICAL, Categories[0]->GetValue(1) );
979 rFormat.SetDistance( DIS_ROOT, Categories[0]->GetValue(2) );
980 rFormat.SetDistance( DIS_SUPERSCRIPT, Categories[1]->GetValue(0) );
981 rFormat.SetDistance( DIS_SUBSCRIPT, Categories[1]->GetValue(1) );
982 rFormat.SetDistance( DIS_NUMERATOR, Categories[2]->GetValue(0) );
983 rFormat.SetDistance( DIS_DENOMINATOR, Categories[2]->GetValue(1) );
984 rFormat.SetDistance( DIS_FRACTION, Categories[3]->GetValue(0) );
985 rFormat.SetDistance( DIS_STROKEWIDTH, Categories[3]->GetValue(1) );
986 rFormat.SetDistance( DIS_UPPERLIMIT, Categories[4]->GetValue(0) );
987 rFormat.SetDistance( DIS_LOWERLIMIT, Categories[4]->GetValue(1) );
988 rFormat.SetDistance( DIS_BRACKETSIZE, Categories[5]->GetValue(0) );
989 rFormat.SetDistance( DIS_BRACKETSPACE, Categories[5]->GetValue(1) );
990 rFormat.SetDistance( DIS_MATRIXROW, Categories[6]->GetValue(0) );
991 rFormat.SetDistance( DIS_MATRIXCOL, Categories[6]->GetValue(1) );
992 rFormat.SetDistance( DIS_ORNAMENTSIZE, Categories[7]->GetValue(0) );
993 rFormat.SetDistance( DIS_ORNAMENTSPACE, Categories[7]->GetValue(1) );
994 rFormat.SetDistance( DIS_OPERATORSIZE, Categories[8]->GetValue(0) );
995 rFormat.SetDistance( DIS_OPERATORSPACE, Categories[8]->GetValue(1) );
996 rFormat.SetDistance( DIS_LEFTSPACE, Categories[9]->GetValue(0) );
997 rFormat.SetDistance( DIS_RIGHTSPACE, Categories[9]->GetValue(1) );
998 rFormat.SetDistance( DIS_TOPSPACE, Categories[9]->GetValue(2) );
999 rFormat.SetDistance( DIS_BOTTOMSPACE, Categories[9]->GetValue(3) );
1000 rFormat.SetDistance( DIS_NORMALBRACKETSIZE, Categories[5]->GetValue(3) );
1002 rFormat.SetScaleNormalBrackets( bScaleAllBrackets );
1004 rFormat.RequestApplyChanges();
1007 IMPL_LINK_NOARG( SmAlignDialog, DefaultButtonClickHdl, Button *, void )
1009 if (ScopedVclPtrInstance<SaveDefaultsQuery>(this)->Execute() == RET_YES)
1011 SmModule *pp = SM_MOD();
1012 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
1013 WriteTo( aFmt );
1014 pp->GetConfig()->SetStandardFormat( aFmt );
1018 SmAlignDialog::SmAlignDialog(vcl::Window * pParent)
1019 : ModalDialog(pParent, "AlignmentDialog",
1020 "modules/smath/ui/alignmentdialog.ui")
1022 get(m_pLeft, "left");
1023 get(m_pCenter, "center");
1024 get(m_pRight, "right");
1025 get(m_pDefaultButton, "default");
1026 m_pDefaultButton->SetClickHdl(LINK(this, SmAlignDialog, DefaultButtonClickHdl));
1029 SmAlignDialog::~SmAlignDialog()
1031 disposeOnce();
1034 void SmAlignDialog::dispose()
1036 m_pLeft.clear();
1037 m_pCenter.clear();
1038 m_pRight.clear();
1039 m_pDefaultButton.clear();
1040 ModalDialog::dispose();
1043 void SmAlignDialog::ReadFrom(const SmFormat &rFormat)
1045 switch (rFormat.GetHorAlign())
1047 case AlignLeft:
1048 m_pLeft->Check();
1049 m_pCenter->Check(false);
1050 m_pRight->Check(false);
1051 break;
1053 case AlignCenter:
1054 m_pLeft->Check(false);
1055 m_pCenter->Check();
1056 m_pRight->Check(false);
1057 break;
1059 case AlignRight:
1060 m_pLeft->Check(false);
1061 m_pCenter->Check(false);
1062 m_pRight->Check();
1063 break;
1068 void SmAlignDialog::WriteTo(SmFormat &rFormat) const
1070 if (m_pLeft->IsChecked())
1071 rFormat.SetHorAlign(AlignLeft);
1072 else if (m_pRight->IsChecked())
1073 rFormat.SetHorAlign(AlignRight);
1074 else
1075 rFormat.SetHorAlign(AlignCenter);
1077 rFormat.RequestApplyChanges();
1081 SmShowSymbolSetWindow::SmShowSymbolSetWindow(vcl::Window *pParent, WinBits nStyle)
1082 : Control(pParent, nStyle)
1083 , m_pVScrollBar(nullptr)
1084 , nLen(0)
1085 , nRows(0)
1086 , nColumns(0)
1087 , nXOffset(0)
1088 , nYOffset(0)
1089 , nSelectSymbol(SYMBOL_NONE)
1093 SmShowSymbolSetWindow::~SmShowSymbolSetWindow()
1095 disposeOnce();
1098 void SmShowSymbolSetWindow::dispose()
1100 m_pVScrollBar.clear();
1101 Control::dispose();
1104 Point SmShowSymbolSetWindow::OffsetPoint(const Point &rPoint) const
1106 return Point(rPoint.X() + nXOffset, rPoint.Y() + nYOffset);
1109 void SmShowSymbolSetWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
1111 Color aBackgroundColor;
1112 Color aTextColor;
1113 lclGetSettingColors(aBackgroundColor, aTextColor);
1115 rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
1116 rRenderContext.SetTextColor(aTextColor);
1118 rRenderContext.Push(PushFlags::MAPMODE);
1120 // set MapUnit for which 'nLen' has been calculated
1121 rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
1123 sal_uInt16 v = sal::static_int_cast< sal_uInt16 >((m_pVScrollBar->GetThumbPos() * nColumns));
1124 size_t nSymbols = aSymbolSet.size();
1126 Color aTxtColor(rRenderContext.GetTextColor());
1127 for (size_t i = v; i < nSymbols ; i++)
1129 SmSym aSymbol(*aSymbolSet[i]);
1130 vcl::Font aFont(aSymbol.GetFace());
1131 aFont.SetAlignment(ALIGN_TOP);
1133 // taking a FontSize which is a bit smaller (compared to nLen) in order to have a buffer
1134 // (hopefully enough for left and right, too)
1135 aFont.SetFontSize(Size(0, nLen - (nLen / 3)));
1136 rRenderContext.SetFont(aFont);
1137 // keep text color
1138 rRenderContext.SetTextColor(aTxtColor);
1140 int nIV = i - v;
1141 sal_UCS4 cChar = aSymbol.GetCharacter();
1142 OUString aText(&cChar, 1);
1143 Size aSize(rRenderContext.GetTextWidth( aText ), rRenderContext.GetTextHeight());
1145 Point aPoint((nIV % nColumns) * nLen + (nLen - aSize.Width()) / 2,
1146 (nIV / nColumns) * nLen + (nLen - aSize.Height()) / 2);
1148 rRenderContext.DrawText(OffsetPoint(aPoint), aText);
1151 if (nSelectSymbol != SYMBOL_NONE)
1153 Point aPoint(((nSelectSymbol - v) % nColumns) * nLen,
1154 ((nSelectSymbol - v) / nColumns) * nLen);
1156 Invert(Rectangle(OffsetPoint(aPoint), Size(nLen, nLen)));
1160 rRenderContext.Pop();
1164 void SmShowSymbolSetWindow::MouseButtonDown(const MouseEvent& rMEvt)
1166 GrabFocus();
1168 Size aOutputSize(nColumns * nLen, nRows * nLen);
1169 aOutputSize.Width() += nXOffset;
1170 aOutputSize.Height() += nYOffset;
1171 Point aPoint(rMEvt.GetPosPixel());
1172 aPoint.X() -= nXOffset;
1173 aPoint.Y() -= nYOffset;
1175 if (rMEvt.IsLeft() && Rectangle(Point(0, 0), aOutputSize).IsInside(rMEvt.GetPosPixel()))
1177 long nPos = (aPoint.Y() / nLen) * nColumns + (aPoint.X() / nLen) +
1178 m_pVScrollBar->GetThumbPos() * nColumns;
1179 SelectSymbol( sal::static_int_cast< sal_uInt16 >(nPos) );
1181 aSelectHdlLink.Call(*this);
1183 if (rMEvt.GetClicks() > 1)
1184 aDblClickHdlLink.Call(*this);
1189 void SmShowSymbolSetWindow::KeyInput(const KeyEvent& rKEvt)
1191 sal_uInt16 n = nSelectSymbol;
1193 if (n != SYMBOL_NONE)
1195 switch (rKEvt.GetKeyCode().GetCode())
1197 case KEY_DOWN: n = n + nColumns; break;
1198 case KEY_UP: n = n - nColumns; break;
1199 case KEY_LEFT: n -= 1; break;
1200 case KEY_RIGHT: n += 1; break;
1201 case KEY_HOME: n = 0; break;
1202 case KEY_END: n = static_cast< sal_uInt16 >(aSymbolSet.size() - 1); break;
1203 case KEY_PAGEUP: n -= nColumns * nRows; break;
1204 case KEY_PAGEDOWN: n += nColumns * nRows; break;
1206 default:
1207 Control::KeyInput(rKEvt);
1208 return;
1211 else
1212 n = 0;
1214 if (n >= aSymbolSet.size())
1215 n = nSelectSymbol;
1217 // adjust scrollbar
1218 if ((n < sal::static_int_cast<sal_uInt16>(m_pVScrollBar->GetThumbPos() * nColumns)) ||
1219 (n >= sal::static_int_cast<sal_uInt16>((m_pVScrollBar->GetThumbPos() + nRows) * nColumns)))
1221 m_pVScrollBar->SetThumbPos(n / nColumns);
1222 Invalidate();
1223 Update();
1226 SelectSymbol(n);
1227 aSelectHdlLink.Call(*this);
1230 void SmShowSymbolSetWindow::setScrollbar(ScrollBar *pVScrollBar)
1232 m_pVScrollBar = pVScrollBar;
1233 m_pVScrollBar->Enable(false);
1234 m_pVScrollBar->Show();
1235 m_pVScrollBar->SetScrollHdl(LINK(this, SmShowSymbolSetWindow, ScrollHdl));
1238 SmShowSymbolSet::SmShowSymbolSet(vcl::Window *pParent)
1239 : VclHBox(pParent, false, 6)
1240 , aSymbolWindow(VclPtr<SmShowSymbolSetWindow>::Create(this, WB_TABSTOP))
1241 , aVScrollBar(VclPtr<ScrollBar>::Create(this, WinBits(WB_VSCROLL)))
1243 aSymbolWindow->set_hexpand(true);
1244 aSymbolWindow->set_vexpand(true);
1245 aSymbolWindow->setScrollbar(aVScrollBar.get());
1246 aSymbolWindow->calccols();
1247 aSymbolWindow->Show();
1250 SmShowSymbolSet::~SmShowSymbolSet()
1252 disposeOnce();
1255 void SmShowSymbolSet::dispose()
1257 aSymbolWindow.disposeAndClear();
1258 aVScrollBar.disposeAndClear();
1259 VclHBox::dispose();
1262 VCL_BUILDER_FACTORY(SmShowSymbolSet)
1264 void SmShowSymbolSetWindow::calccols()
1266 // Height of 16pt in pixels (matching 'aOutputSize')
1267 nLen = LogicToPixel(Size(0, 16), MapMode(MapUnit::MapPoint)).Height();
1269 Size aOutputSize = GetOutputSizePixel();
1271 nColumns = aOutputSize.Width() / nLen;
1272 nRows = aOutputSize.Height() / nLen;
1273 nColumns = std::max<long>(1, nColumns);
1274 nRows = std::max<long>(1, nRows);
1276 nXOffset = (aOutputSize.Width() - (nColumns * nLen)) / 2;
1277 nYOffset = (aOutputSize.Height() - (nRows * nLen)) / 2;
1279 SetScrollBarRange();
1282 Size SmShowSymbolSetWindow::GetOptimalSize() const
1284 vcl::Window *pParent = GetParent();
1285 return Size(pParent->approximate_char_width() * 24, pParent->GetTextHeight() * 8);
1288 void SmShowSymbolSetWindow::SetSymbolSet(const SymbolPtrVec_t& rSymbolSet)
1290 aSymbolSet = rSymbolSet;
1292 SetScrollBarRange();
1295 void SmShowSymbolSetWindow::SetScrollBarRange()
1297 if (aSymbolSet.size() > static_cast<size_t>(nColumns * nRows))
1299 m_pVScrollBar->SetRange(Range(0, ((aSymbolSet.size() + (nColumns - 1)) / nColumns) - nRows));
1300 m_pVScrollBar->Enable();
1302 else
1304 m_pVScrollBar->SetRange(Range(0,0));
1305 m_pVScrollBar->Enable (false);
1308 Invalidate();
1311 void SmShowSymbolSetWindow::SelectSymbol(sal_uInt16 nSymbol)
1313 int v = static_cast<int>(m_pVScrollBar->GetThumbPos() * nColumns);
1315 if (nSelectSymbol != SYMBOL_NONE)
1316 Invalidate(Rectangle(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
1317 ((nSelectSymbol - v) / nColumns) * nLen)),
1318 Size(nLen, nLen)));
1320 if (nSymbol < aSymbolSet.size())
1321 nSelectSymbol = nSymbol;
1323 if (aSymbolSet.empty())
1324 nSelectSymbol = SYMBOL_NONE;
1326 if (nSelectSymbol != SYMBOL_NONE)
1327 Invalidate(Rectangle(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
1328 ((nSelectSymbol - v) / nColumns) * nLen)),
1329 Size(nLen, nLen)));
1331 Update();
1334 void SmShowSymbolSetWindow::Resize()
1336 Control::Resize();
1337 calccols();
1340 IMPL_LINK( SmShowSymbolSetWindow, ScrollHdl, ScrollBar*, /*pScrollBar*/, void)
1342 Invalidate();
1345 VCL_BUILDER_FACTORY_CONSTRUCTOR(SmShowSymbol, 0)
1347 void SmShowSymbol::Resize()
1349 Control::Resize();
1350 Invalidate();
1353 void SmShowSymbol::ApplySettings(vcl::RenderContext& /*rRenderContext*/ )
1357 void SmShowSymbol::setFontSize(vcl::Font &rFont) const
1359 rFont.SetFontSize(Size(0, GetOutputSize().Height() - GetOutputSize().Height() / 3));
1362 void SmShowSymbol::Paint(vcl::RenderContext& rRenderContext, const Rectangle &rRect)
1364 Control::Paint(rRenderContext, rRect);
1366 Color aBackgroundColor;
1367 Color aTextColor;
1368 lclGetSettingColors(aBackgroundColor, aTextColor);
1369 SetBackground(Wallpaper(aBackgroundColor));
1370 SetTextColor(aTextColor);
1372 vcl::Font aFont(rRenderContext.GetFont());
1373 setFontSize(aFont);
1374 rRenderContext.SetFont(aFont);
1376 const OUString &rText = GetText();
1377 Size aTextSize(rRenderContext.GetTextWidth(rText), rRenderContext.GetTextHeight());
1379 rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
1380 (rRenderContext.GetOutputSize().Height() * 7 / 10)), rText);
1383 void SmShowSymbol::MouseButtonDown(const MouseEvent& rMEvt)
1385 if (rMEvt.GetClicks() > 1)
1386 aDblClickHdlLink.Call(*this);
1387 else
1388 Control::MouseButtonDown (rMEvt);
1391 void SmShowSymbol::SetSymbol(const SmSym *pSymbol)
1393 if (pSymbol)
1395 vcl::Font aFont (pSymbol->GetFace());
1396 setFontSize(aFont);
1397 aFont.SetAlignment(ALIGN_BASELINE);
1398 SetFont(aFont);
1400 sal_UCS4 cChar = pSymbol->GetCharacter();
1401 OUString aText(&cChar, 1);
1402 SetText( aText );
1405 // 'Invalidate' fills the background with the background color.
1406 // If a NULL pointer has been passed that's already enough to clear the display
1407 Invalidate();
1411 void SmSymbolDialog::FillSymbolSets()
1412 // populate the entries of possible SymbolsSets in the dialog with
1413 // current values of the SymbolSet manager but selects none of those
1415 m_pSymbolSets->Clear();
1416 m_pSymbolSets->SetNoSelection();
1418 std::set< OUString > aSybolSetNames( rSymbolMgr.GetSymbolSetNames() );
1419 std::set< OUString >::const_iterator aIt( aSybolSetNames.begin() );
1420 for ( ; aIt != aSybolSetNames.end(); ++aIt)
1421 m_pSymbolSets->InsertEntry( *aIt );
1425 IMPL_LINK_NOARG( SmSymbolDialog, SymbolSetChangeHdl, ListBox&, void )
1427 SelectSymbolSet(m_pSymbolSets->GetSelectEntry());
1431 IMPL_LINK_NOARG( SmSymbolDialog, SymbolChangeHdl, SmShowSymbolSetWindow&, void )
1433 SelectSymbol(m_pSymbolSetDisplay->GetSelectSymbol());
1436 IMPL_LINK_NOARG(SmSymbolDialog, EditClickHdl, Button*, void)
1438 ScopedVclPtrInstance<SmSymDefineDialog> pDialog(this, pFontListDev, rSymbolMgr);
1440 // set current symbol and SymbolSet for the new dialog
1441 const OUString aSymSetName (m_pSymbolSets->GetSelectEntry()),
1442 aSymName (m_pSymbolName->GetText());
1443 pDialog->SelectOldSymbolSet(aSymSetName);
1444 pDialog->SelectOldSymbol(aSymName);
1445 pDialog->SelectSymbolSet(aSymSetName);
1446 pDialog->SelectSymbol(aSymName);
1448 // remember old SymbolSet
1449 OUString aOldSymbolSet (m_pSymbolSets->GetSelectEntry());
1451 sal_uInt16 nSymPos = m_pSymbolSetDisplay->GetSelectSymbol();
1453 // adapt dialog to data of the SymbolSet manager, which might have changed
1454 if (pDialog->Execute() == RET_OK && rSymbolMgr.IsModified())
1456 rSymbolMgr.Save();
1457 FillSymbolSets();
1460 // if the old SymbolSet doesn't exist anymore, go to the first one SymbolSet (if one exists)
1461 if (!SelectSymbolSet(aOldSymbolSet) && m_pSymbolSets->GetEntryCount() > 0)
1462 SelectSymbolSet(m_pSymbolSets->GetEntry(0));
1463 else
1465 // just update display of current symbol set
1466 assert(aSymSetName == aSymSetName); //unexpected change in symbol set name
1467 aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
1468 m_pSymbolSetDisplay->SetSymbolSet( aSymbolSet );
1471 if (nSymPos >= aSymbolSet.size())
1472 nSymPos = static_cast< sal_uInt16 >(aSymbolSet.size()) - 1;
1473 SelectSymbol( nSymPos );
1477 IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl2, SmShowSymbolSetWindow&, void )
1479 SymbolDblClickHdl();
1481 IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl, SmShowSymbol&, void )
1483 SymbolDblClickHdl();
1485 void SmSymbolDialog::SymbolDblClickHdl()
1487 GetClickHdl(m_pGetBtn);
1488 EndDialog(RET_OK);
1492 IMPL_LINK_NOARG( SmSymbolDialog, GetClickHdl, Button*, void )
1494 const SmSym *pSym = GetSymbol();
1495 if (pSym)
1497 OUStringBuffer aText;
1498 aText.append('%').append(pSym->GetName()).append(' ');
1500 rViewSh.GetViewFrame()->GetDispatcher()->ExecuteList(
1501 SID_INSERTSYMBOL, SfxCallMode::RECORD,
1502 { new SfxStringItem(SID_INSERTSYMBOL, aText.makeStringAndClear()) });
1507 SmSymbolDialog::SmSymbolDialog(vcl::Window *pParent, OutputDevice *pFntListDevice,
1508 SmSymbolManager &rMgr, SmViewShell &rViewShell)
1509 : ModalDialog(pParent, "CatalogDialog",
1510 "modules/smath/ui/catalogdialog.ui")
1514 rViewSh (rViewShell),
1515 rSymbolMgr (rMgr),
1516 pFontListDev (pFntListDevice)
1518 get(m_pSymbolSets, "symbolset");
1519 m_pSymbolSets->SetStyle(m_pSymbolSets->GetStyle()|WB_SORT);
1520 get(m_pSymbolName, "symbolname");
1521 get(m_pGetBtn, "insert");
1522 get(m_pEditBtn, "edit");
1523 get(m_pSymbolSetDisplay, "symbolsetdisplay");
1524 get(m_pSymbolDisplay, "preview");
1526 aSymbolSetName.clear();
1527 aSymbolSet.clear();
1528 FillSymbolSets();
1529 if (m_pSymbolSets->GetEntryCount() > 0)
1530 SelectSymbolSet(m_pSymbolSets->GetEntry(0));
1532 // preview like controls should have a 2D look
1533 m_pSymbolDisplay->SetBorderStyle( WindowBorderStyle::MONO );
1535 m_pSymbolSets->SetSelectHdl(LINK(this, SmSymbolDialog, SymbolSetChangeHdl));
1536 m_pSymbolSetDisplay->SetSelectHdl(LINK(this, SmSymbolDialog, SymbolChangeHdl));
1537 m_pSymbolSetDisplay->SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl2));
1538 m_pSymbolDisplay->SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl));
1539 m_pEditBtn->SetClickHdl(LINK(this, SmSymbolDialog, EditClickHdl));
1540 m_pGetBtn->SetClickHdl(LINK(this, SmSymbolDialog, GetClickHdl));
1543 SmSymbolDialog::~SmSymbolDialog()
1545 disposeOnce();
1548 void SmSymbolDialog::dispose()
1550 m_pSymbolSets.clear();
1551 m_pSymbolSetDisplay.clear();
1552 m_pSymbolName.clear();
1553 m_pSymbolDisplay.clear();
1554 m_pGetBtn.clear();
1555 m_pEditBtn.clear();
1556 pFontListDev.clear();
1557 ModalDialog::dispose();
1560 void SmSymbolDialog::DataChanged( const DataChangedEvent& rDCEvt )
1562 if (rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
1564 m_pSymbolDisplay->Invalidate();
1565 m_pSymbolSetDisplay->Invalidate();
1568 ModalDialog::DataChanged( rDCEvt );
1571 bool SmSymbolDialog::SelectSymbolSet(const OUString &rSymbolSetName)
1573 bool bRet = false;
1574 sal_Int32 nPos = m_pSymbolSets->GetEntryPos(rSymbolSetName);
1576 aSymbolSetName.clear();
1577 aSymbolSet.clear();
1578 if (nPos != LISTBOX_ENTRY_NOTFOUND)
1580 m_pSymbolSets->SelectEntryPos(nPos);
1582 aSymbolSetName = rSymbolSetName;
1583 aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
1585 // sort symbols by Unicode position (useful for displaying Greek characters alphabetically)
1586 std::sort( aSymbolSet.begin(), aSymbolSet.end(),
1587 [](const SmSym *pSym1, const SmSym *pSym2)
1589 return pSym1->GetCharacter() < pSym2->GetCharacter();
1590 } );
1592 m_pSymbolSetDisplay->SetSymbolSet( aSymbolSet );
1593 if (aSymbolSet.size() > 0)
1594 SelectSymbol(0);
1596 bRet = true;
1598 else
1599 m_pSymbolSets->SetNoSelection();
1601 return bRet;
1604 void SmSymbolDialog::SelectSymbol(sal_uInt16 nSymbolNo)
1606 const SmSym *pSym = nullptr;
1607 if (!aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size()))
1608 pSym = aSymbolSet[ nSymbolNo ];
1610 m_pSymbolSetDisplay->SelectSymbol(nSymbolNo);
1611 m_pSymbolDisplay->SetSymbol(pSym);
1612 m_pSymbolName->SetText(pSym ? pSym->GetName() : OUString());
1615 const SmSym* SmSymbolDialog::GetSymbol() const
1617 sal_uInt16 nSymbolNo = m_pSymbolSetDisplay->GetSelectSymbol();
1618 bool bValid = !aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size());
1619 return bValid ? aSymbolSet[ nSymbolNo ] : nullptr;
1622 VCL_BUILDER_FACTORY_CONSTRUCTOR(SmShowChar, 0)
1624 void SmShowChar::Paint(vcl::RenderContext& rRenderContext, const Rectangle &rRect)
1626 Control::Paint(rRenderContext, rRect);
1628 OUString aText( GetText() );
1629 if (!aText.isEmpty())
1631 Size aTextSize(rRenderContext.GetTextWidth(aText), rRenderContext.GetTextHeight());
1633 rRenderContext.DrawText(Point((GetOutputSize().Width() - aTextSize.Width()) / 2,
1634 (GetOutputSize().Height() * 7/10)), aText);
1639 void SmShowChar::SetSymbol( const SmSym *pSym )
1641 if (pSym)
1642 SetSymbol( pSym->GetCharacter(), pSym->GetFace() );
1646 void SmShowChar::SetSymbol( sal_UCS4 cChar, const vcl::Font &rFont )
1648 vcl::Font aFont( rFont );
1649 aFont.SetFontSize( Size(0, GetOutputSize().Height() - GetOutputSize().Height() / 3) );
1650 aFont.SetAlignment(ALIGN_BASELINE);
1651 SetFont(aFont);
1652 aFont.SetTransparent(true);
1654 OUString aText(&cChar, 1);
1655 SetText( aText );
1657 Invalidate();
1660 void SmShowChar::Resize()
1662 Control::Resize();
1663 const OUString &rText = GetText();
1664 if (rText.isEmpty())
1665 return;
1666 sal_Int32 nStrIndex = 0;
1667 sal_UCS4 cChar = rText.iterateCodePoints(&nStrIndex);
1668 SetSymbol(cChar, GetFont()); //force recalculation of size
1671 void SmSymDefineDialog::FillSymbols(ComboBox &rComboBox, bool bDeleteText)
1673 assert((&rComboBox == pOldSymbols || &rComboBox == pSymbols) && "Sm : wrong ComboBox");
1675 rComboBox.Clear();
1676 if (bDeleteText)
1677 rComboBox.SetText(OUString());
1679 ComboBox &rBox = &rComboBox == pOldSymbols ? *pOldSymbolSets : *pSymbolSets;
1680 SymbolPtrVec_t aSymSet( aSymbolMgrCopy.GetSymbolSet( rBox.GetText() ) );
1681 for (const SmSym* i : aSymSet)
1682 rComboBox.InsertEntry( i->GetName() );
1686 void SmSymDefineDialog::FillSymbolSets(ComboBox &rComboBox, bool bDeleteText)
1688 assert((&rComboBox == pOldSymbolSets || &rComboBox == pSymbolSets) && "Sm : falsche ComboBox");
1690 rComboBox.Clear();
1691 if (bDeleteText)
1692 rComboBox.SetText(OUString());
1694 const std::set< OUString > aSymbolSetNames( aSymbolMgrCopy.GetSymbolSetNames() );
1695 std::set< OUString >::const_iterator aIt( aSymbolSetNames.begin() );
1696 for ( ; aIt != aSymbolSetNames.end(); ++aIt)
1697 rComboBox.InsertEntry( *aIt );
1701 void SmSymDefineDialog::FillFonts()
1703 pFonts->Clear();
1704 pFonts->SetNoSelection();
1706 // Include all fonts of FontList into the font list.
1707 // If there are duplicates, only include one entry of each font since the style will be
1708 // already selected using the FontStyleBox.
1709 if (pFontList)
1711 sal_uInt16 nCount = pFontList->GetFontNameCount();
1712 for (sal_uInt16 i = 0; i < nCount; i++)
1713 pFonts->InsertEntry( pFontList->GetFontName(i).GetFamilyName() );
1718 void SmSymDefineDialog::FillStyles()
1720 pStyles->Clear();
1721 pStyles->SetText(OUString());
1723 OUString aText (pFonts->GetSelectEntry());
1724 if (!aText.isEmpty())
1726 // use own StyleNames
1727 const SmFontStyles &rStyles = GetFontStyles();
1728 for (sal_uInt16 i = 0; i < SmFontStyles::GetCount(); i++)
1729 pStyles->InsertEntry( rStyles.GetStyleName(i) );
1731 assert(pStyles->GetEntryCount() > 0 && "Sm : no styles available");
1732 pStyles->SetText( pStyles->GetEntry(0) );
1737 SmSym * SmSymDefineDialog::GetSymbol(const ComboBox &rComboBox)
1739 assert((&rComboBox == pOldSymbols || &rComboBox == pSymbols) && "Sm : wrong combobox");
1740 return aSymbolMgrCopy.GetSymbolByName(rComboBox.GetText());
1744 IMPL_LINK( SmSymDefineDialog, OldSymbolChangeHdl, ComboBox&, rComboBox, void )
1746 (void) rComboBox;
1747 assert(&rComboBox == pOldSymbols && "Sm : wrong argument");
1748 SelectSymbol(*pOldSymbols, pOldSymbols->GetText(), false);
1752 IMPL_LINK( SmSymDefineDialog, OldSymbolSetChangeHdl, ComboBox&, rComboBox, void )
1754 (void) rComboBox;
1755 assert(&rComboBox == pOldSymbolSets && "Sm : wrong argument");
1756 SelectSymbolSet(*pOldSymbolSets, pOldSymbolSets->GetText(), false);
1760 IMPL_LINK( SmSymDefineDialog, ModifyHdl, Edit&, rEdit, void )
1762 ComboBox& rComboBox = static_cast<ComboBox&>(rEdit);
1763 // remember cursor position for later restoring of it
1764 Selection aSelection (rComboBox.GetSelection());
1766 if (&rComboBox == pSymbols)
1767 SelectSymbol(*pSymbols, pSymbols->GetText(), false);
1768 else if (&rComboBox == pSymbolSets)
1769 SelectSymbolSet(*pSymbolSets, pSymbolSets->GetText(), false);
1770 else if (&rComboBox == pOldSymbols)
1771 // allow only names from the list
1772 SelectSymbol(*pOldSymbols, pOldSymbols->GetText(), true);
1773 else if (&rComboBox == pOldSymbolSets)
1774 // allow only names from the list
1775 SelectSymbolSet(*pOldSymbolSets, pOldSymbolSets->GetText(), true);
1776 else if (&rComboBox == pStyles)
1777 // allow only names from the list (that's the case here anyway)
1778 SelectStyle(pStyles->GetText(), true);
1779 else
1780 SAL_WARN("starmath", "wrong combobox argument");
1782 rComboBox.SetSelection(aSelection);
1784 UpdateButtons();
1787 IMPL_LINK( SmSymDefineDialog, FontChangeHdl, ListBox&, rListBox, void )
1789 (void) rListBox;
1790 assert(&rListBox == pFonts && "Sm : wrong argument");
1792 SelectFont(pFonts->GetSelectEntry());
1796 IMPL_LINK_NOARG( SmSymDefineDialog, SubsetChangeHdl, ListBox&, void )
1798 sal_Int32 nPos = pFontsSubsetLB->GetSelectEntryPos();
1799 if (LISTBOX_ENTRY_NOTFOUND != nPos)
1801 const Subset* pSubset = static_cast<const Subset*> (pFontsSubsetLB->GetEntryData( nPos ));
1802 if (pSubset)
1804 pCharsetDisplay->SelectCharacter( pSubset->GetRangeMin() );
1810 IMPL_LINK( SmSymDefineDialog, StyleChangeHdl, ComboBox&, rComboBox, void )
1812 (void) rComboBox;
1813 assert(&rComboBox == pStyles && "Sm : falsches Argument");
1815 SelectStyle(pStyles->GetText());
1819 IMPL_LINK_NOARG(SmSymDefineDialog, CharHighlightHdl, SvxShowCharSet*, void)
1821 sal_UCS4 cChar = pCharsetDisplay->GetSelectCharacter();
1823 assert(pSubsetMap && "SubsetMap missing");
1824 if (pSubsetMap)
1826 const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
1827 if (pSubset)
1828 pFontsSubsetLB->SelectEntry( pSubset->GetName() );
1829 else
1830 pFontsSubsetLB->SetNoSelection();
1833 pSymbolDisplay->SetSymbol( cChar, pCharsetDisplay->GetFont() );
1835 UpdateButtons();
1837 // display Unicode position as symbol name while iterating over characters
1838 const OUString aHex(OUString::number(cChar, 16 ).toAsciiUpperCase());
1839 const OUString aPattern( (aHex.getLength() > 4) ? OUString("Ux000000") : OUString("Ux0000") );
1840 OUString aUnicodePos( aPattern.copy( 0, aPattern.getLength() - aHex.getLength() ) );
1841 aUnicodePos += aHex;
1842 pSymbols->SetText( aUnicodePos );
1843 pSymbolName->SetText( aUnicodePos );
1847 IMPL_LINK( SmSymDefineDialog, AddClickHdl, Button *, pButton, void )
1849 (void) pButton;
1850 assert(pButton == pAddBtn && "Sm : wrong argument");
1851 assert(pButton->IsEnabled() && "Sm : requirements met ??");
1853 // add symbol
1854 const SmSym aNewSymbol( pSymbols->GetText(), pCharsetDisplay->GetFont(),
1855 pCharsetDisplay->GetSelectCharacter(), pSymbolSets->GetText() );
1856 //OSL_ENSURE( aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == NULL, "symbol already exists" );
1857 aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol );
1859 // update display of new symbol
1860 pSymbolDisplay->SetSymbol( &aNewSymbol );
1861 pSymbolName->SetText( aNewSymbol.GetName() );
1862 pSymbolSetName->SetText( aNewSymbol.GetSymbolSetName() );
1864 // update list box entries
1865 FillSymbolSets(*pOldSymbolSets, false);
1866 FillSymbolSets(*pSymbolSets, false);
1867 FillSymbols(*pOldSymbols ,false);
1868 FillSymbols(*pSymbols ,false);
1870 UpdateButtons();
1874 IMPL_LINK( SmSymDefineDialog, ChangeClickHdl, Button *, pButton, void )
1876 (void) pButton;
1877 assert(pButton == pChangeBtn && "Sm : wrong argument");
1878 assert(pChangeBtn->IsEnabled() && "Sm : requirements met ??");
1880 // get new Sybol to use
1881 //! get font from symbol-disp lay since charset-display does not keep
1882 //! the bold attribute.
1883 const SmSym aNewSymbol( pSymbols->GetText(), pCharsetDisplay->GetFont(),
1884 pCharsetDisplay->GetSelectCharacter(), pSymbolSets->GetText() );
1886 // remove old symbol if the name was changed then add new one
1887 const bool bNameChanged = pOldSymbols->GetText() != pSymbols->GetText();
1888 if (bNameChanged)
1889 aSymbolMgrCopy.RemoveSymbol( pOldSymbols->GetText() );
1890 aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol, true );
1892 // clear display for original symbol if necessary
1893 if (bNameChanged)
1894 SetOrigSymbol(nullptr, OUString());
1896 // update display of new symbol
1897 pSymbolDisplay->SetSymbol( &aNewSymbol );
1898 pSymbolName->SetText( aNewSymbol.GetName() );
1899 pSymbolSetName->SetText( aNewSymbol.GetSymbolSetName() );
1901 // update list box entries
1902 FillSymbolSets(*pOldSymbolSets, false);
1903 FillSymbolSets(*pSymbolSets, false);
1904 FillSymbols(*pOldSymbols ,false);
1905 FillSymbols(*pSymbols ,false);
1907 UpdateButtons();
1911 IMPL_LINK( SmSymDefineDialog, DeleteClickHdl, Button *, pButton, void )
1913 (void) pButton;
1914 assert(pButton == pDeleteBtn && "Sm : wrong argument");
1915 assert(pDeleteBtn->IsEnabled() && "Sm : requirements met ??");
1917 if (pOrigSymbol)
1919 aSymbolMgrCopy.RemoveSymbol( pOrigSymbol->GetName() );
1921 // clear display for original symbol
1922 SetOrigSymbol(nullptr, OUString());
1924 // update list box entries
1925 FillSymbolSets(*pOldSymbolSets, false);
1926 FillSymbolSets(*pSymbolSets, false);
1927 FillSymbols(*pOldSymbols ,false);
1928 FillSymbols(*pSymbols ,false);
1931 UpdateButtons();
1935 void SmSymDefineDialog::UpdateButtons()
1937 bool bAdd = false,
1938 bChange = false,
1939 bDelete = false;
1940 OUString aTmpSymbolName (pSymbols->GetText()),
1941 aTmpSymbolSetName (pSymbolSets->GetText());
1943 if (aTmpSymbolName.getLength() > 0 && aTmpSymbolSetName.getLength() > 0)
1945 // are all settings equal?
1946 //! (Font-, Style- und SymbolSet name comparison is not case sensitive)
1947 bool bEqual = pOrigSymbol
1948 && aTmpSymbolSetName.equalsIgnoreAsciiCase(pOldSymbolSetName->GetText())
1949 && aTmpSymbolName.equals(pOrigSymbol->GetName())
1950 && pFonts->GetSelectEntry().equalsIgnoreAsciiCase(
1951 pOrigSymbol->GetFace().GetFamilyName())
1952 && pStyles->GetText().equalsIgnoreAsciiCase(
1953 GetFontStyles().GetStyleName(pOrigSymbol->GetFace()))
1954 && pCharsetDisplay->GetSelectCharacter() == pOrigSymbol->GetCharacter();
1956 // only add it if there isn't already a symbol with the same name
1957 bAdd = aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == nullptr;
1959 // only delete it if all settings are equal
1960 bDelete = bool(pOrigSymbol);
1962 // only change it if the old symbol exists and the new one is different
1963 bChange = pOrigSymbol && !bEqual;
1966 pAddBtn ->Enable(bAdd);
1967 pChangeBtn->Enable(bChange);
1968 pDeleteBtn->Enable(bDelete);
1971 SmSymDefineDialog::SmSymDefineDialog(vcl::Window * pParent,
1972 OutputDevice *pFntListDevice, SmSymbolManager &rMgr) :
1973 ModalDialog (pParent, "EditSymbols", "modules/smath/ui/symdefinedialog.ui"),
1974 rSymbolMgr (rMgr),
1975 pOrigSymbol (),
1976 pSubsetMap (),
1977 pFontList (nullptr)
1979 get(pOldSymbols, "oldSymbols");
1980 get(pOldSymbolSets, "oldSymbolSets");
1981 get(pCharsetDisplay, "charsetDisplay");
1982 get(pSymbols, "symbols");
1983 get(pSymbolSets, "symbolSets");
1984 get(pFonts, "fonts");
1985 get(pFontsSubsetLB, "fontsSubsetLB");
1986 get(pStyles, "styles");
1987 get(pOldSymbolName, "oldSymbolName");
1988 get(pOldSymbolDisplay, "oldSymbolDisplay");
1989 get(pOldSymbolSetName, "oldSymbolSetName");
1990 get(pSymbolName, "symbolName");
1991 get(pSymbolDisplay, "symbolDisplay");
1992 get(pSymbolSetName, "symbolSetName");
1993 get(pAddBtn, "add");
1994 get(pChangeBtn, "modify");
1995 get(pDeleteBtn, "delete");
1997 pFontList = new FontList( pFntListDevice );
1999 // auto completion is troublesome since that symbols character also gets automatically selected in the
2000 // display and if the user previously selected a character to define/redefine that one this is bad
2001 pOldSymbols->EnableAutocomplete( false, true );
2002 pSymbols->EnableAutocomplete( false, true );
2004 FillFonts();
2005 if (pFonts->GetEntryCount() > 0)
2006 SelectFont(pFonts->GetEntry(0));
2008 SetSymbolSetManager(rSymbolMgr);
2010 pOldSymbols ->SetSelectHdl(LINK(this, SmSymDefineDialog, OldSymbolChangeHdl));
2011 pOldSymbolSets ->SetSelectHdl(LINK(this, SmSymDefineDialog, OldSymbolSetChangeHdl));
2012 pSymbolSets ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2013 pOldSymbolSets ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2014 pSymbols ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2015 pOldSymbols ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2016 pStyles ->SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
2017 pFonts ->SetSelectHdl(LINK(this, SmSymDefineDialog, FontChangeHdl));
2018 pFontsSubsetLB ->SetSelectHdl(LINK(this, SmSymDefineDialog, SubsetChangeHdl));
2019 pStyles ->SetSelectHdl(LINK(this, SmSymDefineDialog, StyleChangeHdl));
2020 pAddBtn ->SetClickHdl (LINK(this, SmSymDefineDialog, AddClickHdl));
2021 pChangeBtn ->SetClickHdl (LINK(this, SmSymDefineDialog, ChangeClickHdl));
2022 pDeleteBtn ->SetClickHdl (LINK(this, SmSymDefineDialog, DeleteClickHdl));
2023 pCharsetDisplay ->SetHighlightHdl( LINK( this, SmSymDefineDialog, CharHighlightHdl ) );
2025 // preview like controls should have a 2D look
2026 pOldSymbolDisplay->SetBorderStyle( WindowBorderStyle::MONO );
2027 pSymbolDisplay ->SetBorderStyle( WindowBorderStyle::MONO );
2031 SmSymDefineDialog::~SmSymDefineDialog()
2033 disposeOnce();
2036 void SmSymDefineDialog::dispose()
2038 pSubsetMap.reset();
2039 pOrigSymbol.reset();
2040 pOldSymbols.clear();
2041 pOldSymbolSets.clear();
2042 pCharsetDisplay.clear();
2043 pSymbols.clear();
2044 pSymbolSets.clear();
2045 pFonts.clear();
2046 pFontsSubsetLB.clear();
2047 pStyles.clear();
2048 pOldSymbolName.clear();
2049 pOldSymbolDisplay.clear();
2050 pOldSymbolSetName.clear();
2051 pSymbolName.clear();
2052 pSymbolDisplay.clear();
2053 pSymbolSetName.clear();
2054 pAddBtn.clear();
2055 pChangeBtn.clear();
2056 pDeleteBtn.clear();
2057 ModalDialog::dispose();
2060 void SmSymDefineDialog::DataChanged( const DataChangedEvent& rDCEvt )
2062 if (rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
2064 Invalidate();
2066 ModalDialog::DataChanged( rDCEvt );
2070 short SmSymDefineDialog::Execute()
2072 short nResult = ModalDialog::Execute();
2074 // apply changes if dialog was closed by clicking OK
2075 if (aSymbolMgrCopy.IsModified() && nResult == RET_OK)
2076 rSymbolMgr = aSymbolMgrCopy;
2078 return nResult;
2082 void SmSymDefineDialog::SetSymbolSetManager(const SmSymbolManager &rMgr)
2084 aSymbolMgrCopy = rMgr;
2086 // Set the modified flag of the copy to false so that
2087 // we can check later on if anything has been changed
2088 aSymbolMgrCopy.SetModified(false);
2090 FillSymbolSets(*pOldSymbolSets);
2091 if (pOldSymbolSets->GetEntryCount() > 0)
2092 SelectSymbolSet(pOldSymbolSets->GetEntry(0));
2093 FillSymbolSets(*pSymbolSets);
2094 if (pSymbolSets->GetEntryCount() > 0)
2095 SelectSymbolSet(pSymbolSets->GetEntry(0));
2096 FillSymbols(*pOldSymbols);
2097 if (pOldSymbols->GetEntryCount() > 0)
2098 SelectSymbol(pOldSymbols->GetEntry(0));
2099 FillSymbols(*pSymbols);
2100 if (pSymbols->GetEntryCount() > 0)
2101 SelectSymbol(pSymbols->GetEntry(0));
2103 UpdateButtons();
2107 bool SmSymDefineDialog::SelectSymbolSet(ComboBox &rComboBox,
2108 const OUString &rSymbolSetName, bool bDeleteText)
2110 assert((&rComboBox == pOldSymbolSets || &rComboBox == pSymbolSets) && "Sm : wrong ComboBox");
2112 // trim SymbolName (no leading and trailing blanks)
2113 OUString aNormName (rSymbolSetName);
2114 aNormName = comphelper::string::stripStart(aNormName, ' ');
2115 aNormName = comphelper::string::stripEnd(aNormName, ' ');
2116 // and remove possible deviations within the input
2117 rComboBox.SetText(aNormName);
2119 bool bRet = false;
2120 sal_Int32 nPos = rComboBox.GetEntryPos(aNormName);
2122 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
2124 rComboBox.SetText(rComboBox.GetEntry(nPos));
2125 bRet = true;
2127 else if (bDeleteText)
2128 rComboBox.SetText(OUString());
2130 bool bIsOld = &rComboBox == pOldSymbolSets;
2132 // setting the SymbolSet name at the associated display
2133 FixedText &rFT = bIsOld ? *pOldSymbolSetName : *pSymbolSetName;
2134 rFT.SetText(rComboBox.GetText());
2136 // set the symbol name which belongs to the SymbolSet at the associated combobox
2137 ComboBox &rCB = bIsOld ? *pOldSymbols : *pSymbols;
2138 FillSymbols(rCB, false);
2140 // display a valid respectively no symbol when changing the SymbolSets
2141 if (bIsOld)
2143 OUString aTmpOldSymbolName;
2144 if (pOldSymbols->GetEntryCount() > 0)
2145 aTmpOldSymbolName = pOldSymbols->GetEntry(0);
2146 SelectSymbol(*pOldSymbols, aTmpOldSymbolName, true);
2149 UpdateButtons();
2151 return bRet;
2155 void SmSymDefineDialog::SetOrigSymbol(const SmSym *pSymbol,
2156 const OUString &rSymbolSetName)
2158 // clear old symbol
2159 pOrigSymbol.reset();
2161 OUString aSymName,
2162 aSymSetName;
2163 if (pSymbol)
2165 // set new symbol
2166 pOrigSymbol.reset(new SmSym( *pSymbol ));
2168 aSymName = pSymbol->GetName();
2169 aSymSetName = rSymbolSetName;
2170 pOldSymbolDisplay->SetSymbol( pSymbol );
2172 else
2173 { // delete displayed symbols
2174 pOldSymbolDisplay->SetText(OUString());
2175 pOldSymbolDisplay->Invalidate();
2177 pOldSymbolName->SetText(aSymName);
2178 pOldSymbolSetName->SetText(aSymSetName);
2182 bool SmSymDefineDialog::SelectSymbol(ComboBox &rComboBox,
2183 const OUString &rSymbolName, bool bDeleteText)
2185 assert((&rComboBox == pOldSymbols || &rComboBox == pSymbols) && "Sm : wrong ComboBox");
2187 // trim SymbolName (no blanks)
2188 OUString aNormName = rSymbolName.replaceAll(" ", "");
2189 // and remove possible deviations within the input
2190 rComboBox.SetText(aNormName);
2192 bool bRet = false;
2193 sal_Int32 nPos = rComboBox.GetEntryPos(aNormName);
2195 bool bIsOld = &rComboBox == pOldSymbols;
2197 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
2199 rComboBox.SetText(rComboBox.GetEntry(nPos));
2201 if (!bIsOld)
2203 const SmSym *pSymbol = GetSymbol(*pSymbols);
2204 if (pSymbol)
2206 // choose font and style accordingly
2207 const vcl::Font &rFont = pSymbol->GetFace();
2208 SelectFont(rFont.GetFamilyName(), false);
2209 SelectStyle(GetFontStyles().GetStyleName(rFont), false);
2211 // Since setting the Font via the Style name of the SymbolFonts doesn't
2212 // work really well (e.g. it can be empty even though the font itself is
2213 // bold or italic) we're manually setting the Font with respect to the Symbol
2214 pCharsetDisplay->SetFont(rFont);
2215 pSymbolDisplay->SetFont(rFont);
2217 // select associated character
2218 SelectChar(pSymbol->GetCharacter());
2220 // since SelectChar will also set the unicode point as text in the
2221 // symbols box, we have to set the symbol name again to get that one displayed
2222 pSymbols->SetText( pSymbol->GetName() );
2226 bRet = true;
2228 else if (bDeleteText)
2229 rComboBox.SetText(OUString());
2231 if (bIsOld)
2233 // if there's a change of the old symbol, show only the available ones, otherwise show none
2234 const SmSym *pOldSymbol = nullptr;
2235 OUString aTmpOldSymbolSetName;
2236 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
2238 pOldSymbol = aSymbolMgrCopy.GetSymbolByName(aNormName);
2239 aTmpOldSymbolSetName = pOldSymbolSets->GetText();
2241 SetOrigSymbol(pOldSymbol, aTmpOldSymbolSetName);
2243 else
2244 pSymbolName->SetText(rComboBox.GetText());
2246 UpdateButtons();
2248 return bRet;
2252 void SmSymDefineDialog::SetFont(const OUString &rFontName, const OUString &rStyleName)
2254 // get Font (FontInfo) matching name and style
2255 FontMetric aFontMetric;
2256 if (pFontList)
2257 aFontMetric = pFontList->Get(rFontName, WEIGHT_NORMAL, ITALIC_NONE);
2258 SetFontStyle(rStyleName, aFontMetric);
2260 pCharsetDisplay->SetFont(aFontMetric);
2261 pSymbolDisplay->SetFont(aFontMetric);
2263 // update subset listbox for new font's unicode subsets
2264 FontCharMapRef xFontCharMap;
2265 pCharsetDisplay->GetFontCharMap( xFontCharMap );
2266 pSubsetMap.reset(new SubsetMap( xFontCharMap ));
2268 pFontsSubsetLB->Clear();
2269 bool bFirst = true;
2270 const Subset* pSubset;
2271 while( nullptr != (pSubset = pSubsetMap->GetNextSubset( bFirst )) )
2273 const sal_Int32 nPos = pFontsSubsetLB->InsertEntry( pSubset->GetName());
2274 pFontsSubsetLB->SetEntryData( nPos, const_cast<Subset *>(pSubset) );
2275 // subset must live at least as long as the selected font !!!
2276 if( bFirst )
2277 pFontsSubsetLB->SelectEntryPos( nPos );
2278 bFirst = false;
2280 if( bFirst )
2281 pFontsSubsetLB->SetNoSelection();
2282 pFontsSubsetLB->Enable( !bFirst );
2286 bool SmSymDefineDialog::SelectFont(const OUString &rFontName, bool bApplyFont)
2288 bool bRet = false;
2289 sal_Int32 nPos = pFonts->GetEntryPos(rFontName);
2291 if (nPos != LISTBOX_ENTRY_NOTFOUND)
2293 pFonts->SelectEntryPos(nPos);
2294 if (pStyles->GetEntryCount() > 0)
2295 SelectStyle(pStyles->GetEntry(0));
2296 if (bApplyFont)
2298 SetFont(pFonts->GetSelectEntry(), pStyles->GetText());
2299 pSymbolDisplay->SetSymbol( pCharsetDisplay->GetSelectCharacter(), pCharsetDisplay->GetFont() );
2301 bRet = true;
2303 else
2304 pFonts->SetNoSelection();
2305 FillStyles();
2307 UpdateButtons();
2309 return bRet;
2313 bool SmSymDefineDialog::SelectStyle(const OUString &rStyleName, bool bApplyFont)
2315 bool bRet = false;
2316 sal_Int32 nPos = pStyles->GetEntryPos(rStyleName);
2318 // if the style is not available take the first available one (if existent)
2319 if (nPos == COMBOBOX_ENTRY_NOTFOUND && pStyles->GetEntryCount() > 0)
2320 nPos = 0;
2322 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
2324 pStyles->SetText(pStyles->GetEntry(nPos));
2325 if (bApplyFont)
2327 SetFont(pFonts->GetSelectEntry(), pStyles->GetText());
2328 pSymbolDisplay->SetSymbol( pCharsetDisplay->GetSelectCharacter(), pCharsetDisplay->GetFont() );
2330 bRet = true;
2332 else
2333 pStyles->SetText(OUString());
2335 UpdateButtons();
2337 return bRet;
2341 void SmSymDefineDialog::SelectChar(sal_Unicode cChar)
2343 pCharsetDisplay->SelectCharacter( cChar );
2344 pSymbolDisplay->SetSymbol( cChar, pCharsetDisplay->GetFont() );
2346 UpdateButtons();
2350 /**************************************************************************/
2352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */