[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-4.1' - 3 commits - sw/qa writerfilter/source

Michael Stahl mstahl at redhat.com
Wed May 28 03:23:19 PDT 2014


 sw/qa/extras/rtfimport/data/footer-para.rtf    |    5 +
 sw/qa/extras/rtfimport/rtfimport.cxx           |   17 +++++
 writerfilter/source/rtftok/rtfcontrolwords.hxx |    1 
 writerfilter/source/rtftok/rtfdocumentimpl.cxx |   71 +++++++++++++++++--------
 writerfilter/source/rtftok/rtfdocumentimpl.hxx |    3 +
 5 files changed, 76 insertions(+), 21 deletions(-)

New commits:
commit 65ef769a60df0aad2dea9811713faa323757f0b2
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Feb 28 20:14:12 2014 +0100

    RTF import: fix paragraphs in header/footer
    
    (cherry picked from commit 74b3f4f00766d199df3b017d056cf7a00ae52988)
    Signed-off-by: Luboš Luňák <l.lunak at centrum.cz>
    
    Conflicts:
    	sw/qa/extras/rtfimport/rtfimport.cxx
    
    Change-Id: I91f04cad7a39428ce6f9555d18b974f0d45181f7

diff --git a/sw/qa/extras/rtfimport/data/footer-para.rtf b/sw/qa/extras/rtfimport/data/footer-para.rtf
new file mode 100644
index 0000000..28863b2
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/footer-para.rtf
@@ -0,0 +1,5 @@
+{\rtf1\fbidis\ansi\ansicpg0\uc0\deff0\deflang0\deflangfe0\paperw11905\paperh16838\margl1200\margr1200\margt1200\margb1200\headery600\footery600\viewscale100\viewzk0\titlepg
+{\fonttbl{\f0\fnil Arial;}}
+{\footerf
+\pard\s0\fi0\li0\qc\ri0\sb0\sa0\itap0 \plain \f0\fs18 All Rights Reserved.\par}
+\pard\par}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index e1a6728..b3bc41f 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1608,6 +1608,20 @@ DECLARE_RTFIMPORT_TEST(testDoDhgtOld, "do-dhgt-old.rtf")
     CPPUNIT_ASSERT_EQUAL(OUString("b"), xShape->getString());
 }
 
+DECLARE_RTFIMPORT_TEST(testFooterPara, "footer-para.rtf")
+{
+    // check that paragraph properties in footer are imported
+    uno::Reference<text::XText> xFooterText =
+        getProperty< uno::Reference<text::XText> >(
+            getStyles("PageStyles")->getByName("First Page"), "FooterText");
+    uno::Reference<text::XTextContent> xParagraph =
+        getParagraphOrTable(1, xFooterText);
+    CPPUNIT_ASSERT_EQUAL(OUString("All Rights Reserved."),
+        uno::Reference<text::XTextRange>(xParagraph, uno::UNO_QUERY)->getString());
+    CPPUNIT_ASSERT_EQUAL((sal_Int16)style::ParagraphAdjust_CENTER,
+        getProperty</*style::ParagraphAdjust*/sal_Int16>(xParagraph, "ParaAdjust"));
+}
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 3f6ebc7..8011bc7 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -401,8 +401,9 @@ void RTFDocumentImpl::setNeedSect(bool bNeedSect)
         if (!m_pSuperstream) // no sections in header/footer!
         {
             Mapper().startSectionGroup();
-            m_bNeedSect = bNeedSect;
         }
+        // set flag in substream too - otherwise multiple startParagraphGroup
+        m_bNeedSect = bNeedSect;
         Mapper().startParagraphGroup();
         setNeedPar(true);
     }
commit 40506e46ca01f812209331d60af859666bb1f931
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Mar 3 17:02:27 2014 +0100

    -Werror,-Wtautological-constant-out-of-range-compare
    
    (If the underlying type of an unscoped enumeration is unfixed, it need not be
    signed.)
    
    Change-Id: I26a406504863512a0d3861ad8b28523b0a6dccaa
    (cherry picked from commit 8899b47d2252fd1c2f58ba30558c4ec41d65e442)
    Signed-off-by: Luboš Luňák <l.lunak at centrum.cz>

diff --git a/writerfilter/source/rtftok/rtfcontrolwords.hxx b/writerfilter/source/rtftok/rtfcontrolwords.hxx
index a29b86d..d38a0b4 100644
--- a/writerfilter/source/rtftok/rtfcontrolwords.hxx
+++ b/writerfilter/source/rtftok/rtfcontrolwords.hxx
@@ -15,6 +15,7 @@ namespace rtftok {
 
 enum RTFKeyword
 {
+    RTF_invalid = -1,
     RTF_HEXCHAR,
     RTF_OPTHYPH,
     RTF_IGNORE,
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index c672aa6..3f6ebc7 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -263,7 +263,7 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
     m_aHexBuffer(),
     m_bMathNor(false),
     m_bIgnoreNextContSectBreak(false),
-    m_nResetBreakOnSectBreak(static_cast<RTFKeyword>(-1)),
+    m_nResetBreakOnSectBreak(RTF_invalid),
     m_bNeedSect(false), // done by checkFirstRun
     m_bWasInFrame(false),
     m_bHadPicture(false),
@@ -1785,10 +1785,10 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
                 else
                 {
                     sectBreak();
-                    if (m_nResetBreakOnSectBreak != -1)
+                    if (m_nResetBreakOnSectBreak != RTF_invalid)
                     {   // this should run on _second_ \sect after \page
                         dispatchSymbol(m_nResetBreakOnSectBreak); // lazy reset
-                        m_nResetBreakOnSectBreak = static_cast<RTFKeyword>(-1);
+                        m_nResetBreakOnSectBreak = RTF_invalid;
                         m_bNeedSect = false; // dispatchSymbol set it
                     }
                 }
@@ -2157,7 +2157,7 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
     }
     if (nParam >= 0)
     {
-        if (m_nResetBreakOnSectBreak != -1)
+        if (m_nResetBreakOnSectBreak != RTF_invalid)
         {
             m_nResetBreakOnSectBreak = nKeyword;
         }
commit 4c8858b4a63906a5f5af009be139a8c5247c54b0
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Feb 27 23:48:59 2014 +0100

    RTF import: fix spurious page breaks at doc end (related: rhbz#1065629)
    
    When a document ends with \sect it's possible that a spurious page break
    is created.  In fact the spurious page break is always created by the
    RTF importer, sometimes it is deleted again by
    DomainMapper_Impl::RemoveLastParagraph() and sometimes not.
    
    It is created because on the final \sect RTFDocumentImpl::sectBreak()
    still calls startSectionGroup(), and the popState() for the \rtf1 group
    then calls sectBreak() another time.
    
    To prevent this, do not call startSectionGroup() from sectBreak() but
    instead from setNeedSect(), and ensure that it is called as soon as
    anything after \sect is read.
    
    One unit test fails because the \page is not handled properly: the
    conversion to \skbpage \sect \skbnone is not correct, because the \skb*
    keywords are an exception and affect the \sect that precedes them, not
    the following one; sending the \skbpage later unfortunately requires
    additional cleanup later.
    
    (cherry picked from commit e3f254ab8211fbab7541cde2100a35c875b0c240)
    Signed-off-by: Luboš Luňák <l.lunak at centrum.cz>
    
    Conflicts:
    	sw/qa/extras/rtfimport/rtfimport.cxx
    	writerfilter/source/rtftok/rtfdocumentimpl.cxx
    
    Change-Id: I3c1a3bceb2c8b75bbecdc748170562451ce5f5c3

diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index f33a47d..e1a6728 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1554,6 +1554,9 @@ void Test::testNestedTable()
     xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
     xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(OUString("Nom: John Doe"), xPara->getString());
+
+    // \sect at the end resulted in spurious page break
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index f7a6aae..c672aa6 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -263,7 +263,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
     m_aHexBuffer(),
     m_bMathNor(false),
     m_bIgnoreNextContSectBreak(false),
-    m_bNeedSect(true),
+    m_nResetBreakOnSectBreak(static_cast<RTFKeyword>(-1)),
+    m_bNeedSect(false), // done by checkFirstRun
     m_bWasInFrame(false),
     m_bHadPicture(false),
     m_bHadSect(false),
@@ -370,16 +371,15 @@ void RTFDocumentImpl::checkFirstRun()
         writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aSettingsTableEntries));
         Mapper().table(NS_ooxml::LN_settings_settings, pTable);
         // start initial paragraph
-        if (!m_pSuperstream)
-            Mapper().startSectionGroup();
-        Mapper().startParagraphGroup();
+        m_bFirstRun = false;
+        assert(!m_bNeedSect);
+        setNeedSect(); // first call that succeeds
 
         // set the requested default font, if there are none
         RTFValue::Pointer_t pFont = m_aDefaultState.aCharacterSprms.find(NS_sprm::LN_CRgFtc0);
         RTFValue::Pointer_t pCurrentFont = m_aStates.top().aCharacterSprms.find(NS_sprm::LN_CRgFtc0);
         if (pFont && !pCurrentFont)
             dispatchValue(RTF_F, pFont->getInt());
-        m_bFirstRun = false;
     }
 }
 
@@ -395,7 +395,21 @@ void RTFDocumentImpl::setNeedPar(bool bNeedPar)
 
 void RTFDocumentImpl::setNeedSect(bool bNeedSect)
 {
-    m_bNeedSect = bNeedSect;
+    // ignore setting before checkFirstRun - every keyword calls setNeedSect!
+    if (!m_bNeedSect && bNeedSect && !m_bFirstRun)
+    {
+        if (!m_pSuperstream) // no sections in header/footer!
+        {
+            Mapper().startSectionGroup();
+            m_bNeedSect = bNeedSect;
+        }
+        Mapper().startParagraphGroup();
+        setNeedPar(true);
+    }
+    else if (m_bNeedSect && !bNeedSect)
+    {
+        m_bNeedSect = bNeedSect;
+    }
 }
 
 writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
@@ -519,6 +533,7 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false)
     {
         dispatchFlag(RTF_PARD);
         dispatchSymbol(RTF_PAR);
+        m_bNeedSect = bNeedSect;
     }
     while (m_nHeaderFooterPositions.size())
     {
@@ -549,12 +564,7 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false)
     Mapper().endParagraphGroup();
     if (!m_pSuperstream)
         Mapper().endSectionGroup();
-    if (!bFinal)
-    {
-        Mapper().startSectionGroup();
-        Mapper().startParagraphGroup();
-    }
-    m_bNeedPar = true;
+    m_bNeedPar = false;
     m_bNeedSect = false;
 }
 
@@ -1225,8 +1235,8 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer)
 
 int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
 {
-    checkUnicode();
     setNeedSect();
+    checkUnicode();
     RTFSkipDestination aSkip(*this);
     switch (nKeyword)
     {
@@ -1697,11 +1707,11 @@ int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
 
 int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
 {
+    setNeedSect();
     if (nKeyword != RTF_HEXCHAR)
         checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
     else
         checkUnicode(/*bUnicode =*/ true, /*bHex =*/ false);
-    setNeedSect();
     RTFSkipDestination aSkip(*this);
 
     if (RTF_LINE == nKeyword)
@@ -1773,7 +1783,15 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
                 if (m_bIgnoreNextContSectBreak)
                     m_bIgnoreNextContSectBreak = false;
                 else
+                {
                     sectBreak();
+                    if (m_nResetBreakOnSectBreak != -1)
+                    {   // this should run on _second_ \sect after \page
+                        dispatchSymbol(m_nResetBreakOnSectBreak); // lazy reset
+                        m_nResetBreakOnSectBreak = static_cast<RTFKeyword>(-1);
+                        m_bNeedSect = false; // dispatchSymbol set it
+                    }
+                }
             }
             break;
         case RTF_NOBREAK:
@@ -1944,19 +1962,24 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
                 RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
                 // Unless we're on a title page.
                 RTFValue::Pointer_t pTitlePg = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_titlePg);
-                if ((pBreak.get() && !pBreak->getInt()) && !(pTitlePg.get() && pTitlePg->getInt()))
+                if (((pBreak.get() && !pBreak->getInt())
+                        || m_nResetBreakOnSectBreak == RTF_SBKNONE)
+                    && !(pTitlePg.get() && pTitlePg->getInt()))
                 {
                     if (m_bWasInFrame)
                     {
                         dispatchSymbol(RTF_PAR);
                         m_bWasInFrame = false;
                     }
-                    dispatchFlag(RTF_SBKPAGE);
                     sectBreak();
-                    dispatchFlag(RTF_SBKNONE);
+                    // note: this will not affect the following section break
+                    // but the one just pushed
+                    dispatchFlag(RTF_SBKPAGE);
                     if (m_bNeedPar)
                         dispatchSymbol(RTF_PAR);
                     m_bIgnoreNextContSectBreak = true;
+                    // arrange to clean up the syntetic RTF_SBKPAGE
+                    m_nResetBreakOnSectBreak = RTF_SBKNONE;
                 }
                 else
                 {
@@ -2001,8 +2024,8 @@ bool lcl_findPropertyName(const std::vector<beans::PropertyValue>& rProperties,
 
 int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
 {
-    checkUnicode();
     setNeedSect();
+    checkUnicode();
     RTFSkipDestination aSkip(*this);
     int nParam = -1;
     int nSprm = -1;
@@ -2134,6 +2157,10 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
     }
     if (nParam >= 0)
     {
+        if (m_nResetBreakOnSectBreak != -1)
+        {
+            m_nResetBreakOnSectBreak = nKeyword;
+        }
         RTFValue::Pointer_t pValue(new RTFValue(nParam));
         m_aStates.top().aSectionSprms.set(NS_sprm::LN_SBkc, pValue);
         return 0;
@@ -2730,8 +2757,8 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
 
 int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
 {
-    checkUnicode(nKeyword != RTF_U, true);
     setNeedSect();
+    checkUnicode(nKeyword != RTF_U, true);
     RTFSkipDestination aSkip(*this);
     int nSprm = 0;
     RTFValue::Pointer_t pIntValue(new RTFValue(nParam));
@@ -3644,8 +3671,8 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
 
 int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam)
 {
-    checkUnicode();
     setNeedSect();
+    checkUnicode();
     RTFSkipDestination aSkip(*this);
     int nSprm = -1;
     RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0));
@@ -4473,7 +4500,8 @@ int RTFDocumentImpl::popState()
     {
         if (m_bNeedCr && !isSubstream())
             dispatchSymbol(RTF_PAR);
-        sectBreak(true);
+        if (m_bNeedSect) // may be set by dispatchSymbol above!
+            sectBreak(true);
     }
 
     m_aStates.pop();
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 51abf48..17e8872 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -596,6 +596,9 @@ namespace writerfilter {
                 bool m_bMathNor;
                 /// If the next continous section break should be ignored.
                 bool m_bIgnoreNextContSectBreak;
+                /// clean up a synthetic page break, see RTF_PAGE
+                /// if inactive value is -1, otherwise the RTF_SKB* to restore
+                RTFKeyword m_nResetBreakOnSectBreak;
                 /// If a section break is needed before the end of the doc (false right after a section break).
                 bool m_bNeedSect;
                 /// If aFrame.inFrame() was true in the previous state.


More information about the Libreoffice-commits mailing list