summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/docxexport.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/ww8/docxexport.cxx')
-rw-r--r--sw/source/filter/ww8/docxexport.cxx812
1 files changed, 812 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
new file mode 100644
index 000000000000..6ad8d6fb6306
--- /dev/null
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -0,0 +1,812 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "docxexport.hxx"
+#include "docxexportfilter.hxx"
+
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/i18n/ScriptType.hdl>
+
+#include <oox/core/tokens.hxx>
+#include <oox/export/drawingml.hxx>
+#include <oox/export/vmlexport.hxx>
+
+#include <map>
+#include <algorithm>
+
+#include <IMark.hxx>
+#include <docsh.hxx>
+#include <ndtxt.hxx>
+#include <wrtww8.hxx>
+#include <fltini.hxx>
+#include <fmtline.hxx>
+#include <fmtpdsc.hxx>
+#include <frmfmt.hxx>
+#include <section.hxx>
+
+#include <docary.hxx>
+#include <numrule.hxx>
+#include <charfmt.hxx>
+
+#include "ww8par.hxx"
+#include "ww8scan.hxx"
+
+#include <comphelper/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/font.hxx>
+
+using namespace ::comphelper;
+using namespace ::com::sun::star;
+
+using oox::vml::VMLExport;
+
+using rtl::OUString;
+using rtl::OUStringBuffer;
+
+using sw::mark::IMark;
+
+#define S( x ) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
+
+AttributeOutputBase& DocxExport::AttrOutput() const
+{
+ return *m_pAttrOutput;
+}
+
+MSWordSections& DocxExport::Sections() const
+{
+ return *m_pSections;
+}
+
+bool DocxExport::CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich )
+{
+ // TODO FIXME is this actually true for docx? - this is ~copied from WW8
+ if ( nScript == i18n::ScriptType::ASIAN )
+ {
+ // for asian in ww8, there is only one fontsize
+ // and one fontstyle (posture/weight)
+ switch ( nWhich )
+ {
+ case RES_CHRATR_FONTSIZE:
+ case RES_CHRATR_POSTURE:
+ case RES_CHRATR_WEIGHT:
+ return false;
+ default:
+ break;
+ }
+ }
+ else if ( nScript != i18n::ScriptType::COMPLEX )
+ {
+ // for western in ww8, there is only one fontsize
+ // and one fontstyle (posture/weight)
+ switch ( nWhich )
+ {
+ case RES_CHRATR_CJK_FONTSIZE:
+ case RES_CHRATR_CJK_POSTURE:
+ case RES_CHRATR_CJK_WEIGHT:
+ return false;
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
+bool DocxExport::GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt,
+ xub_StrLen nEnd, IMarkVector& rArr )
+{
+ IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
+ ULONG nNd = rNd.GetIndex( );
+
+ const sal_Int32 nMarks = pMarkAccess->getMarksCount();
+ for ( sal_Int32 i = 0; i < nMarks; i++ )
+ {
+ IMark* pMark = ( pMarkAccess->getMarksBegin() + i )->get();
+
+ // Only keep the bookmarks starting or ending in this node
+ if ( pMark->GetMarkStart().nNode == nNd ||
+ pMark->GetMarkEnd().nNode == nNd )
+ {
+ xub_StrLen nBStart = pMark->GetMarkStart().nContent.GetIndex();
+ xub_StrLen nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+ // Keep only the bookmars starting or ending in the snippet
+ bool bIsStartOk = ( nBStart >= nStt ) && ( nBStart <= nEnd );
+ bool bIsEndOk = ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
+
+ if ( bIsStartOk || bIsEndOk )
+ rArr.push_back( pMark );
+ }
+ }
+ return ( rArr.size() > 0 );
+}
+
+class CompareMarksEnd : public std::binary_function < const IMark *, const IMark *, bool >
+{
+public:
+ inline bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
+ {
+ xub_StrLen nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
+ xub_StrLen nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
+
+ return nOEnd < nTEnd;
+ }
+};
+
+bool DocxExport::NearestBookmark( xub_StrLen& rNearest )
+{
+ bool bHasBookmark = false;
+
+ if ( m_rSortedMarksStart.size( ) > 0 )
+ {
+ IMark* pMarkStart = m_rSortedMarksStart.front();
+ rNearest = pMarkStart->GetMarkStart().nContent.GetIndex();
+ bHasBookmark = true;
+ }
+
+ if ( m_rSortedMarksEnd.size( ) > 0 )
+ {
+ IMark* pMarkEnd = m_rSortedMarksEnd[0];
+ if ( !bHasBookmark )
+ rNearest = pMarkEnd->GetMarkEnd().nContent.GetIndex();
+ else
+ rNearest = std::min( rNearest, pMarkEnd->GetMarkEnd().nContent.GetIndex() );
+ bHasBookmark = true;
+ }
+
+ return bHasBookmark;
+}
+
+xub_StrLen DocxExport::GetNextPos( SwAttrIter* pAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos )
+{
+ // Get the bookmarks for the normal run
+ xub_StrLen nNextPos = MSWordExportBase::GetNextPos( pAttrIter, rNode, nAktPos );
+
+ GetSortedBookmarks( rNode, nAktPos, nNextPos - nAktPos );
+
+ xub_StrLen nNextBookmark = nNextPos;
+ NearestBookmark( nNextPos );
+
+ return std::min( nNextPos, nNextBookmark );
+}
+
+void DocxExport::UpdatePosition( SwAttrIter* pAttrIter, xub_StrLen nAktPos, xub_StrLen nEnd )
+{
+ xub_StrLen nNextPos;
+
+ // either no bookmark, or it is not at the current position
+ if ( !NearestBookmark( nNextPos ) || nNextPos > nAktPos )
+ {
+ MSWordExportBase::UpdatePosition( pAttrIter, nAktPos, nEnd );
+ }
+}
+
+void DocxExport::GetSortedBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
+{
+ IMarkVector aMarksStart;
+ if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) )
+ {
+ IMarkVector aSortedEnd;
+ IMarkVector aSortedStart;
+ for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = aMarksStart.end();
+ it < end; ++it )
+ {
+ IMark* pMark = (*it);
+
+ // Remove the positions egals to the current pos
+ xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
+ xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+ if ( nStart > nAktPos )
+ aSortedStart.push_back( pMark );
+
+ if ( nEnd > nAktPos )
+ aSortedEnd.push_back( pMark );
+ }
+
+ // Sort the bookmarks by end position
+ std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
+
+ m_rSortedMarksStart.swap( aSortedStart );
+ m_rSortedMarksEnd.swap( aSortedEnd );
+ }
+ else
+ {
+ m_rSortedMarksStart.clear( );
+ m_rSortedMarksEnd.clear( );
+ }
+}
+
+void DocxExport::AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
+{
+ std::vector< OUString > aStarts;
+ std::vector< OUString > aEnds;
+
+ IMarkVector aMarks;
+ if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
+ {
+ for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
+ it < end; ++it )
+ {
+ IMark* pMark = (*it);
+
+ xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
+ xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+ if ( nStart == nAktPos )
+ aStarts.push_back( pMark->GetName() );
+
+ if ( nEnd == nAktPos )
+ aEnds.push_back( pMark->GetName() );
+ }
+ }
+
+ m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
+}
+
+void DocxExport::AppendBookmark( const OUString& rName, bool /*bSkip*/ )
+{
+ std::vector< OUString > aStarts;
+ std::vector< OUString > aEnds;
+
+ aStarts.push_back( rName );
+ aEnds.push_back( rName );
+
+ m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
+}
+
+::rtl::OString DocxExport::AddRelation( const OUString& rType, const OUString& rTarget, const OUString& rMode )
+{
+ OUString sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ rType, rTarget, rMode );
+
+ return ::rtl::OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
+}
+
+bool DocxExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
+{
+ bool bRet( false );
+
+ if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
+ {
+ if (const SwFmt *pParent = rFmt.DerivedFrom())
+ {
+ if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
+ {
+ ::sax_fastparser::FSHelperPtr pSerializer = m_pAttrOutput->GetSerializer( );
+ // Level 9 disables the outline
+ pSerializer->singleElementNS( XML_w, XML_outlineLvl,
+ FSNS( XML_w, XML_val ), "9" ,
+ FSEND );
+
+ bRet = true;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+void DocxExport::WriteHeadersFooters( BYTE nHeadFootFlags,
+ const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt )
+{
+ // headers
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
+ WriteHeaderFooter( rLeftFmt, true, "even" );
+
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
+ WriteHeaderFooter( rFmt, true, "default" );
+
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
+ WriteHeaderFooter( rFirstPageFmt, true, "first" );
+
+ // footers
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
+ WriteHeaderFooter( rLeftFmt, false, "even" );
+
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
+ WriteHeaderFooter( rFmt, false, "default" );
+
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
+ WriteHeaderFooter( rFirstPageFmt, false, "first" );
+}
+
+void DocxExport::OutputField( const SwField* pFld, ww::eField eFldType, const String& rFldCmd, BYTE nMode )
+{
+ m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode );
+}
+
+void DocxExport::WriteFormData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
+{
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO DocxExport::WriteFormData()\n" );
+#endif
+}
+
+void DocxExport::DoComboBox(const rtl::OUString& rName,
+ const rtl::OUString& rHelp,
+ const rtl::OUString& rToolTip,
+ const rtl::OUString& rSelected,
+ uno::Sequence<rtl::OUString>& rListItems)
+{
+ m_pDocumentFS->startElementNS( XML_w, XML_ffData, FSEND );
+
+ m_pDocumentFS->singleElementNS( XML_w, XML_name,
+ FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
+ FSEND );
+
+ m_pDocumentFS->singleElementNS( XML_w, XML_enabled, FSEND );
+
+ if ( rHelp.getLength( ) > 0 )
+ m_pDocumentFS->singleElementNS( XML_w, XML_helpText,
+ FSNS( XML_w, XML_val ), OUStringToOString( rHelp, RTL_TEXTENCODING_UTF8 ).getStr(),
+ FSEND );
+
+ if ( rToolTip.getLength( ) > 0 )
+ m_pDocumentFS->singleElementNS( XML_w, XML_statusText,
+ FSNS( XML_w, XML_val ), OUStringToOString( rToolTip, RTL_TEXTENCODING_UTF8 ).getStr(),
+ FSEND );
+
+ m_pDocumentFS->startElementNS( XML_w, XML_ddList, FSEND );
+
+ // Output the 0-based index of the selected value
+ sal_uInt32 nListItems = rListItems.getLength();
+ sal_Int32 nId = 0;
+ sal_uInt32 nI = 0;
+ while ( ( nI < nListItems ) && ( nId == 0 ) )
+ {
+ if ( rListItems[nI] == rSelected )
+ nId = nI;
+ nI++;
+ }
+
+ m_pDocumentFS->singleElementNS( XML_w, XML_result,
+ FSNS( XML_w, XML_val ), rtl::OString::valueOf( nId ).getStr( ),
+ FSEND );
+
+ // Loop over the entries
+
+ for (sal_uInt32 i = 0; i < nListItems; i++)
+ {
+ m_pDocumentFS->singleElementNS( XML_w, XML_listEntry,
+ FSNS( XML_w, XML_val ), OUStringToOString( rListItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
+ FSEND );
+ }
+
+ m_pDocumentFS->endElementNS( XML_w, XML_ddList );
+
+ m_pDocumentFS->endElementNS( XML_w, XML_ffData );
+}
+
+void DocxExport::DoFormText(const SwInputField* /*pFld*/)
+{
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO DocxExport::ForFormText()\n" );
+#endif
+}
+
+void DocxExport::ExportDocument_Impl()
+{
+ InitStyles();
+
+ // init sections
+ m_pSections = new MSWordSections( *this );
+
+ WriteMainText();
+
+ WriteFootnotesEndnotes();
+
+ WriteNumbering();
+
+ WriteFonts();
+
+ delete pStyles, pStyles = NULL;
+ delete m_pSections, m_pSections = NULL;
+}
+
+void DocxExport::OutputPageSectionBreaks( const SwTxtNode& )
+{
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO DocxExport::OutputPageSectionBreaks( const SwTxtNode& )\n" );
+#endif
+}
+
+
+void DocxExport::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum )
+{
+ AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
+ m_pSections->AppendSep( pPageDesc, pFmt, nLnNum );
+}
+
+void DocxExport::OutputEndNode( const SwEndNode& rEndNode )
+{
+ MSWordExportBase::OutputEndNode( rEndNode );
+
+ if ( TXT_MAINTEXT == nTxtTyp && rEndNode.StartOfSectionNode()->IsSectionNode() )
+ {
+ // this originally comes from WW8Export::WriteText(), and looks like it
+ // could have some code common with SectionNode()...
+
+ const SwSection& rSect = rEndNode.StartOfSectionNode()->GetSectionNode()->GetSection();
+ if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
+ bStartTOX = false;
+
+ SwNodeIndex aIdx( rEndNode, 1 );
+ const SwNode& rNd = aIdx.GetNode();
+ if ( rNd.IsEndNode() && rNd.StartOfSectionNode()->IsSectionNode() )
+ return;
+
+ if ( !rNd.IsSectionNode() && !bIsInTable ) // No sections in table
+ {
+ const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent();
+ if( !pParentFmt )
+ pParentFmt = (SwSectionFmt*)0xFFFFFFFF;
+
+ ULONG nRstLnNum;
+ if( rNd.IsCntntNode() )
+ nRstLnNum = const_cast< SwCntntNode* >( rNd.GetCntntNode() )->GetSwAttrSet().GetLineNumber().GetStartValue();
+ else
+ nRstLnNum = 0;
+
+ AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo( ) );
+ m_pSections->AppendSep( pAktPageDesc, pParentFmt, nRstLnNum );
+ }
+ }
+}
+
+void DocxExport::OutputTableNode( const SwTableNode& )
+{
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO DocxExport::OutputTableNode( const SwTableNode& )\n" );
+#endif
+}
+
+void DocxExport::OutputGrfNode( const SwGrfNode& )
+{
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO DocxExport::OutputGrfNode( const SwGrfNode& )\n" );
+#endif
+}
+
+void DocxExport::OutputOLENode( const SwOLENode& )
+{
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO DocxExport::OutputOLENode( const SwOLENode& )\n" );
+#endif
+}
+
+ULONG DocxExport::ReplaceCr( BYTE )
+{
+ // Completely unused for Docx export... only here for code sharing
+ // purpose with binary export
+ return 0;
+}
+
+void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet,
+ const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt,
+ const SwPageDesc* pNewPgDesc )
+{
+ // tell the attribute output that we are ready to write the section
+ // break [has to be output inside paragraph properties]
+ AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
+
+ const SwSectionFmt* pFmt = GetSectionFormat( rNd );
+ const ULONG nLnNm = GetSectionLineNo( pSet, rNd );
+
+ ASSERT( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
+
+ if ( pNewPgDescFmt )
+ {
+ m_pSections->AppendSep( *pNewPgDescFmt, rNd, pFmt, nLnNm );
+ }
+ else if ( pNewPgDesc )
+ {
+ m_pSections->AppendSep( pNewPgDesc, rNd, pFmt, nLnNm );
+ }
+
+}
+
+void DocxExport::InitStyles()
+{
+ pStyles = new MSWordStyles( *this );
+
+ // setup word/styles.xml and the relations + content type
+ m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" ),
+ S( "styles.xml" ) );
+
+ ::sax_fastparser::FSHelperPtr pStylesFS =
+ m_pFilter->openOutputStreamWithSerializer( S( "word/styles.xml" ),
+ S( "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" ) );
+
+ // switch the serializer to redirect the output to word/styles.xml
+ m_pAttrOutput->SetSerializer( pStylesFS );
+
+ // do the work
+ pStyles->OutputStylesTable();
+
+ // switch the serializer back
+ m_pAttrOutput->SetSerializer( m_pDocumentFS );
+}
+
+void DocxExport::WriteFootnotesEndnotes()
+{
+ if ( m_pAttrOutput->HasFootnotes() )
+ {
+ // setup word/styles.xml and the relations + content type
+ m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" ),
+ S( "footnotes.xml" ) );
+
+ ::sax_fastparser::FSHelperPtr pFootnotesFS =
+ m_pFilter->openOutputStreamWithSerializer( S( "word/footnotes.xml" ),
+ S( "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" ) );
+
+ // switch the serializer to redirect the output to word/footnotes.xml
+ m_pAttrOutput->SetSerializer( pFootnotesFS );
+
+ // do the work
+ m_pAttrOutput->FootnotesEndnotes( true );
+
+ // switch the serializer back
+ m_pAttrOutput->SetSerializer( m_pDocumentFS );
+ }
+
+ if ( m_pAttrOutput->HasEndnotes() )
+ {
+ // setup word/styles.xml and the relations + content type
+ m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" ),
+ S( "endnotes.xml" ) );
+
+ ::sax_fastparser::FSHelperPtr pEndnotesFS =
+ m_pFilter->openOutputStreamWithSerializer( S( "word/endnotes.xml" ),
+ S( "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" ) );
+
+ // switch the serializer to redirect the output to word/endnotes.xml
+ m_pAttrOutput->SetSerializer( pEndnotesFS );
+
+ // do the work
+ m_pAttrOutput->FootnotesEndnotes( false );
+
+ // switch the serializer back
+ m_pAttrOutput->SetSerializer( m_pDocumentFS );
+ }
+}
+
+void DocxExport::WriteNumbering()
+{
+ if ( !pUsedNumTbl )
+ return; // no numbering is used
+
+ m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" ),
+ S( "numbering.xml" ) );
+
+ ::sax_fastparser::FSHelperPtr pNumberingFS = m_pFilter->openOutputStreamWithSerializer( S( "word/numbering.xml" ),
+ S( "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" ) );
+
+ // switch the serializer to redirect the output to word/nubering.xml
+ m_pAttrOutput->SetSerializer( pNumberingFS );
+
+ pNumberingFS->startElementNS( XML_w, XML_numbering,
+ FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
+ FSEND );
+
+ AbstractNumberingDefinitions();
+
+ NumberingDefinitions();
+
+ pNumberingFS->endElementNS( XML_w, XML_numbering );
+
+ // switch the serializer back
+ m_pAttrOutput->SetSerializer( m_pDocumentFS );
+}
+
+void DocxExport::WriteHeaderFooter( const SwFmt& rFmt, bool bHeader, const char* pType )
+{
+ // setup the xml stream
+ OUString aRelId;
+ ::sax_fastparser::FSHelperPtr pFS;
+ if ( bHeader )
+ {
+ OUString aName( OUStringBuffer().appendAscii( "header" ).append( ++m_nHeaders ).appendAscii( ".xml" ).makeStringAndClear() );
+
+ aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" ),
+ aName );
+
+ pFS = m_pFilter->openOutputStreamWithSerializer( OUStringBuffer().appendAscii( "word/" ).append( aName ).makeStringAndClear(),
+ S( "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" ) );
+
+ pFS->startElementNS( XML_w, XML_hdr,
+ FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
+ FSEND );
+ }
+ else
+ {
+ OUString aName( OUStringBuffer().appendAscii( "footer" ).append( ++m_nFooters ).appendAscii( ".xml" ).makeStringAndClear() );
+
+ aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" ),
+ aName );
+
+ pFS = m_pFilter->openOutputStreamWithSerializer( OUStringBuffer().appendAscii( "word/" ).append( aName ).makeStringAndClear(),
+ S( "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" ) );
+
+ pFS->startElementNS( XML_w, XML_ftr,
+ FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
+ FSEND );
+ }
+
+ // switch the serializer to redirect the output to word/styles.xml
+ m_pAttrOutput->SetSerializer( pFS );
+
+ // do the work
+ WriteHeaderFooterText( rFmt, bHeader );
+
+ // switch the serializer back
+ m_pAttrOutput->SetSerializer( m_pDocumentFS );
+
+ // close the tag
+ sal_Int32 nReference;
+ if ( bHeader )
+ {
+ pFS->endElementNS( XML_w, XML_hdr );
+ nReference = XML_headerReference;
+ }
+ else
+ {
+ pFS->endElementNS( XML_w, XML_ftr );
+ nReference = XML_footerReference;
+ }
+
+ // and write the reference
+ m_pDocumentFS->singleElementNS( XML_w, nReference,
+ FSNS( XML_w, XML_type ), pType,
+ FSNS( XML_r, XML_id ), rtl::OUStringToOString( aRelId, RTL_TEXTENCODING_UTF8 ).getStr(),
+ FSEND );
+}
+
+void DocxExport::WriteFonts()
+{
+ m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" ),
+ S( "fontTable.xml" ) );
+
+ ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openOutputStreamWithSerializer(
+ S( "word/fontTable.xml" ),
+ S( "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" ) );
+
+ pFS->startElementNS( XML_w, XML_fonts,
+ FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
+ FSEND );
+
+ // switch the serializer to redirect the output to word/styles.xml
+ m_pAttrOutput->SetSerializer( pFS );
+
+ // do the work
+ maFontHelper.WriteFontTable( *m_pAttrOutput );
+
+ // switch the serializer back
+ m_pAttrOutput->SetSerializer( m_pDocumentFS );
+
+ pFS->endElementNS( XML_w, XML_fonts );
+}
+
+
+void DocxExport::WriteProperties( )
+{
+ // Write the core properties
+ SwDocShell* pDocShell( pDoc->GetDocShell( ) );
+ uno::Reference<document::XDocumentProperties> xDocProps;
+ if ( pDocShell )
+ {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel( ), uno::UNO_QUERY );
+ xDocProps = xDPS->getDocumentProperties();
+ }
+
+ m_pFilter->exportDocumentProperties( xDocProps );
+}
+
+VMLExport& DocxExport::VMLExporter()
+{
+ return *m_pVMLExport;
+}
+
+void DocxExport::WriteMainText()
+{
+ // setup the namespaces
+ m_pDocumentFS->startElementNS( XML_w, XML_document,
+ FSNS( XML_xmlns, XML_o ), "urn:schemas-microsoft-com:office:office",
+ FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ FSNS( XML_xmlns, XML_v ), "urn:schemas-microsoft-com:vml",
+ FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
+ FSNS( XML_xmlns, XML_w10 ), "urn:schemas-microsoft-com:office:word",
+ FSNS( XML_xmlns, XML_wp ), "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
+ FSEND );
+
+ // body
+ m_pDocumentFS->startElementNS( XML_w, XML_body, FSEND );
+
+ pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
+
+ // the text
+ WriteText();
+
+ // the last section info
+ const WW8_SepInfo *pSectionInfo = m_pSections? m_pSections->CurrentSectionInfo(): NULL;
+ if ( pSectionInfo )
+ SectionProperties( *pSectionInfo );
+
+ // finish body and document
+ m_pDocumentFS->endElementNS( XML_w, XML_body );
+ m_pDocumentFS->endElementNS( XML_w, XML_document );
+}
+
+DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam )
+ : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
+ m_pFilter( pFilter ),
+ m_pAttrOutput( NULL ),
+ m_pSections( NULL ),
+ m_nHeaders( 0 ),
+ m_nFooters( 0 ),
+ m_pVMLExport( NULL )
+{
+ // Write the document properies
+ WriteProperties( );
+
+ // relations for the document
+ m_pFilter->addRelation( S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ),
+ S( "word/document.xml" ) );
+
+ // the actual document
+ m_pDocumentFS = m_pFilter->openOutputStreamWithSerializer( S( "word/document.xml" ),
+ S( "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" ) );
+
+ // the DrawingML access
+ m_pDrawingML = new oox::drawingml::DrawingML( m_pDocumentFS, m_pFilter, oox::drawingml::DrawingML::DOCUMENT_DOCX );
+
+ // the attribute output for the document
+ m_pAttrOutput = new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML );
+
+ // the related VMLExport
+ m_pVMLExport = new VMLExport( m_pDocumentFS );
+}
+
+DocxExport::~DocxExport()
+{
+ delete m_pVMLExport, m_pVMLExport = NULL;
+ delete m_pAttrOutput, m_pAttrOutput = NULL;
+ delete m_pDrawingML, m_pDrawingML = NULL;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */