Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / filter / xml / xmldrani.cxx
blob5a6e362677d8c3a68477f3a385487204ab868ae8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "xmldrani.hxx"
21 #include "xmlimprt.hxx"
22 #include "xmlfilti.hxx"
23 #include "xmlsorti.hxx"
24 #include <document.hxx>
25 #include <globalnames.hxx>
26 #include <dbdata.hxx>
27 #include <datauno.hxx>
28 #include <attrib.hxx>
29 #include <unonames.hxx>
30 #include "XMLConverter.hxx"
31 #include <rangeutl.hxx>
32 #include <dputil.hxx>
33 #include <sortparam.hxx>
35 #include <xmloff/xmltoken.hxx>
36 #include <xmloff/xmlnmspe.hxx>
38 #include <sax/tools/converter.hxx>
40 #include <com/sun/star/sheet/DataImportMode.hpp>
41 #include <com/sun/star/table/TableOrientation.hpp>
42 #include <osl/diagnose.h>
44 #include <memory>
46 using namespace com::sun::star;
47 using namespace xmloff::token;
49 ScXMLDatabaseRangesContext::ScXMLDatabaseRangesContext( ScXMLImport& rImport ) :
50 ScXMLImportContext( rImport )
52 // has no attributes
53 rImport.LockSolarMutex();
56 ScXMLDatabaseRangesContext::~ScXMLDatabaseRangesContext()
58 GetScImport().UnlockSolarMutex();
61 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDatabaseRangesContext::createFastChildContext(
62 sal_Int32 nElement,
63 const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
65 SvXMLImportContext *pContext = nullptr;
66 sax_fastparser::FastAttributeList *pAttribList =
67 sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
69 switch( nElement )
71 case XML_ELEMENT( TABLE, XML_DATABASE_RANGE ):
73 pContext = new ScXMLDatabaseRangeContext( GetScImport(), pAttribList );
75 break;
78 if( !pContext )
79 pContext = new SvXMLImportContext( GetImport() );
81 return pContext;
84 ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport,
85 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList ) :
86 ScXMLImportContext( rImport ),
87 mpQueryParam(new ScQueryParam),
88 sDatabaseRangeName(STR_DB_LOCAL_NONAME),
89 aSortSequence(),
90 nRefresh(0),
91 nSubTotalsUserListIndex(0),
92 mbValidRange(true),
93 bContainsSort(false),
94 bContainsSubTotal(false),
95 bNative(true),
96 bIsSelection(false),
97 bKeepFormats(false),
98 bMoveCells(false),
99 bStripData(false),
100 bAutoFilter(false),
101 bSubTotalsBindFormatsToContent(false),
102 bSubTotalsIsCaseSensitive(false),
103 bSubTotalsInsertPageBreaks(false),
104 bSubTotalsSortGroups(false),
105 bSubTotalsEnabledUserList(false),
106 bSubTotalsAscending(true),
107 bFilterConditionSourceRange(false),
108 bHasHeader(true),
109 bByRow(false),
110 meRangeType(ScDBCollection::GlobalNamed)
112 nSourceType = sheet::DataImportMode_NONE;
113 if( rAttrList.is() )
115 for( auto &aIter : *rAttrList )
117 switch( aIter.getToken() )
119 case XML_ELEMENT( TABLE, XML_NAME ):
121 sDatabaseRangeName = aIter.toString();
123 break;
124 case XML_ELEMENT( TABLE, XML_IS_SELECTION ):
126 bIsSelection = IsXMLToken( aIter, XML_TRUE );
128 break;
129 case XML_ELEMENT( TABLE, XML_ON_UPDATE_KEEP_STYLES ):
131 bKeepFormats = IsXMLToken( aIter, XML_TRUE );
133 break;
134 case XML_ELEMENT( TABLE, XML_ON_UPDATE_KEEP_SIZE ):
136 bMoveCells = !IsXMLToken( aIter, XML_TRUE );
138 break;
139 case XML_ELEMENT( TABLE, XML_HAS_PERSISTENT_DATA ):
141 bStripData = !IsXMLToken( aIter, XML_TRUE );
143 break;
144 case XML_ELEMENT( TABLE, XML_ORIENTATION ):
146 bByRow = !IsXMLToken( aIter, XML_COLUMN );
147 mpQueryParam->bByRow = bByRow;
149 break;
150 case XML_ELEMENT( TABLE, XML_CONTAINS_HEADER ):
152 bHasHeader = IsXMLToken( aIter, XML_TRUE );
153 mpQueryParam->bHasHeader = bHasHeader;
155 break;
156 case XML_ELEMENT( TABLE, XML_DISPLAY_FILTER_BUTTONS ):
158 bAutoFilter = IsXMLToken( aIter, XML_TRUE );
160 break;
161 case XML_ELEMENT( TABLE, XML_TARGET_RANGE_ADDRESS ):
163 ScDocument* pDoc = GetScImport().GetDocument();
164 sal_Int32 nOffset = 0;
165 if (!ScRangeStringConverter::GetRangeFromString(
166 maRange, aIter.toString(), pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset))
167 mbValidRange = false;
169 break;
170 case XML_ELEMENT( TABLE, XML_REFRESH_DELAY ):
172 double fTime;
173 if (::sax::Converter::convertDuration( fTime, aIter.toString() ))
174 nRefresh = std::max( static_cast<sal_Int32>(fTime * 86400.0), sal_Int32(0) );
176 break;
181 mpQueryParam->nTab = maRange.aStart.Tab();
182 mpQueryParam->nCol1 = maRange.aStart.Col();
183 mpQueryParam->nRow1 = maRange.aStart.Row();
184 mpQueryParam->nCol2 = maRange.aEnd.Col();
185 mpQueryParam->nRow2 = maRange.aEnd.Row();
187 if (sDatabaseRangeName.startsWith(STR_DB_LOCAL_NONAME))
188 meRangeType = ScDBCollection::SheetAnonymous;
189 else if (sDatabaseRangeName.startsWith(STR_DB_GLOBAL_NONAME))
190 meRangeType = ScDBCollection::GlobalAnonymous;
193 ScXMLDatabaseRangeContext::~ScXMLDatabaseRangeContext()
197 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDatabaseRangeContext::createFastChildContext(
198 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
200 SvXMLImportContext *pContext = nullptr;
201 sax_fastparser::FastAttributeList *pAttribList =
202 sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
204 switch (nElement)
206 case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_SQL ):
208 pContext = new ScXMLSourceSQLContext( GetScImport(), pAttribList, this);
210 break;
211 case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_TABLE ):
213 pContext = new ScXMLSourceTableContext( GetScImport(), pAttribList, this);
215 break;
216 case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_QUERY ):
218 pContext = new ScXMLSourceQueryContext( GetScImport(), pAttribList, this);
220 break;
221 case XML_ELEMENT( TABLE, XML_FILTER ):
223 pContext = new ScXMLFilterContext(
224 GetScImport(), pAttribList, *mpQueryParam, this);
226 break;
227 case XML_ELEMENT( TABLE, XML_SORT ):
229 bContainsSort = true;
230 pContext = new ScXMLSortContext( GetScImport(), pAttribList, this);
232 break;
233 case XML_ELEMENT( TABLE, XML_SUBTOTAL_RULES ):
235 bContainsSubTotal = true;
236 pContext = new ScXMLSubTotalRulesContext( GetScImport(), pAttribList, this);
238 break;
241 if( !pContext )
242 pContext = new SvXMLImportContext( GetImport() );
244 return pContext;
247 std::unique_ptr<ScDBData> ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
249 if (!mbValidRange)
250 return nullptr;
252 ScDocument* pDoc = GetScImport().GetDocument();
254 ::std::unique_ptr<ScDBData> pData(
255 new ScDBData(rName, maRange.aStart.Tab(), maRange.aStart.Col(), maRange.aStart.Row(), maRange.aEnd.Col(), maRange.aEnd.Row(), bByRow, bHasHeader));
257 pData->SetAutoFilter(bAutoFilter);
258 pData->SetKeepFmt(bKeepFormats);
259 pData->SetDoSize(bMoveCells);
260 pData->SetStripData(bStripData);
262 pData->SetQueryParam(*mpQueryParam);
264 if (bFilterConditionSourceRange)
266 pData->SetAdvancedQuerySource( &aFilterConditionSourceRangeAddress );
270 ScImportParam aParam;
271 aParam.bNative = bNative;
272 aParam.aDBName = sDatabaseName.isEmpty() ? sConnectionResource : sDatabaseName;
273 aParam.aStatement = sSourceObject;
274 switch (nSourceType)
276 case sheet::DataImportMode_NONE:
277 aParam.bImport = false;
278 break;
279 case sheet::DataImportMode_SQL:
280 aParam.bImport = true;
281 aParam.bSql = true;
282 break;
283 case sheet::DataImportMode_TABLE:
284 aParam.bImport = true;
285 aParam.bSql = false;
286 aParam.nType = ScDbTable;
287 break;
288 case sheet::DataImportMode_QUERY:
289 aParam.bImport = true;
290 aParam.bSql = false;
291 aParam.nType = ScDbQuery;
292 break;
293 default:
294 OSL_FAIL("Unknown data import mode");
295 aParam.bImport = false;
297 pData->SetImportParam(aParam);
300 if (bContainsSort)
302 size_t nOldSize = aSortSequence.getLength();
303 aSortSequence.realloc(nOldSize + 1);
304 beans::PropertyValue aProperty;
305 aProperty.Name = SC_UNONAME_ORIENT;
306 table::TableOrientation eOrient = mpQueryParam->bByRow ?
307 table::TableOrientation_ROWS : table::TableOrientation_COLUMNS;
308 aProperty.Value <<= eOrient;
309 aSortSequence[nOldSize] = aProperty;
310 ScSortParam aParam;
311 ScSortDescriptor::FillSortParam(aParam, aSortSequence);
313 SCCOLROW nStartPos = aParam.bByRow ? maRange.aStart.Col() : maRange.aStart.Row();
314 for (size_t i = 0; i < aParam.GetSortKeyCount(); ++i)
316 if (!aParam.maKeyState[i].bDoSort)
317 break;
318 aParam.maKeyState[i].nField += nStartPos;
321 pData->SetSortParam(aParam);
324 if (bContainsSubTotal)
326 ScSubTotalParam aParam;
327 aParam.bIncludePattern = bSubTotalsBindFormatsToContent;
328 aParam.bUserDef = bSubTotalsEnabledUserList;
329 aParam.nUserIndex = nSubTotalsUserListIndex;
330 aParam.bPagebreak = bSubTotalsInsertPageBreaks;
331 aParam.bCaseSens = bSubTotalsIsCaseSensitive;
332 aParam.bDoSort = bSubTotalsSortGroups;
333 aParam.bAscending = bSubTotalsAscending;
334 size_t nPos = 0;
335 for (const auto& rSubTotalRule : aSubTotalRules)
337 if (nPos >= MAXSUBTOTAL)
338 break;
340 const uno::Sequence<sheet::SubTotalColumn>& rColumns = rSubTotalRule.aSubTotalColumns;
341 sal_Int32 nColCount = rColumns.getLength();
342 sal_Int16 nGroupColumn = rSubTotalRule.nSubTotalRuleGroupFieldNumber;
343 aParam.bGroupActive[nPos] = true;
344 aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
346 SCCOL nCount = static_cast<SCCOL>(nColCount);
347 aParam.nSubTotals[nPos] = nCount;
348 if (nCount != 0)
350 aParam.pSubTotals[nPos] = new SCCOL[nCount];
351 aParam.pFunctions[nPos] = new ScSubTotalFunc[nCount];
353 const sheet::SubTotalColumn* pAry = rColumns.getConstArray();
354 for (SCCOL i = 0; i < nCount; ++i)
356 aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column);
357 aParam.pFunctions[nPos][i] = ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function));
360 else
362 aParam.pSubTotals[nPos] = nullptr;
363 aParam.pFunctions[nPos] = nullptr;
365 ++nPos;
368 pData->SetSubTotalParam(aParam);
371 if (pData->HasImportParam() && !pData->HasImportSelection())
373 pData->SetRefreshDelay(nRefresh);
374 pData->SetRefreshHandler(pDoc->GetDBCollection()->GetRefreshHandler());
375 pData->SetRefreshControl(&pDoc->GetRefreshTimerControlAddress());
378 return pData;
381 namespace {
383 bool setAutoFilterFlags(ScDocument& rDoc, const ScDBData& rData)
385 if (!rData.HasAutoFilter())
386 return false;
388 // Set autofilter flags so that the buttons get displayed.
389 ScRange aRange;
390 rData.GetArea(aRange);
391 rDoc.ApplyFlagsTab(
392 aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aStart.Row(),
393 aRange.aStart.Tab(), ScMF::Auto);
394 return false;
399 void SAL_CALL ScXMLDatabaseRangeContext::endFastElement( sal_Int32 /*nElement*/ )
401 ScDocument* pDoc = GetScImport().GetDocument();
402 if (!pDoc)
403 return;
405 if (meRangeType == ScDBCollection::SheetAnonymous)
407 ::std::unique_ptr<ScDBData> pData(ConvertToDBData(STR_DB_LOCAL_NONAME));
409 if (pData)
411 ScRange aRange;
412 pData->GetArea(aRange);
414 setAutoFilterFlags(*pDoc, *pData);
415 pDoc->SetAnonymousDBData(aRange.aStart.Tab(), std::move(pData));
417 return;
419 else if (meRangeType == ScDBCollection::GlobalAnonymous)
421 ::std::unique_ptr<ScDBData> pData(ConvertToDBData(STR_DB_GLOBAL_NONAME));
423 if (pData)
425 ScRange aRange;
426 pData->GetArea(aRange);
428 if (setAutoFilterFlags(*pDoc, *pData))
429 pDoc->SetAnonymousDBData(aRange.aStart.Tab(), std::move(pData));
430 else
431 pDoc->GetDBCollection()->getAnonDBs().insert(pData.release());
433 return;
435 else if (meRangeType == ScDBCollection::GlobalNamed)
437 ::std::unique_ptr<ScDBData> pData(ConvertToDBData(sDatabaseRangeName));
439 if (pData)
441 setAutoFilterFlags(*pDoc, *pData);
442 (void)pDoc->GetDBCollection()->getNamedDBs().insert(std::move(pData));
447 ScXMLSourceSQLContext::ScXMLSourceSQLContext( ScXMLImport& rImport,
448 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
449 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
450 ScXMLImportContext( rImport ),
451 pDatabaseRangeContext(pTempDatabaseRangeContext)
453 if ( rAttrList.is() )
455 for (auto &aIter : *rAttrList)
457 switch (aIter.getToken())
459 case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
460 sDBName = aIter.toString();
461 break;
462 case XML_ELEMENT( TABLE, XML_SQL_STATEMENT ):
463 pDatabaseRangeContext->SetSourceObject(aIter.toString());
464 break;
465 case XML_ELEMENT( TABLE, XML_PARSE_SQL_STATEMENT ):
466 pDatabaseRangeContext->SetNative(IsXMLToken(aIter, XML_TRUE));
467 break;
471 pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_SQL);
474 ScXMLSourceSQLContext::~ScXMLSourceSQLContext()
478 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceSQLContext::createFastChildContext(
479 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
481 SvXMLImportContext *pContext = nullptr;
482 sax_fastparser::FastAttributeList *pAttribList =
483 sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
485 if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
487 pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
490 if( !pContext )
491 pContext = new SvXMLImportContext( GetImport() );
493 return pContext;
496 void SAL_CALL ScXMLSourceSQLContext::endFastElement( sal_Int32 /*nElement*/ )
498 if (!sDBName.isEmpty())
499 pDatabaseRangeContext->SetDatabaseName(sDBName);
502 ScXMLSourceTableContext::ScXMLSourceTableContext( ScXMLImport& rImport,
503 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
504 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
505 ScXMLImportContext( rImport ),
506 pDatabaseRangeContext(pTempDatabaseRangeContext)
508 if ( rAttrList.is() )
510 for (auto &aIter : *rAttrList)
512 switch (aIter.getToken())
514 case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
515 sDBName = aIter.toString();
516 break;
517 case XML_ELEMENT( TABLE, XML_TABLE_NAME ):
518 case XML_ELEMENT( TABLE, XML_DATABASE_TABLE_NAME ):
519 pDatabaseRangeContext->SetSourceObject(aIter.toString());
520 break;
524 pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_TABLE);
527 ScXMLSourceTableContext::~ScXMLSourceTableContext()
531 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceTableContext::createFastChildContext(
532 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
534 SvXMLImportContext *pContext = nullptr;
535 sax_fastparser::FastAttributeList *pAttribList =
536 sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
538 if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
540 pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
543 if( !pContext )
544 pContext = new SvXMLImportContext( GetImport() );
546 return pContext;
549 void SAL_CALL ScXMLSourceTableContext::endFastElement( sal_Int32 /*nElement*/ )
551 if (!sDBName.isEmpty())
552 pDatabaseRangeContext->SetDatabaseName(sDBName);
555 ScXMLSourceQueryContext::ScXMLSourceQueryContext( ScXMLImport& rImport,
556 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
557 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
558 ScXMLImportContext( rImport ),
559 pDatabaseRangeContext(pTempDatabaseRangeContext)
561 if ( rAttrList.is() )
563 for (auto &aIter : *rAttrList)
565 switch (aIter.getToken())
567 case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
568 sDBName = aIter.toString();
569 break;
570 case XML_ELEMENT( TABLE, XML_QUERY_NAME ):
571 pDatabaseRangeContext->SetSourceObject(aIter.toString());
572 break;
576 pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_QUERY);
579 ScXMLSourceQueryContext::~ScXMLSourceQueryContext()
583 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceQueryContext::createFastChildContext(
584 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
586 SvXMLImportContext *pContext = nullptr;
587 sax_fastparser::FastAttributeList *pAttribList =
588 sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
590 if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
592 pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
595 if( !pContext )
596 pContext = new SvXMLImportContext( GetImport() );
598 return pContext;
601 void SAL_CALL ScXMLSourceQueryContext::endFastElement( sal_Int32 /*nElement*/ )
603 if (!sDBName.isEmpty())
604 pDatabaseRangeContext->SetDatabaseName(sDBName);
607 ScXMLConResContext::ScXMLConResContext( ScXMLImport& rImport,
608 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
609 ScXMLDatabaseRangeContext* pDatabaseRangeContext) :
610 ScXMLImportContext( rImport )
612 OUString sConRes;
613 if ( rAttrList.is() )
615 auto aIter( rAttrList->find( XML_ELEMENT( XLINK, XML_HREF ) ) );
616 if (aIter != rAttrList->end())
617 sConRes = aIter.toString();
619 if (!sConRes.isEmpty())
620 pDatabaseRangeContext->SetConnectionResource(sConRes);
623 ScXMLConResContext::~ScXMLConResContext()
627 ScXMLSubTotalRulesContext::ScXMLSubTotalRulesContext( ScXMLImport& rImport,
628 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
629 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
630 ScXMLImportContext( rImport ),
631 pDatabaseRangeContext(pTempDatabaseRangeContext)
633 if ( rAttrList.is() )
635 for (auto &aIter : *rAttrList)
637 switch (aIter.getToken())
639 case XML_ELEMENT( TABLE, XML_BIND_STYLES_TO_CONTENT ):
640 pDatabaseRangeContext->SetSubTotalsBindFormatsToContent(IsXMLToken(aIter, XML_TRUE));
641 break;
642 case XML_ELEMENT( TABLE, XML_CASE_SENSITIVE ):
643 pDatabaseRangeContext->SetSubTotalsIsCaseSensitive(IsXMLToken(aIter, XML_TRUE));
644 break;
645 case XML_ELEMENT( TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE ):
646 pDatabaseRangeContext->SetSubTotalsInsertPageBreaks(IsXMLToken(aIter, XML_TRUE));
647 break;
653 ScXMLSubTotalRulesContext::~ScXMLSubTotalRulesContext()
657 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSubTotalRulesContext::createFastChildContext(
658 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
660 SvXMLImportContext *pContext = nullptr;
661 sax_fastparser::FastAttributeList *pAttribList =
662 sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
664 switch (nElement)
666 case XML_ELEMENT( TABLE, XML_SORT_GROUPS ):
668 pContext = new ScXMLSortGroupsContext( GetScImport(), pAttribList, pDatabaseRangeContext);
670 break;
671 case XML_ELEMENT( TABLE, XML_SUBTOTAL_RULE ):
673 pContext = new ScXMLSubTotalRuleContext( GetScImport(), pAttribList, pDatabaseRangeContext);
675 break;
678 if( !pContext )
679 pContext = new SvXMLImportContext( GetImport() );
681 return pContext;
684 ScXMLSortGroupsContext::ScXMLSortGroupsContext( ScXMLImport& rImport,
685 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
686 ScXMLDatabaseRangeContext* pDatabaseRangeContext) :
687 ScXMLImportContext( rImport )
689 pDatabaseRangeContext->SetSubTotalsSortGroups(true);
690 if ( rAttrList.is() )
692 for (auto &aIter : *rAttrList)
694 switch (aIter.getToken())
696 case XML_ELEMENT( TABLE, XML_DATA_TYPE ):
698 const OUString &sValue = aIter.toString();
699 if (sValue.getLength() > 8)
701 OUString sTemp = sValue.copy(0, 8);
702 if (sTemp == "UserList")
704 pDatabaseRangeContext->SetSubTotalsEnabledUserList(true);
705 sTemp = sValue.copy(8);
706 pDatabaseRangeContext->SetSubTotalsUserListIndex(static_cast<sal_Int16>(sTemp.toInt32()));
708 else
710 //if (IsXMLToken(aIter, XML_AUTOMATIC))
711 //aSortField.FieldType = util::SortFieldType_AUTOMATIC;
712 // is not supported by StarOffice
715 else
717 //if (IsXMLToken(aIter, XML_TEXT))
718 //aSortField.FieldType = util::SortFieldType_ALPHANUMERIC;
719 // is not supported by StarOffice
720 //else if (IsXMLToken(aIter, XML_NUMBER))
721 //aSortField.FieldType = util::SortFieldType_NUMERIC;
722 // is not supported by StarOffice
725 break;
726 case XML_ELEMENT( TABLE, XML_ORDER ):
728 if (IsXMLToken(aIter, XML_ASCENDING))
729 pDatabaseRangeContext->SetSubTotalsAscending(true);
730 else
731 pDatabaseRangeContext->SetSubTotalsAscending(false);
733 break;
739 ScXMLSortGroupsContext::~ScXMLSortGroupsContext()
743 ScXMLSubTotalRuleContext::ScXMLSubTotalRuleContext( ScXMLImport& rImport,
744 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
745 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
746 ScXMLImportContext( rImport ),
747 pDatabaseRangeContext(pTempDatabaseRangeContext)
749 if ( rAttrList.is() )
751 for (auto &aIter : *rAttrList)
753 switch (aIter.getToken())
755 case XML_ELEMENT( TABLE, XML_GROUP_BY_FIELD_NUMBER ):
756 aSubTotalRule.nSubTotalRuleGroupFieldNumber = static_cast<sal_Int16>(aIter.toInt32());
757 break;
763 ScXMLSubTotalRuleContext::~ScXMLSubTotalRuleContext()
767 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSubTotalRuleContext::createFastChildContext(
768 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
770 SvXMLImportContext *pContext = nullptr;
771 sax_fastparser::FastAttributeList *pAttribList =
772 sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
774 switch (nElement)
776 case XML_ELEMENT( TABLE, XML_SUBTOTAL_FIELD ):
778 pContext = new ScXMLSubTotalFieldContext( GetScImport(), pAttribList, this);
780 break;
783 if( !pContext )
784 pContext = new SvXMLImportContext( GetImport() );
786 return pContext;
789 void SAL_CALL ScXMLSubTotalRuleContext::endFastElement( sal_Int32 /*nElement*/ )
791 if (pDatabaseRangeContext)
792 pDatabaseRangeContext->AddSubTotalRule(aSubTotalRule);
795 ScXMLSubTotalFieldContext::ScXMLSubTotalFieldContext( ScXMLImport& rImport,
796 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
797 ScXMLSubTotalRuleContext* pTempSubTotalRuleContext) :
798 ScXMLImportContext( rImport ),
799 pSubTotalRuleContext(pTempSubTotalRuleContext)
801 if ( rAttrList.is() )
803 for (auto &aIter : *rAttrList)
805 switch (aIter.getToken())
807 case XML_ELEMENT( TABLE, XML_FIELD_NUMBER ):
808 sFieldNumber = aIter.toString();
809 break;
810 case XML_ELEMENT( TABLE, XML_FUNCTION ):
811 sFunction = aIter.toString();
812 break;
818 ScXMLSubTotalFieldContext::~ScXMLSubTotalFieldContext()
822 void SAL_CALL ScXMLSubTotalFieldContext::endFastElement( sal_Int32 /*nElement*/ )
824 sheet::SubTotalColumn aSubTotalColumn;
825 aSubTotalColumn.Column = sFieldNumber.toInt32();
826 aSubTotalColumn.Function = ScXMLConverter::GetFunctionFromString( sFunction );
827 pSubTotalRuleContext->AddSubTotalColumn(aSubTotalColumn);
830 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */