diff options
Diffstat (limited to 'sw/source/filter/ww8')
-rw-r--r-- | sw/source/filter/ww8/attributeoutputbase.hxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 216 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.hxx | 8 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.hxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfattributeoutput.hxx | 1 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfexport.hxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8nds.cxx | 23 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 7 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8atr.cxx | 64 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8attributeoutput.hxx | 2 |
10 files changed, 325 insertions, 2 deletions
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx index 5327be3a819a..b2a7605a9330 100644 --- a/sw/source/filter/ww8/attributeoutputbase.hxx +++ b/sw/source/filter/ww8/attributeoutputbase.hxx @@ -209,6 +209,8 @@ public: virtual void FieldVanish( const OUString& rText, ww::eField eType ) = 0; + virtual void GenerateBookmarksForSequenceField(const SwTextNode& rNode, SwWW8AttrIter& rAttrIter) = 0; + void StartTOX( const SwSection& rSect ); void EndTOX( const SwSection& rSect,bool bCareEnd=true ); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 57e182dc34ac..4bf1b1c3dc27 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -125,6 +125,8 @@ #include <IDocumentSettingAccess.hxx> #include <IDocumentStylePoolAccess.hxx> #include <IDocumentRedlineAccess.hxx> +#include <IDocumentFieldsAccess.hxx> +#include <reffld.hxx> #include <osl/file.hxx> #include <vcl/embeddedfontshelper.hxx> @@ -594,6 +596,10 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT if( !m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen() ) m_bParagraphOpened = false; + // Clear gererated bookmarks + m_aBookmarksWithPosStart.clear(); + m_aBookmarksWithPosEnd.clear(); + } void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, @@ -1278,6 +1284,8 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos) m_endPageRef = true; } + DoWriteBookmarkStartIfExist(nPos); + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); if(GetExport().m_bTabInTOC && m_pHyperlinkAttrList.is()) { @@ -1377,6 +1385,8 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos) } m_nFieldsInHyperlink = 0; } + + DoWriteBookmarkEndIfExist(nPos); } void DocxAttributeOutput::DoWriteBookmarkTagStart(const OUString & bookmarkName) @@ -1404,6 +1414,34 @@ void DocxAttributeOutput::DoWriteBookmarkTagEnd(const OUString & bookmarkName) } } +void DocxAttributeOutput::DoWriteBookmarkStartIfExist(sal_Int32 nPos) +{ + auto aRange = m_aBookmarksWithPosStart.equal_range(nPos); + for( auto aIter = aRange.first; aIter != aRange.second; ++aIter) + { + DoWriteBookmarkTagStart(aIter->second); + m_rOpenedBookmarksIds[aIter->second] = m_nNextBookmarkId; + m_sLastOpenedBookmark = OUStringToOString(BookmarkToWord(aIter->second), RTL_TEXTENCODING_UTF8).getStr(); + m_nNextBookmarkId++; + } +} + +void DocxAttributeOutput::DoWriteBookmarkEndIfExist(sal_Int32 nPos) +{ + auto aRange = m_aBookmarksWithPosEnd.equal_range(nPos); + for( auto aIter = aRange.first; aIter != aRange.second; ++aIter) + { + // Get the id of the bookmark + auto pPos = m_rOpenedBookmarksIds.find(aIter->second); + if (pPos != m_rOpenedBookmarksIds.end()) + { + // Output the bookmark + DoWriteBookmarkTagEnd(aIter->second); + m_rOpenedBookmarksIds.erase(aIter->second); + } + } +} + /// Write the start bookmarks void DocxAttributeOutput::DoWriteBookmarksStart() { @@ -1662,7 +1700,7 @@ void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nP else { // Write the field start - if ( rInfos.pField && rInfos.pField->GetSubType() & FIXEDFLD ) + if ( rInfos.pField && (rInfos.pField->Which() == SwFieldIds::DateTime) && rInfos.pField->GetSubType() & FIXEDFLD ) { m_pSerializer->startElementNS( XML_w, XML_fldChar, FSNS( XML_w, XML_fldCharType ), "begin", @@ -7143,6 +7181,176 @@ bool DocxAttributeOutput::PlaceholderField( const SwField* pField ) return false; // do not expand } +void DocxAttributeOutput::GenerateBookmarksForSequenceField(const SwTextNode& rNode, SwWW8AttrIter& rAttrIter) +{ + if (const SwpHints* pTextAttrs = rNode.GetpSwpHints()) + { + for( size_t i = 0; i < pTextAttrs->Count(); ++i ) + { + const SwTextAttr* pHt = pTextAttrs->Get(i); + if (pHt->GetAttr().Which() == RES_TXTATR_FIELD) + { + const SwFormatField& rField = static_cast<const SwFormatField&>(pHt->GetAttr()); + const SwField* pField = rField.GetField(); + // Need to have bookmarks only for sequence fields + if (pField && pField->GetTyp()->Which() == SwFieldIds::SetExp && pField->GetSubType() == nsSwGetSetExpType::GSE_SEQ) + { + const sal_uInt16 nSeqFieldNumber = static_cast<const SwSetExpField*>(pField)->GetSeqNumber(); + const OUString sObjectName = static_cast<const SwSetExpFieldType*>(pField->GetTyp())->GetName(); + const SwFieldTypes* pFieldTypes = m_rExport.m_pDoc->getIDocumentFieldsAccess().GetFieldTypes(); + bool bHaveFullBkm = false; + bool bHaveLabelAndNumberBkm = false; + bool bHaveCaptionOnlyBkm = false; + bool bHaveNumberOnlyBkm = false; + bool bRunSplittedAtSep = false; + for( auto pFieldType : *pFieldTypes ) + { + if( SwFieldIds::GetRef == pFieldType->Which() ) + { + SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType ); + for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() ) + { + SwGetRefField* pRefField = static_cast<SwGetRefField*>(pFormatField->GetField()); + // If we have a reference to the current sequence field + if(pRefField->GetSeqNo() == nSeqFieldNumber && pRefField->GetSetRefName() == sObjectName) + { + // Need to create a seperate run for separator character + SwWW8AttrIter aLocalAttrIter( m_rExport, rNode ); + const OUString aText = rNode.GetText(); + const sal_Int32 nCategoryStart = aText.indexOf(pRefField->GetSetRefName()); + const sal_Int32 nPosBeforeSeparator = std::max(nCategoryStart, pHt->GetStart()); + bool bCategoryFirst = nCategoryStart < pHt->GetStart(); + sal_Int32 nSeparatorPos = 0; + if (bCategoryFirst) + { + nSeparatorPos = aLocalAttrIter.WhereNext(); + while (nSeparatorPos <= nPosBeforeSeparator) + { + aLocalAttrIter.NextPos(); + nSeparatorPos = aLocalAttrIter.WhereNext(); + } + } + else + { + nSeparatorPos = nCategoryStart + pRefField->GetSetRefName().getLength(); + } + sal_Int32 nRefTextPos = 0; + if(nSeparatorPos < aText.getLength()) + { + nRefTextPos = SwGetExpField::GetReferenceTextPos(pHt->GetFormatField(), *m_rExport.m_pDoc, nSeparatorPos); + if(nRefTextPos != nSeparatorPos) + { + if(!bRunSplittedAtSep) + { + if(!bCategoryFirst) + rAttrIter.SplitRun(nSeparatorPos); + rAttrIter.SplitRun(nRefTextPos); + bRunSplittedAtSep = true; + } + if(!bCategoryFirst) + aLocalAttrIter.SplitRun(nSeparatorPos); + aLocalAttrIter.SplitRun(nRefTextPos); + } + else if (bCategoryFirst) + { + if(!bRunSplittedAtSep) + { + rAttrIter.SplitRun(nSeparatorPos); + bRunSplittedAtSep = true; + } + aLocalAttrIter.SplitRun(nSeparatorPos); + } + } + // Generate bookmarks on the right position + OUString sName("Ref_" + pRefField->GetSetRefName()); + sName += OUString::number(pRefField->GetSeqNo()); + switch (pRefField->GetFormat()) + { + case REF_PAGE: + case REF_PAGE_PGDESC: + case REF_CONTENT: + case REF_UPDOWN: + sName += "_full"; + if(!bHaveFullBkm) + { + sal_Int32 nLastAttrStart = 0; + sal_Int32 nActAttr = aLocalAttrIter.WhereNext(); + while (nActAttr < rNode.GetText().getLength()) + { + nLastAttrStart = nActAttr; + aLocalAttrIter.NextPos(); + nActAttr = aLocalAttrIter.WhereNext(); + } + WriteBookmarks_Impl( sName, std::min(nCategoryStart, pHt->GetStart()), nLastAttrStart ); + bHaveFullBkm = true; + } + break; + case REF_ONLYNUMBER: + { + sName += "_label_and_number"; + if(!bHaveLabelAndNumberBkm) + { + if(bCategoryFirst) + WriteBookmarks_Impl( sName, std::min(nCategoryStart, pHt->GetStart()), std::max(nCategoryStart, pHt->GetStart()) ); + else + { + // Find the last run which contains category text + SwWW8AttrIter aLocalAttrIter2( m_rExport, rNode ); + sal_Int32 nCatLastRun = 0; + sal_Int32 nNextAttr = aLocalAttrIter2.WhereNext(); + while (nNextAttr < nSeparatorPos) + { + nCatLastRun = nNextAttr; + aLocalAttrIter2.NextPos(); + nNextAttr = aLocalAttrIter2.WhereNext(); + } + WriteBookmarks_Impl( sName, pHt->GetStart(), nCatLastRun ); + } + bHaveLabelAndNumberBkm = true; + } + break; + } + case REF_ONLYCAPTION: + { + sName += "_caption_only"; + if(!bHaveCaptionOnlyBkm) + { + // Find last run + sal_Int32 nLastAttrStart = 0; + sal_Int32 nActAttr = aLocalAttrIter.WhereNext(); + while (nActAttr < rNode.GetText().getLength()) + { + nLastAttrStart = nActAttr; + aLocalAttrIter.NextPos(); + nActAttr = aLocalAttrIter.WhereNext(); + } + WriteBookmarks_Impl( sName, nRefTextPos, nLastAttrStart ); + bHaveCaptionOnlyBkm = true; + } + break; + } + case REF_ONLYSEQNO: + { + sName += "_number_only"; + if(!bHaveNumberOnlyBkm) + { + WriteBookmarks_Impl( sName, pHt->GetStart(), pHt->GetStart() ); + bHaveNumberOnlyBkm = true; + } + break; + } + } + } + } + } + } + return; + } + } + } + } +} + void DocxAttributeOutput::WritePendingPlaceholder() { if( pendingPlaceholder == nullptr ) @@ -7248,6 +7456,12 @@ void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts, rEnds.clear(); } +void DocxAttributeOutput::WriteBookmarks_Impl( const OUString& rName, sal_Int32 nWithStartPos, sal_Int32 nWithEndPos ) +{ + m_aBookmarksWithPosStart.insert(std::pair<sal_Int32, OUString>(nWithStartPos, rName)); + m_aBookmarksWithPosEnd.insert(std::pair<sal_Int32, OUString>(nWithEndPos, rName)); +} + void DocxAttributeOutput::WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds ) { diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 8822d523dec3..eb9dcf4d6791 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -370,6 +370,7 @@ public: void WriteFormData_Impl( const ::sw::mark::IFieldmark& rFieldmark ); void WriteBookmarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds ); + void WriteBookmarks_Impl( const OUString& rName, sal_Int32 nWithStartPos, sal_Int32 nWithEndPos ); void WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds ); void PushRelIdCache(); void PopRelIdCache(); @@ -699,6 +700,8 @@ private: void DoWriteBookmarkTagEnd(const OUString & bookmarkName); void DoWriteBookmarksStart(); void DoWriteBookmarksEnd(); + void DoWriteBookmarkStartIfExist(sal_Int32 nPos); + void DoWriteBookmarkEndIfExist(sal_Int32 nPos); void DoWritePermissionTagStart(const OUString & permission); void DoWritePermissionTagEnd(const OUString & permission); @@ -730,6 +733,7 @@ private: void CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun ); void EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos& rInfos ); void DoWriteFieldRunProperties( const SwTextNode* pNode, sal_Int32 nPos ); + virtual void GenerateBookmarksForSequenceField(const SwTextNode& rNode, SwWW8AttrIter& rAttrIter) override; static void AddToAttrList( rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nAttrName, const sal_Char* sAttrValue ); static void AddToAttrList( rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nArgs, ... ); @@ -787,6 +791,10 @@ private: std::vector<OUString> m_rBookmarksStart; std::vector<OUString> m_rBookmarksEnd; + /// Bookmarks with position to output + std::multimap<sal_Int32, OUString> m_aBookmarksWithPosStart; + std::multimap<sal_Int32, OUString> m_aBookmarksWithPosEnd; + /// Permissions to output std::vector<OUString> m_rPermissionsStart; std::vector<OUString> m_rPermissionsEnd; diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx index de017201ed78..df65f3d39e93 100644 --- a/sw/source/filter/ww8/docxexport.hxx +++ b/sw/source/filter/ww8/docxexport.hxx @@ -186,6 +186,8 @@ public: void WriteOutliner(const OutlinerParaObject& rOutliner, sal_uInt8 nTyp); + virtual ExportFormat GetExportFormat() const override { return ExportFormat::DOCX; } + protected: /// Format-dependent part of the actual export. virtual void ExportDocument_Impl() override; diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index 1520569a7dd3..0f25754927c4 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -218,6 +218,7 @@ public: void WriteBookmarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds); void WriteAnnotationMarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds); void WriteHeaderFooter_Impl(const SwFrameFormat& rFormat, bool bHeader, const sal_Char* pStr, bool bTitlepg); + void GenerateBookmarksForSequenceField(const SwTextNode& /*rNode*/, SwWW8AttrIter& /*rAttrIter*/) override {}; protected: /// Output frames - the implementation. diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx index 0b58e27392ae..64cceef9b333 100644 --- a/sw/source/filter/ww8/rtfexport.hxx +++ b/sw/source/filter/ww8/rtfexport.hxx @@ -124,6 +124,8 @@ public: sal_uLong ReplaceCr(sal_uInt8 nChar) override; + ExportFormat GetExportFormat() const override { return ExportFormat::RTF; } + protected: /// Format-dependent part of the actual export. void ExportDocument_Impl() override; diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 87c27db44c89..23208e90a8fc 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -1173,6 +1173,25 @@ void SwWW8AttrIter::OutSwFormatRefMark(const SwFormatRefMark& rAttr) &rAttr.GetRefName(), 0 )); } +void SwWW8AttrIter::SplitRun( sal_Int32 nSplitEndPos ) +{ + for(auto aIter = maCharRuns.begin(); aIter != maCharRuns.end(); ++aIter) + { + if(aIter->mnEndPos == nSplitEndPos) + return; + else if (aIter->mnEndPos > nSplitEndPos) + { + CharRunEntry aNewEntry = *aIter; + aIter->mnEndPos = nSplitEndPos; + maCharRuns.insert( ++aIter, aNewEntry); + maCharRunIter = maCharRuns.begin(); + IterToCurrent(); + nAktSwPos = SearchNext(1); + break; + } + } +} + void WW8AttributeOutput::FieldVanish( const OUString& rText, ww::eField /*eType*/ ) { ww::bytes aItems; @@ -2163,6 +2182,10 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) AppendBookmark( BookmarkToWord( sBkmkName ) ); } + // Call this before write out fields and runs + if(GetExportFormat() == ExportFormat::DOCX) + AttrOutput().GenerateBookmarksForSequenceField(rNode, aAttrIter); + const OUString& aStr( rNode.GetText() ); sal_Int32 nAktPos = 0; diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index c3f05caad3c9..c96dcd8299b0 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -783,6 +783,9 @@ public: /// Returns the index of a picture bullet, used in numberings. int GetGrfIndex(const SvxBrushItem& rBrush); + enum ExportFormat { DOC = 0, RTF = 1, DOCX = 2}; + virtual ExportFormat GetExportFormat() const = 0; + protected: /// Format-dependent part of the actual export. virtual void ExportDocument_Impl() = 0; @@ -1145,6 +1148,8 @@ public: const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const SwFrameFormat& rFirstPageFormat, sal_uInt8 nBreakCode) override; + virtual ExportFormat GetExportFormat() const override { return ExportFormat::DOC; } + protected: /// Output SwGrfNode virtual void OutputGrfNode( const SwGrfNode& ) override; @@ -1508,6 +1513,8 @@ public: bool IsWatermarkFrame(); bool IsAnchorLinkedToThisNode( sal_uLong nNodePos ); + + void SplitRun( sal_Int32 nSplitEndPos ); }; /// Class to collect and output the styles table. diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index dfa4c2d29aa2..ad4c300b0350 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -899,7 +899,12 @@ OUString MSWordExportBase::GetBookmarkName( sal_uInt16 nTyp, const OUString* pNa } break; case REF_SEQUENCEFLD: - break; // ??? + { + assert(pName); + sRet += "Ref_"; + sRet += *pName; + break; + } case REF_BOOKMARK: if ( pName ) sRet = *pName; @@ -2779,6 +2784,63 @@ void AttributeOutputBase::TextField( const SwFormatField& rField ) break; } break; + case REF_SEQUENCEFLD: + { + // Have this only for DOCX format by now + if(!(GetExport().GetExportFormat() == MSWordExportBase::ExportFormat::DOCX)) + break; + + switch (pField->GetFormat()) + { + case REF_PAGE: + case REF_PAGE_PGDESC: + eField = ww::ePAGEREF; + break; + default: + eField = ww::eREF; + break; + } + // Generate a unique bookmark name + { + OUString sName(rRField.GetSetRefName()); + sName += OUString::number(rRField.GetSeqNo()); + switch (pField->GetFormat()) + { + case REF_PAGE: + case REF_PAGE_PGDESC: + case REF_CONTENT: + case REF_UPDOWN: + sName += "_full"; + break; + case REF_ONLYNUMBER: + sName += "_label_and_number"; + break; + case REF_ONLYCAPTION: + sName += "_caption_only"; + break; + case REF_ONLYSEQNO: + sName += "_number_only"; + break; + default: // Ingore other types of reference fields + eField = ww::eNONE; + break; + } + sStr = FieldString(eField) + MSWordExportBase::GetBookmarkName(nSubType, &sName, 0); + } + switch (pField->GetFormat()) + { + case REF_NUMBER: + sStr += " \\r"; + break; + case REF_NUMBER_NO_CONTEXT: + sStr += " \\n"; + break; + case REF_NUMBER_FULL_CONTEXT: + sStr += " \\w"; + break; + } + break; + } case REF_FOOTNOTE: case REF_ENDNOTE: switch (pField->GetFormat()) diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx index 9a4701d49199..d814fff62805 100644 --- a/sw/source/filter/ww8/ww8attributeoutput.hxx +++ b/sw/source/filter/ww8/ww8attributeoutput.hxx @@ -84,6 +84,8 @@ public: virtual void FieldVanish( const OUString& rText, ww::eField eType ) override; + virtual void GenerateBookmarksForSequenceField(const SwTextNode& /*rNode*/, SwWW8AttrIter& /*rAttrIter*/) override {}; + /// Output redlining. virtual void Redline( const SwRedlineData* pRedline ) override; |