Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "docxexport.hxx"
21 : #include "docxexportfilter.hxx"
22 : #include "docxattributeoutput.hxx"
23 : #include "docxsdrexport.hxx"
24 :
25 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
26 : #include <com/sun/star/document/XDocumentProperties.hpp>
27 : #include <com/sun/star/drawing/XShape.hpp>
28 : #include <com/sun/star/i18n/ScriptType.hpp>
29 : #include <com/sun/star/frame/XModel.hpp>
30 : #include <com/sun/star/xml/dom/XDocument.hpp>
31 : #include <com/sun/star/xml/sax/XSAXSerializable.hpp>
32 : #include <com/sun/star/xml/sax/Writer.hpp>
33 :
34 : #include <oox/token/tokens.hxx>
35 : #include <oox/export/drawingml.hxx>
36 : #include <oox/export/vmlexport.hxx>
37 : #include <oox/export/chartexport.hxx>
38 : #include <oox/export/shapes.hxx>
39 :
40 : #include <map>
41 : #include <algorithm>
42 :
43 : #include <IMark.hxx>
44 : #include <IDocumentSettingAccess.hxx>
45 : #include <IDocumentLayoutAccess.hxx>
46 : #include <docsh.hxx>
47 : #include <ndtxt.hxx>
48 : #include <wrtww8.hxx>
49 : #include <fltini.hxx>
50 : #include <fmtline.hxx>
51 : #include <fmtpdsc.hxx>
52 : #include <frmfmt.hxx>
53 : #include <section.hxx>
54 : #include <ftninfo.hxx>
55 : #include <pagedesc.hxx>
56 :
57 : #include <editeng/unoprnms.hxx>
58 : #include <editeng/editobj.hxx>
59 : #include <editeng/outlobj.hxx>
60 : #include <editeng/brushitem.hxx>
61 :
62 : #include <docary.hxx>
63 : #include <numrule.hxx>
64 : #include <charfmt.hxx>
65 : #include <viewsh.hxx>
66 : #include <viewopt.hxx>
67 :
68 : #include "ww8par.hxx"
69 : #include "ww8scan.hxx"
70 : #include <oox/token/properties.hxx>
71 : #include <comphelper/embeddedobjectcontainer.hxx>
72 : #include <comphelper/string.hxx>
73 : #include <rtl/ustrbuf.hxx>
74 : #include <vcl/font.hxx>
75 :
76 : using namespace sax_fastparser;
77 : using namespace ::comphelper;
78 : using namespace ::com::sun::star;
79 : using namespace ::oox;
80 :
81 : using oox::vml::VMLExport;
82 :
83 : using sw::mark::IMark;
84 :
85 635098 : AttributeOutputBase& DocxExport::AttrOutput() const
86 : {
87 635098 : return *m_pAttrOutput;
88 : }
89 :
90 644 : DocxAttributeOutput& DocxExport::DocxAttrOutput() const
91 : {
92 644 : return *m_pAttrOutput;
93 : }
94 :
95 188 : MSWordSections& DocxExport::Sections() const
96 : {
97 188 : return *m_pSections;
98 : }
99 :
100 118948 : bool DocxExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
101 : {
102 : // TODO FIXME is this actually true for docx? - this is ~copied from WW8
103 118948 : if ( nScript == i18n::ScriptType::ASIAN )
104 : {
105 : // for asian in ww8, there is only one fontsize
106 : // and one fontstyle (posture/weight)
107 8 : switch ( nWhich )
108 : {
109 : case RES_CHRATR_FONTSIZE:
110 : case RES_CHRATR_POSTURE:
111 : case RES_CHRATR_WEIGHT:
112 2 : return false;
113 : default:
114 6 : break;
115 : }
116 : }
117 118940 : else if ( nScript != i18n::ScriptType::COMPLEX )
118 : {
119 : // for western in ww8, there is only one fontsize
120 : // and one fontstyle (posture/weight)
121 118932 : switch ( nWhich )
122 : {
123 : case RES_CHRATR_CJK_FONTSIZE:
124 : case RES_CHRATR_CJK_POSTURE:
125 : case RES_CHRATR_CJK_WEIGHT:
126 23932 : return false;
127 : default:
128 95000 : break;
129 : }
130 : }
131 95014 : return true;
132 : }
133 :
134 30562 : void DocxExport::AppendBookmarks( const SwTxtNode& rNode, sal_Int32 nAktPos, sal_Int32 nLen )
135 : {
136 30562 : std::vector< OUString > aStarts;
137 61124 : std::vector< OUString > aEnds;
138 :
139 61124 : IMarkVector aMarks;
140 30562 : if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
141 : {
142 4432 : for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
143 : it != end; ++it )
144 : {
145 2524 : IMark* pMark = (*it);
146 :
147 2524 : const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
148 2524 : const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
149 :
150 2524 : if ( nStart == nAktPos )
151 1652 : aStarts.push_back( pMark->GetName() );
152 :
153 2524 : if ( nEnd == nAktPos )
154 1616 : aEnds.push_back( pMark->GetName() );
155 : }
156 : }
157 :
158 61124 : m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
159 30562 : }
160 :
161 4 : void DocxExport::AppendBookmark( const OUString& rName, bool /*bSkip*/ )
162 : {
163 4 : std::vector< OUString > aStarts;
164 8 : std::vector< OUString > aEnds;
165 :
166 4 : aStarts.push_back( rName );
167 4 : aEnds.push_back( rName );
168 :
169 8 : m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
170 4 : }
171 :
172 30562 : void DocxExport::AppendAnnotationMarks( const SwTxtNode& rNode, sal_Int32 nAktPos, sal_Int32 nLen )
173 : {
174 30562 : std::vector< OUString > aStarts;
175 61124 : std::vector< OUString > aEnds;
176 :
177 61124 : IMarkVector aMarks;
178 30562 : if ( GetAnnotationMarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
179 : {
180 78 : for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
181 : it != end; ++it )
182 : {
183 40 : IMark* pMark = (*it);
184 :
185 40 : const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
186 40 : const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
187 :
188 40 : if ( nStart == nAktPos )
189 14 : aStarts.push_back( pMark->GetName() );
190 :
191 40 : if ( nEnd == nAktPos )
192 10 : aEnds.push_back( pMark->GetName() );
193 : }
194 : }
195 :
196 61124 : m_pAttrOutput->WriteAnnotationMarks_Impl( aStarts, aEnds );
197 30562 : }
198 :
199 824 : void DocxExport::ExportGrfBullet(const SwTxtNode&)
200 : {
201 : // Just collect the bullets for now, numbering.xml is not yet started.
202 824 : CollectGrfsOfBullets();
203 824 : }
204 :
205 0 : OString DocxExport::AddRelation( const OUString& rType, const OUString& rTarget )
206 : {
207 : OUString sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
208 0 : rType, rTarget, true );
209 :
210 0 : return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
211 : }
212 :
213 12874 : bool DocxExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
214 : {
215 12874 : bool bRet( false );
216 :
217 12874 : if (SfxItemState::SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
218 : {
219 12816 : if (const SwFmt *pParent = rFmt.DerivedFrom())
220 : {
221 12816 : if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
222 : {
223 0 : ::sax_fastparser::FSHelperPtr pSerializer = m_pAttrOutput->GetSerializer( );
224 : // Level 9 disables the outline
225 : pSerializer->singleElementNS( XML_w, XML_outlineLvl,
226 : FSNS( XML_w, XML_val ), "9" ,
227 0 : FSEND );
228 :
229 0 : bRet = true;
230 : }
231 : }
232 : }
233 :
234 12874 : return bRet;
235 : }
236 :
237 930 : void DocxExport::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
238 : const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, sal_uInt8 /*nBreakCode*/ )
239 : {
240 930 : m_nHeadersFootersInSection = 1;
241 : // Turn ON flag for 'Writing Headers \ Footers'
242 930 : m_pAttrOutput->SetWritingHeaderFooter( true );
243 :
244 : // headers
245 930 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
246 26 : WriteHeaderFooter( rLeftFmt, true, "even" );
247 :
248 930 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
249 198 : WriteHeaderFooter( rFmt, true, "default" );
250 :
251 930 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
252 38 : WriteHeaderFooter( rFirstPageFmt, true, "first" );
253 :
254 : // footers
255 930 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
256 22 : WriteHeaderFooter( rLeftFmt, false, "even" );
257 :
258 930 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
259 218 : WriteHeaderFooter( rFmt, false, "default" );
260 :
261 930 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
262 26 : WriteHeaderFooter( rFirstPageFmt, false, "first" );
263 :
264 930 : if ( nHeadFootFlags & ( nsHdFtFlags::WW8_FOOTER_EVEN | nsHdFtFlags::WW8_HEADER_EVEN ))
265 34 : m_aSettings.evenAndOddHeaders = true;
266 :
267 : // Turn OFF flag for 'Writing Headers \ Footers'
268 930 : m_pAttrOutput->SetWritingHeaderFooter( false );
269 : #if OSL_DEBUG_LEVEL > 1
270 : fprintf( stderr, "DocxExport::WriteHeadersFooters() - nBreakCode introduced, but ignored\n" );
271 : #endif
272 930 : }
273 :
274 520 : void DocxExport::OutputField( const SwField* pFld, ww::eField eFldType, const OUString& rFldCmd, sal_uInt8 nMode )
275 : {
276 520 : m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode );
277 520 : }
278 :
279 2 : void DocxExport::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
280 : {
281 2 : m_pAttrOutput->WriteFormData_Impl( rFieldmark );
282 2 : }
283 :
284 0 : void DocxExport::WriteHyperlinkData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
285 : {
286 : #if OSL_DEBUG_LEVEL > 1
287 : fprintf( stderr, "TODO DocxExport::WriteHyperlinkData()\n" );
288 : #endif
289 0 : }
290 :
291 0 : void DocxExport::DoComboBox(const OUString& rName,
292 : const OUString& rHelp,
293 : const OUString& rToolTip,
294 : const OUString& rSelected,
295 : uno::Sequence<OUString>& rListItems)
296 : {
297 0 : m_pDocumentFS->startElementNS( XML_w, XML_ffData, FSEND );
298 :
299 : m_pDocumentFS->singleElementNS( XML_w, XML_name,
300 : FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
301 0 : FSEND );
302 :
303 0 : m_pDocumentFS->singleElementNS( XML_w, XML_enabled, FSEND );
304 :
305 0 : if ( !rHelp.isEmpty() )
306 : m_pDocumentFS->singleElementNS( XML_w, XML_helpText,
307 : FSNS( XML_w, XML_val ), OUStringToOString( rHelp, RTL_TEXTENCODING_UTF8 ).getStr(),
308 0 : FSEND );
309 :
310 0 : if ( !rToolTip.isEmpty() )
311 : m_pDocumentFS->singleElementNS( XML_w, XML_statusText,
312 : FSNS( XML_w, XML_val ), OUStringToOString( rToolTip, RTL_TEXTENCODING_UTF8 ).getStr(),
313 0 : FSEND );
314 :
315 0 : m_pDocumentFS->startElementNS( XML_w, XML_ddList, FSEND );
316 :
317 : // Output the 0-based index of the selected value
318 0 : sal_uInt32 nListItems = rListItems.getLength();
319 0 : sal_Int32 nId = 0;
320 0 : sal_uInt32 nI = 0;
321 0 : while ( ( nI < nListItems ) && ( nId == 0 ) )
322 : {
323 0 : if ( rListItems[nI] == rSelected )
324 0 : nId = nI;
325 0 : nI++;
326 : }
327 :
328 : m_pDocumentFS->singleElementNS( XML_w, XML_result,
329 : FSNS( XML_w, XML_val ), OString::number( nId ).getStr( ),
330 0 : FSEND );
331 :
332 : // Loop over the entries
333 :
334 0 : for (sal_uInt32 i = 0; i < nListItems; i++)
335 : {
336 : m_pDocumentFS->singleElementNS( XML_w, XML_listEntry,
337 0 : FSNS( XML_w, XML_val ), OUStringToOString( rListItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
338 0 : FSEND );
339 : }
340 :
341 0 : m_pDocumentFS->endElementNS( XML_w, XML_ddList );
342 :
343 0 : m_pDocumentFS->endElementNS( XML_w, XML_ffData );
344 0 : }
345 :
346 0 : void DocxExport::DoFormText(const SwInputField* /*pFld*/)
347 : {
348 : OSL_TRACE( "TODO DocxExport::ForFormText()" );
349 0 : }
350 :
351 72 : OString DocxExport::OutputChart( uno::Reference< frame::XModel >& xModel, sal_Int32 nCount, ::sax_fastparser::FSHelperPtr m_pSerializer )
352 : {
353 72 : OUString aFileName = "charts/chart" + OUString::number(nCount) + ".xml";
354 : OUString sId = m_pFilter->addRelation( m_pSerializer->getOutputStream(),
355 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
356 144 : aFileName );
357 72 : aFileName = "word/charts/chart" + OUString::number(nCount) + ".xml";
358 : ::sax_fastparser::FSHelperPtr pChartFS =
359 : m_pFilter->openFragmentStreamWithSerializer( aFileName,
360 144 : "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" );
361 :
362 144 : oox::drawingml::ChartExport aChartExport( XML_w, pChartFS, xModel, m_pFilter, oox::drawingml::DrawingML::DOCUMENT_DOCX );
363 72 : aChartExport.ExportContent();
364 144 : return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
365 : }
366 :
367 32 : OString DocxExport::WriteOLEObject( SwOLEObj& rObject, const OUString& sMediaType, const OUString& sRelationType, const OUString& sFileExtension )
368 : {
369 32 : uno::Reference <embed::XEmbeddedObject> xObj( rObject.GetOleRef() );
370 32 : comphelper::EmbeddedObjectContainer* aContainer = rObject.GetObject().GetContainer();
371 64 : uno::Reference< io::XInputStream > xInStream = aContainer->GetObjectStream( xObj, NULL );
372 :
373 64 : OUString sFileName = "embeddings/oleObject" + OUString::number( ++m_nOLEObjects ) + "." + sFileExtension;
374 32 : uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream( OUStringBuffer()
375 64 : .appendAscii( "word/" )
376 32 : .append( sFileName )
377 : .makeStringAndClear(),
378 96 : sMediaType );
379 64 : OUString sId;
380 32 : if( lcl_CopyStream( xInStream, xOutStream ) )
381 :
382 56 : sId = m_pFilter->addRelation( GetFS()->getOutputStream(),
383 28 : sRelationType, sFileName, false );
384 :
385 64 : return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
386 : }
387 :
388 : // function copied from embeddedobj/source/msole/oleembed.cxx
389 32 : bool DocxExport::lcl_CopyStream( uno::Reference<io::XInputStream> xIn, uno::Reference<io::XOutputStream> xOut )
390 : {
391 32 : if( !xIn.is() || !xOut.is() )
392 4 : return false;
393 :
394 28 : const sal_Int32 nChunkSize = 4096;
395 28 : uno::Sequence< sal_Int8 > aData(nChunkSize);
396 28 : sal_Int32 nTotalRead = 0;
397 28 : sal_Int32 nRead = 0;
398 288 : do
399 : {
400 288 : nRead = xIn->readBytes(aData, nChunkSize);
401 288 : nTotalRead += nRead;
402 288 : xOut->writeBytes(aData);
403 : } while (nRead == nChunkSize);
404 28 : return nTotalRead != 0;
405 : }
406 :
407 640 : void DocxExport::OutputDML(uno::Reference<drawing::XShape>& xShape)
408 : {
409 640 : uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
410 640 : sal_Int32 nNamespace = XML_wps;
411 640 : if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
412 48 : nNamespace = XML_wpg;
413 592 : else if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
414 68 : nNamespace = XML_pic;
415 1280 : oox::drawingml::ShapeExport aExport(nNamespace, m_pAttrOutput->GetSerializer(), 0, m_pFilter, oox::drawingml::DrawingML::DOCUMENT_DOCX, m_pAttrOutput);
416 1280 : aExport.WriteShape(xShape);
417 640 : }
418 :
419 860 : void DocxExport::ExportDocument_Impl()
420 : {
421 : // Set the 'Track Revisions' flag in the settings structure
422 860 : m_aSettings.trackRevisions = 0 != ( nsRedlineMode_t::REDLINE_ON & mnRedlineMode );
423 :
424 860 : InitStyles();
425 :
426 : // init sections
427 860 : m_pSections = new MSWordSections( *this );
428 :
429 : // Make sure images are counted from one, even when exporting multiple documents.
430 860 : oox::drawingml::DrawingML::ResetCounters();
431 :
432 860 : WriteMainText();
433 :
434 860 : WriteFootnotesEndnotes();
435 :
436 860 : WritePostitFields();
437 :
438 860 : WriteNumbering();
439 :
440 860 : WriteFonts();
441 :
442 860 : WriteSettings();
443 :
444 860 : WriteTheme();
445 :
446 860 : WriteGlossary();
447 :
448 860 : WriteCustomXml();
449 :
450 860 : WriteActiveX();
451 :
452 860 : WriteEmbeddings();
453 :
454 860 : delete pStyles, pStyles = NULL;
455 860 : delete m_pSections, m_pSections = NULL;
456 860 : }
457 :
458 0 : void DocxExport::OutputPageSectionBreaks( const SwTxtNode& )
459 : {
460 : OSL_TRACE( "TODO DocxExport::OutputPageSectionBreaks( const SwTxtNode& )" );
461 0 : }
462 :
463 20 : void DocxExport::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, sal_uLong nLnNum )
464 : {
465 20 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
466 20 : m_pSections->AppendSection( pPageDesc, pFmt, nLnNum );
467 20 : }
468 :
469 4038 : void DocxExport::OutputEndNode( const SwEndNode& rEndNode )
470 : {
471 4038 : MSWordExportBase::OutputEndNode( rEndNode );
472 :
473 4038 : if ( TXT_MAINTEXT == nTxtTyp && rEndNode.StartOfSectionNode()->IsSectionNode() )
474 : {
475 : // this originally comes from WW8Export::WriteText(), and looks like it
476 : // could have some code common with SectionNode()...
477 :
478 0 : const SwSection& rSect = rEndNode.StartOfSectionNode()->GetSectionNode()->GetSection();
479 0 : if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
480 0 : bStartTOX = false;
481 :
482 0 : SwNodeIndex aIdx( rEndNode, 1 );
483 0 : const SwNode& rNd = aIdx.GetNode();
484 0 : if ( rNd.IsEndNode() && rNd.StartOfSectionNode()->IsSectionNode() )
485 4038 : return;
486 :
487 0 : bool isInTable = IsInTable();
488 0 : if ( !rNd.IsSectionNode() && isInTable ) // No sections in table
489 : {
490 0 : const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent();
491 0 : if( !pParentFmt )
492 0 : pParentFmt = (SwSectionFmt*)0xFFFFFFFF;
493 :
494 : sal_uLong nRstLnNum;
495 0 : if( rNd.IsCntntNode() )
496 0 : nRstLnNum = const_cast< SwCntntNode* >( rNd.GetCntntNode() )->GetSwAttrSet().GetLineNumber().GetStartValue();
497 : else
498 0 : nRstLnNum = 0;
499 :
500 0 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo( ) );
501 0 : m_pSections->AppendSection( pAktPageDesc, pParentFmt, nRstLnNum );
502 0 : }
503 : }
504 : }
505 :
506 0 : void DocxExport::OutputTableNode( const SwTableNode& )
507 : {
508 : OSL_TRACE( "TODO DocxExport::OutputTableNode( const SwTableNode& )" );
509 0 : }
510 :
511 0 : void DocxExport::OutputGrfNode( const SwGrfNode& )
512 : {
513 : OSL_TRACE( "TODO DocxExport::OutputGrfNode( const SwGrfNode& )" );
514 0 : }
515 :
516 0 : void DocxExport::OutputOLENode( const SwOLENode& )
517 : {
518 : OSL_TRACE( "TODO DocxExport::OutputOLENode( const SwOLENode& )" );
519 0 : }
520 :
521 0 : void DocxExport::OutputLinkedOLE( const OUString& )
522 : {
523 : // Nothing to implement here: WW8 only
524 0 : }
525 :
526 20 : sal_uLong DocxExport::ReplaceCr( sal_uInt8 )
527 : {
528 : // Completely unused for Docx export... only here for code sharing
529 : // purpose with binary export
530 20 : return 0;
531 : }
532 :
533 40 : void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet,
534 : const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt,
535 : const SwPageDesc* pNewPgDesc )
536 : {
537 : // tell the attribute output that we are ready to write the section
538 : // break [has to be output inside paragraph properties]
539 40 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
540 :
541 40 : const SwSectionFmt* pFmt = GetSectionFormat( rNd );
542 40 : const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
543 :
544 : OSL_ENSURE( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
545 :
546 40 : if ( pNewPgDescFmt )
547 : {
548 40 : m_pSections->AppendSection( *pNewPgDescFmt, rNd, pFmt, nLnNm );
549 : }
550 0 : else if ( pNewPgDesc )
551 : {
552 0 : m_pSections->AppendSection( pNewPgDesc, rNd, pFmt, nLnNm );
553 : }
554 :
555 40 : }
556 :
557 860 : void DocxExport::InitStyles()
558 : {
559 860 : pStyles = new MSWordStyles( *this, /*bListStyles =*/ true );
560 :
561 : // setup word/styles.xml and the relations + content type
562 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
563 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
564 860 : "styles.xml" );
565 :
566 : ::sax_fastparser::FSHelperPtr pStylesFS =
567 : m_pFilter->openFragmentStreamWithSerializer( "word/styles.xml",
568 860 : "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" );
569 :
570 : // switch the serializer to redirect the output to word/styles.xml
571 860 : m_pAttrOutput->SetSerializer( pStylesFS );
572 :
573 : // do the work
574 860 : pStyles->OutputStylesTable();
575 :
576 : // switch the serializer back
577 860 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
578 860 : }
579 :
580 860 : void DocxExport::WriteFootnotesEndnotes()
581 : {
582 860 : if ( m_pAttrOutput->HasFootnotes() )
583 : {
584 : // setup word/styles.xml and the relations + content type
585 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
586 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
587 8 : "footnotes.xml" );
588 :
589 : ::sax_fastparser::FSHelperPtr pFootnotesFS =
590 : m_pFilter->openFragmentStreamWithSerializer( "word/footnotes.xml",
591 8 : "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" );
592 :
593 : // switch the serializer to redirect the output to word/footnotes.xml
594 8 : m_pAttrOutput->SetSerializer( pFootnotesFS );
595 :
596 : // do the work
597 8 : m_pAttrOutput->FootnotesEndnotes( true );
598 :
599 : // switch the serializer back
600 8 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
601 : }
602 :
603 860 : if ( m_pAttrOutput->HasEndnotes() )
604 : {
605 : // setup word/styles.xml and the relations + content type
606 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
607 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes",
608 4 : "endnotes.xml" );
609 :
610 : ::sax_fastparser::FSHelperPtr pEndnotesFS =
611 : m_pFilter->openFragmentStreamWithSerializer( "word/endnotes.xml",
612 4 : "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" );
613 :
614 : // switch the serializer to redirect the output to word/endnotes.xml
615 4 : m_pAttrOutput->SetSerializer( pEndnotesFS );
616 :
617 : // do the work
618 4 : m_pAttrOutput->FootnotesEndnotes( false );
619 :
620 : // switch the serializer back
621 4 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
622 : }
623 860 : }
624 :
625 860 : void DocxExport::WritePostitFields()
626 : {
627 860 : if ( m_pAttrOutput->HasPostitFields() )
628 : {
629 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
630 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
631 12 : "comments.xml" );
632 :
633 : ::sax_fastparser::FSHelperPtr pPostitFS =
634 : m_pFilter->openFragmentStreamWithSerializer( "word/comments.xml",
635 12 : "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" );
636 :
637 12 : pPostitFS->startElementNS( XML_w, XML_comments, MainXmlNamespaces( pPostitFS ));
638 12 : m_pAttrOutput->SetSerializer( pPostitFS );
639 12 : m_pAttrOutput->WritePostitFields();
640 12 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
641 12 : pPostitFS->endElementNS( XML_w, XML_comments );
642 : }
643 860 : }
644 :
645 860 : void DocxExport::WriteNumbering()
646 : {
647 860 : if ( !pUsedNumTbl )
648 1652 : return; // no numbering is used
649 :
650 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
651 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
652 68 : "numbering.xml" );
653 :
654 : ::sax_fastparser::FSHelperPtr pNumberingFS = m_pFilter->openFragmentStreamWithSerializer( "word/numbering.xml",
655 68 : "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" );
656 :
657 : // switch the serializer to redirect the output to word/nubering.xml
658 68 : m_pAttrOutput->SetSerializer( pNumberingFS );
659 :
660 : pNumberingFS->startElementNS( XML_w, XML_numbering,
661 : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
662 : FSNS( XML_xmlns, XML_o ), "urn:schemas-microsoft-com:office:office",
663 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
664 : FSNS( XML_xmlns, XML_v ), "urn:schemas-microsoft-com:vml",
665 68 : FSEND );
666 :
667 68 : BulletDefinitions();
668 :
669 68 : AbstractNumberingDefinitions();
670 :
671 68 : NumberingDefinitions();
672 :
673 68 : pNumberingFS->endElementNS( XML_w, XML_numbering );
674 :
675 : // switch the serializer back
676 68 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
677 : }
678 :
679 528 : void DocxExport::WriteHeaderFooter( const SwFmt& rFmt, bool bHeader, const char* pType )
680 : {
681 : // setup the xml stream
682 528 : OUString aRelId;
683 1056 : ::sax_fastparser::FSHelperPtr pFS;
684 528 : if ( bHeader )
685 : {
686 262 : OUString aName( OUStringBuffer().append("header").append( ++m_nHeaders ).append(".xml").makeStringAndClear() );
687 :
688 524 : aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
689 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
690 262 : aName );
691 :
692 524 : pFS = m_pFilter->openFragmentStreamWithSerializer( OUStringBuffer().append("word/").append( aName ).makeStringAndClear(),
693 262 : "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" );
694 :
695 262 : pFS->startElementNS( XML_w, XML_hdr, MainXmlNamespaces( pFS ));
696 : }
697 : else
698 : {
699 266 : OUString aName( OUStringBuffer().append("footer").append( ++m_nFooters ).append(".xml").makeStringAndClear() );
700 :
701 532 : aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
702 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
703 266 : aName );
704 :
705 532 : pFS = m_pFilter->openFragmentStreamWithSerializer( OUStringBuffer().append("word/").append( aName ).makeStringAndClear(),
706 266 : "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" );
707 :
708 266 : pFS->startElementNS( XML_w, XML_ftr, MainXmlNamespaces( pFS ));
709 : }
710 :
711 : // switch the serializer to redirect the output to word/styles.xml
712 528 : m_pAttrOutput->SetSerializer( pFS );
713 528 : m_pVMLExport->SetFS( pFS );
714 528 : m_pSdrExport->setSerializer(pFS);
715 528 : SetFS( pFS );
716 528 : bool bStartedParaSdt = m_pAttrOutput->IsStartedParaSdt();
717 528 : m_pAttrOutput->SetStartedParaSdt(false);
718 :
719 1056 : DocxTableExportContext aTableExportContext;
720 528 : m_pAttrOutput->pushToTableExportContext(aTableExportContext);
721 : // do the work
722 528 : WriteHeaderFooterText( rFmt, bHeader );
723 528 : m_pAttrOutput->popFromTableExportContext(aTableExportContext);
724 528 : m_pAttrOutput->EndParaSdtBlock();
725 :
726 : //When the stream changes the cache which is maintained for the graphics in case of alternate content is not cleared.
727 : //So clearing the alternate content graphic cache.
728 528 : m_pAttrOutput->ClearRelIdCache();
729 :
730 : // switch the serializer back
731 528 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
732 528 : m_pVMLExport->SetFS( m_pDocumentFS );
733 528 : m_pSdrExport->setSerializer(m_pDocumentFS);
734 528 : SetFS( m_pDocumentFS );
735 528 : m_pAttrOutput->SetStartedParaSdt(bStartedParaSdt);
736 :
737 : // close the tag
738 : sal_Int32 nReference;
739 528 : if ( bHeader )
740 : {
741 262 : pFS->endElementNS( XML_w, XML_hdr );
742 262 : nReference = XML_headerReference;
743 : }
744 : else
745 : {
746 266 : pFS->endElementNS( XML_w, XML_ftr );
747 266 : nReference = XML_footerReference;
748 : }
749 :
750 : // and write the reference
751 : m_pDocumentFS->singleElementNS( XML_w, nReference,
752 : FSNS( XML_w, XML_type ), pType,
753 : FSNS( XML_r, XML_id ), OUStringToOString( aRelId, RTL_TEXTENCODING_UTF8 ).getStr(),
754 1056 : FSEND );
755 528 : }
756 :
757 860 : void DocxExport::WriteFonts()
758 : {
759 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
760 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
761 860 : "fontTable.xml" );
762 :
763 : ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openFragmentStreamWithSerializer(
764 : "word/fontTable.xml",
765 860 : "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" );
766 :
767 : pFS->startElementNS( XML_w, XML_fonts,
768 : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
769 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
770 860 : FSEND );
771 :
772 : // switch the serializer to redirect the output to word/styles.xml
773 860 : m_pAttrOutput->SetSerializer( pFS );
774 :
775 : // do the work
776 860 : maFontHelper.WriteFontTable( *m_pAttrOutput );
777 :
778 : // switch the serializer back
779 860 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
780 :
781 860 : pFS->endElementNS( XML_w, XML_fonts );
782 860 : }
783 :
784 860 : void DocxExport::WriteProperties( )
785 : {
786 : // Write the core properties
787 860 : SwDocShell* pDocShell( pDoc->GetDocShell( ) );
788 860 : uno::Reference<document::XDocumentProperties> xDocProps;
789 860 : if ( pDocShell )
790 : {
791 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
792 860 : pDocShell->GetModel( ), uno::UNO_QUERY );
793 860 : xDocProps = xDPS->getDocumentProperties();
794 : }
795 :
796 860 : m_pFilter->exportDocumentProperties( xDocProps );
797 860 : }
798 :
799 860 : void DocxExport::WriteSettings()
800 : {
801 860 : SwViewShell *pViewShell(pDoc->getIDocumentLayoutAccess().GetCurrentViewShell());
802 860 : if( !pViewShell && !m_aSettings.hasData() && !m_pAttrOutput->HasFootnotes() && !m_pAttrOutput->HasEndnotes())
803 860 : return;
804 :
805 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
806 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
807 860 : "settings.xml" );
808 :
809 : ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openFragmentStreamWithSerializer(
810 : "word/settings.xml",
811 860 : "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" );
812 :
813 : pFS->startElementNS( XML_w, XML_settings,
814 : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
815 860 : FSEND );
816 :
817 : // Zoom
818 860 : if (pViewShell)
819 : {
820 848 : OString aZoom(OString::number(pViewShell->GetViewOptions()->GetZoom()));
821 848 : pFS->singleElementNS(XML_w, XML_zoom, FSNS(XML_w, XML_percent), aZoom.getStr(), FSEND);
822 : }
823 :
824 : // Display Background Shape
825 860 : if (boost::optional<SvxBrushItem> oBrush = getBackground())
826 : {
827 : // Turn on the 'displayBackgroundShape'
828 12 : pFS->singleElementNS( XML_w, XML_displayBackgroundShape, FSEND );
829 860 : }
830 :
831 : // Track Changes
832 860 : if ( m_aSettings.trackRevisions )
833 18 : pFS->singleElementNS( XML_w, XML_trackRevisions, FSEND );
834 :
835 : // Mirror Margins
836 860 : if(isMirroredMargin())
837 8 : pFS->singleElementNS( XML_w, XML_mirrorMargins, FSEND );
838 :
839 : // Embed Fonts
840 860 : if( pDoc->getIDocumentSettingAccess().get( IDocumentSettingAccess::EMBED_FONTS ))
841 0 : pFS->singleElementNS( XML_w, XML_embedTrueTypeFonts, FSEND );
842 :
843 : // Embed System Fonts
844 860 : if( pDoc->getIDocumentSettingAccess().get( IDocumentSettingAccess::EMBED_SYSTEM_FONTS ))
845 54 : pFS->singleElementNS( XML_w, XML_embedSystemFonts, FSEND );
846 :
847 : // Default Tab Stop
848 860 : if( m_aSettings.defaultTabStop != 0 )
849 : pFS->singleElementNS( XML_w, XML_defaultTabStop, FSNS( XML_w, XML_val ),
850 860 : OString::number( m_aSettings.defaultTabStop).getStr(), FSEND );
851 :
852 : // Even and Odd Headers
853 860 : if( m_aSettings.evenAndOddHeaders )
854 30 : pFS->singleElementNS( XML_w, XML_evenAndOddHeaders, FSEND );
855 :
856 : // Has Footnotes
857 860 : if( m_pAttrOutput->HasFootnotes())
858 8 : m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_footnotePr, pDoc->GetFtnInfo(), XML_footnote );
859 :
860 : // Has Endnotes
861 860 : if( m_pAttrOutput->HasEndnotes())
862 4 : m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_endnotePr, pDoc->GetEndNoteInfo(), XML_endnote );
863 :
864 : // Has themeFontLang information
865 1720 : uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
866 :
867 1720 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
868 1720 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
869 860 : if ( xPropSetInfo->hasPropertyByName( pName ) )
870 : {
871 860 : uno::Sequence< beans::PropertyValue > propList;
872 860 : xPropSet->getPropertyValue( pName ) >>= propList;
873 10652 : for( sal_Int32 i=0; i < propList.getLength(); ++i )
874 : {
875 9792 : if ( propList[i].Name == "ThemeFontLangProps" )
876 : {
877 822 : uno::Sequence< beans::PropertyValue > themeFontLangProps;
878 822 : propList[i].Value >>= themeFontLangProps;
879 1644 : OUString aValues[3];
880 3288 : for( sal_Int32 j=0; j < themeFontLangProps.getLength(); ++j )
881 : {
882 2466 : if( themeFontLangProps[j].Name == "val" )
883 774 : themeFontLangProps[j].Value >>= aValues[0];
884 1692 : else if( themeFontLangProps[j].Name == "eastAsia" )
885 316 : themeFontLangProps[j].Value >>= aValues[1];
886 1376 : else if( themeFontLangProps[j].Name == "bidi" )
887 340 : themeFontLangProps[j].Value >>= aValues[2];
888 : }
889 : pFS->singleElementNS( XML_w, XML_themeFontLang,
890 : FSNS( XML_w, XML_val ), OUStringToOString( aValues[0], RTL_TEXTENCODING_UTF8 ).getStr(),
891 : FSNS( XML_w, XML_eastAsia ), OUStringToOString( aValues[1], RTL_TEXTENCODING_UTF8 ).getStr(),
892 : FSNS( XML_w, XML_bidi ), OUStringToOString( aValues[2], RTL_TEXTENCODING_UTF8 ).getStr(),
893 1644 : FSEND );
894 : }
895 8970 : else if ( propList[i].Name == "CompatSettings" )
896 : {
897 822 : pFS->startElementNS( XML_w, XML_compat, FSEND );
898 :
899 822 : uno::Sequence< beans::PropertyValue > aCompatSettingsSequence;
900 822 : propList[i].Value >>= aCompatSettingsSequence;
901 3296 : for(sal_Int32 j=0; j < aCompatSettingsSequence.getLength(); ++j)
902 : {
903 2474 : uno::Sequence< beans::PropertyValue > aCompatSetting;
904 2474 : aCompatSettingsSequence[j].Value >>= aCompatSetting;
905 4948 : OUString aName;
906 4948 : OUString aUri;
907 4948 : OUString aValue;
908 :
909 9896 : for(sal_Int32 k=0; k < aCompatSetting.getLength(); ++k)
910 : {
911 7422 : if( aCompatSetting[k].Name == "name" )
912 2474 : aCompatSetting[k].Value >>= aName;
913 4948 : else if( aCompatSetting[k].Name == "uri" )
914 2474 : aCompatSetting[k].Value >>= aUri;
915 2474 : else if( aCompatSetting[k].Name == "val" )
916 2474 : aCompatSetting[k].Value >>= aValue;
917 : }
918 : pFS->singleElementNS( XML_w, XML_compatSetting,
919 : FSNS( XML_w, XML_name ), OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr(),
920 : FSNS( XML_w, XML_uri ), OUStringToOString(aUri, RTL_TEXTENCODING_UTF8).getStr(),
921 : FSNS( XML_w, XML_val ), OUStringToOString(aValue, RTL_TEXTENCODING_UTF8).getStr(),
922 2474 : FSEND);
923 2474 : }
924 :
925 822 : pFS->endElementNS( XML_w, XML_compat );
926 : }
927 860 : }
928 : }
929 :
930 1720 : pFS->endElementNS( XML_w, XML_settings );
931 : }
932 :
933 860 : void DocxExport::WriteTheme()
934 : {
935 860 : uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
936 :
937 1638 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
938 1638 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
939 860 : if ( !xPropSetInfo->hasPropertyByName( pName ) )
940 0 : return;
941 :
942 1638 : uno::Reference<xml::dom::XDocument> themeDom;
943 1638 : uno::Sequence< beans::PropertyValue > propList;
944 860 : xPropSet->getPropertyValue( pName ) >>= propList;
945 7462 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
946 : {
947 7424 : OUString propName = propList[nProp].Name;
948 7424 : if ( propName == "OOXTheme" )
949 : {
950 822 : propList[nProp].Value >>= themeDom;
951 822 : break;
952 : }
953 6602 : }
954 :
955 : // no theme dom to write
956 860 : if ( !themeDom.is() )
957 82 : return;
958 :
959 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
960 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
961 778 : "theme/theme1.xml" );
962 :
963 1556 : uno::Reference< xml::sax::XSAXSerializable > serializer( themeDom, uno::UNO_QUERY );
964 1556 : uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
965 1556 : writer->setOutputStream( GetFilter().openFragmentStream( "word/theme/theme1.xml",
966 1556 : "application/vnd.openxmlformats-officedocument.theme+xml" ) );
967 778 : serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
968 1556 : uno::Sequence< beans::StringPair >() );
969 : }
970 :
971 860 : void DocxExport::WriteGlossary()
972 : {
973 860 : uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
974 :
975 902 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
976 902 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
977 860 : if ( !xPropSetInfo->hasPropertyByName( pName ) )
978 0 : return;
979 :
980 902 : uno::Reference<xml::dom::XDocument> glossaryDocDom;
981 902 : uno::Sequence< uno::Sequence< uno::Any> > glossaryDomList;
982 902 : uno::Sequence< beans::PropertyValue > propList;
983 860 : xPropSet->getPropertyValue( pName ) >>= propList;
984 860 : sal_Int32 collectedProperties = 0;
985 6640 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
986 : {
987 6602 : OUString propName = propList[nProp].Name;
988 6602 : if ( propName == "OOXGlossary" )
989 : {
990 822 : propList[nProp].Value >>= glossaryDocDom;
991 822 : collectedProperties++;
992 : }
993 6602 : if (propName == "OOXGlossaryDom")
994 : {
995 822 : propList[nProp].Value >>= glossaryDomList;
996 822 : collectedProperties++;
997 : }
998 6602 : if (collectedProperties == 2)
999 822 : break;
1000 5780 : }
1001 :
1002 : // no glossary dom to write
1003 860 : if ( !glossaryDocDom.is() )
1004 818 : return;
1005 :
1006 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
1007 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/glossaryDocument",
1008 42 : "glossary/document.xml" );
1009 :
1010 42 : uno::Reference< io::XOutputStream > xOutputStream = GetFilter().openFragmentStream( "word/glossary/document.xml",
1011 126 : "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml" );
1012 :
1013 84 : uno::Reference< xml::sax::XSAXSerializable > serializer( glossaryDocDom, uno::UNO_QUERY );
1014 84 : uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1015 42 : writer->setOutputStream( xOutputStream );
1016 42 : serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1017 42 : uno::Sequence< beans::StringPair >() );
1018 :
1019 42 : sal_Int32 length = glossaryDomList.getLength();
1020 210 : for ( int i =0; i < length; i++)
1021 : {
1022 168 : uno::Sequence< uno::Any> glossaryElement = glossaryDomList[i];
1023 336 : OUString gTarget, gType, gId, contentType;
1024 336 : uno::Reference<xml::dom::XDocument> xDom;
1025 168 : glossaryElement[0] >>= xDom;
1026 168 : glossaryElement[1] >>= gId;
1027 168 : glossaryElement[2] >>= gType;
1028 168 : glossaryElement[3] >>= gTarget;
1029 168 : glossaryElement[4] >>= contentType;
1030 168 : gId = gId.copy(3); //"rId" only save the numeric value
1031 :
1032 336 : PropertySet aProps(xOutputStream);
1033 168 : aProps.setAnyProperty( PROP_RelId, uno::makeAny( sal_Int32( gId.toInt32() )));
1034 168 : m_pFilter->addRelation( xOutputStream, gType, gTarget);
1035 336 : uno::Reference< xml::sax::XSAXSerializable > gserializer( xDom, uno::UNO_QUERY );
1036 168 : writer->setOutputStream(GetFilter().openFragmentStream( "word/glossary/" + gTarget, contentType ) );
1037 168 : gserializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1038 168 : uno::Sequence< beans::StringPair >() );
1039 210 : }
1040 : }
1041 :
1042 860 : void DocxExport::WriteCustomXml()
1043 : {
1044 860 : uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1045 :
1046 1720 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1047 1720 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1048 860 : if ( !xPropSetInfo->hasPropertyByName( pName ) )
1049 860 : return;
1050 :
1051 1720 : uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomlist;
1052 1720 : uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomPropslist;
1053 1720 : uno::Sequence< beans::PropertyValue > propList;
1054 860 : xPropSet->getPropertyValue( pName ) >>= propList;
1055 3352 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
1056 : {
1057 3314 : OUString propName = propList[nProp].Name;
1058 3314 : if ( propName == "OOXCustomXml" )
1059 : {
1060 822 : propList[nProp].Value >>= customXmlDomlist;
1061 822 : break;
1062 : }
1063 2492 : }
1064 :
1065 4174 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
1066 : {
1067 4136 : OUString propName = propList[nProp].Name;
1068 4136 : if ( propName == "OOXCustomXmlProps" )
1069 : {
1070 822 : propList[nProp].Value >>= customXmlDomPropslist;
1071 822 : break;
1072 : }
1073 3314 : }
1074 :
1075 1166 : for (sal_Int32 j = 0; j < customXmlDomlist.getLength(); j++) {
1076 :
1077 306 : uno::Reference<xml::dom::XDocument> customXmlDom = customXmlDomlist[j];
1078 612 : uno::Reference<xml::dom::XDocument> customXmlDomProps = customXmlDomPropslist[j];
1079 306 : if ( customXmlDom.is() )
1080 : {
1081 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
1082 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml",
1083 306 : "../customXml/item"+OUString::number((j+1))+".xml" );
1084 :
1085 306 : uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDom, uno::UNO_QUERY );
1086 612 : uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1087 1224 : writer->setOutputStream( GetFilter().openFragmentStream( "customXml/item"+OUString::number((j+1))+".xml",
1088 1224 : "application/xml" ) );
1089 306 : serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1090 612 : uno::Sequence< beans::StringPair >() );
1091 : }
1092 :
1093 306 : if ( customXmlDomProps.is() )
1094 : {
1095 :
1096 306 : uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDomProps, uno::UNO_QUERY );
1097 612 : uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1098 1224 : writer->setOutputStream( GetFilter().openFragmentStream( "customXml/itemProps"+OUString::number((j+1))+".xml",
1099 1224 : "application/vnd.openxmlformats-officedocument.customXmlProperties+xml" ) );
1100 306 : serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1101 306 : uno::Sequence< beans::StringPair >() );
1102 :
1103 : // Adding itemprops's relationship entry to item.xml.rels file
1104 918 : m_pFilter->addRelation( GetFilter().openFragmentStream( "customXml/item"+OUString::number((j+1))+".xml",
1105 : "application/xml" ) ,
1106 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps",
1107 1530 : "itemProps"+OUString::number((j+1))+".xml" );
1108 :
1109 : }
1110 1166 : }
1111 : }
1112 :
1113 860 : void DocxExport::WriteActiveX()
1114 : {
1115 860 : uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1116 :
1117 1720 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1118 1720 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1119 860 : if ( !xPropSetInfo->hasPropertyByName( pName ) )
1120 860 : return;
1121 :
1122 1720 : uno::Sequence<uno::Reference<xml::dom::XDocument> > activeXDomlist;
1123 1720 : uno::Sequence<uno::Reference<io::XInputStream> > activeXBinList;
1124 1720 : uno::Sequence< beans::PropertyValue > propList;
1125 860 : xPropSet->getPropertyValue( pName ) >>= propList;
1126 1708 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
1127 : {
1128 1670 : OUString propName = propList[nProp].Name;
1129 1670 : if ( propName == "OOXActiveX" )
1130 : {
1131 822 : propList[nProp].Value >>= activeXDomlist;
1132 822 : break;
1133 : }
1134 848 : }
1135 :
1136 2530 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
1137 : {
1138 2492 : OUString propName = propList[nProp].Name;
1139 2492 : if ( propName == "OOXActiveXBin" )
1140 : {
1141 822 : propList[nProp].Value >>= activeXBinList;
1142 822 : break;
1143 : }
1144 1670 : }
1145 :
1146 1786 : for (sal_Int32 j = 0; j < activeXDomlist.getLength(); j++)
1147 : {
1148 926 : uno::Reference<xml::dom::XDocument> activeXDom = activeXDomlist[j];
1149 1852 : uno::Reference<io::XInputStream> activeXBin = activeXBinList[j];
1150 :
1151 926 : if ( activeXDom.is() )
1152 : {
1153 : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
1154 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/control",
1155 926 : "activeX/activeX"+OUString::number((j+1))+".xml" );
1156 :
1157 926 : uno::Reference< xml::sax::XSAXSerializable > serializer( activeXDom, uno::UNO_QUERY );
1158 1852 : uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1159 3704 : writer->setOutputStream( GetFilter().openFragmentStream( "word/activeX/activeX"+OUString::number((j+1))+".xml",
1160 3704 : "application/vnd.ms-office.activeX+xml" ) );
1161 926 : serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1162 1852 : uno::Sequence< beans::StringPair >() );
1163 : }
1164 :
1165 926 : if ( activeXBin.is() )
1166 : {
1167 2778 : uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream("word/activeX/activeX"+OUString::number((j+1))+".bin",
1168 3704 : "application/vnd.ms-office.activeX");
1169 :
1170 : try
1171 : {
1172 926 : sal_Int32 nBufferSize = 512;
1173 926 : uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize);
1174 : sal_Int32 nRead;
1175 2120 : do
1176 : {
1177 2120 : nRead = activeXBin->readBytes( aDataBuffer, nBufferSize );
1178 2120 : if( nRead )
1179 : {
1180 1194 : if( nRead < nBufferSize )
1181 : {
1182 906 : nBufferSize = nRead;
1183 906 : aDataBuffer.realloc(nRead);
1184 : }
1185 1194 : xOutStream->writeBytes( aDataBuffer );
1186 : }
1187 : }
1188 : while( nRead );
1189 926 : xOutStream->flush();
1190 : }
1191 0 : catch(const uno::Exception&)
1192 : {
1193 : SAL_WARN("sw.ww8", "WriteActiveX() ::Failed to copy Inputstream to outputstream exception catched!");
1194 : }
1195 :
1196 926 : xOutStream->closeOutput();
1197 : // Adding itemprops's relationship entry to item.xml.rels file
1198 2778 : m_pFilter->addRelation( GetFilter().openFragmentStream( "/word/activeX/activeX"+OUString::number((j+1))+".xml",
1199 : "application/vnd.ms-office.activeX+xml" ) ,
1200 : "http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary",
1201 3704 : "activeX"+OUString::number((j+1))+".bin" );
1202 :
1203 : }
1204 1786 : }
1205 : }
1206 :
1207 860 : void DocxExport::WriteEmbeddings()
1208 : {
1209 860 : uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1210 :
1211 1720 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1212 1720 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1213 860 : if ( !xPropSetInfo->hasPropertyByName( pName ) )
1214 860 : return;
1215 :
1216 1720 : uno::Sequence< beans::PropertyValue > embeddingsList;
1217 1720 : uno::Sequence< beans::PropertyValue > propList;
1218 860 : xPropSet->getPropertyValue( pName ) >>= propList;
1219 4996 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
1220 : {
1221 4958 : OUString propName = propList[nProp].Name;
1222 4958 : if ( propName == "OOXEmbeddings" )
1223 : {
1224 822 : propList[nProp].Value >>= embeddingsList;
1225 822 : break;
1226 : }
1227 4136 : }
1228 928 : for (sal_Int32 j = 0; j < embeddingsList.getLength(); j++)
1229 : {
1230 68 : OUString embeddingPath = embeddingsList[j].Name;
1231 136 : uno::Reference<io::XInputStream> embeddingsStream;
1232 68 : embeddingsList[j].Value >>= embeddingsStream;
1233 :
1234 136 : OUString contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
1235 68 : if (embeddingPath.endsWith(OUString(".xlsm")))
1236 2 : contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
1237 66 : else if (embeddingPath.endsWith(OUString(".bin")))
1238 0 : contentType = "application/vnd.openxmlformats-officedocument.oleObject";
1239 :
1240 68 : if ( embeddingsStream.is() )
1241 : {
1242 68 : uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream(embeddingPath,
1243 68 : contentType);
1244 : try
1245 : {
1246 68 : sal_Int32 nBufferSize = 512;
1247 68 : uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize);
1248 : sal_Int32 nRead;
1249 1468 : do
1250 : {
1251 1468 : nRead = embeddingsStream->readBytes( aDataBuffer, nBufferSize );
1252 1468 : if( nRead )
1253 : {
1254 1400 : if( nRead < nBufferSize )
1255 : {
1256 64 : nBufferSize = nRead;
1257 64 : aDataBuffer.realloc(nRead);
1258 : }
1259 1400 : xOutStream->writeBytes( aDataBuffer );
1260 : }
1261 : }
1262 : while( nRead );
1263 68 : xOutStream->flush();
1264 : }
1265 0 : catch(const uno::Exception&)
1266 : {
1267 : SAL_WARN("sw.ww8", "WriteEmbeddings() ::Failed to copy Inputstream to outputstream exception catched!");
1268 : }
1269 68 : xOutStream->closeOutput();
1270 : }
1271 928 : }
1272 : }
1273 :
1274 860 : bool DocxExport::isMirroredMargin()
1275 : {
1276 860 : bool bMirroredMargins = false;
1277 860 : if ( nsUseOnPage::PD_MIRROR == (nsUseOnPage::PD_MIRROR & pDoc->GetPageDesc(0).ReadUseOn()) )
1278 : {
1279 8 : bMirroredMargins = true;
1280 : }
1281 860 : return bMirroredMargins;
1282 : }
1283 :
1284 1720 : boost::optional<SvxBrushItem> DocxExport::getBackground()
1285 : {
1286 1720 : boost::optional<SvxBrushItem> oRet;
1287 1720 : const SwFrmFmt &rFmt = pDoc->GetPageDesc(0).GetMaster();
1288 3440 : SvxBrushItem aBrush(RES_BACKGROUND);
1289 1720 : SfxItemState eState = rFmt.GetBackgroundState(aBrush);
1290 :
1291 1720 : if (SfxItemState::SET == eState)
1292 : {
1293 : // The 'color' is set for the first page style - take it and use it as the background color of the entire DOCX
1294 28 : if (aBrush.GetColor().GetColor() != COL_AUTO)
1295 24 : oRet.reset(aBrush);
1296 : }
1297 3440 : return oRet;
1298 : }
1299 :
1300 860 : void DocxExport::WriteMainText()
1301 : {
1302 : // setup the namespaces
1303 860 : m_pDocumentFS->startElementNS( XML_w, XML_document, MainXmlNamespaces( m_pDocumentFS ));
1304 :
1305 : // Write background page color
1306 860 : if (boost::optional<SvxBrushItem> oBrush = getBackground())
1307 : {
1308 12 : Color backgroundColor = oBrush->GetColor();
1309 12 : OString aBackgroundColorStr = msfilter::util::ConvertColor(backgroundColor);
1310 :
1311 12 : m_pDocumentFS->singleElementNS( XML_w, XML_background, FSNS( XML_w, XML_color ), aBackgroundColorStr, FSEND );
1312 860 : }
1313 :
1314 : // body
1315 860 : m_pDocumentFS->startElementNS( XML_w, XML_body, FSEND );
1316 :
1317 860 : pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
1318 :
1319 : // the text
1320 860 : WriteText();
1321 :
1322 : // the last section info
1323 860 : m_pAttrOutput->EndParaSdtBlock();
1324 860 : const WW8_SepInfo *pSectionInfo = m_pSections? m_pSections->CurrentSectionInfo(): NULL;
1325 860 : if ( pSectionInfo )
1326 860 : SectionProperties( *pSectionInfo );
1327 :
1328 : // finish body and document
1329 860 : m_pDocumentFS->endElementNS( XML_w, XML_body );
1330 860 : m_pDocumentFS->endElementNS( XML_w, XML_document );
1331 860 : }
1332 :
1333 1412 : XFastAttributeListRef DocxExport::MainXmlNamespaces( FSHelperPtr serializer )
1334 : {
1335 1412 : FastAttributeList* pAttr = serializer->createAttrList();
1336 1412 : pAttr->add( FSNS( XML_xmlns, XML_o ), "urn:schemas-microsoft-com:office:office" );
1337 1412 : pAttr->add( FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships" );
1338 1412 : pAttr->add( FSNS( XML_xmlns, XML_v ), "urn:schemas-microsoft-com:vml" );
1339 1412 : pAttr->add( FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main" );
1340 1412 : pAttr->add( FSNS( XML_xmlns, XML_w10 ), "urn:schemas-microsoft-com:office:word" );
1341 1412 : pAttr->add( FSNS( XML_xmlns, XML_wp ), "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" );
1342 1412 : pAttr->add( FSNS( XML_xmlns, XML_wps ), "http://schemas.microsoft.com/office/word/2010/wordprocessingShape" );
1343 1412 : pAttr->add( FSNS( XML_xmlns, XML_wpg ), "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" );
1344 1412 : pAttr->add( FSNS( XML_xmlns, XML_mc ), "http://schemas.openxmlformats.org/markup-compatibility/2006" );
1345 1412 : pAttr->add( FSNS( XML_xmlns, XML_wp14 ), "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" );
1346 1412 : pAttr->add( FSNS( XML_xmlns, XML_w14 ), "http://schemas.microsoft.com/office/word/2010/wordml" );
1347 1412 : pAttr->add( FSNS( XML_mc, XML_Ignorable ), "w14 wp14" );
1348 1412 : return XFastAttributeListRef( pAttr );
1349 : }
1350 :
1351 27486 : bool DocxExport::ignoreAttributeForStyles( sal_uInt16 nWhich ) const
1352 : {
1353 27486 : if( nWhich == RES_TEXTGRID )
1354 1486 : return true; // w:docGrid is written only to document.xml, not to styles.xml
1355 26000 : return MSWordExportBase::ignoreAttributeForStyles( nWhich );
1356 : }
1357 :
1358 16 : void DocxExport::WriteOutliner(const OutlinerParaObject& rParaObj, sal_uInt8 nTyp)
1359 : {
1360 16 : const EditTextObject& rEditObj = rParaObj.GetTextObject();
1361 16 : MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
1362 :
1363 16 : sal_Int32 nPara = rEditObj.GetParagraphCount();
1364 34 : for( sal_Int32 n = 0; n < nPara; ++n )
1365 : {
1366 18 : if( n )
1367 2 : aAttrIter.NextPara( n );
1368 :
1369 18 : AttrOutput().StartParagraph( ww8::WW8TableNodeInfo::Pointer_t());
1370 18 : rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
1371 18 : OUString aStr( rEditObj.GetText( n ));
1372 18 : sal_Int32 nAktPos = 0;
1373 18 : const sal_Int32 nEnd = aStr.getLength();
1374 26 : do {
1375 26 : AttrOutput().StartRun( NULL );
1376 26 : const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
1377 26 : rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
1378 :
1379 26 : bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
1380 26 : if( !bTxtAtr )
1381 : {
1382 26 : if( nAktPos == 0 && nNextAttr - nAktPos == aStr.getLength())
1383 16 : AttrOutput().RunText( aStr, eChrSet );
1384 : else
1385 : {
1386 10 : OUString tmp( aStr.copy( nAktPos, nNextAttr - nAktPos ));
1387 10 : AttrOutput().RunText( tmp, eChrSet );
1388 : }
1389 : }
1390 26 : AttrOutput().StartRunProperties();
1391 26 : aAttrIter.OutAttr( nAktPos );
1392 26 : AttrOutput().EndRunProperties( NULL );
1393 :
1394 26 : nAktPos = nNextAttr;
1395 26 : eChrSet = eNextChrSet;
1396 26 : aAttrIter.NextPos();
1397 26 : AttrOutput().EndRun();
1398 26 : } while( nAktPos < nEnd );
1399 : // aAttrIter.OutParaAttr(false);
1400 18 : AttrOutput().EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t());
1401 34 : }
1402 16 : }
1403 :
1404 1916 : void DocxExport::SetFS( ::sax_fastparser::FSHelperPtr pFS )
1405 : {
1406 1916 : mpFS = pFS;
1407 1916 : }
1408 :
1409 860 : DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam )
1410 : : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
1411 : m_pFilter( pFilter ),
1412 : m_pAttrOutput( NULL ),
1413 : m_pSections( NULL ),
1414 : m_nHeaders( 0 ),
1415 : m_nFooters( 0 ),
1416 : m_nOLEObjects( 0 ),
1417 : m_nHeadersFootersInSection(0),
1418 : m_pVMLExport( NULL ),
1419 860 : m_pSdrExport( NULL )
1420 : {
1421 : // Write the document properies
1422 860 : WriteProperties( );
1423 :
1424 : // relations for the document
1425 : m_pFilter->addRelation( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
1426 860 : "word/document.xml" );
1427 :
1428 : // the actual document
1429 1720 : m_pDocumentFS = m_pFilter->openFragmentStreamWithSerializer( "word/document.xml",
1430 860 : "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" );
1431 :
1432 860 : SetFS(m_pDocumentFS);
1433 :
1434 : // the DrawingML access
1435 860 : m_pDrawingML = new oox::drawingml::DrawingML( m_pDocumentFS, m_pFilter, oox::drawingml::DrawingML::DOCUMENT_DOCX );
1436 :
1437 : // the attribute output for the document
1438 860 : m_pAttrOutput = new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML );
1439 :
1440 : // the related VMLExport
1441 860 : m_pVMLExport = new VMLExport( m_pDocumentFS, m_pAttrOutput );
1442 :
1443 : // the related drawing export
1444 860 : m_pSdrExport = new DocxSdrExport( *this, m_pDocumentFS, m_pDrawingML );
1445 860 : }
1446 :
1447 1720 : DocxExport::~DocxExport()
1448 : {
1449 860 : delete m_pSdrExport, m_pSdrExport = NULL;
1450 860 : delete m_pVMLExport, m_pVMLExport = NULL;
1451 860 : delete m_pAttrOutput, m_pAttrOutput = NULL;
1452 860 : delete m_pDrawingML, m_pDrawingML = NULL;
1453 860 : }
1454 :
1455 860 : DocxSettingsData::DocxSettingsData()
1456 : : evenAndOddHeaders( false )
1457 : , defaultTabStop( 0 )
1458 860 : , trackRevisions( false )
1459 : {
1460 860 : }
1461 :
1462 12 : bool DocxSettingsData::hasData() const
1463 : {
1464 12 : if( evenAndOddHeaders )
1465 2 : return true;
1466 10 : if( defaultTabStop != 0 )
1467 10 : return true;
1468 0 : if ( trackRevisions )
1469 0 : return true;
1470 :
1471 0 : return false;
1472 102 : }
1473 :
1474 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|