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 "XMLExportIterator.hxx"
37 #include "XMLColumnRowGroupExport.hxx"
38 #include "XMLStylesExportHelper.hxx"
39 #include "XMLChangeTrackingExportHelper.hxx"
40 #include <sheetdata.hxx>
41 #include <docoptio.hxx>
42 #include "XMLExportSharedData.hxx"
43 #include <chgviset.hxx>
45 #include <textuno.hxx>
46 #include <chartlis.hxx>
47 #include <scitems.hxx>
48 #include <docpool.hxx>
49 #include <userdat.hxx>
50 #include <chgtrack.hxx>
51 #include <rangeutl.hxx>
53 #include <externalrefmgr.hxx>
54 #include <editutil.hxx>
55 #include <tabprotection.hxx>
56 #include "cachedattraccess.hxx"
57 #include <colorscale.hxx>
58 #include <conditio.hxx>
59 #include <cellvalue.hxx>
60 #include <stylehelper.hxx>
61 #include <edittextiterator.hxx>
62 #include "editattributemap.hxx"
63 #include <arealink.hxx>
64 #include <datastream.hxx>
65 #include <documentlinkmgr.hxx>
66 #include <tokenstringcontext.hxx>
67 #include <cellform.hxx>
68 #include <datamapper.hxx>
69 #include <datatransformation.hxx>
70 #include "SparklineGroupsExport.hxx"
71 #include <SparklineList.hxx>
73 #include <xmloff/xmltoken.hxx>
74 #include <xmloff/xmlnamespace.hxx>
75 #include <xmloff/xmluconv.hxx>
76 #include <xmloff/namespacemap.hxx>
77 #include <xmloff/families.hxx>
78 #include <xmloff/numehelp.hxx>
79 #include <xmloff/txtparae.hxx>
80 #include <editeng/autokernitem.hxx>
81 #include <editeng/charreliefitem.hxx>
82 #include <editeng/charscaleitem.hxx>
83 #include <editeng/colritem.hxx>
84 #include <editeng/contouritem.hxx>
85 #include <editeng/crossedoutitem.hxx>
86 #include <editeng/emphasismarkitem.hxx>
87 #include <editeng/escapementitem.hxx>
88 #include <editeng/fhgtitem.hxx>
89 #include <editeng/fontitem.hxx>
90 #include <editeng/kernitem.hxx>
91 #include <editeng/langitem.hxx>
92 #include <editeng/postitem.hxx>
93 #include <editeng/section.hxx>
94 #include <editeng/shdditem.hxx>
95 #include <editeng/udlnitem.hxx>
96 #include <editeng/wghtitem.hxx>
97 #include <editeng/wrlmitem.hxx>
98 #include <editeng/xmlcnitm.hxx>
99 #include <editeng/flditem.hxx>
100 #include <editeng/eeitem.hxx>
101 #include <formula/errorcodes.hxx>
102 #include <xmloff/xmlerror.hxx>
103 #include <xmloff/XMLEventExport.hxx>
104 #include <xmloff/xmlprmap.hxx>
105 #include <xmloff/ProgressBarHelper.hxx>
106 #include <xmloff/table/XMLTableExport.hxx>
108 #include <sax/tools/converter.hxx>
109 #include <tools/fldunit.hxx>
111 #include <rtl/ustring.hxx>
113 #include <tools/color.hxx>
114 #include <comphelper/diagnose_ex.hxx>
115 #include <rtl/math.hxx>
116 #include <svl/numformat.hxx>
117 #include <svl/zforlist.hxx>
118 #include <comphelper/base64.hxx>
119 #include <comphelper/extract.hxx>
120 #include <svx/svdoashp.hxx>
121 #include <svx/svdobj.hxx>
122 #include <svx/svdocapt.hxx>
123 #include <vcl/svapp.hxx>
125 #include <comphelper/processfactory.hxx>
126 #include <com/sun/star/beans/XPropertySet.hpp>
127 #include <com/sun/star/container/XNamed.hpp>
128 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
129 #include <com/sun/star/form/XFormsSupplier2.hpp>
130 #include <com/sun/star/io/XActiveDataSource.hpp>
131 #include <com/sun/star/io/XSeekable.hpp>
132 #include <com/sun/star/sheet/XUsedAreaCursor.hpp>
133 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
134 #include <com/sun/star/sheet/XPrintAreas.hpp>
135 #include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp>
136 #include <com/sun/star/sheet/XLabelRange.hpp>
137 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
138 #include <com/sun/star/sheet/XSheetCellCursor.hpp>
139 #include <com/sun/star/sheet/XSheetCellRanges.hpp>
140 #include <com/sun/star/sheet/XSheetLinkable.hpp>
141 #include <com/sun/star/sheet/GlobalSheetSettings.hpp>
142 #include <com/sun/star/table/XColumnRowRange.hpp>
143 #include <com/sun/star/util/XProtectable.hpp>
144 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
145 #include <com/sun/star/chart2/XChartDocument.hpp>
146 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
147 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
149 #include <com/sun/star/document/XDocumentProperties.hpp>
150 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
152 #include "XMLCodeNameProvider.hxx"
154 #include <sfx2/linkmgr.hxx>
155 #include <sfx2/objsh.hxx>
159 #include <vbahelper/vbaaccesshelper.hxx>
160 #include <officecfg/Office/Common.hxx>
162 namespace com::sun::star::uno
{ class XComponentContext
; }
166 //! not found in unonames.hxx
167 constexpr OUStringLiteral SC_LAYERID
= u
"LayerID";
169 #define SC_VIEWCHANGES_COUNT 13
170 #define SC_SHOW_CHANGES 0
171 #define SC_SHOW_ACCEPTED_CHANGES 1
172 #define SC_SHOW_REJECTED_CHANGES 2
173 #define SC_SHOW_CHANGES_BY_DATETIME 3
174 #define SC_SHOW_CHANGES_BY_DATETIME_MODE 4
175 #define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5
176 #define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6
177 #define SC_SHOW_CHANGES_BY_AUTHOR 7
178 #define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8
179 #define SC_SHOW_CHANGES_BY_COMMENT 9
180 #define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10
181 #define SC_SHOW_CHANGES_BY_RANGES 11
182 #define SC_SHOW_CHANGES_BY_RANGES_LIST 12
184 using namespace formula
;
185 using namespace com::sun::star
;
186 using namespace xmloff::token
;
188 using ::com::sun::star::uno::UNO_QUERY
;
192 OUString
lcl_RangeSequenceToString(
193 const uno::Sequence
< OUString
> & rRanges
,
194 const uno::Reference
< chart2::data::XRangeXMLConversion
> & xFormatConverter
)
196 OUStringBuffer aResult
;
197 const sal_Int32
nMaxIndex( rRanges
.getLength() - 1 );
198 const sal_Unicode
cSep(' ');
199 for( sal_Int32 i
=0; i
<=nMaxIndex
; ++i
)
201 OUString
aRange( rRanges
[i
] );
202 if( xFormatConverter
.is())
203 aRange
= xFormatConverter
->convertRangeToXML( aRange
);
204 aResult
.append( aRange
);
206 aResult
.append( cSep
);
208 return aResult
.makeStringAndClear();
211 OUString
lcl_GetFormattedString(ScDocument
* pDoc
, const ScRefCellValue
& rCell
, const ScAddress
& rAddr
)
213 // return text/edit cell string content, with line feeds in edit cells
218 switch (rCell
.getType())
220 case CELLTYPE_STRING
:
223 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
225 sal_uInt32 nFormat
= pDoc
->GetNumberFormat(rAddr
);
226 return ScCellFormat::GetString(rCell
, nFormat
, &pColor
, *pFormatter
, *pDoc
);
230 const EditTextObject
* pData
= rCell
.getEditText();
234 EditEngine
& rEngine
= pDoc
->GetEditEngine();
235 rEngine
.SetText(*pData
);
236 return rEngine
.GetText();
246 } // anonymous namespace
248 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
249 Calc_XMLExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
251 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLExporter", SvXMLExportFlags::ALL
));
254 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
255 Calc_XMLMetaExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
257 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLMetaExporter", SvXMLExportFlags::META
));
260 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
261 Calc_XMLStylesExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
263 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLStylesExporter", SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::FONTDECLS
));
266 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
267 Calc_XMLContentExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
269 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLContentExporter", SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SCRIPTS
|SvXMLExportFlags::FONTDECLS
));
272 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
273 Calc_XMLSettingsExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
275 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLSettingsExporter", SvXMLExportFlags::SETTINGS
));
278 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
279 Calc_XMLOasisExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
281 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisExporter", SvXMLExportFlags::ALL
|SvXMLExportFlags::OASIS
));
284 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
285 Calc_XMLOasisMetaExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
287 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisMetaExporter", SvXMLExportFlags::META
|SvXMLExportFlags::OASIS
));
290 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
291 Calc_XMLOasisStylesExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
293 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisStylesExporter", SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::OASIS
));
296 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
297 Calc_XMLOasisContentExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
299 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisContentExporter", SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SCRIPTS
|SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::OASIS
));
302 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
303 Calc_XMLOasisSettingsExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
305 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisSettingsExporter", SvXMLExportFlags::SETTINGS
|SvXMLExportFlags::OASIS
));
310 class ScXMLShapeExport
: public XMLShapeExport
313 explicit ScXMLShapeExport(SvXMLExport
& rExp
)
314 : XMLShapeExport(rExp
,
315 // chain text attributes
316 XMLTextParagraphExport::CreateParaExtPropMapper(rExp
))
320 /** is called before a shape element for the given XShape is exported */
321 virtual void onExport( const uno::Reference
< drawing::XShape
>& xShape
) override
;
326 void ScXMLShapeExport::onExport( const uno::Reference
< drawing::XShape
>& xShape
)
328 uno::Reference
< beans::XPropertySet
> xShapeProp( xShape
, uno::UNO_QUERY
);
329 if( xShapeProp
.is() )
331 sal_Int16 nLayerID
= 0;
332 if( (xShapeProp
->getPropertyValue( SC_LAYERID
) >>= nLayerID
) && (SdrLayerID(nLayerID
) == SC_LAYER_BACK
) )
333 GetExport().AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_BACKGROUND
, XML_TRUE
);
337 sal_Int16
ScXMLExport::GetMeasureUnit()
339 css::uno::Reference
<css::sheet::XGlobalSheetSettings
> xProperties
=
340 css::sheet::GlobalSheetSettings::create( comphelper::getProcessComponentContext() );
341 const FieldUnit eFieldUnit
= static_cast<FieldUnit
>(xProperties
->getMetric());
342 return SvXMLUnitConverter::GetMeasureUnit(eFieldUnit
);
345 ScXMLExport::ScXMLExport(
346 const css::uno::Reference
< css::uno::XComponentContext
>& rContext
,
347 OUString
const & implementationName
, SvXMLExportFlags nExportFlag
)
349 rContext
, implementationName
, GetMeasureUnit(), XML_SPREADSHEET
, nExportFlag
),
352 pCurrentCell(nullptr),
356 bHasRowHeader(false),
357 bRowHeaderOpen(false)
359 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
361 pGroupColumns
.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP
) );
362 pGroupRows
.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP
) );
363 pColumnStyles
.reset( new ScColumnStyles() );
364 pRowStyles
.reset( new ScRowStyles() );
365 pRowFormatRanges
.reset( new ScRowFormatRanges() );
366 pMergedRangesContainer
.reset( new ScMyMergedRangesContainer() );
367 pValidationsContainer
.reset( new ScMyValidationsContainer() );
368 mpCellsItr
.reset(new ScMyNotEmptyCellsIterator(*this));
369 pDefaults
.reset( new ScMyDefaultStyles
);
371 pCellStyles
.reset( new ScFormatRangeStyles() );
373 // document is not set here - create ScChangeTrackingExportHelper later
375 xScPropHdlFactory
= new XMLScPropHdlFactory
;
376 xCellStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScCellStylesProperties
, xScPropHdlFactory
, true);
377 xColumnStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScColumnStylesProperties
, xScPropHdlFactory
, true);
378 xRowStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScRowStylesProperties
, xScPropHdlFactory
, true);
379 xTableStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScTableStylesProperties
, xScPropHdlFactory
, true);
380 xCellStylesExportPropertySetMapper
= new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper
);
381 xCellStylesExportPropertySetMapper
->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
382 xColumnStylesExportPropertySetMapper
= new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper
);
383 xRowStylesExportPropertySetMapper
= new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper
);
384 xTableStylesExportPropertySetMapper
= new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper
);
386 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_CELL
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
,
387 xCellStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
);
388 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_COLUMN
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME
,
389 xColumnStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX
);
390 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_ROW
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME
,
391 xRowStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX
);
392 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_TABLE
, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME
,
393 xTableStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX
);
395 if( !(getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
)) )
398 // This name is reserved for the external ref cache tables. This
399 // should not conflict with user-defined styles since this name is
400 // used for a table style which is not available in the UI.
401 sExternalRefTabStyleName
= "ta_extref";
402 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE
, sExternalRefTabStyleName
);
404 sAttrName
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_NAME
));
405 sAttrStyleName
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_STYLE_NAME
));
406 sAttrColumnsRepeated
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED
));
407 sAttrFormula
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_FORMULA
));
408 sAttrStringValue
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_STRING_VALUE
));
409 sAttrValueType
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_VALUE_TYPE
));
410 sElemCell
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_CELL
));
411 sElemCoveredCell
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_COVERED_TABLE_CELL
));
412 sElemCol
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_COLUMN
));
413 sElemRow
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_ROW
));
414 sElemTab
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE
));
415 sElemP
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
418 ScXMLExport::~ScXMLExport()
420 pGroupColumns
.reset();
422 pColumnStyles
.reset();
425 pRowFormatRanges
.reset();
426 pMergedRangesContainer
.reset();
427 pValidationsContainer
.reset();
428 pChangeTrackingExportHelper
.reset();
430 pNumberFormatAttributesExportHelper
.reset();
433 void ScXMLExport::SetSourceStream( const uno::Reference
<io::XInputStream
>& xNewStream
)
435 xSourceStream
= xNewStream
;
437 if ( !xSourceStream
.is() )
440 // make sure it's a plain UTF-8 stream as written by OOo itself
442 const char pXmlHeader
[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
443 sal_Int32 nLen
= strlen(pXmlHeader
);
445 uno::Sequence
<sal_Int8
> aFileStart(nLen
);
446 sal_Int32 nRead
= xSourceStream
->readBytes( aFileStart
, nLen
);
448 if ( nRead
!= nLen
|| memcmp( aFileStart
.getConstArray(), pXmlHeader
, nLen
) != 0 )
450 // invalid - ignore stream, save normally
451 xSourceStream
.clear();
455 // keep track of the bytes already read
456 nSourceStreamPos
= nRead
;
458 const ScSheetSaveData
* pSheetData
= comphelper::getFromUnoTunnel
<ScModelObj
>(GetModel())->GetSheetSaveData();
461 // add the loaded namespaces to the name space map
463 if ( !pSheetData
->AddLoadedNamespaces( GetNamespaceMap_() ) )
465 // conflicts in the namespaces - ignore the stream, save normally
466 xSourceStream
.clear();
472 sal_Int32
ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt
) const
474 NumberFormatIndexMap::const_iterator itr
= aNumFmtIndexMap
.find(nNumFmt
);
475 if (itr
== aNumFmtIndexMap
.end())
481 void ScXMLExport::CollectSharedData(SCTAB
& nTableCount
, sal_Int32
& nShapesCount
)
483 if (!GetModel().is())
486 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc(GetModel(), uno::UNO_QUERY
);
487 if (!xSpreadDoc
.is())
490 uno::Reference
<container::XIndexAccess
> xIndex(xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
494 nTableCount
= xIndex
->getCount();
496 pSharedData
.reset(new ScMySharedData(nTableCount
));
498 pCellStyles
->AddNewTable(nTableCount
- 1);
500 for (SCTAB nTable
= 0; nTable
< nTableCount
; ++nTable
)
502 nCurrentTable
= sal::static_int_cast
<sal_uInt16
>(nTable
);
503 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
504 if (!xDrawPageSupplier
.is())
507 uno::Reference
<drawing::XDrawPage
> xDrawPage(xDrawPageSupplier
->getDrawPage());
508 ScMyDrawPage aDrawPage
;
509 aDrawPage
.bHasForms
= false;
510 aDrawPage
.xDrawPage
.set(xDrawPage
);
511 pSharedData
->AddDrawPage(aDrawPage
, nTable
);
515 sal_Int32 nShapes
= xDrawPage
->getCount();
516 for (sal_Int32 nShape
= 0; nShape
< nShapes
; ++nShape
)
518 uno::Reference
<drawing::XShape
> xShape(xDrawPage
->getByIndex(nShape
), uno::UNO_QUERY
);
522 uno::Reference
<beans::XPropertySet
> xShapeProp(xShape
, uno::UNO_QUERY
);
523 if (!xShapeProp
.is())
526 sal_Int16 nLayerID
= 0;
527 bool bExtracted
= xShapeProp
->getPropertyValue(SC_LAYERID
) >>= nLayerID
;
531 if ((SdrLayerID(nLayerID
) == SC_LAYER_INTERN
) || (SdrLayerID(nLayerID
) == SC_LAYER_HIDDEN
))
533 CollectInternalShape(xShape
);
539 SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape(xShape
);
543 if (ScDrawObjData
*pAnchor
= ScDrawLayer::GetNonRotatedObjData(pSdrObj
))
546 aMyShape
.aAddress
= pAnchor
->maStart
;
547 SAL_WARN_IF(aMyShape
.aAddress
.Tab() != nTable
, "sc", "not anchored to current sheet!");
548 aMyShape
.aAddress
.SetTab(nTable
);
549 aMyShape
.aEndAddress
= pAnchor
->maEnd
;
550 aMyShape
.aEndAddress
.SetTab( nTable
);
551 aMyShape
.nEndX
= pAnchor
->maEndOffset
.X();
552 aMyShape
.nEndY
= pAnchor
->maEndOffset
.Y();
553 aMyShape
.xShape
= xShape
;
554 aMyShape
.bResizeWithCell
= ScDrawLayer::IsResizeWithCell(*pSdrObj
);
555 pSharedData
->AddNewShape(aMyShape
);
556 pSharedData
->SetLastColumn(nTable
, pAnchor
->maStart
.Col());
557 pSharedData
->SetLastRow(nTable
, pAnchor
->maStart
.Row());
560 pSharedData
->AddTableShape(nTable
, xShape
);
565 void ScXMLExport::CollectShapesAutoStyles(SCTAB nTableCount
)
567 // #i84077# To avoid compiler warnings about uninitialized aShapeItr,
568 // it's initialized using this dummy list. The iterator contains shapes
569 // from all sheets, so it can't be declared inside the nTable loop where
571 ScMyShapeList aDummyInitList
;
573 pSharedData
->SortShapesContainer();
574 pSharedData
->SortNoteShapes();
575 const ScMyShapeList
* pShapeList(nullptr);
576 ScMyShapeList::const_iterator aShapeItr
= aDummyInitList
.end();
577 if (pSharedData
->GetShapesContainer())
579 pShapeList
= &pSharedData
->GetShapesContainer()->GetShapes();
580 aShapeItr
= pShapeList
->begin();
582 if (pSharedData
->HasDrawPage())
584 css::uno::Sequence
<OUString
> aAutoStylePropNames
= GetAutoStylePool()->GetPropertyNames();
585 for (SCTAB nTable
= 0; nTable
< nTableCount
; ++nTable
)
587 uno::Reference
<drawing::XDrawPage
> xDrawPage(pSharedData
->GetDrawPage(nTable
));
591 GetShapeExport()->seekShapes(xDrawPage
);
592 uno::Reference
< form::XFormsSupplier2
> xFormsSupplier( xDrawPage
, uno::UNO_QUERY
);
593 if( xFormsSupplier
.is() && xFormsSupplier
->hasForms() )
595 GetFormExport()->examineForms(xDrawPage
);
596 pSharedData
->SetDrawPageHasForms(nTable
, true);
598 ScMyTableShapes
* pTableShapes(pSharedData
->GetTableShapes());
601 for (const auto& rxShape
: (*pTableShapes
)[nTable
])
603 GetShapeExport()->collectShapeAutoStyles(rxShape
, aAutoStylePropNames
);
604 IncrementProgressBar(false);
609 ScMyShapeList::const_iterator
aEndItr(pShapeList
->end());
610 while ( aShapeItr
!= aEndItr
&& ( aShapeItr
->aAddress
.Tab() == nTable
) )
612 GetShapeExport()->collectShapeAutoStyles(aShapeItr
->xShape
, aAutoStylePropNames
);
613 IncrementProgressBar(false);
617 if (pSharedData
->GetNoteShapes())
619 const ScMyNoteShapeList
& rNoteShapes
= pSharedData
->GetNoteShapes()->GetNotes();
620 for (const auto& rNoteShape
: rNoteShapes
)
622 if ( rNoteShape
.aPos
.Tab() == nTable
)
623 GetShapeExport()->collectShapeAutoStyles(rNoteShape
.xShape
, aAutoStylePropNames
);
629 pSharedData
->SortNoteShapes(); // sort twice, because some more shapes are added
632 void ScXMLExport::ExportMeta_()
634 sal_Int32
nCellCount(pDoc
? pDoc
->GetCellCount() : 0);
635 SCTAB
nTableCount(0);
636 sal_Int32
nShapesCount(0);
637 GetAutoStylePool()->ClearEntries();
638 CollectSharedData(nTableCount
, nShapesCount
);
640 uno::Sequence
<beans::NamedValue
> stats
642 { "TableCount", uno::Any(static_cast<sal_Int32
>(nTableCount
)) },
643 { "CellCount", uno::Any(nCellCount
) },
644 { "ObjectCount", uno::Any(nShapesCount
) }
647 // update document statistics at the model
648 uno::Reference
<document::XDocumentPropertiesSupplier
> xPropSup(GetModel(),
649 uno::UNO_QUERY_THROW
);
650 uno::Reference
<document::XDocumentProperties
> xDocProps(
651 xPropSup
->getDocumentProperties());
652 if (xDocProps
.is()) {
653 xDocProps
->setDocumentStatistics(stats
);
656 // export document properties
657 SvXMLExport::ExportMeta_();
660 void ScXMLExport::ExportFontDecls_()
662 GetFontAutoStylePool(); // make sure the pool is created
663 SvXMLExport::ExportFontDecls_();
666 table::CellRangeAddress
ScXMLExport::GetEndAddress(const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
668 table::CellRangeAddress aCellAddress
;
669 uno::Reference
<sheet::XSheetCellCursor
> xCursor(xTable
->createCursor());
670 uno::Reference
<sheet::XUsedAreaCursor
> xUsedArea (xCursor
, uno::UNO_QUERY
);
671 uno::Reference
<sheet::XCellRangeAddressable
> xCellAddress (xCursor
, uno::UNO_QUERY
);
672 if (xUsedArea
.is() && xCellAddress
.is())
674 xUsedArea
->gotoEndOfUsedArea(true);
675 aCellAddress
= xCellAddress
->getRangeAddress();
680 void ScXMLExport::GetAreaLinks( ScMyAreaLinksContainer
& rAreaLinks
)
682 if (pDoc
->GetLinkManager())
684 const sfx2::SvBaseLinks
& rLinks
= pDoc
->GetLinkManager()->GetLinks();
685 for (const auto & rLink
: rLinks
)
687 ScAreaLink
*pLink
= dynamic_cast<ScAreaLink
*>(rLink
.get());
690 ScMyAreaLink aAreaLink
;
691 aAreaLink
.aDestRange
= pLink
->GetDestArea();
692 aAreaLink
.sSourceStr
= pLink
->GetSource();
693 aAreaLink
.sFilter
= pLink
->GetFilter();
694 aAreaLink
.sFilterOptions
= pLink
->GetOptions();
695 aAreaLink
.sURL
= pLink
->GetFile();
696 aAreaLink
.nRefreshDelaySeconds
= pLink
->GetRefreshDelaySeconds();
697 rAreaLinks
.AddNewAreaLink( aAreaLink
);
704 // core implementation
705 void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer
& rDetOp
)
710 ScDetOpList
* pOpList(pDoc
->GetDetOpList());
714 size_t nCount
= pOpList
->Count();
715 for (size_t nIndex
= 0; nIndex
< nCount
; ++nIndex
)
717 const ScDetOpData
& rDetData
= pOpList
->GetObject( nIndex
);
718 const ScAddress
& rDetPos
= rDetData
.GetPos();
719 SCTAB nTab
= rDetPos
.Tab();
720 if ( nTab
< pDoc
->GetTableCount() )
722 rDetOp
.AddOperation( rDetData
.GetOperation(), rDetPos
, static_cast<sal_uInt32
>( nIndex
) );
724 // cells with detective operations are written even if empty
725 pSharedData
->SetLastColumn( nTab
, rDetPos
.Col() );
726 pSharedData
->SetLastRow( nTab
, rDetPos
.Row() );
732 void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns
, const sal_Int32 nStyleIndex
,
733 const sal_Int32 nIndex
, const bool bIsAutoStyle
, const bool bIsVisible
)
737 if (nStyleIndex
!= -1)
738 AddAttribute(sAttrStyleName
, pColumnStyles
->GetStyleNameByIndex(nStyleIndex
));
740 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_COLLAPSE
);
741 if (nRepeatColumns
> 1)
743 OUString
sOUEndCol(OUString::number(nRepeatColumns
));
744 AddAttribute(sAttrColumnsRepeated
, sOUEndCol
);
747 AddAttribute(XML_NAMESPACE_TABLE
, XML_DEFAULT_CELL_STYLE_NAME
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
748 SvXMLElementExport
aElemC(*this, sElemCol
, true, true);
751 void ScXMLExport::WriteColumn(const sal_Int32 nColumn
, const sal_Int32 nRepeatColumns
,
752 const sal_Int32 nStyleIndex
, const bool bIsVisible
)
754 sal_Int32
nRepeat(1);
755 sal_Int32
nPrevIndex(pDefaults
->GetColDefaults()[nColumn
].nIndex
);
756 bool bPrevAutoStyle(pDefaults
->GetColDefaults()[nColumn
].bIsAutoStyle
);
757 for (sal_Int32 i
= nColumn
+ 1; i
< nColumn
+ nRepeatColumns
; ++i
)
759 if ((pDefaults
->GetColDefaults()[i
].nIndex
!= nPrevIndex
) ||
760 (pDefaults
->GetColDefaults()[i
].bIsAutoStyle
!= bPrevAutoStyle
))
762 WriteSingleColumn(nRepeat
, nStyleIndex
, nPrevIndex
, bPrevAutoStyle
, bIsVisible
);
763 nPrevIndex
= pDefaults
->GetColDefaults()[i
].nIndex
;
764 bPrevAutoStyle
= pDefaults
->GetColDefaults()[i
].bIsAutoStyle
;
770 WriteSingleColumn(nRepeat
, nStyleIndex
, nPrevIndex
, bPrevAutoStyle
, bIsVisible
);
773 void ScXMLExport::OpenHeaderColumn()
775 StartElement( XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, true );
778 void ScXMLExport::CloseHeaderColumn()
780 EndElement(XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, true);
783 void ScXMLExport::ExportColumns(const sal_Int32 nTable
, const ScRange
& aColumnHeaderRange
, const bool bHasColumnHeader
)
785 sal_Int32
nColsRepeated (1);
787 sal_Int32
nPrevColumn(0);
788 bool bPrevIsVisible (true);
789 bool bWasHeader (false);
790 bool bIsClosed (true);
791 sal_Int32
nPrevIndex (-1);
793 for (nColumn
= 0; nColumn
<= pSharedData
->GetLastColumn(nTable
); ++nColumn
)
796 bool bIsVisible(true);
797 nIndex
= pColumnStyles
->GetStyleNameIndex(nTable
, nColumn
, bIsVisible
);
799 const bool bIsHeader
= bHasColumnHeader
&& (aColumnHeaderRange
.aStart
.Col() <= nColumn
) && (nColumn
<= aColumnHeaderRange
.aEnd
.Col());
800 if (bIsHeader
!= bWasHeader
)
806 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
807 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
808 pGroupColumns
->CloseGroups(nColumn
- 1);
810 bPrevIsVisible
= bIsVisible
;
812 nPrevColumn
= nColumn
;
814 if(pGroupColumns
->IsGroupStart(nColumn
))
815 pGroupColumns
->OpenGroups(nColumn
);
822 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
824 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
825 pGroupColumns
->CloseGroups(nColumn
- 1);
826 if(pGroupColumns
->IsGroupStart(nColumn
))
827 pGroupColumns
->OpenGroups(nColumn
);
828 bPrevIsVisible
= bIsVisible
;
830 nPrevColumn
= nColumn
;
836 else if (nColumn
== 0)
838 if (pGroupColumns
->IsGroupStart(nColumn
))
839 pGroupColumns
->OpenGroups(nColumn
);
840 bPrevIsVisible
= bIsVisible
;
843 else if ((bIsVisible
== bPrevIsVisible
) && (nIndex
== nPrevIndex
) &&
844 !pGroupColumns
->IsGroupStart(nColumn
) && !pGroupColumns
->IsGroupEnd(nColumn
- 1))
848 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
849 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
853 pGroupColumns
->CloseGroups(nColumn
- 1);
857 if (pGroupColumns
->IsGroupStart(nColumn
))
861 pGroupColumns
->OpenGroups(nColumn
);
865 bPrevIsVisible
= bIsVisible
;
867 nPrevColumn
= nColumn
;
871 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
874 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
875 pGroupColumns
->CloseGroups(nColumn
- 1);
878 void ScXMLExport::ExportExternalRefCacheStyles()
880 sal_Int32 nEntryIndex
= GetCellStylesPropertySetMapper()->FindEntryIndex(
881 "NumberFormat", XML_NAMESPACE_STYLE
, u
"data-style-name");
884 // No entry index for the number format is found.
887 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
888 if (!pRefMgr
->hasExternalData())
889 // No external reference data cached.
892 // Export each unique number format used in the external ref cache.
893 vector
<sal_uInt32
> aNumFmts
;
894 pRefMgr
->getAllCachedNumberFormats(aNumFmts
);
895 const OUString aDefaultStyle
= OUString("Default").intern();
896 for (const auto& rNumFmt
: aNumFmts
)
898 sal_Int32 nNumFmt
= static_cast<sal_Int32
>(rNumFmt
);
900 addDataStyle(nNumFmt
);
904 vector
<XMLPropertyState
> aProps
;
905 aVal
<<= aDefaultStyle
;
906 aProps
.emplace_back(nEntryIndex
, aVal
);
910 if (GetAutoStylePool()->Add(aName
, XmlStyleFamily::TABLE_CELL
, aDefaultStyle
, std::move(aProps
)))
912 pCellStyles
->AddStyleName(aName
, nIndex
);
917 nIndex
= pCellStyles
->GetIndexOfStyleName(
918 aName
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
, bIsAuto
);
921 // store the number format to index mapping for later use.
922 aNumFmtIndexMap
.emplace(nNumFmt
, nIndex
);
929 SvXMLExport
& rExport
,
930 std::vector
<XMLPropertyState
>& rPropStates
,
931 const SfxPoolItem
* p
, const rtl::Reference
<XMLPropertySetMapper
>& xMapper
, std::u16string_view rXMLName
)
933 sal_Int32 nEntryCount
= xMapper
->GetEntryCount();
935 // Apparently font info needs special handling.
936 const SvxFontItem
* pItem
= static_cast<const SvxFontItem
*>(p
);
938 sal_Int32 nIndexFontName
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, rXMLName
, 0);
940 if (nIndexFontName
== -1 || nIndexFontName
>= nEntryCount
)
943 OUString
const sFamilyName(pItem
->GetFamilyName());
944 OUString
const sStyleName(pItem
->GetStyleName());
945 auto const nFamily(pItem
->GetFamily());
946 auto const nPitch(pItem
->GetPitch());
947 auto const eEnc(pItem
->GetCharSet());
948 OUString
const sName(rExport
.GetFontAutoStylePool()->Find(
949 sFamilyName
, sStyleName
, nFamily
, nPitch
, eEnc
));
952 assert(false); // fallback to fo:font-family etc. probably not needed
955 rPropStates
.emplace_back(nIndexFontName
, uno::Any(sName
));
958 const SvxFieldData
* toXMLPropertyStates(
959 SvXMLExport
& rExport
,
960 std::vector
<XMLPropertyState
>& rPropStates
, const std::vector
<const SfxPoolItem
*>& rSecAttrs
,
961 const rtl::Reference
<XMLPropertySetMapper
>& xMapper
, const ScXMLEditAttributeMap
& rAttrMap
)
963 const SvxFieldData
* pField
= nullptr;
964 sal_Int32 nEntryCount
= xMapper
->GetEntryCount();
965 rPropStates
.reserve(rSecAttrs
.size());
966 for (const SfxPoolItem
* p
: rSecAttrs
)
968 if (p
->Which() == EE_FEATURE_FIELD
)
970 pField
= static_cast<const SvxFieldItem
*>(p
)->GetField();
974 const ScXMLEditAttributeMap::Entry
* pEntry
= rAttrMap
.getEntryByItemID(p
->Which());
978 sal_Int32 nIndex
= xMapper
->GetEntryIndex(
979 pEntry
->nmXMLNS
, OUString::createFromAscii(pEntry
->mpXMLName
), 0);
981 if (nIndex
== -1 || nIndex
>= nEntryCount
)
987 case EE_CHAR_FONTINFO
:
988 handleFont(rExport
, rPropStates
, p
, xMapper
, u
"font-name");
990 case EE_CHAR_FONTINFO_CJK
:
991 handleFont(rExport
, rPropStates
, p
, xMapper
, u
"font-name-asian");
993 case EE_CHAR_FONTINFO_CTL
:
994 handleFont(rExport
, rPropStates
, p
, xMapper
, u
"font-name-complex");
997 case EE_CHAR_WEIGHT_CJK
:
998 case EE_CHAR_WEIGHT_CTL
:
1000 if (!static_cast<const SvxWeightItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1003 rPropStates
.emplace_back(nIndex
, aAny
);
1006 case EE_CHAR_FONTHEIGHT
:
1007 case EE_CHAR_FONTHEIGHT_CJK
:
1008 case EE_CHAR_FONTHEIGHT_CTL
:
1010 if (!static_cast<const SvxFontHeightItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1013 rPropStates
.emplace_back(nIndex
, aAny
);
1016 case EE_CHAR_ITALIC
:
1017 case EE_CHAR_ITALIC_CJK
:
1018 case EE_CHAR_ITALIC_CTL
:
1020 if (!static_cast<const SvxPostureItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1023 rPropStates
.emplace_back(nIndex
, aAny
);
1026 case EE_CHAR_UNDERLINE
:
1028 // Underline attribute needs to export multiple entries.
1029 sal_Int32 nIndexStyle
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-underline-style", 0);
1030 if (nIndexStyle
== -1 || nIndexStyle
> nEntryCount
)
1033 sal_Int32 nIndexWidth
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-underline-width", 0);
1034 if (nIndexWidth
== -1 || nIndexWidth
> nEntryCount
)
1037 sal_Int32 nIndexType
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-underline-type", 0);
1038 if (nIndexType
== -1 || nIndexType
> nEntryCount
)
1041 sal_Int32 nIndexColor
= xMapper
->FindEntryIndex("CharUnderlineColor", XML_NAMESPACE_STYLE
, u
"text-underline-color");
1042 if (nIndexColor
== -1 || nIndexColor
> nEntryCount
)
1045 sal_Int32 nIndexHasColor
= xMapper
->FindEntryIndex("CharUnderlineHasColor", XML_NAMESPACE_STYLE
, u
"text-underline-color");
1046 if (nIndexHasColor
== -1 || nIndexHasColor
> nEntryCount
)
1049 const SvxUnderlineItem
* pUL
= static_cast<const SvxUnderlineItem
*>(p
);
1050 pUL
->QueryValue(aAny
, MID_TL_STYLE
);
1051 rPropStates
.emplace_back(nIndexStyle
, aAny
);
1052 rPropStates
.emplace_back(nIndexType
, aAny
);
1053 rPropStates
.emplace_back(nIndexWidth
, aAny
);
1055 pUL
->QueryValue(aAny
, MID_TL_COLOR
);
1056 rPropStates
.emplace_back(nIndexColor
, aAny
);
1058 pUL
->QueryValue(aAny
, MID_TL_HASCOLOR
);
1059 rPropStates
.emplace_back(nIndexHasColor
, aAny
);
1062 case EE_CHAR_OVERLINE
:
1064 // Same with overline. Do just as we do with underline attributes.
1065 sal_Int32 nIndexStyle
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-overline-style", 0);
1066 if (nIndexStyle
== -1 || nIndexStyle
> nEntryCount
)
1069 sal_Int32 nIndexWidth
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-overline-width", 0);
1070 if (nIndexWidth
== -1 || nIndexWidth
> nEntryCount
)
1073 sal_Int32 nIndexType
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, u
"text-overline-type", 0);
1074 if (nIndexType
== -1 || nIndexType
> nEntryCount
)
1077 sal_Int32 nIndexColor
= xMapper
->FindEntryIndex("CharOverlineColor", XML_NAMESPACE_STYLE
, u
"text-overline-color");
1078 if (nIndexColor
== -1 || nIndexColor
> nEntryCount
)
1081 sal_Int32 nIndexHasColor
= xMapper
->FindEntryIndex("CharOverlineHasColor", XML_NAMESPACE_STYLE
, u
"text-overline-color");
1082 if (nIndexHasColor
== -1 || nIndexHasColor
> nEntryCount
)
1085 const SvxOverlineItem
* pOL
= static_cast<const SvxOverlineItem
*>(p
);
1086 pOL
->QueryValue(aAny
, MID_TL_STYLE
);
1087 rPropStates
.emplace_back(nIndexStyle
, aAny
);
1088 rPropStates
.emplace_back(nIndexType
, aAny
);
1089 rPropStates
.emplace_back(nIndexWidth
, aAny
);
1091 pOL
->QueryValue(aAny
, MID_TL_COLOR
);
1092 rPropStates
.emplace_back(nIndexColor
, aAny
);
1094 pOL
->QueryValue(aAny
, MID_TL_HASCOLOR
);
1095 rPropStates
.emplace_back(nIndexHasColor
, aAny
);
1100 if (!static_cast<const SvxColorItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1104 if ( aAny
>>= nColor
)
1106 sal_Int32 nIndexColor
= ( nColor
== COL_AUTO
) ? xMapper
->GetEntryIndex(
1107 XML_NAMESPACE_STYLE
, GetXMLToken( XML_USE_WINDOW_FONT_COLOR
), 0 ) : nIndex
;
1108 rPropStates
.emplace_back( nIndexColor
, aAny
);
1114 if (!static_cast<const SvxWordLineModeItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1117 rPropStates
.emplace_back(nIndex
, aAny
);
1120 case EE_CHAR_STRIKEOUT
:
1122 if (!static_cast<const SvxCrossedOutItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1125 rPropStates
.emplace_back(nIndex
, aAny
);
1128 case EE_CHAR_RELIEF
:
1130 if (!static_cast<const SvxCharReliefItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1133 rPropStates
.emplace_back(nIndex
, aAny
);
1136 case EE_CHAR_OUTLINE
:
1138 if (!static_cast<const SvxContourItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1141 rPropStates
.emplace_back(nIndex
, aAny
);
1144 case EE_CHAR_SHADOW
:
1146 if (!static_cast<const SvxShadowedItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1149 rPropStates
.emplace_back(nIndex
, aAny
);
1152 case EE_CHAR_KERNING
:
1154 if (!static_cast<const SvxKerningItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1157 rPropStates
.emplace_back(nIndex
, aAny
);
1160 case EE_CHAR_PAIRKERNING
:
1162 if (!static_cast<const SvxAutoKernItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1165 rPropStates
.emplace_back(nIndex
, aAny
);
1168 case EE_CHAR_FONTWIDTH
:
1170 if (!static_cast<const SvxCharScaleWidthItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1173 rPropStates
.emplace_back(nIndex
, aAny
);
1176 case EE_CHAR_ESCAPEMENT
:
1178 sal_Int32 nIndexEsc
= xMapper
->FindEntryIndex("CharEscapement", XML_NAMESPACE_STYLE
, u
"text-position");
1179 if (nIndexEsc
== -1 || nIndexEsc
> nEntryCount
)
1182 sal_Int32 nIndexEscHeight
= xMapper
->FindEntryIndex("CharEscapementHeight", XML_NAMESPACE_STYLE
, u
"text-position");
1183 if (nIndexEscHeight
== -1 || nIndexEscHeight
> nEntryCount
)
1186 const SvxEscapementItem
* pEsc
= static_cast<const SvxEscapementItem
*>(p
);
1188 pEsc
->QueryValue(aAny
);
1189 rPropStates
.emplace_back(nIndexEsc
, aAny
);
1191 pEsc
->QueryValue(aAny
, MID_ESC_HEIGHT
);
1192 rPropStates
.emplace_back(nIndexEscHeight
, aAny
);
1196 case EE_CHAR_EMPHASISMARK
:
1198 if (!static_cast<const SvxEmphasisMarkItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1201 rPropStates
.emplace_back(nIndex
, aAny
);
1204 case EE_CHAR_LANGUAGE
:
1205 case EE_CHAR_LANGUAGE_CJK
:
1206 case EE_CHAR_LANGUAGE_CTL
:
1208 if (!static_cast<const SvxLanguageItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1211 // Export multiple entries.
1212 sal_Int32 nIndexLanguage
, nIndexCountry
, nIndexScript
, nIndexTag
;
1215 case EE_CHAR_LANGUAGE
:
1216 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, u
"language", 0);
1217 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, u
"country", 0);
1218 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, u
"script", 0);
1219 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"rfc-language-tag", 0);
1221 case EE_CHAR_LANGUAGE_CJK
:
1222 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"language-asian", 0);
1223 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"country-asian", 0);
1224 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"script-asian", 0);
1225 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"rfc-language-tag-asian", 0);
1227 case EE_CHAR_LANGUAGE_CTL
:
1228 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"language-complex", 0);
1229 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"country-complex", 0);
1230 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"script-complex", 0);
1231 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, u
"rfc-language-tag-complex", 0);
1234 nIndexLanguage
= nIndexCountry
= nIndexScript
= nIndexTag
= -1;
1236 assert( nIndexLanguage
>= 0 && nIndexCountry
>= 0 && nIndexScript
>= 0 && nIndexTag
>= 0);
1237 rPropStates
.emplace_back( nIndexLanguage
, aAny
);
1238 rPropStates
.emplace_back( nIndexCountry
, aAny
);
1239 rPropStates
.emplace_back( nIndexScript
, aAny
);
1240 rPropStates
.emplace_back( nIndexTag
, aAny
);
1253 void ScXMLExport::ExportCellTextAutoStyles(sal_Int32 nTable
)
1255 if (!ValidTab(nTable
))
1258 rtl::Reference
<XMLPropertySetMapper
> xMapper
= GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
1259 rtl::Reference
<SvXMLAutoStylePoolP
> xStylePool
= GetAutoStylePool();
1260 const ScXMLEditAttributeMap
& rAttrMap
= GetEditAttributeMap();
1262 sc::EditTextIterator
aIter(*pDoc
, nTable
);
1263 sal_Int32 nCellCount
= 0;
1264 for (const EditTextObject
* pEdit
= aIter
.first(); pEdit
; pEdit
= aIter
.next(), ++nCellCount
)
1266 std::vector
<editeng::Section
> aAttrs
;
1267 pEdit
->GetAllSections(aAttrs
);
1271 for (const auto& rSec
: aAttrs
)
1273 const std::vector
<const SfxPoolItem
*>& rSecAttrs
= rSec
.maAttributes
;
1274 if (rSecAttrs
.empty())
1275 // No formats applied to this section. Skip it.
1278 std::vector
<XMLPropertyState
> aPropStates
;
1279 toXMLPropertyStates(*this, aPropStates
, rSecAttrs
, xMapper
, rAttrMap
);
1280 if (!aPropStates
.empty())
1281 xStylePool
->Add(XmlStyleFamily::TEXT_TEXT
, OUString(), std::move(aPropStates
));
1285 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCellCount
);
1288 void ScXMLExport::WriteRowContent()
1290 ScMyRowFormatRange aRange
;
1291 sal_Int32
nIndex(-1);
1292 #if OSL_DEBUG_LEVEL > 0
1293 sal_Int32
nPrevCol(0);
1296 sal_Int32
nPrevValidationIndex(-1);
1297 bool bIsAutoStyle(true);
1298 bool bIsFirst(true);
1299 while (pRowFormatRanges
->GetNext(aRange
))
1301 #if OSL_DEBUG_LEVEL > 0
1302 OSL_ENSURE(bIsFirst
|| (!bIsFirst
&& (nPrevCol
+ nCols
== aRange
.nStartColumn
)), "here are some columns missing");
1306 nIndex
= aRange
.nIndex
;
1307 nPrevValidationIndex
= aRange
.nValidationIndex
;
1308 bIsAutoStyle
= aRange
.bIsAutoStyle
;
1309 nCols
= aRange
.nRepeatColumns
;
1311 #if OSL_DEBUG_LEVEL > 0
1312 nPrevCol
= aRange
.nStartColumn
;
1317 if (((aRange
.nIndex
== nIndex
&& aRange
.bIsAutoStyle
== bIsAutoStyle
) ||
1318 (aRange
.nIndex
== nIndex
&& nIndex
== -1)) &&
1319 nPrevValidationIndex
== aRange
.nValidationIndex
)
1320 nCols
+= aRange
.nRepeatColumns
;
1324 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
1325 if (nPrevValidationIndex
> -1)
1326 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(nPrevValidationIndex
));
1329 AddAttribute(sAttrColumnsRepeated
, OUString::number(nCols
));
1331 SvXMLElementExport
aElemC(*this, sElemCell
, true, true);
1332 nIndex
= aRange
.nIndex
;
1333 bIsAutoStyle
= aRange
.bIsAutoStyle
;
1334 nCols
= aRange
.nRepeatColumns
;
1335 nPrevValidationIndex
= aRange
.nValidationIndex
;
1336 #if OSL_DEBUG_LEVEL > 0
1337 nPrevCol
= aRange
.nStartColumn
;
1345 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
1346 if (nPrevValidationIndex
> -1)
1347 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(nPrevValidationIndex
));
1350 AddAttribute(sAttrColumnsRepeated
, OUString::number(nCols
));
1352 SvXMLElementExport
aElemC(*this, sElemCell
, true, true);
1356 void ScXMLExport::WriteRowStartTag(
1357 const sal_Int32 nIndex
, const sal_Int32 nEqualRows
,
1358 bool bHidden
, bool bFiltered
)
1362 AddAttribute(sAttrStyleName
, pRowStyles
->GetStyleNameByIndex(nIndex
));
1366 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_FILTER
);
1368 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_COLLAPSE
);
1372 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, OUString::number(nEqualRows
));
1375 StartElement( sElemRow
, true);
1378 void ScXMLExport::OpenHeaderRows()
1380 StartElement( XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, true);
1381 bRowHeaderOpen
= true;
1384 void ScXMLExport::CloseHeaderRows()
1386 EndElement(XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, true);
1389 void ScXMLExport::OpenNewRow(
1390 const sal_Int32 nIndex
, const sal_Int32 nStartRow
, const sal_Int32 nEqualRows
,
1391 bool bHidden
, bool bFiltered
)
1393 nOpenRow
= nStartRow
;
1394 if (pGroupRows
->IsGroupStart(nStartRow
))
1396 if (bHasRowHeader
&& bRowHeaderOpen
)
1398 pGroupRows
->OpenGroups(nStartRow
);
1399 if (bHasRowHeader
&& bRowHeaderOpen
)
1402 if (bHasRowHeader
&& !bRowHeaderOpen
&& nStartRow
>= aRowHeaderRange
.aStart
.Row() && nStartRow
<= aRowHeaderRange
.aEnd
.Row())
1404 if (nStartRow
== aRowHeaderRange
.aStart
.Row())
1407 if (aRowHeaderRange
.aEnd
.Row() < nStartRow
+ nEqualRows
- 1)
1408 nEquals
= aRowHeaderRange
.aEnd
.Row() - nStartRow
+ 1;
1410 nEquals
= nEqualRows
;
1411 WriteRowStartTag(nIndex
, nEquals
, bHidden
, bFiltered
);
1412 nOpenRow
= nStartRow
+ nEquals
- 1;
1413 if (nEquals
< nEqualRows
)
1415 CloseRow(nStartRow
+ nEquals
- 1);
1416 WriteRowStartTag(nIndex
, nEqualRows
- nEquals
, bHidden
, bFiltered
);
1417 nOpenRow
= nStartRow
+ nEqualRows
- 1;
1421 WriteRowStartTag(nIndex
, nEqualRows
, bHidden
, bFiltered
);
1424 void ScXMLExport::OpenAndCloseRow(
1425 const sal_Int32 nIndex
, const sal_Int32 nStartRow
, const sal_Int32 nEqualRows
,
1426 bool bHidden
, bool bFiltered
)
1428 OpenNewRow(nIndex
, nStartRow
, nEqualRows
, bHidden
, bFiltered
);
1430 CloseRow(nStartRow
+ nEqualRows
- 1);
1431 pRowFormatRanges
->Clear();
1434 void ScXMLExport::OpenRow(const sal_Int32 nTable
, const sal_Int32 nStartRow
, const sal_Int32 nRepeatRow
, ScXMLCachedRowAttrAccess
& rRowAttr
)
1438 sal_Int32
nPrevIndex(0), nIndex
;
1439 bool bPrevHidden
= false;
1440 bool bPrevFiltered
= false;
1441 bool bHidden
= false;
1442 bool bFiltered
= false;
1443 sal_Int32
nEqualRows(1);
1444 sal_Int32
nEndRow(nStartRow
+ nRepeatRow
);
1445 sal_Int32 nEndRowHidden
= nStartRow
- 1;
1446 sal_Int32 nEndRowFiltered
= nStartRow
- 1;
1448 for (nRow
= nStartRow
; nRow
< nEndRow
; ++nRow
)
1450 if (nRow
== nStartRow
)
1452 nPrevIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nRow
);
1455 if (nRow
> nEndRowHidden
)
1457 bPrevHidden
= rRowAttr
.rowHidden(nTable
, nRow
, nEndRowHidden
);
1458 bHidden
= bPrevHidden
;
1460 if (nRow
> nEndRowFiltered
)
1462 bPrevFiltered
= rRowAttr
.rowFiltered(nTable
, nRow
, nEndRowFiltered
);
1463 bFiltered
= bPrevFiltered
;
1470 nIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nRow
);
1473 if (nRow
> nEndRowHidden
)
1474 bHidden
= rRowAttr
.rowHidden(nTable
, nRow
, nEndRowHidden
);
1475 if (nRow
> nEndRowFiltered
)
1476 bFiltered
= rRowAttr
.rowFiltered(nTable
, nRow
, nEndRowFiltered
);
1478 if (nIndex
== nPrevIndex
&& bHidden
== bPrevHidden
&& bFiltered
== bPrevFiltered
&&
1479 !(bHasRowHeader
&& ((nRow
== aRowHeaderRange
.aStart
.Row()) || (nRow
- 1 == aRowHeaderRange
.aEnd
.Row()))) &&
1480 !(pGroupRows
->IsGroupStart(nRow
)) &&
1481 !(pGroupRows
->IsGroupEnd(nRow
- 1)))
1485 assert(nPrevIndex
>= 0 && "coverity#1438402");
1486 ScRowFormatRanges
* pTempRowFormatRanges
= new ScRowFormatRanges(pRowFormatRanges
.get());
1487 OpenAndCloseRow(nPrevIndex
, nRow
- nEqualRows
, nEqualRows
, bPrevHidden
, bPrevFiltered
);
1488 pRowFormatRanges
.reset(pTempRowFormatRanges
);
1490 nPrevIndex
= nIndex
;
1491 bPrevHidden
= bHidden
;
1492 bPrevFiltered
= bFiltered
;
1496 assert(nPrevIndex
>= 0 && "coverity#1438402");
1497 OpenNewRow(nPrevIndex
, nRow
- nEqualRows
, nEqualRows
, bPrevHidden
, bPrevFiltered
);
1501 sal_Int32 nIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nStartRow
);
1502 bool bHidden
= false;
1503 bool bFiltered
= false;
1506 sal_Int32 nEndRowHidden
;
1507 sal_Int32 nEndRowFiltered
;
1508 bHidden
= rRowAttr
.rowHidden(nTable
, nStartRow
, nEndRowHidden
);
1509 bFiltered
= rRowAttr
.rowFiltered(nTable
, nStartRow
, nEndRowFiltered
);
1511 assert(nIndex
>= 0 && "coverity#1438402");
1512 OpenNewRow(nIndex
, nStartRow
, 1, bHidden
, bFiltered
);
1514 nOpenRow
= nStartRow
+ nRepeatRow
- 1;
1517 void ScXMLExport::CloseRow(const sal_Int32 nRow
)
1521 EndElement(sElemRow
, true);
1522 if (bHasRowHeader
&& nRow
== aRowHeaderRange
.aEnd
.Row())
1525 bRowHeaderOpen
= false;
1527 if (pGroupRows
->IsGroupEnd(nRow
))
1529 if (bHasRowHeader
&& bRowHeaderOpen
)
1531 pGroupRows
->CloseGroups(nRow
);
1532 if (bHasRowHeader
&& bRowHeaderOpen
)
1539 void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol
, const sal_Int32 nStartRow
,
1540 const sal_Int32 nEndCol
, const sal_Int32 nEndRow
, const sal_Int32 nSheet
)
1542 pRowFormatRanges
->Clear();
1543 ScXMLCachedRowAttrAccess
aRowAttr(pDoc
);
1544 if (nStartRow
== nEndRow
)
1546 pCellStyles
->GetFormatRanges(nStartCol
, nEndCol
, nStartRow
, nSheet
, pRowFormatRanges
.get());
1547 if (nOpenRow
== - 1)
1548 OpenRow(nSheet
, nStartRow
, 1, aRowAttr
);
1550 pRowFormatRanges
->Clear();
1556 pCellStyles
->GetFormatRanges(nStartCol
, pSharedData
->GetLastColumn(nSheet
), nStartRow
, nSheet
, pRowFormatRanges
.get());
1558 CloseRow(nStartRow
);
1560 sal_Int32
nTotalRows(nEndRow
- nStartRow
+ 1 - 1);
1561 while (nRows
< nTotalRows
)
1563 pRowFormatRanges
->Clear();
1564 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1565 sal_Int32 nMaxRows
= pRowFormatRanges
->GetMaxRows();
1566 OSL_ENSURE(nMaxRows
, "something went wrong");
1567 if (nMaxRows
>= nTotalRows
- nRows
)
1569 OpenRow(nSheet
, nStartRow
+ nRows
, nTotalRows
- nRows
, aRowAttr
);
1570 nRows
+= nTotalRows
- nRows
;
1574 OpenRow(nSheet
, nStartRow
+ nRows
, nMaxRows
, aRowAttr
);
1577 if (!pRowFormatRanges
->GetSize())
1578 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1580 CloseRow(nStartRow
+ nRows
- 1);
1582 if (nTotalRows
== 1)
1583 CloseRow(nStartRow
);
1584 OpenRow(nSheet
, nEndRow
, 1, aRowAttr
);
1585 pRowFormatRanges
->Clear();
1586 pCellStyles
->GetFormatRanges(0, nEndCol
, nEndRow
, nSheet
, pRowFormatRanges
.get());
1592 sal_Int32
nTotalRows(nEndRow
- nStartRow
+ 1 - 1);
1593 while (nRows
< nTotalRows
)
1595 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1596 sal_Int32 nMaxRows
= pRowFormatRanges
->GetMaxRows();
1597 OSL_ENSURE(nMaxRows
, "something went wrong");
1598 if (nMaxRows
>= nTotalRows
- nRows
)
1600 OpenRow(nSheet
, nStartRow
+ nRows
, nTotalRows
- nRows
, aRowAttr
);
1601 nRows
+= nTotalRows
- nRows
;
1605 OpenRow(nSheet
, nStartRow
+ nRows
, nMaxRows
, aRowAttr
);
1608 if (!pRowFormatRanges
->GetSize())
1609 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1611 CloseRow(nStartRow
+ nRows
- 1);
1613 OpenRow(nSheet
, nEndRow
, 1, aRowAttr
);
1614 pRowFormatRanges
->Clear();
1615 pCellStyles
->GetFormatRanges(0, nEndCol
, nEndRow
, nSheet
, pRowFormatRanges
.get());
1621 void ScXMLExport::GetColumnRowHeader(bool& rHasColumnHeader
, ScRange
& rColumnHeaderRange
,
1622 bool& rHasRowHeader
, ScRange
& rRowHeaderRange
,
1623 OUString
& rPrintRanges
) const
1625 uno::Reference
<sheet::XPrintAreas
> xPrintAreas (xCurrentTable
, uno::UNO_QUERY
);
1626 if (!xPrintAreas
.is())
1629 rHasRowHeader
= xPrintAreas
->getPrintTitleRows();
1630 rHasColumnHeader
= xPrintAreas
->getPrintTitleColumns();
1631 table::CellRangeAddress rTempRowHeaderRange
= xPrintAreas
->getTitleRows();
1632 rRowHeaderRange
= ScRange(rTempRowHeaderRange
.StartColumn
,
1633 rTempRowHeaderRange
.StartRow
,
1634 rTempRowHeaderRange
.Sheet
,
1635 rTempRowHeaderRange
.EndColumn
,
1636 rTempRowHeaderRange
.EndRow
,
1637 rTempRowHeaderRange
.Sheet
);
1638 table::CellRangeAddress rTempColumnHeaderRange
= xPrintAreas
->getTitleColumns();
1639 rColumnHeaderRange
= ScRange(rTempColumnHeaderRange
.StartColumn
,
1640 rTempColumnHeaderRange
.StartRow
,
1641 rTempColumnHeaderRange
.Sheet
,
1642 rTempColumnHeaderRange
.EndColumn
,
1643 rTempColumnHeaderRange
.EndRow
,
1644 rTempColumnHeaderRange
.Sheet
);
1645 uno::Sequence
< table::CellRangeAddress
> aRangeList( xPrintAreas
->getPrintAreas() );
1646 ScRangeStringConverter::GetStringFromRangeList( rPrintRanges
, aRangeList
, pDoc
, FormulaGrammar::CONV_OOO
);
1649 void ScXMLExport::FillFieldGroup(ScOutlineArray
* pFields
, ScMyOpenCloseColumnRowGroup
* pGroups
)
1651 size_t nDepth
= pFields
->GetDepth();
1652 for (size_t i
= 0; i
< nDepth
; ++i
)
1654 size_t nFields
= pFields
->GetCount(i
);
1655 for (size_t j
= 0; j
< nFields
; ++j
)
1657 ScMyColumnRowGroup aGroup
;
1658 const ScOutlineEntry
* pEntry
= pFields
->GetEntry(i
, j
);
1659 aGroup
.nField
= pEntry
->GetStart();
1660 aGroup
.nLevel
= static_cast<sal_Int16
>(i
);
1661 aGroup
.bDisplay
= !(pEntry
->IsHidden());
1662 pGroups
->AddGroup(aGroup
, pEntry
->GetEnd());
1669 void ScXMLExport::FillColumnRowGroups()
1674 ScOutlineTable
* pOutlineTable
= pDoc
->GetOutlineTable( static_cast<SCTAB
>(nCurrentTable
) );
1677 ScOutlineArray
& rCols(pOutlineTable
->GetColArray());
1678 ScOutlineArray
& rRows(pOutlineTable
->GetRowArray());
1679 FillFieldGroup(&rCols
, pGroupColumns
.get());
1680 FillFieldGroup(&rRows
, pGroupRows
.get());
1681 pSharedData
->SetLastColumn(nCurrentTable
, pGroupColumns
->GetLast());
1682 pSharedData
->SetLastRow(nCurrentTable
, pGroupRows
->GetLast());
1686 void ScXMLExport::SetBodyAttributes()
1688 if (!(pDoc
&& pDoc
->IsDocProtected()))
1691 AddAttribute(XML_NAMESPACE_TABLE
, XML_STRUCTURE_PROTECTED
, XML_TRUE
);
1692 OUStringBuffer aBuffer
;
1693 uno::Sequence
<sal_Int8
> aPassHash
;
1694 ScPasswordHash eHashUsed
= PASSHASH_UNSPECIFIED
;
1695 const ScDocProtection
* p
= pDoc
->GetDocProtection();
1698 if (p
->hasPasswordHash(PASSHASH_SHA1
))
1700 aPassHash
= p
->getPasswordHash(PASSHASH_SHA1
);
1701 eHashUsed
= PASSHASH_SHA1
;
1703 else if (p
->hasPasswordHash(PASSHASH_SHA256
))
1705 aPassHash
= p
->getPasswordHash(PASSHASH_SHA256
);
1706 eHashUsed
= PASSHASH_SHA256
;
1708 else if (p
->hasPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
))
1710 aPassHash
= p
->getPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
);
1711 eHashUsed
= PASSHASH_XL
;
1714 ::comphelper::Base64::encode(aBuffer
, aPassHash
);
1715 if (aBuffer
.isEmpty())
1718 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY
, aBuffer
.makeStringAndClear());
1719 if (getSaneDefaultVersion() < SvtSaveOptions::ODFSVER_012
)
1722 if (eHashUsed
== PASSHASH_XL
)
1724 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1725 ScPassHashHelper::getHashURI(PASSHASH_XL
));
1726 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
1727 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
,
1728 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
1730 else if (eHashUsed
== PASSHASH_SHA1
)
1732 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1733 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
1735 else if (eHashUsed
== PASSHASH_SHA256
)
1737 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1738 ScPassHashHelper::getHashURI(PASSHASH_SHA256
));
1742 static bool lcl_CopyStreamElement( const uno::Reference
< io::XInputStream
>& xInput
,
1743 const uno::Reference
< io::XOutputStream
>& xOutput
,
1746 const sal_Int32 nBufSize
= 16*1024;
1747 uno::Sequence
<sal_Int8
> aSequence(nBufSize
);
1749 sal_Int32 nRemaining
= nCount
;
1752 while ( nRemaining
> 0 )
1754 sal_Int32 nRead
= xInput
->readBytes( aSequence
, std::min( nRemaining
, nBufSize
) );
1757 // safety check: Make sure the copied part actually points to the start of an element
1758 if ( nRead
< 1 || aSequence
[0] != static_cast<sal_Int8
>('<') )
1760 return false; // abort and set an error
1764 if (nRead
== nRemaining
)
1766 // safety check: Make sure the copied part also ends at the end of an element
1767 if ( aSequence
[nRead
-1] != static_cast<sal_Int8
>('>') )
1769 return false; // abort and set an error
1773 if ( nRead
== nBufSize
)
1775 xOutput
->writeBytes( aSequence
);
1776 nRemaining
-= nRead
;
1782 uno::Sequence
<sal_Int8
> aTempBuf( aSequence
.getConstArray(), nRead
);
1783 xOutput
->writeBytes( aTempBuf
);
1788 return true; // successful
1791 static void lcl_SkipBytesInBlocks( const uno::Reference
< io::XInputStream
>& xInput
, sal_Int32 nBytesToSkip
)
1793 // skipBytes in zip stream is implemented as reading.
1794 // For now, split into several calls to avoid allocating a large buffer.
1795 // Later, skipBytes should be changed.
1797 const sal_Int32 nMaxSize
= 32*1024;
1799 if ( nBytesToSkip
> 0 )
1801 sal_Int32 nRemaining
= nBytesToSkip
;
1802 while ( nRemaining
> 0 )
1804 sal_Int32 nSkip
= std::min( nRemaining
, nMaxSize
);
1805 xInput
->skipBytes( nSkip
);
1806 nRemaining
-= nSkip
;
1811 void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset
, sal_Int32 nEndOffset
, sal_Int32
& rNewStart
, sal_Int32
& rNewEnd
)
1813 uno::Reference
<xml::sax::XDocumentHandler
> xHandler
= GetDocHandler();
1814 uno::Reference
<io::XActiveDataSource
> xDestSource( xHandler
, uno::UNO_QUERY
);
1815 if ( !xDestSource
.is() )
1818 uno::Reference
<io::XOutputStream
> xDestStream
= xDestSource
->getOutputStream();
1819 uno::Reference
<io::XSeekable
> xDestSeek( xDestStream
, uno::UNO_QUERY
);
1820 if ( !xDestSeek
.is() )
1823 // temporary: set same stream again to clear buffer
1824 xDestSource
->setOutputStream( xDestStream
);
1826 if ( getExportFlags() & SvXMLExportFlags::PRETTY
)
1828 const OString
aOutStr("\n ");
1829 uno::Sequence
<sal_Int8
> aOutSeq( reinterpret_cast<sal_Int8
const *>(aOutStr
.getStr()), aOutStr
.getLength() );
1830 xDestStream
->writeBytes( aOutSeq
);
1833 rNewStart
= static_cast<sal_Int32
>(xDestSeek
->getPosition());
1835 if ( nStartOffset
> nSourceStreamPos
)
1836 lcl_SkipBytesInBlocks( xSourceStream
, nStartOffset
- nSourceStreamPos
);
1838 if ( !lcl_CopyStreamElement( xSourceStream
, xDestStream
, nEndOffset
- nStartOffset
) )
1840 // If copying went wrong, set an error.
1841 // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
1843 uno::Sequence
<OUString
> aEmptySeq
;
1844 SetError(XMLERROR_CANCEL
|XMLERROR_FLAG_SEVERE
, aEmptySeq
);
1846 nSourceStreamPos
= nEndOffset
;
1848 rNewEnd
= static_cast<sal_Int32
>(xDestSeek
->getPosition());
1851 const ScXMLEditAttributeMap
& ScXMLExport::GetEditAttributeMap() const
1854 mpEditAttrMap
.reset(new ScXMLEditAttributeMap
);
1855 return *mpEditAttrMap
;
1858 void ScXMLExport::RegisterDefinedStyleNames( const uno::Reference
< css::sheet::XSpreadsheetDocument
> & xSpreadDoc
)
1860 ScFormatSaveData
* pFormatData
= comphelper::getFromUnoTunnel
<ScModelObj
>(xSpreadDoc
)->GetFormatSaveData();
1861 auto xAutoStylePool
= GetAutoStylePool();
1862 for (const auto& rFormatInfo
: pFormatData
->maIDToName
)
1864 xAutoStylePool
->RegisterDefinedName(XmlStyleFamily::TABLE_CELL
, rFormatInfo
.second
);
1868 void ScXMLExport::ExportContent_()
1873 SCTAB
nTableCount(0);
1874 sal_Int32
nShapesCount(0);
1875 CollectSharedData(nTableCount
, nShapesCount
);
1876 OSL_FAIL("no shared data set");
1880 ScXMLExportDatabaseRanges
aExportDatabaseRanges(*this);
1881 if (!GetModel().is())
1884 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
1885 if ( !xSpreadDoc
.is() )
1888 ScSheetSaveData
* pSheetData
= comphelper::getFromUnoTunnel
<ScModelObj
>(xSpreadDoc
)->GetSheetSaveData();
1890 pSheetData
->ResetSaveEntries();
1892 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
1895 //_GetNamespaceMap().ClearQNamesCache();
1896 pChangeTrackingExportHelper
->CollectAndWriteChanges();
1897 WriteCalculationSettings(xSpreadDoc
);
1898 sal_Int32
nTableCount(xIndex
->getCount());
1899 ScMyAreaLinksContainer aAreaLinks
;
1900 GetAreaLinks( aAreaLinks
);
1901 ScMyEmptyDatabaseRangesContainer
aEmptyRanges(aExportDatabaseRanges
.GetEmptyDatabaseRanges());
1902 ScMyDetectiveOpContainer aDetectiveOpContainer
;
1903 GetDetectiveOpList( aDetectiveOpContainer
);
1905 pCellStyles
->Sort();
1906 pMergedRangesContainer
->Sort();
1907 pSharedData
->GetDetectiveObjContainer()->Sort();
1909 mpCellsItr
->Clear();
1910 mpCellsItr
->SetShapes( pSharedData
->GetShapesContainer() );
1911 mpCellsItr
->SetNoteShapes( pSharedData
->GetNoteShapes() );
1912 mpCellsItr
->SetMergedRanges( pMergedRangesContainer
.get() );
1913 mpCellsItr
->SetAreaLinks( &aAreaLinks
);
1914 mpCellsItr
->SetEmptyDatabaseRanges( &aEmptyRanges
);
1915 mpCellsItr
->SetDetectiveObj( pSharedData
->GetDetectiveObjContainer() );
1916 mpCellsItr
->SetDetectiveOp( &aDetectiveOpContainer
);
1918 if (nTableCount
> 0)
1919 pValidationsContainer
->WriteValidations(*this);
1920 WriteTheLabelRanges( xSpreadDoc
);
1921 for (sal_Int32 nTable
= 0; nTable
< nTableCount
; ++nTable
)
1923 sal_Int32 nStartOffset
= -1;
1924 sal_Int32 nEndOffset
= -1;
1925 if (pSheetData
&& pDoc
&& pDoc
->IsStreamValid(static_cast<SCTAB
>(nTable
)) && !pDoc
->GetChangeTrack())
1926 pSheetData
->GetStreamPos( nTable
, nStartOffset
, nEndOffset
);
1928 if ( nStartOffset
>= 0 && nEndOffset
>= 0 && xSourceStream
.is() )
1930 sal_Int32 nNewStart
= -1;
1931 sal_Int32 nNewEnd
= -1;
1932 CopySourceStream( nStartOffset
, nEndOffset
, nNewStart
, nNewEnd
);
1934 // store position of copied sheet in output
1935 pSheetData
->AddSavePos( nTable
, nNewStart
, nNewEnd
);
1937 // skip iterator entries for this sheet
1938 mpCellsItr
->SkipTable(static_cast<SCTAB
>(nTable
));
1942 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
1943 WriteTable(nTable
, xTable
);
1945 IncrementProgressBar(false);
1948 WriteExternalRefCaches();
1949 WriteNamedExpressions();
1951 aExportDatabaseRanges
.WriteDatabaseRanges();
1952 WriteExternalDataMapping();
1953 ScXMLExportDataPilot
aExportDataPilot(*this);
1954 aExportDataPilot
.WriteDataPilots();
1955 WriteConsolidation();
1956 ScXMLExportDDELinks
aExportDDELinks(*this);
1957 aExportDDELinks
.WriteDDELinks(xSpreadDoc
);
1958 IncrementProgressBar(true, 0);
1959 GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
1962 void ScXMLExport::ExportStyles_( bool bUsed
)
1964 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
1965 if (xSpreadDoc
.is())
1966 RegisterDefinedStyleNames( xSpreadDoc
);
1970 SCTAB
nTableCount(0);
1971 sal_Int32
nShapesCount(0);
1972 CollectSharedData(nTableCount
, nShapesCount
);
1974 rtl::Reference
<XMLCellStyleExport
> aStylesExp(new XMLCellStyleExport(*this, GetAutoStylePool().get()));
1975 if (GetModel().is())
1977 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
1978 if (xMultiServiceFactory
.is())
1980 uno::Reference
<beans::XPropertySet
> xProperties(xMultiServiceFactory
->createInstance("com.sun.star.sheet.Defaults"), uno::UNO_QUERY
);
1981 if (xProperties
.is())
1982 aStylesExp
->exportDefaultStyle(xProperties
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
, xCellStylesExportPropertySetMapper
);
1983 if (pSharedData
->HasShapes())
1985 GetShapeExport()->ExportGraphicDefaults();
1988 collectDataStyles(false);
1992 aStylesExp
->exportStyleFamily(OUString("CellStyles"),
1993 OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
), xCellStylesExportPropertySetMapper
, false, XmlStyleFamily::TABLE_CELL
);
1995 SvXMLExport::ExportStyles_(bUsed
);
1998 void ScXMLExport::AddStyleFromCells(const uno::Reference
<beans::XPropertySet
>& xProperties
,
1999 const uno::Reference
<sheet::XSpreadsheet
>& xTable
,
2000 sal_Int32 nTable
, const OUString
* pOldName
)
2002 css::uno::Any aAny
= xProperties
->getPropertyValue("FormatID");
2003 sal_uInt64 nKey
= 0;
2006 //! pass xCellRanges instead
2007 uno::Reference
<sheet::XSheetCellRanges
> xCellRanges( xProperties
, uno::UNO_QUERY
);
2009 OUString sStyleName
;
2010 sal_Int32
nNumberFormat(-1);
2011 sal_Int32
nValidationIndex(-1);
2012 std::vector
<XMLPropertyState
> aPropStates(xCellStylesExportPropertySetMapper
->Filter(*this, xProperties
));
2013 std::vector
< XMLPropertyState
>::iterator
aItr(aPropStates
.begin());
2014 std::vector
< XMLPropertyState
>::iterator
aEndItr(aPropStates
.end());
2015 sal_Int32
nCount(0);
2016 while (aItr
!= aEndItr
)
2018 if (aItr
->mnIndex
!= -1)
2020 switch (xCellStylesPropertySetMapper
->GetEntryContextId(aItr
->mnIndex
))
2022 case CTF_SC_VALIDATION
:
2024 pValidationsContainer
->AddValidation(aItr
->maValue
, nValidationIndex
);
2025 // this is not very slow, because it is most the last property or
2026 // if it is not the last property it is the property before the last property,
2027 // so in the worst case only one property has to be copied, but in the best case no
2028 // property has to be copied
2029 aItr
= aPropStates
.erase(aItr
);
2030 aEndItr
= aPropStates
.end(); // old aEndItr is invalidated!
2033 case CTF_SC_CELLSTYLE
:
2035 aItr
->maValue
>>= sStyleName
;
2041 case CTF_SC_NUMBERFORMAT
:
2043 if (aItr
->maValue
>>= nNumberFormat
)
2044 addDataStyle(nNumberFormat
);
2063 if (nCount
== 1) // this is the CellStyle and should be removed if alone
2064 aPropStates
.clear();
2065 if (nNumberFormat
== -1)
2066 xProperties
->getPropertyValue(SC_UNONAME_NUMFMT
) >>= nNumberFormat
;
2067 if (sStyleName
.isEmpty())
2070 if (!aPropStates
.empty())
2075 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, std::move(aPropStates
)))
2077 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_CELL
, *pOldName
);
2078 // add to pCellStyles, so the name is found for normal sheets
2079 pCellStyles
->AddStyleName(*pOldName
, nIndex
);
2085 bool bAdded
= false;
2088 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2089 ScFormatSaveData
* pFormatData
= comphelper::getFromUnoTunnel
<ScModelObj
>(xSpreadDoc
)->GetFormatSaveData();
2090 auto itr
= pFormatData
->maIDToName
.find(nKey
);
2091 if (itr
!= pFormatData
->maIDToName
.end())
2093 sName
= itr
->second
;
2094 bAdded
= GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, aPropStates
);
2096 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_CELL
, sName
);
2099 bool bIsAutoStyle(true);
2100 if (bAdded
|| GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, std::move(aPropStates
)))
2102 pCellStyles
->AddStyleName(sName
, nIndex
);
2105 nIndex
= pCellStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
, bIsAutoStyle
);
2107 const uno::Sequence
<table::CellRangeAddress
> aAddresses(xCellRanges
->getRangeAddresses());
2108 bool bGetMerge(true);
2109 for (table::CellRangeAddress
const & address
: aAddresses
)
2111 pSharedData
->SetLastColumn(nTable
, address
.EndColumn
);
2112 pSharedData
->SetLastRow(nTable
, address
.EndRow
);
2113 pCellStyles
->AddRangeStyleName(address
, nIndex
, bIsAutoStyle
, nValidationIndex
, nNumberFormat
);
2115 bGetMerge
= GetMerged(&address
, xTable
);
2121 OUString
sEncodedStyleName(EncodeStyleName(sStyleName
));
2122 sal_Int32
nIndex(0);
2123 pCellStyles
->AddStyleName(sEncodedStyleName
, nIndex
, false);
2126 const uno::Sequence
<table::CellRangeAddress
> aAddresses(xCellRanges
->getRangeAddresses());
2127 bool bGetMerge(true);
2128 for (table::CellRangeAddress
const & address
: aAddresses
)
2131 bGetMerge
= GetMerged(&address
, xTable
);
2132 pCellStyles
->AddRangeStyleName(address
, nIndex
, false, nValidationIndex
, nNumberFormat
);
2133 if( sStyleName
!= "Default" || nValidationIndex
!= -1 )
2135 pSharedData
->SetLastColumn(nTable
, address
.EndColumn
);
2136 pSharedData
->SetLastRow(nTable
, address
.EndRow
);
2143 void ScXMLExport::AddStyleFromColumn(const uno::Reference
<beans::XPropertySet
>& xColumnProperties
,
2144 const OUString
* pOldName
, sal_Int32
& rIndex
, bool& rIsVisible
)
2146 std::vector
<XMLPropertyState
> aPropStates(xColumnStylesExportPropertySetMapper
->Filter(*this, xColumnProperties
));
2147 if(aPropStates
.empty())
2150 auto aItr
= std::find_if(aPropStates
.begin(), aPropStates
.end(),
2151 [this](const XMLPropertyState
& rPropState
) {
2152 return xColumnStylesPropertySetMapper
->GetEntryContextId(rPropState
.mnIndex
) == CTF_SC_ISVISIBLE
; });
2153 if (aItr
!= aPropStates
.end())
2155 aItr
->maValue
>>= rIsVisible
;
2158 const OUString sParent
;
2161 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_COLUMN
, sParent
, std::move(aPropStates
)))
2163 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_COLUMN
, *pOldName
);
2164 // add to pColumnStyles, so the name is found for normal sheets
2165 rIndex
= pColumnStyles
->AddStyleName(*pOldName
);
2171 if (GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_COLUMN
, sParent
, std::move(aPropStates
)))
2173 rIndex
= pColumnStyles
->AddStyleName(sName
);
2176 rIndex
= pColumnStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX
);
2180 void ScXMLExport::AddStyleFromRow(const uno::Reference
<beans::XPropertySet
>& xRowProperties
,
2181 const OUString
* pOldName
, sal_Int32
& rIndex
)
2183 std::vector
<XMLPropertyState
> aPropStates(xRowStylesExportPropertySetMapper
->Filter(*this, xRowProperties
));
2184 if(aPropStates
.empty())
2187 const OUString sParent
;
2190 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_ROW
, sParent
, std::move(aPropStates
)))
2192 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_ROW
, *pOldName
);
2193 // add to pRowStyles, so the name is found for normal sheets
2194 rIndex
= pRowStyles
->AddStyleName(*pOldName
);
2200 if (GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_ROW
, sParent
, std::move(aPropStates
)))
2202 rIndex
= pRowStyles
->AddStyleName(sName
);
2205 rIndex
= pRowStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX
);
2209 static uno::Any
lcl_GetEnumerated( uno::Reference
<container::XEnumerationAccess
> const & xEnumAccess
, sal_Int32 nIndex
)
2212 uno::Reference
<container::XEnumeration
> xEnum( xEnumAccess
->createEnumeration() );
2215 sal_Int32 nSkip
= nIndex
;
2218 (void) xEnum
->nextElement();
2221 aRet
= xEnum
->nextElement();
2223 catch (container::NoSuchElementException
&)
2230 void ScXMLExport::collectAutoStyles()
2232 SvXMLExport::collectAutoStyles();
2234 if (mbAutoStylesCollected
)
2237 if (!GetModel().is())
2240 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2241 if (!xSpreadDoc
.is())
2244 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
2248 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
2250 // Reserve the loaded cell style names.
2251 RegisterDefinedStyleNames( xSpreadDoc
);
2253 // re-create automatic styles with old names from stored data
2254 ScSheetSaveData
* pSheetData
= comphelper::getFromUnoTunnel
<ScModelObj
>(xSpreadDoc
)->GetSheetSaveData();
2255 if (pSheetData
&& pDoc
)
2257 // formulas have to be calculated now, to detect changed results
2258 // (during normal save, they will be calculated anyway)
2259 SCTAB nTabCount
= pDoc
->GetTableCount();
2260 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
2261 if (pDoc
->IsStreamValid(nTab
))
2262 pDoc
->InterpretDirtyCells(ScRange(0, 0, nTab
, pDoc
->MaxCol(), pDoc
->MaxRow(), nTab
));
2264 // stored cell styles
2265 const std::vector
<ScCellStyleEntry
>& rCellEntries
= pSheetData
->GetCellStyles();
2266 for (const auto& rCellEntry
: rCellEntries
)
2268 ScAddress aPos
= rCellEntry
.maCellPos
;
2269 sal_Int32 nTable
= aPos
.Tab();
2270 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2273 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2274 uno::Reference
<beans::XPropertySet
> xProperties(
2275 xTable
->getCellByPosition( aPos
.Col(), aPos
.Row() ), uno::UNO_QUERY
);
2277 AddStyleFromCells(xProperties
, xTable
, nTable
, &rCellEntry
.maName
);
2281 // stored column styles
2282 const std::vector
<ScCellStyleEntry
>& rColumnEntries
= pSheetData
->GetColumnStyles();
2283 for (const auto& rColumnEntry
: rColumnEntries
)
2285 ScAddress aPos
= rColumnEntry
.maCellPos
;
2286 sal_Int32 nTable
= aPos
.Tab();
2287 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2290 uno::Reference
<table::XColumnRowRange
> xColumnRowRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2291 uno::Reference
<table::XTableColumns
> xTableColumns(xColumnRowRange
->getColumns());
2292 uno::Reference
<beans::XPropertySet
> xColumnProperties(xTableColumns
->getByIndex( aPos
.Col() ), uno::UNO_QUERY
);
2294 sal_Int32
nIndex(-1);
2295 bool bIsVisible(true);
2296 AddStyleFromColumn( xColumnProperties
, &rColumnEntry
.maName
, nIndex
, bIsVisible
);
2300 // stored row styles
2301 const std::vector
<ScCellStyleEntry
>& rRowEntries
= pSheetData
->GetRowStyles();
2302 for (const auto& rRowEntry
: rRowEntries
)
2304 ScAddress aPos
= rRowEntry
.maCellPos
;
2305 sal_Int32 nTable
= aPos
.Tab();
2306 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2309 uno::Reference
<table::XColumnRowRange
> xColumnRowRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2310 uno::Reference
<table::XTableRows
> xTableRows(xColumnRowRange
->getRows());
2311 uno::Reference
<beans::XPropertySet
> xRowProperties(xTableRows
->getByIndex( aPos
.Row() ), uno::UNO_QUERY
);
2313 sal_Int32
nIndex(-1);
2314 AddStyleFromRow( xRowProperties
, &rRowEntry
.maName
, nIndex
);
2318 // stored table styles
2319 const std::vector
<ScCellStyleEntry
>& rTableEntries
= pSheetData
->GetTableStyles();
2320 for (const auto& rTableEntry
: rTableEntries
)
2322 ScAddress aPos
= rTableEntry
.maCellPos
;
2323 sal_Int32 nTable
= aPos
.Tab();
2324 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2327 //! separate method AddStyleFromTable needed?
2328 uno::Reference
<beans::XPropertySet
> xTableProperties(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2329 if (xTableProperties
.is())
2331 std::vector
<XMLPropertyState
> aPropStates(xTableStylesExportPropertySetMapper
->Filter(*this, xTableProperties
));
2332 OUString
sName( rTableEntry
.maName
);
2333 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TABLE_TABLE
, OUString(), std::move(aPropStates
));
2334 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE
, sName
);
2339 // stored styles for notes
2341 rtl::Reference
<SvXMLExportPropertyMapper
> xShapeMapper
= XMLShapeExport::CreateShapePropMapper( *this );
2342 GetShapeExport(); // make sure the graphics styles family is added
2344 const std::vector
<ScNoteStyleEntry
>& rNoteEntries
= pSheetData
->GetNoteStyles();
2345 for (const auto& rNoteEntry
: rNoteEntries
)
2347 ScAddress aPos
= rNoteEntry
.maCellPos
;
2348 SCTAB nTable
= aPos
.Tab();
2349 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2352 //! separate method AddStyleFromNote needed?
2354 ScPostIt
* pNote
= pDoc
->GetNote(aPos
);
2355 OSL_ENSURE( pNote
, "note not found" );
2358 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2359 // all uno shapes are created anyway in CollectSharedData
2360 uno::Reference
<beans::XPropertySet
> xShapeProperties( pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2361 if (xShapeProperties
.is())
2363 if ( !rNoteEntry
.maStyleName
.isEmpty() )
2365 std::vector
<XMLPropertyState
> aPropStates(xShapeMapper
->Filter(*this, xShapeProperties
));
2366 OUString
sName( rNoteEntry
.maStyleName
);
2367 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::SD_GRAPHICS_ID
, OUString(), std::move(aPropStates
));
2368 GetAutoStylePool()->RegisterName(XmlStyleFamily::SD_GRAPHICS_ID
, sName
);
2370 if ( !rNoteEntry
.maTextStyle
.isEmpty() )
2372 std::vector
<XMLPropertyState
> aPropStates(
2373 GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(*this, xShapeProperties
));
2374 OUString
sName( rNoteEntry
.maTextStyle
);
2375 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_PARAGRAPH
, OUString(), std::move(aPropStates
));
2376 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH
, sName
);
2383 // note paragraph styles
2385 rtl::Reference
<SvXMLExportPropertyMapper
> xParaPropMapper
= GetTextParagraphExport()->GetParagraphPropertyMapper();
2387 const std::vector
<ScTextStyleEntry
>& rNoteParaEntries
= pSheetData
->GetNoteParaStyles();
2388 for (const auto& rNoteParaEntry
: rNoteParaEntries
)
2390 ScAddress aPos
= rNoteParaEntry
.maCellPos
;
2391 SCTAB nTable
= aPos
.Tab();
2392 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2395 ScPostIt
* pNote
= pDoc
->GetNote( aPos
);
2396 OSL_ENSURE( pNote
, "note not found" );
2399 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2400 uno::Reference
<container::XEnumerationAccess
> xCellText(pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2401 uno::Reference
<beans::XPropertySet
> xParaProp(
2402 lcl_GetEnumerated( xCellText
, rNoteParaEntry
.maSelection
.nStartPara
), uno::UNO_QUERY
);
2403 if ( xParaProp
.is() )
2405 std::vector
<XMLPropertyState
> aPropStates(xParaPropMapper
->Filter(*this, xParaProp
));
2406 OUString
sName( rNoteParaEntry
.maName
);
2407 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_PARAGRAPH
, OUString(), std::move(aPropStates
));
2408 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH
, sName
);
2416 rtl::Reference
<SvXMLExportPropertyMapper
> xTextPropMapper
= XMLTextParagraphExport::CreateCharExtPropMapper( *this );
2418 const std::vector
<ScTextStyleEntry
>& rNoteTextEntries
= pSheetData
->GetNoteTextStyles();
2419 for (const auto& rNoteTextEntry
: rNoteTextEntries
)
2421 ScAddress aPos
= rNoteTextEntry
.maCellPos
;
2422 SCTAB nTable
= aPos
.Tab();
2423 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2426 ScPostIt
* pNote
= pDoc
->GetNote( aPos
);
2427 OSL_ENSURE( pNote
, "note not found" );
2430 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2431 uno::Reference
<text::XSimpleText
> xCellText(pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2432 uno::Reference
<beans::XPropertySet
> xCursorProp(xCellText
->createTextCursor(), uno::UNO_QUERY
);
2433 ScDrawTextCursor
* pCursor
= comphelper::getFromUnoTunnel
<ScDrawTextCursor
>( xCursorProp
);
2436 pCursor
->SetSelection( rNoteTextEntry
.maSelection
);
2438 std::vector
<XMLPropertyState
> aPropStates(xTextPropMapper
->Filter(*this, xCursorProp
));
2439 OUString
sName( rNoteTextEntry
.maName
);
2440 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_TEXT
, OUString(), std::move(aPropStates
));
2441 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT
, sName
);
2447 // stored text styles
2449 // Calling createTextCursor fires up editeng, which is very slow, and often subsequent style entries
2450 // refer to the same cell, so cache it.
2452 uno::Reference
<beans::XPropertySet
> xPrevCursorProp
;
2453 const std::vector
<ScTextStyleEntry
>& rTextEntries
= pSheetData
->GetTextStyles();
2454 for (const auto& rTextEntry
: rTextEntries
)
2456 ScAddress aPos
= rTextEntry
.maCellPos
;
2457 sal_Int32 nTable
= aPos
.Tab();
2458 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2462 //! separate method AddStyleFromText needed?
2463 //! cache sheet object
2465 uno::Reference
<beans::XPropertySet
> xCursorProp
;
2466 if (xPrevCursorProp
&& aPrevPos
== aPos
)
2467 xCursorProp
= xPrevCursorProp
;
2470 uno::Reference
<table::XCellRange
> xCellRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2471 uno::Reference
<text::XSimpleText
> xCellText(xCellRange
->getCellByPosition(aPos
.Col(), aPos
.Row()), uno::UNO_QUERY
);
2472 xCursorProp
.set(xCellText
->createTextCursor(), uno::UNO_QUERY
);
2474 ScCellTextCursor
* pCursor
= comphelper::getFromUnoTunnel
<ScCellTextCursor
>( xCursorProp
);
2477 pCursor
->SetSelection( rTextEntry
.maSelection
);
2479 std::vector
<XMLPropertyState
> aPropStates(xTextPropMapper
->Filter(*this, xCursorProp
));
2480 OUString
sName( rTextEntry
.maName
);
2481 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_TEXT
, OUString(), std::move(aPropStates
));
2482 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT
, sName
);
2483 xPrevCursorProp
= xCursorProp
;
2488 ExportExternalRefCacheStyles();
2492 SCTAB
nTableCount(0);
2493 sal_Int32
nShapesCount(0);
2494 CollectSharedData(nTableCount
, nShapesCount
);
2496 sal_Int32
nTableCount(xIndex
->getCount());
2497 pCellStyles
->AddNewTable(nTableCount
- 1);
2498 CollectShapesAutoStyles(nTableCount
);
2499 for (sal_Int32 nTable
= 0; nTable
< nTableCount
; ++nTable
, IncrementProgressBar(false))
2501 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2505 // table styles array must be complete, including copied tables - Add should find the stored style
2506 uno::Reference
<beans::XPropertySet
> xTableProperties(xTable
, uno::UNO_QUERY
);
2507 if (xTableProperties
.is())
2509 std::vector
<XMLPropertyState
> aPropStates(xTableStylesExportPropertySetMapper
->Filter(*this, xTableProperties
));
2510 if(!aPropStates
.empty())
2513 GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_TABLE
, OUString(), std::move(aPropStates
));
2514 aTableStyles
.push_back(sName
);
2518 // collect other auto-styles only for non-copied sheets
2519 uno::Reference
<sheet::XUniqueCellFormatRangesSupplier
> xCellFormatRanges ( xTable
, uno::UNO_QUERY
);
2520 if ( xCellFormatRanges
.is() )
2522 uno::Reference
<container::XIndexAccess
> xFormatRangesIndex(xCellFormatRanges
->getUniqueCellFormatRanges());
2523 if (xFormatRangesIndex
.is())
2525 sal_Int32
nFormatRangesCount(xFormatRangesIndex
->getCount());
2526 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount
);
2527 for (sal_Int32 nFormatRange
= 0; nFormatRange
< nFormatRangesCount
; ++nFormatRange
)
2529 uno::Reference
< sheet::XSheetCellRanges
> xCellRanges(xFormatRangesIndex
->getByIndex(nFormatRange
), uno::UNO_QUERY
);
2530 if (xCellRanges
.is())
2532 uno::Reference
<beans::XPropertySet
> xProperties (xCellRanges
, uno::UNO_QUERY
);
2533 if (xProperties
.is())
2535 AddStyleFromCells(xProperties
, xTable
, nTable
, nullptr);
2536 IncrementProgressBar(false);
2542 uno::Reference
<table::XColumnRowRange
> xColumnRowRange (xTable
, uno::UNO_QUERY
);
2543 if (xColumnRowRange
.is() && pDoc
)
2545 pDoc
->SyncColRowFlags();
2546 uno::Reference
<table::XTableColumns
> xTableColumns(xColumnRowRange
->getColumns());
2547 if (xTableColumns
.is())
2549 sal_Int32
nColumns(pDoc
->GetLastChangedColFlagsWidth(sal::static_int_cast
<SCTAB
>(nTable
)));
2550 pSharedData
->SetLastColumn(nTable
, nColumns
);
2551 table::CellRangeAddress
aCellAddress(GetEndAddress(xTable
));
2552 if (aCellAddress
.EndColumn
> nColumns
)
2555 pColumnStyles
->AddNewTable(nTable
, aCellAddress
.EndColumn
);
2558 pColumnStyles
->AddNewTable(nTable
, nColumns
);
2559 sal_Int32 nColumn
= 0;
2560 while (nColumn
<= pDoc
->MaxCol())
2562 sal_Int32
nIndex(-1);
2563 bool bIsVisible(true);
2564 uno::Reference
<beans::XPropertySet
> xColumnProperties(xTableColumns
->getByIndex(nColumn
), uno::UNO_QUERY
);
2565 if (xColumnProperties
.is())
2567 AddStyleFromColumn( xColumnProperties
, nullptr, nIndex
, bIsVisible
);
2568 pColumnStyles
->AddFieldStyleName(nTable
, nColumn
, nIndex
, bIsVisible
);
2570 sal_Int32
nOld(nColumn
);
2571 nColumn
= pDoc
->GetNextDifferentChangedColFlagsWidth(sal::static_int_cast
<SCTAB
>(nTable
), static_cast<SCCOL
>(nColumn
));
2572 for (sal_Int32 i
= nOld
+ 1; i
< nColumn
; ++i
)
2573 pColumnStyles
->AddFieldStyleName(nTable
, i
, nIndex
, bIsVisible
);
2575 if (aCellAddress
.EndColumn
> nColumns
)
2577 bool bIsVisible(true);
2578 sal_Int32
nIndex(pColumnStyles
->GetStyleNameIndex(nTable
, nColumns
, bIsVisible
));
2579 for (sal_Int32 i
= nColumns
+ 1; i
<= aCellAddress
.EndColumn
; ++i
)
2580 pColumnStyles
->AddFieldStyleName(nTable
, i
, nIndex
, bIsVisible
);
2583 uno::Reference
<table::XTableRows
> xTableRows(xColumnRowRange
->getRows());
2584 if (xTableRows
.is())
2586 sal_Int32
nRows(pDoc
->GetLastChangedRowFlagsWidth(sal::static_int_cast
<SCTAB
>(nTable
)));
2587 pSharedData
->SetLastRow(nTable
, nRows
);
2589 pRowStyles
->AddNewTable(nTable
, pDoc
->MaxRow());
2591 while (nRow
<= pDoc
->MaxRow())
2593 sal_Int32 nIndex
= 0;
2594 uno::Reference
<beans::XPropertySet
> xRowProperties(xTableRows
->getByIndex(nRow
), uno::UNO_QUERY
);
2595 if(xRowProperties
.is())
2597 AddStyleFromRow( xRowProperties
, nullptr, nIndex
);
2598 pRowStyles
->AddFieldStyleName(nTable
, nRow
, nIndex
);
2600 sal_Int32
nOld(nRow
);
2601 nRow
= pDoc
->GetNextDifferentChangedRowFlagsWidth(sal::static_int_cast
<SCTAB
>(nTable
), static_cast<SCROW
>(nRow
));
2602 if (nRow
> nOld
+ 1)
2603 pRowStyles
->AddFieldStyleName(nTable
, nOld
+ 1, nIndex
, nRow
- 1);
2607 ExportCellTextAutoStyles(nTable
);
2610 pChangeTrackingExportHelper
->CollectAutoStyles();
2613 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
)
2614 GetPageExport()->collectAutoStyles(true);
2616 mbAutoStylesCollected
= true;
2619 void ScXMLExport::ExportAutoStyles_()
2621 if (!GetModel().is())
2624 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2625 if (!xSpreadDoc
.is())
2628 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
2632 collectAutoStyles();
2634 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
2636 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_COLUMN
);
2637 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_ROW
);
2638 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_TABLE
);
2639 exportAutoDataStyles();
2640 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_CELL
);
2642 GetShapeExport()->exportAutoStyles();
2643 GetFormExport()->exportAutoStyles( );
2647 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
2648 // #i100879# write the table style for cached tables only if there are cached tables
2649 // (same logic as in ExportExternalRefCacheStyles)
2650 if (pRefMgr
->hasExternalData())
2652 // Special table style for the external ref cache tables.
2653 AddAttribute(XML_NAMESPACE_STYLE
, XML_NAME
, sExternalRefTabStyleName
);
2654 AddAttribute(XML_NAMESPACE_STYLE
, XML_FAMILY
, XML_TABLE
);
2655 SvXMLElementExport
aElemStyle(*this, XML_NAMESPACE_STYLE
, XML_STYLE
, true, true);
2656 AddAttribute(XML_NAMESPACE_TABLE
, XML_DISPLAY
, XML_FALSE
);
2657 SvXMLElementExport
aElemStyleTabProps(*this, XML_NAMESPACE_STYLE
, XML_TABLE_PROPERTIES
, true, true);
2662 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
)
2664 exportAutoDataStyles();
2665 GetPageExport()->exportAutoStyles();
2668 // #i30251#; only write Text Styles once
2670 if ((getExportFlags() & SvXMLExportFlags::CONTENT
) || (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
))
2671 GetTextParagraphExport()->exportTextAutoStyles();
2674 void ScXMLExport::ExportMasterStyles_()
2676 GetPageExport()->exportMasterStyles( true );
2679 void ScXMLExport::CollectInternalShape( uno::Reference
< drawing::XShape
> const & xShape
)
2681 // detective objects and notes
2682 SdrObject
* pObject
= SdrObject::getSdrObjectFromXShape( xShape
);
2686 // collect note caption objects from all layers (internal or hidden)
2687 if( ScDrawObjData
* pCaptData
= ScDrawLayer::GetNoteCaptionData( pObject
, static_cast< SCTAB
>( nCurrentTable
) ) )
2689 if(pDoc
->GetNote(pCaptData
->maStart
))
2691 pSharedData
->AddNoteObj( xShape
, pCaptData
->maStart
);
2693 // #i60851# When the file is saved while editing a new note,
2694 // the cell is still empty -> last column/row must be updated
2695 OSL_ENSURE( pCaptData
->maStart
.Tab() == nCurrentTable
, "invalid table in object data" );
2696 pSharedData
->SetLastColumn( nCurrentTable
, pCaptData
->maStart
.Col() );
2697 pSharedData
->SetLastRow( nCurrentTable
, pCaptData
->maStart
.Row() );
2700 // other objects from internal layer only (detective)
2701 else if( pObject
->GetLayer() == SC_LAYER_INTERN
)
2703 ScDetectiveFunc
aDetFunc( *pDoc
, static_cast<SCTAB
>(nCurrentTable
) );
2704 ScAddress aPosition
;
2705 ScRange aSourceRange
;
2707 ScDetectiveObjType eObjType
= aDetFunc
.GetDetectiveObjectType(
2708 pObject
, nCurrentTable
, aPosition
, aSourceRange
, bRedLine
);
2709 pSharedData
->GetDetectiveObjContainer()->AddObject( eObjType
, static_cast<SCTAB
>(nCurrentTable
), aPosition
, aSourceRange
, bRedLine
);
2713 bool ScXMLExport::GetMerged (const table::CellRangeAddress
* pCellAddress
,
2714 const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
2717 sal_Int32
nRow(pCellAddress
->StartRow
);
2718 sal_Int32
nCol(pCellAddress
->StartColumn
);
2719 sal_Int32
nEndRow(pCellAddress
->EndRow
);
2720 sal_Int32
nEndCol(pCellAddress
->EndColumn
);
2721 bool bRowInc(nEndRow
> nRow
);
2722 while(!bReady
&& nRow
<= nEndRow
&& nCol
<= nEndCol
)
2724 uno::Reference
<sheet::XSheetCellRange
> xSheetCellRange(xTable
->getCellRangeByPosition(nCol
, nRow
, nCol
, nRow
), uno::UNO_QUERY
);
2725 if (xSheetCellRange
.is())
2727 uno::Reference
<sheet::XSheetCellCursor
> xCursor(xTable
->createCursorByRange(xSheetCellRange
));
2730 uno::Reference
<sheet::XCellRangeAddressable
> xCellAddress (xCursor
, uno::UNO_QUERY
);
2731 xCursor
->collapseToMergedArea();
2732 table::CellRangeAddress
aCellAddress2(xCellAddress
->getRangeAddress());
2733 ScRange
aScRange( aCellAddress2
.StartColumn
, aCellAddress2
.StartRow
, aCellAddress2
.Sheet
,
2734 aCellAddress2
.EndColumn
, aCellAddress2
.EndRow
, aCellAddress2
.Sheet
);
2736 if ((aScRange
.aEnd
.Row() > nRow
||
2737 aScRange
.aEnd
.Col() > nCol
) &&
2738 aScRange
.aStart
.Row() == nRow
&&
2739 aScRange
.aStart
.Col() == nCol
)
2741 pMergedRangesContainer
->AddRange(aScRange
);
2742 pSharedData
->SetLastColumn(aScRange
.aEnd
.Tab(), aScRange
.aEnd
.Col());
2743 pSharedData
->SetLastRow(aScRange
.aEnd
.Tab(), aScRange
.aEnd
.Row());
2757 OSL_ENSURE(!(!bReady
&& nEndRow
> nRow
&& nEndCol
> nCol
), "should not be possible");
2761 bool ScXMLExport::IsMatrix (const ScAddress
& aCell
,
2762 ScRange
& aCellAddress
, bool& bIsFirst
) const
2766 ScRange aMatrixRange
;
2768 if (pDoc
&& pDoc
->GetMatrixFormulaRange(aCell
, aMatrixRange
))
2770 aCellAddress
= aMatrixRange
;
2771 if ((aCellAddress
.aStart
.Col() == aCell
.Col() && aCellAddress
.aStart
.Row() == aCell
.Row()) &&
2772 (aCellAddress
.aEnd
.Col() > aCell
.Col() || aCellAddress
.aEnd
.Row() > aCell
.Row()))
2777 else if (aCellAddress
.aStart
.Col() != aCell
.Col() || aCellAddress
.aStart
.Row() != aCell
.Row() ||
2778 aCellAddress
.aEnd
.Col() != aCell
.Col() || aCellAddress
.aEnd
.Row()!= aCell
.Row())
2790 void ScXMLExport::WriteTable(sal_Int32 nTable
, const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
2795 xCurrentTable
.set(xTable
);
2796 uno::Reference
<container::XNamed
> xName (xTable
, uno::UNO_QUERY
);
2800 nCurrentTable
= sal::static_int_cast
<sal_uInt16
>( nTable
);
2801 OUString
sOUTableName(xName
->getName());
2802 AddAttribute(sAttrName
, sOUTableName
);
2803 AddAttribute(sAttrStyleName
, aTableStyles
[nTable
]);
2805 uno::Reference
<util::XProtectable
> xProtectable (xTable
, uno::UNO_QUERY
);
2806 const ScTableProtection
* pProtect
= nullptr;
2807 if (xProtectable
.is() && xProtectable
->isProtected())
2809 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
2812 pProtect
= pDoc
->GetTabProtection(nTable
);
2815 OUStringBuffer aBuffer
;
2816 ScPasswordHash eHashUsed
= PASSHASH_UNSPECIFIED
;
2817 if (pProtect
->hasPasswordHash(PASSHASH_SHA1
))
2819 ::comphelper::Base64::encode(aBuffer
,
2820 pProtect
->getPasswordHash(PASSHASH_SHA1
));
2821 eHashUsed
= PASSHASH_SHA1
;
2823 else if (pProtect
->hasPasswordHash(PASSHASH_SHA256
))
2825 ::comphelper::Base64::encode(aBuffer
,
2826 pProtect
->getPasswordHash(PASSHASH_SHA256
));
2827 eHashUsed
= PASSHASH_SHA256
;
2829 else if (pProtect
->hasPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
))
2831 // Double-hash this by SHA1 on top of the legacy xls hash.
2832 uno::Sequence
<sal_Int8
> aHash
= pProtect
->getPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
);
2833 ::comphelper::Base64::encode(aBuffer
, aHash
);
2834 eHashUsed
= PASSHASH_XL
;
2836 if (!aBuffer
.isEmpty())
2838 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY
, aBuffer
.makeStringAndClear());
2839 if (getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
2841 if (eHashUsed
== PASSHASH_XL
)
2843 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2844 ScPassHashHelper::getHashURI(PASSHASH_XL
));
2845 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2846 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
,
2847 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
2849 else if (eHashUsed
== PASSHASH_SHA1
)
2851 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2852 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
2854 else if (eHashUsed
== PASSHASH_SHA256
)
2856 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2857 ScPassHashHelper::getHashURI(PASSHASH_SHA256
));
2864 OUString sPrintRanges
;
2865 ScRange aColumnHeaderRange
;
2866 bool bHasColumnHeader
;
2867 GetColumnRowHeader(bHasColumnHeader
, aColumnHeaderRange
, bHasRowHeader
, aRowHeaderRange
, sPrintRanges
);
2868 if( !sPrintRanges
.isEmpty() )
2869 AddAttribute( XML_NAMESPACE_TABLE
, XML_PRINT_RANGES
, sPrintRanges
);
2870 else if (pDoc
&& !pDoc
->IsPrintEntireSheet(static_cast<SCTAB
>(nTable
)))
2871 AddAttribute( XML_NAMESPACE_TABLE
, XML_PRINT
, XML_FALSE
);
2872 SvXMLElementExport
aElemT(*this, sElemTab
, true, true);
2874 if (pProtect
&& pProtect
->isProtected() && getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2876 if (pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
))
2877 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SELECT_PROTECTED_CELLS
, XML_TRUE
);
2878 if (pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
))
2879 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SELECT_UNPROTECTED_CELLS
, XML_TRUE
);
2881 if (pProtect
->isOptionEnabled(ScTableProtection::INSERT_COLUMNS
))
2882 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_INSERT_COLUMNS
, XML_TRUE
);
2883 if (pProtect
->isOptionEnabled(ScTableProtection::INSERT_ROWS
))
2884 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_INSERT_ROWS
, XML_TRUE
);
2886 if (pProtect
->isOptionEnabled(ScTableProtection::DELETE_COLUMNS
))
2887 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DELETE_COLUMNS
, XML_TRUE
);
2888 if (pProtect
->isOptionEnabled(ScTableProtection::DELETE_ROWS
))
2889 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DELETE_ROWS
, XML_TRUE
);
2891 OUString aElemName
= GetNamespaceMap().GetQNameByKey(
2892 XML_NAMESPACE_LO_EXT
, GetXMLToken(XML_TABLE_PROTECTION
));
2894 SvXMLElementExport
aElemProtected(*this, aElemName
, true, true);
2899 if ( pDoc
&& pDoc
->GetSheetEvents( static_cast<SCTAB
>(nTable
) ) &&
2900 getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
2902 // store sheet events
2903 uno::Reference
<document::XEventsSupplier
> xSupplier(xTable
, uno::UNO_QUERY
);
2904 uno::Reference
<container::XNameAccess
> xEvents
= xSupplier
->getEvents();
2905 GetEventExport().ExportExt( xEvents
);
2910 uno::Reference
<drawing::XDrawPage
> xDrawPage
;
2911 if (pSharedData
->HasForm(nTable
, xDrawPage
) && xDrawPage
.is())
2913 ::xmloff::OOfficeFormsExport
aForms(*this);
2914 GetFormExport()->exportForms( xDrawPage
);
2915 bool bRet(GetFormExport()->seekPage( xDrawPage
));
2916 OSL_ENSURE( bRet
, "OFormLayerXMLExport::seekPage failed!" );
2918 if (pSharedData
->HasDrawPage())
2920 GetShapeExport()->seekShapes(pSharedData
->GetDrawPage(nTable
));
2923 table::CellRangeAddress
aRange(GetEndAddress(xTable
));
2924 pSharedData
->SetLastColumn(nTable
, aRange
.EndColumn
);
2925 pSharedData
->SetLastRow(nTable
, aRange
.EndRow
);
2926 mpCellsItr
->SetCurrentTable(static_cast<SCTAB
>(nTable
), xCurrentTable
);
2927 pGroupColumns
->NewTable();
2928 pGroupRows
->NewTable();
2929 FillColumnRowGroups();
2930 if (bHasColumnHeader
)
2931 pSharedData
->SetLastColumn(nTable
, aColumnHeaderRange
.aEnd
.Col());
2932 bRowHeaderOpen
= false;
2934 pSharedData
->SetLastRow(nTable
, aRowHeaderRange
.aEnd
.Row());
2935 pDefaults
->FillDefaultStyles(nTable
, pSharedData
->GetLastRow(nTable
),
2936 pSharedData
->GetLastColumn(nTable
), pCellStyles
.get(), pDoc
);
2937 pRowFormatRanges
->SetColDefaults(&pDefaults
->GetColDefaults());
2938 pCellStyles
->SetColDefaults(&pDefaults
->GetColDefaults());
2939 ExportColumns(nTable
, aColumnHeaderRange
, bHasColumnHeader
);
2940 bool bIsFirst(true);
2941 sal_Int32
nEqualCells(0);
2944 while (mpCellsItr
->GetNext(aCell
, pCellStyles
.get()))
2948 ExportFormatRanges(0, 0, aCell
.maCellAddress
.Col()-1, aCell
.maCellAddress
.Row(), nTable
);
2954 if ((aPrevCell
.maCellAddress
.Row() == aCell
.maCellAddress
.Row()) &&
2955 (aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1 == aCell
.maCellAddress
.Col()))
2957 if(IsCellEqual(aPrevCell
, aCell
))
2961 WriteCell(aPrevCell
, nEqualCells
);
2968 WriteCell(aPrevCell
, nEqualCells
);
2969 ExportFormatRanges(aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1, aPrevCell
.maCellAddress
.Row(),
2970 aCell
.maCellAddress
.Col()-1, aCell
.maCellAddress
.Row(), nTable
);
2978 WriteCell(aPrevCell
, nEqualCells
);
2979 ExportFormatRanges(aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1, aPrevCell
.maCellAddress
.Row(),
2980 pSharedData
->GetLastColumn(nTable
), pSharedData
->GetLastRow(nTable
), nTable
);
2983 ExportFormatRanges(0, 0, pSharedData
->GetLastColumn(nTable
), pSharedData
->GetLastRow(nTable
), nTable
);
2985 CloseRow(pSharedData
->GetLastRow(nTable
));
2990 // Export sheet-local named ranges.
2991 ScRangeName
* pRangeName
= pDoc
->GetRangeName(nTable
);
2992 if (pRangeName
&& !pRangeName
->empty())
2994 WriteNamedRange(pRangeName
);
2997 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2999 //export new conditional format information
3000 ExportConditionalFormat(nTable
);
3001 exportSparklineGroups(nTable
);
3008 ScXMLExport
& rExport
, const OUString
& rStyleName
, const OUString
& rContent
, const SvxFieldData
* pField
)
3010 std::unique_ptr
<SvXMLElementExport
> pElem
;
3011 if (!rStyleName
.isEmpty())
3013 // Formatted section with automatic style.
3014 rExport
.AddAttribute(XML_NAMESPACE_TEXT
, XML_STYLE_NAME
, rStyleName
);
3015 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3016 XML_NAMESPACE_TEXT
, GetXMLToken(XML_SPAN
));
3017 pElem
.reset(new SvXMLElementExport(rExport
, aElemName
, false, false));
3022 // Write a field item.
3023 OUString aFieldVal
= ScEditUtil::GetCellFieldValue(*pField
, rExport
.GetDocument(), nullptr);
3024 switch (pField
->GetClassId())
3026 case text::textfield::Type::URL
:
3028 // <text:a xlink:href="url" xlink:type="simple">value</text:a>
3030 const SvxURLField
* pURLField
= static_cast<const SvxURLField
*>(pField
);
3031 const OUString
& aURL
= pURLField
->GetURL();
3032 rExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, rExport
.GetRelativeReference(aURL
));
3033 rExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, "simple");
3034 const OUString
& aTargetFrame
= pURLField
->GetTargetFrame();
3035 if (!aTargetFrame
.isEmpty())
3036 rExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_TARGET_FRAME_NAME
, aTargetFrame
);
3038 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3039 XML_NAMESPACE_TEXT
, GetXMLToken(XML_A
));
3040 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3041 rExport
.Characters(aFieldVal
);
3044 case text::textfield::Type::DATE
:
3046 // <text:date style:data-style-name="N2" text:date-value="YYYY-MM-DD">value</text:date>
3048 Date
aDate(Date::SYSTEM
);
3049 OUStringBuffer aBuf
;
3050 sal_Int32 nVal
= aDate
.GetYear();
3053 nVal
= aDate
.GetMonth();
3058 nVal
= aDate
.GetDay();
3062 rExport
.AddAttribute(XML_NAMESPACE_STYLE
, XML_DATA_STYLE_NAME
, "N2");
3063 rExport
.AddAttribute(XML_NAMESPACE_TEXT
, XML_DATE_VALUE
, aBuf
.makeStringAndClear());
3065 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3066 XML_NAMESPACE_TEXT
, GetXMLToken(XML_DATE
));
3067 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3068 rExport
.Characters(aFieldVal
);
3071 case text::textfield::Type::DOCINFO_TITLE
:
3073 // <text:title>value</text:title>
3075 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3076 XML_NAMESPACE_TEXT
, GetXMLToken(XML_TITLE
));
3077 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3078 rExport
.Characters(aFieldVal
);
3081 case text::textfield::Type::TABLE
:
3083 // <text:sheet-name>value</text:sheet-name>
3085 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3086 XML_NAMESPACE_TEXT
, GetXMLToken(XML_SHEET_NAME
));
3087 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3088 rExport
.Characters(aFieldVal
);
3092 rExport
.Characters(aFieldVal
);
3096 rExport
.Characters(rContent
);
3099 void flushParagraph(
3100 ScXMLExport
& rExport
, std::u16string_view rParaText
,
3101 rtl::Reference
<XMLPropertySetMapper
> const & xMapper
, rtl::Reference
<SvXMLAutoStylePoolP
> const & xStylePool
,
3102 const ScXMLEditAttributeMap
& rAttrMap
,
3103 std::vector
<editeng::Section
>::const_iterator it
, std::vector
<editeng::Section
>::const_iterator
const & itEnd
)
3105 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3106 XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
3107 SvXMLElementExport
aElemP(rExport
, aElemName
, false, false);
3109 for (; it
!= itEnd
; ++it
)
3111 const editeng::Section
& rSec
= *it
;
3113 OUString
aContent(rParaText
.substr(rSec
.mnStart
, rSec
.mnEnd
- rSec
.mnStart
));
3115 std::vector
<XMLPropertyState
> aPropStates
;
3116 const SvxFieldData
* pField
= toXMLPropertyStates(rExport
, aPropStates
, rSec
.maAttributes
, xMapper
, rAttrMap
);
3117 OUString aStyleName
= xStylePool
->Find(XmlStyleFamily::TEXT_TEXT
, OUString(), aPropStates
);
3118 if (aContent
== "\x001" && !pField
)
3120 for (const SfxPoolItem
* p
: rSec
.maAttributes
)
3122 if (p
->Which() == EE_FEATURE_TAB
)
3124 SvXMLElementExport
Tab(rExport
, XML_NAMESPACE_TEXT
, XML_TAB
, false, false);
3130 writeContent(rExport
, aStyleName
, aContent
, pField
);
3136 void ScXMLExport::WriteCell(ScMyCell
& aCell
, sal_Int32 nEqualCellCount
)
3138 // nEqualCellCount is the number of additional cells
3139 SetRepeatAttribute(nEqualCellCount
, (aCell
.nType
!= table::CellContentType_EMPTY
));
3141 if (aCell
.nStyleIndex
!= -1)
3142 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(aCell
.nStyleIndex
, aCell
.bIsAutoStyle
));
3143 if (aCell
.nValidationIndex
> -1)
3144 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(aCell
.nValidationIndex
));
3145 const bool bIsFirstMatrixCell(aCell
.bIsMatrixBase
);
3146 if (bIsFirstMatrixCell
)
3148 SCCOL
nColumns( aCell
.aMatrixRange
.aEnd
.Col() - aCell
.aMatrixRange
.aStart
.Col() + 1 );
3149 SCROW
nRows( aCell
.aMatrixRange
.aEnd
.Row() - aCell
.aMatrixRange
.aStart
.Row() + 1 );
3150 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_MATRIX_COLUMNS_SPANNED
, OUString::number(nColumns
));
3151 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_MATRIX_ROWS_SPANNED
, OUString::number(nRows
));
3153 bool bIsEmpty(false);
3154 switch (aCell
.nType
)
3156 case table::CellContentType_EMPTY
:
3161 case table::CellContentType_VALUE
:
3163 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3164 aCell
.nNumberFormat
, aCell
.maBaseCell
.getDouble());
3165 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3166 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3167 aCell
.nNumberFormat
, aCell
.maBaseCell
.getDouble(), false, XML_NAMESPACE_CALC_EXT
, false);
3170 case table::CellContentType_TEXT
:
3172 OUString
sFormattedString(lcl_GetFormattedString(pDoc
, aCell
.maBaseCell
, aCell
.maCellAddress
));
3173 OUString sCellString
= aCell
.maBaseCell
.getString(pDoc
);
3174 bool bExportValue
= sCellString
.indexOf('\x001') == -1;
3175 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3176 sCellString
, sFormattedString
, bExportValue
);
3177 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3178 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3179 sCellString
, sFormattedString
, false, XML_NAMESPACE_CALC_EXT
);
3182 case table::CellContentType_FORMULA
:
3184 if (aCell
.maBaseCell
.getType() == CELLTYPE_FORMULA
)
3186 const bool bIsMatrix(bIsFirstMatrixCell
|| aCell
.bIsMatrixCovered
);
3187 ScFormulaCell
* pFormulaCell
= aCell
.maBaseCell
.getFormula();
3188 if (!bIsMatrix
|| bIsFirstMatrixCell
)
3190 if (!mpCompileFormulaCxt
)
3192 const formula::FormulaGrammar::Grammar eGrammar
= pDoc
->GetStorageGrammar();
3193 mpCompileFormulaCxt
.reset(new sc::CompileFormulaContext(*pDoc
, eGrammar
));
3196 OUString aFormula
= pFormulaCell
->GetFormula(*mpCompileFormulaCxt
);
3197 sal_uInt16 nNamespacePrefix
=
3198 (mpCompileFormulaCxt
->getGrammar() == formula::FormulaGrammar::GRAM_ODFF
? XML_NAMESPACE_OF
: XML_NAMESPACE_OOOC
);
3202 AddAttribute(sAttrFormula
, GetNamespaceMap().GetQNameByKey(nNamespacePrefix
, aFormula
, false));
3206 AddAttribute(sAttrFormula
, GetNamespaceMap().GetQNameByKey(nNamespacePrefix
, aFormula
.copy(1, aFormula
.getLength()-2), false));
3209 if (pFormulaCell
->GetErrCode() != FormulaError::NONE
)
3211 AddAttribute(sAttrValueType
, XML_STRING
);
3212 AddAttribute(sAttrStringValue
, aCell
.maBaseCell
.getString(pDoc
));
3213 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3215 //export calcext:value-type="error"
3216 AddAttribute(XML_NAMESPACE_CALC_EXT
,XML_VALUE_TYPE
, OUString("error"));
3219 else if (pFormulaCell
->IsValue())
3223 GetNumberFormatAttributesExportHelper()->GetCellType(aCell
.nNumberFormat
, sCurrency
, bIsStandard
);
3226 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3227 aCell
.nNumberFormat
, pDoc
->GetValue(aCell
.maCellAddress
));
3228 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3230 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3231 aCell
.nNumberFormat
, pDoc
->GetValue(aCell
.maCellAddress
), false, XML_NAMESPACE_CALC_EXT
, false );
3237 if (!aCell
.maBaseCell
.getString(pDoc
).isEmpty())
3239 AddAttribute(sAttrValueType
, XML_STRING
);
3240 AddAttribute(sAttrStringValue
, aCell
.maBaseCell
.getString(pDoc
));
3241 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3243 AddAttribute(XML_NAMESPACE_CALC_EXT
,XML_VALUE_TYPE
, XML_STRING
);
3253 OUString
* pCellString(&sElemCell
);
3254 if (aCell
.bIsCovered
)
3256 pCellString
= &sElemCoveredCell
;
3260 if (aCell
.bIsMergedBase
)
3262 SCCOL
nColumns( aCell
.aMergeRange
.aEnd
.Col() - aCell
.aMergeRange
.aStart
.Col() + 1 );
3263 SCROW
nRows( aCell
.aMergeRange
.aEnd
.Row() - aCell
.aMergeRange
.aStart
.Row() + 1 );
3264 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_SPANNED
, OUString::number(nColumns
));
3265 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_SPANNED
, OUString::number(nRows
));
3268 SvXMLElementExport
aElemC(*this, *pCellString
, true, true);
3270 WriteAreaLink(aCell
);
3271 WriteAnnotation(aCell
);
3272 WriteDetective(aCell
);
3276 if (aCell
.maBaseCell
.getType() == CELLTYPE_EDIT
)
3278 WriteEditCell(aCell
.maBaseCell
.getEditText());
3280 else if (aCell
.maBaseCell
.getType() == CELLTYPE_FORMULA
&& aCell
.maBaseCell
.getFormula()->IsMultilineResult())
3282 WriteMultiLineFormulaResult(aCell
.maBaseCell
.getFormula());
3286 SvXMLElementExport
aElemP(*this, sElemP
, true, false);
3289 ScCellFormat::GetOutputString(*pDoc
, aCell
.maCellAddress
, aCell
.maBaseCell
);
3291 bool bPrevCharWasSpace
= true;
3292 GetTextParagraphExport()->exportCharacterData(aParaStr
, bPrevCharWasSpace
);
3297 IncrementProgressBar(false);
3300 void ScXMLExport::WriteEditCell(const EditTextObject
* pText
)
3302 rtl::Reference
<XMLPropertySetMapper
> xMapper
= GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
3303 rtl::Reference
<SvXMLAutoStylePoolP
> xStylePool
= GetAutoStylePool();
3304 const ScXMLEditAttributeMap
& rAttrMap
= GetEditAttributeMap();
3306 // Get raw paragraph texts first.
3307 std::vector
<OUString
> aParaTexts
;
3308 sal_Int32 nParaCount
= pText
->GetParagraphCount();
3309 aParaTexts
.reserve(nParaCount
);
3310 for (sal_Int32 i
= 0; i
< nParaCount
; ++i
)
3311 aParaTexts
.push_back(pText
->GetText(i
));
3313 // Get all section data and iterate through them.
3314 std::vector
<editeng::Section
> aAttrs
;
3315 pText
->GetAllSections(aAttrs
);
3316 std::vector
<editeng::Section
>::const_iterator itSec
= aAttrs
.begin(), itSecEnd
= aAttrs
.end();
3317 std::vector
<editeng::Section
>::const_iterator itPara
= itSec
;
3318 sal_Int32 nCurPara
= 0; // current paragraph
3319 for (; itSec
!= itSecEnd
; ++itSec
)
3321 const editeng::Section
& rSec
= *itSec
;
3322 if (nCurPara
== rSec
.mnParagraph
)
3323 // Still in the same paragraph.
3326 // Start of a new paragraph. Flush the old paragraph.
3327 flushParagraph(*this, aParaTexts
[nCurPara
], xMapper
, xStylePool
, rAttrMap
, itPara
, itSec
);
3328 nCurPara
= rSec
.mnParagraph
;
3332 flushParagraph(*this, aParaTexts
[nCurPara
], xMapper
, xStylePool
, rAttrMap
, itPara
, itSecEnd
);
3335 void ScXMLExport::WriteMultiLineFormulaResult(const ScFormulaCell
* pCell
)
3337 OUString aElemName
= GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
3339 OUString aResStr
= pCell
->GetResultString().getString();
3340 const sal_Unicode
* p
= aResStr
.getStr();
3341 const sal_Unicode
* pEnd
= p
+ static_cast<size_t>(aResStr
.getLength());
3342 const sal_Unicode
* pPara
= p
; // paragraph head.
3343 for (; p
!= pEnd
; ++p
)
3348 // flush the paragraph.
3353 aContent
= OUString(pPara
, p
-pPara
);
3355 SvXMLElementExport
aElem(*this, aElemName
, false, false);
3356 Characters(aContent
);
3365 aContent
= OUString(pPara
, pEnd
-pPara
);
3367 SvXMLElementExport
aElem(*this, aElemName
, false, false);
3368 Characters(aContent
);
3371 void ScXMLExport::ExportShape(const uno::Reference
< drawing::XShape
>& xShape
, awt::Point
* pPoint
)
3373 uno::Reference
< beans::XPropertySet
> xShapeProps ( xShape
, uno::UNO_QUERY
);
3374 bool bIsChart( false );
3375 if (xShapeProps
.is())
3377 sal_Int32 nZOrder
= 0;
3378 if (xShapeProps
->getPropertyValue("ZOrder") >>= nZOrder
)
3380 AddAttribute(XML_NAMESPACE_DRAW
, XML_ZINDEX
, OUString::number(nZOrder
));
3382 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
= xShapeProps
->getPropertySetInfo();
3383 OUString
sPropCLSID ("CLSID");
3384 if( xPropSetInfo
->hasPropertyByName( sPropCLSID
) )
3387 if (xShapeProps
->getPropertyValue( sPropCLSID
) >>= sCLSID
)
3389 if ( sCLSID
.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) )
3395 OUString aChartName
;
3396 xShapeProps
->getPropertyValue( "PersistName" ) >>= aChartName
;
3397 ScChartListenerCollection
* pCollection
= pDoc
->GetChartListenerCollection();
3400 ScChartListener
* pListener
= pCollection
->findByName(aChartName
);
3403 const ScRangeListRef
& rRangeList
= pListener
->GetRangeList();
3404 if ( rRangeList
.is() )
3406 ScRangeStringConverter::GetStringFromRangeList( sRanges
, rRangeList
.get(), pDoc
, FormulaGrammar::CONV_OOO
);
3407 if ( !sRanges
.isEmpty() )
3410 rtl::Reference
<SvXMLAttributeList
> pAttrList
= new SvXMLAttributeList();
3411 pAttrList
->AddAttribute(
3412 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW
, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES
) ), sRanges
);
3413 GetShapeExport()->exportShape( xShape
, SEF_DEFAULT
, pPoint
, pAttrList
.get() );
3420 if ( sRanges
.isEmpty() )
3422 uno::Reference
< frame::XModel
> xChartModel
;
3423 if( ( xShapeProps
->getPropertyValue( "Model" ) >>= xChartModel
) &&
3426 uno::Reference
< chart2::XChartDocument
> xChartDoc( xChartModel
, uno::UNO_QUERY
);
3427 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartModel
, uno::UNO_QUERY
);
3428 if( xChartDoc
.is() && xReceiver
.is() &&
3429 ! xChartDoc
->hasInternalDataProvider())
3431 // we have a chart that gets its data from Calc
3433 uno::Sequence
< OUString
> aRepresentations(
3434 xReceiver
->getUsedRangeRepresentations());
3435 rtl::Reference
<SvXMLAttributeList
> pAttrList
;
3438 if (aRepresentations
.hasElements())
3440 // add the ranges used by the chart to the shape
3441 // element to be able to start listening after
3442 // load (when the chart is not yet loaded)
3443 uno::Reference
< chart2::data::XRangeXMLConversion
> xRangeConverter( xChartDoc
->getDataProvider(), uno::UNO_QUERY
);
3444 sRanges
= lcl_RangeSequenceToString( aRepresentations
, xRangeConverter
);
3445 pAttrList
= new SvXMLAttributeList();
3446 pAttrList
->AddAttribute(
3447 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW
, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES
) ), sRanges
);
3450 catch (const lang::IllegalArgumentException
&)
3452 TOOLS_WARN_EXCEPTION("sc", "Exception in lcl_RangeSequenceToString - invalid range?");
3454 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
, pPoint
, pAttrList
.get());
3463 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
, pPoint
);
3465 IncrementProgressBar(false);
3468 void ScXMLExport::WriteShapes(const ScMyCell
& rMyCell
)
3470 if( !(rMyCell
.bHasShape
&& !rMyCell
.aShapeList
.empty() && pDoc
) )
3473 // Reference point to turn absolute coordinates in reference point + offset. That happens in most
3474 // cases in XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint, which gets the absolute
3475 // coordinates as translation from matrix in property "Transformation". For cell anchored shapes
3476 // the reference point is left-top (in LTR mode) of that cell, which contains the shape.
3477 tools::Rectangle aCellRectFull
= pDoc
->GetMMRect(
3478 rMyCell
.maCellAddress
.Col(), rMyCell
.maCellAddress
.Row(), rMyCell
.maCellAddress
.Col(),
3479 rMyCell
.maCellAddress
.Row(), rMyCell
.maCellAddress
.Tab(), false /*bHiddenAsZero*/);
3481 bool bNegativePage
= pDoc
->IsNegativePage(rMyCell
.maCellAddress
.Tab());
3483 aPoint
.X
= aCellRectFull
.Right();
3485 aPoint
.X
= aCellRectFull
.Left();
3486 aPoint
.Y
= aCellRectFull
.Top();
3488 for (const auto& rShape
: rMyCell
.aShapeList
)
3490 if (rShape
.xShape
.is())
3492 // The current object geometry is based on bHiddenAsZero=true, but ODF file format
3493 // needs it as if there were no hidden rows or columns. We manipulate the geometry
3494 // accordingly for writing xml markup and restore geometry later.
3495 bool bNeedsRestore
= false;
3496 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(rShape
.xShape
);
3497 // Remember original geometry
3498 std::unique_ptr
<SdrObjGeoData
> pGeoData
;
3500 pGeoData
= pObj
->GetGeoData();
3502 // Hiding row or column affects the shape based on its snap rect. So we need start and
3503 // end cell address of snap rect. In case of a transformed shape, it is not in rMyCell.
3504 ScAddress aSnapStartAddress
= rMyCell
.maCellAddress
;
3505 ScDrawObjData
* pObjData
= nullptr;
3508 pObjData
= ScDrawLayer::GetObjData(pObj
);
3510 aSnapStartAddress
= pObjData
->maStart
;
3513 // In case rows or columns are hidden above or before the snap rect, move the shape to the
3514 // position it would have, if these rows and columns are visible.
3515 tools::Rectangle aRectFull
= pDoc
->GetMMRect(
3516 aSnapStartAddress
.Col(), aSnapStartAddress
.Row(), aSnapStartAddress
.Col(),
3517 aSnapStartAddress
.Row(), aSnapStartAddress
.Tab(), false /*bHiddenAsZero*/);
3518 tools::Rectangle aRectReduced
= pDoc
->GetMMRect(
3519 aSnapStartAddress
.Col(), aSnapStartAddress
.Row(), aSnapStartAddress
.Col(),
3520 aSnapStartAddress
.Row(), aSnapStartAddress
.Tab(), true /*bHiddenAsZero*/);
3521 const tools::Long
nLeftDiff(aRectFull
.Left() - aRectReduced
.Left());
3522 const tools::Long
nTopDiff(aRectFull
.Top() - aRectReduced
.Top());
3523 if (pObj
&& (abs(nLeftDiff
) > 1 || abs(nTopDiff
) > 1))
3525 bNeedsRestore
= true;
3526 pObj
->NbcMove(Size(nLeftDiff
, nTopDiff
));
3529 // tdf#137033 In case the shape is anchored "To Cell (resize with cell)" hiding rows or
3530 // columns inside the snap rect has not only changed size of the shape but rotate and shear
3531 // angle too. We resize the shape to full size. That will recover the original angles too.
3532 if (rShape
.bResizeWithCell
&& pObjData
) // implies pObj & aSnapStartAddress = pObjData->maStart
3534 // Get original size from anchor
3535 const Point aSnapStartOffset
= pObjData
->maStartOffset
;
3536 // In case of 'resize with cell' maEnd and maEndOffset should be valid.
3537 const ScAddress
aSnapEndAddress(pObjData
->maEnd
);
3538 const Point aSnapEndOffset
= pObjData
->maEndOffset
;
3539 const tools::Rectangle aStartCellRect
= pDoc
->GetMMRect(
3540 aSnapStartAddress
.Col(), aSnapStartAddress
.Row(), aSnapStartAddress
.Col(),
3541 aSnapStartAddress
.Row(), aSnapStartAddress
.Tab(), false /*bHiddenAsZero*/);
3542 const tools::Rectangle aEndCellRect
= pDoc
->GetMMRect(
3543 aSnapEndAddress
.Col(), aSnapEndAddress
.Row(), aSnapEndAddress
.Col(),
3544 aSnapEndAddress
.Row(), aSnapEndAddress
.Tab(), false /*bHiddenAsZero*/);
3547 aRectFull
.SetLeft(aEndCellRect
.Right() - aSnapEndOffset
.X());
3548 aRectFull
.SetRight(aStartCellRect
.Right() - aSnapStartOffset
.X());
3552 aRectFull
.SetLeft(aStartCellRect
.Left() + aSnapStartOffset
.X());
3553 aRectFull
.SetRight(aEndCellRect
.Left() + aSnapEndOffset
.X());
3555 aRectFull
.SetTop(aStartCellRect
.Top() + aSnapStartOffset
.Y());
3556 aRectFull
.SetBottom(aEndCellRect
.Top() + aSnapEndOffset
.Y());
3557 aRectReduced
= pObjData
->getShapeRect();
3558 if(abs(aRectFull
.getOpenWidth() - aRectReduced
.getOpenWidth()) > 1
3559 || abs(aRectFull
.getOpenHeight() - aRectReduced
.getOpenHeight()) > 1)
3561 bNeedsRestore
= true;
3562 Fraction
aScaleWidth(aRectFull
.getOpenWidth(), aRectReduced
.getOpenWidth());
3563 if (!aScaleWidth
.IsValid())
3564 aScaleWidth
= Fraction(1.0);
3565 Fraction
aScaleHeight(aRectFull
.getOpenHeight(), aRectReduced
.getOpenHeight());
3566 if (!aScaleHeight
.IsValid())
3567 aScaleHeight
= Fraction(1.0);
3568 pObj
->NbcResize(pObj
->GetRelativePos(), aScaleWidth
, aScaleHeight
);
3572 // We only write the end address if we want the shape to resize with the cell
3573 if ( rShape
.bResizeWithCell
&&
3574 rShape
.xShape
->getShapeType() != "com.sun.star.drawing.CaptionShape" )
3576 OUString sEndAddress
;
3577 ScRangeStringConverter::GetStringFromAddress(sEndAddress
, rShape
.aEndAddress
, pDoc
, FormulaGrammar::CONV_OOO
);
3578 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_CELL_ADDRESS
, sEndAddress
);
3579 OUStringBuffer sBuffer
;
3580 GetMM100UnitConverter().convertMeasureToXML(
3581 sBuffer
, rShape
.nEndX
);
3582 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_X
, sBuffer
.makeStringAndClear());
3583 GetMM100UnitConverter().convertMeasureToXML(
3584 sBuffer
, rShape
.nEndY
);
3585 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_Y
, sBuffer
.makeStringAndClear());
3588 // Correct above calculated reference point for some cases:
3589 // a) For a RTL-sheet translate from matrix is not suitable, because the shape
3590 // from xml (which is always LTR) is not mirrored to negative page but shifted.
3591 // b) In case of horizontal mirrored, 'resize with cell' anchored custom shape, translate
3592 // has wrong values. FixMe: Why is translate wrong?
3593 // c) Measure lines do not use transformation matrix but use start and end point directly.
3594 ScDrawObjData
* pNRObjData
= nullptr;
3595 if (pObj
&& bNegativePage
3596 && rShape
.xShape
->getShapeType() == "com.sun.star.drawing.MeasureShape")
3598 // inverse of shift when import
3599 tools::Rectangle aSnapRect
= pObj
->GetSnapRect();
3600 aPoint
.X
= aSnapRect
.Left() + aSnapRect
.Right() - aPoint
.X
;
3602 else if (pObj
&& (pNRObjData
= ScDrawLayer::GetNonRotatedObjData(pObj
))
3603 && ((rShape
.bResizeWithCell
&& pObj
->GetObjIdentifier() == SdrObjKind::CustomShape
3604 && static_cast<SdrObjCustomShape
*>(pObj
)->IsMirroredX())
3607 //In these cases we set reference Point = matrix translate - startOffset.
3608 awt::Point aMatrixTranslate
= rShape
.xShape
->getPosition();
3609 aPoint
.X
= aMatrixTranslate
.X
- pNRObjData
->maStartOffset
.X();
3610 aPoint
.Y
= aMatrixTranslate
.Y
- pNRObjData
->maStartOffset
.Y();
3613 ExportShape(rShape
.xShape
, &aPoint
);
3615 // Restore object geometry
3616 if (bNeedsRestore
&& pObj
&& pGeoData
)
3617 pObj
->SetGeoData(*pGeoData
);
3622 void ScXMLExport::WriteTableShapes()
3624 ScMyTableShapes
* pTableShapes(pSharedData
->GetTableShapes());
3625 if (!pTableShapes
|| (*pTableShapes
)[nCurrentTable
].empty())
3628 OSL_ENSURE(pTableShapes
->size() > static_cast<size_t>(nCurrentTable
), "wrong Table");
3629 SvXMLElementExport
aShapesElem(*this, XML_NAMESPACE_TABLE
, XML_SHAPES
, true, false);
3630 for (const auto& rxShape
: (*pTableShapes
)[nCurrentTable
])
3634 if (pDoc
->IsNegativePage(static_cast<SCTAB
>(nCurrentTable
)))
3636 // RTL-mirroring refers to snap rectangle, not to logic rectangle, therefore cannot use
3637 // getPosition() and getSize(), but need property "FrameRect" from rxShape or
3638 // GetSnapRect() from associated SdrObject.
3639 uno::Reference
<beans::XPropertySet
> xShapeProp(rxShape
, uno::UNO_QUERY
);
3640 awt::Rectangle aFrameRect
;
3641 if (xShapeProp
.is() && (xShapeProp
->getPropertyValue("FrameRect") >>= aFrameRect
))
3643 // file format uses shape in LTR mode. newLeft = - oldRight = - (oldLeft + width).
3644 // newTranslate = oldTranslate - refPoint, oldTranslate from transformation matrix,
3645 // calculated in XMLShapeExport::exportShape common for all modules.
3646 // oldTranslate.X = oldLeft ==> refPoint.X = 2 * oldLeft + width
3647 awt::Point aRefPoint
;
3648 aRefPoint
.X
= 2 * aFrameRect
.X
+ aFrameRect
.Width
- 1;
3650 ExportShape(rxShape
, &aRefPoint
);
3652 // else should not happen
3655 ExportShape(rxShape
, nullptr);
3658 (*pTableShapes
)[nCurrentTable
].clear();
3661 void ScXMLExport::WriteAreaLink( const ScMyCell
& rMyCell
)
3663 if( !rMyCell
.bHasAreaLink
)
3666 const ScMyAreaLink
& rAreaLink
= rMyCell
.aAreaLink
;
3667 AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, rAreaLink
.sSourceStr
);
3668 AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3669 AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(rAreaLink
.sURL
) );
3670 AddAttribute( XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, rAreaLink
.sFilter
);
3671 if( !rAreaLink
.sFilterOptions
.isEmpty() )
3672 AddAttribute( XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, rAreaLink
.sFilterOptions
);
3673 AddAttribute( XML_NAMESPACE_TABLE
, XML_LAST_COLUMN_SPANNED
, OUString::number(rAreaLink
.GetColCount()) );
3674 AddAttribute( XML_NAMESPACE_TABLE
, XML_LAST_ROW_SPANNED
, OUString::number(rAreaLink
.GetRowCount()) );
3675 if( rAreaLink
.nRefreshDelaySeconds
)
3677 OUStringBuffer sValue
;
3678 ::sax::Converter::convertDuration( sValue
,
3679 static_cast<double>(rAreaLink
.nRefreshDelaySeconds
) / 86400 );
3680 AddAttribute( XML_NAMESPACE_TABLE
, XML_REFRESH_DELAY
, sValue
.makeStringAndClear() );
3682 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_CELL_RANGE_SOURCE
, true, true );
3685 void ScXMLExport::exportAnnotationMeta( const uno::Reference
< drawing::XShape
>& xShape
)
3687 ScPostIt
* pNote
= pCurrentCell
->pNote
;
3693 //is it still useful, as this call back is only called from ScXMLExport::WriteAnnotation
3694 // and should be in sync with pCurrentCell
3695 SdrCaptionObj
* pNoteCaption
= pNote
->GetOrCreateCaption(pCurrentCell
->maCellAddress
);
3696 uno::Reference
<drawing::XShape
> xCurrentShape( pNoteCaption
->getUnoShape(), uno::UNO_QUERY
);
3697 if (xCurrentShape
.get()!=xShape
.get())
3700 const OUString
& sAuthor(pNote
->GetAuthor());
3701 if (!sAuthor
.isEmpty())
3703 SvXMLElementExport
aCreatorElem( *this, XML_NAMESPACE_DC
,
3706 Characters(sAuthor
);
3709 const OUString
& aDate(pNote
->GetDate());
3712 SvNumberFormatter
* pNumForm
= pDoc
->GetFormatTable();
3714 sal_uInt32 nfIndex
= pNumForm
->GetFormatIndex(NF_DATE_SYS_DDMMYYYY
, LANGUAGE_SYSTEM
);
3715 if (pNumForm
->IsNumberFormat(aDate
, nfIndex
, fDate
))
3717 OUStringBuffer sBuf
;
3718 GetMM100UnitConverter().convertDateTime(sBuf
, fDate
,true);
3719 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_DC
,
3722 Characters(sBuf
.makeStringAndClear());
3726 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_META
,
3727 XML_DATE_STRING
, true,
3734 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_META
,
3735 XML_DATE_STRING
, true,
3741 void ScXMLExport::WriteAnnotation(const ScMyCell
& rMyCell
)
3743 ScPostIt
* pNote
= pDoc
->GetNote(rMyCell
.maCellAddress
);
3747 if (pNote
->IsCaptionShown())
3748 AddAttribute(XML_NAMESPACE_OFFICE
, XML_DISPLAY
, XML_TRUE
);
3750 pCurrentCell
= &rMyCell
;
3752 SdrCaptionObj
* pNoteCaption
= pNote
->GetOrCreateCaption(rMyCell
.maCellAddress
);
3755 uno::Reference
<drawing::XShape
> xShape( pNoteCaption
->getUnoShape(), uno::UNO_QUERY
);
3757 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
|XMLShapeExportFlags::ANNOTATION
);
3760 pCurrentCell
= nullptr;
3763 void ScXMLExport::WriteDetective( const ScMyCell
& rMyCell
)
3765 if( !(rMyCell
.bHasDetectiveObj
|| rMyCell
.bHasDetectiveOp
) )
3768 const ScMyDetectiveObjVec
& rObjVec
= rMyCell
.aDetectiveObjVec
;
3769 const ScMyDetectiveOpVec
& rOpVec
= rMyCell
.aDetectiveOpVec
;
3770 sal_Int32
nObjCount(rObjVec
.size());
3771 sal_Int32
nOpCount(rOpVec
.size());
3772 if( !(nObjCount
|| nOpCount
) )
3775 SvXMLElementExport
aDetElem( *this, XML_NAMESPACE_TABLE
, XML_DETECTIVE
, true, true );
3777 for(const auto& rObj
: rObjVec
)
3779 if (rObj
.eObjType
!= SC_DETOBJ_CIRCLE
)
3781 if( (rObj
.eObjType
== SC_DETOBJ_ARROW
) || (rObj
.eObjType
== SC_DETOBJ_TOOTHERTAB
))
3783 ScRangeStringConverter::GetStringFromRange( sString
, rObj
.aSourceRange
, pDoc
, FormulaGrammar::CONV_OOO
);
3784 AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, sString
);
3786 sString
= ScXMLConverter::GetStringFromDetObjType( rObj
.eObjType
);
3787 AddAttribute( XML_NAMESPACE_TABLE
, XML_DIRECTION
, sString
);
3788 if( rObj
.bHasError
)
3789 AddAttribute( XML_NAMESPACE_TABLE
, XML_CONTAINS_ERROR
, XML_TRUE
);
3792 AddAttribute( XML_NAMESPACE_TABLE
, XML_MARKED_INVALID
, XML_TRUE
);
3793 SvXMLElementExport
aRangeElem( *this, XML_NAMESPACE_TABLE
, XML_HIGHLIGHTED_RANGE
, true, true );
3795 for(const auto& rOp
: rOpVec
)
3797 OUString sOpString
= ScXMLConverter::GetStringFromDetOpType( rOp
.eOpType
);
3798 AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, sOpString
);
3799 AddAttribute( XML_NAMESPACE_TABLE
, XML_INDEX
, OUString::number(rOp
.nIndex
) );
3800 SvXMLElementExport
aRangeElem( *this, XML_NAMESPACE_TABLE
, XML_OPERATION
, true, true );
3804 void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount
, bool bIncProgress
)
3806 // nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1
3807 if (nEqualCellCount
> 0)
3809 sal_Int32
nTemp(nEqualCellCount
+ 1);
3810 OUString
sOUEqualCellCount(OUString::number(nTemp
));
3811 AddAttribute(sAttrColumnsRepeated
, sOUEqualCellCount
);
3813 IncrementProgressBar(false, nEqualCellCount
);
3817 bool ScXMLExport::IsEditCell(const ScMyCell
& rCell
)
3819 return rCell
.maBaseCell
.getType() == CELLTYPE_EDIT
;
3822 bool ScXMLExport::IsCellEqual (const ScMyCell
& aCell1
, const ScMyCell
& aCell2
)
3824 bool bIsEqual
= false;
3825 if( !aCell1
.bIsMergedBase
&& !aCell2
.bIsMergedBase
&&
3826 aCell1
.bIsCovered
== aCell2
.bIsCovered
&&
3827 !aCell1
.bIsMatrixBase
&& !aCell2
.bIsMatrixBase
&&
3828 aCell1
.bIsMatrixCovered
== aCell2
.bIsMatrixCovered
&&
3829 aCell1
.bHasAnnotation
== aCell2
.bHasAnnotation
&&
3830 !aCell1
.bHasShape
&& !aCell2
.bHasShape
&&
3831 aCell1
.bHasAreaLink
== aCell2
.bHasAreaLink
&&
3832 !aCell1
.bHasDetectiveObj
&& !aCell2
.bHasDetectiveObj
)
3834 if( (aCell1
.bHasAreaLink
&&
3835 (aCell1
.aAreaLink
.GetColCount() == 1) &&
3836 (aCell2
.aAreaLink
.GetColCount() == 1) &&
3837 aCell1
.aAreaLink
.Compare( aCell2
.aAreaLink
) ) ||
3838 !aCell1
.bHasAreaLink
)
3840 if (!aCell1
.bHasAnnotation
)
3842 if ((((aCell1
.nStyleIndex
== aCell2
.nStyleIndex
) && (aCell1
.bIsAutoStyle
== aCell2
.bIsAutoStyle
)) ||
3843 ((aCell1
.nStyleIndex
== aCell2
.nStyleIndex
) && (aCell1
.nStyleIndex
== -1))) &&
3844 aCell1
.nValidationIndex
== aCell2
.nValidationIndex
&&
3845 aCell1
.nType
== aCell2
.nType
)
3847 switch ( aCell1
.nType
)
3849 case table::CellContentType_EMPTY
:
3854 case table::CellContentType_VALUE
:
3856 // #i29101# number format may be different from column default styles,
3857 // but can lead to different value types, so it must also be compared
3858 bIsEqual
= (aCell1
.nNumberFormat
== aCell2
.nNumberFormat
) &&
3859 (aCell1
.maBaseCell
.getDouble() == aCell2
.maBaseCell
.getDouble());
3862 case table::CellContentType_TEXT
:
3864 if (IsEditCell(aCell1
) || IsEditCell(aCell2
))
3868 bIsEqual
= (aCell1
.maBaseCell
.getString(pDoc
) == aCell2
.maBaseCell
.getString(pDoc
));
3872 case table::CellContentType_FORMULA
:
3890 void ScXMLExport::WriteCalculationSettings(const uno::Reference
<sheet::XSpreadsheetDocument
>& xSpreadDoc
)
3892 uno::Reference
<beans::XPropertySet
> xPropertySet(xSpreadDoc
, uno::UNO_QUERY
);
3893 if (!xPropertySet
.is())
3896 bool bCalcAsShown (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_CALCASSHOWN
) ));
3897 bool bIgnoreCase (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_IGNORECASE
) ));
3898 bool bLookUpLabels (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_LOOKUPLABELS
) ));
3899 bool bMatchWholeCell (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_MATCHWHOLE
) ));
3900 bool bUseRegularExpressions (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_REGEXENABLED
) ));
3901 bool bUseWildcards (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_WILDCARDSENABLED
) ));
3902 if (bUseWildcards
&& bUseRegularExpressions
)
3903 bUseRegularExpressions
= false; // mutually exclusive, wildcards take precedence
3904 bool bIsIterationEnabled (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_ITERENABLED
) ));
3905 sal_uInt16
nYear2000 (pDoc
? pDoc
->GetDocOptions().GetYear2000() : 0);
3906 sal_Int32
nIterationCount(100);
3907 xPropertySet
->getPropertyValue( SC_UNO_ITERCOUNT
) >>= nIterationCount
;
3908 double fIterationEpsilon
= 0;
3909 xPropertySet
->getPropertyValue( SC_UNO_ITEREPSILON
) >>= fIterationEpsilon
;
3910 util::Date aNullDate
;
3911 xPropertySet
->getPropertyValue( SC_UNO_NULLDATE
) >>= aNullDate
;
3912 if (!(bCalcAsShown
|| bIgnoreCase
|| !bLookUpLabels
|| !bMatchWholeCell
|| !bUseRegularExpressions
||
3914 bIsIterationEnabled
|| nIterationCount
!= 100 || !::rtl::math::approxEqual(fIterationEpsilon
, 0.001) ||
3915 aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899 || nYear2000
!= 1930))
3919 AddAttribute(XML_NAMESPACE_TABLE
, XML_CASE_SENSITIVE
, XML_FALSE
);
3921 AddAttribute(XML_NAMESPACE_TABLE
, XML_PRECISION_AS_SHOWN
, XML_TRUE
);
3922 if (!bMatchWholeCell
)
3923 AddAttribute(XML_NAMESPACE_TABLE
, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL
, XML_FALSE
);
3925 AddAttribute(XML_NAMESPACE_TABLE
, XML_AUTOMATIC_FIND_LABELS
, XML_FALSE
);
3926 if (!bUseRegularExpressions
)
3927 AddAttribute(XML_NAMESPACE_TABLE
, XML_USE_REGULAR_EXPRESSIONS
, XML_FALSE
);
3929 AddAttribute(XML_NAMESPACE_TABLE
, XML_USE_WILDCARDS
, XML_TRUE
);
3930 if (nYear2000
!= 1930)
3932 AddAttribute(XML_NAMESPACE_TABLE
, XML_NULL_YEAR
, OUString::number(nYear2000
));
3934 SvXMLElementExport
aCalcSettings(*this, XML_NAMESPACE_TABLE
, XML_CALCULATION_SETTINGS
, true, true);
3936 if (aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899)
3938 OUStringBuffer sDate
;
3939 SvXMLUnitConverter::convertDateTime(sDate
, 0.0, aNullDate
);
3940 AddAttribute(XML_NAMESPACE_TABLE
, XML_DATE_VALUE
, sDate
.makeStringAndClear());
3941 SvXMLElementExport
aElemNullDate(*this, XML_NAMESPACE_TABLE
, XML_NULL_DATE
, true, true);
3943 if (bIsIterationEnabled
|| nIterationCount
!= 100 || !::rtl::math::approxEqual(fIterationEpsilon
, 0.001))
3945 if (bIsIterationEnabled
)
3946 AddAttribute(XML_NAMESPACE_TABLE
, XML_STATUS
, XML_ENABLE
);
3947 if (nIterationCount
!= 100)
3949 AddAttribute(XML_NAMESPACE_TABLE
, XML_STEPS
, OUString::number(nIterationCount
));
3951 if (!::rtl::math::approxEqual(fIterationEpsilon
, 0.001))
3953 OUStringBuffer sBuffer
;
3954 ::sax::Converter::convertDouble(sBuffer
,
3956 AddAttribute(XML_NAMESPACE_TABLE
, XML_MAXIMUM_DIFFERENCE
, sBuffer
.makeStringAndClear());
3958 SvXMLElementExport
aElemIteration(*this, XML_NAMESPACE_TABLE
, XML_ITERATION
, true, true);
3963 void ScXMLExport::WriteTableSource()
3965 uno::Reference
<sheet::XSheetLinkable
> xLinkable (xCurrentTable
, uno::UNO_QUERY
);
3966 if (!(xLinkable
.is() && GetModel().is()))
3969 sheet::SheetLinkMode
nMode (xLinkable
->getLinkMode());
3970 if (nMode
== sheet::SheetLinkMode_NONE
)
3973 OUString
sLink (xLinkable
->getLinkUrl());
3974 uno::Reference
<beans::XPropertySet
> xProps (GetModel(), uno::UNO_QUERY
);
3978 uno::Reference
<container::XIndexAccess
> xIndex(xProps
->getPropertyValue(SC_UNO_SHEETLINKS
), uno::UNO_QUERY
);
3982 sal_Int32
nCount(xIndex
->getCount());
3987 uno::Reference
<beans::XPropertySet
> xLinkProps
;
3988 for (sal_Int32 i
= 0; (i
< nCount
) && !bFound
; ++i
)
3990 xLinkProps
.set(xIndex
->getByIndex(i
), uno::UNO_QUERY
);
3991 if (xLinkProps
.is())
3994 if (xLinkProps
->getPropertyValue(SC_UNONAME_LINKURL
) >>= sNewLink
)
3995 bFound
= sLink
== sNewLink
;
3998 if (!(bFound
&& xLinkProps
.is()))
4002 OUString sFilterOptions
;
4003 OUString
sTableName (xLinkable
->getLinkSheetName());
4004 sal_Int32
nRefresh(0);
4005 xLinkProps
->getPropertyValue(SC_UNONAME_FILTER
) >>= sFilter
;
4006 xLinkProps
->getPropertyValue(SC_UNONAME_FILTOPT
) >>= sFilterOptions
;
4007 xLinkProps
->getPropertyValue(SC_UNONAME_REFDELAY
) >>= nRefresh
;
4008 if (sLink
.isEmpty())
4011 AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
4012 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(sLink
));
4013 if (!sTableName
.isEmpty())
4014 AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_NAME
, sTableName
);
4015 if (!sFilter
.isEmpty())
4016 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, sFilter
);
4017 if (!sFilterOptions
.isEmpty())
4018 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, sFilterOptions
);
4019 if (nMode
!= sheet::SheetLinkMode_NORMAL
)
4020 AddAttribute(XML_NAMESPACE_TABLE
, XML_MODE
, XML_COPY_RESULTS_ONLY
);
4023 OUStringBuffer sBuffer
;
4024 ::sax::Converter::convertDuration( sBuffer
,
4025 static_cast<double>(nRefresh
) / 86400 );
4026 AddAttribute( XML_NAMESPACE_TABLE
, XML_REFRESH_DELAY
, sBuffer
.makeStringAndClear() );
4028 SvXMLElementExport
aSourceElem(*this, XML_NAMESPACE_TABLE
, XML_TABLE_SOURCE
, true, true);
4031 // core implementation
4032 void ScXMLExport::WriteScenario()
4034 if (!(pDoc
&& pDoc
->IsScenario(static_cast<SCTAB
>(nCurrentTable
))))
4039 ScScenarioFlags nFlags
;
4040 pDoc
->GetScenarioData(static_cast<SCTAB
>(nCurrentTable
), sComment
, aColor
, nFlags
);
4041 if (!(nFlags
& ScScenarioFlags::ShowFrame
))
4042 AddAttribute(XML_NAMESPACE_TABLE
, XML_DISPLAY_BORDER
, XML_FALSE
);
4043 OUStringBuffer aBuffer
;
4044 ::sax::Converter::convertColor(aBuffer
, aColor
);
4045 AddAttribute(XML_NAMESPACE_TABLE
, XML_BORDER_COLOR
, aBuffer
.makeStringAndClear());
4046 if (!(nFlags
& ScScenarioFlags::TwoWay
))
4047 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_BACK
, XML_FALSE
);
4048 if (!(nFlags
& ScScenarioFlags::Attrib
))
4049 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_STYLES
, XML_FALSE
);
4050 if (nFlags
& ScScenarioFlags::Value
)
4051 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_FORMULAS
, XML_FALSE
);
4052 if (nFlags
& ScScenarioFlags::Protected
)
4053 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
4054 ::sax::Converter::convertBool(aBuffer
,
4055 pDoc
->IsActiveScenario(static_cast<SCTAB
>(nCurrentTable
)));
4056 AddAttribute(XML_NAMESPACE_TABLE
, XML_IS_ACTIVE
, aBuffer
.makeStringAndClear());
4057 const ScRangeList
* pRangeList
= pDoc
->GetScenarioRanges(static_cast<SCTAB
>(nCurrentTable
));
4058 OUString sRangeListStr
;
4059 ScRangeStringConverter::GetStringFromRangeList( sRangeListStr
, pRangeList
, pDoc
, FormulaGrammar::CONV_OOO
);
4060 AddAttribute(XML_NAMESPACE_TABLE
, XML_SCENARIO_RANGES
, sRangeListStr
);
4061 if (!sComment
.isEmpty())
4062 AddAttribute(XML_NAMESPACE_TABLE
, XML_COMMENT
, sComment
);
4063 SvXMLElementExport
aElem(*this, XML_NAMESPACE_TABLE
, XML_SCENARIO
, true, true);
4066 void ScXMLExport::WriteTheLabelRanges( const uno::Reference
< sheet::XSpreadsheetDocument
>& xSpreadDoc
)
4068 uno::Reference
< beans::XPropertySet
> xDocProp( xSpreadDoc
, uno::UNO_QUERY
);
4069 if( !xDocProp
.is() ) return;
4071 sal_Int32
nCount(0);
4072 uno::Reference
< container::XIndexAccess
> xColRangesIAccess(xDocProp
->getPropertyValue( SC_UNO_COLLABELRNG
), uno::UNO_QUERY
);
4073 if( xColRangesIAccess
.is() )
4074 nCount
+= xColRangesIAccess
->getCount();
4076 uno::Reference
< container::XIndexAccess
> xRowRangesIAccess(xDocProp
->getPropertyValue( SC_UNO_ROWLABELRNG
), uno::UNO_QUERY
);
4077 if( xRowRangesIAccess
.is() )
4078 nCount
+= xRowRangesIAccess
->getCount();
4082 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_LABEL_RANGES
, true, true );
4083 WriteLabelRanges( xColRangesIAccess
, true );
4084 WriteLabelRanges( xRowRangesIAccess
, false );
4088 void ScXMLExport::WriteLabelRanges( const uno::Reference
< container::XIndexAccess
>& xRangesIAccess
, bool bColumn
)
4090 if( !xRangesIAccess
.is() ) return;
4092 sal_Int32
nCount(xRangesIAccess
->getCount());
4093 for( sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
4095 uno::Reference
< sheet::XLabelRange
> xRange(xRangesIAccess
->getByIndex( nIndex
), uno::UNO_QUERY
);
4099 table::CellRangeAddress
aCellRange( xRange
->getLabelArea() );
4100 ScRangeStringConverter::GetStringFromRange( sRangeStr
, aCellRange
, pDoc
, FormulaGrammar::CONV_OOO
);
4101 AddAttribute( XML_NAMESPACE_TABLE
, XML_LABEL_CELL_RANGE_ADDRESS
, sRangeStr
);
4102 aCellRange
= xRange
->getDataArea();
4103 ScRangeStringConverter::GetStringFromRange( sRangeStr
, aCellRange
, pDoc
, FormulaGrammar::CONV_OOO
);
4104 AddAttribute( XML_NAMESPACE_TABLE
, XML_DATA_CELL_RANGE_ADDRESS
, sRangeStr
);
4105 AddAttribute( XML_NAMESPACE_TABLE
, XML_ORIENTATION
, bColumn
? XML_COLUMN
: XML_ROW
);
4106 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_LABEL_RANGE
, true, true );
4111 void ScXMLExport::WriteNamedExpressions()
4115 ScRangeName
* pNamedRanges
= pDoc
->GetRangeName();
4116 WriteNamedRange(pNamedRanges
);
4119 void ScXMLExport::WriteExternalDataMapping()
4124 if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
4125 // Export this only for 1.2 extended and above.
4128 sc::ExternalDataMapper
& rDataMapper
= pDoc
->GetExternalDataMapper();
4129 auto& rDataSources
= rDataMapper
.getDataSources();
4131 if (rDataSources
.empty())
4134 SvXMLElementExport
aMappings(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_MAPPINGS
, true, true);
4135 for (const auto& itr
: rDataSources
)
4137 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, itr
.getURL());
4138 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_PROVIDER
, itr
.getProvider());
4139 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_DATA_FREQUENCY
, OUString::number(sc::ExternalDataSource::getUpdateFrequency()));
4140 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_ID
, itr
.getID());
4141 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_DATABASE_NAME
, itr
.getDBName());
4143 SvXMLElementExport
aMapping(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_MAPPING
, true, true);
4144 // Add the data transformations
4145 WriteExternalDataTransformations(itr
.getDataTransformation());
4149 void ScXMLExport::WriteExternalDataTransformations(const std::vector
<std::shared_ptr
<sc::DataTransformation
>>& aDataTransformations
)
4151 SvXMLElementExport
aTransformations(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_TRANSFORMATIONS
, true, true);
4152 for (auto& itr
: aDataTransformations
)
4154 sc::TransformationType aTransformationType
= itr
->getTransformationType();
4156 switch(aTransformationType
)
4158 case sc::TransformationType::DELETE_TRANSFORMATION
:
4160 // Delete Columns Transformation
4161 std::shared_ptr
<sc::ColumnRemoveTransformation
> aDeleteTransformation
= std::dynamic_pointer_cast
<sc::ColumnRemoveTransformation
>(itr
);
4162 std::set
<SCCOL
> aColumns
= aDeleteTransformation
->getColumns();
4163 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_REMOVE_TRANSFORMATION
, true, true);
4164 for(auto& col
: aColumns
)
4167 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4168 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4172 case sc::TransformationType::SPLIT_TRANSFORMATION
:
4174 std::shared_ptr
<sc::SplitColumnTransformation
> aSplitTransformation
= std::dynamic_pointer_cast
<sc::SplitColumnTransformation
>(itr
);
4176 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(aSplitTransformation
->getColumn()));
4177 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SEPARATOR
, OUString::number(aSplitTransformation
->getSeparator()));
4178 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_SPLIT_TRANSFORMATION
, true, true);
4181 case sc::TransformationType::MERGE_TRANSFORMATION
:
4183 // Merge Transformation
4184 std::shared_ptr
<sc::MergeColumnTransformation
> aMergeTransformation
= std::dynamic_pointer_cast
<sc::MergeColumnTransformation
>(itr
);
4185 std::set
<SCCOL
> aColumns
= aMergeTransformation
->getColumns();
4187 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MERGE_STRING
, aMergeTransformation
->getMergeString());
4188 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_MERGE_TRANSFORMATION
, true, true);
4190 for(auto& col
: aColumns
)
4193 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4194 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4198 case sc::TransformationType::SORT_TRANSFORMATION
:
4200 // Sort Transformation
4201 std::shared_ptr
<sc::SortTransformation
> aSortTransformation
= std::dynamic_pointer_cast
<sc::SortTransformation
>(itr
);
4202 ScSortParam aSortParam
= aSortTransformation
->getSortParam();
4203 const sc::DocumentLinkManager
& rMgr
= pDoc
->GetDocLinkManager();
4204 const sc::DataStream
* pStrm
= rMgr
.getDataStream();
4210 ScRange aRange
= pStrm
->GetRange();
4212 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_SORT_TRANSFORMATION
, true, true);
4214 writeSort(*this, aSortParam
, aRange
, pDoc
);
4217 case sc::TransformationType::TEXT_TRANSFORMATION
:
4219 // Text Transformation
4220 std::shared_ptr
<sc::TextTransformation
> aTextTransformation
= std::dynamic_pointer_cast
<sc::TextTransformation
>(itr
);
4222 sc::TEXT_TRANSFORM_TYPE aTextTransformType
= aTextTransformation
->getTextTransformationType();
4224 switch ( aTextTransformType
)
4226 case sc::TEXT_TRANSFORM_TYPE::TO_LOWER
:
4227 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_LOWERCASE
);
4229 case sc::TEXT_TRANSFORM_TYPE::TO_UPPER
:
4230 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_UPPERCASE
);
4232 case sc::TEXT_TRANSFORM_TYPE::CAPITALIZE
:
4233 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_CAPITALIZE
);
4235 case sc::TEXT_TRANSFORM_TYPE::TRIM
:
4236 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_TRIM
);
4240 std::set
<SCCOL
> aColumns
= aTextTransformation
->getColumns();
4242 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_TEXT_TRANSFORMATION
, true, true);
4244 for(auto& col
: aColumns
)
4247 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4248 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4252 case sc::TransformationType::AGGREGATE_FUNCTION
:
4254 // Aggregate Transformation
4255 std::shared_ptr
<sc::AggregateFunction
> aAggregateFunction
= std::dynamic_pointer_cast
<sc::AggregateFunction
>(itr
);
4256 std::set
<SCCOL
> aColumns
= aAggregateFunction
->getColumns();
4258 sc::AGGREGATE_FUNCTION aAggregateType
= aAggregateFunction
->getAggregateType();
4260 switch (aAggregateType
)
4262 case sc::AGGREGATE_FUNCTION::SUM
:
4263 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SUM
);
4265 case sc::AGGREGATE_FUNCTION::AVERAGE
:
4266 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_AVERAGE
);
4268 case sc::AGGREGATE_FUNCTION::MIN
:
4269 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MIN
);
4271 case sc::AGGREGATE_FUNCTION::MAX
:
4272 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MAX
);
4276 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
,XML_COLUMN_AGGREGATE_TRANSFORMATION
, true, true);
4278 for(auto& col
: aColumns
)
4281 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4282 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4286 case sc::TransformationType::NUMBER_TRANSFORMATION
:
4288 // Number Transformation
4289 std::shared_ptr
<sc::NumberTransformation
> aNumberTransformation
= std::dynamic_pointer_cast
<sc::NumberTransformation
>(itr
);
4291 sc::NUMBER_TRANSFORM_TYPE aNumberTransformType
= aNumberTransformation
->getNumberTransformationType();
4293 switch ( aNumberTransformType
)
4295 case sc::NUMBER_TRANSFORM_TYPE::ROUND
:
4296 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND
);
4298 case sc::NUMBER_TRANSFORM_TYPE::ROUND_UP
:
4299 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND_UP
);
4301 case sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN
:
4302 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND_DOWN
);
4304 case sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE
:
4305 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ABS
);
4307 case sc::NUMBER_TRANSFORM_TYPE::LOG_E
:
4308 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_LOG
);
4310 case sc::NUMBER_TRANSFORM_TYPE::LOG_10
:
4311 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_LOG_10
);
4313 case sc::NUMBER_TRANSFORM_TYPE::CUBE
:
4314 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CUBE
);
4316 case sc::NUMBER_TRANSFORM_TYPE::SQUARE
:
4317 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SQUARE
);
4319 case sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT
:
4320 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SQUARE_ROOT
);
4322 case sc::NUMBER_TRANSFORM_TYPE::EXPONENT
:
4323 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_EXPONENTIAL
);
4325 case sc::NUMBER_TRANSFORM_TYPE::IS_EVEN
:
4326 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_EVEN
);
4328 case sc::NUMBER_TRANSFORM_TYPE::IS_ODD
:
4329 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ODD
);
4331 case sc::NUMBER_TRANSFORM_TYPE::SIGN
:
4332 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SIGN
);
4336 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_PRECISION
, OUString::number(aNumberTransformation
->getPrecision()));
4337 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_NUMBER_TRANSFORMATION
, true, true);
4339 std::set
<SCCOL
> aColumns
= aNumberTransformation
->getColumn();
4340 for(auto& col
: aColumns
)
4343 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4344 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4348 case sc::TransformationType::REMOVE_NULL_TRANSFORMATION
:
4350 // Replace Null Transformation
4351 std::shared_ptr
<sc::ReplaceNullTransformation
> aReplaceNullTransformation
= std::dynamic_pointer_cast
<sc::ReplaceNullTransformation
>(itr
);
4352 std::set
<SCCOL
> aColumns
= aReplaceNullTransformation
->getColumn();
4354 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_REPLACE_STRING
, aReplaceNullTransformation
->getReplaceString());
4355 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_REPLACENULL_TRANSFORMATION
, true, true);
4357 for(auto& col
: aColumns
)
4360 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4361 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4365 case sc::TransformationType::DATETIME_TRANSFORMATION
:
4367 // Number Transformation
4368 std::shared_ptr
<sc::DateTimeTransformation
> aDateTimeTransformation
= std::dynamic_pointer_cast
<sc::DateTimeTransformation
>(itr
);
4370 sc::DATETIME_TRANSFORMATION_TYPE aDateTimeTransformationType
= aDateTimeTransformation
->getDateTimeTransformationType();
4372 switch ( aDateTimeTransformationType
)
4374 case sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING
:
4375 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DATE_STRING
);
4377 case sc::DATETIME_TRANSFORMATION_TYPE::YEAR
:
4378 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_YEAR
);
4380 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR
:
4381 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_YEAR
);
4383 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR
:
4384 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_YEAR
);
4386 case sc::DATETIME_TRANSFORMATION_TYPE::MONTH
:
4387 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MONTH
);
4389 case sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME
:
4390 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MONTH_NAME
);
4392 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH
:
4393 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_MONTH
);
4395 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH
:
4396 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_MONTH
);
4398 case sc::DATETIME_TRANSFORMATION_TYPE::DAY
:
4399 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY
);
4401 case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK
:
4402 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY_OF_WEEK
);
4404 case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR
:
4405 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY_OF_YEAR
);
4407 case sc::DATETIME_TRANSFORMATION_TYPE::QUARTER
:
4408 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_QUARTER
);
4410 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER
:
4411 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_QUARTER
);
4413 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER
:
4414 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_QUARTER
);
4416 case sc::DATETIME_TRANSFORMATION_TYPE::TIME
:
4417 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_TIME
);
4419 case sc::DATETIME_TRANSFORMATION_TYPE::HOUR
:
4420 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_HOUR
);
4422 case sc::DATETIME_TRANSFORMATION_TYPE::MINUTE
:
4423 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MINUTE
);
4425 case sc::DATETIME_TRANSFORMATION_TYPE::SECOND
:
4426 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SECONDS
);
4430 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_DATETIME_TRANSFORMATION
, true, true);
4432 std::set
<SCCOL
> aColumns
= aDateTimeTransformation
->getColumn();
4433 for(auto& col
: aColumns
)
4436 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4437 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4447 void ScXMLExport::WriteDataStream()
4452 if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
4453 // Export this only in experimental mode.
4456 if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
4457 // Export this only for 1.2 extended and above.
4460 const sc::DocumentLinkManager
& rMgr
= pDoc
->GetDocLinkManager();
4461 const sc::DataStream
* pStrm
= rMgr
.getDataStream();
4467 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(pStrm
->GetURL()));
4470 ScRange aRange
= pStrm
->GetRange();
4472 ScRangeStringConverter::GetStringFromRange(
4473 aRangeStr
, aRange
, pDoc
, formula::FormulaGrammar::CONV_OOO
);
4474 AddAttribute(XML_NAMESPACE_TABLE
, XML_TARGET_RANGE_ADDRESS
, aRangeStr
);
4476 // Empty line refresh option.
4477 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_EMPTY_LINE_REFRESH
, pStrm
->IsRefreshOnEmptyLine() ? XML_TRUE
: XML_FALSE
);
4479 // New data insertion position. Either top of bottom. Default to bottom.
4480 xmloff::token::XMLTokenEnum eInsertPosition
= XML_BOTTOM
;
4481 if (pStrm
->GetMove() == sc::DataStream::MOVE_DOWN
)
4482 eInsertPosition
= XML_TOP
;
4484 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_INSERTION_POSITION
, eInsertPosition
);
4486 SvXMLElementExport
aElem(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_STREAM_SOURCE
, true, true);
4489 void ScXMLExport::WriteNamedRange(ScRangeName
* pRangeName
)
4491 //write a global or local ScRangeName
4492 SvXMLElementExport
aElemNEs(*this, XML_NAMESPACE_TABLE
, XML_NAMED_EXPRESSIONS
, true, true);
4493 for (const auto& rxEntry
: *pRangeName
)
4495 AddAttribute(sAttrName
, rxEntry
.second
->GetName());
4497 OUString sBaseCellAddress
;
4498 rxEntry
.second
->ValidateTabRefs();
4499 ScRangeStringConverter::GetStringFromAddress( sBaseCellAddress
, rxEntry
.second
->GetPos(), pDoc
,
4500 FormulaGrammar::CONV_OOO
, ' ', false, ScRefFlags::ADDR_ABS_3D
);
4501 assert(!sBaseCellAddress
.isEmpty());
4502 AddAttribute(XML_NAMESPACE_TABLE
, XML_BASE_CELL_ADDRESS
, sBaseCellAddress
);
4504 OUString sSymbol
= rxEntry
.second
->GetSymbol(pDoc
->GetStorageGrammar());
4505 OUString
sTempSymbol(sSymbol
);
4507 if (rxEntry
.second
->IsReference(aRange
))
4510 OUString
sContent(sTempSymbol
.copy(1, sTempSymbol
.getLength() -2 ));
4511 AddAttribute(XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, sContent
);
4513 sal_Int32 nRangeType
= rxEntry
.second
->GetUnoType();
4514 OUStringBuffer sBufferRangeType
;
4515 if ((nRangeType
& sheet::NamedRangeFlag::COLUMN_HEADER
) == sheet::NamedRangeFlag::COLUMN_HEADER
)
4516 sBufferRangeType
.append(GetXMLToken(XML_REPEAT_COLUMN
));
4517 if ((nRangeType
& sheet::NamedRangeFlag::ROW_HEADER
) == sheet::NamedRangeFlag::ROW_HEADER
)
4519 if (!sBufferRangeType
.isEmpty())
4520 sBufferRangeType
.append(" ");
4521 sBufferRangeType
.append(GetXMLToken(XML_REPEAT_ROW
));
4523 if ((nRangeType
& sheet::NamedRangeFlag::FILTER_CRITERIA
) == sheet::NamedRangeFlag::FILTER_CRITERIA
)
4525 if (!sBufferRangeType
.isEmpty())
4526 sBufferRangeType
.append(" ");
4527 sBufferRangeType
.append(GetXMLToken(XML_FILTER
));
4529 if ((nRangeType
& sheet::NamedRangeFlag::PRINT_AREA
) == sheet::NamedRangeFlag::PRINT_AREA
)
4531 if (!sBufferRangeType
.isEmpty())
4532 sBufferRangeType
.append(" ");
4533 sBufferRangeType
.append(GetXMLToken(XML_PRINT_RANGE
));
4535 OUString sRangeType
= sBufferRangeType
.makeStringAndClear();
4536 if (!sRangeType
.isEmpty())
4537 AddAttribute(XML_NAMESPACE_TABLE
, XML_RANGE_USABLE_AS
, sRangeType
);
4538 SvXMLElementExport
aElemNR(*this, XML_NAMESPACE_TABLE
, XML_NAMED_RANGE
, true, true);
4543 AddAttribute(XML_NAMESPACE_TABLE
, XML_EXPRESSION
, sTempSymbol
);
4544 SvXMLElementExport
aElemNE(*this, XML_NAMESPACE_TABLE
, XML_NAMED_EXPRESSION
, true, true);
4549 void ScXMLExport::exportSparklineGroups(SCTAB nTable
)
4551 sc::SparklineGroupsExport
aSparklineGroupExport(*this, nTable
);
4552 aSparklineGroupExport
.write();
4557 OUString
getCondFormatEntryType(const ScColorScaleEntry
& rEntry
, bool bFirst
= true)
4559 switch(rEntry
.GetType())
4561 case COLORSCALE_MIN
:
4563 case COLORSCALE_MAX
:
4565 case COLORSCALE_PERCENT
:
4567 case COLORSCALE_PERCENTILE
:
4568 return "percentile";
4569 case COLORSCALE_FORMULA
:
4571 case COLORSCALE_VALUE
:
4573 case COLORSCALE_AUTO
:
4574 // only important for data bars
4576 return "auto-minimum";
4578 return "auto-maximum";
4583 OUString
getDateStringForType(condformat::ScCondFormatDateType eType
)
4587 case condformat::TODAY
:
4589 case condformat::YESTERDAY
:
4591 case condformat::TOMORROW
:
4593 case condformat::LAST7DAYS
:
4594 return "last-7-days";
4595 case condformat::THISWEEK
:
4597 case condformat::LASTWEEK
:
4599 case condformat::NEXTWEEK
:
4601 case condformat::THISMONTH
:
4602 return "this-month";
4603 case condformat::LASTMONTH
:
4604 return "last-month";
4605 case condformat::NEXTMONTH
:
4606 return "next-month";
4607 case condformat::THISYEAR
:
4609 case condformat::LASTYEAR
:
4611 case condformat::NEXTYEAR
:
4620 void ScXMLExport::ExportConditionalFormat(SCTAB nTab
)
4622 ScConditionalFormatList
* pCondFormatList
= pDoc
->GetCondFormList(nTab
);
4623 if(!pCondFormatList
)
4626 if (pCondFormatList
->empty())
4629 SvXMLElementExport
aElementCondFormats(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITIONAL_FORMATS
, true, true);
4631 for(const auto& rxCondFormat
: *pCondFormatList
)
4634 const ScRangeList
& rRangeList
= rxCondFormat
->GetRange();
4635 ScRangeStringConverter::GetStringFromRangeList( sRanges
, &rRangeList
, pDoc
, formula::FormulaGrammar::CONV_OOO
);
4636 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TARGET_RANGE_ADDRESS
, sRanges
);
4637 SvXMLElementExport
aElementCondFormat(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITIONAL_FORMAT
, true, true);
4638 size_t nEntries
= rxCondFormat
->size();
4639 for(size_t i
= 0; i
< nEntries
; ++i
)
4641 const ScFormatEntry
* pFormatEntry
= rxCondFormat
->GetEntry(i
);
4642 if(pFormatEntry
->GetType()==ScFormatEntry::Type::Condition
)
4644 const ScCondFormatEntry
* pEntry
= static_cast<const ScCondFormatEntry
*>(pFormatEntry
);
4645 OUStringBuffer aCond
;
4646 ScAddress aPos
= pEntry
->GetSrcPos();
4647 switch(pEntry
->GetOperation())
4649 case ScConditionMode::Equal
:
4651 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4653 case ScConditionMode::Less
:
4655 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4657 case ScConditionMode::Greater
:
4659 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4661 case ScConditionMode::EqLess
:
4663 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4665 case ScConditionMode::EqGreater
:
4667 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4669 case ScConditionMode::NotEqual
:
4671 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4673 case ScConditionMode::Between
:
4674 aCond
.append("between(");
4675 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4677 aCond
.append(pEntry
->GetExpression(aPos
, 1, 0, formula::FormulaGrammar::GRAM_ODFF
));
4680 case ScConditionMode::NotBetween
:
4681 aCond
.append("not-between(");
4682 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4684 aCond
.append(pEntry
->GetExpression(aPos
, 1, 0, formula::FormulaGrammar::GRAM_ODFF
));
4687 case ScConditionMode::Duplicate
:
4688 aCond
.append("duplicate");
4690 case ScConditionMode::NotDuplicate
:
4691 aCond
.append("unique");
4693 case ScConditionMode::Direct
:
4694 aCond
.append("formula-is(");
4695 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4698 case ScConditionMode::Top10
:
4699 aCond
.append("top-elements(");
4700 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4703 case ScConditionMode::Bottom10
:
4704 aCond
.append("bottom-elements(");
4705 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4708 case ScConditionMode::TopPercent
:
4709 aCond
.append("top-percent(");
4710 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4713 case ScConditionMode::BottomPercent
:
4714 aCond
.append("bottom-percent(");
4715 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4718 case ScConditionMode::AboveAverage
:
4719 aCond
.append("above-average");
4721 case ScConditionMode::BelowAverage
:
4722 aCond
.append("below-average");
4724 case ScConditionMode::AboveEqualAverage
:
4725 aCond
.append("above-equal-average");
4727 case ScConditionMode::BelowEqualAverage
:
4728 aCond
.append("below-equal-average");
4730 case ScConditionMode::Error
:
4731 aCond
.append("is-error");
4733 case ScConditionMode::NoError
:
4734 aCond
.append("is-no-error");
4736 case ScConditionMode::BeginsWith
:
4737 aCond
.append("begins-with(");
4738 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4741 case ScConditionMode::EndsWith
:
4742 aCond
.append("ends-with(");
4743 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4746 case ScConditionMode::ContainsText
:
4747 aCond
.append("contains-text(");
4748 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4751 case ScConditionMode::NotContainsText
:
4752 aCond
.append("not-contains-text(");
4753 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4756 case ScConditionMode::NONE
:
4759 SAL_WARN("sc", "unimplemented conditional format export");
4761 OUString sStyle
= ScStyleNameConversion::DisplayToProgrammaticName(pEntry
->GetStyle(), SfxStyleFamily::Para
);
4762 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_APPLY_STYLE_NAME
, sStyle
);
4763 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, aCond
.makeStringAndClear());
4765 OUString sBaseAddress
;
4766 ScRangeStringConverter::GetStringFromAddress( sBaseAddress
, aPos
, pDoc
,formula::FormulaGrammar::CONV_ODF
);
4767 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_BASE_CELL_ADDRESS
, sBaseAddress
);
4768 SvXMLElementExport
aElementCondEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITION
, true, true);
4770 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Colorscale
)
4772 SvXMLElementExport
aElementColorScale(*this, XML_NAMESPACE_CALC_EXT
, XML_COLOR_SCALE
, true, true);
4773 const ScColorScaleFormat
& rColorScale
= static_cast<const ScColorScaleFormat
&>(*pFormatEntry
);
4774 for(const auto& rxItem
: rColorScale
)
4776 if(rxItem
->GetType() == COLORSCALE_FORMULA
)
4778 OUString sFormula
= rxItem
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4779 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4782 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(rxItem
->GetValue()));
4784 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*rxItem
));
4785 OUStringBuffer aBuffer
;
4786 ::sax::Converter::convertColor(aBuffer
, rxItem
->GetColor());
4787 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLOR
, aBuffer
.makeStringAndClear());
4788 SvXMLElementExport
aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_COLOR_SCALE_ENTRY
, true, true);
4791 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Databar
)
4793 const ScDataBarFormatData
* pFormatData
= static_cast<const ScDataBarFormat
&>(*pFormatEntry
).GetDataBarData();
4794 if(!pFormatData
->mbGradient
)
4795 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_GRADIENT
, XML_FALSE
);
4796 if(pFormatData
->mbOnlyBar
)
4797 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SHOW_VALUE
, XML_FALSE
);
4799 if (pFormatData
->mnMinLength
!= 0.0)
4800 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MIN_LENGTH
, OUString::number(pFormatData
->mnMinLength
));
4802 if (pFormatData
->mnMaxLength
!= 0.0)
4803 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MAX_LENGTH
, OUString::number(pFormatData
->mnMaxLength
));
4805 if(pFormatData
->mbNeg
)
4807 if(pFormatData
->mxNegativeColor
)
4809 OUStringBuffer aBuffer
;
4810 ::sax::Converter::convertColor(aBuffer
, *pFormatData
->mxNegativeColor
);
4811 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_NEGATIVE_COLOR
, aBuffer
.makeStringAndClear());
4815 OUStringBuffer aBuffer
;
4816 ::sax::Converter::convertColor(aBuffer
, COL_LIGHTRED
);
4817 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_NEGATIVE_COLOR
, aBuffer
.makeStringAndClear());
4821 if(pFormatData
->meAxisPosition
!= databar::AUTOMATIC
)
4823 if(pFormatData
->meAxisPosition
== databar::NONE
)
4825 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_POSITION
, OUString("none"));
4829 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_POSITION
, OUString("middle"));
4833 OUStringBuffer aBuffer
;
4834 ::sax::Converter::convertColor(aBuffer
, pFormatData
->maPositiveColor
);
4835 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_POSITIVE_COLOR
, aBuffer
.makeStringAndClear());
4838 ::sax::Converter::convertColor(aBuffer
, pFormatData
->maAxisColor
);
4839 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_COLOR
, aBuffer
.makeStringAndClear());
4840 SvXMLElementExport
aElementDataBar(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_BAR
, true, true);
4843 if(pFormatData
->mpLowerLimit
->GetType() == COLORSCALE_FORMULA
)
4845 OUString sFormula
= pFormatData
->mpLowerLimit
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4846 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4849 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(pFormatData
->mpLowerLimit
->GetValue()));
4850 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*pFormatData
->mpLowerLimit
));
4851 SvXMLElementExport
aElementDataBarEntryLower(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4855 if(pFormatData
->mpUpperLimit
->GetType() == COLORSCALE_FORMULA
)
4857 OUString sFormula
= pFormatData
->mpUpperLimit
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4858 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4861 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(pFormatData
->mpUpperLimit
->GetValue()));
4862 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*pFormatData
->mpUpperLimit
, false));
4863 SvXMLElementExport
aElementDataBarEntryUpper(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4866 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Iconset
)
4868 const ScIconSetFormat
& rIconSet
= static_cast<const ScIconSetFormat
&>(*pFormatEntry
);
4869 OUString aIconSetName
= OUString::createFromAscii(ScIconSetFormat::getIconSetName(rIconSet
.GetIconSetData()->eIconSetType
));
4870 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_ICON_SET_TYPE
, aIconSetName
);
4871 if (rIconSet
.GetIconSetData()->mbCustom
)
4872 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM
, OUString::boolean(true));
4874 SvXMLElementExport
aElementColorScale(*this, XML_NAMESPACE_CALC_EXT
, XML_ICON_SET
, true, true);
4876 if (rIconSet
.GetIconSetData()->mbCustom
)
4878 for (const auto& [rType
, rIndex
] : rIconSet
.GetIconSetData()->maCustomVector
)
4880 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET_NAME
, OUString::createFromAscii(ScIconSetFormat::getIconSetName(rType
)));
4881 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET_INDEX
, OUString::number(rIndex
));
4882 SvXMLElementExport
aCustomIcon(*this, XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET
, true, true);
4887 if(!rIconSet
.GetIconSetData()->mbShowValue
)
4888 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SHOW_VALUE
, XML_FALSE
);
4889 for (auto const& it
: rIconSet
)
4891 if(it
->GetType() == COLORSCALE_FORMULA
)
4893 OUString sFormula
= it
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4894 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4897 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(it
->GetValue()));
4899 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*it
));
4900 SvXMLElementExport
aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4903 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Date
)
4905 const ScCondDateFormatEntry
& rDateFormat
= static_cast<const ScCondDateFormatEntry
&>(*pFormatEntry
);
4906 OUString aDateType
= getDateStringForType(rDateFormat
.GetDateType());
4907 OUString aStyleName
= ScStyleNameConversion::DisplayToProgrammaticName(rDateFormat
.GetStyleName(), SfxStyleFamily::Para
);
4908 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_STYLE
, aStyleName
);
4909 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_DATE
, aDateType
);
4910 SvXMLElementExport
aElementDateFormat(*this, XML_NAMESPACE_CALC_EXT
, XML_DATE_IS
, true, true);
4916 void ScXMLExport::WriteExternalRefCaches()
4921 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
4922 pRefMgr
->resetSrcFileData(GetOrigFileName());
4923 sal_uInt16 nCount
= pRefMgr
->getExternalFileCount();
4924 for (sal_uInt16 nFileId
= 0; nFileId
< nCount
; ++nFileId
)
4926 const OUString
* pUrl
= pRefMgr
->getExternalFileName(nFileId
);
4930 vector
<OUString
> aTabNames
;
4931 pRefMgr
->getAllCachedTableNames(nFileId
, aTabNames
);
4932 if (aTabNames
.empty())
4935 for (const auto& rTabName
: aTabNames
)
4937 ScExternalRefCache::TableTypeRef pTable
= pRefMgr
->getCacheTable(nFileId
, rTabName
, false);
4938 if (!pTable
|| !pTable
->isReferenced())
4941 AddAttribute(XML_NAMESPACE_TABLE
, XML_NAME
, "'" + *pUrl
+ "'#" + rTabName
);
4942 AddAttribute(XML_NAMESPACE_TABLE
, XML_PRINT
, GetXMLToken(XML_FALSE
));
4943 AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, sExternalRefTabStyleName
);
4944 SvXMLElementExport
aElemTable(*this, XML_NAMESPACE_TABLE
, XML_TABLE
, true, true);
4946 const ScExternalRefManager::SrcFileData
* pExtFileData
= pRefMgr
->getExternalFileData(nFileId
);
4950 if (!pExtFileData
->maRelativeName
.isEmpty())
4951 aRelUrl
= pExtFileData
->maRelativeName
;
4953 aRelUrl
= GetRelativeReference(pExtFileData
->maRelativeName
);
4954 AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
4955 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, aRelUrl
);
4956 AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_NAME
, rTabName
);
4957 if (!pExtFileData
->maFilterName
.isEmpty())
4958 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, pExtFileData
->maFilterName
);
4959 if (!pExtFileData
->maFilterOptions
.isEmpty())
4960 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, pExtFileData
->maFilterOptions
);
4961 AddAttribute(XML_NAMESPACE_TABLE
, XML_MODE
, XML_COPY_RESULTS_ONLY
);
4963 SvXMLElementExport
aElemTableSource(*this, XML_NAMESPACE_TABLE
, XML_TABLE_SOURCE
, true, true);
4966 // Determine maximum column count of used area, for repeated cells.
4967 SCCOL nMaxColsUsed
= 1; // assume that there is at least one cell somewhere...
4968 vector
<SCROW
> aRows
;
4969 pTable
->getAllRows(aRows
);
4970 for (SCROW nRow
: aRows
)
4972 vector
<SCCOL
> aCols
;
4973 pTable
->getAllCols(nRow
, aCols
);
4976 SCCOL nCol
= aCols
.back();
4977 if (nMaxColsUsed
<= nCol
)
4978 nMaxColsUsed
= nCol
+ 1;
4982 // Column definitions have to be present to make a valid file
4984 if (nMaxColsUsed
> 1)
4985 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
4986 OUString::number(nMaxColsUsed
));
4987 SvXMLElementExport
aElemColumn(*this, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true);
4990 // Write cache content for this table.
4992 bool bFirstRow
= true;
4993 for (SCROW nRow
: aRows
)
5001 OUString aVal
= OUString::number(nRow
);
5002 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, aVal
);
5004 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5005 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nMaxColsUsed
));
5006 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5007 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5012 SCROW nRowGap
= nRow
- nLastRow
;
5017 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nRowGap
-1));
5018 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, aVal
);
5020 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5021 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nMaxColsUsed
));
5022 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5023 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5026 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5028 vector
<SCCOL
> aCols
;
5029 pTable
->getAllCols(nRow
, aCols
);
5031 bool bFirstCol
= true;
5032 for (SCCOL nCol
: aCols
)
5040 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nCol
));
5041 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5043 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5048 SCCOL nColGap
= nCol
- nLastCol
;
5053 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nColGap
-1));
5054 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5056 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5060 // Write out this cell.
5061 sal_uInt32 nNumFmt
= 0;
5062 ScExternalRefCache::TokenRef pToken
= pTable
->getCell(nCol
, nRow
, &nNumFmt
);
5066 sal_Int32 nIndex
= GetNumberFormatStyleIndex(nNumFmt
);
5069 const OUString
& aStyleName
= pCellStyles
->GetStyleNameByIndex(nIndex
, true);
5070 AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, aStyleName
);
5073 switch(pToken
->GetType())
5077 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
5078 OUStringBuffer aVal
;
5079 aVal
.append(pToken
->GetDouble());
5080 aStrVal
= aVal
.makeStringAndClear();
5081 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE
, aStrVal
);
5086 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
5087 aStrVal
= pToken
->GetString().getString();
5094 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5095 SvXMLElementExport
aElemText(*this, XML_NAMESPACE_TEXT
, XML_P
, true, false);
5096 Characters(aStrVal
);
5108 // core implementation
5109 void ScXMLExport::WriteConsolidation()
5114 const ScConsolidateParam
* pCons(pDoc
->GetConsolidateDlgData());
5118 OUString sStrData
= ScXMLConverter::GetStringFromFunction( pCons
->eFunction
);
5119 AddAttribute( XML_NAMESPACE_TABLE
, XML_FUNCTION
, sStrData
);
5122 for( sal_Int32 nIndex
= 0; nIndex
< pCons
->nDataAreaCount
; ++nIndex
)
5123 ScRangeStringConverter::GetStringFromArea( sStrData
, pCons
->pDataAreas
[ nIndex
], pDoc
, FormulaGrammar::CONV_OOO
, ' ', true );
5124 AddAttribute( XML_NAMESPACE_TABLE
, XML_SOURCE_CELL_RANGE_ADDRESSES
, sStrData
);
5126 ScRangeStringConverter::GetStringFromAddress( sStrData
, ScAddress( pCons
->nCol
, pCons
->nRow
, pCons
->nTab
), pDoc
, FormulaGrammar::CONV_OOO
);
5127 AddAttribute( XML_NAMESPACE_TABLE
, XML_TARGET_CELL_ADDRESS
, sStrData
);
5129 if( pCons
->bByCol
&& !pCons
->bByRow
)
5130 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_COLUMN
);
5131 else if( !pCons
->bByCol
&& pCons
->bByRow
)
5132 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_ROW
);
5133 else if( pCons
->bByCol
&& pCons
->bByRow
)
5134 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_BOTH
);
5136 if( pCons
->bReferenceData
)
5137 AddAttribute( XML_NAMESPACE_TABLE
, XML_LINK_TO_SOURCE_DATA
, XML_TRUE
);
5139 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_CONSOLIDATION
, true, true );
5142 SvXMLAutoStylePoolP
* ScXMLExport::CreateAutoStylePool()
5144 return new ScXMLAutoStylePoolP(*this);
5147 XMLPageExport
* ScXMLExport::CreatePageExport()
5149 return new XMLTableMasterPageExport( *this );
5152 void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence
<beans::PropertyValue
>& rProps
)
5154 ScChangeViewSettings
* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : nullptr);
5158 sal_Int32
nChangePos(rProps
.getLength());
5159 rProps
.realloc(nChangePos
+ 1);
5160 beans::PropertyValue
* pProps(rProps
.getArray());
5162 uno::Sequence
<beans::PropertyValue
> aChangeProps(SC_VIEWCHANGES_COUNT
);
5163 beans::PropertyValue
* pChangeProps(aChangeProps
.getArray());
5164 pChangeProps
[SC_SHOW_CHANGES
].Name
= "ShowChanges";
5165 pChangeProps
[SC_SHOW_CHANGES
].Value
<<= pViewSettings
->ShowChanges();
5166 pChangeProps
[SC_SHOW_ACCEPTED_CHANGES
].Name
= "ShowAcceptedChanges";
5167 pChangeProps
[SC_SHOW_ACCEPTED_CHANGES
].Value
<<= pViewSettings
->IsShowAccepted();
5168 pChangeProps
[SC_SHOW_REJECTED_CHANGES
].Name
= "ShowRejectedChanges";
5169 pChangeProps
[SC_SHOW_REJECTED_CHANGES
].Value
<<= pViewSettings
->IsShowRejected();
5170 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME
].Name
= "ShowChangesByDatetime";
5171 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME
].Value
<<= pViewSettings
->HasDate();
5172 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_MODE
].Name
= "ShowChangesByDatetimeMode";
5173 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_MODE
].Value
<<= static_cast<sal_Int16
>(pViewSettings
->GetTheDateMode());
5174 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME
].Name
= "ShowChangesByDatetimeFirstDatetime";
5175 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME
].Value
<<= pViewSettings
->GetTheFirstDateTime().GetUNODateTime();
5176 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME
].Name
= "ShowChangesByDatetimeSecondDatetime";
5177 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME
].Value
<<= pViewSettings
->GetTheLastDateTime().GetUNODateTime();
5178 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR
].Name
= "ShowChangesByAuthor";
5179 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR
].Value
<<= pViewSettings
->HasAuthor();
5180 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR_NAME
].Name
= "ShowChangesByAuthorName";
5181 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR_NAME
].Value
<<= pViewSettings
->GetTheAuthorToShow();
5182 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT
].Name
= "ShowChangesByComment";
5183 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT
].Value
<<= pViewSettings
->HasComment();
5184 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT_TEXT
].Name
= "ShowChangesByCommentText";
5185 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT_TEXT
].Value
<<= pViewSettings
->GetTheComment();
5186 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES
].Name
= "ShowChangesByRanges";
5187 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES
].Value
<<= pViewSettings
->HasRange();
5188 OUString sRangeList
;
5189 ScRangeStringConverter::GetStringFromRangeList(sRangeList
, &(pViewSettings
->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO
);
5190 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES_LIST
].Name
= "ShowChangesByRangesList";
5191 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES_LIST
].Value
<<= sRangeList
;
5193 pProps
[nChangePos
].Name
= "TrackedChangesViewSettings";
5194 pProps
[nChangePos
].Value
<<= aChangeProps
;
5197 void ScXMLExport::GetViewSettings(uno::Sequence
<beans::PropertyValue
>& rProps
)
5199 if (GetModel().is())
5202 beans::PropertyValue
* pProps(rProps
.getArray());
5203 ScModelObj
* pDocObj(comphelper::getFromUnoTunnel
<ScModelObj
>( GetModel() ));
5206 SfxObjectShell
* pEmbeddedObj
= pDocObj
->GetEmbeddedObject();
5209 tools::Rectangle
aRect(pEmbeddedObj
->GetVisArea());
5211 pProps
[i
].Name
= "VisibleAreaTop";
5212 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.Top());
5213 pProps
[++i
].Name
= "VisibleAreaLeft";
5214 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.Left());
5215 pProps
[++i
].Name
= "VisibleAreaWidth";
5216 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.getOpenWidth());
5217 pProps
[++i
].Name
= "VisibleAreaHeight";
5218 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.getOpenHeight());
5222 GetChangeTrackViewSettings(rProps
);
5225 void ScXMLExport::GetConfigurationSettings(uno::Sequence
<beans::PropertyValue
>& rProps
)
5227 if (!GetModel().is())
5230 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
5231 if (!xMultiServiceFactory
.is())
5234 uno::Reference
<beans::XPropertySet
> xProperties(xMultiServiceFactory
->createInstance("com.sun.star.comp.SpreadsheetSettings"), uno::UNO_QUERY
);
5235 if (xProperties
.is())
5236 SvXMLUnitConverter::convertPropertySet(rProps
, xProperties
);
5238 sal_Int32 nPropsToAdd
= 0;
5239 OUStringBuffer aTrackedChangesKey
;
5240 if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected())
5242 ::comphelper::Base64::encode(aTrackedChangesKey
,
5243 GetDocument()->GetChangeTrack()->GetProtection());
5244 if (!aTrackedChangesKey
.isEmpty())
5248 bool bVBACompat
= false;
5249 uno::Reference
<container::XNameAccess
> xCodeNameAccess
;
5250 OSL_ENSURE( pDoc
, "ScXMLExport::GetConfigurationSettings - no ScDocument!" );
5251 // tdf#71271 - add code names regardless of VBA compatibility mode
5254 // VBA compatibility mode
5255 if (bVBACompat
= pDoc
->IsInVBAMode(); bVBACompat
)
5259 xCodeNameAccess
= new XMLCodeNameProvider( pDoc
);
5260 if( xCodeNameAccess
->hasElements() )
5263 xCodeNameAccess
.clear();
5266 if( nPropsToAdd
<= 0 )
5269 sal_Int32
nCount(rProps
.getLength());
5270 rProps
.realloc(nCount
+ nPropsToAdd
);
5271 auto pProps
= rProps
.getArray();
5272 if (!aTrackedChangesKey
.isEmpty())
5274 pProps
[nCount
].Name
= "TrackedChangesProtectionKey";
5275 pProps
[nCount
].Value
<<= aTrackedChangesKey
.makeStringAndClear();
5280 pProps
[nCount
].Name
= "VBACompatibilityMode";
5281 pProps
[nCount
].Value
<<= bVBACompat
;
5284 if( xCodeNameAccess
.is() )
5286 pProps
[nCount
].Name
= "ScriptConfiguration";
5287 pProps
[nCount
].Value
<<= xCodeNameAccess
;
5292 XMLShapeExport
* ScXMLExport::CreateShapeExport()
5294 return new ScXMLShapeExport(*this);
5297 XMLNumberFormatAttributesExportHelper
* ScXMLExport::GetNumberFormatAttributesExportHelper()
5299 if (!pNumberFormatAttributesExportHelper
)
5300 pNumberFormatAttributesExportHelper
.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this ));
5301 return pNumberFormatAttributesExportHelper
.get();
5304 void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool
* pPool
, sal_uInt16 nAttrib
)
5306 for (const SfxPoolItem
* pItem
: pPool
->GetItemSurrogates(nAttrib
))
5308 const SvXMLAttrContainerItem
*pUnknown(static_cast<const SvXMLAttrContainerItem
*>(pItem
));
5309 if( pUnknown
->GetAttrCount() > 0 )
5311 sal_uInt16
nIdx(pUnknown
->GetFirstNamespaceIndex());
5312 while( USHRT_MAX
!= nIdx
)
5314 if( (XML_NAMESPACE_UNKNOWN_FLAG
& nIdx
) != 0 )
5316 const OUString
& rPrefix
= pUnknown
->GetPrefix( nIdx
);
5317 // Add namespace declaration for unknown attributes if
5318 // there aren't existing ones for the prefix used by the
5320 GetNamespaceMap_().Add( rPrefix
,
5321 pUnknown
->GetNamespace( nIdx
) );
5323 nIdx
= pUnknown
->GetNextNamespaceIndex( nIdx
);
5328 // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
5329 GetNamespaceMap_().Add(
5330 GetXMLToken( XML_NP_PRESENTATION
),
5331 GetXMLToken( XML_N_PRESENTATION
),
5332 XML_NAMESPACE_PRESENTATION
);
5335 void ScXMLExport::IncrementProgressBar(bool bFlush
, sal_Int32 nInc
)
5337 nProgressCount
+= nInc
;
5338 if (bFlush
|| nProgressCount
> 100)
5340 GetProgressBarHelper()->Increment(nProgressCount
);
5345 ErrCode
ScXMLExport::exportDoc( enum XMLTokenEnum eClass
)
5347 if( getExportFlags() & (SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::STYLES
|
5348 SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
) )
5352 // if source doc was Excel then
5353 uno::Reference
< frame::XModel
> xModel
= GetModel();
5356 auto pFoundShell
= comphelper::getFromUnoTunnel
<SfxObjectShell
>(xModel
);
5357 if ( pFoundShell
&& ooo::vba::isAlienExcelDoc( *pFoundShell
) )
5359 xRowStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScFromXLSRowStylesProperties
, xScPropHdlFactory
, true);
5360 xRowStylesExportPropertySetMapper
= new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper
);
5361 GetAutoStylePool()->SetFamilyPropSetMapper( XmlStyleFamily::TABLE_ROW
,
5362 xRowStylesExportPropertySetMapper
);
5365 CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF
);
5366 CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS
);
5367 CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS
);
5368 ScDrawLayer
* pDrawLayer
= GetDocument()->GetDrawLayer();
5371 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), EE_PARA_XMLATTRIBS
);
5372 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), EE_CHAR_XMLATTRIBS
);
5373 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), SDRATTR_XMLATTRIBUTES
);
5376 // sheet events use officeooo namespace
5377 if( (getExportFlags() & SvXMLExportFlags::CONTENT
) &&
5378 getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
5380 bool bAnySheetEvents
= false;
5381 SCTAB nTabCount
= pDoc
->GetTableCount();
5382 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
5383 if (pDoc
->GetSheetEvents(nTab
))
5384 bAnySheetEvents
= true;
5385 if (bAnySheetEvents
)
5386 GetNamespaceMap_().Add(
5387 GetXMLToken( XML_NP_OFFICE_EXT
),
5388 GetXMLToken( XML_N_OFFICE_EXT
),
5389 XML_NAMESPACE_OFFICE_EXT
);
5393 return SvXMLExport::exportDoc( eClass
);
5397 void SAL_CALL
ScXMLExport::setSourceDocument( const uno::Reference
<lang::XComponent
>& xComponent
)
5399 SolarMutexGuard aGuard
;
5400 SvXMLExport::setSourceDocument( xComponent
);
5402 pDoc
= ScXMLConverter::GetScDocument( GetModel() );
5403 OSL_ENSURE( pDoc
, "ScXMLExport::setSourceDocument - no ScDocument!" );
5405 throw lang::IllegalArgumentException();
5407 // create ScChangeTrackingExportHelper after document is known
5408 pChangeTrackingExportHelper
.reset(new ScChangeTrackingExportHelper(*this));
5410 // Set the document's storage grammar corresponding to the ODF version that
5411 // is to be written.
5412 SvtSaveOptions::ODFSaneDefaultVersion meODFDefaultVersion
= getSaneDefaultVersion();
5413 switch (meODFDefaultVersion
)
5415 // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF
5416 case SvtSaveOptions::ODFSVER_010
:
5417 case SvtSaveOptions::ODFSVER_011
:
5418 pDoc
->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF
);
5421 pDoc
->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF
);
5426 sal_Bool SAL_CALL
ScXMLExport::filter( const css::uno::Sequence
< css::beans::PropertyValue
>& aDescriptor
)
5428 SolarMutexGuard aGuard
;
5430 pDoc
->EnableIdle(false);
5431 bool bReturn(SvXMLExport::filter(aDescriptor
));
5433 pDoc
->EnableIdle(true);
5437 void SAL_CALL
ScXMLExport::cancel()
5439 SolarMutexGuard aGuard
;
5441 pDoc
->EnableIdle(true);
5442 SvXMLExport::cancel();
5446 void SAL_CALL
ScXMLExport::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
5448 SolarMutexGuard aGuard
;
5449 SvXMLExport::initialize(aArguments
);
5453 sal_Int64 SAL_CALL
ScXMLExport::getSomething( const css::uno::Sequence
< sal_Int8
>& aIdentifier
)
5455 SolarMutexGuard aGuard
;
5456 return SvXMLExport::getSomething(aIdentifier
);
5459 void ScXMLExport::DisposingModel()
5461 SvXMLExport::DisposingModel();
5463 xCurrentTable
= nullptr;
5466 void ScXMLExport::SetSharedData(std::unique_ptr
<ScMySharedData
> pTemp
) { pSharedData
= std::move(pTemp
); }
5468 std::unique_ptr
<ScMySharedData
> ScXMLExport::ReleaseSharedData() { return std::move(pSharedData
); }
5469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */