xref: /aoo4110/main/sw/source/filter/ww8/docxexport.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "docxexport.hxx"
25 #include "docxexportfilter.hxx"
26 
27 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
28 #include <com/sun/star/document/XDocumentProperties.hpp>
29 #include <com/sun/star/i18n/ScriptType.hdl>
30 
31 #include <oox/token/tokens.hxx>
32 #include <oox/export/drawingml.hxx>
33 #include <oox/export/vmlexport.hxx>
34 
35 #include <map>
36 #include <algorithm>
37 
38 #include <IMark.hxx>
39 #include <docsh.hxx>
40 #include <ndtxt.hxx>
41 #include <wrtww8.hxx>
42 #include <fltini.hxx>
43 #include <fmtline.hxx>
44 #include <fmtpdsc.hxx>
45 #include <frmfmt.hxx>
46 #include <section.hxx>
47 
48 #include <docary.hxx>
49 #include <numrule.hxx>
50 #include <charfmt.hxx>
51 
52 #include "ww8par.hxx"
53 #include "ww8scan.hxx"
54 
55 #include <comphelper/string.hxx>
56 #include <rtl/ustrbuf.hxx>
57 #include <vcl/font.hxx>
58 
59 using namespace ::comphelper;
60 using namespace ::com::sun::star;
61 using namespace ::oox;
62 
63 using oox::vml::VMLExport;
64 
65 using rtl::OUString;
66 using rtl::OUStringBuffer;
67 
68 using sw::mark::IMark;
69 
70 #define S( x ) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
71 
AttrOutput() const72 AttributeOutputBase& DocxExport::AttrOutput() const
73 {
74     return *m_pAttrOutput;
75 }
76 
Sections() const77 MSWordSections& DocxExport::Sections() const
78 {
79     return *m_pSections;
80 }
81 
CollapseScriptsforWordOk(sal_uInt16 nScript,sal_uInt16 nWhich)82 bool DocxExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
83 {
84     // TODO FIXME is this actually true for docx? - this is ~copied from WW8
85     if ( nScript == i18n::ScriptType::ASIAN )
86     {
87         // for asian in ww8, there is only one fontsize
88         // and one fontstyle (posture/weight)
89         switch ( nWhich )
90         {
91             case RES_CHRATR_FONTSIZE:
92             case RES_CHRATR_POSTURE:
93             case RES_CHRATR_WEIGHT:
94                 return false;
95             default:
96                 break;
97         }
98     }
99     else if ( nScript != i18n::ScriptType::COMPLEX )
100     {
101         // for western in ww8, there is only one fontsize
102         // and one fontstyle (posture/weight)
103         switch ( nWhich )
104         {
105             case RES_CHRATR_CJK_FONTSIZE:
106             case RES_CHRATR_CJK_POSTURE:
107             case RES_CHRATR_CJK_WEIGHT:
108                 return false;
109             default:
110                 break;
111         }
112     }
113     return true;
114 }
115 
AppendBookmarks(const SwTxtNode & rNode,xub_StrLen nAktPos,xub_StrLen nLen)116 void DocxExport::AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
117 {
118     std::vector< OUString > aStarts;
119     std::vector< OUString > aEnds;
120 
121     IMarkVector aMarks;
122     if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
123     {
124         for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
125               it < end; ++it )
126         {
127             IMark* pMark = (*it);
128 
129             xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
130             xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
131 
132             if ( nStart == nAktPos )
133                 aStarts.push_back( pMark->GetName() );
134 
135             if ( nEnd == nAktPos )
136                 aEnds.push_back( pMark->GetName() );
137         }
138     }
139 
140     m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
141 }
142 
AppendBookmark(const OUString & rName,bool)143 void DocxExport::AppendBookmark( const OUString& rName, bool /*bSkip*/ )
144 {
145     std::vector< OUString > aStarts;
146     std::vector< OUString > aEnds;
147 
148     aStarts.push_back( rName );
149     aEnds.push_back( rName );
150 
151     m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
152 }
153 
AddRelation(const OUString & rType,const OUString & rTarget,const OUString & rMode)154 ::rtl::OString DocxExport::AddRelation( const OUString& rType, const OUString& rTarget, const OUString& rMode )
155 {
156     OUString sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
157            rType, rTarget, rMode );
158 
159     return ::rtl::OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
160 }
161 
DisallowInheritingOutlineNumbering(const SwFmt & rFmt)162 bool DocxExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
163 {
164     bool bRet( false );
165 
166     if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
167     {
168         if (const SwFmt *pParent = rFmt.DerivedFrom())
169         {
170 			if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
171             {
172                 ::sax_fastparser::FSHelperPtr pSerializer = m_pAttrOutput->GetSerializer( );
173                 // Level 9 disables the outline
174                 pSerializer->singleElementNS( XML_w, XML_outlineLvl,
175                         FSNS( XML_w, XML_val ), "9" ,
176                         FSEND );
177 
178                 bRet = true;
179             }
180         }
181     }
182 
183     return bRet;
184 }
185 
WriteHeadersFooters(sal_uInt8 nHeadFootFlags,const SwFrmFmt & rFmt,const SwFrmFmt & rLeftFmt,const SwFrmFmt & rFirstPageFmt)186 void DocxExport::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
187         const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt )
188 {
189     // headers
190     if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
191         WriteHeaderFooter( rLeftFmt, true, "even" );
192 
193     if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
194         WriteHeaderFooter( rFmt, true, "default" );
195 
196     if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
197         WriteHeaderFooter( rFirstPageFmt, true, "first" );
198 
199     // footers
200     if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
201         WriteHeaderFooter( rLeftFmt, false, "even" );
202 
203     if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
204         WriteHeaderFooter( rFmt, false, "default" );
205 
206     if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
207         WriteHeaderFooter( rFirstPageFmt, false, "first" );
208 }
209 
OutputField(const SwField * pFld,ww::eField eFldType,const String & rFldCmd,sal_uInt8 nMode)210 void DocxExport::OutputField( const SwField* pFld, ww::eField eFldType, const String& rFldCmd, sal_uInt8 nMode )
211 {
212     m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode );
213 }
214 
WriteFormData(const::sw::mark::IFieldmark &)215 void DocxExport::WriteFormData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
216 {
217     OSL_TRACE( "TODO DocxExport::WriteFormData()\n" );
218 }
219 
DoComboBox(const rtl::OUString & rName,const rtl::OUString & rHelp,const rtl::OUString & rToolTip,const rtl::OUString & rSelected,uno::Sequence<rtl::OUString> & rListItems)220 void DocxExport::DoComboBox(const rtl::OUString& rName,
221                              const rtl::OUString& rHelp,
222                              const rtl::OUString& rToolTip,
223                              const rtl::OUString& rSelected,
224                              uno::Sequence<rtl::OUString>& rListItems)
225 {
226     m_pDocumentFS->startElementNS( XML_w, XML_ffData, FSEND );
227 
228     m_pDocumentFS->singleElementNS( XML_w, XML_name,
229             FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
230             FSEND );
231 
232     m_pDocumentFS->singleElementNS( XML_w, XML_enabled, FSEND );
233 
234     if ( rHelp.getLength( ) > 0 )
235         m_pDocumentFS->singleElementNS( XML_w, XML_helpText,
236             FSNS( XML_w, XML_val ), OUStringToOString( rHelp, RTL_TEXTENCODING_UTF8 ).getStr(),
237             FSEND );
238 
239     if ( rToolTip.getLength( ) > 0 )
240         m_pDocumentFS->singleElementNS( XML_w, XML_statusText,
241             FSNS( XML_w, XML_val ), OUStringToOString( rToolTip, RTL_TEXTENCODING_UTF8 ).getStr(),
242             FSEND );
243 
244     m_pDocumentFS->startElementNS( XML_w, XML_ddList, FSEND );
245 
246     // Output the 0-based index of the selected value
247     sal_uInt32 nListItems = rListItems.getLength();
248     sal_Int32 nId = 0;
249     sal_uInt32 nI = 0;
250     while ( ( nI < nListItems ) && ( nId == 0 ) )
251     {
252         if ( rListItems[nI] == rSelected )
253             nId = nI;
254         nI++;
255     }
256 
257     m_pDocumentFS->singleElementNS( XML_w, XML_result,
258             FSNS( XML_w, XML_val ), rtl::OString::valueOf( nId ).getStr( ),
259             FSEND );
260 
261     // Loop over the entries
262 
263     for (sal_uInt32 i = 0; i < nListItems; i++)
264     {
265         m_pDocumentFS->singleElementNS( XML_w, XML_listEntry,
266                 FSNS( XML_w, XML_val ), OUStringToOString( rListItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
267                FSEND );
268     }
269 
270     m_pDocumentFS->endElementNS( XML_w, XML_ddList );
271 
272     m_pDocumentFS->endElementNS( XML_w, XML_ffData );
273 }
274 
DoFormText(const SwInputField *)275 void DocxExport::DoFormText(const SwInputField* /*pFld*/)
276 {
277     OSL_TRACE( "TODO DocxExport::ForFormText()\n" );
278 }
279 
ExportDocument_Impl()280 void DocxExport::ExportDocument_Impl()
281 {
282     InitStyles();
283 
284     // init sections
285     m_pSections = new MSWordSections( *this );
286 
287     WriteMainText();
288 
289     WriteFootnotesEndnotes();
290 
291     WriteNumbering();
292 
293     WriteFonts();
294 
295     delete pStyles, pStyles = NULL;
296     delete m_pSections, m_pSections = NULL;
297 }
298 
OutputPageSectionBreaks(const SwTxtNode &)299 void DocxExport::OutputPageSectionBreaks( const SwTxtNode& )
300 {
301     OSL_TRACE( "TODO DocxExport::OutputPageSectionBreaks( const SwTxtNode& )\n" );
302 }
303 
304 
AppendSection(const SwPageDesc * pPageDesc,const SwSectionFmt * pFmt,sal_uLong nLnNum)305 void DocxExport::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, sal_uLong nLnNum )
306 {
307     AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
308     m_pSections->AppendSection( pPageDesc, pFmt, nLnNum );
309 }
310 
OutputEndNode(const SwEndNode & rEndNode)311 void DocxExport::OutputEndNode( const SwEndNode& rEndNode )
312 {
313     MSWordExportBase::OutputEndNode( rEndNode );
314 
315     if ( TXT_MAINTEXT == nTxtTyp && rEndNode.StartOfSectionNode()->IsSectionNode() )
316     {
317         // this originally comes from WW8Export::WriteText(), and looks like it
318         // could have some code common with SectionNode()...
319 
320         const SwSection& rSect = rEndNode.StartOfSectionNode()->GetSectionNode()->GetSection();
321         if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
322             bStartTOX = false;
323 
324         SwNodeIndex aIdx( rEndNode, 1 );
325         const SwNode& rNd = aIdx.GetNode();
326         if ( rNd.IsEndNode() && rNd.StartOfSectionNode()->IsSectionNode() )
327             return;
328 
329         if ( !rNd.IsSectionNode() && !bIsInTable ) // No sections in table
330         {
331             const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent();
332             if( !pParentFmt )
333                 pParentFmt = (SwSectionFmt*)0xFFFFFFFF;
334 
335             sal_uLong nRstLnNum;
336             if( rNd.IsCntntNode() )
337                 nRstLnNum = const_cast< SwCntntNode* >( rNd.GetCntntNode() )->GetSwAttrSet().GetLineNumber().GetStartValue();
338             else
339                 nRstLnNum = 0;
340 
341             AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo( ) );
342             m_pSections->AppendSection( pAktPageDesc, pParentFmt, nRstLnNum );
343         }
344     }
345 }
346 
OutputTableNode(const SwTableNode &)347 void DocxExport::OutputTableNode( const SwTableNode& )
348 {
349     OSL_TRACE( "TODO DocxExport::OutputTableNode( const SwTableNode& )\n" );
350 }
351 
OutputGrfNode(const SwGrfNode &)352 void DocxExport::OutputGrfNode( const SwGrfNode& )
353 {
354     OSL_TRACE( "TODO DocxExport::OutputGrfNode( const SwGrfNode& )\n" );
355 }
356 
OutputOLENode(const SwOLENode &)357 void DocxExport::OutputOLENode( const SwOLENode& )
358 {
359     OSL_TRACE( "TODO DocxExport::OutputOLENode( const SwOLENode& )\n" );
360 }
361 
ReplaceCr(sal_uInt8)362 sal_uLong DocxExport::ReplaceCr( sal_uInt8 )
363 {
364     // Completely unused for Docx export... only here for code sharing
365     // purpose with binary export
366     return 0;
367 }
368 
PrepareNewPageDesc(const SfxItemSet * pSet,const SwNode & rNd,const SwFmtPageDesc * pNewPgDescFmt,const SwPageDesc * pNewPgDesc)369 void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet,
370         const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt,
371         const SwPageDesc* pNewPgDesc )
372 {
373     // tell the attribute output that we are ready to write the section
374     // break [has to be output inside paragraph properties]
375     AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
376 
377     const SwSectionFmt* pFmt = GetSectionFormat( rNd );
378     const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
379 
380     ASSERT( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
381 
382     if ( pNewPgDescFmt )
383     {
384         m_pSections->AppendSection( *pNewPgDescFmt, rNd, pFmt, nLnNm );
385     }
386     else if ( pNewPgDesc )
387     {
388         m_pSections->AppendSection( pNewPgDesc, rNd, pFmt, nLnNm );
389     }
390 
391 }
392 
InitStyles()393 void DocxExport::InitStyles()
394 {
395     pStyles = new MSWordStyles( *this );
396 
397     // setup word/styles.xml and the relations + content type
398     m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
399             S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" ),
400             S( "styles.xml" ) );
401 
402     ::sax_fastparser::FSHelperPtr pStylesFS =
403         m_pFilter->openOutputStreamWithSerializer( S( "word/styles.xml" ),
404             S( "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" ) );
405 
406     // switch the serializer to redirect the output to word/styles.xml
407     m_pAttrOutput->SetSerializer( pStylesFS );
408 
409     // do the work
410     pStyles->OutputStylesTable();
411 
412     // switch the serializer back
413     m_pAttrOutput->SetSerializer( m_pDocumentFS );
414 }
415 
WriteFootnotesEndnotes()416 void DocxExport::WriteFootnotesEndnotes()
417 {
418     if ( m_pAttrOutput->HasFootnotes() )
419     {
420         // setup word/styles.xml and the relations + content type
421         m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
422                 S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" ),
423                 S( "footnotes.xml" ) );
424 
425         ::sax_fastparser::FSHelperPtr pFootnotesFS =
426             m_pFilter->openOutputStreamWithSerializer( S( "word/footnotes.xml" ),
427                     S( "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" ) );
428 
429         // switch the serializer to redirect the output to word/footnotes.xml
430         m_pAttrOutput->SetSerializer( pFootnotesFS );
431 
432         // do the work
433         m_pAttrOutput->FootnotesEndnotes( true );
434 
435         // switch the serializer back
436         m_pAttrOutput->SetSerializer( m_pDocumentFS );
437     }
438 
439     if ( m_pAttrOutput->HasEndnotes() )
440     {
441         // setup word/styles.xml and the relations + content type
442         m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
443                 S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" ),
444                 S( "endnotes.xml" ) );
445 
446         ::sax_fastparser::FSHelperPtr pEndnotesFS =
447             m_pFilter->openOutputStreamWithSerializer( S( "word/endnotes.xml" ),
448                     S( "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" ) );
449 
450         // switch the serializer to redirect the output to word/endnotes.xml
451         m_pAttrOutput->SetSerializer( pEndnotesFS );
452 
453         // do the work
454         m_pAttrOutput->FootnotesEndnotes( false );
455 
456         // switch the serializer back
457         m_pAttrOutput->SetSerializer( m_pDocumentFS );
458     }
459 }
460 
WriteNumbering()461 void DocxExport::WriteNumbering()
462 {
463     if ( !pUsedNumTbl )
464         return; // no numbering is used
465 
466     m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
467         S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" ),
468         S( "numbering.xml" ) );
469 
470     ::sax_fastparser::FSHelperPtr pNumberingFS = m_pFilter->openOutputStreamWithSerializer( S( "word/numbering.xml" ),
471         S( "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" ) );
472 
473     // switch the serializer to redirect the output to word/nubering.xml
474     m_pAttrOutput->SetSerializer( pNumberingFS );
475 
476     pNumberingFS->startElementNS( XML_w, XML_numbering,
477             FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
478             FSEND );
479 
480     AbstractNumberingDefinitions();
481 
482     NumberingDefinitions();
483 
484     pNumberingFS->endElementNS( XML_w, XML_numbering );
485 
486     // switch the serializer back
487     m_pAttrOutput->SetSerializer( m_pDocumentFS );
488 }
489 
WriteHeaderFooter(const SwFmt & rFmt,bool bHeader,const char * pType)490 void DocxExport::WriteHeaderFooter( const SwFmt& rFmt, bool bHeader, const char* pType )
491 {
492     // setup the xml stream
493     OUString aRelId;
494     ::sax_fastparser::FSHelperPtr pFS;
495     if ( bHeader )
496     {
497         OUString aName( OUStringBuffer().appendAscii( "header" ).append( ++m_nHeaders ).appendAscii( ".xml" ).makeStringAndClear() );
498 
499         aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
500                 S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" ),
501                 aName );
502 
503         pFS = m_pFilter->openOutputStreamWithSerializer( OUStringBuffer().appendAscii( "word/" ).append( aName ).makeStringAndClear(),
504                     S( "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" ) );
505 
506         pFS->startElementNS( XML_w, XML_hdr,
507                 FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
508                 FSEND );
509     }
510     else
511     {
512         OUString aName( OUStringBuffer().appendAscii( "footer" ).append( ++m_nFooters ).appendAscii( ".xml" ).makeStringAndClear() );
513 
514         aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
515                 S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" ),
516                 aName );
517 
518         pFS = m_pFilter->openOutputStreamWithSerializer( OUStringBuffer().appendAscii( "word/" ).append( aName ).makeStringAndClear(),
519                     S( "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" ) );
520 
521         pFS->startElementNS( XML_w, XML_ftr,
522                 FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
523                 FSEND );
524     }
525 
526     // switch the serializer to redirect the output to word/styles.xml
527     m_pAttrOutput->SetSerializer( pFS );
528 
529     // do the work
530     WriteHeaderFooterText( rFmt, bHeader );
531 
532     // switch the serializer back
533     m_pAttrOutput->SetSerializer( m_pDocumentFS );
534 
535     // close the tag
536     sal_Int32 nReference;
537     if ( bHeader )
538     {
539         pFS->endElementNS( XML_w, XML_hdr );
540         nReference = XML_headerReference;
541     }
542     else
543     {
544         pFS->endElementNS( XML_w, XML_ftr );
545         nReference = XML_footerReference;
546     }
547 
548     // and write the reference
549     m_pDocumentFS->singleElementNS( XML_w, nReference,
550             FSNS( XML_w, XML_type ), pType,
551             FSNS( XML_r, XML_id ), rtl::OUStringToOString( aRelId, RTL_TEXTENCODING_UTF8 ).getStr(),
552             FSEND );
553 }
554 
WriteFonts()555 void DocxExport::WriteFonts()
556 {
557     m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
558             S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" ),
559             S( "fontTable.xml" ) );
560 
561     ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openOutputStreamWithSerializer(
562             S( "word/fontTable.xml" ),
563             S( "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" ) );
564 
565     pFS->startElementNS( XML_w, XML_fonts,
566             FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
567             FSEND );
568 
569     // switch the serializer to redirect the output to word/styles.xml
570     m_pAttrOutput->SetSerializer( pFS );
571 
572     // do the work
573     maFontHelper.WriteFontTable( *m_pAttrOutput );
574 
575     // switch the serializer back
576     m_pAttrOutput->SetSerializer( m_pDocumentFS );
577 
578     pFS->endElementNS( XML_w, XML_fonts );
579 }
580 
581 
WriteProperties()582 void DocxExport::WriteProperties( )
583 {
584     // Write the core properties
585     SwDocShell* pDocShell( pDoc->GetDocShell( ) );
586     uno::Reference<document::XDocumentProperties> xDocProps;
587     if ( pDocShell )
588     {
589         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
590                pDocShell->GetModel( ), uno::UNO_QUERY );
591         xDocProps = xDPS->getDocumentProperties();
592     }
593 
594     m_pFilter->exportDocumentProperties( xDocProps );
595 }
596 
VMLExporter()597 VMLExport& DocxExport::VMLExporter()
598 {
599     return *m_pVMLExport;
600 }
601 
WriteMainText()602 void DocxExport::WriteMainText()
603 {
604     // setup the namespaces
605     m_pDocumentFS->startElementNS( XML_w, XML_document,
606             FSNS( XML_xmlns, XML_o ), "urn:schemas-microsoft-com:office:office",
607             FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
608             FSNS( XML_xmlns, XML_v ), "urn:schemas-microsoft-com:vml",
609             FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
610             FSNS( XML_xmlns, XML_w10 ), "urn:schemas-microsoft-com:office:word",
611             FSNS( XML_xmlns, XML_wp ), "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
612             FSEND );
613 
614     // body
615     m_pDocumentFS->startElementNS( XML_w, XML_body, FSEND );
616 
617     pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
618 
619     // the text
620     WriteText();
621 
622     // the last section info
623     const WW8_SepInfo *pSectionInfo = m_pSections? m_pSections->CurrentSectionInfo(): NULL;
624     if ( pSectionInfo )
625         SectionProperties( *pSectionInfo );
626 
627     // finish body and document
628     m_pDocumentFS->endElementNS( XML_w, XML_body );
629     m_pDocumentFS->endElementNS( XML_w, XML_document );
630 }
631 
DocxExport(DocxExportFilter * pFilter,SwDoc * pDocument,SwPaM * pCurrentPam,SwPaM * pOriginalPam)632 DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam )
633     : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
634       m_pFilter( pFilter ),
635       m_pAttrOutput( NULL ),
636       m_pSections( NULL ),
637       m_nHeaders( 0 ),
638       m_nFooters( 0 ),
639       m_pVMLExport( NULL )
640 {
641     // Write the document properies
642     WriteProperties( );
643 
644     // relations for the document
645     m_pFilter->addRelation( S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ),
646             S( "word/document.xml" ) );
647 
648     // the actual document
649     m_pDocumentFS = m_pFilter->openOutputStreamWithSerializer( S( "word/document.xml" ),
650             S( "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" ) );
651 
652     // the DrawingML access
653     m_pDrawingML = new oox::drawingml::DrawingML( m_pDocumentFS, m_pFilter, oox::drawingml::DrawingML::DOCUMENT_DOCX );
654 
655     // the attribute output for the document
656     m_pAttrOutput = new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML );
657 
658     // the related VMLExport
659     m_pVMLExport = new VMLExport( m_pDocumentFS );
660 }
661 
~DocxExport()662 DocxExport::~DocxExport()
663 {
664     delete m_pVMLExport, m_pVMLExport = NULL;
665     delete m_pAttrOutput, m_pAttrOutput = NULL;
666     delete m_pDrawingML, m_pDrawingML = NULL;
667 }
668 
669 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
670