summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/source/core/inc/unoparaframeenum.hxx4
-rw-r--r--sw/source/core/unocore/unoobj2.cxx25
-rw-r--r--sw/source/core/unocore/unoparagraph.cxx18
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx79
4 files changed, 92 insertions, 34 deletions
diff --git a/sw/source/core/inc/unoparaframeenum.hxx b/sw/source/core/inc/unoparaframeenum.hxx
index 81a653aac57f..c44e0f660c6d 100644
--- a/sw/source/core/inc/unoparaframeenum.hxx
+++ b/sw/source/core/inc/unoparaframeenum.hxx
@@ -31,6 +31,8 @@ class SwNodeIndex;
class SwPaM;
class SwFrameFormat;
+namespace com { namespace sun { namespace star { namespace text { class XTextContent; } } } }
+
namespace sw
{
struct FrameClient final : public SwClient
@@ -70,6 +72,8 @@ struct SwXParaFrameEnumeration
static rtl::Reference<SwXParaFrameEnumeration> Create(const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, SwFrameFormat* const pFormat = nullptr);
};
+css::uno::Reference<css::text::XTextContent> FrameClientToXTextContent(sw::FrameClient* pClient);
+
#endif // INCLUDED_SW_SOURCE_CORE_INC_UNOPARAFRAMEENUM_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index e4f5ccdf22d9..7614f0a31485 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -1788,9 +1788,17 @@ bool SwXParaFrameEnumerationImpl::CreateNextObject()
if (m_vFrames.empty())
return false;
- SwFrameFormat* const pFormat = static_cast<SwFrameFormat*>(
- m_vFrames.front()->GetRegisteredIn());
+ m_xNextObject.set(FrameClientToXTextContent(m_vFrames.front().get()));
m_vFrames.pop_front();
+ return m_xNextObject.is();
+}
+
+uno::Reference<text::XTextContent> FrameClientToXTextContent(sw::FrameClient* pClient)
+{
+ assert(pClient);
+
+ uno::Reference<text::XTextContent> xRet;
+ SwFrameFormat* const pFormat = static_cast<SwFrameFormat*>(pClient->GetRegisteredIn());
// the format should be valid here, otherwise the client
// would have been removed by PurgeFrameClients
// check for a shape first
@@ -1799,33 +1807,32 @@ bool SwXParaFrameEnumerationImpl::CreateNextObject()
SdrObject* pObject(nullptr);
pFormat->CallSwClientNotify(sw::FindSdrObjectHint(pObject));
if(pObject)
- m_xNextObject.set(pObject->getUnoShape(), uno::UNO_QUERY);
+ xRet.set(pObject->getUnoShape(), uno::UNO_QUERY);
}
else
{
const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
OSL_ENSURE(pIdx, "where is the index?");
- SwNode const*const pNd =
- m_pUnoCursor->GetDoc().GetNodes()[ pIdx->GetIndex() + 1 ];
+ SwNode const* const pNd = pIdx->GetNodes()[pIdx->GetIndex() + 1];
if (!pNd->IsNoTextNode())
{
- m_xNextObject = static_cast<SwXFrame*>(SwXTextFrame::CreateXTextFrame(
+ xRet = static_cast<SwXFrame*>(SwXTextFrame::CreateXTextFrame(
*pFormat->GetDoc(), pFormat).get());
}
else if (pNd->IsGrfNode())
{
- m_xNextObject.set(SwXTextGraphicObject::CreateXTextGraphicObject(
+ xRet.set(SwXTextGraphicObject::CreateXTextGraphicObject(
*pFormat->GetDoc(), pFormat));
}
else
{
assert(pNd->IsOLENode());
- m_xNextObject.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
+ xRet.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
*pFormat->GetDoc(), pFormat));
}
}
- return m_xNextObject.is();
+ return xRet;
}
sal_Bool SAL_CALL
diff --git a/sw/source/core/unocore/unoparagraph.cxx b/sw/source/core/unocore/unoparagraph.cxx
index 68dbe34f55d5..dab5270588e3 100644
--- a/sw/source/core/unocore/unoparagraph.cxx
+++ b/sw/source/core/unocore/unoparagraph.cxx
@@ -54,6 +54,7 @@
#include <com/sun/star/drawing/BitmapMode.hpp>
#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequence.hxx>
#include <comphelper/servicehelper.hxx>
#include <editeng/unoipset.hxx>
#include <svl/listener.hxx>
@@ -550,6 +551,23 @@ uno::Sequence< uno::Any > SwXParagraph::Impl::GetPropertyValues_Impl(
continue;
}
+ if (pPropertyNames[nProp] == "OOXMLImport_AnchoredShapes")
+ {
+ // A hack to provide list of anchored objects fast
+ // See reanchorObjects in writerfilter/source/dmapper/DomainMapper_Impl.cxx
+ FrameClientSortList_t aFrames;
+ CollectFrameAtNode(rTextNode, aFrames, false); // Frames anchored to paragraph
+ CollectFrameAtNode(rTextNode, aFrames, true); // Frames anchored to character
+ std::vector<uno::Reference<text::XTextContent>> aRet;
+ aRet.reserve(aFrames.size());
+ for (const auto& rFrame : aFrames)
+ if (auto xContent = FrameClientToXTextContent(rFrame.pFrameClient.get()))
+ aRet.push_back(xContent);
+
+ pValues[nProp] <<= comphelper::containerToSequence(aRet);
+ continue;
+ }
+
SfxItemPropertyMapEntry const*const pEntry =
rMap.getByName( pPropertyNames[nProp] );
if (!pEntry)
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 57a9f3bc5223..0ae745eec97a 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -750,6 +750,59 @@ void DomainMapper_Impl::AddDummyParaForTableInSection()
return sName;
}
+static void reanchorObjects(const uno::Reference<uno::XInterface>& xFrom,
+ const uno::Reference<text::XTextRange>& xTo,
+ const uno::Reference<drawing::XDrawPage>& xDrawPage)
+{
+ std::vector<uno::Reference<text::XTextContent>> aShapes;
+ bool bFastPathDone = false;
+ if (uno::Reference<beans::XPropertySet> xProps{ xFrom, uno::UNO_QUERY })
+ {
+ try
+ {
+ // See SwXParagraph::Impl::GetPropertyValues_Impl
+ uno::Sequence<uno::Reference<text::XTextContent>> aSeq;
+ xProps->getPropertyValue(u"OOXMLImport_AnchoredShapes"_ustr) >>= aSeq;
+ aShapes.insert(aShapes.end(), aSeq.begin(), aSeq.end());
+ bFastPathDone = true;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+
+ if (!bFastPathDone)
+ {
+ // Can this happen? Fallback to slow DrawPage iteration and range comparison
+ uno::Reference<text::XTextRange> xRange(xFrom, uno::UNO_QUERY_THROW);
+ uno::Reference<text::XTextRangeCompare> xCompare(xRange->getText(), uno::UNO_QUERY_THROW);
+
+ const sal_Int32 count = xDrawPage->getCount();
+ for (sal_Int32 i = 0; i < count; ++i)
+ {
+ try
+ {
+ uno::Reference<text::XTextContent> xShape(xDrawPage->getByIndex(i),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<text::XTextRange> xAnchor(xShape->getAnchor(), uno::UNO_SET_THROW);
+ if (xCompare->compareRegionStarts(xAnchor, xRange) <= 0
+ && xCompare->compareRegionEnds(xAnchor, xRange) >= 0)
+ {
+ aShapes.push_back(xShape);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ // Can happen e.g. in compareRegion*, when the shape is in a header,
+ // and paragraph in body
+ }
+ }
+ }
+
+ for (const auto& xShape : aShapes)
+ xShape->attach(xTo);
+}
+
void DomainMapper_Impl::RemoveLastParagraph( )
{
if (m_bDiscardHeaderFooter)
@@ -828,31 +881,7 @@ void DomainMapper_Impl::RemoveLastParagraph( )
auto xEnumeration = xEA->createEnumeration();
uno::Reference<text::XTextRange> xPrevParagraph(xEnumeration->nextElement(),
uno::UNO_QUERY_THROW);
-
- uno::Reference<text::XTextRange> xParaRange(xParagraph, uno::UNO_QUERY_THROW);
- uno::Reference<text::XTextRangeCompare> xRegionCompare(xParaRange->getText(),
- uno::UNO_QUERY_THROW);
- const sal_Int32 count = xDrawPage->getCount();
- for (sal_Int32 i = 0; i < count; ++i)
- {
- try
- {
- uno::Reference<text::XTextContent> xShape(xDrawPage->getByIndex(i),
- uno::UNO_QUERY_THROW);
- uno::Reference<text::XTextRange> xAnchor(xShape->getAnchor(),
- uno::UNO_SET_THROW);
- if (xRegionCompare->compareRegionStarts(xAnchor, xParaRange) <= 0
- && xRegionCompare->compareRegionEnds(xAnchor, xParaRange) >= 0)
- {
- xShape->attach(xPrevParagraph);
- }
- }
- catch (const uno::Exception&)
- {
- // Can happen e.g. in compareRegion*, when the shape is in a header,
- // and paragraph in body
- }
- }
+ reanchorObjects(xParagraph, xPrevParagraph, xDrawPage);
}
xParagraph->dispose();