Bug Summary

File:home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx
Warning:line 2920, column 9
Branch condition evaluates to a garbage value

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)
883 // No entry index for the number format is found.
884 return;
885
886 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
887 if (!pRefMgr->hasExternalData())
888 // No external reference data cached.
889 return;
890
891 // Export each unique number format used in the external ref cache.
892 vector<sal_uInt32> aNumFmts;
893 pRefMgr->getAllCachedNumberFormats(aNumFmts);
894 const OUString aDefaultStyle = OUString("Default").intern();
895 for (const auto& rNumFmt : aNumFmts)
896 {
897 sal_Int32 nNumFmt = static_cast<sal_Int32>(rNumFmt);
898
899 addDataStyle(nNumFmt);
900
901 uno::Any aVal;
902 aVal <<= nNumFmt;
903 vector<XMLPropertyState> aProps;
904 aVal <<= aDefaultStyle;
905 aProps.emplace_back(nEntryIndex, aVal);
906
907 OUString aName;
908 sal_Int32 nIndex;
909 if (GetAutoStylePool()->Add(aName, XmlStyleFamily::TABLE_CELL, aDefaultStyle, aProps))
910 {
911 pCellStyles->AddStyleName(aName, nIndex);
912 }
913 else
914 {
915 bool bIsAuto;
916 nIndex = pCellStyles->GetIndexOfStyleName(
917 aName, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX"ce", bIsAuto);
918 }
919
920 // store the number format to index mapping for later use.
921 aNumFmtIndexMap.emplace(nNumFmt, nIndex);
922 }
923}
924
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())
23
Taking true branch
1614 return;
24
Returning without writing to 'rHasColumnHeader'
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();
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)
1
Taking false branch
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())
2
Taking false branch
1869 return;
1870
1871 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
1872 if ( !xSpreadDoc.is() )
3
Taking false branch
1873 return;
1874
1875 ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetSheetSaveData();
1876 if (pSheetData)
4
Assuming 'pSheetData' is null
5
Taking false branch
1877 pSheetData->ResetSaveEntries();
1878
1879 uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
1880 if ( xIndex.is() )
6
Taking true branch
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)
7
Assuming 'nTableCount' is > 0
8
Taking true branch
1906 pValidationsContainer->WriteValidations(*this);
1907 WriteTheLabelRanges( xSpreadDoc );
1908 for (sal_Int32 nTable = 0; nTable
8.1
'nTable' is < 'nTableCount'
8.1
'nTable' is < 'nTableCount'
< nTableCount; ++nTable)
9
Loop condition is true. Entering loop body
1909 {
1910 sal_Int32 nStartOffset = -1;
1911 sal_Int32 nEndOffset = -1;
1912 if (pSheetData
9.1
'pSheetData' is null
9.1
'pSheetData' is null
&& pDoc && pDoc->IsStreamValid(static_cast<SCTAB>(nTable)) && !pDoc->GetChangeTrack())
1913 pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset );
1914
1915 if ( nStartOffset
9.2
'nStartOffset' is < 0
9.2
'nStartOffset' is < 0
>= 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);
10
Calling 'ScXMLExport::WriteTable'
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)
2222 return;
2223
2224 if (!GetModel().is())
2225 return;
2226
2227 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
2228 if (!xSpreadDoc.is())
2229 return;
2230
2231 uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
2232 if (!xIndex.is())
2233 return;
2234
2235 if (getExportFlags() & SvXMLExportFlags::CONTENT)
2236 {
2237 // Reserve the loaded cell style names.
2238 RegisterDefinedStyleNames( xSpreadDoc);
2239
2240 // re-create automatic styles with old names from stored data
2241 ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetSheetSaveData();
2242 if (pSheetData && pDoc)
2243 {
2244 // formulas have to be calculated now, to detect changed results
2245 // (during normal save, they will be calculated anyway)
2246 SCTAB nTabCount = pDoc->GetTableCount();
2247 for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
2248 if (pDoc->IsStreamValid(nTab))
2249 pDoc->InterpretDirtyCells(ScRange(0, 0, nTab, pDoc->MaxCol(), pDoc->MaxRow(), nTab));
2250
2251 // stored cell styles
2252 const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles();
2253 for (const auto& rCellEntry : rCellEntries)
2254 {
2255 ScAddress aPos = rCellEntry.maCellPos;
2256 sal_Int32 nTable = aPos.Tab();
2257 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2258 if (bCopySheet)
2259 {
2260 uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2261 uno::Reference <beans::XPropertySet> xProperties(
2262 xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY );
2263
2264 AddStyleFromCells(xProperties, xTable, nTable, &rCellEntry.maName);
2265 }
2266 }
2267
2268 // stored column styles
2269 const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles();
2270 for (const auto& rColumnEntry : rColumnEntries)
2271 {
2272 ScAddress aPos = rColumnEntry.maCellPos;
2273 sal_Int32 nTable = aPos.Tab();
2274 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2275 if (bCopySheet)
2276 {
2277 uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2278 uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
2279 uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY);
2280
2281 sal_Int32 nIndex(-1);
2282 bool bIsVisible(true);
2283 AddStyleFromColumn( xColumnProperties, &rColumnEntry.maName, nIndex, bIsVisible );
2284 }
2285 }
2286
2287 // stored row styles
2288 const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles();
2289 for (const auto& rRowEntry : rRowEntries)
2290 {
2291 ScAddress aPos = rRowEntry.maCellPos;
2292 sal_Int32 nTable = aPos.Tab();
2293 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2294 if (bCopySheet)
2295 {
2296 uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2297 uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
2298 uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY);
2299
2300 sal_Int32 nIndex(-1);
2301 AddStyleFromRow( xRowProperties, &rRowEntry.maName, nIndex );
2302 }
2303 }
2304
2305 // stored table styles
2306 const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles();
2307 for (const auto& rTableEntry : rTableEntries)
2308 {
2309 ScAddress aPos = rTableEntry.maCellPos;
2310 sal_Int32 nTable = aPos.Tab();
2311 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2312 if (bCopySheet)
2313 {
2314 //! separate method AddStyleFromTable needed?
2315 uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2316 if (xTableProperties.is())
2317 {
2318 std::vector<XMLPropertyState> aPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
2319 OUString sName( rTableEntry.maName );
2320 GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TABLE_TABLE, OUString(), aPropStates);
2321 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE, sName);
2322 }
2323 }
2324 }
2325
2326 // stored styles for notes
2327
2328 rtl::Reference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this );
2329 GetShapeExport(); // make sure the graphics styles family is added
2330
2331 const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles();
2332 for (const auto& rNoteEntry : rNoteEntries)
2333 {
2334 ScAddress aPos = rNoteEntry.maCellPos;
2335 SCTAB nTable = aPos.Tab();
2336 bool bCopySheet = pDoc->IsStreamValid( nTable );
2337 if (bCopySheet)
2338 {
2339 //! separate method AddStyleFromNote needed?
2340
2341 ScPostIt* pNote = pDoc->GetNote(aPos);
2342 OSL_ENSURE( pNote, "note not found" )do { if (true && (!(pNote))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx"
":" "2342" ": "), "%s", "note not found"); } } while (false)
;
2343 if (pNote)
2344 {
2345 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2346 // all uno shapes are created anyway in CollectSharedData
2347 uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY );
2348 if (xShapeProperties.is())
2349 {
2350 if ( !rNoteEntry.maStyleName.isEmpty() )
2351 {
2352 std::vector<XMLPropertyState> aPropStates(xShapeMapper->Filter(xShapeProperties));
2353 OUString sName( rNoteEntry.maStyleName );
2354 GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::SD_GRAPHICS_ID, OUString(), aPropStates);
2355 GetAutoStylePool()->RegisterName(XmlStyleFamily::SD_GRAPHICS_ID, sName);
2356 }
2357 if ( !rNoteEntry.maTextStyle.isEmpty() )
2358 {
2359 std::vector<XMLPropertyState> aPropStates(
2360 GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties));
2361 OUString sName( rNoteEntry.maTextStyle );
2362 GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TEXT_PARAGRAPH, OUString(), aPropStates);
2363 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH, sName);
2364 }
2365 }
2366 }
2367 }
2368 }
2369
2370 // note paragraph styles
2371
2372 rtl::Reference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper();
2373
2374 const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles();
2375 for (const auto& rNoteParaEntry : rNoteParaEntries)
2376 {
2377 ScAddress aPos = rNoteParaEntry.maCellPos;
2378 SCTAB nTable = aPos.Tab();
2379 bool bCopySheet = pDoc->IsStreamValid( nTable );
2380 if (bCopySheet)
2381 {
2382 ScPostIt* pNote = pDoc->GetNote( aPos );
2383 OSL_ENSURE( pNote, "note not found" )do { if (true && (!(pNote))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx"
":" "2383" ": "), "%s", "note not found"); } } while (false)
;
2384 if (pNote)
2385 {
2386 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2387 uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
2388 uno::Reference<beans::XPropertySet> xParaProp(
2389 lcl_GetEnumerated( xCellText, rNoteParaEntry.maSelection.nStartPara ), uno::UNO_QUERY );
2390 if ( xParaProp.is() )
2391 {
2392 std::vector<XMLPropertyState> aPropStates(xParaPropMapper->Filter(xParaProp));
2393 OUString sName( rNoteParaEntry.maName );
2394 GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TEXT_PARAGRAPH, OUString(), aPropStates);
2395 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH, sName);
2396 }
2397 }
2398 }
2399 }
2400
2401 // note text styles
2402
2403 rtl::Reference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
2404
2405 const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles();
2406 for (const auto& rNoteTextEntry : rNoteTextEntries)
2407 {
2408 ScAddress aPos = rNoteTextEntry.maCellPos;
2409 SCTAB nTable = aPos.Tab();
2410 bool bCopySheet = pDoc->IsStreamValid( nTable );
2411 if (bCopySheet)
2412 {
2413 ScPostIt* pNote = pDoc->GetNote( aPos );
2414 OSL_ENSURE( pNote, "note not found" )do { if (true && (!(pNote))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/xml/xmlexprt.cxx"
":" "2414" ": "), "%s", "note not found"); } } while (false)
;
2415 if (pNote)
2416 {
2417 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2418 uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
2419 uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
2420 ScDrawTextCursor* pCursor = comphelper::getUnoTunnelImplementation<ScDrawTextCursor>( xCursorProp );
2421 if (pCursor)
2422 {
2423 pCursor->SetSelection( rNoteTextEntry.maSelection );
2424
2425 std::vector<XMLPropertyState> aPropStates(xTextPropMapper->Filter(xCursorProp));
2426 OUString sName( rNoteTextEntry.maName );
2427 GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TEXT_TEXT, OUString(), aPropStates);
2428 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT, sName);
2429 }
2430 }
2431 }
2432 }
2433
2434 // stored text styles
2435
2436 // Calling createTextCursor fires up editeng, which is very slow, and often subsequent style entries
2437 // refer to the same cell, so cache it.
2438 ScAddress aPrevPos;
2439 uno::Reference<beans::XPropertySet> xPrevCursorProp;
2440 const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles();
2441 for (const auto& rTextEntry : rTextEntries)
2442 {
2443 ScAddress aPos = rTextEntry.maCellPos;
2444 sal_Int32 nTable = aPos.Tab();
2445 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2446 if (!bCopySheet)
2447 continue;
2448
2449 //! separate method AddStyleFromText needed?
2450 //! cache sheet object
2451
2452 uno::Reference<beans::XPropertySet> xCursorProp;
2453 if (xPrevCursorProp && aPrevPos == aPos)
2454 xCursorProp = xPrevCursorProp;
2455 else
2456 {
2457 uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2458 uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY);
2459 xCursorProp.set(xCellText->createTextCursor(), uno::UNO_QUERY);
2460 }
2461 ScCellTextCursor* pCursor = comphelper::getUnoTunnelImplementation<ScCellTextCursor>( xCursorProp );
2462 if (!pCursor)
2463 continue;
2464 pCursor->SetSelection( rTextEntry.maSelection );
2465
2466 std::vector<XMLPropertyState> aPropStates(xTextPropMapper->Filter(xCursorProp));
2467 OUString sName( rTextEntry.maName );
2468 GetAutoStylePool()->AddNamed(sName, XmlStyleFamily::TEXT_TEXT, OUString(), aPropStates);
2469 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT, sName);
2470 xPrevCursorProp = xCursorProp;
2471 aPrevPos = aPos;
2472 }
2473 }
2474
2475 ExportExternalRefCacheStyles();
2476
2477 if (!pSharedData)
2478 {
2479 SCTAB nTableCount(0);
2480 sal_Int32 nShapesCount(0);
2481 CollectSharedData(nTableCount, nShapesCount);
2482 }
2483 sal_Int32 nTableCount(xIndex->getCount());
2484 pCellStyles->AddNewTable(nTableCount - 1);
2485 CollectShapesAutoStyles(nTableCount);
2486 for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable, IncrementProgressBar(false))
2487 {
2488 uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2489 if (!xTable.is())
2490 continue;
2491
2492 // table styles array must be complete, including copied tables - Add should find the stored style
2493 uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
2494 if (xTableProperties.is())
2495 {
2496 std::vector<XMLPropertyState> aPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
2497 if(!aPropStates.empty())
2498 {
2499 OUString sName;
2500 GetAutoStylePool()->Add(sName, XmlStyleFamily::TABLE_TABLE, OUString(), aPropStates);
2501 aTableStyles.push_back(sName);
2502 }
2503 }
2504
2505 // collect other auto-styles only for non-copied sheets
2506 uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY );
2507 if ( xCellFormatRanges.is() )
2508 {
2509 uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges());
2510 if (xFormatRangesIndex.is())
2511 {
2512 sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount());
2513 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount);
2514 for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange)
2515 {
2516 uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY);
2517 if (xCellRanges.is())
2518 {
2519 uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY);
2520 if (xProperties.is())
2521 {
2522 AddStyleFromCells(xProperties, xTable, nTable, nullptr);
2523 IncrementProgressBar(false);
2524 }
2525 }
2526 }
2527 }
2528 }
2529 uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY);
2530 if (xColumnRowRange.is() && pDoc)
2531 {
2532 pDoc->SyncColRowFlags();
2533 uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
2534 if (xTableColumns.is())
2535 {
2536 sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable)));
2537 pSharedData->SetLastColumn(nTable, nColumns);
2538 table::CellRangeAddress aCellAddress(GetEndAddress(xTable));
2539 if (aCellAddress.EndColumn > nColumns)
2540 {
2541 ++nColumns;
2542 pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn);
2543 }
2544 else
2545 pColumnStyles->AddNewTable(nTable, nColumns);
2546 sal_Int32 nColumn = 0;
2547 while (nColumn <= pDoc->MaxCol())
2548 {
2549 sal_Int32 nIndex(-1);
2550 bool bIsVisible(true);
2551 uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY);
2552 if (xColumnProperties.is())
2553 {
2554 AddStyleFromColumn( xColumnProperties, nullptr, nIndex, bIsVisible );
2555 pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible);
2556 }
2557 sal_Int32 nOld(nColumn);
2558 nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn));
2559 for (sal_Int32 i = nOld + 1; i < nColumn; ++i)
2560 pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
2561 }
2562 if (aCellAddress.EndColumn > nColumns)
2563 {
2564 bool bIsVisible(true);
2565 sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible));
2566 for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i)
2567 pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
2568 }
2569 }
2570 uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
2571 if (xTableRows.is())
2572 {
2573 sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable)));
2574 pSharedData->SetLastRow(nTable, nRows);
2575
2576 pRowStyles->AddNewTable(nTable, pDoc->MaxRow());
2577 sal_Int32 nRow = 0;
2578 while (nRow <= pDoc->MaxRow())
2579 {
2580 sal_Int32 nIndex = 0;
2581 uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY);
2582 if(xRowProperties.is())
2583 {
2584 AddStyleFromRow( xRowProperties, nullptr, nIndex );
2585 pRowStyles->AddFieldStyleName(nTable, nRow, nIndex);
2586 }
2587 sal_Int32 nOld(nRow);
2588 nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow));
2589 if (nRow > nOld + 1)
2590 pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1);
2591 }
2592 }
2593 }
2594 ExportCellTextAutoStyles(nTable);
2595 }
2596
2597 pChangeTrackingExportHelper->CollectAutoStyles();
2598 }
2599
2600 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES)
2601 GetPageExport()->collectAutoStyles(true);
2602
2603 mbAutoStylesCollected = true;
2604}
2605
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())
11
Calling 'BaseReference::is'
14
Returning from 'BaseReference::is'
15
Taking false branch
2783 return;
2784
2785 xCurrentTable.set(xTable);
2786 uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY );
2787 if (!xName.is())
16
Calling 'BaseReference::is'
19
Returning from 'BaseReference::is'
20
Taking false branch
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;
21
'bHasColumnHeader' declared without an initial value
2857 GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges);
22
Calling 'ScXMLExport::GetColumnRowHeader'
25
Returning from 'ScXMLExport::GetColumnRowHeader'
2858 if( !sPrintRanges.isEmpty() )
26
Taking true branch
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
26.1
'pProtect' is null
26.1
'pProtect' is null
&& 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) ) &&
27
Assuming field 'pDoc' is null
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())
28
Assuming the condition is false
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())
29
Taking false branch
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)
30
Branch condition evaluates to a garbage value
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/com/sun/star/uno/Reference.h

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#ifndef INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
20#define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
21
22#include "sal/config.h"
23
24#include <cassert>
25#include <cstddef>
26
27#if defined LIBO_INTERNAL_ONLY1
28#include <type_traits>
29#endif
30
31#include "rtl/alloc.h"
32
33namespace com
34{
35namespace sun
36{
37namespace star
38{
39namespace uno
40{
41
42class RuntimeException;
43class XInterface;
44class Type;
45class Any;
46
47/** Enum defining UNO_REF_NO_ACQUIRE for setting reference without acquiring a given interface.
48 Deprecated, please use SAL_NO_ACQUIRE.
49 @deprecated
50*/
51enum UnoReference_NoAcquire
52{
53 /** This enum value can be used for creating a reference granting a given interface,
54 i.e. transferring ownership to it.
55 */
56 UNO_REF_NO_ACQUIRE
57};
58
59/** This base class serves as a base class for all template reference classes and
60 has been introduced due to compiler problems with templated operators ==, =!.
61*/
62class BaseReference
63{
64protected:
65 /** the interface pointer
66 */
67 XInterface * _pInterface;
68
69 /** Queries given interface for type rType.
70
71 @param pInterface interface pointer
72 @param rType interface type
73 @return interface of demanded type (may be null)
74 */
75 inline static XInterface * SAL_CALL iquery( XInterface * pInterface, const Type & rType );
76 /** Queries given interface for type rType.
77 Throws a RuntimeException if the demanded interface cannot be queried.
78
79 @param pInterface interface pointer
80 @param rType interface type
81 @return interface of demanded type
82 */
83 inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface, const Type & rType );
84
85public:
86 /** Gets interface pointer. This call does not acquire the interface.
87
88 @return UNacquired interface pointer
89 */
90 XInterface * SAL_CALL get() const
91 { return _pInterface; }
92
93 /** Checks if reference is null.
94
95 @return true if reference acquires an interface, i.e. true if it is not null
96 */
97 bool SAL_CALL is() const
98 { return (NULL__null != _pInterface); }
12
Assuming NULL is not equal to field '_pInterface'
13
Returning the value 1, which participates in a condition later
17
Assuming NULL is not equal to field '_pInterface'
18
Returning the value 1, which participates in a condition later
99
100#if defined LIBO_INTERNAL_ONLY1
101 /** Checks if reference is null.
102
103 @return true if reference acquires an interface, i.e. true if it is not null
104 */
105 explicit operator bool() const
106 { return is(); }
107#endif
108
109 /** Equality operator: compares two interfaces
110 Checks if both references are null or refer to the same object.
111
112 @param pInterface another interface
113 @return true if both references are null or refer to the same object, false otherwise
114 */
115 inline bool SAL_CALL operator == ( XInterface * pInterface ) const;
116 /** Inequality operator: compares two interfaces
117 Checks if both references are null or refer to the same object.
118
119 @param pInterface another interface
120 @return false if both references are null or refer to the same object, true otherwise
121 */
122 inline bool SAL_CALL operator != ( XInterface * pInterface ) const;
123
124 /** Equality operator: compares two interfaces
125 Checks if both references are null or refer to the same object.
126
127 @param rRef another reference
128 @return true if both references are null or refer to the same object, false otherwise
129 */
130 inline bool SAL_CALL operator == ( const BaseReference & rRef ) const;
131 /** Inequality operator: compares two interfaces
132 Checks if both references are null or refer to the same object.
133
134 @param rRef another reference
135 @return false if both references are null or refer to the same object, true otherwise
136 */
137 inline bool SAL_CALL operator != ( const BaseReference & rRef ) const;
138
139 /** Needed by some STL containers.
140
141 @param rRef another reference
142 @return true, if this reference is less than rRef
143 */
144 inline bool SAL_CALL operator < ( const BaseReference & rRef ) const;
145};
146
147/** Enum defining UNO_QUERY for implicit interface query.
148*/
149enum UnoReference_Query
150{
151 /** This enum value can be used for implicit interface query.
152 */
153 UNO_QUERY
154};
155/** Enum defining UNO_QUERY_THROW for implicit interface query.
156 If the demanded interface is unavailable, then a RuntimeException is thrown.
157*/
158enum UnoReference_QueryThrow
159{
160 /** This enum value can be used for implicit interface query.
161 */
162 UNO_QUERY_THROW
163};
164/** Enum defining UNO_SET_THROW for throwing if attempts are made to assign a null
165 interface
166
167 @since UDK 3.2.8
168*/
169enum UnoReference_SetThrow
170{
171 UNO_SET_THROW
172};
173
174/** Template reference class for interface type derived from BaseReference.
175 A special constructor given the UNO_QUERY identifier queries interfaces
176 for reference type.
177*/
178template< class interface_type >
179class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) Reference : public BaseReference
180{
181 /** Queries given interface for type interface_type.
182
183 @param pInterface interface pointer
184 @return interface of demanded type (may be null)
185 */
186 inline static XInterface * SAL_CALL iquery( XInterface * pInterface );
187 /** Queries given interface for type interface_type.
188 Throws a RuntimeException if the demanded interface cannot be queried.
189
190 @param pInterface interface pointer
191 @return interface of demanded type
192 */
193 inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface );
194 /** Returns the given interface if it is not <NULL/>, throws a RuntimeException otherwise.
195
196 @param pInterface interface pointer
197 @return pInterface
198 */
199 inline static interface_type * SAL_CALL iset_throw( interface_type * pInterface );
200
201 /** Cast from an "interface pointer" (e.g., BaseReference::_pInterface) to a
202 pointer to this interface_type.
203
204 To work around ambiguities in the case of multiple-inheritance interface
205 types (which inherit XInterface more than once), use reinterpret_cast
206 (resp. a sequence of two static_casts, to avoid warnings about
207 reinterpret_cast used between related classes) to switch from a pointer
208 to XInterface to a pointer to this derived interface_type. In
209 principle, this is not guaranteed to work. In practice, it seems to
210 work on all supported platforms.
211 */
212 static interface_type * castFromXInterface(XInterface * p) {
213 return static_cast< interface_type * >(static_cast< void * >(p));
214 }
215
216 /** Cast from a pointer to this interface_type to an "interface pointer"
217 (e.g., BaseReference::_pInterface).
218
219 To work around ambiguities in the case of multiple-inheritance interface
220 types (which inherit XInterface more than once), use reinterpret_cast
221 (resp. a sequence of two static_casts, to avoid warnings about
222 reinterpret_cast used between related classes) to switch from a pointer
223 to this derived interface_type to a pointer to XInterface. In
224 principle, this is not guaranteed to work. In practice, it seems to
225 work on all supported platforms.
226 */
227 static XInterface * castToXInterface(interface_type * p) {
228 return static_cast< XInterface * >(static_cast< void * >(p));
229 }
230
231public:
232 /// @cond INTERNAL
233 // these are here to force memory de/allocation to sal lib.
234 static void * SAL_CALL operator new ( ::size_t nSize )
235 { return ::rtl_allocateMemory( nSize ); }
236 static void SAL_CALL operator delete ( void * pMem )
237 { ::rtl_freeMemory( pMem ); }
238 static void * SAL_CALL operator new ( ::size_t, void * pMem )
239 { return pMem; }
240 static void SAL_CALL operator delete ( void *, void * )
241 {}
242 /// @endcond
243
244 /** Destructor: Releases interface if set.
245 */
246 inline ~Reference() COVERITY_NOEXCEPT_FALSE;
247
248 /** Default Constructor: Sets null reference.
249 */
250 inline Reference();
251
252 /** Copy constructor: Copies interface reference.
253
254 @param rRef another reference
255 */
256 inline Reference( const Reference< interface_type > & rRef );
257
258#if defined LIBO_INTERNAL_ONLY1
259 /** Move constructor
260
261 @param rRef another reference
262 */
263 inline Reference( Reference< interface_type > && rRef ) noexcept;
264
265 /** Up-casting conversion constructor: Copies interface reference.
266
267 Does not work for up-casts to ambiguous bases. For the special case of
268 up-casting to Reference< XInterface >, see the corresponding conversion
269 operator.
270
271 @param rRef another reference
272 */
273 template< class derived_type >
274 inline Reference(
275 const Reference< derived_type > & rRef,
276 std::enable_if_t<
277 std::is_base_of_v<interface_type, derived_type>
278 && !std::is_same_v<interface_type, XInterface>, void *> = nullptr);
279#endif
280
281 /** Constructor: Sets given interface pointer.
282
283 @param pInterface an interface pointer
284 */
285 inline Reference( interface_type * pInterface );
286
287 /** Constructor: Sets given interface pointer without acquiring it.
288
289 @param pInterface another reference
290 @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors
291 */
292 inline Reference( interface_type * pInterface, __sal_NoAcquire dummy);
293 /** Constructor: Sets given interface pointer without acquiring it.
294 Deprecated, please use SAL_NO_ACQUIRE version.
295
296 @deprecated
297 @param pInterface another reference
298 @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to other constructors
299 */
300 inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version")__attribute__((deprecated("use SAL_NO_ACQUIRE version"))) Reference( interface_type * pInterface, UnoReference_NoAcquire dummy );
301
302 /** Constructor: Queries given interface for reference interface type (interface_type).
303
304 @param rRef another reference
305 @param dummy UNO_QUERY to force obvious distinction to other constructors
306 */
307 inline Reference( const BaseReference & rRef, UnoReference_Query dummy );
308 /** Constructor: Queries given interface for reference interface type (interface_type).
309
310 @param pInterface an interface pointer
311 @param dummy UNO_QUERY to force obvious distinction to other constructors
312 */
313 inline Reference( XInterface * pInterface, UnoReference_Query dummy);
314 /** Constructor: Queries given any for reference interface type (interface_type).
315
316 @param rAny an any
317 @param dummy UNO_QUERY to force obvious distinction to other constructors
318 */
319 inline Reference( const Any & rAny, UnoReference_Query dummy);
320 /** Constructor: Queries given interface for reference interface type (interface_type).
321 Throws a RuntimeException if the demanded interface cannot be queried.
322
323 @param rRef another reference
324 @param dummy UNO_QUERY_THROW to force obvious distinction
325 to other constructors
326 */
327 inline Reference( const BaseReference & rRef, UnoReference_QueryThrow dummy );
328#ifdef LIBO_INTERNAL_ONLY1
329 /**
330 Prevent code from calling the QUERY_THROW constructor, when they meant to use the SET_THROW constructor.
331 */
332 Reference( const Reference< interface_type > & rRef, UnoReference_QueryThrow dummy ) = delete;
333#endif
334 /** Constructor: Queries given interface for reference interface type (interface_type).
335 Throws a RuntimeException if the demanded interface cannot be queried.
336
337 @param pInterface an interface pointer
338 @param dummy UNO_QUERY_THROW to force obvious distinction
339 to other constructors
340 */
341 inline Reference( XInterface * pInterface, UnoReference_QueryThrow dummy );
342 /** Constructor: Queries given any for reference interface type (interface_type).
343 Throws a RuntimeException if the demanded interface cannot be queried.
344
345 @param rAny an any
346 @param dummy UNO_QUERY_THROW to force obvious distinction
347 to other constructors
348 */
349 inline Reference( const Any & rAny, UnoReference_QueryThrow dummy );
350 /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
351 if the source interface is NULL.
352
353 @param rRef another interface reference of the same type
354 @param dummy UNO_SET_THROW to distinguish from default copy constructor
355
356 @since UDK 3.2.8
357 */
358 inline Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy );
359 /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
360 if the source interface is NULL.
361
362 @param pInterface an interface pointer
363 @param dummy UNO_SET_THROW to distinguish from default assignment constructor
364
365 @since UDK 3.2.8
366 */
367 inline Reference( interface_type * pInterface, UnoReference_SetThrow dummy );
368
369 /** Cast operator to Reference< XInterface >: Reference objects are binary compatible and
370 any interface must be derived from com.sun.star.uno.XInterface.
371 This a useful direct cast possibility.
372 */
373 SAL_CALL operator const Reference< XInterface > & () const
374 { return * reinterpret_cast< const Reference< XInterface > * >( this ); }
375
376 /** Dereference operator: Used to call interface methods.
377
378 @return UNacquired interface pointer
379 */
380 interface_type * SAL_CALL operator -> () const {
381 assert(_pInterface != NULL)(static_cast <bool> (_pInterface != __null) ? void (0) :
__assert_fail ("_pInterface != NULL", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Reference.h"
, 381, __extension__ __PRETTY_FUNCTION__))
;
382 return castFromXInterface(_pInterface);
383 }
384
385 /** Indirection operator.
386
387 @since LibreOffice 6.3
388 @return UNacquired interface reference
389 */
390 interface_type & SAL_CALL operator * () const {
391 assert(_pInterface != NULL)(static_cast <bool> (_pInterface != __null) ? void (0) :
__assert_fail ("_pInterface != NULL", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Reference.h"
, 391, __extension__ __PRETTY_FUNCTION__))
;
392 return *castFromXInterface(_pInterface);
393 }
394
395 /** Gets interface pointer. This call does not acquire the interface.
396
397 @return UNacquired interface pointer
398 */
399 interface_type * SAL_CALL get() const
400 { return castFromXInterface(_pInterface); }
401
402 /** Clears reference, i.e. releases interface. Reference is null after clear() call.
403 */
404 inline void SAL_CALL clear();
405
406 /** Sets the given interface. An interface already set will be released.
407
408 @param rRef another reference
409 @return true, if non-null interface was set
410 */
411 inline bool SAL_CALL set( const Reference< interface_type > & rRef );
412 /** Sets the given interface. An interface already set will be released.
413
414 @param pInterface another interface
415 @return true, if non-null interface was set
416 */
417 inline bool SAL_CALL set( interface_type * pInterface );
418
419 /** Sets interface pointer without acquiring it. An interface already set will be released.
420
421 @param pInterface an interface pointer
422 @param dummy SAL_NO_ACQUIRE to force obvious distinction to set methods
423 @return true, if non-null interface was set
424 */
425 inline bool SAL_CALL set( interface_type * pInterface, __sal_NoAcquire dummy);
426 /** Sets interface pointer without acquiring it. An interface already set will be released.
427 Deprecated, please use SAL_NO_ACQUIRE version.
428
429 @deprecated
430 @param pInterface an interface pointer
431 @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to set methods
432 @return true, if non-null interface was set
433 */
434 inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version")__attribute__((deprecated("use SAL_NO_ACQUIRE version"))) bool SAL_CALL set( interface_type * pInterface, UnoReference_NoAcquire dummy);
435
436 /** Queries given interface for reference interface type (interface_type) and sets it.
437 An interface already set will be released.
438
439 @param pInterface an interface pointer
440 @param dummy UNO_QUERY to force obvious distinction to set methods
441 @return true, if non-null interface was set
442 */
443 inline bool SAL_CALL set( XInterface * pInterface, UnoReference_Query dummy );
444 /** Queries given interface for reference interface type (interface_type) and sets it.
445 An interface already set will be released.
446
447 @param rRef another reference
448 @param dummy UNO_QUERY to force obvious distinction to set methods
449 @return true, if non-null interface was set
450 */
451 inline bool SAL_CALL set( const BaseReference & rRef, UnoReference_Query dummy);
452
453 /** Queries given any for reference interface type (interface_type)
454 and sets it. An interface already set will be released.
455
456 @param rAny
457 an Any containing an interface
458 @param dummy
459 UNO_QUERY to force obvious distinction
460 to set methods
461 @return
462 true, if non-null interface was set
463 */
464 inline bool set( Any const & rAny, UnoReference_Query dummy );
465
466 /** Queries given interface for reference interface type (interface_type) and sets it.
467 An interface already set will be released.
468 Throws a RuntimeException if the demanded interface cannot be set.
469
470 @param pInterface an interface pointer
471 @param dummy UNO_QUERY_THROW to force obvious distinction
472 to set methods
473 */
474 inline void SAL_CALL set( XInterface * pInterface, UnoReference_QueryThrow dummy );
475 /** Queries given interface for reference interface type (interface_type) and sets it.
476 An interface already set will be released.
477 Throws a RuntimeException if the demanded interface cannot be set.
478
479 @param rRef another reference
480 @param dummy UNO_QUERY_THROW to force obvious distinction
481 to set methods
482 */
483 inline void SAL_CALL set( const BaseReference & rRef, UnoReference_QueryThrow dummy );
484#ifdef LIBO_INTERNAL_ONLY1
485 /**
486 Prevent code from calling the QUERY_THROW version, when they meant to use the SET_THROW version.
487 */
488 void set( const Reference< interface_type > & rRef, UnoReference_QueryThrow dummy ) = delete;
489#endif
490
491 /** Queries given any for reference interface type (interface_type) and
492 sets it. An interface already set will be released.
493 Throws a RuntimeException if the demanded interface cannot be set.
494
495 @param rAny
496 an Any containing an interface
497 @param dummy
498 UNO_QUERY_THROW to force obvious distinction to set methods
499 */
500 inline void set( Any const & rAny, UnoReference_QueryThrow dummy);
501 /** sets the given interface
502 An interface already set will be released.
503 Throws a RuntimeException if the source interface is @b NULL.
504
505 @param pInterface an interface pointer
506 @param dummy UNO_SET_THROW to force obvious distinction to other set methods
507
508 @since UDK 3.2.8
509 */
510 inline void SAL_CALL set( interface_type * pInterface, UnoReference_SetThrow dummy);
511 /** sets the given interface
512 An interface already set will be released.
513 Throws a RuntimeException if the source interface is @b NULL.
514
515 @param rRef an interface reference
516 @param dummy UNO_SET_THROW to force obvious distinction to other set methods
517
518 @since UDK 3.2.8
519 */
520 inline void SAL_CALL set( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy);
521
522
523 /** Assignment operator: Acquires given interface pointer and sets reference.
524 An interface already set will be released.
525
526 @param pInterface an interface pointer
527 @return this reference
528 */
529 inline Reference< interface_type > & SAL_CALL operator = ( interface_type * pInterface );
530 /** Assignment operator: Acquires given interface reference and sets reference.
531 An interface already set will be released.
532
533 @param rRef an interface reference
534 @return this reference
535 */
536 inline Reference< interface_type > & SAL_CALL operator = ( const Reference< interface_type > & rRef );
537#if defined LIBO_INTERNAL_ONLY1
538 /** Assignment move operator: Acquires given interface reference and sets reference.
539 An interface already set will be released.
540
541 @param rRef an interface reference
542 @return this reference
543 */
544 inline Reference< interface_type > & SAL_CALL operator = ( Reference< interface_type > && rRef ) noexcept;
545#endif
546 /** Queries given interface reference for type interface_type.
547
548 @param rRef interface reference
549 @return interface reference of demanded type (may be null)
550 */
551 SAL_WARN_UNUSED_RESULT[[nodiscard]] inline static Reference< interface_type > SAL_CALL query( const BaseReference & rRef );
552 /** Queries given interface for type interface_type.
553
554 @param pInterface interface pointer
555 @return interface reference of demanded type (may be null)
556 */
557 SAL_WARN_UNUSED_RESULT[[nodiscard]] inline static Reference< interface_type > SAL_CALL query( XInterface * pInterface );
558};
559
560}
561}
562}
563}
564
565#endif
566
567/* vim:set shiftwidth=4 softtabstop=4 expandtab: */