fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / filter / xml / xmlexprt.cxx
blobf44f6fca54af811b0382bbfaa9cdb82bf2bf2f79
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include "appluno.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 "cellsuno.hxx"
30 #include "formulacell.hxx"
31 #include "rangenam.hxx"
32 #include "XMLTableMasterPageExport.hxx"
33 #include "drwlayer.hxx"
34 #include "XMLExportDataPilot.hxx"
35 #include "XMLExportDatabaseRanges.hxx"
36 #include "XMLExportDDELinks.hxx"
37 #include "XMLExportIterator.hxx"
38 #include "XMLColumnRowGroupExport.hxx"
39 #include "XMLStylesExportHelper.hxx"
40 #include "XMLChangeTrackingExportHelper.hxx"
41 #include "sheetdata.hxx"
42 #include "docoptio.hxx"
43 #include "XMLExportSharedData.hxx"
44 #include "chgviset.hxx"
45 #include "docuno.hxx"
46 #include "textuno.hxx"
47 #include "chartlis.hxx"
48 #include "scitems.hxx"
49 #include "docpool.hxx"
50 #include "userdat.hxx"
51 #include "dociter.hxx"
52 #include "chgtrack.hxx"
53 #include "rangeutl.hxx"
54 #include "convuno.hxx"
55 #include "postit.hxx"
56 #include "externalrefmgr.hxx"
57 #include "editutil.hxx"
58 #include "tabprotection.hxx"
59 #include "cachedattraccess.hxx"
60 #include "colorscale.hxx"
61 #include "conditio.hxx"
62 #include "cellvalue.hxx"
63 #include "stylehelper.hxx"
64 #include "edittextiterator.hxx"
65 #include "editattributemap.hxx"
66 #include <arealink.hxx>
67 #include <datastream.hxx>
68 #include <documentlinkmgr.hxx>
69 #include <tokenstringcontext.hxx>
70 #include <cellform.hxx>
72 #include <xmloff/xmltoken.hxx>
73 #include <xmloff/xmlnmspe.hxx>
74 #include <xmloff/xmluconv.hxx>
75 #include <xmloff/nmspmap.hxx>
76 #include <xmloff/families.hxx>
77 #include <xmloff/numehelp.hxx>
78 #include <xmloff/txtparae.hxx>
79 #include <editeng/autokernitem.hxx>
80 #include <editeng/charreliefitem.hxx>
81 #include <editeng/charscaleitem.hxx>
82 #include <editeng/colritem.hxx>
83 #include <editeng/contouritem.hxx>
84 #include <editeng/crossedoutitem.hxx>
85 #include <editeng/emphasismarkitem.hxx>
86 #include <editeng/escapementitem.hxx>
87 #include <editeng/fhgtitem.hxx>
88 #include <editeng/fontitem.hxx>
89 #include <editeng/kernitem.hxx>
90 #include <editeng/langitem.hxx>
91 #include <editeng/postitem.hxx>
92 #include <editeng/section.hxx>
93 #include <editeng/shdditem.hxx>
94 #include <editeng/udlnitem.hxx>
95 #include <editeng/wghtitem.hxx>
96 #include <editeng/wrlmitem.hxx>
97 #include <editeng/xmlcnitm.hxx>
98 #include <editeng/flditem.hxx>
99 #include <editeng/eeitem.hxx>
100 #include <xmloff/xmlerror.hxx>
101 #include <xmloff/XMLEventExport.hxx>
103 #include <sax/tools/converter.hxx>
105 #include <rtl/ustring.hxx>
107 #include <tools/color.hxx>
108 #include <tools/urlobj.hxx>
109 #include <rtl/math.hxx>
110 #include <svl/zforlist.hxx>
111 #include <svx/unoshape.hxx>
112 #include <comphelper/extract.hxx>
113 #include <toolkit/helper/convert.hxx>
114 #include <svx/svdobj.hxx>
115 #include <svx/svdocapt.hxx>
116 #include <editeng/outlobj.hxx>
117 #include <svx/svditer.hxx>
118 #include <svx/svdpage.hxx>
119 #include <svtools/miscopt.hxx>
121 #include <officecfg/Office/Common.hxx>
123 #include <com/sun/star/uno/XComponentContext.hpp>
124 #include <comphelper/processfactory.hxx>
125 #include <com/sun/star/beans/XPropertySet.hpp>
126 #include <com/sun/star/container/XNamed.hpp>
127 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
128 #include <com/sun/star/form/XFormsSupplier2.hpp>
129 #include <com/sun/star/io/XActiveDataSource.hpp>
130 #include <com/sun/star/io/XSeekable.hpp>
131 #include <com/sun/star/sheet/XUsedAreaCursor.hpp>
132 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
133 #include <com/sun/star/sheet/XAreaLinks.hpp>
134 #include <com/sun/star/sheet/XAreaLink.hpp>
135 #include <com/sun/star/sheet/XPrintAreas.hpp>
136 #include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp>
137 #include <com/sun/star/sheet/XCellRangesQuery.hpp>
138 #include <com/sun/star/sheet/CellFlags.hpp>
139 #include <com/sun/star/sheet/XArrayFormulaRange.hpp>
140 #include <com/sun/star/sheet/XLabelRanges.hpp>
141 #include <com/sun/star/sheet/XLabelRange.hpp>
142 #include <com/sun/star/sheet/XNamedRanges.hpp>
143 #include <com/sun/star/sheet/XNamedRange.hpp>
144 #include <com/sun/star/sheet/XCellRangeReferrer.hpp>
145 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
146 #include <com/sun/star/sheet/XSheetLinkable.hpp>
147 #include <com/sun/star/sheet/GlobalSheetSettings.hpp>
148 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
149 #include <com/sun/star/table/XColumnRowRange.hpp>
150 #include <com/sun/star/text/XText.hpp>
151 #include <com/sun/star/util/XMergeable.hpp>
152 #include <com/sun/star/util/XProtectable.hpp>
154 #include <com/sun/star/chart2/XChartDocument.hpp>
155 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
156 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
158 #include <com/sun/star/document/XDocumentProperties.hpp>
159 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
161 #include "XMLCodeNameProvider.hxx"
163 #include <sfx2/linkmgr.hxx>
164 #include <sfx2/objsh.hxx>
166 #include <vector>
167 #include <vbahelper/vbaaccesshelper.hxx>
168 #include <boost/scoped_ptr.hpp>
170 //! not found in unonames.hxx
171 #define SC_LAYERID "LayerID"
173 #define SC_VIEWCHANGES_COUNT 13
174 #define SC_SHOW_CHANGES 0
175 #define SC_SHOW_ACCEPTED_CHANGES 1
176 #define SC_SHOW_REJECTED_CHANGES 2
177 #define SC_SHOW_CHANGES_BY_DATETIME 3
178 #define SC_SHOW_CHANGES_BY_DATETIME_MODE 4
179 #define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5
180 #define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6
181 #define SC_SHOW_CHANGES_BY_AUTHOR 7
182 #define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8
183 #define SC_SHOW_CHANGES_BY_COMMENT 9
184 #define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10
185 #define SC_SHOW_CHANGES_BY_RANGES 11
186 #define SC_SHOW_CHANGES_BY_RANGES_LIST 12
188 using namespace formula;
189 using namespace com::sun::star;
190 using namespace xmloff::token;
191 using ::std::vector;
192 using ::com::sun::star::uno::Reference;
193 using ::com::sun::star::uno::UNO_QUERY;
195 namespace
197 OUString lcl_RangeSequenceToString(
198 const uno::Sequence< OUString > & rRanges,
199 const uno::Reference< chart2::data::XRangeXMLConversion > & xFormatConverter )
201 OUStringBuffer aResult;
202 const sal_Int32 nMaxIndex( rRanges.getLength() - 1 );
203 const sal_Unicode cSep(' ');
204 for( sal_Int32 i=0; i<=nMaxIndex; ++i )
206 OUString aRange( rRanges[i] );
207 if( xFormatConverter.is())
208 aRange = xFormatConverter->convertRangeToXML( aRange );
209 aResult.append( aRange );
210 if( i < nMaxIndex )
211 aResult.append( cSep );
213 return aResult.makeStringAndClear();
216 OUString lcl_GetFormattedString( ScDocument* pDoc, const ScAddress& rPos )
218 // return text/edit cell string content, with line feeds in edit cells
220 if (!pDoc)
221 return EMPTY_OUSTRING;
223 switch (pDoc->GetCellType(rPos))
225 case CELLTYPE_STRING:
226 return pDoc->GetString(rPos);
227 case CELLTYPE_EDIT:
229 const EditTextObject* pData = pDoc->GetEditText(rPos);
230 if (!pData)
231 return EMPTY_OUSTRING;
233 EditEngine& rEngine = pDoc->GetEditEngine();
234 rEngine.SetText(*pData);
235 return rEngine.GetText(LINEEND_LF);
237 break;
238 default:
242 return EMPTY_OUSTRING;
245 } // anonymous namespace
247 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
248 Calc_XMLExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
250 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLExporter", SvXMLExportFlags::ALL));
253 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
254 Calc_XMLMetaExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
256 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLMetaExporter", SvXMLExportFlags::META));
259 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
260 Calc_XMLStylesExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
262 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLStylesExporter", SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS));
265 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
266 Calc_XMLContentExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
268 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLContentExporter", SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::FONTDECLS));
271 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
272 Calc_XMLSettingsExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
274 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLSettingsExporter", SvXMLExportFlags::SETTINGS));
277 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
278 Calc_XMLOasisExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
280 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisExporter", SvXMLExportFlags::ALL|SvXMLExportFlags::OASIS));
283 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
284 Calc_XMLOasisMetaExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
286 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisMetaExporter", SvXMLExportFlags::META|SvXMLExportFlags::OASIS));
289 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
290 Calc_XMLOasisStylesExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
292 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisStylesExporter", SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::OASIS));
295 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
296 Calc_XMLOasisContentExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
298 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisContentExporter", SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::OASIS));
301 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
302 Calc_XMLOasisSettingsExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &)
304 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisSettingsExporter", SvXMLExportFlags::SETTINGS|SvXMLExportFlags::OASIS));
307 class ScXMLShapeExport : public XMLShapeExport
309 public:
310 ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {}
311 virtual ~ScXMLShapeExport();
313 /** is called before a shape element for the given XShape is exported */
314 virtual void onExport( const uno::Reference < drawing::XShape >& xShape ) SAL_OVERRIDE;
317 ScXMLShapeExport::~ScXMLShapeExport()
321 void ScXMLShapeExport::onExport( const uno::Reference < drawing::XShape >& xShape )
323 uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
324 if( xShapeProp.is() )
326 sal_Int16 nLayerID = 0;
327 if( (xShapeProp->getPropertyValue(OUString( SC_LAYERID )) >>= nLayerID) && (nLayerID == SC_LAYER_BACK) )
328 GetExport().AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_BACKGROUND, XML_TRUE);
332 sal_Int16 ScXMLExport::GetMeasureUnit()
334 css::uno::Reference<css::sheet::XGlobalSheetSettings> xProperties =
335 css::sheet::GlobalSheetSettings::create( comphelper::getProcessComponentContext() );
336 return xProperties->getMetric();
339 // #110680#
340 ScXMLExport::ScXMLExport(
341 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rContext,
342 OUString const & implementationName, SvXMLExportFlags nExportFlag)
343 : SvXMLExport( GetMeasureUnit(),
344 rContext, implementationName, XML_SPREADSHEET, nExportFlag ),
345 pDoc(NULL),
346 nSourceStreamPos(0),
347 pNumberFormatAttributesExportHelper(NULL),
348 pSharedData(NULL),
349 pColumnStyles(NULL),
350 pRowStyles(NULL),
351 pCellStyles(NULL),
352 pRowFormatRanges(NULL),
353 aTableStyles(),
354 pGroupColumns (NULL),
355 pGroupRows (NULL),
356 pDefaults(NULL),
357 pChartListener(NULL),
358 pCurrentCell(NULL),
359 pMergedRangesContainer(NULL),
360 pValidationsContainer(NULL),
361 pChangeTrackingExportHelper(NULL),
362 sLayerID( SC_LAYERID ),
363 sCaptionShape("com.sun.star.drawing.CaptionShape"),
364 nOpenRow(-1),
365 nProgressCount(0),
366 nCurrentTable(0),
367 bHasRowHeader(false),
368 bRowHeaderOpen(false),
369 mbShowProgress( false )
371 if (getExportFlags() & SvXMLExportFlags::CONTENT)
373 pGroupColumns = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP);
374 pGroupRows = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP);
375 pColumnStyles = new ScColumnStyles();
376 pRowStyles = new ScRowStyles();
377 pRowFormatRanges = new ScRowFormatRanges();
378 pMergedRangesContainer = new ScMyMergedRangesContainer();
379 pValidationsContainer = new ScMyValidationsContainer();
380 mpCellsItr.reset(new ScMyNotEmptyCellsIterator(*this));
381 pDefaults = new ScMyDefaultStyles();
383 pCellStyles = new ScFormatRangeStyles();
385 // document is not set here - create ScChangeTrackingExportHelper later
387 xScPropHdlFactory = new XMLScPropHdlFactory;
388 xCellStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScCellStylesProperties, xScPropHdlFactory, true);
389 xColumnStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScColumnStylesProperties, xScPropHdlFactory, true);
390 xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScRowStylesProperties, xScPropHdlFactory, true);
391 xTableStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScTableStylesProperties, xScPropHdlFactory, true);
392 xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper);
393 xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
394 xColumnStylesExportPropertySetMapper = new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper);
395 xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper);
396 xTableStylesExportPropertySetMapper = new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper);
398 GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL, OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME),
399 xCellStylesExportPropertySetMapper, OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX));
400 GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN, OUString(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME),
401 xColumnStylesExportPropertySetMapper, OUString(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX));
402 GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW, OUString(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME),
403 xRowStylesExportPropertySetMapper, OUString(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX));
404 GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE, OUString(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME),
405 xTableStylesExportPropertySetMapper, OUString(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX));
407 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
409 // This name is reserved for the external ref cache tables. This
410 // should not conflict with user-defined styles since this name is
411 // used for a table style which is not available in the UI.
412 sExternalRefTabStyleName = "ta_extref";
413 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sExternalRefTabStyleName);
415 sAttrName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NAME));
416 sAttrStyleName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME));
417 sAttrColumnsRepeated = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED));
418 sAttrFormula = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_FORMULA));
419 sAttrStringValue = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE));
420 sAttrValueType = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE));
421 sElemCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_CELL));
422 sElemCoveredCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_COVERED_TABLE_CELL));
423 sElemCol = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_COLUMN));
424 sElemRow = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_ROW));
425 sElemTab = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE));
426 sElemP = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
430 ScXMLExport::~ScXMLExport()
432 delete pGroupColumns;
433 delete pGroupRows;
434 delete pColumnStyles;
435 delete pRowStyles;
436 delete pCellStyles;
437 delete pRowFormatRanges;
438 delete pMergedRangesContainer;
439 delete pValidationsContainer;
440 delete pChangeTrackingExportHelper;
441 delete pChartListener;
442 delete pDefaults;
443 delete pNumberFormatAttributesExportHelper;
446 void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream )
448 xSourceStream = xNewStream;
450 if ( xSourceStream.is() )
452 // make sure it's a plain UTF-8 stream as written by OOo itself
454 const sal_Char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
455 sal_Int32 nLen = strlen(pXmlHeader);
457 uno::Sequence<sal_Int8> aFileStart(nLen);
458 sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen );
460 if ( nRead != nLen || memcmp( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 )
462 // invalid - ignore stream, save normally
463 xSourceStream.clear();
465 else
467 // keep track of the bytes already read
468 nSourceStreamPos = nRead;
470 const ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
471 if (pSheetData)
473 // add the loaded namespaces to the name space map
475 if ( !pSheetData->AddLoadedNamespaces( _GetNamespaceMap() ) )
477 // conflicts in the namespaces - ignore the stream, save normally
478 xSourceStream.clear();
485 sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const
487 NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt);
488 if (itr == aNumFmtIndexMap.end())
489 return -1;
491 return itr->second;
494 void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount)
496 if (!GetModel().is())
497 return;
499 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc(GetModel(), uno::UNO_QUERY);
500 if (!xSpreadDoc.is())
501 return;
503 uno::Reference<container::XIndexAccess> xIndex(xSpreadDoc->getSheets(), uno::UNO_QUERY);
504 if (!xIndex.is())
505 return;
507 nTableCount = xIndex->getCount();
508 if (!pSharedData)
509 CreateSharedData(nTableCount);
511 pCellStyles->AddNewTable(nTableCount - 1);
513 for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
515 nCurrentTable = sal::static_int_cast<sal_uInt16>(nTable);
516 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY);
517 if (!xDrawPageSupplier.is())
518 continue;
520 uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage());
521 ScMyDrawPage aDrawPage;
522 aDrawPage.bHasForms = false;
523 aDrawPage.xDrawPage.set(xDrawPage);
524 pSharedData->AddDrawPage(aDrawPage, nTable);
525 uno::Reference<container::XIndexAccess> xShapesIndex(xDrawPage, uno::UNO_QUERY);
526 if (!xShapesIndex.is())
527 continue;
529 sal_Int32 nShapes = xShapesIndex->getCount();
530 for (sal_Int32 nShape = 0; nShape < nShapes; ++nShape)
532 uno::Reference<drawing::XShape> xShape(xShapesIndex->getByIndex(nShape), uno::UNO_QUERY);
533 if (!xShape.is())
534 continue;
536 uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY);
537 if (!xShapeProp.is())
538 continue;
540 sal_Int16 nLayerID = 0;
541 bool bExtracted = xShapeProp->getPropertyValue(sLayerID) >>= nLayerID;
542 if (!bExtracted)
543 continue;
545 if ((nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN))
547 CollectInternalShape(xShape);
548 continue;
551 ++nShapesCount;
553 SvxShape* pShapeImp = SvxShape::getImplementation(xShape);
554 if (!pShapeImp)
555 continue;
557 SdrObject* pSdrObj = pShapeImp->GetSdrObject();
558 if (!pSdrObj)
559 continue;
561 if (ScDrawObjData *pAnchor = ScDrawLayer::GetNonRotatedObjData(pSdrObj))
563 ScMyShape aMyShape;
564 aMyShape.aAddress = pAnchor->maStart;
565 SAL_WARN_IF(aMyShape.aAddress.Tab() != nTable, "sc", "not anchored to current sheet!");
566 aMyShape.aAddress.SetTab(nTable);
567 aMyShape.aEndAddress = pAnchor->maEnd;
568 aMyShape.aEndAddress.SetTab( nTable );
569 aMyShape.nEndX = pAnchor->maEndOffset.X();
570 aMyShape.nEndY = pAnchor->maEndOffset.Y();
571 aMyShape.xShape = xShape;
572 pSharedData->AddNewShape(aMyShape);
573 pSharedData->SetLastColumn(nTable, pAnchor->maStart.Col());
574 pSharedData->SetLastRow(nTable, pAnchor->maStart.Row());
576 else
577 pSharedData->AddTableShape(nTable, xShape);
582 void ScXMLExport::CollectShapesAutoStyles(const sal_Int32 nTableCount)
584 // #i84077# To avoid compiler warnings about uninitialized aShapeItr,
585 // it's initialized using this dummy list. The iterator contains shapes
586 // from all sheets, so it can't be declared inside the nTable loop where
587 // it is used.
588 ScMyShapeList aDummyInitList;
590 pSharedData->SortShapesContainer();
591 pSharedData->SortNoteShapes();
592 const ScMyShapeList* pShapeList(NULL);
593 ScMyShapeList::const_iterator aShapeItr = aDummyInitList.end();
594 if (pSharedData->GetShapesContainer())
596 pShapeList = &pSharedData->GetShapesContainer()->GetShapes();
597 aShapeItr = pShapeList->begin();
599 if (pSharedData->HasDrawPage())
601 for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
603 uno::Reference<drawing::XDrawPage> xDrawPage(pSharedData->GetDrawPage(nTable));
604 uno::Reference<drawing::XShapes> xShapes (xDrawPage, uno::UNO_QUERY);
606 if (xShapes.is())
608 GetShapeExport()->seekShapes(xShapes);
609 uno::Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, uno::UNO_QUERY );
610 if( xFormsSupplier.is() && xFormsSupplier->hasForms() )
612 GetFormExport()->examineForms(xDrawPage);
613 pSharedData->SetDrawPageHasForms(nTable, true);
615 ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
616 if (pTableShapes)
618 ScMyTableXShapes::iterator aItr((*pTableShapes)[nTable].begin());
619 ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nTable].end());
620 while (aItr != aEndItr)
622 GetShapeExport()->collectShapeAutoStyles(*aItr);
623 IncrementProgressBar(false);
624 ++aItr;
627 if (pShapeList)
629 ScMyShapeList::const_iterator aEndItr(pShapeList->end());
630 while (aShapeItr != aEndItr && (static_cast<sal_Int32>(aShapeItr->aAddress.Tab()) == nTable))
632 GetShapeExport()->collectShapeAutoStyles(aShapeItr->xShape);
633 IncrementProgressBar(false);
634 ++aShapeItr;
637 if (pSharedData->GetNoteShapes())
639 const ScMyNoteShapeList& rNoteShapes = pSharedData->GetNoteShapes()->GetNotes();
640 for (ScMyNoteShapeList::const_iterator aNoteShapeItr = rNoteShapes.begin(), aNoteShapeEndItr = rNoteShapes.end();
641 aNoteShapeItr != aNoteShapeEndItr; ++aNoteShapeItr)
643 if (static_cast<sal_Int32>(aNoteShapeItr->aPos.Tab()) == nTable)
644 GetShapeExport()->collectShapeAutoStyles(aNoteShapeItr->xShape);
650 pSharedData->SortNoteShapes(); // sort twice, because some more shapes are added
653 void ScXMLExport::_ExportMeta()
655 sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
656 sal_Int32 nTableCount(0);
657 sal_Int32 nShapesCount(0);
658 GetAutoStylePool()->ClearEntries();
659 CollectSharedData(nTableCount, nShapesCount);
661 uno::Sequence<beans::NamedValue> stats(3);
662 stats[0] = beans::NamedValue(OUString("TableCount"),
663 uno::makeAny(nTableCount));
664 stats[1] = beans::NamedValue(OUString("CellCount"),
665 uno::makeAny(nCellCount));
666 stats[2] = beans::NamedValue(OUString("ObjectCount"),
667 uno::makeAny(nShapesCount));
669 // update document statistics at the model
670 uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(),
671 uno::UNO_QUERY_THROW);
672 uno::Reference<document::XDocumentProperties> xDocProps(
673 xPropSup->getDocumentProperties());
674 if (xDocProps.is()) {
675 xDocProps->setDocumentStatistics(stats);
678 // export document properties
679 SvXMLExport::_ExportMeta();
682 void ScXMLExport::_ExportFontDecls()
684 GetFontAutoStylePool(); // make sure the pool is created
685 SvXMLExport::_ExportFontDecls();
688 table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable, const sal_Int32 /* nTable */)
690 table::CellRangeAddress aCellAddress;
691 uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor());
692 uno::Reference<sheet::XUsedAreaCursor> xUsedArea (xCursor, uno::UNO_QUERY);
693 uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
694 if (xUsedArea.is() && xCellAddress.is())
696 xUsedArea->gotoEndOfUsedArea(true);
697 aCellAddress = xCellAddress->getRangeAddress();
699 return aCellAddress;
702 void ScXMLExport::GetAreaLinks( ScMyAreaLinksContainer& rAreaLinks )
704 if (pDoc->GetLinkManager())
706 const sfx2::SvBaseLinks& rLinks = pDoc->GetLinkManager()->GetLinks();
707 for (size_t i = 0; i < rLinks.size(); i++)
709 ScAreaLink *pLink = dynamic_cast<ScAreaLink*>(&(*(*rLinks[i])));
710 if (pLink)
712 ScMyAreaLink aAreaLink;
713 ScUnoConversion::FillApiRange( aAreaLink.aDestRange, pLink->GetDestArea() );
714 aAreaLink.sSourceStr = pLink->GetSource();
715 aAreaLink.sFilter = pLink->GetFilter();
716 aAreaLink.sFilterOptions = pLink->GetOptions();
717 aAreaLink.sURL = pLink->GetFile();
718 aAreaLink.nRefresh = pLink->GetRefreshDelay();
719 rAreaLinks.AddNewAreaLink( aAreaLink );
723 rAreaLinks.Sort();
726 // core implementation
727 void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp )
729 if (pDoc)
731 ScDetOpList* pOpList(pDoc->GetDetOpList());
732 if( pOpList )
734 size_t nCount = pOpList->Count();
735 for (size_t nIndex = 0; nIndex < nCount; ++nIndex )
737 const ScDetOpData* pDetData = pOpList->GetObject( nIndex);
738 if( pDetData )
740 const ScAddress& rDetPos = pDetData->GetPos();
741 SCTAB nTab = rDetPos.Tab();
742 if ( nTab < pDoc->GetTableCount() )
744 rDetOp.AddOperation( pDetData->GetOperation(), rDetPos, static_cast<sal_uInt32>( nIndex) );
746 // cells with detective operations are written even if empty
747 pSharedData->SetLastColumn( nTab, rDetPos.Col() );
748 pSharedData->SetLastRow( nTab, rDetPos.Row() );
752 rDetOp.Sort();
757 void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex,
758 const sal_Int32 nIndex, const bool bIsAutoStyle, const bool bIsVisible)
760 CheckAttrList();
761 AddAttribute(sAttrStyleName, *pColumnStyles->GetStyleNameByIndex(nStyleIndex));
762 if (!bIsVisible)
763 AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
764 if (nRepeatColumns > 1)
766 OUString sOUEndCol(OUString::number(nRepeatColumns));
767 AddAttribute(sAttrColumnsRepeated, sOUEndCol);
769 if (nIndex != -1)
770 AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
771 SvXMLElementExport aElemC(*this, sElemCol, true, true);
774 void ScXMLExport::WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns,
775 const sal_Int32 nStyleIndex, const bool bIsVisible)
777 sal_Int32 nRepeat(1);
778 sal_Int32 nPrevIndex(pDefaults->GetColDefaults()[nColumn].nIndex);
779 bool bPrevAutoStyle(pDefaults->GetColDefaults()[nColumn].bIsAutoStyle);
780 for (sal_Int32 i = nColumn + 1; i < nColumn + nRepeatColumns; ++i)
782 if ((pDefaults->GetColDefaults()[i].nIndex != nPrevIndex) ||
783 (pDefaults->GetColDefaults()[i].bIsAutoStyle != bPrevAutoStyle))
785 WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
786 nPrevIndex = pDefaults->GetColDefaults()[i].nIndex;
787 bPrevAutoStyle = pDefaults->GetColDefaults()[i].bIsAutoStyle;
788 nRepeat = 1;
790 else
791 ++nRepeat;
793 WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
796 void ScXMLExport::OpenHeaderColumn()
798 StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, true );
801 void ScXMLExport::CloseHeaderColumn()
803 EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, true);
806 void ScXMLExport::ExportColumns(const sal_Int32 nTable, const table::CellRangeAddress& aColumnHeaderRange, const bool bHasColumnHeader)
808 sal_Int32 nColsRepeated (1);
809 sal_Int32 nIndex;
810 sal_Int32 nPrevColumn(0);
811 bool bPrevIsVisible (true);
812 bool bWasHeader (false);
813 bool bIsClosed (true);
814 sal_Int32 nPrevIndex (-1);
815 sal_Int32 nColumn;
816 for (nColumn = 0; nColumn <= pSharedData->GetLastColumn(nTable); ++nColumn)
818 CheckAttrList();
819 bool bIsVisible(true);
820 nIndex = pColumnStyles->GetStyleNameIndex(nTable, nColumn, bIsVisible);
822 const bool bIsHeader = bHasColumnHeader && (aColumnHeaderRange.StartColumn <= nColumn) && (nColumn <= aColumnHeaderRange.EndColumn);
823 if (bIsHeader != bWasHeader)
825 if (bIsHeader)
827 if (nColumn > 0)
829 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
830 if (pGroupColumns->IsGroupEnd(nColumn - 1))
831 pGroupColumns->CloseGroups(nColumn - 1);
833 bPrevIsVisible = bIsVisible;
834 nPrevIndex = nIndex;
835 nPrevColumn = nColumn;
836 nColsRepeated = 1;
837 if(pGroupColumns->IsGroupStart(nColumn))
838 pGroupColumns->OpenGroups(nColumn);
839 OpenHeaderColumn();
840 bWasHeader = true;
841 bIsClosed = false;
843 else
845 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
846 CloseHeaderColumn();
847 if (pGroupColumns->IsGroupEnd(nColumn - 1))
848 pGroupColumns->CloseGroups(nColumn - 1);
849 if(pGroupColumns->IsGroupStart(nColumn))
850 pGroupColumns->OpenGroups(nColumn);
851 bPrevIsVisible = bIsVisible;
852 nPrevIndex = nIndex;
853 nPrevColumn = nColumn;
854 nColsRepeated = 1;
855 bWasHeader = false;
856 bIsClosed = true;
859 else if (nColumn == 0)
861 if (pGroupColumns->IsGroupStart(nColumn))
862 pGroupColumns->OpenGroups(nColumn);
863 bPrevIsVisible = bIsVisible;
864 nPrevIndex = nIndex;
866 else if ((bIsVisible == bPrevIsVisible) && (nIndex == nPrevIndex) &&
867 !pGroupColumns->IsGroupStart(nColumn) && !pGroupColumns->IsGroupEnd(nColumn - 1))
868 ++nColsRepeated;
869 else
871 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
872 if (pGroupColumns->IsGroupEnd(nColumn - 1))
874 if (bIsHeader)
875 CloseHeaderColumn();
876 pGroupColumns->CloseGroups(nColumn - 1);
877 if (bIsHeader)
878 OpenHeaderColumn();
880 if (pGroupColumns->IsGroupStart(nColumn))
882 if (bIsHeader)
883 CloseHeaderColumn();
884 pGroupColumns->OpenGroups(nColumn);
885 if (bIsHeader)
886 OpenHeaderColumn();
888 bPrevIsVisible = bIsVisible;
889 nPrevIndex = nIndex;
890 nPrevColumn = nColumn;
891 nColsRepeated = 1;
894 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
895 if (!bIsClosed)
896 CloseHeaderColumn();
897 if (pGroupColumns->IsGroupEnd(nColumn - 1))
898 pGroupColumns->CloseGroups(nColumn - 1);
901 void ScXMLExport::ExportExternalRefCacheStyles()
903 sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex(
904 "NumberFormat", XML_NAMESPACE_STYLE, OUString("data-style-name"));
906 if (nEntryIndex < 0)
907 // No entry index for the number format is found.
908 return;
910 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
911 if (!pRefMgr->hasExternalData())
912 // No external reference data cached.
913 return;
915 // Export each unique number format used in the external ref cache.
916 vector<sal_uInt32> aNumFmts;
917 pRefMgr->getAllCachedNumberFormats(aNumFmts);
918 const OUString aDefaultStyle = OUString("Default").intern();
919 for (vector<sal_uInt32>::const_iterator itr = aNumFmts.begin(), itrEnd = aNumFmts.end();
920 itr != itrEnd; ++itr)
922 sal_Int32 nNumFmt = static_cast<sal_Int32>(*itr);
924 addDataStyle(nNumFmt);
926 uno::Any aVal;
927 aVal <<= nNumFmt;
928 vector<XMLPropertyState> aProps;
929 aVal <<= aDefaultStyle;
930 aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
932 OUString aName;
933 sal_Int32 nIndex;
934 if (GetAutoStylePool()->Add(aName, XML_STYLE_FAMILY_TABLE_CELL, aDefaultStyle, aProps))
936 OUString* pTemp(new OUString(aName));
937 if (!pCellStyles->AddStyleName(pTemp, nIndex, true))
938 delete pTemp;
940 else
942 bool bIsAuto;
943 nIndex = pCellStyles->GetIndexOfStyleName(
944 aName, OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX), bIsAuto);
947 // store the number format to index mapping for later use.
948 aNumFmtIndexMap.insert(NumberFormatIndexMap::value_type(nNumFmt, nIndex));
952 namespace {
954 void handleFont(
955 std::vector<XMLPropertyState>& rPropStates,
956 const SfxPoolItem* p, const rtl::Reference<XMLPropertySetMapper>& xMapper, const OUString& rXMLName )
958 sal_Int32 nEntryCount = xMapper->GetEntryCount();
960 // Apparently font info needs special handling.
961 const SvxFontItem* pItem = static_cast<const SvxFontItem*>(p);
963 sal_Int32 nIndexFontName = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, rXMLName, 0);
965 if (nIndexFontName == -1 || nIndexFontName >= nEntryCount)
966 return;
968 uno::Any aAny;
969 if (!pItem->QueryValue(aAny, MID_FONT_FAMILY_NAME))
970 return;
972 rPropStates.push_back(XMLPropertyState(nIndexFontName, aAny));
975 const SvxFieldData* toXMLPropertyStates(
976 std::vector<XMLPropertyState>& rPropStates, const std::vector<const SfxPoolItem*>& rSecAttrs,
977 const rtl::Reference<XMLPropertySetMapper>& xMapper, const ScXMLEditAttributeMap& rAttrMap )
979 const SvxFieldData* pField = NULL;
980 sal_Int32 nEntryCount = xMapper->GetEntryCount();
981 rPropStates.reserve(rSecAttrs.size());
982 std::vector<const SfxPoolItem*>::const_iterator it = rSecAttrs.begin(), itEnd = rSecAttrs.end();
983 for (; it != itEnd; ++it)
985 const SfxPoolItem* p = *it;
986 if (p->Which() == EE_FEATURE_FIELD)
988 pField = static_cast<const SvxFieldItem*>(p)->GetField();
989 continue;
992 const ScXMLEditAttributeMap::Entry* pEntry = rAttrMap.getEntryByItemID(p->Which());
993 if (!pEntry)
994 continue;
996 sal_Int32 nIndex = xMapper->GetEntryIndex(
997 pEntry->nmXMLNS, OUString::createFromAscii(pEntry->mpXMLName), 0);
999 if (nIndex == -1 || nIndex >= nEntryCount)
1000 continue;
1002 uno::Any aAny;
1003 switch (p->Which())
1005 case EE_CHAR_FONTINFO:
1006 handleFont(rPropStates, p, xMapper, "font-name");
1007 break;
1008 case EE_CHAR_FONTINFO_CJK:
1009 handleFont(rPropStates, p, xMapper, "font-name-asian");
1010 break;
1011 case EE_CHAR_FONTINFO_CTL:
1012 handleFont(rPropStates, p, xMapper, "font-name-complex");
1013 break;
1014 case EE_CHAR_WEIGHT:
1015 case EE_CHAR_WEIGHT_CJK:
1016 case EE_CHAR_WEIGHT_CTL:
1018 if (!static_cast<const SvxWeightItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1019 continue;
1021 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1023 break;
1024 case EE_CHAR_FONTHEIGHT:
1025 case EE_CHAR_FONTHEIGHT_CJK:
1026 case EE_CHAR_FONTHEIGHT_CTL:
1028 if (!static_cast<const SvxFontHeightItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1029 continue;
1031 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1033 break;
1034 case EE_CHAR_ITALIC:
1035 case EE_CHAR_ITALIC_CJK:
1036 case EE_CHAR_ITALIC_CTL:
1038 if (!static_cast<const SvxPostureItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1039 continue;
1041 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1043 break;
1044 case EE_CHAR_UNDERLINE:
1046 // Underline attribute needs to export multiple entries.
1047 sal_Int32 nIndexStyle = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-style", 0);
1048 if (nIndexStyle == -1 || nIndexStyle > nEntryCount)
1049 break;
1051 sal_Int32 nIndexWidth = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-width", 0);
1052 if (nIndexWidth == -1 || nIndexWidth > nEntryCount)
1053 break;
1055 sal_Int32 nIndexType = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-type", 0);
1056 if (nIndexType == -1 || nIndexType > nEntryCount)
1057 break;
1059 sal_Int32 nIndexColor = xMapper->FindEntryIndex("CharUnderlineColor", XML_NAMESPACE_STYLE, "text-underline-color");
1060 if (nIndexColor == -1 || nIndexColor > nEntryCount)
1061 break;
1063 sal_Int32 nIndexHasColor = xMapper->FindEntryIndex("CharUnderlineHasColor", XML_NAMESPACE_STYLE, "text-underline-color");
1064 if (nIndexHasColor == -1 || nIndexHasColor > nEntryCount)
1065 break;
1067 const SvxUnderlineItem* pUL = static_cast<const SvxUnderlineItem*>(p);
1068 pUL->QueryValue(aAny, MID_TL_STYLE);
1069 rPropStates.push_back(XMLPropertyState(nIndexStyle, aAny));
1070 rPropStates.push_back(XMLPropertyState(nIndexType, aAny));
1071 rPropStates.push_back(XMLPropertyState(nIndexWidth, aAny));
1073 pUL->QueryValue(aAny, MID_TL_COLOR);
1074 rPropStates.push_back(XMLPropertyState(nIndexColor, aAny));
1076 pUL->QueryValue(aAny, MID_TL_HASCOLOR);
1077 rPropStates.push_back(XMLPropertyState(nIndexHasColor, aAny));
1079 break;
1080 case EE_CHAR_OVERLINE:
1082 // Same with overline. Do just as we do with underline attributes.
1083 sal_Int32 nIndexStyle = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-style", 0);
1084 if (nIndexStyle == -1 || nIndexStyle > nEntryCount)
1085 break;
1087 sal_Int32 nIndexWidth = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-width", 0);
1088 if (nIndexWidth == -1 || nIndexWidth > nEntryCount)
1089 break;
1091 sal_Int32 nIndexType = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-type", 0);
1092 if (nIndexType == -1 || nIndexType > nEntryCount)
1093 break;
1095 sal_Int32 nIndexColor = xMapper->FindEntryIndex("CharOverlineColor", XML_NAMESPACE_STYLE, "text-overline-color");
1096 if (nIndexColor == -1 || nIndexColor > nEntryCount)
1097 break;
1099 sal_Int32 nIndexHasColor = xMapper->FindEntryIndex("CharOverlineHasColor", XML_NAMESPACE_STYLE, "text-overline-color");
1100 if (nIndexHasColor == -1 || nIndexHasColor > nEntryCount)
1101 break;
1103 const SvxOverlineItem* pOL = static_cast<const SvxOverlineItem*>(p);
1104 pOL->QueryValue(aAny, MID_TL_STYLE);
1105 rPropStates.push_back(XMLPropertyState(nIndexStyle, aAny));
1106 rPropStates.push_back(XMLPropertyState(nIndexType, aAny));
1107 rPropStates.push_back(XMLPropertyState(nIndexWidth, aAny));
1109 pOL->QueryValue(aAny, MID_TL_COLOR);
1110 rPropStates.push_back(XMLPropertyState(nIndexColor, aAny));
1112 pOL->QueryValue(aAny, MID_TL_HASCOLOR);
1113 rPropStates.push_back(XMLPropertyState(nIndexHasColor, aAny));
1115 break;
1116 case EE_CHAR_COLOR:
1118 if (!static_cast<const SvxColorItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1119 continue;
1121 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1123 break;
1124 case EE_CHAR_WLM:
1126 if (!static_cast<const SvxWordLineModeItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1127 continue;
1129 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1131 break;
1132 case EE_CHAR_STRIKEOUT:
1134 if (!static_cast<const SvxCrossedOutItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1135 continue;
1137 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1139 break;
1140 case EE_CHAR_RELIEF:
1142 if (!static_cast<const SvxCharReliefItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1143 continue;
1145 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1147 break;
1148 case EE_CHAR_OUTLINE:
1150 if (!static_cast<const SvxContourItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1151 continue;
1153 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1155 break;
1156 case EE_CHAR_SHADOW:
1158 if (!static_cast<const SvxShadowedItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1159 continue;
1161 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1163 break;
1164 case EE_CHAR_KERNING:
1166 if (!static_cast<const SvxKerningItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1167 continue;
1169 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1171 break;
1172 case EE_CHAR_PAIRKERNING:
1174 if (!static_cast<const SvxAutoKernItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1175 continue;
1177 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1179 break;
1180 case EE_CHAR_FONTWIDTH:
1182 if (!static_cast<const SvxCharScaleWidthItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1183 continue;
1185 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1187 break;
1188 case EE_CHAR_ESCAPEMENT:
1190 if (!static_cast<const SvxEscapementItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1191 continue;
1193 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1195 break;
1196 case EE_CHAR_EMPHASISMARK:
1198 if (!static_cast<const SvxEmphasisMarkItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1199 continue;
1201 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1203 break;
1204 case EE_CHAR_LANGUAGE:
1205 case EE_CHAR_LANGUAGE_CJK:
1206 case EE_CHAR_LANGUAGE_CTL:
1208 if (!static_cast<const SvxLanguageItem*>(p)->QueryValue(aAny, pEntry->mnFlag))
1209 continue;
1211 rPropStates.push_back(XMLPropertyState(nIndex, aAny));
1213 break;
1214 default:
1215 continue;
1219 return pField;
1224 void ScXMLExport::ExportCellTextAutoStyles(sal_Int32 nTable)
1226 if (!ValidTab(nTable))
1227 return;
1229 rtl::Reference<XMLPropertySetMapper> xMapper = GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
1230 rtl::Reference<SvXMLAutoStylePoolP> xStylePool = GetAutoStylePool();
1231 const ScXMLEditAttributeMap& rAttrMap = GetEditAttributeMap();
1233 sc::EditTextIterator aIter(*pDoc, nTable);
1234 sal_Int32 nCellCount = 0;
1235 for (const EditTextObject* pEdit = aIter.first(); pEdit; pEdit = aIter.next(), ++nCellCount)
1237 std::vector<editeng::Section> aAttrs;
1238 pEdit->GetAllSections(aAttrs);
1239 if (aAttrs.empty())
1240 continue;
1242 std::vector<editeng::Section>::const_iterator itSec = aAttrs.begin(), itSecEnd = aAttrs.end();
1243 for (; itSec != itSecEnd; ++itSec)
1245 const std::vector<const SfxPoolItem*>& rSecAttrs = itSec->maAttributes;
1246 if (rSecAttrs.empty())
1247 // No formats applied to this section. Skip it.
1248 continue;
1250 std::vector<XMLPropertyState> aPropStates;
1251 toXMLPropertyStates(aPropStates, rSecAttrs, xMapper, rAttrMap);
1252 if (!aPropStates.empty())
1253 xStylePool->Add(XML_STYLE_FAMILY_TEXT_TEXT, OUString(), aPropStates, false);
1257 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCellCount);
1260 void ScXMLExport::WriteRowContent()
1262 ScMyRowFormatRange aRange;
1263 sal_Int32 nIndex(-1);
1264 #if OSL_DEBUG_LEVEL > 0
1265 sal_Int32 nPrevCol(0);
1266 #endif
1267 sal_Int32 nCols(0);
1268 sal_Int32 nPrevValidationIndex(-1);
1269 bool bIsAutoStyle(true);
1270 bool bIsFirst(true);
1271 while (pRowFormatRanges->GetNext(aRange))
1273 #if OSL_DEBUG_LEVEL > 0
1274 OSL_ENSURE(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn)), "here are some columns missing");
1275 #endif
1276 if (bIsFirst)
1278 nIndex = aRange.nIndex;
1279 nPrevValidationIndex = aRange.nValidationIndex;
1280 bIsAutoStyle = aRange.bIsAutoStyle;
1281 nCols = aRange.nRepeatColumns;
1282 bIsFirst = false;
1283 #if OSL_DEBUG_LEVEL > 0
1284 nPrevCol = aRange.nStartColumn;
1285 #endif
1287 else
1289 if (((aRange.nIndex == nIndex && aRange.bIsAutoStyle == bIsAutoStyle) ||
1290 (aRange.nIndex == nIndex && nIndex == -1)) &&
1291 nPrevValidationIndex == aRange.nValidationIndex)
1292 nCols += aRange.nRepeatColumns;
1293 else
1295 if (nIndex != -1)
1296 AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
1297 if (nPrevValidationIndex > -1)
1298 AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
1299 if (nCols > 1)
1301 OUStringBuffer aBuf;
1302 ::sax::Converter::convertNumber(aBuf, nCols);
1303 AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
1305 SvXMLElementExport aElemC(*this, sElemCell, true, true);
1306 nIndex = aRange.nIndex;
1307 bIsAutoStyle = aRange.bIsAutoStyle;
1308 nCols = aRange.nRepeatColumns;
1309 nPrevValidationIndex = aRange.nValidationIndex;
1310 #if OSL_DEBUG_LEVEL > 0
1311 nPrevCol = aRange.nStartColumn;
1312 #endif
1316 if (!bIsFirst)
1318 table::CellAddress aCellAddress;
1319 if (nIndex != -1)
1320 AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
1321 if (nPrevValidationIndex > -1)
1322 AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
1323 if (nCols > 1)
1325 OUStringBuffer aBuf;
1326 ::sax::Converter::convertNumber(aBuf, nCols);
1327 AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
1329 SvXMLElementExport aElemC(*this, sElemCell, true, true);
1333 void ScXMLExport::WriteRowStartTag(
1334 const sal_Int32 nIndex, const sal_Int32 nEqualRows,
1335 bool bHidden, bool bFiltered)
1337 AddAttribute(sAttrStyleName, *pRowStyles->GetStyleNameByIndex(nIndex));
1338 if (bHidden)
1340 if (bFiltered)
1341 AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_FILTER);
1342 else
1343 AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
1345 if (nEqualRows > 1)
1347 OUStringBuffer aBuf;
1348 ::sax::Converter::convertNumber(aBuf, nEqualRows);
1349 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aBuf.makeStringAndClear());
1352 StartElement( sElemRow, true);
1355 void ScXMLExport::OpenHeaderRows()
1357 StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, true);
1358 bRowHeaderOpen = true;
1361 void ScXMLExport::CloseHeaderRows()
1363 EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, true);
1366 void ScXMLExport::OpenNewRow(
1367 const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEqualRows,
1368 bool bHidden, bool bFiltered)
1370 nOpenRow = nStartRow;
1371 if (pGroupRows->IsGroupStart(nStartRow))
1373 if (bHasRowHeader && bRowHeaderOpen)
1374 CloseHeaderRows();
1375 pGroupRows->OpenGroups(nStartRow);
1376 if (bHasRowHeader && bRowHeaderOpen)
1377 OpenHeaderRows();
1379 if (bHasRowHeader && !bRowHeaderOpen && nStartRow >= aRowHeaderRange.StartRow && nStartRow <= aRowHeaderRange.EndRow)
1381 if (nStartRow == aRowHeaderRange.StartRow)
1382 OpenHeaderRows();
1383 sal_Int32 nEquals;
1384 if (aRowHeaderRange.EndRow < nStartRow + nEqualRows - 1)
1385 nEquals = aRowHeaderRange.EndRow - nStartRow + 1;
1386 else
1387 nEquals = nEqualRows;
1388 WriteRowStartTag(nIndex, nEquals, bHidden, bFiltered);
1389 nOpenRow = nStartRow + nEquals - 1;
1390 if (nEquals < nEqualRows)
1392 CloseRow(nStartRow + nEquals - 1);
1393 WriteRowStartTag(nIndex, nEqualRows - nEquals, bHidden, bFiltered);
1394 nOpenRow = nStartRow + nEqualRows - 1;
1397 else
1398 WriteRowStartTag(nIndex, nEqualRows, bHidden, bFiltered);
1401 void ScXMLExport::OpenAndCloseRow(
1402 const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEqualRows,
1403 bool bHidden, bool bFiltered)
1405 OpenNewRow(nIndex, nStartRow, nEqualRows, bHidden, bFiltered);
1406 WriteRowContent();
1407 CloseRow(nStartRow + nEqualRows - 1);
1408 pRowFormatRanges->Clear();
1411 void ScXMLExport::OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow, ScXMLCachedRowAttrAccess& rRowAttr)
1413 if (nRepeatRow > 1)
1415 sal_Int32 nPrevIndex(0), nIndex;
1416 bool bPrevHidden = false;
1417 bool bPrevFiltered = false;
1418 bool bHidden = false;
1419 bool bFiltered = false;
1420 sal_Int32 nEqualRows(1);
1421 sal_Int32 nEndRow(nStartRow + nRepeatRow);
1422 sal_Int32 nRow;
1423 for (nRow = nStartRow; nRow < nEndRow; ++nRow)
1425 if (nRow == nStartRow)
1427 nPrevIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
1428 if (pDoc)
1430 bPrevHidden = rRowAttr.rowHidden(nTable, nRow);
1431 bPrevFiltered = rRowAttr.rowFiltered(nTable, nRow);
1434 else
1436 nIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
1437 if (pDoc)
1439 bHidden = rRowAttr.rowHidden(nTable, nRow);
1440 bFiltered = rRowAttr.rowFiltered(nTable, nRow);
1442 if (nIndex == nPrevIndex && bHidden == bPrevHidden && bFiltered == bPrevFiltered &&
1443 !(bHasRowHeader && ((nRow == aRowHeaderRange.StartRow) || (nRow - 1 == aRowHeaderRange.EndRow))) &&
1444 !(pGroupRows->IsGroupStart(nRow)) &&
1445 !(pGroupRows->IsGroupEnd(nRow - 1)))
1446 ++nEqualRows;
1447 else
1449 if (nRow < nEndRow)
1451 ScRowFormatRanges* pTempRowFormatRanges = new ScRowFormatRanges(pRowFormatRanges);
1452 OpenAndCloseRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered);
1453 delete pRowFormatRanges;
1454 pRowFormatRanges = pTempRowFormatRanges;
1456 else
1457 OpenAndCloseRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered);
1458 nEqualRows = 1;
1459 nPrevIndex = nIndex;
1460 bPrevHidden = bHidden;
1461 bPrevFiltered = bFiltered;
1465 OpenNewRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered);
1467 else
1469 sal_Int32 nIndex = pRowStyles->GetStyleNameIndex(nTable, nStartRow);
1470 bool bHidden = false;
1471 bool bFiltered = false;
1472 if (pDoc)
1474 bHidden = rRowAttr.rowHidden(nTable, nStartRow);
1475 bFiltered = rRowAttr.rowFiltered(nTable, nStartRow);
1477 OpenNewRow(nIndex, nStartRow, 1, bHidden, bFiltered);
1479 nOpenRow = nStartRow + nRepeatRow - 1;
1482 void ScXMLExport::CloseRow(const sal_Int32 nRow)
1484 if (nOpenRow > -1)
1486 EndElement(sElemRow, true);
1487 if (bHasRowHeader && nRow == aRowHeaderRange.EndRow)
1489 CloseHeaderRows();
1490 bRowHeaderOpen = false;
1492 if (pGroupRows->IsGroupEnd(nRow))
1494 if (bHasRowHeader && bRowHeaderOpen)
1495 CloseHeaderRows();
1496 pGroupRows->CloseGroups(nRow);
1497 if (bHasRowHeader && bRowHeaderOpen)
1498 OpenHeaderRows();
1501 nOpenRow = -1;
1504 void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow,
1505 const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet)
1507 pRowFormatRanges->Clear();
1508 ScXMLCachedRowAttrAccess aRowAttr(pDoc);
1509 if (nStartRow == nEndRow)
1511 pCellStyles->GetFormatRanges(nStartCol, nEndCol, nStartRow, nSheet, pRowFormatRanges);
1512 if (nOpenRow == - 1)
1513 OpenRow(nSheet, nStartRow, 1, aRowAttr);
1514 WriteRowContent();
1515 pRowFormatRanges->Clear();
1517 else
1519 if (nOpenRow > -1)
1521 pCellStyles->GetFormatRanges(nStartCol, pSharedData->GetLastColumn(nSheet), nStartRow, nSheet, pRowFormatRanges);
1522 WriteRowContent();
1523 CloseRow(nStartRow);
1524 sal_Int32 nRows(1);
1525 sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
1526 while (nRows < nTotalRows)
1528 pRowFormatRanges->Clear();
1529 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
1530 sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
1531 OSL_ENSURE(nMaxRows, "something wents wrong");
1532 if (nMaxRows >= nTotalRows - nRows)
1534 OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows, aRowAttr);
1535 nRows += nTotalRows - nRows;
1537 else
1539 OpenRow(nSheet, nStartRow + nRows, nMaxRows, aRowAttr);
1540 nRows += nMaxRows;
1542 if (!pRowFormatRanges->GetSize())
1543 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
1544 WriteRowContent();
1545 CloseRow(nStartRow + nRows - 1);
1547 if (nTotalRows == 1)
1548 CloseRow(nStartRow);
1549 OpenRow(nSheet, nEndRow, 1, aRowAttr);
1550 pRowFormatRanges->Clear();
1551 pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
1552 WriteRowContent();
1554 else
1556 sal_Int32 nRows(0);
1557 sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
1558 while (nRows < nTotalRows)
1560 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
1561 sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
1562 if (nMaxRows >= nTotalRows - nRows)
1564 OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows, aRowAttr);
1565 nRows += nTotalRows - nRows;
1567 else
1569 OpenRow(nSheet, nStartRow + nRows, nMaxRows, aRowAttr);
1570 nRows += nMaxRows;
1572 if (!pRowFormatRanges->GetSize())
1573 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
1574 WriteRowContent();
1575 CloseRow(nStartRow + nRows - 1);
1577 OpenRow(nSheet, nEndRow, 1, aRowAttr);
1578 pRowFormatRanges->Clear();
1579 pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
1580 WriteRowContent();
1585 void ScXMLExport::GetColumnRowHeader(bool& rHasColumnHeader, table::CellRangeAddress& rColumnHeaderRange,
1586 bool& rHasRowHeader, table::CellRangeAddress& rRowHeaderRange,
1587 OUString& rPrintRanges) const
1589 uno::Reference <sheet::XPrintAreas> xPrintAreas (xCurrentTable, uno::UNO_QUERY);
1590 if (xPrintAreas.is())
1592 rHasRowHeader = xPrintAreas->getPrintTitleRows();
1593 rHasColumnHeader = xPrintAreas->getPrintTitleColumns();
1594 rRowHeaderRange = xPrintAreas->getTitleRows();
1595 rColumnHeaderRange = xPrintAreas->getTitleColumns();
1596 uno::Sequence< table::CellRangeAddress > aRangeList( xPrintAreas->getPrintAreas() );
1597 ScRangeStringConverter::GetStringFromRangeList( rPrintRanges, aRangeList, pDoc, FormulaGrammar::CONV_OOO );
1601 void ScXMLExport::FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups)
1603 size_t nDepth = pFields->GetDepth();
1604 for (size_t i = 0; i < nDepth; ++i)
1606 size_t nFields = pFields->GetCount(i);
1607 for (size_t j = 0; j < nFields; ++j)
1609 ScMyColumnRowGroup aGroup;
1610 const ScOutlineEntry* pEntry = pFields->GetEntry(i, j);
1611 aGroup.nField = pEntry->GetStart();
1612 aGroup.nLevel = static_cast<sal_Int16>(i);
1613 aGroup.bDisplay = !(pEntry->IsHidden());
1614 pGroups->AddGroup(aGroup, pEntry->GetEnd());
1617 if (nDepth)
1618 pGroups->Sort();
1621 void ScXMLExport::FillColumnRowGroups()
1623 if (pDoc)
1625 ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable( static_cast<SCTAB>(nCurrentTable), false );
1626 if(pOutlineTable)
1628 ScOutlineArray& rCols(pOutlineTable->GetColArray());
1629 ScOutlineArray& rRows(pOutlineTable->GetRowArray());
1630 FillFieldGroup(&rCols, pGroupColumns);
1631 FillFieldGroup(&rRows, pGroupRows);
1632 pSharedData->SetLastColumn(nCurrentTable, pGroupColumns->GetLast());
1633 pSharedData->SetLastRow(nCurrentTable, pGroupRows->GetLast());
1638 void ScXMLExport::SetBodyAttributes()
1640 if (pDoc && pDoc->IsDocProtected())
1642 AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE);
1643 OUStringBuffer aBuffer;
1644 uno::Sequence<sal_Int8> aPassHash;
1645 ScPasswordHash eHashUsed = PASSHASH_UNSPECIFIED;
1646 const ScDocProtection* p = pDoc->GetDocProtection();
1647 if (p)
1649 if (p->hasPasswordHash(PASSHASH_SHA1))
1651 aPassHash = p->getPasswordHash(PASSHASH_SHA1);
1652 eHashUsed = PASSHASH_SHA1;
1654 else if (p->hasPasswordHash(PASSHASH_XL, PASSHASH_SHA1))
1656 aPassHash = p->getPasswordHash(PASSHASH_XL, PASSHASH_SHA1);
1657 eHashUsed = PASSHASH_XL;
1660 ::sax::Converter::encodeBase64(aBuffer, aPassHash);
1661 if (!aBuffer.isEmpty())
1663 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
1664 if ( getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
1666 if (eHashUsed == PASSHASH_XL)
1668 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM,
1669 ScPassHashHelper::getHashURI(PASSHASH_XL));
1670 if (getDefaultVersion() > SvtSaveOptions::ODFVER_012)
1671 AddAttribute(XML_NAMESPACE_LO_EXT, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2,
1672 ScPassHashHelper::getHashURI(PASSHASH_SHA1));
1674 else if (eHashUsed == PASSHASH_SHA1)
1675 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM,
1676 ScPassHashHelper::getHashURI(PASSHASH_SHA1));
1682 static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput,
1683 const uno::Reference< io::XOutputStream >& xOutput,
1684 sal_Int32 nCount )
1686 const sal_Int32 nBufSize = 16*1024;
1687 uno::Sequence<sal_Int8> aSequence(nBufSize);
1689 sal_Int32 nRemaining = nCount;
1690 bool bFirst = true;
1692 while ( nRemaining > 0 )
1694 sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) );
1695 if (bFirst)
1697 // safety check: Make sure the copied part actually points to the start of an element
1698 if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') )
1700 return false; // abort and set an error
1702 bFirst = false;
1704 if (nRead == nRemaining)
1706 // safety check: Make sure the copied part also ends at the end of an element
1707 if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') )
1709 return false; // abort and set an error
1713 if ( nRead == nBufSize )
1715 xOutput->writeBytes( aSequence );
1716 nRemaining -= nRead;
1718 else
1720 if ( nRead > 0 )
1722 uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead );
1723 xOutput->writeBytes( aTempBuf );
1725 nRemaining = 0;
1728 return true; // successful
1731 static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip )
1733 // skipBytes in zip stream is implemented as reading.
1734 // For now, split into several calls to avoid allocating a large buffer.
1735 // Later, skipBytes should be changed.
1737 const sal_Int32 nMaxSize = 32*1024;
1739 if ( nBytesToSkip > 0 )
1741 sal_Int32 nRemaining = nBytesToSkip;
1742 while ( nRemaining > 0 )
1744 sal_Int32 nSkip = std::min( nRemaining, nMaxSize );
1745 xInput->skipBytes( nSkip );
1746 nRemaining -= nSkip;
1751 void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd )
1753 uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler();
1754 uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY );
1755 if ( xDestSource.is() )
1757 uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream();
1758 uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY );
1759 if ( xDestSeek.is() )
1761 // temporary: set same stream again to clear buffer
1762 xDestSource->setOutputStream( xDestStream );
1764 if ( getExportFlags() & SvXMLExportFlags::PRETTY )
1766 const OString aOutStr("\n ");
1767 uno::Sequence<sal_Int8> aOutSeq( reinterpret_cast<sal_Int8 const *>(aOutStr.getStr()), aOutStr.getLength() );
1768 xDestStream->writeBytes( aOutSeq );
1771 rNewStart = (sal_Int32)xDestSeek->getPosition();
1773 if ( nStartOffset > nSourceStreamPos )
1774 lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos );
1776 if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) )
1778 // If copying went wrong, set an error.
1779 // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
1781 uno::Sequence<OUString> aEmptySeq;
1782 SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
1784 nSourceStreamPos = nEndOffset;
1786 rNewEnd = (sal_Int32)xDestSeek->getPosition();
1791 const ScXMLEditAttributeMap& ScXMLExport::GetEditAttributeMap() const
1793 if (!mpEditAttrMap)
1794 mpEditAttrMap.reset(new ScXMLEditAttributeMap);
1795 return *mpEditAttrMap;
1798 void ScXMLExport::_ExportContent()
1800 nCurrentTable = 0;
1801 if (!pSharedData)
1803 sal_Int32 nTableCount(0);
1804 sal_Int32 nShapesCount(0);
1805 CollectSharedData(nTableCount, nShapesCount);
1806 OSL_FAIL("no shared data setted");
1807 if (!pSharedData)
1808 return;
1810 ScXMLExportDatabaseRanges aExportDatabaseRanges(*this);
1811 if (!GetModel().is())
1812 return;
1814 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
1815 if ( !xSpreadDoc.is() )
1816 return;
1818 ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
1819 if (pSheetData)
1820 pSheetData->ResetSaveEntries();
1822 uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
1823 if ( xIndex.is() )
1825 //_GetNamespaceMap().ClearQNamesCache();
1826 pChangeTrackingExportHelper->CollectAndWriteChanges();
1827 WriteCalculationSettings(xSpreadDoc);
1828 sal_Int32 nTableCount(xIndex->getCount());
1829 ScMyAreaLinksContainer aAreaLinks;
1830 GetAreaLinks( aAreaLinks );
1831 ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges());
1832 ScMyDetectiveOpContainer aDetectiveOpContainer;
1833 GetDetectiveOpList( aDetectiveOpContainer );
1835 pCellStyles->Sort();
1836 pMergedRangesContainer->Sort();
1837 pSharedData->GetDetectiveObjContainer()->Sort();
1839 mpCellsItr->Clear();
1840 mpCellsItr->SetShapes( pSharedData->GetShapesContainer() );
1841 mpCellsItr->SetNoteShapes( pSharedData->GetNoteShapes() );
1842 mpCellsItr->SetMergedRanges( pMergedRangesContainer );
1843 mpCellsItr->SetAreaLinks( &aAreaLinks );
1844 mpCellsItr->SetEmptyDatabaseRanges( &aEmptyRanges );
1845 mpCellsItr->SetDetectiveObj( pSharedData->GetDetectiveObjContainer() );
1846 mpCellsItr->SetDetectiveOp( &aDetectiveOpContainer );
1848 if (nTableCount > 0)
1849 pValidationsContainer->WriteValidations(*this);
1850 WriteTheLabelRanges( xSpreadDoc );
1851 for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
1853 sal_Int32 nStartOffset = -1;
1854 sal_Int32 nEndOffset = -1;
1855 if (pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) && !pDoc->GetChangeTrack())
1856 pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset );
1858 if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() )
1860 sal_Int32 nNewStart = -1;
1861 sal_Int32 nNewEnd = -1;
1862 CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd );
1864 // store position of copied sheet in output
1865 pSheetData->AddSavePos( nTable, nNewStart, nNewEnd );
1867 // skip iterator entries for this sheet
1868 mpCellsItr->SkipTable(static_cast<SCTAB>(nTable));
1870 else
1872 uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
1873 WriteTable(nTable, xTable);
1875 IncrementProgressBar(false);
1878 WriteExternalRefCaches();
1879 WriteNamedExpressions();
1880 WriteDataStream();
1881 aExportDatabaseRanges.WriteDatabaseRanges();
1882 ScXMLExportDataPilot aExportDataPilot(*this);
1883 aExportDataPilot.WriteDataPilots(xSpreadDoc);
1884 WriteConsolidation();
1885 ScXMLExportDDELinks aExportDDELinks(*this);
1886 aExportDDELinks.WriteDDELinks(xSpreadDoc);
1887 IncrementProgressBar(true, 0);
1888 GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
1891 void ScXMLExport::_ExportStyles( bool bUsed )
1893 if (!pSharedData)
1895 sal_Int32 nTableCount(0);
1896 sal_Int32 nShapesCount(0);
1897 CollectSharedData(nTableCount, nShapesCount);
1899 ScXMLStyleExport aStylesExp(*this, OUString(), GetAutoStylePool().get());
1900 if (GetModel().is())
1902 uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
1903 if (xMultiServiceFactory.is())
1905 uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance("com.sun.star.sheet.Defaults"), uno::UNO_QUERY);
1906 if (xProperties.is())
1907 aStylesExp.exportDefaultStyle(xProperties, OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME), xCellStylesExportPropertySetMapper);
1908 if (pSharedData->HasShapes())
1910 GetShapeExport()->ExportGraphicDefaults();
1913 uno::Reference <style::XStyleFamiliesSupplier> xStyleFamiliesSupplier (GetModel(), uno::UNO_QUERY);
1914 if (xStyleFamiliesSupplier.is())
1916 uno::Reference <container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies());
1917 if (xStylesFamilies.is())
1919 uno::Reference <container::XIndexAccess> xCellStyles(xStylesFamilies->getByName("CellStyles"), uno::UNO_QUERY);
1920 if (xCellStyles.is())
1922 sal_Int32 nCount(xCellStyles->getCount());
1923 OUString sNumberFormat(SC_UNONAME_NUMFMT);
1924 for (sal_Int32 i = 0; i < nCount; ++i)
1926 uno::Reference <beans::XPropertySet> xCellProperties(xCellStyles->getByIndex(i), uno::UNO_QUERY);
1927 if (xCellProperties.is())
1929 sal_Int32 nNumberFormat = 0;
1930 if (xCellProperties->getPropertyValue(sNumberFormat) >>= nNumberFormat)
1931 addDataStyle(nNumberFormat);
1938 exportDataStyles();
1940 aStylesExp.exportStyleFamily(OUString("CellStyles"),
1941 OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME), xCellStylesExportPropertySetMapper, false, XML_STYLE_FAMILY_TABLE_CELL);
1943 SvXMLExport::_ExportStyles(bUsed);
1946 void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties,
1947 const uno::Reference<sheet::XSpreadsheet>& xTable,
1948 sal_Int32 nTable, const OUString* pOldName)
1950 //! pass xCellRanges instead
1951 uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY );
1953 OUString SC_SCELLPREFIX(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX);
1954 OUString SC_NUMBERFORMAT(SC_UNONAME_NUMFMT);
1956 OUString sStyleName;
1957 sal_Int32 nNumberFormat(-1);
1958 sal_Int32 nValidationIndex(-1);
1959 std::vector< XMLPropertyState > xPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties ));
1960 std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
1961 std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
1962 sal_Int32 nCount(0);
1963 while (aItr != aEndItr)
1965 if (aItr->mnIndex != -1)
1967 switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex))
1969 case CTF_SC_VALIDATION :
1971 pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex);
1972 // this is not very slow, because it is most the last property or
1973 // if it is not the last property it is the property before the last property,
1974 // so in the worst case only one property has to be copied, but in the best case no
1975 // property has to be copied
1976 aItr = xPropStates.erase(aItr);
1977 aEndItr = xPropStates.end(); // old aEndItr is invalidated!
1979 break;
1980 case CTF_SC_CELLSTYLE :
1982 aItr->maValue >>= sStyleName;
1983 aItr->mnIndex = -1;
1984 ++aItr;
1985 ++nCount;
1987 break;
1988 case CTF_SC_NUMBERFORMAT :
1990 if (aItr->maValue >>= nNumberFormat)
1991 addDataStyle(nNumberFormat);
1992 ++aItr;
1993 ++nCount;
1995 break;
1996 default:
1998 ++aItr;
1999 ++nCount;
2001 break;
2004 else
2006 ++aItr;
2007 ++nCount;
2010 if (nCount == 1) // this is the CellStyle and should be removed if alone
2011 xPropStates.clear();
2012 if (nNumberFormat == -1)
2013 xProperties->getPropertyValue(SC_NUMBERFORMAT) >>= nNumberFormat;
2014 if (!sStyleName.isEmpty())
2016 if (!xPropStates.empty())
2018 sal_Int32 nIndex;
2019 if (pOldName)
2021 if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
2023 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, *pOldName);
2024 // add to pCellStyles, so the name is found for normal sheets
2025 OUString* pTemp(new OUString(*pOldName));
2026 if (!pCellStyles->AddStyleName(pTemp, nIndex))
2027 delete pTemp;
2030 else
2032 OUString sName;
2033 bool bIsAutoStyle(true);
2034 if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
2036 OUString* pTemp(new OUString(sName));
2037 if (!pCellStyles->AddStyleName(pTemp, nIndex))
2038 delete pTemp;
2040 else
2041 nIndex = pCellStyles->GetIndexOfStyleName(sName, SC_SCELLPREFIX, bIsAutoStyle);
2043 uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
2044 table::CellRangeAddress* pAddresses(aAddresses.getArray());
2045 bool bGetMerge(true);
2046 for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
2048 pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
2049 pSharedData->SetLastRow(nTable, pAddresses->EndRow);
2050 pCellStyles->AddRangeStyleName(*pAddresses, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat);
2051 if (bGetMerge)
2052 bGetMerge = GetMerged(pAddresses, xTable);
2056 else
2058 OUString* pTemp(new OUString(EncodeStyleName(sStyleName)));
2059 sal_Int32 nIndex(0);
2060 if (!pCellStyles->AddStyleName(pTemp, nIndex, false))
2062 delete pTemp;
2063 pTemp = NULL;
2065 if ( !pOldName )
2067 uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
2068 table::CellRangeAddress* pAddresses(aAddresses.getArray());
2069 bool bGetMerge(true);
2070 for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
2072 if (bGetMerge)
2073 bGetMerge = GetMerged(pAddresses, xTable);
2074 pCellStyles->AddRangeStyleName(*pAddresses, nIndex, false, nValidationIndex, nNumberFormat);
2075 if( sStyleName != "Default" || nValidationIndex != -1 )
2077 pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
2078 pSharedData->SetLastRow(nTable, pAddresses->EndRow);
2086 void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties,
2087 const OUString* pOldName, sal_Int32& rIndex, bool& rIsVisible)
2089 OUString SC_SCOLUMNPREFIX(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX);
2091 std::vector<XMLPropertyState> xPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties));
2092 if(!xPropStates.empty())
2094 std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
2095 std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
2096 while (aItr != aEndItr)
2098 if (xColumnStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex) == CTF_SC_ISVISIBLE)
2100 aItr->maValue >>= rIsVisible;
2101 break;
2103 ++aItr;
2106 OUString sParent;
2107 if (pOldName)
2109 if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
2111 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_COLUMN, *pOldName);
2112 // add to pColumnStyles, so the name is found for normal sheets
2113 OUString* pTemp(new OUString(*pOldName));
2114 rIndex = pColumnStyles->AddStyleName(pTemp);
2117 else
2119 OUString sName;
2120 if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
2122 OUString* pTemp(new OUString(sName));
2123 rIndex = pColumnStyles->AddStyleName(pTemp);
2125 else
2126 rIndex = pColumnStyles->GetIndexOfStyleName(sName, SC_SCOLUMNPREFIX);
2131 void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties,
2132 const OUString* pOldName, sal_Int32& rIndex)
2134 OUString SC_SROWPREFIX(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX);
2136 std::vector<XMLPropertyState> xPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties));
2137 if(!xPropStates.empty())
2139 OUString sParent;
2140 if (pOldName)
2142 if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
2144 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_ROW, *pOldName);
2145 // add to pRowStyles, so the name is found for normal sheets
2146 OUString* pTemp(new OUString(*pOldName));
2147 rIndex = pRowStyles->AddStyleName(pTemp);
2150 else
2152 OUString sName;
2153 if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
2155 OUString* pTemp(new OUString(sName));
2156 rIndex = pRowStyles->AddStyleName(pTemp);
2158 else
2159 rIndex = pRowStyles->GetIndexOfStyleName(sName, SC_SROWPREFIX);
2164 static uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> xEnumAccess, sal_Int32 nIndex )
2166 uno::Any aRet;
2167 uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() );
2170 sal_Int32 nSkip = nIndex;
2171 while ( nSkip > 0 )
2173 (void) xEnum->nextElement();
2174 --nSkip;
2176 aRet = xEnum->nextElement();
2178 catch (container::NoSuchElementException&)
2180 // leave aRet empty
2182 return aRet;
2185 void ScXMLExport::_ExportAutoStyles()
2187 if (!GetModel().is())
2188 return;
2190 Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
2191 if (!xSpreadDoc.is())
2192 return;
2194 Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
2195 if (!xIndex.is())
2196 return;
2198 if (getExportFlags() & SvXMLExportFlags::CONTENT)
2200 // re-create automatic styles with old names from stored data
2201 ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
2202 if (pSheetData && pDoc)
2204 // formulas have to be calculated now, to detect changed results
2205 // (during normal save, they will be calculated anyway)
2206 SCTAB nTabCount = pDoc->GetTableCount();
2207 for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
2208 if (pDoc->IsStreamValid(nTab))
2209 pDoc->InterpretDirtyCells(ScRange(0, 0, nTab, MAXCOL, MAXROW, nTab));
2211 // stored cell styles
2212 const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles();
2213 std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin();
2214 std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end();
2215 while (aCellIter != aCellEnd)
2217 ScAddress aPos = aCellIter->maCellPos;
2218 sal_Int32 nTable = aPos.Tab();
2219 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2220 if (bCopySheet)
2222 Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2223 Reference <beans::XPropertySet> xProperties(
2224 xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY );
2226 AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName);
2228 ++aCellIter;
2231 // stored column styles
2232 const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles();
2233 std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin();
2234 std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end();
2235 while (aColumnIter != aColumnEnd)
2237 ScAddress aPos = aColumnIter->maCellPos;
2238 sal_Int32 nTable = aPos.Tab();
2239 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2240 if (bCopySheet)
2242 Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2243 Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
2244 Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY);
2246 sal_Int32 nIndex(-1);
2247 bool bIsVisible(true);
2248 AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible );
2250 ++aColumnIter;
2253 // stored row styles
2254 const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles();
2255 std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin();
2256 std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end();
2257 while (aRowIter != aRowEnd)
2259 ScAddress aPos = aRowIter->maCellPos;
2260 sal_Int32 nTable = aPos.Tab();
2261 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2262 if (bCopySheet)
2264 Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2265 Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
2266 Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY);
2268 sal_Int32 nIndex(-1);
2269 AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex );
2271 ++aRowIter;
2274 // stored table styles
2275 const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles();
2276 std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin();
2277 std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end();
2278 while (aTableIter != aTableEnd)
2280 ScAddress aPos = aTableIter->maCellPos;
2281 sal_Int32 nTable = aPos.Tab();
2282 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2283 if (bCopySheet)
2285 //! separate method AddStyleFromTable needed?
2286 Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2287 if (xTableProperties.is())
2289 std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
2290 OUString sParent;
2291 OUString sName( aTableIter->maName );
2292 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
2293 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName);
2296 ++aTableIter;
2299 // stored styles for notes
2301 rtl::Reference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this );
2302 GetShapeExport(); // make sure the graphics styles family is added
2304 const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles();
2305 std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin();
2306 std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end();
2307 while (aNoteIter != aNoteEnd)
2309 ScAddress aPos = aNoteIter->maCellPos;
2310 SCTAB nTable = aPos.Tab();
2311 bool bCopySheet = pDoc->IsStreamValid( nTable );
2312 if (bCopySheet)
2314 //! separate method AddStyleFromNote needed?
2316 ScPostIt* pNote = pDoc->GetNote(aPos);
2317 OSL_ENSURE( pNote, "note not found" );
2318 if (pNote)
2320 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2321 // all uno shapes are created anyway in CollectSharedData
2322 Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY );
2323 if (xShapeProperties.is())
2325 if ( !aNoteIter->maStyleName.isEmpty() )
2327 std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties));
2328 OUString sParent;
2329 OUString sName( aNoteIter->maStyleName );
2330 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates);
2331 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName);
2333 if ( !aNoteIter->maTextStyle.isEmpty() )
2335 std::vector<XMLPropertyState> xPropStates(
2336 GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties));
2337 OUString sParent;
2338 OUString sName( aNoteIter->maTextStyle );
2339 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
2340 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
2345 ++aNoteIter;
2348 // note paragraph styles
2350 rtl::Reference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper();
2352 const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles();
2353 std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin();
2354 std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end();
2355 while (aNoteParaIter != aNoteParaEnd)
2357 ScAddress aPos = aNoteParaIter->maCellPos;
2358 SCTAB nTable = aPos.Tab();
2359 bool bCopySheet = pDoc->IsStreamValid( nTable );
2360 if (bCopySheet)
2362 ScPostIt* pNote = pDoc->GetNote( aPos );
2363 OSL_ENSURE( pNote, "note not found" );
2364 if (pNote)
2366 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2367 Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
2368 Reference<beans::XPropertySet> xParaProp(
2369 lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY );
2370 if ( xParaProp.is() )
2372 std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp));
2373 OUString sParent;
2374 OUString sName( aNoteParaIter->maName );
2375 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
2376 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
2380 ++aNoteParaIter;
2383 // note text styles
2385 rtl::Reference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
2387 const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles();
2388 std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin();
2389 std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end();
2390 while (aNoteTextIter != aNoteTextEnd)
2392 ScAddress aPos = aNoteTextIter->maCellPos;
2393 SCTAB nTable = aPos.Tab();
2394 bool bCopySheet = pDoc->IsStreamValid( nTable );
2395 if (bCopySheet)
2397 ScPostIt* pNote = pDoc->GetNote( aPos );
2398 OSL_ENSURE( pNote, "note not found" );
2399 if (pNote)
2401 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2402 Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
2403 Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
2404 ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp );
2405 if (pCursor)
2407 pCursor->SetSelection( aNoteTextIter->maSelection );
2409 std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
2410 OUString sParent;
2411 OUString sName( aNoteTextIter->maName );
2412 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
2413 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
2417 ++aNoteTextIter;
2420 // stored text styles
2422 const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles();
2423 std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin();
2424 std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end();
2425 while (aTextIter != aTextEnd)
2427 ScAddress aPos = aTextIter->maCellPos;
2428 sal_Int32 nTable = aPos.Tab();
2429 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2430 if (bCopySheet)
2432 //! separate method AddStyleFromText needed?
2433 //! cache sheet object
2435 Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2436 Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY);
2437 Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
2438 ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp );
2439 if (pCursor)
2441 pCursor->SetSelection( aTextIter->maSelection );
2443 std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
2444 OUString sParent;
2445 OUString sName( aTextIter->maName );
2446 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
2447 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
2450 ++aTextIter;
2454 ExportExternalRefCacheStyles();
2456 if (!pSharedData)
2458 sal_Int32 nTableCount(0);
2459 sal_Int32 nShapesCount(0);
2460 CollectSharedData(nTableCount, nShapesCount);
2462 sal_Int32 nTableCount(xIndex->getCount());
2463 pCellStyles->AddNewTable(nTableCount - 1);
2464 CollectShapesAutoStyles(nTableCount);
2465 for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable, IncrementProgressBar(false))
2467 Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2468 if (!xTable.is())
2469 continue;
2471 // table styles array must be complete, including copied tables - Add should find the stored style
2472 Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
2473 if (xTableProperties.is())
2475 std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
2476 if(!xPropStates.empty())
2478 OUString sParent;
2479 OUString sName;
2480 GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
2481 aTableStyles.push_back(sName);
2485 // collect other auto-styles only for non-copied sheets
2486 Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY );
2487 if ( xCellFormatRanges.is() )
2489 Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges());
2490 if (xFormatRangesIndex.is())
2492 sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount());
2493 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount);
2494 for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange)
2496 Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY);
2497 if (xCellRanges.is())
2499 Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY);
2500 if (xProperties.is())
2502 AddStyleFromCells(xProperties, xTable, nTable, NULL);
2503 IncrementProgressBar(false);
2509 Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY);
2510 if (xColumnRowRange.is())
2512 if (pDoc)
2514 pDoc->SyncColRowFlags();
2515 Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
2516 if (xTableColumns.is())
2518 sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable)));
2519 pSharedData->SetLastColumn(nTable, nColumns);
2520 table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
2521 if (aCellAddress.EndColumn > nColumns)
2523 ++nColumns;
2524 pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn);
2526 else
2527 pColumnStyles->AddNewTable(nTable, nColumns);
2528 sal_Int32 nColumn = 0;
2529 while (nColumn <= MAXCOL)
2531 sal_Int32 nIndex(-1);
2532 bool bIsVisible(true);
2533 Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY);
2534 if (xColumnProperties.is())
2536 AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible );
2537 pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible);
2539 sal_Int32 nOld(nColumn);
2540 nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn));
2541 for (sal_Int32 i = nOld + 1; i < nColumn; ++i)
2542 pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
2544 if (aCellAddress.EndColumn > nColumns)
2546 bool bIsVisible(true);
2547 sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible));
2548 for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i)
2549 pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
2552 Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
2553 if (xTableRows.is())
2555 sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable)));
2556 pSharedData->SetLastRow(nTable, nRows);
2558 pRowStyles->AddNewTable(nTable, MAXROW);
2559 sal_Int32 nRow = 0;
2560 while (nRow <= MAXROW)
2562 sal_Int32 nIndex = 0;
2563 Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY);
2564 if(xRowProperties.is())
2566 AddStyleFromRow( xRowProperties, NULL, nIndex );
2567 pRowStyles->AddFieldStyleName(nTable, nRow, nIndex);
2569 sal_Int32 nOld(nRow);
2570 nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow), false);
2571 if (nRow > nOld + 1)
2572 pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1);
2578 ExportCellTextAutoStyles(nTable);
2581 pChangeTrackingExportHelper->CollectAutoStyles();
2583 GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN,
2584 GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
2585 GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW,
2586 GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
2587 GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE,
2588 GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
2589 exportAutoDataStyles();
2590 GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL,
2591 GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
2593 GetShapeExport()->exportAutoStyles();
2594 GetFormExport()->exportAutoStyles( );
2596 if (pDoc)
2598 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
2599 // #i100879# write the table style for cached tables only if there are cached tables
2600 // (same logic as in ExportExternalRefCacheStyles)
2601 if (pRefMgr->hasExternalData())
2603 // Special table style for the external ref cache tables.
2604 AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName);
2605 AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE);
2606 SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, true, true);
2607 AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE);
2608 SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, true, true);
2613 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES)
2615 GetPageExport()->collectAutoStyles(true);
2616 GetPageExport()->exportAutoStyles();
2619 // #i30251#; only write Text Styles once
2621 if ((getExportFlags() & SvXMLExportFlags::CONTENT) || (getExportFlags() & SvXMLExportFlags::MASTERSTYLES))
2622 GetTextParagraphExport()->exportTextAutoStyles();
2625 void ScXMLExport::_ExportMasterStyles()
2627 GetPageExport()->exportMasterStyles( true );
2630 void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > xShape )
2632 // detective objects and notes
2633 if( SvxShape* pShapeImp = SvxShape::getImplementation( xShape ) )
2635 if( SdrObject* pObject = pShapeImp->GetSdrObject() )
2637 // collect note caption objects from all layers (internal or hidden)
2638 if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) )
2640 if(pDoc->GetNote(pCaptData->maStart))
2642 pSharedData->AddNoteObj( xShape, pCaptData->maStart );
2644 // #i60851# When the file is saved while editing a new note,
2645 // the cell is still empty -> last column/row must be updated
2646 OSL_ENSURE( pCaptData->maStart.Tab() == nCurrentTable, "invalid table in object data" );
2647 pSharedData->SetLastColumn( nCurrentTable, pCaptData->maStart.Col() );
2648 pSharedData->SetLastRow( nCurrentTable, pCaptData->maStart.Row() );
2651 // other objects from internal layer only (detective)
2652 else if( pObject->GetLayer() == SC_LAYER_INTERN )
2654 ScDetectiveFunc aDetFunc( pDoc, static_cast<SCTAB>(nCurrentTable) );
2655 ScAddress aPosition;
2656 ScRange aSourceRange;
2657 bool bRedLine;
2658 ScDetectiveObjType eObjType = aDetFunc.GetDetectiveObjectType(
2659 pObject, nCurrentTable, aPosition, aSourceRange, bRedLine );
2660 pSharedData->GetDetectiveObjContainer()->AddObject( eObjType, static_cast<SCTAB>(nCurrentTable), aPosition, aSourceRange, bRedLine );
2666 bool ScXMLExport::GetMerged (const table::CellRangeAddress* pCellAddress,
2667 const uno::Reference <sheet::XSpreadsheet>& xTable)
2669 bool bReady(false);
2670 sal_Int32 nRow(pCellAddress->StartRow);
2671 sal_Int32 nCol(pCellAddress->StartColumn);
2672 sal_Int32 nEndRow(pCellAddress->EndRow);
2673 sal_Int32 nEndCol(pCellAddress->EndColumn);
2674 bool bRowInc(nEndRow > nRow);
2675 while(!bReady && nRow <= nEndRow && nCol <= nEndCol)
2677 uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY);
2678 if (xSheetCellRange.is())
2680 uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange));
2681 if(xCursor.is())
2683 uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
2684 xCursor->collapseToMergedArea();
2685 table::CellRangeAddress aCellAddress2(xCellAddress->getRangeAddress());
2686 if ((aCellAddress2.EndRow > nRow ||
2687 aCellAddress2.EndColumn > nCol) &&
2688 aCellAddress2.StartRow == nRow &&
2689 aCellAddress2.StartColumn == nCol)
2691 pMergedRangesContainer->AddRange(aCellAddress2);
2692 pSharedData->SetLastColumn(aCellAddress2.Sheet, aCellAddress2.EndColumn);
2693 pSharedData->SetLastRow(aCellAddress2.Sheet, aCellAddress2.EndRow);
2695 else
2696 bReady = true;
2699 if (!bReady)
2701 if (bRowInc)
2702 ++nRow;
2703 else
2704 ++nCol;
2707 OSL_ENSURE(!(!bReady && nEndRow > nRow && nEndCol > nCol), "should not be possible");
2708 return !bReady;
2711 bool ScXMLExport::IsMatrix (const ScAddress& aCell,
2712 table::CellRangeAddress& aCellAddress, bool& bIsFirst) const
2714 bIsFirst = false;
2716 ScRange aMatrixRange;
2718 if (pDoc && pDoc->GetMatrixFormulaRange(aCell, aMatrixRange))
2720 ScUnoConversion::FillApiRange( aCellAddress, aMatrixRange );
2721 if ((aCellAddress.StartColumn == aCell.Col() && aCellAddress.StartRow == aCell.Row()) &&
2722 (aCellAddress.EndColumn > aCell.Col() || aCellAddress.EndRow > aCell.Row()))
2724 bIsFirst = true;
2725 return true;
2727 else if (aCellAddress.StartColumn != aCell.Col() || aCellAddress.StartRow != aCell.Row() ||
2728 aCellAddress.EndColumn != aCell.Col() || aCellAddress.EndRow != aCell.Row())
2729 return true;
2730 else
2732 bIsFirst = true;
2733 return true;
2737 return false;
2740 void ScXMLExport::WriteTable(sal_Int32 nTable, const Reference<sheet::XSpreadsheet>& xTable)
2742 if (!xTable.is())
2743 return;
2745 xCurrentTable.set(xTable);
2746 xCurrentTableCellRange.set(xTable, uno::UNO_QUERY);
2747 uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY );
2748 if (!xName.is())
2749 return;
2751 nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
2752 OUString sOUTableName(xName->getName());
2753 AddAttribute(sAttrName, sOUTableName);
2754 AddAttribute(sAttrStyleName, aTableStyles[nTable]);
2756 uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY);
2757 ScTableProtection* pProtect = NULL;
2758 if (xProtectable.is() && xProtectable->isProtected())
2760 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
2761 if (pDoc)
2763 pProtect = pDoc->GetTabProtection(nTable);
2764 if (pProtect)
2766 OUStringBuffer aBuffer;
2767 ScPasswordHash eHashUsed = PASSHASH_UNSPECIFIED;
2768 if (pProtect->hasPasswordHash(PASSHASH_SHA1))
2770 ::sax::Converter::encodeBase64(aBuffer,
2771 pProtect->getPasswordHash(PASSHASH_SHA1));
2772 eHashUsed = PASSHASH_SHA1;
2774 else if (pProtect->hasPasswordHash(PASSHASH_XL, PASSHASH_SHA1))
2776 // Double-hash this by SHA1 on top of the legacy xls hash.
2777 uno::Sequence<sal_Int8> aHash = pProtect->getPasswordHash(PASSHASH_XL, PASSHASH_SHA1);
2778 ::sax::Converter::encodeBase64(aBuffer, aHash);
2779 eHashUsed = PASSHASH_XL;
2781 if (!aBuffer.isEmpty())
2783 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
2784 if ( getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
2786 if (eHashUsed == PASSHASH_XL)
2788 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM,
2789 ScPassHashHelper::getHashURI(PASSHASH_XL));
2790 if (getDefaultVersion() > SvtSaveOptions::ODFVER_012)
2791 AddAttribute(XML_NAMESPACE_LO_EXT, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2,
2792 ScPassHashHelper::getHashURI(PASSHASH_SHA1));
2794 else if (eHashUsed == PASSHASH_SHA1)
2795 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM,
2796 ScPassHashHelper::getHashURI(PASSHASH_SHA1));
2802 OUString sPrintRanges;
2803 table::CellRangeAddress aColumnHeaderRange;
2804 bool bHasColumnHeader;
2805 GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges);
2806 if( !sPrintRanges.isEmpty() )
2807 AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges );
2808 else if (pDoc && !pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable)))
2809 AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE);
2810 SvXMLElementExport aElemT(*this, sElemTab, true, true);
2812 if (pProtect && pProtect->isProtected() && getDefaultVersion() > SvtSaveOptions::ODFVER_012)
2814 if (pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS))
2815 AddAttribute(XML_NAMESPACE_LO_EXT, XML_SELECT_PROTECTED_CELLS, XML_TRUE);
2816 if (pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS))
2817 AddAttribute(XML_NAMESPACE_LO_EXT, XML_SELECT_UNPROTECTED_CELLS, XML_TRUE);
2819 OUString aElemName = GetNamespaceMap().GetQNameByKey(
2820 XML_NAMESPACE_LO_EXT, GetXMLToken(XML_TABLE_PROTECTION));
2822 SvXMLElementExport aElemProtected(*this, aElemName, true, true);
2825 CheckAttrList();
2827 if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) &&
2828 getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
2830 // store sheet events
2831 uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY);
2832 uno::Reference<container::XNameAccess> xEvents(xSupplier->getEvents(), uno::UNO_QUERY);
2833 GetEventExport().ExportExt( xEvents );
2836 WriteTableSource();
2837 WriteScenario();
2838 uno::Reference<drawing::XDrawPage> xDrawPage;
2839 if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is())
2841 ::xmloff::OOfficeFormsExport aForms(*this);
2842 GetFormExport()->exportForms( xDrawPage );
2843 bool bRet(GetFormExport()->seekPage( xDrawPage ));
2844 OSL_ENSURE( bRet, "OFormLayerXMLExport::seekPage failed!" );
2845 (void)bRet; // avoid warning in product version
2847 if (pSharedData->HasDrawPage())
2849 GetShapeExport()->seekShapes(uno::Reference<drawing::XShapes>(pSharedData->GetDrawPage(nTable), uno::UNO_QUERY));
2850 WriteTableShapes();
2852 table::CellRangeAddress aRange(GetEndAddress(xTable, nTable));
2853 pSharedData->SetLastColumn(nTable, aRange.EndColumn);
2854 pSharedData->SetLastRow(nTable, aRange.EndRow);
2855 mpCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable);
2856 pGroupColumns->NewTable();
2857 pGroupRows->NewTable();
2858 FillColumnRowGroups();
2859 if (bHasColumnHeader)
2860 pSharedData->SetLastColumn(nTable, aColumnHeaderRange.EndColumn);
2861 bRowHeaderOpen = false;
2862 if (bHasRowHeader)
2863 pSharedData->SetLastRow(nTable, aRowHeaderRange.EndRow);
2864 pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable),
2865 pSharedData->GetLastColumn(nTable), pCellStyles, pDoc);
2866 pRowFormatRanges->SetColDefaults(&pDefaults->GetColDefaults());
2867 pCellStyles->SetColDefaults(&pDefaults->GetColDefaults());
2868 ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader);
2869 bool bIsFirst(true);
2870 sal_Int32 nEqualCells(0);
2871 ScMyCell aCell;
2872 ScMyCell aPrevCell;
2873 while (mpCellsItr->GetNext(aCell, pCellStyles))
2875 if (bIsFirst)
2877 ExportFormatRanges(0, 0, aCell.maCellAddress.Col()-1, aCell.maCellAddress.Row(), nTable);
2878 aPrevCell = aCell;
2879 bIsFirst = false;
2881 else
2883 if ((aPrevCell.maCellAddress.Row() == aCell.maCellAddress.Row()) &&
2884 (aPrevCell.maCellAddress.Col() + nEqualCells + 1 == aCell.maCellAddress.Col()))
2886 if(IsCellEqual(aPrevCell, aCell))
2887 ++nEqualCells;
2888 else
2890 WriteCell(aPrevCell, nEqualCells);
2891 nEqualCells = 0;
2892 aPrevCell = aCell;
2895 else
2897 WriteCell(aPrevCell, nEqualCells);
2898 ExportFormatRanges(aPrevCell.maCellAddress.Col() + nEqualCells + 1, aPrevCell.maCellAddress.Row(),
2899 aCell.maCellAddress.Col()-1, aCell.maCellAddress.Row(), nTable);
2900 nEqualCells = 0;
2901 aPrevCell = aCell;
2905 if (!bIsFirst)
2907 WriteCell(aPrevCell, nEqualCells);
2908 ExportFormatRanges(aPrevCell.maCellAddress.Col() + nEqualCells + 1, aPrevCell.maCellAddress.Row(),
2909 pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
2911 else
2912 ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
2914 CloseRow(pSharedData->GetLastRow(nTable));
2915 nEqualCells = 0;
2917 if (pDoc)
2919 // Export sheet-local named ranges.
2920 ScRangeName* pRangeName = pDoc->GetRangeName(nTable);
2921 if (pRangeName && !pRangeName->empty())
2923 WriteNamedRange(pRangeName);
2926 if(getDefaultVersion() > SvtSaveOptions::ODFVER_012)
2928 //export new conditional format information
2929 ExportConditionalFormat(nTable);
2935 namespace {
2937 void writeContent(
2938 ScXMLExport& rExport, const OUString& rStyleName, const OUString& rContent, const SvxFieldData* pField )
2940 boost::scoped_ptr<SvXMLElementExport> pElem;
2941 if (!rStyleName.isEmpty())
2943 // Formatted section with automatic style.
2944 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, rStyleName);
2945 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
2946 XML_NAMESPACE_TEXT, GetXMLToken(XML_SPAN));
2947 pElem.reset(new SvXMLElementExport(rExport, aElemName, false, false));
2950 if (pField)
2952 // Write an field item.
2953 OUString aFieldVal = ScEditUtil::GetCellFieldValue(*pField, rExport.GetDocument(), NULL);
2954 switch (pField->GetClassId())
2956 case text::textfield::Type::URL:
2958 // <text:a xlink:href="url" xlink:type="simple">value</text:a>
2960 OUString aURL = static_cast<const SvxURLField*>(pField)->GetURL();
2961 rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, rExport.GetRelativeReference(aURL));
2962 rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, "simple");
2964 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
2965 XML_NAMESPACE_TEXT, GetXMLToken(XML_A));
2966 SvXMLElementExport aElem(rExport, aElemName, false, false);
2967 rExport.Characters(aFieldVal);
2969 break;
2970 case text::textfield::Type::DATE:
2972 // <text:date style:data-style-name="N2" text:date-value="YYYY-MM-DD">value</text:date>
2974 Date aDate(Date::SYSTEM);
2975 OUStringBuffer aBuf;
2976 sal_Int32 nVal = aDate.GetYear();
2977 aBuf.append(nVal);
2978 aBuf.append('-');
2979 nVal = aDate.GetMonth();
2980 if (nVal < 10)
2981 aBuf.append('0');
2982 aBuf.append(nVal);
2983 aBuf.append('-');
2984 nVal = aDate.GetDay();
2985 if (nVal < 10)
2986 aBuf.append('0');
2987 aBuf.append(nVal);
2988 rExport.AddAttribute(XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, "N2");
2989 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_DATE_VALUE, aBuf.makeStringAndClear());
2991 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
2992 XML_NAMESPACE_TEXT, GetXMLToken(XML_DATE));
2993 SvXMLElementExport aElem(rExport, aElemName, false, false);
2994 rExport.Characters(aFieldVal);
2996 break;
2997 case text::textfield::Type::DOCINFO_TITLE:
2999 // <text:title>value</text:title>
3001 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
3002 XML_NAMESPACE_TEXT, GetXMLToken(XML_TITLE));
3003 SvXMLElementExport aElem(rExport, aElemName, false, false);
3004 rExport.Characters(aFieldVal);
3006 break;
3007 case text::textfield::Type::TABLE:
3009 // <text:sheet-name>value</text:sheet-name>
3011 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
3012 XML_NAMESPACE_TEXT, GetXMLToken(XML_SHEET_NAME));
3013 SvXMLElementExport aElem(rExport, aElemName, false, false);
3014 rExport.Characters(aFieldVal);
3016 break;
3017 default:
3018 rExport.Characters(aFieldVal);
3021 else
3022 rExport.Characters(rContent);
3025 void flushParagraph(
3026 ScXMLExport& rExport, const OUString& rParaText,
3027 rtl::Reference<XMLPropertySetMapper> xMapper, rtl::Reference<SvXMLAutoStylePoolP> xStylePool,
3028 const ScXMLEditAttributeMap& rAttrMap,
3029 std::vector<editeng::Section>::const_iterator it, std::vector<editeng::Section>::const_iterator itEnd )
3031 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
3032 XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
3033 SvXMLElementExport aElemP(rExport, aElemName, false, false);
3035 for (; it != itEnd; ++it)
3037 const editeng::Section& rSec = *it;
3039 const sal_Unicode* pBeg = rParaText.getStr();
3040 std::advance(pBeg, rSec.mnStart);
3041 const sal_Unicode* pEnd = pBeg;
3042 std::advance(pEnd, rSec.mnEnd-rSec.mnStart);
3044 OUString aContent(pBeg, pEnd-pBeg);
3046 std::vector<XMLPropertyState> aPropStates;
3047 const SvxFieldData* pField = toXMLPropertyStates(aPropStates, rSec.maAttributes, xMapper, rAttrMap);
3048 OUString aStyleName = xStylePool->Find(XML_STYLE_FAMILY_TEXT_TEXT, OUString(), aPropStates);
3049 writeContent(rExport, aStyleName, aContent, pField);
3055 void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
3057 // nEqualCellCount is the number of additional cells
3058 SetRepeatAttribute(nEqualCellCount, (aCell.nType != table::CellContentType_EMPTY));
3060 if (aCell.nStyleIndex != -1)
3061 AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(aCell.nStyleIndex, aCell.bIsAutoStyle));
3062 if (aCell.nValidationIndex > -1)
3063 AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(aCell.nValidationIndex));
3064 bool bIsMatrix(aCell.bIsMatrixBase || aCell.bIsMatrixCovered);
3065 bool bIsFirstMatrixCell(aCell.bIsMatrixBase);
3066 if (bIsFirstMatrixCell)
3068 sal_Int32 nColumns(aCell.aMatrixRange.EndColumn - aCell.aMatrixRange.StartColumn + 1);
3069 sal_Int32 nRows(aCell.aMatrixRange.EndRow - aCell.aMatrixRange.StartRow + 1);
3070 OUStringBuffer sColumns;
3071 OUStringBuffer sRows;
3072 ::sax::Converter::convertNumber(sColumns, nColumns);
3073 ::sax::Converter::convertNumber(sRows, nRows);
3074 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
3075 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
3077 bool bIsEmpty(false);
3078 switch (aCell.nType)
3080 case table::CellContentType_EMPTY :
3082 bIsEmpty = true;
3084 break;
3085 case table::CellContentType_VALUE :
3087 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3088 aCell.nNumberFormat, aCell.maBaseCell.mfValue);
3089 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 )
3090 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3091 aCell.nNumberFormat, aCell.maBaseCell.mfValue, false, XML_NAMESPACE_CALC_EXT, false);
3093 break;
3094 case table::CellContentType_TEXT :
3096 OUString sFormattedString(lcl_GetFormattedString(pDoc, aCell.maCellAddress));
3097 OUString sCellString = aCell.maBaseCell.getString(pDoc);
3098 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3099 sCellString, sFormattedString, true, true);
3100 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 )
3101 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3102 sCellString, sFormattedString, false, true, XML_NAMESPACE_CALC_EXT);
3104 break;
3105 case table::CellContentType_FORMULA :
3107 if (aCell.maBaseCell.meType == CELLTYPE_FORMULA)
3109 ScFormulaCell* pFormulaCell = aCell.maBaseCell.mpFormula;
3110 if (!bIsMatrix || (bIsMatrix && bIsFirstMatrixCell))
3112 if (!mpCompileFormulaCxt)
3114 const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
3115 mpCompileFormulaCxt.reset(new sc::CompileFormulaContext(pDoc, eGrammar));
3118 OUString aFormula = pFormulaCell->GetFormula(*mpCompileFormulaCxt);
3119 sal_uInt16 nNamespacePrefix =
3120 (mpCompileFormulaCxt->getGrammar() == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
3122 if (!bIsMatrix)
3124 AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey(nNamespacePrefix, aFormula, false));
3126 else
3128 AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey(nNamespacePrefix, aFormula.copy(1, aFormula.getLength()-2), false));
3131 if (pFormulaCell->GetErrCode())
3133 AddAttribute(sAttrValueType, XML_STRING);
3134 AddAttribute(sAttrStringValue, aCell.maBaseCell.getString(pDoc));
3135 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 )
3137 //export calcext:value-type="error"
3138 AddAttribute(XML_NAMESPACE_CALC_EXT,XML_VALUE_TYPE, OUString("error"));
3141 else if (pFormulaCell->IsValue())
3143 bool bIsStandard;
3144 OUString sCurrency;
3145 GetNumberFormatAttributesExportHelper()->GetCellType(aCell.nNumberFormat, sCurrency, bIsStandard);
3146 if (pDoc)
3148 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3149 aCell.nNumberFormat, pDoc->GetValue(aCell.maCellAddress));
3150 if( getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
3152 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
3153 aCell.nNumberFormat, pDoc->GetValue(aCell.maCellAddress), false, XML_NAMESPACE_CALC_EXT, false );
3157 else
3159 if (!aCell.maBaseCell.getString(pDoc).isEmpty())
3161 AddAttribute(sAttrValueType, XML_STRING);
3162 AddAttribute(sAttrStringValue, aCell.maBaseCell.getString(pDoc));
3163 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 )
3165 AddAttribute(XML_NAMESPACE_CALC_EXT,XML_VALUE_TYPE, XML_STRING);
3171 break;
3172 default:
3173 break;
3175 OUString* pCellString(&sElemCell);
3176 if (aCell.bIsCovered)
3178 pCellString = &sElemCoveredCell;
3180 else
3182 if (aCell.bIsMergedBase)
3184 sal_Int32 nColumns(aCell.aMergeRange.EndColumn - aCell.aMergeRange.StartColumn + 1);
3185 sal_Int32 nRows(aCell.aMergeRange.EndRow - aCell.aMergeRange.StartRow + 1);
3186 OUStringBuffer sColumns;
3187 OUStringBuffer sRows;
3188 ::sax::Converter::convertNumber(sColumns, nColumns);
3189 ::sax::Converter::convertNumber(sRows, nRows);
3190 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, sColumns.makeStringAndClear());
3191 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, sRows.makeStringAndClear());
3194 SvXMLElementExport aElemC(*this, *pCellString, true, true);
3195 CheckAttrList();
3196 WriteAreaLink(aCell);
3197 WriteAnnotation(aCell);
3198 WriteDetective(aCell);
3200 if (!bIsEmpty)
3202 if (aCell.maBaseCell.meType == CELLTYPE_EDIT)
3204 WriteEditCell(aCell.maBaseCell.mpEditText);
3206 else if (aCell.maBaseCell.meType == CELLTYPE_FORMULA && aCell.maBaseCell.mpFormula->IsMultilineResult())
3208 WriteMultiLineFormulaResult(aCell.maBaseCell.mpFormula);
3210 else
3212 SvXMLElementExport aElemP(*this, sElemP, true, false);
3214 OUString aParaStr =
3215 ScCellFormat::GetOutputString(*pDoc, aCell.maCellAddress, aCell.maBaseCell);
3217 bool bPrevCharWasSpace = true;
3218 GetTextParagraphExport()->exportText(aParaStr, bPrevCharWasSpace);
3221 WriteShapes(aCell);
3222 if (!bIsEmpty)
3223 IncrementProgressBar(false);
3226 void ScXMLExport::WriteEditCell(const EditTextObject* pText)
3228 rtl::Reference<XMLPropertySetMapper> xMapper = GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
3229 rtl::Reference<SvXMLAutoStylePoolP> xStylePool = GetAutoStylePool();
3230 const ScXMLEditAttributeMap& rAttrMap = GetEditAttributeMap();
3232 // Get raw paragraph texts first.
3233 std::vector<OUString> aParaTexts;
3234 sal_Int32 nParaCount = pText->GetParagraphCount();
3235 aParaTexts.reserve(nParaCount);
3236 for (sal_Int32 i = 0; i < nParaCount; ++i)
3237 aParaTexts.push_back(pText->GetText(i));
3239 // Get all section data and iterate through them.
3240 std::vector<editeng::Section> aAttrs;
3241 pText->GetAllSections(aAttrs);
3242 std::vector<editeng::Section>::const_iterator itSec = aAttrs.begin(), itSecEnd = aAttrs.end();
3243 std::vector<editeng::Section>::const_iterator itPara = itSec;
3244 sal_Int32 nCurPara = 0; // current paragraph
3245 for (; itSec != itSecEnd; ++itSec)
3247 const editeng::Section& rSec = *itSec;
3248 if (nCurPara == rSec.mnParagraph)
3249 // Still in the same paragraph.
3250 continue;
3252 // Start of a new paragraph. Flush the old paragraph.
3253 flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSec);
3254 nCurPara = rSec.mnParagraph;
3255 itPara = itSec;
3258 flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSecEnd);
3261 void ScXMLExport::WriteMultiLineFormulaResult(const ScFormulaCell* pCell)
3263 OUString aElemName = GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
3265 OUString aResStr = pCell->GetResultString().getString();
3266 const sal_Unicode* p = aResStr.getStr();
3267 const sal_Unicode* pEnd = p + static_cast<size_t>(aResStr.getLength());
3268 const sal_Unicode* pPara = p; // paragraph head.
3269 for (; p != pEnd; ++p)
3271 if (*p != '\n')
3272 continue;
3274 // flush the paragraph.
3275 OUString aContent;
3276 if (*pPara == '\n')
3277 ++pPara;
3278 if (p > pPara)
3279 aContent = OUString(pPara, p-pPara);
3281 SvXMLElementExport aElem(*this, aElemName, false, false);
3282 Characters(aContent);
3284 pPara = p;
3287 OUString aContent;
3288 if (*pPara == '\n')
3289 ++pPara;
3290 if (pEnd > pPara)
3291 aContent = OUString(pPara, pEnd-pPara);
3293 SvXMLElementExport aElem(*this, aElemName, false, false);
3294 Characters(aContent);
3297 void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint)
3299 uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY );
3300 bool bIsChart( false );
3301 OUString sPropCLSID ("CLSID");
3302 OUString sPropModel ("Model");
3303 OUString sPersistName ("PersistName");
3304 if (xShapeProps.is())
3306 sal_Int32 nZOrder = 0;
3307 if (xShapeProps->getPropertyValue("ZOrder") >>= nZOrder)
3309 OUStringBuffer sBuffer;
3310 ::sax::Converter::convertNumber(sBuffer, nZOrder);
3311 AddAttribute(XML_NAMESPACE_DRAW, XML_ZINDEX, sBuffer.makeStringAndClear());
3313 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xShapeProps->getPropertySetInfo();
3314 if( xPropSetInfo->hasPropertyByName( sPropCLSID ) )
3316 OUString sCLSID;
3317 if (xShapeProps->getPropertyValue( sPropCLSID ) >>= sCLSID)
3319 if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) )
3321 // we have a chart
3322 OUString sRanges;
3323 if ( pDoc )
3325 OUString aChartName;
3326 xShapeProps->getPropertyValue( sPersistName ) >>= aChartName;
3327 ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
3328 if (pCollection)
3330 ScChartListener* pListener = pCollection->findByName(aChartName);
3331 if (pListener)
3333 const ScRangeListRef& rRangeList = pListener->GetRangeList();
3334 if ( rRangeList.Is() )
3336 ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList, pDoc, FormulaGrammar::CONV_OOO );
3337 if ( !sRanges.isEmpty() )
3339 bIsChart = true;
3340 SvXMLAttributeList* pAttrList = new SvXMLAttributeList();
3341 pAttrList->AddAttribute(
3342 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges );
3343 GetShapeExport()->exportShape( xShape, XMLShapeExportFlags::NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList );
3350 if ( sRanges.isEmpty() )
3352 uno::Reference< frame::XModel > xChartModel;
3353 if( ( xShapeProps->getPropertyValue( sPropModel ) >>= xChartModel ) &&
3354 xChartModel.is())
3356 uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
3357 uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY );
3358 if( xChartDoc.is() && xReceiver.is() &&
3359 ! xChartDoc->hasInternalDataProvider())
3361 // we have a chart that gets its data from Calc
3362 bIsChart = true;
3363 uno::Sequence< OUString > aRepresentations(
3364 xReceiver->getUsedRangeRepresentations());
3365 SvXMLAttributeList* pAttrList = 0;
3366 if(aRepresentations.getLength())
3368 // add the ranges used by the chart to the shape
3369 // element to be able to start listening after
3370 // load (when the chart is not yet loaded)
3371 uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY );
3372 sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter );
3373 pAttrList = new SvXMLAttributeList();
3374 pAttrList->AddAttribute(
3375 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
3377 GetShapeExport()->exportShape(xShape, XMLShapeExportFlags::NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
3385 if (!bIsChart)
3387 // #i66550 HLINK_FOR_SHAPES
3388 OUString sHlink;
3391 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
3392 if ( xProps.is() )
3393 xProps->getPropertyValue( OUString( SC_UNONAME_HYPERLINK ) ) >>= sHlink;
3395 catch ( const beans::UnknownPropertyException& )
3397 // no hyperlink property
3400 boost::scoped_ptr< SvXMLElementExport > pDrawA;
3401 // enlose shapes with <draw:a> element only if sHlink contains something
3402 if ( !sHlink.isEmpty() )
3404 // need to get delete the attributes that are pre-loaded
3405 // for the shape export ( otherwise they will become
3406 // attributes of the draw:a element ) This *shouldn't*
3407 // affect performance adversely as there are only a
3408 // couple of attributes involved
3409 uno::Reference< xml::sax::XAttributeList > xSaveAttribs( new SvXMLAttributeList( GetAttrList() ) );
3410 ClearAttrList();
3411 // Add Hlink
3412 AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
3413 AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sHlink);
3414 pDrawA.reset( new SvXMLElementExport( *this, XML_NAMESPACE_DRAW, XML_A, false, false ) );
3415 // Attribute list has been cleared by previous operation
3416 // re-add pre-loaded attributes
3417 AddAttributeList( xSaveAttribs );
3419 GetShapeExport()->exportShape(xShape, SEF_DEFAULT, pPoint);
3421 IncrementProgressBar(false);
3424 void ScXMLExport::WriteShapes(const ScMyCell& rMyCell)
3426 if( rMyCell.bHasShape && !rMyCell.aShapeList.empty() && pDoc )
3428 awt::Point aPoint;
3429 Rectangle aRect = pDoc->GetMMRect(rMyCell.maCellAddress.Col(), rMyCell.maCellAddress.Row(),
3430 rMyCell.maCellAddress.Col(), rMyCell.maCellAddress.Row(), rMyCell.maCellAddress.Tab());
3431 bool bNegativePage = pDoc->IsNegativePage(rMyCell.maCellAddress.Tab());
3432 if (bNegativePage)
3433 aPoint.X = aRect.Right();
3434 else
3435 aPoint.X = aRect.Left();
3436 aPoint.Y = aRect.Top();
3437 ScMyShapeList::const_iterator aItr = rMyCell.aShapeList.begin();
3438 ScMyShapeList::const_iterator aEndItr(rMyCell.aShapeList.end());
3439 while (aItr != aEndItr)
3441 if (aItr->xShape.is())
3443 if (bNegativePage)
3444 aPoint.X = 2 * aItr->xShape->getPosition().X + aItr->xShape->getSize().Width - aPoint.X;
3445 if ( !aItr->xShape->getShapeType().equals(sCaptionShape) )
3447 OUString sEndAddress;
3448 ScRangeStringConverter::GetStringFromAddress(sEndAddress, aItr->aEndAddress, pDoc, FormulaGrammar::CONV_OOO);
3449 AddAttribute(XML_NAMESPACE_TABLE, XML_END_CELL_ADDRESS, sEndAddress);
3450 OUStringBuffer sBuffer;
3451 GetMM100UnitConverter().convertMeasureToXML(
3452 sBuffer, aItr->nEndX);
3453 AddAttribute(XML_NAMESPACE_TABLE, XML_END_X, sBuffer.makeStringAndClear());
3454 GetMM100UnitConverter().convertMeasureToXML(
3455 sBuffer, aItr->nEndY);
3456 AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear());
3458 ExportShape(aItr->xShape, &aPoint);
3460 ++aItr;
3465 void ScXMLExport::WriteTableShapes()
3467 ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
3468 if (pTableShapes && !(*pTableShapes)[nCurrentTable].empty())
3470 OSL_ENSURE(pTableShapes->size() > static_cast<size_t>(nCurrentTable), "wrong Table");
3471 SvXMLElementExport aShapesElem(*this, XML_NAMESPACE_TABLE, XML_SHAPES, true, false);
3472 ScMyTableXShapes::iterator aItr((*pTableShapes)[nCurrentTable].begin());
3473 ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nCurrentTable].end());
3474 while (aItr != aEndItr)
3476 if (aItr->is())
3478 if (pDoc->IsNegativePage(static_cast<SCTAB>(nCurrentTable)))
3480 awt::Point aPoint((*aItr)->getPosition());
3481 awt::Size aSize((*aItr)->getSize());
3482 aPoint.X += aPoint.X + aSize.Width;
3483 aPoint.Y = 0;
3484 ExportShape(*aItr, &aPoint);
3486 else
3487 ExportShape(*aItr, NULL);
3489 aItr = (*pTableShapes)[nCurrentTable].erase(aItr);
3494 void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell )
3496 if( rMyCell.bHasAreaLink )
3498 const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink;
3499 AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr );
3500 AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
3501 AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) );
3502 AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter );
3503 if( !rAreaLink.sFilterOptions.isEmpty() )
3504 AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, rAreaLink.sFilterOptions );
3505 OUStringBuffer sValue;
3506 ::sax::Converter::convertNumber( sValue, rAreaLink.GetColCount() );
3507 AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, sValue.makeStringAndClear() );
3508 ::sax::Converter::convertNumber( sValue, rAreaLink.GetRowCount() );
3509 AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, sValue.makeStringAndClear() );
3510 if( rAreaLink.nRefresh )
3512 ::sax::Converter::convertDuration( sValue,
3513 (double)rAreaLink.nRefresh / 86400 );
3514 AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sValue.makeStringAndClear() );
3516 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, true, true );
3520 void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape)
3522 ScPostIt* pNote = pCurrentCell->pNote;
3524 if (pNote)
3526 // TODO : notes
3527 //is it still useful, as this call back is only called from ScXMLExport::WriteAnnotation
3528 // and should be in sync with pCurrentCell
3529 SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(pCurrentCell->maCellAddress);
3530 Reference<drawing::XShape> xCurrentShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY );
3531 if (xCurrentShape.get()!=xShape.get())
3532 return;
3534 OUString sAuthor(pNote->GetAuthor());
3535 if (!sAuthor.isEmpty())
3537 SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC,
3538 XML_CREATOR, true,
3539 false );
3540 Characters(sAuthor);
3543 OUString aDate(pNote->GetDate());
3544 if (pDoc)
3546 SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
3547 double fDate;
3548 sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
3549 if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate))
3551 OUStringBuffer sBuf;
3552 GetMM100UnitConverter().convertDateTime(sBuf, fDate,true);
3553 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC,
3554 XML_DATE, true,
3555 false );
3556 Characters(sBuf.makeStringAndClear());
3558 else
3560 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
3561 XML_DATE_STRING, true,
3562 false );
3563 Characters(OUString(aDate));
3566 else
3568 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
3569 XML_DATE_STRING, true,
3570 false );
3571 Characters(OUString(aDate));
3576 void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell)
3578 ScPostIt* pNote = pDoc->GetNote(rMyCell.maCellAddress);
3579 if (pNote)
3581 if (pNote->IsCaptionShown())
3582 AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE);
3584 pCurrentCell = &rMyCell;
3586 SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(rMyCell.maCellAddress);
3587 if (pNoteCaption)
3589 Reference<drawing::XShape> xShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY );
3590 if (xShape.is())
3591 GetShapeExport()->exportShape(xShape, SEF_DEFAULT|XMLShapeExportFlags::ANNOTATION, NULL);
3594 pCurrentCell = NULL;
3599 void ScXMLExport::WriteDetective( const ScMyCell& rMyCell )
3601 if( rMyCell.bHasDetectiveObj || rMyCell.bHasDetectiveOp )
3603 const ScMyDetectiveObjVec& rObjVec = rMyCell.aDetectiveObjVec;
3604 const ScMyDetectiveOpVec& rOpVec = rMyCell.aDetectiveOpVec;
3605 sal_Int32 nObjCount(rObjVec.size());
3606 sal_Int32 nOpCount(rOpVec.size());
3607 if( nObjCount || nOpCount )
3609 SvXMLElementExport aDetElem( *this, XML_NAMESPACE_TABLE, XML_DETECTIVE, true, true );
3610 OUString sString;
3611 ScMyDetectiveObjVec::const_iterator aObjItr(rObjVec.begin());
3612 ScMyDetectiveObjVec::const_iterator aEndObjItr(rObjVec.end());
3613 while(aObjItr != aEndObjItr)
3615 if (aObjItr->eObjType != SC_DETOBJ_CIRCLE)
3617 if( (aObjItr->eObjType == SC_DETOBJ_ARROW) || (aObjItr->eObjType == SC_DETOBJ_TOOTHERTAB))
3619 ScRangeStringConverter::GetStringFromRange( sString, aObjItr->aSourceRange, pDoc, FormulaGrammar::CONV_OOO );
3620 AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sString );
3622 ScXMLConverter::GetStringFromDetObjType( sString, aObjItr->eObjType );
3623 AddAttribute( XML_NAMESPACE_TABLE, XML_DIRECTION, sString );
3624 if( aObjItr->bHasError )
3625 AddAttribute( XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TRUE );
3627 else
3628 AddAttribute( XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TRUE );
3629 SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, true, true );
3630 ++aObjItr;
3632 OUStringBuffer aBuffer;
3633 ScMyDetectiveOpVec::const_iterator aOpItr(rOpVec.begin());
3634 ScMyDetectiveOpVec::const_iterator aEndOpItr(rOpVec.end());
3635 while(aOpItr != aEndOpItr)
3637 OUString sOpString;
3638 ScXMLConverter::GetStringFromDetOpType( sOpString, aOpItr->eOpType );
3639 AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, sOpString );
3640 ::sax::Converter::convertNumber( aBuffer, aOpItr->nIndex );
3641 AddAttribute( XML_NAMESPACE_TABLE, XML_INDEX, aBuffer.makeStringAndClear() );
3642 SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_OPERATION, true, true );
3643 ++aOpItr;
3649 void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount, bool bIncProgress)
3651 // nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1
3652 if (nEqualCellCount > 0)
3654 sal_Int32 nTemp(nEqualCellCount + 1);
3655 OUString sOUEqualCellCount(OUString::number(nTemp));
3656 AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount);
3657 if (bIncProgress)
3658 IncrementProgressBar(false, nEqualCellCount);
3662 bool ScXMLExport::IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2)
3664 return (aCell1.nType == aCell2.nType);
3667 bool ScXMLExport::IsEditCell(ScMyCell& rCell)
3669 return rCell.maBaseCell.meType == CELLTYPE_EDIT;
3672 bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2)
3674 bool bIsEqual = false;
3675 if( !aCell1.bIsMergedBase && !aCell2.bIsMergedBase &&
3676 aCell1.bIsCovered == aCell2.bIsCovered &&
3677 !aCell1.bIsMatrixBase && !aCell2.bIsMatrixBase &&
3678 aCell1.bIsMatrixCovered == aCell2.bIsMatrixCovered &&
3679 aCell1.bHasAnnotation == aCell2.bHasAnnotation &&
3680 !aCell1.bHasShape && !aCell2.bHasShape &&
3681 aCell1.bHasAreaLink == aCell2.bHasAreaLink &&
3682 !aCell1.bHasDetectiveObj && !aCell2.bHasDetectiveObj)
3684 if( (aCell1.bHasAreaLink &&
3685 (aCell1.aAreaLink.GetColCount() == 1) &&
3686 (aCell2.aAreaLink.GetColCount() == 1) &&
3687 aCell1.aAreaLink.Compare( aCell2.aAreaLink ) ) ||
3688 !aCell1.bHasAreaLink )
3690 if (!aCell1.bHasAnnotation || (aCell1.bHasAnnotation && false/*IsAnnotationEqual(aCell1.xCell, aCell2.xCell)*/)) // no longer compareable
3692 if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) ||
3693 ((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) &&
3694 (aCell1.nValidationIndex == aCell2.nValidationIndex) &&
3695 IsCellTypeEqual(aCell1, aCell2))
3697 switch ( aCell1.nType )
3699 case table::CellContentType_EMPTY :
3701 bIsEqual = true;
3703 break;
3704 case table::CellContentType_VALUE :
3706 // #i29101# number format may be different from column default styles,
3707 // but can lead to different value types, so it must also be compared
3708 bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) &&
3709 (aCell1.maBaseCell.mfValue == aCell2.maBaseCell.mfValue);
3711 break;
3712 case table::CellContentType_TEXT :
3714 if (IsEditCell(aCell1) || IsEditCell(aCell2))
3715 bIsEqual = false;
3716 else
3718 bIsEqual = (aCell1.maBaseCell.getString(pDoc) == aCell2.maBaseCell.getString(pDoc));
3721 break;
3722 case table::CellContentType_FORMULA :
3724 bIsEqual = false;
3726 break;
3727 default :
3729 bIsEqual = false;
3731 break;
3737 return bIsEqual;
3740 void ScXMLExport::WriteCalculationSettings(const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc)
3742 uno::Reference<beans::XPropertySet> xPropertySet(xSpreadDoc, uno::UNO_QUERY);
3743 if (xPropertySet.is())
3745 bool bCalcAsShown (::cppu::any2bool( xPropertySet->getPropertyValue(OUString(SC_UNO_CALCASSHOWN)) ));
3746 bool bIgnoreCase (::cppu::any2bool( xPropertySet->getPropertyValue(OUString(SC_UNO_IGNORECASE)) ));
3747 bool bLookUpLabels (::cppu::any2bool( xPropertySet->getPropertyValue(OUString(SC_UNO_LOOKUPLABELS)) ));
3748 bool bMatchWholeCell (::cppu::any2bool( xPropertySet->getPropertyValue(OUString(SC_UNO_MATCHWHOLE)) ));
3749 bool bUseRegularExpressions (::cppu::any2bool( xPropertySet->getPropertyValue(OUString(SC_UNO_REGEXENABLED)) ));
3750 bool bIsIterationEnabled (::cppu::any2bool( xPropertySet->getPropertyValue(OUString(SC_UNO_ITERENABLED)) ));
3751 sal_uInt16 nYear2000 (pDoc ? pDoc->GetDocOptions().GetYear2000() : 0);
3752 sal_Int32 nIterationCount(100);
3753 xPropertySet->getPropertyValue( OUString(SC_UNO_ITERCOUNT)) >>= nIterationCount;
3754 double fIterationEpsilon = 0;
3755 xPropertySet->getPropertyValue( OUString(SC_UNO_ITEREPSILON)) >>= fIterationEpsilon;
3756 util::Date aNullDate;
3757 xPropertySet->getPropertyValue( OUString(SC_UNO_NULLDATE)) >>= aNullDate;
3758 if (bCalcAsShown || bIgnoreCase || !bLookUpLabels || !bMatchWholeCell || !bUseRegularExpressions ||
3759 bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001) ||
3760 aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 || nYear2000 != 1930)
3762 if (bIgnoreCase)
3763 AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_FALSE);
3764 if (bCalcAsShown)
3765 AddAttribute(XML_NAMESPACE_TABLE, XML_PRECISION_AS_SHOWN, XML_TRUE);
3766 if (!bMatchWholeCell)
3767 AddAttribute(XML_NAMESPACE_TABLE, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL, XML_FALSE);
3768 if (!bLookUpLabels)
3769 AddAttribute(XML_NAMESPACE_TABLE, XML_AUTOMATIC_FIND_LABELS, XML_FALSE);
3770 if (!bUseRegularExpressions)
3771 AddAttribute(XML_NAMESPACE_TABLE, XML_USE_REGULAR_EXPRESSIONS, XML_FALSE);
3772 if (nYear2000 != 1930)
3774 OUStringBuffer sBuffer;
3775 ::sax::Converter::convertNumber(sBuffer, nYear2000);
3776 AddAttribute(XML_NAMESPACE_TABLE, XML_NULL_YEAR, sBuffer.makeStringAndClear());
3778 SvXMLElementExport aCalcSettings(*this, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, true, true);
3780 if (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899)
3782 OUStringBuffer sDate;
3783 SvXMLUnitConverter::convertDateTime(sDate, 0.0, aNullDate);
3784 AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_VALUE, sDate.makeStringAndClear());
3785 SvXMLElementExport aElemNullDate(*this, XML_NAMESPACE_TABLE, XML_NULL_DATE, true, true);
3787 if (bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001))
3789 OUStringBuffer sBuffer;
3790 if (bIsIterationEnabled)
3791 AddAttribute(XML_NAMESPACE_TABLE, XML_STATUS, XML_ENABLE);
3792 if (nIterationCount != 100)
3794 ::sax::Converter::convertNumber(sBuffer,
3795 nIterationCount);
3796 AddAttribute(XML_NAMESPACE_TABLE, XML_STEPS, sBuffer.makeStringAndClear());
3798 if (!::rtl::math::approxEqual(fIterationEpsilon, 0.001))
3800 ::sax::Converter::convertDouble(sBuffer,
3801 fIterationEpsilon);
3802 AddAttribute(XML_NAMESPACE_TABLE, XML_MAXIMUM_DIFFERENCE, sBuffer.makeStringAndClear());
3804 SvXMLElementExport aElemIteration(*this, XML_NAMESPACE_TABLE, XML_ITERATION, true, true);
3811 void ScXMLExport::WriteTableSource()
3813 uno::Reference <sheet::XSheetLinkable> xLinkable (xCurrentTable, uno::UNO_QUERY);
3814 if (xLinkable.is() && GetModel().is())
3816 sheet::SheetLinkMode nMode (xLinkable->getLinkMode());
3817 if (nMode != sheet::SheetLinkMode_NONE)
3819 OUString sLink (xLinkable->getLinkUrl());
3820 uno::Reference <beans::XPropertySet> xProps (GetModel(), uno::UNO_QUERY);
3821 if (xProps.is())
3823 uno::Reference <container::XIndexAccess> xIndex(xProps->getPropertyValue(OUString(SC_UNO_SHEETLINKS)), uno::UNO_QUERY);
3824 if (xIndex.is())
3826 sal_Int32 nCount(xIndex->getCount());
3827 if (nCount)
3829 bool bFound(false);
3830 uno::Reference <beans::XPropertySet> xLinkProps;
3831 for (sal_Int32 i = 0; (i < nCount) && !bFound; ++i)
3833 xLinkProps.set(xIndex->getByIndex(i), uno::UNO_QUERY);
3834 if (xLinkProps.is())
3836 OUString sNewLink;
3837 if (xLinkProps->getPropertyValue(OUString(SC_UNONAME_LINKURL)) >>= sNewLink)
3838 bFound = sLink.equals(sNewLink);
3841 if (bFound && xLinkProps.is())
3843 OUString sFilter;
3844 OUString sFilterOptions;
3845 OUString sTableName (xLinkable->getLinkSheetName());
3846 sal_Int32 nRefresh(0);
3847 xLinkProps->getPropertyValue(OUString(SC_UNONAME_FILTER)) >>= sFilter;
3848 xLinkProps->getPropertyValue(OUString(SC_UNONAME_FILTOPT)) >>= sFilterOptions;
3849 xLinkProps->getPropertyValue(OUString(SC_UNONAME_REFDELAY)) >>= nRefresh;
3850 if (!sLink.isEmpty())
3852 AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
3853 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink));
3854 if (!sTableName.isEmpty())
3855 AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName);
3856 if (!sFilter.isEmpty())
3857 AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, sFilter);
3858 if (!sFilterOptions.isEmpty())
3859 AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, sFilterOptions);
3860 if (nMode != sheet::SheetLinkMode_NORMAL)
3861 AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
3862 if( nRefresh )
3864 OUStringBuffer sBuffer;
3865 ::sax::Converter::convertDuration( sBuffer,
3866 (double)nRefresh / 86400 );
3867 AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() );
3869 SvXMLElementExport aSourceElem(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, true, true);
3879 // core implementation
3880 void ScXMLExport::WriteScenario()
3882 if (pDoc && pDoc->IsScenario(static_cast<SCTAB>(nCurrentTable)))
3884 OUString sComment;
3885 Color aColor;
3886 sal_uInt16 nFlags;
3887 pDoc->GetScenarioData(static_cast<SCTAB>(nCurrentTable), sComment, aColor, nFlags);
3888 if (!(nFlags & SC_SCENARIO_SHOWFRAME))
3889 AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_FALSE);
3890 OUStringBuffer aBuffer;
3891 ::sax::Converter::convertColor(aBuffer, aColor.GetColor());
3892 AddAttribute(XML_NAMESPACE_TABLE, XML_BORDER_COLOR, aBuffer.makeStringAndClear());
3893 if (!(nFlags & SC_SCENARIO_TWOWAY))
3894 AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_FALSE);
3895 if (!(nFlags & SC_SCENARIO_ATTRIB))
3896 AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_FALSE);
3897 if (nFlags & SC_SCENARIO_VALUE)
3898 AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_FALSE);
3899 if (nFlags & SC_SCENARIO_PROTECT)
3900 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
3901 ::sax::Converter::convertBool(aBuffer,
3902 pDoc->IsActiveScenario(static_cast<SCTAB>(nCurrentTable)));
3903 AddAttribute(XML_NAMESPACE_TABLE, XML_IS_ACTIVE, aBuffer.makeStringAndClear());
3904 const ScRangeList* pRangeList = pDoc->GetScenarioRanges(static_cast<SCTAB>(nCurrentTable));
3905 OUString sRangeListStr;
3906 ScRangeStringConverter::GetStringFromRangeList( sRangeListStr, pRangeList, pDoc, FormulaGrammar::CONV_OOO );
3907 AddAttribute(XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, sRangeListStr);
3908 if (!sComment.isEmpty())
3909 AddAttribute(XML_NAMESPACE_TABLE, XML_COMMENT, sComment);
3910 SvXMLElementExport aElem(*this, XML_NAMESPACE_TABLE, XML_SCENARIO, true, true);
3914 void ScXMLExport::WriteTheLabelRanges( const uno::Reference< sheet::XSpreadsheetDocument >& xSpreadDoc )
3916 uno::Reference< beans::XPropertySet > xDocProp( xSpreadDoc, uno::UNO_QUERY );
3917 if( !xDocProp.is() ) return;
3919 sal_Int32 nCount(0);
3920 uno::Reference< container::XIndexAccess > xColRangesIAccess(xDocProp->getPropertyValue( OUString( SC_UNO_COLLABELRNG ) ), uno::UNO_QUERY);
3921 if( xColRangesIAccess.is() )
3922 nCount += xColRangesIAccess->getCount();
3924 uno::Reference< container::XIndexAccess > xRowRangesIAccess(xDocProp->getPropertyValue( OUString( SC_UNO_ROWLABELRNG ) ), uno::UNO_QUERY);
3925 if( xRowRangesIAccess.is() )
3926 nCount += xRowRangesIAccess->getCount();
3928 if( nCount )
3930 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGES, true, true );
3931 WriteLabelRanges( xColRangesIAccess, true );
3932 WriteLabelRanges( xRowRangesIAccess, false );
3936 void ScXMLExport::WriteLabelRanges( const uno::Reference< container::XIndexAccess >& xRangesIAccess, bool bColumn )
3938 if( !xRangesIAccess.is() ) return;
3940 sal_Int32 nCount(xRangesIAccess->getCount());
3941 for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
3943 uno::Reference< sheet::XLabelRange > xRange(xRangesIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
3944 if( xRange.is() )
3946 OUString sRangeStr;
3947 table::CellRangeAddress aCellRange( xRange->getLabelArea() );
3948 ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
3949 AddAttribute( XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, sRangeStr );
3950 aCellRange = xRange->getDataArea();
3951 ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
3952 AddAttribute( XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, sRangeStr );
3953 AddAttribute( XML_NAMESPACE_TABLE, XML_ORIENTATION, bColumn ? XML_COLUMN : XML_ROW );
3954 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGE, true, true );
3959 void ScXMLExport::WriteNamedExpressions()
3961 if (!pDoc)
3962 return;
3963 ScRangeName* pNamedRanges = pDoc->GetRangeName();
3964 WriteNamedRange(pNamedRanges);
3967 void ScXMLExport::WriteDataStream()
3969 if (!pDoc)
3970 return;
3972 SvtMiscOptions aMiscOptions;
3973 if (!aMiscOptions.IsExperimentalMode())
3974 // Export this only in experimental mode.
3975 return;
3977 if (getDefaultVersion() <= SvtSaveOptions::ODFVER_012)
3978 // Export this only for 1.2 extended and above.
3979 return;
3981 const sc::DocumentLinkManager& rMgr = pDoc->GetDocLinkManager();
3982 const sc::DataStream* pStrm = rMgr.getDataStream();
3983 if (!pStrm)
3984 // No data stream.
3985 return;
3987 // Source URL
3988 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(pStrm->GetURL()));
3990 // Streamed range
3991 ScRange aRange = pStrm->GetRange();
3992 OUString aRangeStr;
3993 ScRangeStringConverter::GetStringFromRange(
3994 aRangeStr, aRange, pDoc, formula::FormulaGrammar::CONV_OOO);
3995 AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aRangeStr);
3997 // Empty line refresh option.
3998 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_EMPTY_LINE_REFRESH, pStrm->IsRefreshOnEmptyLine() ? XML_TRUE : XML_FALSE);
4000 // New data insertion position. Either top of bottom. Default to bottom.
4001 xmloff::token::XMLTokenEnum eInsertPosition = XML_BOTTOM;
4002 if (pStrm->GetMove() == sc::DataStream::MOVE_DOWN)
4003 eInsertPosition = XML_TOP;
4005 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_INSERTION_POSITION, eInsertPosition);
4007 SvXMLElementExport aElem(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_STREAM_SOURCE, true, true);
4010 void ScXMLExport::WriteNamedRange(ScRangeName* pRangeName)
4012 //write a global or local ScRangeName
4013 SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, true, true);
4014 for (ScRangeName::iterator it = pRangeName->begin(); it != pRangeName->end(); ++it)
4016 AddAttribute(sAttrName, it->second->GetName());
4018 OUString sBaseCellAddress;
4019 it->second->ValidateTabRefs();
4020 ScRangeStringConverter::GetStringFromAddress( sBaseCellAddress, it->second->GetPos(), pDoc,
4021 FormulaGrammar::CONV_OOO, ' ', false, SCA_ABS_3D);
4022 AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, sBaseCellAddress);
4024 OUString sSymbol;
4025 it->second->GetSymbol(sSymbol, pDoc->GetStorageGrammar());
4026 OUString sTempSymbol(sSymbol);
4027 ScRange aRange;
4028 if (it->second->IsReference(aRange))
4031 OUString sContent(sTempSymbol.copy(1, sTempSymbol.getLength() -2 ));
4032 AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sContent);
4034 sal_Int32 nRangeType = it->second->GetUnoType();
4035 OUStringBuffer sBufferRangeType;
4036 if ((nRangeType & sheet::NamedRangeFlag::COLUMN_HEADER) == sheet::NamedRangeFlag::COLUMN_HEADER)
4037 sBufferRangeType.append(GetXMLToken(XML_REPEAT_COLUMN));
4038 if ((nRangeType & sheet::NamedRangeFlag::ROW_HEADER) == sheet::NamedRangeFlag::ROW_HEADER)
4040 if (!sBufferRangeType.isEmpty())
4041 sBufferRangeType.appendAscii(" ");
4042 sBufferRangeType.append(GetXMLToken(XML_REPEAT_ROW));
4044 if ((nRangeType & sheet::NamedRangeFlag::FILTER_CRITERIA) == sheet::NamedRangeFlag::FILTER_CRITERIA)
4046 if (!sBufferRangeType.isEmpty())
4047 sBufferRangeType.appendAscii(" ");
4048 sBufferRangeType.append(GetXMLToken(XML_FILTER));
4050 if ((nRangeType & sheet::NamedRangeFlag::PRINT_AREA) == sheet::NamedRangeFlag::PRINT_AREA)
4052 if (!sBufferRangeType.isEmpty())
4053 sBufferRangeType.appendAscii(" ");
4054 sBufferRangeType.append(GetXMLToken(XML_PRINT_RANGE));
4056 OUString sRangeType = sBufferRangeType.makeStringAndClear();
4057 if (!sRangeType.isEmpty())
4058 AddAttribute(XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, sRangeType);
4059 SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_RANGE, true, true);
4062 else
4064 AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, sTempSymbol);
4065 SvXMLElementExport aElemNE(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, true, true);
4070 namespace {
4072 OUString getCondFormatEntryType(const ScColorScaleEntry& rEntry, bool bFirst = true)
4074 switch(rEntry.GetType())
4076 case COLORSCALE_MIN:
4077 return OUString("minimum");
4078 case COLORSCALE_MAX:
4079 return OUString("maximum");
4080 case COLORSCALE_PERCENT:
4081 return OUString("percent");
4082 case COLORSCALE_PERCENTILE:
4083 return OUString("percentile");
4084 case COLORSCALE_FORMULA:
4085 return OUString("formula");
4086 case COLORSCALE_VALUE:
4087 return OUString("number");
4088 case COLORSCALE_AUTO:
4089 // only important for data bars
4090 if(bFirst)
4091 return OUString("auto-minimum");
4092 else
4093 return OUString("auto-maximum");
4095 return OUString();
4098 OUString getIconSetName(ScIconSetType eType)
4100 const char* pName = NULL;
4101 ScIconSetMap* pMap = ScIconSetFormat::getIconSetMap();
4102 for(;pMap->pName;++pMap)
4104 if(pMap->eType == eType)
4106 pName = pMap->pName;
4107 break;
4110 assert(pName);
4111 return OUString::createFromAscii(pName);
4114 OUString getDateStringForType(condformat::ScCondFormatDateType eType)
4116 switch(eType)
4118 case condformat::TODAY:
4119 return OUString("today");
4120 case condformat::YESTERDAY:
4121 return OUString("yesterday");
4122 case condformat::TOMORROW:
4123 return OUString("tomorrow");
4124 case condformat::LAST7DAYS:
4125 return OUString("last-7-days");
4126 case condformat::THISWEEK:
4127 return OUString("this-week");
4128 case condformat::LASTWEEK:
4129 return OUString("last-week");
4130 case condformat::NEXTWEEK:
4131 return OUString("next-week");
4132 case condformat::THISMONTH:
4133 return OUString("this-month");
4134 case condformat::LASTMONTH:
4135 return OUString("last-month");
4136 case condformat::NEXTMONTH:
4137 return OUString("next-month");
4138 case condformat::THISYEAR:
4139 return OUString("this-year");
4140 case condformat::LASTYEAR:
4141 return OUString("last-year");
4142 case condformat::NEXTYEAR:
4143 return OUString("next-year");
4146 return OUString();
4151 void ScXMLExport::ExportConditionalFormat(SCTAB nTab)
4153 ScConditionalFormatList* pCondFormatList = pDoc->GetCondFormList(nTab);
4154 if(pCondFormatList)
4156 if(pCondFormatList && !pCondFormatList->size())
4157 return;
4159 SvXMLElementExport aElementCondFormats(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITIONAL_FORMATS, true, true);
4161 if(pCondFormatList)
4163 for(ScConditionalFormatList::const_iterator itr = pCondFormatList->begin();
4164 itr != pCondFormatList->end(); ++itr)
4166 OUString sRanges;
4167 const ScRangeList& rRangeList = itr->GetRange();
4168 ScRangeStringConverter::GetStringFromRangeList( sRanges, &rRangeList, pDoc, formula::FormulaGrammar::CONV_OOO );
4169 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TARGET_RANGE_ADDRESS, sRanges);
4170 SvXMLElementExport aElementCondFormat(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITIONAL_FORMAT, true, true);
4171 size_t nEntries = itr->size();
4172 for(size_t i = 0; i < nEntries; ++i)
4174 const ScFormatEntry* pFormatEntry = itr->GetEntry(i);
4175 if(pFormatEntry->GetType()==condformat::CONDITION)
4177 const ScCondFormatEntry* pEntry = static_cast<const ScCondFormatEntry*>(pFormatEntry);
4178 OUStringBuffer aCond;
4179 ScAddress aPos = pEntry->GetSrcPos();
4180 switch(pEntry->GetOperation())
4182 case SC_COND_EQUAL:
4183 aCond.append('=');
4184 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4185 break;
4186 case SC_COND_LESS:
4187 aCond.append('<');
4188 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4189 break;
4190 case SC_COND_GREATER:
4191 aCond.append('>');
4192 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4193 break;
4194 case SC_COND_EQLESS:
4195 aCond.append("<=");
4196 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4197 break;
4198 case SC_COND_EQGREATER:
4199 aCond.append(">=");
4200 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4201 break;
4202 case SC_COND_NOTEQUAL:
4203 aCond.append("!=");
4204 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4205 break;
4206 case SC_COND_BETWEEN:
4207 aCond.append("between(");
4208 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4209 aCond.append(',');
4210 aCond.append(pEntry->GetExpression(aPos, 1, 0, formula::FormulaGrammar::GRAM_ODFF));
4211 aCond.append(')');
4212 break;
4213 case SC_COND_NOTBETWEEN:
4214 aCond.append("not-between(");
4215 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4216 aCond.append(',');
4217 aCond.append(pEntry->GetExpression(aPos, 1, 0, formula::FormulaGrammar::GRAM_ODFF));
4218 aCond.append(')');
4219 break;
4220 case SC_COND_DUPLICATE:
4221 aCond.append("duplicate");
4222 break;
4223 case SC_COND_NOTDUPLICATE:
4224 aCond.append("unique");
4225 break;
4226 case SC_COND_DIRECT:
4227 aCond.append("formula-is(");
4228 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4229 aCond.append(')');
4230 break;
4231 case SC_COND_TOP10:
4232 aCond.append("top-elements(");
4233 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4234 aCond.append(")");
4235 break;
4236 case SC_COND_BOTTOM10:
4237 aCond.append("bottom-elements(");
4238 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4239 aCond.append(")");
4240 break;
4241 case SC_COND_TOP_PERCENT:
4242 aCond.append("top-percent(");
4243 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4244 aCond.append(")");
4245 break;
4246 case SC_COND_BOTTOM_PERCENT:
4247 aCond.append("bottom-percent(");
4248 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4249 aCond.append(")");
4250 break;
4251 case SC_COND_ABOVE_AVERAGE:
4252 aCond.append("above-average");
4253 break;
4254 case SC_COND_BELOW_AVERAGE:
4255 aCond.append("below-average");
4256 break;
4257 case SC_COND_ABOVE_EQUAL_AVERAGE:
4258 aCond.append("above-equal-average");
4259 break;
4260 case SC_COND_BELOW_EQUAL_AVERAGE:
4261 aCond.append("below-equal-average");
4262 break;
4263 case SC_COND_ERROR:
4264 aCond.append("is-error");
4265 break;
4266 case SC_COND_NOERROR:
4267 aCond.append("is-no-error");
4268 break;
4269 case SC_COND_BEGINS_WITH:
4270 aCond.append("begins-with(");
4271 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4272 aCond.append(")");
4273 break;
4274 case SC_COND_ENDS_WITH:
4275 aCond.append("ends-with(");
4276 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4277 aCond.append(")");
4278 break;
4279 case SC_COND_CONTAINS_TEXT:
4280 aCond.append("contains-text(");
4281 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4282 aCond.append(")");
4283 break;
4284 case SC_COND_NOT_CONTAINS_TEXT:
4285 aCond.append("not-contains-text(");
4286 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF));
4287 aCond.append(")");
4288 break;
4289 case SC_COND_NONE:
4290 continue;
4291 default:
4292 SAL_WARN("sc", "unimplemented conditional format export");
4294 OUString sStyle = ScStyleNameConversion::DisplayToProgrammaticName(pEntry->GetStyle(), SFX_STYLE_FAMILY_PARA);
4295 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_APPLY_STYLE_NAME, sStyle);
4296 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, aCond.makeStringAndClear());
4298 OUString sBaseAddress;
4299 ScRangeStringConverter::GetStringFromAddress( sBaseAddress, aPos, pDoc,formula::FormulaGrammar::CONV_ODF );
4300 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_BASE_CELL_ADDRESS, sBaseAddress);
4301 SvXMLElementExport aElementCondEntry(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITION, true, true);
4303 else if(pFormatEntry->GetType() == condformat::COLORSCALE)
4305 SvXMLElementExport aElementColorScale(*this, XML_NAMESPACE_CALC_EXT, XML_COLOR_SCALE, true, true);
4306 const ScColorScaleFormat& mrColorScale = static_cast<const ScColorScaleFormat&>(*pFormatEntry);
4307 for(ScColorScaleFormat::const_iterator it = mrColorScale.begin();
4308 it != mrColorScale.end(); ++it)
4310 if(it->GetType() == COLORSCALE_FORMULA)
4312 OUString sFormula = it->GetFormula(formula::FormulaGrammar::GRAM_ODFF);
4313 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula);
4315 else
4316 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(it->GetValue()));
4318 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*it));
4319 OUStringBuffer aBuffer;
4320 ::sax::Converter::convertColor(aBuffer, it->GetColor().GetColor());
4321 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLOR, aBuffer.makeStringAndClear());
4322 SvXMLElementExport aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT, XML_COLOR_SCALE_ENTRY, true, true);
4325 else if(pFormatEntry->GetType() == condformat::DATABAR)
4327 const ScDataBarFormatData* pFormatData = static_cast<const ScDataBarFormat&>(*pFormatEntry).GetDataBarData();
4328 if(!pFormatData->mbGradient)
4329 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_GRADIENT, XML_FALSE);
4330 if(pFormatData->mbOnlyBar)
4331 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_SHOW_VALUE, XML_FALSE);
4333 if (pFormatData->mnMinLength != 0.0)
4334 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MIN_LENGTH, OUString::number(pFormatData->mnMinLength));
4336 if (pFormatData->mnMaxLength != 0.0)
4337 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MAX_LENGTH, OUString::number(pFormatData->mnMaxLength));
4339 if(pFormatData->mbNeg)
4341 if(pFormatData->mpNegativeColor)
4343 OUStringBuffer aBuffer;
4344 ::sax::Converter::convertColor(aBuffer, pFormatData->mpNegativeColor->GetColor());
4345 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_NEGATIVE_COLOR, aBuffer.makeStringAndClear());
4347 else
4349 OUStringBuffer aBuffer;
4350 ::sax::Converter::convertColor(aBuffer, Color(COL_LIGHTRED).GetColor());
4351 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_NEGATIVE_COLOR, aBuffer.makeStringAndClear());
4355 if(pFormatData->meAxisPosition != databar::AUTOMATIC)
4357 if(pFormatData->meAxisPosition == databar::NONE)
4359 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_POSITION, OUString("none"));
4361 else
4363 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_POSITION, OUString("middle"));
4367 OUStringBuffer aBuffer;
4368 ::sax::Converter::convertColor(aBuffer, pFormatData->maPositiveColor.GetColor());
4369 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_POSITIVE_COLOR, aBuffer.makeStringAndClear());
4371 aBuffer = OUStringBuffer();
4372 ::sax::Converter::convertColor(aBuffer, pFormatData->maAxisColor.GetColor());
4373 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_COLOR, aBuffer.makeStringAndClear());
4374 SvXMLElementExport aElementDataBar(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_BAR, true, true);
4377 if(pFormatData->mpLowerLimit->GetType() == COLORSCALE_FORMULA)
4379 OUString sFormula = pFormatData->mpLowerLimit->GetFormula(formula::FormulaGrammar::GRAM_ODFF);
4380 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula);
4382 else
4383 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(pFormatData->mpLowerLimit->GetValue()));
4384 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*pFormatData->mpLowerLimit, true));
4385 SvXMLElementExport aElementDataBarEntryLower(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true);
4389 if(pFormatData->mpUpperLimit->GetType() == COLORSCALE_FORMULA)
4391 OUString sFormula = pFormatData->mpUpperLimit->GetFormula(formula::FormulaGrammar::GRAM_ODFF);
4392 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula);
4394 else
4395 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(pFormatData->mpUpperLimit->GetValue()));
4396 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*pFormatData->mpUpperLimit, false));
4397 SvXMLElementExport aElementDataBarEntryUpper(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true);
4400 else if(pFormatEntry->GetType() == condformat::ICONSET)
4402 const ScIconSetFormat& mrIconSet = static_cast<const ScIconSetFormat&>(*pFormatEntry);
4403 OUString aIconSetName = getIconSetName(mrIconSet.GetIconSetData()->eIconSetType);
4404 AddAttribute( XML_NAMESPACE_CALC_EXT, XML_ICON_SET_TYPE, aIconSetName );
4405 SvXMLElementExport aElementColorScale(*this, XML_NAMESPACE_CALC_EXT, XML_ICON_SET, true, true);
4406 if(!mrIconSet.GetIconSetData()->mbShowValue)
4407 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_SHOW_VALUE, XML_FALSE);
4408 for(ScIconSetFormat::const_iterator it = mrIconSet.begin();
4409 it != mrIconSet.end(); ++it)
4411 if(it->GetType() == COLORSCALE_FORMULA)
4413 OUString sFormula = it->GetFormula(formula::FormulaGrammar::GRAM_ODFF);
4414 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula);
4416 else
4417 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(it->GetValue()));
4419 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*it));
4420 SvXMLElementExport aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true);
4423 else if(pFormatEntry->GetType() == condformat::DATE)
4425 const ScCondDateFormatEntry& mrDateFormat = static_cast<const ScCondDateFormatEntry&>(*pFormatEntry);
4426 OUString aDateType = getDateStringForType(mrDateFormat.GetDateType());
4427 OUString aStyleName = ScStyleNameConversion::DisplayToProgrammaticName(mrDateFormat.GetStyleName(), SFX_STYLE_FAMILY_PARA );
4428 AddAttribute( XML_NAMESPACE_CALC_EXT, XML_STYLE, aStyleName);
4429 AddAttribute( XML_NAMESPACE_CALC_EXT, XML_DATE, aDateType);
4430 SvXMLElementExport aElementDateFormat(*this, XML_NAMESPACE_CALC_EXT, XML_DATE_IS, true, true);
4438 void ScXMLExport::WriteExternalRefCaches()
4440 if (!pDoc)
4441 return;
4443 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
4444 pRefMgr->resetSrcFileData(GetOrigFileName());
4445 sal_uInt16 nCount = pRefMgr->getExternalFileCount();
4446 for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId)
4448 const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
4449 if (!pUrl)
4450 continue;
4452 vector<OUString> aTabNames;
4453 pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
4454 if (aTabNames.empty())
4455 continue;
4457 for (vector<OUString>::const_iterator itr = aTabNames.begin(), itrEnd = aTabNames.end();
4458 itr != itrEnd; ++itr)
4460 ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
4461 if (!pTable.get() || !pTable->isReferenced())
4462 continue;
4464 AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, "'" + *pUrl + "'#" + *itr);
4465 AddAttribute(XML_NAMESPACE_TABLE, XML_PRINT, GetXMLToken(XML_FALSE));
4466 AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sExternalRefTabStyleName);
4467 SvXMLElementExport aElemTable(*this, XML_NAMESPACE_TABLE, XML_TABLE, true, true);
4469 const ScExternalRefManager::SrcFileData* pExtFileData = pRefMgr->getExternalFileData(nFileId);
4470 if (pExtFileData)
4472 OUString aRelUrl;
4473 if (!pExtFileData->maRelativeName.isEmpty())
4474 aRelUrl = pExtFileData->maRelativeName;
4475 else
4476 aRelUrl = GetRelativeReference(pExtFileData->maRelativeName);
4477 AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
4478 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl);
4479 AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, *itr);
4480 if (!pExtFileData->maFilterName.isEmpty())
4481 AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, pExtFileData->maFilterName);
4482 if (!pExtFileData->maFilterOptions.isEmpty())
4483 AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, pExtFileData->maFilterOptions);
4484 AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
4486 SvXMLElementExport aElemTableSource(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, true, true);
4489 // Determine maximum column count of used area, for repeated cells.
4490 SCCOL nMaxColsUsed = 1; // assume that there is at least one cell somewhere..
4491 vector<SCROW> aRows;
4492 pTable->getAllRows(aRows);
4493 for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
4494 itrRow != itrRowEnd; ++itrRow)
4496 SCROW nRow = *itrRow;
4497 vector<SCCOL> aCols;
4498 pTable->getAllCols(nRow, aCols);
4499 if (!aCols.empty())
4501 SCCOL nCol = aCols.back();
4502 if (nMaxColsUsed <= nCol)
4503 nMaxColsUsed = nCol + 1;
4507 // Column definitions have to be present to make a valid file
4509 if (nMaxColsUsed > 1)
4510 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
4511 OUString::number(nMaxColsUsed));
4512 SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, true, true);
4515 // Write cache content for this table.
4516 SCROW nLastRow = 0;
4517 bool bFirstRow = true;
4518 for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
4519 itrRow != itrRowEnd; ++itrRow)
4521 SCROW nRow = *itrRow;
4522 if (bFirstRow)
4524 if (nRow > 0)
4526 if (nRow > 1)
4528 OUStringBuffer aVal;
4529 aVal.append(nRow);
4530 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
4532 SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true);
4533 OUStringBuffer aVal;
4534 aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
4535 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
4536 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true);
4539 else
4541 SCROW nRowGap = nRow - nLastRow;
4542 if (nRowGap > 1)
4544 if (nRowGap > 2)
4546 OUStringBuffer aVal;
4547 aVal.append(static_cast<sal_Int32>(nRowGap-1));
4548 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
4550 SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true);
4551 OUStringBuffer aVal;
4552 aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
4553 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
4554 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true);
4557 SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true);
4559 vector<SCCOL> aCols;
4560 pTable->getAllCols(nRow, aCols);
4561 SCCOL nLastCol = 0;
4562 bool bFirstCol = true;
4563 for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end();
4564 itrCol != itrColEnd; ++itrCol)
4566 SCCOL nCol = *itrCol;
4567 if (bFirstCol)
4569 if (nCol > 0)
4571 if (nCol > 1)
4573 OUStringBuffer aVal;
4574 aVal.append(static_cast<sal_Int32>(nCol));
4575 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
4577 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true);
4580 else
4582 SCCOL nColGap = nCol - nLastCol;
4583 if (nColGap > 1)
4585 if (nColGap > 2)
4587 OUStringBuffer aVal;
4588 aVal.append(static_cast<sal_Int32>(nColGap-1));
4589 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
4591 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true);
4595 // Write out this cell.
4596 sal_uInt32 nNumFmt = 0;
4597 ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow, &nNumFmt);
4598 OUString aStrVal;
4599 if (pToken.get())
4601 sal_Int32 nIndex = GetNumberFormatStyleIndex(nNumFmt);
4602 if (nIndex >= 0)
4604 const OUString aStyleName = *pCellStyles->GetStyleNameByIndex(nIndex, true);
4605 AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, aStyleName);
4608 switch(pToken->GetType())
4610 case svDouble:
4612 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
4613 OUStringBuffer aVal;
4614 aVal.append(pToken->GetDouble());
4615 aStrVal = aVal.makeStringAndClear();
4616 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aStrVal);
4618 break;
4619 case svString:
4621 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
4622 aStrVal = pToken->GetString().getString();
4624 break;
4625 default:
4629 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true);
4630 SvXMLElementExport aElemText(*this, XML_NAMESPACE_TEXT, XML_P, true, false);
4631 Characters(aStrVal);
4633 nLastCol = nCol;
4634 bFirstCol = false;
4636 nLastRow = nRow;
4637 bFirstRow = false;
4643 // core implementation
4644 void ScXMLExport::WriteConsolidation()
4646 if (pDoc)
4648 const ScConsolidateParam* pCons(pDoc->GetConsolidateDlgData());
4649 if( pCons )
4651 OUString sStrData;
4653 ScXMLConverter::GetStringFromFunction( sStrData, pCons->eFunction );
4654 AddAttribute( XML_NAMESPACE_TABLE, XML_FUNCTION, sStrData );
4656 sStrData.clear();
4657 for( sal_Int32 nIndex = 0; nIndex < pCons->nDataAreaCount; ++nIndex )
4658 ScRangeStringConverter::GetStringFromArea( sStrData, *pCons->ppDataAreas[ nIndex ], pDoc, FormulaGrammar::CONV_OOO, ' ', true );
4659 AddAttribute( XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, sStrData );
4661 ScRangeStringConverter::GetStringFromAddress( sStrData, ScAddress( pCons->nCol, pCons->nRow, pCons->nTab ), pDoc, FormulaGrammar::CONV_OOO );
4662 AddAttribute( XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, sStrData );
4664 if( pCons->bByCol && !pCons->bByRow )
4665 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_COLUMN );
4666 else if( !pCons->bByCol && pCons->bByRow )
4667 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_ROW );
4668 else if( pCons->bByCol && pCons->bByRow )
4669 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_BOTH );
4671 if( pCons->bReferenceData )
4672 AddAttribute( XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TRUE );
4674 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CONSOLIDATION, true, true );
4679 SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool()
4681 return new ScXMLAutoStylePoolP(*this);
4684 XMLPageExport* ScXMLExport::CreatePageExport()
4686 return new XMLTableMasterPageExport( *this );
4689 void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
4691 ScChangeViewSettings* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : NULL);
4692 if (pViewSettings)
4694 sal_Int32 nChangePos(rProps.getLength());
4695 rProps.realloc(nChangePos + 1);
4696 beans::PropertyValue* pProps(rProps.getArray());
4697 if (pProps)
4699 uno::Sequence<beans::PropertyValue> aChangeProps(SC_VIEWCHANGES_COUNT);
4700 beans::PropertyValue* pChangeProps(aChangeProps.getArray());
4701 if (pChangeProps)
4703 pChangeProps[SC_SHOW_CHANGES].Name = "ShowChanges";
4704 pChangeProps[SC_SHOW_CHANGES].Value <<= pViewSettings->ShowChanges();
4705 pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Name = "ShowAcceptedChanges";
4706 pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Value <<= pViewSettings->IsShowAccepted();
4707 pChangeProps[SC_SHOW_REJECTED_CHANGES].Name = "ShowRejectedChanges";
4708 pChangeProps[SC_SHOW_REJECTED_CHANGES].Value <<= pViewSettings->IsShowRejected();
4709 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Name = "ShowChangesByDatetime";
4710 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Value <<= pViewSettings->HasDate();
4711 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Name = "ShowChangesByDatetimeMode";
4712 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Value <<= static_cast<sal_Int16>(pViewSettings->GetTheDateMode());
4713 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Name = "ShowChangesByDatetimeFirstDatetime";
4714 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Value <<= pViewSettings->GetTheFirstDateTime().GetUNODateTime();
4715 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Name = "ShowChangesByDatetimeSecondDatetime";
4716 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Value <<= pViewSettings->GetTheLastDateTime().GetUNODateTime();
4717 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Name = "ShowChangesByAuthor";
4718 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Value <<= pViewSettings->HasAuthor();
4719 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Name = "ShowChangesByAuthorName";
4720 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Value <<= OUString (pViewSettings->GetTheAuthorToShow());
4721 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Name = "ShowChangesByComment";
4722 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Value <<= pViewSettings->HasComment();
4723 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Name = "ShowChangesByCommentText";
4724 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Value <<= OUString (pViewSettings->GetTheComment());
4725 pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Name = "ShowChangesByRanges";
4726 pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Value <<= pViewSettings->HasRange();
4727 OUString sRangeList;
4728 ScRangeStringConverter::GetStringFromRangeList(sRangeList, &(pViewSettings->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO);
4729 pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Name = "ShowChangesByRangesList";
4730 pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Value <<= sRangeList;
4732 pProps[nChangePos].Name = "TrackedChangesViewSettings";
4733 pProps[nChangePos].Value <<= aChangeProps;
4739 void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
4741 rProps.realloc(4);
4742 beans::PropertyValue* pProps(rProps.getArray());
4743 if(pProps)
4745 if (GetModel().is())
4747 ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() ));
4748 if (pDocObj)
4750 SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
4751 if (pEmbeddedObj)
4753 Rectangle aRect(pEmbeddedObj->GetVisArea());
4754 sal_uInt16 i(0);
4755 pProps[i].Name = "VisibleAreaTop";
4756 pProps[i].Value <<= static_cast<sal_Int32>(aRect.getY());
4757 pProps[++i].Name = "VisibleAreaLeft";
4758 pProps[i].Value <<= static_cast<sal_Int32>(aRect.getX());
4759 pProps[++i].Name = "VisibleAreaWidth";
4760 pProps[i].Value <<= static_cast<sal_Int32>(aRect.getWidth());
4761 pProps[++i].Name = "VisibleAreaHeight";
4762 pProps[i].Value <<= static_cast<sal_Int32>(aRect.getHeight());
4767 GetChangeTrackViewSettings(rProps);
4770 void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps)
4772 if (GetModel().is())
4774 uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
4775 if (xMultiServiceFactory.is())
4777 uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance("com.sun.star.comp.SpreadsheetSettings"), uno::UNO_QUERY);
4778 if (xProperties.is())
4779 SvXMLUnitConverter::convertPropertySet(rProps, xProperties);
4781 sal_Int32 nPropsToAdd = 0;
4782 OUStringBuffer aTrackedChangesKey;
4783 if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected())
4785 ::sax::Converter::encodeBase64(aTrackedChangesKey,
4786 GetDocument()->GetChangeTrack()->GetProtection());
4787 if (!aTrackedChangesKey.isEmpty())
4788 ++nPropsToAdd;
4791 bool bVBACompat = false;
4792 uno::Reference <container::XNameAccess> xCodeNameAccess;
4793 OSL_ENSURE( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" );
4794 if( pDoc && pDoc->IsInVBAMode() )
4796 // VBA compatibility mode
4797 bVBACompat = true;
4798 ++nPropsToAdd;
4799 // code names
4800 xCodeNameAccess = new XMLCodeNameProvider( pDoc );
4801 if( xCodeNameAccess->hasElements() )
4802 ++nPropsToAdd;
4803 else
4804 xCodeNameAccess.clear();
4807 if( nPropsToAdd > 0 )
4809 sal_Int32 nCount(rProps.getLength());
4810 rProps.realloc(nCount + nPropsToAdd);
4811 if (!aTrackedChangesKey.isEmpty())
4813 rProps[nCount].Name = "TrackedChangesProtectionKey";
4814 rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear();
4815 ++nCount;
4817 if( bVBACompat )
4819 rProps[nCount].Name = "VBACompatibilityMode";
4820 rProps[nCount].Value <<= bVBACompat;
4821 ++nCount;
4823 if( xCodeNameAccess.is() )
4825 rProps[nCount].Name = "ScriptConfiguration";
4826 rProps[nCount].Value <<= xCodeNameAccess;
4827 ++nCount;
4834 XMLShapeExport* ScXMLExport::CreateShapeExport()
4836 return new ScXMLShapeExport(*this);
4839 void ScXMLExport::CreateSharedData(const sal_Int32 nTableCount)
4841 pSharedData = new ScMySharedData(nTableCount);
4844 XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper()
4846 if (!pNumberFormatAttributesExportHelper)
4847 pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this );
4848 return pNumberFormatAttributesExportHelper;
4851 void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib)
4853 sal_uInt32 nItems(pPool->GetItemCount2( nAttrib ));
4854 for( sal_uInt32 i = 0; i < nItems; ++i )
4856 const SfxPoolItem* pItem;
4857 if( 0 != (pItem = pPool->GetItem2( nAttrib, i ) ) )
4859 const SvXMLAttrContainerItem *pUnknown(static_cast<const SvXMLAttrContainerItem *>(pItem));
4860 if( (pUnknown->GetAttrCount() > 0) )
4862 sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex());
4863 while( USHRT_MAX != nIdx )
4865 if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 )
4867 const OUString& rPrefix = pUnknown->GetPrefix( nIdx );
4868 // Add namespace declaration for unknown attributes if
4869 // there aren't existing ones for the prefix used by the
4870 // attibutes
4871 _GetNamespaceMap().Add( rPrefix,
4872 pUnknown->GetNamespace( nIdx ),
4873 XML_NAMESPACE_UNKNOWN );
4875 nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
4881 // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
4882 _GetNamespaceMap().Add(
4883 GetXMLToken( XML_NP_PRESENTATION ),
4884 GetXMLToken( XML_N_PRESENTATION ),
4885 XML_NAMESPACE_PRESENTATION );
4888 void ScXMLExport::IncrementProgressBar(bool bFlush, sal_Int32 nInc)
4890 nProgressCount += nInc;
4891 if (bFlush || nProgressCount > 100)
4893 GetProgressBarHelper()->Increment(nProgressCount);
4894 nProgressCount = 0;
4898 sal_uInt32 ScXMLExport::exportDoc( enum XMLTokenEnum eClass )
4900 if( getExportFlags() & (SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::STYLES|
4901 SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
4903 if (GetDocument())
4905 // if source doc was Excel then
4906 uno::Reference< frame::XModel > xModel = GetModel();
4907 if ( xModel.is() )
4909 uno::Reference< lang::XUnoTunnel > xObjShellTunnel( xModel, uno::UNO_QUERY );
4910 SfxObjectShell* pFoundShell = reinterpret_cast<SfxObjectShell*>( xObjShellTunnel.is() ? xObjShellTunnel->getSomething(SfxObjectShell::getUnoTunnelId()) : 0 );
4911 if ( pFoundShell && ooo::vba::isAlienExcelDoc( *pFoundShell ) )
4913 xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScFromXLSRowStylesProperties, xScPropHdlFactory, true);
4914 xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper);
4915 GetAutoStylePool()->SetFamilyPropSetMapper( XML_STYLE_FAMILY_TABLE_ROW,
4916 xRowStylesExportPropertySetMapper );
4919 CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF);
4920 CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS);
4921 CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS);
4922 ScDrawLayer* pDrawLayer = GetDocument()->GetDrawLayer();
4923 if (pDrawLayer)
4925 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_PARA_XMLATTRIBS);
4926 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS);
4927 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES);
4930 // sheet events use officeooo namespace
4931 if( (getExportFlags() & SvXMLExportFlags::CONTENT) &&
4932 getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
4934 bool bAnySheetEvents = false;
4935 SCTAB nTabCount = pDoc->GetTableCount();
4936 for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
4937 if (pDoc->GetSheetEvents(nTab))
4938 bAnySheetEvents = true;
4939 if (bAnySheetEvents)
4940 _GetNamespaceMap().Add(
4941 GetXMLToken( XML_NP_OFFICE_EXT ),
4942 GetXMLToken( XML_N_OFFICE_EXT ),
4943 XML_NAMESPACE_OFFICE_EXT );
4947 return SvXMLExport::exportDoc( eClass );
4950 // XExporter
4951 void SAL_CALL ScXMLExport::setSourceDocument( const uno::Reference<lang::XComponent>& xComponent )
4952 throw(lang::IllegalArgumentException, uno::RuntimeException, std::exception)
4954 SolarMutexGuard aGuard;
4955 SvXMLExport::setSourceDocument( xComponent );
4957 pDoc = ScXMLConverter::GetScDocument( GetModel() );
4958 OSL_ENSURE( pDoc, "ScXMLExport::setSourceDocument - no ScDocument!" );
4959 if (!pDoc)
4960 throw lang::IllegalArgumentException();
4962 // create ScChangeTrackingExportHelper after document is known
4963 pChangeTrackingExportHelper = new ScChangeTrackingExportHelper(*this);
4965 // Set the document's storage grammar corresponding to the ODF version that
4966 // is to be written.
4967 SvtSaveOptions::ODFDefaultVersion meODFDefaultVersion = getDefaultVersion();
4968 switch (meODFDefaultVersion)
4970 // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF
4971 case SvtSaveOptions::ODFVER_010:
4972 case SvtSaveOptions::ODFVER_011:
4973 pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF);
4974 break;
4975 default:
4976 pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF);
4980 // XFilter
4981 sal_Bool SAL_CALL ScXMLExport::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
4982 throw(::com::sun::star::uno::RuntimeException, std::exception)
4984 SolarMutexGuard aGuard;
4985 if (pDoc)
4986 pDoc->EnableIdle(false);
4987 bool bReturn(SvXMLExport::filter(aDescriptor));
4988 if (pDoc)
4989 pDoc->EnableIdle(true);
4990 return bReturn;
4993 void SAL_CALL ScXMLExport::cancel()
4994 throw(::com::sun::star::uno::RuntimeException, std::exception)
4996 SolarMutexGuard aGuard;
4997 if (pDoc)
4998 pDoc->EnableIdle(true);
4999 SvXMLExport::cancel();
5002 // XInitialization
5003 void SAL_CALL ScXMLExport::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
5004 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
5006 SolarMutexGuard aGuard;
5007 SvXMLExport::initialize(aArguments);
5010 // XUnoTunnel
5011 sal_Int64 SAL_CALL ScXMLExport::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
5012 throw(::com::sun::star::uno::RuntimeException, std::exception)
5014 SolarMutexGuard aGuard;
5015 return SvXMLExport::getSomething(aIdentifier);
5018 void ScXMLExport::DisposingModel()
5020 SvXMLExport::DisposingModel();
5021 pDoc = NULL;
5022 xCurrentTable = 0;
5025 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */