diff options
Diffstat (limited to 'sc/source/filter/xml/xmltabi.cxx')
-rw-r--r-- | sc/source/filter/xml/xmltabi.cxx | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx new file mode 100644 index 000000000000..69f00106b7c7 --- /dev/null +++ b/sc/source/filter/xml/xmltabi.cxx @@ -0,0 +1,422 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmltabi.hxx" +#include "xmlimprt.hxx" +#include "xmlrowi.hxx" +#include "xmlcoli.hxx" +#include "xmlsceni.hxx" +#include "xmlexternaltabi.hxx" +#include "document.hxx" +#include "docuno.hxx" +#include "olinetab.hxx" +#include "XMLConverter.hxx" +#include "XMLTableShapesContext.hxx" +#include "XMLTableSourceContext.hxx" +#include "XMLStylesImportHelper.hxx" +#include "rangeutl.hxx" +#include "externalrefmgr.hxx" +#include "sheetdata.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/formsimp.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/XMLEventsImportContext.hxx> + +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XSpreadsheets.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XPrintAreas.hpp> +#include <com/sun/star/table/CellAddress.hpp> + +using namespace com::sun::star; +using namespace xmloff::token; + +/** + * Determine whether this table is an external reference cache from its + * name. There is currently no way of determining whether a table is a + * regular table or an external reference cache other than examining the + * name itself. We should probably introduce a new boolean value for + * table:table element and use it instead of doing this, to make it more + * reliable and future-proof. + * + * @param rName + * + * @return + */ +static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rUrl, rtl::OUString& rExtTabName) +{ + // 'file:///path/to/file.ods'#MySheet + // 'file:///path/to/file.ods'#MySheet with space + // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name. + // That's allowed.) + + static const sal_Unicode aPrefix[] = { + '\'', 'f', 'i', 'l', 'e', ':', '/', '/' + }; + + rtl::OUStringBuffer aUrlBuf, aTabNameBuf; + aUrlBuf.appendAscii("file://"); + sal_Int32 n = rName.getLength(); + const sal_Unicode* p = rName.getStr(); + + bool bInUrl = true; + sal_Unicode cPrev = 0; + for (sal_Int32 i = 0; i < n; ++i) + { + const sal_Unicode c = p[i]; + if (i <= 7) + { + // Checking the prefix 'file://'. + if (c != aPrefix[i]) + return false; + } + else if (bInUrl) + { + // parsing file URL + if (c == '#') + { + if (cPrev != '\'') + return false; + + rUrl = aUrlBuf.makeStringAndClear(); + rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote. + bInUrl = false; + } + else + aUrlBuf.append(c); + } + else + // parsing sheet name. + aTabNameBuf.append(c); + + cPrev = c; + } + + if (bInUrl) + return false; + + if (aTabNameBuf.getLength() == 0) + return false; + + rExtTabName = aTabNameBuf.makeStringAndClear(); + + return true; +} + +ScXMLExternalTabData::ScXMLExternalTabData() : + mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0) +{ +} + +//------------------------------------------------------------------ + +ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport, + USHORT nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bTempIsSubTable, + const sal_Int32 nSpannedCols) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pExternalRefInfo(NULL), + nStartOffset(-1), + bStartFormPage(sal_False), + bPrintEntireSheet(sal_True) +{ + // get start offset in file (if available) + nStartOffset = GetScImport().GetByteOffset(); + + if (!bTempIsSubTable) + { + sal_Bool bProtection(sal_False); + rtl::OUString sName; + rtl::OUString sStyleName; + rtl::OUString sPassword; + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_TABLE_NAME: + sName = sValue; + break; + case XML_TOK_TABLE_STYLE_NAME: + sStyleName = sValue; + break; + case XML_TOK_TABLE_PROTECTION: + bProtection = IsXMLToken(sValue, XML_TRUE); + break; + case XML_TOK_TABLE_PRINT_RANGES: + sPrintRanges = sValue; + break; + case XML_TOK_TABLE_PASSWORD: + sPassword = sValue; + break; + case XML_TOK_TABLE_PRINT: + { + if (IsXMLToken(sValue, XML_FALSE)) + bPrintEntireSheet = sal_False; + } + break; + } + } + + rtl::OUString aExtUrl, aExtTabName; + if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName)) + { + // This is an external ref cache table. + pExternalRefInfo.reset(new ScXMLExternalTabData); + pExternalRefInfo->maFileUrl = aExtUrl; + ScDocument* pDoc = GetScImport().GetDocument(); + if (pDoc) + { + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl); + pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true); + pExternalRefInfo->mpCacheTable->setWholeTableCached(); + } + } + else + { + // This is a regular table. + GetScImport().GetTables().NewSheet(sName, sStyleName, bProtection, sPassword); + } + } + else + { + GetScImport().GetTables().NewTable(nSpannedCols); + } +} + +ScXMLTableContext::~ScXMLTableContext() +{ +} + +SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + const SvXMLTokenMap& rTokenMap(GetScImport().GetTableElemTokenMap()); + sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLName); + if (pExternalRefInfo.get()) + { + // We only care about the table-row and table-source elements for + // external cache data. + switch (nToken) + { + case XML_TOK_TABLE_ROW_GROUP: + case XML_TOK_TABLE_HEADER_ROWS: + case XML_TOK_TABLE_ROWS: + // #i101319# don't discard rows in groups or header (repeat range) + return new ScXMLExternalRefRowsContext( + GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo); + case XML_TOK_TABLE_ROW: + return new ScXMLExternalRefRowContext( + GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo); + case XML_TOK_TABLE_SOURCE: + return new ScXMLExternalRefTabSourceContext( + GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo); + default: + ; + } + + return new SvXMLImportContext(GetImport(), nPrefix, rLName); + } + + SvXMLImportContext *pContext(0); + + switch (nToken) + { + case XML_TOK_TABLE_COL_GROUP: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_True ); + break; + case XML_TOK_TABLE_HEADER_COLS: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_True, sal_False ); + break; + case XML_TOK_TABLE_COLS: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_False ); + break; + case XML_TOK_TABLE_COL: + pContext = new ScXMLTableColContext( GetScImport(), nPrefix, + rLName, xAttrList ); + break; + case XML_TOK_TABLE_ROW_GROUP: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_True ); + break; + case XML_TOK_TABLE_HEADER_ROWS: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_True, sal_False ); + break; + case XML_TOK_TABLE_ROWS: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_False ); + break; + case XML_TOK_TABLE_ROW: + pContext = new ScXMLTableRowContext( GetScImport(), nPrefix, + rLName, xAttrList//, + //this + ); + break; + case XML_TOK_TABLE_SOURCE: + pContext = new ScXMLTableSourceContext( GetScImport(), nPrefix, rLName, xAttrList); + break; + case XML_TOK_TABLE_SCENARIO: + pContext = new ScXMLTableScenarioContext( GetScImport(), nPrefix, rLName, xAttrList); + break; + case XML_TOK_TABLE_SHAPES: + pContext = new ScXMLTableShapesContext( GetScImport(), nPrefix, rLName, xAttrList); + break; + case XML_TOK_TABLE_FORMS: + { + GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage()); + bStartFormPage = sal_True; + pContext = GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix, rLName ); + } + break; + case XML_TOK_TABLE_EVENT_LISTENERS: + case XML_TOK_TABLE_EVENT_LISTENERS_EXT: + { + // use XEventsSupplier interface of the sheet + uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY ); + pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName, xSupplier ); + } + break; + default: + ; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLTableContext::EndElement() +{ + // get end offset in file (if available) +// sal_Int32 nEndOffset = GetScImport().GetByteOffset(); + + GetScImport().LockSolarMutex(); + GetScImport().GetStylesImportHelper()->EndTable(); + ScDocument* pDoc(GetScImport().GetDocument()); + if (pDoc) + { + if (sPrintRanges.getLength()) + { + uno::Reference< sheet::XPrintAreas > xPrintAreas( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY ); + if( xPrintAreas.is() ) + { + uno::Sequence< table::CellRangeAddress > aRangeList; + ScRangeStringConverter::GetRangeListFromString( aRangeList, sPrintRanges, pDoc, ::formula::FormulaGrammar::CONV_OOO ); + xPrintAreas->setPrintAreas( aRangeList ); + } + } + else if (bPrintEntireSheet) pDoc->SetPrintEntireSheet(static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet())); + + ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()), sal_False)); + if (pOutlineTable) + { + ScOutlineArray* pColArray(pOutlineTable->GetColArray()); + sal_Int32 nDepth(pColArray->GetDepth()); + sal_Int32 i; + for (i = 0; i < nDepth; ++i) + { + sal_Int32 nCount(pColArray->GetCount(static_cast<USHORT>(i))); + for (sal_Int32 j = 0; j < nCount; ++j) + { + ScOutlineEntry* pEntry(pColArray->GetEntry(static_cast<USHORT>(i), static_cast<USHORT>(j))); + if (pEntry->IsHidden()) + pColArray->SetVisibleBelow(static_cast<USHORT>(i), static_cast<USHORT>(j), sal_False); + } + } + ScOutlineArray* pRowArray(pOutlineTable->GetRowArray()); + nDepth = pRowArray->GetDepth(); + for (i = 0; i < nDepth; ++i) + { + sal_Int32 nCount(pRowArray->GetCount(static_cast<USHORT>(i))); + for (sal_Int32 j = 0; j < nCount; ++j) + { + ScOutlineEntry* pEntry(pRowArray->GetEntry(static_cast<USHORT>(i), static_cast<USHORT>(j))); + if (pEntry->IsHidden()) + pRowArray->SetVisibleBelow(static_cast<USHORT>(i), static_cast<USHORT>(j), sal_False); + } + } + } + if (GetScImport().GetTables().HasDrawPage()) + { + if (GetScImport().GetTables().HasXShapes()) + { + GetScImport().GetShapeImport()->popGroupAndSort(); + uno::Reference < drawing::XShapes > xTempShapes(GetScImport().GetTables().GetCurrentXShapes()); + GetScImport().GetShapeImport()->endPage(xTempShapes); + } + if (bStartFormPage) + GetScImport().GetFormImport()->endPage(); + } + + GetScImport().GetTables().DeleteTable(); + GetScImport().ProgressBarIncrement(sal_False); + + // store stream positions + if (!pExternalRefInfo.get() && nStartOffset >= 0 /* && nEndOffset >= 0 */) + { + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData(); + sal_Int32 nTab = GetScImport().GetTables().GetCurrentSheet(); + // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset ); + pSheetData->StartStreamPos( nTab, nStartOffset ); + } + } + GetScImport().UnlockSolarMutex(); +} + |