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