sw/inc/formatlinebreak.hxx               |    2 
 sw/inc/textlinebreak.hxx                 |    5 +
 sw/inc/unomap.hxx                        |    4 +
 sw/inc/unoprnms.hxx                      |    1 
 sw/qa/core/unocore/unocore.cxx           |    3 +
 sw/source/core/txtnode/attrlinebreak.cxx |   30 +++++++++-
 sw/source/core/txtnode/thints.cxx        |    5 +
 sw/source/core/unocore/unolinebreak.cxx  |   85 ++++++++++++++++++++++++++-----
 sw/source/core/unocore/unomap.cxx        |    5 +
 sw/source/core/unocore/unomap1.cxx       |   18 ++++++
 10 files changed, 140 insertions(+), 18 deletions(-)

New commits:
commit 1a240807f2c051ff9a63d713625404a024d7c221
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Mar 2 09:38:14 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Mar 2 10:36:12 2022 +0100

    sw clearing breaks: add UNO API to insert this with custom clear / char 
props
    
    - if (character) properties are specified when the text content itself
      is inserted, then format the anchor ("dummy") character like that
    
    - add the ability to specify a clear type (none/left/right/all) on the
      line break object itself before insertion
    
    Change-Id: I219a1031e53c2e0368ff329d45b7e3fff0934038
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130818
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/formatlinebreak.hxx b/sw/inc/formatlinebreak.hxx
index 9e26ab11351f..c3a2b0164f86 100644
--- a/sw/inc/formatlinebreak.hxx
+++ b/sw/inc/formatlinebreak.hxx
@@ -70,7 +70,7 @@ public:
 
     void InvalidateLineBreak();
 
-    css::uno::Reference<css::text::XTextRange> getAnchor(SwDoc& rDoc) const;
+    css::uno::Reference<css::text::XTextRange> GetAnchor() const;
 
     void SetTextLineBreak(SwTextLineBreak* pTextAttr) { m_pTextAttr = 
pTextAttr; }
 
diff --git a/sw/inc/textlinebreak.hxx b/sw/inc/textlinebreak.hxx
index c0853aa2bd56..33401972f60b 100644
--- a/sw/inc/textlinebreak.hxx
+++ b/sw/inc/textlinebreak.hxx
@@ -32,11 +32,16 @@ class SwFormatLineBreak;
  */
 class SW_DLLPUBLIC SwTextLineBreak final : public SwTextAttr
 {
+    SwTextNode* m_pTextNode;
+
 public:
     SwTextLineBreak(SwFormatLineBreak& rAttr, sal_Int32 nStart);
 
     ~SwTextLineBreak() override;
 
+    const SwTextNode& GetTextNode() const;
+    void SetTextNode(SwTextNode* pNew);
+
     void dumpAsXml(xmlTextWriterPtr pWriter) const override;
 };
 
diff --git a/sw/inc/unomap.hxx b/sw/inc/unomap.hxx
index c4c166032983..413adfaf7fc3 100644
--- a/sw/inc/unomap.hxx
+++ b/sw/inc/unomap.hxx
@@ -125,7 +125,8 @@ struct SfxItemPropertyMapEntry;
 #define PROPERTY_MAP_TABLE_STYLE                        100
 #define PROPERTY_MAP_CELL_STYLE                         101
 #define PROPERTY_MAP_FIELDMARK                          102
-#define PROPERTY_MAP_END                                103
+#define PROPERTY_MAP_LINEBREAK                          103
+#define PROPERTY_MAP_END                                104
 
 //S&E
 #define WID_WORDS                0
@@ -351,6 +352,7 @@ private:
     static const SfxItemPropertyMapEntry*  GetRedlinePropertyMap();
     static const SfxItemPropertyMapEntry*  GetRedlinePortionPropertyMap();
     static       SfxItemPropertyMapEntry*  GetTextDefaultPropertyMap();
+    static const SfxItemPropertyMapEntry* GetLineBreakPropertyMap();
 };
 
 extern SwUnoPropertyMapProvider aSwMapProvider;
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 8e982a84c4ac..d82bb18a0023 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -867,6 +867,7 @@
 
 #define UNO_NAME_RESOLVED "Resolved"
 #define UNO_NAME_ALLOW_OVERLAP "AllowOverlap"
+#define UNO_NAME_CLEAR "Clear"
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx
index b7d92d8485ac..315716a6da15 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -226,6 +226,9 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testLineBreakInsert)
     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
     uno::Reference<text::XTextContent> xLineBreak(
         xMSF->createInstance("com.sun.star.text.LineBreak"), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xLineBreakProps(xLineBreak, 
uno::UNO_QUERY);
+    auto eClear = static_cast<sal_Int16>(SwLineBreakClear::ALL);
+    xLineBreakProps->setPropertyValue("Clear", uno::makeAny(eClear));
     uno::Reference<text::XText> xText = xTextDocument->getText();
     uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
     xText->insertTextContent(xCursor, xLineBreak, /*bAbsorb=*/false);
diff --git a/sw/source/core/txtnode/attrlinebreak.cxx 
b/sw/source/core/txtnode/attrlinebreak.cxx
index f0f583ecc2df..00d1c275e3dd 100644
--- a/sw/source/core/txtnode/attrlinebreak.cxx
+++ b/sw/source/core/txtnode/attrlinebreak.cxx
@@ -27,6 +27,8 @@
 #include <hints.hxx>
 #include <pam.hxx>
 #include <textlinebreak.hxx>
+#include <ndtxt.hxx>
+#include <unotextrange.hxx>
 
 using namespace com::sun::star;
 
@@ -74,17 +76,21 @@ void SwFormatLineBreak::InvalidateLineBreak()
     CallSwClientNotify(sw::LegacyModifyHint(&aItem, &aItem));
 }
 
-uno::Reference<text::XTextRange> SwFormatLineBreak::getAnchor(SwDoc& /*rDoc*/) 
const
+uno::Reference<text::XTextRange> SwFormatLineBreak::GetAnchor() const
 {
     SolarMutexGuard aGuard;
 
-    SAL_WARN("sw.core", "SwFormatLineBreak::getAnchor: not implemented");
     if (!m_pTextAttr)
     {
         return uno::Reference<text::XTextRange>();
     }
 
-    return {};
+    SwPaM aPam(m_pTextAttr->GetTextNode(), m_pTextAttr->GetStart());
+    aPam.SetMark();
+    ++aPam.GetMark()->nContent;
+    uno::Reference<text::XTextRange> xRet
+        = SwXTextRange::CreateXTextRange(aPam.GetDoc(), *aPam.Start(), 
aPam.End());
+    return xRet;
 }
 
 void SwFormatLineBreak::dumpAsXml(xmlTextWriterPtr pWriter) const
@@ -102,6 +108,7 @@ void SwFormatLineBreak::dumpAsXml(xmlTextWriterPtr pWriter) 
const
 
 SwTextLineBreak::SwTextLineBreak(SwFormatLineBreak& rAttr, sal_Int32 nStartPos)
     : SwTextAttr(rAttr, nStartPos)
+    , m_pTextNode(nullptr)
 {
     rAttr.SetTextLineBreak(this);
     SetHasDummyChar(true);
@@ -112,8 +119,25 @@ SwTextLineBreak::~SwTextLineBreak() {}
 void SwTextLineBreak::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwTextLineBreak"));
+    if (m_pTextNode)
+    {
+        (void)xmlTextWriterStartElement(pWriter, BAD_CAST("m_pTextNode"));
+        (void)xmlTextWriterWriteAttribute(
+            pWriter, BAD_CAST("index"),
+            
BAD_CAST(OString::number(sal_Int32(m_pTextNode->GetIndex())).getStr()));
+        (void)xmlTextWriterEndElement(pWriter);
+    }
+
     SwTextAttr::dumpAsXml(pWriter);
     (void)xmlTextWriterEndElement(pWriter);
 }
 
+void SwTextLineBreak::SetTextNode(SwTextNode* pNew) { m_pTextNode = pNew; }
+
+const SwTextNode& SwTextLineBreak::GetTextNode() const
+{
+    assert(m_pTextNode);
+    return *m_pTextNode;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/thints.cxx 
b/sw/source/core/txtnode/thints.cxx
index a04a427826fa..383d5763cd2e 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1528,6 +1528,11 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, 
const SetAttrMode nMode )
                     }
                 }
                 break;
+        case RES_TXTATR_LINEBREAK :
+                {
+                    static_cast<SwTextLineBreak*>(pAttr)->SetTextNode(this);
+                }
+                break;
 
         }
         // CH_TXTATR_* are inserted for SwTextHints without EndIndex
diff --git a/sw/source/core/unocore/unolinebreak.cxx 
b/sw/source/core/unocore/unolinebreak.cxx
index 1d44a273df5d..1c5aeba9152e 100644
--- a/sw/source/core/unocore/unolinebreak.cxx
+++ b/sw/source/core/unocore/unolinebreak.cxx
@@ -23,6 +23,7 @@
 #include <cppuhelper/weakref.hxx>
 #include <sal/log.hxx>
 #include <svl/listener.hxx>
+#include <svl/itemprop.hxx>
 
 #include <IDocumentContentOperations.hxx>
 #include <doc.hxx>
@@ -30,6 +31,8 @@
 #include <unotextrange.hxx>
 #include <ndtxt.hxx>
 #include <textlinebreak.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
 
 using namespace com::sun::star;
 
@@ -40,11 +43,13 @@ public:
     uno::WeakReference<uno::XInterface> m_wThis;
     bool m_bIsDescriptor;
     SwFormatLineBreak* m_pFormatLineBreak;
+    SwLineBreakClear m_eClear;
 
     Impl(SwXLineBreak& rThis, SwFormatLineBreak* const pLineBreak)
         : m_rThis(rThis)
         , m_bIsDescriptor(pLineBreak == nullptr)
         , m_pFormatLineBreak(pLineBreak)
+        , m_eClear(SwLineBreakClear::NONE)
     {
         if (m_pFormatLineBreak)
         {
@@ -52,12 +57,32 @@ public:
         }
     }
 
+    const SwFormatLineBreak* GetLineBreakFormat() const;
+
+    const SwFormatLineBreak& GetLineBreakFormatOrThrow() const;
+
     void Invalidate();
 
 protected:
     void Notify(const SfxHint& rHint) override;
 };
 
+const SwFormatLineBreak* SwXLineBreak::Impl::GetLineBreakFormat() const
+{
+    return m_pFormatLineBreak;
+}
+
+const SwFormatLineBreak& SwXLineBreak::Impl::GetLineBreakFormatOrThrow() const
+{
+    const SwFormatLineBreak* pLineBreak(GetLineBreakFormat());
+    if (!pLineBreak)
+    {
+        throw uno::RuntimeException("SwXLineBreak: disposed or invalid", 
nullptr);
+    }
+
+    return *pLineBreak;
+}
+
 void SwXLineBreak::Impl::Invalidate()
 {
     EndListeningAll();
@@ -126,7 +151,7 @@ void SAL_CALL SwXLineBreak::attach(const 
uno::Reference<text::XTextRange>& xText
     SwUnoInternalPaM aPam(rNewDoc);
     sw::XTextRangeToSwPaM(aPam, xTextRange);
     UnoActionContext aContext(&rNewDoc);
-    SwFormatLineBreak aLineBreak(SwLineBreakClear::ALL);
+    SwFormatLineBreak aLineBreak(m_pImpl->m_eClear);
     SetAttrMode nInsertFlags = SetAttrMode::DEFAULT;
     rNewDoc.getIDocumentContentOperations().InsertPoolItem(aPam, aLineBreak, 
nInsertFlags);
     auto pTextAttr
@@ -146,9 +171,7 @@ uno::Reference<text::XTextRange> SAL_CALL 
SwXLineBreak::getAnchor()
 {
     SolarMutexGuard aGuard;
 
-    SAL_WARN("sw.uno", "SwXLineBreak::getAnnchor: not implemented");
-
-    return {};
+    return m_pImpl->GetLineBreakFormatOrThrow().GetAnchor();
 }
 
 void SAL_CALL SwXLineBreak::dispose()
@@ -172,26 +195,62 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL 
SwXLineBreak::getPropertySetInf
 {
     SolarMutexGuard aGuard;
 
-    SAL_WARN("sw.uno", "SwXLineBreak::getPropertySetInfo: not implemented");
-
-    return {};
+    static uno::Reference<beans::XPropertySetInfo> xRet
+        = 
aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINEBREAK)->getPropertySetInfo();
+    return xRet;
 }
 
-void SAL_CALL SwXLineBreak::setPropertyValue(const OUString& /*rPropertyName*/,
-                                             const css::uno::Any& /*rValue*/)
+void SAL_CALL SwXLineBreak::setPropertyValue(const OUString& rPropertyName,
+                                             const css::uno::Any& rValue)
 {
     SolarMutexGuard aGuard;
 
-    SAL_WARN("sw.uno", "SwXLineBreak::setPropertySetInfo: not implemented");
+    if (rPropertyName != UNO_NAME_CLEAR)
+    {
+        throw lang::IllegalArgumentException();
+    }
+
+    if (m_pImpl->m_bIsDescriptor)
+    {
+        sal_Int16 eValue{};
+        if (rValue >>= eValue)
+        {
+            m_pImpl->m_eClear = static_cast<SwLineBreakClear>(eValue);
+        }
+    }
+    else
+    {
+        m_pImpl->m_pFormatLineBreak->PutValue(rValue, 0);
+    }
 }
 
-uno::Any SAL_CALL SwXLineBreak::getPropertyValue(const OUString& 
/*rPropertyName*/)
+uno::Any SAL_CALL SwXLineBreak::getPropertyValue(const OUString& rPropertyName)
 {
     SolarMutexGuard aGuard;
 
-    SAL_WARN("sw.uno", "SwXLineBreak::getPropertyValue: not implemented");
+    uno::Any aRet;
+    if (sw::GetDefaultTextContentValue(aRet, rPropertyName))
+    {
+        return aRet;
+    }
+
+    if (rPropertyName != UNO_NAME_CLEAR)
+    {
+        beans::UnknownPropertyException aExcept;
+        aExcept.Message = rPropertyName;
+        throw aExcept;
+    }
 
-    return {};
+    if (m_pImpl->m_bIsDescriptor)
+    {
+        auto eValue = static_cast<sal_Int16>(m_pImpl->m_eClear);
+        aRet <<= eValue;
+    }
+    else
+    {
+        m_pImpl->m_pFormatLineBreak->QueryValue(aRet, 0);
+    }
+    return aRet;
 }
 
 void SAL_CALL SwXLineBreak::addPropertyChangeListener(
diff --git a/sw/source/core/unocore/unomap.cxx 
b/sw/source/core/unocore/unomap.cxx
index 053e80e83ca9..312b07b68786 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -1554,6 +1554,11 @@ const SfxItemPropertyMapEntry* 
SwUnoPropertyMapProvider::GetPropertyMapEntries(s
                 m_aMapEntriesArr[nPropertyId] = aCellStyleMap;
             }
             break;
+            case PROPERTY_MAP_LINEBREAK:
+            {
+                m_aMapEntriesArr[nPropertyId] = GetLineBreakPropertyMap();
+            }
+            break;
 
             default:
                 OSL_FAIL( "unexpected property map ID" );
diff --git a/sw/source/core/unocore/unomap1.cxx 
b/sw/source/core/unocore/unomap1.cxx
index 543bee1363f9..77b0909faec6 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1008,6 +1008,18 @@ const SfxItemPropertyMapEntry*  
SwUnoPropertyMapProvider::GetFootnotePropertyMap
     return aFootnoteMap_Impl;
 }
 
+const SfxItemPropertyMapEntry* 
SwUnoPropertyMapProvider::GetLineBreakPropertyMap()
+{
+    static SfxItemPropertyMapEntry const aLineBreakMap_Impl[] =
+    {
+        { u"" UNO_NAME_CLEAR, 0, cppu::UnoType<sal_Int16>::get(), 
PROPERTY_NONE, 0 },
+        COMMON_TEXT_CONTENT_PROPERTIES
+        { u"", 0, css::uno::Type(), 0, 0 }
+    };
+
+    return aLineBreakMap_Impl;
+}
+
 const SfxItemPropertyMapEntry*  
SwUnoPropertyMapProvider::GetRedlinePropertyMap()
 {
     static SfxItemPropertyMapEntry const aRedlineMap_Impl[] =
@@ -1661,6 +1673,12 @@ const SfxItemPropertySet*  
SwUnoPropertyMapProvider::GetPropertySet( sal_uInt16
                 m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_CELL_STYLE;
             }
             break;
+            case PROPERTY_MAP_LINEBREAK:
+            {
+                static SfxItemPropertySet aPROPERTY_MAP_LINEBREAK(pEntries);
+                m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_LINEBREAK;
+            }
+            break;
         }
     }
     return m_aPropertySetArr[nPropertyId];

Reply via email to