Index: source/filter/ww8/attributeoutputbase.hxx =================================================================== --- source/filter/ww8/attributeoutputbase.hxx (revision 1387848) +++ source/filter/ww8/attributeoutputbase.hxx (working copy) @@ -187,8 +187,11 @@ void StartTOX( const SwSection& rSect ); + //Add a parameter for paragraph end position + //On ending a TOX, we should identical whether the TOX should care about the paragraph end void EndTOX( const SwSection& rSect,bool bCareEnd=true ); + //Add new interface, for importing TOX from MS word binary format with high fidelity virtual void OnTOXEnding() {} virtual void TOXMark( const SwTxtNode& rNode, const SwTOXMark& rAttr ); Index: source/filter/ww8/writerwordglue.cxx =================================================================== --- source/filter/ww8/writerwordglue.cxx (revision 1387848) +++ source/filter/ww8/writerwordglue.cxx (working copy) @@ -518,6 +518,10 @@ depandancies for export, in which case this is the place to do it */ + /* + For the similar situation, we also need to make the RES_TXTATR_INETFMT + to be the exporting attribute with 2nd preority. + */ if (nA == nB) return false; if (nA == RES_TXTATR_CHARFMT) Index: source/filter/ww8/wrtw8nds.cxx =================================================================== --- source/filter/ww8/wrtw8nds.cxx (revision 1387848) +++ source/filter/ww8/wrtw8nds.cxx (working copy) @@ -1993,11 +1993,17 @@ aAttrIter.OutFlys( nEnd ); // insert final bookmarks if any before CR and after flys AppendBookmarks( rNode, nEnd, 1 ); + //Here as the paragraph end should be inside a TOX field, + //we need to invoke the WriterCR at first, then export the + //tox field end stuff WriteCR( pTextNodeInfoInner ); if ( pTOXSect ) { m_aCurrentCharPropStarts.pop(); + //Further more, as we alternate the order of exporting + //paragraph end and field end, we need to adjust the + //paragraph end position when exporting the PapxFKP AttrOutput().EndTOX( *pTOXSect ); } @@ -2522,8 +2528,10 @@ SwNodeIndex aIdx( rSectionNode, 1 ); const SwNode& rNd = aIdx.GetNode(); - if ( !rNd.IsSectionNode() && !IsInTable() - && rSection.GetType() != TOX_CONTENT_SECTION && rSection.GetType() != TOX_HEADER_SECTION) //No sections in table + if ( !rNd.IsSectionNode() && !IsInTable() //No sections in table + //If the current section is actually a TOC section, we will convert it into a TOC field in MS Word format, + //So the section break stuff need not to export anymore + && rSection.GetType() != TOX_CONTENT_SECTION && rSection.GetType() != TOX_HEADER_SECTION) { // Bug 74245 - if the first Node inside the section has an own // PageDesc or PageBreak attribut, then dont write Index: source/filter/ww8/wrtww8.cxx =================================================================== --- source/filter/ww8/wrtww8.cxx (revision 1387848) +++ source/filter/ww8/wrtww8.cxx (working copy) @@ -190,6 +190,45 @@ WW8_FC GetStartFc() const { return nStartFc; } }; +//Yes, we just refined the whole definition and implementation of class WW8_WrtBookmarks. +//The reason is that, the former one can not export the bookmark range in the correct way, +//if the bookmarks ranges have the intersection situation. And it will cause MS word crash when +//perform the TOC we exported depend on such bookmarks. +//The correct way of Bookmark exporting in MS word binary format (CAUTION, it is REALLY a wired way): +//At first, all the first positions of all the bookmarks will be exported together, in ascent order; +//At last, all the last positions of all the bookmarks will be exported together, in ascent order; +//Between above 2 blocks, is the matching relationship between the first and last position of each bookmarks, in the order of the first block; +//For example, we have 3 bookmarks with character position like below: +//Bookmark1: [1-10]; +//Bookmark2: [5-5]; +//Bookmark3: [6-7]; +//the correct exporting of bookmark ranges should be: +//[1st block start]1, 5, 6[1st block end][2nd block start]3,1,2[2nd block end][3rd block start]5,7,10[3rd block end] +//Congratulations, you survived, but I guess you prefer having not experienced this nightmare. +/*class WW8_WrtBookmarks +{ +private: + SvULongs aSttCps, aEndCps; // Array of Start- and End CPs + SvBools aFieldMarks; // If the bookmark is in a field result + std::vector maSwBkmkNms; // Array of Sw - Bookmarknames + typedef std::vector::iterator myIter; + + sal_uInt16 GetPos( const String& rNm ); + + //No copying + WW8_WrtBookmarks(const WW8_WrtBookmarks&); + WW8_WrtBookmarks& operator=(const WW8_WrtBookmarks&); +public: + WW8_WrtBookmarks(); + ~WW8_WrtBookmarks(); + + void Append( WW8_CP nStartCp, const String& rNm, const ::sw::mark::IMark* pBkmk=NULL ); + void Write( WW8Export& rWrt ); + void MoveFieldMarks(sal_uLong nFrom,sal_uLong nTo); + +// String GetWWBkmkName( const String& rName ) const; +};*/ + typedef std::map BKMKNames; typedef BKMKNames::iterator BKMKNmItr; typedef std::pair BKMK; @@ -2547,8 +2586,10 @@ ; else if ( aIdx.GetNode().IsSectionNode() ) ; - else if ( !IsInTable() - && (rSect.GetType() != TOX_CONTENT_SECTION && rSect.GetType() != TOX_HEADER_SECTION )) //No sections in table + else if ( !IsInTable() //No sections in table + //If the current section is actually a TOC section, we will convert it into a TOC field in MS Word format, + //So the section break stuff need not to export anymore + && (rSect.GetType() != TOX_CONTENT_SECTION && rSect.GetType() != TOX_HEADER_SECTION )) { //#120140# Do not need to insert a page/section break after a section end. Check this case first sal_Bool bNeedExportBreakHere = sal_True; Index: source/filter/ww8/ww8atr.cxx =================================================================== --- source/filter/ww8/ww8atr.cxx (revision 1387848) +++ source/filter/ww8/ww8atr.cxx (working copy) @@ -967,7 +967,13 @@ void WW8AttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) { + //Here, if the data member mbOnTOXEnding is true, means that + // we alternate the order of exporting + //paragraph end and field end, we need to adjust the + //paragraph end position when exporting the PapxFKP m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() - (mbOnTOXEnding?2:0), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() ); + //After dealing with the paragraph end adjust stuff, we need to change + //the value of mbOnTOXEnding back to false, as its default value. mbOnTOXEnding = false; m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete @@ -1015,6 +1021,11 @@ } } +//Implemente new method, for importing TOX from MS word binary format with high fidelity +//The method only could be invoked inside AttributeOutputBase::EndTOX, and only things to do +//is to enable the flag for indicating that currently on dealing with the end of a TOX. This flag will +//be concerned inside the function WW8AttributeOutput::EndParagraph, also will be disabled inside +//the function WW8AttributeOutput::EndParagraph void WW8AttributeOutput::OnTOXEnding() { mbOnTOXEnding = true; Index: source/filter/ww8/ww8attributeoutput.hxx =================================================================== --- source/filter/ww8/ww8attributeoutput.hxx (revision 1387848) +++ source/filter/ww8/ww8attributeoutput.hxx (working copy) @@ -52,6 +52,7 @@ /// virtual void StartRun( const SwRedlineData* pRedlineData ); + //Add new method, for importing TOX from MS word binary format with high fidelity virtual void OnTOXEnding(); /// End of the text run. @@ -437,6 +438,10 @@ /// of the field results if we were forced to split text. sal_uInt16 m_nFieldResults; + //Add new member for marking the TOX end status + //this flag for indicating that currently on dealing with the end of a TOX with false value by default. + //And it will be enabled in the WW8AttributeOutput::OnTOXEnding, and will be concerned and + //be disabled inside the function WW8AttributeOutput::EndParagraph bool mbOnTOXEnding; public: Index: source/filter/ww8/ww8par.cxx =================================================================== --- source/filter/ww8/ww8par.cxx (revision 1387848) +++ source/filter/ww8/ww8par.cxx (working copy) @@ -3177,12 +3177,22 @@ if (mbCareFirstParaEndInToc) { mbCareFirstParaEndInToc = false; + //Here as the previous paragraph of toc is not end before toc started, + //now we should check that whether the first paragraph inside TOC section + //is actually an empty one, which means, the rest part of previous paragraph + //inside the toc section, is only a paragraph end: 0x0D. If Yes, ignore it. And + //of cause, reset the flag at sametime if (pPaM->End() && pPaM->End()->nNode.GetNode().GetTxtNode() && pPaM->End()->nNode.GetNode().GetTxtNode()->Len() == 0) bSplit = false; } if (mbCareLastParaEndInToc) { mbCareLastParaEndInToc = false; + //Here as the last paragraph inside toc section is not end before toc ended, + //now we should check that whether the following paragraph of TOC section + //is actually an empty one, which means, the rest part of following paragraph + //of the toc section, is only a paragraph end: 0x0D. If Yes, ignore it. And + //of cause, reset the flag at sametime if (pPaM->End() && pPaM->End()->nNode.GetNode().GetTxtNode() && pPaM->End()->nNode.GetNode().GetTxtNode()->Len() == 0) bSplit = false; } Index: source/filter/ww8/ww8par.hxx =================================================================== --- source/filter/ww8/ww8par.hxx (revision 1387848) +++ source/filter/ww8/ww8par.hxx (working copy) @@ -1109,6 +1109,32 @@ bool mbLoadingTOCHyperlink; // a document position recorded the after-position of TOC section, managed by Read_F_TOX() and End_Field() SwPaM* mpPosAfterTOC; + //Here for the TOC importing fidelity issue, we need to face a fundmantally mapping problem that: + //The TOC in AOO is embeded inside a section. For the most common TOC case in MS word file, + //that the TOC including several whole paragraphs, such mapping mechanism could work perfectly. + //Refer to the following descrition: + // common TOX Field and context case in MS Binary format: + //Previous paragraph 0x0D + //0x13 TOC XXXXX 0x14 + //toc item 1 0x0D + //toc item 2 0x0D + //... + //toc item last 0x0D + //0x15 + //But, unfortunately, MS Word binary format do support in-common TOC field data, + //which may contain last part of its previous paragraph, or does not contain the + //last part of its last item, for example: + //Previous paragraph first part + //0x13 TOC XXXXX 0x14 + //Previous paragraph last part 0x0D + //toc item 1 0x0D + //toc item 2 0x0D + //... + //toc item X first part + //0x15 + //toc item X last part 0x0D + //For such in-common TOC cases, we need following 2 data members for avoid the + //unexpected blank paragraphs before or after the TOC. bool mbCareFirstParaEndInToc; bool mbCareLastParaEndInToc; Index: source/filter/ww8/ww8par5.cxx =================================================================== --- source/filter/ww8/ww8par5.cxx (revision 1387848) +++ source/filter/ww8/ww8par5.cxx (working copy) @@ -701,6 +701,12 @@ { maTOXEndCps.insert(nCP); mbLoadingTOCCache = false; + //If the last paragraph inside toc section is empty one, lucky, for it is a common toc case, + //which contain the whole last paragraph inside, including the paragraph end also; We just + //need to join the node back and no further works. + //If not, also lucky, for we met a rare toc case, something like win in lottery. But we have to + //do further works on: enable flag mbCareLastParaEndInToc indicate that we shall care about + //the following paragrah of toc section importing if ( pPaM->End() && pPaM->End()->nNode.GetNode().GetTxtNode() && pPaM->End()->nNode.GetNode().GetTxtNode()->Len() == 0 ) @@ -3449,7 +3455,8 @@ //#i10028# inserting a toc implicltly acts like a parabreak //in word and writer - + //If the paragraph end of the previous paragraph of toc not be reached before the toc is reached + //we need to care about the first paragraph in TOC section if ( pPaM->End() && pPaM->End()->nNode.GetNode().GetTxtNode() && pPaM->End()->nNode.GetNode().GetTxtNode()->Len() != 0 )