diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-03-02 09:38:14 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-03-02 10:36:12 +0100 |
commit | 1a240807f2c051ff9a63d713625404a024d7c221 (patch) | |
tree | 05ebf0969a011658e5cb99c318e8e227df91886a | |
parent | 46cf4096b794b11fee2bf75975f1083a38d889ec (diff) |
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 <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/inc/formatlinebreak.hxx | 2 | ||||
-rw-r--r-- | sw/inc/textlinebreak.hxx | 5 | ||||
-rw-r--r-- | sw/inc/unomap.hxx | 4 | ||||
-rw-r--r-- | sw/inc/unoprnms.hxx | 1 | ||||
-rw-r--r-- | sw/qa/core/unocore/unocore.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/txtnode/attrlinebreak.cxx | 30 | ||||
-rw-r--r-- | sw/source/core/txtnode/thints.cxx | 5 | ||||
-rw-r--r-- | sw/source/core/unocore/unolinebreak.cxx | 85 | ||||
-rw-r--r-- | sw/source/core/unocore/unomap.cxx | 5 | ||||
-rw-r--r-- | sw/source/core/unocore/unomap1.cxx | 18 |
10 files changed, 140 insertions, 18 deletions
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]; |