[Libreoffice-commits] .: sw/qa sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Jan 21 00:29:33 PST 2013


 sw/qa/extras/ww8import/data/fdo59530.doc |binary
 sw/qa/extras/ww8import/ww8import.cxx     |   26 +++++++++
 sw/source/filter/ww8/ww8par.cxx          |   89 +++++++++++++++++++++++++++++--
 sw/source/filter/ww8/ww8par.hxx          |    6 ++
 sw/source/filter/ww8/ww8struc.hxx        |    8 ++
 5 files changed, 125 insertions(+), 4 deletions(-)

New commits:
commit 7907cc0ef9751d553014bd3bab49be9e7fc31bca
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Mon Jan 21 09:31:26 2013 +0100

    fdo#59530 WW8 import of commented text ranges
    
    Change-Id: I3e2928922ebcec8188c1b5416108373c4f26dd62

diff --git a/sw/qa/extras/ww8import/data/fdo59530.doc b/sw/qa/extras/ww8import/data/fdo59530.doc
new file mode 100755
index 0000000..4e41cb8
Binary files /dev/null and b/sw/qa/extras/ww8import/data/fdo59530.doc differ
diff --git a/sw/qa/extras/ww8import/ww8import.cxx b/sw/qa/extras/ww8import/ww8import.cxx
index d650e11..d471b7b 100644
--- a/sw/qa/extras/ww8import/ww8import.cxx
+++ b/sw/qa/extras/ww8import/ww8import.cxx
@@ -47,6 +47,7 @@ public:
     void testN757118();
     void testN757905();
     void testAllGapsWord();
+    void testFdo59530();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -68,6 +69,7 @@ void Test::run()
         {"n757118.doc", &Test::testN757118},
         {"n757905.doc", &Test::testN757905},
         {"all_gaps_word.doc", &Test::testAllGapsWord},
+        {"fdo59530.doc", &Test::testFdo59530},
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -226,6 +228,30 @@ void Test::testAllGapsWord()
     borderTest.testTheBorders(mxComponent);
 }
 
+void Test::testFdo59530()
+{
+    // See ooxmlexport's testFdo38244().
+    // Test comment range feature.
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+    uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
+    xRunEnum->nextElement();
+    uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty<OUString>(xPropertySet, "TextPortionType"));
+    xRunEnum->nextElement();
+    xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("TextFieldEnd"), getProperty<OUString>(xPropertySet, "TextPortionType"));
+
+    // Test initials.
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+    uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+    xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("346376201"), getProperty<OUString>(xPropertySet, "Name"));
+    CPPUNIT_ASSERT_EQUAL(OUString("M"), getProperty<OUString>(xPropertySet, "Initials"));
+}
 
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 7705aae..acfecb2 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -1761,6 +1761,8 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
         return 0;
 
     String sAuthor;
+    String sInitials;
+    String sName;
     if( bVer67 )
     {
         const WW67_ATRD* pDescri = (const WW67_ATRD*)pSD->GetData();
@@ -1775,13 +1777,35 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
     {
         const WW8_ATRD* pDescri = (const WW8_ATRD*)pSD->GetData();
 
+        {
+            sal_uInt16 nLen = SVBT16ToShort(pDescri->xstUsrInitl[0]);
+            for(sal_uInt16 nIdx = 1; nIdx <= nLen; ++nIdx)
+                sInitials += SVBT16ToShort(pDescri->xstUsrInitl[nIdx]);
+        }
+
         if (const String* pA = GetAnnotationAuthor(SVBT16ToShort(pDescri->ibst)))
             sAuthor = *pA;
         else
+            sAuthor = sInitials;
+
+        // If there is a bookmark tag, a text range should be commented.
+        sal_uInt32 nTagBkmk = SVBT32ToUInt32(pDescri->ITagBkmk);
+        if (nTagBkmk != 0xFFFFFFFF)
         {
-            sal_uInt16 nLen = SVBT16ToShort(pDescri->xstUsrInitl[0]);
-            for(sal_uInt16 nIdx = 1; nIdx <= nLen; ++nIdx)
-                sAuthor += SVBT16ToShort(pDescri->xstUsrInitl[nIdx]);
+            sName = OUString::valueOf(sal_Int32(nTagBkmk));
+            int nAtnIndex = GetAnnotationIndex(nTagBkmk);
+            if (nAtnIndex != -1)
+            {
+                WW8_CP nStart = GetAnnotationStart(nAtnIndex);
+                WW8_CP nEnd = GetAnnotationEnd(nAtnIndex);
+                sal_Int32 nLen = nEnd - nStart;
+                // Don't support ranges affecting multiple SwTxtNode for now.
+                if (nLen && pPaM->GetPoint()->nContent.GetIndex() >= nLen)
+                {
+                    pPaM->SetMark();
+                    pPaM->GetPoint()->nContent -= nLen;
+                }
+            }
         }
     }
 
@@ -1803,9 +1827,18 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
     this->pFmtOfJustInsertedApo = 0;
     SwPostItField aPostIt(
         (SwPostItFieldType*)rDoc.GetSysFldType(RES_POSTITFLD), sAuthor,
-        sTxt, aEmptyStr, aEmptyStr, aDate );
+        sTxt, sInitials, sName, aDate );
     aPostIt.SetTextObject(pOutliner);
 
