Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / starmath / source / dialog.cxx
blob1dabf0abd0b3afcb26a83580367fc3e66fdbf36e
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 <comphelper/string.hxx>
25 #include <svl/eitem.hxx>
26 #include <svl/intitem.hxx>
27 #include <svl/stritem.hxx>
28 #include <vcl/builderfactory.hxx>
29 #include <vcl/weld.hxx>
30 #include <svtools/ctrltool.hxx>
31 #include <vcl/waitobj.hxx>
32 #include <vcl/settings.hxx>
33 #include <vcl/wall.hxx>
34 #include <vcl/fontcharmap.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <svx/ucsubset.hxx>
38 #include <dialog.hxx>
39 #include <starmath.hrc>
40 #include <strings.hrc>
41 #include <helpids.h>
42 #include "cfgitem.hxx"
43 #include <smmod.hxx>
44 #include <symbol.hxx>
45 #include <view.hxx>
47 #include <algorithm>
49 namespace
52 void lclGetSettingColors(Color& rBackgroundColor, Color& rTextColor)
54 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
55 if (rStyleSettings.GetHighContrastMode())
57 rBackgroundColor = rStyleSettings.GetFieldColor();
58 rTextColor = rStyleSettings.GetFieldTextColor();
60 else
62 rBackgroundColor = COL_WHITE;
63 rTextColor = COL_BLACK;
67 } // end anonymous namespace
69 // Since it's better to set/query the FontStyle via its attributes rather
70 // than via the StyleName we create a way to translate
71 // Attribute <-> StyleName
73 class SmFontStyles
75 OUString aNormal;
76 OUString aBold;
77 OUString aItalic;
78 OUString aBoldItalic;
80 public:
81 SmFontStyles();
83 static sal_uInt16 GetCount() { return 4; }
84 const OUString& GetStyleName(const vcl::Font& rFont) const;
85 const OUString& GetStyleName(sal_uInt16 nIdx) const;
88 SmFontStyles::SmFontStyles()
89 : aNormal(SmResId(RID_FONTREGULAR))
90 , aBold(SmResId(RID_FONTBOLD))
91 , aItalic(SmResId(RID_FONTITALIC))
93 aBoldItalic = aBold;
94 aBoldItalic += ", ";
95 aBoldItalic += aItalic;
98 const OUString& SmFontStyles::GetStyleName(const vcl::Font& rFont) const
100 //! compare also SmSpecialNode::Prepare
101 bool bBold = IsBold( rFont ),
102 bItalic = IsItalic( rFont );
104 if (bBold && bItalic)
105 return aBoldItalic;
106 else if (bItalic)
107 return aItalic;
108 else if (bBold)
109 return aBold;
110 return aNormal;
113 const OUString& SmFontStyles::GetStyleName( sal_uInt16 nIdx ) const
115 // 0 = "normal", 1 = "italic",
116 // 2 = "bold", 3 = "bold italic"
118 assert( nIdx < GetCount() );
119 switch (nIdx)
121 case 0 : return aNormal;
122 case 1 : return aItalic;
123 case 2 : return aBold;
124 default: /*case 3:*/ return aBoldItalic;
128 const SmFontStyles & GetFontStyles()
130 static const SmFontStyles aImpl;
131 return aImpl;
134 void SetFontStyle(const OUString &rStyleName, vcl::Font &rFont)
136 // Find index related to StyleName. For an empty StyleName it's assumed to be
137 // 0 (neither bold nor italic).
138 sal_uInt16 nIndex = 0;
139 if (!rStyleName.isEmpty())
141 sal_uInt16 i;
142 const SmFontStyles &rStyles = GetFontStyles();
143 for (i = 0; i < SmFontStyles::GetCount(); ++i)
144 if (rStyleName == rStyles.GetStyleName(i))
145 break;
146 assert(i < SmFontStyles::GetCount() && "style-name unknown");
147 nIndex = i;
150 rFont.SetItalic((nIndex & 0x1) ? ITALIC_NORMAL : ITALIC_NONE);
151 rFont.SetWeight((nIndex & 0x2) ? WEIGHT_BOLD : WEIGHT_NORMAL);
154 IMPL_LINK_NOARG(SmPrintOptionsTabPage, SizeButtonClickHdl, weld::ToggleButton&, void)
156 m_xZoom->set_sensitive(m_xSizeZoomed->get_active());
159 SmPrintOptionsTabPage::SmPrintOptionsTabPage(TabPageParent pPage, const SfxItemSet& rOptions)
160 : SfxTabPage(pPage, "modules/smath/ui/smathsettings.ui", "SmathSettings", &rOptions)
161 , m_xTitle(m_xBuilder->weld_check_button("title"))
162 , m_xText(m_xBuilder->weld_check_button("text"))
163 , m_xFrame(m_xBuilder->weld_check_button("frame"))
164 , m_xSizeNormal(m_xBuilder->weld_radio_button("sizenormal"))
165 , m_xSizeScaled(m_xBuilder->weld_radio_button("sizescaled"))
166 , m_xSizeZoomed(m_xBuilder->weld_radio_button("sizezoomed"))
167 , m_xZoom(m_xBuilder->weld_metric_spin_button("zoom", FUNIT_PERCENT))
168 , m_xNoRightSpaces(m_xBuilder->weld_check_button("norightspaces"))
169 , m_xSaveOnlyUsedSymbols(m_xBuilder->weld_check_button("saveonlyusedsymbols"))
170 , m_xAutoCloseBrackets(m_xBuilder->weld_check_button("autoclosebrackets"))
172 m_xSizeNormal->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
173 m_xSizeScaled->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
174 m_xSizeZoomed->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
176 Reset(&rOptions);
179 SmPrintOptionsTabPage::~SmPrintOptionsTabPage()
183 bool SmPrintOptionsTabPage::FillItemSet(SfxItemSet* rSet)
185 sal_uInt16 nPrintSize;
186 if (m_xSizeNormal->get_active())
187 nPrintSize = PRINT_SIZE_NORMAL;
188 else if (m_xSizeScaled->get_active())
189 nPrintSize = PRINT_SIZE_SCALED;
190 else
191 nPrintSize = PRINT_SIZE_ZOOMED;
193 rSet->Put(SfxUInt16Item(GetWhich(SID_PRINTSIZE), nPrintSize));
194 rSet->Put(SfxUInt16Item(GetWhich(SID_PRINTZOOM), sal::static_int_cast<sal_uInt16>(m_xZoom->get_value(FUNIT_PERCENT))));
195 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTTITLE), m_xTitle->get_active()));
196 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTTEXT), m_xText->get_active()));
197 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTFRAME), m_xFrame->get_active()));
198 rSet->Put(SfxBoolItem(GetWhich(SID_NO_RIGHT_SPACES), m_xNoRightSpaces->get_active()));
199 rSet->Put(SfxBoolItem(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS), m_xSaveOnlyUsedSymbols->get_active()));
200 rSet->Put(SfxBoolItem(GetWhich(SID_AUTO_CLOSE_BRACKETS), m_xAutoCloseBrackets->get_active()));
202 return true;
205 void SmPrintOptionsTabPage::Reset(const SfxItemSet* rSet)
207 SmPrintSize ePrintSize = static_cast<SmPrintSize>(static_cast<const SfxUInt16Item &>(rSet->Get(GetWhich(SID_PRINTSIZE))).GetValue());
209 m_xSizeNormal->set_active(ePrintSize == PRINT_SIZE_NORMAL);
210 m_xSizeScaled->set_active(ePrintSize == PRINT_SIZE_SCALED);
211 m_xSizeZoomed->set_active(ePrintSize == PRINT_SIZE_ZOOMED);
213 m_xZoom->set_sensitive(m_xSizeZoomed->get_active());
215 m_xZoom->set_value(static_cast<const SfxUInt16Item &>(rSet->Get(GetWhich(SID_PRINTZOOM))).GetValue(), FUNIT_PERCENT);
217 m_xTitle->set_active(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_PRINTTITLE))).GetValue());
218 m_xNoRightSpaces->set_active(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_NO_RIGHT_SPACES))).GetValue());
219 m_xSaveOnlyUsedSymbols->set_active(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS))).GetValue());
220 m_xAutoCloseBrackets->set_active(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_AUTO_CLOSE_BRACKETS))).GetValue());
223 VclPtr<SfxTabPage> SmPrintOptionsTabPage::Create(TabPageParent pParent, const SfxItemSet& rSet)
225 return VclPtr<SmPrintOptionsTabPage>::Create(pParent, rSet).get();
228 void SmShowFont::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
230 Window::Paint(rRenderContext, rRect);
232 Color aBackColor;
233 Color aTextColor;
234 lclGetSettingColors(aBackColor, aTextColor);
236 rRenderContext.SetBackground(Wallpaper(aBackColor));
238 vcl::Font aFont(maFont);
239 aFont.SetFontSize(Size(0, 24 * rRenderContext.GetDPIScaleFactor()));
240 aFont.SetAlignment(ALIGN_TOP);
241 rRenderContext.SetFont(aFont);
242 rRenderContext.SetTextColor(aTextColor);
244 OUString sText(rRenderContext.GetFont().GetFamilyName());
245 Size aTextSize(rRenderContext.GetTextWidth(sText), rRenderContext.GetTextHeight());
247 rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
248 (rRenderContext.GetOutputSize().Height() - aTextSize.Height()) / 2), sText);
251 VCL_BUILDER_FACTORY_CONSTRUCTOR(SmShowFont, 0)
253 Size SmShowFont::GetOptimalSize() const
255 return LogicToPixel(Size(111 , 31), MapMode(MapUnit::MapAppFont));
258 void SmShowFont::SetFont(const vcl::Font& rFont)
260 maFont = rFont;
261 Invalidate();
264 IMPL_LINK( SmFontDialog, FontSelectHdl, ComboBox&, rComboBox, void )
266 maFont.SetFamilyName(rComboBox.GetText());
267 m_pShowFont->SetFont(maFont);
270 IMPL_LINK( SmFontDialog, FontModifyHdl, Edit&, rEdit, void )
272 ComboBox& rComboBox = static_cast<ComboBox&>(rEdit);
273 // if font is available in list then use it
274 sal_Int32 nPos = rComboBox.GetEntryPos( rComboBox.GetText() );
275 if (COMBOBOX_ENTRY_NOTFOUND != nPos)
277 FontSelectHdl( rComboBox );
281 IMPL_LINK_NOARG( SmFontDialog, AttrChangeHdl, Button*, void )
283 if (m_pBoldCheckBox->IsChecked())
284 maFont.SetWeight(WEIGHT_BOLD);
285 else
286 maFont.SetWeight(WEIGHT_NORMAL);
288 if (m_pItalicCheckBox->IsChecked())
289 maFont.SetItalic(ITALIC_NORMAL);
290 else
291 maFont.SetItalic(ITALIC_NONE);
293 m_pShowFont->SetFont(maFont);
296 void SmFontDialog::SetFont(const vcl::Font &rFont)
298 maFont = rFont;
300 m_pFontBox->SetText(maFont.GetFamilyName());
301 m_pBoldCheckBox->Check(IsBold(maFont));
302 m_pItalicCheckBox->Check(IsItalic(maFont));
303 m_pShowFont->SetFont(maFont);
306 SmFontDialog::SmFontDialog(vcl::Window * pParent, OutputDevice *pFntListDevice, bool bHideCheckboxes)
307 : ModalDialog(pParent, "FontDialog", "modules/smath/ui/fontdialog.ui")
309 get(m_pFontBox, "font");
310 m_pFontBox->set_height_request(8 * m_pFontBox->GetTextHeight());
311 get(m_pAttrFrame, "attrframe");
312 get(m_pBoldCheckBox, "bold");
313 get(m_pItalicCheckBox, "italic");
314 get(m_pShowFont, "preview");
317 WaitObject aWait( this );
319 FontList aFontList( pFntListDevice );
321 sal_uInt16 nCount = aFontList.GetFontNameCount();
322 for (sal_uInt16 i = 0; i < nCount; ++i)
324 m_pFontBox->InsertEntry( aFontList.GetFontName(i).GetFamilyName() );
326 maFont.SetFontSize(Size(0, 24));
327 maFont.SetWeight(WEIGHT_NORMAL);
328 maFont.SetItalic(ITALIC_NONE);
329 maFont.SetFamily(FAMILY_DONTKNOW);
330 maFont.SetPitch(PITCH_DONTKNOW);
331 maFont.SetCharSet(RTL_TEXTENCODING_DONTKNOW);
332 maFont.SetTransparent(true);
334 // preview like controls should have a 2D look
335 m_pShowFont->SetBorderStyle( WindowBorderStyle::MONO );
338 m_pFontBox->SetSelectHdl(LINK(this, SmFontDialog, FontSelectHdl));
339 m_pFontBox->SetModifyHdl(LINK(this, SmFontDialog, FontModifyHdl));
340 m_pBoldCheckBox->SetClickHdl(LINK(this, SmFontDialog, AttrChangeHdl));
341 m_pItalicCheckBox->SetClickHdl(LINK(this, SmFontDialog, AttrChangeHdl));
343 if (bHideCheckboxes)
345 m_pBoldCheckBox->Check( false );
346 m_pBoldCheckBox->Enable( false );
347 m_pItalicCheckBox->Check( false );
348 m_pItalicCheckBox->Enable( false );
349 m_pAttrFrame->Show(false);
353 SmFontDialog::~SmFontDialog()
355 disposeOnce();
358 void SmFontDialog::dispose()
360 m_pFontBox.clear();
361 m_pAttrFrame.clear();
362 m_pBoldCheckBox.clear();
363 m_pItalicCheckBox.clear();
364 m_pShowFont.clear();
365 ModalDialog::dispose();
368 void SmFontDialog::DataChanged( const DataChangedEvent& rDCEvt )
370 if (rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
371 m_pShowFont->Invalidate();
373 ModalDialog::DataChanged( rDCEvt );
376 class SaveDefaultsQuery : public weld::MessageDialogController
378 public:
379 explicit SaveDefaultsQuery(weld::Widget* pParent)
380 : MessageDialogController(pParent, "modules/smath/ui/savedefaultsdialog.ui",
381 "SaveDefaultsDialog")
386 IMPL_LINK_NOARG( SmFontSizeDialog, DefaultButtonClickHdl, weld::Button&, void )
388 SaveDefaultsQuery aQuery(m_xDialog.get());
389 if (aQuery.run() == RET_YES)
391 SmModule *pp = SM_MOD();
392 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
393 WriteTo( aFmt );
394 pp->GetConfig()->SetStandardFormat( aFmt );
398 SmFontSizeDialog::SmFontSizeDialog(weld::Window* pParent)
399 : GenericDialogController(pParent, "modules/smath/ui/fontsizedialog.ui", "FontSizeDialog")
400 , m_xBaseSize(m_xBuilder->weld_metric_spin_button("spinB_baseSize", FUNIT_POINT))
401 , m_xTextSize(m_xBuilder->weld_metric_spin_button("spinB_text", FUNIT_PERCENT))
402 , m_xIndexSize(m_xBuilder->weld_metric_spin_button("spinB_index", FUNIT_PERCENT))
403 , m_xFunctionSize(m_xBuilder->weld_metric_spin_button("spinB_function", FUNIT_PERCENT))
404 , m_xOperatorSize(m_xBuilder->weld_metric_spin_button("spinB_operator", FUNIT_PERCENT))
405 , m_xBorderSize(m_xBuilder->weld_metric_spin_button("spinB_limit", FUNIT_PERCENT))
406 , m_xDefaultButton(m_xBuilder->weld_button("default"))
408 m_xDefaultButton->connect_clicked(LINK(this, SmFontSizeDialog, DefaultButtonClickHdl));
411 SmFontSizeDialog::~SmFontSizeDialog()
415 void SmFontSizeDialog::ReadFrom(const SmFormat &rFormat)
417 //! watch out: round properly!
418 m_xBaseSize->set_value( SmRoundFraction(
419 Sm100th_mmToPts( rFormat.GetBaseSize().Height() ) ), FUNIT_NONE );
421 m_xTextSize->set_value( rFormat.GetRelSize(SIZ_TEXT), FUNIT_NONE );
422 m_xIndexSize->set_value( rFormat.GetRelSize(SIZ_INDEX), FUNIT_NONE );
423 m_xFunctionSize->set_value( rFormat.GetRelSize(SIZ_FUNCTION), FUNIT_NONE );
424 m_xOperatorSize->set_value( rFormat.GetRelSize(SIZ_OPERATOR), FUNIT_NONE );
425 m_xBorderSize->set_value( rFormat.GetRelSize(SIZ_LIMITS), FUNIT_NONE );
428 void SmFontSizeDialog::WriteTo(SmFormat &rFormat) const
430 rFormat.SetBaseSize( Size(0, SmPtsTo100th_mm( static_cast< long >(m_xBaseSize->get_value(FUNIT_NONE)))) );
432 rFormat.SetRelSize(SIZ_TEXT, sal::static_int_cast<sal_uInt16>(m_xTextSize->get_value(FUNIT_NONE)));
433 rFormat.SetRelSize(SIZ_INDEX, sal::static_int_cast<sal_uInt16>(m_xIndexSize->get_value(FUNIT_NONE)));
434 rFormat.SetRelSize(SIZ_FUNCTION, sal::static_int_cast<sal_uInt16>(m_xFunctionSize->get_value(FUNIT_NONE)));
435 rFormat.SetRelSize(SIZ_OPERATOR, sal::static_int_cast<sal_uInt16>(m_xOperatorSize->get_value(FUNIT_NONE)));
436 rFormat.SetRelSize(SIZ_LIMITS, sal::static_int_cast<sal_uInt16>(m_xBorderSize->get_value(FUNIT_NONE)));
438 const Size aTmp (rFormat.GetBaseSize());
439 for (sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++)
440 rFormat.SetFontSize(i, aTmp);
442 rFormat.RequestApplyChanges();
445 IMPL_LINK(SmFontTypeDialog, MenuSelectHdl, const OString&, rIdent, void)
447 SmFontPickListBox *pActiveListBox;
449 bool bHideCheckboxes = false;
450 if (rIdent == "variables")
451 pActiveListBox = m_xVariableFont.get();
452 else if (rIdent == "functions")
453 pActiveListBox = m_xFunctionFont.get();
454 else if (rIdent == "numbers")
455 pActiveListBox = m_xNumberFont.get();
456 else if (rIdent == "text")
457 pActiveListBox = m_xTextFont.get();
458 else if (rIdent == "serif")
460 pActiveListBox = m_xSerifFont.get();
461 bHideCheckboxes = true;
463 else if (rIdent == "sansserif")
465 pActiveListBox = m_xSansFont.get();
466 bHideCheckboxes = true;
468 else if (rIdent == "fixedwidth")
470 pActiveListBox = m_xFixedFont.get();
471 bHideCheckboxes = true;
473 else
474 pActiveListBox = nullptr;
476 if (pActiveListBox)
478 ScopedVclPtrInstance<SmFontDialog> pFontDialog(nullptr /*TODO*/, pFontListDev, bHideCheckboxes);
480 pActiveListBox->WriteTo(*pFontDialog);
481 if (pFontDialog->Execute() == RET_OK)
482 pActiveListBox->ReadFrom(*pFontDialog);
486 IMPL_LINK_NOARG(SmFontTypeDialog, DefaultButtonClickHdl, weld::Button&, void)
488 SaveDefaultsQuery aQuery(m_xDialog.get());
489 if (aQuery.run() == RET_YES)
491 SmModule *pp = SM_MOD();
492 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
493 WriteTo( aFmt );
494 pp->GetConfig()->SetStandardFormat( aFmt, true );
498 SmFontTypeDialog::SmFontTypeDialog(weld::Window* pParent, OutputDevice *pFntListDevice)
499 : GenericDialogController(pParent, "modules/smath/ui/fonttypedialog.ui", "FontsDialog")
500 , pFontListDev(pFntListDevice)
501 , m_xVariableFont(new SmFontPickListBox(m_xBuilder->weld_combo_box_text("variableCB")))
502 , m_xFunctionFont(new SmFontPickListBox(m_xBuilder->weld_combo_box_text("functionCB")))
503 , m_xNumberFont(new SmFontPickListBox(m_xBuilder->weld_combo_box_text("numberCB")))
504 , m_xTextFont(new SmFontPickListBox(m_xBuilder->weld_combo_box_text("textCB")))
505 , m_xSerifFont(new SmFontPickListBox(m_xBuilder->weld_combo_box_text("serifCB")))
506 , m_xSansFont(new SmFontPickListBox(m_xBuilder->weld_combo_box_text("sansCB")))
507 , m_xFixedFont(new SmFontPickListBox(m_xBuilder->weld_combo_box_text("fixedCB")))
508 , m_xMenuButton(m_xBuilder->weld_menu_button("modify"))
509 , m_xDefaultButton(m_xBuilder->weld_button("default"))
511 m_xDefaultButton->connect_clicked(LINK(this, SmFontTypeDialog, DefaultButtonClickHdl));
512 m_xMenuButton->connect_selected(LINK(this, SmFontTypeDialog, MenuSelectHdl));
515 SmFontTypeDialog::~SmFontTypeDialog()
519 void SmFontTypeDialog::ReadFrom(const SmFormat &rFormat)
521 SmModule *pp = SM_MOD();
523 *m_xVariableFont = pp->GetConfig()->GetFontPickList(FNT_VARIABLE);
524 *m_xFunctionFont = pp->GetConfig()->GetFontPickList(FNT_FUNCTION);
525 *m_xNumberFont = pp->GetConfig()->GetFontPickList(FNT_NUMBER);
526 *m_xTextFont = pp->GetConfig()->GetFontPickList(FNT_TEXT);
527 *m_xSerifFont = pp->GetConfig()->GetFontPickList(FNT_SERIF);
528 *m_xSansFont = pp->GetConfig()->GetFontPickList(FNT_SANS);
529 *m_xFixedFont = pp->GetConfig()->GetFontPickList(FNT_FIXED);
531 m_xVariableFont->Insert( rFormat.GetFont(FNT_VARIABLE) );
532 m_xFunctionFont->Insert( rFormat.GetFont(FNT_FUNCTION) );
533 m_xNumberFont->Insert( rFormat.GetFont(FNT_NUMBER) );
534 m_xTextFont->Insert( rFormat.GetFont(FNT_TEXT) );
535 m_xSerifFont->Insert( rFormat.GetFont(FNT_SERIF) );
536 m_xSansFont->Insert( rFormat.GetFont(FNT_SANS) );
537 m_xFixedFont->Insert( rFormat.GetFont(FNT_FIXED) );
541 void SmFontTypeDialog::WriteTo(SmFormat &rFormat) const
543 SmModule *pp = SM_MOD();
545 pp->GetConfig()->GetFontPickList(FNT_VARIABLE) = *m_xVariableFont;
546 pp->GetConfig()->GetFontPickList(FNT_FUNCTION) = *m_xFunctionFont;
547 pp->GetConfig()->GetFontPickList(FNT_NUMBER) = *m_xNumberFont;
548 pp->GetConfig()->GetFontPickList(FNT_TEXT) = *m_xTextFont;
549 pp->GetConfig()->GetFontPickList(FNT_SERIF) = *m_xSerifFont;
550 pp->GetConfig()->GetFontPickList(FNT_SANS) = *m_xSansFont;
551 pp->GetConfig()->GetFontPickList(FNT_FIXED) = *m_xFixedFont;
553 rFormat.SetFont( FNT_VARIABLE, m_xVariableFont->Get() );
554 rFormat.SetFont( FNT_FUNCTION, m_xFunctionFont->Get() );
555 rFormat.SetFont( FNT_NUMBER, m_xNumberFont->Get() );
556 rFormat.SetFont( FNT_TEXT, m_xTextFont->Get() );
557 rFormat.SetFont( FNT_SERIF, m_xSerifFont->Get() );
558 rFormat.SetFont( FNT_SANS, m_xSansFont->Get() );
559 rFormat.SetFont( FNT_FIXED, m_xFixedFont->Get() );
561 rFormat.RequestApplyChanges();
564 /**************************************************************************/
566 struct FieldMinMax
568 sal_uInt16 nMin, nMax;
571 // Data for min and max values of the 4 metric fields
572 // for each of the 10 categories
573 static const FieldMinMax pMinMaxData[10][4] =
575 // 0
576 {{ 0, 200 }, { 0, 200 }, { 0, 100 }, { 0, 0 }},
577 // 1
578 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
579 // 2
580 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
581 // 3
582 {{ 0, 100 }, { 1, 100 }, { 0, 0 }, { 0, 0 }},
583 // 4
584 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
585 // 5
586 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 100 }},
587 // 6
588 {{ 0, 300 }, { 0, 300 }, { 0, 0 }, { 0, 0 }},
589 // 7
590 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
591 // 8
592 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
593 // 9
594 {{ 0, 10000 }, { 0, 10000 }, { 0, 10000 }, { 0, 10000 }}
597 SmCategoryDesc::SmCategoryDesc(weld::Builder& rBuilder, sal_uInt16 nCategoryIdx)
599 ++nCategoryIdx;
600 std::unique_ptr<weld::Label> xTitle(rBuilder.weld_label(OString::number(nCategoryIdx)+"title"));
601 if (xTitle)
603 Name = xTitle->get_label();
605 for (int i = 0; i < 4; ++i)
607 std::unique_ptr<weld::Label> xLabel(rBuilder.weld_label(OString::number(nCategoryIdx)+"label"+OString::number(i+1)));
609 if (xLabel)
611 Strings[i] = xLabel->get_label();
612 Graphics[i].reset(rBuilder.weld_widget(OString::number(nCategoryIdx)+"image"+OString::number(i+1)));
614 else
616 Strings[i].clear();
617 Graphics[i].reset();
620 const FieldMinMax& rMinMax = pMinMaxData[ nCategoryIdx-1 ][i];
621 Value[i] = Minimum[i] = rMinMax.nMin;
622 Maximum[i] = rMinMax.nMax;
626 SmCategoryDesc::~SmCategoryDesc()
630 /**************************************************************************/
632 IMPL_LINK( SmDistanceDialog, GetFocusHdl, weld::Widget&, rControl, void )
634 if (Categories[nActiveCategory])
636 sal_uInt16 i;
638 if (&rControl == &m_xMetricField1->get_widget())
639 i = 0;
640 else if (&rControl == &m_xMetricField2->get_widget())
641 i = 1;
642 else if (&rControl == &m_xMetricField3->get_widget())
643 i = 2;
644 else if (&rControl == &m_xMetricField4->get_widget())
645 i = 3;
646 else
647 return;
648 if (m_pCurrentImage)
649 m_pCurrentImage->hide();
650 m_pCurrentImage = Categories[nActiveCategory]->GetGraphic(i);
651 m_pCurrentImage->show();
655 IMPL_LINK(SmDistanceDialog, MenuSelectHdl, const OString&, rId, void)
657 assert(rId.startsWith("menuitem"));
658 SetCategory(rId.replaceFirst("menuitem", "").toInt32() - 1);
661 IMPL_LINK_NOARG( SmDistanceDialog, DefaultButtonClickHdl, weld::Button&, void )
663 SaveDefaultsQuery aQuery(m_xDialog.get());
664 if (aQuery.run() == RET_YES)
666 SmModule *pp = SM_MOD();
667 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
668 WriteTo( aFmt );
669 pp->GetConfig()->SetStandardFormat( aFmt );
673 IMPL_LINK( SmDistanceDialog, CheckBoxClickHdl, weld::ToggleButton&, rCheckBox, void )
675 if (&rCheckBox == m_xCheckBox1.get())
677 bool bChecked = m_xCheckBox1->get_active();
678 m_xFixedText4->set_sensitive( bChecked );
679 m_xMetricField4->set_sensitive( bChecked );
683 void SmDistanceDialog::SetCategory(sal_uInt16 nCategory)
685 assert(nCategory < NOCATEGORIES && "Sm: wrong category number in SmDistanceDialog");
687 // array to convert category- and metricfield-number in help ids.
688 // 0 is used in case of unused combinations.
689 assert(NOCATEGORIES == 10 && "Sm : array doesn't fit into the number of categories");
690 static const char * aCatMf2Hid[10][4] =
692 { HID_SMA_DEFAULT_DIST, HID_SMA_LINE_DIST, HID_SMA_ROOT_DIST, nullptr },
693 { HID_SMA_SUP_DIST, HID_SMA_SUB_DIST , nullptr, nullptr },
694 { HID_SMA_NUMERATOR_DIST, HID_SMA_DENOMINATOR_DIST, nullptr, nullptr },
695 { HID_SMA_FRACLINE_EXCWIDTH, HID_SMA_FRACLINE_LINEWIDTH, nullptr, nullptr },
696 { HID_SMA_UPPERLIMIT_DIST, HID_SMA_LOWERLIMIT_DIST, nullptr, nullptr },
697 { HID_SMA_BRACKET_EXCHEIGHT, HID_SMA_BRACKET_DIST, nullptr, HID_SMA_BRACKET_EXCHEIGHT2 },
698 { HID_SMA_MATRIXROW_DIST, HID_SMA_MATRIXCOL_DIST, nullptr, nullptr },
699 { HID_SMA_ATTRIBUT_DIST, HID_SMA_INTERATTRIBUT_DIST, nullptr, nullptr },
700 { HID_SMA_OPERATOR_EXCHEIGHT, HID_SMA_OPERATOR_DIST, nullptr, nullptr },
701 { HID_SMA_LEFTBORDER_DIST, HID_SMA_RIGHTBORDER_DIST, HID_SMA_UPPERBORDER_DIST, HID_SMA_LOWERBORDER_DIST }
704 // array to help iterate over the controls
705 std::pair<weld::Label*, weld::MetricSpinButton*> const aWin[4] =
707 { m_xFixedText1.get(), m_xMetricField1.get() },
708 { m_xFixedText2.get(), m_xMetricField2.get() },
709 { m_xFixedText3.get(), m_xMetricField3.get() },
710 { m_xFixedText4.get(), m_xMetricField4.get() }
713 SmCategoryDesc *pCat;
715 // remember the (maybe new) settings of the active SmCategoryDesc
716 // before switching to the new one
717 if (nActiveCategory != CATEGORY_NONE)
719 pCat = Categories[nActiveCategory];
720 pCat->SetValue(0, sal::static_int_cast<sal_uInt16>(m_xMetricField1->get_value(FUNIT_NONE)));
721 pCat->SetValue(1, sal::static_int_cast<sal_uInt16>(m_xMetricField2->get_value(FUNIT_NONE)));
722 pCat->SetValue(2, sal::static_int_cast<sal_uInt16>(m_xMetricField3->get_value(FUNIT_NONE)));
723 pCat->SetValue(3, sal::static_int_cast<sal_uInt16>(m_xMetricField4->get_value(FUNIT_NONE)));
725 if (nActiveCategory == 5)
726 bScaleAllBrackets = m_xCheckBox1->get_active();
728 m_xMenuButton->set_item_active("menuitem" + OString::number(nActiveCategory + 1), false);
731 // activation/deactivation of the associated controls depending on the chosen category
732 bool bActive;
733 for (sal_uInt16 i = 0; i < 4; i++)
735 weld::Label *pFT = aWin[i].first;
736 weld::MetricSpinButton *pMF = aWin[i].second;
738 // To determine which Controls should be active, the existence
739 // of an associated HelpID is checked
740 bActive = aCatMf2Hid[nCategory][i] != nullptr;
742 pFT->show(bActive);
743 pFT->set_sensitive(bActive);
744 pMF->show(bActive);
745 pMF->set_sensitive(bActive);
747 // set measurement unit and number of decimal places
748 FieldUnit eUnit;
749 sal_uInt16 nDigits;
750 if (nCategory < 9)
752 eUnit = FUNIT_PERCENT;
753 nDigits = 0;
755 else
757 eUnit = FUNIT_100TH_MM;
758 nDigits = 2;
760 pMF->set_unit(eUnit); // changes the value
761 pMF->set_digits(nDigits);
763 if (bActive)
765 pCat = Categories[nCategory];
766 pFT->set_label(pCat->GetString(i));
768 pMF->set_range(pCat->GetMinimum(i), pCat->GetMaximum(i), FUNIT_NONE);
769 pMF->set_value(pCat->GetValue(i), FUNIT_NONE);
771 pMF->set_help_id(aCatMf2Hid[nCategory][i]);
774 // activate the CheckBox and the associated MetricField if we're dealing with the brackets menu
775 bActive = nCategory == 5;
776 m_xCheckBox1->set_visible(bActive);
777 m_xCheckBox1->set_sensitive(bActive);
778 if (bActive)
780 m_xCheckBox1->set_active(bScaleAllBrackets);
782 bool bChecked = m_xCheckBox1->get_active();
783 m_xFixedText4->set_sensitive( bChecked );
784 m_xMetricField4->set_sensitive( bChecked );
787 m_xMenuButton->set_item_active("menuitem" + OString::number(nCategory + 1), true);
788 m_xFrame->set_label(Categories[nCategory]->GetName());
790 nActiveCategory = nCategory;
792 m_xMetricField1->grab_focus();
795 SmDistanceDialog::SmDistanceDialog(weld::Window *pParent)
796 : GenericDialogController(pParent, "modules/smath/ui/spacingdialog.ui", "SpacingDialog")
797 , m_xFrame(m_xBuilder->weld_frame("template"))
798 , m_xFixedText1(m_xBuilder->weld_label("label1"))
799 , m_xMetricField1(m_xBuilder->weld_metric_spin_button("spinbutton1", FUNIT_CM))
800 , m_xFixedText2(m_xBuilder->weld_label("label2"))
801 , m_xMetricField2(m_xBuilder->weld_metric_spin_button("spinbutton2", FUNIT_CM))
802 , m_xFixedText3(m_xBuilder->weld_label("label3"))
803 , m_xMetricField3(m_xBuilder->weld_metric_spin_button("spinbutton3", FUNIT_CM))
804 , m_xCheckBox1(m_xBuilder->weld_check_button("checkbutton"))
805 , m_xFixedText4(m_xBuilder->weld_label("label4"))
806 , m_xMetricField4(m_xBuilder->weld_metric_spin_button("spinbutton4", FUNIT_CM))
807 , m_xMenuButton(m_xBuilder->weld_menu_button("category"))
808 , m_xDefaultButton(m_xBuilder->weld_button("default"))
809 , m_xBitmap(m_xBuilder->weld_widget("image"))
810 , m_pCurrentImage(m_xBitmap.get())
812 for (sal_uInt16 i = 0; i < NOCATEGORIES; ++i)
813 Categories[i] = new SmCategoryDesc(*m_xBuilder, i);
814 nActiveCategory = CATEGORY_NONE;
815 bScaleAllBrackets = false;
817 m_xMetricField1->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
818 m_xMetricField2->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
819 m_xMetricField3->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
820 m_xMetricField4->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
821 m_xCheckBox1->connect_toggled(LINK(this, SmDistanceDialog, CheckBoxClickHdl));
822 m_xMenuButton->connect_selected(LINK(this, SmDistanceDialog, MenuSelectHdl));
823 m_xDefaultButton->connect_clicked(LINK(this, SmDistanceDialog, DefaultButtonClickHdl));
825 //set the initial size, with max visible widgets visible, as preferred size
826 m_xDialog->set_size_request(-1, m_xDialog->get_preferred_size().Height());
829 SmDistanceDialog::~SmDistanceDialog()
831 for (SmCategoryDesc* & rpDesc : Categories)
832 DELETEZ(rpDesc);
835 void SmDistanceDialog::ReadFrom(const SmFormat &rFormat)
837 Categories[0]->SetValue(0, rFormat.GetDistance(DIS_HORIZONTAL));
838 Categories[0]->SetValue(1, rFormat.GetDistance(DIS_VERTICAL));
839 Categories[0]->SetValue(2, rFormat.GetDistance(DIS_ROOT));
840 Categories[1]->SetValue(0, rFormat.GetDistance(DIS_SUPERSCRIPT));
841 Categories[1]->SetValue(1, rFormat.GetDistance(DIS_SUBSCRIPT));
842 Categories[2]->SetValue(0, rFormat.GetDistance(DIS_NUMERATOR));
843 Categories[2]->SetValue(1, rFormat.GetDistance(DIS_DENOMINATOR));
844 Categories[3]->SetValue(0, rFormat.GetDistance(DIS_FRACTION));
845 Categories[3]->SetValue(1, rFormat.GetDistance(DIS_STROKEWIDTH));
846 Categories[4]->SetValue(0, rFormat.GetDistance(DIS_UPPERLIMIT));
847 Categories[4]->SetValue(1, rFormat.GetDistance(DIS_LOWERLIMIT));
848 Categories[5]->SetValue(0, rFormat.GetDistance(DIS_BRACKETSIZE));
849 Categories[5]->SetValue(1, rFormat.GetDistance(DIS_BRACKETSPACE));
850 Categories[5]->SetValue(3, rFormat.GetDistance(DIS_NORMALBRACKETSIZE));
851 Categories[6]->SetValue(0, rFormat.GetDistance(DIS_MATRIXROW));
852 Categories[6]->SetValue(1, rFormat.GetDistance(DIS_MATRIXCOL));
853 Categories[7]->SetValue(0, rFormat.GetDistance(DIS_ORNAMENTSIZE));
854 Categories[7]->SetValue(1, rFormat.GetDistance(DIS_ORNAMENTSPACE));
855 Categories[8]->SetValue(0, rFormat.GetDistance(DIS_OPERATORSIZE));
856 Categories[8]->SetValue(1, rFormat.GetDistance(DIS_OPERATORSPACE));
857 Categories[9]->SetValue(0, rFormat.GetDistance(DIS_LEFTSPACE));
858 Categories[9]->SetValue(1, rFormat.GetDistance(DIS_RIGHTSPACE));
859 Categories[9]->SetValue(2, rFormat.GetDistance(DIS_TOPSPACE));
860 Categories[9]->SetValue(3, rFormat.GetDistance(DIS_BOTTOMSPACE));
862 bScaleAllBrackets = rFormat.IsScaleNormalBrackets();
864 // force update (even of category 0) by setting nActiveCategory to a
865 // non-existent category number
866 nActiveCategory = CATEGORY_NONE;
867 SetCategory(0);
871 void SmDistanceDialog::WriteTo(SmFormat &rFormat) /*const*/
873 // TODO can they actually be different?
874 // if that's not the case 'const' could be used above!
875 SetCategory(nActiveCategory);
877 rFormat.SetDistance( DIS_HORIZONTAL, Categories[0]->GetValue(0) );
878 rFormat.SetDistance( DIS_VERTICAL, Categories[0]->GetValue(1) );
879 rFormat.SetDistance( DIS_ROOT, Categories[0]->GetValue(2) );
880 rFormat.SetDistance( DIS_SUPERSCRIPT, Categories[1]->GetValue(0) );
881 rFormat.SetDistance( DIS_SUBSCRIPT, Categories[1]->GetValue(1) );
882 rFormat.SetDistance( DIS_NUMERATOR, Categories[2]->GetValue(0) );
883 rFormat.SetDistance( DIS_DENOMINATOR, Categories[2]->GetValue(1) );
884 rFormat.SetDistance( DIS_FRACTION, Categories[3]->GetValue(0) );
885 rFormat.SetDistance( DIS_STROKEWIDTH, Categories[3]->GetValue(1) );
886 rFormat.SetDistance( DIS_UPPERLIMIT, Categories[4]->GetValue(0) );
887 rFormat.SetDistance( DIS_LOWERLIMIT, Categories[4]->GetValue(1) );
888 rFormat.SetDistance( DIS_BRACKETSIZE, Categories[5]->GetValue(0) );
889 rFormat.SetDistance( DIS_BRACKETSPACE, Categories[5]->GetValue(1) );
890 rFormat.SetDistance( DIS_MATRIXROW, Categories[6]->GetValue(0) );
891 rFormat.SetDistance( DIS_MATRIXCOL, Categories[6]->GetValue(1) );
892 rFormat.SetDistance( DIS_ORNAMENTSIZE, Categories[7]->GetValue(0) );
893 rFormat.SetDistance( DIS_ORNAMENTSPACE, Categories[7]->GetValue(1) );
894 rFormat.SetDistance( DIS_OPERATORSIZE, Categories[8]->GetValue(0) );
895 rFormat.SetDistance( DIS_OPERATORSPACE, Categories[8]->GetValue(1) );
896 rFormat.SetDistance( DIS_LEFTSPACE, Categories[9]->GetValue(0) );
897 rFormat.SetDistance( DIS_RIGHTSPACE, Categories[9]->GetValue(1) );
898 rFormat.SetDistance( DIS_TOPSPACE, Categories[9]->GetValue(2) );
899 rFormat.SetDistance( DIS_BOTTOMSPACE, Categories[9]->GetValue(3) );
900 rFormat.SetDistance( DIS_NORMALBRACKETSIZE, Categories[5]->GetValue(3) );
902 rFormat.SetScaleNormalBrackets( bScaleAllBrackets );
904 rFormat.RequestApplyChanges();
907 IMPL_LINK_NOARG( SmAlignDialog, DefaultButtonClickHdl, weld::Button&, void )
909 SaveDefaultsQuery aQuery(m_xDialog.get());
910 if (aQuery.run() == RET_YES)
912 SmModule *pp = SM_MOD();
913 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
914 WriteTo( aFmt );
915 pp->GetConfig()->SetStandardFormat( aFmt );
919 SmAlignDialog::SmAlignDialog(weld::Window* pParent)
920 : GenericDialogController(pParent, "modules/smath/ui/alignmentdialog.ui", "AlignmentDialog")
921 , m_xLeft(m_xBuilder->weld_radio_button("left"))
922 , m_xCenter(m_xBuilder->weld_radio_button("center"))
923 , m_xRight(m_xBuilder->weld_radio_button("right"))
924 , m_xDefaultButton(m_xBuilder->weld_button("default"))
926 m_xDefaultButton->connect_clicked(LINK(this, SmAlignDialog, DefaultButtonClickHdl));
929 SmAlignDialog::~SmAlignDialog()
933 void SmAlignDialog::ReadFrom(const SmFormat &rFormat)
935 switch (rFormat.GetHorAlign())
937 case SmHorAlign::Left:
938 m_xLeft->set_active(true);
939 break;
940 case SmHorAlign::Center:
941 m_xCenter->set_active(true);
942 break;
943 case SmHorAlign::Right:
944 m_xRight->set_active(true);
945 break;
949 void SmAlignDialog::WriteTo(SmFormat &rFormat) const
951 if (m_xLeft->get_active())
952 rFormat.SetHorAlign(SmHorAlign::Left);
953 else if (m_xRight->get_active())
954 rFormat.SetHorAlign(SmHorAlign::Right);
955 else
956 rFormat.SetHorAlign(SmHorAlign::Center);
958 rFormat.RequestApplyChanges();
961 SmShowSymbolSet::SmShowSymbolSet(weld::ScrolledWindow* pScrolledWindow)
962 : nLen(0)
963 , nRows(0)
964 , nColumns(0)
965 , nXOffset(0)
966 , nYOffset(0)
967 , nSelectSymbol(SYMBOL_NONE)
968 , m_xScrolledWindow(pScrolledWindow)
970 m_xScrolledWindow->set_user_managed_scrolling();
971 m_xScrolledWindow->connect_vadjustment_changed(LINK(this, SmShowSymbolSet, ScrollHdl));
974 Point SmShowSymbolSet::OffsetPoint(const Point &rPoint) const
976 return Point(rPoint.X() + nXOffset, rPoint.Y() + nYOffset);
979 void SmShowSymbolSet::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
981 Size aWinSize(GetOutputSizePixel());
982 if (aWinSize != m_aOldSize)
984 calccols(rRenderContext);
985 m_aOldSize = aWinSize;
988 Color aBackgroundColor;
989 Color aTextColor;
990 lclGetSettingColors(aBackgroundColor, aTextColor);
992 rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
993 rRenderContext.SetTextColor(aTextColor);
995 rRenderContext.Push(PushFlags::MAPMODE);
997 // set MapUnit for which 'nLen' has been calculated
998 rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
1000 sal_uInt16 v = sal::static_int_cast< sal_uInt16 >(m_xScrolledWindow->vadjustment_get_value() * nColumns);
1001 size_t nSymbols = aSymbolSet.size();
1003 Color aTxtColor(rRenderContext.GetTextColor());
1004 for (size_t i = v; i < nSymbols ; i++)
1006 SmSym aSymbol(*aSymbolSet[i]);
1007 vcl::Font aFont(aSymbol.GetFace());
1008 aFont.SetAlignment(ALIGN_TOP);
1010 // taking a FontSize which is a bit smaller (compared to nLen) in order to have a buffer
1011 // (hopefully enough for left and right, too)
1012 aFont.SetFontSize(Size(0, nLen - (nLen / 3)));
1013 rRenderContext.SetFont(aFont);
1014 // keep text color
1015 rRenderContext.SetTextColor(aTxtColor);
1017 int nIV = i - v;
1018 sal_UCS4 cChar = aSymbol.GetCharacter();
1019 OUString aText(&cChar, 1);
1020 Size aSize(rRenderContext.GetTextWidth( aText ), rRenderContext.GetTextHeight());
1022 Point aPoint((nIV % nColumns) * nLen + (nLen - aSize.Width()) / 2,
1023 (nIV / nColumns) * nLen + (nLen - aSize.Height()) / 2);
1025 rRenderContext.DrawText(OffsetPoint(aPoint), aText);
1028 if (nSelectSymbol != SYMBOL_NONE)
1030 Point aPoint(((nSelectSymbol - v) % nColumns) * nLen,
1031 ((nSelectSymbol - v) / nColumns) * nLen);
1033 rRenderContext.Invert(tools::Rectangle(OffsetPoint(aPoint), Size(nLen, nLen)));
1037 rRenderContext.Pop();
1040 void SmShowSymbolSet::MouseButtonDown(const MouseEvent& rMEvt)
1042 GrabFocus();
1044 Size aOutputSize(nColumns * nLen, nRows * nLen);
1045 aOutputSize.AdjustWidth(nXOffset );
1046 aOutputSize.AdjustHeight(nYOffset );
1047 Point aPoint(rMEvt.GetPosPixel());
1048 aPoint.AdjustX( -(nXOffset) );
1049 aPoint.AdjustY( -(nYOffset) );
1051 if (rMEvt.IsLeft() && tools::Rectangle(Point(0, 0), aOutputSize).IsInside(rMEvt.GetPosPixel()))
1053 long nPos = (aPoint.Y() / nLen) * nColumns + (aPoint.X() / nLen) +
1054 m_xScrolledWindow->vadjustment_get_value() * nColumns;
1055 SelectSymbol( sal::static_int_cast< sal_uInt16 >(nPos) );
1057 aSelectHdlLink.Call(*this);
1059 if (rMEvt.GetClicks() > 1)
1060 aDblClickHdlLink.Call(*this);
1064 bool SmShowSymbolSet::KeyInput(const KeyEvent& rKEvt)
1066 sal_uInt16 n = nSelectSymbol;
1068 if (n != SYMBOL_NONE)
1070 switch (rKEvt.GetKeyCode().GetCode())
1072 case KEY_DOWN: n = n + nColumns; break;
1073 case KEY_UP: n = n - nColumns; break;
1074 case KEY_LEFT: n -= 1; break;
1075 case KEY_RIGHT: n += 1; break;
1076 case KEY_HOME: n = 0; break;
1077 case KEY_END: n = static_cast< sal_uInt16 >(aSymbolSet.size() - 1); break;
1078 case KEY_PAGEUP: n -= nColumns * nRows; break;
1079 case KEY_PAGEDOWN: n += nColumns * nRows; break;
1080 default:
1081 return false;
1084 else
1085 n = 0;
1087 if (n >= aSymbolSet.size())
1088 n = nSelectSymbol;
1090 // adjust scrollbar
1091 if ((n < sal::static_int_cast<sal_uInt16>(m_xScrolledWindow->vadjustment_get_value() * nColumns)) ||
1092 (n >= sal::static_int_cast<sal_uInt16>((m_xScrolledWindow->vadjustment_get_value() + nRows) * nColumns)))
1094 m_xScrolledWindow->vadjustment_set_value(n / nColumns);
1095 Invalidate();
1098 SelectSymbol(n);
1099 aSelectHdlLink.Call(*this);
1101 return true;
1104 void SmShowSymbolSet::calccols(vcl::RenderContext& rRenderContext)
1106 // Height of 16pt in pixels (matching 'aOutputSize')
1107 nLen = rRenderContext.LogicToPixel(Size(0, 16), MapMode(MapUnit::MapPoint)).Height();
1109 Size aOutputSize(GetOutputSizePixel());
1111 nColumns = aOutputSize.Width() / nLen;
1112 nRows = aOutputSize.Height() / nLen;
1113 nColumns = std::max<long>(1, nColumns);
1114 nRows = std::max<long>(1, nRows);
1116 nXOffset = (aOutputSize.Width() - (nColumns * nLen)) / 2;
1117 nYOffset = (aOutputSize.Height() - (nRows * nLen)) / 2;
1119 SetScrollBarRange();
1122 void SmShowSymbolSet::SetSymbolSet(const SymbolPtrVec_t& rSymbolSet)
1124 aSymbolSet = rSymbolSet;
1125 Invalidate();
1128 void SmShowSymbolSet::SetScrollBarRange()
1130 const int nLastRow = (aSymbolSet.size() - 1 + nColumns) / nColumns;
1131 m_xScrolledWindow->vadjustment_configure(m_xScrolledWindow->vadjustment_get_value(), 0, nLastRow, 1, nRows - 1, nRows);
1132 Invalidate();
1135 void SmShowSymbolSet::SelectSymbol(sal_uInt16 nSymbol)
1137 int v = m_xScrolledWindow->vadjustment_get_value() * nColumns;
1139 if (nSelectSymbol != SYMBOL_NONE && nColumns)
1141 Point aPoint(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
1142 ((nSelectSymbol - v) / nColumns) * nLen)));
1143 Invalidate(tools::Rectangle(aPoint, Size(nLen, nLen)));
1146 if (nSymbol < aSymbolSet.size())
1147 nSelectSymbol = nSymbol;
1149 if (aSymbolSet.empty())
1150 nSelectSymbol = SYMBOL_NONE;
1152 if (nSelectSymbol != SYMBOL_NONE && nColumns)
1154 Point aPoint(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
1155 ((nSelectSymbol - v) / nColumns) * nLen)));
1156 Invalidate(tools::Rectangle(aPoint, Size(nLen, nLen)));
1159 if (!nColumns)
1160 Invalidate();
1163 IMPL_LINK_NOARG(SmShowSymbolSet, ScrollHdl, weld::ScrolledWindow&, void)
1165 Invalidate();
1168 SmShowSymbol::SmShowSymbol()
1172 void SmShowSymbol::setFontSize(vcl::Font &rFont) const
1174 Size aSize(GetOutputSizePixel());
1175 rFont.SetFontSize(Size(0, aSize.Height() - aSize.Height() / 3));
1178 void SmShowSymbol::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
1180 Color aBackgroundColor;
1181 Color aTextColor;
1182 lclGetSettingColors(aBackgroundColor, aTextColor);
1183 rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
1184 rRenderContext.SetTextColor(aTextColor);
1185 rRenderContext.Erase();
1187 vcl::Font aFont(GetFont());
1188 setFontSize(aFont);
1189 rRenderContext.SetFont(aFont);
1191 const OUString &rText = GetText();
1192 Size aTextSize(rRenderContext.GetTextWidth(rText), rRenderContext.GetTextHeight());
1194 rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
1195 (rRenderContext.GetOutputSize().Height() * 7 / 10)), rText);
1198 void SmShowSymbol::MouseButtonDown(const MouseEvent& rMEvt)
1200 if (rMEvt.GetClicks() > 1)
1201 aDblClickHdlLink.Call(*this);
1204 void SmShowSymbol::SetSymbol(const SmSym *pSymbol)
1206 if (pSymbol)
1208 vcl::Font aFont(pSymbol->GetFace());
1209 aFont.SetAlignment(ALIGN_BASELINE);
1210 SetFont(aFont);
1212 sal_UCS4 cChar = pSymbol->GetCharacter();
1213 OUString aText(&cChar, 1);
1214 SetText( aText );
1217 Invalidate();
1220 void SmSymbolDialog::FillSymbolSets()
1221 // populate the entries of possible SymbolsSets in the dialog with
1222 // current values of the SymbolSet manager but selects none of those
1224 m_xSymbolSets->clear();
1225 m_xSymbolSets->set_active(-1);
1227 std::set< OUString > aSybolSetNames( rSymbolMgr.GetSymbolSetNames() );
1228 std::set< OUString >::const_iterator aIt( aSybolSetNames.begin() );
1229 for ( ; aIt != aSybolSetNames.end(); ++aIt)
1230 m_xSymbolSets->append_text(*aIt);
1233 IMPL_LINK_NOARG( SmSymbolDialog, SymbolSetChangeHdl, weld::ComboBoxText&, void )
1235 SelectSymbolSet(m_xSymbolSets->get_active_text());
1238 IMPL_LINK_NOARG( SmSymbolDialog, SymbolChangeHdl, SmShowSymbolSet&, void )
1240 SelectSymbol(m_xSymbolSetDisplay->GetSelectSymbol());
1243 IMPL_LINK_NOARG(SmSymbolDialog, EditClickHdl, weld::Button&, void)
1245 SmSymDefineDialog aDialog(m_xDialog.get(), pFontListDev, rSymbolMgr);
1247 // set current symbol and SymbolSet for the new dialog
1248 const OUString aSymSetName (m_xSymbolSets->get_active_text()),
1249 aSymName (m_xSymbolName->get_label());
1250 aDialog.SelectOldSymbolSet(aSymSetName);
1251 aDialog.SelectOldSymbol(aSymName);
1252 aDialog.SelectSymbolSet(aSymSetName);
1253 aDialog.SelectSymbol(aSymName);
1255 // remember old SymbolSet
1256 OUString aOldSymbolSet (m_xSymbolSets->get_active_text());
1258 sal_uInt16 nSymPos = m_xSymbolSetDisplay->GetSelectSymbol();
1260 // adapt dialog to data of the SymbolSet manager, which might have changed
1261 if (aDialog.execute() == RET_OK && rSymbolMgr.IsModified())
1263 rSymbolMgr.Save();
1264 FillSymbolSets();
1267 // if the old SymbolSet doesn't exist anymore, go to the first one SymbolSet (if one exists)
1268 if (!SelectSymbolSet(aOldSymbolSet) && m_xSymbolSets->get_count() > 0)
1269 SelectSymbolSet(m_xSymbolSets->get_text(0));
1270 else
1272 // just update display of current symbol set
1273 assert(aSymSetName == aSymSetName); //unexpected change in symbol set name
1274 aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
1275 m_xSymbolSetDisplay->SetSymbolSet( aSymbolSet );
1278 if (nSymPos >= aSymbolSet.size())
1279 nSymPos = static_cast< sal_uInt16 >(aSymbolSet.size()) - 1;
1280 SelectSymbol( nSymPos );
1283 IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl2, SmShowSymbolSet&, void )
1285 SymbolDblClickHdl();
1288 IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl, SmShowSymbol&, void )
1290 SymbolDblClickHdl();
1293 void SmSymbolDialog::SymbolDblClickHdl()
1295 GetClickHdl(*m_xGetBtn);
1296 m_xDialog->response(RET_OK);
1299 IMPL_LINK_NOARG(SmSymbolDialog, GetClickHdl, weld::Button&, void)
1301 const SmSym *pSym = GetSymbol();
1302 if (pSym)
1304 OUString aText = "%" + pSym->GetName() + " ";
1306 rViewSh.GetViewFrame()->GetDispatcher()->ExecuteList(
1307 SID_INSERTSPECIAL, SfxCallMode::RECORD,
1308 { new SfxStringItem(SID_INSERTSPECIAL, aText) });
1312 SmSymbolDialog::SmSymbolDialog(weld::Window *pParent, OutputDevice *pFntListDevice,
1313 SmSymbolManager &rMgr, SmViewShell &rViewShell)
1314 : GenericDialogController(pParent, "modules/smath/ui/catalogdialog.ui", "CatalogDialog")
1315 , rViewSh(rViewShell)
1316 , rSymbolMgr(rMgr)
1317 , pFontListDev(pFntListDevice)
1318 , m_xSymbolSets(m_xBuilder->weld_combo_box_text("symbolset"))
1319 , m_xSymbolSetDisplay(new SmShowSymbolSet(m_xBuilder->weld_scrolled_window("scrolledwindow")))
1320 , m_xSymbolSetDisplayArea(new weld::CustomWeld(*m_xBuilder, "symbolsetdisplay", *m_xSymbolSetDisplay))
1321 , m_xSymbolName(m_xBuilder->weld_label("symbolname"))
1322 , m_xSymbolDisplay(new weld::CustomWeld(*m_xBuilder, "preview", m_aSymbolDisplay))
1323 , m_xGetBtn(m_xBuilder->weld_button("ok"))
1324 , m_xEditBtn(m_xBuilder->weld_button("edit"))
1326 m_xSymbolSets->make_sorted();
1328 aSymbolSetName.clear();
1329 aSymbolSet.clear();
1330 FillSymbolSets();
1331 if (m_xSymbolSets->get_count() > 0)
1332 SelectSymbolSet(m_xSymbolSets->get_text(0));
1334 m_xSymbolSets->connect_changed(LINK(this, SmSymbolDialog, SymbolSetChangeHdl));
1335 m_xSymbolSetDisplay->SetSelectHdl(LINK(this, SmSymbolDialog, SymbolChangeHdl));
1336 m_xSymbolSetDisplay->SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl2));
1337 m_aSymbolDisplay.SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl));
1338 m_xEditBtn->connect_clicked(LINK(this, SmSymbolDialog, EditClickHdl));
1339 m_xGetBtn->connect_clicked(LINK(this, SmSymbolDialog, GetClickHdl));
1342 SmSymbolDialog::~SmSymbolDialog()
1346 bool SmSymbolDialog::SelectSymbolSet(const OUString &rSymbolSetName)
1348 bool bRet = false;
1349 sal_Int32 nPos = m_xSymbolSets->find_text(rSymbolSetName);
1351 aSymbolSetName.clear();
1352 aSymbolSet.clear();
1353 if (nPos != -1)
1355 m_xSymbolSets->set_active(nPos);
1357 aSymbolSetName = rSymbolSetName;
1358 aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
1360 // sort symbols by Unicode position (useful for displaying Greek characters alphabetically)
1361 std::sort( aSymbolSet.begin(), aSymbolSet.end(),
1362 [](const SmSym *pSym1, const SmSym *pSym2)
1364 return pSym1->GetCharacter() < pSym2->GetCharacter();
1365 } );
1367 m_xSymbolSetDisplay->SetSymbolSet( aSymbolSet );
1368 if (!aSymbolSet.empty())
1369 SelectSymbol(0);
1371 bRet = true;
1373 else
1374 m_xSymbolSets->set_active(-1);
1376 return bRet;
1379 void SmSymbolDialog::SelectSymbol(sal_uInt16 nSymbolNo)
1381 const SmSym *pSym = nullptr;
1382 if (!aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size()))
1383 pSym = aSymbolSet[ nSymbolNo ];
1385 m_xSymbolSetDisplay->SelectSymbol(nSymbolNo);
1386 m_aSymbolDisplay.SetSymbol(pSym);
1387 m_xSymbolName->set_label(pSym ? pSym->GetName() : OUString());
1390 const SmSym* SmSymbolDialog::GetSymbol() const
1392 sal_uInt16 nSymbolNo = m_xSymbolSetDisplay->GetSelectSymbol();
1393 bool bValid = !aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size());
1394 return bValid ? aSymbolSet[ nSymbolNo ] : nullptr;
1397 void SmShowChar::Resize()
1399 const OUString &rText = GetText();
1400 if (rText.isEmpty())
1401 return;
1402 sal_Int32 nStrIndex = 0;
1403 sal_UCS4 cChar = rText.iterateCodePoints(&nStrIndex);
1404 SetSymbol(cChar, GetFont()); //force recalculation of size
1407 void SmShowChar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
1409 Color aTextCol = rRenderContext.GetTextColor();
1410 Color aFillCol = rRenderContext.GetFillColor();
1412 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1413 const Color aWindowTextColor(rStyleSettings.GetDialogTextColor());
1414 const Color aWindowColor(rStyleSettings.GetWindowColor());
1415 rRenderContext.SetTextColor(aWindowTextColor);
1416 rRenderContext.SetFillColor(aWindowColor);
1418 Size aSize(GetOutputSizePixel());
1419 rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aSize));
1421 OUString aText(GetText());
1422 if (!aText.isEmpty())
1424 vcl::Font aFont(m_aFont);
1425 aFont.SetAlignment(ALIGN_TOP);
1426 rRenderContext.SetFont(aFont);
1428 Size aTextSize(rRenderContext.GetTextWidth(aText), rRenderContext.GetTextHeight());
1430 rRenderContext.DrawText(Point((aSize.Width() - aTextSize.Width()) / 2,
1431 (aSize.Height() - aTextSize.Height()) / 2), aText);
1434 rRenderContext.SetTextColor(aTextCol);
1435 rRenderContext.SetFillColor(aFillCol);
1438 void SmShowChar::SetSymbol( const SmSym *pSym )
1440 if (pSym)
1441 SetSymbol( pSym->GetCharacter(), pSym->GetFace() );
1445 void SmShowChar::SetSymbol( sal_UCS4 cChar, const vcl::Font &rFont )
1447 vcl::Font aFont( rFont );
1448 Size aSize(GetOutputSizePixel());
1449 aFont.SetFontSize(Size(0, aSize.Height() - aSize.Height() / 3));
1450 aFont.SetAlignment(ALIGN_BASELINE);
1451 SetFont(aFont);
1453 OUString aText(&cChar, 1);
1454 SetText( aText );
1456 Invalidate();
1459 void SmSymDefineDialog::FillSymbols(weld::ComboBoxText& rComboBox, bool bDeleteText)
1461 assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong ComboBox");
1463 rComboBox.clear();
1464 if (bDeleteText)
1465 rComboBox.set_entry_text(OUString());
1467 weld::ComboBoxText& rBox = &rComboBox == m_xOldSymbols.get() ? *m_xOldSymbolSets : *m_xSymbolSets;
1468 SymbolPtrVec_t aSymSet(m_aSymbolMgrCopy.GetSymbolSet(rBox.get_active_text()));
1469 for (const SmSym* i : aSymSet)
1470 rComboBox.append_text(i->GetName());
1473 void SmSymDefineDialog::FillSymbolSets(weld::ComboBoxText& rComboBox, bool bDeleteText)
1475 assert((&rComboBox == m_xOldSymbolSets.get() || &rComboBox == m_xSymbolSets.get()) && "Sm : wrong ComboBox");
1477 rComboBox.clear();
1478 if (bDeleteText)
1479 rComboBox.set_entry_text(OUString());
1481 const std::set< OUString > aSymbolSetNames( m_aSymbolMgrCopy.GetSymbolSetNames() );
1482 std::set< OUString >::const_iterator aIt( aSymbolSetNames.begin() );
1483 for ( ; aIt != aSymbolSetNames.end(); ++aIt)
1484 rComboBox.append_text(*aIt);
1487 void SmSymDefineDialog::FillFonts()
1489 m_xFonts->clear();
1490 m_xFonts->set_active(-1);
1492 // Include all fonts of FontList into the font list.
1493 // If there are duplicates, only include one entry of each font since the style will be
1494 // already selected using the FontStyleBox.
1495 if (m_xFontList)
1497 sal_uInt16 nCount = m_xFontList->GetFontNameCount();
1498 for (sal_uInt16 i = 0; i < nCount; ++i)
1499 m_xFonts->append_text(m_xFontList->GetFontName(i).GetFamilyName());
1503 void SmSymDefineDialog::FillStyles()
1505 m_xStyles->clear();
1506 // pStyles->SetText(OUString());
1508 OUString aText(m_xFonts->get_active_text());
1509 if (!aText.isEmpty())
1511 // use own StyleNames
1512 const SmFontStyles &rStyles = GetFontStyles();
1513 for (sal_uInt16 i = 0; i < SmFontStyles::GetCount(); ++i)
1514 m_xStyles->append_text(rStyles.GetStyleName(i));
1516 assert(m_xStyles->get_count() > 0 && "Sm : no styles available");
1517 m_xStyles->set_active(0);
1521 SmSym* SmSymDefineDialog::GetSymbol(const weld::ComboBoxText& rComboBox)
1523 assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong combobox");
1524 return m_aSymbolMgrCopy.GetSymbolByName(rComboBox.get_active_text());
1527 IMPL_LINK(SmSymDefineDialog, OldSymbolChangeHdl, weld::ComboBoxText&, rComboBox, void)
1529 (void) rComboBox;
1530 assert(&rComboBox == m_xOldSymbols.get() && "Sm : wrong argument");
1531 SelectSymbol(*m_xOldSymbols, m_xOldSymbols->get_active_text(), false);
1534 IMPL_LINK( SmSymDefineDialog, OldSymbolSetChangeHdl, weld::ComboBoxText&, rComboBox, void )
1536 (void) rComboBox;
1537 assert(&rComboBox == m_xOldSymbolSets.get() && "Sm : wrong argument");
1538 SelectSymbolSet(*m_xOldSymbolSets, m_xOldSymbolSets->get_active_text(), false);
1541 IMPL_LINK(SmSymDefineDialog, ModifyHdl, weld::ComboBoxText&, rComboBox, void)
1543 // remember cursor position for later restoring of it
1544 int nStartPos, nEndPos;
1545 rComboBox.get_entry_selection_bounds(nStartPos, nEndPos);
1547 if (&rComboBox == m_xSymbols.get())
1548 SelectSymbol(*m_xSymbols, m_xSymbols->get_active_text(), false);
1549 else if (&rComboBox == m_xSymbolSets.get())
1550 SelectSymbolSet(*m_xSymbolSets, m_xSymbolSets->get_active_text(), false);
1551 else if (&rComboBox == m_xOldSymbols.get())
1552 // allow only names from the list
1553 SelectSymbol(*m_xOldSymbols, m_xOldSymbols->get_active_text(), true);
1554 else if (&rComboBox == m_xOldSymbolSets.get())
1555 // allow only names from the list
1556 SelectSymbolSet(*m_xOldSymbolSets, m_xOldSymbolSets->get_active_text(), true);
1557 else if (&rComboBox == m_xStyles.get())
1558 // allow only names from the list (that's the case here anyway)
1559 SelectStyle(m_xStyles->get_active_text(), true);
1560 else
1561 SAL_WARN("starmath", "wrong combobox argument");
1563 rComboBox.select_entry_region(nStartPos, nEndPos);
1565 UpdateButtons();
1568 IMPL_LINK(SmSymDefineDialog, FontChangeHdl, weld::ComboBoxText&, rListBox, void)
1570 (void) rListBox;
1571 assert(&rListBox == m_xFonts.get() && "Sm : wrong argument");
1573 SelectFont(m_xFonts->get_active_text());
1576 IMPL_LINK_NOARG(SmSymDefineDialog, SubsetChangeHdl, weld::ComboBoxText&, void)
1578 int nPos = m_xFontsSubsetLB->get_active();
1579 if (nPos != -1)
1581 const Subset* pSubset = reinterpret_cast<const Subset*>(m_xFontsSubsetLB->get_active_id().toUInt64());
1582 if (pSubset)
1584 m_xCharsetDisplay->SelectCharacter( pSubset->GetRangeMin() );
1589 IMPL_LINK( SmSymDefineDialog, StyleChangeHdl, weld::ComboBoxText&, rComboBox, void )
1591 (void) rComboBox;
1592 assert(&rComboBox == m_xStyles.get() && "Sm : wrong argument");
1594 SelectStyle(m_xStyles->get_active_text());
1597 IMPL_LINK_NOARG(SmSymDefineDialog, CharHighlightHdl, SvxShowCharSet*, void)
1599 sal_UCS4 cChar = m_xCharsetDisplay->GetSelectCharacter();
1601 if (m_xSubsetMap)
1603 const Subset* pSubset = m_xSubsetMap->GetSubsetByUnicode(cChar);
1604 if (pSubset)
1605 m_xFontsSubsetLB->set_active_text(pSubset->GetName());
1606 else
1607 m_xFontsSubsetLB->set_active(-1);
1610 m_aSymbolDisplay.SetSymbol(cChar, m_xCharsetDisplay->GetFont());
1612 UpdateButtons();
1614 // display Unicode position as symbol name while iterating over characters
1615 const OUString aHex(OUString::number(cChar, 16 ).toAsciiUpperCase());
1616 const OUString aPattern( (aHex.getLength() > 4) ? OUString("Ux000000") : OUString("Ux0000") );
1617 OUString aUnicodePos( aPattern.copy( 0, aPattern.getLength() - aHex.getLength() ) );
1618 aUnicodePos += aHex;
1619 m_xSymbols->set_entry_text(aUnicodePos);
1620 m_xSymbolName->set_label(aUnicodePos);
1623 IMPL_LINK( SmSymDefineDialog, AddClickHdl, weld::Button&, rButton, void )
1625 (void) rButton;
1626 assert(&rButton == m_xAddBtn.get() && "Sm : wrong argument");
1627 assert(rButton.get_sensitive() && "Sm : requirements met ??");
1629 // add symbol
1630 const SmSym aNewSymbol(m_xSymbols->get_active_text(), m_xCharsetDisplay->GetFont(),
1631 m_xCharsetDisplay->GetSelectCharacter(), m_xSymbolSets->get_active_text());
1632 //OSL_ENSURE( m_aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == NULL, "symbol already exists" );
1633 m_aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol );
1635 // update display of new symbol
1636 m_aSymbolDisplay.SetSymbol( &aNewSymbol );
1637 m_xSymbolName->set_label(aNewSymbol.GetName());
1638 m_xSymbolSetName->set_label(aNewSymbol.GetSymbolSetName());
1640 // update list box entries
1641 FillSymbolSets(*m_xOldSymbolSets, false);
1642 FillSymbolSets(*m_xSymbolSets, false);
1643 FillSymbols(*m_xOldSymbols, false);
1644 FillSymbols(*m_xSymbols, false);
1646 UpdateButtons();
1649 IMPL_LINK( SmSymDefineDialog, ChangeClickHdl, weld::Button&, rButton, void )
1651 (void) rButton;
1652 assert(&rButton == m_xChangeBtn.get() && "Sm : wrong argument");
1653 assert(m_xChangeBtn->get_sensitive() && "Sm : requirements met ??");
1655 // get new Sybol to use
1656 //! get font from symbol-disp lay since charset-display does not keep
1657 //! the bold attribute.
1658 const SmSym aNewSymbol(m_xSymbols->get_active_text(), m_xCharsetDisplay->GetFont(),
1659 m_xCharsetDisplay->GetSelectCharacter(), m_xSymbolSets->get_active_text());
1661 // remove old symbol if the name was changed then add new one
1662 const bool bNameChanged = m_xOldSymbols->get_active_text() != m_xSymbols->get_active_text();
1663 if (bNameChanged)
1664 m_aSymbolMgrCopy.RemoveSymbol(m_xOldSymbols->get_active_text());
1665 m_aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol, true );
1667 // clear display for original symbol if necessary
1668 if (bNameChanged)
1669 SetOrigSymbol(nullptr, OUString());
1671 // update display of new symbol
1672 m_aSymbolDisplay.SetSymbol(&aNewSymbol);
1673 m_xSymbolName->set_label(aNewSymbol.GetName());
1674 m_xSymbolSetName->set_label(aNewSymbol.GetSymbolSetName());
1676 // update list box entries
1677 FillSymbolSets(*m_xOldSymbolSets, false);
1678 FillSymbolSets(*m_xSymbolSets, false);
1679 FillSymbols(*m_xOldSymbols, false);
1680 FillSymbols(*m_xSymbols, false);
1682 UpdateButtons();
1685 IMPL_LINK(SmSymDefineDialog, DeleteClickHdl, weld::Button&, rButton, void)
1687 (void) rButton;
1688 assert(&rButton == m_xDeleteBtn.get() && "Sm : wrong argument");
1689 assert(m_xDeleteBtn->get_sensitive() && "Sm : requirements met ??");
1691 if (m_xOrigSymbol)
1693 m_aSymbolMgrCopy.RemoveSymbol(m_xOrigSymbol->GetName());
1695 // clear display for original symbol
1696 SetOrigSymbol(nullptr, OUString());
1698 // update list box entries
1699 FillSymbolSets(*m_xOldSymbolSets, false);
1700 FillSymbolSets(*m_xSymbolSets, false);
1701 FillSymbols(*m_xOldSymbols ,false);
1702 FillSymbols(*m_xSymbols ,false);
1705 UpdateButtons();
1708 void SmSymDefineDialog::UpdateButtons()
1710 bool bAdd = false,
1711 bChange = false,
1712 bDelete = false;
1713 OUString aTmpSymbolName(m_xSymbols->get_active_text()),
1714 aTmpSymbolSetName(m_xSymbolSets->get_active_text());
1716 if (!aTmpSymbolName.isEmpty() && !aTmpSymbolSetName.isEmpty())
1718 // are all settings equal?
1719 //! (Font-, Style- and SymbolSet name comparison is not case sensitive)
1720 bool bEqual = m_xOrigSymbol
1721 && aTmpSymbolSetName.equalsIgnoreAsciiCase(m_xOldSymbolSetName->get_label())
1722 && aTmpSymbolName == m_xOrigSymbol->GetName()
1723 && m_xFonts->get_active_text().equalsIgnoreAsciiCase(
1724 m_xOrigSymbol->GetFace().GetFamilyName())
1725 && m_xStyles->get_active_text().equalsIgnoreAsciiCase(
1726 GetFontStyles().GetStyleName(m_xOrigSymbol->GetFace()))
1727 && m_xCharsetDisplay->GetSelectCharacter() == m_xOrigSymbol->GetCharacter();
1729 // only add it if there isn't already a symbol with the same name
1730 bAdd = m_aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == nullptr;
1732 // only delete it if all settings are equal
1733 bDelete = bool(m_xOrigSymbol);
1735 // only change it if the old symbol exists and the new one is different
1736 bChange = m_xOrigSymbol && !bEqual;
1739 m_xAddBtn->set_sensitive(bAdd);
1740 m_xChangeBtn->set_sensitive(bChange);
1741 m_xDeleteBtn->set_sensitive(bDelete);
1744 SmSymDefineDialog::SmSymDefineDialog(weld::Window* pParent, OutputDevice *pFntListDevice, SmSymbolManager &rMgr)
1745 : GenericDialogController(pParent, "modules/smath/ui/symdefinedialog.ui", "EditSymbols")
1746 , m_xVirDev(VclPtr<VirtualDevice>::Create())
1747 , m_rSymbolMgr(rMgr)
1748 , m_xFontList(new FontList(pFntListDevice))
1749 , m_xOldSymbols(m_xBuilder->weld_combo_box_text("oldSymbols"))
1750 , m_xOldSymbolSets(m_xBuilder->weld_combo_box_text("oldSymbolSets"))
1751 , m_xSymbols(m_xBuilder->weld_combo_box_text("symbols"))
1752 , m_xSymbolSets(m_xBuilder->weld_combo_box_text("symbolSets"))
1753 , m_xFonts(m_xBuilder->weld_combo_box_text("fonts"))
1754 , m_xFontsSubsetLB(m_xBuilder->weld_combo_box_text("fontsSubsetLB"))
1755 , m_xStyles(m_xBuilder->weld_combo_box_text("styles"))
1756 , m_xOldSymbolName(m_xBuilder->weld_label("oldSymbolName"))
1757 , m_xOldSymbolSetName(m_xBuilder->weld_label("oldSymbolSetName"))
1758 , m_xSymbolName(m_xBuilder->weld_label("symbolName"))
1759 , m_xSymbolSetName(m_xBuilder->weld_label("symbolSetName"))
1760 , m_xAddBtn(m_xBuilder->weld_button("add"))
1761 , m_xChangeBtn(m_xBuilder->weld_button("modify"))
1762 , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
1763 , m_xOldSymbolDisplay(new weld::CustomWeld(*m_xBuilder, "oldSymbolDisplay", m_aOldSymbolDisplay))
1764 , m_xSymbolDisplay(new weld::CustomWeld(*m_xBuilder, "symbolDisplay", m_aSymbolDisplay))
1765 , m_xCharsetDisplay(new SvxShowCharSet(m_xBuilder->weld_scrolled_window("showscroll"), m_xVirDev))
1766 , m_xCharsetDisplayArea(new weld::CustomWeld(*m_xBuilder, "charsetDisplay", *m_xCharsetDisplay))
1768 // auto completion is troublesome since that symbols character also gets automatically selected in the
1769 // display and if the user previously selected a character to define/redefine that one this is bad
1770 m_xOldSymbols->set_entry_completion(false);
1771 m_xSymbols->set_entry_completion(false);
1773 FillFonts();
1774 if (m_xFonts->get_count() > 0)
1775 SelectFont(m_xFonts->get_text(0));
1777 SetSymbolSetManager(m_rSymbolMgr);
1779 m_xOldSymbols->connect_changed(LINK(this, SmSymDefineDialog, OldSymbolChangeHdl));
1780 m_xOldSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, OldSymbolSetChangeHdl));
1781 m_xSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1782 m_xOldSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1783 m_xSymbols->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1784 m_xOldSymbols->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1785 m_xStyles->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1786 m_xFonts->connect_changed(LINK(this, SmSymDefineDialog, FontChangeHdl));
1787 m_xFontsSubsetLB->connect_changed(LINK(this, SmSymDefineDialog, SubsetChangeHdl));
1788 m_xStyles->connect_changed(LINK(this, SmSymDefineDialog, StyleChangeHdl));
1789 m_xAddBtn->connect_clicked(LINK(this, SmSymDefineDialog, AddClickHdl));
1790 m_xChangeBtn->connect_clicked(LINK(this, SmSymDefineDialog, ChangeClickHdl));
1791 m_xDeleteBtn->connect_clicked(LINK(this, SmSymDefineDialog, DeleteClickHdl));
1792 m_xCharsetDisplay->SetHighlightHdl( LINK( this, SmSymDefineDialog, CharHighlightHdl ) );
1795 SmSymDefineDialog::~SmSymDefineDialog()
1799 short SmSymDefineDialog::execute()
1801 short nResult = m_xDialog->run();
1803 // apply changes if dialog was closed by clicking OK
1804 if (m_aSymbolMgrCopy.IsModified() && nResult == RET_OK)
1805 m_rSymbolMgr = m_aSymbolMgrCopy;
1807 return nResult;
1810 void SmSymDefineDialog::SetSymbolSetManager(const SmSymbolManager &rMgr)
1812 m_aSymbolMgrCopy = rMgr;
1814 // Set the modified flag of the copy to false so that
1815 // we can check later on if anything has been changed
1816 m_aSymbolMgrCopy.SetModified(false);
1818 FillSymbolSets(*m_xOldSymbolSets);
1819 if (m_xOldSymbolSets->get_count() > 0)
1820 SelectSymbolSet(m_xOldSymbolSets->get_text(0));
1821 FillSymbolSets(*m_xSymbolSets);
1822 if (m_xSymbolSets->get_count() > 0)
1823 SelectSymbolSet(m_xSymbolSets->get_text(0));
1824 FillSymbols(*m_xOldSymbols);
1825 if (m_xOldSymbols->get_count() > 0)
1826 SelectSymbol(m_xOldSymbols->get_text(0));
1827 FillSymbols(*m_xSymbols);
1828 if (m_xSymbols->get_count() > 0)
1829 SelectSymbol(m_xSymbols->get_text(0));
1831 UpdateButtons();
1834 bool SmSymDefineDialog::SelectSymbolSet(weld::ComboBoxText& rComboBox,
1835 const OUString &rSymbolSetName, bool bDeleteText)
1837 assert((&rComboBox == m_xOldSymbolSets.get() || &rComboBox == m_xSymbolSets.get()) && "Sm : wrong ComboBox");
1839 // trim SymbolName (no leading and trailing blanks)
1840 OUString aNormName (rSymbolSetName);
1841 aNormName = comphelper::string::stripStart(aNormName, ' ');
1842 aNormName = comphelper::string::stripEnd(aNormName, ' ');
1843 // and remove possible deviations within the input
1844 rComboBox.set_entry_text(aNormName);
1846 bool bRet = false;
1847 int nPos = rComboBox.find_text(aNormName);
1849 if (nPos != -1)
1851 rComboBox.set_active(nPos);
1852 bRet = true;
1854 else if (bDeleteText)
1855 rComboBox.set_entry_text(OUString());
1857 bool bIsOld = &rComboBox == m_xOldSymbolSets.get();
1859 // setting the SymbolSet name at the associated display
1860 weld::Label& rFT = bIsOld ? *m_xOldSymbolSetName : *m_xSymbolSetName;
1861 rFT.set_label(rComboBox.get_active_text());
1863 // set the symbol name which belongs to the SymbolSet at the associated combobox
1864 weld::ComboBoxText& rCB = bIsOld ? *m_xOldSymbols : *m_xSymbols;
1865 FillSymbols(rCB, false);
1867 // display a valid respectively no symbol when changing the SymbolSets
1868 if (bIsOld)
1870 OUString aTmpOldSymbolName;
1871 if (m_xOldSymbols->get_count() > 0)
1872 aTmpOldSymbolName = m_xOldSymbols->get_text(0);
1873 SelectSymbol(*m_xOldSymbols, aTmpOldSymbolName, true);
1876 UpdateButtons();
1878 return bRet;
1881 void SmSymDefineDialog::SetOrigSymbol(const SmSym *pSymbol,
1882 const OUString &rSymbolSetName)
1884 // clear old symbol
1885 m_xOrigSymbol.reset();
1887 OUString aSymName,
1888 aSymSetName;
1889 if (pSymbol)
1891 // set new symbol
1892 m_xOrigSymbol.reset(new SmSym(*pSymbol));
1894 aSymName = pSymbol->GetName();
1895 aSymSetName = rSymbolSetName;
1896 m_aOldSymbolDisplay.SetSymbol( pSymbol );
1898 else
1899 { // delete displayed symbols
1900 m_aOldSymbolDisplay.SetText(OUString());
1901 m_aOldSymbolDisplay.Invalidate();
1903 m_xOldSymbolName->set_label(aSymName);
1904 m_xOldSymbolSetName->set_label(aSymSetName);
1908 bool SmSymDefineDialog::SelectSymbol(weld::ComboBoxText& rComboBox,
1909 const OUString &rSymbolName, bool bDeleteText)
1911 assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong ComboBox");
1913 // trim SymbolName (no blanks)
1914 OUString aNormName = rSymbolName.replaceAll(" ", "");
1915 // and remove possible deviations within the input
1916 rComboBox.set_entry_text(aNormName);
1918 bool bRet = false;
1919 int nPos = rComboBox.find_text(aNormName);
1921 bool bIsOld = &rComboBox == m_xOldSymbols.get();
1923 if (nPos != -1)
1925 rComboBox.set_active(nPos);
1927 if (!bIsOld)
1929 const SmSym *pSymbol = GetSymbol(*m_xSymbols);
1930 if (pSymbol)
1932 // choose font and style accordingly
1933 const vcl::Font &rFont = pSymbol->GetFace();
1934 SelectFont(rFont.GetFamilyName(), false);
1935 SelectStyle(GetFontStyles().GetStyleName(rFont), false);
1937 // Since setting the Font via the Style name of the SymbolFonts doesn't
1938 // work really well (e.g. it can be empty even though the font itself is
1939 // bold or italic) we're manually setting the Font with respect to the Symbol
1940 m_xCharsetDisplay->SetFont(rFont);
1941 m_aSymbolDisplay.SetFont(rFont);
1943 // select associated character
1944 SelectChar(pSymbol->GetCharacter());
1946 // since SelectChar will also set the unicode point as text in the
1947 // symbols box, we have to set the symbol name again to get that one displayed
1948 m_xSymbols->set_entry_text(pSymbol->GetName());
1952 bRet = true;
1954 else if (bDeleteText)
1955 rComboBox.set_entry_text(OUString());
1957 if (bIsOld)
1959 // if there's a change of the old symbol, show only the available ones, otherwise show none
1960 const SmSym *pOldSymbol = nullptr;
1961 OUString aTmpOldSymbolSetName;
1962 if (nPos != COMBOBOX_ENTRY_NOTFOUND)
1964 pOldSymbol = m_aSymbolMgrCopy.GetSymbolByName(aNormName);
1965 aTmpOldSymbolSetName = m_xOldSymbolSets->get_active_text();
1967 SetOrigSymbol(pOldSymbol, aTmpOldSymbolSetName);
1969 else
1970 m_xSymbolName->set_label(rComboBox.get_active_text());
1972 UpdateButtons();
1974 return bRet;
1978 void SmSymDefineDialog::SetFont(const OUString &rFontName, const OUString &rStyleName)
1980 // get Font (FontInfo) matching name and style
1981 FontMetric aFontMetric;
1982 if (m_xFontList)
1983 aFontMetric = m_xFontList->Get(rFontName, WEIGHT_NORMAL, ITALIC_NONE);
1984 SetFontStyle(rStyleName, aFontMetric);
1986 m_xCharsetDisplay->SetFont(aFontMetric);
1987 m_aSymbolDisplay.SetFont(aFontMetric);
1989 // update subset listbox for new font's unicode subsets
1990 FontCharMapRef xFontCharMap = m_xCharsetDisplay->GetFontCharMap();
1991 m_xSubsetMap.reset(new SubsetMap( xFontCharMap ));
1993 m_xFontsSubsetLB->clear();
1994 bool bFirst = true;
1995 for (auto & subset : m_xSubsetMap->GetSubsetMap())
1997 m_xFontsSubsetLB->append(OUString::number(reinterpret_cast<sal_uInt64>(&subset)), subset.GetName());
1998 // subset must live at least as long as the selected font !!!
1999 if (bFirst)
2000 m_xFontsSubsetLB->set_active(0);
2001 bFirst = false;
2003 if (bFirst)
2004 m_xFontsSubsetLB->set_active(-1);
2005 m_xFontsSubsetLB->set_sensitive(!bFirst);
2008 bool SmSymDefineDialog::SelectFont(const OUString &rFontName, bool bApplyFont)
2010 bool bRet = false;
2011 int nPos = m_xFonts->find_text(rFontName);
2013 if (nPos != -1)
2015 m_xFonts->set_active(nPos);
2016 if (m_xStyles->get_count() > 0)
2017 SelectStyle(m_xStyles->get_text(0));
2018 if (bApplyFont)
2020 SetFont(m_xFonts->get_active_text(), m_xStyles->get_active_text());
2021 m_aSymbolDisplay.SetSymbol(m_xCharsetDisplay->GetSelectCharacter(), m_xCharsetDisplay->GetFont());
2023 bRet = true;
2025 else
2026 m_xFonts->set_active(-1);
2027 FillStyles();
2029 UpdateButtons();
2031 return bRet;
2035 bool SmSymDefineDialog::SelectStyle(const OUString &rStyleName, bool bApplyFont)
2037 bool bRet = false;
2038 int nPos = m_xStyles->find_text(rStyleName);
2040 // if the style is not available take the first available one (if existent)
2041 if (nPos == -1 && m_xStyles->get_count() > 0)
2042 nPos = 0;
2044 if (nPos != -1)
2046 m_xStyles->set_active(nPos);
2047 if (bApplyFont)
2049 SetFont(m_xFonts->get_active_text(), m_xStyles->get_active_text());
2050 m_aSymbolDisplay.SetSymbol(m_xCharsetDisplay->GetSelectCharacter(), m_xCharsetDisplay->GetFont());
2052 bRet = true;
2054 else
2055 m_xStyles->set_entry_text(OUString());
2057 UpdateButtons();
2059 return bRet;
2062 void SmSymDefineDialog::SelectChar(sal_Unicode cChar)
2064 m_xCharsetDisplay->SelectCharacter( cChar );
2065 m_aSymbolDisplay.SetSymbol(cChar, m_xCharsetDisplay->GetFont());
2067 UpdateButtons();
2070 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */