include/xmloff/txtimp.hxx                   |    5 +
 sw/qa/extras/odfimport/data/tdf100033_1.odt |binary
 sw/qa/extras/odfimport/data/tdf100033_2.odt |binary
 sw/qa/extras/odfimport/odfimport.cxx        |   16 ++++++
 xmloff/source/text/XMLTextFrameContext.cxx  |   29 +++++++----
 xmloff/source/text/txtimp.cxx               |   71 ++++++++++++++++++++++++++++
 6 files changed, 112 insertions(+), 9 deletions(-)

New commits:
commit 6952d696439981962ad378aa28b0d16ea6e48f0e
Author: Tamás Zolnai <tamas.zol...@collabora.com>
Date:   Wed May 17 11:16:17 2017 +0200

    tdf#100033: Frames with the same name are removed
    
    Allow to have frames with the same name. For removing
    real duplicated frames (generated by LO earlier)
    check other things also next to the frame name:
    position, size or whether the two frames are anchored
    to the same position.
    
    Change-Id: I191ae5128d0228eb85f78f065b44b1f0b3ba6dcf
    Reviewed-on: https://gerrit.libreoffice.org/37702
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com>

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
Binary files /dev/null and b/sw/qa/extras/odfimport/data/tdf100033_1.odt 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
Binary files /dev/null and b/sw/qa/extras/odfimport/data/tdf100033_2.odt 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;
 }
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to