LibreOffice Module sw (master)  1
docxexport.cxx
Go to the documentation of this file.
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 #include "docxhelper.hxx"
25 
26 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
27 #include <com/sun/star/document/XDocumentProperties.hpp>
28 #include <com/sun/star/document/XStorageBasedDocument.hpp>
29 #include <com/sun/star/drawing/XShape.hpp>
30 #include <com/sun/star/i18n/ScriptType.hpp>
31 #include <com/sun/star/frame/XModel.hpp>
32 #include <com/sun/star/xml/dom/XDocument.hpp>
33 #include <com/sun/star/xml/sax/XSAXSerializable.hpp>
34 #include <com/sun/star/xml/sax/Writer.hpp>
35 #include <com/sun/star/awt/XControlModel.hpp>
36 #include <com/sun/star/sdb/CommandType.hpp>
37 
38 #include <oox/token/namespaces.hxx>
39 #include <oox/token/tokens.hxx>
40 #include <oox/export/drawingml.hxx>
41 #include <oox/export/vmlexport.hxx>
43 #include <oox/export/shapes.hxx>
47 #include <oox/ole/olestorage.hxx>
48 #include <oox/ole/olehelper.hxx>
49 
50 #include <map>
51 #include <algorithm>
52 
53 #include <IMark.hxx>
57 #include <docsh.hxx>
58 #include <ndtxt.hxx>
59 #include "wrtww8.hxx"
60 #include <fltini.hxx>
61 #include <fmtline.hxx>
62 #include <fmtpdsc.hxx>
63 #include <frmfmt.hxx>
64 #include <section.hxx>
65 #include <ftninfo.hxx>
66 #include <pagedesc.hxx>
67 #include <poolfmt.hxx>
68 #include <swdbdata.hxx>
69 
70 #include <editeng/unoprnms.hxx>
71 #include <editeng/editobj.hxx>
72 #include <editeng/outlobj.hxx>
73 #include <editeng/brushitem.hxx>
75 
76 #include <docary.hxx>
77 #include <numrule.hxx>
78 #include <charfmt.hxx>
79 #include <viewsh.hxx>
80 #include <viewopt.hxx>
81 
82 #include "ww8par.hxx"
83 #include "ww8scan.hxx"
84 #include <oox/token/properties.hxx>
86 #include <comphelper/sequence.hxx>
88 #include <rtl/ustrbuf.hxx>
89 #include <sal/log.hxx>
90 #include <vcl/font.hxx>
92 #include <tools/diagnose_ex.h>
93 
94 using namespace sax_fastparser;
95 using namespace ::comphelper;
96 using namespace ::com::sun::star;
97 using namespace ::oox;
98 
100 
101 using sw::mark::IMark;
102 
104 {
105  return *m_pAttrOutput;
106 }
107 
109 {
110  return *m_pAttrOutput;
111 }
112 
114 {
115  return *m_pSections;
116 }
117 
118 bool DocxExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
119 {
120  // TODO FIXME is this actually true for docx? - this is ~copied from WW8
121  if ( nScript == i18n::ScriptType::ASIAN )
122  {
123  // for asian in ww8, there is only one fontsize
124  // and one fontstyle (posture/weight)
125  switch ( nWhich )
126  {
127  case RES_CHRATR_FONTSIZE:
128  case RES_CHRATR_POSTURE:
129  case RES_CHRATR_WEIGHT:
130  return false;
131  default:
132  break;
133  }
134  }
135  else if ( nScript != i18n::ScriptType::COMPLEX )
136  {
137  // for western in ww8, there is only one fontsize
138  // and one fontstyle (posture/weight)
139  switch ( nWhich )
140  {
144  return false;
145  default:
146  break;
147  }
148  }
149  return true;
150 }
151 
152 void DocxExport::AppendBookmarks( const SwTextNode& rNode, sal_Int32 nCurrentPos, sal_Int32 nLen )
153 {
154  std::vector< OUString > aStarts;
155  std::vector< OUString > aEnds;
156 
157  IMarkVector aMarks;
158  if ( GetBookmarks( rNode, nCurrentPos, nCurrentPos + nLen, aMarks ) )
159  {
160  for ( IMark* pMark : aMarks )
161  {
162  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
163  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
164 
165  if ( nStart == nCurrentPos )
166  aStarts.push_back( pMark->GetName() );
167 
168  if ( nEnd == nCurrentPos )
169  aEnds.push_back( pMark->GetName() );
170  }
171  }
172 
173  const OUString& aStr( rNode.GetText() );
174  const sal_Int32 nEnd = aStr.getLength();
175 
176  if ( nCurrentPos == nEnd )
177  m_pAttrOutput->WriteFinalBookmarks_Impl( aStarts, aEnds );
178  else
179  m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
180 }
181 
182 void DocxExport::AppendBookmark( const OUString& rName )
183 {
184  std::vector< OUString > aStarts;
185  std::vector< OUString > aEnds;
186 
187  aStarts.push_back( rName );
188  aEnds.push_back( rName );
189 
190  m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
191 }
192 
193 void DocxExport::AppendAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen )
194 {
195  std::vector< OUString > aStarts;
196  std::vector< OUString > aEnds;
197 
198  IMarkVector aMarks;
199  if (GetAnnotationMarks(rAttrs, nCurrentPos, nCurrentPos + nLen, aMarks))
200  {
201  for ( IMark* pMark : aMarks )
202  {
203  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
204  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
205 
206  if ( nStart == nCurrentPos )
207  aStarts.push_back( pMark->GetName() );
208 
209  if ( nEnd == nCurrentPos )
210  aEnds.push_back( pMark->GetName() );
211  }
212  }
213 
214  m_pAttrOutput->WriteAnnotationMarks_Impl( aStarts, aEnds );
215 }
216 
218 {
219  // Just collect the bullets for now, numbering.xml is not yet started.
220  CollectGrfsOfBullets();
221 }
222 
223 OString DocxExport::AddRelation( const OUString& rType, const OUString& rTarget )
224 {
225  OUString sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
226  rType, rTarget, true );
227 
228  return sId.toUtf8();
229 }
230 
232 {
233  bool bRet( false );
234 
235  if (SfxItemState::SET != rFormat.GetItemState(RES_PARATR_NUMRULE, false))
236  {
237  if (const SwFormat *pParent = rFormat.DerivedFrom())
238  {
239  if (static_cast<const SwTextFormatColl*>(pParent)->IsAssignedToListLevelOfOutlineStyle())
240  {
241  ::sax_fastparser::FSHelperPtr pSerializer = m_pAttrOutput->GetSerializer( );
242  // Level 9 disables the outline
243  pSerializer->singleElementNS(XML_w, XML_outlineLvl, FSNS(XML_w, XML_val), "9");
244 
245  bRet = true;
246  }
247  }
248  }
249 
250  return bRet;
251 }
252 
254  const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const SwFrameFormat& rFirstPageFormat, sal_uInt8 nBreakCode )
255 {
256  m_nHeadersFootersInSection = 1;
257 
258  // document setting indicating the requirement of EVEN and ODD for both headers and footers
260  m_aSettings.evenAndOddHeaders = true;
261 
262  // Turn ON flag for 'Writing Headers \ Footers'
263  m_pAttrOutput->SetWritingHeaderFooter( true );
264 
265  // headers
266  if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
267  WriteHeaderFooter( &rLeftFormat, true, "even" );
268  else if ( m_aSettings.evenAndOddHeaders )
269  {
270  if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
271  WriteHeaderFooter( &rFormat, true, "even" );
272  else if ( m_bHasHdr && nBreakCode == 2 )
273  WriteHeaderFooter( nullptr, true, "even" );
274  }
275 
276  if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
277  WriteHeaderFooter( &rFormat, true, "default" );
278 
279  if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
280  WriteHeaderFooter( &rFirstPageFormat, true, "first" );
281 
282  if( (nHeadFootFlags & (nsHdFtFlags::WW8_HEADER_EVEN
283  | nsHdFtFlags::WW8_HEADER_ODD
284  | nsHdFtFlags::WW8_HEADER_FIRST)) == 0
285  && m_bHasHdr && nBreakCode == 2 ) // 2: nexPage
286  WriteHeaderFooter( nullptr, true, "default" );
287 
288 
289  // footers
290  if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
291  WriteHeaderFooter( &rLeftFormat, false, "even" );
292  else if ( m_aSettings.evenAndOddHeaders )
293  {
294  if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
295  WriteHeaderFooter( &rFormat, false, "even" );
296  else if ( m_bHasFtr && nBreakCode == 2 )
297  WriteHeaderFooter( nullptr, false, "even");
298  }
299 
300  if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
301  WriteHeaderFooter( &rFormat, false, "default" );
302 
303  if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
304  WriteHeaderFooter( &rFirstPageFormat, false, "first" );
305 
306  if( (nHeadFootFlags & (nsHdFtFlags::WW8_FOOTER_EVEN
307  | nsHdFtFlags::WW8_FOOTER_ODD
308  | nsHdFtFlags::WW8_FOOTER_FIRST)) == 0
309  && m_bHasFtr && nBreakCode == 2 ) // 2: nexPage
310  WriteHeaderFooter( nullptr, false, "default");
311 
312  // Turn OFF flag for 'Writing Headers \ Footers'
313  m_pAttrOutput->SetWritingHeaderFooter( false );
314 }
315 
316 void DocxExport::OutputField( const SwField* pField, ww::eField eFieldType, const OUString& rFieldCmd, FieldFlags nMode )
317 {
318  m_pAttrOutput->WriteField_Impl( pField, eFieldType, rFieldCmd, nMode );
319 }
320 
321 void DocxExport::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
322 {
323  m_pAttrOutput->WriteFormData_Impl( rFieldmark );
324 }
325 
326 void DocxExport::WriteHyperlinkData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
327 {
328 #if OSL_DEBUG_LEVEL > 1
329  fprintf( stderr, "TODO DocxExport::WriteHyperlinkData()\n" );
330 #endif
331 }
332 
333 void DocxExport::DoComboBox(const OUString& rName,
334  const OUString& rHelp,
335  const OUString& rToolTip,
336  const OUString& rSelected,
337  const uno::Sequence<OUString>& rListItems)
338 {
339  m_pDocumentFS->startElementNS(XML_w, XML_ffData);
340 
341  m_pDocumentFS->singleElementNS(XML_w, XML_name, FSNS(XML_w, XML_val), rName.toUtf8());
342 
343  m_pDocumentFS->singleElementNS(XML_w, XML_enabled);
344 
345  if ( !rHelp.isEmpty() )
346  m_pDocumentFS->singleElementNS(XML_w, XML_helpText, FSNS(XML_w, XML_val), rHelp.toUtf8());
347 
348  if ( !rToolTip.isEmpty() )
349  m_pDocumentFS->singleElementNS( XML_w, XML_statusText,
350  FSNS( XML_w, XML_val ), rToolTip.toUtf8() );
351 
352  m_pDocumentFS->startElementNS(XML_w, XML_ddList);
353 
354  // Output the 0-based index of the selected value
355  sal_Int32 nId = comphelper::findValue(rListItems, rSelected);
356  if (nId == -1)
357  nId = 0;
358 
359  m_pDocumentFS->singleElementNS(XML_w, XML_result, FSNS(XML_w, XML_val), OString::number(nId));
360 
361  // Loop over the entries
362 
363  for (const auto& rItem : rListItems)
364  {
365  m_pDocumentFS->singleElementNS( XML_w, XML_listEntry,
366  FSNS( XML_w, XML_val ), rItem.toUtf8() );
367  }
368 
369  m_pDocumentFS->endElementNS( XML_w, XML_ddList );
370 
371  m_pDocumentFS->endElementNS( XML_w, XML_ffData );
372 }
373 
375 {
376  assert(pField);
377  const OUString sStr = FieldString(ww::eFILLIN) + "\"" + pField->GetPar2() + "\"";
378  OutputField(pField, ww::eFILLIN, sStr);
379 }
380 
381 OString DocxExport::OutputChart( uno::Reference< frame::XModel > const & xModel, sal_Int32 nCount, ::sax_fastparser::FSHelperPtr const & m_pSerializer )
382 {
383  OUString aFileName = "charts/chart" + OUString::number(nCount) + ".xml";
384  OUString sId = m_pFilter->addRelation( m_pSerializer->getOutputStream(),
385  oox::getRelationship(Relationship::CHART),
386  aFileName );
387  aFileName = "word/charts/chart" + OUString::number(nCount) + ".xml";
389  m_pFilter->openFragmentStreamWithSerializer( aFileName,
390  "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" );
391 
392  oox::drawingml::ChartExport aChartExport(XML_w, pChartFS, xModel, m_pFilter, oox::drawingml::DOCUMENT_DOCX);
393  aChartExport.ExportContent();
394  return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
395 }
396 
397 OString DocxExport::WriteOLEObject(SwOLEObj& rObject, OUString & io_rProgID)
398 {
399  uno::Reference <embed::XEmbeddedObject> xObj( rObject.GetOleRef() );
400  uno::Reference<uno::XComponentContext> const xContext(
401  GetFilter().getComponentContext());
402 
403  OUString sMediaType;
404  OUString sRelationType;
405  OUString sSuffix;
406  const char * pProgID(nullptr);
407 
408  uno::Reference<io::XInputStream> const xInStream =
409  oox::GetOLEObjectStream(xContext, xObj, io_rProgID,
410  sMediaType, sRelationType, sSuffix, pProgID);
411 
412  if (!xInStream.is())
413  {
414  return OString();
415  }
416 
417  assert(!sMediaType.isEmpty());
418  assert(!sRelationType.isEmpty());
419  assert(!sSuffix.isEmpty());
420  OUString sFileName = "embeddings/oleObject" + OUString::number( ++m_nOLEObjects ) + "." + sSuffix;
421  uno::Reference<io::XOutputStream> const xOutStream =
422  GetFilter().openFragmentStream("word/" + sFileName, sMediaType);
423  assert(xOutStream.is()); // no reason why that could fail
424 
425  try
426  {
428  }
429  catch (uno::Exception const&)
430  {
431  TOOLS_WARN_EXCEPTION("sw.ww8", "DocxExport::WriteOLEObject");
432  return OString();
433  }
434 
435  OUString const sId = m_pFilter->addRelation( GetFS()->getOutputStream(),
436  sRelationType, sFileName );
437  if (pProgID)
438  {
439  io_rProgID = OUString::createFromAscii(pProgID);
440  }
441 
442  return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
443 }
444 
445 std::pair<OString, OString> DocxExport::WriteActiveXObject(const uno::Reference<drawing::XShape>& rxShape,
446  const uno::Reference<awt::XControlModel>& rxControlModel)
447 {
448  ++m_nActiveXControls;
449 
450  // Write out ActiveX binary
451  const OUString sBinaryFileName = "word/activeX/activeX" + OUString::number(m_nActiveXControls) + ".bin";
452 
453  OString sGUID;
454  OString sName;
455  uno::Reference<io::XStream> xOutStorage(m_pFilter->openFragmentStream(sBinaryFileName, "application/vnd.ms-office.activeX"), uno::UNO_QUERY);
456  if(xOutStorage.is())
457  {
458  oox::ole::OleStorage aOleStorage(m_pFilter->getComponentContext(), xOutStorage, false);
459  uno::Reference<io::XOutputStream> xOutputStream(aOleStorage.openOutputStream("contents"), uno::UNO_SET_THROW);
460  uno::Reference< css::frame::XModel > xModel( m_pDoc->GetDocShell() ? m_pDoc->GetDocShell()->GetModel() : nullptr );
462  if ( !exportHelper.isValid() )
463  return std::make_pair<OString, OString>(OString(), OString());
464  sGUID = OUStringToOString(exportHelper.getGUID(), RTL_TEXTENCODING_UTF8);
465  sName = OUStringToOString(exportHelper.getName(), RTL_TEXTENCODING_UTF8);
466  exportHelper.exportControl(xOutputStream, rxShape->getSize(), true);
467  aOleStorage.commit();
468  }
469 
470  // Write out ActiveX fragment
471  const OUString sXMLFileName = "word/activeX/activeX" + OUString::number( m_nActiveXControls ) + ".xml";
472  ::sax_fastparser::FSHelperPtr pActiveXFS = m_pFilter->openFragmentStreamWithSerializer(sXMLFileName, "application/vnd.ms-office.activeX+xml" );
473 
474  const OUString sBinaryId = m_pFilter->addRelation( pActiveXFS->getOutputStream(),
475  oox::getRelationship(Relationship::ACTIVEXCONTROLBINARY),
476  sBinaryFileName.copy(sBinaryFileName.lastIndexOf("/") + 1) );
477 
478  pActiveXFS->singleElementNS(XML_ax, XML_ocx,
479  FSNS(XML_xmlns, XML_ax), m_pFilter->getNamespaceURL(OOX_NS(ax)).toUtf8(),
480  FSNS(XML_xmlns, XML_r), m_pFilter->getNamespaceURL(OOX_NS(officeRel)).toUtf8(),
481  FSNS(XML_ax, XML_classid), "{" + sGUID + "}",
482  FSNS(XML_ax, XML_persistence), "persistStorage",
483  FSNS(XML_r, XML_id), sBinaryId.toUtf8());
484 
485  OString sXMLId = OUStringToOString(m_pFilter->addRelation(m_pDocumentFS->getOutputStream(),
486  oox::getRelationship(Relationship::CONTROL),
487  sXMLFileName.copy(sBinaryFileName.indexOf("/") + 1)),
488  RTL_TEXTENCODING_UTF8);
489 
490  return std::pair<OString, OString>(sXMLId, sName);
491 }
492 
493 void DocxExport::OutputDML(uno::Reference<drawing::XShape> const & xShape)
494 {
495  uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
496  sal_Int32 nNamespace = XML_wps;
497  if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
498  nNamespace = XML_wpg;
499  else if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
500  nNamespace = XML_pic;
501  oox::drawingml::ShapeExport aExport(nNamespace, m_pAttrOutput->GetSerializer(), nullptr, m_pFilter, oox::drawingml::DOCUMENT_DOCX, m_pAttrOutput.get());
502  aExport.WriteShape(xShape);
503 }
504 
506 {
507  // Set the 'Reviewing' flags in the settings structure
508  m_aSettings.revisionView = m_bOrigShowChanges;
509  m_aSettings.trackRevisions = bool( RedlineFlags::On & m_nOrigRedlineFlags );
510 
511  InitStyles();
512 
513  // init sections
514  m_pSections.reset(new MSWordSections( *this ));
515 
516  // Make sure images are counted from one, even when exporting multiple documents.
518 
519  WriteMainText();
520 
521  WriteFootnotesEndnotes();
522 
523  WritePostitFields();
524 
525  WriteNumbering();
526 
527  WriteFonts();
528 
529  WriteSettings();
530 
531  WriteTheme();
532 
533  WriteGlossary();
534 
535  WriteCustomXml();
536 
537  WriteEmbeddings();
538 
539  WriteVBA();
540 
541  m_aLinkedTextboxesHelper.clear(); //final cleanup
542  m_pStyles.reset();
543  m_pSections.reset();
544 
545  return ERRCODE_NONE;
546 }
547 
548 void DocxExport::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum )
549 {
550  AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
551  m_pSections->AppendSection( pPageDesc, pFormat, nLnNum, m_pAttrOutput->IsFirstParagraph() );
552 }
553 
554 void DocxExport::OutputEndNode( const SwEndNode& rEndNode )
555 {
557 
558  if ( TXT_MAINTEXT == m_nTextTyp && rEndNode.StartOfSectionNode()->IsSectionNode() )
559  {
560  // this originally comes from WW8Export::WriteText(), and looks like it
561  // could have some code common with SectionNode()...
562 
563  const SwSection& rSect = rEndNode.StartOfSectionNode()->GetSectionNode()->GetSection();
564  if ( m_bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
565  m_bStartTOX = false;
566 
567  SwNodeIndex aIdx( rEndNode, 1 );
568  const SwNode& rNd = aIdx.GetNode();
569  if ( rNd.IsEndNode() && rNd.StartOfSectionNode()->IsSectionNode() )
570  return;
571 
572  bool isInTable = IsInTable();
573  if ( !rNd.IsSectionNode() && isInTable ) // No sections in table
574  {
575  const SwSectionFormat* pParentFormat = rSect.GetFormat()->GetParent();
576  if( !pParentFormat )
577  pParentFormat = reinterpret_cast<SwSectionFormat*>(sal_IntPtr(-1));
578 
579  sal_uLong nRstLnNum;
580  if( rNd.IsContentNode() )
581  nRstLnNum = rNd.GetContentNode()->GetSwAttrSet().GetLineNumber().GetStartValue();
582  else
583  nRstLnNum = 0;
584 
585  AppendSection( m_pCurrentPageDesc, pParentFormat, nRstLnNum );
586  }
587  else
588  {
589  AttrOutput().SectionBreaks( rEndNode );
590  }
591  }
592  else if (TXT_MAINTEXT == m_nTextTyp && rEndNode.StartOfSectionNode()->IsTableNode())
593  // End node of a table: see if a section break should be written after the table.
594  AttrOutput().SectionBreaks(rEndNode);
595 }
596 
598 {
599  SAL_INFO("sw.ww8", "TODO DocxExport::OutputGrfNode( const SwGrfNode& )" );
600 }
601 
603 {
604  SAL_INFO("sw.ww8", "TODO DocxExport::OutputOLENode( const SwOLENode& )" );
605 }
606 
607 void DocxExport::OutputLinkedOLE( const OUString& )
608 {
609  // Nothing to implement here: WW8 only
610 }
611 
613 {
614  // Completely unused for Docx export... only here for code sharing
615  // purpose with binary export
616  return 0;
617 }
618 
620  const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat,
621  const SwPageDesc* pNewPgDesc )
622 {
623  // tell the attribute output that we are ready to write the section
624  // break [has to be output inside paragraph properties]
625  AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
626 
627  const SwSectionFormat* pFormat = GetSectionFormat( rNd );
628  const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
629 
630  OSL_ENSURE( pNewPgDescFormat || pNewPgDesc, "Neither page desc format nor page desc provided." );
631 
632  if ( pNewPgDescFormat )
633  {
634  m_pSections->AppendSection( *pNewPgDescFormat, rNd, pFormat, nLnNm );
635  }
636  else if ( pNewPgDesc )
637  {
638  m_pSections->AppendSection( pNewPgDesc, rNd, pFormat, nLnNm );
639  }
640 
641 }
642 
644 {
645  m_pStyles.reset(new MSWordStyles( *this, /*bListStyles =*/ true ));
646 
647  // setup word/styles.xml and the relations + content type
648  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
649  oox::getRelationship(Relationship::STYLES),
650  "styles.xml" );
651 
653  m_pFilter->openFragmentStreamWithSerializer( "word/styles.xml",
654  "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" );
655 
656  // switch the serializer to redirect the output to word/styles.xml
657  m_pAttrOutput->SetSerializer( pStylesFS );
658 
659  // do the work
660  m_pStyles->OutputStylesTable();
661 
662  // switch the serializer back
663  m_pAttrOutput->SetSerializer( m_pDocumentFS );
664 }
665 
667 {
668  if ( m_pAttrOutput->HasFootnotes() )
669  {
670  // setup word/styles.xml and the relations + content type
671  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
672  oox::getRelationship(Relationship::FOOTNOTES),
673  "footnotes.xml" );
674 
675  ::sax_fastparser::FSHelperPtr pFootnotesFS =
676  m_pFilter->openFragmentStreamWithSerializer( "word/footnotes.xml",
677  "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" );
678 
679  // switch the serializer to redirect the output to word/footnotes.xml
680  m_pAttrOutput->SetSerializer( pFootnotesFS );
681  // tdf#99227
682  m_pSdrExport->setSerializer( pFootnotesFS );
683  // tdf#107969
684  m_pVMLExport->SetFS(pFootnotesFS);
685 
686  // do the work
687  m_pAttrOutput->FootnotesEndnotes( true );
688 
689  // switch the serializer back
690  m_pVMLExport->SetFS(m_pDocumentFS);
691  m_pSdrExport->setSerializer( m_pDocumentFS );
692  m_pAttrOutput->SetSerializer( m_pDocumentFS );
693  }
694 
695  if ( m_pAttrOutput->HasEndnotes() )
696  {
697  // setup word/styles.xml and the relations + content type
698  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
699  oox::getRelationship(Relationship::ENDNOTES),
700  "endnotes.xml" );
701 
702  ::sax_fastparser::FSHelperPtr pEndnotesFS =
703  m_pFilter->openFragmentStreamWithSerializer( "word/endnotes.xml",
704  "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" );
705 
706  // switch the serializer to redirect the output to word/endnotes.xml
707  m_pAttrOutput->SetSerializer( pEndnotesFS );
708  // tdf#99227
709  m_pSdrExport->setSerializer( pEndnotesFS );
710  // tdf#107969
711  m_pVMLExport->SetFS(pEndnotesFS);
712 
713  // do the work
714  m_pAttrOutput->FootnotesEndnotes( false );
715 
716  // switch the serializer back
717  m_pVMLExport->SetFS(m_pDocumentFS);
718  m_pSdrExport->setSerializer( m_pDocumentFS );
719  m_pAttrOutput->SetSerializer( m_pDocumentFS );
720  }
721 }
722 
724 {
725  if ( m_pAttrOutput->HasPostitFields() )
726  {
727  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
728  oox::getRelationship(Relationship::COMMENTS),
729  "comments.xml" );
730 
732  m_pFilter->openFragmentStreamWithSerializer( "word/comments.xml",
733  "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" );
734 
735  pPostitFS->startElementNS( XML_w, XML_comments, MainXmlNamespaces());
736  m_pAttrOutput->SetSerializer( pPostitFS );
737  m_pAttrOutput->WritePostitFields();
738  m_pAttrOutput->SetSerializer( m_pDocumentFS );
739  pPostitFS->endElementNS( XML_w, XML_comments );
740  }
741 }
742 
744 {
745  if ( !m_pUsedNumTable )
746  return; // no numbering is used
747 
748  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
749  oox::getRelationship(Relationship::NUMBERING),
750  "numbering.xml" );
751 
752  ::sax_fastparser::FSHelperPtr pNumberingFS = m_pFilter->openFragmentStreamWithSerializer( "word/numbering.xml",
753  "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" );
754 
755  // switch the serializer to redirect the output to word/numbering.xml
756  m_pAttrOutput->SetSerializer( pNumberingFS );
757  m_pDrawingML->SetFS( pNumberingFS );
758 
759  pNumberingFS->startElementNS( XML_w, XML_numbering,
760  FSNS( XML_xmlns, XML_w ), m_pFilter->getNamespaceURL(OOX_NS(doc)).toUtf8(),
761  FSNS( XML_xmlns, XML_o ), m_pFilter->getNamespaceURL(OOX_NS(vmlOffice)).toUtf8(),
762  FSNS( XML_xmlns, XML_r ), m_pFilter->getNamespaceURL(OOX_NS(officeRel)).toUtf8(),
763  FSNS( XML_xmlns, XML_v ), m_pFilter->getNamespaceURL(OOX_NS(vml)).toUtf8() );
764 
765  BulletDefinitions();
766 
767  AbstractNumberingDefinitions();
768 
769  NumberingDefinitions();
770 
771  pNumberingFS->endElementNS( XML_w, XML_numbering );
772 
773  // switch the serializer back
774  m_pDrawingML->SetFS( m_pDocumentFS );
775  m_pAttrOutput->SetSerializer( m_pDocumentFS );
776 }
777 
778 void DocxExport::WriteHeaderFooter( const SwFormat* pFormat, bool bHeader, const char* pType )
779 {
780  // setup the xml stream
781  OUString aRelId;
783  if ( bHeader )
784  {
785  OUString aName( "header" + OUString::number( ++m_nHeaders ) + ".xml" );
786 
787  aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
788  oox::getRelationship(Relationship::HEADER),
789  aName );
790 
791  pFS = m_pFilter->openFragmentStreamWithSerializer( "word/" + aName,
792  "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" );
793 
794  pFS->startElementNS( XML_w, XML_hdr, MainXmlNamespaces());
795  }
796  else
797  {
798  OUString aName( "footer" + OUString::number( ++m_nFooters ) + ".xml" );
799 
800  aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
801  oox::getRelationship(Relationship::FOOTER),
802  aName );
803 
804  pFS = m_pFilter->openFragmentStreamWithSerializer( "word/" + aName,
805  "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" );
806 
807  pFS->startElementNS( XML_w, XML_ftr, MainXmlNamespaces());
808  }
809 
810  // switch the serializer to redirect the output to word/styles.xml
811  m_pAttrOutput->SetSerializer( pFS );
812  m_pVMLExport->SetFS( pFS );
813  m_pSdrExport->setSerializer(pFS);
814  SetFS( pFS );
815  {
816  DocxTableExportContext aTableExportContext(*m_pAttrOutput);
817  //When the stream changes the cache which is maintained for the graphics in case of alternate content is not cleared.
818  //So clearing the alternate content graphic cache.
819  m_pAttrOutput->PushRelIdCache();
820  // do the work
821  if (pFormat == nullptr)
822  AttrOutput().EmptyParagraph();
823  else
824  WriteHeaderFooterText(*pFormat, bHeader);
825  m_pAttrOutput->PopRelIdCache();
826  m_pAttrOutput->EndParaSdtBlock();
827  }
828 
829  // switch the serializer back
830  m_pAttrOutput->SetSerializer( m_pDocumentFS );
831  m_pVMLExport->SetFS( m_pDocumentFS );
832  m_pSdrExport->setSerializer(m_pDocumentFS);
833  SetFS( m_pDocumentFS );
834 
835  // close the tag
836  sal_Int32 nReference;
837  if ( bHeader )
838  {
839  pFS->endElementNS( XML_w, XML_hdr );
840  nReference = XML_headerReference;
841  }
842  else
843  {
844  pFS->endElementNS( XML_w, XML_ftr );
845  nReference = XML_footerReference;
846  }
847 
848  // and write the reference
849  m_pDocumentFS->singleElementNS( XML_w, nReference,
850  FSNS( XML_w, XML_type ), pType,
851  FSNS( XML_r, XML_id ), aRelId.toUtf8() );
852 }
853 
855 {
856  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
857  oox::getRelationship(Relationship::FONTTABLE),
858  "fontTable.xml" );
859 
860  ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openFragmentStreamWithSerializer(
861  "word/fontTable.xml",
862  "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" );
863 
864  pFS->startElementNS( XML_w, XML_fonts,
865  FSNS( XML_xmlns, XML_w ), m_pFilter->getNamespaceURL(OOX_NS(doc)).toUtf8(),
866  FSNS( XML_xmlns, XML_r ), m_pFilter->getNamespaceURL(OOX_NS(officeRel)).toUtf8() );
867 
868  // switch the serializer to redirect the output to word/styles.xml
869  m_pAttrOutput->SetSerializer( pFS );
870 
871  // do the work
872  m_aFontHelper.WriteFontTable( *m_pAttrOutput );
873 
874  // switch the serializer back
875  m_pAttrOutput->SetSerializer( m_pDocumentFS );
876 
877  pFS->endElementNS( XML_w, XML_fonts );
878 }
879 
881 {
882  // Write the core properties
883  SwDocShell* pDocShell( m_pDoc->GetDocShell( ) );
884  uno::Reference<document::XDocumentProperties> xDocProps;
885  bool bSecurityOptOpenReadOnly = false;
886  if ( pDocShell )
887  {
888  uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
889  pDocShell->GetModel( ), uno::UNO_QUERY );
890  xDocProps = xDPS->getDocumentProperties();
891  bSecurityOptOpenReadOnly = pDocShell->IsSecurityOptOpenReadOnly();
892  }
893 
894  m_pFilter->exportDocumentProperties( xDocProps, bSecurityOptOpenReadOnly );
895 }
896 
898 {
899  SwViewShell *pViewShell(m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell());
900  if( !pViewShell && !m_aSettings.hasData() && !m_pAttrOutput->HasFootnotes() && !m_pAttrOutput->HasEndnotes())
901  return;
902 
903  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
904  oox::getRelationship(Relationship::SETTINGS),
905  "settings.xml" );
906 
907  ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openFragmentStreamWithSerializer(
908  "word/settings.xml",
909  "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" );
910 
911  pFS->startElementNS( XML_w, XML_settings,
912  FSNS( XML_xmlns, XML_w ), m_pFilter->getNamespaceURL(OOX_NS(doc)).toUtf8() );
913 
914  // View
915  if (pViewShell && pViewShell->GetViewOptions()->getBrowseMode())
916  {
917  pFS->singleElementNS(XML_w, XML_view, FSNS(XML_w, XML_val), "web");
918  }
919 
920  // Zoom
921  if (pViewShell)
922  {
925 
926  switch (pViewShell->GetViewOptions()->GetZoomType())
927  {
928  case SvxZoomType::WHOLEPAGE:
929  pAttributeList->add(FSNS(XML_w, XML_val), "fullPage");
930  break;
931  case SvxZoomType::PAGEWIDTH:
932  pAttributeList->add(FSNS(XML_w, XML_val), "bestFit");
933  break;
934  case SvxZoomType::OPTIMAL:
935  pAttributeList->add(FSNS(XML_w, XML_val), "textFit");
936  break;
937  default:
938  break;
939  }
940 
941  OString aZoom(OString::number(pViewShell->GetViewOptions()->GetZoom()));
942  pAttributeList->add(FSNS(XML_w, XML_percent), aZoom);
943  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList.get());
944  pFS->singleElementNS(XML_w, XML_zoom, xAttributeList);
945  }
946 
947  // Display Background Shape
948  if (std::shared_ptr<SvxBrushItem> oBrush = getBackground(); oBrush)
949  {
950  // Turn on the 'displayBackgroundShape'
951  pFS->singleElementNS(XML_w, XML_displayBackgroundShape);
952  }
953 
954  // Track Changes
955  if ( !m_aSettings.revisionView )
956  pFS->singleElementNS( XML_w, XML_revisionView,
957  FSNS( XML_w, XML_insDel ), "0",
958  FSNS( XML_w, XML_formatting ), "0" );
959 
960  if ( m_aSettings.trackRevisions )
961  pFS->singleElementNS(XML_w, XML_trackRevisions);
962 
963  // Mirror Margins
964  if(isMirroredMargin())
965  pFS->singleElementNS(XML_w, XML_mirrorMargins);
966 
967  // Embed Fonts
968  if( m_pDoc->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_FONTS ))
969  pFS->singleElementNS(XML_w, XML_embedTrueTypeFonts);
970 
971  // Embed System Fonts
972  if( m_pDoc->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_SYSTEM_FONTS ))
973  pFS->singleElementNS(XML_w, XML_embedSystemFonts);
974 
975  // Default Tab Stop
976  if( m_aSettings.defaultTabStop != 0 )
977  pFS->singleElementNS( XML_w, XML_defaultTabStop, FSNS( XML_w, XML_val ),
978  OString::number(m_aSettings.defaultTabStop) );
979 
980  // Do not justify lines with manual break
981  if( m_pDoc->getIDocumentSettingAccess().get( DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK ))
982  {
983  pFS->startElementNS(XML_w, XML_compat);
984  pFS->singleElementNS(XML_w, XML_doNotExpandShiftReturn);
985  pFS->endElementNS( XML_w, XML_compat );
986  }
987 
988  // export current mail merge database and table names
989  SwDBData aData = m_pDoc->GetDBData();
990  if ( !aData.sDataSource.isEmpty() && aData.nCommandType == css::sdb::CommandType::TABLE && !aData.sCommand.isEmpty() )
991  {
992  OUString sDataSource =
993  "SELECT * FROM " +
994  aData.sDataSource + // current database
995  ".dbo." + // default database owner
996  aData.sCommand + // sheet name
997  "$"; // sheet identifier
998  pFS->startElementNS( XML_w, XML_mailMerge );
999  pFS->singleElementNS(XML_w, XML_mainDocumentType,
1000  FSNS( XML_w, XML_val ), "formLetters" );
1001  pFS->singleElementNS(XML_w, XML_dataType,
1002  FSNS( XML_w, XML_val ), "textFile" );
1003  pFS->singleElementNS( XML_w, XML_query,
1004  FSNS( XML_w, XML_val ), OUStringToOString( sDataSource, RTL_TEXTENCODING_UTF8 ).getStr() );
1005  pFS->endElementNS( XML_w, XML_mailMerge );
1006  }
1007 
1008  // Automatic hyphenation: it's a global setting in Word, it's a paragraph setting in Writer.
1009  // Use the setting from the default style.
1010  SwTextFormatColl* pColl = m_pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD, /*bRegardLanguage=*/false);
1011  const SfxPoolItem* pItem;
1012  if (pColl && SfxItemState::SET == pColl->GetItemState(RES_PARATR_HYPHENZONE, false, &pItem))
1013  {
1014  pFS->singleElementNS(XML_w, XML_autoHyphenation,
1015  FSNS(XML_w, XML_val), OString::boolean(static_cast<const SvxHyphenZoneItem*>(pItem)->IsHyphen()));
1016  }
1017 
1018  // Even and Odd Headers
1019  if( m_aSettings.evenAndOddHeaders )
1020  pFS->singleElementNS(XML_w, XML_evenAndOddHeaders);
1021 
1022  // Has Footnotes
1023  if( m_pAttrOutput->HasFootnotes())
1024  DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_footnotePr, m_pDoc->GetFootnoteInfo(), XML_footnote );
1025 
1026  // Has Endnotes
1027  if( m_pAttrOutput->HasEndnotes())
1028  DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_endnotePr, m_pDoc->GetEndNoteInfo(), XML_endnote );
1029 
1030  // Has themeFontLang information
1031  uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1032 
1033  bool hasProtectionProperties = false;
1034  bool bHasRedlineProtectionKey = false;
1035  bool bHasDummyRedlineProtectionKey = false;
1036  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1037  if ( xPropSetInfo->hasPropertyByName( "RedlineProtectionKey" ) )
1038  {
1039  uno::Sequence<sal_Int8> aKey;
1040  xPropSet->getPropertyValue( "RedlineProtectionKey" ) >>= aKey;
1041  bHasRedlineProtectionKey = aKey.hasElements();
1042  bHasDummyRedlineProtectionKey = aKey.getLength() == 1 && aKey[0] == 1;
1043  }
1044  const OUString aGrabBagName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1045  if ( xPropSetInfo->hasPropertyByName( aGrabBagName ) )
1046  {
1047  uno::Sequence< beans::PropertyValue > propList;
1048  xPropSet->getPropertyValue( aGrabBagName ) >>= propList;
1049 
1050  for( const auto& rProp : std::as_const(propList) )
1051  {
1052  if ( rProp.Name == "ThemeFontLangProps" )
1053  {
1054  uno::Sequence< beans::PropertyValue > themeFontLangProps;
1055  rProp.Value >>= themeFontLangProps;
1056  OUString aValues[3];
1057  for( const auto& rThemeFontLangProp : std::as_const(themeFontLangProps) )
1058  {
1059  if( rThemeFontLangProp.Name == "val" )
1060  rThemeFontLangProp.Value >>= aValues[0];
1061  else if( rThemeFontLangProp.Name == "eastAsia" )
1062  rThemeFontLangProp.Value >>= aValues[1];
1063  else if( rThemeFontLangProp.Name == "bidi" )
1064  rThemeFontLangProp.Value >>= aValues[2];
1065  }
1066  pFS->singleElementNS( XML_w, XML_themeFontLang,
1067  FSNS( XML_w, XML_val ), aValues[0].toUtf8(),
1068  FSNS( XML_w, XML_eastAsia ), aValues[1].toUtf8(),
1069  FSNS( XML_w, XML_bidi ), aValues[2].toUtf8() );
1070  }
1071  else if ( rProp.Name == "CompatSettings" )
1072  {
1073  pFS->startElementNS(XML_w, XML_compat);
1074 
1075  uno::Sequence< beans::PropertyValue > aCompatSettingsSequence;
1076  rProp.Value >>= aCompatSettingsSequence;
1077 
1078  for(const auto& rCompatSetting : std::as_const(aCompatSettingsSequence))
1079  {
1080  uno::Sequence< beans::PropertyValue > aCompatSetting;
1081  rCompatSetting.Value >>= aCompatSetting;
1082  OUString aName;
1083  OUString aUri;
1084  OUString aValue;
1085 
1086  for(const auto& rPropVal : std::as_const(aCompatSetting))
1087  {
1088  if( rPropVal.Name == "name" )
1089  rPropVal.Value >>= aName;
1090  else if( rPropVal.Name == "uri" )
1091  rPropVal.Value >>= aUri;
1092  else if( rPropVal.Name == "val" )
1093  rPropVal.Value >>= aValue;
1094  }
1095  pFS->singleElementNS( XML_w, XML_compatSetting,
1096  FSNS( XML_w, XML_name ), aName.toUtf8(),
1097  FSNS( XML_w, XML_uri ), aUri.toUtf8(),
1098  FSNS( XML_w, XML_val ), aValue.toUtf8());
1099  }
1100 
1101  pFS->endElementNS( XML_w, XML_compat );
1102  }
1103  else if (rProp.Name == "DocumentProtection")
1104  {
1105 
1106  uno::Sequence< beans::PropertyValue > rAttributeList;
1107  rProp.Value >>= rAttributeList;
1108 
1109  if (rAttributeList.hasElements())
1110  {
1112  bool bIsProtectionTrackChanges = false;
1113  for (const auto& rAttribute : std::as_const(rAttributeList))
1114  {
1115  static DocxStringTokenMap const aTokens[] =
1116  {
1117  { "edit", XML_edit },
1118  { "enforcement", XML_enforcement },
1119  { "formatting", XML_formatting },
1120  { "cryptProviderType", XML_cryptProviderType },
1121  { "cryptAlgorithmClass", XML_cryptAlgorithmClass },
1122  { "cryptAlgorithmType", XML_cryptAlgorithmType },
1123  { "cryptAlgorithmSid", XML_cryptAlgorithmSid },
1124  { "cryptSpinCount", XML_cryptSpinCount },
1125  { "hash", XML_hash },
1126  { "salt", XML_salt },
1127  { nullptr, 0 }
1128  };
1129 
1130  if (sal_Int32 nToken = DocxStringGetToken(aTokens, rAttribute.Name))
1131  {
1132  OUString sValue = rAttribute.Value.get<OUString>();
1133  pAttributeList->add(FSNS(XML_w, nToken), sValue.toUtf8());
1134  if ( nToken == XML_edit && sValue == "trackedChanges" )
1135  bIsProtectionTrackChanges = true;
1136  }
1137  }
1138 
1139  // we have document protection from input DOCX file
1140  // and in the case of change tracking protection, we didn't modify it
1141 
1142  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
1143  if (!bIsProtectionTrackChanges || bHasDummyRedlineProtectionKey)
1144  pFS->singleElementNS(XML_w, XML_documentProtection, xAttributeList);
1145 
1146  hasProtectionProperties = true;
1147  }
1148  }
1149  else if (rProp.Name == "HyphenationZone")
1150  {
1151  sal_Int16 nHyphenationZone;
1152  rProp.Value >>= nHyphenationZone;
1153  if (nHyphenationZone > 0)
1154  pFS->singleElementNS(XML_w, XML_hyphenationZone, FSNS(XML_w, XML_val),
1155  OString::number(nHyphenationZone));
1156  }
1157  }
1158  }
1159 
1160  // Protect form
1161  // Section-specific write protection
1162  if (! hasProtectionProperties)
1163  {
1164  if (m_pDoc->getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FORM) ||
1165  m_pSections->DocumentIsProtected())
1166  {
1167  // we have form protection from Writer or from input ODT file
1168 
1169  pFS->singleElementNS(XML_w, XML_documentProtection,
1170  FSNS(XML_w, XML_edit), "forms",
1171  FSNS(XML_w, XML_enforcement), "true");
1172  }
1173  }
1174 
1175  // Protect Change Tracking
1176  if ( bHasRedlineProtectionKey && !bHasDummyRedlineProtectionKey )
1177  {
1178  // we have change tracking protection from Writer or from input ODT file
1179 
1180  pFS->singleElementNS(XML_w, XML_documentProtection,
1181  FSNS(XML_w, XML_edit), "trackedChanges",
1182  FSNS(XML_w, XML_enforcement), "1");
1183  }
1184 
1185  // finish settings.xml
1186  pFS->endElementNS( XML_w, XML_settings );
1187 }
1188 
1190 {
1191  uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1192 
1193  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1195  if ( !xPropSetInfo->hasPropertyByName( aName ) )
1196  return;
1197 
1198  uno::Reference<xml::dom::XDocument> themeDom;
1199  uno::Sequence< beans::PropertyValue > propList;
1200  xPropSet->getPropertyValue( aName ) >>= propList;
1201  auto pProp = std::find_if(propList.begin(), propList.end(),
1202  [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXTheme"; });
1203  if (pProp != propList.end())
1204  pProp->Value >>= themeDom;
1205 
1206  // no theme dom to write
1207  if ( !themeDom.is() )
1208  return;
1209 
1210  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
1211  oox::getRelationship(Relationship::THEME),
1212  "theme/theme1.xml" );
1213 
1214  uno::Reference< xml::sax::XSAXSerializable > serializer( themeDom, uno::UNO_QUERY );
1215  uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1216  writer->setOutputStream( GetFilter().openFragmentStream( "word/theme/theme1.xml",
1217  "application/vnd.openxmlformats-officedocument.theme+xml" ) );
1218  serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1219  uno::Sequence< beans::StringPair >() );
1220 }
1221 
1223 {
1224  uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1225 
1226  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1228  if ( !xPropSetInfo->hasPropertyByName( aName ) )
1229  return;
1230 
1231  uno::Reference<xml::dom::XDocument> glossaryDocDom;
1232  uno::Sequence< uno::Sequence< uno::Any> > glossaryDomList;
1233  uno::Sequence< beans::PropertyValue > propList;
1234  xPropSet->getPropertyValue( aName ) >>= propList;
1235  sal_Int32 collectedProperties = 0;
1236  for ( const auto& rProp : std::as_const(propList) )
1237  {
1238  OUString propName = rProp.Name;
1239  if ( propName == "OOXGlossary" )
1240  {
1241  rProp.Value >>= glossaryDocDom;
1242  collectedProperties++;
1243  }
1244  if (propName == "OOXGlossaryDom")
1245  {
1246  rProp.Value >>= glossaryDomList;
1247  collectedProperties++;
1248  }
1249  if (collectedProperties == 2)
1250  break;
1251  }
1252 
1253  // no glossary dom to write
1254  if ( !glossaryDocDom.is() )
1255  return;
1256 
1257  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
1258  oox::getRelationship(Relationship::GLOSSARYDOCUMENT),
1259  "glossary/document.xml" );
1260 
1261  uno::Reference< io::XOutputStream > xOutputStream = GetFilter().openFragmentStream( "word/glossary/document.xml",
1262  "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml" );
1263 
1264  uno::Reference< xml::sax::XSAXSerializable > serializer( glossaryDocDom, uno::UNO_QUERY );
1265  uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1266  writer->setOutputStream( xOutputStream );
1267  serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1268  uno::Sequence< beans::StringPair >() );
1269 
1270  for ( const uno::Sequence< uno::Any>& glossaryElement : std::as_const(glossaryDomList))
1271  {
1272  OUString gTarget, gType, gId, contentType;
1273  uno::Reference<xml::dom::XDocument> xDom;
1274  glossaryElement[0] >>= xDom;
1275  glossaryElement[1] >>= gId;
1276  glossaryElement[2] >>= gType;
1277  glossaryElement[3] >>= gTarget;
1278  glossaryElement[4] >>= contentType;
1279  gId = gId.copy(3); //"rId" only save the numeric value
1280 
1281  PropertySet aProps(xOutputStream);
1282  aProps.setAnyProperty( PROP_RelId, uno::makeAny( gId.toInt32() ));
1283  m_pFilter->addRelation( xOutputStream, gType, gTarget);
1284  uno::Reference< xml::sax::XSAXSerializable > gserializer( xDom, uno::UNO_QUERY );
1285  writer->setOutputStream(GetFilter().openFragmentStream( "word/glossary/" + gTarget, contentType ) );
1286  gserializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1287  uno::Sequence< beans::StringPair >() );
1288  }
1289 }
1290 
1292 {
1293  uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1294 
1295  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1296  static const OUString aName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1297  if ( !xPropSetInfo->hasPropertyByName( aName ) )
1298  return;
1299 
1300  uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomlist;
1301  uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomPropslist;
1302  uno::Sequence< beans::PropertyValue > propList;
1303  xPropSet->getPropertyValue( aName ) >>= propList;
1304  auto pProp = std::find_if(propList.begin(), propList.end(),
1305  [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXCustomXml"; });
1306  if (pProp != propList.end())
1307  pProp->Value >>= customXmlDomlist;
1308 
1309  pProp = std::find_if(propList.begin(), propList.end(),
1310  [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXCustomXmlProps"; });
1311  if (pProp != propList.end())
1312  pProp->Value >>= customXmlDomPropslist;
1313 
1314  for (sal_Int32 j = 0; j < customXmlDomlist.getLength(); j++)
1315  {
1316  uno::Reference<xml::dom::XDocument> customXmlDom = customXmlDomlist[j];
1317  uno::Reference<xml::dom::XDocument> customXmlDomProps = customXmlDomPropslist[j];
1318  if (customXmlDom.is())
1319  {
1320  m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
1321  oox::getRelationship(Relationship::CUSTOMXML),
1322  "../customXml/item"+OUString::number((j+1))+".xml" );
1323 
1324  uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDom, uno::UNO_QUERY );
1325  uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1326  writer->setOutputStream( GetFilter().openFragmentStream( "customXml/item"+OUString::number((j+1))+".xml",
1327  "application/xml" ) );
1328  serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1329  uno::Sequence< beans::StringPair >() );
1330  }
1331 
1332  if (customXmlDomProps.is())
1333  {
1334  uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDomProps, uno::UNO_QUERY );
1335  uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1336  writer->setOutputStream( GetFilter().openFragmentStream( "customXml/itemProps"+OUString::number((j+1))+".xml",
1337  "application/vnd.openxmlformats-officedocument.customXmlProperties+xml" ) );
1338  serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1339  uno::Sequence< beans::StringPair >() );
1340 
1341  // Adding itemprops's relationship entry to item.xml.rels file
1342  m_pFilter->addRelation( GetFilter().openFragmentStream( "customXml/item"+OUString::number((j+1))+".xml",
1343  "application/xml" ) ,
1344  oox::getRelationship(Relationship::CUSTOMXMLPROPS),
1345  "itemProps"+OUString::number((j+1))+".xml" );
1346  }
1347  }
1348 }
1349 
1351 {
1352  uno::Reference<document::XStorageBasedDocument> xStorageBasedDocument(m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
1353  if (!xStorageBasedDocument.is())
1354  return;
1355 
1356  uno::Reference<embed::XStorage> xDocumentStorage = xStorageBasedDocument->getDocumentStorage();
1357  OUString aMacrosName("_MS_VBA_Macros");
1358  if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aMacrosName))
1359  return;
1360 
1361  const sal_Int32 nOpenMode = embed::ElementModes::READ;
1362  uno::Reference<io::XStream> xMacrosStream = xDocumentStorage->openStreamElement(aMacrosName, nOpenMode);
1363  uno::Reference<io::XOutputStream> xProjectStream;
1364  if (xMacrosStream.is())
1365  {
1366  // First handle the project stream, this sets xProjectStream.
1367  std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xMacrosStream));
1368 
1369  xProjectStream = GetFilter().openFragmentStream("word/vbaProject.bin", "application/vnd.ms-office.vbaProject");
1370  uno::Reference<io::XStream> xOutputStream(xProjectStream, uno::UNO_QUERY);
1371  if (!xOutputStream.is())
1372  return;
1373  std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
1374 
1375  // Write the stream.
1376  pOut->WriteStream(*pIn);
1377 
1378  // Write the relationship.
1379  m_pFilter->addRelation(m_pDocumentFS->getOutputStream(), oox::getRelationship(Relationship::VBAPROJECT), "vbaProject.bin");
1380  }
1381 
1382  OUString aDataName("_MS_VBA_Macros_XML");
1383  if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aDataName))
1384  return;
1385 
1386  uno::Reference<io::XStream> xDataStream = xDocumentStorage->openStreamElement(aDataName, nOpenMode);
1387  if (xDataStream.is())
1388  {
1389  // Then the data stream, which wants to work with an already set
1390  // xProjectStream.
1391  std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xDataStream));
1392 
1393  uno::Reference<io::XStream> xOutputStream(GetFilter().openFragmentStream("word/vbaData.xml", "application/vnd.ms-word.vbaData+xml"), uno::UNO_QUERY);
1394  if (!xOutputStream.is())
1395  return;
1396  std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
1397 
1398  // Write the stream.
1399  pOut->WriteStream(*pIn);
1400 
1401  // Write the relationship.
1402  if (!xProjectStream.is())
1403  return;
1404 
1405  m_pFilter->addRelation(xProjectStream, oox::getRelationship(Relationship::WORDVBADATA), "vbaData.xml");
1406  }
1407 }
1408 
1410 {
1411  uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1412 
1413  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1415  if ( !xPropSetInfo->hasPropertyByName( aName ) )
1416  return;
1417 
1418  uno::Sequence< beans::PropertyValue > embeddingsList;
1419  uno::Sequence< beans::PropertyValue > propList;
1420  xPropSet->getPropertyValue( aName ) >>= propList;
1421  auto pProp = std::find_if(propList.begin(), propList.end(),
1422  [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXEmbeddings"; });
1423  if (pProp != propList.end())
1424  pProp->Value >>= embeddingsList;
1425  for (const auto& rEmbedding : std::as_const(embeddingsList))
1426  {
1427  OUString embeddingPath = rEmbedding.Name;
1428  uno::Reference<io::XInputStream> embeddingsStream;
1429  rEmbedding.Value >>= embeddingsStream;
1430 
1431  OUString contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
1432  // FIXME: this .xlsm hack is silly - if anything the mime-type for an existing embedded object should be read from [Content_Types].xml
1433  if (embeddingPath.endsWith(".xlsm"))
1434  contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
1435  else if (embeddingPath.endsWith(".bin"))
1436  contentType = "application/vnd.openxmlformats-officedocument.oleObject";
1437 
1438  if ( embeddingsStream.is() )
1439  {
1440  uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream(embeddingPath,
1441  contentType);
1442  try
1443  {
1444  sal_Int32 nBufferSize = 512;
1445  uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize);
1446  sal_Int32 nRead;
1447  do
1448  {
1449  nRead = embeddingsStream->readBytes( aDataBuffer, nBufferSize );
1450  if( nRead )
1451  {
1452  if( nRead < nBufferSize )
1453  {
1454  nBufferSize = nRead;
1455  aDataBuffer.realloc(nRead);
1456  }
1457  xOutStream->writeBytes( aDataBuffer );
1458  }
1459  }
1460  while( nRead );
1461  xOutStream->flush();
1462  }
1463  catch(const uno::Exception&)
1464  {
1465  TOOLS_WARN_EXCEPTION("sw.ww8", "WriteEmbeddings() ::Failed to copy Inputstream to outputstream exception caught");
1466  }
1467  xOutStream->closeOutput();
1468  }
1469  }
1470 }
1471 
1473 {
1474  bool bMirroredMargins = false;
1475  if ( UseOnPage::Mirror == (UseOnPage::Mirror & m_pDoc->GetPageDesc(0).ReadUseOn()) )
1476  {
1477  bMirroredMargins = true;
1478  }
1479  return bMirroredMargins;
1480 }
1481 
1483 {
1484  // setup the namespaces
1485  m_pDocumentFS->startElementNS( XML_w, XML_document, MainXmlNamespaces());
1486 
1487  if ( getenv("SW_DEBUG_DOM") )
1488  {
1489  m_pDoc->dumpAsXml();
1490  }
1491 
1492  // reset the incrementing linked-textboxes chain ID before re-saving.
1493  m_nLinkedTextboxesChainId=0;
1494  m_aLinkedTextboxesHelper.clear();
1495 
1496  // Write background page color
1497  if (std::shared_ptr<SvxBrushItem> oBrush = getBackground(); oBrush)
1498  {
1499  Color backgroundColor = oBrush->GetColor();
1500  OString aBackgroundColorStr = msfilter::util::ConvertColor(backgroundColor);
1501 
1502  m_pDocumentFS->singleElementNS(XML_w, XML_background, FSNS(XML_w, XML_color),
1503  aBackgroundColorStr);
1504  }
1505 
1506  // body
1507  m_pDocumentFS->startElementNS(XML_w, XML_body);
1508 
1509  m_pCurPam->GetPoint()->nNode = m_pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
1510 
1511  // the text
1512  WriteText();
1513 
1514  // clear linked textboxes since old ones can't be linked to frames in a different section (correct?)
1515  m_aLinkedTextboxesHelper.clear();
1516 
1517  // the last section info
1518  m_pAttrOutput->EndParaSdtBlock();
1519  const WW8_SepInfo *pSectionInfo = m_pSections? m_pSections->CurrentSectionInfo(): nullptr;
1520  if ( pSectionInfo )
1521  SectionProperties( *pSectionInfo );
1522 
1523  // finish body and document
1524  m_pDocumentFS->endElementNS( XML_w, XML_body );
1525  m_pDocumentFS->endElementNS( XML_w, XML_document );
1526 }
1527 
1529 {
1531  pAttr->add( FSNS( XML_xmlns, XML_o ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(vmlOffice)), RTL_TEXTENCODING_UTF8).getStr() );
1532  pAttr->add( FSNS( XML_xmlns, XML_r ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(officeRel)), RTL_TEXTENCODING_UTF8).getStr() );
1533  pAttr->add( FSNS( XML_xmlns, XML_v ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(vml)), RTL_TEXTENCODING_UTF8).getStr() );
1534  pAttr->add( FSNS( XML_xmlns, XML_w ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(doc)), RTL_TEXTENCODING_UTF8).getStr() );
1535  pAttr->add( FSNS( XML_xmlns, XML_w10 ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(vmlWord)), RTL_TEXTENCODING_UTF8).getStr() );
1536  pAttr->add( FSNS( XML_xmlns, XML_wp ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(dmlWordDr)), RTL_TEXTENCODING_UTF8).getStr() );
1537  pAttr->add( FSNS( XML_xmlns, XML_wps ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(wps)), RTL_TEXTENCODING_UTF8).getStr() );
1538  pAttr->add( FSNS( XML_xmlns, XML_wpg ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(wpg)), RTL_TEXTENCODING_UTF8).getStr() );
1539  pAttr->add( FSNS( XML_xmlns, XML_mc ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(mce)), RTL_TEXTENCODING_UTF8).getStr() );
1540  pAttr->add( FSNS( XML_xmlns, XML_wp14 ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(wp14)), RTL_TEXTENCODING_UTF8).getStr() );
1541  pAttr->add( FSNS( XML_xmlns, XML_w14 ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(w14)), RTL_TEXTENCODING_UTF8).getStr() );
1542  pAttr->add( FSNS( XML_mc, XML_Ignorable ), "w14 wp14" );
1543  return XFastAttributeListRef( pAttr );
1544 }
1545 
1546 bool DocxExport::ignoreAttributeForStyleDefaults( sal_uInt16 nWhich ) const
1547 {
1548  if( nWhich == RES_TEXTGRID )
1549  return true; // w:docGrid is written only to document.xml, not to styles.xml
1550  if (nWhich == RES_PARATR_HYPHENZONE)
1551  return true; // w:suppressAutoHyphens is only a formatting exception, not a default
1553 }
1554 
1556 {
1557  const EditTextObject& rEditObj = rParaObj.GetTextObject();
1558  MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
1559 
1560  sal_Int32 nPara = rEditObj.GetParagraphCount();
1561  for( sal_Int32 n = 0; n < nPara; ++n )
1562  {
1563  if( n )
1564  aAttrIter.NextPara( n );
1565 
1566  AttrOutput().StartParagraph( ww8::WW8TableNodeInfo::Pointer_t());
1567  rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
1568  OUString aStr( rEditObj.GetText( n ));
1569  sal_Int32 nCurrentPos = 0;
1570  const sal_Int32 nEnd = aStr.getLength();
1571  do {
1572  AttrOutput().StartRun( nullptr, 0 );
1573  const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
1574  rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
1575 
1576  bool bTextAtr = aAttrIter.IsTextAttr( nCurrentPos );
1577  if( !bTextAtr )
1578  {
1579  if( nCurrentPos == 0 && nNextAttr - nCurrentPos == aStr.getLength())
1580  AttrOutput().RunText( aStr, eChrSet );
1581  else
1582  {
1583  OUString tmp( aStr.copy( nCurrentPos, nNextAttr - nCurrentPos ));
1584  AttrOutput().RunText( tmp, eChrSet );
1585  }
1586  }
1587  AttrOutput().StartRunProperties();
1588  aAttrIter.OutAttr( nCurrentPos );
1589  AttrOutput().EndRunProperties( nullptr );
1590 
1591  nCurrentPos = nNextAttr;
1592  eChrSet = eNextChrSet;
1593  aAttrIter.NextPos();
1594 
1595  AttrOutput().EndRun( nullptr, 0 );
1596 
1597  } while( nCurrentPos < nEnd );
1598 // aAttrIter.OutParaAttr(false);
1599  AttrOutput().EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t());
1600  }
1601 }
1602 
1604 {
1605  mpFS = pFS;
1606 }
1607 
1609  std::shared_ptr<SwUnoCursor> & pCurrentPam,
1610  SwPaM* pOriginalPam, bool bDocm, bool bTemplate)
1611  : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
1612  m_pFilter( pFilter ),
1613  m_nHeaders( 0 ),
1614  m_nFooters( 0 ),
1615  m_nOLEObjects( 0 ),
1616  m_nActiveXControls( 0 ),
1617  m_nHeadersFootersInSection(0),
1618  m_bDocm(bDocm),
1619  m_bTemplate(bTemplate)
1620 {
1621  // Write the document properties
1622  WriteProperties( );
1623 
1624  // relations for the document
1625  m_pFilter->addRelation( oox::getRelationship(Relationship::OFFICEDOCUMENT),
1626  "word/document.xml" );
1627 
1628  // Set media type depending of document type
1629  OUString aMediaType;
1630  if (m_bDocm)
1631  {
1632  if (m_bTemplate)
1633  {
1634  aMediaType = "application/vnd.ms-word.template.macroEnabledTemplate.main+xml";
1635  }
1636  else
1637  {
1638  aMediaType = "application/vnd.ms-word.document.macroEnabled.main+xml";
1639  }
1640  }
1641  else
1642  {
1643  if (m_bTemplate)
1644  {
1645  aMediaType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml";
1646  }
1647  else
1648  {
1649  aMediaType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
1650  }
1651  }
1652 
1653 
1654  // the actual document
1655  m_pDocumentFS = m_pFilter->openFragmentStreamWithSerializer( "word/document.xml", aMediaType );
1656 
1658 
1659  // the DrawingML access
1661 
1662  // the attribute output for the document
1663  m_pAttrOutput.reset(new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML.get() ));
1664 
1665  // the related VMLExport
1666  m_pVMLExport.reset(new VMLExport( m_pDocumentFS, m_pAttrOutput.get() ));
1667 
1668  // the related drawing export
1669  m_pSdrExport.reset(new DocxSdrExport( *this, m_pDocumentFS, m_pDrawingML.get() ));
1670 }
1671 
1673 {
1674 }
1675 
1677 : evenAndOddHeaders( false )
1678 , defaultTabStop( 0 )
1679 , revisionView( true )
1680 , trackRevisions( false )
1681 {
1682 }
1683 
1685 {
1686  if( evenAndOddHeaders )
1687  return true;
1688  if( defaultTabStop != 0 )
1689  return true;
1690  if ( !revisionView )
1691  return true;
1692  if ( trackRevisions )
1693  return true;
1694 
1695  return false;
1696 }
1697 
1698 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void WriteFootnotesEndnotes()
Write footnotes.xml and endnotes.xml.
Definition: docxexport.cxx:666
bool IsHyphen(sal_Unicode cChar)
#define RES_CHRATR_WEIGHT
Definition: hintids.hxx:84
void OutAttr(sal_Int32 nSwPos)
Definition: wrtw8esh.cxx:1128
void InitStyles()
Setup pStyles and write styles.xml.
Definition: docxexport.cxx:643
virtual void DoFormText(const SwInputField *pField) override
Definition: docxexport.cxx:374
sal_Int32 WhereNext() const
Definition: wrtww8.hxx:1487
virtual void OutputLinkedOLE(const OUString &) override
Definition: docxexport.cxx:607
const char * sGUID
std::unique_ptr< oox::vml::VMLExport > m_pVMLExport
Exporter of the VML shapes.
Definition: docxexport.hxx:101
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
bool hasData() const
const HdFtFlags WW8_FOOTER_FIRST
Definition: ww8scan.hxx:1593
Class to collect and output the sections/headers/footers.
Definition: wrtww8.hxx:198
DocxAttributeOutput & DocxAttrOutput() const
Access to the derived attribute output class.
Definition: docxexport.cxx:108
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
The class that has handlers for various resource types when exporting as DOCX.
Handles DOCX export of drawings.
bool IsSectionNode() const
Definition: node.hxx:644
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) override
Return value indicates if an inherited outline numbering is suppressed.
Definition: docxexport.cxx:231
#define RES_CHRATR_FONTSIZE
Definition: hintids.hxx:77
rtl_TextEncoding GetNodeCharSet() const
Definition: wrtww8.hxx:1489
static FastAttributeList * createAttrList()
const OUString & GetText() const
Definition: ndtxt.hxx:210
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
virtual void OutputEndNode(const SwEndNode &)
Output SwEndNode.
Definition: wrtww8.cxx:4255
virtual void AppendBookmarks(const SwTextNode &rNode, sal_Int32 nCurrentPos, sal_Int32 nLen) override
Definition: docxexport.cxx:152
css::uno::Reference< css::xml::sax::XFastAttributeList > XFastAttributeListRef
std::pair< OString, OString > WriteActiveXObject(const uno::Reference< css::drawing::XShape > &rxShape, const uno::Reference< awt::XControlModel > &rxControlModel)
Definition: docxexport.cxx:445
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
#define RES_CHRATR_CJK_POSTURE
Definition: hintids.hxx:94
bool IsSecurityOptOpenReadOnly() const
sal_uIntPtr sal_uLong
OUString sDataSource
Definition: swdbdata.hxx:30
virtual void WriteHyperlinkData(const ::sw::mark::IFieldmark &rFieldmark) override
Definition: docxexport.cxx:326
Base class of all fields.
Definition: fldbas.hxx:280
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:913
bool const m_bDocm
If the result will be a .docm file or not.
Definition: docxexport.hxx:107
Definition: doc.hxx:185
sal_Int16 nId
#define RES_CHRATR_CJK_WEIGHT
Definition: hintids.hxx:95
All the information that should be stashed away when we're in the middle of of a table export and sti...
SwNode & GetNode() const
Definition: ndindex.hxx:119
void WriteSettings()
Write word/settings.xml.
Definition: docxexport.cxx:897
void WriteGlossary()
SwSectionFormat * GetFormat()
Definition: section.hxx:336
for(size_t a(0);a< count;a++)
void WriteFonts()
Write word/fontTable.xml.
Definition: docxexport.cxx:854
virtual void WriteHeadersFooters(sal_uInt8 nHeadFootFlags, const SwFrameFormat &rFormat, const SwFrameFormat &rLeftFormat, const SwFrameFormat &rFirstPageFormat, sal_uInt8 nBreakCode) override
Output the actual headers and footers.
Definition: docxexport.cxx:253
#define RES_CHRATR_CJK_FONTSIZE
Definition: hintids.hxx:92
virtual void OutputGrfNode(const SwGrfNode &) override
Output SwGrfNode.
Definition: docxexport.cxx:597
void WriteCustomXml()
Write customXml/item[n].xml and customXml/itemProps[n].xml.
bool isMirroredMargin()
return true if Page Layout is set as Mirrored
Used to export formatted text associated to drawings.
Definition: wrtww8.hxx:1451
sax_fastparser::XFastAttributeListRef MainXmlNamespaces()
All xml namespaces to be used at the top of any text .xml file (main doc, headers, footers,...)
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2588
const SwSection & GetSection() const
Definition: node.hxx:541
static void WriteFootnoteEndnotePr(::sax_fastparser::FSHelperPtr const &fs, int tag, const SwEndNoteInfo &info, int listtag)
writes the footnotePr/endnotePr (depending on tag) section
FieldFlags
Definition: wrtww8.hxx:146
std::unique_ptr< DocxAttributeOutput > m_pAttrOutput
Attribute output for document.
Definition: docxexport.hxx:80
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
bool const m_bTemplate
Export is done into template (.dotx)
Definition: docxexport.hxx:110
Class to collect and output the styles table.
Definition: wrtww8.hxx:1567
virtual bool ignoreAttributeForStyleDefaults(sal_uInt16 nWhich) const override
Used to filter out attributes that can be e.g. written to .doc but not to .docx.
virtual AttributeOutputBase & AttrOutput() const override
Access to the attribute output class.
Definition: docxexport.cxx:103
ShapeExport & WriteShape(const css::uno::Reference< css::drawing::XShape > &xShape)
OString OutputChart(css::uno::Reference< css::frame::XModel > const &xModel, sal_Int32 nCount,::sax_fastparser::FSHelperPtr const &m_pSerializer)
Returns the relationd id.
Definition: docxexport.cxx:381
eField
Definition: fields.hxx:26
void WritePostitFields()
Write comments.xml.
Definition: docxexport.cxx:723
const HdFtFlags WW8_FOOTER_EVEN
Definition: ww8scan.hxx:1590
sal_uLong GetStartValue() const
Definition: fmtline.hxx:57
#define RES_PARATR_NUMRULE
Definition: hintids.hxx:171
OString WriteOLEObject(SwOLEObj &rObject, OUString &io_rProgID)
Definition: docxexport.cxx:397
void WriteOutliner(const OutlinerParaObject &rOutliner, sal_uInt8 nTyp)
RedlineFlags on.
virtual void AppendSection(const SwPageDesc *pPageDesc, const SwSectionFormat *pFormat, sal_uLong nLnNum) override
Definition: docxexport.cxx:548
void WriteHeaderFooter(const SwFormat *pFormat, bool bHeader, const char *pType)
Write reference to a header/footer + the actual xml containing the text.
Definition: docxexport.cxx:778
OString AddRelation(const OUString &rType, const OUString &rTarget)
Returns the relationd id.
Definition: docxexport.cxx:223
OUString getRelationship(Relationship eRelationship)
virtual MSWordSections & Sections() const override
Access to the sections/headers/footres.
Definition: docxexport.cxx:113
#define UNO_NAME_MISC_OBJ_INTEROPGRABBAG
virtual void AppendAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen) override
Definition: docxexport.cxx:193
if(nullptr==pCandidateA||nullptr==pCandidateB)
OUString GetText(sal_Int32 nPara) const
bool getOutputStream(ProgramOptions const &options, OString const &extension, std::ostream **ppOutputStream, OString &targetSourceFileName, OString &tmpSourceFileName)
const HdFtFlags WW8_HEADER_ODD
Definition: ww8scan.hxx:1589
Base class for various Writer styles.
Definition: format.hxx:43
void WriteEmbeddings()
Write word/embeddings/Worksheet[n].xlsx.
bool IsContentNode() const
Definition: node.hxx:628
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
const EditTextObject & GetTextObject() const
::sax_fastparser::FSHelperPtr openFragmentStreamWithSerializer(const OUString &rStreamName, const OUString &rMediaType)
void WriteProperties()
Write docProps/core.xml.
Definition: docxexport.cxx:880
Style of a layout element.
Definition: frmfmt.hxx:57
#define TOOLS_WARN_EXCEPTION(area, stream)
virtual bool CollapseScriptsforWordOk(sal_uInt16 nScript, sal_uInt16 nWhich) override
Guess the script (asian/western).
Definition: docxexport.cxx:118
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
OUString sName
void OutputDML(css::uno::Reference< css::drawing::XShape > const &xShape)
Writes the shape using drawingML syntax.
Definition: docxexport.cxx:493
SwContentNode * GetContentNode()
Definition: node.hxx:615
#define RES_PARATR_HYPHENZONE
Definition: hintids.hxx:168
sal_Int32 DocxStringGetToken(DocxStringTokenMap const *pMap, const OUString &rName)
std::unique_ptr< oox::drawingml::DrawingML > m_pDrawingML
Access to the DrawingML writer.
Definition: docxexport.hxx:77
virtual void DoComboBox(const OUString &rName, const OUString &rHelp, const OUString &ToolTip, const OUString &rSelected, const css::uno::Sequence< OUString > &rListItems) override
Definition: docxexport.cxx:333
OString ConvertColor(const Color &rColor)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:396
Marks a node in the document model.
Definition: ndindex.hxx:31
bool IsEndNode() const
Definition: node.hxx:632
GUIDCNamePair const aData
virtual void OutputOLENode(const SwOLENode &) override
Output SwOLENode.
Definition: docxexport.cxx:602
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
DocxExport(DocxExportFilter *pFilter, SwDoc *pDocument, std::shared_ptr< SwUnoCursor > &pCurrentPam, SwPaM *pOriginalPam, bool bDocm, bool bTemplate)
Pass the pDocument, pCurrentPam and pOriginalPam to the base class.
void SetFS(::sax_fastparser::FSHelperPtr const &mpFS)
std::shared_ptr< FastSerializerHelper > FSHelperPtr
virtual void OutputEndNode(const SwEndNode &) override
Output SwEndNode.
Definition: docxexport.cxx:554
SwSectionFormat * GetParent() const
Definition: section.hxx:355
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
std::unique_ptr< DocxSdrExport > m_pSdrExport
Exporter of drawings.
Definition: docxexport.hxx:104
sal_Int32 GetParagraphCount() const
virtual void WriteNumbering() override
Write the numbering table.
Definition: docxexport.cxx:743
SwFormat * DerivedFrom() const
Definition: format.hxx:108
OUString addRelation(const OUString &rType, const OUString &rTarget)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual sal_uLong ReplaceCr(sal_uInt8 nChar) override
Definition: docxexport.cxx:612
virtual void PrepareNewPageDesc(const SfxItemSet *pSet, const SwNode &rNd, const SwFormatPageDesc *pNewPgDescFormat, const SwPageDesc *pNewPgDesc) override
Get ready for a new section.
Definition: docxexport.cxx:619
::sax_fastparser::FSHelperPtr m_pDocumentFS
Fast serializer for the document output.
Definition: docxexport.hxx:71
#define RES_TEXTGRID
Definition: hintids.hxx:222
void WriteVBA()
Writes word/vbaProject.bin.
DocxExportFilter * m_pFilter
Pointer to the filter that owns us.
Definition: docxexport.hxx:68
#define ERRCODE_NONE
unsigned char sal_uInt8
#define RES_CHRATR_POSTURE
Definition: hintids.hxx:80
bool IsTextAttr(sal_Int32 nSwPos)
Definition: wrtw8esh.cxx:1208
#define SAL_INFO(area, stream)
virtual ErrCode ExportDocument_Impl() override
Format-dependent part of the actual export.
Definition: docxexport.cxx:505
const HdFtFlags WW8_HEADER_FIRST
Definition: ww8scan.hxx:1592
void WriteTheme()
Write word/theme/theme1.xml.
virtual void WriteFormData(const ::sw::mark::IFieldmark &rFieldmark) override
Write the data of the form field.
Definition: docxexport.cxx:321
const sal_uInt8 PageBreak
void add(sal_Int32 nToken, const sal_Char *pValue)
The physical access to the DOCX document (for writing).
Reference< XComponentContext > getProcessComponentContext()
std::shared_ptr< WW8TableNodeInfoInner > Pointer_t
virtual void OutputField(const SwField *pField, ww::eField eFieldType, const OUString &rFieldCmd, FieldFlags nMode=FieldFlags::All) override
Write the field.
Definition: docxexport.cxx:316
static void ResetCounters()
bool evenAndOddHeaders
returns true if there are any non-default settings (i.e. something to write)
Definition: docxexport.hxx:58
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:723
OString const aName
uno::Reference< io::XInputStream > GetOLEObjectStream(uno::Reference< uno::XComponentContext > const &xContext, uno::Reference< embed::XEmbeddedObject > const &xObj, OUString const &i_rProgID, OUString &o_rMediaType, OUString &o_rRelationType, OUString &o_rSuffix, const char *&o_rpProgID)
virtual bool ignoreAttributeForStyleDefaults(sal_uInt16) const
Used to filter out attributes that can be e.g. written to .doc but not to .docx.
Definition: wrtww8.hxx:688
virtual void AppendBookmark(const OUString &rName) override
Definition: docxexport.cxx:182
Base class for WW8Export and DocxExport.
Definition: wrtww8.hxx:453
Reference< XModel > xModel
bool IsTableNode() const
Definition: node.hxx:640
virtual ~DocxExport() override
Destructor.
SwSectionNode * GetSectionNode()
Definition: node.hxx:607
Ends a section of nodes in the document model.
Definition: node.hxx:333
rtl_TextEncoding GetNextCharSet() const
Definition: wrtw8esh.cxx:1054
SectionType GetType() const
Definition: section.hxx:171
std::vector< ::sw::mark::IMark * > IMarkVector
Used to split the runs according to the bookmarks start and ends.
Definition: wrtww8.hxx:584
std::shared_ptr< WW8TableNodeInfo > Pointer_t
DefTokenId const nToken
OUString sCommand
Definition: swdbdata.hxx:31
aStr
void NextPara(sal_Int32 nPar)
Definition: wrtw8esh.cxx:1034
virtual OUString GetPar2() const override
aPromptText
Definition: expfld.cxx:1403
const HdFtFlags WW8_FOOTER_ODD
Definition: ww8scan.hxx:1591
virtual void ExportGrfBullet(const SwTextNode &) override
Definition: docxexport.cxx:217
const HdFtFlags WW8_HEADER_EVEN
Definition: ww8scan.hxx:1588
const SwFormatLineNumber & GetLineNumber(bool=true) const
Definition: fmtline.hxx:64
Base class of the Writer document model elements.
Definition: node.hxx:79
void WriteMainText()
FIXME this is temporary, remotely reminding the method of the same name in WW8Export.
OUString sId