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>
71 #include <xmloff/xmltoken.hxx>
72 #include <xmloff/xmlnamespace.hxx>
73 #include <xmloff/xmluconv.hxx>
74 #include <xmloff/namespacemap.hxx>
75 #include <xmloff/families.hxx>
76 #include <xmloff/numehelp.hxx>
77 #include <xmloff/txtparae.hxx>
78 #include <editeng/autokernitem.hxx>
79 #include <editeng/charreliefitem.hxx>
80 #include <editeng/charscaleitem.hxx>
81 #include <editeng/colritem.hxx>
82 #include <editeng/contouritem.hxx>
83 #include <editeng/crossedoutitem.hxx>
84 #include <editeng/emphasismarkitem.hxx>
85 #include <editeng/escapementitem.hxx>
86 #include <editeng/fhgtitem.hxx>
87 #include <editeng/fontitem.hxx>
88 #include <editeng/kernitem.hxx>
89 #include <editeng/langitem.hxx>
90 #include <editeng/postitem.hxx>
91 #include <editeng/section.hxx>
92 #include <editeng/shdditem.hxx>
93 #include <editeng/udlnitem.hxx>
94 #include <editeng/wghtitem.hxx>
95 #include <editeng/wrlmitem.hxx>
96 #include <editeng/xmlcnitm.hxx>
97 #include <editeng/flditem.hxx>
98 #include <editeng/eeitem.hxx>
99 #include <formula/errorcodes.hxx>
100 #include <xmloff/xmlerror.hxx>
101 #include <xmloff/XMLEventExport.hxx>
102 #include <xmloff/xmlprmap.hxx>
103 #include <xmloff/ProgressBarHelper.hxx>
104 #include <xmloff/table/XMLTableExport.hxx>
106 #include <sax/tools/converter.hxx>
107 #include <tools/fldunit.hxx>
109 #include <rtl/ustring.hxx>
111 #include <tools/color.hxx>
112 #include <rtl/math.hxx>
113 #include <svl/zforlist.hxx>
114 #include <svx/unoshape.hxx>
115 #include <comphelper/base64.hxx>
116 #include <comphelper/extract.hxx>
117 #include <svx/svdoashp.hxx>
118 #include <svx/svdobj.hxx>
119 #include <svx/svdocapt.hxx>
120 #include <vcl/svapp.hxx>
121 #include <svx/unoapi.hxx>
122 #include <basegfx/polygon/b2dpolypolygon.hxx>
123 #include <basegfx/matrix/b2dhommatrix.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/style/XStyleFamiliesSupplier.hpp>
143 #include <com/sun/star/table/XColumnRowRange.hpp>
144 #include <com/sun/star/util/XProtectable.hpp>
145 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
146 #include <com/sun/star/chart2/XChartDocument.hpp>
147 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
148 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
150 #include <com/sun/star/document/XDocumentProperties.hpp>
151 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
153 #include "XMLCodeNameProvider.hxx"
155 #include <sfx2/linkmgr.hxx>
156 #include <sfx2/objsh.hxx>
160 #include <vbahelper/vbaaccesshelper.hxx>
161 #include <officecfg/Office/Common.hxx>
163 namespace com::sun::star::uno
{ class XComponentContext
; }
167 //! not found in unonames.hxx
168 #define SC_LAYERID "LayerID"
170 #define SC_VIEWCHANGES_COUNT 13
171 #define SC_SHOW_CHANGES 0
172 #define SC_SHOW_ACCEPTED_CHANGES 1
173 #define SC_SHOW_REJECTED_CHANGES 2
174 #define SC_SHOW_CHANGES_BY_DATETIME 3
175 #define SC_SHOW_CHANGES_BY_DATETIME_MODE 4
176 #define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5
177 #define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6
178 #define SC_SHOW_CHANGES_BY_AUTHOR 7
179 #define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8
180 #define SC_SHOW_CHANGES_BY_COMMENT 9
181 #define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10
182 #define SC_SHOW_CHANGES_BY_RANGES 11
183 #define SC_SHOW_CHANGES_BY_RANGES_LIST 12
185 using namespace formula
;
186 using namespace com::sun::star
;
187 using namespace xmloff::token
;
189 using ::com::sun::star::uno::UNO_QUERY
;
193 OUString
lcl_RangeSequenceToString(
194 const uno::Sequence
< OUString
> & rRanges
,
195 const uno::Reference
< chart2::data::XRangeXMLConversion
> & xFormatConverter
)
197 OUStringBuffer aResult
;
198 const sal_Int32
nMaxIndex( rRanges
.getLength() - 1 );
199 const sal_Unicode
cSep(' ');
200 for( sal_Int32 i
=0; i
<=nMaxIndex
; ++i
)
202 OUString
aRange( rRanges
[i
] );
203 if( xFormatConverter
.is())
204 aRange
= xFormatConverter
->convertRangeToXML( aRange
);
205 aResult
.append( aRange
);
207 aResult
.append( cSep
);
209 return aResult
.makeStringAndClear();
212 OUString
lcl_GetFormattedString(ScDocument
* pDoc
, const ScRefCellValue
& rCell
, const ScAddress
& rAddr
)
214 // return text/edit cell string content, with line feeds in edit cells
217 return EMPTY_OUSTRING
;
219 switch (rCell
.meType
)
221 case CELLTYPE_STRING
:
225 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
227 sal_uInt32 nFormat
= pDoc
->GetNumberFormat(rAddr
);
228 ScCellFormat::GetString(rCell
, nFormat
, aStr
, &pColor
, *pFormatter
, *pDoc
);
233 const EditTextObject
* pData
= rCell
.mpEditText
;
235 return EMPTY_OUSTRING
;
237 EditEngine
& rEngine
= pDoc
->GetEditEngine();
238 rEngine
.SetText(*pData
);
239 return rEngine
.GetText();
246 return EMPTY_OUSTRING
;
249 } // anonymous namespace
251 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
252 Calc_XMLExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
254 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLExporter", SvXMLExportFlags::ALL
));
257 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
258 Calc_XMLMetaExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
260 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLMetaExporter", SvXMLExportFlags::META
));
263 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
264 Calc_XMLStylesExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
266 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLStylesExporter", SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::FONTDECLS
));
269 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
270 Calc_XMLContentExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
272 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLContentExporter", SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SCRIPTS
|SvXMLExportFlags::FONTDECLS
));
275 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
276 Calc_XMLSettingsExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
278 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLSettingsExporter", SvXMLExportFlags::SETTINGS
));
281 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
282 Calc_XMLOasisExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
284 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisExporter", SvXMLExportFlags::ALL
|SvXMLExportFlags::OASIS
));
287 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
288 Calc_XMLOasisMetaExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
290 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisMetaExporter", SvXMLExportFlags::META
|SvXMLExportFlags::OASIS
));
293 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
294 Calc_XMLOasisStylesExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
296 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisStylesExporter", SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::OASIS
));
299 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
300 Calc_XMLOasisContentExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
302 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisContentExporter", SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SCRIPTS
|SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::OASIS
));
305 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
306 Calc_XMLOasisSettingsExporter_get_implementation(css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const &)
308 return cppu::acquire(new ScXMLExport(context
, "com.sun.star.comp.Calc.XMLOasisSettingsExporter", SvXMLExportFlags::SETTINGS
|SvXMLExportFlags::OASIS
));
313 class ScXMLShapeExport
: public XMLShapeExport
316 explicit ScXMLShapeExport(SvXMLExport
& rExp
) : XMLShapeExport(rExp
) {}
318 /** is called before a shape element for the given XShape is exported */
319 virtual void onExport( const uno::Reference
< drawing::XShape
>& xShape
) override
;
324 void ScXMLShapeExport::onExport( const uno::Reference
< drawing::XShape
>& xShape
)
326 uno::Reference
< beans::XPropertySet
> xShapeProp( xShape
, uno::UNO_QUERY
);
327 if( xShapeProp
.is() )
329 sal_Int16 nLayerID
= 0;
330 if( (xShapeProp
->getPropertyValue( SC_LAYERID
) >>= nLayerID
) && (SdrLayerID(nLayerID
) == SC_LAYER_BACK
) )
331 GetExport().AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_BACKGROUND
, XML_TRUE
);
335 sal_Int16
ScXMLExport::GetMeasureUnit()
337 css::uno::Reference
<css::sheet::XGlobalSheetSettings
> xProperties
=
338 css::sheet::GlobalSheetSettings::create( comphelper::getProcessComponentContext() );
339 const FieldUnit eFieldUnit
= static_cast<FieldUnit
>(xProperties
->getMetric());
340 return SvXMLUnitConverter::GetMeasureUnit(eFieldUnit
);
343 constexpr OUStringLiteral
gsLayerID( u
"" SC_LAYERID
);
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
),
353 pCurrentCell(nullptr),
357 bHasRowHeader(false),
358 bRowHeaderOpen(false)
360 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
362 pGroupColumns
.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP
) );
363 pGroupRows
.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP
) );
364 pColumnStyles
.reset( new ScColumnStyles() );
365 pRowStyles
.reset( new ScRowStyles() );
366 pRowFormatRanges
.reset( new ScRowFormatRanges() );
367 pMergedRangesContainer
.reset( new ScMyMergedRangesContainer() );
368 pValidationsContainer
.reset( new ScMyValidationsContainer() );
369 mpCellsItr
.reset(new ScMyNotEmptyCellsIterator(*this));
370 pDefaults
.reset( new ScMyDefaultStyles
);
372 pCellStyles
.reset( new ScFormatRangeStyles() );
374 // document is not set here - create ScChangeTrackingExportHelper later
376 xScPropHdlFactory
= new XMLScPropHdlFactory
;
377 xCellStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScCellStylesProperties
, xScPropHdlFactory
, true);
378 xColumnStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScColumnStylesProperties
, xScPropHdlFactory
, true);
379 xRowStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScRowStylesProperties
, xScPropHdlFactory
, true);
380 xTableStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScTableStylesProperties
, xScPropHdlFactory
, true);
381 xCellStylesExportPropertySetMapper
= new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper
);
382 xCellStylesExportPropertySetMapper
->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
383 xColumnStylesExportPropertySetMapper
= new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper
);
384 xRowStylesExportPropertySetMapper
= new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper
);
385 xTableStylesExportPropertySetMapper
= new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper
);
387 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_CELL
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
,
388 xCellStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
);
389 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_COLUMN
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME
,
390 xColumnStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX
);
391 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_ROW
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME
,
392 xRowStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX
);
393 GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_TABLE
, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME
,
394 xTableStylesExportPropertySetMapper
, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX
);
396 if( !(getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
)) )
399 // This name is reserved for the external ref cache tables. This
400 // should not conflict with user-defined styles since this name is
401 // used for a table style which is not available in the UI.
402 sExternalRefTabStyleName
= "ta_extref";
403 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE
, sExternalRefTabStyleName
);
405 sAttrName
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_NAME
));
406 sAttrStyleName
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_STYLE_NAME
));
407 sAttrColumnsRepeated
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED
));
408 sAttrFormula
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_FORMULA
));
409 sAttrStringValue
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_STRING_VALUE
));
410 sAttrValueType
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_VALUE_TYPE
));
411 sElemCell
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_CELL
));
412 sElemCoveredCell
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_COVERED_TABLE_CELL
));
413 sElemCol
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_COLUMN
));
414 sElemRow
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE_ROW
));
415 sElemTab
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE
, GetXMLToken(XML_TABLE
));
416 sElemP
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
419 ScXMLExport::~ScXMLExport()
421 pGroupColumns
.reset();
423 pColumnStyles
.reset();
426 pRowFormatRanges
.reset();
427 pMergedRangesContainer
.reset();
428 pValidationsContainer
.reset();
429 pChangeTrackingExportHelper
.reset();
431 pNumberFormatAttributesExportHelper
.reset();
434 void ScXMLExport::SetSourceStream( const uno::Reference
<io::XInputStream
>& xNewStream
)
436 xSourceStream
= xNewStream
;
438 if ( !xSourceStream
.is() )
441 // make sure it's a plain UTF-8 stream as written by OOo itself
443 const char pXmlHeader
[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
444 sal_Int32 nLen
= strlen(pXmlHeader
);
446 uno::Sequence
<sal_Int8
> aFileStart(nLen
);
447 sal_Int32 nRead
= xSourceStream
->readBytes( aFileStart
, nLen
);
449 if ( nRead
!= nLen
|| memcmp( aFileStart
.getConstArray(), pXmlHeader
, nLen
) != 0 )
451 // invalid - ignore stream, save normally
452 xSourceStream
.clear();
456 // keep track of the bytes already read
457 nSourceStreamPos
= nRead
;
459 const ScSheetSaveData
* pSheetData
= comphelper::getUnoTunnelImplementation
<ScModelObj
>(GetModel())->GetSheetSaveData();
462 // add the loaded namespaces to the name space map
464 if ( !pSheetData
->AddLoadedNamespaces( GetNamespaceMap_() ) )
466 // conflicts in the namespaces - ignore the stream, save normally
467 xSourceStream
.clear();
473 sal_Int32
ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt
) const
475 NumberFormatIndexMap::const_iterator itr
= aNumFmtIndexMap
.find(nNumFmt
);
476 if (itr
== aNumFmtIndexMap
.end())
482 void ScXMLExport::CollectSharedData(SCTAB
& nTableCount
, sal_Int32
& nShapesCount
)
484 if (!GetModel().is())
487 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc(GetModel(), uno::UNO_QUERY
);
488 if (!xSpreadDoc
.is())
491 uno::Reference
<container::XIndexAccess
> xIndex(xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
495 nTableCount
= xIndex
->getCount();
497 pSharedData
.reset(new ScMySharedData(nTableCount
));
499 pCellStyles
->AddNewTable(nTableCount
- 1);
501 for (SCTAB nTable
= 0; nTable
< nTableCount
; ++nTable
)
503 nCurrentTable
= sal::static_int_cast
<sal_uInt16
>(nTable
);
504 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
505 if (!xDrawPageSupplier
.is())
508 uno::Reference
<drawing::XDrawPage
> xDrawPage(xDrawPageSupplier
->getDrawPage());
509 ScMyDrawPage aDrawPage
;
510 aDrawPage
.bHasForms
= false;
511 aDrawPage
.xDrawPage
.set(xDrawPage
);
512 pSharedData
->AddDrawPage(aDrawPage
, nTable
);
516 sal_Int32 nShapes
= xDrawPage
->getCount();
517 for (sal_Int32 nShape
= 0; nShape
< nShapes
; ++nShape
)
519 uno::Reference
<drawing::XShape
> xShape(xDrawPage
->getByIndex(nShape
), uno::UNO_QUERY
);
523 uno::Reference
<beans::XPropertySet
> xShapeProp(xShape
, uno::UNO_QUERY
);
524 if (!xShapeProp
.is())
527 sal_Int16 nLayerID
= 0;
528 bool bExtracted
= xShapeProp
->getPropertyValue(gsLayerID
) >>= nLayerID
;
532 if ((SdrLayerID(nLayerID
) == SC_LAYER_INTERN
) || (SdrLayerID(nLayerID
) == SC_LAYER_HIDDEN
))
534 CollectInternalShape(xShape
);
540 SvxShape
* pShapeImp
= comphelper::getUnoTunnelImplementation
<SvxShape
>(xShape
);
544 SdrObject
* pSdrObj
= pShapeImp
->GetSdrObject();
548 if (ScDrawObjData
*pAnchor
= ScDrawLayer::GetNonRotatedObjData(pSdrObj
))
551 aMyShape
.aAddress
= pAnchor
->maStart
;
552 SAL_WARN_IF(aMyShape
.aAddress
.Tab() != nTable
, "sc", "not anchored to current sheet!");
553 aMyShape
.aAddress
.SetTab(nTable
);
554 aMyShape
.aEndAddress
= pAnchor
->maEnd
;
555 aMyShape
.aEndAddress
.SetTab( nTable
);
556 aMyShape
.nEndX
= pAnchor
->maEndOffset
.X();
557 aMyShape
.nEndY
= pAnchor
->maEndOffset
.Y();
558 aMyShape
.xShape
= xShape
;
559 aMyShape
.bResizeWithCell
= ScDrawLayer::IsResizeWithCell(*pSdrObj
);
560 pSharedData
->AddNewShape(aMyShape
);
561 pSharedData
->SetLastColumn(nTable
, pAnchor
->maStart
.Col());
562 pSharedData
->SetLastRow(nTable
, pAnchor
->maStart
.Row());
565 pSharedData
->AddTableShape(nTable
, xShape
);
570 void ScXMLExport::CollectShapesAutoStyles(SCTAB nTableCount
)
572 // #i84077# To avoid compiler warnings about uninitialized aShapeItr,
573 // it's initialized using this dummy list. The iterator contains shapes
574 // from all sheets, so it can't be declared inside the nTable loop where
576 ScMyShapeList aDummyInitList
;
578 pSharedData
->SortShapesContainer();
579 pSharedData
->SortNoteShapes();
580 const ScMyShapeList
* pShapeList(nullptr);
581 ScMyShapeList::const_iterator aShapeItr
= aDummyInitList
.end();
582 if (pSharedData
->GetShapesContainer())
584 pShapeList
= &pSharedData
->GetShapesContainer()->GetShapes();
585 aShapeItr
= pShapeList
->begin();
587 if (pSharedData
->HasDrawPage())
589 for (SCTAB nTable
= 0; nTable
< nTableCount
; ++nTable
)
591 uno::Reference
<drawing::XDrawPage
> xDrawPage(pSharedData
->GetDrawPage(nTable
));
595 GetShapeExport()->seekShapes(xDrawPage
);
596 uno::Reference
< form::XFormsSupplier2
> xFormsSupplier( xDrawPage
, uno::UNO_QUERY
);
597 if( xFormsSupplier
.is() && xFormsSupplier
->hasForms() )
599 GetFormExport()->examineForms(xDrawPage
);
600 pSharedData
->SetDrawPageHasForms(nTable
, true);
602 ScMyTableShapes
* pTableShapes(pSharedData
->GetTableShapes());
605 for (const auto& rxShape
: (*pTableShapes
)[nTable
])
607 GetShapeExport()->collectShapeAutoStyles(rxShape
);
608 IncrementProgressBar(false);
613 ScMyShapeList::const_iterator
aEndItr(pShapeList
->end());
614 while ( aShapeItr
!= aEndItr
&& ( aShapeItr
->aAddress
.Tab() == nTable
) )
616 GetShapeExport()->collectShapeAutoStyles(aShapeItr
->xShape
);
617 IncrementProgressBar(false);
621 if (pSharedData
->GetNoteShapes())
623 const ScMyNoteShapeList
& rNoteShapes
= pSharedData
->GetNoteShapes()->GetNotes();
624 for (const auto& rNoteShape
: rNoteShapes
)
626 if ( rNoteShape
.aPos
.Tab() == nTable
)
627 GetShapeExport()->collectShapeAutoStyles(rNoteShape
.xShape
);
633 pSharedData
->SortNoteShapes(); // sort twice, because some more shapes are added
636 void ScXMLExport::ExportMeta_()
638 sal_Int32
nCellCount(pDoc
? pDoc
->GetCellCount() : 0);
639 SCTAB
nTableCount(0);
640 sal_Int32
nShapesCount(0);
641 GetAutoStylePool()->ClearEntries();
642 CollectSharedData(nTableCount
, nShapesCount
);
644 uno::Sequence
<beans::NamedValue
> stats
646 { "TableCount", uno::makeAny(static_cast<sal_Int32
>(nTableCount
)) },
647 { "CellCount", uno::makeAny(nCellCount
) },
648 { "ObjectCount", uno::makeAny(nShapesCount
) }
651 // update document statistics at the model
652 uno::Reference
<document::XDocumentPropertiesSupplier
> xPropSup(GetModel(),
653 uno::UNO_QUERY_THROW
);
654 uno::Reference
<document::XDocumentProperties
> xDocProps(
655 xPropSup
->getDocumentProperties());
656 if (xDocProps
.is()) {
657 xDocProps
->setDocumentStatistics(stats
);
660 // export document properties
661 SvXMLExport::ExportMeta_();
664 void ScXMLExport::ExportFontDecls_()
666 GetFontAutoStylePool(); // make sure the pool is created
667 SvXMLExport::ExportFontDecls_();
670 table::CellRangeAddress
ScXMLExport::GetEndAddress(const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
672 table::CellRangeAddress aCellAddress
;
673 uno::Reference
<sheet::XSheetCellCursor
> xCursor(xTable
->createCursor());
674 uno::Reference
<sheet::XUsedAreaCursor
> xUsedArea (xCursor
, uno::UNO_QUERY
);
675 uno::Reference
<sheet::XCellRangeAddressable
> xCellAddress (xCursor
, uno::UNO_QUERY
);
676 if (xUsedArea
.is() && xCellAddress
.is())
678 xUsedArea
->gotoEndOfUsedArea(true);
679 aCellAddress
= xCellAddress
->getRangeAddress();
684 void ScXMLExport::GetAreaLinks( ScMyAreaLinksContainer
& rAreaLinks
)
686 if (pDoc
->GetLinkManager())
688 const sfx2::SvBaseLinks
& rLinks
= pDoc
->GetLinkManager()->GetLinks();
689 for (const auto & rLink
: rLinks
)
691 ScAreaLink
*pLink
= dynamic_cast<ScAreaLink
*>(rLink
.get());
694 ScMyAreaLink aAreaLink
;
695 aAreaLink
.aDestRange
= pLink
->GetDestArea();
696 aAreaLink
.sSourceStr
= pLink
->GetSource();
697 aAreaLink
.sFilter
= pLink
->GetFilter();
698 aAreaLink
.sFilterOptions
= pLink
->GetOptions();
699 aAreaLink
.sURL
= pLink
->GetFile();
700 aAreaLink
.nRefresh
= pLink
->GetRefreshDelay();
701 rAreaLinks
.AddNewAreaLink( aAreaLink
);
708 // core implementation
709 void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer
& rDetOp
)
714 ScDetOpList
* pOpList(pDoc
->GetDetOpList());
718 size_t nCount
= pOpList
->Count();
719 for (size_t nIndex
= 0; nIndex
< nCount
; ++nIndex
)
721 const ScDetOpData
& rDetData
= pOpList
->GetObject( nIndex
);
722 const ScAddress
& rDetPos
= rDetData
.GetPos();
723 SCTAB nTab
= rDetPos
.Tab();
724 if ( nTab
< pDoc
->GetTableCount() )
726 rDetOp
.AddOperation( rDetData
.GetOperation(), rDetPos
, static_cast<sal_uInt32
>( nIndex
) );
728 // cells with detective operations are written even if empty
729 pSharedData
->SetLastColumn( nTab
, rDetPos
.Col() );
730 pSharedData
->SetLastRow( nTab
, rDetPos
.Row() );
736 void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns
, const sal_Int32 nStyleIndex
,
737 const sal_Int32 nIndex
, const bool bIsAutoStyle
, const bool bIsVisible
)
741 if (nStyleIndex
!= -1)
742 AddAttribute(sAttrStyleName
, pColumnStyles
->GetStyleNameByIndex(nStyleIndex
));
744 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_COLLAPSE
);
745 if (nRepeatColumns
> 1)
747 OUString
sOUEndCol(OUString::number(nRepeatColumns
));
748 AddAttribute(sAttrColumnsRepeated
, sOUEndCol
);
751 AddAttribute(XML_NAMESPACE_TABLE
, XML_DEFAULT_CELL_STYLE_NAME
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
752 SvXMLElementExport
aElemC(*this, sElemCol
, true, true);
755 void ScXMLExport::WriteColumn(const sal_Int32 nColumn
, const sal_Int32 nRepeatColumns
,
756 const sal_Int32 nStyleIndex
, const bool bIsVisible
)
758 sal_Int32
nRepeat(1);
759 sal_Int32
nPrevIndex(pDefaults
->GetColDefaults()[nColumn
].nIndex
);
760 bool bPrevAutoStyle(pDefaults
->GetColDefaults()[nColumn
].bIsAutoStyle
);
761 for (sal_Int32 i
= nColumn
+ 1; i
< nColumn
+ nRepeatColumns
; ++i
)
763 if ((pDefaults
->GetColDefaults()[i
].nIndex
!= nPrevIndex
) ||
764 (pDefaults
->GetColDefaults()[i
].bIsAutoStyle
!= bPrevAutoStyle
))
766 WriteSingleColumn(nRepeat
, nStyleIndex
, nPrevIndex
, bPrevAutoStyle
, bIsVisible
);
767 nPrevIndex
= pDefaults
->GetColDefaults()[i
].nIndex
;
768 bPrevAutoStyle
= pDefaults
->GetColDefaults()[i
].bIsAutoStyle
;
774 WriteSingleColumn(nRepeat
, nStyleIndex
, nPrevIndex
, bPrevAutoStyle
, bIsVisible
);
777 void ScXMLExport::OpenHeaderColumn()
779 StartElement( XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, true );
782 void ScXMLExport::CloseHeaderColumn()
784 EndElement(XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_COLUMNS
, true);
787 void ScXMLExport::ExportColumns(const sal_Int32 nTable
, const ScRange
& aColumnHeaderRange
, const bool bHasColumnHeader
)
789 sal_Int32
nColsRepeated (1);
791 sal_Int32
nPrevColumn(0);
792 bool bPrevIsVisible (true);
793 bool bWasHeader (false);
794 bool bIsClosed (true);
795 sal_Int32
nPrevIndex (-1);
797 for (nColumn
= 0; nColumn
<= pSharedData
->GetLastColumn(nTable
); ++nColumn
)
800 bool bIsVisible(true);
801 nIndex
= pColumnStyles
->GetStyleNameIndex(nTable
, nColumn
, bIsVisible
);
803 const bool bIsHeader
= bHasColumnHeader
&& (aColumnHeaderRange
.aStart
.Col() <= nColumn
) && (nColumn
<= aColumnHeaderRange
.aEnd
.Col());
804 if (bIsHeader
!= bWasHeader
)
810 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
811 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
812 pGroupColumns
->CloseGroups(nColumn
- 1);
814 bPrevIsVisible
= bIsVisible
;
816 nPrevColumn
= nColumn
;
818 if(pGroupColumns
->IsGroupStart(nColumn
))
819 pGroupColumns
->OpenGroups(nColumn
);
826 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
828 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
829 pGroupColumns
->CloseGroups(nColumn
- 1);
830 if(pGroupColumns
->IsGroupStart(nColumn
))
831 pGroupColumns
->OpenGroups(nColumn
);
832 bPrevIsVisible
= bIsVisible
;
834 nPrevColumn
= nColumn
;
840 else if (nColumn
== 0)
842 if (pGroupColumns
->IsGroupStart(nColumn
))
843 pGroupColumns
->OpenGroups(nColumn
);
844 bPrevIsVisible
= bIsVisible
;
847 else if ((bIsVisible
== bPrevIsVisible
) && (nIndex
== nPrevIndex
) &&
848 !pGroupColumns
->IsGroupStart(nColumn
) && !pGroupColumns
->IsGroupEnd(nColumn
- 1))
852 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
853 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
857 pGroupColumns
->CloseGroups(nColumn
- 1);
861 if (pGroupColumns
->IsGroupStart(nColumn
))
865 pGroupColumns
->OpenGroups(nColumn
);
869 bPrevIsVisible
= bIsVisible
;
871 nPrevColumn
= nColumn
;
875 WriteColumn(nPrevColumn
, nColsRepeated
, nPrevIndex
, bPrevIsVisible
);
878 if (pGroupColumns
->IsGroupEnd(nColumn
- 1))
879 pGroupColumns
->CloseGroups(nColumn
- 1);
882 void ScXMLExport::ExportExternalRefCacheStyles()
884 sal_Int32 nEntryIndex
= GetCellStylesPropertySetMapper()->FindEntryIndex(
885 "NumberFormat", XML_NAMESPACE_STYLE
, "data-style-name");
888 // No entry index for the number format is found.
891 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
892 if (!pRefMgr
->hasExternalData())
893 // No external reference data cached.
896 // Export each unique number format used in the external ref cache.
897 vector
<sal_uInt32
> aNumFmts
;
898 pRefMgr
->getAllCachedNumberFormats(aNumFmts
);
899 const OUString aDefaultStyle
= OUString("Default").intern();
900 for (const auto& rNumFmt
: aNumFmts
)
902 sal_Int32 nNumFmt
= static_cast<sal_Int32
>(rNumFmt
);
904 addDataStyle(nNumFmt
);
908 vector
<XMLPropertyState
> aProps
;
909 aVal
<<= aDefaultStyle
;
910 aProps
.emplace_back(nEntryIndex
, aVal
);
914 if (GetAutoStylePool()->Add(aName
, XmlStyleFamily::TABLE_CELL
, aDefaultStyle
, aProps
))
916 pCellStyles
->AddStyleName(aName
, nIndex
);
921 nIndex
= pCellStyles
->GetIndexOfStyleName(
922 aName
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
, bIsAuto
);
925 // store the number format to index mapping for later use.
926 aNumFmtIndexMap
.emplace(nNumFmt
, nIndex
);
933 std::vector
<XMLPropertyState
>& rPropStates
,
934 const SfxPoolItem
* p
, const rtl::Reference
<XMLPropertySetMapper
>& xMapper
, const OUString
& rXMLName
)
936 sal_Int32 nEntryCount
= xMapper
->GetEntryCount();
938 // Apparently font info needs special handling.
939 const SvxFontItem
* pItem
= static_cast<const SvxFontItem
*>(p
);
941 sal_Int32 nIndexFontName
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, rXMLName
, 0);
943 if (nIndexFontName
== -1 || nIndexFontName
>= nEntryCount
)
947 if (!pItem
->QueryValue(aAny
, MID_FONT_FAMILY_NAME
))
950 rPropStates
.emplace_back(nIndexFontName
, aAny
);
953 const SvxFieldData
* toXMLPropertyStates(
954 std::vector
<XMLPropertyState
>& rPropStates
, const std::vector
<const SfxPoolItem
*>& rSecAttrs
,
955 const rtl::Reference
<XMLPropertySetMapper
>& xMapper
, const ScXMLEditAttributeMap
& rAttrMap
)
957 const SvxFieldData
* pField
= nullptr;
958 sal_Int32 nEntryCount
= xMapper
->GetEntryCount();
959 rPropStates
.reserve(rSecAttrs
.size());
960 for (const SfxPoolItem
* p
: rSecAttrs
)
962 if (p
->Which() == EE_FEATURE_FIELD
)
964 pField
= static_cast<const SvxFieldItem
*>(p
)->GetField();
968 const ScXMLEditAttributeMap::Entry
* pEntry
= rAttrMap
.getEntryByItemID(p
->Which());
972 sal_Int32 nIndex
= xMapper
->GetEntryIndex(
973 pEntry
->nmXMLNS
, OUString::createFromAscii(pEntry
->mpXMLName
), 0);
975 if (nIndex
== -1 || nIndex
>= nEntryCount
)
981 case EE_CHAR_FONTINFO
:
982 handleFont(rPropStates
, p
, xMapper
, "font-name");
984 case EE_CHAR_FONTINFO_CJK
:
985 handleFont(rPropStates
, p
, xMapper
, "font-name-asian");
987 case EE_CHAR_FONTINFO_CTL
:
988 handleFont(rPropStates
, p
, xMapper
, "font-name-complex");
991 case EE_CHAR_WEIGHT_CJK
:
992 case EE_CHAR_WEIGHT_CTL
:
994 if (!static_cast<const SvxWeightItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
997 rPropStates
.emplace_back(nIndex
, aAny
);
1000 case EE_CHAR_FONTHEIGHT
:
1001 case EE_CHAR_FONTHEIGHT_CJK
:
1002 case EE_CHAR_FONTHEIGHT_CTL
:
1004 if (!static_cast<const SvxFontHeightItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1007 rPropStates
.emplace_back(nIndex
, aAny
);
1010 case EE_CHAR_ITALIC
:
1011 case EE_CHAR_ITALIC_CJK
:
1012 case EE_CHAR_ITALIC_CTL
:
1014 if (!static_cast<const SvxPostureItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1017 rPropStates
.emplace_back(nIndex
, aAny
);
1020 case EE_CHAR_UNDERLINE
:
1022 // Underline attribute needs to export multiple entries.
1023 sal_Int32 nIndexStyle
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, "text-underline-style", 0);
1024 if (nIndexStyle
== -1 || nIndexStyle
> nEntryCount
)
1027 sal_Int32 nIndexWidth
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, "text-underline-width", 0);
1028 if (nIndexWidth
== -1 || nIndexWidth
> nEntryCount
)
1031 sal_Int32 nIndexType
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, "text-underline-type", 0);
1032 if (nIndexType
== -1 || nIndexType
> nEntryCount
)
1035 sal_Int32 nIndexColor
= xMapper
->FindEntryIndex("CharUnderlineColor", XML_NAMESPACE_STYLE
, "text-underline-color");
1036 if (nIndexColor
== -1 || nIndexColor
> nEntryCount
)
1039 sal_Int32 nIndexHasColor
= xMapper
->FindEntryIndex("CharUnderlineHasColor", XML_NAMESPACE_STYLE
, "text-underline-color");
1040 if (nIndexHasColor
== -1 || nIndexHasColor
> nEntryCount
)
1043 const SvxUnderlineItem
* pUL
= static_cast<const SvxUnderlineItem
*>(p
);
1044 pUL
->QueryValue(aAny
, MID_TL_STYLE
);
1045 rPropStates
.emplace_back(nIndexStyle
, aAny
);
1046 rPropStates
.emplace_back(nIndexType
, aAny
);
1047 rPropStates
.emplace_back(nIndexWidth
, aAny
);
1049 pUL
->QueryValue(aAny
, MID_TL_COLOR
);
1050 rPropStates
.emplace_back(nIndexColor
, aAny
);
1052 pUL
->QueryValue(aAny
, MID_TL_HASCOLOR
);
1053 rPropStates
.emplace_back(nIndexHasColor
, aAny
);
1056 case EE_CHAR_OVERLINE
:
1058 // Same with overline. Do just as we do with underline attributes.
1059 sal_Int32 nIndexStyle
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, "text-overline-style", 0);
1060 if (nIndexStyle
== -1 || nIndexStyle
> nEntryCount
)
1063 sal_Int32 nIndexWidth
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, "text-overline-width", 0);
1064 if (nIndexWidth
== -1 || nIndexWidth
> nEntryCount
)
1067 sal_Int32 nIndexType
= xMapper
->GetEntryIndex(XML_NAMESPACE_STYLE
, "text-overline-type", 0);
1068 if (nIndexType
== -1 || nIndexType
> nEntryCount
)
1071 sal_Int32 nIndexColor
= xMapper
->FindEntryIndex("CharOverlineColor", XML_NAMESPACE_STYLE
, "text-overline-color");
1072 if (nIndexColor
== -1 || nIndexColor
> nEntryCount
)
1075 sal_Int32 nIndexHasColor
= xMapper
->FindEntryIndex("CharOverlineHasColor", XML_NAMESPACE_STYLE
, "text-overline-color");
1076 if (nIndexHasColor
== -1 || nIndexHasColor
> nEntryCount
)
1079 const SvxOverlineItem
* pOL
= static_cast<const SvxOverlineItem
*>(p
);
1080 pOL
->QueryValue(aAny
, MID_TL_STYLE
);
1081 rPropStates
.emplace_back(nIndexStyle
, aAny
);
1082 rPropStates
.emplace_back(nIndexType
, aAny
);
1083 rPropStates
.emplace_back(nIndexWidth
, aAny
);
1085 pOL
->QueryValue(aAny
, MID_TL_COLOR
);
1086 rPropStates
.emplace_back(nIndexColor
, aAny
);
1088 pOL
->QueryValue(aAny
, MID_TL_HASCOLOR
);
1089 rPropStates
.emplace_back(nIndexHasColor
, aAny
);
1094 if (!static_cast<const SvxColorItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1098 if ( aAny
>>= nColor
)
1100 sal_Int32 nIndexColor
= ( nColor
== COL_AUTO
) ? xMapper
->GetEntryIndex(
1101 XML_NAMESPACE_STYLE
, GetXMLToken( XML_USE_WINDOW_FONT_COLOR
), 0 ) : nIndex
;
1102 rPropStates
.emplace_back( nIndexColor
, aAny
);
1108 if (!static_cast<const SvxWordLineModeItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1111 rPropStates
.emplace_back(nIndex
, aAny
);
1114 case EE_CHAR_STRIKEOUT
:
1116 if (!static_cast<const SvxCrossedOutItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1119 rPropStates
.emplace_back(nIndex
, aAny
);
1122 case EE_CHAR_RELIEF
:
1124 if (!static_cast<const SvxCharReliefItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1127 rPropStates
.emplace_back(nIndex
, aAny
);
1130 case EE_CHAR_OUTLINE
:
1132 if (!static_cast<const SvxContourItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1135 rPropStates
.emplace_back(nIndex
, aAny
);
1138 case EE_CHAR_SHADOW
:
1140 if (!static_cast<const SvxShadowedItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1143 rPropStates
.emplace_back(nIndex
, aAny
);
1146 case EE_CHAR_KERNING
:
1148 if (!static_cast<const SvxKerningItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1151 rPropStates
.emplace_back(nIndex
, aAny
);
1154 case EE_CHAR_PAIRKERNING
:
1156 if (!static_cast<const SvxAutoKernItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1159 rPropStates
.emplace_back(nIndex
, aAny
);
1162 case EE_CHAR_FONTWIDTH
:
1164 if (!static_cast<const SvxCharScaleWidthItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1167 rPropStates
.emplace_back(nIndex
, aAny
);
1170 case EE_CHAR_ESCAPEMENT
:
1172 sal_Int32 nIndexEsc
= xMapper
->FindEntryIndex("CharEscapement", XML_NAMESPACE_STYLE
, "text-position");
1173 if (nIndexEsc
== -1 || nIndexEsc
> nEntryCount
)
1176 sal_Int32 nIndexEscHeight
= xMapper
->FindEntryIndex("CharEscapementHeight", XML_NAMESPACE_STYLE
, "text-position");
1177 if (nIndexEscHeight
== -1 || nIndexEscHeight
> nEntryCount
)
1180 const SvxEscapementItem
* pEsc
= static_cast<const SvxEscapementItem
*>(p
);
1182 pEsc
->QueryValue(aAny
);
1183 rPropStates
.emplace_back(nIndexEsc
, aAny
);
1185 pEsc
->QueryValue(aAny
, MID_ESC_HEIGHT
);
1186 rPropStates
.emplace_back(nIndexEscHeight
, aAny
);
1190 case EE_CHAR_EMPHASISMARK
:
1192 if (!static_cast<const SvxEmphasisMarkItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1195 rPropStates
.emplace_back(nIndex
, aAny
);
1198 case EE_CHAR_LANGUAGE
:
1199 case EE_CHAR_LANGUAGE_CJK
:
1200 case EE_CHAR_LANGUAGE_CTL
:
1202 if (!static_cast<const SvxLanguageItem
*>(p
)->QueryValue(aAny
, pEntry
->mnFlag
))
1205 // Export multiple entries.
1206 sal_Int32 nIndexLanguage
, nIndexCountry
, nIndexScript
, nIndexTag
;
1209 case EE_CHAR_LANGUAGE
:
1210 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, "language", 0);
1211 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, "country", 0);
1212 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_FO
, "script", 0);
1213 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "rfc-language-tag", 0);
1215 case EE_CHAR_LANGUAGE_CJK
:
1216 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "language-asian", 0);
1217 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "country-asian", 0);
1218 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "script-asian", 0);
1219 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "rfc-language-tag-asian", 0);
1221 case EE_CHAR_LANGUAGE_CTL
:
1222 nIndexLanguage
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "language-complex", 0);
1223 nIndexCountry
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "country-complex", 0);
1224 nIndexScript
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "script-complex", 0);
1225 nIndexTag
= xMapper
->GetEntryIndex( XML_NAMESPACE_STYLE
, "rfc-language-tag-complex", 0);
1228 nIndexLanguage
= nIndexCountry
= nIndexScript
= nIndexTag
= -1;
1230 assert( nIndexLanguage
>= 0 && nIndexCountry
>= 0 && nIndexScript
>= 0 && nIndexTag
>= 0);
1231 rPropStates
.emplace_back( nIndexLanguage
, aAny
);
1232 rPropStates
.emplace_back( nIndexCountry
, aAny
);
1233 rPropStates
.emplace_back( nIndexScript
, aAny
);
1234 rPropStates
.emplace_back( nIndexTag
, aAny
);
1247 void ScXMLExport::ExportCellTextAutoStyles(sal_Int32 nTable
)
1249 if (!ValidTab(nTable
))
1252 rtl::Reference
<XMLPropertySetMapper
> xMapper
= GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
1253 rtl::Reference
<SvXMLAutoStylePoolP
> xStylePool
= GetAutoStylePool();
1254 const ScXMLEditAttributeMap
& rAttrMap
= GetEditAttributeMap();
1256 sc::EditTextIterator
aIter(*pDoc
, nTable
);
1257 sal_Int32 nCellCount
= 0;
1258 for (const EditTextObject
* pEdit
= aIter
.first(); pEdit
; pEdit
= aIter
.next(), ++nCellCount
)
1260 std::vector
<editeng::Section
> aAttrs
;
1261 pEdit
->GetAllSections(aAttrs
);
1265 for (const auto& rSec
: aAttrs
)
1267 const std::vector
<const SfxPoolItem
*>& rSecAttrs
= rSec
.maAttributes
;
1268 if (rSecAttrs
.empty())
1269 // No formats applied to this section. Skip it.
1272 std::vector
<XMLPropertyState
> aPropStates
;
1273 toXMLPropertyStates(aPropStates
, rSecAttrs
, xMapper
, rAttrMap
);
1274 if (!aPropStates
.empty())
1275 xStylePool
->Add(XmlStyleFamily::TEXT_TEXT
, OUString(), aPropStates
);
1279 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCellCount
);
1282 void ScXMLExport::WriteRowContent()
1284 ScMyRowFormatRange aRange
;
1285 sal_Int32
nIndex(-1);
1286 #if OSL_DEBUG_LEVEL > 0
1287 sal_Int32
nPrevCol(0);
1290 sal_Int32
nPrevValidationIndex(-1);
1291 bool bIsAutoStyle(true);
1292 bool bIsFirst(true);
1293 while (pRowFormatRanges
->GetNext(aRange
))
1295 #if OSL_DEBUG_LEVEL > 0
1296 OSL_ENSURE(bIsFirst
|| (!bIsFirst
&& (nPrevCol
+ nCols
== aRange
.nStartColumn
)), "here are some columns missing");
1300 nIndex
= aRange
.nIndex
;
1301 nPrevValidationIndex
= aRange
.nValidationIndex
;
1302 bIsAutoStyle
= aRange
.bIsAutoStyle
;
1303 nCols
= aRange
.nRepeatColumns
;
1305 #if OSL_DEBUG_LEVEL > 0
1306 nPrevCol
= aRange
.nStartColumn
;
1311 if (((aRange
.nIndex
== nIndex
&& aRange
.bIsAutoStyle
== bIsAutoStyle
) ||
1312 (aRange
.nIndex
== nIndex
&& nIndex
== -1)) &&
1313 nPrevValidationIndex
== aRange
.nValidationIndex
)
1314 nCols
+= aRange
.nRepeatColumns
;
1318 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
1319 if (nPrevValidationIndex
> -1)
1320 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(nPrevValidationIndex
));
1323 AddAttribute(sAttrColumnsRepeated
, OUString::number(nCols
));
1325 SvXMLElementExport
aElemC(*this, sElemCell
, true, true);
1326 nIndex
= aRange
.nIndex
;
1327 bIsAutoStyle
= aRange
.bIsAutoStyle
;
1328 nCols
= aRange
.nRepeatColumns
;
1329 nPrevValidationIndex
= aRange
.nValidationIndex
;
1330 #if OSL_DEBUG_LEVEL > 0
1331 nPrevCol
= aRange
.nStartColumn
;
1339 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(nIndex
, bIsAutoStyle
));
1340 if (nPrevValidationIndex
> -1)
1341 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(nPrevValidationIndex
));
1344 AddAttribute(sAttrColumnsRepeated
, OUString::number(nCols
));
1346 SvXMLElementExport
aElemC(*this, sElemCell
, true, true);
1350 void ScXMLExport::WriteRowStartTag(
1351 const sal_Int32 nIndex
, const sal_Int32 nEqualRows
,
1352 bool bHidden
, bool bFiltered
)
1356 AddAttribute(sAttrStyleName
, pRowStyles
->GetStyleNameByIndex(nIndex
));
1360 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_FILTER
);
1362 AddAttribute(XML_NAMESPACE_TABLE
, XML_VISIBILITY
, XML_COLLAPSE
);
1366 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, OUString::number(nEqualRows
));
1369 StartElement( sElemRow
, true);
1372 void ScXMLExport::OpenHeaderRows()
1374 StartElement( XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, true);
1375 bRowHeaderOpen
= true;
1378 void ScXMLExport::CloseHeaderRows()
1380 EndElement(XML_NAMESPACE_TABLE
, XML_TABLE_HEADER_ROWS
, true);
1383 void ScXMLExport::OpenNewRow(
1384 const sal_Int32 nIndex
, const sal_Int32 nStartRow
, const sal_Int32 nEqualRows
,
1385 bool bHidden
, bool bFiltered
)
1387 nOpenRow
= nStartRow
;
1388 if (pGroupRows
->IsGroupStart(nStartRow
))
1390 if (bHasRowHeader
&& bRowHeaderOpen
)
1392 pGroupRows
->OpenGroups(nStartRow
);
1393 if (bHasRowHeader
&& bRowHeaderOpen
)
1396 if (bHasRowHeader
&& !bRowHeaderOpen
&& nStartRow
>= aRowHeaderRange
.aStart
.Row() && nStartRow
<= aRowHeaderRange
.aEnd
.Row())
1398 if (nStartRow
== aRowHeaderRange
.aStart
.Row())
1401 if (aRowHeaderRange
.aEnd
.Row() < nStartRow
+ nEqualRows
- 1)
1402 nEquals
= aRowHeaderRange
.aEnd
.Row() - nStartRow
+ 1;
1404 nEquals
= nEqualRows
;
1405 WriteRowStartTag(nIndex
, nEquals
, bHidden
, bFiltered
);
1406 nOpenRow
= nStartRow
+ nEquals
- 1;
1407 if (nEquals
< nEqualRows
)
1409 CloseRow(nStartRow
+ nEquals
- 1);
1410 WriteRowStartTag(nIndex
, nEqualRows
- nEquals
, bHidden
, bFiltered
);
1411 nOpenRow
= nStartRow
+ nEqualRows
- 1;
1415 WriteRowStartTag(nIndex
, nEqualRows
, bHidden
, bFiltered
);
1418 void ScXMLExport::OpenAndCloseRow(
1419 const sal_Int32 nIndex
, const sal_Int32 nStartRow
, const sal_Int32 nEqualRows
,
1420 bool bHidden
, bool bFiltered
)
1422 OpenNewRow(nIndex
, nStartRow
, nEqualRows
, bHidden
, bFiltered
);
1424 CloseRow(nStartRow
+ nEqualRows
- 1);
1425 pRowFormatRanges
->Clear();
1428 void ScXMLExport::OpenRow(const sal_Int32 nTable
, const sal_Int32 nStartRow
, const sal_Int32 nRepeatRow
, ScXMLCachedRowAttrAccess
& rRowAttr
)
1432 sal_Int32
nPrevIndex(0), nIndex
;
1433 bool bPrevHidden
= false;
1434 bool bPrevFiltered
= false;
1435 bool bHidden
= false;
1436 bool bFiltered
= false;
1437 sal_Int32
nEqualRows(1);
1438 sal_Int32
nEndRow(nStartRow
+ nRepeatRow
);
1439 sal_Int32 nEndRowHidden
= nStartRow
- 1;
1440 sal_Int32 nEndRowFiltered
= nStartRow
- 1;
1442 for (nRow
= nStartRow
; nRow
< nEndRow
; ++nRow
)
1444 if (nRow
== nStartRow
)
1446 nPrevIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nRow
);
1449 if (nRow
> nEndRowHidden
)
1451 bPrevHidden
= rRowAttr
.rowHidden(nTable
, nRow
, nEndRowHidden
);
1452 bHidden
= bPrevHidden
;
1454 if (nRow
> nEndRowFiltered
)
1456 bPrevFiltered
= rRowAttr
.rowFiltered(nTable
, nRow
, nEndRowFiltered
);
1457 bFiltered
= bPrevFiltered
;
1464 nIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nRow
);
1467 if (nRow
> nEndRowHidden
)
1468 bHidden
= rRowAttr
.rowHidden(nTable
, nRow
, nEndRowHidden
);
1469 if (nRow
> nEndRowFiltered
)
1470 bFiltered
= rRowAttr
.rowFiltered(nTable
, nRow
, nEndRowFiltered
);
1472 if (nIndex
== nPrevIndex
&& bHidden
== bPrevHidden
&& bFiltered
== bPrevFiltered
&&
1473 !(bHasRowHeader
&& ((nRow
== aRowHeaderRange
.aStart
.Row()) || (nRow
- 1 == aRowHeaderRange
.aEnd
.Row()))) &&
1474 !(pGroupRows
->IsGroupStart(nRow
)) &&
1475 !(pGroupRows
->IsGroupEnd(nRow
- 1)))
1479 assert(nPrevIndex
>= 0 && "coverity#1438402");
1480 ScRowFormatRanges
* pTempRowFormatRanges
= new ScRowFormatRanges(pRowFormatRanges
.get());
1481 OpenAndCloseRow(nPrevIndex
, nRow
- nEqualRows
, nEqualRows
, bPrevHidden
, bPrevFiltered
);
1482 pRowFormatRanges
.reset(pTempRowFormatRanges
);
1484 nPrevIndex
= nIndex
;
1485 bPrevHidden
= bHidden
;
1486 bPrevFiltered
= bFiltered
;
1490 assert(nPrevIndex
>= 0 && "coverity#1438402");
1491 OpenNewRow(nPrevIndex
, nRow
- nEqualRows
, nEqualRows
, bPrevHidden
, bPrevFiltered
);
1495 sal_Int32 nIndex
= pRowStyles
->GetStyleNameIndex(nTable
, nStartRow
);
1496 bool bHidden
= false;
1497 bool bFiltered
= false;
1500 sal_Int32 nEndRowHidden
;
1501 sal_Int32 nEndRowFiltered
;
1502 bHidden
= rRowAttr
.rowHidden(nTable
, nStartRow
, nEndRowHidden
);
1503 bFiltered
= rRowAttr
.rowFiltered(nTable
, nStartRow
, nEndRowFiltered
);
1505 assert(nIndex
>= 0 && "coverity#1438402");
1506 OpenNewRow(nIndex
, nStartRow
, 1, bHidden
, bFiltered
);
1508 nOpenRow
= nStartRow
+ nRepeatRow
- 1;
1511 void ScXMLExport::CloseRow(const sal_Int32 nRow
)
1515 EndElement(sElemRow
, true);
1516 if (bHasRowHeader
&& nRow
== aRowHeaderRange
.aEnd
.Row())
1519 bRowHeaderOpen
= false;
1521 if (pGroupRows
->IsGroupEnd(nRow
))
1523 if (bHasRowHeader
&& bRowHeaderOpen
)
1525 pGroupRows
->CloseGroups(nRow
);
1526 if (bHasRowHeader
&& bRowHeaderOpen
)
1533 void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol
, const sal_Int32 nStartRow
,
1534 const sal_Int32 nEndCol
, const sal_Int32 nEndRow
, const sal_Int32 nSheet
)
1536 pRowFormatRanges
->Clear();
1537 ScXMLCachedRowAttrAccess
aRowAttr(pDoc
);
1538 if (nStartRow
== nEndRow
)
1540 pCellStyles
->GetFormatRanges(nStartCol
, nEndCol
, nStartRow
, nSheet
, pRowFormatRanges
.get());
1541 if (nOpenRow
== - 1)
1542 OpenRow(nSheet
, nStartRow
, 1, aRowAttr
);
1544 pRowFormatRanges
->Clear();
1550 pCellStyles
->GetFormatRanges(nStartCol
, pSharedData
->GetLastColumn(nSheet
), nStartRow
, nSheet
, pRowFormatRanges
.get());
1552 CloseRow(nStartRow
);
1554 sal_Int32
nTotalRows(nEndRow
- nStartRow
+ 1 - 1);
1555 while (nRows
< nTotalRows
)
1557 pRowFormatRanges
->Clear();
1558 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1559 sal_Int32 nMaxRows
= pRowFormatRanges
->GetMaxRows();
1560 OSL_ENSURE(nMaxRows
, "something went wrong");
1561 if (nMaxRows
>= nTotalRows
- nRows
)
1563 OpenRow(nSheet
, nStartRow
+ nRows
, nTotalRows
- nRows
, aRowAttr
);
1564 nRows
+= nTotalRows
- nRows
;
1568 OpenRow(nSheet
, nStartRow
+ nRows
, nMaxRows
, aRowAttr
);
1571 if (!pRowFormatRanges
->GetSize())
1572 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1574 CloseRow(nStartRow
+ nRows
- 1);
1576 if (nTotalRows
== 1)
1577 CloseRow(nStartRow
);
1578 OpenRow(nSheet
, nEndRow
, 1, aRowAttr
);
1579 pRowFormatRanges
->Clear();
1580 pCellStyles
->GetFormatRanges(0, nEndCol
, nEndRow
, nSheet
, pRowFormatRanges
.get());
1586 sal_Int32
nTotalRows(nEndRow
- nStartRow
+ 1 - 1);
1587 while (nRows
< nTotalRows
)
1589 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1590 sal_Int32 nMaxRows
= pRowFormatRanges
->GetMaxRows();
1591 OSL_ENSURE(nMaxRows
, "something went wrong");
1592 if (nMaxRows
>= nTotalRows
- nRows
)
1594 OpenRow(nSheet
, nStartRow
+ nRows
, nTotalRows
- nRows
, aRowAttr
);
1595 nRows
+= nTotalRows
- nRows
;
1599 OpenRow(nSheet
, nStartRow
+ nRows
, nMaxRows
, aRowAttr
);
1602 if (!pRowFormatRanges
->GetSize())
1603 pCellStyles
->GetFormatRanges(0, pSharedData
->GetLastColumn(nSheet
), nStartRow
+ nRows
, nSheet
, pRowFormatRanges
.get());
1605 CloseRow(nStartRow
+ nRows
- 1);
1607 OpenRow(nSheet
, nEndRow
, 1, aRowAttr
);
1608 pRowFormatRanges
->Clear();
1609 pCellStyles
->GetFormatRanges(0, nEndCol
, nEndRow
, nSheet
, pRowFormatRanges
.get());
1615 void ScXMLExport::GetColumnRowHeader(bool& rHasColumnHeader
, ScRange
& rColumnHeaderRange
,
1616 bool& rHasRowHeader
, ScRange
& rRowHeaderRange
,
1617 OUString
& rPrintRanges
) const
1619 uno::Reference
<sheet::XPrintAreas
> xPrintAreas (xCurrentTable
, uno::UNO_QUERY
);
1620 if (!xPrintAreas
.is())
1623 rHasRowHeader
= xPrintAreas
->getPrintTitleRows();
1624 rHasColumnHeader
= xPrintAreas
->getPrintTitleColumns();
1625 table::CellRangeAddress rTempRowHeaderRange
= xPrintAreas
->getTitleRows();
1626 rRowHeaderRange
= ScRange(rTempRowHeaderRange
.StartColumn
,
1627 rTempRowHeaderRange
.StartRow
,
1628 rTempRowHeaderRange
.Sheet
,
1629 rTempRowHeaderRange
.EndColumn
,
1630 rTempRowHeaderRange
.EndRow
,
1631 rTempRowHeaderRange
.Sheet
);
1632 table::CellRangeAddress rTempColumnHeaderRange
= xPrintAreas
->getTitleColumns();
1633 rColumnHeaderRange
= ScRange(rTempColumnHeaderRange
.StartColumn
,
1634 rTempColumnHeaderRange
.StartRow
,
1635 rTempColumnHeaderRange
.Sheet
,
1636 rTempColumnHeaderRange
.EndColumn
,
1637 rTempColumnHeaderRange
.EndRow
,
1638 rTempColumnHeaderRange
.Sheet
);
1639 uno::Sequence
< table::CellRangeAddress
> aRangeList( xPrintAreas
->getPrintAreas() );
1640 ScRangeStringConverter::GetStringFromRangeList( rPrintRanges
, aRangeList
, pDoc
, FormulaGrammar::CONV_OOO
);
1643 void ScXMLExport::FillFieldGroup(ScOutlineArray
* pFields
, ScMyOpenCloseColumnRowGroup
* pGroups
)
1645 size_t nDepth
= pFields
->GetDepth();
1646 for (size_t i
= 0; i
< nDepth
; ++i
)
1648 size_t nFields
= pFields
->GetCount(i
);
1649 for (size_t j
= 0; j
< nFields
; ++j
)
1651 ScMyColumnRowGroup aGroup
;
1652 const ScOutlineEntry
* pEntry
= pFields
->GetEntry(i
, j
);
1653 aGroup
.nField
= pEntry
->GetStart();
1654 aGroup
.nLevel
= static_cast<sal_Int16
>(i
);
1655 aGroup
.bDisplay
= !(pEntry
->IsHidden());
1656 pGroups
->AddGroup(aGroup
, pEntry
->GetEnd());
1663 void ScXMLExport::FillColumnRowGroups()
1668 ScOutlineTable
* pOutlineTable
= pDoc
->GetOutlineTable( static_cast<SCTAB
>(nCurrentTable
) );
1671 ScOutlineArray
& rCols(pOutlineTable
->GetColArray());
1672 ScOutlineArray
& rRows(pOutlineTable
->GetRowArray());
1673 FillFieldGroup(&rCols
, pGroupColumns
.get());
1674 FillFieldGroup(&rRows
, pGroupRows
.get());
1675 pSharedData
->SetLastColumn(nCurrentTable
, pGroupColumns
->GetLast());
1676 pSharedData
->SetLastRow(nCurrentTable
, pGroupRows
->GetLast());
1680 void ScXMLExport::SetBodyAttributes()
1682 if (!(pDoc
&& pDoc
->IsDocProtected()))
1685 AddAttribute(XML_NAMESPACE_TABLE
, XML_STRUCTURE_PROTECTED
, XML_TRUE
);
1686 OUStringBuffer aBuffer
;
1687 uno::Sequence
<sal_Int8
> aPassHash
;
1688 ScPasswordHash eHashUsed
= PASSHASH_UNSPECIFIED
;
1689 const ScDocProtection
* p
= pDoc
->GetDocProtection();
1692 if (p
->hasPasswordHash(PASSHASH_SHA1
))
1694 aPassHash
= p
->getPasswordHash(PASSHASH_SHA1
);
1695 eHashUsed
= PASSHASH_SHA1
;
1697 else if (p
->hasPasswordHash(PASSHASH_SHA256
))
1699 aPassHash
= p
->getPasswordHash(PASSHASH_SHA256
);
1700 eHashUsed
= PASSHASH_SHA256
;
1702 else if (p
->hasPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
))
1704 aPassHash
= p
->getPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
);
1705 eHashUsed
= PASSHASH_XL
;
1708 ::comphelper::Base64::encode(aBuffer
, aPassHash
);
1709 if (aBuffer
.isEmpty())
1712 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY
, aBuffer
.makeStringAndClear());
1713 if (getSaneDefaultVersion() < SvtSaveOptions::ODFSVER_012
)
1716 if (eHashUsed
== PASSHASH_XL
)
1718 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1719 ScPassHashHelper::getHashURI(PASSHASH_XL
));
1720 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
1721 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
,
1722 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
1724 else if (eHashUsed
== PASSHASH_SHA1
)
1726 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1727 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
1729 else if (eHashUsed
== PASSHASH_SHA256
)
1731 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
1732 ScPassHashHelper::getHashURI(PASSHASH_SHA256
));
1736 static bool lcl_CopyStreamElement( const uno::Reference
< io::XInputStream
>& xInput
,
1737 const uno::Reference
< io::XOutputStream
>& xOutput
,
1740 const sal_Int32 nBufSize
= 16*1024;
1741 uno::Sequence
<sal_Int8
> aSequence(nBufSize
);
1743 sal_Int32 nRemaining
= nCount
;
1746 while ( nRemaining
> 0 )
1748 sal_Int32 nRead
= xInput
->readBytes( aSequence
, std::min( nRemaining
, nBufSize
) );
1751 // safety check: Make sure the copied part actually points to the start of an element
1752 if ( nRead
< 1 || aSequence
[0] != static_cast<sal_Int8
>('<') )
1754 return false; // abort and set an error
1758 if (nRead
== nRemaining
)
1760 // safety check: Make sure the copied part also ends at the end of an element
1761 if ( aSequence
[nRead
-1] != static_cast<sal_Int8
>('>') )
1763 return false; // abort and set an error
1767 if ( nRead
== nBufSize
)
1769 xOutput
->writeBytes( aSequence
);
1770 nRemaining
-= nRead
;
1776 uno::Sequence
<sal_Int8
> aTempBuf( aSequence
.getConstArray(), nRead
);
1777 xOutput
->writeBytes( aTempBuf
);
1782 return true; // successful
1785 static void lcl_SkipBytesInBlocks( const uno::Reference
< io::XInputStream
>& xInput
, sal_Int32 nBytesToSkip
)
1787 // skipBytes in zip stream is implemented as reading.
1788 // For now, split into several calls to avoid allocating a large buffer.
1789 // Later, skipBytes should be changed.
1791 const sal_Int32 nMaxSize
= 32*1024;
1793 if ( nBytesToSkip
> 0 )
1795 sal_Int32 nRemaining
= nBytesToSkip
;
1796 while ( nRemaining
> 0 )
1798 sal_Int32 nSkip
= std::min( nRemaining
, nMaxSize
);
1799 xInput
->skipBytes( nSkip
);
1800 nRemaining
-= nSkip
;
1805 void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset
, sal_Int32 nEndOffset
, sal_Int32
& rNewStart
, sal_Int32
& rNewEnd
)
1807 uno::Reference
<xml::sax::XDocumentHandler
> xHandler
= GetDocHandler();
1808 uno::Reference
<io::XActiveDataSource
> xDestSource( xHandler
, uno::UNO_QUERY
);
1809 if ( !xDestSource
.is() )
1812 uno::Reference
<io::XOutputStream
> xDestStream
= xDestSource
->getOutputStream();
1813 uno::Reference
<io::XSeekable
> xDestSeek( xDestStream
, uno::UNO_QUERY
);
1814 if ( !xDestSeek
.is() )
1817 // temporary: set same stream again to clear buffer
1818 xDestSource
->setOutputStream( xDestStream
);
1820 if ( getExportFlags() & SvXMLExportFlags::PRETTY
)
1822 const OString
aOutStr("\n ");
1823 uno::Sequence
<sal_Int8
> aOutSeq( reinterpret_cast<sal_Int8
const *>(aOutStr
.getStr()), aOutStr
.getLength() );
1824 xDestStream
->writeBytes( aOutSeq
);
1827 rNewStart
= static_cast<sal_Int32
>(xDestSeek
->getPosition());
1829 if ( nStartOffset
> nSourceStreamPos
)
1830 lcl_SkipBytesInBlocks( xSourceStream
, nStartOffset
- nSourceStreamPos
);
1832 if ( !lcl_CopyStreamElement( xSourceStream
, xDestStream
, nEndOffset
- nStartOffset
) )
1834 // If copying went wrong, set an error.
1835 // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
1837 uno::Sequence
<OUString
> aEmptySeq
;
1838 SetError(XMLERROR_CANCEL
|XMLERROR_FLAG_SEVERE
, aEmptySeq
);
1840 nSourceStreamPos
= nEndOffset
;
1842 rNewEnd
= static_cast<sal_Int32
>(xDestSeek
->getPosition());
1845 const ScXMLEditAttributeMap
& ScXMLExport::GetEditAttributeMap() const
1848 mpEditAttrMap
.reset(new ScXMLEditAttributeMap
);
1849 return *mpEditAttrMap
;
1852 void ScXMLExport::RegisterDefinedStyleNames( const uno::Reference
< css::sheet::XSpreadsheetDocument
> & xSpreadDoc
)
1854 ScFormatSaveData
* pFormatData
= comphelper::getUnoTunnelImplementation
<ScModelObj
>(xSpreadDoc
)->GetFormatSaveData();
1855 auto xAutoStylePool
= GetAutoStylePool();
1856 for (const auto& rFormatInfo
: pFormatData
->maIDToName
)
1858 xAutoStylePool
->RegisterDefinedName(XmlStyleFamily::TABLE_CELL
, rFormatInfo
.second
);
1862 void ScXMLExport::ExportContent_()
1867 SCTAB
nTableCount(0);
1868 sal_Int32
nShapesCount(0);
1869 CollectSharedData(nTableCount
, nShapesCount
);
1870 OSL_FAIL("no shared data set");
1874 ScXMLExportDatabaseRanges
aExportDatabaseRanges(*this);
1875 if (!GetModel().is())
1878 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
1879 if ( !xSpreadDoc
.is() )
1882 ScSheetSaveData
* pSheetData
= comphelper::getUnoTunnelImplementation
<ScModelObj
>(xSpreadDoc
)->GetSheetSaveData();
1884 pSheetData
->ResetSaveEntries();
1886 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
1889 //_GetNamespaceMap().ClearQNamesCache();
1890 pChangeTrackingExportHelper
->CollectAndWriteChanges();
1891 WriteCalculationSettings(xSpreadDoc
);
1892 sal_Int32
nTableCount(xIndex
->getCount());
1893 ScMyAreaLinksContainer aAreaLinks
;
1894 GetAreaLinks( aAreaLinks
);
1895 ScMyEmptyDatabaseRangesContainer
aEmptyRanges(aExportDatabaseRanges
.GetEmptyDatabaseRanges());
1896 ScMyDetectiveOpContainer aDetectiveOpContainer
;
1897 GetDetectiveOpList( aDetectiveOpContainer
);
1899 pCellStyles
->Sort();
1900 pMergedRangesContainer
->Sort();
1901 pSharedData
->GetDetectiveObjContainer()->Sort();
1903 mpCellsItr
->Clear();
1904 mpCellsItr
->SetShapes( pSharedData
->GetShapesContainer() );
1905 mpCellsItr
->SetNoteShapes( pSharedData
->GetNoteShapes() );
1906 mpCellsItr
->SetMergedRanges( pMergedRangesContainer
.get() );
1907 mpCellsItr
->SetAreaLinks( &aAreaLinks
);
1908 mpCellsItr
->SetEmptyDatabaseRanges( &aEmptyRanges
);
1909 mpCellsItr
->SetDetectiveObj( pSharedData
->GetDetectiveObjContainer() );
1910 mpCellsItr
->SetDetectiveOp( &aDetectiveOpContainer
);
1912 if (nTableCount
> 0)
1913 pValidationsContainer
->WriteValidations(*this);
1914 WriteTheLabelRanges( xSpreadDoc
);
1915 for (sal_Int32 nTable
= 0; nTable
< nTableCount
; ++nTable
)
1917 sal_Int32 nStartOffset
= -1;
1918 sal_Int32 nEndOffset
= -1;
1919 if (pSheetData
&& pDoc
&& pDoc
->IsStreamValid(static_cast<SCTAB
>(nTable
)) && !pDoc
->GetChangeTrack())
1920 pSheetData
->GetStreamPos( nTable
, nStartOffset
, nEndOffset
);
1922 if ( nStartOffset
>= 0 && nEndOffset
>= 0 && xSourceStream
.is() )
1924 sal_Int32 nNewStart
= -1;
1925 sal_Int32 nNewEnd
= -1;
1926 CopySourceStream( nStartOffset
, nEndOffset
, nNewStart
, nNewEnd
);
1928 // store position of copied sheet in output
1929 pSheetData
->AddSavePos( nTable
, nNewStart
, nNewEnd
);
1931 // skip iterator entries for this sheet
1932 mpCellsItr
->SkipTable(static_cast<SCTAB
>(nTable
));
1936 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
1937 WriteTable(nTable
, xTable
);
1939 IncrementProgressBar(false);
1942 WriteExternalRefCaches();
1943 WriteNamedExpressions();
1945 aExportDatabaseRanges
.WriteDatabaseRanges();
1946 WriteExternalDataMapping();
1947 ScXMLExportDataPilot
aExportDataPilot(*this);
1948 aExportDataPilot
.WriteDataPilots();
1949 WriteConsolidation();
1950 ScXMLExportDDELinks
aExportDDELinks(*this);
1951 aExportDDELinks
.WriteDDELinks(xSpreadDoc
);
1952 IncrementProgressBar(true, 0);
1953 GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
1956 void ScXMLExport::ExportStyles_( bool bUsed
)
1958 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
1959 if (xSpreadDoc
.is())
1960 RegisterDefinedStyleNames( xSpreadDoc
);
1964 SCTAB
nTableCount(0);
1965 sal_Int32
nShapesCount(0);
1966 CollectSharedData(nTableCount
, nShapesCount
);
1968 rtl::Reference
<XMLCellStyleExport
> aStylesExp(new XMLCellStyleExport(*this, GetAutoStylePool().get()));
1969 if (GetModel().is())
1971 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
1972 if (xMultiServiceFactory
.is())
1974 uno::Reference
<beans::XPropertySet
> xProperties(xMultiServiceFactory
->createInstance("com.sun.star.sheet.Defaults"), uno::UNO_QUERY
);
1975 if (xProperties
.is())
1976 aStylesExp
->exportDefaultStyle(xProperties
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
, xCellStylesExportPropertySetMapper
);
1977 if (pSharedData
->HasShapes())
1979 GetShapeExport()->ExportGraphicDefaults();
1982 collectDataStyles(false);
1986 aStylesExp
->exportStyleFamily(OUString("CellStyles"),
1987 OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
), xCellStylesExportPropertySetMapper
, false, XmlStyleFamily::TABLE_CELL
);
1989 SvXMLExport::ExportStyles_(bUsed
);
1992 void ScXMLExport::AddStyleFromCells(const uno::Reference
<beans::XPropertySet
>& xProperties
,
1993 const uno::Reference
<sheet::XSpreadsheet
>& xTable
,
1994 sal_Int32 nTable
, const OUString
* pOldName
)
1996 css::uno::Any aAny
= xProperties
->getPropertyValue("FormatID");
1997 sal_uInt64 nKey
= 0;
2000 //! pass xCellRanges instead
2001 uno::Reference
<sheet::XSheetCellRanges
> xCellRanges( xProperties
, uno::UNO_QUERY
);
2003 OUString sStyleName
;
2004 sal_Int32
nNumberFormat(-1);
2005 sal_Int32
nValidationIndex(-1);
2006 std::vector
<XMLPropertyState
> aPropStates(xCellStylesExportPropertySetMapper
->Filter(*this, xProperties
));
2007 std::vector
< XMLPropertyState
>::iterator
aItr(aPropStates
.begin());
2008 std::vector
< XMLPropertyState
>::iterator
aEndItr(aPropStates
.end());
2009 sal_Int32
nCount(0);
2010 while (aItr
!= aEndItr
)
2012 if (aItr
->mnIndex
!= -1)
2014 switch (xCellStylesPropertySetMapper
->GetEntryContextId(aItr
->mnIndex
))
2016 case CTF_SC_VALIDATION
:
2018 pValidationsContainer
->AddValidation(aItr
->maValue
, nValidationIndex
);
2019 // this is not very slow, because it is most the last property or
2020 // if it is not the last property it is the property before the last property,
2021 // so in the worst case only one property has to be copied, but in the best case no
2022 // property has to be copied
2023 aItr
= aPropStates
.erase(aItr
);
2024 aEndItr
= aPropStates
.end(); // old aEndItr is invalidated!
2027 case CTF_SC_CELLSTYLE
:
2029 aItr
->maValue
>>= sStyleName
;
2035 case CTF_SC_NUMBERFORMAT
:
2037 if (aItr
->maValue
>>= nNumberFormat
)
2038 addDataStyle(nNumberFormat
);
2057 if (nCount
== 1) // this is the CellStyle and should be removed if alone
2058 aPropStates
.clear();
2059 if (nNumberFormat
== -1)
2060 xProperties
->getPropertyValue(SC_UNONAME_NUMFMT
) >>= nNumberFormat
;
2061 if (sStyleName
.isEmpty())
2064 if (!aPropStates
.empty())
2069 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, aPropStates
))
2071 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_CELL
, *pOldName
);
2072 // add to pCellStyles, so the name is found for normal sheets
2073 pCellStyles
->AddStyleName(*pOldName
, nIndex
);
2079 bool bAdded
= false;
2082 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2083 ScFormatSaveData
* pFormatData
= comphelper::getUnoTunnelImplementation
<ScModelObj
>(xSpreadDoc
)->GetFormatSaveData();
2084 auto itr
= pFormatData
->maIDToName
.find(nKey
);
2085 if (itr
!= pFormatData
->maIDToName
.end())
2087 sName
= itr
->second
;
2088 bAdded
= GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, aPropStates
);
2090 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_CELL
, sName
);
2093 bool bIsAutoStyle(true);
2094 if (bAdded
|| GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_CELL
, sStyleName
, aPropStates
))
2096 pCellStyles
->AddStyleName(sName
, nIndex
);
2099 nIndex
= pCellStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
, bIsAutoStyle
);
2101 const uno::Sequence
<table::CellRangeAddress
> aAddresses(xCellRanges
->getRangeAddresses());
2102 bool bGetMerge(true);
2103 for (table::CellRangeAddress
const & address
: aAddresses
)
2105 pSharedData
->SetLastColumn(nTable
, address
.EndColumn
);
2106 pSharedData
->SetLastRow(nTable
, address
.EndRow
);
2107 pCellStyles
->AddRangeStyleName(address
, nIndex
, bIsAutoStyle
, nValidationIndex
, nNumberFormat
);
2109 bGetMerge
= GetMerged(&address
, xTable
);
2115 OUString
sEncodedStyleName(EncodeStyleName(sStyleName
));
2116 sal_Int32
nIndex(0);
2117 pCellStyles
->AddStyleName(sEncodedStyleName
, nIndex
, false);
2120 const uno::Sequence
<table::CellRangeAddress
> aAddresses(xCellRanges
->getRangeAddresses());
2121 bool bGetMerge(true);
2122 for (table::CellRangeAddress
const & address
: aAddresses
)
2125 bGetMerge
= GetMerged(&address
, xTable
);
2126 pCellStyles
->AddRangeStyleName(address
, nIndex
, false, nValidationIndex
, nNumberFormat
);
2127 if( sStyleName
!= "Default" || nValidationIndex
!= -1 )
2129 pSharedData
->SetLastColumn(nTable
, address
.EndColumn
);
2130 pSharedData
->SetLastRow(nTable
, address
.EndRow
);
2137 void ScXMLExport::AddStyleFromColumn(const uno::Reference
<beans::XPropertySet
>& xColumnProperties
,
2138 const OUString
* pOldName
, sal_Int32
& rIndex
, bool& rIsVisible
)
2140 std::vector
<XMLPropertyState
> aPropStates(xColumnStylesExportPropertySetMapper
->Filter(*this, xColumnProperties
));
2141 if(aPropStates
.empty())
2144 auto aItr
= std::find_if(aPropStates
.begin(), aPropStates
.end(),
2145 [this](const XMLPropertyState
& rPropState
) {
2146 return xColumnStylesPropertySetMapper
->GetEntryContextId(rPropState
.mnIndex
) == CTF_SC_ISVISIBLE
; });
2147 if (aItr
!= aPropStates
.end())
2149 aItr
->maValue
>>= rIsVisible
;
2152 const OUString sParent
;
2155 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_COLUMN
, sParent
, aPropStates
))
2157 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_COLUMN
, *pOldName
);
2158 // add to pColumnStyles, so the name is found for normal sheets
2159 rIndex
= pColumnStyles
->AddStyleName(*pOldName
);
2165 if (GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_COLUMN
, sParent
, aPropStates
))
2167 rIndex
= pColumnStyles
->AddStyleName(sName
);
2170 rIndex
= pColumnStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX
);
2174 void ScXMLExport::AddStyleFromRow(const uno::Reference
<beans::XPropertySet
>& xRowProperties
,
2175 const OUString
* pOldName
, sal_Int32
& rIndex
)
2177 std::vector
<XMLPropertyState
> aPropStates(xRowStylesExportPropertySetMapper
->Filter(*this, xRowProperties
));
2178 if(aPropStates
.empty())
2181 const OUString sParent
;
2184 if (GetAutoStylePool()->AddNamed(*pOldName
, XmlStyleFamily::TABLE_ROW
, sParent
, aPropStates
))
2186 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_ROW
, *pOldName
);
2187 // add to pRowStyles, so the name is found for normal sheets
2188 rIndex
= pRowStyles
->AddStyleName(*pOldName
);
2194 if (GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_ROW
, sParent
, aPropStates
))
2196 rIndex
= pRowStyles
->AddStyleName(sName
);
2199 rIndex
= pRowStyles
->GetIndexOfStyleName(sName
, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX
);
2203 static uno::Any
lcl_GetEnumerated( uno::Reference
<container::XEnumerationAccess
> const & xEnumAccess
, sal_Int32 nIndex
)
2206 uno::Reference
<container::XEnumeration
> xEnum( xEnumAccess
->createEnumeration() );
2209 sal_Int32 nSkip
= nIndex
;
2212 (void) xEnum
->nextElement();
2215 aRet
= xEnum
->nextElement();
2217 catch (container::NoSuchElementException
&)
2224 void ScXMLExport::collectAutoStyles()
2226 SvXMLExport::collectAutoStyles();
2228 if (mbAutoStylesCollected
)
2231 if (!GetModel().is())
2234 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2235 if (!xSpreadDoc
.is())
2238 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
2242 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
2244 // Reserve the loaded cell style names.
2245 RegisterDefinedStyleNames( xSpreadDoc
);
2247 // re-create automatic styles with old names from stored data
2248 ScSheetSaveData
* pSheetData
= comphelper::getUnoTunnelImplementation
<ScModelObj
>(xSpreadDoc
)->GetSheetSaveData();
2249 if (pSheetData
&& pDoc
)
2251 // formulas have to be calculated now, to detect changed results
2252 // (during normal save, they will be calculated anyway)
2253 SCTAB nTabCount
= pDoc
->GetTableCount();
2254 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
2255 if (pDoc
->IsStreamValid(nTab
))
2256 pDoc
->InterpretDirtyCells(ScRange(0, 0, nTab
, pDoc
->MaxCol(), pDoc
->MaxRow(), nTab
));
2258 // stored cell styles
2259 const std::vector
<ScCellStyleEntry
>& rCellEntries
= pSheetData
->GetCellStyles();
2260 for (const auto& rCellEntry
: rCellEntries
)
2262 ScAddress aPos
= rCellEntry
.maCellPos
;
2263 sal_Int32 nTable
= aPos
.Tab();
2264 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2267 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2268 uno::Reference
<beans::XPropertySet
> xProperties(
2269 xTable
->getCellByPosition( aPos
.Col(), aPos
.Row() ), uno::UNO_QUERY
);
2271 AddStyleFromCells(xProperties
, xTable
, nTable
, &rCellEntry
.maName
);
2275 // stored column styles
2276 const std::vector
<ScCellStyleEntry
>& rColumnEntries
= pSheetData
->GetColumnStyles();
2277 for (const auto& rColumnEntry
: rColumnEntries
)
2279 ScAddress aPos
= rColumnEntry
.maCellPos
;
2280 sal_Int32 nTable
= aPos
.Tab();
2281 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2284 uno::Reference
<table::XColumnRowRange
> xColumnRowRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2285 uno::Reference
<table::XTableColumns
> xTableColumns(xColumnRowRange
->getColumns());
2286 uno::Reference
<beans::XPropertySet
> xColumnProperties(xTableColumns
->getByIndex( aPos
.Col() ), uno::UNO_QUERY
);
2288 sal_Int32
nIndex(-1);
2289 bool bIsVisible(true);
2290 AddStyleFromColumn( xColumnProperties
, &rColumnEntry
.maName
, nIndex
, bIsVisible
);
2294 // stored row styles
2295 const std::vector
<ScCellStyleEntry
>& rRowEntries
= pSheetData
->GetRowStyles();
2296 for (const auto& rRowEntry
: rRowEntries
)
2298 ScAddress aPos
= rRowEntry
.maCellPos
;
2299 sal_Int32 nTable
= aPos
.Tab();
2300 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2303 uno::Reference
<table::XColumnRowRange
> xColumnRowRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2304 uno::Reference
<table::XTableRows
> xTableRows(xColumnRowRange
->getRows());
2305 uno::Reference
<beans::XPropertySet
> xRowProperties(xTableRows
->getByIndex( aPos
.Row() ), uno::UNO_QUERY
);
2307 sal_Int32
nIndex(-1);
2308 AddStyleFromRow( xRowProperties
, &rRowEntry
.maName
, nIndex
);
2312 // stored table styles
2313 const std::vector
<ScCellStyleEntry
>& rTableEntries
= pSheetData
->GetTableStyles();
2314 for (const auto& rTableEntry
: rTableEntries
)
2316 ScAddress aPos
= rTableEntry
.maCellPos
;
2317 sal_Int32 nTable
= aPos
.Tab();
2318 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2321 //! separate method AddStyleFromTable needed?
2322 uno::Reference
<beans::XPropertySet
> xTableProperties(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2323 if (xTableProperties
.is())
2325 std::vector
<XMLPropertyState
> aPropStates(xTableStylesExportPropertySetMapper
->Filter(*this, xTableProperties
));
2326 OUString
sName( rTableEntry
.maName
);
2327 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TABLE_TABLE
, OUString(), aPropStates
);
2328 GetAutoStylePool()->RegisterName(XmlStyleFamily::TABLE_TABLE
, sName
);
2333 // stored styles for notes
2335 rtl::Reference
<SvXMLExportPropertyMapper
> xShapeMapper
= XMLShapeExport::CreateShapePropMapper( *this );
2336 GetShapeExport(); // make sure the graphics styles family is added
2338 const std::vector
<ScNoteStyleEntry
>& rNoteEntries
= pSheetData
->GetNoteStyles();
2339 for (const auto& rNoteEntry
: rNoteEntries
)
2341 ScAddress aPos
= rNoteEntry
.maCellPos
;
2342 SCTAB nTable
= aPos
.Tab();
2343 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2346 //! separate method AddStyleFromNote needed?
2348 ScPostIt
* pNote
= pDoc
->GetNote(aPos
);
2349 OSL_ENSURE( pNote
, "note not found" );
2352 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2353 // all uno shapes are created anyway in CollectSharedData
2354 uno::Reference
<beans::XPropertySet
> xShapeProperties( pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2355 if (xShapeProperties
.is())
2357 if ( !rNoteEntry
.maStyleName
.isEmpty() )
2359 std::vector
<XMLPropertyState
> aPropStates(xShapeMapper
->Filter(*this, xShapeProperties
));
2360 OUString
sName( rNoteEntry
.maStyleName
);
2361 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::SD_GRAPHICS_ID
, OUString(), aPropStates
);
2362 GetAutoStylePool()->RegisterName(XmlStyleFamily::SD_GRAPHICS_ID
, sName
);
2364 if ( !rNoteEntry
.maTextStyle
.isEmpty() )
2366 std::vector
<XMLPropertyState
> aPropStates(
2367 GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(*this, xShapeProperties
));
2368 OUString
sName( rNoteEntry
.maTextStyle
);
2369 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_PARAGRAPH
, OUString(), aPropStates
);
2370 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH
, sName
);
2377 // note paragraph styles
2379 rtl::Reference
<SvXMLExportPropertyMapper
> xParaPropMapper
= GetTextParagraphExport()->GetParagraphPropertyMapper();
2381 const std::vector
<ScTextStyleEntry
>& rNoteParaEntries
= pSheetData
->GetNoteParaStyles();
2382 for (const auto& rNoteParaEntry
: rNoteParaEntries
)
2384 ScAddress aPos
= rNoteParaEntry
.maCellPos
;
2385 SCTAB nTable
= aPos
.Tab();
2386 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2389 ScPostIt
* pNote
= pDoc
->GetNote( aPos
);
2390 OSL_ENSURE( pNote
, "note not found" );
2393 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2394 uno::Reference
<container::XEnumerationAccess
> xCellText(pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2395 uno::Reference
<beans::XPropertySet
> xParaProp(
2396 lcl_GetEnumerated( xCellText
, rNoteParaEntry
.maSelection
.nStartPara
), uno::UNO_QUERY
);
2397 if ( xParaProp
.is() )
2399 std::vector
<XMLPropertyState
> aPropStates(xParaPropMapper
->Filter(*this, xParaProp
));
2400 OUString
sName( rNoteParaEntry
.maName
);
2401 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_PARAGRAPH
, OUString(), aPropStates
);
2402 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_PARAGRAPH
, sName
);
2410 rtl::Reference
<SvXMLExportPropertyMapper
> xTextPropMapper
= XMLTextParagraphExport::CreateCharExtPropMapper( *this );
2412 const std::vector
<ScTextStyleEntry
>& rNoteTextEntries
= pSheetData
->GetNoteTextStyles();
2413 for (const auto& rNoteTextEntry
: rNoteTextEntries
)
2415 ScAddress aPos
= rNoteTextEntry
.maCellPos
;
2416 SCTAB nTable
= aPos
.Tab();
2417 bool bCopySheet
= pDoc
->IsStreamValid( nTable
);
2420 ScPostIt
* pNote
= pDoc
->GetNote( aPos
);
2421 OSL_ENSURE( pNote
, "note not found" );
2424 SdrCaptionObj
* pDrawObj
= pNote
->GetOrCreateCaption( aPos
);
2425 uno::Reference
<text::XSimpleText
> xCellText(pDrawObj
->getUnoShape(), uno::UNO_QUERY
);
2426 uno::Reference
<beans::XPropertySet
> xCursorProp(xCellText
->createTextCursor(), uno::UNO_QUERY
);
2427 ScDrawTextCursor
* pCursor
= comphelper::getUnoTunnelImplementation
<ScDrawTextCursor
>( xCursorProp
);
2430 pCursor
->SetSelection( rNoteTextEntry
.maSelection
);
2432 std::vector
<XMLPropertyState
> aPropStates(xTextPropMapper
->Filter(*this, xCursorProp
));
2433 OUString
sName( rNoteTextEntry
.maName
);
2434 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_TEXT
, OUString(), aPropStates
);
2435 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT
, sName
);
2441 // stored text styles
2443 // Calling createTextCursor fires up editeng, which is very slow, and often subsequent style entries
2444 // refer to the same cell, so cache it.
2446 uno::Reference
<beans::XPropertySet
> xPrevCursorProp
;
2447 const std::vector
<ScTextStyleEntry
>& rTextEntries
= pSheetData
->GetTextStyles();
2448 for (const auto& rTextEntry
: rTextEntries
)
2450 ScAddress aPos
= rTextEntry
.maCellPos
;
2451 sal_Int32 nTable
= aPos
.Tab();
2452 bool bCopySheet
= pDoc
->IsStreamValid( static_cast<SCTAB
>(nTable
) );
2456 //! separate method AddStyleFromText needed?
2457 //! cache sheet object
2459 uno::Reference
<beans::XPropertySet
> xCursorProp
;
2460 if (xPrevCursorProp
&& aPrevPos
== aPos
)
2461 xCursorProp
= xPrevCursorProp
;
2464 uno::Reference
<table::XCellRange
> xCellRange(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2465 uno::Reference
<text::XSimpleText
> xCellText(xCellRange
->getCellByPosition(aPos
.Col(), aPos
.Row()), uno::UNO_QUERY
);
2466 xCursorProp
.set(xCellText
->createTextCursor(), uno::UNO_QUERY
);
2468 ScCellTextCursor
* pCursor
= comphelper::getUnoTunnelImplementation
<ScCellTextCursor
>( xCursorProp
);
2471 pCursor
->SetSelection( rTextEntry
.maSelection
);
2473 std::vector
<XMLPropertyState
> aPropStates(xTextPropMapper
->Filter(*this, xCursorProp
));
2474 OUString
sName( rTextEntry
.maName
);
2475 GetAutoStylePool()->AddNamed(sName
, XmlStyleFamily::TEXT_TEXT
, OUString(), aPropStates
);
2476 GetAutoStylePool()->RegisterName(XmlStyleFamily::TEXT_TEXT
, sName
);
2477 xPrevCursorProp
= xCursorProp
;
2482 ExportExternalRefCacheStyles();
2486 SCTAB
nTableCount(0);
2487 sal_Int32
nShapesCount(0);
2488 CollectSharedData(nTableCount
, nShapesCount
);
2490 sal_Int32
nTableCount(xIndex
->getCount());
2491 pCellStyles
->AddNewTable(nTableCount
- 1);
2492 CollectShapesAutoStyles(nTableCount
);
2493 for (sal_Int32 nTable
= 0; nTable
< nTableCount
; ++nTable
, IncrementProgressBar(false))
2495 uno::Reference
<sheet::XSpreadsheet
> xTable(xIndex
->getByIndex(nTable
), uno::UNO_QUERY
);
2499 // table styles array must be complete, including copied tables - Add should find the stored style
2500 uno::Reference
<beans::XPropertySet
> xTableProperties(xTable
, uno::UNO_QUERY
);
2501 if (xTableProperties
.is())
2503 std::vector
<XMLPropertyState
> aPropStates(xTableStylesExportPropertySetMapper
->Filter(*this, xTableProperties
));
2504 if(!aPropStates
.empty())
2507 GetAutoStylePool()->Add(sName
, XmlStyleFamily::TABLE_TABLE
, OUString(), aPropStates
);
2508 aTableStyles
.push_back(sName
);
2512 // collect other auto-styles only for non-copied sheets
2513 uno::Reference
<sheet::XUniqueCellFormatRangesSupplier
> xCellFormatRanges ( xTable
, uno::UNO_QUERY
);
2514 if ( xCellFormatRanges
.is() )
2516 uno::Reference
<container::XIndexAccess
> xFormatRangesIndex(xCellFormatRanges
->getUniqueCellFormatRanges());
2517 if (xFormatRangesIndex
.is())
2519 sal_Int32
nFormatRangesCount(xFormatRangesIndex
->getCount());
2520 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount
);
2521 for (sal_Int32 nFormatRange
= 0; nFormatRange
< nFormatRangesCount
; ++nFormatRange
)
2523 uno::Reference
< sheet::XSheetCellRanges
> xCellRanges(xFormatRangesIndex
->getByIndex(nFormatRange
), uno::UNO_QUERY
);
2524 if (xCellRanges
.is())
2526 uno::Reference
<beans::XPropertySet
> xProperties (xCellRanges
, uno::UNO_QUERY
);
2527 if (xProperties
.is())
2529 AddStyleFromCells(xProperties
, xTable
, nTable
, nullptr);
2530 IncrementProgressBar(false);
2536 uno::Reference
<table::XColumnRowRange
> xColumnRowRange (xTable
, uno::UNO_QUERY
);
2537 if (xColumnRowRange
.is() && pDoc
)
2539 pDoc
->SyncColRowFlags();
2540 uno::Reference
<table::XTableColumns
> xTableColumns(xColumnRowRange
->getColumns());
2541 if (xTableColumns
.is())
2543 sal_Int32
nColumns(pDoc
->GetLastChangedCol(sal::static_int_cast
<SCTAB
>(nTable
)));
2544 pSharedData
->SetLastColumn(nTable
, nColumns
);
2545 table::CellRangeAddress
aCellAddress(GetEndAddress(xTable
));
2546 if (aCellAddress
.EndColumn
> nColumns
)
2549 pColumnStyles
->AddNewTable(nTable
, aCellAddress
.EndColumn
);
2552 pColumnStyles
->AddNewTable(nTable
, nColumns
);
2553 sal_Int32 nColumn
= 0;
2554 while (nColumn
<= pDoc
->MaxCol())
2556 sal_Int32
nIndex(-1);
2557 bool bIsVisible(true);
2558 uno::Reference
<beans::XPropertySet
> xColumnProperties(xTableColumns
->getByIndex(nColumn
), uno::UNO_QUERY
);
2559 if (xColumnProperties
.is())
2561 AddStyleFromColumn( xColumnProperties
, nullptr, nIndex
, bIsVisible
);
2562 pColumnStyles
->AddFieldStyleName(nTable
, nColumn
, nIndex
, bIsVisible
);
2564 sal_Int32
nOld(nColumn
);
2565 nColumn
= pDoc
->GetNextDifferentChangedCol(sal::static_int_cast
<SCTAB
>(nTable
), static_cast<SCCOL
>(nColumn
));
2566 for (sal_Int32 i
= nOld
+ 1; i
< nColumn
; ++i
)
2567 pColumnStyles
->AddFieldStyleName(nTable
, i
, nIndex
, bIsVisible
);
2569 if (aCellAddress
.EndColumn
> nColumns
)
2571 bool bIsVisible(true);
2572 sal_Int32
nIndex(pColumnStyles
->GetStyleNameIndex(nTable
, nColumns
, bIsVisible
));
2573 for (sal_Int32 i
= nColumns
+ 1; i
<= aCellAddress
.EndColumn
; ++i
)
2574 pColumnStyles
->AddFieldStyleName(nTable
, i
, nIndex
, bIsVisible
);
2577 uno::Reference
<table::XTableRows
> xTableRows(xColumnRowRange
->getRows());
2578 if (xTableRows
.is())
2580 sal_Int32
nRows(pDoc
->GetLastChangedRow(sal::static_int_cast
<SCTAB
>(nTable
)));
2581 pSharedData
->SetLastRow(nTable
, nRows
);
2583 pRowStyles
->AddNewTable(nTable
, pDoc
->MaxRow());
2585 while (nRow
<= pDoc
->MaxRow())
2587 sal_Int32 nIndex
= 0;
2588 uno::Reference
<beans::XPropertySet
> xRowProperties(xTableRows
->getByIndex(nRow
), uno::UNO_QUERY
);
2589 if(xRowProperties
.is())
2591 AddStyleFromRow( xRowProperties
, nullptr, nIndex
);
2592 pRowStyles
->AddFieldStyleName(nTable
, nRow
, nIndex
);
2594 sal_Int32
nOld(nRow
);
2595 nRow
= pDoc
->GetNextDifferentChangedRow(sal::static_int_cast
<SCTAB
>(nTable
), static_cast<SCROW
>(nRow
));
2596 if (nRow
> nOld
+ 1)
2597 pRowStyles
->AddFieldStyleName(nTable
, nOld
+ 1, nIndex
, nRow
- 1);
2601 ExportCellTextAutoStyles(nTable
);
2604 pChangeTrackingExportHelper
->CollectAutoStyles();
2607 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
)
2608 GetPageExport()->collectAutoStyles(true);
2610 mbAutoStylesCollected
= true;
2613 void ScXMLExport::ExportAutoStyles_()
2615 if (!GetModel().is())
2618 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetModel(), uno::UNO_QUERY
);
2619 if (!xSpreadDoc
.is())
2622 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
2626 collectAutoStyles();
2628 if (getExportFlags() & SvXMLExportFlags::CONTENT
)
2630 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_COLUMN
);
2631 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_ROW
);
2632 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_TABLE
);
2633 exportAutoDataStyles();
2634 GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_CELL
);
2636 GetShapeExport()->exportAutoStyles();
2637 GetFormExport()->exportAutoStyles( );
2641 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
2642 // #i100879# write the table style for cached tables only if there are cached tables
2643 // (same logic as in ExportExternalRefCacheStyles)
2644 if (pRefMgr
->hasExternalData())
2646 // Special table style for the external ref cache tables.
2647 AddAttribute(XML_NAMESPACE_STYLE
, XML_NAME
, sExternalRefTabStyleName
);
2648 AddAttribute(XML_NAMESPACE_STYLE
, XML_FAMILY
, XML_TABLE
);
2649 SvXMLElementExport
aElemStyle(*this, XML_NAMESPACE_STYLE
, XML_STYLE
, true, true);
2650 AddAttribute(XML_NAMESPACE_TABLE
, XML_DISPLAY
, XML_FALSE
);
2651 SvXMLElementExport
aElemStyleTabProps(*this, XML_NAMESPACE_STYLE
, XML_TABLE_PROPERTIES
, true, true);
2656 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
)
2658 exportAutoDataStyles();
2659 GetPageExport()->exportAutoStyles();
2662 // #i30251#; only write Text Styles once
2664 if ((getExportFlags() & SvXMLExportFlags::CONTENT
) || (getExportFlags() & SvXMLExportFlags::MASTERSTYLES
))
2665 GetTextParagraphExport()->exportTextAutoStyles();
2668 void ScXMLExport::ExportMasterStyles_()
2670 GetPageExport()->exportMasterStyles( true );
2673 void ScXMLExport::CollectInternalShape( uno::Reference
< drawing::XShape
> const & xShape
)
2675 // detective objects and notes
2676 SvxShape
* pShapeImp
= comphelper::getUnoTunnelImplementation
<SvxShape
>( xShape
);
2680 SdrObject
* pObject
= pShapeImp
->GetSdrObject();
2684 // collect note caption objects from all layers (internal or hidden)
2685 if( ScDrawObjData
* pCaptData
= ScDrawLayer::GetNoteCaptionData( pObject
, static_cast< SCTAB
>( nCurrentTable
) ) )
2687 if(pDoc
->GetNote(pCaptData
->maStart
))
2689 pSharedData
->AddNoteObj( xShape
, pCaptData
->maStart
);
2691 // #i60851# When the file is saved while editing a new note,
2692 // the cell is still empty -> last column/row must be updated
2693 OSL_ENSURE( pCaptData
->maStart
.Tab() == nCurrentTable
, "invalid table in object data" );
2694 pSharedData
->SetLastColumn( nCurrentTable
, pCaptData
->maStart
.Col() );
2695 pSharedData
->SetLastRow( nCurrentTable
, pCaptData
->maStart
.Row() );
2698 // other objects from internal layer only (detective)
2699 else if( pObject
->GetLayer() == SC_LAYER_INTERN
)
2701 ScDetectiveFunc
aDetFunc( *pDoc
, static_cast<SCTAB
>(nCurrentTable
) );
2702 ScAddress aPosition
;
2703 ScRange aSourceRange
;
2705 ScDetectiveObjType eObjType
= aDetFunc
.GetDetectiveObjectType(
2706 pObject
, nCurrentTable
, aPosition
, aSourceRange
, bRedLine
);
2707 pSharedData
->GetDetectiveObjContainer()->AddObject( eObjType
, static_cast<SCTAB
>(nCurrentTable
), aPosition
, aSourceRange
, bRedLine
);
2711 bool ScXMLExport::GetMerged (const table::CellRangeAddress
* pCellAddress
,
2712 const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
2715 sal_Int32
nRow(pCellAddress
->StartRow
);
2716 sal_Int32
nCol(pCellAddress
->StartColumn
);
2717 sal_Int32
nEndRow(pCellAddress
->EndRow
);
2718 sal_Int32
nEndCol(pCellAddress
->EndColumn
);
2719 bool bRowInc(nEndRow
> nRow
);
2720 while(!bReady
&& nRow
<= nEndRow
&& nCol
<= nEndCol
)
2722 uno::Reference
<sheet::XSheetCellRange
> xSheetCellRange(xTable
->getCellRangeByPosition(nCol
, nRow
, nCol
, nRow
), uno::UNO_QUERY
);
2723 if (xSheetCellRange
.is())
2725 uno::Reference
<sheet::XSheetCellCursor
> xCursor(xTable
->createCursorByRange(xSheetCellRange
));
2728 uno::Reference
<sheet::XCellRangeAddressable
> xCellAddress (xCursor
, uno::UNO_QUERY
);
2729 xCursor
->collapseToMergedArea();
2730 table::CellRangeAddress
aCellAddress2(xCellAddress
->getRangeAddress());
2731 ScRange
aScRange( aCellAddress2
.StartColumn
, aCellAddress2
.StartRow
, aCellAddress2
.Sheet
,
2732 aCellAddress2
.EndColumn
, aCellAddress2
.EndRow
, aCellAddress2
.Sheet
);
2734 if ((aScRange
.aEnd
.Row() > nRow
||
2735 aScRange
.aEnd
.Col() > nCol
) &&
2736 aScRange
.aStart
.Row() == nRow
&&
2737 aScRange
.aStart
.Col() == nCol
)
2739 pMergedRangesContainer
->AddRange(aScRange
);
2740 pSharedData
->SetLastColumn(aScRange
.aEnd
.Tab(), aScRange
.aEnd
.Col());
2741 pSharedData
->SetLastRow(aScRange
.aEnd
.Tab(), aScRange
.aEnd
.Row());
2755 OSL_ENSURE(!(!bReady
&& nEndRow
> nRow
&& nEndCol
> nCol
), "should not be possible");
2759 bool ScXMLExport::IsMatrix (const ScAddress
& aCell
,
2760 ScRange
& aCellAddress
, bool& bIsFirst
) const
2764 ScRange aMatrixRange
;
2766 if (pDoc
&& pDoc
->GetMatrixFormulaRange(aCell
, aMatrixRange
))
2768 aCellAddress
= aMatrixRange
;
2769 if ((aCellAddress
.aStart
.Col() == aCell
.Col() && aCellAddress
.aStart
.Row() == aCell
.Row()) &&
2770 (aCellAddress
.aEnd
.Col() > aCell
.Col() || aCellAddress
.aEnd
.Row() > aCell
.Row()))
2775 else if (aCellAddress
.aStart
.Col() != aCell
.Col() || aCellAddress
.aStart
.Row() != aCell
.Row() ||
2776 aCellAddress
.aEnd
.Col() != aCell
.Col() || aCellAddress
.aEnd
.Row()!= aCell
.Row())
2788 void ScXMLExport::WriteTable(sal_Int32 nTable
, const uno::Reference
<sheet::XSpreadsheet
>& xTable
)
2793 xCurrentTable
.set(xTable
);
2794 uno::Reference
<container::XNamed
> xName (xTable
, uno::UNO_QUERY
);
2798 nCurrentTable
= sal::static_int_cast
<sal_uInt16
>( nTable
);
2799 OUString
sOUTableName(xName
->getName());
2800 AddAttribute(sAttrName
, sOUTableName
);
2801 AddAttribute(sAttrStyleName
, aTableStyles
[nTable
]);
2803 uno::Reference
<util::XProtectable
> xProtectable (xTable
, uno::UNO_QUERY
);
2804 ScTableProtection
* pProtect
= nullptr;
2805 if (xProtectable
.is() && xProtectable
->isProtected())
2807 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
2810 pProtect
= pDoc
->GetTabProtection(nTable
);
2813 OUStringBuffer aBuffer
;
2814 ScPasswordHash eHashUsed
= PASSHASH_UNSPECIFIED
;
2815 if (pProtect
->hasPasswordHash(PASSHASH_SHA1
))
2817 ::comphelper::Base64::encode(aBuffer
,
2818 pProtect
->getPasswordHash(PASSHASH_SHA1
));
2819 eHashUsed
= PASSHASH_SHA1
;
2821 else if (pProtect
->hasPasswordHash(PASSHASH_SHA256
))
2823 ::comphelper::Base64::encode(aBuffer
,
2824 pProtect
->getPasswordHash(PASSHASH_SHA256
));
2825 eHashUsed
= PASSHASH_SHA256
;
2827 else if (pProtect
->hasPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
))
2829 // Double-hash this by SHA1 on top of the legacy xls hash.
2830 uno::Sequence
<sal_Int8
> aHash
= pProtect
->getPasswordHash(PASSHASH_XL
, PASSHASH_SHA1
);
2831 ::comphelper::Base64::encode(aBuffer
, aHash
);
2832 eHashUsed
= PASSHASH_XL
;
2834 if (!aBuffer
.isEmpty())
2836 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY
, aBuffer
.makeStringAndClear());
2837 if (getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
2839 if (eHashUsed
== PASSHASH_XL
)
2841 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2842 ScPassHashHelper::getHashURI(PASSHASH_XL
));
2843 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2844 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
,
2845 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
2847 else if (eHashUsed
== PASSHASH_SHA1
)
2849 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2850 ScPassHashHelper::getHashURI(PASSHASH_SHA1
));
2852 else if (eHashUsed
== PASSHASH_SHA256
)
2854 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
,
2855 ScPassHashHelper::getHashURI(PASSHASH_SHA256
));
2862 OUString sPrintRanges
;
2863 ScRange aColumnHeaderRange
;
2864 bool bHasColumnHeader
;
2865 GetColumnRowHeader(bHasColumnHeader
, aColumnHeaderRange
, bHasRowHeader
, aRowHeaderRange
, sPrintRanges
);
2866 if( !sPrintRanges
.isEmpty() )
2867 AddAttribute( XML_NAMESPACE_TABLE
, XML_PRINT_RANGES
, sPrintRanges
);
2868 else if (pDoc
&& !pDoc
->IsPrintEntireSheet(static_cast<SCTAB
>(nTable
)))
2869 AddAttribute( XML_NAMESPACE_TABLE
, XML_PRINT
, XML_FALSE
);
2870 SvXMLElementExport
aElemT(*this, sElemTab
, true, true);
2872 if (pProtect
&& pProtect
->isProtected() && getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2874 if (pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
))
2875 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SELECT_PROTECTED_CELLS
, XML_TRUE
);
2876 if (pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
))
2877 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SELECT_UNPROTECTED_CELLS
, XML_TRUE
);
2879 if (pProtect
->isOptionEnabled(ScTableProtection::INSERT_COLUMNS
))
2880 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_INSERT_COLUMNS
, XML_TRUE
);
2881 if (pProtect
->isOptionEnabled(ScTableProtection::INSERT_ROWS
))
2882 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_INSERT_ROWS
, XML_TRUE
);
2884 if (pProtect
->isOptionEnabled(ScTableProtection::DELETE_COLUMNS
))
2885 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DELETE_COLUMNS
, XML_TRUE
);
2886 if (pProtect
->isOptionEnabled(ScTableProtection::DELETE_ROWS
))
2887 AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DELETE_ROWS
, XML_TRUE
);
2889 OUString aElemName
= GetNamespaceMap().GetQNameByKey(
2890 XML_NAMESPACE_LO_EXT
, GetXMLToken(XML_TABLE_PROTECTION
));
2892 SvXMLElementExport
aElemProtected(*this, aElemName
, true, true);
2897 if ( pDoc
&& pDoc
->GetSheetEvents( static_cast<SCTAB
>(nTable
) ) &&
2898 getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
2900 // store sheet events
2901 uno::Reference
<document::XEventsSupplier
> xSupplier(xTable
, uno::UNO_QUERY
);
2902 uno::Reference
<container::XNameAccess
> xEvents
= xSupplier
->getEvents();
2903 GetEventExport().ExportExt( xEvents
);
2908 uno::Reference
<drawing::XDrawPage
> xDrawPage
;
2909 if (pSharedData
->HasForm(nTable
, xDrawPage
) && xDrawPage
.is())
2911 ::xmloff::OOfficeFormsExport
aForms(*this);
2912 GetFormExport()->exportForms( xDrawPage
);
2913 bool bRet(GetFormExport()->seekPage( xDrawPage
));
2914 OSL_ENSURE( bRet
, "OFormLayerXMLExport::seekPage failed!" );
2916 if (pSharedData
->HasDrawPage())
2918 GetShapeExport()->seekShapes(pSharedData
->GetDrawPage(nTable
));
2921 table::CellRangeAddress
aRange(GetEndAddress(xTable
));
2922 pSharedData
->SetLastColumn(nTable
, aRange
.EndColumn
);
2923 pSharedData
->SetLastRow(nTable
, aRange
.EndRow
);
2924 mpCellsItr
->SetCurrentTable(static_cast<SCTAB
>(nTable
), xCurrentTable
);
2925 pGroupColumns
->NewTable();
2926 pGroupRows
->NewTable();
2927 FillColumnRowGroups();
2928 if (bHasColumnHeader
)
2929 pSharedData
->SetLastColumn(nTable
, aColumnHeaderRange
.aEnd
.Col());
2930 bRowHeaderOpen
= false;
2932 pSharedData
->SetLastRow(nTable
, aRowHeaderRange
.aEnd
.Row());
2933 pDefaults
->FillDefaultStyles(nTable
, pSharedData
->GetLastRow(nTable
),
2934 pSharedData
->GetLastColumn(nTable
), pCellStyles
.get(), pDoc
);
2935 pRowFormatRanges
->SetColDefaults(&pDefaults
->GetColDefaults());
2936 pCellStyles
->SetColDefaults(&pDefaults
->GetColDefaults());
2937 ExportColumns(nTable
, aColumnHeaderRange
, bHasColumnHeader
);
2938 bool bIsFirst(true);
2939 sal_Int32
nEqualCells(0);
2942 while (mpCellsItr
->GetNext(aCell
, pCellStyles
.get()))
2946 ExportFormatRanges(0, 0, aCell
.maCellAddress
.Col()-1, aCell
.maCellAddress
.Row(), nTable
);
2952 if ((aPrevCell
.maCellAddress
.Row() == aCell
.maCellAddress
.Row()) &&
2953 (aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1 == aCell
.maCellAddress
.Col()))
2955 if(IsCellEqual(aPrevCell
, aCell
))
2959 WriteCell(aPrevCell
, nEqualCells
);
2966 WriteCell(aPrevCell
, nEqualCells
);
2967 ExportFormatRanges(aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1, aPrevCell
.maCellAddress
.Row(),
2968 aCell
.maCellAddress
.Col()-1, aCell
.maCellAddress
.Row(), nTable
);
2976 WriteCell(aPrevCell
, nEqualCells
);
2977 ExportFormatRanges(aPrevCell
.maCellAddress
.Col() + nEqualCells
+ 1, aPrevCell
.maCellAddress
.Row(),
2978 pSharedData
->GetLastColumn(nTable
), pSharedData
->GetLastRow(nTable
), nTable
);
2981 ExportFormatRanges(0, 0, pSharedData
->GetLastColumn(nTable
), pSharedData
->GetLastRow(nTable
), nTable
);
2983 CloseRow(pSharedData
->GetLastRow(nTable
));
2988 // Export sheet-local named ranges.
2989 ScRangeName
* pRangeName
= pDoc
->GetRangeName(nTable
);
2990 if (pRangeName
&& !pRangeName
->empty())
2992 WriteNamedRange(pRangeName
);
2995 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2997 //export new conditional format information
2998 ExportConditionalFormat(nTable
);
3005 ScXMLExport
& rExport
, const OUString
& rStyleName
, const OUString
& rContent
, const SvxFieldData
* pField
)
3007 std::unique_ptr
<SvXMLElementExport
> pElem
;
3008 if (!rStyleName
.isEmpty())
3010 // Formatted section with automatic style.
3011 rExport
.AddAttribute(XML_NAMESPACE_TEXT
, XML_STYLE_NAME
, rStyleName
);
3012 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3013 XML_NAMESPACE_TEXT
, GetXMLToken(XML_SPAN
));
3014 pElem
.reset(new SvXMLElementExport(rExport
, aElemName
, false, false));
3019 // Write a field item.
3020 OUString aFieldVal
= ScEditUtil::GetCellFieldValue(*pField
, rExport
.GetDocument(), nullptr);
3021 switch (pField
->GetClassId())
3023 case text::textfield::Type::URL
:
3025 // <text:a xlink:href="url" xlink:type="simple">value</text:a>
3027 const SvxURLField
* pURLField
= static_cast<const SvxURLField
*>(pField
);
3028 const OUString
& aURL
= pURLField
->GetURL();
3029 rExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, rExport
.GetRelativeReference(aURL
));
3030 rExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, "simple");
3031 const OUString
& aTargetFrame
= pURLField
->GetTargetFrame();
3032 if (!aTargetFrame
.isEmpty())
3033 rExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_TARGET_FRAME_NAME
, aTargetFrame
);
3035 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3036 XML_NAMESPACE_TEXT
, GetXMLToken(XML_A
));
3037 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3038 rExport
.Characters(aFieldVal
);
3041 case text::textfield::Type::DATE
:
3043 // <text:date style:data-style-name="N2" text:date-value="YYYY-MM-DD">value</text:date>
3045 Date
aDate(Date::SYSTEM
);
3046 OUStringBuffer aBuf
;
3047 sal_Int32 nVal
= aDate
.GetYear();
3050 nVal
= aDate
.GetMonth();
3055 nVal
= aDate
.GetDay();
3059 rExport
.AddAttribute(XML_NAMESPACE_STYLE
, XML_DATA_STYLE_NAME
, "N2");
3060 rExport
.AddAttribute(XML_NAMESPACE_TEXT
, XML_DATE_VALUE
, aBuf
.makeStringAndClear());
3062 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3063 XML_NAMESPACE_TEXT
, GetXMLToken(XML_DATE
));
3064 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3065 rExport
.Characters(aFieldVal
);
3068 case text::textfield::Type::DOCINFO_TITLE
:
3070 // <text:title>value</text:title>
3072 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3073 XML_NAMESPACE_TEXT
, GetXMLToken(XML_TITLE
));
3074 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3075 rExport
.Characters(aFieldVal
);
3078 case text::textfield::Type::TABLE
:
3080 // <text:sheet-name>value</text:sheet-name>
3082 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3083 XML_NAMESPACE_TEXT
, GetXMLToken(XML_SHEET_NAME
));
3084 SvXMLElementExport
aElem(rExport
, aElemName
, false, false);
3085 rExport
.Characters(aFieldVal
);
3089 rExport
.Characters(aFieldVal
);
3093 rExport
.Characters(rContent
);
3096 void flushParagraph(
3097 ScXMLExport
& rExport
, const OUString
& rParaText
,
3098 rtl::Reference
<XMLPropertySetMapper
> const & xMapper
, rtl::Reference
<SvXMLAutoStylePoolP
> const & xStylePool
,
3099 const ScXMLEditAttributeMap
& rAttrMap
,
3100 std::vector
<editeng::Section
>::const_iterator it
, std::vector
<editeng::Section
>::const_iterator
const & itEnd
)
3102 OUString aElemName
= rExport
.GetNamespaceMap().GetQNameByKey(
3103 XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
3104 SvXMLElementExport
aElemP(rExport
, aElemName
, false, false);
3106 for (; it
!= itEnd
; ++it
)
3108 const editeng::Section
& rSec
= *it
;
3110 OUString
aContent(rParaText
.copy(rSec
.mnStart
, rSec
.mnEnd
- rSec
.mnStart
));
3112 std::vector
<XMLPropertyState
> aPropStates
;
3113 const SvxFieldData
* pField
= toXMLPropertyStates(aPropStates
, rSec
.maAttributes
, xMapper
, rAttrMap
);
3114 OUString aStyleName
= xStylePool
->Find(XmlStyleFamily::TEXT_TEXT
, OUString(), aPropStates
);
3115 writeContent(rExport
, aStyleName
, aContent
, pField
);
3121 void ScXMLExport::WriteCell(ScMyCell
& aCell
, sal_Int32 nEqualCellCount
)
3123 // nEqualCellCount is the number of additional cells
3124 SetRepeatAttribute(nEqualCellCount
, (aCell
.nType
!= table::CellContentType_EMPTY
));
3126 if (aCell
.nStyleIndex
!= -1)
3127 AddAttribute(sAttrStyleName
, pCellStyles
->GetStyleNameByIndex(aCell
.nStyleIndex
, aCell
.bIsAutoStyle
));
3128 if (aCell
.nValidationIndex
> -1)
3129 AddAttribute(XML_NAMESPACE_TABLE
, XML_CONTENT_VALIDATION_NAME
, pValidationsContainer
->GetValidationName(aCell
.nValidationIndex
));
3130 const bool bIsFirstMatrixCell(aCell
.bIsMatrixBase
);
3131 if (bIsFirstMatrixCell
)
3133 SCCOL
nColumns( aCell
.aMatrixRange
.aEnd
.Col() - aCell
.aMatrixRange
.aStart
.Col() + 1 );
3134 SCROW
nRows( aCell
.aMatrixRange
.aEnd
.Row() - aCell
.aMatrixRange
.aStart
.Row() + 1 );
3135 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_MATRIX_COLUMNS_SPANNED
, OUString::number(nColumns
));
3136 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_MATRIX_ROWS_SPANNED
, OUString::number(nRows
));
3138 bool bIsEmpty(false);
3139 switch (aCell
.nType
)
3141 case table::CellContentType_EMPTY
:
3146 case table::CellContentType_VALUE
:
3148 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3149 aCell
.nNumberFormat
, aCell
.maBaseCell
.mfValue
);
3150 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3151 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3152 aCell
.nNumberFormat
, aCell
.maBaseCell
.mfValue
, false, XML_NAMESPACE_CALC_EXT
, false);
3155 case table::CellContentType_TEXT
:
3157 OUString
sFormattedString(lcl_GetFormattedString(pDoc
, aCell
.maBaseCell
, aCell
.maCellAddress
));
3158 OUString sCellString
= aCell
.maBaseCell
.getString(pDoc
);
3159 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3160 sCellString
, sFormattedString
);
3161 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3162 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3163 sCellString
, sFormattedString
, false, XML_NAMESPACE_CALC_EXT
);
3166 case table::CellContentType_FORMULA
:
3168 if (aCell
.maBaseCell
.meType
== CELLTYPE_FORMULA
)
3170 const bool bIsMatrix(bIsFirstMatrixCell
|| aCell
.bIsMatrixCovered
);
3171 ScFormulaCell
* pFormulaCell
= aCell
.maBaseCell
.mpFormula
;
3172 if (!bIsMatrix
|| bIsFirstMatrixCell
)
3174 if (!mpCompileFormulaCxt
)
3176 const formula::FormulaGrammar::Grammar eGrammar
= pDoc
->GetStorageGrammar();
3177 mpCompileFormulaCxt
.reset(new sc::CompileFormulaContext(*pDoc
, eGrammar
));
3180 OUString aFormula
= pFormulaCell
->GetFormula(*mpCompileFormulaCxt
);
3181 sal_uInt16 nNamespacePrefix
=
3182 (mpCompileFormulaCxt
->getGrammar() == formula::FormulaGrammar::GRAM_ODFF
? XML_NAMESPACE_OF
: XML_NAMESPACE_OOOC
);
3186 AddAttribute(sAttrFormula
, GetNamespaceMap().GetQNameByKey(nNamespacePrefix
, aFormula
, false));
3190 AddAttribute(sAttrFormula
, GetNamespaceMap().GetQNameByKey(nNamespacePrefix
, aFormula
.copy(1, aFormula
.getLength()-2), false));
3193 if (pFormulaCell
->GetErrCode() != FormulaError::NONE
)
3195 AddAttribute(sAttrValueType
, XML_STRING
);
3196 AddAttribute(sAttrStringValue
, aCell
.maBaseCell
.getString(pDoc
));
3197 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3199 //export calcext:value-type="error"
3200 AddAttribute(XML_NAMESPACE_CALC_EXT
,XML_VALUE_TYPE
, OUString("error"));
3203 else if (pFormulaCell
->IsValue())
3207 GetNumberFormatAttributesExportHelper()->GetCellType(aCell
.nNumberFormat
, sCurrency
, bIsStandard
);
3210 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3211 aCell
.nNumberFormat
, pDoc
->GetValue(aCell
.maCellAddress
));
3212 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3214 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3215 aCell
.nNumberFormat
, pDoc
->GetValue(aCell
.maCellAddress
), false, XML_NAMESPACE_CALC_EXT
, false );
3221 if (!aCell
.maBaseCell
.getString(pDoc
).isEmpty())
3223 AddAttribute(sAttrValueType
, XML_STRING
);
3224 AddAttribute(sAttrStringValue
, aCell
.maBaseCell
.getString(pDoc
));
3225 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
3227 AddAttribute(XML_NAMESPACE_CALC_EXT
,XML_VALUE_TYPE
, XML_STRING
);
3237 OUString
* pCellString(&sElemCell
);
3238 if (aCell
.bIsCovered
)
3240 pCellString
= &sElemCoveredCell
;
3244 if (aCell
.bIsMergedBase
)
3246 SCCOL
nColumns( aCell
.aMergeRange
.aEnd
.Col() - aCell
.aMergeRange
.aStart
.Col() + 1 );
3247 SCROW
nRows( aCell
.aMergeRange
.aEnd
.Row() - aCell
.aMergeRange
.aStart
.Row() + 1 );
3248 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_SPANNED
, OUString::number(nColumns
));
3249 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_SPANNED
, OUString::number(nRows
));
3252 SvXMLElementExport
aElemC(*this, *pCellString
, true, true);
3254 WriteAreaLink(aCell
);
3255 WriteAnnotation(aCell
);
3256 WriteDetective(aCell
);
3260 if (aCell
.maBaseCell
.meType
== CELLTYPE_EDIT
)
3262 WriteEditCell(aCell
.maBaseCell
.mpEditText
);
3264 else if (aCell
.maBaseCell
.meType
== CELLTYPE_FORMULA
&& aCell
.maBaseCell
.mpFormula
->IsMultilineResult())
3266 WriteMultiLineFormulaResult(aCell
.maBaseCell
.mpFormula
);
3270 SvXMLElementExport
aElemP(*this, sElemP
, true, false);
3273 ScCellFormat::GetOutputString(*pDoc
, aCell
.maCellAddress
, aCell
.maBaseCell
);
3275 bool bPrevCharWasSpace
= true;
3276 GetTextParagraphExport()->exportCharacterData(aParaStr
, bPrevCharWasSpace
);
3281 IncrementProgressBar(false);
3284 void ScXMLExport::WriteEditCell(const EditTextObject
* pText
)
3286 rtl::Reference
<XMLPropertySetMapper
> xMapper
= GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
3287 rtl::Reference
<SvXMLAutoStylePoolP
> xStylePool
= GetAutoStylePool();
3288 const ScXMLEditAttributeMap
& rAttrMap
= GetEditAttributeMap();
3290 // Get raw paragraph texts first.
3291 std::vector
<OUString
> aParaTexts
;
3292 sal_Int32 nParaCount
= pText
->GetParagraphCount();
3293 aParaTexts
.reserve(nParaCount
);
3294 for (sal_Int32 i
= 0; i
< nParaCount
; ++i
)
3295 aParaTexts
.push_back(pText
->GetText(i
));
3297 // Get all section data and iterate through them.
3298 std::vector
<editeng::Section
> aAttrs
;
3299 pText
->GetAllSections(aAttrs
);
3300 std::vector
<editeng::Section
>::const_iterator itSec
= aAttrs
.begin(), itSecEnd
= aAttrs
.end();
3301 std::vector
<editeng::Section
>::const_iterator itPara
= itSec
;
3302 sal_Int32 nCurPara
= 0; // current paragraph
3303 for (; itSec
!= itSecEnd
; ++itSec
)
3305 const editeng::Section
& rSec
= *itSec
;
3306 if (nCurPara
== rSec
.mnParagraph
)
3307 // Still in the same paragraph.
3310 // Start of a new paragraph. Flush the old paragraph.
3311 flushParagraph(*this, aParaTexts
[nCurPara
], xMapper
, xStylePool
, rAttrMap
, itPara
, itSec
);
3312 nCurPara
= rSec
.mnParagraph
;
3316 flushParagraph(*this, aParaTexts
[nCurPara
], xMapper
, xStylePool
, rAttrMap
, itPara
, itSecEnd
);
3319 void ScXMLExport::WriteMultiLineFormulaResult(const ScFormulaCell
* pCell
)
3321 OUString aElemName
= GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TEXT
, GetXMLToken(XML_P
));
3323 OUString aResStr
= pCell
->GetResultString().getString();
3324 const sal_Unicode
* p
= aResStr
.getStr();
3325 const sal_Unicode
* pEnd
= p
+ static_cast<size_t>(aResStr
.getLength());
3326 const sal_Unicode
* pPara
= p
; // paragraph head.
3327 for (; p
!= pEnd
; ++p
)
3332 // flush the paragraph.
3337 aContent
= OUString(pPara
, p
-pPara
);
3339 SvXMLElementExport
aElem(*this, aElemName
, false, false);
3340 Characters(aContent
);
3349 aContent
= OUString(pPara
, pEnd
-pPara
);
3351 SvXMLElementExport
aElem(*this, aElemName
, false, false);
3352 Characters(aContent
);
3355 void ScXMLExport::ExportShape(const uno::Reference
< drawing::XShape
>& xShape
, awt::Point
* pPoint
)
3357 uno::Reference
< beans::XPropertySet
> xShapeProps ( xShape
, uno::UNO_QUERY
);
3358 bool bIsChart( false );
3359 if (xShapeProps
.is())
3361 sal_Int32 nZOrder
= 0;
3362 if (xShapeProps
->getPropertyValue("ZOrder") >>= nZOrder
)
3364 AddAttribute(XML_NAMESPACE_DRAW
, XML_ZINDEX
, OUString::number(nZOrder
));
3366 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
= xShapeProps
->getPropertySetInfo();
3367 OUString
sPropCLSID ("CLSID");
3368 if( xPropSetInfo
->hasPropertyByName( sPropCLSID
) )
3371 if (xShapeProps
->getPropertyValue( sPropCLSID
) >>= sCLSID
)
3373 if ( sCLSID
.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) )
3379 OUString aChartName
;
3380 xShapeProps
->getPropertyValue( "PersistName" ) >>= aChartName
;
3381 ScChartListenerCollection
* pCollection
= pDoc
->GetChartListenerCollection();
3384 ScChartListener
* pListener
= pCollection
->findByName(aChartName
);
3387 const ScRangeListRef
& rRangeList
= pListener
->GetRangeList();
3388 if ( rRangeList
.is() )
3390 ScRangeStringConverter::GetStringFromRangeList( sRanges
, rRangeList
.get(), pDoc
, FormulaGrammar::CONV_OOO
);
3391 if ( !sRanges
.isEmpty() )
3394 SvXMLAttributeList
* pAttrList
= new SvXMLAttributeList();
3395 pAttrList
->AddAttribute(
3396 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW
, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES
) ), sRanges
);
3397 GetShapeExport()->exportShape( xShape
, SEF_DEFAULT
, pPoint
, pAttrList
);
3404 if ( sRanges
.isEmpty() )
3406 uno::Reference
< frame::XModel
> xChartModel
;
3407 if( ( xShapeProps
->getPropertyValue( "Model" ) >>= xChartModel
) &&
3410 uno::Reference
< chart2::XChartDocument
> xChartDoc( xChartModel
, uno::UNO_QUERY
);
3411 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartModel
, uno::UNO_QUERY
);
3412 if( xChartDoc
.is() && xReceiver
.is() &&
3413 ! xChartDoc
->hasInternalDataProvider())
3415 // we have a chart that gets its data from Calc
3417 uno::Sequence
< OUString
> aRepresentations(
3418 xReceiver
->getUsedRangeRepresentations());
3419 SvXMLAttributeList
* pAttrList
= nullptr;
3420 if(aRepresentations
.hasElements())
3422 // add the ranges used by the chart to the shape
3423 // element to be able to start listening after
3424 // load (when the chart is not yet loaded)
3425 uno::Reference
< chart2::data::XRangeXMLConversion
> xRangeConverter( xChartDoc
->getDataProvider(), uno::UNO_QUERY
);
3426 sRanges
= lcl_RangeSequenceToString( aRepresentations
, xRangeConverter
);
3427 pAttrList
= new SvXMLAttributeList();
3428 pAttrList
->AddAttribute(
3429 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW
, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES
) ), sRanges
);
3431 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
, pPoint
, pAttrList
);
3444 uno::Reference
< beans::XPropertySet
> xProps( xShape
, uno::UNO_QUERY
);
3446 xProps
->getPropertyValue( SC_UNONAME_HYPERLINK
) >>= sHlink
;
3448 catch ( const beans::UnknownPropertyException
& )
3450 // no hyperlink property
3453 std::unique_ptr
< SvXMLElementExport
> pDrawA
;
3454 // enclose shapes with <draw:a> element only if sHlink contains something
3455 if ( !sHlink
.isEmpty() )
3457 // need to get delete the attributes that are pre-loaded
3458 // for the shape export ( otherwise they will become
3459 // attributes of the draw:a element ) This *shouldn't*
3460 // affect performance adversely as there are only a
3461 // couple of attributes involved
3462 uno::Reference
< xml::sax::XAttributeList
> xSaveAttribs( new SvXMLAttributeList( GetAttrList() ) );
3465 AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3466 AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, sHlink
);
3467 pDrawA
.reset( new SvXMLElementExport( *this, XML_NAMESPACE_DRAW
, XML_A
, false, false ) );
3468 // Attribute list has been cleared by previous operation
3469 // re-add pre-loaded attributes
3470 AddAttributeList( xSaveAttribs
);
3472 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
, pPoint
);
3474 IncrementProgressBar(false);
3477 void ScXMLExport::WriteShapes(const ScMyCell
& rMyCell
)
3479 if( !(rMyCell
.bHasShape
&& !rMyCell
.aShapeList
.empty() && pDoc
) )
3482 // Reference point to turn absolute coordinates in reference point + offset. That happens in most
3483 // cases in XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint, which gets the absolute
3484 // coordinates as translation from matrix in property "Transformation". For cell anchored shapes
3485 // the reference point is left-top (in LTR mode) of that cell, which contains the shape.
3486 tools::Rectangle aCellRectFull
= pDoc
->GetMMRect(
3487 rMyCell
.maCellAddress
.Col(), rMyCell
.maCellAddress
.Row(), rMyCell
.maCellAddress
.Col(),
3488 rMyCell
.maCellAddress
.Row(), rMyCell
.maCellAddress
.Tab(), false /*bHiddenAsZero*/);
3490 bool bNegativePage
= pDoc
->IsNegativePage(rMyCell
.maCellAddress
.Tab());
3492 aPoint
.X
= aCellRectFull
.Right();
3494 aPoint
.X
= aCellRectFull
.Left();
3495 aPoint
.Y
= aCellRectFull
.Top();
3497 for (const auto& rShape
: rMyCell
.aShapeList
)
3499 if (rShape
.xShape
.is())
3501 // The current object geometry is based on bHiddenAsZero=true, but ODF file format
3502 // needs it as if there were no hidden rows or columns. We manipulate the geometry
3503 // accordingly for writing xml markup and restore geometry later.
3504 bool bNeedsRestore
= false;
3505 SdrObject
* pObj
= GetSdrObjectFromXShape(rShape
.xShape
);
3506 // Remember original geometry
3507 SdrObjGeoData
* pGeoData
= nullptr;
3509 pGeoData
= pObj
->GetGeoData();
3511 // Hiding row or column affects the shape based on its snap rect. So we need start and
3512 // end cell address of snap rect. In case of a transformed shape, it is not in rMyCell.
3513 ScAddress aSnapStartAddress
= rMyCell
.maCellAddress
;
3514 ScDrawObjData
* pObjData
= nullptr;
3515 bool bIsShapeTransformed
= false;
3518 pObjData
= ScDrawLayer::GetObjData(pObj
);
3519 bIsShapeTransformed
= pObj
->GetRotateAngle() != 0 || pObj
->GetShearAngle() != 0;
3521 if (bIsShapeTransformed
&& pObjData
)
3522 aSnapStartAddress
= pObjData
->maStart
;
3524 // In case rows or columns are hidden above or before the snap rect, move the shape to the
3525 // position it would have, if these rows and columns are visible.
3526 tools::Rectangle aRectFull
= pDoc
->GetMMRect(
3527 aSnapStartAddress
.Col(), aSnapStartAddress
.Row(), aSnapStartAddress
.Col(),
3528 aSnapStartAddress
.Row(), aSnapStartAddress
.Tab(), false /*bHiddenAsZero*/);
3529 tools::Rectangle aRectReduced
= pDoc
->GetMMRect(
3530 aSnapStartAddress
.Col(), aSnapStartAddress
.Row(), aSnapStartAddress
.Col(),
3531 aSnapStartAddress
.Row(), aSnapStartAddress
.Tab(), true /*bHiddenAsZero*/);
3532 const tools::Long
nLeftDiff(aRectFull
.Left() - aRectReduced
.Left());
3533 const tools::Long
nTopDiff(aRectFull
.Top() - aRectReduced
.Top());
3534 if (pObj
&& (abs(nLeftDiff
) > 1 || abs(nTopDiff
) > 1))
3536 bNeedsRestore
= true;
3537 pObj
->NbcMove(Size(nLeftDiff
, nTopDiff
));
3540 // tdf#137033 In case the shape is anchored "To Cell (resize with cell)" hiding rows or
3541 // columns inside the snap rect has not only changed size of the shape but rotate and shear
3542 // angle too. We resize the shape to full size. That will recover the original angles too.
3543 if (rShape
.bResizeWithCell
&& pObjData
&& pObj
)
3545 // Get original size from anchor
3546 const Point aSnapStartOffset
= pObjData
->maStartOffset
;
3547 // In case of 'resize with cell' maEnd and maEndOffset should be valid.
3548 const ScAddress
aSnapEndAddress(pObjData
->maEnd
);
3549 const Point aSnapEndOffset
= pObjData
->maEndOffset
;
3550 const tools::Rectangle aStartCellRect
= pDoc
->GetMMRect(
3551 aSnapStartAddress
.Col(), aSnapStartAddress
.Row(), aSnapStartAddress
.Col(),
3552 aSnapStartAddress
.Row(), aSnapStartAddress
.Tab(), false /*bHiddenAsZero*/);
3553 const tools::Rectangle aEndCellRect
= pDoc
->GetMMRect(
3554 aSnapEndAddress
.Col(), aSnapEndAddress
.Row(), aSnapEndAddress
.Col(),
3555 aSnapEndAddress
.Row(), aSnapEndAddress
.Tab(), false /*bHiddenAsZero*/);
3558 aRectFull
.SetLeft(aEndCellRect
.Right() - aSnapEndOffset
.X());
3559 aRectFull
.SetRight(aStartCellRect
.Right() - aSnapStartOffset
.X());
3563 aRectFull
.SetLeft(aStartCellRect
.Left() + aSnapStartOffset
.X());
3564 aRectFull
.SetRight(aEndCellRect
.Left() + aSnapEndOffset
.X());
3566 aRectFull
.SetTop(aStartCellRect
.Top() + aSnapStartOffset
.Y());
3567 aRectFull
.SetBottom(aEndCellRect
.Top() + aSnapEndOffset
.Y());
3568 aRectReduced
= pObjData
->getShapeRect();
3569 if(abs(aRectFull
.getWidth() - aRectReduced
.getWidth()) > 1
3570 || abs(aRectFull
.getHeight() - aRectReduced
.getHeight()) > 1)
3572 bNeedsRestore
= true;
3573 Fraction
aScaleWidth(aRectFull
.getWidth(), aRectReduced
.getWidth());
3574 if (!aScaleWidth
.IsValid())
3575 aScaleWidth
= Fraction(1.0);
3576 Fraction
aScaleHeight(aRectFull
.getHeight(), aRectReduced
.getHeight());
3577 if (!aScaleHeight
.IsValid())
3578 aScaleHeight
= Fraction(1.0);
3579 pObj
->NbcResize(pObj
->GetRelativePos(), aScaleWidth
, aScaleHeight
);
3583 // We only write the end address if we want the shape to resize with the cell
3584 if ( rShape
.bResizeWithCell
&&
3585 rShape
.xShape
->getShapeType() != "com.sun.star.drawing.CaptionShape" )
3587 OUString sEndAddress
;
3588 ScRangeStringConverter::GetStringFromAddress(sEndAddress
, rShape
.aEndAddress
, pDoc
, FormulaGrammar::CONV_OOO
);
3589 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_CELL_ADDRESS
, sEndAddress
);
3590 OUStringBuffer sBuffer
;
3591 GetMM100UnitConverter().convertMeasureToXML(
3592 sBuffer
, rShape
.nEndX
);
3593 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_X
, sBuffer
.makeStringAndClear());
3594 GetMM100UnitConverter().convertMeasureToXML(
3595 sBuffer
, rShape
.nEndY
);
3596 AddAttribute(XML_NAMESPACE_TABLE
, XML_END_Y
, sBuffer
.makeStringAndClear());
3599 // Correct above calculated reference point for some cases:
3600 // a) For a RTL-sheet translate from matrix is not suitable, because the shape
3601 // from xml (which is always LTR) is not mirrored to negative page but shifted.
3602 // b) In case of horizontal mirrored, 'resize with cell' anchored custom shape, translate
3603 // has wrong values. FixMe: Why is translate wrong?
3604 // c) Measure lines do not use transformation matrix but use start and end point directly.
3605 ScDrawObjData
* pNRObjData
= nullptr;
3606 if (pObj
&& bNegativePage
3607 && rShape
.xShape
->getShapeType() == "com.sun.star.drawing.MeasureShape")
3609 // invers of shift when import
3610 tools::Rectangle aSnapRect
= pObj
->GetSnapRect();
3611 aPoint
.X
= aSnapRect
.Left() + aSnapRect
.Right() - aPoint
.X
;
3613 else if (pObj
&& (pNRObjData
= ScDrawLayer::GetNonRotatedObjData(pObj
))
3614 && ((rShape
.bResizeWithCell
&& pObj
->GetObjIdentifier() == OBJ_CUSTOMSHAPE
3615 && static_cast<SdrObjCustomShape
*>(pObj
)->IsMirroredX())
3618 //In these cases we set reference Point = matrix translate - startOffset.
3619 awt::Point aMatrixTranslate
= rShape
.xShape
->getPosition();
3620 aPoint
.X
= aMatrixTranslate
.X
- pNRObjData
->maStartOffset
.X();
3621 aPoint
.Y
= aMatrixTranslate
.Y
- pNRObjData
->maStartOffset
.Y();
3624 ExportShape(rShape
.xShape
, &aPoint
);
3626 // Restore object geometry
3627 if (bNeedsRestore
&& pObj
&& pGeoData
)
3628 pObj
->SetGeoData(*pGeoData
);
3633 void ScXMLExport::WriteTableShapes()
3635 ScMyTableShapes
* pTableShapes(pSharedData
->GetTableShapes());
3636 if (!pTableShapes
|| (*pTableShapes
)[nCurrentTable
].empty())
3639 OSL_ENSURE(pTableShapes
->size() > static_cast<size_t>(nCurrentTable
), "wrong Table");
3640 SvXMLElementExport
aShapesElem(*this, XML_NAMESPACE_TABLE
, XML_SHAPES
, true, false);
3641 for (const auto& rxShape
: (*pTableShapes
)[nCurrentTable
])
3645 if (pDoc
->IsNegativePage(static_cast<SCTAB
>(nCurrentTable
)))
3647 // RTL-mirroring refers to snap rectangle, not to logic rectangle, therefore cannot use
3648 // getPosition() and getSize(), but need property "FrameRect" from rxShape or
3649 // GetSnapRect() from associated SdrObject.
3650 uno::Reference
<beans::XPropertySet
> xShapeProp(rxShape
, uno::UNO_QUERY
);
3651 awt::Rectangle aFrameRect
;
3652 if (xShapeProp
.is() && (xShapeProp
->getPropertyValue("FrameRect") >>= aFrameRect
))
3654 // file format uses shape in LTR mode. newLeft = - oldRight = - (oldLeft + width).
3655 // newTranslate = oldTranslate - refPoint, oldTranslate from transformation matrix,
3656 // calculated in XMLShapeExport::exportShape common for all modules.
3657 // oldTranslate.X = oldLeft ==> refPoint.X = 2 * oldLeft + width
3658 awt::Point aRefPoint
;
3659 aRefPoint
.X
= 2 * aFrameRect
.X
+ aFrameRect
.Width
- 1;
3661 ExportShape(rxShape
, &aRefPoint
);
3663 // else should not happen
3666 ExportShape(rxShape
, nullptr);
3669 (*pTableShapes
)[nCurrentTable
].clear();
3672 void ScXMLExport::WriteAreaLink( const ScMyCell
& rMyCell
)
3674 if( !rMyCell
.bHasAreaLink
)
3677 const ScMyAreaLink
& rAreaLink
= rMyCell
.aAreaLink
;
3678 AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, rAreaLink
.sSourceStr
);
3679 AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3680 AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(rAreaLink
.sURL
) );
3681 AddAttribute( XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, rAreaLink
.sFilter
);
3682 if( !rAreaLink
.sFilterOptions
.isEmpty() )
3683 AddAttribute( XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, rAreaLink
.sFilterOptions
);
3684 AddAttribute( XML_NAMESPACE_TABLE
, XML_LAST_COLUMN_SPANNED
, OUString::number(rAreaLink
.GetColCount()) );
3685 AddAttribute( XML_NAMESPACE_TABLE
, XML_LAST_ROW_SPANNED
, OUString::number(rAreaLink
.GetRowCount()) );
3686 if( rAreaLink
.nRefresh
)
3688 OUStringBuffer sValue
;
3689 ::sax::Converter::convertDuration( sValue
,
3690 static_cast<double>(rAreaLink
.nRefresh
) / 86400 );
3691 AddAttribute( XML_NAMESPACE_TABLE
, XML_REFRESH_DELAY
, sValue
.makeStringAndClear() );
3693 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_CELL_RANGE_SOURCE
, true, true );
3696 void ScXMLExport::exportAnnotationMeta( const uno::Reference
< drawing::XShape
>& xShape
)
3698 ScPostIt
* pNote
= pCurrentCell
->pNote
;
3704 //is it still useful, as this call back is only called from ScXMLExport::WriteAnnotation
3705 // and should be in sync with pCurrentCell
3706 SdrCaptionObj
* pNoteCaption
= pNote
->GetOrCreateCaption(pCurrentCell
->maCellAddress
);
3707 uno::Reference
<drawing::XShape
> xCurrentShape( pNoteCaption
->getUnoShape(), uno::UNO_QUERY
);
3708 if (xCurrentShape
.get()!=xShape
.get())
3711 const OUString
& sAuthor(pNote
->GetAuthor());
3712 if (!sAuthor
.isEmpty())
3714 SvXMLElementExport
aCreatorElem( *this, XML_NAMESPACE_DC
,
3717 Characters(sAuthor
);
3720 const OUString
& aDate(pNote
->GetDate());
3723 SvNumberFormatter
* pNumForm
= pDoc
->GetFormatTable();
3725 sal_uInt32 nfIndex
= pNumForm
->GetFormatIndex(NF_DATE_SYS_DDMMYYYY
, LANGUAGE_SYSTEM
);
3726 if (pNumForm
->IsNumberFormat(aDate
, nfIndex
, fDate
))
3728 OUStringBuffer sBuf
;
3729 GetMM100UnitConverter().convertDateTime(sBuf
, fDate
,true);
3730 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_DC
,
3733 Characters(sBuf
.makeStringAndClear());
3737 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_META
,
3738 XML_DATE_STRING
, true,
3745 SvXMLElementExport
aDateElem( *this, XML_NAMESPACE_META
,
3746 XML_DATE_STRING
, true,
3752 void ScXMLExport::WriteAnnotation(ScMyCell
& rMyCell
)
3754 ScPostIt
* pNote
= pDoc
->GetNote(rMyCell
.maCellAddress
);
3758 if (pNote
->IsCaptionShown())
3759 AddAttribute(XML_NAMESPACE_OFFICE
, XML_DISPLAY
, XML_TRUE
);
3761 pCurrentCell
= &rMyCell
;
3763 SdrCaptionObj
* pNoteCaption
= pNote
->GetOrCreateCaption(rMyCell
.maCellAddress
);
3766 uno::Reference
<drawing::XShape
> xShape( pNoteCaption
->getUnoShape(), uno::UNO_QUERY
);
3768 GetShapeExport()->exportShape(xShape
, SEF_DEFAULT
|XMLShapeExportFlags::ANNOTATION
);
3771 pCurrentCell
= nullptr;
3774 void ScXMLExport::WriteDetective( const ScMyCell
& rMyCell
)
3776 if( !(rMyCell
.bHasDetectiveObj
|| rMyCell
.bHasDetectiveOp
) )
3779 const ScMyDetectiveObjVec
& rObjVec
= rMyCell
.aDetectiveObjVec
;
3780 const ScMyDetectiveOpVec
& rOpVec
= rMyCell
.aDetectiveOpVec
;
3781 sal_Int32
nObjCount(rObjVec
.size());
3782 sal_Int32
nOpCount(rOpVec
.size());
3783 if( !(nObjCount
|| nOpCount
) )
3786 SvXMLElementExport
aDetElem( *this, XML_NAMESPACE_TABLE
, XML_DETECTIVE
, true, true );
3788 for(const auto& rObj
: rObjVec
)
3790 if (rObj
.eObjType
!= SC_DETOBJ_CIRCLE
)
3792 if( (rObj
.eObjType
== SC_DETOBJ_ARROW
) || (rObj
.eObjType
== SC_DETOBJ_TOOTHERTAB
))
3794 ScRangeStringConverter::GetStringFromRange( sString
, rObj
.aSourceRange
, pDoc
, FormulaGrammar::CONV_OOO
);
3795 AddAttribute( XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, sString
);
3797 ScXMLConverter::GetStringFromDetObjType( sString
, rObj
.eObjType
);
3798 AddAttribute( XML_NAMESPACE_TABLE
, XML_DIRECTION
, sString
);
3799 if( rObj
.bHasError
)
3800 AddAttribute( XML_NAMESPACE_TABLE
, XML_CONTAINS_ERROR
, XML_TRUE
);
3803 AddAttribute( XML_NAMESPACE_TABLE
, XML_MARKED_INVALID
, XML_TRUE
);
3804 SvXMLElementExport
aRangeElem( *this, XML_NAMESPACE_TABLE
, XML_HIGHLIGHTED_RANGE
, true, true );
3806 for(const auto& rOp
: rOpVec
)
3809 ScXMLConverter::GetStringFromDetOpType( sOpString
, rOp
.eOpType
);
3810 AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, sOpString
);
3811 AddAttribute( XML_NAMESPACE_TABLE
, XML_INDEX
, OUString::number(rOp
.nIndex
) );
3812 SvXMLElementExport
aRangeElem( *this, XML_NAMESPACE_TABLE
, XML_OPERATION
, true, true );
3816 void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount
, bool bIncProgress
)
3818 // nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1
3819 if (nEqualCellCount
> 0)
3821 sal_Int32
nTemp(nEqualCellCount
+ 1);
3822 OUString
sOUEqualCellCount(OUString::number(nTemp
));
3823 AddAttribute(sAttrColumnsRepeated
, sOUEqualCellCount
);
3825 IncrementProgressBar(false, nEqualCellCount
);
3829 bool ScXMLExport::IsEditCell(const ScMyCell
& rCell
)
3831 return rCell
.maBaseCell
.meType
== CELLTYPE_EDIT
;
3834 bool ScXMLExport::IsCellEqual (const ScMyCell
& aCell1
, const ScMyCell
& aCell2
)
3836 bool bIsEqual
= false;
3837 if( !aCell1
.bIsMergedBase
&& !aCell2
.bIsMergedBase
&&
3838 aCell1
.bIsCovered
== aCell2
.bIsCovered
&&
3839 !aCell1
.bIsMatrixBase
&& !aCell2
.bIsMatrixBase
&&
3840 aCell1
.bIsMatrixCovered
== aCell2
.bIsMatrixCovered
&&
3841 aCell1
.bHasAnnotation
== aCell2
.bHasAnnotation
&&
3842 !aCell1
.bHasShape
&& !aCell2
.bHasShape
&&
3843 aCell1
.bHasAreaLink
== aCell2
.bHasAreaLink
&&
3844 !aCell1
.bHasDetectiveObj
&& !aCell2
.bHasDetectiveObj
)
3846 if( (aCell1
.bHasAreaLink
&&
3847 (aCell1
.aAreaLink
.GetColCount() == 1) &&
3848 (aCell2
.aAreaLink
.GetColCount() == 1) &&
3849 aCell1
.aAreaLink
.Compare( aCell2
.aAreaLink
) ) ||
3850 !aCell1
.bHasAreaLink
)
3852 if (!aCell1
.bHasAnnotation
)
3854 if ((((aCell1
.nStyleIndex
== aCell2
.nStyleIndex
) && (aCell1
.bIsAutoStyle
== aCell2
.bIsAutoStyle
)) ||
3855 ((aCell1
.nStyleIndex
== aCell2
.nStyleIndex
) && (aCell1
.nStyleIndex
== -1))) &&
3856 aCell1
.nValidationIndex
== aCell2
.nValidationIndex
&&
3857 aCell1
.nType
== aCell2
.nType
)
3859 switch ( aCell1
.nType
)
3861 case table::CellContentType_EMPTY
:
3866 case table::CellContentType_VALUE
:
3868 // #i29101# number format may be different from column default styles,
3869 // but can lead to different value types, so it must also be compared
3870 bIsEqual
= (aCell1
.nNumberFormat
== aCell2
.nNumberFormat
) &&
3871 (aCell1
.maBaseCell
.mfValue
== aCell2
.maBaseCell
.mfValue
);
3874 case table::CellContentType_TEXT
:
3876 if (IsEditCell(aCell1
) || IsEditCell(aCell2
))
3880 bIsEqual
= (aCell1
.maBaseCell
.getString(pDoc
) == aCell2
.maBaseCell
.getString(pDoc
));
3884 case table::CellContentType_FORMULA
:
3902 void ScXMLExport::WriteCalculationSettings(const uno::Reference
<sheet::XSpreadsheetDocument
>& xSpreadDoc
)
3904 uno::Reference
<beans::XPropertySet
> xPropertySet(xSpreadDoc
, uno::UNO_QUERY
);
3905 if (!xPropertySet
.is())
3908 bool bCalcAsShown (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_CALCASSHOWN
) ));
3909 bool bIgnoreCase (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_IGNORECASE
) ));
3910 bool bLookUpLabels (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_LOOKUPLABELS
) ));
3911 bool bMatchWholeCell (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_MATCHWHOLE
) ));
3912 bool bUseRegularExpressions (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_REGEXENABLED
) ));
3913 bool bUseWildcards (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_WILDCARDSENABLED
) ));
3914 if (bUseWildcards
&& bUseRegularExpressions
)
3915 bUseRegularExpressions
= false; // mutually exclusive, wildcards take precedence
3916 bool bIsIterationEnabled (::cppu::any2bool( xPropertySet
->getPropertyValue(SC_UNO_ITERENABLED
) ));
3917 sal_uInt16
nYear2000 (pDoc
? pDoc
->GetDocOptions().GetYear2000() : 0);
3918 sal_Int32
nIterationCount(100);
3919 xPropertySet
->getPropertyValue( SC_UNO_ITERCOUNT
) >>= nIterationCount
;
3920 double fIterationEpsilon
= 0;
3921 xPropertySet
->getPropertyValue( SC_UNO_ITEREPSILON
) >>= fIterationEpsilon
;
3922 util::Date aNullDate
;
3923 xPropertySet
->getPropertyValue( SC_UNO_NULLDATE
) >>= aNullDate
;
3924 if (!(bCalcAsShown
|| bIgnoreCase
|| !bLookUpLabels
|| !bMatchWholeCell
|| !bUseRegularExpressions
||
3926 bIsIterationEnabled
|| nIterationCount
!= 100 || !::rtl::math::approxEqual(fIterationEpsilon
, 0.001) ||
3927 aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899 || nYear2000
!= 1930))
3931 AddAttribute(XML_NAMESPACE_TABLE
, XML_CASE_SENSITIVE
, XML_FALSE
);
3933 AddAttribute(XML_NAMESPACE_TABLE
, XML_PRECISION_AS_SHOWN
, XML_TRUE
);
3934 if (!bMatchWholeCell
)
3935 AddAttribute(XML_NAMESPACE_TABLE
, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL
, XML_FALSE
);
3937 AddAttribute(XML_NAMESPACE_TABLE
, XML_AUTOMATIC_FIND_LABELS
, XML_FALSE
);
3938 if (!bUseRegularExpressions
)
3939 AddAttribute(XML_NAMESPACE_TABLE
, XML_USE_REGULAR_EXPRESSIONS
, XML_FALSE
);
3941 AddAttribute(XML_NAMESPACE_TABLE
, XML_USE_WILDCARDS
, XML_TRUE
);
3942 if (nYear2000
!= 1930)
3944 AddAttribute(XML_NAMESPACE_TABLE
, XML_NULL_YEAR
, OUString::number(nYear2000
));
3946 SvXMLElementExport
aCalcSettings(*this, XML_NAMESPACE_TABLE
, XML_CALCULATION_SETTINGS
, true, true);
3948 if (aNullDate
.Day
!= 30 || aNullDate
.Month
!= 12 || aNullDate
.Year
!= 1899)
3950 OUStringBuffer sDate
;
3951 SvXMLUnitConverter::convertDateTime(sDate
, 0.0, aNullDate
);
3952 AddAttribute(XML_NAMESPACE_TABLE
, XML_DATE_VALUE
, sDate
.makeStringAndClear());
3953 SvXMLElementExport
aElemNullDate(*this, XML_NAMESPACE_TABLE
, XML_NULL_DATE
, true, true);
3955 if (bIsIterationEnabled
|| nIterationCount
!= 100 || !::rtl::math::approxEqual(fIterationEpsilon
, 0.001))
3957 if (bIsIterationEnabled
)
3958 AddAttribute(XML_NAMESPACE_TABLE
, XML_STATUS
, XML_ENABLE
);
3959 if (nIterationCount
!= 100)
3961 AddAttribute(XML_NAMESPACE_TABLE
, XML_STEPS
, OUString::number(nIterationCount
));
3963 if (!::rtl::math::approxEqual(fIterationEpsilon
, 0.001))
3965 OUStringBuffer sBuffer
;
3966 ::sax::Converter::convertDouble(sBuffer
,
3968 AddAttribute(XML_NAMESPACE_TABLE
, XML_MAXIMUM_DIFFERENCE
, sBuffer
.makeStringAndClear());
3970 SvXMLElementExport
aElemIteration(*this, XML_NAMESPACE_TABLE
, XML_ITERATION
, true, true);
3975 void ScXMLExport::WriteTableSource()
3977 uno::Reference
<sheet::XSheetLinkable
> xLinkable (xCurrentTable
, uno::UNO_QUERY
);
3978 if (!(xLinkable
.is() && GetModel().is()))
3981 sheet::SheetLinkMode
nMode (xLinkable
->getLinkMode());
3982 if (nMode
== sheet::SheetLinkMode_NONE
)
3985 OUString
sLink (xLinkable
->getLinkUrl());
3986 uno::Reference
<beans::XPropertySet
> xProps (GetModel(), uno::UNO_QUERY
);
3990 uno::Reference
<container::XIndexAccess
> xIndex(xProps
->getPropertyValue(SC_UNO_SHEETLINKS
), uno::UNO_QUERY
);
3994 sal_Int32
nCount(xIndex
->getCount());
3999 uno::Reference
<beans::XPropertySet
> xLinkProps
;
4000 for (sal_Int32 i
= 0; (i
< nCount
) && !bFound
; ++i
)
4002 xLinkProps
.set(xIndex
->getByIndex(i
), uno::UNO_QUERY
);
4003 if (xLinkProps
.is())
4006 if (xLinkProps
->getPropertyValue(SC_UNONAME_LINKURL
) >>= sNewLink
)
4007 bFound
= sLink
== sNewLink
;
4010 if (!(bFound
&& xLinkProps
.is()))
4014 OUString sFilterOptions
;
4015 OUString
sTableName (xLinkable
->getLinkSheetName());
4016 sal_Int32
nRefresh(0);
4017 xLinkProps
->getPropertyValue(SC_UNONAME_FILTER
) >>= sFilter
;
4018 xLinkProps
->getPropertyValue(SC_UNONAME_FILTOPT
) >>= sFilterOptions
;
4019 xLinkProps
->getPropertyValue(SC_UNONAME_REFDELAY
) >>= nRefresh
;
4020 if (sLink
.isEmpty())
4023 AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
4024 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(sLink
));
4025 if (!sTableName
.isEmpty())
4026 AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_NAME
, sTableName
);
4027 if (!sFilter
.isEmpty())
4028 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, sFilter
);
4029 if (!sFilterOptions
.isEmpty())
4030 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, sFilterOptions
);
4031 if (nMode
!= sheet::SheetLinkMode_NORMAL
)
4032 AddAttribute(XML_NAMESPACE_TABLE
, XML_MODE
, XML_COPY_RESULTS_ONLY
);
4035 OUStringBuffer sBuffer
;
4036 ::sax::Converter::convertDuration( sBuffer
,
4037 static_cast<double>(nRefresh
) / 86400 );
4038 AddAttribute( XML_NAMESPACE_TABLE
, XML_REFRESH_DELAY
, sBuffer
.makeStringAndClear() );
4040 SvXMLElementExport
aSourceElem(*this, XML_NAMESPACE_TABLE
, XML_TABLE_SOURCE
, true, true);
4043 // core implementation
4044 void ScXMLExport::WriteScenario()
4046 if (!(pDoc
&& pDoc
->IsScenario(static_cast<SCTAB
>(nCurrentTable
))))
4051 ScScenarioFlags nFlags
;
4052 pDoc
->GetScenarioData(static_cast<SCTAB
>(nCurrentTable
), sComment
, aColor
, nFlags
);
4053 if (!(nFlags
& ScScenarioFlags::ShowFrame
))
4054 AddAttribute(XML_NAMESPACE_TABLE
, XML_DISPLAY_BORDER
, XML_FALSE
);
4055 OUStringBuffer aBuffer
;
4056 ::sax::Converter::convertColor(aBuffer
, aColor
);
4057 AddAttribute(XML_NAMESPACE_TABLE
, XML_BORDER_COLOR
, aBuffer
.makeStringAndClear());
4058 if (!(nFlags
& ScScenarioFlags::TwoWay
))
4059 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_BACK
, XML_FALSE
);
4060 if (!(nFlags
& ScScenarioFlags::Attrib
))
4061 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_STYLES
, XML_FALSE
);
4062 if (nFlags
& ScScenarioFlags::Value
)
4063 AddAttribute(XML_NAMESPACE_TABLE
, XML_COPY_FORMULAS
, XML_FALSE
);
4064 if (nFlags
& ScScenarioFlags::Protected
)
4065 AddAttribute(XML_NAMESPACE_TABLE
, XML_PROTECTED
, XML_TRUE
);
4066 ::sax::Converter::convertBool(aBuffer
,
4067 pDoc
->IsActiveScenario(static_cast<SCTAB
>(nCurrentTable
)));
4068 AddAttribute(XML_NAMESPACE_TABLE
, XML_IS_ACTIVE
, aBuffer
.makeStringAndClear());
4069 const ScRangeList
* pRangeList
= pDoc
->GetScenarioRanges(static_cast<SCTAB
>(nCurrentTable
));
4070 OUString sRangeListStr
;
4071 ScRangeStringConverter::GetStringFromRangeList( sRangeListStr
, pRangeList
, pDoc
, FormulaGrammar::CONV_OOO
);
4072 AddAttribute(XML_NAMESPACE_TABLE
, XML_SCENARIO_RANGES
, sRangeListStr
);
4073 if (!sComment
.isEmpty())
4074 AddAttribute(XML_NAMESPACE_TABLE
, XML_COMMENT
, sComment
);
4075 SvXMLElementExport
aElem(*this, XML_NAMESPACE_TABLE
, XML_SCENARIO
, true, true);
4078 void ScXMLExport::WriteTheLabelRanges( const uno::Reference
< sheet::XSpreadsheetDocument
>& xSpreadDoc
)
4080 uno::Reference
< beans::XPropertySet
> xDocProp( xSpreadDoc
, uno::UNO_QUERY
);
4081 if( !xDocProp
.is() ) return;
4083 sal_Int32
nCount(0);
4084 uno::Reference
< container::XIndexAccess
> xColRangesIAccess(xDocProp
->getPropertyValue( SC_UNO_COLLABELRNG
), uno::UNO_QUERY
);
4085 if( xColRangesIAccess
.is() )
4086 nCount
+= xColRangesIAccess
->getCount();
4088 uno::Reference
< container::XIndexAccess
> xRowRangesIAccess(xDocProp
->getPropertyValue( SC_UNO_ROWLABELRNG
), uno::UNO_QUERY
);
4089 if( xRowRangesIAccess
.is() )
4090 nCount
+= xRowRangesIAccess
->getCount();
4094 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_LABEL_RANGES
, true, true );
4095 WriteLabelRanges( xColRangesIAccess
, true );
4096 WriteLabelRanges( xRowRangesIAccess
, false );
4100 void ScXMLExport::WriteLabelRanges( const uno::Reference
< container::XIndexAccess
>& xRangesIAccess
, bool bColumn
)
4102 if( !xRangesIAccess
.is() ) return;
4104 sal_Int32
nCount(xRangesIAccess
->getCount());
4105 for( sal_Int32 nIndex
= 0; nIndex
< nCount
; ++nIndex
)
4107 uno::Reference
< sheet::XLabelRange
> xRange(xRangesIAccess
->getByIndex( nIndex
), uno::UNO_QUERY
);
4111 table::CellRangeAddress
aCellRange( xRange
->getLabelArea() );
4112 ScRangeStringConverter::GetStringFromRange( sRangeStr
, aCellRange
, pDoc
, FormulaGrammar::CONV_OOO
);
4113 AddAttribute( XML_NAMESPACE_TABLE
, XML_LABEL_CELL_RANGE_ADDRESS
, sRangeStr
);
4114 aCellRange
= xRange
->getDataArea();
4115 ScRangeStringConverter::GetStringFromRange( sRangeStr
, aCellRange
, pDoc
, FormulaGrammar::CONV_OOO
);
4116 AddAttribute( XML_NAMESPACE_TABLE
, XML_DATA_CELL_RANGE_ADDRESS
, sRangeStr
);
4117 AddAttribute( XML_NAMESPACE_TABLE
, XML_ORIENTATION
, bColumn
? XML_COLUMN
: XML_ROW
);
4118 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_LABEL_RANGE
, true, true );
4123 void ScXMLExport::WriteNamedExpressions()
4127 ScRangeName
* pNamedRanges
= pDoc
->GetRangeName();
4128 WriteNamedRange(pNamedRanges
);
4131 void ScXMLExport::WriteExternalDataMapping()
4136 if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
4137 // Export this only for 1.2 extended and above.
4140 sc::ExternalDataMapper
& rDataMapper
= pDoc
->GetExternalDataMapper();
4141 auto& rDataSources
= rDataMapper
.getDataSources();
4143 if (rDataSources
.empty())
4146 SvXMLElementExport
aMappings(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_MAPPINGS
, true, true);
4147 for (const auto& itr
: rDataSources
)
4149 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, itr
.getURL());
4150 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_PROVIDER
, itr
.getProvider());
4151 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_DATA_FREQUENCY
, OUString::number(sc::ExternalDataSource::getUpdateFrequency()));
4152 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_ID
, itr
.getID());
4153 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_DATABASE_NAME
, itr
.getDBName());
4155 SvXMLElementExport
aMapping(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_MAPPING
, true, true);
4156 // Add the data transformations
4157 WriteExternalDataTransformations(itr
.getDataTransformation());
4161 void ScXMLExport::WriteExternalDataTransformations(const std::vector
<std::shared_ptr
<sc::DataTransformation
>>& aDataTransformations
)
4163 SvXMLElementExport
aTransformations(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_TRANSFORMATIONS
, true, true);
4164 for (auto& itr
: aDataTransformations
)
4166 sc::TransformationType aTransformationType
= itr
->getTransformationType();
4168 switch(aTransformationType
)
4170 case sc::TransformationType::DELETE_TRANSFORMATION
:
4172 // Delete Columns Transformation
4173 std::shared_ptr
<sc::ColumnRemoveTransformation
> aDeleteTransformation
= std::dynamic_pointer_cast
<sc::ColumnRemoveTransformation
>(itr
);
4174 std::set
<SCCOL
> aColumns
= aDeleteTransformation
->getColumns();
4175 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_REMOVE_TRANSFORMATION
, true, true);
4176 for(auto& col
: aColumns
)
4179 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4180 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4184 case sc::TransformationType::SPLIT_TRANSFORMATION
:
4186 std::shared_ptr
<sc::SplitColumnTransformation
> aSplitTransformation
= std::dynamic_pointer_cast
<sc::SplitColumnTransformation
>(itr
);
4188 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(aSplitTransformation
->getColumn()));
4189 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SEPARATOR
, OUString::number(aSplitTransformation
->getSeparator()));
4190 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_SPLIT_TRANSFORMATION
, true, true);
4193 case sc::TransformationType::MERGE_TRANSFORMATION
:
4195 // Merge Transformation
4196 std::shared_ptr
<sc::MergeColumnTransformation
> aMergeTransformation
= std::dynamic_pointer_cast
<sc::MergeColumnTransformation
>(itr
);
4197 std::set
<SCCOL
> aColumns
= aMergeTransformation
->getColumns();
4199 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MERGE_STRING
, aMergeTransformation
->getMergeString());
4200 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_MERGE_TRANSFORMATION
, true, true);
4202 for(auto& col
: aColumns
)
4205 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4206 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4210 case sc::TransformationType::SORT_TRANSFORMATION
:
4212 // Sort Transformation
4213 std::shared_ptr
<sc::SortTransformation
> aSortTransformation
= std::dynamic_pointer_cast
<sc::SortTransformation
>(itr
);
4214 ScSortParam aSortParam
= aSortTransformation
->getSortParam();
4215 const sc::DocumentLinkManager
& rMgr
= pDoc
->GetDocLinkManager();
4216 const sc::DataStream
* pStrm
= rMgr
.getDataStream();
4222 ScRange aRange
= pStrm
->GetRange();
4224 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_SORT_TRANSFORMATION
, true, true);
4226 writeSort(*this, aSortParam
, aRange
, pDoc
);
4229 case sc::TransformationType::TEXT_TRANSFORMATION
:
4231 // Text Transformation
4232 std::shared_ptr
<sc::TextTransformation
> aTextTransformation
= std::dynamic_pointer_cast
<sc::TextTransformation
>(itr
);
4234 sc::TEXT_TRANSFORM_TYPE aTextTransformType
= aTextTransformation
->getTextTransformationType();
4236 switch ( aTextTransformType
)
4238 case sc::TEXT_TRANSFORM_TYPE::TO_LOWER
:
4239 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_LOWERCASE
);
4241 case sc::TEXT_TRANSFORM_TYPE::TO_UPPER
:
4242 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_UPPERCASE
);
4244 case sc::TEXT_TRANSFORM_TYPE::CAPITALIZE
:
4245 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CASEMAP_CAPITALIZE
);
4247 case sc::TEXT_TRANSFORM_TYPE::TRIM
:
4248 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_TRIM
);
4252 std::set
<SCCOL
> aColumns
= aTextTransformation
->getColumns();
4254 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_TEXT_TRANSFORMATION
, true, true);
4256 for(auto& col
: aColumns
)
4259 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4260 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4264 case sc::TransformationType::AGGREGATE_FUNCTION
:
4266 // Aggregate Transformation
4267 std::shared_ptr
<sc::AggregateFunction
> aAggregateFunction
= std::dynamic_pointer_cast
<sc::AggregateFunction
>(itr
);
4268 std::set
<SCCOL
> aColumns
= aAggregateFunction
->getColumns();
4270 sc::AGGREGATE_FUNCTION aAggregateType
= aAggregateFunction
->getAggregateType();
4272 switch (aAggregateType
)
4274 case sc::AGGREGATE_FUNCTION::SUM
:
4275 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SUM
);
4277 case sc::AGGREGATE_FUNCTION::AVERAGE
:
4278 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_AVERAGE
);
4280 case sc::AGGREGATE_FUNCTION::MIN
:
4281 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MIN
);
4283 case sc::AGGREGATE_FUNCTION::MAX
:
4284 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MAX
);
4288 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
,XML_COLUMN_AGGREGATE_TRANSFORMATION
, true, true);
4290 for(auto& col
: aColumns
)
4293 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4294 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4298 case sc::TransformationType::NUMBER_TRANSFORMATION
:
4300 // Number Transformation
4301 std::shared_ptr
<sc::NumberTransformation
> aNumberTransformation
= std::dynamic_pointer_cast
<sc::NumberTransformation
>(itr
);
4303 sc::NUMBER_TRANSFORM_TYPE aNumberTransformType
= aNumberTransformation
->getNumberTransformationType();
4305 switch ( aNumberTransformType
)
4307 case sc::NUMBER_TRANSFORM_TYPE::ROUND
:
4308 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND
);
4310 case sc::NUMBER_TRANSFORM_TYPE::ROUND_UP
:
4311 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND_UP
);
4313 case sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN
:
4314 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ROUND_DOWN
);
4316 case sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE
:
4317 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ABS
);
4319 case sc::NUMBER_TRANSFORM_TYPE::LOG_E
:
4320 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_LOG
);
4322 case sc::NUMBER_TRANSFORM_TYPE::LOG_10
:
4323 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_LOG_10
);
4325 case sc::NUMBER_TRANSFORM_TYPE::CUBE
:
4326 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_CUBE
);
4328 case sc::NUMBER_TRANSFORM_TYPE::SQUARE
:
4329 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SQUARE
);
4331 case sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT
:
4332 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SQUARE_ROOT
);
4334 case sc::NUMBER_TRANSFORM_TYPE::EXPONENT
:
4335 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_EXPONENTIAL
);
4337 case sc::NUMBER_TRANSFORM_TYPE::IS_EVEN
:
4338 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_EVEN
);
4340 case sc::NUMBER_TRANSFORM_TYPE::IS_ODD
:
4341 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_ODD
);
4343 case sc::NUMBER_TRANSFORM_TYPE::SIGN
:
4344 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SIGN
);
4348 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_PRECISION
, OUString::number(aNumberTransformation
->getPrecision()));
4349 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_NUMBER_TRANSFORMATION
, true, true);
4351 std::set
<SCCOL
> aColumns
= aNumberTransformation
->getColumn();
4352 for(auto& col
: aColumns
)
4355 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4356 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4360 case sc::TransformationType::REMOVE_NULL_TRANSFORMATION
:
4362 // Replace Null Transformation
4363 std::shared_ptr
<sc::ReplaceNullTransformation
> aReplaceNullTransformation
= std::dynamic_pointer_cast
<sc::ReplaceNullTransformation
>(itr
);
4364 std::set
<SCCOL
> aColumns
= aReplaceNullTransformation
->getColumn();
4366 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_REPLACE_STRING
, aReplaceNullTransformation
->getReplaceString());
4367 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_REPLACENULL_TRANSFORMATION
, true, true);
4369 for(auto& col
: aColumns
)
4372 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4373 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4377 case sc::TransformationType::DATETIME_TRANSFORMATION
:
4379 // Number Transformation
4380 std::shared_ptr
<sc::DateTimeTransformation
> aDateTimeTransformation
= std::dynamic_pointer_cast
<sc::DateTimeTransformation
>(itr
);
4382 sc::DATETIME_TRANSFORMATION_TYPE aDateTimeTransformationType
= aDateTimeTransformation
->getDateTimeTransformationType();
4384 switch ( aDateTimeTransformationType
)
4386 case sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING
:
4387 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DATE_STRING
);
4389 case sc::DATETIME_TRANSFORMATION_TYPE::YEAR
:
4390 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_YEAR
);
4392 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR
:
4393 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_YEAR
);
4395 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR
:
4396 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_YEAR
);
4398 case sc::DATETIME_TRANSFORMATION_TYPE::MONTH
:
4399 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MONTH
);
4401 case sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME
:
4402 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MONTH_NAME
);
4404 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH
:
4405 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_MONTH
);
4407 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH
:
4408 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_MONTH
);
4410 case sc::DATETIME_TRANSFORMATION_TYPE::DAY
:
4411 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY
);
4413 case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK
:
4414 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY_OF_WEEK
);
4416 case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR
:
4417 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_DAY_OF_YEAR
);
4419 case sc::DATETIME_TRANSFORMATION_TYPE::QUARTER
:
4420 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_QUARTER
);
4422 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER
:
4423 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_START_OF_QUARTER
);
4425 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER
:
4426 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_END_OF_QUARTER
);
4428 case sc::DATETIME_TRANSFORMATION_TYPE::TIME
:
4429 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_TIME
);
4431 case sc::DATETIME_TRANSFORMATION_TYPE::HOUR
:
4432 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_HOUR
);
4434 case sc::DATETIME_TRANSFORMATION_TYPE::MINUTE
:
4435 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_MINUTE
);
4437 case sc::DATETIME_TRANSFORMATION_TYPE::SECOND
:
4438 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, XML_SECONDS
);
4442 SvXMLElementExport
aTransformation(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN_DATETIME_TRANSFORMATION
, true, true);
4444 std::set
<SCCOL
> aColumns
= aDateTimeTransformation
->getColumn();
4445 for(auto& col
: aColumns
)
4448 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, OUString::number(col
));
4449 SvXMLElementExport
aCol(*this, XML_NAMESPACE_CALC_EXT
, XML_COLUMN
, true, true);
4459 void ScXMLExport::WriteDataStream()
4464 if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
4465 // Export this only in experimental mode.
4468 if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
4469 // Export this only for 1.2 extended and above.
4472 const sc::DocumentLinkManager
& rMgr
= pDoc
->GetDocLinkManager();
4473 const sc::DataStream
* pStrm
= rMgr
.getDataStream();
4479 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetRelativeReference(pStrm
->GetURL()));
4482 ScRange aRange
= pStrm
->GetRange();
4484 ScRangeStringConverter::GetStringFromRange(
4485 aRangeStr
, aRange
, pDoc
, formula::FormulaGrammar::CONV_OOO
);
4486 AddAttribute(XML_NAMESPACE_TABLE
, XML_TARGET_RANGE_ADDRESS
, aRangeStr
);
4488 // Empty line refresh option.
4489 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_EMPTY_LINE_REFRESH
, pStrm
->IsRefreshOnEmptyLine() ? XML_TRUE
: XML_FALSE
);
4491 // New data insertion position. Either top of bottom. Default to bottom.
4492 xmloff::token::XMLTokenEnum eInsertPosition
= XML_BOTTOM
;
4493 if (pStrm
->GetMove() == sc::DataStream::MOVE_DOWN
)
4494 eInsertPosition
= XML_TOP
;
4496 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_INSERTION_POSITION
, eInsertPosition
);
4498 SvXMLElementExport
aElem(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_STREAM_SOURCE
, true, true);
4501 void ScXMLExport::WriteNamedRange(ScRangeName
* pRangeName
)
4503 //write a global or local ScRangeName
4504 SvXMLElementExport
aElemNEs(*this, XML_NAMESPACE_TABLE
, XML_NAMED_EXPRESSIONS
, true, true);
4505 for (const auto& rxEntry
: *pRangeName
)
4507 AddAttribute(sAttrName
, rxEntry
.second
->GetName());
4509 OUString sBaseCellAddress
;
4510 rxEntry
.second
->ValidateTabRefs();
4511 ScRangeStringConverter::GetStringFromAddress( sBaseCellAddress
, rxEntry
.second
->GetPos(), pDoc
,
4512 FormulaGrammar::CONV_OOO
, ' ', false, ScRefFlags::ADDR_ABS_3D
);
4513 AddAttribute(XML_NAMESPACE_TABLE
, XML_BASE_CELL_ADDRESS
, sBaseCellAddress
);
4516 rxEntry
.second
->GetSymbol(sSymbol
, pDoc
->GetStorageGrammar());
4517 OUString
sTempSymbol(sSymbol
);
4519 if (rxEntry
.second
->IsReference(aRange
))
4522 OUString
sContent(sTempSymbol
.copy(1, sTempSymbol
.getLength() -2 ));
4523 AddAttribute(XML_NAMESPACE_TABLE
, XML_CELL_RANGE_ADDRESS
, sContent
);
4525 sal_Int32 nRangeType
= rxEntry
.second
->GetUnoType();
4526 OUStringBuffer sBufferRangeType
;
4527 if ((nRangeType
& sheet::NamedRangeFlag::COLUMN_HEADER
) == sheet::NamedRangeFlag::COLUMN_HEADER
)
4528 sBufferRangeType
.append(GetXMLToken(XML_REPEAT_COLUMN
));
4529 if ((nRangeType
& sheet::NamedRangeFlag::ROW_HEADER
) == sheet::NamedRangeFlag::ROW_HEADER
)
4531 if (!sBufferRangeType
.isEmpty())
4532 sBufferRangeType
.append(" ");
4533 sBufferRangeType
.append(GetXMLToken(XML_REPEAT_ROW
));
4535 if ((nRangeType
& sheet::NamedRangeFlag::FILTER_CRITERIA
) == sheet::NamedRangeFlag::FILTER_CRITERIA
)
4537 if (!sBufferRangeType
.isEmpty())
4538 sBufferRangeType
.append(" ");
4539 sBufferRangeType
.append(GetXMLToken(XML_FILTER
));
4541 if ((nRangeType
& sheet::NamedRangeFlag::PRINT_AREA
) == sheet::NamedRangeFlag::PRINT_AREA
)
4543 if (!sBufferRangeType
.isEmpty())
4544 sBufferRangeType
.append(" ");
4545 sBufferRangeType
.append(GetXMLToken(XML_PRINT_RANGE
));
4547 OUString sRangeType
= sBufferRangeType
.makeStringAndClear();
4548 if (!sRangeType
.isEmpty())
4549 AddAttribute(XML_NAMESPACE_TABLE
, XML_RANGE_USABLE_AS
, sRangeType
);
4550 SvXMLElementExport
aElemNR(*this, XML_NAMESPACE_TABLE
, XML_NAMED_RANGE
, true, true);
4555 AddAttribute(XML_NAMESPACE_TABLE
, XML_EXPRESSION
, sTempSymbol
);
4556 SvXMLElementExport
aElemNE(*this, XML_NAMESPACE_TABLE
, XML_NAMED_EXPRESSION
, true, true);
4563 OUString
getCondFormatEntryType(const ScColorScaleEntry
& rEntry
, bool bFirst
= true)
4565 switch(rEntry
.GetType())
4567 case COLORSCALE_MIN
:
4569 case COLORSCALE_MAX
:
4571 case COLORSCALE_PERCENT
:
4573 case COLORSCALE_PERCENTILE
:
4574 return "percentile";
4575 case COLORSCALE_FORMULA
:
4577 case COLORSCALE_VALUE
:
4579 case COLORSCALE_AUTO
:
4580 // only important for data bars
4582 return "auto-minimum";
4584 return "auto-maximum";
4589 OUString
getDateStringForType(condformat::ScCondFormatDateType eType
)
4593 case condformat::TODAY
:
4595 case condformat::YESTERDAY
:
4597 case condformat::TOMORROW
:
4599 case condformat::LAST7DAYS
:
4600 return "last-7-days";
4601 case condformat::THISWEEK
:
4603 case condformat::LASTWEEK
:
4605 case condformat::NEXTWEEK
:
4607 case condformat::THISMONTH
:
4608 return "this-month";
4609 case condformat::LASTMONTH
:
4610 return "last-month";
4611 case condformat::NEXTMONTH
:
4612 return "next-month";
4613 case condformat::THISYEAR
:
4615 case condformat::LASTYEAR
:
4617 case condformat::NEXTYEAR
:
4626 void ScXMLExport::ExportConditionalFormat(SCTAB nTab
)
4628 ScConditionalFormatList
* pCondFormatList
= pDoc
->GetCondFormList(nTab
);
4629 if(!pCondFormatList
)
4632 if (pCondFormatList
->empty())
4635 SvXMLElementExport
aElementCondFormats(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITIONAL_FORMATS
, true, true);
4637 for(const auto& rxCondFormat
: *pCondFormatList
)
4640 const ScRangeList
& rRangeList
= rxCondFormat
->GetRange();
4641 ScRangeStringConverter::GetStringFromRangeList( sRanges
, &rRangeList
, pDoc
, formula::FormulaGrammar::CONV_OOO
);
4642 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TARGET_RANGE_ADDRESS
, sRanges
);
4643 SvXMLElementExport
aElementCondFormat(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITIONAL_FORMAT
, true, true);
4644 size_t nEntries
= rxCondFormat
->size();
4645 for(size_t i
= 0; i
< nEntries
; ++i
)
4647 const ScFormatEntry
* pFormatEntry
= rxCondFormat
->GetEntry(i
);
4648 if(pFormatEntry
->GetType()==ScFormatEntry::Type::Condition
)
4650 const ScCondFormatEntry
* pEntry
= static_cast<const ScCondFormatEntry
*>(pFormatEntry
);
4651 OUStringBuffer aCond
;
4652 ScAddress aPos
= pEntry
->GetSrcPos();
4653 switch(pEntry
->GetOperation())
4655 case ScConditionMode::Equal
:
4657 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4659 case ScConditionMode::Less
:
4661 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4663 case ScConditionMode::Greater
:
4665 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4667 case ScConditionMode::EqLess
:
4669 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4671 case ScConditionMode::EqGreater
:
4673 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4675 case ScConditionMode::NotEqual
:
4677 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4679 case ScConditionMode::Between
:
4680 aCond
.append("between(");
4681 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4683 aCond
.append(pEntry
->GetExpression(aPos
, 1, 0, formula::FormulaGrammar::GRAM_ODFF
));
4686 case ScConditionMode::NotBetween
:
4687 aCond
.append("not-between(");
4688 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4690 aCond
.append(pEntry
->GetExpression(aPos
, 1, 0, formula::FormulaGrammar::GRAM_ODFF
));
4693 case ScConditionMode::Duplicate
:
4694 aCond
.append("duplicate");
4696 case ScConditionMode::NotDuplicate
:
4697 aCond
.append("unique");
4699 case ScConditionMode::Direct
:
4700 aCond
.append("formula-is(");
4701 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4704 case ScConditionMode::Top10
:
4705 aCond
.append("top-elements(");
4706 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4709 case ScConditionMode::Bottom10
:
4710 aCond
.append("bottom-elements(");
4711 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4714 case ScConditionMode::TopPercent
:
4715 aCond
.append("top-percent(");
4716 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4719 case ScConditionMode::BottomPercent
:
4720 aCond
.append("bottom-percent(");
4721 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4724 case ScConditionMode::AboveAverage
:
4725 aCond
.append("above-average");
4727 case ScConditionMode::BelowAverage
:
4728 aCond
.append("below-average");
4730 case ScConditionMode::AboveEqualAverage
:
4731 aCond
.append("above-equal-average");
4733 case ScConditionMode::BelowEqualAverage
:
4734 aCond
.append("below-equal-average");
4736 case ScConditionMode::Error
:
4737 aCond
.append("is-error");
4739 case ScConditionMode::NoError
:
4740 aCond
.append("is-no-error");
4742 case ScConditionMode::BeginsWith
:
4743 aCond
.append("begins-with(");
4744 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4747 case ScConditionMode::EndsWith
:
4748 aCond
.append("ends-with(");
4749 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4752 case ScConditionMode::ContainsText
:
4753 aCond
.append("contains-text(");
4754 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4757 case ScConditionMode::NotContainsText
:
4758 aCond
.append("not-contains-text(");
4759 aCond
.append(pEntry
->GetExpression(aPos
, 0, 0, formula::FormulaGrammar::GRAM_ODFF
));
4762 case ScConditionMode::NONE
:
4765 SAL_WARN("sc", "unimplemented conditional format export");
4767 OUString sStyle
= ScStyleNameConversion::DisplayToProgrammaticName(pEntry
->GetStyle(), SfxStyleFamily::Para
);
4768 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_APPLY_STYLE_NAME
, sStyle
);
4769 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, aCond
.makeStringAndClear());
4771 OUString sBaseAddress
;
4772 ScRangeStringConverter::GetStringFromAddress( sBaseAddress
, aPos
, pDoc
,formula::FormulaGrammar::CONV_ODF
);
4773 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_BASE_CELL_ADDRESS
, sBaseAddress
);
4774 SvXMLElementExport
aElementCondEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_CONDITION
, true, true);
4776 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Colorscale
)
4778 SvXMLElementExport
aElementColorScale(*this, XML_NAMESPACE_CALC_EXT
, XML_COLOR_SCALE
, true, true);
4779 const ScColorScaleFormat
& rColorScale
= static_cast<const ScColorScaleFormat
&>(*pFormatEntry
);
4780 for(const auto& rxItem
: rColorScale
)
4782 if(rxItem
->GetType() == COLORSCALE_FORMULA
)
4784 OUString sFormula
= rxItem
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4785 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4788 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(rxItem
->GetValue()));
4790 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*rxItem
));
4791 OUStringBuffer aBuffer
;
4792 ::sax::Converter::convertColor(aBuffer
, rxItem
->GetColor());
4793 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_COLOR
, aBuffer
.makeStringAndClear());
4794 SvXMLElementExport
aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_COLOR_SCALE_ENTRY
, true, true);
4797 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Databar
)
4799 const ScDataBarFormatData
* pFormatData
= static_cast<const ScDataBarFormat
&>(*pFormatEntry
).GetDataBarData();
4800 if(!pFormatData
->mbGradient
)
4801 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_GRADIENT
, XML_FALSE
);
4802 if(pFormatData
->mbOnlyBar
)
4803 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SHOW_VALUE
, XML_FALSE
);
4805 if (pFormatData
->mnMinLength
!= 0.0)
4806 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MIN_LENGTH
, OUString::number(pFormatData
->mnMinLength
));
4808 if (pFormatData
->mnMaxLength
!= 0.0)
4809 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_MAX_LENGTH
, OUString::number(pFormatData
->mnMaxLength
));
4811 if(pFormatData
->mbNeg
)
4813 if(pFormatData
->mxNegativeColor
)
4815 OUStringBuffer aBuffer
;
4816 ::sax::Converter::convertColor(aBuffer
, *pFormatData
->mxNegativeColor
);
4817 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_NEGATIVE_COLOR
, aBuffer
.makeStringAndClear());
4821 OUStringBuffer aBuffer
;
4822 ::sax::Converter::convertColor(aBuffer
, COL_LIGHTRED
);
4823 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_NEGATIVE_COLOR
, aBuffer
.makeStringAndClear());
4827 if(pFormatData
->meAxisPosition
!= databar::AUTOMATIC
)
4829 if(pFormatData
->meAxisPosition
== databar::NONE
)
4831 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_POSITION
, OUString("none"));
4835 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_POSITION
, OUString("middle"));
4839 OUStringBuffer aBuffer
;
4840 ::sax::Converter::convertColor(aBuffer
, pFormatData
->maPositiveColor
);
4841 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_POSITIVE_COLOR
, aBuffer
.makeStringAndClear());
4844 ::sax::Converter::convertColor(aBuffer
, pFormatData
->maAxisColor
);
4845 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_AXIS_COLOR
, aBuffer
.makeStringAndClear());
4846 SvXMLElementExport
aElementDataBar(*this, XML_NAMESPACE_CALC_EXT
, XML_DATA_BAR
, true, true);
4849 if(pFormatData
->mpLowerLimit
->GetType() == COLORSCALE_FORMULA
)
4851 OUString sFormula
= pFormatData
->mpLowerLimit
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4852 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4855 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(pFormatData
->mpLowerLimit
->GetValue()));
4856 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*pFormatData
->mpLowerLimit
));
4857 SvXMLElementExport
aElementDataBarEntryLower(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4861 if(pFormatData
->mpUpperLimit
->GetType() == COLORSCALE_FORMULA
)
4863 OUString sFormula
= pFormatData
->mpUpperLimit
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4864 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4867 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(pFormatData
->mpUpperLimit
->GetValue()));
4868 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*pFormatData
->mpUpperLimit
, false));
4869 SvXMLElementExport
aElementDataBarEntryUpper(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4872 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Iconset
)
4874 const ScIconSetFormat
& rIconSet
= static_cast<const ScIconSetFormat
&>(*pFormatEntry
);
4875 OUString aIconSetName
= OUString::createFromAscii(ScIconSetFormat::getIconSetName(rIconSet
.GetIconSetData()->eIconSetType
));
4876 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_ICON_SET_TYPE
, aIconSetName
);
4877 if (rIconSet
.GetIconSetData()->mbCustom
)
4878 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM
, OUString::boolean(true));
4880 SvXMLElementExport
aElementColorScale(*this, XML_NAMESPACE_CALC_EXT
, XML_ICON_SET
, true, true);
4882 if (rIconSet
.GetIconSetData()->mbCustom
)
4884 for (const auto& [rType
, rIndex
] : rIconSet
.GetIconSetData()->maCustomVector
)
4886 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET_NAME
, OUString::createFromAscii(ScIconSetFormat::getIconSetName(rType
)));
4887 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET_INDEX
, OUString::number(rIndex
));
4888 SvXMLElementExport
aCustomIcon(*this, XML_NAMESPACE_CALC_EXT
, XML_CUSTOM_ICONSET
, true, true);
4893 if(!rIconSet
.GetIconSetData()->mbShowValue
)
4894 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_SHOW_VALUE
, XML_FALSE
);
4895 for (auto const& it
: rIconSet
)
4897 if(it
->GetType() == COLORSCALE_FORMULA
)
4899 OUString sFormula
= it
->GetFormula(formula::FormulaGrammar::GRAM_ODFF
);
4900 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, sFormula
);
4903 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_VALUE
, OUString::number(it
->GetValue()));
4905 AddAttribute(XML_NAMESPACE_CALC_EXT
, XML_TYPE
, getCondFormatEntryType(*it
));
4906 SvXMLElementExport
aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT
, XML_FORMATTING_ENTRY
, true, true);
4909 else if(pFormatEntry
->GetType() == ScFormatEntry::Type::Date
)
4911 const ScCondDateFormatEntry
& rDateFormat
= static_cast<const ScCondDateFormatEntry
&>(*pFormatEntry
);
4912 OUString aDateType
= getDateStringForType(rDateFormat
.GetDateType());
4913 OUString aStyleName
= ScStyleNameConversion::DisplayToProgrammaticName(rDateFormat
.GetStyleName(), SfxStyleFamily::Para
);
4914 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_STYLE
, aStyleName
);
4915 AddAttribute( XML_NAMESPACE_CALC_EXT
, XML_DATE
, aDateType
);
4916 SvXMLElementExport
aElementDateFormat(*this, XML_NAMESPACE_CALC_EXT
, XML_DATE_IS
, true, true);
4922 void ScXMLExport::WriteExternalRefCaches()
4927 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
4928 pRefMgr
->resetSrcFileData(GetOrigFileName());
4929 sal_uInt16 nCount
= pRefMgr
->getExternalFileCount();
4930 for (sal_uInt16 nFileId
= 0; nFileId
< nCount
; ++nFileId
)
4932 const OUString
* pUrl
= pRefMgr
->getExternalFileName(nFileId
);
4936 vector
<OUString
> aTabNames
;
4937 pRefMgr
->getAllCachedTableNames(nFileId
, aTabNames
);
4938 if (aTabNames
.empty())
4941 for (const auto& rTabName
: aTabNames
)
4943 ScExternalRefCache::TableTypeRef pTable
= pRefMgr
->getCacheTable(nFileId
, rTabName
, false);
4944 if (!pTable
|| !pTable
->isReferenced())
4947 AddAttribute(XML_NAMESPACE_TABLE
, XML_NAME
, "'" + *pUrl
+ "'#" + rTabName
);
4948 AddAttribute(XML_NAMESPACE_TABLE
, XML_PRINT
, GetXMLToken(XML_FALSE
));
4949 AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, sExternalRefTabStyleName
);
4950 SvXMLElementExport
aElemTable(*this, XML_NAMESPACE_TABLE
, XML_TABLE
, true, true);
4952 const ScExternalRefManager::SrcFileData
* pExtFileData
= pRefMgr
->getExternalFileData(nFileId
);
4956 if (!pExtFileData
->maRelativeName
.isEmpty())
4957 aRelUrl
= pExtFileData
->maRelativeName
;
4959 aRelUrl
= GetRelativeReference(pExtFileData
->maRelativeName
);
4960 AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
4961 AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, aRelUrl
);
4962 AddAttribute(XML_NAMESPACE_TABLE
, XML_TABLE_NAME
, rTabName
);
4963 if (!pExtFileData
->maFilterName
.isEmpty())
4964 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_NAME
, pExtFileData
->maFilterName
);
4965 if (!pExtFileData
->maFilterOptions
.isEmpty())
4966 AddAttribute(XML_NAMESPACE_TABLE
, XML_FILTER_OPTIONS
, pExtFileData
->maFilterOptions
);
4967 AddAttribute(XML_NAMESPACE_TABLE
, XML_MODE
, XML_COPY_RESULTS_ONLY
);
4969 SvXMLElementExport
aElemTableSource(*this, XML_NAMESPACE_TABLE
, XML_TABLE_SOURCE
, true, true);
4972 // Determine maximum column count of used area, for repeated cells.
4973 SCCOL nMaxColsUsed
= 1; // assume that there is at least one cell somewhere...
4974 vector
<SCROW
> aRows
;
4975 pTable
->getAllRows(aRows
);
4976 for (SCROW nRow
: aRows
)
4978 vector
<SCCOL
> aCols
;
4979 pTable
->getAllCols(nRow
, aCols
);
4982 SCCOL nCol
= aCols
.back();
4983 if (nMaxColsUsed
<= nCol
)
4984 nMaxColsUsed
= nCol
+ 1;
4988 // Column definitions have to be present to make a valid file
4990 if (nMaxColsUsed
> 1)
4991 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
4992 OUString::number(nMaxColsUsed
));
4993 SvXMLElementExport
aElemColumn(*this, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true);
4996 // Write cache content for this table.
4998 bool bFirstRow
= true;
4999 for (SCROW nRow
: aRows
)
5007 OUString aVal
= OUString::number(nRow
);
5008 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, aVal
);
5010 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5011 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nMaxColsUsed
));
5012 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5013 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5018 SCROW nRowGap
= nRow
- nLastRow
;
5023 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nRowGap
-1));
5024 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_REPEATED
, aVal
);
5026 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5027 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nMaxColsUsed
));
5028 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5029 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5032 SvXMLElementExport
aElemRow(*this, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true);
5034 vector
<SCCOL
> aCols
;
5035 pTable
->getAllCols(nRow
, aCols
);
5037 bool bFirstCol
= true;
5038 for (SCCOL nCol
: aCols
)
5046 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nCol
));
5047 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5049 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5054 SCCOL nColGap
= nCol
- nLastCol
;
5059 OUString aVal
= OUString::number(static_cast<sal_Int32
>(nColGap
-1));
5060 AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
, aVal
);
5062 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5066 // Write out this cell.
5067 sal_uInt32 nNumFmt
= 0;
5068 ScExternalRefCache::TokenRef pToken
= pTable
->getCell(nCol
, nRow
, &nNumFmt
);
5072 sal_Int32 nIndex
= GetNumberFormatStyleIndex(nNumFmt
);
5075 const OUString
& aStyleName
= pCellStyles
->GetStyleNameByIndex(nIndex
, true);
5076 AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, aStyleName
);
5079 switch(pToken
->GetType())
5083 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
5084 OUStringBuffer aVal
;
5085 aVal
.append(pToken
->GetDouble());
5086 aStrVal
= aVal
.makeStringAndClear();
5087 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE
, aStrVal
);
5092 AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
5093 aStrVal
= pToken
->GetString().getString();
5100 SvXMLElementExport
aElemCell(*this, XML_NAMESPACE_TABLE
, XML_TABLE_CELL
, true, true);
5101 SvXMLElementExport
aElemText(*this, XML_NAMESPACE_TEXT
, XML_P
, true, false);
5102 Characters(aStrVal
);
5114 // core implementation
5115 void ScXMLExport::WriteConsolidation()
5120 const ScConsolidateParam
* pCons(pDoc
->GetConsolidateDlgData());
5126 ScXMLConverter::GetStringFromFunction( sStrData
, pCons
->eFunction
);
5127 AddAttribute( XML_NAMESPACE_TABLE
, XML_FUNCTION
, sStrData
);
5130 for( sal_Int32 nIndex
= 0; nIndex
< pCons
->nDataAreaCount
; ++nIndex
)
5131 ScRangeStringConverter::GetStringFromArea( sStrData
, pCons
->pDataAreas
[ nIndex
], pDoc
, FormulaGrammar::CONV_OOO
, ' ', true );
5132 AddAttribute( XML_NAMESPACE_TABLE
, XML_SOURCE_CELL_RANGE_ADDRESSES
, sStrData
);
5134 ScRangeStringConverter::GetStringFromAddress( sStrData
, ScAddress( pCons
->nCol
, pCons
->nRow
, pCons
->nTab
), pDoc
, FormulaGrammar::CONV_OOO
);
5135 AddAttribute( XML_NAMESPACE_TABLE
, XML_TARGET_CELL_ADDRESS
, sStrData
);
5137 if( pCons
->bByCol
&& !pCons
->bByRow
)
5138 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_COLUMN
);
5139 else if( !pCons
->bByCol
&& pCons
->bByRow
)
5140 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_ROW
);
5141 else if( pCons
->bByCol
&& pCons
->bByRow
)
5142 AddAttribute( XML_NAMESPACE_TABLE
, XML_USE_LABEL
, XML_BOTH
);
5144 if( pCons
->bReferenceData
)
5145 AddAttribute( XML_NAMESPACE_TABLE
, XML_LINK_TO_SOURCE_DATA
, XML_TRUE
);
5147 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_CONSOLIDATION
, true, true );
5150 SvXMLAutoStylePoolP
* ScXMLExport::CreateAutoStylePool()
5152 return new ScXMLAutoStylePoolP(*this);
5155 XMLPageExport
* ScXMLExport::CreatePageExport()
5157 return new XMLTableMasterPageExport( *this );
5160 void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence
<beans::PropertyValue
>& rProps
)
5162 ScChangeViewSettings
* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : nullptr);
5166 sal_Int32
nChangePos(rProps
.getLength());
5167 rProps
.realloc(nChangePos
+ 1);
5168 beans::PropertyValue
* pProps(rProps
.getArray());
5170 uno::Sequence
<beans::PropertyValue
> aChangeProps(SC_VIEWCHANGES_COUNT
);
5171 beans::PropertyValue
* pChangeProps(aChangeProps
.getArray());
5172 pChangeProps
[SC_SHOW_CHANGES
].Name
= "ShowChanges";
5173 pChangeProps
[SC_SHOW_CHANGES
].Value
<<= pViewSettings
->ShowChanges();
5174 pChangeProps
[SC_SHOW_ACCEPTED_CHANGES
].Name
= "ShowAcceptedChanges";
5175 pChangeProps
[SC_SHOW_ACCEPTED_CHANGES
].Value
<<= pViewSettings
->IsShowAccepted();
5176 pChangeProps
[SC_SHOW_REJECTED_CHANGES
].Name
= "ShowRejectedChanges";
5177 pChangeProps
[SC_SHOW_REJECTED_CHANGES
].Value
<<= pViewSettings
->IsShowRejected();
5178 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME
].Name
= "ShowChangesByDatetime";
5179 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME
].Value
<<= pViewSettings
->HasDate();
5180 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_MODE
].Name
= "ShowChangesByDatetimeMode";
5181 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_MODE
].Value
<<= static_cast<sal_Int16
>(pViewSettings
->GetTheDateMode());
5182 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME
].Name
= "ShowChangesByDatetimeFirstDatetime";
5183 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME
].Value
<<= pViewSettings
->GetTheFirstDateTime().GetUNODateTime();
5184 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME
].Name
= "ShowChangesByDatetimeSecondDatetime";
5185 pChangeProps
[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME
].Value
<<= pViewSettings
->GetTheLastDateTime().GetUNODateTime();
5186 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR
].Name
= "ShowChangesByAuthor";
5187 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR
].Value
<<= pViewSettings
->HasAuthor();
5188 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR_NAME
].Name
= "ShowChangesByAuthorName";
5189 pChangeProps
[SC_SHOW_CHANGES_BY_AUTHOR_NAME
].Value
<<= pViewSettings
->GetTheAuthorToShow();
5190 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT
].Name
= "ShowChangesByComment";
5191 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT
].Value
<<= pViewSettings
->HasComment();
5192 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT_TEXT
].Name
= "ShowChangesByCommentText";
5193 pChangeProps
[SC_SHOW_CHANGES_BY_COMMENT_TEXT
].Value
<<= pViewSettings
->GetTheComment();
5194 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES
].Name
= "ShowChangesByRanges";
5195 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES
].Value
<<= pViewSettings
->HasRange();
5196 OUString sRangeList
;
5197 ScRangeStringConverter::GetStringFromRangeList(sRangeList
, &(pViewSettings
->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO
);
5198 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES_LIST
].Name
= "ShowChangesByRangesList";
5199 pChangeProps
[SC_SHOW_CHANGES_BY_RANGES_LIST
].Value
<<= sRangeList
;
5201 pProps
[nChangePos
].Name
= "TrackedChangesViewSettings";
5202 pProps
[nChangePos
].Value
<<= aChangeProps
;
5205 void ScXMLExport::GetViewSettings(uno::Sequence
<beans::PropertyValue
>& rProps
)
5207 if (GetModel().is())
5210 beans::PropertyValue
* pProps(rProps
.getArray());
5211 ScModelObj
* pDocObj(comphelper::getUnoTunnelImplementation
<ScModelObj
>( GetModel() ));
5214 SfxObjectShell
* pEmbeddedObj
= pDocObj
->GetEmbeddedObject();
5217 tools::Rectangle
aRect(pEmbeddedObj
->GetVisArea());
5219 pProps
[i
].Name
= "VisibleAreaTop";
5220 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.getY());
5221 pProps
[++i
].Name
= "VisibleAreaLeft";
5222 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.getX());
5223 pProps
[++i
].Name
= "VisibleAreaWidth";
5224 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.getWidth());
5225 pProps
[++i
].Name
= "VisibleAreaHeight";
5226 pProps
[i
].Value
<<= static_cast<sal_Int32
>(aRect
.getHeight());
5230 GetChangeTrackViewSettings(rProps
);
5233 void ScXMLExport::GetConfigurationSettings(uno::Sequence
<beans::PropertyValue
>& rProps
)
5235 if (!GetModel().is())
5238 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
5239 if (!xMultiServiceFactory
.is())
5242 uno::Reference
<beans::XPropertySet
> xProperties(xMultiServiceFactory
->createInstance("com.sun.star.comp.SpreadsheetSettings"), uno::UNO_QUERY
);
5243 if (xProperties
.is())
5244 SvXMLUnitConverter::convertPropertySet(rProps
, xProperties
);
5246 sal_Int32 nPropsToAdd
= 0;
5247 OUStringBuffer aTrackedChangesKey
;
5248 if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected())
5250 ::comphelper::Base64::encode(aTrackedChangesKey
,
5251 GetDocument()->GetChangeTrack()->GetProtection());
5252 if (!aTrackedChangesKey
.isEmpty())
5256 bool bVBACompat
= false;
5257 uno::Reference
<container::XNameAccess
> xCodeNameAccess
;
5258 OSL_ENSURE( pDoc
, "ScXMLExport::GetConfigurationSettings - no ScDocument!" );
5259 // tdf#71271 - add code names regardless of VBA compatibility mode
5262 // VBA compatibility mode
5263 if (bVBACompat
= pDoc
->IsInVBAMode(); bVBACompat
)
5267 xCodeNameAccess
= new XMLCodeNameProvider( pDoc
);
5268 if( xCodeNameAccess
->hasElements() )
5271 xCodeNameAccess
.clear();
5274 if( nPropsToAdd
<= 0 )
5277 sal_Int32
nCount(rProps
.getLength());
5278 rProps
.realloc(nCount
+ nPropsToAdd
);
5279 if (!aTrackedChangesKey
.isEmpty())
5281 rProps
[nCount
].Name
= "TrackedChangesProtectionKey";
5282 rProps
[nCount
].Value
<<= aTrackedChangesKey
.makeStringAndClear();
5287 rProps
[nCount
].Name
= "VBACompatibilityMode";
5288 rProps
[nCount
].Value
<<= bVBACompat
;
5291 if( xCodeNameAccess
.is() )
5293 rProps
[nCount
].Name
= "ScriptConfiguration";
5294 rProps
[nCount
].Value
<<= xCodeNameAccess
;
5299 XMLShapeExport
* ScXMLExport::CreateShapeExport()
5301 return new ScXMLShapeExport(*this);
5304 XMLNumberFormatAttributesExportHelper
* ScXMLExport::GetNumberFormatAttributesExportHelper()
5306 if (!pNumberFormatAttributesExportHelper
)
5307 pNumberFormatAttributesExportHelper
.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this ));
5308 return pNumberFormatAttributesExportHelper
.get();
5311 void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool
* pPool
, sal_uInt16 nAttrib
)
5313 for (const SfxPoolItem
* pItem
: pPool
->GetItemSurrogates(nAttrib
))
5315 const SvXMLAttrContainerItem
*pUnknown(static_cast<const SvXMLAttrContainerItem
*>(pItem
));
5316 if( pUnknown
->GetAttrCount() > 0 )
5318 sal_uInt16
nIdx(pUnknown
->GetFirstNamespaceIndex());
5319 while( USHRT_MAX
!= nIdx
)
5321 if( (XML_NAMESPACE_UNKNOWN_FLAG
& nIdx
) != 0 )
5323 const OUString
& rPrefix
= pUnknown
->GetPrefix( nIdx
);
5324 // Add namespace declaration for unknown attributes if
5325 // there aren't existing ones for the prefix used by the
5327 GetNamespaceMap_().Add( rPrefix
,
5328 pUnknown
->GetNamespace( nIdx
) );
5330 nIdx
= pUnknown
->GetNextNamespaceIndex( nIdx
);
5335 // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
5336 GetNamespaceMap_().Add(
5337 GetXMLToken( XML_NP_PRESENTATION
),
5338 GetXMLToken( XML_N_PRESENTATION
),
5339 XML_NAMESPACE_PRESENTATION
);
5342 void ScXMLExport::IncrementProgressBar(bool bFlush
, sal_Int32 nInc
)
5344 nProgressCount
+= nInc
;
5345 if (bFlush
|| nProgressCount
> 100)
5347 GetProgressBarHelper()->Increment(nProgressCount
);
5352 ErrCode
ScXMLExport::exportDoc( enum XMLTokenEnum eClass
)
5354 if( getExportFlags() & (SvXMLExportFlags::FONTDECLS
|SvXMLExportFlags::STYLES
|
5355 SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
) )
5359 // if source doc was Excel then
5360 uno::Reference
< frame::XModel
> xModel
= GetModel();
5363 auto pFoundShell
= comphelper::getUnoTunnelImplementation
<SfxObjectShell
>(xModel
);
5364 if ( pFoundShell
&& ooo::vba::isAlienExcelDoc( *pFoundShell
) )
5366 xRowStylesPropertySetMapper
= new XMLPropertySetMapper(aXMLScFromXLSRowStylesProperties
, xScPropHdlFactory
, true);
5367 xRowStylesExportPropertySetMapper
= new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper
);
5368 GetAutoStylePool()->SetFamilyPropSetMapper( XmlStyleFamily::TABLE_ROW
,
5369 xRowStylesExportPropertySetMapper
);
5372 CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF
);
5373 CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS
);
5374 CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS
);
5375 ScDrawLayer
* pDrawLayer
= GetDocument()->GetDrawLayer();
5378 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), EE_PARA_XMLATTRIBS
);
5379 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), EE_CHAR_XMLATTRIBS
);
5380 CollectUserDefinedNamespaces(&pDrawLayer
->GetItemPool(), SDRATTR_XMLATTRIBUTES
);
5383 // sheet events use officeooo namespace
5384 if( (getExportFlags() & SvXMLExportFlags::CONTENT
) &&
5385 getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
5387 bool bAnySheetEvents
= false;
5388 SCTAB nTabCount
= pDoc
->GetTableCount();
5389 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
5390 if (pDoc
->GetSheetEvents(nTab
))
5391 bAnySheetEvents
= true;
5392 if (bAnySheetEvents
)
5393 GetNamespaceMap_().Add(
5394 GetXMLToken( XML_NP_OFFICE_EXT
),
5395 GetXMLToken( XML_N_OFFICE_EXT
),
5396 XML_NAMESPACE_OFFICE_EXT
);
5400 return SvXMLExport::exportDoc( eClass
);
5404 void SAL_CALL
ScXMLExport::setSourceDocument( const uno::Reference
<lang::XComponent
>& xComponent
)
5406 SolarMutexGuard aGuard
;
5407 SvXMLExport::setSourceDocument( xComponent
);
5409 pDoc
= ScXMLConverter::GetScDocument( GetModel() );
5410 OSL_ENSURE( pDoc
, "ScXMLExport::setSourceDocument - no ScDocument!" );
5412 throw lang::IllegalArgumentException();
5414 // create ScChangeTrackingExportHelper after document is known
5415 pChangeTrackingExportHelper
.reset(new ScChangeTrackingExportHelper(*this));
5417 // Set the document's storage grammar corresponding to the ODF version that
5418 // is to be written.
5419 SvtSaveOptions::ODFSaneDefaultVersion meODFDefaultVersion
= getSaneDefaultVersion();
5420 switch (meODFDefaultVersion
)
5422 // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF
5423 case SvtSaveOptions::ODFSVER_010
:
5424 case SvtSaveOptions::ODFSVER_011
:
5425 pDoc
->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF
);
5428 pDoc
->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF
);
5433 sal_Bool SAL_CALL
ScXMLExport::filter( const css::uno::Sequence
< css::beans::PropertyValue
>& aDescriptor
)
5435 SolarMutexGuard aGuard
;
5437 pDoc
->EnableIdle(false);
5438 bool bReturn(SvXMLExport::filter(aDescriptor
));
5440 pDoc
->EnableIdle(true);
5444 void SAL_CALL
ScXMLExport::cancel()
5446 SolarMutexGuard aGuard
;
5448 pDoc
->EnableIdle(true);
5449 SvXMLExport::cancel();
5453 void SAL_CALL
ScXMLExport::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
5455 SolarMutexGuard aGuard
;
5456 SvXMLExport::initialize(aArguments
);
5460 sal_Int64 SAL_CALL
ScXMLExport::getSomething( const css::uno::Sequence
< sal_Int8
>& aIdentifier
)
5462 SolarMutexGuard aGuard
;
5463 return SvXMLExport::getSomething(aIdentifier
);
5466 void ScXMLExport::DisposingModel()
5468 SvXMLExport::DisposingModel();
5470 xCurrentTable
= nullptr;
5473 void ScXMLExport::SetSharedData(std::unique_ptr
<ScMySharedData
> pTemp
) { pSharedData
= std::move(pTemp
); }
5475 std::unique_ptr
<ScMySharedData
> ScXMLExport::ReleaseSharedData() { return std::move(pSharedData
); }
5476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */