summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-03-01 16:44:03 +0100
committerMiklos Vajna <vmiklos@collabora.com>2022-03-01 19:52:31 +0100
commit5028e5670da25ec1e8eeee62789b744c32e6108b (patch)
tree4dcc91bb0b928e4d7d5cb26ad3feedbf35d25932 /sw
parent2c5d4436f05ee99cf6937940f2010edf90e7f9e9 (diff)
sw clearing breaks: add UNO API to insert this
This only allows the clear=all break type, the others are not yet handled. Change-Id: Id4981b3cc0a8faca2166ad93827ae547f5539095 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130741 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/Library_sw.mk1
-rw-r--r--sw/inc/unocoll.hxx1
-rw-r--r--sw/qa/core/unocore/unocore.cxx32
-rw-r--r--sw/source/core/bastyp/init.cxx2
-rw-r--r--sw/source/core/inc/unolinebreak.hxx91
-rw-r--r--sw/source/core/txtnode/attrlinebreak.cxx1
-rw-r--r--sw/source/core/txtnode/thints.cxx5
-rw-r--r--sw/source/core/unocore/unocoll.cxx7
-rw-r--r--sw/source/core/unocore/unolinebreak.cxx236
9 files changed, 374 insertions, 2 deletions
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index 401ac0d307fd..30c53b6131b1 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -489,6 +489,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
sw/source/core/unocore/unoframe \
sw/source/core/unocore/unoftn \
sw/source/core/unocore/unoidx \
+ sw/source/core/unocore/unolinebreak \
sw/source/core/unocore/unomap \
sw/source/core/unocore/unomap1 \
sw/source/core/unocore/unoobj \
diff --git a/sw/inc/unocoll.hxx b/sw/inc/unocoll.hxx
index ae16ab4ab7bc..821d50ab4a2c 100644
--- a/sw/inc/unocoll.hxx
+++ b/sw/inc/unocoll.hxx
@@ -176,6 +176,7 @@ enum class SwServiceType {
VbaGlobals = 113,
StyleTable = 114,
StyleCell = 115,
+ LineBreak = 116,
Invalid = USHRT_MAX
};
diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx
index 55bfa1425528..b7d92d8485ac 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -22,6 +22,8 @@
#include <unotextrange.hxx>
#include <unotxdoc.hxx>
#include <docsh.hxx>
+#include <ndtxt.hxx>
+#include <textlinebreak.hxx>
using namespace ::com::sun::star;
@@ -214,6 +216,36 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testBrokenEmbeddedObject)
xEmbeddedObject->supportsService("com.sun.star.comp.embed.OCommonEmbeddedObject"));
}
+CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testLineBreakInsert)
+{
+ // Given an empty document:
+ SwDoc* pDoc = createSwDoc();
+
+ // When inserting a line-break with properties:
+ uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, uno::UNO_QUERY);
+ 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<text::XText> xText = xTextDocument->getText();
+ uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+ xText->insertTextContent(xCursor, xLineBreak, /*bAbsorb=*/false);
+
+ // Then make sure that both the line break and its matching text attribute is inserted:
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ SwNodeOffset nIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
+ SwTextNode* pTextNode = pDoc->GetNodes()[nIndex]->GetTextNode();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: "\n" (newline)
+ // - Actual : "" (empty string)
+ // i.e. SwXLineBreak::attach() did not insert the newline + its text attribute.
+ CPPUNIT_ASSERT_EQUAL(OUString("\n"), pTextNode->GetText());
+ SwTextAttr* pAttr = pTextNode->GetTextAttrForCharAt(0, RES_TXTATR_LINEBREAK);
+ CPPUNIT_ASSERT(pAttr);
+ auto pTextLineBreak = static_cast<SwTextLineBreak*>(pAttr);
+ auto& rFormatLineBreak = static_cast<SwFormatLineBreak&>(pTextLineBreak->GetAttr());
+ CPPUNIT_ASSERT_EQUAL(SwLineBreakClear::ALL, rFormatLineBreak.GetValue());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index 9bbe888ba3b9..f7ad215602bf 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -320,7 +320,7 @@ SfxItemInfo aSlotTab[] =
{ 0, false }, // RES_TXTATR_FLYCNT
{ 0, false }, // RES_TXTATR_FTN
{ 0, false }, // RES_TXTATR_ANNOTATION
- { 0, true }, // RES_TXTATR_LINEBREAK
+ { 0, false }, // RES_TXTATR_LINEBREAK
{ 0, true }, // RES_TXTATR_DUMMY1
{ 0, true }, // RES_TXTATR_DUMMY2
diff --git a/sw/source/core/inc/unolinebreak.hxx b/sw/source/core/inc/unolinebreak.hxx
new file mode 100644
index 000000000000..1eb939e24b68
--- /dev/null
+++ b/sw/source/core/inc/unolinebreak.hxx
@@ -0,0 +1,91 @@
+/* -*- 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/.
+ *
+ * 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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_INC_UNOLINEBREAK_HXX
+#define INCLUDED_SW_SOURCE_CORE_INC_UNOLINEBREAK_HXX
+
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+
+#include <unobaseclass.hxx>
+
+class SwDoc;
+class SwFormatLineBreak;
+
+/// UNO API wrapper around an SwFormatLineBreak, exposed as the com.sun.star.text.LineBreak service.
+class SwXLineBreak final
+ : public cppu::WeakImplHelper<css::beans::XPropertySet, css::lang::XServiceInfo,
+ css::text::XTextContent, css::lang::XUnoTunnel>
+{
+ class Impl;
+ ::sw::UnoImplPtr<Impl> m_pImpl;
+
+ SwXLineBreak(SwFormatLineBreak& rFormat);
+ SwXLineBreak();
+
+ ~SwXLineBreak() override;
+
+public:
+ static css::uno::Reference<css::text::XTextContent> CreateXLineBreak();
+
+ // XPropertySet
+ css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override;
+ void SAL_CALL setPropertyValue(const OUString& rPropertyName,
+ const css::uno::Any& rValue) override;
+ css::uno::Any SAL_CALL getPropertyValue(const OUString& rPropertyName) override;
+ void SAL_CALL addPropertyChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference<css::beans::XPropertyChangeListener>& xListener) override;
+ void SAL_CALL removePropertyChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference<css::beans::XPropertyChangeListener>& xListener) override;
+ void SAL_CALL addVetoableChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference<css::beans::XVetoableChangeListener>& xListener) override;
+ void SAL_CALL removeVetoableChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference<css::beans::XVetoableChangeListener>& xListener) override;
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() override;
+ sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
+ css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+ // XTextContent
+ void SAL_CALL attach(const css::uno::Reference<css::text::XTextRange>& xTextRange) override;
+ css::uno::Reference<css::text::XTextRange> SAL_CALL getAnchor() override;
+
+ // XComponent, via XTextContent
+ void SAL_CALL dispose() override;
+ void SAL_CALL
+ addEventListener(const css::uno::Reference<css::lang::XEventListener>& xListener) override;
+ void SAL_CALL
+ removeEventListener(const css::uno::Reference<css::lang::XEventListener>& xListener) override;
+
+ // XUnoTunnel
+ sal_Int64 SAL_CALL getSomething(const css::uno::Sequence<sal_Int8>& rIdentifier) override;
+
+ static const css::uno::Sequence<sal_Int8>& getUnoTunnelId();
+};
+
+#endif // INCLUDED_SW_SOURCE_CORE_INC_UNOLINEBREAK_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/attrlinebreak.cxx b/sw/source/core/txtnode/attrlinebreak.cxx
index 64aedd9d2be1..f0f583ecc2df 100644
--- a/sw/source/core/txtnode/attrlinebreak.cxx
+++ b/sw/source/core/txtnode/attrlinebreak.cxx
@@ -104,6 +104,7 @@ SwTextLineBreak::SwTextLineBreak(SwFormatLineBreak& rAttr, sal_Int32 nStartPos)
: SwTextAttr(rAttr, nStartPos)
{
rAttr.SetTextLineBreak(this);
+ SetHasDummyChar(true);
}
SwTextLineBreak::~SwTextLineBreak() {}
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index 4ca96f593cb4..a04a427826fa 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -3476,6 +3476,11 @@ sal_Unicode GetCharOfTextAttr( const SwTextAttr& rAttr )
cRet = CH_TXTATR_BREAKWORD;
}
break;
+ case RES_TXTATR_LINEBREAK:
+ {
+ cRet = CH_TXTATR_NEWLINE;
+ }
+ break;
default:
assert(!"GetCharOfTextAttr: unknown attr");
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 5edf059d4885..cb7a0bbb390f 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -43,6 +43,7 @@
#include <unoframe.hxx>
#include <textboxhelper.hxx>
#include <unofootnote.hxx>
+#include <unolinebreak.hxx>
#include <vcl/svapp.hxx>
#include <fmtcntnt.hxx>
#include <authfld.hxx>
@@ -453,7 +454,8 @@ const ProvNamesId_Type aProvNamesId[] =
{ CSS_TEXT_FIELDMASTER_DATABASE, SwServiceType::FieldMasterDatabase },
{ CSS_TEXT_FIELDMASTER_BIBLIOGRAPHY, SwServiceType::FieldMasterBibliography },
{ "com.sun.star.style.TableStyle", SwServiceType::StyleTable },
- { "com.sun.star.style.CellStyle", SwServiceType::StyleCell }
+ { "com.sun.star.style.CellStyle", SwServiceType::StyleCell },
+ { "com.sun.star.text.LineBreak", SwServiceType::LineBreak }
};
const SvEventDescription* sw_GetSupportedMacroItems()
@@ -823,6 +825,9 @@ SwXServiceProvider::MakeInstance(SwServiceType nObjectType, SwDoc & rDoc)
case SwServiceType::FieldTypeMetafield:
xRet = SwXMeta::CreateXMeta(rDoc, true);
break;
+ case SwServiceType::LineBreak:
+ xRet = SwXLineBreak::CreateXLineBreak();
+ break;
default:
throw uno::RuntimeException();
}
diff --git a/sw/source/core/unocore/unolinebreak.cxx b/sw/source/core/unocore/unolinebreak.cxx
new file mode 100644
index 000000000000..1d44a273df5d
--- /dev/null
+++ b/sw/source/core/unocore/unolinebreak.cxx
@@ -0,0 +1,236 @@
+/* -*- 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/.
+ *
+ * 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 <unolinebreak.hxx>
+
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <sal/log.hxx>
+#include <svl/listener.hxx>
+
+#include <IDocumentContentOperations.hxx>
+#include <doc.hxx>
+#include <formatlinebreak.hxx>
+#include <unotextrange.hxx>
+#include <ndtxt.hxx>
+#include <textlinebreak.hxx>
+
+using namespace com::sun::star;
+
+class SwXLineBreak::Impl : public SvtListener
+{
+public:
+ SwXLineBreak& m_rThis;
+ uno::WeakReference<uno::XInterface> m_wThis;
+ bool m_bIsDescriptor;
+ SwFormatLineBreak* m_pFormatLineBreak;
+
+ Impl(SwXLineBreak& rThis, SwFormatLineBreak* const pLineBreak)
+ : m_rThis(rThis)
+ , m_bIsDescriptor(pLineBreak == nullptr)
+ , m_pFormatLineBreak(pLineBreak)
+ {
+ if (m_pFormatLineBreak)
+ {
+ StartListening(m_pFormatLineBreak->GetNotifier());
+ }
+ }
+
+ void Invalidate();
+
+protected:
+ void Notify(const SfxHint& rHint) override;
+};
+
+void SwXLineBreak::Impl::Invalidate()
+{
+ EndListeningAll();
+ m_pFormatLineBreak = nullptr;
+}
+
+void SwXLineBreak::Impl::Notify(const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::Dying)
+ {
+ Invalidate();
+ }
+}
+
+SwXLineBreak::SwXLineBreak(SwFormatLineBreak& rFormat)
+ : m_pImpl(new SwXLineBreak::Impl(*this, &rFormat))
+{
+}
+
+SwXLineBreak::SwXLineBreak()
+ : m_pImpl(new SwXLineBreak::Impl(*this, nullptr))
+{
+}
+
+SwXLineBreak::~SwXLineBreak() {}
+
+uno::Reference<text::XTextContent> SwXLineBreak::CreateXLineBreak()
+{
+ uno::Reference<text::XTextContent> xLineBreak;
+
+ rtl::Reference<SwXLineBreak> pLineBreak(new SwXLineBreak);
+ xLineBreak.set(pLineBreak);
+ pLineBreak->m_pImpl->m_wThis = xLineBreak;
+
+ return xLineBreak;
+}
+
+OUString SAL_CALL SwXLineBreak::getImplementationName() { return "SwXLineBreak"; }
+
+sal_Bool SAL_CALL SwXLineBreak::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL SwXLineBreak::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.LineBreak" };
+}
+
+void SAL_CALL SwXLineBreak::attach(const uno::Reference<text::XTextRange>& xTextRange)
+{
+ SolarMutexGuard aGuard;
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel(xTextRange, uno::UNO_QUERY);
+ auto pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ if (!pRange)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwDoc& rNewDoc = pRange->GetDoc();
+ SwUnoInternalPaM aPam(rNewDoc);
+ sw::XTextRangeToSwPaM(aPam, xTextRange);
+ UnoActionContext aContext(&rNewDoc);
+ SwFormatLineBreak aLineBreak(SwLineBreakClear::ALL);
+ SetAttrMode nInsertFlags = SetAttrMode::DEFAULT;
+ rNewDoc.getIDocumentContentOperations().InsertPoolItem(aPam, aLineBreak, nInsertFlags);
+ auto pTextAttr
+ = static_cast<SwTextLineBreak*>(aPam.GetNode().GetTextNode()->GetTextAttrForCharAt(
+ aPam.GetPoint()->nContent.GetIndex() - 1, RES_TXTATR_LINEBREAK));
+ if (pTextAttr)
+ {
+ m_pImpl->EndListeningAll();
+ auto pLineBreak = const_cast<SwFormatLineBreak*>(&pTextAttr->GetLineBreak());
+ m_pImpl->m_pFormatLineBreak = pLineBreak;
+ m_pImpl->StartListening(pLineBreak->GetNotifier());
+ }
+ m_pImpl->m_bIsDescriptor = false;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL SwXLineBreak::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ SAL_WARN("sw.uno", "SwXLineBreak::getAnnchor: not implemented");
+
+ return {};
+}
+
+void SAL_CALL SwXLineBreak::dispose()
+{
+ SolarMutexGuard aGuard;
+
+ SAL_WARN("sw.uno", "SwXLineBreak::dispose: not implemented");
+}
+
+void SAL_CALL
+SwXLineBreak::addEventListener(const uno::Reference<lang::XEventListener>& /*xListener*/)
+{
+}
+
+void SAL_CALL
+SwXLineBreak::removeEventListener(const uno::Reference<lang::XEventListener>& /*xListener*/)
+{
+}
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL SwXLineBreak::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+
+ SAL_WARN("sw.uno", "SwXLineBreak::getPropertySetInfo: not implemented");
+
+ return {};
+}
+
+void SAL_CALL SwXLineBreak::setPropertyValue(const OUString& /*rPropertyName*/,
+ const css::uno::Any& /*rValue*/)
+{
+ SolarMutexGuard aGuard;
+
+ SAL_WARN("sw.uno", "SwXLineBreak::setPropertySetInfo: not implemented");
+}
+
+uno::Any SAL_CALL SwXLineBreak::getPropertyValue(const OUString& /*rPropertyName*/)
+{
+ SolarMutexGuard aGuard;
+
+ SAL_WARN("sw.uno", "SwXLineBreak::getPropertyValue: not implemented");
+
+ return {};
+}
+
+void SAL_CALL SwXLineBreak::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::addPropertyChangeListener: not implemented");
+}
+
+void SAL_CALL SwXLineBreak::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::removePropertyChangeListener: not implemented");
+}
+
+void SAL_CALL SwXLineBreak::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::addVetoableChangeListener: not implemented");
+}
+
+void SAL_CALL SwXLineBreak::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::removeVetoableChangeListener: not implemented");
+}
+
+sal_Int64 SAL_CALL SwXLineBreak::getSomething(const css::uno::Sequence<sal_Int8>& rIdentifier)
+{
+ return comphelper::getSomethingImpl<SwXLineBreak>(rIdentifier, this);
+}
+
+const uno::Sequence<sal_Int8>& SwXLineBreak::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit theSwXLineBreakUnoTunnelId;
+ return theSwXLineBreakUnoTunnelId.getSeq();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */