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/io/XSeekable.hpp>
37 #include <com/sun/star/sdb/CommandType.hpp>
38 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
39 #include <com/sun/star/util/XModifiable.hpp>
40 
41 #include <oox/token/namespaces.hxx>
42 #include <oox/token/tokens.hxx>
43 #include <oox/export/drawingml.hxx>
44 #include <oox/export/vmlexport.hxx>
46 #include <oox/export/shapes.hxx>
49 #include <oox/ole/olestorage.hxx>
50 #include <oox/ole/olehelper.hxx>
51 
52 #include <map>
53 #include <algorithm>
54 
55 #include <IMark.hxx>
59 #include <docsh.hxx>
60 #include <ndtxt.hxx>
61 #include "wrtww8.hxx"
62 #include <fmtline.hxx>
63 #include <fmtpdsc.hxx>
64 #include <frmfmt.hxx>
65 #include <section.hxx>
66 #include <ftninfo.hxx>
67 #include <pagedesc.hxx>
68 #include <poolfmt.hxx>
69 #include <swdbdata.hxx>
70 
71 #include <editeng/unoprnms.hxx>
72 #include <editeng/editobj.hxx>
73 #include <editeng/outlobj.hxx>
74 #include <editeng/brushitem.hxx>
76 
77 #include <viewsh.hxx>
78 #include <viewopt.hxx>
79 
80 #include "ww8scan.hxx"
81 #include <oox/token/properties.hxx>
83 #include <comphelper/sequence.hxx>
85 #include <o3tl/any.hxx>
86 #include <sal/log.hxx>
88 #include <tools/diagnose_ex.h>
89 
90 using namespace sax_fastparser;
91 using namespace ::comphelper;
92 using namespace ::com::sun::star;
93 using namespace ::oox;
94 
96 
97 using sw::mark::IMark;
98 
100 {
101  return *m_pAttrOutput;
102 }
103 
105 {
106  return *m_pAttrOutput;
107 }
108 
110 {
111  return *m_pSections;
112 }
113 
114 bool DocxExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
115 {
116  // TODO FIXME is this actually true for docx? - this is ~copied from WW8
117  if ( nScript == i18n::ScriptType::ASIAN )
118  {
119  // for asian in ww8, there is only one fontsize
120  // and one fontstyle (posture/weight)
121  switch ( nWhich )
122  {
123  case RES_CHRATR_FONTSIZE:
124  case RES_CHRATR_POSTURE:
125  case RES_CHRATR_WEIGHT:
126  return false;
127  default:
128  break;
129  }
130  }
131  else if ( nScript != i18n::ScriptType::COMPLEX )
132  {
133  // for western in ww8, there is only one fontsize
134  // and one fontstyle (posture/weight)
135  switch ( nWhich )
136  {
140  return false;
141  default:
142  break;
143  }
144  }
145  return true;
146 }
147 
148 void DocxExport::AppendBookmarks( const SwTextNode& rNode, sal_Int32 nCurrentPos, sal_Int32 nLen )
149 {
150  std::vector< OUString > aStarts;
151  std::vector< OUString > aEnds;
152 
153  IMarkVector aMarks;
154  if ( GetBookmarks( rNode, nCurrentPos, nCurrentPos + nLen, aMarks ) )
155  {
156  for ( IMark* pMark : aMarks )
157  {
158  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
159  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
160 
161  if ( nStart == nCurrentPos )
162  aStarts.push_back( pMark->GetName() );
163 
164  if ( nEnd == nCurrentPos )
165  aEnds.push_back( pMark->GetName() );
166  }
167  }
168 
169  const OUString& aStr( rNode.GetText() );
170  const sal_Int32 nEnd = aStr.getLength();
171 
172  if ( nCurrentPos == nEnd )
173  m_pAttrOutput->WriteFinalBookmarks_Impl( aStarts, aEnds );
174  else
175  m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
176 }
177 
178 void DocxExport::AppendBookmark( const OUString& rName )
179 {
180  std::vector< OUString > aStarts;
181  std::vector< OUString > aEnds;
182 
183  aStarts.push_back( rName );
184  aEnds.push_back( rName );
185 
186  m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
187 }
188 
189 void DocxExport::AppendAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen )
190 {
191  std::vector< OUString > aStarts;
192  std::vector< OUString > aEnds;
193 
194  IMarkVector aMarks;
195  if (GetAnnotationMarks(rAttrs, nCurrentPos, nCurrentPos + nLen, aMarks))
196  {
197  for ( IMark* pMark : aMarks )
198  {
199  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
200  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
201 
202  if ( nStart == nCurrentPos )
203  aStarts.push_back( pMark->GetName() );
204 
205  if ( nEnd == nCurrentPos )
206  aEnds.push_back( pMark->GetName() );
207  }
208  }
209 
210  m_pAttrOutput->WriteAnnotationMarks_Impl( aStarts, aEnds );
211 }
212 
214 {
215  // Just collect the bullets for now, numbering.xml is not yet started.
216  CollectGrfsOfBullets();
217 }
218 
219 OString DocxExport::AddRelation( const OUString& rType, std::u16string_view rTarget )
220 {
221  OUString sId = m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
222  rType, rTarget, true );
223 
224  return sId.toUtf8();
225 }
226 
228 {
229  bool bRet( false );
230 
231  if (SfxItemState::SET != rFormat.GetItemState(RES_PARATR_NUMRULE, false))
232  {
233  if (const SwFormat *pParent = rFormat.DerivedFrom())
234  {
235  if (static_cast<const SwTextFormatColl*>(pParent)->IsAssignedToListLevelOfOutlineStyle())
236  {
237  ::sax_fastparser::FSHelperPtr pSerializer = m_pAttrOutput->GetSerializer( );
238  // Level 9 disables the outline
239  pSerializer->singleElementNS(XML_w, XML_outlineLvl, FSNS(XML_w, XML_val), "9");
240 
241  bRet = true;
242  }
243  }
244  }
245 
246  return bRet;
247 }
248 
250  const SwFrameFormat& rFormat, const SwFrameFormat& rLeftHeaderFormat, const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& rFirstPageFormat,
251  sal_uInt8 nBreakCode, bool bEvenAndOddHeaders )
252 {
253  m_nHeadersFootersInSection = 1;
254 
255  // document setting indicating the requirement of EVEN and ODD for both headers and footers
256  if ( nHeadFootFlags & ( nsHdFtFlags::WW8_FOOTER_EVEN | nsHdFtFlags::WW8_HEADER_EVEN ) && bEvenAndOddHeaders )
257  m_aSettings.evenAndOddHeaders = true;
258 
259  // Turn ON flag for 'Writing Headers \ Footers'
260  m_pAttrOutput->SetWritingHeaderFooter( true );
261 
262  // headers
263  if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
264  WriteHeaderFooter( &rLeftHeaderFormat, true, "even" );
265  else if ( m_aSettings.evenAndOddHeaders )
266  {
267  if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
268  WriteHeaderFooter( &rFormat, true, "even" );
269  else if ( m_bHasHdr && nBreakCode == 2 )
270  WriteHeaderFooter( nullptr, true, "even" );
271  }
272 
273  if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
274  WriteHeaderFooter( &rFormat, true, "default" );
275 
276  if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
277  WriteHeaderFooter( &rFirstPageFormat, true, "first" );
278 
279  if( (nHeadFootFlags & (nsHdFtFlags::WW8_HEADER_EVEN
280  | nsHdFtFlags::WW8_HEADER_ODD
281  | nsHdFtFlags::WW8_HEADER_FIRST)) == 0
282  && m_bHasHdr && nBreakCode == 2 ) // 2: nexPage
283  WriteHeaderFooter( nullptr, true, "default" );
284 
285 
286  // footers
287  if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
288  WriteHeaderFooter( &rLeftFooterFormat, false, "even" );
289  else if ( m_aSettings.evenAndOddHeaders )
290  {
291  if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
292  WriteHeaderFooter( &rFormat, false, "even" );
293  else if ( m_bHasFtr && nBreakCode == 2 )
294  WriteHeaderFooter( nullptr, false, "even");
295  }
296 
297  if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
298  WriteHeaderFooter( &rFormat, false, "default" );
299 
300  if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
301  WriteHeaderFooter( &rFirstPageFormat, false, "first" );
302 
303  if( (nHeadFootFlags & (nsHdFtFlags::WW8_FOOTER_EVEN
304  | nsHdFtFlags::WW8_FOOTER_ODD
305  | nsHdFtFlags::WW8_FOOTER_FIRST)) == 0
306  && m_bHasFtr && nBreakCode == 2 ) // 2: nexPage
307  WriteHeaderFooter( nullptr, false, "default");
308 
309  // Turn OFF flag for 'Writing Headers \ Footers'
310  m_pAttrOutput->SetWritingHeaderFooter( false );
311 }
312 
313 void DocxExport::OutputField( const SwField* pField, ww::eField eFieldType, const OUString& rFieldCmd, FieldFlags nMode )
314 {
315  m_pAttrOutput->WriteField_Impl( pField, eFieldType, rFieldCmd, nMode );
316 }
317 
318 void DocxExport::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
319 {
320  m_pAttrOutput->WriteFormData_Impl( rFieldmark );
321 }
322 
323 void DocxExport::WriteHyperlinkData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
324 {
325  SAL_INFO("sw.ww8", "TODO DocxExport::WriteHyperlinkData().");
326 }
327 
328 void DocxExport::DoComboBox(const OUString& rName,
329  const OUString& rHelp,
330  const OUString& rToolTip,
331  const OUString& rSelected,
332  const uno::Sequence<OUString>& rListItems)
333 {
334  m_pDocumentFS->startElementNS(XML_w, XML_ffData);
335 
336  m_pDocumentFS->singleElementNS(XML_w, XML_name, FSNS(XML_w, XML_val), rName);
337 
338  m_pDocumentFS->singleElementNS(XML_w, XML_enabled);
339 
340  if ( !rHelp.isEmpty() )
341  m_pDocumentFS->singleElementNS(XML_w, XML_helpText, FSNS(XML_w, XML_val), rHelp);
342 
343  if ( !rToolTip.isEmpty() )
344  m_pDocumentFS->singleElementNS(XML_w, XML_statusText, FSNS(XML_w, XML_val), rToolTip);
345 
346  m_pDocumentFS->startElementNS(XML_w, XML_ddList);
347 
348  // Output the 0-based index of the selected value
349  sal_Int32 nId = comphelper::findValue(rListItems, rSelected);
350  if (nId == -1)
351  nId = 0;
352 
353  m_pDocumentFS->singleElementNS(XML_w, XML_result, FSNS(XML_w, XML_val), OString::number(nId));
354 
355  // unfortunately Word 2013 refuses to load DOCX with more than 25 listEntry
356  SAL_WARN_IF(25 < rListItems.getLength(), "sw.ww8", "DocxExport::DoComboBox data loss with more than 25 entries");
357  auto const nSize(std::min(sal_Int32(25), rListItems.getLength()));
358  for (auto i = 0; i < nSize; ++i)
359  {
360  m_pDocumentFS->singleElementNS(XML_w, XML_listEntry, FSNS(XML_w, XML_val), rListItems[i]);
361  }
362 
363  m_pDocumentFS->endElementNS( XML_w, XML_ddList );
364 
365  m_pDocumentFS->endElementNS( XML_w, XML_ffData );
366 }
367 
369 {
370  assert(pField);
371  const OUString sStr = FieldString(ww::eFILLIN) + "\"" + pField->GetPar2() + "\"";
372  OutputField(pField, ww::eFILLIN, sStr);
373 }
374 
375 OString DocxExport::OutputChart( uno::Reference< frame::XModel > const & xModel, sal_Int32 nCount, ::sax_fastparser::FSHelperPtr const & m_pSerializer )
376 {
377  OUString aFileName = "charts/chart" + OUString::number(nCount) + ".xml";
378  OUString sId = m_rFilter.addRelation( m_pSerializer->getOutputStream(),
379  oox::getRelationship(Relationship::CHART),
380  aFileName );
381  aFileName = "word/charts/chart" + OUString::number(nCount) + ".xml";
383  m_rFilter.openFragmentStreamWithSerializer( aFileName,
384  "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" );
385 
386  oox::drawingml::ChartExport aChartExport(XML_w, pChartFS, xModel, &m_rFilter, oox::drawingml::DOCUMENT_DOCX);
387  css::uno::Reference<css::util::XModifiable> xModifiable(xModel, css::uno::UNO_QUERY);
388  const bool bOldModified = xModifiable && xModifiable->isModified();
389  aChartExport.ExportContent();
390  if (!bOldModified && xModifiable && xModifiable->isModified())
391  // tdf#134973: the model could get modified: e.g., calling XChartDocument::getSubTitle(),
392  // which creates the object if absent, and sets the modified state.
393  xModifiable->setModified(bOldModified);
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  {
427  comphelper::OStorageHelper::CopyInputToOutput(xInStream, xOutStream);
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_rFilter.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_rFilter.openFragmentStream(sBinaryFileName, "application/vnd.ms-office.activeX"), uno::UNO_QUERY);
456  if(xOutStorage.is())
457  {
458  oox::ole::OleStorage aOleStorage(m_rFilter.getComponentContext(), xOutStorage, false);
459  uno::Reference<io::XOutputStream> xOutputStream(aOleStorage.openOutputStream("contents"), uno::UNO_SET_THROW);
460  uno::Reference< css::frame::XModel > xModel( m_rDoc.GetDocShell() ? m_rDoc.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_rFilter.openFragmentStreamWithSerializer(sXMLFileName, "application/vnd.ms-office.activeX+xml" );
473 
474  const OUString sBinaryId = m_rFilter.addRelation( pActiveXFS->getOutputStream(),
475  oox::getRelationship(Relationship::ACTIVEXCONTROLBINARY),
476  sBinaryFileName.subView(sBinaryFileName.lastIndexOf("/") + 1) );
477 
478  pActiveXFS->singleElementNS(XML_ax, XML_ocx,
479  FSNS(XML_xmlns, XML_ax), m_rFilter.getNamespaceURL(OOX_NS(ax)),
480  FSNS(XML_xmlns, XML_r), m_rFilter.getNamespaceURL(OOX_NS(officeRel)),
481  FSNS(XML_ax, XML_classid), "{" + sGUID + "}",
482  FSNS(XML_ax, XML_persistence), "persistStorage",
483  FSNS(XML_r, XML_id), sBinaryId);
484 
485  OString sXMLId = OUStringToOString(m_rFilter.addRelation(m_pDocumentFS->getOutputStream(),
486  oox::getRelationship(Relationship::CONTROL),
487  sXMLFileName.subView(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_rFilter, 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, false, 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 && SectionType::ToxContent == 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, bool bExtraPageBreak )
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, false, m_pSections->CurrentSectionInfo(), bExtraPageBreak );
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_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
649  oox::getRelationship(Relationship::STYLES),
650  u"styles.xml" );
651 
653  m_rFilter.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_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
672  oox::getRelationship(Relationship::FOOTNOTES),
673  u"footnotes.xml" );
674 
675  ::sax_fastparser::FSHelperPtr pFootnotesFS =
676  m_rFilter.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  return;
697 
698  // setup word/styles.xml and the relations + content type
699  m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
700  oox::getRelationship(Relationship::ENDNOTES),
701  u"endnotes.xml" );
702 
703  ::sax_fastparser::FSHelperPtr pEndnotesFS =
704  m_rFilter.openFragmentStreamWithSerializer( "word/endnotes.xml",
705  "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" );
706 
707  // switch the serializer to redirect the output to word/endnotes.xml
708  m_pAttrOutput->SetSerializer( pEndnotesFS );
709  // tdf#99227
710  m_pSdrExport->setSerializer( pEndnotesFS );
711  // tdf#107969
712  m_pVMLExport->SetFS(pEndnotesFS);
713 
714  // do the work
715  m_pAttrOutput->FootnotesEndnotes( false );
716 
717  // switch the serializer back
718  m_pVMLExport->SetFS(m_pDocumentFS);
719  m_pSdrExport->setSerializer( m_pDocumentFS );
720  m_pAttrOutput->SetSerializer( m_pDocumentFS );
721 }
722 
724 {
725  if ( !m_pAttrOutput->HasPostitFields() )
726  return;
727 
728  m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
729  oox::getRelationship(Relationship::COMMENTS),
730  u"comments.xml" );
731 
733  m_rFilter.openFragmentStreamWithSerializer( "word/comments.xml",
734  "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" );
735 
736  pPostitFS->startElementNS( XML_w, XML_comments, MainXmlNamespaces());
737  m_pAttrOutput->SetSerializer( pPostitFS );
738  const auto eHasResolved = m_pAttrOutput->WritePostitFields();
739  m_pAttrOutput->SetSerializer( m_pDocumentFS );
740  pPostitFS->endElementNS( XML_w, XML_comments );
741 
742  if (eHasResolved != DocxAttributeOutput::hasResolved::yes)
743  return;
744 
745  m_rFilter.addRelation(m_pDocumentFS->getOutputStream(),
746  oox::getRelationship(Relationship::COMMENTSEXTENDED),
747  u"commentsExtended.xml");
748 
749  pPostitFS = m_rFilter.openFragmentStreamWithSerializer(
750  "word/commentsExtended.xml",
751  "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml");
752 
753  pPostitFS->startElementNS(XML_w15, XML_commentsEx, // Add namespaces manually now
754  FSNS(XML_xmlns, XML_mc), m_rFilter.getNamespaceURL(OOX_NS(mce)),
755  FSNS(XML_xmlns, XML_w15), m_rFilter.getNamespaceURL(OOX_NS(w15)),
756  FSNS(XML_mc, XML_Ignorable), "w15");
757  m_pAttrOutput->SetSerializer(pPostitFS);
758  m_pAttrOutput->WritePostItFieldsResolved();
759  m_pAttrOutput->SetSerializer(m_pDocumentFS);
760  pPostitFS->endElementNS(XML_w15, XML_commentsEx);
761 }
762 
764 {
765  if ( !m_pUsedNumTable )
766  return; // no numbering is used
767 
768  m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
769  oox::getRelationship(Relationship::NUMBERING),
770  u"numbering.xml" );
771 
772  ::sax_fastparser::FSHelperPtr pNumberingFS = m_rFilter.openFragmentStreamWithSerializer( "word/numbering.xml",
773  "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" );
774 
775  // switch the serializer to redirect the output to word/numbering.xml
776  m_pAttrOutput->SetSerializer( pNumberingFS );
777  m_pDrawingML->SetFS( pNumberingFS );
778 
779  pNumberingFS->startElementNS( XML_w, XML_numbering,
780  FSNS( XML_xmlns, XML_w ), m_rFilter.getNamespaceURL(OOX_NS(doc)),
781  FSNS( XML_xmlns, XML_o ), m_rFilter.getNamespaceURL(OOX_NS(vmlOffice)),
782  FSNS( XML_xmlns, XML_r ), m_rFilter.getNamespaceURL(OOX_NS(officeRel)),
783  FSNS( XML_xmlns, XML_v ), m_rFilter.getNamespaceURL(OOX_NS(vml)),
784  FSNS( XML_xmlns, XML_mc ), m_rFilter.getNamespaceURL(OOX_NS(mce)),
785  FSNS( XML_xmlns, XML_w14 ), m_rFilter.getNamespaceURL(OOX_NS(w14)),
786  FSNS( XML_mc, XML_Ignorable ), "w14" );
787 
788  BulletDefinitions();
789 
790  AbstractNumberingDefinitions();
791 
792  NumberingDefinitions();
793 
794  pNumberingFS->endElementNS( XML_w, XML_numbering );
795 
796  // switch the serializer back
797  m_pDrawingML->SetFS( m_pDocumentFS );
798  m_pAttrOutput->SetSerializer( m_pDocumentFS );
799 }
800 
801 void DocxExport::WriteHeaderFooter( const SwFormat* pFormat, bool bHeader, const char* pType )
802 {
803  // setup the xml stream
804  OUString aRelId;
806  if ( bHeader )
807  {
808  OUString aName( "header" + OUString::number( ++m_nHeaders ) + ".xml" );
809 
810  aRelId = m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
811  oox::getRelationship(Relationship::HEADER),
812  aName );
813 
814  pFS = m_rFilter.openFragmentStreamWithSerializer( "word/" + aName,
815  "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" );
816 
817  pFS->startElementNS( XML_w, XML_hdr, MainXmlNamespaces());
818  }
819  else
820  {
821  OUString aName( "footer" + OUString::number( ++m_nFooters ) + ".xml" );
822 
823  aRelId = m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
824  oox::getRelationship(Relationship::FOOTER),
825  aName );
826 
827  pFS = m_rFilter.openFragmentStreamWithSerializer( "word/" + aName,
828  "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" );
829 
830  pFS->startElementNS( XML_w, XML_ftr, MainXmlNamespaces());
831  }
832 
833  // switch the serializer to redirect the output to word/styles.xml
834  m_pAttrOutput->SetSerializer( pFS );
835  m_pVMLExport->SetFS( pFS );
836  m_pSdrExport->setSerializer(pFS);
837  SetFS( pFS );
838  {
839  DocxTableExportContext aTableExportContext(*m_pAttrOutput);
840  // do the work
841  if (pFormat == nullptr)
842  AttrOutput().EmptyParagraph();
843  else
844  WriteHeaderFooterText(*pFormat, bHeader);
845  m_pAttrOutput->EndParaSdtBlock();
846  }
847 
848  // switch the serializer back
849  m_pAttrOutput->SetSerializer( m_pDocumentFS );
850  m_pVMLExport->SetFS( m_pDocumentFS );
851  m_pSdrExport->setSerializer(m_pDocumentFS);
852  SetFS( m_pDocumentFS );
853 
854  // close the tag
855  sal_Int32 nReference;
856  if ( bHeader )
857  {
858  pFS->endElementNS( XML_w, XML_hdr );
859  nReference = XML_headerReference;
860  }
861  else
862  {
863  pFS->endElementNS( XML_w, XML_ftr );
864  nReference = XML_footerReference;
865  }
866 
867  // and write the reference
868  m_pDocumentFS->singleElementNS( XML_w, nReference,
869  FSNS( XML_w, XML_type ), pType,
870  FSNS( XML_r, XML_id ), aRelId );
871 }
872 
874 {
875  m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
876  oox::getRelationship(Relationship::FONTTABLE),
877  u"fontTable.xml" );
878 
879  ::sax_fastparser::FSHelperPtr pFS = m_rFilter.openFragmentStreamWithSerializer(
880  "word/fontTable.xml",
881  "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" );
882 
883  pFS->startElementNS( XML_w, XML_fonts,
884  FSNS( XML_xmlns, XML_w ), m_rFilter.getNamespaceURL(OOX_NS(doc)),
885  FSNS( XML_xmlns, XML_r ), m_rFilter.getNamespaceURL(OOX_NS(officeRel)) );
886 
887  // switch the serializer to redirect the output to word/styles.xml
888  m_pAttrOutput->SetSerializer( pFS );
889 
890  // do the work
891  m_aFontHelper.WriteFontTable( *m_pAttrOutput );
892 
893  // switch the serializer back
894  m_pAttrOutput->SetSerializer( m_pDocumentFS );
895 
896  pFS->endElementNS( XML_w, XML_fonts );
897 }
898 
900 {
901  // Write the core properties
902  SwDocShell* pDocShell( m_rDoc.GetDocShell( ) );
903  uno::Reference<document::XDocumentProperties> xDocProps;
904  bool bSecurityOptOpenReadOnly = false;
905  if ( pDocShell )
906  {
907  uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
908  pDocShell->GetModel( ), uno::UNO_QUERY );
909  xDocProps = xDPS->getDocumentProperties();
910  bSecurityOptOpenReadOnly = pDocShell->IsSecurityOptOpenReadOnly();
911  }
912 
913  m_rFilter.exportDocumentProperties( xDocProps, bSecurityOptOpenReadOnly );
914 }
915 
917 {
918  SwDocShell* pDocShell = m_rDoc.GetDocShell();
919  if (!pDocShell)
920  {
921  return;
922  }
923 
924  uno::Reference<text::XTextFieldsSupplier> xModel(pDocShell->GetModel(), uno::UNO_QUERY);
925  uno::Reference<container::XNameAccess> xTextFieldMasters = xModel->getTextFieldMasters();
926  uno::Sequence<rtl::OUString> aMasterNames = xTextFieldMasters->getElementNames();
927  if (!aMasterNames.hasElements())
928  {
929  return;
930  }
931 
932  // Only write docVars if there will be at least a single docVar.
933  bool bStarted = false;
934  constexpr OUStringLiteral aPrefix(u"com.sun.star.text.fieldmaster.User.");
935  for (const auto& rMasterName : std::as_const(aMasterNames))
936  {
937  if (!rMasterName.startsWith(aPrefix))
938  {
939  // Not a user field.
940  continue;
941  }
942 
943  uno::Reference<beans::XPropertySet> xField;
944  xTextFieldMasters->getByName(rMasterName) >>= xField;
945  if (!xField.is())
946  {
947  continue;
948  }
949 
950  OUString aKey = rMasterName.copy(aPrefix.getLength());
951  OUString aValue;
952  xField->getPropertyValue("Content") >>= aValue;
953  if (!bStarted)
954  {
955  bStarted = true;
956  pFS->startElementNS(XML_w, XML_docVars);
957  }
958  pFS->singleElementNS(XML_w, XML_docVar, FSNS(XML_w, XML_name), aKey,
959  FSNS(XML_w, XML_val), aValue);
960  }
961 
962  if (bStarted)
963  {
964  pFS->endElementNS(XML_w, XML_docVars);
965  }
966 }
967 
968 static auto
969 WriteCompat(SwDoc const& rDoc, ::sax_fastparser::FSHelperPtr const& rpFS,
970  sal_Int32 & rTargetCompatibilityMode) -> void
971 {
972  if (!rDoc.getIDocumentSettingAccess().get(DocumentSettingId::ADD_EXT_LEADING))
973  {
974  rpFS->singleElementNS(XML_w, XML_noLeading);
975  if (rTargetCompatibilityMode > 14)
976  { // Word ignores noLeading in compatibilityMode 15
977  rTargetCompatibilityMode = 14;
978  }
979  }
980  // Do not justify lines with manual break
981  if (rDoc.getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK))
982  {
983  rpFS->singleElementNS(XML_w, XML_doNotExpandShiftReturn);
984  }
985 }
986 
988 {
990  if( !pViewShell && !m_aSettings.hasData() && !m_pAttrOutput->HasFootnotes() && !m_pAttrOutput->HasEndnotes())
991  return;
992 
993  m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
994  oox::getRelationship(Relationship::SETTINGS),
995  u"settings.xml" );
996 
997  ::sax_fastparser::FSHelperPtr pFS = m_rFilter.openFragmentStreamWithSerializer(
998  "word/settings.xml",
999  "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" );
1000 
1001  pFS->startElementNS( XML_w, XML_settings,
1002  FSNS( XML_xmlns, XML_w ), m_rFilter.getNamespaceURL(OOX_NS(doc)) );
1003 
1004  // View
1005  if (pViewShell && pViewShell->GetViewOptions()->getBrowseMode())
1006  {
1007  pFS->singleElementNS(XML_w, XML_view, FSNS(XML_w, XML_val), "web");
1008  }
1009 
1010  // Zoom
1011  if (pViewShell)
1012  {
1015 
1016  switch (pViewShell->GetViewOptions()->GetZoomType())
1017  {
1018  case SvxZoomType::WHOLEPAGE:
1019  pAttributeList->add(FSNS(XML_w, XML_val), "fullPage");
1020  break;
1021  case SvxZoomType::PAGEWIDTH:
1022  pAttributeList->add(FSNS(XML_w, XML_val), "bestFit");
1023  break;
1024  case SvxZoomType::OPTIMAL:
1025  pAttributeList->add(FSNS(XML_w, XML_val), "textFit");
1026  break;
1027  default:
1028  break;
1029  }
1030 
1031  OString aZoom(OString::number(pViewShell->GetViewOptions()->GetZoom()));
1032  pAttributeList->add(FSNS(XML_w, XML_percent), aZoom);
1033  pFS->singleElementNS(XML_w, XML_zoom, pAttributeList);
1034  }
1035 
1036  // Display Background Shape
1037  if (std::unique_ptr<SvxBrushItem> oBrush = getBackground(); oBrush)
1038  {
1039  // Turn on the 'displayBackgroundShape'
1040  pFS->singleElementNS(XML_w, XML_displayBackgroundShape);
1041  }
1042 
1043  // Track Changes
1044  if ( !m_aSettings.revisionView )
1045  pFS->singleElementNS( XML_w, XML_revisionView,
1046  FSNS( XML_w, XML_insDel ), "0",
1047  FSNS( XML_w, XML_formatting ), "0" );
1048 
1049  if ( m_aSettings.trackRevisions )
1050  pFS->singleElementNS(XML_w, XML_trackRevisions);
1051 
1052  // Mirror Margins
1053  if(isMirroredMargin())
1054  pFS->singleElementNS(XML_w, XML_mirrorMargins);
1055 
1057  {
1058  pFS->singleElementNS(XML_w, XML_gutterAtTop);
1059  }
1060 
1061  // Embed Fonts
1063  pFS->singleElementNS(XML_w, XML_embedTrueTypeFonts);
1064 
1065  // Embed System Fonts
1067  pFS->singleElementNS(XML_w, XML_embedSystemFonts);
1068 
1069  // Default Tab Stop
1070  if( m_aSettings.defaultTabStop != 0 )
1071  pFS->singleElementNS( XML_w, XML_defaultTabStop, FSNS( XML_w, XML_val ),
1072  OString::number(m_aSettings.defaultTabStop) );
1073 
1074  // export current mail merge database and table names
1076  if ( !aData.sDataSource.isEmpty() && aData.nCommandType == css::sdb::CommandType::TABLE && !aData.sCommand.isEmpty() )
1077  {
1078  OUString sDataSource =
1079  "SELECT * FROM " +
1080  aData.sDataSource + // current database
1081  ".dbo." + // default database owner
1082  aData.sCommand + // sheet name
1083  "$"; // sheet identifier
1084  pFS->startElementNS( XML_w, XML_mailMerge );
1085  pFS->singleElementNS(XML_w, XML_mainDocumentType,
1086  FSNS( XML_w, XML_val ), "formLetters" );
1087  pFS->singleElementNS(XML_w, XML_dataType,
1088  FSNS( XML_w, XML_val ), "textFile" );
1089  pFS->singleElementNS( XML_w, XML_query,
1090  FSNS( XML_w, XML_val ), OUStringToOString( sDataSource, RTL_TEXTENCODING_UTF8 ).getStr() );
1091  pFS->endElementNS( XML_w, XML_mailMerge );
1092  }
1093 
1094  // Automatic hyphenation: it's a global setting in Word, it's a paragraph setting in Writer.
1095  // Set it's value to "auto" and disable on paragraph level, if no hyphenation is used there.
1096  pFS->singleElementNS(XML_w, XML_autoHyphenation, FSNS(XML_w, XML_val), "true");
1097 
1098  // Hyphenation details set depending on default style
1100  const SfxPoolItem* pItem;
1101  if (pColl && SfxItemState::SET == pColl->GetItemState(RES_PARATR_HYPHENZONE, false, &pItem))
1102  {
1103  if (static_cast<const SvxHyphenZoneItem*>(pItem)->IsNoCapsHyphenation())
1104  pFS->singleElementNS(XML_w, XML_doNotHyphenateCaps);
1105  }
1106 
1107  // Even and Odd Headers
1108  if( m_aSettings.evenAndOddHeaders )
1109  pFS->singleElementNS(XML_w, XML_evenAndOddHeaders);
1110 
1111  // Has Footnotes
1112  if( m_pAttrOutput->HasFootnotes())
1113  DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_footnotePr, m_rDoc.GetFootnoteInfo(), XML_footnote );
1114 
1115  // Has Endnotes
1116  if( m_pAttrOutput->HasEndnotes())
1117  DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_endnotePr, m_rDoc.GetEndNoteInfo(), XML_endnote );
1118 
1119  // Has themeFontLang information
1120  uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1121 
1122  bool bUseGrabBagProtection = false;
1123  bool bWriterWantsToProtect = false;
1124  bool bWriterWantsToProtectForm = false;
1125  bool bWriterWantsToProtectRedline = false;
1126  bool bHasDummyRedlineProtectionKey = false;
1127  bool bReadOnlyStatusUnchanged = true;
1128  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1130  m_pSections->DocumentIsProtected() )
1131  {
1132  bWriterWantsToProtect = bWriterWantsToProtectForm = true;
1133  }
1134  if ( xPropSetInfo->hasPropertyByName( "RedlineProtectionKey" ) )
1135  {
1136  uno::Sequence<sal_Int8> aKey;
1137  xPropSet->getPropertyValue( "RedlineProtectionKey" ) >>= aKey;
1138  bool bHasRedlineProtectionKey = aKey.hasElements();
1139  bHasDummyRedlineProtectionKey = aKey.getLength() == 1 && aKey[0] == 1;
1140  if ( bHasRedlineProtectionKey && !bHasDummyRedlineProtectionKey )
1141  bWriterWantsToProtect = bWriterWantsToProtectRedline = true;
1142  }
1143 
1144  /* Compatibility Mode (tdf#131304)
1145  * 11: .doc level [Word 97-2003]
1146  * 12: .docx default [Word 2007] [LO < 7.0]
1147  * 14: [Word 2010]
1148  * 15: [Word 2013/2016/2019] [LO >= 7.0]
1149  *
1150  * The PRIMARY purpose of compatibility mode does not seem to be related to layout etc.
1151  * Its focus is on sharing files between multiple users, tracking the lowest supported mode in the group.
1152  * It is to BENEFIT older programs by not using certain new features that they don't understand.
1153  *
1154  * The next time the compat mode needs to be changed, I foresee the following steps:
1155  * 1.) Accept the new mode: Start round-tripping the new value, indicating we understand that format.
1156  * 2.) Many years later, change the TargetCompatilityMode for new documents, when we no longer care
1157  * about working with perfect compatibility with older versions of MS Word.
1158  */
1159  sal_Int32 nTargetCompatibilityMode = 15; //older versions might not open our files well
1160  bool bHasCompatibilityMode = false;
1161  const OUString aGrabBagName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1162  if ( xPropSetInfo->hasPropertyByName( aGrabBagName ) )
1163  {
1164  uno::Sequence< beans::PropertyValue > propList;
1165  xPropSet->getPropertyValue( aGrabBagName ) >>= propList;
1166 
1167  for( const auto& rProp : std::as_const(propList) )
1168  {
1169  if ( rProp.Name == "ThemeFontLangProps" )
1170  {
1171  uno::Sequence< beans::PropertyValue > themeFontLangProps;
1172  rProp.Value >>= themeFontLangProps;
1173  OUString aValues[3];
1174  for( const auto& rThemeFontLangProp : std::as_const(themeFontLangProps) )
1175  {
1176  if( rThemeFontLangProp.Name == "val" )
1177  rThemeFontLangProp.Value >>= aValues[0];
1178  else if( rThemeFontLangProp.Name == "eastAsia" )
1179  rThemeFontLangProp.Value >>= aValues[1];
1180  else if( rThemeFontLangProp.Name == "bidi" )
1181  rThemeFontLangProp.Value >>= aValues[2];
1182  }
1183  pFS->singleElementNS( XML_w, XML_themeFontLang,
1184  FSNS( XML_w, XML_val ), aValues[0],
1185  FSNS( XML_w, XML_eastAsia ), aValues[1],
1186  FSNS( XML_w, XML_bidi ), aValues[2] );
1187  }
1188  else if ( rProp.Name == "CompatSettings" )
1189  {
1190  pFS->startElementNS(XML_w, XML_compat);
1191 
1192  WriteCompat(m_rDoc, pFS, nTargetCompatibilityMode);
1193 
1194  uno::Sequence< beans::PropertyValue > aCompatSettingsSequence;
1195  rProp.Value >>= aCompatSettingsSequence;
1196 
1197  for(const auto& rCompatSetting : std::as_const(aCompatSettingsSequence))
1198  {
1199  uno::Sequence< beans::PropertyValue > aCompatSetting;
1200  rCompatSetting.Value >>= aCompatSetting;
1201  OUString aName;
1202  OUString aUri;
1203  OUString aValue;
1204 
1205  for(const auto& rPropVal : std::as_const(aCompatSetting))
1206  {
1207  if( rPropVal.Name == "name" )
1208  rPropVal.Value >>= aName;
1209  else if( rPropVal.Name == "uri" )
1210  rPropVal.Value >>= aUri;
1211  else if( rPropVal.Name == "val" )
1212  rPropVal.Value >>= aValue;
1213  }
1214  if ( aName == "compatibilityMode" )
1215  {
1216  bHasCompatibilityMode = true;
1217  // Among the group of programs sharing this document, the lowest mode is retained.
1218  // Reduce this number if we are not comfortable with the new/unknown mode yet.
1219  // Step 1 in accepting a new mode would be to comment out the following clause
1220  // and roundtrip the new value instead of overwriting with the older number.
1221  // There are no newer modes at the time this code was written.
1222  if ( aValue.toInt32() > nTargetCompatibilityMode )
1223  aValue = OUString::number(nTargetCompatibilityMode);
1224  }
1225 
1226  pFS->singleElementNS( XML_w, XML_compatSetting,
1227  FSNS( XML_w, XML_name ), aName,
1228  FSNS( XML_w, XML_uri ), aUri,
1229  FSNS( XML_w, XML_val ), aValue);
1230  }
1231 
1232  if ( !bHasCompatibilityMode )
1233  {
1234  pFS->singleElementNS( XML_w, XML_compatSetting,
1235  FSNS( XML_w, XML_name ), "compatibilityMode",
1236  FSNS( XML_w, XML_uri ), "http://schemas.microsoft.com/office/word",
1237  FSNS( XML_w, XML_val ), OString::number(nTargetCompatibilityMode));
1238  bHasCompatibilityMode = true;
1239  }
1240 
1241  pFS->endElementNS( XML_w, XML_compat );
1242  }
1243  else if (rProp.Name == "DocumentProtection")
1244  {
1245  uno::Sequence< beans::PropertyValue > rAttributeList;
1246  rProp.Value >>= rAttributeList;
1247 
1248  if (rAttributeList.hasElements())
1249  {
1251  bool bIsProtectionTrackChanges = false;
1252  // if grabbag protection is not enforced, allow Writer protection to override
1253  bool bEnforced = false;
1254  for (const auto& rAttribute : std::as_const(rAttributeList))
1255  {
1256  static DocxStringTokenMap const aTokens[] =
1257  {
1258  { "edit", XML_edit },
1259  { "enforcement", XML_enforcement },
1260  { "formatting", XML_formatting },
1261  { "cryptProviderType", XML_cryptProviderType },
1262  { "cryptAlgorithmClass", XML_cryptAlgorithmClass },
1263  { "cryptAlgorithmType", XML_cryptAlgorithmType },
1264  { "cryptAlgorithmSid", XML_cryptAlgorithmSid },
1265  { "cryptSpinCount", XML_cryptSpinCount },
1266  { "hash", XML_hash },
1267  { "salt", XML_salt },
1268  { nullptr, 0 }
1269  };
1270 
1271  if (sal_Int32 nToken = DocxStringGetToken(aTokens, rAttribute.Name))
1272  {
1273  OUString sValue = rAttribute.Value.get<OUString>();
1274  xAttributeList->add(FSNS(XML_w, nToken), sValue.toUtf8());
1275  if ( nToken == XML_edit && sValue == "trackedChanges" )
1276  bIsProtectionTrackChanges = true;
1277  else if ( nToken == XML_edit && sValue == "readOnly" )
1278  {
1279  // Ignore the case where read-only was not enforced, but now is. That is handled by _MarkAsFinal
1280  bReadOnlyStatusUnchanged = m_rDoc.GetDocShell()->IsSecurityOptOpenReadOnly();
1281  }
1282  else if ( nToken == XML_enforcement )
1283  bEnforced = sValue.toBoolean();
1284  }
1285  }
1286 
1287  // we have document protection from input DOCX file
1288  if ( !bEnforced )
1289  {
1290  // Leave as an un-enforced suggestion if Writer doesn't want to set any enforcement
1291  bUseGrabBagProtection = !bWriterWantsToProtect;
1292  }
1293  else
1294  {
1295  // Check if the grabbag protection is still valid
1296  // In the case of change tracking protection, we didn't modify it
1297  // and in the case of read-only, we didn't modify it.
1298  bUseGrabBagProtection = (!bIsProtectionTrackChanges || bHasDummyRedlineProtectionKey)
1299  && bReadOnlyStatusUnchanged;
1300  }
1301 
1302  if ( bUseGrabBagProtection )
1303  {
1304  pFS->singleElementNS(XML_w, XML_documentProtection, xAttributeList);
1305  }
1306 
1307  }
1308  }
1309  else if (rProp.Name == "HyphenationZone")
1310  {
1311  sal_Int16 nHyphenationZone = *o3tl::doAccess<sal_Int16>(rProp.Value);
1312  if (nHyphenationZone > 0)
1313  pFS->singleElementNS(XML_w, XML_hyphenationZone, FSNS(XML_w, XML_val),
1314  OString::number(nHyphenationZone));
1315  }
1316  }
1317  }
1318  if ( !bHasCompatibilityMode )
1319  {
1320  pFS->startElementNS(XML_w, XML_compat);
1321 
1322  WriteCompat(m_rDoc, pFS, nTargetCompatibilityMode);
1323 
1324  pFS->singleElementNS( XML_w, XML_compatSetting,
1325  FSNS( XML_w, XML_name ), "compatibilityMode",
1326  FSNS( XML_w, XML_uri ), "http://schemas.microsoft.com/office/word",
1327  FSNS( XML_w, XML_val ), OString::number(nTargetCompatibilityMode));
1328  pFS->endElementNS( XML_w, XML_compat );
1329  }
1330 
1331  WriteDocVars(pFS);
1332 
1333  if ( !bUseGrabBagProtection )
1334  {
1335  // Protect form - highest priority
1336  // Section-specific write protection
1337  if ( bWriterWantsToProtectForm )
1338  {
1339  // we have form protection from Writer or from input ODT file
1340 
1341  pFS->singleElementNS(XML_w, XML_documentProtection,
1342  FSNS(XML_w, XML_edit), "forms",
1343  FSNS(XML_w, XML_enforcement), "true");
1344  }
1345  // Protect Change Tracking - next priority
1346  else if ( bWriterWantsToProtectRedline )
1347  {
1348  // we have change tracking protection from Writer or from input ODT file
1349 
1350  pFS->singleElementNS(XML_w, XML_documentProtection,
1351  FSNS(XML_w, XML_edit), "trackedChanges",
1352  FSNS(XML_w, XML_enforcement), "1");
1353  }
1354  }
1355 
1356  // finish settings.xml
1357  pFS->endElementNS( XML_w, XML_settings );
1358 }
1359 
1361 {
1362  uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1363 
1364  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1366  if ( !xPropSetInfo->hasPropertyByName( aName ) )
1367  return;
1368 
1369  uno::Reference<xml::dom::XDocument> themeDom;
1370  uno::Sequence< beans::PropertyValue > propList;
1371  xPropSet->getPropertyValue( aName ) >>= propList;
1372  auto pProp = std::find_if(propList.begin(), propList.end(),
1373  [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXTheme"; });
1374  if (pProp != propList.end())
1375  pProp->Value >>= themeDom;
1376 
1377  // no theme dom to write
1378  if ( !themeDom.is() )
1379  return;
1380 
1381  m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
1382  oox::getRelationship(Relationship::THEME),
1383  u"theme/theme1.xml" );
1384 
1385  uno::Reference< xml::sax::XSAXSerializable > serializer( themeDom, uno::UNO_QUERY );
1386  uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1387  writer->setOutputStream( GetFilter().openFragmentStream( "word/theme/theme1.xml",
1388  "application/vnd.openxmlformats-officedocument.theme+xml" ) );
1389  serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1390  uno::Sequence< beans::StringPair >() );
1391 }
1392 
1394 {
1395  uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1396 
1397  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1399  if ( !xPropSetInfo->hasPropertyByName( aName ) )
1400  return;
1401 
1402  uno::Reference<xml::dom::XDocument> glossaryDocDom;
1403  uno::Sequence< uno::Sequence< uno::Any> > glossaryDomList;
1404  uno::Sequence< beans::PropertyValue > propList;
1405  xPropSet->getPropertyValue( aName ) >>= propList;
1406  sal_Int32 collectedProperties = 0;
1407  for ( const auto& rProp : std::as_const(propList) )
1408  {
1409  OUString propName = rProp.Name;
1410  if ( propName == "OOXGlossary" )
1411  {
1412  rProp.Value >>= glossaryDocDom;
1413  collectedProperties++;
1414  }
1415  if (propName == "OOXGlossaryDom")
1416  {
1417  rProp.Value >>= glossaryDomList;
1418  collectedProperties++;
1419  }
1420  if (collectedProperties == 2)
1421  break;
1422  }
1423 
1424  // no glossary dom to write
1425  if ( !glossaryDocDom.is() )
1426  return;
1427 
1428  m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
1429  oox::getRelationship(Relationship::GLOSSARYDOCUMENT),
1430  u"glossary/document.xml" );
1431 
1432  uno::Reference< io::XOutputStream > xOutputStream = GetFilter().openFragmentStream( "word/glossary/document.xml",
1433  "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml" );
1434 
1435  uno::Reference< xml::sax::XSAXSerializable > serializer( glossaryDocDom, uno::UNO_QUERY );
1436  uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1437  writer->setOutputStream( xOutputStream );
1438  serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1439  uno::Sequence< beans::StringPair >() );
1440 
1441  for ( const uno::Sequence< uno::Any>& glossaryElement : std::as_const(glossaryDomList))
1442  {
1443  OUString gTarget, gType, gId, contentType;
1444  uno::Reference<xml::dom::XDocument> xDom;
1445  glossaryElement[0] >>= xDom;
1446  glossaryElement[1] >>= gId;
1447  glossaryElement[2] >>= gType;
1448  glossaryElement[3] >>= gTarget;
1449  glossaryElement[4] >>= contentType;
1450  gId = gId.copy(3); //"rId" only save the numeric value
1451 
1452  PropertySet aProps(xOutputStream);
1453  aProps.setAnyProperty( PROP_RelId, uno::makeAny( gId.toInt32() ));
1454  m_rFilter.addRelation( xOutputStream, gType, gTarget);
1455  uno::Reference< xml::sax::XSAXSerializable > gserializer( xDom, uno::UNO_QUERY );
1456  writer->setOutputStream(GetFilter().openFragmentStream( "word/glossary/" + gTarget, contentType ) );
1457  gserializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1458  uno::Sequence< beans::StringPair >() );
1459  }
1460 }
1461 
1463 {
1464  uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1465 
1466  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1467  static constexpr OUStringLiteral aName = u"" UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1468  if ( !xPropSetInfo->hasPropertyByName( aName ) )
1469  return;
1470 
1471  uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomlist;
1472  uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomPropslist;
1473  uno::Sequence< beans::PropertyValue > propList;
1474  xPropSet->getPropertyValue( aName ) >>= propList;
1475  auto pProp = std::find_if(propList.begin(), propList.end(),
1476  [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXCustomXml"; });
1477  if (pProp != propList.end())
1478  pProp->Value >>= customXmlDomlist;
1479 
1480  pProp = std::find_if(propList.begin(), propList.end(),
1481  [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXCustomXmlProps"; });
1482  if (pProp != propList.end())
1483  pProp->Value >>= customXmlDomPropslist;
1484 
1485  for (sal_Int32 j = 0; j < customXmlDomlist.getLength(); j++)
1486  {
1487  uno::Reference<xml::dom::XDocument> customXmlDom = customXmlDomlist[j];
1488  uno::Reference<xml::dom::XDocument> customXmlDomProps = customXmlDomPropslist[j];
1489  if (customXmlDom.is())
1490  {
1491  m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
1492  oox::getRelationship(Relationship::CUSTOMXML),
1493  OUStringConcatenation("../customXml/item"+OUString::number(j+1)+".xml" ));
1494 
1495  uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDom, uno::UNO_QUERY );
1496  uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1497  writer->setOutputStream( GetFilter().openFragmentStream( "customXml/item"+OUString::number(j+1)+".xml",
1498  "application/xml" ) );
1499  serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1500  uno::Sequence< beans::StringPair >() );
1501  }
1502 
1503  if (customXmlDomProps.is())
1504  {
1505  uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDomProps, uno::UNO_QUERY );
1506  uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1507  writer->setOutputStream( GetFilter().openFragmentStream( "customXml/itemProps"+OUString::number(j+1)+".xml",
1508  "application/vnd.openxmlformats-officedocument.customXmlProperties+xml" ) );
1509  serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1510  uno::Sequence< beans::StringPair >() );
1511 
1512  // Adding itemprops's relationship entry to item.xml.rels file
1513  m_rFilter.addRelation( GetFilter().openFragmentStream( "customXml/item"+OUString::number(j+1)+".xml",
1514  "application/xml" ) ,
1515  oox::getRelationship(Relationship::CUSTOMXMLPROPS),
1516  OUStringConcatenation("itemProps"+OUString::number(j+1)+".xml" ));
1517  }
1518  }
1519 }
1520 
1522 {
1523  uno::Reference<document::XStorageBasedDocument> xStorageBasedDocument(m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
1524  if (!xStorageBasedDocument.is())
1525  return;
1526 
1527  uno::Reference<embed::XStorage> xDocumentStorage = xStorageBasedDocument->getDocumentStorage();
1528  OUString aMacrosName("_MS_VBA_Macros");
1529  if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aMacrosName))
1530  return;
1531 
1532  const sal_Int32 nOpenMode = embed::ElementModes::READ;
1533  uno::Reference<io::XStream> xMacrosStream = xDocumentStorage->openStreamElement(aMacrosName, nOpenMode);
1534  uno::Reference<io::XOutputStream> xProjectStream;
1535  if (xMacrosStream.is())
1536  {
1537  // First handle the project stream, this sets xProjectStream.
1538  std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xMacrosStream));
1539 
1540  xProjectStream = GetFilter().openFragmentStream("word/vbaProject.bin", "application/vnd.ms-office.vbaProject");
1541  uno::Reference<io::XStream> xOutputStream(xProjectStream, uno::UNO_QUERY);
1542  if (!xOutputStream.is())
1543  return;
1544  std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
1545 
1546  // Write the stream.
1547  pOut->WriteStream(*pIn);
1548 
1549  // Write the relationship.
1550  m_rFilter.addRelation(m_pDocumentFS->getOutputStream(), oox::getRelationship(Relationship::VBAPROJECT), u"vbaProject.bin");
1551  }
1552 
1553  OUString aDataName("_MS_VBA_Macros_XML");
1554  if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aDataName))
1555  return;
1556 
1557  uno::Reference<io::XStream> xDataStream = xDocumentStorage->openStreamElement(aDataName, nOpenMode);
1558  if (!xDataStream.is())
1559  return;
1560 
1561  // Then the data stream, which wants to work with an already set
1562  // xProjectStream.
1563  std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xDataStream));
1564 
1565  uno::Reference<io::XStream> xOutputStream(GetFilter().openFragmentStream("word/vbaData.xml", "application/vnd.ms-word.vbaData+xml"), uno::UNO_QUERY);
1566  if (!xOutputStream.is())
1567  return;
1568  std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
1569 
1570  // Write the stream.
1571  pOut->WriteStream(*pIn);
1572 
1573  // Write the relationship.
1574  if (!xProjectStream.is())
1575  return;
1576 
1577  m_rFilter.addRelation(xProjectStream, oox::getRelationship(Relationship::WORDVBADATA), u"vbaData.xml");
1578 }
1579 
1581 {
1582  uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1583 
1584  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1586  if ( !xPropSetInfo->hasPropertyByName( aName ) )
1587  return;
1588 
1589  uno::Sequence< beans::PropertyValue > embeddingsList;
1590  uno::Sequence< beans::PropertyValue > propList;
1591  xPropSet->getPropertyValue( aName ) >>= propList;
1592  auto pProp = std::find_if(propList.begin(), propList.end(),
1593  [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXEmbeddings"; });
1594  if (pProp != propList.end())
1595  pProp->Value >>= embeddingsList;
1596  for (const auto& rEmbedding : std::as_const(embeddingsList))
1597  {
1598  OUString embeddingPath = rEmbedding.Name;
1599  uno::Reference<io::XInputStream> embeddingsStream;
1600  rEmbedding.Value >>= embeddingsStream;
1601  if (!embeddingsStream)
1602  continue;
1603 
1604  OUString contentType;
1605  if (css::uno::Reference<css::beans::XPropertySet> xProps{ embeddingsStream,
1606  css::uno::UNO_QUERY })
1607  {
1608  try
1609  {
1610  const css::uno::Any val = xProps->getPropertyValue("MediaType");
1611  val >>= contentType;
1612  }
1613  catch (const css::beans::UnknownPropertyException&)
1614  {
1615  TOOLS_WARN_EXCEPTION("sw.ww8", "WriteEmbeddings: Embedding without MediaType");
1616  }
1617  }
1618 
1619  if (contentType.isEmpty())
1620  {
1621  // FIXME: this .xlsm hack is silly - if anything the mime-type for an existing embedded object should be read from [Content_Types].xml
1622  if (embeddingPath.endsWith(".xlsm"))
1623  contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
1624  else if (embeddingPath.endsWith(".bin"))
1625  contentType = "application/vnd.openxmlformats-officedocument.oleObject";
1626  else
1627  contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
1628  }
1629 
1630  uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream(embeddingPath,
1631  contentType);
1632  try
1633  {
1634  // tdf#131288: the stream must be seekable for direct access
1635  uno::Reference<io::XSeekable> xSeekable(embeddingsStream, uno::UNO_QUERY);
1636  if (xSeekable)
1637  xSeekable->seek(0); // tdf#131288: a previous save could position it elsewhere
1638  comphelper::OStorageHelper::CopyInputToOutput(embeddingsStream, xOutStream);
1639  }
1640  catch(const uno::Exception&)
1641  {
1642  TOOLS_WARN_EXCEPTION("sw.ww8", "WriteEmbeddings() ::Failed to copy Inputstream to outputstream exception caught");
1643  }
1644  xOutStream->closeOutput();
1645  }
1646 }
1647 
1649 {
1650  bool bMirroredMargins = false;
1652  {
1653  bMirroredMargins = true;
1654  }
1655  return bMirroredMargins;
1656 }
1657 
1659 {
1660  // setup the namespaces
1661  m_pDocumentFS->startElementNS( XML_w, XML_document, MainXmlNamespaces());
1662 
1663  if ( getenv("SW_DEBUG_DOM") )
1664  {
1665  m_rDoc.dumpAsXml();
1666  }
1667 
1668  // reset the incrementing linked-textboxes chain ID before re-saving.
1669  m_nLinkedTextboxesChainId=0;
1670  m_aLinkedTextboxesHelper.clear();
1671 
1672  // Write background page color
1673  if (std::unique_ptr<SvxBrushItem> oBrush = getBackground(); oBrush)
1674  {
1675  Color backgroundColor = oBrush->GetColor();
1676  OString aBackgroundColorStr = msfilter::util::ConvertColor(backgroundColor);
1677 
1678  m_pDocumentFS->singleElementNS(XML_w, XML_background, FSNS(XML_w, XML_color),
1679  aBackgroundColorStr);
1680  }
1681 
1682  // body
1683  m_pDocumentFS->startElementNS(XML_w, XML_body);
1684 
1685  m_pCurPam->GetPoint()->nNode = m_rDoc.GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
1686 
1687  // the text
1688  WriteText();
1689 
1690  // clear linked textboxes since old ones can't be linked to frames in a different section (correct?)
1691  m_aLinkedTextboxesHelper.clear();
1692 
1693  // the last section info
1694  m_pAttrOutput->EndParaSdtBlock();
1695  const WW8_SepInfo *pSectionInfo = m_pSections? m_pSections->CurrentSectionInfo(): nullptr;
1696  if ( pSectionInfo )
1697  SectionProperties( *pSectionInfo );
1698 
1699  // finish body and document
1700  m_pDocumentFS->endElementNS( XML_w, XML_body );
1701  m_pDocumentFS->endElementNS( XML_w, XML_document );
1702 }
1703 
1705 {
1707  pAttr->add( FSNS( XML_xmlns, XML_o ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(vmlOffice)), RTL_TEXTENCODING_UTF8) );
1708  pAttr->add( FSNS( XML_xmlns, XML_r ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(officeRel)), RTL_TEXTENCODING_UTF8) );
1709  pAttr->add( FSNS( XML_xmlns, XML_v ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(vml)), RTL_TEXTENCODING_UTF8) );
1710  pAttr->add( FSNS( XML_xmlns, XML_w ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(doc)), RTL_TEXTENCODING_UTF8) );
1711  pAttr->add( FSNS( XML_xmlns, XML_w10 ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(vmlWord)), RTL_TEXTENCODING_UTF8) );
1712  pAttr->add( FSNS( XML_xmlns, XML_wp ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(dmlWordDr)), RTL_TEXTENCODING_UTF8) );
1713  pAttr->add( FSNS( XML_xmlns, XML_wps ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(wps)), RTL_TEXTENCODING_UTF8) );
1714  pAttr->add( FSNS( XML_xmlns, XML_wpg ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(wpg)), RTL_TEXTENCODING_UTF8) );
1715  pAttr->add( FSNS( XML_xmlns, XML_mc ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(mce)), RTL_TEXTENCODING_UTF8) );
1716  pAttr->add( FSNS( XML_xmlns, XML_wp14 ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(wp14)), RTL_TEXTENCODING_UTF8) );
1717  pAttr->add( FSNS( XML_xmlns, XML_w14 ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(w14)), RTL_TEXTENCODING_UTF8) );
1718  pAttr->add( FSNS( XML_mc, XML_Ignorable ), "w14 wp14" );
1719  return pAttr;
1720 }
1721 
1722 bool DocxExport::ignoreAttributeForStyleDefaults( sal_uInt16 nWhich ) const
1723 {
1724  if( nWhich == RES_TEXTGRID )
1725  return true; // w:docGrid is written only to document.xml, not to styles.xml
1726  if (nWhich == RES_PARATR_HYPHENZONE)
1727  return true; // w:suppressAutoHyphens is only a formatting exception, not a default
1729 }
1730 
1732  bool bNeedsLastParaId)
1733 {
1734  const EditTextObject& rEditObj = rParaObj.GetTextObject();
1735  MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
1736 
1737  sal_Int32 nPara = rEditObj.GetParagraphCount();
1738  sal_Int32 nParaId = 0;
1739  for( sal_Int32 n = 0; n < nPara; ++n )
1740  {
1741  if( n )
1742  aAttrIter.NextPara( n );
1743 
1744  nParaId = AttrOutput().StartParagraph(ww8::WW8TableNodeInfo::Pointer_t(),
1745  bNeedsLastParaId && n == nPara - 1);
1746  rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
1747  OUString aStr( rEditObj.GetText( n ));
1748  sal_Int32 nCurrentPos = 0;
1749  const sal_Int32 nEnd = aStr.getLength();
1750  do {
1751  AttrOutput().StartRun( nullptr, 0 );
1752  const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
1753  rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
1754 
1755  bool bTextAtr = aAttrIter.IsTextAttr( nCurrentPos );
1756  if( !bTextAtr )
1757  {
1758  if( nCurrentPos == 0 && nNextAttr - nCurrentPos == aStr.getLength())
1759  AttrOutput().RunText( aStr, eChrSet );
1760  else
1761  {
1762  OUString tmp( aStr.copy( nCurrentPos, nNextAttr - nCurrentPos ));
1763  AttrOutput().RunText( tmp, eChrSet );
1764  }
1765  }
1766  AttrOutput().StartRunProperties();
1767  aAttrIter.OutAttr( nCurrentPos );
1768  AttrOutput().EndRunProperties( nullptr );
1769 
1770  nCurrentPos = nNextAttr;
1771  eChrSet = eNextChrSet;
1772  aAttrIter.NextPos();
1773 
1774  AttrOutput().EndRun( nullptr, 0 );
1775 
1776  } while( nCurrentPos < nEnd );
1777 // aAttrIter.OutParaAttr(false);
1778  AttrOutput().EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t());
1779  }
1780  return nParaId;
1781 }
1782 
1783 //Keep this function in-sync with the one in writerfilter/.../SettingsTable.cxx
1784 //Since this is not import code, "-1" needs to be handled as the mode that LO will save as.
1785 //To identify how your code should handle a "-1", look in DocxExport::WriteSettings().
1787 {
1788  sal_Int32 nWordCompatibilityMode = -1;
1789  uno::Reference< beans::XPropertySet > xPropSet(m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
1790  uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1791  if (xPropSetInfo->hasPropertyByName(UNO_NAME_MISC_OBJ_INTEROPGRABBAG))
1792  {
1793  uno::Sequence< beans::PropertyValue > propList;
1794  xPropSet->getPropertyValue( UNO_NAME_MISC_OBJ_INTEROPGRABBAG ) >>= propList;
1795 
1796  for (const auto& rProp : std::as_const(propList))
1797  {
1798  if (rProp.Name == "CompatSettings")
1799  {
1800  css::uno::Sequence< css::beans::PropertyValue > aCurrentCompatSettings;
1801  rProp.Value >>= aCurrentCompatSettings;
1802 
1803  for (const auto& rCurrentCompatSetting : std::as_const(aCurrentCompatSettings))
1804  {
1805  uno::Sequence< beans::PropertyValue > aCompatSetting;
1806  rCurrentCompatSetting.Value >>= aCompatSetting;
1807 
1808  OUString sName;
1809  OUString sUri;
1810  OUString sVal;
1811 
1812  for (const auto& rPropVal : std::as_const(aCompatSetting))
1813  {
1814  if ( rPropVal.Name == "name" ) rPropVal.Value >>= sName;
1815  if ( rPropVal.Name == "uri" ) rPropVal.Value >>= sUri;
1816  if ( rPropVal.Name == "val" ) rPropVal.Value >>= sVal;
1817  }
1818 
1819  if (sName == "compatibilityMode" && sUri == "http://schemas.microsoft.com/office/word")
1820  {
1821  const sal_Int32 nValidMode = sVal.toInt32();
1822  // if repeated, highest mode wins in MS Word. 11 is the first valid mode.
1823  if (nValidMode > 10 && nValidMode > nWordCompatibilityMode)
1824  nWordCompatibilityMode = nValidMode;
1825 
1826  }
1827  }
1828  }
1829  }
1830  }
1831 
1832  return nWordCompatibilityMode;
1833 }
1834 
1836 {
1837  mpFS = pFS;
1838 }
1839 
1841  std::shared_ptr<SwUnoCursor> & pCurrentPam,
1842  SwPaM& rOriginalPam, bool bDocm, bool bTemplate)
1843  : MSWordExportBase(rDocument, pCurrentPam, &rOriginalPam),
1844  m_rFilter( rFilter ),
1845  m_nHeaders( 0 ),
1846  m_nFooters( 0 ),
1847  m_nOLEObjects( 0 ),
1848  m_nActiveXControls( 0 ),
1849  m_nHeadersFootersInSection(0),
1850  m_bDocm(bDocm),
1851  m_bTemplate(bTemplate),
1852  m_pAuthorIDs(new SvtSecurityMapPersonalInfo)
1853 {
1854  // Write the document properties
1855  WriteProperties( );
1856 
1857  // relations for the document
1858  m_rFilter.addRelation( oox::getRelationship(Relationship::OFFICEDOCUMENT),
1859  u"word/document.xml" );
1860 
1861  // Set media type depending of document type
1862  OUString aMediaType;
1863  if (m_bDocm)
1864  {
1865  if (m_bTemplate)
1866  {
1867  aMediaType = "application/vnd.ms-word.template.macroEnabledTemplate.main+xml";
1868  }
1869  else
1870  {
1871  aMediaType = "application/vnd.ms-word.document.macroEnabled.main+xml";
1872  }
1873  }
1874  else
1875  {
1876  if (m_bTemplate)
1877  {
1878  aMediaType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml";
1879  }
1880  else
1881  {
1882  aMediaType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
1883  }
1884  }
1885 
1886 
1887  // the actual document
1888  m_pDocumentFS = m_rFilter.openFragmentStreamWithSerializer( "word/document.xml", aMediaType );
1889 
1891 
1892  // the DrawingML access
1894 
1895  // the attribute output for the document
1896  m_pAttrOutput.reset(new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML.get() ));
1897 
1898  // the related VMLExport
1899  m_pVMLExport.reset(new VMLExport( m_pDocumentFS, m_pAttrOutput.get() ));
1900 
1901  // the related drawing export
1902  m_pSdrExport.reset(new DocxSdrExport( *this, m_pDocumentFS, m_pDrawingML.get() ));
1903 }
1904 
1906 {
1907 }
1908 
1910 : evenAndOddHeaders( false )
1911 , defaultTabStop( 0 )
1912 , revisionView( true )
1913 , trackRevisions( false )
1914 {
1915 }
1916 
1918 {
1919  if( evenAndOddHeaders )
1920  return true;
1921  if( defaultTabStop != 0 )
1922  return true;
1923  if ( !revisionView )
1924  return true;
1925  if ( trackRevisions )
1926  return true;
1927 
1928  return false;
1929 }
1930 
1931 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void WriteFootnotesEndnotes()
Write footnotes.xml and endnotes.xml.
Definition: docxexport.cxx:666
void OutAttr(sal_Int32 nSwPos)
Definition: wrtw8esh.cxx:1118
void InitStyles()
Setup pStyles and write styles.xml.
Definition: docxexport.cxx:643
virtual void DoFormText(const SwInputField *pField) override
Definition: docxexport.cxx:368
sal_uLong GetIndex() const
Definition: node.hxx:291
sal_Int32 WhereNext() const
Definition: wrtww8.hxx:1488
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:102
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
bool hasData() const
const HdFtFlags WW8_FOOTER_FIRST
Definition: ww8scan.hxx:1601
Class to collect and output the sections/headers/footers.
Definition: wrtww8.hxx:194
DocxAttributeOutput & DocxAttrOutput() const
Access to the derived attribute output class.
Definition: docxexport.cxx:104
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
bool m_bDocm
If the result will be a .docm file or not.
Definition: docxexport.hxx:108
The class that has handlers for various resource types when exporting as DOCX.
Handles DOCX export of drawings.
bool IsSectionNode() const
Definition: node.hxx:645
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:227
rtl_TextEncoding GetNodeCharSet() const
Definition: wrtww8.hxx:1490
const OUString & GetText() const
Definition: ndtxt.hxx:218
SwDocShell * GetDocShell()
Definition: doc.hxx:1352
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:4436
virtual void AppendBookmarks(const SwTextNode &rNode, sal_Int32 nCurrentPos, sal_Int32 nLen) override
Definition: docxexport.cxx:148
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)
bool IsSecurityOptOpenReadOnly() const
sal_uIntPtr sal_uLong
OUString sDataSource
Definition: swdbdata.hxx:30
constexpr TypedWhichId< SwNumRuleItem > RES_PARATR_NUMRULE(72)
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
virtual void WriteHyperlinkData(const ::sw::mark::IFieldmark &rFieldmark) override
Definition: docxexport.cxx:323
Base class of all fields.
Definition: fldbas.hxx:289
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:909
sal_Int64 n
css::uno::Reference< css::frame::XModel3 > GetModel() const
Definition: doc.hxx:188
static auto WriteCompat(SwDoc const &rDoc,::sax_fastparser::FSHelperPtr const &rpFS, sal_Int32 &rTargetCompatibilityMode) -> void
Definition: docxexport.cxx:969
sal_Int16 nId
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:987
void WriteGlossary()
SwSectionFormat * GetFormat()
Definition: section.hxx:336
void WriteFonts()
Write word/fontTable.xml.
Definition: docxexport.cxx:873
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:1452
constexpr TypedWhichId< SvxPostureItem > RES_CHRATR_CJK_POSTURE(25)
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2685
const SwSection & GetSection() const
Definition: node.hxx:542
SwDoc & m_rDoc
Definition: docbm.cxx:1204
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:141
std::unique_ptr< DocxAttributeOutput > m_pAttrOutput
Attribute output for document.
Definition: docxexport.hxx:81
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
sal_Int32 getWordCompatibilityModeFromGrabBag() const
bool const m_bTemplate
Export is done into template (.dotx)
Definition: docxexport.hxx:111
Class to collect and output the styles table.
Definition: wrtww8.hxx:1570
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:99
ShapeExport & WriteShape(const css::uno::Reference< css::drawing::XShape > &xShape)
OUString sSuffix
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:426
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:375
void WritePostitFields()
Write comments.xml.
Definition: docxexport.cxx:723
oslFileHandle & pOut
const HdFtFlags WW8_FOOTER_EVEN
Definition: ww8scan.hxx:1598
sal_uLong GetStartValue() const
Definition: fmtline.hxx:57
OString WriteOLEObject(SwOLEObj &rObject, OUString &io_rProgID)
Definition: docxexport.cxx:397
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
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:801
OUString getRelationship(Relationship eRelationship)
virtual MSWordSections & Sections() const override
Access to the sections/headers/footres.
Definition: docxexport.cxx:109
#define UNO_NAME_MISC_OBJ_INTEROPGRABBAG
virtual void AppendAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen) override
Definition: docxexport.cxx:189
const char * sName
bool getOutputStream(ProgramOptions const &options, OString const &extension, std::ostream **ppOutputStream, OString &targetSourceFileName, OString &tmpSourceFileName)
constexpr TypedWhichId< SvxHyphenZoneItem > RES_PARATR_HYPHENZONE(69)
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_WEIGHT(15)
const HdFtFlags WW8_HEADER_ODD
Definition: ww8scan.hxx:1597
constexpr OUStringLiteral aData
Definition: ww8scan.hxx:48
Base class for various Writer styles.
Definition: format.hxx:46
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:160
void WriteEmbeddings()
Write word/embeddings/Worksheet[n].xlsx.
bool IsContentNode() const
Definition: node.hxx:629
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
virtual void PrepareNewPageDesc(const SfxItemSet *pSet, const SwNode &rNd, const SwFormatPageDesc *pNewPgDescFormat, const SwPageDesc *pNewPgDesc, bool bExtraPageBreak=false) override
Get ready for a new section.
Definition: docxexport.cxx:619
const EditTextObject & GetTextObject() const
::sax_fastparser::FSHelperPtr openFragmentStreamWithSerializer(const OUString &rStreamName, const OUString &rMediaType)
void WriteProperties()
Write docProps/core.xml.
Definition: docxexport.cxx:899
Style of a layout element.
Definition: frmfmt.hxx:59
#define TOOLS_WARN_EXCEPTION(area, stream)
static rtl::Reference< FastAttributeList > createAttrList()
SwDBData const & GetDBData()
Definition: docfld.cxx:371
virtual bool CollapseScriptsforWordOk(sal_uInt16 nScript, sal_uInt16 nWhich) override
Guess the script (asian/western).
Definition: docxexport.cxx:114
int i
void dumpAsXml(xmlTextWriterPtr=nullptr) const
Dumps the entire nodes structure to the given destination (file nodes.xml in the current directory by...
Definition: docfmt.cxx:1951
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:132
const SwPageDesc & GetPageDesc(const size_t i) const
Definition: doc.hxx:881
DocxExportFilter & m_rFilter
Pointer to the filter that owns us.
Definition: docxexport.hxx:69
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:616
virtual OUString GetText(sal_Int32 nPara) const =0
UseOnPage ReadUseOn() const
Definition: pagedesc.hxx:236
std::unique_ptr< oox::drawingml::DrawingML > m_pDrawingML
Access to the DrawingML writer.
Definition: docxexport.hxx:78
virtual void WriteHeadersFooters(sal_uInt8 nHeadFootFlags, const SwFrameFormat &rFormat, const SwFrameFormat &rLeftHeaderFormat, const SwFrameFormat &rLeftFooterFormat, const SwFrameFormat &rFirstPageFormat, sal_uInt8 nBreakCode, bool bEvenAndOddHeaders) override
Output the actual headers and footers.
Definition: docxexport.cxx:249
float u
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:328
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
uno::Reference< io::XInputStream > GetOLEObjectStream(uno::Reference< uno::XComponentContext > const &xContext, uno::Reference< embed::XEmbeddedObject > const &xObj, std::u16string_view i_rProgID, OUString &o_rMediaType, OUString &o_rRelationType, OUString &o_rSuffix, const char *&o_rpProgID)
OString ConvertColor(const Color &rColor)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:388
Marks a node in the document model.
Definition: ndindex.hxx:31
bool IsEndNode() const
Definition: node.hxx:633
virtual void OutputOLENode(const SwOLENode &) override
Output SwOLENode.
Definition: docxexport.cxx:602
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
void SetFS(::sax_fastparser::FSHelperPtr const &mpFS)
std::shared_ptr< FastSerializerHelper > FSHelperPtr
virtual void OutputEndNode(const SwEndNode &) override
Output SwEndNode.
Definition: docxexport.cxx:554
rtl::Reference< sax_fastparser::FastAttributeList > MainXmlNamespaces()
All xml namespaces to be used at the top of any text .xml file (main doc, headers, footers,...)
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
SwSectionFormat * GetParent() const
Definition: section.hxx:355
DocxExport(DocxExportFilter &rFilter, SwDoc &rDocument, std::shared_ptr< SwUnoCursor > &pCurrentPam, SwPaM &rOriginalPam, bool bDocm, bool bTemplate)
Pass the pDocument, pCurrentPam and pOriginalPam to the base class.
std::unique_ptr< DocxSdrExport > m_pSdrExport
Exporter of drawings.
Definition: docxexport.hxx:105
::comphelper::NamedValueCollection m_aSettings
virtual void WriteNumbering() override
Write the numbering table.
Definition: docxexport.cxx:763
SwFormat * DerivedFrom() const
Definition: format.hxx:112
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
DefTokenId nToken
virtual sal_uLong ReplaceCr(sal_uInt8 nChar) override
Definition: docxexport.cxx:612
constexpr TypedWhichId< SwTextGridItem > RES_TEXTGRID(115)
::sax_fastparser::FSHelperPtr m_pDocumentFS
Fast serializer for the document output.
Definition: docxexport.hxx:72
constexpr OUStringLiteral sMediaType
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_CJK_WEIGHT(26)
void WriteVBA()
Writes word/vbaProject.bin.
#define SAL_WARN_IF(condition, area, stream)
#define ERRCODE_NONE
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
unsigned char sal_uInt8
virtual sal_Int32 GetParagraphCount() const =0
bool IsTextAttr(sal_Int32 nSwPos)
Definition: wrtw8esh.cxx:1198
#define SAL_INFO(area, stream)
OUString aName
virtual ErrCode ExportDocument_Impl() override
Format-dependent part of the actual export.
Definition: docxexport.cxx:505
const HdFtFlags WW8_HEADER_FIRST
Definition: ww8scan.hxx:1600
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:318
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
SwNodes & GetNodes()
Definition: doc.hxx:409
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
void WriteDocVars(const sax_fastparser::FSHelperPtr &pFS)
Writes the part of settings.xml.
Definition: docxexport.cxx:916
const sal_uInt8 PageBreak
OReadImagesDocumentHandler::Image_XML_Namespace nNamespace
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:313
static void ResetCounters()
bool evenAndOddHeaders
returns true if there are any non-default settings (i.e. something to write)
Definition: docxexport.hxx:59
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
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:715
sal_Int32 DocxStringGetToken(DocxStringTokenMap const *pMap, std::u16string_view rName)
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:690
virtual void AppendBookmark(const OUString &rName) override
Definition: docxexport.cxx:178
Base class for WW8Export and DocxExport.
Definition: wrtww8.hxx:449
Reference< XModel > xModel
bool IsTableNode() const
Definition: node.hxx:641
virtual ~DocxExport() override
Destructor.
SwSectionNode * GetSectionNode()
Definition: node.hxx:608
Ends a section of nodes in the document model.
Definition: node.hxx:342
rtl_TextEncoding GetNextCharSet() const
Definition: wrtw8esh.cxx:1044
SectionType GetType() const
Definition: section.hxx:170
std::vector< ::sw::mark::IMark * > IMarkVector
Used to split the runs according to the bookmarks start and ends.
Definition: wrtww8.hxx:583
std::shared_ptr< WW8TableNodeInfo > Pointer_t
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_CJK_FONTSIZE(23)
OUString sCommand
Definition: swdbdata.hxx:31
OUString addRelation(const OUString &rType, std::u16string_view rTarget)
aStr
void NextPara(sal_Int32 nPar)
Definition: wrtw8esh.cxx:1024
constexpr TypedWhichId< SvxPostureItem > RES_CHRATR_POSTURE(11)
virtual OUString GetPar2() const override
aPromptText
Definition: expfld.cxx:1399
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:630
OString AddRelation(const OUString &rType, std::u16string_view rTarget)
Returns the relationd id.
Definition: docxexport.cxx:219
const SwEndNoteInfo & GetEndNoteInfo() const
Definition: doc.hxx:632
const HdFtFlags WW8_FOOTER_ODD
Definition: ww8scan.hxx:1599
virtual void ExportGrfBullet(const SwTextNode &) override
Definition: docxexport.cxx:213
const HdFtFlags WW8_HEADER_EVEN
Definition: ww8scan.hxx:1596
const SwFormatLineNumber & GetLineNumber(bool=true) const
Definition: fmtline.hxx:64
sal_Int32 WriteOutliner(const OutlinerParaObject &rOutliner, sal_uInt8 nTyp, bool bNeedsLastParaId)
Base class of the Writer document model elements.
Definition: node.hxx:80
void WriteMainText()
FIXME this is temporary, remotely reminding the method of the same name in WW8Export.
OUString sId