summaryrefslogtreecommitdiff
path: root/starmath/source
diff options
context:
space:
mode:
authorHeiko Tietze <tietze.heiko@gmail.com>2024-11-19 18:04:04 +0100
committerHeiko Tietze <heiko.tietze@documentfoundation.org>2024-11-26 13:56:48 +0100
commitf395e6599facba41392eac3d646a0d505868e6fa (patch)
treec31862731252a08babbc7c9525e7af84d3f749d0 /starmath/source
parentf81af8f7a5e8f86d4214bc328c44632841fbec2b (diff)
Resolves tdf#163685 - Save user-defined formula
Change-Id: I88a1c40d3e97d77c289c8b670b52dca50dea126f Co-authored-by: Rafael Lima <rafael.palma.lima@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176788 Reviewed-by: Rafael Lima <rafael.palma.lima@gmail.com> Tested-by: Jenkins
Diffstat (limited to 'starmath/source')
-rw-r--r--starmath/source/ElementsDockingWindow.cxx87
-rw-r--r--starmath/source/SmElementsPanel.cxx22
-rw-r--r--starmath/source/SmElementsPanel.hxx6
-rw-r--r--starmath/source/cfgitem.cxx44
-rw-r--r--starmath/source/view.cxx38
5 files changed, 172 insertions, 25 deletions
diff --git a/starmath/source/ElementsDockingWindow.cxx b/starmath/source/ElementsDockingWindow.cxx
index 351e4773b6bc..f202d1bd74e0 100644
--- a/starmath/source/ElementsDockingWindow.cxx
+++ b/starmath/source/ElementsDockingWindow.cxx
@@ -460,6 +460,7 @@ const std::vector<TranslateId> s_a5Categories{
RID_CATEGORY_FORMATS,
RID_CATEGORY_OTHERS,
RID_CATEGORY_EXAMPLES,
+ RID_CATEGORY_USERDEFINED,
};
template <size_t N>
@@ -493,24 +494,30 @@ struct ElementData
{
OUString maElementSource;
OUString maHelpText;
- ElementData(const OUString& aElementSource, const OUString& aHelpText)
+ int maPos;
+ ElementData(const OUString& aElementSource, const OUString& aHelpText, const int& aPos)
: maElementSource(aElementSource)
, maHelpText(aHelpText)
+ , maPos(aPos)
{
}
};
-SmElementsControl::SmElementsControl(std::unique_ptr<weld::IconView> pIconView)
+SmElementsControl::SmElementsControl(std::unique_ptr<weld::IconView> pIconView,
+ std::unique_ptr<weld::Menu> pMenu)
: mpDocShell(new SmDocShell(SfxModelFlags::EMBEDDED_OBJECT))
, mnCurrentSetIndex(-1)
, m_nSmSyntaxVersion(SmModule::get()->GetConfig()->GetDefaultSmSyntaxVersion())
+ , m_bAllowDelete(false)
, mpIconView(std::move(pIconView))
+ , mxPopup(std::move(pMenu))
{
maParser.reset(starmathdatabase::GetVersionSmParser(m_nSmSyntaxVersion));
maParser->SetImportSymbolNames(true);
mpIconView->connect_query_tooltip(LINK(this, SmElementsControl, QueryTooltipHandler));
mpIconView->connect_item_activated(LINK(this, SmElementsControl, ElementActivatedHandler));
+ mpIconView->connect_mouse_press(LINK(this, SmElementsControl, MousePressHdl));
}
SmElementsControl::~SmElementsControl()
@@ -585,7 +592,7 @@ void SmElementsControl::addElement(const OUString& aElementVisual, const OUStrin
pDevice->SetOutputSizePixel(aSize);
SmDrawingVisitor(*pDevice, pDevice->PixelToLogic(Point(5, 0)), pNode.get(), maFormat);
- maItemDatas.push_back(std::make_unique<ElementData>(aElementSource, aHelpText));
+ maItemDatas.push_back(std::make_unique<ElementData>(aElementSource, aHelpText, maItemDatas.size()));
const OUString aId(weld::toId(maItemDatas.back().get()));
mpIconView->insert(-1, nullptr, &aId, pDevice, nullptr);
if (mpIconView->get_item_width() < aSize.Width())
@@ -602,9 +609,14 @@ OUString SmElementsControl::GetElementHelpText(const OUString& itemId)
return weld::fromId<ElementData*>(itemId)->maHelpText;
}
-void SmElementsControl::setElementSetIndex(int nSetIndex)
+int SmElementsControl::GetElementPos(const OUString& itemId)
{
- if (mnCurrentSetIndex == nSetIndex)
+ return weld::fromId<ElementData*>(itemId)->maPos;
+}
+
+void SmElementsControl::setElementSetIndex(int nSetIndex, bool bForceBuild)
+{
+ if (!bForceBuild && mnCurrentSetIndex == nSetIndex)
return;
mnCurrentSetIndex = nSetIndex;
build();
@@ -617,25 +629,36 @@ void SmElementsControl::addElements(int nCategory)
mpIconView->set_item_width(0);
maItemDatas.clear();
- assert(nCategory >= 0 && o3tl::make_unsigned(nCategory) < s_a5CategoryDescriptions.size());
-
- const auto& [aElementsArray, aElementsArraySize] = s_a5CategoryDescriptions[nCategory];
-
- for (size_t i = 0; i < aElementsArraySize; i++)
+ if (o3tl::make_unsigned(nCategory) < s_a5CategoryDescriptions.size())
{
- const auto& [element, elementHelp, elementVisual, visualTranslatable] = aElementsArray[i];
- if (element.empty())
+ const auto& [aElementsArray, aElementsArraySize] = s_a5CategoryDescriptions[nCategory];
+
+ for (size_t i = 0; i < aElementsArraySize; i++)
{
- mpIconView->append_separator({});
+ const auto& [element, elementHelp, elementVisual, visualTranslatable] = aElementsArray[i];
+ if (element.empty())
+ {
+ mpIconView->append_separator({});
+ }
+ else
+ {
+ OUString aElement(element);
+ OUString aVisual(elementVisual.empty() ? aElement : OUString(elementVisual));
+ if (visualTranslatable)
+ aVisual = aVisual.replaceFirst("$1", SmResId(visualTranslatable));
+ OUString aHelp(elementHelp ? SmResId(elementHelp) : OUString());
+ addElement(aVisual, aElement, aHelp);
+ }
}
- else
+ }
+ else
+ {
+ css::uno::Sequence<OUString> sNames = SmModule::get()->GetConfig()->LoadUserDefinedNames();
+ OUString sFormula;
+ for (int i = 0; i < sNames.getLength(); i++)
{
- OUString aElement(element);
- OUString aVisual(elementVisual.empty() ? aElement : OUString(elementVisual));
- if (visualTranslatable)
- aVisual = aVisual.replaceFirst("$1", SmResId(visualTranslatable));
- OUString aHelp(elementHelp ? SmResId(elementHelp) : OUString());
- addElement(aVisual, aElement, aHelp);
+ SmModule::get()->GetConfig()->GetUserDefinedFormula(sNames[i], sFormula);
+ addElement(sFormula, sFormula, sNames[i]);
}
}
@@ -649,6 +672,7 @@ void SmElementsControl::build()
{
case 5:
addElements(mnCurrentSetIndex);
+ m_sHoveredItem = "nil"; // if list is empty we must not use the previously hovered item
break;
case 6:
default:
@@ -671,7 +695,10 @@ void SmElementsControl::setSmSyntaxVersion(sal_Int16 nSmSyntaxVersion)
IMPL_LINK(SmElementsControl, QueryTooltipHandler, const weld::TreeIter&, iter, OUString)
{
if (const OUString id = mpIconView->get_id(iter); !id.isEmpty())
+ {
+ m_sHoveredItem = id;
return GetElementHelpText(id);
+ }
return {};
}
@@ -684,4 +711,24 @@ IMPL_LINK_NOARG(SmElementsControl, ElementActivatedHandler, weld::IconView&, boo
return true;
}
+IMPL_LINK(SmElementsControl, MousePressHdl, const MouseEvent&, rEvt, bool)
+{
+ if (rEvt.IsRight() && m_bAllowDelete && (m_sHoveredItem != "nil"))
+ {
+ mpIconView->select( GetElementPos(m_sHoveredItem) );
+ OUString sElementId = mpIconView->get_selected_id();
+ if (!sElementId.isEmpty())
+ {
+ OUString sResponse = mxPopup->popup_at_rect(
+ mpIconView.get(), tools::Rectangle(rEvt.GetPosPixel(), Size(1, 1)));
+ if (sResponse == "delete")
+ {
+ SmModule::get()->GetConfig()->DeleteUserDefinedFormula( GetElementHelpText(m_sHoveredItem) );
+ build(); //refresh view
+ }
+ mpIconView->unselect_all();
+ }
+ }
+ return true;
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/SmElementsPanel.cxx b/starmath/source/SmElementsPanel.cxx
index ad0fb7089890..afe27a80fc50 100644
--- a/starmath/source/SmElementsPanel.cxx
+++ b/starmath/source/SmElementsPanel.cxx
@@ -24,6 +24,7 @@
#include <sfx2/lokcomponenthelpers.hxx>
#include <svl/stritem.hxx>
#include <svl/itemset.hxx>
+#include <svl/hint.hxx>
#include "SmElementsPanel.hxx"
#include <starmath.hrc>
@@ -45,8 +46,8 @@ SmElementsPanel::SmElementsPanel(weld::Widget& rParent, const SfxBindings& rBind
u"modules/smath/ui/sidebarelements_math.ui"_ustr)
, mrBindings(rBindings)
, mxCategoryList(m_xBuilder->weld_combo_box(u"categorylist"_ustr))
- , mxElementsControl(
- std::make_unique<SmElementsControl>(m_xBuilder->weld_icon_view(u"elements"_ustr)))
+ , mxElementsControl(std::make_unique<SmElementsControl>(
+ m_xBuilder->weld_icon_view(u"elements"_ustr), m_xBuilder->weld_menu("deletemenu")))
{
for (const auto& rCategoryId : SmElementsControl::categories())
mxCategoryList->append_text(SmResId(rCategoryId));
@@ -58,6 +59,8 @@ SmElementsPanel::SmElementsPanel(weld::Widget& rParent, const SfxBindings& rBind
mxElementsControl->setElementSetIndex(0);
mxElementsControl->SetSelectHdl(LINK(this, SmElementsPanel, ElementClickHandler));
+
+ StartListening(*GetView());
}
SmElementsPanel::~SmElementsPanel()
@@ -66,6 +69,15 @@ SmElementsPanel::~SmElementsPanel()
mxCategoryList.reset();
}
+void SmElementsPanel::Notify(SfxBroadcaster&, const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::SmNewUserFormula)
+ {
+ mxCategoryList->set_active_text(SmResId(RID_CATEGORY_USERDEFINED));
+ mxElementsControl->setElementSetIndex(mxCategoryList->get_active(), true);
+ }
+}
+
IMPL_LINK(SmElementsPanel, CategorySelectedHandle, weld::ComboBox&, rList, void)
{
const int nActive = rList.get_active();
@@ -74,6 +86,12 @@ IMPL_LINK(SmElementsPanel, CategorySelectedHandle, weld::ComboBox&, rList, void)
mxElementsControl->setElementSetIndex(nActive);
if (SmViewShell* pViewSh = GetView())
mxElementsControl->setSmSyntaxVersion(pViewSh->GetDoc()->GetSmSyntaxVersion());
+
+ // If the "User-defined" category is selected, allow deletion
+ if (mxCategoryList->get_active_text() == SmResId(RID_CATEGORY_USERDEFINED))
+ mxElementsControl->SetAllowDelete(true);
+ else
+ mxElementsControl->SetAllowDelete(false);
}
IMPL_LINK(SmElementsPanel, ElementClickHandler, const OUString&, ElementSource, void)
diff --git a/starmath/source/SmElementsPanel.hxx b/starmath/source/SmElementsPanel.hxx
index c3dde01c6724..c1f4b2ab31f3 100644
--- a/starmath/source/SmElementsPanel.hxx
+++ b/starmath/source/SmElementsPanel.hxx
@@ -21,6 +21,7 @@
#include <sal/config.h>
+#include <svl/lstner.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/sidebar/PanelLayout.hxx>
#include <vcl/customweld.hxx>
@@ -32,10 +33,13 @@
namespace sm::sidebar
{
-class SmElementsPanel : public PanelLayout
+class SmElementsPanel : public PanelLayout, public SfxListener
{
public:
static std::unique_ptr<PanelLayout> Create(weld::Widget& rParent, const SfxBindings& rBindings);
+
+ void Notify(SfxBroadcaster& rBC, const SfxHint& rHint);
+
SmElementsPanel(weld::Widget& rParent, const SfxBindings& rBindings);
~SmElementsPanel();
diff --git a/starmath/source/cfgitem.cxx b/starmath/source/cfgitem.cxx
index 78cdbc97e131..6f0134047d07 100644
--- a/starmath/source/cfgitem.cxx
+++ b/starmath/source/cfgitem.cxx
@@ -44,6 +44,7 @@ using namespace com::sun::star::beans;
constexpr OUString SYMBOL_LIST = u"SymbolList"_ustr;
constexpr OUString FONT_FORMAT_LIST = u"FontFormatList"_ustr;
+constexpr OUString USER_DEFINED_LIST = u"User-Defined"_ustr;
static Sequence< OUString > lcl_GetFontPropertyNames()
{
@@ -575,7 +576,6 @@ void SmMathConfig::SetSymbols( const std::vector< SmSym > &rNewSymbols )
StripFontFormatList( rNewSymbols );
}
-
SmFontFormatList & SmMathConfig::GetFontFormatList()
{
if (!pFontFormatList)
@@ -585,7 +585,6 @@ SmFontFormatList & SmMathConfig::GetFontFormatList()
return *pFontFormatList;
}
-
void SmMathConfig::LoadFontFormatList()
{
if (!pFontFormatList)
@@ -661,6 +660,47 @@ void SmMathConfig::ReadFontFormat( SmFontFormat &rFontFormat,
OSL_ENSURE( bOK, "read FontFormat failed" );
}
+css::uno::Sequence<OUString> SmMathConfig::LoadUserDefinedNames()
+{
+ m_sUserDefinedNames = GetNodeNames(USER_DEFINED_LIST);
+ return m_sUserDefinedNames;
+}
+
+void SmMathConfig::GetUserDefinedFormula(std::u16string_view sName, OUString &sFormula)
+{
+ css::uno::Sequence<OUString> aNames(1);
+ OUString* pName = aNames.getArray();
+ pName[0] = USER_DEFINED_LIST + "/" + sName + "/FormulaText";
+ const Sequence<Any> aValues(GetProperties(aNames));
+ const Any* pValues = aValues.getConstArray();
+ const Any* pVal = pValues;
+ *pVal >>= sFormula;
+}
+
+bool SmMathConfig::HasUserDefinedFormula(std::u16string_view sName)
+{
+ for (int i = 0; i < m_sUserDefinedNames.getLength(); i++)
+ if (m_sUserDefinedNames[i] == sName)
+ return true;
+ return false;
+}
+
+void SmMathConfig::SaveUserDefinedFormula(std::u16string_view sName, const OUString& sElement)
+{
+ Sequence<PropertyValue> pValues(1);
+ auto pArgs = pValues.getArray();
+
+ pArgs[0].Name = USER_DEFINED_LIST + "/" + sName + "/FormulaText";
+ pArgs[0].Value <<= sElement;
+
+ SetSetProperties( USER_DEFINED_LIST, pValues );
+}
+
+void SmMathConfig::DeleteUserDefinedFormula(std::u16string_view sName)
+{
+ Sequence<OUString> aElements { OUString(sName) };
+ ClearNodeElements(USER_DEFINED_LIST, aElements);
+}
void SmMathConfig::SaveFontFormatList()
{
diff --git a/starmath/source/view.cxx b/starmath/source/view.cxx
index f1130e5701de..da074984964d 100644
--- a/starmath/source/view.cxx
+++ b/starmath/source/view.cxx
@@ -89,6 +89,7 @@
#include <mathmlimport.hxx>
#include <cursor.hxx>
#include "accessibility.hxx"
+#include <svl/hint.hxx>
#include <ElementsDockingWindow.hxx>
#include <helpids.h>
@@ -1840,6 +1841,39 @@ void SmViewShell::Execute(SfxRequest& rReq)
GetViewFrame().GetBindings().Invalidate(bRTL ? SID_ATTR_PARA_LEFT_TO_RIGHT : SID_ATTR_PARA_RIGHT_TO_LEFT);
}
break;
+ case SID_SAVE_FORMULA:
+ {
+ OUString aName = "My Formula 1";
+ OUString aDesc(SmResId(STR_USER_DEFINED_FORMULA));
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(
+ pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ aName = pDlg->GetName();
+ if (SmModule::get()->GetConfig()->HasUserDefinedFormula(aName))
+ {
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(
+ GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
+ SmResId(STR_USER_DEFINED_FORMULA_EXISTS).replaceAll("%1", aName)));
+ if (xQuery->run() == RET_NO)
+ break;
+ }
+ SmEditWindow* pEditWin = GetEditWindow();
+ SmModule::get()->GetConfig()->SaveUserDefinedFormula(aName, pEditWin->GetText());
+
+ // Show the Elements sidebar with the "User-defined" entry selected
+ GetViewFrame().ShowChildWindow(SID_SIDEBAR);
+ sfx2::sidebar::Sidebar::ShowPanel(u"MathElementsPanel",
+ GetViewFrame().GetFrame().GetFrameInterface());
+ GetViewFrame().GetBindings().Invalidate( SID_ELEMENTSDOCKINGWINDOW );
+ Broadcast(SfxHint(SfxHintId::SmNewUserFormula));
+ rReq.Ignore ();
+ }
+ pDlg.disposeAndClear();
+ }
+ break;
}
rReq.Done();
}
@@ -1949,6 +1983,10 @@ void SmViewShell::GetState(SfxItemSet &rSet)
case SID_ATTR_PARA_RIGHT_TO_LEFT:
rSet.Put(SfxBoolItem(nWh, GetDoc()->GetFormat().IsRightToLeft()));
break;
+ case SID_SAVE_FORMULA:
+ if (!pEditWin || pEditWin->IsEmpty())
+ rSet.DisableItem(nWh);
+ break;
}
}
}