+    // If this is a range, create the associated fieldmark.
+    if (pPaM->HasMark())
+    {
+        IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess();
+        pMarksAccess->makeFieldBookmark(*pPaM, aPostIt.GetName(), ODF_COMMENTRANGE);
+        pPaM->Exchange();
+        pPaM->DeleteMark();
+    }
+
     pCtrlStck->NewAttr(*pPaM->GetPoint(), SvxCharHiddenItem(false, RES_CHRATR_HIDDEN));
     rDoc.InsertPoolItem(*pPaM, SwFmtFld(aPostIt), 0);
     pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_HIDDEN);
@@ -5367,6 +5400,54 @@ const String* SwWW8ImplReader::GetAnnotationAuthor(sal_uInt16 nIdx)
     return pRet;
 }
 
+int SwWW8ImplReader::GetAnnotationIndex(sal_uInt32 nTag)
+{
+    if (!mpAtnIndexes.get() && pWwFib->lcbSttbfAtnbkmk)
+    {
+        mpAtnIndexes.reset(new std::map<sal_uInt32, int>());
+        std::vector<String> aStrings;
+        std::vector<ww::bytes> aEntries;
+        WW8ReadSTTBF(!bVer67, *pTableStream, pWwFib->fcSttbfAtnbkmk, pWwFib->lcbSttbfAtnbkmk, sizeof(struct WW8_ATNBE), eStructCharSet, aStrings, &aEntries);
+        for (size_t i = 0; i < aStrings.size() && i < aEntries.size(); ++i)
+        {
+            ww::bytes aEntry = aEntries[i];
+            WW8_ATNBE* pAtnbeStruct = (WW8_ATNBE*)(&aEntry[0]);
+            mpAtnIndexes->insert(std::pair<sal_uInt32, int>(SVBT32ToUInt32(pAtnbeStruct->nTag), i));
+        }
+    }
+    if (mpAtnIndexes.get())
+    {
+        std::map<sal_uInt32, int>::iterator it = mpAtnIndexes->find(nTag);
+        if (it != mpAtnIndexes->end())
+            return it->second;
+    }
+    return -1;
+}
+
+WW8_CP SwWW8ImplReader::GetAnnotationStart(int nIndex)
+{
+    if (!mpAtnStarts.get() && pWwFib->lcbPlcfAtnbkf)
+        // A PLCFBKF is a PLC whose data elements are FBKF structures (4 bytes each).
+        mpAtnStarts.reset(new WW8PLCFspecial(pTableStream, pWwFib->fcPlcfAtnbkf, pWwFib->lcbPlcfAtnbkf, 4));
+
+    if (mpAtnStarts.get())
+        return mpAtnStarts->GetPos(nIndex);
+    else
+        return SAL_MAX_INT32;
+}
+
+WW8_CP SwWW8ImplReader::GetAnnotationEnd(int nIndex)
+{
+    if (!mpAtnEnds.get() && pWwFib->lcbPlcfAtnbkl)
+        // The Plcfbkl structure is a PLC that contains only CPs and no additional data.
+        mpAtnEnds.reset(new WW8PLCFspecial(pTableStream, pWwFib->fcPlcfAtnbkl, pWwFib->lcbPlcfAtnbkl, 0));
+
+    if (mpAtnEnds.get())
+        return mpAtnEnds->GetPos(nIndex);
+    else
+        return SAL_MAX_INT32;
+}
+
 sal_uLong SwWW8ImplReader::LoadDoc( SwPaM& rPaM,WW8Glossary *pGloss)
 {
     sal_uLong nErrRet = 0;
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 31321f7..485cc34 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1101,6 +1101,9 @@ private:
     SwMSDffManager* pMSDffManager;
 
     std::vector<String>* mpAtnNames;
+    boost::shared_ptr< std::map<sal_uInt32, int> > mpAtnIndexes;
+    boost::shared_ptr<WW8PLCFspecial> mpAtnStarts;
+    boost::shared_ptr<WW8PLCFspecial> mpAtnEnds;
 
     sw::util::AuthorInfos m_aAuthorInfos;
     String sBaseURL;
@@ -1484,6 +1487,9 @@ private:
 // spaeter zu ersetzen durch Aufruf in entsprechend erweiterten SvxMSDffManager
 
     const String* GetAnnotationAuthor(sal_uInt16 nIdx);
+    int GetAnnotationIndex(sal_uInt32 nTag);
+    WW8_CP GetAnnotationStart(int nIndex);
+    WW8_CP GetAnnotationEnd(int nIndex);
 
     // Schnittstellen fuer die Toggle-Attribute
     void SetToggleAttr(sal_uInt8 nAttrId, bool bOn);
diff --git a/sw/source/filter/ww8/ww8struc.hxx b/sw/source/filter/ww8/ww8struc.hxx
index 9bb467d..56d39d9 100644
--- a/sw/source/filter/ww8/ww8struc.hxx
+++ b/sw/source/filter/ww8/ww8struc.hxx
@@ -878,6 +878,14 @@ struct WW8_STRINGID
     SVBT16 reserved3;
 };
 
+/// The ATNBE structure contains information about an annotation bookmark in the document.
+struct WW8_ATNBE
+{
+    SVBT16 nBmc;
+    SVBT32 nTag;
+    SVBT32 nTagOld;
+};
+
 struct WW8_WKB
 {
     // M.M. This is the WkbPLCF struct


More information about the Libreoffice-commits mailing list