[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - 27 commits - comphelper/source configure.ac cui/source desktop/source editeng/qa editeng/source include/comphelper include/editeng include/LibreOfficeKit include/oox include/svtools include/svx include/vcl oox/source package/inc package/source sc/inc sc/qa sc/source sd/qa sd/source solenv/vs svtools/source svx/source sw/inc sw/qa sw/source vcl/source writerfilter/source xmloff/source

Mike Kaganski mike.kaganski at collabora.com
Sun Mar 25 19:19:55 UTC 2018


 comphelper/source/xml/ofopxmlhelper.cxx         |   18 
 configure.ac                                    |    2 
 cui/source/tabpages/chardlg.cxx                 |   10 
 desktop/source/app/app.cxx                      |    4 
 desktop/source/lib/init.cxx                     |   41 +-
 editeng/qa/unit/core-test.cxx                   |  144 +++++++
 editeng/source/editeng/editeng.cxx              |   10 
 editeng/source/editeng/impedit.hxx              |    7 
 editeng/source/editeng/impedit2.cxx             |   10 
 editeng/source/editeng/impedit3.cxx             |   12 
 editeng/source/items/itemtype.cxx               |    8 
 editeng/source/outliner/outliner.cxx            |   10 
 editeng/source/xml/xmltxtexp.cxx                |    6 
 include/LibreOfficeKit/LibreOfficeKit.h         |    1 
 include/LibreOfficeKit/LibreOfficeKit.hxx       |    6 
 include/comphelper/windowsdebugoutput.hxx       |  456 +++++++++++++++++++++++-
 include/editeng/editeng.hxx                     |    4 
 include/editeng/outliner.hxx                    |    4 
 include/oox/core/xmlfilterbase.hxx              |   12 
 include/svtools/ctrlbox.hxx                     |    3 
 include/svx/svdmodel.hxx                        |    4 
 include/svx/svdotext.hxx                        |    2 
 include/vcl/ITiledRenderable.hxx                |   12 
 include/vcl/field.hxx                           |   18 
 oox/source/core/xmlfilterbase.cxx               |  206 ++++++++++
 oox/source/export/drawingml.cxx                 |   19 -
 package/inc/ZipPackageEntry.hxx                 |   10 
 package/source/zippackage/ZipPackage.cxx        |   31 +
 sc/inc/docuno.hxx                               |    6 
 sc/qa/unit/tiledrendering/tiledrendering.cxx    |    6 
 sc/source/ui/unoobj/docuno.cxx                  |   34 -
 sd/qa/unit/data/odp/tdf115639.odp               |binary
 sd/qa/unit/data/ppt/tdf115639.ppt               |binary
 sd/qa/unit/data/pptx/font-scale.pptx            |binary
 sd/qa/unit/data/pptx/tdf115639.pptx             |binary
 sd/qa/unit/export-tests-ooxml2.cxx              |   17 
 sd/qa/unit/import-tests.cxx                     |   33 +
 sd/qa/unit/tiledrendering/tiledrendering.cxx    |    6 
 sd/source/ui/docshell/docshel4.cxx              |   16 
 sd/source/ui/inc/unomodel.hxx                   |    3 
 sd/source/ui/unoidl/unomodel.cxx                |   36 -
 sd/source/ui/view/Outliner.cxx                  |    1 
 solenv/vs/LibreOffice.natvis                    |    7 
 svtools/source/control/ctrlbox.cxx              |   14 
 svx/source/svdraw/svdetc.cxx                    |    1 
 svx/source/svdraw/svdmodel.cxx                  |   22 +
 svx/source/svdraw/svdotext.cxx                  |   63 +++
 sw/inc/strings.hrc                              |    1 
 sw/inc/unotxdoc.hxx                             |    4 
 sw/qa/extras/tiledrendering/tiledrendering.cxx  |    6 
 sw/source/filter/ww8/docxexport.cxx             |   14 
 sw/source/uibase/app/docsh2.cxx                 |    2 
 sw/source/uibase/app/docst.cxx                  |    3 
 sw/source/uibase/app/docstyle.cxx               |   24 -
 sw/source/uibase/uno/unotxdoc.cxx               |   30 -
 vcl/source/control/field.cxx                    |   77 +---
 vcl/source/control/fixed.cxx                    |   21 -
 vcl/source/window/toolbox.cxx                   |    2 
 vcl/source/window/window.cxx                    |    8 
 writerfilter/source/filter/WriterFilter.cxx     |   38 --
 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx |   60 +--
 xmloff/source/core/xmlimp.cxx                   |    7 
 62 files changed, 1312 insertions(+), 320 deletions(-)

New commits:
commit 73629949c1d6245f7fad419b677cf92a49ffd18a
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Wed Feb 21 00:30:16 2018 +0300

    tdf#115892: properly get the box' saved value
    
    Previously textual value like "10,5 pt" was converted to int as simply
    10 (multiplied by 10, it became 100), which compared as different from
    unchanged value of 105. This made the fractional values to be treated
    as always changed.
    
    This patch uses the same code to convert saved value as is used for
    current edit box value.
    
    Reviewed-on: https://gerrit.libreoffice.org/50066
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit f00e891f3369f7b8c2532634d9ff4ab19da17c33)
    
    Change-Id: I09a84a6bf33b17e0192b79b31af21ef14d7e9c63

diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
index af80bb565ef7..75dab248267c 100644
--- a/cui/source/tabpages/chardlg.cxx
+++ b/cui/source/tabpages/chardlg.cxx
@@ -1041,14 +1041,8 @@ bool SvxCharNamePage::FillItemSet_Impl( SfxItemSet& rSet, LanguageGroup eLangGrp
 
     if ( pSizeBox->GetText().isEmpty() )   // GetValue() returns the min-value
         nSize = 0;
-    long nSavedSize = pSizeBox->GetSavedValue().toInt32();
-    bool bRel = true;
-
-    if ( !pSizeBox->IsRelative() )
-    {
-        nSavedSize *= 10;
-        bRel = false;
-    }
+    long nSavedSize = static_cast<long>(pSizeBox->GetSavedIntValue());
+    const bool bRel = pSizeBox->IsRelative();
 
     switch ( eLangGrp )
     {
diff --git a/include/svtools/ctrlbox.hxx b/include/svtools/ctrlbox.hxx
index 6e0358721885..d1a8a90cdd2b 100644
--- a/include/svtools/ctrlbox.hxx
+++ b/include/svtools/ctrlbox.hxx
@@ -363,6 +363,7 @@ class SVT_DLLPUBLIC FontSizeBox : public MetricBox
 
 protected:
     virtual OUString CreateFieldText( sal_Int64 nValue ) const override;
+    virtual sal_Int64 GetValueFromStringUnit(const OUString& rStr, FieldUnit eOutUnit) const override;
 
 public:
                     FontSizeBox( vcl::Window* pParent, WinBits nWinStyle );
@@ -385,8 +386,6 @@ public:
 
     virtual void    SetValue( sal_Int64 nNewValue, FieldUnit eInUnit ) override;
     virtual void    SetValue( sal_Int64 nNewValue  ) override;
-    virtual sal_Int64   GetValue( FieldUnit eOutUnit ) const override;
-    virtual sal_Int64   GetValue() const override;
 
 private:
                     FontSizeBox( const FontSizeBox& ) = delete;
diff --git a/include/vcl/field.hxx b/include/vcl/field.hxx
index 3fb0633fe3a6..de00346a2e51 100644
--- a/include/vcl/field.hxx
+++ b/include/vcl/field.hxx
@@ -153,7 +153,8 @@ public:
 
     void                    SetUserValue( sal_Int64 nNewValue );
     virtual void            SetValue( sal_Int64 nNewValue );
-    virtual sal_Int64       GetValue() const;
+    sal_Int64               GetValue() const;
+    sal_Int64               GetSavedIntValue() const;
     virtual OUString        CreateFieldText( sal_Int64 nValue ) const;
     bool                    IsValueModified() const;
 
@@ -184,6 +185,8 @@ protected:
     SAL_DLLPRIVATE void     ImplNewFieldValue( sal_Int64 nNewValue );
     SAL_DLLPRIVATE void     ImplSetUserValue( sal_Int64 nNewValue, Selection const * pNewSelection = nullptr );
 
+    virtual sal_Int64       GetValueFromString(const OUString& rStr) const;
+
 private:
     SAL_DLLPRIVATE void     ImplInit();
 
@@ -223,8 +226,8 @@ public:
     virtual void            SetValue( sal_Int64 nValue ) override;
     using NumericFormatter::SetUserValue;
     void                    SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit );
-    virtual sal_Int64       GetValue( FieldUnit eOutUnit ) const;
-    virtual sal_Int64       GetValue() const override;
+    using NumericFormatter::GetValue;
+    sal_Int64               GetValue( FieldUnit eOutUnit ) const;
     virtual OUString        CreateFieldText( sal_Int64 nValue ) const override;
     sal_Int64               GetCorrectedValue( FieldUnit eOutUnit ) const;
 
@@ -240,6 +243,9 @@ protected:
 
     SAL_DLLPRIVATE bool     ImplMetricReformat( const OUString& rStr, double& rValue, OUString& rOutStr );
 
+    virtual sal_Int64       GetValueFromString(const OUString& rStr) const override;
+    virtual sal_Int64       GetValueFromStringUnit(const OUString& rStr, FieldUnit eOutUnit) const;
+
 private:
     SAL_DLLPRIVATE  void    ImplInit();
 
@@ -253,6 +259,7 @@ class VCL_DLLPUBLIC CurrencyFormatter : public NumericFormatter
 protected:
                             CurrencyFormatter();
     SAL_DLLPRIVATE bool     ImplCurrencyReformat( const OUString& rStr, OUString& rOutStr );
+    virtual sal_Int64       GetValueFromString(const OUString& rStr) const override;
 
 public:
     virtual                 ~CurrencyFormatter() override;
@@ -260,7 +267,6 @@ public:
     virtual void            Reformat() override;
 
     virtual void            SetValue( sal_Int64 nNewValue ) override;
-    virtual sal_Int64       GetValue() const override;
     virtual OUString        CreateFieldText( sal_Int64 nValue ) const override;
 };
 
@@ -659,8 +665,7 @@ public:
                                          FieldUnit eInUnit = FUNIT_NONE ) const;
 
     // Needed, because GetValue() with nPos hide these functions
-    virtual sal_Int64       GetValue( FieldUnit eOutUnit ) const override;
-    virtual sal_Int64       GetValue() const override;
+    using MetricFormatter::GetValue;
 
     virtual void            dispose() override;
 };
@@ -679,7 +684,6 @@ public:
 
     virtual void            ReformatAll() override;
 
-    virtual sal_Int64       GetValue() const override;
     virtual void            dispose() override;
 };
 
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index a4b64f2ef042..5810132ed431 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -1582,23 +1582,17 @@ void FontSizeBox::SetValue( sal_Int64 nNewValue )
     SetValue( nNewValue, FUNIT_NONE );
 }
 
-sal_Int64 FontSizeBox::GetValue( FieldUnit eOutUnit ) const
+sal_Int64 FontSizeBox::GetValueFromStringUnit(const OUString& rStr, FieldUnit eOutUnit) const
 {
     if ( !bRelative )
     {
         FontSizeNames aFontSizeNames( GetSettings().GetUILanguageTag().getLanguageType() );
-        sal_Int64 nValue = aFontSizeNames.Name2Size( GetText() );
-        if ( nValue)
+        sal_Int64 nValue = aFontSizeNames.Name2Size( rStr );
+        if ( nValue )
             return MetricField::ConvertValue( nValue, GetBaseValue(), GetDecimalDigits(), GetUnit(), eOutUnit );
     }
 
-    return MetricBox::GetValue( eOutUnit );
-}
-
-sal_Int64 FontSizeBox::GetValue() const
-{
-    // implementation not inline, because it is a virtual function
-    return GetValue( FUNIT_NONE );
+    return MetricBox::GetValueFromStringUnit( rStr, eOutUnit );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx
index 220da283ba86..c1dbb33417c4 100644
--- a/vcl/source/control/field.cxx
+++ b/vcl/source/control/field.cxx
@@ -576,15 +576,12 @@ void NumericFormatter::SetUserValue( sal_Int64 nNewValue )
     ImplSetUserValue( nNewValue );
 }
 
-sal_Int64 NumericFormatter::GetValue() const
+sal_Int64 NumericFormatter::GetValueFromString(const OUString& rStr) const
 {
-    if ( !GetField() )
-        return 0;
-
     sal_Int64 nTempValue;
 
-    if ( ImplNumericGetValue( GetField()->GetText(), nTempValue,
-                              GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
+    if (ImplNumericGetValue(rStr, nTempValue,
+        GetDecimalDigits(), ImplGetLocaleDataWrapper()))
     {
         return ClipAgainstMinMax(nTempValue);
     }
@@ -592,6 +589,16 @@ sal_Int64 NumericFormatter::GetValue() const
         return mnLastValue;
 }
 
+sal_Int64 NumericFormatter::GetValue() const
+{
+    return GetField() ? GetValueFromString(GetField()->GetText()) : 0;
+}
+
+sal_Int64 NumericFormatter::GetSavedIntValue() const
+{
+    return GetField() ? GetValueFromString(GetField()->GetSavedValue()) : 0;
+}
+
 bool NumericFormatter::IsValueModified() const
 {
     if ( ImplGetEmptyFieldValue() )
@@ -1393,36 +1400,37 @@ void MetricFormatter::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
     NumericFormatter::SetUserValue( nNewValue );
 }
 
-sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const
+sal_Int64 MetricFormatter::GetValueFromStringUnit(const OUString& rStr, FieldUnit eOutUnit) const
 {
-    if ( !GetField() )
-        return 0;
-
     double nTempValue;
     // caution: precision loss in double cast
-    if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
-        nTempValue = (double)mnLastValue;
+    if (!ImplMetricGetValue(rStr, nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit))
+        nTempValue = static_cast<double>(mnLastValue);
 
     // caution: precision loss in double cast
-    if ( nTempValue > mnMax )
-        nTempValue = (double)mnMax;
-    else if ( nTempValue < mnMin )
-        nTempValue = (double)mnMin;
+    if (nTempValue > mnMax)
+        nTempValue = static_cast<double>(mnMax);
+    else if (nTempValue < mnMin)
+        nTempValue = static_cast<double>(mnMin);
 
     // convert to requested units
-    return MetricField::ConvertValue( (sal_Int64)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit );
+    return MetricField::ConvertValue(static_cast<sal_Int64>(nTempValue), mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit);
 }
 
-void MetricFormatter::SetValue( sal_Int64 nValue )
+sal_Int64 MetricFormatter::GetValueFromString(const OUString& rStr) const
 {
-    // Implementation not inline, because it is a virtual Function
-    SetValue( nValue, FUNIT_NONE );
+    return GetValueFromStringUnit(rStr, FUNIT_NONE);
+}
+
+sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const
+{
+    return GetField() ? GetValueFromStringUnit(GetField()->GetText(), eOutUnit) : 0;
 }
 
-sal_Int64 MetricFormatter::GetValue() const
+void MetricFormatter::SetValue( sal_Int64 nValue )
 {
     // Implementation not inline, because it is a virtual Function
-    return GetValue( FUNIT_NONE );
+    SetValue( nValue, FUNIT_NONE );
 }
 
 void MetricFormatter::SetMin( sal_Int64 nNewMin, FieldUnit eInUnit )
@@ -1777,18 +1785,6 @@ sal_Int32 MetricBox::GetValuePos( sal_Int64 nValue, FieldUnit eInUnit ) const
     return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
 }
 
-sal_Int64 MetricBox::GetValue( FieldUnit eOutUnit ) const
-{
-    // Implementation not inline, because it is a virtual Function
-    return MetricFormatter::GetValue( eOutUnit );
-}
-
-sal_Int64 MetricBox::GetValue() const
-{
-    // Implementation not inline, because it is a virtual Function
-    return GetValue( FUNIT_NONE );
-}
-
 static bool ImplCurrencyProcessKeyInput( const KeyEvent& rKEvt,
                                          bool bUseThousandSep, const LocaleDataWrapper& rWrapper )
 {
@@ -1843,13 +1839,10 @@ OUString CurrencyFormatter::CreateFieldText( sal_Int64 nValue ) const
                                                IsUseThousandSep() );
 }
 
-sal_Int64 CurrencyFormatter::GetValue() const
+sal_Int64 CurrencyFormatter::GetValueFromString(const OUString& rStr) const
 {
-    if ( !GetField() )
-        return 0;
-
     sal_Int64 nTempValue;
-    if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
+    if ( ImplCurrencyGetValue( rStr, nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
     {
         return ClipAgainstMinMax(nTempValue);
     }
@@ -2037,10 +2030,4 @@ void CurrencyBox::ReformatAll()
     SetUpdateMode( true );
 }
 
-sal_Int64 CurrencyBox::GetValue() const
-{
-    // Implementation not inline, because it is a virtual Function
-    return CurrencyFormatter::GetValue();
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 3ac438cde11c4cbe32a1c09e9fe885a0b0accc2c
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Wed Feb 21 00:43:13 2018 +0300

    Update LibreOffice.natvis
    
    Change-Id: I46a976de94508dd2b79c9dcb19d25d307f4c732c
    Reviewed-on: https://gerrit.libreoffice.org/50067
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit fd20935bb819cb24e71f4f91b97149c35bc5987d)

diff --git a/solenv/vs/LibreOffice.natvis b/solenv/vs/LibreOffice.natvis
index 04350ccb6019..03aae0fca6b7 100644
--- a/solenv/vs/LibreOffice.natvis
+++ b/solenv/vs/LibreOffice.natvis
@@ -102,6 +102,13 @@
   <Type Name="SwRect">
     <DisplayString>{m_Point}, {m_Size}</DisplayString>
   </Type>
+  <Type Name="tools::Rectangle">
+    <DisplayString IncludeView="w">{nRight==-32767?0:(nRight-nLeft+(nLeft>nRight?(-1):(1)))}</DisplayString>
+    <DisplayString IncludeView="h">{nBottom==-32767?0:(nBottom-nTop+(nTop>nBottom?(-1):(1)))}</DisplayString>
+    <DisplayString IncludeView="sz" Condition="nRight==-32767 || nBottom==-32767">empty</DisplayString>
+    <DisplayString IncludeView="sz">{*this,view(w)nd} x {*this,view(h)nd}</DisplayString>
+    <DisplayString>{{ LT=[{nLeft} , {nTop}] RB=[{nRight} , {nBottom}] [{*this,view(sz)}] }}</DisplayString>
+  </Type>
   <Type Name="_sal_Sequence">
     <DisplayString Condition="nElements == 0">_sal_Sequence (empty)</DisplayString>
     <DisplayString>_sal_Sequence of {nElements,d} elements</DisplayString>
commit 62cf24fbd48064e3ba309109a92a2c408ae654b6
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Wed Feb 21 01:03:59 2018 +0100

    Increase delta value for these checks
    
    Reviewed-on: https://gerrit.libreoffice.org/50073
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit 156f5105e5c0d127d618ce8c120cfe9618a0e44a)
    
    Change-Id: I14582541bf076340cfc95a17e1a9070a596c67db

diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index 78e17a78d54b..a54434a59635 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -1877,7 +1877,7 @@ void Test::testHoriAlignIgnoreTrailingWhitespace()
         // Check horizontal position
         ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
         EditLine* pLine = &pParaPortion->GetLines()[0];
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4527), pLine->GetStartPosX(), 10);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4527), pLine->GetStartPosX(), 100);
     }
 
     // Second test case: center alignment with compatibility option disabled
@@ -1898,7 +1898,7 @@ void Test::testHoriAlignIgnoreTrailingWhitespace()
         // Check horizontal position
         ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
         EditLine* pLine = &pParaPortion->GetLines()[0];
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4407), pLine->GetStartPosX(), 10);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4407), pLine->GetStartPosX(), 100);
     }
 
     // Third test case: right alignment with compatibility option enabled
@@ -1919,7 +1919,7 @@ void Test::testHoriAlignIgnoreTrailingWhitespace()
         // Check horizontal position
         ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
         EditLine* pLine = &pParaPortion->GetLines()[0];
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(9054), pLine->GetStartPosX(), 10);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(9054), pLine->GetStartPosX(), 100);
     }
 
     // Fourth test case: right alignment with compatibility option disabled
@@ -1940,7 +1940,7 @@ void Test::testHoriAlignIgnoreTrailingWhitespace()
         // Check horizontal position
         ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
         EditLine* pLine = &pParaPortion->GetLines()[0];
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(8815), pLine->GetStartPosX(), 10);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(8815), pLine->GetStartPosX(), 100);
     }
 
     // Test multiple paragraph case
@@ -1971,9 +1971,9 @@ void Test::testHoriAlignIgnoreTrailingWhitespace()
 
         // Check horizontal position
         ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4527), pParaPortion->GetLines()[0].GetStartPosX(), 50);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4527), pParaPortion->GetLines()[0].GetStartPosX(), 100);
         pParaPortion = aEditEngine.GetParaPortions()[1];
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(8815), pParaPortion->GetLines()[0].GetStartPosX(), 50);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(8815), pParaPortion->GetLines()[0].GetStartPosX(), 100);
     }
 }
 
commit 37eed98f79dcc2f502c92264665c3d7d7f0ad087
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Tue Feb 20 15:03:38 2018 +0300

    tdf#115875: treat Western/Asian/CTL font groups consistently
    
    ... for both Paragraph and Character Styles.
    
    Change-Id: Iab2cf6ef0fc29ba7e7afe2b52adf8cc9836ea608
    Reviewed-on: https://gerrit.libreoffice.org/50036
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit 86cdda67e4ec6fd6893a1d05d88eafa0ad838e2f)

diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index b6bd848e7b57..6545d5f41e3e 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -273,6 +273,7 @@
 #define STR_PAGEBREAK                           NC_("STR_PAGEBREAK", "Break before new page")
 #define STR_WESTERN_FONT                        NC_("STR_WESTERN_FONT", "Western text: ")
 #define STR_CJK_FONT                            NC_("STR_CJK_FONT", "Asian text: ")
+#define STR_CTL_FONT                            NC_("STR_CTL_FONT", "CTL text: ")
 #define STR_REDLINE_UNKNOWN_AUTHOR              NC_("STR_REDLINE_UNKNOWN_AUTHOR", "Unknown Author")
 #define STR_DELETE_NOTE_AUTHOR                  NC_("STR_DELETE_NOTE_AUTHOR", "Delete ~All Comments by $1")
 #define STR_HIDE_NOTE_AUTHOR                    NC_("STR_HIDE_NOTE_AUTHOR", "H~ide All Comments by $1")
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
index c5180e3038ae..c2ba65e1f391 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -56,6 +56,7 @@
 #include <paratr.hxx>
 #include <SwStyleNameMapper.hxx>
 #include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
 #include <comphelper/processfactory.hxx>
 #include <unotools/localedatawrapper.hxx>
 #include <unotools/intlwrapper.hxx>
@@ -859,7 +860,7 @@ OUString  SwDocStyleSheet::GetDescription(MapUnit eUnit)
         return aDesc;
     }
 
-    if ( SfxStyleFamily::Frame == nFamily || SfxStyleFamily::Para == nFamily)
+    if ( SfxStyleFamily::Frame == nFamily || SfxStyleFamily::Para == nFamily || SfxStyleFamily::Char == nFamily )
     {
         if( !pSet )
             GetItemSet();
@@ -871,7 +872,9 @@ OUString  SwDocStyleSheet::GetDescription(MapUnit eUnit)
         OUString sBreak;
         bool bHasWesternFontPrefix = false;
         bool bHasCJKFontPrefix = false;
+        bool bHasCTLFontPrefix = false;
         SvtCJKOptions aCJKOptions;
+        SvtCTLOptions aCTLOptions;
 
         // Get currently used FillStyle and remember, also need the XFillFloatTransparenceItem
         // to decide if gradient transparence is used
@@ -886,12 +889,6 @@ OUString  SwDocStyleSheet::GetDescription(MapUnit eUnit)
                 {
                     case SID_ATTR_AUTO_STYLE_UPDATE:
                     case RES_PAGEDESC:
-                    //CTL not yet supported
-                    case RES_CHRATR_CTL_FONT:
-                    case RES_CHRATR_CTL_FONTSIZE:
-                    case RES_CHRATR_CTL_LANGUAGE:
-                    case RES_CHRATR_CTL_POSTURE:
-                    case RES_CHRATR_CTL_WEIGHT:
                         break;
                     default:
                     {
@@ -962,6 +959,19 @@ OUString  SwDocStyleSheet::GetDescription(MapUnit eUnit)
                                     bHasCJKFontPrefix = true;
                                 }
                                 break;
+                                case RES_CHRATR_CTL_FONT:
+                                case RES_CHRATR_CTL_FONTSIZE:
+                                case RES_CHRATR_CTL_LANGUAGE:
+                                case RES_CHRATR_CTL_POSTURE:
+                                case RES_CHRATR_CTL_WEIGHT:
+                                if(aCTLOptions.IsCTLFontEnabled())
+                                    bIsDefault = true;
+                                if(!bHasCTLFontPrefix)
+                                {
+                                    aItemPresentation = SwResId(STR_CTL_FONT) + aItemPresentation;
+                                    bHasCTLFontPrefix = true;
+                                }
+                                break;
                                 case RES_CHRATR_FONT:
                                 case RES_CHRATR_FONTSIZE:
                                 case RES_CHRATR_LANGUAGE:
commit 8edd9a85bbbfba3d9edb232bdbd03a7634bb8614
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Tue Feb 20 13:28:10 2018 +0300

    tdf#115874: show non-zero fraction part for pts
    
    Change-Id: I6183d9d7e28b76bb4da0229c42573ee833f2520a
    Reviewed-on: https://gerrit.libreoffice.org/50033
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit 3fcf374de426102da36f5b07fda5b0534de62233)

diff --git a/editeng/source/items/itemtype.cxx b/editeng/source/items/itemtype.cxx
index 39126f065f1d..83d8c8e91661 100644
--- a/editeng/source/items/itemtype.cxx
+++ b/editeng/source/items/itemtype.cxx
@@ -29,6 +29,7 @@
 OUString GetMetricText( long nVal, MapUnit eSrcUnit, MapUnit eDestUnit, const IntlWrapper* pIntl )
 {
     bool bNeg = false;
+    bool bShowAtLeastOneDecimalDigit = true;
     sal_Int32 nRet = 0;
 
     if ( nVal < 0 )
@@ -74,6 +75,11 @@ OUString GetMetricText( long nVal, MapUnit eSrcUnit, MapUnit eDestUnit, const In
         }
 
         case MapUnit::MapPoint:
+            // fractions of a point are used, e.g., for font size
+            nRet = OutputDevice::LogicToLogic(nVal, eSrcUnit, MapUnit::MapTwip) * 50;
+            bShowAtLeastOneDecimalDigit = false;
+            break;
+
         case MapUnit::MapTwip:
         case MapUnit::MapPixel:
             return OUString::number( OutputDevice::LogicToLogic(
@@ -107,7 +113,7 @@ OUString GetMetricText( long nVal, MapUnit eSrcUnit, MapUnit eDestUnit, const In
         else
             sRet.append(nRet / nDiff);
         nRet %= nDiff;
-        if( 4 == nDigits )
+        if( 4 == nDigits && (bShowAtLeastOneDecimalDigit || nRet) )
         {
             if(pIntl)
                 sRet.append(pIntl->getLocaleData()->getNumDecimalSep());
commit 2ea6fc6b1f8465d6859b6acd1a96a0157ecf18f5
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Tue Feb 20 08:46:23 2018 +0100

    Use existing variable for that
    
    Change-Id: I583bec8ea5dc7c2462cedee116048db12492e128
    Reviewed-on: https://gerrit.libreoffice.org/50026
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit e42cce6be36b82bf92ed04af275ff1d4703d982b)

diff --git a/sw/source/uibase/app/docst.cxx b/sw/source/uibase/app/docst.cxx
index 8719f7444ece..ab91f5e13f26 100644
--- a/sw/source/uibase/app/docst.cxx
+++ b/sw/source/uibase/app/docst.cxx
@@ -820,8 +820,7 @@ void SwDocShell::Edit(
         SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
         assert( pFact );
         ScopedVclPtr<SfxAbstractApplyTabDialog> pDlg(pFact->CreateTemplateDialog(&GetView()->GetViewFrame()->GetWindow(),
-                                                    *(xTmp.get()), nFamily, sPage,
-                                                    pActShell ? pActShell : m_pWrtShell, bNew));
+                                                    *(xTmp.get()), nFamily, sPage, pCurrShell, bNew));
         assert( pDlg );
         std::shared_ptr<ApplyStyle> pApplyStyleHelper(new ApplyStyle(*this, bNew, xTmp, nFamily, pDlg.get(), m_xBasePool, bModified));
         pDlg->SetApplyHdl(LINK(pApplyStyleHelper.get(), ApplyStyle, ApplyHdl));
commit ea4a9ca0a6ccf747a34997dc1d50efb82f9106ee
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Mon Feb 19 22:23:32 2018 +0100

    tdf#115639: Handle alignment correctly for multiple paragraph case
    
    I used the wrong calculator method to get the line width.
    This commit also fixes the crashes found by crashtest.
    
    Change-Id: I25392f86af912ee54c07b14480d82282210ac346
    Reviewed-on: https://gerrit.libreoffice.org/49994
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit f0485ba2d90aae0312f5775588f22789016165d2)

diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index dbd169f50b94..78e17a78d54b 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -1942,6 +1942,39 @@ void Test::testHoriAlignIgnoreTrailingWhitespace()
         EditLine* pLine = &pParaPortion->GetLines()[0];
         CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(8815), pLine->GetStartPosX(), 10);
     }
+
+    // Test multiple paragraph case
+    {
+        // Set initial text
+        aText = "Some text    \nMore Text   ";
+        aTextLen = aText.getLength();
+        aEditEngine.SetText(aText);
+
+        // Assert changes - text insertion
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong>(aTextLen - 1), rDoc.GetTextLen());
+        CPPUNIT_ASSERT_EQUAL(OUString("Some text    "), rDoc.GetParaAsString(static_cast<sal_Int32>(0)));
+        CPPUNIT_ASSERT_EQUAL(OUString("More Text   "), rDoc.GetParaAsString(static_cast<sal_Int32>(1)));
+
+        aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(true);
+        std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet()));
+        pSet->Put(SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST ));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count());
+
+        // Select all paragraphs and apply changes
+        ESelection aSelection(0, 0, 0, aTextLen);
+        aEditEngine.QuickSetAttribs(*pSet, aSelection);
+
+        // Get one line paragraphs
+        aEditEngine.SetPaperSize(Size(10000, 6000));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(1));
+
+        // Check horizontal position
+        ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4527), pParaPortion->GetLines()[0].GetStartPosX(), 50);
+        pParaPortion = aEditEngine.GetParaPortions()[1];
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(8815), pParaPortion->GetLines()[0].GetStartPosX(), 50);
+    }
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index 54d07d3dd9ec..d840584f2739 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -1432,13 +1432,13 @@ sal_uInt32 EditEngine::GetTextHeightNTP() const
     return pImpEditEngine->GetTextHeightNTP();
 }
 
-sal_uInt32 EditEngine::CalcTextWidth(bool bIgnoreTrailingWhiteSpaces)
+sal_uInt32 EditEngine::CalcTextWidth()
 {
 
     if ( !pImpEditEngine->IsFormatted() )
         pImpEditEngine->FormatDoc();
 
-    sal_uInt32 nWidth = !IsVertical() ? pImpEditEngine->CalcTextWidth( true, bIgnoreTrailingWhiteSpaces ) : pImpEditEngine->GetTextHeight();
+    sal_uInt32 nWidth = !IsVertical() ? pImpEditEngine->CalcTextWidth( true ) : pImpEditEngine->GetTextHeight();
      return nWidth;
 }
 
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 808d92248d2a..e80ab97cf918 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -832,7 +832,7 @@ public:
     sal_uInt32      CalcTextHeight( sal_uInt32* pHeightNTP );
     sal_uInt32      GetTextHeight() const;
     sal_uInt32      GetTextHeightNTP() const;
-    sal_uInt32      CalcTextWidth( bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces = false );
+    sal_uInt32      CalcTextWidth( bool bIgnoreExtraSpace );
     sal_uInt32      CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces = false );
     sal_Int32       GetLineCount( sal_Int32 nParagraph ) const;
     sal_Int32       GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine ) const;
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index 8c67172db098..d66bf4e6e973 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -3093,7 +3093,7 @@ sal_uInt32 ImpEditEngine::GetTextHeight() const
     return nCurTextHeight;
 }
 
-sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces )
+sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace )
 {
     // If still not formatted and not in the process.
     // Will be brought in the formatting for AutoPageSize.
@@ -3140,7 +3140,7 @@ sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace, bool bIgnoreTra
                     }
                 }
                 nCurWidth += GetXValue( rLRItem.GetRight() );
-                nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace, bIgnoreTrailingWhiteSpaces );
+                nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace );
                 if ( nCurWidth > nMaxWidth )
                 {
                     nMaxWidth = nCurWidth;
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 609ff154eb85..011525fbab94 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -1514,7 +1514,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
             {
                 long n;
                 if(IsHoriAlignIgnoreTrailingWhitespace())
-                    n = ( nMaxLineWidth - CalcTextWidth( true, true ) ) / 2;
+                    n = ( nMaxLineWidth - CalcLineWidth( pParaPortion, pLine, false, true ) ) / 2;
                 else
                     n = ( nMaxLineWidth - aTextSize.Width() ) / 2;
                 n += nStartX;  // Indentation is kept.
@@ -1527,7 +1527,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
                 // the blank must not be displayed!
                 long n;
                 if(IsHoriAlignIgnoreTrailingWhitespace())
-                    n = nMaxLineWidth - CalcTextWidth( true, true );
+                    n = nMaxLineWidth - CalcLineWidth( pParaPortion, pLine, false, true );
                 else
                     n = nMaxLineWidth - aTextSize.Width();
                 n += nStartX;  // Indentation is kept.
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index 1193a402b84e..da55da70e931 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -273,7 +273,7 @@ public:
     sal_uInt32      GetTextLen() const;
     sal_uInt32      GetTextHeight() const;
     sal_uInt32      GetTextHeightNTP() const;
-    sal_uInt32      CalcTextWidth( bool bIgnoreTrailingWhiteSpaces = false );
+    sal_uInt32      CalcTextWidth();
 
     OUString        GetText( sal_Int32 nParagraph ) const;
     sal_Int32       GetTextLen( sal_Int32 nParagraph ) const;
commit 50137347163468482648b603a0e42ebe5af448a5
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Fri Feb 16 12:25:13 2018 +0530

    lok IME: underline characters which are being composed
    
    Change-Id: Ibfc35f1668228400f37ec9b0b0350583483f484d
    (cherry picked from commit 05e4ce8643cc4cba6e86779af162caf79c2c7bf3)

diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 9d95bafcc408..cebc4e56f2cc 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -2094,7 +2094,7 @@ void Window::PostExtTextInputEvent(VclEventId nType, const OUString& rText)
     {
         std::unique_ptr<ExtTextInputAttr[]> pAttr(new ExtTextInputAttr[rText.getLength()]);
         for (int i = 0; i < rText.getLength(); ++i) {
-            pAttr[i] = ExtTextInputAttr::NONE;
+            pAttr[i] = ExtTextInputAttr::Underline;
         }
         SalExtTextInputEvent aEvent { rText, pAttr.get(), rText.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE };
         ImplWindowFrameProc(this, SalEvent::ExtTextInput, &aEvent);
commit af71e215c363449843121d01c3b8129493cbd49e
Author: Henry Castro <hcastro at collabora.com>
Date:   Sun Feb 18 11:26:20 2018 -0400

    sw lok: assign a parent window to property dialog
    
    Change-Id: Ief98b93502c3c69f84e7de47393718370a839208
    Reviewed-on: https://gerrit.libreoffice.org/49926
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Henry Castro <hcastro at collabora.com>
    (cherry picked from commit 55f5afe532c61c6bc382f23e17dfeb6ed3985790)

diff --git a/sw/source/uibase/app/docsh2.cxx b/sw/source/uibase/app/docsh2.cxx
index e9877bf14ee9..83b1384aebd0 100644
--- a/sw/source/uibase/app/docsh2.cxx
+++ b/sw/source/uibase/app/docsh2.cxx
@@ -140,7 +140,7 @@ using namespace ::sfx2;
 // create DocInfo (virtual)
 VclPtr<SfxDocumentInfoDialog> SwDocShell::CreateDocumentInfoDialog(const SfxItemSet &rSet)
 {
-    VclPtr<SfxDocumentInfoDialog> pDlg = VclPtr<SfxDocumentInfoDialog>::Create(nullptr, rSet);
+    VclPtr<SfxDocumentInfoDialog> pDlg = VclPtr<SfxDocumentInfoDialog>::Create(&GetView()->GetViewFrame()->GetWindow(), rSet);
     //only with statistics, when this document is being shown, not
     //from within the Doc-Manager
     SwDocShell* pDocSh = static_cast<SwDocShell*>( SfxObjectShell::Current());
commit cb75f14a446ae2f59e65414c3ac078068762e92c
Author: Tor Lillqvist <tml at collabora.com>
Date:   Sat Feb 17 17:22:59 2018 +0200

    tdf#115283: Avoid bashism
    
    (We do require bash for other parts of the build, though, and have no
    plans to change that. But let's make the bug reporter happy here.)
    
    Change-Id: I4bcd3a86fb4e6f95d4eec8557faf359bf5549c03
    (cherry picked from commit c902cbc7dc5294ab721a9aef3a152aa243d00011)

diff --git a/configure.ac b/configure.ac
index 87b996dbb293..f8394c9677a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -169,7 +169,7 @@ if test "$enable_release_build" = "" -o "$enable_release_build" = "no"; then
 fi
 AC_MSG_RESULT([$PRODUCTNAME])
 AC_SUBST(PRODUCTNAME)
-PRODUCTNAME_WITHOUT_SPACES=${PRODUCTNAME// /}
+PRODUCTNAME_WITHOUT_SPACES=$(echo "$PRODUCTNAME" | sed 's/ //g')
 AC_SUBST(PRODUCTNAME_WITHOUT_SPACES)
 
 dnl ===================================================================
commit 2a664263d043f0327a92d5d5f7507bd10143fd31
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Sat Feb 17 06:35:29 2018 +0100

    tdf#115639: Align right/center with trailing spaces the same as MS PowerPoint
    
    * Add HoriAlignIgnoreTrailingWhitespace compatibility option.
    ** For MSO file formats it is set to true
    ** For ODP format it's set to false by default
    ** The flag is saved to ODP format as user data if the document
    comes from an MSO format.
    
    Reviewed-on: https://gerrit.libreoffice.org/49889
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit 1da3a3cb74a415a76fa547ef0c8f61780e260e7f)
    
    Change-Id: Ie22233d33a25e605de46120bfc2195038dffd63c

diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index 5e18be53aa17..dbd169f50b94 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -33,6 +33,7 @@
 #include <svl/srchitem.hxx>
 #include <editeng/fontitem.hxx>
 #include <editeng/fhgtitem.hxx>
+#include <editeng/adjustitem.hxx>
 
 #include <com/sun/star/text/textfield/Type.hpp>
 
@@ -95,6 +96,9 @@ public:
 
     void testLargeParaCopyPaste();
 
+    /// Test HoriAlignIgnoreTrailingWhitespace compatibility flag
+    void testHoriAlignIgnoreTrailingWhitespace();
+
     DECL_STATIC_LINK( Test, CalcFieldValueHdl, EditFieldInfo*, void );
 
     CPPUNIT_TEST_SUITE(Test);
@@ -114,6 +118,7 @@ public:
     CPPUNIT_TEST(testParaStartCopyPaste);
     CPPUNIT_TEST(testSectionAttributes);
     CPPUNIT_TEST(testLargeParaCopyPaste);
+    CPPUNIT_TEST(testHoriAlignIgnoreTrailingWhitespace);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -1833,6 +1838,112 @@ void Test::testLargeParaCopyPaste()
     CPPUNIT_ASSERT_EQUAL( aTenthPara, rDoc.GetParaAsString(sal_Int32(11)) );
 }
 
+void Test::testHoriAlignIgnoreTrailingWhitespace()
+{
+    // Create EditEngine's instance
+    EditEngine aEditEngine(mpItemPool);
+
+    // Get EditDoc for current EditEngine's instance
+    EditDoc &rDoc = aEditEngine.GetEditDoc();
+
+    // Initially no text should be there
+    CPPUNIT_ASSERT_EQUAL(sal_uLong(0), rDoc.GetTextLen());
+    CPPUNIT_ASSERT_EQUAL(OUString(), rDoc.GetParaAsString(sal_Int32(0)));
+
+    // Set initial text
+    OUString aText = "Some text    ";
+    sal_Int32 aTextLen = aText.getLength();
+    aEditEngine.SetText(aText);
+
+    // Assert changes - text insertion
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong>(aTextLen), rDoc.GetTextLen());
+    CPPUNIT_ASSERT_EQUAL(aText, rDoc.GetParaAsString(static_cast<sal_Int32>(0)));
+
+    // First test case: center alignment with compatibility option enabled
+    {
+        aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(true);
+        std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet()));
+        pSet->Put(SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST ));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count());
+
+        // Select all paragraphs and apply changes
+        ESelection aSelection(0, 0, 0, aTextLen);
+        aEditEngine.QuickSetAttribs(*pSet, aSelection);
+
+        // Use a one line paragraph
+        aEditEngine.SetPaperSize(Size(10000, 6000));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0));
+
+        // Check horizontal position
+        ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
+        EditLine* pLine = &pParaPortion->GetLines()[0];
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4527), pLine->GetStartPosX(), 10);
+    }
+
+    // Second test case: center alignment with compatibility option disabled
+    {
+        aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(false);
+        std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet()));
+        pSet->Put(SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST ));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count());
+
+        // Select all paragraphs and apply changes
+        ESelection aSelection(0, 0, 0, aTextLen);
+        aEditEngine.QuickSetAttribs(*pSet, aSelection);
+
+        // Use a one line paragraph
+        aEditEngine.SetPaperSize(Size(10000, 6000));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0));
+
+        // Check horizontal position
+        ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
+        EditLine* pLine = &pParaPortion->GetLines()[0];
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4407), pLine->GetStartPosX(), 10);
+    }
+
+    // Third test case: right alignment with compatibility option enabled
+    {
+        aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(true);
+        std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet()));
+        pSet->Put(SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST ));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count());
+
+        // Select all paragraphs and apply changes
+        ESelection aSelection(0, 0, 0, aTextLen);
+        aEditEngine.QuickSetAttribs(*pSet, aSelection);
+
+        // Use a one line paragraph
+        aEditEngine.SetPaperSize(Size(10000, 6000));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0));
+
+        // Check horizontal position
+        ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
+        EditLine* pLine = &pParaPortion->GetLines()[0];
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(9054), pLine->GetStartPosX(), 10);
+    }
+
+    // Fourth test case: right alignment with compatibility option disabled
+    {
+        aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(false);
+        std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet()));
+        pSet->Put(SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST ));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count());
+
+        // Select all paragraphs and apply changes
+        ESelection aSelection(0, 0, 0, aTextLen);
+        aEditEngine.QuickSetAttribs(*pSet, aSelection);
+
+        // Use a one line paragraph
+        aEditEngine.SetPaperSize(Size(10000, 6000));
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0));
+
+        // Check horizontal position
+        ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
+        EditLine* pLine = &pParaPortion->GetLines()[0];
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(8815), pLine->GetStartPosX(), 10);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 }
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index a3679f5809b1..54d07d3dd9ec 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -1432,13 +1432,13 @@ sal_uInt32 EditEngine::GetTextHeightNTP() const
     return pImpEditEngine->GetTextHeightNTP();
 }
 
-sal_uInt32 EditEngine::CalcTextWidth()
+sal_uInt32 EditEngine::CalcTextWidth(bool bIgnoreTrailingWhiteSpaces)
 {
 
     if ( !pImpEditEngine->IsFormatted() )
         pImpEditEngine->FormatDoc();
 
-    sal_uInt32 nWidth = !IsVertical() ? pImpEditEngine->CalcTextWidth( true ) : pImpEditEngine->GetTextHeight();
+    sal_uInt32 nWidth = !IsVertical() ? pImpEditEngine->CalcTextWidth( true, bIgnoreTrailingWhiteSpaces ) : pImpEditEngine->GetTextHeight();
      return nWidth;
 }
 
@@ -2804,6 +2804,16 @@ bool EditEngine::IsPageOverflow() {
     return pImpEditEngine->IsPageOverflow();
 }
 
+void EditEngine::SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled)
+{
+    pImpEditEngine->SetHoriAlignIgnoreTrailingWhitespace(bEnabled);
+}
+
+bool EditEngine::IsHoriAlignIgnoreTrailingWhitespace() const
+{
+    return pImpEditEngine->IsHoriAlignIgnoreTrailingWhitespace();
+}
+
 EFieldInfo::EFieldInfo()
 {
 }
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index d9ec9a17136a..808d92248d2a 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -535,6 +535,7 @@ private:
     bool            bFirstWordCapitalization:1;   // specifies if auto-correction should capitalize the first word or not
     bool            mbLastTryMerge:1;
     bool            mbReplaceLeadingSingleQuotationMark:1;
+    bool            mbHoriAlignIgnoreTrailingWhitespace:1;
 
     bool            mbNbspRunNext;  // can't be a bitfield as it is passed as bool&
 
@@ -831,8 +832,8 @@ public:
     sal_uInt32      CalcTextHeight( sal_uInt32* pHeightNTP );
     sal_uInt32      GetTextHeight() const;
     sal_uInt32      GetTextHeightNTP() const;
-    sal_uInt32      CalcTextWidth( bool bIgnoreExtraSpace );
-    sal_uInt32      CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace );
+    sal_uInt32      CalcTextWidth( bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces = false );
+    sal_uInt32      CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces = false );
     sal_Int32       GetLineCount( sal_Int32 nParagraph ) const;
     sal_Int32       GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine ) const;
     void            GetLineBoundaries( /*out*/sal_Int32& rStart, /*out*/sal_Int32& rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const;
@@ -1063,6 +1064,10 @@ public:
     bool            IsNbspRunNext() const { return mbNbspRunNext; }
 
     void Dispose();
+
+    // tdf#115639 compatibility flag
+    void SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled) { mbHoriAlignIgnoreTrailingWhitespace = bEnabled; }
+    bool IsHoriAlignIgnoreTrailingWhitespace() const { return mbHoriAlignIgnoreTrailingWhitespace; }
 };
 
 inline EPaM ImpEditEngine::CreateEPaM( const EditPaM& rPaM )
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index 41fec1bf80b3..8c67172db098 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -108,6 +108,7 @@ ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) :
     bFirstWordCapitalization(true),
     mbLastTryMerge(false),
     mbReplaceLeadingSingleQuotationMark(true),
+    mbHoriAlignIgnoreTrailingWhitespace(false),
     mbNbspRunNext(false)
 {
     pEditEngine         = pEE;
@@ -3092,7 +3093,7 @@ sal_uInt32 ImpEditEngine::GetTextHeight() const
     return nCurTextHeight;
 }
 
-sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace )
+sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces )
 {
     // If still not formatted and not in the process.
     // Will be brought in the formatting for AutoPageSize.
@@ -3139,7 +3140,7 @@ sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace )
                     }
                 }
                 nCurWidth += GetXValue( rLRItem.GetRight() );
-                nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace );
+                nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace, bIgnoreTrailingWhiteSpaces );
                 if ( nCurWidth > nMaxWidth )
                 {
                     nMaxWidth = nCurWidth;
@@ -3152,7 +3153,7 @@ sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace )
     return (sal_uInt32)nMaxWidth;
 }
 
-sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace )
+sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces )
 {
     sal_Int32 nPara = GetEditDoc().GetPos( pPortion->GetNode() );
 
@@ -3181,7 +3182,7 @@ sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine,
             break;
             case PortionKind::TEXT:
             {
-                if ( ( eJustification != SvxAdjust::Block ) || ( !bIgnoreExtraSpace ) )
+                if ( (( eJustification != SvxAdjust::Block ) || ( !bIgnoreExtraSpace )) && !bIgnoreTrailingWhiteSpaces )
                 {
                     nWidth += rTextPortion.GetSize().Width();
                 }
@@ -3191,7 +3192,10 @@ sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine,
                     SeekCursor( pPortion->GetNode(), nPos+1, aTmpFont );
                     aTmpFont.SetPhysFont( GetRefDevice() );
                     ImplInitDigitMode(GetRefDevice(), aTmpFont.GetLanguage());
-                    nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString(), nPos, rTextPortion.GetLen() ).Width();
+                    if (bIgnoreTrailingWhiteSpaces)
+                        nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString().trim(), nPos, rTextPortion.GetLen() ).Width();
+                    else
+                        nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString(), nPos, rTextPortion.GetLen() ).Width();
                 }
             }
             break;
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 7058233308ee..609ff154eb85 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -1512,7 +1512,11 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
         {
             case SvxAdjust::Center:
             {
-                long n = ( nMaxLineWidth - aTextSize.Width() ) / 2;
+                long n;
+                if(IsHoriAlignIgnoreTrailingWhitespace())
+                    n = ( nMaxLineWidth - CalcTextWidth( true, true ) ) / 2;
+                else
+                    n = ( nMaxLineWidth - aTextSize.Width() ) / 2;
                 n += nStartX;  // Indentation is kept.
                 pLine->SetStartPosX( n );
             }
@@ -1521,7 +1525,11 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
             {
                 // For automatically wrapped lines, which has a blank at the end
                 // the blank must not be displayed!
-                long n = nMaxLineWidth - aTextSize.Width();
+                long n;
+                if(IsHoriAlignIgnoreTrailingWhitespace())
+                    n = nMaxLineWidth - CalcTextWidth( true, true );
+                else
+                    n = nMaxLineWidth - aTextSize.Width();
                 n += nStartX;  // Indentation is kept.
                 pLine->SetStartPosX( n );
             }
diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx
index 27ffe02353db..7e65100b03f7 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -366,6 +366,16 @@ sal_Int32 Outliner::GetBulletsNumberingStatus() const
            : 2;
 }
 
+void Outliner::SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled)
+{
+    pEditEngine->SetHoriAlignIgnoreTrailingWhitespace( bEnabled );
+}
+
+bool Outliner::IsHoriAlignIgnoreTrailingWhitespace() const
+{
+    return pEditEngine->IsHoriAlignIgnoreTrailingWhitespace();
+}
+
 OutlinerParaObject* Outliner::CreateParaObject( sal_Int32 nStartPara, sal_Int32 nCount ) const
 {
     if ( static_cast<sal_uLong>(nStartPara) + nCount >
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index 7fa9ebb910a6..1193a402b84e 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -273,7 +273,7 @@ public:
     sal_uInt32      GetTextLen() const;
     sal_uInt32      GetTextHeight() const;
     sal_uInt32      GetTextHeightNTP() const;
-    sal_uInt32      CalcTextWidth();
+    sal_uInt32      CalcTextWidth( bool bIgnoreTrailingWhiteSpaces = false );
 
     OUString        GetText( sal_Int32 nParagraph ) const;
     sal_Int32       GetTextLen( sal_Int32 nParagraph ) const;
@@ -620,6 +620,10 @@ public:
     sal_Int32 GetOverflowingLineNum() const;
     void ClearOverflowingParaNum();
     bool IsPageOverflow();
+
+    // tdf#115639 compatibility flag
+    void SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled);
+    bool IsHoriAlignIgnoreTrailingWhitespace() const;
 };
 
 #endif // INCLUDED_EDITENG_EDITENG_HXX
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index 24ec0ec0f8a4..c303e1a84522 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -999,6 +999,10 @@ public:
 
     // convenient method to determine the bullets/numbering status for all paragraphs
     sal_Int32 GetBulletsNumberingStatus() const;
+
+    // tdf#115639 compatibility flag
+    void SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled);
+    bool IsHoriAlignIgnoreTrailingWhitespace() const;
 };
 
 #endif
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index 4a38209b561d..5ea384c5ed6b 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -538,6 +538,10 @@ public:
     void SetAnchoredTextOverflowLegacy(bool bEnabled);
     bool IsAnchoredTextOverflowLegacy() const;
 
+    // tdf#115639 compatibility flag
+    void SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled);
+    bool IsHoriAlignIgnoreTrailingWhitespace() const;
+
     void ReformatAllTextObjects();
 
     SdrOutliner* createOutliner( OutlinerMode nOutlinerMode );
diff --git a/sd/qa/unit/data/odp/tdf115639.odp b/sd/qa/unit/data/odp/tdf115639.odp
new file mode 100755
index 000000000000..b732e4e7652b
Binary files /dev/null and b/sd/qa/unit/data/odp/tdf115639.odp differ
diff --git a/sd/qa/unit/data/ppt/tdf115639.ppt b/sd/qa/unit/data/ppt/tdf115639.ppt
new file mode 100755
index 000000000000..dade453bfeee
Binary files /dev/null and b/sd/qa/unit/data/ppt/tdf115639.ppt differ
diff --git a/sd/qa/unit/data/pptx/tdf115639.pptx b/sd/qa/unit/data/pptx/tdf115639.pptx
new file mode 100755
index 000000000000..7e00b60cb397
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf115639.pptx differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 2c32a71a6d69..b8e6575a3628 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -172,6 +172,7 @@ public:
     void testTdf51340();
     void testTdf115394();
     void testTdf115394PPT();
+    void testTdf115639();
 
     bool checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected);
     void testPatternImport();
@@ -249,6 +250,7 @@ public:
     CPPUNIT_TEST(testTdf51340);
     CPPUNIT_TEST(testTdf115394);
     CPPUNIT_TEST(testTdf115394PPT);
+    CPPUNIT_TEST(testTdf115639);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -2435,6 +2437,37 @@ void SdImportTest::testTdf115394PPT()
     xDocShRef->DoClose();
 }
 
+
+void SdImportTest::testTdf115639()
+{
+    // Check whether the new compatibility option is loaded correctly
+    // For PPTX we have the flag enabled by default
+    {
+        sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf115639.pptx"), PPTX);
+        SdDrawDocument *pDoc = xDocShRef->GetDoc();
+        CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+        CPPUNIT_ASSERT( pDoc->IsHoriAlignIgnoreTrailingWhitespace() );
+    }
+
+    // For PPT we have the flag enabled by default
+    {
+        sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf115639.ppt"), PPT);
+        SdDrawDocument *pDoc = xDocShRef->GetDoc();
+        CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+        CPPUNIT_ASSERT( pDoc->IsHoriAlignIgnoreTrailingWhitespace() );
+        xDocShRef->DoClose();
+    }
+
+    // For ODP we have the flag disabled by default
+    {
+        sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/tdf115639.odp"), ODP);
+        SdDrawDocument *pDoc = xDocShRef->GetDoc();
+        CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+        CPPUNIT_ASSERT( !pDoc->IsHoriAlignIgnoreTrailingWhitespace() );
+        xDocShRef->DoClose();
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/ui/docshell/docshel4.cxx b/sd/source/ui/docshell/docshel4.cxx
index b5d3edb68e59..a6fa0870ae43 100644
--- a/sd/source/ui/docshell/docshel4.cxx
+++ b/sd/source/ui/docshell/docshel4.cxx
@@ -406,6 +406,14 @@ bool DrawDocShell::ImportFrom(SfxMedium &rMedium,
         mpDoc->SetSummationOfParagraphs();
     }
 
+    // Set this flag for MSO formats
+    if (aFilterName.startsWith("MS PowerPoint 97") ||
+        aFilterName.startsWith("Impress MS PowerPoint 2007 XML") ||
+        aFilterName.startsWith("Impress Office Open XML"))
+    {
+        mpDoc->SetHoriAlignIgnoreTrailingWhitespace(true);
+    }
+
     const bool bRet = SfxObjectShell::ImportFrom(rMedium, xInsertPosition);
 
     SfxItemSet* pSet = rMedium.GetItemSet();
@@ -495,6 +503,14 @@ bool DrawDocShell::ConvertFrom( SfxMedium& rMedium )
         bRet = SdGRFFilter( rMedium, *this ).Import();
     }
 
+    // Set this flag for MSO formats
+    if (aFilterName.startsWith("MS PowerPoint 97") ||
+        aFilterName.startsWith("Impress MS PowerPoint 2007 XML") ||
+        aFilterName.startsWith("Impress Office Open XML"))
+    {
+        mpDoc->SetHoriAlignIgnoreTrailingWhitespace(true);
+    }
+
     FinishedLoading();
 
     // tell SFX to change viewshell when in preview mode
diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx
index 2609e6e65bce..e6402b2dc6ce 100644
--- a/sd/source/ui/view/Outliner.cxx
+++ b/sd/source/ui/view/Outliner.cxx
@@ -226,6 +226,7 @@ SdOutliner::SdOutliner( SdDrawDocument* pDoc, OutlinerMode nMode )
         SetHyphenator( xHyphenator );
 
     SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
+    SetHoriAlignIgnoreTrailingWhitespace( pDoc->IsHoriAlignIgnoreTrailingWhitespace() );
 }
 
 /// Nothing spectacular in the destructor.
diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
index 807e31fc6da9..4f6d9a44a891 100644
--- a/svx/source/svdraw/svdetc.cxx
+++ b/svx/source/svdraw/svdetc.cxx
@@ -344,6 +344,7 @@ SdrOutliner* SdrMakeOutliner(OutlinerMode nOutlinerMode, SdrModel& rModel)
     pOutl->SetAsianCompressionMode(rModel.GetCharCompressType());
     pOutl->SetKernAsianPunctuation(rModel.IsKernAsianPunctuation());
     pOutl->SetAddExtLeading(rModel.IsAddExtLeading());
+    pOutl->SetHoriAlignIgnoreTrailingWhitespace(rModel.IsHoriAlignIgnoreTrailingWhitespace());
     return pOutl;
 }
 
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index 95532a7b6b34..e7cce55439a6 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -108,6 +108,7 @@ struct SdrModelImpl
     SdrUndoFactory* mpUndoFactory;
 
     bool mbAnchoredTextOverflowLegacy; // tdf#99729 compatibility flag
+    bool mbHoriAlignIgnoreTrailingWhitespace; // tdf#115639 compatibility flag
 };
 
 
@@ -118,6 +119,7 @@ void SdrModel::ImpCtor(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* _pEmbe
     mpImpl->mpUndoManager=nullptr;
     mpImpl->mpUndoFactory=nullptr;
     mpImpl->mbAnchoredTextOverflowLegacy = false;
+    mpImpl->mbHoriAlignIgnoreTrailingWhitespace = false;
     mbInDestruction = false;
     aObjUnit=SdrEngineDefaults::GetMapFraction();
     eObjUnit=SdrEngineDefaults::GetMapUnit();
@@ -1890,6 +1892,17 @@ bool SdrModel::IsAnchoredTextOverflowLegacy() const
     return mpImpl->mbAnchoredTextOverflowLegacy;
 }
 
+void SdrModel::SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled)
+{
+    mpImpl->mbHoriAlignIgnoreTrailingWhitespace = bEnabled;
+    pDrawOutliner->SetHoriAlignIgnoreTrailingWhitespace(bEnabled);
+}
+
+bool SdrModel::IsHoriAlignIgnoreTrailingWhitespace() const
+{
+    return mpImpl->mbHoriAlignIgnoreTrailingWhitespace;
+}
+
 void SdrModel::ReformatAllTextObjects()
 {
     ImpReformatAllTextObjects();
@@ -1939,6 +1952,13 @@ void SdrModel::ReadUserDataSequenceValue(const css::beans::PropertyValue* pValue
             mpImpl->mbAnchoredTextOverflowLegacy = bBool;
         }
     }
+    if (pValue->Name == "HoriAlignIgnoreTrailingWhitespace")
+    {
+        if (pValue->Value >>= bBool)
+        {
+            SetHoriAlignIgnoreTrailingWhitespace(bBool);
+        }
+    }
 }
 
 template <typename T>
@@ -1951,6 +1971,8 @@ void SdrModel::WriteUserDataSequence(css::uno::Sequence < css::beans::PropertyVa
 {
     std::vector< std::pair< OUString, Any > > aUserData;
     addPair(aUserData, "AnchoredTextOverflowLegacy", IsAnchoredTextOverflowLegacy());
+    if (IsHoriAlignIgnoreTrailingWhitespace())
+        addPair(aUserData, "HoriAlignIgnoreTrailingWhitespace", IsHoriAlignIgnoreTrailingWhitespace());
 
     const sal_Int32 nOldLength = rValues.getLength();
     rValues.realloc(nOldLength + aUserData.size());
commit a4c6b3fa56ef6b8310f94eac90384243355046f6
Author: Szymon Kłos <szymon.klos at collabora.com>
Date:   Fri Feb 16 22:13:49 2018 +0100

    Fix fontScale test
    
    Change-Id: Idd16270cc6af0108442ba26db62ed933bbb0a63a
    Reviewed-on: https://gerrit.libreoffice.org/49881
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
    (cherry picked from commit 7a510effa4566d405d2033b6635b42c08d34dec8)

diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index fda810363356..f09345d9e9cc 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -1377,7 +1377,10 @@ void SdOOXMLExportTest2::testFontScale()
     xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
     xmlDocPtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml");
 
-    assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit", "fontScale", "73000");
+    // Rounding errors possible, approximate value
+    OUString sScale = getXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit", "fontScale");
+    if (sScale != "73000" && sScale != "72000" && sScale != "74000")
+        CPPUNIT_ASSERT_EQUAL(OUString("73000"), sScale);
 
     xDocShRef->DoClose();
 }
commit ece07693152747e33343ce16428390f91561f4a7
Author: Szymon Kłos <szymon.klos at collabora.com>
Date:   Tue Feb 13 17:47:23 2018 +0100

    PPTX export scale for TextFitToSize
    
    MSO requires to save fontScale attribute to have
    all the text shown properly (with FitToSize property)
    
    Values are approximated, after any modification in MSO
    scale is recalculated.
    
    Change-Id: I73657fdd663b540b436747cfeeef3c76e8fe388c
    Reviewed-on: https://gerrit.libreoffice.org/49742
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
    (cherry picked from commit 2c2919cb591d88b11bb2e25e45d6f75923821457)

diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index a2860906481f..4bd5ec29c410 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -211,6 +211,7 @@ protected:
 
     virtual SdrObject* getFullDragClone() const override;
 
+
 public:
     const Point& GetTextEditOffset() const { return maTextEditOffset; }
     void SetTextEditOffset(const Point& rNew) { maTextEditOffset = rNew; }
@@ -383,6 +384,7 @@ public:
     // FitToSize and Fontwork are not taken into account in GetTextSize()!
     virtual const Size& GetTextSize() const;
     void FitFrameToTextSize();
+    double GetFontScaleY() const;
 
     // Simultaneously sets the text into the Outliner (possibly
     // the one of the EditOutliner) and sets the PaperSize.
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 481d01fc5813..25d4e23fbb5c 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2378,8 +2378,25 @@ void DrawingML::WriteText( const Reference< XInterface >& rXIface, const OUStrin
             TextFitToSizeType eFit = TextFitToSizeType_NONE;
             if (GETA(TextFitToSize))
                 mAny >>= eFit;
+
             if (eFit == TextFitToSizeType_AUTOFIT)
-                mpFS->singleElementNS(XML_a, XML_normAutofit, FSEND);
+            {
+                const sal_Int32 MAX_SCALE_VAL = 100000;
+                sal_Int32 nFontScale = MAX_SCALE_VAL;
+                SvxShapeText* pTextShape = dynamic_cast<SvxShapeText*>(rXIface.get());
+                if (pTextShape)
+                {
+                    SdrTextObj* pTextObject = dynamic_cast<SdrTextObj*>(pTextShape->GetSdrObject());
+                    if (pTextObject)
+                    {
+                        double fScaleY = pTextObject->GetFontScaleY();
+                        nFontScale = static_cast<sal_uInt32>(fScaleY * 100) * 1000;
+                    }
+                }
+
+                mpFS->singleElementNS(XML_a, XML_normAutofit, XML_fontScale,
+                    ( nFontScale < MAX_SCALE_VAL && nFontScale > 0 ) ? I32S(nFontScale) : nullptr, FSEND);
+            }
         }
         mpFS->endElementNS((nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr);
     }
diff --git a/sd/qa/unit/data/pptx/font-scale.pptx b/sd/qa/unit/data/pptx/font-scale.pptx
new file mode 100644
index 000000000000..df33b20cebca
Binary files /dev/null and b/sd/qa/unit/data/pptx/font-scale.pptx differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index 411eb5f1a09c..fda810363356 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -126,6 +126,7 @@ public:
     void testTdf114848();
     void testTdf107608();
     void testTdf111786();
+    void testFontScale();
     void testTdf115394();
     void testTdf115394Zero();
 
@@ -179,6 +180,7 @@ public:
     CPPUNIT_TEST(testTdf114848);
     CPPUNIT_TEST(testTdf107608);
     CPPUNIT_TEST(testTdf111786);
+    CPPUNIT_TEST(testFontScale);
     CPPUNIT_TEST(testTdf115394);
     CPPUNIT_TEST(testTdf115394Zero);
 
@@ -1368,6 +1370,18 @@ void SdOOXMLExportTest2::testTdf111786()
     xDocShRef->DoClose();
 }
 
+void SdOOXMLExportTest2::testFontScale()
+{
+    sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/font-scale.pptx"), PPTX);
+    utl::TempFile tempFile;
+    xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
+    xmlDocPtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml");
+
+    assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit", "fontScale", "73000");
+
+    xDocShRef->DoClose();
+}
+
 void SdOOXMLExportTest2::testTdf115394()
 {
     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf115394.pptx"), PPTX);
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index 4662f70df497..e9560e87bb33 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -1259,6 +1259,69 @@ void SdrTextObj::ImpSetupDrawOutlinerForPaint( bool             bContourFrame,
     }
 }
 
+double SdrTextObj::GetFontScaleY() const
+{
+    SdrText* pText = getActiveText();
+    if (pText == nullptr || !pText->GetOutlinerParaObject() || pModel == nullptr)
+        return 1.0;
+
+    SdrOutliner& rOutliner = ImpGetDrawOutliner();
+    const Size aShapeSize = GetSnapRect().GetSize();
+    const Size aSize = Size(aShapeSize.Width() - GetTextLeftDistance() - GetTextRightDistance(),
+        aShapeSize.Height() - GetTextUpperDistance() - GetTextLowerDistance());
+
+    rOutliner.SetPaperSize(aSize);
+    rOutliner.SetUpdateMode(true);
+    rOutliner.SetText(*pText->GetOutlinerParaObject());
+    bool bIsVerticalWriting = IsVerticalWriting();
+
+    // Algorithm from SdrTextObj::ImpAutoFitText
+
+    sal_uInt16 nMinStretchX = 0, nMinStretchY = 0;
+    sal_uInt16 nCurrStretchX = 100, nCurrStretchY = 100;
+    sal_uInt16 aOldStretchXVals[] = { 0,0,0 };
+    const size_t aStretchArySize = SAL_N_ELEMENTS(aOldStretchXVals);
+    for (unsigned int i = 0; i<aStretchArySize; ++i)
+    {
+        const Size aCurrTextSize = rOutliner.CalcTextSizeNTP();
+        double fFactor(1.0);
+        if (bIsVerticalWriting)
+        {
+            if (aCurrTextSize.Width() != 0)
+            {
+                fFactor = double(aSize.Width()) / aCurrTextSize.Width();
+            }
+        }
+        else if (aCurrTextSize.Height() != 0)
+        {
+            fFactor = double(aSize.Height()) / aCurrTextSize.Height();
+        }
+        fFactor = std::sqrt(fFactor);
+
+        rOutliner.GetGlobalCharStretching(nCurrStretchX, nCurrStretchY);
+
+        if (fFactor >= 1.0)
+        {
+            nMinStretchX = std::max(nMinStretchX, nCurrStretchX);
+            nMinStretchY = std::max(nMinStretchY, nCurrStretchY);
+        }
+
+        aOldStretchXVals[i] = nCurrStretchX;
+        if (std::find(aOldStretchXVals, aOldStretchXVals + i, nCurrStretchX) != aOldStretchXVals + i)
+            break; // same value already attained once; algo is looping, exit
+
+        if (fFactor < 1.0 || nCurrStretchX != 100)
+        {
+            nCurrStretchX = sal::static_int_cast<sal_uInt16>(nCurrStretchX*fFactor);
+            nCurrStretchY = sal::static_int_cast<sal_uInt16>(nCurrStretchY*fFactor);
+            rOutliner.SetGlobalCharStretching(std::min(sal_uInt16(100), nCurrStretchX),
+                std::min(sal_uInt16(100), nCurrStretchY));
+        }
+    }
+
+    return std::min(sal_uInt16(100), nCurrStretchY) / 100.0;
+}
+
 void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner ) const
 {
     const Size aShapeSize=GetSnapRect().GetSize();
commit f734ff65dfa8fd02a03f26c7b9d0a21692a6d5fb
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Feb 15 11:52:46 2018 +0100

    editeng: fix up ODF export test code to build again
    
    The ability to inspect the output from the editeng ODF export is useful,
    but the test code no longer built as the used SfxMedium ctor is gone.
    
    We don't really need a full SfxMedium, a simple SvFileStream is enough.
    
    Change-Id: I9b8cead4b7ebd6d4c9461cdecf357c84e623d856
    Reviewed-on: https://gerrit.libreoffice.org/49806
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit e20164ad9f2b3125c8ecdb5f19feee4a654e24f2)

diff --git a/editeng/source/xml/xmltxtexp.cxx b/editeng/source/xml/xmltxtexp.cxx
index 1ada3a700339..083d23626bd8 100644
--- a/editeng/source/xml/xmltxtexp.cxx
+++ b/editeng/source/xml/xmltxtexp.cxx
@@ -312,8 +312,8 @@ void SvxWriteXML( EditEngine& rEditEngine, SvStream& rStream, const ESelection&
 
 /* testcode
             const OUString aURL( "file:///e:/test.xml" );
-            SfxMedium aMedium( aURL, StreamMode::WRITE | StreamMode::TRUNC, sal_True );
-            uno::Reference<io::XOutputStream> xOut( new utl::OOutputStreamWrapper( *aMedium.GetOutStream() ) );
+            SvFileStream aStream(aURL, StreamMode::WRITE | StreamMode::TRUNC);
+            xOut = new utl::OOutputStreamWrapper(aStream);
 */
 
 
@@ -329,7 +329,7 @@ void SvxWriteXML( EditEngine& rEditEngine, SvStream& rStream, const ESelection&
             xExporter->exportDoc();
 
 /* testcode
-            aMedium.Commit();
+            aStream.Close();
 */
 
         }
commit 984c9e6ff7a0e3afb06fd4ad1f77d75b7b50d7ef
Author: Tor Lillqvist <tml at collabora.com>
Date:   Thu Feb 15 15:43:28 2018 +0200

    Do what the TODO said
    
    Change-Id: I6358b550482188c6fdaf0cd01af353850d12138b
    (cherry picked from commit 032c49b98635f3cc787d90cb744fcc212405a833)

diff --git a/include/comphelper/windowsdebugoutput.hxx b/include/comphelper/windowsdebugoutput.hxx
index 4e396db92715..28eaab810ff2 100644
--- a/include/comphelper/windowsdebugoutput.hxx
+++ b/include/comphelper/windowsdebugoutput.hxx
@@ -19,6 +19,7 @@
 #include <iomanip>
 #include <ostream>
 #include <string>
+#include <vector>
 
 #ifdef LIBO_INTERNAL_ONLY
 #include <prewin.h>
@@ -35,11 +36,41 @@ inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, t
     if (StringFromIID(rIid, &pRiid) != S_OK)
         return stream << "?";
 
-    // TODO: Maybe look up a descriptive name for the service or interface, from HKCR\CLSID or
-    // HKCR\Interface?
-
     stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
         std::wstring(pRiid));
+
+    DWORD nSize;
+    if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"CLSID\\").append(pRiid).data(), NULL,
+                     RRF_RT_REG_SZ, NULL, NULL, &nSize)
+        == ERROR_SUCCESS)
+    {
+        std::vector<wchar_t> sValue(nSize / 2);
+        if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"CLSID\\").append(pRiid).data(), NULL,
+                         RRF_RT_REG_SZ, NULL, sValue.data(), &nSize)
+            == ERROR_SUCCESS)
+        {
+            stream << "=\""
+                   << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
+                          std::wstring(sValue.data()))
+                   << "\"";
+        }
+    }
+    else if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"Interface\\").append(pRiid).data(),
+                          NULL, RRF_RT_REG_SZ, NULL, NULL, &nSize)
+             == ERROR_SUCCESS)
+    {
+        std::vector<wchar_t> sValue(nSize / 2);
+        if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"Interface\\").append(pRiid).data(), NULL,
+                         RRF_RT_REG_SZ, NULL, sValue.data(), &nSize)
+            == ERROR_SUCCESS)
+        {
+            stream << "=\""
+                   << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
+                          std::wstring(sValue.data()))
+                   << "\"";
+        }
+    }
+
     CoTaskMemFree(pRiid);
     return stream;
 }
commit 5f18b82dc4fb933e3af53809741ef7f739f23ff5
Author: Tor Lillqvist <tml at collabora.com>
Date:   Thu Feb 15 14:17:20 2018 +0200

    Apply clang-format
    
    Change-Id: I089cdb8c770df5e8c99d55870061a18645b2cd05
    (cherry picked from commit 1647bfa019124aefd34d8ad231d19399e93a6096)

diff --git a/include/comphelper/windowsdebugoutput.hxx b/include/comphelper/windowsdebugoutput.hxx
index 594afc7280d3..4e396db92715 100644
--- a/include/comphelper/windowsdebugoutput.hxx
+++ b/include/comphelper/windowsdebugoutput.hxx
@@ -38,7 +38,8 @@ inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, t
     // TODO: Maybe look up a descriptive name for the service or interface, from HKCR\CLSID or
     // HKCR\Interface?
 
-    stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(std::wstring(pRiid));
+    stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
+        std::wstring(pRiid));
     CoTaskMemFree(pRiid);
     return stream;
 }
@@ -56,52 +57,144 @@ inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, t
 
     switch (rVariant.vt)
     {
-    case VT_EMPTY: stream << "EMPTY"; break;
-    case VT_NULL: stream << "NULL"; break;
-    case VT_I2: stream << "I2"; break;
-    case VT_I4: stream << "I4"; break;
-    case VT_R4: stream << "R4"; break;
-    case VT_R8: stream << "R8"; break;
-    case VT_CY: stream << "CY"; break;
-    case VT_DATE: stream << "DATE"; break;
-    case VT_BSTR: stream << "BSTR"; break;
-    case VT_DISPATCH: stream << "DISPATCH"; break;
-    case VT_ERROR: stream << "ERROR"; break;
-    case VT_BOOL: stream << "BOOL"; break;
-    case VT_VARIANT: stream << "VARIANT"; break;
-    case VT_UNKNOWN: stream << "UNKNOWN"; break;
-    case VT_DECIMAL: stream << "DECIMAL"; break;
-    case VT_I1: stream << "I1"; break;
-    case VT_UI1: stream << "UI1"; break;
-    case VT_UI2: stream << "UI2"; break;
-    case VT_UI4: stream << "UI4"; break;
-    case VT_I8: stream << "I8"; break;
-    case VT_UI8: stream << "UI8"; break;
-    case VT_INT: stream << "INT"; break;
-    case VT_UINT: stream << "UINT"; break;
-    case VT_VOID: stream << "VOID"; break;
-    case VT_HRESULT: stream << "HRESULT"; break;
-    case VT_PTR: stream << "PTR"; break;
-    case VT_SAFEARRAY: stream << "SAFEARRAY"; break;
-    case VT_CARRAY: stream << "CARRAY"; break;
-    case VT_USERDEFINED: stream << "USERDEFINED"; break;
-    case VT_LPSTR: stream << "LPSTR"; break;
-    case VT_LPWSTR: stream << "LPWSTR"; break;
-    case VT_RECORD: stream << "RECORD"; break;
-    case VT_INT_PTR: stream << "INT_PTR"; break;
-    case VT_UINT_PTR: stream << "UINT_PTR"; break;
-    case VT_FILETIME: stream << "FILETIME"; break;
-    case VT_BLOB: stream << "BLOB"; break;
-    case VT_STREAM: stream << "STREAM"; break;
-    case VT_STORAGE: stream << "STORAGE"; break;
-    case VT_STREAMED_OBJECT: stream << "STREAMED_OBJECT"; break;
-    case VT_STORED_OBJECT: stream << "STORED_OBJECT"; break;
-    case VT_BLOB_OBJECT: stream << "BLOB_OBJECT"; break;
-    case VT_CF: stream << "CF"; break;
-    case VT_CLSID: stream << "CLSID"; break;
-    case VT_VERSIONED_STREAM: stream << "VERSIONED_STREAM"; break;
-    case VT_BSTR_BLOB: stream << "BSTR_BLOB"; break;
-    default: stream << rVariant.vt; break;
+        case VT_EMPTY:
+            stream << "EMPTY";
+            break;
+        case VT_NULL:
+            stream << "NULL";
+            break;
+        case VT_I2:
+            stream << "I2";
+            break;
+        case VT_I4:
+            stream << "I4";
+            break;
+        case VT_R4:
+            stream << "R4";
+            break;
+        case VT_R8:
+            stream << "R8";
+            break;
+        case VT_CY:
+            stream << "CY";
+            break;
+        case VT_DATE:
+            stream << "DATE";
+            break;
+        case VT_BSTR:
+            stream << "BSTR";
+            break;
+        case VT_DISPATCH:
+            stream << "DISPATCH";
+            break;
+        case VT_ERROR:
+            stream << "ERROR";
+            break;
+        case VT_BOOL:
+            stream << "BOOL";
+            break;
+        case VT_VARIANT:
+            stream << "VARIANT";
+            break;
+        case VT_UNKNOWN:
+            stream << "UNKNOWN";
+            break;
+        case VT_DECIMAL:
+            stream << "DECIMAL";
+            break;
+        case VT_I1:
+            stream << "I1";
+            break;
+        case VT_UI1:
+            stream << "UI1";
+            break;
+        case VT_UI2:
+            stream << "UI2";
+            break;
+        case VT_UI4:
+            stream << "UI4";
+            break;
+        case VT_I8:
+            stream << "I8";
+            break;
+        case VT_UI8:
+            stream << "UI8";
+            break;
+        case VT_INT:
+            stream << "INT";
+            break;
+        case VT_UINT:
+            stream << "UINT";
+            break;
+        case VT_VOID:
+            stream << "VOID";
+            break;
+        case VT_HRESULT:
+            stream << "HRESULT";
+            break;
+        case VT_PTR:
+            stream << "PTR";
+            break;
+        case VT_SAFEARRAY:
+            stream << "SAFEARRAY";
+            break;
+        case VT_CARRAY:
+            stream << "CARRAY";
+            break;
+        case VT_USERDEFINED:
+            stream << "USERDEFINED";
+            break;
+        case VT_LPSTR:
+            stream << "LPSTR";
+            break;
+        case VT_LPWSTR:
+            stream << "LPWSTR";
+            break;
+        case VT_RECORD:
+            stream << "RECORD";
+            break;
+        case VT_INT_PTR:
+            stream << "INT_PTR";
+            break;
+        case VT_UINT_PTR:
+            stream << "UINT_PTR";
+            break;
+        case VT_FILETIME:
+            stream << "FILETIME";
+            break;
+        case VT_BLOB:
+            stream << "BLOB";
+            break;
+        case VT_STREAM:
+            stream << "STREAM";
+            break;
+        case VT_STORAGE:
+            stream << "STORAGE";
+            break;
+        case VT_STREAMED_OBJECT:
+            stream << "STREAMED_OBJECT";
+            break;
+        case VT_STORED_OBJECT:
+            stream << "STORED_OBJECT";
+            break;
+        case VT_BLOB_OBJECT:
+            stream << "BLOB_OBJECT";
+            break;
+        case VT_CF:
+            stream << "CF";
+            break;
+        case VT_CLSID:
+            stream << "CLSID";
+            break;
+        case VT_VERSIONED_STREAM:
+            stream << "VERSIONED_STREAM";
+            break;
+        case VT_BSTR_BLOB:
+            stream << "BSTR_BLOB";
+            break;
+        default:
+            stream << rVariant.vt;
+            break;
     }
     if (rVariant.vt == VT_EMPTY || rVariant.vt == VT_NULL || rVariant.vt == VT_VOID)
         return stream;
@@ -116,124 +209,246 @@ inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, t
         stream << rVariant.byref << ":";
         if (rVariant.byref == nullptr)
             return stream;
-        if ((rVariant.vt & VT_TYPEMASK) == VT_VOID ||
-            (rVariant.vt & VT_TYPEMASK) == VT_USERDEFINED)
+        if ((rVariant.vt & VT_TYPEMASK) == VT_VOID || (rVariant.vt & VT_TYPEMASK) == VT_USERDEFINED)
             return stream;
         stream << ":";
         switch (rVariant.vt & VT_TYPEMASK)
         {
-        case VT_I2: stream << *(short*)rVariant.byref; break;
-        case VT_I4: stream << *(int*)rVariant.byref; break;
-        case VT_R4: stream << *(float*)rVariant.byref; break;
-        case VT_R8: stream << *(double*)rVariant.byref; break;
-        case VT_CY: stream << ((CY*)rVariant.byref)->int64; break;
-        case VT_DATE: stream << *(double*)rVariant.byref; break; // FIXME
-        case VT_BSTR: stream << (OLECHAR*)rVariant.byref; break;
-        case VT_DISPATCH: stream << rVariant.byref; break;
+            case VT_I2:
+                stream << *(short*)rVariant.byref;
+                break;
+            case VT_I4:
+                stream << *(int*)rVariant.byref;
+                break;
+            case VT_R4:
+                stream << *(float*)rVariant.byref;
+                break;
+            case VT_R8:
+                stream << *(double*)rVariant.byref;
+                break;
+            case VT_CY:
+                stream << ((CY*)rVariant.byref)->int64;
+                break;
+            case VT_DATE:
+                stream << *(double*)rVariant.byref;
+                break; // FIXME
+            case VT_BSTR:
+                stream << (OLECHAR*)rVariant.byref;
+                break;
+            case VT_DISPATCH:
+                stream << rVariant.byref;
+                break;
+            case VT_ERROR:
+            case VT_HRESULT:
+                flags = stream.flags();
+                stream << std::hex << *(int*)rVariant.byref;
+                stream.setf(flags);
+                break;
+            case VT_BOOL:
+                stream << (*(VARIANT_BOOL*)rVariant.byref ? "YES" : "NO");
+                break;
+            case VT_VARIANT:
+                stream << *(VARIANT*)rVariant.byref;
+                break;
+            case VT_UNKNOWN:
+                stream << *(IUnknown**)rVariant.byref;
+                break;
+            case VT_DECIMAL:
+                flags = stream.flags();
+                width = stream.width();
+                fill = stream.fill();
+                stream << std::hex << std::setw(8) << std::setfill('0')
+                       << ((DECIMAL*)rVariant.byref)->Hi32;
+                stream << std::setw(16) << ((DECIMAL*)rVariant.byref)->Lo64;
+                stream.setf(flags);
+                stream << std::setw(width) << std::setfill(fill);
+                break;
+            case VT_I1:
+                stream << (int)*(char*)rVariant.byref;
+                break;
+            case VT_UI1:
+                stream << (unsigned int)*(unsigned char*)rVariant.byref;
+                break;
+            case VT_UI2:
+                stream << *(unsigned short*)rVariant.byref;
+                break;
+            case VT_UI4:
+                stream << *(unsigned int*)rVariant.byref;
+                break;
+            case VT_I8:
+                stream << *(long long*)rVariant.byref;
+                break;
+            case VT_UI8:
+                stream << *(unsigned long long*)rVariant.byref;
+                break;
+            case VT_INT:
+                stream << *(int*)rVariant.byref;
+                break;
+            case VT_UINT:
+                stream << *(unsigned int*)rVariant.byref;
+                break;
+            case VT_INT_PTR:
+                stream << *(intptr_t*)rVariant.byref;
+                break;
+            case VT_UINT_PTR:
+                stream << *(uintptr_t*)rVariant.byref;
+                break;
+            case VT_PTR:
+            case VT_CARRAY:
+                stream << *(void**)rVariant.byref;
+                break;
+            case VT_SAFEARRAY:
+                break; // FIXME
+            case VT_LPSTR:
+                stream << *(char**)rVariant.byref;
+                break;
+            case VT_LPWSTR:
+                stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
+                    std::wstring(*(wchar_t**)rVariant.byref));
+                break;
+            case VT_FILETIME:
+                break; // FIXME
+            case VT_BLOB:
+                break; // FIXME
+            case VT_STREAM:
+                break; // FIXME
+            case VT_STORAGE:
+                break; // FIXME
+            case VT_STREAMED_OBJECT:
+                break; // FIXME
+            case VT_STORED_OBJECT:
+                break; // FIXME
+            case VT_BLOB_OBJECT:
+                break; // FIXME
+            case VT_CF:
+                break; // FIXME
+            case VT_CLSID:
+                stream << *(IID*)rVariant.byref;
+                break;
+            case VT_VERSIONED_STREAM:
+                break; // FIXME
+            case VT_BSTR_BLOB:
+                break; // FIXME
+            default:
+                stream << "?(" << (rVariant.vt & VT_TYPEMASK) << ")";
+                break;
+        }
+        return stream;
+    }
+
+    switch (rVariant.vt & VT_TYPEMASK)
+    {
+        case VT_I2:
+            stream << rVariant.iVal;
+            break;
+        case VT_I4:
+            stream << rVariant.lVal;
+            break;
+        case VT_R4:
+            stream << rVariant.fltVal;
+            break;
+        case VT_R8:
+            stream << rVariant.dblVal;
+            break;
+        case VT_CY:
+            stream << rVariant.cyVal.int64;
+            break;
+        case VT_DATE:
+            stream << (double)rVariant.date;
+            break; // FIXME
+        case VT_BSTR:
+            stream << rVariant.bstrVal;
+            break;
+        case VT_DISPATCH:
+            stream << rVariant.pdispVal;
+            break;
         case VT_ERROR:
         case VT_HRESULT:
             flags = stream.flags();
-            stream << std::hex << *(int*)rVariant.byref;
+            stream << std::hex << rVariant.lVal;
             stream.setf(flags);
             break;
-        case VT_BOOL: stream << (*(VARIANT_BOOL*)rVariant.byref?"YES":"NO"); break;
-        case VT_VARIANT: stream << *(VARIANT*)rVariant.byref; break;
-        case VT_UNKNOWN: stream << *(IUnknown**)rVariant.byref; break;
+        case VT_BOOL:
+            stream << (rVariant.boolVal ? "YES" : "NO");
+            break;
+        case VT_UNKNOWN:
+            stream << rVariant.punkVal;
+            break;
         case VT_DECIMAL:
             flags = stream.flags();
             width = stream.width();
             fill = stream.fill();
-            stream << std::hex << std::setw(8) << std::setfill('0') << ((DECIMAL*)rVariant.byref)->Hi32;
-            stream << std::setw(16) << ((DECIMAL*)rVariant.byref)->Lo64;
+            stream << std::hex << std::setw(8) << std::setfill('0') << rVariant.decVal.Hi32;
+            stream << std::setw(16) << rVariant.decVal.Lo64;
             stream.setf(flags);
             stream << std::setw(width) << std::setfill(fill);
             break;
-        case VT_I1: stream << (int)*(char*)rVariant.byref; break;
-        case VT_UI1: stream << (unsigned int)*(unsigned char*)rVariant.byref; break;
-        case VT_UI2: stream << *(unsigned short*)rVariant.byref; break;
-        case VT_UI4: stream << *(unsigned int*)rVariant.byref; break;
-        case VT_I8: stream << *(long long*)rVariant.byref; break;
-        case VT_UI8: stream << *(unsigned long long*)rVariant.byref; break;
-        case VT_INT: stream << *(int*)rVariant.byref; break;
-        case VT_UINT: stream << *(unsigned int*)rVariant.byref; break;
-        case VT_INT_PTR: stream << *(intptr_t*)rVariant.byref; break;
-        case VT_UINT_PTR: stream << *(uintptr_t*)rVariant.byref; break;
+        case VT_I1:
+            stream << (int)rVariant.bVal;
+            break;
+        case VT_UI1:
+            stream << (unsigned int)rVariant.bVal;
+            break;
+        case VT_UI2:
+            stream << (unsigned short)rVariant.iVal;
+            break;
+        case VT_UI4:
+            stream << (unsigned int)rVariant.lVal;
+            break;
+        case VT_I8:
+            stream << rVariant.llVal;
+            break;
+        case VT_UI8:
+            stream << (unsigned long long)rVariant.llVal;
+            break;
+        case VT_INT:
+            stream << rVariant.lVal;
+            break;
+        case VT_UINT:
+            stream << (unsigned int)rVariant.lVal;
+            break;
+        case VT_INT_PTR:
+            stream << (intptr_t)rVariant.plVal;
+            break;
+        case VT_UINT_PTR:
+            stream << (uintptr_t)rVariant.plVal;
+            break;
         case VT_PTR:
         case VT_CARRAY:
-            stream << *(void**)rVariant.byref; break;
-        case VT_SAFEARRAY: break; // FIXME
-        case VT_LPSTR: stream << *(char**)rVariant.byref; break;
-        case VT_LPWSTR: stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(std::wstring(*(wchar_t**)rVariant.byref)); break;
-        case VT_FILETIME: break; // FIXME
-        case VT_BLOB: break; // FIXME
-        case VT_STREAM: break; // FIXME
-        case VT_STORAGE: break; // FIXME
-        case VT_STREAMED_OBJECT: break; // FIXME
-        case VT_STORED_OBJECT: break; // FIXME
-        case VT_BLOB_OBJECT: break; // FIXME
-        case VT_CF: break; // FIXME
-        case VT_CLSID: stream << *(IID*)rVariant.byref; break;
-        case VT_VERSIONED_STREAM: break; // FIXME
-        case VT_BSTR_BLOB: break; // FIXME
-        default: stream << "?(" << (rVariant.vt & VT_TYPEMASK) << ")"; break;
-        }
-        return stream;
-    }
-
-    switch (rVariant.vt & VT_TYPEMASK)
-    {
-    case VT_I2: stream << rVariant.iVal; break;
-    case VT_I4: stream << rVariant.lVal; break;
-    case VT_R4: stream << rVariant.fltVal; break;
-    case VT_R8: stream << rVariant.dblVal; break;
-    case VT_CY: stream << rVariant.cyVal.int64; break;
-    case VT_DATE: stream << (double)rVariant.date; break; // FIXME
-    case VT_BSTR: stream << rVariant.bstrVal; break;
-    case VT_DISPATCH: stream << rVariant.pdispVal; break;
-    case VT_ERROR:
-    case VT_HRESULT:
-        flags = stream.flags();
-        stream << std::hex << rVariant.lVal;
-        stream.setf(flags);
-        break;
-    case VT_BOOL: stream << (rVariant.boolVal?"YES":"NO"); break;
-    case VT_UNKNOWN: stream << rVariant.punkVal; break;
-    case VT_DECIMAL:
-        flags = stream.flags();
-        width = stream.width();
-        fill = stream.fill();
-        stream << std::hex << std::setw(8) << std::setfill('0') << rVariant.decVal.Hi32;
-        stream << std::setw(16) << rVariant.decVal.Lo64;
-        stream.setf(flags);
-        stream << std::setw(width) << std::setfill(fill);
-        break;
-    case VT_I1: stream << (int)rVariant.bVal; break;
-    case VT_UI1: stream << (unsigned int)rVariant.bVal; break;
-    case VT_UI2: stream << (unsigned short)rVariant.iVal; break;
-    case VT_UI4: stream << (unsigned int)rVariant.lVal; break;
-    case VT_I8: stream << rVariant.llVal; break;
-    case VT_UI8: stream << (unsigned long long)rVariant.llVal; break;
-    case VT_INT: stream << rVariant.lVal; break;
-    case VT_UINT: stream << (unsigned int)rVariant.lVal; break;
-    case VT_INT_PTR: stream << (intptr_t)rVariant.plVal; break;
-    case VT_UINT_PTR: stream << (uintptr_t)rVariant.plVal; break;
-    case VT_PTR:
-    case VT_CARRAY:
-        stream << rVariant.byref; break;
-    case VT_SAFEARRAY: break; // FIXME
-    case VT_LPSTR: stream << rVariant.bstrVal; break;
-    case VT_LPWSTR: stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(std::wstring((wchar_t*)rVariant.byref)); break;
-    case VT_FILETIME: break; // FIXME
-    case VT_BLOB: break; // FIXME
-    case VT_STREAM: break; // FIXME
-    case VT_STORAGE: break; // FIXME
-    case VT_STREAMED_OBJECT: break; // FIXME
-    case VT_STORED_OBJECT: break; // FIXME
-    case VT_BLOB_OBJECT: break; // FIXME
-    case VT_CF: break; // FIXME
-    case VT_VERSIONED_STREAM: break; // FIXME
-    case VT_BSTR_BLOB: break; // FIXME
-    default: stream << "?(" << (rVariant.vt & VT_TYPEMASK) << ")"; break;
+            stream << rVariant.byref;
+            break;
+        case VT_SAFEARRAY:
+            break; // FIXME
+        case VT_LPSTR:
+            stream << rVariant.bstrVal;
+            break;
+        case VT_LPWSTR:
+            stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
+                std::wstring((wchar_t*)rVariant.byref));
+            break;
+        case VT_FILETIME:
+            break; // FIXME
+        case VT_BLOB:
+            break; // FIXME
+        case VT_STREAM:
+            break; // FIXME
+        case VT_STORAGE:
+            break; // FIXME
+        case VT_STREAMED_OBJECT:
+            break; // FIXME
+        case VT_STORED_OBJECT:
+            break; // FIXME
+        case VT_BLOB_OBJECT:
+            break; // FIXME
+        case VT_CF:
+            break; // FIXME
+        case VT_VERSIONED_STREAM:
+            break; // FIXME
+        case VT_BSTR_BLOB:
+            break; // FIXME
+        default:
+            stream << "?(" << (rVariant.vt & VT_TYPEMASK) << ")";
+            break;
     }
     return stream;
 }
commit 63d644e8bbc9d3ceffb8c374ff409295892a6941
Author: Tor Lillqvist <tml at collabora.com>
Date:   Thu Feb 15 14:14:02 2018 +0200

    Add debug output operator for VARIANT
    
    Change-Id: I3994f0444b2f415e55645f890a84e42e66512d03
    (cherry picked from commit d1416444e5622132b30e4a90fcad8b8eaca09399)

diff --git a/include/comphelper/windowsdebugoutput.hxx b/include/comphelper/windowsdebugoutput.hxx
index 53719899b0bc..594afc7280d3 100644
--- a/include/comphelper/windowsdebugoutput.hxx
+++ b/include/comphelper/windowsdebugoutput.hxx
@@ -16,6 +16,7 @@
 #define INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX
 
 #include <codecvt>
+#include <iomanip>
 #include <ostream>
 #include <string>
 
@@ -42,6 +43,201 @@ inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, t
     return stream;
 }
 
+template <typename charT, typename traits>
+inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
+                                                     const VARIANT& rVariant)
+{
+    if (rVariant.vt & VT_VECTOR)
+        stream << "VECTOR:";
+    if (rVariant.vt & VT_ARRAY)
+        stream << "ARRAY:";
+    if (rVariant.vt & VT_BYREF)
+        stream << "BYREF:";
+
+    switch (rVariant.vt)
+    {
+    case VT_EMPTY: stream << "EMPTY"; break;
+    case VT_NULL: stream << "NULL"; break;
+    case VT_I2: stream << "I2"; break;
+    case VT_I4: stream << "I4"; break;
+    case VT_R4: stream << "R4"; break;
+    case VT_R8: stream << "R8"; break;
+    case VT_CY: stream << "CY"; break;
+    case VT_DATE: stream << "DATE"; break;
+    case VT_BSTR: stream << "BSTR"; break;
+    case VT_DISPATCH: stream << "DISPATCH"; break;
+    case VT_ERROR: stream << "ERROR"; break;
+    case VT_BOOL: stream << "BOOL"; break;
+    case VT_VARIANT: stream << "VARIANT"; break;
+    case VT_UNKNOWN: stream << "UNKNOWN"; break;
+    case VT_DECIMAL: stream << "DECIMAL"; break;
+    case VT_I1: stream << "I1"; break;
+    case VT_UI1: stream << "UI1"; break;
+    case VT_UI2: stream << "UI2"; break;
+    case VT_UI4: stream << "UI4"; break;
+    case VT_I8: stream << "I8"; break;
+    case VT_UI8: stream << "UI8"; break;
+    case VT_INT: stream << "INT"; break;
+    case VT_UINT: stream << "UINT"; break;
+    case VT_VOID: stream << "VOID"; break;
+    case VT_HRESULT: stream << "HRESULT"; break;
+    case VT_PTR: stream << "PTR"; break;
+    case VT_SAFEARRAY: stream << "SAFEARRAY"; break;
+    case VT_CARRAY: stream << "CARRAY"; break;
+    case VT_USERDEFINED: stream << "USERDEFINED"; break;
+    case VT_LPSTR: stream << "LPSTR"; break;
+    case VT_LPWSTR: stream << "LPWSTR"; break;
+    case VT_RECORD: stream << "RECORD"; break;
+    case VT_INT_PTR: stream << "INT_PTR"; break;
+    case VT_UINT_PTR: stream << "UINT_PTR"; break;
+    case VT_FILETIME: stream << "FILETIME"; break;
+    case VT_BLOB: stream << "BLOB"; break;
+    case VT_STREAM: stream << "STREAM"; break;
+    case VT_STORAGE: stream << "STORAGE"; break;
+    case VT_STREAMED_OBJECT: stream << "STREAMED_OBJECT"; break;
+    case VT_STORED_OBJECT: stream << "STORED_OBJECT"; break;
+    case VT_BLOB_OBJECT: stream << "BLOB_OBJECT"; break;
+    case VT_CF: stream << "CF"; break;
+    case VT_CLSID: stream << "CLSID"; break;
+    case VT_VERSIONED_STREAM: stream << "VERSIONED_STREAM"; break;
+    case VT_BSTR_BLOB: stream << "BSTR_BLOB"; break;
+    default: stream << rVariant.vt; break;
+    }
+    if (rVariant.vt == VT_EMPTY || rVariant.vt == VT_NULL || rVariant.vt == VT_VOID)
+        return stream;
+    stream << ":";
+
+    std::ios_base::fmtflags flags;
+    std::streamsize width;
+    charT fill;
+
+    if (rVariant.vt & VT_BYREF)
+    {
+        stream << rVariant.byref << ":";
+        if (rVariant.byref == nullptr)
+            return stream;
+        if ((rVariant.vt & VT_TYPEMASK) == VT_VOID ||
+            (rVariant.vt & VT_TYPEMASK) == VT_USERDEFINED)
+            return stream;
+        stream << ":";
+        switch (rVariant.vt & VT_TYPEMASK)
+        {
+        case VT_I2: stream << *(short*)rVariant.byref; break;
+        case VT_I4: stream << *(int*)rVariant.byref; break;
+        case VT_R4: stream << *(float*)rVariant.byref; break;
+        case VT_R8: stream << *(double*)rVariant.byref; break;
+        case VT_CY: stream << ((CY*)rVariant.byref)->int64; break;
+        case VT_DATE: stream << *(double*)rVariant.byref; break; // FIXME
+        case VT_BSTR: stream << (OLECHAR*)rVariant.byref; break;
+        case VT_DISPATCH: stream << rVariant.byref; break;
+        case VT_ERROR:
+        case VT_HRESULT:
+            flags = stream.flags();
+            stream << std::hex << *(int*)rVariant.byref;
+            stream.setf(flags);
+            break;
+        case VT_BOOL: stream << (*(VARIANT_BOOL*)rVariant.byref?"YES":"NO"); break;
+        case VT_VARIANT: stream << *(VARIANT*)rVariant.byref; break;
+        case VT_UNKNOWN: stream << *(IUnknown**)rVariant.byref; break;
+        case VT_DECIMAL:
+            flags = stream.flags();
+            width = stream.width();
+            fill = stream.fill();
+            stream << std::hex << std::setw(8) << std::setfill('0') << ((DECIMAL*)rVariant.byref)->Hi32;
+            stream << std::setw(16) << ((DECIMAL*)rVariant.byref)->Lo64;
+            stream.setf(flags);
+            stream << std::setw(width) << std::setfill(fill);
+            break;
+        case VT_I1: stream << (int)*(char*)rVariant.byref; break;
+        case VT_UI1: stream << (unsigned int)*(unsigned char*)rVariant.byref; break;
+        case VT_UI2: stream << *(unsigned short*)rVariant.byref; break;
+        case VT_UI4: stream << *(unsigned int*)rVariant.byref; break;
+        case VT_I8: stream << *(long long*)rVariant.byref; break;
+        case VT_UI8: stream << *(unsigned long long*)rVariant.byref; break;
+        case VT_INT: stream << *(int*)rVariant.byref; break;
+        case VT_UINT: stream << *(unsigned int*)rVariant.byref; break;
+        case VT_INT_PTR: stream << *(intptr_t*)rVariant.byref; break;
+        case VT_UINT_PTR: stream << *(uintptr_t*)rVariant.byref; break;
+        case VT_PTR:
+        case VT_CARRAY:
+            stream << *(void**)rVariant.byref; break;
+        case VT_SAFEARRAY: break; // FIXME

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list