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 <config_wasm_strip.h>
21
22#include "docxexport.hxx"
23#include "docxexportfilter.hxx"
25#include "docxsdrexport.hxx"
26#include "docxhelper.hxx"
27
28#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
29#include <com/sun/star/document/XDocumentProperties.hpp>
30#include <com/sun/star/document/XStorageBasedDocument.hpp>
31#include <com/sun/star/drawing/XShape.hpp>
32#include <com/sun/star/i18n/ScriptType.hpp>
33#include <com/sun/star/frame/XModel.hpp>
34#include <com/sun/star/xml/dom/XDocument.hpp>
35#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
36#include <com/sun/star/xml/sax/Writer.hpp>
37#include <com/sun/star/awt/XControlModel.hpp>
38#include <com/sun/star/io/XSeekable.hpp>
39#include <com/sun/star/io/XStreamListener.hpp>
40#include <com/sun/star/sdb/CommandType.hpp>
41#include <com/sun/star/text/XTextFieldsSupplier.hpp>
42#include <com/sun/star/util/XModifiable.hpp>
43#include <com/sun/star/xml/xslt/XSLTTransformer.hpp>
44
45#include <oox/token/namespaces.hxx>
46#include <oox/token/tokens.hxx>
50#include <oox/export/shapes.hxx>
54#include <oox/ole/olehelper.hxx>
55
56#include <map>
57#include <algorithm>
58#include <condition_variable>
59#include <mutex>
60
61#include <IMark.hxx>
65#include <docsh.hxx>
66#include <ndtxt.hxx>
67#include "wrtww8.hxx"
68#include <fmtline.hxx>
69#include <fmtpdsc.hxx>
70#include <frmfmt.hxx>
71#include <section.hxx>
72#include <ftninfo.hxx>
73#include <pagedesc.hxx>
74#include <poolfmt.hxx>
75#include <redline.hxx>
76#include <swdbdata.hxx>
77
78#include <editeng/unoprnms.hxx>
79#include <editeng/editobj.hxx>
80#include <editeng/outlobj.hxx>
81#include <editeng/brushitem.hxx>
83
84#include <viewsh.hxx>
85#include <viewopt.hxx>
86
87#include "ww8scan.hxx"
88#include <oox/token/properties.hxx>
92#include <o3tl/any.hxx>
93#include <sal/log.hxx>
96
97using namespace sax_fastparser;
98using namespace ::comphelper;
99using namespace ::com::sun::star;
100using namespace ::oox;
101
103
104using sw::mark::IMark;
105
107{
108 return *m_pAttrOutput;
109}
110
112{
113 return *m_pAttrOutput;
114}
115
117{
118 return *m_pSections;
119}
120
121bool DocxExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
122{
123 // TODO FIXME is this actually true for docx? - this is ~copied from WW8
124 if ( nScript == i18n::ScriptType::ASIAN )
125 {
126 // for asian in ww8, there is only one fontsize
127 // and one fontstyle (posture/weight)
128 switch ( nWhich )
129 {
133 return false;
134 default:
135 break;
136 }
137 }
138 else if ( nScript != i18n::ScriptType::COMPLEX )
139 {
140 // for western in ww8, there is only one fontsize
141 // and one fontstyle (posture/weight)
142 switch ( nWhich )
143 {
147 return false;
148 default:
149 break;
150 }
151 }
152 return true;
153}
154
155void DocxExport::AppendBookmarks( const SwTextNode& rNode, sal_Int32 nCurrentPos, sal_Int32 nLen, const SwRedlineData* pRedlineData )
156{
157 std::vector< OUString > aStarts;
158 std::vector< OUString > aEnds;
159
160 IMarkVector aMarks;
161 if ( GetBookmarks( rNode, nCurrentPos, nCurrentPos + nLen, aMarks ) )
162 {
163 for ( IMark* pMark : aMarks )
164 {
165 const sal_Int32 nStart = pMark->GetMarkStart().GetContentIndex();
166 const sal_Int32 nEnd = pMark->GetMarkEnd().GetContentIndex();
167
168 if ( nStart == nCurrentPos )
169 aStarts.push_back( pMark->GetName() );
170
171 if ( nEnd == nCurrentPos )
172 aEnds.push_back( pMark->GetName() );
173 }
174 }
175
176 const OUString& aStr( rNode.GetText() );
177 const sal_Int32 nEnd = aStr.getLength();
178
179 if ( nCurrentPos == nEnd )
180 m_pAttrOutput->WriteFinalBookmarks_Impl( aStarts, aEnds );
181 else
182 m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds, pRedlineData );
183}
184
185void DocxExport::AppendBookmark( const OUString& rName )
186{
187 std::vector< OUString > aStarts { rName };
188 std::vector< OUString > aEnds { rName };
189
190 m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
191}
192
193void DocxExport::AppendAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen )
194{
195 std::vector< OUString > aStarts;
196 std::vector< OUString > aEnds;
197
198 IMarkVector aMarks;
199 if (GetAnnotationMarks(rAttrs, nCurrentPos, nCurrentPos + nLen, aMarks))
200 {
201 for ( IMark* pMark : aMarks )
202 {
203 const sal_Int32 nStart = pMark->GetMarkStart().GetContentIndex();
204 const sal_Int32 nEnd = pMark->GetMarkEnd().GetContentIndex();
205
206 if ( nStart == nCurrentPos )
207 aStarts.push_back( pMark->GetName() );
208
209 if ( nEnd == nCurrentPos )
210 aEnds.push_back( pMark->GetName() );
211 }
212 }
213
214 m_pAttrOutput->WriteAnnotationMarks_Impl( aStarts, aEnds );
215}
216
218{
219 // Just collect the bullets for now, numbering.xml is not yet started.
221}
222
223OString DocxExport::AddRelation( const OUString& rType, std::u16string_view rTarget )
224{
225 OUString sId = m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
226 rType, rTarget, true );
227
228 return sId.toUtf8();
229}
230
232{
233 bool bRet( false );
234
235 if (SfxItemState::SET != rFormat.GetItemState(RES_PARATR_NUMRULE, false))
236 {
237 if (const SwFormat *pParent = rFormat.DerivedFrom())
238 {
239 if (static_cast<const SwTextFormatColl*>(pParent)->IsAssignedToListLevelOfOutlineStyle())
240 {
241 ::sax_fastparser::FSHelperPtr pSerializer = m_pAttrOutput->GetSerializer( );
242 // Level 9 disables the outline
243 pSerializer->singleElementNS(XML_w, XML_outlineLvl, FSNS(XML_w, XML_val), "9");
244
245 bRet = true;
246 }
247 }
248 }
249
250 return bRet;
251}
252
254 const SwFrameFormat& rFormat, const SwFrameFormat& rLeftHeaderFormat, const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& rFirstPageFormat,
255 sal_uInt8 nBreakCode, bool bEvenAndOddHeaders )
256{
258
259 // document setting indicating the requirement of EVEN and ODD for both headers and footers
260 if ( nHeadFootFlags & ( nsHdFtFlags::WW8_FOOTER_EVEN | nsHdFtFlags::WW8_HEADER_EVEN ) && bEvenAndOddHeaders )
262
263 // Turn ON flag for 'Writing Headers \ Footers'
264 m_pAttrOutput->SetWritingHeaderFooter( true );
265
266 const bool bPrevSectionHadHeader = m_bHasHdr;
267 const bool bPrevSectionHadFooter = m_bHasFtr;
268 m_bHasHdr = m_bHasFtr = false;
269
270 // headers
271 if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
272 WriteHeaderFooter( &rLeftHeaderFormat, true, "even" );
274 {
275 if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
276 WriteHeaderFooter( &rFormat, true, "even" );
277 else if (bPrevSectionHadHeader && nBreakCode == 2)
278 WriteHeaderFooter( nullptr, true, "even" );
279 }
280
281 if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
282 WriteHeaderFooter( &rFormat, true, "default" );
283 else if (bPrevSectionHadHeader && nBreakCode == 2) // 2: nextPage
284 WriteHeaderFooter(nullptr, true, "default");
285
286 if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
287 WriteHeaderFooter( &rFirstPageFormat, true, "first" );
288 else if (bPrevSectionHadHeader && nBreakCode == 2)
289 WriteHeaderFooter(nullptr, true, "first");
290
291 // footers
292 if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
293 WriteHeaderFooter( &rLeftFooterFormat, false, "even" );
295 {
296 if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
297 WriteHeaderFooter( &rFormat, false, "even" );
298 else if (bPrevSectionHadFooter && nBreakCode == 2)
299 WriteHeaderFooter( nullptr, false, "even");
300 }
301
302 if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
303 WriteHeaderFooter( &rFormat, false, "default" );
304 else if (bPrevSectionHadFooter && nBreakCode == 2)
305 WriteHeaderFooter(nullptr, false, "default");
306
307 if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
308 WriteHeaderFooter( &rFirstPageFormat, false, "first" );
309 else if (bPrevSectionHadFooter && nBreakCode == 2)
310 WriteHeaderFooter(nullptr, false, "first");
311
312 // Turn OFF flag for 'Writing Headers \ Footers'
313 m_pAttrOutput->SetWritingHeaderFooter( false );
314}
315
316void DocxExport::OutputField( const SwField* pField, ww::eField eFieldType, const OUString& rFieldCmd, FieldFlags nMode )
317{
318 m_pAttrOutput->WriteField_Impl( pField, eFieldType, rFieldCmd, nMode );
319}
320
321void DocxExport::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
322{
323 m_pAttrOutput->WriteFormData_Impl( rFieldmark );
324}
325
326void DocxExport::WriteHyperlinkData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
327{
328 SAL_INFO("sw.ww8", "TODO DocxExport::WriteHyperlinkData().");
329}
330
331void DocxExport::DoComboBox(const OUString& rName,
332 const OUString& rHelp,
333 const OUString& rToolTip,
334 const OUString& rSelected,
335 const uno::Sequence<OUString>& rListItems)
336{
337 m_pDocumentFS->startElementNS(XML_w, XML_ffData);
338
339 m_pDocumentFS->singleElementNS(XML_w, XML_name, FSNS(XML_w, XML_val), rName);
340
341 m_pDocumentFS->singleElementNS(XML_w, XML_enabled);
342
343 if ( !rHelp.isEmpty() )
344 m_pDocumentFS->singleElementNS(XML_w, XML_helpText, FSNS(XML_w, XML_val), rHelp);
345
346 if ( !rToolTip.isEmpty() )
347 m_pDocumentFS->singleElementNS(XML_w, XML_statusText, FSNS(XML_w, XML_val), rToolTip);
348
349 m_pDocumentFS->startElementNS(XML_w, XML_ddList);
350
351 // Output the 0-based index of the selected value
352 sal_Int32 nId = comphelper::findValue(rListItems, rSelected);
353 if (nId == -1)
354 nId = 0;
355
356 m_pDocumentFS->singleElementNS(XML_w, XML_result, FSNS(XML_w, XML_val), OString::number(nId));
357
358 // unfortunately Word 2013 refuses to load DOCX with more than 25 listEntry
359 SAL_WARN_IF(25 < rListItems.getLength(), "sw.ww8", "DocxExport::DoComboBox data loss with more than 25 entries");
360 auto const nSize(std::min(sal_Int32(25), rListItems.getLength()));
361 for (auto i = 0; i < nSize; ++i)
362 {
363 m_pDocumentFS->singleElementNS(XML_w, XML_listEntry, FSNS(XML_w, XML_val), rListItems[i]);
364 }
365
366 m_pDocumentFS->endElementNS( XML_w, XML_ddList );
367
368 m_pDocumentFS->endElementNS( XML_w, XML_ffData );
369}
370
372{
373 assert(pField);
374 const OUString sStr = FieldString(ww::eFILLIN) + "\"" + pField->GetPar2() + "\"";
375 OutputField(pField, ww::eFILLIN, sStr);
376}
377
378OString DocxExport::OutputChart( uno::Reference< frame::XModel > const & xModel, sal_Int32 nCount, ::sax_fastparser::FSHelperPtr const & m_pSerializer )
379{
380 OUString aFileName = "charts/chart" + OUString::number(nCount) + ".xml";
381 OUString sId = m_rFilter.addRelation( m_pSerializer->getOutputStream(),
382 oox::getRelationship(Relationship::CHART),
383 aFileName );
384 aFileName = "word/charts/chart" + OUString::number(nCount) + ".xml";
387 "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" );
388
389#if !ENABLE_WASM_STRIP_CHART
390 // WASM_CHART change
391 // TODO: With Chart extracted this cannot really happen since
392 // no Chart could've been added at all
394 css::uno::Reference<css::util::XModifiable> xModifiable(xModel, css::uno::UNO_QUERY);
395 const bool bOldModified = xModifiable && xModifiable->isModified();
396 aChartExport.ExportContent();
397 if (!bOldModified && xModifiable && xModifiable->isModified())
398 // tdf#134973: the model could get modified: e.g., calling XChartDocument::getSubTitle(),
399 // which creates the object if absent, and sets the modified state.
400 xModifiable->setModified(bOldModified);
401#else
402 (void)xModel;
403#endif
404 return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
405}
406
407OString DocxExport::WriteOLEObject(SwOLEObj& rObject, OUString & io_rProgID)
408{
409 uno::Reference <embed::XEmbeddedObject> xObj( rObject.GetOleRef() );
410 uno::Reference<uno::XComponentContext> const xContext(
412
413 OUString sMediaType;
414 OUString sRelationType;
415 OUString sSuffix;
416 const char * pProgID(nullptr);
417
418 uno::Reference<io::XInputStream> const xInStream =
419 oox::GetOLEObjectStream(xContext, xObj, io_rProgID,
420 sMediaType, sRelationType, sSuffix, pProgID);
421
422 if (!xInStream.is())
423 {
424 return OString();
425 }
426
427 assert(!sMediaType.isEmpty());
428 assert(!sRelationType.isEmpty());
429 assert(!sSuffix.isEmpty());
430 OUString sFileName = "embeddings/oleObject" + OUString::number( ++m_nOLEObjects ) + "." + sSuffix;
431 uno::Reference<io::XOutputStream> const xOutStream =
432 GetFilter().openFragmentStream("word/" + sFileName, sMediaType);
433 assert(xOutStream.is()); // no reason why that could fail
434
435 try
436 {
438 }
439 catch (uno::Exception const&)
440 {
441 TOOLS_WARN_EXCEPTION("sw.ww8", "DocxExport::WriteOLEObject");
442 return OString();
443 }
444
445 OUString const sId = m_rFilter.addRelation( GetFS()->getOutputStream(),
446 sRelationType, sFileName );
447 if (pProgID)
448 {
449 io_rProgID = OUString::createFromAscii(pProgID);
450 }
451
452 return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
453}
454
455std::pair<OString, OString> DocxExport::WriteActiveXObject(const uno::Reference<drawing::XShape>& rxShape,
456 const uno::Reference<awt::XControlModel>& rxControlModel)
457{
459
460 // Write out ActiveX binary
461 const OUString sBinaryFileName = "word/activeX/activeX" + OUString::number(m_nActiveXControls) + ".bin";
462
463 OString sGUID;
464 OString sName;
465 uno::Reference<io::XStream> xOutStorage(m_rFilter.openFragmentStream(sBinaryFileName, "application/vnd.ms-office.activeX"), uno::UNO_QUERY);
466 if(xOutStorage.is())
467 {
468 oox::ole::OleStorage aOleStorage(m_rFilter.getComponentContext(), xOutStorage, false);
469 uno::Reference<io::XOutputStream> xOutputStream(aOleStorage.openOutputStream("contents"), uno::UNO_SET_THROW);
470 uno::Reference< css::frame::XModel > xModel( m_rDoc.GetDocShell() ? m_rDoc.GetDocShell()->GetModel() : nullptr );
472 if ( !exportHelper.isValid() )
473 return std::make_pair<OString, OString>(OString(), OString());
474 sGUID = OUStringToOString(exportHelper.getGUID(), RTL_TEXTENCODING_UTF8);
475 sName = OUStringToOString(exportHelper.getName(), RTL_TEXTENCODING_UTF8);
476 exportHelper.exportControl(xOutputStream, rxShape->getSize(), true);
477 aOleStorage.commit();
478 }
479
480 // Write out ActiveX fragment
481 const OUString sXMLFileName = "word/activeX/activeX" + OUString::number( m_nActiveXControls ) + ".xml";
482 ::sax_fastparser::FSHelperPtr pActiveXFS = m_rFilter.openFragmentStreamWithSerializer(sXMLFileName, "application/vnd.ms-office.activeX+xml" );
483
484 const OUString sBinaryId = m_rFilter.addRelation( pActiveXFS->getOutputStream(),
485 oox::getRelationship(Relationship::ACTIVEXCONTROLBINARY),
486 sBinaryFileName.subView(sBinaryFileName.lastIndexOf("/") + 1) );
487
488 pActiveXFS->singleElementNS(XML_ax, XML_ocx,
489 FSNS(XML_xmlns, XML_ax), m_rFilter.getNamespaceURL(OOX_NS(ax)),
490 FSNS(XML_xmlns, XML_r), m_rFilter.getNamespaceURL(OOX_NS(officeRel)),
491 FSNS(XML_ax, XML_classid), "{" + sGUID + "}",
492 FSNS(XML_ax, XML_persistence), "persistStorage",
493 FSNS(XML_r, XML_id), sBinaryId);
494
495 OString sXMLId = OUStringToOString(m_rFilter.addRelation(m_pDocumentFS->getOutputStream(),
496 oox::getRelationship(Relationship::CONTROL),
497 sXMLFileName.subView(sBinaryFileName.indexOf("/") + 1)),
498 RTL_TEXTENCODING_UTF8);
499
500 return std::pair<OString, OString>(sXMLId, sName);
501}
502
503void DocxExport::OutputDML(uno::Reference<drawing::XShape> const & xShape)
504{
505 uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
506 sal_Int32 nNamespace = XML_wps;
507 if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
508 nNamespace = XML_wpg;
509 else if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
510 nNamespace = XML_pic;
512 aExport.WriteShape(xShape);
513}
514
516{
517 // Set the 'Reviewing' flags in the settings structure
520
521 InitStyles();
522
523 // init sections
524 m_pSections.reset(new MSWordSections( *this ));
525
526 // Make sure images are counted from one, even when exporting multiple documents.
529
531
533
535
537
538 WriteFonts();
539
541
542 WriteTheme();
543
545
547
549
550 WriteVBA();
551
552 m_aLinkedTextboxesHelper.clear(); //final cleanup
553 m_pStyles.reset();
554 m_pSections.reset();
556
557 return ERRCODE_NONE;
558}
559
560void DocxExport::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum )
561{
562 AttrOutput().SectionBreak( msword::PageBreak, false, m_pSections->CurrentSectionInfo() );
563 m_pSections->AppendSection( pPageDesc, pFormat, nLnNum, m_pAttrOutput->IsFirstParagraph() );
564}
565
567{
569
571 {
572 // this originally comes from WW8Export::WriteText(), and looks like it
573 // could have some code common with SectionNode()...
574
575 const SwSection& rSect = rEndNode.StartOfSectionNode()->GetSectionNode()->GetSection();
576 if ( m_bStartTOX && SectionType::ToxContent == rSect.GetType() )
577 m_bStartTOX = false;
578
579 SwNodeIndex aIdx( rEndNode, 1 );
580 const SwNode& rNd = aIdx.GetNode();
581 if ( rNd.IsEndNode() && rNd.StartOfSectionNode()->IsSectionNode() )
582 return;
583
584 bool isInTable = IsInTable();
585 if ( !rNd.IsSectionNode() && isInTable ) // No sections in table
586 {
587 const SwSectionFormat* pParentFormat = rSect.GetFormat()->GetParent();
588 if( !pParentFormat )
589 pParentFormat = reinterpret_cast<SwSectionFormat*>(sal_IntPtr(-1));
590
591 sal_uLong nRstLnNum;
592 if( rNd.IsContentNode() )
594 else
595 nRstLnNum = 0;
596
597 AppendSection( m_pCurrentPageDesc, pParentFormat, nRstLnNum );
598 }
599 else
600 {
601 AttrOutput().SectionBreaks( rEndNode );
602 }
603 }
604 else if (TXT_MAINTEXT == m_nTextTyp && rEndNode.StartOfSectionNode()->IsTableNode())
605 // End node of a table: see if a section break should be written after the table.
606 AttrOutput().SectionBreaks(rEndNode);
607}
608
610{
611 SAL_INFO("sw.ww8", "TODO DocxExport::OutputGrfNode( const SwGrfNode& )" );
612}
613
615{
616 SAL_INFO("sw.ww8", "TODO DocxExport::OutputOLENode( const SwOLENode& )" );
617}
618
619void DocxExport::OutputLinkedOLE( const OUString& )
620{
621 // Nothing to implement here: WW8 only
622}
623
625{
626 // Completely unused for Docx export... only here for code sharing
627 // purpose with binary export
628 return 0;
629}
630
632 const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat,
633 const SwPageDesc* pNewPgDesc, bool bExtraPageBreak )
634{
635 // tell the attribute output that we are ready to write the section
636 // break [has to be output inside paragraph properties]
637 AttrOutput().SectionBreak( msword::PageBreak, false, m_pSections->CurrentSectionInfo(), bExtraPageBreak );
638
639 const SwSectionFormat* pFormat = GetSectionFormat( rNd );
640 const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
641
642 OSL_ENSURE( pNewPgDescFormat || pNewPgDesc, "Neither page desc format nor page desc provided." );
643
644 if ( pNewPgDescFormat )
645 {
646 m_pSections->AppendSection( *pNewPgDescFormat, rNd, pFormat, nLnNm );
647 }
648 else if ( pNewPgDesc )
649 {
650 m_pSections->AppendSection( pNewPgDesc, rNd, pFormat, nLnNm );
651 }
652
653}
654
656{
657 m_pStyles.reset(new MSWordStyles( *this, /*bListStyles =*/ true ));
658
659 // setup word/styles.xml and the relations + content type
660 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
661 oox::getRelationship(Relationship::STYLES),
662 u"styles.xml" );
663
666 "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" );
667
668 // switch the serializer to redirect the output to word/styles.xml
669 m_pAttrOutput->SetSerializer( pStylesFS );
670
671 // do the work
672 m_pStyles->OutputStylesTable();
673
674 // switch the serializer back
675 m_pAttrOutput->SetSerializer( m_pDocumentFS );
676}
677
679{
680 if ( m_pAttrOutput->HasFootnotes() )
681 {
682 // setup word/styles.xml and the relations + content type
683 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
684 oox::getRelationship(Relationship::FOOTNOTES),
685 u"footnotes.xml" );
686
687 ::sax_fastparser::FSHelperPtr pFootnotesFS =
688 m_rFilter.openFragmentStreamWithSerializer( "word/footnotes.xml",
689 "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" );
690
691 // switch the serializer to redirect the output to word/footnotes.xml
692 m_pAttrOutput->SetSerializer( pFootnotesFS );
693 // tdf#99227
694 m_pSdrExport->setSerializer( pFootnotesFS );
695 // tdf#107969
696 m_pVMLExport->SetFS(pFootnotesFS);
697
698 // do the work
699 m_pAttrOutput->FootnotesEndnotes( true );
700
701 // switch the serializer back
703 m_pSdrExport->setSerializer( m_pDocumentFS );
704 m_pAttrOutput->SetSerializer( m_pDocumentFS );
705 }
706
707 if ( !m_pAttrOutput->HasEndnotes() )
708 return;
709
710 // setup word/styles.xml and the relations + content type
711 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
712 oox::getRelationship(Relationship::ENDNOTES),
713 u"endnotes.xml" );
714
716 m_rFilter.openFragmentStreamWithSerializer( "word/endnotes.xml",
717 "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" );
718
719 // switch the serializer to redirect the output to word/endnotes.xml
720 m_pAttrOutput->SetSerializer( pEndnotesFS );
721 // tdf#99227
722 m_pSdrExport->setSerializer( pEndnotesFS );
723 // tdf#107969
724 m_pVMLExport->SetFS(pEndnotesFS);
725
726 // do the work
727 m_pAttrOutput->FootnotesEndnotes( false );
728
729 // switch the serializer back
731 m_pSdrExport->setSerializer( m_pDocumentFS );
732 m_pAttrOutput->SetSerializer( m_pDocumentFS );
733}
734
736{
737 if ( !m_pAttrOutput->HasPostitFields() )
738 return;
739
740 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
741 oox::getRelationship(Relationship::COMMENTS),
742 u"comments.xml" );
743
745 m_rFilter.openFragmentStreamWithSerializer( "word/comments.xml",
746 "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" );
747
748 pPostitFS->startElementNS( XML_w, XML_comments, MainXmlNamespaces());
749 m_pAttrOutput->SetSerializer( pPostitFS );
750 const auto eHasResolved = m_pAttrOutput->WritePostitFields();
751 m_pAttrOutput->SetSerializer( m_pDocumentFS );
752 pPostitFS->endElementNS( XML_w, XML_comments );
753
754 if (eHasResolved != DocxAttributeOutput::hasResolved::yes)
755 return;
756
757 m_rFilter.addRelation(m_pDocumentFS->getOutputStream(),
758 oox::getRelationship(Relationship::COMMENTSEXTENDED),
759 u"commentsExtended.xml");
760
762 "word/commentsExtended.xml",
763 "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml");
764
765 pPostitFS->startElementNS(XML_w15, XML_commentsEx, // Add namespaces manually now
766 FSNS(XML_xmlns, XML_mc), m_rFilter.getNamespaceURL(OOX_NS(mce)),
767 FSNS(XML_xmlns, XML_w15), m_rFilter.getNamespaceURL(OOX_NS(w15)),
768 FSNS(XML_mc, XML_Ignorable), "w15");
769 m_pAttrOutput->SetSerializer(pPostitFS);
770 m_pAttrOutput->WritePostItFieldsResolved();
771 m_pAttrOutput->SetSerializer(m_pDocumentFS);
772 pPostitFS->endElementNS(XML_w15, XML_commentsEx);
773}
774
776{
777 if ( !m_pUsedNumTable )
778 return; // no numbering is used
779
780 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
781 oox::getRelationship(Relationship::NUMBERING),
782 u"numbering.xml" );
783
785 "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" );
786
787 // switch the serializer to redirect the output to word/numbering.xml
788 m_pAttrOutput->SetSerializer( pNumberingFS );
789 m_pDrawingML->SetFS( pNumberingFS );
790
791 pNumberingFS->startElementNS( XML_w, XML_numbering,
792 FSNS( XML_xmlns, XML_w ), m_rFilter.getNamespaceURL(OOX_NS(doc)),
793 FSNS( XML_xmlns, XML_o ), m_rFilter.getNamespaceURL(OOX_NS(vmlOffice)),
794 FSNS( XML_xmlns, XML_r ), m_rFilter.getNamespaceURL(OOX_NS(officeRel)),
795 FSNS( XML_xmlns, XML_v ), m_rFilter.getNamespaceURL(OOX_NS(vml)),
796 FSNS( XML_xmlns, XML_mc ), m_rFilter.getNamespaceURL(OOX_NS(mce)),
797 FSNS( XML_xmlns, XML_w14 ), m_rFilter.getNamespaceURL(OOX_NS(w14)),
798 FSNS( XML_mc, XML_Ignorable ), "w14" );
799
801
803
805
806 pNumberingFS->endElementNS( XML_w, XML_numbering );
807
808 // switch the serializer back
809 m_pDrawingML->SetFS( m_pDocumentFS );
810 m_pAttrOutput->SetSerializer( m_pDocumentFS );
811}
812
813void DocxExport::WriteHeaderFooter( const SwFormat* pFormat, bool bHeader, const char* pType )
814{
815 // setup the xml stream
816 OUString aRelId;
818 if ( bHeader )
819 {
820 OUString aName( "header" + OUString::number( ++m_nHeaders ) + ".xml" );
821
822 aRelId = m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
823 oox::getRelationship(Relationship::HEADER),
824 aName );
825
827 "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" );
828
829 pFS->startElementNS( XML_w, XML_hdr, MainXmlNamespaces());
830 }
831 else
832 {
833 OUString aName( "footer" + OUString::number( ++m_nFooters ) + ".xml" );
834
835 aRelId = m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
836 oox::getRelationship(Relationship::FOOTER),
837 aName );
838
840 "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" );
841
842 pFS->startElementNS( XML_w, XML_ftr, MainXmlNamespaces());
843 }
844
845 // switch the serializer to redirect the output to word/styles.xml
846 m_pAttrOutput->SetSerializer( pFS );
847 m_pVMLExport->SetFS( pFS );
848 m_pSdrExport->setSerializer(pFS);
849 SetFS( pFS );
850 {
851 DocxTableExportContext aTableExportContext(*m_pAttrOutput);
852 // do the work
853 if (pFormat == nullptr)
855 else
856 WriteHeaderFooterText(*pFormat, bHeader);
857 m_pAttrOutput->EndParaSdtBlock();
858 }
859
860 // switch the serializer back
861 m_pAttrOutput->SetSerializer( m_pDocumentFS );
862 m_pVMLExport->SetFS( m_pDocumentFS );
863 m_pSdrExport->setSerializer(m_pDocumentFS);
865
866 // close the tag
867 sal_Int32 nReference;
868 if ( bHeader )
869 {
870 pFS->endElementNS( XML_w, XML_hdr );
871 nReference = XML_headerReference;
872 }
873 else
874 {
875 pFS->endElementNS( XML_w, XML_ftr );
876 nReference = XML_footerReference;
877 }
878
879 // and write the reference
880 m_pDocumentFS->singleElementNS( XML_w, nReference,
881 FSNS( XML_w, XML_type ), pType,
882 FSNS( XML_r, XML_id ), aRelId );
883}
884
886{
887 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
888 oox::getRelationship(Relationship::FONTTABLE),
889 u"fontTable.xml" );
890
892 "word/fontTable.xml",
893 "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" );
894
895 pFS->startElementNS( XML_w, XML_fonts,
896 FSNS( XML_xmlns, XML_w ), m_rFilter.getNamespaceURL(OOX_NS(doc)),
897 FSNS( XML_xmlns, XML_r ), m_rFilter.getNamespaceURL(OOX_NS(officeRel)) );
898
899 // switch the serializer to redirect the output to word/styles.xml
900 m_pAttrOutput->SetSerializer( pFS );
901
902 // do the work
904
905 // switch the serializer back
906 m_pAttrOutput->SetSerializer( m_pDocumentFS );
907
908 pFS->endElementNS( XML_w, XML_fonts );
909}
910
912{
913 // Write the core properties
914 SwDocShell* pDocShell( m_rDoc.GetDocShell( ) );
915 uno::Reference<document::XDocumentProperties> xDocProps;
916 bool bSecurityOptOpenReadOnly = false;
917 if ( pDocShell )
918 {
919 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
920 pDocShell->GetModel( ), uno::UNO_QUERY );
921 xDocProps = xDPS->getDocumentProperties();
922 bSecurityOptOpenReadOnly = pDocShell->IsSecurityOptOpenReadOnly();
923 }
924
925 m_rFilter.exportDocumentProperties( xDocProps, bSecurityOptOpenReadOnly );
926}
927
929{
930 SwDocShell* pDocShell = m_rDoc.GetDocShell();
931 if (!pDocShell)
932 {
933 return;
934 }
935
936 uno::Reference<text::XTextFieldsSupplier> xModel(pDocShell->GetModel(), uno::UNO_QUERY);
937 uno::Reference<container::XNameAccess> xTextFieldMasters = xModel->getTextFieldMasters();
938 uno::Sequence<rtl::OUString> aMasterNames = xTextFieldMasters->getElementNames();
939 if (!aMasterNames.hasElements())
940 {
941 return;
942 }
943
944 // Only write docVars if there will be at least a single docVar.
945 bool bStarted = false;
946 constexpr OUStringLiteral aPrefix(u"com.sun.star.text.fieldmaster.User.");
947 for (const auto& rMasterName : std::as_const(aMasterNames))
948 {
949 if (!rMasterName.startsWith(aPrefix))
950 {
951 // Not a user field.
952 continue;
953 }
954
955 uno::Reference<beans::XPropertySet> xField;
956 xTextFieldMasters->getByName(rMasterName) >>= xField;
957 if (!xField.is())
958 {
959 continue;
960 }
961
962 OUString aKey = rMasterName.copy(aPrefix.getLength());
963 OUString aValue;
964 xField->getPropertyValue("Content") >>= aValue;
965 if (!bStarted)
966 {
967 bStarted = true;
968 pFS->startElementNS(XML_w, XML_docVars);
969 }
970 pFS->singleElementNS(XML_w, XML_docVar, FSNS(XML_w, XML_name), aKey,
971 FSNS(XML_w, XML_val), aValue);
972 }
973
974 if (bStarted)
975 {
976 pFS->endElementNS(XML_w, XML_docVars);
977 }
978}
979
980static auto
982 sal_Int32 & rTargetCompatibilityMode) -> void
983{
984 if (!rDoc.getIDocumentSettingAccess().get(DocumentSettingId::ADD_EXT_LEADING))
985 {
986 rpFS->singleElementNS(XML_w, XML_noLeading);
987 if (rTargetCompatibilityMode > 14)
988 { // Word ignores noLeading in compatibilityMode 15
989 rTargetCompatibilityMode = 14;
990 }
991 }
992 // Do not justify lines with manual break
993 if (rDoc.getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK))
994 {
995 rpFS->singleElementNS(XML_w, XML_doNotExpandShiftReturn);
996 }
997 // tdf#146515 export "Use printer metrics for document formatting"
998 if (!rDoc.getIDocumentSettingAccess().get(DocumentSettingId::USE_VIRTUAL_DEVICE))
999 rpFS->singleElementNS(XML_w, XML_usePrinterMetrics);
1000}
1001
1003{
1005 if( !pViewShell && !m_aSettings.hasData() && !m_pAttrOutput->HasFootnotes() && !m_pAttrOutput->HasEndnotes())
1006 return;
1007
1008 SwDocShell* pDocShell = m_rDoc.GetDocShell();
1009
1010 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
1011 oox::getRelationship(Relationship::SETTINGS),
1012 u"settings.xml" );
1013
1015 "word/settings.xml",
1016 "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" );
1017
1018 pFS->startElementNS( XML_w, XML_settings,
1019 FSNS( XML_xmlns, XML_w ), m_rFilter.getNamespaceURL(OOX_NS(doc)) );
1020
1021 // Write protection
1022 const uno::Sequence<beans::PropertyValue> aInfo = pDocShell->GetModifyPasswordInfo();
1023 if (aInfo.hasElements())
1024 {
1025 OUString sAlgorithm, sSalt, sHash;
1026 sal_Int32 nCount = 0;
1027 for (const auto& prop : aInfo)
1028 {
1029 if (prop.Name == "algorithm-name")
1030 prop.Value >>= sAlgorithm;
1031 else if (prop.Name == "salt")
1032 prop.Value >>= sSalt;
1033 else if (prop.Name == "iteration-count")
1034 prop.Value >>= nCount;
1035 else if (prop.Name == "hash")
1036 prop.Value >>= sHash;
1037 }
1038 if (!sAlgorithm.isEmpty() && !sSalt.isEmpty() && !sHash.isEmpty())
1039 {
1040 sal_Int32 nAlgorithmSid = 0;
1041 if (sAlgorithm == "MD2")
1042 nAlgorithmSid = 1;
1043 else if (sAlgorithm == "MD4")
1044 nAlgorithmSid = 2;
1045 else if (sAlgorithm == "MD5")
1046 nAlgorithmSid = 3;
1047 else if (sAlgorithm == "SHA-1")
1048 nAlgorithmSid = 4;
1049 else if (sAlgorithm == "MAC")
1050 nAlgorithmSid = 5;
1051 else if (sAlgorithm == "RIPEMD")
1052 nAlgorithmSid = 6;
1053 else if (sAlgorithm == "RIPEMD-160")
1054 nAlgorithmSid = 7;
1055 else if (sAlgorithm == "HMAC")
1056 nAlgorithmSid = 9;
1057 else if (sAlgorithm == "SHA-256")
1058 nAlgorithmSid = 12;
1059 else if (sAlgorithm == "SHA-384")
1060 nAlgorithmSid = 13;
1061 else if (sAlgorithm == "SHA-512")
1062 nAlgorithmSid = 14;
1063
1064 if (nAlgorithmSid != 0)
1065 pFS->singleElementNS(XML_w, XML_writeProtection,
1066 FSNS(XML_w, XML_cryptProviderType), "rsaAES",
1067 FSNS(XML_w, XML_cryptAlgorithmClass), "hash",
1068 FSNS(XML_w, XML_cryptAlgorithmType), "typeAny",
1069 FSNS(XML_w, XML_cryptAlgorithmSid), OString::number(nAlgorithmSid).getStr(),
1070 FSNS(XML_w, XML_cryptSpinCount), OString::number(nCount).getStr(),
1071 FSNS(XML_w, XML_hash), sHash.toUtf8().getStr(),
1072 FSNS(XML_w, XML_salt), sSalt.toUtf8().getStr());
1073 }
1074 }
1075
1076 // View
1077 if (pViewShell && pViewShell->GetViewOptions()->getBrowseMode())
1078 {
1079 pFS->singleElementNS(XML_w, XML_view, FSNS(XML_w, XML_val), "web");
1080 }
1081
1082 // Zoom
1083 if (pViewShell)
1084 {
1087
1088 switch (pViewShell->GetViewOptions()->GetZoomType())
1089 {
1090 case SvxZoomType::WHOLEPAGE:
1091 pAttributeList->add(FSNS(XML_w, XML_val), "fullPage");
1092 break;
1093 case SvxZoomType::PAGEWIDTH:
1094 pAttributeList->add(FSNS(XML_w, XML_val), "bestFit");
1095 break;
1096 case SvxZoomType::OPTIMAL:
1097 pAttributeList->add(FSNS(XML_w, XML_val), "textFit");
1098 break;
1099 default:
1100 break;
1101 }
1102
1103 OString aZoom(OString::number(pViewShell->GetViewOptions()->GetZoom()));
1104 pAttributeList->add(FSNS(XML_w, XML_percent), aZoom);
1105 pFS->singleElementNS(XML_w, XML_zoom, pAttributeList);
1106 }
1107
1108 // Display Background Shape
1109 if (std::unique_ptr<SvxBrushItem> oBrush = getBackground(); oBrush)
1110 {
1111 // Turn on the 'displayBackgroundShape'
1112 pFS->singleElementNS(XML_w, XML_displayBackgroundShape);
1113 }
1114
1115 // Track Changes
1117 pFS->singleElementNS( XML_w, XML_revisionView,
1118 FSNS( XML_w, XML_insDel ), "0",
1119 FSNS( XML_w, XML_formatting ), "0" );
1120
1122 pFS->singleElementNS(XML_w, XML_trackRevisions);
1123
1124 // Mirror Margins
1125 if(isMirroredMargin())
1126 pFS->singleElementNS(XML_w, XML_mirrorMargins);
1127
1129 {
1130 pFS->singleElementNS(XML_w, XML_gutterAtTop);
1131 }
1132
1133 // Embed Fonts
1135 pFS->singleElementNS(XML_w, XML_embedTrueTypeFonts);
1136
1137 // Embed System Fonts
1139 pFS->singleElementNS(XML_w, XML_embedSystemFonts);
1140
1141 // Default Tab Stop
1142 if( m_aSettings.defaultTabStop != 0 )
1143 pFS->singleElementNS( XML_w, XML_defaultTabStop, FSNS( XML_w, XML_val ),
1144 OString::number(m_aSettings.defaultTabStop) );
1145
1146 // export current mail merge database and table names
1148 if ( !aData.sDataSource.isEmpty() && aData.nCommandType == css::sdb::CommandType::TABLE && !aData.sCommand.isEmpty() )
1149 {
1150 OUString sDataSource =
1151 "SELECT * FROM " +
1152 aData.sDataSource + // current database
1153 ".dbo." + // default database owner
1154 aData.sCommand + // sheet name
1155 "$"; // sheet identifier
1156 pFS->startElementNS( XML_w, XML_mailMerge );
1157 pFS->singleElementNS(XML_w, XML_mainDocumentType,
1158 FSNS( XML_w, XML_val ), "formLetters" );
1159 pFS->singleElementNS(XML_w, XML_dataType,
1160 FSNS( XML_w, XML_val ), "textFile" );
1161 pFS->singleElementNS( XML_w, XML_query,
1162 FSNS( XML_w, XML_val ), OUStringToOString( sDataSource, RTL_TEXTENCODING_UTF8 ).getStr() );
1163 pFS->endElementNS( XML_w, XML_mailMerge );
1164 }
1165
1166 // Automatic hyphenation: it's a global setting in Word, it's a paragraph setting in Writer.
1167 // Set it's value to "auto" and disable on paragraph level, if no hyphenation is used there.
1168 pFS->singleElementNS(XML_w, XML_autoHyphenation, FSNS(XML_w, XML_val), "true");
1169
1170 // Hyphenation details set depending on default style
1172 const SvxHyphenZoneItem* pZoneItem;
1173 if (pColl && (pZoneItem = pColl->GetItemIfSet(RES_PARATR_HYPHENZONE, false)))
1174 {
1175 if (pZoneItem->IsNoCapsHyphenation())
1176 pFS->singleElementNS(XML_w, XML_doNotHyphenateCaps);
1177
1178 if ( sal_Int16 nHyphenZone = pZoneItem->GetTextHyphenZone() )
1179 pFS->singleElementNS(XML_w, XML_hyphenationZone, FSNS(XML_w, XML_val),
1180 OString::number(nHyphenZone));
1181 }
1182
1183 // Even and Odd Headers
1185 pFS->singleElementNS(XML_w, XML_evenAndOddHeaders);
1186
1187 // Has Footnotes
1188 if( m_pAttrOutput->HasFootnotes())
1189 DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_footnotePr, m_rDoc.GetFootnoteInfo(), XML_footnote );
1190
1191 // Has Endnotes
1192 if( m_pAttrOutput->HasEndnotes())
1193 DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_endnotePr, m_rDoc.GetEndNoteInfo(), XML_endnote );
1194
1195 // Has themeFontLang information
1196 uno::Reference< beans::XPropertySet > xPropSet( pDocShell->GetBaseModel(), uno::UNO_QUERY_THROW );
1197
1198 bool bUseGrabBagProtection = false;
1199 bool bWriterWantsToProtect = false;
1200 bool bWriterWantsToProtectForm = false;
1201 bool bWriterWantsToProtectRedline = false;
1202 bool bHasDummyRedlineProtectionKey = false;
1203 bool bReadOnlyStatusUnchanged = true;
1204 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1206 m_pSections->DocumentIsProtected() )
1207 {
1208 bWriterWantsToProtect = bWriterWantsToProtectForm = true;
1209 }
1210 if ( xPropSetInfo->hasPropertyByName( "RedlineProtectionKey" ) )
1211 {
1212 uno::Sequence<sal_Int8> aKey;
1213 xPropSet->getPropertyValue( "RedlineProtectionKey" ) >>= aKey;
1214 bool bHasRedlineProtectionKey = aKey.hasElements();
1215 bHasDummyRedlineProtectionKey = aKey.getLength() == 1 && aKey[0] == 1;
1216 if ( bHasRedlineProtectionKey && !bHasDummyRedlineProtectionKey )
1217 bWriterWantsToProtect = bWriterWantsToProtectRedline = true;
1218 }
1219
1220 /* Compatibility Mode (tdf#131304)
1221 * 11: .doc level [Word 97-2003]
1222 * 12: .docx default [Word 2007] [LO < 7.0]
1223 * 14: [Word 2010]
1224 * 15: [Word 2013/2016/2019] [LO >= 7.0]
1225 *
1226 * The PRIMARY purpose of compatibility mode does not seem to be related to layout etc.
1227 * Its focus is on sharing files between multiple users, tracking the lowest supported mode in the group.
1228 * It is to BENEFIT older programs by not using certain new features that they don't understand.
1229 *
1230 * The next time the compat mode needs to be changed, I foresee the following steps:
1231 * 1.) Accept the new mode: Start round-tripping the new value, indicating we understand that format.
1232 * 2.) Many years later, change the TargetCompatilityMode for new documents, when we no longer care
1233 * about working with perfect compatibility with older versions of MS Word.
1234 */
1235 sal_Int32 nTargetCompatibilityMode = 15; //older versions might not open our files well
1236 bool bHasCompatibilityMode = false;
1237 const OUString aGrabBagName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1238 if ( xPropSetInfo->hasPropertyByName( aGrabBagName ) )
1239 {
1240 uno::Sequence< beans::PropertyValue > propList;
1241 xPropSet->getPropertyValue( aGrabBagName ) >>= propList;
1242
1243 for( const auto& rProp : std::as_const(propList) )
1244 {
1245 if ( rProp.Name == "ThemeFontLangProps" )
1246 {
1247 uno::Sequence< beans::PropertyValue > themeFontLangProps;
1248 rProp.Value >>= themeFontLangProps;
1249 OUString aValues[3];
1250 for( const auto& rThemeFontLangProp : std::as_const(themeFontLangProps) )
1251 {
1252 if( rThemeFontLangProp.Name == "val" )
1253 rThemeFontLangProp.Value >>= aValues[0];
1254 else if( rThemeFontLangProp.Name == "eastAsia" )
1255 rThemeFontLangProp.Value >>= aValues[1];
1256 else if( rThemeFontLangProp.Name == "bidi" )
1257 rThemeFontLangProp.Value >>= aValues[2];
1258 }
1259 pFS->singleElementNS( XML_w, XML_themeFontLang,
1260 FSNS( XML_w, XML_val ), aValues[0],
1261 FSNS( XML_w, XML_eastAsia ), aValues[1],
1262 FSNS( XML_w, XML_bidi ), aValues[2] );
1263 }
1264 else if ( rProp.Name == "CompatSettings" )
1265 {
1266 pFS->startElementNS(XML_w, XML_compat);
1267
1268 WriteCompat(m_rDoc, pFS, nTargetCompatibilityMode);
1269
1270 uno::Sequence< beans::PropertyValue > aCompatSettingsSequence;
1271 rProp.Value >>= aCompatSettingsSequence;
1272
1273 for(const auto& rCompatSetting : std::as_const(aCompatSettingsSequence))
1274 {
1275 uno::Sequence< beans::PropertyValue > aCompatSetting;
1276 rCompatSetting.Value >>= aCompatSetting;
1277 OUString aName;
1278 OUString aUri;
1279 OUString aValue;
1280
1281 for(const auto& rPropVal : std::as_const(aCompatSetting))
1282 {
1283 if( rPropVal.Name == "name" )
1284 rPropVal.Value >>= aName;
1285 else if( rPropVal.Name == "uri" )
1286 rPropVal.Value >>= aUri;
1287 else if( rPropVal.Name == "val" )
1288 rPropVal.Value >>= aValue;
1289 }
1290 if ( aName == "compatibilityMode" )
1291 {
1292 bHasCompatibilityMode = true;
1293 // Among the group of programs sharing this document, the lowest mode is retained.
1294 // Reduce this number if we are not comfortable with the new/unknown mode yet.
1295 // Step 1 in accepting a new mode would be to comment out the following clause
1296 // and roundtrip the new value instead of overwriting with the older number.
1297 // There are no newer modes at the time this code was written.
1298 if ( aValue.toInt32() > nTargetCompatibilityMode )
1299 aValue = OUString::number(nTargetCompatibilityMode);
1300 }
1301
1302 pFS->singleElementNS( XML_w, XML_compatSetting,
1303 FSNS( XML_w, XML_name ), aName,
1304 FSNS( XML_w, XML_uri ), aUri,
1305 FSNS( XML_w, XML_val ), aValue);
1306 }
1307
1308 if ( !bHasCompatibilityMode )
1309 {
1310 pFS->singleElementNS( XML_w, XML_compatSetting,
1311 FSNS( XML_w, XML_name ), "compatibilityMode",
1312 FSNS( XML_w, XML_uri ), "http://schemas.microsoft.com/office/word",
1313 FSNS( XML_w, XML_val ), OString::number(nTargetCompatibilityMode));
1314 bHasCompatibilityMode = true;
1315 }
1316
1317 pFS->endElementNS( XML_w, XML_compat );
1318 }
1319 else if (rProp.Name == "DocumentProtection")
1320 {
1321 uno::Sequence< beans::PropertyValue > rAttributeList;
1322 rProp.Value >>= rAttributeList;
1323
1324 if (rAttributeList.hasElements())
1325 {
1327 bool bIsProtectionTrackChanges = false;
1328 // if grabbag protection is not enforced, allow Writer protection to override
1329 bool bEnforced = false;
1330 for (const auto& rAttribute : std::as_const(rAttributeList))
1331 {
1332 static DocxStringTokenMap const aTokens[] =
1333 {
1334 { "edit", XML_edit },
1335 { "enforcement", XML_enforcement },
1336 { "formatting", XML_formatting },
1337 { "cryptProviderType", XML_cryptProviderType },
1338 { "cryptAlgorithmClass", XML_cryptAlgorithmClass },
1339 { "cryptAlgorithmType", XML_cryptAlgorithmType },
1340 { "cryptAlgorithmSid", XML_cryptAlgorithmSid },
1341 { "cryptSpinCount", XML_cryptSpinCount },
1342 { "hash", XML_hash },
1343 { "salt", XML_salt },
1344 { nullptr, 0 }
1345 };
1346
1347 if (sal_Int32 nToken = DocxStringGetToken(aTokens, rAttribute.Name))
1348 {
1349 OUString sValue = rAttribute.Value.get<OUString>();
1350 xAttributeList->add(FSNS(XML_w, nToken), sValue.toUtf8());
1351 if ( nToken == XML_edit && sValue == "trackedChanges" )
1352 bIsProtectionTrackChanges = true;
1353 else if ( nToken == XML_edit && sValue == "readOnly" )
1354 {
1355 // Ignore the case where read-only was not enforced, but now is. That is handled by _MarkAsFinal
1356 bReadOnlyStatusUnchanged = pDocShell->IsSecurityOptOpenReadOnly();
1357 }
1358 else if ( nToken == XML_enforcement )
1359 bEnforced = sValue.toBoolean();
1360 }
1361 }
1362
1363 // we have document protection from input DOCX file
1364 if ( !bEnforced )
1365 {
1366 // Leave as an un-enforced suggestion if Writer doesn't want to set any enforcement
1367 bUseGrabBagProtection = !bWriterWantsToProtect;
1368 }
1369 else
1370 {
1371 // Check if the grabbag protection is still valid
1372 // In the case of change tracking protection, we didn't modify it
1373 // and in the case of read-only, we didn't modify it.
1374 bUseGrabBagProtection = (!bIsProtectionTrackChanges || bHasDummyRedlineProtectionKey)
1375 && bReadOnlyStatusUnchanged;
1376 }
1377
1378 if ( bUseGrabBagProtection )
1379 {
1380 pFS->singleElementNS(XML_w, XML_documentProtection, xAttributeList);
1381 }
1382
1383 }
1384 }
1385 else if (rProp.Name == "HyphenationZone")
1386 {
1387 sal_Int16 nHyphenationZone = *o3tl::doAccess<sal_Int16>(rProp.Value);
1388 if (nHyphenationZone > 0)
1389 pFS->singleElementNS(XML_w, XML_hyphenationZone, FSNS(XML_w, XML_val),
1390 OString::number(nHyphenationZone));
1391 }
1392 }
1393 }
1394 if ( !bHasCompatibilityMode )
1395 {
1396 pFS->startElementNS(XML_w, XML_compat);
1397
1398 WriteCompat(m_rDoc, pFS, nTargetCompatibilityMode);
1399
1400 pFS->singleElementNS( XML_w, XML_compatSetting,
1401 FSNS( XML_w, XML_name ), "compatibilityMode",
1402 FSNS( XML_w, XML_uri ), "http://schemas.microsoft.com/office/word",
1403 FSNS( XML_w, XML_val ), OString::number(nTargetCompatibilityMode));
1404 pFS->endElementNS( XML_w, XML_compat );
1405 }
1406
1407 WriteDocVars(pFS);
1408
1409 if ( !bUseGrabBagProtection )
1410 {
1411 // Protect form - highest priority
1412 // Section-specific write protection
1413 if ( bWriterWantsToProtectForm )
1414 {
1415 // we have form protection from Writer or from input ODT file
1416
1417 pFS->singleElementNS(XML_w, XML_documentProtection,
1418 FSNS(XML_w, XML_edit), "forms",
1419 FSNS(XML_w, XML_enforcement), "true");
1420 }
1421 // Protect Change Tracking - next priority
1422 else if ( bWriterWantsToProtectRedline )
1423 {
1424 // we have change tracking protection from Writer or from input ODT file
1425
1426 pFS->singleElementNS(XML_w, XML_documentProtection,
1427 FSNS(XML_w, XML_edit), "trackedChanges",
1428 FSNS(XML_w, XML_enforcement), "1");
1429 }
1430 }
1431
1432 // finish settings.xml
1433 pFS->endElementNS( XML_w, XML_settings );
1434}
1435
1437{
1438 uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1439
1440 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1442 if ( !xPropSetInfo->hasPropertyByName( aName ) )
1443 return;
1444
1445 uno::Reference<xml::dom::XDocument> themeDom;
1446 uno::Sequence< beans::PropertyValue > propList;
1447 xPropSet->getPropertyValue( aName ) >>= propList;
1448 auto pProp = std::find_if(std::cbegin(propList), std::cend(propList),
1449 [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXTheme"; });
1450 if (pProp != std::cend(propList))
1451 pProp->Value >>= themeDom;
1452
1453 // no theme dom to write
1454 if ( !themeDom.is() )
1455 return;
1456
1457 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
1458 oox::getRelationship(Relationship::THEME),
1459 u"theme/theme1.xml" );
1460
1461 uno::Reference< xml::sax::XSAXSerializable > serializer( themeDom, uno::UNO_QUERY );
1462 uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1463 writer->setOutputStream( GetFilter().openFragmentStream( "word/theme/theme1.xml",
1464 "application/vnd.openxmlformats-officedocument.theme+xml" ) );
1465 serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1466 uno::Sequence< beans::StringPair >() );
1467}
1468
1470{
1471 uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1472
1473 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1475 if ( !xPropSetInfo->hasPropertyByName( aName ) )
1476 return;
1477
1478 uno::Reference<xml::dom::XDocument> glossaryDocDom;
1479 uno::Sequence< uno::Sequence< uno::Any> > glossaryDomList;
1480 uno::Sequence< beans::PropertyValue > propList;
1481 xPropSet->getPropertyValue( aName ) >>= propList;
1482 sal_Int32 collectedProperties = 0;
1483 for ( const auto& rProp : std::as_const(propList) )
1484 {
1485 OUString propName = rProp.Name;
1486 if ( propName == "OOXGlossary" )
1487 {
1488 rProp.Value >>= glossaryDocDom;
1489 collectedProperties++;
1490 }
1491 if (propName == "OOXGlossaryDom")
1492 {
1493 rProp.Value >>= glossaryDomList;
1494 collectedProperties++;
1495 }
1496 if (collectedProperties == 2)
1497 break;
1498 }
1499
1500 // no glossary dom to write
1501 if ( !glossaryDocDom.is() )
1502 return;
1503
1504 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
1505 oox::getRelationship(Relationship::GLOSSARYDOCUMENT),
1506 u"glossary/document.xml" );
1507
1508 uno::Reference< io::XOutputStream > xOutputStream = GetFilter().openFragmentStream( "word/glossary/document.xml",
1509 "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml" );
1510
1511 uno::Reference< xml::sax::XSAXSerializable > serializer( glossaryDocDom, uno::UNO_QUERY );
1512 uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1513 writer->setOutputStream( xOutputStream );
1514 serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1515 uno::Sequence< beans::StringPair >() );
1516
1517 for ( const uno::Sequence< uno::Any>& glossaryElement : std::as_const(glossaryDomList))
1518 {
1519 OUString gTarget, gType, gId, contentType;
1520 uno::Reference<xml::dom::XDocument> xDom;
1521 glossaryElement[0] >>= xDom;
1522 glossaryElement[1] >>= gId;
1523 glossaryElement[2] >>= gType;
1524 glossaryElement[3] >>= gTarget;
1525 glossaryElement[4] >>= contentType;
1526 gId = gId.copy(3); //"rId" only save the numeric value
1527
1528 PropertySet aProps(xOutputStream);
1529 aProps.setAnyProperty( PROP_RelId, uno::Any( gId.toInt32() ));
1530 m_rFilter.addRelation( xOutputStream, gType, gTarget);
1531 uno::Reference< xml::sax::XSAXSerializable > gserializer( xDom, uno::UNO_QUERY );
1532 writer->setOutputStream(GetFilter().openFragmentStream( "word/glossary/" + gTarget, contentType ) );
1533 gserializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1534 uno::Sequence< beans::StringPair >() );
1535 }
1536}
1537
1538namespace {
1539 class XsltTransformListener : public ::cppu::WeakImplHelper<io::XStreamListener>
1540 {
1541 public:
1542 XsltTransformListener() : m_bDone(false) {}
1543
1544 void wait() {
1545 std::unique_lock<std::mutex> g(m_mutex);
1546 m_cond.wait(g, [this]() { return m_bDone; });
1547 }
1548
1549 private:
1550 std::mutex m_mutex;
1551 std::condition_variable m_cond;
1552 bool m_bDone;
1553
1554 virtual void SAL_CALL disposing(const lang::EventObject&) noexcept override {}
1555 virtual void SAL_CALL started() noexcept override {}
1556 virtual void SAL_CALL closed() noexcept override { notifyDone(); }
1557 virtual void SAL_CALL terminated() noexcept override { notifyDone(); }
1558 virtual void SAL_CALL error(const uno::Any& e) override
1559 {
1560 notifyDone(); // set on error too, otherwise main thread waits forever
1561 SAL_WARN("sw.ww8", e);
1562 }
1563
1564 void notifyDone() {
1565 std::scoped_lock<std::mutex> g(m_mutex);
1566 m_bDone = true;
1567 m_cond.notify_all();
1568 }
1569 };
1570}
1571
1572static void lcl_UpdateXmlValues(const SdtData& sdtData, const uno::Reference<css::io::XInputStream>& xInputStream, const uno::Reference<css::io::XOutputStream>& xOutputStream)
1573{
1574 uno::Sequence<uno::Any> aArgs{
1575 // XSLT transformation stylesheet:
1576 // - write all elements as is
1577 // - but if element matches sdtData.xpath, replace its text content by sdtData.xpath
1578 uno::Any(beans::NamedValue("StylesheetText", uno::Any(OUString("<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
1579<xsl:stylesheet\
1580 xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\
1581 " + sdtData.namespaces + "\
1582 version=\"1.0\">\
1583 <xsl:template match=\"@* | node()\">\
1584 <xsl:copy>\
1585 <xsl:apply-templates select=\"@* | node()\"/>\
1586 </xsl:copy>\
1587 </xsl:template>\
1588 <xsl:template match = \"" + sdtData.xpath + "\">\
1589 <xsl:copy>\
1590 <xsl:text>" + sdtData.data + "</xsl:text>\
1591 </xsl:copy>\
1592 </xsl:template>\
1593</xsl:stylesheet>\
1594"))))
1595 };
1596
1597 css::uno::Reference<css::xml::xslt::XXSLTTransformer> xTransformer =
1598 css::xml::xslt::XSLTTransformer::create(comphelper::getProcessComponentContext(), aArgs);
1599 xTransformer->setInputStream(xInputStream);
1600 xTransformer->setOutputStream(xOutputStream);
1601
1602 rtl::Reference<XsltTransformListener> xListener = new XsltTransformListener();
1603 xTransformer->addListener(xListener);
1604
1605 xTransformer->start();
1606 xListener->wait();
1607}
1608
1610{
1611 uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1612
1613 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1614 if ( !xPropSetInfo->hasPropertyByName( UNO_NAME_MISC_OBJ_INTEROPGRABBAG ) )
1615 return;
1616
1617 uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomlist;
1618 uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomPropslist;
1619 uno::Sequence< beans::PropertyValue > propList;
1620 xPropSet->getPropertyValue( UNO_NAME_MISC_OBJ_INTEROPGRABBAG ) >>= propList;
1621 auto pProp = std::find_if(std::cbegin(propList), std::cend(propList),
1622 [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXCustomXml"; });
1623 if (pProp != std::cend(propList))
1624 pProp->Value >>= customXmlDomlist;
1625
1626 pProp = std::find_if(std::cbegin(propList), std::cend(propList),
1627 [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXCustomXmlProps"; });
1628 if (pProp != std::cend(propList))
1629 pProp->Value >>= customXmlDomPropslist;
1630
1631 for (sal_Int32 j = 0; j < customXmlDomlist.getLength(); j++)
1632 {
1633 uno::Reference<xml::dom::XDocument> customXmlDom = customXmlDomlist[j];
1634 uno::Reference<xml::dom::XDocument> customXmlDomProps = customXmlDomPropslist[j];
1635 if (customXmlDom.is())
1636 {
1637 m_rFilter.addRelation( m_pDocumentFS->getOutputStream(),
1638 oox::getRelationship(Relationship::CUSTOMXML),
1639 OUStringConcatenation("../customXml/item"+OUString::number(j+1)+".xml" ));
1640
1641 uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDom, uno::UNO_QUERY );
1642 uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1643
1644 uno::Reference < css::io::XOutputStream > xOutStream = GetFilter().openFragmentStream("customXml/item" + OUString::number(j + 1) + ".xml",
1645 "application/xml");
1646 if (m_SdtData.size())
1647 {
1648 // There are some SDT blocks data with data bindings which can update some custom xml values
1649 uno::Reference< io::XStream > xMemStream(
1650 comphelper::getProcessComponentContext()->getServiceManager()->createInstanceWithContext("com.sun.star.comp.MemoryStream",
1652 uno::UNO_QUERY_THROW);
1653
1654 writer->setOutputStream(xMemStream->getOutputStream());
1655
1656 serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
1657 uno::Sequence< beans::StringPair >());
1658
1659 uno::Reference< io::XStream > xXSLTInStream = xMemStream;
1660 uno::Reference< io::XStream > xXSLTOutStream;
1661 // Apply XSLT transformations for each SDT data binding
1662 // Seems it is not possible to do this as one transformation: each data binding
1663 // can have different namespaces, but with conflicting names (ns0, ns1, etc..)
1664 for (size_t i = 0; i < m_SdtData.size(); i++)
1665 {
1666 if (i == m_SdtData.size() - 1)
1667 {
1668 // last transformation
1669 lcl_UpdateXmlValues(m_SdtData[i], xXSLTInStream->getInputStream(), xOutStream);
1670 }
1671 else
1672 {
1673 xXSLTOutStream.set(
1674 comphelper::getProcessComponentContext()->getServiceManager()->createInstanceWithContext("com.sun.star.comp.MemoryStream",
1676 uno::UNO_QUERY_THROW);
1677 lcl_UpdateXmlValues(m_SdtData[i], xXSLTInStream->getInputStream(), xXSLTOutStream->getOutputStream());
1678 // Use previous output as an input for next run
1679 xXSLTInStream.set( xXSLTOutStream );
1680 }
1681 }
1682
1683 }
1684 else
1685 {
1686 writer->setOutputStream(xOutStream);
1687
1688 serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
1689 uno::Sequence< beans::StringPair >());
1690 }
1691 }
1692
1693 if (customXmlDomProps.is())
1694 {
1695 uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDomProps, uno::UNO_QUERY );
1696 uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
1697 writer->setOutputStream( GetFilter().openFragmentStream( "customXml/itemProps"+OUString::number(j+1)+".xml",
1698 "application/vnd.openxmlformats-officedocument.customXmlProperties+xml" ) );
1699 serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
1700 uno::Sequence< beans::StringPair >() );
1701
1702 // Adding itemprops's relationship entry to item.xml.rels file
1703 m_rFilter.addRelation( GetFilter().openFragmentStream( "customXml/item"+OUString::number(j+1)+".xml",
1704 "application/xml" ) ,
1705 oox::getRelationship(Relationship::CUSTOMXMLPROPS),
1706 OUStringConcatenation("itemProps"+OUString::number(j+1)+".xml" ));
1707 }
1708 }
1709}
1710
1712{
1713 uno::Reference<document::XStorageBasedDocument> xStorageBasedDocument(m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
1714 if (!xStorageBasedDocument.is())
1715 return;
1716
1717 uno::Reference<embed::XStorage> xDocumentStorage = xStorageBasedDocument->getDocumentStorage();
1718 OUString aMacrosName("_MS_VBA_Macros");
1719 if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aMacrosName))
1720 return;
1721
1722 const sal_Int32 nOpenMode = embed::ElementModes::READ;
1723 uno::Reference<io::XStream> xMacrosStream = xDocumentStorage->openStreamElement(aMacrosName, nOpenMode);
1724 uno::Reference<io::XOutputStream> xProjectStream;
1725 if (xMacrosStream.is())
1726 {
1727 // First handle the project stream, this sets xProjectStream.
1728 std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xMacrosStream));
1729
1730 xProjectStream = GetFilter().openFragmentStream("word/vbaProject.bin", "application/vnd.ms-office.vbaProject");
1731 uno::Reference<io::XStream> xOutputStream(xProjectStream, uno::UNO_QUERY);
1732 if (!xOutputStream.is())
1733 return;
1734 std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
1735
1736 // Write the stream.
1737 pOut->WriteStream(*pIn);
1738
1739 // Write the relationship.
1740 m_rFilter.addRelation(m_pDocumentFS->getOutputStream(), oox::getRelationship(Relationship::VBAPROJECT), u"vbaProject.bin");
1741 }
1742
1743 OUString aDataName("_MS_VBA_Macros_XML");
1744 if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aDataName))
1745 return;
1746
1747 uno::Reference<io::XStream> xDataStream = xDocumentStorage->openStreamElement(aDataName, nOpenMode);
1748 if (!xDataStream.is())
1749 return;
1750
1751 // Then the data stream, which wants to work with an already set
1752 // xProjectStream.
1753 std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xDataStream));
1754
1755 uno::Reference<io::XStream> xOutputStream(GetFilter().openFragmentStream("word/vbaData.xml", "application/vnd.ms-word.vbaData+xml"), uno::UNO_QUERY);
1756 if (!xOutputStream.is())
1757 return;
1758 std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
1759
1760 // Write the stream.
1761 pOut->WriteStream(*pIn);
1762
1763 // Write the relationship.
1764 if (!xProjectStream.is())
1765 return;
1766
1767 m_rFilter.addRelation(xProjectStream, oox::getRelationship(Relationship::WORDVBADATA), u"vbaData.xml");
1768}
1769
1771{
1772 uno::Reference< beans::XPropertySet > xPropSet( m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
1773
1774 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1776 if ( !xPropSetInfo->hasPropertyByName( aName ) )
1777 return;
1778
1779 uno::Sequence< beans::PropertyValue > embeddingsList;
1780 uno::Sequence< beans::PropertyValue > propList;
1781 xPropSet->getPropertyValue( aName ) >>= propList;
1782 auto pProp = std::find_if(std::cbegin(propList), std::cend(propList),
1783 [](const beans::PropertyValue& rProp) { return rProp.Name == "OOXEmbeddings"; });
1784 if (pProp != std::cend(propList))
1785 pProp->Value >>= embeddingsList;
1786 for (const auto& rEmbedding : std::as_const(embeddingsList))
1787 {
1788 OUString embeddingPath = rEmbedding.Name;
1789 uno::Reference<io::XInputStream> embeddingsStream;
1790 rEmbedding.Value >>= embeddingsStream;
1791 if (!embeddingsStream)
1792 continue;
1793
1794 OUString contentType;
1795 if (css::uno::Reference<css::beans::XPropertySet> xProps{ embeddingsStream,
1796 css::uno::UNO_QUERY })
1797 {
1798 try
1799 {
1800 const css::uno::Any val = xProps->getPropertyValue("MediaType");
1801 val >>= contentType;
1802 }
1803 catch (const css::beans::UnknownPropertyException&)
1804 {
1805 TOOLS_WARN_EXCEPTION("sw.ww8", "WriteEmbeddings: Embedding without MediaType");
1806 }
1807 }
1808
1809 if (contentType.isEmpty())
1810 {
1811 // FIXME: this .xlsm hack is silly - if anything the mime-type for an existing embedded object should be read from [Content_Types].xml
1812 if (embeddingPath.endsWith(".xlsm"))
1813 contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
1814 else if (embeddingPath.endsWith(".bin"))
1815 contentType = "application/vnd.openxmlformats-officedocument.oleObject";
1816 else
1817 contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
1818 }
1819
1820 uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream(embeddingPath,
1821 contentType);
1822 try
1823 {
1824 // tdf#131288: the stream must be seekable for direct access
1825 uno::Reference<io::XSeekable> xSeekable(embeddingsStream, uno::UNO_QUERY);
1826 if (xSeekable)
1827 xSeekable->seek(0); // tdf#131288: a previous save could position it elsewhere
1828 comphelper::OStorageHelper::CopyInputToOutput(embeddingsStream, xOutStream);
1829 }
1830 catch(const uno::Exception&)
1831 {
1832 TOOLS_WARN_EXCEPTION("sw.ww8", "WriteEmbeddings() ::Failed to copy Inputstream to outputstream exception caught");
1833 }
1834 xOutStream->closeOutput();
1835 }
1836}
1837
1839{
1840 bool bMirroredMargins = false;
1842 {
1843 bMirroredMargins = true;
1844 }
1845 return bMirroredMargins;
1846}
1847
1849{
1850 // setup the namespaces
1851 m_pDocumentFS->startElementNS( XML_w, XML_document, MainXmlNamespaces());
1852
1853 if ( getenv("SW_DEBUG_DOM") )
1854 {
1855 m_rDoc.dumpAsXml();
1856 }
1857
1858 // reset the incrementing linked-textboxes chain ID before re-saving.
1861
1862 // Write background page color
1863 if (std::unique_ptr<SvxBrushItem> oBrush = getBackground(); oBrush)
1864 {
1865 Color backgroundColor = oBrush->GetColor();
1866 OString aBackgroundColorStr = msfilter::util::ConvertColor(backgroundColor);
1867
1868 m_pDocumentFS->singleElementNS(XML_w, XML_background, FSNS(XML_w, XML_color),
1869 aBackgroundColorStr);
1870 }
1871
1872 // body
1873 m_pDocumentFS->startElementNS(XML_w, XML_body);
1874
1875 m_pCurPam->GetPoint()->Assign(*m_rDoc.GetNodes().GetEndOfContent().StartOfSectionNode());
1876
1877 // the text
1878 WriteText();
1879
1880 // clear linked textboxes since old ones can't be linked to frames in a different section (correct?)
1882
1883 // the last section info
1884 m_pAttrOutput->EndParaSdtBlock();
1885 const WW8_SepInfo *pSectionInfo = m_pSections? m_pSections->CurrentSectionInfo(): nullptr;
1886 if ( pSectionInfo )
1887 SectionProperties( *pSectionInfo );
1888
1889 // finish body and document
1890 m_pDocumentFS->endElementNS( XML_w, XML_body );
1891 m_pDocumentFS->endElementNS( XML_w, XML_document );
1892}
1893
1895{
1896 rtl::Reference<FastAttributeList> pAttr = FastSerializerHelper::createAttrList();
1897 pAttr->add( FSNS( XML_xmlns, XML_o ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(vmlOffice)), RTL_TEXTENCODING_UTF8) );
1898 pAttr->add( FSNS( XML_xmlns, XML_r ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(officeRel)), RTL_TEXTENCODING_UTF8) );
1899 pAttr->add( FSNS( XML_xmlns, XML_v ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(vml)), RTL_TEXTENCODING_UTF8) );
1900 pAttr->add( FSNS( XML_xmlns, XML_w ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(doc)), RTL_TEXTENCODING_UTF8) );
1901 pAttr->add( FSNS( XML_xmlns, XML_w10 ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(vmlWord)), RTL_TEXTENCODING_UTF8) );
1902 pAttr->add( FSNS( XML_xmlns, XML_wp ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(dmlWordDr)), RTL_TEXTENCODING_UTF8) );
1903 pAttr->add( FSNS( XML_xmlns, XML_wps ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(wps)), RTL_TEXTENCODING_UTF8) );
1904 pAttr->add( FSNS( XML_xmlns, XML_wpg ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(wpg)), RTL_TEXTENCODING_UTF8) );
1905 pAttr->add( FSNS( XML_xmlns, XML_mc ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(mce)), RTL_TEXTENCODING_UTF8) );
1906 pAttr->add( FSNS( XML_xmlns, XML_wp14 ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(wp14)), RTL_TEXTENCODING_UTF8) );
1907 pAttr->add( FSNS( XML_xmlns, XML_w14 ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(w14)), RTL_TEXTENCODING_UTF8) );
1908 pAttr->add( FSNS( XML_xmlns, XML_w15 ), OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(w15)), RTL_TEXTENCODING_UTF8));
1909 pAttr->add( FSNS( XML_mc, XML_Ignorable ), "w14 wp14 w15" );
1910 return pAttr;
1911}
1912
1913bool DocxExport::ignoreAttributeForStyleDefaults( sal_uInt16 nWhich ) const
1914{
1915 if( nWhich == RES_TEXTGRID )
1916 return true; // w:docGrid is written only to document.xml, not to styles.xml
1917 if (nWhich == RES_PARATR_HYPHENZONE)
1918 return true; // w:suppressAutoHyphens is only a formatting exception, not a default
1920}
1921
1923 bool bNeedsLastParaId)
1924{
1925 const EditTextObject& rEditObj = rParaObj.GetTextObject();
1926 MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
1927
1928 sal_Int32 nPara = rEditObj.GetParagraphCount();
1929 sal_Int32 nParaId = 0;
1930 for( sal_Int32 n = 0; n < nPara; ++n )
1931 {
1932 if( n )
1933 aAttrIter.NextPara( n );
1934
1936 bNeedsLastParaId && n == nPara - 1);
1937 rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
1938 OUString aStr( rEditObj.GetText( n ));
1939 sal_Int32 nCurrentPos = 0;
1940 const sal_Int32 nEnd = aStr.getLength();
1941
1942 // Write paragraph properties.
1944 aAttrIter.OutParaAttr(/*bCharAttr=*/false);
1945 SfxItemSet aParagraphMarkerProperties(m_rDoc.GetAttrPool());
1946 AttrOutput().EndParagraphProperties(aParagraphMarkerProperties, nullptr, nullptr, nullptr);
1947
1948 do {
1949 AttrOutput().StartRun( nullptr, 0 );
1950 const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
1951 rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
1952
1953 bool bTextAtr = aAttrIter.IsTextAttr( nCurrentPos );
1954 if( !bTextAtr )
1955 {
1956 if( nCurrentPos == 0 && nNextAttr - nCurrentPos == aStr.getLength())
1957 AttrOutput().RunText( aStr, eChrSet );
1958 else
1959 {
1960 OUString tmp( aStr.copy( nCurrentPos, nNextAttr - nCurrentPos ));
1961 AttrOutput().RunText( tmp, eChrSet );
1962 }
1963 }
1965 aAttrIter.OutAttr( nCurrentPos );
1966 AttrOutput().EndRunProperties( nullptr );
1967
1968 nCurrentPos = nNextAttr;
1969 eChrSet = eNextChrSet;
1970 aAttrIter.NextPos();
1971
1972 AttrOutput().EndRun( nullptr, 0, -1 );
1973
1974 } while( nCurrentPos < nEnd );
1975
1977 }
1978 return nParaId;
1979}
1980
1981//Keep this function in-sync with the one in writerfilter/.../SettingsTable.cxx
1982//Since this is not import code, "-1" needs to be handled as the mode that LO will save as.
1983//To identify how your code should handle a "-1", look in DocxExport::WriteSettings().
1985{
1986 sal_Int32 nWordCompatibilityMode = -1;
1987 uno::Reference< beans::XPropertySet > xPropSet(m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
1988 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1989 if (xPropSetInfo->hasPropertyByName(UNO_NAME_MISC_OBJ_INTEROPGRABBAG))
1990 {
1991 uno::Sequence< beans::PropertyValue > propList;
1992 xPropSet->getPropertyValue( UNO_NAME_MISC_OBJ_INTEROPGRABBAG ) >>= propList;
1993
1994 for (const auto& rProp : std::as_const(propList))
1995 {
1996 if (rProp.Name == "CompatSettings")
1997 {
1998 css::uno::Sequence< css::beans::PropertyValue > aCurrentCompatSettings;
1999 rProp.Value >>= aCurrentCompatSettings;
2000
2001 for (const auto& rCurrentCompatSetting : std::as_const(aCurrentCompatSettings))
2002 {
2003 uno::Sequence< beans::PropertyValue > aCompatSetting;
2004 rCurrentCompatSetting.Value >>= aCompatSetting;
2005
2006 OUString sName;
2007 OUString sUri;
2008 OUString sVal;
2009
2010 for (const auto& rPropVal : std::as_const(aCompatSetting))
2011 {
2012 if ( rPropVal.Name == "name" ) rPropVal.Value >>= sName;
2013 if ( rPropVal.Name == "uri" ) rPropVal.Value >>= sUri;
2014 if ( rPropVal.Name == "val" ) rPropVal.Value >>= sVal;
2015 }
2016
2017 if (sName == "compatibilityMode" && sUri == "http://schemas.microsoft.com/office/word")
2018 {
2019 const sal_Int32 nValidMode = sVal.toInt32();
2020 // if repeated, highest mode wins in MS Word. 11 is the first valid mode.
2021 if (nValidMode > 10 && nValidMode > nWordCompatibilityMode)
2022 nWordCompatibilityMode = nValidMode;
2023
2024 }
2025 }
2026 }
2027 }
2028 }
2029
2030 return nWordCompatibilityMode;
2031}
2032
2034{
2035 mpFS = pFS;
2036}
2037
2039 std::shared_ptr<SwUnoCursor> & pCurrentPam,
2040 SwPaM& rOriginalPam, bool bDocm, bool bTemplate)
2041 : MSWordExportBase(rDocument, pCurrentPam, &rOriginalPam),
2042 m_rFilter( rFilter ),
2043 m_nHeaders( 0 ),
2044 m_nFooters( 0 ),
2045 m_nOLEObjects( 0 ),
2046 m_nActiveXControls( 0 ),
2047 m_nHeadersFootersInSection(0),
2048 m_bDocm(bDocm),
2049 m_bTemplate(bTemplate),
2050 m_pAuthorIDs(new SvtSecurityMapPersonalInfo)
2051{
2052 // Write the document properties
2053 WriteProperties( );
2054
2055 // relations for the document
2056 m_rFilter.addRelation( oox::getRelationship(Relationship::OFFICEDOCUMENT),
2057 u"word/document.xml" );
2058
2059 // Set media type depending of document type
2060 OUString aMediaType;
2061 if (m_bDocm)
2062 {
2063 if (m_bTemplate)
2064 {
2065 aMediaType = "application/vnd.ms-word.template.macroEnabledTemplate.main+xml";
2066 }
2067 else
2068 {
2069 aMediaType = "application/vnd.ms-word.document.macroEnabled.main+xml";
2070 }
2071 }
2072 else
2073 {
2074 if (m_bTemplate)
2075 {
2076 aMediaType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml";
2077 }
2078 else
2079 {
2080 aMediaType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
2081 }
2082 }
2083
2084
2085 // the actual document
2086 m_pDocumentFS = m_rFilter.openFragmentStreamWithSerializer( "word/document.xml", aMediaType );
2087
2089
2090 // the DrawingML access
2092
2093 // the attribute output for the document
2094 m_pAttrOutput.reset(new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML.get() ));
2095
2096 // the related VMLExport
2098
2099 // the related drawing export
2100 m_pSdrExport.reset(new DocxSdrExport( *this, m_pDocumentFS, m_pDrawingML.get() ));
2101}
2102
2104{
2105}
2106
2108: evenAndOddHeaders( false )
2109, defaultTabStop( 0 )
2110, revisionView( true )
2111, trackRevisions( false )
2112{
2113}
2114
2116{
2117 if( evenAndOddHeaders )
2118 return true;
2119 if( defaultTabStop != 0 )
2120 return true;
2121 if ( !revisionView )
2122 return true;
2123 if ( trackRevisions )
2124 return true;
2125
2126 return false;
2127}
2128
2129/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ On
RedlineFlags on.
@ DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK
constexpr OUStringLiteral sMediaType
virtual void EndParagraphProperties(const SfxItemSet &rParagraphMarkerProperties, const SwRedlineData *pRedlineData, const SwRedlineData *pRedlineParagraphMarkerDeleted, const SwRedlineData *pRedlineParagraphMarkerInserted)=0
Called after we end outputting the attributes.
virtual void EmptyParagraph()=0
Empty paragraph.
virtual sal_Int32 StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, bool bGenerateParaId)=0
Start of the paragraph.
virtual void EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)=0
End of the paragraph.
virtual void RunText(const OUString &rText, rtl_TextEncoding eCharSet=RTL_TEXTENCODING_UTF8)=0
Output text (inside a run).
virtual void EndRun(const SwTextNode *pNode, sal_Int32 nPos, sal_Int32 nLen, bool bLastRun=false)=0
End of the text run.
virtual void StartRunProperties()=0
Called before we start outputting the attributes.
virtual void StartParagraphProperties()=0
Called before we start outputting the attributes.
virtual void StartRun(const SwRedlineData *pRedlineData, sal_Int32 nPos, bool bSingleEmptyRun=false)=0
Start of the text run.
virtual void SectionBreaks(const SwNode &rNode)=0
Called in order to output section breaks.
virtual void EndRunProperties(const SwRedlineData *pRedlineData)=0
Called after we end outputting the attributes.
virtual void SectionBreak(sal_uInt8 nC, bool bBreakAfter, const WW8_SepInfo *pSectionInfo=nullptr, bool bExtraPageBreak=false)=0
Write a section break msword::ColumnBreak or msword::PageBreak bBreakAfter: the break must be schedul...
The class that has handlers for various resource types when exporting as DOCX.
static void WriteFootnoteEndnotePr(::sax_fastparser::FSHelperPtr const &fs, int tag, const SwEndNoteInfo &info, int listtag)
writes the footnotePr/endnotePr (depending on tag) section
The physical access to the DOCX document (for writing).
virtual void WriteNumbering() override
Write the numbering table.
Definition: docxexport.cxx:775
rtl::Reference< sax_fastparser::FastAttributeList > MainXmlNamespaces()
All xml namespaces to be used at the top of any text .xml file (main doc, headers,...
virtual void AppendAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen) override
Definition: docxexport.cxx:193
sal_Int32 m_nFooters
Footer counter.
Definition: docxexport.hxx:98
void WriteTheme()
Write word/theme/theme1.xml.
virtual MSWordSections & Sections() const override
Access to the sections/headers/footres.
Definition: docxexport.cxx:116
virtual void OutputField(const SwField *pField, ww::eField eFieldType, const OUString &rFieldCmd, FieldFlags nMode=FieldFlags::All) override
Write the field.
Definition: docxexport.cxx:316
void WritePostitFields()
Write comments.xml.
Definition: docxexport.cxx:735
virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) override
Return value indicates if an inherited outline numbering is suppressed.
Definition: docxexport.cxx:231
OString AddRelation(const OUString &rType, std::u16string_view rTarget)
Returns the relationd id.
Definition: docxexport.cxx:223
std::pair< OString, OString > WriteActiveXObject(const uno::Reference< css::drawing::XShape > &rxShape, const uno::Reference< awt::XControlModel > &rxControlModel)
Definition: docxexport.cxx:455
sal_Int32 WriteOutliner(const OutlinerParaObject &rOutliner, sal_uInt8 nTyp, bool bNeedsLastParaId)
virtual void PrepareNewPageDesc(const SfxItemSet *pSet, const SwNode &rNd, const SwFormatPageDesc *pNewPgDescFormat, const SwPageDesc *pNewPgDesc, bool bExtraPageBreak=false) override
Get ready for a new section.
Definition: docxexport.cxx:631
virtual void AppendBookmark(const OUString &rName) override
Definition: docxexport.cxx:185
void WriteProperties()
Write docProps/core.xml.
Definition: docxexport.cxx:911
const ::sax_fastparser::FSHelperPtr & GetFS() const
Definition: docxexport.hxx:313
virtual void AppendBookmarks(const SwTextNode &rNode, sal_Int32 nCurrentPos, sal_Int32 nLen, const SwRedlineData *pRedlineData=nullptr) override
Definition: docxexport.cxx:155
std::vector< SdtData > m_SdtData
Storage for sdt data which need to be written to other XMLs.
Definition: docxexport.hxx:130
void WriteSettings()
Write word/settings.xml.
virtual ErrCode ExportDocument_Impl() override
Format-dependent part of the actual export.
Definition: docxexport.cxx:515
virtual void OutputOLENode(const SwOLENode &) override
Output SwOLENode.
Definition: docxexport.cxx:614
bool m_bDocm
If the result will be a .docm file or not.
Definition: docxexport.hxx:116
virtual void ExportGrfBullet(const SwTextNode &) override
Definition: docxexport.cxx:217
virtual sal_uInt64 ReplaceCr(sal_uInt8 nChar) override
Definition: docxexport.cxx:624
OString WriteOLEObject(SwOLEObj &rObject, OUString &io_rProgID)
Definition: docxexport.cxx:407
sal_Int32 m_nHeadersFootersInSection
Footer and Header counter in Section properties.
Definition: docxexport.hxx:107
::sax_fastparser::FSHelperPtr m_pDocumentFS
Fast serializer for the document output.
Definition: docxexport.hxx:80
std::unique_ptr< DocxSdrExport > m_pSdrExport
Exporter of drawings.
Definition: docxexport.hxx:113
::sax_fastparser::FSHelperPtr mpFS
Fast serializer to output the data.
Definition: docxexport.hxx:83
virtual void OutputGrfNode(const SwGrfNode &) override
Output SwGrfNode.
Definition: docxexport.cxx:609
virtual void AppendSection(const SwPageDesc *pPageDesc, const SwSectionFormat *pFormat, sal_uLong nLnNum) override
Definition: docxexport.cxx:560
DocxExportFilter & m_rFilter
Pointer to the filter that owns us.
Definition: docxexport.hxx:77
void InitStyles()
Setup pStyles and write styles.xml.
Definition: docxexport.cxx:655
void WriteMainText()
FIXME this is temporary, remotely reminding the method of the same name in WW8Export.
virtual void WriteHeadersFooters(sal_uInt8 nHeadFootFlags, const SwFrameFormat &rFormat, const SwFrameFormat &rLeftHeaderFormat, const SwFrameFormat &rLeftFooterFormat, const SwFrameFormat &rFirstPageFormat, sal_uInt8 nBreakCode, bool bEvenAndOddHeaders) override
Output the actual headers and footers.
Definition: docxexport.cxx:253
std::unique_ptr< MSWordSections > m_pSections
Sections/headers/footers.
Definition: docxexport.hxx:92
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:813
virtual void OutputLinkedOLE(const OUString &) override
Definition: docxexport.cxx:619
virtual void DoFormText(const SwInputField *pField) override
Definition: docxexport.cxx:371
bool const m_bTemplate
Export is done into template (.dotx)
Definition: docxexport.hxx:119
void WriteFootnotesEndnotes()
Write footnotes.xml and endnotes.xml.
Definition: docxexport.cxx:678
std::unique_ptr< DocxAttributeOutput > m_pAttrOutput
Attribute output for document.
Definition: docxexport.hxx:89
bool isMirroredMargin()
return true if Page Layout is set as Mirrored
sal_Int32 m_nOLEObjects
OLE objects counter.
Definition: docxexport.hxx:101
virtual ~DocxExport() override
Destructor.
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:331
virtual bool CollapseScriptsforWordOk(sal_uInt16 nScript, sal_uInt16 nWhich) override
Guess the script (asian/western).
Definition: docxexport.cxx:121
virtual void WriteHyperlinkData(const ::sw::mark::IFieldmark &rFieldmark) override
Definition: docxexport.cxx:326
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.
void WriteVBA()
Writes word/vbaProject.bin.
virtual void OutputEndNode(const SwEndNode &) override
Output SwEndNode.
Definition: docxexport.cxx:566
void WriteFonts()
Write word/fontTable.xml.
Definition: docxexport.cxx:885
void WriteEmbeddings()
Write word/embeddings/Worksheet[n].xlsx.
std::unique_ptr< oox::vml::VMLExport > m_pVMLExport
Exporter of the VML shapes.
Definition: docxexport.hxx:110
virtual AttributeOutputBase & AttrOutput() const override
Access to the attribute output class.
Definition: docxexport.cxx:106
std::unique_ptr< oox::drawingml::DrawingML > m_pDrawingML
Access to the DrawingML writer.
Definition: docxexport.hxx:86
DocxAttributeOutput & DocxAttrOutput() const
Access to the derived attribute output class.
Definition: docxexport.cxx:111
void SetFS(::sax_fastparser::FSHelperPtr const &mpFS)
void WriteDocVars(const sax_fastparser::FSHelperPtr &pFS)
Writes the <w:docVars> part of settings.xml.
Definition: docxexport.cxx:928
virtual void WriteFormData(const ::sw::mark::IFieldmark &rFieldmark) override
Write the data of the form field.
Definition: docxexport.cxx:321
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:378
DocxSettingsData m_aSettings
Definition: docxexport.hxx:121
DocxExportFilter & GetFilter()
Definition: docxexport.hxx:134
DocxExport(DocxExportFilter &rFilter, SwDoc &rDocument, std::shared_ptr< SwUnoCursor > &pCurrentPam, SwPaM &rOriginalPam, bool bDocm, bool bTemplate)
Pass the pDocument, pCurrentPam and pOriginalPam to the base class.
sal_Int32 getWordCompatibilityModeFromGrabBag() const
sal_Int32 m_nHeaders
Header counter.
Definition: docxexport.hxx:95
void WriteGlossary()
sal_Int32 m_nActiveXControls
ActiveX controls counter.
Definition: docxexport.hxx:104
void OutputDML(css::uno::Reference< css::drawing::XShape > const &xShape)
Writes the shape using drawingML syntax.
Definition: docxexport.cxx:503
void WriteCustomXml()
Write customXml/item[n].xml and customXml/itemProps[n].xml.
Handles DOCX export of drawings.
virtual sal_Int32 GetParagraphCount() const=0
virtual OUString GetText(sal_Int32 nPara) const=0
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
Base class for WW8Export and DocxExport.
Definition: wrtww8.hxx:451
void WriteText()
Iterate through the nodes and call the appropriate OutputNode() on them.
Definition: wrtww8.cxx:2785
sal_uInt8 m_nTextTyp
Definition: wrtww8.hxx:549
void WriteHeaderFooterText(const SwFormat &rFormat, bool bHeader)
Write header/footer text.
Definition: wrtw8sty.cxx:2074
int CollectGrfsOfBullets()
Populates m_vecBulletPic with all the bullet graphics used by numberings.
Definition: wrtww8.cxx:1522
bool IsInTable() const
Return whether currently exported node is in table.
Definition: wrtww8.cxx:2959
bool m_bOrigShowChanges
Remember the original Show Changes mode.
Definition: wrtww8.hxx:489
virtual void OutputEndNode(const SwEndNode &)
Output SwEndNode.
Definition: wrtww8.cxx:4440
RedlineFlags m_nOrigRedlineFlags
Remember the original redline mode.
Definition: wrtww8.hxx:488
std::unique_ptr< SvxBrushItem > getBackground()
Get background color of the document, if there is one.
Definition: wrtww8.cxx:1506
sal_Int32 m_nLinkedTextboxesChainId
Definition: wrtww8.hxx:518
std::unique_ptr< MSWordStyles > m_pStyles
Definition: wrtww8.hxx:503
std::vector< ::sw::mark::IMark * > IMarkVector
Used to split the runs according to the bookmarks start and ends.
Definition: wrtww8.hxx:585
wwFontHelper m_aFontHelper
Definition: wrtww8.hxx:453
static sal_uLong GetSectionLineNo(const SfxItemSet *pSet, const SwNode &rNd)
Line number of the section start.
Definition: ww8atr.cxx:668
const SwPageDesc * m_pCurrentPageDesc
Definition: wrtww8.hxx:497
void SectionProperties(const WW8_SepInfo &rSectionInfo, WW8_PdAttrDesc *pA=nullptr)
Write section properties.
Definition: wrtw8sty.cxx:1598
bool GetBookmarks(const SwTextNode &rNd, sal_Int32 nStt, sal_Int32 nEnd, IMarkVector &rArr)
Definition: wrtw8nds.cxx:1941
bool GetAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nStt, sal_Int32 nEnd, IMarkVector &rArr)
Definition: wrtw8nds.cxx:1988
std::unique_ptr< SwNumRuleTable > m_pUsedNumTable
Definition: wrtww8.hxx:460
std::shared_ptr< SwUnoCursor > & m_pCurPam
Definition: wrtww8.hxx:578
std::map< OUString, LinkedTextboxInfo > m_aLinkedTextboxesHelper
Definition: wrtww8.hxx:516
static const SwSectionFormat * GetSectionFormat(const SwNode &rNd)
Format of the section.
Definition: ww8atr.cxx:655
void AbstractNumberingDefinitions()
Write all Levels for all SwNumRules - LVLF.
Definition: wrtw8num.cxx:383
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:692
void BulletDefinitions()
Write the numbering picture bullets.
Definition: wrtww8.cxx:1563
void NumberingDefinitions()
Write static data of SwNumRule - LSTF.
Definition: wrtw8num.cxx:210
SwDoc & m_rDoc
Definition: wrtww8.hxx:576
Class to collect and output the sections/headers/footers.
Definition: wrtww8.hxx:196
Class to collect and output the styles table.
Definition: wrtww8.hxx:1581
Used to export formatted text associated to drawings.
Definition: wrtww8.hxx:1463
void OutAttr(sal_Int32 nSwPos)
Definition: wrtw8esh.cxx:1112
rtl_TextEncoding GetNextCharSet() const
Definition: wrtw8esh.cxx:1038
void OutParaAttr(bool bCharAttr, const std::set< sal_uInt16 > *pWhichsToIgnore=nullptr)
Definition: wrtw8esh.cxx:1275
rtl_TextEncoding GetNodeCharSet() const
Definition: wrtww8.hxx:1500
void NextPara(sal_Int32 nPar)
Definition: wrtw8esh.cxx:1018
bool IsTextAttr(sal_Int32 nSwPos)
Definition: wrtw8esh.cxx:1198
sal_Int32 WhereNext() const
Definition: wrtww8.hxx:1498
const EditTextObject & GetTextObject() const
bool IsSecurityOptOpenReadOnly() const
css::uno::Reference< css::frame::XModel3 > GetModel() const
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
const css::uno::Sequence< css::beans::PropertyValue > & GetModifyPasswordInfo() const
sal_uInt16 & GetTextHyphenZone()
bool IsNoCapsHyphenation() const
const SwFormatLineNumber & GetLineNumber(bool=true) const
Definition: fmtline.hxx:64
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:742
Definition: doc.hxx:192
SwDBData const & GetDBData()
Definition: docfld.cxx:384
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:634
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:1943
SwNodes & GetNodes()
Definition: doc.hxx:413
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:406
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:177
const SwEndNoteInfo & GetEndNoteInfo() const
Definition: doc.hxx:636
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:427
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1322
SwDocShell * GetDocShell()
Definition: doc.hxx:1355
const SwPageDesc & GetPageDesc(const size_t i) const
Definition: doc.hxx:885
Ends a section of nodes in the document model.
Definition: node.hxx:355
Base class of all fields.
Definition: fldbas.hxx:292
sal_uLong GetStartValue() const
Definition: fmtline.hxx:57
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:36
Base class for various Writer styles.
Definition: format.hxx:47
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:387
SwFormat * DerivedFrom() const
Definition: format.hxx:128
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
Templatized version of GetItemState() to directly return the correct type.
Definition: format.hxx:111
Style of a layout element.
Definition: frmfmt.hxx:62
virtual OUString GetPar2() const override
aPromptText
Definition: expfld.cxx:1408
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:136
Base class of the Writer document model elements.
Definition: node.hxx:84
SwSectionNode * GetSectionNode()
Definition: node.hxx:635
bool IsContentNode() const
Definition: node.hxx:656
bool IsEndNode() const
Definition: node.hxx:660
bool IsSectionNode() const
Definition: node.hxx:672
bool IsTableNode() const
Definition: node.hxx:668
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:137
SwContentNode * GetContentNode()
Definition: node.hxx:643
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:940
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
UseOnPage ReadUseOn() const
Definition: pagedesc.hxx:236
SwSectionFormat * GetParent() const
Definition: section.hxx:356
const SwSection & GetSection() const
Definition: node.hxx:567
SwSectionFormat * GetFormat()
Definition: section.hxx:337
SectionType GetType() const
Definition: section.hxx:171
Represents the style of a paragraph.
Definition: fmtcol.hxx:59
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:86
const OUString & GetText() const
Definition: ndtxt.hxx:222
SvxZoomType GetZoomType() const
Definition: viewopt.hxx:546
sal_uInt16 GetZoom() const
Definition: viewopt.hxx:505
bool getBrowseMode() const
Definition: viewopt.hxx:472
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:436
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
css::uno::Reference< css::io::XOutputStream > openOutputStream(const OUString &rStreamName)
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
::sax_fastparser::FSHelperPtr openFragmentStreamWithSerializer(const OUString &rStreamName, const OUString &rMediaType)
OUString addRelation(const OUString &rType, std::u16string_view rTarget)
css::uno::Reference< css::io::XOutputStream > openFragmentStream(const OUString &rStreamName, const OUString &rMediaType)
OUString getNamespaceURL(sal_Int32 nNSID) const
void exportDocumentProperties(const css::uno::Reference< css::document::XDocumentProperties > &xProperties, bool bSecurityOptOpenReadOnly)
static void PushExportGraphics()
static void PopExportGraphics()
static void ResetCounters()
ShapeExport & WriteShape(const css::uno::Reference< css::drawing::XShape > &xShape)
std::u16string_view getGUID() const
const OUString & getName() const
void exportControl(const css::uno::Reference< css::io::XOutputStream > &rxOut, const css::awt::Size &rSize, bool bAutoClose=false)
static rtl::Reference< FastAttributeList > createAttrList()
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
std::shared_ptr< WW8TableNodeInfoInner > Pointer_t
std::shared_ptr< WW8TableNodeInfo > Pointer_t
void WriteFontTable(SvStream *pTableStream, WW8Fib &pFib)
Definition: wrtw8sty.cxx:923
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
sal_Int32 DocxStringGetToken(DocxStringTokenMap const *pMap, std::u16string_view rName)
static void lcl_UpdateXmlValues(const SdtData &sdtData, const uno::Reference< css::io::XInputStream > &xInputStream, const uno::Reference< css::io::XOutputStream > &xOutputStream)
static auto WriteCompat(SwDoc const &rDoc, ::sax_fastparser::FSHelperPtr const &rpFS, sal_Int32 &rTargetCompatibilityMode) -> void
Definition: docxexport.cxx:981
float u
#define ERRCODE_NONE
FilterGroup & rTarget
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
constexpr TypedWhichId< SwTextGridItem > RES_TEXTGRID(115)
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_WEIGHT(15)
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_CJK_FONTSIZE(23)
constexpr TypedWhichId< SvxHyphenZoneItem > RES_PARATR_HYPHENZONE(69)
constexpr TypedWhichId< SvxPostureItem > RES_CHRATR_POSTURE(11)
constexpr TypedWhichId< SwNumRuleItem > RES_PARATR_NUMRULE(72)
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_CJK_WEIGHT(26)
constexpr TypedWhichId< SvxPostureItem > RES_CHRATR_CJK_POSTURE(25)
char const sHash[]
Mutex m_mutex
OUString aName
sal_Int64 n
OUString sSuffix
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
aStr
const char * sName
constexpr OUStringLiteral aData
Definition: ww8scan.hxx:48
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
Reference< XComponentContext > getProcessComponentContext()
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
int i
OString ConvertColor(const Color &rColor)
const sal_uInt8 PageBreak
const HdFtFlags WW8_HEADER_FIRST
Definition: ww8scan.hxx:1600
const HdFtFlags WW8_FOOTER_ODD
Definition: ww8scan.hxx:1599
const HdFtFlags WW8_FOOTER_EVEN
Definition: ww8scan.hxx:1598
const HdFtFlags WW8_HEADER_EVEN
Definition: ww8scan.hxx:1596
const HdFtFlags WW8_FOOTER_FIRST
Definition: ww8scan.hxx:1601
const HdFtFlags WW8_HEADER_ODD
Definition: ww8scan.hxx:1597
uno::Reference< io::XInputStream > GetOLEObjectStream(uno::Reference< uno::XComponentContext > const &xContext, uno::Reference< embed::XEmbeddedObject > const &xObj, std::u16string_view i_rProgID, OUString &o_rMediaType, OUString &o_rRelationType, OUString &o_rSuffix, const char *&o_rpProgID)
OUString getRelationship(Relationship eRelationship)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::shared_ptr< FastSerializerHelper > FSHelperPtr
bool getOutputStream(ProgramOptions const &options, OString const &extension, std::ostream **ppOutputStream, OString &targetSourceFileName, OString &tmpSourceFileName)
XML_type
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
sal_Int16 nId
const char * sGUID
@ RES_POOLCOLL_STANDARD
Standard.
Definition: poolfmt.hxx:250
DefTokenId nToken
sal_uIntPtr sal_uLong
OReadStatusBarDocumentHandler::StatusBar_XML_Namespace nNamespace
bool evenAndOddHeaders
returns true if there are any non-default settings (i.e. something to write)
Definition: docxexport.hxx:59
bool hasData() const
All the information that should be stashed away when we're in the middle of of a table export and sti...
Data to keep and write to XMLs.
Definition: docxexport.hxx:67
OUString namespaces
Definition: docxexport.hxx:68
OUString data
Definition: docxexport.hxx:70
OUString xpath
Definition: docxexport.hxx:69
Reference< XModel > xModel
unsigned char sal_uInt8
OUString sId
constexpr OUStringLiteral UNO_NAME_MISC_OBJ_INTEROPGRABBAG
oslFileHandle & pOut
FieldFlags
Definition: wrtww8.hxx:143
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2701
@ TXT_MAINTEXT
Definition: wrtww8.hxx:158