[Libreoffice-commits] core.git: include/svl include/svx offapi/com sd/qa sd/source svx/Library_svxcore.mk svx/source sw/inc sw/source xmloff/source

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Tue Jun 8 12:51:45 UTC 2021


 include/svl/solar.hrc                             |    2 
 include/svx/SvxXTextColumns.hxx                   |   22 +
 include/svx/svdotext.hxx                          |    4 
 include/svx/unoshprp.hxx                          |    6 
 offapi/com/sun/star/drawing/TextProperties.idl    |    8 
 sd/qa/unit/data/odg/two_columns.odg               |binary
 sd/qa/unit/export-tests.cxx                       |   69 ++++
 sd/source/core/stlsheet.cxx                       |   13 
 svx/Library_svxcore.mk                            |    1 
 svx/source/svdraw/svdotext.cxx                    |   20 +
 svx/source/unodraw/SvxXTextColumns.cxx            |  325 ++++++++++++++++++++++
 svx/source/unodraw/unomod.cxx                     |    5 
 svx/source/unodraw/unopool.cxx                    |    7 
 svx/source/unodraw/unoshape.cxx                   |   39 ++
 sw/inc/unomap.hxx                                 |   11 
 sw/inc/unosett.hxx                                |   65 ----
 sw/source/core/layout/atrfrm.cxx                  |  116 ++++++-
 sw/source/core/unocore/unocoll.cxx                |    3 
 sw/source/core/unocore/unomap.cxx                 |   17 -
 sw/source/core/unocore/unomap1.cxx                |    6 
 sw/source/core/unocore/unosett.cxx                |  291 -------------------
 xmloff/source/draw/XMLShapePropertySetContext.cxx |    3 
 xmloff/source/draw/sdpropls.cxx                   |    6 
 xmloff/source/text/XMLTextColumnsExport.cxx       |    2 
 xmloff/source/text/txtprhdl.cxx                   |    3 
 25 files changed, 637 insertions(+), 407 deletions(-)

New commits:
commit 95ebd24a629b4c8cd62cc20c0701683512cc8fa0
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Thu May 27 13:00:10 2021 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Tue Jun 8 14:50:55 2021 +0200

    editengine-columns: ODF support [API CHANGE]
    
    This uses existing ODF markup, as used by Writer's text frame:
    style::columns child element of style:graphic-properties, its
    fo:column-count and fo:column-gap attributes. No ODF extension
    is required.
    
    Since currently only columns with same width and spacing are
    implemented, without additional settings, style:column child
    elements are exported, but ignored on import.
    
    This adds new property to css::drawing::TextProperties service:
    TextColumns (of type css::text::XTextColumns).
    
    Change-Id: I7e63293e5814b281ceec8a9632e696322d3629e8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116035
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/include/svl/solar.hrc b/include/svl/solar.hrc
index 317d45a84bc1..521e24365f9f 100644
--- a/include/svl/solar.hrc
+++ b/include/svl/solar.hrc
@@ -23,7 +23,7 @@
 // defines ------------------------------------------------------------------
 
 #define OWN_ATTR_VALUE_START                    3900
-#define OWN_ATTR_VALUE_END                      4005
+#define OWN_ATTR_VALUE_END                      4006
 
 #define RID_LIB_START               10000
 #define RID_LIB_END                 19999
diff --git a/include/svx/SvxXTextColumns.hxx b/include/svx/SvxXTextColumns.hxx
new file mode 100644
index 000000000000..0dbc92ba9611
--- /dev/null
+++ b/include/svx/SvxXTextColumns.hxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/XInterface.hpp>
+
+#include <svx/svxdllapi.h>
+
+SVXCORE_DLLPUBLIC css::uno::Reference<css::uno::XInterface>
+SvxXTextColumns_createInstance() noexcept;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index 746d1d2de93e..360c8c72daac 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -439,8 +439,12 @@ public:
     SdrTextAniKind GetTextAniKind() const;
     SdrTextAniDirection GetTextAniDirection() const;
 
+    bool HasTextColumnsNumber() const;
     sal_Int16 GetTextColumnsNumber() const;
+    void SetTextColumnsNumber(sal_Int16 nColumns);
+    bool HasTextColumnsSpacing() const;
     sal_Int32 GetTextColumnsSpacing() const;
+    void SetTextColumnsSpacing(sal_Int32 nSpacing);
 
     // react on model/page change
     virtual void handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage) override;
diff --git a/include/svx/unoshprp.hxx b/include/svx/unoshprp.hxx
index c98b5b9eb433..3f61ce77c6d1 100644
--- a/include/svx/unoshprp.hxx
+++ b/include/svx/unoshprp.hxx
@@ -60,6 +60,7 @@
 #include <com/sun/star/drawing/TextureProjectionMode.hpp>
 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
 #include <com/sun/star/text/GraphicCrop.hpp>
+#include <com/sun/star/text/XTextColumns.hpp>
 #include <com/sun/star/drawing/BitmapMode.hpp>
 #include <com/sun/star/drawing/CameraGeometry.hpp>
 #include <com/sun/star/text/WritingMode.hpp>
@@ -193,7 +194,9 @@
 #define OWN_ATTR_SIGNATURELINE_IS_SIGNED        (OWN_ATTR_VALUE_START+103)
 #define OWN_ATTR_QRCODE                         (OWN_ATTR_VALUE_START+104)
 #define OWN_ATTR_TEXTFITTOSIZESCALE             (OWN_ATTR_VALUE_START+105)
-// ATTENTION: maximum is OWN_ATTR_VALUE_START+105 svx, see include/svl/solar.hrc
+#define OWN_ATTR_TEXTCOLUMNS                    (OWN_ATTR_VALUE_START+106)
+// ATTENTION: current maximum is OWN_ATTR_VALUE_START+106 svx; wnen adding values, update
+// OWN_ATTR_VALUE_END in include/svl/solar.hrc accordingly
 
 // #FontWork#
 #define FONTWORK_PROPERTIES \
@@ -316,6 +319,7 @@
     { u"" UNO_NAME_TEXT_VERTADJUST,       SDRATTR_TEXT_VERTADJUST,        cppu::UnoType<css::drawing::TextVerticalAdjust>::get(),    0,      0},\
     { u"" UNO_NAME_TEXT_WORDWRAP,         SDRATTR_TEXT_WORDWRAP,          cppu::UnoType<bool>::get(),        0,      0}, \
     { u"" UNO_NAME_TEXT_CHAINNEXTNAME,    SDRATTR_TEXT_CHAINNEXTNAME,     ::cppu::UnoType<OUString>::get(),        0,      0}, \
+    { u"TextColumns",                     OWN_ATTR_TEXTCOLUMNS,           cppu::UnoType<css::text::XTextColumns>::get(), 0, 0 }, \
     SVX_UNOEDIT_CHAR_PROPERTIES, \
     SVX_UNOEDIT_PARA_PROPERTIES,
 
diff --git a/offapi/com/sun/star/drawing/TextProperties.idl b/offapi/com/sun/star/drawing/TextProperties.idl
index 4516c9829781..40f8f89acd0a 100644
--- a/offapi/com/sun/star/drawing/TextProperties.idl
+++ b/offapi/com/sun/star/drawing/TextProperties.idl
@@ -40,6 +40,7 @@
 #include <com/sun/star/drawing/TextVerticalAdjust.idl>
 #include <com/sun/star/drawing/TextHorizontalAdjust.idl>
 #include <com/sun/star/text/WritingMode.idl>
+#include <com/sun/star/text/XTextColumns.idl>
 
 
  module com {  module sun {  module star {  module drawing {
@@ -249,6 +250,13 @@ published service TextProperties
     /** This value selects the writing mode for the text.
      */
     [property] ::com::sun::star::text::WritingMode TextWritingMode;
+
+
+    /** Column layout properties for the text.
+
+        @since LibreOffice 7.3
+     */
+    [optional, property] ::com::sun::star::text::XTextColumns TextColumns;
 };
 
 
diff --git a/sd/qa/unit/data/odg/two_columns.odg b/sd/qa/unit/data/odg/two_columns.odg
new file mode 100644
index 000000000000..bd721f0c0d86
Binary files /dev/null and b/sd/qa/unit/data/odg/two_columns.odg differ
diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx
index 0529178f43e9..7805b591b6ed 100644
--- a/sd/qa/unit/export-tests.cxx
+++ b/sd/qa/unit/export-tests.cxx
@@ -39,8 +39,10 @@
 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
 #include <com/sun/star/table/BorderLine2.hpp>
 #include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/text/XTextColumns.hpp>
 
 #include <svx/svdotable.hxx>
+#include <svx/unoapi.hxx>
 #include <vcl/filter/PDFiumLibrary.hxx>
 
 using namespace css;
@@ -89,6 +91,7 @@ public:
     void testTdf128550();
     void testTdf140714();
     void testMasterPageBackgroundFullSize();
+    void testColumnsODG();
 
     CPPUNIT_TEST_SUITE(SdExportTest);
 
@@ -132,6 +135,7 @@ public:
     CPPUNIT_TEST(testTdf128550);
     CPPUNIT_TEST(testTdf140714);
     CPPUNIT_TEST(testMasterPageBackgroundFullSize);
+    CPPUNIT_TEST(testColumnsODG);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -1571,6 +1575,71 @@ void SdExportTest::testMasterPageBackgroundFullSize()
     tempFile.EnableKillingFile();
 }
 
+void SdExportTest::testColumnsODG()
+{
+    auto xDocShRef
+        = loadURL(m_directories.getURLFromSrc(u"sd/qa/unit/data/odg/two_columns.odg"), ODG);
+
+    {
+        uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier = getDoc(xDocShRef);
+        uno::Reference<drawing::XDrawPages> xPages = xDrawPagesSupplier->getDrawPages();
+        uno::Reference<drawing::XDrawPage> xPage(xPages->getByIndex(0), uno::UNO_QUERY_THROW);
+        uno::Reference<container::XIndexAccess> xIndexAccess(xPage, uno::UNO_QUERY_THROW);
+        uno::Reference<drawing::XShape> xShape(xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW);
+        uno::Reference<beans::XPropertySet> xProps(xShape, uno::UNO_QUERY_THROW);
+        uno::Reference<text::XTextColumns> xCols(xProps->getPropertyValue("TextColumns"),
+                                                 uno::UNO_QUERY_THROW);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xCols->getColumnCount());
+        uno::Reference<beans::XPropertySet> xColProps(xCols, uno::UNO_QUERY_THROW);
+        CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(700)),
+                             xColProps->getPropertyValue("AutomaticDistance"));
+
+        auto pTextObj = dynamic_cast<SdrTextObj*>(GetSdrObjectFromXShape(xShape));
+        CPPUNIT_ASSERT(pTextObj);
+
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(2), pTextObj->GetTextColumnsNumber());
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(700), pTextObj->GetTextColumnsSpacing());
+    }
+
+    utl::TempFile tempFile;
+    xDocShRef = saveAndReload(xDocShRef.get(), ODG, &tempFile);
+
+    {
+        uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier = getDoc(xDocShRef);
+        uno::Reference<drawing::XDrawPages> xPages = xDrawPagesSupplier->getDrawPages();
+        uno::Reference<drawing::XDrawPage> xPage(xPages->getByIndex(0), uno::UNO_QUERY_THROW);
+        uno::Reference<container::XIndexAccess> xIndexAccess(xPage, uno::UNO_QUERY_THROW);
+        uno::Reference<drawing::XShape> xShape(xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW);
+        uno::Reference<beans::XPropertySet> xProps(xShape, uno::UNO_QUERY_THROW);
+        uno::Reference<text::XTextColumns> xCols(xProps->getPropertyValue("TextColumns"),
+                                                 uno::UNO_QUERY_THROW);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xCols->getColumnCount());
+        uno::Reference<beans::XPropertySet> xColProps(xCols, uno::UNO_QUERY_THROW);
+        CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(700)),
+                             xColProps->getPropertyValue("AutomaticDistance"));
+
+        auto pTextObj = dynamic_cast<SdrTextObj*>(GetSdrObjectFromXShape(xShape));
+        CPPUNIT_ASSERT(pTextObj);
+
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(2), pTextObj->GetTextColumnsNumber());
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(700), pTextObj->GetTextColumnsSpacing());
+    }
+
+    xDocShRef->DoClose();
+
+    xmlDocUniquePtr pXmlDoc = parseExport(tempFile, "content.xml");
+    assertXPath(pXmlDoc,
+                "/office:document-content/office:automatic-styles/style:style/"
+                "style:graphic-properties/style:columns",
+                "column-count", "2");
+    assertXPath(pXmlDoc,
+                "/office:document-content/office:automatic-styles/style:style/"
+                "style:graphic-properties/style:columns",
+                "column-gap", "0.7cm");
+
+    tempFile.EnableKillingFile();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdExportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/core/stlsheet.cxx b/sd/source/core/stlsheet.cxx
index 93bc3f0c8ac0..5b79e7333176 100644
--- a/sd/source/core/stlsheet.cxx
+++ b/sd/source/core/stlsheet.cxx
@@ -1186,6 +1186,19 @@ PropertyState SAL_CALL SdStyleSheet::getPropertyState( const OUString& PropertyN
             return PropertyState_AMBIGUOUS_VALUE;
         }
     }
+    else if (pEntry->nWID == OWN_ATTR_TEXTCOLUMNS)
+    {
+        const SfxItemSet& rSet = GetItemSet();
+
+        const auto eState1 = rSet.GetItemState(SDRATTR_TEXTCOLUMNS_NUMBER, false);
+        const auto eState2 = rSet.GetItemState(SDRATTR_TEXTCOLUMNS_SPACING, false);
+        if (eState1 == SfxItemState::SET || eState2 == SfxItemState::SET)
+            return PropertyState_DIRECT_VALUE;
+        else if (eState1 == SfxItemState::DEFAULT && eState2 == SfxItemState::DEFAULT)
+            return PropertyState_DEFAULT_VALUE;
+        else
+            return PropertyState_AMBIGUOUS_VALUE;
+    }
     else
     {
         SfxItemSet &rStyleSet = GetItemSet();
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index 20915ae573c9..8e596acd4605 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -390,6 +390,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
     svx/source/toolbars/fontworkbar \
     svx/source/unodraw/gluepts \
     svx/source/unodraw/shapepropertynotifier \
+    svx/source/unodraw/SvxXTextColumns \
     svx/source/unodraw/tableshape \
     svx/source/unodraw/unobrushitemhelper \
     svx/source/unodraw/unobtabl \
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index a5d9939a6103..27b514dc4ea9 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -1724,16 +1724,36 @@ SdrTextAniDirection SdrTextObj::GetTextAniDirection() const
     return GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION).GetValue();
 }
 
+bool SdrTextObj::HasTextColumnsNumber() const
+{
+    return GetObjectItemSet().HasItem(SDRATTR_TEXTCOLUMNS_NUMBER);
+}
+
 sal_Int16 SdrTextObj::GetTextColumnsNumber() const
 {
     return GetObjectItemSet().Get(SDRATTR_TEXTCOLUMNS_NUMBER).GetValue();
 }
 
+void SdrTextObj::SetTextColumnsNumber(sal_Int16 nColumns)
+{
+    SetObjectItem(SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, nColumns));
+}
+
+bool SdrTextObj::HasTextColumnsSpacing() const
+{
+    return GetObjectItemSet().HasItem(SDRATTR_TEXTCOLUMNS_SPACING);
+}
+
 sal_Int32 SdrTextObj::GetTextColumnsSpacing() const
 {
     return GetObjectItemSet().Get(SDRATTR_TEXTCOLUMNS_SPACING).GetValue();
 }
 
+void SdrTextObj::SetTextColumnsSpacing(sal_Int32 nSpacing)
+{
+    SetObjectItem(SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, nSpacing));
+}
+
 // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a
 // painting rectangle. Rotation is excluded from the returned values.
 GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle(
diff --git a/svx/source/unodraw/SvxXTextColumns.cxx b/svx/source/unodraw/SvxXTextColumns.cxx
new file mode 100644
index 000000000000..d245f071391b
--- /dev/null
+++ b/svx/source/unodraw/SvxXTextColumns.cxx
@@ -0,0 +1,325 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyVetoException.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/text/ColumnSeparatorStyle.hpp>
+#include <com/sun/star/text/XTextColumns.hpp>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/util/Color.hpp>
+
+#include <cppuhelper/supportsservice.hxx>
+#include <o3tl/safeint.hxx>
+#include <svl/itemprop.hxx>
+#include <svx/SvxXTextColumns.hxx>
+#include <tools/UnitConversion.hxx>
+#include <vcl/svapp.hxx>
+
+namespace
+{
+enum : sal_uInt16
+{
+    WID_TXTCOL_IS_AUTOMATIC,
+    WID_TXTCOL_AUTO_DISTANCE,
+    WID_TXTCOL_LINE_WIDTH,
+    WID_TXTCOL_LINE_COLOR,
+    WID_TXTCOL_LINE_REL_HGT,
+    WID_TXTCOL_LINE_ALIGN,
+    WID_TXTCOL_LINE_IS_ON,
+    WID_TXTCOL_LINE_STYLE,
+};
+
+SfxItemPropertyMapEntry const saTextColumns_Impl[] = {
+    { u"IsAutomatic", WID_TXTCOL_IS_AUTOMATIC, cppu::UnoType<bool>::get(),
+      css::beans::PropertyAttribute::READONLY, 0 },
+    { u"AutomaticDistance", WID_TXTCOL_AUTO_DISTANCE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
+    { u"SeparatorLineWidth", WID_TXTCOL_LINE_WIDTH, cppu::UnoType<sal_Int32>::get(), 0, 0 },
+    { u"SeparatorLineColor", WID_TXTCOL_LINE_COLOR,
+      cppu::UnoType<com::sun::star::util::Color>::get(), 0, 0 },
+    { u"SeparatorLineRelativeHeight", WID_TXTCOL_LINE_REL_HGT, cppu::UnoType<sal_Int32>::get(), 0,
+      0 },
+    { u"SeparatorLineVerticalAlignment", WID_TXTCOL_LINE_ALIGN,
+      cppu::UnoType<css::style::VerticalAlignment>::get(), 0, 0 },
+    { u"SeparatorLineIsOn", WID_TXTCOL_LINE_IS_ON, cppu::UnoType<bool>::get(), 0, 0 },
+    { u"SeparatorLineStyle", WID_TXTCOL_LINE_STYLE, cppu::UnoType<sal_Int16>::get(), 0, 0 },
+    { u"", 0, css::uno::Type(), 0, 0 },
+};
+
+class SvxXTextColumns final
+    : public cppu::WeakImplHelper<css::beans::XPropertySet, css::text::XTextColumns,
+                                  css::lang::XServiceInfo>
+{
+public:
+    SvxXTextColumns() = default;
+
+    // XTextColumns
+    virtual sal_Int32 SAL_CALL getReferenceValue() override;
+    virtual sal_Int16 SAL_CALL getColumnCount() override;
+    virtual void SAL_CALL setColumnCount(sal_Int16 nColumns) override;
+    virtual css::uno::Sequence<css::text::TextColumn> SAL_CALL getColumns() override;
+    virtual void SAL_CALL
+    setColumns(const css::uno::Sequence<css::text::TextColumn>& Columns) override;
+
+    // XPropertySet
+    virtual css::uno::Reference<css::beans::XPropertySetInfo>
+        SAL_CALL getPropertySetInfo() override;
+    virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName,
+                                           const css::uno::Any& aValue) override;
+    virtual css::uno::Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
+    virtual void SAL_CALL addPropertyChangeListener(
+        const OUString& aPropertyName,
+        const css::uno::Reference<css::beans::XPropertyChangeListener>& xListener) override;
+    virtual void SAL_CALL removePropertyChangeListener(
+        const OUString& aPropertyName,
+        const css::uno::Reference<css::beans::XPropertyChangeListener>& aListener) override;
+    virtual void SAL_CALL addVetoableChangeListener(
+        const OUString& PropertyName,
+        const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override;
+    virtual void SAL_CALL removeVetoableChangeListener(
+        const OUString& PropertyName,
+        const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override;
+
+    // XServiceInfo
+    virtual OUString SAL_CALL getImplementationName() override;
+    virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
+    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+private:
+    sal_Int32 m_nReference = USHRT_MAX;
+    css::uno::Sequence<css::text::TextColumn> m_aTextColumns;
+    bool m_bIsAutomaticWidth = true;
+    sal_Int32 m_nAutoDistance = 0;
+
+    const SfxItemPropertySet m_aPropSet = { saTextColumns_Impl };
+
+    //separator line
+    sal_Int32 m_nSepLineWidth = 0;
+    com::sun::star::util::Color m_nSepLineColor = 0; // black
+    sal_Int32 m_nSepLineHeightRelative = 100; // full height
+    css::style::VerticalAlignment m_nSepLineVertAlign = css::style::VerticalAlignment_MIDDLE;
+    bool m_bSepLineIsOn = false;
+    sal_Int16 m_nSepLineStyle = css::text::ColumnSeparatorStyle::NONE;
+};
+
+OUString SvxXTextColumns::getImplementationName() { return "SvxXTextColumns"; }
+
+sal_Bool SvxXTextColumns::supportsService(const OUString& rServiceName)
+{
+    return cppu::supportsService(this, rServiceName);
+}
+
+css::uno::Sequence<OUString> SvxXTextColumns::getSupportedServiceNames()
+{
+    return { "com.sun.star.text.TextColumns" };
+}
+
+sal_Int32 SvxXTextColumns::getReferenceValue()
+{
+    SolarMutexGuard aGuard;
+    return m_nReference;
+}
+
+sal_Int16 SvxXTextColumns::getColumnCount()
+{
+    SolarMutexGuard aGuard;
+    return o3tl::narrowing<sal_Int16>(m_aTextColumns.getLength());
+}
+
+void SvxXTextColumns::setColumnCount(sal_Int16 nColumns)
+{
+    SolarMutexGuard aGuard;
+    if (nColumns <= 0)
+        throw css::uno::RuntimeException();
+    m_bIsAutomaticWidth = true;
+    m_aTextColumns.realloc(nColumns);
+    css::text::TextColumn* pCols = m_aTextColumns.getArray();
+    m_nReference = USHRT_MAX;
+    sal_Int32 nWidth = m_nReference / nColumns;
+    sal_Int32 nDiff = m_nReference - nWidth * nColumns;
+    sal_Int32 nDist = m_nAutoDistance / 2;
+    for (sal_Int16 i = 0; i < nColumns; i++)
+    {
+        pCols[i].Width = nWidth;
+        pCols[i].LeftMargin = i == 0 ? 0 : nDist;
+        pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
+    }
+    pCols[nColumns - 1].Width += nDiff;
+}
+
+css::uno::Sequence<css::text::TextColumn> SvxXTextColumns::getColumns()
+{
+    SolarMutexGuard aGuard;
+    return m_aTextColumns;
+}
+
+void SvxXTextColumns::setColumns(const css::uno::Sequence<css::text::TextColumn>& rColumns)
+{
+    SolarMutexGuard aGuard;
+    sal_Int32 nReferenceTemp = std::accumulate(
+        rColumns.begin(), rColumns.end(), sal_Int32(0),
+        [](const sal_Int32 nSum, const css::text::TextColumn& rCol) { return nSum + rCol.Width; });
+    m_bIsAutomaticWidth = false;
+    m_nReference = !nReferenceTemp ? USHRT_MAX : nReferenceTemp;
+    m_aTextColumns = rColumns;
+}
+
+css::uno::Reference<css::beans::XPropertySetInfo> SvxXTextColumns::getPropertySetInfo()
+{
+    return m_aPropSet.getPropertySetInfo();
+}
+
+void SvxXTextColumns::setPropertyValue(const OUString& rPropertyName, const css::uno::Any& aValue)
+{
+    const SfxItemPropertyMapEntry* pEntry = m_aPropSet.getPropertyMap().getByName(rPropertyName);
+    if (!pEntry)
+        throw css::beans::UnknownPropertyException("Unknown property: " + rPropertyName,
+                                                   static_cast<cppu::OWeakObject*>(this));
+    if (pEntry->nFlags & css::beans::PropertyAttribute::READONLY)
+        throw css::beans::PropertyVetoException("Property is read-only: " + rPropertyName,
+                                                static_cast<cppu::OWeakObject*>(this));
+
+    switch (pEntry->nWID)
+    {
+        case WID_TXTCOL_LINE_WIDTH:
+            if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0)
+                throw css::lang::IllegalArgumentException();
+            else
+                m_nSepLineWidth = convertMm100ToTwip(nTmp);
+            break;
+        case WID_TXTCOL_LINE_COLOR:
+            if (!(aValue >>= m_nSepLineColor))
+                throw css::lang::IllegalArgumentException();
+            break;
+        case WID_TXTCOL_LINE_STYLE:
+            if (!(aValue >>= m_nSepLineStyle))
+                throw css::lang::IllegalArgumentException();
+            break;
+        case WID_TXTCOL_LINE_REL_HGT:
+            if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0)
+                throw css::lang::IllegalArgumentException();
+            else
+                m_nSepLineHeightRelative = nTmp;
+            break;
+        case WID_TXTCOL_LINE_ALIGN:
+            if (css::style::VerticalAlignment eAlign; aValue >>= eAlign)
+                m_nSepLineVertAlign = eAlign;
+            else if (sal_Int8 nTmp; aValue >>= nTmp)
+                m_nSepLineVertAlign = static_cast<css::style::VerticalAlignment>(nTmp);
+            else
+                throw css::lang::IllegalArgumentException();
+            break;
+        case WID_TXTCOL_LINE_IS_ON:
+            if (!(aValue >>= m_bSepLineIsOn))
+                throw css::lang::IllegalArgumentException();
+            break;
+        case WID_TXTCOL_AUTO_DISTANCE:
+            if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0 || nTmp >= m_nReference)
+                throw css::lang::IllegalArgumentException();
+            else
+            {
+                m_nAutoDistance = nTmp;
+                sal_Int32 nColumns = m_aTextColumns.getLength();
+                css::text::TextColumn* pCols = m_aTextColumns.getArray();
+                sal_Int32 nDist = m_nAutoDistance / 2;
+                for (sal_Int32 i = 0; i < nColumns; i++)
+                {
+                    pCols[i].LeftMargin = i == 0 ? 0 : nDist;
+                    pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
+                }
+            }
+            break;
+    }
+}
+
+css::uno::Any SvxXTextColumns::getPropertyValue(const OUString& rPropertyName)
+{
+    const SfxItemPropertyMapEntry* pEntry = m_aPropSet.getPropertyMap().getByName(rPropertyName);
+    if (!pEntry)
+        throw css::beans::UnknownPropertyException("Unknown property: " + rPropertyName,
+                                                   static_cast<cppu::OWeakObject*>(this));
+
+    css::uno::Any aRet;
+    switch (pEntry->nWID)
+    {
+        case WID_TXTCOL_LINE_WIDTH:
+            aRet <<= o3tl::narrowing<sal_Int32>(convertTwipToMm100(m_nSepLineWidth));
+            break;
+        case WID_TXTCOL_LINE_COLOR:
+            aRet <<= m_nSepLineColor;
+            break;
+        case WID_TXTCOL_LINE_STYLE:
+            aRet <<= m_nSepLineStyle;
+            break;
+        case WID_TXTCOL_LINE_REL_HGT:
+            aRet <<= m_nSepLineHeightRelative;
+            break;
+        case WID_TXTCOL_LINE_ALIGN:
+            aRet <<= m_nSepLineVertAlign;
+            break;
+        case WID_TXTCOL_LINE_IS_ON:
+            aRet <<= m_bSepLineIsOn;
+            break;
+        case WID_TXTCOL_IS_AUTOMATIC:
+            aRet <<= m_bIsAutomaticWidth;
+            break;
+        case WID_TXTCOL_AUTO_DISTANCE:
+            aRet <<= m_nAutoDistance;
+            break;
+    }
+    return aRet;
+}
+
+void SvxXTextColumns::addPropertyChangeListener(
+    const OUString& /*rPropertyName*/,
+    const css::uno::Reference<css::beans::XPropertyChangeListener>& /*xListener*/)
+{
+}
+
+void SvxXTextColumns::removePropertyChangeListener(
+    const OUString& /*rPropertyName*/,
+    const css::uno::Reference<css::beans::XPropertyChangeListener>& /*xListener*/)
+{
+}
+
+void SvxXTextColumns::addVetoableChangeListener(
+    const OUString& /*rPropertyName*/,
+    const css::uno::Reference<css::beans::XVetoableChangeListener>& /*xListener*/)
+{
+}
+
+void SvxXTextColumns::removeVetoableChangeListener(
+    const OUString& /*rPropertyName*/,
+    const css::uno::Reference<css::beans::XVetoableChangeListener>& /*xListener*/)
+{
+}
+}
+
+css::uno::Reference<css::uno::XInterface> SvxXTextColumns_createInstance() noexcept
+{
+    return static_cast<cppu::OWeakObject*>(new SvxXTextColumns);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/svx/source/unodraw/unomod.cxx b/svx/source/unodraw/unomod.cxx
index 5980da82d73d..25b6016dd419 100644
--- a/svx/source/unodraw/unomod.cxx
+++ b/svx/source/unodraw/unomod.cxx
@@ -48,6 +48,7 @@
 #include <svx/unomodel.hxx>
 #include <svx/svdobj.hxx>
 #include <svx/svdpage.hxx>
+#include <svx/SvxXTextColumns.hxx>
 #include <svx/unoshape.hxx>
 #include <svx/xmlgrhlp.hxx>
 
@@ -182,6 +183,10 @@ css::uno::Reference<css::uno::XInterface> create(
         uno::Reference< uno::XInterface> xRet( static_cast< ::cppu::OWeakObject* >( pGraphicHelper.get() ) );
         return xRet;
     }
+    else if (rServiceSpecifier == "com.sun.star.text.TextColumns")
+    {
+        return SvxXTextColumns_createInstance();
+    }
 
     uno::Reference< uno::XInterface > xRet( SvxUnoDrawMSFactory::createTextField( rServiceSpecifier ) );
     if( !xRet.is() )
diff --git a/svx/source/unodraw/unopool.cxx b/svx/source/unodraw/unopool.cxx
index 5931087349c3..59c19c70262d 100644
--- a/svx/source/unodraw/unopool.cxx
+++ b/svx/source/unodraw/unopool.cxx
@@ -241,6 +241,13 @@ void SvxUnoDrawPool::_getPropertyStates( const comphelper::PropertyMapEntry** pp
                     }
                 }
                 break;
+            case OWN_ATTR_TEXTCOLUMNS:
+                if (IsStaticDefaultItem(&pPool->GetDefaultItem(sal_uInt16(SDRATTR_TEXTCOLUMNS_NUMBER)))
+                    && IsStaticDefaultItem(&pPool->GetDefaultItem(sal_uInt16(SDRATTR_TEXTCOLUMNS_SPACING))))
+                    *pStates = beans::PropertyState_DEFAULT_VALUE;
+                else
+                    *pStates = beans::PropertyState_DIRECT_VALUE;
+                break;
             default:
                 //#i18732# - correction:
                 // use method <IsStaticDefaultItem(..)> instead of using probably
diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx
index fd5296007a1d..32e3a5c6768a 100644
--- a/svx/source/unodraw/unoshape.cxx
+++ b/svx/source/unodraw/unoshape.cxx
@@ -86,6 +86,7 @@
 #include <svx/sdtfsitm.hxx>
 #include <svx/svdoutl.hxx>
 #include <svx/svdopath.hxx>
+#include <svx/SvxXTextColumns.hxx>
 
 #include <memory>
 #include <optional>
@@ -2494,6 +2495,27 @@ bool SvxShape::setPropertyValueImpl( const OUString&, const SfxItemPropertyMapEn
             return false;
         }
     }
