blob: 6289d6fddcbcc50b4eea0598c8221c824fa46b3b [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
// INCLUDE ---------------------------------------------------------------
#include <editeng/eeitem.hxx>
#include "xmlexprt.hxx"
#include "XMLConverter.hxx"
#include "xmlstyle.hxx"
#include "unonames.hxx"
#include "document.hxx"
#include "olinetab.hxx"
#include "cellsuno.hxx"
#include "cell.hxx"
#include "rangenam.hxx"
#include "XMLTableMasterPageExport.hxx"
#include "drwlayer.hxx"
#include "XMLExportDataPilot.hxx"
#include "XMLExportDatabaseRanges.hxx"
#include "XMLExportDDELinks.hxx"
#include "XMLExportIterator.hxx"
#include "XMLColumnRowGroupExport.hxx"
#include "XMLStylesExportHelper.hxx"
#include "XMLChangeTrackingExportHelper.hxx"
#include "sheetdata.hxx"
#include "docoptio.hxx"
#include "XMLExportSharedData.hxx"
#include "chgviset.hxx"
#include "docuno.hxx"
#include "textuno.hxx"
#include "chartlis.hxx"
#include "unoguard.hxx"
#include "scitems.hxx"
#include "docpool.hxx"
#include "userdat.hxx"
#include "dociter.hxx"
#include "chgtrack.hxx"
#include "rangeutl.hxx"
#include "convuno.hxx"
#include "postit.hxx"
#include "externalrefmgr.hxx"
#include "editutil.hxx"
#include "tabprotection.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlnmspe.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/families.hxx>
#include <xmloff/numehelp.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/txtparae.hxx>
#include <xmloff/xmlcnitm.hxx>
#include <xmloff/xmlerror.hxx>
#include <xmloff/XMLEventExport.hxx>
#include <rtl/ustring.hxx>
#include <tools/debug.hxx>
#include "tools/color.hxx"
#include <rtl/math.hxx>
#include <svl/zforlist.hxx>
#include <svx/unoshape.hxx>
#include <comphelper/extract.hxx>
#include <editeng/eeitem.hxx>
#include <toolkit/helper/convert.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdocapt.hxx>
#include <editeng/outlobj.hxx>
#include <svx/svditer.hxx>
#include <svx/svdpage.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/sheet/XUsedAreaCursor.hpp>
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#include <com/sun/star/sheet/XAreaLinks.hpp>
#include <com/sun/star/sheet/XAreaLink.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/table/XColumnRowRange.hpp>
#include <com/sun/star/sheet/XPrintAreas.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XProtectable.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp>
#include <com/sun/star/sheet/XCellRangesQuery.hpp>
#include <com/sun/star/sheet/CellFlags.hpp>
#include <com/sun/star/util/XMergeable.hpp>
#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/sheet/XLabelRanges.hpp>
#include <com/sun/star/sheet/XLabelRange.hpp>
#include <com/sun/star/sheet/XNamedRanges2.hpp>
#include <com/sun/star/sheet/XNamedRange2.hpp>
#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
#include <com/sun/star/sheet/NamedRangeFlag.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/sheet/XSheetLinkable.hpp>
#include <com/sun/star/form/XFormsSupplier2.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include "XMLCodeNameProvider.hxx"
#include <sfx2/objsh.hxx>
#include <vector>
//! not found in unonames.hxx
#define SC_STANDARDFORMAT "StandardFormat"
#define SC_LAYERID "LayerID"
#define SC_DEFAULT_TABLE_COUNT 3
#define SC_VIEWCHANGES_COUNT 13
#define SC_SHOW_CHANGES 0
#define SC_SHOW_ACCEPTED_CHANGES 1
#define SC_SHOW_REJECTED_CHANGES 2
#define SC_SHOW_CHANGES_BY_DATETIME 3
#define SC_SHOW_CHANGES_BY_DATETIME_MODE 4
#define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5
#define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6
#define SC_SHOW_CHANGES_BY_AUTHOR 7
#define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8
#define SC_SHOW_CHANGES_BY_COMMENT 9
#define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10
#define SC_SHOW_CHANGES_BY_RANGES 11
#define SC_SHOW_CHANGES_BY_RANGES_LIST 12
using namespace rtl;
using namespace formula;
using namespace com::sun::star;
using namespace xmloff::token;
using ::std::vector;
using ::com::sun::star::uno::UNO_QUERY;
//----------------------------------------------------------------------------
namespace
{
OUString lcl_RangeSequenceToString(
const uno::Sequence< OUString > & rRanges,
const uno::Reference< chart2::data::XRangeXMLConversion > & xFormatConverter )
{
OUStringBuffer aResult;
const sal_Int32 nMaxIndex( rRanges.getLength() - 1 );
const sal_Unicode cSep( sal_Char(' '));
for( sal_Int32 i=0; i<=nMaxIndex; ++i )
{
OUString aRange( rRanges[i] );
if( xFormatConverter.is())
aRange = xFormatConverter->convertRangeToXML( aRange );
aResult.append( aRange );
if( i < nMaxIndex )
aResult.append( cSep );
}
return aResult.makeStringAndClear();
}
OUString lcl_GetRawString( ScDocument* pDoc, const ScAddress& rPos )
{
// return text/edit cell string content, with line feeds in edit cells
String aVal; // document uses tools-strings
if (pDoc)
{
ScBaseCell* pCell = pDoc->GetCell( rPos );
if (pCell)
{
CellType eType = pCell->GetCellType();
if ( eType == CELLTYPE_STRING )
static_cast<ScStringCell*>(pCell)->GetString(aVal); // string cell: content
else if ( eType == CELLTYPE_EDIT )
{
// edit cell: text with line breaks
const EditTextObject* pData = static_cast<ScEditCell*>(pCell)->GetData();
if (pData)
{
EditEngine& rEngine = pDoc->GetEditEngine();
rEngine.SetText( *pData );
aVal = rEngine.GetText( LINEEND_LF );
}
}
}
}
return aVal;
}
} // anonymous namespace
//----------------------------------------------------------------------------
OUString SAL_CALL ScXMLOOoExport_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOOoExport_getImplementationName() );
return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
// #110680#
// return (cppu::OWeakObject*)new ScXMLExport(EXPORT_ALL);
return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_ALL );
}
OUString SAL_CALL ScXMLOOoExport_Meta_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLMetaExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Meta_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOOoExport_Meta_getImplementationName() );
return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Meta_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
// #110680#
// return (cppu::OWeakObject*)new ScXMLExport(EXPORT_META);
return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_META );
}
OUString SAL_CALL ScXMLOOoExport_Styles_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLStylesExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Styles_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOOoExport_Styles_getImplementationName() );
return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Styles_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
// #110680#
// return (cppu::OWeakObject*)new ScXMLExport(EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS);
return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS);
}
OUString SAL_CALL ScXMLOOoExport_Content_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLContentExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Content_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOOoExport_Content_getImplementationName() );
return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Content_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
// #110680#
// return (cppu::OWeakObject*)new ScXMLExport(EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS);
return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS);
}
OUString SAL_CALL ScXMLOOoExport_Settings_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLSettingsExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Settings_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOOoExport_Settings_getImplementationName() );
return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Settings_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
// #110680#
// return (cppu::OWeakObject*)new ScXMLExport(EXPORT_SETTINGS);
return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_SETTINGS );
}
// Oasis Filter
OUString SAL_CALL ScXMLOasisExport_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOasisExport_getImplementationName() );
const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
return aSeq;
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_ALL|EXPORT_OASIS);
}
OUString SAL_CALL ScXMLOasisExport_Meta_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisMetaExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Meta_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOasisExport_Meta_getImplementationName() );
const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
return aSeq;
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Meta_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_META|EXPORT_OASIS);
}
OUString SAL_CALL ScXMLOasisExport_Styles_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisStylesExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Styles_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOasisExport_Styles_getImplementationName() );
const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
return aSeq;
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Styles_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS|EXPORT_OASIS);
}
OUString SAL_CALL ScXMLOasisExport_Content_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisContentExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Content_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOasisExport_Content_getImplementationName() );
const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
return aSeq;
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Content_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS|EXPORT_OASIS);
}
OUString SAL_CALL ScXMLOasisExport_Settings_getImplementationName() throw()
{
return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisSettingsExporter" ) );
}
uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Settings_getSupportedServiceNames() throw()
{
const rtl::OUString aServiceName( ScXMLOasisExport_Settings_getImplementationName() );
const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
return aSeq;
}
uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Settings_createInstance(
const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_SETTINGS|EXPORT_OASIS);
}
//----------------------------------------------------------------------------
class ScXMLShapeExport : public XMLShapeExport
{
public:
ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {}
~ScXMLShapeExport();
/** is called before a shape element for the given XShape is exported */
virtual void onExport( const uno::Reference < drawing::XShape >& xShape );
};
ScXMLShapeExport::~ScXMLShapeExport()
{
}
void ScXMLShapeExport::onExport( const uno::Reference < drawing::XShape >& xShape )
{
uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
if( xShapeProp.is() )
{
sal_Int16 nLayerID = 0;
if( (xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ))) >>= nLayerID) && (nLayerID == SC_LAYER_BACK) )
GetExport().AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_BACKGROUND, XML_TRUE);
}
}
//----------------------------------------------------------------------------
sal_Int16 ScXMLExport::GetFieldUnit()
{
com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xProperties(
comphelper::getProcessServiceFactory()->createInstance(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" )) ),
com::sun::star::uno::UNO_QUERY);
if (xProperties.is())
{
sal_Int16 nFieldUnit = 0;
if (xProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Metric"))) >>= nFieldUnit)
return nFieldUnit;
}
return 0;
}
// #110680#
ScXMLExport::ScXMLExport(
const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
const sal_uInt16 nExportFlag)
: SvXMLExport( xServiceFactory, SvXMLUnitConverter::GetMapUnit(GetFieldUnit()), XML_SPREADSHEET, nExportFlag ),
pDoc(NULL),
nSourceStreamPos(0),
pNumberFormatAttributesExportHelper(NULL),
pSharedData(NULL),
pColumnStyles(NULL),
pRowStyles(NULL),
pCellStyles(NULL),
pRowFormatRanges(NULL),
aTableStyles(),
pGroupColumns (NULL),
pGroupRows (NULL),
pDefaults(NULL),
pChartListener(NULL),
pCurrentCell(NULL),
pMergedRangesContainer(NULL),
pValidationsContainer(NULL),
pCellsItr(NULL),
pChangeTrackingExportHelper(NULL),
sLayerID(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID )),
sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape")),
nOpenRow(-1),
nProgressCount(0),
nCurrentTable(0),
bHasRowHeader(sal_False),
bRowHeaderOpen(sal_False),
mbShowProgress( sal_False )
{
if (getExportFlags() & EXPORT_CONTENT)
{
pGroupColumns = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP);
pGroupRows = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP);
pColumnStyles = new ScColumnStyles();
pRowStyles = new ScRowStyles();
pRowFormatRanges = new ScRowFormatRanges();
pMergedRangesContainer = new ScMyMergedRangesContainer();
pValidationsContainer = new ScMyValidationsContainer();
pCellsItr = new ScMyNotEmptyCellsIterator(*this);
pDefaults = new ScMyDefaultStyles();
}
pCellStyles = new ScFormatRangeStyles();
// document is not set here - create ScChangeTrackingExportHelper later
xScPropHdlFactory = new XMLScPropHdlFactory;
xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory);
xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory);
xRowStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScRowStylesProperties, xScPropHdlFactory);
xTableStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScTableStylesProperties, xScPropHdlFactory);
xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper);
xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
xColumnStylesExportPropertySetMapper = new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper);
xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper);
xTableStylesExportPropertySetMapper = new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper);
GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)),
xCellStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX)));
GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME)),
xColumnStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX)));
GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME)),
xRowStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX)));
GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME)),
xTableStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX)));
if( (getExportFlags() & (EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
{
// This name is reserved for the external ref cache tables. This
// should not conflict with user-defined styles since this name is
// used for a table style which is not available in the UI.
sExternalRefTabStyleName = rtl::OUString::createFromAscii("ta_extref");
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sExternalRefTabStyleName);
sAttrName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NAME));
sAttrStyleName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME));
sAttrColumnsRepeated = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED));
sAttrFormula = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_FORMULA));
sAttrStringValue = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE));
sAttrValueType = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE));
sElemCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_CELL));
sElemCoveredCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_COVERED_TABLE_CELL));
sElemCol = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_COLUMN));
sElemRow = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_ROW));
sElemTab = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE));
sElemP = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
}
}
ScXMLExport::~ScXMLExport()
{
if (pGroupColumns)
delete pGroupColumns;
if (pGroupRows)
delete pGroupRows;
if (pColumnStyles)
delete pColumnStyles;
if (pRowStyles)
delete pRowStyles;
if (pCellStyles)
delete pCellStyles;
if (pRowFormatRanges)
delete pRowFormatRanges;
if (pMergedRangesContainer)
delete pMergedRangesContainer;
if (pValidationsContainer)
delete pValidationsContainer;
if (pChangeTrackingExportHelper)
delete pChangeTrackingExportHelper;
if (pChartListener)
delete pChartListener;
if (pCellsItr)
delete pCellsItr;
if (pDefaults)
delete pDefaults;
if (pNumberFormatAttributesExportHelper)
delete pNumberFormatAttributesExportHelper;
}
void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream )
{
xSourceStream = xNewStream;
if ( xSourceStream.is() )
{
// make sure it's a plain UTF-8 stream as written by OOo itself
const sal_Char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
sal_Int32 nLen = strlen(pXmlHeader);
uno::Sequence<sal_Int8> aFileStart(nLen);
sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen );
if ( nRead != nLen || rtl_compareMemory( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 )
{
// invalid - ignore stream, save normally
xSourceStream.clear();
}
else
{
// keep track of the bytes already read
nSourceStreamPos = nRead;
const ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
if (pSheetData)
{
// add the loaded namespaces to the name space map
if ( !pSheetData->AddLoadedNamespaces( _GetNamespaceMap() ) )
{
// conflicts in the namespaces - ignore the stream, save normally
xSourceStream.clear();
}
}
}
}
}
sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const
{
NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt);
if (itr == aNumFmtIndexMap.end())
return -1;
return itr->second;
}
sal_Bool ScXMLExport::HasDrawPages(uno::Reference <sheet::XSpreadsheetDocument>& xDoc)
{
uno::Reference <beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY );
return (xDocProps.is() && ::cppu::any2bool( xDocProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_HASDRAWPAGES))) ));
}
void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount, const sal_Int32 nCellCount)
{
if (GetModel().is())
{
uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
if ( xSpreadDoc.is())
{
uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
if ( xIndex.is() )
{
nTableCount = xIndex->getCount();
if (!pSharedData)
CreateSharedData(nTableCount);
pCellStyles->AddNewTable(nTableCount - 1);
pDoc->InitializeAllNoteCaptions( true );
if (HasDrawPages(xSpreadDoc))
{
rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
{
nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY);
if (xDrawPageSupplier.is())
{
uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage());
ScMyDrawPage aDrawPage;
aDrawPage.bHasForms = sal_False;
aDrawPage.xDrawPage.set(xDrawPage);
pSharedData->AddDrawPage(aDrawPage, nTable);
uno::Reference<container::XIndexAccess> xShapesIndex (xDrawPage, uno::UNO_QUERY);
if (xShapesIndex.is())
{
sal_Int32 nShapes(xShapesIndex->getCount());
for (sal_Int32 nShape = 0; nShape < nShapes; ++nShape)
{
uno::Reference<drawing::XShape> xShape(xShapesIndex->getByIndex(nShape), uno::UNO_QUERY);
if (xShape.is())
{
uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
if( xShapeProp.is() )
{
sal_Int16 nLayerID = 0;
if( xShapeProp->getPropertyValue(sLayerID) >>= nLayerID )
{
if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
CollectInternalShape( xShape );
else
{
++nShapesCount;
SvxShape* pShapeImp(SvxShape::getImplementation(xShape));
if (pShapeImp)
{
SdrObject *pSdrObj(pShapeImp->GetSdrObject());
if (pSdrObj)
{
if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL)
{
if (pDoc)
{
awt::Point aPoint(xShape->getPosition());
awt::Size aSize(xShape->getSize());
rtl::OUString sType(xShape->getShapeType());
Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
if ( sType.equals(sCaptionShape) )
{
awt::Point aRelativeCaptionPoint;
xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint;
Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y);
Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y);
aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint;
aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint));
}
ScRange aRange(pDoc->GetRange(static_cast<SCTAB>(nTable), aRectangle));
ScMyShape aMyShape;
aMyShape.aAddress = aRange.aStart;
aMyShape.aEndAddress = aRange.aEnd;
aMyShape.xShape = xShape;
pSharedData->AddNewShape(aMyShape);
pSharedData->SetLastColumn(nTable, aRange.aStart.Col());
pSharedData->SetLastRow(nTable, aRange.aStart.Row());
}
}
else
pSharedData->AddTableShape(nTable, xShape);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
sal_Int32 nRef(nCellCount + (2 * nTableCount) + (2 * nShapesCount));
GetProgressBarHelper()->SetReference(nRef);
GetProgressBarHelper()->SetValue(0);
}
void ScXMLExport::CollectShapesAutoStyles(const sal_Int32 nTableCount)
{
// #i84077# To avoid compiler warnings about uninitialized aShapeItr,
// it's initialized using this dummy list. The iterator contains shapes
// from all sheets, so it can't be declared inside the nTable loop where
// it is used.
ScMyShapeList aDummyInitList;
pSharedData->SortShapesContainer();
pSharedData->SortNoteShapes();
const ScMyShapeList* pShapeList(NULL);
ScMyShapeList::const_iterator aShapeItr = aDummyInitList.end();
if (pSharedData->GetShapesContainer())
{
pShapeList = pSharedData->GetShapesContainer()->GetShapes();
aShapeItr = pShapeList->begin();
}
if (pSharedData->HasDrawPage())
{
for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
{
uno::Reference<drawing::XDrawPage> xDrawPage(pSharedData->GetDrawPage(nTable));
uno::Reference<drawing::XShapes> xShapes (xDrawPage, uno::UNO_QUERY);
if (xShapes.is())
{
GetShapeExport()->seekShapes(xShapes);
uno::Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, uno::UNO_QUERY );
if( xFormsSupplier.is() && xFormsSupplier->hasForms() )
{
GetFormExport()->examineForms(xDrawPage);
pSharedData->SetDrawPageHasForms(nTable, sal_True);
}
ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
if (pTableShapes)
{
ScMyTableXShapes::iterator aItr((*pTableShapes)[nTable].begin());
ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nTable].end());
while (aItr != aEndItr)
{
GetShapeExport()->collectShapeAutoStyles(*aItr);
IncrementProgressBar(sal_False);
++aItr;
}
}
if (pShapeList)
{
ScMyShapeList::const_iterator aEndItr(pShapeList->end());
while (aShapeItr != aEndItr && (static_cast<sal_Int32>(aShapeItr->aAddress.Tab()) == nTable))
{
GetShapeExport()->collectShapeAutoStyles(aShapeItr->xShape);
IncrementProgressBar(sal_False);
++aShapeItr;
}
}
const ScMyNoteShapeList* pNoteShapes = NULL;
ScMyNoteShapeList::const_iterator aNoteShapeItr;
ScMyNoteShapeList::const_iterator aNoteShapeEndItr;
if (pSharedData->GetNoteShapes())
{
pNoteShapes = pSharedData->GetNoteShapes()->GetNotes();
if (pNoteShapes)
{
aNoteShapeItr = pNoteShapes->begin();
aNoteShapeEndItr = pNoteShapes->end();
}
}
if (pNoteShapes)
{
while (aNoteShapeItr != aNoteShapeEndItr)
{
if (static_cast<sal_Int32>(aNoteShapeItr->aPos.Tab()) == nTable)
GetShapeExport()->collectShapeAutoStyles(aNoteShapeItr->xShape);
++aNoteShapeItr;
}
}
}
}
}
pSharedData->SortNoteShapes(); // sort twice, because some more shapes are added
}
void ScXMLExport::_ExportMeta()
{
sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
sal_Int32 nTableCount(0);
sal_Int32 nShapesCount(0);
GetAutoStylePool()->ClearEntries();
CollectSharedData(nTableCount, nShapesCount, nCellCount);
uno::Sequence<beans::NamedValue> stats(3);
stats[0] = beans::NamedValue(::rtl::OUString::createFromAscii("TableCount"),
uno::makeAny(nTableCount));
stats[1] = beans::NamedValue(::rtl::OUString::createFromAscii("CellCount"),
uno::makeAny(nCellCount));
stats[2] = beans::NamedValue(::rtl::OUString::createFromAscii("ObjectCount"),
uno::makeAny(nShapesCount));
// update document statistics at the model
uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(),
uno::UNO_QUERY_THROW);
uno::Reference<document::XDocumentProperties> xDocProps(
xPropSup->getDocumentProperties());
if (xDocProps.is()) {
xDocProps->setDocumentStatistics(stats);
}
// export document properties
SvXMLExport::_ExportMeta();
}
void ScXMLExport::_ExportFontDecls()
{
GetFontAutoStylePool(); // make sure the pool is created
SvXMLExport::_ExportFontDecls();
}
table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable, const sal_Int32 /* nTable */)
{
table::CellRangeAddress aCellAddress;
uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor());
uno::Reference<sheet::XUsedAreaCursor> xUsedArea (xCursor, uno::UNO_QUERY);
uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
if (xUsedArea.is() && xCellAddress.is())
{
xUsedArea->gotoEndOfUsedArea(sal_True);
aCellAddress = xCellAddress->getRangeAddress();
}
return aCellAddress;
}
void ScXMLExport::GetAreaLinks( uno::Reference< sheet::XSpreadsheetDocument>& xSpreadDoc,
ScMyAreaLinksContainer& rAreaLinks )
{
uno::Reference< beans::XPropertySet > xPropSet( xSpreadDoc, uno::UNO_QUERY );
if( !xPropSet.is() ) return;
uno::Reference< container::XIndexAccess > xLinksIAccess( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_AREALINKS ) ) ), uno::UNO_QUERY);
if( xLinksIAccess.is() )
{
const OUString sFilter( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTER ) );
const OUString sFilterOpt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTOPT ) );
const OUString sURL( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_LINKURL ) );
const OUString sRefresh( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_REFDELAY ) );
sal_Int32 nCount(xLinksIAccess->getCount());
for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
{
uno::Reference< sheet::XAreaLink > xAreaLink(xLinksIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
if( xAreaLink.is() )
{
ScMyAreaLink aAreaLink;
aAreaLink.aDestRange = xAreaLink->getDestArea();
aAreaLink.sSourceStr = xAreaLink->getSourceArea();
uno::Reference< beans::XPropertySet > xLinkProp( xAreaLink, uno::UNO_QUERY );
if( xLinkProp.is() )
{
xLinkProp->getPropertyValue( sFilter ) >>= aAreaLink.sFilter;
xLinkProp->getPropertyValue( sFilterOpt ) >>= aAreaLink.sFilterOptions;
xLinkProp->getPropertyValue( sURL ) >>= aAreaLink.sURL;
xLinkProp->getPropertyValue( sRefresh ) >>= aAreaLink.nRefresh;
}
rAreaLinks.AddNewAreaLink( aAreaLink );
}
}
}
rAreaLinks.Sort();
}
// core implementation
void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp )
{
if (pDoc)
{
ScDetOpList* pOpList(pDoc->GetDetOpList());
if( pOpList )
{
sal_uInt32 nCount(pOpList->Count());
for( sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex )
{
ScDetOpData* pDetData(pOpList->GetObject( static_cast<sal_uInt16>(nIndex) ));
if( pDetData )
{
const ScAddress& rDetPos = pDetData->GetPos();
SCTAB nTab = rDetPos.Tab();
if ( nTab < pDoc->GetTableCount() )
{
rDetOp.AddOperation( pDetData->GetOperation(), rDetPos, nIndex );
// #123981# cells with detective operations are written even if empty
pSharedData->SetLastColumn( nTab, rDetPos.Col() );
pSharedData->SetLastRow( nTab, rDetPos.Row() );
}
}
}
rDetOp.Sort();
}
}
}
void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex,
const sal_Int32 nIndex, const sal_Bool bIsAutoStyle, const sal_Bool bIsVisible)
{
CheckAttrList();
AddAttribute(sAttrStyleName, *pColumnStyles->GetStyleNameByIndex(nStyleIndex));
if (!bIsVisible)
AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
if (nRepeatColumns > 1)
{
OUString sOUEndCol(OUString::valueOf(static_cast <sal_Int32> (nRepeatColumns)));
AddAttribute(sAttrColumnsRepeated, sOUEndCol);
}
if (nIndex != -1)
AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
SvXMLElementExport aElemC(*this, sElemCol, sal_True, sal_True);
}
void ScXMLExport::WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns,
const sal_Int32 nStyleIndex, const sal_Bool bIsVisible)
{
sal_Int32 nRepeat(1);
sal_Int32 nPrevIndex((*pDefaults->GetColDefaults())[nColumn].nIndex);
sal_Bool bPrevAutoStyle((*pDefaults->GetColDefaults())[nColumn].bIsAutoStyle);
for (sal_Int32 i = nColumn + 1; i < nColumn + nRepeatColumns; ++i)
{
if (((*pDefaults->GetColDefaults())[i].nIndex != nPrevIndex) ||
((*pDefaults->GetColDefaults())[i].bIsAutoStyle != bPrevAutoStyle))
{
WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
nPrevIndex = (*pDefaults->GetColDefaults())[i].nIndex;
bPrevAutoStyle = (*pDefaults->GetColDefaults())[i].bIsAutoStyle;
nRepeat = 1;
}
else
++nRepeat;
}
WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
}
void ScXMLExport::OpenHeaderColumn()
{
StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True );
}
void ScXMLExport::CloseHeaderColumn()
{
EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True);
}
void ScXMLExport::ExportColumns(const sal_Int32 nTable, const table::CellRangeAddress& aColumnHeaderRange, const sal_Bool bHasColumnHeader)
{
sal_Int32 nColsRepeated (1);
rtl::OUString sParent;
sal_Int32 nIndex;
sal_Int32 nPrevColumn(0);
sal_Bool bPrevIsVisible (sal_True);
sal_Bool bWasHeader (sal_False);
sal_Bool bIsHeader (sal_False);
sal_Bool bIsClosed (sal_True);
sal_Bool bIsFirst (sal_False);
sal_Int32 nPrevIndex (-1);
sal_Int32 nColumn;
for (nColumn = 0; nColumn <= pSharedData->GetLastColumn(nTable); ++nColumn)
{
CheckAttrList();
sal_Bool bIsVisible(sal_True);
nIndex = pColumnStyles->GetStyleNameIndex(nTable, nColumn, bIsVisible);
bIsHeader = bHasColumnHeader && (aColumnHeaderRange.StartColumn <= nColumn) && (nColumn <= aColumnHeaderRange.EndColumn);
if (bIsHeader != bWasHeader)
{
if (bIsHeader)
{
bIsFirst = sal_False;
if (nColumn > 0)
{
WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
if (pGroupColumns->IsGroupEnd(nColumn - 1))
pGroupColumns->CloseGroups(nColumn - 1);
}
bPrevIsVisible = bIsVisible;
nPrevIndex = nIndex;
nPrevColumn = nColumn;
nColsRepeated = 1;
bIsFirst = sal_True;
if(pGroupColumns->IsGroupStart(nColumn))
pGroupColumns->OpenGroups(nColumn);
OpenHeaderColumn();
bWasHeader = sal_True;
bIsClosed = sal_False;
}
else
{
WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
CloseHeaderColumn();
if (pGroupColumns->IsGroupEnd(nColumn - 1))
pGroupColumns->CloseGroups(nColumn - 1);
if(pGroupColumns->IsGroupStart(nColumn))
pGroupColumns->OpenGroups(nColumn);
bPrevIsVisible = bIsVisible;
nPrevIndex = nIndex;
nPrevColumn = nColumn;
nColsRepeated = 1;
bWasHeader = sal_False;
bIsClosed = sal_True;
}
}
else if (nColumn == 0)
{
if (pGroupColumns->IsGroupStart(nColumn))
pGroupColumns->OpenGroups(nColumn);
bPrevIsVisible = bIsVisible;
nPrevIndex = nIndex;
bIsFirst = sal_True;
}
else if ((bIsVisible == bPrevIsVisible) && (nIndex == nPrevIndex) &&
!pGroupColumns->IsGroupStart(nColumn) && !pGroupColumns->IsGroupEnd(nColumn - 1))
++nColsRepeated;
else
{
bIsFirst = sal_False;
WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
if (pGroupColumns->IsGroupEnd(nColumn - 1))
{
if (bIsHeader)
CloseHeaderColumn();
pGroupColumns->CloseGroups(nColumn - 1);
if (bIsHeader)
OpenHeaderColumn();
}
if (pGroupColumns->IsGroupStart(nColumn))
{
if (bIsHeader)
CloseHeaderColumn();
pGroupColumns->OpenGroups(nColumn);
if (bIsHeader)
OpenHeaderColumn();
}
bPrevIsVisible = bIsVisible;
nPrevIndex = nIndex;
nPrevColumn = nColumn;
nColsRepeated = 1;
}
}
//if (nColsRepeated > 1 || bIsFirst)
WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
if (!bIsClosed)
CloseHeaderColumn();
if (pGroupColumns->IsGroupEnd(nColumn - 1))
pGroupColumns->CloseGroups(nColumn - 1);
}
void ScXMLExport::ExportExternalRefCacheStyles()
{
sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex(
"NumberFormat", XML_NAMESPACE_STYLE, OUString::createFromAscii("data-style-name"));
if (nEntryIndex < 0)
// No entry index for the number format is found.
return;
ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
if (!pRefMgr->hasExternalData())
// No external reference data cached.
return;
// Export each unique number format used in the external ref cache.
vector<sal_uInt32> aNumFmts;
pRefMgr->getAllCachedNumberFormats(aNumFmts);
const OUString aDefaultStyle = OUString::createFromAscii("Default").intern();
for (vector<sal_uInt32>::const_iterator itr = aNumFmts.begin(), itrEnd = aNumFmts.end();
itr != itrEnd; ++itr)
{
sal_Int32 nNumFmt = static_cast<sal_Int32>(*itr);
addDataStyle(nNumFmt);
uno::Any aVal;
aVal <<= nNumFmt;
vector<XMLPropertyState> aProps;
aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
aVal <<= aDefaultStyle;
aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
OUString aName;
sal_Int32 nIndex;
if (GetAutoStylePool()->Add(aName, XML_STYLE_FAMILY_TABLE_CELL, aDefaultStyle, aProps))
{
OUString* pTemp(new OUString(aName));
if (!pCellStyles->AddStyleName(pTemp, nIndex, true))
delete pTemp;
}
else
{
sal_Bool bIsAuto;
nIndex = pCellStyles->GetIndexOfStyleName(
aName, OUString::createFromAscii(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX), bIsAuto);
}
// store the number format to index mapping for later use.
aNumFmtIndexMap.insert(NumberFormatIndexMap::value_type(nNumFmt, nIndex));
}
}
void ScXMLExport::WriteRowContent()
{
ScMyRowFormatRange aRange;
sal_Int32 nIndex(-1);
#ifdef DBG_UTIL
sal_Int32 nPrevCol(0);
#endif
sal_Int32 nCols(0);
sal_Int32 nPrevValidationIndex(-1);
sal_Bool bIsAutoStyle(sal_True);
sal_Bool bIsFirst(sal_True);
while (pRowFormatRanges->GetNext(aRange))
{
#ifdef DBG_UTIL
DBG_ASSERT(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn)), "here are some columns missing");
#endif
if (bIsFirst)
{
nIndex = aRange.nIndex;
nPrevValidationIndex = aRange.nValidationIndex;
bIsAutoStyle = aRange.bIsAutoStyle;
nCols = aRange.nRepeatColumns;
bIsFirst = sal_False;
#ifdef DBG_UTIL
nPrevCol = aRange.nStartColumn;
#endif
}
else
{
if (((aRange.nIndex == nIndex && aRange.bIsAutoStyle == bIsAutoStyle) ||
(aRange.nIndex == nIndex && nIndex == -1)) &&
nPrevValidationIndex == aRange.nValidationIndex)
nCols += aRange.nRepeatColumns;
else
{
if (nIndex != -1)
AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
if (nPrevValidationIndex > -1)
AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
if (nCols > 1)
{
rtl::OUStringBuffer aBuf;
GetMM100UnitConverter().convertNumber(aBuf, nCols);
AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
}
SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True);
nIndex = aRange.nIndex;
bIsAutoStyle = aRange.bIsAutoStyle;
nCols = aRange.nRepeatColumns;
nPrevValidationIndex = aRange.nValidationIndex;
#ifdef DBG_UTIL
nPrevCol = aRange.nStartColumn;
#endif
}
}
}
if (!bIsFirst)
{
table::CellAddress aCellAddress;
if (nIndex != -1)
AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
if (nPrevValidationIndex > -1)
AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
if (nCols > 1)
{
rtl::OUStringBuffer aBuf;
GetMM100UnitConverter().convertNumber(aBuf, nCols);
AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
}
SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True);
}
}
void ScXMLExport::WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex,
const sal_Int8 nFlag, const sal_Int32 nEqualRows)
{
AddAttribute(sAttrStyleName, *pRowStyles->GetStyleNameByIndex(nIndex));
if (nFlag)
if (nFlag & CR_HIDDEN)
{
if (nFlag & CR_FILTERED)
AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_FILTER);
else
AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
}
if (nEqualRows > 1)
{
rtl::OUStringBuffer aBuf;
GetMM100UnitConverter().convertNumber(aBuf, nEqualRows);
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aBuf.makeStringAndClear());
}
const ScMyDefaultStyleList& rRowDefaults = *pDefaults->GetRowDefaults();
if ( nRow >= sal::static_int_cast<sal_Int32>( rRowDefaults.size() ) )
{
// #123981# used to happen with detective operations - if there are more cases, use the last row's style
DBG_ERRORFILE("WriteRowStartTag: not enough defaults");
nRow = rRowDefaults.size() - 1;
}
sal_Int32 nCellStyleIndex(rRowDefaults[nRow].nIndex);
if (nCellStyleIndex != -1)
AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME,
*pCellStyles->GetStyleNameByIndex(nCellStyleIndex,
(*pDefaults->GetRowDefaults())[nRow].bIsAutoStyle));
StartElement( sElemRow, sal_True);
}
void ScXMLExport::OpenHeaderRows()
{
StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True);
bRowHeaderOpen = sal_True;
}
void ScXMLExport::CloseHeaderRows()
{
EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True);
}
void ScXMLExport::OpenNewRow(const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nStartRow, const sal_Int32 nEqualRows)
{
nOpenRow = nStartRow;
if (pGroupRows->IsGroupStart(nStartRow))
{
if (bHasRowHeader && bRowHeaderOpen)
CloseHeaderRows();
pGroupRows->OpenGroups(nStartRow);
if (bHasRowHeader && bRowHeaderOpen)
OpenHeaderRows();
}
if (bHasRowHeader && !bRowHeaderOpen && nStartRow >= aRowHeaderRange.StartRow && nStartRow <= aRowHeaderRange.EndRow)
{
if (nStartRow == aRowHeaderRange.StartRow)
OpenHeaderRows();
sal_Int32 nEquals;
if (aRowHeaderRange.EndRow < nStartRow + nEqualRows - 1)
nEquals = aRowHeaderRange.EndRow - nStartRow + 1;
else
nEquals = nEqualRows;
WriteRowStartTag(nStartRow, nIndex, nFlag, nEquals);
nOpenRow = nStartRow + nEquals - 1;
if (nEquals < nEqualRows)
{
CloseRow(nStartRow + nEquals - 1);
WriteRowStartTag(nStartRow, nIndex, nFlag, nEqualRows - nEquals);
nOpenRow = nStartRow + nEqualRows - 1;
}
}
else
WriteRowStartTag(nStartRow, nIndex, nFlag, nEqualRows);
}
void ScXMLExport::OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int8 nFlag,
const sal_Int32 nStartRow, const sal_Int32 nEqualRows)
{
OpenNewRow(nIndex, nFlag, nStartRow, nEqualRows);
WriteRowContent();
CloseRow(nStartRow + nEqualRows - 1);
pRowFormatRanges->Clear();
}
void ScXMLExport::OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow)
{
if (nRepeatRow > 1)
{
sal_Int32 nPrevIndex(0), nIndex;
sal_Int8 nPrevFlag(0);
sal_Int8 nFlag(0);
sal_Int32 nEqualRows(1);
sal_Int32 nEndRow(nStartRow + nRepeatRow);
sal_Int32 nRow;
for (nRow = nStartRow; nRow < nEndRow; ++nRow)
{
if (nRow == nStartRow)
{
nPrevIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
if (pDoc)
nPrevFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
}
else
{
nIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
if (pDoc)
nFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
if (nIndex == nPrevIndex && nFlag == nPrevFlag &&
!(bHasRowHeader && ((nRow == aRowHeaderRange.StartRow) || (nRow - 1 == aRowHeaderRange.EndRow))) &&
!(pGroupRows->IsGroupStart(nRow)) &&
!(pGroupRows->IsGroupEnd(nRow - 1)))
++nEqualRows;
else
{
if (nRow < nEndRow)
{
ScRowFormatRanges* pTempRowFormatRanges = new ScRowFormatRanges(pRowFormatRanges);
OpenAndCloseRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
delete pRowFormatRanges;
pRowFormatRanges = pTempRowFormatRanges;
}
else
OpenAndCloseRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
nEqualRows = 1;
nPrevIndex = nIndex;
nPrevFlag = nFlag;
}
}
}
OpenNewRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
}
else
{
sal_Int32 nIndex = pRowStyles->GetStyleNameIndex(nTable, nStartRow);
sal_Int8 nFlag(0);
if (pDoc)
nFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nStartRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
OpenNewRow(nIndex, nFlag, nStartRow, 1);
}
nOpenRow = nStartRow + nRepeatRow - 1;
}
void ScXMLExport::CloseRow(const sal_Int32 nRow)
{
if (nOpenRow > -1)
{
EndElement(sElemRow, sal_True);
if (bHasRowHeader && nRow == aRowHeaderRange.EndRow)
{
CloseHeaderRows();
bRowHeaderOpen = sal_False;
}
if (pGroupRows->IsGroupEnd(nRow))
{
if (bHasRowHeader && bRowHeaderOpen)
CloseHeaderRows();
pGroupRows->CloseGroups(nRow);
if (bHasRowHeader && bRowHeaderOpen)
OpenHeaderRows();
}
}
nOpenRow = -1;
}
void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow,
const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet)
{
pRowFormatRanges->Clear();
if (nStartRow == nEndRow)
{
pCellStyles->GetFormatRanges(nStartCol, nEndCol, nStartRow, nSheet, pRowFormatRanges);
if (nOpenRow == - 1)
OpenRow(nSheet, nStartRow, 1);
WriteRowContent();
pRowFormatRanges->Clear();
}
else
{
if (nOpenRow > -1)
{
pCellStyles->GetFormatRanges(nStartCol, pSharedData->GetLastColumn(nSheet), nStartRow, nSheet, pRowFormatRanges);
WriteRowContent();
CloseRow(nStartRow);
sal_Int32 nRows(1);
sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
while (nRows < nTotalRows)
{
pRowFormatRanges->Clear();
pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
DBG_ASSERT(nMaxRows, "something wents wrong");
if (nMaxRows >= nTotalRows - nRows)
{
OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows);
nRows += nTotalRows - nRows;
}
else
{
OpenRow(nSheet, nStartRow + nRows, nMaxRows);
nRows += nMaxRows;
}
if (!pRowFormatRanges->GetSize())
pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
WriteRowContent();
CloseRow(nStartRow + nRows - 1);
}
if (nTotalRows == 1)
CloseRow(nStartRow);
OpenRow(nSheet, nEndRow, 1);
pRowFormatRanges->Clear();
pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
WriteRowContent();
}
else
{
sal_Int32 nRows(0);
sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
while (nRows < nTotalRows)
{
pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
if (nMaxRows >= nTotalRows - nRows)
{
OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows);
nRows += nTotalRows - nRows;
}
else
{
OpenRow(nSheet, nStartRow + nRows, nMaxRows);
nRows += nMaxRows;
}
if (!pRowFormatRanges->GetSize())
pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
WriteRowContent();
CloseRow(nStartRow + nRows - 1);
}
OpenRow(nSheet, nEndRow, 1);
pRowFormatRanges->Clear();
pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
WriteRowContent();
}
}
}
void ScXMLExport::GetColumnRowHeader(sal_Bool& rHasColumnHeader, table::CellRangeAddress& rColumnHeaderRange,
sal_Bool& rHasRowHeader, table::CellRangeAddress& rRowHeaderRange,
rtl::OUString& rPrintRanges) const
{
uno::Reference <sheet::XPrintAreas> xPrintAreas (xCurrentTable, uno::UNO_QUERY);
if (xPrintAreas.is())
{
rHasRowHeader = xPrintAreas->getPrintTitleRows();
rHasColumnHeader = xPrintAreas->getPrintTitleColumns();
rRowHeaderRange = xPrintAreas->getTitleRows();
rColumnHeaderRange = xPrintAreas->getTitleColumns();
uno::Sequence< table::CellRangeAddress > aRangeList( xPrintAreas->getPrintAreas() );
ScRangeStringConverter::GetStringFromRangeList( rPrintRanges, aRangeList, pDoc, FormulaGrammar::CONV_OOO );
}
}
void ScXMLExport::FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups)
{
sal_Int32 nDepth(pFields->GetDepth());
for(sal_Int32 i = 0; i < nDepth; ++i)
{
sal_Int32 nFields = pFields->GetCount(static_cast<sal_uInt16>(i));
for (sal_Int32 j = 0; j < nFields; ++j)
{
ScMyColumnRowGroup aGroup;
ScOutlineEntry* pEntry(pFields->GetEntry(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j)));
aGroup.nField = pEntry->GetStart();
aGroup.nLevel = static_cast<sal_Int16>(i);
aGroup.bDisplay = !(pEntry->IsHidden());
pGroups->AddGroup(aGroup, pEntry->GetEnd());
}
}
if (nDepth)
pGroups->Sort();
}
void ScXMLExport::FillColumnRowGroups()
{
if (pDoc)
{
ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable( static_cast<SCTAB>(nCurrentTable), sal_False );
if(pOutlineTable)
{
ScOutlineArray* pCols(pOutlineTable->GetColArray());
ScOutlineArray* pRows(pOutlineTable->GetRowArray());
if (pCols)
FillFieldGroup(pCols, pGroupColumns);
if (pRows)
FillFieldGroup(pRows, pGroupRows);
pSharedData->SetLastColumn(nCurrentTable, pGroupColumns->GetLast());
pSharedData->SetLastRow(nCurrentTable, pGroupRows->GetLast());
}
}
}
void ScXMLExport::SetBodyAttributes()
{
if (pDoc && pDoc->IsDocProtected())
{
AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE);
rtl::OUStringBuffer aBuffer;
uno::Sequence<sal_Int8> aPassHash;
const ScDocProtection* p = pDoc->GetDocProtection();
if (p)
aPassHash = p->getPasswordHash(PASSHASH_OOO);
SvXMLUnitConverter::encodeBase64(aBuffer, aPassHash);
if (aBuffer.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
}
}
static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput,
const uno::Reference< io::XOutputStream >& xOutput,
sal_Int32 nCount )
{
const sal_Int32 nBufSize = 16*1024;
uno::Sequence<sal_Int8> aSequence(nBufSize);
sal_Int32 nRemaining = nCount;
bool bFirst = true;
while ( nRemaining > 0 )
{
sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) );
if (bFirst)
{
// safety check: Make sure the copied part actually points to the start of an element
if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') )
{
return false; // abort and set an error
}
bFirst = false;
}
if (nRead == nRemaining)
{
// safety check: Make sure the copied part also ends at the end of an element
if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') )
{
return false; // abort and set an error
}
}
if ( nRead == nBufSize )
{
xOutput->writeBytes( aSequence );
nRemaining -= nRead;
}
else
{
if ( nRead > 0 )
{
uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead );
xOutput->writeBytes( aTempBuf );
}
nRemaining = 0;
}
}
return true; // successful
}
static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip )
{
// skipBytes in zip stream is implemented as reading.
// For now, split into several calls to avoid allocating a large buffer.
// Later, skipBytes should be changed.
const sal_Int32 nMaxSize = 32*1024;
if ( nBytesToSkip > 0 )
{
sal_Int32 nRemaining = nBytesToSkip;
while ( nRemaining > 0 )
{
sal_Int32 nSkip = std::min( nRemaining, nMaxSize );
xInput->skipBytes( nSkip );
nRemaining -= nSkip;
}
}
}
void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd )
{
uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler();
uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY );
if ( xDestSource.is() )
{
uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream();
uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY );
if ( xDestSeek.is() )
{
// temporary: set same stream again to clear buffer
xDestSource->setOutputStream( xDestStream );
if ( getExportFlags() & EXPORT_PRETTY )
{
ByteString aOutStr("\n ");
uno::Sequence<sal_Int8> aOutSeq( (sal_Int8*)aOutStr.GetBuffer(), aOutStr.Len() );
xDestStream->writeBytes( aOutSeq );
}
rNewStart = (sal_Int32)xDestSeek->getPosition();
if ( nStartOffset > nSourceStreamPos )
lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos );
if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) )
{
// If copying went wrong, set an error.
// ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
uno::Sequence<OUString> aEmptySeq;
SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
}
nSourceStreamPos = nEndOffset;
rNewEnd = (sal_Int32)xDestSeek->getPosition();
}
}
}
void ScXMLExport::_ExportContent()
{
nCurrentTable = 0;
if (!pSharedData)
{
sal_Int32 nTableCount(0);
sal_Int32 nShapesCount(0);
sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
CollectSharedData(nTableCount, nShapesCount, nCellCount);
DBG_ERROR("no shared data setted");
}
ScXMLExportDatabaseRanges aExportDatabaseRanges(*this);
if (!GetModel().is())
return;
uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
if ( !xSpreadDoc.is() )
return;
ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
if (pSheetData)
pSheetData->ResetSaveEntries();
uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
if ( xIndex.is() )
{
//_GetNamespaceMap().ClearQNamesCache();
pChangeTrackingExportHelper->CollectAndWriteChanges();
WriteCalculationSettings(xSpreadDoc);
sal_Int32 nTableCount(xIndex->getCount());
ScMyAreaLinksContainer aAreaLinks;
GetAreaLinks( xSpreadDoc, aAreaLinks );
ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges());
ScMyDetectiveOpContainer aDetectiveOpContainer;
GetDetectiveOpList( aDetectiveOpContainer );
pCellStyles->Sort();
pMergedRangesContainer->Sort();
pSharedData->GetDetectiveObjContainer()->Sort();
pCellsItr->Clear();
pCellsItr->SetShapes( pSharedData->GetShapesContainer() );
pCellsItr->SetNoteShapes( pSharedData->GetNoteShapes() );
pCellsItr->SetMergedRanges( pMergedRangesContainer );
pCellsItr->SetAreaLinks( &aAreaLinks );
pCellsItr->SetEmptyDatabaseRanges( &aEmptyRanges );
pCellsItr->SetDetectiveObj( pSharedData->GetDetectiveObjContainer() );
pCellsItr->SetDetectiveOp( &aDetectiveOpContainer );
if (nTableCount > 0)
pValidationsContainer->WriteValidations(*this);
WriteTheLabelRanges( xSpreadDoc );
for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
{
sal_Int32 nStartOffset = -1;
sal_Int32 nEndOffset = -1;
if (pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable))
pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset );
if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() )
{
sal_Int32 nNewStart = -1;
sal_Int32 nNewEnd = -1;
CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd );
// store position of copied sheet in output
pSheetData->AddSavePos( nTable, nNewStart, nNewEnd );
// skip iterator entries for this sheet
pCellsItr->SkipTable(static_cast<SCTAB>(nTable));
}
else
{
uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
if (xTable.is())
{
xCurrentTable.set(xTable);
xCurrentTableCellRange.set(xTable, uno::UNO_QUERY);
uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY );
if ( xName.is() )
{
nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
rtl::OUString sOUTableName(xName->getName());
AddAttribute(sAttrName, sOUTableName);
AddAttribute(sAttrStyleName, aTableStyles[nTable]);
uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY);
if (xProtectable.is() && xProtectable->isProtected())
{
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
rtl::OUStringBuffer aBuffer;
if (pDoc)
{
ScTableProtection* pProtect = pDoc->GetTabProtection(static_cast<SCTAB>(nTable));
if (pProtect)
SvXMLUnitConverter::encodeBase64(aBuffer, pProtect->getPasswordHash(PASSHASH_OOO));
}
if (aBuffer.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
}
rtl::OUString sPrintRanges;
table::CellRangeAddress aColumnHeaderRange;
sal_Bool bHasColumnHeader;
GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges);
if( sPrintRanges.getLength() )
AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges );
else if (!pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable)))
AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE);
SvXMLElementExport aElemT(*this, sElemTab, sal_True, sal_True);
CheckAttrList();
if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) &&
getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
{
// store sheet events
uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY);
uno::Reference<container::XNameAccess> xEvents(xSupplier->getEvents(), uno::UNO_QUERY);
GetEventExport().ExportExt( xEvents );
}
WriteTableSource();
WriteScenario();
uno::Reference<drawing::XDrawPage> xDrawPage;
if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is())
{
::xmloff::OOfficeFormsExport aForms(*this);
GetFormExport()->exportForms( xDrawPage );
sal_Bool bRet(GetFormExport()->seekPage( xDrawPage ));
DBG_ASSERT( bRet, "OFormLayerXMLExport::seekPage failed!" );
(void)bRet; // avoid warning in product version
}
if (pSharedData->HasDrawPage())
{
GetShapeExport()->seekShapes(uno::Reference<drawing::XShapes>(pSharedData->GetDrawPage(nTable), uno::UNO_QUERY));
WriteTableShapes();
}
table::CellRangeAddress aRange(GetEndAddress(xTable, nTable));
pSharedData->SetLastColumn(nTable, aRange.EndColumn);
pSharedData->SetLastRow(nTable, aRange.EndRow);
pCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable);
pGroupColumns->NewTable();
pGroupRows->NewTable();
FillColumnRowGroups();
if (bHasColumnHeader)
pSharedData->SetLastColumn(nTable, aColumnHeaderRange.EndColumn);
bRowHeaderOpen = sal_False;
if (bHasRowHeader)
pSharedData->SetLastRow(nTable, aRowHeaderRange.EndRow);
pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable),
pSharedData->GetLastColumn(nTable), pCellStyles, pDoc);
pRowFormatRanges->SetRowDefaults(pDefaults->GetRowDefaults());
pRowFormatRanges->SetColDefaults(pDefaults->GetColDefaults());
pCellStyles->SetRowDefaults(pDefaults->GetRowDefaults());
pCellStyles->SetColDefaults(pDefaults->GetColDefaults());
ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader);
sal_Bool bIsFirst(sal_True);
sal_Int32 nEqualCells(0);
ScMyCell aCell;
ScMyCell aPrevCell;
while(pCellsItr->GetNext(aCell, pCellStyles))
{
if (bIsFirst)
{
ExportFormatRanges(0, 0, aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable);
aPrevCell = aCell;
bIsFirst = sal_False;
}
else
{
if ((aPrevCell.aCellAddress.Row == aCell.aCellAddress.Row) &&
(aPrevCell.aCellAddress.Column + nEqualCells + 1 == aCell.aCellAddress.Column))
{
if(IsCellEqual(aPrevCell, aCell))
++nEqualCells;
else
{
WriteCell(aPrevCell, nEqualCells);
nEqualCells = 0;
aPrevCell = aCell;
}
}
else
{
WriteCell(aPrevCell, nEqualCells);
ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row,
aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable);
nEqualCells = 0;
aPrevCell = aCell;
}
}
}
if (!bIsFirst)
{
WriteCell(aPrevCell, nEqualCells);
ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row,
pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
}
else
ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
CloseRow(pSharedData->GetLastRow(nTable));
WriteNamedExpressions(xSpreadDoc, nTable);
nEqualCells = 0;
}
}
}
IncrementProgressBar(sal_False);
}
}
WriteExternalRefCaches();
WriteNamedExpressions(xSpreadDoc, MAXTABCOUNT);
aExportDatabaseRanges.WriteDatabaseRanges(xSpreadDoc);
ScXMLExportDataPilot aExportDataPilot(*this);
aExportDataPilot.WriteDataPilots(xSpreadDoc);
WriteConsolidation();
ScXMLExportDDELinks aExportDDELinks(*this);
aExportDDELinks.WriteDDELinks(xSpreadDoc);
IncrementProgressBar(sal_True, 0);
GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
}
void ScXMLExport::_ExportStyles( sal_Bool bUsed )
{
if (!pSharedData)
{
sal_Int32 nTableCount(0);
sal_Int32 nShapesCount(0);
sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
CollectSharedData(nTableCount, nShapesCount, nCellCount);
//DBG_ERROR("no shared data setted");
}
ScXMLStyleExport aStylesExp(*this, rtl::OUString(), GetAutoStylePool().get());
if (GetModel().is())
{
uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
if (xMultiServiceFactory.is())
{
uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.Defaults"))), uno::UNO_QUERY);
if (xProperties.is())
aStylesExp.exportDefaultStyle(xProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper);
if (pSharedData->HasShapes())
{
GetShapeExport()->ExportGraphicDefaults();
/* xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Defaults")));
uno::Reference <beans::XPropertySet> xDrawProperties(xInterface, uno::UNO_QUERY);
if (xDrawProperties.is())
aStylesExp.exportDefaultStyle(xDrawProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)), GetShapeExport()->CreateShapePropMapper(*this));*/
}
}
uno::Reference <style::XStyleFamiliesSupplier> xStyleFamiliesSupplier (GetModel(), uno::UNO_QUERY);
if (xStyleFamiliesSupplier.is())
{
uno::Reference <container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies());
if (xStylesFamilies.is())
{
uno::Reference <container::XIndexAccess> xCellStyles(xStylesFamilies->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles"))), uno::UNO_QUERY);
if (xCellStyles.is())
{
sal_Int32 nCount(xCellStyles->getCount());
rtl::OUString sNumberFormat(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
for (sal_Int32 i = 0; i < nCount; ++i)
{
uno::Reference <beans::XPropertySet> xCellProperties(xCellStyles->getByIndex(i), uno::UNO_QUERY);
if (xCellProperties.is())
{
sal_Int32 nNumberFormat = 0;
if (xCellProperties->getPropertyValue(sNumberFormat) >>= nNumberFormat)
addDataStyle(nNumberFormat);
}
}
}
}
}
}
exportDataStyles();
aStylesExp.exportStyleFamily(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles")),
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper, sal_False, XML_STYLE_FAMILY_TABLE_CELL);
SvXMLExport::_ExportStyles(bUsed);
}
void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties,
const uno::Reference<sheet::XSpreadsheet>& xTable,
sal_Int32 nTable, const rtl::OUString* pOldName)
{
//! pass xCellRanges instead
uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY );
rtl::OUString SC_SCELLPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX));
rtl::OUString SC_NUMBERFORMAT(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
rtl::OUString sStyleName;
sal_Int32 nNumberFormat(-1);
sal_Int32 nValidationIndex(-1);
std::vector< XMLPropertyState > xPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties ));
std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
sal_Int32 nCount(0);
while (aItr != aEndItr)
{
if (aItr->mnIndex != -1)
{
switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex))
{
case CTF_SC_VALIDATION :
{
pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex);
// this is not very slow, because it is most the last property or
// if it is not the last property it is the property before the last property,
// so in the worst case only one property has to be copied, but in the best case no
// property has to be copied
aItr = xPropStates.erase(aItr);
aEndItr = xPropStates.end(); // #120346# old aEndItr is invalidated!
}
break;
case CTF_SC_CELLSTYLE :
{
aItr->maValue >>= sStyleName;
aItr->mnIndex = -1;
++aItr;
++nCount;
}
break;
case CTF_SC_NUMBERFORMAT :
{
if (aItr->maValue >>= nNumberFormat)
addDataStyle(nNumberFormat);
++aItr;
++nCount;
}
break;
default:
{
++aItr;
++nCount;
}
break;
}
}
else
{
++aItr;
++nCount;
}
}
if (nCount == 1) // this is the CellStyle and should be removed if alone
xPropStates.clear();
if (nNumberFormat == -1)
xProperties->getPropertyValue(SC_NUMBERFORMAT) >>= nNumberFormat;
if (sStyleName.getLength())
{
if (xPropStates.size())
{
sal_Int32 nIndex;
if (pOldName)
{
if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
{
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, *pOldName);
// add to pCellStyles, so the name is found for normal sheets
rtl::OUString* pTemp(new rtl::OUString(*pOldName));
if (!pCellStyles->AddStyleName(pTemp, nIndex))
delete pTemp;
}
}
else
{
rtl::OUString sName;
sal_Bool bIsAutoStyle(sal_True);
if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
{
rtl::OUString* pTemp(new rtl::OUString(sName));
if (!pCellStyles->AddStyleName(pTemp, nIndex))
delete pTemp;
}
else
nIndex = pCellStyles->GetIndexOfStyleName(sName, SC_SCELLPREFIX, bIsAutoStyle);
uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
table::CellRangeAddress* pAddresses(aAddresses.getArray());
sal_Bool bGetMerge(sal_True);
for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
{
pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
pSharedData->SetLastRow(nTable, pAddresses->EndRow);
pCellStyles->AddRangeStyleName(*pAddresses, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat);
if (bGetMerge)
bGetMerge = GetMerged(pAddresses, xTable);
}
}
}
else
{
rtl::OUString* pTemp(new rtl::OUString(EncodeStyleName(sStyleName)));
sal_Int32 nIndex(0);
if (!pCellStyles->AddStyleName(pTemp, nIndex, sal_False))
{
delete pTemp;
pTemp = NULL;
}
if ( !pOldName )
{
uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
table::CellRangeAddress* pAddresses(aAddresses.getArray());
sal_Bool bGetMerge(sal_True);
for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
{
if (bGetMerge)
bGetMerge = GetMerged(pAddresses, xTable);
pCellStyles->AddRangeStyleName(*pAddresses, nIndex, sal_False, nValidationIndex, nNumberFormat);
if (!sStyleName.equalsAsciiL("Default", 7) || nValidationIndex != -1)
{
pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
pSharedData->SetLastRow(nTable, pAddresses->EndRow);
}
}
}
}
}
}
void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties,
const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible)
{
rtl::OUString SC_SCOLUMNPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX));
std::vector<XMLPropertyState> xPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties));
if(xPropStates.size())
{
std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
while (aItr != aEndItr)
{
if (xColumnStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex) == CTF_SC_ISVISIBLE)
{
aItr->maValue >>= rIsVisible;
break;
}
++aItr;
}
rtl::OUString sParent;
if (pOldName)
{
if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
{
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_COLUMN, *pOldName);
// add to pColumnStyles, so the name is found for normal sheets
rtl::OUString* pTemp(new rtl::OUString(*pOldName));
rIndex = pColumnStyles->AddStyleName(pTemp);
}
}
else
{
rtl::OUString sName;
if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
{
rtl::OUString* pTemp(new rtl::OUString(sName));
rIndex = pColumnStyles->AddStyleName(pTemp);
}
else
rIndex = pColumnStyles->GetIndexOfStyleName(sName, SC_SCOLUMNPREFIX);
}
}
}
void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties,
const rtl::OUString* pOldName, sal_Int32& rIndex)
{
rtl::OUString SC_SROWPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX));
std::vector<XMLPropertyState> xPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties));
if(xPropStates.size())
{
rtl::OUString sParent;
if (pOldName)
{
if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
{
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_ROW, *pOldName);
// add to pRowStyles, so the name is found for normal sheets
rtl::OUString* pTemp(new rtl::OUString(*pOldName));
rIndex = pRowStyles->AddStyleName(pTemp);
}
}
else
{
rtl::OUString sName;
if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
{
rtl::OUString* pTemp(new rtl::OUString(sName));
rIndex = pRowStyles->AddStyleName(pTemp);
}
else
rIndex = pRowStyles->GetIndexOfStyleName(sName, SC_SROWPREFIX);
}
}
}
uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> xEnumAccess, sal_Int32 nIndex )
{
uno::Any aRet;
uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() );
try
{
sal_Int32 nSkip = nIndex;
while ( nSkip > 0 )
{
(void) xEnum->nextElement();
--nSkip;
}
aRet = xEnum->nextElement();
}
catch (container::NoSuchElementException&)
{
// leave aRet empty
}
return aRet;
}
void ScXMLExport::_ExportAutoStyles()
{
if (!GetModel().is())
return;
uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
if (!xSpreadDoc.is())
return;
uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
if (!xIndex.is())
return;
if (getExportFlags() & EXPORT_CONTENT)
{
// re-create automatic styles with old names from stored data
ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
if (pSheetData && pDoc)
{
// formulas have to be calculated now, to detect changed results
// (during normal save, they will be calculated anyway)
SCTAB nTabCount = pDoc->GetTableCount();
for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
if (pDoc->IsStreamValid(nTab))
{
ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
ScBaseCell* pCell = aIter.GetFirst();
while (pCell)
{
if (pCell->GetCellType() == CELLTYPE_FORMULA)
static_cast<ScFormulaCell*>(pCell)->IsValue(); // interpret if dirty
pCell = aIter.GetNext();
}
}
// stored cell styles
const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles();
std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin();
std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end();
while (aCellIter != aCellEnd)
{
ScAddress aPos = aCellIter->maCellPos;
sal_Int32 nTable = aPos.Tab();
bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
if (bCopySheet)
{
uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
uno::Reference <beans::XPropertySet> xProperties(
xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY );
AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName);
}
++aCellIter;
}
// stored column styles
const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles();
std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin();
std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end();
while (aColumnIter != aColumnEnd)
{
ScAddress aPos = aColumnIter->maCellPos;
sal_Int32 nTable = aPos.Tab();
bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
if (bCopySheet)
{
uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY);
sal_Int32 nIndex(-1);
sal_Bool bIsVisible(sal_True);
AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible );
}
++aColumnIter;
}
// stored row styles
const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles();
std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin();
std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end();
while (aRowIter != aRowEnd)
{
ScAddress aPos = aRowIter->maCellPos;
sal_Int32 nTable = aPos.Tab();
bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
if (bCopySheet)
{
uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY);
sal_Int32 nIndex(-1);
AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex );
}
++aRowIter;
}
// stored table styles
const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles();
std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin();
std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end();
while (aTableIter != aTableEnd)
{
ScAddress aPos = aTableIter->maCellPos;
sal_Int32 nTable = aPos.Tab();
bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
if (bCopySheet)
{
//! separate method AddStyleFromTable needed?
uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY);
if (xTableProperties.is())
{
std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
rtl::OUString sParent;
rtl::OUString sName( aTableIter->maName );
GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName);
}
}
++aTableIter;
}
// stored styles for notes
UniReference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this );
GetShapeExport(); // make sure the graphics styles family is added
const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles();
std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin();
std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end();
while (aNoteIter != aNoteEnd)
{
ScAddress aPos = aNoteIter->maCellPos;
sal_Int32 nTable = aPos.Tab();
bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
if (bCopySheet)
{
//! separate method AddStyleFromNote needed?
ScPostIt* pNote = pDoc->GetNote( aPos );
DBG_ASSERT( pNote, "note not found" );
if (pNote)
{
SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
// all uno shapes are created anyway in CollectSharedData
uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY );
if (xShapeProperties.is())
{
if ( aNoteIter->maStyleName.getLength() )
{
std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties));
rtl::OUString sParent;
rtl::OUString sName( aNoteIter->maStyleName );
GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates);
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName);
}
if ( aNoteIter->maTextStyle.getLength() )
{
std::vector<XMLPropertyState> xPropStates(
GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties));
rtl::OUString sParent;
rtl::OUString sName( aNoteIter->maTextStyle );
GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
}
}
}
}
++aNoteIter;
}
// note paragraph styles
//UniReference<SvXMLExportPropertyMapper> xParaPropMapper = XMLTextParagraphExport::CreateParaExtPropMapper( *this );
UniReference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper();
const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles();
std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin();
std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end();
while (aNoteParaIter != aNoteParaEnd)
{
ScAddress aPos = aNoteParaIter->maCellPos;
sal_Int32 nTable = aPos.Tab();
bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
if (bCopySheet)
{
ScPostIt* pNote = pDoc->GetNote( aPos );
DBG_ASSERT( pNote, "note not found" );
if (pNote)
{
SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xParaProp(
lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY );
if ( xParaProp.is() )
{
std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp));
rtl::OUString sParent;
rtl::OUString sName( aNoteParaIter->maName );
GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
}
}
}
++aNoteParaIter;
}
// note text styles
UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles();
std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin();
std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end();
while (aNoteTextIter != aNoteTextEnd)
{
ScAddress aPos = aNoteTextIter->maCellPos;
sal_Int32 nTable = aPos.Tab();
bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
if (bCopySheet)
{
ScPostIt* pNote = pDoc->GetNote( aPos );
DBG_ASSERT( pNote, "note not found" );
if (pNote)
{
SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp );
if (pCursor)
{
pCursor->SetSelection( aNoteTextIter->maSelection );
std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
rtl::OUString sParent;
rtl::OUString sName( aNoteTextIter->maName );
GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
}
}
}
++aNoteTextIter;
}
// stored text styles
//UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles();
std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin();
std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end();
while (aTextIter != aTextEnd)
{
ScAddress aPos = aTextIter->maCellPos;
sal_Int32 nTable = aPos.Tab();
bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
if (bCopySheet)
{
//! separate method AddStyleFromText needed?
//! cache sheet object
uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp );
if (pCursor)
{
pCursor->SetSelection( aTextIter->maSelection );
std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
rtl::OUString sParent;
rtl::OUString sName( aTextIter->maName );
GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
}
}
++aTextIter;
}
}
ExportExternalRefCacheStyles();
if (!pSharedData)
{
sal_Int32 nTableCount(0);
sal_Int32 nShapesCount(0);
sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
CollectSharedData(nTableCount, nShapesCount, nCellCount);
//DBG_ERROR("no shared data setted");
}
sal_Int32 nTableCount(xIndex->getCount());
pCellStyles->AddNewTable(nTableCount - 1);
CollectShapesAutoStyles(nTableCount);
for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
{
bool bUseStream = pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) &&
pSheetData->HasStreamPos(nTable) && xSourceStream.is();
uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
if (xTable.is())
{
// table styles array must be complete, including copied tables - Add should find the stored style
uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
if (xTableProperties.is())
{
std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
if(xPropStates.size())
{
rtl::OUString sParent;
rtl::OUString sName;
GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
aTableStyles.push_back(sName);
}
}
}
// collect other auto-styles only for non-copied sheets
if (xTable.is() && !bUseStream)
{
uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY );
if ( xCellFormatRanges.is() )
{
uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges());
if (xFormatRangesIndex.is())
{
sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount());
GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount);
for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange)
{
uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY);
if (xCellRanges.is())
{
uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY);
if (xProperties.is())
{
AddStyleFromCells(xProperties, xTable, nTable, NULL);
IncrementProgressBar(sal_False);
}
}
}
}
}
uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY);
if (xColumnRowRange.is())
{
if (pDoc)
{
pDoc->SyncColRowFlags();
uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
if (xTableColumns.is())
{
sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable)));
pSharedData->SetLastColumn(nTable, nColumns);
table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
if (aCellAddress.EndColumn > nColumns)
{
++nColumns;
pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn);
}
// else if (nColumns < MAXCOL)
// pColumnStyles->AddNewTable(nTable, ++nColumns);
else
pColumnStyles->AddNewTable(nTable, nColumns);
sal_Int32 nColumn = 0;
while (/*nColumn <= nColumns && */nColumn <= MAXCOL)
{
sal_Int32 nIndex(-1);
sal_Bool bIsVisible(sal_True);
uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY);
if (xColumnProperties.is())
{
AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible );
//if(xPropStates.size())
pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible);
}
sal_Int32 nOld(nColumn);
nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn));
for (sal_Int32 i = nOld + 1; i < nColumn; ++i)
pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
}
if (aCellAddress.EndColumn > nColumns)
{
sal_Bool bIsVisible(sal_True);
sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible));
for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i)
pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
}
}
uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
if (xTableRows.is())
{
sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable)));
pSharedData->SetLastRow(nTable, nRows);
table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
if (aCellAddress.EndRow > nRows)
{
++nRows;
pRowStyles->AddNewTable(nTable, aCellAddress.EndRow);
}
// else if (nRows < MAXROW)
// pRowStyles->AddNewTable(nTable, ++nRows);
else
pRowStyles->AddNewTable(nTable, nRows);
sal_Int32 nRow = 0;
while (nRow <= nRows && nRow <= MAXROW)
{
sal_Int32 nIndex = 0;
uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY);
if(xRowProperties.is())
{
AddStyleFromRow( xRowProperties, NULL, nIndex );
//if(xPropStates.size())
pRowStyles->AddFieldStyleName(nTable, nRow, nIndex);
}
sal_Int32 nOld(nRow);
nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow), false);
if (nRow > nOld + 1)
pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1);
}
if (aCellAddress.EndRow > nRows)
{
sal_Int32 nIndex(pRowStyles->GetStyleNameIndex(nTable, nRows));
pRowStyles->AddFieldStyleName(nTable, nRows + 1, nIndex, aCellAddress.EndRow);
}
}
}
}
uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTable, uno::UNO_QUERY);
if (xCellRangesQuery.is())
{
uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(xCellRangesQuery->queryContentCells(sheet::CellFlags::FORMATTED));
uno::Reference<sheet::XSheetOperation> xSheetOperation(xSheetCellRanges, uno::UNO_QUERY);
if (xSheetCellRanges.is() && xSheetOperation.is())
{
sal_uInt32 nCount(sal_uInt32(xSheetOperation->computeFunction(sheet::GeneralFunction_COUNT)));
uno::Reference<container::XEnumerationAccess> xCellsAccess(xSheetCellRanges->getCells());
if (xCellsAccess.is())
{
GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCount);
uno::Reference<container::XEnumeration> xCells(xCellsAccess->createEnumeration());
if (xCells.is())
{
sal_uInt32 nCount2(0);
while (xCells->hasMoreElements())
{
uno::Reference<text::XText> xText(xCells->nextElement(), uno::UNO_QUERY);
if (xText.is())
GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False);
++nCount2;
IncrementProgressBar(sal_False);
}
if(nCount2 > nCount)
GetProgressBarHelper()->SetReference(GetProgressBarHelper()->GetReference() + nCount2 - nCount);
}
}
}
}
}
IncrementProgressBar(sal_False);
}
pChangeTrackingExportHelper->CollectAutoStyles();
GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN,
GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW,
GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE,
GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
exportAutoDataStyles();
GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL,
GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
GetShapeExport()->exportAutoStyles();
GetFormExport()->exportAutoStyles( );
if (pDoc)
{
ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
// #i100879# write the table style for cached tables only if there are cached tables
// (same logic as in ExportExternalRefCacheStyles)
if (pRefMgr->hasExternalData())
{
// Special table style for the external ref cache tables.
AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName);
AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE);
SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, sal_True, sal_True);
AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE);
SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, sal_True, sal_True);
}
}
}
if (getExportFlags() & EXPORT_MASTERSTYLES)
{
GetPageExport()->collectAutoStyles(sal_True);
GetPageExport()->exportAutoStyles();
}
// #i30251#; only write Text Styles once
if ((getExportFlags() & EXPORT_CONTENT) || (getExportFlags() & EXPORT_MASTERSTYLES))
GetTextParagraphExport()->exportTextAutoStyles();
}
void ScXMLExport::_ExportMasterStyles()
{
GetPageExport()->exportMasterStyles( sal_True );
}
void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > xShape )
{
// detective objects and notes
if( SvxShape* pShapeImp = SvxShape::getImplementation( xShape ) )
{
if( SdrObject* pObject = pShapeImp->GetSdrObject() )
{
// collect note caption objects from all layers (internal or hidden)
if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) )
{
pSharedData->AddNoteObj( xShape, pCaptData->maStart );
// #i60851# When the file is saved while editing a new note,
// the cell is still empty -> last column/row must be updated
DBG_ASSERT( pCaptData->maStart.Tab() == nCurrentTable, "invalid table in object data" );
pSharedData->SetLastColumn( nCurrentTable, pCaptData->maStart.Col() );
pSharedData->SetLastRow( nCurrentTable, pCaptData->maStart.Row() );
}
// other objects from internal layer only (detective)
else if( pObject->GetLayer() == SC_LAYER_INTERN )
{
ScDetectiveFunc aDetFunc( pDoc, static_cast<SCTAB>(nCurrentTable) );
ScAddress aPosition;
ScRange aSourceRange;
sal_Bool bRedLine;
ScDetectiveObjType eObjType = aDetFunc.GetDetectiveObjectType(
pObject, nCurrentTable, aPosition, aSourceRange, bRedLine );
pSharedData->GetDetectiveObjContainer()->AddObject( eObjType, static_cast<SCTAB>(nCurrentTable), aPosition, aSourceRange, bRedLine );
}
}
}
}
//UNUSED2008-05 sal_Bool ScXMLExport::GetMerge (const uno::Reference <sheet::XSpreadsheet>& xTable,
//UNUSED2008-05 const sal_Int32 nCol, const sal_Int32 nRow,
//UNUSED2008-05 table::CellRangeAddress& aCellAddress)
//UNUSED2008-05 {
//UNUSED2008-05 uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY);
//UNUSED2008-05 if (xSheetCellRange.is())
//UNUSED2008-05 {
//UNUSED2008-05 uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange));
//UNUSED2008-05 if (xCursor.is())
//UNUSED2008-05 {
//UNUSED2008-05 uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
//UNUSED2008-05 xCursor->collapseToMergedArea();
//UNUSED2008-05 aCellAddress = xCellAddress->getRangeAddress();
//UNUSED2008-05 return sal_True;
//UNUSED2008-05 }
//UNUSED2008-05 }
//UNUSED2008-05 return sal_False;
//UNUSED2008-05 }
sal_Bool ScXMLExport::GetMerged (const table::CellRangeAddress* pCellAddress,
const uno::Reference <sheet::XSpreadsheet>& xTable)
{
sal_Bool bReady(sal_False);
sal_Int32 nRow(pCellAddress->StartRow);
sal_Int32 nCol(pCellAddress->StartColumn);
sal_Int32 nEndRow(pCellAddress->EndRow);
sal_Int32 nEndCol(pCellAddress->EndColumn);
sal_Bool bRowInc(nEndRow > nRow);
while(!bReady && nRow <= nEndRow && nCol <= nEndCol)
{
uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY);
if (xSheetCellRange.is())
{
uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange));
if(xCursor.is())
{
uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
xCursor->collapseToMergedArea();
table::CellRangeAddress aCellAddress2(xCellAddress->getRangeAddress());
if ((aCellAddress2.EndRow > nRow ||
aCellAddress2.EndColumn > nCol) &&
aCellAddress2.StartRow == nRow &&
aCellAddress2.StartColumn == nCol)
{
pMergedRangesContainer->AddRange(aCellAddress2);
pSharedData->SetLastColumn(aCellAddress2.Sheet, aCellAddress2.EndColumn);
pSharedData->SetLastRow(aCellAddress2.Sheet, aCellAddress2.EndRow);
}
else
bReady = sal_True;
}
}
if (!bReady)
{
if (bRowInc)
++nRow;
else
++nCol;
}
}
DBG_ASSERT(!(!bReady && nEndRow > nRow && nEndCol > nCol), "should not be possible");
return !bReady;
}
//UNUSED2008-05 sal_Bool ScXMLExport::IsMatrix (const uno::Reference <table::XCellRange>& xCellRange,
//UNUSED2008-05 const uno::Reference <sheet::XSpreadsheet>& xTable,
//UNUSED2008-05 const sal_Int32 nCol, const sal_Int32 nRow,
//UNUSED2008-05 table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const
//UNUSED2008-05 {
//UNUSED2008-05 bIsFirst = sal_False;
//UNUSED2008-05 uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
//UNUSED2008-05 if (xArrayFormulaRange.is())
//UNUSED2008-05 {
//UNUSED2008-05 rtl::OUString sArrayFormula(xArrayFormulaRange->getArrayFormula());
//UNUSED2008-05 if (sArrayFormula.getLength())
//UNUSED2008-05 {
//UNUSED2008-05 uno::Reference<sheet::XSheetCellRange> xMatrixSheetCellRange (xArrayFormulaRange, uno::UNO_QUERY);
//UNUSED2008-05 if (xMatrixSheetCellRange.is())
//UNUSED2008-05 {
//UNUSED2008-05 uno::Reference<sheet::XSheetCellCursor> xMatrixSheetCursor(xTable->createCursorByRange(xMatrixSheetCellRange));
//UNUSED2008-05 if (xMatrixSheetCursor.is())
//UNUSED2008-05 {
//UNUSED2008-05 xMatrixSheetCursor->collapseToCurrentArray();
//UNUSED2008-05 uno::Reference<sheet::XCellRangeAddressable> xMatrixCellAddress (xMatrixSheetCursor, uno::UNO_QUERY);
//UNUSED2008-05 if (xMatrixCellAddress.is())
//UNUSED2008-05 {
//UNUSED2008-05 aCellAddress = xMatrixCellAddress->getRangeAddress();
//UNUSED2008-05 if ((aCellAddress.StartColumn == nCol && aCellAddress.StartRow == nRow) &&
//UNUSED2008-05 (aCellAddress.EndColumn > nCol || aCellAddress.EndRow > nRow))
//UNUSED2008-05 {
//UNUSED2008-05 bIsFirst = sal_True;
//UNUSED2008-05 return sal_True;
//UNUSED2008-05 }
//UNUSED2008-05 else if (aCellAddress.StartColumn != nCol || aCellAddress.StartRow != nRow ||
//UNUSED2008-05 aCellAddress.EndColumn != nCol || aCellAddress.EndRow != nRow)
//UNUSED2008-05 return sal_True;
//UNUSED2008-05 else
//UNUSED2008-05 {
//UNUSED2008-05 bIsFirst = sal_True;
//UNUSED2008-05 return sal_True;
//UNUSED2008-05 }
//UNUSED2008-05 }
//UNUSED2008-05 }
//UNUSED2008-05 }
//UNUSED2008-05 }
//UNUSED2008-05 }
//UNUSED2008-05 return sal_False;
//UNUSED2008-05 }
sal_Bool ScXMLExport::IsMatrix (const ScAddress& aCell,
table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const
{
bIsFirst = sal_False;
ScRange aMatrixRange;
if (pDoc && pDoc->GetMatrixFormulaRange(aCell, aMatrixRange))
{
ScUnoConversion::FillApiRange( aCellAddress, aMatrixRange );
if ((aCellAddress.StartColumn == aCell.Col() && aCellAddress.StartRow == aCell.Row()) &&
(aCellAddress.EndColumn > aCell.Col() || aCellAddress.EndRow > aCell.Row()))
{
bIsFirst = sal_True;
return sal_True;
}
else if (aCellAddress.StartColumn != aCell.Col() || aCellAddress.StartRow != aCell.Row() ||
aCellAddress.EndColumn != aCell.Col() || aCellAddress.EndRow != aCell.Row())
return sal_True;
else
{
bIsFirst = sal_True;
return sal_True;
}
}
return sal_False;
/* uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange (xCell, uno::UNO_QUERY);
if (xArrayFormulaRange.is())
{
rtl::OUString sArrayFormula(xArrayFormulaRange->getArrayFormula());
if (sArrayFormula.getLength())
{
uno::Reference<sheet::XSheetCellRange> xMatrixSheetCellRange (xCell, uno::UNO_QUERY);
if (xMatrixSheetCellRange.is())
{
uno::Reference<sheet::XSheetCellCursor> xMatrixSheetCursor(xTable->createCursorByRange(xMatrixSheetCellRange));
if (xMatrixSheetCursor.is())
{
xMatrixSheetCursor->collapseToCurrentArray();
uno::Reference<sheet::XCellRangeAddressable> xMatrixCellAddress (xMatrixSheetCursor, uno::UNO_QUERY);
if (xMatrixCellAddress.is())
{
aCellAddress = xMatrixCellAddress->getRangeAddress();
if ((aCellAddress.StartColumn == nCol && aCellAddress.StartRow == nRow) &&
(aCellAddress.EndColumn > nCol || aCellAddress.EndRow > nRow))
{
bIsFirst = sal_True;
return sal_True;
}
else if (aCellAddress.StartColumn != nCol || aCellAddress.StartRow != nRow ||
aCellAddress.EndColumn != nCol || aCellAddress.EndRow != nRow)
return sal_True;
else
{
bIsFirst = sal_True;
return sal_True;
}
}
}
}
}
}
return sal_False;*/
}
sal_Bool ScXMLExport::GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const
{
if (rMyCell.bHasStringValue)
return sal_True;
else
{
/* if (!rMyCell.bHasXText)
{
rMyCell.xText.set(xCurrentTableCellRange->getCellByPosition(rMyCell.aCellAddress.Column, rMyCell.aCellAddress.Row), uno::UNO_QUERY);
rMyCell.bHasXText = sal_True;
}*/
// if (rMyCell.xText.is())
// {
rMyCell.sStringValue = ScCellObj::GetOutputString_Impl(pDoc, aPos);
rMyCell.bHasStringValue = sal_True;
return sal_True;
// }
}
}
void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
{
// nEqualCellCount is the number of additional cells
SetRepeatAttribute(nEqualCellCount, (aCell.nType != table::CellContentType_EMPTY));
ScAddress aCellPos;
ScUnoConversion::FillScAddress( aCellPos, aCell.aCellAddress );
if (aCell.nStyleIndex != -1)
AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(aCell.nStyleIndex, aCell.bIsAutoStyle));
if (aCell.nValidationIndex > -1)
AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(aCell.nValidationIndex));
sal_Bool bIsMatrix(aCell.bIsMatrixBase || aCell.bIsMatrixCovered);
sal_Bool bIsFirstMatrixCell(aCell.bIsMatrixBase);
if (bIsFirstMatrixCell)
{
sal_Int32 nColumns(aCell.aMatrixRange.EndColumn - aCell.aMatrixRange.StartColumn + 1);
sal_Int32 nRows(aCell.aMatrixRange.EndRow - aCell.aMatrixRange.StartRow + 1);
rtl::OUStringBuffer sColumns;
rtl::OUStringBuffer sRows;
SvXMLUnitConverter::convertNumber(sColumns, nColumns);
SvXMLUnitConverter::convertNumber(sRows, nRows);
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
}
sal_Bool bIsEmpty(sal_False);
switch (aCell.nType)
{
case table::CellContentType_EMPTY :
{
bIsEmpty = sal_True;
}
break;
case table::CellContentType_VALUE :
{
if (!aCell.bHasDoubleValue)
{
aCell.fValue = pDoc->GetValue( aCellPos );
aCell.bHasDoubleValue = sal_True;
}
GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
aCell.nNumberFormat, aCell.fValue);
}
break;
case table::CellContentType_TEXT :
{
if (GetCellText(aCell, aCellPos))
{
rtl::OUString sFormula(lcl_GetRawString(pDoc, aCellPos));
GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
sFormula, aCell.sStringValue, sal_True, sal_True);
}
}
break;
case table::CellContentType_FORMULA :
{
ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aCellPos) : NULL;
if (pBaseCell && pBaseCell->GetCellType() == CELLTYPE_FORMULA)
{
rtl::OUStringBuffer sFormula;
ScFormulaCell* pFormulaCell((ScFormulaCell*) pBaseCell);
if (!bIsMatrix || (bIsMatrix && bIsFirstMatrixCell))
{
const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
pFormulaCell->GetFormula(sFormula, eGrammar);//ange scope name support
rtl::OUString sOUFormula(sFormula.makeStringAndClear());
if (!bIsMatrix)
{
AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula, sal_False ));
}
else
{
AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula.copy(1, sOUFormula.getLength() - 2), sal_False ));
}
}
if (pFormulaCell->IsValue())
{
sal_Bool bIsStandard;
rtl::OUString sCurrency;
GetNumberFormatAttributesExportHelper()->GetCellType(aCell.nNumberFormat, sCurrency, bIsStandard);
if (bIsStandard)
{
if (pDoc)
GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
pFormulaCell->GetStandardFormat(*pDoc->GetFormatTable(), 0),
pDoc->GetValue( aCellPos ));
}
else
GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
aCell.nNumberFormat, pDoc->GetValue( aCellPos ));
}
else
{
if (GetCellText(aCell, aCellPos))
if (aCell.sStringValue.getLength())
{
AddAttribute(sAttrValueType, XML_STRING);
AddAttribute(sAttrStringValue, aCell.sStringValue);
}
}
}
}
break;
default:
{
// added to avoid warnings
}
}
rtl::OUString* pCellString(&sElemCell);
if (aCell.bIsCovered)
{
pCellString = &sElemCoveredCell;
}
else
{
if (aCell.bIsMergedBase)
{
sal_Int32 nColumns(aCell.aMergeRange.EndColumn - aCell.aMergeRange.StartColumn + 1);
sal_Int32 nRows(aCell.aMergeRange.EndRow - aCell.aMergeRange.StartRow + 1);
rtl::OUStringBuffer sColumns;
rtl::OUStringBuffer sRows;
SvXMLUnitConverter::convertNumber(sColumns, nColumns);
SvXMLUnitConverter::convertNumber(sRows, nRows);
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, sColumns.makeStringAndClear());
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, sRows.makeStringAndClear());
}
}
SvXMLElementExport aElemC(*this, *pCellString, sal_True, sal_True);
CheckAttrList();
WriteAreaLink(aCell);
WriteAnnotation(aCell);
WriteDetective(aCell);
sal_Bool bEditCell = sal_False;
if (!bIsEmpty)
{
if ((aCell.nType == table::CellContentType_TEXT && IsEditCell(aCell)) ||
(aCell.nType == table::CellContentType_FORMULA && IsMultiLineFormulaCell(aCell)))
{
bEditCell = sal_True;
uno::Reference<text::XText> xText(xCurrentTableCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row), uno::UNO_QUERY);
if ( xText.is())
GetTextParagraphExport()->exportText(xText, sal_False, sal_False);
}
else
{
SvXMLElementExport aElemP(*this, sElemP, sal_True, sal_False);
sal_Bool bPrevCharWasSpace(sal_True);
if (GetCellText(aCell, aCellPos))
GetTextParagraphExport()->exportText(aCell.sStringValue, bPrevCharWasSpace);
}
}
WriteShapes(aCell);
if (!bIsEmpty)
IncrementProgressBar(bEditCell);
}
void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint)
{
uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY );
//BM sal_Bool bMemChart(sal_False); // das muss man jetzt umbenennen :-)
bool bIsChart( false );
rtl::OUString sPropCLSID (RTL_CONSTASCII_USTRINGPARAM("CLSID"));
rtl::OUString sPropModel (RTL_CONSTASCII_USTRINGPARAM("Model"));
rtl::OUString sPersistName (RTL_CONSTASCII_USTRINGPARAM("PersistName"));
if (xShapeProps.is())
{
sal_Int32 nZOrder = 0;
if (xShapeProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ZOrder"))) >>= nZOrder)
{
rtl::OUStringBuffer sBuffer;
GetMM100UnitConverter().convertNumber(sBuffer, nZOrder);
AddAttribute(XML_NAMESPACE_DRAW, XML_ZINDEX, sBuffer.makeStringAndClear());
}
uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xShapeProps->getPropertySetInfo();
if( xPropSetInfo->hasPropertyByName( sPropCLSID ) )
{
rtl::OUString sCLSID;
if (xShapeProps->getPropertyValue( sPropCLSID ) >>= sCLSID)
{
if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) )
{
// we have a chart
::rtl::OUString sRanges;
if ( pDoc )
{
::rtl::OUString aChartName;
xShapeProps->getPropertyValue( sPersistName ) >>= aChartName;
ScRange aEmptyRange;
ScChartListener aSearcher( aChartName, pDoc, aEmptyRange );
sal_uInt16 nIndex = 0;
ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
if ( pCollection && pCollection->Search( &aSearcher, nIndex ) )
{
ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) );
if ( pListener )
{
const ScRangeListRef& rRangeList = pListener->GetRangeList();
if ( rRangeList.Is() )
{
ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList, pDoc, FormulaGrammar::CONV_OOO );
if ( sRanges.getLength() > 0 )
{
bIsChart = true;
SvXMLAttributeList* pAttrList = new SvXMLAttributeList();
if ( pAttrList )
{
pAttrList->AddAttribute(
GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges );
}
GetShapeExport()->exportShape( xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList );
}
}
}
}
}
if ( sRanges.getLength() == 0 )
{
uno::Reference< frame::XModel > xChartModel;
if( ( xShapeProps->getPropertyValue( sPropModel ) >>= xChartModel ) &&
xChartModel.is())
{
uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY );
if( xChartDoc.is() && xReceiver.is() &&
! xChartDoc->hasInternalDataProvider())
{
// we have a chart that gets its data from Calc
bIsChart = true;
uno::Sequence< ::rtl::OUString > aRepresentations(
xReceiver->getUsedRangeRepresentations());
SvXMLAttributeList* pAttrList = 0;
if(aRepresentations.getLength())
{
// add the ranges used by the chart to the shape
// element to be able to start listening after
// load (when the chart is not yet loaded)
uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY );
sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter );
pAttrList = new SvXMLAttributeList();
pAttrList->AddAttribute(
GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
}
GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
}
}
}
//BM rtl::OUString sOUName;
//BM xShapeProps->getPropertyValue(sPersistName) >>= sOUName;
//BM String sName(sOUName);
//BM if (!pChartListener)
//BM {
//BM String aEmptyString;
//BM ScRange aRange;
//BM pChartListener = new ScChartListener ( aEmptyString, GetDocument(), aRange );
//BM }
//BM if(pChartListener)
//BM {
//BM sal_uInt16 nIndex(0);
//BM pChartListener->SetString( sName );
//BM if ( GetDocument() && GetDocument()->GetChartListenerCollection()->Search( pChartListener, nIndex ) )
//BM {
//BM const ScRangeListRef& rRangeListRef(((ScChartListener*)
//BM (GetDocument()->GetChartListenerCollection()->
//BM At( nIndex )))->GetRangeList());
//BM if (rRangeListRef.Is())
//BM {
//BM bMemChart = sal_True;
//BM rtl::OUString sRanges;
//BM ScRangeStringConverter::GetStringFromRangeList(sRanges, rRangeListRef, GetDocument());
//BM SvXMLAttributeList* pAttrList = NULL;
//BM if (sRanges.getLength())
//BM {
//BM pAttrList = new SvXMLAttributeList();
//BM pAttrList->AddAttribute(
//BM GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
//BM }
//BM GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
//BM }
//BM }
//BM else
//BM {
//BM bMemChart = sal_True;
//BM SvXMLAttributeList* pAttrList = new SvXMLAttributeList();
//BM pAttrList->AddAttribute(
//BM GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), rtl::OUString() );
//BM GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
//BM }
//BM }
/* SchMemChart* pMemChart = pDoc->FindChartData(sName);
if (pMemChart && pMemChart->GetSeriesAddresses().getLength())
{
bMemChart = sal_True;
rtl::OUString sRanges(pMemChart->getXMLStringForChartRange());
if (sRanges.getLength())
AddAttribute(XML_NAMESPACE_DRAW, XML_NOTIFY_ON_UPDATE_OF_RANGES, sRanges);
GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint);
}*/
}
}
}
}
if (!bIsChart)
GetShapeExport()->exportShape(xShape, SEF_DEFAULT, pPoint);
IncrementProgressBar(sal_False);
}
void ScXMLExport::WriteShapes(const ScMyCell& rMyCell)
{
if( rMyCell.bHasShape && !rMyCell.aShapeList.empty() && pDoc )
{
awt::Point aPoint;
Rectangle aRec = pDoc->GetMMRect(static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row),
static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row), static_cast<SCTAB>(rMyCell.aCellAddress.Sheet));
sal_Bool bNegativePage(pDoc->IsNegativePage(rMyCell.aCellAddress.Sheet));
if (bNegativePage)
aPoint.X = aRec.Right();
else
aPoint.X = aRec.Left();
aPoint.Y = aRec.Top();
ScMyShapeList::const_iterator aItr = rMyCell.aShapeList.begin();
ScMyShapeList::const_iterator aEndItr(rMyCell.aShapeList.end());
while (aItr != aEndItr)
{
if (aItr->xShape.is())
{
if (bNegativePage)
aPoint.X = 2 * aItr->xShape->getPosition().X + aItr->xShape->getSize().Width - aPoint.X;
if ( !aItr->xShape->getShapeType().equals(sCaptionShape) )
{
awt::Point aEndPoint;
Rectangle aEndRec(pDoc->GetMMRect(aItr->aEndAddress.Col(), aItr->aEndAddress.Row(),
aItr->aEndAddress.Col(), aItr->aEndAddress.Row(), aItr->aEndAddress.Tab()));
rtl::OUString sEndAddress;
ScRangeStringConverter::GetStringFromAddress(sEndAddress, aItr->aEndAddress, pDoc, FormulaGrammar::CONV_OOO);
AddAttribute(XML_NAMESPACE_TABLE, XML_END_CELL_ADDRESS, sEndAddress);
if (bNegativePage)
aEndPoint.X = -aEndRec.Right();
else
aEndPoint.X = aEndRec.Left();
aEndPoint.Y = aEndRec.Top();
awt::Point aStartPoint(aItr->xShape->getPosition());
awt::Size aSize(aItr->xShape->getSize());
sal_Int32 nEndX;
if (bNegativePage)
nEndX = -aStartPoint.X - aEndPoint.X;
else
nEndX = aStartPoint.X + aSize.Width - aEndPoint.X;
sal_Int32 nEndY(aStartPoint.Y + aSize.Height - aEndPoint.Y);
rtl::OUStringBuffer sBuffer;
GetMM100UnitConverter().convertMeasure(sBuffer, nEndX);
AddAttribute(XML_NAMESPACE_TABLE, XML_END_X, sBuffer.makeStringAndClear());
GetMM100UnitConverter().convertMeasure(sBuffer, nEndY);
AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear());
}
ExportShape(aItr->xShape, &aPoint);
// if there's an error in ExportShape, the attributes from above must be removed
CheckAttrList(); // asserts in non pro if we have attributes left
ClearAttrList(); // clears the attributes
}
++aItr;
}
}
}
void ScXMLExport::WriteTableShapes()
{
ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
if (pTableShapes && !(*pTableShapes)[nCurrentTable].empty())
{
DBG_ASSERT(pTableShapes->size() > static_cast<size_t>(nCurrentTable), "wrong Table");
SvXMLElementExport aShapesElem(*this, XML_NAMESPACE_TABLE, XML_SHAPES, sal_True, sal_False);
ScMyTableXShapes::iterator aItr((*pTableShapes)[nCurrentTable].begin());
ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nCurrentTable].end());
while (aItr != aEndItr)
{
if (aItr->is())
{
if (pDoc->IsNegativePage(static_cast<SCTAB>(nCurrentTable)))
{
awt::Point aPoint((*aItr)->getPosition());
awt::Size aSize((*aItr)->getSize());
aPoint.X += aPoint.X + aSize.Width;
aPoint.Y = 0;
ExportShape(*aItr, &aPoint);
}
else
ExportShape(*aItr, NULL);
}
aItr = (*pTableShapes)[nCurrentTable].erase(aItr);
}
}
}
void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell )
{
if( rMyCell.bHasAreaLink )
{
const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink;
AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr );
AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) );
AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter );
if( rAreaLink.sFilterOptions.getLength() )
AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, rAreaLink.sFilterOptions );
OUStringBuffer sValue;
SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetColCount() );
AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, sValue.makeStringAndClear() );
SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetRowCount() );
AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, sValue.makeStringAndClear() );
if( rAreaLink.nRefresh )
{
SvXMLUnitConverter::convertTime( sValue, (double)rAreaLink.nRefresh / 86400 );
AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sValue.makeStringAndClear() );
}
SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, sal_True, sal_True );
}
}
void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape)
{
if (pCurrentCell && pCurrentCell->xNoteShape.is() && pCurrentCell->xNoteShape.get() == xShape.get() && pCurrentCell->xAnnotation.is())
{
rtl::OUString sAuthor(pCurrentCell->xAnnotation->getAuthor());
if (sAuthor.getLength())
{
SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC,
XML_CREATOR, sal_True,
sal_False );
Characters(sAuthor);
}
String aDate(pCurrentCell->xAnnotation->getDate());
if (pDoc)
{
SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
double fDate;
sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate))
{
rtl::OUStringBuffer sBuf;
GetMM100UnitConverter().convertDateTime(sBuf, fDate,sal_True);
SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC,
XML_DATE, sal_True,
sal_False );
Characters(sBuf.makeStringAndClear());
}
else
{
SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
XML_DATE_STRING, sal_True,
sal_False );
Characters(rtl::OUString(aDate));
}
}
else
{
SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
XML_DATE_STRING, sal_True,
sal_False );
Characters(rtl::OUString(aDate));
}
}
}
void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell)
{
if( rMyCell.bHasAnnotation && rMyCell.xAnnotation.is())
{
/* rtl::OUString sAuthor(rMyCell.xAnnotation->getAuthor());
if (sAuthor.getLength())
{
SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC,
XML_CREATOR, sal_True,
sal_False );
rtl::OUString sAuthor(sAuthor);
Characters(sAuthor);
}
String aDate(rMyCell.xAnnotation->getDate());
if (pDoc)
{
SvNumberFormatter* pNumForm(pDoc->GetFormatTable());
double fDate;
sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate))
{
rtl::OUStringBuffer sBuf;
GetMM100UnitConverter().convertDateTime(sBuf, fDate);
SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC,
XML_DATE, sal_True,
sal_False );
Characters(sBuf.makeStringAndClear());
}
else
{
SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
XML_DATE_STRING, sal_True,
sal_False );
Characters(rtl::OUString(aDate));
}
}
else
{
SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
XML_DATE_STRING, sal_True,
sal_False );
Characters(rtl::OUString(aDate));
}*/
if (rMyCell.xAnnotation->getIsVisible())
AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE);
pCurrentCell = &rMyCell;
if(rMyCell.xNoteShape.is())
GetShapeExport()->exportShape(rMyCell.xNoteShape, SEF_DEFAULT|SEF_EXPORT_ANNOTATION, NULL);
pCurrentCell = NULL;
rMyCell.xNoteShape.clear();
}
}
void ScXMLExport::WriteDetective( const ScMyCell& rMyCell )
{
if( rMyCell.bHasDetectiveObj || rMyCell.bHasDetectiveOp )
{
const ScMyDetectiveObjVec& rObjVec = rMyCell.aDetectiveObjVec;
const ScMyDetectiveOpVec& rOpVec = rMyCell.aDetectiveOpVec;
sal_Int32 nObjCount(rObjVec.size());
sal_Int32 nOpCount(rOpVec.size());
if( nObjCount || nOpCount )
{
SvXMLElementExport aDetElem( *this, XML_NAMESPACE_TABLE, XML_DETECTIVE, sal_True, sal_True );
OUString sString;
ScMyDetectiveObjVec::const_iterator aObjItr(rObjVec.begin());
ScMyDetectiveObjVec::const_iterator aEndObjItr(rObjVec.end());
while(aObjItr != aEndObjItr)
{
if (aObjItr->eObjType != SC_DETOBJ_CIRCLE)
{
if( (aObjItr->eObjType == SC_DETOBJ_ARROW) || (aObjItr->eObjType == SC_DETOBJ_TOOTHERTAB))
{
ScRangeStringConverter::GetStringFromRange( sString, aObjItr->aSourceRange, pDoc, FormulaGrammar::CONV_OOO );
AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sString );
}
ScXMLConverter::GetStringFromDetObjType( sString, aObjItr->eObjType );
AddAttribute( XML_NAMESPACE_TABLE, XML_DIRECTION, sString );
if( aObjItr->bHasError )
AddAttribute( XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TRUE );
}
else
AddAttribute( XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TRUE );
SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, sal_True, sal_True );
++aObjItr;
}
OUStringBuffer aBuffer;
ScMyDetectiveOpVec::const_iterator aOpItr(rOpVec.begin());
ScMyDetectiveOpVec::const_iterator aEndOpItr(rOpVec.end());
while(aOpItr != aEndOpItr)
{
OUString sOpString;
ScXMLConverter::GetStringFromDetOpType( sOpString, aOpItr->eOpType );
AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, sOpString );
SvXMLUnitConverter::convertNumber( aBuffer, aOpItr->nIndex );
AddAttribute( XML_NAMESPACE_TABLE, XML_INDEX, aBuffer.makeStringAndClear() );
SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_OPERATION, sal_True, sal_True );
++aOpItr;
}
}
}
}
void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount, bool bIncProgress)
{
// nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1
if (nEqualCellCount > 0)
{
sal_Int32 nTemp(nEqualCellCount + 1);
OUString sOUEqualCellCount(OUString::valueOf(nTemp));
AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount);
if (bIncProgress)
IncrementProgressBar(sal_False, nEqualCellCount);
}
}
sal_Bool ScXMLExport::IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const
{
return (aCell1.nType == aCell2.nType);
}
sal_Bool ScXMLExport::IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell) const
{
ScAddress aCoreAddress(static_cast<SCCOL>(aAddress.Column),
static_cast<SCROW>(aAddress.Row),
static_cast<SCTAB>(aAddress.Sheet));
ScBaseCell* pBaseCell = GetDocument() ? GetDocument()->GetCell(aCoreAddress) : NULL;
if (pMyCell)
pMyCell->pBaseCell = pBaseCell;
if (pBaseCell)
return (pBaseCell->GetCellType() == CELLTYPE_EDIT);
return sal_False;
}
//UNUSED2008-05 sal_Bool ScXMLExport::IsEditCell(const com::sun::star::uno::Reference <com::sun::star::table::XCell>& xCell) const
//UNUSED2008-05 {
//UNUSED2008-05 uno::Reference<sheet::XCellAddressable> xAddressable (xCell, uno::UNO_QUERY);
//UNUSED2008-05 if ( xAddressable.is() )
//UNUSED2008-05 return IsEditCell(xAddressable->getCellAddress());
//UNUSED2008-05 return sal_False;
//UNUSED2008-05 }
sal_Bool ScXMLExport::IsEditCell(ScMyCell& rCell) const
{
if (rCell.bKnowWhetherIsEditCell)
return rCell.bIsEditCell;
else
{
rCell.bIsEditCell = IsEditCell(rCell.aCellAddress, &rCell);
rCell.bKnowWhetherIsEditCell = sal_True;
return rCell.bIsEditCell;
}
}
sal_Bool ScXMLExport::IsMultiLineFormulaCell(ScMyCell& rCell) const
{
if (rCell.pBaseCell)
{
if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA)
return false;
return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult();
}
ScAddress aAddr(static_cast<SCCOL>(rCell.aCellAddress.Column),
static_cast<SCROW>(rCell.aCellAddress.Row),
static_cast<SCTAB>(rCell.aCellAddress.Sheet));
ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aAddr) : NULL;
if (!pBaseCell)
return false;
rCell.pBaseCell = pBaseCell;
if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA)
return false;
return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult();
}
//UNUSED2008-05 sal_Bool ScXMLExport::IsAnnotationEqual(const uno::Reference<table::XCell>& /* xCell1 */,
//UNUSED2008-05 const uno::Reference<table::XCell>& /* xCell2 */)
//UNUSED2008-05 {
//UNUSED2008-05 // no longer compareable, because the position and size and other attributes can also differ
//UNUSED2008-05
//UNUSED2008-05 /* uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor1(xCell1, uno::UNO_QUERY);
//UNUSED2008-05 uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor2(xCell2, uno::UNO_QUERY);
//UNUSED2008-05 if (xSheetAnnotationAnchor1.is() && xSheetAnnotationAnchor2.is())
//UNUSED2008-05 {
//UNUSED2008-05 uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation1(xSheetAnnotationAnchor1->getAnnotation());
//UNUSED2008-05 uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation2(xSheetAnnotationAnchor2->getAnnotation());
//UNUSED2008-05 uno::Reference<text::XSimpleText> xSimpleText1(xSheetAnnotation1, uno::UNO_QUERY);
//UNUSED2008-05 uno::Reference<text::XSimpleText> xSimpleText2(xSheetAnnotation2, uno::UNO_QUERY);
//UNUSED2008-05 if (xSheetAnnotation1.is() && xSimpleText1.is() &&
//UNUSED2008-05 xSheetAnnotation2.is() && xSimpleText2.is())
//UNUSED2008-05 {
//UNUSED2008-05 rtl::OUString sText1(xSimpleText1->getString());
//UNUSED2008-05 rtl::OUString sText2(xSimpleText2->getString());
//UNUSED2008-05 sal_Int32 nLength1(sText1.getLength());
//UNUSED2008-05 sal_Int32 nLength2(sText2.getLength());
//UNUSED2008-05 if (nLength1 && nLength2)
//UNUSED2008-05 if (sText1 == sText2 &&
//UNUSED2008-05 xSheetAnnotation1->getAuthor() == xSheetAnnotation2->getAuthor() &&
//UNUSED2008-05 xSheetAnnotation1->getDate() == xSheetAnnotation2->getDate() &&
//UNUSED2008-05 xSheetAnnotation1->getIsVisible() == xSheetAnnotation2->getIsVisible())
//UNUSED2008-05 return sal_True;
//UNUSED2008-05 else
//UNUSED2008-05 return sal_False;
//UNUSED2008-05 else
//UNUSED2008-05 if (nLength1 || nLength2)
//UNUSED2008-05 return sal_False;
//UNUSED2008-05 else
//UNUSED2008-05 return sal_True;
//UNUSED2008-05 }
//UNUSED2008-05 }*/
//UNUSED2008-05 return sal_False;
//UNUSED2008-05 }
sal_Bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2)
{
ScAddress aCellPos1;
ScUnoConversion::FillScAddress( aCellPos1, aCell1.aCellAddress );
ScAddress aCellPos2;
ScUnoConversion::FillScAddress( aCellPos2, aCell2.aCellAddress );
sal_Bool bIsEqual = sal_False;
if( !aCell1.bIsMergedBase && !aCell2.bIsMergedBase &&
aCell1.bIsCovered == aCell2.bIsCovered &&
!aCell1.bIsMatrixBase && !aCell2.bIsMatrixBase &&
aCell1.bIsMatrixCovered == aCell2.bIsMatrixCovered &&
aCell1.bHasAnnotation == aCell2.bHasAnnotation &&
!aCell1.bHasShape && !aCell2.bHasShape &&
aCell1.bHasAreaLink == aCell2.bHasAreaLink &&
!aCell1.bHasDetectiveObj && !aCell2.bHasDetectiveObj)
{
if( (aCell1.bHasAreaLink &&
(aCell1.aAreaLink.GetColCount() == 1) &&
(aCell2.aAreaLink.GetColCount() == 1) &&
aCell1.aAreaLink.Compare( aCell2.aAreaLink ) ) ||
!aCell1.bHasAreaLink )
{
if (!aCell1.bHasAnnotation || (aCell1.bHasAnnotation && sal_False/*IsAnnotationEqual(aCell1.xCell, aCell2.xCell)*/)) // no longer compareable
{
if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) ||
((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) &&
(aCell1.nValidationIndex == aCell2.nValidationIndex) &&
IsCellTypeEqual(aCell1, aCell2))
{
switch ( aCell1.nType )
{
case table::CellContentType_EMPTY :
{
bIsEqual = sal_True;
}
break;
case table::CellContentType_VALUE :
{
if(!aCell1.bHasDoubleValue)
{
aCell1.fValue = pDoc->GetValue( aCellPos1 );
aCell1.bHasDoubleValue = sal_True;
}
if (!aCell2.bHasDoubleValue)
{
aCell2.fValue = pDoc->GetValue( aCellPos2 );
aCell2.bHasDoubleValue = sal_True;
}
// #i29101# number format may be different from column default styles,
// but can lead to different value types, so it must also be compared
bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) &&
(aCell1.fValue == aCell2.fValue);
}
break;
case table::CellContentType_TEXT :
{
if (IsEditCell(aCell1) || IsEditCell(aCell2))
bIsEqual = sal_False;
else
{
if (GetCellText(aCell1, aCellPos1) && GetCellText(aCell2, aCellPos2))
{
bIsEqual = (aCell1.sStringValue == aCell2.sStringValue) &&
(lcl_GetRawString(pDoc, aCellPos1) == lcl_GetRawString(pDoc, aCellPos2));
}
else
bIsEqual = sal_False;
}
}
break;
case table::CellContentType_FORMULA :
{
bIsEqual = sal_False;
}
break;
default :
{
bIsEqual = sal_False;
}
break;
}
}
}
}
}
return bIsEqual;
}
void ScXMLExport::WriteCalculationSettings(const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc)
{
uno::Reference<beans::XPropertySet> xPropertySet(xSpreadDoc, uno::UNO_QUERY);
if (xPropertySet.is())
{
sal_Bool bCalcAsShown (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN))) ));
sal_Bool bIgnoreCase (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE))) ));
sal_Bool bLookUpLabels (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS))) ));
sal_Bool bMatchWholeCell (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE))) ));
sal_Bool bUseRegularExpressions (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED))) ));
sal_Bool bIsIterationEnabled (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED))) ));
sal_uInt16 nYear2000 (pDoc ? pDoc->GetDocOptions().GetYear2000() : 0);
sal_Int32 nIterationCount(100);
xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT))) >>= nIterationCount;
double fIterationEpsilon = 0;
xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON))) >>= fIterationEpsilon;
util::Date aNullDate;
xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE))) >>= aNullDate;
if (bCalcAsShown || bIgnoreCase || !bLookUpLabels || !bMatchWholeCell || !bUseRegularExpressions ||
bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001) ||
aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 || nYear2000 != 1930)
{
if (bIgnoreCase)
AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_FALSE);
if (bCalcAsShown)
AddAttribute(XML_NAMESPACE_TABLE, XML_PRECISION_AS_SHOWN, XML_TRUE);
if (!bMatchWholeCell)
AddAttribute(XML_NAMESPACE_TABLE, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL, XML_FALSE);
if (!bLookUpLabels)
AddAttribute(XML_NAMESPACE_TABLE, XML_AUTOMATIC_FIND_LABELS, XML_FALSE);
if (!bUseRegularExpressions)
AddAttribute(XML_NAMESPACE_TABLE, XML_USE_REGULAR_EXPRESSIONS, XML_FALSE);
if (nYear2000 != 1930)
{
rtl::OUStringBuffer sBuffer;
GetMM100UnitConverter().convertNumber(sBuffer, nYear2000);
AddAttribute(XML_NAMESPACE_TABLE, XML_NULL_YEAR, sBuffer.makeStringAndClear());
}
SvXMLElementExport aCalcSettings(*this, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, sal_True, sal_True);
{
if (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899)
{
rtl::OUStringBuffer sDate;
GetMM100UnitConverter().convertDateTime(sDate, 0.0, aNullDate);
AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_VALUE, sDate.makeStringAndClear());
SvXMLElementExport aElemNullDate(*this, XML_NAMESPACE_TABLE, XML_NULL_DATE, sal_True, sal_True);
}
if (bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001))
{
rtl::OUStringBuffer sBuffer;
if (bIsIterationEnabled)
AddAttribute(XML_NAMESPACE_TABLE, XML_STATUS, XML_ENABLE);
if (nIterationCount != 100)
{
GetMM100UnitConverter().convertNumber(sBuffer, nIterationCount);
AddAttribute(XML_NAMESPACE_TABLE, XML_STEPS, sBuffer.makeStringAndClear());
}
if (!::rtl::math::approxEqual(fIterationEpsilon, 0.001))
{
GetMM100UnitConverter().convertDouble(sBuffer, fIterationEpsilon);
AddAttribute(XML_NAMESPACE_TABLE, XML_MAXIMUM_DIFFERENCE, sBuffer.makeStringAndClear());
}
SvXMLElementExport aElemIteration(*this, XML_NAMESPACE_TABLE, XML_ITERATION, sal_True, sal_True);
}
}
}
}
}
void ScXMLExport::WriteTableSource()
{
uno::Reference <sheet::XSheetLinkable> xLinkable (xCurrentTable, uno::UNO_QUERY);
if (xLinkable.is() && GetModel().is())
{
sheet::SheetLinkMode nMode (xLinkable->getLinkMode());
if (nMode != sheet::SheetLinkMode_NONE)
{
rtl::OUString sLink (xLinkable->getLinkUrl());
uno::Reference <beans::XPropertySet> xProps (GetModel(), uno::UNO_QUERY);
if (xProps.is())
{
uno::Reference <container::XIndexAccess> xIndex(xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHEETLINKS))), uno::UNO_QUERY);
if (xIndex.is())
{
sal_Int32 nCount(xIndex->getCount());
if (nCount)
{
sal_Bool bFound(sal_False);
uno::Reference <beans::XPropertySet> xLinkProps;
for (sal_Int32 i = 0; (i < nCount) && !bFound; ++i)
{
xLinkProps.set(xIndex->getByIndex(i), uno::UNO_QUERY);
if (xLinkProps.is())
{
rtl::OUString sNewLink;
if (xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_LINKURL))) >>= sNewLink)
bFound = sLink.equals(sNewLink);
}
}
if (bFound && xLinkProps.is())
{
rtl::OUString sFilter;
rtl::OUString sFilterOptions;
rtl::OUString sTableName (xLinkable->getLinkSheetName());
sal_Int32 nRefresh(0);
xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTER))) >>= sFilter;
xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTOPT))) >>= sFilterOptions;
xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_REFDELAY))) >>= nRefresh;
if (sLink.getLength())
{
AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink));
if (sTableName.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName);
if (sFilter.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, sFilter);
if (sFilterOptions.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, sFilterOptions);
if (nMode != sheet::SheetLinkMode_NORMAL)
AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
if( nRefresh )
{
rtl::OUStringBuffer sBuffer;
SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 );
AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() );
}
SvXMLElementExport aSourceElem(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True);
}
}
}
}
}
}
}
}
// core implementation
void ScXMLExport::WriteScenario()
{
if (pDoc && pDoc->IsScenario(static_cast<SCTAB>(nCurrentTable)))
{
String sComment;
Color aColor;
sal_uInt16 nFlags;
pDoc->GetScenarioData(static_cast<SCTAB>(nCurrentTable), sComment, aColor, nFlags);
if (!(nFlags & SC_SCENARIO_SHOWFRAME))
AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_FALSE);
rtl::OUStringBuffer aBuffer;
SvXMLUnitConverter::convertColor(aBuffer, aColor);
AddAttribute(XML_NAMESPACE_TABLE, XML_BORDER_COLOR, aBuffer.makeStringAndClear());
if (!(nFlags & SC_SCENARIO_TWOWAY))
AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_FALSE);
if (!(nFlags & SC_SCENARIO_ATTRIB))
AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_FALSE);
if (nFlags & SC_SCENARIO_VALUE)
AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_FALSE);
if (nFlags & SC_SCENARIO_PROTECT)
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
SvXMLUnitConverter::convertBool(aBuffer, pDoc->IsActiveScenario(static_cast<SCTAB>(nCurrentTable)));
AddAttribute(XML_NAMESPACE_TABLE, XML_IS_ACTIVE, aBuffer.makeStringAndClear());
const ScRangeList* pRangeList = pDoc->GetScenarioRanges(static_cast<SCTAB>(nCurrentTable));
rtl::OUString sRangeListStr;
ScRangeStringConverter::GetStringFromRangeList( sRangeListStr, pRangeList, pDoc, FormulaGrammar::CONV_OOO );
AddAttribute(XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, sRangeListStr);
if (sComment.Len())
AddAttribute(XML_NAMESPACE_TABLE, XML_COMMENT, rtl::OUString(sComment));
SvXMLElementExport aElem(*this, XML_NAMESPACE_TABLE, XML_SCENARIO, sal_True, sal_True);
}
}
void ScXMLExport::WriteTheLabelRanges( const uno::Reference< sheet::XSpreadsheetDocument >& xSpreadDoc )
{
uno::Reference< beans::XPropertySet > xDocProp( xSpreadDoc, uno::UNO_QUERY );
if( !xDocProp.is() ) return;
sal_Int32 nCount(0);
uno::Reference< container::XIndexAccess > xColRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLLABELRNG ) ) ), uno::UNO_QUERY);
if( xColRangesIAccess.is() )
nCount += xColRangesIAccess->getCount();
uno::Reference< container::XIndexAccess > xRowRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ROWLABELRNG ) ) ), uno::UNO_QUERY);
if( xRowRangesIAccess.is() )
nCount += xRowRangesIAccess->getCount();
if( nCount )
{
SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGES, sal_True, sal_True );
WriteLabelRanges( xColRangesIAccess, sal_True );
WriteLabelRanges( xRowRangesIAccess, sal_False );
}
}
void ScXMLExport::WriteLabelRanges( const uno::Reference< container::XIndexAccess >& xRangesIAccess, sal_Bool bColumn )
{
if( !xRangesIAccess.is() ) return;
sal_Int32 nCount(xRangesIAccess->getCount());
for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
{
uno::Reference< sheet::XLabelRange > xRange(xRangesIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
if( xRange.is() )
{
OUString sRangeStr;
table::CellRangeAddress aCellRange( xRange->getLabelArea() );
ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
AddAttribute( XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, sRangeStr );
aCellRange = xRange->getDataArea();
ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
AddAttribute( XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, sRangeStr );
AddAttribute( XML_NAMESPACE_TABLE, XML_ORIENTATION, bColumn ? XML_COLUMN : XML_ROW );
SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGE, sal_True, sal_True );
}
}
}
void ScXMLExport::WriteNamedExpressions(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc, sal_Int16 nWhichTable)
{
uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
if (xPropertySet.is())
{
uno::Reference <sheet::XNamedRanges2> xNamedRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NAMEDRANGES))), uno::UNO_QUERY);
CheckAttrList();
if (xNamedRanges.is())
{
uno::Sequence <sheet::RangeScopeName> aRangesNames(xNamedRanges->getElementScopeNames());//modified 20091211, range scope name support
sal_Int32 nNamedRangesCount(aRangesNames.getLength());
if (nNamedRangesCount > 0)
{
if (pDoc)
{
ScRangeName* pNamedRanges(pDoc->GetRangeName());
SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, sal_True, sal_True);
for (sal_Int32 i = 0; i < nNamedRangesCount; ++i)
{
CheckAttrList();
//range scope name support -start
rtl::OUString sNamedRange(aRangesNames[i].RangeName);
rtl::OUString sRangeScope(aRangesNames[i].ScopeName);
SCTAB nScopeNumber = MAXTABCOUNT;
String sScopeStr(sRangeScope);
if(sScopeStr !=EMPTY_STRING)
{
pDoc->GetTable(sScopeStr,nScopeNumber);
if( nWhichTable != nScopeNumber || nScopeNumber ==MAXTABCOUNT)
continue;
}
else if( nWhichTable !=MAXTABCOUNT)
continue;
uno::Reference <sheet::XNamedRange2> xNamedRange(xNamedRanges->getByScopeName(sRangeScope,sNamedRange), uno::UNO_QUERY);
//range scope name support
if (xNamedRange.is())
{
uno::Reference <container::XNamed> xNamed (xNamedRange, uno::UNO_QUERY);
uno::Reference <sheet::XCellRangeReferrer> xCellRangeReferrer (xNamedRange, uno::UNO_QUERY);
if (xNamed.is() && xCellRangeReferrer.is())
{
rtl::OUString sOUName(xNamed->getName());
AddAttribute(sAttrName, sOUName);
OUString sOUBaseCellAddress;
ScRangeStringConverter::GetStringFromAddress( sOUBaseCellAddress,
xNamedRange->getReferencePosition(), pDoc, FormulaGrammar::CONV_OOO, ' ', sal_False, SCA_ABS_3D );
AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, sOUBaseCellAddress);
sal_uInt16 nRangeIndex;
String sName(sOUName);
//range scope name support -start
SCTAB nScopeName = MAXTABCOUNT;
String sScopeName(sRangeScope);
if(sScopeName !=EMPTY_STRING)
{
pDoc->GetTable(sScopeName,nScopeName);
}
pNamedRanges->SearchName(sName, nRangeIndex,nScopeName);
//range scope name support - end
ScRangeData* pNamedRange((*pNamedRanges)[nRangeIndex]); //should get directly and not with ScDocument
String sContent;
pNamedRange->GetSymbol(sContent, pDoc->GetStorageGrammar());
rtl::OUString sOUTempContent(sContent);
uno::Reference <table::XCellRange> xCellRange(xCellRangeReferrer->getReferredCells());
if(xCellRange.is())
{
rtl::OUString sOUContent(sOUTempContent.copy(1, sOUTempContent.getLength() - 2));
AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sOUContent);
sal_Int32 nRangeType(xNamedRange->getType());
rtl::OUStringBuffer sBufferRangeType;
if ((nRangeType & sheet::NamedRangeFlag::COLUMN_HEADER) == sheet::NamedRangeFlag::COLUMN_HEADER)
sBufferRangeType.append(GetXMLToken(XML_REPEAT_COLUMN));
if ((nRangeType & sheet::NamedRangeFlag::ROW_HEADER) == sheet::NamedRangeFlag::ROW_HEADER)
{
if (sBufferRangeType.getLength() > 0)
sBufferRangeType.appendAscii(" ");
sBufferRangeType.append(GetXMLToken(XML_REPEAT_ROW));
}
if ((nRangeType & sheet::NamedRangeFlag::FILTER_CRITERIA) == sheet::NamedRangeFlag::FILTER_CRITERIA)
{
if (sBufferRangeType.getLength() > 0)
sBufferRangeType.appendAscii(" ");
sBufferRangeType.append(GetXMLToken(XML_FILTER));
}
if ((nRangeType & sheet::NamedRangeFlag::PRINT_AREA) == sheet::NamedRangeFlag::PRINT_AREA)
{
if (sBufferRangeType.getLength() > 0)
sBufferRangeType.appendAscii(" ");
sBufferRangeType.append(GetXMLToken(XML_PRINT_RANGE));
}
rtl::OUString sRangeType = sBufferRangeType.makeStringAndClear();
if (sRangeType.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, sRangeType);
SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_RANGE, sal_True, sal_True);
}
else
{
AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, sOUTempContent);
SvXMLElementExport aElemNE(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, sal_True, sal_True);
}
}
}
}
}
}
}
}
}
void ScXMLExport::WriteExternalRefCaches()
{
if (!pDoc)
return;
ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
pRefMgr->resetSrcFileData(GetOrigFileName());
sal_uInt16 nCount = pRefMgr->getExternalFileCount();
for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId)
{
const String* pUrl = pRefMgr->getExternalFileName(nFileId);
if (!pUrl)
continue;
vector<String> aTabNames;
pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
if (aTabNames.empty())
continue;
for (vector<String>::const_iterator itr = aTabNames.begin(), itrEnd = aTabNames.end();
itr != itrEnd; ++itr)
{
ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
if (!pTable.get() || !pTable->isReferenced())
continue;
OUStringBuffer aBuf;
aBuf.append(sal_Unicode('\''));
aBuf.append(*pUrl);
aBuf.append(sal_Unicode('\''));
aBuf.append(sal_Unicode('#'));
aBuf.append(*itr);
AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aBuf.makeStringAndClear());
AddAttribute(XML_NAMESPACE_TABLE, XML_PRINT, GetXMLToken(XML_FALSE));
AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sExternalRefTabStyleName);
SvXMLElementExport aElemTable(*this, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True);
{
const ScExternalRefManager::SrcFileData* pExtFileData = pRefMgr->getExternalFileData(nFileId);
if (pExtFileData)
{
String aRelUrl;
if (pExtFileData->maRelativeName.Len())
aRelUrl = pExtFileData->maRelativeName;
else
aRelUrl = GetRelativeReference(pExtFileData->maRelativeName);
AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl);
AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, *itr);
if (pExtFileData->maFilterName.Len())
AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, pExtFileData->maFilterName);
if (pExtFileData->maFilterOptions.Len())
AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, pExtFileData->maFilterOptions);
AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
}
SvXMLElementExport aElemTableSource(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True);
}
// Determine maximum column count of used area, for repeated cells.
SCCOL nMaxColsUsed = 1; // assume that there is at least one cell somewhere..
vector<SCROW> aRows;
pTable->getAllRows(aRows);
for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
itrRow != itrRowEnd; ++itrRow)
{
SCROW nRow = *itrRow;
vector<SCCOL> aCols;
pTable->getAllCols(nRow, aCols);
if (!aCols.empty())
{
SCCOL nCol = aCols.back();
if (nMaxColsUsed <= nCol)
nMaxColsUsed = nCol + 1;
}
}
// Column definitions have to be present to make a valid file
{
if (nMaxColsUsed > 1)
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
OUString::valueOf(static_cast<sal_Int32>(nMaxColsUsed)));
SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True);
}
// Write cache content for this table.
SCROW nLastRow = 0;
bool bFirstRow = true;
for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
itrRow != itrRowEnd; ++itrRow)
{
SCROW nRow = *itrRow;
if (bFirstRow)
{
if (nRow > 0)
{
if (nRow > 1)
{
OUStringBuffer aVal;
aVal.append(nRow);
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
}
SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
OUStringBuffer aVal;
aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
}
}
else
{
SCROW nRowGap = nRow - nLastRow;
if (nRowGap > 1)
{
if (nRowGap > 2)
{
OUStringBuffer aVal;
aVal.append(static_cast<sal_Int32>(nRowGap-1));
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
}
SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
OUStringBuffer aVal;
aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
}
}
SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
vector<SCCOL> aCols;
pTable->getAllCols(nRow, aCols);
SCCOL nLastCol = 0;
bool bFirstCol = true;
for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end();
itrCol != itrColEnd; ++itrCol)
{
SCCOL nCol = *itrCol;
if (bFirstCol)
{
if (nCol > 0)
{
if (nCol > 1)
{
OUStringBuffer aVal;
aVal.append(static_cast<sal_Int32>(nCol));
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
}
SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
}
}
else
{
SCCOL nColGap = nCol - nLastCol;
if (nColGap > 1)
{
if (nColGap > 2)
{
OUStringBuffer aVal;
aVal.append(static_cast<sal_Int32>(nColGap-1));
AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
}
SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
}
}
// Write out this cell.
sal_uInt32 nNumFmt = 0;
ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow, &nNumFmt);
OUString aStrVal;
if (pToken.get())
{
sal_Int32 nIndex = GetNumberFormatStyleIndex(nNumFmt);
if (nIndex >= 0)
{
const OUString aStyleName = *pCellStyles->GetStyleNameByIndex(nIndex, true);
AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, aStyleName);
}
switch(pToken->GetType())
{
case svDouble:
{
AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
OUStringBuffer aVal;
aVal.append(pToken->GetDouble());
aStrVal = aVal.makeStringAndClear();
AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aStrVal);
}
break;
case svString:
{
AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
aStrVal = pToken->GetString();
}
break;
default:
;
}
}
SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
SvXMLElementExport aElemText(*this, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
Characters(aStrVal);
nLastCol = nCol;
bFirstCol = false;
}
nLastRow = nRow;
bFirstRow = false;
}
}
}
}
// core implementation
void ScXMLExport::WriteConsolidation()
{
if (pDoc)
{
const ScConsolidateParam* pCons(pDoc->GetConsolidateDlgData());
if( pCons )
{
OUString sStrData;
ScXMLConverter::GetStringFromFunction( sStrData, pCons->eFunction );
AddAttribute( XML_NAMESPACE_TABLE, XML_FUNCTION, sStrData );
sStrData = OUString();
for( sal_Int32 nIndex = 0; nIndex < pCons->nDataAreaCount; ++nIndex )
ScRangeStringConverter::GetStringFromArea( sStrData, *pCons->ppDataAreas[ nIndex ], pDoc, FormulaGrammar::CONV_OOO, sal_True );
AddAttribute( XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, sStrData );
ScRangeStringConverter::GetStringFromAddress( sStrData, ScAddress( pCons->nCol, pCons->nRow, pCons->nTab ), pDoc, FormulaGrammar::CONV_OOO );
AddAttribute( XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, sStrData );
if( pCons->bByCol && !pCons->bByRow )
AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_COLUMN );
else if( !pCons->bByCol && pCons->bByRow )
AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_ROW );
else if( pCons->bByCol && pCons->bByRow )
AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_BOTH );
if( pCons->bReferenceData )
AddAttribute( XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TRUE );
SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CONSOLIDATION, sal_True, sal_True );
}
}
}
SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool()
{
return new ScXMLAutoStylePoolP(*this);
}
XMLPageExport* ScXMLExport::CreatePageExport()
{
return new XMLTableMasterPageExport( *this );
}
void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
{
ScChangeViewSettings* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : NULL);
if (pViewSettings)
{
sal_Int32 nChangePos(rProps.getLength());
rProps.realloc(nChangePos + 1);
beans::PropertyValue* pProps(rProps.getArray());
if (pProps)
{
uno::Sequence<beans::PropertyValue> aChangeProps(SC_VIEWCHANGES_COUNT);
beans::PropertyValue* pChangeProps(aChangeProps.getArray());
if (pChangeProps)
{
pChangeProps[SC_SHOW_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChanges"));
pChangeProps[SC_SHOW_CHANGES].Value <<= pViewSettings->ShowChanges();
pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowAcceptedChanges"));
pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Value <<= pViewSettings->IsShowAccepted();
pChangeProps[SC_SHOW_REJECTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowRejectedChanges"));
pChangeProps[SC_SHOW_REJECTED_CHANGES].Value <<= pViewSettings->IsShowRejected();
pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetime"));
pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Value <<= pViewSettings->HasDate();
pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeMode"));
pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Value <<= static_cast<sal_Int16>(pViewSettings->GetTheDateMode());
util::DateTime aDateTime;
ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheFirstDateTime(), aDateTime);
pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeFirstDatetime"));
pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Value <<= aDateTime;
ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheLastDateTime(), aDateTime);
pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeSecondDatetime"));
pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Value <<= aDateTime;
pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthor"));
pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Value <<= pViewSettings->HasAuthor();
pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthorName"));
pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Value <<= rtl::OUString (pViewSettings->GetTheAuthorToShow());
pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByComment"));
pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Value <<= pViewSettings->HasComment();
pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByCommentText"));
pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Value <<= rtl::OUString (pViewSettings->GetTheComment());
pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRanges"));
pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Value <<= pViewSettings->HasRange();
rtl::OUString sRangeList;
ScRangeStringConverter::GetStringFromRangeList(sRangeList, &(pViewSettings->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO);
pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRangesList"));
pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Value <<= sRangeList;
pProps[nChangePos].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesViewSettings"));
pProps[nChangePos].Value <<= aChangeProps;
}
}
}
}
void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
{
rProps.realloc(4);
beans::PropertyValue* pProps(rProps.getArray());
if(pProps)
{
if (GetModel().is())
{
ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() ));
if (pDocObj)
{
SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
if (pEmbeddedObj)
{
Rectangle aRect(pEmbeddedObj->GetVisArea());
sal_uInt16 i(0);
pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaTop"));
pProps[i].Value <<= static_cast<sal_Int32>(aRect.getY());
pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaLeft"));
pProps[i].Value <<= static_cast<sal_Int32>(aRect.getX());
pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaWidth"));
pProps[i].Value <<= static_cast<sal_Int32>(aRect.getWidth());
pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaHeight"));
pProps[i].Value <<= static_cast<sal_Int32>(aRect.getHeight());
}
}
}
}
GetChangeTrackViewSettings(rProps);
}
void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps)
{
if (GetModel().is())
{
uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
if (xMultiServiceFactory.is())
{
uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))), uno::UNO_QUERY);
if (xProperties.is())
SvXMLUnitConverter::convertPropertySet(rProps, xProperties);
sal_Int32 nPropsToAdd = 0;
rtl::OUStringBuffer aTrackedChangesKey;
if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected())
{
SvXMLUnitConverter::encodeBase64(aTrackedChangesKey, GetDocument()->GetChangeTrack()->GetProtection());
if (aTrackedChangesKey.getLength())
++nPropsToAdd;
}
bool bVBACompat = false;
uno::Reference <container::XNameAccess> xCodeNameAccess;
DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" );
if( pDoc && pDoc->IsInVBAMode() )
{
// VBA compatibility mode
bVBACompat = true;
++nPropsToAdd;
// code names
xCodeNameAccess = new XMLCodeNameProvider( pDoc );
if( xCodeNameAccess->hasElements() )
++nPropsToAdd;
else
xCodeNameAccess.clear();
}
if( nPropsToAdd > 0 )
{
sal_Int32 nCount(rProps.getLength());
rProps.realloc(nCount + nPropsToAdd);
if (aTrackedChangesKey.getLength())
{
rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey"));
rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear();
++nCount;
}
if( bVBACompat )
{
rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode"));
rProps[nCount].Value <<= bVBACompat;
++nCount;
}
if( xCodeNameAccess.is() )
{
rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration"));
rProps[nCount].Value <<= xCodeNameAccess;
++nCount;
}
}
}
}
}
XMLShapeExport* ScXMLExport::CreateShapeExport()
{
return new ScXMLShapeExport(*this);
}
void ScXMLExport::CreateSharedData(const sal_Int32 nTableCount)
{
pSharedData = new ScMySharedData(nTableCount);
}
XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper()
{
if (!pNumberFormatAttributesExportHelper)
pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this );
return pNumberFormatAttributesExportHelper;
}
void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib)
{
const SfxPoolItem* pItem;
sal_uInt32 nItems(pPool->GetItemCount2( nAttrib ));
for( sal_uInt32 i = 0; i < nItems; ++i )
{
if( 0 != (pItem = pPool->GetItem2( nAttrib, i ) ) )
{
const SvXMLAttrContainerItem *pUnknown((const SvXMLAttrContainerItem *)pItem);
if( (pUnknown->GetAttrCount() > 0) )
{
sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex());
while( USHRT_MAX != nIdx )
{
if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 )
{
const OUString& rPrefix = pUnknown->GetPrefix( nIdx );
// Add namespace declaration for unknown attributes if
// there aren't existing ones for the prefix used by the
// attibutes
_GetNamespaceMap().Add( rPrefix,
pUnknown->GetNamespace( nIdx ),
XML_NAMESPACE_UNKNOWN );
}
nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
}
}
}
}
// #i66550# needed for 'presentation:event-listener' element for URLs in shapes
_GetNamespaceMap().Add(
GetXMLToken( XML_NP_PRESENTATION ),
GetXMLToken( XML_N_PRESENTATION ),
XML_NAMESPACE_PRESENTATION );
}
void ScXMLExport::IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc)
{
nProgressCount += nInc;
if (bEditCell || nProgressCount > 100)
{
GetProgressBarHelper()->Increment(nProgressCount);
nProgressCount = 0;
}
}
sal_uInt32 ScXMLExport::exportDoc( enum XMLTokenEnum eClass )
{
if( (getExportFlags() & (EXPORT_FONTDECLS|EXPORT_STYLES|
EXPORT_MASTERSTYLES|EXPORT_CONTENT)) != 0 )
{
if (GetDocument())
{
CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF);
CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS);
CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS);
ScDrawLayer* pDrawLayer = GetDocument()->GetDrawLayer();
if (pDrawLayer)
{
CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_PARA_XMLATTRIBS);
CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS);
CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES);
}
// sheet events use officeooo namespace
if( (getExportFlags() & EXPORT_CONTENT) != 0 &&
getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
{
bool bAnySheetEvents = false;
SCTAB nTabCount = pDoc->GetTableCount();
for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
if (pDoc->GetSheetEvents(nTab))
bAnySheetEvents = true;
if (bAnySheetEvents)
_GetNamespaceMap().Add(
GetXMLToken( XML_NP_OFFICE_EXT ),
GetXMLToken( XML_N_OFFICE_EXT ),
XML_NAMESPACE_OFFICE_EXT );
}
}
}
return SvXMLExport::exportDoc( eClass );
}
// XExporter
void SAL_CALL ScXMLExport::setSourceDocument( const uno::Reference<lang::XComponent>& xComponent )
throw(lang::IllegalArgumentException, uno::RuntimeException)
{
ScUnoGuard aGuard;
SvXMLExport::setSourceDocument( xComponent );
pDoc = ScXMLConverter::GetScDocument( GetModel() );
DBG_ASSERT( pDoc, "ScXMLExport::setSourceDocument - no ScDocument!" );
if (!pDoc)
throw lang::IllegalArgumentException();
// create ScChangeTrackingExportHelper after document is known
pChangeTrackingExportHelper = new ScChangeTrackingExportHelper(*this);
// Set the document's storage grammar corresponding to the ODF version that
// is to be written.
SvtSaveOptions::ODFDefaultVersion meODFDefaultVersion = getDefaultVersion();
switch (meODFDefaultVersion)
{
// ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF
case SvtSaveOptions::ODFVER_010:
case SvtSaveOptions::ODFVER_011:
pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF);
break;
default:
pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF);
}
}
// XFilter
sal_Bool SAL_CALL ScXMLExport::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
throw(::com::sun::star::uno::RuntimeException)
{
ScUnoGuard aGuard;
if (pDoc)
pDoc->DisableIdle(sal_True);
sal_Bool bReturn(SvXMLExport::filter(aDescriptor));
if (pDoc)
pDoc->DisableIdle(sal_False);
return bReturn;
}
void SAL_CALL ScXMLExport::cancel()
throw(::com::sun::star::uno::RuntimeException)
{
ScUnoGuard aGuard;
if (pDoc)
pDoc->DisableIdle(sal_False);
SvXMLExport::cancel();
}
// XInitialization
void SAL_CALL ScXMLExport::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
{
ScUnoGuard aGuard;
SvXMLExport::initialize(aArguments);
}
// XServiceInfo
::rtl::OUString SAL_CALL ScXMLExport::getImplementationName( )
throw(::com::sun::star::uno::RuntimeException)
{
ScUnoGuard aGuard;
sal_uInt16 nFlags = getExportFlags();
if (nFlags & EXPORT_OASIS)
{
nFlags |= EXPORT_OASIS;
switch( nFlags )
{
case EXPORT_ALL:
return ScXMLOasisExport_getImplementationName();
case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS):
return ScXMLOasisExport_Styles_getImplementationName();
case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS):
return ScXMLOasisExport_Content_getImplementationName();
case EXPORT_META:
return ScXMLOasisExport_Meta_getImplementationName();
case EXPORT_SETTINGS:
return ScXMLOasisExport_Settings_getImplementationName();
default:
// generic name for 'unknown' cases
return ScXMLOasisExport_getImplementationName();
}
}
else
{
switch( nFlags )
{
case EXPORT_ALL:
return ScXMLOOoExport_getImplementationName();
case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS):
return ScXMLOOoExport_Styles_getImplementationName();
case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS):
return ScXMLOOoExport_Content_getImplementationName();
case EXPORT_META:
return ScXMLOOoExport_Meta_getImplementationName();
case EXPORT_SETTINGS:
return ScXMLOOoExport_Settings_getImplementationName();
default:
// generic name for 'unknown' cases
return ScXMLOOoExport_getImplementationName();
}
}
return SvXMLExport::getImplementationName();
}
sal_Bool SAL_CALL ScXMLExport::supportsService( const ::rtl::OUString& ServiceName )
throw(::com::sun::star::uno::RuntimeException)
{
ScUnoGuard aGuard;
return SvXMLExport::supportsService( ServiceName );
}
::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ScXMLExport::getSupportedServiceNames( )
throw(::com::sun::star::uno::RuntimeException)
{
ScUnoGuard aGuard;
return SvXMLExport::getSupportedServiceNames();
}
// XUnoTunnel
sal_Int64 SAL_CALL ScXMLExport::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
throw(::com::sun::star::uno::RuntimeException)
{
ScUnoGuard aGuard;
return SvXMLExport::getSomething(aIdentifier);
}
void ScXMLExport::DisposingModel()
{
SvXMLExport::DisposingModel();
pDoc = NULL;
xCurrentTable = 0;
}