File: | home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx |
Warning: | line 886, column 37 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <sal/config.h> | |||
21 | #include <sal/log.hxx> | |||
22 | ||||
23 | #include "xmlexprt.hxx" | |||
24 | #include "XMLConverter.hxx" | |||
25 | #include "xmlstyle.hxx" | |||
26 | #include <unonames.hxx> | |||
27 | #include <document.hxx> | |||
28 | #include <olinetab.hxx> | |||
29 | #include <formulacell.hxx> | |||
30 | #include <rangenam.hxx> | |||
31 | #include "XMLTableMasterPageExport.hxx" | |||
32 | #include <drwlayer.hxx> | |||
33 | #include "XMLExportDataPilot.hxx" | |||
34 | #include "XMLExportDatabaseRanges.hxx" | |||
35 | #include "XMLExportDDELinks.hxx" | |||
36 | #include "XMLExportIterator.hxx" | |||
37 | #include "XMLColumnRowGroupExport.hxx" | |||
38 | #include "XMLStylesExportHelper.hxx" | |||
39 | #include "XMLChangeTrackingExportHelper.hxx" | |||
40 | #include <sheetdata.hxx> | |||
41 | #include <docoptio.hxx> | |||
42 | #include "XMLExportSharedData.hxx" | |||
43 | #include <chgviset.hxx> | |||
44 | #include <docuno.hxx> | |||
45 | #include <textuno.hxx> | |||
46 | #include <chartlis.hxx> | |||
47 | #include <scitems.hxx> | |||
48 | #include <docpool.hxx> | |||
49 | #include <userdat.hxx> | |||
50 | #include <chgtrack.hxx> | |||
51 | #include <rangeutl.hxx> | |||
52 | #include <postit.hxx> | |||
53 | #include <externalrefmgr.hxx> | |||
54 | #include <editutil.hxx> | |||
55 | #include <tabprotection.hxx> | |||
56 | #include "cachedattraccess.hxx" | |||
57 | #include <colorscale.hxx> | |||
58 | #include <conditio.hxx> | |||
59 | #include <cellvalue.hxx> | |||
60 | #include <stylehelper.hxx> | |||
61 | #include <edittextiterator.hxx> | |||
62 | #include "editattributemap.hxx" | |||
63 | #include <arealink.hxx> | |||
64 | #include <datastream.hxx> | |||
65 | #include <documentlinkmgr.hxx> | |||
66 | #include <tokenstringcontext.hxx> | |||
67 | #include <cellform.hxx> | |||
68 | #include <datamapper.hxx> | |||
69 | #include <datatransformation.hxx> | |||
70 | ||||
71 | #include <xmloff/xmltoken.hxx> | |||
72 | #include <xmloff/xmlnamespace.hxx> | |||
73 | #include <xmloff/xmluconv.hxx> | |||
74 | #include <xmloff/namespacemap.hxx> | |||
75 | #include <xmloff/families.hxx> | |||
76 | #include <xmloff/numehelp.hxx> | |||
77 | #include <xmloff/txtparae.hxx> | |||
78 | #include <editeng/autokernitem.hxx> | |||
79 | #include <editeng/charreliefitem.hxx> | |||
80 | #include <editeng/charscaleitem.hxx> | |||
81 | #include <editeng/colritem.hxx> | |||
82 | #include <editeng/contouritem.hxx> | |||
83 | #include <editeng/crossedoutitem.hxx> | |||
84 | #include <editeng/emphasismarkitem.hxx> | |||
85 | #include <editeng/escapementitem.hxx> | |||
86 | #include <editeng/fhgtitem.hxx> | |||
87 | #include <editeng/fontitem.hxx> | |||
88 | #include <editeng/kernitem.hxx> | |||
89 | #include <editeng/langitem.hxx> | |||
90 | #include <editeng/postitem.hxx> | |||
91 | #include <editeng/section.hxx> | |||
92 | #include <editeng/shdditem.hxx> | |||
93 | #include <editeng/udlnitem.hxx> | |||
94 | #include <editeng/wghtitem.hxx> | |||
95 | #include <editeng/wrlmitem.hxx> | |||
96 | #include <editeng/xmlcnitm.hxx> | |||
97 | #include <editeng/flditem.hxx> | |||
98 | #include <editeng/eeitem.hxx> | |||
99 | #include <formula/errorcodes.hxx> | |||
100 | #include <xmloff/xmlerror.hxx> | |||
101 | #include <xmloff/XMLEventExport.hxx> | |||
102 | #include <xmloff/xmlprmap.hxx> | |||
103 | #include <xmloff/ProgressBarHelper.hxx> | |||
104 | #include <xmloff/table/XMLTableExport.hxx> | |||
105 | ||||
106 | #include <sax/tools/converter.hxx> | |||
107 | #include <tools/fldunit.hxx> | |||
108 | ||||
109 | #include <rtl/ustring.hxx> | |||
110 | ||||
111 | #include <tools/color.hxx> | |||
112 | #include <rtl/math.hxx> | |||
113 | #include <svl/zforlist.hxx> | |||
114 | #include <svx/unoshape.hxx> | |||
115 | #include <comphelper/base64.hxx> | |||
116 | #include <comphelper/extract.hxx> | |||
117 | #include <svx/svdobj.hxx> | |||
118 | #include <svx/svdocapt.hxx> | |||
119 | #include <svtools/miscopt.hxx> | |||
120 | #include <vcl/svapp.hxx> | |||
121 | ||||
122 | #include <comphelper/processfactory.hxx> | |||
123 | #include <com/sun/star/beans/XPropertySet.hpp> | |||
124 | #include <com/sun/star/container/XNamed.hpp> | |||
125 | #include <com/sun/star/drawing/XDrawPageSupplier.hpp> | |||
126 | #include <com/sun/star/form/XFormsSupplier2.hpp> | |||
127 | #include <com/sun/star/io/XActiveDataSource.hpp> | |||
128 | #include <com/sun/star/io/XSeekable.hpp> | |||
129 | #include <com/sun/star/sheet/XUsedAreaCursor.hpp> | |||
130 | #include <com/sun/star/sheet/XCellRangeAddressable.hpp> | |||
131 | #include <com/sun/star/sheet/XPrintAreas.hpp> | |||
132 | #include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp> | |||
133 | #include <com/sun/star/sheet/XLabelRange.hpp> | |||
134 | #include <com/sun/star/sheet/NamedRangeFlag.hpp> | |||
135 | #include <com/sun/star/sheet/XSheetCellCursor.hpp> | |||
136 | #include <com/sun/star/sheet/XSheetCellRanges.hpp> | |||
137 | #include <com/sun/star/sheet/XSheetLinkable.hpp> | |||
138 | #include <com/sun/star/sheet/GlobalSheetSettings.hpp> | |||
139 | #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> | |||
140 | #include <com/sun/star/table/XColumnRowRange.hpp> | |||
141 | #include <com/sun/star/util/XProtectable.hpp> | |||
142 | #include <com/sun/star/xml/sax/XDocumentHandler.hpp> | |||
143 | #include <com/sun/star/chart2/XChartDocument.hpp> | |||
144 | #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp> | |||
145 | #include <com/sun/star/chart2/data/XDataReceiver.hpp> | |||
146 | ||||
147 | #include <com/sun/star/document/XDocumentProperties.hpp> | |||
148 | #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> | |||
149 | ||||
150 | #include "XMLCodeNameProvider.hxx" | |||
151 | ||||
152 | #include <sfx2/linkmgr.hxx> | |||
153 | #include <sfx2/objsh.hxx> | |||
154 | ||||
155 | #include <memory> | |||
156 | #include <vector> | |||
157 | #include <vbahelper/vbaaccesshelper.hxx> | |||
158 | ||||
159 | namespace com::sun::star::uno { class XComponentContext; } | |||
160 | ||||
161 | ||||
162 | ||||
163 | //! not found in unonames.hxx | |||
164 | #define SC_LAYERID"LayerID" "LayerID" | |||
165 | ||||
166 | #define SC_VIEWCHANGES_COUNT13 13 | |||
167 | #define SC_SHOW_CHANGES0 0 | |||
168 | #define SC_SHOW_ACCEPTED_CHANGES1 1 | |||
169 | #define SC_SHOW_REJECTED_CHANGES2 2 | |||
170 | #define SC_SHOW_CHANGES_BY_DATETIME3 3 | |||
171 | #define SC_SHOW_CHANGES_BY_DATETIME_MODE4 4 | |||
172 | #define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME5 5 | |||
173 | #define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME6 6 | |||
174 | #define SC_SHOW_CHANGES_BY_AUTHOR7 7 | |||
175 | #define SC_SHOW_CHANGES_BY_AUTHOR_NAME8 8 | |||
176 | #define SC_SHOW_CHANGES_BY_COMMENT9 9 | |||
177 | #define SC_SHOW_CHANGES_BY_COMMENT_TEXT10 10 | |||
178 | #define SC_SHOW_CHANGES_BY_RANGES11 11 | |||
179 | #define SC_SHOW_CHANGES_BY_RANGES_LIST12 12 | |||
180 | ||||
181 | using namespace formula; | |||
182 | using namespace com::sun::star; | |||
183 | using namespace xmloff::token; | |||
184 | using ::std::vector; | |||
185 | using ::com::sun::star::uno::UNO_QUERY; | |||
186 | ||||
187 | namespace | |||
188 | { | |||
189 | OUString lcl_RangeSequenceToString( | |||
190 | const uno::Sequence< OUString > & rRanges, | |||
191 | const uno::Reference< chart2::data::XRangeXMLConversion > & xFormatConverter ) | |||
192 | { | |||
193 | OUStringBuffer aResult; | |||
194 | const sal_Int32 nMaxIndex( rRanges.getLength() - 1 ); | |||
195 | const sal_Unicode cSep(' '); | |||
196 | for( sal_Int32 i=0; i<=nMaxIndex; ++i ) | |||
197 | { | |||
198 | OUString aRange( rRanges[i] ); | |||
199 | if( xFormatConverter.is()) | |||
200 | aRange = xFormatConverter->convertRangeToXML( aRange ); | |||
201 | aResult.append( aRange ); | |||
202 | if( i < nMaxIndex ) | |||
203 | aResult.append( cSep ); | |||
204 | } | |||
205 | return aResult.makeStringAndClear(); | |||
206 | } | |||
207 | ||||
208 | OUString lcl_GetFormattedString(ScDocument* pDoc, const ScRefCellValue& rCell, const ScAddress& rAddr) | |||
209 | { | |||
210 | // return text/edit cell string content, with line feeds in edit cells | |||
211 | ||||
212 | if (!pDoc) | |||
213 | return EMPTY_OUSTRINGScGlobal::GetEmptyOUString(); | |||
214 | ||||
215 | switch (rCell.meType) | |||
216 | { | |||
217 | case CELLTYPE_STRING: | |||
218 | { | |||
219 | OUString aStr; | |||
220 | const Color* pColor; | |||
221 | SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); | |||
222 | ||||
223 | sal_uInt32 nFormat = pDoc->GetNumberFormat(rAddr); | |||
224 | ScCellFormat::GetString(rCell, nFormat, aStr, &pColor, *pFormatter, *pDoc); | |||
225 | return aStr; | |||
226 | } | |||
227 | case CELLTYPE_EDIT: | |||
228 | { | |||
229 | const EditTextObject* pData = rCell.mpEditText; | |||
230 | if (!pData) | |||
231 | return EMPTY_OUSTRINGScGlobal::GetEmptyOUString(); | |||
232 | ||||
233 | EditEngine& rEngine = pDoc->GetEditEngine(); | |||
234 | rEngine.SetText(*pData); | |||
235 | return rEngine.GetText(); | |||
236 | } | |||
237 | break; | |||
238 | default: | |||
239 | ; | |||
240 | } | |||
241 | ||||
242 | return EMPTY_OUSTRINGScGlobal::GetEmptyOUString(); | |||
243 | } | |||
244 | ||||
245 | } // anonymous namespace | |||
246 | ||||
247 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
248 | Calc_XMLExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
249 | { | |||
250 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLExporter", SvXMLExportFlags::ALL)); | |||
251 | } | |||
252 | ||||
253 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
254 | Calc_XMLMetaExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
255 | { | |||
256 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLMetaExporter", SvXMLExportFlags::META)); | |||
257 | } | |||
258 | ||||
259 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
260 | Calc_XMLStylesExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
261 | { | |||
262 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLStylesExporter", SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS)); | |||
263 | } | |||
264 | ||||
265 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
266 | Calc_XMLContentExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
267 | { | |||
268 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLContentExporter", SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::FONTDECLS)); | |||
269 | } | |||
270 | ||||
271 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
272 | Calc_XMLSettingsExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
273 | { | |||
274 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLSettingsExporter", SvXMLExportFlags::SETTINGS)); | |||
275 | } | |||
276 | ||||
277 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
278 | Calc_XMLOasisExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
279 | { | |||
280 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisExporter", SvXMLExportFlags::ALL|SvXMLExportFlags::OASIS)); | |||
281 | } | |||
282 | ||||
283 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
284 | Calc_XMLOasisMetaExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
285 | { | |||
286 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisMetaExporter", SvXMLExportFlags::META|SvXMLExportFlags::OASIS)); | |||
287 | } | |||
288 | ||||
289 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
290 | Calc_XMLOasisStylesExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
291 | { | |||
292 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisStylesExporter", SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::OASIS)); | |||
293 | } | |||
294 | ||||
295 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
296 | Calc_XMLOasisContentExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
297 | { | |||
298 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisContentExporter", SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::OASIS)); | |||
299 | } | |||
300 | ||||
301 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
302 | Calc_XMLOasisSettingsExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) | |||
303 | { | |||
304 | return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisSettingsExporter", SvXMLExportFlags::SETTINGS|SvXMLExportFlags::OASIS)); | |||
305 | } | |||
306 | ||||
307 | namespace { | |||
308 | ||||
309 | class ScXMLShapeExport : public XMLShapeExport | |||
310 | { | |||
311 | public: | |||
312 | explicit ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {} | |||
313 | ||||
314 | /** is called before a shape element for the given XShape is exported */ | |||
315 | virtual void onExport( const uno::Reference < drawing::XShape >& xShape ) override; | |||
316 | }; | |||
317 | ||||
318 | } | |||
319 | ||||
320 | void ScXMLShapeExport::onExport( const uno::Reference < drawing::XShape >& xShape ) | |||
321 | { | |||
322 | uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY ); | |||
323 | if( xShapeProp.is() ) | |||
324 | { | |||
325 | sal_Int16 nLayerID = 0; | |||
326 | if( (xShapeProp->getPropertyValue( SC_LAYERID"LayerID" ) >>= nLayerID) && (SdrLayerID(nLayerID) == SC_LAYER_BACK) ) | |||
327 | GetExport().AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_BACKGROUND, XML_TRUE); | |||
328 | } | |||
329 | } | |||
330 | ||||
331 | sal_Int16 ScXMLExport::GetMeasureUnit() | |||
332 | { | |||
333 | css::uno::Reference<css::sheet::XGlobalSheetSettings> xProperties = | |||
334 | css::sheet::GlobalSheetSettings::create( comphelper::getProcessComponentContext() ); | |||
335 | const FieldUnit eFieldUnit = static_cast<FieldUnit>(xProperties->getMetric()); | |||
336 | return SvXMLUnitConverter::GetMeasureUnit(eFieldUnit); | |||
337 | } | |||
338 | ||||
339 | constexpr OUStringLiteral gsLayerID( u"" SC_LAYERID"LayerID" ); | |||
340 | ||||
341 | ScXMLExport::ScXMLExport( | |||
342 | const css::uno::Reference< css::uno::XComponentContext >& rContext, | |||
343 | OUString const & implementationName, SvXMLExportFlags nExportFlag) | |||
344 | : SvXMLExport( | |||
345 | rContext, implementationName, GetMeasureUnit(), XML_SPREADSHEET, nExportFlag ), | |||
346 | pDoc(nullptr), | |||
347 | nSourceStreamPos(0), | |||
348 | aTableStyles(), | |||
349 | pCurrentCell(nullptr), | |||
350 | nOpenRow(-1), | |||
351 | nProgressCount(0), | |||
352 | nCurrentTable(0), | |||
353 | bHasRowHeader(false), | |||
354 | bRowHeaderOpen(false) | |||
355 | { | |||
356 | if (getExportFlags() & SvXMLExportFlags::CONTENT) | |||
357 | { | |||
358 | pGroupColumns.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP) ); | |||
359 | pGroupRows.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP) ); | |||
360 | pColumnStyles.reset( new ScColumnStyles() ); | |||
361 | pRowStyles.reset( new ScRowStyles() ); | |||
362 | pRowFormatRanges.reset( new ScRowFormatRanges() ); | |||
363 | pMergedRangesContainer.reset( new ScMyMergedRangesContainer() ); | |||
364 | pValidationsContainer.reset( new ScMyValidationsContainer() ); | |||
365 | mpCellsItr.reset(new ScMyNotEmptyCellsIterator(*this)); | |||
366 | pDefaults.reset( new ScMyDefaultStyles ); | |||
367 | } | |||
368 | pCellStyles.reset( new ScFormatRangeStyles() ); | |||
369 | ||||
370 | // document is not set here - create ScChangeTrackingExportHelper later | |||
371 | ||||
372 | xScPropHdlFactory = new XMLScPropHdlFactory; | |||
373 | xCellStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScCellStylesProperties, xScPropHdlFactory, true); | |||
374 | xColumnStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScColumnStylesProperties, xScPropHdlFactory, true); | |||
375 | xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScRowStylesProperties, xScPropHdlFactory, true); | |||
376 | xTableStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScTableStylesProperties, xScPropHdlFactory, true); | |||
377 | xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper); | |||
378 | xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this)); | |||
379 | xColumnStylesExportPropertySetMapper = new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper); | |||
380 | xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper); | |||
381 | xTableStylesExportPropertySetMapper = new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper); | |||
382 | ||||
383 | GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_CELL, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME"table-cell", | |||
384 | xCellStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX"ce"); | |||
385 | GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_COLUMN, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME"table-column", | |||
386 | xColumnStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX"co"); | |||
387 | GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_ROW, XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME"table-row", | |||
388 | xRowStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX"ro"); | |||
389 | GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_TABLE, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME"table", | |||
390 | xTableStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX"ta"); | |||
391 | ||||
392 | if( !(getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT)) ) | |||
393 | return; | |||
394 | ||||
395 | // This name is reserved for the external ref cache tables. This | |||
396 | // should not conflict with user-defined styles since this name is | |||
397 | // used for a table style which is not available in the UI. | |||
398 | sExternalRefTabStyleName = "ta_extref"; | |||
399 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE, sExternalRefTabStyleName); | |||
400 | ||||
401 | sAttrName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NAME)); | |||
402 | sAttrStyleName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME)); | |||
403 | sAttrColumnsRepeated = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED)); | |||
404 | sAttrFormula = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_FORMULA)); | |||
405 | sAttrStringValue = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE)); | |||
406 | sAttrValueType = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE)); | |||
407 | sElemCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_CELL)); | |||
408 | sElemCoveredCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_COVERED_TABLE_CELL)); | |||
409 | sElemCol = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_COLUMN)); | |||
410 | sElemRow = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_ROW)); | |||
411 | sElemTab = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE)); | |||
412 | sElemP = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT, GetXMLToken(XML_P)); | |||
413 | } | |||
414 | ||||
415 | ScXMLExport::~ScXMLExport() | |||
416 | { | |||
417 | pGroupColumns.reset(); | |||
418 | pGroupRows.reset(); | |||
419 | pColumnStyles.reset(); | |||
420 | pRowStyles.reset(); | |||
421 | pCellStyles.reset(); | |||
422 | pRowFormatRanges.reset(); | |||
423 | pMergedRangesContainer.reset(); | |||
424 | pValidationsContainer.reset(); | |||
425 | pChangeTrackingExportHelper.reset(); | |||
426 | pDefaults.reset(); | |||
427 | pNumberFormatAttributesExportHelper.reset(); | |||
428 | } | |||
429 | ||||
430 | void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream ) | |||
431 | { | |||
432 | xSourceStream = xNewStream; | |||
433 | ||||
434 | if ( !xSourceStream.is() ) | |||
435 | return; | |||
436 | ||||
437 | // make sure it's a plain UTF-8 stream as written by OOo itself | |||
438 | ||||
439 | const char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | |||
440 | sal_Int32 nLen = strlen(pXmlHeader); | |||
441 | ||||
442 | uno::Sequence<sal_Int8> aFileStart(nLen); | |||
443 | sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen ); | |||
444 | ||||
445 | if ( nRead != nLen || memcmp( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 ) | |||
446 | { | |||
447 | // invalid - ignore stream, save normally | |||
448 | xSourceStream.clear(); | |||
449 | } | |||
450 | else | |||
451 | { | |||
452 | // keep track of the bytes already read | |||
453 | nSourceStreamPos = nRead; | |||
454 | ||||
455 | const ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(GetModel())->GetSheetSaveData(); | |||
456 | if (pSheetData) | |||
457 | { | |||
458 | // add the loaded namespaces to the name space map | |||
459 | ||||
460 | if ( !pSheetData->AddLoadedNamespaces( GetNamespaceMap_() ) ) | |||
461 | { | |||
462 | // conflicts in the namespaces - ignore the stream, save normally | |||
463 | xSourceStream.clear(); | |||
464 | } | |||
465 | } | |||
466 | } | |||
467 | } | |||
468 | ||||
469 | sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const | |||
470 | { | |||
471 | NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt); | |||
472 | if (itr == aNumFmtIndexMap.end()) | |||
473 | return -1; | |||
474 | ||||
475 | return itr->second; | |||
476 | } | |||
477 | ||||
478 | void ScXMLExport::CollectSharedData(SCTAB& nTableCount, sal_Int32& nShapesCount) | |||
479 | { | |||
480 | if (!GetModel().is()) | |||
481 | return; | |||
482 | ||||
483 | uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc(GetModel(), uno::UNO_QUERY); | |||
484 | if (!xSpreadDoc.is()) | |||
485 | return; | |||
486 | ||||
487 | uno::Reference<container::XIndexAccess> xIndex(xSpreadDoc->getSheets(), uno::UNO_QUERY); | |||
488 | if (!xIndex.is()) | |||
489 | return; | |||
490 | ||||
491 | nTableCount = xIndex->getCount(); | |||
492 | if (!pSharedData) | |||
493 | pSharedData.reset(new ScMySharedData(nTableCount)); | |||
494 | ||||
495 | pCellStyles->AddNewTable(nTableCount - 1); | |||
496 | ||||
497 | for (SCTAB nTable = 0; nTable < nTableCount; ++nTable) | |||
498 | { | |||
499 | nCurrentTable = sal::static_int_cast<sal_uInt16>(nTable); | |||
500 | uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY); | |||
501 | if (!xDrawPageSupplier.is()) | |||
502 | continue; | |||
503 | ||||
504 | uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage()); | |||
505 | ScMyDrawPage aDrawPage; | |||
506 | aDrawPage.bHasForms = false; | |||
507 | aDrawPage.xDrawPage.set(xDrawPage); | |||
508 | pSharedData->AddDrawPage(aDrawPage, nTable); | |||
509 | if (!xDrawPage.is()) | |||
510 | continue; | |||
511 | ||||
512 | sal_Int32 nShapes = xDrawPage->getCount(); | |||
513 | for (sal_Int32 nShape = 0; nShape < nShapes; ++nShape) | |||
514 | { | |||
515 | uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(nShape), uno::UNO_QUERY); | |||
516 | if (!xShape.is()) | |||
517 | continue; | |||
518 | ||||
519 | uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY); | |||
520 | if (!xShapeProp.is()) | |||
521 | continue; | |||
522 | ||||
523 | sal_Int16 nLayerID = 0; | |||
524 | bool bExtracted = xShapeProp->getPropertyValue(gsLayerID) >>= nLayerID; | |||
525 | if (!bExtracted) | |||
526 | continue; | |||
527 | ||||
528 | if ((SdrLayerID(nLayerID) == SC_LAYER_INTERN) || (SdrLayerID(nLayerID) == SC_LAYER_HIDDEN)) | |||
529 | { | |||
530 | CollectInternalShape(xShape); | |||
531 | continue; | |||
532 | } | |||
533 | ||||
534 | ++nShapesCount; | |||
535 | ||||
536 | SvxShape* pShapeImp = comphelper::getUnoTunnelImplementation<SvxShape>(xShape); | |||
537 | if (!pShapeImp) | |||
538 | continue; | |||
539 | ||||
540 | SdrObject* pSdrObj = pShapeImp->GetSdrObject(); | |||
541 | if (!pSdrObj) | |||
542 | continue; | |||
543 | ||||
544 | if (ScDrawObjData *pAnchor = ScDrawLayer::GetNonRotatedObjData(pSdrObj)) | |||
545 | { | |||
546 | ScMyShape aMyShape; | |||
547 | aMyShape.aAddress = pAnchor->maStart; | |||
548 | SAL_WARN_IF(aMyShape.aAddress.Tab() != nTable, "sc", "not anchored to current sheet!")do { if (true && (aMyShape.aAddress.Tab() != nTable)) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "sc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not anchored to current sheet!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "548" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "not anchored to current sheet!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "not anchored to current sheet!"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "548" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not anchored to current sheet!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "548" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "not anchored to current sheet!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "not anchored to current sheet!"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "548" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
549 | aMyShape.aAddress.SetTab(nTable); | |||
550 | aMyShape.aEndAddress = pAnchor->maEnd; | |||
551 | aMyShape.aEndAddress.SetTab( nTable ); | |||
552 | aMyShape.nEndX = pAnchor->maEndOffset.X(); | |||
553 | aMyShape.nEndY = pAnchor->maEndOffset.Y(); | |||
554 | aMyShape.xShape = xShape; | |||
555 | aMyShape.bResizeWithCell = ScDrawLayer::IsResizeWithCell(*pSdrObj); | |||
556 | pSharedData->AddNewShape(aMyShape); | |||
557 | pSharedData->SetLastColumn(nTable, pAnchor->maStart.Col()); | |||
558 | pSharedData->SetLastRow(nTable, pAnchor->maStart.Row()); | |||
559 | } | |||
560 | else | |||
561 | pSharedData->AddTableShape(nTable, xShape); | |||
562 | } | |||
563 | } | |||
564 | } | |||
565 | ||||
566 | void ScXMLExport::CollectShapesAutoStyles(SCTAB nTableCount) | |||
567 | { | |||
568 | // #i84077# To avoid compiler warnings about uninitialized aShapeItr, | |||
569 | // it's initialized using this dummy list. The iterator contains shapes | |||
570 | // from all sheets, so it can't be declared inside the nTable loop where | |||
571 | // it is used. | |||
572 | ScMyShapeList aDummyInitList; | |||
573 | ||||
574 | pSharedData->SortShapesContainer(); | |||
575 | pSharedData->SortNoteShapes(); | |||
576 | const ScMyShapeList* pShapeList(nullptr); | |||
577 | ScMyShapeList::const_iterator aShapeItr = aDummyInitList.end(); | |||
578 | if (pSharedData->GetShapesContainer()) | |||
579 | { | |||
580 | pShapeList = &pSharedData->GetShapesContainer()->GetShapes(); | |||
581 | aShapeItr = pShapeList->begin(); | |||
582 | } | |||
583 | if (pSharedData->HasDrawPage()) | |||
584 | { | |||
585 | for (SCTAB nTable = 0; nTable < nTableCount; ++nTable) | |||
586 | { | |||
587 | uno::Reference<drawing::XDrawPage> xDrawPage(pSharedData->GetDrawPage(nTable)); | |||
588 | ||||
589 | if (xDrawPage.is()) | |||
590 | { | |||
591 | GetShapeExport()->seekShapes(xDrawPage); | |||
592 | uno::Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, uno::UNO_QUERY ); | |||
593 | if( xFormsSupplier.is() && xFormsSupplier->hasForms() ) | |||
594 | { | |||
595 | GetFormExport()->examineForms(xDrawPage); | |||
596 | pSharedData->SetDrawPageHasForms(nTable, true); | |||
597 | } | |||
598 | ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes()); | |||
599 | if (pTableShapes) | |||
600 | { | |||
601 | for (const auto& rxShape : (*pTableShapes)[nTable]) | |||
602 | { | |||
603 | GetShapeExport()->collectShapeAutoStyles(rxShape); | |||
604 | IncrementProgressBar(false); | |||
605 | } | |||
606 | } | |||
607 | if (pShapeList) | |||
608 | { | |||
609 | ScMyShapeList::const_iterator aEndItr(pShapeList->end()); | |||
610 | while ( aShapeItr != aEndItr && ( aShapeItr->aAddress.Tab() == nTable ) ) | |||
611 | { | |||
612 | GetShapeExport()->collectShapeAutoStyles(aShapeItr->xShape); | |||
613 | IncrementProgressBar(false); | |||
614 | ++aShapeItr; | |||
615 | } | |||
616 | } | |||
617 | if (pSharedData->GetNoteShapes()) | |||
618 | { | |||
619 | const ScMyNoteShapeList& rNoteShapes = pSharedData->GetNoteShapes()->GetNotes(); | |||
620 | for (const auto& rNoteShape : rNoteShapes) | |||
621 | { | |||
622 | if ( rNoteShape.aPos.Tab() == nTable ) | |||
623 | GetShapeExport()->collectShapeAutoStyles(rNoteShape.xShape); | |||
624 | } | |||
625 | } | |||
626 | } | |||
627 | } | |||
628 | } | |||
629 | pSharedData->SortNoteShapes(); // sort twice, because some more shapes are added | |||
630 | } | |||
631 | ||||
632 | void ScXMLExport::ExportMeta_() | |||
633 | { | |||
634 | sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0); | |||
635 | SCTAB nTableCount(0); | |||
636 | sal_Int32 nShapesCount(0); | |||
637 | GetAutoStylePool()->ClearEntries(); | |||
638 | CollectSharedData(nTableCount, nShapesCount); | |||
639 | ||||
640 | uno::Sequence<beans::NamedValue> stats | |||
641 | { | |||
642 | { "TableCount", uno::makeAny(static_cast<sal_Int32>(nTableCount)) }, | |||
643 | { "CellCount", uno::makeAny(nCellCount) }, | |||
644 | { "ObjectCount", uno::makeAny(nShapesCount) } | |||
645 | }; | |||
646 | ||||
647 | // update document statistics at the model | |||
648 | uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(), | |||
649 | uno::UNO_QUERY_THROW); | |||
650 | uno::Reference<document::XDocumentProperties> xDocProps( | |||
651 | xPropSup->getDocumentProperties()); | |||
652 | if (xDocProps.is()) { | |||
653 | xDocProps->setDocumentStatistics(stats); | |||
654 | } | |||
655 | ||||
656 | // export document properties | |||
657 | SvXMLExport::ExportMeta_(); | |||
658 | } | |||
659 | ||||
660 | void ScXMLExport::ExportFontDecls_() | |||
661 | { | |||
662 | GetFontAutoStylePool(); // make sure the pool is created | |||
663 | SvXMLExport::ExportFontDecls_(); | |||
664 | } | |||
665 | ||||
666 | table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable) | |||
667 | { | |||
668 | table::CellRangeAddress aCellAddress; | |||
669 | uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor()); | |||
670 | uno::Reference<sheet::XUsedAreaCursor> xUsedArea (xCursor, uno::UNO_QUERY); | |||
671 | uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY); | |||
672 | if (xUsedArea.is() && xCellAddress.is()) | |||
673 | { | |||
674 | xUsedArea->gotoEndOfUsedArea(true); | |||
675 | aCellAddress = xCellAddress->getRangeAddress(); | |||
676 | } | |||
677 | return aCellAddress; | |||
678 | } | |||
679 | ||||
680 | void ScXMLExport::GetAreaLinks( ScMyAreaLinksContainer& rAreaLinks ) | |||
681 | { | |||
682 | if (pDoc->GetLinkManager()) | |||
683 | { | |||
684 | const sfx2::SvBaseLinks& rLinks = pDoc->GetLinkManager()->GetLinks(); | |||
685 | for (const auto & rLink : rLinks) | |||
686 | { | |||
687 | ScAreaLink *pLink = dynamic_cast<ScAreaLink*>(rLink.get()); | |||
688 | if (pLink) | |||
689 | { | |||
690 | ScMyAreaLink aAreaLink; | |||
691 | aAreaLink.aDestRange = pLink->GetDestArea(); | |||
692 | aAreaLink.sSourceStr = pLink->GetSource(); | |||
693 | aAreaLink.sFilter = pLink->GetFilter(); | |||
694 | aAreaLink.sFilterOptions = pLink->GetOptions(); | |||
695 | aAreaLink.sURL = pLink->GetFile(); | |||
696 | aAreaLink.nRefresh = pLink->GetRefreshDelay(); | |||
697 | rAreaLinks.AddNewAreaLink( aAreaLink ); | |||
698 | } | |||
699 | } | |||
700 | } | |||
701 | rAreaLinks.Sort(); | |||
702 | } | |||
703 | ||||
704 | // core implementation | |||
705 | void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp ) | |||
706 | { | |||
707 | if (!pDoc) | |||
708 | return; | |||
709 | ||||
710 | ScDetOpList* pOpList(pDoc->GetDetOpList()); | |||
711 | if( !pOpList ) | |||
712 | return; | |||
713 | ||||
714 | size_t nCount = pOpList->Count(); | |||
715 | for (size_t nIndex = 0; nIndex < nCount; ++nIndex ) | |||
716 | { | |||
717 | const ScDetOpData& rDetData = pOpList->GetObject( nIndex); | |||
718 | const ScAddress& rDetPos = rDetData.GetPos(); | |||
719 | SCTAB nTab = rDetPos.Tab(); | |||
720 | if ( nTab < pDoc->GetTableCount() ) | |||
721 | { | |||
722 | rDetOp.AddOperation( rDetData.GetOperation(), rDetPos, static_cast<sal_uInt32>( nIndex) ); | |||
723 | ||||
724 | // cells with detective operations are written even if empty | |||
725 | pSharedData->SetLastColumn( nTab, rDetPos.Col() ); | |||
726 | pSharedData->SetLastRow( nTab, rDetPos.Row() ); | |||
727 | } | |||
728 | } | |||
729 | rDetOp.Sort(); | |||
730 | } | |||
731 | ||||
732 | void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex, | |||
733 | const sal_Int32 nIndex, const bool bIsAutoStyle, const bool bIsVisible) | |||
734 | { | |||
735 | CheckAttrList(); | |||
736 | AddAttribute(sAttrStyleName, pColumnStyles->GetStyleNameByIndex(nStyleIndex)); | |||
737 | if (!bIsVisible) | |||
738 | AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE); | |||
739 | if (nRepeatColumns > 1) | |||
740 | { | |||
741 | OUString sOUEndCol(OUString::number(nRepeatColumns)); | |||
742 | AddAttribute(sAttrColumnsRepeated, sOUEndCol); | |||
743 | } | |||
744 | if (nIndex != -1) | |||
745 | AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); | |||
746 | SvXMLElementExport aElemC(*this, sElemCol, true, true); | |||
747 | } | |||
748 | ||||
749 | void ScXMLExport::WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns, | |||
750 | const sal_Int32 nStyleIndex, const bool bIsVisible) | |||
751 | { | |||
752 | sal_Int32 nRepeat(1); | |||
753 | sal_Int32 nPrevIndex(pDefaults->GetColDefaults()[nColumn].nIndex); | |||
754 | bool bPrevAutoStyle(pDefaults->GetColDefaults()[nColumn].bIsAutoStyle); | |||
755 | for (sal_Int32 i = nColumn + 1; i < nColumn + nRepeatColumns; ++i) | |||
756 | { | |||
757 | if ((pDefaults->GetColDefaults()[i].nIndex != nPrevIndex) || | |||
758 | (pDefaults->GetColDefaults()[i].bIsAutoStyle != bPrevAutoStyle)) | |||
759 | { | |||
760 | WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible); | |||
761 | nPrevIndex = pDefaults->GetColDefaults()[i].nIndex; | |||
762 | bPrevAutoStyle = pDefaults->GetColDefaults()[i].bIsAutoStyle; | |||
763 | nRepeat = 1; | |||
764 | } | |||
765 | else | |||
766 | ++nRepeat; | |||
767 | } | |||
768 | WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible); | |||
769 | } | |||
770 | ||||
771 | void ScXMLExport::OpenHeaderColumn() | |||
772 | { | |||
773 | StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, true ); | |||
774 | } | |||
775 | ||||
776 | void ScXMLExport::CloseHeaderColumn() | |||
777 | { | |||
778 | EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, true); | |||
779 | } | |||
780 | ||||
781 | void ScXMLExport::ExportColumns(const sal_Int32 nTable, const ScRange& aColumnHeaderRange, const bool bHasColumnHeader) | |||
782 | { | |||
783 | sal_Int32 nColsRepeated (1); | |||
784 | sal_Int32 nIndex; | |||
785 | sal_Int32 nPrevColumn(0); | |||
786 | bool bPrevIsVisible (true); | |||
787 | bool bWasHeader (false); | |||
788 | bool bIsClosed (true); | |||
789 | sal_Int32 nPrevIndex (-1); | |||
790 | sal_Int32 nColumn; | |||
791 | for (nColumn = 0; nColumn <= pSharedData->GetLastColumn(nTable); ++nColumn) | |||
792 | { | |||
793 | CheckAttrList(); | |||
794 | bool bIsVisible(true); | |||
795 | nIndex = pColumnStyles->GetStyleNameIndex(nTable, nColumn, bIsVisible); | |||
796 | ||||
797 | const bool bIsHeader = bHasColumnHeader && (aColumnHeaderRange.aStart.Col() <= nColumn) && (nColumn <= aColumnHeaderRange.aEnd.Col()); | |||
798 | if (bIsHeader != bWasHeader) | |||
799 | { | |||
800 | if (bIsHeader) | |||
801 | { | |||
802 | if (nColumn > 0) | |||
803 | { | |||
804 | WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); | |||
805 | if (pGroupColumns->IsGroupEnd(nColumn - 1)) | |||
806 | pGroupColumns->CloseGroups(nColumn - 1); | |||
807 | } | |||
808 | bPrevIsVisible = bIsVisible; | |||
809 | nPrevIndex = nIndex; | |||
810 | nPrevColumn = nColumn; | |||
811 | nColsRepeated = 1; | |||
812 | if(pGroupColumns->IsGroupStart(nColumn)) | |||
813 | pGroupColumns->OpenGroups(nColumn); | |||
814 | OpenHeaderColumn(); | |||
815 | bWasHeader = true; | |||
816 | bIsClosed = false; | |||
817 | } | |||
818 | else | |||
819 | { | |||
820 | WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); | |||
821 | CloseHeaderColumn(); | |||
822 | if (pGroupColumns->IsGroupEnd(nColumn - 1)) | |||
823 | pGroupColumns->CloseGroups(nColumn - 1); | |||
824 | if(pGroupColumns->IsGroupStart(nColumn)) | |||
825 | pGroupColumns->OpenGroups(nColumn); | |||
826 | bPrevIsVisible = bIsVisible; | |||
827 | nPrevIndex = nIndex; | |||
828 | nPrevColumn = nColumn; | |||
829 | nColsRepeated = 1; | |||
830 | bWasHeader = false; | |||
831 | bIsClosed = true; | |||
832 | } | |||
833 | } | |||
834 | else if (nColumn == 0) | |||
835 | { | |||
836 | if (pGroupColumns->IsGroupStart(nColumn)) | |||
837 | pGroupColumns->OpenGroups(nColumn); | |||
838 | bPrevIsVisible = bIsVisible; | |||
839 | nPrevIndex = nIndex; | |||
840 | } | |||
841 | else if ((bIsVisible == bPrevIsVisible) && (nIndex == nPrevIndex) && | |||
842 | !pGroupColumns->IsGroupStart(nColumn) && !pGroupColumns->IsGroupEnd(nColumn - 1)) | |||
843 | ++nColsRepeated; | |||
844 | else | |||
845 | { | |||
846 | WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); | |||
847 | if (pGroupColumns->IsGroupEnd(nColumn - 1)) | |||
848 | { | |||
849 | if (bIsHeader) | |||
850 | CloseHeaderColumn(); | |||
851 | pGroupColumns->CloseGroups(nColumn - 1); | |||
852 | if (bIsHeader) | |||
853 | OpenHeaderColumn(); | |||
854 | } | |||
855 | if (pGroupColumns->IsGroupStart(nColumn)) | |||
856 | { | |||
857 | if (bIsHeader) | |||
858 | CloseHeaderColumn(); | |||
859 | pGroupColumns->OpenGroups(nColumn); | |||
860 | if (bIsHeader) | |||
861 | OpenHeaderColumn(); | |||
862 | } | |||
863 | bPrevIsVisible = bIsVisible; | |||
864 | nPrevIndex = nIndex; | |||
865 | nPrevColumn = nColumn; | |||
866 | nColsRepeated = 1; | |||
867 | } | |||
868 | } | |||
869 | assert(nPrevIndex >= 0 && "coverity#1438402")(static_cast <bool> (nPrevIndex >= 0 && "coverity#1438402" ) ? void (0) : __assert_fail ("nPrevIndex >= 0 && \"coverity#1438402\"" , "/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" , 869, __extension__ __PRETTY_FUNCTION__)); | |||
870 | WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); | |||
871 | if (!bIsClosed) | |||
872 | CloseHeaderColumn(); | |||
873 | if (pGroupColumns->IsGroupEnd(nColumn - 1)) | |||
874 | pGroupColumns->CloseGroups(nColumn - 1); | |||
875 | } | |||
876 | ||||
877 | void ScXMLExport::ExportExternalRefCacheStyles() | |||
878 | { | |||
879 | sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex( | |||
880 | "NumberFormat", XML_NAMESPACE_STYLE, "data-style-name"); | |||
881 | ||||
882 | if (nEntryIndex < 0) | |||
883 | // No entry index for the number format is found. | |||
884 | return; | |||
885 | ||||
886 | ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); | |||
| ||||
887 | if (!pRefMgr->hasExternalData()) | |||
888 | // No external reference data cached. | |||
889 | return; | |||
890 | ||||
891 | // Export each unique number format used in the external ref cache. | |||
892 | vector<sal_uInt32> aNumFmts; | |||
893 | pRefMgr->getAllCachedNumberFormats(aNumFmts); | |||
894 | const OUString aDefaultStyle = OUString("Default").intern(); | |||
895 | for (const auto& rNumFmt : aNumFmts) | |||
896 | { | |||
897 | sal_Int32 nNumFmt = static_cast<sal_Int32>(rNumFmt); | |||
898 | ||||
899 | addDataStyle(nNumFmt); | |||
900 | ||||
901 | uno::Any aVal; | |||
902 | aVal <<= nNumFmt; | |||
903 | vector<XMLPropertyState> aProps; | |||
904 | aVal <<= aDefaultStyle; | |||
905 | aProps.emplace_back(nEntryIndex, aVal); | |||
906 | ||||
907 | OUString aName; | |||
908 | sal_Int32 nIndex; | |||
909 | if (GetAutoStylePool()->Add(aName, XmlStyleFamily::TABLE_CELL, aDefaultStyle, aProps)) | |||
910 | { | |||
911 | pCellStyles->AddStyleName(aName, nIndex); | |||
912 | } | |||
913 | else | |||
914 | { | |||
915 | bool bIsAuto; | |||
916 | nIndex = pCellStyles->GetIndexOfStyleName( | |||
917 | aName, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX"ce", bIsAuto); | |||
918 | } | |||
919 | ||||
920 | // store the number format to index mapping for later use. | |||
921 | aNumFmtIndexMap.emplace(nNumFmt, nIndex); | |||
922 | } | |||
923 | } | |||
924 | ||||
925 | namespace { | |||
926 | ||||
927 | void handleFont( | |||
928 | std::vector<XMLPropertyState>& rPropStates, | |||
929 | const SfxPoolItem* p, const rtl::Reference<XMLPropertySetMapper>& xMapper, const OUString& rXMLName ) | |||
930 | { | |||
931 | sal_Int32 nEntryCount = xMapper->GetEntryCount(); | |||
932 | ||||
933 | // Apparently font info needs special handling. | |||
934 | const SvxFontItem* pItem = static_cast<const SvxFontItem*>(p); | |||
935 | ||||
936 | sal_Int32 nIndexFontName = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, rXMLName, 0); | |||
937 | ||||
938 | if (nIndexFontName == -1 || nIndexFontName >= nEntryCount) | |||
939 | return; | |||
940 | ||||
941 | uno::Any aAny; | |||
942 | if (!pItem->QueryValue(aAny, MID_FONT_FAMILY_NAME1)) | |||
943 | return; | |||
944 | ||||
945 | rPropStates.emplace_back(nIndexFontName, aAny); | |||
946 | } | |||
947 | ||||
948 | const SvxFieldData* toXMLPropertyStates( | |||
949 | std::vector<XMLPropertyState>& rPropStates, const std::vector<const SfxPoolItem*>& rSecAttrs, | |||
950 | const rtl::Reference<XMLPropertySetMapper>& xMapper, const ScXMLEditAttributeMap& rAttrMap ) | |||
951 | { | |||
952 | const SvxFieldData* pField = nullptr; | |||
953 | sal_Int32 nEntryCount = xMapper->GetEntryCount(); | |||
954 | rPropStates.reserve(rSecAttrs.size()); | |||
955 | for (const SfxPoolItem* p : rSecAttrs) | |||
956 | { | |||
957 | if (p->Which() == EE_FEATURE_FIELD) | |||
958 | { | |||
959 | pField = static_cast<const SvxFieldItem*>(p)->GetField(); | |||
960 | continue; | |||
961 | } | |||
962 | ||||
963 | const ScXMLEditAttributeMap::Entry* pEntry = rAttrMap.getEntryByItemID(p->Which()); | |||
964 | if (!pEntry) | |||
965 | continue; | |||
966 | ||||
967 | sal_Int32 nIndex = xMapper->GetEntryIndex( | |||
968 | pEntry->nmXMLNS, OUString::createFromAscii(pEntry->mpXMLName), 0); | |||
969 | ||||
970 | if (nIndex == -1 || nIndex >= nEntryCount) | |||
971 | continue; | |||
972 | ||||
973 | uno::Any aAny; | |||
974 | switch (p->Which()) | |||
975 | { | |||
976 | case EE_CHAR_FONTINFO: | |||
977 | handleFont(rPropStates, p, xMapper, "font-name"); | |||
978 | break; | |||
979 | case EE_CHAR_FONTINFO_CJK: | |||
980 | handleFont(rPropStates, p, xMapper, "font-name-asian"); | |||
981 | break; | |||
982 | case EE_CHAR_FONTINFO_CTL: | |||
983 | handleFont(rPropStates, p, xMapper, "font-name-complex"); | |||
984 | break; | |||
985 | case EE_CHAR_WEIGHT: | |||
986 | case EE_CHAR_WEIGHT_CJK: | |||
987 | case EE_CHAR_WEIGHT_CTL: | |||
988 | { | |||
989 | if (!static_cast<const SvxWeightItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
990 | continue; | |||
991 | ||||
992 | rPropStates.emplace_back(nIndex, aAny); | |||
993 | } | |||
994 | break; | |||
995 | case EE_CHAR_FONTHEIGHT: | |||
996 | case EE_CHAR_FONTHEIGHT_CJK: | |||
997 | case EE_CHAR_FONTHEIGHT_CTL: | |||
998 | { | |||
999 | if (!static_cast<const SvxFontHeightItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1000 | continue; | |||
1001 | ||||
1002 | rPropStates.emplace_back(nIndex, aAny); | |||
1003 | } | |||
1004 | break; | |||
1005 | case EE_CHAR_ITALIC: | |||
1006 | case EE_CHAR_ITALIC_CJK: | |||
1007 | case EE_CHAR_ITALIC_CTL: | |||
1008 | { | |||
1009 | if (!static_cast<const SvxPostureItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1010 | continue; | |||
1011 | ||||
1012 | rPropStates.emplace_back(nIndex, aAny); | |||
1013 | } | |||
1014 | break; | |||
1015 | case EE_CHAR_UNDERLINE: | |||
1016 | { | |||
1017 | // Underline attribute needs to export multiple entries. | |||
1018 | sal_Int32 nIndexStyle = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-style", 0); | |||
1019 | if (nIndexStyle == -1 || nIndexStyle > nEntryCount) | |||
1020 | break; | |||
1021 | ||||
1022 | sal_Int32 nIndexWidth = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-width", 0); | |||
1023 | if (nIndexWidth == -1 || nIndexWidth > nEntryCount) | |||
1024 | break; | |||
1025 | ||||
1026 | sal_Int32 nIndexType = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-type", 0); | |||
1027 | if (nIndexType == -1 || nIndexType > nEntryCount) | |||
1028 | break; | |||
1029 | ||||
1030 | sal_Int32 nIndexColor = xMapper->FindEntryIndex("CharUnderlineColor", XML_NAMESPACE_STYLE, "text-underline-color"); | |||
1031 | if (nIndexColor == -1 || nIndexColor > nEntryCount) | |||
1032 | break; | |||
1033 | ||||
1034 | sal_Int32 nIndexHasColor = xMapper->FindEntryIndex("CharUnderlineHasColor", XML_NAMESPACE_STYLE, "text-underline-color"); | |||
1035 | if (nIndexHasColor == -1 || nIndexHasColor > nEntryCount) | |||
1036 | break; | |||
1037 | ||||
1038 | const SvxUnderlineItem* pUL = static_cast<const SvxUnderlineItem*>(p); | |||
1039 | pUL->QueryValue(aAny, MID_TL_STYLE1); | |||
1040 | rPropStates.emplace_back(nIndexStyle, aAny); | |||
1041 | rPropStates.emplace_back(nIndexType, aAny); | |||
1042 | rPropStates.emplace_back(nIndexWidth, aAny); | |||
1043 | ||||
1044 | pUL->QueryValue(aAny, MID_TL_COLOR2); | |||
1045 | rPropStates.emplace_back(nIndexColor, aAny); | |||
1046 | ||||
1047 | pUL->QueryValue(aAny, MID_TL_HASCOLOR3); | |||
1048 | rPropStates.emplace_back(nIndexHasColor, aAny); | |||
1049 | } | |||
1050 | break; | |||
1051 | case EE_CHAR_OVERLINE: | |||
1052 | { | |||
1053 | // Same with overline. Do just as we do with underline attributes. | |||
1054 | sal_Int32 nIndexStyle = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-style", 0); | |||
1055 | if (nIndexStyle == -1 || nIndexStyle > nEntryCount) | |||
1056 | break; | |||
1057 | ||||
1058 | sal_Int32 nIndexWidth = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-width", 0); | |||
1059 | if (nIndexWidth == -1 || nIndexWidth > nEntryCount) | |||
1060 | break; | |||
1061 | ||||
1062 | sal_Int32 nIndexType = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-type", 0); | |||
1063 | if (nIndexType == -1 || nIndexType > nEntryCount) | |||
1064 | break; | |||
1065 | ||||
1066 | sal_Int32 nIndexColor = xMapper->FindEntryIndex("CharOverlineColor", XML_NAMESPACE_STYLE, "text-overline-color"); | |||
1067 | if (nIndexColor == -1 || nIndexColor > nEntryCount) | |||
1068 | break; | |||
1069 | ||||
1070 | sal_Int32 nIndexHasColor = xMapper->FindEntryIndex("CharOverlineHasColor", XML_NAMESPACE_STYLE, "text-overline-color"); | |||
1071 | if (nIndexHasColor == -1 || nIndexHasColor > nEntryCount) | |||
1072 | break; | |||
1073 | ||||
1074 | const SvxOverlineItem* pOL = static_cast<const SvxOverlineItem*>(p); | |||
1075 | pOL->QueryValue(aAny, MID_TL_STYLE1); | |||
1076 | rPropStates.emplace_back(nIndexStyle, aAny); | |||
1077 | rPropStates.emplace_back(nIndexType, aAny); | |||
1078 | rPropStates.emplace_back(nIndexWidth, aAny); | |||
1079 | ||||
1080 | pOL->QueryValue(aAny, MID_TL_COLOR2); | |||
1081 | rPropStates.emplace_back(nIndexColor, aAny); | |||
1082 | ||||
1083 | pOL->QueryValue(aAny, MID_TL_HASCOLOR3); | |||
1084 | rPropStates.emplace_back(nIndexHasColor, aAny); | |||
1085 | } | |||
1086 | break; | |||
1087 | case EE_CHAR_COLOR: | |||
1088 | { | |||
1089 | if (!static_cast<const SvxColorItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1090 | continue; | |||
1091 | ||||
1092 | ::Color nColor; | |||
1093 | if ( aAny >>= nColor ) | |||
1094 | { | |||
1095 | sal_Int32 nIndexColor = ( nColor == COL_AUTO ) ? xMapper->GetEntryIndex( | |||
1096 | XML_NAMESPACE_STYLE, GetXMLToken( XML_USE_WINDOW_FONT_COLOR ), 0 ) : nIndex; | |||
1097 | rPropStates.emplace_back( nIndexColor, aAny ); | |||
1098 | } | |||
1099 | } | |||
1100 | break; | |||
1101 | case EE_CHAR_WLM: | |||
1102 | { | |||
1103 | if (!static_cast<const SvxWordLineModeItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1104 | continue; | |||
1105 | ||||
1106 | rPropStates.emplace_back(nIndex, aAny); | |||
1107 | } | |||
1108 | break; | |||
1109 | case EE_CHAR_STRIKEOUT: | |||
1110 | { | |||
1111 | if (!static_cast<const SvxCrossedOutItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1112 | continue; | |||
1113 | ||||
1114 | rPropStates.emplace_back(nIndex, aAny); | |||
1115 | } | |||
1116 | break; | |||
1117 | case EE_CHAR_RELIEF: | |||
1118 | { | |||
1119 | if (!static_cast<const SvxCharReliefItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1120 | continue; | |||
1121 | ||||
1122 | rPropStates.emplace_back(nIndex, aAny); | |||
1123 | } | |||
1124 | break; | |||
1125 | case EE_CHAR_OUTLINE: | |||
1126 | { | |||
1127 | if (!static_cast<const SvxContourItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1128 | continue; | |||
1129 | ||||
1130 | rPropStates.emplace_back(nIndex, aAny); | |||
1131 | } | |||
1132 | break; | |||
1133 | case EE_CHAR_SHADOW: | |||
1134 | { | |||
1135 | if (!static_cast<const SvxShadowedItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1136 | continue; | |||
1137 | ||||
1138 | rPropStates.emplace_back(nIndex, aAny); | |||
1139 | } | |||
1140 | break; | |||
1141 | case EE_CHAR_KERNING: | |||
1142 | { | |||
1143 | if (!static_cast<const SvxKerningItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1144 | continue; | |||
1145 | ||||
1146 | rPropStates.emplace_back(nIndex, aAny); | |||
1147 | } | |||
1148 | break; | |||
1149 | case EE_CHAR_PAIRKERNING: | |||
1150 | { | |||
1151 | if (!static_cast<const SvxAutoKernItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1152 | continue; | |||
1153 | ||||
1154 | rPropStates.emplace_back(nIndex, aAny); | |||
1155 | } | |||
1156 | break; | |||
1157 | case EE_CHAR_FONTWIDTH: | |||
1158 | { | |||
1159 | if (!static_cast<const SvxCharScaleWidthItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1160 | continue; | |||
1161 | ||||
1162 | rPropStates.emplace_back(nIndex, aAny); | |||
1163 | } | |||
1164 | break; | |||
1165 | case EE_CHAR_ESCAPEMENT: | |||
1166 | { | |||
1167 | sal_Int32 nIndexEsc = xMapper->FindEntryIndex("CharEscapement", XML_NAMESPACE_STYLE, "text-position"); | |||
1168 | if (nIndexEsc == -1 || nIndexEsc > nEntryCount) | |||
1169 | break; | |||
1170 | ||||
1171 | sal_Int32 nIndexEscHeight = xMapper->FindEntryIndex("CharEscapementHeight", XML_NAMESPACE_STYLE, "text-position"); | |||
1172 | if (nIndexEscHeight == -1 || nIndexEscHeight > nEntryCount) | |||
1173 | break; | |||
1174 | ||||
1175 | const SvxEscapementItem* pEsc = static_cast<const SvxEscapementItem*>(p); | |||
1176 | ||||
1177 | pEsc->QueryValue(aAny); | |||
1178 | rPropStates.emplace_back(nIndexEsc, aAny); | |||
1179 | ||||
1180 | pEsc->QueryValue(aAny, MID_ESC_HEIGHT1); | |||
1181 | rPropStates.emplace_back(nIndexEscHeight, aAny); | |||
1182 | ||||
1183 | } | |||
1184 | break; | |||
1185 | case EE_CHAR_EMPHASISMARK: | |||
1186 | { | |||
1187 | if (!static_cast<const SvxEmphasisMarkItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1188 | continue; | |||
1189 | ||||
1190 | rPropStates.emplace_back(nIndex, aAny); | |||
1191 | } | |||
1192 | break; | |||
1193 | case EE_CHAR_LANGUAGE: | |||
1194 | case EE_CHAR_LANGUAGE_CJK: | |||
1195 | case EE_CHAR_LANGUAGE_CTL: | |||
1196 | { | |||
1197 | if (!static_cast<const SvxLanguageItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) | |||
1198 | continue; | |||
1199 | ||||
1200 | // Export multiple entries. | |||
1201 | sal_Int32 nIndexLanguage, nIndexCountry, nIndexScript, nIndexTag; | |||
1202 | switch (p->Which()) | |||
1203 | { | |||
1204 | case EE_CHAR_LANGUAGE: | |||
1205 | nIndexLanguage = xMapper->GetEntryIndex( XML_NAMESPACE_FO, "language", 0); | |||
1206 | nIndexCountry = xMapper->GetEntryIndex( XML_NAMESPACE_FO, "country", 0); | |||
1207 | nIndexScript = xMapper->GetEntryIndex( XML_NAMESPACE_FO, "script", 0); | |||
1208 | nIndexTag = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "rfc-language-tag", 0); | |||
1209 | break; | |||
1210 | case EE_CHAR_LANGUAGE_CJK: | |||
1211 | nIndexLanguage = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "language-asian", 0); | |||
1212 | nIndexCountry = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "country-asian", 0); | |||
1213 | nIndexScript = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "script-asian", 0); | |||
1214 | nIndexTag = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "rfc-language-tag-asian", 0); | |||
1215 | break; | |||
1216 | case EE_CHAR_LANGUAGE_CTL: | |||
1217 | nIndexLanguage = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "language-complex", 0); | |||
1218 | nIndexCountry = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "country-complex", 0); | |||
1219 | nIndexScript = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "script-complex", 0); | |||
1220 | nIndexTag = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "rfc-language-tag-complex", 0); | |||
1221 | break; | |||
1222 | default: | |||
1223 | nIndexLanguage = nIndexCountry = nIndexScript = nIndexTag = -1; | |||
1224 | } | |||
1225 | assert( nIndexLanguage >= 0 && nIndexCountry >= 0 && nIndexScript >= 0 && nIndexTag >= 0)(static_cast <bool> (nIndexLanguage >= 0 && nIndexCountry >= 0 && nIndexScript >= 0 && nIndexTag >= 0) ? void (0) : __assert_fail ("nIndexLanguage >= 0 && nIndexCountry >= 0 && nIndexScript >= 0 && nIndexTag >= 0" , "/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" , 1225, __extension__ __PRETTY_FUNCTION__)); | |||
1226 | rPropStates.emplace_back( nIndexLanguage, aAny); | |||
1227 | rPropStates.emplace_back( nIndexCountry, aAny); | |||
1228 | rPropStates.emplace_back( nIndexScript, aAny); | |||
1229 | rPropStates.emplace_back( nIndexTag, aAny); | |||
1230 | } | |||
1231 | break; | |||
1232 | default: | |||
1233 | continue; | |||
1234 | } | |||
1235 | } | |||
1236 | ||||
1237 | return pField; | |||
1238 | } | |||
1239 | ||||
1240 | } | |||
1241 | ||||
1242 | void ScXMLExport::ExportCellTextAutoStyles(sal_Int32 nTable) | |||
1243 | { | |||
1244 | if (!ValidTab(nTable)) | |||
1245 | return; | |||
1246 | ||||
1247 | rtl::Reference<XMLPropertySetMapper> xMapper = GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper(); | |||
1248 | rtl::Reference<SvXMLAutoStylePoolP> xStylePool = GetAutoStylePool(); | |||
1249 | const ScXMLEditAttributeMap& rAttrMap = GetEditAttributeMap(); | |||
1250 | ||||
1251 | sc::EditTextIterator aIter(*pDoc, nTable); | |||
1252 | sal_Int32 nCellCount = 0; | |||
1253 | for (const EditTextObject* pEdit = aIter.first(); pEdit; pEdit = aIter.next(), ++nCellCount) | |||
1254 | { | |||
1255 | std::vector<editeng::Section> aAttrs; | |||
1256 | pEdit->GetAllSections(aAttrs); | |||
1257 | if (aAttrs.empty()) | |||
1258 | continue; | |||
1259 | ||||
1260 | for (const auto& rSec : aAttrs) | |||
1261 | { | |||
1262 | const std::vector<const SfxPoolItem*>& rSecAttrs = rSec.maAttributes; | |||
1263 | if (rSecAttrs.empty()) | |||
1264 | // No formats applied to this section. Skip it. | |||
1265 | continue; | |||
1266 | ||||
1267 | std::vector<XMLPropertyState> aPropStates; | |||
1268 | toXMLPropertyStates(aPropStates, rSecAttrs, xMapper, rAttrMap); | |||
1269 | if (!aPropStates.empty()) | |||
1270 | xStylePool->Add(XmlStyleFamily::TEXT_TEXT, OUString(), aPropStates); | |||
1271 | } | |||
1272 | } | |||
1273 | ||||
1274 | GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCellCount); | |||
1275 | } | |||
1276 | ||||
1277 | void ScXMLExport::WriteRowContent() | |||
1278 | { | |||
1279 | ScMyRowFormatRange aRange; | |||
1280 | sal_Int32 nIndex(-1); | |||
1281 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1282 | sal_Int32 nPrevCol(0); | |||
1283 | #endif | |||
1284 | sal_Int32 nCols(0); | |||
1285 | sal_Int32 nPrevValidationIndex(-1); | |||
1286 | bool bIsAutoStyle(true); | |||
1287 | bool bIsFirst(true); | |||
1288 | while (pRowFormatRanges->GetNext(aRange)) | |||
1289 | { | |||
1290 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1291 | OSL_ENSURE(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn)), "here are some columns missing")do { if (true && (!(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn))))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "1291" ": "), "%s", "here are some columns missing"); } } while (false); | |||
1292 | #endif | |||
1293 | if (bIsFirst) | |||
1294 | { | |||
1295 | nIndex = aRange.nIndex; | |||
1296 | nPrevValidationIndex = aRange.nValidationIndex; | |||
1297 | bIsAutoStyle = aRange.bIsAutoStyle; | |||
1298 | nCols = aRange.nRepeatColumns; | |||
1299 | bIsFirst = false; | |||
1300 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1301 | nPrevCol = aRange.nStartColumn; | |||
1302 | #endif | |||
1303 | } | |||
1304 | else | |||
1305 | { | |||
1306 | if (((aRange.nIndex == nIndex && aRange.bIsAutoStyle == bIsAutoStyle) || | |||
1307 | (aRange.nIndex == nIndex && nIndex == -1)) && | |||
1308 | nPrevValidationIndex == aRange.nValidationIndex) | |||
1309 | nCols += aRange.nRepeatColumns; | |||
1310 | else | |||
1311 | { | |||
1312 | if (nIndex != -1) | |||
1313 | AddAttribute(sAttrStyleName, pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); | |||
1314 | if (nPrevValidationIndex > -1) | |||
1315 | AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex)); | |||
1316 | if (nCols > 1) | |||
1317 | { | |||
1318 | AddAttribute(sAttrColumnsRepeated, OUString::number(nCols)); | |||
1319 | } | |||
1320 | SvXMLElementExport aElemC(*this, sElemCell, true, true); | |||
1321 | nIndex = aRange.nIndex; | |||
1322 | bIsAutoStyle = aRange.bIsAutoStyle; | |||
1323 | nCols = aRange.nRepeatColumns; | |||
1324 | nPrevValidationIndex = aRange.nValidationIndex; | |||
1325 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1326 | nPrevCol = aRange.nStartColumn; | |||
1327 | #endif | |||
1328 | } | |||
1329 | } | |||
1330 | } | |||
1331 | if (!bIsFirst) | |||
1332 | { | |||
1333 | if (nIndex != -1) | |||
1334 | AddAttribute(sAttrStyleName, pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); | |||
1335 | if (nPrevValidationIndex > -1) | |||
1336 | AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex)); | |||
1337 | if (nCols > 1) | |||
1338 | { | |||
1339 | AddAttribute(sAttrColumnsRepeated, OUString::number(nCols)); | |||
1340 | } | |||
1341 | SvXMLElementExport aElemC(*this, sElemCell, true, true); | |||
1342 | } | |||
1343 | } | |||
1344 | ||||
1345 | void ScXMLExport::WriteRowStartTag( | |||
1346 | const sal_Int32 nIndex, const sal_Int32 nEqualRows, | |||
1347 | bool bHidden, bool bFiltered) | |||
1348 | { | |||
1349 | AddAttribute(sAttrStyleName, pRowStyles->GetStyleNameByIndex(nIndex)); | |||
1350 | if (bHidden) | |||
1351 | { | |||
1352 | if (bFiltered) | |||
1353 | AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_FILTER); | |||
1354 | else | |||
1355 | AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE); | |||
1356 | } | |||
1357 | if (nEqualRows > 1) | |||
1358 | { | |||
1359 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, OUString::number(nEqualRows)); | |||
1360 | } | |||
1361 | ||||
1362 | StartElement( sElemRow, true); | |||
1363 | } | |||
1364 | ||||
1365 | void ScXMLExport::OpenHeaderRows() | |||
1366 | { | |||
1367 | StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, true); | |||
1368 | bRowHeaderOpen = true; | |||
1369 | } | |||
1370 | ||||
1371 | void ScXMLExport::CloseHeaderRows() | |||
1372 | { | |||
1373 | EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, true); | |||
1374 | } | |||
1375 | ||||
1376 | void ScXMLExport::OpenNewRow( | |||
1377 | const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEqualRows, | |||
1378 | bool bHidden, bool bFiltered) | |||
1379 | { | |||
1380 | nOpenRow = nStartRow; | |||
1381 | if (pGroupRows->IsGroupStart(nStartRow)) | |||
1382 | { | |||
1383 | if (bHasRowHeader && bRowHeaderOpen) | |||
1384 | CloseHeaderRows(); | |||
1385 | pGroupRows->OpenGroups(nStartRow); | |||
1386 | if (bHasRowHeader && bRowHeaderOpen) | |||
1387 | OpenHeaderRows(); | |||
1388 | } | |||
1389 | if (bHasRowHeader && !bRowHeaderOpen && nStartRow >= aRowHeaderRange.aStart.Row() && nStartRow <= aRowHeaderRange.aEnd.Row()) | |||
1390 | { | |||
1391 | if (nStartRow == aRowHeaderRange.aStart.Row()) | |||
1392 | OpenHeaderRows(); | |||
1393 | sal_Int32 nEquals; | |||
1394 | if (aRowHeaderRange.aEnd.Row() < nStartRow + nEqualRows - 1) | |||
1395 | nEquals = aRowHeaderRange.aEnd.Row() - nStartRow + 1; | |||
1396 | else | |||
1397 | nEquals = nEqualRows; | |||
1398 | WriteRowStartTag(nIndex, nEquals, bHidden, bFiltered); | |||
1399 | nOpenRow = nStartRow + nEquals - 1; | |||
1400 | if (nEquals < nEqualRows) | |||
1401 | { | |||
1402 | CloseRow(nStartRow + nEquals - 1); | |||
1403 | WriteRowStartTag(nIndex, nEqualRows - nEquals, bHidden, bFiltered); | |||
1404 | nOpenRow = nStartRow + nEqualRows - 1; | |||
1405 | } | |||
1406 | } | |||
1407 | else | |||
1408 | WriteRowStartTag(nIndex, nEqualRows, bHidden, bFiltered); | |||
1409 | } | |||
1410 | ||||
1411 | void ScXMLExport::OpenAndCloseRow( | |||
1412 | const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEqualRows, | |||
1413 | bool bHidden, bool bFiltered) | |||
1414 | { | |||
1415 | OpenNewRow(nIndex, nStartRow, nEqualRows, bHidden, bFiltered); | |||
1416 | WriteRowContent(); | |||
1417 | CloseRow(nStartRow + nEqualRows - 1); | |||
1418 | pRowFormatRanges->Clear(); | |||
1419 | } | |||
1420 | ||||
1421 | void ScXMLExport::OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow, ScXMLCachedRowAttrAccess& rRowAttr) | |||
1422 | { | |||
1423 | if (nRepeatRow > 1) | |||
1424 | { | |||
1425 | sal_Int32 nPrevIndex(0), nIndex; | |||
1426 | bool bPrevHidden = false; | |||
1427 | bool bPrevFiltered = false; | |||
1428 | bool bHidden = false; | |||
1429 | bool bFiltered = false; | |||
1430 | sal_Int32 nEqualRows(1); | |||
1431 | sal_Int32 nEndRow(nStartRow + nRepeatRow); | |||
1432 | sal_Int32 nEndRowHidden = nStartRow - 1; | |||
1433 | sal_Int32 nEndRowFiltered = nStartRow - 1; | |||
1434 | sal_Int32 nRow; | |||
1435 | for (nRow = nStartRow; nRow < nEndRow; ++nRow) | |||
1436 | { | |||
1437 | if (nRow == nStartRow) | |||
1438 | { | |||
1439 | nPrevIndex = pRowStyles->GetStyleNameIndex(nTable, nRow); | |||
1440 | if (pDoc) | |||
1441 | { | |||
1442 | if (nRow > nEndRowHidden) | |||
1443 | { | |||
1444 | bPrevHidden = rRowAttr.rowHidden(nTable, nRow, nEndRowHidden); | |||
1445 | bHidden = bPrevHidden; | |||
1446 | } | |||
1447 | if (nRow > nEndRowFiltered) | |||
1448 | { | |||
1449 | bPrevFiltered = rRowAttr.rowFiltered(nTable, nRow, nEndRowFiltered); | |||
1450 | bFiltered = bPrevFiltered; | |||
1451 | } | |||
1452 | } | |||
1453 | ||||
1454 | } | |||
1455 | else | |||
1456 | { | |||
1457 | nIndex = pRowStyles->GetStyleNameIndex(nTable, nRow); | |||
1458 | if (pDoc) | |||
1459 | { | |||
1460 | if (nRow > nEndRowHidden) | |||
1461 | bHidden = rRowAttr.rowHidden(nTable, nRow, nEndRowHidden); | |||
1462 | if (nRow > nEndRowFiltered) | |||
1463 | bFiltered = rRowAttr.rowFiltered(nTable, nRow, nEndRowFiltered); | |||
1464 | } | |||
1465 | if (nIndex == nPrevIndex && bHidden == bPrevHidden && bFiltered == bPrevFiltered && | |||
1466 | !(bHasRowHeader && ((nRow == aRowHeaderRange.aStart.Row()) || (nRow - 1 == aRowHeaderRange.aEnd.Row()))) && | |||
1467 | !(pGroupRows->IsGroupStart(nRow)) && | |||
1468 | !(pGroupRows->IsGroupEnd(nRow - 1))) | |||
1469 | ++nEqualRows; | |||
1470 | else | |||
1471 | { | |||
1472 | assert(nPrevIndex >= 0 && "coverity#1438402")(static_cast <bool> (nPrevIndex >= 0 && "coverity#1438402" ) ? void (0) : __assert_fail ("nPrevIndex >= 0 && \"coverity#1438402\"" , "/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" , 1472, __extension__ __PRETTY_FUNCTION__)); | |||
1473 | ScRowFormatRanges* pTempRowFormatRanges = new ScRowFormatRanges(pRowFormatRanges.get()); | |||
1474 | OpenAndCloseRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered); | |||
1475 | pRowFormatRanges.reset(pTempRowFormatRanges); | |||
1476 | nEqualRows = 1; | |||
1477 | nPrevIndex = nIndex; | |||
1478 | bPrevHidden = bHidden; | |||
1479 | bPrevFiltered = bFiltered; | |||
1480 | } | |||
1481 | } | |||
1482 | } | |||
1483 | assert(nPrevIndex >= 0 && "coverity#1438402")(static_cast <bool> (nPrevIndex >= 0 && "coverity#1438402" ) ? void (0) : __assert_fail ("nPrevIndex >= 0 && \"coverity#1438402\"" , "/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" , 1483, __extension__ __PRETTY_FUNCTION__)); | |||
1484 | OpenNewRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered); | |||
1485 | } | |||
1486 | else | |||
1487 | { | |||
1488 | sal_Int32 nIndex = pRowStyles->GetStyleNameIndex(nTable, nStartRow); | |||
1489 | bool bHidden = false; | |||
1490 | bool bFiltered = false; | |||
1491 | if (pDoc) | |||
1492 | { | |||
1493 | sal_Int32 nEndRowHidden; | |||
1494 | sal_Int32 nEndRowFiltered; | |||
1495 | bHidden = rRowAttr.rowHidden(nTable, nStartRow, nEndRowHidden); | |||
1496 | bFiltered = rRowAttr.rowFiltered(nTable, nStartRow, nEndRowFiltered); | |||
1497 | } | |||
1498 | assert(nIndex >= 0 && "coverity#1438402")(static_cast <bool> (nIndex >= 0 && "coverity#1438402" ) ? void (0) : __assert_fail ("nIndex >= 0 && \"coverity#1438402\"" , "/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" , 1498, __extension__ __PRETTY_FUNCTION__)); | |||
1499 | OpenNewRow(nIndex, nStartRow, 1, bHidden, bFiltered); | |||
1500 | } | |||
1501 | nOpenRow = nStartRow + nRepeatRow - 1; | |||
1502 | } | |||
1503 | ||||
1504 | void ScXMLExport::CloseRow(const sal_Int32 nRow) | |||
1505 | { | |||
1506 | if (nOpenRow > -1) | |||
1507 | { | |||
1508 | EndElement(sElemRow, true); | |||
1509 | if (bHasRowHeader && nRow == aRowHeaderRange.aEnd.Row()) | |||
1510 | { | |||
1511 | CloseHeaderRows(); | |||
1512 | bRowHeaderOpen = false; | |||
1513 | } | |||
1514 | if (pGroupRows->IsGroupEnd(nRow)) | |||
1515 | { | |||
1516 | if (bHasRowHeader && bRowHeaderOpen) | |||
1517 | CloseHeaderRows(); | |||
1518 | pGroupRows->CloseGroups(nRow); | |||
1519 | if (bHasRowHeader && bRowHeaderOpen) | |||
1520 | OpenHeaderRows(); | |||
1521 | } | |||
1522 | } | |||
1523 | nOpenRow = -1; | |||
1524 | } | |||
1525 | ||||
1526 | void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow, | |||
1527 | const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet) | |||
1528 | { | |||
1529 | pRowFormatRanges->Clear(); | |||
1530 | ScXMLCachedRowAttrAccess aRowAttr(pDoc); | |||
1531 | if (nStartRow == nEndRow) | |||
1532 | { | |||
1533 | pCellStyles->GetFormatRanges(nStartCol, nEndCol, nStartRow, nSheet, pRowFormatRanges.get()); | |||
1534 | if (nOpenRow == - 1) | |||
1535 | OpenRow(nSheet, nStartRow, 1, aRowAttr); | |||
1536 | WriteRowContent(); | |||
1537 | pRowFormatRanges->Clear(); | |||
1538 | } | |||
1539 | else | |||
1540 | { | |||
1541 | if (nOpenRow > -1) | |||
1542 | { | |||
1543 | pCellStyles->GetFormatRanges(nStartCol, pSharedData->GetLastColumn(nSheet), nStartRow, nSheet, pRowFormatRanges.get()); | |||
1544 | WriteRowContent(); | |||
1545 | CloseRow(nStartRow); | |||
1546 | sal_Int32 nRows(1); | |||
1547 | sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1); | |||
1548 | while (nRows < nTotalRows) | |||
1549 | { | |||
1550 | pRowFormatRanges->Clear(); | |||
1551 | pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges.get()); | |||
1552 | sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows(); | |||
1553 | OSL_ENSURE(nMaxRows, "something went wrong")do { if (true && (!(nMaxRows))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "1553" ": "), "%s", "something went wrong"); } } while ( false); | |||
1554 | if (nMaxRows >= nTotalRows - nRows) | |||
1555 | { | |||
1556 | OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows, aRowAttr); | |||
1557 | nRows += nTotalRows - nRows; | |||
1558 | } | |||
1559 | else | |||
1560 | { | |||
1561 | OpenRow(nSheet, nStartRow + nRows, nMaxRows, aRowAttr); | |||
1562 | nRows += nMaxRows; | |||
1563 | } | |||
1564 | if (!pRowFormatRanges->GetSize()) | |||
1565 | pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges.get()); | |||
1566 | WriteRowContent(); | |||
1567 | CloseRow(nStartRow + nRows - 1); | |||
1568 | } | |||
1569 | if (nTotalRows == 1) | |||
1570 | CloseRow(nStartRow); | |||
1571 | OpenRow(nSheet, nEndRow, 1, aRowAttr); | |||
1572 | pRowFormatRanges->Clear(); | |||
1573 | pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges.get()); | |||
1574 | WriteRowContent(); | |||
1575 | } | |||
1576 | else | |||
1577 | { | |||
1578 | sal_Int32 nRows(0); | |||
1579 | sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1); | |||
1580 | while (nRows < nTotalRows) | |||
1581 | { | |||
1582 | pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges.get()); | |||
1583 | sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows(); | |||
1584 | OSL_ENSURE(nMaxRows, "something went wrong")do { if (true && (!(nMaxRows))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "1584" ": "), "%s", "something went wrong"); } } while ( false); | |||
1585 | if (nMaxRows >= nTotalRows - nRows) | |||
1586 | { | |||
1587 | OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows, aRowAttr); | |||
1588 | nRows += nTotalRows - nRows; | |||
1589 | } | |||
1590 | else | |||
1591 | { | |||
1592 | OpenRow(nSheet, nStartRow + nRows, nMaxRows, aRowAttr); | |||
1593 | nRows += nMaxRows; | |||
1594 | } | |||
1595 | if (!pRowFormatRanges->GetSize()) | |||
1596 | pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges.get()); | |||
1597 | WriteRowContent(); | |||
1598 | CloseRow(nStartRow + nRows - 1); | |||
1599 | } | |||
1600 | OpenRow(nSheet, nEndRow, 1, aRowAttr); | |||
1601 | pRowFormatRanges->Clear(); | |||
1602 | pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges.get()); | |||
1603 | WriteRowContent(); | |||
1604 | } | |||
1605 | } | |||
1606 | } | |||
1607 | ||||
1608 | void ScXMLExport::GetColumnRowHeader(bool& rHasColumnHeader, ScRange& rColumnHeaderRange, | |||
1609 | bool& rHasRowHeader, ScRange& rRowHeaderRange, | |||
1610 | OUString& rPrintRanges) const | |||
1611 | { | |||
1612 | uno::Reference <sheet::XPrintAreas> xPrintAreas (xCurrentTable, uno::UNO_QUERY); | |||
1613 | if (!xPrintAreas.is()) | |||
1614 | return; | |||
1615 | ||||
1616 | rHasRowHeader = xPrintAreas->getPrintTitleRows(); | |||
1617 | rHasColumnHeader = xPrintAreas->getPrintTitleColumns(); | |||
1618 | table::CellRangeAddress rTempRowHeaderRange = xPrintAreas->getTitleRows(); | |||
1619 | rRowHeaderRange = ScRange(rTempRowHeaderRange.StartColumn, | |||
1620 | rTempRowHeaderRange.StartRow, | |||
1621 | rTempRowHeaderRange.Sheet, | |||
1622 | rTempRowHeaderRange.EndColumn, | |||
1623 | rTempRowHeaderRange.EndRow, | |||
1624 | rTempRowHeaderRange.Sheet); | |||
1625 | table::CellRangeAddress rTempColumnHeaderRange = xPrintAreas->getTitleColumns(); | |||
1626 | rColumnHeaderRange = ScRange(rTempColumnHeaderRange.StartColumn, | |||
1627 | rTempColumnHeaderRange.StartRow, | |||
1628 | rTempColumnHeaderRange.Sheet, | |||
1629 | rTempColumnHeaderRange.EndColumn, | |||
1630 | rTempColumnHeaderRange.EndRow, | |||
1631 | rTempColumnHeaderRange.Sheet); | |||
1632 | uno::Sequence< table::CellRangeAddress > aRangeList( xPrintAreas->getPrintAreas() ); | |||
1633 | ScRangeStringConverter::GetStringFromRangeList( rPrintRanges, aRangeList, pDoc, FormulaGrammar::CONV_OOO ); | |||
1634 | } | |||
1635 | ||||
1636 | void ScXMLExport::FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups) | |||
1637 | { | |||
1638 | size_t nDepth = pFields->GetDepth(); | |||
1639 | for (size_t i = 0; i < nDepth; ++i) | |||
1640 | { | |||
1641 | size_t nFields = pFields->GetCount(i); | |||
1642 | for (size_t j = 0; j < nFields; ++j) | |||
1643 | { | |||
1644 | ScMyColumnRowGroup aGroup; | |||
1645 | const ScOutlineEntry* pEntry = pFields->GetEntry(i, j); | |||
1646 | aGroup.nField = pEntry->GetStart(); | |||
1647 | aGroup.nLevel = static_cast<sal_Int16>(i); | |||
1648 | aGroup.bDisplay = !(pEntry->IsHidden()); | |||
1649 | pGroups->AddGroup(aGroup, pEntry->GetEnd()); | |||
1650 | } | |||
1651 | } | |||
1652 | if (nDepth) | |||
1653 | pGroups->Sort(); | |||
1654 | } | |||
1655 | ||||
1656 | void ScXMLExport::FillColumnRowGroups() | |||
1657 | { | |||
1658 | if (!pDoc) | |||
1659 | return; | |||
1660 | ||||
1661 | ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable( static_cast<SCTAB>(nCurrentTable) ); | |||
1662 | if(pOutlineTable) | |||
1663 | { | |||
1664 | ScOutlineArray& rCols(pOutlineTable->GetColArray()); | |||
1665 | ScOutlineArray& rRows(pOutlineTable->GetRowArray()); | |||
1666 | FillFieldGroup(&rCols, pGroupColumns.get()); | |||
1667 | FillFieldGroup(&rRows, pGroupRows.get()); | |||
1668 | pSharedData->SetLastColumn(nCurrentTable, pGroupColumns->GetLast()); | |||
1669 | pSharedData->SetLastRow(nCurrentTable, pGroupRows->GetLast()); | |||
1670 | } | |||
1671 | } | |||
1672 | ||||
1673 | void ScXMLExport::SetBodyAttributes() | |||
1674 | { | |||
1675 | if (!(pDoc && pDoc->IsDocProtected())) | |||
1676 | return; | |||
1677 | ||||
1678 | AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE); | |||
1679 | OUStringBuffer aBuffer; | |||
1680 | uno::Sequence<sal_Int8> aPassHash; | |||
1681 | ScPasswordHash eHashUsed = PASSHASH_UNSPECIFIED; | |||
1682 | const ScDocProtection* p = pDoc->GetDocProtection(); | |||
1683 | if (p) | |||
1684 | { | |||
1685 | if (p->hasPasswordHash(PASSHASH_SHA1)) | |||
1686 | { | |||
1687 | aPassHash = p->getPasswordHash(PASSHASH_SHA1); | |||
1688 | eHashUsed = PASSHASH_SHA1; | |||
1689 | } | |||
1690 | else if (p->hasPasswordHash(PASSHASH_SHA256)) | |||
1691 | { | |||
1692 | aPassHash = p->getPasswordHash(PASSHASH_SHA256); | |||
1693 | eHashUsed = PASSHASH_SHA256; | |||
1694 | } | |||
1695 | else if (p->hasPasswordHash(PASSHASH_XL, PASSHASH_SHA1)) | |||
1696 | { | |||
1697 | aPassHash = p->getPasswordHash(PASSHASH_XL, PASSHASH_SHA1); | |||
1698 | eHashUsed = PASSHASH_XL; | |||
1699 | } | |||
1700 | } | |||
1701 | ::comphelper::Base64::encode(aBuffer, aPassHash); | |||
1702 | if (aBuffer.isEmpty()) | |||
1703 | return; | |||
1704 | ||||
1705 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); | |||
1706 | if (getSaneDefaultVersion() < SvtSaveOptions::ODFSVER_012) | |||
1707 | return; | |||
1708 | ||||
1709 | if (eHashUsed == PASSHASH_XL) | |||
1710 | { | |||
1711 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, | |||
1712 | ScPassHashHelper::getHashURI(PASSHASH_XL)); | |||
1713 | if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
1714 | AddAttribute(XML_NAMESPACE_LO_EXT, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2, | |||
1715 | ScPassHashHelper::getHashURI(PASSHASH_SHA1)); | |||
1716 | } | |||
1717 | else if (eHashUsed == PASSHASH_SHA1) | |||
1718 | { | |||
1719 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, | |||
1720 | ScPassHashHelper::getHashURI(PASSHASH_SHA1)); | |||
1721 | } | |||
1722 | else if (eHashUsed == PASSHASH_SHA256) | |||
1723 | { | |||
1724 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, | |||
1725 | ScPassHashHelper::getHashURI(PASSHASH_SHA256)); | |||
1726 | } | |||
1727 | } | |||
1728 | ||||
1729 | static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput, | |||
1730 | const uno::Reference< io::XOutputStream >& xOutput, | |||
1731 | sal_Int32 nCount ) | |||
1732 | { | |||
1733 | const sal_Int32 nBufSize = 16*1024; | |||
1734 | uno::Sequence<sal_Int8> aSequence(nBufSize); | |||
1735 | ||||
1736 | sal_Int32 nRemaining = nCount; | |||
1737 | bool bFirst = true; | |||
1738 | ||||
1739 | while ( nRemaining > 0 ) | |||
1740 | { | |||
1741 | sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) ); | |||
1742 | if (bFirst) | |||
1743 | { | |||
1744 | // safety check: Make sure the copied part actually points to the start of an element | |||
1745 | if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') ) | |||
1746 | { | |||
1747 | return false; // abort and set an error | |||
1748 | } | |||
1749 | bFirst = false; | |||
1750 | } | |||
1751 | if (nRead == nRemaining) | |||
1752 | { | |||
1753 | // safety check: Make sure the copied part also ends at the end of an element | |||
1754 | if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') ) | |||
1755 | { | |||
1756 | return false; // abort and set an error | |||
1757 | } | |||
1758 | } | |||
1759 | ||||
1760 | if ( nRead == nBufSize ) | |||
1761 | { | |||
1762 | xOutput->writeBytes( aSequence ); | |||
1763 | nRemaining -= nRead; | |||
1764 | } | |||
1765 | else | |||
1766 | { | |||
1767 | if ( nRead > 0 ) | |||
1768 | { | |||
1769 | uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead ); | |||
1770 | xOutput->writeBytes( aTempBuf ); | |||
1771 | } | |||
1772 | nRemaining = 0; | |||
1773 | } | |||
1774 | } | |||
1775 | return true; // successful | |||
1776 | } | |||
1777 | ||||
1778 | static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip ) | |||
1779 | { | |||
1780 | // skipBytes in zip stream is implemented as reading. | |||
1781 | // For now, split into several calls to avoid allocating a large buffer. | |||
1782 | // Later, skipBytes should be changed. | |||
1783 | ||||
1784 | const sal_Int32 nMaxSize = 32*1024; | |||
1785 | ||||
1786 | if ( nBytesToSkip > 0 ) | |||
1787 | { | |||
1788 | sal_Int32 nRemaining = nBytesToSkip; | |||
1789 | while ( nRemaining > 0 ) | |||
1790 | { | |||
1791 | sal_Int32 nSkip = std::min( nRemaining, nMaxSize ); | |||
1792 | xInput->skipBytes( nSkip ); | |||
1793 | nRemaining -= nSkip; | |||
1794 | } | |||
1795 | } | |||
1796 | } | |||
1797 | ||||
1798 | void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd ) | |||
1799 | { | |||
1800 | uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler(); | |||
1801 | uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY ); | |||
1802 | if ( !xDestSource.is() ) | |||
1803 | return; | |||
1804 | ||||
1805 | uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream(); | |||
1806 | uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY ); | |||
1807 | if ( !xDestSeek.is() ) | |||
1808 | return; | |||
1809 | ||||
1810 | // temporary: set same stream again to clear buffer | |||
1811 | xDestSource->setOutputStream( xDestStream ); | |||
1812 | ||||
1813 | if ( getExportFlags() & SvXMLExportFlags::PRETTY ) | |||
1814 | { | |||
1815 | const OString aOutStr("\n "); | |||
1816 | uno::Sequence<sal_Int8> aOutSeq( reinterpret_cast<sal_Int8 const *>(aOutStr.getStr()), aOutStr.getLength() ); | |||
1817 | xDestStream->writeBytes( aOutSeq ); | |||
1818 | } | |||
1819 | ||||
1820 | rNewStart = static_cast<sal_Int32>(xDestSeek->getPosition()); | |||
1821 | ||||
1822 | if ( nStartOffset > nSourceStreamPos ) | |||
1823 | lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos ); | |||
1824 | ||||
1825 | if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) ) | |||
1826 | { | |||
1827 | // If copying went wrong, set an error. | |||
1828 | // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving. | |||
1829 | ||||
1830 | uno::Sequence<OUString> aEmptySeq; | |||
1831 | SetError(XMLERROR_CANCEL( 0x00080000 | 0x00000001 )|XMLERROR_FLAG_SEVERE0x40000000, aEmptySeq); | |||
1832 | } | |||
1833 | nSourceStreamPos = nEndOffset; | |||
1834 | ||||
1835 | rNewEnd = static_cast<sal_Int32>(xDestSeek->getPosition()); | |||
1836 | } | |||
1837 | ||||
1838 | const ScXMLEditAttributeMap& ScXMLExport::GetEditAttributeMap() const | |||
1839 | { | |||
1840 | if (!mpEditAttrMap) | |||
1841 | mpEditAttrMap.reset(new ScXMLEditAttributeMap); | |||
1842 | return *mpEditAttrMap; | |||
1843 | } | |||
1844 | ||||
1845 | void ScXMLExport::RegisterDefinedStyleNames( const uno::Reference< css::sheet::XSpreadsheetDocument > & xSpreadDoc ) | |||
1846 | { | |||
1847 | ScFormatSaveData* pFormatData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetFormatSaveData(); | |||
1848 | auto xAutoStylePool = GetAutoStylePool(); | |||
1849 | for (const auto& rFormatInfo : pFormatData->maIDToName) | |||
1850 | { | |||
1851 | xAutoStylePool->RegisterDefinedName(XmlStyleFamily::TABLE_CELL, rFormatInfo.second); | |||
1852 | } | |||
1853 | } | |||
1854 | ||||
1855 | void ScXMLExport::ExportContent_() | |||
1856 | { | |||
1857 | nCurrentTable = 0; | |||
1858 | if (!pSharedData) | |||
1859 | { | |||
1860 | SCTAB nTableCount(0); | |||
1861 | sal_Int32 nShapesCount(0); | |||
1862 | CollectSharedData(nTableCount, nShapesCount); | |||
1863 | OSL_FAIL("no shared data set")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "1863" ": "), "%s", "no shared data set"); } } while (false ); | |||
1864 | if (!pSharedData) | |||
1865 | return; | |||
1866 | } | |||
1867 | ScXMLExportDatabaseRanges aExportDatabaseRanges(*this); | |||
1868 | if (!GetModel().is()) | |||
1869 | return; | |||
1870 | ||||
1871 | uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); | |||
1872 | if ( !xSpreadDoc.is() ) | |||
1873 | return; | |||
1874 | ||||
1875 | ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetSheetSaveData(); | |||
1876 | if (pSheetData) | |||
1877 | pSheetData->ResetSaveEntries(); | |||
1878 | ||||
1879 | uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); | |||
1880 | if ( xIndex.is() ) | |||
1881 | { | |||
1882 | //_GetNamespaceMap().ClearQNamesCache(); | |||
1883 | pChangeTrackingExportHelper->CollectAndWriteChanges(); | |||
1884 | WriteCalculationSettings(xSpreadDoc); | |||
1885 | sal_Int32 nTableCount(xIndex->getCount()); | |||
1886 | ScMyAreaLinksContainer aAreaLinks; | |||
1887 | GetAreaLinks( aAreaLinks ); | |||
1888 | ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges()); | |||
1889 | ScMyDetectiveOpContainer aDetectiveOpContainer; | |||
1890 | GetDetectiveOpList( aDetectiveOpContainer ); | |||
1891 | ||||
1892 | pCellStyles->Sort(); | |||
1893 | pMergedRangesContainer->Sort(); | |||
1894 | pSharedData->GetDetectiveObjContainer()->Sort(); | |||
1895 | ||||
1896 | mpCellsItr->Clear(); | |||
1897 | mpCellsItr->SetShapes( pSharedData->GetShapesContainer() ); | |||
1898 | mpCellsItr->SetNoteShapes( pSharedData->GetNoteShapes() ); | |||
1899 | mpCellsItr->SetMergedRanges( pMergedRangesContainer.get() ); | |||
1900 | mpCellsItr->SetAreaLinks( &aAreaLinks ); | |||
1901 | mpCellsItr->SetEmptyDatabaseRanges( &aEmptyRanges ); | |||
1902 | mpCellsItr->SetDetectiveObj( pSharedData->GetDetectiveObjContainer() ); | |||
1903 | mpCellsItr->SetDetectiveOp( &aDetectiveOpContainer ); | |||
1904 | ||||
1905 | if (nTableCount > 0) | |||
1906 | pValidationsContainer->WriteValidations(*this); | |||
1907 | WriteTheLabelRanges( xSpreadDoc ); | |||
1908 | for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable) | |||
1909 | { | |||
1910 | sal_Int32 nStartOffset = -1; | |||
1911 | sal_Int32 nEndOffset = -1; | |||
1912 | if (pSheetData && pDoc && pDoc->IsStreamValid(static_cast<SCTAB>(nTable)) && !pDoc->GetChangeTrack()) | |||
1913 | pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset ); | |||
1914 | ||||
1915 | if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() ) | |||
1916 | { | |||
1917 | sal_Int32 nNewStart = -1; | |||
1918 | sal_Int32 nNewEnd = -1; | |||
1919 | CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd ); | |||
1920 | ||||
1921 | // store position of copied sheet in output | |||
1922 | pSheetData->AddSavePos( nTable, nNewStart, nNewEnd ); | |||
1923 | ||||
1924 | // skip iterator entries for this sheet | |||
1925 | mpCellsItr->SkipTable(static_cast<SCTAB>(nTable)); | |||
1926 | } | |||
1927 | else | |||
1928 | { | |||
1929 | uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); | |||
1930 | WriteTable(nTable, xTable); | |||
1931 | } | |||
1932 | IncrementProgressBar(false); | |||
1933 | } | |||
1934 | } | |||
1935 | WriteExternalRefCaches(); | |||
1936 | WriteNamedExpressions(); | |||
1937 | WriteDataStream(); | |||
1938 | aExportDatabaseRanges.WriteDatabaseRanges(); | |||
1939 | WriteExternalDataMapping(); | |||
1940 | ScXMLExportDataPilot aExportDataPilot(*this); | |||
1941 | aExportDataPilot.WriteDataPilots(); | |||
1942 | WriteConsolidation(); | |||
1943 | ScXMLExportDDELinks aExportDDELinks(*this); | |||
1944 | aExportDDELinks.WriteDDELinks(xSpreadDoc); | |||
1945 | IncrementProgressBar(true, 0); | |||
1946 | GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference()); | |||
1947 | } | |||
1948 | ||||
1949 | void ScXMLExport::ExportStyles_( bool bUsed ) | |||
1950 | { | |||
1951 | uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); | |||
1952 | if (xSpreadDoc.is()) | |||
1953 | RegisterDefinedStyleNames( xSpreadDoc); | |||
1954 | ||||
1955 | if (!pSharedData) | |||
1956 | { | |||
1957 | SCTAB nTableCount(0); | |||
1958 | sal_Int32 nShapesCount(0); | |||
1959 | CollectSharedData(nTableCount, nShapesCount); | |||
1960 | } | |||
1961 | rtl::Reference<XMLCellStyleExport> aStylesExp(new XMLCellStyleExport(*this, GetAutoStylePool().get())); | |||
1962 | if (GetModel().is()) | |||
1963 | { | |||
1964 | uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); | |||
1965 | if (xMultiServiceFactory.is()) | |||
1966 | { | |||
1967 | uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance("com.sun.star.sheet.Defaults"), uno::UNO_QUERY); | |||
1968 | if (xProperties.is()) | |||
1969 | aStylesExp->exportDefaultStyle(xProperties, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME"table-cell", xCellStylesExportPropertySetMapper); | |||
1970 | if (pSharedData->HasShapes()) | |||
1971 | { | |||
1972 | GetShapeExport()->ExportGraphicDefaults(); | |||
1973 | } | |||
1974 | } | |||
1975 | collectDataStyles(false); | |||
1976 | } | |||
1977 | exportDataStyles(); | |||
1978 | ||||
1979 | aStylesExp->exportStyleFamily(OUString("CellStyles"), | |||
1980 | OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME"table-cell"), xCellStylesExportPropertySetMapper, false, XmlStyleFamily::TABLE_CELL); | |||
1981 | ||||
1982 | SvXMLExport::ExportStyles_(bUsed); | |||
1983 | } | |||
1984 | ||||
1985 | void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties, | |||
1986 | const uno::Reference<sheet::XSpreadsheet>& xTable, | |||
1987 | sal_Int32 nTable, const OUString* pOldName) | |||
1988 | { | |||
1989 | css::uno::Any aAny = xProperties->getPropertyValue("FormatID"); | |||
1990 | sal_uInt64 nKey = 0; | |||
1991 | aAny >>= nKey; | |||
1992 | ||||
1993 | //! pass xCellRanges instead | |||
1994 | uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY ); | |||
1995 | ||||
1996 | OUString sStyleName; | |||
1997 | sal_Int32 nNumberFormat(-1); | |||
1998 | sal_Int32 nValidationIndex(-1); | |||
1999 | std::vector< XMLPropertyState > aPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties )); | |||
2000 | std::vector< XMLPropertyState >::iterator aItr(aPropStates.begin()); | |||
2001 | std::vector< XMLPropertyState >::iterator aEndItr(aPropStates.end()); | |||
2002 | sal_Int32 nCount(0); | |||
2003 | while (aItr != aEndItr) | |||
2004 | { | |||
2005 | if (aItr->mnIndex != -1) | |||
2006 | { | |||
2007 | switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex)) | |||
2008 | { | |||
2009 | case CTF_SC_VALIDATION(0x00001000 + 24) : | |||
2010 | { | |||
2011 | pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex); | |||
2012 | // this is not very slow, because it is most the last property or | |||
2013 | // if it is not the last property it is the property before the last property, | |||
2014 | // so in the worst case only one property has to be copied, but in the best case no | |||
2015 | // property has to be copied | |||
2016 | aItr = aPropStates.erase(aItr); | |||
2017 | aEndItr = aPropStates.end(); // old aEndItr is invalidated! | |||
2018 | } | |||
2019 | break; | |||
2020 | case CTF_SC_CELLSTYLE(0x00001000 + 23) : | |||
2021 | { | |||
2022 | aItr->maValue >>= sStyleName; | |||
2023 | aItr->mnIndex = -1; | |||
2024 | ++aItr; | |||
2025 | ++nCount; | |||
2026 | } | |||
2027 | break; | |||
2028 | case CTF_SC_NUMBERFORMAT(0x00001000 + 18) : | |||
2029 | { | |||
2030 | if (aItr->maValue >>= nNumberFormat) | |||
2031 | addDataStyle(nNumberFormat); | |||
2032 | ++aItr; | |||
2033 | ++nCount; | |||
2034 | } | |||
2035 | break; | |||
2036 | default: | |||
2037 | { | |||
2038 | ++aItr; | |||
2039 | ++nCount; | |||
2040 | } | |||
2041 | break; | |||
2042 | } | |||
2043 | } | |||
2044 | else | |||
2045 | { | |||
2046 | ++aItr; | |||
2047 | ++nCount; | |||
2048 | } | |||
2049 | } | |||
2050 | if (nCount == 1) // this is the CellStyle and should be removed if alone | |||
2051 | aPropStates.clear(); | |||
2052 | if (nNumberFormat == -1) | |||
2053 | xProperties->getPropertyValue(SC_UNONAME_NUMFMT"NumberFormat") >>= nNumberFormat; | |||
2054 | if (sStyleName.isEmpty()) | |||
2055 | return; | |||
2056 | ||||
2057 | if (!aPropStates.empty()) | |||
2058 | { | |||
2059 | sal_Int32 nIndex; | |||
2060 | if (pOldName) | |||
2061 | { | |||
2062 | if (GetAutoStylePool()->AddNamed(*pOldName, XmlStyleFamily::TABLE_CELL, sStyleName, aPropStates)) | |||
2063 | { | |||
2064 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_CELL, *pOldName); | |||
2065 | // add to pCellStyles, so the name is found for normal sheets | |||
2066 | pCellStyles->AddStyleName(*pOldName, nIndex); | |||
2067 | } | |||
2068 | } | |||
2069 | else | |||
2070 | { | |||
2071 | OUString sName; | |||
2072 | bool bAdded = false; | |||
2073 | if (nKey) | |||
2074 | { | |||
2075 | uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); | |||
2076 | ScFormatSaveData* pFormatData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetFormatSaveData(); | |||
2077 | auto itr = pFormatData->maIDToName.find(nKey); | |||
2078 | if (itr != pFormatData->maIDToName.end()) | |||
2079 | { | |||
2080 | sName = itr->second; | |||
2081 | bAdded = GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TABLE_CELL, sStyleName, aPropStates); | |||
2082 | if (bAdded) | |||
2083 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_CELL, sName); | |||
2084 | } | |||
2085 | } | |||
2086 | bool bIsAutoStyle(true); | |||
2087 | if (bAdded || GetAutoStylePool()->Add(sName, XmlStyleFamily::TABLE_CELL, sStyleName, aPropStates)) | |||
2088 | { | |||
2089 | pCellStyles->AddStyleName(sName, nIndex); | |||
2090 | } | |||
2091 | else | |||
2092 | nIndex = pCellStyles->GetIndexOfStyleName(sName, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX"ce", bIsAutoStyle); | |||
2093 | ||||
2094 | const uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses()); | |||
2095 | bool bGetMerge(true); | |||
2096 | for (table::CellRangeAddress const & address : aAddresses) | |||
2097 | { | |||
2098 | pSharedData->SetLastColumn(nTable, address.EndColumn); | |||
2099 | pSharedData->SetLastRow(nTable, address.EndRow); | |||
2100 | pCellStyles->AddRangeStyleName(address, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat); | |||
2101 | if (bGetMerge) | |||
2102 | bGetMerge = GetMerged(&address, xTable); | |||
2103 | } | |||
2104 | } | |||
2105 | } | |||
2106 | else | |||
2107 | { | |||
2108 | OUString sEncodedStyleName(EncodeStyleName(sStyleName)); | |||
2109 | sal_Int32 nIndex(0); | |||
2110 | pCellStyles->AddStyleName(sEncodedStyleName, nIndex, false); | |||
2111 | if ( !pOldName ) | |||
2112 | { | |||
2113 | const uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses()); | |||
2114 | bool bGetMerge(true); | |||
2115 | for (table::CellRangeAddress const & address : aAddresses) | |||
2116 | { | |||
2117 | if (bGetMerge) | |||
2118 | bGetMerge = GetMerged(&address, xTable); | |||
2119 | pCellStyles->AddRangeStyleName(address, nIndex, false, nValidationIndex, nNumberFormat); | |||
2120 | if( sStyleName != "Default" || nValidationIndex != -1 ) | |||
2121 | { | |||
2122 | pSharedData->SetLastColumn(nTable, address.EndColumn); | |||
2123 | pSharedData->SetLastRow(nTable, address.EndRow); | |||
2124 | } | |||
2125 | } | |||
2126 | } | |||
2127 | } | |||
2128 | } | |||
2129 | ||||
2130 | void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties, | |||
2131 | const OUString* pOldName, sal_Int32& rIndex, bool& rIsVisible) | |||
2132 | { | |||
2133 | std::vector<XMLPropertyState> aPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties)); | |||
2134 | if(aPropStates.empty()) | |||
2135 | return; | |||
2136 | ||||
2137 | auto aItr = std::find_if(aPropStates.begin(), aPropStates.end(), | |||
2138 | [this](const XMLPropertyState& rPropState) { | |||
2139 | return xColumnStylesPropertySetMapper->GetEntryContextId(rPropState.mnIndex) == CTF_SC_ISVISIBLE(0x00001000 + 53); }); | |||
2140 | if (aItr != aPropStates.end()) | |||
2141 | { | |||
2142 | aItr->maValue >>= rIsVisible; | |||
2143 | } | |||
2144 | ||||
2145 | const OUString sParent; | |||
2146 | if (pOldName) | |||
2147 | { | |||
2148 | if (GetAutoStylePool()->AddNamed(*pOldName, XmlStyleFamily::TABLE_COLUMN, sParent, aPropStates)) | |||
2149 | { | |||
2150 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_COLUMN, *pOldName); | |||
2151 | // add to pColumnStyles, so the name is found for normal sheets | |||
2152 | rIndex = pColumnStyles->AddStyleName(*pOldName); | |||
2153 | } | |||
2154 | } | |||
2155 | else | |||
2156 | { | |||
2157 | OUString sName; | |||
2158 | if (GetAutoStylePool()->Add(sName, XmlStyleFamily::TABLE_COLUMN, sParent, aPropStates)) | |||
2159 | { | |||
2160 | rIndex = pColumnStyles->AddStyleName(sName); | |||
2161 | } | |||
2162 | else | |||
2163 | rIndex = pColumnStyles->GetIndexOfStyleName(sName, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX"co"); | |||
2164 | } | |||
2165 | } | |||
2166 | ||||
2167 | void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties, | |||
2168 | const OUString* pOldName, sal_Int32& rIndex) | |||
2169 | { | |||
2170 | std::vector<XMLPropertyState> aPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties)); | |||
2171 | if(aPropStates.empty()) | |||
2172 | return; | |||
2173 | ||||
2174 | const OUString sParent; | |||
2175 | if (pOldName) | |||
2176 | { | |||
2177 | if (GetAutoStylePool()->AddNamed(*pOldName, XmlStyleFamily::TABLE_ROW, sParent, aPropStates)) | |||
2178 | { | |||
2179 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_ROW, *pOldName); | |||
2180 | // add to pRowStyles, so the name is found for normal sheets | |||
2181 | rIndex = pRowStyles->AddStyleName(*pOldName); | |||
2182 | } | |||
2183 | } | |||
2184 | else | |||
2185 | { | |||
2186 | OUString sName; | |||
2187 | if (GetAutoStylePool()->Add(sName, XmlStyleFamily::TABLE_ROW, sParent, aPropStates)) | |||
2188 | { | |||
2189 | rIndex = pRowStyles->AddStyleName(sName); | |||
2190 | } | |||
2191 | else | |||
2192 | rIndex = pRowStyles->GetIndexOfStyleName(sName, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX"ro"); | |||
2193 | } | |||
2194 | } | |||
2195 | ||||
2196 | static uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> const & xEnumAccess, sal_Int32 nIndex ) | |||
2197 | { | |||
2198 | uno::Any aRet; | |||
2199 | uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() ); | |||
2200 | try | |||
2201 | { | |||
2202 | sal_Int32 nSkip = nIndex; | |||
2203 | while ( nSkip > 0 ) | |||
2204 | { | |||
2205 | (void) xEnum->nextElement(); | |||
2206 | --nSkip; | |||
2207 | } | |||
2208 | aRet = xEnum->nextElement(); | |||
2209 | } | |||
2210 | catch (container::NoSuchElementException&) | |||
2211 | { | |||
2212 | // leave aRet empty | |||
2213 | } | |||
2214 | return aRet; | |||
2215 | } | |||
2216 | ||||
2217 | void ScXMLExport::collectAutoStyles() | |||
2218 | { | |||
2219 | SvXMLExport::collectAutoStyles(); | |||
2220 | ||||
2221 | if (mbAutoStylesCollected) | |||
| ||||
2222 | return; | |||
2223 | ||||
2224 | if (!GetModel().is()) | |||
2225 | return; | |||
2226 | ||||
2227 | uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); | |||
2228 | if (!xSpreadDoc.is()) | |||
2229 | return; | |||
2230 | ||||
2231 | uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); | |||
2232 | if (!xIndex.is()) | |||
2233 | return; | |||
2234 | ||||
2235 | if (getExportFlags() & SvXMLExportFlags::CONTENT) | |||
2236 | { | |||
2237 | // Reserve the loaded cell style names. | |||
2238 | RegisterDefinedStyleNames( xSpreadDoc); | |||
2239 | ||||
2240 | // re-create automatic styles with old names from stored data | |||
2241 | ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetSheetSaveData(); | |||
2242 | if (pSheetData && pDoc) | |||
2243 | { | |||
2244 | // formulas have to be calculated now, to detect changed results | |||
2245 | // (during normal save, they will be calculated anyway) | |||
2246 | SCTAB nTabCount = pDoc->GetTableCount(); | |||
2247 | for (SCTAB nTab=0; nTab<nTabCount; ++nTab) | |||
2248 | if (pDoc->IsStreamValid(nTab)) | |||
2249 | pDoc->InterpretDirtyCells(ScRange(0, 0, nTab, pDoc->MaxCol(), pDoc->MaxRow(), nTab)); | |||
2250 | ||||
2251 | // stored cell styles | |||
2252 | const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles(); | |||
2253 | for (const auto& rCellEntry : rCellEntries) | |||
2254 | { | |||
2255 | ScAddress aPos = rCellEntry.maCellPos; | |||
2256 | sal_Int32 nTable = aPos.Tab(); | |||
2257 | bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); | |||
2258 | if (bCopySheet) | |||
2259 | { | |||
2260 | uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); | |||
2261 | uno::Reference <beans::XPropertySet> xProperties( | |||
2262 | xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY ); | |||
2263 | ||||
2264 | AddStyleFromCells(xProperties, xTable, nTable, &rCellEntry.maName); | |||
2265 | } | |||
2266 | } | |||
2267 | ||||
2268 | // stored column styles | |||
2269 | const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles(); | |||
2270 | for (const auto& rColumnEntry : rColumnEntries) | |||
2271 | { | |||
2272 | ScAddress aPos = rColumnEntry.maCellPos; | |||
2273 | sal_Int32 nTable = aPos.Tab(); | |||
2274 | bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); | |||
2275 | if (bCopySheet) | |||
2276 | { | |||
2277 | uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); | |||
2278 | uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); | |||
2279 | uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY); | |||
2280 | ||||
2281 | sal_Int32 nIndex(-1); | |||
2282 | bool bIsVisible(true); | |||
2283 | AddStyleFromColumn( xColumnProperties, &rColumnEntry.maName, nIndex, bIsVisible ); | |||
2284 | } | |||
2285 | } | |||
2286 | ||||
2287 | // stored row styles | |||
2288 | const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles(); | |||
2289 | for (const auto& rRowEntry : rRowEntries) | |||
2290 | { | |||
2291 | ScAddress aPos = rRowEntry.maCellPos; | |||
2292 | sal_Int32 nTable = aPos.Tab(); | |||
2293 | bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); | |||
2294 | if (bCopySheet) | |||
2295 | { | |||
2296 | uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); | |||
2297 | uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); | |||
2298 | uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY); | |||
2299 | ||||
2300 | sal_Int32 nIndex(-1); | |||
2301 | AddStyleFromRow( xRowProperties, &rRowEntry.maName, nIndex ); | |||
2302 | } | |||
2303 | } | |||
2304 | ||||
2305 | // stored table styles | |||
2306 | const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles(); | |||
2307 | for (const auto& rTableEntry : rTableEntries) | |||
2308 | { | |||
2309 | ScAddress aPos = rTableEntry.maCellPos; | |||
2310 | sal_Int32 nTable = aPos.Tab(); | |||
2311 | bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); | |||
2312 | if (bCopySheet) | |||
2313 | { | |||
2314 | //! separate method AddStyleFromTable needed? | |||
2315 | uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY); | |||
2316 | if (xTableProperties.is()) | |||
2317 | { | |||
2318 | std::vector<XMLPropertyState> aPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); | |||
2319 | OUString sName( rTableEntry.maName ); | |||
2320 | GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TABLE_TABLE, OUString(), aPropStates); | |||
2321 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE, sName); | |||
2322 | } | |||
2323 | } | |||
2324 | } | |||
2325 | ||||
2326 | // stored styles for notes | |||
2327 | ||||
2328 | rtl::Reference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this ); | |||
2329 | GetShapeExport(); // make sure the graphics styles family is added | |||
2330 | ||||
2331 | const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles(); | |||
2332 | for (const auto& rNoteEntry : rNoteEntries) | |||
2333 | { | |||
2334 | ScAddress aPos = rNoteEntry.maCellPos; | |||
2335 | SCTAB nTable = aPos.Tab(); | |||
2336 | bool bCopySheet = pDoc->IsStreamValid( nTable ); | |||
2337 | if (bCopySheet) | |||
2338 | { | |||
2339 | //! separate method AddStyleFromNote needed? | |||
2340 | ||||
2341 | ScPostIt* pNote = pDoc->GetNote(aPos); | |||
2342 | OSL_ENSURE( pNote, "note not found" )do { if (true && (!(pNote))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "2342" ": "), "%s", "note not found"); } } while (false); | |||
2343 | if (pNote) | |||
2344 | { | |||
2345 | SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); | |||
2346 | // all uno shapes are created anyway in CollectSharedData | |||
2347 | uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY ); | |||
2348 | if (xShapeProperties.is()) | |||
2349 | { | |||
2350 | if ( !rNoteEntry.maStyleName.isEmpty() ) | |||
2351 | { | |||
2352 | std::vector<XMLPropertyState> aPropStates(xShapeMapper->Filter(xShapeProperties)); | |||
2353 | OUString sName( rNoteEntry.maStyleName ); | |||
2354 | GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::SD_GRAPHICS_ID, OUString(), aPropStates); | |||
2355 | GetAutoStylePool()->RegisterName(XmlStyleFamily::SD_GRAPHICS_ID, sName); | |||
2356 | } | |||
2357 | if ( !rNoteEntry.maTextStyle.isEmpty() ) | |||
2358 | { | |||
2359 | std::vector<XMLPropertyState> aPropStates( | |||
2360 | GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties)); | |||
2361 | OUString sName( rNoteEntry.maTextStyle ); | |||
2362 | GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TEXT_PARAGRAPH, OUString(), aPropStates); | |||
2363 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH, sName); | |||
2364 | } | |||
2365 | } | |||
2366 | } | |||
2367 | } | |||
2368 | } | |||
2369 | ||||
2370 | // note paragraph styles | |||
2371 | ||||
2372 | rtl::Reference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper(); | |||
2373 | ||||
2374 | const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles(); | |||
2375 | for (const auto& rNoteParaEntry : rNoteParaEntries) | |||
2376 | { | |||
2377 | ScAddress aPos = rNoteParaEntry.maCellPos; | |||
2378 | SCTAB nTable = aPos.Tab(); | |||
2379 | bool bCopySheet = pDoc->IsStreamValid( nTable ); | |||
2380 | if (bCopySheet) | |||
2381 | { | |||
2382 | ScPostIt* pNote = pDoc->GetNote( aPos ); | |||
2383 | OSL_ENSURE( pNote, "note not found" )do { if (true && (!(pNote))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "2383" ": "), "%s", "note not found"); } } while (false); | |||
2384 | if (pNote) | |||
2385 | { | |||
2386 | SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); | |||
2387 | uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); | |||
2388 | uno::Reference<beans::XPropertySet> xParaProp( | |||
2389 | lcl_GetEnumerated( xCellText, rNoteParaEntry.maSelection.nStartPara ), uno::UNO_QUERY ); | |||
2390 | if ( xParaProp.is() ) | |||
2391 | { | |||
2392 | std::vector<XMLPropertyState> aPropStates(xParaPropMapper->Filter(xParaProp)); | |||
2393 | OUString sName( rNoteParaEntry.maName ); | |||
2394 | GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TEXT_PARAGRAPH, OUString(), aPropStates); | |||
2395 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH, sName); | |||
2396 | } | |||
2397 | } | |||
2398 | } | |||
2399 | } | |||
2400 | ||||
2401 | // note text styles | |||
2402 | ||||
2403 | rtl::Reference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this ); | |||
2404 | ||||
2405 | const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles(); | |||
2406 | for (const auto& rNoteTextEntry : rNoteTextEntries) | |||
2407 | { | |||
2408 | ScAddress aPos = rNoteTextEntry.maCellPos; | |||
2409 | SCTAB nTable = aPos.Tab(); | |||
2410 | bool bCopySheet = pDoc->IsStreamValid( nTable ); | |||
2411 | if (bCopySheet) | |||
2412 | { | |||
2413 | ScPostIt* pNote = pDoc->GetNote( aPos ); | |||
2414 | OSL_ENSURE( pNote, "note not found" )do { if (true && (!(pNote))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "2414" ": "), "%s", "note not found"); } } while (false); | |||
2415 | if (pNote) | |||
2416 | { | |||
2417 | SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); | |||
2418 | uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); | |||
2419 | uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); | |||
2420 | ScDrawTextCursor* pCursor = comphelper::getUnoTunnelImplementation<ScDrawTextCursor>( xCursorProp ); | |||
2421 | if (pCursor) | |||
2422 | { | |||
2423 | pCursor->SetSelection( rNoteTextEntry.maSelection ); | |||
2424 | ||||
2425 | std::vector<XMLPropertyState> aPropStates(xTextPropMapper->Filter(xCursorProp)); | |||
2426 | OUString sName( rNoteTextEntry.maName ); | |||
2427 | GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TEXT_TEXT, OUString(), aPropStates); | |||
2428 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT, sName); | |||
2429 | } | |||
2430 | } | |||
2431 | } | |||
2432 | } | |||
2433 | ||||
2434 | // stored text styles | |||
2435 | ||||
2436 | // Calling createTextCursor fires up editeng, which is very slow, and often subsequent style entries | |||
2437 | // refer to the same cell, so cache it. | |||
2438 | ScAddress aPrevPos; | |||
2439 | uno::Reference<beans::XPropertySet> xPrevCursorProp; | |||
2440 | const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles(); | |||
2441 | for (const auto& rTextEntry : rTextEntries) | |||
2442 | { | |||
2443 | ScAddress aPos = rTextEntry.maCellPos; | |||
2444 | sal_Int32 nTable = aPos.Tab(); | |||
2445 | bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); | |||
2446 | if (!bCopySheet) | |||
2447 | continue; | |||
2448 | ||||
2449 | //! separate method AddStyleFromText needed? | |||
2450 | //! cache sheet object | |||
2451 | ||||
2452 | uno::Reference<beans::XPropertySet> xCursorProp; | |||
2453 | if (xPrevCursorProp && aPrevPos == aPos) | |||
2454 | xCursorProp = xPrevCursorProp; | |||
2455 | else | |||
2456 | { | |||
2457 | uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); | |||
2458 | uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY); | |||
2459 | xCursorProp.set(xCellText->createTextCursor(), uno::UNO_QUERY); | |||
2460 | } | |||
2461 | ScCellTextCursor* pCursor = comphelper::getUnoTunnelImplementation<ScCellTextCursor>( xCursorProp ); | |||
2462 | if (!pCursor) | |||
2463 | continue; | |||
2464 | pCursor->SetSelection( rTextEntry.maSelection ); | |||
2465 | ||||
2466 | std::vector<XMLPropertyState> aPropStates(xTextPropMapper->Filter(xCursorProp)); | |||
2467 | OUString sName( rTextEntry.maName ); | |||
2468 | GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TEXT_TEXT, OUString(), aPropStates); | |||
2469 | GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT, sName); | |||
2470 | xPrevCursorProp = xCursorProp; | |||
2471 | aPrevPos = aPos; | |||
2472 | } | |||
2473 | } | |||
2474 | ||||
2475 | ExportExternalRefCacheStyles(); | |||
2476 | ||||
2477 | if (!pSharedData) | |||
2478 | { | |||
2479 | SCTAB nTableCount(0); | |||
2480 | sal_Int32 nShapesCount(0); | |||
2481 | CollectSharedData(nTableCount, nShapesCount); | |||
2482 | } | |||
2483 | sal_Int32 nTableCount(xIndex->getCount()); | |||
2484 | pCellStyles->AddNewTable(nTableCount - 1); | |||
2485 | CollectShapesAutoStyles(nTableCount); | |||
2486 | for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable, IncrementProgressBar(false)) | |||
2487 | { | |||
2488 | uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); | |||
2489 | if (!xTable.is()) | |||
2490 | continue; | |||
2491 | ||||
2492 | // table styles array must be complete, including copied tables - Add should find the stored style | |||
2493 | uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); | |||
2494 | if (xTableProperties.is()) | |||
2495 | { | |||
2496 | std::vector<XMLPropertyState> aPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); | |||
2497 | if(!aPropStates.empty()) | |||
2498 | { | |||
2499 | OUString sName; | |||
2500 | GetAutoStylePool()->Add(sName, XmlStyleFamily::TABLE_TABLE, OUString(), aPropStates); | |||
2501 | aTableStyles.push_back(sName); | |||
2502 | } | |||
2503 | } | |||
2504 | ||||
2505 | // collect other auto-styles only for non-copied sheets | |||
2506 | uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY ); | |||
2507 | if ( xCellFormatRanges.is() ) | |||
2508 | { | |||
2509 | uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges()); | |||
2510 | if (xFormatRangesIndex.is()) | |||
2511 | { | |||
2512 | sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount()); | |||
2513 | GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount); | |||
2514 | for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange) | |||
2515 | { | |||
2516 | uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY); | |||
2517 | if (xCellRanges.is()) | |||
2518 | { | |||
2519 | uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY); | |||
2520 | if (xProperties.is()) | |||
2521 | { | |||
2522 | AddStyleFromCells(xProperties, xTable, nTable, nullptr); | |||
2523 | IncrementProgressBar(false); | |||
2524 | } | |||
2525 | } | |||
2526 | } | |||
2527 | } | |||
2528 | } | |||
2529 | uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY); | |||
2530 | if (xColumnRowRange.is() && pDoc) | |||
2531 | { | |||
2532 | pDoc->SyncColRowFlags(); | |||
2533 | uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); | |||
2534 | if (xTableColumns.is()) | |||
2535 | { | |||
2536 | sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable))); | |||
2537 | pSharedData->SetLastColumn(nTable, nColumns); | |||
2538 | table::CellRangeAddress aCellAddress(GetEndAddress(xTable)); | |||
2539 | if (aCellAddress.EndColumn > nColumns) | |||
2540 | { | |||
2541 | ++nColumns; | |||
2542 | pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn); | |||
2543 | } | |||
2544 | else | |||
2545 | pColumnStyles->AddNewTable(nTable, nColumns); | |||
2546 | sal_Int32 nColumn = 0; | |||
2547 | while (nColumn <= pDoc->MaxCol()) | |||
2548 | { | |||
2549 | sal_Int32 nIndex(-1); | |||
2550 | bool bIsVisible(true); | |||
2551 | uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY); | |||
2552 | if (xColumnProperties.is()) | |||
2553 | { | |||
2554 | AddStyleFromColumn( xColumnProperties, nullptr, nIndex, bIsVisible ); | |||
2555 | pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible); | |||
2556 | } | |||
2557 | sal_Int32 nOld(nColumn); | |||
2558 | nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn)); | |||
2559 | for (sal_Int32 i = nOld + 1; i < nColumn; ++i) | |||
2560 | pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); | |||
2561 | } | |||
2562 | if (aCellAddress.EndColumn > nColumns) | |||
2563 | { | |||
2564 | bool bIsVisible(true); | |||
2565 | sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible)); | |||
2566 | for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i) | |||
2567 | pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); | |||
2568 | } | |||
2569 | } | |||
2570 | uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); | |||
2571 | if (xTableRows.is()) | |||
2572 | { | |||
2573 | sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable))); | |||
2574 | pSharedData->SetLastRow(nTable, nRows); | |||
2575 | ||||
2576 | pRowStyles->AddNewTable(nTable, pDoc->MaxRow()); | |||
2577 | sal_Int32 nRow = 0; | |||
2578 | while (nRow <= pDoc->MaxRow()) | |||
2579 | { | |||
2580 | sal_Int32 nIndex = 0; | |||
2581 | uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY); | |||
2582 | if(xRowProperties.is()) | |||
2583 | { | |||
2584 | AddStyleFromRow( xRowProperties, nullptr, nIndex ); | |||
2585 | pRowStyles->AddFieldStyleName(nTable, nRow, nIndex); | |||
2586 | } | |||
2587 | sal_Int32 nOld(nRow); | |||
2588 | nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow)); | |||
2589 | if (nRow > nOld + 1) | |||
2590 | pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1); | |||
2591 | } | |||
2592 | } | |||
2593 | } | |||
2594 | ExportCellTextAutoStyles(nTable); | |||
2595 | } | |||
2596 | ||||
2597 | pChangeTrackingExportHelper->CollectAutoStyles(); | |||
2598 | } | |||
2599 | ||||
2600 | if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES) | |||
2601 | GetPageExport()->collectAutoStyles(true); | |||
2602 | ||||
2603 | mbAutoStylesCollected = true; | |||
2604 | } | |||
2605 | ||||
2606 | void ScXMLExport::ExportAutoStyles_() | |||
2607 | { | |||
2608 | if (!GetModel().is()) | |||
2609 | return; | |||
2610 | ||||
2611 | uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); | |||
2612 | if (!xSpreadDoc.is()) | |||
2613 | return; | |||
2614 | ||||
2615 | uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); | |||
2616 | if (!xIndex.is()) | |||
2617 | return; | |||
2618 | ||||
2619 | collectAutoStyles(); | |||
2620 | ||||
2621 | if (getExportFlags() & SvXMLExportFlags::CONTENT) | |||
2622 | { | |||
2623 | GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_COLUMN); | |||
2624 | GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_ROW); | |||
2625 | GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_TABLE); | |||
2626 | exportAutoDataStyles(); | |||
2627 | GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_CELL); | |||
2628 | ||||
2629 | GetShapeExport()->exportAutoStyles(); | |||
2630 | GetFormExport()->exportAutoStyles( ); | |||
2631 | ||||
2632 | if (pDoc) | |||
2633 | { | |||
2634 | ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); | |||
2635 | // #i100879# write the table style for cached tables only if there are cached tables | |||
2636 | // (same logic as in ExportExternalRefCacheStyles) | |||
2637 | if (pRefMgr->hasExternalData()) | |||
2638 | { | |||
2639 | // Special table style for the external ref cache tables. | |||
2640 | AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName); | |||
2641 | AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE); | |||
2642 | SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, true, true); | |||
2643 | AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE); | |||
2644 | SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, true, true); | |||
2645 | } | |||
2646 | } | |||
2647 | } | |||
2648 | ||||
2649 | if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES) | |||
2650 | { | |||
2651 | GetPageExport()->exportAutoStyles(); | |||
2652 | } | |||
2653 | ||||
2654 | // #i30251#; only write Text Styles once | |||
2655 | ||||
2656 | if ((getExportFlags() & SvXMLExportFlags::CONTENT) || (getExportFlags() & SvXMLExportFlags::MASTERSTYLES)) | |||
2657 | GetTextParagraphExport()->exportTextAutoStyles(); | |||
2658 | } | |||
2659 | ||||
2660 | void ScXMLExport::ExportMasterStyles_() | |||
2661 | { | |||
2662 | GetPageExport()->exportMasterStyles( true ); | |||
2663 | } | |||
2664 | ||||
2665 | void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > const & xShape ) | |||
2666 | { | |||
2667 | // detective objects and notes | |||
2668 | SvxShape* pShapeImp = comphelper::getUnoTunnelImplementation<SvxShape>( xShape ); | |||
2669 | if( !pShapeImp ) | |||
2670 | return; | |||
2671 | ||||
2672 | SdrObject* pObject = pShapeImp->GetSdrObject(); | |||
2673 | if( !pObject ) | |||
2674 | return; | |||
2675 | ||||
2676 | // collect note caption objects from all layers (internal or hidden) | |||
2677 | if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) ) | |||
2678 | { | |||
2679 | if(pDoc->GetNote(pCaptData->maStart)) | |||
2680 | { | |||
2681 | pSharedData->AddNoteObj( xShape, pCaptData->maStart ); | |||
2682 | ||||
2683 | // #i60851# When the file is saved while editing a new note, | |||
2684 | // the cell is still empty -> last column/row must be updated | |||
2685 | OSL_ENSURE( pCaptData->maStart.Tab() == nCurrentTable, "invalid table in object data" )do { if (true && (!(pCaptData->maStart.Tab() == nCurrentTable ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "2685" ": "), "%s", "invalid table in object data"); } } while (false); | |||
2686 | pSharedData->SetLastColumn( nCurrentTable, pCaptData->maStart.Col() ); | |||
2687 | pSharedData->SetLastRow( nCurrentTable, pCaptData->maStart.Row() ); | |||
2688 | } | |||
2689 | } | |||
2690 | // other objects from internal layer only (detective) | |||
2691 | else if( pObject->GetLayer() == SC_LAYER_INTERN ) | |||
2692 | { | |||
2693 | ScDetectiveFunc aDetFunc( *pDoc, static_cast<SCTAB>(nCurrentTable) ); | |||
2694 | ScAddress aPosition; | |||
2695 | ScRange aSourceRange; | |||
2696 | bool bRedLine; | |||
2697 | ScDetectiveObjType eObjType = aDetFunc.GetDetectiveObjectType( | |||
2698 | pObject, nCurrentTable, aPosition, aSourceRange, bRedLine ); | |||
2699 | pSharedData->GetDetectiveObjContainer()->AddObject( eObjType, static_cast<SCTAB>(nCurrentTable), aPosition, aSourceRange, bRedLine ); | |||
2700 | } | |||
2701 | } | |||
2702 | ||||
2703 | bool ScXMLExport::GetMerged (const table::CellRangeAddress* pCellAddress, | |||
2704 | const uno::Reference <sheet::XSpreadsheet>& xTable) | |||
2705 | { | |||
2706 | bool bReady(false); | |||
2707 | sal_Int32 nRow(pCellAddress->StartRow); | |||
2708 | sal_Int32 nCol(pCellAddress->StartColumn); | |||
2709 | sal_Int32 nEndRow(pCellAddress->EndRow); | |||
2710 | sal_Int32 nEndCol(pCellAddress->EndColumn); | |||
2711 | bool bRowInc(nEndRow > nRow); | |||
2712 | while(!bReady && nRow <= nEndRow && nCol <= nEndCol) | |||
2713 | { | |||
2714 | uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY); | |||
2715 | if (xSheetCellRange.is()) | |||
2716 | { | |||
2717 | uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange)); | |||
2718 | if(xCursor.is()) | |||
2719 | { | |||
2720 | uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY); | |||
2721 | xCursor->collapseToMergedArea(); | |||
2722 | table::CellRangeAddress aCellAddress2(xCellAddress->getRangeAddress()); | |||
2723 | ScRange aScRange( aCellAddress2.StartColumn, aCellAddress2.StartRow, aCellAddress2.Sheet, | |||
2724 | aCellAddress2.EndColumn, aCellAddress2.EndRow, aCellAddress2.Sheet ); | |||
2725 | ||||
2726 | if ((aScRange.aEnd.Row() > nRow || | |||
2727 | aScRange.aEnd.Col() > nCol) && | |||
2728 | aScRange.aStart.Row() == nRow && | |||
2729 | aScRange.aStart.Col() == nCol) | |||
2730 | { | |||
2731 | pMergedRangesContainer->AddRange(aScRange); | |||
2732 | pSharedData->SetLastColumn(aScRange.aEnd.Tab(), aScRange.aEnd.Col()); | |||
2733 | pSharedData->SetLastRow(aScRange.aEnd.Tab(), aScRange.aEnd.Row()); | |||
2734 | } | |||
2735 | else | |||
2736 | bReady = true; | |||
2737 | } | |||
2738 | } | |||
2739 | if (!bReady) | |||
2740 | { | |||
2741 | if (bRowInc) | |||
2742 | ++nRow; | |||
2743 | else | |||
2744 | ++nCol; | |||
2745 | } | |||
2746 | } | |||
2747 | OSL_ENSURE(!(!bReady && nEndRow > nRow && nEndCol > nCol), "should not be possible")do { if (true && (!(!(!bReady && nEndRow > nRow && nEndCol > nCol)))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "2747" ": "), "%s", "should not be possible"); } } while (false); | |||
2748 | return !bReady; | |||
2749 | } | |||
2750 | ||||
2751 | bool ScXMLExport::IsMatrix (const ScAddress& aCell, | |||
2752 | ScRange& aCellAddress, bool& bIsFirst) const | |||
2753 | { | |||
2754 | bIsFirst = false; | |||
2755 | ||||
2756 | ScRange aMatrixRange; | |||
2757 | ||||
2758 | if (pDoc && pDoc->GetMatrixFormulaRange(aCell, aMatrixRange)) | |||
2759 | { | |||
2760 | aCellAddress = aMatrixRange; | |||
2761 | if ((aCellAddress.aStart.Col() == aCell.Col() && aCellAddress.aStart.Row() == aCell.Row()) && | |||
2762 | (aCellAddress.aEnd.Col() > aCell.Col() || aCellAddress.aEnd.Row() > aCell.Row())) | |||
2763 | { | |||
2764 | bIsFirst = true; | |||
2765 | return true; | |||
2766 | } | |||
2767 | else if (aCellAddress.aStart.Col() != aCell.Col() || aCellAddress.aStart.Row() != aCell.Row() || | |||
2768 | aCellAddress.aEnd.Col() != aCell.Col() || aCellAddress.aEnd.Row()!= aCell.Row()) | |||
2769 | return true; | |||
2770 | else | |||
2771 | { | |||
2772 | bIsFirst = true; | |||
2773 | return true; | |||
2774 | } | |||
2775 | } | |||
2776 | ||||
2777 | return false; | |||
2778 | } | |||
2779 | ||||
2780 | void ScXMLExport::WriteTable(sal_Int32 nTable, const uno::Reference<sheet::XSpreadsheet>& xTable) | |||
2781 | { | |||
2782 | if (!xTable.is()) | |||
2783 | return; | |||
2784 | ||||
2785 | xCurrentTable.set(xTable); | |||
2786 | uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY ); | |||
2787 | if (!xName.is()) | |||
2788 | return; | |||
2789 | ||||
2790 | nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable ); | |||
2791 | OUString sOUTableName(xName->getName()); | |||
2792 | AddAttribute(sAttrName, sOUTableName); | |||
2793 | AddAttribute(sAttrStyleName, aTableStyles[nTable]); | |||
2794 | ||||
2795 | uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY); | |||
2796 | ScTableProtection* pProtect = nullptr; | |||
2797 | if (xProtectable.is() && xProtectable->isProtected()) | |||
2798 | { | |||
2799 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE); | |||
2800 | if (pDoc) | |||
2801 | { | |||
2802 | pProtect = pDoc->GetTabProtection(nTable); | |||
2803 | if (pProtect) | |||
2804 | { | |||
2805 | OUStringBuffer aBuffer; | |||
2806 | ScPasswordHash eHashUsed = PASSHASH_UNSPECIFIED; | |||
2807 | if (pProtect->hasPasswordHash(PASSHASH_SHA1)) | |||
2808 | { | |||
2809 | ::comphelper::Base64::encode(aBuffer, | |||
2810 | pProtect->getPasswordHash(PASSHASH_SHA1)); | |||
2811 | eHashUsed = PASSHASH_SHA1; | |||
2812 | } | |||
2813 | else if (pProtect->hasPasswordHash(PASSHASH_SHA256)) | |||
2814 | { | |||
2815 | ::comphelper::Base64::encode(aBuffer, | |||
2816 | pProtect->getPasswordHash(PASSHASH_SHA256)); | |||
2817 | eHashUsed = PASSHASH_SHA256; | |||
2818 | } | |||
2819 | else if (pProtect->hasPasswordHash(PASSHASH_XL, PASSHASH_SHA1)) | |||
2820 | { | |||
2821 | // Double-hash this by SHA1 on top of the legacy xls hash. | |||
2822 | uno::Sequence<sal_Int8> aHash = pProtect->getPasswordHash(PASSHASH_XL, PASSHASH_SHA1); | |||
2823 | ::comphelper::Base64::encode(aBuffer, aHash); | |||
2824 | eHashUsed = PASSHASH_XL; | |||
2825 | } | |||
2826 | if (!aBuffer.isEmpty()) | |||
2827 | { | |||
2828 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); | |||
2829 | if (getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012) | |||
2830 | { | |||
2831 | if (eHashUsed == PASSHASH_XL) | |||
2832 | { | |||
2833 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, | |||
2834 | ScPassHashHelper::getHashURI(PASSHASH_XL)); | |||
2835 | if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
2836 | AddAttribute(XML_NAMESPACE_LO_EXT, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2, | |||
2837 | ScPassHashHelper::getHashURI(PASSHASH_SHA1)); | |||
2838 | } | |||
2839 | else if (eHashUsed == PASSHASH_SHA1) | |||
2840 | { | |||
2841 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, | |||
2842 | ScPassHashHelper::getHashURI(PASSHASH_SHA1)); | |||
2843 | } | |||
2844 | else if (eHashUsed == PASSHASH_SHA256) | |||
2845 | { | |||
2846 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, | |||
2847 | ScPassHashHelper::getHashURI(PASSHASH_SHA256)); | |||
2848 | } | |||
2849 | } | |||
2850 | } | |||
2851 | } | |||
2852 | } | |||
2853 | } | |||
2854 | OUString sPrintRanges; | |||
2855 | ScRange aColumnHeaderRange; | |||
2856 | bool bHasColumnHeader; | |||
2857 | GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges); | |||
2858 | if( !sPrintRanges.isEmpty() ) | |||
2859 | AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges ); | |||
2860 | else if (pDoc && !pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable))) | |||
2861 | AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE); | |||
2862 | SvXMLElementExport aElemT(*this, sElemTab, true, true); | |||
2863 | ||||
2864 | if (pProtect && pProtect->isProtected() && getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
2865 | { | |||
2866 | if (pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS)) | |||
2867 | AddAttribute(XML_NAMESPACE_LO_EXT, XML_SELECT_PROTECTED_CELLS, XML_TRUE); | |||
2868 | if (pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS)) | |||
2869 | AddAttribute(XML_NAMESPACE_LO_EXT, XML_SELECT_UNPROTECTED_CELLS, XML_TRUE); | |||
2870 | ||||
2871 | if (pProtect->isOptionEnabled(ScTableProtection::INSERT_COLUMNS)) | |||
2872 | AddAttribute(XML_NAMESPACE_LO_EXT, XML_INSERT_COLUMNS, XML_TRUE); | |||
2873 | if (pProtect->isOptionEnabled(ScTableProtection::INSERT_ROWS)) | |||
2874 | AddAttribute(XML_NAMESPACE_LO_EXT, XML_INSERT_ROWS, XML_TRUE); | |||
2875 | ||||
2876 | if (pProtect->isOptionEnabled(ScTableProtection::DELETE_COLUMNS)) | |||
2877 | AddAttribute(XML_NAMESPACE_LO_EXT, XML_DELETE_COLUMNS, XML_TRUE); | |||
2878 | if (pProtect->isOptionEnabled(ScTableProtection::DELETE_ROWS)) | |||
2879 | AddAttribute(XML_NAMESPACE_LO_EXT, XML_DELETE_ROWS, XML_TRUE); | |||
2880 | ||||
2881 | OUString aElemName = GetNamespaceMap().GetQNameByKey( | |||
2882 | XML_NAMESPACE_LO_EXT, GetXMLToken(XML_TABLE_PROTECTION)); | |||
2883 | ||||
2884 | SvXMLElementExport aElemProtected(*this, aElemName, true, true); | |||
2885 | } | |||
2886 | ||||
2887 | CheckAttrList(); | |||
2888 | ||||
2889 | if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) && | |||
2890 | getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012) | |||
2891 | { | |||
2892 | // store sheet events | |||
2893 | uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY); | |||
2894 | uno::Reference<container::XNameAccess> xEvents = xSupplier->getEvents(); | |||
2895 | GetEventExport().ExportExt( xEvents ); | |||
2896 | } | |||
2897 | ||||
2898 | WriteTableSource(); | |||
2899 | WriteScenario(); | |||
2900 | uno::Reference<drawing::XDrawPage> xDrawPage; | |||
2901 | if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is()) | |||
2902 | { | |||
2903 | ::xmloff::OOfficeFormsExport aForms(*this); | |||
2904 | GetFormExport()->exportForms( xDrawPage ); | |||
2905 | bool bRet(GetFormExport()->seekPage( xDrawPage )); | |||
2906 | OSL_ENSURE( bRet, "OFormLayerXMLExport::seekPage failed!" )do { if (true && (!(bRet))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "2906" ": "), "%s", "OFormLayerXMLExport::seekPage failed!" ); } } while (false); | |||
2907 | } | |||
2908 | if (pSharedData->HasDrawPage()) | |||
2909 | { | |||
2910 | GetShapeExport()->seekShapes(pSharedData->GetDrawPage(nTable)); | |||
2911 | WriteTableShapes(); | |||
2912 | } | |||
2913 | table::CellRangeAddress aRange(GetEndAddress(xTable)); | |||
2914 | pSharedData->SetLastColumn(nTable, aRange.EndColumn); | |||
2915 | pSharedData->SetLastRow(nTable, aRange.EndRow); | |||
2916 | mpCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable); | |||
2917 | pGroupColumns->NewTable(); | |||
2918 | pGroupRows->NewTable(); | |||
2919 | FillColumnRowGroups(); | |||
2920 | if (bHasColumnHeader) | |||
2921 | pSharedData->SetLastColumn(nTable, aColumnHeaderRange.aEnd.Col()); | |||
2922 | bRowHeaderOpen = false; | |||
2923 | if (bHasRowHeader) | |||
2924 | pSharedData->SetLastRow(nTable, aRowHeaderRange.aEnd.Row()); | |||
2925 | pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable), | |||
2926 | pSharedData->GetLastColumn(nTable), pCellStyles.get(), pDoc); | |||
2927 | pRowFormatRanges->SetColDefaults(&pDefaults->GetColDefaults()); | |||
2928 | pCellStyles->SetColDefaults(&pDefaults->GetColDefaults()); | |||
2929 | ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader); | |||
2930 | bool bIsFirst(true); | |||
2931 | sal_Int32 nEqualCells(0); | |||
2932 | ScMyCell aCell; | |||
2933 | ScMyCell aPrevCell; | |||
2934 | while (mpCellsItr->GetNext(aCell, pCellStyles.get())) | |||
2935 | { | |||
2936 | if (bIsFirst) | |||
2937 | { | |||
2938 | ExportFormatRanges(0, 0, aCell.maCellAddress.Col()-1, aCell.maCellAddress.Row(), nTable); | |||
2939 | aPrevCell = aCell; | |||
2940 | bIsFirst = false; | |||
2941 | } | |||
2942 | else | |||
2943 | { | |||
2944 | if ((aPrevCell.maCellAddress.Row() == aCell.maCellAddress.Row()) && | |||
2945 | (aPrevCell.maCellAddress.Col() + nEqualCells + 1 == aCell.maCellAddress.Col())) | |||
2946 | { | |||
2947 | if(IsCellEqual(aPrevCell, aCell)) | |||
2948 | ++nEqualCells; | |||
2949 | else | |||
2950 | { | |||
2951 | WriteCell(aPrevCell, nEqualCells); | |||
2952 | nEqualCells = 0; | |||
2953 | aPrevCell = aCell; | |||
2954 | } | |||
2955 | } | |||
2956 | else | |||
2957 | { | |||
2958 | WriteCell(aPrevCell, nEqualCells); | |||
2959 | ExportFormatRanges(aPrevCell.maCellAddress.Col() + nEqualCells + 1, aPrevCell.maCellAddress.Row(), | |||
2960 | aCell.maCellAddress.Col()-1, aCell.maCellAddress.Row(), nTable); | |||
2961 | nEqualCells = 0; | |||
2962 | aPrevCell = aCell; | |||
2963 | } | |||
2964 | } | |||
2965 | } | |||
2966 | if (!bIsFirst) | |||
2967 | { | |||
2968 | WriteCell(aPrevCell, nEqualCells); | |||
2969 | ExportFormatRanges(aPrevCell.maCellAddress.Col() + nEqualCells + 1, aPrevCell.maCellAddress.Row(), | |||
2970 | pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); | |||
2971 | } | |||
2972 | else | |||
2973 | ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); | |||
2974 | ||||
2975 | CloseRow(pSharedData->GetLastRow(nTable)); | |||
2976 | ||||
2977 | if (!pDoc) | |||
2978 | return; | |||
2979 | ||||
2980 | // Export sheet-local named ranges. | |||
2981 | ScRangeName* pRangeName = pDoc->GetRangeName(nTable); | |||
2982 | if (pRangeName && !pRangeName->empty()) | |||
2983 | { | |||
2984 | WriteNamedRange(pRangeName); | |||
2985 | } | |||
2986 | ||||
2987 | if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
2988 | { | |||
2989 | //export new conditional format information | |||
2990 | ExportConditionalFormat(nTable); | |||
2991 | } | |||
2992 | } | |||
2993 | ||||
2994 | namespace { | |||
2995 | ||||
2996 | void writeContent( | |||
2997 | ScXMLExport& rExport, const OUString& rStyleName, const OUString& rContent, const SvxFieldData* pField ) | |||
2998 | { | |||
2999 | std::unique_ptr<SvXMLElementExport> pElem; | |||
3000 | if (!rStyleName.isEmpty()) | |||
3001 | { | |||
3002 | // Formatted section with automatic style. | |||
3003 | rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, rStyleName); | |||
3004 | OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( | |||
3005 | XML_NAMESPACE_TEXT, GetXMLToken(XML_SPAN)); | |||
3006 | pElem.reset(new SvXMLElementExport(rExport, aElemName, false, false)); | |||
3007 | } | |||
3008 | ||||
3009 | if (pField) | |||
3010 | { | |||
3011 | // Write a field item. | |||
3012 | OUString aFieldVal = ScEditUtil::GetCellFieldValue(*pField, rExport.GetDocument(), nullptr); | |||
3013 | switch (pField->GetClassId()) | |||
3014 | { | |||
3015 | case text::textfield::Type::URL: | |||
3016 | { | |||
3017 | // <text:a xlink:href="url" xlink:type="simple">value</text:a> | |||
3018 | ||||
3019 | const SvxURLField* pURLField = static_cast<const SvxURLField*>(pField); | |||
3020 | const OUString& aURL = pURLField->GetURL(); | |||
3021 | rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, rExport.GetRelativeReference(aURL)); | |||
3022 | rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, "simple"); | |||
3023 | const OUString& aTargetFrame = pURLField->GetTargetFrame(); | |||
3024 | if (!aTargetFrame.isEmpty()) | |||
3025 | rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, aTargetFrame); | |||
3026 | ||||
3027 | OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( | |||
3028 | XML_NAMESPACE_TEXT, GetXMLToken(XML_A)); | |||
3029 | SvXMLElementExport aElem(rExport, aElemName, false, false); | |||
3030 | rExport.Characters(aFieldVal); | |||
3031 | } | |||
3032 | break; | |||
3033 | case text::textfield::Type::DATE: | |||
3034 | { | |||
3035 | // <text:date style:data-style-name="N2" text:date-value="YYYY-MM-DD">value</text:date> | |||
3036 | ||||
3037 | Date aDate(Date::SYSTEM); | |||
3038 | OUStringBuffer aBuf; | |||
3039 | sal_Int32 nVal = aDate.GetYear(); | |||
3040 | aBuf.append(nVal); | |||
3041 | aBuf.append('-'); | |||
3042 | nVal = aDate.GetMonth(); | |||
3043 | if (nVal < 10) | |||
3044 | aBuf.append('0'); | |||
3045 | aBuf.append(nVal); | |||
3046 | aBuf.append('-'); | |||
3047 | nVal = aDate.GetDay(); | |||
3048 | if (nVal < 10) | |||
3049 | aBuf.append('0'); | |||
3050 | aBuf.append(nVal); | |||
3051 | rExport.AddAttribute(XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, "N2"); | |||
3052 | rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_DATE_VALUE, aBuf.makeStringAndClear()); | |||
3053 | ||||
3054 | OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( | |||
3055 | XML_NAMESPACE_TEXT, GetXMLToken(XML_DATE)); | |||
3056 | SvXMLElementExport aElem(rExport, aElemName, false, false); | |||
3057 | rExport.Characters(aFieldVal); | |||
3058 | } | |||
3059 | break; | |||
3060 | case text::textfield::Type::DOCINFO_TITLE: | |||
3061 | { | |||
3062 | // <text:title>value</text:title> | |||
3063 | ||||
3064 | OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( | |||
3065 | XML_NAMESPACE_TEXT, GetXMLToken(XML_TITLE)); | |||
3066 | SvXMLElementExport aElem(rExport, aElemName, false, false); | |||
3067 | rExport.Characters(aFieldVal); | |||
3068 | } | |||
3069 | break; | |||
3070 | case text::textfield::Type::TABLE: | |||
3071 | { | |||
3072 | // <text:sheet-name>value</text:sheet-name> | |||
3073 | ||||
3074 | OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( | |||
3075 | XML_NAMESPACE_TEXT, GetXMLToken(XML_SHEET_NAME)); | |||
3076 | SvXMLElementExport aElem(rExport, aElemName, false, false); | |||
3077 | rExport.Characters(aFieldVal); | |||
3078 | } | |||
3079 | break; | |||
3080 | default: | |||
3081 | rExport.Characters(aFieldVal); | |||
3082 | } | |||
3083 | } | |||
3084 | else | |||
3085 | rExport.Characters(rContent); | |||
3086 | } | |||
3087 | ||||
3088 | void flushParagraph( | |||
3089 | ScXMLExport& rExport, const OUString& rParaText, | |||
3090 | rtl::Reference<XMLPropertySetMapper> const & xMapper, rtl::Reference<SvXMLAutoStylePoolP> const & xStylePool, | |||
3091 | const ScXMLEditAttributeMap& rAttrMap, | |||
3092 | std::vector<editeng::Section>::const_iterator it, std::vector<editeng::Section>::const_iterator const & itEnd ) | |||
3093 | { | |||
3094 | OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( | |||
3095 | XML_NAMESPACE_TEXT, GetXMLToken(XML_P)); | |||
3096 | SvXMLElementExport aElemP(rExport, aElemName, false, false); | |||
3097 | ||||
3098 | for (; it != itEnd; ++it) | |||
3099 | { | |||
3100 | const editeng::Section& rSec = *it; | |||
3101 | ||||
3102 | OUString aContent(rParaText.copy(rSec.mnStart, rSec.mnEnd - rSec.mnStart)); | |||
3103 | ||||
3104 | std::vector<XMLPropertyState> aPropStates; | |||
3105 | const SvxFieldData* pField = toXMLPropertyStates(aPropStates, rSec.maAttributes, xMapper, rAttrMap); | |||
3106 | OUString aStyleName = xStylePool->Find(XmlStyleFamily::TEXT_TEXT, OUString(), aPropStates); | |||
3107 | writeContent(rExport, aStyleName, aContent, pField); | |||
3108 | } | |||
3109 | } | |||
3110 | ||||
3111 | } | |||
3112 | ||||
3113 | void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount) | |||
3114 | { | |||
3115 | // nEqualCellCount is the number of additional cells | |||
3116 | SetRepeatAttribute(nEqualCellCount, (aCell.nType != table::CellContentType_EMPTY)); | |||
3117 | ||||
3118 | if (aCell.nStyleIndex != -1) | |||
3119 | AddAttribute(sAttrStyleName, pCellStyles->GetStyleNameByIndex(aCell.nStyleIndex, aCell.bIsAutoStyle)); | |||
3120 | if (aCell.nValidationIndex > -1) | |||
3121 | AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(aCell.nValidationIndex)); | |||
3122 | const bool bIsFirstMatrixCell(aCell.bIsMatrixBase); | |||
3123 | if (bIsFirstMatrixCell) | |||
3124 | { | |||
3125 | SCCOL nColumns( aCell.aMatrixRange.aEnd.Col() - aCell.aMatrixRange.aStart.Col() + 1 ); | |||
3126 | SCROW nRows( aCell.aMatrixRange.aEnd.Row() - aCell.aMatrixRange.aStart.Row() + 1 ); | |||
3127 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, OUString::number(nColumns)); | |||
3128 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, OUString::number(nRows)); | |||
3129 | } | |||
3130 | bool bIsEmpty(false); | |||
3131 | switch (aCell.nType) | |||
3132 | { | |||
3133 | case table::CellContentType_EMPTY : | |||
3134 | { | |||
3135 | bIsEmpty = true; | |||
3136 | } | |||
3137 | break; | |||
3138 | case table::CellContentType_VALUE : | |||
3139 | { | |||
3140 | GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( | |||
3141 | aCell.nNumberFormat, aCell.maBaseCell.mfValue); | |||
3142 | if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
3143 | GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( | |||
3144 | aCell.nNumberFormat, aCell.maBaseCell.mfValue, false, XML_NAMESPACE_CALC_EXT, false); | |||
3145 | } | |||
3146 | break; | |||
3147 | case table::CellContentType_TEXT : | |||
3148 | { | |||
3149 | OUString sFormattedString(lcl_GetFormattedString(pDoc, aCell.maBaseCell, aCell.maCellAddress)); | |||
3150 | OUString sCellString = aCell.maBaseCell.getString(pDoc); | |||
3151 | GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( | |||
3152 | sCellString, sFormattedString); | |||
3153 | if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
3154 | GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( | |||
3155 | sCellString, sFormattedString, false, XML_NAMESPACE_CALC_EXT); | |||
3156 | } | |||
3157 | break; | |||
3158 | case table::CellContentType_FORMULA : | |||
3159 | { | |||
3160 | if (aCell.maBaseCell.meType == CELLTYPE_FORMULA) | |||
3161 | { | |||
3162 | const bool bIsMatrix(bIsFirstMatrixCell || aCell.bIsMatrixCovered); | |||
3163 | ScFormulaCell* pFormulaCell = aCell.maBaseCell.mpFormula; | |||
3164 | if (!bIsMatrix || bIsFirstMatrixCell) | |||
3165 | { | |||
3166 | if (!mpCompileFormulaCxt) | |||
3167 | { | |||
3168 | const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar(); | |||
3169 | mpCompileFormulaCxt.reset(new sc::CompileFormulaContext(*pDoc, eGrammar)); | |||
3170 | } | |||
3171 | ||||
3172 | OUString aFormula = pFormulaCell->GetFormula(*mpCompileFormulaCxt); | |||
3173 | sal_uInt16 nNamespacePrefix = | |||
3174 | (mpCompileFormulaCxt->getGrammar() == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC); | |||
3175 | ||||
3176 | if (!bIsMatrix) | |||
3177 | { | |||
3178 | AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey(nNamespacePrefix, aFormula, false)); | |||
3179 | } | |||
3180 | else | |||
3181 | { | |||
3182 | AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey(nNamespacePrefix, aFormula.copy(1, aFormula.getLength()-2), false)); | |||
3183 | } | |||
3184 | } | |||
3185 | if (pFormulaCell->GetErrCode() != FormulaError::NONE) | |||
3186 | { | |||
3187 | AddAttribute(sAttrValueType, XML_STRING); | |||
3188 | AddAttribute(sAttrStringValue, aCell.maBaseCell.getString(pDoc)); | |||
3189 | if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
3190 | { | |||
3191 | //export calcext:value-type="error" | |||
3192 | AddAttribute(XML_NAMESPACE_CALC_EXT,XML_VALUE_TYPE, OUString("error")); | |||
3193 | } | |||
3194 | } | |||
3195 | else if (pFormulaCell->IsValue()) | |||
3196 | { | |||
3197 | bool bIsStandard; | |||
3198 | OUString sCurrency; | |||
3199 | GetNumberFormatAttributesExportHelper()->GetCellType(aCell.nNumberFormat, sCurrency, bIsStandard); | |||
3200 | if (pDoc) | |||
3201 | { | |||
3202 | GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( | |||
3203 | aCell.nNumberFormat, pDoc->GetValue(aCell.maCellAddress)); | |||
3204 | if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
3205 | { | |||
3206 | GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( | |||
3207 | aCell.nNumberFormat, pDoc->GetValue(aCell.maCellAddress), false, XML_NAMESPACE_CALC_EXT, false ); | |||
3208 | } | |||
3209 | } | |||
3210 | } | |||
3211 | else | |||
3212 | { | |||
3213 | if (!aCell.maBaseCell.getString(pDoc).isEmpty()) | |||
3214 | { | |||
3215 | AddAttribute(sAttrValueType, XML_STRING); | |||
3216 | AddAttribute(sAttrStringValue, aCell.maBaseCell.getString(pDoc)); | |||
3217 | if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) | |||
3218 | { | |||
3219 | AddAttribute(XML_NAMESPACE_CALC_EXT,XML_VALUE_TYPE, XML_STRING); | |||
3220 | } | |||
3221 | } | |||
3222 | } | |||
3223 | } | |||
3224 | } | |||
3225 | break; | |||
3226 | default: | |||
3227 | break; | |||
3228 | } | |||
3229 | OUString* pCellString(&sElemCell); | |||
3230 | if (aCell.bIsCovered) | |||
3231 | { | |||
3232 | pCellString = &sElemCoveredCell; | |||
3233 | } | |||
3234 | else | |||
3235 | { | |||
3236 | if (aCell.bIsMergedBase) | |||
3237 | { | |||
3238 | SCCOL nColumns( aCell.aMergeRange.aEnd.Col() - aCell.aMergeRange.aStart.Col() + 1 ); | |||
3239 | SCROW nRows( aCell.aMergeRange.aEnd.Row() - aCell.aMergeRange.aStart.Row() + 1 ); | |||
3240 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, OUString::number(nColumns)); | |||
3241 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, OUString::number(nRows)); | |||
3242 | } | |||
3243 | } | |||
3244 | SvXMLElementExport aElemC(*this, *pCellString, true, true); | |||
3245 | CheckAttrList(); | |||
3246 | WriteAreaLink(aCell); | |||
3247 | WriteAnnotation(aCell); | |||
3248 | WriteDetective(aCell); | |||
3249 | ||||
3250 | if (!bIsEmpty) | |||
3251 | { | |||
3252 | if (aCell.maBaseCell.meType == CELLTYPE_EDIT) | |||
3253 | { | |||
3254 | WriteEditCell(aCell.maBaseCell.mpEditText); | |||
3255 | } | |||
3256 | else if (aCell.maBaseCell.meType == CELLTYPE_FORMULA && aCell.maBaseCell.mpFormula->IsMultilineResult()) | |||
3257 | { | |||
3258 | WriteMultiLineFormulaResult(aCell.maBaseCell.mpFormula); | |||
3259 | } | |||
3260 | else | |||
3261 | { | |||
3262 | SvXMLElementExport aElemP(*this, sElemP, true, false); | |||
3263 | ||||
3264 | OUString aParaStr = | |||
3265 | ScCellFormat::GetOutputString(*pDoc, aCell.maCellAddress, aCell.maBaseCell); | |||
3266 | ||||
3267 | bool bPrevCharWasSpace = true; | |||
3268 | GetTextParagraphExport()->exportCharacterData(aParaStr, bPrevCharWasSpace); | |||
3269 | } | |||
3270 | } | |||
3271 | WriteShapes(aCell); | |||
3272 | if (!bIsEmpty) | |||
3273 | IncrementProgressBar(false); | |||
3274 | } | |||
3275 | ||||
3276 | void ScXMLExport::WriteEditCell(const EditTextObject* pText) | |||
3277 | { | |||
3278 | rtl::Reference<XMLPropertySetMapper> xMapper = GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper(); | |||
3279 | rtl::Reference<SvXMLAutoStylePoolP> xStylePool = GetAutoStylePool(); | |||
3280 | const ScXMLEditAttributeMap& rAttrMap = GetEditAttributeMap(); | |||
3281 | ||||
3282 | // Get raw paragraph texts first. | |||
3283 | std::vector<OUString> aParaTexts; | |||
3284 | sal_Int32 nParaCount = pText->GetParagraphCount(); | |||
3285 | aParaTexts.reserve(nParaCount); | |||
3286 | for (sal_Int32 i = 0; i < nParaCount; ++i) | |||
3287 | aParaTexts.push_back(pText->GetText(i)); | |||
3288 | ||||
3289 | // Get all section data and iterate through them. | |||
3290 | std::vector<editeng::Section> aAttrs; | |||
3291 | pText->GetAllSections(aAttrs); | |||
3292 | std::vector<editeng::Section>::const_iterator itSec = aAttrs.begin(), itSecEnd = aAttrs.end(); | |||
3293 | std::vector<editeng::Section>::const_iterator itPara = itSec; | |||
3294 | sal_Int32 nCurPara = 0; // current paragraph | |||
3295 | for (; itSec != itSecEnd; ++itSec) | |||
3296 | { | |||
3297 | const editeng::Section& rSec = *itSec; | |||
3298 | if (nCurPara == rSec.mnParagraph) | |||
3299 | // Still in the same paragraph. | |||
3300 | continue; | |||
3301 | ||||
3302 | // Start of a new paragraph. Flush the old paragraph. | |||
3303 | flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSec); | |||
3304 | nCurPara = rSec.mnParagraph; | |||
3305 | itPara = itSec; | |||
3306 | } | |||
3307 | ||||
3308 | flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSecEnd); | |||
3309 | } | |||
3310 | ||||
3311 | void ScXMLExport::WriteMultiLineFormulaResult(const ScFormulaCell* pCell) | |||
3312 | { | |||
3313 | OUString aElemName = GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TEXT, GetXMLToken(XML_P)); | |||
3314 | ||||
3315 | OUString aResStr = pCell->GetResultString().getString(); | |||
3316 | const sal_Unicode* p = aResStr.getStr(); | |||
3317 | const sal_Unicode* pEnd = p + static_cast<size_t>(aResStr.getLength()); | |||
3318 | const sal_Unicode* pPara = p; // paragraph head. | |||
3319 | for (; p != pEnd; ++p) | |||
3320 | { | |||
3321 | if (*p != '\n') | |||
3322 | continue; | |||
3323 | ||||
3324 | // flush the paragraph. | |||
3325 | OUString aContent; | |||
3326 | if (*pPara == '\n') | |||
3327 | ++pPara; | |||
3328 | if (p > pPara) | |||
3329 | aContent = OUString(pPara, p-pPara); | |||
3330 | ||||
3331 | SvXMLElementExport aElem(*this, aElemName, false, false); | |||
3332 | Characters(aContent); | |||
3333 | ||||
3334 | pPara = p; | |||
3335 | } | |||
3336 | ||||
3337 | OUString aContent; | |||
3338 | if (*pPara == '\n') | |||
3339 | ++pPara; | |||
3340 | if (pEnd > pPara) | |||
3341 | aContent = OUString(pPara, pEnd-pPara); | |||
3342 | ||||
3343 | SvXMLElementExport aElem(*this, aElemName, false, false); | |||
3344 | Characters(aContent); | |||
3345 | } | |||
3346 | ||||
3347 | void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint) | |||
3348 | { | |||
3349 | uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY ); | |||
3350 | bool bIsChart( false ); | |||
3351 | if (xShapeProps.is()) | |||
3352 | { | |||
3353 | sal_Int32 nZOrder = 0; | |||
3354 | if (xShapeProps->getPropertyValue("ZOrder") >>= nZOrder) | |||
3355 | { | |||
3356 | AddAttribute(XML_NAMESPACE_DRAW, XML_ZINDEX, OUString::number(nZOrder)); | |||
3357 | } | |||
3358 | uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xShapeProps->getPropertySetInfo(); | |||
3359 | OUString sPropCLSID ("CLSID"); | |||
3360 | if( xPropSetInfo->hasPropertyByName( sPropCLSID ) ) | |||
3361 | { | |||
3362 | OUString sCLSID; | |||
3363 | if (xShapeProps->getPropertyValue( sPropCLSID ) >>= sCLSID) | |||
3364 | { | |||
3365 | if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) ) | |||
3366 | { | |||
3367 | // we have a chart | |||
3368 | OUString sRanges; | |||
3369 | if ( pDoc ) | |||
3370 | { | |||
3371 | OUString aChartName; | |||
3372 | xShapeProps->getPropertyValue( "PersistName" ) >>= aChartName; | |||
3373 | ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); | |||
3374 | if (pCollection) | |||
3375 | { | |||
3376 | ScChartListener* pListener = pCollection->findByName(aChartName); | |||
3377 | if (pListener) | |||
3378 | { | |||
3379 | const ScRangeListRef& rRangeList = pListener->GetRangeList(); | |||
3380 | if ( rRangeList.is() ) | |||
3381 | { | |||
3382 | ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList.get(), pDoc, FormulaGrammar::CONV_OOO ); | |||
3383 | if ( !sRanges.isEmpty() ) | |||
3384 | { | |||
3385 | bIsChart = true; | |||
3386 | SvXMLAttributeList* pAttrList = new SvXMLAttributeList(); | |||
3387 | pAttrList->AddAttribute( | |||
3388 | GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges ); | |||
3389 | GetShapeExport()->exportShape( xShape, SEF_DEFAULTXMLShapeExportFlags::POSITION|XMLShapeExportFlags::SIZE, pPoint, pAttrList ); | |||
3390 | } | |||
3391 | } | |||
3392 | } | |||
3393 | } | |||
3394 | } | |||
3395 | ||||
3396 | if ( sRanges.isEmpty() ) | |||
3397 | { | |||
3398 | uno::Reference< frame::XModel > xChartModel; | |||
3399 | if( ( xShapeProps->getPropertyValue( "Model" ) >>= xChartModel ) && | |||
3400 | xChartModel.is()) | |||
3401 | { | |||
3402 | uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY ); | |||
3403 | uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY ); | |||
3404 | if( xChartDoc.is() && xReceiver.is() && | |||
3405 | ! xChartDoc->hasInternalDataProvider()) | |||
3406 | { | |||
3407 | // we have a chart that gets its data from Calc | |||
3408 | bIsChart = true; | |||
3409 | uno::Sequence< OUString > aRepresentations( | |||
3410 | xReceiver->getUsedRangeRepresentations()); | |||
3411 | SvXMLAttributeList* pAttrList = nullptr; | |||
3412 | if(aRepresentations.hasElements()) | |||
3413 | { | |||
3414 | // add the ranges used by the chart to the shape | |||
3415 | // element to be able to start listening after | |||
3416 | // load (when the chart is not yet loaded) | |||
3417 | uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY ); | |||
3418 | sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter ); | |||
3419 | pAttrList = new SvXMLAttributeList(); | |||
3420 | pAttrList->AddAttribute( | |||
3421 | GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges ); | |||
3422 | } | |||
3423 | GetShapeExport()->exportShape(xShape, SEF_DEFAULTXMLShapeExportFlags::POSITION|XMLShapeExportFlags::SIZE, pPoint, pAttrList); | |||
3424 | } | |||
3425 | } | |||
3426 | } | |||
3427 | } | |||
3428 | } | |||
3429 | } | |||
3430 | } | |||
3431 | if (!bIsChart) | |||
3432 | { | |||
3433 | OUString sHlink; | |||
3434 | try | |||
3435 | { | |||
3436 | uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); | |||
3437 | if ( xProps.is() ) | |||
3438 | xProps->getPropertyValue( SC_UNONAME_HYPERLINK"Hyperlink" ) >>= sHlink; | |||
3439 | } | |||
3440 | catch ( const beans::UnknownPropertyException& ) | |||
3441 | { | |||
3442 | // no hyperlink property | |||
3443 | } | |||
3444 | ||||
3445 | std::unique_ptr< SvXMLElementExport > pDrawA; | |||
3446 | // enclose shapes with <draw:a> element only if sHlink contains something | |||
3447 | if ( !sHlink.isEmpty() ) | |||
3448 | { | |||
3449 | // need to get delete the attributes that are pre-loaded | |||
3450 | // for the shape export ( otherwise they will become | |||
3451 | // attributes of the draw:a element ) This *shouldn't* | |||
3452 | // affect performance adversely as there are only a | |||
3453 | // couple of attributes involved | |||
3454 | uno::Reference< xml::sax::XAttributeList > xSaveAttribs( new SvXMLAttributeList( GetAttrList() ) ); | |||
3455 | ClearAttrList(); | |||
3456 | // Add Hlink | |||
3457 | AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); | |||
3458 | AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sHlink); | |||
3459 | pDrawA.reset( new SvXMLElementExport( *this, XML_NAMESPACE_DRAW, XML_A, false, false ) ); | |||
3460 | // Attribute list has been cleared by previous operation | |||
3461 | // re-add pre-loaded attributes | |||
3462 | AddAttributeList( xSaveAttribs ); | |||
3463 | } | |||
3464 | GetShapeExport()->exportShape(xShape, SEF_DEFAULTXMLShapeExportFlags::POSITION|XMLShapeExportFlags::SIZE, pPoint); | |||
3465 | } | |||
3466 | IncrementProgressBar(false); | |||
3467 | } | |||
3468 | ||||
3469 | void ScXMLExport::WriteShapes(const ScMyCell& rMyCell) | |||
3470 | { | |||
3471 | if( !(rMyCell.bHasShape && !rMyCell.aShapeList.empty() && pDoc) ) | |||
3472 | return; | |||
3473 | ||||
3474 | awt::Point aPoint; | |||
3475 | tools::Rectangle aRect = pDoc->GetMMRect(rMyCell.maCellAddress.Col(), rMyCell.maCellAddress.Row(), | |||
3476 | rMyCell.maCellAddress.Col(), rMyCell.maCellAddress.Row(), rMyCell.maCellAddress.Tab()); | |||
3477 | bool bNegativePage = pDoc->IsNegativePage(rMyCell.maCellAddress.Tab()); | |||
3478 | if (bNegativePage) | |||
3479 | aPoint.X = aRect.Right(); | |||
3480 | else | |||
3481 | aPoint.X = aRect.Left(); | |||
3482 | aPoint.Y = aRect.Top(); | |||
3483 | for (const auto& rShape : rMyCell.aShapeList) | |||
3484 | { | |||
3485 | if (rShape.xShape.is()) | |||
3486 | { | |||
3487 | if (bNegativePage) | |||
3488 | aPoint.X = 2 * rShape.xShape->getPosition().X + rShape.xShape->getSize().Width - aPoint.X; | |||
3489 | ||||
3490 | // We only write the end address if we want the shape to resize with the cell | |||
3491 | if ( rShape.bResizeWithCell && | |||
3492 | rShape.xShape->getShapeType() != "com.sun.star.drawing.CaptionShape" ) | |||
3493 | { | |||
3494 | OUString sEndAddress; | |||
3495 | ScRangeStringConverter::GetStringFromAddress(sEndAddress, rShape.aEndAddress, pDoc, FormulaGrammar::CONV_OOO); | |||
3496 | AddAttribute(XML_NAMESPACE_TABLE, XML_END_CELL_ADDRESS, sEndAddress); | |||
3497 | OUStringBuffer sBuffer; | |||
3498 | GetMM100UnitConverter().convertMeasureToXML( | |||
3499 | sBuffer, rShape.nEndX); | |||
3500 | AddAttribute(XML_NAMESPACE_TABLE, XML_END_X, sBuffer.makeStringAndClear()); | |||
3501 | GetMM100UnitConverter().convertMeasureToXML( | |||
3502 | sBuffer, rShape.nEndY); | |||
3503 | AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear()); | |||
3504 | } | |||
3505 | ExportShape(rShape.xShape, &aPoint); | |||
3506 | } | |||
3507 | } | |||
3508 | } | |||
3509 | ||||
3510 | void ScXMLExport::WriteTableShapes() | |||
3511 | { | |||
3512 | ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes()); | |||
3513 | if (!pTableShapes || (*pTableShapes)[nCurrentTable].empty()) | |||
3514 | return; | |||
3515 | ||||
3516 | OSL_ENSURE(pTableShapes->size() > static_cast<size_t>(nCurrentTable), "wrong Table")do { if (true && (!(pTableShapes->size() > static_cast <size_t>(nCurrentTable)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "3516" ": "), "%s", "wrong Table"); } } while (false); | |||
3517 | SvXMLElementExport aShapesElem(*this, XML_NAMESPACE_TABLE, XML_SHAPES, true, false); | |||
3518 | for (const auto& rxShape : (*pTableShapes)[nCurrentTable]) | |||
3519 | { | |||
3520 | if (rxShape.is()) | |||
3521 | { | |||
3522 | if (pDoc->IsNegativePage(static_cast<SCTAB>(nCurrentTable))) | |||
3523 | { | |||
3524 | awt::Point aPoint(rxShape->getPosition()); | |||
3525 | awt::Size aSize(rxShape->getSize()); | |||
3526 | aPoint.X += aPoint.X + aSize.Width; | |||
3527 | aPoint.Y = 0; | |||
3528 | ExportShape(rxShape, &aPoint); | |||
3529 | } | |||
3530 | else | |||
3531 | ExportShape(rxShape, nullptr); | |||
3532 | } | |||
3533 | } | |||
3534 | (*pTableShapes)[nCurrentTable].clear(); | |||
3535 | } | |||
3536 | ||||
3537 | void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell ) | |||
3538 | { | |||
3539 | if( !rMyCell.bHasAreaLink ) | |||
3540 | return; | |||
3541 | ||||
3542 | const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink; | |||
3543 | AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr ); | |||
3544 | AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); | |||
3545 | AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) ); | |||
3546 | AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter ); | |||
3547 | if( !rAreaLink.sFilterOptions.isEmpty() ) | |||
3548 | AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, rAreaLink.sFilterOptions ); | |||
3549 | AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, OUString::number(rAreaLink.GetColCount()) ); | |||
3550 | AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, OUString::number(rAreaLink.GetRowCount()) ); | |||
3551 | if( rAreaLink.nRefresh ) | |||
3552 | { | |||
3553 | OUStringBuffer sValue; | |||
3554 | ::sax::Converter::convertDuration( sValue, | |||
3555 | static_cast<double>(rAreaLink.nRefresh) / 86400 ); | |||
3556 | AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sValue.makeStringAndClear() ); | |||
3557 | } | |||
3558 | SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, true, true ); | |||
3559 | } | |||
3560 | ||||
3561 | void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape) | |||
3562 | { | |||
3563 | ScPostIt* pNote = pCurrentCell->pNote; | |||
3564 | ||||
3565 | if (!pNote) | |||
3566 | return; | |||
3567 | ||||
3568 | // TODO : notes | |||
3569 | //is it still useful, as this call back is only called from ScXMLExport::WriteAnnotation | |||
3570 | // and should be in sync with pCurrentCell | |||
3571 | SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(pCurrentCell->maCellAddress); | |||
3572 | uno::Reference<drawing::XShape> xCurrentShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY ); | |||
3573 | if (xCurrentShape.get()!=xShape.get()) | |||
3574 | return; | |||
3575 | ||||
3576 | const OUString& sAuthor(pNote->GetAuthor()); | |||
3577 | if (!sAuthor.isEmpty()) | |||
3578 | { | |||
3579 | SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC, | |||
3580 | XML_CREATOR, true, | |||
3581 | false ); | |||
3582 | Characters(sAuthor); | |||
3583 | } | |||
3584 | ||||
3585 | const OUString& aDate(pNote->GetDate()); | |||
3586 | if (pDoc) | |||
3587 | { | |||
3588 | SvNumberFormatter* pNumForm = pDoc->GetFormatTable(); | |||
3589 | double fDate; | |||
3590 | sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEMLanguageType(0x0000)); | |||
3591 | if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate)) | |||
3592 | { | |||
3593 | OUStringBuffer sBuf; | |||
3594 | GetMM100UnitConverter().convertDateTime(sBuf, fDate,true); | |||
3595 | SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC, | |||
3596 | XML_DATE, true, | |||
3597 | false ); | |||
3598 | Characters(sBuf.makeStringAndClear()); | |||
3599 | } | |||
3600 | else | |||
3601 | { | |||
3602 | SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META, | |||
3603 | XML_DATE_STRING, true, | |||
3604 | false ); | |||
3605 | Characters(aDate); | |||
3606 | } | |||
3607 | } | |||
3608 | else | |||
3609 | { | |||
3610 | SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META, | |||
3611 | XML_DATE_STRING, true, | |||
3612 | false ); | |||
3613 | Characters(aDate); | |||
3614 | } | |||
3615 | } | |||
3616 | ||||
3617 | void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell) | |||
3618 | { | |||
3619 | ScPostIt* pNote = pDoc->GetNote(rMyCell.maCellAddress); | |||
3620 | if (!pNote) | |||
3621 | return; | |||
3622 | ||||
3623 | if (pNote->IsCaptionShown()) | |||
3624 | AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE); | |||
3625 | ||||
3626 | pCurrentCell = &rMyCell; | |||
3627 | ||||
3628 | SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(rMyCell.maCellAddress); | |||
3629 | if (pNoteCaption) | |||
3630 | { | |||
3631 | uno::Reference<drawing::XShape> xShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY ); | |||
3632 | if (xShape.is()) | |||
3633 | GetShapeExport()->exportShape(xShape, SEF_DEFAULTXMLShapeExportFlags::POSITION|XMLShapeExportFlags::SIZE|XMLShapeExportFlags::ANNOTATION); | |||
3634 | } | |||
3635 | ||||
3636 | pCurrentCell = nullptr; | |||
3637 | } | |||
3638 | ||||
3639 | void ScXMLExport::WriteDetective( const ScMyCell& rMyCell ) | |||
3640 | { | |||
3641 | if( !(rMyCell.bHasDetectiveObj || rMyCell.bHasDetectiveOp) ) | |||
3642 | return; | |||
3643 | ||||
3644 | const ScMyDetectiveObjVec& rObjVec = rMyCell.aDetectiveObjVec; | |||
3645 | const ScMyDetectiveOpVec& rOpVec = rMyCell.aDetectiveOpVec; | |||
3646 | sal_Int32 nObjCount(rObjVec.size()); | |||
3647 | sal_Int32 nOpCount(rOpVec.size()); | |||
3648 | if( !(nObjCount || nOpCount) ) | |||
3649 | return; | |||
3650 | ||||
3651 | SvXMLElementExport aDetElem( *this, XML_NAMESPACE_TABLE, XML_DETECTIVE, true, true ); | |||
3652 | OUString sString; | |||
3653 | for(const auto& rObj : rObjVec) | |||
3654 | { | |||
3655 | if (rObj.eObjType != SC_DETOBJ_CIRCLE) | |||
3656 | { | |||
3657 | if( (rObj.eObjType == SC_DETOBJ_ARROW) || (rObj.eObjType == SC_DETOBJ_TOOTHERTAB)) | |||
3658 | { | |||
3659 | ScRangeStringConverter::GetStringFromRange( sString, rObj.aSourceRange, pDoc, FormulaGrammar::CONV_OOO ); | |||
3660 | AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sString ); | |||
3661 | } | |||
3662 | ScXMLConverter::GetStringFromDetObjType( sString, rObj.eObjType ); | |||
3663 | AddAttribute( XML_NAMESPACE_TABLE, XML_DIRECTION, sString ); | |||
3664 | if( rObj.bHasError ) | |||
3665 | AddAttribute( XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TRUE ); | |||
3666 | } | |||
3667 | else | |||
3668 | AddAttribute( XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TRUE ); | |||
3669 | SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, true, true ); | |||
3670 | } | |||
3671 | for(const auto& rOp : rOpVec) | |||
3672 | { | |||
3673 | OUString sOpString; | |||
3674 | ScXMLConverter::GetStringFromDetOpType( sOpString, rOp.eOpType ); | |||
3675 | AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, sOpString ); | |||
3676 | AddAttribute( XML_NAMESPACE_TABLE, XML_INDEX, OUString::number(rOp.nIndex) ); | |||
3677 | SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_OPERATION, true, true ); | |||
3678 | } | |||
3679 | } | |||
3680 | ||||
3681 | void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount, bool bIncProgress) | |||
3682 | { | |||
3683 | // nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1 | |||
3684 | if (nEqualCellCount > 0) | |||
3685 | { | |||
3686 | sal_Int32 nTemp(nEqualCellCount + 1); | |||
3687 | OUString sOUEqualCellCount(OUString::number(nTemp)); | |||
3688 | AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount); | |||
3689 | if (bIncProgress) | |||
3690 | IncrementProgressBar(false, nEqualCellCount); | |||
3691 | } | |||
3692 | } | |||
3693 | ||||
3694 | bool ScXMLExport::IsEditCell(const ScMyCell& rCell) | |||
3695 | { | |||
3696 | return rCell.maBaseCell.meType == CELLTYPE_EDIT; | |||
3697 | } | |||
3698 | ||||
3699 | bool ScXMLExport::IsCellEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) | |||
3700 | { | |||
3701 | bool bIsEqual = false; | |||
3702 | if( !aCell1.bIsMergedBase && !aCell2.bIsMergedBase && | |||
3703 | aCell1.bIsCovered == aCell2.bIsCovered && | |||
3704 | !aCell1.bIsMatrixBase && !aCell2.bIsMatrixBase && | |||
3705 | aCell1.bIsMatrixCovered == aCell2.bIsMatrixCovered && | |||
3706 | aCell1.bHasAnnotation == aCell2.bHasAnnotation && | |||
3707 | !aCell1.bHasShape && !aCell2.bHasShape && | |||
3708 | aCell1.bHasAreaLink == aCell2.bHasAreaLink && | |||
3709 | !aCell1.bHasDetectiveObj && !aCell2.bHasDetectiveObj) | |||
3710 | { | |||
3711 | if( (aCell1.bHasAreaLink && | |||
3712 | (aCell1.aAreaLink.GetColCount() == 1) && | |||
3713 | (aCell2.aAreaLink.GetColCount() == 1) && | |||
3714 | aCell1.aAreaLink.Compare( aCell2.aAreaLink ) ) || | |||
3715 | !aCell1.bHasAreaLink ) | |||
3716 | { | |||
3717 | if (!aCell1.bHasAnnotation) | |||
3718 | { | |||
3719 | if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) || | |||
3720 | ((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) && | |||
3721 | aCell1.nValidationIndex == aCell2.nValidationIndex && | |||
3722 | aCell1.nType == aCell2.nType) | |||
3723 | { | |||
3724 | switch ( aCell1.nType ) | |||
3725 | { | |||
3726 | case table::CellContentType_EMPTY : | |||
3727 | { | |||
3728 | bIsEqual = true; | |||
3729 | } | |||
3730 | break; | |||
3731 | case table::CellContentType_VALUE : | |||
3732 | { | |||
3733 | // #i29101# number format may be different from column default styles, | |||
3734 | // but can lead to different value types, so it must also be compared | |||
3735 | bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) && | |||
3736 | (aCell1.maBaseCell.mfValue == aCell2.maBaseCell.mfValue); | |||
3737 | } | |||
3738 | break; | |||
3739 | case table::CellContentType_TEXT : | |||
3740 | { | |||
3741 | if (IsEditCell(aCell1) || IsEditCell(aCell2)) | |||
3742 | bIsEqual = false; | |||
3743 | else | |||
3744 | { | |||
3745 | bIsEqual = (aCell1.maBaseCell.getString(pDoc) == aCell2.maBaseCell.getString(pDoc)); | |||
3746 | } | |||
3747 | } | |||
3748 | break; | |||
3749 | case table::CellContentType_FORMULA : | |||
3750 | { | |||
3751 | bIsEqual = false; | |||
3752 | } | |||
3753 | break; | |||
3754 | default : | |||
3755 | { | |||
3756 | bIsEqual = false; | |||
3757 | } | |||
3758 | break; | |||
3759 | } | |||
3760 | } | |||
3761 | } | |||
3762 | } | |||
3763 | } | |||
3764 | return bIsEqual; | |||
3765 | } | |||
3766 | ||||
3767 | void ScXMLExport::WriteCalculationSettings(const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc) | |||
3768 | { | |||
3769 | uno::Reference<beans::XPropertySet> xPropertySet(xSpreadDoc, uno::UNO_QUERY); | |||
3770 | if (!xPropertySet.is()) | |||
3771 | return; | |||
3772 | ||||
3773 | bool bCalcAsShown (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_CALCASSHOWN"CalcAsShown") )); | |||
3774 | bool bIgnoreCase (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_IGNORECASE"IgnoreCase") )); | |||
3775 | bool bLookUpLabels (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_LOOKUPLABELS"LookUpLabels") )); | |||
3776 | bool bMatchWholeCell (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_MATCHWHOLE"MatchWholeCell") )); | |||
3777 | bool bUseRegularExpressions (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_REGEXENABLED"RegularExpressions") )); | |||
3778 | bool bUseWildcards (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_WILDCARDSENABLED"Wildcards") )); | |||
3779 | if (bUseWildcards && bUseRegularExpressions) | |||
3780 | bUseRegularExpressions = false; // mutually exclusive, wildcards take precedence | |||
3781 | bool bIsIterationEnabled (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_ITERENABLED"IsIterationEnabled") )); | |||
3782 | sal_uInt16 nYear2000 (pDoc ? pDoc->GetDocOptions().GetYear2000() : 0); | |||
3783 | sal_Int32 nIterationCount(100); | |||
3784 | xPropertySet->getPropertyValue( SC_UNO_ITERCOUNT"IterationCount" ) >>= nIterationCount; | |||
3785 | double fIterationEpsilon = 0; | |||
3786 | xPropertySet->getPropertyValue( SC_UNO_ITEREPSILON"IterationEpsilon" ) >>= fIterationEpsilon; | |||
3787 | util::Date aNullDate; | |||
3788 | xPropertySet->getPropertyValue( SC_UNO_NULLDATE"NullDate" ) >>= aNullDate; | |||
3789 | if (!(bCalcAsShown || bIgnoreCase || !bLookUpLabels || !bMatchWholeCell || !bUseRegularExpressions || | |||
3790 | bUseWildcards || | |||
3791 | bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001) || | |||
3792 | aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 || nYear2000 != 1930)) | |||
3793 | return; | |||
3794 | ||||
3795 | if (bIgnoreCase) | |||
3796 | AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_FALSE); | |||
3797 | if (bCalcAsShown) | |||
3798 | AddAttribute(XML_NAMESPACE_TABLE, XML_PRECISION_AS_SHOWN, XML_TRUE); | |||
3799 | if (!bMatchWholeCell) | |||
3800 | AddAttribute(XML_NAMESPACE_TABLE, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL, XML_FALSE); | |||
3801 | if (!bLookUpLabels) | |||
3802 | AddAttribute(XML_NAMESPACE_TABLE, XML_AUTOMATIC_FIND_LABELS, XML_FALSE); | |||
3803 | if (!bUseRegularExpressions) | |||
3804 | AddAttribute(XML_NAMESPACE_TABLE, XML_USE_REGULAR_EXPRESSIONS, XML_FALSE); | |||
3805 | if (bUseWildcards) | |||
3806 | AddAttribute(XML_NAMESPACE_TABLE, XML_USE_WILDCARDS, XML_TRUE); | |||
3807 | if (nYear2000 != 1930) | |||
3808 | { | |||
3809 | AddAttribute(XML_NAMESPACE_TABLE, XML_NULL_YEAR, OUString::number(nYear2000)); | |||
3810 | } | |||
3811 | SvXMLElementExport aCalcSettings(*this, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, true, true); | |||
3812 | { | |||
3813 | if (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899) | |||
3814 | { | |||
3815 | OUStringBuffer sDate; | |||
3816 | SvXMLUnitConverter::convertDateTime(sDate, 0.0, aNullDate); | |||
3817 | AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_VALUE, sDate.makeStringAndClear()); | |||
3818 | SvXMLElementExport aElemNullDate(*this, XML_NAMESPACE_TABLE, XML_NULL_DATE, true, true); | |||
3819 | } | |||
3820 | if (bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001)) | |||
3821 | { | |||
3822 | if (bIsIterationEnabled) | |||
3823 | AddAttribute(XML_NAMESPACE_TABLE, XML_STATUS, XML_ENABLE); | |||
3824 | if (nIterationCount != 100) | |||
3825 | { | |||
3826 | AddAttribute(XML_NAMESPACE_TABLE, XML_STEPS, OUString::number(nIterationCount)); | |||
3827 | } | |||
3828 | if (!::rtl::math::approxEqual(fIterationEpsilon, 0.001)) | |||
3829 | { | |||
3830 | OUStringBuffer sBuffer; | |||
3831 | ::sax::Converter::convertDouble(sBuffer, | |||
3832 | fIterationEpsilon); | |||
3833 | AddAttribute(XML_NAMESPACE_TABLE, XML_MAXIMUM_DIFFERENCE, sBuffer.makeStringAndClear()); | |||
3834 | } | |||
3835 | SvXMLElementExport aElemIteration(*this, XML_NAMESPACE_TABLE, XML_ITERATION, true, true); | |||
3836 | } | |||
3837 | } | |||
3838 | } | |||
3839 | ||||
3840 | void ScXMLExport::WriteTableSource() | |||
3841 | { | |||
3842 | uno::Reference <sheet::XSheetLinkable> xLinkable (xCurrentTable, uno::UNO_QUERY); | |||
3843 | if (!(xLinkable.is() && GetModel().is())) | |||
3844 | return; | |||
3845 | ||||
3846 | sheet::SheetLinkMode nMode (xLinkable->getLinkMode()); | |||
3847 | if (nMode == sheet::SheetLinkMode_NONE) | |||
3848 | return; | |||
3849 | ||||
3850 | OUString sLink (xLinkable->getLinkUrl()); | |||
3851 | uno::Reference <beans::XPropertySet> xProps (GetModel(), uno::UNO_QUERY); | |||
3852 | if (!xProps.is()) | |||
3853 | return; | |||
3854 | ||||
3855 | uno::Reference <container::XIndexAccess> xIndex(xProps->getPropertyValue(SC_UNO_SHEETLINKS"SheetLinks"), uno::UNO_QUERY); | |||
3856 | if (!xIndex.is()) | |||
3857 | return; | |||
3858 | ||||
3859 | sal_Int32 nCount(xIndex->getCount()); | |||
3860 | if (!nCount) | |||
3861 | return; | |||
3862 | ||||
3863 | bool bFound(false); | |||
3864 | uno::Reference <beans::XPropertySet> xLinkProps; | |||
3865 | for (sal_Int32 i = 0; (i < nCount) && !bFound; ++i) | |||
3866 | { | |||
3867 | xLinkProps.set(xIndex->getByIndex(i), uno::UNO_QUERY); | |||
3868 | if (xLinkProps.is()) | |||
3869 | { | |||
3870 | OUString sNewLink; | |||
3871 | if (xLinkProps->getPropertyValue(SC_UNONAME_LINKURL"Url") >>= sNewLink) | |||
3872 | bFound = sLink == sNewLink; | |||
3873 | } | |||
3874 | } | |||
3875 | if (!(bFound && xLinkProps.is())) | |||
3876 | return; | |||
3877 | ||||
3878 | OUString sFilter; | |||
3879 | OUString sFilterOptions; | |||
3880 | OUString sTableName (xLinkable->getLinkSheetName()); | |||
3881 | sal_Int32 nRefresh(0); | |||
3882 | xLinkProps->getPropertyValue(SC_UNONAME_FILTER"Filter") >>= sFilter; | |||
3883 | xLinkProps->getPropertyValue(SC_UNONAME_FILTOPT"FilterOptions") >>= sFilterOptions; | |||
3884 | xLinkProps->getPropertyValue(SC_UNONAME_REFDELAY"RefreshDelay") >>= nRefresh; | |||
3885 | if (sLink.isEmpty()) | |||
3886 | return; | |||
3887 | ||||
3888 | AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); | |||
3889 | AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink)); | |||
3890 | if (!sTableName.isEmpty()) | |||
3891 | AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName); | |||
3892 | if (!sFilter.isEmpty()) | |||
3893 | AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, sFilter); | |||
3894 | if (!sFilterOptions.isEmpty()) | |||
3895 | AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, sFilterOptions); | |||
3896 | if (nMode != sheet::SheetLinkMode_NORMAL) | |||
3897 | AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY); | |||
3898 | if( nRefresh ) | |||
3899 | { | |||
3900 | OUStringBuffer sBuffer; | |||
3901 | ::sax::Converter::convertDuration( sBuffer, | |||
3902 | static_cast<double>(nRefresh) / 86400 ); | |||
3903 | AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() ); | |||
3904 | } | |||
3905 | SvXMLElementExport aSourceElem(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, true, true); | |||
3906 | } | |||
3907 | ||||
3908 | // core implementation | |||
3909 | void ScXMLExport::WriteScenario() | |||
3910 | { | |||
3911 | if (!(pDoc && pDoc->IsScenario(static_cast<SCTAB>(nCurrentTable)))) | |||
3912 | return; | |||
3913 | ||||
3914 | OUString sComment; | |||
3915 | Color aColor; | |||
3916 | ScScenarioFlags nFlags; | |||
3917 | pDoc->GetScenarioData(static_cast<SCTAB>(nCurrentTable), sComment, aColor, nFlags); | |||
3918 | if (!(nFlags & ScScenarioFlags::ShowFrame)) | |||
3919 | AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_FALSE); | |||
3920 | OUStringBuffer aBuffer; | |||
3921 | ::sax::Converter::convertColor(aBuffer, aColor); | |||
3922 | AddAttribute(XML_NAMESPACE_TABLE, XML_BORDER_COLOR, aBuffer.makeStringAndClear()); | |||
3923 | if (!(nFlags & ScScenarioFlags::TwoWay)) | |||
3924 | AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_FALSE); | |||
3925 | if (!(nFlags & ScScenarioFlags::Attrib)) | |||
3926 | AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_FALSE); | |||
3927 | if (nFlags & ScScenarioFlags::Value) | |||
3928 | AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_FALSE); | |||
3929 | if (nFlags & ScScenarioFlags::Protected) | |||
3930 | AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE); | |||
3931 | ::sax::Converter::convertBool(aBuffer, | |||
3932 | pDoc->IsActiveScenario(static_cast<SCTAB>(nCurrentTable))); | |||
3933 | AddAttribute(XML_NAMESPACE_TABLE, XML_IS_ACTIVE, aBuffer.makeStringAndClear()); | |||
3934 | const ScRangeList* pRangeList = pDoc->GetScenarioRanges(static_cast<SCTAB>(nCurrentTable)); | |||
3935 | OUString sRangeListStr; | |||
3936 | ScRangeStringConverter::GetStringFromRangeList( sRangeListStr, pRangeList, pDoc, FormulaGrammar::CONV_OOO ); | |||
3937 | AddAttribute(XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, sRangeListStr); | |||
3938 | if (!sComment.isEmpty()) | |||
3939 | AddAttribute(XML_NAMESPACE_TABLE, XML_COMMENT, sComment); | |||
3940 | SvXMLElementExport aElem(*this, XML_NAMESPACE_TABLE, XML_SCENARIO, true, true); | |||
3941 | } | |||
3942 | ||||
3943 | void ScXMLExport::WriteTheLabelRanges( const uno::Reference< sheet::XSpreadsheetDocument >& xSpreadDoc ) | |||
3944 | { | |||
3945 | uno::Reference< beans::XPropertySet > xDocProp( xSpreadDoc, uno::UNO_QUERY ); | |||
3946 | if( !xDocProp.is() ) return; | |||
3947 | ||||
3948 | sal_Int32 nCount(0); | |||
3949 | uno::Reference< container::XIndexAccess > xColRangesIAccess(xDocProp->getPropertyValue( SC_UNO_COLLABELRNG"ColumnLabelRanges" ), uno::UNO_QUERY); | |||
3950 | if( xColRangesIAccess.is() ) | |||
3951 | nCount += xColRangesIAccess->getCount(); | |||
3952 | ||||
3953 | uno::Reference< container::XIndexAccess > xRowRangesIAccess(xDocProp->getPropertyValue( SC_UNO_ROWLABELRNG"RowLabelRanges" ), uno::UNO_QUERY); | |||
3954 | if( xRowRangesIAccess.is() ) | |||
3955 | nCount += xRowRangesIAccess->getCount(); | |||
3956 | ||||
3957 | if( nCount ) | |||
3958 | { | |||
3959 | SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGES, true, true ); | |||
3960 | WriteLabelRanges( xColRangesIAccess, true ); | |||
3961 | WriteLabelRanges( xRowRangesIAccess, false ); | |||
3962 | } | |||
3963 | } | |||
3964 | ||||
3965 | void ScXMLExport::WriteLabelRanges( const uno::Reference< container::XIndexAccess >& xRangesIAccess, bool bColumn ) | |||
3966 | { | |||
3967 | if( !xRangesIAccess.is() ) return; | |||
3968 | ||||
3969 | sal_Int32 nCount(xRangesIAccess->getCount()); | |||
3970 | for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) | |||
3971 | { | |||
3972 | uno::Reference< sheet::XLabelRange > xRange(xRangesIAccess->getByIndex( nIndex ), uno::UNO_QUERY); | |||
3973 | if( xRange.is() ) | |||
3974 | { | |||
3975 | OUString sRangeStr; | |||
3976 | table::CellRangeAddress aCellRange( xRange->getLabelArea() ); | |||
3977 | ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO ); | |||
3978 | AddAttribute( XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, sRangeStr ); | |||
3979 | aCellRange = xRange->getDataArea(); | |||
3980 | ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO ); | |||
3981 | AddAttribute( XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, sRangeStr ); | |||
3982 | AddAttribute( XML_NAMESPACE_TABLE, XML_ORIENTATION, bColumn ? XML_COLUMN : XML_ROW ); | |||
3983 | SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGE, true, true ); | |||
3984 | } | |||
3985 | } | |||
3986 | } | |||
3987 | ||||
3988 | void ScXMLExport::WriteNamedExpressions() | |||
3989 | { | |||
3990 | if (!pDoc) | |||
3991 | return; | |||
3992 | ScRangeName* pNamedRanges = pDoc->GetRangeName(); | |||
3993 | WriteNamedRange(pNamedRanges); | |||
3994 | } | |||
3995 | ||||
3996 | void ScXMLExport::WriteExternalDataMapping() | |||
3997 | { | |||
3998 | if (!pDoc) | |||
3999 | return; | |||
4000 | ||||
4001 | if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0) | |||
4002 | // Export this only for 1.2 extended and above. | |||
4003 | return; | |||
4004 | ||||
4005 | sc::ExternalDataMapper& rDataMapper = pDoc->GetExternalDataMapper(); | |||
4006 | auto& rDataSources = rDataMapper.getDataSources(); | |||
4007 | ||||
4008 | if (rDataSources.empty()) | |||
4009 | return; | |||
4010 | ||||
4011 | SvXMLElementExport aMappings(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_MAPPINGS, true, true); | |||
4012 | for (const auto& itr : rDataSources) | |||
4013 | { | |||
4014 | AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, itr.getURL()); | |||
4015 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_PROVIDER, itr.getProvider()); | |||
4016 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_DATA_FREQUENCY, OUString::number(sc::ExternalDataSource::getUpdateFrequency())); | |||
4017 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_ID, itr.getID()); | |||
4018 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_DATABASE_NAME, itr.getDBName()); | |||
4019 | ||||
4020 | SvXMLElementExport aMapping(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_MAPPING, true, true); | |||
4021 | // Add the data transformations | |||
4022 | WriteExternalDataTransformations(itr.getDataTransformation()); | |||
4023 | } | |||
4024 | } | |||
4025 | ||||
4026 | void ScXMLExport::WriteExternalDataTransformations(const std::vector<std::shared_ptr<sc::DataTransformation>>& aDataTransformations) | |||
4027 | { | |||
4028 | SvXMLElementExport aTransformations(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_TRANSFORMATIONS, true, true); | |||
4029 | for (auto& itr : aDataTransformations) | |||
4030 | { | |||
4031 | sc::TransformationType aTransformationType = itr->getTransformationType(); | |||
4032 | ||||
4033 | switch(aTransformationType) | |||
4034 | { | |||
4035 | case sc::TransformationType::DELETE_TRANSFORMATION: | |||
4036 | { | |||
4037 | // Delete Columns Transformation | |||
4038 | std::shared_ptr<sc::ColumnRemoveTransformation> aDeleteTransformation = std::dynamic_pointer_cast<sc::ColumnRemoveTransformation>(itr); | |||
4039 | std::set<SCCOL> aColumns = aDeleteTransformation->getColumns(); | |||
4040 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_REMOVE_TRANSFORMATION, true, true); | |||
4041 | for(auto& col : aColumns) | |||
4042 | { | |||
4043 | // Add Columns | |||
4044 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); | |||
4045 | SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); | |||
4046 | } | |||
4047 | } | |||
4048 | break; | |||
4049 | case sc::TransformationType::SPLIT_TRANSFORMATION: | |||
4050 | { | |||
4051 | std::shared_ptr<sc::SplitColumnTransformation> aSplitTransformation = std::dynamic_pointer_cast<sc::SplitColumnTransformation>(itr); | |||
4052 | ||||
4053 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(aSplitTransformation->getColumn())); | |||
4054 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_SEPARATOR, OUString::number(aSplitTransformation->getSeparator())); | |||
4055 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_SPLIT_TRANSFORMATION, true, true); | |||
4056 | } | |||
4057 | break; | |||
4058 | case sc::TransformationType::MERGE_TRANSFORMATION: | |||
4059 | { | |||
4060 | // Merge Transformation | |||
4061 | std::shared_ptr<sc::MergeColumnTransformation> aMergeTransformation = std::dynamic_pointer_cast<sc::MergeColumnTransformation>(itr); | |||
4062 | std::set<SCCOL> aColumns = aMergeTransformation->getColumns(); | |||
4063 | ||||
4064 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MERGE_STRING, aMergeTransformation->getMergeString()); | |||
4065 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_MERGE_TRANSFORMATION, true, true); | |||
4066 | ||||
4067 | for(auto& col : aColumns) | |||
4068 | { | |||
4069 | // Columns | |||
4070 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); | |||
4071 | SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); | |||
4072 | } | |||
4073 | } | |||
4074 | break; | |||
4075 | case sc::TransformationType::SORT_TRANSFORMATION: | |||
4076 | { | |||
4077 | // Sort Transformation | |||
4078 | std::shared_ptr<sc::SortTransformation> aSortTransformation = std::dynamic_pointer_cast<sc::SortTransformation>(itr); | |||
4079 | ScSortParam aSortParam = aSortTransformation->getSortParam(); | |||
4080 | const sc::DocumentLinkManager& rMgr = pDoc->GetDocLinkManager(); | |||
4081 | const sc::DataStream* pStrm = rMgr.getDataStream(); | |||
4082 | if (!pStrm) | |||
4083 | // No data stream. | |||
4084 | return; | |||
4085 | ||||
4086 | // Streamed range | |||
4087 | ScRange aRange = pStrm->GetRange(); | |||
4088 | ||||
4089 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_SORT_TRANSFORMATION, true, true); | |||
4090 | ||||
4091 | writeSort(*this, aSortParam, aRange, pDoc); | |||
4092 | } | |||
4093 | break; | |||
4094 | case sc::TransformationType::TEXT_TRANSFORMATION: | |||
4095 | { | |||
4096 | // Text Transformation | |||
4097 | std::shared_ptr<sc::TextTransformation> aTextTransformation = std::dynamic_pointer_cast<sc::TextTransformation>(itr); | |||
4098 | ||||
4099 | sc::TEXT_TRANSFORM_TYPE aTextTransformType = aTextTransformation->getTextTransformationType(); | |||
4100 | ||||
4101 | switch ( aTextTransformType ) | |||
4102 | { | |||
4103 | case sc::TEXT_TRANSFORM_TYPE::TO_LOWER: | |||
4104 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_CASEMAP_LOWERCASE); | |||
4105 | break; | |||
4106 | case sc::TEXT_TRANSFORM_TYPE::TO_UPPER: | |||
4107 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_CASEMAP_UPPERCASE); | |||
4108 | break; | |||
4109 | case sc::TEXT_TRANSFORM_TYPE::CAPITALIZE: | |||
4110 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_CASEMAP_CAPITALIZE); | |||
4111 | break; | |||
4112 | case sc::TEXT_TRANSFORM_TYPE::TRIM: | |||
4113 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_TRIM); | |||
4114 | break; | |||
4115 | } | |||
4116 | ||||
4117 | std::set<SCCOL> aColumns = aTextTransformation->getColumns(); | |||
4118 | ||||
4119 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_TEXT_TRANSFORMATION, true, true); | |||
4120 | ||||
4121 | for(auto& col : aColumns) | |||
4122 | { | |||
4123 | // Columns | |||
4124 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); | |||
4125 | SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); | |||
4126 | } | |||
4127 | } | |||
4128 | break; | |||
4129 | case sc::TransformationType::AGGREGATE_FUNCTION: | |||
4130 | { | |||
4131 | // Aggregate Transformation | |||
4132 | std::shared_ptr<sc::AggregateFunction> aAggregateFunction = std::dynamic_pointer_cast<sc::AggregateFunction>(itr); | |||
4133 | std::set<SCCOL> aColumns = aAggregateFunction->getColumns(); | |||
4134 | ||||
4135 | sc::AGGREGATE_FUNCTION aAggregateType = aAggregateFunction->getAggregateType(); | |||
4136 | ||||
4137 | switch (aAggregateType) | |||
4138 | { | |||
4139 | case sc::AGGREGATE_FUNCTION::SUM: | |||
4140 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SUM); | |||
4141 | break; | |||
4142 | case sc::AGGREGATE_FUNCTION::AVERAGE: | |||
4143 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_AVERAGE); | |||
4144 | break; | |||
4145 | case sc::AGGREGATE_FUNCTION::MIN: | |||
4146 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MIN); | |||
4147 | break; | |||
4148 | case sc::AGGREGATE_FUNCTION::MAX: | |||
4149 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MAX); | |||
4150 | break; | |||
4151 | } | |||
4152 | ||||
4153 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT,XML_COLUMN_AGGREGATE_TRANSFORMATION, true, true); | |||
4154 | ||||
4155 | for(auto& col : aColumns) | |||
4156 | { | |||
4157 | // Columns | |||
4158 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); | |||
4159 | SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); | |||
4160 | } | |||
4161 | } | |||
4162 | break; | |||
4163 | case sc::TransformationType::NUMBER_TRANSFORMATION: | |||
4164 | { | |||
4165 | // Number Transformation | |||
4166 | std::shared_ptr<sc::NumberTransformation> aNumberTransformation = std::dynamic_pointer_cast<sc::NumberTransformation>(itr); | |||
4167 | ||||
4168 | sc::NUMBER_TRANSFORM_TYPE aNumberTransformType = aNumberTransformation->getNumberTransformationType(); | |||
4169 | ||||
4170 | switch ( aNumberTransformType ) | |||
4171 | { | |||
4172 | case sc::NUMBER_TRANSFORM_TYPE::ROUND: | |||
4173 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ROUND); | |||
4174 | break; | |||
4175 | case sc::NUMBER_TRANSFORM_TYPE::ROUND_UP: | |||
4176 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ROUND_UP); | |||
4177 | break; | |||
4178 | case sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN: | |||
4179 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ROUND_DOWN); | |||
4180 | break; | |||
4181 | case sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE: | |||
4182 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ABS); | |||
4183 | break; | |||
4184 | case sc::NUMBER_TRANSFORM_TYPE::LOG_E: | |||
4185 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_LOG); | |||
4186 | break; | |||
4187 | case sc::NUMBER_TRANSFORM_TYPE::LOG_10: | |||
4188 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_LOG_10); | |||
4189 | break; | |||
4190 | case sc::NUMBER_TRANSFORM_TYPE::CUBE: | |||
4191 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_CUBE); | |||
4192 | break; | |||
4193 | case sc::NUMBER_TRANSFORM_TYPE::SQUARE: | |||
4194 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SQUARE); | |||
4195 | break; | |||
4196 | case sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT: | |||
4197 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SQUARE_ROOT); | |||
4198 | break; | |||
4199 | case sc::NUMBER_TRANSFORM_TYPE::EXPONENT: | |||
4200 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_EXPONENTIAL); | |||
4201 | break; | |||
4202 | case sc::NUMBER_TRANSFORM_TYPE::IS_EVEN: | |||
4203 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_EVEN); | |||
4204 | break; | |||
4205 | case sc::NUMBER_TRANSFORM_TYPE::IS_ODD: | |||
4206 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ODD); | |||
4207 | break; | |||
4208 | case sc::NUMBER_TRANSFORM_TYPE::SIGN: | |||
4209 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SIGN); | |||
4210 | break; | |||
4211 | } | |||
4212 | ||||
4213 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_PRECISION, OUString::number(aNumberTransformation->getPrecision())); | |||
4214 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_NUMBER_TRANSFORMATION, true, true); | |||
4215 | ||||
4216 | std::set<SCCOL> aColumns = aNumberTransformation->getColumn(); | |||
4217 | for(auto& col : aColumns) | |||
4218 | { | |||
4219 | // Columns | |||
4220 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); | |||
4221 | SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); | |||
4222 | } | |||
4223 | } | |||
4224 | break; | |||
4225 | case sc::TransformationType::REMOVE_NULL_TRANSFORMATION: | |||
4226 | { | |||
4227 | // Replace Null Transformation | |||
4228 | std::shared_ptr<sc::ReplaceNullTransformation> aReplaceNullTransformation = std::dynamic_pointer_cast<sc::ReplaceNullTransformation>(itr); | |||
4229 | std::set<SCCOL> aColumns = aReplaceNullTransformation->getColumn(); | |||
4230 | ||||
4231 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_REPLACE_STRING, aReplaceNullTransformation->getReplaceString()); | |||
4232 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_REPLACENULL_TRANSFORMATION, true, true); | |||
4233 | ||||
4234 | for(auto& col : aColumns) | |||
4235 | { | |||
4236 | // Columns | |||
4237 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); | |||
4238 | SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); | |||
4239 | } | |||
4240 | } | |||
4241 | break; | |||
4242 | case sc::TransformationType::DATETIME_TRANSFORMATION: | |||
4243 | { | |||
4244 | // Number Transformation | |||
4245 | std::shared_ptr<sc::DateTimeTransformation> aDateTimeTransformation = std::dynamic_pointer_cast<sc::DateTimeTransformation>(itr); | |||
4246 | ||||
4247 | sc::DATETIME_TRANSFORMATION_TYPE aDateTimeTransformationType = aDateTimeTransformation->getDateTimeTransformationType(); | |||
4248 | ||||
4249 | switch ( aDateTimeTransformationType ) | |||
4250 | { | |||
4251 | case sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING: | |||
4252 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_DATE_STRING); | |||
4253 | break; | |||
4254 | case sc::DATETIME_TRANSFORMATION_TYPE::YEAR: | |||
4255 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_YEAR); | |||
4256 | break; | |||
4257 | case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR: | |||
4258 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_START_OF_YEAR); | |||
4259 | break; | |||
4260 | case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR: | |||
4261 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_END_OF_YEAR); | |||
4262 | break; | |||
4263 | case sc::DATETIME_TRANSFORMATION_TYPE::MONTH: | |||
4264 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MONTH); | |||
4265 | break; | |||
4266 | case sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME: | |||
4267 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MONTH_NAME); | |||
4268 | break; | |||
4269 | case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH: | |||
4270 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_START_OF_MONTH); | |||
4271 | break; | |||
4272 | case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH: | |||
4273 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_END_OF_MONTH); | |||
4274 | break; | |||
4275 | case sc::DATETIME_TRANSFORMATION_TYPE::DAY: | |||
4276 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_DAY); | |||
4277 | break; | |||
4278 | case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK: | |||
4279 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_DAY_OF_WEEK); | |||
4280 | break; | |||
4281 | case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR: | |||
4282 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_DAY_OF_YEAR); | |||
4283 | break; | |||
4284 | case sc::DATETIME_TRANSFORMATION_TYPE::QUARTER: | |||
4285 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_QUARTER); | |||
4286 | break; | |||
4287 | case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER: | |||
4288 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_START_OF_QUARTER); | |||
4289 | break; | |||
4290 | case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER: | |||
4291 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_END_OF_QUARTER); | |||
4292 | break; | |||
4293 | case sc::DATETIME_TRANSFORMATION_TYPE::TIME: | |||
4294 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_TIME); | |||
4295 | break; | |||
4296 | case sc::DATETIME_TRANSFORMATION_TYPE::HOUR: | |||
4297 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_HOUR); | |||
4298 | break; | |||
4299 | case sc::DATETIME_TRANSFORMATION_TYPE::MINUTE: | |||
4300 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MINUTE); | |||
4301 | break; | |||
4302 | case sc::DATETIME_TRANSFORMATION_TYPE::SECOND: | |||
4303 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SECONDS); | |||
4304 | break; | |||
4305 | } | |||
4306 | ||||
4307 | SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_DATETIME_TRANSFORMATION, true, true); | |||
4308 | ||||
4309 | std::set<SCCOL> aColumns = aDateTimeTransformation->getColumn(); | |||
4310 | for(auto& col : aColumns) | |||
4311 | { | |||
4312 | // Columns | |||
4313 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); | |||
4314 | SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); | |||
4315 | } | |||
4316 | } | |||
4317 | break; | |||
4318 | default: | |||
4319 | break; | |||
4320 | } | |||
4321 | } | |||
4322 | } | |||
4323 | ||||
4324 | void ScXMLExport::WriteDataStream() | |||
4325 | { | |||
4326 | if (!pDoc) | |||
4327 | return; | |||
4328 | ||||
4329 | SvtMiscOptions aMiscOptions; | |||
4330 | if (!aMiscOptions.IsExperimentalMode()) | |||
4331 | // Export this only in experimental mode. | |||
4332 | return; | |||
4333 | ||||
4334 | if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0) | |||
4335 | // Export this only for 1.2 extended and above. | |||
4336 | return; | |||
4337 | ||||
4338 | const sc::DocumentLinkManager& rMgr = pDoc->GetDocLinkManager(); | |||
4339 | const sc::DataStream* pStrm = rMgr.getDataStream(); | |||
4340 | if (!pStrm) | |||
4341 | // No data stream. | |||
4342 | return; | |||
4343 | ||||
4344 | // Source URL | |||
4345 | AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(pStrm->GetURL())); | |||
4346 | ||||
4347 | // Streamed range | |||
4348 | ScRange aRange = pStrm->GetRange(); | |||
4349 | OUString aRangeStr; | |||
4350 | ScRangeStringConverter::GetStringFromRange( | |||
4351 | aRangeStr, aRange, pDoc, formula::FormulaGrammar::CONV_OOO); | |||
4352 | AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aRangeStr); | |||
4353 | ||||
4354 | // Empty line refresh option. | |||
4355 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_EMPTY_LINE_REFRESH, pStrm->IsRefreshOnEmptyLine() ? XML_TRUE : XML_FALSE); | |||
4356 | ||||
4357 | // New data insertion position. Either top of bottom. Default to bottom. | |||
4358 | xmloff::token::XMLTokenEnum eInsertPosition = XML_BOTTOM; | |||
4359 | if (pStrm->GetMove() == sc::DataStream::MOVE_DOWN) | |||
4360 | eInsertPosition = XML_TOP; | |||
4361 | ||||
4362 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_INSERTION_POSITION, eInsertPosition); | |||
4363 | ||||
4364 | SvXMLElementExport aElem(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_STREAM_SOURCE, true, true); | |||
4365 | } | |||
4366 | ||||
4367 | void ScXMLExport::WriteNamedRange(ScRangeName* pRangeName) | |||
4368 | { | |||
4369 | //write a global or local ScRangeName | |||
4370 | SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, true, true); | |||
4371 | for (const auto& rxEntry : *pRangeName) | |||
4372 | { | |||
4373 | AddAttribute(sAttrName, rxEntry.second->GetName()); | |||
4374 | ||||
4375 | OUString sBaseCellAddress; | |||
4376 | rxEntry.second->ValidateTabRefs(); | |||
4377 | ScRangeStringConverter::GetStringFromAddress( sBaseCellAddress, rxEntry.second->GetPos(), pDoc, | |||
4378 | FormulaGrammar::CONV_OOO, ' ', false, ScRefFlags::ADDR_ABS_3D); | |||
4379 | AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, sBaseCellAddress); | |||
4380 | ||||
4381 | OUString sSymbol; | |||
4382 | rxEntry.second->GetSymbol(sSymbol, pDoc->GetStorageGrammar()); | |||
4383 | OUString sTempSymbol(sSymbol); | |||
4384 | ScRange aRange; | |||
4385 | if (rxEntry.second->IsReference(aRange)) | |||
4386 | { | |||
4387 | ||||
4388 | OUString sContent(sTempSymbol.copy(1, sTempSymbol.getLength() -2 )); | |||
4389 | AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sContent); | |||
4390 | ||||
4391 | sal_Int32 nRangeType = rxEntry.second->GetUnoType(); | |||
4392 | OUStringBuffer sBufferRangeType; | |||
4393 | if ((nRangeType & sheet::NamedRangeFlag::COLUMN_HEADER) == sheet::NamedRangeFlag::COLUMN_HEADER) | |||
4394 | sBufferRangeType.append(GetXMLToken(XML_REPEAT_COLUMN)); | |||
4395 | if ((nRangeType & sheet::NamedRangeFlag::ROW_HEADER) == sheet::NamedRangeFlag::ROW_HEADER) | |||
4396 | { | |||
4397 | if (!sBufferRangeType.isEmpty()) | |||
4398 | sBufferRangeType.append(" "); | |||
4399 | sBufferRangeType.append(GetXMLToken(XML_REPEAT_ROW)); | |||
4400 | } | |||
4401 | if ((nRangeType & sheet::NamedRangeFlag::FILTER_CRITERIA) == sheet::NamedRangeFlag::FILTER_CRITERIA) | |||
4402 | { | |||
4403 | if (!sBufferRangeType.isEmpty()) | |||
4404 | sBufferRangeType.append(" "); | |||
4405 | sBufferRangeType.append(GetXMLToken(XML_FILTER)); | |||
4406 | } | |||
4407 | if ((nRangeType & sheet::NamedRangeFlag::PRINT_AREA) == sheet::NamedRangeFlag::PRINT_AREA) | |||
4408 | { | |||
4409 | if (!sBufferRangeType.isEmpty()) | |||
4410 | sBufferRangeType.append(" "); | |||
4411 | sBufferRangeType.append(GetXMLToken(XML_PRINT_RANGE)); | |||
4412 | } | |||
4413 | OUString sRangeType = sBufferRangeType.makeStringAndClear(); | |||
4414 | if (!sRangeType.isEmpty()) | |||
4415 | AddAttribute(XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, sRangeType); | |||
4416 | SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_RANGE, true, true); | |||
4417 | ||||
4418 | } | |||
4419 | else | |||
4420 | { | |||
4421 | AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, sTempSymbol); | |||
4422 | SvXMLElementExport aElemNE(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, true, true); | |||
4423 | } | |||
4424 | } | |||
4425 | } | |||
4426 | ||||
4427 | namespace { | |||
4428 | ||||
4429 | OUString getCondFormatEntryType(const ScColorScaleEntry& rEntry, bool bFirst = true) | |||
4430 | { | |||
4431 | switch(rEntry.GetType()) | |||
4432 | { | |||
4433 | case COLORSCALE_MIN: | |||
4434 | return "minimum"; | |||
4435 | case COLORSCALE_MAX: | |||
4436 | return "maximum"; | |||
4437 | case COLORSCALE_PERCENT: | |||
4438 | return "percent"; | |||
4439 | case COLORSCALE_PERCENTILE: | |||
4440 | return "percentile"; | |||
4441 | case COLORSCALE_FORMULA: | |||
4442 | return "formula"; | |||
4443 | case COLORSCALE_VALUE: | |||
4444 | return "number"; | |||
4445 | case COLORSCALE_AUTO: | |||
4446 | // only important for data bars | |||
4447 | if(bFirst) | |||
4448 | return "auto-minimum"; | |||
4449 | else | |||
4450 | return "auto-maximum"; | |||
4451 | } | |||
4452 | return OUString(); | |||
4453 | } | |||
4454 | ||||
4455 | OUString getDateStringForType(condformat::ScCondFormatDateType eType) | |||
4456 | { | |||
4457 | switch(eType) | |||
4458 | { | |||
4459 | case condformat::TODAY: | |||
4460 | return "today"; | |||
4461 | case condformat::YESTERDAY: | |||
4462 | return "yesterday"; | |||
4463 | case condformat::TOMORROW: | |||
4464 | return "tomorrow"; | |||
4465 | case condformat::LAST7DAYS: | |||
4466 | return "last-7-days"; | |||
4467 | case condformat::THISWEEK: | |||
4468 | return "this-week"; | |||
4469 | case condformat::LASTWEEK: | |||
4470 | return "last-week"; | |||
4471 | case condformat::NEXTWEEK: | |||
4472 | return "next-week"; | |||
4473 | case condformat::THISMONTH: | |||
4474 | return "this-month"; | |||
4475 | case condformat::LASTMONTH: | |||
4476 | return "last-month"; | |||
4477 | case condformat::NEXTMONTH: | |||
4478 | return "next-month"; | |||
4479 | case condformat::THISYEAR: | |||
4480 | return "this-year"; | |||
4481 | case condformat::LASTYEAR: | |||
4482 | return "last-year"; | |||
4483 | case condformat::NEXTYEAR: | |||
4484 | return "next-year"; | |||
4485 | } | |||
4486 | ||||
4487 | return OUString(); | |||
4488 | } | |||
4489 | ||||
4490 | } | |||
4491 | ||||
4492 | void ScXMLExport::ExportConditionalFormat(SCTAB nTab) | |||
4493 | { | |||
4494 | ScConditionalFormatList* pCondFormatList = pDoc->GetCondFormList(nTab); | |||
4495 | if(!pCondFormatList) | |||
4496 | return; | |||
4497 | ||||
4498 | if (pCondFormatList->empty()) | |||
4499 | return; | |||
4500 | ||||
4501 | SvXMLElementExport aElementCondFormats(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITIONAL_FORMATS, true, true); | |||
4502 | ||||
4503 | for(const auto& rxCondFormat : *pCondFormatList) | |||
4504 | { | |||
4505 | OUString sRanges; | |||
4506 | const ScRangeList& rRangeList = rxCondFormat->GetRange(); | |||
4507 | ScRangeStringConverter::GetStringFromRangeList( sRanges, &rRangeList, pDoc, formula::FormulaGrammar::CONV_OOO ); | |||
4508 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TARGET_RANGE_ADDRESS, sRanges); | |||
4509 | SvXMLElementExport aElementCondFormat(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITIONAL_FORMAT, true, true); | |||
4510 | size_t nEntries = rxCondFormat->size(); | |||
4511 | for(size_t i = 0; i < nEntries; ++i) | |||
4512 | { | |||
4513 | const ScFormatEntry* pFormatEntry = rxCondFormat->GetEntry(i); | |||
4514 | if(pFormatEntry->GetType()==ScFormatEntry::Type::Condition) | |||
4515 | { | |||
4516 | const ScCondFormatEntry* pEntry = static_cast<const ScCondFormatEntry*>(pFormatEntry); | |||
4517 | OUStringBuffer aCond; | |||
4518 | ScAddress aPos = pEntry->GetSrcPos(); | |||
4519 | switch(pEntry->GetOperation()) | |||
4520 | { | |||
4521 | case ScConditionMode::Equal: | |||
4522 | aCond.append('='); | |||
4523 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4524 | break; | |||
4525 | case ScConditionMode::Less: | |||
4526 | aCond.append('<'); | |||
4527 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4528 | break; | |||
4529 | case ScConditionMode::Greater: | |||
4530 | aCond.append('>'); | |||
4531 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4532 | break; | |||
4533 | case ScConditionMode::EqLess: | |||
4534 | aCond.append("<="); | |||
4535 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4536 | break; | |||
4537 | case ScConditionMode::EqGreater: | |||
4538 | aCond.append(">="); | |||
4539 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4540 | break; | |||
4541 | case ScConditionMode::NotEqual: | |||
4542 | aCond.append("!="); | |||
4543 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4544 | break; | |||
4545 | case ScConditionMode::Between: | |||
4546 | aCond.append("between("); | |||
4547 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4548 | aCond.append(','); | |||
4549 | aCond.append(pEntry->GetExpression(aPos, 1, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4550 | aCond.append(')'); | |||
4551 | break; | |||
4552 | case ScConditionMode::NotBetween: | |||
4553 | aCond.append("not-between("); | |||
4554 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4555 | aCond.append(','); | |||
4556 | aCond.append(pEntry->GetExpression(aPos, 1, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4557 | aCond.append(')'); | |||
4558 | break; | |||
4559 | case ScConditionMode::Duplicate: | |||
4560 | aCond.append("duplicate"); | |||
4561 | break; | |||
4562 | case ScConditionMode::NotDuplicate: | |||
4563 | aCond.append("unique"); | |||
4564 | break; | |||
4565 | case ScConditionMode::Direct: | |||
4566 | aCond.append("formula-is("); | |||
4567 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4568 | aCond.append(')'); | |||
4569 | break; | |||
4570 | case ScConditionMode::Top10: | |||
4571 | aCond.append("top-elements("); | |||
4572 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4573 | aCond.append(")"); | |||
4574 | break; | |||
4575 | case ScConditionMode::Bottom10: | |||
4576 | aCond.append("bottom-elements("); | |||
4577 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4578 | aCond.append(")"); | |||
4579 | break; | |||
4580 | case ScConditionMode::TopPercent: | |||
4581 | aCond.append("top-percent("); | |||
4582 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4583 | aCond.append(")"); | |||
4584 | break; | |||
4585 | case ScConditionMode::BottomPercent: | |||
4586 | aCond.append("bottom-percent("); | |||
4587 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4588 | aCond.append(")"); | |||
4589 | break; | |||
4590 | case ScConditionMode::AboveAverage: | |||
4591 | aCond.append("above-average"); | |||
4592 | break; | |||
4593 | case ScConditionMode::BelowAverage: | |||
4594 | aCond.append("below-average"); | |||
4595 | break; | |||
4596 | case ScConditionMode::AboveEqualAverage: | |||
4597 | aCond.append("above-equal-average"); | |||
4598 | break; | |||
4599 | case ScConditionMode::BelowEqualAverage: | |||
4600 | aCond.append("below-equal-average"); | |||
4601 | break; | |||
4602 | case ScConditionMode::Error: | |||
4603 | aCond.append("is-error"); | |||
4604 | break; | |||
4605 | case ScConditionMode::NoError: | |||
4606 | aCond.append("is-no-error"); | |||
4607 | break; | |||
4608 | case ScConditionMode::BeginsWith: | |||
4609 | aCond.append("begins-with("); | |||
4610 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4611 | aCond.append(")"); | |||
4612 | break; | |||
4613 | case ScConditionMode::EndsWith: | |||
4614 | aCond.append("ends-with("); | |||
4615 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4616 | aCond.append(")"); | |||
4617 | break; | |||
4618 | case ScConditionMode::ContainsText: | |||
4619 | aCond.append("contains-text("); | |||
4620 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4621 | aCond.append(")"); | |||
4622 | break; | |||
4623 | case ScConditionMode::NotContainsText: | |||
4624 | aCond.append("not-contains-text("); | |||
4625 | aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); | |||
4626 | aCond.append(")"); | |||
4627 | break; | |||
4628 | case ScConditionMode::NONE: | |||
4629 | continue; | |||
4630 | default: | |||
4631 | SAL_WARN("sc", "unimplemented conditional format export")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "unimplemented conditional format export") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "4631" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "unimplemented conditional format export" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "unimplemented conditional format export"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "4631" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "unimplemented conditional format export") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "4631" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "unimplemented conditional format export" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "unimplemented conditional format export"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "4631" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
4632 | } | |||
4633 | OUString sStyle = ScStyleNameConversion::DisplayToProgrammaticName(pEntry->GetStyle(), SfxStyleFamily::Para); | |||
4634 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_APPLY_STYLE_NAME, sStyle); | |||
4635 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, aCond.makeStringAndClear()); | |||
4636 | ||||
4637 | OUString sBaseAddress; | |||
4638 | ScRangeStringConverter::GetStringFromAddress( sBaseAddress, aPos, pDoc,formula::FormulaGrammar::CONV_ODF ); | |||
4639 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_BASE_CELL_ADDRESS, sBaseAddress); | |||
4640 | SvXMLElementExport aElementCondEntry(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITION, true, true); | |||
4641 | } | |||
4642 | else if(pFormatEntry->GetType() == ScFormatEntry::Type::Colorscale) | |||
4643 | { | |||
4644 | SvXMLElementExport aElementColorScale(*this, XML_NAMESPACE_CALC_EXT, XML_COLOR_SCALE, true, true); | |||
4645 | const ScColorScaleFormat& rColorScale = static_cast<const ScColorScaleFormat&>(*pFormatEntry); | |||
4646 | for(const auto& rxItem : rColorScale) | |||
4647 | { | |||
4648 | if(rxItem->GetType() == COLORSCALE_FORMULA) | |||
4649 | { | |||
4650 | OUString sFormula = rxItem->GetFormula(formula::FormulaGrammar::GRAM_ODFF); | |||
4651 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula); | |||
4652 | } | |||
4653 | else | |||
4654 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(rxItem->GetValue())); | |||
4655 | ||||
4656 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*rxItem)); | |||
4657 | OUStringBuffer aBuffer; | |||
4658 | ::sax::Converter::convertColor(aBuffer, rxItem->GetColor()); | |||
4659 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLOR, aBuffer.makeStringAndClear()); | |||
4660 | SvXMLElementExport aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT, XML_COLOR_SCALE_ENTRY, true, true); | |||
4661 | } | |||
4662 | } | |||
4663 | else if(pFormatEntry->GetType() == ScFormatEntry::Type::Databar) | |||
4664 | { | |||
4665 | const ScDataBarFormatData* pFormatData = static_cast<const ScDataBarFormat&>(*pFormatEntry).GetDataBarData(); | |||
4666 | if(!pFormatData->mbGradient) | |||
4667 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_GRADIENT, XML_FALSE); | |||
4668 | if(pFormatData->mbOnlyBar) | |||
4669 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_SHOW_VALUE, XML_FALSE); | |||
4670 | ||||
4671 | if (pFormatData->mnMinLength != 0.0) | |||
4672 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MIN_LENGTH, OUString::number(pFormatData->mnMinLength)); | |||
4673 | ||||
4674 | if (pFormatData->mnMaxLength != 0.0) | |||
4675 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MAX_LENGTH, OUString::number(pFormatData->mnMaxLength)); | |||
4676 | ||||
4677 | if(pFormatData->mbNeg) | |||
4678 | { | |||
4679 | if(pFormatData->mpNegativeColor) | |||
4680 | { | |||
4681 | OUStringBuffer aBuffer; | |||
4682 | ::sax::Converter::convertColor(aBuffer, *pFormatData->mpNegativeColor); | |||
4683 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_NEGATIVE_COLOR, aBuffer.makeStringAndClear()); | |||
4684 | } | |||
4685 | else | |||
4686 | { | |||
4687 | OUStringBuffer aBuffer; | |||
4688 | ::sax::Converter::convertColor(aBuffer, COL_LIGHTRED); | |||
4689 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_NEGATIVE_COLOR, aBuffer.makeStringAndClear()); | |||
4690 | } | |||
4691 | } | |||
4692 | ||||
4693 | if(pFormatData->meAxisPosition != databar::AUTOMATIC) | |||
4694 | { | |||
4695 | if(pFormatData->meAxisPosition == databar::NONE) | |||
4696 | { | |||
4697 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_POSITION, OUString("none")); | |||
4698 | } | |||
4699 | else | |||
4700 | { | |||
4701 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_POSITION, OUString("middle")); | |||
4702 | } | |||
4703 | } | |||
4704 | ||||
4705 | OUStringBuffer aBuffer; | |||
4706 | ::sax::Converter::convertColor(aBuffer, pFormatData->maPositiveColor); | |||
4707 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_POSITIVE_COLOR, aBuffer.makeStringAndClear()); | |||
4708 | ||||
4709 | aBuffer.truncate(); | |||
4710 | ::sax::Converter::convertColor(aBuffer, pFormatData->maAxisColor); | |||
4711 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_COLOR, aBuffer.makeStringAndClear()); | |||
4712 | SvXMLElementExport aElementDataBar(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_BAR, true, true); | |||
4713 | ||||
4714 | { | |||
4715 | if(pFormatData->mpLowerLimit->GetType() == COLORSCALE_FORMULA) | |||
4716 | { | |||
4717 | OUString sFormula = pFormatData->mpLowerLimit->GetFormula(formula::FormulaGrammar::GRAM_ODFF); | |||
4718 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula); | |||
4719 | } | |||
4720 | else | |||
4721 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(pFormatData->mpLowerLimit->GetValue())); | |||
4722 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*pFormatData->mpLowerLimit)); | |||
4723 | SvXMLElementExport aElementDataBarEntryLower(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true); | |||
4724 | } | |||
4725 | ||||
4726 | { | |||
4727 | if(pFormatData->mpUpperLimit->GetType() == COLORSCALE_FORMULA) | |||
4728 | { | |||
4729 | OUString sFormula = pFormatData->mpUpperLimit->GetFormula(formula::FormulaGrammar::GRAM_ODFF); | |||
4730 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula); | |||
4731 | } | |||
4732 | else | |||
4733 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(pFormatData->mpUpperLimit->GetValue())); | |||
4734 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*pFormatData->mpUpperLimit, false)); | |||
4735 | SvXMLElementExport aElementDataBarEntryUpper(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true); | |||
4736 | } | |||
4737 | } | |||
4738 | else if(pFormatEntry->GetType() == ScFormatEntry::Type::Iconset) | |||
4739 | { | |||
4740 | const ScIconSetFormat& rIconSet = static_cast<const ScIconSetFormat&>(*pFormatEntry); | |||
4741 | OUString aIconSetName = OUString::createFromAscii(ScIconSetFormat::getIconSetName(rIconSet.GetIconSetData()->eIconSetType)); | |||
4742 | AddAttribute( XML_NAMESPACE_CALC_EXT, XML_ICON_SET_TYPE, aIconSetName ); | |||
4743 | if (rIconSet.GetIconSetData()->mbCustom) | |||
4744 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_CUSTOM, OUString::boolean(true)); | |||
4745 | ||||
4746 | SvXMLElementExport aElementColorScale(*this, XML_NAMESPACE_CALC_EXT, XML_ICON_SET, true, true); | |||
4747 | ||||
4748 | if (rIconSet.GetIconSetData()->mbCustom) | |||
4749 | { | |||
4750 | for (const auto& [rType, rIndex] : rIconSet.GetIconSetData()->maCustomVector) | |||
4751 | { | |||
4752 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_CUSTOM_ICONSET_NAME, OUString::createFromAscii(ScIconSetFormat::getIconSetName(rType))); | |||
4753 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_CUSTOM_ICONSET_INDEX, OUString::number(rIndex)); | |||
4754 | SvXMLElementExport aCustomIcon(*this, XML_NAMESPACE_CALC_EXT, XML_CUSTOM_ICONSET, true, true); | |||
4755 | } | |||
4756 | ||||
4757 | } | |||
4758 | ||||
4759 | if(!rIconSet.GetIconSetData()->mbShowValue) | |||
4760 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_SHOW_VALUE, XML_FALSE); | |||
4761 | for (auto const& it : rIconSet) | |||
4762 | { | |||
4763 | if(it->GetType() == COLORSCALE_FORMULA) | |||
4764 | { | |||
4765 | OUString sFormula = it->GetFormula(formula::FormulaGrammar::GRAM_ODFF); | |||
4766 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula); | |||
4767 | } | |||
4768 | else | |||
4769 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(it->GetValue())); | |||
4770 | ||||
4771 | AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*it)); | |||
4772 | SvXMLElementExport aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true); | |||
4773 | } | |||
4774 | } | |||
4775 | else if(pFormatEntry->GetType() == ScFormatEntry::Type::Date) | |||
4776 | { | |||
4777 | const ScCondDateFormatEntry& rDateFormat = static_cast<const ScCondDateFormatEntry&>(*pFormatEntry); | |||
4778 | OUString aDateType = getDateStringForType(rDateFormat.GetDateType()); | |||
4779 | OUString aStyleName = ScStyleNameConversion::DisplayToProgrammaticName(rDateFormat.GetStyleName(), SfxStyleFamily::Para ); | |||
4780 | AddAttribute( XML_NAMESPACE_CALC_EXT, XML_STYLE, aStyleName); | |||
4781 | AddAttribute( XML_NAMESPACE_CALC_EXT, XML_DATE, aDateType); | |||
4782 | SvXMLElementExport aElementDateFormat(*this, XML_NAMESPACE_CALC_EXT, XML_DATE_IS, true, true); | |||
4783 | } | |||
4784 | } | |||
4785 | } | |||
4786 | } | |||
4787 | ||||
4788 | void ScXMLExport::WriteExternalRefCaches() | |||
4789 | { | |||
4790 | if (!pDoc) | |||
4791 | return; | |||
4792 | ||||
4793 | ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); | |||
4794 | pRefMgr->resetSrcFileData(GetOrigFileName()); | |||
4795 | sal_uInt16 nCount = pRefMgr->getExternalFileCount(); | |||
4796 | for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId) | |||
4797 | { | |||
4798 | const OUString* pUrl = pRefMgr->getExternalFileName(nFileId); | |||
4799 | if (!pUrl) | |||
4800 | continue; | |||
4801 | ||||
4802 | vector<OUString> aTabNames; | |||
4803 | pRefMgr->getAllCachedTableNames(nFileId, aTabNames); | |||
4804 | if (aTabNames.empty()) | |||
4805 | continue; | |||
4806 | ||||
4807 | for (const auto& rTabName : aTabNames) | |||
4808 | { | |||
4809 | ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, rTabName, false); | |||
4810 | if (!pTable || !pTable->isReferenced()) | |||
4811 | continue; | |||
4812 | ||||
4813 | AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, "'" + *pUrl + "'#" + rTabName); | |||
4814 | AddAttribute(XML_NAMESPACE_TABLE, XML_PRINT, GetXMLToken(XML_FALSE)); | |||
4815 | AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sExternalRefTabStyleName); | |||
4816 | SvXMLElementExport aElemTable(*this, XML_NAMESPACE_TABLE, XML_TABLE, true, true); | |||
4817 | { | |||
4818 | const ScExternalRefManager::SrcFileData* pExtFileData = pRefMgr->getExternalFileData(nFileId); | |||
4819 | if (pExtFileData) | |||
4820 | { | |||
4821 | OUString aRelUrl; | |||
4822 | if (!pExtFileData->maRelativeName.isEmpty()) | |||
4823 | aRelUrl = pExtFileData->maRelativeName; | |||
4824 | else | |||
4825 | aRelUrl = GetRelativeReference(pExtFileData->maRelativeName); | |||
4826 | AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); | |||
4827 | AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl); | |||
4828 | AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, rTabName); | |||
4829 | if (!pExtFileData->maFilterName.isEmpty()) | |||
4830 | AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, pExtFileData->maFilterName); | |||
4831 | if (!pExtFileData->maFilterOptions.isEmpty()) | |||
4832 | AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, pExtFileData->maFilterOptions); | |||
4833 | AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY); | |||
4834 | } | |||
4835 | SvXMLElementExport aElemTableSource(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, true, true); | |||
4836 | } | |||
4837 | ||||
4838 | // Determine maximum column count of used area, for repeated cells. | |||
4839 | SCCOL nMaxColsUsed = 1; // assume that there is at least one cell somewhere... | |||
4840 | vector<SCROW> aRows; | |||
4841 | pTable->getAllRows(aRows); | |||
4842 | for (SCROW nRow : aRows) | |||
4843 | { | |||
4844 | vector<SCCOL> aCols; | |||
4845 | pTable->getAllCols(nRow, aCols); | |||
4846 | if (!aCols.empty()) | |||
4847 | { | |||
4848 | SCCOL nCol = aCols.back(); | |||
4849 | if (nMaxColsUsed <= nCol) | |||
4850 | nMaxColsUsed = nCol + 1; | |||
4851 | } | |||
4852 | } | |||
4853 | ||||
4854 | // Column definitions have to be present to make a valid file | |||
4855 | { | |||
4856 | if (nMaxColsUsed > 1) | |||
4857 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, | |||
4858 | OUString::number(nMaxColsUsed)); | |||
4859 | SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, true, true); | |||
4860 | } | |||
4861 | ||||
4862 | // Write cache content for this table. | |||
4863 | SCROW nLastRow = 0; | |||
4864 | bool bFirstRow = true; | |||
4865 | for (SCROW nRow : aRows) | |||
4866 | { | |||
4867 | if (bFirstRow) | |||
4868 | { | |||
4869 | if (nRow > 0) | |||
4870 | { | |||
4871 | if (nRow > 1) | |||
4872 | { | |||
4873 | OUString aVal = OUString::number(nRow); | |||
4874 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal); | |||
4875 | } | |||
4876 | SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true); | |||
4877 | OUString aVal = OUString::number(static_cast<sal_Int32>(nMaxColsUsed)); | |||
4878 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal); | |||
4879 | SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); | |||
4880 | } | |||
4881 | } | |||
4882 | else | |||
4883 | { | |||
4884 | SCROW nRowGap = nRow - nLastRow; | |||
4885 | if (nRowGap > 1) | |||
4886 | { | |||
4887 | if (nRowGap > 2) | |||
4888 | { | |||
4889 | OUString aVal = OUString::number(static_cast<sal_Int32>(nRowGap-1)); | |||
4890 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal); | |||
4891 | } | |||
4892 | SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true); | |||
4893 | OUString aVal = OUString::number(static_cast<sal_Int32>(nMaxColsUsed)); | |||
4894 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal); | |||
4895 | SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); | |||
4896 | } | |||
4897 | } | |||
4898 | SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true); | |||
4899 | ||||
4900 | vector<SCCOL> aCols; | |||
4901 | pTable->getAllCols(nRow, aCols); | |||
4902 | SCCOL nLastCol = 0; | |||
4903 | bool bFirstCol = true; | |||
4904 | for (SCCOL nCol : aCols) | |||
4905 | { | |||
4906 | if (bFirstCol) | |||
4907 | { | |||
4908 | if (nCol > 0) | |||
4909 | { | |||
4910 | if (nCol > 1) | |||
4911 | { | |||
4912 | OUString aVal = OUString::number(static_cast<sal_Int32>(nCol)); | |||
4913 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal); | |||
4914 | } | |||
4915 | SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); | |||
4916 | } | |||
4917 | } | |||
4918 | else | |||
4919 | { | |||
4920 | SCCOL nColGap = nCol - nLastCol; | |||
4921 | if (nColGap > 1) | |||
4922 | { | |||
4923 | if (nColGap > 2) | |||
4924 | { | |||
4925 | OUString aVal = OUString::number(static_cast<sal_Int32>(nColGap-1)); | |||
4926 | AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal); | |||
4927 | } | |||
4928 | SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); | |||
4929 | } | |||
4930 | } | |||
4931 | ||||
4932 | // Write out this cell. | |||
4933 | sal_uInt32 nNumFmt = 0; | |||
4934 | ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow, &nNumFmt); | |||
4935 | OUString aStrVal; | |||
4936 | if (pToken) | |||
4937 | { | |||
4938 | sal_Int32 nIndex = GetNumberFormatStyleIndex(nNumFmt); | |||
4939 | if (nIndex >= 0) | |||
4940 | { | |||
4941 | const OUString & aStyleName = pCellStyles->GetStyleNameByIndex(nIndex, true); | |||
4942 | AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, aStyleName); | |||
4943 | } | |||
4944 | ||||
4945 | switch(pToken->GetType()) | |||
4946 | { | |||
4947 | case svDouble: | |||
4948 | { | |||
4949 | AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT); | |||
4950 | OUStringBuffer aVal; | |||
4951 | aVal.append(pToken->GetDouble()); | |||
4952 | aStrVal = aVal.makeStringAndClear(); | |||
4953 | AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aStrVal); | |||
4954 | } | |||
4955 | break; | |||
4956 | case svString: | |||
4957 | { | |||
4958 | AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING); | |||
4959 | aStrVal = pToken->GetString().getString(); | |||
4960 | } | |||
4961 | break; | |||
4962 | default: | |||
4963 | ; | |||
4964 | } | |||
4965 | } | |||
4966 | SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); | |||
4967 | SvXMLElementExport aElemText(*this, XML_NAMESPACE_TEXT, XML_P, true, false); | |||
4968 | Characters(aStrVal); | |||
4969 | ||||
4970 | nLastCol = nCol; | |||
4971 | bFirstCol = false; | |||
4972 | } | |||
4973 | nLastRow = nRow; | |||
4974 | bFirstRow = false; | |||
4975 | } | |||
4976 | } | |||
4977 | } | |||
4978 | } | |||
4979 | ||||
4980 | // core implementation | |||
4981 | void ScXMLExport::WriteConsolidation() | |||
4982 | { | |||
4983 | if (!pDoc) | |||
4984 | return; | |||
4985 | ||||
4986 | const ScConsolidateParam* pCons(pDoc->GetConsolidateDlgData()); | |||
4987 | if( !pCons ) | |||
4988 | return; | |||
4989 | ||||
4990 | OUString sStrData; | |||
4991 | ||||
4992 | ScXMLConverter::GetStringFromFunction( sStrData, pCons->eFunction ); | |||
4993 | AddAttribute( XML_NAMESPACE_TABLE, XML_FUNCTION, sStrData ); | |||
4994 | ||||
4995 | sStrData.clear(); | |||
4996 | for( sal_Int32 nIndex = 0; nIndex < pCons->nDataAreaCount; ++nIndex ) | |||
4997 | ScRangeStringConverter::GetStringFromArea( sStrData, pCons->pDataAreas[ nIndex ], pDoc, FormulaGrammar::CONV_OOO, ' ', true ); | |||
4998 | AddAttribute( XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, sStrData ); | |||
4999 | ||||
5000 | ScRangeStringConverter::GetStringFromAddress( sStrData, ScAddress( pCons->nCol, pCons->nRow, pCons->nTab ), pDoc, FormulaGrammar::CONV_OOO ); | |||
5001 | AddAttribute( XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, sStrData ); | |||
5002 | ||||
5003 | if( pCons->bByCol && !pCons->bByRow ) | |||
5004 | AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_COLUMN ); | |||
5005 | else if( !pCons->bByCol && pCons->bByRow ) | |||
5006 | AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_ROW ); | |||
5007 | else if( pCons->bByCol && pCons->bByRow ) | |||
5008 | AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_BOTH ); | |||
5009 | ||||
5010 | if( pCons->bReferenceData ) | |||
5011 | AddAttribute( XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TRUE ); | |||
5012 | ||||
5013 | SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CONSOLIDATION, true, true ); | |||
5014 | } | |||
5015 | ||||
5016 | SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool() | |||
5017 | { | |||
5018 | return new ScXMLAutoStylePoolP(*this); | |||
5019 | } | |||
5020 | ||||
5021 | XMLPageExport* ScXMLExport::CreatePageExport() | |||
5022 | { | |||
5023 | return new XMLTableMasterPageExport( *this ); | |||
5024 | } | |||
5025 | ||||
5026 | void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue>& rProps) | |||
5027 | { | |||
5028 | ScChangeViewSettings* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : nullptr); | |||
5029 | if (!pViewSettings) | |||
5030 | return; | |||
5031 | ||||
5032 | sal_Int32 nChangePos(rProps.getLength()); | |||
5033 | rProps.realloc(nChangePos + 1); | |||
5034 | beans::PropertyValue* pProps(rProps.getArray()); | |||
5035 | ||||
5036 | uno::Sequence<beans::PropertyValue> aChangeProps(SC_VIEWCHANGES_COUNT13); | |||
5037 | beans::PropertyValue* pChangeProps(aChangeProps.getArray()); | |||
5038 | pChangeProps[SC_SHOW_CHANGES0].Name = "ShowChanges"; | |||
5039 | pChangeProps[SC_SHOW_CHANGES0].Value <<= pViewSettings->ShowChanges(); | |||
5040 | pChangeProps[SC_SHOW_ACCEPTED_CHANGES1].Name = "ShowAcceptedChanges"; | |||
5041 | pChangeProps[SC_SHOW_ACCEPTED_CHANGES1].Value <<= pViewSettings->IsShowAccepted(); | |||
5042 | pChangeProps[SC_SHOW_REJECTED_CHANGES2].Name = "ShowRejectedChanges"; | |||
5043 | pChangeProps[SC_SHOW_REJECTED_CHANGES2].Value <<= pViewSettings->IsShowRejected(); | |||
5044 | pChangeProps[SC_SHOW_CHANGES_BY_DATETIME3].Name = "ShowChangesByDatetime"; | |||
5045 | pChangeProps[SC_SHOW_CHANGES_BY_DATETIME3].Value <<= pViewSettings->HasDate(); | |||
5046 | pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE4].Name = "ShowChangesByDatetimeMode"; | |||
5047 | pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE4].Value <<= static_cast<sal_Int16>(pViewSettings->GetTheDateMode()); | |||
5048 | pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME5].Name = "ShowChangesByDatetimeFirstDatetime"; | |||
5049 | pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME5].Value <<= pViewSettings->GetTheFirstDateTime().GetUNODateTime(); | |||
5050 | pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME6].Name = "ShowChangesByDatetimeSecondDatetime"; | |||
5051 | pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME6].Value <<= pViewSettings->GetTheLastDateTime().GetUNODateTime(); | |||
5052 | pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR7].Name = "ShowChangesByAuthor"; | |||
5053 | pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR7].Value <<= pViewSettings->HasAuthor(); | |||
5054 | pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME8].Name = "ShowChangesByAuthorName"; | |||
5055 | pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME8].Value <<= pViewSettings->GetTheAuthorToShow(); | |||
5056 | pChangeProps[SC_SHOW_CHANGES_BY_COMMENT9].Name = "ShowChangesByComment"; | |||
5057 | pChangeProps[SC_SHOW_CHANGES_BY_COMMENT9].Value <<= pViewSettings->HasComment(); | |||
5058 | pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT10].Name = "ShowChangesByCommentText"; | |||
5059 | pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT10].Value <<= pViewSettings->GetTheComment(); | |||
5060 | pChangeProps[SC_SHOW_CHANGES_BY_RANGES11].Name = "ShowChangesByRanges"; | |||
5061 | pChangeProps[SC_SHOW_CHANGES_BY_RANGES11].Value <<= pViewSettings->HasRange(); | |||
5062 | OUString sRangeList; | |||
5063 | ScRangeStringConverter::GetStringFromRangeList(sRangeList, &(pViewSettings->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO); | |||
5064 | pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST12].Name = "ShowChangesByRangesList"; | |||
5065 | pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST12].Value <<= sRangeList; | |||
5066 | ||||
5067 | pProps[nChangePos].Name = "TrackedChangesViewSettings"; | |||
5068 | pProps[nChangePos].Value <<= aChangeProps; | |||
5069 | } | |||
5070 | ||||
5071 | void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps) | |||
5072 | { | |||
5073 | if (GetModel().is()) | |||
5074 | { | |||
5075 | rProps.realloc(4); | |||
5076 | beans::PropertyValue* pProps(rProps.getArray()); | |||
5077 | ScModelObj* pDocObj(comphelper::getUnoTunnelImplementation<ScModelObj>( GetModel() )); | |||
5078 | if (pDocObj) | |||
5079 | { | |||
5080 | SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject(); | |||
5081 | if (pEmbeddedObj) | |||
5082 | { | |||
5083 | tools::Rectangle aRect(pEmbeddedObj->GetVisArea()); | |||
5084 | sal_uInt16 i(0); | |||
5085 | pProps[i].Name = "VisibleAreaTop"; | |||
5086 | pProps[i].Value <<= static_cast<sal_Int32>(aRect.getY()); | |||
5087 | pProps[++i].Name = "VisibleAreaLeft"; | |||
5088 | pProps[i].Value <<= static_cast<sal_Int32>(aRect.getX()); | |||
5089 | pProps[++i].Name = "VisibleAreaWidth"; | |||
5090 | pProps[i].Value <<= static_cast<sal_Int32>(aRect.getWidth()); | |||
5091 | pProps[++i].Name = "VisibleAreaHeight"; | |||
5092 | pProps[i].Value <<= static_cast<sal_Int32>(aRect.getHeight()); | |||
5093 | } | |||
5094 | } | |||
5095 | } | |||
5096 | GetChangeTrackViewSettings(rProps); | |||
5097 | } | |||
5098 | ||||
5099 | void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps) | |||
5100 | { | |||
5101 | if (!GetModel().is()) | |||
5102 | return; | |||
5103 | ||||
5104 | uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); | |||
5105 | if (!xMultiServiceFactory.is()) | |||
5106 | return; | |||
5107 | ||||
5108 | uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance("com.sun.star.comp.SpreadsheetSettings"), uno::UNO_QUERY); | |||
5109 | if (xProperties.is()) | |||
5110 | SvXMLUnitConverter::convertPropertySet(rProps, xProperties); | |||
5111 | ||||
5112 | sal_Int32 nPropsToAdd = 0; | |||
5113 | OUStringBuffer aTrackedChangesKey; | |||
5114 | if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected()) | |||
5115 | { | |||
5116 | ::comphelper::Base64::encode(aTrackedChangesKey, | |||
5117 | GetDocument()->GetChangeTrack()->GetProtection()); | |||
5118 | if (!aTrackedChangesKey.isEmpty()) | |||
5119 | ++nPropsToAdd; | |||
5120 | } | |||
5121 | ||||
5122 | bool bVBACompat = false; | |||
5123 | uno::Reference <container::XNameAccess> xCodeNameAccess; | |||
5124 | OSL_ENSURE( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" )do { if (true && (!(pDoc))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "5124" ": "), "%s", "ScXMLExport::GetConfigurationSettings - no ScDocument!" ); } } while (false); | |||
5125 | if( pDoc && pDoc->IsInVBAMode() ) | |||
5126 | { | |||
5127 | // VBA compatibility mode | |||
5128 | bVBACompat = true; | |||
5129 | ++nPropsToAdd; | |||
5130 | // code names | |||
5131 | xCodeNameAccess = new XMLCodeNameProvider( pDoc ); | |||
5132 | if( xCodeNameAccess->hasElements() ) | |||
5133 | ++nPropsToAdd; | |||
5134 | else | |||
5135 | xCodeNameAccess.clear(); | |||
5136 | } | |||
5137 | ||||
5138 | if( nPropsToAdd <= 0 ) | |||
5139 | return; | |||
5140 | ||||
5141 | sal_Int32 nCount(rProps.getLength()); | |||
5142 | rProps.realloc(nCount + nPropsToAdd); | |||
5143 | if (!aTrackedChangesKey.isEmpty()) | |||
5144 | { | |||
5145 | rProps[nCount].Name = "TrackedChangesProtectionKey"; | |||
5146 | rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear(); | |||
5147 | ++nCount; | |||
5148 | } | |||
5149 | if( bVBACompat ) | |||
5150 | { | |||
5151 | rProps[nCount].Name = "VBACompatibilityMode"; | |||
5152 | rProps[nCount].Value <<= bVBACompat; | |||
5153 | ++nCount; | |||
5154 | } | |||
5155 | if( xCodeNameAccess.is() ) | |||
5156 | { | |||
5157 | rProps[nCount].Name = "ScriptConfiguration"; | |||
5158 | rProps[nCount].Value <<= xCodeNameAccess; | |||
5159 | ++nCount; | |||
5160 | } | |||
5161 | } | |||
5162 | ||||
5163 | XMLShapeExport* ScXMLExport::CreateShapeExport() | |||
5164 | { | |||
5165 | return new ScXMLShapeExport(*this); | |||
5166 | } | |||
5167 | ||||
5168 | XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper() | |||
5169 | { | |||
5170 | if (!pNumberFormatAttributesExportHelper) | |||
5171 | pNumberFormatAttributesExportHelper.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this )); | |||
5172 | return pNumberFormatAttributesExportHelper.get(); | |||
5173 | } | |||
5174 | ||||
5175 | void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib) | |||
5176 | { | |||
5177 | for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib)) | |||
5178 | { | |||
5179 | const SvXMLAttrContainerItem *pUnknown(static_cast<const SvXMLAttrContainerItem *>(pItem)); | |||
5180 | if( pUnknown->GetAttrCount() > 0 ) | |||
5181 | { | |||
5182 | sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex()); | |||
5183 | while( USHRT_MAX(32767 *2 +1) != nIdx ) | |||
5184 | { | |||
5185 | if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 ) | |||
5186 | { | |||
5187 | const OUString& rPrefix = pUnknown->GetPrefix( nIdx ); | |||
5188 | // Add namespace declaration for unknown attributes if | |||
5189 | // there aren't existing ones for the prefix used by the | |||
5190 | // attributes | |||
5191 | GetNamespaceMap_().Add( rPrefix, | |||
5192 | pUnknown->GetNamespace( nIdx ) ); | |||
5193 | } | |||
5194 | nIdx = pUnknown->GetNextNamespaceIndex( nIdx ); | |||
5195 | } | |||
5196 | } | |||
5197 | } | |||
5198 | ||||
5199 | // #i66550# needed for 'presentation:event-listener' element for URLs in shapes | |||
5200 | GetNamespaceMap_().Add( | |||
5201 | GetXMLToken( XML_NP_PRESENTATION ), | |||
5202 | GetXMLToken( XML_N_PRESENTATION ), | |||
5203 | XML_NAMESPACE_PRESENTATION ); | |||
5204 | } | |||
5205 | ||||
5206 | void ScXMLExport::IncrementProgressBar(bool bFlush, sal_Int32 nInc) | |||
5207 | { | |||
5208 | nProgressCount += nInc; | |||
5209 | if (bFlush || nProgressCount > 100) | |||
5210 | { | |||
5211 | GetProgressBarHelper()->Increment(nProgressCount); | |||
5212 | nProgressCount = 0; | |||
5213 | } | |||
5214 | } | |||
5215 | ||||
5216 | ErrCode ScXMLExport::exportDoc( enum XMLTokenEnum eClass ) | |||
5217 | { | |||
5218 | if( getExportFlags() & (SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::STYLES| | |||
5219 | SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) | |||
5220 | { | |||
5221 | if (GetDocument()) | |||
5222 | { | |||
5223 | // if source doc was Excel then | |||
5224 | uno::Reference< frame::XModel > xModel = GetModel(); | |||
5225 | if ( xModel.is() ) | |||
5226 | { | |||
5227 | auto pFoundShell = comphelper::getUnoTunnelImplementation<SfxObjectShell>(xModel); | |||
5228 | if ( pFoundShell && ooo::vba::isAlienExcelDoc( *pFoundShell ) ) | |||
5229 | { | |||
5230 | xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScFromXLSRowStylesProperties, xScPropHdlFactory, true); | |||
5231 | xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper); | |||
5232 | GetAutoStylePool()->SetFamilyPropSetMapper( XmlStyleFamily::TABLE_ROW, | |||
5233 | xRowStylesExportPropertySetMapper ); | |||
5234 | } | |||
5235 | } | |||
5236 | CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF); | |||
5237 | CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS); | |||
5238 | CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS); | |||
5239 | ScDrawLayer* pDrawLayer = GetDocument()->GetDrawLayer(); | |||
5240 | if (pDrawLayer) | |||
5241 | { | |||
5242 | CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_PARA_XMLATTRIBS); | |||
5243 | CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS); | |||
5244 | CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES); | |||
5245 | } | |||
5246 | ||||
5247 | // sheet events use officeooo namespace | |||
5248 | if( (getExportFlags() & SvXMLExportFlags::CONTENT) && | |||
5249 | getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012) | |||
5250 | { | |||
5251 | bool bAnySheetEvents = false; | |||
5252 | SCTAB nTabCount = pDoc->GetTableCount(); | |||
5253 | for (SCTAB nTab=0; nTab<nTabCount; ++nTab) | |||
5254 | if (pDoc->GetSheetEvents(nTab)) | |||
5255 | bAnySheetEvents = true; | |||
5256 | if (bAnySheetEvents) | |||
5257 | GetNamespaceMap_().Add( | |||
5258 | GetXMLToken( XML_NP_OFFICE_EXT ), | |||
5259 | GetXMLToken( XML_N_OFFICE_EXT ), | |||
5260 | XML_NAMESPACE_OFFICE_EXT ); | |||
5261 | } | |||
5262 | } | |||
5263 | } | |||
5264 | return SvXMLExport::exportDoc( eClass ); | |||
5265 | } | |||
5266 | ||||
5267 | // XExporter | |||
5268 | void SAL_CALL ScXMLExport::setSourceDocument( const uno::Reference<lang::XComponent>& xComponent ) | |||
5269 | { | |||
5270 | SolarMutexGuard aGuard; | |||
5271 | SvXMLExport::setSourceDocument( xComponent ); | |||
5272 | ||||
5273 | pDoc = ScXMLConverter::GetScDocument( GetModel() ); | |||
5274 | OSL_ENSURE( pDoc, "ScXMLExport::setSourceDocument - no ScDocument!" )do { if (true && (!(pDoc))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx" ":" "5274" ": "), "%s", "ScXMLExport::setSourceDocument - no ScDocument!" ); } } while (false); | |||
5275 | if (!pDoc) | |||
5276 | throw lang::IllegalArgumentException(); | |||
5277 | ||||
5278 | // create ScChangeTrackingExportHelper after document is known | |||
5279 | pChangeTrackingExportHelper.reset(new ScChangeTrackingExportHelper(*this)); | |||
5280 | ||||
5281 | // Set the document's storage grammar corresponding to the ODF version that | |||
5282 | // is to be written. | |||
5283 | SvtSaveOptions::ODFSaneDefaultVersion meODFDefaultVersion = getSaneDefaultVersion(); | |||
5284 | switch (meODFDefaultVersion) | |||
5285 | { | |||
5286 | // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF | |||
5287 | case SvtSaveOptions::ODFSVER_010: | |||
5288 | case SvtSaveOptions::ODFSVER_011: | |||
5289 | pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF); | |||
5290 | break; | |||
5291 | default: | |||
5292 | pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF); | |||
5293 | } | |||
5294 | } | |||
5295 | ||||
5296 | // XFilter | |||
5297 | sal_Bool SAL_CALL ScXMLExport::filter( const css::uno::Sequence< css::beans::PropertyValue >& aDescriptor ) | |||
5298 | { | |||
5299 | SolarMutexGuard aGuard; | |||
5300 | if (pDoc) | |||
5301 | pDoc->EnableIdle(false); | |||
5302 | bool bReturn(SvXMLExport::filter(aDescriptor)); | |||
5303 | if (pDoc) | |||
5304 | pDoc->EnableIdle(true); | |||
5305 | return bReturn; | |||
5306 | } | |||
5307 | ||||
5308 | void SAL_CALL ScXMLExport::cancel() | |||
5309 | { | |||
5310 | SolarMutexGuard aGuard; | |||
5311 | if (pDoc) | |||
5312 | pDoc->EnableIdle(true); | |||
5313 | SvXMLExport::cancel(); | |||
5314 | } | |||
5315 | ||||
5316 | // XInitialization | |||
5317 | void SAL_CALL ScXMLExport::initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) | |||
5318 | { | |||
5319 | SolarMutexGuard aGuard; | |||
5320 | SvXMLExport::initialize(aArguments); | |||
5321 | } | |||
5322 | ||||
5323 | // XUnoTunnel | |||
5324 | sal_Int64 SAL_CALL ScXMLExport::getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) | |||
5325 | { | |||
5326 | SolarMutexGuard aGuard; | |||
5327 | return SvXMLExport::getSomething(aIdentifier); | |||
5328 | } | |||
5329 | ||||
5330 | void ScXMLExport::DisposingModel() | |||
5331 | { | |||
5332 | SvXMLExport::DisposingModel(); | |||
5333 | pDoc = nullptr; | |||
5334 | xCurrentTable = nullptr; | |||
5335 | } | |||
5336 | ||||
5337 | void ScXMLExport::SetSharedData(std::unique_ptr<ScMySharedData> pTemp) { pSharedData = std::move(pTemp); } | |||
5338 | ||||
5339 | std::unique_ptr<ScMySharedData> ScXMLExport::ReleaseSharedData() { return std::move(pSharedData); } | |||
5340 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_XMLOFF_XMLEXP_HXX |
21 | #define INCLUDED_XMLOFF_XMLEXP_HXX |
22 | |
23 | #include <sal/config.h> |
24 | #include <xmloff/dllapi.h> |
25 | #include <sal/types.h> |
26 | |
27 | #include <com/sun/star/lang/XUnoTunnel.hpp> |
28 | #include <rtl/ustring.hxx> |
29 | #include <xmloff/attrlist.hxx> |
30 | #include <xmloff/txtparae.hxx> |
31 | #include <xmloff/formlayerexport.hxx> |
32 | #include <xmloff/xmlnumfe.hxx> |
33 | #include <xmloff/xmlaustp.hxx> |
34 | #include <xmloff/shapeexport.hxx> |
35 | #include <xmloff/xmltoken.hxx> |
36 | #include <xmloff/SchXMLExportHelper.hxx> |
37 | #include <xmloff/XMLFontAutoStylePool.hxx> |
38 | #include <xmloff/xmluconv.hxx> |
39 | #include <com/sun/star/document/XFilter.hpp> |
40 | #include <com/sun/star/lang/XServiceInfo.hpp> |
41 | #include <com/sun/star/document/XExporter.hpp> |
42 | #include <com/sun/star/lang/XInitialization.hpp> |
43 | #include <com/sun/star/container/XNamed.hpp> |
44 | |
45 | #include <unotools/saveopt.hxx> |
46 | |
47 | #include <xmloff/XMLPageExport.hxx> |
48 | #include <comphelper/servicehelper.hxx> |
49 | #include <cppuhelper/implbase.hxx> |
50 | #include <tools/fldunit.hxx> |
51 | #include <vcl/errcode.hxx> |
52 | |
53 | #include <vector> |
54 | #include <memory> |
55 | #include <o3tl/typed_flags_set.hxx> |
56 | |
57 | namespace com::sun::star::beans { class XPropertySet; } |
58 | namespace com::sun::star::document { class XEmbeddedObjectResolver; } |
59 | namespace com::sun::star::document { class XGraphicStorageHandler; } |
60 | namespace com::sun::star::embed { class XStorage; } |
61 | namespace com::sun::star::graphic { class XGraphic; } |
62 | namespace com::sun::star::lang { class XEventListener; } |
63 | namespace com::sun::star::task { class XStatusIndicator; } |
64 | namespace com::sun::star::uno { class XComponentContext; } |
65 | namespace com::sun::star::util { class XNumberFormatsSupplier; } |
66 | namespace com::sun::star::xml::sax { class XAttributeList; } |
67 | namespace com::sun::star::xml::sax { class XDocumentHandler; } |
68 | namespace com::sun::star::xml::sax { class XExtendedDocumentHandler; } |
69 | namespace com::sun::star::xml::sax { class XLocator; } |
70 | |
71 | class SvXMLNamespaceMap; |
72 | class SvXMLExport_Impl; |
73 | class ProgressBarHelper; |
74 | class XMLEventExport; |
75 | class XMLImageMapExport; |
76 | class XMLErrors; |
77 | class LanguageTag; |
78 | enum class SvXMLErrorFlags; |
79 | |
80 | // Shapes in Writer cannot be named via context menu (#i51726#) |
81 | #include <unotools/moduleoptions.hxx> |
82 | |
83 | namespace com::sun::star { |
84 | namespace frame { class XModel; } |
85 | namespace lang { struct Locale; } |
86 | } |
87 | namespace comphelper { class UnoInterfaceToUniqueIdentifierMapper; } |
88 | |
89 | enum class SvXMLExportFlags { |
90 | NONE = 0, |
91 | META = 0x0001, |
92 | STYLES = 0x0002, |
93 | MASTERSTYLES = 0x0004, |
94 | AUTOSTYLES = 0x0008, |
95 | CONTENT = 0x0010, |
96 | SCRIPTS = 0x0020, |
97 | SETTINGS = 0x0040, |
98 | FONTDECLS = 0x0080, |
99 | EMBEDDED = 0x0100, |
100 | PRETTY = 0x0400, |
101 | OASIS = 0x8000, |
102 | ALL = 0x05ff |
103 | }; |
104 | namespace o3tl |
105 | { |
106 | template<> struct typed_flags<SvXMLExportFlags> : is_typed_flags<SvXMLExportFlags, 0x85ff> {}; |
107 | } |
108 | |
109 | class XMLOFF_DLLPUBLIC__attribute__ ((visibility("default"))) SvXMLExport : public cppu::WeakImplHelper< |
110 | css::document::XFilter, |
111 | css::lang::XServiceInfo, |
112 | css::document::XExporter, |
113 | css::lang::XInitialization, |
114 | css::container::XNamed, |
115 | css::lang::XUnoTunnel> |
116 | { |
117 | std::unique_ptr<SvXMLExport_Impl> mpImpl; // dummy |
118 | |
119 | css::uno::Reference< css::uno::XComponentContext > m_xContext; |
120 | OUString m_implementationName; |
121 | |
122 | css::uno::Reference< css::frame::XModel > mxModel; |
123 | css::uno::Reference< css::xml::sax::XDocumentHandler > mxHandler; // the handlers |
124 | css::uno::Reference< css::xml::sax::XExtendedDocumentHandler > mxExtHandler; |
125 | css::uno::Reference< css::util::XNumberFormatsSupplier > mxNumberFormatsSupplier; |
126 | css::uno::Reference< css::document::XGraphicStorageHandler > mxGraphicStorageHandler; |
127 | css::uno::Reference< css::document::XEmbeddedObjectResolver > mxEmbeddedResolver; |
128 | css::uno::Reference< css::task::XStatusIndicator > mxStatusIndicator; |
129 | css::uno::Reference< css::beans::XPropertySet > mxExportInfo; |
130 | css::uno::Reference< css::lang::XEventListener > mxEventListener; |
131 | |
132 | rtl::Reference<SvXMLAttributeList> mxAttrList; // a common attribute list |
133 | |
134 | OUString msOrigFileName; // the original URL |
135 | OUString msFilterName; |
136 | OUString msImgFilterName; |
137 | std::unique_ptr<SvXMLNamespaceMap> mpNamespaceMap; // the namepspace map |
138 | SvXMLUnitConverter maUnitConv; // the unit converter |
139 | std::unique_ptr<SvXMLNumFmtExport> mpNumExport; |
140 | std::unique_ptr<ProgressBarHelper> mpProgressBarHelper; |
141 | |
142 | rtl::Reference< XMLTextParagraphExport > mxTextParagraphExport; |
143 | rtl::Reference< XMLShapeExport > mxShapeExport; |
144 | rtl::Reference< SvXMLAutoStylePoolP > mxAutoStylePool; |
145 | rtl::Reference< SchXMLExportHelper > mxChartExport; |
146 | rtl::Reference< XMLPageExport > mxPageExport; |
147 | rtl::Reference< XMLFontAutoStylePool > mxFontAutoStylePool; |
148 | rtl::Reference< xmloff::OFormLayerXMLExport > mxFormExport; |
149 | std::unique_ptr<XMLEventExport> mpEventExport; |
150 | std::unique_ptr<XMLImageMapExport> mpImageMapExport; |
151 | std::unique_ptr<XMLErrors> mpXMLErrors; |
152 | |
153 | const enum ::xmloff::token::XMLTokenEnum meClass; |
154 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void InitCtor_(); |
155 | |
156 | SvXMLExportFlags mnExportFlags; |
157 | SvXMLErrorFlags mnErrorFlags; |
158 | |
159 | const OUString msWS; // " " |
160 | |
161 | // Shapes in Writer cannot be named via context menu (#i51726#) |
162 | SvtModuleOptions::EFactory meModelType; |
163 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DetermineModelType_(); |
164 | |
165 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplExportMeta(); // <office:meta> |
166 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplExportSettings(); // <office:settings> |
167 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplExportStyles(); // <office:styles> |
168 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplExportAutoStyles(); |
169 | // <office:automatic-styles> |
170 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplExportMasterStyles(); |
171 | // <office:master-styles> |
172 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplExportContent(); // <office:body> |
173 | virtual void SetBodyAttributes(); |
174 | void GetViewSettingsAndViews(css::uno::Sequence<css::beans::PropertyValue>& rProps); |
175 | |
176 | protected: |
177 | void setExportFlags( SvXMLExportFlags nExportFlags ) { mnExportFlags = nExportFlags; } |
178 | |
179 | // Get (modifiable) namespace map |
180 | SvXMLNamespaceMap& GetNamespaceMap_() { return *mpNamespaceMap; } |
181 | |
182 | // get a new namespace map (used in starmath to have a default namespace) |
183 | void ResetNamespaceMap(); |
184 | |
185 | /// Override this method to export the content of <office:meta>. |
186 | /// There is a default implementation. |
187 | virtual void ExportMeta_(); |
188 | |
189 | /// Override this method to export the content of <office:scripts>. |
190 | /// There is a default implementation. |
191 | virtual void ExportScripts_(); |
192 | |
193 | /// Override this method to export the font declarations |
194 | /// The default implementation will export the contents of the |
195 | /// XMLFontAutoStylePool if it has been created. |
196 | virtual void ExportFontDecls_(); |
197 | |
198 | /// Override this method to export the content of <style:styles>. |
199 | /// If bUsed is set, used styles should be exported only. |
200 | /// Overriding Methods must call this method ! |
201 | virtual void ExportStyles_( bool bUsed ); |
202 | |
203 | /// Override this method to export the contents of <style:auto-styles>. |
204 | virtual void ExportAutoStyles_() = 0; |
205 | |
206 | /// Override this method to export the contents of <style:master-styles>. |
207 | virtual void ExportMasterStyles_() = 0; |
208 | |
209 | /// Override this method to export the content of <office:body>. |
210 | virtual void ExportContent_() = 0; |
211 | |
212 | OUString const & GetSourceShellID() const; |
213 | OUString const & GetDestinationShellID() const; |
214 | |
215 | // save linked sections? (may be false in global documents) |
216 | bool mbSaveLinkedSections; |
217 | |
218 | virtual XMLTextParagraphExport* CreateTextParagraphExport(); |
219 | virtual XMLShapeExport* CreateShapeExport(); |
220 | virtual SvXMLAutoStylePoolP* CreateAutoStylePool(); |
221 | SchXMLExportHelper* CreateChartExport(); |
222 | virtual XMLPageExport* CreatePageExport(); |
223 | virtual XMLFontAutoStylePool* CreateFontAutoStylePool(); |
224 | xmloff::OFormLayerXMLExport* CreateFormExport(); |
225 | virtual void GetViewSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps); |
226 | virtual void GetConfigurationSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps); |
227 | |
228 | struct SettingsGroup |
229 | { |
230 | ::xmloff::token::XMLTokenEnum eGroupName; |
231 | css::uno::Sequence< css::beans::PropertyValue > aSettings; |
232 | |
233 | SettingsGroup( |
234 | const ::xmloff::token::XMLTokenEnum _eGroupName, |
235 | const css::uno::Sequence< css::beans::PropertyValue >& _rSettings ) |
236 | :eGroupName( _eGroupName ) |
237 | ,aSettings( _rSettings ) |
238 | { |
239 | } |
240 | }; |
241 | /** returns the current document settings |
242 | |
243 | The default implementation will obtain the view settings by calling GetViewSettingsAndViews, and the |
244 | configuration settings by calling GetConfigurationSettings, and return them together with the proper XML token. |
245 | |
246 | @return |
247 | the accumulated count of all settings in all groups |
248 | */ |
249 | virtual sal_Int32 GetDocumentSpecificSettings( ::std::vector< SettingsGroup >& _out_rSettings ); |
250 | |
251 | const css::uno::Reference< css::document::XEmbeddedObjectResolver >& GetEmbeddedResolver() const { return mxEmbeddedResolver; } |
252 | inline void SetEmbeddedResolver( css::uno::Reference< css::document::XEmbeddedObjectResolver > const & _xEmbeddedResolver ); |
253 | |
254 | const css::uno::Reference<css::document::XGraphicStorageHandler> & GetGraphicStorageHandler() const |
255 | { |
256 | return mxGraphicStorageHandler; |
257 | } |
258 | void SetGraphicStorageHandler(css::uno::Reference<css::document::XGraphicStorageHandler> const & rxGraphicStorageHandler); |
259 | |
260 | void SetDocHandler( const css::uno::Reference< css::xml::sax::XDocumentHandler > &rHandler ); |
261 | |
262 | bool mbAutoStylesCollected; |
263 | public: |
264 | |
265 | SvXMLExport( |
266 | const css::uno::Reference< css::uno::XComponentContext >& xContext, |
267 | OUString const & implementationName, |
268 | sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/, |
269 | const enum ::xmloff::token::XMLTokenEnum eClass, |
270 | SvXMLExportFlags nExportFlag ); |
271 | |
272 | SvXMLExport( |
273 | const css::uno::Reference< css::uno::XComponentContext >& xContext, |
274 | OUString const & implementationName, |
275 | const OUString& rFileName, |
276 | sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/, |
277 | const css::uno::Reference< css::xml::sax::XDocumentHandler > & rHandler); |
278 | |
279 | SvXMLExport( |
280 | const css::uno::Reference< css::uno::XComponentContext >& xContext, |
281 | OUString const & implementationName, |
282 | const OUString& rFileName, |
283 | const css::uno::Reference< css::xml::sax::XDocumentHandler > & rHandler, |
284 | const css::uno::Reference< css::frame::XModel > &, |
285 | FieldUnit const eDefaultFieldUnit, |
286 | SvXMLExportFlags nExportFlag ); |
287 | |
288 | virtual ~SvXMLExport() override; |
289 | |
290 | virtual void collectAutoStyles(); |
291 | |
292 | // XExporter |
293 | virtual void SAL_CALL setSourceDocument( const css::uno::Reference< css::lang::XComponent >& xDoc ) override; |
294 | |
295 | // XFilter |
296 | virtual sal_Bool SAL_CALL filter( const css::uno::Sequence< css::beans::PropertyValue >& aDescriptor ) override; |
297 | virtual void SAL_CALL cancel() override; |
298 | |
299 | // XInitialization |
300 | virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; |
301 | |
302 | // XNamed |
303 | virtual OUString SAL_CALL getName( ) override; |
304 | virtual void SAL_CALL setName( const OUString& aName ) override; |
305 | |
306 | // XServiceInfo |
307 | virtual OUString SAL_CALL getImplementationName( ) final override; |
308 | virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) final override; |
309 | virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) final override; |
310 | |
311 | // XUnoTunnel |
312 | UNO3_GETIMPLEMENTATION_DECL(SvXMLExport)static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId () throw(); virtual sal_Int64 getSomething( const css::uno::Sequence < sal_Int8 >& aIdentifier ) override; |
313 | |
314 | /** ensures that the given namespace is in scope at the next started |
315 | element. |
316 | |
317 | <p>If the namespace is not yet declared, the necessary attribute will |
318 | be added, as well.</p> |
319 | |
320 | @param i_rNamespace the namespace to be declared |
321 | |
322 | @returns the actual prefix that the namespace is associated with |
323 | */ |
324 | OUString EnsureNamespace(OUString const & i_rNamespace ); |
325 | |
326 | // Check if common attribute list is empty. |
327 | #ifndef DBG_UTIL |
328 | void CheckAttrList() { (void) this; /* avoid loplugin:staticmethods */ } |
329 | #else |
330 | void CheckAttrList(); |
331 | #endif |
332 | |
333 | // Clear common attribute list. |
334 | void ClearAttrList(); |
335 | |
336 | // Add an attribute to the common attribute list. |
337 | void AddAttributeASCII( sal_uInt16 nPrefix, const char *pName, |
338 | const char *pValue ); |
339 | void AddAttribute( sal_uInt16 nPrefix, const char *pName, |
340 | const OUString& rValue ); |
341 | void AddAttribute( sal_uInt16 nPrefix, const OUString& rName, |
342 | const OUString& rValue ); |
343 | void AddAttribute( sal_uInt16 nPrefix, |
344 | enum ::xmloff::token::XMLTokenEnum eName, |
345 | const OUString& rValue ); |
346 | void AddAttribute( sal_uInt16 nPrefix, |
347 | enum ::xmloff::token::XMLTokenEnum eName, |
348 | enum ::xmloff::token::XMLTokenEnum eValue ); |
349 | void AddAttribute( const OUString& rQName, |
350 | const OUString& rValue ); |
351 | void AddAttribute( const OUString& rQName, |
352 | enum ::xmloff::token::XMLTokenEnum eValue ); |
353 | |
354 | /** Add language tag attributes, deciding which are necessary. |
355 | |
356 | @param nPrefix |
357 | Namespace prefix for *:language, *:script and *:country |
358 | |
359 | @param nPrefixRfc |
360 | Namespace prefix for *:rfc-language-tag |
361 | |
362 | @param bWriteEmpty |
363 | Whether to write empty *:language and *:country attribute |
364 | values in case of an empty locale (denoting system). |
365 | */ |
366 | void AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc, |
367 | const css::lang::Locale& rLocale, bool bWriteEmpty); |
368 | |
369 | /** Same as AddLanguageTagAttributes() but with LanguageTag parameter |
370 | instead of Locale. |
371 | */ |
372 | void AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc, |
373 | const LanguageTag& rLanguageTag, bool bWriteEmpty ); |
374 | |
375 | // add several attributes to the common attribute list |
376 | void AddAttributeList( const css::uno::Reference< |
377 | css::xml::sax::XAttributeList >& xAttrList ); |
378 | |
379 | // Get common attribute list as implementation or interface. |
380 | SvXMLAttributeList &GetAttrList() { return *mxAttrList; } |
381 | css::uno::Reference< css::xml::sax::XAttributeList > GetXAttrList() { return mxAttrList.get(); } |
382 | |
383 | // Get document handler. This methods are not const, because the |
384 | // reference allows modifications through the handler. |
385 | const css::uno::Reference< css::xml::sax::XDocumentHandler > & GetDocHandler() const { return mxHandler; } |
386 | |
387 | // Get original URL. |
388 | const OUString& GetOrigFileName() const { return msOrigFileName; } |
389 | |
390 | // Get (const) namespace map. |
391 | const SvXMLNamespaceMap& GetNamespaceMap() const { return *mpNamespaceMap; } |
392 | |
393 | // Get unit converter |
394 | const SvXMLUnitConverter& GetMM100UnitConverter() const { return maUnitConv; } |
395 | |
396 | SvXMLUnitConverter& GetMM100UnitConverter() { return maUnitConv; } |
397 | |
398 | void addChaffWhenEncryptedStorage(); |
399 | |
400 | // Export the document. |
401 | virtual ErrCode exportDoc( enum ::xmloff::token::XMLTokenEnum eClass = ::xmloff::token::XML_TOKEN_INVALID ); |
402 | |
403 | void collectDataStyles(bool bFromUsedStyles); |
404 | virtual void addDataStyle(const sal_Int32 nNumberFormat, bool bTimeFormat = false ); |
405 | virtual void exportDataStyles(); |
406 | virtual void exportAutoDataStyles(); |
407 | virtual OUString getDataStyleName(const sal_Int32 nNumberFormat, bool bTimeFormat = false ) const; |
408 | sal_Int32 dataStyleForceSystemLanguage(sal_Int32 nFormat) const; |
409 | |
410 | virtual void exportAnnotationMeta( const css::uno::Reference < css::drawing::XShape >& xShape); |
411 | |
412 | // Get XModel |
413 | const css::uno::Reference< css::frame::XModel > & |
414 | GetModel() const { return mxModel; } |
415 | // Get XNumberFormatsSupplier |
416 | css::uno::Reference< css::util::XNumberFormatsSupplier > & GetNumberFormatsSupplier() { return mxNumberFormatsSupplier; } |
417 | void SetNumberFormatsSupplier(const css::uno::Reference< css::util::XNumberFormatsSupplier >& _xNumberFormatSupplier) |
418 | { |
419 | mxNumberFormatsSupplier = _xNumberFormatSupplier; |
420 | if ( mxNumberFormatsSupplier.is() && mxHandler.is() ) |
421 | mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) ); |
422 | } |
423 | |
424 | // get export helper for text |
425 | inline rtl::Reference< XMLTextParagraphExport > const & GetTextParagraphExport(); |
426 | |
427 | // get export helper for shapes |
428 | inline rtl::Reference< XMLShapeExport > const & GetShapeExport(); |
429 | |
430 | // get auto style pool |
431 | inline rtl::Reference< SvXMLAutoStylePoolP > const & GetAutoStylePool(); |
432 | |
433 | // get Page Export |
434 | inline rtl::Reference< XMLPageExport > const & GetPageExport(); |
435 | |
436 | // get chart export helper |
437 | inline rtl::Reference< SchXMLExportHelper > const & GetChartExport(); |
438 | |
439 | // get font auto style pool |
440 | inline rtl::Reference< XMLFontAutoStylePool > const & GetFontAutoStylePool(); |
441 | |
442 | ProgressBarHelper* GetProgressBarHelper(); |
443 | |
444 | // get Formlayer Export |
445 | inline rtl::Reference< xmloff::OFormLayerXMLExport > const & GetFormExport(); |
446 | inline bool HasFormExport() const; |
447 | |
448 | // get XPropertySet with export information |
449 | const css::uno::Reference< css::beans::XPropertySet >& getExportInfo() const { return mxExportInfo; } |
450 | |
451 | const css::uno::Reference< css::task::XStatusIndicator >& GetStatusIndicator() const { return mxStatusIndicator; } |
452 | |
453 | /// get Event export, with handlers for script types "None" and |
454 | /// "StarBasic" already registered; other handlers may be registered, too. |
455 | XMLEventExport& GetEventExport(); |
456 | |
457 | /// get the export for image maps |
458 | XMLImageMapExport& GetImageMapExport(); |
459 | |
460 | OUString AddEmbeddedXGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic, OUString & rOutMimeType, OUString const & rRequestedName = OUString()); |
461 | bool AddEmbeddedXGraphicAsBase64(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic); |
462 | bool GetGraphicMimeTypeFromStream(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic, OUString & rOutMimeType); |
463 | |
464 | OUString AddEmbeddedObject( |
465 | const OUString& rEmbeddedObjectURL ); |
466 | bool AddEmbeddedObjectAsBase64( |
467 | const OUString& rEmbeddedObjectURL ); |
468 | |
469 | OUString EncodeStyleName( const OUString& rName, |
470 | bool *pEncoded=nullptr ) const; |
471 | |
472 | // save linked sections? |
473 | bool IsSaveLinkedSections() const { return mbSaveLinkedSections; } |
474 | |
475 | // get export flags |
476 | SvXMLExportFlags getExportFlags() const { return mnExportFlags; } |
477 | |
478 | void ExportEmbeddedOwnObject( |
479 | css::uno::Reference<css::lang::XComponent > const & rComp ); |
480 | |
481 | OUString GetRelativeReference(const OUString& rValue); |
482 | |
483 | // methods for accessing the document handler and handling SAX errors |
484 | void StartElement(sal_uInt16 nPrefix, |
485 | enum ::xmloff::token::XMLTokenEnum eName, |
486 | bool bIgnWSOutside ); |
487 | void StartElement(const OUString& rName, |
488 | bool bIgnWSOutside ); |
489 | void Characters(const OUString& rChars); |
490 | void EndElement(sal_uInt16 nPrefix, |
491 | enum ::xmloff::token::XMLTokenEnum eName, |
492 | bool bIgnWSInside ); |
493 | void EndElement(const OUString& rName, |
494 | bool bIgnWSInside ); |
495 | void IgnorableWhitespace(); |
496 | |
497 | /** |
498 | * Record an error condition that occurred during export. The |
499 | * behavior of SetError can be modified using the error flag |
500 | * constants. |
501 | */ |
502 | void SetError( |
503 | /// error ID, may contain an error flag |
504 | sal_Int32 nId, |
505 | /// string parameters for the error message |
506 | const css::uno::Sequence< OUString> & rMsgParams, |
507 | /// original exception message (if applicable) |
508 | const OUString& rExceptionMessage, |
509 | /// error location (if applicable) |
510 | const css::uno::Reference<css::xml::sax::XLocator> & rLocator ); |
511 | |
512 | void SetError( |
513 | sal_Int32 nId, |
514 | const css::uno::Sequence< OUString> & rMsgParams); |
515 | |
516 | virtual void DisposingModel(); |
517 | |
518 | ::comphelper::UnoInterfaceToUniqueIdentifierMapper& getInterfaceToIdentifierMapper(); |
519 | |
520 | const css::uno::Reference< css::uno::XComponentContext >& getComponentContext() const { return m_xContext;} |
521 | |
522 | // Shapes in Writer cannot be named via context menu (#i51726#) |
523 | SvtModuleOptions::EFactory GetModelType() const |
524 | { |
525 | return meModelType; |
526 | } |
527 | |
528 | // Written OpenDocument file format doesn't fit to the created text document (#i69627#) |
529 | bool writeOutlineStyleAsNormalListStyle() const; |
530 | |
531 | css::uno::Reference< css::embed::XStorage > const & GetTargetStorage() const; |
532 | |
533 | /// returns value of ODF version attribute |
534 | char const* GetODFVersionAttributeValue() const; |
535 | |
536 | /// returns the deterministic version for odf export |
537 | SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const; |
538 | |
539 | // FIXME: this is only for legacy stuff that has not yet been adapted |
540 | // to implement XMetadatable; this can write duplicate IDs! |
541 | /// add xml:id and legacy namespace id |
542 | void SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) AddAttributeIdLegacy( |
543 | sal_uInt16 const nLegacyPrefix, OUString const& rValue); |
544 | |
545 | /// add xml:id attribute (for RDF metadata) |
546 | void AddAttributeXmlId(css::uno::Reference<css::uno::XInterface> const & i_xIfc); |
547 | |
548 | /// add RDFa attributes for a metadatable text content |
549 | void AddAttributesRDFa( css::uno::Reference<css::text::XTextContent> const & i_xTextContent); |
550 | |
551 | bool exportTextNumberElement() const; |
552 | |
553 | /// set null date from model to unit converter, if not already done |
554 | bool SetNullDateOnUnitConverter(); |
555 | |
556 | /// Get clamped mimetype for image export (empty if none) |
557 | OUString const & GetImageFilterName() const; |
558 | }; |
559 | |
560 | inline rtl::Reference< XMLTextParagraphExport > const & SvXMLExport::GetTextParagraphExport() |
561 | { |
562 | if( !mxTextParagraphExport.is() ) |
563 | mxTextParagraphExport = CreateTextParagraphExport(); |
564 | |
565 | return mxTextParagraphExport; |
566 | } |
567 | |
568 | inline rtl::Reference< XMLShapeExport > const & SvXMLExport::GetShapeExport() |
569 | { |
570 | if( !mxShapeExport.is() ) |
571 | mxShapeExport = CreateShapeExport(); |
572 | |
573 | return mxShapeExport; |
574 | } |
575 | |
576 | inline rtl::Reference< SvXMLAutoStylePoolP > const & SvXMLExport::GetAutoStylePool() |
577 | { |
578 | if( !mxAutoStylePool.is() ) |
579 | mxAutoStylePool = CreateAutoStylePool(); |
580 | |
581 | return mxAutoStylePool; |
582 | } |
583 | |
584 | inline rtl::Reference< SchXMLExportHelper > const & SvXMLExport::GetChartExport() |
585 | { |
586 | if( !mxChartExport.is() ) |
587 | mxChartExport = CreateChartExport(); |
588 | |
589 | return mxChartExport; |
590 | } |
591 | |
592 | inline rtl::Reference< XMLPageExport > const & SvXMLExport::GetPageExport() |
593 | { |
594 | if( !mxPageExport.is() ) |
595 | mxPageExport = CreatePageExport(); |
596 | |
597 | return mxPageExport; |
598 | } |
599 | |
600 | inline rtl::Reference< XMLFontAutoStylePool > const & SvXMLExport::GetFontAutoStylePool() |
601 | { |
602 | if( !mxFontAutoStylePool.is() ) |
603 | mxFontAutoStylePool = CreateFontAutoStylePool(); |
604 | |
605 | return mxFontAutoStylePool; |
606 | } |
607 | |
608 | inline rtl::Reference< xmloff::OFormLayerXMLExport > const & SvXMLExport::GetFormExport() |
609 | { |
610 | if( !mxFormExport.is() ) |
611 | mxFormExport = CreateFormExport(); |
612 | |
613 | return mxFormExport; |
614 | } |
615 | |
616 | inline bool SvXMLExport::HasFormExport() const |
617 | { |
618 | return mxFormExport.is(); |
619 | } |
620 | |
621 | inline void SvXMLExport::SetEmbeddedResolver( |
622 | css::uno::Reference< css::document::XEmbeddedObjectResolver > const & _xEmbeddedResolver ) |
623 | { |
624 | mxEmbeddedResolver = _xEmbeddedResolver; |
625 | } |
626 | |
627 | inline void SvXMLExport::SetGraphicStorageHandler( |
628 | css::uno::Reference<css::document::XGraphicStorageHandler> const & rxGraphicStorageHandler) |
629 | { |
630 | mxGraphicStorageHandler = rxGraphicStorageHandler; |
631 | } |
632 | |
633 | // Helper class to export an element. |
634 | class XMLOFF_DLLPUBLIC__attribute__ ((visibility("default"))) SvXMLElementExport |
635 | { |
636 | SvXMLExport& mrExport; |
637 | OUString maElementName; |
638 | const bool mbIgnoreWhitespaceInside :1; |
639 | const bool mbDoSomething :1; |
640 | |
641 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) |
642 | void StartElement( |
643 | const sal_uInt16 nPrefix, |
644 | const OUString& rName, |
645 | const bool bIgnoreWhitespaceOutside ); |
646 | |
647 | public: |
648 | |
649 | // The constructor prints a start tag that has the common attributes |
650 | // of the XMLExport instance attached. |
651 | SvXMLElementExport( SvXMLExport& rExp, sal_uInt16 nPrefix, |
652 | const char *pName, |
653 | bool bIgnWSOutside, bool bIgnWSInside ); |
654 | SvXMLElementExport( SvXMLExport& rExp, sal_uInt16 nPrefix, |
655 | const OUString& rName, |
656 | bool bIgnWSOutside, bool bIgnWSInside ); |
657 | SvXMLElementExport( SvXMLExport& rExp, sal_uInt16 nPrefix, |
658 | enum ::xmloff::token::XMLTokenEnum eName, |
659 | bool bIgnWSOutside, bool bIgnWSInside ); |
660 | SvXMLElementExport( SvXMLExport& rExp, const OUString& rQName, |
661 | bool bIgnWSOutside, bool bIgnWSInside ); |
662 | |
663 | // These constructors do nothing if bDoSomething is not set |
664 | SvXMLElementExport( SvXMLExport& rExp, bool bDoSomething, |
665 | sal_uInt16 nPrefix, |
666 | enum ::xmloff::token::XMLTokenEnum eName, |
667 | bool bIgnWSOutside, bool bIgnWSInside ); |
668 | |
669 | // The destructor prints an end tag. |
670 | ~SvXMLElementExport(); |
671 | }; |
672 | |
673 | #endif // _XMLOFF_SVXMLEXP_HXX |
674 | |
675 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |