/src/libreoffice/xmloff/source/style/XMLPageExport.cxx
Line | Count | Source |
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 <xmloff/XMLPageExport.hxx> |
21 | | #include <o3tl/any.hxx> |
22 | | #include <sal/log.hxx> |
23 | | #include <xmloff/xmlnamespace.hxx> |
24 | | #include <xmloff/xmltoken.hxx> |
25 | | #include <com/sun/star/frame/XModel.hpp> |
26 | | #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> |
27 | | #include <com/sun/star/style/XStyle.hpp> |
28 | | #include <com/sun/star/beans/XPropertySet.hpp> |
29 | | #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
30 | | #include <xmloff/families.hxx> |
31 | | #include <xmloff/xmlexp.hxx> |
32 | | #include <PageMasterPropHdlFactory.hxx> |
33 | | #include <PageMasterStyleMap.hxx> |
34 | | #include <PageMasterPropMapper.hxx> |
35 | | #include "PageMasterExportPropMapper.hxx" |
36 | | |
37 | | using namespace ::com::sun::star; |
38 | | using namespace ::com::sun::star::uno; |
39 | | using namespace ::com::sun::star::style; |
40 | | using namespace ::com::sun::star::container; |
41 | | using namespace ::com::sun::star::beans; |
42 | | using namespace ::xmloff::token; |
43 | | |
44 | | constexpr OUString gsIsPhysical( u"IsPhysical"_ustr ); |
45 | | constexpr OUString gsFollowStyle( u"FollowStyle"_ustr ); |
46 | | constexpr OUString gsFirstShareContent( u"FirstIsShared"_ustr ); |
47 | | constexpr OUString gsHeaderNoFirst( u"HeaderNoFirst"_ustr ); |
48 | | constexpr OUString gsFooterNoFirst( u"FooterNoFirst"_ustr ); |
49 | | |
50 | | namespace { |
51 | | |
52 | | bool findPageMasterNameEntry( |
53 | | ::std::vector<XMLPageExportNameEntry> const& aNameVector, |
54 | | const OUString& rStyleName, XMLPageExportNameEntry & o_rEntry) |
55 | 0 | { |
56 | 0 | auto pEntry = std::find_if(aNameVector.cbegin(), aNameVector.cend(), |
57 | 0 | [&rStyleName](const XMLPageExportNameEntry& rEntry) { return rEntry.sStyleName == rStyleName; }); |
58 | |
|
59 | 0 | if( pEntry != aNameVector.cend() ) |
60 | 0 | { |
61 | 0 | o_rEntry = *pEntry; |
62 | 0 | return true; |
63 | 0 | } |
64 | | |
65 | 0 | return false; |
66 | 0 | } |
67 | | |
68 | | } // namespace |
69 | | |
70 | | void XMLPageExport::collectPageMasterAutoStyle( |
71 | | const Reference < XPropertySet > & rPropSet, |
72 | | XMLPageExportNameEntry & rEntry) |
73 | 0 | { |
74 | 0 | SAL_WARN_IF( !m_xPageMasterPropSetMapper.is(), "xmloff", "page master family/XMLPageMasterPropSetMapper not found" ); |
75 | 0 | if( m_xPageMasterPropSetMapper.is() ) |
76 | 0 | { |
77 | 0 | ::std::vector<XMLPropertyState> aPropStates = m_xPageMasterExportPropMapper->Filter(m_rExport, rPropSet); |
78 | 0 | if( !aPropStates.empty()) |
79 | 0 | { |
80 | 0 | OUString sParent; |
81 | 0 | rEntry.sPageMasterName = m_rExport.GetAutoStylePool()->Find( XmlStyleFamily::PAGE_MASTER, sParent, aPropStates ); |
82 | 0 | if (rEntry.sPageMasterName.isEmpty()) |
83 | 0 | { |
84 | 0 | rEntry.sPageMasterName = m_rExport.GetAutoStylePool()->Add(XmlStyleFamily::PAGE_MASTER, sParent, std::move(aPropStates)); |
85 | 0 | } |
86 | 0 | } |
87 | 0 | } |
88 | 0 | assert(m_xPageMasterDrawingPageExportPropMapper.is()); |
89 | 0 | ::std::vector<XMLPropertyState> aPropStates( |
90 | 0 | m_xPageMasterDrawingPageExportPropMapper->Filter(m_rExport, rPropSet)); |
91 | 0 | if (!aPropStates.empty()) |
92 | 0 | { |
93 | 0 | OUString sParent; |
94 | 0 | rEntry.sDrawingPageStyleName = m_rExport.GetAutoStylePool()->Find(XmlStyleFamily::SD_DRAWINGPAGE_ID, sParent, aPropStates); |
95 | 0 | if (rEntry.sDrawingPageStyleName.isEmpty()) |
96 | 0 | { |
97 | 0 | rEntry.sDrawingPageStyleName = m_rExport.GetAutoStylePool()->Add(XmlStyleFamily::SD_DRAWINGPAGE_ID, sParent, std::move(aPropStates)); |
98 | 0 | } |
99 | 0 | } |
100 | 0 | } |
101 | | |
102 | | void XMLPageExport::exportMasterPageContent( |
103 | | const Reference < XPropertySet > &, |
104 | | bool /*bAutoStyles*/ ) |
105 | 0 | { |
106 | |
|
107 | 0 | } |
108 | | |
109 | | bool XMLPageExport::exportStyle( |
110 | | const Reference< XStyle >& rStyle, |
111 | | bool bAutoStyles ) |
112 | 0 | { |
113 | 0 | Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY ); |
114 | 0 | Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); |
115 | | |
116 | | // Don't export styles that aren't existing really. This may be the |
117 | | // case for StarOffice Writer's pool styles. |
118 | 0 | if( xPropSetInfo->hasPropertyByName( gsIsPhysical ) ) |
119 | 0 | { |
120 | 0 | Any aAny = xPropSet->getPropertyValue( gsIsPhysical ); |
121 | 0 | if( !*o3tl::doAccess<bool>(aAny) ) |
122 | 0 | return false; |
123 | 0 | } |
124 | | |
125 | 0 | if( bAutoStyles ) |
126 | 0 | { |
127 | 0 | XMLPageExportNameEntry aEntry; |
128 | 0 | collectPageMasterAutoStyle(xPropSet, aEntry); |
129 | 0 | aEntry.sStyleName = rStyle->getName(); |
130 | 0 | m_aNameVector.push_back( aEntry ); |
131 | |
|
132 | 0 | exportMasterPageContent( xPropSet, true ); |
133 | 0 | } |
134 | 0 | else |
135 | 0 | { |
136 | 0 | OUString sName( rStyle->getName() ); |
137 | 0 | bool bEncoded = false; |
138 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, |
139 | 0 | GetExport().EncodeStyleName( sName, &bEncoded ) ); |
140 | |
|
141 | 0 | if ( xPropSetInfo->hasPropertyByName( u"Hidden"_ustr ) ) |
142 | 0 | { |
143 | 0 | uno::Any aValue = xPropSet->getPropertyValue( u"Hidden"_ustr ); |
144 | 0 | bool bHidden = false; |
145 | 0 | if ((aValue >>= bHidden) && bHidden |
146 | 0 | && GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) |
147 | 0 | { |
148 | 0 | GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_HIDDEN, u"true"_ustr); |
149 | 0 | GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_HIDDEN, u"true"_ustr); // FIXME for compatibility |
150 | 0 | } |
151 | 0 | } |
152 | |
|
153 | 0 | if( bEncoded ) |
154 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME, |
155 | 0 | sName); |
156 | |
|
157 | 0 | XMLPageExportNameEntry entry; |
158 | 0 | if (findPageMasterNameEntry(m_aNameVector, sName, entry)) |
159 | 0 | { |
160 | 0 | GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, GetExport().EncodeStyleName(entry.sPageMasterName)); |
161 | 0 | if (!entry.sDrawingPageStyleName.isEmpty()) |
162 | 0 | { |
163 | 0 | GetExport().AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, GetExport().EncodeStyleName(entry.sDrawingPageStyleName)); |
164 | 0 | } |
165 | 0 | } |
166 | |
|
167 | 0 | Reference<XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo(); |
168 | 0 | if ( xInfo.is() && xInfo->hasPropertyByName(gsFollowStyle) ) |
169 | 0 | { |
170 | 0 | OUString sNextName; |
171 | 0 | xPropSet->getPropertyValue( gsFollowStyle ) >>= sNextName; |
172 | |
|
173 | 0 | if( sName != sNextName && !sNextName.isEmpty() ) |
174 | 0 | { |
175 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NEXT_STYLE_NAME, |
176 | 0 | GetExport().EncodeStyleName( sNextName ) ); |
177 | 0 | } |
178 | 0 | } |
179 | | |
180 | | //attributes to define shared/hidden headers/footers in Writer |
181 | 0 | if( xPropSetInfo->hasPropertyByName(gsHeaderNoFirst) ) |
182 | 0 | { |
183 | 0 | Any aAny; |
184 | | //same flag footer/header |
185 | 0 | bool bFirstShared = false; |
186 | 0 | aAny = xPropSet->getPropertyValue( gsFirstShareContent ); |
187 | 0 | aAny >>= bFirstShared; |
188 | |
|
189 | 0 | bool bWithoutFirstHeader = false; |
190 | 0 | aAny = xPropSet->getPropertyValue( gsHeaderNoFirst ); |
191 | 0 | aAny >>= bWithoutFirstHeader; |
192 | | //TODO: version and odf extension ticket id |
193 | 0 | if( GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) |
194 | 0 | GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_IS_FIRST_PAGE_HEADER_ENABLED, |
195 | 0 | !bFirstShared && bWithoutFirstHeader ? XML_FALSE |
196 | 0 | : XML_TRUE); |
197 | |
|
198 | 0 | bool bWithoutFirstFooter = false; |
199 | 0 | aAny = xPropSet->getPropertyValue( gsFooterNoFirst ); |
200 | 0 | aAny >>= bWithoutFirstFooter; |
201 | | //TODO: version and odf extension ticket id |
202 | 0 | if( GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) |
203 | 0 | GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_IS_FIRST_PAGE_FOOTER_ENABLED, |
204 | 0 | !bFirstShared && bWithoutFirstFooter ? XML_FALSE |
205 | 0 | : XML_TRUE); |
206 | 0 | } |
207 | |
|
208 | 0 | SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, |
209 | 0 | XML_MASTER_PAGE, true, true ); |
210 | |
|
211 | 0 | exportMasterPageContent( xPropSet, false ); |
212 | 0 | } |
213 | |
|
214 | 0 | return true; |
215 | 0 | } |
216 | | |
217 | | XMLPageExport::XMLPageExport(SvXMLExport & rExp) |
218 | 0 | : m_rExport(rExp) |
219 | 0 | , m_xPageMasterPropHdlFactory(new XMLPageMasterPropHdlFactory) |
220 | 0 | , m_xPageMasterPropSetMapper(new XMLPageMasterPropSetMapper( |
221 | 0 | aXMLPageMasterStyleMap, |
222 | 0 | m_xPageMasterPropHdlFactory)) |
223 | 0 | , m_xPageMasterExportPropMapper(new XMLPageMasterExportPropMapper( |
224 | 0 | m_xPageMasterPropSetMapper, rExp)) |
225 | 0 | , m_xPageMasterDrawingPagePropSetMapper(new XMLPageMasterPropSetMapper( |
226 | 0 | g_XMLPageMasterDrawingPageStyleMap, |
227 | 0 | m_xPageMasterPropHdlFactory)) |
228 | | // use same class but with different map, need its ContextFilter() |
229 | 0 | , m_xPageMasterDrawingPageExportPropMapper(new XMLPageMasterExportPropMapper( |
230 | 0 | m_xPageMasterDrawingPagePropSetMapper, rExp)) |
231 | 0 | { |
232 | 0 | m_rExport.GetAutoStylePool()->AddFamily( XmlStyleFamily::PAGE_MASTER, XML_STYLE_FAMILY_PAGE_MASTER_NAME, |
233 | 0 | m_xPageMasterExportPropMapper, XML_STYLE_FAMILY_PAGE_MASTER_PREFIX, false ); |
234 | 0 | m_rExport.GetAutoStylePool()->AddFamily(XmlStyleFamily::SD_DRAWINGPAGE_ID, XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME, |
235 | 0 | m_xPageMasterDrawingPageExportPropMapper, XML_STYLE_FAMILY_SD_DRAWINGPAGE_PREFIX); |
236 | |
|
237 | 0 | Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(), |
238 | 0 | UNO_QUERY ); |
239 | 0 | SAL_WARN_IF( !xFamiliesSupp.is(), "xmloff", |
240 | 0 | "No XStyleFamiliesSupplier from XModel for export!" ); |
241 | 0 | if( !xFamiliesSupp.is() ) |
242 | 0 | return; |
243 | | |
244 | 0 | Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() ); |
245 | 0 | SAL_WARN_IF( !xFamiliesSupp.is(), "xmloff", |
246 | 0 | "getStyleFamilies() from XModel failed for export!" ); |
247 | 0 | if( xFamilies.is() ) |
248 | 0 | { |
249 | 0 | static constexpr OUString aPageStyleName(u"PageStyles"_ustr); |
250 | |
|
251 | 0 | if( xFamilies->hasByName( aPageStyleName ) ) |
252 | 0 | { |
253 | 0 | m_xPageStyles.set(xFamilies->getByName( aPageStyleName ),uno::UNO_QUERY); |
254 | |
|
255 | 0 | SAL_WARN_IF( !m_xPageStyles.is(), "xmloff", |
256 | 0 | "Page Styles not found for export!" ); |
257 | 0 | } |
258 | 0 | } |
259 | | |
260 | 0 | if (GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITER) |
261 | 0 | return; |
262 | | |
263 | 0 | uno::Reference<lang::XMultiServiceFactory> xFac(GetExport().GetModel(), uno::UNO_QUERY); |
264 | 0 | if (!xFac.is()) |
265 | 0 | return; |
266 | | |
267 | 0 | uno::Reference<beans::XPropertySet> xProps( |
268 | 0 | xFac->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY); |
269 | 0 | if (!xProps.is()) |
270 | 0 | return; |
271 | | |
272 | 0 | bool bGutterAtTop{}; |
273 | 0 | xProps->getPropertyValue(u"GutterAtTop"_ustr) >>= bGutterAtTop; |
274 | 0 | if (bGutterAtTop) |
275 | 0 | { |
276 | 0 | m_xPageMasterExportPropMapper->SetGutterAtTop(true); |
277 | 0 | } |
278 | 0 | } |
279 | | |
280 | | XMLPageExport::~XMLPageExport() |
281 | 0 | { |
282 | 0 | } |
283 | | |
284 | | void XMLPageExport::exportStyles( bool bUsed, bool bAutoStyles ) |
285 | 0 | { |
286 | 0 | if( m_xPageStyles.is() ) |
287 | 0 | { |
288 | 0 | const uno::Sequence< OUString> aSeq = m_xPageStyles->getElementNames(); |
289 | 0 | for(const auto& rName : aSeq) |
290 | 0 | { |
291 | 0 | Reference< XStyle > xStyle(m_xPageStyles->getByName( rName ),uno::UNO_QUERY); |
292 | 0 | if( !bUsed || xStyle->isInUse() ) |
293 | 0 | exportStyle( xStyle, bAutoStyles ); |
294 | 0 | } |
295 | 0 | } |
296 | 0 | } |
297 | | |
298 | | void XMLPageExport::exportAutoStyles() |
299 | 0 | { |
300 | 0 | m_rExport.GetAutoStylePool()->exportXML(XmlStyleFamily::PAGE_MASTER); |
301 | | // tdf#103602 this is called by both Writer and Calc but Calc doesn't |
302 | | // have fill properties yet |
303 | 0 | m_rExport.GetAutoStylePool()->exportXML(XmlStyleFamily::SD_DRAWINGPAGE_ID); |
304 | 0 | } |
305 | | |
306 | | void XMLPageExport::exportDefaultStyle() |
307 | 0 | { |
308 | 0 | Reference < lang::XMultiServiceFactory > xFactory (GetExport().GetModel(), UNO_QUERY); |
309 | 0 | if (!xFactory.is()) |
310 | 0 | return; |
311 | | |
312 | 0 | Reference < XPropertySet > xPropSet (xFactory->createInstance ( u"com.sun.star.text.Defaults"_ustr ), UNO_QUERY); |
313 | 0 | if (!xPropSet.is()) |
314 | 0 | return; |
315 | | |
316 | | // <style:default-style ...> |
317 | 0 | GetExport().CheckAttrList(); |
318 | |
|
319 | 0 | ::std::vector< XMLPropertyState > aPropStates = |
320 | 0 | m_xPageMasterExportPropMapper->FilterDefaults(m_rExport, xPropSet); |
321 | |
|
322 | 0 | bool bExport = false; |
323 | 0 | rtl::Reference < XMLPropertySetMapper > aPropMapper(m_xPageMasterExportPropMapper->getPropertySetMapper()); |
324 | 0 | for( const auto& rProp : aPropStates ) |
325 | 0 | { |
326 | 0 | sal_Int16 nContextId = aPropMapper->GetEntryContextId( rProp.mnIndex ); |
327 | 0 | if( nContextId == CTF_PM_STANDARD_MODE ) |
328 | 0 | { |
329 | 0 | bExport = true; |
330 | 0 | break; |
331 | 0 | } |
332 | 0 | } |
333 | |
|
334 | 0 | if( !bExport ) |
335 | 0 | return; |
336 | | |
337 | 0 | assert(GetExport().getSaneDefaultVersion() |
338 | 0 | >= SvtSaveOptions::ODFSVER_012); |
339 | | |
340 | | //<style:default-page-layout> |
341 | 0 | SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, |
342 | 0 | XML_DEFAULT_PAGE_LAYOUT, |
343 | 0 | true, true ); |
344 | |
|
345 | 0 | m_xPageMasterExportPropMapper->exportXML( GetExport(), aPropStates, |
346 | 0 | SvXmlExportFlags::IGN_WS ); |
347 | 0 | } |
348 | | |
349 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |