Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / starmath / source / dialog.cxx
blob1c2d5f3405fc7ac766335aa931b2383230fa1c2e
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>
21 #include <sal/log.hxx>
23 #include <cassert>
25 #include <comphelper/string.hxx>
26 #include <svl/eitem.hxx>
27 #include <svl/intitem.hxx>
28 #include <svl/stritem.hxx>
29 #include <vcl/event.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/virdev.hxx>
32 #include <vcl/weld.hxx>
33 #include <svtools/ctrltool.hxx>
34 #include <vcl/settings.hxx>
35 #include <vcl/wall.hxx>
36 #include <vcl/fontcharmap.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <svx/charmap.hxx>
39 #include <svx/ucsubset.hxx>
41 #include <dialog.hxx>
42 #include <starmath.hrc>
43 #include <strings.hrc>
44 #include <helpids.h>
45 #include "cfgitem.hxx"
46 #include <smmod.hxx>
47 #include <symbol.hxx>
48 #include <view.hxx>
50 #include <algorithm>
52 namespace
55 void lclGetSettingColors(Color& rBackgroundColor, Color& rTextColor)
57 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
58 if (rStyleSettings.GetHighContrastMode())
60 rBackgroundColor = rStyleSettings.GetFieldColor();
61 rTextColor = rStyleSettings.GetFieldTextColor();
63 else
65 rBackgroundColor = COL_WHITE;
66 rTextColor = COL_BLACK;
70 } // end anonymous namespace
72 // Since it's better to set/query the FontStyle via its attributes rather
73 // than via the StyleName we create a way to translate
74 // Attribute <-> StyleName
76 class SmFontStyles
78 OUString const aNormal;
79 OUString const aBold;
80 OUString const aItalic;
81 OUString aBoldItalic;
83 public:
84 SmFontStyles();
86 static sal_uInt16 GetCount() { return 4; }
87 const OUString& GetStyleName(const vcl::Font& rFont) const;
88 const OUString& GetStyleName(sal_uInt16 nIdx) const;
91 SmFontStyles::SmFontStyles()
92 : aNormal(SmResId(RID_FONTREGULAR))
93 , aBold(SmResId(RID_FONTBOLD))
94 , aItalic(SmResId(RID_FONTITALIC))
96 aBoldItalic = aBold;
97 aBoldItalic += ", ";
98 aBoldItalic += aItalic;
101 const OUString& SmFontStyles::GetStyleName(const vcl::Font& rFont) const
103 //! compare also SmSpecialNode::Prepare
104 bool bBold = IsBold( rFont ),
105 bItalic = IsItalic( rFont );
107 if (bBold && bItalic)
108 return aBoldItalic;
109 else if (bItalic)
110 return aItalic;
111 else if (bBold)
112 return aBold;
113 return aNormal;
116 const OUString& SmFontStyles::GetStyleName( sal_uInt16 nIdx ) const
118 // 0 = "normal", 1 = "italic",
119 // 2 = "bold", 3 = "bold italic"
121 assert( nIdx < GetCount() );
122 switch (nIdx)
124 case 0 : return aNormal;
125 case 1 : return aItalic;
126 case 2 : return aBold;
127 default: /*case 3:*/ return aBoldItalic;
131 static const SmFontStyles & GetFontStyles()
133 static const SmFontStyles aImpl;
134 return aImpl;
137 void SetFontStyle(const OUString &rStyleName, vcl::Font &rFont)
139 // Find index related to StyleName. For an empty StyleName it's assumed to be
140 // 0 (neither bold nor italic).
141 sal_uInt16 nIndex = 0;
142 if (!rStyleName.isEmpty())
144 sal_uInt16 i;
145 const SmFontStyles &rStyles = GetFontStyles();
146 for (i = 0; i < SmFontStyles::GetCount(); ++i)
147 if (rStyleName == rStyles.GetStyleName(i))
148 break;
149 assert(i < SmFontStyles::GetCount() && "style-name unknown");
150 nIndex = i;
153 rFont.SetItalic((nIndex & 0x1) ? ITALIC_NORMAL : ITALIC_NONE);
154 rFont.SetWeight((nIndex & 0x2) ? WEIGHT_BOLD : WEIGHT_NORMAL);
157 IMPL_LINK_NOARG(SmPrintOptionsTabPage, SizeButtonClickHdl, weld::ToggleButton&, void)
159 m_xZoom->set_sensitive(m_xSizeZoomed->get_active());
162 SmPrintOptionsTabPage::SmPrintOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rOptions)
163 : SfxTabPage(pPage, pController, "modules/smath/ui/smathsettings.ui", "SmathSettings", &rOptions)
164 , m_xTitle(m_xBuilder->weld_check_button("title"))
165 , m_xText(m_xBuilder->weld_check_button("text"))
166 , m_xFrame(m_xBuilder->weld_check_button("frame"))
167 , m_xSizeNormal(m_xBuilder->weld_radio_button("sizenormal"))
168 , m_xSizeScaled(m_xBuilder->weld_radio_button("sizescaled"))
169 , m_xSizeZoomed(m_xBuilder->weld_radio_button("sizezoomed"))
170 , m_xZoom(m_xBuilder->weld_metric_spin_button("zoom", FieldUnit::PERCENT))
171 , m_xNoRightSpaces(m_xBuilder->weld_check_button("norightspaces"))
172 , m_xSaveOnlyUsedSymbols(m_xBuilder->weld_check_button("saveonlyusedsymbols"))
173 , m_xAutoCloseBrackets(m_xBuilder->weld_check_button("autoclosebrackets"))
175 m_xSizeNormal->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
176 m_xSizeScaled->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
177 m_xSizeZoomed->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
179 Reset(&rOptions);
182 SmPrintOptionsTabPage::~SmPrintOptionsTabPage()
186 bool SmPrintOptionsTabPage::FillItemSet(SfxItemSet* rSet)
188 sal_uInt16 nPrintSize;
189 if (m_xSizeNormal->get_active())
190 nPrintSize = PRINT_SIZE_NORMAL;
191 else if (m_xSizeScaled->get_active())
192 nPrintSize = PRINT_SIZE_SCALED;
193 else
194 nPrintSize = PRINT_SIZE_ZOOMED;
196 rSet->Put(SfxUInt16Item(GetWhich(SID_PRINTSIZE), nPrintSize));
197 rSet->Put(SfxUInt16Item(GetWhich(SID_PRINTZOOM), sal::static_int_cast<sal_uInt16>(m_xZoom->get_value(FieldUnit::PERCENT))));
198 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTTITLE), m_xTitle->get_active()));
199 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTTEXT), m_xText->get_active()));
200 rSet->Put(SfxBoolItem(GetWhich(SID_PRINTFRAME), m_xFrame->get_active()));
201 rSet->Put(SfxBoolItem(GetWhich(SID_NO_RIGHT_SPACES), m_xNoRightSpaces->get_active()));
202 rSet->Put(SfxBoolItem(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS), m_xSaveOnlyUsedSymbols->get_active()));
203 rSet->Put(SfxBoolItem(GetWhich(SID_AUTO_CLOSE_BRACKETS), m_xAutoCloseBrackets->get_active()));
205 return true;
208 void SmPrintOptionsTabPage::Reset(const SfxItemSet* rSet)
210 SmPrintSize ePrintSize = static_cast<SmPrintSize>(static_cast<const SfxUInt16Item &>(rSet->Get(GetWhich(SID_PRINTSIZE))).GetValue());
212 m_xSizeNormal->set_active(ePrintSize == PRINT_SIZE_NORMAL);
213 m_xSizeScaled->set_active(ePrintSize == PRINT_SIZE_SCALED);
214 m_xSizeZoomed->set_active(ePrintSize == PRINT_SIZE_ZOOMED);
216 m_xZoom->set_sensitive(m_xSizeZoomed->get_active());
218 m_xZoom->set_value(static_cast<const SfxUInt16Item &>(rSet->Get(GetWhich(SID_PRINTZOOM))).GetValue(), FieldUnit::PERCENT);
220 m_xTitle->set_active(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_PRINTTITLE))).GetValue());
221 m_xNoRightSpaces->set_active(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_NO_RIGHT_SPACES))).GetValue());
222 m_xSaveOnlyUsedSymbols->set_active(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS))).GetValue());
223 m_xAutoCloseBrackets->set_active(static_cast<const SfxBoolItem &>(rSet->Get(GetWhich(SID_AUTO_CLOSE_BRACKETS))).GetValue());
226 std::unique_ptr<SfxTabPage> SmPrintOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
228 return std::make_unique<SmPrintOptionsTabPage>(pPage, pController, rSet);
231 void SmShowFont::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
233 Color aBackColor;
234 Color aTextColor;
235 lclGetSettingColors(aBackColor, aTextColor);
237 rRenderContext.SetBackground(Wallpaper(aBackColor));
239 vcl::Font aFont(maFont);
240 aFont.SetFontSize(Size(0, 24 * rRenderContext.GetDPIScaleFactor()));
241 aFont.SetAlignment(ALIGN_TOP);
242 rRenderContext.SetFont(aFont);
243 rRenderContext.SetTextColor(aTextColor);
245 OUString sText(rRenderContext.GetFont().GetFamilyName());
246 Size aTextSize(rRenderContext.GetTextWidth(sText), rRenderContext.GetTextHeight());
248 rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
249 (rRenderContext.GetOutputSize().Height() - aTextSize.Height()) / 2), sText);
252 void SmShowFont::SetDrawingArea(weld::DrawingArea* pDrawingArea)
254 CustomWidgetController::SetDrawingArea(pDrawingArea);
255 Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(111 , 31), MapMode(MapUnit::MapAppFont)));
256 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
259 void SmShowFont::SetFont(const vcl::Font& rFont)
261 maFont = rFont;
262 Invalidate();
265 IMPL_LINK( SmFontDialog, FontSelectHdl, weld::ComboBox&, rComboBox, void )
267 maFont.SetFamilyName(rComboBox.get_active_text());
268 m_aShowFont.SetFont(maFont);
271 IMPL_LINK_NOARG(SmFontDialog, AttrChangeHdl, weld::ToggleButton&, void)
273 if (m_xBoldCheckBox->get_active())
274 maFont.SetWeight(WEIGHT_BOLD);
275 else
276 maFont.SetWeight(WEIGHT_NORMAL);
278 if (m_xItalicCheckBox->get_active())
279 maFont.SetItalic(ITALIC_NORMAL);
280 else
281 maFont.SetItalic(ITALIC_NONE);
283 m_aShowFont.SetFont(maFont);
286 void SmFontDialog::SetFont(const vcl::Font &rFont)
288 maFont = rFont;
290 m_xFontBox->set_active_text(maFont.GetFamilyName());
291 m_xBoldCheckBox->set_active(IsBold(maFont));
292 m_xItalicCheckBox->set_active(IsItalic(maFont));
293 m_aShowFont.SetFont(maFont);
296 SmFontDialog::SmFontDialog(weld::Window * pParent, OutputDevice *pFntListDevice, bool bHideCheckboxes)
297 : GenericDialogController(pParent, "modules/smath/ui/fontdialog.ui", "FontDialog")
298 , m_xFontBox(m_xBuilder->weld_entry_tree_view("fontgrid", "font", "fonts"))
299 , m_xAttrFrame(m_xBuilder->weld_widget("attrframe"))
300 , m_xBoldCheckBox(m_xBuilder->weld_check_button("bold"))
301 , m_xItalicCheckBox(m_xBuilder->weld_check_button("italic"))
302 , m_xShowFont(new weld::CustomWeld(*m_xBuilder, "preview", m_aShowFont))
304 m_xFontBox->set_height_request_by_rows(8);
307 weld::WaitObject aWait(pParent);
309 FontList aFontList( pFntListDevice );
311 sal_uInt16 nCount = aFontList.GetFontNameCount();
312 for (sal_uInt16 i = 0; i < nCount; ++i)
314 m_xFontBox->append_text(aFontList.GetFontName(i).GetFamilyName());
316 maFont.SetFontSize(Size(0, 24));
317 maFont.SetWeight(WEIGHT_NORMAL);
318 maFont.SetItalic(ITALIC_NONE);
319 maFont.SetFamily(FAMILY_DONTKNOW);
320 maFont.SetPitch(PITCH_DONTKNOW);
321 maFont.SetCharSet(RTL_TEXTENCODING_DONTKNOW);
322 maFont.SetTransparent(true);
325 m_xFontBox->connect_changed(LINK(this, SmFontDialog, FontSelectHdl));
326 m_xBoldCheckBox->connect_toggled(LINK(this, SmFontDialog, AttrChangeHdl));
327 m_xItalicCheckBox->connect_toggled(LINK(this, SmFontDialog, AttrChangeHdl));
329 if (bHideCheckboxes)
331 m_xBoldCheckBox->set_active(false);
332 m_xBoldCheckBox->set_sensitive(false);
333 m_xItalicCheckBox->set_active(false);
334 m_xItalicCheckBox->set_sensitive(false);
335 m_xAttrFrame->hide();
339 SmFontDialog::~SmFontDialog()
343 class SaveDefaultsQuery : public weld::MessageDialogController
345 public:
346 explicit SaveDefaultsQuery(weld::Widget* pParent)
347 : MessageDialogController(pParent, "modules/smath/ui/savedefaultsdialog.ui",
348 "SaveDefaultsDialog")
353 IMPL_LINK_NOARG( SmFontSizeDialog, DefaultButtonClickHdl, weld::Button&, void )
355 SaveDefaultsQuery aQuery(m_xDialog.get());
356 if (aQuery.run() == RET_YES)
358 SmModule *pp = SM_MOD();
359 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
360 WriteTo( aFmt );
361 pp->GetConfig()->SetStandardFormat( aFmt );
365 SmFontSizeDialog::SmFontSizeDialog(weld::Window* pParent)
366 : GenericDialogController(pParent, "modules/smath/ui/fontsizedialog.ui", "FontSizeDialog")
367 , m_xBaseSize(m_xBuilder->weld_metric_spin_button("spinB_baseSize", FieldUnit::POINT))
368 , m_xTextSize(m_xBuilder->weld_metric_spin_button("spinB_text", FieldUnit::PERCENT))
369 , m_xIndexSize(m_xBuilder->weld_metric_spin_button("spinB_index", FieldUnit::PERCENT))
370 , m_xFunctionSize(m_xBuilder->weld_metric_spin_button("spinB_function", FieldUnit::PERCENT))
371 , m_xOperatorSize(m_xBuilder->weld_metric_spin_button("spinB_operator", FieldUnit::PERCENT))
372 , m_xBorderSize(m_xBuilder->weld_metric_spin_button("spinB_limit", FieldUnit::PERCENT))
373 , m_xDefaultButton(m_xBuilder->weld_button("default"))
375 m_xDefaultButton->connect_clicked(LINK(this, SmFontSizeDialog, DefaultButtonClickHdl));
378 SmFontSizeDialog::~SmFontSizeDialog()
382 void SmFontSizeDialog::ReadFrom(const SmFormat &rFormat)
384 //! watch out: round properly!
385 m_xBaseSize->set_value( SmRoundFraction(
386 Sm100th_mmToPts( rFormat.GetBaseSize().Height() ) ), FieldUnit::NONE );
388 m_xTextSize->set_value( rFormat.GetRelSize(SIZ_TEXT), FieldUnit::NONE );
389 m_xIndexSize->set_value( rFormat.GetRelSize(SIZ_INDEX), FieldUnit::NONE );
390 m_xFunctionSize->set_value( rFormat.GetRelSize(SIZ_FUNCTION), FieldUnit::NONE );
391 m_xOperatorSize->set_value( rFormat.GetRelSize(SIZ_OPERATOR), FieldUnit::NONE );
392 m_xBorderSize->set_value( rFormat.GetRelSize(SIZ_LIMITS), FieldUnit::NONE );
395 void SmFontSizeDialog::WriteTo(SmFormat &rFormat) const
397 rFormat.SetBaseSize( Size(0, SmPtsTo100th_mm( static_cast< long >(m_xBaseSize->get_value(FieldUnit::NONE)))) );
399 rFormat.SetRelSize(SIZ_TEXT, sal::static_int_cast<sal_uInt16>(m_xTextSize->get_value(FieldUnit::NONE)));
400 rFormat.SetRelSize(SIZ_INDEX, sal::static_int_cast<sal_uInt16>(m_xIndexSize->get_value(FieldUnit::NONE)));
401 rFormat.SetRelSize(SIZ_FUNCTION, sal::static_int_cast<sal_uInt16>(m_xFunctionSize->get_value(FieldUnit::NONE)));
402 rFormat.SetRelSize(SIZ_OPERATOR, sal::static_int_cast<sal_uInt16>(m_xOperatorSize->get_value(FieldUnit::NONE)));
403 rFormat.SetRelSize(SIZ_LIMITS, sal::static_int_cast<sal_uInt16>(m_xBorderSize->get_value(FieldUnit::NONE)));
405 const Size aTmp (rFormat.GetBaseSize());
406 for (sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++)
407 rFormat.SetFontSize(i, aTmp);
409 rFormat.RequestApplyChanges();
412 IMPL_LINK(SmFontTypeDialog, MenuSelectHdl, const OString&, rIdent, void)
414 SmFontPickListBox *pActiveListBox;
416 bool bHideCheckboxes = false;
417 if (rIdent == "variables")
418 pActiveListBox = m_xVariableFont.get();
419 else if (rIdent == "functions")
420 pActiveListBox = m_xFunctionFont.get();
421 else if (rIdent == "numbers")
422 pActiveListBox = m_xNumberFont.get();
423 else if (rIdent == "text")
424 pActiveListBox = m_xTextFont.get();
425 else if (rIdent == "serif")
427 pActiveListBox = m_xSerifFont.get();
428 bHideCheckboxes = true;
430 else if (rIdent == "sansserif")
432 pActiveListBox = m_xSansFont.get();
433 bHideCheckboxes = true;
435 else if (rIdent == "fixedwidth")
437 pActiveListBox = m_xFixedFont.get();
438 bHideCheckboxes = true;
440 else
441 pActiveListBox = nullptr;
443 if (pActiveListBox)
445 SmFontDialog aFontDialog(m_xDialog.get(), pFontListDev, bHideCheckboxes);
447 pActiveListBox->WriteTo(aFontDialog);
448 if (aFontDialog.run() == RET_OK)
449 pActiveListBox->ReadFrom(aFontDialog);
453 IMPL_LINK_NOARG(SmFontTypeDialog, DefaultButtonClickHdl, weld::Button&, void)
455 SaveDefaultsQuery aQuery(m_xDialog.get());
456 if (aQuery.run() == RET_YES)
458 SmModule *pp = SM_MOD();
459 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
460 WriteTo( aFmt );
461 pp->GetConfig()->SetStandardFormat( aFmt, true );
465 SmFontTypeDialog::SmFontTypeDialog(weld::Window* pParent, OutputDevice *pFntListDevice)
466 : GenericDialogController(pParent, "modules/smath/ui/fonttypedialog.ui", "FontsDialog")
467 , pFontListDev(pFntListDevice)
468 , m_xVariableFont(new SmFontPickListBox(m_xBuilder->weld_combo_box("variableCB")))
469 , m_xFunctionFont(new SmFontPickListBox(m_xBuilder->weld_combo_box("functionCB")))
470 , m_xNumberFont(new SmFontPickListBox(m_xBuilder->weld_combo_box("numberCB")))
471 , m_xTextFont(new SmFontPickListBox(m_xBuilder->weld_combo_box("textCB")))
472 , m_xSerifFont(new SmFontPickListBox(m_xBuilder->weld_combo_box("serifCB")))
473 , m_xSansFont(new SmFontPickListBox(m_xBuilder->weld_combo_box("sansCB")))
474 , m_xFixedFont(new SmFontPickListBox(m_xBuilder->weld_combo_box("fixedCB")))
475 , m_xMenuButton(m_xBuilder->weld_menu_button("modify"))
476 , m_xDefaultButton(m_xBuilder->weld_button("default"))
478 m_xDefaultButton->connect_clicked(LINK(this, SmFontTypeDialog, DefaultButtonClickHdl));
479 m_xMenuButton->connect_selected(LINK(this, SmFontTypeDialog, MenuSelectHdl));
482 SmFontTypeDialog::~SmFontTypeDialog()
486 void SmFontTypeDialog::ReadFrom(const SmFormat &rFormat)
488 SmModule *pp = SM_MOD();
490 *m_xVariableFont = pp->GetConfig()->GetFontPickList(FNT_VARIABLE);
491 *m_xFunctionFont = pp->GetConfig()->GetFontPickList(FNT_FUNCTION);
492 *m_xNumberFont = pp->GetConfig()->GetFontPickList(FNT_NUMBER);
493 *m_xTextFont = pp->GetConfig()->GetFontPickList(FNT_TEXT);
494 *m_xSerifFont = pp->GetConfig()->GetFontPickList(FNT_SERIF);
495 *m_xSansFont = pp->GetConfig()->GetFontPickList(FNT_SANS);
496 *m_xFixedFont = pp->GetConfig()->GetFontPickList(FNT_FIXED);
498 m_xVariableFont->Insert( rFormat.GetFont(FNT_VARIABLE) );
499 m_xFunctionFont->Insert( rFormat.GetFont(FNT_FUNCTION) );
500 m_xNumberFont->Insert( rFormat.GetFont(FNT_NUMBER) );
501 m_xTextFont->Insert( rFormat.GetFont(FNT_TEXT) );
502 m_xSerifFont->Insert( rFormat.GetFont(FNT_SERIF) );
503 m_xSansFont->Insert( rFormat.GetFont(FNT_SANS) );
504 m_xFixedFont->Insert( rFormat.GetFont(FNT_FIXED) );
508 void SmFontTypeDialog::WriteTo(SmFormat &rFormat) const
510 SmModule *pp = SM_MOD();
512 pp->GetConfig()->GetFontPickList(FNT_VARIABLE) = *m_xVariableFont;
513 pp->GetConfig()->GetFontPickList(FNT_FUNCTION) = *m_xFunctionFont;
514 pp->GetConfig()->GetFontPickList(FNT_NUMBER) = *m_xNumberFont;
515 pp->GetConfig()->GetFontPickList(FNT_TEXT) = *m_xTextFont;
516 pp->GetConfig()->GetFontPickList(FNT_SERIF) = *m_xSerifFont;
517 pp->GetConfig()->GetFontPickList(FNT_SANS) = *m_xSansFont;
518 pp->GetConfig()->GetFontPickList(FNT_FIXED) = *m_xFixedFont;
520 rFormat.SetFont( FNT_VARIABLE, m_xVariableFont->Get() );
521 rFormat.SetFont( FNT_FUNCTION, m_xFunctionFont->Get() );
522 rFormat.SetFont( FNT_NUMBER, m_xNumberFont->Get() );
523 rFormat.SetFont( FNT_TEXT, m_xTextFont->Get() );
524 rFormat.SetFont( FNT_SERIF, m_xSerifFont->Get() );
525 rFormat.SetFont( FNT_SANS, m_xSansFont->Get() );
526 rFormat.SetFont( FNT_FIXED, m_xFixedFont->Get() );
528 rFormat.RequestApplyChanges();
531 /**************************************************************************/
533 struct FieldMinMax
535 sal_uInt16 nMin, nMax;
538 // Data for min and max values of the 4 metric fields
539 // for each of the 10 categories
540 static const FieldMinMax pMinMaxData[10][4] =
542 // 0
543 {{ 0, 200 }, { 0, 200 }, { 0, 100 }, { 0, 0 }},
544 // 1
545 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
546 // 2
547 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
548 // 3
549 {{ 0, 100 }, { 1, 100 }, { 0, 0 }, { 0, 0 }},
550 // 4
551 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
552 // 5
553 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 100 }},
554 // 6
555 {{ 0, 300 }, { 0, 300 }, { 0, 0 }, { 0, 0 }},
556 // 7
557 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
558 // 8
559 {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
560 // 9
561 {{ 0, 10000 }, { 0, 10000 }, { 0, 10000 }, { 0, 10000 }}
564 SmCategoryDesc::SmCategoryDesc(weld::Builder& rBuilder, sal_uInt16 nCategoryIdx)
566 ++nCategoryIdx;
567 std::unique_ptr<weld::Label> xTitle(rBuilder.weld_label(OString::number(nCategoryIdx)+"title"));
568 if (xTitle)
570 Name = xTitle->get_label();
572 for (int i = 0; i < 4; ++i)
574 std::unique_ptr<weld::Label> xLabel(rBuilder.weld_label(OString::number(nCategoryIdx)+"label"+OString::number(i+1)));
576 if (xLabel)
578 Strings[i] = xLabel->get_label();
579 Graphics[i] = rBuilder.weld_widget(OString::number(nCategoryIdx)+"image"+OString::number(i+1));
581 else
583 Strings[i].clear();
584 Graphics[i].reset();
587 const FieldMinMax& rMinMax = pMinMaxData[ nCategoryIdx-1 ][i];
588 Value[i] = Minimum[i] = rMinMax.nMin;
589 Maximum[i] = rMinMax.nMax;
593 SmCategoryDesc::~SmCategoryDesc()
597 /**************************************************************************/
599 IMPL_LINK( SmDistanceDialog, GetFocusHdl, weld::Widget&, rControl, void )
601 if (!m_xCategories[nActiveCategory])
602 return;
604 sal_uInt16 i;
606 if (&rControl == &m_xMetricField1->get_widget())
607 i = 0;
608 else if (&rControl == &m_xMetricField2->get_widget())
609 i = 1;
610 else if (&rControl == &m_xMetricField3->get_widget())
611 i = 2;
612 else if (&rControl == &m_xMetricField4->get_widget())
613 i = 3;
614 else
615 return;
616 if (m_pCurrentImage)
617 m_pCurrentImage->hide();
618 m_pCurrentImage = m_xCategories[nActiveCategory]->GetGraphic(i);
619 m_pCurrentImage->show();
622 IMPL_LINK(SmDistanceDialog, MenuSelectHdl, const OString&, rId, void)
624 assert(rId.startsWith("menuitem"));
625 SetCategory(rId.replaceFirst("menuitem", "").toInt32() - 1);
628 IMPL_LINK_NOARG( SmDistanceDialog, DefaultButtonClickHdl, weld::Button&, void )
630 SaveDefaultsQuery aQuery(m_xDialog.get());
631 if (aQuery.run() == RET_YES)
633 SmModule *pp = SM_MOD();
634 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
635 WriteTo( aFmt );
636 pp->GetConfig()->SetStandardFormat( aFmt );
640 IMPL_LINK( SmDistanceDialog, CheckBoxClickHdl, weld::ToggleButton&, rCheckBox, void )
642 if (&rCheckBox == m_xCheckBox1.get())
644 bool bChecked = m_xCheckBox1->get_active();
645 m_xFixedText4->set_sensitive( bChecked );
646 m_xMetricField4->set_sensitive( bChecked );
650 void SmDistanceDialog::SetCategory(sal_uInt16 nCategory)
652 assert(nCategory < NOCATEGORIES && "Sm: wrong category number in SmDistanceDialog");
654 // array to convert category- and metricfield-number in help ids.
655 // 0 is used in case of unused combinations.
656 assert(NOCATEGORIES == 10 && "Sm : array doesn't fit into the number of categories");
657 static const char * aCatMf2Hid[10][4] =
659 { HID_SMA_DEFAULT_DIST, HID_SMA_LINE_DIST, HID_SMA_ROOT_DIST, nullptr },
660 { HID_SMA_SUP_DIST, HID_SMA_SUB_DIST , nullptr, nullptr },
661 { HID_SMA_NUMERATOR_DIST, HID_SMA_DENOMINATOR_DIST, nullptr, nullptr },
662 { HID_SMA_FRACLINE_EXCWIDTH, HID_SMA_FRACLINE_LINEWIDTH, nullptr, nullptr },
663 { HID_SMA_UPPERLIMIT_DIST, HID_SMA_LOWERLIMIT_DIST, nullptr, nullptr },
664 { HID_SMA_BRACKET_EXCHEIGHT, HID_SMA_BRACKET_DIST, nullptr, HID_SMA_BRACKET_EXCHEIGHT2 },
665 { HID_SMA_MATRIXROW_DIST, HID_SMA_MATRIXCOL_DIST, nullptr, nullptr },
666 { HID_SMA_ATTRIBUT_DIST, HID_SMA_INTERATTRIBUT_DIST, nullptr, nullptr },
667 { HID_SMA_OPERATOR_EXCHEIGHT, HID_SMA_OPERATOR_DIST, nullptr, nullptr },
668 { HID_SMA_LEFTBORDER_DIST, HID_SMA_RIGHTBORDER_DIST, HID_SMA_UPPERBORDER_DIST, HID_SMA_LOWERBORDER_DIST }
671 // array to help iterate over the controls
672 std::pair<weld::Label*, weld::MetricSpinButton*> const aWin[4] =
674 { m_xFixedText1.get(), m_xMetricField1.get() },
675 { m_xFixedText2.get(), m_xMetricField2.get() },
676 { m_xFixedText3.get(), m_xMetricField3.get() },
677 { m_xFixedText4.get(), m_xMetricField4.get() }
680 SmCategoryDesc *pCat;
682 // remember the (maybe new) settings of the active SmCategoryDesc
683 // before switching to the new one
684 if (nActiveCategory != CATEGORY_NONE)
686 pCat = m_xCategories[nActiveCategory].get();
687 pCat->SetValue(0, sal::static_int_cast<sal_uInt16>(m_xMetricField1->get_value(FieldUnit::NONE)));
688 pCat->SetValue(1, sal::static_int_cast<sal_uInt16>(m_xMetricField2->get_value(FieldUnit::NONE)));
689 pCat->SetValue(2, sal::static_int_cast<sal_uInt16>(m_xMetricField3->get_value(FieldUnit::NONE)));
690 pCat->SetValue(3, sal::static_int_cast<sal_uInt16>(m_xMetricField4->get_value(FieldUnit::NONE)));
692 if (nActiveCategory == 5)
693 bScaleAllBrackets = m_xCheckBox1->get_active();
695 m_xMenuButton->set_item_active("menuitem" + OString::number(nActiveCategory + 1), false);
698 // activation/deactivation of the associated controls depending on the chosen category
699 bool bActive;
700 for (sal_uInt16 i = 0; i < 4; i++)
702 weld::Label *pFT = aWin[i].first;
703 weld::MetricSpinButton *pMF = aWin[i].second;
705 // To determine which Controls should be active, the existence
706 // of an associated HelpID is checked
707 bActive = aCatMf2Hid[nCategory][i] != nullptr;
709 pFT->set_visible(bActive);
710 pFT->set_sensitive(bActive);
711 pMF->set_visible(bActive);
712 pMF->set_sensitive(bActive);
714 // set measurement unit and number of decimal places
715 FieldUnit eUnit;
716 sal_uInt16 nDigits;
717 if (nCategory < 9)
719 eUnit = FieldUnit::PERCENT;
720 nDigits = 0;
722 else
724 eUnit = FieldUnit::MM_100TH;
725 nDigits = 2;
727 pMF->set_unit(eUnit); // changes the value
728 pMF->set_digits(nDigits);
730 if (bActive)
732 pCat = m_xCategories[nCategory].get();
733 pFT->set_label(pCat->GetString(i));
735 pMF->set_range(pCat->GetMinimum(i), pCat->GetMaximum(i), FieldUnit::NONE);
736 pMF->set_value(pCat->GetValue(i), FieldUnit::NONE);
738 pMF->set_help_id(aCatMf2Hid[nCategory][i]);
741 // activate the CheckBox and the associated MetricField if we're dealing with the brackets menu
742 bActive = nCategory == 5;
743 m_xCheckBox1->set_visible(bActive);
744 m_xCheckBox1->set_sensitive(bActive);
745 if (bActive)
747 m_xCheckBox1->set_active(bScaleAllBrackets);
749 bool bChecked = m_xCheckBox1->get_active();
750 m_xFixedText4->set_sensitive( bChecked );
751 m_xMetricField4->set_sensitive( bChecked );
754 m_xMenuButton->set_item_active("menuitem" + OString::number(nCategory + 1), true);
755 m_xFrame->set_label(m_xCategories[nCategory]->GetName());
757 nActiveCategory = nCategory;
759 m_xMetricField1->grab_focus();
762 SmDistanceDialog::SmDistanceDialog(weld::Window *pParent)
763 : GenericDialogController(pParent, "modules/smath/ui/spacingdialog.ui", "SpacingDialog")
764 , m_xFrame(m_xBuilder->weld_frame("template"))
765 , m_xFixedText1(m_xBuilder->weld_label("label1"))
766 , m_xMetricField1(m_xBuilder->weld_metric_spin_button("spinbutton1", FieldUnit::CM))
767 , m_xFixedText2(m_xBuilder->weld_label("label2"))
768 , m_xMetricField2(m_xBuilder->weld_metric_spin_button("spinbutton2", FieldUnit::CM))
769 , m_xFixedText3(m_xBuilder->weld_label("label3"))
770 , m_xMetricField3(m_xBuilder->weld_metric_spin_button("spinbutton3", FieldUnit::CM))
771 , m_xCheckBox1(m_xBuilder->weld_check_button("checkbutton"))
772 , m_xFixedText4(m_xBuilder->weld_label("label4"))
773 , m_xMetricField4(m_xBuilder->weld_metric_spin_button("spinbutton4", FieldUnit::CM))
774 , m_xMenuButton(m_xBuilder->weld_menu_button("category"))
775 , m_xDefaultButton(m_xBuilder->weld_button("default"))
776 , m_xBitmap(m_xBuilder->weld_widget("image"))
777 , m_pCurrentImage(m_xBitmap.get())
779 for (sal_uInt16 i = 0; i < NOCATEGORIES; ++i)
780 m_xCategories[i].reset( new SmCategoryDesc(*m_xBuilder, i) );
781 nActiveCategory = CATEGORY_NONE;
782 bScaleAllBrackets = false;
784 m_xMetricField1->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
785 m_xMetricField2->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
786 m_xMetricField3->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
787 m_xMetricField4->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
788 m_xCheckBox1->connect_toggled(LINK(this, SmDistanceDialog, CheckBoxClickHdl));
789 m_xMenuButton->connect_selected(LINK(this, SmDistanceDialog, MenuSelectHdl));
790 m_xDefaultButton->connect_clicked(LINK(this, SmDistanceDialog, DefaultButtonClickHdl));
792 //set the initial size, with max visible widgets visible, as preferred size
793 m_xDialog->set_size_request(-1, m_xDialog->get_preferred_size().Height());
796 SmDistanceDialog::~SmDistanceDialog()
800 void SmDistanceDialog::ReadFrom(const SmFormat &rFormat)
802 m_xCategories[0]->SetValue(0, rFormat.GetDistance(DIS_HORIZONTAL));
803 m_xCategories[0]->SetValue(1, rFormat.GetDistance(DIS_VERTICAL));
804 m_xCategories[0]->SetValue(2, rFormat.GetDistance(DIS_ROOT));
805 m_xCategories[1]->SetValue(0, rFormat.GetDistance(DIS_SUPERSCRIPT));
806 m_xCategories[1]->SetValue(1, rFormat.GetDistance(DIS_SUBSCRIPT));
807 m_xCategories[2]->SetValue(0, rFormat.GetDistance(DIS_NUMERATOR));
808 m_xCategories[2]->SetValue(1, rFormat.GetDistance(DIS_DENOMINATOR));
809 m_xCategories[3]->SetValue(0, rFormat.GetDistance(DIS_FRACTION));
810 m_xCategories[3]->SetValue(1, rFormat.GetDistance(DIS_STROKEWIDTH));
811 m_xCategories[4]->SetValue(0, rFormat.GetDistance(DIS_UPPERLIMIT));
812 m_xCategories[4]->SetValue(1, rFormat.GetDistance(DIS_LOWERLIMIT));
813 m_xCategories[5]->SetValue(0, rFormat.GetDistance(DIS_BRACKETSIZE));
814 m_xCategories[5]->SetValue(1, rFormat.GetDistance(DIS_BRACKETSPACE));
815 m_xCategories[5]->SetValue(3, rFormat.GetDistance(DIS_NORMALBRACKETSIZE));
816 m_xCategories[6]->SetValue(0, rFormat.GetDistance(DIS_MATRIXROW));
817 m_xCategories[6]->SetValue(1, rFormat.GetDistance(DIS_MATRIXCOL));
818 m_xCategories[7]->SetValue(0, rFormat.GetDistance(DIS_ORNAMENTSIZE));
819 m_xCategories[7]->SetValue(1, rFormat.GetDistance(DIS_ORNAMENTSPACE));
820 m_xCategories[8]->SetValue(0, rFormat.GetDistance(DIS_OPERATORSIZE));
821 m_xCategories[8]->SetValue(1, rFormat.GetDistance(DIS_OPERATORSPACE));
822 m_xCategories[9]->SetValue(0, rFormat.GetDistance(DIS_LEFTSPACE));
823 m_xCategories[9]->SetValue(1, rFormat.GetDistance(DIS_RIGHTSPACE));
824 m_xCategories[9]->SetValue(2, rFormat.GetDistance(DIS_TOPSPACE));
825 m_xCategories[9]->SetValue(3, rFormat.GetDistance(DIS_BOTTOMSPACE));
827 bScaleAllBrackets = rFormat.IsScaleNormalBrackets();
829 // force update (even of category 0) by setting nActiveCategory to a
830 // non-existent category number
831 nActiveCategory = CATEGORY_NONE;
832 SetCategory(0);
836 void SmDistanceDialog::WriteTo(SmFormat &rFormat) /*const*/
838 // TODO can they actually be different?
839 // if that's not the case 'const' could be used above!
840 SetCategory(nActiveCategory);
842 rFormat.SetDistance( DIS_HORIZONTAL, m_xCategories[0]->GetValue(0) );
843 rFormat.SetDistance( DIS_VERTICAL, m_xCategories[0]->GetValue(1) );
844 rFormat.SetDistance( DIS_ROOT, m_xCategories[0]->GetValue(2) );
845 rFormat.SetDistance( DIS_SUPERSCRIPT, m_xCategories[1]->GetValue(0) );
846 rFormat.SetDistance( DIS_SUBSCRIPT, m_xCategories[1]->GetValue(1) );
847 rFormat.SetDistance( DIS_NUMERATOR, m_xCategories[2]->GetValue(0) );
848 rFormat.SetDistance( DIS_DENOMINATOR, m_xCategories[2]->GetValue(1) );
849 rFormat.SetDistance( DIS_FRACTION, m_xCategories[3]->GetValue(0) );
850 rFormat.SetDistance( DIS_STROKEWIDTH, m_xCategories[3]->GetValue(1) );
851 rFormat.SetDistance( DIS_UPPERLIMIT, m_xCategories[4]->GetValue(0) );
852 rFormat.SetDistance( DIS_LOWERLIMIT, m_xCategories[4]->GetValue(1) );
853 rFormat.SetDistance( DIS_BRACKETSIZE, m_xCategories[5]->GetValue(0) );
854 rFormat.SetDistance( DIS_BRACKETSPACE, m_xCategories[5]->GetValue(1) );
855 rFormat.SetDistance( DIS_MATRIXROW, m_xCategories[6]->GetValue(0) );
856 rFormat.SetDistance( DIS_MATRIXCOL, m_xCategories[6]->GetValue(1) );
857 rFormat.SetDistance( DIS_ORNAMENTSIZE, m_xCategories[7]->GetValue(0) );
858 rFormat.SetDistance( DIS_ORNAMENTSPACE, m_xCategories[7]->GetValue(1) );
859 rFormat.SetDistance( DIS_OPERATORSIZE, m_xCategories[8]->GetValue(0) );
860 rFormat.SetDistance( DIS_OPERATORSPACE, m_xCategories[8]->GetValue(1) );
861 rFormat.SetDistance( DIS_LEFTSPACE, m_xCategories[9]->GetValue(0) );
862 rFormat.SetDistance( DIS_RIGHTSPACE, m_xCategories[9]->GetValue(1) );
863 rFormat.SetDistance( DIS_TOPSPACE, m_xCategories[9]->GetValue(2) );
864 rFormat.SetDistance( DIS_BOTTOMSPACE, m_xCategories[9]->GetValue(3) );
865 rFormat.SetDistance( DIS_NORMALBRACKETSIZE, m_xCategories[5]->GetValue(3) );
867 rFormat.SetScaleNormalBrackets( bScaleAllBrackets );
869 rFormat.RequestApplyChanges();
872 IMPL_LINK_NOARG( SmAlignDialog, DefaultButtonClickHdl, weld::Button&, void )
874 SaveDefaultsQuery aQuery(m_xDialog.get());
875 if (aQuery.run() == RET_YES)
877 SmModule *pp = SM_MOD();
878 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
879 WriteTo( aFmt );
880 pp->GetConfig()->SetStandardFormat( aFmt );
884 SmAlignDialog::SmAlignDialog(weld::Window* pParent)
885 : GenericDialogController(pParent, "modules/smath/ui/alignmentdialog.ui", "AlignmentDialog")
886 , m_xLeft(m_xBuilder->weld_radio_button("left"))
887 , m_xCenter(m_xBuilder->weld_radio_button("center"))
888 , m_xRight(m_xBuilder->weld_radio_button("right"))
889 , m_xDefaultButton(m_xBuilder->weld_button("default"))
891 m_xDefaultButton->connect_clicked(LINK(this, SmAlignDialog, DefaultButtonClickHdl));
894 SmAlignDialog::~SmAlignDialog()
898 void SmAlignDialog::ReadFrom(const SmFormat &rFormat)
900 switch (rFormat.GetHorAlign())
902 case SmHorAlign::Left:
903 m_xLeft->set_active(true);
904 break;
905 case SmHorAlign::Center:
906 m_xCenter->set_active(true);
907 break;
908 case SmHorAlign::Right:
909 m_xRight->set_active(true);
910 break;
914 void SmAlignDialog::WriteTo(SmFormat &rFormat) const
916 if (m_xLeft->get_active())
917 rFormat.SetHorAlign(SmHorAlign::Left);
918 else if (m_xRight->get_active())
919 rFormat.SetHorAlign(SmHorAlign::Right);
920 else
921 rFormat.SetHorAlign(SmHorAlign::Center);
923 rFormat.RequestApplyChanges();
926 SmShowSymbolSet::SmShowSymbolSet(std::unique_ptr<weld::ScrolledWindow> pScrolledWindow)
927 : nLen(0)
928 , nRows(0)
929 , nColumns(0)
930 , nXOffset(0)
931 , nYOffset(0)
932 , nSelectSymbol(SYMBOL_NONE)
933 , m_xScrolledWindow(std::move(pScrolledWindow))
935 m_xScrolledWindow->set_user_managed_scrolling();
936 m_xScrolledWindow->connect_vadjustment_changed(LINK(this, SmShowSymbolSet, ScrollHdl));
939 Point SmShowSymbolSet::OffsetPoint(const Point &rPoint) const
941 return Point(rPoint.X() + nXOffset, rPoint.Y() + nYOffset);
944 void SmShowSymbolSet::Resize()
946 CustomWidgetController::Resize();
947 Size aWinSize(GetOutputSizePixel());
948 if (aWinSize != m_aOldSize)
950 calccols(GetDrawingArea()->get_ref_device());
951 m_aOldSize = aWinSize;
955 void SmShowSymbolSet::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
957 Color aBackgroundColor;
958 Color aTextColor;
959 lclGetSettingColors(aBackgroundColor, aTextColor);
961 rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
962 rRenderContext.SetTextColor(aTextColor);
964 rRenderContext.Push(PushFlags::MAPMODE);
966 // set MapUnit for which 'nLen' has been calculated
967 rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
969 sal_uInt16 v = sal::static_int_cast< sal_uInt16 >(m_xScrolledWindow->vadjustment_get_value() * nColumns);
970 size_t nSymbols = aSymbolSet.size();
972 Color aTxtColor(rRenderContext.GetTextColor());
973 for (size_t i = v; i < nSymbols ; i++)
975 SmSym aSymbol(*aSymbolSet[i]);
976 vcl::Font aFont(aSymbol.GetFace());
977 aFont.SetAlignment(ALIGN_TOP);
979 // taking a FontSize which is a bit smaller (compared to nLen) in order to have a buffer
980 // (hopefully enough for left and right, too)
981 aFont.SetFontSize(Size(0, nLen - (nLen / 3)));
982 rRenderContext.SetFont(aFont);
983 // keep text color
984 rRenderContext.SetTextColor(aTxtColor);
986 int nIV = i - v;
987 sal_UCS4 cChar = aSymbol.GetCharacter();
988 OUString aText(&cChar, 1);
989 Size aSize(rRenderContext.GetTextWidth( aText ), rRenderContext.GetTextHeight());
991 Point aPoint((nIV % nColumns) * nLen + (nLen - aSize.Width()) / 2,
992 (nIV / nColumns) * nLen + (nLen - aSize.Height()) / 2);
994 rRenderContext.DrawText(OffsetPoint(aPoint), aText);
997 if (nSelectSymbol != SYMBOL_NONE)
999 Point aPoint(((nSelectSymbol - v) % nColumns) * nLen,
1000 ((nSelectSymbol - v) / nColumns) * nLen);
1002 rRenderContext.Invert(tools::Rectangle(OffsetPoint(aPoint), Size(nLen, nLen)));
1006 rRenderContext.Pop();
1009 bool SmShowSymbolSet::MouseButtonDown(const MouseEvent& rMEvt)
1011 GrabFocus();
1013 Size aOutputSize(nColumns * nLen, nRows * nLen);
1014 aOutputSize.AdjustWidth(nXOffset );
1015 aOutputSize.AdjustHeight(nYOffset );
1016 Point aPoint(rMEvt.GetPosPixel());
1017 aPoint.AdjustX( -nXOffset );
1018 aPoint.AdjustY( -nYOffset );
1020 if (rMEvt.IsLeft() && tools::Rectangle(Point(0, 0), aOutputSize).IsInside(rMEvt.GetPosPixel()))
1022 long nPos = (aPoint.Y() / nLen) * nColumns + (aPoint.X() / nLen) +
1023 m_xScrolledWindow->vadjustment_get_value() * nColumns;
1024 SelectSymbol( sal::static_int_cast< sal_uInt16 >(nPos) );
1026 aSelectHdlLink.Call(*this);
1028 if (rMEvt.GetClicks() > 1)
1029 aDblClickHdlLink.Call(*this);
1032 return true;
1035 bool SmShowSymbolSet::KeyInput(const KeyEvent& rKEvt)
1037 sal_uInt16 n = nSelectSymbol;
1039 if (n != SYMBOL_NONE)
1041 switch (rKEvt.GetKeyCode().GetCode())
1043 case KEY_DOWN: n = n + nColumns; break;
1044 case KEY_UP: n = n - nColumns; break;
1045 case KEY_LEFT: n -= 1; break;
1046 case KEY_RIGHT: n += 1; break;
1047 case KEY_HOME: n = 0; break;
1048 case KEY_END: n = static_cast< sal_uInt16 >(aSymbolSet.size() - 1); break;
1049 case KEY_PAGEUP: n -= nColumns * nRows; break;
1050 case KEY_PAGEDOWN: n += nColumns * nRows; break;
1051 default:
1052 return false;
1055 else
1056 n = 0;
1058 if (n >= aSymbolSet.size())
1059 n = nSelectSymbol;
1061 // adjust scrollbar
1062 if ((n < sal::static_int_cast<sal_uInt16>(m_xScrolledWindow->vadjustment_get_value() * nColumns)) ||
1063 (n >= sal::static_int_cast<sal_uInt16>((m_xScrolledWindow->vadjustment_get_value() + nRows) * nColumns)))
1065 m_xScrolledWindow->vadjustment_set_value(n / nColumns);
1066 Invalidate();
1069 SelectSymbol(n);
1070 aSelectHdlLink.Call(*this);
1072 return true;
1075 void SmShowSymbolSet::calccols(const vcl::RenderContext& rRenderContext)
1077 // Height of 16pt in pixels (matching 'aOutputSize')
1078 nLen = rRenderContext.LogicToPixel(Size(0, 16), MapMode(MapUnit::MapPoint)).Height();
1080 Size aOutputSize(GetOutputSizePixel());
1082 nColumns = aOutputSize.Width() / nLen;
1083 nRows = aOutputSize.Height() / nLen;
1084 nColumns = std::max<long>(1, nColumns);
1085 nRows = std::max<long>(1, nRows);
1087 nXOffset = (aOutputSize.Width() - (nColumns * nLen)) / 2;
1088 nYOffset = (aOutputSize.Height() - (nRows * nLen)) / 2;
1090 SetScrollBarRange();
1093 void SmShowSymbolSet::SetSymbolSet(const SymbolPtrVec_t& rSymbolSet)
1095 aSymbolSet = rSymbolSet;
1096 SetScrollBarRange();
1097 Invalidate();
1100 void SmShowSymbolSet::SetScrollBarRange()
1102 const int nLastRow = (aSymbolSet.size() - 1 + nColumns) / nColumns;
1103 m_xScrolledWindow->vadjustment_configure(m_xScrolledWindow->vadjustment_get_value(), 0, nLastRow, 1, nRows - 1, nRows);
1104 Invalidate();
1107 void SmShowSymbolSet::SelectSymbol(sal_uInt16 nSymbol)
1109 int v = m_xScrolledWindow->vadjustment_get_value() * nColumns;
1111 if (nSelectSymbol != SYMBOL_NONE && nColumns)
1113 Point aPoint(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
1114 ((nSelectSymbol - v) / nColumns) * nLen)));
1115 Invalidate(tools::Rectangle(aPoint, Size(nLen, nLen)));
1118 if (nSymbol < aSymbolSet.size())
1119 nSelectSymbol = nSymbol;
1121 if (aSymbolSet.empty())
1122 nSelectSymbol = SYMBOL_NONE;
1124 if (nSelectSymbol != SYMBOL_NONE && nColumns)
1126 Point aPoint(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
1127 ((nSelectSymbol - v) / nColumns) * nLen)));
1128 Invalidate(tools::Rectangle(aPoint, Size(nLen, nLen)));
1131 if (!nColumns)
1132 Invalidate();
1135 IMPL_LINK_NOARG(SmShowSymbolSet, ScrollHdl, weld::ScrolledWindow&, void)
1137 Invalidate();
1140 SmShowSymbol::SmShowSymbol()
1144 void SmShowSymbol::setFontSize(vcl::Font &rFont) const
1146 Size aSize(GetOutputSizePixel());
1147 rFont.SetFontSize(Size(0, aSize.Height() - aSize.Height() / 3));
1150 void SmShowSymbol::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
1152 Color aBackgroundColor;
1153 Color aTextColor;
1154 lclGetSettingColors(aBackgroundColor, aTextColor);
1155 rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
1156 rRenderContext.SetTextColor(aTextColor);
1157 rRenderContext.Erase();
1159 vcl::Font aFont(GetFont());
1160 setFontSize(aFont);
1161 rRenderContext.SetFont(aFont);
1163 const OUString &rText = GetText();
1164 Size aTextSize(rRenderContext.GetTextWidth(rText), rRenderContext.GetTextHeight());
1166 rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
1167 (rRenderContext.GetOutputSize().Height() * 7 / 10)), rText);
1170 bool SmShowSymbol::MouseButtonDown(const MouseEvent& rMEvt)
1172 if (rMEvt.GetClicks() > 1)
1173 aDblClickHdlLink.Call(*this);
1174 return true;
1177 void SmShowSymbol::SetSymbol(const SmSym *pSymbol)
1179 if (pSymbol)
1181 vcl::Font aFont(pSymbol->GetFace());
1182 aFont.SetAlignment(ALIGN_BASELINE);
1183 SetFont(aFont);
1185 sal_UCS4 cChar = pSymbol->GetCharacter();
1186 OUString aText(&cChar, 1);
1187 SetText( aText );
1190 Invalidate();
1193 void SmSymbolDialog::FillSymbolSets()
1194 // populate the entries of possible SymbolsSets in the dialog with
1195 // current values of the SymbolSet manager but selects none of those
1197 m_xSymbolSets->clear();
1198 m_xSymbolSets->set_active(-1);
1200 std::set< OUString > aSymbolSetNames( rSymbolMgr.GetSymbolSetNames() );
1201 for (const auto& rSymbolSetName : aSymbolSetNames)
1202 m_xSymbolSets->append_text(rSymbolSetName);
1205 IMPL_LINK_NOARG( SmSymbolDialog, SymbolSetChangeHdl, weld::ComboBox&, void )
1207 SelectSymbolSet(m_xSymbolSets->get_active_text());
1210 IMPL_LINK_NOARG( SmSymbolDialog, SymbolChangeHdl, SmShowSymbolSet&, void )
1212 SelectSymbol(m_xSymbolSetDisplay->GetSelectSymbol());
1215 IMPL_LINK_NOARG(SmSymbolDialog, EditClickHdl, weld::Button&, void)
1217 SmSymDefineDialog aDialog(m_xDialog.get(), pFontListDev, rSymbolMgr);
1219 // set current symbol and SymbolSet for the new dialog
1220 const OUString aSymSetName (m_xSymbolSets->get_active_text()),
1221 aSymName (m_xSymbolName->get_label());
1222 aDialog.SelectOldSymbolSet(aSymSetName);
1223 aDialog.SelectOldSymbol(aSymName);
1224 aDialog.SelectSymbolSet(aSymSetName);
1225 aDialog.SelectSymbol(aSymName);
1227 // remember old SymbolSet
1228 OUString aOldSymbolSet (m_xSymbolSets->get_active_text());
1230 sal_uInt16 nSymPos = m_xSymbolSetDisplay->GetSelectSymbol();
1232 // adapt dialog to data of the SymbolSet manager, which might have changed
1233 if (aDialog.run() == RET_OK && rSymbolMgr.IsModified())
1235 rSymbolMgr.Save();
1236 FillSymbolSets();
1239 // if the old SymbolSet doesn't exist anymore, go to the first one SymbolSet (if one exists)
1240 if (!SelectSymbolSet(aOldSymbolSet) && m_xSymbolSets->get_count() > 0)
1241 SelectSymbolSet(m_xSymbolSets->get_text(0));
1242 else
1244 // just update display of current symbol set
1245 assert(aSymSetName == aSymSetName); //unexpected change in symbol set name
1246 aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
1247 m_xSymbolSetDisplay->SetSymbolSet( aSymbolSet );
1250 if (nSymPos >= aSymbolSet.size())
1251 nSymPos = static_cast< sal_uInt16 >(aSymbolSet.size()) - 1;
1252 SelectSymbol( nSymPos );
1255 IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl2, SmShowSymbolSet&, void )
1257 SymbolDblClickHdl();
1260 IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl, SmShowSymbol&, void )
1262 SymbolDblClickHdl();
1265 void SmSymbolDialog::SymbolDblClickHdl()
1267 GetClickHdl(*m_xGetBtn);
1268 m_xDialog->response(RET_OK);
1271 IMPL_LINK_NOARG(SmSymbolDialog, GetClickHdl, weld::Button&, void)
1273 const SmSym *pSym = GetSymbol();
1274 if (pSym)
1276 OUString aText = "%" + pSym->GetName() + " ";
1278 rViewSh.GetViewFrame()->GetDispatcher()->ExecuteList(
1279 SID_INSERTSPECIAL, SfxCallMode::RECORD,
1280 { new SfxStringItem(SID_INSERTSPECIAL, aText) });
1284 SmSymbolDialog::SmSymbolDialog(weld::Window *pParent, OutputDevice *pFntListDevice,
1285 SmSymbolManager &rMgr, SmViewShell &rViewShell)
1286 : GenericDialogController(pParent, "modules/smath/ui/catalogdialog.ui", "CatalogDialog")
1287 , rViewSh(rViewShell)
1288 , rSymbolMgr(rMgr)
1289 , pFontListDev(pFntListDevice)
1290 , m_xSymbolSets(m_xBuilder->weld_combo_box("symbolset"))
1291 , m_xSymbolSetDisplay(new SmShowSymbolSet(m_xBuilder->weld_scrolled_window("scrolledwindow")))
1292 , m_xSymbolSetDisplayArea(new weld::CustomWeld(*m_xBuilder, "symbolsetdisplay", *m_xSymbolSetDisplay))
1293 , m_xSymbolName(m_xBuilder->weld_label("symbolname"))
1294 , m_xSymbolDisplay(new weld::CustomWeld(*m_xBuilder, "preview", m_aSymbolDisplay))
1295 , m_xGetBtn(m_xBuilder->weld_button("ok"))
1296 , m_xEditBtn(m_xBuilder->weld_button("edit"))
1298 m_xSymbolSets->make_sorted();
1300 aSymbolSetName.clear();
1301 aSymbolSet.clear();
1302 FillSymbolSets();
1303 if (m_xSymbolSets->get_count() > 0)
1304 SelectSymbolSet(m_xSymbolSets->get_text(0));
1306 m_xSymbolSets->connect_changed(LINK(this, SmSymbolDialog, SymbolSetChangeHdl));
1307 m_xSymbolSetDisplay->SetSelectHdl(LINK(this, SmSymbolDialog, SymbolChangeHdl));
1308 m_xSymbolSetDisplay->SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl2));
1309 m_aSymbolDisplay.SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl));
1310 m_xEditBtn->connect_clicked(LINK(this, SmSymbolDialog, EditClickHdl));
1311 m_xGetBtn->connect_clicked(LINK(this, SmSymbolDialog, GetClickHdl));
1314 SmSymbolDialog::~SmSymbolDialog()
1318 bool SmSymbolDialog::SelectSymbolSet(const OUString &rSymbolSetName)
1320 bool bRet = false;
1321 sal_Int32 nPos = m_xSymbolSets->find_text(rSymbolSetName);
1323 aSymbolSetName.clear();
1324 aSymbolSet.clear();
1325 if (nPos != -1)
1327 m_xSymbolSets->set_active(nPos);
1329 aSymbolSetName = rSymbolSetName;
1330 aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
1332 // sort symbols by Unicode position (useful for displaying Greek characters alphabetically)
1333 std::sort( aSymbolSet.begin(), aSymbolSet.end(),
1334 [](const SmSym *pSym1, const SmSym *pSym2)
1336 return pSym1->GetCharacter() < pSym2->GetCharacter();
1337 } );
1339 m_xSymbolSetDisplay->SetSymbolSet( aSymbolSet );
1340 if (!aSymbolSet.empty())
1341 SelectSymbol(0);
1343 bRet = true;
1345 else
1346 m_xSymbolSets->set_active(-1);
1348 return bRet;
1351 void SmSymbolDialog::SelectSymbol(sal_uInt16 nSymbolNo)
1353 const SmSym *pSym = nullptr;
1354 if (!aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size()))
1355 pSym = aSymbolSet[ nSymbolNo ];
1357 m_xSymbolSetDisplay->SelectSymbol(nSymbolNo);
1358 m_aSymbolDisplay.SetSymbol(pSym);
1359 m_xSymbolName->set_label(pSym ? pSym->GetName() : OUString());
1362 const SmSym* SmSymbolDialog::GetSymbol() const
1364 sal_uInt16 nSymbolNo = m_xSymbolSetDisplay->GetSelectSymbol();
1365 bool bValid = !aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size());
1366 return bValid ? aSymbolSet[ nSymbolNo ] : nullptr;
1369 void SmShowChar::Resize()
1371 const OUString &rText = GetText();
1372 if (rText.isEmpty())
1373 return;
1374 sal_Int32 nStrIndex = 0;
1375 sal_UCS4 cChar = rText.iterateCodePoints(&nStrIndex);
1376 SetSymbol(cChar, GetFont()); //force recalculation of size
1379 void SmShowChar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
1381 Color aTextCol = rRenderContext.GetTextColor();
1382 Color aFillCol = rRenderContext.GetFillColor();
1384 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1385 const Color aWindowTextColor(rStyleSettings.GetDialogTextColor());
1386 const Color aWindowColor(rStyleSettings.GetWindowColor());
1387 rRenderContext.SetTextColor(aWindowTextColor);
1388 rRenderContext.SetFillColor(aWindowColor);
1390 Size aSize(GetOutputSizePixel());
1391 rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aSize));
1393 OUString aText(GetText());
1394 if (!aText.isEmpty())
1396 vcl::Font aFont(m_aFont);
1397 aFont.SetAlignment(ALIGN_TOP);
1398 rRenderContext.SetFont(aFont);
1400 Size aTextSize(rRenderContext.GetTextWidth(aText), rRenderContext.GetTextHeight());
1402 rRenderContext.DrawText(Point((aSize.Width() - aTextSize.Width()) / 2,
1403 (aSize.Height() - aTextSize.Height()) / 2), aText);
1406 rRenderContext.SetTextColor(aTextCol);
1407 rRenderContext.SetFillColor(aFillCol);
1410 void SmShowChar::SetSymbol( const SmSym *pSym )
1412 if (pSym)
1413 SetSymbol( pSym->GetCharacter(), pSym->GetFace() );
1417 void SmShowChar::SetSymbol( sal_UCS4 cChar, const vcl::Font &rFont )
1419 vcl::Font aFont( rFont );
1420 Size aSize(GetOutputSizePixel());
1421 aFont.SetFontSize(Size(0, aSize.Height() - aSize.Height() / 3));
1422 aFont.SetAlignment(ALIGN_BASELINE);
1423 SetFont(aFont);
1425 OUString aText(&cChar, 1);
1426 SetText( aText );
1428 Invalidate();
1431 void SmSymDefineDialog::FillSymbols(weld::ComboBox& rComboBox, bool bDeleteText)
1433 assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong ComboBox");
1435 rComboBox.clear();
1436 if (bDeleteText)
1437 rComboBox.set_entry_text(OUString());
1439 weld::ComboBox& rBox = &rComboBox == m_xOldSymbols.get() ? *m_xOldSymbolSets : *m_xSymbolSets;
1440 SymbolPtrVec_t aSymSet(m_aSymbolMgrCopy.GetSymbolSet(rBox.get_active_text()));
1441 for (const SmSym* i : aSymSet)
1442 rComboBox.append_text(i->GetName());
1445 void SmSymDefineDialog::FillSymbolSets(weld::ComboBox& rComboBox, bool bDeleteText)
1447 assert((&rComboBox == m_xOldSymbolSets.get() || &rComboBox == m_xSymbolSets.get()) && "Sm : wrong ComboBox");
1449 rComboBox.clear();
1450 if (bDeleteText)
1451 rComboBox.set_entry_text(OUString());
1453 const std::set< OUString > aSymbolSetNames( m_aSymbolMgrCopy.GetSymbolSetNames() );
1454 for (const auto& rSymbolSetName : aSymbolSetNames)
1455 rComboBox.append_text(rSymbolSetName);
1458 void SmSymDefineDialog::FillFonts()
1460 m_xFonts->clear();
1461 m_xFonts->set_active(-1);
1463 // Include all fonts of FontList into the font list.
1464 // If there are duplicates, only include one entry of each font since the style will be
1465 // already selected using the FontStyleBox.
1466 if (m_xFontList)
1468 sal_uInt16 nCount = m_xFontList->GetFontNameCount();
1469 for (sal_uInt16 i = 0; i < nCount; ++i)
1470 m_xFonts->append_text(m_xFontList->GetFontName(i).GetFamilyName());
1474 void SmSymDefineDialog::FillStyles()
1476 m_xStyles->clear();
1477 // pStyles->SetText(OUString());
1479 OUString aText(m_xFonts->get_active_text());
1480 if (!aText.isEmpty())
1482 // use own StyleNames
1483 const SmFontStyles &rStyles = GetFontStyles();
1484 for (sal_uInt16 i = 0; i < SmFontStyles::GetCount(); ++i)
1485 m_xStyles->append_text(rStyles.GetStyleName(i));
1487 assert(m_xStyles->get_count() > 0 && "Sm : no styles available");
1488 m_xStyles->set_active(0);
1492 SmSym* SmSymDefineDialog::GetSymbol(const weld::ComboBox& rComboBox)
1494 assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong combobox");
1495 return m_aSymbolMgrCopy.GetSymbolByName(rComboBox.get_active_text());
1498 IMPL_LINK(SmSymDefineDialog, OldSymbolChangeHdl, weld::ComboBox&, rComboBox, void)
1500 (void) rComboBox;
1501 assert(&rComboBox == m_xOldSymbols.get() && "Sm : wrong argument");
1502 SelectSymbol(*m_xOldSymbols, m_xOldSymbols->get_active_text(), false);
1505 IMPL_LINK( SmSymDefineDialog, OldSymbolSetChangeHdl, weld::ComboBox&, rComboBox, void )
1507 (void) rComboBox;
1508 assert(&rComboBox == m_xOldSymbolSets.get() && "Sm : wrong argument");
1509 SelectSymbolSet(*m_xOldSymbolSets, m_xOldSymbolSets->get_active_text(), false);
1512 IMPL_LINK(SmSymDefineDialog, ModifyHdl, weld::ComboBox&, rComboBox, void)
1514 // remember cursor position for later restoring of it
1515 int nStartPos, nEndPos;
1516 rComboBox.get_entry_selection_bounds(nStartPos, nEndPos);
1518 if (&rComboBox == m_xSymbols.get())
1519 SelectSymbol(*m_xSymbols, m_xSymbols->get_active_text(), false);
1520 else if (&rComboBox == m_xSymbolSets.get())
1521 SelectSymbolSet(*m_xSymbolSets, m_xSymbolSets->get_active_text(), false);
1522 else if (&rComboBox == m_xOldSymbols.get())
1523 // allow only names from the list
1524 SelectSymbol(*m_xOldSymbols, m_xOldSymbols->get_active_text(), true);
1525 else if (&rComboBox == m_xOldSymbolSets.get())
1526 // allow only names from the list
1527 SelectSymbolSet(*m_xOldSymbolSets, m_xOldSymbolSets->get_active_text(), true);
1528 else if (&rComboBox == m_xStyles.get())
1529 // allow only names from the list (that's the case here anyway)
1530 SelectStyle(m_xStyles->get_active_text(), true);
1531 else
1532 SAL_WARN("starmath", "wrong combobox argument");
1534 rComboBox.select_entry_region(nStartPos, nEndPos);
1536 UpdateButtons();
1539 IMPL_LINK(SmSymDefineDialog, FontChangeHdl, weld::ComboBox&, rListBox, void)
1541 (void) rListBox;
1542 assert(&rListBox == m_xFonts.get() && "Sm : wrong argument");
1544 SelectFont(m_xFonts->get_active_text());
1547 IMPL_LINK_NOARG(SmSymDefineDialog, SubsetChangeHdl, weld::ComboBox&, void)
1549 int nPos = m_xFontsSubsetLB->get_active();
1550 if (nPos != -1)
1552 const Subset* pSubset = reinterpret_cast<const Subset*>(m_xFontsSubsetLB->get_active_id().toUInt64());
1553 if (pSubset)
1555 m_xCharsetDisplay->SelectCharacter( pSubset->GetRangeMin() );
1560 IMPL_LINK( SmSymDefineDialog, StyleChangeHdl, weld::ComboBox&, rComboBox, void )
1562 (void) rComboBox;
1563 assert(&rComboBox == m_xStyles.get() && "Sm : wrong argument");
1565 SelectStyle(m_xStyles->get_active_text());
1568 IMPL_LINK_NOARG(SmSymDefineDialog, CharHighlightHdl, SvxShowCharSet*, void)
1570 sal_UCS4 cChar = m_xCharsetDisplay->GetSelectCharacter();
1572 if (m_xSubsetMap)
1574 const Subset* pSubset = m_xSubsetMap->GetSubsetByUnicode(cChar);
1575 if (pSubset)
1576 m_xFontsSubsetLB->set_active_text(pSubset->GetName());
1577 else
1578 m_xFontsSubsetLB->set_active(-1);
1581 m_aSymbolDisplay.SetSymbol(cChar, m_xCharsetDisplay->GetFont());
1583 UpdateButtons();
1585 // display Unicode position as symbol name while iterating over characters
1586 const OUString aHex(OUString::number(cChar, 16).toAsciiUpperCase());
1587 const OUString aPattern( (aHex.getLength() > 4) ? OUString("Ux000000") : OUString("Ux0000") );
1588 OUString aUnicodePos = aPattern.copy( 0, aPattern.getLength() - aHex.getLength() ) +
1589 aHex;
1590 m_xSymbols->set_entry_text(aUnicodePos);
1591 m_xSymbolName->set_label(aUnicodePos);
1594 IMPL_LINK( SmSymDefineDialog, AddClickHdl, weld::Button&, rButton, void )
1596 (void) rButton;
1597 assert(&rButton == m_xAddBtn.get() && "Sm : wrong argument");
1598 assert(rButton.get_sensitive() && "Sm : requirements met ??");
1600 // add symbol
1601 const SmSym aNewSymbol(m_xSymbols->get_active_text(), m_xCharsetDisplay->GetFont(),
1602 m_xCharsetDisplay->GetSelectCharacter(), m_xSymbolSets->get_active_text());
1603 //OSL_ENSURE( m_aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == NULL, "symbol already exists" );
1604 m_aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol );
1606 // update display of new symbol
1607 m_aSymbolDisplay.SetSymbol( &aNewSymbol );
1608 m_xSymbolName->set_label(aNewSymbol.GetName());
1609 m_xSymbolSetName->set_label(aNewSymbol.GetSymbolSetName());
1611 // update list box entries
1612 FillSymbolSets(*m_xOldSymbolSets, false);
1613 FillSymbolSets(*m_xSymbolSets, false);
1614 FillSymbols(*m_xOldSymbols, false);
1615 FillSymbols(*m_xSymbols, false);
1617 UpdateButtons();
1620 IMPL_LINK( SmSymDefineDialog, ChangeClickHdl, weld::Button&, rButton, void )
1622 (void) rButton;
1623 assert(&rButton == m_xChangeBtn.get() && "Sm : wrong argument");
1624 assert(m_xChangeBtn->get_sensitive() && "Sm : requirements met ??");
1626 // get new Symbol to use
1627 //! get font from symbol-disp lay since charset-display does not keep
1628 //! the bold attribute.
1629 const SmSym aNewSymbol(m_xSymbols->get_active_text(), m_xCharsetDisplay->GetFont(),
1630 m_xCharsetDisplay->GetSelectCharacter(), m_xSymbolSets->get_active_text());
1632 // remove old symbol if the name was changed then add new one
1633 const bool bNameChanged = m_xOldSymbols->get_active_text() != m_xSymbols->get_active_text();
1634 if (bNameChanged)
1635 m_aSymbolMgrCopy.RemoveSymbol(m_xOldSymbols->get_active_text());
1636 m_aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol, true );
1638 // clear display for original symbol if necessary
1639 if (bNameChanged)
1640 SetOrigSymbol(nullptr, OUString());
1642 // update display of new symbol
1643 m_aSymbolDisplay.SetSymbol(&aNewSymbol);
1644 m_xSymbolName->set_label(aNewSymbol.GetName());
1645 m_xSymbolSetName->set_label(aNewSymbol.GetSymbolSetName());
1647 // update list box entries
1648 FillSymbolSets(*m_xOldSymbolSets, false);
1649 FillSymbolSets(*m_xSymbolSets, false);
1650 FillSymbols(*m_xOldSymbols, false);
1651 FillSymbols(*m_xSymbols, false);
1653 UpdateButtons();
1656 IMPL_LINK(SmSymDefineDialog, DeleteClickHdl, weld::Button&, rButton, void)
1658 (void) rButton;
1659 assert(&rButton == m_xDeleteBtn.get() && "Sm : wrong argument");
1660 assert(m_xDeleteBtn->get_sensitive() && "Sm : requirements met ??");
1662 if (m_xOrigSymbol)
1664 m_aSymbolMgrCopy.RemoveSymbol(m_xOrigSymbol->GetName());
1666 // clear display for original symbol
1667 SetOrigSymbol(nullptr, OUString());
1669 // update list box entries
1670 FillSymbolSets(*m_xOldSymbolSets, false);
1671 FillSymbolSets(*m_xSymbolSets, false);
1672 FillSymbols(*m_xOldSymbols ,false);
1673 FillSymbols(*m_xSymbols ,false);
1676 UpdateButtons();
1679 void SmSymDefineDialog::UpdateButtons()
1681 bool bAdd = false,
1682 bChange = false,
1683 bDelete = false;
1684 OUString aTmpSymbolName(m_xSymbols->get_active_text()),
1685 aTmpSymbolSetName(m_xSymbolSets->get_active_text());
1687 if (!aTmpSymbolName.isEmpty() && !aTmpSymbolSetName.isEmpty())
1689 // are all settings equal?
1690 //! (Font-, Style- and SymbolSet name comparison is not case sensitive)
1691 bool bEqual = m_xOrigSymbol
1692 && aTmpSymbolSetName.equalsIgnoreAsciiCase(m_xOldSymbolSetName->get_label())
1693 && aTmpSymbolName == m_xOrigSymbol->GetName()
1694 && m_xFonts->get_active_text().equalsIgnoreAsciiCase(
1695 m_xOrigSymbol->GetFace().GetFamilyName())
1696 && m_xStyles->get_active_text().equalsIgnoreAsciiCase(
1697 GetFontStyles().GetStyleName(m_xOrigSymbol->GetFace()))
1698 && m_xCharsetDisplay->GetSelectCharacter() == m_xOrigSymbol->GetCharacter();
1700 // only add it if there isn't already a symbol with the same name
1701 bAdd = m_aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == nullptr;
1703 // only delete it if all settings are equal
1704 bDelete = bool(m_xOrigSymbol);
1706 // only change it if the old symbol exists and the new one is different
1707 bChange = m_xOrigSymbol && !bEqual;
1710 m_xAddBtn->set_sensitive(bAdd);
1711 m_xChangeBtn->set_sensitive(bChange);
1712 m_xDeleteBtn->set_sensitive(bDelete);
1715 SmSymDefineDialog::SmSymDefineDialog(weld::Window* pParent, OutputDevice *pFntListDevice, SmSymbolManager &rMgr)
1716 : GenericDialogController(pParent, "modules/smath/ui/symdefinedialog.ui", "EditSymbols")
1717 , m_xVirDev(VclPtr<VirtualDevice>::Create())
1718 , m_rSymbolMgr(rMgr)
1719 , m_xFontList(new FontList(pFntListDevice))
1720 , m_xOldSymbols(m_xBuilder->weld_combo_box("oldSymbols"))
1721 , m_xOldSymbolSets(m_xBuilder->weld_combo_box("oldSymbolSets"))
1722 , m_xSymbols(m_xBuilder->weld_combo_box("symbols"))
1723 , m_xSymbolSets(m_xBuilder->weld_combo_box("symbolSets"))
1724 , m_xFonts(m_xBuilder->weld_combo_box("fonts"))
1725 , m_xFontsSubsetLB(m_xBuilder->weld_combo_box("fontsSubsetLB"))
1726 , m_xStyles(m_xBuilder->weld_combo_box("styles"))
1727 , m_xOldSymbolName(m_xBuilder->weld_label("oldSymbolName"))
1728 , m_xOldSymbolSetName(m_xBuilder->weld_label("oldSymbolSetName"))
1729 , m_xSymbolName(m_xBuilder->weld_label("symbolName"))
1730 , m_xSymbolSetName(m_xBuilder->weld_label("symbolSetName"))
1731 , m_xAddBtn(m_xBuilder->weld_button("add"))
1732 , m_xChangeBtn(m_xBuilder->weld_button("modify"))
1733 , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
1734 , m_xOldSymbolDisplay(new weld::CustomWeld(*m_xBuilder, "oldSymbolDisplay", m_aOldSymbolDisplay))
1735 , m_xSymbolDisplay(new weld::CustomWeld(*m_xBuilder, "symbolDisplay", m_aSymbolDisplay))
1736 , m_xCharsetDisplay(new SvxShowCharSet(m_xBuilder->weld_scrolled_window("showscroll"), m_xVirDev))
1737 , m_xCharsetDisplayArea(new weld::CustomWeld(*m_xBuilder, "charsetDisplay", *m_xCharsetDisplay))
1739 // auto completion is troublesome since that symbols character also gets automatically selected in the
1740 // display and if the user previously selected a character to define/redefine that one this is bad
1741 m_xOldSymbols->set_entry_completion(false);
1742 m_xSymbols->set_entry_completion(false);
1744 FillFonts();
1745 if (m_xFonts->get_count() > 0)
1746 SelectFont(m_xFonts->get_text(0));
1748 SetSymbolSetManager(m_rSymbolMgr);
1750 m_xOldSymbols->connect_changed(LINK(this, SmSymDefineDialog, OldSymbolChangeHdl));
1751 m_xOldSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, OldSymbolSetChangeHdl));
1752 m_xSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1753 m_xOldSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1754 m_xSymbols->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1755 m_xOldSymbols->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1756 m_xStyles->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
1757 m_xFonts->connect_changed(LINK(this, SmSymDefineDialog, FontChangeHdl));
1758 m_xFontsSubsetLB->connect_changed(LINK(this, SmSymDefineDialog, SubsetChangeHdl));
1759 m_xStyles->connect_changed(LINK(this, SmSymDefineDialog, StyleChangeHdl));
1760 m_xAddBtn->connect_clicked(LINK(this, SmSymDefineDialog, AddClickHdl));
1761 m_xChangeBtn->connect_clicked(LINK(this, SmSymDefineDialog, ChangeClickHdl));
1762 m_xDeleteBtn->connect_clicked(LINK(this, SmSymDefineDialog, DeleteClickHdl));
1763 m_xCharsetDisplay->SetHighlightHdl( LINK( this, SmSymDefineDialog, CharHighlightHdl ) );
1766 SmSymDefineDialog::~SmSymDefineDialog()
1770 short SmSymDefineDialog::run()
1772 short nResult = GenericDialogController::run();
1774 // apply changes if dialog was closed by clicking OK
1775 if (m_aSymbolMgrCopy.IsModified() && nResult == RET_OK)
1776 m_rSymbolMgr = m_aSymbolMgrCopy;
1778 return nResult;
1781 void SmSymDefineDialog::SetSymbolSetManager(const SmSymbolManager &rMgr)
1783 m_aSymbolMgrCopy = rMgr;
1785 // Set the modified flag of the copy to false so that
1786 // we can check later on if anything has been changed
1787 m_aSymbolMgrCopy.SetModified(false);
1789 FillSymbolSets(*m_xOldSymbolSets);
1790 if (m_xOldSymbolSets->get_count() > 0)
1791 SelectSymbolSet(m_xOldSymbolSets->get_text(0));
1792 FillSymbolSets(*m_xSymbolSets);
1793 if (m_xSymbolSets->get_count() > 0)
1794 SelectSymbolSet(m_xSymbolSets->get_text(0));
1795 FillSymbols(*m_xOldSymbols);
1796 if (m_xOldSymbols->get_count() > 0)
1797 SelectSymbol(m_xOldSymbols->get_text(0));
1798 FillSymbols(*m_xSymbols);
1799 if (m_xSymbols->get_count() > 0)
1800 SelectSymbol(m_xSymbols->get_text(0));
1802 UpdateButtons();
1805 bool SmSymDefineDialog::SelectSymbolSet(weld::ComboBox& rComboBox,
1806 const OUString &rSymbolSetName, bool bDeleteText)
1808 assert((&rComboBox == m_xOldSymbolSets.get() || &rComboBox == m_xSymbolSets.get()) && "Sm : wrong ComboBox");
1810 // trim SymbolName (no leading and trailing blanks)
1811 OUString aNormName = comphelper::string::stripStart(rSymbolSetName, ' ');
1812 aNormName = comphelper::string::stripEnd(aNormName, ' ');
1813 // and remove possible deviations within the input
1814 rComboBox.set_entry_text(aNormName);
1816 bool bRet = false;
1817 int nPos = rComboBox.find_text(aNormName);
1819 if (nPos != -1)
1821 rComboBox.set_active(nPos);
1822 bRet = true;
1824 else if (bDeleteText)
1825 rComboBox.set_entry_text(OUString());
1827 bool bIsOld = &rComboBox == m_xOldSymbolSets.get();
1829 // setting the SymbolSet name at the associated display
1830 weld::Label& rFT = bIsOld ? *m_xOldSymbolSetName : *m_xSymbolSetName;
1831 rFT.set_label(rComboBox.get_active_text());
1833 // set the symbol name which belongs to the SymbolSet at the associated combobox
1834 weld::ComboBox& rCB = bIsOld ? *m_xOldSymbols : *m_xSymbols;
1835 FillSymbols(rCB, false);
1837 // display a valid respectively no symbol when changing the SymbolSets
1838 if (bIsOld)
1840 OUString aTmpOldSymbolName;
1841 if (m_xOldSymbols->get_count() > 0)
1842 aTmpOldSymbolName = m_xOldSymbols->get_text(0);
1843 SelectSymbol(*m_xOldSymbols, aTmpOldSymbolName, true);
1846 UpdateButtons();
1848 return bRet;
1851 void SmSymDefineDialog::SetOrigSymbol(const SmSym *pSymbol,
1852 const OUString &rSymbolSetName)
1854 // clear old symbol
1855 m_xOrigSymbol.reset();
1857 OUString aSymName,
1858 aSymSetName;
1859 if (pSymbol)
1861 // set new symbol
1862 m_xOrigSymbol.reset(new SmSym(*pSymbol));
1864 aSymName = pSymbol->GetName();
1865 aSymSetName = rSymbolSetName;
1866 m_aOldSymbolDisplay.SetSymbol( pSymbol );
1868 else
1869 { // delete displayed symbols
1870 m_aOldSymbolDisplay.SetText(OUString());
1871 m_aOldSymbolDisplay.Invalidate();
1873 m_xOldSymbolName->set_label(aSymName);
1874 m_xOldSymbolSetName->set_label(aSymSetName);
1878 bool SmSymDefineDialog::SelectSymbol(weld::ComboBox& rComboBox,
1879 const OUString &rSymbolName, bool bDeleteText)
1881 assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong ComboBox");
1883 // trim SymbolName (no blanks)
1884 OUString aNormName = rSymbolName.replaceAll(" ", "");
1885 // and remove possible deviations within the input
1886 rComboBox.set_entry_text(aNormName);
1888 bool bRet = false;
1889 int nPos = rComboBox.find_text(aNormName);
1891 bool bIsOld = &rComboBox == m_xOldSymbols.get();
1893 if (nPos != -1)
1895 rComboBox.set_active(nPos);
1897 if (!bIsOld)
1899 const SmSym *pSymbol = GetSymbol(*m_xSymbols);
1900 if (pSymbol)
1902 // choose font and style accordingly
1903 const vcl::Font &rFont = pSymbol->GetFace();
1904 SelectFont(rFont.GetFamilyName(), false);
1905 SelectStyle(GetFontStyles().GetStyleName(rFont), false);
1907 // Since setting the Font via the Style name of the SymbolFonts doesn't
1908 // work really well (e.g. it can be empty even though the font itself is
1909 // bold or italic) we're manually setting the Font with respect to the Symbol
1910 m_xCharsetDisplay->SetFont(rFont);
1911 m_aSymbolDisplay.SetFont(rFont);
1913 // select associated character
1914 SelectChar(pSymbol->GetCharacter());
1916 // since SelectChar will also set the unicode point as text in the
1917 // symbols box, we have to set the symbol name again to get that one displayed
1918 m_xSymbols->set_entry_text(pSymbol->GetName());
1922 bRet = true;
1924 else if (bDeleteText)
1925 rComboBox.set_entry_text(OUString());
1927 if (bIsOld)
1929 // if there's a change of the old symbol, show only the available ones, otherwise show none
1930 const SmSym *pOldSymbol = nullptr;
1931 OUString aTmpOldSymbolSetName;
1932 if (nPos != -1)
1934 pOldSymbol = m_aSymbolMgrCopy.GetSymbolByName(aNormName);
1935 aTmpOldSymbolSetName = m_xOldSymbolSets->get_active_text();
1937 SetOrigSymbol(pOldSymbol, aTmpOldSymbolSetName);
1939 else
1940 m_xSymbolName->set_label(rComboBox.get_active_text());
1942 UpdateButtons();
1944 return bRet;
1948 void SmSymDefineDialog::SetFont(const OUString &rFontName, const OUString &rStyleName)
1950 // get Font (FontInfo) matching name and style
1951 FontMetric aFontMetric;
1952 if (m_xFontList)
1953 aFontMetric = m_xFontList->Get(rFontName, WEIGHT_NORMAL, ITALIC_NONE);
1954 SetFontStyle(rStyleName, aFontMetric);
1956 m_xCharsetDisplay->SetFont(aFontMetric);
1957 m_aSymbolDisplay.SetFont(aFontMetric);
1959 // update subset listbox for new font's unicode subsets
1960 FontCharMapRef xFontCharMap = m_xCharsetDisplay->GetFontCharMap();
1961 m_xSubsetMap.reset(new SubsetMap( xFontCharMap ));
1963 m_xFontsSubsetLB->clear();
1964 bool bFirst = true;
1965 for (auto & subset : m_xSubsetMap->GetSubsetMap())
1967 m_xFontsSubsetLB->append(OUString::number(reinterpret_cast<sal_uInt64>(&subset)), subset.GetName());
1968 // subset must live at least as long as the selected font !!!
1969 if (bFirst)
1970 m_xFontsSubsetLB->set_active(0);
1971 bFirst = false;
1973 if (bFirst)
1974 m_xFontsSubsetLB->set_active(-1);
1975 m_xFontsSubsetLB->set_sensitive(!bFirst);
1978 bool SmSymDefineDialog::SelectFont(const OUString &rFontName, bool bApplyFont)
1980 bool bRet = false;
1981 int nPos = m_xFonts->find_text(rFontName);
1983 if (nPos != -1)
1985 m_xFonts->set_active(nPos);
1986 if (m_xStyles->get_count() > 0)
1987 SelectStyle(m_xStyles->get_text(0));
1988 if (bApplyFont)
1990 SetFont(m_xFonts->get_active_text(), m_xStyles->get_active_text());
1991 m_aSymbolDisplay.SetSymbol(m_xCharsetDisplay->GetSelectCharacter(), m_xCharsetDisplay->GetFont());
1993 bRet = true;
1995 else
1996 m_xFonts->set_active(-1);
1997 FillStyles();
1999 UpdateButtons();
2001 return bRet;
2005 bool SmSymDefineDialog::SelectStyle(const OUString &rStyleName, bool bApplyFont)
2007 bool bRet = false;
2008 int nPos = m_xStyles->find_text(rStyleName);
2010 // if the style is not available take the first available one (if existent)
2011 if (nPos == -1 && m_xStyles->get_count() > 0)
2012 nPos = 0;
2014 if (nPos != -1)
2016 m_xStyles->set_active(nPos);
2017 if (bApplyFont)
2019 SetFont(m_xFonts->get_active_text(), m_xStyles->get_active_text());
2020 m_aSymbolDisplay.SetSymbol(m_xCharsetDisplay->GetSelectCharacter(), m_xCharsetDisplay->GetFont());
2022 bRet = true;
2024 else
2025 m_xStyles->set_entry_text(OUString());
2027 UpdateButtons();
2029 return bRet;
2032 void SmSymDefineDialog::SelectChar(sal_Unicode cChar)
2034 m_xCharsetDisplay->SelectCharacter( cChar );
2035 m_aSymbolDisplay.SetSymbol(cChar, m_xCharsetDisplay->GetFont());
2037 UpdateButtons();
2040 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */