summaryrefslogtreecommitdiffstats
path: root/sc/source/filter/oox/workbookhelper.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/oox/workbookhelper.cxx')
-rw-r--r--sc/source/filter/oox/workbookhelper.cxx1036
1 files changed, 1036 insertions, 0 deletions
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
new file mode 100644
index 000000000..1f07567f1
--- /dev/null
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -0,0 +1,1036 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+#include <workbookhelper.hxx>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XViewDataSupplier.hpp>
+#include <o3tl/any.hxx>
+#include <osl/thread.h>
+#include <osl/diagnose.h>
+#include <oox/helper/progressbar.hxx>
+#include <oox/helper/propertyset.hxx>
+#include <oox/ole/vbaproject.hxx>
+#include <oox/token/properties.hxx>
+#include <addressconverter.hxx>
+#include <connectionsbuffer.hxx>
+#include <defnamesbuffer.hxx>
+#include <excelchartconverter.hxx>
+#include <excelfilter.hxx>
+#include <externallinkbuffer.hxx>
+#include <formulaparser.hxx>
+#include <pagesettings.hxx>
+#include <pivotcachebuffer.hxx>
+#include <pivottablebuffer.hxx>
+#include <scenariobuffer.hxx>
+#include <sharedstringsbuffer.hxx>
+#include <stylesbuffer.hxx>
+#include <tablebuffer.hxx>
+#include <themebuffer.hxx>
+#include <unitconverter.hxx>
+#include <viewsettings.hxx>
+#include <workbooksettings.hxx>
+#include <worksheetbuffer.hxx>
+#include <docsh.hxx>
+#include <document.hxx>
+#include <docuno.hxx>
+#include <rangenam.hxx>
+#include <tokenarray.hxx>
+#include <tokenuno.hxx>
+#include <dbdata.hxx>
+#include <datauno.hxx>
+#include <globalnames.hxx>
+#include <documentimport.hxx>
+#include <drwlayer.hxx>
+#include <globstr.hrc>
+#include <scresid.hxx>
+
+#include <formulabuffer.hxx>
+#include <editutil.hxx>
+#include <editeng/editstat.hxx>
+#include <unotools/charclass.hxx>
+#include <o3tl/string_view.hxx>
+#include <ViewSettingsSequenceDefines.hxx>
+
+#include <memory>
+
+namespace oox::xls {
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+using ::oox::core::FilterBase;
+using ::oox::core::FragmentHandler;
+using ::oox::core::XmlFilterBase;
+
+bool IgnoreCaseCompare::operator()( std::u16string_view rName1, std::u16string_view rName2 ) const
+{
+ // TODO: compare with collator
+ return o3tl::compareToIgnoreAsciiCase(rName1, rName2 ) < 0;
+}
+
+class WorkbookGlobals
+{
+public:
+ // noncopyable ------------------------------------------------------------
+
+ WorkbookGlobals(const WorkbookGlobals&) = delete;
+ const WorkbookGlobals& operator=(const WorkbookGlobals&) = delete;
+
+ explicit WorkbookGlobals( ExcelFilter& rFilter );
+ ~WorkbookGlobals();
+
+ /** Returns true, if this helper refers to a valid document. */
+ bool isValid() const { return mxDoc.is(); }
+
+ // filter -----------------------------------------------------------------
+
+ /** Returns the base filter object (base class of all filters). */
+ FilterBase& getBaseFilter() const { return mrBaseFilter; }
+ /** Returns the filter progress bar. */
+ SegmentProgressBar& getProgressBar() const { return *mxProgressBar; }
+ /** Returns the VBA project storage. */
+ const StorageRef& getVbaProjectStorage() const { return mxVbaPrjStrg; }
+ /** Returns the index of the current Calc sheet, if filter currently processes a sheet. */
+ sal_Int16 getCurrentSheetIndex() const { return mnCurrSheet; }
+ /** Returns true when reading a file generated by a known good generator. */
+ bool isGeneratorKnownGood() const { return mbGeneratorKnownGood; }
+
+ /** Sets the VBA project storage used to import VBA source code and forms. */
+ void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mxVbaPrjStrg = rxVbaPrjStrg; }
+ /** Sets the index of the current Calc sheet, if filter currently processes a sheet. */
+ void setCurrentSheetIndex( SCTAB nSheet ) { mnCurrSheet = nSheet; }
+
+ // document model ---------------------------------------------------------
+
+ ScEditEngineDefaulter& getEditEngine() const
+ {
+ return *mxEditEngine;
+ }
+
+ ScDocument& getScDocument() { return *mpDoc; }
+
+ ScDocumentImport& getDocImport();
+
+ /** Returns a reference to the source/target spreadsheet document model. */
+ const Reference< XSpreadsheetDocument >& getDocument() const { return mxDoc; }
+ /** Returns the cell or page styles container from the Calc document. */
+ Reference< XNameContainer > getStyleFamily( bool bPageStyles ) const;
+ /** Returns the specified cell or page style from the Calc document. */
+ Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const;
+ /** Creates and returns a defined name on-the-fly in the Calc document. */
+ WorkbookHelper::RangeDataRet createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, bool bHidden );
+ /** Creates and returns a defined name on the-fly in the correct Calc sheet. */
+ WorkbookHelper::RangeDataRet createLocalNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab, bool bHidden );
+ /** Creates and returns a database range on-the-fly in the Calc document. */
+ Reference< XDatabaseRange > createDatabaseRangeObject( OUString& orName, const ScRange& rRangeAddr );
+ /** Creates and returns an unnamed database range on-the-fly in the Calc document. */
+ Reference< XDatabaseRange > createUnnamedDatabaseRangeObject( const ScRange& rRangeAddr );
+ /** Finds the (already existing) database range of the given formula token index. */
+ ScDBData* findDatabaseRangeByIndex( sal_uInt16 nIndex );
+ /** Creates and returns a com.sun.star.style.Style object for cells or pages. */
+ Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle );
+ /** Helper to switch chart data table - specifically for xlsx imports */
+ void useInternalChartDataTable( bool bInternal );
+
+ // buffers ----------------------------------------------------------------
+
+ FormulaBuffer& getFormulaBuffer() const { return *mxFormulaBuffer; }
+ /** Returns the global workbook settings object. */
+ WorkbookSettings& getWorkbookSettings() const { return *mxWorkbookSettings; }
+ /** Returns the workbook and sheet view settings object. */
+ ViewSettings& getViewSettings() const { return *mxViewSettings; }
+ /** Returns the worksheet buffer containing sheet names and properties. */
+ WorksheetBuffer& getWorksheets() const { return *mxWorksheets; }
+ /** Returns the office theme object read from the theme substorage. */
+ ThemeBuffer& getTheme() const { return *mxTheme; }
+ /** Returns all cell formatting objects read from the styles substream. */
+ StylesBuffer& getStyles() const { return *mxStyles; }
+ /** Returns the shared strings read from the shared strings substream. */
+ SharedStringsBuffer& getSharedStrings() const { return *mxSharedStrings; }
+ /** Returns the external links read from the external links substream. */
+ ExternalLinkBuffer& getExternalLinks() const { return *mxExtLinks; }
+ /** Returns the defined names read from the workbook globals. */
+ DefinedNamesBuffer& getDefinedNames() const { return *mxDefNames; }
+ /** Returns the tables collection (equivalent to Calc's database ranges). */
+ TableBuffer& getTables() const { return *mxTables; }
+ /** Returns the scenarios collection. */
+ ScenarioBuffer& getScenarios() const { return *mxScenarios; }
+ /** Returns the collection of external data connections. */
+ ConnectionsBuffer& getConnections() const { return *mxConnections; }
+ /** Returns the collection of pivot caches. */
+ PivotCacheBuffer& getPivotCaches() const { return *mxPivotCaches; }
+ /** Returns the collection of pivot tables. */
+ PivotTableBuffer& getPivotTables() { return *mxPivotTables; }
+
+ // converters -------------------------------------------------------------
+
+ /** Returns a shared import formula parser. */
+ FormulaParser& getFormulaParser() const { return *mxFmlaParser; }
+ /** Returns an unshared import formula parser. */
+ FormulaParser* createFormulaParser() { return new FormulaParser(*this); }
+ /** Returns the measurement unit converter. */
+ UnitConverter& getUnitConverter() const { return *mxUnitConverter; }
+ /** Returns the converter for string to cell address/range conversion. */
+ AddressConverter& getAddressConverter() const { return *mxAddrConverter; }
+ /** Returns the chart object converter. */
+ oox::drawingml::chart::ChartConverter* getChartConverter() const { return mxChartConverter.get(); }
+ /** Returns the page/print settings converter. */
+ PageSettingsConverter& getPageSettingsConverter() const { return *mxPageSettConverter; }
+
+ // OOXML/BIFF12 specific --------------------------------------------------
+
+ /** Returns the base OOXML/BIFF12 filter object. */
+ XmlFilterBase& getOoxFilter() const { return *mpOoxFilter; }
+
+ // BIFF2-BIFF8 specific ---------------------------------------------------
+
+ /** Returns the text encoding used to import/export byte strings. */
+ rtl_TextEncoding getTextEncoding() const { return meTextEnc; }
+
+private:
+ /** Initializes some basic members and sets needed document properties. */
+ void initialize();
+ /** Finalizes the filter process (sets some needed document properties). */
+ void finalize();
+
+private:
+ typedef ::std::unique_ptr< ScEditEngineDefaulter > EditEngineDefaulterPtr;
+ typedef ::std::unique_ptr< FormulaBuffer > FormulaBufferPtr;
+ typedef ::std::unique_ptr< SegmentProgressBar > ProgressBarPtr;
+ typedef ::std::unique_ptr< WorkbookSettings > WorkbookSettPtr;
+ typedef ::std::unique_ptr< ViewSettings > ViewSettingsPtr;
+ typedef ::std::unique_ptr< WorksheetBuffer > WorksheetBfrPtr;
+ typedef ::std::shared_ptr< ThemeBuffer > ThemeBfrRef;
+ typedef ::std::unique_ptr< StylesBuffer > StylesBfrPtr;
+ typedef ::std::unique_ptr< SharedStringsBuffer > SharedStrBfrPtr;
+ typedef ::std::unique_ptr< ExternalLinkBuffer > ExtLinkBfrPtr;
+ typedef ::std::unique_ptr< DefinedNamesBuffer > DefNamesBfrPtr;
+ typedef ::std::unique_ptr< TableBuffer > TableBfrPtr;
+ typedef ::std::unique_ptr< ScenarioBuffer > ScenarioBfrPtr;
+ typedef ::std::unique_ptr< ConnectionsBuffer > ConnectionsBfrPtr;
+ typedef ::std::unique_ptr< PivotCacheBuffer > PivotCacheBfrPtr;
+ typedef ::std::unique_ptr< PivotTableBuffer > PivotTableBfrPtr;
+ typedef ::std::unique_ptr< FormulaParser > FormulaParserPtr;
+ typedef ::std::unique_ptr< UnitConverter > UnitConvPtr;
+ typedef ::std::unique_ptr< AddressConverter > AddressConvPtr;
+ typedef ::std::unique_ptr< oox::drawingml::chart::ChartConverter > ExcelChartConvPtr;
+ typedef ::std::unique_ptr< PageSettingsConverter > PageSettConvPtr;
+
+ OUString maCellStyles; /// Style family name for cell styles.
+ OUString maPageStyles; /// Style family name for page styles.
+ OUString maCellStyleServ; /// Service name for a cell style.
+ OUString maPageStyleServ; /// Service name for a page style.
+ Reference< XSpreadsheetDocument > mxDoc; /// Document model.
+ FilterBase& mrBaseFilter; /// Base filter object.
+ ExcelFilter& mrExcelFilter; /// Base object for registration of this structure.
+ ProgressBarPtr mxProgressBar; /// The progress bar.
+ StorageRef mxVbaPrjStrg; /// Storage containing the VBA project.
+ sal_Int16 mnCurrSheet; /// Current sheet index in Calc document.
+ bool mbGeneratorKnownGood; /// Whether reading a file generated by Excel or Calc.
+
+ // buffers
+ FormulaBufferPtr mxFormulaBuffer;
+ WorkbookSettPtr mxWorkbookSettings; /// Global workbook settings.
+ ViewSettingsPtr mxViewSettings; /// Workbook and sheet view settings.
+ WorksheetBfrPtr mxWorksheets; /// Sheet info buffer.
+ ThemeBfrRef mxTheme; /// Formatting theme from theme substream.
+ StylesBfrPtr mxStyles; /// All cell style objects from styles substream.
+ SharedStrBfrPtr mxSharedStrings; /// All strings from shared strings substream.
+ ExtLinkBfrPtr mxExtLinks; /// All external links.
+ DefNamesBfrPtr mxDefNames; /// All defined names.
+ TableBfrPtr mxTables; /// All tables (database ranges).
+ ScenarioBfrPtr mxScenarios; /// All scenarios.
+ ConnectionsBfrPtr mxConnections; /// All external data connections.
+ PivotCacheBfrPtr mxPivotCaches; /// All pivot caches in the document.
+ PivotTableBfrPtr mxPivotTables; /// All pivot tables in the document.
+
+ // converters
+ FormulaParserPtr mxFmlaParser; /// Import formula parser.
+ UnitConvPtr mxUnitConverter; /// General unit converter.
+ AddressConvPtr mxAddrConverter; /// Cell address and cell range address converter.
+ ExcelChartConvPtr mxChartConverter; /// Chart object converter.
+ PageSettConvPtr mxPageSettConverter; /// Page/print settings converter.
+
+ EditEngineDefaulterPtr mxEditEngine;
+
+ // OOXML/BIFF12 specific
+ XmlFilterBase* mpOoxFilter; /// Base OOXML/BIFF12 filter object.
+
+ // BIFF2-BIFF8 specific
+ rtl_TextEncoding meTextEnc; /// BIFF byte string text encoding.
+ ScDocument* mpDoc;
+ ScDocShell* mpDocShell;
+ std::unique_ptr<ScDocumentImport> mxDocImport;
+};
+
+WorkbookGlobals::WorkbookGlobals( ExcelFilter& rFilter ) :
+ mrBaseFilter( rFilter ),
+ mrExcelFilter( rFilter ),
+ mpOoxFilter( &rFilter ),
+ mpDoc(nullptr),
+ mpDocShell(nullptr)
+{
+ // register at the filter, needed for virtual callbacks (even during construction)
+ mrExcelFilter.registerWorkbookGlobals( *this );
+ initialize();
+}
+
+WorkbookGlobals::~WorkbookGlobals()
+{
+ finalize();
+ mrExcelFilter.unregisterWorkbookGlobals();
+}
+
+ScDocumentImport& WorkbookGlobals::getDocImport()
+{
+ return *mxDocImport;
+}
+
+Reference< XNameContainer > WorkbookGlobals::getStyleFamily( bool bPageStyles ) const
+{
+ Reference< XNameContainer > xStylesNC;
+ try
+ {
+ Reference< XStyleFamiliesSupplier > xFamiliesSup( mxDoc, UNO_QUERY_THROW );
+ Reference< XNameAccess > xFamiliesNA( xFamiliesSup->getStyleFamilies(), UNO_SET_THROW );
+ xStylesNC.set( xFamiliesNA->getByName( bPageStyles ? maPageStyles : maCellStyles ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xStylesNC.is(), "WorkbookGlobals::getStyleFamily - cannot access style family" );
+ return xStylesNC;
+}
+
+Reference< XStyle > WorkbookGlobals::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
+{
+ Reference< XStyle > xStyle;
+ try
+ {
+ Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
+ xStyle.set( xStylesNC->getByName( rStyleName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xStyle.is(), "WorkbookGlobals::getStyleObject - cannot access style object" );
+ return xStyle;
+}
+
+namespace {
+
+WorkbookHelper::RangeDataRet lcl_addNewByNameAndTokens( ScDocument& rDoc, ScRangeName* pNames, const OUString& rName, const Sequence<FormulaToken>& rTokens, sal_Int16 nIndex, sal_Int32 nUnoType, bool bHidden )
+{
+ bool bDone = false;
+ ScRangeData::Type nNewType = ScRangeData::Type::Name;
+ if ( nUnoType & NamedRangeFlag::FILTER_CRITERIA ) nNewType |= ScRangeData::Type::Criteria;
+ if ( nUnoType & NamedRangeFlag::PRINT_AREA ) nNewType |= ScRangeData::Type::PrintArea;
+ if ( nUnoType & NamedRangeFlag::COLUMN_HEADER ) nNewType |= ScRangeData::Type::ColHeader;
+ if ( nUnoType & NamedRangeFlag::ROW_HEADER ) nNewType |= ScRangeData::Type::RowHeader;
+ ScTokenArray aTokenArray(rDoc);
+ (void)ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
+ ScRangeData* pNew = new ScRangeData( rDoc, rName, aTokenArray, ScAddress(), nNewType );
+ pNew->GuessPosition();
+ if ( nIndex )
+ pNew->SetIndex( nIndex );
+ // create but not insert hidden FILTER_CRITERIA named ranges to ScRangeName
+ if ( bHidden && nNewType == ScRangeData::Type::Criteria )
+ {
+ return WorkbookHelper::RangeDataRet(pNew, true);
+ }
+ if ( pNames->insert(pNew) )
+ bDone = true;
+ if (!bDone)
+ {
+ delete pNew;
+ throw RuntimeException();
+ }
+ return WorkbookHelper::RangeDataRet(pNew, false);
+}
+
+OUString findUnusedName( const ScRangeName* pRangeName, const OUString& rSuggestedName )
+{
+ OUString aNewName = rSuggestedName;
+ sal_Int32 nIndex = 0;
+ while(pRangeName->findByUpperName(ScGlobal::getCharClass().uppercase(aNewName)))
+ aNewName = rSuggestedName + OUStringChar('_') + OUString::number( nIndex++ );
+
+ return aNewName;
+}
+
+}
+
+WorkbookHelper::RangeDataRet WorkbookGlobals::createNamedRangeObject(
+ OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, bool bHidden )
+{
+ // create the name and insert it into the Calc document
+ WorkbookHelper::RangeDataRet aScRangeData(nullptr, false);
+ if( !orName.isEmpty() )
+ {
+ ScDocument& rDoc = getScDocument();
+ ScRangeName* pNames = rDoc.GetRangeName();
+ // find an unused name
+ orName = findUnusedName( pNames, orName );
+ // create the named range
+ aScRangeData = lcl_addNewByNameAndTokens( rDoc, pNames, orName, rTokens, nIndex, nNameFlags, bHidden );
+ }
+ return aScRangeData;
+}
+
+WorkbookHelper::RangeDataRet WorkbookGlobals::createLocalNamedRangeObject(
+ OUString& orName, const Sequence< FormulaToken >& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab, bool bHidden )
+{
+ // create the name and insert it into the Calc document
+ WorkbookHelper::RangeDataRet aScRangeData(nullptr, false);
+ if( !orName.isEmpty() )
+ {
+ ScDocument& rDoc = getScDocument();
+ ScRangeName* pNames = rDoc.GetRangeName( nTab );
+ if(!pNames)
+ throw RuntimeException("invalid sheet index used");
+ // find an unused name
+ orName = findUnusedName( pNames, orName );
+ // create the named range
+ aScRangeData = lcl_addNewByNameAndTokens( rDoc, pNames, orName, rTokens, nIndex, nNameFlags, bHidden );
+ }
+ return aScRangeData;
+}
+
+Reference< XDatabaseRange > WorkbookGlobals::createDatabaseRangeObject( OUString& orName, const ScRange& rRangeAddr )
+{
+ // validate cell range
+ ScRange aDestRange = rRangeAddr;
+ bool bValidRange = getAddressConverter().validateCellRange( aDestRange, true, true );
+
+ // create database range and insert it into the Calc document
+ Reference< XDatabaseRange > xDatabaseRange;
+ if( bValidRange && !orName.isEmpty() ) try
+ {
+ // find an unused name
+ PropertySet aDocProps( mxDoc );
+ Reference< XDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_DatabaseRanges ), UNO_QUERY_THROW );
+ orName = ContainerHelper::getUnusedName( xDatabaseRanges, orName, '_' );
+ // create the database range
+ CellRangeAddress aApiRange( aDestRange.aStart.Tab(), aDestRange.aStart.Col(), aDestRange.aStart.Row(),
+ aDestRange.aEnd.Col(), aDestRange.aEnd.Row() );
+ xDatabaseRanges->addNewByName( orName, aApiRange );
+ xDatabaseRange.set( xDatabaseRanges->getByName( orName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xDatabaseRange.is(), "WorkbookGlobals::createDatabaseRangeObject - cannot create database range" );
+ return xDatabaseRange;
+}
+
+Reference< XDatabaseRange > WorkbookGlobals::createUnnamedDatabaseRangeObject( const ScRange& rRangeAddr )
+{
+ // validate cell range
+ ScRange aDestRange = rRangeAddr;
+ bool bValidRange = getAddressConverter().validateCellRange( aDestRange, true, true );
+
+ // create database range and insert it into the Calc document
+ Reference< XDatabaseRange > xDatabaseRange;
+ if( bValidRange ) try
+ {
+ ScDocument& rDoc = getScDocument();
+ if( rDoc.GetTableCount() <= aDestRange.aStart.Tab() )
+ throw css::lang::IndexOutOfBoundsException();
+ std::unique_ptr<ScDBData> pNewDBData(new ScDBData( STR_DB_LOCAL_NONAME, aDestRange.aStart.Tab(),
+ aDestRange.aStart.Col(), aDestRange.aStart.Row(),
+ aDestRange.aEnd.Col(), aDestRange.aEnd.Row() ));
+ rDoc.SetAnonymousDBData( aDestRange.aStart.Tab() , std::move(pNewDBData) );
+ ScDocShell* pDocSh = static_cast< ScDocShell* >(rDoc.GetDocumentShell());
+ xDatabaseRange.set(new ScDatabaseRangeObj(pDocSh, aDestRange.aStart.Tab()));
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xDatabaseRange.is(), "WorkbookData::createDatabaseRangeObject - cannot create database range" );
+ return xDatabaseRange;
+}
+
+ScDBData* WorkbookGlobals::findDatabaseRangeByIndex( sal_uInt16 nIndex )
+{
+ ScDBCollection* pDBCollection = getScDocument().GetDBCollection();
+ if (!pDBCollection)
+ return nullptr;
+ return pDBCollection->getNamedDBs().findByIndex( nIndex );
+}
+
+Reference< XStyle > WorkbookGlobals::createStyleObject( OUString& orStyleName, bool bPageStyle )
+{
+ Reference< XStyle > xStyle;
+ try
+ {
+ Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
+ xStyle.set( mrBaseFilter.getModelFactory()->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW );
+ orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ) );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xStyle.is(), "WorkbookGlobals::createStyleObject - cannot create style" );
+ return xStyle;
+}
+
+void WorkbookGlobals::useInternalChartDataTable( bool bInternal )
+{
+ if( bInternal )
+ mxChartConverter.reset( new oox::drawingml::chart::ChartConverter() );
+ else
+ mxChartConverter.reset( new ExcelChartConverter( *this ) );
+}
+
+// BIFF specific --------------------------------------------------------------
+
+// private --------------------------------------------------------------------
+
+void WorkbookGlobals::initialize()
+{
+ maCellStyles = "CellStyles";
+ maPageStyles = "PageStyles";
+ maCellStyleServ = "com.sun.star.style.CellStyle";
+ maPageStyleServ = "com.sun.star.style.PageStyle";
+ mnCurrSheet = -1;
+ mbGeneratorKnownGood = false;
+ meTextEnc = osl_getThreadTextEncoding();
+
+ // the spreadsheet document
+ mxDoc.set( mrBaseFilter.getModel(), UNO_QUERY );
+ OSL_ENSURE( mxDoc.is(), "WorkbookGlobals::initialize - no spreadsheet document" );
+
+ if (mxDoc)
+ {
+ ScModelObj* pModel = dynamic_cast<ScModelObj*>(mxDoc.get());
+ if (pModel)
+ mpDocShell = static_cast<ScDocShell*>(pModel->GetEmbeddedObject());
+ if (mpDocShell)
+ mpDoc = &mpDocShell->GetDocument();
+ }
+
+ if (!mpDoc)
+ throw RuntimeException("Workbookhelper::getScDocument(): Failed to access ScDocument from model");
+
+ Reference< XDocumentPropertiesSupplier > xPropSupplier( mxDoc, UNO_QUERY);
+ Reference< XDocumentProperties > xDocProps = xPropSupplier->getDocumentProperties();
+ const OUString aGenerator( xDocProps->getGenerator());
+
+ if (aGenerator.startsWithIgnoreAsciiCase("Microsoft"))
+ {
+ mbGeneratorKnownGood = true;
+ ScCalcConfig aCalcConfig = mpDoc->GetCalcConfig();
+ aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_XL_A1 ) ;
+ mpDoc->SetCalcConfig(aCalcConfig);
+ }
+ else if (aGenerator.startsWithIgnoreAsciiCase("LibreOffice"))
+ {
+ mbGeneratorKnownGood = true;
+ }
+
+ mxDocImport.reset(new ScDocumentImport(*mpDoc));
+
+ mxFormulaBuffer.reset( new FormulaBuffer( *this ) );
+ mxWorkbookSettings.reset( new WorkbookSettings( *this ) );
+ mxViewSettings.reset( new ViewSettings( *this ) );
+ mxWorksheets.reset( new WorksheetBuffer( *this ) );
+ mxTheme = std::make_shared<ThemeBuffer>( *this );
+ mxStyles.reset( new StylesBuffer( *this ) );
+ mxSharedStrings.reset( new SharedStringsBuffer( *this ) );
+ mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
+ mxDefNames.reset( new DefinedNamesBuffer( *this ) );
+ mxTables.reset( new TableBuffer( *this ) );
+ mxScenarios.reset( new ScenarioBuffer( *this ) );
+ mxConnections.reset( new ConnectionsBuffer( *this ) );
+ mxPivotCaches.reset( new PivotCacheBuffer( *this ) );
+ mxPivotTables.reset( new PivotTableBuffer( *this ) );
+
+ mxUnitConverter.reset( new UnitConverter( *this ) );
+ mxAddrConverter.reset( new AddressConverter( *this ) );
+ mxChartConverter.reset( new ExcelChartConverter( *this ) );
+ mxPageSettConverter.reset( new PageSettingsConverter( *this ) );
+
+ // initialise edit engine
+ ScDocument& rDoc = getScDocument();
+ mxEditEngine.reset( new ScEditEngineDefaulter( rDoc.GetEnginePool() ) );
+ mxEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
+ mxEditEngine->SetEditTextObjectPool( rDoc.GetEditPool() );
+ mxEditEngine->SetUpdateLayout( false );
+ mxEditEngine->EnableUndo( false );
+ mxEditEngine->SetControlWord( mxEditEngine->GetControlWord() & ~EEControlBits::ALLOWBIGOBJS );
+
+ // set some document properties needed during import
+ if( mrBaseFilter.isImportFilter() )
+ {
+ // enable editing read-only documents (e.g. from read-only files)
+ mpDoc->EnableChangeReadOnly(true);
+ // #i76026# disable Undo while loading the document
+ mpDoc->EnableUndo(false);
+ // #i79826# disable calculating automatic row height while loading the document
+ mpDoc->LockAdjustHeight();
+ // disable automatic update of linked sheets and DDE links
+ mpDoc->EnableExecuteLink(false);
+
+ mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), ScResId(STR_LOAD_DOC) ) );
+ mxFmlaParser.reset( createFormulaParser() );
+
+ //prevent unnecessary broadcasts and "half way listeners" as
+ //is done in ScDocShell::BeforeXMLLoading() for ods
+ mpDoc->SetInsertingFromOtherDoc(true);
+ }
+ else if( mrBaseFilter.isExportFilter() )
+ {
+ mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), ScResId(STR_SAVE_DOC) ) );
+ }
+}
+
+void WorkbookGlobals::finalize()
+{
+ // set some document properties needed after import
+ if( !mrBaseFilter.isImportFilter() )
+ return;
+
+ // #i74668# do not insert default sheets
+ mpDocShell->SetEmpty(false);
+ // enable automatic update of linked sheets and DDE links
+ mpDoc->EnableExecuteLink(true);
+ // #i79826# enable updating automatic row height after loading the document
+ mpDoc->UnlockAdjustHeight();
+
+ // #i76026# enable Undo after loading the document
+ mpDoc->EnableUndo(true);
+
+ // disable editing read-only documents (e.g. from read-only files)
+ mpDoc->EnableChangeReadOnly(false);
+ // #111099# open forms in alive mode (has no effect, if no controls in document)
+ ScDrawLayer* pModel = mpDoc->GetDrawLayer();
+ if (pModel)
+ pModel->SetOpenInDesignMode(false);
+}
+
+
+WorkbookHelper::~WorkbookHelper()
+{
+}
+
+/*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelFilter& rFilter )
+{
+ WorkbookGlobalsRef xBookGlob = std::make_shared<WorkbookGlobals>( rFilter );
+ if( !xBookGlob->isValid() )
+ xBookGlob.reset();
+ return xBookGlob;
+}
+
+// filter ---------------------------------------------------------------------
+
+FilterBase& WorkbookHelper::getBaseFilter() const
+{
+ return mrBookGlob.getBaseFilter();
+}
+
+SegmentProgressBar& WorkbookHelper::getProgressBar() const
+{
+ return mrBookGlob.getProgressBar();
+}
+
+sal_Int16 WorkbookHelper::getCurrentSheetIndex() const
+{
+ return mrBookGlob.getCurrentSheetIndex();
+}
+
+bool WorkbookHelper::isGeneratorKnownGood() const
+{
+ return mrBookGlob.isGeneratorKnownGood();
+}
+
+void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg )
+{
+ mrBookGlob.setVbaProjectStorage( rxVbaPrjStrg );
+}
+
+void WorkbookHelper::setCurrentSheetIndex( SCTAB nSheet )
+{
+ mrBookGlob.setCurrentSheetIndex( nSheet );
+}
+
+void WorkbookHelper::finalizeWorkbookImport()
+{
+ // workbook settings, document and sheet view settings
+ mrBookGlob.getWorkbookSettings().finalizeImport();
+ mrBookGlob.getViewSettings().finalizeImport();
+
+ // Import the VBA project (after finalizing workbook settings which
+ // contains the workbook code name). Do it before processing formulas in
+ // order to correctly resolve VBA custom function names.
+ StorageRef xVbaPrjStrg = mrBookGlob.getVbaProjectStorage();
+ if( xVbaPrjStrg && xVbaPrjStrg->isStorage() )
+ getBaseFilter().getVbaProject().importModulesAndForms( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() );
+
+ // need to import formulas before scenarios
+ mrBookGlob.getFormulaBuffer().finalizeImport();
+
+ // Insert all pivot tables. Must be done after loading all sheets and
+ // formulas, because data pilots expect existing source data on
+ // creation.
+ getPivotTables().finalizeImport();
+
+ /* Insert scenarios after all sheet processing is done, because new hidden
+ sheets are created for scenarios which would confuse code that relies
+ on certain sheet indexes. Must be done after pivot tables too. */
+ mrBookGlob.getScenarios().finalizeImport();
+
+ /* Set 'Default' page style to automatic page numbering (default is manual
+ number 1). Otherwise hidden sheets (e.g. for scenarios) which have
+ 'Default' page style will break automatic page numbering for following
+ sheets. Automatic numbering is set by passing the value 0. */
+ PropertySet aDefPageStyle( getStyleObject( "Default", true ) );
+ aDefPageStyle.setProperty< sal_Int16 >( PROP_FirstPageNumber, 0 );
+
+ // Has any string ref syntax been imported?
+ // If not, we need to take action
+ ScCalcConfig aCalcConfig = getScDocument().GetCalcConfig();
+
+ if ( !aCalcConfig.mbHasStringRefSyntax )
+ {
+ aCalcConfig.meStringRefAddressSyntax = formula::FormulaGrammar::CONV_A1_XL_A1;
+ getScDocument().SetCalcConfig(aCalcConfig);
+ }
+
+ // set selected sheet and positionleft/positiontop for OLE objects
+ Reference<XViewDataSupplier> xViewDataSupplier(getDocument(), UNO_QUERY);
+ if (!xViewDataSupplier.is())
+ return;
+
+ Reference<XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData());
+ if (!(xIndexAccess.is() && xIndexAccess->getCount() > 0))
+ return;
+
+ Sequence< PropertyValue > aSeq;
+ if (!(xIndexAccess->getByIndex(0) >>= aSeq))
+ return;
+
+ OUString sTabName;
+ Reference< XNameAccess > xSheetsNC;
+ for (const auto& rProp : std::as_const(aSeq))
+ {
+ OUString sName(rProp.Name);
+ if (sName == SC_ACTIVETABLE)
+ {
+ if(rProp.Value >>= sTabName)
+ {
+ SCTAB nTab(0);
+ if (getScDocument().GetTable(sTabName, nTab))
+ getScDocument().SetVisibleTab(nTab);
+ }
+ }
+ else if (sName == SC_TABLES)
+ {
+ rProp.Value >>= xSheetsNC;
+ }
+ }
+ if (!(xSheetsNC.is() && xSheetsNC->hasByName(sTabName)))
+ return;
+
+ Sequence<PropertyValue> aProperties;
+ Any aAny = xSheetsNC->getByName(sTabName);
+ if ( !(aAny >>= aProperties) )
+ return;
+
+ for (const auto& rProp : std::as_const(aProperties))
+ {
+ OUString sName(rProp.Name);
+ if (sName == SC_POSITIONLEFT)
+ {
+ SCCOL nPosLeft = *o3tl::doAccess<SCCOL>(rProp.Value);
+ getScDocument().SetPosLeft(nPosLeft);
+ }
+ else if (sName == SC_POSITIONTOP)
+ {
+ SCROW nPosTop = *o3tl::doAccess<SCROW>(rProp.Value);
+ getScDocument().SetPosTop(nPosTop);
+ }
+ }
+}
+
+// document model -------------------------------------------------------------
+
+ScDocument& WorkbookHelper::getScDocument()
+{
+ return mrBookGlob.getScDocument();
+}
+
+const ScDocument& WorkbookHelper::getScDocument() const
+{
+ return mrBookGlob.getScDocument();
+}
+
+ScDocumentImport& WorkbookHelper::getDocImport()
+{
+ return mrBookGlob.getDocImport();
+}
+
+const ScDocumentImport& WorkbookHelper::getDocImport() const
+{
+ return mrBookGlob.getDocImport();
+}
+
+ScEditEngineDefaulter& WorkbookHelper::getEditEngine() const
+{
+ return mrBookGlob.getEditEngine();
+}
+
+const Reference< XSpreadsheetDocument > & WorkbookHelper::getDocument() const
+{
+ return mrBookGlob.getDocument();
+}
+
+Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int32 nSheet ) const
+{
+ Reference< XSpreadsheet > xSheet;
+ try
+ {
+ Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
+ xSheet.set( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ return xSheet;
+}
+
+Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( const OUString& rSheet ) const
+{
+ Reference< XSpreadsheet > xSheet;
+ try
+ {
+ Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
+ xSheet.set( xSheetsNA->getByName( rSheet ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xSheet;
+}
+
+Reference< XCellRange > WorkbookHelper::getCellRangeFromDoc( const ScRange& rRange ) const
+{
+ Reference< XCellRange > xRange;
+ try
+ {
+ Reference< XSpreadsheet > xSheet( getSheetFromDoc( rRange.aStart.Tab() ), UNO_SET_THROW );
+ xRange = xSheet->getCellRangeByPosition( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row() );
+ }
+ catch( Exception& )
+ {
+ }
+ return xRange;
+}
+
+Reference< XNameContainer > WorkbookHelper::getCellStyleFamily() const
+{
+ return mrBookGlob.getStyleFamily( false/*bPageStyles*/ );
+}
+
+Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
+{
+ return mrBookGlob.getStyleObject( rStyleName, bPageStyle );
+}
+
+WorkbookHelper::RangeDataRet WorkbookHelper::createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, bool bHidden ) const
+{
+ return mrBookGlob.createNamedRangeObject( orName, rTokens, nIndex, nNameFlags, bHidden );
+}
+
+WorkbookHelper::RangeDataRet WorkbookHelper::createLocalNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab, bool bHidden ) const
+{
+ return mrBookGlob.createLocalNamedRangeObject( orName, rTokens, nIndex, nNameFlags, nTab, bHidden );
+}
+
+Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const ScRange& rRangeAddr ) const
+{
+ return mrBookGlob.createDatabaseRangeObject( orName, rRangeAddr );
+}
+
+Reference< XDatabaseRange > WorkbookHelper::createUnnamedDatabaseRangeObject( const ScRange& rRangeAddr ) const
+{
+ return mrBookGlob.createUnnamedDatabaseRangeObject( rRangeAddr );
+}
+
+ScDBData* WorkbookHelper::findDatabaseRangeByIndex( sal_uInt16 nIndex ) const
+{
+ return mrBookGlob.findDatabaseRangeByIndex( nIndex );
+}
+
+Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
+{
+ return mrBookGlob.createStyleObject( orStyleName, bPageStyle );
+}
+
+// buffers --------------------------------------------------------------------
+
+FormulaBuffer& WorkbookHelper::getFormulaBuffer() const
+{
+ return mrBookGlob.getFormulaBuffer();
+}
+
+WorkbookSettings& WorkbookHelper::getWorkbookSettings() const
+{
+ return mrBookGlob.getWorkbookSettings();
+}
+
+ViewSettings& WorkbookHelper::getViewSettings() const
+{
+ return mrBookGlob.getViewSettings();
+}
+
+WorksheetBuffer& WorkbookHelper::getWorksheets() const
+{
+ return mrBookGlob.getWorksheets();
+}
+
+ThemeBuffer& WorkbookHelper::getTheme() const
+{
+ return mrBookGlob.getTheme();
+}
+
+StylesBuffer& WorkbookHelper::getStyles() const
+{
+ return mrBookGlob.getStyles();
+}
+
+SharedStringsBuffer& WorkbookHelper::getSharedStrings() const
+{
+ return mrBookGlob.getSharedStrings();
+}
+
+ExternalLinkBuffer& WorkbookHelper::getExternalLinks() const
+{
+ return mrBookGlob.getExternalLinks();
+}
+
+DefinedNamesBuffer& WorkbookHelper::getDefinedNames() const
+{
+ return mrBookGlob.getDefinedNames();
+}
+
+TableBuffer& WorkbookHelper::getTables() const
+{
+ return mrBookGlob.getTables();
+}
+
+ScenarioBuffer& WorkbookHelper::getScenarios() const
+{
+ return mrBookGlob.getScenarios();
+}
+
+ConnectionsBuffer& WorkbookHelper::getConnections() const
+{
+ return mrBookGlob.getConnections();
+}
+
+PivotCacheBuffer& WorkbookHelper::getPivotCaches() const
+{
+ return mrBookGlob.getPivotCaches();
+}
+
+PivotTableBuffer& WorkbookHelper::getPivotTables() const
+{
+ return mrBookGlob.getPivotTables();
+}
+
+// converters -----------------------------------------------------------------
+
+FormulaParser& WorkbookHelper::getFormulaParser() const
+{
+ return mrBookGlob.getFormulaParser();
+}
+
+FormulaParser* WorkbookHelper::createFormulaParser() const
+{
+ return mrBookGlob.createFormulaParser();
+}
+
+UnitConverter& WorkbookHelper::getUnitConverter() const
+{
+ return mrBookGlob.getUnitConverter();
+}
+
+AddressConverter& WorkbookHelper::getAddressConverter() const
+{
+ return mrBookGlob.getAddressConverter();
+}
+
+oox::drawingml::chart::ChartConverter* WorkbookHelper::getChartConverter() const
+{
+ return mrBookGlob.getChartConverter();
+}
+
+void WorkbookHelper::useInternalChartDataTable( bool bInternal )
+{
+ mrBookGlob.useInternalChartDataTable( bInternal );
+}
+
+PageSettingsConverter& WorkbookHelper::getPageSettingsConverter() const
+{
+ return mrBookGlob.getPageSettingsConverter();
+}
+
+// OOXML/BIFF12 specific ------------------------------------------------------
+
+XmlFilterBase& WorkbookHelper::getOoxFilter() const
+{
+ return mrBookGlob.getOoxFilter();
+}
+
+bool WorkbookHelper::importOoxFragment( const rtl::Reference<FragmentHandler>& rxHandler )
+{
+ return getOoxFilter().importFragment( rxHandler );
+}
+
+bool WorkbookHelper::importOoxFragment( const rtl::Reference<FragmentHandler>& rxHandler, oox::core::FastParser& rParser )
+{
+ return getOoxFilter().importFragment(rxHandler, rParser);
+}
+
+// BIFF specific --------------------------------------------------------------
+
+rtl_TextEncoding WorkbookHelper::getTextEncoding() const
+{
+ return mrBookGlob.getTextEncoding();
+}
+
+} // namespace oox
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */