sw/inc/fldbas.hxx                |    5 ++++
 sw/inc/usrfld.hxx                |    4 ++-
 sw/source/core/fields/fldbas.cxx |   37 ++++++++++++++++++++++++++++++++
 sw/source/core/fields/usrfld.cxx |    7 +++++-
 sw/source/ui/fldui/fldvar.cxx    |   44 ++++++++++++++++++++++++---------------
 5 files changed, 79 insertions(+), 18 deletions(-)

New commits:
commit 185cf4496d8750c9e4905c4e384252b01b85d130
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Sun Apr 9 14:47:41 2023 +0200
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Mon Apr 10 00:56:42 2023 +0200

    Resolves: tdf#154217 Edit date+time User Field and Set Variable
    
    ... instead of the raw numeric value.
    
    Change-Id: I256cb4fde1e4ea6b0580b3208c5d4948e2573448
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150169
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins

diff --git a/sw/inc/fldbas.hxx b/sw/inc/fldbas.hxx
index 5768d822d853..8ece6e214da1 100644
--- a/sw/inc/fldbas.hxx
+++ b/sw/inc/fldbas.hxx
@@ -442,6 +442,8 @@ public:
     OUString        ExpandValue(const double& rVal, sal_uInt32 nFormat, 
LanguageType nLng) const;
     OUString        DoubleToString(const double &rVal, LanguageType eLng) 
const;
     OUString        DoubleToString(const double &rVal, sal_uInt32 nFormat) 
const;
+    /// Query input or formatted value for dialog.
+    OUString        GetInputOrDateTime( const OUString& rInput, const double& 
rVal, sal_uInt32 nFormat ) const;
 };
 
 class SW_DLLPUBLIC SwValueField : public SwField
@@ -489,6 +491,9 @@ public:
 
     void                    SetExpandedFormula(const OUString& rStr);
     OUString                GetExpandedFormula() const;
+
+    /// Query formula or formatted value for dialog.
+    OUString                GetInputOrDateTime() const;
 };
 
 #endif // INCLUDED_SW_INC_FLDBAS_HXX
diff --git a/sw/inc/usrfld.hxx b/sw/inc/usrfld.hxx
index faedb80671a8..28d582c4c5ac 100644
--- a/sw/inc/usrfld.hxx
+++ b/sw/inc/usrfld.hxx
@@ -52,9 +52,11 @@ public:
 
     OUString                Expand(sal_uInt32 nFormat, sal_uInt16 nSubType, 
LanguageType nLng);
 
-    OUString                GetContent( sal_uInt32 nFormat = 0 );
+    OUString                GetContent( sal_uInt32 nFormat = 0 ) const;
            void             SetContent( const OUString& rStr, sal_uInt32 
nFormat = 0 );
 
+    OUString                GetInputOrDateTime( sal_uInt32 nFormat ) const;
+
     inline bool             IsValid() const;
 
            double           GetValue(SwCalc& rCalc);    // Recalculate member 
nValue.
diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx
index 2f816d208938..f511c047b183 100644
--- a/sw/source/core/fields/fldbas.cxx
+++ b/sw/source/core/fields/fldbas.cxx
@@ -24,6 +24,7 @@
 #include <libxml/xmlwriter.h>
 
 #include <rtl/math.hxx>
+#include <comphelper/string.hxx>
 #include <svl/numformat.hxx>
 #include <svl/zforlist.hxx>
 #include <svl/zformat.hxx>
@@ -648,6 +649,22 @@ OUString SwValueFieldType::DoubleToString( const double 
&rVal,
                                     pFormatter->GetNumDecimalSep()[0], true );
 }
 
+OUString SwValueFieldType::GetInputOrDateTime( const OUString& rInput, const 
double& rVal, sal_uInt32 nFormat ) const
+{
+    if (nFormat && nFormat != SAL_MAX_UINT32 && UseFormat())
+    {
+        SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
+        const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
+        if (pEntry && (pEntry->GetType() & SvNumFormatType::DATETIME))
+        {
+            OUString aEdit;
+            pFormatter->GetInputLineString( rVal, nFormat, aEdit);
+            return aEdit;
+        }
+    }
+    return rInput;
+}
+
 SwValueField::SwValueField( SwValueFieldType* pFieldType, sal_uInt32 nFormat,
                             LanguageType nLng, const double fVal )
     : SwField(pFieldType, nFormat, nLng)
@@ -861,6 +878,26 @@ OUString SwFormulaField::GetExpandedFormula() const
         return GetFormula();
 }
 
+OUString SwFormulaField::GetInputOrDateTime() const
+{
+    // GetFormula() leads to problems with date formats because only the
+    // number string without formatting is returned (additionally that may or
+    // may not use a localized decimal separator due to the convoluted handling
+    // of "formula"). It must be used for expressions though because otherwise
+    // with GetPar2() only the value calculated by SwCalc would be displayed
+    // (instead of test2 = test + 1).
+    // Force a formatted edit value for date+time formats, assuming they are
+    // not editable calculated expressions if the formula doesn't contain
+    // arithmetic operators or assignment.
+
+    const OUString aFormula( GetFormula());
+
+    if (comphelper::string::indexOfAny( aFormula, u"=+-*/", 0) == -1)
+        return static_cast<SwValueFieldType*>(GetTyp())->GetInputOrDateTime( 
aFormula, GetValue(), GetFormat());
+
+    return aFormula;
+}
+
 OUString SwField::GetDescription() const
 {
     return SwResId(STR_FIELD);
diff --git a/sw/source/core/fields/usrfld.cxx b/sw/source/core/fields/usrfld.cxx
index 4f84b8b7bcbb..b24123c552d3 100644
--- a/sw/source/core/fields/usrfld.cxx
+++ b/sw/source/core/fields/usrfld.cxx
@@ -275,7 +275,12 @@ double SwUserFieldType::GetValue( SwCalc& rCalc )
     return m_nValue;
 }
 
