cui/UIConfig_cui.mk                        |    1 
 cui/source/dialogs/dlgname.cxx             |   22 ++++
 cui/source/options/optaboutconfig.cxx      |  144 ++++++++++++++++++-----------
 cui/uiconfig/ui/numberdialog.ui            |  128 +++++++++++++++++++++++++
 include/cui/dlgname.hxx                    |   28 +++++
 static/CustomTarget_emscripten_fs_image.mk |    1 
 6 files changed, 273 insertions(+), 51 deletions(-)

New commits:
commit 1f874d384228867ee450d3e1d53c821519b51722
Author:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
AuthorDate: Thu Nov 9 16:18:35 2023 +0100
Commit:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
CommitDate: Thu Nov 16 08:03:32 2023 +0100

    expert config: Proper editing support for numbers
    
    Change-Id: Ib97e027cedfdf2c5bb3c956aeee75af25198e498
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159355
    Tested-by: Jenkins
    Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>

diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk
index e36cfc7f11b6..97a4a56f3ecc 100644
--- a/cui/UIConfig_cui.mk
+++ b/cui/UIConfig_cui.mk
@@ -124,6 +124,7 @@ $(eval $(call gb_UIConfig_add_uifiles,cui,\
        cui/uiconfig/ui/newlibdialog \
        cui/uiconfig/ui/newtabledialog \
        cui/uiconfig/ui/newtoolbardialog \
+       cui/uiconfig/ui/numberdialog \
        cui/uiconfig/ui/numberingformatpage \
        cui/uiconfig/ui/numberingoptionspage \
        cui/uiconfig/ui/numberingpositionpage \
diff --git a/cui/source/dialogs/dlgname.cxx b/cui/source/dialogs/dlgname.cxx
index a1f6283d92b5..a96b59290bbd 100644
--- a/cui/source/dialogs/dlgname.cxx
+++ b/cui/source/dialogs/dlgname.cxx
@@ -60,6 +60,28 @@ IMPL_LINK_NOARG(SvxNameDialog, ModifyHdl, weld::Entry&, void)
     m_xEdtName->set_tooltip_text(rTip);
 }
 
+SvxNumberDialog::SvxNumberDialog(weld::Window* pParent, const OUString& rDesc, 
sal_Int64 nValue,
+                                 sal_Int64 nMin, sal_Int64 nMax)
+    : GenericDialogController(pParent, "cui/ui/numberdialog.ui", 
"NumberDialog")
+    , m_xEdtNumber(m_xBuilder->weld_spin_button("number_spinbtn"))
+    , m_xFtDescription(m_xBuilder->weld_label("description_label"))
+{
+    m_xFtDescription->set_label(rDesc);
+    m_xEdtNumber->set_min(nMin);
+    m_xEdtNumber->set_max(nMax);
+    m_xEdtNumber->set_value(nValue);
+}
+
+SvxDecimalNumberDialog::SvxDecimalNumberDialog(weld::Window* pParent, const 
OUString& rDesc,
+                                               double fValue)
+    : GenericDialogController(pParent, "cui/ui/numberdialog.ui", 
"NumberDialog")
+    , m_xEdtNumber(m_xBuilder->weld_formatted_spin_button("number_spinbtn"))
+    , m_xFtDescription(m_xBuilder->weld_label("description_label"))
+{
+    m_xFtDescription->set_label(rDesc);
+    m_xEdtNumber->GetFormatter().SetValue(fValue);
+}
+
 // #i68101#
 // Dialog for editing Object Name
 // plus uniqueness-callback-linkHandler
diff --git a/cui/source/options/optaboutconfig.cxx 
b/cui/source/options/optaboutconfig.cxx
index bdc51afdea51..11806faa8477 100644
--- a/cui/source/options/optaboutconfig.cxx
+++ b/cui/source/options/optaboutconfig.cxx
@@ -654,96 +654,138 @@ IMPL_LINK_NOARG( CuiAboutConfigTabPage, 
StandardHdl_Impl, weld::Button&, void )
     {
         if( bOpenDialog )
         {
-            SvxNameDialog aNameDialog(m_pParent, sDialogValue, sPropertyName);
-            aNameDialog.SetCheckNameHdl( LINK( this, CuiAboutConfigTabPage, 
ValidNameHdl ) );
-            if (aNameDialog.run() == RET_OK )
+            if (sPropertyType == "short" || sPropertyType == "int" || 
sPropertyType == "long")
             {
-                OUString sNewValue = aNameDialog.GetName();
-                bSaveChanges = true;
-                if ( sPropertyType == "short")
+                sal_Int64 nMin = sPropertyType == "short"
+                                     ? SAL_MIN_INT16
+                                     : sPropertyType == "int" ? SAL_MIN_INT32 
: SAL_MIN_INT64;
+                sal_Int64 nMax = sPropertyType == "short"
+                                     ? SAL_MAX_INT16
+                                     : sPropertyType == "int" ? SAL_MAX_INT32 
: SAL_MAX_INT64;
+                SvxNumberDialog aNumberDialog(m_pParent, sPropertyName, 
sDialogValue.toInt64(),
+                                              nMin, nMax);
+                if (aNumberDialog.run() == RET_OK)
                 {
-                    sal_Int16 nShort;
-                    sal_Int32 nNumb = sNewValue.toInt32();
-
-                    //if the value is 0 and length is not 1, there is 
something wrong
-                    if( ( nNumb==0 && sNewValue.getLength()!=1 ) || nNumb > 
SAL_MAX_INT16 || nNumb < SAL_MIN_INT16)
-                        throw uno::Exception("out of range short", nullptr);
-                    nShort = static_cast<sal_Int16>(nNumb);
-                    pProperty->Value <<= nShort;
-                }
-                else if( sPropertyType == "int" )
-                {
-                    sal_Int32 nLong = sNewValue.toInt32();
-                    if( nLong==0 && sNewValue.getLength()!=1)
-                        throw uno::Exception("out of range int", nullptr);
-                    pProperty->Value <<= nLong;
-                }
-                else if( sPropertyType == "long")
-                {
-                    sal_Int64 nHyper = sNewValue.toInt64();
-                    if( nHyper==0 && sNewValue.getLength()!=1)
-                        throw uno::Exception("out of range long", nullptr);
-                    pProperty->Value <<= nHyper;
+                    sal_Int64 nNewValue = aNumberDialog.GetNumber();
+                    if (sPropertyType == "short")
+                    {
+                        pProperty->Value <<= static_cast<sal_Int16>(nNewValue);
+                    }
+                    else if (sPropertyType == "int")
+                    {
+                        pProperty->Value <<= static_cast<sal_Int32>(nNewValue);
+                    }
+                    else if (sPropertyType == "long")
+                    {
+                        pProperty->Value <<= nNewValue;
+                    }
+                    bSaveChanges = true;
+                    sDialogValue = OUString::number(nNewValue);
                 }
-                else if( sPropertyType == "double")
+            }
+            else if( sPropertyType == "double")
+            {
+                SvxDecimalNumberDialog aNumberDialog(m_pParent, sPropertyName, 
sDialogValue.toDouble());
+                if (aNumberDialog.run() == RET_OK)
                 {
-                    double nDoub = sNewValue.toDouble();
-                    if( nDoub ==0 && sNewValue.getLength()!=1)
-                        throw uno::Exception("out of range double", nullptr);
-                    pProperty->Value <<= nDoub;
+                    double fNewValue = aNumberDialog.GetNumber();
+                    pProperty->Value <<= fNewValue;
+                    bSaveChanges = true;
+                    sDialogValue = OUString::number(fNewValue);
                 }
-                else if( sPropertyType == "string" )
+            }
+            else if( sPropertyType == "string" )
+            {
+                SvxNameDialog aNameDialog(m_pParent, sDialogValue, 
sPropertyName);
+                aNameDialog.SetCheckNameHdl( LINK( this, 
CuiAboutConfigTabPage, ValidNameHdl ) );
+                if (aNameDialog.run() == RET_OK )
                 {
-                    pProperty->Value <<= sNewValue;
+                    sDialogValue = aNameDialog.GetName();
+                    pProperty->Value <<= sDialogValue;
+                    bSaveChanges = true;
                 }
-                else if( sPropertyType == "short-list" )
+            }
+            else if( sPropertyType == "short-list" )
+            {
+                SvxNameDialog aNameDialog(m_pParent, sDialogValue, 
sPropertyName);
+                aNameDialog.SetCheckNameHdl( LINK( this, 
CuiAboutConfigTabPage, ValidNameHdl ) );
+                if (aNameDialog.run() == RET_OK )
                 {
+                    sDialogValue = aNameDialog.GetName();
                     //create string sequence from comma separated string
                     //uno::Sequence< OUString > seqStr;
-                    std::vector< OUString > seqStr = commaStringToSequence( 
sNewValue );
+                    std::vector< OUString > seqStr = commaStringToSequence( 
sDialogValue );
 
                     //create appropriate sequence with same size as string 
sequence
                     uno::Sequence< sal_Int16 > seqShort( seqStr.size() );
                     //convert all strings to appropriate type
                     std::transform(seqStr.begin(), seqStr.end(), 
seqShort.getArray(),
-                                   [](const auto& str)
-                                   { return 
static_cast<sal_Int16>(str.toInt32()); });
+                                    [](const auto& str)
+                                    { return 
static_cast<sal_Int16>(str.toInt32()); });
                     pProperty->Value <<= seqShort;
+                    bSaveChanges = true;
                 }
-                else if( sPropertyType == "int-list" )
+
+            }
+            else if( sPropertyType == "int-list" )
+            {
+                SvxNameDialog aNameDialog(m_pParent, sDialogValue, 
sPropertyName);
+                aNameDialog.SetCheckNameHdl( LINK( this, 
CuiAboutConfigTabPage, ValidNameHdl ) );
+                if (aNameDialog.run() == RET_OK )
                 {
-                    std::vector< OUString > seqStrLong = 
commaStringToSequence( sNewValue );
+                    sDialogValue = aNameDialog.GetName();
+                    std::vector< OUString > seqStrLong = 
commaStringToSequence( sDialogValue );
 
                     uno::Sequence< sal_Int32 > seqLong( seqStrLong.size() );
                     std::transform(seqStrLong.begin(), seqStrLong.end(), 
seqLong.getArray(),
                         [](const auto& str) { return str.toInt32(); });
                     pProperty->Value <<= seqLong;
+                    bSaveChanges = true;
                 }
-                else if( sPropertyType == "long-list" )
+            }
+            else if( sPropertyType == "long-list" )
+            {
+                SvxNameDialog aNameDialog(m_pParent, sDialogValue, 
sPropertyName);
+                aNameDialog.SetCheckNameHdl( LINK( this, 
CuiAboutConfigTabPage, ValidNameHdl ) );
+                if (aNameDialog.run() == RET_OK )
                 {
-                    std::vector< OUString > seqStrHyper = 
commaStringToSequence( sNewValue );
+                    sDialogValue = aNameDialog.GetName();
+                    std::vector< OUString > seqStrHyper = 
commaStringToSequence( sDialogValue );
                     uno::Sequence< sal_Int64 > seqHyper( seqStrHyper.size() );
                     std::transform(seqStrHyper.begin(), seqStrHyper.end(), 
seqHyper.getArray(),
                         [](const auto& str) { return str.toInt64(); });
                     pProperty->Value <<= seqHyper;
+                    bSaveChanges = true;
                 }
-                else if( sPropertyType == "double-list" )
+            }
+            else if( sPropertyType == "double-list" )
+            {
+                SvxNameDialog aNameDialog(m_pParent, sDialogValue, 
sPropertyName);
+                aNameDialog.SetCheckNameHdl( LINK( this, 
CuiAboutConfigTabPage, ValidNameHdl ) );
+                if (aNameDialog.run() == RET_OK )
                 {
-                    std::vector< OUString > seqStrDoub = 
commaStringToSequence( sNewValue );
+                    sDialogValue = aNameDialog.GetName();
+                    std::vector< OUString > seqStrDoub = 
commaStringToSequence( sDialogValue );
                     uno::Sequence< double > seqDoub( seqStrDoub.size() );
                     std::transform(seqStrDoub.begin(), seqStrDoub.end(), 
seqDoub.getArray(),
                         [](const auto& str) { return str.toDouble(); });
                     pProperty->Value <<= seqDoub;
+                    bSaveChanges = true;
                 }
-                else if( sPropertyType == "string-list" )
+            }
+            else if( sPropertyType == "string-list" )
+            {
+                SvxNameDialog aNameDialog(m_pParent, sDialogValue, 
sPropertyName);
+                aNameDialog.SetCheckNameHdl( LINK( this, 
CuiAboutConfigTabPage, ValidNameHdl ) );
+                if (aNameDialog.run() == RET_OK )
                 {
-                    pProperty->Value <<= comphelper::containerToSequence( 
commaStringToSequence( sNewValue ));
+                    sDialogValue = aNameDialog.GetName();
+                    pProperty->Value <<= comphelper::containerToSequence( 
commaStringToSequence( sDialogValue ));
+                    bSaveChanges = true;
                 }
-                else //unknown
-                    throw uno::Exception("unknown property type " + 
sPropertyType, nullptr);
-
-                sDialogValue = sNewValue;
             }
+            else //unknown
+                throw uno::Exception("unknown property type " + sPropertyType, 
nullptr);
         }
 
         if(bSaveChanges)
diff --git a/cui/uiconfig/ui/numberdialog.ui b/cui/uiconfig/ui/numberdialog.ui
new file mode 100644
index 000000000000..2db7699f0faf
--- /dev/null
+++ b/cui/uiconfig/ui/numberdialog.ui
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface domain="cui">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="upper">100</property>
+    <property name="step-increment">1</property>
+    <property name="page-increment">10</property>
+  </object>
+  <object class="GtkDialog" id="NumberDialog">
+    <property name="can-focus">False</property>
+    <property name="border-width">6</property>
+    <property name="title" translatable="yes" 
context="numberdialog|NumberDialog">Enter Number</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="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="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">0</property>
+                <property name="secondary">True</property>
+              </packing>
+            </child>
+            <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">1</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">2</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="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="description_label">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="use-underline">True</property>
+                <property name="wrap">True</property>
+                <property name="mnemonic-widget">number_spinbtn</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSpinButton" id="number_spinbtn">
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="adjustment">adjustment1</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-11">help</action-widget>
+      <action-widget response="-5">ok</action-widget>
+      <action-widget response="-6">cancel</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/include/cui/dlgname.hxx b/include/cui/dlgname.hxx
index 7d207d281812..45d7d541ccce 100644
--- a/include/cui/dlgname.hxx
+++ b/include/cui/dlgname.hxx
@@ -20,7 +20,9 @@
 
 #include "cuidllapi.h"
 
+#include <vcl/formatter.hxx>
 #include <vcl/weld.hxx>
+#include <sal/log.hxx>
 
 /// Dialog for editing a name
 class CUI_DLLPUBLIC SvxNameDialog final : public weld::GenericDialogController
@@ -63,6 +65,32 @@ public:
     void SetEditHelpId(const OUString& aHelpId) { 
m_xEdtName->set_help_id(aHelpId); }
 };
 
