writerfilter/source/rtftok/rtfdocumentimpl.cxx        |   27 ++++++++++++++----
 writerfilter/source/rtftok/rtfdocumentimpl.hxx        |    4 ++
 writerfilter/source/rtftok/rtfreferenceproperties.cxx |   10 ++++++
 writerfilter/source/rtftok/rtfreferenceproperties.hxx |    2 +
 writerfilter/source/rtftok/rtfsprm.cxx                |   20 +++++++++++++
 writerfilter/source/rtftok/rtfsprm.hxx                |    2 +
 writerfilter/source/rtftok/rtfvalue.cxx               |    5 +++
 writerfilter/source/rtftok/rtfvalue.hxx               |    1 
 8 files changed, 65 insertions(+), 6 deletions(-)

New commits:
commit 9f5263c477b82fef5aa9c3e79fb6af92aa049e24
Author: Miklos Vajna <vmik...@suse.cz>
Date:   Sun Nov 25 00:54:10 2012 +0100

    fdo#44736 RTF import: ignore direct formatting which equals to style
    
    Change-Id: Ie82f18381a95adbfedf7ea02d6844685e44b151d

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index c8992ec..d1888dc 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -399,6 +399,21 @@ void RTFDocumentImpl::setNeedPar(bool bNeedPar)
     m_bNeedPar = bNeedPar;
 }
 
+writerfilter::Reference<Properties>::Pointer_t 
RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
+{
+    int nStyle = m_aStates.top().nCurrentStyleIndex;
+    RTFReferenceTable::Entries_t::iterator it = 
m_aStyleTableEntries.find(nStyle);
+    if (it != m_aStyleTableEntries.end())
+    {
+        RTFReferenceProperties& rProps = 
*(RTFReferenceProperties*)it->second.get();
+        // Get rid of direct formatting what is already in the style.
+        rSprms.deduplicate(rProps.getSprms());
+        rAttributes.deduplicate(rProps.getAttributes());
+    }
+    writerfilter::Reference<Properties>::Pointer_t pRet(new 
RTFReferenceProperties(rAttributes, rSprms));
+    return pRet;
+}
+
 void RTFDocumentImpl::checkNeedPap()
 {
     if (m_bNeedPap)
@@ -407,7 +422,7 @@ void RTFDocumentImpl::checkNeedPap()
         if (!m_pCurrentBuffer)
         {
             writerfilter::Reference<Properties>::Pointer_t const 
pParagraphProperties(
-                    new 
RTFReferenceProperties(m_aStates.top().aParagraphAttributes, 
m_aStates.top().aParagraphSprms)
+                    getProperties(m_aStates.top().aParagraphAttributes, 
m_aStates.top().aParagraphSprms)
                     );
 
             // Writer will ignore a page break before a text frame, so guard 
it with empty paragraphs
@@ -441,9 +456,7 @@ void RTFDocumentImpl::runProps()
 {
     if (!m_pCurrentBuffer)
     {
-        writerfilter::Reference<Properties>::Pointer_t const pProperties(
-                new 
RTFReferenceProperties(m_aStates.top().aCharacterAttributes, 
m_aStates.top().aCharacterSprms)
-                );
+        writerfilter::Reference<Properties>::Pointer_t const pProperties = 
getProperties(m_aStates.top().aCharacterAttributes, 
m_aStates.top().aCharacterSprms);
         Mapper().props(pProperties);
     }
     else
@@ -1677,7 +1690,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
                 m_aStates.top().aTableCellAttributes = 
m_aDefaultState.aTableCellAttributes;
 
                 writerfilter::Reference<Properties>::Pointer_t const 
pParagraphProperties(
-                        new 
RTFReferenceProperties(m_aStates.top().aParagraphAttributes, 
m_aStates.top().aParagraphSprms)
+                        getProperties(m_aStates.top().aParagraphAttributes, 
m_aStates.top().aParagraphSprms)
                         );
                 Mapper().props(pParagraphProperties);
 
@@ -2623,6 +2636,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, 
int nParam)
             }
             break;
         case RTF_S:
+            m_aStates.top().nCurrentStyleIndex = nParam;
             if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || 
m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
             {
                 m_nCurrentStyleIndex = nParam;
@@ -4206,7 +4220,8 @@ RTFParserState::RTFParserState(RTFDocumentImpl 
*pDocumentImpl)
     nMonth(0),
     nDay(0),
     nHour(0),
-    nMinute(0)
+    nMinute(0),
+    nCurrentStyleIndex(-1)
 {
 }
 
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 4942fac..9801164 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -399,6 +399,9 @@ namespace writerfilter {
 
                 /// Text from special destinations.
                 rtl::OUStringBuffer aDestinationText;
+
+                /// Same as the int value of NS_rtf::LN_ISTD in 
aParagraphAttributes, for performance reasons.
+                int nCurrentStyleIndex;
         };
 
         class RTFTokenizer;
@@ -478,6 +481,7 @@ namespace writerfilter {
                 void runBreak();
                 void parBreak();
                 void tableBreak();
+                writerfilter::Reference<Properties>::Pointer_t 
getProperties(RTFSprms& rAttributes, RTFSprms& rSprms);
                 void checkNeedPap();
                 void sectBreak(bool bFinal);
                 void replayBuffer(RTFBuffer_t& rBuffer);
diff --git a/writerfilter/source/rtftok/rtfreferenceproperties.cxx 
b/writerfilter/source/rtftok/rtfreferenceproperties.cxx
index 03cd0e9..50f76e3 100644
--- a/writerfilter/source/rtftok/rtfreferenceproperties.cxx
+++ b/writerfilter/source/rtftok/rtfreferenceproperties.cxx
@@ -62,6 +62,16 @@ std::string RTFReferenceProperties::getType() const
     return "RTFReferenceProperties";
 }
 
+RTFSprms& RTFReferenceProperties::getAttributes()
+{
+    return m_aAttributes;
+}
+
+RTFSprms& RTFReferenceProperties::getSprms()
+{
+    return m_aSprms;
+}
+
 } // namespace rtftok
 } // namespace writerfilter
 
diff --git a/writerfilter/source/rtftok/rtfreferenceproperties.hxx 
b/writerfilter/source/rtftok/rtfreferenceproperties.hxx
index d580de9..369590b 100644
--- a/writerfilter/source/rtftok/rtfreferenceproperties.hxx
+++ b/writerfilter/source/rtftok/rtfreferenceproperties.hxx
@@ -42,6 +42,8 @@ namespace writerfilter {
                 virtual ~RTFReferenceProperties();
                 virtual void resolve(Properties & rHandler);
                 virtual std::string getType() const;
+                RTFSprms& getAttributes();
+                RTFSprms& getSprms();
             private:
                 RTFSprms m_aAttributes;
                 RTFSprms m_aSprms;
diff --git a/writerfilter/source/rtftok/rtfsprm.cxx 
b/writerfilter/source/rtftok/rtfsprm.cxx
index fb61d29..2958cde 100644
--- a/writerfilter/source/rtftok/rtfsprm.cxx
+++ b/writerfilter/source/rtftok/rtfsprm.cxx
@@ -29,6 +29,7 @@
 #include <rtl/strbuf.hxx>
 
 #include <resourcemodel/QNameToString.hxx>
+#include <doctok/resourceids.hxx> // NS_rtf namespace
 
 using rtl::OStringBuffer;
 
@@ -130,6 +131,25 @@ bool RTFSprms::erase(Id nKeyword)
     return false;
 }
 
+void RTFSprms::deduplicate(RTFSprms& rReference)
+{
+    RTFSprms::Iterator_t i = m_aSprms.begin();
+    while (i != m_aSprms.end())
+    {
+        bool bIgnore = false;
+        if (i->first != NS_rtf::LN_ISTD)
+        {
+            RTFValue::Pointer_t pValue(rReference.find(i->first));
+            if (pValue.get() && i->second->equals(*pValue))
+                bIgnore = true;
+        }
+        if (bIgnore)
+            i = m_aSprms.erase(i);
+        else
+            ++i;
+    }
+}
+
 RTFSprms::RTFSprms()
     : m_aSprms()
 {
diff --git a/writerfilter/source/rtftok/rtfsprm.hxx 
b/writerfilter/source/rtftok/rtfsprm.hxx
index df223fc..80d41a3 100644
--- a/writerfilter/source/rtftok/rtfsprm.hxx
+++ b/writerfilter/source/rtftok/rtfsprm.hxx
@@ -47,6 +47,8 @@ namespace writerfilter {
                 /// Does the same as ->push_back(), except that it can 
overwrite existing entries.
                 void set(Id nKeyword, RTFValue::Pointer_t pValue, bool 
bOverwrite = true);
                 bool erase(Id nKeyword);
+                /// Removes elements, which are already in the reference set.
+                void deduplicate(RTFSprms& rReference);
                 void swap(RTFSprms& rOther);
                 size_t size() const { return m_aSprms.size(); }
                 bool empty() const { return m_aSprms.empty(); }
diff --git a/writerfilter/source/rtftok/rtfvalue.cxx 
b/writerfilter/source/rtftok/rtfvalue.cxx
index 4882522..eaacc2a 100644
--- a/writerfilter/source/rtftok/rtfvalue.cxx
+++ b/writerfilter/source/rtftok/rtfvalue.cxx
@@ -200,6 +200,11 @@ RTFValue* RTFValue::Clone()
     return new RTFValue(m_nValue, m_sValue, *m_pAttributes, *m_pSprms, 
m_xShape, m_xStream, m_xObject, m_bForceString);
 }
 
+bool RTFValue::equals(RTFValue& rOther)
+{
+    return m_nValue == rOther.m_nValue;
+}
+
 RTFSprms& RTFValue::getAttributes()
 {
     return *m_pAttributes;
diff --git a/writerfilter/source/rtftok/rtfvalue.hxx 
b/writerfilter/source/rtftok/rtfvalue.hxx
index 6751126..3714d26 100644
--- a/writerfilter/source/rtftok/rtfvalue.hxx
+++ b/writerfilter/source/rtftok/rtfvalue.hxx
@@ -62,6 +62,7 @@ namespace writerfilter {
                 virtual RTFValue* Clone();
                 RTFSprms& getAttributes();
                 RTFSprms& getSprms();
+                bool equals(RTFValue& rOther);
             private:
                 RTFValue& operator=(RTFValue const& rOther);
                 int m_nValue;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to