[Libreoffice-commits] core.git: svtools/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Mon Jul 19 11:18:33 UTC 2021


 svtools/source/table/cellvalueconversion.cxx |  560 ++++++++++++---------------
 svtools/source/table/cellvalueconversion.hxx |   49 +-
 2 files changed, 286 insertions(+), 323 deletions(-)

New commits:
commit 6b018077789797490786f854fd725a4955715d6f
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Mon Jul 19 10:06:07 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Mon Jul 19 13:17:59 2021 +0200

    no need for pimpl in CellValueConversion
    
    Change-Id: I4d01fa33a8d9c4cf5610f25890ee6df9bca061bc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119158
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/svtools/source/table/cellvalueconversion.cxx b/svtools/source/table/cellvalueconversion.cxx
index 76a0a1395ffd..32e368864d3a 100644
--- a/svtools/source/table/cellvalueconversion.cxx
+++ b/svtools/source/table/cellvalueconversion.cxx
@@ -19,7 +19,6 @@
 
 #include "cellvalueconversion.hxx"
 
-#include <com/sun/star/util/NumberFormatter.hpp>
 #include <com/sun/star/util/NumberFormatsSupplier.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/util/Date.hpp>
@@ -38,396 +37,339 @@
 
 #include <limits>
 #include <memory>
-#include <unordered_map>
 
 namespace svt
 {
+using namespace ::com::sun::star::uno;
+using ::com::sun::star::util::XNumberFormatter;
+using ::com::sun::star::util::NumberFormatter;
+using ::com::sun::star::util::XNumberFormatsSupplier;
+using ::com::sun::star::util::NumberFormatsSupplier;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::lang::Locale;
+using ::com::sun::star::util::DateTime;
+using ::com::sun::star::util::XNumberFormatTypes;
 
+namespace NumberFormat = ::com::sun::star::util::NumberFormat;
 
-    using namespace ::com::sun::star::uno;
-    using ::com::sun::star::util::XNumberFormatter;
-    using ::com::sun::star::util::NumberFormatter;
-    using ::com::sun::star::util::XNumberFormatsSupplier;
-    using ::com::sun::star::util::NumberFormatsSupplier;
-    using ::com::sun::star::beans::XPropertySet;
-    using ::com::sun::star::lang::Locale;
-    using ::com::sun::star::util::DateTime;
-    using ::com::sun::star::util::XNumberFormatTypes;
+//= helper
 
-    namespace NumberFormat = ::com::sun::star::util::NumberFormat;
+namespace
+{
+double lcl_convertDateToDays(sal_uInt16 const i_day, sal_uInt16 const i_month,
+                             sal_Int16 const i_year)
+{
+    tools::Long const nNullDateDays = ::Date::DateToDays(1, 1, 1900);
+    tools::Long const nValueDateDays = ::Date::DateToDays(i_day, i_month, i_year);
 
+    return nValueDateDays - nNullDateDays;
+}
 
-    //= helper
+double lcl_convertTimeToDays(tools::Long const i_hours, tools::Long const i_minutes,
+                             tools::Long const i_seconds, tools::Long const i_100thSeconds)
+{
+    return tools::Time(i_hours, i_minutes, i_seconds, i_100thSeconds).GetTimeInDays();
+}
+}
 
-    namespace
-    {
+//= StandardFormatNormalizer
 
-        double lcl_convertDateToDays( sal_uInt16 const i_day, sal_uInt16 const i_month, sal_Int16 const i_year )
-        {
-            tools::Long const nNullDateDays = ::Date::DateToDays( 1, 1, 1900 );
-            tools::Long const nValueDateDays = ::Date::DateToDays( i_day, i_month, i_year );
+StandardFormatNormalizer::StandardFormatNormalizer(Reference<XNumberFormatter> const& i_formatter,
+                                                   ::sal_Int32 const i_numberFormatType)
+    : m_nFormatKey(0)
+{
+    try
+    {
+        ENSURE_OR_THROW(i_formatter.is(), "StandardFormatNormalizer: no formatter!");
+        Reference<XNumberFormatsSupplier> const xSupplier(i_formatter->getNumberFormatsSupplier(),
+                                                          UNO_SET_THROW);
+        Reference<XNumberFormatTypes> const xTypes(xSupplier->getNumberFormats(), UNO_QUERY_THROW);
+        m_nFormatKey = xTypes->getStandardFormat(i_numberFormatType,
+                                                 SvtSysLocale().GetLanguageTag().getLocale());
+    }
+    catch (const Exception&)
+    {
+        DBG_UNHANDLED_EXCEPTION("svtools.table");
+    }
+}
 
-            return nValueDateDays - nNullDateDays;
-        }
+//= DoubleNormalization
 
+namespace
+{
+class DoubleNormalization : public StandardFormatNormalizer
+{
+public:
+    explicit DoubleNormalization(Reference<XNumberFormatter> const& i_formatter)
+        : StandardFormatNormalizer(i_formatter, NumberFormat::NUMBER)
+    {
+    }
 
-        double lcl_convertTimeToDays( tools::Long const i_hours, tools::Long const i_minutes, tools::Long const i_seconds, tools::Long const i_100thSeconds )
-        {
-            return tools::Time( i_hours, i_minutes, i_seconds, i_100thSeconds ).GetTimeInDays();
-        }
+    virtual double convertToDouble(Any const& i_value) const override
+    {
+        double returnValue = std::numeric_limits<double>::quiet_NaN();
+        OSL_VERIFY(i_value >>= returnValue);
+        return returnValue;
+    }
+};
 
-    //= CellValueConversion_Data
-    class StandardFormatNormalizer;
+//= IntegerNormalization
 
+class IntegerNormalization : public StandardFormatNormalizer
+{
+public:
+    explicit IntegerNormalization(Reference<XNumberFormatter> const& i_formatter)
+        : StandardFormatNormalizer(i_formatter, NumberFormat::NUMBER)
+    {
     }
 
-    struct CellValueConversion_Data
+    virtual double convertToDouble(Any const& i_value) const override
     {
-        typedef std::unordered_map< OUString, std::shared_ptr< StandardFormatNormalizer > >    NormalizerCache;
+        sal_Int64 value(0);
+        OSL_VERIFY(i_value >>= value);
+        return value;
+    }
+};
 
-        Reference< XNumberFormatter >           xNumberFormatter;
-        bool                                    bAttemptedFormatterCreation;
-        NormalizerCache                         aNormalizers;
+//= BooleanNormalization
 
-        CellValueConversion_Data()
-            :xNumberFormatter()
-            ,bAttemptedFormatterCreation( false )
-            ,aNormalizers()
-        {
-        }
-    };
+class BooleanNormalization : public StandardFormatNormalizer
+{
+public:
+    explicit BooleanNormalization(Reference<XNumberFormatter> const& i_formatter)
+        : StandardFormatNormalizer(i_formatter, NumberFormat::LOGICAL)
+    {
+    }
 
+    virtual double convertToDouble(Any const& i_value) const override
+    {
+        bool value(false);
+        OSL_VERIFY(i_value >>= value);
+        return value ? 1 : 0;
+    }
+};
 
-    //= StandardFormatNormalizer
+//= DateTimeNormalization
 
-    namespace {
+class DateTimeNormalization : public StandardFormatNormalizer
+{
+public:
+    explicit DateTimeNormalization(Reference<XNumberFormatter> const& i_formatter)
+        : StandardFormatNormalizer(i_formatter, NumberFormat::DATETIME)
+    {
+    }
 
-    class StandardFormatNormalizer
+    virtual double convertToDouble(Any const& i_value) const override
     {
-    public:
-        /** converts the given <code>Any</code> into a <code>double</code> value to be fed into a number formatter
-        */
-        virtual double convertToDouble( Any const & i_value ) const = 0;
-
-        /** returns the format key to be used for formatting values
-        */
-        sal_Int32 getFormatKey() const
-        {
-            return m_nFormatKey;
-        }
+        double returnValue = std::numeric_limits<double>::quiet_NaN();
 
-    protected:
-        StandardFormatNormalizer( Reference< XNumberFormatter > const & i_formatter, ::sal_Int32 const i_numberFormatType )
-            :m_nFormatKey( 0 )
-        {
-            try
-            {
-                ENSURE_OR_THROW( i_formatter.is(), "StandardFormatNormalizer: no formatter!" );
-                Reference< XNumberFormatsSupplier > const xSupplier( i_formatter->getNumberFormatsSupplier(), UNO_SET_THROW );
-                Reference< XNumberFormatTypes > const xTypes( xSupplier->getNumberFormats(), UNO_QUERY_THROW );
-                m_nFormatKey = xTypes->getStandardFormat( i_numberFormatType, SvtSysLocale().GetLanguageTag().getLocale() );
-            }
-            catch( const Exception& )
-            {
-                DBG_UNHANDLED_EXCEPTION("svtools.table");
-            }
-        }
+        // extract actual UNO value
+        DateTime aDateTimeValue;
+        ENSURE_OR_RETURN(i_value >>= aDateTimeValue, "allowed for DateTime values only",
+                         returnValue);
 
-        virtual ~StandardFormatNormalizer() {}
+        // date part
+        returnValue
+            = lcl_convertDateToDays(aDateTimeValue.Day, aDateTimeValue.Month, aDateTimeValue.Year);
 
-    private:
-        ::sal_Int32 m_nFormatKey;
-    };
+        // time part
+        returnValue += lcl_convertTimeToDays(aDateTimeValue.Hours, aDateTimeValue.Minutes,
+                                             aDateTimeValue.Seconds, aDateTimeValue.NanoSeconds);
 
+        // done
+        return returnValue;
+    }
+};
 
-    //= DoubleNormalization
+//= DateNormalization
 
-    class DoubleNormalization : public StandardFormatNormalizer
+class DateNormalization : public StandardFormatNormalizer
+{
+public:
+    explicit DateNormalization(Reference<XNumberFormatter> const& i_formatter)
+        : StandardFormatNormalizer(i_formatter, NumberFormat::DATE)
     {
-    public:
-        explicit DoubleNormalization( Reference< XNumberFormatter > const & i_formatter )
-            :StandardFormatNormalizer( i_formatter, NumberFormat::NUMBER )
-        {
-        }
-
-        virtual double convertToDouble( Any const & i_value ) const override
-        {
-            double returnValue = std::numeric_limits<double>::quiet_NaN();
-            OSL_VERIFY( i_value >>= returnValue );
-            return returnValue;
-        }
-    };
-
-
-    //= IntegerNormalization
+    }
 
-    class IntegerNormalization : public StandardFormatNormalizer
+    virtual double convertToDouble(Any const& i_value) const override
     {
-    public:
-        explicit IntegerNormalization( Reference< XNumberFormatter > const & i_formatter )
-            :StandardFormatNormalizer( i_formatter, NumberFormat::NUMBER )
-        {
-        }
+        double returnValue = std::numeric_limits<double>::quiet_NaN();
 
-        virtual double convertToDouble( Any const & i_value ) const override
-        {
-            sal_Int64 value( 0 );
-            OSL_VERIFY( i_value >>= value );
-            return value;
-        }
-    };
+        // extract
+        css::util::Date aDateValue;
+        ENSURE_OR_RETURN(i_value >>= aDateValue, "allowed for Date values only", returnValue);
 
+        // convert
+        returnValue = lcl_convertDateToDays(aDateValue.Day, aDateValue.Month, aDateValue.Year);
 
-    //= BooleanNormalization
+        // done
+        return returnValue;
+    }
+};
+
+//= TimeNormalization
 
-    class BooleanNormalization : public StandardFormatNormalizer
+class TimeNormalization : public StandardFormatNormalizer
+{
+public:
+    explicit TimeNormalization(Reference<XNumberFormatter> const& i_formatter)
+        : StandardFormatNormalizer(i_formatter, NumberFormat::TIME)
     {
-    public:
-        explicit BooleanNormalization( Reference< XNumberFormatter > const & i_formatter )
-            :StandardFormatNormalizer( i_formatter, NumberFormat::LOGICAL )
-        {
-        }
+    }
 
-        virtual double convertToDouble( Any const & i_value ) const override
-        {
-            bool value( false );
-            OSL_VERIFY( i_value >>= value );
-            return value ? 1 : 0;
-        }
-    };
+    virtual double convertToDouble(Any const& i_value) const override
+    {
+        double returnValue = std::numeric_limits<double>::quiet_NaN();
 
+        // extract
+        css::util::Time aTimeValue;
+        ENSURE_OR_RETURN(i_value >>= aTimeValue, "allowed for tools::Time values only",
+                         returnValue);
 
-    //= DateTimeNormalization
+        // convert
+        returnValue += lcl_convertTimeToDays(aTimeValue.Hours, aTimeValue.Minutes,
+                                             aTimeValue.Seconds, aTimeValue.NanoSeconds);
 
-    class DateTimeNormalization : public StandardFormatNormalizer
-    {
-    public:
-        explicit DateTimeNormalization( Reference< XNumberFormatter > const & i_formatter )
-            :StandardFormatNormalizer( i_formatter, NumberFormat::DATETIME )
-        {
-        }
+        // done
+        return returnValue;
+    }
+};
+}
 
-        virtual double convertToDouble( Any const & i_value ) const override
-        {
-            double returnValue = std::numeric_limits<double>::quiet_NaN();
+//= operations
 
-            // extract actual UNO value
-            DateTime aDateTimeValue;
-            ENSURE_OR_RETURN( i_value >>= aDateTimeValue, "allowed for DateTime values only", returnValue );
+bool CellValueConversion::ensureNumberFormatter()
+{
+    if (bAttemptedFormatterCreation)
+        return xNumberFormatter.is();
+    bAttemptedFormatterCreation = true;
 
-            // date part
-            returnValue = lcl_convertDateToDays( aDateTimeValue.Day, aDateTimeValue.Month, aDateTimeValue.Year );
+    try
+    {
+        Reference<XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+        // a number formatter
+        Reference<XNumberFormatter> const xFormatter(NumberFormatter::create(xContext),
+                                                     UNO_QUERY_THROW);
 
-            // time part
-            returnValue += lcl_convertTimeToDays(
-                aDateTimeValue.Hours, aDateTimeValue.Minutes, aDateTimeValue.Seconds, aDateTimeValue.NanoSeconds );
+        // a supplier of number formats
+        Locale aLocale = SvtSysLocale().GetLanguageTag().getLocale();
 
-            // done
-            return returnValue;
-        }
-    };
+        Reference<XNumberFormatsSupplier> const xSupplier
+            = NumberFormatsSupplier::createWithLocale(xContext, aLocale);
 
+        // ensure a NullDate we will assume later on
+        css::util::Date const aNullDate(1, 1, 1900);
+        Reference<XPropertySet> const xFormatSettings(xSupplier->getNumberFormatSettings(),
+                                                      UNO_SET_THROW);
+        xFormatSettings->setPropertyValue("NullDate", makeAny(aNullDate));
 
-    //= DateNormalization
+        // knit
+        xFormatter->attachNumberFormatsSupplier(xSupplier);
 
-    class DateNormalization : public StandardFormatNormalizer
+        // done
+        xNumberFormatter = xFormatter;
+    }
+    catch (const Exception&)
     {
-    public:
-        explicit DateNormalization( Reference< XNumberFormatter > const & i_formatter )
-            :StandardFormatNormalizer( i_formatter, NumberFormat::DATE )
-        {
-        }
+        DBG_UNHANDLED_EXCEPTION("svtools.table");
+    }
 
-        virtual double convertToDouble( Any const & i_value ) const override
-        {
-            double returnValue = std::numeric_limits<double>::quiet_NaN();
+    return xNumberFormatter.is();
+}
 
-            // extract
-            css::util::Date aDateValue;
-            ENSURE_OR_RETURN( i_value >>= aDateValue, "allowed for Date values only", returnValue );
+bool CellValueConversion::getValueNormalizer(Type const& i_valueType,
+                                             std::shared_ptr<StandardFormatNormalizer>& o_formatter)
+{
+    auto pos = aNormalizers.find(i_valueType.getTypeName());
+    if (pos == aNormalizers.end())
+    {
+        // never encountered this type before
+        o_formatter.reset();
 
-            // convert
-            returnValue = lcl_convertDateToDays( aDateValue.Day, aDateValue.Month, aDateValue.Year );
+        OUString const sTypeName(i_valueType.getTypeName());
+        TypeClass const eTypeClass = i_valueType.getTypeClass();
 
-            // done
-            return returnValue;
+        if (sTypeName == ::cppu::UnoType<DateTime>::get().getTypeName())
+        {
+            o_formatter = std::make_shared<DateTimeNormalization>(xNumberFormatter);
         }
-    };
-
-
-    //= TimeNormalization
-
-    class TimeNormalization : public StandardFormatNormalizer
-    {
-    public:
-        explicit TimeNormalization( Reference< XNumberFormatter > const & i_formatter )
-            :StandardFormatNormalizer( i_formatter, NumberFormat::TIME )
+        else if (sTypeName == ::cppu::UnoType<css::util::Date>::get().getTypeName())
         {
+            o_formatter = std::make_shared<DateNormalization>(xNumberFormatter);
         }
-
-        virtual double convertToDouble( Any const & i_value ) const override
+        else if (sTypeName == ::cppu::UnoType<css::util::Time>::get().getTypeName())
         {
-            double returnValue = std::numeric_limits<double>::quiet_NaN();
-
-            // extract
-            css::util::Time aTimeValue;
-            ENSURE_OR_RETURN( i_value >>= aTimeValue, "allowed for tools::Time values only", returnValue );
-
-            // convert
-            returnValue += lcl_convertTimeToDays(
-                aTimeValue.Hours, aTimeValue.Minutes, aTimeValue.Seconds, aTimeValue.NanoSeconds );
-
-            // done
-            return returnValue;
+            o_formatter = std::make_shared<TimeNormalization>(xNumberFormatter);
         }
-    };
-
-
-    //= operations
-
-        bool lcl_ensureNumberFormatter( CellValueConversion_Data & io_data )
+        else if (sTypeName == ::cppu::UnoType<sal_Bool>::get().getTypeName())
         {
-            if ( io_data.bAttemptedFormatterCreation )
-                return io_data.xNumberFormatter.is();
-            io_data.bAttemptedFormatterCreation = true;
-
-            try
-            {
-                Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
-                // a number formatter
-                Reference< XNumberFormatter > const xFormatter( NumberFormatter::create( xContext ), UNO_QUERY_THROW );
-
-                // a supplier of number formats
-                Locale aLocale = SvtSysLocale().GetLanguageTag().getLocale();
-
-                Reference< XNumberFormatsSupplier > const xSupplier =
-                    NumberFormatsSupplier::createWithLocale( xContext, aLocale );
-
-                // ensure a NullDate we will assume later on
-                css::util::Date const aNullDate( 1, 1, 1900 );
-                Reference< XPropertySet > const xFormatSettings( xSupplier->getNumberFormatSettings(), UNO_SET_THROW );
-                xFormatSettings->setPropertyValue( "NullDate", makeAny( aNullDate ) );
-
-                // knit
-                xFormatter->attachNumberFormatsSupplier( xSupplier );
-
-                // done
-                io_data.xNumberFormatter = xFormatter;
-            }
-            catch( const Exception& )
-            {
-                DBG_UNHANDLED_EXCEPTION("svtools.table");
-            }
-
-            return io_data.xNumberFormatter.is();
+            o_formatter = std::make_shared<BooleanNormalization>(xNumberFormatter);
         }
-
-
-        bool lcl_getValueNormalizer( CellValueConversion_Data & io_data, Type const & i_valueType,
-            std::shared_ptr< StandardFormatNormalizer > & o_formatter )
+        else if (sTypeName == ::cppu::UnoType<double>::get().getTypeName()
+                 || sTypeName == ::cppu::UnoType<float>::get().getTypeName())
         {
-            CellValueConversion_Data::NormalizerCache::const_iterator pos = io_data.aNormalizers.find( i_valueType.getTypeName() );
-            if ( pos == io_data.aNormalizers.end() )
-            {
-                // never encountered this type before
-                o_formatter.reset();
-
-                OUString const sTypeName( i_valueType.getTypeName() );
-                TypeClass const eTypeClass = i_valueType.getTypeClass();
-
-                if ( sTypeName == ::cppu::UnoType< DateTime >::get().getTypeName() )
-                {
-                    o_formatter = std::make_shared<DateTimeNormalization>( io_data.xNumberFormatter );
-                }
-                else if ( sTypeName == ::cppu::UnoType< css::util::Date >::get().getTypeName() )
-                {
-                    o_formatter = std::make_shared<DateNormalization>( io_data.xNumberFormatter );
-                }
-                else if ( sTypeName == ::cppu::UnoType< css::util::Time >::get().getTypeName() )
-                {
-                    o_formatter = std::make_shared<TimeNormalization>( io_data.xNumberFormatter );
-                }
-                else if ( sTypeName == ::cppu::UnoType< sal_Bool >::get().getTypeName() )
-                {
-                    o_formatter = std::make_shared<BooleanNormalization>( io_data.xNumberFormatter );
-                }
-                else if (   sTypeName == ::cppu::UnoType< double >::get().getTypeName()
-                        ||  sTypeName == ::cppu::UnoType< float >::get().getTypeName()
-                        )
-                {
-                    o_formatter = std::make_shared<DoubleNormalization>( io_data.xNumberFormatter );
-                }
-                else if (   ( eTypeClass == TypeClass_BYTE )
-                        ||  ( eTypeClass == TypeClass_SHORT )
-                        ||  ( eTypeClass == TypeClass_UNSIGNED_SHORT )
-                        ||  ( eTypeClass == TypeClass_LONG )
-                        ||  ( eTypeClass == TypeClass_UNSIGNED_LONG )
-                        ||  ( eTypeClass == TypeClass_HYPER )
-                        )
-                {
-                    o_formatter = std::make_shared<IntegerNormalization>( io_data.xNumberFormatter );
-                }
-                else
-                {
-                    SAL_WARN( "svtools.table", "unsupported type '" << sTypeName << "'!" );
-                }
-                io_data.aNormalizers[ sTypeName ] = o_formatter;
-            }
-            else
-                o_formatter = pos->second;
-
-            return bool(o_formatter);
+            o_formatter = std::make_shared<DoubleNormalization>(xNumberFormatter);
+        }
+        else if ((eTypeClass == TypeClass_BYTE) || (eTypeClass == TypeClass_SHORT)
+                 || (eTypeClass == TypeClass_UNSIGNED_SHORT) || (eTypeClass == TypeClass_LONG)
+                 || (eTypeClass == TypeClass_UNSIGNED_LONG) || (eTypeClass == TypeClass_HYPER))
+        {
+            o_formatter = std::make_shared<IntegerNormalization>(xNumberFormatter);
         }
+        else
+        {
+            SAL_WARN("svtools.table", "unsupported type '" << sTypeName << "'!");
+        }
+        aNormalizers[sTypeName] = o_formatter;
     }
+    else
+        o_formatter = pos->second;
 
+    return bool(o_formatter);
+}
 
-    //= CellValueConversion
-
-
-    CellValueConversion::CellValueConversion()
-        :m_pData( new CellValueConversion_Data )
-    {
-    }
+//= CellValueConversion
 
+CellValueConversion::CellValueConversion()
+    : xNumberFormatter()
+    , bAttemptedFormatterCreation(false)
+    , aNormalizers()
+{
+}
 
-    CellValueConversion::~CellValueConversion()
-    {
-    }
+CellValueConversion::~CellValueConversion() {}
 
+OUString CellValueConversion::convertToString(const Any& i_value)
+{
+    OUString sStringValue;
+    if (!i_value.hasValue())
+        return sStringValue;
 
-    OUString CellValueConversion::convertToString( const Any& i_value )
+    if (!(i_value >>= sStringValue))
     {
-        OUString sStringValue;
-        if ( !i_value.hasValue() )
-            return sStringValue;
-
-        if ( ! ( i_value >>= sStringValue ) )
+        if (ensureNumberFormatter())
         {
-            if ( lcl_ensureNumberFormatter( *m_pData ) )
+            std::shared_ptr<StandardFormatNormalizer> pNormalizer;
+            if (getValueNormalizer(i_value.getValueType(), pNormalizer))
             {
-                std::shared_ptr< StandardFormatNormalizer > pNormalizer;
-                if ( lcl_getValueNormalizer( *m_pData, i_value.getValueType(), pNormalizer ) )
+                try
+                {
+                    double const formatterCompliantValue = pNormalizer->convertToDouble(i_value);
+                    sal_Int32 const formatKey = pNormalizer->getFormatKey();
+                    sStringValue = xNumberFormatter->convertNumberToString(formatKey,
+                                                                           formatterCompliantValue);
+                }
+                catch (const Exception&)
                 {
-                    try
-                    {
-                        double const formatterCompliantValue = pNormalizer->convertToDouble( i_value );
-                        sal_Int32 const formatKey = pNormalizer->getFormatKey();
-                        sStringValue = m_pData->xNumberFormatter->convertNumberToString(
-                            formatKey, formatterCompliantValue );
-                    }
-                    catch( const Exception& )
-                    {
-                        DBG_UNHANDLED_EXCEPTION("svtools.table");
-                    }
+                    DBG_UNHANDLED_EXCEPTION("svtools.table");
                 }
             }
         }
-
-        return sStringValue;
     }
 
+    return sStringValue;
+}
 
 } // namespace svt
 
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/table/cellvalueconversion.hxx b/svtools/source/table/cellvalueconversion.hxx
index 3a5bb924c914..d05a84c5db85 100644
--- a/svtools/source/table/cellvalueconversion.hxx
+++ b/svtools/source/table/cellvalueconversion.hxx
@@ -19,33 +19,54 @@
 
 #pragma once
 
+#include <com/sun/star/util/NumberFormatter.hpp>
 #include <com/sun/star/uno/Any.hxx>
-
+#include <unordered_map>
 #include <memory>
 
-
 namespace svt
 {
+class StandardFormatNormalizer
+{
+public:
+    /** converts the given <code>Any</code> into a <code>double</code> value to be fed into a number formatter
+        */
+    virtual double convertToDouble(css::uno::Any const& i_value) const = 0;
 
+    /** returns the format key to be used for formatting values
+        */
+    sal_Int32 getFormatKey() const { return m_nFormatKey; }
 
-    //= CellValueConversion
+protected:
+    StandardFormatNormalizer(css::uno::Reference<css::util::XNumberFormatter> const& i_formatter,
+                             ::sal_Int32 const i_numberFormatType);
 
-    struct CellValueConversion_Data;
-    class CellValueConversion
-    {
-    public:
-        CellValueConversion();
-        ~CellValueConversion();
+    virtual ~StandardFormatNormalizer() {}
 
-        OUString convertToString( const css::uno::Any& i_cellValue );
+private:
+    ::sal_Int32 m_nFormatKey;
+};
 
-    private:
-        ::std::unique_ptr< CellValueConversion_Data > m_pData;
-    };
+class CellValueConversion
+{
+public:
+    CellValueConversion();
+    ~CellValueConversion();
 
+    OUString convertToString(const css::uno::Any& i_cellValue);
 
-} // namespace svt
+private:
+    bool ensureNumberFormatter();
+    bool getValueNormalizer(css::uno::Type const& i_valueType,
+                            std::shared_ptr<StandardFormatNormalizer>& o_formatter);
+
+    typedef std::unordered_map<OUString, std::shared_ptr<StandardFormatNormalizer>> NormalizerCache;
 
+    css::uno::Reference<css::util::XNumberFormatter> xNumberFormatter;
+    bool bAttemptedFormatterCreation;
+    NormalizerCache aNormalizers;
+};
 
+} // namespace svt
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list