[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - 3 commits - sw/inc sw/qa sw/source

Miklos Vajna vmiklos at collabora.co.uk
Mon Jan 5 12:25:08 PST 2015


 sw/inc/hintids.hxx                              |    1 
 sw/qa/extras/ww8export/data/commented-table.doc |binary
 sw/qa/extras/ww8export/ww8export.cxx            |   12 ++
 sw/source/filter/basflt/fltshell.cxx            |   14 ++
 sw/source/filter/inc/fltshell.hxx               |    2 
 sw/source/filter/ww8/ww8par.cxx                 |  144 ------------------------
 sw/source/filter/ww8/ww8par.hxx                 |    6 -
 sw/source/filter/ww8/ww8par5.cxx                |   12 ++
 sw/source/filter/ww8/ww8par6.cxx                |    3 
 sw/source/filter/ww8/ww8scan.cxx                |  141 +++++++++++++++++++++++
 sw/source/filter/ww8/ww8scan.hxx                |   39 ++++++
 sw/source/filter/ww8/ww8struc.hxx               |    8 -
 12 files changed, 219 insertions(+), 163 deletions(-)

New commits:
commit ac95452f211038d9f0959f801ef33ee7a4cad277
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Dec 30 18:49:04 2014 +0100

    i#93570 DOC import: handle commented text ranges via RES_FLTR_ANNOTATIONMARK
    
    And add a minimal reproducer that shows how the old way was broken.
    
    (cherry picked from commit 0ec0ec267986644084baaa5bda5ba917dc5744df)
    
    Conflicts:
    	sw/source/filter/ww8/ww8par.cxx
    
    Change-Id: Ic2dadf9905d603b0fd0573651b235ecd5dd70e71

diff --git a/sw/qa/extras/ww8export/data/commented-table.doc b/sw/qa/extras/ww8export/data/commented-table.doc
new file mode 100644
index 0000000..049c7e3
Binary files /dev/null and b/sw/qa/extras/ww8export/data/commented-table.doc differ
diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx
index f55967e..357b06a 100644
--- a/sw/qa/extras/ww8export/ww8export.cxx
+++ b/sw/qa/extras/ww8export/ww8export.cxx
@@ -440,6 +440,18 @@ DECLARE_WW8EXPORT_TEST(testWw8Cjklist35, "cjklist35.doc")
     CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_LOWER_ZH, numFormat);
 }
 
+DECLARE_WW8EXPORT_TEST(testCommentedTable, "commented-table.doc")
+{
+    // Document has a non-trivial commented text range, as the range contains a table.
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+    uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+    uno::Reference<text::XTextContent> xField(xFields->nextElement(), uno::UNO_QUERY);
+    // After first import, there was an off-by-one during import, so this was "efore.\nA1\nB1\nAfte". (Notice the additional "e" prefix.)
+    // After export and import, things got worse, this was "\nA1\nB1\nAfte".
+    CPPUNIT_ASSERT_EQUAL(OUString("fore.\nA1\nB1\nAfte"), xField->getAnchor()->getString());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index abcdf62..af76674 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -2192,79 +2192,6 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
             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)
-        {
-            int nAtnIndex = GetAnnotationIndex(nTagBkmk);
-            if (nAtnIndex != -1)
-            {
-                WW8_CP nStart = GetAnnotationStart(nAtnIndex);
-                WW8_CP nEnd = GetAnnotationEnd(GetAnnotationEndIndex(nAtnIndex));
-                //It is unfortunately fragile and wrong to assume that two
-                //character positions in the original word document, which is
-                //what nStart and nEnd are, will equate to the same length in
-                //the destination writer document.
-                //
-                //Better would be, while writing the content into the writer
-                //document to store the equivalent writer document positions
-                //that relate to each annotation index as the parser passes
-                //those points.
-                sal_Int32 nLen = nEnd - nStart;
-                // the start and end positions are apparently stored in
-                // different arrays, so in an invalid file only one could exist
-                if(SAL_MAX_INT32 != nEnd && SAL_MAX_INT32 != nStart && nLen > 0)
-                {
-                    if (pPaM->GetPoint()->nContent.GetIndex() >= nLen)
-                    {
-                        pPaM->SetMark();
-                        pPaM->GetPoint()->nContent -= nLen;
-                    }
-                    else if (pPaM->GetPoint()->nNode.GetNode().IsTxtNode() )
-                    {
-                        pPaM->SetMark();
-                        nLen -= pPaM->GetPoint()->nContent.GetIndex();
-
-                        SwTxtNode* pTxtNode = 0;
-
-                        // Find first text node which is affected by the comment
-                        while (nLen > 0)
-                        {
-                            // Move to previous content node
-                            bool bSuccess = pPaM->Move(fnMoveBackward, fnGoNode);
-
-                            if (!bSuccess)
-                            {
-                                nLen = 0;
-                                break;
-                            }
-
-                            --nLen; // End line character
-
-                            SwNode& rNode = pPaM->GetPoint()->nNode.GetNode();
-
-                            // Subtract previous text node's length
-                            if (rNode.IsTxtNode())
-                            {
-                                pTxtNode = rNode.GetTxtNode();
-                                if (nLen < pTxtNode->Len())
-                                    break;
-                                else
-                                    nLen -= pTxtNode->Len();
-                            }
-                        }
-
-                        // Set position of the text range's first character
-                        if( pTxtNode )
-                        {
-                            pTxtNode->MakeStartIndex(&pPaM->GetPoint()->nContent);
-                            pPaM->GetPoint()->nContent += pTxtNode->Len() - nLen;
-                        }
-                    }
-                }
-            }
-        }
     }
 
     sal_uInt32 nDateTime = 0;
@@ -2292,15 +2219,8 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
     pCtrlStck->NewAttr(*aEnd.GetPoint(), SvxCharHiddenItem(false, RES_CHRATR_HIDDEN));
     rDoc.getIDocumentContentOperations().InsertPoolItem(aEnd, SwFmtFld(aPostIt), 0);
     pCtrlStck->SetAttr(*aEnd.GetPoint(), RES_CHRATR_HIDDEN);
-
-    // If this is a range, create the associated fieldmark.
-    if (pPaM->HasMark())
-    {
-        IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess();
-        pMarksAccess->makeAnnotationMark(*pPaM, aPostIt.GetName());
-        pPaM->Exchange();
-        pPaM->DeleteMark();
-    }
+    // If this is a range, make sure that it ends after the just inserted character, not before it.
+    pReffedStck->MoveAttrs(*aEnd.GetPoint());
 
     return 0;
 }
@@ -6010,66 +5930,6 @@ const OUString* 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<OUString> 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;
-}
-
-sal_uInt16 SwWW8ImplReader::GetAnnotationEndIndex(sal_uInt16 nStart)
-{
-    WW8_CP nStartAkt;
-    void* p;
-    if (mpAtnStarts->GetData(nStart, nStartAkt, p) && p)
-    {
-        // p is an FBKF, and its first 2 bytes is the ibkl member, which is the end index.
-        return SVBT16ToShort(*((SVBT16*)p));
-    }
-    return nStart;
-}
-
-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 7484214..b3f5c16 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1670,11 +1670,6 @@ private:
 // spaeter zu ersetzen durch Aufruf in entsprechend erweiterten SvxMSDffManager
 
     const OUString* GetAnnotationAuthor(sal_uInt16 nIdx);
-    int GetAnnotationIndex(sal_uInt32 nTag);
-    /// Return the end index based on the start one.
-    sal_uInt16 GetAnnotationEndIndex(sal_uInt16 nStart);
-    WW8_CP GetAnnotationStart(int nIndex);
-    WW8_CP GetAnnotationEnd(int nIndex);
 
     // Schnittstellen fuer die Toggle-Attribute
     void SetToggleAttr(sal_uInt8 nAttrId, bool bOn);
@@ -1736,6 +1731,7 @@ public:     // eigentlich private, geht aber leider nur public
     sal_uInt16 End_Field();
     long Read_Book(WW8PLCFManResult*);
     long Read_And(WW8PLCFManResult* pRes);
+    long Read_AtnBook(WW8PLCFManResult*);
 
     // Attribute
 
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index fb2251f..1d46adb 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -220,6 +220,18 @@ long SwWW8ImplReader::Read_Book(WW8PLCFManResult*)
     return 0;
 }
 
+long SwWW8ImplReader::Read_AtnBook(WW8PLCFManResult*)
+{
+    if (WW8PLCFx_AtnBook* pAtnBook = pPlcxMan->GetAtnBook())
+    {
+        if (pAtnBook->getIsEnd())
+            pReffedStck->SetAttr(*pPaM->GetPoint(), RES_FLTR_ANNOTATIONMARK, true, pAtnBook->getHandle());
+        else
+            pReffedStck->NewAttr(*pPaM->GetPoint(), CntUInt16Item(RES_FLTR_ANNOTATIONMARK, pAtnBook->getHandle()));
+    }
+    return 0;
+}
+
 //    general help methods to separate parameters
 
 /// translate FieldParameter names into the system character set and
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index c3a468b..b46ec7d 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -4987,7 +4987,8 @@ long SwWW8ImplReader::ImportExtSprm(WW8PLCFManResult* pRes)
         /* 1 (257) */   &SwWW8ImplReader::Read_Ftn,     // EndNote
         /* 2 (258) */   &SwWW8ImplReader::Read_Field,  // Feld
         /* 3 (259) */   &SwWW8ImplReader::Read_Book,   // Bookmark
-        /* 4 (260) */   &SwWW8ImplReader::Read_And     // Annotation
+        /* 4 (260) */   &SwWW8ImplReader::Read_And,     // Annotation
+        /* 5 (261) */   &SwWW8ImplReader::Read_AtnBook // Annotationmark
     };
 
     if( pRes->nSprmId < 280 )
diff --git a/sw/source/filter/ww8/ww8struc.hxx b/sw/source/filter/ww8/ww8struc.hxx
index e1c8dfa..56d0627 100644
--- a/sw/source/filter/ww8/ww8struc.hxx
+++ b/sw/source/filter/ww8/ww8struc.hxx
@@ -981,14 +981,6 @@ 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
commit 4ec2e1d30bdab5ce9f4dbf53269a9a8d4af51a59
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Dec 30 10:46:26 2014 +0100

    i#93570 DOC import: tokenize PlcfAtnBkf and PlcfAtnBkl
    
    So that later SwWW8ImplReader can read these structures in a way similar
    to bookmarks.
    
    (cherry picked from commit 677fdd4fa235466649911042577bc4980d42deb6)
    
    Conflicts:
    	sw/source/filter/ww8/ww8scan.hxx
    
    Change-Id: I8e5bc804832b944336701ac12fe6cb50e17c6b94

diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 28525bd..af36b28 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -1752,6 +1752,7 @@ WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTblSt,
     }
 
     pBook = new WW8PLCFx_Book(pTblSt, *pWwFib);
+    pAtnBook = new WW8PLCFx_AtnBook(pTblSt, *pWwFib);
 }
 
 WW8ScannerBase::~WW8ScannerBase()
@@ -4234,6 +4235,138 @@ const OUString* WW8PLCFx_Book::GetName() const
     return pRet;
 }
 
+WW8PLCFx_AtnBook::WW8PLCFx_AtnBook(SvStream* pTblSt, const WW8Fib& rFib)
+    : WW8PLCFx(rFib.GetFIBVersion(), /*bSprm=*/false),
+    m_bIsEnd(false)
+{
+    if (!rFib.fcPlcfAtnbkf || !rFib.lcbPlcfAtnbkf || !rFib.fcPlcfAtnbkl || !rFib.lcbPlcfAtnbkl)
+    {
+        m_pBook[0] = m_pBook[1] = 0;
+        nIMax = 0;
+    }
+    else
+    {
+        m_pBook[0] = new WW8PLCFspecial(pTblSt, rFib.fcPlcfAtnbkf, rFib.lcbPlcfAtnbkf, 4);
+        m_pBook[1] = new WW8PLCFspecial(pTblSt, rFib.fcPlcfAtnbkl, rFib.lcbPlcfAtnbkl, 0);
+
+        nIMax = m_pBook[0]->GetIMax();
+        if (m_pBook[1]->GetIMax() < nIMax)
+            nIMax = m_pBook[1]->GetIMax();
+    }
+}
+
+WW8PLCFx_AtnBook::~WW8PLCFx_AtnBook()
+{
+    delete m_pBook[1];
+    delete m_pBook[0];
+}
+
+sal_uInt32 WW8PLCFx_AtnBook::GetIdx() const
+{
+    return nIMax ? m_pBook[0]->GetIdx() : 0;
+}
+
+void WW8PLCFx_AtnBook::SetIdx( sal_uLong nI )
+{
+    if( nIMax )
+        m_pBook[0]->SetIdx( nI );
+}
+
+sal_uLong WW8PLCFx_AtnBook::GetIdx2() const
+{
+    if (nIMax)
+        return m_pBook[1]->GetIdx() | ( m_bIsEnd ? 0x80000000 : 0 );
+    else
+        return 0;
+}
+
+void WW8PLCFx_AtnBook::SetIdx2( sal_uLong nI )
+{
+    if( nIMax )
+    {
+        m_pBook[1]->SetIdx( nI & 0x7fffffff );
+        m_bIsEnd = static_cast<bool>(( nI >> 31 ) & 1);
+    }
+}
+
+bool WW8PLCFx_AtnBook::SeekPos(WW8_CP nCpPos)
+{
+    if (!m_pBook[0])
+        return false;
+
+    bool bOk = m_pBook[0]->SeekPosExact(nCpPos);
+    bOk &= m_pBook[1]->SeekPosExact(nCpPos);
+    m_bIsEnd = false;
+
+    return bOk;
+}
+
+WW8_CP WW8PLCFx_AtnBook::Where()
+{
+    return m_pBook[static_cast<int>(m_bIsEnd)]->Where();
+}
+
+long WW8PLCFx_AtnBook::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
+{
+    void* pData;
+    rEnd = WW8_CP_MAX;
+    rLen = 0;
+
+    if (!m_pBook[0] || !m_pBook[1] || !nIMax || (m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx()) >= nIMax)
+    {
+        rStart = rEnd = WW8_CP_MAX;
+        return -1;
+    }
+
+    (void)m_pBook[static_cast<int>(m_bIsEnd)]->Get(rStart, pData);
+    return m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx();
+}
+
+void WW8PLCFx_AtnBook::advance()
+{
+    if( m_pBook[0] && m_pBook[1] && nIMax )
+    {
+        (*m_pBook[static_cast<int>(m_bIsEnd)]).advance();
+
+        sal_uLong l0 = m_pBook[0]->Where();
+        sal_uLong l1 = m_pBook[1]->Where();
+        if( l0 < l1 )
+            m_bIsEnd = false;
+        else if( l1 < l0 )
+            m_bIsEnd = true;
+        else
+        {
+            const void * p = m_pBook[0]->GetData(m_pBook[0]->GetIdx());
+            long nPairFor = (p == NULL)? 0L : SVBT16ToShort(*((SVBT16*) p));
+            if (nPairFor == m_pBook[1]->GetIdx())
+                m_bIsEnd = false;
+            else
+                m_bIsEnd = !m_bIsEnd;
+        }
+    }
+}
+
+sal_uInt16 WW8PLCFx_AtnBook::getHandle() const
+{
+    if (!m_pBook[0] || !m_pBook[1])
+        return LONG_MAX;
+
+    if (m_bIsEnd)
+        return m_pBook[1]->GetIdx();
+    else
+    {
+        if (const void* p = m_pBook[0]->GetData(m_pBook[0]->GetIdx()))
+            return SVBT16ToShort(*(static_cast<const SVBT16*>(p)));
+        else
+            return LONG_MAX;
+    }
+}
+
+bool WW8PLCFx_AtnBook::getIsEnd() const
+{
+    return m_bIsEnd;
+}
+
 #ifndef DUMP
 
 // Am Ende eines Absatzes reichen bei WW6 die Attribute bis hinter das <CR>.
@@ -4374,12 +4507,14 @@ WW8PLCFMan::WW8PLCFMan(WW8ScannerBase* pBase, ManTypes nType, long nStartCp,
         pChp = &aD[7];
         pPap = &aD[8];
         pSep = &aD[9];
+        pAtnBkm = &aD[10];
 
         pSep->pPLCFx = pBase->pSepPLCF;
         pFtn->pPLCFx = pBase->pFtnPLCF;
         pEdn->pPLCFx = pBase->pEdnPLCF;
         pBkm->pPLCFx = pBase->pBook;
         pAnd->pPLCFx = pBase->pAndPLCF;
+        pAtnBkm->pPLCFx = pBase->pAtnBook;
 
     }
     else
@@ -4397,7 +4532,7 @@ WW8PLCFMan::WW8PLCFMan(WW8ScannerBase* pBase, ManTypes nType, long nStartCp,
         pPap = &aD[5];
         pSep = &aD[6]; // Dummy
 
-        pAnd = pFtn = pEdn = 0;     // unbenutzt bei SpezText
+        pAnd = pAtnBkm = pFtn = pEdn = 0;     // unbenutzt bei SpezText
     }
 
     pChp->pPLCFx = pBase->pChpPLCF;
@@ -4674,6 +4809,8 @@ void WW8PLCFMan::GetNoSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
         pRes->nSprmId = eEDN;
     else if( p == pBkm )
         pRes->nSprmId = eBKN;
+    else if (p == pAtnBkm)
+        pRes->nSprmId = eATNBKN;
     else if( p == pAnd )
         pRes->nSprmId = eAND;
     else if( p == pPcd )
@@ -4692,6 +4829,8 @@ void WW8PLCFMan::GetNoSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
 
     if( &aD[nIdx] == pBkm )
         pRes->nSprmId = eBKN;
+    else if (&aD[nIdx] == pAtnBkm)
+        pRes->nSprmId = eATNBKN;
     else if( &aD[nIdx] == pPcd )
     {
         //We slave the piece table attributes to the piece table, the piece
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 95711ae..a3bdf78 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -364,7 +364,7 @@ public:
 enum ePLCFT{ CHP=0, PAP, SEP, /*HED, FNR, ENR,*/ PLCF_END };
 
 //Its hardcoded that eFTN be the first one: A very poor hack, needs to be fixed
-enum eExtSprm { eFTN = 256, eEDN = 257, eFLD = 258, eBKN = 259, eAND = 260 };
+enum eExtSprm { eFTN = 256, eEDN = 257, eFLD = 258, eBKN = 259, eAND = 260, eATNBKN = 261 };
 
 /*
     pure virtual:
@@ -769,6 +769,37 @@ public:
     OUString GetUniqueBookmarkName(const OUString &rSuggestedName);
 };
 
+/// Handles the import of PlcfAtnBkf and PlcfAtnBkl: start / end position of annotation marks.
+class WW8PLCFx_AtnBook : public WW8PLCFx
+{
+private:
+    /// Start and end positions.
+    WW8PLCFspecial* m_pBook[2];
+    /// Number of annotation marks
+    sal_Int32 nIMax;
+    bool m_bIsEnd;
+
+    //No copying
+    WW8PLCFx_AtnBook(const WW8PLCFx_AtnBook&);
+    WW8PLCFx_AtnBook& operator=(const WW8PLCFx_AtnBook&);
+
+public:
+    WW8PLCFx_AtnBook(SvStream* pTblSt,const WW8Fib& rFib);
+    virtual ~WW8PLCFx_AtnBook();
+    virtual sal_uInt32 GetIdx() const SAL_OVERRIDE;
+    virtual void SetIdx( sal_uLong nI ) SAL_OVERRIDE;
+    virtual sal_uLong GetIdx2() const SAL_OVERRIDE;
+    virtual void SetIdx2( sal_uLong nIdx ) SAL_OVERRIDE;
+    virtual bool SeekPos(WW8_CP nCpPos) SAL_OVERRIDE;
+    virtual WW8_FC Where() SAL_OVERRIDE;
+    virtual long GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen ) SAL_OVERRIDE;
+    virtual void advance() SAL_OVERRIDE;
+
+    /// Handle is the unique ID of an annotation mark.
+    sal_uInt16 getHandle() const;
+    bool getIsEnd() const;
+};
+
 /*
     hiermit arbeiten wir draussen:
 */
@@ -857,7 +888,7 @@ struct WW8PLCFxSaveAll;
 class WW8PLCFMan
 {
 public:
-    enum WW8PLCFManLimits {MAN_ANZ_PLCF = 10};
+    enum WW8PLCFManLimits {MAN_ANZ_PLCF = 11};
 
 private:
     wwSprmParser maSprmParser;
@@ -874,7 +905,7 @@ private:
 
     WW8PLCFxDesc aD[MAN_ANZ_PLCF];
     WW8PLCFxDesc *pChp, *pPap, *pSep, *pFld, *pFtn, *pEdn, *pBkm, *pPcd,
-        *pPcdA, *pAnd;
+        *pPcdA, *pAnd, *pAtnBkm;
     WW8PLCFspecial *pFdoa, *pTxbx, *pTxbxBkd,*pMagicTables, *pSubdocs;
     sal_uInt8* pExtendedAtrds;
 
@@ -911,6 +942,7 @@ public:
     WW8PLCFx_SubDoc* GetFtn() const { return (WW8PLCFx_SubDoc*)pFtn->pPLCFx; }
     WW8PLCFx_SubDoc* GetAtn() const { return (WW8PLCFx_SubDoc*)pAnd->pPLCFx; }
     WW8PLCFx_Book* GetBook() const { return (WW8PLCFx_Book*)pBkm->pPLCFx; }
+    WW8PLCFx_AtnBook* GetAtnBook() const { return static_cast<WW8PLCFx_AtnBook*>(pAtnBkm->pPLCFx); }
     long GetCpOfs() const { return pChp->nCpOfs; }  // for Header/Footer...
 
     /* fragt, ob *aktueller Absatz* einen Sprm diesen Typs hat */
@@ -989,6 +1021,7 @@ private:
     WW8PLCFspecial*   pSubdocs;         // subdoc references in master document
     sal_uInt8*        pExtendedAtrds;   // Extended ATRDs
     WW8PLCFx_Book*    pBook;            // Bookmarks
+    WW8PLCFx_AtnBook* pAtnBook;         // Annotationmarks
 
     WW8PLCFpcd*         pPiecePLCF; // fuer FastSave ( Basis-PLCF ohne Iterator )
     WW8PLCFpcd_Iter*    pPieceIter; // fuer FastSave ( Iterator dazu )
commit 1cea71c84a07ce84efd44578538faddea0708cfb
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Dec 30 10:32:16 2014 +0100

    i#93570 sw: add RES_FLTR_ANNOTATIONMARK
    
    As commit b1cd83c625a2afeb9da43cc9745d79c01963c797 (fix crash loading
    ooo#93570-3.doc, 2014-07-04) notes, the way how we map WW8 CP indexes to
    sw character positions is working only in the very simple cases.
    
    However, to do that properly, we need a way to store the start position
    of an annotation mark before we create it, so add a
    RES_FLTR_ANNOTATIONMARK that can do so.
    
    (cherry picked from commit 271722d923610d128a358528e64d7233641ea0dc)
    
    Conflicts:
    	sw/source/filter/basflt/fltshell.cxx
    
    Change-Id: I7cb3564621803fef9a76edaac48773cab7649ee8

diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index 4bcde23..ecfd937 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -350,6 +350,7 @@ enum RES_FLTRATTR
     RES_FLTR_NUMRULE,
     RES_FLTR_TOX,
     RES_FLTR_REDLINE,
+    RES_FLTR_ANNOTATIONMARK,
     RES_FLTRATTR_END
 };
 
diff --git a/sw/source/filter/basflt/fltshell.cxx b/sw/source/filter/basflt/fltshell.cxx
index 5b94102..d30a6db 100644
--- a/sw/source/filter/basflt/fltshell.cxx
+++ b/sw/source/filter/basflt/fltshell.cxx
@@ -347,12 +347,16 @@ SwFltStackEntry* SwFltControlStack::SetAttr(const SwPosition& rPos,
             }
             else if (nAttrId == rEntry.pAttr->Which())
             {
-                if( nAttrId != RES_FLTR_BOOKMARK )
+                if( nAttrId != RES_FLTR_BOOKMARK && nAttrId != RES_FLTR_ANNOTATIONMARK )
                 {
                     // query handle
                     bF = true;
                 }
-                else if (nHand == ((SwFltBookmark*)(rEntry.pAttr))->GetHandle())
+                else if (nAttrId == RES_FLTR_BOOKMARK && nHand == static_cast<SwFltBookmark*>(rEntry.pAttr)->GetHandle())
+                {
+                    bF = true;
+                }
+                else if (nAttrId == RES_FLTR_ANNOTATIONMARK && nHand == static_cast<CntUInt16Item*>(rEntry.pAttr)->GetValue())
                 {
                     bF = true;
                 }
@@ -583,6 +587,12 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
             }
         }
         break;
+    case RES_FLTR_ANNOTATIONMARK:
+        {
+            MakeBookRegionOrPoint(rEntry, pDoc, aRegion, true);
+            pDoc->getIDocumentMarkAccess()->makeAnnotationMark(aRegion, OUString());
+        }
+        break;
     case RES_FLTR_TOX:
         {
             MakePoint(rEntry, pDoc, aRegion);
diff --git a/sw/source/filter/inc/fltshell.hxx b/sw/source/filter/inc/fltshell.hxx
index 3738c19..8aa6ede 100644
--- a/sw/source/filter/inc/fltshell.hxx
+++ b/sw/source/filter/inc/fltshell.hxx
@@ -148,7 +148,6 @@ protected:
     SwDoc* pDoc;
     bool bIsEndStack;
 
-    void MoveAttrs( const SwPosition&  rPos );
     virtual void SetAttrInDoc(const SwPosition& rTmpPos, SwFltStackEntry& rEntry);
     virtual sal_Int32 GetCurrAttrCP() const {return -1;}
     virtual bool IsParaEndInCPs(sal_Int32 nStart,sal_Int32 nEnd,bool bSdOD=true) const;
@@ -159,6 +158,7 @@ protected:
     bool HasSdOD();
 
 public:
+    void MoveAttrs( const SwPosition&  rPos );
     enum Flags
     {
         HYPO,


More information about the Libreoffice-commits mailing list