summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/xmloff/txtimp.hxx5
-rwxr-xr-xsw/qa/extras/odfimport/data/tdf100033_1.odtbin0 -> 9367 bytes
-rwxr-xr-xsw/qa/extras/odfimport/data/tdf100033_2.odtbin0 -> 9401 bytes
-rw-r--r--sw/qa/extras/odfimport/odfimport.cxx16
-rw-r--r--xmloff/source/text/XMLTextFrameContext.cxx29
-rw-r--r--xmloff/source/text/txtimp.cxx71
6 files changed, 112 insertions, 9 deletions
diff --git a/include/xmloff/txtimp.hxx b/include/xmloff/txtimp.hxx
index 3e8ff127cd03..109469cf74ba 100644
--- a/include/xmloff/txtimp.hxx
+++ b/include/xmloff/txtimp.hxx
@@ -523,6 +523,11 @@ public:
GetChapterNumbering() const;
bool HasFrameByName( const OUString& rName ) const;
+
+ bool IsDuplicateFrame(const OUString& sName, sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight) const;
+ void StoreLastImportedFrameName(const OUString& rName);
+ void ClearLastImportedTextFrameName();
+
void ConnectFrameChains( const OUString& rFrmName,
const OUString& rNextFrmName,
const css::uno::Reference< css::beans::XPropertySet >& rFrmPropSet );
diff --git a/sw/qa/extras/odfimport/data/tdf100033_1.odt b/sw/qa/extras/odfimport/data/tdf100033_1.odt
new file mode 100755
index 000000000000..b7f3ae7aaeb4
--- /dev/null
+++ b/sw/qa/extras/odfimport/data/tdf100033_1.odt
Binary files differ
diff --git a/sw/qa/extras/odfimport/data/tdf100033_2.odt b/sw/qa/extras/odfimport/data/tdf100033_2.odt
new file mode 100755
index 000000000000..98ae7bd6b31d
--- /dev/null
+++ b/sw/qa/extras/odfimport/data/tdf100033_2.odt
Binary files differ
diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx
index ce4a69b7b369..06f2bf7f8a9c 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -784,5 +784,21 @@ DECLARE_ODFIMPORT_TEST(testTdf107392, "tdf107392.odt")
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), getProperty<sal_Int32>(getShapeByName("SVG"), "ZOrder"));
}
+DECLARE_ODFIMPORT_TEST(testTdf100033_1, "tdf100033_1.odt")
+{
+ // Test document have three duplicated frames with the same name and position/size -> import one frame
+ uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
+}
+
+DECLARE_ODFIMPORT_TEST(testTdf100033_2, "tdf100033_2.odt")
+{
+ // Test document have three different frames anchored to different paragraphs -> import all frames
+ uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xIndexAccess->getCount());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/text/XMLTextFrameContext.cxx b/xmloff/source/text/XMLTextFrameContext.cxx
index 539d41e4fd8e..ece946e001b6 100644
--- a/xmloff/source/text/XMLTextFrameContext.cxx
+++ b/xmloff/source/text/XMLTextFrameContext.cxx
@@ -368,6 +368,7 @@ class XMLTextFrameContext_Impl : public SvXMLImportContext
bool bSyncHeight : 1;
bool bCreateFailed : 1;
bool bOwnBase64Stream : 1;
+ bool mbMultipleContent : 1; // This context is created based on a multiple content (image)
void Create();
@@ -383,7 +384,8 @@ public:
const css::uno::Reference<css::xml::sax::XAttributeList > & rAttrList,
css::text::TextContentAnchorType eAnchorType,
sal_uInt16 nType,
- const css::uno::Reference<css::xml::sax::XAttributeList > & rFrameAttrList );
+ const css::uno::Reference<css::xml::sax::XAttributeList > & rFrameAttrList,
+ bool bMultipleContent = false );
virtual void EndElement() override;
@@ -405,6 +407,8 @@ public:
void SetName();
+ const OUString& GetOrigName() const { return m_sOrigName; }
+
css::text::TextContentAnchorType GetAnchorType() const { return eAnchorType; }
const css::uno::Reference < css::beans::XPropertySet >& GetPropSet() const { return xPropSet; }
@@ -520,6 +524,14 @@ void XMLTextFrameContext_Impl::Create()
Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
+ // Skip duplicated frames
+ if(!mbMultipleContent && // It's allowed to have multiple image for the same frame
+ xTextImportHelper->IsDuplicateFrame(sName, nX, nY, nWidth, nHeight))
+ {
+ bCreateFailed = true;
+ return;
+ }
+
// set name
Reference < XNamed > xNamed( xPropSet, UNO_QUERY );
if( xNamed.is() )
@@ -539,14 +551,9 @@ void XMLTextFrameContext_Impl::Create()
xNamed->setName( sName );
if( sName != sOldName )
{
- bool bSuccess = xTextImportHelper->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_FRAME,
+ xTextImportHelper->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_FRAME,
sOldName, sName );
- if (!bSuccess && !sOldName.isEmpty())
- {
- bCreateFailed = true;
- return;
- }
}
}
}
@@ -787,7 +794,8 @@ XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
const Reference< XAttributeList > & rAttrList,
TextContentAnchorType eATyp,
sal_uInt16 nNewType,
- const Reference< XAttributeList > & rFrameAttrList )
+ const Reference< XAttributeList > & rFrameAttrList,
+ bool bMultipleContent )
: SvXMLImportContext( rImport, nPrfx, rLName )
, mbListContextPushed( false )
, nType( nNewType )
@@ -810,6 +818,7 @@ XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
bSyncHeight = false;
bCreateFailed = false;
bOwnBase64Stream = false;
+ mbMultipleContent = bMultipleContent;
rtl::Reference < XMLTextImportHelper > xTxtImport =
GetImport().GetTextImport();
@@ -1363,6 +1372,8 @@ void XMLTextFrameContext::EndElement()
m_pHyperlink.reset();
}
+ GetImport().GetTextImport()->StoreLastImportedFrameName(pImpl->GetOrigName());
+
}
}
@@ -1466,7 +1477,7 @@ SvXMLImportContext *XMLTextFrameContext::CreateChildContext(
// read another image
pContext = new XMLTextFrameContext_Impl(
GetImport(), p_nPrefix, rLocalName, xAttrList,
- m_eDefaultAnchorType, XML_TEXT_FRAME_GRAPHIC, m_xAttrList);
+ m_eDefaultAnchorType, XML_TEXT_FRAME_GRAPHIC, m_xAttrList, true);
m_xImplContext = pContext;
addContent(*m_xImplContext.get());
diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index 2f248359b58f..4d5543bbddbd 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -537,6 +537,9 @@ struct XMLTextImportHelper::Impl
/// name of the last 'open' redline that started between paragraphs
OUString m_sOpenRedlineIdentifier;
+ // Used for frame deduplication, the name of the last frame imported directly before the current one
+ OUString msLastImportedFrameName;
+
uno::Reference<text::XText> m_xText;
uno::Reference<text::XTextCursor> m_xCursor;
uno::Reference<text::XTextRange> m_xCursorAsRange;
@@ -1108,6 +1111,72 @@ bool XMLTextImportHelper::HasFrameByName( const OUString& rName ) const
m_xImpl->m_xObjects->hasByName(rName));
}
+bool XMLTextImportHelper::IsDuplicateFrame(const OUString& sName, sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight) const
+{
+ if (HasFrameByName(sName))
+ {
+ uno::Reference<beans::XPropertySet> xOtherFrame;
+ if(m_xImpl->m_xTextFrames && m_xImpl->m_xTextFrames->hasByName(sName))
+ xOtherFrame.set(m_xImpl->m_xTextFrames->getByName(sName), uno::UNO_QUERY);
+ else if(m_xImpl->m_xGraphics && m_xImpl->m_xGraphics->hasByName(sName))
+ xOtherFrame.set(m_xImpl->m_xGraphics->getByName(sName), uno::UNO_QUERY);
+ else if (m_xImpl->m_xObjects && m_xImpl->m_xObjects->hasByName(sName))
+ xOtherFrame.set(m_xImpl->m_xObjects->getByName(sName), uno::UNO_QUERY);
+
+ Reference< XPropertySetInfo > xPropSetInfo = xOtherFrame->getPropertySetInfo();
+ if(xPropSetInfo->hasPropertyByName("Width"))
+ {
+ sal_Int32 nOtherWidth = 0;
+ xOtherFrame->getPropertyValue("Width") >>= nOtherWidth;
+ if(nWidth != nOtherWidth)
+ return false;
+ }
+
+ if (xPropSetInfo->hasPropertyByName("Height"))
+ {
+ sal_Int32 nOtherHeight = 0;
+ xOtherFrame->getPropertyValue("Height") >>= nOtherHeight;
+ if (nHeight != nOtherHeight)
+ return false;
+ }
+
+ if (xPropSetInfo->hasPropertyByName("HoriOrientPosition"))
+ {
+ sal_Int32 nOtherX = 0;
+ xOtherFrame->getPropertyValue("HoriOrientPosition") >>= nOtherX;
+ if (nX != nOtherX)
+ return false;
+ }
+
+ if (xPropSetInfo->hasPropertyByName("VertOrientPosition"))
+ {
+ sal_Int32 nOtherY = 0;
+ xOtherFrame->getPropertyValue("VertOrientPosition") >>= nOtherY;
+ if (nY != nOtherY)
+ return false;
+ }
+
+ // In some case, position is not defined for frames, so check whether the two frames follow each other (are anchored to the same position)
+ if (m_xImpl->msLastImportedFrameName != sName)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+void XMLTextImportHelper::StoreLastImportedFrameName(const OUString& rName)
+{
+ m_xImpl->msLastImportedFrameName = rName;
+}
+
+void XMLTextImportHelper::ClearLastImportedTextFrameName()
+{
+ m_xImpl->msLastImportedFrameName.clear();
+}
+
void XMLTextImportHelper::InsertString( const OUString& rChars )
{
assert(m_xImpl->m_xText.is());
@@ -2343,6 +2412,8 @@ SvXMLImportContext *XMLTextImportHelper::CreateTextChildContext(
m_xImpl->m_bBodyContentStarted = false;
}
+ if( nToken != XML_TOK_TEXT_FRAME_PAGE )
+ ClearLastImportedTextFrameName();
return pContext;
}