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>
21 #include <xmloff/xmlnmspe.hxx>
22 #include <xmloff/attrlist.hxx>
23 #include "xmlexpit.hxx"
24 #include <xmloff/nmspmap.hxx>
25 #include <xmloff/XMLTextListAutoStylePool.hxx>
26 #include <xmloff/XMLTextMasterPageExport.hxx>
27 #include <xmloff/table/XMLTableExport.hxx>
28 
29 #include <xmloff/txtprmap.hxx>
30 #include <xmloff/xmlaustp.hxx>
31 #include <xmloff/families.hxx>
32 #include <xmloff/maptype.hxx>
33 #include <format.hxx>
34 #include <fmtpdsc.hxx>
35 #include <pagedesc.hxx>
36 #include <cellatr.hxx>
37 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
38 #include "xmlexp.hxx"
39 #include <SwStyleNameMapper.hxx>
40 #include <osl/diagnose.h>
41 
42 using namespace ::com::sun::star::beans;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::text;
45 using namespace ::com::sun::star::drawing;
46 using namespace ::com::sun::star::lang;
47 using namespace ::xmloff::token;
48 
ExportFormat(const SwFormat & rFormat,enum XMLTokenEnum eFamily)49 void SwXMLExport::ExportFormat( const SwFormat& rFormat, enum XMLTokenEnum eFamily )
50 {
51     // <style:style ...>
52     CheckAttrList();
53 
54     // style:family="..."
55     OSL_ENSURE( RES_FRMFMT==rFormat.Which(), "frame format expected" );
56     if( RES_FRMFMT != rFormat.Which() )
57         return;
58     OSL_ENSURE( eFamily != XML_TOKEN_INVALID, "family must be specified" );
59     // style:name="..."
60     bool bEncoded = false;
61     AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, EncodeStyleName(
62                     rFormat.GetName(), &bEncoded ) );
63     if( bEncoded )
64         AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME, rFormat.GetName() );
65 
66     if( eFamily != XML_TOKEN_INVALID )
67         AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY, eFamily );
68 
69 #if OSL_DEBUG_LEVEL > 0
70     // style:parent-style-name="..." (if it's not the default only)
71     const SwFormat* pParent = rFormat.DerivedFrom();
72     // Only adopt parent name, if it's not the default
73     OSL_ENSURE( !pParent || pParent->IsDefault(), "unexpected parent" );
74 
75     OSL_ENSURE( USHRT_MAX == rFormat.GetPoolFormatId(), "pool ids aren't supported" );
76     OSL_ENSURE( USHRT_MAX == rFormat.GetPoolHelpId(), "help ids aren't supported" );
77     OSL_ENSURE( USHRT_MAX == rFormat.GetPoolHelpId() ||
78             UCHAR_MAX == rFormat.GetPoolHlpFileId(), "help file ids aren't supported" );
79 #endif
80 
81     // style:master-page-name
82     if( RES_FRMFMT == rFormat.Which() && XML_TABLE == eFamily )
83     {
84         const SfxPoolItem *pItem;
85         if( SfxItemState::SET == rFormat.GetAttrSet().GetItemState( RES_PAGEDESC,
86                                                             false, &pItem ) )
87         {
88             OUString sName;
89             const SwPageDesc *pPageDesc =
90                 static_cast<const SwFormatPageDesc *>(pItem)->GetPageDesc();
91             if( pPageDesc )
92                 SwStyleNameMapper::FillProgName(
93                                     pPageDesc->GetName(),
94                                     sName,
95                                     SwGetPoolIdFromName::PageDesc);
96             AddAttribute( XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME,
97                           EncodeStyleName( sName ) );
98         }
99     }
100 
101     if( XML_TABLE_CELL == eFamily )
102     {
103         OSL_ENSURE(RES_FRMFMT == rFormat.Which(), "only frame format");
104 
105         const SfxPoolItem *pItem;
106         if( SfxItemState::SET ==
107             rFormat.GetAttrSet().GetItemState( RES_BOXATR_FORMAT,
108                                             false, &pItem ) )
109         {
110             sal_Int32 nFormat = static_cast<sal_Int32>(static_cast<const SwTableBoxNumFormat *>(pItem)->GetValue());
111 
112             if ( (nFormat != -1) && (nFormat != static_cast<sal_Int32>(getSwDefaultTextFormat())) )
113             {
114                 // if we have a format, register and then export
115                 // (Careful: here we assume that data styles will be
116                 // written after cell styles)
117                 addDataStyle(nFormat);
118                 OUString sDataStyleName = getDataStyleName(nFormat);
119                 if( !sDataStyleName.isEmpty() )
120                     AddAttribute( XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME,
121                                   sDataStyleName );
122             }
123         }
124     }
125 
126     {
127         SvXMLElementExport aElem( *this, XML_NAMESPACE_STYLE, XML_STYLE,
128                                   true, true );
129 
130         SvXMLItemMapEntriesRef xItemMap;
131         XMLTokenEnum ePropToken = XML_TABLE_PROPERTIES;
132         if( XML_TABLE == eFamily )
133         {
134             xItemMap = m_xTableItemMap;
135         }
136         else if( XML_TABLE_ROW == eFamily )
137         {
138             xItemMap = m_xTableRowItemMap;
139             ePropToken = XML_TABLE_ROW_PROPERTIES;
140         }
141         else if( XML_TABLE_CELL == eFamily )
142         {
143             xItemMap = m_xTableCellItemMap;
144             ePropToken = XML_TABLE_CELL_PROPERTIES;
145         }
146 
147         if( xItemMap.is() )
148         {
149             m_pTableItemMapper->setMapEntries( xItemMap );
150             m_pTableItemMapper->exportXML( *this,
151                                            rFormat.GetAttrSet(),
152                                            GetTwipUnitConverter(),
153                                            ePropToken );
154         }
155     }
156 }
157 
ExportStyles_(bool bUsed)158 void SwXMLExport::ExportStyles_( bool bUsed )
159 {
160     SvXMLExport::ExportStyles_( bUsed );
161 
162     // drawing defaults
163     GetShapeExport()->ExportGraphicDefaults();
164 
165     GetTextParagraphExport()->exportTextStyles( bUsed
166                                              ,IsShowProgress()
167                                               );
168     collectDataStyles(true);
169     exportDataStyles();
170     GetShapeExport()->GetShapeTableExport()->exportTableStyles();
171     //page defaults
172     GetPageExport()->exportDefaultStyle();
173 }
174 
collectAutoStyles()175 void SwXMLExport::collectAutoStyles()
176 {
177     SvXMLExport::collectAutoStyles();
178 
179     if (mbAutoStylesCollected)
180         return;
181 
182     // The order in which styles are collected *MUST* be the same as
183     // the order in which they are exported. Otherwise, caching will
184     // fail.
185     if( getExportFlags() & (SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
186     {
187         if( !(getExportFlags() & SvXMLExportFlags::CONTENT) )
188         {
189             // only master pages are exported => styles for frames bound
190             // to frames (but none for frames bound to pages) need to be
191             // collected.
192             // TODO: exclude PageBoundFrames on export
193         }
194     }
195 
196     // exported in _ExportMasterStyles
197     if( getExportFlags() & SvXMLExportFlags::MASTERSTYLES )
198         GetPageExport()->collectAutoStyles( false );
199 
200 
201     // exported in ExportContent_
202     if( getExportFlags() & SvXMLExportFlags::CONTENT )
203     {
204         // collect form autostyle
205         // (do this before collectTextAutoStyles, 'cause the shapes need the results of the work
206         // done by examineForms)
207         Reference<XDrawPageSupplier> xDrawPageSupplier( GetModel(), UNO_QUERY );
208         if (xDrawPageSupplier.is() && GetFormExport().is())
209         {
210             Reference<XDrawPage> xPage = xDrawPageSupplier->getDrawPage();
211             if (xPage.is())
212                 GetFormExport()->examineForms(xPage);
213         }
214 
215         GetTextParagraphExport()->collectTextAutoStylesOptimized( m_bShowProgress );
216     }
217 
218     mbAutoStylesCollected = true;
219 }
220 
ExportAutoStyles_()221 void SwXMLExport::ExportAutoStyles_()
222 {
223     collectAutoStyles();
224 
225     // if we don't export styles (i.e. in content stream only, but not
226     // in single-stream case), then we can save ourselves a bit of
227     // work and memory by not collecting field masters
228     if( !(getExportFlags() & SvXMLExportFlags::STYLES) )
229         GetTextParagraphExport()->exportUsedDeclarations();
230 
231     // exported in ExportContent_
232     if( getExportFlags() & SvXMLExportFlags::CONTENT )
233     {
234         GetTextParagraphExport()->exportTrackedChanges( true );
235     }
236 
237     GetTextParagraphExport()->exportTextAutoStyles();
238     GetShapeExport()->exportAutoStyles();
239     if( getExportFlags() & SvXMLExportFlags::MASTERSTYLES )
240         GetPageExport()->exportAutoStyles();
241 
242     // we rely on data styles being written after cell styles in the
243     // ExportFormat() method; so be careful when changing order.
244     exportAutoDataStyles();
245 
246     SvXMLExportFlags nContentAutostyles = SvXMLExportFlags::CONTENT | SvXMLExportFlags::AUTOSTYLES;
247     if ( ( getExportFlags() & nContentAutostyles ) == nContentAutostyles )
248         GetFormExport()->exportAutoStyles();
249 }
250 
CreatePageExport()251 XMLPageExport* SwXMLExport::CreatePageExport()
252 {
253     return new XMLTextMasterPageExport( *this );
254 }
255 
ExportMasterStyles_()256 void SwXMLExport::ExportMasterStyles_()
257 {
258     // export master styles
259     GetPageExport()->exportMasterStyles( false );
260 }
261 
262 class SwXMLAutoStylePoolP : public SvXMLAutoStylePoolP
263 {
264     SvXMLExport& rExport;
265     const OUString sListStyleName;
266     const OUString sMasterPageName;
267 
268 protected:
269 
270     virtual void exportStyleAttributes(
271             SvXMLAttributeList& rAttrList,
272             sal_Int32 nFamily,
273             const std::vector< XMLPropertyState >& rProperties,
274             const SvXMLExportPropertyMapper& rPropExp
275             , const SvXMLUnitConverter& rUnitConverter,
276             const SvXMLNamespaceMap& rNamespaceMap
277             ) const override;
278 public:
279 
280     explicit SwXMLAutoStylePoolP( SvXMLExport& rExport );
281 };
282 
exportStyleAttributes(SvXMLAttributeList & rAttrList,sal_Int32 nFamily,const std::vector<XMLPropertyState> & rProperties,const SvXMLExportPropertyMapper & rPropExp,const SvXMLUnitConverter & rUnitConverter,const SvXMLNamespaceMap & rNamespaceMap) const283 void SwXMLAutoStylePoolP::exportStyleAttributes(
284             SvXMLAttributeList& rAttrList,
285             sal_Int32 nFamily,
286             const std::vector< XMLPropertyState >& rProperties,
287             const SvXMLExportPropertyMapper& rPropExp
288             , const SvXMLUnitConverter& rUnitConverter,
289             const SvXMLNamespaceMap& rNamespaceMap
290             ) const
291 {
292     SvXMLAutoStylePoolP::exportStyleAttributes( rAttrList, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap);
293 
294     if( XML_STYLE_FAMILY_TEXT_PARAGRAPH == nFamily )
295     {
296         for( const auto& rProperty : rProperties )
297         {
298             if (rProperty.mnIndex != -1) // #i26762#
299             {
300                 switch( rPropExp.getPropertySetMapper()->
301                         GetEntryContextId( rProperty.mnIndex ) )
302                 {
303                 case CTF_NUMBERINGSTYLENAME:
304                     {
305                         OUString sStyleName;
306                         rProperty.maValue >>= sStyleName;
307                         // #i70748# - export also empty list styles
308                         if( !sStyleName.isEmpty() )
309                         {
310                             OUString sTmp = rExport.GetTextParagraphExport()->GetListAutoStylePool().Find( sStyleName );
311                             if( !sTmp.isEmpty() )
312                                 sStyleName = sTmp;
313                         }
314                         GetExport().AddAttribute( XML_NAMESPACE_STYLE,
315                               sListStyleName,
316                               GetExport().EncodeStyleName( sStyleName ) );
317                     }
318                     break;
319                 case CTF_PAGEDESCNAME:
320                     {
321                         OUString sStyleName;
322                         rProperty.maValue >>= sStyleName;
323                         GetExport().AddAttribute( XML_NAMESPACE_STYLE,
324                                       sMasterPageName,
325                                       GetExport().EncodeStyleName( sStyleName ) );
326                     }
327                     break;
328                 }
329             }
330         }
331     }
332 }
333 
SwXMLAutoStylePoolP(SvXMLExport & rExp)334 SwXMLAutoStylePoolP::SwXMLAutoStylePoolP(SvXMLExport& rExp ) :
335     SvXMLAutoStylePoolP( rExp ),
336     rExport( rExp ),
337     sListStyleName( GetXMLToken( XML_LIST_STYLE_NAME ) ),
338     sMasterPageName( GetXMLToken( XML_MASTER_PAGE_NAME ) )
339 {
340 }
341 
CreateAutoStylePool()342 SvXMLAutoStylePoolP* SwXMLExport::CreateAutoStylePool()
343 {
344     return new SwXMLAutoStylePoolP( *this );
345 }
346 
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
348