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