diff options
author | Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de> | 2023-11-16 21:33:25 +0100 |
---|---|---|
committer | Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de> | 2023-11-20 08:24:51 +0100 |
commit | 847db3fa1244c2707e1966d3e6579258bb6d8924 (patch) | |
tree | 9b453e79a3adf69a93ff67c39ae7372ea1df4011 | |
parent | c860e7cc974c306961c421be1eb034c78c6c244f (diff) |
tdf#157438 Make string lists editable in expert config
Change-Id: Ia8b8553d547e760c18624c5c599951523b74ac82
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159523
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de>
-rw-r--r-- | cui/UIConfig_cui.mk | 1 | ||||
-rw-r--r-- | cui/source/dialogs/dlgname.cxx | 109 | ||||
-rw-r--r-- | cui/source/options/optaboutconfig.cxx | 37 | ||||
-rw-r--r-- | cui/uiconfig/ui/listdialog.ui | 231 | ||||
-rw-r--r-- | include/cui/dlgname.hxx | 26 |
5 files changed, 389 insertions, 15 deletions
diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk index 97a4a56f3ecc..10acd83c8c39 100644 --- a/cui/UIConfig_cui.mk +++ b/cui/UIConfig_cui.mk @@ -113,6 +113,7 @@ $(eval $(call gb_UIConfig_add_uifiles,cui,\ cui/uiconfig/ui/linetabpage \ cui/uiconfig/ui/lineendstabpage \ cui/uiconfig/ui/linestyletabpage \ + cui/uiconfig/ui/listdialog \ cui/uiconfig/ui/macroassigndialog \ cui/uiconfig/ui/macroassignpage \ cui/uiconfig/ui/macroselectordialog \ diff --git a/cui/source/dialogs/dlgname.cxx b/cui/source/dialogs/dlgname.cxx index a96b59290bbd..a06833bb6ce6 100644 --- a/cui/source/dialogs/dlgname.cxx +++ b/cui/source/dialogs/dlgname.cxx @@ -19,6 +19,8 @@ #include <cui/dlgname.hxx> +#include <comphelper/string.hxx> + /************************************************************************* |* |* Dialog for editing a name @@ -144,4 +146,111 @@ IMPL_LINK_NOARG(SvxObjectTitleDescDialog, DecorativeHdl, weld::Toggleable&, void m_xDescriptionFT->set_sensitive(bEnable); } +SvxListDialog::SvxListDialog(weld::Window* pParent) + : GenericDialogController(pParent, "cui/ui/listdialog.ui", "ListDialog") + , m_xList(m_xBuilder->weld_tree_view("assignlist")) + , m_xAddBtn(m_xBuilder->weld_button("addbtn")) + , m_xRemoveBtn(m_xBuilder->weld_button("removebtn")) + , m_xEditBtn(m_xBuilder->weld_button("editbtn")) +{ + m_xList->set_size_request(m_xList->get_approximate_digit_width() * 54, + m_xList->get_height_rows(6)); + m_xAddBtn->connect_clicked(LINK(this, SvxListDialog, AddHdl_Impl)); + m_xRemoveBtn->connect_clicked(LINK(this, SvxListDialog, RemoveHdl_Impl)); + m_xEditBtn->connect_clicked(LINK(this, SvxListDialog, EditHdl_Impl)); + m_xList->connect_changed(LINK(this, SvxListDialog, SelectHdl_Impl)); + m_xList->connect_row_activated(LINK(this, SvxListDialog, DblClickHdl_Impl)); + + SelectionChanged(); +} + +SvxListDialog::~SvxListDialog() {} + +IMPL_LINK_NOARG(SvxListDialog, AddHdl_Impl, weld::Button&, void) +{ + SvxNameDialog aNameDlg(m_xDialog.get(), "", "blabla"); + + if (!aNameDlg.run()) + return; + OUString sNewText = comphelper::string::strip(aNameDlg.GetName(), ' '); + if (!sNewText.isEmpty()) + { + m_xList->insert_text(-1, sNewText); + m_xList->select(-1); + } +} + +IMPL_LINK_NOARG(SvxListDialog, EditHdl_Impl, weld::Button&, void) { EditEntry(); } + +IMPL_LINK_NOARG(SvxListDialog, SelectHdl_Impl, weld::TreeView&, void) { SelectionChanged(); } + +IMPL_LINK_NOARG(SvxListDialog, DblClickHdl_Impl, weld::TreeView&, bool) +{ + EditEntry(); + return true; +} + +IMPL_LINK_NOARG(SvxListDialog, RemoveHdl_Impl, weld::Button&, void) +{ + int nPos = m_xList->get_selected_index(); + if (nPos == -1) + return; + m_xList->remove(nPos); + int nCount = m_xList->n_children(); + if (nCount) + { + if (nPos >= nCount) + nPos = nCount - 1; + m_xList->select(nPos); + } + SelectionChanged(); +} + +void SvxListDialog::SelectionChanged() +{ + bool bEnable = m_xList->get_selected_index() != -1; + m_xRemoveBtn->set_sensitive(bEnable); + m_xEditBtn->set_sensitive(bEnable); +} + +std::vector<OUString> SvxListDialog::GetEntries() const +{ + int nCount = m_xList->n_children(); + std::vector<OUString> aList; + aList.reserve(nCount); + for (int i = 0; i < nCount; ++i) + aList.push_back(m_xList->get_text(i)); + return aList; +} + +void SvxListDialog::SetEntries(std::vector<OUString> const& rEntries) +{ + m_xList->clear(); + for (auto const& sEntry : rEntries) + { + m_xList->append_text(sEntry); + } + SelectionChanged(); +} + +void SvxListDialog::EditEntry() +{ + int nPos = m_xList->get_selected_index(); + if (nPos == -1) + return; + + OUString sOldText(m_xList->get_selected_text()); + SvxNameDialog aNameDlg(m_xDialog.get(), sOldText, "blabla"); + + if (!aNameDlg.run()) + return; + OUString sNewText = comphelper::string::strip(aNameDlg.GetName(), ' '); + if (!sNewText.isEmpty() && sNewText != sOldText) + { + m_xList->remove(nPos); + m_xList->insert_text(nPos, sNewText); + m_xList->select(nPos); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cui/source/options/optaboutconfig.cxx b/cui/source/options/optaboutconfig.cxx index 362af44cfd7d..bb002d55d0d1 100644 --- a/cui/source/options/optaboutconfig.cxx +++ b/cui/source/options/optaboutconfig.cxx @@ -245,6 +245,21 @@ void CuiAboutConfigTabPage::FillItemSet() } } +namespace +{ +OUString lcl_StringListToString(const uno::Sequence<OUString>& seq) +{ + OUStringBuffer sBuffer; + for (sal_Int32 i = 0; i != seq.getLength(); ++i) + { + if (i != 0) + sBuffer.append(","); + sBuffer.append(seq[i]); + } + return sBuffer.makeStringAndClear(); +} +} + void CuiAboutConfigTabPage::FillItems(const Reference<XNameAccess>& xNameAccess, const weld::TreeIter* pParentEntry, int lineage, bool bLoadAll) @@ -484,15 +499,7 @@ void CuiAboutConfigTabPage::FillItems(const Reference<XNameAccess>& xNameAccess, } else if (sType == "oor:string-list") { - uno::Sequence<OUString> seq = aNode.get<uno::Sequence<OUString>>(); - for (sal_Int32 j = 0; j != seq.getLength(); ++j) - { - if (j != 0) - { - sValue.append(","); - } - sValue.append(seq[j]); - } + sValue = lcl_StringListToString(aNode.get<uno::Sequence<OUString>>()); sType = "string-list"; } else if (sType == "oor:hexBinary-list") @@ -778,13 +785,13 @@ IMPL_LINK_NOARG(CuiAboutConfigTabPage, StandardHdl_Impl, weld::Button&, void) } else if (sPropertyType == "string-list") { - SvxNameDialog aNameDialog(m_pParent, sDialogValue, sPropertyName); - aNameDialog.SetCheckNameHdl(LINK(this, CuiAboutConfigTabPage, ValidNameHdl)); - if (aNameDialog.run() == RET_OK) + SvxListDialog aListDialog(m_pParent); + aListDialog.SetEntries(commaStringToSequence(sDialogValue)); + if (aListDialog.run() == RET_OK) { - sDialogValue = aNameDialog.GetName(); - pProperty->Value - <<= comphelper::containerToSequence(commaStringToSequence(sDialogValue)); + auto seq = comphelper::containerToSequence(aListDialog.GetEntries()); + sDialogValue = lcl_StringListToString(seq); + pProperty->Value <<= seq; bSaveChanges = true; } } diff --git a/cui/uiconfig/ui/listdialog.ui b/cui/uiconfig/ui/listdialog.ui new file mode 100644 index 000000000000..18fffa18640d --- /dev/null +++ b/cui/uiconfig/ui/listdialog.ui @@ -0,0 +1,231 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.40.0 --> +<interface domain="cui"> + <requires lib="gtk+" version="3.20"/> + <object class="GtkTreeStore" id="liststore1"> + <columns> + <!-- column-name text --> + <column type="gchararray"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> + <object class="GtkDialog" id="ListDialog"> + <property name="can-focus">False</property> + <property name="border-width">6</property> + <property name="title" translatable="yes" context="listdialog|ListDialog">Edit List</property> + <property name="modal">True</property> + <property name="default-width">0</property> + <property name="default-height">0</property> + <property name="type-hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area1"> + <property name="can-focus">False</property> + <property name="layout-style">end</property> + <child> + <object class="GtkButton" id="ok"> + <property name="label" translatable="yes" context="stock">_OK</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="can-default">True</property> + <property name="has-default">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="cancel"> + <property name="label" translatable="yes" context="stock">_Cancel</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="help"> + <property name="label" translatable="yes" context="stock">_Help</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + <property name="secondary">True</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="spacing">6</property> + <child> + <!-- n-columns=2 n-rows=2 --> + <object class="GtkGrid" id="grid1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="row-spacing">6</property> + <property name="column-spacing">6</property> + <child> + <object class="GtkScrolledWindow"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="shadow-type">in</property> + <child> + <object class="GtkTreeView" id="assignlist"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="vexpand">True</property> + <property name="model">liststore1</property> + <property name="headers-visible">False</property> + <property name="headers-clickable">False</property> + <property name="search-column">0</property> + <property name="show-expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn1"> + <child> + <object class="GtkCellRendererText" id="cellrenderertext1"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box2"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkButton" id="addbtn"> + <property name="label" translatable="yes" context="listdialog|addbtn">_Add</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="editbtn"> + <property name="label" translatable="yes" context="listdialog|editbtn">_Edit</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="valign">start</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="removebtn"> + <property name="label" translatable="yes" context="listdialog|removebtn">_Remove</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="valign">start</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="description"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="use-underline">True</property> + <property name="mnemonic-widget">assignlist</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + <property name="width">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-5">ok</action-widget> + <action-widget response="-6">cancel</action-widget> + <action-widget response="-11">help</action-widget> + </action-widgets> + </object> +</interface> diff --git a/include/cui/dlgname.hxx b/include/cui/dlgname.hxx index 45d7d541ccce..eb3ac6b3ec17 100644 --- a/include/cui/dlgname.hxx +++ b/include/cui/dlgname.hxx @@ -146,4 +146,30 @@ public: bool IsDecorative() const { return m_xDecorativeCB->get_active(); } }; +/** Generic dialog to edit lists */ +class SvxListDialog : public weld::GenericDialogController +{ +private: + std::unique_ptr<weld::TreeView> m_xList; + std::unique_ptr<weld::Button> m_xAddBtn; + std::unique_ptr<weld::Button> m_xRemoveBtn; + std::unique_ptr<weld::Button> m_xEditBtn; + + DECL_LINK(SelectHdl_Impl, weld::TreeView&, void); + DECL_LINK(DblClickHdl_Impl, weld::TreeView&, bool); + DECL_LINK(AddHdl_Impl, weld::Button&, void); + DECL_LINK(RemoveHdl_Impl, weld::Button&, void); + DECL_LINK(EditHdl_Impl, weld::Button&, void); + + void SelectionChanged(); + +public: + explicit SvxListDialog(weld::Window* pParent); + virtual ~SvxListDialog() override; + + std::vector<OUString> GetEntries() const; + void SetEntries(std::vector<OUString> const& rParams); + void EditEntry(); +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |