[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-4.2' - 14 commits - cui/source drawinglayer/source editeng/source extensions/source filter/CppunitTest_filter_xslt.mk filter/Module_filter.mk filter/qa filter/source include/svtools include/xmloff offapi/com sc/inc sc/source svtools/source sw/qa sw/source vcl/source vcl/unx xmloff/source

Eike Rathke erack at redhat.com
Thu Mar 6 23:36:58 PST 2014


 cui/source/inc/border.hxx                                 |    2 
 cui/source/tabpages/border.cxx                            |   73 +-
 drawinglayer/source/primitive2d/borderlineprimitive2d.cxx |  120 ++--
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx   |    4 
 editeng/source/items/borderline.cxx                       |    5 
 editeng/source/items/frmitems.cxx                         |    2 
 extensions/source/propctrlr/browserlistbox.cxx            |    9 
 filter/CppunitTest_filter_xslt.mk                         |   45 +
 filter/Module_filter.mk                                   |    4 
 filter/qa/cppunit/data/xslt/copy.xslt                     |    9 
 filter/qa/cppunit/xslt-test.cxx                           |  193 +++++++
 filter/source/xsltfilter/LibXSLTTransformer.cxx           |    5 
 include/svtools/ctrlbox.hxx                               |    9 
 include/xmloff/xmltoken.hxx                               |    1 
 offapi/com/sun/star/table/BorderLineStyle.idl             |   10 
 sc/inc/formulagroup.hxx                                   |    7 
 sc/inc/stlalgorithm.hxx                                   |   81 +++
 sc/source/core/data/formulacell.cxx                       |   44 -
 sc/source/core/data/validat.cxx                           |   12 
 sc/source/core/tool/formulagroup.cxx                      |    4 
 sc/source/filter/excel/xistyle.cxx                        |    2 
 sc/source/filter/html/htmlexp.cxx                         |    1 
 sc/source/filter/lotus/lotattr.cxx                        |    2 
 sc/source/filter/oox/stylesbuffer.cxx                     |    4 
 svtools/source/control/ctrlbox.cxx                        |    9 
 sw/qa/extras/ww8import/data/bnc821208.doc                 |binary
 sw/qa/extras/ww8import/ww8import.cxx                      |    9 
 sw/source/core/layout/paintfrm.cxx                        |  369 ++++++++------
 sw/source/filter/ww8/ww8par2.cxx                          |    5 
 vcl/source/window/splitwin.cxx                            |   63 +-
 vcl/unx/kde4/KDE4FilePicker.cxx                           |    9 
 vcl/unx/kde4/KDE4FilePicker.hxx                           |    5 
 vcl/unx/kde4/KDEData.cxx                                  |   17 
 vcl/unx/kde4/KDESalGraphics.cxx                           |   12 
 vcl/unx/kde4/KDEXLib.cxx                                  |   17 
 vcl/unx/kde4/KDEXLib.hxx                                  |    2 
 xmloff/source/core/xmltoken.cxx                           |    1 
 xmloff/source/style/bordrhdl.cxx                          |   46 -
 38 files changed, 880 insertions(+), 332 deletions(-)

New commits:
commit 0d3af365585c90d64d1fcceca31f52626a0521c6
Author: Eike Rathke <erack at redhat.com>
Date:   Thu Mar 6 01:23:37 2014 +0100

    resolved fdo#61520 do not add multiple empty strings to the validation list
    
    Change-Id: I4f6180b2f8c914a965965ca362e1670e8b434d37
    (cherry picked from commit 7122ef19847b26529ed1d5bad40df869e91a8495)
    Reviewed-on: https://gerrit.libreoffice.org/8469
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    Tested-by: Kohei Yoshida <libreoffice at kohei.us>

diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index b7e51ba..cbd3a94 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -713,6 +713,8 @@ bool ScValidationData::GetSelectionFromFormula(
         }
     }
 
+    bool bHaveEmpty = false;
+
     /* XL artificially limits things to a single col or row in the UI but does
      * not list the constraint in MOOXml. If a defined name or INDIRECT
      * resulting in 1D is entered in the UI and the definition later modified
@@ -733,6 +735,16 @@ bool ScValidationData::GetSelectionFromFormula(
             {
                 aValStr = nMatVal.GetString().getString();
 
+                // Do not add multiple empty strings to the validation list,
+                // especially not if they'd bloat the tail with a million empty
+                // entries for a column range, fdo#61520
+                if (aValStr.isEmpty())
+                {
+                    if (bHaveEmpty)
+                        continue;
+                    bHaveEmpty = true;
+                }
+
                 if( NULL != pStrings )
                     pEntry = new ScTypedStrData( aValStr, 0.0, ScTypedStrData::Standard);
 
commit 59a86772ce61bdd12c3920e18fe24c71dbaf4536
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Mar 5 18:47:07 2014 -0500

    Fix incorrect group calc state check.
    
    And the code in the else block is pretty dangerous as it passes an empty
    token array to the group interpreter whose effect is entirely unpredictable.
    
    Also, declare the destructor of CompiledFormula class to be virtual as it
    serves as a base class for DynamicKernel.
    
    Change-Id: I4e191550a4437ad6ebac55fcdeee4f3654722ff1
    (cherry picked from commit 95637452609260c97d8e5aaa7500531bb458a8bc)
    Reviewed-on: https://gerrit.libreoffice.org/8468
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 602c4a4..a3f1891 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -81,6 +81,9 @@ struct FormulaGroupContext : boost::noncopyable
  */
 class SC_DLLPUBLIC CompiledFormula
 {
+public:
+    CompiledFormula();
+    virtual ~CompiledFormula();
 };
 
 /**
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index d733525..71d55f7 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3678,38 +3678,26 @@ bool ScFormulaCell::InterpretFormulaGroup()
     if (mxGroup->mbInvariant && false)
         return InterpretInvariantFormulaGroup();
 
-    if (mxGroup->meCalcState == sc::GroupCalcEnabled)
-    {
-        ScTokenArray aCode;
-        ScAddress aTopPos = aPos;
-        aTopPos.SetRow(mxGroup->mpTopCell->aPos.Row());
-        ScGroupTokenConverter aConverter(aCode, *pDocument, *this, mxGroup->mpTopCell->aPos);
-        if (!aConverter.convert(*pCode))
-        {
-            SAL_INFO("sc.opencl", "conversion of group " << this << " failed, disabling");
-            mxGroup->meCalcState = sc::GroupCalcDisabled;
-            return false;
-        }
-        mxGroup->meCalcState = sc::GroupCalcRunning;
-        if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, mxGroup->mpTopCell->aPos, mxGroup, aCode))
-        {
-            SAL_INFO("sc.opencl", "interpreting group " << mxGroup << " (state " << mxGroup->meCalcState << ") failed, disabling");
-            mxGroup->meCalcState = sc::GroupCalcDisabled;
-            return false;
-        }
-        mxGroup->meCalcState = sc::GroupCalcEnabled;
+    ScTokenArray aCode;
+    ScAddress aTopPos = aPos;
+    aTopPos.SetRow(mxGroup->mpTopCell->aPos.Row());
+    ScGroupTokenConverter aConverter(aCode, *pDocument, *this, mxGroup->mpTopCell->aPos);
+    if (!aConverter.convert(*pCode))
+    {
+        SAL_INFO("sc.opencl", "conversion of group " << this << " failed, disabling");
+        mxGroup->meCalcState = sc::GroupCalcDisabled;
+        return false;
     }
-    else
+
+    mxGroup->meCalcState = sc::GroupCalcRunning;
+    if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, mxGroup->mpTopCell->aPos, mxGroup, aCode))
     {
-        ScTokenArray aDummy;
-        if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, mxGroup->mpTopCell->aPos, mxGroup, aDummy))
-        {
-            SAL_INFO("sc.opencl", "interpreting group " << mxGroup << " (state " << mxGroup->meCalcState << ") failed, disabling");
-            mxGroup->meCalcState = sc::GroupCalcDisabled;
-            return false;
-        }
+        SAL_INFO("sc.opencl", "interpreting group " << mxGroup << " (state " << mxGroup->meCalcState << ") failed, disabling");
+        mxGroup->meCalcState = sc::GroupCalcDisabled;
+        return false;
     }
 
+    mxGroup->meCalcState = sc::GroupCalcEnabled;
     return true;
 }
 
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index f58f7dc..a611298 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -277,6 +277,10 @@ void fillMatrix( ScMatrix& rMat, size_t nCol, const double* pNums, rtl_uString**
 
 }
 
+CompiledFormula::CompiledFormula() {}
+
+CompiledFormula::~CompiledFormula() {}
+
 FormulaGroupInterpreterSoftware::FormulaGroupInterpreterSoftware() : FormulaGroupInterpreter()
 {
 }
commit 1112837550fd0d24a8130948d7238cbb1d1946bc
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Mar 5 15:35:33 2014 -0500

    Build fix for OSX.
    
    Change-Id: I63613c40a5a947625c449fcd52ca129af116c900

diff --git a/sc/inc/stlalgorithm.hxx b/sc/inc/stlalgorithm.hxx
index 5cc22f2..fb2b35b 100644
--- a/sc/inc/stlalgorithm.hxx
+++ b/sc/inc/stlalgorithm.hxx
@@ -14,7 +14,9 @@
 #include <limits>
 
 #include <stdlib.h>
+#if defined(WNT) || defined (__ANDROID__)
 #include <malloc.h>
+#endif
 
 /**
  * Function object to allow deleting instances stored in STL containers as
commit b245c4dee43d8308a9dc860b238520df7048db0a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Mar 5 13:58:56 2014 -0500

    Build fix on Windows.
    
    Change-Id: Icbd46d5bc72bdc07490dd45b3d29a4400a66119f

diff --git a/sc/inc/stlalgorithm.hxx b/sc/inc/stlalgorithm.hxx
index d2beaa6..5cc22f2 100644
--- a/sc/inc/stlalgorithm.hxx
+++ b/sc/inc/stlalgorithm.hxx
@@ -80,9 +80,9 @@ public:
 
         size_type size = n*sizeof(value_type);
 #ifdef WNT
-        return _aligned_malloc(size, _Alignment);
+        return (pointer)_aligned_malloc(size, _Alignment);
 #elif defined __ANDROID__
-        return memalign(_Alignment, size);
+        return (pointer)memalign(_Alignment, size);
 #else
         void* ptr;
         int err = posix_memalign(&ptr, _Alignment, size);
commit a00f04653e3895f8e8dcdf0f1d5035c6af4da6ac
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Mar 5 12:28:21 2014 -0500

    Oopsy.
    
    Change-Id: Ie961fca03b99ec14f401462da56dd4110ea5518c
    Reviewed-on: https://gerrit.libreoffice.org/8467
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/inc/stlalgorithm.hxx b/sc/inc/stlalgorithm.hxx
index f788667..d2beaa6 100644
--- a/sc/inc/stlalgorithm.hxx
+++ b/sc/inc/stlalgorithm.hxx
@@ -82,7 +82,7 @@ public:
 #ifdef WNT
         return _aligned_malloc(size, _Alignment);
 #elif defined __ANDROID__
-        return memalign(align, size);
+        return memalign(_Alignment, size);
 #else
         void* ptr;
         int err = posix_memalign(&ptr, _Alignment, size);
commit d638491ef601c349a3d7576fdf4e28485d1917ff
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Feb 26 16:29:27 2014 -0500

    Ensure that numeric array storage is aligned to 256-byte boundary.
    
    OpenCL devices require this else we would get a performance hit.
    
    (cherry picked from commit 03f7a342011a4f69cfcbec7af3e4f1a2e835618b)
    (cherry picked from commit 757856e9275d19e2c7a3673d10fa8963fb9fbeb3)
    
    Change-Id: Ie69e07dc5d9b62abad5cc39d1f30e1d770c56758
    Reviewed-on: https://gerrit.libreoffice.org/8466
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 3834e49..602c4a4 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -13,6 +13,7 @@
 #include "address.hxx"
 #include "types.hxx"
 #include "platforminfo.hxx"
+#include <stlalgorithm.hxx>
 
 #include "svl/sharedstringpool.hxx"
 
@@ -28,7 +29,8 @@ namespace sc {
 
 struct FormulaGroupContext : boost::noncopyable
 {
-    typedef std::vector<double> NumArrayType;
+    typedef AlignedAllocator<double,256> DoubleAllocType;
+    typedef std::vector<double, DoubleAllocType> NumArrayType;
     typedef std::vector<rtl_uString*> StrArrayType;
     typedef boost::ptr_vector<NumArrayType> NumArrayStoreType;
     typedef boost::ptr_vector<StrArrayType> StrArrayStoreType;
diff --git a/sc/inc/stlalgorithm.hxx b/sc/inc/stlalgorithm.hxx
index fb5509f..f788667 100644
--- a/sc/inc/stlalgorithm.hxx
+++ b/sc/inc/stlalgorithm.hxx
@@ -11,6 +11,10 @@
 #define __SC_STLALGORITHM_HXX__
 
 #include <functional>
+#include <limits>
+
+#include <stdlib.h>
+#include <malloc.h>
 
 /**
  * Function object to allow deleting instances stored in STL containers as
@@ -25,6 +29,81 @@ struct ScDeleteObjectByPtr : public ::std::unary_function<T*, void>
     }
 };
 
+namespace sc {
+
+/**
+ * Custom allocator for STL container to ensure that the base address of
+ * allocated storage is aligned to a specified boundary.
+ */
+template<typename T, size_t _Alignment>
+class AlignedAllocator
+{
+public:
+    typedef T value_type;
+    typedef size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef T* void_pointer;
+
+    typedef T& reference;
+    typedef const T& const_reference;
+
+    template<typename _Type2>
+    struct rebind
+    {
+        typedef AlignedAllocator<_Type2,_Alignment> other;
+    };
+
+    AlignedAllocator() {}
+    ~AlignedAllocator() {}
+
+    template<typename _Type2>
+    AlignedAllocator(const AlignedAllocator<_Type2,_Alignment>&) {}
+
+    void construct(T* p, const value_type& val) { new(p) value_type(val); }
+    void destroy(T* p) { p->~value_type(); }
+
+    size_type max_size() const
+    {
+        return std::numeric_limits<size_type>::max() / sizeof(value_type);
+    }
+
+    bool operator== (const AlignedAllocator&) const { return true; }
+    bool operator!= (const AlignedAllocator&) const { return false; }
+
+    pointer allocate(size_type n)
+    {
+        if (!n)
+            return NULL;
+
+        size_type size = n*sizeof(value_type);
+#ifdef WNT
+        return _aligned_malloc(size, _Alignment);
+#elif defined __ANDROID__
+        return memalign(align, size);
+#else
+        void* ptr;
+        int err = posix_memalign(&ptr, _Alignment, size);
+        if (err)
+            ptr = NULL;
+        return (pointer)ptr;
+#endif
+    }
+
+    void deallocate(pointer p, size_type)
+    {
+#ifdef WNT
+        _aligned_free(p);
+#else
+        free(p);
+#endif
+    }
+};
+
+}
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 9ec1c955533c8506d996e95fa312e3463898dd09
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Mar 3 17:58:11 2014 -0500

    fdo#75260: Correctly draw double lines for both Writer and Calc.
    
    Fix all sorts of incorrect double line handling in drawinglayer in order to
    draw thick-thin double line types correctly.  Also change handling of border
    lines in writer tables. There are still some outstanding issues but it's
    much better than how it was before.
    
    Also realized that Word and Excel handle simple thin double lines differently;
    Word varies widths of all of the lines and the gap whereas Excel only has one
    fixed size for its double line.  For this reason I decided to add a separate
    double line type (DOUBLE_THIN) to handle Excel's double line.
    
    (cherry picked from commit 2c62596cf264ef10749d8bfdb2bb2ebef2d98fbc)
    
    Conflicts:
    	cui/source/tabpages/border.cxx
    	sc/qa/unit/subsequent_export-test.cxx
    	sc/source/ui/view/tabvwsha.cxx
    	sw/source/core/layout/paintfrm.cxx
    	xmloff/source/style/bordrhdl.cxx
    
    Change-Id: Iaaa353b6e4f998b524262bea59260b4333e0cdb4
    Reviewed-on: https://gerrit.libreoffice.org/8464
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/cui/source/inc/border.hxx b/cui/source/inc/border.hxx
index 793d584..8f66e5d 100644
--- a/cui/source/inc/border.hxx
+++ b/cui/source/inc/border.hxx
@@ -130,6 +130,8 @@ private:
     void                ResetFrameLine_Impl( svx::FrameBorderType eBorder,
                                              const editeng::SvxBorderLine* pCurLine,
                                              bool bValid );
+
+    bool IsBorderLineStyleAllowed( sal_Int16 nStyle ) const;
 };
 
 
diff --git a/cui/source/tabpages/border.cxx b/cui/source/tabpages/border.cxx
index 6713ee8..d2d12ac 100644
--- a/cui/source/tabpages/border.cxx
+++ b/cui/source/tabpages/border.cxx
@@ -42,6 +42,7 @@
 #include <sfx2/itemconnect.hxx>
 #include <sal/macros.h>
 #include "borderconn.hxx"
+#include <svtools/ctrlbox.hxx>
 
 using namespace ::editeng;
 
@@ -332,6 +333,11 @@ void SvxBorderTabPage::ResetFrameLine_Impl( svx::FrameBorderType eBorder, const
     }
 }
 
+bool SvxBorderTabPage::IsBorderLineStyleAllowed( sal_Int16 /*nStyle*/ ) const
+{
+    return true;
+}
+
 // -----------------------------------------------------------------------
 
 void SvxBorderTabPage::Reset( const SfxItemSet& rSet )
@@ -985,38 +991,49 @@ void SvxBorderTabPage::FillLineListBox_Impl()
 {
     using namespace ::com::sun::star::table::BorderLineStyle;
 
+    struct {
+        sal_Int16 mnStyle;
+        long mnMinWidth;
+        LineListBox::ColorFunc mpColor1Fn;
+        LineListBox::ColorFunc mpColor2Fn;
+        LineListBox::ColorDistFunc mpColorDistFn;
+    } aLines[] = {
+        // Simple lines
+        { SOLID,       0, &sameColor, &sameColor, &sameDistColor },
+        { DOTTED,      0, &sameColor, &sameColor, &sameDistColor },
+        { DASHED,      0, &sameColor, &sameColor, &sameDistColor },
+        { FINE_DASHED, 0, &sameColor, &sameColor, &sameDistColor },
+
+        // Double lines
+        { DOUBLE,              10, &sameColor, &sameColor, &sameDistColor },
+        { DOUBLE_THIN,         10, &sameColor, &sameColor, &sameDistColor },
+        { THINTHICK_SMALLGAP,  20, &sameColor, &sameColor, &sameDistColor },
+        { THINTHICK_MEDIUMGAP,  0, &sameColor, &sameColor, &sameDistColor },
+        { THINTHICK_LARGEGAP,   0, &sameColor, &sameColor, &sameDistColor },
+        { THICKTHIN_SMALLGAP,  20, &sameColor, &sameColor, &sameDistColor },
+        { THICKTHIN_MEDIUMGAP,  0, &sameColor, &sameColor, &sameDistColor },
+        { THICKTHIN_LARGEGAP,   0, &sameColor, &sameColor, &sameDistColor },
+
+        { EMBOSSED, 15, &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor, &lcl_mediumColor },
+        { ENGRAVED, 15, &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor, &lcl_mediumColor },
+
+        { OUTSET, 10, &SvxBorderLine::lightColor, &SvxBorderLine::darkColor, &sameDistColor },
+        { INSET,  10, &SvxBorderLine::darkColor, &SvxBorderLine::lightColor, &sameDistColor }
+    };
+
     m_pLbLineStyle->SetSourceUnit( FUNIT_TWIP );
 
     m_pLbLineStyle->SetNone( SVX_RESSTR( RID_SVXSTR_NONE ) );
 
-    // Simple lines
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( SOLID ), SOLID );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( DOTTED ), DOTTED );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( DASHED ), DASHED );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( FINE_DASHED ), FINE_DASHED );
-
-    // Double lines
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( DOUBLE ), DOUBLE );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( THINTHICK_SMALLGAP ), THINTHICK_SMALLGAP, 20 );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( THINTHICK_MEDIUMGAP ), THINTHICK_MEDIUMGAP );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( THINTHICK_LARGEGAP ), THINTHICK_LARGEGAP );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( THICKTHIN_SMALLGAP ), THICKTHIN_SMALLGAP, 20 );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( THICKTHIN_MEDIUMGAP ), THICKTHIN_MEDIUMGAP );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( THICKTHIN_LARGEGAP ), THICKTHIN_LARGEGAP );
-
-    // Engraved / Embossed
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( EMBOSSED ), EMBOSSED, 15,
-            &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor,
-            &lcl_mediumColor );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( ENGRAVED ), ENGRAVED, 15,
-            &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor,
-            &lcl_mediumColor );
-
-    // Inset / Outset
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( OUTSET ), OUTSET, 10,
-           &SvxBorderLine::lightColor, &SvxBorderLine::darkColor );
-    m_pLbLineStyle->InsertEntry( SvxBorderLine::getWidthImpl( INSET ), INSET, 10,
-           &SvxBorderLine::darkColor, &SvxBorderLine::lightColor );
+    for (size_t i = 0, n = SAL_N_ELEMENTS(aLines); i < n; ++i)
+    {
+        if (!IsBorderLineStyleAllowed(aLines[i].mnStyle))
+            continue;
+
+        m_pLbLineStyle->InsertEntry(
+            SvxBorderLine::getWidthImpl(aLines[i].mnStyle), aLines[i].mnStyle,
+            aLines[i].mnMinWidth, aLines[i].mpColor1Fn, aLines[i].mpColor2Fn, aLines[i].mpColorDistFn);
+    }
 
     sal_Int64 nVal = static_cast<sal_Int64>(MetricField::ConvertDoubleValue(
                 m_pLineWidthMF->GetValue( ),
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 290c87a..67efa09 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -28,6 +28,8 @@
 #include <numeric>
 #include <algorithm>
 
+namespace drawinglayer {
+
 namespace {
 
 void moveLine(basegfx::B2DPolygon& rPoly, double fGap, const basegfx::B2DVector& rVector)
@@ -44,10 +46,46 @@ void moveLine(basegfx::B2DPolygon& rPoly, double fGap, const basegfx::B2DVector&
     }
 }
 
+primitive2d::Primitive2DReference makeHairLinePrimitive(
+    const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd, const basegfx::B2DVector& rVector,
+    const basegfx::BColor& rColor, double fGap)
+{
+    basegfx::B2DPolygon aPolygon;
+    aPolygon.append(rStart);
+    aPolygon.append(rEnd);
+    moveLine(aPolygon, fGap, rVector);
+
+    return primitive2d::Primitive2DReference(new primitive2d::PolygonHairlinePrimitive2D(aPolygon, rColor));
 }
 
-namespace drawinglayer
+primitive2d::Primitive2DReference makeSolidLinePrimitive(
+    const basegfx::B2DPolyPolygon& rClipRegion, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd,
+    const basegfx::B2DVector& rVector, const basegfx::BColor& rColor, double fLineWidth, double fGap)
 {
+    const basegfx::B2DVector aPerpendicular = basegfx::getPerpendicular(rVector);
+    const basegfx::B2DVector aLineWidthOffset = ((fLineWidth + 1.0) * 0.5) * aPerpendicular;
+
+    basegfx::B2DPolygon aPolygon;
+    aPolygon.append(rStart + aLineWidthOffset);
+    aPolygon.append(rEnd + aLineWidthOffset);
+    aPolygon.append(rEnd - aLineWidthOffset);
+    aPolygon.append(rStart - aLineWidthOffset);
+    aPolygon.setClosed(true);
+
+    moveLine(aPolygon, fGap, rVector);
+
+    basegfx::B2DPolyPolygon aClipped =
+        basegfx::tools::clipPolygonOnPolyPolygon(aPolygon, rClipRegion, true, false);
+
+    if (aClipped.count())
+        aPolygon = aClipped.getB2DPolygon(0);
+
+    return primitive2d::Primitive2DReference(
+        new primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon), rColor));
+}
+
+}
+
     // fdo#49438: heuristic pseudo hack
     static bool lcl_UseHairline(double const fW,
             basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd,
@@ -139,66 +177,42 @@ namespace drawinglayer
 
                 if(isOutsideUsed() && isInsideUsed())
                 {
-                    basegfx::B2DPolygon aPolygon;
                     const double fExt = getWidth(rViewInformation);  // Extend a lot: it'll be clipped later.
                     const basegfx::B2DPoint aTmpStart(getStart() - (fExt * aVector));
                     const basegfx::B2DPoint aTmpEnd(getEnd() + (fExt * aVector));
 
-                    // Get which is the line to show
-                    double nWidth = getLeftWidth();
-                    basegfx::BColor aColor = getRGBColorLeft();
-
-                    bool const bIsHairline = lcl_UseHairline(
-                            nWidth, getStart(), getEnd(), rViewInformation);
-                    nWidth = lcl_GetCorrectedWidth(nWidth,
-                                getStart(), getEnd(), rViewInformation);
+                    xRetval.realloc(2);
 
-                    // distance is already scaled.
-                    double fGap = mfDistance*8.0;
-
-                    if (bIsHairline)
                     {
-                        // create hairline primitive
-                        aPolygon.append( getStart() );
-                        aPolygon.append( getEnd() );
-
-                        basegfx::B2DPolygon aPolygon2 = aPolygon;
-                        moveLine(aPolygon2, fGap, aVector);
-
-                        xRetval.realloc(2);
-                        xRetval[0] = Primitive2DReference(new PolygonHairlinePrimitive2D(
-                            aPolygon,
-                            aColor));
-
-                        xRetval[1] = Primitive2DReference(new PolygonHairlinePrimitive2D(
-                            aPolygon2,
-                            aColor));
+                        // "inside" line
+                        double fWidth = getLeftWidth();
+                        basegfx::BColor aColor = getRGBColorLeft();
+                        bool bIsHairline = lcl_UseHairline(
+                                fWidth, getStart(), getEnd(), rViewInformation);
+                        fWidth = lcl_GetCorrectedWidth(fWidth,
+                                    getStart(), getEnd(), rViewInformation);
+
+                        if (bIsHairline)
+                            xRetval[0] = makeHairLinePrimitive(getStart(), getEnd(), aVector, aColor, 0.0);
+                        else
+                            xRetval[0] = makeSolidLinePrimitive(
+                                aClipRegion, aTmpStart, aTmpEnd, aVector, aColor, fWidth, 0.0);
                     }
-                    else
-                    {
-                        // create filled polygon primitive
-                        const basegfx::B2DVector aLineWidthOffset(((nWidth + 1) * 0.5) * aPerpendicular);
 
-                        aPolygon.append( aTmpStart + aLineWidthOffset );
-                        aPolygon.append( aTmpEnd + aLineWidthOffset );
-                        aPolygon.append( aTmpEnd - aLineWidthOffset );
-                        aPolygon.append( aTmpStart - aLineWidthOffset );
-                        aPolygon.setClosed( true );
-
-                        basegfx::B2DPolyPolygon aClipped = basegfx::tools::clipPolygonOnPolyPolygon(
-                            aPolygon, aClipRegion, true, false );
-
-                        if ( aClipped.count() )
-                            aPolygon = aClipped.getB2DPolygon(0);
-
-                        basegfx::B2DPolygon aPolygon2 = aPolygon;
-                        moveLine(aPolygon2, fGap, aVector);
-
-                        xRetval.realloc(2);
-                        xRetval[0] = Primitive2DReference(
-                            new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon), aColor));
-                        xRetval[1] = Primitive2DReference(
-                            new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon2), aColor));
+                    {
+                        // "outside" line
+                        double fWidth = getRightWidth();
+                        basegfx::BColor aColor = getRGBColorRight();
+                        bool bIsHairline = lcl_UseHairline(
+                                fWidth, getStart(), getEnd(), rViewInformation);
+                        fWidth = lcl_GetCorrectedWidth(fWidth,
+                                    getStart(), getEnd(), rViewInformation);
+
+                        if (bIsHairline)
+                            xRetval[1] = makeHairLinePrimitive(getStart(), getEnd(), aVector, aColor, mfDistance);
+                        else
+                            xRetval[1] = makeSolidLinePrimitive(
+                                aClipRegion, aTmpStart, aTmpEnd, aVector, aColor, fWidth, mfDistance);
                     }
                 }
                 else
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 9552be3..203ce5f 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -297,13 +297,13 @@ namespace drawinglayer
             switch (rSource.getStyle())
             {
                 case table::BorderLineStyle::SOLID:
-                case table::BorderLineStyle::DOUBLE:
+                case table::BorderLineStyle::DOUBLE_THIN:
                 {
                     const basegfx::BColor aLineColor =
                         maBColorModifierStack.getModifiedColor(rSource.getRGBColorLeft());
                     double nThick = rtl::math::round(rSource.getLeftWidth());
 
-                    bool bDouble = rSource.getStyle() == table::BorderLineStyle::DOUBLE;
+                    bool bDouble = rSource.getStyle() == table::BorderLineStyle::DOUBLE_THIN;
 
                     basegfx::B2DPolygon aTarget;
 
diff --git a/editeng/source/items/borderline.cxx b/editeng/source/items/borderline.cxx
index e80685e..b393420 100644
--- a/editeng/source/items/borderline.cxx
+++ b/editeng/source/items/borderline.cxx
@@ -316,6 +316,10 @@ BorderWidthImpl SvxBorderLine::getWidthImpl( SvxBorderStyle nStyle )
                     1.0/3.0, 1.0/3.0, 1.0/3.0 );
             break;
 
+        case DOUBLE_THIN:
+            aImpl = BorderWidthImpl(CHANGE_DIST, 10.0, 10.0, 1.0);
+            break;
+
         case THINTHICK_SMALLGAP:
             aImpl = BorderWidthImpl( CHANGE_LINE1, 1.0,
                     THINTHICK_SMALLGAP_line2, THINTHICK_SMALLGAP_gap );
@@ -429,6 +433,7 @@ void SvxBorderLine::GuessLinesWidths( SvxBorderStyle nStyle, sal_uInt16 nOut, sa
         static const SvxBorderStyle aDoubleStyles[] =
         {
             DOUBLE,
+            DOUBLE_THIN,
             THINTHICK_SMALLGAP,
             THINTHICK_MEDIUMGAP,
             THINTHICK_LARGEGAP,
diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx
index 020488c..dff98c6 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -1802,7 +1802,7 @@ SvxBoxItem::LineToSvxLine(const ::com::sun::star::table::BorderLine2& rLine, Svx
         rSvxLine.SetWidth( bConvert? MM100_TO_TWIP_UNSIGNED( rLine.LineWidth ) : rLine.LineWidth );
         // fdo#46112: double does not necessarily mean symmetric
         // for backwards compatibility
-        bGuessWidth = (DOUBLE == nStyle) &&
+        bGuessWidth = ((DOUBLE == nStyle || DOUBLE_THIN == nStyle)) &&
             (rLine.InnerLineWidth > 0) && (rLine.OuterLineWidth > 0);
     }
 
diff --git a/include/svtools/ctrlbox.hxx b/include/svtools/ctrlbox.hxx
index 19eea12..6599091 100644
--- a/include/svtools/ctrlbox.hxx
+++ b/include/svtools/ctrlbox.hxx
@@ -317,6 +317,9 @@ class SVT_DLLPUBLIC LineListBox : public ListBox
     sal_uInt16           GetStylePos( sal_uInt16 nListPos, long nWidth );
 
 public:
+    typedef Color (*ColorFunc)(Color);
+    typedef Color (*ColorDistFunc)(Color, Color);
+
                     LineListBox( Window* pParent, WinBits nWinStyle = WB_BORDER );
     virtual         ~LineListBox();
 
@@ -330,9 +333,9 @@ public:
     /** Insert a listbox entry with all widths in Twips. */
     void            InsertEntry( BorderWidthImpl aWidthImpl,
                         sal_uInt16 nStyle, long nMinWidth = 0,
-                        Color (*pColor1Fn)(Color) = &sameColor,
-                        Color (*pColor2Fn)( Color ) = &sameColor,
-                        Color (*pColorDistFn)( Color, Color ) = &sameDistColor );
+                        ColorFunc pColor1Fn = &sameColor,
+                        ColorFunc pColor2Fn = &sameColor,
+                        ColorDistFunc pColorDistFn = &sameDistColor );
 
     using ListBox::RemoveEntry;
     virtual void    RemoveEntry( sal_uInt16 nPos );
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index d288c8848..09bc908 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -647,6 +647,7 @@ namespace xmloff { namespace token {
         XML_DOTTED,
         XML_DOUBLE,
         XML_DOUBLE_SIDED,
+        XML_DOUBLE_THIN,
         XML_DOWN,
         XML_DRAFT,
         XML_DRAW,
diff --git a/offapi/com/sun/star/table/BorderLineStyle.idl b/offapi/com/sun/star/table/BorderLineStyle.idl
index 7613272..0c37c67 100644
--- a/offapi/com/sun/star/table/BorderLineStyle.idl
+++ b/offapi/com/sun/star/table/BorderLineStyle.idl
@@ -41,7 +41,8 @@ constants BorderLineStyle
      */
     const short DASHED = 2;
 
-    /** Double border line.
+    /** Double border line. Widths of the lines and the gap are all equal,
+        and vary equally with the total width.
      */
     const short DOUBLE = 3;
 
@@ -95,9 +96,14 @@ constants BorderLineStyle
      */
     const short FINE_DASHED = 14;
 
+    /** Double border line consisting of two fixed thin lines separated by a
+        variable gap.
+     */
+    const short DOUBLE_THIN = 15;
+
     /** Maximum valid border line style value.
      */
-    const short BORDER_LINE_STYLE_MAX = 14;
+    const short BORDER_LINE_STYLE_MAX = 15;
 };
 
 
diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx
index c569ce8..203eda6 100644
--- a/sc/source/filter/excel/xistyle.cxx
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -903,7 +903,7 @@ bool lclConvertBorderLine( ::editeng::SvxBorderLine& rLine, const XclImpPalette&
         {   EXC_BORDER_THIN,    table::BorderLineStyle::FINE_DASHED }, // 3 = dashed
         {   EXC_BORDER_THIN,    table::BorderLineStyle::DOTTED }, // 4 = dotted
         {   EXC_BORDER_THICK,   table::BorderLineStyle::SOLID },  // 5 = thick
-        {   EXC_BORDER_THIN,    table::BorderLineStyle::DOUBLE }, // 6 = double
+        {   EXC_BORDER_THICK,   table::BorderLineStyle::DOUBLE_THIN }, // 6 = double
         {   EXC_BORDER_HAIR,    table::BorderLineStyle::SOLID },  // 7 = hair
         {   EXC_BORDER_MEDIUM,  table::BorderLineStyle::DASHED }, // 8 = med dash
         {   EXC_BORDER_THIN,    table::BorderLineStyle::SOLID },  // 9 = thin dashdot
diff --git a/sc/source/filter/html/htmlexp.cxx b/sc/source/filter/html/htmlexp.cxx
index a6450cd..83b91e3 100644
--- a/sc/source/filter/html/htmlexp.cxx
+++ b/sc/source/filter/html/htmlexp.cxx
@@ -515,6 +515,7 @@ OString ScHTMLExport::BorderToStyle(const char* pBorderName,
                 aOut.append("dashed");
                 break;
             case table::BorderLineStyle::DOUBLE:
+            case table::BorderLineStyle::DOUBLE_THIN:
             case table::BorderLineStyle::THINTHICK_SMALLGAP:
             case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
             case table::BorderLineStyle::THINTHICK_LARGEGAP:
diff --git a/sc/source/filter/lotus/lotattr.cxx b/sc/source/filter/lotus/lotattr.cxx
index bc17dff..cdc804a 100644
--- a/sc/source/filter/lotus/lotattr.cxx
+++ b/sc/source/filter/lotus/lotattr.cxx
@@ -169,7 +169,7 @@ void LotAttrCache::LotusToScBorderLine( sal_uInt8 nLine, ::editeng::SvxBorderLin
         case 2: aBL.SetWidth( DEF_LINE_WIDTH_2 ); break;
         case 3:
         {
-            aBL.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
+            aBL.SetBorderLineStyle(table::BorderLineStyle::DOUBLE_THIN);
             aBL.SetWidth( DEF_LINE_WIDTH_1 );
         }
         break;
diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx
index d14b353..3990c0b 100644
--- a/sc/source/filter/oox/stylesbuffer.cxx
+++ b/sc/source/filter/oox/stylesbuffer.cxx
@@ -1736,8 +1736,8 @@ bool Border::convertBorderLine( BorderLine2& rBorderLine, const BorderLineModel&
             rBorderLine.LineStyle = table::BorderLineStyle::DOTTED;
         break;
         case XML_double:
-            lclSetBorderLineWidth( rBorderLine, 5 ,5, 5 );
-            rBorderLine.LineStyle = table::BorderLineStyle::DOUBLE;
+            lclSetBorderLineWidth( rBorderLine, 10, 30, 10 );
+            rBorderLine.LineStyle = table::BorderLineStyle::DOUBLE_THIN;
         break;
         case XML_hair:              lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR );    break;
         case XML_medium:            lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );  break;
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index 06a4a9c..fe48970 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -835,14 +835,11 @@ sal_uInt16 LineListBox::InsertEntry( const OUString& rStr, sal_uInt16 nPos )
 // -----------------------------------------------------------------------
 
 void LineListBox::InsertEntry(
-        BorderWidthImpl aWidthImpl,
-        sal_uInt16 nStyle, long nMinWidth,
-        Color ( *pColor1Fn )( Color ), Color ( *pColor2Fn )( Color ),
-        Color ( *pColorDistFn )( Color, Color ) )
+    BorderWidthImpl aWidthImpl, sal_uInt16 nStyle, long nMinWidth,
+    ColorFunc pColor1Fn, ColorFunc pColor2Fn, ColorDistFunc pColorDistFn )
 {
     ImpLineListData* pData = new ImpLineListData(
-            aWidthImpl, nStyle, nMinWidth,
-           pColor1Fn, pColor2Fn, pColorDistFn );
+        aWidthImpl, nStyle, nMinWidth, pColor1Fn, pColor2Fn, pColorDistFn);
     pLineList->push_back( pData );
 }
 
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 54de397..f10d7b4 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2275,6 +2275,11 @@ struct SwLineEntry
     SwTwips mnKey;
     SwTwips mnStartPos;
     SwTwips mnEndPos;
+    SwTwips mnOffset;
+
+    bool mbOffsetPerp;
+    bool mbOffsetStart;
+    bool mbOffsetEnd;
 
     svx::frame::Style maAttribute;
 
@@ -2296,6 +2301,10 @@ SwLineEntry::SwLineEntry( SwTwips nKey,
     :   mnKey( nKey ),
         mnStartPos( nStartPos ),
         mnEndPos( nEndPos ),
+        mnOffset( 0 ),
+        mbOffsetPerp(false),
+        mbOffsetStart(false),
+        mbOffsetEnd(false),
         maAttribute( rAttribute )
 {
 }
@@ -2378,6 +2387,8 @@ class SwTabFrmPainter
                             svx::frame::Style*,
                             bool bHori ) const;
 
+    void AdjustTopLeftFrames();
+
 public:
     SwTabFrmPainter( const SwTabFrm& rTabFrm );
 
@@ -2388,6 +2399,7 @@ SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm )
     : mrTabFrm( rTabFrm )
 {
     HandleFrame( rTabFrm );
+    AdjustTopLeftFrames();
 }
 
 void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm )
@@ -2420,7 +2432,7 @@ void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm )
     }
 }
 
-void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) const
+void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
 {
     // #i16816# tagged pdf support
     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, rDev );
@@ -2452,7 +2464,7 @@ void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) cons
     aSize.Width() += nPixelSzW; aSize.Height() += nPixelSzH;
     rDev.SetClipRegion(Region(Rectangle(rRect.Pos(), aSize)));
 
-    // The following stuff if necessary to have the new table borders fit
+    // The following stuff is necessary to have the new table borders fit
     // into a ::SwAlignRect adjusted world.
     const SwTwips nTwipXCorr =  bVert ? 0 : std::max( 0L, nHalfPixelSzW - 2 );    // 1 < 2 < 3 ;-)
     const SwTwips nTwipYCorr = !bVert ? 0 : std::max( 0L, nHalfPixelSzW - 2 );    // 1 < 2 < 3 ;-)
@@ -2496,6 +2508,45 @@ void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) cons
                 aEnd.Y() = rEntry.mnEndPos;
             }
 
+            svx::frame::Style aStyles[ 7 ];
+            aStyles[ 0 ] = rEntryStyle;
+            FindStylesForLine( aStart, aEnd, aStyles, bHori );
+
+            // Account for double line thicknesses for the top- and left-most borders.
+            if (rEntry.mnOffset)
+            {
+                if (bHori)
+                {
+                    if (rEntry.mbOffsetPerp)
+                    {
+                        // Apply offset in perpendicular direction.
+                        aStart.Y() -= rEntry.mnOffset;
+                        aEnd.Y() -= rEntry.mnOffset;
+                    }
+                    if (rEntry.mbOffsetStart)
+                        // Apply offset at the start of a border.
+                        aStart.X() -= rEntry.mnOffset;
+                    if (rEntry.mbOffsetEnd)
+                        // Apply offset at the end of a border.
+                        aEnd.X() += rEntry.mnOffset;
+                }
+                else
+                {
+                    if (rEntry.mbOffsetPerp)
+                    {
+                        // Apply offset in perpendicular direction.
+                        aStart.X() -= rEntry.mnOffset;
+                        aEnd.X() -= rEntry.mnOffset;
+                    }
+                    if (rEntry.mbOffsetStart)
+                        // Apply offset at the start of a border.
+                        aStart.Y() -= rEntry.mnOffset;
+                    if (rEntry.mbOffsetEnd)
+                        // Apply offset at the end of a border.
+                        aEnd.Y() += rEntry.mnOffset;
+                }
+            }
+
             SwRect aRepaintRect( aStart, aEnd );
 
             // the repaint rectangle has to be moved a bit for the centered lines:
@@ -2511,142 +2562,138 @@ void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) cons
                 aRepaintRect.Pos().X() -= nRepaintRectSize;
             }
 
-            if ( rRect.IsOver( aRepaintRect ) )
+            if (!rRect.IsOver(aRepaintRect))
             {
-                svx::frame::Style aStyles[ 7 ];
-                aStyles[ 0 ] = rEntryStyle;
-                FindStylesForLine( aStart, aEnd, aStyles, bHori );
+                continue;
+            }
 
-                // subsidiary lines
-                const Color* pTmpColor = 0;
-                if ( 0 == aStyles[ 0 ].GetWidth() )
-                {
-                    if ( IS_SUBS_TABLE && pGlobalShell->GetWin() )
-                        aStyles[ 0 ].Set( rCol, rCol, rCol, false, 1, 0, 0 );
-                }
-                else
-                    pTmpColor = pHCColor;
+            // subsidiary lines
+            const Color* pTmpColor = 0;
+            if (0 == aStyles[ 0 ].GetWidth())
+            {
+                if (IS_SUBS_TABLE && pGlobalShell->GetWin())
+                    aStyles[ 0 ].Set( rCol, rCol, rCol, false, 1, 0, 0 );
+            }
+            else
+                pTmpColor = pHCColor;
 
-                // The line sizes stored in the line style have to be adjusted as well.
-                // This will guarantee that lines with the same twip size will have the
-                // same pixel size.
-                for ( int i = 0; i < 7; ++i )
-                {
-                    sal_uInt16 nPrim = aStyles[ i ].Prim();
-                    sal_uInt16 nDist = aStyles[ i ].Dist();
-                    sal_uInt16 nSecn = aStyles[ i ].Secn();
-
-                    if ( nPrim > 0 )
-                        nPrim = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nPrim / nPixelSzH ) ) );
-                    if ( nDist > 0 )
-                        nDist = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nDist / nPixelSzH ) ) );
-                    if ( nSecn > 0 )
-                        nSecn = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nSecn / nPixelSzH ) ) );
-
-                    aStyles[ i ].Set( nPrim, nDist, nSecn );
-                }
+            // The line sizes stored in the line style have to be adjusted as
+            // well.  This will guarantee that lines with the same twip size
+            // will have the same pixel size.
+            for ( int i = 0; i < 7; ++i )
+            {
+                sal_uInt16 nPrim = aStyles[ i ].Prim();
+                sal_uInt16 nDist = aStyles[ i ].Dist();
+                sal_uInt16 nSecn = aStyles[ i ].Secn();
+
+                if (nPrim > 0)
+                    nPrim = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nPrim / nPixelSzH ) ) );
+                if (nDist > 0)
+                    nDist = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nDist / nPixelSzH ) ) );
+                if (nSecn > 0)
+                    nSecn = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nSecn / nPixelSzH ) ) );
+
+                aStyles[ i ].Set( nPrim, nDist, nSecn );
+            }
 
-                // The (twip) positions will be adjusted to meet these requirements:
-                // 1. The y coordinates are located in the middle of the pixel grid
-                // 2. The x coordinated are located at the beginning of the pixel grid
-                // This is done, because the horizontal lines are painted "at beginning",
-                // whereas the vertical lines are painted "centered". By making the line
-                // sizes a multiple of one pixel size, we can assure, that all lines having
-                // the same twip size have the same pixel size, independent of their position
-                // on the screen.
-                Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel( aStart ) );
-                Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel( aEnd ) );
-
-                if( pGlobalShell->GetWin() )
-                {
-                    // The table borders do not use SwAlignRect, but all the other frames do.
-                    // Therefore we tweak the outer borders a bit to achieve that the outer
-                    // borders match the subsidiary lines of the upper:
-                    if ( aStart.X() == aUpper.Left() )
-                        aPaintStart.X() = aUpperAligned.Left();
-                    else if ( aStart.X() == aUpper._Right() )
-                        aPaintStart.X() = aUpperAligned._Right();
-                    if ( aStart.Y() == aUpper.Top() )
-                        aPaintStart.Y() = aUpperAligned.Top();
-                    else if ( aStart.Y() == aUpper._Bottom() )
-                        aPaintStart.Y() = aUpperAligned._Bottom();
-
-                    if ( aEnd.X() == aUpper.Left() )
-                        aPaintEnd.X() = aUpperAligned.Left();
-                    else if ( aEnd.X() == aUpper._Right() )
-                        aPaintEnd.X() = aUpperAligned._Right();
-                    if ( aEnd.Y() == aUpper.Top() )
-                        aPaintEnd.Y() = aUpperAligned.Top();
-                    else if ( aEnd.Y() == aUpper._Bottom() )
-                        aPaintEnd.Y() = aUpperAligned._Bottom();
-                }
+            // The (twip) positions will be adjusted to meet these requirements:
+            // 1. The y coordinates are located in the middle of the pixel grid
+            // 2. The x coordinated are located at the beginning of the pixel grid
+            // This is done, because the horizontal lines are painted "at
+            // beginning", whereas the vertical lines are painted "centered".
+            // By making the line sizes a multiple of one pixel size, we can
+            // assure that all lines having the same twip size have the same
+            // pixel size, independent of their position on the screen.
+            Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel(aStart) );
+            Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel(aEnd) );
+
+            if (pGlobalShell->GetWin())
+            {
+                // The table borders do not use SwAlignRect, but all the other frames do.
+                // Therefore we tweak the outer borders a bit to achieve that the outer
+                // borders match the subsidiary lines of the upper:
+                if (aStart.X() == aUpper.Left())
+                    aPaintStart.X() = aUpperAligned.Left();
+                else if (aStart.X() == aUpper._Right())
+                    aPaintStart.X() = aUpperAligned._Right();
+                if (aStart.Y() == aUpper.Top())
+                    aPaintStart.Y() = aUpperAligned.Top();
+                else if (aStart.Y() == aUpper._Bottom())
+                    aPaintStart.Y() = aUpperAligned._Bottom();
+
+                if (aEnd.X() == aUpper.Left())
+                    aPaintEnd.X() = aUpperAligned.Left();
+                else if (aEnd.X() == aUpper._Right())
+                    aPaintEnd.X() = aUpperAligned._Right();
+                if (aEnd.Y() == aUpper.Top())
+                    aPaintEnd.Y() = aUpperAligned.Top();
+                else if (aEnd.Y() == aUpper._Bottom())
+                    aPaintEnd.Y() = aUpperAligned._Bottom();
+            }
 
-                // logically vertical lines are painted centered on the line,
-                // logically horizontal lines are painted "below" the line
-                bool const isBelow((mrTabFrm.IsVertical()) ? !bHori : bHori);
-                double const offsetStart = (isBelow)
-                    ?   aStyles[0].GetWidth() / 2.0
-                    :   std::max<double>(aStyles[1].GetWidth(),
-                            aStyles[3].GetWidth()) / 2.0;
-                double const offsetEnd = (isBelow)
-                    ?   aStyles[0].GetWidth() / 2.0
-                    :   std::max<double>(aStyles[4].GetWidth(),
-                            aStyles[6].GetWidth()) / 2.0;
-                if (mrTabFrm.IsVertical())
-                {
-                    aPaintStart.X() -= static_cast<long>(offsetStart + 0.5);
-                    aPaintEnd.X()   -= static_cast<long>(offsetEnd   + 0.5);
-                }
-                else
-                {
-                    aPaintStart.Y() += static_cast<long>(offsetStart + 0.5);
-                    aPaintEnd.Y()   += static_cast<long>(offsetEnd   + 0.5);
-                }
+            // logically vertical lines are painted centered on the line,
+            // logically horizontal lines are painted "below" the line
+            bool const isBelow((mrTabFrm.IsVertical()) ? !bHori : bHori);
+            double const offsetStart = (isBelow)
+                ?   aStyles[0].GetWidth() / 2.0
+                :   std::max<double>(aStyles[1].GetWidth(),
+                        aStyles[3].GetWidth()) / 2.0;
+            double const offsetEnd = (isBelow)
+                ?   aStyles[0].GetWidth() / 2.0
+                :   std::max<double>(aStyles[4].GetWidth(),
+                        aStyles[6].GetWidth()) / 2.0;
+            if (mrTabFrm.IsVertical())
+            {
+                aPaintStart.X() -= static_cast<long>(offsetStart + 0.5);
+                aPaintEnd.X()   -= static_cast<long>(offsetEnd   + 0.5);
+            }
+            else
+            {
+                aPaintStart.Y() += static_cast<long>(offsetStart + 0.5);
+                aPaintEnd.Y()   += static_cast<long>(offsetEnd   + 0.5);
+            }
 
-                aPaintStart.X() -= nTwipXCorr; // nHalfPixelSzW - 2 to assure that we do not leave the pixel
-                aPaintEnd.X()   -= nTwipXCorr;
-                aPaintStart.Y() -= nTwipYCorr;
-                aPaintEnd.Y()   -= nTwipYCorr;
+            aPaintStart.X() -= nTwipXCorr; // nHalfPixelSzW - 2 to assure that we do not leave the pixel
+            aPaintEnd.X()   -= nTwipXCorr;
+            aPaintStart.Y() -= nTwipYCorr;
+            aPaintEnd.Y()   -= nTwipYCorr;
 
-                if (::rtl::math::approxEqual(aStyles[0].Prim(), 0.0) &&
-                    ::rtl::math::approxEqual(aStyles[0].Secn(), 0.0))
-                {
-                    continue; // fdo#75118 do not paint zero-width lines
-                }
+            if (::rtl::math::approxEqual(aStyles[0].Prim(), 0.0) &&
+                ::rtl::math::approxEqual(aStyles[0].Secn(), 0.0))
+            {
+                continue; // fdo#75118 do not paint zero-width lines
+            }
 
-                // Here comes the painting stuff: Thank you, DR, great job!!!
-                if ( bHori )
-                {
-                    mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
-                        aPaintStart,
-                        aPaintEnd,
-                        aStyles[ 0 ],   // current style
-                        aStyles[ 1 ],   // aLFromT
-                        aStyles[ 2 ],   // aLFromL
-                        aStyles[ 3 ],   // aLFromB
-                        aStyles[ 4 ],   // aRFromT
-                        aStyles[ 5 ],   // aRFromR
-                        aStyles[ 6 ],   // aRFromB
-                        pTmpColor
-                        )
-                    );
-                }
-                else
-                {
-                    mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
-                        aPaintEnd,
-                        aPaintStart,
-                        aStyles[ 0 ],   // current style
-                        aStyles[ 4 ],   // aBFromL
-                        aStyles[ 5 ],   // aBFromB
-                        aStyles[ 6 ],   // aBFromR
-                        aStyles[ 1 ],   // aTFromL
-                        aStyles[ 2 ],   // aTFromT
-                        aStyles[ 3 ],   // aTFromR
-                        pTmpColor
-                        )
-                    );
-                }
+            // Here comes the painting stuff: Thank you, DR, great job!!!
+            if (bHori)
+            {
+                mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
+                    aPaintStart,
+                    aPaintEnd,
+                    aStyles[ 0 ],   // current style
+                    aStyles[ 1 ],   // aLFromT
+                    aStyles[ 2 ],   // aLFromL
+                    aStyles[ 3 ],   // aLFromB
+                    aStyles[ 4 ],   // aRFromT
+                    aStyles[ 5 ],   // aRFromR
+                    aStyles[ 6 ],   // aRFromB
+                    pTmpColor)
+                );
+            }
+            else
+            {
+                mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
+                    aPaintEnd,
+                    aPaintStart,
+                    aStyles[ 0 ],   // current style
+                    aStyles[ 4 ],   // aBFromL
+                    aStyles[ 5 ],   // aBFromB
+                    aStyles[ 6 ],   // aBFromR
+                    aStyles[ 1 ],   // aTFromL
+                    aStyles[ 2 ],   // aTFromT
+                    aStyles[ 3 ],   // aTFromR
+                    pTmpColor)
+                );
             }
         }
 
@@ -2759,6 +2806,54 @@ void SwTabFrmPainter::FindStylesForLine( const Point& rStartPoint,
     }
 }
 
+namespace {
+
+void calcOffsetForDoubleLine( SwLineEntryMap& rLines )
+{
+    SwLineEntryMap aNewLines;
+    SwLineEntryMap::iterator it = rLines.begin(), itEnd = rLines.end();
+    bool bFirst = true;
+    for (; it != itEnd; ++it)
+    {
+        if (bFirst)
+        {
+            // First line needs to be offset to account for double line thickness.
+            SwLineEntrySet aNewSet;
+            const SwLineEntrySet& rSet = it->second;
+            SwLineEntrySet::iterator itSet = rSet.begin(), itSetEnd = rSet.end();
+            size_t nEntryCount = rSet.size();
+            for (size_t i = 0; itSet != itSetEnd; ++itSet, ++i)
+            {
+                SwLineEntry aLine = *itSet;
+                aLine.mnOffset = static_cast<SwTwips>(aLine.maAttribute.Dist());
+                aLine.mbOffsetPerp = true;
+
+                if (i == 0)
+                    aLine.mbOffsetStart = true;
+                if (i == nEntryCount - 1)
+                    aLine.mbOffsetEnd = true;
+
+                aNewSet.insert(aLine);
+            }
+
+            aNewLines.insert(SwLineEntryMap::value_type(it->first, aNewSet));
+        }
+        else
+            aNewLines.insert(SwLineEntryMap::value_type(it->first, it->second));
+
+        bFirst = false;
+    }
+    rLines.swap(aNewLines);
+}
+
+}
+
+void SwTabFrmPainter::AdjustTopLeftFrames()
+{
+    calcOffsetForDoubleLine(maHoriLines);
+    calcOffsetForDoubleLine(maVertLines);
+}
+
 // special case: #i9860#
 // first line in follow table without repeated headlines
 static bool lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines(
@@ -2792,10 +2887,16 @@ void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem )
     bool const bVert = mrTabFrm.IsVertical();
     bool const bR2L  = mrTabFrm.IsRightToLeft();
 
-    svx::frame::Style aL( rBoxItem.GetLeft() );
-    svx::frame::Style aR( rBoxItem.GetRight() );
-    svx::frame::Style aT( rBoxItem.GetTop() );
-    svx::frame::Style aB( rBoxItem.GetBottom() );
+    SwViewShell* pViewShell = mrTabFrm.getRootFrm()->GetCurrShell();
+    OutputDevice* pOutDev = pViewShell->GetOut();
+    const MapMode& rMapMode = pOutDev->GetMapMode();
+    const Fraction& rFracX = rMapMode.GetScaleX();
+    const Fraction& rFracY = rMapMode.GetScaleY();
+
+    svx::frame::Style aL(rBoxItem.GetLeft(), rFracX);
+    svx::frame::Style aR(rBoxItem.GetRight(), rFracY);
+    svx::frame::Style aT(rBoxItem.GetTop(), rFracX);
+    svx::frame::Style aB(rBoxItem.GetBottom(), rFracY);
 
     aR.MirrorSelf();
     aB.MirrorSelf();
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 5840f95..d9d646e 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -651,6 +651,7 @@ namespace xmloff { namespace token {
         TOKEN( "dotted",                          XML_DOTTED ),
         TOKEN( "double",                          XML_DOUBLE ),
         TOKEN( "double-sided",                    XML_DOUBLE_SIDED ),
+        TOKEN( "double-thin",                     XML_DOUBLE_THIN ),
         TOKEN( "down",                            XML_DOWN ),
         TOKEN( "draft",                           XML_DRAFT ),
         TOKEN( "draw",                            XML_DRAW ),
diff --git a/xmloff/source/style/bordrhdl.cxx b/xmloff/source/style/bordrhdl.cxx
index 36c4dea..e0c7be5 100644
--- a/xmloff/source/style/bordrhdl.cxx
+++ b/xmloff/source/style/bordrhdl.cxx
@@ -24,6 +24,7 @@
 #include <rtl/ustrbuf.hxx>
 #include <com/sun/star/uno/Any.hxx>
 #include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/table/BorderLineStyle.hpp>
 
 using namespace ::com::sun::star;
 using namespace ::xmloff::token;
@@ -55,18 +56,19 @@ const sal_uInt16 API_LINE_NONE = USHRT_MAX;
 
 SvXMLEnumMapEntry pXML_BorderStyles[] =
 {
-    { XML_NONE,                 API_LINE_NONE   },
-    { XML_HIDDEN,               API_LINE_NONE   },
-    { XML_SOLID,                API_LINE_SOLID  },
-    { XML_DOUBLE,               API_LINE_DOUBLE },
-    { XML_DOTTED,               API_LINE_DOTTED },
-    { XML_DASHED,               API_LINE_DASHED },
-    { XML_GROOVE,               API_LINE_ENGRAVED },
-    { XML_RIDGE,                API_LINE_EMBOSSED },
-    { XML_INSET,                API_LINE_INSET  },
-    { XML_OUTSET,               API_LINE_OUTSET },
-    { XML_FINE_DASHED,          API_LINE_FINE_DASHED },
-    { XML_TOKEN_INVALID,        0 }
+    { XML_NONE,          table::BorderLineStyle::NONE   },
+    { XML_HIDDEN,        table::BorderLineStyle::NONE   },
+    { XML_SOLID,         table::BorderLineStyle::SOLID  },
+    { XML_DOUBLE,        table::BorderLineStyle::DOUBLE },
+    { XML_DOUBLE_THIN,   table::BorderLineStyle::DOUBLE_THIN },
+    { XML_DOTTED,        table::BorderLineStyle::DOTTED },
+    { XML_DASHED,        table::BorderLineStyle::DASHED },
+    { XML_GROOVE,        table::BorderLineStyle::ENGRAVED },
+    { XML_RIDGE,         table::BorderLineStyle::EMBOSSED },
+    { XML_INSET,         table::BorderLineStyle::INSET  },
+    { XML_OUTSET,        table::BorderLineStyle::OUTSET },
+    { XML_FINE_DASHED,   table::BorderLineStyle::FINE_DASHED },
+    { XML_TOKEN_INVALID, 0 }
 };
 
 SvXMLEnumMapEntry pXML_NamedBorderWidths[] =
@@ -151,13 +153,14 @@ bool XMLBorderWidthHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValu
     bool bDouble = false;
     switch ( aBorderLine.LineStyle )
     {
-        case API_LINE_DOUBLE:
-        case API_LINE_THINTHICK_SMALLGAP:
-        case API_LINE_THINTHICK_MEDIUMGAP:
-        case API_LINE_THINTHICK_LARGEGAP:
-        case API_LINE_THICKTHIN_SMALLGAP:
-        case API_LINE_THICKTHIN_MEDIUMGAP:
-        case API_LINE_THICKTHIN_LARGEGAP:
+        case table::BorderLineStyle::DOUBLE:
+        case table::BorderLineStyle::DOUBLE_THIN:
+        case table::BorderLineStyle::THINTHICK_SMALLGAP:
+        case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
+        case table::BorderLineStyle::THINTHICK_LARGEGAP:
+        case table::BorderLineStyle::THICKTHIN_SMALLGAP:
+        case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
+        case table::BorderLineStyle::THICKTHIN_LARGEGAP:
             bDouble = true;
             break;
         default:
@@ -339,7 +342,10 @@ bool XMLBorderHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, co
             case API_LINE_FINE_DASHED:
                 eStyleToken = XML_FINE_DASHED;
                 break;
-            case API_LINE_SOLID:
+            case table::BorderLineStyle::DOUBLE_THIN:
+                eStyleToken = XML_DOUBLE_THIN;
+                break;
+            case table::BorderLineStyle::SOLID:
             default:
                 break;
         }
commit 46df72612da749dc6d58bad0f33c0f9e82d389b3
Author: Ahmad H. Al Harthi <aalharthi at kacst.edu.sa>
Date:   Sun Mar 2 12:53:14 2014 +0300

    fdo#59329 Fix docked window border lines
    
    This patch completes the missing border lines. This is intended
    for versions 4.1 and 4.2 only.
    
    Change-Id: Ib15cb3b01dca4631f643a0036475cf684793d256
    Reviewed-on: https://gerrit.libreoffice.org/8411
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/source/window/splitwin.cxx b/vcl/source/window/splitwin.cxx
index b23a65d..fdadc8e 100644
--- a/vcl/source/window/splitwin.cxx
+++ b/vcl/source/window/splitwin.cxx
@@ -179,23 +179,43 @@ void SplitWindow::ImplDrawBorder( SplitWindow* pWin )
         {
         case WINDOWALIGN_BOTTOM:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( 0, 6 ), Point( nDX-1, 6 ) );
             pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
+            pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
+
+            pWin->SetLineColor( rStyleSettings.GetLightColor() );
+            pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
+            pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
             break;
         case WINDOWALIGN_TOP:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+            pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
+            pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
+
+            pWin->SetLineColor( rStyleSettings.GetLightColor() );
             pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
-            pWin->DrawLine( Point( 0, nDY-7 ), Point( nDX-1, nDY-7 ) );
+            pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
             break;
         case WINDOWALIGN_LEFT:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-1 ) );
-            pWin->DrawLine( Point( nDX-8, 0 ), Point( nDX-8, nDY-1 ) );
+            pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-2 ) );
+            pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
+            pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
+
+            pWin->SetLineColor( rStyleSettings.GetLightColor() );
+            pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
+            pWin->DrawLine( Point( 0, 1 ), Point( nDX-3, 1 ) );
+            pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-2, nDY-1 ) );
             break;
         default:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
-            pWin->DrawLine( Point( 6, 0 ), Point( 6, nDY-1 ) );
+            pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-2 ) );
+            pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
+            pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
+
+            pWin->SetLineColor( rStyleSettings.GetLightColor() );
+            pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
+            pWin->DrawLine( Point( 1, 1 ), Point( nDX-1, 1 ) );
+            pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
         }
     }
 }
@@ -214,27 +234,31 @@ void SplitWindow::ImplDrawBorderLine( SplitWindow* pWin )
         {
         case WINDOWALIGN_LEFT:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, nDY-3 ) );
+            pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, nDY-2 ) );
+
             pWin->SetLineColor( rStyleSettings.GetLightColor() );
-            pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN, nDY-4 ) );
+            pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN, nDY-3 ) );
             break;
         case WINDOWALIGN_RIGHT:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( SPLITWIN_SPLITSIZEEXLN-1, nDY-3 ) );
+            pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( SPLITWIN_SPLITSIZEEXLN-1, nDY-2 ) );
+
             pWin->SetLineColor( rStyleSettings.GetLightColor() );
-            pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN, 1 ), Point( SPLITWIN_SPLITSIZEEXLN, nDY-4 ) );
+            pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN, 1 ), Point( SPLITWIN_SPLITSIZEEXLN, nDY-3 ) );
             break;
         case WINDOWALIGN_TOP:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-3, nDY-SPLITWIN_SPLITSIZEEXLN-1 ) );
+            pWin->DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-1, nDY-SPLITWIN_SPLITSIZEEXLN-1 ) );
+
             pWin->SetLineColor( rStyleSettings.GetLightColor() );
-            pWin->DrawLine( Point( 1, nDY-SPLITWIN_SPLITSIZEEXLN ), Point( nDX-4, nDY-SPLITWIN_SPLITSIZEEXLN ) );
+            pWin->DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN ), Point( nDX-1, nDY-SPLITWIN_SPLITSIZEEXLN ) );
             break;
         case WINDOWALIGN_BOTTOM:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( 0, SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-3, SPLITWIN_SPLITSIZEEXLN-1 ) );
+            pWin->DrawLine( Point( 0, 5 ), Point( nDX-1, 5 ) );
+
             pWin->SetLineColor( rStyleSettings.GetLightColor() );
-            pWin->DrawLine( Point( 1, SPLITWIN_SPLITSIZEEXLN ), Point( nDX-4, SPLITWIN_SPLITSIZEEXLN ) );
+            pWin->DrawLine( Point( 0, SPLITWIN_SPLITSIZEEXLN ), Point( nDX-1, SPLITWIN_SPLITSIZEEXLN ) );
             break;
         }
     }
commit 39711c9f7dda4b992d8adf090e6c3bb7e130b5f1
Author: Ahmad H. Al Harthi <aalharthi at kacst.edu.sa>
Date:   Tue Feb 11 11:19:16 2014 +0300

    fdo#59329 fix docked panels borders
    
    Change-Id: Ia918d644fb57d6fbaeef90c8c1a6806a8d7e589c
    Reviewed-on: https://gerrit.libreoffice.org/8410
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/source/window/splitwin.cxx b/vcl/source/window/splitwin.cxx
index 8937527..b23a65d 100644
--- a/vcl/source/window/splitwin.cxx
+++ b/vcl/source/window/splitwin.cxx
@@ -137,9 +137,9 @@ static void ImplCalcBorder( WindowAlign eAlign, sal_Bool bNoAlign,
             rBottom = 0;
             break;
         case WINDOWALIGN_LEFT:
-            rLeft   = 2;
+            rLeft   = 0;
             rTop    = 2;
-            rRight  = 0;
+            rRight  = 2;
             rBottom = 2;
             break;
         case WINDOWALIGN_BOTTOM:
@@ -179,48 +179,23 @@ void SplitWindow::ImplDrawBorder( SplitWindow* pWin )
         {
         case WINDOWALIGN_BOTTOM:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
-            pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
-            pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
-
-            pWin->SetLineColor( rStyleSettings.GetLightColor() );
-            pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
-            pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
-            pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
+            pWin->DrawLine( Point( 0, 6 ), Point( nDX-1, 6 ) );
+            pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
             break;
         case WINDOWALIGN_TOP:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
-            pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
-            pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-1 ) );
-
-            pWin->SetLineColor( rStyleSettings.GetLightColor() );
-            pWin->DrawLine( Point( 1, 1 ), Point( nDX-3, 1 ) );
-            pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-1 ) );
-            pWin->DrawLine( Point( nDX-1, 1 ), Point( nDX-1, nDY-1 ) );
+            pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
+            pWin->DrawLine( Point( 0, nDY-7 ), Point( nDX-1, nDY-7 ) );
             break;
         case WINDOWALIGN_LEFT:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
-            pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
-            pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
-
-            pWin->SetLineColor( rStyleSettings.GetLightColor() );
-            pWin->DrawLine( Point( 1, 1 ), Point( nDX-1, 1 ) );
-            pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
-            pWin->DrawLine( Point( 1, nDY-1 ), Point( nDX-1, nDY-1 ) );
+            pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-1 ) );
+            pWin->DrawLine( Point( nDX-8, 0 ), Point( nDX-8, nDY-1 ) );
             break;
         default:
             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
-            pWin->DrawLine( Point( 0, 0 ), Point( nDX-2, 0 ) );
-            pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
-            pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
-
-            pWin->SetLineColor( rStyleSettings.GetLightColor() );
-            pWin->DrawLine( Point( 0, 1 ), Point( nDX-3, 1 ) );
-            pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
-            pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
-            break;
+            pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
+            pWin->DrawLine( Point( 6, 0 ), Point( 6, nDY-1 ) );
         }
     }
 }
@@ -1648,7 +1623,7 @@ void SplitWindow::ImplSplitMousePos( Point& rMousePos )
 
 void SplitWindow::ImplGetButtonRect( Rectangle& rRect, long nEx, sal_Bool bTest ) const
 {
-    long nSplitSize = mpMainSet->mnSplitSize-2;
+    long nSplitSize = mpMainSet->mnSplitSize-1;
     if ( mbAutoHide || mbFadeOut || mbFadeIn )
         nSplitSize += SPLITWIN_SPLITSIZEEX;
 
@@ -1998,7 +1973,7 @@ void SplitWindow::ImplDrawGrip( const Rectangle& rRect, sal_Bool bHorz, sal_Bool
         int height = (int) (0.5 * rRect.getHeight() + 0.5);
         int i = rRect.Top() + (rRect.getHeight() - height) / 2;
         height += i;
-        const int x = rRect.Left() + 1;
+        const int x = rRect.Left() + 2;
         ImplDrawFadeArrow( Point( x, i-8), bHorz, bLeft );
         while( i <= height )
         {
commit 8975a85896734a86c2110730bb864aeb50f90abf
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Feb 27 08:54:57 2014 +0000

    fdo#45935: try hard to paint a frame for menus
    
    Current Oxygen theme doesn't draw frames for menus, but uses shaped
    and "colored" background images. This workaround paints the window
    and menu frame for menus. Any frame seems to be better then no frame
    at all.
    
    Change-Id: I4d553ea58cac2729826f8395cb2597fa200187b6
    (cherry picked from commit e72849cd435cc50a744dcbcfb422f5600dd0cce9)
    Reviewed-on: https://gerrit.libreoffice.org/8436
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/unx/kde4/KDEData.cxx b/vcl/unx/kde4/KDEData.cxx
index 196f186..ccbbd99 100644
--- a/vcl/unx/kde4/KDEData.cxx
+++ b/vcl/unx/kde4/KDEData.cxx
@@ -17,10 +17,18 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#define Region QtXRegion
+
+#include <QStyle>
+#include <kapplication.h>
+
+#undef Region
+
 #include "KDEData.hxx"
 
 #include "KDEXLib.hxx"
 
+
 KDEData::~KDEData()
 {
 }
@@ -39,6 +47,15 @@ void KDEData::initNWF()
     pSVData->maNWFData.mbDockingAreaSeparateTB = true;
     // no borders for menu, theming does that
     pSVData->maNWFData.mbFlatMenu = true;
+
+    // Styled menus need additional space
+    QStyle *style = kapp->style();
+    pSVData->maNWFData.mnMenuFormatBorderX =
+       style->pixelMetric( QStyle::PM_MenuPanelWidth ) +
+       style->pixelMetric( QStyle::PM_MenuHMargin );
+    pSVData->maNWFData.mnMenuFormatBorderY =
+       style->pixelMetric( QStyle::PM_MenuPanelWidth ) +
+       style->pixelMetric( QStyle::PM_MenuVMargin );
 }
 
 void KDEData::deInitNWF()
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index cf72dcd..967864f 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -78,7 +78,7 @@ QRect region2QRect( const Rectangle& rControlRegion )
 }
 
 KDESalGraphics::KDESalGraphics() :
-    m_image(0)
+    m_image(NULL)
 {
 }
 
@@ -130,13 +130,7 @@ sal_Bool KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart
     if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA) )
         return true;
 
-    if ( (type == CTRL_PROGRESS)    && (part == PART_ENTIRE_CONTROL) ) return true;
-
-    return false;
-
-    if ( (type == CTRL_TAB_ITEM) && (part == PART_ENTIRE_CONTROL) ) return true;
-    if ( (type == CTRL_TAB_PANE) && (part == PART_ENTIRE_CONTROL) ) return true;
-    // no CTRL_TAB_BODY for KDE
+    if ( (type == CTRL_PROGRESS) && (part == PART_ENTIRE_CONTROL) ) return true;
 
     return false;
 }
@@ -378,8 +372,10 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
         {
             QStyleOptionMenuItem option;
             draw( QStyle::PE_PanelMenu, &option, m_image, vclStateValue2StateFlag( nControlState, value ));
+            // Try hard to get any frame!
             QStyleOptionFrame frame;
             draw( QStyle::PE_FrameMenu, &frame, m_image, vclStateValue2StateFlag( nControlState, value ));
+            draw( QStyle::PE_FrameWindow, &frame, m_image, vclStateValue2StateFlag( nControlState, value ));
             lastPopupRect = widgetRect;
         }
         else
commit 5c1236fe2dd4a7a0aeca40487788af095429e64b
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Feb 26 18:19:11 2014 +0000

    fdo#74416: sleep in yield for native file picker
    
    As it seems to be the only way to poll the clipboard, reintroduce
    
     m_pApplication->clipboard()->setProperty(
        "useEventLoopWhenWaiting", true );
    
    To prevent crashes, disable event processing in the Qt thread while
    the dialog is open.
    
    Instead this applies the same workaround as the Windows backend to
    sleep a ms, which keeps the FP dialogs more usable, but feels like
    a horrible workaround.
    
    This is still slower then running processEvent in Yield but still
    much better then the current situation.
    
    (cherry picked from commit 380f3b4b6cbbe8e82b58ddf55e95c5005307b51f)
    
    Change-Id: I10c422f1c0d7448d4a7ad28e57a32ed2cb42f48f
    Reviewed-on: https://gerrit.libreoffice.org/8435
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index b3fde26..405eafe 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -38,6 +38,7 @@
 
 #include "KDE4FilePicker.hxx"
 #include "FPServiceInfo.hxx"
+#include "KDEXLib.hxx"
 
 /* ********* Hack, but needed because of conflicting types... */
 #define Region QtXRegion
@@ -113,10 +114,11 @@ QString toQString(const OUString& s)
 // KDE4FilePicker
 //////////////////////////////////////////////////////////////////////////
 
-KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& )
+KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>&, KDEXLib *xlib )
     : KDE4FilePicker_Base(_helperMutex)
     , _resMgr( ResMgr::CreateResMgr("fps_office") )
     , allowRemoteUrls( false )
+    , _mXLib( xlib )
 {
     _extraControls = new QWidget();
     _layout = new QGridLayout(_extraControls);
@@ -261,8 +263,11 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
     _dialog->filterWidget()->setEditable(false);
 
     // We're entering a nested loop.
-    // Release the yield mutex to prevent deadlocks.
+    // Prevent yield calls, which would crash LO.
+
+    _mXLib->freezeYield( true );
     int result = _dialog->exec();
+    _mXLib->freezeYield( false );
 
     // HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings
     // (such as the auto-extension flag), but that doesn't update KGlobal::config()
diff --git a/vcl/unx/kde4/KDE4FilePicker.hxx b/vcl/unx/kde4/KDE4FilePicker.hxx
index 6dc97df..81acf0c 100644
--- a/vcl/unx/kde4/KDE4FilePicker.hxx
+++ b/vcl/unx/kde4/KDE4FilePicker.hxx
@@ -40,6 +40,7 @@
 class KFileDialog;
 class QWidget;
 class QLayout;
+class KDEXLib;
 
 class ResMgr;
 
@@ -82,8 +83,10 @@ protected:
 
     bool allowRemoteUrls;
 
+    KDEXLib* _mXLib;
+
 public:
-    KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& );
+    KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&, KDEXLib* );
     virtual ~KDE4FilePicker();
 
     // XFilePickerNotifier
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 7c67e35..b4be6d6 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -64,7 +64,8 @@
 KDEXLib::KDEXLib() :
     SalXLib(),  m_bStartupDone(false), m_pApplication(0),
     m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
-    eventLoopType( LibreOfficeEventLoop )
+    eventLoopType( LibreOfficeEventLoop ),
+    m_bYieldFrozen( false )
 {
     // the timers created here means they belong to the main thread
     connect( &timeoutTimer, SIGNAL( timeout()), this, SLOT( timeoutActivated()));
@@ -225,6 +226,7 @@ void KDEXLib::setupEventLoop()
         eventLoopType = GlibEventLoop;
         old_gpoll = g_main_context_get_poll_func( NULL );
         g_main_context_set_poll_func( NULL, gpoll_wrapper );
+        m_pApplication->clipboard()->setProperty( "useEventLoopWhenWaiting", true );
         return;
     }
 #endif
@@ -308,6 +310,17 @@ void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
         return SalXLib::Yield( bWait, bHandleAllCurrentEvents );
     }
 
+    if( m_bYieldFrozen ) {
+        if( qApp->thread() != QThread::currentThread() ) {
+            QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance( qApp->thread() );
+            if( dispatcher->hasPendingEvents() ) {
+                struct timespec delay = {0, ( 1000000 )};
+                nanosleep(&delay, NULL);
+            }
+        }
+        return;
+    }
+
     // if we are the main thread (which is where the event processing is done),
     // good, just do it
     if( qApp->thread() == QThread::currentThread()) {
@@ -425,7 +438,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
         SalYieldMutexReleaser aReleaser;
         return Q_EMIT createFilePickerSignal( xMSF );
     }
-    return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) );
+    return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF, this ) );
 }
 
 #include "KDEXLib.moc"
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index d9bd4d6..d07b9f6 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -52,6 +52,7 @@ class KDEXLib : public QObject, public SalXLib
         QTimer timeoutTimer;
         QTimer userEventTimer;
         enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
+        bool m_bYieldFrozen;
 
     private:
         void setupEventLoop();
@@ -84,6 +85,7 @@ class KDEXLib : public QObject, public SalXLib
         virtual void Wakeup();
         virtual void PostUserEvent();
 
+        void freezeYield(bool freeze) { m_bYieldFrozen = freeze; }
         void doStartup();
 
     public Q_SLOTS:
commit eb66d534b78c471ebbffe960d7df5a683a7e8f8e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Feb 27 09:55:18 2014 +0000

    coverity#704633 Dereference after null check
    
    (cherry picked from commit ccf0f7ef03bf98831a3e21b4b1327673a590b918)
    
    Change-Id: I4985249110da93ba67881dcd1c8cd1dc66ae08e2
    Reviewed-on: https://gerrit.libreoffice.org/8379
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/extensions/source/propctrlr/browserlistbox.cxx b/extensions/source/propctrlr/browserlistbox.cxx
index fa6bfcc..9a8cf37 100644
--- a/extensions/source/propctrlr/browserlistbox.cxx
+++ b/extensions/source/propctrlr/browserlistbox.cxx
@@ -1196,11 +1196,12 @@ namespace pcr
                 // So, we manually switch this to read-only.
                 if ( xControl.is() && ( xControl->getControlType() == PropertyControlType::Unknown ) )
                 {
-                    Edit* pControlWindowAsEdit = dynamic_cast< Edit* >( rLine.pLine->getControlWindow() );
-                    if ( pControlWindowAsEdit )
-                        pControlWindowAsEdit->SetReadOnly( sal_True );
+                    Window *pWindow = rLine.pLine->getControlWindow();
+                    Edit* pControlWindowAsEdit = dynamic_cast<Edit*>(pWindow);
+                    if (pControlWindowAsEdit)
+                        pControlWindowAsEdit->SetReadOnly(sal_True);
                     else
-                        pControlWindowAsEdit->Enable( sal_False );
+                        pWindow->Enable(sal_False);
                 }
             }
         }
commit 5b4f4ad23d6c7369fb587b16076e78c74b609bd7
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Mar 4 14:47:13 2014 +0100

    bnc#821208 DOC import: don't overwrite WW8Num* character styles
    
    In general we're overwriting styles on import in case we're not pasting.
    But these WW8Num* character styles are in general not from the document,
    they are created because Writer needs a character style for each
    numbering level to handle what's in the DOC file.
    
    So, in case there is a character style with the same name as our
    "character style for numbering" styles, prefer the later ones, as that's
    intended most likely.
    
    Change-Id: I675f867722360aca765bb96b0b43ea47deab9847
    (cherry picked from commit e88ee8aa307ecec1cc22cda56b97dcfd8b838ce8)
    Reviewed-on: https://gerrit.libreoffice.org/8448
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/qa/extras/ww8import/data/bnc821208.doc b/sw/qa/extras/ww8import/data/bnc821208.doc
new file mode 100755
index 0000000..d89d711
Binary files /dev/null and b/sw/qa/extras/ww8import/data/bnc821208.doc differ
diff --git a/sw/qa/extras/ww8import/ww8import.cxx b/sw/qa/extras/ww8import/ww8import.cxx
index 0c3e1fc..cc107e0 100644
--- a/sw/qa/extras/ww8import/ww8import.cxx
+++ b/sw/qa/extras/ww8import/ww8import.cxx
@@ -234,6 +234,15 @@ DECLARE_WW8IMPORT_TEST(testListNolevel, "list-nolevel.doc")
     CPPUNIT_ASSERT_EQUAL(OUString("1."), aText);
 }
 
+DECLARE_WW8IMPORT_TEST(testBnc821208, "bnc821208.doc")
+{
+    // WW8Num1z0 earned a Symbol font, turning numbers into rectangles.
+    uno::Reference<beans::XPropertyState> xPropertyState(getStyles("CharacterStyles")->getByName("WW8Num1z0"), uno::UNO_QUERY);
+    beans::PropertyState ePropertyState = xPropertyState->getPropertyState("CharFontName");
+    // This was beans::PropertyState_DIRECT_VALUE.
+    CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DEFAULT_VALUE, ePropertyState);
+}
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index 4d454e1..f94e055 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -3750,6 +3750,11 @@ bool WW8RStyle::PrepareStyle(SwWW8StyInf &rSI, ww::sti eSti, sal_uInt16 nThisSty
     }
 
     bool bImport = !bStyExist || pIo->mbNewDoc; // import content ?
+
+    // Do not override character styles the list import code created earlier.
+    if (bImport && bStyExist && rSI.GetOrgWWName().startsWith("WW8Num"))
+        bImport = false;
+
     bool bOldNoImp = pIo->bNoAttrImport;
     rSI.bImportSkipped = !bImport;
 
commit 66e322c32d270288a2cb93bf01599c79789b36d5
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Mar 4 17:59:45 2014 +0100

    filter: make LibXSLTTransformer init backward compatible
    
    As reported by Fernand Vanrie, initializing the XSLT service can fail
    because the LibXSLTTransformer::initialize was changed to require
    the parameters as a nested Sequence; accept previous parameter
    convention as a fall-back.
    
    (regression from ca0ea73a4ab104031a16b5bac7a9bb6e57c77ba0)
    
    (cherry picked from commit 6967da019b69767a15116de101d33a16b95c8a44)
    
    filter: and we learn that BootstrapFixture requires boost headers
    (cherry picked from commit bfdd18eb35f5c8bf7f713910ec35b853c7456969)
    
    filter: don't wait forever if the xslt test fails
    (cherry picked from commit 8af7a8953248dd184cd620b934ee6abc147f4076)
    
    I imagine this should have a SAL_CALL decoration
    (cherry picked from commit 62d6252d2cde33f6ef0e627c3192a63d43ba2a87)
    
    filter: sigh... fix the xslt test to run on WNT too
    (cherry picked from commit 4fcd5534348adcb61ab85b93478c272b8d9e8f8c)
    
    Change-Id: I136e6e6338f11ffecf9f856f0736d1d0e6b17c3f
    Reviewed-on: https://gerrit.libreoffice.org/8451
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/filter/CppunitTest_filter_xslt.mk b/filter/CppunitTest_filter_xslt.mk
new file mode 100644
index 0000000..181f482
--- /dev/null
+++ b/filter/CppunitTest_filter_xslt.mk
@@ -0,0 +1,45 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,filter_xslt))
+
+$(eval $(call gb_CppunitTest_use_api,filter_xslt,\
+	offapi \
+	udkapi \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,filter_xslt))
+
+$(eval $(call gb_CppunitTest_use_configuration,filter_xslt))
+
+$(eval $(call gb_CppunitTest_use_external,filter_xslt,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_libraries,filter_xslt, \
+	comphelper \
+	test \
+	unotest \
+	cppuhelper \
+	cppu \
+	sal \
+	$(gb_UWINAPI) \
+))
+
+$(eval $(call gb_CppunitTest_use_components,filter_xslt,\
+	configmgr/source/configmgr \
+	filter/source/xsltfilter/xsltfilter \
+	i18npool/util/i18npool \
+	ucb/source/core/ucb1 \
+	ucb/source/ucp/file/ucpfile1 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,filter_xslt, \
+	filter/qa/cppunit/xslt-test \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/filter/Module_filter.mk b/filter/Module_filter.mk
index 403184a..e5d67e7 100644
--- a/filter/Module_filter.mk
+++ b/filter/Module_filter.mk
@@ -77,6 +77,10 @@ $(eval $(call gb_Module_add_targets,filter,\
 ))
 endif
 
+$(eval $(call gb_Module_add_check_targets,filter,\
+    CppunitTest_filter_xslt \
+))
+
 ifneq ($(DISABLE_CVE_TESTS),TRUE)
 $(eval $(call gb_Module_add_check_targets,filter,\
     CppunitTest_filter_pict_test \
diff --git a/filter/qa/cppunit/data/xslt/copy.xslt b/filter/qa/cppunit/data/xslt/copy.xslt
new file mode 100644
index 0000000..d46172a
--- /dev/null
+++ b/filter/qa/cppunit/data/xslt/copy.xslt
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="/">
+   <xsl:copy-of select="/"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/filter/qa/cppunit/xslt-test.cxx b/filter/qa/cppunit/xslt-test.cxx
new file mode 100644
index 0000000..509d37c
--- /dev/null
+++ b/filter/qa/cppunit/xslt-test.cxx
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <limits>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <sal/types.h>
+
+#include <rtl/ref.hxx>
+
+#include <osl/file.hxx>
+#include <osl/thread.h>
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/io/XStreamListener.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <com/sun/star/xml/xslt/XSLTTransformer.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <test/bootstrapfixture.hxx>
+
+
+using namespace std;
+using namespace ::com::sun::star;
+
+
+namespace {
+
+class XsltFilterTest
+    : public test::BootstrapFixture
+{
+public:
+    void testXsltCopyOld();
+    void testXsltCopyNew();
+
+    CPPUNIT_TEST_SUITE(XsltFilterTest);
+    CPPUNIT_TEST(testXsltCopyOld);
+    CPPUNIT_TEST(testXsltCopyNew);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+struct Listener : public ::cppu::WeakImplHelper1<io::XStreamListener>
+{
+    bool m_bDone;
+
+    Listener() : m_bDone(false) {}
+
+    virtual void SAL_CALL disposing(const lang::EventObject&) throw() SAL_OVERRIDE {}
+    virtual void SAL_CALL started() throw() SAL_OVERRIDE { m_bDone = false; }
+    virtual void SAL_CALL closed() throw() SAL_OVERRIDE { m_bDone = true; }
+    virtual void SAL_CALL terminated() throw() SAL_OVERRIDE { m_bDone = true; }
+    virtual void SAL_CALL error(const uno::Any& e) throw() SAL_OVERRIDE
+    {
+        (void)e;
+        m_bDone = true; // set on error too, otherwise main thread waits forever
+        CPPUNIT_FAIL("exception while in XSLT");
+    }
+};
+
+void XsltFilterTest::testXsltCopyNew()
+{
+    OUString tempDirURL;
+    osl_getTempDirURL(&tempDirURL.pData);
+    oslFileHandle tempFile;
+    OUString tempURL;
+    osl::File::RC rc = osl::File::createTempFile(0, &tempFile, &tempURL);
+    CPPUNIT_ASSERT(osl::FileBase::E_None == rc);
+    osl_closeFile(tempFile); // close it so xSFA can open it on WNT
+
+    OUString source(
+            getURLFromSrc("/filter/source/xsltfilter/xsltfilter.component"));
+    uno::Sequence<uno::Any> args(7);
+    args[0] <<= beans::NamedValue("StylesheetURL",
+        uno::makeAny(getURLFromSrc("/filter/qa/cppunit/data/xslt/copy.xslt")));
+    args[1] <<= beans::NamedValue("SourceURL", uno::makeAny(source));
+    args[2] <<= beans::NamedValue("TargetURL", uno::makeAny(tempURL));
+    args[3] <<= beans::NamedValue("SourceBaseURL",
+        uno::makeAny(getURLFromSrc("/filter/source/xsltfilter/")));
+    args[4] <<= beans::NamedValue("TargetBaseURL", uno::makeAny(tempDirURL));
+    args[5] <<= beans::NamedValue("SystemType", uno::makeAny(OUString()));
+    args[6] <<= beans::NamedValue("PublicType", uno::makeAny(OUString()));
+
+    uno::Reference<ucb::XSimpleFileAccess3> xSFA =
+        ucb::SimpleFileAccess::create(getComponentContext());
+
+    uno::Reference<io::XInputStream> xIn = xSFA->openFileRead(source);
+    uno::Reference<io::XOutputStream> xOut = xSFA->openFileWrite(tempURL);
+
+    rtl::Reference<Listener> xListener = new Listener();
+
+    uno::Reference<xml::xslt::XXSLTTransformer> xXslt(
+            xml::xslt::XSLTTransformer::create(getComponentContext(), args));
+
+    xXslt->addListener(uno::Reference<io::XStreamListener>(xListener.get()));
+    xXslt->setInputStream(xIn);
+    xXslt->setOutputStream(xOut);
+
+    xXslt->start();
+
+    TimeValue delay;
+    delay.Seconds = 0;
+    delay.Nanosec = 1000000;
+    while (!xListener->m_bDone) { osl_waitThread(&delay); }
+
+    xIn->closeInput();
+    xOut->closeOutput();
+
+    osl::File foo(tempURL); // apparently it's necessary to open it again?
+    foo.open(osl_File_OpenFlag_Read);
+    sal_uInt64 size(0);
+    foo.getSize(size);
+    CPPUNIT_ASSERT(size > 1000); // check that something happened
+}
+
+void XsltFilterTest::testXsltCopyOld()
+{
+    OUString tempDirURL;
+    osl_getTempDirURL(&tempDirURL.pData);
+    oslFileHandle tempFile;
+    OUString tempURL;
+    osl::File::RC rc = osl::File::createTempFile(0, &tempFile, &tempURL);
+    CPPUNIT_ASSERT(osl::FileBase::E_None == rc);
+    osl_closeFile(tempFile); // close it so xSFA can open it on WNT
+
+    OUString source(
+            getURLFromSrc("/filter/source/xsltfilter/xsltfilter.component"));
+    uno::Sequence<uno::Any> args(7);
+    args[0] <<= beans::NamedValue("StylesheetURL",
+        uno::makeAny(getURLFromSrc("/filter/qa/cppunit/data/xslt/copy.xslt")));
+    args[1] <<= beans::NamedValue("SourceURL", uno::makeAny(source));
+    args[2] <<= beans::NamedValue("TargetURL", uno::makeAny(tempURL));
+    args[3] <<= beans::NamedValue("SourceBaseURL",
+        uno::makeAny(getURLFromSrc("/filter/source/xsltfilter/")));
+    args[4] <<= beans::NamedValue("TargetBaseURL", uno::makeAny(tempDirURL));
+    args[5] <<= beans::NamedValue("SystemType", uno::makeAny(OUString()));
+    args[6] <<= beans::NamedValue("PublicType", uno::makeAny(OUString()));
+
+
+    uno::Reference<ucb::XSimpleFileAccess3> xSFA =
+        ucb::SimpleFileAccess::create(getComponentContext());
+
+    uno::Reference<io::XInputStream> xIn = xSFA->openFileRead(source);
+    uno::Reference<io::XOutputStream> xOut = xSFA->openFileWrite(tempURL);
+
+    rtl::Reference<Listener> xListener = new Listener();
+
+    uno::Reference<xml::xslt::XXSLTTransformer> xXslt(
+        getMultiServiceFactory()->createInstance(
+            "com.sun.star.comp.documentconversion.LibXSLTTransformer"),
+        uno::UNO_QUERY_THROW);
+
+    uno::Reference<lang::XInitialization> xInit(xXslt, uno::UNO_QUERY_THROW);
+    xInit->initialize(args);
+    xXslt->addListener(uno::Reference<io::XStreamListener>(xListener.get()));
+    xXslt->setInputStream(xIn);
+    xXslt->setOutputStream(xOut);
+
+    xXslt->start();
+
+    TimeValue delay;
+    delay.Seconds = 0;
+    delay.Nanosec = 1000000;
+    while (!xListener->m_bDone) { osl_waitThread(&delay); }
+
+    xIn->closeInput();
+    xOut->closeOutput();
+
+    osl::File foo(tempURL); // apparently it's necessary to open it again?
+    foo.open(osl_File_OpenFlag_Read);
+    sal_uInt64 size(0);
+    foo.getSize(size);
+    CPPUNIT_ASSERT(size > 1000); // check that something happened
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(XsltFilterTest);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx b/filter/source/xsltfilter/LibXSLTTransformer.cxx
index c0abb88..f7b2500 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.cxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx
@@ -478,7 +478,10 @@ namespace XSLT
             throw (RuntimeException)
     {
         Sequence<Any> params;
-        args[0] >>= params;
+        if (!(args[0] >>= params))
+        {   // backward compatibility for old clients using createInstance
+            params = args;
+        }
         xmlSubstituteEntitiesDefault(0);
         m_parameters.clear();
         for (int i = 0; i < params.getLength(); i++)


More information about the Libreoffice-commits mailing list