-OUString SwUserFieldType::GetContent( sal_uInt32 nFormat )
+OUString SwUserFieldType::GetInputOrDateTime( sal_uInt32 nFormat ) const
+{
+    return static_cast<const SwValueFieldType*>(this)->GetInputOrDateTime( 
m_aContent, GetValue(), nFormat);
+}
+
+OUString SwUserFieldType::GetContent( sal_uInt32 nFormat ) const
 {
     if (nFormat && nFormat != SAL_MAX_UINT32)
     {
diff --git a/sw/source/ui/fldui/fldvar.cxx b/sw/source/ui/fldui/fldvar.cxx
index bf2456ee8c41..ae3af154f0b5 100644
--- a/sw/source/ui/fldui/fldvar.cxx
+++ b/sw/source/ui/fldui/fldvar.cxx
@@ -225,6 +225,19 @@ IMPL_LINK( SwFieldVarPage, SubTypeListBoxHdl, 
weld::TreeView&, rBox, void )
     SubTypeHdl(&rBox);
 }
 
+static inline sal_uInt32 lcl_getUsedNumFormat( const SwNumFormatTreeView& 
rNumFormatLB, bool& rbText )
+{
+    sal_uInt32 nNumberFormat = 0;
+    const sal_Int32 nNumFormatPos = rNumFormatLB.get_selected_index();
+    if (nNumFormatPos != -1)
+    {
+        nNumberFormat = rNumFormatLB.GetFormat();
+        if ((rbText = (nNumFormatPos == 0 && nNumberFormat == SAL_MAX_UINT32)))
+            nNumberFormat = 0;
+    }
+    return nNumberFormat;
+}
+
 void SwFieldVarPage::SubTypeHdl(const weld::TreeView* pBox)
 {
     SwFieldTypesEnum nTypeId = 
static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
@@ -277,11 +290,19 @@ void SwFieldVarPage::SubTypeHdl(const weld::TreeView* 
pBox)
                             m_xNumFormatLB->select(0);
                         }
                         else
-                            m_xValueED->set_text(pType->GetContent());
+                        {
+                            bool bText = false;
+                            const sal_uInt32 nNumberFormat = 
lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
+                            
m_xValueED->set_text(pType->GetInputOrDateTime(nNumberFormat));
+                        }
                     }
                 }
                 else
-                    m_xValueED->set_text(pType->GetContent());
+                {
+                    bool bText = false;
+                    const sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( 
*m_xNumFormatLB, bText);
+                    
m_xValueED->set_text(pType->GetInputOrDateTime(nNumberFormat));
+                }
             }
             else
             {
@@ -336,12 +357,7 @@ void SwFieldVarPage::SubTypeHdl(const weld::TreeView* pBox)
             }
             if (GetCurField() != nullptr && IsFieldEdit())
             {
-                // GetFormula leads to problems with date formats because
-                // only the numeric value without formatting is returned.
-                // It must be used though because otherwise in GetPar2 only
-                // the value calculated by Kalkulator would be displayed
-                // (instead of test2 = test + 1)
-                
m_xValueED->set_text(static_cast<SwSetExpField*>(GetCurField())->GetFormula());
+                
m_xValueED->set_text(static_cast<SwSetExpField*>(GetCurField())->GetInputOrDateTime());
             }
             m_xValueED->SetDropEnable(true);
             break;
@@ -1010,10 +1026,8 @@ IMPL_LINK(SwFieldVarPage, TBClickHdl, weld::Button&, 
rBox, void)
                         // Formula and both are SAL_MAX_UINT32 :-/ but only if
                         // not another yet unlisted of Additional Formats was
                         // selected that may claim the top position :-/
-                        sal_uInt32 nNumberFormat = m_xNumFormatLB->GetFormat();
-                        const bool bText = (nNumFormatPos == 0 && 
nNumberFormat == SAL_MAX_UINT32);
-                        if (bText)
-                            nNumberFormat = 0;
+                        bool bText = false;
+                        sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( 
*m_xNumFormatLB, bText);
                         if (nNumberFormat && nNumberFormat != SAL_MAX_UINT32)
                         {   // Switch language to office-language because 
Kalkulator expects
                             // String in office format and it should be fed 
into dialog like
@@ -1060,10 +1074,8 @@ IMPL_LINK(SwFieldVarPage, TBClickHdl, weld::Button&, 
rBox, void)
                         // Formula and both are SAL_MAX_UINT32 :-/ but only if
                         // not another yet unlisted of Additional Formats was
                         // selected that may claim the top position :-/
-                        sal_uInt32 nNumberFormat = m_xNumFormatLB->GetFormat();
-                        const bool bText = (nNumFormatPos == 0 && 
nNumberFormat == SAL_MAX_UINT32);
-                        if (bText)
-                            nNumberFormat = 0;
+                        bool bText = false;
+                        sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( 
*m_xNumFormatLB, bText);
                         aType.SetType(bText ? nsSwGetSetExpType::GSE_STRING : 
nsSwGetSetExpType::GSE_EXPR);
                         aType.SetContent( sValue, nNumberFormat );
                         m_xSelectionLB->append_text(sName);

Reply via email to