summaryrefslogtreecommitdiffstats
path: root/sc/source/filter/xml/xmldrani.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/xml/xmldrani.cxx')
-rw-r--r--sc/source/filter/xml/xmldrani.cxx812
1 files changed, 812 insertions, 0 deletions
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
new file mode 100644
index 000000000..5708c74d2
--- /dev/null
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -0,0 +1,812 @@
+/* -*- 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 "xmldrani.hxx"
+#include "xmlimprt.hxx"
+#include "xmlfilti.hxx"
+#include "xmlsorti.hxx"
+#include <document.hxx>
+#include <globalnames.hxx>
+#include <dbdata.hxx>
+#include <datauno.hxx>
+#include <attrib.hxx>
+#include <unonames.hxx>
+#include "XMLConverter.hxx"
+#include <rangeutl.hxx>
+#include <dputil.hxx>
+#include <sortparam.hxx>
+
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+
+#include <sax/tools/converter.hxx>
+
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+#include <osl/diagnose.h>
+#include <o3tl/string_view.hxx>
+
+#include <memory>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+ScXMLDatabaseRangesContext::ScXMLDatabaseRangesContext( ScXMLImport& rImport ) :
+ ScXMLImportContext( rImport )
+{
+ // has no attributes
+ rImport.LockSolarMutex();
+}
+
+ScXMLDatabaseRangesContext::~ScXMLDatabaseRangesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDatabaseRangesContext::createFastChildContext(
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext *pContext = nullptr;
+ sax_fastparser::FastAttributeList *pAttribList =
+ &sax_fastparser::castToFastAttributeList( xAttrList );
+
+ switch( nElement )
+ {
+ case XML_ELEMENT( TABLE, XML_DATABASE_RANGE ):
+ {
+ pContext = new ScXMLDatabaseRangeContext( GetScImport(), pAttribList );
+ }
+ break;
+ }
+
+ return pContext;
+}
+
+ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList ) :
+ ScXMLImportContext( rImport ),
+ mpQueryParam(new ScQueryParam),
+ sDatabaseRangeName(STR_DB_LOCAL_NONAME),
+ nSourceType(sheet::DataImportMode_NONE),
+ nRefresh(0),
+ nSubTotalsUserListIndex(0),
+ mbValidRange(true),
+ bContainsSort(false),
+ bContainsSubTotal(false),
+ bNative(true),
+ bIsSelection(false),
+ bKeepFormats(false),
+ bMoveCells(false),
+ bStripData(false),
+ bAutoFilter(false),
+ bSubTotalsBindFormatsToContent(false),
+ bSubTotalsIsCaseSensitive(false),
+ bSubTotalsInsertPageBreaks(false),
+ bSubTotalsSortGroups(false),
+ bSubTotalsEnabledUserList(false),
+ bSubTotalsAscending(true),
+ bFilterConditionSourceRange(false),
+ bHasHeader(true),
+ bByRow(true),
+ meRangeType(ScDBCollection::GlobalNamed)
+{
+ if( rAttrList.is() )
+ {
+ for( auto &aIter : *rAttrList )
+ {
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT( TABLE, XML_NAME ):
+ {
+ sDatabaseRangeName = aIter.toString();
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_IS_SELECTION ):
+ {
+ bIsSelection = IsXMLToken( aIter, XML_TRUE );
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_ON_UPDATE_KEEP_STYLES ):
+ {
+ bKeepFormats = IsXMLToken( aIter, XML_TRUE );
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_ON_UPDATE_KEEP_SIZE ):
+ {
+ bMoveCells = !IsXMLToken( aIter, XML_TRUE );
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_HAS_PERSISTENT_DATA ):
+ {
+ bStripData = !IsXMLToken( aIter, XML_TRUE );
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_ORIENTATION ):
+ {
+ bByRow = !IsXMLToken( aIter, XML_COLUMN );
+ mpQueryParam->bByRow = bByRow;
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_CONTAINS_HEADER ):
+ {
+ bHasHeader = IsXMLToken( aIter, XML_TRUE );
+ mpQueryParam->bHasHeader = bHasHeader;
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_DISPLAY_FILTER_BUTTONS ):
+ {
+ bAutoFilter = IsXMLToken( aIter, XML_TRUE );
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_TARGET_RANGE_ADDRESS ):
+ {
+ ScDocument* pDoc = GetScImport().GetDocument();
+ assert(pDoc);
+ sal_Int32 nOffset = 0;
+ if (!ScRangeStringConverter::GetRangeFromString(
+ maRange, aIter.toString(), *pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset))
+ mbValidRange = false;
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_REFRESH_DELAY ):
+ {
+ double fTime;
+ if (::sax::Converter::convertDuration( fTime, aIter.toView() ))
+ nRefresh = std::max( static_cast<sal_Int32>(fTime * 86400.0), sal_Int32(0) );
+ }
+ break;
+ }
+ }
+ }
+
+ mpQueryParam->nTab = maRange.aStart.Tab();
+ mpQueryParam->nCol1 = maRange.aStart.Col();
+ mpQueryParam->nRow1 = maRange.aStart.Row();
+ mpQueryParam->nCol2 = maRange.aEnd.Col();
+ mpQueryParam->nRow2 = maRange.aEnd.Row();
+
+ if (sDatabaseRangeName.startsWith(STR_DB_LOCAL_NONAME))
+ meRangeType = ScDBCollection::SheetAnonymous;
+ else if (sDatabaseRangeName.startsWith(STR_DB_GLOBAL_NONAME))
+ meRangeType = ScDBCollection::GlobalAnonymous;
+}
+
+ScXMLDatabaseRangeContext::~ScXMLDatabaseRangeContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDatabaseRangeContext::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext *pContext = nullptr;
+ sax_fastparser::FastAttributeList *pAttribList =
+ &sax_fastparser::castToFastAttributeList( xAttrList );
+
+ switch (nElement)
+ {
+ case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_SQL ):
+ {
+ pContext = new ScXMLSourceSQLContext( GetScImport(), pAttribList, this);
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_TABLE ):
+ {
+ pContext = new ScXMLSourceTableContext( GetScImport(), pAttribList, this);
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_QUERY ):
+ {
+ pContext = new ScXMLSourceQueryContext( GetScImport(), pAttribList, this);
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_FILTER ):
+ {
+ pContext = new ScXMLFilterContext(
+ GetScImport(), pAttribList, *mpQueryParam, this);
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_SORT ):
+ {
+ bContainsSort = true;
+ pContext = new ScXMLSortContext( GetScImport(), pAttribList, this);
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_SUBTOTAL_RULES ):
+ {
+ bContainsSubTotal = true;
+ pContext = new ScXMLSubTotalRulesContext( GetScImport(), pAttribList, this);
+ }
+ break;
+ }
+
+ return pContext;
+}
+
+std::unique_ptr<ScDBData> ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
+{
+ if (!mbValidRange)
+ return nullptr;
+
+ ScDocument* pDoc = GetScImport().GetDocument();
+
+ ::std::unique_ptr<ScDBData> pData(
+ new ScDBData(rName, maRange.aStart.Tab(), maRange.aStart.Col(), maRange.aStart.Row(), maRange.aEnd.Col(), maRange.aEnd.Row(), bByRow, bHasHeader));
+
+ pData->SetAutoFilter(bAutoFilter);
+ pData->SetKeepFmt(bKeepFormats);
+ pData->SetDoSize(bMoveCells);
+ pData->SetStripData(bStripData);
+
+ pDoc->PrepareQuery(mpQueryParam->nTab, *mpQueryParam);
+
+ pData->SetQueryParam(*mpQueryParam);
+
+ if (bFilterConditionSourceRange)
+ {
+ pData->SetAdvancedQuerySource( &aFilterConditionSourceRangeAddress );
+ }
+
+ {
+ ScImportParam aParam;
+ aParam.bNative = bNative;
+ aParam.aDBName = sDatabaseName.isEmpty() ? sConnectionResource : sDatabaseName;
+ aParam.aStatement = sSourceObject;
+ switch (nSourceType)
+ {
+ case sheet::DataImportMode_NONE:
+ aParam.bImport = false;
+ break;
+ case sheet::DataImportMode_SQL:
+ aParam.bImport = true;
+ aParam.bSql = true;
+ break;
+ case sheet::DataImportMode_TABLE:
+ aParam.bImport = true;
+ aParam.bSql = false;
+ aParam.nType = ScDbTable;
+ break;
+ case sheet::DataImportMode_QUERY:
+ aParam.bImport = true;
+ aParam.bSql = false;
+ aParam.nType = ScDbQuery;
+ break;
+ default:
+ OSL_FAIL("Unknown data import mode");
+ aParam.bImport = false;
+ }
+ pData->SetImportParam(aParam);
+ }
+
+ if (bContainsSort)
+ {
+ size_t nOldSize = aSortSequence.getLength();
+ aSortSequence.realloc(nOldSize + 1);
+ beans::PropertyValue aProperty;
+ aProperty.Name = SC_UNONAME_ORIENT;
+ table::TableOrientation eOrient = mpQueryParam->bByRow ?
+ table::TableOrientation_ROWS : table::TableOrientation_COLUMNS;
+ aProperty.Value <<= eOrient;
+ aSortSequence.getArray()[nOldSize] = aProperty;
+ ScSortParam aParam;
+ ScSortDescriptor::FillSortParam(aParam, aSortSequence);
+
+ SCCOLROW nStartPos = aParam.bByRow ? maRange.aStart.Col() : maRange.aStart.Row();
+ for (size_t i = 0; i < aParam.GetSortKeyCount(); ++i)
+ {
+ if (!aParam.maKeyState[i].bDoSort)
+ break;
+ aParam.maKeyState[i].nField += nStartPos;
+ }
+
+ pData->SetSortParam(aParam);
+ }
+
+ if (bContainsSubTotal)
+ {
+ ScSubTotalParam aParam;
+ aParam.bIncludePattern = bSubTotalsBindFormatsToContent;
+ aParam.bUserDef = bSubTotalsEnabledUserList;
+ aParam.nUserIndex = nSubTotalsUserListIndex;
+ aParam.bPagebreak = bSubTotalsInsertPageBreaks;
+ aParam.bCaseSens = bSubTotalsIsCaseSensitive;
+ aParam.bDoSort = bSubTotalsSortGroups;
+ aParam.bAscending = bSubTotalsAscending;
+ size_t nPos = 0;
+ for (const auto& rSubTotalRule : aSubTotalRules)
+ {
+ if (nPos >= MAXSUBTOTAL)
+ break;
+
+ const uno::Sequence<sheet::SubTotalColumn>& rColumns = rSubTotalRule.aSubTotalColumns;
+ sal_Int32 nColCount = rColumns.getLength();
+ sal_Int16 nGroupColumn = rSubTotalRule.nSubTotalRuleGroupFieldNumber;
+ aParam.bGroupActive[nPos] = true;
+ aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
+
+ SCCOL nCount = static_cast<SCCOL>(nColCount);
+ aParam.nSubTotals[nPos] = nCount;
+ if (nCount != 0)
+ {
+ aParam.pSubTotals[nPos].reset(new SCCOL[nCount]);
+ aParam.pFunctions[nPos].reset(new ScSubTotalFunc[nCount]);
+
+ const sheet::SubTotalColumn* pAry = rColumns.getConstArray();
+ for (SCCOL i = 0; i < nCount; ++i)
+ {
+ aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column);
+ aParam.pFunctions[nPos][i] = ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function));
+ }
+ }
+ else
+ {
+ aParam.pSubTotals[nPos].reset();
+ aParam.pFunctions[nPos].reset();
+ }
+ ++nPos;
+ }
+
+ pData->SetSubTotalParam(aParam);
+ }
+
+ if (pData->HasImportParam() && !pData->HasImportSelection())
+ {
+ pData->SetRefreshDelay(nRefresh);
+ pData->SetRefreshHandler(pDoc->GetDBCollection()->GetRefreshHandler());
+ pData->SetRefreshControl(&pDoc->GetRefreshTimerControlAddress());
+ }
+
+ return pData;
+}
+
+namespace {
+
+bool setAutoFilterFlags(ScDocument& rDoc, const ScDBData& rData)
+{
+ if (!rData.HasAutoFilter())
+ return false;
+
+ // Set autofilter flags so that the buttons get displayed.
+ ScRange aRange;
+ rData.GetArea(aRange);
+ rDoc.ApplyFlagsTab(
+ aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), ScMF::Auto);
+ return false;
+}
+
+}
+
+void SAL_CALL ScXMLDatabaseRangeContext::endFastElement( sal_Int32 /*nElement*/ )
+{
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (!pDoc)
+ return;
+
+ if (meRangeType == ScDBCollection::SheetAnonymous)
+ {
+ ::std::unique_ptr<ScDBData> pData(ConvertToDBData(STR_DB_LOCAL_NONAME));
+
+ if (pData)
+ {
+ ScRange aRange;
+ pData->GetArea(aRange);
+
+ setAutoFilterFlags(*pDoc, *pData);
+ pDoc->SetAnonymousDBData(aRange.aStart.Tab(), std::move(pData));
+ }
+ return;
+ }
+ else if (meRangeType == ScDBCollection::GlobalAnonymous)
+ {
+ ::std::unique_ptr<ScDBData> pData(ConvertToDBData(STR_DB_GLOBAL_NONAME));
+
+ if (pData)
+ {
+ ScRange aRange;
+ pData->GetArea(aRange);
+
+ if (setAutoFilterFlags(*pDoc, *pData))
+ pDoc->SetAnonymousDBData(aRange.aStart.Tab(), std::move(pData));
+ else
+ pDoc->GetDBCollection()->getAnonDBs().insert(pData.release());
+ }
+ return;
+ }
+ else if (meRangeType == ScDBCollection::GlobalNamed)
+ {
+ ::std::unique_ptr<ScDBData> pData(ConvertToDBData(sDatabaseRangeName));
+
+ if (pData)
+ {
+ setAutoFilterFlags(*pDoc, *pData);
+ (void)pDoc->GetDBCollection()->getNamedDBs().insert(std::move(pData));
+ }
+ }
+}
+
+ScXMLSourceSQLContext::ScXMLSourceSQLContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ ScXMLImportContext( rImport ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ if ( rAttrList.is() )
+ {
+ for (auto &aIter : *rAttrList)
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
+ sDBName = aIter.toString();
+ break;
+ case XML_ELEMENT( TABLE, XML_SQL_STATEMENT ):
+ pDatabaseRangeContext->SetSourceObject(aIter.toString());
+ break;
+ case XML_ELEMENT( TABLE, XML_PARSE_SQL_STATEMENT ):
+ pDatabaseRangeContext->SetNative(IsXMLToken(aIter, XML_TRUE));
+ break;
+ }
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_SQL);
+}
+
+ScXMLSourceSQLContext::~ScXMLSourceSQLContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceSQLContext::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext *pContext = nullptr;
+ sax_fastparser::FastAttributeList *pAttribList =
+ &sax_fastparser::castToFastAttributeList( xAttrList );
+
+ if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
+ {
+ pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
+ }
+
+ return pContext;
+}
+
+void SAL_CALL ScXMLSourceSQLContext::endFastElement( sal_Int32 /*nElement*/ )
+{
+ if (!sDBName.isEmpty())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLSourceTableContext::ScXMLSourceTableContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ ScXMLImportContext( rImport ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ if ( rAttrList.is() )
+ {
+ for (auto &aIter : *rAttrList)
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
+ sDBName = aIter.toString();
+ break;
+ case XML_ELEMENT( TABLE, XML_TABLE_NAME ):
+ case XML_ELEMENT( TABLE, XML_DATABASE_TABLE_NAME ):
+ pDatabaseRangeContext->SetSourceObject(aIter.toString());
+ break;
+ }
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_TABLE);
+}
+
+ScXMLSourceTableContext::~ScXMLSourceTableContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceTableContext::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext *pContext = nullptr;
+ sax_fastparser::FastAttributeList *pAttribList =
+ &sax_fastparser::castToFastAttributeList( xAttrList );
+
+ if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
+ {
+ pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
+ }
+
+ return pContext;
+}
+
+void SAL_CALL ScXMLSourceTableContext::endFastElement( sal_Int32 /*nElement*/ )
+{
+ if (!sDBName.isEmpty())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLSourceQueryContext::ScXMLSourceQueryContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ ScXMLImportContext( rImport ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ if ( rAttrList.is() )
+ {
+ for (auto &aIter : *rAttrList)
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
+ sDBName = aIter.toString();
+ break;
+ case XML_ELEMENT( TABLE, XML_QUERY_NAME ):
+ pDatabaseRangeContext->SetSourceObject(aIter.toString());
+ break;
+ }
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_QUERY);
+}
+
+ScXMLSourceQueryContext::~ScXMLSourceQueryContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceQueryContext::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext *pContext = nullptr;
+ sax_fastparser::FastAttributeList *pAttribList =
+ &sax_fastparser::castToFastAttributeList( xAttrList );
+
+ if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
+ {
+ pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
+ }
+
+ return pContext;
+}
+
+void SAL_CALL ScXMLSourceQueryContext::endFastElement( sal_Int32 /*nElement*/ )
+{
+ if (!sDBName.isEmpty())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLConResContext::ScXMLConResContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext) :
+ ScXMLImportContext( rImport )
+{
+ OUString sConRes;
+ if ( rAttrList.is() )
+ {
+ auto aIter( rAttrList->find( XML_ELEMENT( XLINK, XML_HREF ) ) );
+ if (aIter != rAttrList->end())
+ sConRes = aIter.toString();
+ }
+ if (!sConRes.isEmpty())
+ pDatabaseRangeContext->SetConnectionResource(sConRes);
+}
+
+ScXMLConResContext::~ScXMLConResContext()
+{
+}
+
+ScXMLSubTotalRulesContext::ScXMLSubTotalRulesContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ ScXMLImportContext( rImport ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ if ( !rAttrList.is() )
+ return;
+
+ for (auto &aIter : *rAttrList)
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TABLE, XML_BIND_STYLES_TO_CONTENT ):
+ pDatabaseRangeContext->SetSubTotalsBindFormatsToContent(IsXMLToken(aIter, XML_TRUE));
+ break;
+ case XML_ELEMENT( TABLE, XML_CASE_SENSITIVE ):
+ pDatabaseRangeContext->SetSubTotalsIsCaseSensitive(IsXMLToken(aIter, XML_TRUE));
+ break;
+ case XML_ELEMENT( TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE ):
+ pDatabaseRangeContext->SetSubTotalsInsertPageBreaks(IsXMLToken(aIter, XML_TRUE));
+ break;
+ }
+ }
+}
+
+ScXMLSubTotalRulesContext::~ScXMLSubTotalRulesContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSubTotalRulesContext::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext *pContext = nullptr;
+ sax_fastparser::FastAttributeList *pAttribList =
+ &sax_fastparser::castToFastAttributeList( xAttrList );
+
+ switch (nElement)
+ {
+ case XML_ELEMENT( TABLE, XML_SORT_GROUPS ):
+ {
+ pContext = new ScXMLSortGroupsContext( GetScImport(), pAttribList, pDatabaseRangeContext);
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_SUBTOTAL_RULE ):
+ {
+ pContext = new ScXMLSubTotalRuleContext( GetScImport(), pAttribList, pDatabaseRangeContext);
+ }
+ break;
+ }
+
+ return pContext;
+}
+
+ScXMLSortGroupsContext::ScXMLSortGroupsContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext) :
+ ScXMLImportContext( rImport )
+{
+ pDatabaseRangeContext->SetSubTotalsSortGroups(true);
+ if ( !rAttrList.is() )
+ return;
+
+ for (auto &aIter : *rAttrList)
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TABLE, XML_DATA_TYPE ):
+ {
+ const OUString &sValue = aIter.toString();
+ if (sValue.getLength() > 8)
+ {
+ std::u16string_view sTemp = sValue.subView(0, 8);
+ if (sTemp == u"UserList")
+ {
+ pDatabaseRangeContext->SetSubTotalsEnabledUserList(true);
+ sTemp = sValue.subView(8);
+ pDatabaseRangeContext->SetSubTotalsUserListIndex(static_cast<sal_Int16>(o3tl::toInt32(sTemp)));
+ }
+ else
+ {
+ //if (IsXMLToken(aIter, XML_AUTOMATIC))
+ //aSortField.FieldType = util::SortFieldType_AUTOMATIC;
+ // is not supported by StarOffice
+ }
+ }
+ else
+ {
+ //if (IsXMLToken(aIter, XML_TEXT))
+ //aSortField.FieldType = util::SortFieldType_ALPHANUMERIC;
+ // is not supported by StarOffice
+ //else if (IsXMLToken(aIter, XML_NUMBER))
+ //aSortField.FieldType = util::SortFieldType_NUMERIC;
+ // is not supported by StarOffice
+ }
+ }
+ break;
+ case XML_ELEMENT( TABLE, XML_ORDER ):
+ {
+ if (IsXMLToken(aIter, XML_ASCENDING))
+ pDatabaseRangeContext->SetSubTotalsAscending(true);
+ else
+ pDatabaseRangeContext->SetSubTotalsAscending(false);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSortGroupsContext::~ScXMLSortGroupsContext()
+{
+}
+
+ScXMLSubTotalRuleContext::ScXMLSubTotalRuleContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ ScXMLImportContext( rImport ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ if ( rAttrList.is() )
+ {
+ for (auto &aIter : *rAttrList)
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TABLE, XML_GROUP_BY_FIELD_NUMBER ):
+ aSubTotalRule.nSubTotalRuleGroupFieldNumber = static_cast<sal_Int16>(aIter.toInt32());
+ break;
+ }
+ }
+ }
+}
+
+ScXMLSubTotalRuleContext::~ScXMLSubTotalRuleContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSubTotalRuleContext::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext *pContext = nullptr;
+ sax_fastparser::FastAttributeList *pAttribList =
+ &sax_fastparser::castToFastAttributeList( xAttrList );
+
+ switch (nElement)
+ {
+ case XML_ELEMENT( TABLE, XML_SUBTOTAL_FIELD ):
+ {
+ pContext = new ScXMLSubTotalFieldContext( GetScImport(), pAttribList, this);
+ }
+ break;
+ }
+
+ return pContext;
+}
+
+void SAL_CALL ScXMLSubTotalRuleContext::endFastElement( sal_Int32 /*nElement*/ )
+{
+ if (pDatabaseRangeContext)
+ pDatabaseRangeContext->AddSubTotalRule(aSubTotalRule);
+}
+
+ScXMLSubTotalFieldContext::ScXMLSubTotalFieldContext( ScXMLImport& rImport,
+ const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
+ ScXMLSubTotalRuleContext* pTempSubTotalRuleContext) :
+ ScXMLImportContext( rImport ),
+ pSubTotalRuleContext(pTempSubTotalRuleContext)
+{
+ if ( !rAttrList.is() )
+ return;
+
+ for (auto &aIter : *rAttrList)
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TABLE, XML_FIELD_NUMBER ):
+ sFieldNumber = aIter.toString();
+ break;
+ case XML_ELEMENT( TABLE, XML_FUNCTION ):
+ sFunction = aIter.toString();
+ break;
+ }
+ }
+}
+
+ScXMLSubTotalFieldContext::~ScXMLSubTotalFieldContext()
+{
+}
+
+void SAL_CALL ScXMLSubTotalFieldContext::endFastElement( sal_Int32 /*nElement*/ )
+{
+ sheet::SubTotalColumn aSubTotalColumn;
+ aSubTotalColumn.Column = sFieldNumber.toInt32();
+ aSubTotalColumn.Function = ScXMLConverter::GetFunctionFromString( sFunction );
+ pSubTotalRuleContext->AddSubTotalColumn(aSubTotalColumn);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */