1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
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 "XMLColumnRowGroupExport.hxx"
37 #include "XMLStylesExportHelper.hxx"
38 #include "XMLChangeTrackingExportHelper.hxx"
39 #include <sheetdata.hxx>
40 #include <docoptio.hxx>
41 #include "XMLExportSharedData.hxx"
42 #include <chgviset.hxx>
44 #include <textuno.hxx>
45 #include <chartlis.hxx>
46 #include <scitems.hxx>
47 #include <docpool.hxx>
48 #include <userdat.hxx>
49 #include <chgtrack.hxx>
50 #include <rangeutl.hxx>
52 #include <externalrefmgr.hxx>
53 #include <editutil.hxx>
54 #include <tabprotection.hxx>
55 #include "cachedattraccess.hxx"
56 #include <colorscale.hxx>
57 #include <conditio.hxx>
58 #include <cellvalue.hxx>
59 #include <stylehelper.hxx>
60 #include <edittextiterator.hxx>
61 #include "editattributemap.hxx"
62 #include <arealink.hxx>
63 #include <datastream.hxx>
64 #include <documentlinkmgr.hxx>
65 #include <tokenstringcontext.hxx>
66 #include <cellform.hxx>
67 #include <datamapper.hxx>
68 #include <datatransformation.hxx>
69 #include "SparklineGroupsExport.hxx"
70 #include <SparklineList.hxx>
72 #include <xmloff/xmltoken.hxx>
73 #include <xmloff/xmlnamespace.hxx>
74 #include <xmloff/xmluconv.hxx>
75 #include <xmloff/namespacemap.hxx>
76 #include <xmloff/families.hxx>
77 #include <xmloff/numehelp.hxx>
78 #include <xmloff/txtparae.hxx>
79 #include <editeng/autokernitem.hxx>
80 #include <editeng/charreliefitem.hxx>
81 #include <editeng/charscaleitem.hxx>
82 #include <editeng/colritem.hxx>
83 #include <editeng/contouritem.hxx>
84 #include <editeng/crossedoutitem.hxx>
85 #include <editeng/emphasismarkitem.hxx>
86 #include <editeng/escapementitem.hxx>
87 #include <editeng/fhgtitem.hxx>
88 #include <editeng/fontitem.hxx>
89 #include <editeng/kernitem.hxx>
90 #include <editeng/langitem.hxx>
91 #include <editeng/postitem.hxx>
92 #include <editeng/section.hxx>
93 #include <editeng/shdditem.hxx>
94 #include <editeng/udlnitem.hxx>
95 #include <editeng/wghtitem.hxx>
96 #include <editeng/wrlmitem.hxx>
97 #include <editeng/xmlcnitm.hxx>
98 #include <editeng/flditem.hxx>
99 #include <editeng/eeitem.hxx>
100 #include <formula/errorcodes.hxx>
101 #include <xmloff/xmlerror.hxx>
102 #include <xmloff/XMLEventExport.hxx>
103 #include <xmloff/xmlprmap.hxx>
104 #include <xmloff/ProgressBarHelper.hxx>
105 #include <xmloff/table/XMLTableExport.hxx>
107 #include <sax/tools/converter.hxx>
108 #include <tools/fldunit.hxx>
110 #include <rtl/ustring.hxx>
112 #include <tools/color.hxx>
113 #include <comphelper/diagnose_ex.hxx>
114 #include <rtl/math.hxx>
115 #include <svl/numformat.hxx>
116 #include <svl/zforlist.hxx>
117 #include <comphelper/base64.hxx>
118 #include <comphelper/extract.hxx>
119 #include <svx/svdoashp.hxx>
120 #include <svx/svdobj.hxx>
121 #include <svx/svdocapt.hxx>
122 #include <svx/svdomeas.hxx>
123 #include <svx/svdmodel.hxx>
124 #include <vcl/svapp.hxx>
125 #include <docmodel/theme/Theme.hxx>
127 #include <comphelper/processfactory.hxx>
128 #include <com/sun/star/beans/XPropertySet.hpp>
129 #include <com/sun/star/container/XNamed.hpp>
130 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
131 #include <com/sun/star/form/XFormsSupplier2.hpp>
132 #include <com/sun/star/io/XActiveDataSource.hpp>
133 #include <com/sun/star/io/XSeekable.hpp>
134 #include <com/sun/star/sheet/XUsedAreaCursor.hpp>
135 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
136 #include <com/sun/star/sheet/XPrintAreas.hpp>
137 #include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp>
138 #include <com/sun/star/sheet/XLabelRange.hpp>
139 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
140 #include <com/sun/star/sheet/XSheetCellCursor.hpp>
141 #include <com/sun/star/sheet/XSheetCellRanges.hpp>
142 #include <com/sun/star/sheet/XSheetLinkable.hpp>
143 #include <com/sun/star/sheet/GlobalSheetSettings.hpp>
144 #include <com/sun/star/table/XColumnRowRange.hpp>
145 #include <com/sun/star/util/XProtectable.hpp>
146 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
147 #include <com/sun/star/chart2/XChartDocument.hpp>
148 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
149 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
151 #include <com/sun/star/document/XDocumentProperties.hpp>
152 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
154 #include "XMLCodeNameProvider.hxx"
156 #include <sfx2/linkmgr.hxx>
157 #include <sfx2/objsh.hxx>
161 #include <vbahelper/vbaaccesshelper.hxx>
162 #include <officecfg/Office/Common.hxx>
164 namespace com::sun::star::uno
{ class XComponentContext
; }
168 //! not found in unonames.hxx
169 constexpr OUString SC_LAYERID
= u
"LayerID"_ustr
;
171 #define SC_VIEWCHANGES_COUNT 13
172 #define SC_SHOW_CHANGES 0
173 #define SC_SHOW_ACCEPTED_CHANGES 1
174 #define SC_SHOW_REJECTED_CHANGES 2
175 #define SC_SHOW_CHANGES_BY_DATETIME 3
176 #define SC_SHOW_CHANGES_BY_DATETIME_MODE 4
177 #define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5
178 #define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6
179 #define SC_SHOW_CHANGES_BY_AUTHOR 7
180 #define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8
181 #define SC_SHOW_CHANGES_BY_COMMENT 9
182 #define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10
183 #define SC_SHOW_CHANGES_BY_RANGES 11
184 #define SC_SHOW_CHANGES_BY_RANGES_LIST 12
186 using namespace formula
;
187 using namespace com::sun::star
;
188 using namespace xmloff::token
;
190 using ::com::sun::star::uno::UNO_QUERY
;
194 OUString
lcl_RangeSequenceToString(
195 const uno::Sequence
< OUString
> & rRanges
,
196 const uno::Reference
< chart2::data::XRangeXMLConversion
> & xFormatConverter
)
198 OUStringBuffer aResult
;
199 const sal_Int32
nMaxIndex( rRanges
.getLength() - 1 );
200 const sal_Unicode
cSep(' ');
201 for( sal_Int32 i
=0; i
<=nMaxIndex
; ++i
)
203 OUString
aRange( rRanges
[i
] );
204 if( xFormatConverter
.is())
205 aRange
= xFormatConverter
->convertRangeToXML( aRange
);
206 aResult
.append( aRange
);
208 aResult
.append( cSep
);
210 return aResult
.makeStringAndClear();
213 OUString
lcl_GetFormattedString(ScDocument
& rDoc
, const ScRefCellValue
& rCell
, const ScAddress
& rAddr
)
215 // return text/edit cell string content, with line feeds in edit cells
217 switch (rCell
.getType())
219 case CELLTYPE_STRING
:
222 sal_uInt32 nFormat
= rDoc
.GetNumberFormat(ScRange(rAddr
));
223 return ScCellFormat::GetString(rCell
, nFormat
, &pColor
, nullptr, rDoc
);
227 const EditTextObject
* pData
= rCell
.getEditText();
231 EditEngine
& rEngine
= rDoc
.GetEditEngine();
232 rEngine
.SetText(*pData
);
233 return rEngine
.GetText();
243 } // anonymous namespace
245 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
246 Calc_XMLExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
248 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLExporter"_ustr
, SvXMLExportFlags::ALL
));
251 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
252 Calc_XMLMetaExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
254 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLMetaExporter"_ustr
, SvXMLExportFlags::META
));
257 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
258 Calc_XMLStylesExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
260 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLStylesExporter"_ustr
, SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::FONTDECLS
));
263 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
264 Calc_XMLContentExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
266 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLContentExporter"_ustr
, SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SCRIPTS
|SvXMLExportFlags::FONTDECLS
));
269 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
270 Calc_XMLSettingsExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
272 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLSettingsExporter"_ustr
, SvXMLExportFlags::SETTINGS
));
275 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
276 Calc_XMLOasisExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
278 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLOasisExporter"_ustr
, SvXMLExportFlags::ALL
|SvXMLExportFlags::OASIS
));
281 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
282 Calc_XMLOasisMetaExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
284 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLOasisMetaExporter"_ustr
, SvXMLExportFlags::META
|SvXMLExportFlags::OASIS
));
287 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
288 Calc_XMLOasisStylesExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
290 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLOasisStylesExporter"_ustr
, SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::OASIS
));
293 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
294 Calc_XMLOasisContentExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
296 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLOasisContentExporter"_ustr
, SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SCRIPTS
|SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::OASIS
));
299 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
300 Calc_XMLOasisSettingsExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
302 return cppu::acquire(new ScXMLExport(context
, u
"com.sun.star.comp.Calc.XMLOasisSettingsExporter"_ustr
, SvXMLExportFlags::SETTINGS
|SvXMLExportFlags::OASIS
));
307 class ScXMLShapeExport
: public XMLShapeExport
310 explicit ScXMLShapeExport(SvXMLExport
& rExp
)
311 : XMLShapeExport(rExp
,
312 // chain text attributes
313 XMLTextParagraphExport::CreateParaExtPropMapper(rExp
))
317 /** is called before a shape element for the given XShape is exported */
318 virtual void onExport( const uno::Reference
< drawing::XShape
>& xShape
) override
;
323 void ScXMLShapeExport::onExport( const uno::Reference
< drawing::XShape
>& xShape
)
325 uno::Reference
< beans::XPropertySet
> xShapeProp( xShape
, uno::UNO_QUERY
);
326 if( xShapeProp
.is() )
328 sal_Int16 nLayerID
= 0;
329 if( (xShapeProp
->getPropertyValue( SC_LAYERID
) >>= nLayerID
) && (SdrLayerID(nLayerID
) == SC_LAYER_BACK
) )
330 GetExport().AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_BACKGROUND
, XML_TRUE
);
334 sal_Int16
ScXMLExport::GetMeasureUnit()
336 css::uno::Reference
<css::sheet::XGlobalSheetSettings
> xProperties
=
337 css::sheet::GlobalSheetSettings::create( comphelper::getProcessComponentContext() );
338 const FieldUnit eFieldUnit
= static_cast<FieldUnit
>(xProperties
->getMetric());
339 return SvXMLUnitConverter::GetMeasureUnit(eFieldUnit
);
342 ScXMLExport::ScXMLExport(
343 const css::uno::Reference
< css::uno::XComponentContext
>& rContext
,
344 OUString
const & implementationName
, SvXMLExportFlags nExportFlag
)
346 rContext
, implementationName
, GetMeasureUnit(), XML_SPREADSHEET
, nExportFlag
),
348 pCurrentCell(nullptr),
352 bHasRowHeader(false),
353 bRowHeaderOpen(false)
355 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
357 pGroupColumns
.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP
) );
358 pGroupRows
.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP
) );
359 pColumnStyles
.reset( new ScColumnStyles() );
360 pRowStyles
.reset( new ScRowStyles() );
361 pRowFormatRanges
.reset( new ScRowFormatRanges() );
362 pMergedRangesContainer
.reset( new ScMyMergedRangesContainer() );
363 pValidationsContainer
.reset( new ScMyValidationsContainer() );
364 mpCellsItr
.reset(new ScMyNotEmptyCellsIterator(*this));
365 pDefaults
.reset( new ScMyDefaultStyles
);
367 pCellStyles
.reset( new ScFormatRangeStyles() );
369 // document is not set here - create ScChangeTrackingExportHelper later
371 xScPropHdlFactory
= new XMLScPropHdlFactory
;
372 xCellStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScCellStylesProperties
, xScPropHdlFactory
, true);
373 xColumnStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScColumnStylesProperties
, xScPropHdlFactory
, true);
374 xRowStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScRowStylesProperties
, xScPropHdlFactory
, true);
375 xTableStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScTableStylesProperties
, xScPropHdlFactory
, true);
376 xCellStylesExportPropertySetMapper
= new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper
);
377 xCellStylesExportPropertySetMapper
->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
378 xColumnStylesExportPropertySetMapper
= new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper
);
379 xRowStylesExportPropertySetMapper
= new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper
);
380 xTableStylesExportPropertySetMapper
= new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper
);
382 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_CELL
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
,
383 xCellStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
);
384 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_COLUMN
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME
,
385 xColumnStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX
);
386 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_ROW
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME
,
387 xRowStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX
);
388 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_TABLE
, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME
,
389 xTableStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX
);
391 GetShapeExport(); // make sure the graphics styles family is added
393 if( !(getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
)) )
396 // This name is reserved for the external ref cache tables. This
397 // should not conflict with user-defined styles since this name is
398 // used for a table style which is not available in the UI.
399 sExternalRefTabStyleName
= "ta_extref";
400 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE
, sExternalRefTabStyleName
);
402 sAttrName
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_NAME
));
403 sAttrStyleName
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_STYLE_NAME
));
404 sAttrColumnsRepeated
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED
));
405 sAttrFormula
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_FORMULA
));
406 sAttrStringValue
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_STRING_VALUE
));
407 sAttrValueType
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_VALUE_TYPE
));
408 sElemCell
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_CELL
));
409 sElemCoveredCell
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_COVERED_TABLE_CELL
));
410 sElemCol
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_COLUMN
));
411 sElemRow
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_ROW
));
412 sElemTab
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE
));
413 sElemP
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
416 ScXMLExport::~ScXMLExport()
418 pGroupColumns
.reset();
420 pColumnStyles
.reset();
423 pRowFormatRanges
.reset();
424 pMergedRangesContainer
.reset();
425 pValidationsContainer
.reset();
426 pChangeTrackingExportHelper
.reset();
428 pNumberFormatAttributesExportHelper
.reset();
431 void ScXMLExport::SetSourceStream( const uno::Reference
<io::XInputStream
>& xNewStream
)
433 xSourceStream
= xNewStream
;
435 if ( !xSourceStream
.is() )
438 // make sure it's a plain UTF-8 stream as written by OOo itself
440 const char pXmlHeader
[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
441 sal_Int32 nLen
= strlen(pXmlHeader
);
443 uno::Sequence
<sal_Int8
> aFileStart(nLen
);
444 sal_Int32 nRead
= xSourceStream
->readBytes( aFileStart
, nLen
);
446 if ( nRead
!= nLen
|| memcmp( aFileStart
.getConstArray(), pXmlHeader
, nLen
) != 0 )
448 // invalid - ignore stream, save normally
449 xSourceStream
.clear();
453 // keep track of the bytes already read
454 nSourceStreamPos
= nRead
;
456 const ScSheetSaveData
* pSheetData
= comphelper::getFromUnoTunnel
<ScModelObj
>(GetModel())->GetSheetSaveData();
459 // add the loaded namespaces to the name space map
461 if ( !pSheetData
->AddLoadedNamespaces( GetNamespaceMap_() ) )
463 // conflicts in the namespaces - ignore the stream, save normally
464 xSourceStream
.clear();
470 sal_Int32
ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt
) const
472 NumberFormatIndexMap::const_iterator itr
= aNumFmtIndexMap
.find(nNumFmt
);
473 if (itr
== aNumFmtIndexMap
.end())
479 ScDocument
* ScXMLExport::GetDocument()
481 return ScXMLConverter::GetScDocument(GetModel());
484 void ScXMLExport::CollectSharedData(SCTAB
& nTableCount
, sal_Int32
& nShapesCount
)
486 if (!GetModel().is())
489 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc(GetModel(), uno::UNO_QUERY
);
490 if (!xSpreadDoc
.is())
493 uno::Reference
<container::XIndexAccess
> xIndex(xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
497 nTableCount
= xIndex
->getCount();
499 pSharedData
.reset(new ScMySharedData(nTableCount
));
501 ScDocument
* pDoc
= GetDocument();
503 for (SCTAB nTable
= 0; nTable
< nTableCount
; ++nTable
)
505 nCurrentTable
= sal::static_int_cast
<sal_uInt16
>(nTable
);
506 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
507 if (!xDrawPageSupplier
.is())
510 uno::Reference
<drawing::XDrawPage
> xDrawPage(xDrawPageSupplier
->getDrawPage());
511 ScMyDrawPage aDrawPage
;
512 aDrawPage
.bHasForms
= false;
513 aDrawPage
.xDrawPage
.set(xDrawPage
);
514 pSharedData
->AddDrawPage(aDrawPage
, nTable
);
518 sal_Int32 nShapes
= xDrawPage
->getCount();
519 for (sal_Int32 nShape
= 0; nShape
< nShapes
; ++nShape
)
521 uno::Reference
<drawing::XShape
> xShape(xDrawPage
->getByIndex(nShape
), uno::UNO_QUERY
);
525 uno::Reference
<beans::XPropertySet
> xShapeProp(xShape
, uno::UNO_QUERY
);
526 if (!xShapeProp
.is())
529 sal_Int16 nLayerID
= 0;
530 bool bExtracted
= xShapeProp
->getPropertyValue(SC_LAYERID
) >>= nLayerID
;
534 if ((SdrLayerID(nLayerID
) == SC_LAYER_INTERN
) || (SdrLayerID(nLayerID
) == SC_LAYER_HIDDEN
))
537 CollectInternalShape(*pDoc
, xShape
);
543 SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape(xShape
);
547 if (ScDrawObjData
*pAnchor
= ScDrawLayer::GetNonRotatedObjData(pSdrObj
))
550 aMyShape
.aAddress
= pAnchor
->maStart
;
551 SAL_WARN_IF(aMyShape
.aAddress
.Tab() != nTable
, "sc", "not anchored to current sheet!");
552 aMyShape
.aAddress
.SetTab(nTable
);
553 aMyShape
.aEndAddress
= pAnchor
->maEnd
;
554 aMyShape
.aEndAddress
.SetTab( nTable
);
555 aMyShape
.nEndX
= pAnchor
->maEndOffset
.X();
556 aMyShape
.nEndY
= pAnchor
->maEndOffset
.Y();
557 aMyShape
.xShape
= std::move(xShape
);
558 pSharedData
->AddNewShape(aMyShape
);
559 pSharedData
->SetLastColumn(nTable
, pAnchor
->maStart
.Col());
560 pSharedData
->SetLastRow(nTable
, pAnchor
->maStart
.Row());
563 pSharedData
->AddTableShape(nTable
, xShape
);
568 void ScXMLExport::CollectShapesAutoStyles(SCTAB nTableCount
)
570 // #i84077# To avoid compiler warnings about uninitialized aShapeItr,
571 // it's initialized using this dummy list. The iterator contains shapes
572 // from all sheets, so it can't be declared inside the nTable loop where
574 ScMyShapeList aDummyInitList
;
576 pSharedData
->SortShapesContainer();
577 pSharedData
->SortNoteShapes();
578 const ScMyShapeList
* pShapeList(nullptr);
579 ScMyShapeList::const_iterator aShapeItr
= aDummyInitList
.end();
580 if (pSharedData
->GetShapesContainer())
582 pShapeList
= &pSharedData
->GetShapesContainer()->GetShapes();
583 aShapeItr
= pShapeList
->begin();
585 if (pSharedData
->HasDrawPage())
587 for (SCTAB nTable
= 0; nTable
< nTableCount
; ++nTable
)
589 uno::Reference
<drawing::XDrawPage
> xDrawPage(pSharedData
->GetDrawPage(nTable
));
593 GetShapeExport()->seekShapes(xDrawPage
);
594 uno::Reference
< form::XFormsSupplier2
> xFormsSupplier( xDrawPage
, uno::UNO_QUERY
);
595 if( xFormsSupplier
.is() && xFormsSupplier
->hasForms() )
597 GetFormExport()->examineForms(xDrawPage
);
598 pSharedData
->SetDrawPageHasForms(nTable
, true);
600 ScMyTableShapes
* pTableShapes(pSharedData
->GetTableShapes());
603 for (const auto& rxShape
: (*pTableShapes
)[nTable
])
605 GetShapeExport()->collectShapeAutoStyles(rxShape
);
606 IncrementProgressBar(false);
611 ScMyShapeList::const_iterator
aEndItr(pShapeList
->end());
612 while ( aShapeItr
!= aEndItr
&& ( aShapeItr
->aAddress
.Tab() == nTable
) )
614 GetShapeExport()->collectShapeAutoStyles(aShapeItr
->xShape
);
615 IncrementProgressBar(false);
619 if (pSharedData
->GetNoteShapes())
621 const ScMyNoteShapeList
& rNoteShapes
= pSharedData
->GetNoteShapes()->GetNotes();
622 for (const auto& rNoteShape
: rNoteShapes
)
624 if ( rNoteShape
.aPos
.Tab() == nTable
)
625 GetShapeExport()->collectShapeAutoStyles(rNoteShape
.xShape
);
631 pSharedData
->SortNoteShapes(); // sort twice, because some more shapes are added
634 void ScXMLExport::ExportMeta_()
636 ScDocument
* pDoc
= GetDocument();
637 sal_Int32
nCellCount(pDoc
? pDoc
->GetCellCount() : 0);
638 SCTAB
nTableCount(0);
639 sal_Int32
nShapesCount(0);
640 GetAutoStylePool()->ClearEntries();
641 CollectSharedData(nTableCount
, nShapesCount
);
643 uno::Sequence
<beans::NamedValue
> stats
645 { u
"TableCount"_ustr
, uno::Any(static_cast<sal_Int32
>(nTableCount
)) },
646 { u
"CellCount"_ustr
, uno::Any(nCellCount
) },
647 { u
"ObjectCount"_ustr
, uno::Any(nShapesCount
) }
650 // update document statistics at the model
651 uno::Reference
<document::XDocumentPropertiesSupplier
> xPropSup(GetModel(),
652 uno::UNO_QUERY_THROW
);
653 uno::Reference
<document::XDocumentProperties
> xDocProps(
654 xPropSup
->getDocumentProperties());
655 if (xDocProps
.is()) {
656 xDocProps
->setDocumentStatistics(stats
);
659 // export document properties
660 SvXMLExport::ExportMeta_();
663 void ScXMLExport::ExportFontDecls_()
665 GetFontAutoStylePool(); // make sure the pool is created
666 SvXMLExport::ExportFontDecls_();
669 table::CellRangeAddress
ScXMLExport::GetEndAddress(const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
671 table::CellRangeAddress aCellAddress
;
672 uno::Reference
<sheet::XSheetCellCursor
> xCursor(xTable
->createCursor());
673 uno::Reference
<sheet::XUsedAreaCursor
> xUsedArea (xCursor
, uno::UNO_QUERY
);
674 uno::Reference
<sheet::XCellRangeAddressable
> xCellAddress (xCursor
, uno::UNO_QUERY
);
675 if (xUsedArea
.is() && xCellAddress
.is())
677 xUsedArea
->gotoEndOfUsedArea(true);
678 aCellAddress
= xCellAddress
->getRangeAddress();
684 ScMyAreaLinksContainer
ScXMLExport::GetAreaLinks(ScDocument
& rDoc
)
686 sfx2::LinkManager
* pManager
= rDoc
.GetLinkManager();
690 ScMyAreaLinkList aAreaLinks
;
691 for (const auto& rLink
: pManager
->GetLinks())
693 if (ScAreaLink
* pLink
= dynamic_cast<ScAreaLink
*>(rLink
.get()))
695 ScMyAreaLink aAreaLink
;
696 aAreaLink
.aDestRange
= pLink
->GetDestArea();
697 aAreaLink
.sSourceStr
= pLink
->GetSource();
698 aAreaLink
.sFilter
= pLink
->GetFilter();
699 aAreaLink
.sFilterOptions
= pLink
->GetOptions();
700 aAreaLink
.sURL
= pLink
->GetFile();
701 aAreaLink
.nRefreshDelaySeconds
= pLink
->GetRefreshDelaySeconds();
702 aAreaLinks
.push_back(aAreaLink
);
705 return ScMyAreaLinksContainer(std::move(aAreaLinks
));
708 // core implementation
709 ScMyDetectiveOpContainer
ScXMLExport::GetDetectiveOpList(ScDocument
& rDoc
)
711 ScDetOpList
* pOpList(rDoc
.GetDetOpList());
715 ScMyDetectiveOpList aDetOp
;
716 size_t nCount
= pOpList
->Count();
717 for (size_t nIndex
= 0; nIndex
< nCount
; ++nIndex
)
719 const ScDetOpData
& rDetData
= pOpList
->GetObject( nIndex
);
720 const ScAddress
& rDetPos
= rDetData
.GetPos();
721 SCTAB nTab
= rDetPos
.Tab();
722 if ( nTab
< rDoc
.GetTableCount() )
724 aDetOp
.push_back({ rDetPos
, rDetData
.GetOperation(), static_cast<sal_Int32
>(nIndex
) });
726 // cells with detective operations are written even if empty
727 pSharedData
->SetLastColumn( nTab
, rDetPos
.Col() );
728 pSharedData
->SetLastRow( nTab
, rDetPos
.Row() );
731 return ScMyDetectiveOpContainer(std::move(aDetOp
));
734 void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns
, const sal_Int32 nStyleIndex
,
735 const sal_Int32 nIndex
, const bool bIsAutoStyle
, const bool bIsVisible
)
739 if (nStyleIndex
!= -1)
740 AddAttribute(sAttrStyleName
, pColumnStyles
->GetStyleNameByIndex(nStyleIndex
));
742 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_COLLAPSE
);
743 if (nRepeatColumns
> 1)
745 OUString
sOUEndCol(OUString::number(nRepeatColumns
));
746 AddAttribute(sAttrColumnsRepeated
, sOUEndCol
);
749 AddAttribute(XML_NAMESPACE_TABLE
, XML_DEFAULT_CELL_STYLE_NAME
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
750 SvXMLElementExport
aElemC(*this, sElemCol
, true, true);
753 void ScXMLExport::WriteColumn(const sal_Int32 nColumn
, const sal_Int32 nRepeatColumns
,
754 const sal_Int32 nStyleIndex
, const bool bIsVisible
)
756 sal_Int32
nRepeat(1);
757 sal_Int32
nPrevIndex(pDefaults
->GetColDefaults()[nColumn
].nIndex
);
758 bool bPrevAutoStyle(pDefaults
->GetColDefaults()[nColumn
].bIsAutoStyle
);
759 for (sal_Int32 i
= nColumn
+ 1; i
< nColumn
+ nRepeatColumns
; ++i
)
761 if ((pDefaults
->GetColDefaults()[i
].nIndex
!= nPrevIndex
) ||
762 (pDefaults
->GetColDefaults()[i
].bIsAutoStyle
!= bPrevAutoStyle
))
764 WriteSingleColumn(nRepeat
, nStyleIndex
, nPrevIndex
, bPrevAutoStyle
, bIsVisible
);
765 nPrevIndex
= pDefaults
->GetColDefaults()[i
].nIndex
;
766 bPrevAutoStyle
= pDefaults
->GetColDefaults()[i
].bIsAutoStyle
;
772 WriteSingleColumn(nRepeat
, nStyleIndex
, nPrevIndex
, bPrevAutoStyle
, bIsVisible
);
775 void ScXMLExport::OpenHeaderColumn()
777 StartElement( XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, true );
780 void ScXMLExport::CloseHeaderColumn()
782 EndElement(XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, true);
785 void ScXMLExport::ExportColumns(const sal_Int32 nTable
, const ScRange
& aColumnHeaderRange
, const bool bHasColumnHeader
)
787 sal_Int32
nColsRepeated (1);
789 sal_Int32
nPrevColumn(0);
790 bool bPrevIsVisible (true);
791 bool bWasHeader (false);
792 bool bIsClosed (true);
793 sal_Int32
nPrevIndex (-1);
795 for (nColumn
= 0; nColumn
<= pSharedData
->GetLastColumn(nTable
); ++nColumn
)
798 bool bIsVisible(true);
799 nIndex
= pColumnStyles
->GetStyleNameIndex(nTable
, nColumn
, bIsVisible
);
801 const bool bIsHeader
= bHasColumnHeader
&& (aColumnHeaderRange
.aStart
.Col() <= nColumn
) && (nColumn
<= aColumnHeaderRange
.aEnd
.Col());
802 if (bIsHeader
!= bWasHeader
)
808 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
809 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
810 pGroupColumns
->CloseGroups(nColumn
- 1);
812 bPrevIsVisible
= bIsVisible
;
814 nPrevColumn
= nColumn
;
816 if(pGroupColumns
->IsGroupStart(nColumn
))
817 pGroupColumns
->OpenGroups(nColumn
);
824 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
826 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
827 pGroupColumns
->CloseGroups(nColumn
- 1);
828 if(pGroupColumns
->IsGroupStart(nColumn
))
829 pGroupColumns
->OpenGroups(nColumn
);
830 bPrevIsVisible
= bIsVisible
;
832 nPrevColumn
= nColumn
;
838 else if (nColumn
== 0)
840 if (pGroupColumns
->IsGroupStart(nColumn
))
841 pGroupColumns
->OpenGroups(nColumn
);
842 bPrevIsVisible
= bIsVisible
;
845 else if ((bIsVisible
== bPrevIsVisible
) && (nIndex
== nPrevIndex
) &&
846 !pGroupColumns
->IsGroupStart(nColumn
) && !pGroupColumns
->IsGroupEnd(nColumn
- 1))
850 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
851 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
855 pGroupColumns
->CloseGroups(nColumn
- 1);
859 if (pGroupColumns
->IsGroupStart(nColumn
))
863 pGroupColumns
->OpenGroups(nColumn
);
867 bPrevIsVisible
= bIsVisible
;
869 nPrevColumn
= nColumn
;
873 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
876 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
877 pGroupColumns
->CloseGroups(nColumn
- 1);
880 void ScXMLExport::ExportExternalRefCacheStyles(ScDocument
& rDoc
)
882 sal_Int32 nEntryIndex
= GetCellStylesPropertySetMapper()->FindEntryIndex(
883 "NumberFormat", XML_NAMESPACE_STYLE
, u
"data-style-name");
886 // No entry index for the number format is found.
889 ScExternalRefManager
* pRefMgr
= rDoc
.GetExternalRefManager();
890 if (!pRefMgr
->hasExternalData())
891 // No external reference data cached.
894 // Export each unique number format used in the external ref cache.
895 vector
<sal_uInt32
> aNumFmts
;
896 pRefMgr
->getAllCachedNumberFormats(aNumFmts
);
897 static constexpr OUString
aDefaultStyle(u
"Default"_ustr
);
898 for (const auto& rNumFmt
: aNumFmts
)
900 sal_Int32 nNumFmt
= static_cast<sal_Int32
>(rNumFmt
);
902 addDataStyle(nNumFmt
);
906 vector
<XMLPropertyState
> aProps
;
907 aVal
<<= aDefaultStyle
;
908 aProps
.emplace_back(nEntryIndex
, aVal
);
912 if (GetAutoStylePool()->Add(aName
, XmlStyleFamily::TABLE_CELL
, aDefaultStyle
, std::move(aProps
)))
914 pCellStyles
->AddStyleName(aName
, nIndex
);
919 nIndex
= pCellStyles
->GetIndexOfStyleName(
920 aName
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
, bIsAuto
);
923 // store the number format to index mapping for later use.
924 aNumFmtIndexMap
.emplace(nNumFmt
, nIndex
);
931 SvXMLExport
& rExport
,
932 std::vector
<XMLPropertyState
>& rPropStates
,
933 const SfxPoolItem
* p
, const rtl::Reference
<XMLPropertySetMapper
>& xMapper
, std::u16string_view rXMLName
)
935 sal_Int32 nEntryCount
= xMapper
->GetEntryCount();
937 // Apparently font info needs special handling.
938 const SvxFontItem
* pItem
= static_cast<const SvxFontItem
*>(p
);
940 sal_Int32 nIndexFontName
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, rXMLName
, 0);
942 if (nIndexFontName
== -1 || nIndexFontName
>= nEntryCount
)
945 OUString
const sFamilyName(pItem
->GetFamilyName());
946 OUString
const sStyleName(pItem
->GetStyleName());
947 auto const nFamily(pItem
->GetFamily());
948 auto const nPitch(pItem
->GetPitch());
949 auto const eEnc(pItem
->GetCharSet());
950 OUString
const sName(rExport
.GetFontAutoStylePool()->Find(
951 sFamilyName
, sStyleName
, nFamily
, nPitch
, eEnc
));
954 assert(false); // fallback to fo:font-family etc. probably not needed
957 rPropStates
.emplace_back(nIndexFontName
, uno::Any(sName
));
960 const SvxFieldData
* toXMLPropertyStates(
961 SvXMLExport
& rExport
,
962 std::vector
<XMLPropertyState
>& rPropStates
, const std::vector
<const SfxPoolItem
*>& rSecAttrs
,
963 const rtl::Reference
<XMLPropertySetMapper
>& xMapper
, const ScXMLEditAttributeMap
& rAttrMap
)
965 const SvxFieldData
* pField
= nullptr;
966 sal_Int32 nEntryCount
= xMapper
->GetEntryCount();
967 rPropStates
.reserve(rSecAttrs
.size());
968 for (const SfxPoolItem
* p
: rSecAttrs
)
970 if (p
->Which() == EE_FEATURE_FIELD
)
972 pField
= static_cast<const SvxFieldItem
*>(p
)->GetField();
976 const ScXMLEditAttributeMap::Entry
* pEntry
= rAttrMap
.getEntryByItemID(p
->Which());
980 sal_Int32 nIndex
= xMapper
->GetEntryIndex(pEntry
->nmXMLNS
, pEntry
->maXMLName
, 0);
982 if (nIndex
== -1 || nIndex
>= nEntryCount
)
988 case EE_CHAR_FONTINFO
:
989 handleFont(rExport
, rPropStates
, p
, xMapper
, u
"font-name");
991 case EE_CHAR_FONTINFO_CJK
:
992 handleFont(rExport
, rPropStates
, p
, xMapper
, u
"font-name-asian");
994 case EE_CHAR_FONTINFO_CTL
:
995 handleFont(rExport
, rPropStates
, p
, xMapper
, u
"font-name-complex");
998 case EE_CHAR_WEIGHT_CJK
:
999 case EE_CHAR_WEIGHT_CTL
:
1001 if (!static_cast<const SvxWeightItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1004 rPropStates
.emplace_back(nIndex
, aAny
);
1007 case EE_CHAR_FONTHEIGHT
:
1008 case EE_CHAR_FONTHEIGHT_CJK
:
1009 case EE_CHAR_FONTHEIGHT_CTL
:
1011 if (!static_cast<const SvxFontHeightItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1014 rPropStates
.emplace_back(nIndex
, aAny
);
1017 case EE_CHAR_ITALIC
:
1018 case EE_CHAR_ITALIC_CJK
:
1019 case EE_CHAR_ITALIC_CTL
:
1021 if (!static_cast<const SvxPostureItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1024 rPropStates
.emplace_back(nIndex
, aAny
);
1027 case EE_CHAR_UNDERLINE
:
1029 // Underline attribute needs to export multiple entries.
1030 sal_Int32 nIndexStyle
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-underline-style", 0);
1031 if (nIndexStyle
== -1 || nIndexStyle
> nEntryCount
)
1034 sal_Int32 nIndexWidth
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-underline-width", 0);
1035 if (nIndexWidth
== -1 || nIndexWidth
> nEntryCount
)
1038 sal_Int32 nIndexType
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-underline-type", 0);
1039 if (nIndexType
== -1 || nIndexType
> nEntryCount
)
1042 sal_Int32 nIndexColor
= xMapper
->FindEntryIndex("CharUnderlineColor", XML_NAMESPACE_STYLE
, u
"text-underline-color");
1043 if (nIndexColor
== -1 || nIndexColor
> nEntryCount
)
1046 sal_Int32 nIndexHasColor
= xMapper
->FindEntryIndex("CharUnderlineHasColor", XML_NAMESPACE_STYLE
, u
"text-underline-color");
1047 if (nIndexHasColor
== -1 || nIndexHasColor
> nEntryCount
)
1050 const SvxUnderlineItem
* pUL
= static_cast<const SvxUnderlineItem
*>(p
);
1051 pUL
->QueryValue(aAny
, MID_TL_STYLE
);
1052 rPropStates
.emplace_back(nIndexStyle
, aAny
);
1053 rPropStates
.emplace_back(nIndexType
, aAny
);
1054 rPropStates
.emplace_back(nIndexWidth
, aAny
);
1056 pUL
->QueryValue(aAny
, MID_TL_COLOR
);
1057 rPropStates
.emplace_back(nIndexColor
, aAny
);
1059 pUL
->QueryValue(aAny
, MID_TL_HASCOLOR
);
1060 rPropStates
.emplace_back(nIndexHasColor
, aAny
);
1063 case EE_CHAR_OVERLINE
:
1065 // Same with overline. Do just as we do with underline attributes.
1066 sal_Int32 nIndexStyle
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-overline-style", 0);
1067 if (nIndexStyle
== -1 || nIndexStyle
> nEntryCount
)
1070 sal_Int32 nIndexWidth
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-overline-width", 0);
1071 if (nIndexWidth
== -1 || nIndexWidth
> nEntryCount
)
1074 sal_Int32 nIndexType
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-overline-type", 0);
1075 if (nIndexType
== -1 || nIndexType
> nEntryCount
)
1078 sal_Int32 nIndexColor
= xMapper
->FindEntryIndex("CharOverlineColor", XML_NAMESPACE_STYLE
, u
"text-overline-color");
1079 if (nIndexColor
== -1 || nIndexColor
> nEntryCount
)
1082 sal_Int32 nIndexHasColor
= xMapper
->FindEntryIndex("CharOverlineHasColor", XML_NAMESPACE_STYLE
, u
"text-overline-color");
1083 if (nIndexHasColor
== -1 || nIndexHasColor
> nEntryCount
)
1086 const SvxOverlineItem
* pOL
= static_cast<const SvxOverlineItem
*>(p
);
1087 pOL
->QueryValue(aAny
, MID_TL_STYLE
);
1088 rPropStates
.emplace_back(nIndexStyle
, aAny
);
1089 rPropStates
.emplace_back(nIndexType
, aAny
);
1090 rPropStates
.emplace_back(nIndexWidth
, aAny
);
1092 pOL
->QueryValue(aAny
, MID_TL_COLOR
);
1093 rPropStates
.emplace_back(nIndexColor
, aAny
);
1095 pOL
->QueryValue(aAny
, MID_TL_HASCOLOR
);
1096 rPropStates
.emplace_back(nIndexHasColor
, aAny
);
1101 if (!static_cast<const SvxColorItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1105 if ( aAny
>>= nColor
)
1107 sal_Int32 nIndexColor
= ( nColor
== COL_AUTO
) ? xMapper
->GetEntryIndex(
1108 XML_NAMESPACE_STYLE
, GetXMLToken( XML_USE_WINDOW_FONT_COLOR
), 0 ) : nIndex
;
1109 rPropStates
.emplace_back( nIndexColor
, aAny
);
1115 if (!static_cast<const SvxWordLineModeItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1118 rPropStates
.emplace_back(nIndex
, aAny
);
1121 case EE_CHAR_STRIKEOUT
:
1123 if (!static_cast<const SvxCrossedOutItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1126 rPropStates
.emplace_back(nIndex
, aAny
);
1129 case EE_CHAR_RELIEF
:
1131 if (!static_cast<const SvxCharReliefItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1134 rPropStates
.emplace_back(nIndex
, aAny
);
1137 case EE_CHAR_OUTLINE
:
1139 if (!static_cast<const SvxContourItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1142 rPropStates
.emplace_back(nIndex
, aAny
);
1145 case EE_CHAR_SHADOW
:
1147 if (!static_cast<const SvxShadowedItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1150 rPropStates
.emplace_back(nIndex
, aAny
);
1153 case EE_CHAR_KERNING
:
1155 if (!static_cast<const SvxKerningItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1158 rPropStates
.emplace_back(nIndex
, aAny
);
1161 case EE_CHAR_PAIRKERNING
:
1163 if (!static_cast<const SvxAutoKernItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1166 rPropStates
.emplace_back(nIndex
, aAny
);
1169 case EE_CHAR_FONTWIDTH
:
1171 if (!static_cast<const SvxCharScaleWidthItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1174 rPropStates
.emplace_back(nIndex
, aAny
);
1177 case EE_CHAR_ESCAPEMENT
:
1179 sal_Int32 nIndexEsc
= xMapper
->FindEntryIndex("CharEscapement", XML_NAMESPACE_STYLE
, u
"text-position");
1180 if (nIndexEsc
== -1 || nIndexEsc
> nEntryCount
)
1183 sal_Int32 nIndexEscHeight
= xMapper
->FindEntryIndex("CharEscapementHeight", XML_NAMESPACE_STYLE
, u
"text-position");
1184 if (nIndexEscHeight
== -1 || nIndexEscHeight
> nEntryCount
)
1187 const SvxEscapementItem
* pEsc
= static_cast<const SvxEscapementItem
*>(p
);
1189 pEsc
->QueryValue(aAny
);
1190 rPropStates
.emplace_back(nIndexEsc
, aAny
);
1192 pEsc
->QueryValue(aAny
, MID_ESC_HEIGHT
);
1193 rPropStates
.emplace_back(nIndexEscHeight
, aAny
);
1197 case EE_CHAR_EMPHASISMARK
:
1199 if (!static_cast<const SvxEmphasisMarkItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1202 rPropStates
.emplace_back(nIndex
, aAny
);
1205 case EE_CHAR_LANGUAGE
:
1206 case EE_CHAR_LANGUAGE_CJK
:
1207 case EE_CHAR_LANGUAGE_CTL
:
1209 if (!static_cast<const SvxLanguageItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1212 // Export multiple entries.
1213 sal_Int32 nIndexLanguage
, nIndexCountry
, nIndexScript
, nIndexTag
;
1216 case EE_CHAR_LANGUAGE
:
1217 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, u
"language", 0);
1218 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, u
"country", 0);
1219 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, u
"script", 0);
1220 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"rfc-language-tag", 0);
1222 case EE_CHAR_LANGUAGE_CJK
:
1223 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"language-asian", 0);
1224 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"country-asian", 0);
1225 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"script-asian", 0);
1226 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"rfc-language-tag-asian", 0);
1228 case EE_CHAR_LANGUAGE_CTL
:
1229 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"language-complex", 0);
1230 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"country-complex", 0);
1231 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"script-complex", 0);
1232 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"rfc-language-tag-complex", 0);
1235 nIndexLanguage
= nIndexCountry
= nIndexScript
= nIndexTag
= -1;
1237 assert( nIndexLanguage
>= 0 && nIndexCountry
>= 0 && nIndexScript
>= 0 && nIndexTag
>= 0);
1238 rPropStates
.emplace_back( nIndexLanguage
, aAny
);
1239 rPropStates
.emplace_back( nIndexCountry
, aAny
);
1240 rPropStates
.emplace_back( nIndexScript
, aAny
);
1241 rPropStates
.emplace_back( nIndexTag
, aAny
);
1254 void ScXMLExport::ExportCellTextAutoStyles(ScDocument
& rDoc
, sal_Int32 nTable
)
1256 if (!ValidTab(nTable
))
1259 rtl::Reference
<XMLPropertySetMapper
> xMapper
= GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
1260 rtl::Reference
<SvXMLAutoStylePoolP
> xStylePool
= GetAutoStylePool();
1261 const ScXMLEditAttributeMap
& rAttrMap
= GetEditAttributeMap();
1263 sc::EditTextIterator
aIter(rDoc
, nTable
);
1264 sal_Int32 nCellCount
= 0;
1265 for (const EditTextObject
* pEdit
= aIter
.first(); pEdit
; pEdit
= aIter
.next(), ++nCellCount
)
1267 std::vector
<editeng::Section
> aAttrs
;
1268 pEdit
->GetAllSections(aAttrs
);
1272 for (const auto& rSec
: aAttrs
)
1274 const std::vector
<const SfxPoolItem
*>& rSecAttrs
= rSec
.maAttributes
;
1275 if (rSecAttrs
.empty())
1276 // No formats applied to this section. Skip it.
1279 std::vector
<XMLPropertyState
> aPropStates
;
1280 toXMLPropertyStates(*this, aPropStates
, rSecAttrs
, xMapper
, rAttrMap
);
1281 if (!aPropStates
.empty())
1282 xStylePool
->Add(XmlStyleFamily::TEXT_TEXT
, OUString(), std::move(aPropStates
));
1286 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCellCount
);
1289 void ScXMLExport::WriteRowContent()
1291 ScMyRowFormatRange aRange
;
1292 sal_Int32
nIndex(-1);
1293 #if OSL_DEBUG_LEVEL > 0
1294 sal_Int32
nPrevCol(0);
1297 sal_Int32
nPrevValidationIndex(-1);
1298 bool bIsAutoStyle(true);
1299 bool bIsFirst(true);
1300 while (pRowFormatRanges
->GetNext(aRange
))
1302 #if OSL_DEBUG_LEVEL > 0
1303 OSL_ENSURE(bIsFirst
|| (!bIsFirst
&& (nPrevCol
+ nCols
== aRange
.nStartColumn
)), "here are some columns missing");
1307 nIndex
= aRange
.nIndex
;
1308 nPrevValidationIndex
= aRange
.nValidationIndex
;
1309 bIsAutoStyle
= aRange
.bIsAutoStyle
;
1310 nCols
= aRange
.nRepeatColumns
;
1312 #if OSL_DEBUG_LEVEL > 0
1313 nPrevCol
= aRange
.nStartColumn
;
1318 if (((aRange
.nIndex
== nIndex
&& aRange
.bIsAutoStyle
== bIsAutoStyle
) ||
1319 (aRange
.nIndex
== nIndex
&& nIndex
== -1)) &&
1320 nPrevValidationIndex
== aRange
.nValidationIndex
)
1321 nCols
+= aRange
.nRepeatColumns
;
1325 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
1326 if (nPrevValidationIndex
> -1)
1327 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(nPrevValidationIndex
));
1330 AddAttribute(sAttrColumnsRepeated
, OUString::number(nCols
));
1332 SvXMLElementExport
aElemC(*this, sElemCell
, true, true);
1333 nIndex
= aRange
.nIndex
;
1334 bIsAutoStyle
= aRange
.bIsAutoStyle
;
1335 nCols
= aRange
.nRepeatColumns
;
1336 nPrevValidationIndex
= aRange
.nValidationIndex
;
1337 #if OSL_DEBUG_LEVEL > 0
1338 nPrevCol
= aRange
.nStartColumn
;
1346 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
1347 if (nPrevValidationIndex
> -1)
1348 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(nPrevValidationIndex
));
1351 AddAttribute(sAttrColumnsRepeated
, OUString::number(nCols
));
1353 SvXMLElementExport
aElemC(*this, sElemCell
, true, true);
1357 void ScXMLExport::WriteRowStartTag(
1358 const sal_Int32 nIndex
, const sal_Int32 nEqualRows
,
1359 bool bHidden
, bool bFiltered
)
1363 AddAttribute(sAttrStyleName
, pRowStyles
->GetStyleNameByIndex(nIndex
));
1367 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_FILTER
);
1369 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_COLLAPSE
);
1373 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, OUString::number(nEqualRows
));
1376 StartElement( sElemRow
, true);
1379 void ScXMLExport::OpenHeaderRows()
1381 StartElement( XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, true);
1382 bRowHeaderOpen
= true;
1385 void ScXMLExport::CloseHeaderRows()
1387 EndElement(XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, true);
1390 void ScXMLExport::OpenNewRow(
1391 const sal_Int32 nIndex
, const sal_Int32 nStartRow
, const sal_Int32 nEqualRows
,
1392 bool bHidden
, bool bFiltered
)
1394 nOpenRow
= nStartRow
;
1395 if (pGroupRows
->IsGroupStart(nStartRow
))
1397 if (bHasRowHeader
&& bRowHeaderOpen
)
1399 pGroupRows
->OpenGroups(nStartRow
);
1400 if (bHasRowHeader
&& bRowHeaderOpen
)
1403 if (bHasRowHeader
&& !bRowHeaderOpen
&& nStartRow
>= aRowHeaderRange
.aStart
.Row() && nStartRow
<= aRowHeaderRange
.aEnd
.Row())
1405 if (nStartRow
== aRowHeaderRange
.aStart
.Row())
1408 if (aRowHeaderRange
.aEnd
.Row() < nStartRow
+ nEqualRows
- 1)
1409 nEquals
= aRowHeaderRange
.aEnd
.Row() - nStartRow
+ 1;
1411 nEquals
= nEqualRows
;
1412 WriteRowStartTag(nIndex
, nEquals
, bHidden
, bFiltered
);
1413 nOpenRow
= nStartRow
+ nEquals
- 1;
1414 if (nEquals
< nEqualRows
)
1416 CloseRow(nStartRow
+ nEquals
- 1);
1417 WriteRowStartTag(nIndex
, nEqualRows
- nEquals
, bHidden
, bFiltered
);
1418 nOpenRow
= nStartRow
+ nEqualRows
- 1;
1422 WriteRowStartTag(nIndex
, nEqualRows
, bHidden
, bFiltered
);
1425 void ScXMLExport::OpenAndCloseRow(
1426 const sal_Int32 nIndex
, const sal_Int32 nStartRow
, const sal_Int32 nEqualRows
,
1427 bool bHidden
, bool bFiltered
)
1429 OpenNewRow(nIndex
, nStartRow
, nEqualRows
, bHidden
, bFiltered
);
1431 CloseRow(nStartRow
+ nEqualRows
- 1);
1432 pRowFormatRanges
->Clear();
1435 void ScXMLExport::OpenRow(const sal_Int32 nTable
, const sal_Int32 nStartRow
, const sal_Int32 nRepeatRow
, ScXMLCachedRowAttrAccess
& rRowAttr
)
1439 sal_Int32
nPrevIndex(0), nIndex
;
1440 bool bPrevHidden
= false;
1441 bool bPrevFiltered
= false;
1442 bool bHidden
= false;
1443 bool bFiltered
= false;
1444 sal_Int32
nEqualRows(1);
1445 sal_Int32
nEndRow(nStartRow
+ nRepeatRow
);
1446 sal_Int32 nEndRowHidden
= nStartRow
- 1;
1447 sal_Int32 nEndRowFiltered
= nStartRow
- 1;
1449 for (nRow
= nStartRow
; nRow
< nEndRow
; ++nRow
)
1451 if (nRow
== nStartRow
)
1453 nPrevIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nRow
);
1454 if (nRow
> nEndRowHidden
)
1456 bPrevHidden
= rRowAttr
.rowHidden(nTable
, nRow
, nEndRowHidden
);
1457 bHidden
= bPrevHidden
;
1459 if (nRow
> nEndRowFiltered
)
1461 bPrevFiltered
= rRowAttr
.rowFiltered(nTable
, nRow
, nEndRowFiltered
);
1462 bFiltered
= bPrevFiltered
;
1468 nIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nRow
);
1469 if (nRow
> nEndRowHidden
)
1470 bHidden
= rRowAttr
.rowHidden(nTable
, nRow
, nEndRowHidden
);
1471 if (nRow
> nEndRowFiltered
)
1472 bFiltered
= rRowAttr
.rowFiltered(nTable
, nRow
, nEndRowFiltered
);
1473 if (nIndex
== nPrevIndex
&& bHidden
== bPrevHidden
&& bFiltered
== bPrevFiltered
&&
1474 !(bHasRowHeader
&& ((nRow
== aRowHeaderRange
.aStart
.Row()) || (nRow
- 1 == aRowHeaderRange
.aEnd
.Row()))) &&
1475 !(pGroupRows
->IsGroupStart(nRow
)) &&
1476 !(pGroupRows
->IsGroupEnd(nRow
- 1)))
1480 assert(nPrevIndex
>= 0 && "coverity#1438402");
1481 ScRowFormatRanges
* pTempRowFormatRanges
= new ScRowFormatRanges(pRowFormatRanges
.get());
1482 OpenAndCloseRow(nPrevIndex
, nRow
- nEqualRows
, nEqualRows
, bPrevHidden
, bPrevFiltered
);
1483 pRowFormatRanges
.reset(pTempRowFormatRanges
);
1485 nPrevIndex
= nIndex
;
1486 bPrevHidden
= bHidden
;
1487 bPrevFiltered
= bFiltered
;
1491 assert(nPrevIndex
>= 0 && "coverity#1438402");
1492 OpenNewRow(nPrevIndex
, nRow
- nEqualRows
, nEqualRows
, bPrevHidden
, bPrevFiltered
);
1496 sal_Int32 nIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nStartRow
);
1497 bool bHidden
= false;
1498 bool bFiltered
= false;
1499 sal_Int32 nEndRowHidden
;
1500 sal_Int32 nEndRowFiltered
;
1501 bHidden
= rRowAttr
.rowHidden(nTable
, nStartRow
, nEndRowHidden
);
1502 bFiltered
= rRowAttr
.rowFiltered(nTable
, nStartRow
, nEndRowFiltered
);
1503 assert(nIndex
>= 0 && "coverity#1438402");
1504 OpenNewRow(nIndex
, nStartRow
, 1, bHidden
, bFiltered
);
1506 nOpenRow
= nStartRow
+ nRepeatRow
- 1;
1509 void ScXMLExport::CloseRow(const sal_Int32 nRow
)
1513 EndElement(sElemRow
, true);
1514 if (bHasRowHeader
&& nRow
== aRowHeaderRange
.aEnd
.Row())
1517 bRowHeaderOpen
= false;
1519 if (pGroupRows
->IsGroupEnd(nRow
))
1521 if (bHasRowHeader
&& bRowHeaderOpen
)
1523 pGroupRows
->CloseGroups(nRow
);
1524 if (bHasRowHeader
&& bRowHeaderOpen
)
1531 void ScXMLExport::ExportFormatRanges(ScDocument
& rDoc
, const sal_Int32 nStartCol
, const sal_Int32 nStartRow
,
1532 const sal_Int32 nEndCol
, const sal_Int32 nEndRow
, const sal_Int32 nSheet
)
1534 pRowFormatRanges
->Clear();
1535 ScXMLCachedRowAttrAccess
aRowAttr(&rDoc
);
1536 if (nStartRow
== nEndRow
)
1538 pCellStyles
->GetFormatRanges(nStartCol
, nEndCol
, nStartRow
, nSheet
, pRowFormatRanges
.get());
1539 if (nOpenRow
== - 1)
1540 OpenRow(nSheet
, nStartRow
, 1, aRowAttr
);
1542 pRowFormatRanges
->Clear();
1548 pCellStyles
->GetFormatRanges(nStartCol
, pSharedData
->GetLastColumn(nSheet
), nStartRow
, nSheet
, pRowFormatRanges
.get());
1550 CloseRow(nStartRow
);
1552 sal_Int32
nTotalRows(nEndRow
- nStartRow
+ 1 - 1);
1553 while (nRows
< nTotalRows
)
1555 pRowFormatRanges
->Clear();
1556 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1557 sal_Int32 nMaxRows
= pRowFormatRanges
->GetMaxRows();
1558 assert(nMaxRows
&& "ScXMLExport::ExportFormatRanges cannot make progress with zero rows, something went wrong");
1561 uno::Sequence
<OUString
> aEmptySeq
;
1562 SetError(XMLERROR_CANCEL
|XMLERROR_FLAG_SEVERE
, aEmptySeq
);
1565 if (nMaxRows
>= nTotalRows
- nRows
)
1567 OpenRow(nSheet
, nStartRow
+ nRows
, nTotalRows
- nRows
, aRowAttr
);
1568 nRows
+= nTotalRows
- nRows
;
1572 OpenRow(nSheet
, nStartRow
+ nRows
, nMaxRows
, aRowAttr
);
1575 if (!pRowFormatRanges
->GetSize())
1576 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1578 CloseRow(nStartRow
+ nRows
- 1);
1580 if (nTotalRows
== 1)
1581 CloseRow(nStartRow
);
1582 OpenRow(nSheet
, nEndRow
, 1, aRowAttr
);
1583 pRowFormatRanges
->Clear();
1584 pCellStyles
->GetFormatRanges(0, nEndCol
, nEndRow
, nSheet
, pRowFormatRanges
.get());
1590 sal_Int32
nTotalRows(nEndRow
- nStartRow
+ 1 - 1);
1591 while (nRows
< nTotalRows
)
1593 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1594 sal_Int32 nMaxRows
= pRowFormatRanges
->GetMaxRows();
1595 OSL_ENSURE(nMaxRows
, "something went wrong");
1596 if (nMaxRows
>= nTotalRows
- nRows
)
1598 OpenRow(nSheet
, nStartRow
+ nRows
, nTotalRows
- nRows
, aRowAttr
);
1599 nRows
+= nTotalRows
- nRows
;
1603 OpenRow(nSheet
, nStartRow
+ nRows
, nMaxRows
, aRowAttr
);
1606 if (!pRowFormatRanges
->GetSize())
1607 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1609 CloseRow(nStartRow
+ nRows
- 1);
1611 OpenRow(nSheet
, nEndRow
, 1, aRowAttr
);
1612 pRowFormatRanges
->Clear();
1613 pCellStyles
->GetFormatRanges(0, nEndCol
, nEndRow
, nSheet
, pRowFormatRanges
.get());
1619 void ScXMLExport::GetColumnRowHeader(ScDocument
& rDoc
, bool& rHasColumnHeader
, ScRange
& rColumnHeaderRange
,
1620 bool& rHasRowHeader
, ScRange
& rRowHeaderRange
,
1621 OUString
& rPrintRanges
) const
1623 uno::Reference
<sheet::XPrintAreas
> xPrintAreas (xCurrentTable
, uno::UNO_QUERY
);
1624 if (!xPrintAreas
.is())
1627 rHasRowHeader
= xPrintAreas
->getPrintTitleRows();
1628 rHasColumnHeader
= xPrintAreas
->getPrintTitleColumns();
1629 table::CellRangeAddress rTempRowHeaderRange
= xPrintAreas
->getTitleRows();
1630 rRowHeaderRange
= ScRange(rTempRowHeaderRange
.StartColumn
,
1631 rTempRowHeaderRange
.StartRow
,
1632 rTempRowHeaderRange
.Sheet
,
1633 rTempRowHeaderRange
.EndColumn
,
1634 rTempRowHeaderRange
.EndRow
,
1635 rTempRowHeaderRange
.Sheet
);
1636 table::CellRangeAddress rTempColumnHeaderRange
= xPrintAreas
->getTitleColumns();
1637 rColumnHeaderRange
= ScRange(rTempColumnHeaderRange
.StartColumn
,
1638 rTempColumnHeaderRange
.StartRow
,
1639 rTempColumnHeaderRange
.Sheet
,
1640 rTempColumnHeaderRange
.EndColumn
,
1641 rTempColumnHeaderRange
.EndRow
,
1642 rTempColumnHeaderRange
.Sheet
);
1643 uno::Sequence
< table::CellRangeAddress
> aRangeList( xPrintAreas
->getPrintAreas() );
1644 ScRangeStringConverter::GetStringFromRangeList( rPrintRanges
, aRangeList
, &rDoc
, FormulaGrammar::CONV_OOO
);
1647 void ScXMLExport::FillFieldGroup(ScOutlineArray
* pFields
, ScMyOpenCloseColumnRowGroup
* pGroups
)
1649 size_t nDepth
= pFields
->GetDepth();
1650 for (size_t i
= 0; i
< nDepth
; ++i
)
1652 size_t nFields
= pFields
->GetCount(i
);
1653 for (size_t j
= 0; j
< nFields
; ++j
)
1655 ScMyColumnRowGroup aGroup
;
1656 const ScOutlineEntry
* pEntry
= pFields
->GetEntry(i
, j
);
1657 aGroup
.nField
= pEntry
->GetStart();
1658 aGroup
.nLevel
= static_cast<sal_Int16
>(i
);
1659 aGroup
.bDisplay
= !(pEntry
->IsHidden());
1660 pGroups
->AddGroup(aGroup
, pEntry
->GetEnd());
1667 void ScXMLExport::FillColumnRowGroups(ScDocument
& rDoc
)
1669 ScOutlineTable
* pOutlineTable
= rDoc
.GetOutlineTable( static_cast<SCTAB
>(nCurrentTable
) );
1672 ScOutlineArray
& rCols(pOutlineTable
->GetColArray());
1673 ScOutlineArray
& rRows(pOutlineTable
->GetRowArray());
1674 FillFieldGroup(&rCols
, pGroupColumns
.get());
1675 FillFieldGroup(&rRows
, pGroupRows
.get());
1676 pSharedData
->SetLastColumn(nCurrentTable
, pGroupColumns
->GetLast());
1677 pSharedData
->SetLastRow(nCurrentTable
, pGroupRows
->GetLast());
1681 void ScXMLExport::SetBodyAttributes()
1683 ScDocument
* pDoc
= GetDocument();
1684 if (!(pDoc
&& pDoc
->IsDocProtected()))
1687 AddAttribute(XML_NAMESPACE_TABLE
, XML_STRUCTURE_PROTECTED
, XML_TRUE
);
1688 OUStringBuffer aBuffer
;
1689 uno::Sequence
<sal_Int8
> aPassHash
;
1690 ScPasswordHash eHashUsed
= PASSHASH_UNSPECIFIED
;
1691 const ScDocProtection
* p
= pDoc
->GetDocProtection();
1694 if (p
->hasPasswordHash(PASSHASH_SHA1
))
1696 aPassHash
= p
->getPasswordHash(PASSHASH_SHA1
);
1697 eHashUsed
= PASSHASH_SHA1
;
1699 else if (p
->hasPasswordHash(PASSHASH_SHA256
))
1701 aPassHash
= p
->getPasswordHash(PASSHASH_SHA256
);
1702 eHashUsed
= PASSHASH_SHA256
;
1704 else if (p
->hasPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
))
1706 aPassHash
= p
->getPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
);
1707 eHashUsed
= PASSHASH_XL
;
1710 ::comphelper::Base64::encode(aBuffer
, aPassHash
);
1711 if (aBuffer
.isEmpty())
1714 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY
, aBuffer
.makeStringAndClear());
1715 if (getSaneDefaultVersion() < SvtSaveOptions::ODFSVER_012
)
1718 if (eHashUsed
== PASSHASH_XL
)
1720 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1721 ScPassHashHelper::getHashURI(PASSHASH_XL
));
1722 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
1723 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
,
1724 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
1726 else if (eHashUsed
== PASSHASH_SHA1
)
1728 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1729 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
1731 else if (eHashUsed
== PASSHASH_SHA256
)
1733 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1734 ScPassHashHelper::getHashURI(PASSHASH_SHA256
));
1738 static bool lcl_CopyStreamElement( const uno::Reference
< io::XInputStream
>& xInput
,
1739 const uno::Reference
< io::XOutputStream
>& xOutput
,
1742 const sal_Int32 nBufSize
= 16*1024;
1743 uno::Sequence
<sal_Int8
> aSequence(nBufSize
);
1745 sal_Int64 nRemaining
= nCount
;
1748 while ( nRemaining
> 0 )
1750 sal_Int32 nRead
= xInput
->readBytes( aSequence
, std::min( nRemaining
, static_cast<sal_Int64
>(nBufSize
) ) );
1753 // safety check: Make sure the copied part actually points to the start of an element
1754 if ( nRead
< 1 || aSequence
[0] != static_cast<sal_Int8
>('<') )
1756 return false; // abort and set an error
1760 if (nRead
== nRemaining
)
1762 // safety check: Make sure the copied part also ends at the end of an element
1763 if ( aSequence
[nRead
-1] != static_cast<sal_Int8
>('>') )
1765 return false; // abort and set an error
1769 if ( nRead
== nBufSize
)
1771 xOutput
->writeBytes( aSequence
);
1772 nRemaining
-= nRead
;
1778 uno::Sequence
<sal_Int8
> aTempBuf( aSequence
.getConstArray(), nRead
);
1779 xOutput
->writeBytes( aTempBuf
);
1784 return true; // successful
1787 static void lcl_SkipBytesInBlocks( const uno::Reference
< io::XInputStream
>& xInput
, sal_Int64 nBytesToSkip
)
1789 // skipBytes in zip stream is implemented as reading.
1790 // For now, split into several calls to avoid allocating a large buffer.
1791 // Later, skipBytes should be changed.
1793 const sal_Int64 nMaxSize
= 32*1024;
1795 if ( nBytesToSkip
> 0 )
1797 sal_Int64 nRemaining
= nBytesToSkip
;
1798 while ( nRemaining
> 0 )
1800 sal_Int32 nSkip
= std::min( nRemaining
, nMaxSize
);
1801 xInput
->skipBytes( nSkip
);
1802 nRemaining
-= nSkip
;
1807 void ScXMLExport::CopySourceStream( sal_Int64 nStartOffset
, sal_Int64 nEndOffset
, sal_Int64
& rNewStart
, sal_Int64
& rNewEnd
)
1809 uno::Reference
<xml::sax::XDocumentHandler
> xHandler
= GetDocHandler();
1810 uno::Reference
<io::XActiveDataSource
> xDestSource( xHandler
, uno::UNO_QUERY
);
1811 if ( !xDestSource
.is() )
1814 uno::Reference
<io::XOutputStream
> xDestStream
= xDestSource
->getOutputStream();
1815 uno::Reference
<io::XSeekable
> xDestSeek( xDestStream
, uno::UNO_QUERY
);
1816 if ( !xDestSeek
.is() )
1819 // temporary: set same stream again to clear buffer
1820 xDestSource
->setOutputStream( xDestStream
);
1822 if ( getExportFlags() & SvXMLExportFlags::PRETTY
)
1824 static constexpr OString
aOutStr("\n "_ostr
);
1825 uno::Sequence
<sal_Int8
> aOutSeq( reinterpret_cast<sal_Int8
const *>(aOutStr
.getStr()), aOutStr
.getLength() );
1826 xDestStream
->writeBytes( aOutSeq
);
1829 rNewStart
= xDestSeek
->getPosition();
1831 if ( nStartOffset
> nSourceStreamPos
)
1832 lcl_SkipBytesInBlocks( xSourceStream
, nStartOffset
- nSourceStreamPos
);
1834 if ( !lcl_CopyStreamElement( xSourceStream
, xDestStream
, nEndOffset
- nStartOffset
) )
1836 // If copying went wrong, set an error.
1837 // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
1839 uno::Sequence
<OUString
> aEmptySeq
;
1840 SetError(XMLERROR_CANCEL
|XMLERROR_FLAG_SEVERE
, aEmptySeq
);
1842 nSourceStreamPos
= nEndOffset
;
1844 rNewEnd
= xDestSeek
->getPosition();
1847 const ScXMLEditAttributeMap
& ScXMLExport::GetEditAttributeMap() const
1850 mpEditAttrMap
.reset(new ScXMLEditAttributeMap
);
1851 return *mpEditAttrMap
;
1854 void ScXMLExport::RegisterDefinedStyleNames( const uno::Reference
< css::sheet::XSpreadsheetDocument
> & xSpreadDoc
)
1856 ScFormatSaveData
* pFormatData
= comphelper::getFromUnoTunnel
<ScModelObj
>(xSpreadDoc
)->GetFormatSaveData();
1857 auto xAutoStylePool
= GetAutoStylePool();
1858 for (const auto& rFormatInfo
: pFormatData
->maIDToName
)
1860 xAutoStylePool
->RegisterDefinedName(XmlStyleFamily::TABLE_CELL
, rFormatInfo
.second
);
1864 void ScXMLExport::ExportContent_()
1869 SCTAB
nTableCount(0);
1870 sal_Int32
nShapesCount(0);
1871 CollectSharedData(nTableCount
, nShapesCount
);
1872 OSL_FAIL("no shared data set");
1876 ScXMLExportDatabaseRanges
aExportDatabaseRanges(*this);
1877 if (!GetModel().is())
1880 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
1881 if ( !xSpreadDoc
.is() )
1884 ScModelObj
* pModel
= comphelper::getFromUnoTunnel
<ScModelObj
>(xSpreadDoc
);
1886 ScDocument
* pDoc
= pModel
->GetDocument();
1889 SAL_WARN("sc", "no ScDocument!");
1893 ScSheetSaveData
* pSheetData
= pModel
->GetSheetSaveData();
1895 pSheetData
->ResetSaveEntries();
1897 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
1900 //_GetNamespaceMap().ClearQNamesCache();
1901 pChangeTrackingExportHelper
->CollectAndWriteChanges();
1902 WriteCalculationSettings(*pDoc
, xSpreadDoc
);
1903 sal_Int32
nTableCount(xIndex
->getCount());
1904 ScMyAreaLinksContainer aAreaLinks
= GetAreaLinks(*pDoc
);
1905 ScMyEmptyDatabaseRangesContainer
aEmptyRanges(aExportDatabaseRanges
.GetEmptyDatabaseRanges());
1906 ScMyDetectiveOpContainer aDetectiveOpContainer
= GetDetectiveOpList(*pDoc
);
1908 pMergedRangesContainer
->Sort();
1909 pSharedData
->GetDetectiveObjContainer()->Sort();
1911 mpCellsItr
->Clear();
1912 mpCellsItr
->SetShapes( pSharedData
->GetShapesContainer() );
1913 mpCellsItr
->SetNoteShapes( pSharedData
->GetNoteShapes() );
1914 mpCellsItr
->SetMergedRanges( pMergedRangesContainer
.get() );
1915 mpCellsItr
->SetAreaLinks( &aAreaLinks
);
1916 mpCellsItr
->SetEmptyDatabaseRanges( &aEmptyRanges
);
1917 mpCellsItr
->SetDetectiveObj( pSharedData
->GetDetectiveObjContainer() );
1918 mpCellsItr
->SetDetectiveOp( &aDetectiveOpContainer
);
1920 if (nTableCount
> 0)
1921 pValidationsContainer
->WriteValidations(*pDoc
, *this);
1922 WriteTheLabelRanges(*pDoc
, xSpreadDoc
);
1923 for (sal_Int32 nTable
= 0; nTable
< nTableCount
; ++nTable
)
1925 sal_Int64 nStartOffset
= -1;
1926 sal_Int64 nEndOffset
= -1;
1927 if (pSheetData
&& pDoc
->IsStreamValid(static_cast<SCTAB
>(nTable
)) && !pDoc
->GetChangeTrack())
1928 pSheetData
->GetStreamPos( nTable
, nStartOffset
, nEndOffset
);
1930 if ( nStartOffset
>= 0 && nEndOffset
>= 0 && xSourceStream
.is() )
1932 sal_Int64 nNewStart
= -1;
1933 sal_Int64 nNewEnd
= -1;
1934 CopySourceStream( nStartOffset
, nEndOffset
, nNewStart
, nNewEnd
);
1936 // store position of copied sheet in output
1937 pSheetData
->AddSavePos( nTable
, nNewStart
, nNewEnd
);
1939 // skip iterator entries for this sheet
1940 mpCellsItr
->SkipTable(static_cast<SCTAB
>(nTable
));
1944 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
1945 WriteTable(*pDoc
, nTable
, xTable
);
1947 IncrementProgressBar(false);
1950 WriteExternalRefCaches(*pDoc
);
1951 WriteNamedExpressions(*pDoc
);
1952 WriteDataStream(*pDoc
);
1953 aExportDatabaseRanges
.WriteDatabaseRanges(*pDoc
);
1954 WriteExternalDataMapping(*pDoc
);
1955 ScXMLExportDataPilot
aExportDataPilot(*this);
1956 aExportDataPilot
.WriteDataPilots(*pDoc
);
1957 WriteConsolidation(*pDoc
);
1958 ScXMLExportDDELinks
aExportDDELinks(*pDoc
, *this);
1959 aExportDDELinks
.WriteDDELinks(xSpreadDoc
);
1960 IncrementProgressBar(true, 0);
1961 GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
1964 void ScXMLExport::ExportStyles_( bool bUsed
)
1966 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
1967 if (xSpreadDoc
.is())
1968 RegisterDefinedStyleNames( xSpreadDoc
);
1972 SCTAB
nTableCount(0);
1973 sal_Int32
nShapesCount(0);
1974 CollectSharedData(nTableCount
, nShapesCount
);
1976 rtl::Reference
<XMLCellStyleExport
> aStylesExp(new XMLCellStyleExport(*this, GetAutoStylePool().get()));
1977 if (GetModel().is())
1979 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
1980 if (xMultiServiceFactory
.is())
1982 uno::Reference
<beans::XPropertySet
> xProperties(xMultiServiceFactory
->createInstance(u
"com.sun.star.sheet.Defaults"_ustr
), uno::UNO_QUERY
);
1983 if (xProperties
.is())
1984 aStylesExp
->exportDefaultStyle(xProperties
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
, xCellStylesExportPropertySetMapper
);
1985 GetShapeExport()->ExportGraphicDefaults();
1987 collectDataStyles(false);
1991 aStylesExp
->exportStyleFamily(u
"CellStyles"_ustr
,
1992 XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
, xCellStylesExportPropertySetMapper
, false, XmlStyleFamily::TABLE_CELL
);
1994 SvXMLExport::ExportStyles_(bUsed
);
1999 void ScXMLExport::exportTheme()
2001 if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
2004 ScDocument
* pDoc
= GetDocument();
2008 SdrModel
* pModel
= pDoc
->GetDrawLayer();
2012 auto const& pTheme
= pModel
->getTheme();
2016 ExportThemeElement(pTheme
);
2019 void ScXMLExport::AddStyleFromCells(const uno::Reference
<beans::XPropertySet
>& xProperties
,
2020 const uno::Reference
<sheet::XSpreadsheet
>& xTable
,
2021 sal_Int32 nTable
, const OUString
* pOldName
)
2023 css::uno::Any aAny
= xProperties
->getPropertyValue(u
"FormatID"_ustr
);
2024 sal_uInt64 nKey
= 0;
2027 //! pass xCellRanges instead
2028 uno::Reference
<sheet::XSheetCellRanges
> xCellRanges( xProperties
, uno::UNO_QUERY
);
2030 OUString sStyleName
;
2031 sal_Int32
nNumberFormat(-1);
2032 sal_Int32
nValidationIndex(-1);
2033 std::vector
<XMLPropertyState
> aPropStates(xCellStylesExportPropertySetMapper
->Filter(*this, xProperties
));
2034 std::vector
< XMLPropertyState
>::iterator
aItr(aPropStates
.begin());
2035 std::vector
< XMLPropertyState
>::iterator
aEndItr(aPropStates
.end());
2036 sal_Int32
nCount(0);
2037 while (aItr
!= aEndItr
)
2039 if (aItr
->mnIndex
!= -1)
2041 switch (xCellStylesPropertySetMapper
->GetEntryContextId(aItr
->mnIndex
))
2043 case CTF_SC_VALIDATION
:
2045 pValidationsContainer
->AddValidation(aItr
->maValue
, nValidationIndex
);
2046 // this is not very slow, because it is most the last property or
2047 // if it is not the last property it is the property before the last property,
2048 // so in the worst case only one property has to be copied, but in the best case no
2049 // property has to be copied
2050 aItr
= aPropStates
.erase(aItr
);
2051 aEndItr
= aPropStates
.end(); // old aEndItr is invalidated!
2054 case CTF_SC_CELLSTYLE
:
2056 aItr
->maValue
>>= sStyleName
;
2062 case CTF_SC_NUMBERFORMAT
:
2064 if (aItr
->maValue
>>= nNumberFormat
)
2065 addDataStyle(nNumberFormat
);
2084 if (nCount
== 1) // this is the CellStyle and should be removed if alone
2085 aPropStates
.clear();
2086 if (nNumberFormat
== -1)
2087 xProperties
->getPropertyValue(SC_UNONAME_NUMFMT
) >>= nNumberFormat
;
2088 if (sStyleName
.isEmpty())
2091 if (!aPropStates
.empty())
2096 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, std::move(aPropStates
)))
2098 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_CELL
, *pOldName
);
2099 // add to pCellStyles, so the name is found for normal sheets
2100 pCellStyles
->AddStyleName(*pOldName
, nIndex
);
2106 bool bAdded
= false;
2109 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2110 ScFormatSaveData
* pFormatData
= comphelper::getFromUnoTunnel
<ScModelObj
>(xSpreadDoc
)->GetFormatSaveData();
2111 auto itr
= pFormatData
->maIDToName
.find(nKey
);
2112 if (itr
!= pFormatData
->maIDToName
.end())
2114 sName
= itr
->second
;
2115 bAdded
= GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, aPropStates
);
2117 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_CELL
, sName
);
2120 bool bIsAutoStyle(true);
2121 if (bAdded
|| GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, std::move(aPropStates
)))
2123 pCellStyles
->AddStyleName(sName
, nIndex
);
2126 nIndex
= pCellStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
, bIsAutoStyle
);
2128 const uno::Sequence
<table::CellRangeAddress
> aAddresses(xCellRanges
->getRangeAddresses());
2129 bool bGetMerge(true);
2130 for (table::CellRangeAddress
const & address
: aAddresses
)
2132 pSharedData
->SetLastColumn(nTable
, address
.EndColumn
);
2133 pSharedData
->SetLastRow(nTable
, address
.EndRow
);
2134 pCellStyles
->AddRangeStyleName(address
, nIndex
, bIsAutoStyle
, nValidationIndex
, nNumberFormat
);
2136 bGetMerge
= GetMerged(&address
, xTable
);
2142 OUString
sEncodedStyleName(EncodeStyleName(sStyleName
));
2143 sal_Int32
nIndex(0);
2144 pCellStyles
->AddStyleName(sEncodedStyleName
, nIndex
, false);
2147 const uno::Sequence
<table::CellRangeAddress
> aAddresses(xCellRanges
->getRangeAddresses());
2148 bool bGetMerge(true);
2149 for (table::CellRangeAddress
const & address
: aAddresses
)
2152 bGetMerge
= GetMerged(&address
, xTable
);
2153 pCellStyles
->AddRangeStyleName(address
, nIndex
, false, nValidationIndex
, nNumberFormat
);
2154 if( sStyleName
!= "Default" || nValidationIndex
!= -1 )
2156 pSharedData
->SetLastColumn(nTable
, address
.EndColumn
);
2157 pSharedData
->SetLastRow(nTable
, address
.EndRow
);
2164 void ScXMLExport::AddStyleFromColumn(const uno::Reference
<beans::XPropertySet
>& xColumnProperties
,
2165 const OUString
* pOldName
, sal_Int32
& rIndex
, bool& rIsVisible
)
2167 std::vector
<XMLPropertyState
> aPropStates(xColumnStylesExportPropertySetMapper
->Filter(*this, xColumnProperties
));
2168 if(aPropStates
.empty())
2171 auto aItr
= std::find_if(aPropStates
.begin(), aPropStates
.end(),
2172 [this](const XMLPropertyState
& rPropState
) {
2173 return xColumnStylesPropertySetMapper
->GetEntryContextId(rPropState
.mnIndex
) == CTF_SC_ISVISIBLE
; });
2174 if (aItr
!= aPropStates
.end())
2176 aItr
->maValue
>>= rIsVisible
;
2179 const OUString sParent
;
2182 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_COLUMN
, sParent
, std::move(aPropStates
)))
2184 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_COLUMN
, *pOldName
);
2185 // add to pColumnStyles, so the name is found for normal sheets
2186 rIndex
= pColumnStyles
->AddStyleName(*pOldName
);
2192 if (GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_COLUMN
, sParent
, std::move(aPropStates
)))
2194 rIndex
= pColumnStyles
->AddStyleName(sName
);
2197 rIndex
= pColumnStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX
);
2201 void ScXMLExport::AddStyleFromRow(const uno::Reference
<beans::XPropertySet
>& xRowProperties
,
2202 const OUString
* pOldName
, sal_Int32
& rIndex
)
2204 std::vector
<XMLPropertyState
> aPropStates(xRowStylesExportPropertySetMapper
->Filter(*this, xRowProperties
));
2205 if(aPropStates
.empty())
2208 const OUString sParent
;
2211 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_ROW
, sParent
, std::move(aPropStates
)))
2213 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_ROW
, *pOldName
);
2214 // add to pRowStyles, so the name is found for normal sheets
2215 rIndex
= pRowStyles
->AddStyleName(*pOldName
);
2221 if (GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_ROW
, sParent
, std::move(aPropStates
)))
2223 rIndex
= pRowStyles
->AddStyleName(sName
);
2226 rIndex
= pRowStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX
);
2230 static uno::Any
lcl_GetEnumerated( uno::Reference
<container::XEnumerationAccess
> const & xEnumAccess
, sal_Int32 nIndex
)
2233 uno::Reference
<container::XEnumeration
> xEnum( xEnumAccess
->createEnumeration() );
2236 sal_Int32 nSkip
= nIndex
;
2239 (void) xEnum
->nextElement();
2242 aRet
= xEnum
->nextElement();
2244 catch (container::NoSuchElementException
&)
2251 void ScXMLExport::collectAutoStyles()
2253 SvXMLExport::collectAutoStyles();
2255 if (mbAutoStylesCollected
)
2258 if (!GetModel().is())
2261 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2262 if (!xSpreadDoc
.is())
2265 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
2269 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
2271 // Reserve the loaded cell style names.
2272 RegisterDefinedStyleNames( xSpreadDoc
);
2274 ScModelObj
* pModel
= comphelper::getFromUnoTunnel
<ScModelObj
>(xSpreadDoc
);
2275 ScDocument
* pDoc
= pModel
->GetDocument();
2278 // re-create automatic styles with old names from stored data
2279 ScSheetSaveData
* pSheetData
= pModel
->GetSheetSaveData();
2282 // formulas have to be calculated now, to detect changed results
2283 // (during normal save, they will be calculated anyway)
2284 SCTAB nTabCount
= pDoc
->GetTableCount();
2285 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
2286 if (pDoc
->IsStreamValid(nTab
))
2287 pDoc
->InterpretDirtyCells(ScRange(0, 0, nTab
, pDoc
->MaxCol(), pDoc
->MaxRow(), nTab
));
2289 // stored cell styles
2290 const std::vector
<ScCellStyleEntry
>& rCellEntries
= pSheetData
->GetCellStyles();
2291 for (const auto& rCellEntry
: rCellEntries
)
2293 ScAddress aPos
= rCellEntry
.maCellPos
;
2294 sal_Int32 nTable
= aPos
.Tab();
2295 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2298 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2299 uno::Reference
<beans::XPropertySet
> xProperties(
2300 xTable
->getCellByPosition( aPos
.Col(), aPos
.Row() ), uno::UNO_QUERY
);
2302 AddStyleFromCells(xProperties
, xTable
, nTable
, &rCellEntry
.maName
);
2306 // stored column styles
2307 const std::vector
<ScCellStyleEntry
>& rColumnEntries
= pSheetData
->GetColumnStyles();
2308 for (const auto& rColumnEntry
: rColumnEntries
)
2310 ScAddress aPos
= rColumnEntry
.maCellPos
;
2311 sal_Int32 nTable
= aPos
.Tab();
2312 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2315 uno::Reference
<table::XColumnRowRange
> xColumnRowRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2316 uno::Reference
<table::XTableColumns
> xTableColumns(xColumnRowRange
->getColumns());
2317 uno::Reference
<beans::XPropertySet
> xColumnProperties(xTableColumns
->getByIndex( aPos
.Col() ), uno::UNO_QUERY
);
2319 sal_Int32
nIndex(-1);
2320 bool bIsVisible(true);
2321 AddStyleFromColumn( xColumnProperties
, &rColumnEntry
.maName
, nIndex
, bIsVisible
);
2325 // stored row styles
2326 const std::vector
<ScCellStyleEntry
>& rRowEntries
= pSheetData
->GetRowStyles();
2327 for (const auto& rRowEntry
: rRowEntries
)
2329 ScAddress aPos
= rRowEntry
.maCellPos
;
2330 sal_Int32 nTable
= aPos
.Tab();
2331 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2334 uno::Reference
<table::XColumnRowRange
> xColumnRowRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2335 uno::Reference
<table::XTableRows
> xTableRows(xColumnRowRange
->getRows());
2336 uno::Reference
<beans::XPropertySet
> xRowProperties(xTableRows
->getByIndex( aPos
.Row() ), uno::UNO_QUERY
);
2338 sal_Int32
nIndex(-1);
2339 AddStyleFromRow( xRowProperties
, &rRowEntry
.maName
, nIndex
);
2343 // stored table styles
2344 const std::vector
<ScCellStyleEntry
>& rTableEntries
= pSheetData
->GetTableStyles();
2345 for (const auto& rTableEntry
: rTableEntries
)
2347 ScAddress aPos
= rTableEntry
.maCellPos
;
2348 sal_Int32 nTable
= aPos
.Tab();
2349 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2352 //! separate method AddStyleFromTable needed?
2353 uno::Reference
<beans::XPropertySet
> xTableProperties(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2354 if (xTableProperties
.is())
2356 std::vector
<XMLPropertyState
> aPropStates(xTableStylesExportPropertySetMapper
->Filter(*this, xTableProperties
));
2357 OUString
sName( rTableEntry
.maName
);
2358 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TABLE_TABLE
, OUString(), std::move(aPropStates
));
2359 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE
, sName
);
2364 // stored styles for notes
2366 rtl::Reference
<SvXMLExportPropertyMapper
> xShapeMapper
= XMLShapeExport::CreateShapePropMapper( *this );
2368 const std::vector
<ScNoteStyleEntry
>& rNoteEntries
= pSheetData
->GetNoteStyles();
2369 for (const auto& rNoteEntry
: rNoteEntries
)
2371 ScAddress aPos
= rNoteEntry
.maCellPos
;
2372 SCTAB nTable
= aPos
.Tab();
2373 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2376 //! separate method AddStyleFromNote needed?
2378 ScPostIt
* pNote
= pDoc
->GetNote(aPos
);
2379 OSL_ENSURE( pNote
, "note not found" );
2382 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2383 // all uno shapes are created anyway in CollectSharedData
2384 uno::Reference
<beans::XPropertySet
> xShapeProperties( pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2385 if (xShapeProperties
.is())
2387 if ( !rNoteEntry
.maStyleName
.isEmpty() )
2389 std::vector
<XMLPropertyState
> aPropStates(xShapeMapper
->Filter(*this, xShapeProperties
));
2390 OUString
sName( rNoteEntry
.maStyleName
);
2391 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::SD_GRAPHICS_ID
, OUString(), std::move(aPropStates
));
2392 GetAutoStylePool()->RegisterName(XmlStyleFamily::SD_GRAPHICS_ID
, sName
);
2394 if ( !rNoteEntry
.maTextStyle
.isEmpty() )
2396 std::vector
<XMLPropertyState
> aPropStates(
2397 GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(*this, xShapeProperties
));
2398 OUString
sName( rNoteEntry
.maTextStyle
);
2399 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_PARAGRAPH
, OUString(), std::move(aPropStates
));
2400 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH
, sName
);
2407 // note paragraph styles
2409 rtl::Reference
<SvXMLExportPropertyMapper
> xParaPropMapper
= GetTextParagraphExport()->GetParagraphPropertyMapper();
2411 const std::vector
<ScTextStyleEntry
>& rNoteParaEntries
= pSheetData
->GetNoteParaStyles();
2412 for (const auto& rNoteParaEntry
: rNoteParaEntries
)
2414 ScAddress aPos
= rNoteParaEntry
.maCellPos
;
2415 SCTAB nTable
= aPos
.Tab();
2416 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2419 ScPostIt
* pNote
= pDoc
->GetNote( aPos
);
2420 OSL_ENSURE( pNote
, "note not found" );
2423 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2424 uno::Reference
<container::XEnumerationAccess
> xCellText(pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2425 uno::Reference
<beans::XPropertySet
> xParaProp(
2426 lcl_GetEnumerated( xCellText
, rNoteParaEntry
.maSelection
.start
.nPara
), uno::UNO_QUERY
);
2427 if ( xParaProp
.is() )
2429 std::vector
<XMLPropertyState
> aPropStates(xParaPropMapper
->Filter(*this, xParaProp
));
2430 OUString
sName( rNoteParaEntry
.maName
);
2431 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_PARAGRAPH
, OUString(), std::move(aPropStates
));
2432 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH
, sName
);
2440 rtl::Reference
<SvXMLExportPropertyMapper
> xTextPropMapper
= XMLTextParagraphExport::CreateCharExtPropMapper( *this );
2442 const std::vector
<ScTextStyleEntry
>& rNoteTextEntries
= pSheetData
->GetNoteTextStyles();
2443 for (const auto& rNoteTextEntry
: rNoteTextEntries
)
2445 ScAddress aPos
= rNoteTextEntry
.maCellPos
;
2446 SCTAB nTable
= aPos
.Tab();
2447 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2450 ScPostIt
* pNote
= pDoc
->GetNote( aPos
);
2451 OSL_ENSURE( pNote
, "note not found" );
2454 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2455 uno::Reference
<text::XSimpleText
> xCellText(pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2456 uno::Reference
<beans::XPropertySet
> xCursorProp(xCellText
->createTextCursor(), uno::UNO_QUERY
);
2457 ScDrawTextCursor
* pCursor
= comphelper::getFromUnoTunnel
<ScDrawTextCursor
>( xCursorProp
);
2460 pCursor
->SetSelection( rNoteTextEntry
.maSelection
);
2462 std::vector
<XMLPropertyState
> aPropStates(xTextPropMapper
->Filter(*this, xCursorProp
));
2463 OUString
sName( rNoteTextEntry
.maName
);
2464 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_TEXT
, OUString(), std::move(aPropStates
));
2465 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT
, sName
);
2471 // stored text styles
2473 // Calling createTextCursor fires up editeng, which is very slow, and often subsequent style entries
2474 // refer to the same cell, so cache it.
2476 uno::Reference
<beans::XPropertySet
> xPrevCursorProp
;
2477 const std::vector
<ScTextStyleEntry
>& rTextEntries
= pSheetData
->GetTextStyles();
2478 for (const auto& rTextEntry
: rTextEntries
)
2480 ScAddress aPos
= rTextEntry
.maCellPos
;
2481 sal_Int32 nTable
= aPos
.Tab();
2482 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2486 //! separate method AddStyleFromText needed?
2487 //! cache sheet object
2489 uno::Reference
<beans::XPropertySet
> xCursorProp
;
2490 if (xPrevCursorProp
&& aPrevPos
== aPos
)
2491 xCursorProp
= xPrevCursorProp
;
2494 uno::Reference
<table::XCellRange
> xCellRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2495 uno::Reference
<text::XSimpleText
> xCellText(xCellRange
->getCellByPosition(aPos
.Col(), aPos
.Row()), uno::UNO_QUERY
);
2496 xCursorProp
.set(xCellText
->createTextCursor(), uno::UNO_QUERY
);
2498 ScCellTextCursor
* pCursor
= comphelper::getFromUnoTunnel
<ScCellTextCursor
>( xCursorProp
);
2501 pCursor
->SetSelection( rTextEntry
.maSelection
);
2503 std::vector
<XMLPropertyState
> aPropStates(xTextPropMapper
->Filter(*this, xCursorProp
));
2504 OUString
sName( rTextEntry
.maName
);
2505 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_TEXT
, OUString(), std::move(aPropStates
));
2506 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT
, sName
);
2507 xPrevCursorProp
= std::move(xCursorProp
);
2512 ExportExternalRefCacheStyles(*pDoc
);
2517 SCTAB
nTableCount(0);
2518 sal_Int32
nShapesCount(0);
2519 CollectSharedData(nTableCount
, nShapesCount
);
2521 sal_Int32
nTableCount(xIndex
->getCount());
2522 CollectShapesAutoStyles(nTableCount
);
2523 for (sal_Int32 nTable
= 0; nTable
< nTableCount
; ++nTable
, IncrementProgressBar(false))
2525 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2529 // table styles array must be complete, including copied tables - Add should find the stored style
2530 uno::Reference
<beans::XPropertySet
> xTableProperties(xTable
, uno::UNO_QUERY
);
2531 if (xTableProperties
.is())
2533 std::vector
<XMLPropertyState
> aPropStates(xTableStylesExportPropertySetMapper
->Filter(*this, xTableProperties
));
2534 if(!aPropStates
.empty())
2537 GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_TABLE
, OUString(), std::move(aPropStates
));
2538 aTableStyles
.push_back(sName
);
2542 // collect other auto-styles only for non-copied sheets
2543 uno::Reference
<sheet::XUniqueCellFormatRangesSupplier
> xCellFormatRanges ( xTable
, uno::UNO_QUERY
);
2544 if ( xCellFormatRanges
.is() )
2546 uno::Reference
<container::XIndexAccess
> xFormatRangesIndex(xCellFormatRanges
->getUniqueCellFormatRanges());
2547 if (xFormatRangesIndex
.is())
2549 sal_Int32
nFormatRangesCount(xFormatRangesIndex
->getCount());
2550 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount
);
2551 for (sal_Int32 nFormatRange
= 0; nFormatRange
< nFormatRangesCount
; ++nFormatRange
)
2553 uno::Reference
< sheet::XSheetCellRanges
> xCellRanges(xFormatRangesIndex
->getByIndex(nFormatRange
), uno::UNO_QUERY
);
2554 if (xCellRanges
.is())
2556 uno::Reference
<beans::XPropertySet
> xProperties (xCellRanges
, uno::UNO_QUERY
);
2557 if (xProperties
.is())
2559 AddStyleFromCells(xProperties
, xTable
, nTable
, nullptr);
2560 IncrementProgressBar(false);
2568 uno::Reference
<table::XColumnRowRange
> xColumnRowRange (xTable
, uno::UNO_QUERY
);
2569 if (xColumnRowRange
.is())
2571 pDoc
->SyncColRowFlags();
2572 uno::Reference
<table::XTableColumns
> xTableColumns(xColumnRowRange
->getColumns());
2573 if (xTableColumns
.is())
2575 sal_Int32
nColumns(pDoc
->GetLastChangedColFlagsWidth(sal::static_int_cast
<SCTAB
>(nTable
)));
2576 pSharedData
->SetLastColumn(nTable
, nColumns
);
2577 table::CellRangeAddress
aCellAddress(GetEndAddress(xTable
));
2578 if (aCellAddress
.EndColumn
> nColumns
)
2581 pColumnStyles
->AddNewTable(nTable
, aCellAddress
.EndColumn
);
2584 pColumnStyles
->AddNewTable(nTable
, nColumns
);
2585 sal_Int32 nColumn
= 0;
2586 while (nColumn
<= pDoc
->MaxCol())
2588 sal_Int32
nIndex(-1);
2589 bool bIsVisible(true);
2590 uno::Reference
<beans::XPropertySet
> xColumnProperties(xTableColumns
->getByIndex(nColumn
), uno::UNO_QUERY
);
2591 if (xColumnProperties
.is())
2593 AddStyleFromColumn( xColumnProperties
, nullptr, nIndex
, bIsVisible
);
2594 pColumnStyles
->AddFieldStyleName(nTable
, nColumn
, nIndex
, bIsVisible
);
2596 sal_Int32
nOld(nColumn
);
2597 nColumn
= pDoc
->GetNextDifferentChangedColFlagsWidth(sal::static_int_cast
<SCTAB
>(nTable
), static_cast<SCCOL
>(nColumn
));
2598 for (sal_Int32 i
= nOld
+ 1; i
< nColumn
; ++i
)
2599 pColumnStyles
->AddFieldStyleName(nTable
, i
, nIndex
, bIsVisible
);
2601 if (aCellAddress
.EndColumn
> nColumns
)
2603 bool bIsVisible(true);
2604 sal_Int32
nIndex(pColumnStyles
->GetStyleNameIndex(nTable
, nColumns
, bIsVisible
));
2605 for (sal_Int32 i
= nColumns
+ 1; i
<= aCellAddress
.EndColumn
; ++i
)
2606 pColumnStyles
->AddFieldStyleName(nTable
, i
, nIndex
, bIsVisible
);
2609 uno::Reference
<table::XTableRows
> xTableRows(xColumnRowRange
->getRows());
2610 if (xTableRows
.is())
2612 sal_Int32
nRows(pDoc
->GetLastChangedRowFlagsWidth(sal::static_int_cast
<SCTAB
>(nTable
)));
2613 pSharedData
->SetLastRow(nTable
, nRows
);
2615 pRowStyles
->AddNewTable(nTable
, pDoc
->MaxRow());
2617 while (nRow
<= pDoc
->MaxRow())
2619 sal_Int32 nIndex
= 0;
2620 uno::Reference
<beans::XPropertySet
> xRowProperties(xTableRows
->getByIndex(nRow
), uno::UNO_QUERY
);
2621 if(xRowProperties
.is())
2623 AddStyleFromRow( xRowProperties
, nullptr, nIndex
);
2624 pRowStyles
->AddFieldStyleName(nTable
, nRow
, nIndex
);
2626 sal_Int32
nOld(nRow
);
2627 nRow
= pDoc
->GetNextDifferentChangedRowFlagsWidth(sal::static_int_cast
<SCTAB
>(nTable
), static_cast<SCROW
>(nRow
));
2628 if (nRow
> nOld
+ 1)
2629 pRowStyles
->AddFieldStyleName(nTable
, nOld
+ 1, nIndex
, nRow
- 1);
2633 ExportCellTextAutoStyles(*pDoc
, nTable
);
2637 pChangeTrackingExportHelper
->CollectAutoStyles();
2640 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
)
2641 // tdf#154445 - export all page styles even if they are not in use
2642 GetPageExport()->collectAutoStyles(false);
2644 mbAutoStylesCollected
= true;
2647 void ScXMLExport::ExportAutoStyles_()
2649 if (!GetModel().is())
2652 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2653 if (!xSpreadDoc
.is())
2656 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
2660 collectAutoStyles();
2662 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
2664 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_COLUMN
);
2665 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_ROW
);
2666 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_TABLE
);
2667 exportAutoDataStyles();
2668 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_CELL
);
2670 GetShapeExport()->exportAutoStyles();
2671 GetFormExport()->exportAutoStyles( );
2673 if (ScDocument
* pDoc
= GetDocument())
2675 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
2676 // #i100879# write the table style for cached tables only if there are cached tables
2677 // (same logic as in ExportExternalRefCacheStyles)
2678 if (pRefMgr
->hasExternalData())
2680 // Special table style for the external ref cache tables.
2681 AddAttribute(XML_NAMESPACE_STYLE
, XML_NAME
, sExternalRefTabStyleName
);
2682 AddAttribute(XML_NAMESPACE_STYLE
, XML_FAMILY
, XML_TABLE
);
2683 SvXMLElementExport
aElemStyle(*this, XML_NAMESPACE_STYLE
, XML_STYLE
, true, true);
2684 AddAttribute(XML_NAMESPACE_TABLE
, XML_DISPLAY
, XML_FALSE
);
2685 SvXMLElementExport
aElemStyleTabProps(*this, XML_NAMESPACE_STYLE
, XML_TABLE_PROPERTIES
, true, true);
2690 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
)
2692 exportAutoDataStyles();
2693 GetPageExport()->exportAutoStyles();
2696 // #i30251#; only write Text Styles once
2698 if ((getExportFlags() & SvXMLExportFlags::CONTENT
) || (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
))
2699 GetTextParagraphExport()->exportTextAutoStyles();
2702 void ScXMLExport::ExportMasterStyles_()
2704 // tdf#154445 - export all page styles even if they are not in use
2705 GetPageExport()->exportMasterStyles( false );
2708 void ScXMLExport::CollectInternalShape(ScDocument
& rDoc
, uno::Reference
< drawing::XShape
> const & xShape
)
2710 // detective objects and notes
2711 SdrObject
* pObject
= SdrObject::getSdrObjectFromXShape( xShape
);
2715 // collect note caption objects from all layers (internal or hidden)
2716 if( ScDrawObjData
* pCaptData
= ScDrawLayer::GetNoteCaptionData( pObject
, static_cast< SCTAB
>( nCurrentTable
) ) )
2718 if (rDoc
.GetNote(pCaptData
->maStart
))
2720 pSharedData
->AddNoteObj( xShape
, pCaptData
->maStart
);
2722 // #i60851# When the file is saved while editing a new note,
2723 // the cell is still empty -> last column/row must be updated
2724 OSL_ENSURE( pCaptData
->maStart
.Tab() == nCurrentTable
, "invalid table in object data" );
2725 pSharedData
->SetLastColumn( nCurrentTable
, pCaptData
->maStart
.Col() );
2726 pSharedData
->SetLastRow( nCurrentTable
, pCaptData
->maStart
.Row() );
2729 // other objects from internal layer only (detective)
2730 else if( pObject
->GetLayer() == SC_LAYER_INTERN
)
2732 ScDetectiveFunc
aDetFunc(rDoc
, static_cast<SCTAB
>(nCurrentTable
));
2733 ScAddress aPosition
;
2734 ScRange aSourceRange
;
2736 ScDetectiveObjType eObjType
= aDetFunc
.GetDetectiveObjectType(
2737 pObject
, nCurrentTable
, aPosition
, aSourceRange
, bRedLine
);
2738 pSharedData
->GetDetectiveObjContainer()->AddObject( eObjType
, static_cast<SCTAB
>(nCurrentTable
), aPosition
, aSourceRange
, bRedLine
);
2742 static uno::Reference
<sheet::XSheetCellRange
> lclGetSheetRange(const uno::Reference
<sheet::XSpreadsheet
>& xTable
, sal_Int32 nCol
, sal_Int32 nRow
)
2746 return uno::Reference
<sheet::XSheetCellRange
>(xTable
->getCellRangeByPosition(nCol
, nRow
, nCol
, nRow
), uno::UNO_QUERY
);
2748 catch (const uno::Exception
&)
2750 TOOLS_WARN_EXCEPTION("sc", "Exception in getCellRangeByPosition, col: " << nCol
<< ", row: " << nRow
);
2751 assert(false && "try and capture this in crashtesting");
2756 bool ScXMLExport::GetMerged (const table::CellRangeAddress
* pCellAddress
,
2757 const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
2760 sal_Int32
nRow(pCellAddress
->StartRow
);
2761 sal_Int32
nCol(pCellAddress
->StartColumn
);
2762 sal_Int32
nEndRow(pCellAddress
->EndRow
);
2763 sal_Int32
nEndCol(pCellAddress
->EndColumn
);
2764 bool bRowInc(nEndRow
> nRow
);
2765 while(!bReady
&& nRow
<= nEndRow
&& nCol
<= nEndCol
)
2767 uno::Reference
<sheet::XSheetCellRange
> xSheetCellRange(lclGetSheetRange(xTable
, nCol
, nRow
));
2768 if (xSheetCellRange
.is())
2770 uno::Reference
<sheet::XSheetCellCursor
> xCursor(xTable
->createCursorByRange(xSheetCellRange
));
2773 uno::Reference
<sheet::XCellRangeAddressable
> xCellAddress (xCursor
, uno::UNO_QUERY
);
2774 xCursor
->collapseToMergedArea();
2775 table::CellRangeAddress
aCellAddress2(xCellAddress
->getRangeAddress());
2776 ScRange
aScRange( aCellAddress2
.StartColumn
, aCellAddress2
.StartRow
, aCellAddress2
.Sheet
,
2777 aCellAddress2
.EndColumn
, aCellAddress2
.EndRow
, aCellAddress2
.Sheet
);
2779 if ((aScRange
.aEnd
.Row() > nRow
||
2780 aScRange
.aEnd
.Col() > nCol
) &&
2781 aScRange
.aStart
.Row() == nRow
&&
2782 aScRange
.aStart
.Col() == nCol
)
2784 pMergedRangesContainer
->AddRange(aScRange
);
2785 pSharedData
->SetLastColumn(aScRange
.aEnd
.Tab(), aScRange
.aEnd
.Col());
2786 pSharedData
->SetLastRow(aScRange
.aEnd
.Tab(), aScRange
.aEnd
.Row());
2800 OSL_ENSURE(!(!bReady
&& nEndRow
> nRow
&& nEndCol
> nCol
), "should not be possible");
2805 bool ScXMLExport::IsMatrix (ScDocument
& rDoc
, const ScAddress
& aCell
,
2806 ScRange
& aCellAddress
, bool& bIsFirst
)
2810 ScRange aMatrixRange
;
2812 if (rDoc
.GetMatrixFormulaRange(aCell
, aMatrixRange
))
2814 aCellAddress
= aMatrixRange
;
2815 if ((aCellAddress
.aStart
.Col() == aCell
.Col() && aCellAddress
.aStart
.Row() == aCell
.Row()) &&
2816 (aCellAddress
.aEnd
.Col() > aCell
.Col() || aCellAddress
.aEnd
.Row() > aCell
.Row()))
2821 else if (aCellAddress
.aStart
.Col() != aCell
.Col() || aCellAddress
.aStart
.Row() != aCell
.Row() ||
2822 aCellAddress
.aEnd
.Col() != aCell
.Col() || aCellAddress
.aEnd
.Row()!= aCell
.Row())
2834 void ScXMLExport::WriteTable(ScDocument
& rDoc
, sal_Int32 nTable
, const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
2839 xCurrentTable
.set(xTable
);
2840 uno::Reference
<container::XNamed
> xName (xTable
, uno::UNO_QUERY
);
2844 nCurrentTable
= sal::static_int_cast
<sal_uInt16
>( nTable
);
2845 OUString
sOUTableName(xName
->getName());
2846 AddAttribute(sAttrName
, sOUTableName
);
2847 AddAttribute(sAttrStyleName
, aTableStyles
[nTable
]);
2849 uno::Reference
<util::XProtectable
> xProtectable (xTable
, uno::UNO_QUERY
);
2850 const ScTableProtection
* pProtect
= nullptr;
2851 if (xProtectable
.is() && xProtectable
->isProtected())
2853 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
2854 pProtect
= rDoc
.GetTabProtection(nTable
);
2857 OUStringBuffer aBuffer
;
2858 ScPasswordHash eHashUsed
= PASSHASH_UNSPECIFIED
;
2859 if (pProtect
->hasPasswordHash(PASSHASH_SHA1
))
2861 ::comphelper::Base64::encode(aBuffer
,
2862 pProtect
->getPasswordHash(PASSHASH_SHA1
));
2863 eHashUsed
= PASSHASH_SHA1
;
2865 else if (pProtect
->hasPasswordHash(PASSHASH_SHA256
))
2867 ::comphelper::Base64::encode(aBuffer
,
2868 pProtect
->getPasswordHash(PASSHASH_SHA256
));
2869 eHashUsed
= PASSHASH_SHA256
;
2871 else if (pProtect
->hasPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
))
2873 // Double-hash this by SHA1 on top of the legacy xls hash.
2874 uno::Sequence
<sal_Int8
> aHash
= pProtect
->getPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
);
2875 ::comphelper::Base64::encode(aBuffer
, aHash
);
2876 eHashUsed
= PASSHASH_XL
;
2878 if (!aBuffer
.isEmpty())
2880 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY
, aBuffer
.makeStringAndClear());
2881 if (getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
2883 if (eHashUsed
== PASSHASH_XL
)
2885 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2886 ScPassHashHelper::getHashURI(PASSHASH_XL
));
2887 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2888 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
,
2889 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
2891 else if (eHashUsed
== PASSHASH_SHA1
)
2893 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2894 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
2896 else if (eHashUsed
== PASSHASH_SHA256
)
2898 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2899 ScPassHashHelper::getHashURI(PASSHASH_SHA256
));
2905 OUString sPrintRanges
;
2906 ScRange aColumnHeaderRange
;
2907 bool bHasColumnHeader
;
2908 GetColumnRowHeader(rDoc
, bHasColumnHeader
, aColumnHeaderRange
, bHasRowHeader
, aRowHeaderRange
, sPrintRanges
);
2909 if( !sPrintRanges
.isEmpty() )
2910 AddAttribute( XML_NAMESPACE_TABLE
, XML_PRINT_RANGES
, sPrintRanges
);
2911 else if (!rDoc
.IsPrintEntireSheet(static_cast<SCTAB
>(nTable
)))
2912 AddAttribute( XML_NAMESPACE_TABLE
, XML_PRINT
, XML_FALSE
);
2913 SvXMLElementExport
aElemT(*this, sElemTab
, true, true);
2915 if (pProtect
&& pProtect
->isProtected() && getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2917 if (pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
))
2918 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SELECT_PROTECTED_CELLS
, XML_TRUE
);
2919 if (pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
))
2920 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SELECT_UNPROTECTED_CELLS
, XML_TRUE
);
2922 if (pProtect
->isOptionEnabled(ScTableProtection::INSERT_COLUMNS
))
2923 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_INSERT_COLUMNS
, XML_TRUE
);
2924 if (pProtect
->isOptionEnabled(ScTableProtection::INSERT_ROWS
))
2925 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_INSERT_ROWS
, XML_TRUE
);
2927 if (pProtect
->isOptionEnabled(ScTableProtection::DELETE_COLUMNS
))
2928 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DELETE_COLUMNS
, XML_TRUE
);
2929 if (pProtect
->isOptionEnabled(ScTableProtection::DELETE_ROWS
))
2930 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DELETE_ROWS
, XML_TRUE
);
2932 if (pProtect
->isOptionEnabled(ScTableProtection::AUTOFILTER
))
2933 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_USE_AUTOFILTER
, XML_TRUE
);
2934 if (pProtect
->isOptionEnabled(ScTableProtection::PIVOT_TABLES
))
2935 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_USE_PIVOT
, XML_TRUE
);
2937 OUString aElemName
= GetNamespaceMap().GetQNameByKey(
2938 XML_NAMESPACE_LO_EXT
, GetXMLToken(XML_TABLE_PROTECTION
));
2940 SvXMLElementExport
aElemProtected(*this, aElemName
, true, true);
2945 if (rDoc
.GetSheetEvents( static_cast<SCTAB
>(nTable
) ) &&
2946 getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
2948 // store sheet events
2949 uno::Reference
<document::XEventsSupplier
> xSupplier(xTable
, uno::UNO_QUERY
);
2950 uno::Reference
<container::XNameAccess
> xEvents
= xSupplier
->getEvents();
2951 GetEventExport().ExportExt( xEvents
);
2955 WriteScenario(rDoc
);
2956 uno::Reference
<drawing::XDrawPage
> xDrawPage
;
2957 if (pSharedData
->HasForm(nTable
, xDrawPage
) && xDrawPage
.is())
2959 ::xmloff::OOfficeFormsExport
aForms(*this);
2960 GetFormExport()->exportForms( xDrawPage
);
2961 bool bRet(GetFormExport()->seekPage( xDrawPage
));
2962 OSL_ENSURE( bRet
, "OFormLayerXMLExport::seekPage failed!" );
2964 if (pSharedData
->HasDrawPage())
2966 GetShapeExport()->seekShapes(pSharedData
->GetDrawPage(nTable
));
2967 WriteTableShapes(rDoc
);
2969 table::CellRangeAddress
aRange(GetEndAddress(xTable
));
2970 pSharedData
->SetLastColumn(nTable
, aRange
.EndColumn
);
2971 pSharedData
->SetLastRow(nTable
, aRange
.EndRow
);
2972 mpCellsItr
->SetCurrentTable(rDoc
, static_cast<SCTAB
>(nTable
), xCurrentTable
);
2973 pGroupColumns
->NewTable();
2974 pGroupRows
->NewTable();
2975 FillColumnRowGroups(rDoc
);
2976 if (bHasColumnHeader
)
2977 pSharedData
->SetLastColumn(nTable
, aColumnHeaderRange
.aEnd
.Col());
2978 bRowHeaderOpen
= false;
2980 pSharedData
->SetLastRow(nTable
, aRowHeaderRange
.aEnd
.Row());
2981 pDefaults
->FillDefaultStyles(nTable
, pSharedData
->GetLastRow(nTable
),
2982 pSharedData
->GetLastColumn(nTable
), pCellStyles
.get(), &rDoc
);
2983 pRowFormatRanges
->SetColDefaults(&pDefaults
->GetColDefaults());
2984 pCellStyles
->SetColDefaults(&pDefaults
->GetColDefaults());
2985 ExportColumns(nTable
, aColumnHeaderRange
, bHasColumnHeader
);
2986 bool bIsFirst(true);
2987 sal_Int32
nEqualCells(0);
2990 while (mpCellsItr
->GetNext(rDoc
, aCell
, pCellStyles
.get()))
2994 ExportFormatRanges(rDoc
, 0, 0, aCell
.maCellAddress
.Col()-1, aCell
.maCellAddress
.Row(), nTable
);
3000 if ((aPrevCell
.maCellAddress
.Row() == aCell
.maCellAddress
.Row()) &&
3001 (aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1 == aCell
.maCellAddress
.Col()))
3003 if (IsCellEqual(rDoc
, aPrevCell
, aCell
))
3007 WriteCell(rDoc
, aPrevCell
, nEqualCells
);
3014 WriteCell(rDoc
, aPrevCell
, nEqualCells
);
3015 ExportFormatRanges(rDoc
, aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1, aPrevCell
.maCellAddress
.Row(),
3016 aCell
.maCellAddress
.Col()-1, aCell
.maCellAddress
.Row(), nTable
);
3024 WriteCell(rDoc
, aPrevCell
, nEqualCells
);
3025 ExportFormatRanges(rDoc
, aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1, aPrevCell
.maCellAddress
.Row(),
3026 pSharedData
->GetLastColumn(nTable
), pSharedData
->GetLastRow(nTable
), nTable
);
3029 ExportFormatRanges(rDoc
, 0, 0, pSharedData
->GetLastColumn(nTable
), pSharedData
->GetLastRow(nTable
), nTable
);
3031 CloseRow(pSharedData
->GetLastRow(nTable
));
3033 // Export sheet-local named ranges.
3034 ScRangeName
* pRangeName
= rDoc
.GetRangeName(nTable
);
3035 if (pRangeName
&& !pRangeName
->empty())
3037 WriteNamedRange(rDoc
, pRangeName
);
3040 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3042 //export new conditional format information
3043 ExportConditionalFormat(rDoc
, nTable
);
3044 exportSparklineGroups(rDoc
, nTable
);
3050 void writeContent(ScDocument
& rDoc
, ScXMLExport
& rExport
, const OUString
& rStyleName
,
3051 const OUString
& rContent
, const SvxFieldData
* pField
)
3053 std::unique_ptr
<SvXMLElementExport
> pElem
;
3054 if (!rStyleName
.isEmpty())
3056 // Formatted section with automatic style.
3057 rExport
.AddAttribute(XML_NAMESPACE_TEXT
, XML_STYLE_NAME
, rStyleName
);
3058 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3059 XML_NAMESPACE_TEXT
, GetXMLToken(XML_SPAN
));
3060 pElem
.reset(new SvXMLElementExport(rExport
, aElemName
, false, false));
3065 // Write a field item.
3066 OUString aFieldVal
= ScEditUtil::GetCellFieldValue(*pField
, &rDoc
, nullptr, nullptr);
3067 switch (pField
->GetClassId())
3069 case text::textfield::Type::URL
:
3071 // <text:a xlink:href="url" xlink:type="simple">value</text:a>
3073 const SvxURLField
* pURLField
= static_cast<const SvxURLField
*>(pField
);
3074 const OUString
& aURL
= pURLField
->GetURL();
3075 rExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, rExport
.GetRelativeReference(aURL
));
3076 rExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, u
"simple"_ustr
);
3077 const OUString
& aTargetFrame
= pURLField
->GetTargetFrame();
3078 if (!aTargetFrame
.isEmpty())
3079 rExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_TARGET_FRAME_NAME
, aTargetFrame
);
3081 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3082 XML_NAMESPACE_TEXT
, GetXMLToken(XML_A
));
3083 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3084 rExport
.Characters(aFieldVal
);
3087 case text::textfield::Type::DATE
:
3089 // <text:date style:data-style-name="N2" text:date-value="YYYY-MM-DD">value</text:date>
3091 Date
aDate(Date::SYSTEM
);
3092 OUStringBuffer aBuf
;
3093 sal_Int32 nVal
= aDate
.GetYear();
3094 aBuf
.append(OUString::number(nVal
) + "-");
3095 nVal
= aDate
.GetMonth();
3098 aBuf
.append(OUString::number(nVal
) + "-");
3099 nVal
= aDate
.GetDay();
3103 rExport
.AddAttribute(XML_NAMESPACE_STYLE
, XML_DATA_STYLE_NAME
, u
"N2"_ustr
);
3104 rExport
.AddAttribute(XML_NAMESPACE_TEXT
, XML_DATE_VALUE
, aBuf
.makeStringAndClear());
3106 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3107 XML_NAMESPACE_TEXT
, GetXMLToken(XML_DATE
));
3108 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3109 rExport
.Characters(aFieldVal
);
3112 case text::textfield::Type::DOCINFO_TITLE
:
3114 // <text:title>value</text:title>
3116 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3117 XML_NAMESPACE_TEXT
, GetXMLToken(XML_TITLE
));
3118 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3119 rExport
.Characters(aFieldVal
);
3122 case text::textfield::Type::TABLE
:
3124 // <text:sheet-name>value</text:sheet-name>
3126 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3127 XML_NAMESPACE_TEXT
, GetXMLToken(XML_SHEET_NAME
));
3128 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3129 rExport
.Characters(aFieldVal
);
3133 rExport
.Characters(aFieldVal
);
3137 rExport
.Characters(rContent
);
3140 void flushParagraph(
3142 ScXMLExport
& rExport
, std::u16string_view rParaText
,
3143 rtl::Reference
<XMLPropertySetMapper
> const & xMapper
, rtl::Reference
<SvXMLAutoStylePoolP
> const & xStylePool
,
3144 const ScXMLEditAttributeMap
& rAttrMap
,
3145 std::vector
<editeng::Section
>::const_iterator it
, std::vector
<editeng::Section
>::const_iterator
const & itEnd
)
3147 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3148 XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
3149 SvXMLElementExport
aElemP(rExport
, aElemName
, false, false);
3151 for (; it
!= itEnd
; ++it
)
3153 const editeng::Section
& rSec
= *it
;
3155 OUString
aContent(rParaText
.substr(rSec
.mnStart
, rSec
.mnEnd
- rSec
.mnStart
));
3157 std::vector
<XMLPropertyState
> aPropStates
;
3158 const SvxFieldData
* pField
= toXMLPropertyStates(rExport
, aPropStates
, rSec
.maAttributes
, xMapper
, rAttrMap
);
3159 OUString aStyleName
= xStylePool
->Find(XmlStyleFamily::TEXT_TEXT
, OUString(), aPropStates
);
3160 if (aContent
== "\x001" && !pField
)
3162 for (const SfxPoolItem
* p
: rSec
.maAttributes
)
3164 if (p
->Which() == EE_FEATURE_TAB
)
3166 SvXMLElementExport
Tab(rExport
, XML_NAMESPACE_TEXT
, XML_TAB
, false, false);
3169 else if (p
->Which() == EE_FEATURE_LINEBR
)
3171 SvXMLElementExport
L(rExport
, XML_NAMESPACE_TEXT
, XML_LINE_BREAK
, false, false);
3177 writeContent(rDoc
, rExport
, aStyleName
, aContent
, pField
);
3183 void ScXMLExport::WriteCell(ScDocument
& rDoc
, ScMyCell
& aCell
, sal_Int32 nEqualCellCount
)
3185 // nEqualCellCount is the number of additional cells
3186 SetRepeatAttribute(nEqualCellCount
, (aCell
.nType
!= table::CellContentType_EMPTY
));
3188 if (aCell
.nStyleIndex
!= -1)
3189 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(aCell
.nStyleIndex
, aCell
.bIsAutoStyle
));
3190 if (aCell
.nValidationIndex
> -1)
3191 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(aCell
.nValidationIndex
));
3192 const bool bIsFirstMatrixCell(aCell
.bIsMatrixBase
);
3193 if (bIsFirstMatrixCell
)
3195 SCCOL
nColumns( aCell
.aMatrixRange
.aEnd
.Col() - aCell
.aMatrixRange
.aStart
.Col() + 1 );
3196 SCROW
nRows( aCell
.aMatrixRange
.aEnd
.Row() - aCell
.aMatrixRange
.aStart
.Row() + 1 );
3197 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_MATRIX_COLUMNS_SPANNED
, OUString::number(nColumns
));
3198 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_MATRIX_ROWS_SPANNED
, OUString::number(nRows
));
3200 bool bIsEmpty(false);
3201 switch (aCell
.nType
)
3203 case table::CellContentType_EMPTY
:
3208 case table::CellContentType_VALUE
:
3210 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3211 aCell
.nNumberFormat
, aCell
.maBaseCell
.getDouble());
3212 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3213 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3214 aCell
.nNumberFormat
, aCell
.maBaseCell
.getDouble(), false, XML_NAMESPACE_CALC_EXT
, false);
3217 case table::CellContentType_TEXT
:
3219 OUString
sFormattedString(lcl_GetFormattedString(rDoc
, aCell
.maBaseCell
, aCell
.maCellAddress
));
3220 OUString sCellString
= aCell
.maBaseCell
.getString(&rDoc
);
3221 bool bExportValue
= sCellString
.indexOf('\x001') == -1;
3222 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3223 sCellString
, sFormattedString
, bExportValue
);
3224 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3225 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3226 sCellString
, sFormattedString
, false, XML_NAMESPACE_CALC_EXT
);
3229 case table::CellContentType_FORMULA
:
3231 if (aCell
.maBaseCell
.getType() == CELLTYPE_FORMULA
)
3233 const bool bIsMatrix(bIsFirstMatrixCell
|| aCell
.bIsMatrixCovered
);
3234 ScFormulaCell
* pFormulaCell
= aCell
.maBaseCell
.getFormula();
3235 if (!bIsMatrix
|| bIsFirstMatrixCell
)
3237 if (!mpCompileFormulaCxt
)
3239 const formula::FormulaGrammar::Grammar eGrammar
= rDoc
.GetStorageGrammar();
3240 mpCompileFormulaCxt
.reset(new sc::CompileFormulaContext(rDoc
, eGrammar
));
3242 mpCompileFormulaCxt
->setODFSavingVersion(getSaneDefaultVersion());
3243 OUString aFormula
= pFormulaCell
->GetFormula(*mpCompileFormulaCxt
);
3244 sal_uInt16 nNamespacePrefix
=
3245 (mpCompileFormulaCxt
->getGrammar() == formula::FormulaGrammar::GRAM_ODFF
? XML_NAMESPACE_OF
: XML_NAMESPACE_OOOC
);
3249 AddAttribute(sAttrFormula
, GetNamespaceMap().GetQNameByKey(nNamespacePrefix
, aFormula
, false));
3253 AddAttribute(sAttrFormula
, GetNamespaceMap().GetQNameByKey(nNamespacePrefix
, aFormula
.copy(1, aFormula
.getLength()-2), false));
3256 if (pFormulaCell
->GetErrCode() != FormulaError::NONE
)
3258 AddAttribute(sAttrValueType
, XML_STRING
);
3259 AddAttribute(sAttrStringValue
, aCell
.maBaseCell
.getString(&rDoc
));
3260 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3262 //export calcext:value-type="error"
3263 AddAttribute(XML_NAMESPACE_CALC_EXT
,XML_VALUE_TYPE
, u
"error"_ustr
);
3266 else if (pFormulaCell
->IsValue())
3270 GetNumberFormatAttributesExportHelper()->GetCellType(aCell
.nNumberFormat
, sCurrency
, bIsStandard
);
3271 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3272 aCell
.nNumberFormat
, rDoc
.GetValue(aCell
.maCellAddress
));
3273 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3275 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3276 aCell
.nNumberFormat
, rDoc
.GetValue(aCell
.maCellAddress
), false, XML_NAMESPACE_CALC_EXT
, false );
3281 if (!aCell
.maBaseCell
.getString(&rDoc
).isEmpty())
3283 AddAttribute(sAttrValueType
, XML_STRING
);
3284 AddAttribute(sAttrStringValue
, aCell
.maBaseCell
.getString(&rDoc
));
3285 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3287 AddAttribute(XML_NAMESPACE_CALC_EXT
,XML_VALUE_TYPE
, XML_STRING
);
3297 OUString
* pCellString(&sElemCell
);
3298 if (aCell
.bIsCovered
)
3300 pCellString
= &sElemCoveredCell
;
3304 if (aCell
.bIsMergedBase
)
3306 SCCOL
nColumns( aCell
.aMergeRange
.aEnd
.Col() - aCell
.aMergeRange
.aStart
.Col() + 1 );
3307 SCROW
nRows( aCell
.aMergeRange
.aEnd
.Row() - aCell
.aMergeRange
.aStart
.Row() + 1 );
3308 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_SPANNED
, OUString::number(nColumns
));
3309 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_SPANNED
, OUString::number(nRows
));
3312 SvXMLElementExport
aElemC(*this, *pCellString
, true, true);
3314 WriteAreaLink(aCell
);
3315 WriteAnnotation(rDoc
, aCell
);
3316 WriteDetective(rDoc
, aCell
);
3320 if (aCell
.maBaseCell
.getType() == CELLTYPE_EDIT
)
3322 WriteEditCell(rDoc
, aCell
.maBaseCell
.getEditText());
3324 else if (aCell
.maBaseCell
.getType() == CELLTYPE_FORMULA
&& aCell
.maBaseCell
.getFormula()->IsMultilineResult())
3326 WriteMultiLineFormulaResult(aCell
.maBaseCell
.getFormula());
3330 SvXMLElementExport
aElemP(*this, sElemP
, true, false);
3333 ScCellFormat::GetOutputString(rDoc
, aCell
.maCellAddress
, aCell
.maBaseCell
);
3335 bool bPrevCharWasSpace
= true;
3336 GetTextParagraphExport()->exportCharacterData(aParaStr
, bPrevCharWasSpace
);
3339 WriteShapes(rDoc
, aCell
);
3341 IncrementProgressBar(false);
3344 void ScXMLExport::WriteEditCell(ScDocument
& rDoc
, const EditTextObject
* pText
)
3346 rtl::Reference
<XMLPropertySetMapper
> xMapper
= GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
3347 rtl::Reference
<SvXMLAutoStylePoolP
> xStylePool
= GetAutoStylePool();
3348 const ScXMLEditAttributeMap
& rAttrMap
= GetEditAttributeMap();
3350 // Get raw paragraph texts first.
3351 std::vector
<OUString
> aParaTexts
;
3352 sal_Int32 nParaCount
= pText
->GetParagraphCount();
3353 aParaTexts
.reserve(nParaCount
);
3354 for (sal_Int32 i
= 0; i
< nParaCount
; ++i
)
3355 aParaTexts
.push_back(pText
->GetText(i
));
3357 // Get all section data and iterate through them.
3358 std::vector
<editeng::Section
> aAttrs
;
3359 pText
->GetAllSections(aAttrs
);
3360 std::vector
<editeng::Section
>::const_iterator itSec
= aAttrs
.begin(), itSecEnd
= aAttrs
.end();
3361 std::vector
<editeng::Section
>::const_iterator itPara
= itSec
;
3362 sal_Int32 nCurPara
= 0; // current paragraph
3363 for (; itSec
!= itSecEnd
; ++itSec
)
3365 const editeng::Section
& rSec
= *itSec
;
3366 if (nCurPara
== rSec
.mnParagraph
)
3367 // Still in the same paragraph.
3370 // Start of a new paragraph. Flush the old paragraph.
3371 flushParagraph(rDoc
, *this, aParaTexts
[nCurPara
], xMapper
, xStylePool
, rAttrMap
, itPara
, itSec
);
3372 nCurPara
= rSec
.mnParagraph
;
3376 flushParagraph(rDoc
, *this, aParaTexts
[nCurPara
], xMapper
, xStylePool
, rAttrMap
, itPara
, itSecEnd
);
3379 void ScXMLExport::WriteMultiLineFormulaResult(const ScFormulaCell
* pCell
)
3381 OUString aElemName
= GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
3383 OUString aResStr
= pCell
->GetResultString().getString();
3384 const sal_Unicode
* p
= aResStr
.getStr();
3385 const sal_Unicode
* pEnd
= p
+ static_cast<size_t>(aResStr
.getLength());
3386 const sal_Unicode
* pPara
= p
; // paragraph head.
3387 for (; p
!= pEnd
; ++p
)
3392 // flush the paragraph.
3397 aContent
= OUString(pPara
, p
-pPara
);
3399 SvXMLElementExport
aElem(*this, aElemName
, false, false);
3400 Characters(aContent
);
3409 aContent
= OUString(pPara
, pEnd
-pPara
);
3411 SvXMLElementExport
aElem(*this, aElemName
, false, false);
3412 Characters(aContent
);
3415 void ScXMLExport::ExportShape(ScDocument
& rDoc
, const uno::Reference
< drawing::XShape
>& xShape
, awt::Point
* pPoint
)
3417 uno::Reference
< beans::XPropertySet
> xShapeProps ( xShape
, uno::UNO_QUERY
);
3418 bool bIsChart( false );
3419 if (xShapeProps
.is())
3421 sal_Int32 nZOrder
= 0;
3422 if (xShapeProps
->getPropertyValue(u
"ZOrder"_ustr
) >>= nZOrder
)
3424 AddAttribute(XML_NAMESPACE_DRAW
, XML_ZINDEX
, OUString::number(nZOrder
));
3426 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
= xShapeProps
->getPropertySetInfo();
3427 OUString
sPropCLSID (u
"CLSID"_ustr
);
3428 if( xPropSetInfo
->hasPropertyByName( sPropCLSID
) )
3431 if (xShapeProps
->getPropertyValue( sPropCLSID
) >>= sCLSID
)
3433 if ( sCLSID
.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) )
3437 OUString aChartName
;
3438 xShapeProps
->getPropertyValue( u
"PersistName"_ustr
) >>= aChartName
;
3439 ScChartListenerCollection
* pCollection
= rDoc
.GetChartListenerCollection();
3442 ScChartListener
* pListener
= pCollection
->findByName(aChartName
);
3445 const ScRangeListRef xRangeList
= pListener
->GetRangeList();
3446 if ( xRangeList
.is() )
3448 ScRangeStringConverter::GetStringFromRangeList( sRanges
, xRangeList
.get(), &rDoc
, FormulaGrammar::CONV_OOO
);
3449 if ( !sRanges
.isEmpty() )
3452 rtl::Reference
<comphelper::AttributeList
> pAttrList
= new comphelper::AttributeList();
3453 pAttrList
->AddAttribute(
3454 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW
, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES
) ), sRanges
);
3455 GetShapeExport()->exportShape( xShape
, SEF_DEFAULT
, pPoint
, pAttrList
.get() );
3461 if ( sRanges
.isEmpty() )
3463 uno::Reference
< frame::XModel
> xChartModel
;
3464 if( ( xShapeProps
->getPropertyValue( u
"Model"_ustr
) >>= xChartModel
) &&
3467 uno::Reference
< chart2::XChartDocument
> xChartDoc( xChartModel
, uno::UNO_QUERY
);
3468 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartModel
, uno::UNO_QUERY
);
3469 if( xChartDoc
.is() && xReceiver
.is() &&
3470 ! xChartDoc
->hasInternalDataProvider())
3472 // we have a chart that gets its data from Calc
3474 uno::Sequence
< OUString
> aRepresentations(
3475 xReceiver
->getUsedRangeRepresentations());
3476 rtl::Reference
<comphelper::AttributeList
> pAttrList
;
3479 if (aRepresentations
.hasElements())
3481 // add the ranges used by the chart to the shape
3482 // element to be able to start listening after
3483 // load (when the chart is not yet loaded)
3484 uno::Reference
< chart2::data::XRangeXMLConversion
> xRangeConverter( xChartDoc
->getDataProvider(), uno::UNO_QUERY
);
3485 sRanges
= lcl_RangeSequenceToString( aRepresentations
, xRangeConverter
);
3486 pAttrList
= new comphelper::AttributeList();
3487 pAttrList
->AddAttribute(
3488 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW
, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES
) ), sRanges
);
3491 catch (const lang::IllegalArgumentException
&)
3493 TOOLS_WARN_EXCEPTION("sc", "Exception in lcl_RangeSequenceToString - invalid range?");
3495 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
, pPoint
, pAttrList
.get());
3504 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
, pPoint
);
3506 IncrementProgressBar(false);
3509 void ScXMLExport::WriteShapes(ScDocument
& rDoc
, const ScMyCell
& rMyCell
)
3511 if( !(rMyCell
.bHasShape
&& !rMyCell
.aShapeList
.empty()) )
3514 // Reference point to turn absolute coordinates in reference point + offset. That happens in most
3515 // cases in XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint, which gets the absolute
3516 // coordinates as translation from matrix in property "Transformation". For cell anchored shapes
3517 // the reference point is left-top (in LTR mode) of that cell, which contains the shape.
3518 tools::Rectangle aCellRectFull
= rDoc
.GetMMRect(
3519 rMyCell
.maCellAddress
.Col(), rMyCell
.maCellAddress
.Row(), rMyCell
.maCellAddress
.Col(),
3520 rMyCell
.maCellAddress
.Row(), rMyCell
.maCellAddress
.Tab(), false /*bHiddenAsZero*/);
3522 bool bNegativePage
= rDoc
.IsNegativePage(rMyCell
.maCellAddress
.Tab());
3524 aPoint
.X
= aCellRectFull
.Right();
3526 aPoint
.X
= aCellRectFull
.Left();
3527 aPoint
.Y
= aCellRectFull
.Top();
3529 for (const auto& rShape
: rMyCell
.aShapeList
)
3531 // Skip the shape if requirements are not met. The tests should not fail, but allow
3532 // shorter conditions in main part below.
3533 if (!rShape
.xShape
.is())
3535 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(rShape
.xShape
);
3538 ScDrawObjData
* pObjData
= ScDrawLayer::GetObjData(pObj
);
3541 ScAddress aSnapStartAddress
= pObjData
->maStart
;
3542 if (!aSnapStartAddress
.IsValid())
3545 // The current object geometry is based on bHiddenAsZero=true, but ODF file format
3546 // needs it as if there were no hidden rows or columns. We determine a fictive snap
3547 // rectangle from the anchor as if all column/rows are shown. Then we move and resize
3548 // (in case of "resize with cell") the object to meet this snap rectangle. We need to
3549 // manipulate the object itself, because the used methods in xmloff do not evaluate the
3550 // ObjData. We remember the transformations and restore them later.
3551 Point
aMoveBy(0, 0);
3552 bool bNeedsRestorePosition
= false;
3553 Fraction
aScaleWidth(1, 1);
3554 Fraction
aScaleHeight(1, 1);
3555 bool bNeedsRestoreSize
= false;
3557 // Determine top point of fictive snap rectangle ('Full' rectangle).
3558 SCTAB
aTab(aSnapStartAddress
.Tab());
3559 SCCOL
aCol(aSnapStartAddress
.Col());
3560 SCROW
aRow(aSnapStartAddress
.Row());
3561 tools::Rectangle aFullStartCellRect
3562 = rDoc
.GetMMRect(aCol
, aRow
, aCol
, aRow
, aTab
, false /*bHiddenAsZero*/);
3563 // The reference corner for the offset is top-left in case of LTR and top-right for RTL.
3564 Point aFullTopPoint
;
3566 aFullTopPoint
.setX(aFullStartCellRect
.Right() - pObjData
->maStartOffset
.X());
3568 aFullTopPoint
.setX(aFullStartCellRect
.Left() + pObjData
->maStartOffset
.X());
3569 aFullTopPoint
.setY(aFullStartCellRect
.Top() + pObjData
->maStartOffset
.Y());
3571 // Compare actual top point and full top point and move object accordingly.
3572 tools::Rectangle
aOrigSnapRect(pObj
->GetSnapRect());
3573 Point aActualTopPoint
= bNegativePage
? aOrigSnapRect
.TopRight() : aOrigSnapRect
.TopLeft();
3574 if (aFullTopPoint
!= aActualTopPoint
)
3576 bNeedsRestorePosition
= true;
3577 aMoveBy
= aFullTopPoint
- aActualTopPoint
;
3578 pObj
->NbcMove(Size(aMoveBy
.X(), aMoveBy
.Y()));
3581 ScAddress aSnapEndAddress
= pObjData
->maEnd
;
3582 // tdf#154005: We treat the combination of "To cell (resize with cell)" with 'size protected'
3583 // as being "To cell".
3584 if (pObjData
->mbResizeWithCell
&& aSnapEndAddress
.IsValid() && !pObj
->IsResizeProtect())
3586 // Object is anchored "To cell (resize with cell)". Compare size of actual snap rectangle
3587 // and fictive full one. Resize object accordingly.
3588 tools::Rectangle
aActualSnapRect(pObj
->GetSnapRect());
3590 Point
aSnapEndOffset(pObjData
->maEndOffset
);
3591 aCol
= aSnapEndAddress
.Col();
3592 aRow
= aSnapEndAddress
.Row();
3593 tools::Rectangle aFullEndCellRect
3594 = rDoc
.GetMMRect(aCol
, aRow
, aCol
, aRow
, aTab
, false /*bHiddenAsZero*/);
3595 Point aFullBottomPoint
;
3597 aFullBottomPoint
.setX(aFullEndCellRect
.Right() - aSnapEndOffset
.X());
3599 aFullBottomPoint
.setX(aFullEndCellRect
.Left() + aSnapEndOffset
.X());
3600 aFullBottomPoint
.setY(aFullEndCellRect
.Top() + aSnapEndOffset
.Y());
3601 tools::Rectangle
aFullSnapRect(aFullTopPoint
, aFullBottomPoint
);
3602 aFullSnapRect
.Normalize();
3604 if (aFullSnapRect
!= aActualSnapRect
)
3606 bNeedsRestoreSize
= true;
3608 = Fraction(aFullSnapRect
.getOpenWidth(), aActualSnapRect
.getOpenWidth());
3609 if (!aScaleWidth
.IsValid())
3610 aScaleWidth
= Fraction(1, 1);
3612 = Fraction(aFullSnapRect
.getOpenHeight(), aActualSnapRect
.getOpenHeight());
3613 if (!aScaleHeight
.IsValid())
3614 aScaleHeight
= Fraction(1, 1);
3615 pObj
->NbcResize(aFullTopPoint
, aScaleWidth
, aScaleHeight
);
3619 // The existence of an end address is equivalent to anchor mode "To Cell (resize with cell)".
3620 // XML needs end address in regard of untransformed shape. Those are contained in rShape but
3621 // could be received from NonRotatedObjData as well.
3622 // tdf#154005: We treat the combination of "To Cell (resize with cell)" anchor with 'size
3623 // protected' property as being "To cell" anchor.
3624 if (pObjData
->mbResizeWithCell
&& !pObj
->IsResizeProtect())
3626 OUString sEndAddress
;
3627 ScRangeStringConverter::GetStringFromAddress(sEndAddress
, rShape
.aEndAddress
, &rDoc
,
3628 FormulaGrammar::CONV_OOO
);
3629 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_CELL_ADDRESS
, sEndAddress
);
3630 OUStringBuffer sBuffer
;
3631 GetMM100UnitConverter().convertMeasureToXML(sBuffer
, rShape
.nEndX
);
3632 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_X
, sBuffer
.makeStringAndClear());
3633 GetMM100UnitConverter().convertMeasureToXML(sBuffer
, rShape
.nEndY
);
3634 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_Y
, sBuffer
.makeStringAndClear());
3637 // Correct above calculated reference point for these cases:
3638 // a) For a RTL-sheet translate from matrix is not suitable, because the shape
3639 // from xml (which is always LTR) is not mirrored to negative page but shifted.
3640 // b) In case of horizontal mirrored, 'resize with cell' anchored custom shape, translate from
3641 // matrix has wrong values. FixMe: Why is translate wrong?
3643 || (pObj
->GetObjIdentifier() == SdrObjKind::CustomShape
3644 && static_cast<SdrObjCustomShape
*>(pObj
)->IsMirroredX()
3645 && pObjData
->mbResizeWithCell
))
3647 // In these cases we set reference point so that the offset calculation in XML export
3648 // (= matrix translate - reference point) results in maStartOffset.
3649 ScDrawObjData
* pNRObjData
= ScDrawLayer::GetNonRotatedObjData(pObj
);
3652 awt::Point aMatrixTranslate
= rShape
.xShape
->getPosition();
3653 aPoint
.X
= aMatrixTranslate
.X
- pNRObjData
->maStartOffset
.X();
3654 aPoint
.Y
= aMatrixTranslate
.Y
- pNRObjData
->maStartOffset
.Y();
3658 ExportShape(rDoc
, rShape
.xShape
, &aPoint
);
3660 if (bNeedsRestoreSize
)
3662 Fraction
aScaleWidthInvers(aScaleWidth
.GetDenominator(), aScaleWidth
.GetNumerator());
3663 if (!aScaleWidthInvers
.IsValid())
3664 aScaleWidthInvers
= Fraction(1, 1);
3665 Fraction
aScaleHeightInvers(aScaleHeight
.GetDenominator(), aScaleHeight
.GetNumerator());
3666 if (!aScaleHeightInvers
.IsValid())
3667 aScaleHeightInvers
= Fraction(1, 1);
3668 pObj
->NbcResize(aFullTopPoint
, aScaleWidthInvers
, aScaleHeightInvers
);
3670 if (bNeedsRestorePosition
)
3672 pObj
->NbcMove(Size(-aMoveBy
.X(), -aMoveBy
.Y()));
3677 void ScXMLExport::WriteTableShapes(ScDocument
& rDoc
)
3679 ScMyTableShapes
* pTableShapes(pSharedData
->GetTableShapes());
3680 if (!pTableShapes
|| (*pTableShapes
)[nCurrentTable
].empty())
3683 OSL_ENSURE(pTableShapes
->size() > static_cast<size_t>(nCurrentTable
), "wrong Table");
3684 SvXMLElementExport
aShapesElem(*this, XML_NAMESPACE_TABLE
, XML_SHAPES
, true, false);
3685 for (const auto& rxShape
: (*pTableShapes
)[nCurrentTable
])
3689 if (rDoc
.IsNegativePage(static_cast<SCTAB
>(nCurrentTable
)))
3691 // RTL-mirroring refers to snap rectangle, not to logic rectangle, therefore cannot use
3692 // getPosition() and getSize(), but need property "FrameRect" from rxShape or
3693 // GetSnapRect() from associated SdrObject.
3694 uno::Reference
<beans::XPropertySet
> xShapeProp(rxShape
, uno::UNO_QUERY
);
3695 awt::Rectangle aFrameRect
;
3696 if (!xShapeProp
.is())
3698 SAL_WARN("sc", "no shape propertyset");
3701 uno::Reference
<beans::XPropertySetInfo
> xPropSetInfo
= xShapeProp
->getPropertySetInfo();
3702 if (!xPropSetInfo
->hasPropertyByName(u
"FrameRect"_ustr
))
3704 SAL_WARN("sc", "shape doesn't support FrameRect property");
3707 if (xShapeProp
->getPropertyValue(u
"FrameRect"_ustr
) >>= aFrameRect
)
3709 // file format uses shape in LTR mode. newLeft = - oldRight = - (oldLeft + width).
3710 // newTranslate = oldTranslate - refPoint, oldTranslate from transformation matrix,
3711 // calculated in XMLShapeExport::exportShape common for all modules.
3712 // oldTranslate.X = oldLeft ==> refPoint.X = 2 * oldLeft + width
3713 awt::Point aRefPoint
;
3714 aRefPoint
.X
= 2 * aFrameRect
.X
+ aFrameRect
.Width
- 1;
3716 ExportShape(rDoc
, rxShape
, &aRefPoint
);
3718 // else should not happen
3721 ExportShape(rDoc
, rxShape
, nullptr);
3724 (*pTableShapes
)[nCurrentTable
].clear();
3727 void ScXMLExport::WriteAreaLink( const ScMyCell
& rMyCell
)
3729 if( !rMyCell
.bHasAreaLink
)
3732 const ScMyAreaLink
& rAreaLink
= rMyCell
.aAreaLink
;
3733 AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, rAreaLink
.sSourceStr
);
3734 AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3735 AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(rAreaLink
.sURL
) );
3736 AddAttribute( XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, rAreaLink
.sFilter
);
3737 if( !rAreaLink
.sFilterOptions
.isEmpty() )
3738 AddAttribute( XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, rAreaLink
.sFilterOptions
);
3739 AddAttribute( XML_NAMESPACE_TABLE
, XML_LAST_COLUMN_SPANNED
, OUString::number(rAreaLink
.GetColCount()) );
3740 AddAttribute( XML_NAMESPACE_TABLE
, XML_LAST_ROW_SPANNED
, OUString::number(rAreaLink
.GetRowCount()) );
3741 if( rAreaLink
.nRefreshDelaySeconds
)
3743 OUStringBuffer sValue
;
3744 ::sax::Converter::convertDuration( sValue
,
3745 static_cast<double>(rAreaLink
.nRefreshDelaySeconds
) / 86400 );
3746 AddAttribute( XML_NAMESPACE_TABLE
, XML_REFRESH_DELAY
, sValue
.makeStringAndClear() );
3748 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_CELL_RANGE_SOURCE
, true, true );
3751 void ScXMLExport::exportAnnotationMeta( const uno::Reference
< drawing::XShape
>& xShape
)
3753 ScPostIt
* pNote
= pCurrentCell
->pNote
;
3759 //is it still useful, as this call back is only called from ScXMLExport::WriteAnnotation
3760 // and should be in sync with pCurrentCell
3761 SdrCaptionObj
* pNoteCaption
= pNote
->GetOrCreateCaption(pCurrentCell
->maCellAddress
);
3762 uno::Reference
<drawing::XShape
> xCurrentShape( pNoteCaption
->getUnoShape(), uno::UNO_QUERY
);
3763 if (xCurrentShape
.get()!=xShape
.get())
3766 bool bRemovePersonalInfo
= SvtSecurityOptions::IsOptionSet(
3767 SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo
) && !SvtSecurityOptions::IsOptionSet(
3768 SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo
);
3770 const OUString
& sAuthor(pNote
->GetAuthor());
3771 if (!sAuthor
.isEmpty())
3773 SvXMLElementExport
aCreatorElem( *this, XML_NAMESPACE_DC
,
3776 Characters( bRemovePersonalInfo
3777 ? "Author" + OUString::number(SvXMLExport::GetInfoID(sAuthor
))
3781 const OUString
aDate(bRemovePersonalInfo
? u
"1970-01-01"_ustr
: pNote
->GetDate()); // Epoch time
3782 if (ScDocument
* pDoc
= GetDocument())
3784 SvNumberFormatter
* pNumForm
= pDoc
->GetFormatTable();
3786 sal_uInt32 nfIndex
= pNumForm
->GetFormatIndex(NF_DATE_SYS_DDMMYYYY
, LANGUAGE_SYSTEM
);
3787 if (pNumForm
->IsNumberFormat(aDate
, nfIndex
, fDate
))
3789 OUStringBuffer sBuf
;
3790 GetMM100UnitConverter().convertDateTime(sBuf
, fDate
,true);
3791 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_DC
,
3794 Characters(sBuf
.makeStringAndClear());
3798 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_META
,
3799 XML_DATE_STRING
, true,
3806 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_META
,
3807 XML_DATE_STRING
, true,
3813 void ScXMLExport::WriteAnnotation(ScDocument
& rDoc
, const ScMyCell
& rMyCell
)
3815 ScPostIt
* pNote
= rDoc
.GetNote(rMyCell
.maCellAddress
);
3819 if (pNote
->IsCaptionShown())
3820 AddAttribute(XML_NAMESPACE_OFFICE
, XML_DISPLAY
, XML_TRUE
);
3822 pCurrentCell
= &rMyCell
;
3824 SdrCaptionObj
* pNoteCaption
= pNote
->GetOrCreateCaption(rMyCell
.maCellAddress
);
3827 uno::Reference
<drawing::XShape
> xShape( pNoteCaption
->getUnoShape(), uno::UNO_QUERY
);
3829 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
|XMLShapeExportFlags::ANNOTATION
);
3832 pCurrentCell
= nullptr;
3835 void ScXMLExport::WriteDetective(ScDocument
& rDoc
, const ScMyCell
& rMyCell
)
3837 if( !(rMyCell
.bHasDetectiveObj
|| rMyCell
.bHasDetectiveOp
) )
3840 const ScMyDetectiveObjVec
& rObjVec
= rMyCell
.aDetectiveObjVec
;
3841 const ScMyDetectiveOpVec
& rOpVec
= rMyCell
.aDetectiveOpVec
;
3842 sal_Int32
nObjCount(rObjVec
.size());
3843 sal_Int32
nOpCount(rOpVec
.size());
3844 if( !(nObjCount
|| nOpCount
) )
3847 SvXMLElementExport
aDetElem( *this, XML_NAMESPACE_TABLE
, XML_DETECTIVE
, true, true );
3849 for(const auto& rObj
: rObjVec
)
3851 if (rObj
.eObjType
!= SC_DETOBJ_CIRCLE
)
3853 if( (rObj
.eObjType
== SC_DETOBJ_ARROW
) || (rObj
.eObjType
== SC_DETOBJ_TOOTHERTAB
))
3855 ScRangeStringConverter::GetStringFromRange( sString
, rObj
.aSourceRange
, &rDoc
, FormulaGrammar::CONV_OOO
);
3856 AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, sString
);
3858 sString
= ScXMLConverter::GetStringFromDetObjType( rObj
.eObjType
);
3859 AddAttribute( XML_NAMESPACE_TABLE
, XML_DIRECTION
, sString
);
3860 if( rObj
.bHasError
)
3861 AddAttribute( XML_NAMESPACE_TABLE
, XML_CONTAINS_ERROR
, XML_TRUE
);
3864 AddAttribute( XML_NAMESPACE_TABLE
, XML_MARKED_INVALID
, XML_TRUE
);
3865 SvXMLElementExport
aRangeElem( *this, XML_NAMESPACE_TABLE
, XML_HIGHLIGHTED_RANGE
, true, true );
3867 for(const auto& rOp
: rOpVec
)
3869 OUString sOpString
= ScXMLConverter::GetStringFromDetOpType( rOp
.eOpType
);
3870 AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, sOpString
);
3871 AddAttribute( XML_NAMESPACE_TABLE
, XML_INDEX
, OUString::number(rOp
.nIndex
) );
3872 SvXMLElementExport
aRangeElem( *this, XML_NAMESPACE_TABLE
, XML_OPERATION
, true, true );
3876 void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount
, bool bIncProgress
)
3878 // nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1
3879 if (nEqualCellCount
> 0)
3881 sal_Int32
nTemp(nEqualCellCount
+ 1);
3882 OUString
sOUEqualCellCount(OUString::number(nTemp
));
3883 AddAttribute(sAttrColumnsRepeated
, sOUEqualCellCount
);
3885 IncrementProgressBar(false, nEqualCellCount
);
3890 bool ScXMLExport::IsEditCell(const ScMyCell
& rCell
)
3892 return rCell
.maBaseCell
.getType() == CELLTYPE_EDIT
;
3896 bool ScXMLExport::IsCellEqual(ScDocument
& rDoc
, const ScMyCell
& aCell1
, const ScMyCell
& aCell2
)
3898 bool bIsEqual
= false;
3899 if( !aCell1
.bIsMergedBase
&& !aCell2
.bIsMergedBase
&&
3900 aCell1
.bIsCovered
== aCell2
.bIsCovered
&&
3901 !aCell1
.bIsMatrixBase
&& !aCell2
.bIsMatrixBase
&&
3902 aCell1
.bIsMatrixCovered
== aCell2
.bIsMatrixCovered
&&
3903 aCell1
.bHasAnnotation
== aCell2
.bHasAnnotation
&&
3904 !aCell1
.bHasShape
&& !aCell2
.bHasShape
&&
3905 aCell1
.bHasAreaLink
== aCell2
.bHasAreaLink
&&
3906 !aCell1
.bHasDetectiveObj
&& !aCell2
.bHasDetectiveObj
)
3908 if( (aCell1
.bHasAreaLink
&&
3909 (aCell1
.aAreaLink
.GetColCount() == 1) &&
3910 (aCell2
.aAreaLink
.GetColCount() == 1) &&
3911 aCell1
.aAreaLink
.Compare( aCell2
.aAreaLink
) ) ||
3912 !aCell1
.bHasAreaLink
)
3914 if (!aCell1
.bHasAnnotation
)
3916 if ((((aCell1
.nStyleIndex
== aCell2
.nStyleIndex
) && (aCell1
.bIsAutoStyle
== aCell2
.bIsAutoStyle
)) ||
3917 ((aCell1
.nStyleIndex
== aCell2
.nStyleIndex
) && (aCell1
.nStyleIndex
== -1))) &&
3918 aCell1
.nValidationIndex
== aCell2
.nValidationIndex
&&
3919 aCell1
.nType
== aCell2
.nType
)
3921 switch ( aCell1
.nType
)
3923 case table::CellContentType_EMPTY
:
3928 case table::CellContentType_VALUE
:
3930 // #i29101# number format may be different from column default styles,
3931 // but can lead to different value types, so it must also be compared
3932 bIsEqual
= (aCell1
.nNumberFormat
== aCell2
.nNumberFormat
) &&
3933 (aCell1
.maBaseCell
.getDouble() == aCell2
.maBaseCell
.getDouble());
3936 case table::CellContentType_TEXT
:
3938 if (IsEditCell(aCell1
) || IsEditCell(aCell2
))
3942 bIsEqual
= (aCell1
.maBaseCell
.getString(&rDoc
) == aCell2
.maBaseCell
.getString(&rDoc
));
3946 case table::CellContentType_FORMULA
:
3964 void ScXMLExport::WriteCalculationSettings(ScDocument
& rDoc
, const uno::Reference
<sheet::XSpreadsheetDocument
>& xSpreadDoc
)
3966 uno::Reference
<beans::XPropertySet
> xPropertySet(xSpreadDoc
, uno::UNO_QUERY
);
3967 if (!xPropertySet
.is())
3970 bool bCalcAsShown (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_CALCASSHOWN
) ));
3971 bool bIgnoreCase (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_IGNORECASE
) ));
3972 bool bLookUpLabels (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_LOOKUPLABELS
) ));
3973 bool bMatchWholeCell (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_MATCHWHOLE
) ));
3974 bool bUseRegularExpressions (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_REGEXENABLED
) ));
3975 bool bUseWildcards (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_WILDCARDSENABLED
) ));
3976 if (bUseWildcards
&& bUseRegularExpressions
)
3977 bUseRegularExpressions
= false; // mutually exclusive, wildcards take precedence
3978 bool bIsIterationEnabled (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_ITERENABLED
) ));
3979 sal_uInt16
nYear2000 (rDoc
.GetDocOptions().GetYear2000());
3980 sal_Int32
nIterationCount(100);
3981 xPropertySet
->getPropertyValue( SC_UNO_ITERCOUNT
) >>= nIterationCount
;
3982 double fIterationEpsilon
= 0;
3983 xPropertySet
->getPropertyValue( SC_UNO_ITEREPSILON
) >>= fIterationEpsilon
;
3984 util::Date aNullDate
;
3985 xPropertySet
->getPropertyValue( SC_UNO_NULLDATE
) >>= aNullDate
;
3986 if (!(bCalcAsShown
|| bIgnoreCase
|| !bLookUpLabels
|| !bMatchWholeCell
|| !bUseRegularExpressions
||
3988 bIsIterationEnabled
|| nIterationCount
!= 100 || !::rtl::math::approxEqual(fIterationEpsilon
, 0.001) ||
3989 aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899 || nYear2000
!= 1930))
3993 AddAttribute(XML_NAMESPACE_TABLE
, XML_CASE_SENSITIVE
, XML_FALSE
);
3995 AddAttribute(XML_NAMESPACE_TABLE
, XML_PRECISION_AS_SHOWN
, XML_TRUE
);
3996 if (!bMatchWholeCell
)
3997 AddAttribute(XML_NAMESPACE_TABLE
, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL
, XML_FALSE
);
3999 AddAttribute(XML_NAMESPACE_TABLE
, XML_AUTOMATIC_FIND_LABELS
, XML_FALSE
);
4000 if (!bUseRegularExpressions
)
4001 AddAttribute(XML_NAMESPACE_TABLE
, XML_USE_REGULAR_EXPRESSIONS
, XML_FALSE
);
4003 AddAttribute(XML_NAMESPACE_TABLE
, XML_USE_WILDCARDS
, XML_TRUE
);
4004 if (nYear2000
!= 1930)
4006 AddAttribute(XML_NAMESPACE_TABLE
, XML_NULL_YEAR
, OUString::number(nYear2000
));
4008 SvXMLElementExport
aCalcSettings(*this, XML_NAMESPACE_TABLE
, XML_CALCULATION_SETTINGS
, true, true);
4010 if (aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899)
4012 OUStringBuffer sDate
;
4013 SvXMLUnitConverter::convertDateTime(sDate
, 0.0, aNullDate
);
4014 AddAttribute(XML_NAMESPACE_TABLE
, XML_DATE_VALUE
, sDate
.makeStringAndClear());
4015 SvXMLElementExport
aElemNullDate(*this, XML_NAMESPACE_TABLE
, XML_NULL_DATE
, true, true);
4017 if (bIsIterationEnabled
|| nIterationCount
!= 100 || !::rtl::math::approxEqual(fIterationEpsilon
, 0.001))
4019 if (bIsIterationEnabled
)
4020 AddAttribute(XML_NAMESPACE_TABLE
, XML_STATUS
, XML_ENABLE
);
4021 if (nIterationCount
!= 100)
4023 AddAttribute(XML_NAMESPACE_TABLE
, XML_STEPS
, OUString::number(nIterationCount
));
4025 if (!::rtl::math::approxEqual(fIterationEpsilon
, 0.001))
4027 OUStringBuffer sBuffer
;
4028 ::sax::Converter::convertDouble(sBuffer
,
4030 AddAttribute(XML_NAMESPACE_TABLE
, XML_MAXIMUM_DIFFERENCE
, sBuffer
.makeStringAndClear());
4032 SvXMLElementExport
aElemIteration(*this, XML_NAMESPACE_TABLE
, XML_ITERATION
, true, true);
4037 void ScXMLExport::WriteTableSource()
4039 uno::Reference
<sheet::XSheetLinkable
> xLinkable (xCurrentTable
, uno::UNO_QUERY
);
4040 if (!(xLinkable
.is() && GetModel().is()))
4043 sheet::SheetLinkMode
nMode (xLinkable
->getLinkMode());
4044 if (nMode
== sheet::SheetLinkMode_NONE
)
4047 OUString
sLink (xLinkable
->getLinkUrl());
4048 uno::Reference
<beans::XPropertySet
> xProps (GetModel(), uno::UNO_QUERY
);
4052 uno::Reference
<container::XIndexAccess
> xIndex(xProps
->getPropertyValue(SC_UNO_SHEETLINKS
), uno::UNO_QUERY
);
4056 sal_Int32
nCount(xIndex
->getCount());
4061 uno::Reference
<beans::XPropertySet
> xLinkProps
;
4062 for (sal_Int32 i
= 0; (i
< nCount
) && !bFound
; ++i
)
4064 xLinkProps
.set(xIndex
->getByIndex(i
), uno::UNO_QUERY
);
4065 if (xLinkProps
.is())
4068 if (xLinkProps
->getPropertyValue(SC_UNONAME_LINKURL
) >>= sNewLink
)
4069 bFound
= sLink
== sNewLink
;
4072 if (!(bFound
&& xLinkProps
.is()))
4076 OUString sFilterOptions
;
4077 OUString
sTableName (xLinkable
->getLinkSheetName());
4078 sal_Int32
nRefresh(0);
4079 xLinkProps
->getPropertyValue(SC_UNONAME_FILTER
) >>= sFilter
;
4080 xLinkProps
->getPropertyValue(SC_UNONAME_FILTOPT
) >>= sFilterOptions
;
4081 xLinkProps
->getPropertyValue(SC_UNONAME_REFDELAY
) >>= nRefresh
;
4082 if (sLink
.isEmpty())
4085 AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
4086 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(sLink
));
4087 if (!sTableName
.isEmpty())
4088 AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_NAME
, sTableName
);
4089 if (!sFilter
.isEmpty())
4090 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, sFilter
);
4091 if (!sFilterOptions
.isEmpty())
4092 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, sFilterOptions
);
4093 if (nMode
!= sheet::SheetLinkMode_NORMAL
)
4094 AddAttribute(XML_NAMESPACE_TABLE
, XML_MODE
, XML_COPY_RESULTS_ONLY
);
4097 OUStringBuffer sBuffer
;
4098 ::sax::Converter::convertDuration( sBuffer
,
4099 static_cast<double>(nRefresh
) / 86400 );
4100 AddAttribute( XML_NAMESPACE_TABLE
, XML_REFRESH_DELAY
, sBuffer
.makeStringAndClear() );
4102 SvXMLElementExport
aSourceElem(*this, XML_NAMESPACE_TABLE
, XML_TABLE_SOURCE
, true, true);
4105 // core implementation
4106 void ScXMLExport::WriteScenario(ScDocument
& rDoc
)
4108 if (!rDoc
.IsScenario(static_cast<SCTAB
>(nCurrentTable
)))
4113 ScScenarioFlags nFlags
;
4114 rDoc
.GetScenarioData(static_cast<SCTAB
>(nCurrentTable
), sComment
, aColor
, nFlags
);
4115 if (!(nFlags
& ScScenarioFlags::ShowFrame
))
4116 AddAttribute(XML_NAMESPACE_TABLE
, XML_DISPLAY_BORDER
, XML_FALSE
);
4117 OUStringBuffer aBuffer
;
4118 ::sax::Converter::convertColor(aBuffer
, aColor
);
4119 AddAttribute(XML_NAMESPACE_TABLE
, XML_BORDER_COLOR
, aBuffer
.makeStringAndClear());
4120 if (!(nFlags
& ScScenarioFlags::TwoWay
))
4121 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_BACK
, XML_FALSE
);
4122 if (!(nFlags
& ScScenarioFlags::Attrib
))
4123 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_STYLES
, XML_FALSE
);
4124 if (nFlags
& ScScenarioFlags::Value
)
4125 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_FORMULAS
, XML_FALSE
);
4126 if (nFlags
& ScScenarioFlags::Protected
)
4127 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
4128 ::sax::Converter::convertBool(aBuffer
,
4129 rDoc
.IsActiveScenario(static_cast<SCTAB
>(nCurrentTable
)));
4130 AddAttribute(XML_NAMESPACE_TABLE
, XML_IS_ACTIVE
, aBuffer
.makeStringAndClear());
4131 const ScRangeList
* pRangeList
= rDoc
.GetScenarioRanges(static_cast<SCTAB
>(nCurrentTable
));
4132 OUString sRangeListStr
;
4133 ScRangeStringConverter::GetStringFromRangeList( sRangeListStr
, pRangeList
, &rDoc
, FormulaGrammar::CONV_OOO
);
4134 AddAttribute(XML_NAMESPACE_TABLE
, XML_SCENARIO_RANGES
, sRangeListStr
);
4135 if (!sComment
.isEmpty())
4136 AddAttribute(XML_NAMESPACE_TABLE
, XML_COMMENT
, sComment
);
4137 SvXMLElementExport
aElem(*this, XML_NAMESPACE_TABLE
, XML_SCENARIO
, true, true);
4140 void ScXMLExport::WriteTheLabelRanges(ScDocument
& rDoc
, const uno::Reference
< sheet::XSpreadsheetDocument
>& xSpreadDoc
)
4142 uno::Reference
< beans::XPropertySet
> xDocProp( xSpreadDoc
, uno::UNO_QUERY
);
4143 if( !xDocProp
.is() ) return;
4145 sal_Int32
nCount(0);
4146 uno::Reference
< container::XIndexAccess
> xColRangesIAccess(xDocProp
->getPropertyValue( SC_UNO_COLLABELRNG
), uno::UNO_QUERY
);
4147 if( xColRangesIAccess
.is() )
4148 nCount
+= xColRangesIAccess
->getCount();
4150 uno::Reference
< container::XIndexAccess
> xRowRangesIAccess(xDocProp
->getPropertyValue( SC_UNO_ROWLABELRNG
), uno::UNO_QUERY
);
4151 if( xRowRangesIAccess
.is() )
4152 nCount
+= xRowRangesIAccess
->getCount();
4156 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_LABEL_RANGES
, true, true );
4157 WriteLabelRanges(rDoc
, xColRangesIAccess
, true);
4158 WriteLabelRanges(rDoc
, xRowRangesIAccess
, false);
4162 void ScXMLExport::WriteLabelRanges(ScDocument
& rDoc
, const uno::Reference
< container::XIndexAccess
>& xRangesIAccess
, bool bColumn
)
4164 if( !xRangesIAccess
.is() ) return;
4166 sal_Int32
nCount(xRangesIAccess
->getCount());
4167 for( sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
4169 uno::Reference
< sheet::XLabelRange
> xRange(xRangesIAccess
->getByIndex( nIndex
), uno::UNO_QUERY
);
4173 table::CellRangeAddress
aCellRange( xRange
->getLabelArea() );
4174 ScRangeStringConverter::GetStringFromRange( sRangeStr
, aCellRange
, &rDoc
, FormulaGrammar::CONV_OOO
);
4175 AddAttribute( XML_NAMESPACE_TABLE
, XML_LABEL_CELL_RANGE_ADDRESS
, sRangeStr
);
4176 aCellRange
= xRange
->getDataArea();
4177 ScRangeStringConverter::GetStringFromRange( sRangeStr
, aCellRange
, &rDoc
, FormulaGrammar::CONV_OOO
);
4178 AddAttribute( XML_NAMESPACE_TABLE
, XML_DATA_CELL_RANGE_ADDRESS
, sRangeStr
);
4179 AddAttribute( XML_NAMESPACE_TABLE
, XML_ORIENTATION
, bColumn
? XML_COLUMN
: XML_ROW
);
4180 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_LABEL_RANGE
, true, true );
4185 void ScXMLExport::WriteNamedExpressions(ScDocument
& rDoc
)
4187 ScRangeName
* pNamedRanges
= rDoc
.GetRangeName();
4188 WriteNamedRange(rDoc
, pNamedRanges
);
4191 void ScXMLExport::WriteExternalDataMapping(ScDocument
& rDoc
)
4193 if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
4194 // Export this only for 1.2 extended and above.
4197 sc::ExternalDataMapper
& rDataMapper
= rDoc
.GetExternalDataMapper();
4198 auto& rDataSources
= rDataMapper
.getDataSources();
4200 if (rDataSources
.empty())
4203 SvXMLElementExport
aMappings(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_MAPPINGS
, true, true);
4204 for (const auto& itr
: rDataSources
)
4206 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, itr
.getURL());
4207 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_PROVIDER
, itr
.getProvider());
4208 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_DATA_FREQUENCY
, OUString::number(sc::ExternalDataSource::getUpdateFrequency()));
4209 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_ID
, itr
.getID());
4210 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_DATABASE_NAME
, itr
.getDBName());
4212 SvXMLElementExport
aMapping(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_MAPPING
, true, true);
4213 // Add the data transformations
4214 WriteExternalDataTransformations(rDoc
, itr
.getDataTransformation());
4218 void ScXMLExport::WriteExternalDataTransformations(ScDocument
& rDoc
, const std::vector
<std::shared_ptr
<sc::DataTransformation
>>& aDataTransformations
)
4220 SvXMLElementExport
aTransformations(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_TRANSFORMATIONS
, true, true);
4221 for (auto& itr
: aDataTransformations
)
4223 sc::TransformationType aTransformationType
= itr
->getTransformationType();
4225 switch(aTransformationType
)
4227 case sc::TransformationType::DELETE_TRANSFORMATION
:
4229 // Delete Columns Transformation
4230 std::shared_ptr
<sc::ColumnRemoveTransformation
> aDeleteTransformation
= std::dynamic_pointer_cast
<sc::ColumnRemoveTransformation
>(itr
);
4231 std::set
<SCCOL
> aColumns
= aDeleteTransformation
->getColumns();
4232 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_REMOVE_TRANSFORMATION
, true, true);
4233 for(auto& col
: aColumns
)
4236 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4237 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4241 case sc::TransformationType::SPLIT_TRANSFORMATION
:
4243 std::shared_ptr
<sc::SplitColumnTransformation
> aSplitTransformation
= std::dynamic_pointer_cast
<sc::SplitColumnTransformation
>(itr
);
4245 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(aSplitTransformation
->getColumn()));
4246 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SEPARATOR
, OUString::number(aSplitTransformation
->getSeparator()));
4247 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_SPLIT_TRANSFORMATION
, true, true);
4250 case sc::TransformationType::MERGE_TRANSFORMATION
:
4252 // Merge Transformation
4253 std::shared_ptr
<sc::MergeColumnTransformation
> aMergeTransformation
= std::dynamic_pointer_cast
<sc::MergeColumnTransformation
>(itr
);
4254 std::set
<SCCOL
> aColumns
= aMergeTransformation
->getColumns();
4256 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MERGE_STRING
, aMergeTransformation
->getMergeString());
4257 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_MERGE_TRANSFORMATION
, true, true);
4259 for(auto& col
: aColumns
)
4262 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4263 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4267 case sc::TransformationType::SORT_TRANSFORMATION
:
4269 // Sort Transformation
4270 std::shared_ptr
<sc::SortTransformation
> aSortTransformation
= std::dynamic_pointer_cast
<sc::SortTransformation
>(itr
);
4271 ScSortParam aSortParam
= aSortTransformation
->getSortParam();
4272 const sc::DocumentLinkManager
& rMgr
= rDoc
.GetDocLinkManager();
4273 const sc::DataStream
* pStrm
= rMgr
.getDataStream();
4279 ScRange aRange
= pStrm
->GetRange();
4281 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_SORT_TRANSFORMATION
, true, true);
4283 writeSort(*this, aSortParam
, aRange
, rDoc
);
4286 case sc::TransformationType::TEXT_TRANSFORMATION
:
4288 // Text Transformation
4289 std::shared_ptr
<sc::TextTransformation
> aTextTransformation
= std::dynamic_pointer_cast
<sc::TextTransformation
>(itr
);
4291 sc::TEXT_TRANSFORM_TYPE aTextTransformType
= aTextTransformation
->getTextTransformationType();
4293 switch ( aTextTransformType
)
4295 case sc::TEXT_TRANSFORM_TYPE::TO_LOWER
:
4296 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_LOWERCASE
);
4298 case sc::TEXT_TRANSFORM_TYPE::TO_UPPER
:
4299 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_UPPERCASE
);
4301 case sc::TEXT_TRANSFORM_TYPE::CAPITALIZE
:
4302 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_CAPITALIZE
);
4304 case sc::TEXT_TRANSFORM_TYPE::TRIM
:
4305 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_TRIM
);
4309 std::set
<SCCOL
> aColumns
= aTextTransformation
->getColumns();
4311 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_TEXT_TRANSFORMATION
, true, true);
4313 for(auto& col
: aColumns
)
4316 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4317 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4321 case sc::TransformationType::AGGREGATE_FUNCTION
:
4323 // Aggregate Transformation
4324 std::shared_ptr
<sc::AggregateFunction
> aAggregateFunction
= std::dynamic_pointer_cast
<sc::AggregateFunction
>(itr
);
4325 std::set
<SCCOL
> aColumns
= aAggregateFunction
->getColumns();
4327 sc::AGGREGATE_FUNCTION aAggregateType
= aAggregateFunction
->getAggregateType();
4329 switch (aAggregateType
)
4331 case sc::AGGREGATE_FUNCTION::SUM
:
4332 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SUM
);
4334 case sc::AGGREGATE_FUNCTION::AVERAGE
:
4335 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_AVERAGE
);
4337 case sc::AGGREGATE_FUNCTION::MIN
:
4338 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MIN
);
4340 case sc::AGGREGATE_FUNCTION::MAX
:
4341 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MAX
);
4345 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
,XML_COLUMN_AGGREGATE_TRANSFORMATION
, true, true);
4347 for(auto& col
: aColumns
)
4350 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4351 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4355 case sc::TransformationType::NUMBER_TRANSFORMATION
:
4357 // Number Transformation
4358 std::shared_ptr
<sc::NumberTransformation
> aNumberTransformation
= std::dynamic_pointer_cast
<sc::NumberTransformation
>(itr
);
4360 sc::NUMBER_TRANSFORM_TYPE aNumberTransformType
= aNumberTransformation
->getNumberTransformationType();
4362 switch ( aNumberTransformType
)
4364 case sc::NUMBER_TRANSFORM_TYPE::ROUND
:
4365 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND
);
4367 case sc::NUMBER_TRANSFORM_TYPE::ROUND_UP
:
4368 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND_UP
);
4370 case sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN
:
4371 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND_DOWN
);
4373 case sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE
:
4374 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ABS
);
4376 case sc::NUMBER_TRANSFORM_TYPE::LOG_E
:
4377 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_LOG
);
4379 case sc::NUMBER_TRANSFORM_TYPE::LOG_10
:
4380 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_LOG_10
);
4382 case sc::NUMBER_TRANSFORM_TYPE::CUBE
:
4383 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CUBE
);
4385 case sc::NUMBER_TRANSFORM_TYPE::SQUARE
:
4386 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SQUARE
);
4388 case sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT
:
4389 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SQUARE_ROOT
);
4391 case sc::NUMBER_TRANSFORM_TYPE::EXPONENT
:
4392 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_EXPONENTIAL
);
4394 case sc::NUMBER_TRANSFORM_TYPE::IS_EVEN
:
4395 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_EVEN
);
4397 case sc::NUMBER_TRANSFORM_TYPE::IS_ODD
:
4398 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ODD
);
4400 case sc::NUMBER_TRANSFORM_TYPE::SIGN
:
4401 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SIGN
);
4405 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_PRECISION
, OUString::number(aNumberTransformation
->getPrecision()));
4406 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_NUMBER_TRANSFORMATION
, true, true);
4408 std::set
<SCCOL
> aColumns
= aNumberTransformation
->getColumn();
4409 for(auto& col
: aColumns
)
4412 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4413 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4417 case sc::TransformationType::REMOVE_NULL_TRANSFORMATION
:
4419 // Replace Null Transformation
4420 std::shared_ptr
<sc::ReplaceNullTransformation
> aReplaceNullTransformation
= std::dynamic_pointer_cast
<sc::ReplaceNullTransformation
>(itr
);
4421 std::set
<SCCOL
> aColumns
= aReplaceNullTransformation
->getColumn();
4423 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_REPLACE_STRING
, aReplaceNullTransformation
->getReplaceString());
4424 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_REPLACENULL_TRANSFORMATION
, true, true);
4426 for(auto& col
: aColumns
)
4429 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4430 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4434 case sc::TransformationType::DATETIME_TRANSFORMATION
:
4436 // Number Transformation
4437 std::shared_ptr
<sc::DateTimeTransformation
> aDateTimeTransformation
= std::dynamic_pointer_cast
<sc::DateTimeTransformation
>(itr
);
4439 sc::DATETIME_TRANSFORMATION_TYPE aDateTimeTransformationType
= aDateTimeTransformation
->getDateTimeTransformationType();
4441 switch ( aDateTimeTransformationType
)
4443 case sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING
:
4444 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DATE_STRING
);
4446 case sc::DATETIME_TRANSFORMATION_TYPE::YEAR
:
4447 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_YEAR
);
4449 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR
:
4450 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_YEAR
);
4452 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR
:
4453 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_YEAR
);
4455 case sc::DATETIME_TRANSFORMATION_TYPE::MONTH
:
4456 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MONTH
);
4458 case sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME
:
4459 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MONTH_NAME
);
4461 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH
:
4462 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_MONTH
);
4464 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH
:
4465 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_MONTH
);
4467 case sc::DATETIME_TRANSFORMATION_TYPE::DAY
:
4468 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY
);
4470 case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK
:
4471 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY_OF_WEEK
);
4473 case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR
:
4474 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY_OF_YEAR
);
4476 case sc::DATETIME_TRANSFORMATION_TYPE::QUARTER
:
4477 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_QUARTER
);
4479 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER
:
4480 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_QUARTER
);
4482 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER
:
4483 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_QUARTER
);
4485 case sc::DATETIME_TRANSFORMATION_TYPE::TIME
:
4486 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_TIME
);
4488 case sc::DATETIME_TRANSFORMATION_TYPE::HOUR
:
4489 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_HOUR
);
4491 case sc::DATETIME_TRANSFORMATION_TYPE::MINUTE
:
4492 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MINUTE
);
4494 case sc::DATETIME_TRANSFORMATION_TYPE::SECOND
:
4495 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SECONDS
);
4499 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_DATETIME_TRANSFORMATION
, true, true);
4501 std::set
<SCCOL
> aColumns
= aDateTimeTransformation
->getColumn();
4502 for(auto& col
: aColumns
)
4505 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4506 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4516 void ScXMLExport::WriteDataStream(ScDocument
& rDoc
)
4518 if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
4519 // Export this only in experimental mode.
4522 if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
4523 // Export this only for 1.2 extended and above.
4526 const sc::DocumentLinkManager
& rMgr
= rDoc
.GetDocLinkManager();
4527 const sc::DataStream
* pStrm
= rMgr
.getDataStream();
4533 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(pStrm
->GetURL()));
4536 ScRange aRange
= pStrm
->GetRange();
4538 ScRangeStringConverter::GetStringFromRange(
4539 aRangeStr
, aRange
, &rDoc
, formula::FormulaGrammar::CONV_OOO
);
4540 AddAttribute(XML_NAMESPACE_TABLE
, XML_TARGET_RANGE_ADDRESS
, aRangeStr
);
4542 // Empty line refresh option.
4543 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_EMPTY_LINE_REFRESH
, pStrm
->IsRefreshOnEmptyLine() ? XML_TRUE
: XML_FALSE
);
4545 // New data insertion position. Either top of bottom. Default to bottom.
4546 xmloff::token::XMLTokenEnum eInsertPosition
= XML_BOTTOM
;
4547 if (pStrm
->GetMove() == sc::DataStream::MOVE_DOWN
)
4548 eInsertPosition
= XML_TOP
;
4550 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_INSERTION_POSITION
, eInsertPosition
);
4552 SvXMLElementExport
aElem(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_STREAM_SOURCE
, true, true);
4555 void ScXMLExport::WriteNamedRange(ScDocument
& rDoc
, ScRangeName
* pRangeName
)
4557 //write a global or local ScRangeName
4558 SvXMLElementExport
aElemNEs(*this, XML_NAMESPACE_TABLE
, XML_NAMED_EXPRESSIONS
, true, true);
4559 for (const auto& rxEntry
: *pRangeName
)
4561 AddAttribute(sAttrName
, rxEntry
.second
->GetName());
4563 OUString sBaseCellAddress
;
4564 rxEntry
.second
->ValidateTabRefs();
4565 ScRangeStringConverter::GetStringFromAddress( sBaseCellAddress
, rxEntry
.second
->GetPos(), &rDoc
,
4566 FormulaGrammar::CONV_OOO
, ' ', false, ScRefFlags::ADDR_ABS_3D
);
4567 assert(!sBaseCellAddress
.isEmpty());
4568 AddAttribute(XML_NAMESPACE_TABLE
, XML_BASE_CELL_ADDRESS
, sBaseCellAddress
);
4570 OUString
sTempSymbol(rxEntry
.second
->GetSymbol(rDoc
.GetStorageGrammar()));
4572 if (rxEntry
.second
->IsReference(aRange
))
4575 OUString
sContent(sTempSymbol
.copy(1, sTempSymbol
.getLength() -2 ));
4576 AddAttribute(XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, sContent
);
4578 sal_Int32 nRangeType
= rxEntry
.second
->GetUnoType();
4579 OUStringBuffer sBufferRangeType
;
4580 if ((nRangeType
& sheet::NamedRangeFlag::COLUMN_HEADER
) == sheet::NamedRangeFlag::COLUMN_HEADER
)
4581 sBufferRangeType
.append(GetXMLToken(XML_REPEAT_COLUMN
));
4582 if ((nRangeType
& sheet::NamedRangeFlag::ROW_HEADER
) == sheet::NamedRangeFlag::ROW_HEADER
)
4584 if (!sBufferRangeType
.isEmpty())
4585 sBufferRangeType
.append(" ");
4586 sBufferRangeType
.append(GetXMLToken(XML_REPEAT_ROW
));
4588 if ((nRangeType
& sheet::NamedRangeFlag::FILTER_CRITERIA
) == sheet::NamedRangeFlag::FILTER_CRITERIA
)
4590 if (!sBufferRangeType
.isEmpty())
4591 sBufferRangeType
.append(" ");
4592 sBufferRangeType
.append(GetXMLToken(XML_FILTER
));
4594 if ((nRangeType
& sheet::NamedRangeFlag::PRINT_AREA
) == sheet::NamedRangeFlag::PRINT_AREA
)
4596 if (!sBufferRangeType
.isEmpty())
4597 sBufferRangeType
.append(" ");
4598 sBufferRangeType
.append(GetXMLToken(XML_PRINT_RANGE
));
4600 if ((nRangeType
& sheet::NamedRangeFlag::HIDDEN
) == sheet::NamedRangeFlag::HIDDEN
)
4602 if (!sBufferRangeType
.isEmpty())
4603 sBufferRangeType
.append(" ");
4604 sBufferRangeType
.append(GetXMLToken(XML_HIDDEN
));
4606 OUString sRangeType
= sBufferRangeType
.makeStringAndClear();
4607 if (!sRangeType
.isEmpty())
4608 AddAttribute(XML_NAMESPACE_TABLE
, XML_RANGE_USABLE_AS
, sRangeType
);
4609 SvXMLElementExport
aElemNR(*this, XML_NAMESPACE_TABLE
, XML_NAMED_RANGE
, true, true);
4614 AddAttribute(XML_NAMESPACE_TABLE
, XML_EXPRESSION
, sTempSymbol
);
4615 // Check if it is a hidden named expression
4616 sal_Int32 nRangeType
= rxEntry
.second
->GetUnoType();
4617 if ((nRangeType
& sheet::NamedRangeFlag::HIDDEN
) == sheet::NamedRangeFlag::HIDDEN
)
4618 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_HIDDEN
, XML_TRUE
);
4619 SvXMLElementExport
aElemNE(*this, XML_NAMESPACE_TABLE
, XML_NAMED_EXPRESSION
, true, true);
4624 void ScXMLExport::exportSparklineGroups(ScDocument
& rDoc
, SCTAB nTable
)
4626 sc::SparklineGroupsExport
aSparklineGroupExport(rDoc
, *this, nTable
);
4627 aSparklineGroupExport
.write();
4632 OUString
getCondFormatEntryType(const ScColorScaleEntry
& rEntry
, bool bFirst
= true)
4634 switch(rEntry
.GetType())
4636 case COLORSCALE_MIN
:
4637 return u
"minimum"_ustr
;
4638 case COLORSCALE_MAX
:
4639 return u
"maximum"_ustr
;
4640 case COLORSCALE_PERCENT
:
4641 return u
"percent"_ustr
;
4642 case COLORSCALE_PERCENTILE
:
4643 return u
"percentile"_ustr
;
4644 case COLORSCALE_FORMULA
:
4645 return u
"formula"_ustr
;
4646 case COLORSCALE_VALUE
:
4647 return u
"number"_ustr
;
4648 case COLORSCALE_AUTO
:
4649 // only important for data bars
4651 return u
"auto-minimum"_ustr
;
4653 return u
"auto-maximum"_ustr
;
4658 OUString
getDateStringForType(condformat::ScCondFormatDateType eType
)
4662 case condformat::TODAY
:
4663 return u
"today"_ustr
;
4664 case condformat::YESTERDAY
:
4665 return u
"yesterday"_ustr
;
4666 case condformat::TOMORROW
:
4667 return u
"tomorrow"_ustr
;
4668 case condformat::LAST7DAYS
:
4669 return u
"last-7-days"_ustr
;
4670 case condformat::THISWEEK
:
4671 return u
"this-week"_ustr
;
4672 case condformat::LASTWEEK
:
4673 return u
"last-week"_ustr
;
4674 case condformat::NEXTWEEK
:
4675 return u
"next-week"_ustr
;
4676 case condformat::THISMONTH
:
4677 return u
"this-month"_ustr
;
4678 case condformat::LASTMONTH
:
4679 return u
"last-month"_ustr
;
4680 case condformat::NEXTMONTH
:
4681 return u
"next-month"_ustr
;
4682 case condformat::THISYEAR
:
4683 return u
"this-year"_ustr
;
4684 case condformat::LASTYEAR
:
4685 return u
"last-year"_ustr
;
4686 case condformat::NEXTYEAR
:
4687 return u
"next-year"_ustr
;
4695 void ScXMLExport::ExportConditionalFormat(ScDocument
& rDoc
, SCTAB nTab
)
4697 ScConditionalFormatList
* pCondFormatList
= rDoc
.GetCondFormList(nTab
);
4698 if(!pCondFormatList
)
4701 if (pCondFormatList
->empty())
4704 SvXMLElementExport
aElementCondFormats(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITIONAL_FORMATS
, true, true);
4706 for(const auto& rxCondFormat
: *pCondFormatList
)
4709 const ScRangeList
& rRangeList
= rxCondFormat
->GetRange();
4710 ScRangeStringConverter::GetStringFromRangeList( sRanges
, &rRangeList
, &rDoc
, formula::FormulaGrammar::CONV_OOO
);
4711 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TARGET_RANGE_ADDRESS
, sRanges
);
4712 SvXMLElementExport
aElementCondFormat(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITIONAL_FORMAT
, true, true);
4713 size_t nEntries
= rxCondFormat
->size();
4714 for(size_t i
= 0; i
< nEntries
; ++i
)
4716 const ScFormatEntry
* pFormatEntry
= rxCondFormat
->GetEntry(i
);
4717 if(pFormatEntry
->GetType()==ScFormatEntry::Type::Condition
)
4719 const ScCondFormatEntry
* pEntry
= static_cast<const ScCondFormatEntry
*>(pFormatEntry
);
4720 OUStringBuffer aCond
;
4721 ScAddress aPos
= pEntry
->GetSrcPos();
4722 switch(pEntry
->GetOperation())
4724 case ScConditionMode::Equal
:
4725 aCond
.append("=" + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4727 case ScConditionMode::Less
:
4728 aCond
.append("<" + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4730 case ScConditionMode::Greater
:
4731 aCond
.append(">" + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4733 case ScConditionMode::EqLess
:
4734 aCond
.append("<=" + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4736 case ScConditionMode::EqGreater
:
4737 aCond
.append(">=" + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4739 case ScConditionMode::NotEqual
:
4740 aCond
.append("!=" + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4742 case ScConditionMode::Between
:
4743 aCond
.append("between("
4744 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4746 + pEntry
->GetExpression(aPos
, 1, 0, formula::FormulaGrammar::GRAM_ODFF
)
4749 case ScConditionMode::NotBetween
:
4750 aCond
.append("not-between("
4751 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4753 + pEntry
->GetExpression(aPos
, 1, 0, formula::FormulaGrammar::GRAM_ODFF
)
4756 case ScConditionMode::Duplicate
:
4757 aCond
.append("duplicate");
4759 case ScConditionMode::NotDuplicate
:
4760 aCond
.append("unique");
4762 case ScConditionMode::Direct
:
4763 aCond
.append("formula-is("
4764 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4767 case ScConditionMode::Top10
:
4768 aCond
.append("top-elements("
4769 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4772 case ScConditionMode::Bottom10
:
4773 aCond
.append("bottom-elements("
4774 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4777 case ScConditionMode::TopPercent
:
4778 aCond
.append("top-percent("
4779 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4782 case ScConditionMode::BottomPercent
:
4783 aCond
.append("bottom-percent("
4784 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4787 case ScConditionMode::AboveAverage
:
4788 aCond
.append("above-average");
4790 case ScConditionMode::BelowAverage
:
4791 aCond
.append("below-average");
4793 case ScConditionMode::AboveEqualAverage
:
4794 aCond
.append("above-equal-average");
4796 case ScConditionMode::BelowEqualAverage
:
4797 aCond
.append("below-equal-average");
4799 case ScConditionMode::Error
:
4800 aCond
.append("is-error");
4802 case ScConditionMode::NoError
:
4803 aCond
.append("is-no-error");
4805 case ScConditionMode::BeginsWith
:
4806 aCond
.append("begins-with("
4807 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4810 case ScConditionMode::EndsWith
:
4811 aCond
.append("ends-with("
4812 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4815 case ScConditionMode::ContainsText
:
4816 aCond
.append("contains-text("
4817 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4820 case ScConditionMode::NotContainsText
:
4821 aCond
.append("not-contains-text("
4822 + pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
)
4825 case ScConditionMode::NONE
:
4828 SAL_WARN("sc", "unimplemented conditional format export");
4830 OUString sStyle
= ScStyleNameConversion::DisplayToProgrammaticName(pEntry
->GetStyle(), SfxStyleFamily::Para
);
4831 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_APPLY_STYLE_NAME
, sStyle
);
4832 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, aCond
.makeStringAndClear());
4834 OUString sBaseAddress
;
4835 ScRangeStringConverter::GetStringFromAddress( sBaseAddress
, aPos
, &rDoc
, formula::FormulaGrammar::CONV_ODF
);
4836 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_BASE_CELL_ADDRESS
, sBaseAddress
);
4837 SvXMLElementExport
aElementCondEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITION
, true, true);
4839 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Colorscale
)
4841 SvXMLElementExport
aElementColorScale(*this, XML_NAMESPACE_CALC_EXT
, XML_COLOR_SCALE
, true, true);
4842 const ScColorScaleFormat
& rColorScale
= static_cast<const ScColorScaleFormat
&>(*pFormatEntry
);
4843 for(const auto& rxItem
: rColorScale
)
4845 if(rxItem
->GetType() == COLORSCALE_FORMULA
)
4847 OUString sFormula
= rxItem
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4848 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4851 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(rxItem
->GetValue()));
4853 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*rxItem
));
4854 OUStringBuffer aBuffer
;
4855 ::sax::Converter::convertColor(aBuffer
, rxItem
->GetColor());
4856 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLOR
, aBuffer
.makeStringAndClear());
4857 SvXMLElementExport
aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_COLOR_SCALE_ENTRY
, true, true);
4860 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Databar
)
4862 const ScDataBarFormatData
* pFormatData
= static_cast<const ScDataBarFormat
&>(*pFormatEntry
).GetDataBarData();
4863 if(!pFormatData
->mbGradient
)
4864 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_GRADIENT
, XML_FALSE
);
4865 if(pFormatData
->mbOnlyBar
)
4866 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SHOW_VALUE
, XML_FALSE
);
4868 if (pFormatData
->mnMinLength
!= 0.0)
4869 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MIN_LENGTH
, OUString::number(pFormatData
->mnMinLength
));
4871 if (pFormatData
->mnMaxLength
!= 0.0)
4872 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MAX_LENGTH
, OUString::number(pFormatData
->mnMaxLength
));
4874 if(pFormatData
->mbNeg
)
4876 if(pFormatData
->mxNegativeColor
)
4878 OUStringBuffer aBuffer
;
4879 ::sax::Converter::convertColor(aBuffer
, *pFormatData
->mxNegativeColor
);
4880 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_NEGATIVE_COLOR
, aBuffer
.makeStringAndClear());
4884 OUStringBuffer aBuffer
;
4885 ::sax::Converter::convertColor(aBuffer
, COL_LIGHTRED
);
4886 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_NEGATIVE_COLOR
, aBuffer
.makeStringAndClear());
4890 if(pFormatData
->meAxisPosition
!= databar::AUTOMATIC
)
4892 if(pFormatData
->meAxisPosition
== databar::NONE
)
4894 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_POSITION
, u
"none"_ustr
);
4898 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_POSITION
, u
"middle"_ustr
);
4902 OUStringBuffer aBuffer
;
4903 ::sax::Converter::convertColor(aBuffer
, pFormatData
->maPositiveColor
);
4904 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_POSITIVE_COLOR
, aBuffer
.makeStringAndClear());
4907 ::sax::Converter::convertColor(aBuffer
, pFormatData
->maAxisColor
);
4908 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_COLOR
, aBuffer
.makeStringAndClear());
4909 SvXMLElementExport
aElementDataBar(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_BAR
, true, true);
4912 if(pFormatData
->mpLowerLimit
->GetType() == COLORSCALE_FORMULA
)
4914 OUString sFormula
= pFormatData
->mpLowerLimit
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4915 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4918 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(pFormatData
->mpLowerLimit
->GetValue()));
4919 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*pFormatData
->mpLowerLimit
));
4920 SvXMLElementExport
aElementDataBarEntryLower(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4924 if(pFormatData
->mpUpperLimit
->GetType() == COLORSCALE_FORMULA
)
4926 OUString sFormula
= pFormatData
->mpUpperLimit
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4927 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4930 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(pFormatData
->mpUpperLimit
->GetValue()));
4931 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*pFormatData
->mpUpperLimit
, false));
4932 SvXMLElementExport
aElementDataBarEntryUpper(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4935 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Iconset
)
4937 const ScIconSetFormat
& rIconSet
= static_cast<const ScIconSetFormat
&>(*pFormatEntry
);
4938 OUString aIconSetName
= ScIconSetFormat::getIconSetName(rIconSet
.GetIconSetData()->eIconSetType
);
4939 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_ICON_SET_TYPE
, aIconSetName
);
4940 if (rIconSet
.GetIconSetData()->mbCustom
)
4941 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM
, OUString::boolean(true));
4943 SvXMLElementExport
aElementColorScale(*this, XML_NAMESPACE_CALC_EXT
, XML_ICON_SET
, true, true);
4945 if (rIconSet
.GetIconSetData()->mbCustom
)
4947 for (const auto& [rType
, rIndex
] : rIconSet
.GetIconSetData()->maCustomVector
)
4949 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET_NAME
, ScIconSetFormat::getIconSetName(rType
));
4950 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET_INDEX
, OUString::number(rIndex
));
4951 SvXMLElementExport
aCustomIcon(*this, XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET
, true, true);
4956 if(!rIconSet
.GetIconSetData()->mbShowValue
)
4957 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SHOW_VALUE
, XML_FALSE
);
4958 for (auto const& it
: rIconSet
)
4960 if(it
->GetType() == COLORSCALE_FORMULA
)
4962 OUString sFormula
= it
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4963 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4966 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(it
->GetValue()));
4968 if (!it
->GetGreaterThanOrEqual())
4969 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_GREATER_EQUAL
, OUString::boolean(false));
4971 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*it
));
4972 SvXMLElementExport
aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4975 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Date
)
4977 const ScCondDateFormatEntry
& rDateFormat
= static_cast<const ScCondDateFormatEntry
&>(*pFormatEntry
);
4978 OUString aDateType
= getDateStringForType(rDateFormat
.GetDateType());
4979 OUString aStyleName
= ScStyleNameConversion::DisplayToProgrammaticName(rDateFormat
.GetStyleName(), SfxStyleFamily::Para
);
4980 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_STYLE
, aStyleName
);
4981 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_DATE
, aDateType
);
4982 SvXMLElementExport
aElementDateFormat(*this, XML_NAMESPACE_CALC_EXT
, XML_DATE_IS
, true, true);
4988 void ScXMLExport::WriteExternalRefCaches(ScDocument
& rDoc
)
4990 ScExternalRefManager
* pRefMgr
= rDoc
.GetExternalRefManager();
4991 pRefMgr
->resetSrcFileData(GetOrigFileName());
4992 sal_uInt16 nCount
= pRefMgr
->getExternalFileCount();
4993 for (sal_uInt16 nFileId
= 0; nFileId
< nCount
; ++nFileId
)
4995 const OUString
* pUrl
= pRefMgr
->getExternalFileName(nFileId
);
4999 vector
<OUString
> aTabNames
;
5000 pRefMgr
->getAllCachedTableNames(nFileId
, aTabNames
);
5001 if (aTabNames
.empty())
5004 for (const auto& rTabName
: aTabNames
)
5006 ScExternalRefCache::TableTypeRef pTable
= pRefMgr
->getCacheTable(nFileId
, rTabName
, false);
5007 if (!pTable
|| !pTable
->isReferenced())
5010 AddAttribute(XML_NAMESPACE_TABLE
, XML_NAME
, "'" + *pUrl
+ "'#" + rTabName
);
5011 AddAttribute(XML_NAMESPACE_TABLE
, XML_PRINT
, GetXMLToken(XML_FALSE
));
5012 AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, sExternalRefTabStyleName
);
5013 SvXMLElementExport
aElemTable(*this, XML_NAMESPACE_TABLE
, XML_TABLE
, true, true);
5015 const ScExternalRefManager::SrcFileData
* pExtFileData
= pRefMgr
->getExternalFileData(nFileId
);
5019 if (!pExtFileData
->maRelativeName
.isEmpty())
5020 aRelUrl
= pExtFileData
->maRelativeName
;
5022 aRelUrl
= GetRelativeReference(pExtFileData
->maRelativeName
);
5023 AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
5024 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, aRelUrl
);
5025 AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_NAME
, rTabName
);
5026 if (!pExtFileData
->maFilterName
.isEmpty())
5027 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, pExtFileData
->maFilterName
);
5028 if (!pExtFileData
->maFilterOptions
.isEmpty())
5029 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, pExtFileData
->maFilterOptions
);
5030 AddAttribute(XML_NAMESPACE_TABLE
, XML_MODE
, XML_COPY_RESULTS_ONLY
);
5032 SvXMLElementExport
aElemTableSource(*this, XML_NAMESPACE_TABLE
, XML_TABLE_SOURCE
, true, true);
5035 // Determine maximum column count of used area, for repeated cells.
5036 SCCOL nMaxColsUsed
= 1; // assume that there is at least one cell somewhere...
5037 vector
<SCROW
> aRows
;
5038 pTable
->getAllRows(aRows
);
5039 for (SCROW nRow
: aRows
)
5041 vector
<SCCOL
> aCols
;
5042 pTable
->getAllCols(nRow
, aCols
);
5045 SCCOL nCol
= aCols
.back();
5046 if (nMaxColsUsed
<= nCol
)
5047 nMaxColsUsed
= nCol
+ 1;
5051 // Column definitions have to be present to make a valid file
5053 if (nMaxColsUsed
> 1)
5054 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
5055 OUString::number(nMaxColsUsed
));
5056 SvXMLElementExport
aElemColumn(*this, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true);
5059 // Write cache content for this table.
5061 bool bFirstRow
= true;
5062 for (SCROW nRow
: aRows
)
5070 OUString aVal
= OUString::number(nRow
);
5071 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, aVal
);
5073 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5074 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nMaxColsUsed
));
5075 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5076 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5081 SCROW nRowGap
= nRow
- nLastRow
;
5086 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nRowGap
-1));
5087 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, aVal
);
5089 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5090 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nMaxColsUsed
));
5091 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5092 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5095 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5097 vector
<SCCOL
> aCols
;
5098 pTable
->getAllCols(nRow
, aCols
);
5100 bool bFirstCol
= true;
5101 for (SCCOL nCol
: aCols
)
5109 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nCol
));
5110 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5112 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5117 SCCOL nColGap
= nCol
- nLastCol
;
5122 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nColGap
-1));
5123 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5125 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5129 // Write out this cell.
5130 sal_uInt32 nNumFmt
= 0;
5131 ScExternalRefCache::TokenRef pToken
= pTable
->getCell(nCol
, nRow
, &nNumFmt
);
5135 sal_Int32 nIndex
= GetNumberFormatStyleIndex(nNumFmt
);
5138 const OUString
& aStyleName
= pCellStyles
->GetStyleNameByIndex(nIndex
, true);
5139 AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, aStyleName
);
5142 switch(pToken
->GetType())
5146 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
5147 aStrVal
= OUString::number(pToken
->GetDouble());
5148 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE
, aStrVal
);
5153 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
5154 aStrVal
= pToken
->GetString().getString();
5161 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5162 SvXMLElementExport
aElemText(*this, XML_NAMESPACE_TEXT
, XML_P
, true, false);
5163 Characters(aStrVal
);
5175 // core implementation
5176 void ScXMLExport::WriteConsolidation(ScDocument
& rDoc
)
5178 const ScConsolidateParam
* pCons(rDoc
.GetConsolidateDlgData());
5182 OUString sStrData
= ScXMLConverter::GetStringFromFunction( pCons
->eFunction
);
5183 AddAttribute( XML_NAMESPACE_TABLE
, XML_FUNCTION
, sStrData
);
5186 for( sal_Int32 nIndex
= 0; nIndex
< pCons
->nDataAreaCount
; ++nIndex
)
5187 ScRangeStringConverter::GetStringFromArea( sStrData
, pCons
->pDataAreas
[ nIndex
], &rDoc
, FormulaGrammar::CONV_OOO
, ' ', true );
5188 AddAttribute( XML_NAMESPACE_TABLE
, XML_SOURCE_CELL_RANGE_ADDRESSES
, sStrData
);
5190 ScRangeStringConverter::GetStringFromAddress( sStrData
, ScAddress( pCons
->nCol
, pCons
->nRow
, pCons
->nTab
), &rDoc
, FormulaGrammar::CONV_OOO
);
5191 AddAttribute( XML_NAMESPACE_TABLE
, XML_TARGET_CELL_ADDRESS
, sStrData
);
5193 if( pCons
->bByCol
&& !pCons
->bByRow
)
5194 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_COLUMN
);
5195 else if( !pCons
->bByCol
&& pCons
->bByRow
)
5196 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_ROW
);
5197 else if( pCons
->bByCol
&& pCons
->bByRow
)
5198 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_BOTH
);
5200 if( pCons
->bReferenceData
)
5201 AddAttribute( XML_NAMESPACE_TABLE
, XML_LINK_TO_SOURCE_DATA
, XML_TRUE
);
5203 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_CONSOLIDATION
, true, true );
5206 SvXMLAutoStylePoolP
* ScXMLExport::CreateAutoStylePool()
5208 return new ScXMLAutoStylePoolP(*this);
5211 XMLPageExport
* ScXMLExport::CreatePageExport()
5213 return new XMLTableMasterPageExport( *this );
5217 void ScXMLExport::GetChangeTrackViewSettings(ScDocument
& rDoc
, uno::Sequence
<beans::PropertyValue
>& rProps
)
5219 ScChangeViewSettings
* pViewSettings(rDoc
.GetChangeViewSettings());
5223 sal_Int32
nChangePos(rProps
.getLength());
5224 rProps
.realloc(nChangePos
+ 1);
5225 beans::PropertyValue
* pProps(rProps
.getArray());
5227 uno::Sequence
<beans::PropertyValue
> aChangeProps(SC_VIEWCHANGES_COUNT
);
5228 beans::PropertyValue
* pChangeProps(aChangeProps
.getArray());
5229 pChangeProps
[SC_SHOW_CHANGES
].Name
= "ShowChanges";
5230 pChangeProps
[SC_SHOW_CHANGES
].Value
<<= pViewSettings
->ShowChanges();
5231 pChangeProps
[SC_SHOW_ACCEPTED_CHANGES
].Name
= "ShowAcceptedChanges";
5232 pChangeProps
[SC_SHOW_ACCEPTED_CHANGES
].Value
<<= pViewSettings
->IsShowAccepted();
5233 pChangeProps
[SC_SHOW_REJECTED_CHANGES
].Name
= "ShowRejectedChanges";
5234 pChangeProps
[SC_SHOW_REJECTED_CHANGES
].Value
<<= pViewSettings
->IsShowRejected();
5235 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME
].Name
= "ShowChangesByDatetime";
5236 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME
].Value
<<= pViewSettings
->HasDate();
5237 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_MODE
].Name
= "ShowChangesByDatetimeMode";
5238 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_MODE
].Value
<<= static_cast<sal_Int16
>(pViewSettings
->GetTheDateMode());
5239 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME
].Name
= "ShowChangesByDatetimeFirstDatetime";
5240 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME
].Value
<<= pViewSettings
->GetTheFirstDateTime().GetUNODateTime();
5241 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME
].Name
= "ShowChangesByDatetimeSecondDatetime";
5242 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME
].Value
<<= pViewSettings
->GetTheLastDateTime().GetUNODateTime();
5243 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR
].Name
= "ShowChangesByAuthor";
5244 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR
].Value
<<= pViewSettings
->HasAuthor();
5245 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR_NAME
].Name
= "ShowChangesByAuthorName";
5246 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR_NAME
].Value
<<= pViewSettings
->GetTheAuthorToShow();
5247 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT
].Name
= "ShowChangesByComment";
5248 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT
].Value
<<= pViewSettings
->HasComment();
5249 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT_TEXT
].Name
= "ShowChangesByCommentText";
5250 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT_TEXT
].Value
<<= pViewSettings
->GetTheComment();
5251 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES
].Name
= "ShowChangesByRanges";
5252 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES
].Value
<<= pViewSettings
->HasRange();
5253 OUString sRangeList
;
5254 ScRangeStringConverter::GetStringFromRangeList(sRangeList
, &(pViewSettings
->GetTheRangeList()), &rDoc
, FormulaGrammar::CONV_OOO
);
5255 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES_LIST
].Name
= "ShowChangesByRangesList";
5256 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES_LIST
].Value
<<= sRangeList
;
5258 pProps
[nChangePos
].Name
= "TrackedChangesViewSettings";
5259 pProps
[nChangePos
].Value
<<= aChangeProps
;
5262 void ScXMLExport::GetViewSettings(uno::Sequence
<beans::PropertyValue
>& rProps
)
5264 if (!GetModel().is())
5267 ScModelObj
* pDocObj(comphelper::getFromUnoTunnel
<ScModelObj
>( GetModel() ));
5271 SfxObjectShell
* pEmbeddedObj
= pDocObj
->GetEmbeddedObject();
5275 beans::PropertyValue
* pProps(rProps
.getArray());
5277 tools::Rectangle
aRect(pEmbeddedObj
->GetVisArea());
5279 pProps
[i
].Name
= "VisibleAreaTop";
5280 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.Top());
5281 pProps
[++i
].Name
= "VisibleAreaLeft";
5282 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.Left());
5283 pProps
[++i
].Name
= "VisibleAreaWidth";
5284 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.getOpenWidth());
5285 pProps
[++i
].Name
= "VisibleAreaHeight";
5286 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.getOpenHeight());
5289 ScDocument
* pDoc
= pDocObj
->GetDocument();
5292 SAL_WARN("sc", "no ScDocument!");
5295 GetChangeTrackViewSettings(*pDoc
, rProps
);
5298 void ScXMLExport::GetConfigurationSettings(uno::Sequence
<beans::PropertyValue
>& rProps
)
5300 if (!GetModel().is())
5303 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
5304 if (!xMultiServiceFactory
.is())
5307 uno::Reference
<beans::XPropertySet
> xProperties(xMultiServiceFactory
->createInstance(u
"com.sun.star.comp.SpreadsheetSettings"_ustr
), uno::UNO_QUERY
);
5308 if (xProperties
.is())
5309 SvXMLUnitConverter::convertPropertySet(rProps
, xProperties
);
5311 ScDocument
* pDoc
= GetDocument();
5313 sal_Int32 nPropsToAdd
= 0;
5314 OUStringBuffer aTrackedChangesKey
;
5315 if (pDoc
&& pDoc
->GetChangeTrack() && pDoc
->GetChangeTrack()->IsProtected())
5317 ::comphelper::Base64::encode(aTrackedChangesKey
,
5318 pDoc
->GetChangeTrack()->GetProtection());
5319 if (!aTrackedChangesKey
.isEmpty())
5323 bool bVBACompat
= false;
5324 uno::Reference
<container::XNameAccess
> xCodeNameAccess
;
5325 OSL_ENSURE( pDoc
, "ScXMLExport::GetConfigurationSettings - no ScDocument!" );
5326 // tdf#71271 - add code names regardless of VBA compatibility mode
5329 // VBA compatibility mode
5330 if (bVBACompat
= pDoc
->IsInVBAMode(); bVBACompat
)
5334 xCodeNameAccess
= new XMLCodeNameProvider( pDoc
);
5335 if( xCodeNameAccess
->hasElements() )
5338 xCodeNameAccess
.clear();
5341 if( nPropsToAdd
<= 0 )
5344 sal_Int32
nCount(rProps
.getLength());
5345 rProps
.realloc(nCount
+ nPropsToAdd
);
5346 auto pProps
= rProps
.getArray();
5347 if (!aTrackedChangesKey
.isEmpty())
5349 pProps
[nCount
].Name
= "TrackedChangesProtectionKey";
5350 pProps
[nCount
].Value
<<= aTrackedChangesKey
.makeStringAndClear();
5355 pProps
[nCount
].Name
= "VBACompatibilityMode";
5356 pProps
[nCount
].Value
<<= bVBACompat
;
5359 if( xCodeNameAccess
.is() )
5361 pProps
[nCount
].Name
= "ScriptConfiguration";
5362 pProps
[nCount
].Value
<<= xCodeNameAccess
;
5367 XMLShapeExport
* ScXMLExport::CreateShapeExport()
5369 return new ScXMLShapeExport(*this);
5372 XMLNumberFormatAttributesExportHelper
* ScXMLExport::GetNumberFormatAttributesExportHelper()
5374 if (!pNumberFormatAttributesExportHelper
)
5375 pNumberFormatAttributesExportHelper
.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this ));
5376 return pNumberFormatAttributesExportHelper
.get();
5379 void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool
* pPool
, sal_uInt16 nAttrib
)
5381 ItemSurrogates aSurrogates
;
5382 pPool
->GetItemSurrogates(aSurrogates
, nAttrib
);
5383 for (const SfxPoolItem
* pItem
: aSurrogates
)
5385 const SvXMLAttrContainerItem
*pUnknown(static_cast<const SvXMLAttrContainerItem
*>(pItem
));
5386 if( pUnknown
->GetAttrCount() > 0 )
5388 sal_uInt16
nIdx(pUnknown
->GetFirstNamespaceIndex());
5389 while( USHRT_MAX
!= nIdx
)
5391 if( (XML_NAMESPACE_UNKNOWN_FLAG
& nIdx
) != 0 )
5393 const OUString
& rPrefix
= pUnknown
->GetPrefix( nIdx
);
5394 // Add namespace declaration for unknown attributes if
5395 // there aren't existing ones for the prefix used by the
5397 GetNamespaceMap_().Add( rPrefix
,
5398 pUnknown
->GetNamespace( nIdx
) );
5400 nIdx
= pUnknown
->GetNextNamespaceIndex( nIdx
);
5405 // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
5406 GetNamespaceMap_().Add(
5407 GetXMLToken( XML_NP_PRESENTATION
),
5408 GetXMLToken( XML_N_PRESENTATION
),
5409 XML_NAMESPACE_PRESENTATION
);
5412 void ScXMLExport::IncrementProgressBar(bool bFlush
, sal_Int32 nInc
)
5414 nProgressCount
+= nInc
;
5415 if (bFlush
|| nProgressCount
> 100)
5417 GetProgressBarHelper()->Increment(nProgressCount
);
5422 ErrCode
ScXMLExport::exportDoc( enum XMLTokenEnum eClass
)
5424 if( getExportFlags() & (SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::STYLES
|
5425 SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
) )
5427 uno::Reference
< frame::XModel
> xModel
= GetModel();
5428 if (ScDocument
* pDoc
= GetDocument())
5430 // if source doc was Excel then
5431 auto pFoundShell
= comphelper::getFromUnoTunnel
<SfxObjectShell
>(xModel
);
5432 if ( pFoundShell
&& ooo::vba::isAlienExcelDoc( *pFoundShell
) )
5434 xRowStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScFromXLSRowStylesProperties
, xScPropHdlFactory
, true);
5435 xRowStylesExportPropertySetMapper
= new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper
);
5436 GetAutoStylePool()->SetFamilyPropSetMapper( XmlStyleFamily::TABLE_ROW
,
5437 xRowStylesExportPropertySetMapper
);
5440 CollectUserDefinedNamespaces(pDoc
->GetPool(), ATTR_USERDEF
);
5441 CollectUserDefinedNamespaces(pDoc
->GetEditPool(), EE_PARA_XMLATTRIBS
);
5442 CollectUserDefinedNamespaces(pDoc
->GetEditPool(), EE_CHAR_XMLATTRIBS
);
5443 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
5446 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), EE_PARA_XMLATTRIBS
);
5447 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), EE_CHAR_XMLATTRIBS
);
5448 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), SDRATTR_XMLATTRIBUTES
);
5451 // sheet events use officeooo namespace
5452 if( (getExportFlags() & SvXMLExportFlags::CONTENT
) &&
5453 getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
5455 bool bAnySheetEvents
= false;
5456 SCTAB nTabCount
= pDoc
->GetTableCount();
5457 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
5458 if (pDoc
->GetSheetEvents(nTab
))
5459 bAnySheetEvents
= true;
5460 if (bAnySheetEvents
)
5461 GetNamespaceMap_().Add(
5462 GetXMLToken( XML_NP_OFFICE_EXT
),
5463 GetXMLToken( XML_N_OFFICE_EXT
),
5464 XML_NAMESPACE_OFFICE_EXT
);
5468 return SvXMLExport::exportDoc( eClass
);
5472 void SAL_CALL
ScXMLExport::setSourceDocument( const uno::Reference
<lang::XComponent
>& xComponent
)
5474 SolarMutexGuard aGuard
;
5475 SvXMLExport::setSourceDocument( xComponent
);
5477 ScDocument
* pDoc
= GetDocument();
5478 OSL_ENSURE( pDoc
, "ScXMLExport::setSourceDocument - no ScDocument!" );
5480 throw lang::IllegalArgumentException();
5482 // create ScChangeTrackingExportHelper after document is known
5483 pChangeTrackingExportHelper
.reset(new ScChangeTrackingExportHelper(*pDoc
, *this));
5485 // Set the document's storage grammar corresponding to the ODF version that
5486 // is to be written.
5487 SvtSaveOptions::ODFSaneDefaultVersion meODFDefaultVersion
= getSaneDefaultVersion();
5488 switch (meODFDefaultVersion
)
5490 // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF
5491 case SvtSaveOptions::ODFSVER_010
:
5492 case SvtSaveOptions::ODFSVER_011
:
5493 pDoc
->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF
);
5496 pDoc
->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF
);
5501 sal_Bool SAL_CALL
ScXMLExport::filter( const css::uno::Sequence
< css::beans::PropertyValue
>& aDescriptor
)
5503 SolarMutexGuard aGuard
;
5504 ScDocument
* pDoc
= GetDocument();
5506 pDoc
->EnableIdle(true);
5507 bool bReturn(SvXMLExport::filter(aDescriptor
));
5509 pDoc
->EnableIdle(true);
5513 void SAL_CALL
ScXMLExport::cancel()
5515 SolarMutexGuard aGuard
;
5516 if (ScDocument
* pDoc
= GetDocument())
5517 pDoc
->EnableIdle(true);
5518 SvXMLExport::cancel();
5522 void SAL_CALL
ScXMLExport::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
5524 SolarMutexGuard aGuard
;
5525 SvXMLExport::initialize(aArguments
);
5528 void ScXMLExport::DisposingModel()
5530 SvXMLExport::DisposingModel();
5531 xCurrentTable
= nullptr;
5534 void ScXMLExport::SetSharedData(std::unique_ptr
<ScMySharedData
> pTemp
) { pSharedData
= std::move(pTemp
); }
5536 std::unique_ptr
<ScMySharedData
> ScXMLExport::ReleaseSharedData() { return std::move(pSharedData
); }
5537 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */