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