+
+    case OWN_ATTR_TEXTCOLUMNS:
+    {
+        if (auto pTextObj = dynamic_cast<SdrTextObj*>(GetSdrObject()))
+        {
+            css::uno::Reference<css::text::XTextColumns> xTextColumns;
+            if (rValue >>= xTextColumns)
+            {
+                pTextObj->SetTextColumnsNumber(xTextColumns->getColumnCount());
+                if (css::uno::Reference<css::beans::XPropertySet> xPropSet{ xTextColumns,
+                                                                            css::uno::UNO_QUERY })
+                {
+                    auto aVal = xPropSet->getPropertyValue("AutomaticDistance");
+                    if (sal_Int32 nSpacing; aVal >>= nSpacing)
+                        pTextObj->SetTextColumnsSpacing(nSpacing);
+                }
+            }
+        }
+        return true;
+    }
+
     default:
     {
         return false;
@@ -2897,6 +2919,23 @@ bool SvxShape::getPropertyValueImpl( const OUString&, const SfxItemPropertyMapEn
         break;
     }
 
+    case OWN_ATTR_TEXTCOLUMNS:
+    {
+        if (auto pTextObj = dynamic_cast<const SdrTextObj*>(GetSdrObject()))
+        {
+            if (pTextObj->HasTextColumnsNumber() || pTextObj->HasTextColumnsSpacing())
+            {
+                auto xIf = SvxXTextColumns_createInstance();
+                css::uno::Reference<css::text::XTextColumns> xCols(xIf, css::uno::UNO_QUERY_THROW);
+                xCols->setColumnCount(pTextObj->GetTextColumnsNumber());
+                css::uno::Reference<css::beans::XPropertySet> xProp(xIf, css::uno::UNO_QUERY_THROW);
+                xProp->setPropertyValue("AutomaticDistance",
+                                        css::uno::Any(pTextObj->GetTextColumnsSpacing()));
+                rValue <<= xIf;
+            }
+        }
+        break;
+    }
 
     default:
         return false;
diff --git a/sw/inc/unomap.hxx b/sw/inc/unomap.hxx
index 1cd22609f02e..d2c54d204188 100644
--- a/sw/inc/unomap.hxx
+++ b/sw/inc/unomap.hxx
@@ -58,7 +58,6 @@ struct SfxItemPropertyMapEntry;
 #define PROPERTY_MAP_AUTO_TEXT_GROUP        31
 #define PROPERTY_MAP_TEXTPORTION_EXTENSIONS 34
 #define PROPERTY_MAP_FOOTNOTE               35
-#define PROPERTY_MAP_TEXT_COLUMS            36
 #define PROPERTY_MAP_PARAGRAPH              37
 #define PROPERTY_MAP_EMBEDDED_OBJECT        38
 #define PROPERTY_MAP_REDLINE                39
@@ -305,16 +304,6 @@ struct SfxItemPropertyMapEntry;
 #define WID_IS_OUTLINE                  4
 #define WID_DEFAULT_LIST_ID             5
 
-// TextColumns
-#define WID_TXTCOL_LINE_WIDTH           0
-#define WID_TXTCOL_LINE_COLOR           1
-#define WID_TXTCOL_LINE_REL_HGT         2
-#define WID_TXTCOL_LINE_ALIGN           3
-#define WID_TXTCOL_LINE_IS_ON           4
-#define WID_TXTCOL_IS_AUTOMATIC         5
-#define WID_TXTCOL_AUTO_DISTANCE        6
-#define WID_TXTCOL_LINE_STYLE           7
-
 // This define would need the include of <svx/unoshprp.hxx>, but this ends
 // in a mess; there *are* double used symbols which are used in a #define in
 // editengine and as an enum in sw; these will then collide and lead to severe
diff --git a/sw/inc/unosett.hxx b/sw/inc/unosett.hxx
index d5351a9b3a4f..f08a473f10b2 100644
--- a/sw/inc/unosett.hxx
+++ b/sw/inc/unosett.hxx
@@ -243,71 +243,6 @@ public:
 
 };
 
-class SwXTextColumns final : public cppu::WeakAggImplHelper4
-<
-
-    css::lang::XUnoTunnel,
-    css::beans::XPropertySet,
-    css::text::XTextColumns,
-    css::lang::XServiceInfo
->
-{
-    sal_Int32                   m_nReference;
-    css::uno::Sequence< css::text::TextColumn>    m_aTextColumns;
-    bool                        m_bIsAutomaticWidth;
-    sal_Int32                   m_nAutoDistance;
-
-    const SfxItemPropertySet*   m_pPropSet;
-
-    //separator line
-    sal_Int32                   m_nSepLineWidth;
-    Color                       m_nSepLineColor;
-    sal_Int8                    m_nSepLineHeightRelative;
-    css::style::VerticalAlignment m_nSepLineVertAlign;
-    bool                        m_bSepLineIsOn;
-    sal_Int8                    m_nSepLineStyle;
-
-
-    virtual ~SwXTextColumns() override;
-public:
-    SwXTextColumns();
-    SwXTextColumns(const SwFormatCol& rFormatCol);
-
-    static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId();
-
-    //XUnoTunnel
-    virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override;
-
-    //XTextColumns
-    virtual sal_Int32 SAL_CALL getReferenceValue(  ) override;
-    virtual sal_Int16 SAL_CALL getColumnCount(  ) override;
-    virtual void SAL_CALL setColumnCount( sal_Int16 nColumns ) override;
-    virtual css::uno::Sequence< css::text::TextColumn > SAL_CALL getColumns(  ) override;
-    virtual void SAL_CALL setColumns( const css::uno::Sequence< css::text::TextColumn >& Columns ) override;
-
-    //XPropertySet
-    virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) override;
-    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
-    virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
-    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override;
-    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
-    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
-    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
-
-    //XServiceInfo
-    virtual OUString SAL_CALL getImplementationName() override;
-    virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
-    virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
-
-    sal_Int32   GetSepLineWidth() const {return m_nSepLineWidth;}
-    Color       GetSepLineColor() const {return m_nSepLineColor;}
-    sal_Int8    GetSepLineHeightRelative() const {return    m_nSepLineHeightRelative;}
-    css::style::VerticalAlignment GetSepLineVertAlign() const {return m_nSepLineVertAlign;}
-    bool        GetSepLineIsOn() const {return  m_bSepLineIsOn;}
-    sal_Int8    GetSepLineStyle() const {return m_nSepLineStyle;}
-
-    bool        IsAutomaticWidth() const {return m_bIsAutomaticWidth;}
-};
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index fc4865619466..5e7d6100bc0e 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -17,6 +17,9 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <sal/config.h>
+
+#include <com/sun/star/text/ColumnSeparatorStyle.hpp>
 #include <com/sun/star/text/WrapTextMode.hpp>
 #include <com/sun/star/text/TextContentAnchorType.hpp>
 #include <com/sun/star/container/XIndexContainer.hpp>
@@ -78,6 +81,7 @@
 #include <unomid.h>
 #include <strings.hrc>
 #include <svx/svdundo.hxx>
+#include <svx/SvxXTextColumns.hxx>
 #include <sortedobjs.hxx>
 #include <HandleAnchorNodeChg.hxx>
 #include <calbck.hxx>
@@ -85,6 +89,7 @@
 #include <drawdoc.hxx>
 #include <hints.hxx>
 #include <frameformats.hxx>
+#include <unoprnms.hxx>
 
 #include <ndtxt.hxx>
 
@@ -1073,7 +1078,81 @@ bool SwFormatCol::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
     }
     else
     {
-        uno::Reference< text::XTextColumns >  xCols = new SwXTextColumns(*this);
+        uno::Reference<text::XTextColumns> xCols(SvxXTextColumns_createInstance(),
+                                                 css::uno::UNO_QUERY_THROW);
+        uno::Reference<beans::XPropertySet> xProps(xCols, css::uno::UNO_QUERY_THROW);
+
+        if (GetNumCols() > 0)
+        {
+            xCols->setColumnCount(GetNumCols());
+            const sal_uInt16 nItemGutterWidth = GetGutterWidth();
+            sal_Int32 nAutoDistance = IsOrtho() ? USHRT_MAX == nItemGutterWidth
+                                                      ? DEF_GUTTER_WIDTH
+                                                      : static_cast<sal_Int32>(nItemGutterWidth)
+                                                : 0;
+            nAutoDistance = convertTwipToMm100(nAutoDistance);
+            xProps->setPropertyValue(UNO_NAME_AUTOMATIC_DISTANCE, uno::Any(nAutoDistance));
+
+            if (!IsOrtho())
+            {
+                auto aTextColumns = xCols->getColumns();
+                text::TextColumn* pColumns = aTextColumns.getArray();
+                const SwColumns& rCols = GetColumns();
+                for (sal_Int32 i = 0; i < aTextColumns.getLength(); ++i)
+                {
+                    const SwColumn* pCol = &rCols[i];
+
+                    pColumns[i].Width = pCol->GetWishWidth();
+                    pColumns[i].LeftMargin = convertTwipToMm100(pCol->GetLeft());
+                    pColumns[i].RightMargin = convertTwipToMm100(pCol->GetRight());
+                }
+                xCols->setColumns(aTextColumns); // sets "IsAutomatic" property to false
+            }
+        }
+        uno::Any aVal;
+        aVal <<= o3tl::narrowing<sal_Int32>(GetLineWidth());
+        xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH, aVal);
+        aVal <<= GetLineColor();
+        xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR, aVal);
+        aVal <<= static_cast<sal_Int32>(GetLineHeight());
+        xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT, aVal);
+        aVal <<= GetLineAdj() != COLADJ_NONE;
+        xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON, aVal);
+        sal_Int16 nStyle;
+        switch (GetLineStyle())
+        {
+            case SvxBorderLineStyle::SOLID:
+                nStyle = css::text::ColumnSeparatorStyle::SOLID;
+                break;
+            case SvxBorderLineStyle::DOTTED:
+                nStyle = css::text::ColumnSeparatorStyle::DOTTED;
+                break;
+            case SvxBorderLineStyle::DASHED:
+                nStyle = css::text::ColumnSeparatorStyle::DASHED;
+                break;
+            case SvxBorderLineStyle::NONE:
+            default:
+                nStyle = css::text::ColumnSeparatorStyle::NONE;
+                break;
+        }
+        aVal <<= nStyle;
+        xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE, aVal);
+        style::VerticalAlignment eAlignment;
+        switch (GetLineAdj())
+        {
+            case COLADJ_TOP:
+                eAlignment = style::VerticalAlignment_TOP;
+                break;
+            case COLADJ_BOTTOM:
+                eAlignment = style::VerticalAlignment_BOTTOM;
+                break;
+            case COLADJ_CENTER:
+            case COLADJ_NONE:
+            default:
+                eAlignment = style::VerticalAlignment_MIDDLE;
+        }
+        aVal <<= eAlignment;
+        xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT, aVal);
         rVal <<= xCols;
     }
     return true;
@@ -1117,24 +1196,33 @@ bool SwFormatCol::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
             m_nWidth = nWidthSum;
             m_bOrtho = false;
 
-            auto pSwColums = comphelper::getUnoTunnelImplementation<SwXTextColumns>(xCols);
-            if(pSwColums)
+            if (uno::Reference<beans::XPropertySet> xProps{ xCols, css::uno::UNO_QUERY })
             {
-                m_bOrtho = pSwColums->IsAutomaticWidth();
-                m_nLineWidth = pSwColums->GetSepLineWidth();
-                m_aLineColor = pSwColums->GetSepLineColor();
-                m_nLineHeight = pSwColums->GetSepLineHeightRelative();
-                switch ( pSwColums->GetSepLineStyle() )
+                xProps->getPropertyValue(UNO_NAME_IS_AUTOMATIC) >>= m_bOrtho;
+                xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH) >>= m_nLineWidth;
+                xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR) >>= m_aLineColor;
+                if (sal_Int32 nHeight;
+                    xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT) >>= nHeight)
+                    m_nLineHeight = nHeight;
+                switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE).get<sal_Int16>())
                 {
                     default:
-                    case 0: m_eLineStyle = SvxBorderLineStyle::NONE; break;
-                    case 1: m_eLineStyle = SvxBorderLineStyle::SOLID; break;
-                    case 2: m_eLineStyle = SvxBorderLineStyle::DOTTED; break;
-                    case 3: m_eLineStyle = SvxBorderLineStyle::DASHED; break;
+                    case css::text::ColumnSeparatorStyle::NONE:
+                        m_eLineStyle = SvxBorderLineStyle::NONE;
+                        break;
+                    case css::text::ColumnSeparatorStyle::SOLID:
+                        m_eLineStyle = SvxBorderLineStyle::SOLID;
+                        break;
+                    case css::text::ColumnSeparatorStyle::DOTTED:
+                        m_eLineStyle = SvxBorderLineStyle::DOTTED;
+                        break;
+                    case css::text::ColumnSeparatorStyle::DASHED:
+                        m_eLineStyle = SvxBorderLineStyle::DASHED;
+                        break;
                 }
-                if(!pSwColums->GetSepLineIsOn())
+                if (!xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON).get<bool>())
                     m_eAdj = COLADJ_NONE;
-                else switch(pSwColums->GetSepLineVertAlign())
+                else switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT).get<style::VerticalAlignment>())
                 {
                     case style::VerticalAlignment_TOP: m_eAdj = COLADJ_TOP;  break;
                     case style::VerticalAlignment_MIDDLE: m_eAdj = COLADJ_CENTER; break;
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 50f0aa61cf38..e7fe4455eb8f 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -35,6 +35,7 @@
 #include <o3tl/safeint.hxx>
 #include <svtools/unoimap.hxx>
 #include <svtools/unoevent.hxx>
+#include <svx/SvxXTextColumns.hxx>
 #include <unotbl.hxx>
 #include <unostyle.hxx>
 #include <unofield.hxx>
@@ -792,7 +793,7 @@ SwXServiceProvider::MakeInstance(SwServiceType nObjectType, SwDoc & rDoc)
             xRet = static_cast<cppu::OWeakObject*>(new SwXNumberingRules(rDoc));
         break;
         case SwServiceType::TextColumns:
-            xRet = static_cast<cppu::OWeakObject*>(new SwXTextColumns);
+            xRet = SvxXTextColumns_createInstance();
         break;
         case SwServiceType::Defaults:
             xRet = static_cast<cppu::OWeakObject*>(new SwXTextDefaults(&rDoc));
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index 0cb439336ae8..3580a8f416a2 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -681,23 +681,6 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s
                 m_aMapEntriesArr[nPropertyId] = GetFootnotePropertyMap();
             }
             break;
-            case PROPERTY_MAP_TEXT_COLUMS :
-            {
-                static SfxItemPropertyMapEntry const aTextColumns_Impl[] =
-                {
-                    {u"" UNO_NAME_IS_AUTOMATIC, WID_TXTCOL_IS_AUTOMATIC, cppu::UnoType<bool>::get(),PropertyAttribute::READONLY, 0},
-                    {u"" UNO_NAME_AUTOMATIC_DISTANCE, WID_TXTCOL_AUTO_DISTANCE, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, 0},
-                    {u"" UNO_NAME_SEPARATOR_LINE_WIDTH, WID_TXTCOL_LINE_WIDTH, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, 0},
-                    {u"" UNO_NAME_SEPARATOR_LINE_COLOR, WID_TXTCOL_LINE_COLOR, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE,    0},
-                    {u"" UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT, WID_TXTCOL_LINE_REL_HGT, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE,    0},
-                    {u"" UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT, WID_TXTCOL_LINE_ALIGN, cppu::UnoType<css::style::VerticalAlignment>::get(),PROPERTY_NONE,   0},
-                    {u"" UNO_NAME_SEPARATOR_LINE_IS_ON, WID_TXTCOL_LINE_IS_ON, cppu::UnoType<bool>::get(),PROPERTY_NONE,  0},
-                    {u"" UNO_NAME_SEPARATOR_LINE_STYLE, WID_TXTCOL_LINE_STYLE, cppu::UnoType<sal_Int8>::get(),PROPERTY_NONE, 0},
-                    { u"", 0, css::uno::Type(), 0, 0 }
-                };
-                m_aMapEntriesArr[nPropertyId] = aTextColumns_Impl;
-            }
-            break;
             case PROPERTY_MAP_REDLINE :
             {
                 m_aMapEntriesArr[nPropertyId] = GetRedlinePropertyMap();
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index 803c93f94b1b..ee7b116d9716 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1275,12 +1275,6 @@ const SfxItemPropertySet*  SwUnoPropertyMapProvider::GetPropertySet( sal_uInt16
                 m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FOOTNOTE;
             }
             break;
-            case PROPERTY_MAP_TEXT_COLUMS            :
-            {
-                static SfxItemPropertySet aPROPERTY_MAP_TEXT_COLUMS(pEntries);
-                m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_COLUMS;
-            }
-            break;
             case PROPERTY_MAP_PARAGRAPH              :
             {
                 static SfxItemPropertySet aPROPERTY_MAP_PARAGRAPH(pEntries);
diff --git a/sw/source/core/unocore/unosett.cxx b/sw/source/core/unocore/unosett.cxx
index eedb0fdbaa2d..186b0e98116e 100644
--- a/sw/source/core/unocore/unosett.cxx
+++ b/sw/source/core/unocore/unosett.cxx
@@ -90,11 +90,6 @@ namespace
         return pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier();
     }
 }
-// Constants for the css::text::ColumnSeparatorStyle
-#define API_COL_LINE_NONE               0
-#define API_COL_LINE_SOLID              1
-#define API_COL_LINE_DOTTED             2
-#define API_COL_LINE_DASHED             3
 
 #define WID_PREFIX                      0
 #define WID_SUFFIX                      1
@@ -2166,290 +2161,4 @@ SwXChapterNumbering::~SwXChapterNumbering()
 {
 }
 
-OUString SwXTextColumns::getImplementationName()
-{
-    return "SwXTextColumns";
-}
-
-sal_Bool SwXTextColumns::supportsService(const OUString& rServiceName)
-{
-    return cppu::supportsService(this, rServiceName);
-}
-
-Sequence< OUString > SwXTextColumns::getSupportedServiceNames()
-{
-    Sequence<OUString> aRet { "com.sun.star.text.TextColumns" };
-    return aRet;
-}
-
-SwXTextColumns::SwXTextColumns() :
-    m_nReference(0),
-    m_bIsAutomaticWidth(true),
-    m_nAutoDistance(0),
-    m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_COLUMS)),
-    m_nSepLineWidth(0),
-    m_nSepLineColor(0), //black
-    m_nSepLineHeightRelative(100),//full height
-    m_nSepLineVertAlign(style::VerticalAlignment_MIDDLE),
-    m_bSepLineIsOn(false),
-    m_nSepLineStyle(API_COL_LINE_NONE) // None
-{
-}
-
-SwXTextColumns::SwXTextColumns(const SwFormatCol& rFormatCol) :
-    m_nReference(0),
-    m_aTextColumns(rFormatCol.GetNumCols()),
-    m_bIsAutomaticWidth(rFormatCol.IsOrtho()),
-    m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_COLUMS))
-{
-    const sal_uInt16 nItemGutterWidth = rFormatCol.GetGutterWidth();
-    m_nAutoDistance = m_bIsAutomaticWidth ?
-                        USHRT_MAX == nItemGutterWidth ? DEF_GUTTER_WIDTH : static_cast<sal_Int32>(nItemGutterWidth)
-                        : 0;
-    m_nAutoDistance = convertTwipToMm100(m_nAutoDistance);
-
-    TextColumn* pColumns = m_aTextColumns.getArray();
-    const SwColumns& rCols = rFormatCol.GetColumns();
-    for(sal_Int32 i = 0; i < m_aTextColumns.getLength(); ++i)
-    {
-        const SwColumn* pCol = &rCols[i];
-
-        pColumns[i].Width = pCol->GetWishWidth();
-        m_nReference += pColumns[i].Width;
-        pColumns[i].LeftMargin =    convertTwipToMm100(pCol->GetLeft ());
-        pColumns[i].RightMargin =   convertTwipToMm100(pCol->GetRight());
-    }
-    if(!m_aTextColumns.hasElements())
-        m_nReference = USHRT_MAX;
-
-    m_nSepLineWidth = rFormatCol.GetLineWidth();
-    m_nSepLineColor = rFormatCol.GetLineColor();
-    m_nSepLineHeightRelative = rFormatCol.GetLineHeight();
-    m_bSepLineIsOn = rFormatCol.GetLineAdj() != COLADJ_NONE;
-    sal_Int8 nStyle = API_COL_LINE_NONE;
-    switch (rFormatCol.GetLineStyle())
-    {
-        case SvxBorderLineStyle::SOLID: nStyle = API_COL_LINE_SOLID; break;
-        case SvxBorderLineStyle::DOTTED: nStyle= API_COL_LINE_DOTTED; break;
-        case SvxBorderLineStyle::DASHED: nStyle= API_COL_LINE_DASHED; break;
-        default: break;
-    }
-    m_nSepLineStyle = nStyle;
-    switch(rFormatCol.GetLineAdj())
-    {
-        case COLADJ_TOP:    m_nSepLineVertAlign = style::VerticalAlignment_TOP;   break;
-        case COLADJ_BOTTOM: m_nSepLineVertAlign = style::VerticalAlignment_BOTTOM;    break;
-        case COLADJ_CENTER:
-        case COLADJ_NONE:   m_nSepLineVertAlign = style::VerticalAlignment_MIDDLE;
-    }
-}
-
-SwXTextColumns::~SwXTextColumns()
-{
-}
-
-sal_Int32 SwXTextColumns::getReferenceValue()
-{
-    SolarMutexGuard aGuard;
-    return m_nReference;
-}
-
-sal_Int16 SwXTextColumns::getColumnCount()
-{
-    SolarMutexGuard aGuard;
-    return static_cast< sal_Int16>( m_aTextColumns.getLength() );
-}
-
-void SwXTextColumns::setColumnCount(sal_Int16 nColumns)
-{
-    SolarMutexGuard aGuard;
-    if(nColumns <= 0)
-        throw uno::RuntimeException();
-    m_bIsAutomaticWidth = true;
-    m_aTextColumns.realloc(nColumns);
-    TextColumn* pCols = m_aTextColumns.getArray();
-    m_nReference = USHRT_MAX;
-    sal_Int32 nWidth = m_nReference / nColumns;
-    sal_Int32 nDiff = m_nReference - nWidth * nColumns;
-    sal_Int32 nDist = m_nAutoDistance / 2;
-    for(sal_Int16 i = 0; i < nColumns; i++)
-    {
-        pCols[i].Width = nWidth;
-        pCols[i].LeftMargin = i == 0 ? 0 : nDist;
-        pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
-    }
-    pCols[nColumns - 1].Width += nDiff;
-}
-
-uno::Sequence< TextColumn > SwXTextColumns::getColumns()
-{
-    SolarMutexGuard aGuard;
-    return m_aTextColumns;
-}
-
-void SwXTextColumns::setColumns(const uno::Sequence< TextColumn >& rColumns)
-{
-    SolarMutexGuard aGuard;
-    sal_Int32 nReferenceTemp = std::accumulate(rColumns.begin(), rColumns.end(), sal_Int32(0),
-        [](const sal_Int32 nSum, const TextColumn& rCol) { return nSum + rCol.Width; });
-    m_bIsAutomaticWidth = false;
-    m_nReference = !nReferenceTemp ? USHRT_MAX : nReferenceTemp;
-    m_aTextColumns = rColumns;
-}
-
-uno::Reference< XPropertySetInfo > SwXTextColumns::getPropertySetInfo(  )
-{
-    static uno::Reference< beans::XPropertySetInfo >  aRef = m_pPropSet->getPropertySetInfo();
-    return aRef;
-}
-
-void SwXTextColumns::setPropertyValue( const OUString& rPropertyName, const Any& aValue )
-{
-    const SfxItemPropertyMapEntry*  pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
-    if (!pEntry)
-        throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
-    if ( pEntry->nFlags & PropertyAttribute::READONLY)
-        throw PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
-
-    switch(pEntry->nWID)
-    {
-        case WID_TXTCOL_LINE_WIDTH:
-        {
-            sal_Int32 nTmp = 0;
-            aValue >>= nTmp;
-            if(nTmp < 0)
-                throw IllegalArgumentException();
-            m_nSepLineWidth = convertMm100ToTwip(nTmp);
-        }
-        break;
-        case WID_TXTCOL_LINE_COLOR:
-            aValue >>= m_nSepLineColor;
-        break;
-        case WID_TXTCOL_LINE_STYLE:
-        {
-            aValue >>= m_nSepLineStyle;
-        }
-        break;
-        case WID_TXTCOL_LINE_REL_HGT:
-        {
-            sal_Int8 nTmp = 0;
-            aValue >>= nTmp;
-            if(nTmp < 0)
-                throw IllegalArgumentException();
-            m_nSepLineHeightRelative = nTmp;
-        }
-        break;
-        case WID_TXTCOL_LINE_ALIGN:
-        {
-            style::VerticalAlignment eAlign;
-            if(!(aValue >>= eAlign) )
-            {
-                sal_Int8 nTmp = 0;
-                if (! ( aValue >>= nTmp ) )
-                    throw IllegalArgumentException();
-                m_nSepLineVertAlign = static_cast<style::VerticalAlignment>(nTmp);
-            }
-            else
-                m_nSepLineVertAlign = eAlign;
-        }
-        break;
-        case WID_TXTCOL_LINE_IS_ON:
-            m_bSepLineIsOn = *o3tl::doAccess<bool>(aValue);
-        break;
-        case WID_TXTCOL_AUTO_DISTANCE:
-        {
-            sal_Int32 nTmp = 0;
-            aValue >>= nTmp;
-            if(nTmp < 0 || nTmp >= m_nReference)
-                throw IllegalArgumentException();
-            m_nAutoDistance = nTmp;
-            sal_Int32 nColumns = m_aTextColumns.getLength();
-            TextColumn* pCols = m_aTextColumns.getArray();
-            sal_Int32 nDist = m_nAutoDistance / 2;
-            for(sal_Int32 i = 0; i < nColumns; i++)
-            {
-                pCols[i].LeftMargin = i == 0 ? 0 : nDist;
-                pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
-            }
-        }
-        break;
-    }
-}
-
-Any SwXTextColumns::getPropertyValue( const OUString& rPropertyName )
-{
-    const SfxItemPropertyMapEntry*  pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
-    if (!pEntry)
-        throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
-
-    Any aRet;
-    switch(pEntry->nWID)
-    {
-        case WID_TXTCOL_LINE_WIDTH:
-            aRet <<= static_cast < sal_Int32 >(convertTwipToMm100(m_nSepLineWidth));
-        break;
-        case WID_TXTCOL_LINE_COLOR:
-            aRet <<= m_nSepLineColor;
-        break;
-        case WID_TXTCOL_LINE_STYLE:
-            aRet <<= m_nSepLineStyle;
-        break;
-        case WID_TXTCOL_LINE_REL_HGT:
-            aRet <<= m_nSepLineHeightRelative;
-        break;
-        case WID_TXTCOL_LINE_ALIGN:
-            aRet <<= m_nSepLineVertAlign;
-        break;
-        case WID_TXTCOL_LINE_IS_ON:
-            aRet <<= m_bSepLineIsOn;
-        break;
-        case WID_TXTCOL_IS_AUTOMATIC :
-            aRet <<= m_bIsAutomaticWidth;
-        break;
-        case WID_TXTCOL_AUTO_DISTANCE:
-            aRet <<= m_nAutoDistance;
-        break;
-    }
-    return aRet;
-}
-
-void SwXTextColumns::addPropertyChangeListener(
-    const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
-{
-}
-
-void SwXTextColumns::removePropertyChangeListener(
-    const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
-{
-}
-
-void SwXTextColumns::addVetoableChangeListener(
-    const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
-{
-}
-
-void SwXTextColumns::removeVetoableChangeListener(
-    const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
-{
-}
-
-namespace
-{
-}
-
-const uno::Sequence< sal_Int8 > & SwXTextColumns::getUnoTunnelId()
-{
-    static const UnoTunnelIdInit theSwXTextColumnsUnoTunnelId;
-    return theSwXTextColumnsUnoTunnelId.getSeq();
-}
-
-sal_Int64 SAL_CALL SwXTextColumns::getSomething( const uno::Sequence< sal_Int8 >& rId )
-{
-    if( isUnoTunnelId<SwXTextColumns>(rId) )
-    {
-        return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
-    }
-    return 0;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/XMLShapePropertySetContext.cxx b/xmloff/source/draw/XMLShapePropertySetContext.cxx
index 45c8ace61fc5..c702bccf9a91 100644
--- a/xmloff/source/draw/XMLShapePropertySetContext.cxx
+++ b/xmloff/source/draw/XMLShapePropertySetContext.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <XMLShapePropertySetContext.hxx>
+#include <XMLTextColumnsContext.hxx>
 #include <xmloff/xmlimp.hxx>
 #include <xmloff/xmlnumi.hxx>
 #include <xmltabi.hxx>
@@ -78,6 +79,8 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > XMLShapePropertySetCon
         return new SvxXMLTabStopImportContext( GetImport(), nElement,
                                                    rProp,
                                                    rProperties );
+    case CTF_TEXTCOLUMNS:
+        return new XMLTextColumnsContext(GetImport(), nElement, xAttrList, rProp, rProperties);
     }
 
     return SvXMLPropertySetContext::createFastChildContext( nElement,
diff --git a/xmloff/source/draw/sdpropls.cxx b/xmloff/source/draw/sdpropls.cxx
index 2bb4be8cab20..c25062efb968 100644
--- a/xmloff/source/draw/sdpropls.cxx
+++ b/xmloff/source/draw/sdpropls.cxx
@@ -58,6 +58,7 @@
 #include <XMLClipPropertyHandler.hxx>
 #include <XMLIsPercentagePropertyHandler.hxx>
 #include <XMLPercentOrMeasurePropertyHandler.hxx>
+#include <XMLTextColumnsPropertyHandler.hxx>
 #include <animations.hxx>
 #include <sax/tools/converter.hxx>
 #include <xmlsdtypes.hxx>
@@ -145,6 +146,8 @@ const XMLPropertyMapEntry aXMLSDProperties[] =
     GMAP( "TextWordWrap",                   XML_NAMESPACE_FO,   XML_WRAP_OPTION,            XML_TYPE_WRAP_OPTION, 0 ),
     GMAP( "TextChainNextName",              XML_NAMESPACE_DRAW,   XML_CHAIN_NEXT_NAME,      XML_TYPE_STRING, 0 ),
 
+    GMAP( "TextColumns",                    XML_NAMESPACE_STYLE, XML_COLUMNS, XML_TYPE_TEXT_COLUMNS|MID_FLAG_ELEMENT_ITEM, CTF_TEXTCOLUMNS ),
+
     // shadow attributes
     GMAP( "Shadow",                         XML_NAMESPACE_DRAW, XML_SHADOW,                 XML_SD_TYPE_VISIBLE_HIDDEN, 0 ),
     GMAP( "ShadowXDistance",                    XML_NAMESPACE_DRAW, XML_SHADOW_OFFSET_X,        XML_TYPE_MEASURE, 0 ),
@@ -1275,6 +1278,9 @@ const XMLPropertyHandler* XMLSdPropHdlFactory::GetPropertyHandler( sal_Int32 nTy
             case XML_SD_TYPE_CELL_ROTATION_ANGLE:
                 pHdl = new XMLSdRotationAngleTypeHdl;
                 break;
+            case XML_TYPE_TEXT_COLUMNS:
+                pHdl = new XMLTextColumnsPropertyHandler;
+                break;
         }
 
         if(pHdl)
diff --git a/xmloff/source/text/XMLTextColumnsExport.cxx b/xmloff/source/text/XMLTextColumnsExport.cxx
index 13f06fde36e6..017045d5f635 100644
--- a/xmloff/source/text/XMLTextColumnsExport.cxx
+++ b/xmloff/source/text/XMLTextColumnsExport.cxx
@@ -61,6 +61,8 @@ void XMLTextColumnsExport::exportXML( const Any& rAny )
 {
     Reference < XTextColumns > xColumns;
     rAny >>= xColumns;
+    if (!xColumns)
+        return;
 
     const Sequence < TextColumn > aColumns = xColumns->getColumns();
     sal_Int32 nCount = aColumns.getLength();
diff --git a/xmloff/source/text/txtprhdl.cxx b/xmloff/source/text/txtprhdl.cxx
index addb880a1b3b..b8dc0a8a550f 100644
--- a/xmloff/source/text/txtprhdl.cxx
+++ b/xmloff/source/text/txtprhdl.cxx
@@ -656,6 +656,9 @@ bool XMLTextColumnsPropertyHandler::equals(
     Reference < XTextColumns > xColumns2;
     r2 >>= xColumns2;
 
+    if (!xColumns1 || !xColumns2)
+        return (!xColumns1 && !xColumns2);
+
     if( xColumns1->getColumnCount() != xColumns2->getColumnCount() ||
           xColumns1->getReferenceValue() != xColumns2->getReferenceValue() )
         return false;


More information about the Libreoffice-commits mailing list