As mentioned for Math's "Format" -> "Spacing" dialog in previous commit Change-Id: I3018c5a76cd863332ac8560a926105ae76327a38 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Fri Apr 11 10:31:09 2025 +0200 tdf#130857 qt weld: Support Math's "Spacing" dialog for the case of using native widgets with the qt6 VCL plugin: > Currently, the image isn't always updated when choosing > a different category via "Category" menu button. This > will be addressed in a separate commit. For some reason (not further analyzed so far), no QApplication::focusChanged signal gets emitted (that would then trigger the slot in QtInstanceWidget::applicationFocusChanged) for the following scenario: * start Math with the qt6 VCL plugin and environment variable SAL_VCL_QT_USE_WELDED_WIDGETS=1 set * open the "Format" -> "Spacing" dialog * while the focus is still on the "Spacing" spinbox, click the "Category" menu button and select another category, e.g. "Operators" The problem cannot be observed when first moving focus away from the "Spacing" spinbox. To make sure the image gets updated, explicitly call the SmDistanceDialog::SetCategory Call the `GetFocusHdl` handler in SmDistanceDialog::SetCategory after setting focus to the spinbutton which makes this work for the case of using native widgets with qt6 as well. Change-Id: Ia4a1389a014f22c9c1665093321b231838ad1215 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184026 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2175 lines
78 KiB
C++
2175 lines
78 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
#include <sal/log.hxx>
|
|
|
|
#include <comphelper/string.hxx>
|
|
#include <o3tl/temporary.hxx>
|
|
#include <svl/eitem.hxx>
|
|
#include <svl/intitem.hxx>
|
|
#include <svl/stritem.hxx>
|
|
#include <vcl/event.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/virdev.hxx>
|
|
#include <vcl/weld.hxx>
|
|
#include <svtools/ctrltool.hxx>
|
|
#include <vcl/settings.hxx>
|
|
#include <vcl/wall.hxx>
|
|
#include <vcl/fontcharmap.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <svx/charmap.hxx>
|
|
#include <svx/ucsubset.hxx>
|
|
|
|
#include <dialog.hxx>
|
|
#include <starmath.hrc>
|
|
#include <strings.hrc>
|
|
#include <helpids.h>
|
|
#include <cfgitem.hxx>
|
|
#include <officecfg/Office/Math.hxx>
|
|
#include <smmod.hxx>
|
|
#include <symbol.hxx>
|
|
#include <view.hxx>
|
|
|
|
#include <algorithm>
|
|
|
|
namespace
|
|
{
|
|
|
|
void lclGetSettingColors(Color& rBackgroundColor, Color& rTextColor)
|
|
{
|
|
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
|
|
if (rStyleSettings.GetHighContrastMode())
|
|
{
|
|
rBackgroundColor = rStyleSettings.GetFieldColor();
|
|
rTextColor = rStyleSettings.GetFieldTextColor();
|
|
}
|
|
else
|
|
{
|
|
rBackgroundColor = rStyleSettings.GetFaceColor();
|
|
rTextColor = rStyleSettings.GetLabelTextColor();
|
|
}
|
|
}
|
|
|
|
// Since it's better to set/query the FontStyle via its attributes rather
|
|
// than via the StyleName we create a way to translate
|
|
// Attribute <-> StyleName
|
|
|
|
class SmFontStyles
|
|
{
|
|
OUString aNormal;
|
|
OUString aBold;
|
|
OUString aItalic;
|
|
OUString aBoldItalic;
|
|
|
|
public:
|
|
SmFontStyles();
|
|
|
|
static sal_uInt16 GetCount() { return 4; }
|
|
const OUString& GetStyleName(const vcl::Font& rFont) const;
|
|
const OUString& GetStyleName(sal_uInt16 nIdx) const;
|
|
};
|
|
|
|
vcl::Font lclGetSymbolFont(const SmViewShell& rViewShell, const SmSym &rSymbol)
|
|
{
|
|
const SmDocShell* pDoc = rViewShell.GetDoc();
|
|
if (pDoc)
|
|
{
|
|
// If we have a document, we want to render the symbol using the font and style used in
|
|
// the document, so we do that by creating a node and preparing it, then get the resolved
|
|
// font and style from it.
|
|
SmToken token(TSPECIAL, '\0', "%" + rSymbol.GetUiName());
|
|
SmSpecialNode aNode(token);
|
|
aNode.Prepare(pDoc->GetFormat(), *pDoc, 1);
|
|
aNode.PrepareAttributes();
|
|
return aNode.GetFont();
|
|
}
|
|
|
|
return rSymbol.GetFace();
|
|
}
|
|
|
|
} // end anonymous namespace
|
|
|
|
SmFontStyles::SmFontStyles()
|
|
: aNormal(SmResId(RID_FONTREGULAR))
|
|
, aBold(SmResId(RID_FONTBOLD))
|
|
, aItalic(SmResId(RID_FONTITALIC))
|
|
{
|
|
aBoldItalic = aBold;
|
|
aBoldItalic += ", ";
|
|
aBoldItalic += aItalic;
|
|
}
|
|
|
|
const OUString& SmFontStyles::GetStyleName(const vcl::Font& rFont) const
|
|
{
|
|
//! compare also SmSpecialNode::Prepare
|
|
bool bBold = IsBold( rFont ),
|
|
bItalic = IsItalic( rFont );
|
|
|
|
if (bBold && bItalic)
|
|
return aBoldItalic;
|
|
else if (bItalic)
|
|
return aItalic;
|
|
else if (bBold)
|
|
return aBold;
|
|
return aNormal;
|
|
}
|
|
|
|
const OUString& SmFontStyles::GetStyleName( sal_uInt16 nIdx ) const
|
|
{
|
|
// 0 = "normal", 1 = "italic",
|
|
// 2 = "bold", 3 = "bold italic"
|
|
|
|
assert( nIdx < GetCount() );
|
|
switch (nIdx)
|
|
{
|
|
case 0 : return aNormal;
|
|
case 1 : return aItalic;
|
|
case 2 : return aBold;
|
|
default: /*case 3:*/ return aBoldItalic;
|
|
}
|
|
}
|
|
|
|
static const SmFontStyles & GetFontStyles()
|
|
{
|
|
static const SmFontStyles aImpl;
|
|
return aImpl;
|
|
}
|
|
|
|
void SetFontStyle(std::u16string_view rStyleName, vcl::Font &rFont)
|
|
{
|
|
// Find index related to StyleName. For an empty StyleName it's assumed to be
|
|
// 0 (neither bold nor italic).
|
|
sal_uInt16 nIndex = 0;
|
|
if (!rStyleName.empty())
|
|
{
|
|
sal_uInt16 i;
|
|
const SmFontStyles &rStyles = GetFontStyles();
|
|
for (i = 0; i < SmFontStyles::GetCount(); ++i)
|
|
if (rStyleName == rStyles.GetStyleName(i))
|
|
break;
|
|
assert(i < SmFontStyles::GetCount() && "style-name unknown");
|
|
nIndex = i;
|
|
}
|
|
|
|
rFont.SetItalic((nIndex & 0x1) ? ITALIC_NORMAL : ITALIC_NONE);
|
|
rFont.SetWeight((nIndex & 0x2) ? WEIGHT_BOLD : WEIGHT_NORMAL);
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SmPrintOptionsTabPage, SizeButtonClickHdl, weld::Toggleable&, void)
|
|
{
|
|
m_xZoom->set_sensitive(m_xSizeZoomed->get_active());
|
|
}
|
|
|
|
SmPrintOptionsTabPage::SmPrintOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rOptions)
|
|
: SfxTabPage(pPage, pController, u"modules/smath/ui/smathsettings.ui"_ustr, u"SmathSettings"_ustr, &rOptions)
|
|
, m_xTitle(m_xBuilder->weld_check_button(u"title"_ustr))
|
|
, m_xTitleImg(m_xBuilder->weld_widget(u"locktitle"_ustr))
|
|
, m_xText(m_xBuilder->weld_check_button(u"text"_ustr))
|
|
, m_xTextImg(m_xBuilder->weld_widget(u"locktext"_ustr))
|
|
, m_xFrame(m_xBuilder->weld_check_button(u"frame"_ustr))
|
|
, m_xFrameImg(m_xBuilder->weld_widget(u"lockframe"_ustr))
|
|
, m_xSizeNormal(m_xBuilder->weld_radio_button(u"sizenormal"_ustr))
|
|
, m_xSizeScaled(m_xBuilder->weld_radio_button(u"sizescaled"_ustr))
|
|
, m_xSizeZoomed(m_xBuilder->weld_radio_button(u"sizezoomed"_ustr))
|
|
, m_xLockPrintImg(m_xBuilder->weld_widget(u"lockprintformat"_ustr))
|
|
, m_xZoom(m_xBuilder->weld_metric_spin_button(u"zoom"_ustr, FieldUnit::PERCENT))
|
|
, m_xEnableInlineEdit(m_xBuilder->weld_check_button(u"enableinlineedit"_ustr))
|
|
, m_xEnableInlineEditImg(m_xBuilder->weld_widget(u"lockenableinlineedit"_ustr))
|
|
, m_xNoRightSpaces(m_xBuilder->weld_check_button(u"norightspaces"_ustr))
|
|
, m_xNoRightSpacesImg(m_xBuilder->weld_widget(u"locknorightspaces"_ustr))
|
|
, m_xSaveOnlyUsedSymbols(m_xBuilder->weld_check_button(u"saveonlyusedsymbols"_ustr))
|
|
, m_xSaveOnlyUsedSymbolsImg(m_xBuilder->weld_widget(u"locksaveonlyusedsymbols"_ustr))
|
|
, m_xAutoCloseBrackets(m_xBuilder->weld_check_button(u"autoclosebrackets"_ustr))
|
|
, m_xAutoCloseBracketsImg(m_xBuilder->weld_widget(u"lockautoclosebrackets"_ustr))
|
|
, m_xSmZoom(m_xBuilder->weld_metric_spin_button(u"smzoom"_ustr, FieldUnit::PERCENT))
|
|
, m_xSmZoomImg(m_xBuilder->weld_widget(u"locksmzoom"_ustr))
|
|
{
|
|
m_xSizeNormal->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
|
|
m_xSizeScaled->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
|
|
m_xSizeZoomed->connect_toggled(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
|
|
|
|
Reset(&rOptions);
|
|
}
|
|
|
|
SmPrintOptionsTabPage::~SmPrintOptionsTabPage()
|
|
{
|
|
if (SmViewShell *pViewSh = SmGetActiveView())
|
|
if (SmEditWindow* pEdit = pViewSh->GetEditWindow())
|
|
pEdit->UpdateStatus();
|
|
}
|
|
|
|
OUString SmPrintOptionsTabPage::GetAllStrings()
|
|
{
|
|
OUString sAllStrings;
|
|
OUString labels[] = { u"label4"_ustr, u"label5"_ustr, u"label1"_ustr, u"label6"_ustr };
|
|
|
|
for (const auto& label : labels)
|
|
{
|
|
if (const auto pString = m_xBuilder->weld_label(label))
|
|
sAllStrings += pString->get_label() + " ";
|
|
}
|
|
|
|
OUString checkButton[]
|
|
= { u"title"_ustr, u"text"_ustr, u"frame"_ustr, u"norightspaces"_ustr, u"saveonlyusedsymbols"_ustr, u"autoclosebrackets"_ustr };
|
|
|
|
for (const auto& check : checkButton)
|
|
{
|
|
if (const auto pString = m_xBuilder->weld_check_button(check))
|
|
sAllStrings += pString->get_label() + " ";
|
|
}
|
|
|
|
OUString radioButton[] = { u"sizenormal"_ustr, u"sizescaled"_ustr, u"sizezoomed"_ustr };
|
|
|
|
for (const auto& radio : radioButton)
|
|
{
|
|
if (const auto pString = m_xBuilder->weld_radio_button(radio))
|
|
sAllStrings += pString->get_label() + " ";
|
|
}
|
|
|
|
return sAllStrings.replaceAll("_", "");
|
|
}
|
|
|
|
bool SmPrintOptionsTabPage::FillItemSet(SfxItemSet* rSet)
|
|
{
|
|
sal_uInt16 nPrintSize;
|
|
if (m_xSizeNormal->get_active())
|
|
nPrintSize = PRINT_SIZE_NORMAL;
|
|
else if (m_xSizeScaled->get_active())
|
|
nPrintSize = PRINT_SIZE_SCALED;
|
|
else
|
|
nPrintSize = PRINT_SIZE_ZOOMED;
|
|
|
|
rSet->Put(SfxUInt16Item(SID_PRINTSIZE, nPrintSize));
|
|
rSet->Put(SfxUInt16Item(SID_PRINTZOOM, sal::static_int_cast<sal_uInt16>(m_xZoom->get_value(FieldUnit::PERCENT))));
|
|
rSet->Put(SfxBoolItem(SID_PRINTTITLE, m_xTitle->get_active()));
|
|
rSet->Put(SfxBoolItem(SID_PRINTTEXT, m_xText->get_active()));
|
|
rSet->Put(SfxBoolItem(SID_PRINTFRAME, m_xFrame->get_active()));
|
|
rSet->Put(SfxBoolItem(SID_INLINE_EDIT_ENABLE, m_xEnableInlineEdit->get_active()));
|
|
rSet->Put(SfxBoolItem(SID_NO_RIGHT_SPACES, m_xNoRightSpaces->get_active()));
|
|
rSet->Put(SfxBoolItem(SID_SAVE_ONLY_USED_SYMBOLS, m_xSaveOnlyUsedSymbols->get_active()));
|
|
rSet->Put(SfxBoolItem(SID_AUTO_CLOSE_BRACKETS, m_xAutoCloseBrackets->get_active()));
|
|
rSet->Put(SfxUInt16Item(SID_SMEDITWINDOWZOOM, sal::static_int_cast<sal_uInt16>(m_xSmZoom->get_value(FieldUnit::PERCENT))));
|
|
|
|
if (SmViewShell *pViewSh = SmGetActiveView())
|
|
if (SmEditWindow* pEdit = pViewSh->GetEditWindow())
|
|
pEdit->UpdateStatus();
|
|
|
|
return true;
|
|
}
|
|
|
|
void SmPrintOptionsTabPage::Reset(const SfxItemSet* rSet)
|
|
{
|
|
SmPrintSize ePrintSize = static_cast<SmPrintSize>(rSet->Get(SID_PRINTSIZE).GetValue());
|
|
|
|
m_xSizeNormal->set_active(ePrintSize == PRINT_SIZE_NORMAL);
|
|
m_xSizeScaled->set_active(ePrintSize == PRINT_SIZE_SCALED);
|
|
m_xSizeZoomed->set_active(ePrintSize == PRINT_SIZE_ZOOMED);
|
|
bool bReadOnly = officecfg::Office::Math::Print::Size::isReadOnly();
|
|
if (bReadOnly)
|
|
{
|
|
m_xSizeNormal->set_sensitive(false);
|
|
m_xSizeScaled->set_sensitive(false);
|
|
m_xSizeZoomed->set_sensitive(false);
|
|
m_xLockPrintImg->set_visible(true);
|
|
}
|
|
|
|
bReadOnly = officecfg::Office::Math::Print::ZoomFactor::isReadOnly();
|
|
m_xZoom->set_value(rSet->Get(SID_PRINTZOOM).GetValue(), FieldUnit::PERCENT);
|
|
m_xZoom->set_sensitive(m_xSizeZoomed->get_active() && !bReadOnly);
|
|
|
|
bReadOnly = officecfg::Office::Math::Misc::SmEditWindowZoomFactor::isReadOnly();
|
|
m_xSmZoom->set_value(rSet->Get(SID_SMEDITWINDOWZOOM).GetValue(), FieldUnit::PERCENT);
|
|
m_xSmZoom->set_sensitive(!bReadOnly);
|
|
m_xSmZoomImg->set_visible(bReadOnly);
|
|
|
|
bReadOnly = officecfg::Office::Math::Print::Title::isReadOnly();
|
|
m_xTitle->set_active(rSet->Get(SID_PRINTTITLE).GetValue());
|
|
m_xTitle->set_sensitive(!bReadOnly);
|
|
m_xTitleImg->set_visible(bReadOnly);
|
|
|
|
bReadOnly = officecfg::Office::Math::Print::FormulaText::isReadOnly();
|
|
m_xText->set_active(rSet->Get(GetWhich(SID_PRINTTEXT)).GetValue());
|
|
m_xText->set_sensitive(!bReadOnly);
|
|
m_xTextImg->set_visible(bReadOnly);
|
|
|
|
bReadOnly = officecfg::Office::Math::Print::Frame::isReadOnly();
|
|
m_xFrame->set_active(rSet->Get(GetWhich(SID_PRINTFRAME)).GetValue());
|
|
m_xFrame->set_sensitive(!bReadOnly);
|
|
m_xFrameImg->set_visible(bReadOnly);
|
|
|
|
bReadOnly = officecfg::Office::Math::Misc::InlineEditEnable::isReadOnly();
|
|
m_xEnableInlineEdit->set_active(rSet->Get(SID_INLINE_EDIT_ENABLE).GetValue());
|
|
m_xEnableInlineEdit->set_sensitive(!bReadOnly);
|
|
m_xEnableInlineEditImg->set_visible(bReadOnly);
|
|
|
|
bReadOnly = officecfg::Office::Math::Misc::IgnoreSpacesRight::isReadOnly();
|
|
m_xNoRightSpaces->set_active(rSet->Get(SID_NO_RIGHT_SPACES).GetValue());
|
|
m_xNoRightSpaces->set_sensitive(!bReadOnly);
|
|
m_xNoRightSpacesImg->set_visible(bReadOnly);
|
|
|
|
bReadOnly = officecfg::Office::Math::LoadSave::IsSaveOnlyUsedSymbols::isReadOnly();
|
|
m_xSaveOnlyUsedSymbols->set_active(rSet->Get(SID_SAVE_ONLY_USED_SYMBOLS).GetValue());
|
|
m_xSaveOnlyUsedSymbols->set_sensitive(!bReadOnly);
|
|
m_xSaveOnlyUsedSymbolsImg->set_visible(bReadOnly);
|
|
|
|
bReadOnly = officecfg::Office::Math::Misc::AutoCloseBrackets::isReadOnly();
|
|
m_xAutoCloseBrackets->set_active(rSet->Get(SID_AUTO_CLOSE_BRACKETS).GetValue());
|
|
m_xAutoCloseBrackets->set_sensitive(!bReadOnly);
|
|
m_xAutoCloseBracketsImg->set_visible(bReadOnly);
|
|
}
|
|
|
|
std::unique_ptr<SfxTabPage> SmPrintOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
|
|
{
|
|
return std::make_unique<SmPrintOptionsTabPage>(pPage, pController, rSet);
|
|
}
|
|
|
|
void SmShowFont::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
|
|
{
|
|
Color aBackColor;
|
|
Color aTextColor;
|
|
lclGetSettingColors(aBackColor, aTextColor);
|
|
|
|
rRenderContext.SetBackground(Wallpaper(aBackColor));
|
|
|
|
vcl::Font aFont(maFont);
|
|
aFont.SetFontSize(Size(0, 24 * rRenderContext.GetDPIScaleFactor()));
|
|
aFont.SetAlignment(ALIGN_TOP);
|
|
rRenderContext.SetFont(aFont);
|
|
rRenderContext.SetTextColor(aTextColor);
|
|
|
|
OUString sText(rRenderContext.GetFont().GetFamilyName());
|
|
Size aTextSize(rRenderContext.GetTextWidth(sText), rRenderContext.GetTextHeight());
|
|
|
|
rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
|
|
(rRenderContext.GetOutputSize().Height() - aTextSize.Height()) / 2), sText);
|
|
}
|
|
|
|
void SmShowFont::SetDrawingArea(weld::DrawingArea* pDrawingArea)
|
|
{
|
|
CustomWidgetController::SetDrawingArea(pDrawingArea);
|
|
Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(111 , 31), MapMode(MapUnit::MapAppFont)));
|
|
pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
|
|
}
|
|
|
|
void SmShowFont::SetFont(const vcl::Font& rFont)
|
|
{
|
|
maFont = rFont;
|
|
Invalidate();
|
|
}
|
|
|
|
IMPL_LINK( SmFontDialog, FontSelectHdl, weld::ComboBox&, rComboBox, void )
|
|
{
|
|
maFont.SetFamilyName(rComboBox.get_active_text());
|
|
m_aShowFont.SetFont(maFont);
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SmFontDialog, AttrChangeHdl, weld::Toggleable&, void)
|
|
{
|
|
if (m_xBoldCheckBox->get_active())
|
|
maFont.SetWeight(WEIGHT_BOLD);
|
|
else
|
|
maFont.SetWeight(WEIGHT_NORMAL);
|
|
|
|
if (m_xItalicCheckBox->get_active())
|
|
maFont.SetItalic(ITALIC_NORMAL);
|
|
else
|
|
maFont.SetItalic(ITALIC_NONE);
|
|
|
|
m_aShowFont.SetFont(maFont);
|
|
}
|
|
|
|
void SmFontDialog::SetFont(const vcl::Font &rFont)
|
|
{
|
|
maFont = rFont;
|
|
|
|
m_xFontBox->set_active_text(maFont.GetFamilyName());
|
|
m_xBoldCheckBox->set_active(IsBold(maFont));
|
|
m_xItalicCheckBox->set_active(IsItalic(maFont));
|
|
m_aShowFont.SetFont(maFont);
|
|
}
|
|
|
|
SmFontDialog::SmFontDialog(weld::Window * pParent, OutputDevice *pFntListDevice, bool bHideCheckboxes)
|
|
: GenericDialogController(pParent, u"modules/smath/ui/fontdialog.ui"_ustr, u"FontDialog"_ustr)
|
|
, m_xFontBox(m_xBuilder->weld_entry_tree_view(u"fontgrid"_ustr, u"font"_ustr, u"fonts"_ustr))
|
|
, m_xAttrFrame(m_xBuilder->weld_widget(u"attrframe"_ustr))
|
|
, m_xBoldCheckBox(m_xBuilder->weld_check_button(u"bold"_ustr))
|
|
, m_xItalicCheckBox(m_xBuilder->weld_check_button(u"italic"_ustr))
|
|
, m_xShowFont(new weld::CustomWeld(*m_xBuilder, u"preview"_ustr, m_aShowFont))
|
|
{
|
|
m_xFontBox->set_height_request_by_rows(8);
|
|
|
|
{
|
|
weld::WaitObject aWait(pParent);
|
|
|
|
FontList aFontList( pFntListDevice );
|
|
|
|
sal_uInt16 nCount = aFontList.GetFontNameCount();
|
|
for (sal_uInt16 i = 0; i < nCount; ++i)
|
|
{
|
|
m_xFontBox->append_text(aFontList.GetFontName(i).GetFamilyName());
|
|
}
|
|
maFont.SetFontSize(Size(0, 24));
|
|
maFont.SetWeight(WEIGHT_NORMAL);
|
|
maFont.SetItalic(ITALIC_NONE);
|
|
maFont.SetFamily(FAMILY_DONTKNOW);
|
|
maFont.SetPitch(PITCH_DONTKNOW);
|
|
maFont.SetCharSet(RTL_TEXTENCODING_DONTKNOW);
|
|
maFont.SetTransparent(true);
|
|
}
|
|
|
|
m_xFontBox->connect_changed(LINK(this, SmFontDialog, FontSelectHdl));
|
|
m_xBoldCheckBox->connect_toggled(LINK(this, SmFontDialog, AttrChangeHdl));
|
|
m_xItalicCheckBox->connect_toggled(LINK(this, SmFontDialog, AttrChangeHdl));
|
|
|
|
if (bHideCheckboxes)
|
|
{
|
|
m_xBoldCheckBox->set_active(false);
|
|
m_xBoldCheckBox->set_sensitive(false);
|
|
m_xItalicCheckBox->set_active(false);
|
|
m_xItalicCheckBox->set_sensitive(false);
|
|
m_xAttrFrame->hide();
|
|
}
|
|
}
|
|
|
|
SmFontDialog::~SmFontDialog()
|
|
{
|
|
}
|
|
|
|
namespace {
|
|
|
|
class SaveDefaultsQuery : public weld::MessageDialogController
|
|
{
|
|
public:
|
|
explicit SaveDefaultsQuery(weld::Widget* pParent)
|
|
: MessageDialogController(pParent, u"modules/smath/ui/savedefaultsdialog.ui"_ustr,
|
|
u"SaveDefaultsDialog"_ustr)
|
|
{
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SmFontSizeDialog, DefaultButtonClickHdl, weld::Button&, void )
|
|
{
|
|
SaveDefaultsQuery aQuery(m_xDialog.get());
|
|
if (aQuery.run() == RET_YES)
|
|
{
|
|
auto* config = SmModule::get()->GetConfig();
|
|
SmFormat aFmt(config->GetStandardFormat());
|
|
WriteTo( aFmt );
|
|
config->SetStandardFormat(aFmt);
|
|
}
|
|
}
|
|
|
|
SmFontSizeDialog::SmFontSizeDialog(weld::Window* pParent)
|
|
: GenericDialogController(pParent, u"modules/smath/ui/fontsizedialog.ui"_ustr, u"FontSizeDialog"_ustr)
|
|
, m_xBaseSize(m_xBuilder->weld_metric_spin_button(u"spinB_baseSize"_ustr, FieldUnit::POINT))
|
|
, m_xTextSize(m_xBuilder->weld_metric_spin_button(u"spinB_text"_ustr, FieldUnit::PERCENT))
|
|
, m_xIndexSize(m_xBuilder->weld_metric_spin_button(u"spinB_index"_ustr, FieldUnit::PERCENT))
|
|
, m_xFunctionSize(m_xBuilder->weld_metric_spin_button(u"spinB_function"_ustr, FieldUnit::PERCENT))
|
|
, m_xOperatorSize(m_xBuilder->weld_metric_spin_button(u"spinB_operator"_ustr, FieldUnit::PERCENT))
|
|
, m_xBorderSize(m_xBuilder->weld_metric_spin_button(u"spinB_limit"_ustr, FieldUnit::PERCENT))
|
|
, m_xDefaultButton(m_xBuilder->weld_button(u"default"_ustr))
|
|
{
|
|
m_xDefaultButton->connect_clicked(LINK(this, SmFontSizeDialog, DefaultButtonClickHdl));
|
|
}
|
|
|
|
SmFontSizeDialog::~SmFontSizeDialog()
|
|
{
|
|
}
|
|
|
|
void SmFontSizeDialog::ReadFrom(const SmFormat &rFormat)
|
|
{
|
|
//! watch out: round properly!
|
|
m_xBaseSize->set_value(
|
|
o3tl::convert(rFormat.GetBaseSize().Height(), SmO3tlLengthUnit(), o3tl::Length::pt),
|
|
FieldUnit::NONE);
|
|
|
|
m_xTextSize->set_value( rFormat.GetRelSize(SIZ_TEXT), FieldUnit::NONE );
|
|
m_xIndexSize->set_value( rFormat.GetRelSize(SIZ_INDEX), FieldUnit::NONE );
|
|
m_xFunctionSize->set_value( rFormat.GetRelSize(SIZ_FUNCTION), FieldUnit::NONE );
|
|
m_xOperatorSize->set_value( rFormat.GetRelSize(SIZ_OPERATOR), FieldUnit::NONE );
|
|
m_xBorderSize->set_value( rFormat.GetRelSize(SIZ_LIMITS), FieldUnit::NONE );
|
|
}
|
|
|
|
void SmFontSizeDialog::WriteTo(SmFormat &rFormat) const
|
|
{
|
|
rFormat.SetBaseSize( Size(0, o3tl::convert(m_xBaseSize->get_value(FieldUnit::NONE), o3tl::Length::pt, SmO3tlLengthUnit())) );
|
|
|
|
rFormat.SetRelSize(SIZ_TEXT, sal::static_int_cast<sal_uInt16>(m_xTextSize->get_value(FieldUnit::NONE)));
|
|
rFormat.SetRelSize(SIZ_INDEX, sal::static_int_cast<sal_uInt16>(m_xIndexSize->get_value(FieldUnit::NONE)));
|
|
rFormat.SetRelSize(SIZ_FUNCTION, sal::static_int_cast<sal_uInt16>(m_xFunctionSize->get_value(FieldUnit::NONE)));
|
|
rFormat.SetRelSize(SIZ_OPERATOR, sal::static_int_cast<sal_uInt16>(m_xOperatorSize->get_value(FieldUnit::NONE)));
|
|
rFormat.SetRelSize(SIZ_LIMITS, sal::static_int_cast<sal_uInt16>(m_xBorderSize->get_value(FieldUnit::NONE)));
|
|
|
|
const Size aTmp (rFormat.GetBaseSize());
|
|
for (sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++)
|
|
rFormat.SetFontSize(i, aTmp);
|
|
|
|
rFormat.RequestApplyChanges();
|
|
}
|
|
|
|
IMPL_LINK(SmFontTypeDialog, MenuSelectHdl, const OUString&, rIdent, void)
|
|
{
|
|
SmFontPickListBox *pActiveListBox;
|
|
|
|
bool bHideCheckboxes = false;
|
|
if (rIdent == "math")
|
|
pActiveListBox = m_xMathFont.get();
|
|
else if (rIdent == "variables")
|
|
pActiveListBox = m_xVariableFont.get();
|
|
else if (rIdent == "functions")
|
|
pActiveListBox = m_xFunctionFont.get();
|
|
else if (rIdent == "numbers")
|
|
pActiveListBox = m_xNumberFont.get();
|
|
else if (rIdent == "text")
|
|
pActiveListBox = m_xTextFont.get();
|
|
else if (rIdent == "serif")
|
|
{
|
|
pActiveListBox = m_xSerifFont.get();
|
|
bHideCheckboxes = true;
|
|
}
|
|
else if (rIdent == "sansserif")
|
|
{
|
|
pActiveListBox = m_xSansFont.get();
|
|
bHideCheckboxes = true;
|
|
}
|
|
else if (rIdent == "fixedwidth")
|
|
{
|
|
pActiveListBox = m_xFixedFont.get();
|
|
bHideCheckboxes = true;
|
|
}
|
|
else
|
|
pActiveListBox = nullptr;
|
|
|
|
if (pActiveListBox)
|
|
{
|
|
SmFontDialog aFontDialog(m_xDialog.get(), pFontListDev, bHideCheckboxes);
|
|
|
|
pActiveListBox->WriteTo(aFontDialog);
|
|
if (aFontDialog.run() == RET_OK)
|
|
pActiveListBox->ReadFrom(aFontDialog);
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SmFontTypeDialog, DefaultButtonClickHdl, weld::Button&, void)
|
|
{
|
|
SaveDefaultsQuery aQuery(m_xDialog.get());
|
|
if (aQuery.run() == RET_YES)
|
|
{
|
|
auto* config = SmModule::get()->GetConfig();
|
|
SmFormat aFmt(config->GetStandardFormat());
|
|
WriteTo( aFmt );
|
|
config->SetStandardFormat(aFmt, true);
|
|
}
|
|
}
|
|
|
|
SmFontTypeDialog::SmFontTypeDialog(weld::Window* pParent, OutputDevice *pFntListDevice)
|
|
: GenericDialogController(pParent, u"modules/smath/ui/fonttypedialog.ui"_ustr, u"FontsDialog"_ustr)
|
|
, pFontListDev(pFntListDevice)
|
|
, m_xMathFont(new SmFontPickListBox(m_xBuilder->weld_combo_box(u"mathCB"_ustr)))
|
|
, m_xVariableFont(new SmFontPickListBox(m_xBuilder->weld_combo_box(u"variableCB"_ustr)))
|
|
, m_xFunctionFont(new SmFontPickListBox(m_xBuilder->weld_combo_box(u"functionCB"_ustr)))
|
|
, m_xNumberFont(new SmFontPickListBox(m_xBuilder->weld_combo_box(u"numberCB"_ustr)))
|
|
, m_xTextFont(new SmFontPickListBox(m_xBuilder->weld_combo_box(u"textCB"_ustr)))
|
|
, m_xSerifFont(new SmFontPickListBox(m_xBuilder->weld_combo_box(u"serifCB"_ustr)))
|
|
, m_xSansFont(new SmFontPickListBox(m_xBuilder->weld_combo_box(u"sansCB"_ustr)))
|
|
, m_xFixedFont(new SmFontPickListBox(m_xBuilder->weld_combo_box(u"fixedCB"_ustr)))
|
|
, m_xMenuButton(m_xBuilder->weld_menu_button(u"modify"_ustr))
|
|
, m_xDefaultButton(m_xBuilder->weld_button(u"default"_ustr))
|
|
{
|
|
m_xDefaultButton->connect_clicked(LINK(this, SmFontTypeDialog, DefaultButtonClickHdl));
|
|
m_xMenuButton->connect_selected(LINK(this, SmFontTypeDialog, MenuSelectHdl));
|
|
}
|
|
|
|
SmFontTypeDialog::~SmFontTypeDialog()
|
|
{
|
|
}
|
|
|
|
void SmFontTypeDialog::ReadFrom(const SmFormat &rFormat)
|
|
{
|
|
auto* config = SmModule::get()->GetConfig();
|
|
|
|
*m_xMathFont = config->GetFontPickList(FNT_MATH);
|
|
*m_xVariableFont = config->GetFontPickList(FNT_VARIABLE);
|
|
*m_xFunctionFont = config->GetFontPickList(FNT_FUNCTION);
|
|
*m_xNumberFont = config->GetFontPickList(FNT_NUMBER);
|
|
*m_xTextFont = config->GetFontPickList(FNT_TEXT);
|
|
*m_xSerifFont = config->GetFontPickList(FNT_SERIF);
|
|
*m_xSansFont = config->GetFontPickList(FNT_SANS);
|
|
*m_xFixedFont = config->GetFontPickList(FNT_FIXED);
|
|
|
|
m_xMathFont->Insert( rFormat.GetFont(FNT_MATH) );
|
|
m_xVariableFont->Insert( rFormat.GetFont(FNT_VARIABLE) );
|
|
m_xFunctionFont->Insert( rFormat.GetFont(FNT_FUNCTION) );
|
|
m_xNumberFont->Insert( rFormat.GetFont(FNT_NUMBER) );
|
|
m_xTextFont->Insert( rFormat.GetFont(FNT_TEXT) );
|
|
m_xSerifFont->Insert( rFormat.GetFont(FNT_SERIF) );
|
|
m_xSansFont->Insert( rFormat.GetFont(FNT_SANS) );
|
|
m_xFixedFont->Insert( rFormat.GetFont(FNT_FIXED) );
|
|
}
|
|
|
|
|
|
void SmFontTypeDialog::WriteTo(SmFormat &rFormat) const
|
|
{
|
|
auto* config = SmModule::get()->GetConfig();
|
|
|
|
config->GetFontPickList(FNT_MATH) = *m_xMathFont;
|
|
config->GetFontPickList(FNT_VARIABLE) = *m_xVariableFont;
|
|
config->GetFontPickList(FNT_FUNCTION) = *m_xFunctionFont;
|
|
config->GetFontPickList(FNT_NUMBER) = *m_xNumberFont;
|
|
config->GetFontPickList(FNT_TEXT) = *m_xTextFont;
|
|
config->GetFontPickList(FNT_SERIF) = *m_xSerifFont;
|
|
config->GetFontPickList(FNT_SANS) = *m_xSansFont;
|
|
config->GetFontPickList(FNT_FIXED) = *m_xFixedFont;
|
|
|
|
rFormat.SetFont( FNT_MATH, SmFace(m_xMathFont->Get()) );
|
|
rFormat.SetFont( FNT_VARIABLE, SmFace(m_xVariableFont->Get()) );
|
|
rFormat.SetFont( FNT_FUNCTION, SmFace(m_xFunctionFont->Get()) );
|
|
rFormat.SetFont( FNT_NUMBER, SmFace(m_xNumberFont->Get()) );
|
|
rFormat.SetFont( FNT_TEXT, SmFace(m_xTextFont->Get()) );
|
|
rFormat.SetFont( FNT_SERIF, SmFace(m_xSerifFont->Get()) );
|
|
rFormat.SetFont( FNT_SANS, SmFace(m_xSansFont->Get()) );
|
|
rFormat.SetFont( FNT_FIXED, SmFace(m_xFixedFont->Get()) );
|
|
|
|
rFormat.RequestApplyChanges();
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
namespace {
|
|
|
|
struct FieldMinMax
|
|
{
|
|
sal_uInt16 nMin, nMax;
|
|
};
|
|
|
|
}
|
|
|
|
// Data for min and max values of the 4 metric fields
|
|
// for each of the 10 categories
|
|
const FieldMinMax pMinMaxData[10][4] =
|
|
{
|
|
// 0
|
|
{{ 0, 200 }, { 0, 200 }, { 0, 100 }, { 0, 0 }},
|
|
// 1
|
|
{{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
|
|
// 2
|
|
{{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
|
|
// 3
|
|
{{ 0, 100 }, { 1, 100 }, { 0, 0 }, { 0, 0 }},
|
|
// 4
|
|
{{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
|
|
// 5
|
|
{{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 100 }},
|
|
// 6
|
|
{{ 0, 300 }, { 0, 300 }, { 0, 0 }, { 0, 0 }},
|
|
// 7
|
|
{{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
|
|
// 8
|
|
{{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
|
|
// 9
|
|
{{ 0, 10000 }, { 0, 10000 }, { 0, 10000 }, { 0, 10000 }}
|
|
};
|
|
|
|
SmCategoryDesc::SmCategoryDesc(weld::Builder& rBuilder, sal_uInt16 nCategoryIdx)
|
|
{
|
|
++nCategoryIdx;
|
|
std::unique_ptr<weld::Label> xTitle(rBuilder.weld_label(OUString::number(nCategoryIdx)+"title"));
|
|
if (xTitle)
|
|
{
|
|
Name = xTitle->get_label();
|
|
}
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
std::unique_ptr<weld::Label> xLabel(rBuilder.weld_label(OUString::number(nCategoryIdx)+"label"+OUString::number(i+1)));
|
|
|
|
if (xLabel)
|
|
{
|
|
Strings[i] = xLabel->get_label();
|
|
Graphics[i] = rBuilder.weld_widget(OUString::number(nCategoryIdx)+"image"+OUString::number(i+1));
|
|
}
|
|
else
|
|
{
|
|
Strings[i].clear();
|
|
Graphics[i].reset();
|
|
}
|
|
|
|
const FieldMinMax& rMinMax = pMinMaxData[ nCategoryIdx-1 ][i];
|
|
Value[i] = Minimum[i] = rMinMax.nMin;
|
|
Maximum[i] = rMinMax.nMax;
|
|
}
|
|
}
|
|
|
|
SmCategoryDesc::~SmCategoryDesc()
|
|
{
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
IMPL_LINK( SmDistanceDialog, GetFocusHdl, weld::Widget&, rControl, void )
|
|
{
|
|
if (!m_xCategories[nActiveCategory])
|
|
return;
|
|
|
|
sal_uInt16 i;
|
|
|
|
if (&rControl == &m_xMetricField1->get_widget())
|
|
i = 0;
|
|
else if (&rControl == &m_xMetricField2->get_widget())
|
|
i = 1;
|
|
else if (&rControl == &m_xMetricField3->get_widget())
|
|
i = 2;
|
|
else if (&rControl == &m_xMetricField4->get_widget())
|
|
i = 3;
|
|
else
|
|
return;
|
|
if (m_pCurrentImage)
|
|
m_pCurrentImage->hide();
|
|
m_pCurrentImage = m_xCategories[nActiveCategory]->GetGraphic(i);
|
|
m_pCurrentImage->show();
|
|
}
|
|
|
|
IMPL_LINK(SmDistanceDialog, MenuSelectHdl, const OUString&, rId, void)
|
|
{
|
|
assert(rId.startsWith("menuitem"));
|
|
SetCategory(rId.replaceFirst("menuitem", "").toInt32() - 1);
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SmDistanceDialog, DefaultButtonClickHdl, weld::Button&, void )
|
|
{
|
|
SaveDefaultsQuery aQuery(m_xDialog.get());
|
|
if (aQuery.run() == RET_YES)
|
|
{
|
|
auto* config = SmModule::get()->GetConfig();
|
|
SmFormat aFmt(config->GetStandardFormat());
|
|
WriteTo( aFmt );
|
|
config->SetStandardFormat( aFmt );
|
|
}
|
|
}
|
|
|
|
IMPL_LINK( SmDistanceDialog, CheckBoxClickHdl, weld::Toggleable&, rCheckBox, void )
|
|
{
|
|
if (&rCheckBox == m_xCheckBox1.get())
|
|
{
|
|
bool bChecked = m_xCheckBox1->get_active();
|
|
m_xFixedText4->set_sensitive( bChecked );
|
|
m_xMetricField4->set_sensitive( bChecked );
|
|
}
|
|
}
|
|
|
|
void SmDistanceDialog::SetCategory(sal_uInt16 nCategory)
|
|
{
|
|
assert(nCategory < NOCATEGORIES && "Sm: wrong category number in SmDistanceDialog");
|
|
|
|
// array to convert category- and metricfield-number in help ids.
|
|
// 0 is used in case of unused combinations.
|
|
assert(NOCATEGORIES == 10 && "Sm : array doesn't fit into the number of categories");
|
|
static constexpr OUString EMPTY(u""_ustr);
|
|
static constexpr OUString aCatMf2Hid[10][4] =
|
|
{
|
|
{ HID_SMA_DEFAULT_DIST, HID_SMA_LINE_DIST, HID_SMA_ROOT_DIST, EMPTY },
|
|
{ HID_SMA_SUP_DIST, HID_SMA_SUB_DIST , EMPTY, EMPTY },
|
|
{ HID_SMA_NUMERATOR_DIST, HID_SMA_DENOMINATOR_DIST, EMPTY, EMPTY },
|
|
{ HID_SMA_FRACLINE_EXCWIDTH, HID_SMA_FRACLINE_LINEWIDTH, EMPTY, EMPTY },
|
|
{ HID_SMA_UPPERLIMIT_DIST, HID_SMA_LOWERLIMIT_DIST, EMPTY, EMPTY },
|
|
{ HID_SMA_BRACKET_EXCHEIGHT, HID_SMA_BRACKET_DIST, EMPTY, HID_SMA_BRACKET_EXCHEIGHT2 },
|
|
{ HID_SMA_MATRIXROW_DIST, HID_SMA_MATRIXCOL_DIST, EMPTY, EMPTY },
|
|
{ HID_SMA_ATTRIBUT_DIST, HID_SMA_INTERATTRIBUT_DIST, EMPTY, EMPTY },
|
|
{ HID_SMA_OPERATOR_EXCHEIGHT, HID_SMA_OPERATOR_DIST, EMPTY, EMPTY },
|
|
{ HID_SMA_LEFTBORDER_DIST, HID_SMA_RIGHTBORDER_DIST, HID_SMA_UPPERBORDER_DIST, HID_SMA_LOWERBORDER_DIST }
|
|
};
|
|
|
|
// array to help iterate over the controls
|
|
std::pair<weld::Label*, weld::MetricSpinButton*> const aWin[4] =
|
|
{
|
|
{ m_xFixedText1.get(), m_xMetricField1.get() },
|
|
{ m_xFixedText2.get(), m_xMetricField2.get() },
|
|
{ m_xFixedText3.get(), m_xMetricField3.get() },
|
|
{ m_xFixedText4.get(), m_xMetricField4.get() }
|
|
};
|
|
|
|
SmCategoryDesc *pCat;
|
|
|
|
// remember the (maybe new) settings of the active SmCategoryDesc
|
|
// before switching to the new one
|
|
if (nActiveCategory != CATEGORY_NONE)
|
|
{
|
|
pCat = m_xCategories[nActiveCategory].get();
|
|
pCat->SetValue(0, sal::static_int_cast<sal_uInt16>(m_xMetricField1->get_value(FieldUnit::NONE)));
|
|
pCat->SetValue(1, sal::static_int_cast<sal_uInt16>(m_xMetricField2->get_value(FieldUnit::NONE)));
|
|
pCat->SetValue(2, sal::static_int_cast<sal_uInt16>(m_xMetricField3->get_value(FieldUnit::NONE)));
|
|
pCat->SetValue(3, sal::static_int_cast<sal_uInt16>(m_xMetricField4->get_value(FieldUnit::NONE)));
|
|
|
|
if (nActiveCategory == 5)
|
|
bScaleAllBrackets = m_xCheckBox1->get_active();
|
|
|
|
m_xMenuButton->set_item_active("menuitem" + OUString::number(nActiveCategory + 1), false);
|
|
}
|
|
|
|
// activation/deactivation of the associated controls depending on the chosen category
|
|
bool bActive;
|
|
for (sal_uInt16 i = 0; i < 4; i++)
|
|
{
|
|
weld::Label *pFT = aWin[i].first;
|
|
weld::MetricSpinButton *pMF = aWin[i].second;
|
|
|
|
// To determine which Controls should be active, the existence
|
|
// of an associated HelpID is checked
|
|
bActive = !aCatMf2Hid[nCategory][i].isEmpty();
|
|
|
|
pFT->set_visible(bActive);
|
|
pFT->set_sensitive(bActive);
|
|
pMF->set_visible(bActive);
|
|
pMF->set_sensitive(bActive);
|
|
|
|
// set measurement unit and number of decimal places
|
|
FieldUnit eUnit;
|
|
sal_uInt16 nDigits;
|
|
if (nCategory < 9)
|
|
{
|
|
eUnit = FieldUnit::PERCENT;
|
|
nDigits = 0;
|
|
}
|
|
else
|
|
{
|
|
eUnit = FieldUnit::MM_100TH;
|
|
nDigits = 2;
|
|
}
|
|
pMF->set_unit(eUnit); // changes the value
|
|
pMF->set_digits(nDigits);
|
|
|
|
if (bActive)
|
|
{
|
|
pCat = m_xCategories[nCategory].get();
|
|
pFT->set_label(pCat->GetString(i));
|
|
|
|
pMF->set_range(pCat->GetMinimum(i), pCat->GetMaximum(i), FieldUnit::NONE);
|
|
pMF->set_value(pCat->GetValue(i), FieldUnit::NONE);
|
|
|
|
pMF->set_help_id(aCatMf2Hid[nCategory][i]);
|
|
}
|
|
}
|
|
// activate the CheckBox and the associated MetricField if we're dealing with the brackets menu
|
|
bActive = nCategory == 5;
|
|
m_xCheckBox1->set_visible(bActive);
|
|
m_xCheckBox1->set_sensitive(bActive);
|
|
if (bActive)
|
|
{
|
|
m_xCheckBox1->set_active(bScaleAllBrackets);
|
|
|
|
bool bChecked = m_xCheckBox1->get_active();
|
|
m_xFixedText4->set_sensitive( bChecked );
|
|
m_xMetricField4->set_sensitive( bChecked );
|
|
}
|
|
|
|
m_xMenuButton->set_item_active("menuitem" + OUString::number(nCategory + 1), true);
|
|
m_xFrame->set_label(m_xCategories[nCategory]->GetName());
|
|
|
|
nActiveCategory = nCategory;
|
|
|
|
m_xMetricField1->grab_focus();
|
|
// ensure the focus handler gets called
|
|
// (for qt6 and native widgets, no focus event gets sent when "Category" menu was triggered using
|
|
// mouse while m_xMetricField1 had keyboard focus)
|
|
GetFocusHdl(m_xMetricField1->get_widget());
|
|
}
|
|
|
|
SmDistanceDialog::SmDistanceDialog(weld::Window *pParent)
|
|
: GenericDialogController(pParent, u"modules/smath/ui/spacingdialog.ui"_ustr, u"SpacingDialog"_ustr)
|
|
, m_xFrame(m_xBuilder->weld_frame(u"template"_ustr))
|
|
, m_xFixedText1(m_xBuilder->weld_label(u"label1"_ustr))
|
|
, m_xMetricField1(m_xBuilder->weld_metric_spin_button(u"spinbutton1"_ustr, FieldUnit::CM))
|
|
, m_xFixedText2(m_xBuilder->weld_label(u"label2"_ustr))
|
|
, m_xMetricField2(m_xBuilder->weld_metric_spin_button(u"spinbutton2"_ustr, FieldUnit::CM))
|
|
, m_xFixedText3(m_xBuilder->weld_label(u"label3"_ustr))
|
|
, m_xMetricField3(m_xBuilder->weld_metric_spin_button(u"spinbutton3"_ustr, FieldUnit::CM))
|
|
, m_xCheckBox1(m_xBuilder->weld_check_button(u"checkbutton"_ustr))
|
|
, m_xFixedText4(m_xBuilder->weld_label(u"label4"_ustr))
|
|
, m_xMetricField4(m_xBuilder->weld_metric_spin_button(u"spinbutton4"_ustr, FieldUnit::CM))
|
|
, m_xMenuButton(m_xBuilder->weld_menu_button(u"category"_ustr))
|
|
, m_xDefaultButton(m_xBuilder->weld_button(u"default"_ustr))
|
|
, m_xBitmap(m_xBuilder->weld_widget(u"image"_ustr))
|
|
, m_pCurrentImage(m_xBitmap.get())
|
|
{
|
|
for (sal_uInt16 i = 0; i < NOCATEGORIES; ++i)
|
|
m_xCategories[i].reset( new SmCategoryDesc(*m_xBuilder, i) );
|
|
nActiveCategory = CATEGORY_NONE;
|
|
bScaleAllBrackets = false;
|
|
|
|
m_xMetricField1->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
|
|
m_xMetricField2->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
|
|
m_xMetricField3->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
|
|
m_xMetricField4->connect_focus_in(LINK(this, SmDistanceDialog, GetFocusHdl));
|
|
m_xCheckBox1->connect_toggled(LINK(this, SmDistanceDialog, CheckBoxClickHdl));
|
|
m_xMenuButton->connect_selected(LINK(this, SmDistanceDialog, MenuSelectHdl));
|
|
m_xDefaultButton->connect_clicked(LINK(this, SmDistanceDialog, DefaultButtonClickHdl));
|
|
|
|
//set the initial size, with max visible widgets visible, as preferred size
|
|
m_xDialog->set_size_request(-1, m_xDialog->get_preferred_size().Height());
|
|
}
|
|
|
|
SmDistanceDialog::~SmDistanceDialog()
|
|
{
|
|
}
|
|
|
|
void SmDistanceDialog::ReadFrom(const SmFormat &rFormat)
|
|
{
|
|
m_xCategories[0]->SetValue(0, rFormat.GetDistance(DIS_HORIZONTAL));
|
|
m_xCategories[0]->SetValue(1, rFormat.GetDistance(DIS_VERTICAL));
|
|
m_xCategories[0]->SetValue(2, rFormat.GetDistance(DIS_ROOT));
|
|
m_xCategories[1]->SetValue(0, rFormat.GetDistance(DIS_SUPERSCRIPT));
|
|
m_xCategories[1]->SetValue(1, rFormat.GetDistance(DIS_SUBSCRIPT));
|
|
m_xCategories[2]->SetValue(0, rFormat.GetDistance(DIS_NUMERATOR));
|
|
m_xCategories[2]->SetValue(1, rFormat.GetDistance(DIS_DENOMINATOR));
|
|
m_xCategories[3]->SetValue(0, rFormat.GetDistance(DIS_FRACTION));
|
|
m_xCategories[3]->SetValue(1, rFormat.GetDistance(DIS_STROKEWIDTH));
|
|
m_xCategories[4]->SetValue(0, rFormat.GetDistance(DIS_UPPERLIMIT));
|
|
m_xCategories[4]->SetValue(1, rFormat.GetDistance(DIS_LOWERLIMIT));
|
|
m_xCategories[5]->SetValue(0, rFormat.GetDistance(DIS_BRACKETSIZE));
|
|
m_xCategories[5]->SetValue(1, rFormat.GetDistance(DIS_BRACKETSPACE));
|
|
m_xCategories[5]->SetValue(3, rFormat.GetDistance(DIS_NORMALBRACKETSIZE));
|
|
m_xCategories[6]->SetValue(0, rFormat.GetDistance(DIS_MATRIXROW));
|
|
m_xCategories[6]->SetValue(1, rFormat.GetDistance(DIS_MATRIXCOL));
|
|
m_xCategories[7]->SetValue(0, rFormat.GetDistance(DIS_ORNAMENTSIZE));
|
|
m_xCategories[7]->SetValue(1, rFormat.GetDistance(DIS_ORNAMENTSPACE));
|
|
m_xCategories[8]->SetValue(0, rFormat.GetDistance(DIS_OPERATORSIZE));
|
|
m_xCategories[8]->SetValue(1, rFormat.GetDistance(DIS_OPERATORSPACE));
|
|
m_xCategories[9]->SetValue(0, rFormat.GetDistance(DIS_LEFTSPACE));
|
|
m_xCategories[9]->SetValue(1, rFormat.GetDistance(DIS_RIGHTSPACE));
|
|
m_xCategories[9]->SetValue(2, rFormat.GetDistance(DIS_TOPSPACE));
|
|
m_xCategories[9]->SetValue(3, rFormat.GetDistance(DIS_BOTTOMSPACE));
|
|
|
|
bScaleAllBrackets = rFormat.IsScaleNormalBrackets();
|
|
|
|
// force update (even of category 0) by setting nActiveCategory to a
|
|
// non-existent category number
|
|
nActiveCategory = CATEGORY_NONE;
|
|
SetCategory(0);
|
|
}
|
|
|
|
|
|
void SmDistanceDialog::WriteTo(SmFormat &rFormat) /*const*/
|
|
{
|
|
// TODO can they actually be different?
|
|
// if that's not the case 'const' could be used above!
|
|
SetCategory(nActiveCategory);
|
|
|
|
rFormat.SetDistance( DIS_HORIZONTAL, m_xCategories[0]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_VERTICAL, m_xCategories[0]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_ROOT, m_xCategories[0]->GetValue(2) );
|
|
rFormat.SetDistance( DIS_SUPERSCRIPT, m_xCategories[1]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_SUBSCRIPT, m_xCategories[1]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_NUMERATOR, m_xCategories[2]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_DENOMINATOR, m_xCategories[2]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_FRACTION, m_xCategories[3]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_STROKEWIDTH, m_xCategories[3]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_UPPERLIMIT, m_xCategories[4]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_LOWERLIMIT, m_xCategories[4]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_BRACKETSIZE, m_xCategories[5]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_BRACKETSPACE, m_xCategories[5]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_MATRIXROW, m_xCategories[6]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_MATRIXCOL, m_xCategories[6]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_ORNAMENTSIZE, m_xCategories[7]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_ORNAMENTSPACE, m_xCategories[7]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_OPERATORSIZE, m_xCategories[8]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_OPERATORSPACE, m_xCategories[8]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_LEFTSPACE, m_xCategories[9]->GetValue(0) );
|
|
rFormat.SetDistance( DIS_RIGHTSPACE, m_xCategories[9]->GetValue(1) );
|
|
rFormat.SetDistance( DIS_TOPSPACE, m_xCategories[9]->GetValue(2) );
|
|
rFormat.SetDistance( DIS_BOTTOMSPACE, m_xCategories[9]->GetValue(3) );
|
|
rFormat.SetDistance( DIS_NORMALBRACKETSIZE, m_xCategories[5]->GetValue(3) );
|
|
|
|
rFormat.SetScaleNormalBrackets( bScaleAllBrackets );
|
|
|
|
rFormat.RequestApplyChanges();
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SmAlignDialog, DefaultButtonClickHdl, weld::Button&, void )
|
|
{
|
|
SaveDefaultsQuery aQuery(m_xDialog.get());
|
|
if (aQuery.run() == RET_YES)
|
|
{
|
|
auto* config = SmModule::get()->GetConfig();
|
|
SmFormat aFmt(config->GetStandardFormat());
|
|
WriteTo( aFmt );
|
|
config->SetStandardFormat(aFmt);
|
|
}
|
|
}
|
|
|
|
SmAlignDialog::SmAlignDialog(weld::Window* pParent)
|
|
: GenericDialogController(pParent, u"modules/smath/ui/alignmentdialog.ui"_ustr, u"AlignmentDialog"_ustr)
|
|
, m_xLeft(m_xBuilder->weld_radio_button(u"left"_ustr))
|
|
, m_xCenter(m_xBuilder->weld_radio_button(u"center"_ustr))
|
|
, m_xRight(m_xBuilder->weld_radio_button(u"right"_ustr))
|
|
, m_xDefaultButton(m_xBuilder->weld_button(u"default"_ustr))
|
|
{
|
|
m_xDefaultButton->connect_clicked(LINK(this, SmAlignDialog, DefaultButtonClickHdl));
|
|
}
|
|
|
|
SmAlignDialog::~SmAlignDialog()
|
|
{
|
|
}
|
|
|
|
void SmAlignDialog::ReadFrom(const SmFormat &rFormat)
|
|
{
|
|
switch (rFormat.GetHorAlign())
|
|
{
|
|
case SmHorAlign::Left:
|
|
m_xLeft->set_active(true);
|
|
break;
|
|
case SmHorAlign::Center:
|
|
m_xCenter->set_active(true);
|
|
break;
|
|
case SmHorAlign::Right:
|
|
m_xRight->set_active(true);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SmAlignDialog::WriteTo(SmFormat &rFormat) const
|
|
{
|
|
if (m_xLeft->get_active())
|
|
rFormat.SetHorAlign(SmHorAlign::Left);
|
|
else if (m_xRight->get_active())
|
|
rFormat.SetHorAlign(SmHorAlign::Right);
|
|
else
|
|
rFormat.SetHorAlign(SmHorAlign::Center);
|
|
|
|
rFormat.RequestApplyChanges();
|
|
}
|
|
|
|
SmShowSymbolSet::SmShowSymbolSet(std::unique_ptr<weld::ScrolledWindow> pScrolledWindow, SmViewShell &rViewShell)
|
|
: m_rViewShell(rViewShell)
|
|
, nLen(0)
|
|
, nRows(0)
|
|
, nColumns(0)
|
|
, nXOffset(0)
|
|
, nYOffset(0)
|
|
, nSelectSymbol(SYMBOL_NONE)
|
|
, m_xScrolledWindow(std::move(pScrolledWindow))
|
|
{
|
|
m_xScrolledWindow->connect_vadjustment_changed(LINK(this, SmShowSymbolSet, ScrollHdl));
|
|
}
|
|
|
|
Point SmShowSymbolSet::OffsetPoint(const Point &rPoint) const
|
|
{
|
|
return Point(rPoint.X() + nXOffset, rPoint.Y() + nYOffset);
|
|
}
|
|
|
|
void SmShowSymbolSet::Resize()
|
|
{
|
|
CustomWidgetController::Resize();
|
|
Size aWinSize(GetOutputSizePixel());
|
|
if (aWinSize != m_aOldSize)
|
|
{
|
|
calccols(GetDrawingArea()->get_ref_device());
|
|
m_aOldSize = aWinSize;
|
|
}
|
|
}
|
|
|
|
void SmShowSymbolSet::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
|
|
{
|
|
Color aBackgroundColor;
|
|
Color aTextColor;
|
|
lclGetSettingColors(aBackgroundColor, aTextColor);
|
|
|
|
rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
|
|
rRenderContext.SetTextColor(aTextColor);
|
|
|
|
rRenderContext.Push(vcl::PushFlags::MAPMODE);
|
|
|
|
// set MapUnit for which 'nLen' has been calculated
|
|
rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
|
|
|
|
sal_uInt16 v = sal::static_int_cast< sal_uInt16 >(m_xScrolledWindow->vadjustment_get_value() * nColumns);
|
|
size_t nSymbols = aSymbolSet.size();
|
|
|
|
Color aTxtColor(rRenderContext.GetTextColor());
|
|
for (size_t i = v; i < nSymbols ; i++)
|
|
{
|
|
SmSym aSymbol(*aSymbolSet[i]);
|
|
vcl::Font aFont(lclGetSymbolFont(m_rViewShell, aSymbol));
|
|
aFont.SetAlignment(ALIGN_TOP);
|
|
|
|
// taking a FontSize which is a bit smaller (compared to nLen) in order to have a buffer
|
|
// (hopefully enough for left and right, too)
|
|
aFont.SetFontSize(Size(0, nLen - (nLen / 3)));
|
|
rRenderContext.SetFont(aFont);
|
|
// keep text color
|
|
rRenderContext.SetTextColor(aTxtColor);
|
|
|
|
int nIV = i - v;
|
|
sal_UCS4 cChar = aSymbol.GetCharacter();
|
|
OUString aText(&cChar, 1);
|
|
Size aSize(rRenderContext.GetTextWidth( aText ), rRenderContext.GetTextHeight());
|
|
|
|
Point aPoint((nIV % nColumns) * nLen + (nLen - aSize.Width()) / 2,
|
|
(nIV / nColumns) * nLen + (nLen - aSize.Height()) / 2);
|
|
|
|
rRenderContext.DrawText(OffsetPoint(aPoint), aText);
|
|
}
|
|
|
|
if (nSelectSymbol != SYMBOL_NONE)
|
|
{
|
|
Point aPoint(((nSelectSymbol - v) % nColumns) * nLen,
|
|
((nSelectSymbol - v) / nColumns) * nLen);
|
|
|
|
rRenderContext.Invert(tools::Rectangle(OffsetPoint(aPoint), Size(nLen, nLen)));
|
|
|
|
}
|
|
|
|
rRenderContext.Pop();
|
|
}
|
|
|
|
bool SmShowSymbolSet::MouseButtonDown(const MouseEvent& rMEvt)
|
|
{
|
|
GrabFocus();
|
|
|
|
Size aOutputSize(nColumns * nLen, nRows * nLen);
|
|
aOutputSize.AdjustWidth(nXOffset );
|
|
aOutputSize.AdjustHeight(nYOffset );
|
|
Point aPoint(rMEvt.GetPosPixel());
|
|
aPoint.AdjustX( -nXOffset );
|
|
aPoint.AdjustY( -nYOffset );
|
|
|
|
if (rMEvt.IsLeft() && tools::Rectangle(Point(0, 0), aOutputSize).Contains(rMEvt.GetPosPixel()))
|
|
{
|
|
tools::Long nPos = (aPoint.Y() / nLen) * nColumns + (aPoint.X() / nLen) +
|
|
m_xScrolledWindow->vadjustment_get_value() * nColumns;
|
|
SelectSymbol( sal::static_int_cast< sal_uInt16 >(nPos) );
|
|
|
|
aSelectHdlLink.Call(*this);
|
|
|
|
if (rMEvt.GetClicks() > 1)
|
|
aDblClickHdlLink.Call(*this);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool SmShowSymbolSet::KeyInput(const KeyEvent& rKEvt)
|
|
{
|
|
sal_uInt16 n = nSelectSymbol;
|
|
|
|
if (n != SYMBOL_NONE)
|
|
{
|
|
switch (rKEvt.GetKeyCode().GetCode())
|
|
{
|
|
case KEY_DOWN: n = n + nColumns; break;
|
|
case KEY_UP: n = n - nColumns; break;
|
|
case KEY_LEFT: n -= 1; break;
|
|
case KEY_RIGHT: n += 1; break;
|
|
case KEY_HOME: n = 0; break;
|
|
case KEY_END: n = static_cast< sal_uInt16 >(aSymbolSet.size() - 1); break;
|
|
case KEY_PAGEUP: n -= nColumns * nRows; break;
|
|
case KEY_PAGEDOWN: n += nColumns * nRows; break;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
n = 0;
|
|
|
|
if (n >= aSymbolSet.size())
|
|
n = nSelectSymbol;
|
|
|
|
// adjust scrollbar
|
|
if ((n < sal::static_int_cast<sal_uInt16>(m_xScrolledWindow->vadjustment_get_value() * nColumns)) ||
|
|
(n >= sal::static_int_cast<sal_uInt16>((m_xScrolledWindow->vadjustment_get_value() + nRows) * nColumns)))
|
|
{
|
|
m_xScrolledWindow->vadjustment_set_value(n / nColumns);
|
|
Invalidate();
|
|
}
|
|
|
|
SelectSymbol(n);
|
|
aSelectHdlLink.Call(*this);
|
|
|
|
return true;
|
|
}
|
|
|
|
void SmShowSymbolSet::calccols(const vcl::RenderContext& rRenderContext)
|
|
{
|
|
// Height of 16pt in pixels (matching 'aOutputSize')
|
|
nLen = rRenderContext.LogicToPixel(Size(0, 16), MapMode(MapUnit::MapPoint)).Height();
|
|
|
|
Size aOutputSize(GetOutputSizePixel());
|
|
|
|
nColumns = aOutputSize.Width() / nLen;
|
|
nRows = aOutputSize.Height() / nLen;
|
|
nColumns = std::max<tools::Long>(1, nColumns);
|
|
nRows = std::max<tools::Long>(1, nRows);
|
|
|
|
nXOffset = (aOutputSize.Width() - (nColumns * nLen)) / 2;
|
|
nYOffset = (aOutputSize.Height() - (nRows * nLen)) / 2;
|
|
|
|
SetScrollBarRange();
|
|
}
|
|
|
|
void SmShowSymbolSet::SetSymbolSet(const SymbolPtrVec_t & rSymbolSet)
|
|
{
|
|
aSymbolSet = rSymbolSet;
|
|
SetScrollBarRange();
|
|
Invalidate();
|
|
}
|
|
|
|
void SmShowSymbolSet::SetScrollBarRange()
|
|
{
|
|
const int nLastRow = (aSymbolSet.size() - 1 + nColumns) / nColumns;
|
|
m_xScrolledWindow->vadjustment_configure(m_xScrolledWindow->vadjustment_get_value(), 0, nLastRow, 1, nRows - 1, nRows);
|
|
Invalidate();
|
|
}
|
|
|
|
void SmShowSymbolSet::SelectSymbol(sal_uInt16 nSymbol)
|
|
{
|
|
int v = m_xScrolledWindow->vadjustment_get_value() * nColumns;
|
|
|
|
if (nSelectSymbol != SYMBOL_NONE && nColumns)
|
|
{
|
|
Point aPoint(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
|
|
((nSelectSymbol - v) / nColumns) * nLen)));
|
|
Invalidate(tools::Rectangle(aPoint, Size(nLen, nLen)));
|
|
}
|
|
|
|
if (nSymbol < aSymbolSet.size())
|
|
nSelectSymbol = nSymbol;
|
|
|
|
if (aSymbolSet.empty())
|
|
nSelectSymbol = SYMBOL_NONE;
|
|
|
|
if (nSelectSymbol != SYMBOL_NONE && nColumns)
|
|
{
|
|
Point aPoint(OffsetPoint(Point(((nSelectSymbol - v) % nColumns) * nLen,
|
|
((nSelectSymbol - v) / nColumns) * nLen)));
|
|
Invalidate(tools::Rectangle(aPoint, Size(nLen, nLen)));
|
|
}
|
|
|
|
if (!nColumns)
|
|
Invalidate();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SmShowSymbolSet, ScrollHdl, weld::ScrolledWindow&, void)
|
|
{
|
|
Invalidate();
|
|
}
|
|
|
|
SmShowSymbol::SmShowSymbol(SmViewShell& rViewShell)
|
|
: m_rViewShell(rViewShell)
|
|
{
|
|
}
|
|
|
|
void SmShowSymbol::setFontSize(vcl::Font &rFont) const
|
|
{
|
|
Size aSize(GetOutputSizePixel());
|
|
rFont.SetFontSize(Size(0, aSize.Height() - aSize.Height() / 3));
|
|
}
|
|
|
|
void SmShowSymbol::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
|
|
{
|
|
Color aBackgroundColor;
|
|
Color aTextColor;
|
|
lclGetSettingColors(aBackgroundColor, aTextColor);
|
|
rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
|
|
rRenderContext.SetTextColor(aTextColor);
|
|
rRenderContext.Erase();
|
|
|
|
vcl::Font aFont(GetFont());
|
|
setFontSize(aFont);
|
|
rRenderContext.SetFont(aFont);
|
|
|
|
const OUString &rText = GetText();
|
|
Size aTextSize(rRenderContext.GetTextWidth(rText), rRenderContext.GetTextHeight());
|
|
|
|
rRenderContext.DrawText(Point((rRenderContext.GetOutputSize().Width() - aTextSize.Width()) / 2,
|
|
(rRenderContext.GetOutputSize().Height() * 7 / 10)), rText);
|
|
}
|
|
|
|
bool SmShowSymbol::MouseButtonDown(const MouseEvent& rMEvt)
|
|
{
|
|
if (rMEvt.GetClicks() > 1)
|
|
aDblClickHdlLink.Call(*this);
|
|
return true;
|
|
}
|
|
|
|
void SmShowSymbol::SetSymbol(const SmSym *pSymbol)
|
|
{
|
|
if (pSymbol)
|
|
{
|
|
vcl::Font aFont(lclGetSymbolFont(m_rViewShell, *pSymbol));
|
|
aFont.SetAlignment(ALIGN_BASELINE);
|
|
SetFont(aFont);
|
|
|
|
sal_UCS4 cChar = pSymbol->GetCharacter();
|
|
OUString aText(&cChar, 1);
|
|
SetText( aText );
|
|
}
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
void SmSymbolDialog::FillSymbolSets()
|
|
// populate the entries of possible SymbolsSets in the dialog with
|
|
// current values of the SymbolSet manager but selects none of those
|
|
{
|
|
m_xSymbolSets->clear();
|
|
m_xSymbolSets->set_active(-1);
|
|
|
|
std::set< OUString > aSymbolSetNames( m_rSymbolMgr.GetSymbolSetNames() );
|
|
for (const auto& rSymbolSetName : aSymbolSetNames)
|
|
m_xSymbolSets->append_text(rSymbolSetName);
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SmSymbolDialog, SymbolSetChangeHdl, weld::ComboBox&, void )
|
|
{
|
|
SelectSymbolSet(m_xSymbolSets->get_active_text());
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SmSymbolDialog, SymbolChangeHdl, SmShowSymbolSet&, void )
|
|
{
|
|
SelectSymbol(m_xSymbolSetDisplay->GetSelectSymbol());
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SmSymbolDialog, EditClickHdl, weld::Button&, void)
|
|
{
|
|
SmSymDefineDialog aDialog(m_xDialog.get(), m_pFontListDev, m_rSymbolMgr);
|
|
|
|
// set current symbol and SymbolSet for the new dialog
|
|
const OUString aSymSetName (m_xSymbolSets->get_active_text()),
|
|
aSymName (m_xSymbolName->get_label());
|
|
aDialog.SelectOldSymbolSet(aSymSetName);
|
|
aDialog.SelectOldSymbol(aSymName);
|
|
aDialog.SelectSymbolSet(aSymSetName);
|
|
aDialog.SelectSymbol(aSymName);
|
|
|
|
// remember old SymbolSet
|
|
OUString aOldSymbolSet (m_xSymbolSets->get_active_text());
|
|
|
|
sal_uInt16 nSymPos = m_xSymbolSetDisplay->GetSelectSymbol();
|
|
|
|
// adapt dialog to data of the SymbolSet manager, which might have changed
|
|
if (aDialog.run() == RET_OK && m_rSymbolMgr.IsModified())
|
|
{
|
|
m_rSymbolMgr.Save();
|
|
FillSymbolSets();
|
|
}
|
|
|
|
// if the old SymbolSet doesn't exist anymore, go to the first one SymbolSet (if one exists)
|
|
if (!SelectSymbolSet(aOldSymbolSet) && m_xSymbolSets->get_count() > 0)
|
|
SelectSymbolSet(m_xSymbolSets->get_text(0));
|
|
else
|
|
{
|
|
// just update display of current symbol set
|
|
assert(m_aSymbolSetName == aSymSetName); //unexpected change in symbol set name
|
|
m_aSymbolSet = m_rSymbolMgr.GetSymbolSet( m_aSymbolSetName );
|
|
m_xSymbolSetDisplay->SetSymbolSet( m_aSymbolSet );
|
|
}
|
|
|
|
if (nSymPos >= m_aSymbolSet.size())
|
|
nSymPos = static_cast< sal_uInt16 >(m_aSymbolSet.size()) - 1;
|
|
SelectSymbol( nSymPos );
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl2, SmShowSymbolSet&, void )
|
|
{
|
|
SymbolDblClickHdl();
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SmSymbolDialog, SymbolDblClickHdl, SmShowSymbol&, void )
|
|
{
|
|
SymbolDblClickHdl();
|
|
}
|
|
|
|
void SmSymbolDialog::SymbolDblClickHdl()
|
|
{
|
|
GetClickHdl(*m_xGetBtn);
|
|
m_xDialog->response(RET_OK);
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SmSymbolDialog, GetClickHdl, weld::Button&, void)
|
|
{
|
|
const SmSym *pSym = GetSymbol();
|
|
if (pSym)
|
|
{
|
|
OUString aText = "%" + pSym->GetUiName() + " ";
|
|
|
|
m_rViewSh.GetViewFrame().GetDispatcher()->ExecuteList(
|
|
SID_INSERTSPECIAL, SfxCallMode::RECORD,
|
|
{ new SfxStringItem(SID_INSERTSPECIAL, aText) });
|
|
}
|
|
}
|
|
|
|
SmSymbolDialog::SmSymbolDialog(weld::Window *pParent, OutputDevice *pFntListDevice,
|
|
SmSymbolManager &rMgr, SmViewShell &rViewShell)
|
|
: GenericDialogController(pParent, u"modules/smath/ui/catalogdialog.ui"_ustr, u"CatalogDialog"_ustr)
|
|
, m_rViewSh(rViewShell)
|
|
, m_rSymbolMgr(rMgr)
|
|
, m_pFontListDev(pFntListDevice)
|
|
, m_aSymbolDisplay(rViewShell)
|
|
, m_xSymbolSets(m_xBuilder->weld_combo_box(u"symbolset"_ustr))
|
|
, m_xSymbolSetDisplay(new SmShowSymbolSet(m_xBuilder->weld_scrolled_window(u"scrolledwindow"_ustr, true), rViewShell))
|
|
, m_xSymbolSetDisplayArea(new weld::CustomWeld(*m_xBuilder, u"symbolsetdisplay"_ustr, *m_xSymbolSetDisplay))
|
|
, m_xSymbolName(m_xBuilder->weld_label(u"symbolname"_ustr))
|
|
, m_xSymbolDisplay(new weld::CustomWeld(*m_xBuilder, u"preview"_ustr, m_aSymbolDisplay))
|
|
, m_xGetBtn(m_xBuilder->weld_button(u"ok"_ustr))
|
|
, m_xEditBtn(m_xBuilder->weld_button(u"edit"_ustr))
|
|
{
|
|
m_xSymbolSets->make_sorted();
|
|
|
|
m_aSymbolSetName.clear();
|
|
m_aSymbolSet.clear();
|
|
FillSymbolSets();
|
|
if (m_xSymbolSets->get_count() > 0)
|
|
SelectSymbolSet(m_xSymbolSets->get_text(0));
|
|
|
|
m_xSymbolSets->connect_changed(LINK(this, SmSymbolDialog, SymbolSetChangeHdl));
|
|
m_xSymbolSetDisplay->SetSelectHdl(LINK(this, SmSymbolDialog, SymbolChangeHdl));
|
|
m_xSymbolSetDisplay->SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl2));
|
|
m_aSymbolDisplay.SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl));
|
|
m_xEditBtn->connect_clicked(LINK(this, SmSymbolDialog, EditClickHdl));
|
|
m_xGetBtn->connect_clicked(LINK(this, SmSymbolDialog, GetClickHdl));
|
|
}
|
|
|
|
SmSymbolDialog::~SmSymbolDialog()
|
|
{
|
|
}
|
|
|
|
bool SmSymbolDialog::SelectSymbolSet(const OUString &rSymbolSetName)
|
|
{
|
|
bool bRet = false;
|
|
sal_Int32 nPos = m_xSymbolSets->find_text(rSymbolSetName);
|
|
|
|
m_aSymbolSetName.clear();
|
|
m_aSymbolSet.clear();
|
|
if (nPos != -1)
|
|
{
|
|
m_xSymbolSets->set_active(nPos);
|
|
|
|
m_aSymbolSetName = rSymbolSetName;
|
|
m_aSymbolSet = m_rSymbolMgr.GetSymbolSet( m_aSymbolSetName );
|
|
|
|
// sort symbols by Unicode position (useful for displaying Greek characters alphabetically)
|
|
std::sort( m_aSymbolSet.begin(), m_aSymbolSet.end(),
|
|
[](const SmSym *pSym1, const SmSym *pSym2)
|
|
{
|
|
return pSym1->GetCharacter() < pSym2->GetCharacter();
|
|
} );
|
|
|
|
const bool bEmptySymbolSet = m_aSymbolSet.empty();
|
|
m_xSymbolSetDisplay->SetSymbolSet( m_aSymbolSet );
|
|
if (!bEmptySymbolSet)
|
|
SelectSymbol(0);
|
|
|
|
bRet = true;
|
|
}
|
|
else
|
|
m_xSymbolSets->set_active(-1);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void SmSymbolDialog::SelectSymbol(sal_uInt16 nSymbolNo)
|
|
{
|
|
const SmSym *pSym = nullptr;
|
|
if (!m_aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(m_aSymbolSet.size()))
|
|
pSym = m_aSymbolSet[ nSymbolNo ];
|
|
|
|
m_xSymbolSetDisplay->SelectSymbol(nSymbolNo);
|
|
m_aSymbolDisplay.SetSymbol(pSym);
|
|
m_xSymbolName->set_label(pSym ? pSym->GetUiName() : OUString());
|
|
}
|
|
|
|
const SmSym* SmSymbolDialog::GetSymbol() const
|
|
{
|
|
sal_uInt16 nSymbolNo = m_xSymbolSetDisplay->GetSelectSymbol();
|
|
bool bValid = !m_aSymbolSetName.isEmpty() && nSymbolNo < static_cast< sal_uInt16 >(m_aSymbolSet.size());
|
|
return bValid ? m_aSymbolSet[ nSymbolNo ] : nullptr;
|
|
}
|
|
|
|
void SmShowChar::Resize()
|
|
{
|
|
const OUString &rText = GetText();
|
|
if (rText.isEmpty())
|
|
return;
|
|
sal_UCS4 cChar = rText.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
|
|
SetSymbol(cChar, GetFont()); //force recalculation of size
|
|
}
|
|
|
|
void SmShowChar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
|
|
{
|
|
Color aTextCol = rRenderContext.GetTextColor();
|
|
Color aFillCol = rRenderContext.GetFillColor();
|
|
|
|
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
|
|
const Color aWindowTextColor(rStyleSettings.GetDialogTextColor());
|
|
const Color aWindowColor(rStyleSettings.GetWindowColor());
|
|
rRenderContext.SetTextColor(aWindowTextColor);
|
|
rRenderContext.SetFillColor(aWindowColor);
|
|
|
|
Size aSize(GetOutputSizePixel());
|
|
rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aSize));
|
|
|
|
OUString aText(GetText());
|
|
if (!aText.isEmpty())
|
|
{
|
|
vcl::Font aFont(m_aFont);
|
|
aFont.SetAlignment(ALIGN_TOP);
|
|
rRenderContext.SetFont(aFont);
|
|
|
|
Size aTextSize(rRenderContext.GetTextWidth(aText), rRenderContext.GetTextHeight());
|
|
|
|
rRenderContext.DrawText(Point((aSize.Width() - aTextSize.Width()) / 2,
|
|
(aSize.Height() - aTextSize.Height()) / 2), aText);
|
|
}
|
|
|
|
rRenderContext.SetTextColor(aTextCol);
|
|
rRenderContext.SetFillColor(aFillCol);
|
|
}
|
|
|
|
void SmShowChar::SetSymbol( const SmSym *pSym )
|
|
{
|
|
if (pSym)
|
|
SetSymbol( pSym->GetCharacter(), pSym->GetFace() );
|
|
}
|
|
|
|
|
|
void SmShowChar::SetSymbol( sal_UCS4 cChar, const vcl::Font &rFont )
|
|
{
|
|
vcl::Font aFont( rFont );
|
|
Size aSize(GetOutputSizePixel());
|
|
aFont.SetFontSize(Size(0, aSize.Height() - aSize.Height() / 3));
|
|
aFont.SetAlignment(ALIGN_BASELINE);
|
|
SetFont(aFont);
|
|
|
|
OUString aText(&cChar, 1);
|
|
SetText( aText );
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
void SmSymDefineDialog::FillSymbols(weld::ComboBox& rComboBox, bool bDeleteText)
|
|
{
|
|
assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong ComboBox");
|
|
|
|
rComboBox.clear();
|
|
if (bDeleteText)
|
|
rComboBox.set_entry_text(OUString());
|
|
|
|
weld::ComboBox& rBox = &rComboBox == m_xOldSymbols.get() ? *m_xOldSymbolSets : *m_xSymbolSets;
|
|
SymbolPtrVec_t aSymSet(m_aSymbolMgrCopy.GetSymbolSet(rBox.get_active_text()));
|
|
for (const SmSym* i : aSymSet)
|
|
rComboBox.append_text(i->GetUiName());
|
|
}
|
|
|
|
void SmSymDefineDialog::FillSymbolSets(weld::ComboBox& rComboBox, bool bDeleteText)
|
|
{
|
|
assert((&rComboBox == m_xOldSymbolSets.get() || &rComboBox == m_xSymbolSets.get()) && "Sm : wrong ComboBox");
|
|
|
|
rComboBox.clear();
|
|
if (bDeleteText)
|
|
rComboBox.set_entry_text(OUString());
|
|
|
|
const std::set< OUString > aSymbolSetNames( m_aSymbolMgrCopy.GetSymbolSetNames() );
|
|
for (const auto& rSymbolSetName : aSymbolSetNames)
|
|
rComboBox.append_text(rSymbolSetName);
|
|
}
|
|
|
|
void SmSymDefineDialog::FillFonts()
|
|
{
|
|
m_xFonts->clear();
|
|
m_xFonts->set_active(-1);
|
|
|
|
// Include all fonts of FontList into the font list.
|
|
// If there are duplicates, only include one entry of each font since the style will be
|
|
// already selected using the FontStyleBox.
|
|
if (m_xFontList)
|
|
{
|
|
sal_uInt16 nCount = m_xFontList->GetFontNameCount();
|
|
for (sal_uInt16 i = 0; i < nCount; ++i)
|
|
m_xFonts->append_text(m_xFontList->GetFontName(i).GetFamilyName());
|
|
}
|
|
}
|
|
|
|
void SmSymDefineDialog::FillStyles()
|
|
{
|
|
m_xStyles->clear();
|
|
// pStyles->SetText(OUString());
|
|
|
|
OUString aText(m_xFonts->get_active_text());
|
|
if (!aText.isEmpty())
|
|
{
|
|
// use own StyleNames
|
|
const SmFontStyles &rStyles = GetFontStyles();
|
|
for (sal_uInt16 i = 0; i < SmFontStyles::GetCount(); ++i)
|
|
m_xStyles->append_text(rStyles.GetStyleName(i));
|
|
|
|
assert(m_xStyles->get_count() > 0 && "Sm : no styles available");
|
|
m_xStyles->set_active(0);
|
|
}
|
|
}
|
|
|
|
SmSym* SmSymDefineDialog::GetSymbol(const weld::ComboBox& rComboBox)
|
|
{
|
|
assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong combobox");
|
|
return m_aSymbolMgrCopy.GetSymbolByUiName(rComboBox.get_active_text());
|
|
}
|
|
|
|
IMPL_LINK(SmSymDefineDialog, OldSymbolChangeHdl, weld::ComboBox&, rComboBox, void)
|
|
{
|
|
(void) rComboBox;
|
|
assert(&rComboBox == m_xOldSymbols.get() && "Sm : wrong argument");
|
|
SelectSymbol(*m_xOldSymbols, m_xOldSymbols->get_active_text(), false);
|
|
}
|
|
|
|
IMPL_LINK( SmSymDefineDialog, OldSymbolSetChangeHdl, weld::ComboBox&, rComboBox, void )
|
|
{
|
|
(void) rComboBox;
|
|
assert(&rComboBox == m_xOldSymbolSets.get() && "Sm : wrong argument");
|
|
SelectSymbolSet(*m_xOldSymbolSets, m_xOldSymbolSets->get_active_text(), false);
|
|
}
|
|
|
|
IMPL_LINK(SmSymDefineDialog, ModifyHdl, weld::ComboBox&, rComboBox, void)
|
|
{
|
|
// remember cursor position for later restoring of it
|
|
int nStartPos, nEndPos;
|
|
rComboBox.get_entry_selection_bounds(nStartPos, nEndPos);
|
|
|
|
if (&rComboBox == m_xSymbols.get())
|
|
SelectSymbol(*m_xSymbols, m_xSymbols->get_active_text(), false);
|
|
else if (&rComboBox == m_xSymbolSets.get())
|
|
SelectSymbolSet(*m_xSymbolSets, m_xSymbolSets->get_active_text(), false);
|
|
else if (&rComboBox == m_xOldSymbols.get())
|
|
// allow only names from the list
|
|
SelectSymbol(*m_xOldSymbols, m_xOldSymbols->get_active_text(), true);
|
|
else if (&rComboBox == m_xOldSymbolSets.get())
|
|
// allow only names from the list
|
|
SelectSymbolSet(*m_xOldSymbolSets, m_xOldSymbolSets->get_active_text(), true);
|
|
else if (&rComboBox == m_xStyles.get())
|
|
// allow only names from the list (that's the case here anyway)
|
|
SelectStyle(m_xStyles->get_active_text(), true);
|
|
else
|
|
SAL_WARN("starmath", "wrong combobox argument");
|
|
|
|
rComboBox.select_entry_region(nStartPos, nEndPos);
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
IMPL_LINK(SmSymDefineDialog, FontChangeHdl, weld::ComboBox&, rListBox, void)
|
|
{
|
|
(void) rListBox;
|
|
assert(&rListBox == m_xFonts.get() && "Sm : wrong argument");
|
|
|
|
SelectFont(m_xFonts->get_active_text());
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SmSymDefineDialog, SubsetChangeHdl, weld::ComboBox&, void)
|
|
{
|
|
int nPos = m_xFontsSubsetLB->get_active();
|
|
if (nPos != -1)
|
|
{
|
|
const Subset* pSubset = weld::fromId<const Subset*>(m_xFontsSubsetLB->get_active_id());
|
|
if (pSubset)
|
|
{
|
|
m_xCharsetDisplay->SelectCharacter( pSubset->GetRangeMin() );
|
|
}
|
|
}
|
|
}
|
|
|
|
IMPL_LINK( SmSymDefineDialog, StyleChangeHdl, weld::ComboBox&, rComboBox, void )
|
|
{
|
|
(void) rComboBox;
|
|
assert(&rComboBox == m_xStyles.get() && "Sm : wrong argument");
|
|
|
|
SelectStyle(m_xStyles->get_active_text());
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SmSymDefineDialog, CharHighlightHdl, SvxShowCharSet*, void)
|
|
{
|
|
sal_UCS4 cChar = m_xCharsetDisplay->GetSelectCharacter();
|
|
|
|
if (m_xSubsetMap)
|
|
{
|
|
const Subset* pSubset = m_xSubsetMap->GetSubsetByUnicode(cChar);
|
|
if (pSubset)
|
|
m_xFontsSubsetLB->set_active_text(pSubset->GetName());
|
|
else
|
|
m_xFontsSubsetLB->set_active(-1);
|
|
}
|
|
|
|
m_aSymbolDisplay.SetSymbol(cChar, m_xCharsetDisplay->GetFont());
|
|
|
|
UpdateButtons();
|
|
|
|
// display Unicode position as symbol name while iterating over characters
|
|
const OUString aHex(OUString::number(cChar, 16).toAsciiUpperCase());
|
|
const OUString aPattern( (aHex.getLength() > 4) ? u"Ux000000"_ustr : u"Ux0000"_ustr );
|
|
OUString aUnicodePos = aPattern.subView( 0, aPattern.getLength() - aHex.getLength() ) +
|
|
aHex;
|
|
m_xSymbols->set_entry_text(aUnicodePos);
|
|
m_xSymbolName->set_label(aUnicodePos);
|
|
}
|
|
|
|
IMPL_LINK( SmSymDefineDialog, AddClickHdl, weld::Button&, rButton, void )
|
|
{
|
|
(void) rButton;
|
|
assert(&rButton == m_xAddBtn.get() && "Sm : wrong argument");
|
|
assert(rButton.get_sensitive() && "Sm : requirements met ??");
|
|
|
|
// add symbol
|
|
const SmSym aNewSymbol(m_xSymbols->get_active_text(), m_xCharsetDisplay->GetFont(),
|
|
m_xCharsetDisplay->GetSelectCharacter(), m_xSymbolSets->get_active_text());
|
|
//OSL_ENSURE( m_aSymbolMgrCopy.GetSymbolByUiName(aTmpSymbolName) == NULL, "symbol already exists" );
|
|
m_aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol );
|
|
|
|
// update display of new symbol
|
|
m_aSymbolDisplay.SetSymbol( &aNewSymbol );
|
|
m_xSymbolName->set_label(aNewSymbol.GetUiName());
|
|
m_xSymbolSetName->set_label(aNewSymbol.GetSymbolSetName());
|
|
|
|
// update list box entries
|
|
FillSymbolSets(*m_xOldSymbolSets, false);
|
|
FillSymbolSets(*m_xSymbolSets, false);
|
|
FillSymbols(*m_xOldSymbols, false);
|
|
FillSymbols(*m_xSymbols, false);
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
IMPL_LINK( SmSymDefineDialog, ChangeClickHdl, weld::Button&, rButton, void )
|
|
{
|
|
(void) rButton;
|
|
assert(&rButton == m_xChangeBtn.get() && "Sm : wrong argument");
|
|
assert(m_xChangeBtn->get_sensitive() && "Sm : requirements met ??");
|
|
|
|
// get new Symbol to use
|
|
//! get font from symbol-disp lay since charset-display does not keep
|
|
//! the bold attribute.
|
|
const SmSym aNewSymbol(m_xSymbols->get_active_text(), m_xCharsetDisplay->GetFont(),
|
|
m_xCharsetDisplay->GetSelectCharacter(), m_xSymbolSets->get_active_text());
|
|
|
|
// remove old symbol if the name was changed then add new one
|
|
const bool bNameChanged = m_xOldSymbols->get_active_text() != m_xSymbols->get_active_text();
|
|
if (bNameChanged)
|
|
m_aSymbolMgrCopy.RemoveSymbol(m_xOldSymbols->get_active_text());
|
|
m_aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol, true );
|
|
|
|
// clear display for original symbol if necessary
|
|
if (bNameChanged)
|
|
SetOrigSymbol(nullptr, OUString());
|
|
|
|
// update display of new symbol
|
|
m_aSymbolDisplay.SetSymbol(&aNewSymbol);
|
|
m_xSymbolName->set_label(aNewSymbol.GetUiName());
|
|
m_xSymbolSetName->set_label(aNewSymbol.GetSymbolSetName());
|
|
|
|
// update list box entries
|
|
FillSymbolSets(*m_xOldSymbolSets, false);
|
|
FillSymbolSets(*m_xSymbolSets, false);
|
|
FillSymbols(*m_xOldSymbols, false);
|
|
FillSymbols(*m_xSymbols, false);
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
IMPL_LINK(SmSymDefineDialog, DeleteClickHdl, weld::Button&, rButton, void)
|
|
{
|
|
(void) rButton;
|
|
assert(&rButton == m_xDeleteBtn.get() && "Sm : wrong argument");
|
|
assert(m_xDeleteBtn->get_sensitive() && "Sm : requirements met ??");
|
|
|
|
if (m_xOrigSymbol)
|
|
{
|
|
m_aSymbolMgrCopy.RemoveSymbol(m_xOrigSymbol->GetUiName());
|
|
|
|
// clear display for original symbol
|
|
SetOrigSymbol(nullptr, OUString());
|
|
|
|
// update list box entries
|
|
FillSymbolSets(*m_xOldSymbolSets, false);
|
|
FillSymbolSets(*m_xSymbolSets, false);
|
|
FillSymbols(*m_xOldSymbols ,false);
|
|
FillSymbols(*m_xSymbols ,false);
|
|
}
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
void SmSymDefineDialog::UpdateButtons()
|
|
{
|
|
bool bAdd = false,
|
|
bChange = false,
|
|
bDelete = false;
|
|
OUString aTmpSymbolName(m_xSymbols->get_active_text()),
|
|
aTmpSymbolSetName(m_xSymbolSets->get_active_text());
|
|
|
|
if (!aTmpSymbolName.isEmpty() && !aTmpSymbolSetName.isEmpty())
|
|
{
|
|
// are all settings equal?
|
|
//! (Font-, Style- and SymbolSet name comparison is not case sensitive)
|
|
bool bEqual = m_xOrigSymbol
|
|
&& aTmpSymbolSetName.equalsIgnoreAsciiCase(m_xOldSymbolSetName->get_label())
|
|
&& aTmpSymbolName == m_xOrigSymbol->GetUiName()
|
|
&& m_xFonts->get_active_text().equalsIgnoreAsciiCase(
|
|
m_xOrigSymbol->GetFace().GetFamilyName())
|
|
&& m_xStyles->get_active_text().equalsIgnoreAsciiCase(
|
|
GetFontStyles().GetStyleName(m_xOrigSymbol->GetFace()))
|
|
&& m_xCharsetDisplay->GetSelectCharacter() == m_xOrigSymbol->GetCharacter();
|
|
|
|
// only add it if there isn't already a symbol with the same name
|
|
bAdd = m_aSymbolMgrCopy.GetSymbolByUiName(aTmpSymbolName) == nullptr;
|
|
|
|
// only delete it if all settings are equal
|
|
bDelete = bool(m_xOrigSymbol);
|
|
|
|
// only change it if the old symbol exists and the new one is different
|
|
bChange = m_xOrigSymbol && !bEqual;
|
|
}
|
|
|
|
m_xAddBtn->set_sensitive(bAdd);
|
|
m_xChangeBtn->set_sensitive(bChange);
|
|
m_xDeleteBtn->set_sensitive(bDelete);
|
|
}
|
|
|
|
SmSymDefineDialog::SmSymDefineDialog(weld::Window* pParent, OutputDevice *pFntListDevice, SmSymbolManager &rMgr)
|
|
: GenericDialogController(pParent, u"modules/smath/ui/symdefinedialog.ui"_ustr, u"EditSymbols"_ustr)
|
|
, m_xVirDev(VclPtr<VirtualDevice>::Create())
|
|
, m_rSymbolMgr(rMgr)
|
|
, m_xFontList(new FontList(pFntListDevice))
|
|
, m_xOldSymbols(m_xBuilder->weld_combo_box(u"oldSymbols"_ustr))
|
|
, m_xOldSymbolSets(m_xBuilder->weld_combo_box(u"oldSymbolSets"_ustr))
|
|
, m_xSymbols(m_xBuilder->weld_combo_box(u"symbols"_ustr))
|
|
, m_xSymbolSets(m_xBuilder->weld_combo_box(u"symbolSets"_ustr))
|
|
, m_xFonts(m_xBuilder->weld_combo_box(u"fonts"_ustr))
|
|
, m_xFontsSubsetLB(m_xBuilder->weld_combo_box(u"fontsSubsetLB"_ustr))
|
|
, m_xStyles(m_xBuilder->weld_combo_box(u"styles"_ustr))
|
|
, m_xOldSymbolName(m_xBuilder->weld_label(u"oldSymbolName"_ustr))
|
|
, m_xOldSymbolSetName(m_xBuilder->weld_label(u"oldSymbolSetName"_ustr))
|
|
, m_xSymbolName(m_xBuilder->weld_label(u"symbolName"_ustr))
|
|
, m_xSymbolSetName(m_xBuilder->weld_label(u"symbolSetName"_ustr))
|
|
, m_xAddBtn(m_xBuilder->weld_button(u"add"_ustr))
|
|
, m_xChangeBtn(m_xBuilder->weld_button(u"modify"_ustr))
|
|
, m_xDeleteBtn(m_xBuilder->weld_button(u"delete"_ustr))
|
|
, m_xOldSymbolDisplay(new weld::CustomWeld(*m_xBuilder, u"oldSymbolDisplay"_ustr, m_aOldSymbolDisplay))
|
|
, m_xSymbolDisplay(new weld::CustomWeld(*m_xBuilder, u"symbolDisplay"_ustr, m_aSymbolDisplay))
|
|
, m_xCharsetDisplay(new SvxShowCharSet(m_xBuilder->weld_scrolled_window(u"showscroll"_ustr, true), m_xVirDev))
|
|
, m_xCharsetDisplayArea(new weld::CustomWeld(*m_xBuilder, u"charsetDisplay"_ustr, *m_xCharsetDisplay))
|
|
{
|
|
// auto completion is troublesome since that symbols character also gets automatically selected in the
|
|
// display and if the user previously selected a character to define/redefine that one this is bad
|
|
m_xOldSymbols->set_entry_completion(false);
|
|
m_xSymbols->set_entry_completion(false);
|
|
|
|
FillFonts();
|
|
if (m_xFonts->get_count() > 0)
|
|
SelectFont(m_xFonts->get_text(0));
|
|
|
|
SetSymbolSetManager(m_rSymbolMgr);
|
|
|
|
m_xOldSymbols->connect_changed(LINK(this, SmSymDefineDialog, OldSymbolChangeHdl));
|
|
m_xOldSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, OldSymbolSetChangeHdl));
|
|
m_xSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
|
|
m_xOldSymbolSets->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
|
|
m_xSymbols->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
|
|
m_xOldSymbols->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
|
|
m_xStyles->connect_changed(LINK(this, SmSymDefineDialog, ModifyHdl));
|
|
m_xFonts->connect_changed(LINK(this, SmSymDefineDialog, FontChangeHdl));
|
|
m_xFontsSubsetLB->connect_changed(LINK(this, SmSymDefineDialog, SubsetChangeHdl));
|
|
m_xStyles->connect_changed(LINK(this, SmSymDefineDialog, StyleChangeHdl));
|
|
m_xAddBtn->connect_clicked(LINK(this, SmSymDefineDialog, AddClickHdl));
|
|
m_xChangeBtn->connect_clicked(LINK(this, SmSymDefineDialog, ChangeClickHdl));
|
|
m_xDeleteBtn->connect_clicked(LINK(this, SmSymDefineDialog, DeleteClickHdl));
|
|
m_xCharsetDisplay->SetHighlightHdl( LINK( this, SmSymDefineDialog, CharHighlightHdl ) );
|
|
}
|
|
|
|
SmSymDefineDialog::~SmSymDefineDialog()
|
|
{
|
|
}
|
|
|
|
short SmSymDefineDialog::run()
|
|
{
|
|
short nResult = GenericDialogController::run();
|
|
|
|
// apply changes if dialog was closed by clicking OK
|
|
if (m_aSymbolMgrCopy.IsModified() && nResult == RET_OK)
|
|
m_rSymbolMgr = m_aSymbolMgrCopy;
|
|
|
|
return nResult;
|
|
}
|
|
|
|
void SmSymDefineDialog::SetSymbolSetManager(const SmSymbolManager &rMgr)
|
|
{
|
|
m_aSymbolMgrCopy = rMgr;
|
|
|
|
// Set the modified flag of the copy to false so that
|
|
// we can check later on if anything has been changed
|
|
m_aSymbolMgrCopy.SetModified(false);
|
|
|
|
FillSymbolSets(*m_xOldSymbolSets);
|
|
if (m_xOldSymbolSets->get_count() > 0)
|
|
SelectSymbolSet(m_xOldSymbolSets->get_text(0));
|
|
FillSymbolSets(*m_xSymbolSets);
|
|
if (m_xSymbolSets->get_count() > 0)
|
|
SelectSymbolSet(m_xSymbolSets->get_text(0));
|
|
FillSymbols(*m_xOldSymbols);
|
|
if (m_xOldSymbols->get_count() > 0)
|
|
SelectSymbol(m_xOldSymbols->get_text(0));
|
|
FillSymbols(*m_xSymbols);
|
|
if (m_xSymbols->get_count() > 0)
|
|
SelectSymbol(m_xSymbols->get_text(0));
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
bool SmSymDefineDialog::SelectSymbolSet(weld::ComboBox& rComboBox,
|
|
std::u16string_view rSymbolSetName, bool bDeleteText)
|
|
{
|
|
assert((&rComboBox == m_xOldSymbolSets.get() || &rComboBox == m_xSymbolSets.get()) && "Sm : wrong ComboBox");
|
|
|
|
// trim SymbolName (no leading and trailing blanks)
|
|
OUString aNormName( comphelper::string::strip(rSymbolSetName, ' ') );
|
|
// and remove possible deviations within the input
|
|
rComboBox.set_entry_text(aNormName);
|
|
|
|
bool bRet = false;
|
|
int nPos = rComboBox.find_text(aNormName);
|
|
|
|
if (nPos != -1)
|
|
{
|
|
rComboBox.set_active(nPos);
|
|
bRet = true;
|
|
}
|
|
else if (bDeleteText)
|
|
rComboBox.set_entry_text(OUString());
|
|
|
|
bool bIsOld = &rComboBox == m_xOldSymbolSets.get();
|
|
|
|
// setting the SymbolSet name at the associated display
|
|
weld::Label& rFT = bIsOld ? *m_xOldSymbolSetName : *m_xSymbolSetName;
|
|
rFT.set_label(rComboBox.get_active_text());
|
|
|
|
// set the symbol name which belongs to the SymbolSet at the associated combobox
|
|
weld::ComboBox& rCB = bIsOld ? *m_xOldSymbols : *m_xSymbols;
|
|
FillSymbols(rCB, false);
|
|
|
|
// display a valid respectively no symbol when changing the SymbolSets
|
|
if (bIsOld)
|
|
{
|
|
OUString aTmpOldSymbolName;
|
|
if (m_xOldSymbols->get_count() > 0)
|
|
aTmpOldSymbolName = m_xOldSymbols->get_text(0);
|
|
SelectSymbol(*m_xOldSymbols, aTmpOldSymbolName, true);
|
|
}
|
|
|
|
UpdateButtons();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void SmSymDefineDialog::SetOrigSymbol(const SmSym *pSymbol,
|
|
const OUString &rSymbolSetName)
|
|
{
|
|
// clear old symbol
|
|
m_xOrigSymbol.reset();
|
|
|
|
OUString aSymName,
|
|
aSymSetName;
|
|
if (pSymbol)
|
|
{
|
|
// set new symbol
|
|
m_xOrigSymbol.reset(new SmSym(*pSymbol));
|
|
|
|
aSymName = pSymbol->GetUiName();
|
|
aSymSetName = rSymbolSetName;
|
|
m_aOldSymbolDisplay.SetSymbol( pSymbol );
|
|
}
|
|
else
|
|
{ // delete displayed symbols
|
|
m_aOldSymbolDisplay.SetText(OUString());
|
|
m_aOldSymbolDisplay.Invalidate();
|
|
}
|
|
m_xOldSymbolName->set_label(aSymName);
|
|
m_xOldSymbolSetName->set_label(aSymSetName);
|
|
}
|
|
|
|
|
|
bool SmSymDefineDialog::SelectSymbol(weld::ComboBox& rComboBox,
|
|
const OUString &rSymbolName, bool bDeleteText)
|
|
{
|
|
assert((&rComboBox == m_xOldSymbols.get() || &rComboBox == m_xSymbols.get()) && "Sm : wrong ComboBox");
|
|
|
|
// trim SymbolName (no blanks)
|
|
OUString aNormName = rSymbolName.replaceAll(" ", "");
|
|
// and remove possible deviations within the input
|
|
rComboBox.set_entry_text(aNormName);
|
|
|
|
bool bRet = false;
|
|
int nPos = rComboBox.find_text(aNormName);
|
|
|
|
bool bIsOld = &rComboBox == m_xOldSymbols.get();
|
|
|
|
if (nPos != -1)
|
|
{
|
|
rComboBox.set_active(nPos);
|
|
|
|
if (!bIsOld)
|
|
{
|
|
const SmSym *pSymbol = GetSymbol(*m_xSymbols);
|
|
if (pSymbol)
|
|
{
|
|
// choose font and style accordingly
|
|
const vcl::Font &rFont = pSymbol->GetFace();
|
|
SelectFont(rFont.GetFamilyName(), false);
|
|
SelectStyle(GetFontStyles().GetStyleName(rFont), false);
|
|
|
|
// Since setting the Font via the Style name of the SymbolFonts doesn't
|
|
// work really well (e.g. it can be empty even though the font itself is
|
|
// bold or italic) we're manually setting the Font with respect to the Symbol
|
|
m_xCharsetDisplay->SetFont(rFont);
|
|
m_aSymbolDisplay.SetFont(rFont);
|
|
|
|
// select associated character
|
|
SelectChar(pSymbol->GetCharacter());
|
|
|
|
// since SelectChar will also set the unicode point as text in the
|
|
// symbols box, we have to set the symbol name again to get that one displayed
|
|
m_xSymbols->set_entry_text(pSymbol->GetUiName());
|
|
}
|
|
}
|
|
|
|
bRet = true;
|
|
}
|
|
else if (bDeleteText)
|
|
rComboBox.set_entry_text(OUString());
|
|
|
|
if (bIsOld)
|
|
{
|
|
// if there's a change of the old symbol, show only the available ones, otherwise show none
|
|
const SmSym *pOldSymbol = nullptr;
|
|
OUString aTmpOldSymbolSetName;
|
|
if (nPos != -1)
|
|
{
|
|
pOldSymbol = m_aSymbolMgrCopy.GetSymbolByUiName(aNormName);
|
|
aTmpOldSymbolSetName = m_xOldSymbolSets->get_active_text();
|
|
}
|
|
SetOrigSymbol(pOldSymbol, aTmpOldSymbolSetName);
|
|
}
|
|
else
|
|
m_xSymbolName->set_label(rComboBox.get_active_text());
|
|
|
|
UpdateButtons();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
void SmSymDefineDialog::SetFont(const OUString &rFontName, std::u16string_view rStyleName)
|
|
{
|
|
// get Font (FontInfo) matching name and style
|
|
FontMetric aFontMetric;
|
|
if (m_xFontList)
|
|
aFontMetric = m_xFontList->Get(rFontName, WEIGHT_NORMAL, ITALIC_NONE);
|
|
SetFontStyle(rStyleName, aFontMetric);
|
|
|
|
m_xCharsetDisplay->SetFont(aFontMetric);
|
|
m_aSymbolDisplay.SetFont(aFontMetric);
|
|
|
|
// update subset listbox for new font's unicode subsets
|
|
FontCharMapRef xFontCharMap = m_xCharsetDisplay->GetFontCharMap();
|
|
m_xSubsetMap.reset(new SubsetMap( xFontCharMap ));
|
|
|
|
m_xFontsSubsetLB->clear();
|
|
bool bFirst = true;
|
|
for (auto & subset : m_xSubsetMap->GetSubsetMap())
|
|
{
|
|
m_xFontsSubsetLB->append(weld::toId(&subset), subset.GetName());
|
|
// subset must live at least as long as the selected font !!!
|
|
if (bFirst)
|
|
m_xFontsSubsetLB->set_active(0);
|
|
bFirst = false;
|
|
}
|
|
if (bFirst)
|
|
m_xFontsSubsetLB->set_active(-1);
|
|
m_xFontsSubsetLB->set_sensitive(!bFirst);
|
|
}
|
|
|
|
bool SmSymDefineDialog::SelectFont(const OUString &rFontName, bool bApplyFont)
|
|
{
|
|
bool bRet = false;
|
|
int nPos = m_xFonts->find_text(rFontName);
|
|
|
|
if (nPos != -1)
|
|
{
|
|
m_xFonts->set_active(nPos);
|
|
if (m_xStyles->get_count() > 0)
|
|
SelectStyle(m_xStyles->get_text(0));
|
|
if (bApplyFont)
|
|
{
|
|
SetFont(m_xFonts->get_active_text(), m_xStyles->get_active_text());
|
|
m_aSymbolDisplay.SetSymbol(m_xCharsetDisplay->GetSelectCharacter(), m_xCharsetDisplay->GetFont());
|
|
}
|
|
bRet = true;
|
|
}
|
|
else
|
|
m_xFonts->set_active(-1);
|
|
FillStyles();
|
|
|
|
UpdateButtons();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
bool SmSymDefineDialog::SelectStyle(const OUString &rStyleName, bool bApplyFont)
|
|
{
|
|
bool bRet = false;
|
|
int nPos = m_xStyles->find_text(rStyleName);
|
|
|
|
// if the style is not available take the first available one (if existent)
|
|
if (nPos == -1 && m_xStyles->get_count() > 0)
|
|
nPos = 0;
|
|
|
|
if (nPos != -1)
|
|
{
|
|
m_xStyles->set_active(nPos);
|
|
if (bApplyFont)
|
|
{
|
|
SetFont(m_xFonts->get_active_text(), m_xStyles->get_active_text());
|
|
m_aSymbolDisplay.SetSymbol(m_xCharsetDisplay->GetSelectCharacter(), m_xCharsetDisplay->GetFont());
|
|
}
|
|
bRet = true;
|
|
}
|
|
else
|
|
m_xStyles->set_entry_text(OUString());
|
|
|
|
UpdateButtons();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void SmSymDefineDialog::SelectChar(sal_Unicode cChar)
|
|
{
|
|
m_xCharsetDisplay->SelectCharacter( cChar );
|
|
m_aSymbolDisplay.SetSymbol(cChar, m_xCharsetDisplay->GetFont());
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|