+/// Dialog for editing a number
+class CUI_DLLPUBLIC SvxNumberDialog final : public 
weld::GenericDialogController
+{
+private:
+    std::unique_ptr<weld::SpinButton> m_xEdtNumber;
+    std::unique_ptr<weld::Label> m_xFtDescription;
+
+public:
+    SvxNumberDialog(weld::Window* pWindow, const OUString& rDesc, sal_Int64 
nValue, sal_Int64 nMin,
+                    sal_Int64 nMax);
+
+    sal_Int64 GetNumber() const { return m_xEdtNumber->get_value(); }
+};
+
+class CUI_DLLPUBLIC SvxDecimalNumberDialog final : public 
weld::GenericDialogController
+{
+private:
+    std::unique_ptr<weld::FormattedSpinButton> m_xEdtNumber;
+    std::unique_ptr<weld::Label> m_xFtDescription;
+
+public:
+    SvxDecimalNumberDialog(weld::Window* pWindow, const OUString& rDesc, 
double fValue);
+
+    double GetNumber() const { return m_xEdtNumber->GetFormatter().GetValue(); 
}
+};
+
 /** #i68101#
     Dialog for editing Object name
     plus uniqueness-callback-linkHandler */
diff --git a/static/CustomTarget_emscripten_fs_image.mk 
b/static/CustomTarget_emscripten_fs_image.mk
index d6d85c17fdbd..3be31b57fc40 100644
--- a/static/CustomTarget_emscripten_fs_image.mk
+++ b/static/CustomTarget_emscripten_fs_image.mk
@@ -144,6 +144,7 @@ gb_emscripten_fs_image_files := \
     $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/cui/ui/newlibdialog.ui 
\
     
$(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/cui/ui/newtabledialog.ui \
     
$(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/cui/ui/newtoolbardialog.ui \
+    $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/cui/ui/numberdialog.ui 
\
     
$(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/cui/ui/numberingformatpage.ui
 \
     
$(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/cui/ui/numberingoptionspage.ui
 \
     
$(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/cui/ui/numberingpositionpage.ui
 \

Reply via email to