LibreOffice Module sw (master) 1
xmlfmte.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 <com/sun/star/text/XTextDocument.hpp>
22#include "xmlexpit.hxx"
27
28#include <xmloff/txtprmap.hxx>
29#include <xmloff/xmlaustp.hxx>
30#include <xmloff/families.hxx>
31#include <xmloff/maptype.hxx>
32#include <format.hxx>
33#include <fmtpdsc.hxx>
34#include <pagedesc.hxx>
35#include <cellatr.hxx>
36#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
37#include <com/sun/star/beans/XPropertySet.hpp>
38#include <com/sun/star/util/Color.hpp>
39#include "xmlexp.hxx"
40#include <SwStyleNameMapper.hxx>
41#include <osl/diagnose.h>
44
45#include <o3tl/enumrange.hxx>
46#include <svx/unoapi.hxx>
47#include <svx/svdpage.hxx>
50
51
52using namespace ::com::sun::star::beans;
53using namespace ::com::sun::star::uno;
54using namespace ::com::sun::star::text;
55using namespace ::com::sun::star::drawing;
56using namespace ::com::sun::star::lang;
57using namespace ::xmloff::token;
58
59void SwXMLExport::ExportFormat(const SwFormat& rFormat, enum XMLTokenEnum eFamily,
60 ::std::optional<OUString> const oStyleName)
61{
62 // <style:style ...>
64
65 // style:family="..."
66 OSL_ENSURE( RES_FRMFMT==rFormat.Which(), "frame format expected" );
67 if( RES_FRMFMT != rFormat.Which() )
68 return;
69 OSL_ENSURE( eFamily != XML_TOKEN_INVALID, "family must be specified" );
70 // style:name="..."
71 assert(oStyleName || (eFamily != XML_TABLE_ROW && eFamily != XML_TABLE_CELL));
72 bool bEncoded = false;
73 OUString const name(oStyleName ? *oStyleName : rFormat.GetName());
75 if( bEncoded )
76 {
78 }
79
80 if( eFamily != XML_TOKEN_INVALID )
82
83#if OSL_DEBUG_LEVEL > 0
84 // style:parent-style-name="..." (if it's not the default only)
85 const SwFormat* pParent = rFormat.DerivedFrom();
86 // Only adopt parent name, if it's not the default
87 OSL_ENSURE( !pParent || pParent->IsDefault(), "unexpected parent" );
88
89 OSL_ENSURE( USHRT_MAX == rFormat.GetPoolFormatId(), "pool ids aren't supported" );
90 OSL_ENSURE( USHRT_MAX == rFormat.GetPoolHelpId(), "help ids aren't supported" );
91 OSL_ENSURE( USHRT_MAX == rFormat.GetPoolHelpId() ||
92 UCHAR_MAX == rFormat.GetPoolHlpFileId(), "help file ids aren't supported" );
93#endif
94
95 // style:master-page-name
96 if( RES_FRMFMT == rFormat.Which() && XML_TABLE == eFamily )
97 {
98 if( const SwFormatPageDesc* pItem = rFormat.GetAttrSet().GetItemIfSet( RES_PAGEDESC,
99 false ) )
100 {
101 OUString sName;
102 const SwPageDesc *pPageDesc = pItem->GetPageDesc();
103 if( pPageDesc )
105 pPageDesc->GetName(),
106 sName,
110 }
111 }
112
113 if( XML_TABLE_CELL == eFamily )
114 {
115 OSL_ENSURE(RES_FRMFMT == rFormat.Which(), "only frame format");
116
117 if( const SwTableBoxNumFormat *pItem =
118 rFormat.GetAttrSet().GetItemIfSet( RES_BOXATR_FORMAT, false ) )
119 {
120 sal_Int32 nFormat = static_cast<sal_Int32>(pItem->GetValue());
121
122 if ( (nFormat != -1) && (nFormat != static_cast<sal_Int32>(getSwDefaultTextFormat())) )
123 {
124 // if we have a format, register and then export
125 // (Careful: here we assume that data styles will be
126 // written after cell styles)
127 addDataStyle(nFormat);
128 OUString sDataStyleName = getDataStyleName(nFormat);
129 if( !sDataStyleName.isEmpty() )
131 sDataStyleName );
132 }
133 }
134 }
135
136 {
138 true, true );
139
140 SvXMLItemMapEntriesRef xItemMap;
142 if( XML_TABLE == eFamily )
143 {
144 xItemMap = m_xTableItemMap;
145 }
146 else if( XML_TABLE_ROW == eFamily )
147 {
148 xItemMap = m_xTableRowItemMap;
149 ePropToken = XML_TABLE_ROW_PROPERTIES;
150 }
151 else if( XML_TABLE_CELL == eFamily )
152 {
153 xItemMap = m_xTableCellItemMap;
154 ePropToken = XML_TABLE_CELL_PROPERTIES;
155 }
156
157 if( xItemMap.is() )
158 {
159 m_pTableItemMapper->setMapEntries( xItemMap );
160 m_pTableItemMapper->exportXML( *this,
161 rFormat.GetAttrSet(),
163 ePropToken );
164 }
165 }
166}
167
169{
171
172 // drawing defaults
173 GetShapeExport()->ExportGraphicDefaults();
174
175 GetTextParagraphExport()->exportTextStyles( bUsed
177 );
178 collectDataStyles(true);
180 GetShapeExport()->GetShapeTableExport()->exportTableStyles();
181 //page defaults
182 GetPageExport()->exportDefaultStyle();
183
184 // Theme
185 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(GetModel(), UNO_QUERY);
186 if (xDrawPageSupplier.is())
187 {
188 uno::Reference<drawing::XDrawPage> xPage = xDrawPageSupplier->getDrawPage();
189 if (xPage.is())
190 ExportThemeElement(xPage);
191 }
192}
193
194void SwXMLExport::ExportThemeElement(const uno::Reference<drawing::XDrawPage>& xDrawPage)
195{
197 {
198 // Do not export in standard ODF 1.3 or older.
199 return;
200 }
201
202 SdrPage* pPage = GetSdrPageFromXDrawPage(xDrawPage);
203 SAL_WARN_IF(!pPage, "oox", "Can't get SdrPage from XDrawPage");
204
205 if (!pPage)
206 return;
207
208 auto const& pTheme = pPage->getSdrPageProperties().GetTheme();
209 if (!pTheme)
210 return;
211
212 if (!pTheme->GetName().isEmpty())
213 AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, pTheme->GetName());
214 SvXMLElementExport aTheme(*this, XML_NAMESPACE_LO_EXT, XML_THEME, true, true);
215
216 auto pColorSet = pTheme->getColorSet();
217 if (!pColorSet->getName().isEmpty())
218 AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, pColorSet->getName());
219 SvXMLElementExport aColorTable(*this, XML_NAMESPACE_LO_EXT, XML_THEME_COLORS, true, true);
220
221 static const XMLTokenEnum aColorTokens[] =
222 {
223 XML_DARK1, // Text 1
224 XML_LIGHT1, // Background 1
225 XML_DARK2, // Text 2
226 XML_LIGHT2, // Background 2
233 XML_HYPERLINK, // Hyperlink
234 XML_FOLLOWED_HYPERLINK, // Followed hyperlink
235 };
236
237 for (auto eThemeColorType : o3tl::enumrange<model::ThemeColorType>())
238 {
239 if (eThemeColorType == model::ThemeColorType::Unknown)
240 continue;
241
242 auto nColor = size_t(eThemeColorType);
243 AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, GetXMLToken(aColorTokens[nColor]));
244 OUStringBuffer sValue;
245 sax::Converter::convertColor(sValue, pColorSet->getColor(eThemeColorType));
246 AddAttribute(XML_NAMESPACE_LO_EXT, XML_COLOR, sValue.makeStringAndClear());
247 SvXMLElementExport aColor(*this, XML_NAMESPACE_LO_EXT, XML_COLOR, true, true);
248 }
249}
250
252{
254
256 return;
257
258 // The order in which styles are collected *MUST* be the same as
259 // the order in which they are exported. Otherwise, caching will
260 // fail.
261 if( getExportFlags() & (SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
262 {
263 if( !(getExportFlags() & SvXMLExportFlags::CONTENT) )
264 {
265 // only master pages are exported => styles for frames bound
266 // to frames (but none for frames bound to pages) need to be
267 // collected.
268 // TODO: exclude PageBoundFrames on export
269 }
270 }
271
272 // exported in _ExportMasterStyles
273 if( getExportFlags() & SvXMLExportFlags::MASTERSTYLES )
274 GetPageExport()->collectAutoStyles( false );
275
276
277 // exported in ExportContent_
278 if( getExportFlags() & SvXMLExportFlags::CONTENT )
279 {
280 // collect form autostyle
281 // (do this before collectTextAutoStyles, 'cause the shapes need the results of the work
282 // done by examineForms)
283 Reference<XDrawPageSupplier> xDrawPageSupplier( GetModel(), UNO_QUERY );
284 if (xDrawPageSupplier.is() && GetFormExport().is())
285 {
286 Reference<XDrawPage> xPage = xDrawPageSupplier->getDrawPage();
287 if (xPage.is())
288 GetFormExport()->examineForms(xPage);
289 }
290
291 GetTextParagraphExport()->collectTextAutoStylesOptimized( m_bShowProgress );
292 }
293
295}
296
298{
300
301 // if we don't export styles (i.e. in content stream only, but not
302 // in single-stream case), then we can save ourselves a bit of
303 // work and memory by not collecting field masters
304 if( !(getExportFlags() & SvXMLExportFlags::STYLES) )
305 GetTextParagraphExport()->exportUsedDeclarations();
306
307 // exported in ExportContent_
308 if( getExportFlags() & SvXMLExportFlags::CONTENT )
309 {
310 GetTextParagraphExport()->exportTrackedChanges( true );
311 }
312
313 GetTextParagraphExport()->exportTextAutoStyles();
314 GetShapeExport()->exportAutoStyles();
315 if( getExportFlags() & SvXMLExportFlags::MASTERSTYLES )
316 GetPageExport()->exportAutoStyles();
317
318 // we rely on data styles being written after cell styles in the
319 // ExportFormat() method; so be careful when changing order.
321
322 SvXMLExportFlags nContentAutostyles = SvXMLExportFlags::CONTENT | SvXMLExportFlags::AUTOSTYLES;
323 if ( ( getExportFlags() & nContentAutostyles ) == nContentAutostyles )
324 GetFormExport()->exportAutoStyles();
325}
326
328{
329 return new XMLTextMasterPageExport( *this );
330}
331
333{
334 // export master styles
335 GetPageExport()->exportMasterStyles( false );
336}
337
338namespace {
339
340class SwXMLAutoStylePoolP : public SvXMLAutoStylePoolP
341{
342 SvXMLExport& m_rExport;
343 const OUString m_sListStyleName;
344 const OUString m_sMasterPageName;
345
346protected:
347
348 virtual void exportStyleAttributes(
349 comphelper::AttributeList& rAttrList,
350 XmlStyleFamily nFamily,
351 const std::vector< XMLPropertyState >& rProperties,
352 const SvXMLExportPropertyMapper& rPropExp
353 , const SvXMLUnitConverter& rUnitConverter,
354 const SvXMLNamespaceMap& rNamespaceMap
355 ) const override;
356public:
357
358 explicit SwXMLAutoStylePoolP( SvXMLExport& rExport );
359};
360
361}
362
363void SwXMLAutoStylePoolP::exportStyleAttributes(
364 comphelper::AttributeList& rAttrList,
365 XmlStyleFamily nFamily,
366 const std::vector< XMLPropertyState >& rProperties,
367 const SvXMLExportPropertyMapper& rPropExp
368 , const SvXMLUnitConverter& rUnitConverter,
369 const SvXMLNamespaceMap& rNamespaceMap
370 ) const
371{
372 SvXMLAutoStylePoolP::exportStyleAttributes( rAttrList, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap);
373
374 if( XmlStyleFamily::TEXT_PARAGRAPH != nFamily )
375 return;
376
377 for( const auto& rProperty : rProperties )
378 {
379 if (rProperty.mnIndex != -1) // #i26762#
380 {
381 switch( rPropExp.getPropertySetMapper()->
382 GetEntryContextId( rProperty.mnIndex ) )
383 {
385 {
386 OUString sStyleName;
387 rProperty.maValue >>= sStyleName;
388 // #i70748# - export also empty list styles
389 if( !sStyleName.isEmpty() )
390 {
391 OUString sTmp = m_rExport.GetTextParagraphExport()->GetListAutoStylePool().Find( sStyleName );
392 if( !sTmp.isEmpty() )
393 sStyleName = sTmp;
394 }
395 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
396 m_sListStyleName,
397 GetExport().EncodeStyleName( sStyleName ) );
398 }
399 break;
400 case CTF_PAGEDESCNAME:
401 {
402 OUString sStyleName;
403 rProperty.maValue >>= sStyleName;
404 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
405 m_sMasterPageName,
406 GetExport().EncodeStyleName( sStyleName ) );
407 }
408 break;
409 }
410 }
411 }
412}
413
414SwXMLAutoStylePoolP::SwXMLAutoStylePoolP(SvXMLExport& rExp ) :
415 SvXMLAutoStylePoolP( rExp ),
416 m_rExport( rExp ),
417 m_sListStyleName( GetXMLToken( XML_LIST_STYLE_NAME ) ),
418 m_sMasterPageName( GetXMLToken( XML_MASTER_PAGE_NAME ) )
419{
420}
421
423{
424 return new SwXMLAutoStylePoolP( *this );
425}
426
427/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr sal_uInt32 getSwDefaultTextFormat()
The number formatter's default locale's @ Text format.
Definition: cellatr.hxx:37
std::shared_ptr< model::Theme > const & GetTheme() const
SdrPageProperties & getSdrPageProperties()
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
virtual void exportStyleAttributes(comphelper::AttributeList &rAttrList, XmlStyleFamily nFamily, const ::std::vector< XMLPropertyState > &rProperties, const SvXMLExportPropertyMapper &rPropExp, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap) const
const rtl::Reference< XMLPropertySetMapper > & getPropertySetMapper() const
virtual void ExportStyles_(bool bUsed)
rtl::Reference< XMLTextParagraphExport > const & GetTextParagraphExport()
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
bool mbAutoStylesCollected
SvXMLExportFlags getExportFlags() const
void collectDataStyles(bool bFromUsedStyles)
virtual void exportDataStyles()
const css::uno::Reference< css::frame::XModel > & GetModel() const
virtual OUString getDataStyleName(const sal_Int32 nNumberFormat, bool bTimeFormat=false) const
rtl::Reference< XMLPageExport > const & GetPageExport()
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
virtual void exportAutoDataStyles()
rtl::Reference< XMLShapeExport > const & GetShapeExport()
OUString EncodeStyleName(const OUString &rName, bool *pEncoded=nullptr) const
void CheckAttrList()
virtual void addDataStyle(const sal_Int32 nNumberFormat, bool bTimeFormat=false)
virtual void collectAutoStyles()
rtl::Reference< xmloff::OFormLayerXMLExport > const & GetFormExport()
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:36
Base class for various Writer styles.
Definition: format.hxx:47
bool IsDefault() const
Definition: format.hxx:129
sal_uInt16 GetPoolFormatId() const
Get and set Pool style IDs.
Definition: format.hxx:163
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
const OUString & GetName() const
Definition: format.hxx:131
sal_uInt16 GetPoolHelpId() const
Get and set Help-IDs for document templates.
Definition: format.hxx:167
sal_uInt8 GetPoolHlpFileId() const
Definition: format.hxx:169
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
SwFormat * DerivedFrom() const
Definition: format.hxx:128
const OUString & GetName() const
Definition: pagedesc.hxx:196
static void FillProgName(const OUString &rName, OUString &rFillName, SwGetPoolIdFromName)
SvXMLItemMapEntriesRef m_xTableCellItemMap
Definition: xmlexp.hxx:59
virtual SvXMLAutoStylePoolP * CreateAutoStylePool() override
Definition: xmlfmte.cxx:422
SvXMLItemMapEntriesRef m_xTableItemMap
Definition: xmlexp.hxx:57
const SvXMLUnitConverter & GetTwipUnitConverter() const
Definition: xmlexp.hxx:140
virtual void ExportMasterStyles_() override
Definition: xmlfmte.cxx:332
bool IsShowProgress() const
Definition: xmlexp.hxx:133
void ExportFormat(const SwFormat &rFormat, enum ::xmloff::token::XMLTokenEnum eClass, ::std::optional< OUString > const oStyleName)
Definition: xmlfmte.cxx:59
SvXMLItemMapEntriesRef m_xTableRowItemMap
Definition: xmlexp.hxx:58
bool m_bShowProgress
Definition: xmlexp.hxx:62
virtual void ExportStyles_(bool bUsed) override
Definition: xmlfmte.cxx:168
virtual XMLPageExport * CreatePageExport() override
Definition: xmlfmte.cxx:327
std::unique_ptr< SvXMLExportItemMapper > m_pTableItemMapper
Definition: xmlexp.hxx:54
virtual void ExportAutoStyles_() override
Definition: xmlfmte.cxx:297
void ExportThemeElement(const css::uno::Reference< css::drawing::XDrawPage > &xDrawPage)
Definition: xmlfmte.cxx:194
void collectAutoStyles() override
Definition: xmlfmte.cxx:251
static bool convertColor(sal_Int32 &rColor, std::u16string_view rValue)
bool is() const
XmlStyleFamily
OUString sName
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(99)
constexpr TypedWhichId< SwTableBoxNumFormat > RES_BOXATR_FORMAT(RES_BOXATR_BEGIN)
constexpr TypedWhichId< SwFrameFormat > RES_FRMFMT(161)
const char * name
#define SAL_WARN_IF(condition, area, stream)
XMLTokenEnum
XML_TABLE_ROW
XML_TABLE_CELL_PROPERTIES
XML_TABLE
XML_MASTER_PAGE_NAME
XML_ACCENT3
XML_LIST_STYLE_NAME
XML_THEME
XML_TOKEN_INVALID
XML_TABLE_PROPERTIES
XML_ACCENT4
XML_FAMILY
XML_ACCENT5
XML_LIGHT1
XML_STYLE
XML_DISPLAY_NAME
XML_DARK2
XML_HYPERLINK
XML_NAME
XML_THEME_COLORS
XML_FOLLOWED_HYPERLINK
XML_DATA_STYLE_NAME
XML_ACCENT2
XML_DARK1
XML_LIGHT2
XML_TABLE_CELL
XML_ACCENT6
XML_TABLE_ROW_PROPERTIES
XML_ACCENT1
XML_COLOR
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
#define CTF_NUMBERINGSTYLENAME
#define CTF_PAGEDESCNAME
SVXCORE_DLLPUBLIC SdrPage * GetSdrPageFromXDrawPage(const css::uno::Reference< css::drawing::XDrawPage > &xDrawPage) noexcept
SvXMLExportFlags
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
constexpr sal_uInt16 XML_NAMESPACE_STYLE