Bug Summary

File:home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx
Warning:line 886, column 37
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name xmlexprt.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SC_DLLIMPLEMENTATION -D SC_INFO_OSVERSION="LINUX" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/clew/source/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sc/source/core/inc -I /home/maarten/src/libreoffice/core/sc/source/filter/inc -I /home/maarten/src/libreoffice/core/sc/source/ui/inc -I /home/maarten/src/libreoffice/core/sc/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sc/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx

/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx

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
159namespace 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
181using namespace formula;
182using namespace com::sun::star;
183using namespace xmloff::token;
184using ::std::vector;
185using ::com::sun::star::uno::UNO_QUERY;
186
187namespace
188{
189OUString 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
208OUString 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
247extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
248Calc_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
253extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
254Calc_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
259extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
260Calc_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
265extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
266Calc_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
271extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
272Calc_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
277extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
278Calc_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
283extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
284Calc_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
289extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
290Calc_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
295extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
296Calc_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
301extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
302Calc_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
307namespace {
308
309class ScXMLShapeExport : public XMLShapeExport
310{
311public:
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
320void 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
331sal_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
339constexpr OUStringLiteral gsLayerID( u"" SC_LAYERID"LayerID" );
340
341ScXMLExport::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
415ScXMLExport::~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
430void 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
469sal_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
478void 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
566void 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
632void 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
660void ScXMLExport::ExportFontDecls_()
661{
662 GetFontAutoStylePool(); // make sure the pool is created
663 SvXMLExport::ExportFontDecls_();
664}
665
666table::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
680void 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
705void 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
732void 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
749void 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
771void ScXMLExport::OpenHeaderColumn()
772{
773 StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, true );
774}
775
776void ScXMLExport::CloseHeaderColumn()
777{
778 EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, true);
779}
780
781void 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
877void ScXMLExport::ExportExternalRefCacheStyles()
878{
879 sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex(
880 "NumberFormat", XML_NAMESPACE_STYLE, "data-style-name");
881
882 if (nEntryIndex < 0)
18
Assuming 'nEntryIndex' is >= 0
19
Taking false branch
883 // No entry index for the number format is found.
884 return;
885
886 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
20
Called C++ object pointer is null
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
925namespace {
926
927void 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
948const 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
1242void 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
1277void 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
1345void 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
1365void ScXMLExport::OpenHeaderRows()
1366{
1367 StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, true);
1368 bRowHeaderOpen = true;
1369}
1370
1371void ScXMLExport::CloseHeaderRows()
1372{
1373 EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, true);
1374}
1375
1376void 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
1411void 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
1421void 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
1504void 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
1526void 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
1608void 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
1636void 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
1656void 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
1673void 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
1729static 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
1778static 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
1798void 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
1838const ScXMLEditAttributeMap& ScXMLExport::GetEditAttributeMap() const
1839{
1840 if (!mpEditAttrMap)
1841 mpEditAttrMap.reset(new ScXMLEditAttributeMap);
1842 return *mpEditAttrMap;
1843}
1844
1845void ScXMLExport::RegisterDefinedStyleNames( const uno::Reference< css::sheet::XSpreadsheetDocument > & xSpreadDoc )
1846{
1847 ScFormatSaveData* pFormatData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetFormatSaveData();
1848 auto xAutoStylePool = GetAutoStylePool();
8
Calling 'SvXMLExport::GetAutoStylePool'
11
Returning from 'SvXMLExport::GetAutoStylePool'
1849 for (const auto& rFormatInfo : pFormatData->maIDToName)
1850 {
1851 xAutoStylePool->RegisterDefinedName(XmlStyleFamily::TABLE_CELL, rFormatInfo.second);
1852 }
1853}
1854
1855void 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
1949void 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
1985void 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
2130void 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
2167void 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
2196static 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
2217void ScXMLExport::collectAutoStyles()
2218{
2219 SvXMLExport::collectAutoStyles();
2220
2221 if (mbAutoStylesCollected)
1
Assuming field 'mbAutoStylesCollected' is false
2
Taking false branch
2222 return;
2223
2224 if (!GetModel().is())
3
Taking false branch
2225 return;
2226
2227 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
2228 if (!xSpreadDoc.is())
4
Taking false branch
2229 return;
2230
2231 uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
2232 if (!xIndex.is())
5
Taking false branch
2233 return;
2234
2235 if (getExportFlags() & SvXMLExportFlags::CONTENT)
6
Taking true branch
2236 {
2237 // Reserve the loaded cell style names.
2238 RegisterDefinedStyleNames( xSpreadDoc);
7
Calling 'ScXMLExport::RegisterDefinedStyleNames'
12
Returning from 'ScXMLExport::RegisterDefinedStyleNames'
2239
2240 // re-create automatic styles with old names from stored data
2241 ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetSheetSaveData();
2242 if (pSheetData && pDoc)
13
Assuming 'pSheetData' is non-null
14
Assuming field 'pDoc' is null
15
Assuming pointer value is null
16
Taking false branch
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();
17
Calling 'ScXMLExport::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
2606void 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
2660void ScXMLExport::ExportMasterStyles_()
2661{
2662 GetPageExport()->exportMasterStyles( true );
2663}
2664
2665void 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
2703bool 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
2751bool 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
2780void 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
2994namespace {
2995
2996void 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
3088void 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
3113void 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
3276void 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
3311void 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
3347void 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
3469void 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
3510void 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
3537void 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
3561void 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
3617void 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
3639void 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
3681void 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
3694bool ScXMLExport::IsEditCell(const ScMyCell& rCell)
3695{
3696 return rCell.maBaseCell.meType == CELLTYPE_EDIT;
3697}
3698
3699bool 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
3767void 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
3840void 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
3909void 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
3943void 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
3965void 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
3988void ScXMLExport::WriteNamedExpressions()
3989{
3990 if (!pDoc)
3991 return;
3992 ScRangeName* pNamedRanges = pDoc->GetRangeName();
3993 WriteNamedRange(pNamedRanges);
3994}
3995
3996void 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
4026void 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
4324void 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
4367void 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
4427namespace {
4428
4429OUString 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
4455OUString 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
4492void 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
4788void 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
4981void 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
5016SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool()
5017{
5018 return new ScXMLAutoStylePoolP(*this);
5019}
5020
5021XMLPageExport* ScXMLExport::CreatePageExport()
5022{
5023 return new XMLTableMasterPageExport( *this );
5024}
5025
5026void 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
5071void 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
5099void 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
5163XMLShapeExport* ScXMLExport::CreateShapeExport()
5164{
5165 return new ScXMLShapeExport(*this);
5166}
5167
5168XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper()
5169{
5170 if (!pNumberFormatAttributesExportHelper)
5171 pNumberFormatAttributesExportHelper.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this ));
5172 return pNumberFormatAttributesExportHelper.get();
5173}
5174
5175void 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
5206void 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
5216ErrCode 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
5268void 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
5297sal_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
5308void SAL_CALL ScXMLExport::cancel()
5309{
5310 SolarMutexGuard aGuard;
5311 if (pDoc)
5312 pDoc->EnableIdle(true);
5313 SvXMLExport::cancel();
5314}
5315
5316// XInitialization
5317void SAL_CALL ScXMLExport::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
5318{
5319 SolarMutexGuard aGuard;
5320 SvXMLExport::initialize(aArguments);
5321}
5322
5323// XUnoTunnel
5324sal_Int64 SAL_CALL ScXMLExport::getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier )
5325{
5326 SolarMutexGuard aGuard;
5327 return SvXMLExport::getSomething(aIdentifier);
5328}
5329
5330void ScXMLExport::DisposingModel()
5331{
5332 SvXMLExport::DisposingModel();
5333 pDoc = nullptr;
5334 xCurrentTable = nullptr;
5335}
5336
5337void ScXMLExport::SetSharedData(std::unique_ptr<ScMySharedData> pTemp) { pSharedData = std::move(pTemp); }
5338
5339std::unique_ptr<ScMySharedData> ScXMLExport::ReleaseSharedData() { return std::move(pSharedData); }
5340/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/xmloff/xmlexp.hxx

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
57namespace com::sun::star::beans { class XPropertySet; }
58namespace com::sun::star::document { class XEmbeddedObjectResolver; }
59namespace com::sun::star::document { class XGraphicStorageHandler; }
60namespace com::sun::star::embed { class XStorage; }
61namespace com::sun::star::graphic { class XGraphic; }
62namespace com::sun::star::lang { class XEventListener; }
63namespace com::sun::star::task { class XStatusIndicator; }
64namespace com::sun::star::uno { class XComponentContext; }
65namespace com::sun::star::util { class XNumberFormatsSupplier; }
66namespace com::sun::star::xml::sax { class XAttributeList; }
67namespace com::sun::star::xml::sax { class XDocumentHandler; }
68namespace com::sun::star::xml::sax { class XExtendedDocumentHandler; }
69namespace com::sun::star::xml::sax { class XLocator; }
70
71class SvXMLNamespaceMap;
72class SvXMLExport_Impl;
73class ProgressBarHelper;
74class XMLEventExport;
75class XMLImageMapExport;
76class XMLErrors;
77class LanguageTag;
78enum class SvXMLErrorFlags;
79
80// Shapes in Writer cannot be named via context menu (#i51726#)
81#include <unotools/moduleoptions.hxx>
82
83namespace com::sun::star {
84 namespace frame { class XModel; }
85 namespace lang { struct Locale; }
86}
87namespace comphelper { class UnoInterfaceToUniqueIdentifierMapper; }
88
89enum 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};
104namespace o3tl
105{
106 template<> struct typed_flags<SvXMLExportFlags> : is_typed_flags<SvXMLExportFlags, 0x85ff> {};
107}
108
109class 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
176protected:
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;
263public:
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
560inline rtl::Reference< XMLTextParagraphExport > const & SvXMLExport::GetTextParagraphExport()
561{
562 if( !mxTextParagraphExport.is() )
563 mxTextParagraphExport = CreateTextParagraphExport();
564
565 return mxTextParagraphExport;
566}
567
568inline rtl::Reference< XMLShapeExport > const & SvXMLExport::GetShapeExport()
569{
570 if( !mxShapeExport.is() )
571 mxShapeExport = CreateShapeExport();
572
573 return mxShapeExport;
574}
575
576inline rtl::Reference< SvXMLAutoStylePoolP > const & SvXMLExport::GetAutoStylePool()
577{
578 if( !mxAutoStylePool.is() )
9
Taking true branch
579 mxAutoStylePool = CreateAutoStylePool();
10
Value assigned to field 'pDoc'
580
581 return mxAutoStylePool;
582}
583
584inline rtl::Reference< SchXMLExportHelper > const & SvXMLExport::GetChartExport()
585{
586 if( !mxChartExport.is() )
587 mxChartExport = CreateChartExport();
588
589 return mxChartExport;
590}
591
592inline rtl::Reference< XMLPageExport > const & SvXMLExport::GetPageExport()
593{
594 if( !mxPageExport.is() )
595 mxPageExport = CreatePageExport();
596
597 return mxPageExport;
598}
599
600inline rtl::Reference< XMLFontAutoStylePool > const & SvXMLExport::GetFontAutoStylePool()
601{
602 if( !mxFontAutoStylePool.is() )
603 mxFontAutoStylePool = CreateFontAutoStylePool();
604
605 return mxFontAutoStylePool;
606}
607
608inline rtl::Reference< xmloff::OFormLayerXMLExport > const & SvXMLExport::GetFormExport()
609{
610 if( !mxFormExport.is() )
611 mxFormExport = CreateFormExport();
612
613 return mxFormExport;
614}
615
616inline bool SvXMLExport::HasFormExport() const
617{
618 return mxFormExport.is();
619}
620
621inline void SvXMLExport::SetEmbeddedResolver(
622 css::uno::Reference< css::document::XEmbeddedObjectResolver > const & _xEmbeddedResolver )
623{
624 mxEmbeddedResolver = _xEmbeddedResolver;
625}
626
627inline 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.
634class 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
647public:
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: */