summaryrefslogtreecommitdiff
path: root/sc/source/filter/xml/xmltabi.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/xml/xmltabi.cxx')
-rw-r--r--sc/source/filter/xml/xmltabi.cxx422
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();
+}
+