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