1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <sal/config.h> 21 #include <sal/log.hxx> 22 23 #include "xmlexprt.hxx" 24 #include "XMLConverter.hxx" 25 #include "xmlstyle.hxx" 26 #include <unonames.hxx> 27 #include <document.hxx> 28 #include <olinetab.hxx> 29 #include <formulacell.hxx> 30 #include <rangenam.hxx> 31 #include "XMLTableMasterPageExport.hxx" 32 #include <drwlayer.hxx> 33 #include "XMLExportDataPilot.hxx" 34 #include "XMLExportDatabaseRanges.hxx" 35 #include "XMLExportDDELinks.hxx" 36 #include "XMLExportIterator.hxx" 37 #include "XMLColumnRowGroupExport.hxx" 38 #include "XMLStylesExportHelper.hxx" 39 #include "XMLChangeTrackingExportHelper.hxx" 40 #include <sheetdata.hxx> 41 #include <docoptio.hxx> 42 #include "XMLExportSharedData.hxx" 43 #include <chgviset.hxx> 44 #include <docuno.hxx> 45 #include <textuno.hxx> 46 #include <chartlis.hxx> 47 #include <scitems.hxx> 48 #include <docpool.hxx> 49 #include <userdat.hxx> 50 #include <chgtrack.hxx> 51 #include <rangeutl.hxx> 52 #include <postit.hxx> 53 #include <externalrefmgr.hxx> 54 #include <editutil.hxx> 55 #include <tabprotection.hxx> 56 #include "cachedattraccess.hxx" 57 #include <colorscale.hxx> 58 #include <conditio.hxx> 59 #include <cellvalue.hxx> 60 #include <stylehelper.hxx> 61 #include <edittextiterator.hxx> 62 #include "editattributemap.hxx" 63 #include <arealink.hxx> 64 #include <datastream.hxx> 65 #include <documentlinkmgr.hxx> 66 #include <tokenstringcontext.hxx> 67 #include <cellform.hxx> 68 #include <datamapper.hxx> 69 #include <datatransformation.hxx> 70 71 #include <xmloff/xmltoken.hxx> 72 #include <xmloff/xmlnmspe.hxx> 73 #include <xmloff/xmluconv.hxx> 74 #include <xmloff/nmspmap.hxx> 75 #include <xmloff/families.hxx> 76 #include <xmloff/numehelp.hxx> 77 #include <xmloff/txtparae.hxx> 78 #include <editeng/autokernitem.hxx> 79 #include <editeng/charreliefitem.hxx> 80 #include <editeng/charscaleitem.hxx> 81 #include <editeng/colritem.hxx> 82 #include <editeng/contouritem.hxx> 83 #include <editeng/crossedoutitem.hxx> 84 #include <editeng/emphasismarkitem.hxx> 85 #include <editeng/escapementitem.hxx> 86 #include <editeng/fhgtitem.hxx> 87 #include <editeng/fontitem.hxx> 88 #include <editeng/kernitem.hxx> 89 #include <editeng/langitem.hxx> 90 #include <editeng/postitem.hxx> 91 #include <editeng/section.hxx> 92 #include <editeng/shdditem.hxx> 93 #include <editeng/udlnitem.hxx> 94 #include <editeng/wghtitem.hxx> 95 #include <editeng/wrlmitem.hxx> 96 #include <editeng/xmlcnitm.hxx> 97 #include <editeng/flditem.hxx> 98 #include <editeng/eeitem.hxx> 99 #include <formula/errorcodes.hxx> 100 #include <xmloff/xmlerror.hxx> 101 #include <xmloff/XMLEventExport.hxx> 102 #include <xmloff/xmlprmap.hxx> 103 #include <xmloff/ProgressBarHelper.hxx> 104 105 #include <sax/tools/converter.hxx> 106 107 #include <rtl/ustring.hxx> 108 109 #include <tools/color.hxx> 110 #include <rtl/math.hxx> 111 #include <svl/zforlist.hxx> 112 #include <svx/unoshape.hxx> 113 #include <comphelper/base64.hxx> 114 #include <comphelper/extract.hxx> 115 #include <svx/svdobj.hxx> 116 #include <svx/svdocapt.hxx> 117 #include <svtools/miscopt.hxx> 118 #include <vcl/svapp.hxx> 119 120 #include <comphelper/processfactory.hxx> 121 #include <com/sun/star/beans/XPropertySet.hpp> 122 #include <com/sun/star/container/XNamed.hpp> 123 #include <com/sun/star/drawing/XDrawPageSupplier.hpp> 124 #include <com/sun/star/form/XFormsSupplier2.hpp> 125 #include <com/sun/star/io/XActiveDataSource.hpp> 126 #include <com/sun/star/io/XSeekable.hpp> 127 #include <com/sun/star/sheet/XUsedAreaCursor.hpp> 128 #include <com/sun/star/sheet/XCellRangeAddressable.hpp> 129 #include <com/sun/star/sheet/XPrintAreas.hpp> 130 #include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp> 131 #include <com/sun/star/sheet/XLabelRange.hpp> 132 #include <com/sun/star/sheet/NamedRangeFlag.hpp> 133 #include <com/sun/star/sheet/XSheetCellCursor.hpp> 134 #include <com/sun/star/sheet/XSheetCellRanges.hpp> 135 #include <com/sun/star/sheet/XSheetLinkable.hpp> 136 #include <com/sun/star/sheet/GlobalSheetSettings.hpp> 137 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> 138 #include <com/sun/star/table/XColumnRowRange.hpp> 139 #include <com/sun/star/util/XProtectable.hpp> 140 141 #include <com/sun/star/chart2/XChartDocument.hpp> 142 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp> 143 #include <com/sun/star/chart2/data/XDataReceiver.hpp> 144 145 #include <com/sun/star/document/XDocumentProperties.hpp> 146 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> 147 148 #include "XMLCodeNameProvider.hxx" 149 150 #include <sfx2/linkmgr.hxx> 151 #include <sfx2/objsh.hxx> 152 153 #include <memory> 154 #include <vector> 155 #include <vbahelper/vbaaccesshelper.hxx> 156 157 namespace com { namespace sun { namespace star { namespace uno { class XComponentContext; } } } } 158 159 160 161 //! not found in unonames.hxx 162 #define SC_LAYERID "LayerID" 163 164 #define SC_VIEWCHANGES_COUNT 13 165 #define SC_SHOW_CHANGES 0 166 #define SC_SHOW_ACCEPTED_CHANGES 1 167 #define SC_SHOW_REJECTED_CHANGES 2 168 #define SC_SHOW_CHANGES_BY_DATETIME 3 169 #define SC_SHOW_CHANGES_BY_DATETIME_MODE 4 170 #define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5 171 #define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6 172 #define SC_SHOW_CHANGES_BY_AUTHOR 7 173 #define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8 174 #define SC_SHOW_CHANGES_BY_COMMENT 9 175 #define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10 176 #define SC_SHOW_CHANGES_BY_RANGES 11 177 #define SC_SHOW_CHANGES_BY_RANGES_LIST 12 178 179 using namespace formula; 180 using namespace com::sun::star; 181 using namespace xmloff::token; 182 using ::std::vector; 183 using ::com::sun::star::uno::UNO_QUERY; 184 185 namespace 186 { 187 OUString lcl_RangeSequenceToString( 188 const uno::Sequence< OUString > & rRanges, 189 const uno::Reference< chart2::data::XRangeXMLConversion > & xFormatConverter ) 190 { 191 OUStringBuffer aResult; 192 const sal_Int32 nMaxIndex( rRanges.getLength() - 1 ); 193 const sal_Unicode cSep(' '); 194 for( sal_Int32 i=0; i<=nMaxIndex; ++i ) 195 { 196 OUString aRange( rRanges[i] ); 197 if( xFormatConverter.is()) 198 aRange = xFormatConverter->convertRangeToXML( aRange ); 199 aResult.append( aRange ); 200 if( i < nMaxIndex ) 201 aResult.append( cSep ); 202 } 203 return aResult.makeStringAndClear(); 204 } 205 206 OUString lcl_GetFormattedString(ScDocument* pDoc, ScRefCellValue& rCell, const ScAddress& rAddr) 207 { 208 // return text/edit cell string content, with line feeds in edit cells 209 210 if (!pDoc) 211 return EMPTY_OUSTRING; 212 213 switch (rCell.meType) 214 { 215 case CELLTYPE_STRING: 216 { 217 OUString aStr; 218 Color* pColor; 219 SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); 220 221 sal_uInt32 nFormat = pDoc->GetNumberFormat(rAddr); 222 ScCellFormat::GetString(rCell, nFormat, aStr, &pColor, *pFormatter, pDoc); 223 return aStr; 224 } 225 case CELLTYPE_EDIT: 226 { 227 const EditTextObject* pData = rCell.mpEditText; 228 if (!pData) 229 return EMPTY_OUSTRING; 230 231 EditEngine& rEngine = pDoc->GetEditEngine(); 232 rEngine.SetText(*pData); 233 return rEngine.GetText(); 234 } 235 break; 236 default: 237 ; 238 } 239 240 return EMPTY_OUSTRING; 241 } 242 243 } // anonymous namespace 244 245 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 246 Calc_XMLExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 247 { 248 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLExporter", SvXMLExportFlags::ALL)); 249 } 250 251 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 252 Calc_XMLMetaExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 253 { 254 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLMetaExporter", SvXMLExportFlags::META)); 255 } 256 257 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 258 Calc_XMLStylesExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 259 { 260 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLStylesExporter", SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS)); 261 } 262 263 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 264 Calc_XMLContentExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 265 { 266 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLContentExporter", SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::FONTDECLS)); 267 } 268 269 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 270 Calc_XMLSettingsExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 271 { 272 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLSettingsExporter", SvXMLExportFlags::SETTINGS)); 273 } 274 275 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 276 Calc_XMLOasisExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 277 { 278 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisExporter", SvXMLExportFlags::ALL|SvXMLExportFlags::OASIS)); 279 } 280 281 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 282 Calc_XMLOasisMetaExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 283 { 284 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisMetaExporter", SvXMLExportFlags::META|SvXMLExportFlags::OASIS)); 285 } 286 287 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 288 Calc_XMLOasisStylesExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 289 { 290 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisStylesExporter", SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::OASIS)); 291 } 292 293 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 294 Calc_XMLOasisContentExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 295 { 296 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisContentExporter", SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::OASIS)); 297 } 298 299 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 300 Calc_XMLOasisSettingsExporter_get_implementation(css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const &) 301 { 302 return cppu::acquire(new ScXMLExport(context, "com.sun.star.comp.Calc.XMLOasisSettingsExporter", SvXMLExportFlags::SETTINGS|SvXMLExportFlags::OASIS)); 303 } 304 305 class ScXMLShapeExport : public XMLShapeExport 306 { 307 public: 308 explicit ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {} 309 310 /** is called before a shape element for the given XShape is exported */ 311 virtual void onExport( const uno::Reference < drawing::XShape >& xShape ) override; 312 }; 313 314 void ScXMLShapeExport::onExport( const uno::Reference < drawing::XShape >& xShape ) 315 { 316 uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY ); 317 if( xShapeProp.is() ) 318 { 319 sal_Int16 nLayerID = 0; 320 if( (xShapeProp->getPropertyValue( SC_LAYERID ) >>= nLayerID) && (SdrLayerID(nLayerID) == SC_LAYER_BACK) ) 321 GetExport().AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_BACKGROUND, XML_TRUE); 322 } 323 } 324 325 sal_Int16 ScXMLExport::GetMeasureUnit() 326 { 327 css::uno::Reference<css::sheet::XGlobalSheetSettings> xProperties = 328 css::sheet::GlobalSheetSettings::create( comphelper::getProcessComponentContext() ); 329 return xProperties->getMetric(); 330 } 331 332 static const OUStringLiteral gsLayerID( SC_LAYERID ); 333 334 ScXMLExport::ScXMLExport( 335 const css::uno::Reference< css::uno::XComponentContext >& rContext, 336 OUString const & implementationName, SvXMLExportFlags nExportFlag) 337 : SvXMLExport( GetMeasureUnit(), 338 rContext, implementationName, XML_SPREADSHEET, nExportFlag ), 339 pDoc(nullptr), 340 nSourceStreamPos(0), 341 aTableStyles(), 342 pCurrentCell(nullptr), 343 nOpenRow(-1), 344 nProgressCount(0), 345 nCurrentTable(0), 346 bHasRowHeader(false), 347 bRowHeaderOpen(false) 348 { 349 if (getExportFlags() & SvXMLExportFlags::CONTENT) 350 { 351 pGroupColumns.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP) ); 352 pGroupRows.reset( new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP) ); 353 pColumnStyles.reset( new ScColumnStyles() ); 354 pRowStyles.reset( new ScRowStyles() ); 355 pRowFormatRanges.reset( new ScRowFormatRanges() ); 356 pMergedRangesContainer.reset( new ScMyMergedRangesContainer() ); 357 pValidationsContainer.reset( new ScMyValidationsContainer() ); 358 mpCellsItr.reset(new ScMyNotEmptyCellsIterator(*this)); 359 pDefaults.reset( new ScMyDefaultStyles ); 360 } 361 pCellStyles.reset( new ScFormatRangeStyles() ); 362 363 // document is not set here - create ScChangeTrackingExportHelper later 364 365 xScPropHdlFactory = new XMLScPropHdlFactory; 366 xCellStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScCellStylesProperties, xScPropHdlFactory, true); 367 xColumnStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScColumnStylesProperties, xScPropHdlFactory, true); 368 xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScRowStylesProperties, xScPropHdlFactory, true); 369 xTableStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScTableStylesProperties, xScPropHdlFactory, true); 370 xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper); 371 xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this)); 372 xColumnStylesExportPropertySetMapper = new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper); 373 xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper); 374 xTableStylesExportPropertySetMapper = new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper); 375 376 GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME, 377 xCellStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX); 378 GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME, 379 xColumnStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX); 380 GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW, XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME, 381 xRowStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX); 382 GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME, 383 xTableStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX); 384 385 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) 386 { 387 // This name is reserved for the external ref cache tables. This 388 // should not conflict with user-defined styles since this name is 389 // used for a table style which is not available in the UI. 390 sExternalRefTabStyleName = "ta_extref"; 391 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sExternalRefTabStyleName); 392 393 sAttrName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NAME)); 394 sAttrStyleName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME)); 395 sAttrColumnsRepeated = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED)); 396 sAttrFormula = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_FORMULA)); 397 sAttrStringValue = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE)); 398 sAttrValueType = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE)); 399 sElemCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_CELL)); 400 sElemCoveredCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_COVERED_TABLE_CELL)); 401 sElemCol = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_COLUMN)); 402 sElemRow = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_ROW)); 403 sElemTab = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE)); 404 sElemP = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT, GetXMLToken(XML_P)); 405 } 406 } 407 408 ScXMLExport::~ScXMLExport() 409 { 410 pGroupColumns.reset(); 411 pGroupRows.reset(); 412 pColumnStyles.reset(); 413 pRowStyles.reset(); 414 pCellStyles.reset(); 415 pRowFormatRanges.reset(); 416 pMergedRangesContainer.reset(); 417 pValidationsContainer.reset(); 418 pChangeTrackingExportHelper.reset(); 419 pDefaults.reset(); 420 pNumberFormatAttributesExportHelper.reset(); 421 } 422 423 void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream ) 424 { 425 xSourceStream = xNewStream; 426 427 if ( xSourceStream.is() ) 428 { 429 // make sure it's a plain UTF-8 stream as written by OOo itself 430 431 const sal_Char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 432 sal_Int32 nLen = strlen(pXmlHeader); 433 434 uno::Sequence<sal_Int8> aFileStart(nLen); 435 sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen ); 436 437 if ( nRead != nLen || memcmp( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 ) 438 { 439 // invalid - ignore stream, save normally 440 xSourceStream.clear(); 441 } 442 else 443 { 444 // keep track of the bytes already read 445 nSourceStreamPos = nRead; 446 447 const ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(GetModel())->GetSheetSaveData(); 448 if (pSheetData) 449 { 450 // add the loaded namespaces to the name space map 451 452 if ( !pSheetData->AddLoadedNamespaces( GetNamespaceMap_() ) ) 453 { 454 // conflicts in the namespaces - ignore the stream, save normally 455 xSourceStream.clear(); 456 } 457 } 458 } 459 } 460 } 461 462 sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const 463 { 464 NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt); 465 if (itr == aNumFmtIndexMap.end()) 466 return -1; 467 468 return itr->second; 469 } 470 471 void ScXMLExport::CollectSharedData(SCTAB& nTableCount, sal_Int32& nShapesCount) 472 { 473 if (!GetModel().is()) 474 return; 475 476 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc(GetModel(), uno::UNO_QUERY); 477 if (!xSpreadDoc.is()) 478 return; 479 480 uno::Reference<container::XIndexAccess> xIndex(xSpreadDoc->getSheets(), uno::UNO_QUERY); 481 if (!xIndex.is()) 482 return; 483 484 nTableCount = xIndex->getCount(); 485 if (!pSharedData) 486 pSharedData.reset(new ScMySharedData(nTableCount)); 487 488 pCellStyles->AddNewTable(nTableCount - 1); 489 490 for (SCTAB nTable = 0; nTable < nTableCount; ++nTable) 491 { 492 nCurrentTable = sal::static_int_cast<sal_uInt16>(nTable); 493 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY); 494 if (!xDrawPageSupplier.is()) 495 continue; 496 497 uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage()); 498 ScMyDrawPage aDrawPage; 499 aDrawPage.bHasForms = false; 500 aDrawPage.xDrawPage.set(xDrawPage); 501 pSharedData->AddDrawPage(aDrawPage, nTable); 502 if (!xDrawPage.is()) 503 continue; 504 505 sal_Int32 nShapes = xDrawPage->getCount(); 506 for (sal_Int32 nShape = 0; nShape < nShapes; ++nShape) 507 { 508 uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(nShape), uno::UNO_QUERY); 509 if (!xShape.is()) 510 continue; 511 512 uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY); 513 if (!xShapeProp.is()) 514 continue; 515 516 sal_Int16 nLayerID = 0; 517 bool bExtracted = xShapeProp->getPropertyValue(gsLayerID) >>= nLayerID; 518 if (!bExtracted) 519 continue; 520 521 if ((SdrLayerID(nLayerID) == SC_LAYER_INTERN) || (SdrLayerID(nLayerID) == SC_LAYER_HIDDEN)) 522 { 523 CollectInternalShape(xShape); 524 continue; 525 } 526 527 ++nShapesCount; 528 529 SvxShape* pShapeImp = comphelper::getUnoTunnelImplementation<SvxShape>(xShape); 530 if (!pShapeImp) 531 continue; 532 533 SdrObject* pSdrObj = pShapeImp->GetSdrObject(); 534 if (!pSdrObj) 535 continue; 536 537 if (ScDrawObjData *pAnchor = ScDrawLayer::GetNonRotatedObjData(pSdrObj)) 538 { 539 ScMyShape aMyShape; 540 aMyShape.aAddress = pAnchor->maStart; 541 SAL_WARN_IF(aMyShape.aAddress.Tab() != nTable, "sc", "not anchored to current sheet!"); 542 aMyShape.aAddress.SetTab(nTable); 543 aMyShape.aEndAddress = pAnchor->maEnd; 544 aMyShape.aEndAddress.SetTab( nTable ); 545 aMyShape.nEndX = pAnchor->maEndOffset.X(); 546 aMyShape.nEndY = pAnchor->maEndOffset.Y(); 547 aMyShape.xShape = xShape; 548 aMyShape.bResizeWithCell = ScDrawLayer::IsResizeWithCell(*pSdrObj); 549 pSharedData->AddNewShape(aMyShape); 550 pSharedData->SetLastColumn(nTable, pAnchor->maStart.Col()); 551 pSharedData->SetLastRow(nTable, pAnchor->maStart.Row()); 552 } 553 else 554 pSharedData->AddTableShape(nTable, xShape); 555 } 556 } 557 } 558 559 void ScXMLExport::CollectShapesAutoStyles(SCTAB nTableCount) 560 { 561 // #i84077# To avoid compiler warnings about uninitialized aShapeItr, 562 // it's initialized using this dummy list. The iterator contains shapes 563 // from all sheets, so it can't be declared inside the nTable loop where 564 // it is used. 565 ScMyShapeList aDummyInitList; 566 567 pSharedData->SortShapesContainer(); 568 pSharedData->SortNoteShapes(); 569 const ScMyShapeList* pShapeList(nullptr); 570 ScMyShapeList::const_iterator aShapeItr = aDummyInitList.end(); 571 if (pSharedData->GetShapesContainer()) 572 { 573 pShapeList = &pSharedData->GetShapesContainer()->GetShapes(); 574 aShapeItr = pShapeList->begin(); 575 } 576 if (pSharedData->HasDrawPage()) 577 { 578 for (SCTAB nTable = 0; nTable < nTableCount; ++nTable) 579 { 580 uno::Reference<drawing::XDrawPage> xDrawPage(pSharedData->GetDrawPage(nTable)); 581 582 if (xDrawPage.is()) 583 { 584 GetShapeExport()->seekShapes(xDrawPage); 585 uno::Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, uno::UNO_QUERY ); 586 if( xFormsSupplier.is() && xFormsSupplier->hasForms() ) 587 { 588 GetFormExport()->examineForms(xDrawPage); 589 pSharedData->SetDrawPageHasForms(nTable, true); 590 } 591 ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes()); 592 if (pTableShapes) 593 { 594 for (const auto& rxShape : (*pTableShapes)[nTable]) 595 { 596 GetShapeExport()->collectShapeAutoStyles(rxShape); 597 IncrementProgressBar(false); 598 } 599 } 600 if (pShapeList) 601 { 602 ScMyShapeList::const_iterator aEndItr(pShapeList->end()); 603 while ( aShapeItr != aEndItr && ( aShapeItr->aAddress.Tab() == nTable ) ) 604 { 605 GetShapeExport()->collectShapeAutoStyles(aShapeItr->xShape); 606 IncrementProgressBar(false); 607 ++aShapeItr; 608 } 609 } 610 if (pSharedData->GetNoteShapes()) 611 { 612 const ScMyNoteShapeList& rNoteShapes = pSharedData->GetNoteShapes()->GetNotes(); 613 for (const auto& rNoteShape : rNoteShapes) 614 { 615 if ( rNoteShape.aPos.Tab() == nTable ) 616 GetShapeExport()->collectShapeAutoStyles(rNoteShape.xShape); 617 } 618 } 619 } 620 } 621 } 622 pSharedData->SortNoteShapes(); // sort twice, because some more shapes are added 623 } 624 625 void ScXMLExport::ExportMeta_() 626 { 627 sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0); 628 SCTAB nTableCount(0); 629 sal_Int32 nShapesCount(0); 630 GetAutoStylePool()->ClearEntries(); 631 CollectSharedData(nTableCount, nShapesCount); 632 633 uno::Sequence<beans::NamedValue> stats 634 { 635 { "TableCount", uno::makeAny(static_cast<sal_Int32>(nTableCount)) }, 636 { "CellCount", uno::makeAny(nCellCount) }, 637 { "ObjectCount", uno::makeAny(nShapesCount) } 638 }; 639 640 // update document statistics at the model 641 uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(), 642 uno::UNO_QUERY_THROW); 643 uno::Reference<document::XDocumentProperties> xDocProps( 644 xPropSup->getDocumentProperties()); 645 if (xDocProps.is()) { 646 xDocProps->setDocumentStatistics(stats); 647 } 648 649 // export document properties 650 SvXMLExport::ExportMeta_(); 651 } 652 653 void ScXMLExport::ExportFontDecls_() 654 { 655 GetFontAutoStylePool(); // make sure the pool is created 656 SvXMLExport::ExportFontDecls_(); 657 } 658 659 table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable) 660 { 661 table::CellRangeAddress aCellAddress; 662 uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor()); 663 uno::Reference<sheet::XUsedAreaCursor> xUsedArea (xCursor, uno::UNO_QUERY); 664 uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY); 665 if (xUsedArea.is() && xCellAddress.is()) 666 { 667 xUsedArea->gotoEndOfUsedArea(true); 668 aCellAddress = xCellAddress->getRangeAddress(); 669 } 670 return aCellAddress; 671 } 672 673 void ScXMLExport::GetAreaLinks( ScMyAreaLinksContainer& rAreaLinks ) 674 { 675 if (pDoc->GetLinkManager()) 676 { 677 const sfx2::SvBaseLinks& rLinks = pDoc->GetLinkManager()->GetLinks(); 678 for (const auto & rLink : rLinks) 679 { 680 ScAreaLink *pLink = dynamic_cast<ScAreaLink*>(rLink.get()); 681 if (pLink) 682 { 683 ScMyAreaLink aAreaLink; 684 aAreaLink.aDestRange = pLink->GetDestArea(); 685 aAreaLink.sSourceStr = pLink->GetSource(); 686 aAreaLink.sFilter = pLink->GetFilter(); 687 aAreaLink.sFilterOptions = pLink->GetOptions(); 688 aAreaLink.sURL = pLink->GetFile(); 689 aAreaLink.nRefresh = pLink->GetRefreshDelay(); 690 rAreaLinks.AddNewAreaLink( aAreaLink ); 691 } 692 } 693 } 694 rAreaLinks.Sort(); 695 } 696 697 // core implementation 698 void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp ) 699 { 700 if (pDoc) 701 { 702 ScDetOpList* pOpList(pDoc->GetDetOpList()); 703 if( pOpList ) 704 { 705 size_t nCount = pOpList->Count(); 706 for (size_t nIndex = 0; nIndex < nCount; ++nIndex ) 707 { 708 const ScDetOpData& rDetData = pOpList->GetObject( nIndex); 709 const ScAddress& rDetPos = rDetData.GetPos(); 710 SCTAB nTab = rDetPos.Tab(); 711 if ( nTab < pDoc->GetTableCount() ) 712 { 713 rDetOp.AddOperation( rDetData.GetOperation(), rDetPos, static_cast<sal_uInt32>( nIndex) ); 714 715 // cells with detective operations are written even if empty 716 pSharedData->SetLastColumn( nTab, rDetPos.Col() ); 717 pSharedData->SetLastRow( nTab, rDetPos.Row() ); 718 } 719 } 720 rDetOp.Sort(); 721 } 722 } 723 } 724 725 void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex, 726 const sal_Int32 nIndex, const bool bIsAutoStyle, const bool bIsVisible) 727 { 728 CheckAttrList(); 729 AddAttribute(sAttrStyleName, pColumnStyles->GetStyleNameByIndex(nStyleIndex)); 730 if (!bIsVisible) 731 AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE); 732 if (nRepeatColumns > 1) 733 { 734 OUString sOUEndCol(OUString::number(nRepeatColumns)); 735 AddAttribute(sAttrColumnsRepeated, sOUEndCol); 736 } 737 if (nIndex != -1) 738 AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); 739 SvXMLElementExport aElemC(*this, sElemCol, true, true); 740 } 741 742 void ScXMLExport::WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns, 743 const sal_Int32 nStyleIndex, const bool bIsVisible) 744 { 745 sal_Int32 nRepeat(1); 746 sal_Int32 nPrevIndex(pDefaults->GetColDefaults()[nColumn].nIndex); 747 bool bPrevAutoStyle(pDefaults->GetColDefaults()[nColumn].bIsAutoStyle); 748 for (sal_Int32 i = nColumn + 1; i < nColumn + nRepeatColumns; ++i) 749 { 750 if ((pDefaults->GetColDefaults()[i].nIndex != nPrevIndex) || 751 (pDefaults->GetColDefaults()[i].bIsAutoStyle != bPrevAutoStyle)) 752 { 753 WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible); 754 nPrevIndex = pDefaults->GetColDefaults()[i].nIndex; 755 bPrevAutoStyle = pDefaults->GetColDefaults()[i].bIsAutoStyle; 756 nRepeat = 1; 757 } 758 else 759 ++nRepeat; 760 } 761 WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible); 762 } 763 764 void ScXMLExport::OpenHeaderColumn() 765 { 766 StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, true ); 767 } 768 769 void ScXMLExport::CloseHeaderColumn() 770 { 771 EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, true); 772 } 773 774 void ScXMLExport::ExportColumns(const sal_Int32 nTable, const ScRange& aColumnHeaderRange, const bool bHasColumnHeader) 775 { 776 sal_Int32 nColsRepeated (1); 777 sal_Int32 nIndex; 778 sal_Int32 nPrevColumn(0); 779 bool bPrevIsVisible (true); 780 bool bWasHeader (false); 781 bool bIsClosed (true); 782 sal_Int32 nPrevIndex (-1); 783 sal_Int32 nColumn; 784 for (nColumn = 0; nColumn <= pSharedData->GetLastColumn(nTable); ++nColumn) 785 { 786 CheckAttrList(); 787 bool bIsVisible(true); 788 nIndex = pColumnStyles->GetStyleNameIndex(nTable, nColumn, bIsVisible); 789 790 const bool bIsHeader = bHasColumnHeader && (aColumnHeaderRange.aStart.Col() <= nColumn) && (nColumn <= aColumnHeaderRange.aEnd.Col()); 791 if (bIsHeader != bWasHeader) 792 { 793 if (bIsHeader) 794 { 795 if (nColumn > 0) 796 { 797 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); 798 if (pGroupColumns->IsGroupEnd(nColumn - 1)) 799 pGroupColumns->CloseGroups(nColumn - 1); 800 } 801 bPrevIsVisible = bIsVisible; 802 nPrevIndex = nIndex; 803 nPrevColumn = nColumn; 804 nColsRepeated = 1; 805 if(pGroupColumns->IsGroupStart(nColumn)) 806 pGroupColumns->OpenGroups(nColumn); 807 OpenHeaderColumn(); 808 bWasHeader = true; 809 bIsClosed = false; 810 } 811 else 812 { 813 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); 814 CloseHeaderColumn(); 815 if (pGroupColumns->IsGroupEnd(nColumn - 1)) 816 pGroupColumns->CloseGroups(nColumn - 1); 817 if(pGroupColumns->IsGroupStart(nColumn)) 818 pGroupColumns->OpenGroups(nColumn); 819 bPrevIsVisible = bIsVisible; 820 nPrevIndex = nIndex; 821 nPrevColumn = nColumn; 822 nColsRepeated = 1; 823 bWasHeader = false; 824 bIsClosed = true; 825 } 826 } 827 else if (nColumn == 0) 828 { 829 if (pGroupColumns->IsGroupStart(nColumn)) 830 pGroupColumns->OpenGroups(nColumn); 831 bPrevIsVisible = bIsVisible; 832 nPrevIndex = nIndex; 833 } 834 else if ((bIsVisible == bPrevIsVisible) && (nIndex == nPrevIndex) && 835 !pGroupColumns->IsGroupStart(nColumn) && !pGroupColumns->IsGroupEnd(nColumn - 1)) 836 ++nColsRepeated; 837 else 838 { 839 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); 840 if (pGroupColumns->IsGroupEnd(nColumn - 1)) 841 { 842 if (bIsHeader) 843 CloseHeaderColumn(); 844 pGroupColumns->CloseGroups(nColumn - 1); 845 if (bIsHeader) 846 OpenHeaderColumn(); 847 } 848 if (pGroupColumns->IsGroupStart(nColumn)) 849 { 850 if (bIsHeader) 851 CloseHeaderColumn(); 852 pGroupColumns->OpenGroups(nColumn); 853 if (bIsHeader) 854 OpenHeaderColumn(); 855 } 856 bPrevIsVisible = bIsVisible; 857 nPrevIndex = nIndex; 858 nPrevColumn = nColumn; 859 nColsRepeated = 1; 860 } 861 } 862 assert(nPrevIndex >= 0 && "coverity#1438402"); 863 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); 864 if (!bIsClosed) 865 CloseHeaderColumn(); 866 if (pGroupColumns->IsGroupEnd(nColumn - 1)) 867 pGroupColumns->CloseGroups(nColumn - 1); 868 } 869 870 void ScXMLExport::ExportExternalRefCacheStyles() 871 { 872 sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex( 873 "NumberFormat", XML_NAMESPACE_STYLE, "data-style-name"); 874 875 if (nEntryIndex < 0) 876 // No entry index for the number format is found. 877 return; 878 879 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); 880 if (!pRefMgr->hasExternalData()) 881 // No external reference data cached. 882 return; 883 884 // Export each unique number format used in the external ref cache. 885 vector<sal_uInt32> aNumFmts; 886 pRefMgr->getAllCachedNumberFormats(aNumFmts); 887 const OUString aDefaultStyle = OUString("Default").intern(); 888 for (const auto& rNumFmt : aNumFmts) 889 { 890 sal_Int32 nNumFmt = static_cast<sal_Int32>(rNumFmt); 891 892 addDataStyle(nNumFmt); 893 894 uno::Any aVal; 895 aVal <<= nNumFmt; 896 vector<XMLPropertyState> aProps; 897 aVal <<= aDefaultStyle; 898 aProps.emplace_back(nEntryIndex, aVal); 899 900 OUString aName; 901 sal_Int32 nIndex; 902 if (GetAutoStylePool()->Add(aName, XML_STYLE_FAMILY_TABLE_CELL, aDefaultStyle, aProps)) 903 { 904 pCellStyles->AddStyleName(aName, nIndex); 905 } 906 else 907 { 908 bool bIsAuto; 909 nIndex = pCellStyles->GetIndexOfStyleName( 910 aName, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX, bIsAuto); 911 } 912 913 // store the number format to index mapping for later use. 914 aNumFmtIndexMap.emplace(nNumFmt, nIndex); 915 } 916 } 917 918 namespace { 919 920 void handleFont( 921 std::vector<XMLPropertyState>& rPropStates, 922 const SfxPoolItem* p, const rtl::Reference<XMLPropertySetMapper>& xMapper, const OUString& rXMLName ) 923 { 924 sal_Int32 nEntryCount = xMapper->GetEntryCount(); 925 926 // Apparently font info needs special handling. 927 const SvxFontItem* pItem = static_cast<const SvxFontItem*>(p); 928 929 sal_Int32 nIndexFontName = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, rXMLName, 0); 930 931 if (nIndexFontName == -1 || nIndexFontName >= nEntryCount) 932 return; 933 934 uno::Any aAny; 935 if (!pItem->QueryValue(aAny, MID_FONT_FAMILY_NAME)) 936 return; 937 938 rPropStates.emplace_back(nIndexFontName, aAny); 939 } 940 941 const SvxFieldData* toXMLPropertyStates( 942 std::vector<XMLPropertyState>& rPropStates, const std::vector<const SfxPoolItem*>& rSecAttrs, 943 const rtl::Reference<XMLPropertySetMapper>& xMapper, const ScXMLEditAttributeMap& rAttrMap ) 944 { 945 const SvxFieldData* pField = nullptr; 946 sal_Int32 nEntryCount = xMapper->GetEntryCount(); 947 rPropStates.reserve(rSecAttrs.size()); 948 for (const SfxPoolItem* p : rSecAttrs) 949 { 950 if (p->Which() == EE_FEATURE_FIELD) 951 { 952 pField = static_cast<const SvxFieldItem*>(p)->GetField(); 953 continue; 954 } 955 956 const ScXMLEditAttributeMap::Entry* pEntry = rAttrMap.getEntryByItemID(p->Which()); 957 if (!pEntry) 958 continue; 959 960 sal_Int32 nIndex = xMapper->GetEntryIndex( 961 pEntry->nmXMLNS, OUString::createFromAscii(pEntry->mpXMLName), 0); 962 963 if (nIndex == -1 || nIndex >= nEntryCount) 964 continue; 965 966 uno::Any aAny; 967 switch (p->Which()) 968 { 969 case EE_CHAR_FONTINFO: 970 handleFont(rPropStates, p, xMapper, "font-name"); 971 break; 972 case EE_CHAR_FONTINFO_CJK: 973 handleFont(rPropStates, p, xMapper, "font-name-asian"); 974 break; 975 case EE_CHAR_FONTINFO_CTL: 976 handleFont(rPropStates, p, xMapper, "font-name-complex"); 977 break; 978 case EE_CHAR_WEIGHT: 979 case EE_CHAR_WEIGHT_CJK: 980 case EE_CHAR_WEIGHT_CTL: 981 { 982 if (!static_cast<const SvxWeightItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 983 continue; 984 985 rPropStates.emplace_back(nIndex, aAny); 986 } 987 break; 988 case EE_CHAR_FONTHEIGHT: 989 case EE_CHAR_FONTHEIGHT_CJK: 990 case EE_CHAR_FONTHEIGHT_CTL: 991 { 992 if (!static_cast<const SvxFontHeightItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 993 continue; 994 995 rPropStates.emplace_back(nIndex, aAny); 996 } 997 break; 998 case EE_CHAR_ITALIC: 999 case EE_CHAR_ITALIC_CJK: 1000 case EE_CHAR_ITALIC_CTL: 1001 { 1002 if (!static_cast<const SvxPostureItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1003 continue; 1004 1005 rPropStates.emplace_back(nIndex, aAny); 1006 } 1007 break; 1008 case EE_CHAR_UNDERLINE: 1009 { 1010 // Underline attribute needs to export multiple entries. 1011 sal_Int32 nIndexStyle = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-style", 0); 1012 if (nIndexStyle == -1 || nIndexStyle > nEntryCount) 1013 break; 1014 1015 sal_Int32 nIndexWidth = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-width", 0); 1016 if (nIndexWidth == -1 || nIndexWidth > nEntryCount) 1017 break; 1018 1019 sal_Int32 nIndexType = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-underline-type", 0); 1020 if (nIndexType == -1 || nIndexType > nEntryCount) 1021 break; 1022 1023 sal_Int32 nIndexColor = xMapper->FindEntryIndex("CharUnderlineColor", XML_NAMESPACE_STYLE, "text-underline-color"); 1024 if (nIndexColor == -1 || nIndexColor > nEntryCount) 1025 break; 1026 1027 sal_Int32 nIndexHasColor = xMapper->FindEntryIndex("CharUnderlineHasColor", XML_NAMESPACE_STYLE, "text-underline-color"); 1028 if (nIndexHasColor == -1 || nIndexHasColor > nEntryCount) 1029 break; 1030 1031 const SvxUnderlineItem* pUL = static_cast<const SvxUnderlineItem*>(p); 1032 pUL->QueryValue(aAny, MID_TL_STYLE); 1033 rPropStates.emplace_back(nIndexStyle, aAny); 1034 rPropStates.emplace_back(nIndexType, aAny); 1035 rPropStates.emplace_back(nIndexWidth, aAny); 1036 1037 pUL->QueryValue(aAny, MID_TL_COLOR); 1038 rPropStates.emplace_back(nIndexColor, aAny); 1039 1040 pUL->QueryValue(aAny, MID_TL_HASCOLOR); 1041 rPropStates.emplace_back(nIndexHasColor, aAny); 1042 } 1043 break; 1044 case EE_CHAR_OVERLINE: 1045 { 1046 // Same with overline. Do just as we do with underline attributes. 1047 sal_Int32 nIndexStyle = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-style", 0); 1048 if (nIndexStyle == -1 || nIndexStyle > nEntryCount) 1049 break; 1050 1051 sal_Int32 nIndexWidth = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-width", 0); 1052 if (nIndexWidth == -1 || nIndexWidth > nEntryCount) 1053 break; 1054 1055 sal_Int32 nIndexType = xMapper->GetEntryIndex(XML_NAMESPACE_STYLE, "text-overline-type", 0); 1056 if (nIndexType == -1 || nIndexType > nEntryCount) 1057 break; 1058 1059 sal_Int32 nIndexColor = xMapper->FindEntryIndex("CharOverlineColor", XML_NAMESPACE_STYLE, "text-overline-color"); 1060 if (nIndexColor == -1 || nIndexColor > nEntryCount) 1061 break; 1062 1063 sal_Int32 nIndexHasColor = xMapper->FindEntryIndex("CharOverlineHasColor", XML_NAMESPACE_STYLE, "text-overline-color"); 1064 if (nIndexHasColor == -1 || nIndexHasColor > nEntryCount) 1065 break; 1066 1067 const SvxOverlineItem* pOL = static_cast<const SvxOverlineItem*>(p); 1068 pOL->QueryValue(aAny, MID_TL_STYLE); 1069 rPropStates.emplace_back(nIndexStyle, aAny); 1070 rPropStates.emplace_back(nIndexType, aAny); 1071 rPropStates.emplace_back(nIndexWidth, aAny); 1072 1073 pOL->QueryValue(aAny, MID_TL_COLOR); 1074 rPropStates.emplace_back(nIndexColor, aAny); 1075 1076 pOL->QueryValue(aAny, MID_TL_HASCOLOR); 1077 rPropStates.emplace_back(nIndexHasColor, aAny); 1078 } 1079 break; 1080 case EE_CHAR_COLOR: 1081 { 1082 if (!static_cast<const SvxColorItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1083 continue; 1084 1085 ::Color nColor; 1086 if ( aAny >>= nColor ) 1087 { 1088 sal_Int32 nIndexColor = ( nColor == COL_AUTO ) ? xMapper->GetEntryIndex( 1089 XML_NAMESPACE_STYLE, GetXMLToken( XML_USE_WINDOW_FONT_COLOR ), 0 ) : nIndex; 1090 rPropStates.emplace_back( nIndexColor, aAny ); 1091 } 1092 } 1093 break; 1094 case EE_CHAR_WLM: 1095 { 1096 if (!static_cast<const SvxWordLineModeItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1097 continue; 1098 1099 rPropStates.emplace_back(nIndex, aAny); 1100 } 1101 break; 1102 case EE_CHAR_STRIKEOUT: 1103 { 1104 if (!static_cast<const SvxCrossedOutItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1105 continue; 1106 1107 rPropStates.emplace_back(nIndex, aAny); 1108 } 1109 break; 1110 case EE_CHAR_RELIEF: 1111 { 1112 if (!static_cast<const SvxCharReliefItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1113 continue; 1114 1115 rPropStates.emplace_back(nIndex, aAny); 1116 } 1117 break; 1118 case EE_CHAR_OUTLINE: 1119 { 1120 if (!static_cast<const SvxContourItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1121 continue; 1122 1123 rPropStates.emplace_back(nIndex, aAny); 1124 } 1125 break; 1126 case EE_CHAR_SHADOW: 1127 { 1128 if (!static_cast<const SvxShadowedItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1129 continue; 1130 1131 rPropStates.emplace_back(nIndex, aAny); 1132 } 1133 break; 1134 case EE_CHAR_KERNING: 1135 { 1136 if (!static_cast<const SvxKerningItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1137 continue; 1138 1139 rPropStates.emplace_back(nIndex, aAny); 1140 } 1141 break; 1142 case EE_CHAR_PAIRKERNING: 1143 { 1144 if (!static_cast<const SvxAutoKernItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1145 continue; 1146 1147 rPropStates.emplace_back(nIndex, aAny); 1148 } 1149 break; 1150 case EE_CHAR_FONTWIDTH: 1151 { 1152 if (!static_cast<const SvxCharScaleWidthItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1153 continue; 1154 1155 rPropStates.emplace_back(nIndex, aAny); 1156 } 1157 break; 1158 case EE_CHAR_ESCAPEMENT: 1159 { 1160 sal_Int32 nIndexEsc = xMapper->FindEntryIndex("CharEscapement", XML_NAMESPACE_STYLE, "text-position"); 1161 if (nIndexEsc == -1 || nIndexEsc > nEntryCount) 1162 break; 1163 1164 sal_Int32 nIndexEscHeight = xMapper->FindEntryIndex("CharEscapementHeight", XML_NAMESPACE_STYLE, "text-position"); 1165 if (nIndexEscHeight == -1 || nIndexEscHeight > nEntryCount) 1166 break; 1167 1168 const SvxEscapementItem* pEsc = static_cast<const SvxEscapementItem*>(p); 1169 1170 pEsc->QueryValue(aAny); 1171 rPropStates.emplace_back(nIndexEsc, aAny); 1172 1173 pEsc->QueryValue(aAny, MID_ESC_HEIGHT); 1174 rPropStates.emplace_back(nIndexEscHeight, aAny); 1175 1176 } 1177 break; 1178 case EE_CHAR_EMPHASISMARK: 1179 { 1180 if (!static_cast<const SvxEmphasisMarkItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1181 continue; 1182 1183 rPropStates.emplace_back(nIndex, aAny); 1184 } 1185 break; 1186 case EE_CHAR_LANGUAGE: 1187 case EE_CHAR_LANGUAGE_CJK: 1188 case EE_CHAR_LANGUAGE_CTL: 1189 { 1190 if (!static_cast<const SvxLanguageItem*>(p)->QueryValue(aAny, pEntry->mnFlag)) 1191 continue; 1192 1193 // Export multiple entries. 1194 sal_Int32 nIndexLanguage, nIndexCountry, nIndexScript, nIndexTag; 1195 switch (p->Which()) 1196 { 1197 case EE_CHAR_LANGUAGE: 1198 nIndexLanguage = xMapper->GetEntryIndex( XML_NAMESPACE_FO, "language", 0); 1199 nIndexCountry = xMapper->GetEntryIndex( XML_NAMESPACE_FO, "country", 0); 1200 nIndexScript = xMapper->GetEntryIndex( XML_NAMESPACE_FO, "script", 0); 1201 nIndexTag = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "rfc-language-tag", 0); 1202 break; 1203 case EE_CHAR_LANGUAGE_CJK: 1204 nIndexLanguage = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "language-asian", 0); 1205 nIndexCountry = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "country-asian", 0); 1206 nIndexScript = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "script-asian", 0); 1207 nIndexTag = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "rfc-language-tag-asian", 0); 1208 break; 1209 case EE_CHAR_LANGUAGE_CTL: 1210 nIndexLanguage = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "language-complex", 0); 1211 nIndexCountry = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "country-complex", 0); 1212 nIndexScript = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "script-complex", 0); 1213 nIndexTag = xMapper->GetEntryIndex( XML_NAMESPACE_STYLE, "rfc-language-tag-complex", 0); 1214 break; 1215 default: 1216 nIndexLanguage = nIndexCountry = nIndexScript = nIndexTag = -1; 1217 } 1218 assert( nIndexLanguage >= 0 && nIndexCountry >= 0 && nIndexScript >= 0 && nIndexTag >= 0); 1219 rPropStates.emplace_back( nIndexLanguage, aAny); 1220 rPropStates.emplace_back( nIndexCountry, aAny); 1221 rPropStates.emplace_back( nIndexScript, aAny); 1222 rPropStates.emplace_back( nIndexTag, aAny); 1223 } 1224 break; 1225 default: 1226 continue; 1227 } 1228 } 1229 1230 return pField; 1231 } 1232 1233 } 1234 1235 void ScXMLExport::ExportCellTextAutoStyles(sal_Int32 nTable) 1236 { 1237 if (!ValidTab(nTable)) 1238 return; 1239 1240 rtl::Reference<XMLPropertySetMapper> xMapper = GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper(); 1241 rtl::Reference<SvXMLAutoStylePoolP> xStylePool = GetAutoStylePool(); 1242 const ScXMLEditAttributeMap& rAttrMap = GetEditAttributeMap(); 1243 1244 sc::EditTextIterator aIter(*pDoc, nTable); 1245 sal_Int32 nCellCount = 0; 1246 for (const EditTextObject* pEdit = aIter.first(); pEdit; pEdit = aIter.next(), ++nCellCount) 1247 { 1248 std::vector<editeng::Section> aAttrs; 1249 pEdit->GetAllSections(aAttrs); 1250 if (aAttrs.empty()) 1251 continue; 1252 1253 for (const auto& rSec : aAttrs) 1254 { 1255 const std::vector<const SfxPoolItem*>& rSecAttrs = rSec.maAttributes; 1256 if (rSecAttrs.empty()) 1257 // No formats applied to this section. Skip it. 1258 continue; 1259 1260 std::vector<XMLPropertyState> aPropStates; 1261 toXMLPropertyStates(aPropStates, rSecAttrs, xMapper, rAttrMap); 1262 if (!aPropStates.empty()) 1263 xStylePool->Add(XML_STYLE_FAMILY_TEXT_TEXT, OUString(), aPropStates); 1264 } 1265 } 1266 1267 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCellCount); 1268 } 1269 1270 void ScXMLExport::WriteRowContent() 1271 { 1272 ScMyRowFormatRange aRange; 1273 sal_Int32 nIndex(-1); 1274 #if OSL_DEBUG_LEVEL > 0 1275 sal_Int32 nPrevCol(0); 1276 #endif 1277 sal_Int32 nCols(0); 1278 sal_Int32 nPrevValidationIndex(-1); 1279 bool bIsAutoStyle(true); 1280 bool bIsFirst(true); 1281 while (pRowFormatRanges->GetNext(aRange)) 1282 { 1283 #if OSL_DEBUG_LEVEL > 0 1284 OSL_ENSURE(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn)), "here are some columns missing"); 1285 #endif 1286 if (bIsFirst) 1287 { 1288 nIndex = aRange.nIndex; 1289 nPrevValidationIndex = aRange.nValidationIndex; 1290 bIsAutoStyle = aRange.bIsAutoStyle; 1291 nCols = aRange.nRepeatColumns; 1292 bIsFirst = false; 1293 #if OSL_DEBUG_LEVEL > 0 1294 nPrevCol = aRange.nStartColumn; 1295 #endif 1296 } 1297 else 1298 { 1299 if (((aRange.nIndex == nIndex && aRange.bIsAutoStyle == bIsAutoStyle) || 1300 (aRange.nIndex == nIndex && nIndex == -1)) && 1301 nPrevValidationIndex == aRange.nValidationIndex) 1302 nCols += aRange.nRepeatColumns; 1303 else 1304 { 1305 if (nIndex != -1) 1306 AddAttribute(sAttrStyleName, pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); 1307 if (nPrevValidationIndex > -1) 1308 AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex)); 1309 if (nCols > 1) 1310 { 1311 AddAttribute(sAttrColumnsRepeated, OUString::number(nCols)); 1312 } 1313 SvXMLElementExport aElemC(*this, sElemCell, true, true); 1314 nIndex = aRange.nIndex; 1315 bIsAutoStyle = aRange.bIsAutoStyle; 1316 nCols = aRange.nRepeatColumns; 1317 nPrevValidationIndex = aRange.nValidationIndex; 1318 #if OSL_DEBUG_LEVEL > 0 1319 nPrevCol = aRange.nStartColumn; 1320 #endif 1321 } 1322 } 1323 } 1324 if (!bIsFirst) 1325 { 1326 if (nIndex != -1) 1327 AddAttribute(sAttrStyleName, pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); 1328 if (nPrevValidationIndex > -1) 1329 AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex)); 1330 if (nCols > 1) 1331 { 1332 AddAttribute(sAttrColumnsRepeated, OUString::number(nCols)); 1333 } 1334 SvXMLElementExport aElemC(*this, sElemCell, true, true); 1335 } 1336 } 1337 1338 void ScXMLExport::WriteRowStartTag( 1339 const sal_Int32 nIndex, const sal_Int32 nEqualRows, 1340 bool bHidden, bool bFiltered) 1341 { 1342 AddAttribute(sAttrStyleName, pRowStyles->GetStyleNameByIndex(nIndex)); 1343 if (bHidden) 1344 { 1345 if (bFiltered) 1346 AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_FILTER); 1347 else 1348 AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE); 1349 } 1350 if (nEqualRows > 1) 1351 { 1352 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, OUString::number(nEqualRows)); 1353 } 1354 1355 StartElement( sElemRow, true); 1356 } 1357 1358 void ScXMLExport::OpenHeaderRows() 1359 { 1360 StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, true); 1361 bRowHeaderOpen = true; 1362 } 1363 1364 void ScXMLExport::CloseHeaderRows() 1365 { 1366 EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, true); 1367 } 1368 1369 void ScXMLExport::OpenNewRow( 1370 const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEqualRows, 1371 bool bHidden, bool bFiltered) 1372 { 1373 nOpenRow = nStartRow; 1374 if (pGroupRows->IsGroupStart(nStartRow)) 1375 { 1376 if (bHasRowHeader && bRowHeaderOpen) 1377 CloseHeaderRows(); 1378 pGroupRows->OpenGroups(nStartRow); 1379 if (bHasRowHeader && bRowHeaderOpen) 1380 OpenHeaderRows(); 1381 } 1382 if (bHasRowHeader && !bRowHeaderOpen && nStartRow >= aRowHeaderRange.aStart.Row() && nStartRow <= aRowHeaderRange.aEnd.Row()) 1383 { 1384 if (nStartRow == aRowHeaderRange.aStart.Row()) 1385 OpenHeaderRows(); 1386 sal_Int32 nEquals; 1387 if (aRowHeaderRange.aEnd.Row() < nStartRow + nEqualRows - 1) 1388 nEquals = aRowHeaderRange.aEnd.Row() - nStartRow + 1; 1389 else 1390 nEquals = nEqualRows; 1391 WriteRowStartTag(nIndex, nEquals, bHidden, bFiltered); 1392 nOpenRow = nStartRow + nEquals - 1; 1393 if (nEquals < nEqualRows) 1394 { 1395 CloseRow(nStartRow + nEquals - 1); 1396 WriteRowStartTag(nIndex, nEqualRows - nEquals, bHidden, bFiltered); 1397 nOpenRow = nStartRow + nEqualRows - 1; 1398 } 1399 } 1400 else 1401 WriteRowStartTag(nIndex, nEqualRows, bHidden, bFiltered); 1402 } 1403 1404 void ScXMLExport::OpenAndCloseRow( 1405 const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEqualRows, 1406 bool bHidden, bool bFiltered) 1407 { 1408 OpenNewRow(nIndex, nStartRow, nEqualRows, bHidden, bFiltered); 1409 WriteRowContent(); 1410 CloseRow(nStartRow + nEqualRows - 1); 1411 pRowFormatRanges->Clear(); 1412 } 1413 1414 void ScXMLExport::OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow, ScXMLCachedRowAttrAccess& rRowAttr) 1415 { 1416 if (nRepeatRow > 1) 1417 { 1418 sal_Int32 nPrevIndex(0), nIndex; 1419 bool bPrevHidden = false; 1420 bool bPrevFiltered = false; 1421 bool bHidden = false; 1422 bool bFiltered = false; 1423 sal_Int32 nEqualRows(1); 1424 sal_Int32 nEndRow(nStartRow + nRepeatRow); 1425 sal_Int32 nEndRowHidden = nStartRow - 1; 1426 sal_Int32 nEndRowFiltered = nStartRow - 1; 1427 sal_Int32 nRow; 1428 for (nRow = nStartRow; nRow < nEndRow; ++nRow) 1429 { 1430 if (nRow == nStartRow) 1431 { 1432 nPrevIndex = pRowStyles->GetStyleNameIndex(nTable, nRow); 1433 if (pDoc) 1434 { 1435 if (nRow > nEndRowHidden) 1436 { 1437 bPrevHidden = rRowAttr.rowHidden(nTable, nRow, nEndRowHidden); 1438 bHidden = bPrevHidden; 1439 } 1440 if (nRow > nEndRowFiltered) 1441 { 1442 bPrevFiltered = rRowAttr.rowFiltered(nTable, nRow, nEndRowFiltered); 1443 bFiltered = bPrevFiltered; 1444 } 1445 } 1446 1447 } 1448 else 1449 { 1450 nIndex = pRowStyles->GetStyleNameIndex(nTable, nRow); 1451 if (pDoc) 1452 { 1453 if (nRow > nEndRowHidden) 1454 bHidden = rRowAttr.rowHidden(nTable, nRow, nEndRowHidden); 1455 if (nRow > nEndRowFiltered) 1456 bFiltered = rRowAttr.rowFiltered(nTable, nRow, nEndRowFiltered); 1457 } 1458 if (nIndex == nPrevIndex && bHidden == bPrevHidden && bFiltered == bPrevFiltered && 1459 !(bHasRowHeader && ((nRow == aRowHeaderRange.aStart.Row()) || (nRow - 1 == aRowHeaderRange.aEnd.Row()))) && 1460 !(pGroupRows->IsGroupStart(nRow)) && 1461 !(pGroupRows->IsGroupEnd(nRow - 1))) 1462 ++nEqualRows; 1463 else 1464 { 1465 assert(nPrevIndex >= 0 && "coverity#1438402"); 1466 ScRowFormatRanges* pTempRowFormatRanges = new ScRowFormatRanges(pRowFormatRanges.get()); 1467 OpenAndCloseRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered); 1468 pRowFormatRanges.reset(pTempRowFormatRanges); 1469 nEqualRows = 1; 1470 nPrevIndex = nIndex; 1471 bPrevHidden = bHidden; 1472 bPrevFiltered = bFiltered; 1473 } 1474 } 1475 } 1476 assert(nPrevIndex >= 0 && "coverity#1438402"); 1477 OpenNewRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered); 1478 } 1479 else 1480 { 1481 sal_Int32 nIndex = pRowStyles->GetStyleNameIndex(nTable, nStartRow); 1482 bool bHidden = false; 1483 bool bFiltered = false; 1484 if (pDoc) 1485 { 1486 sal_Int32 nEndRowHidden; 1487 sal_Int32 nEndRowFiltered; 1488 bHidden = rRowAttr.rowHidden(nTable, nStartRow, nEndRowHidden); 1489 bFiltered = rRowAttr.rowFiltered(nTable, nStartRow, nEndRowFiltered); 1490 } 1491 assert(nIndex >= 0 && "coverity#1438402"); 1492 OpenNewRow(nIndex, nStartRow, 1, bHidden, bFiltered); 1493 } 1494 nOpenRow = nStartRow + nRepeatRow - 1; 1495 } 1496 1497 void ScXMLExport::CloseRow(const sal_Int32 nRow) 1498 { 1499 if (nOpenRow > -1) 1500 { 1501 EndElement(sElemRow, true); 1502 if (bHasRowHeader && nRow == aRowHeaderRange.aEnd.Row()) 1503 { 1504 CloseHeaderRows(); 1505 bRowHeaderOpen = false; 1506 } 1507 if (pGroupRows->IsGroupEnd(nRow)) 1508 { 1509 if (bHasRowHeader && bRowHeaderOpen) 1510 CloseHeaderRows(); 1511 pGroupRows->CloseGroups(nRow); 1512 if (bHasRowHeader && bRowHeaderOpen) 1513 OpenHeaderRows(); 1514 } 1515 } 1516 nOpenRow = -1; 1517 } 1518 1519 void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow, 1520 const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet) 1521 { 1522 pRowFormatRanges->Clear(); 1523 ScXMLCachedRowAttrAccess aRowAttr(pDoc); 1524 if (nStartRow == nEndRow) 1525 { 1526 pCellStyles->GetFormatRanges(nStartCol, nEndCol, nStartRow, nSheet, pRowFormatRanges.get()); 1527 if (nOpenRow == - 1) 1528 OpenRow(nSheet, nStartRow, 1, aRowAttr); 1529 WriteRowContent(); 1530 pRowFormatRanges->Clear(); 1531 } 1532 else 1533 { 1534 if (nOpenRow > -1) 1535 { 1536 pCellStyles->GetFormatRanges(nStartCol, pSharedData->GetLastColumn(nSheet), nStartRow, nSheet, pRowFormatRanges.get()); 1537 WriteRowContent(); 1538 CloseRow(nStartRow); 1539 sal_Int32 nRows(1); 1540 sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1); 1541 while (nRows < nTotalRows) 1542 { 1543 pRowFormatRanges->Clear(); 1544 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges.get()); 1545 sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows(); 1546 OSL_ENSURE(nMaxRows, "something went wrong"); 1547 if (nMaxRows >= nTotalRows - nRows) 1548 { 1549 OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows, aRowAttr); 1550 nRows += nTotalRows - nRows; 1551 } 1552 else 1553 { 1554 OpenRow(nSheet, nStartRow + nRows, nMaxRows, aRowAttr); 1555 nRows += nMaxRows; 1556 } 1557 if (!pRowFormatRanges->GetSize()) 1558 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges.get()); 1559 WriteRowContent(); 1560 CloseRow(nStartRow + nRows - 1); 1561 } 1562 if (nTotalRows == 1) 1563 CloseRow(nStartRow); 1564 OpenRow(nSheet, nEndRow, 1, aRowAttr); 1565 pRowFormatRanges->Clear(); 1566 pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges.get()); 1567 WriteRowContent(); 1568 } 1569 else 1570 { 1571 sal_Int32 nRows(0); 1572 sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1); 1573 while (nRows < nTotalRows) 1574 { 1575 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges.get()); 1576 sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows(); 1577 if (nMaxRows >= nTotalRows - nRows) 1578 { 1579 OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows, aRowAttr); 1580 nRows += nTotalRows - nRows; 1581 } 1582 else 1583 { 1584 OpenRow(nSheet, nStartRow + nRows, nMaxRows, aRowAttr); 1585 nRows += nMaxRows; 1586 } 1587 if (!pRowFormatRanges->GetSize()) 1588 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges.get()); 1589 WriteRowContent(); 1590 CloseRow(nStartRow + nRows - 1); 1591 } 1592 OpenRow(nSheet, nEndRow, 1, aRowAttr); 1593 pRowFormatRanges->Clear(); 1594 pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges.get()); 1595 WriteRowContent(); 1596 } 1597 } 1598 } 1599 1600 void ScXMLExport::GetColumnRowHeader(bool& rHasColumnHeader, ScRange& rColumnHeaderRange, 1601 bool& rHasRowHeader, ScRange& rRowHeaderRange, 1602 OUString& rPrintRanges) const 1603 { 1604 uno::Reference <sheet::XPrintAreas> xPrintAreas (xCurrentTable, uno::UNO_QUERY); 1605 if (xPrintAreas.is()) 1606 { 1607 rHasRowHeader = xPrintAreas->getPrintTitleRows(); 1608 rHasColumnHeader = xPrintAreas->getPrintTitleColumns(); 1609 table::CellRangeAddress rTempRowHeaderRange = xPrintAreas->getTitleRows(); 1610 rRowHeaderRange = ScRange(rTempRowHeaderRange.StartColumn, 1611 rTempRowHeaderRange.StartRow, 1612 rTempRowHeaderRange.Sheet, 1613 rTempRowHeaderRange.EndColumn, 1614 rTempRowHeaderRange.EndRow, 1615 rTempRowHeaderRange.Sheet); 1616 table::CellRangeAddress rTempColumnHeaderRange = xPrintAreas->getTitleColumns(); 1617 rColumnHeaderRange = ScRange(rTempColumnHeaderRange.StartColumn, 1618 rTempColumnHeaderRange.StartRow, 1619 rTempColumnHeaderRange.Sheet, 1620 rTempColumnHeaderRange.EndColumn, 1621 rTempColumnHeaderRange.EndRow, 1622 rTempColumnHeaderRange.Sheet); 1623 uno::Sequence< table::CellRangeAddress > aRangeList( xPrintAreas->getPrintAreas() ); 1624 ScRangeStringConverter::GetStringFromRangeList( rPrintRanges, aRangeList, pDoc, FormulaGrammar::CONV_OOO ); 1625 } 1626 } 1627 1628 void ScXMLExport::FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups) 1629 { 1630 size_t nDepth = pFields->GetDepth(); 1631 for (size_t i = 0; i < nDepth; ++i) 1632 { 1633 size_t nFields = pFields->GetCount(i); 1634 for (size_t j = 0; j < nFields; ++j) 1635 { 1636 ScMyColumnRowGroup aGroup; 1637 const ScOutlineEntry* pEntry = pFields->GetEntry(i, j); 1638 aGroup.nField = pEntry->GetStart(); 1639 aGroup.nLevel = static_cast<sal_Int16>(i); 1640 aGroup.bDisplay = !(pEntry->IsHidden()); 1641 pGroups->AddGroup(aGroup, pEntry->GetEnd()); 1642 } 1643 } 1644 if (nDepth) 1645 pGroups->Sort(); 1646 } 1647 1648 void ScXMLExport::FillColumnRowGroups() 1649 { 1650 if (pDoc) 1651 { 1652 ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable( static_cast<SCTAB>(nCurrentTable) ); 1653 if(pOutlineTable) 1654 { 1655 ScOutlineArray& rCols(pOutlineTable->GetColArray()); 1656 ScOutlineArray& rRows(pOutlineTable->GetRowArray()); 1657 FillFieldGroup(&rCols, pGroupColumns.get()); 1658 FillFieldGroup(&rRows, pGroupRows.get()); 1659 pSharedData->SetLastColumn(nCurrentTable, pGroupColumns->GetLast()); 1660 pSharedData->SetLastRow(nCurrentTable, pGroupRows->GetLast()); 1661 } 1662 } 1663 } 1664 1665 void ScXMLExport::SetBodyAttributes() 1666 { 1667 if (pDoc && pDoc->IsDocProtected()) 1668 { 1669 AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE); 1670 OUStringBuffer aBuffer; 1671 uno::Sequence<sal_Int8> aPassHash; 1672 ScPasswordHash eHashUsed = PASSHASH_UNSPECIFIED; 1673 const ScDocProtection* p = pDoc->GetDocProtection(); 1674 if (p) 1675 { 1676 if (p->hasPasswordHash(PASSHASH_SHA1)) 1677 { 1678 aPassHash = p->getPasswordHash(PASSHASH_SHA1); 1679 eHashUsed = PASSHASH_SHA1; 1680 } 1681 else if (p->hasPasswordHash(PASSHASH_SHA256)) 1682 { 1683 aPassHash = p->getPasswordHash(PASSHASH_SHA256); 1684 eHashUsed = PASSHASH_SHA256; 1685 } 1686 else if (p->hasPasswordHash(PASSHASH_XL, PASSHASH_SHA1)) 1687 { 1688 aPassHash = p->getPasswordHash(PASSHASH_XL, PASSHASH_SHA1); 1689 eHashUsed = PASSHASH_XL; 1690 } 1691 } 1692 ::comphelper::Base64::encode(aBuffer, aPassHash); 1693 if (!aBuffer.isEmpty()) 1694 { 1695 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); 1696 if ( getDefaultVersion() >= SvtSaveOptions::ODFVER_012 ) 1697 { 1698 if (eHashUsed == PASSHASH_XL) 1699 { 1700 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, 1701 ScPassHashHelper::getHashURI(PASSHASH_XL)); 1702 if (getDefaultVersion() > SvtSaveOptions::ODFVER_012) 1703 AddAttribute(XML_NAMESPACE_LO_EXT, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2, 1704 ScPassHashHelper::getHashURI(PASSHASH_SHA1)); 1705 } 1706 else if (eHashUsed == PASSHASH_SHA1) 1707 { 1708 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, 1709 ScPassHashHelper::getHashURI(PASSHASH_SHA1)); 1710 } 1711 else if (eHashUsed == PASSHASH_SHA256) 1712 { 1713 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, 1714 ScPassHashHelper::getHashURI(PASSHASH_SHA256)); 1715 } 1716 } 1717 } 1718 } 1719 } 1720 1721 static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput, 1722 const uno::Reference< io::XOutputStream >& xOutput, 1723 sal_Int32 nCount ) 1724 { 1725 const sal_Int32 nBufSize = 16*1024; 1726 uno::Sequence<sal_Int8> aSequence(nBufSize); 1727 1728 sal_Int32 nRemaining = nCount; 1729 bool bFirst = true; 1730 1731 while ( nRemaining > 0 ) 1732 { 1733 sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) ); 1734 if (bFirst) 1735 { 1736 // safety check: Make sure the copied part actually points to the start of an element 1737 if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') ) 1738 { 1739 return false; // abort and set an error 1740 } 1741 bFirst = false; 1742 } 1743 if (nRead == nRemaining) 1744 { 1745 // safety check: Make sure the copied part also ends at the end of an element 1746 if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') ) 1747 { 1748 return false; // abort and set an error 1749 } 1750 } 1751 1752 if ( nRead == nBufSize ) 1753 { 1754 xOutput->writeBytes( aSequence ); 1755 nRemaining -= nRead; 1756 } 1757 else 1758 { 1759 if ( nRead > 0 ) 1760 { 1761 uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead ); 1762 xOutput->writeBytes( aTempBuf ); 1763 } 1764 nRemaining = 0; 1765 } 1766 } 1767 return true; // successful 1768 } 1769 1770 static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip ) 1771 { 1772 // skipBytes in zip stream is implemented as reading. 1773 // For now, split into several calls to avoid allocating a large buffer. 1774 // Later, skipBytes should be changed. 1775 1776 const sal_Int32 nMaxSize = 32*1024; 1777 1778 if ( nBytesToSkip > 0 ) 1779 { 1780 sal_Int32 nRemaining = nBytesToSkip; 1781 while ( nRemaining > 0 ) 1782 { 1783 sal_Int32 nSkip = std::min( nRemaining, nMaxSize ); 1784 xInput->skipBytes( nSkip ); 1785 nRemaining -= nSkip; 1786 } 1787 } 1788 } 1789 1790 void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd ) 1791 { 1792 uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler(); 1793 uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY ); 1794 if ( xDestSource.is() ) 1795 { 1796 uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream(); 1797 uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY ); 1798 if ( xDestSeek.is() ) 1799 { 1800 // temporary: set same stream again to clear buffer 1801 xDestSource->setOutputStream( xDestStream ); 1802 1803 if ( getExportFlags() & SvXMLExportFlags::PRETTY ) 1804 { 1805 const OString aOutStr("\n "); 1806 uno::Sequence<sal_Int8> aOutSeq( reinterpret_cast<sal_Int8 const *>(aOutStr.getStr()), aOutStr.getLength() ); 1807 xDestStream->writeBytes( aOutSeq ); 1808 } 1809 1810 rNewStart = static_cast<sal_Int32>(xDestSeek->getPosition()); 1811 1812 if ( nStartOffset > nSourceStreamPos ) 1813 lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos ); 1814 1815 if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) ) 1816 { 1817 // If copying went wrong, set an error. 1818 // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving. 1819 1820 uno::Sequence<OUString> aEmptySeq; 1821 SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq); 1822 } 1823 nSourceStreamPos = nEndOffset; 1824 1825 rNewEnd = static_cast<sal_Int32>(xDestSeek->getPosition()); 1826 } 1827 } 1828 } 1829 1830 const ScXMLEditAttributeMap& ScXMLExport::GetEditAttributeMap() const 1831 { 1832 if (!mpEditAttrMap) 1833 mpEditAttrMap.reset(new ScXMLEditAttributeMap); 1834 return *mpEditAttrMap; 1835 } 1836 1837 void ScXMLExport::RegisterDefinedStyleNames( const uno::Reference< css::sheet::XSpreadsheetDocument > & xSpreadDoc ) 1838 { 1839 ScFormatSaveData* pFormatData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetFormatSaveData(); 1840 auto xAutoStylePool = GetAutoStylePool(); 1841 for (const auto& rFormatInfo : pFormatData->maIDToName) 1842 { 1843 xAutoStylePool->RegisterDefinedName(XML_STYLE_FAMILY_TABLE_CELL, rFormatInfo.second); 1844 } 1845 } 1846 1847 void ScXMLExport::ExportContent_() 1848 { 1849 nCurrentTable = 0; 1850 if (!pSharedData) 1851 { 1852 SCTAB nTableCount(0); 1853 sal_Int32 nShapesCount(0); 1854 CollectSharedData(nTableCount, nShapesCount); 1855 OSL_FAIL("no shared data set"); 1856 if (!pSharedData) 1857 return; 1858 } 1859 ScXMLExportDatabaseRanges aExportDatabaseRanges(*this); 1860 if (!GetModel().is()) 1861 return; 1862 1863 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); 1864 if ( !xSpreadDoc.is() ) 1865 return; 1866 1867 ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetSheetSaveData(); 1868 if (pSheetData) 1869 pSheetData->ResetSaveEntries(); 1870 1871 uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); 1872 if ( xIndex.is() ) 1873 { 1874 //_GetNamespaceMap().ClearQNamesCache(); 1875 pChangeTrackingExportHelper->CollectAndWriteChanges(); 1876 WriteCalculationSettings(xSpreadDoc); 1877 sal_Int32 nTableCount(xIndex->getCount()); 1878 ScMyAreaLinksContainer aAreaLinks; 1879 GetAreaLinks( aAreaLinks ); 1880 ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges()); 1881 ScMyDetectiveOpContainer aDetectiveOpContainer; 1882 GetDetectiveOpList( aDetectiveOpContainer ); 1883 1884 pCellStyles->Sort(); 1885 pMergedRangesContainer->Sort(); 1886 pSharedData->GetDetectiveObjContainer()->Sort(); 1887 1888 mpCellsItr->Clear(); 1889 mpCellsItr->SetShapes( pSharedData->GetShapesContainer() ); 1890 mpCellsItr->SetNoteShapes( pSharedData->GetNoteShapes() ); 1891 mpCellsItr->SetMergedRanges( pMergedRangesContainer.get() ); 1892 mpCellsItr->SetAreaLinks( &aAreaLinks ); 1893 mpCellsItr->SetEmptyDatabaseRanges( &aEmptyRanges ); 1894 mpCellsItr->SetDetectiveObj( pSharedData->GetDetectiveObjContainer() ); 1895 mpCellsItr->SetDetectiveOp( &aDetectiveOpContainer ); 1896 1897 if (nTableCount > 0) 1898 pValidationsContainer->WriteValidations(*this); 1899 WriteTheLabelRanges( xSpreadDoc ); 1900 for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable) 1901 { 1902 sal_Int32 nStartOffset = -1; 1903 sal_Int32 nEndOffset = -1; 1904 if (pSheetData && pDoc && pDoc->IsStreamValid(static_cast<SCTAB>(nTable)) && !pDoc->GetChangeTrack()) 1905 pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset ); 1906 1907 if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() ) 1908 { 1909 sal_Int32 nNewStart = -1; 1910 sal_Int32 nNewEnd = -1; 1911 CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd ); 1912 1913 // store position of copied sheet in output 1914 pSheetData->AddSavePos( nTable, nNewStart, nNewEnd ); 1915 1916 // skip iterator entries for this sheet 1917 mpCellsItr->SkipTable(static_cast<SCTAB>(nTable)); 1918 } 1919 else 1920 { 1921 uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); 1922 WriteTable(nTable, xTable); 1923 } 1924 IncrementProgressBar(false); 1925 } 1926 } 1927 WriteExternalRefCaches(); 1928 WriteNamedExpressions(); 1929 WriteDataStream(); 1930 aExportDatabaseRanges.WriteDatabaseRanges(); 1931 WriteExternalDataMapping(); 1932 ScXMLExportDataPilot aExportDataPilot(*this); 1933 aExportDataPilot.WriteDataPilots(); 1934 WriteConsolidation(); 1935 ScXMLExportDDELinks aExportDDELinks(*this); 1936 aExportDDELinks.WriteDDELinks(xSpreadDoc); 1937 IncrementProgressBar(true, 0); 1938 GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference()); 1939 } 1940 1941 void ScXMLExport::ExportStyles_( bool bUsed ) 1942 { 1943 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); 1944 if (xSpreadDoc.is()) 1945 RegisterDefinedStyleNames( xSpreadDoc); 1946 1947 if (!pSharedData) 1948 { 1949 SCTAB nTableCount(0); 1950 sal_Int32 nShapesCount(0); 1951 CollectSharedData(nTableCount, nShapesCount); 1952 } 1953 rtl::Reference<ScXMLStyleExport> aStylesExp(new ScXMLStyleExport(*this, GetAutoStylePool().get())); 1954 if (GetModel().is()) 1955 { 1956 uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); 1957 if (xMultiServiceFactory.is()) 1958 { 1959 uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance("com.sun.star.sheet.Defaults"), uno::UNO_QUERY); 1960 if (xProperties.is()) 1961 aStylesExp->exportDefaultStyle(xProperties, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME, xCellStylesExportPropertySetMapper); 1962 if (pSharedData->HasShapes()) 1963 { 1964 GetShapeExport()->ExportGraphicDefaults(); 1965 } 1966 } 1967 uno::Reference <style::XStyleFamiliesSupplier> xStyleFamiliesSupplier (GetModel(), uno::UNO_QUERY); 1968 if (xStyleFamiliesSupplier.is()) 1969 { 1970 uno::Reference <container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies()); 1971 if (xStylesFamilies.is()) 1972 { 1973 uno::Reference <container::XIndexAccess> xCellStyles(xStylesFamilies->getByName("CellStyles"), uno::UNO_QUERY); 1974 if (xCellStyles.is()) 1975 { 1976 sal_Int32 nCount(xCellStyles->getCount()); 1977 for (sal_Int32 i = 0; i < nCount; ++i) 1978 { 1979 uno::Reference <beans::XPropertySet> xCellProperties(xCellStyles->getByIndex(i), uno::UNO_QUERY); 1980 if (xCellProperties.is()) 1981 { 1982 sal_Int32 nNumberFormat = 0; 1983 if (xCellProperties->getPropertyValue(SC_UNONAME_NUMFMT) >>= nNumberFormat) 1984 addDataStyle(nNumberFormat); 1985 } 1986 } 1987 } 1988 } 1989 } 1990 } 1991 exportDataStyles(); 1992 1993 aStylesExp->exportStyleFamily(OUString("CellStyles"), 1994 OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME), xCellStylesExportPropertySetMapper, false, XML_STYLE_FAMILY_TABLE_CELL); 1995 1996 SvXMLExport::ExportStyles_(bUsed); 1997 } 1998 1999 void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties, 2000 const uno::Reference<sheet::XSpreadsheet>& xTable, 2001 sal_Int32 nTable, const OUString* pOldName) 2002 { 2003 css::uno::Any aAny = xProperties->getPropertyValue("FormatID"); 2004 sal_uInt64 nKey = 0; 2005 aAny >>= nKey; 2006 2007 //! pass xCellRanges instead 2008 uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY ); 2009 2010 OUString sStyleName; 2011 sal_Int32 nNumberFormat(-1); 2012 sal_Int32 nValidationIndex(-1); 2013 std::vector< XMLPropertyState > aPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties )); 2014 std::vector< XMLPropertyState >::iterator aItr(aPropStates.begin()); 2015 std::vector< XMLPropertyState >::iterator aEndItr(aPropStates.end()); 2016 sal_Int32 nCount(0); 2017 while (aItr != aEndItr) 2018 { 2019 if (aItr->mnIndex != -1) 2020 { 2021 switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex)) 2022 { 2023 case CTF_SC_VALIDATION : 2024 { 2025 pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex); 2026 // this is not very slow, because it is most the last property or 2027 // if it is not the last property it is the property before the last property, 2028 // so in the worst case only one property has to be copied, but in the best case no 2029 // property has to be copied 2030 aItr = aPropStates.erase(aItr); 2031 aEndItr = aPropStates.end(); // old aEndItr is invalidated! 2032 } 2033 break; 2034 case CTF_SC_CELLSTYLE : 2035 { 2036 aItr->maValue >>= sStyleName; 2037 aItr->mnIndex = -1; 2038 ++aItr; 2039 ++nCount; 2040 } 2041 break; 2042 case CTF_SC_NUMBERFORMAT : 2043 { 2044 if (aItr->maValue >>= nNumberFormat) 2045 addDataStyle(nNumberFormat); 2046 ++aItr; 2047 ++nCount; 2048 } 2049 break; 2050 default: 2051 { 2052 ++aItr; 2053 ++nCount; 2054 } 2055 break; 2056 } 2057 } 2058 else 2059 { 2060 ++aItr; 2061 ++nCount; 2062 } 2063 } 2064 if (nCount == 1) // this is the CellStyle and should be removed if alone 2065 aPropStates.clear(); 2066 if (nNumberFormat == -1) 2067 xProperties->getPropertyValue(SC_UNONAME_NUMFMT) >>= nNumberFormat; 2068 if (!sStyleName.isEmpty()) 2069 { 2070 if (!aPropStates.empty()) 2071 { 2072 sal_Int32 nIndex; 2073 if (pOldName) 2074 { 2075 if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, aPropStates)) 2076 { 2077 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, *pOldName); 2078 // add to pCellStyles, so the name is found for normal sheets 2079 pCellStyles->AddStyleName(*pOldName, nIndex); 2080 } 2081 } 2082 else 2083 { 2084 OUString sName; 2085 bool bAdded = false; 2086 if (nKey) 2087 { 2088 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); 2089 ScFormatSaveData* pFormatData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetFormatSaveData(); 2090 auto itr = pFormatData->maIDToName.find(nKey); 2091 if (itr != pFormatData->maIDToName.end()) 2092 { 2093 sName = itr->second; 2094 bAdded = GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, aPropStates); 2095 if (bAdded) 2096 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, sName); 2097 } 2098 } 2099 bool bIsAutoStyle(true); 2100 if (bAdded || GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, aPropStates)) 2101 { 2102 pCellStyles->AddStyleName(sName, nIndex); 2103 } 2104 else 2105 nIndex = pCellStyles->GetIndexOfStyleName(sName, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX, bIsAutoStyle); 2106 2107 const uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses()); 2108 bool bGetMerge(true); 2109 for (table::CellRangeAddress const & address : aAddresses) 2110 { 2111 pSharedData->SetLastColumn(nTable, address.EndColumn); 2112 pSharedData->SetLastRow(nTable, address.EndRow); 2113 pCellStyles->AddRangeStyleName(address, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat); 2114 if (bGetMerge) 2115 bGetMerge = GetMerged(&address, xTable); 2116 } 2117 } 2118 } 2119 else 2120 { 2121 OUString sEncodedStyleName(EncodeStyleName(sStyleName)); 2122 sal_Int32 nIndex(0); 2123 pCellStyles->AddStyleName(sEncodedStyleName, nIndex, false); 2124 if ( !pOldName ) 2125 { 2126 const uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses()); 2127 bool bGetMerge(true); 2128 for (table::CellRangeAddress const & address : aAddresses) 2129 { 2130 if (bGetMerge) 2131 bGetMerge = GetMerged(&address, xTable); 2132 pCellStyles->AddRangeStyleName(address, nIndex, false, nValidationIndex, nNumberFormat); 2133 if( sStyleName != "Default" || nValidationIndex != -1 ) 2134 { 2135 pSharedData->SetLastColumn(nTable, address.EndColumn); 2136 pSharedData->SetLastRow(nTable, address.EndRow); 2137 } 2138 } 2139 } 2140 } 2141 } 2142 } 2143 2144 void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties, 2145 const OUString* pOldName, sal_Int32& rIndex, bool& rIsVisible) 2146 { 2147 std::vector<XMLPropertyState> aPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties)); 2148 if(!aPropStates.empty()) 2149 { 2150 auto aItr = std::find_if(aPropStates.begin(), aPropStates.end(), 2151 [this](const XMLPropertyState& rPropState) { 2152 return xColumnStylesPropertySetMapper->GetEntryContextId(rPropState.mnIndex) == CTF_SC_ISVISIBLE; }); 2153 if (aItr != aPropStates.end()) 2154 { 2155 aItr->maValue >>= rIsVisible; 2156 } 2157 2158 OUString sParent; 2159 if (pOldName) 2160 { 2161 if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, aPropStates)) 2162 { 2163 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_COLUMN, *pOldName); 2164 // add to pColumnStyles, so the name is found for normal sheets 2165 rIndex = pColumnStyles->AddStyleName(*pOldName); 2166 } 2167 } 2168 else 2169 { 2170 OUString sName; 2171 if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, aPropStates)) 2172 { 2173 rIndex = pColumnStyles->AddStyleName(sName); 2174 } 2175 else 2176 rIndex = pColumnStyles->GetIndexOfStyleName(sName, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX); 2177 } 2178 } 2179 } 2180 2181 void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties, 2182 const OUString* pOldName, sal_Int32& rIndex) 2183 { 2184 std::vector<XMLPropertyState> aPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties)); 2185 if(!aPropStates.empty()) 2186 { 2187 OUString sParent; 2188 if (pOldName) 2189 { 2190 if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_ROW, sParent, aPropStates)) 2191 { 2192 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_ROW, *pOldName); 2193 // add to pRowStyles, so the name is found for normal sheets 2194 rIndex = pRowStyles->AddStyleName(*pOldName); 2195 } 2196 } 2197 else 2198 { 2199 OUString sName; 2200 if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, aPropStates)) 2201 { 2202 rIndex = pRowStyles->AddStyleName(sName); 2203 } 2204 else 2205 rIndex = pRowStyles->GetIndexOfStyleName(sName, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX); 2206 } 2207 } 2208 } 2209 2210 static uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> const & xEnumAccess, sal_Int32 nIndex ) 2211 { 2212 uno::Any aRet; 2213 uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() ); 2214 try 2215 { 2216 sal_Int32 nSkip = nIndex; 2217 while ( nSkip > 0 ) 2218 { 2219 (void) xEnum->nextElement(); 2220 --nSkip; 2221 } 2222 aRet = xEnum->nextElement(); 2223 } 2224 catch (container::NoSuchElementException&) 2225 { 2226 // leave aRet empty 2227 } 2228 return aRet; 2229 } 2230 2231 void ScXMLExport::collectAutoStyles() 2232 { 2233 SvXMLExport::collectAutoStyles(); 2234 2235 if (mbAutoStylesCollected) 2236 return; 2237 2238 if (!GetModel().is()) 2239 return; 2240 2241 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); 2242 if (!xSpreadDoc.is()) 2243 return; 2244 2245 uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); 2246 if (!xIndex.is()) 2247 return; 2248 2249 if (getExportFlags() & SvXMLExportFlags::CONTENT) 2250 { 2251 // Reserve the loaded cell style names. 2252 RegisterDefinedStyleNames( xSpreadDoc); 2253 2254 // re-create automatic styles with old names from stored data 2255 ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(xSpreadDoc)->GetSheetSaveData(); 2256 if (pSheetData && pDoc) 2257 { 2258 // formulas have to be calculated now, to detect changed results 2259 // (during normal save, they will be calculated anyway) 2260 SCTAB nTabCount = pDoc->GetTableCount(); 2261 for (SCTAB nTab=0; nTab<nTabCount; ++nTab) 2262 if (pDoc->IsStreamValid(nTab)) 2263 pDoc->InterpretDirtyCells(ScRange(0, 0, nTab, MAXCOL, MAXROW, nTab)); 2264 2265 // stored cell styles 2266 const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles(); 2267 for (const auto& rCellEntry : rCellEntries) 2268 { 2269 ScAddress aPos = rCellEntry.maCellPos; 2270 sal_Int32 nTable = aPos.Tab(); 2271 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); 2272 if (bCopySheet) 2273 { 2274 uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); 2275 uno::Reference <beans::XPropertySet> xProperties( 2276 xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY ); 2277 2278 AddStyleFromCells(xProperties, xTable, nTable, &rCellEntry.maName); 2279 } 2280 } 2281 2282 // stored column styles 2283 const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles(); 2284 for (const auto& rColumnEntry : rColumnEntries) 2285 { 2286 ScAddress aPos = rColumnEntry.maCellPos; 2287 sal_Int32 nTable = aPos.Tab(); 2288 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); 2289 if (bCopySheet) 2290 { 2291 uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); 2292 uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); 2293 uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY); 2294 2295 sal_Int32 nIndex(-1); 2296 bool bIsVisible(true); 2297 AddStyleFromColumn( xColumnProperties, &rColumnEntry.maName, nIndex, bIsVisible ); 2298 } 2299 } 2300 2301 // stored row styles 2302 const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles(); 2303 for (const auto& rRowEntry : rRowEntries) 2304 { 2305 ScAddress aPos = rRowEntry.maCellPos; 2306 sal_Int32 nTable = aPos.Tab(); 2307 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); 2308 if (bCopySheet) 2309 { 2310 uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); 2311 uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); 2312 uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY); 2313 2314 sal_Int32 nIndex(-1); 2315 AddStyleFromRow( xRowProperties, &rRowEntry.maName, nIndex ); 2316 } 2317 } 2318 2319 // stored table styles 2320 const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles(); 2321 for (const auto& rTableEntry : rTableEntries) 2322 { 2323 ScAddress aPos = rTableEntry.maCellPos; 2324 sal_Int32 nTable = aPos.Tab(); 2325 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); 2326 if (bCopySheet) 2327 { 2328 //! separate method AddStyleFromTable needed? 2329 uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY); 2330 if (xTableProperties.is()) 2331 { 2332 std::vector<XMLPropertyState> aPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); 2333 OUString sName( rTableEntry.maName ); 2334 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, OUString(), aPropStates); 2335 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName); 2336 } 2337 } 2338 } 2339 2340 // stored styles for notes 2341 2342 rtl::Reference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this ); 2343 GetShapeExport(); // make sure the graphics styles family is added 2344 2345 const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles(); 2346 for (const auto& rNoteEntry : rNoteEntries) 2347 { 2348 ScAddress aPos = rNoteEntry.maCellPos; 2349 SCTAB nTable = aPos.Tab(); 2350 bool bCopySheet = pDoc->IsStreamValid( nTable ); 2351 if (bCopySheet) 2352 { 2353 //! separate method AddStyleFromNote needed? 2354 2355 ScPostIt* pNote = pDoc->GetNote(aPos); 2356 OSL_ENSURE( pNote, "note not found" ); 2357 if (pNote) 2358 { 2359 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); 2360 // all uno shapes are created anyway in CollectSharedData 2361 uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY ); 2362 if (xShapeProperties.is()) 2363 { 2364 if ( !rNoteEntry.maStyleName.isEmpty() ) 2365 { 2366 std::vector<XMLPropertyState> aPropStates(xShapeMapper->Filter(xShapeProperties)); 2367 OUString sName( rNoteEntry.maStyleName ); 2368 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, OUString(), aPropStates); 2369 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName); 2370 } 2371 if ( !rNoteEntry.maTextStyle.isEmpty() ) 2372 { 2373 std::vector<XMLPropertyState> aPropStates( 2374 GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties)); 2375 OUString sName( rNoteEntry.maTextStyle ); 2376 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, OUString(), aPropStates); 2377 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName); 2378 } 2379 } 2380 } 2381 } 2382 } 2383 2384 // note paragraph styles 2385 2386 rtl::Reference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper(); 2387 2388 const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles(); 2389 for (const auto& rNoteParaEntry : rNoteParaEntries) 2390 { 2391 ScAddress aPos = rNoteParaEntry.maCellPos; 2392 SCTAB nTable = aPos.Tab(); 2393 bool bCopySheet = pDoc->IsStreamValid( nTable ); 2394 if (bCopySheet) 2395 { 2396 ScPostIt* pNote = pDoc->GetNote( aPos ); 2397 OSL_ENSURE( pNote, "note not found" ); 2398 if (pNote) 2399 { 2400 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); 2401 uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); 2402 uno::Reference<beans::XPropertySet> xParaProp( 2403 lcl_GetEnumerated( xCellText, rNoteParaEntry.maSelection.nStartPara ), uno::UNO_QUERY ); 2404 if ( xParaProp.is() ) 2405 { 2406 std::vector<XMLPropertyState> aPropStates(xParaPropMapper->Filter(xParaProp)); 2407 OUString sName( rNoteParaEntry.maName ); 2408 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, OUString(), aPropStates); 2409 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName); 2410 } 2411 } 2412 } 2413 } 2414 2415 // note text styles 2416 2417 rtl::Reference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this ); 2418 2419 const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles(); 2420 for (const auto& rNoteTextEntry : rNoteTextEntries) 2421 { 2422 ScAddress aPos = rNoteTextEntry.maCellPos; 2423 SCTAB nTable = aPos.Tab(); 2424 bool bCopySheet = pDoc->IsStreamValid( nTable ); 2425 if (bCopySheet) 2426 { 2427 ScPostIt* pNote = pDoc->GetNote( aPos ); 2428 OSL_ENSURE( pNote, "note not found" ); 2429 if (pNote) 2430 { 2431 SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); 2432 uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); 2433 uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); 2434 ScDrawTextCursor* pCursor = comphelper::getUnoTunnelImplementation<ScDrawTextCursor>( xCursorProp ); 2435 if (pCursor) 2436 { 2437 pCursor->SetSelection( rNoteTextEntry.maSelection ); 2438 2439 std::vector<XMLPropertyState> aPropStates(xTextPropMapper->Filter(xCursorProp)); 2440 OUString sName( rNoteTextEntry.maName ); 2441 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, OUString(), aPropStates); 2442 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName); 2443 } 2444 } 2445 } 2446 } 2447 2448 // stored text styles 2449 2450 // Calling createTextCursor fires up editeng, which is very slow, and often subsequent style entries 2451 // refer to the same cell, so cache it. 2452 ScAddress aPrevPos; 2453 uno::Reference<beans::XPropertySet> xPrevCursorProp; 2454 const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles(); 2455 for (const auto& rTextEntry : rTextEntries) 2456 { 2457 ScAddress aPos = rTextEntry.maCellPos; 2458 sal_Int32 nTable = aPos.Tab(); 2459 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); 2460 if (!bCopySheet) 2461 continue; 2462 2463 //! separate method AddStyleFromText needed? 2464 //! cache sheet object 2465 2466 uno::Reference<beans::XPropertySet> xCursorProp; 2467 if (xPrevCursorProp && aPrevPos == aPos) 2468 xCursorProp = xPrevCursorProp; 2469 else 2470 { 2471 uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); 2472 uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY); 2473 xCursorProp.set(xCellText->createTextCursor(), uno::UNO_QUERY); 2474 } 2475 ScCellTextCursor* pCursor = comphelper::getUnoTunnelImplementation<ScCellTextCursor>( xCursorProp ); 2476 if (!pCursor) 2477 continue; 2478 pCursor->SetSelection( rTextEntry.maSelection ); 2479 2480 std::vector<XMLPropertyState> aPropStates(xTextPropMapper->Filter(xCursorProp)); 2481 OUString sName( rTextEntry.maName ); 2482 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, OUString(), aPropStates); 2483 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName); 2484 xPrevCursorProp = xCursorProp; 2485 aPrevPos = aPos; 2486 } 2487 } 2488 2489 ExportExternalRefCacheStyles(); 2490 2491 if (!pSharedData) 2492 { 2493 SCTAB nTableCount(0); 2494 sal_Int32 nShapesCount(0); 2495 CollectSharedData(nTableCount, nShapesCount); 2496 } 2497 sal_Int32 nTableCount(xIndex->getCount()); 2498 pCellStyles->AddNewTable(nTableCount - 1); 2499 CollectShapesAutoStyles(nTableCount); 2500 for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable, IncrementProgressBar(false)) 2501 { 2502 uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); 2503 if (!xTable.is()) 2504 continue; 2505 2506 // table styles array must be complete, including copied tables - Add should find the stored style 2507 uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); 2508 if (xTableProperties.is()) 2509 { 2510 std::vector<XMLPropertyState> aPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); 2511 if(!aPropStates.empty()) 2512 { 2513 OUString sName; 2514 GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, OUString(), aPropStates); 2515 aTableStyles.push_back(sName); 2516 } 2517 } 2518 2519 // collect other auto-styles only for non-copied sheets 2520 uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY ); 2521 if ( xCellFormatRanges.is() ) 2522 { 2523 uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges()); 2524 if (xFormatRangesIndex.is()) 2525 { 2526 sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount()); 2527 GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount); 2528 for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange) 2529 { 2530 uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY); 2531 if (xCellRanges.is()) 2532 { 2533 uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY); 2534 if (xProperties.is()) 2535 { 2536 AddStyleFromCells(xProperties, xTable, nTable, nullptr); 2537 IncrementProgressBar(false); 2538 } 2539 } 2540 } 2541 } 2542 } 2543 uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY); 2544 if (xColumnRowRange.is() && pDoc) 2545 { 2546 pDoc->SyncColRowFlags(); 2547 uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); 2548 if (xTableColumns.is()) 2549 { 2550 sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable))); 2551 pSharedData->SetLastColumn(nTable, nColumns); 2552 table::CellRangeAddress aCellAddress(GetEndAddress(xTable)); 2553 if (aCellAddress.EndColumn > nColumns) 2554 { 2555 ++nColumns; 2556 pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn); 2557 } 2558 else 2559 pColumnStyles->AddNewTable(nTable, nColumns); 2560 sal_Int32 nColumn = 0; 2561 while (nColumn <= MAXCOL) 2562 { 2563 sal_Int32 nIndex(-1); 2564 bool bIsVisible(true); 2565 uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY); 2566 if (xColumnProperties.is()) 2567 { 2568 AddStyleFromColumn( xColumnProperties, nullptr, nIndex, bIsVisible ); 2569 pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible); 2570 } 2571 sal_Int32 nOld(nColumn); 2572 nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn)); 2573 for (sal_Int32 i = nOld + 1; i < nColumn; ++i) 2574 pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); 2575 } 2576 if (aCellAddress.EndColumn > nColumns) 2577 { 2578 bool bIsVisible(true); 2579 sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible)); 2580 for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i) 2581 pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); 2582 } 2583 } 2584 uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); 2585 if (xTableRows.is()) 2586 { 2587 sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable))); 2588 pSharedData->SetLastRow(nTable, nRows); 2589 2590 pRowStyles->AddNewTable(nTable, MAXROW); 2591 sal_Int32 nRow = 0; 2592 while (nRow <= MAXROW) 2593 { 2594 sal_Int32 nIndex = 0; 2595 uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY); 2596 if(xRowProperties.is()) 2597 { 2598 AddStyleFromRow( xRowProperties, nullptr, nIndex ); 2599 pRowStyles->AddFieldStyleName(nTable, nRow, nIndex); 2600 } 2601 sal_Int32 nOld(nRow); 2602 nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow)); 2603 if (nRow > nOld + 1) 2604 pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1); 2605 } 2606 } 2607 } 2608 ExportCellTextAutoStyles(nTable); 2609 } 2610 2611 pChangeTrackingExportHelper->CollectAutoStyles(); 2612 } 2613 2614 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES) 2615 GetPageExport()->collectAutoStyles(true); 2616 2617 mbAutoStylesCollected = true; 2618 } 2619 2620 void ScXMLExport::ExportAutoStyles_() 2621 { 2622 if (!GetModel().is()) 2623 return; 2624 2625 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); 2626 if (!xSpreadDoc.is()) 2627 return; 2628 2629 uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); 2630 if (!xIndex.is()) 2631 return; 2632 2633 collectAutoStyles(); 2634 2635 if (getExportFlags() & SvXMLExportFlags::CONTENT) 2636 { 2637 GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN); 2638 GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW); 2639 GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE); 2640 exportAutoDataStyles(); 2641 GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL); 2642 2643 GetShapeExport()->exportAutoStyles(); 2644 GetFormExport()->exportAutoStyles( ); 2645 2646 if (pDoc) 2647 { 2648 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); 2649 // #i100879# write the table style for cached tables only if there are cached tables 2650 // (same logic as in ExportExternalRefCacheStyles) 2651 if (pRefMgr->hasExternalData()) 2652 { 2653 // Special table style for the external ref cache tables. 2654 AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName); 2655 AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE); 2656 SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, true, true); 2657 AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE); 2658 SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, true, true); 2659 } 2660 } 2661 } 2662 2663 if (getExportFlags() & SvXMLExportFlags::MASTERSTYLES) 2664 { 2665 GetPageExport()->exportAutoStyles(); 2666 } 2667 2668 // #i30251#; only write Text Styles once 2669 2670 if ((getExportFlags() & SvXMLExportFlags::CONTENT) || (getExportFlags() & SvXMLExportFlags::MASTERSTYLES)) 2671 GetTextParagraphExport()->exportTextAutoStyles(); 2672 } 2673 2674 void ScXMLExport::ExportMasterStyles_() 2675 { 2676 GetPageExport()->exportMasterStyles( true ); 2677 } 2678 2679 void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > const & xShape ) 2680 { 2681 // detective objects and notes 2682 if( SvxShape* pShapeImp = comphelper::getUnoTunnelImplementation<SvxShape>( xShape ) ) 2683 { 2684 if( SdrObject* pObject = pShapeImp->GetSdrObject() ) 2685 { 2686 // collect note caption objects from all layers (internal or hidden) 2687 if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) ) 2688 { 2689 if(pDoc->GetNote(pCaptData->maStart)) 2690 { 2691 pSharedData->AddNoteObj( xShape, pCaptData->maStart ); 2692 2693 // #i60851# When the file is saved while editing a new note, 2694 // the cell is still empty -> last column/row must be updated 2695 OSL_ENSURE( pCaptData->maStart.Tab() == nCurrentTable, "invalid table in object data" ); 2696 pSharedData->SetLastColumn( nCurrentTable, pCaptData->maStart.Col() ); 2697 pSharedData->SetLastRow( nCurrentTable, pCaptData->maStart.Row() ); 2698 } 2699 } 2700 // other objects from internal layer only (detective) 2701 else if( pObject->GetLayer() == SC_LAYER_INTERN ) 2702 { 2703 ScDetectiveFunc aDetFunc( pDoc, static_cast<SCTAB>(nCurrentTable) ); 2704 ScAddress aPosition; 2705 ScRange aSourceRange; 2706 bool bRedLine; 2707 ScDetectiveObjType eObjType = aDetFunc.GetDetectiveObjectType( 2708 pObject, nCurrentTable, aPosition, aSourceRange, bRedLine ); 2709 pSharedData->GetDetectiveObjContainer()->AddObject( eObjType, static_cast<SCTAB>(nCurrentTable), aPosition, aSourceRange, bRedLine ); 2710 } 2711 } 2712 } 2713 } 2714 2715 bool ScXMLExport::GetMerged (const table::CellRangeAddress* pCellAddress, 2716 const uno::Reference <sheet::XSpreadsheet>& xTable) 2717 { 2718 bool bReady(false); 2719 sal_Int32 nRow(pCellAddress->StartRow); 2720 sal_Int32 nCol(pCellAddress->StartColumn); 2721 sal_Int32 nEndRow(pCellAddress->EndRow); 2722 sal_Int32 nEndCol(pCellAddress->EndColumn); 2723 bool bRowInc(nEndRow > nRow); 2724 while(!bReady && nRow <= nEndRow && nCol <= nEndCol) 2725 { 2726 uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY); 2727 if (xSheetCellRange.is()) 2728 { 2729 uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange)); 2730 if(xCursor.is()) 2731 { 2732 uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY); 2733 xCursor->collapseToMergedArea(); 2734 table::CellRangeAddress aCellAddress2(xCellAddress->getRangeAddress()); 2735 ScRange aScRange( aCellAddress2.StartColumn, aCellAddress2.StartRow, aCellAddress2.Sheet, 2736 aCellAddress2.EndColumn, aCellAddress2.EndRow, aCellAddress2.Sheet ); 2737 2738 if ((aScRange.aEnd.Row() > nRow || 2739 aScRange.aEnd.Col() > nCol) && 2740 aScRange.aStart.Row() == nRow && 2741 aScRange.aStart.Col() == nCol) 2742 { 2743 pMergedRangesContainer->AddRange(aScRange); 2744 pSharedData->SetLastColumn(aScRange.aEnd.Tab(), aScRange.aEnd.Col()); 2745 pSharedData->SetLastRow(aScRange.aEnd.Tab(), aScRange.aEnd.Row()); 2746 } 2747 else 2748 bReady = true; 2749 } 2750 } 2751 if (!bReady) 2752 { 2753 if (bRowInc) 2754 ++nRow; 2755 else 2756 ++nCol; 2757 } 2758 } 2759 OSL_ENSURE(!(!bReady && nEndRow > nRow && nEndCol > nCol), "should not be possible"); 2760 return !bReady; 2761 } 2762 2763 bool ScXMLExport::IsMatrix (const ScAddress& aCell, 2764 ScRange& aCellAddress, bool& bIsFirst) const 2765 { 2766 bIsFirst = false; 2767 2768 ScRange aMatrixRange; 2769 2770 if (pDoc && pDoc->GetMatrixFormulaRange(aCell, aMatrixRange)) 2771 { 2772 aCellAddress = aMatrixRange; 2773 if ((aCellAddress.aStart.Col() == aCell.Col() && aCellAddress.aStart.Row() == aCell.Row()) && 2774 (aCellAddress.aEnd.Col() > aCell.Col() || aCellAddress.aEnd.Row() > aCell.Row())) 2775 { 2776 bIsFirst = true; 2777 return true; 2778 } 2779 else if (aCellAddress.aStart.Col() != aCell.Col() || aCellAddress.aStart.Row() != aCell.Row() || 2780 aCellAddress.aEnd.Col() != aCell.Col() || aCellAddress.aEnd.Row()!= aCell.Row()) 2781 return true; 2782 else 2783 { 2784 bIsFirst = true; 2785 return true; 2786 } 2787 } 2788 2789 return false; 2790 } 2791 2792 void ScXMLExport::WriteTable(sal_Int32 nTable, const uno::Reference<sheet::XSpreadsheet>& xTable) 2793 { 2794 if (!xTable.is()) 2795 return; 2796 2797 xCurrentTable.set(xTable); 2798 uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY ); 2799 if (!xName.is()) 2800 return; 2801 2802 nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable ); 2803 OUString sOUTableName(xName->getName()); 2804 AddAttribute(sAttrName, sOUTableName); 2805 AddAttribute(sAttrStyleName, aTableStyles[nTable]); 2806 2807 uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY); 2808 ScTableProtection* pProtect = nullptr; 2809 if (xProtectable.is() && xProtectable->isProtected()) 2810 { 2811 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE); 2812 if (pDoc) 2813 { 2814 pProtect = pDoc->GetTabProtection(nTable); 2815 if (pProtect) 2816 { 2817 OUStringBuffer aBuffer; 2818 ScPasswordHash eHashUsed = PASSHASH_UNSPECIFIED; 2819 if (pProtect->hasPasswordHash(PASSHASH_SHA1)) 2820 { 2821 ::comphelper::Base64::encode(aBuffer, 2822 pProtect->getPasswordHash(PASSHASH_SHA1)); 2823 eHashUsed = PASSHASH_SHA1; 2824 } 2825 else if (pProtect->hasPasswordHash(PASSHASH_SHA256)) 2826 { 2827 ::comphelper::Base64::encode(aBuffer, 2828 pProtect->getPasswordHash(PASSHASH_SHA256)); 2829 eHashUsed = PASSHASH_SHA256; 2830 } 2831 else if (pProtect->hasPasswordHash(PASSHASH_XL, PASSHASH_SHA1)) 2832 { 2833 // Double-hash this by SHA1 on top of the legacy xls hash. 2834 uno::Sequence<sal_Int8> aHash = pProtect->getPasswordHash(PASSHASH_XL, PASSHASH_SHA1); 2835 ::comphelper::Base64::encode(aBuffer, aHash); 2836 eHashUsed = PASSHASH_XL; 2837 } 2838 if (!aBuffer.isEmpty()) 2839 { 2840 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); 2841 if ( getDefaultVersion() >= SvtSaveOptions::ODFVER_012 ) 2842 { 2843 if (eHashUsed == PASSHASH_XL) 2844 { 2845 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, 2846 ScPassHashHelper::getHashURI(PASSHASH_XL)); 2847 if (getDefaultVersion() > SvtSaveOptions::ODFVER_012) 2848 AddAttribute(XML_NAMESPACE_LO_EXT, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2, 2849 ScPassHashHelper::getHashURI(PASSHASH_SHA1)); 2850 } 2851 else if (eHashUsed == PASSHASH_SHA1) 2852 { 2853 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, 2854 ScPassHashHelper::getHashURI(PASSHASH_SHA1)); 2855 } 2856 else if (eHashUsed == PASSHASH_SHA256) 2857 { 2858 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, 2859 ScPassHashHelper::getHashURI(PASSHASH_SHA256)); 2860 } 2861 } 2862 } 2863 } 2864 } 2865 } 2866 OUString sPrintRanges; 2867 ScRange aColumnHeaderRange; 2868 bool bHasColumnHeader; 2869 GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges); 2870 if( !sPrintRanges.isEmpty() ) 2871 AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges ); 2872 else if (pDoc && !pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable))) 2873 AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE); 2874 SvXMLElementExport aElemT(*this, sElemTab, true, true); 2875 2876 if (pProtect && pProtect->isProtected() && getDefaultVersion() > SvtSaveOptions::ODFVER_012) 2877 { 2878 if (pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS)) 2879 AddAttribute(XML_NAMESPACE_LO_EXT, XML_SELECT_PROTECTED_CELLS, XML_TRUE); 2880 if (pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS)) 2881 AddAttribute(XML_NAMESPACE_LO_EXT, XML_SELECT_UNPROTECTED_CELLS, XML_TRUE); 2882 2883 if (pProtect->isOptionEnabled(ScTableProtection::INSERT_COLUMNS)) 2884 AddAttribute(XML_NAMESPACE_LO_EXT, XML_INSERT_COLUMNS, XML_TRUE); 2885 if (pProtect->isOptionEnabled(ScTableProtection::INSERT_ROWS)) 2886 AddAttribute(XML_NAMESPACE_LO_EXT, XML_INSERT_ROWS, XML_TRUE); 2887 2888 if (pProtect->isOptionEnabled(ScTableProtection::DELETE_COLUMNS)) 2889 AddAttribute(XML_NAMESPACE_LO_EXT, XML_DELETE_COLUMNS, XML_TRUE); 2890 if (pProtect->isOptionEnabled(ScTableProtection::DELETE_ROWS)) 2891 AddAttribute(XML_NAMESPACE_LO_EXT, XML_DELETE_ROWS, XML_TRUE); 2892 2893 OUString aElemName = GetNamespaceMap().GetQNameByKey( 2894 XML_NAMESPACE_LO_EXT, GetXMLToken(XML_TABLE_PROTECTION)); 2895 2896 SvXMLElementExport aElemProtected(*this, aElemName, true, true); 2897 } 2898 2899 CheckAttrList(); 2900 2901 if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) && 2902 getDefaultVersion() >= SvtSaveOptions::ODFVER_012 ) 2903 { 2904 // store sheet events 2905 uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY); 2906 uno::Reference<container::XNameAccess> xEvents = xSupplier->getEvents(); 2907 GetEventExport().ExportExt( xEvents ); 2908 } 2909 2910 WriteTableSource(); 2911 WriteScenario(); 2912 uno::Reference<drawing::XDrawPage> xDrawPage; 2913 if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is()) 2914 { 2915 ::xmloff::OOfficeFormsExport aForms(*this); 2916 GetFormExport()->exportForms( xDrawPage ); 2917 bool bRet(GetFormExport()->seekPage( xDrawPage )); 2918 OSL_ENSURE( bRet, "OFormLayerXMLExport::seekPage failed!" ); 2919 } 2920 if (pSharedData->HasDrawPage()) 2921 { 2922 GetShapeExport()->seekShapes(pSharedData->GetDrawPage(nTable)); 2923 WriteTableShapes(); 2924 } 2925 table::CellRangeAddress aRange(GetEndAddress(xTable)); 2926 pSharedData->SetLastColumn(nTable, aRange.EndColumn); 2927 pSharedData->SetLastRow(nTable, aRange.EndRow); 2928 mpCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable); 2929 pGroupColumns->NewTable(); 2930 pGroupRows->NewTable(); 2931 FillColumnRowGroups(); 2932 if (bHasColumnHeader) 2933 pSharedData->SetLastColumn(nTable, aColumnHeaderRange.aEnd.Col()); 2934 bRowHeaderOpen = false; 2935 if (bHasRowHeader) 2936 pSharedData->SetLastRow(nTable, aRowHeaderRange.aEnd.Row()); 2937 pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable), 2938 pSharedData->GetLastColumn(nTable), pCellStyles.get(), pDoc); 2939 pRowFormatRanges->SetColDefaults(&pDefaults->GetColDefaults()); 2940 pCellStyles->SetColDefaults(&pDefaults->GetColDefaults()); 2941 ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader); 2942 bool bIsFirst(true); 2943 sal_Int32 nEqualCells(0); 2944 ScMyCell aCell; 2945 ScMyCell aPrevCell; 2946 while (mpCellsItr->GetNext(aCell, pCellStyles.get())) 2947 { 2948 if (bIsFirst) 2949 { 2950 ExportFormatRanges(0, 0, aCell.maCellAddress.Col()-1, aCell.maCellAddress.Row(), nTable); 2951 aPrevCell = aCell; 2952 bIsFirst = false; 2953 } 2954 else 2955 { 2956 if ((aPrevCell.maCellAddress.Row() == aCell.maCellAddress.Row()) && 2957 (aPrevCell.maCellAddress.Col() + nEqualCells + 1 == aCell.maCellAddress.Col())) 2958 { 2959 if(IsCellEqual(aPrevCell, aCell)) 2960 ++nEqualCells; 2961 else 2962 { 2963 WriteCell(aPrevCell, nEqualCells); 2964 nEqualCells = 0; 2965 aPrevCell = aCell; 2966 } 2967 } 2968 else 2969 { 2970 WriteCell(aPrevCell, nEqualCells); 2971 ExportFormatRanges(aPrevCell.maCellAddress.Col() + nEqualCells + 1, aPrevCell.maCellAddress.Row(), 2972 aCell.maCellAddress.Col()-1, aCell.maCellAddress.Row(), nTable); 2973 nEqualCells = 0; 2974 aPrevCell = aCell; 2975 } 2976 } 2977 } 2978 if (!bIsFirst) 2979 { 2980 WriteCell(aPrevCell, nEqualCells); 2981 ExportFormatRanges(aPrevCell.maCellAddress.Col() + nEqualCells + 1, aPrevCell.maCellAddress.Row(), 2982 pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); 2983 } 2984 else 2985 ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); 2986 2987 CloseRow(pSharedData->GetLastRow(nTable)); 2988 2989 if (pDoc) 2990 { 2991 // Export sheet-local named ranges. 2992 ScRangeName* pRangeName = pDoc->GetRangeName(nTable); 2993 if (pRangeName && !pRangeName->empty()) 2994 { 2995 WriteNamedRange(pRangeName); 2996 } 2997 2998 if(getDefaultVersion() > SvtSaveOptions::ODFVER_012) 2999 { 3000 //export new conditional format information 3001 ExportConditionalFormat(nTable); 3002 } 3003 3004 } 3005 } 3006 3007 namespace { 3008 3009 void writeContent( 3010 ScXMLExport& rExport, const OUString& rStyleName, const OUString& rContent, const SvxFieldData* pField ) 3011 { 3012 std::unique_ptr<SvXMLElementExport> pElem; 3013 if (!rStyleName.isEmpty()) 3014 { 3015 // Formatted section with automatic style. 3016 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, rStyleName); 3017 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( 3018 XML_NAMESPACE_TEXT, GetXMLToken(XML_SPAN)); 3019 pElem.reset(new SvXMLElementExport(rExport, aElemName, false, false)); 3020 } 3021 3022 if (pField) 3023 { 3024 // Write a field item. 3025 OUString aFieldVal = ScEditUtil::GetCellFieldValue(*pField, rExport.GetDocument(), nullptr); 3026 switch (pField->GetClassId()) 3027 { 3028 case text::textfield::Type::URL: 3029 { 3030 // <text:a xlink:href="url" xlink:type="simple">value</text:a> 3031 3032 const SvxURLField* pURLField = static_cast<const SvxURLField*>(pField); 3033 const OUString& aURL = pURLField->GetURL(); 3034 rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, rExport.GetRelativeReference(aURL)); 3035 rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, "simple"); 3036 const OUString& aTargetFrame = pURLField->GetTargetFrame(); 3037 if (!aTargetFrame.isEmpty()) 3038 rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, aTargetFrame); 3039 3040 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( 3041 XML_NAMESPACE_TEXT, GetXMLToken(XML_A)); 3042 SvXMLElementExport aElem(rExport, aElemName, false, false); 3043 rExport.Characters(aFieldVal); 3044 } 3045 break; 3046 case text::textfield::Type::DATE: 3047 { 3048 // <text:date style:data-style-name="N2" text:date-value="YYYY-MM-DD">value</text:date> 3049 3050 Date aDate(Date::SYSTEM); 3051 OUStringBuffer aBuf; 3052 sal_Int32 nVal = aDate.GetYear(); 3053 aBuf.append(nVal); 3054 aBuf.append('-'); 3055 nVal = aDate.GetMonth(); 3056 if (nVal < 10) 3057 aBuf.append('0'); 3058 aBuf.append(nVal); 3059 aBuf.append('-'); 3060 nVal = aDate.GetDay(); 3061 if (nVal < 10) 3062 aBuf.append('0'); 3063 aBuf.append(nVal); 3064 rExport.AddAttribute(XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, "N2"); 3065 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_DATE_VALUE, aBuf.makeStringAndClear()); 3066 3067 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( 3068 XML_NAMESPACE_TEXT, GetXMLToken(XML_DATE)); 3069 SvXMLElementExport aElem(rExport, aElemName, false, false); 3070 rExport.Characters(aFieldVal); 3071 } 3072 break; 3073 case text::textfield::Type::DOCINFO_TITLE: 3074 { 3075 // <text:title>value</text:title> 3076 3077 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( 3078 XML_NAMESPACE_TEXT, GetXMLToken(XML_TITLE)); 3079 SvXMLElementExport aElem(rExport, aElemName, false, false); 3080 rExport.Characters(aFieldVal); 3081 } 3082 break; 3083 case text::textfield::Type::TABLE: 3084 { 3085 // <text:sheet-name>value</text:sheet-name> 3086 3087 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( 3088 XML_NAMESPACE_TEXT, GetXMLToken(XML_SHEET_NAME)); 3089 SvXMLElementExport aElem(rExport, aElemName, false, false); 3090 rExport.Characters(aFieldVal); 3091 } 3092 break; 3093 default: 3094 rExport.Characters(aFieldVal); 3095 } 3096 } 3097 else 3098 rExport.Characters(rContent); 3099 } 3100 3101 void flushParagraph( 3102 ScXMLExport& rExport, const OUString& rParaText, 3103 rtl::Reference<XMLPropertySetMapper> const & xMapper, rtl::Reference<SvXMLAutoStylePoolP> const & xStylePool, 3104 const ScXMLEditAttributeMap& rAttrMap, 3105 std::vector<editeng::Section>::const_iterator it, std::vector<editeng::Section>::const_iterator const & itEnd ) 3106 { 3107 OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey( 3108 XML_NAMESPACE_TEXT, GetXMLToken(XML_P)); 3109 SvXMLElementExport aElemP(rExport, aElemName, false, false); 3110 3111 for (; it != itEnd; ++it) 3112 { 3113 const editeng::Section& rSec = *it; 3114 3115 OUString aContent(rParaText.copy(rSec.mnStart, rSec.mnEnd - rSec.mnStart)); 3116 3117 std::vector<XMLPropertyState> aPropStates; 3118 const SvxFieldData* pField = toXMLPropertyStates(aPropStates, rSec.maAttributes, xMapper, rAttrMap); 3119 OUString aStyleName = xStylePool->Find(XML_STYLE_FAMILY_TEXT_TEXT, OUString(), aPropStates); 3120 writeContent(rExport, aStyleName, aContent, pField); 3121 } 3122 } 3123 3124 } 3125 3126 void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount) 3127 { 3128 // nEqualCellCount is the number of additional cells 3129 SetRepeatAttribute(nEqualCellCount, (aCell.nType != table::CellContentType_EMPTY)); 3130 3131 if (aCell.nStyleIndex != -1) 3132 AddAttribute(sAttrStyleName, pCellStyles->GetStyleNameByIndex(aCell.nStyleIndex, aCell.bIsAutoStyle)); 3133 if (aCell.nValidationIndex > -1) 3134 AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(aCell.nValidationIndex)); 3135 const bool bIsFirstMatrixCell(aCell.bIsMatrixBase); 3136 if (bIsFirstMatrixCell) 3137 { 3138 SCCOL nColumns( aCell.aMatrixRange.aEnd.Col() - aCell.aMatrixRange.aStart.Col() + 1 ); 3139 SCROW nRows( aCell.aMatrixRange.aEnd.Row() - aCell.aMatrixRange.aStart.Row() + 1 ); 3140 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, OUString::number(nColumns)); 3141 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, OUString::number(nRows)); 3142 } 3143 bool bIsEmpty(false); 3144 switch (aCell.nType) 3145 { 3146 case table::CellContentType_EMPTY : 3147 { 3148 bIsEmpty = true; 3149 } 3150 break; 3151 case table::CellContentType_VALUE : 3152 { 3153 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( 3154 aCell.nNumberFormat, aCell.maBaseCell.mfValue); 3155 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 ) 3156 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( 3157 aCell.nNumberFormat, aCell.maBaseCell.mfValue, false, XML_NAMESPACE_CALC_EXT, false); 3158 } 3159 break; 3160 case table::CellContentType_TEXT : 3161 { 3162 OUString sFormattedString(lcl_GetFormattedString(pDoc, aCell.maBaseCell, aCell.maCellAddress)); 3163 OUString sCellString = aCell.maBaseCell.getString(pDoc); 3164 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( 3165 sCellString, sFormattedString); 3166 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 ) 3167 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( 3168 sCellString, sFormattedString, false, XML_NAMESPACE_CALC_EXT); 3169 } 3170 break; 3171 case table::CellContentType_FORMULA : 3172 { 3173 if (aCell.maBaseCell.meType == CELLTYPE_FORMULA) 3174 { 3175 const bool bIsMatrix(bIsFirstMatrixCell || aCell.bIsMatrixCovered); 3176 ScFormulaCell* pFormulaCell = aCell.maBaseCell.mpFormula; 3177 if (!bIsMatrix || bIsFirstMatrixCell) 3178 { 3179 if (!mpCompileFormulaCxt) 3180 { 3181 const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar(); 3182 mpCompileFormulaCxt.reset(new sc::CompileFormulaContext(pDoc, eGrammar)); 3183 } 3184 3185 OUString aFormula = pFormulaCell->GetFormula(*mpCompileFormulaCxt); 3186 sal_uInt16 nNamespacePrefix = 3187 (mpCompileFormulaCxt->getGrammar() == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC); 3188 3189 if (!bIsMatrix) 3190 { 3191 AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey(nNamespacePrefix, aFormula, false)); 3192 } 3193 else 3194 { 3195 AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey(nNamespacePrefix, aFormula.copy(1, aFormula.getLength()-2), false)); 3196 } 3197 } 3198 if (pFormulaCell->GetErrCode() != FormulaError::NONE) 3199 { 3200 AddAttribute(sAttrValueType, XML_STRING); 3201 AddAttribute(sAttrStringValue, aCell.maBaseCell.getString(pDoc)); 3202 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 ) 3203 { 3204 //export calcext:value-type="error" 3205 AddAttribute(XML_NAMESPACE_CALC_EXT,XML_VALUE_TYPE, OUString("error")); 3206 } 3207 } 3208 else if (pFormulaCell->IsValue()) 3209 { 3210 bool bIsStandard; 3211 OUString sCurrency; 3212 GetNumberFormatAttributesExportHelper()->GetCellType(aCell.nNumberFormat, sCurrency, bIsStandard); 3213 if (pDoc) 3214 { 3215 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( 3216 aCell.nNumberFormat, pDoc->GetValue(aCell.maCellAddress)); 3217 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 ) 3218 { 3219 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( 3220 aCell.nNumberFormat, pDoc->GetValue(aCell.maCellAddress), false, XML_NAMESPACE_CALC_EXT, false ); 3221 } 3222 } 3223 } 3224 else 3225 { 3226 if (!aCell.maBaseCell.getString(pDoc).isEmpty()) 3227 { 3228 AddAttribute(sAttrValueType, XML_STRING); 3229 AddAttribute(sAttrStringValue, aCell.maBaseCell.getString(pDoc)); 3230 if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 ) 3231 { 3232 AddAttribute(XML_NAMESPACE_CALC_EXT,XML_VALUE_TYPE, XML_STRING); 3233 } 3234 } 3235 } 3236 } 3237 } 3238 break; 3239 default: 3240 break; 3241 } 3242 OUString* pCellString(&sElemCell); 3243 if (aCell.bIsCovered) 3244 { 3245 pCellString = &sElemCoveredCell; 3246 } 3247 else 3248 { 3249 if (aCell.bIsMergedBase) 3250 { 3251 SCCOL nColumns( aCell.aMergeRange.aEnd.Col() - aCell.aMergeRange.aStart.Col() + 1 ); 3252 SCROW nRows( aCell.aMergeRange.aEnd.Row() - aCell.aMergeRange.aStart.Row() + 1 ); 3253 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, OUString::number(nColumns)); 3254 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, OUString::number(nRows)); 3255 } 3256 } 3257 SvXMLElementExport aElemC(*this, *pCellString, true, true); 3258 CheckAttrList(); 3259 WriteAreaLink(aCell); 3260 WriteAnnotation(aCell); 3261 WriteDetective(aCell); 3262 3263 if (!bIsEmpty) 3264 { 3265 if (aCell.maBaseCell.meType == CELLTYPE_EDIT) 3266 { 3267 WriteEditCell(aCell.maBaseCell.mpEditText); 3268 } 3269 else if (aCell.maBaseCell.meType == CELLTYPE_FORMULA && aCell.maBaseCell.mpFormula->IsMultilineResult()) 3270 { 3271 WriteMultiLineFormulaResult(aCell.maBaseCell.mpFormula); 3272 } 3273 else 3274 { 3275 SvXMLElementExport aElemP(*this, sElemP, true, false); 3276 3277 OUString aParaStr = 3278 ScCellFormat::GetOutputString(*pDoc, aCell.maCellAddress, aCell.maBaseCell); 3279 3280 bool bPrevCharWasSpace = true; 3281 GetTextParagraphExport()->exportCharacterData(aParaStr, bPrevCharWasSpace); 3282 } 3283 } 3284 WriteShapes(aCell); 3285 if (!bIsEmpty) 3286 IncrementProgressBar(false); 3287 } 3288 3289 void ScXMLExport::WriteEditCell(const EditTextObject* pText) 3290 { 3291 rtl::Reference<XMLPropertySetMapper> xMapper = GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper(); 3292 rtl::Reference<SvXMLAutoStylePoolP> xStylePool = GetAutoStylePool(); 3293 const ScXMLEditAttributeMap& rAttrMap = GetEditAttributeMap(); 3294 3295 // Get raw paragraph texts first. 3296 std::vector<OUString> aParaTexts; 3297 sal_Int32 nParaCount = pText->GetParagraphCount(); 3298 aParaTexts.reserve(nParaCount); 3299 for (sal_Int32 i = 0; i < nParaCount; ++i) 3300 aParaTexts.push_back(pText->GetText(i)); 3301 3302 // Get all section data and iterate through them. 3303 std::vector<editeng::Section> aAttrs; 3304 pText->GetAllSections(aAttrs); 3305 std::vector<editeng::Section>::const_iterator itSec = aAttrs.begin(), itSecEnd = aAttrs.end(); 3306 std::vector<editeng::Section>::const_iterator itPara = itSec; 3307 sal_Int32 nCurPara = 0; // current paragraph 3308 for (; itSec != itSecEnd; ++itSec) 3309 { 3310 const editeng::Section& rSec = *itSec; 3311 if (nCurPara == rSec.mnParagraph) 3312 // Still in the same paragraph. 3313 continue; 3314 3315 // Start of a new paragraph. Flush the old paragraph. 3316 flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSec); 3317 nCurPara = rSec.mnParagraph; 3318 itPara = itSec; 3319 } 3320 3321 flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSecEnd); 3322 } 3323 3324 void ScXMLExport::WriteMultiLineFormulaResult(const ScFormulaCell* pCell) 3325 { 3326 OUString aElemName = GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TEXT, GetXMLToken(XML_P)); 3327 3328 OUString aResStr = pCell->GetResultString().getString(); 3329 const sal_Unicode* p = aResStr.getStr(); 3330 const sal_Unicode* pEnd = p + static_cast<size_t>(aResStr.getLength()); 3331 const sal_Unicode* pPara = p; // paragraph head. 3332 for (; p != pEnd; ++p) 3333 { 3334 if (*p != '\n') 3335 continue; 3336 3337 // flush the paragraph. 3338 OUString aContent; 3339 if (*pPara == '\n') 3340 ++pPara; 3341 if (p > pPara) 3342 aContent = OUString(pPara, p-pPara); 3343 3344 SvXMLElementExport aElem(*this, aElemName, false, false); 3345 Characters(aContent); 3346 3347 pPara = p; 3348 } 3349 3350 OUString aContent; 3351 if (*pPara == '\n') 3352 ++pPara; 3353 if (pEnd > pPara) 3354 aContent = OUString(pPara, pEnd-pPara); 3355 3356 SvXMLElementExport aElem(*this, aElemName, false, false); 3357 Characters(aContent); 3358 } 3359 3360 void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint) 3361 { 3362 uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY ); 3363 bool bIsChart( false ); 3364 OUString sPropCLSID ("CLSID"); 3365 if (xShapeProps.is()) 3366 { 3367 sal_Int32 nZOrder = 0; 3368 if (xShapeProps->getPropertyValue("ZOrder") >>= nZOrder) 3369 { 3370 AddAttribute(XML_NAMESPACE_DRAW, XML_ZINDEX, OUString::number(nZOrder)); 3371 } 3372 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xShapeProps->getPropertySetInfo(); 3373 if( xPropSetInfo->hasPropertyByName( sPropCLSID ) ) 3374 { 3375 OUString sCLSID; 3376 if (xShapeProps->getPropertyValue( sPropCLSID ) >>= sCLSID) 3377 { 3378 if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) ) 3379 { 3380 // we have a chart 3381 OUString sRanges; 3382 if ( pDoc ) 3383 { 3384 OUString aChartName; 3385 xShapeProps->getPropertyValue( "PersistName" ) >>= aChartName; 3386 ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); 3387 if (pCollection) 3388 { 3389 ScChartListener* pListener = pCollection->findByName(aChartName); 3390 if (pListener) 3391 { 3392 const ScRangeListRef& rRangeList = pListener->GetRangeList(); 3393 if ( rRangeList.is() ) 3394 { 3395 ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList.get(), pDoc, FormulaGrammar::CONV_OOO ); 3396 if ( !sRanges.isEmpty() ) 3397 { 3398 bIsChart = true; 3399 SvXMLAttributeList* pAttrList = new SvXMLAttributeList(); 3400 pAttrList->AddAttribute( 3401 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges ); 3402 GetShapeExport()->exportShape( xShape, SEF_DEFAULT, pPoint, pAttrList ); 3403 } 3404 } 3405 } 3406 } 3407 } 3408 3409 if ( sRanges.isEmpty() ) 3410 { 3411 uno::Reference< frame::XModel > xChartModel; 3412 if( ( xShapeProps->getPropertyValue( "Model" ) >>= xChartModel ) && 3413 xChartModel.is()) 3414 { 3415 uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY ); 3416 uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY ); 3417 if( xChartDoc.is() && xReceiver.is() && 3418 ! xChartDoc->hasInternalDataProvider()) 3419 { 3420 // we have a chart that gets its data from Calc 3421 bIsChart = true; 3422 uno::Sequence< OUString > aRepresentations( 3423 xReceiver->getUsedRangeRepresentations()); 3424 SvXMLAttributeList* pAttrList = nullptr; 3425 if(aRepresentations.hasElements()) 3426 { 3427 // add the ranges used by the chart to the shape 3428 // element to be able to start listening after 3429 // load (when the chart is not yet loaded) 3430 uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY ); 3431 sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter ); 3432 pAttrList = new SvXMLAttributeList(); 3433 pAttrList->AddAttribute( 3434 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges ); 3435 } 3436 GetShapeExport()->exportShape(xShape, SEF_DEFAULT, pPoint, pAttrList); 3437 } 3438 } 3439 } 3440 } 3441 } 3442 } 3443 } 3444 if (!bIsChart) 3445 { 3446 OUString sHlink; 3447 try 3448 { 3449 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); 3450 if ( xProps.is() ) 3451 xProps->getPropertyValue( SC_UNONAME_HYPERLINK ) >>= sHlink; 3452 } 3453 catch ( const beans::UnknownPropertyException& ) 3454 { 3455 // no hyperlink property 3456 } 3457 3458 std::unique_ptr< SvXMLElementExport > pDrawA; 3459 // enclose shapes with <draw:a> element only if sHlink contains something 3460 if ( !sHlink.isEmpty() ) 3461 { 3462 // need to get delete the attributes that are pre-loaded 3463 // for the shape export ( otherwise they will become 3464 // attributes of the draw:a element ) This *shouldn't* 3465 // affect performance adversely as there are only a 3466 // couple of attributes involved 3467 uno::Reference< xml::sax::XAttributeList > xSaveAttribs( new SvXMLAttributeList( GetAttrList() ) ); 3468 ClearAttrList(); 3469 // Add Hlink 3470 AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); 3471 AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sHlink); 3472 pDrawA.reset( new SvXMLElementExport( *this, XML_NAMESPACE_DRAW, XML_A, false, false ) ); 3473 // Attribute list has been cleared by previous operation 3474 // re-add pre-loaded attributes 3475 AddAttributeList( xSaveAttribs ); 3476 } 3477 GetShapeExport()->exportShape(xShape, SEF_DEFAULT, pPoint); 3478 } 3479 IncrementProgressBar(false); 3480 } 3481 3482 void ScXMLExport::WriteShapes(const ScMyCell& rMyCell) 3483 { 3484 if( rMyCell.bHasShape && !rMyCell.aShapeList.empty() && pDoc ) 3485 { 3486 awt::Point aPoint; 3487 tools::Rectangle aRect = pDoc->GetMMRect(rMyCell.maCellAddress.Col(), rMyCell.maCellAddress.Row(), 3488 rMyCell.maCellAddress.Col(), rMyCell.maCellAddress.Row(), rMyCell.maCellAddress.Tab()); 3489 bool bNegativePage = pDoc->IsNegativePage(rMyCell.maCellAddress.Tab()); 3490 if (bNegativePage) 3491 aPoint.X = aRect.Right(); 3492 else 3493 aPoint.X = aRect.Left(); 3494 aPoint.Y = aRect.Top(); 3495 for (const auto& rShape : rMyCell.aShapeList) 3496 { 3497 if (rShape.xShape.is()) 3498 { 3499 if (bNegativePage) 3500 aPoint.X = 2 * rShape.xShape->getPosition().X + rShape.xShape->getSize().Width - aPoint.X; 3501 3502 // We only write the end address if we want the shape to resize with the cell 3503 if ( rShape.bResizeWithCell && 3504 rShape.xShape->getShapeType() != "com.sun.star.drawing.CaptionShape" ) 3505 { 3506 OUString sEndAddress; 3507 ScRangeStringConverter::GetStringFromAddress(sEndAddress, rShape.aEndAddress, pDoc, FormulaGrammar::CONV_OOO); 3508 AddAttribute(XML_NAMESPACE_TABLE, XML_END_CELL_ADDRESS, sEndAddress); 3509 OUStringBuffer sBuffer; 3510 GetMM100UnitConverter().convertMeasureToXML( 3511 sBuffer, rShape.nEndX); 3512 AddAttribute(XML_NAMESPACE_TABLE, XML_END_X, sBuffer.makeStringAndClear()); 3513 GetMM100UnitConverter().convertMeasureToXML( 3514 sBuffer, rShape.nEndY); 3515 AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear()); 3516 } 3517 ExportShape(rShape.xShape, &aPoint); 3518 } 3519 } 3520 } 3521 } 3522 3523 void ScXMLExport::WriteTableShapes() 3524 { 3525 ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes()); 3526 if (pTableShapes && !(*pTableShapes)[nCurrentTable].empty()) 3527 { 3528 OSL_ENSURE(pTableShapes->size() > static_cast<size_t>(nCurrentTable), "wrong Table"); 3529 SvXMLElementExport aShapesElem(*this, XML_NAMESPACE_TABLE, XML_SHAPES, true, false); 3530 for (const auto& rxShape : (*pTableShapes)[nCurrentTable]) 3531 { 3532 if (rxShape.is()) 3533 { 3534 if (pDoc->IsNegativePage(static_cast<SCTAB>(nCurrentTable))) 3535 { 3536 awt::Point aPoint(rxShape->getPosition()); 3537 awt::Size aSize(rxShape->getSize()); 3538 aPoint.X += aPoint.X + aSize.Width; 3539 aPoint.Y = 0; 3540 ExportShape(rxShape, &aPoint); 3541 } 3542 else 3543 ExportShape(rxShape, nullptr); 3544 } 3545 } 3546 (*pTableShapes)[nCurrentTable].clear(); 3547 } 3548 } 3549 3550 void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell ) 3551 { 3552 if( rMyCell.bHasAreaLink ) 3553 { 3554 const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink; 3555 AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr ); 3556 AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); 3557 AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) ); 3558 AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter ); 3559 if( !rAreaLink.sFilterOptions.isEmpty() ) 3560 AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, rAreaLink.sFilterOptions ); 3561 OUStringBuffer sValue; 3562 AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, OUString::number(rAreaLink.GetColCount()) ); 3563 AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, OUString::number(rAreaLink.GetRowCount()) ); 3564 if( rAreaLink.nRefresh ) 3565 { 3566 ::sax::Converter::convertDuration( sValue, 3567 static_cast<double>(rAreaLink.nRefresh) / 86400 ); 3568 AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sValue.makeStringAndClear() ); 3569 } 3570 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, true, true ); 3571 } 3572 } 3573 3574 void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape) 3575 { 3576 ScPostIt* pNote = pCurrentCell->pNote; 3577 3578 if (pNote) 3579 { 3580 // TODO : notes 3581 //is it still useful, as this call back is only called from ScXMLExport::WriteAnnotation 3582 // and should be in sync with pCurrentCell 3583 SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(pCurrentCell->maCellAddress); 3584 uno::Reference<drawing::XShape> xCurrentShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY ); 3585 if (xCurrentShape.get()!=xShape.get()) 3586 return; 3587 3588 const OUString& sAuthor(pNote->GetAuthor()); 3589 if (!sAuthor.isEmpty()) 3590 { 3591 SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC, 3592 XML_CREATOR, true, 3593 false ); 3594 Characters(sAuthor); 3595 } 3596 3597 const OUString& aDate(pNote->GetDate()); 3598 if (pDoc) 3599 { 3600 SvNumberFormatter* pNumForm = pDoc->GetFormatTable(); 3601 double fDate; 3602 sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM); 3603 if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate)) 3604 { 3605 OUStringBuffer sBuf; 3606 GetMM100UnitConverter().convertDateTime(sBuf, fDate,true); 3607 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC, 3608 XML_DATE, true, 3609 false ); 3610 Characters(sBuf.makeStringAndClear()); 3611 } 3612 else 3613 { 3614 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META, 3615 XML_DATE_STRING, true, 3616 false ); 3617 Characters(aDate); 3618 } 3619 } 3620 else 3621 { 3622 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META, 3623 XML_DATE_STRING, true, 3624 false ); 3625 Characters(aDate); 3626 } 3627 } 3628 } 3629 3630 void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell) 3631 { 3632 ScPostIt* pNote = pDoc->GetNote(rMyCell.maCellAddress); 3633 if (pNote) 3634 { 3635 if (pNote->IsCaptionShown()) 3636 AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE); 3637 3638 pCurrentCell = &rMyCell; 3639 3640 SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(rMyCell.maCellAddress); 3641 if (pNoteCaption) 3642 { 3643 uno::Reference<drawing::XShape> xShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY ); 3644 if (xShape.is()) 3645 GetShapeExport()->exportShape(xShape, SEF_DEFAULT|XMLShapeExportFlags::ANNOTATION); 3646 } 3647 3648 pCurrentCell = nullptr; 3649 3650 } 3651 } 3652 3653 void ScXMLExport::WriteDetective( const ScMyCell& rMyCell ) 3654 { 3655 if( rMyCell.bHasDetectiveObj || rMyCell.bHasDetectiveOp ) 3656 { 3657 const ScMyDetectiveObjVec& rObjVec = rMyCell.aDetectiveObjVec; 3658 const ScMyDetectiveOpVec& rOpVec = rMyCell.aDetectiveOpVec; 3659 sal_Int32 nObjCount(rObjVec.size()); 3660 sal_Int32 nOpCount(rOpVec.size()); 3661 if( nObjCount || nOpCount ) 3662 { 3663 SvXMLElementExport aDetElem( *this, XML_NAMESPACE_TABLE, XML_DETECTIVE, true, true ); 3664 OUString sString; 3665 for(const auto& rObj : rObjVec) 3666 { 3667 if (rObj.eObjType != SC_DETOBJ_CIRCLE) 3668 { 3669 if( (rObj.eObjType == SC_DETOBJ_ARROW) || (rObj.eObjType == SC_DETOBJ_TOOTHERTAB)) 3670 { 3671 ScRangeStringConverter::GetStringFromRange( sString, rObj.aSourceRange, pDoc, FormulaGrammar::CONV_OOO ); 3672 AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sString ); 3673 } 3674 ScXMLConverter::GetStringFromDetObjType( sString, rObj.eObjType ); 3675 AddAttribute( XML_NAMESPACE_TABLE, XML_DIRECTION, sString ); 3676 if( rObj.bHasError ) 3677 AddAttribute( XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TRUE ); 3678 } 3679 else 3680 AddAttribute( XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TRUE ); 3681 SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, true, true ); 3682 } 3683 for(const auto& rOp : rOpVec) 3684 { 3685 OUString sOpString; 3686 ScXMLConverter::GetStringFromDetOpType( sOpString, rOp.eOpType ); 3687 AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, sOpString ); 3688 AddAttribute( XML_NAMESPACE_TABLE, XML_INDEX, OUString::number(rOp.nIndex) ); 3689 SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_OPERATION, true, true ); 3690 } 3691 } 3692 } 3693 } 3694 3695 void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount, bool bIncProgress) 3696 { 3697 // nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1 3698 if (nEqualCellCount > 0) 3699 { 3700 sal_Int32 nTemp(nEqualCellCount + 1); 3701 OUString sOUEqualCellCount(OUString::number(nTemp)); 3702 AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount); 3703 if (bIncProgress) 3704 IncrementProgressBar(false, nEqualCellCount); 3705 } 3706 } 3707 3708 bool ScXMLExport::IsEditCell(const ScMyCell& rCell) 3709 { 3710 return rCell.maBaseCell.meType == CELLTYPE_EDIT; 3711 } 3712 3713 bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2) 3714 { 3715 bool bIsEqual = false; 3716 if( !aCell1.bIsMergedBase && !aCell2.bIsMergedBase && 3717 aCell1.bIsCovered == aCell2.bIsCovered && 3718 !aCell1.bIsMatrixBase && !aCell2.bIsMatrixBase && 3719 aCell1.bIsMatrixCovered == aCell2.bIsMatrixCovered && 3720 aCell1.bHasAnnotation == aCell2.bHasAnnotation && 3721 !aCell1.bHasShape && !aCell2.bHasShape && 3722 aCell1.bHasAreaLink == aCell2.bHasAreaLink && 3723 !aCell1.bHasDetectiveObj && !aCell2.bHasDetectiveObj) 3724 { 3725 if( (aCell1.bHasAreaLink && 3726 (aCell1.aAreaLink.GetColCount() == 1) && 3727 (aCell2.aAreaLink.GetColCount() == 1) && 3728 aCell1.aAreaLink.Compare( aCell2.aAreaLink ) ) || 3729 !aCell1.bHasAreaLink ) 3730 { 3731 if (!aCell1.bHasAnnotation) 3732 { 3733 if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) || 3734 ((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) && 3735 aCell1.nValidationIndex == aCell2.nValidationIndex && 3736 aCell1.nType == aCell2.nType) 3737 { 3738 switch ( aCell1.nType ) 3739 { 3740 case table::CellContentType_EMPTY : 3741 { 3742 bIsEqual = true; 3743 } 3744 break; 3745 case table::CellContentType_VALUE : 3746 { 3747 // #i29101# number format may be different from column default styles, 3748 // but can lead to different value types, so it must also be compared 3749 bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) && 3750 (aCell1.maBaseCell.mfValue == aCell2.maBaseCell.mfValue); 3751 } 3752 break; 3753 case table::CellContentType_TEXT : 3754 { 3755 if (IsEditCell(aCell1) || IsEditCell(aCell2)) 3756 bIsEqual = false; 3757 else 3758 { 3759 bIsEqual = (aCell1.maBaseCell.getString(pDoc) == aCell2.maBaseCell.getString(pDoc)); 3760 } 3761 } 3762 break; 3763 case table::CellContentType_FORMULA : 3764 { 3765 bIsEqual = false; 3766 } 3767 break; 3768 default : 3769 { 3770 bIsEqual = false; 3771 } 3772 break; 3773 } 3774 } 3775 } 3776 } 3777 } 3778 return bIsEqual; 3779 } 3780 3781 void ScXMLExport::WriteCalculationSettings(const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc) 3782 { 3783 uno::Reference<beans::XPropertySet> xPropertySet(xSpreadDoc, uno::UNO_QUERY); 3784 if (xPropertySet.is()) 3785 { 3786 bool bCalcAsShown (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_CALCASSHOWN) )); 3787 bool bIgnoreCase (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_IGNORECASE) )); 3788 bool bLookUpLabels (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_LOOKUPLABELS) )); 3789 bool bMatchWholeCell (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_MATCHWHOLE) )); 3790 bool bUseRegularExpressions (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_REGEXENABLED) )); 3791 bool bUseWildcards (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_WILDCARDSENABLED) )); 3792 if (bUseWildcards && bUseRegularExpressions) 3793 bUseRegularExpressions = false; // mutually exclusive, wildcards take precedence 3794 bool bIsIterationEnabled (::cppu::any2bool( xPropertySet->getPropertyValue(SC_UNO_ITERENABLED) )); 3795 sal_uInt16 nYear2000 (pDoc ? pDoc->GetDocOptions().GetYear2000() : 0); 3796 sal_Int32 nIterationCount(100); 3797 xPropertySet->getPropertyValue( SC_UNO_ITERCOUNT ) >>= nIterationCount; 3798 double fIterationEpsilon = 0; 3799 xPropertySet->getPropertyValue( SC_UNO_ITEREPSILON ) >>= fIterationEpsilon; 3800 util::Date aNullDate; 3801 xPropertySet->getPropertyValue( SC_UNO_NULLDATE ) >>= aNullDate; 3802 if (bCalcAsShown || bIgnoreCase || !bLookUpLabels || !bMatchWholeCell || !bUseRegularExpressions || 3803 bUseWildcards || 3804 bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001) || 3805 aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 || nYear2000 != 1930) 3806 { 3807 if (bIgnoreCase) 3808 AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_FALSE); 3809 if (bCalcAsShown) 3810 AddAttribute(XML_NAMESPACE_TABLE, XML_PRECISION_AS_SHOWN, XML_TRUE); 3811 if (!bMatchWholeCell) 3812 AddAttribute(XML_NAMESPACE_TABLE, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL, XML_FALSE); 3813 if (!bLookUpLabels) 3814 AddAttribute(XML_NAMESPACE_TABLE, XML_AUTOMATIC_FIND_LABELS, XML_FALSE); 3815 if (!bUseRegularExpressions) 3816 AddAttribute(XML_NAMESPACE_TABLE, XML_USE_REGULAR_EXPRESSIONS, XML_FALSE); 3817 if (bUseWildcards) 3818 AddAttribute(XML_NAMESPACE_TABLE, XML_USE_WILDCARDS, XML_TRUE); 3819 if (nYear2000 != 1930) 3820 { 3821 AddAttribute(XML_NAMESPACE_TABLE, XML_NULL_YEAR, OUString::number(nYear2000)); 3822 } 3823 SvXMLElementExport aCalcSettings(*this, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, true, true); 3824 { 3825 if (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899) 3826 { 3827 OUStringBuffer sDate; 3828 SvXMLUnitConverter::convertDateTime(sDate, 0.0, aNullDate); 3829 AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_VALUE, sDate.makeStringAndClear()); 3830 SvXMLElementExport aElemNullDate(*this, XML_NAMESPACE_TABLE, XML_NULL_DATE, true, true); 3831 } 3832 if (bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001)) 3833 { 3834 OUStringBuffer sBuffer; 3835 if (bIsIterationEnabled) 3836 AddAttribute(XML_NAMESPACE_TABLE, XML_STATUS, XML_ENABLE); 3837 if (nIterationCount != 100) 3838 { 3839 AddAttribute(XML_NAMESPACE_TABLE, XML_STEPS, OUString::number(nIterationCount)); 3840 } 3841 if (!::rtl::math::approxEqual(fIterationEpsilon, 0.001)) 3842 { 3843 ::sax::Converter::convertDouble(sBuffer, 3844 fIterationEpsilon); 3845 AddAttribute(XML_NAMESPACE_TABLE, XML_MAXIMUM_DIFFERENCE, sBuffer.makeStringAndClear()); 3846 } 3847 SvXMLElementExport aElemIteration(*this, XML_NAMESPACE_TABLE, XML_ITERATION, true, true); 3848 } 3849 } 3850 } 3851 } 3852 } 3853 3854 void ScXMLExport::WriteTableSource() 3855 { 3856 uno::Reference <sheet::XSheetLinkable> xLinkable (xCurrentTable, uno::UNO_QUERY); 3857 if (xLinkable.is() && GetModel().is()) 3858 { 3859 sheet::SheetLinkMode nMode (xLinkable->getLinkMode()); 3860 if (nMode != sheet::SheetLinkMode_NONE) 3861 { 3862 OUString sLink (xLinkable->getLinkUrl()); 3863 uno::Reference <beans::XPropertySet> xProps (GetModel(), uno::UNO_QUERY); 3864 if (xProps.is()) 3865 { 3866 uno::Reference <container::XIndexAccess> xIndex(xProps->getPropertyValue(SC_UNO_SHEETLINKS), uno::UNO_QUERY); 3867 if (xIndex.is()) 3868 { 3869 sal_Int32 nCount(xIndex->getCount()); 3870 if (nCount) 3871 { 3872 bool bFound(false); 3873 uno::Reference <beans::XPropertySet> xLinkProps; 3874 for (sal_Int32 i = 0; (i < nCount) && !bFound; ++i) 3875 { 3876 xLinkProps.set(xIndex->getByIndex(i), uno::UNO_QUERY); 3877 if (xLinkProps.is()) 3878 { 3879 OUString sNewLink; 3880 if (xLinkProps->getPropertyValue(SC_UNONAME_LINKURL) >>= sNewLink) 3881 bFound = sLink == sNewLink; 3882 } 3883 } 3884 if (bFound && xLinkProps.is()) 3885 { 3886 OUString sFilter; 3887 OUString sFilterOptions; 3888 OUString sTableName (xLinkable->getLinkSheetName()); 3889 sal_Int32 nRefresh(0); 3890 xLinkProps->getPropertyValue(SC_UNONAME_FILTER) >>= sFilter; 3891 xLinkProps->getPropertyValue(SC_UNONAME_FILTOPT) >>= sFilterOptions; 3892 xLinkProps->getPropertyValue(SC_UNONAME_REFDELAY) >>= nRefresh; 3893 if (!sLink.isEmpty()) 3894 { 3895 AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); 3896 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink)); 3897 if (!sTableName.isEmpty()) 3898 AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName); 3899 if (!sFilter.isEmpty()) 3900 AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, sFilter); 3901 if (!sFilterOptions.isEmpty()) 3902 AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, sFilterOptions); 3903 if (nMode != sheet::SheetLinkMode_NORMAL) 3904 AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY); 3905 if( nRefresh ) 3906 { 3907 OUStringBuffer sBuffer; 3908 ::sax::Converter::convertDuration( sBuffer, 3909 static_cast<double>(nRefresh) / 86400 ); 3910 AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() ); 3911 } 3912 SvXMLElementExport aSourceElem(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, true, true); 3913 } 3914 } 3915 } 3916 } 3917 } 3918 } 3919 } 3920 } 3921 3922 // core implementation 3923 void ScXMLExport::WriteScenario() 3924 { 3925 if (pDoc && pDoc->IsScenario(static_cast<SCTAB>(nCurrentTable))) 3926 { 3927 OUString sComment; 3928 Color aColor; 3929 ScScenarioFlags nFlags; 3930 pDoc->GetScenarioData(static_cast<SCTAB>(nCurrentTable), sComment, aColor, nFlags); 3931 if (!(nFlags & ScScenarioFlags::ShowFrame)) 3932 AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_FALSE); 3933 OUStringBuffer aBuffer; 3934 ::sax::Converter::convertColor(aBuffer, aColor); 3935 AddAttribute(XML_NAMESPACE_TABLE, XML_BORDER_COLOR, aBuffer.makeStringAndClear()); 3936 if (!(nFlags & ScScenarioFlags::TwoWay)) 3937 AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_FALSE); 3938 if (!(nFlags & ScScenarioFlags::Attrib)) 3939 AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_FALSE); 3940 if (nFlags & ScScenarioFlags::Value) 3941 AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_FALSE); 3942 if (nFlags & ScScenarioFlags::Protected) 3943 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE); 3944 ::sax::Converter::convertBool(aBuffer, 3945 pDoc->IsActiveScenario(static_cast<SCTAB>(nCurrentTable))); 3946 AddAttribute(XML_NAMESPACE_TABLE, XML_IS_ACTIVE, aBuffer.makeStringAndClear()); 3947 const ScRangeList* pRangeList = pDoc->GetScenarioRanges(static_cast<SCTAB>(nCurrentTable)); 3948 OUString sRangeListStr; 3949 ScRangeStringConverter::GetStringFromRangeList( sRangeListStr, pRangeList, pDoc, FormulaGrammar::CONV_OOO ); 3950 AddAttribute(XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, sRangeListStr); 3951 if (!sComment.isEmpty()) 3952 AddAttribute(XML_NAMESPACE_TABLE, XML_COMMENT, sComment); 3953 SvXMLElementExport aElem(*this, XML_NAMESPACE_TABLE, XML_SCENARIO, true, true); 3954 } 3955 } 3956 3957 void ScXMLExport::WriteTheLabelRanges( const uno::Reference< sheet::XSpreadsheetDocument >& xSpreadDoc ) 3958 { 3959 uno::Reference< beans::XPropertySet > xDocProp( xSpreadDoc, uno::UNO_QUERY ); 3960 if( !xDocProp.is() ) return; 3961 3962 sal_Int32 nCount(0); 3963 uno::Reference< container::XIndexAccess > xColRangesIAccess(xDocProp->getPropertyValue( SC_UNO_COLLABELRNG ), uno::UNO_QUERY); 3964 if( xColRangesIAccess.is() ) 3965 nCount += xColRangesIAccess->getCount(); 3966 3967 uno::Reference< container::XIndexAccess > xRowRangesIAccess(xDocProp->getPropertyValue( SC_UNO_ROWLABELRNG ), uno::UNO_QUERY); 3968 if( xRowRangesIAccess.is() ) 3969 nCount += xRowRangesIAccess->getCount(); 3970 3971 if( nCount ) 3972 { 3973 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGES, true, true ); 3974 WriteLabelRanges( xColRangesIAccess, true ); 3975 WriteLabelRanges( xRowRangesIAccess, false ); 3976 } 3977 } 3978 3979 void ScXMLExport::WriteLabelRanges( const uno::Reference< container::XIndexAccess >& xRangesIAccess, bool bColumn ) 3980 { 3981 if( !xRangesIAccess.is() ) return; 3982 3983 sal_Int32 nCount(xRangesIAccess->getCount()); 3984 for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) 3985 { 3986 uno::Reference< sheet::XLabelRange > xRange(xRangesIAccess->getByIndex( nIndex ), uno::UNO_QUERY); 3987 if( xRange.is() ) 3988 { 3989 OUString sRangeStr; 3990 table::CellRangeAddress aCellRange( xRange->getLabelArea() ); 3991 ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO ); 3992 AddAttribute( XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, sRangeStr ); 3993 aCellRange = xRange->getDataArea(); 3994 ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO ); 3995 AddAttribute( XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, sRangeStr ); 3996 AddAttribute( XML_NAMESPACE_TABLE, XML_ORIENTATION, bColumn ? XML_COLUMN : XML_ROW ); 3997 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGE, true, true ); 3998 } 3999 } 4000 } 4001 4002 void ScXMLExport::WriteNamedExpressions() 4003 { 4004 if (!pDoc) 4005 return; 4006 ScRangeName* pNamedRanges = pDoc->GetRangeName(); 4007 WriteNamedRange(pNamedRanges); 4008 } 4009 4010 void ScXMLExport::WriteExternalDataMapping() 4011 { 4012 if (!pDoc) 4013 return; 4014 4015 if (getDefaultVersion() <= SvtSaveOptions::ODFVER_012) 4016 // Export this only for 1.2 extended and above. 4017 return; 4018 4019 sc::ExternalDataMapper& rDataMapper = pDoc->GetExternalDataMapper(); 4020 auto& rDataSources = rDataMapper.getDataSources(); 4021 4022 if (!rDataSources.empty()) 4023 { 4024 SvXMLElementExport aMappings(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_MAPPINGS, true, true); 4025 for (const auto& itr : rDataSources) 4026 { 4027 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, itr.getURL()); 4028 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_PROVIDER, itr.getProvider()); 4029 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_DATA_FREQUENCY, OUString::number(sc::ExternalDataSource::getUpdateFrequency())); 4030 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_ID, itr.getID()); 4031 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_DATABASE_NAME, itr.getDBName()); 4032 4033 SvXMLElementExport aMapping(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_MAPPING, true, true); 4034 // Add the data transformations 4035 WriteExternalDataTransformations(itr.getDataTransformation()); 4036 } 4037 } 4038 } 4039 4040 void ScXMLExport::WriteExternalDataTransformations(const std::vector<std::shared_ptr<sc::DataTransformation>>& aDataTransformations) 4041 { 4042 SvXMLElementExport aTransformations(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_TRANSFORMATIONS, true, true); 4043 for (auto& itr : aDataTransformations) 4044 { 4045 sc::TransformationType aTransformationType = itr->getTransformationType(); 4046 4047 switch(aTransformationType) 4048 { 4049 case sc::TransformationType::DELETE_TRANSFORMATION: 4050 { 4051 // Delete Columns Transformation 4052 std::shared_ptr<sc::ColumnRemoveTransformation> aDeleteTransformation = std::dynamic_pointer_cast<sc::ColumnRemoveTransformation>(itr); 4053 std::set<SCCOL> aColumns = aDeleteTransformation->getColumns(); 4054 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_REMOVE_TRANSFORMATION, true, true); 4055 for(auto& col : aColumns) 4056 { 4057 // Add Columns 4058 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); 4059 SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); 4060 } 4061 } 4062 break; 4063 case sc::TransformationType::SPLIT_TRANSFORMATION: 4064 { 4065 std::shared_ptr<sc::SplitColumnTransformation> aSplitTransformation = std::dynamic_pointer_cast<sc::SplitColumnTransformation>(itr); 4066 4067 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(aSplitTransformation->getColumn())); 4068 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_SEPARATOR, OUString::number(aSplitTransformation->getSeparator())); 4069 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_SPLIT_TRANSFORMATION, true, true); 4070 } 4071 break; 4072 case sc::TransformationType::MERGE_TRANSFORMATION: 4073 { 4074 // Merge Transformation 4075 std::shared_ptr<sc::MergeColumnTransformation> aMergeTransformation = std::dynamic_pointer_cast<sc::MergeColumnTransformation>(itr); 4076 std::set<SCCOL> aColumns = aMergeTransformation->getColumns(); 4077 4078 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MERGE_STRING, aMergeTransformation->getMergeString()); 4079 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_MERGE_TRANSFORMATION, true, true); 4080 4081 for(auto& col : aColumns) 4082 { 4083 // Columns 4084 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); 4085 SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); 4086 } 4087 } 4088 break; 4089 case sc::TransformationType::SORT_TRANSFORMATION: 4090 { 4091 // Sort Transformation 4092 std::shared_ptr<sc::SortTransformation> aSortTransformation = std::dynamic_pointer_cast<sc::SortTransformation>(itr); 4093 ScSortParam aSortParam = aSortTransformation->getSortParam(); 4094 const sc::DocumentLinkManager& rMgr = pDoc->GetDocLinkManager(); 4095 const sc::DataStream* pStrm = rMgr.getDataStream(); 4096 if (!pStrm) 4097 // No data stream. 4098 return; 4099 4100 // Streamed range 4101 ScRange aRange = pStrm->GetRange(); 4102 4103 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_SORT_TRANSFORMATION, true, true); 4104 4105 writeSort(*this, aSortParam, aRange, pDoc); 4106 } 4107 break; 4108 case sc::TransformationType::TEXT_TRANSFORMATION: 4109 { 4110 // Text Transformation 4111 std::shared_ptr<sc::TextTransformation> aTextTransformation = std::dynamic_pointer_cast<sc::TextTransformation>(itr); 4112 4113 sc::TEXT_TRANSFORM_TYPE aTextTransformType = aTextTransformation->getTextTransformationType(); 4114 4115 switch ( aTextTransformType ) 4116 { 4117 case sc::TEXT_TRANSFORM_TYPE::TO_LOWER: 4118 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_CASEMAP_LOWERCASE); 4119 break; 4120 case sc::TEXT_TRANSFORM_TYPE::TO_UPPER: 4121 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_CASEMAP_UPPERCASE); 4122 break; 4123 case sc::TEXT_TRANSFORM_TYPE::CAPITALIZE: 4124 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_CASEMAP_CAPITALIZE); 4125 break; 4126 case sc::TEXT_TRANSFORM_TYPE::TRIM: 4127 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_TRIM); 4128 break; 4129 } 4130 4131 std::set<SCCOL> aColumns = aTextTransformation->getColumns(); 4132 4133 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_TEXT_TRANSFORMATION, true, true); 4134 4135 for(auto& col : aColumns) 4136 { 4137 // Columns 4138 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); 4139 SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); 4140 } 4141 } 4142 break; 4143 case sc::TransformationType::AGGREGATE_FUNCTION: 4144 { 4145 // Aggregate Transformation 4146 std::shared_ptr<sc::AggregateFunction> aAggregateFunction = std::dynamic_pointer_cast<sc::AggregateFunction>(itr); 4147 std::set<SCCOL> aColumns = aAggregateFunction->getColumns(); 4148 4149 sc::AGGREGATE_FUNCTION aAggregateType = aAggregateFunction->getAggregateType(); 4150 4151 switch (aAggregateType) 4152 { 4153 case sc::AGGREGATE_FUNCTION::SUM: 4154 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SUM); 4155 break; 4156 case sc::AGGREGATE_FUNCTION::AVERAGE: 4157 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_AVERAGE); 4158 break; 4159 case sc::AGGREGATE_FUNCTION::MIN: 4160 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MIN); 4161 break; 4162 case sc::AGGREGATE_FUNCTION::MAX: 4163 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MAX); 4164 break; 4165 } 4166 4167 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT,XML_COLUMN_AGGREGATE_TRANSFORMATION, true, true); 4168 4169 for(auto& col : aColumns) 4170 { 4171 // Columns 4172 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); 4173 SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); 4174 } 4175 } 4176 break; 4177 case sc::TransformationType::NUMBER_TRANSFORMATION: 4178 { 4179 // Number Transformation 4180 std::shared_ptr<sc::NumberTransformation> aNumberTransformation = std::dynamic_pointer_cast<sc::NumberTransformation>(itr); 4181 4182 sc::NUMBER_TRANSFORM_TYPE aNumberTransformType = aNumberTransformation->getNumberTransformationType(); 4183 4184 switch ( aNumberTransformType ) 4185 { 4186 case sc::NUMBER_TRANSFORM_TYPE::ROUND: 4187 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ROUND); 4188 break; 4189 case sc::NUMBER_TRANSFORM_TYPE::ROUND_UP: 4190 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ROUND_UP); 4191 break; 4192 case sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN: 4193 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ROUND_DOWN); 4194 break; 4195 case sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE: 4196 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ABS); 4197 break; 4198 case sc::NUMBER_TRANSFORM_TYPE::LOG_E: 4199 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_LOG); 4200 break; 4201 case sc::NUMBER_TRANSFORM_TYPE::LOG_10: 4202 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_LOG_10); 4203 break; 4204 case sc::NUMBER_TRANSFORM_TYPE::CUBE: 4205 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_CUBE); 4206 break; 4207 case sc::NUMBER_TRANSFORM_TYPE::SQUARE: 4208 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SQUARE); 4209 break; 4210 case sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT: 4211 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SQUARE_ROOT); 4212 break; 4213 case sc::NUMBER_TRANSFORM_TYPE::EXPONENT: 4214 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_EXPONENTIAL); 4215 break; 4216 case sc::NUMBER_TRANSFORM_TYPE::IS_EVEN: 4217 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_EVEN); 4218 break; 4219 case sc::NUMBER_TRANSFORM_TYPE::IS_ODD: 4220 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_ODD); 4221 break; 4222 case sc::NUMBER_TRANSFORM_TYPE::SIGN: 4223 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SIGN); 4224 break; 4225 } 4226 4227 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_PRECISION, OUString::number(aNumberTransformation->getPrecision())); 4228 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_NUMBER_TRANSFORMATION, true, true); 4229 4230 std::set<SCCOL> aColumns = aNumberTransformation->getColumn(); 4231 for(auto& col : aColumns) 4232 { 4233 // Columns 4234 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); 4235 SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); 4236 } 4237 } 4238 break; 4239 case sc::TransformationType::REMOVE_NULL_TRANSFORMATION: 4240 { 4241 // Replace Null Transformation 4242 std::shared_ptr<sc::ReplaceNullTransformation> aReplaceNullTransformation = std::dynamic_pointer_cast<sc::ReplaceNullTransformation>(itr); 4243 std::set<SCCOL> aColumns = aReplaceNullTransformation->getColumn(); 4244 4245 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_REPLACE_STRING, aReplaceNullTransformation->getReplaceString()); 4246 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_REPLACENULL_TRANSFORMATION, true, true); 4247 4248 for(auto& col : aColumns) 4249 { 4250 // Columns 4251 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); 4252 SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); 4253 } 4254 } 4255 break; 4256 case sc::TransformationType::DATETIME_TRANSFORMATION: 4257 { 4258 // Number Transformation 4259 std::shared_ptr<sc::DateTimeTransformation> aDateTimeTransformation = std::dynamic_pointer_cast<sc::DateTimeTransformation>(itr); 4260 4261 sc::DATETIME_TRANSFORMATION_TYPE aDateTimeTransformationType = aDateTimeTransformation->getDateTimeTransformationType(); 4262 4263 switch ( aDateTimeTransformationType ) 4264 { 4265 case sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING: 4266 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_DATE_STRING); 4267 break; 4268 case sc::DATETIME_TRANSFORMATION_TYPE::YEAR: 4269 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_YEAR); 4270 break; 4271 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR: 4272 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_START_OF_YEAR); 4273 break; 4274 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR: 4275 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_END_OF_YEAR); 4276 break; 4277 case sc::DATETIME_TRANSFORMATION_TYPE::MONTH: 4278 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MONTH); 4279 break; 4280 case sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME: 4281 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MONTH_NAME); 4282 break; 4283 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH: 4284 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_START_OF_MONTH); 4285 break; 4286 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH: 4287 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_END_OF_MONTH); 4288 break; 4289 case sc::DATETIME_TRANSFORMATION_TYPE::DAY: 4290 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_DAY); 4291 break; 4292 case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK: 4293 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_DAY_OF_WEEK); 4294 break; 4295 case sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR: 4296 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_DAY_OF_YEAR); 4297 break; 4298 case sc::DATETIME_TRANSFORMATION_TYPE::QUARTER: 4299 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_QUARTER); 4300 break; 4301 case sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER: 4302 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_START_OF_QUARTER); 4303 break; 4304 case sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER: 4305 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_END_OF_QUARTER); 4306 break; 4307 case sc::DATETIME_TRANSFORMATION_TYPE::TIME: 4308 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_TIME); 4309 break; 4310 case sc::DATETIME_TRANSFORMATION_TYPE::HOUR: 4311 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_HOUR); 4312 break; 4313 case sc::DATETIME_TRANSFORMATION_TYPE::MINUTE: 4314 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_MINUTE); 4315 break; 4316 case sc::DATETIME_TRANSFORMATION_TYPE::SECOND: 4317 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, XML_SECONDS); 4318 break; 4319 } 4320 4321 SvXMLElementExport aTransformation(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN_DATETIME_TRANSFORMATION, true, true); 4322 4323 std::set<SCCOL> aColumns = aDateTimeTransformation->getColumn(); 4324 for(auto& col : aColumns) 4325 { 4326 // Columns 4327 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLUMN, OUString::number(col)); 4328 SvXMLElementExport aCol(*this, XML_NAMESPACE_CALC_EXT, XML_COLUMN, true, true); 4329 } 4330 } 4331 break; 4332 default: 4333 break; 4334 } 4335 } 4336 } 4337 4338 void ScXMLExport::WriteDataStream() 4339 { 4340 if (!pDoc) 4341 return; 4342 4343 SvtMiscOptions aMiscOptions; 4344 if (!aMiscOptions.IsExperimentalMode()) 4345 // Export this only in experimental mode. 4346 return; 4347 4348 if (getDefaultVersion() <= SvtSaveOptions::ODFVER_012) 4349 // Export this only for 1.2 extended and above. 4350 return; 4351 4352 const sc::DocumentLinkManager& rMgr = pDoc->GetDocLinkManager(); 4353 const sc::DataStream* pStrm = rMgr.getDataStream(); 4354 if (!pStrm) 4355 // No data stream. 4356 return; 4357 4358 // Source URL 4359 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(pStrm->GetURL())); 4360 4361 // Streamed range 4362 ScRange aRange = pStrm->GetRange(); 4363 OUString aRangeStr; 4364 ScRangeStringConverter::GetStringFromRange( 4365 aRangeStr, aRange, pDoc, formula::FormulaGrammar::CONV_OOO); 4366 AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aRangeStr); 4367 4368 // Empty line refresh option. 4369 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_EMPTY_LINE_REFRESH, pStrm->IsRefreshOnEmptyLine() ? XML_TRUE : XML_FALSE); 4370 4371 // New data insertion position. Either top of bottom. Default to bottom. 4372 xmloff::token::XMLTokenEnum eInsertPosition = XML_BOTTOM; 4373 if (pStrm->GetMove() == sc::DataStream::MOVE_DOWN) 4374 eInsertPosition = XML_TOP; 4375 4376 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_INSERTION_POSITION, eInsertPosition); 4377 4378 SvXMLElementExport aElem(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_STREAM_SOURCE, true, true); 4379 } 4380 4381 void ScXMLExport::WriteNamedRange(ScRangeName* pRangeName) 4382 { 4383 //write a global or local ScRangeName 4384 SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, true, true); 4385 for (const auto& rxEntry : *pRangeName) 4386 { 4387 AddAttribute(sAttrName, rxEntry.second->GetName()); 4388 4389 OUString sBaseCellAddress; 4390 rxEntry.second->ValidateTabRefs(); 4391 ScRangeStringConverter::GetStringFromAddress( sBaseCellAddress, rxEntry.second->GetPos(), pDoc, 4392 FormulaGrammar::CONV_OOO, ' ', false, ScRefFlags::ADDR_ABS_3D); 4393 AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, sBaseCellAddress); 4394 4395 OUString sSymbol; 4396 rxEntry.second->GetSymbol(sSymbol, pDoc->GetStorageGrammar()); 4397 OUString sTempSymbol(sSymbol); 4398 ScRange aRange; 4399 if (rxEntry.second->IsReference(aRange)) 4400 { 4401 4402 OUString sContent(sTempSymbol.copy(1, sTempSymbol.getLength() -2 )); 4403 AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sContent); 4404 4405 sal_Int32 nRangeType = rxEntry.second->GetUnoType(); 4406 OUStringBuffer sBufferRangeType; 4407 if ((nRangeType & sheet::NamedRangeFlag::COLUMN_HEADER) == sheet::NamedRangeFlag::COLUMN_HEADER) 4408 sBufferRangeType.append(GetXMLToken(XML_REPEAT_COLUMN)); 4409 if ((nRangeType & sheet::NamedRangeFlag::ROW_HEADER) == sheet::NamedRangeFlag::ROW_HEADER) 4410 { 4411 if (!sBufferRangeType.isEmpty()) 4412 sBufferRangeType.append(" "); 4413 sBufferRangeType.append(GetXMLToken(XML_REPEAT_ROW)); 4414 } 4415 if ((nRangeType & sheet::NamedRangeFlag::FILTER_CRITERIA) == sheet::NamedRangeFlag::FILTER_CRITERIA) 4416 { 4417 if (!sBufferRangeType.isEmpty()) 4418 sBufferRangeType.append(" "); 4419 sBufferRangeType.append(GetXMLToken(XML_FILTER)); 4420 } 4421 if ((nRangeType & sheet::NamedRangeFlag::PRINT_AREA) == sheet::NamedRangeFlag::PRINT_AREA) 4422 { 4423 if (!sBufferRangeType.isEmpty()) 4424 sBufferRangeType.append(" "); 4425 sBufferRangeType.append(GetXMLToken(XML_PRINT_RANGE)); 4426 } 4427 OUString sRangeType = sBufferRangeType.makeStringAndClear(); 4428 if (!sRangeType.isEmpty()) 4429 AddAttribute(XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, sRangeType); 4430 SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_RANGE, true, true); 4431 4432 } 4433 else 4434 { 4435 AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, sTempSymbol); 4436 SvXMLElementExport aElemNE(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, true, true); 4437 } 4438 } 4439 } 4440 4441 namespace { 4442 4443 OUString getCondFormatEntryType(const ScColorScaleEntry& rEntry, bool bFirst = true) 4444 { 4445 switch(rEntry.GetType()) 4446 { 4447 case COLORSCALE_MIN: 4448 return "minimum"; 4449 case COLORSCALE_MAX: 4450 return "maximum"; 4451 case COLORSCALE_PERCENT: 4452 return "percent"; 4453 case COLORSCALE_PERCENTILE: 4454 return "percentile"; 4455 case COLORSCALE_FORMULA: 4456 return "formula"; 4457 case COLORSCALE_VALUE: 4458 return "number"; 4459 case COLORSCALE_AUTO: 4460 // only important for data bars 4461 if(bFirst) 4462 return "auto-minimum"; 4463 else 4464 return "auto-maximum"; 4465 } 4466 return OUString(); 4467 } 4468 4469 OUString getDateStringForType(condformat::ScCondFormatDateType eType) 4470 { 4471 switch(eType) 4472 { 4473 case condformat::TODAY: 4474 return "today"; 4475 case condformat::YESTERDAY: 4476 return "yesterday"; 4477 case condformat::TOMORROW: 4478 return "tomorrow"; 4479 case condformat::LAST7DAYS: 4480 return "last-7-days"; 4481 case condformat::THISWEEK: 4482 return "this-week"; 4483 case condformat::LASTWEEK: 4484 return "last-week"; 4485 case condformat::NEXTWEEK: 4486 return "next-week"; 4487 case condformat::THISMONTH: 4488 return "this-month"; 4489 case condformat::LASTMONTH: 4490 return "last-month"; 4491 case condformat::NEXTMONTH: 4492 return "next-month"; 4493 case condformat::THISYEAR: 4494 return "this-year"; 4495 case condformat::LASTYEAR: 4496 return "last-year"; 4497 case condformat::NEXTYEAR: 4498 return "next-year"; 4499 } 4500 4501 return OUString(); 4502 } 4503 4504 } 4505 4506 void ScXMLExport::ExportConditionalFormat(SCTAB nTab) 4507 { 4508 ScConditionalFormatList* pCondFormatList = pDoc->GetCondFormList(nTab); 4509 if(!pCondFormatList) 4510 return; 4511 4512 if (pCondFormatList->empty()) 4513 return; 4514 4515 SvXMLElementExport aElementCondFormats(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITIONAL_FORMATS, true, true); 4516 4517 for(const auto& rxCondFormat : *pCondFormatList) 4518 { 4519 OUString sRanges; 4520 const ScRangeList& rRangeList = rxCondFormat->GetRange(); 4521 ScRangeStringConverter::GetStringFromRangeList( sRanges, &rRangeList, pDoc, formula::FormulaGrammar::CONV_OOO ); 4522 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TARGET_RANGE_ADDRESS, sRanges); 4523 SvXMLElementExport aElementCondFormat(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITIONAL_FORMAT, true, true); 4524 size_t nEntries = rxCondFormat->size(); 4525 for(size_t i = 0; i < nEntries; ++i) 4526 { 4527 const ScFormatEntry* pFormatEntry = rxCondFormat->GetEntry(i); 4528 if(pFormatEntry->GetType()==ScFormatEntry::Type::Condition) 4529 { 4530 const ScCondFormatEntry* pEntry = static_cast<const ScCondFormatEntry*>(pFormatEntry); 4531 OUStringBuffer aCond; 4532 ScAddress aPos = pEntry->GetSrcPos(); 4533 switch(pEntry->GetOperation()) 4534 { 4535 case ScConditionMode::Equal: 4536 aCond.append('='); 4537 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4538 break; 4539 case ScConditionMode::Less: 4540 aCond.append('<'); 4541 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4542 break; 4543 case ScConditionMode::Greater: 4544 aCond.append('>'); 4545 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4546 break; 4547 case ScConditionMode::EqLess: 4548 aCond.append("<="); 4549 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4550 break; 4551 case ScConditionMode::EqGreater: 4552 aCond.append(">="); 4553 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4554 break; 4555 case ScConditionMode::NotEqual: 4556 aCond.append("!="); 4557 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4558 break; 4559 case ScConditionMode::Between: 4560 aCond.append("between("); 4561 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4562 aCond.append(','); 4563 aCond.append(pEntry->GetExpression(aPos, 1, 0, formula::FormulaGrammar::GRAM_ODFF)); 4564 aCond.append(')'); 4565 break; 4566 case ScConditionMode::NotBetween: 4567 aCond.append("not-between("); 4568 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4569 aCond.append(','); 4570 aCond.append(pEntry->GetExpression(aPos, 1, 0, formula::FormulaGrammar::GRAM_ODFF)); 4571 aCond.append(')'); 4572 break; 4573 case ScConditionMode::Duplicate: 4574 aCond.append("duplicate"); 4575 break; 4576 case ScConditionMode::NotDuplicate: 4577 aCond.append("unique"); 4578 break; 4579 case ScConditionMode::Direct: 4580 aCond.append("formula-is("); 4581 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4582 aCond.append(')'); 4583 break; 4584 case ScConditionMode::Top10: 4585 aCond.append("top-elements("); 4586 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4587 aCond.append(")"); 4588 break; 4589 case ScConditionMode::Bottom10: 4590 aCond.append("bottom-elements("); 4591 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4592 aCond.append(")"); 4593 break; 4594 case ScConditionMode::TopPercent: 4595 aCond.append("top-percent("); 4596 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4597 aCond.append(")"); 4598 break; 4599 case ScConditionMode::BottomPercent: 4600 aCond.append("bottom-percent("); 4601 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4602 aCond.append(")"); 4603 break; 4604 case ScConditionMode::AboveAverage: 4605 aCond.append("above-average"); 4606 break; 4607 case ScConditionMode::BelowAverage: 4608 aCond.append("below-average"); 4609 break; 4610 case ScConditionMode::AboveEqualAverage: 4611 aCond.append("above-equal-average"); 4612 break; 4613 case ScConditionMode::BelowEqualAverage: 4614 aCond.append("below-equal-average"); 4615 break; 4616 case ScConditionMode::Error: 4617 aCond.append("is-error"); 4618 break; 4619 case ScConditionMode::NoError: 4620 aCond.append("is-no-error"); 4621 break; 4622 case ScConditionMode::BeginsWith: 4623 aCond.append("begins-with("); 4624 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4625 aCond.append(")"); 4626 break; 4627 case ScConditionMode::EndsWith: 4628 aCond.append("ends-with("); 4629 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4630 aCond.append(")"); 4631 break; 4632 case ScConditionMode::ContainsText: 4633 aCond.append("contains-text("); 4634 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4635 aCond.append(")"); 4636 break; 4637 case ScConditionMode::NotContainsText: 4638 aCond.append("not-contains-text("); 4639 aCond.append(pEntry->GetExpression(aPos, 0, 0, formula::FormulaGrammar::GRAM_ODFF)); 4640 aCond.append(")"); 4641 break; 4642 case ScConditionMode::NONE: 4643 continue; 4644 default: 4645 SAL_WARN("sc", "unimplemented conditional format export"); 4646 } 4647 OUString sStyle = ScStyleNameConversion::DisplayToProgrammaticName(pEntry->GetStyle(), SfxStyleFamily::Para); 4648 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_APPLY_STYLE_NAME, sStyle); 4649 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, aCond.makeStringAndClear()); 4650 4651 OUString sBaseAddress; 4652 ScRangeStringConverter::GetStringFromAddress( sBaseAddress, aPos, pDoc,formula::FormulaGrammar::CONV_ODF ); 4653 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_BASE_CELL_ADDRESS, sBaseAddress); 4654 SvXMLElementExport aElementCondEntry(*this, XML_NAMESPACE_CALC_EXT, XML_CONDITION, true, true); 4655 } 4656 else if(pFormatEntry->GetType() == ScFormatEntry::Type::Colorscale) 4657 { 4658 SvXMLElementExport aElementColorScale(*this, XML_NAMESPACE_CALC_EXT, XML_COLOR_SCALE, true, true); 4659 const ScColorScaleFormat& rColorScale = static_cast<const ScColorScaleFormat&>(*pFormatEntry); 4660 for(const auto& rxItem : rColorScale) 4661 { 4662 if(rxItem->GetType() == COLORSCALE_FORMULA) 4663 { 4664 OUString sFormula = rxItem->GetFormula(formula::FormulaGrammar::GRAM_ODFF); 4665 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula); 4666 } 4667 else 4668 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(rxItem->GetValue())); 4669 4670 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*rxItem)); 4671 OUStringBuffer aBuffer; 4672 ::sax::Converter::convertColor(aBuffer, rxItem->GetColor()); 4673 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_COLOR, aBuffer.makeStringAndClear()); 4674 SvXMLElementExport aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT, XML_COLOR_SCALE_ENTRY, true, true); 4675 } 4676 } 4677 else if(pFormatEntry->GetType() == ScFormatEntry::Type::Databar) 4678 { 4679 const ScDataBarFormatData* pFormatData = static_cast<const ScDataBarFormat&>(*pFormatEntry).GetDataBarData(); 4680 if(!pFormatData->mbGradient) 4681 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_GRADIENT, XML_FALSE); 4682 if(pFormatData->mbOnlyBar) 4683 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_SHOW_VALUE, XML_FALSE); 4684 4685 if (pFormatData->mnMinLength != 0.0) 4686 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MIN_LENGTH, OUString::number(pFormatData->mnMinLength)); 4687 4688 if (pFormatData->mnMaxLength != 0.0) 4689 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MAX_LENGTH, OUString::number(pFormatData->mnMaxLength)); 4690 4691 if(pFormatData->mbNeg) 4692 { 4693 if(pFormatData->mpNegativeColor) 4694 { 4695 OUStringBuffer aBuffer; 4696 ::sax::Converter::convertColor(aBuffer, *pFormatData->mpNegativeColor); 4697 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_NEGATIVE_COLOR, aBuffer.makeStringAndClear()); 4698 } 4699 else 4700 { 4701 OUStringBuffer aBuffer; 4702 ::sax::Converter::convertColor(aBuffer, COL_LIGHTRED); 4703 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_NEGATIVE_COLOR, aBuffer.makeStringAndClear()); 4704 } 4705 } 4706 4707 if(pFormatData->meAxisPosition != databar::AUTOMATIC) 4708 { 4709 if(pFormatData->meAxisPosition == databar::NONE) 4710 { 4711 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_POSITION, OUString("none")); 4712 } 4713 else 4714 { 4715 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_POSITION, OUString("middle")); 4716 } 4717 } 4718 4719 OUStringBuffer aBuffer; 4720 ::sax::Converter::convertColor(aBuffer, pFormatData->maPositiveColor); 4721 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_POSITIVE_COLOR, aBuffer.makeStringAndClear()); 4722 4723 aBuffer.truncate(); 4724 ::sax::Converter::convertColor(aBuffer, pFormatData->maAxisColor); 4725 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_AXIS_COLOR, aBuffer.makeStringAndClear()); 4726 SvXMLElementExport aElementDataBar(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_BAR, true, true); 4727 4728 { 4729 if(pFormatData->mpLowerLimit->GetType() == COLORSCALE_FORMULA) 4730 { 4731 OUString sFormula = pFormatData->mpLowerLimit->GetFormula(formula::FormulaGrammar::GRAM_ODFF); 4732 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula); 4733 } 4734 else 4735 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(pFormatData->mpLowerLimit->GetValue())); 4736 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*pFormatData->mpLowerLimit)); 4737 SvXMLElementExport aElementDataBarEntryLower(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true); 4738 } 4739 4740 { 4741 if(pFormatData->mpUpperLimit->GetType() == COLORSCALE_FORMULA) 4742 { 4743 OUString sFormula = pFormatData->mpUpperLimit->GetFormula(formula::FormulaGrammar::GRAM_ODFF); 4744 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula); 4745 } 4746 else 4747 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(pFormatData->mpUpperLimit->GetValue())); 4748 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*pFormatData->mpUpperLimit, false)); 4749 SvXMLElementExport aElementDataBarEntryUpper(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true); 4750 } 4751 } 4752 else if(pFormatEntry->GetType() == ScFormatEntry::Type::Iconset) 4753 { 4754 const ScIconSetFormat& rIconSet = static_cast<const ScIconSetFormat&>(*pFormatEntry); 4755 OUString aIconSetName = OUString::createFromAscii(ScIconSetFormat::getIconSetName(rIconSet.GetIconSetData()->eIconSetType)); 4756 AddAttribute( XML_NAMESPACE_CALC_EXT, XML_ICON_SET_TYPE, aIconSetName ); 4757 if (rIconSet.GetIconSetData()->mbCustom) 4758 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_CUSTOM, OUString::boolean(true)); 4759 4760 SvXMLElementExport aElementColorScale(*this, XML_NAMESPACE_CALC_EXT, XML_ICON_SET, true, true); 4761 4762 if (rIconSet.GetIconSetData()->mbCustom) 4763 { 4764 for (const auto& [rType, rIndex] : rIconSet.GetIconSetData()->maCustomVector) 4765 { 4766 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_CUSTOM_ICONSET_NAME, OUString::createFromAscii(ScIconSetFormat::getIconSetName(rType))); 4767 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_CUSTOM_ICONSET_INDEX, OUString::number(rIndex)); 4768 SvXMLElementExport aCustomIcon(*this, XML_NAMESPACE_CALC_EXT, XML_CUSTOM_ICONSET, true, true); 4769 } 4770 4771 } 4772 4773 if(!rIconSet.GetIconSetData()->mbShowValue) 4774 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_SHOW_VALUE, XML_FALSE); 4775 for (auto const& it : rIconSet) 4776 { 4777 if(it->GetType() == COLORSCALE_FORMULA) 4778 { 4779 OUString sFormula = it->GetFormula(formula::FormulaGrammar::GRAM_ODFF); 4780 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, sFormula); 4781 } 4782 else 4783 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_VALUE, OUString::number(it->GetValue())); 4784 4785 AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, getCondFormatEntryType(*it)); 4786 SvXMLElementExport aElementColorScaleEntry(*this, XML_NAMESPACE_CALC_EXT, XML_FORMATTING_ENTRY, true, true); 4787 } 4788 } 4789 else if(pFormatEntry->GetType() == ScFormatEntry::Type::Date) 4790 { 4791 const ScCondDateFormatEntry& rDateFormat = static_cast<const ScCondDateFormatEntry&>(*pFormatEntry); 4792 OUString aDateType = getDateStringForType(rDateFormat.GetDateType()); 4793 OUString aStyleName = ScStyleNameConversion::DisplayToProgrammaticName(rDateFormat.GetStyleName(), SfxStyleFamily::Para ); 4794 AddAttribute( XML_NAMESPACE_CALC_EXT, XML_STYLE, aStyleName); 4795 AddAttribute( XML_NAMESPACE_CALC_EXT, XML_DATE, aDateType); 4796 SvXMLElementExport aElementDateFormat(*this, XML_NAMESPACE_CALC_EXT, XML_DATE_IS, true, true); 4797 } 4798 } 4799 } 4800 } 4801 4802 void ScXMLExport::WriteExternalRefCaches() 4803 { 4804 if (!pDoc) 4805 return; 4806 4807 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); 4808 pRefMgr->resetSrcFileData(GetOrigFileName()); 4809 sal_uInt16 nCount = pRefMgr->getExternalFileCount(); 4810 for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId) 4811 { 4812 const OUString* pUrl = pRefMgr->getExternalFileName(nFileId); 4813 if (!pUrl) 4814 continue; 4815 4816 vector<OUString> aTabNames; 4817 pRefMgr->getAllCachedTableNames(nFileId, aTabNames); 4818 if (aTabNames.empty()) 4819 continue; 4820 4821 for (const auto& rTabName : aTabNames) 4822 { 4823 ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, rTabName, false); 4824 if (!pTable.get() || !pTable->isReferenced()) 4825 continue; 4826 4827 AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, "'" + *pUrl + "'#" + rTabName); 4828 AddAttribute(XML_NAMESPACE_TABLE, XML_PRINT, GetXMLToken(XML_FALSE)); 4829 AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sExternalRefTabStyleName); 4830 SvXMLElementExport aElemTable(*this, XML_NAMESPACE_TABLE, XML_TABLE, true, true); 4831 { 4832 const ScExternalRefManager::SrcFileData* pExtFileData = pRefMgr->getExternalFileData(nFileId); 4833 if (pExtFileData) 4834 { 4835 OUString aRelUrl; 4836 if (!pExtFileData->maRelativeName.isEmpty()) 4837 aRelUrl = pExtFileData->maRelativeName; 4838 else 4839 aRelUrl = GetRelativeReference(pExtFileData->maRelativeName); 4840 AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); 4841 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl); 4842 AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, rTabName); 4843 if (!pExtFileData->maFilterName.isEmpty()) 4844 AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, pExtFileData->maFilterName); 4845 if (!pExtFileData->maFilterOptions.isEmpty()) 4846 AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, pExtFileData->maFilterOptions); 4847 AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY); 4848 } 4849 SvXMLElementExport aElemTableSource(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, true, true); 4850 } 4851 4852 // Determine maximum column count of used area, for repeated cells. 4853 SCCOL nMaxColsUsed = 1; // assume that there is at least one cell somewhere... 4854 vector<SCROW> aRows; 4855 pTable->getAllRows(aRows); 4856 for (SCROW nRow : aRows) 4857 { 4858 vector<SCCOL> aCols; 4859 pTable->getAllCols(nRow, aCols); 4860 if (!aCols.empty()) 4861 { 4862 SCCOL nCol = aCols.back(); 4863 if (nMaxColsUsed <= nCol) 4864 nMaxColsUsed = nCol + 1; 4865 } 4866 } 4867 4868 // Column definitions have to be present to make a valid file 4869 { 4870 if (nMaxColsUsed > 1) 4871 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, 4872 OUString::number(nMaxColsUsed)); 4873 SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, true, true); 4874 } 4875 4876 // Write cache content for this table. 4877 SCROW nLastRow = 0; 4878 bool bFirstRow = true; 4879 for (SCROW nRow : aRows) 4880 { 4881 if (bFirstRow) 4882 { 4883 if (nRow > 0) 4884 { 4885 if (nRow > 1) 4886 { 4887 OUStringBuffer aVal; 4888 aVal.append(nRow); 4889 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear()); 4890 } 4891 SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true); 4892 OUStringBuffer aVal; 4893 aVal.append(static_cast<sal_Int32>(nMaxColsUsed)); 4894 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear()); 4895 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); 4896 } 4897 } 4898 else 4899 { 4900 SCROW nRowGap = nRow - nLastRow; 4901 if (nRowGap > 1) 4902 { 4903 if (nRowGap > 2) 4904 { 4905 OUStringBuffer aVal; 4906 aVal.append(static_cast<sal_Int32>(nRowGap-1)); 4907 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear()); 4908 } 4909 SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true); 4910 OUStringBuffer aVal; 4911 aVal.append(static_cast<sal_Int32>(nMaxColsUsed)); 4912 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear()); 4913 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); 4914 } 4915 } 4916 SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true); 4917 4918 vector<SCCOL> aCols; 4919 pTable->getAllCols(nRow, aCols); 4920 SCCOL nLastCol = 0; 4921 bool bFirstCol = true; 4922 for (SCCOL nCol : aCols) 4923 { 4924 if (bFirstCol) 4925 { 4926 if (nCol > 0) 4927 { 4928 if (nCol > 1) 4929 { 4930 OUStringBuffer aVal; 4931 aVal.append(static_cast<sal_Int32>(nCol)); 4932 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear()); 4933 } 4934 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); 4935 } 4936 } 4937 else 4938 { 4939 SCCOL nColGap = nCol - nLastCol; 4940 if (nColGap > 1) 4941 { 4942 if (nColGap > 2) 4943 { 4944 OUStringBuffer aVal; 4945 aVal.append(static_cast<sal_Int32>(nColGap-1)); 4946 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear()); 4947 } 4948 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); 4949 } 4950 } 4951 4952 // Write out this cell. 4953 sal_uInt32 nNumFmt = 0; 4954 ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow, &nNumFmt); 4955 OUString aStrVal; 4956 if (pToken.get()) 4957 { 4958 sal_Int32 nIndex = GetNumberFormatStyleIndex(nNumFmt); 4959 if (nIndex >= 0) 4960 { 4961 const OUString & aStyleName = pCellStyles->GetStyleNameByIndex(nIndex, true); 4962 AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, aStyleName); 4963 } 4964 4965 switch(pToken->GetType()) 4966 { 4967 case svDouble: 4968 { 4969 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT); 4970 OUStringBuffer aVal; 4971 aVal.append(pToken->GetDouble()); 4972 aStrVal = aVal.makeStringAndClear(); 4973 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aStrVal); 4974 } 4975 break; 4976 case svString: 4977 { 4978 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING); 4979 aStrVal = pToken->GetString().getString(); 4980 } 4981 break; 4982 default: 4983 ; 4984 } 4985 } 4986 SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); 4987 SvXMLElementExport aElemText(*this, XML_NAMESPACE_TEXT, XML_P, true, false); 4988 Characters(aStrVal); 4989 4990 nLastCol = nCol; 4991 bFirstCol = false; 4992 } 4993 nLastRow = nRow; 4994 bFirstRow = false; 4995 } 4996 } 4997 } 4998 } 4999 5000 // core implementation 5001 void ScXMLExport::WriteConsolidation() 5002 { 5003 if (pDoc) 5004 { 5005 const ScConsolidateParam* pCons(pDoc->GetConsolidateDlgData()); 5006 if( pCons ) 5007 { 5008 OUString sStrData; 5009 5010 ScXMLConverter::GetStringFromFunction( sStrData, pCons->eFunction ); 5011 AddAttribute( XML_NAMESPACE_TABLE, XML_FUNCTION, sStrData ); 5012 5013 sStrData.clear(); 5014 for( sal_Int32 nIndex = 0; nIndex < pCons->nDataAreaCount; ++nIndex ) 5015 ScRangeStringConverter::GetStringFromArea( sStrData, pCons->pDataAreas[ nIndex ], pDoc, FormulaGrammar::CONV_OOO, ' ', true ); 5016 AddAttribute( XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, sStrData ); 5017 5018 ScRangeStringConverter::GetStringFromAddress( sStrData, ScAddress( pCons->nCol, pCons->nRow, pCons->nTab ), pDoc, FormulaGrammar::CONV_OOO ); 5019 AddAttribute( XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, sStrData ); 5020 5021 if( pCons->bByCol && !pCons->bByRow ) 5022 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_COLUMN ); 5023 else if( !pCons->bByCol && pCons->bByRow ) 5024 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_ROW ); 5025 else if( pCons->bByCol && pCons->bByRow ) 5026 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_BOTH ); 5027 5028 if( pCons->bReferenceData ) 5029 AddAttribute( XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TRUE ); 5030 5031 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CONSOLIDATION, true, true ); 5032 } 5033 } 5034 } 5035 5036 SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool() 5037 { 5038 return new ScXMLAutoStylePoolP(*this); 5039 } 5040 5041 XMLPageExport* ScXMLExport::CreatePageExport() 5042 { 5043 return new XMLTableMasterPageExport( *this ); 5044 } 5045 5046 void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue>& rProps) 5047 { 5048 ScChangeViewSettings* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : nullptr); 5049 if (pViewSettings) 5050 { 5051 sal_Int32 nChangePos(rProps.getLength()); 5052 rProps.realloc(nChangePos + 1); 5053 beans::PropertyValue* pProps(rProps.getArray()); 5054 5055 uno::Sequence<beans::PropertyValue> aChangeProps(SC_VIEWCHANGES_COUNT); 5056 beans::PropertyValue* pChangeProps(aChangeProps.getArray()); 5057 pChangeProps[SC_SHOW_CHANGES].Name = "ShowChanges"; 5058 pChangeProps[SC_SHOW_CHANGES].Value <<= pViewSettings->ShowChanges(); 5059 pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Name = "ShowAcceptedChanges"; 5060 pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Value <<= pViewSettings->IsShowAccepted(); 5061 pChangeProps[SC_SHOW_REJECTED_CHANGES].Name = "ShowRejectedChanges"; 5062 pChangeProps[SC_SHOW_REJECTED_CHANGES].Value <<= pViewSettings->IsShowRejected(); 5063 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Name = "ShowChangesByDatetime"; 5064 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Value <<= pViewSettings->HasDate(); 5065 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Name = "ShowChangesByDatetimeMode"; 5066 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Value <<= static_cast<sal_Int16>(pViewSettings->GetTheDateMode()); 5067 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Name = "ShowChangesByDatetimeFirstDatetime"; 5068 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Value <<= pViewSettings->GetTheFirstDateTime().GetUNODateTime(); 5069 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Name = "ShowChangesByDatetimeSecondDatetime"; 5070 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Value <<= pViewSettings->GetTheLastDateTime().GetUNODateTime(); 5071 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Name = "ShowChangesByAuthor"; 5072 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Value <<= pViewSettings->HasAuthor(); 5073 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Name = "ShowChangesByAuthorName"; 5074 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Value <<= pViewSettings->GetTheAuthorToShow(); 5075 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Name = "ShowChangesByComment"; 5076 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Value <<= pViewSettings->HasComment(); 5077 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Name = "ShowChangesByCommentText"; 5078 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Value <<= pViewSettings->GetTheComment(); 5079 pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Name = "ShowChangesByRanges"; 5080 pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Value <<= pViewSettings->HasRange(); 5081 OUString sRangeList; 5082 ScRangeStringConverter::GetStringFromRangeList(sRangeList, &(pViewSettings->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO); 5083 pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Name = "ShowChangesByRangesList"; 5084 pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Value <<= sRangeList; 5085 5086 pProps[nChangePos].Name = "TrackedChangesViewSettings"; 5087 pProps[nChangePos].Value <<= aChangeProps; 5088 } 5089 } 5090 5091 void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps) 5092 { 5093 if (GetModel().is()) 5094 { 5095 rProps.realloc(4); 5096 beans::PropertyValue* pProps(rProps.getArray()); 5097 ScModelObj* pDocObj(comphelper::getUnoTunnelImplementation<ScModelObj>( GetModel() )); 5098 if (pDocObj) 5099 { 5100 SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject(); 5101 if (pEmbeddedObj) 5102 { 5103 tools::Rectangle aRect(pEmbeddedObj->GetVisArea()); 5104 sal_uInt16 i(0); 5105 pProps[i].Name = "VisibleAreaTop"; 5106 pProps[i].Value <<= static_cast<sal_Int32>(aRect.getY()); 5107 pProps[++i].Name = "VisibleAreaLeft"; 5108 pProps[i].Value <<= static_cast<sal_Int32>(aRect.getX()); 5109 pProps[++i].Name = "VisibleAreaWidth"; 5110 pProps[i].Value <<= static_cast<sal_Int32>(aRect.getWidth()); 5111 pProps[++i].Name = "VisibleAreaHeight"; 5112 pProps[i].Value <<= static_cast<sal_Int32>(aRect.getHeight()); 5113 } 5114 } 5115 } 5116 GetChangeTrackViewSettings(rProps); 5117 } 5118 5119 void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps) 5120 { 5121 if (GetModel().is()) 5122 { 5123 uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); 5124 if (xMultiServiceFactory.is()) 5125 { 5126 uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance("com.sun.star.comp.SpreadsheetSettings"), uno::UNO_QUERY); 5127 if (xProperties.is()) 5128 SvXMLUnitConverter::convertPropertySet(rProps, xProperties); 5129 5130 sal_Int32 nPropsToAdd = 0; 5131 OUStringBuffer aTrackedChangesKey; 5132 if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected()) 5133 { 5134 ::comphelper::Base64::encode(aTrackedChangesKey, 5135 GetDocument()->GetChangeTrack()->GetProtection()); 5136 if (!aTrackedChangesKey.isEmpty()) 5137 ++nPropsToAdd; 5138 } 5139 5140 bool bVBACompat = false; 5141 uno::Reference <container::XNameAccess> xCodeNameAccess; 5142 OSL_ENSURE( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" ); 5143 if( pDoc && pDoc->IsInVBAMode() ) 5144 { 5145 // VBA compatibility mode 5146 bVBACompat = true; 5147 ++nPropsToAdd; 5148 // code names 5149 xCodeNameAccess = new XMLCodeNameProvider( pDoc ); 5150 if( xCodeNameAccess->hasElements() ) 5151 ++nPropsToAdd; 5152 else 5153 xCodeNameAccess.clear(); 5154 } 5155 5156 if( nPropsToAdd > 0 ) 5157 { 5158 sal_Int32 nCount(rProps.getLength()); 5159 rProps.realloc(nCount + nPropsToAdd); 5160 if (!aTrackedChangesKey.isEmpty()) 5161 { 5162 rProps[nCount].Name = "TrackedChangesProtectionKey"; 5163 rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear(); 5164 ++nCount; 5165 } 5166 if( bVBACompat ) 5167 { 5168 rProps[nCount].Name = "VBACompatibilityMode"; 5169 rProps[nCount].Value <<= bVBACompat; 5170 ++nCount; 5171 } 5172 if( xCodeNameAccess.is() ) 5173 { 5174 rProps[nCount].Name = "ScriptConfiguration"; 5175 rProps[nCount].Value <<= xCodeNameAccess; 5176 ++nCount; 5177 } 5178 } 5179 } 5180 } 5181 } 5182 5183 XMLShapeExport* ScXMLExport::CreateShapeExport() 5184 { 5185 return new ScXMLShapeExport(*this); 5186 } 5187 5188 XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper() 5189 { 5190 if (!pNumberFormatAttributesExportHelper) 5191 pNumberFormatAttributesExportHelper.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this )); 5192 return pNumberFormatAttributesExportHelper.get(); 5193 } 5194 5195 void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib) 5196 { 5197 for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib)) 5198 { 5199 const SvXMLAttrContainerItem *pUnknown(static_cast<const SvXMLAttrContainerItem *>(pItem)); 5200 if( pUnknown->GetAttrCount() > 0 ) 5201 { 5202 sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex()); 5203 while( USHRT_MAX != nIdx ) 5204 { 5205 if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 ) 5206 { 5207 const OUString& rPrefix = pUnknown->GetPrefix( nIdx ); 5208 // Add namespace declaration for unknown attributes if 5209 // there aren't existing ones for the prefix used by the 5210 // attributes 5211 GetNamespaceMap_().Add( rPrefix, 5212 pUnknown->GetNamespace( nIdx ) ); 5213 } 5214 nIdx = pUnknown->GetNextNamespaceIndex( nIdx ); 5215 } 5216 } 5217 } 5218 5219 // #i66550# needed for 'presentation:event-listener' element for URLs in shapes 5220 GetNamespaceMap_().Add( 5221 GetXMLToken( XML_NP_PRESENTATION ), 5222 GetXMLToken( XML_N_PRESENTATION ), 5223 XML_NAMESPACE_PRESENTATION ); 5224 } 5225 5226 void ScXMLExport::IncrementProgressBar(bool bFlush, sal_Int32 nInc) 5227 { 5228 nProgressCount += nInc; 5229 if (bFlush || nProgressCount > 100) 5230 { 5231 GetProgressBarHelper()->Increment(nProgressCount); 5232 nProgressCount = 0; 5233 } 5234 } 5235 5236 ErrCode ScXMLExport::exportDoc( enum XMLTokenEnum eClass ) 5237 { 5238 if( getExportFlags() & (SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::STYLES| 5239 SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) 5240 { 5241 if (GetDocument()) 5242 { 5243 // if source doc was Excel then 5244 uno::Reference< frame::XModel > xModel = GetModel(); 5245 if ( xModel.is() ) 5246 { 5247 uno::Reference< lang::XUnoTunnel > xObjShellTunnel( xModel, uno::UNO_QUERY ); 5248 SfxObjectShell* pFoundShell = reinterpret_cast<SfxObjectShell*>( xObjShellTunnel.is() ? xObjShellTunnel->getSomething(SfxObjectShell::getUnoTunnelId()) : 0 ); 5249 if ( pFoundShell && ooo::vba::isAlienExcelDoc( *pFoundShell ) ) 5250 { 5251 xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScFromXLSRowStylesProperties, xScPropHdlFactory, true); 5252 xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper); 5253 GetAutoStylePool()->SetFamilyPropSetMapper( XML_STYLE_FAMILY_TABLE_ROW, 5254 xRowStylesExportPropertySetMapper ); 5255 } 5256 } 5257 CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF); 5258 CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS); 5259 CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS); 5260 ScDrawLayer* pDrawLayer = GetDocument()->GetDrawLayer(); 5261 if (pDrawLayer) 5262 { 5263 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_PARA_XMLATTRIBS); 5264 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS); 5265 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES); 5266 } 5267 5268 // sheet events use officeooo namespace 5269 if( (getExportFlags() & SvXMLExportFlags::CONTENT) && 5270 getDefaultVersion() >= SvtSaveOptions::ODFVER_012 ) 5271 { 5272 bool bAnySheetEvents = false; 5273 SCTAB nTabCount = pDoc->GetTableCount(); 5274 for (SCTAB nTab=0; nTab<nTabCount; ++nTab) 5275 if (pDoc->GetSheetEvents(nTab)) 5276 bAnySheetEvents = true; 5277 if (bAnySheetEvents) 5278 GetNamespaceMap_().Add( 5279 GetXMLToken( XML_NP_OFFICE_EXT ), 5280 GetXMLToken( XML_N_OFFICE_EXT ), 5281 XML_NAMESPACE_OFFICE_EXT ); 5282 } 5283 } 5284 } 5285 return SvXMLExport::exportDoc( eClass ); 5286 } 5287 5288 // XExporter 5289 void SAL_CALL ScXMLExport::setSourceDocument( const uno::Reference<lang::XComponent>& xComponent ) 5290 { 5291 SolarMutexGuard aGuard; 5292 SvXMLExport::setSourceDocument( xComponent ); 5293 5294 pDoc = ScXMLConverter::GetScDocument( GetModel() ); 5295 OSL_ENSURE( pDoc, "ScXMLExport::setSourceDocument - no ScDocument!" ); 5296 if (!pDoc) 5297 throw lang::IllegalArgumentException(); 5298 5299 // create ScChangeTrackingExportHelper after document is known 5300 pChangeTrackingExportHelper.reset(new ScChangeTrackingExportHelper(*this)); 5301 5302 // Set the document's storage grammar corresponding to the ODF version that 5303 // is to be written. 5304 SvtSaveOptions::ODFDefaultVersion meODFDefaultVersion = getDefaultVersion(); 5305 switch (meODFDefaultVersion) 5306 { 5307 // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF 5308 case SvtSaveOptions::ODFVER_010: 5309 case SvtSaveOptions::ODFVER_011: 5310 pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF); 5311 break; 5312 default: 5313 pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF); 5314 } 5315 } 5316 5317 // XFilter 5318 sal_Bool SAL_CALL ScXMLExport::filter( const css::uno::Sequence< css::beans::PropertyValue >& aDescriptor ) 5319 { 5320 SolarMutexGuard aGuard; 5321 if (pDoc) 5322 pDoc->EnableIdle(false); 5323 bool bReturn(SvXMLExport::filter(aDescriptor)); 5324 if (pDoc) 5325 pDoc->EnableIdle(true); 5326 return bReturn; 5327 } 5328 5329 void SAL_CALL ScXMLExport::cancel() 5330 { 5331 SolarMutexGuard aGuard; 5332 if (pDoc) 5333 pDoc->EnableIdle(true); 5334 SvXMLExport::cancel(); 5335 } 5336 5337 // XInitialization 5338 void SAL_CALL ScXMLExport::initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) 5339 { 5340 SolarMutexGuard aGuard; 5341 SvXMLExport::initialize(aArguments); 5342 } 5343 5344 // XUnoTunnel 5345 sal_Int64 SAL_CALL ScXMLExport::getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) 5346 { 5347 SolarMutexGuard aGuard; 5348 return SvXMLExport::getSomething(aIdentifier); 5349 } 5350 5351 void ScXMLExport::DisposingModel() 5352 { 5353 SvXMLExport::DisposingModel(); 5354 pDoc = nullptr; 5355 xCurrentTable = nullptr; 5356 } 5357 5358 void ScXMLExport::SetSharedData(std::unique_ptr<ScMySharedData> pTemp) { pSharedData = std::move(pTemp); } 5359 5360 std::unique_ptr<ScMySharedData> ScXMLExport::ReleaseSharedData() { return std::move(pSharedData); } 5361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 5362
