Version 7.5.1.1, tag libreoffice-7.5.1.1
[LibreOffice.git] / sc / source / filter / xml / xmldrani.cxx
blob5708c74d2fa32e805a8bcaacb68d02d74e14606b
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/xmlnamespace.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>
43 #include <o3tl/string_view.hxx>
45 #include <memory>
47 using namespace com::sun::star;
48 using namespace xmloff::token;
50 ScXMLDatabaseRangesContext::ScXMLDatabaseRangesContext( ScXMLImport& rImport ) :
51 ScXMLImportContext( rImport )
53 // has no attributes
54 rImport.LockSolarMutex();
57 ScXMLDatabaseRangesContext::~ScXMLDatabaseRangesContext()
59 GetScImport().UnlockSolarMutex();
62 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDatabaseRangesContext::createFastChildContext(
63 sal_Int32 nElement,
64 const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
66 SvXMLImportContext *pContext = nullptr;
67 sax_fastparser::FastAttributeList *pAttribList =
68 &sax_fastparser::castToFastAttributeList( xAttrList );
70 switch( nElement )
72 case XML_ELEMENT( TABLE, XML_DATABASE_RANGE ):
74 pContext = new ScXMLDatabaseRangeContext( GetScImport(), pAttribList );
76 break;
79 return pContext;
82 ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport,
83 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList ) :
84 ScXMLImportContext( rImport ),
85 mpQueryParam(new ScQueryParam),
86 sDatabaseRangeName(STR_DB_LOCAL_NONAME),
87 nSourceType(sheet::DataImportMode_NONE),
88 nRefresh(0),
89 nSubTotalsUserListIndex(0),
90 mbValidRange(true),
91 bContainsSort(false),
92 bContainsSubTotal(false),
93 bNative(true),
94 bIsSelection(false),
95 bKeepFormats(false),
96 bMoveCells(false),
97 bStripData(false),
98 bAutoFilter(false),
99 bSubTotalsBindFormatsToContent(false),
100 bSubTotalsIsCaseSensitive(false),
101 bSubTotalsInsertPageBreaks(false),
102 bSubTotalsSortGroups(false),
103 bSubTotalsEnabledUserList(false),
104 bSubTotalsAscending(true),
105 bFilterConditionSourceRange(false),
106 bHasHeader(true),
107 bByRow(true),
108 meRangeType(ScDBCollection::GlobalNamed)
110 if( rAttrList.is() )
112 for( auto &aIter : *rAttrList )
114 switch( aIter.getToken() )
116 case XML_ELEMENT( TABLE, XML_NAME ):
118 sDatabaseRangeName = aIter.toString();
120 break;
121 case XML_ELEMENT( TABLE, XML_IS_SELECTION ):
123 bIsSelection = IsXMLToken( aIter, XML_TRUE );
125 break;
126 case XML_ELEMENT( TABLE, XML_ON_UPDATE_KEEP_STYLES ):
128 bKeepFormats = IsXMLToken( aIter, XML_TRUE );
130 break;
131 case XML_ELEMENT( TABLE, XML_ON_UPDATE_KEEP_SIZE ):
133 bMoveCells = !IsXMLToken( aIter, XML_TRUE );
135 break;
136 case XML_ELEMENT( TABLE, XML_HAS_PERSISTENT_DATA ):
138 bStripData = !IsXMLToken( aIter, XML_TRUE );
140 break;
141 case XML_ELEMENT( TABLE, XML_ORIENTATION ):
143 bByRow = !IsXMLToken( aIter, XML_COLUMN );
144 mpQueryParam->bByRow = bByRow;
146 break;
147 case XML_ELEMENT( TABLE, XML_CONTAINS_HEADER ):
149 bHasHeader = IsXMLToken( aIter, XML_TRUE );
150 mpQueryParam->bHasHeader = bHasHeader;
152 break;
153 case XML_ELEMENT( TABLE, XML_DISPLAY_FILTER_BUTTONS ):
155 bAutoFilter = IsXMLToken( aIter, XML_TRUE );
157 break;
158 case XML_ELEMENT( TABLE, XML_TARGET_RANGE_ADDRESS ):
160 ScDocument* pDoc = GetScImport().GetDocument();
161 assert(pDoc);
162 sal_Int32 nOffset = 0;
163 if (!ScRangeStringConverter::GetRangeFromString(
164 maRange, aIter.toString(), *pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset))
165 mbValidRange = false;
167 break;
168 case XML_ELEMENT( TABLE, XML_REFRESH_DELAY ):
170 double fTime;
171 if (::sax::Converter::convertDuration( fTime, aIter.toView() ))
172 nRefresh = std::max( static_cast<sal_Int32>(fTime * 86400.0), sal_Int32(0) );
174 break;
179 mpQueryParam->nTab = maRange.aStart.Tab();
180 mpQueryParam->nCol1 = maRange.aStart.Col();
181 mpQueryParam->nRow1 = maRange.aStart.Row();
182 mpQueryParam->nCol2 = maRange.aEnd.Col();
183 mpQueryParam->nRow2 = maRange.aEnd.Row();
185 if (sDatabaseRangeName.startsWith(STR_DB_LOCAL_NONAME))
186 meRangeType = ScDBCollection::SheetAnonymous;
187 else if (sDatabaseRangeName.startsWith(STR_DB_GLOBAL_NONAME))
188 meRangeType = ScDBCollection::GlobalAnonymous;
191 ScXMLDatabaseRangeContext::~ScXMLDatabaseRangeContext()
195 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDatabaseRangeContext::createFastChildContext(
196 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
198 SvXMLImportContext *pContext = nullptr;
199 sax_fastparser::FastAttributeList *pAttribList =
200 &sax_fastparser::castToFastAttributeList( xAttrList );
202 switch (nElement)
204 case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_SQL ):
206 pContext = new ScXMLSourceSQLContext( GetScImport(), pAttribList, this);
208 break;
209 case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_TABLE ):
211 pContext = new ScXMLSourceTableContext( GetScImport(), pAttribList, this);
213 break;
214 case XML_ELEMENT( TABLE, XML_DATABASE_SOURCE_QUERY ):
216 pContext = new ScXMLSourceQueryContext( GetScImport(), pAttribList, this);
218 break;
219 case XML_ELEMENT( TABLE, XML_FILTER ):
221 pContext = new ScXMLFilterContext(
222 GetScImport(), pAttribList, *mpQueryParam, this);
224 break;
225 case XML_ELEMENT( TABLE, XML_SORT ):
227 bContainsSort = true;
228 pContext = new ScXMLSortContext( GetScImport(), pAttribList, this);
230 break;
231 case XML_ELEMENT( TABLE, XML_SUBTOTAL_RULES ):
233 bContainsSubTotal = true;
234 pContext = new ScXMLSubTotalRulesContext( GetScImport(), pAttribList, this);
236 break;
239 return pContext;
242 std::unique_ptr<ScDBData> ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
244 if (!mbValidRange)
245 return nullptr;
247 ScDocument* pDoc = GetScImport().GetDocument();
249 ::std::unique_ptr<ScDBData> pData(
250 new ScDBData(rName, maRange.aStart.Tab(), maRange.aStart.Col(), maRange.aStart.Row(), maRange.aEnd.Col(), maRange.aEnd.Row(), bByRow, bHasHeader));
252 pData->SetAutoFilter(bAutoFilter);
253 pData->SetKeepFmt(bKeepFormats);
254 pData->SetDoSize(bMoveCells);
255 pData->SetStripData(bStripData);
257 pDoc->PrepareQuery(mpQueryParam->nTab, *mpQueryParam);
259 pData->SetQueryParam(*mpQueryParam);
261 if (bFilterConditionSourceRange)
263 pData->SetAdvancedQuerySource( &aFilterConditionSourceRangeAddress );
267 ScImportParam aParam;
268 aParam.bNative = bNative;
269 aParam.aDBName = sDatabaseName.isEmpty() ? sConnectionResource : sDatabaseName;
270 aParam.aStatement = sSourceObject;
271 switch (nSourceType)
273 case sheet::DataImportMode_NONE:
274 aParam.bImport = false;
275 break;
276 case sheet::DataImportMode_SQL:
277 aParam.bImport = true;
278 aParam.bSql = true;
279 break;
280 case sheet::DataImportMode_TABLE:
281 aParam.bImport = true;
282 aParam.bSql = false;
283 aParam.nType = ScDbTable;
284 break;
285 case sheet::DataImportMode_QUERY:
286 aParam.bImport = true;
287 aParam.bSql = false;
288 aParam.nType = ScDbQuery;
289 break;
290 default:
291 OSL_FAIL("Unknown data import mode");
292 aParam.bImport = false;
294 pData->SetImportParam(aParam);
297 if (bContainsSort)
299 size_t nOldSize = aSortSequence.getLength();
300 aSortSequence.realloc(nOldSize + 1);
301 beans::PropertyValue aProperty;
302 aProperty.Name = SC_UNONAME_ORIENT;
303 table::TableOrientation eOrient = mpQueryParam->bByRow ?
304 table::TableOrientation_ROWS : table::TableOrientation_COLUMNS;
305 aProperty.Value <<= eOrient;
306 aSortSequence.getArray()[nOldSize] = aProperty;
307 ScSortParam aParam;
308 ScSortDescriptor::FillSortParam(aParam, aSortSequence);
310 SCCOLROW nStartPos = aParam.bByRow ? maRange.aStart.Col() : maRange.aStart.Row();
311 for (size_t i = 0; i < aParam.GetSortKeyCount(); ++i)
313 if (!aParam.maKeyState[i].bDoSort)
314 break;
315 aParam.maKeyState[i].nField += nStartPos;
318 pData->SetSortParam(aParam);
321 if (bContainsSubTotal)
323 ScSubTotalParam aParam;
324 aParam.bIncludePattern = bSubTotalsBindFormatsToContent;
325 aParam.bUserDef = bSubTotalsEnabledUserList;
326 aParam.nUserIndex = nSubTotalsUserListIndex;
327 aParam.bPagebreak = bSubTotalsInsertPageBreaks;
328 aParam.bCaseSens = bSubTotalsIsCaseSensitive;
329 aParam.bDoSort = bSubTotalsSortGroups;
330 aParam.bAscending = bSubTotalsAscending;
331 size_t nPos = 0;
332 for (const auto& rSubTotalRule : aSubTotalRules)
334 if (nPos >= MAXSUBTOTAL)
335 break;
337 const uno::Sequence<sheet::SubTotalColumn>& rColumns = rSubTotalRule.aSubTotalColumns;
338 sal_Int32 nColCount = rColumns.getLength();
339 sal_Int16 nGroupColumn = rSubTotalRule.nSubTotalRuleGroupFieldNumber;
340 aParam.bGroupActive[nPos] = true;
341 aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
343 SCCOL nCount = static_cast<SCCOL>(nColCount);
344 aParam.nSubTotals[nPos] = nCount;
345 if (nCount != 0)
347 aParam.pSubTotals[nPos].reset(new SCCOL[nCount]);
348 aParam.pFunctions[nPos].reset(new ScSubTotalFunc[nCount]);
350 const sheet::SubTotalColumn* pAry = rColumns.getConstArray();
351 for (SCCOL i = 0; i < nCount; ++i)
353 aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column);
354 aParam.pFunctions[nPos][i] = ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function));
357 else
359 aParam.pSubTotals[nPos].reset();
360 aParam.pFunctions[nPos].reset();
362 ++nPos;
365 pData->SetSubTotalParam(aParam);
368 if (pData->HasImportParam() && !pData->HasImportSelection())
370 pData->SetRefreshDelay(nRefresh);
371 pData->SetRefreshHandler(pDoc->GetDBCollection()->GetRefreshHandler());
372 pData->SetRefreshControl(&pDoc->GetRefreshTimerControlAddress());
375 return pData;
378 namespace {
380 bool setAutoFilterFlags(ScDocument& rDoc, const ScDBData& rData)
382 if (!rData.HasAutoFilter())
383 return false;
385 // Set autofilter flags so that the buttons get displayed.
386 ScRange aRange;
387 rData.GetArea(aRange);
388 rDoc.ApplyFlagsTab(
389 aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aStart.Row(),
390 aRange.aStart.Tab(), ScMF::Auto);
391 return false;
396 void SAL_CALL ScXMLDatabaseRangeContext::endFastElement( sal_Int32 /*nElement*/ )
398 ScDocument* pDoc = GetScImport().GetDocument();
399 if (!pDoc)
400 return;
402 if (meRangeType == ScDBCollection::SheetAnonymous)
404 ::std::unique_ptr<ScDBData> pData(ConvertToDBData(STR_DB_LOCAL_NONAME));
406 if (pData)
408 ScRange aRange;
409 pData->GetArea(aRange);
411 setAutoFilterFlags(*pDoc, *pData);
412 pDoc->SetAnonymousDBData(aRange.aStart.Tab(), std::move(pData));
414 return;
416 else if (meRangeType == ScDBCollection::GlobalAnonymous)
418 ::std::unique_ptr<ScDBData> pData(ConvertToDBData(STR_DB_GLOBAL_NONAME));
420 if (pData)
422 ScRange aRange;
423 pData->GetArea(aRange);
425 if (setAutoFilterFlags(*pDoc, *pData))
426 pDoc->SetAnonymousDBData(aRange.aStart.Tab(), std::move(pData));
427 else
428 pDoc->GetDBCollection()->getAnonDBs().insert(pData.release());
430 return;
432 else if (meRangeType == ScDBCollection::GlobalNamed)
434 ::std::unique_ptr<ScDBData> pData(ConvertToDBData(sDatabaseRangeName));
436 if (pData)
438 setAutoFilterFlags(*pDoc, *pData);
439 (void)pDoc->GetDBCollection()->getNamedDBs().insert(std::move(pData));
444 ScXMLSourceSQLContext::ScXMLSourceSQLContext( ScXMLImport& rImport,
445 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
446 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
447 ScXMLImportContext( rImport ),
448 pDatabaseRangeContext(pTempDatabaseRangeContext)
450 if ( rAttrList.is() )
452 for (auto &aIter : *rAttrList)
454 switch (aIter.getToken())
456 case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
457 sDBName = aIter.toString();
458 break;
459 case XML_ELEMENT( TABLE, XML_SQL_STATEMENT ):
460 pDatabaseRangeContext->SetSourceObject(aIter.toString());
461 break;
462 case XML_ELEMENT( TABLE, XML_PARSE_SQL_STATEMENT ):
463 pDatabaseRangeContext->SetNative(IsXMLToken(aIter, XML_TRUE));
464 break;
468 pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_SQL);
471 ScXMLSourceSQLContext::~ScXMLSourceSQLContext()
475 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceSQLContext::createFastChildContext(
476 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
478 SvXMLImportContext *pContext = nullptr;
479 sax_fastparser::FastAttributeList *pAttribList =
480 &sax_fastparser::castToFastAttributeList( xAttrList );
482 if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
484 pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
487 return pContext;
490 void SAL_CALL ScXMLSourceSQLContext::endFastElement( sal_Int32 /*nElement*/ )
492 if (!sDBName.isEmpty())
493 pDatabaseRangeContext->SetDatabaseName(sDBName);
496 ScXMLSourceTableContext::ScXMLSourceTableContext( ScXMLImport& rImport,
497 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
498 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
499 ScXMLImportContext( rImport ),
500 pDatabaseRangeContext(pTempDatabaseRangeContext)
502 if ( rAttrList.is() )
504 for (auto &aIter : *rAttrList)
506 switch (aIter.getToken())
508 case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
509 sDBName = aIter.toString();
510 break;
511 case XML_ELEMENT( TABLE, XML_TABLE_NAME ):
512 case XML_ELEMENT( TABLE, XML_DATABASE_TABLE_NAME ):
513 pDatabaseRangeContext->SetSourceObject(aIter.toString());
514 break;
518 pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_TABLE);
521 ScXMLSourceTableContext::~ScXMLSourceTableContext()
525 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceTableContext::createFastChildContext(
526 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
528 SvXMLImportContext *pContext = nullptr;
529 sax_fastparser::FastAttributeList *pAttribList =
530 &sax_fastparser::castToFastAttributeList( xAttrList );
532 if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
534 pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
537 return pContext;
540 void SAL_CALL ScXMLSourceTableContext::endFastElement( sal_Int32 /*nElement*/ )
542 if (!sDBName.isEmpty())
543 pDatabaseRangeContext->SetDatabaseName(sDBName);
546 ScXMLSourceQueryContext::ScXMLSourceQueryContext( ScXMLImport& rImport,
547 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
548 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
549 ScXMLImportContext( rImport ),
550 pDatabaseRangeContext(pTempDatabaseRangeContext)
552 if ( rAttrList.is() )
554 for (auto &aIter : *rAttrList)
556 switch (aIter.getToken())
558 case XML_ELEMENT( TABLE, XML_DATABASE_NAME ):
559 sDBName = aIter.toString();
560 break;
561 case XML_ELEMENT( TABLE, XML_QUERY_NAME ):
562 pDatabaseRangeContext->SetSourceObject(aIter.toString());
563 break;
567 pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_QUERY);
570 ScXMLSourceQueryContext::~ScXMLSourceQueryContext()
574 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSourceQueryContext::createFastChildContext(
575 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
577 SvXMLImportContext *pContext = nullptr;
578 sax_fastparser::FastAttributeList *pAttribList =
579 &sax_fastparser::castToFastAttributeList( xAttrList );
581 if ( nElement == XML_ELEMENT( FORM, XML_CONNECTION_RESOURCE ) && sDBName.isEmpty() )
583 pContext = new ScXMLConResContext( GetScImport(), pAttribList, pDatabaseRangeContext);
586 return pContext;
589 void SAL_CALL ScXMLSourceQueryContext::endFastElement( sal_Int32 /*nElement*/ )
591 if (!sDBName.isEmpty())
592 pDatabaseRangeContext->SetDatabaseName(sDBName);
595 ScXMLConResContext::ScXMLConResContext( ScXMLImport& rImport,
596 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
597 ScXMLDatabaseRangeContext* pDatabaseRangeContext) :
598 ScXMLImportContext( rImport )
600 OUString sConRes;
601 if ( rAttrList.is() )
603 auto aIter( rAttrList->find( XML_ELEMENT( XLINK, XML_HREF ) ) );
604 if (aIter != rAttrList->end())
605 sConRes = aIter.toString();
607 if (!sConRes.isEmpty())
608 pDatabaseRangeContext->SetConnectionResource(sConRes);
611 ScXMLConResContext::~ScXMLConResContext()
615 ScXMLSubTotalRulesContext::ScXMLSubTotalRulesContext( ScXMLImport& rImport,
616 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
617 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
618 ScXMLImportContext( rImport ),
619 pDatabaseRangeContext(pTempDatabaseRangeContext)
621 if ( !rAttrList.is() )
622 return;
624 for (auto &aIter : *rAttrList)
626 switch (aIter.getToken())
628 case XML_ELEMENT( TABLE, XML_BIND_STYLES_TO_CONTENT ):
629 pDatabaseRangeContext->SetSubTotalsBindFormatsToContent(IsXMLToken(aIter, XML_TRUE));
630 break;
631 case XML_ELEMENT( TABLE, XML_CASE_SENSITIVE ):
632 pDatabaseRangeContext->SetSubTotalsIsCaseSensitive(IsXMLToken(aIter, XML_TRUE));
633 break;
634 case XML_ELEMENT( TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE ):
635 pDatabaseRangeContext->SetSubTotalsInsertPageBreaks(IsXMLToken(aIter, XML_TRUE));
636 break;
641 ScXMLSubTotalRulesContext::~ScXMLSubTotalRulesContext()
645 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSubTotalRulesContext::createFastChildContext(
646 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
648 SvXMLImportContext *pContext = nullptr;
649 sax_fastparser::FastAttributeList *pAttribList =
650 &sax_fastparser::castToFastAttributeList( xAttrList );
652 switch (nElement)
654 case XML_ELEMENT( TABLE, XML_SORT_GROUPS ):
656 pContext = new ScXMLSortGroupsContext( GetScImport(), pAttribList, pDatabaseRangeContext);
658 break;
659 case XML_ELEMENT( TABLE, XML_SUBTOTAL_RULE ):
661 pContext = new ScXMLSubTotalRuleContext( GetScImport(), pAttribList, pDatabaseRangeContext);
663 break;
666 return pContext;
669 ScXMLSortGroupsContext::ScXMLSortGroupsContext( ScXMLImport& rImport,
670 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
671 ScXMLDatabaseRangeContext* pDatabaseRangeContext) :
672 ScXMLImportContext( rImport )
674 pDatabaseRangeContext->SetSubTotalsSortGroups(true);
675 if ( !rAttrList.is() )
676 return;
678 for (auto &aIter : *rAttrList)
680 switch (aIter.getToken())
682 case XML_ELEMENT( TABLE, XML_DATA_TYPE ):
684 const OUString &sValue = aIter.toString();
685 if (sValue.getLength() > 8)
687 std::u16string_view sTemp = sValue.subView(0, 8);
688 if (sTemp == u"UserList")
690 pDatabaseRangeContext->SetSubTotalsEnabledUserList(true);
691 sTemp = sValue.subView(8);
692 pDatabaseRangeContext->SetSubTotalsUserListIndex(static_cast<sal_Int16>(o3tl::toInt32(sTemp)));
694 else
696 //if (IsXMLToken(aIter, XML_AUTOMATIC))
697 //aSortField.FieldType = util::SortFieldType_AUTOMATIC;
698 // is not supported by StarOffice
701 else
703 //if (IsXMLToken(aIter, XML_TEXT))
704 //aSortField.FieldType = util::SortFieldType_ALPHANUMERIC;
705 // is not supported by StarOffice
706 //else if (IsXMLToken(aIter, XML_NUMBER))
707 //aSortField.FieldType = util::SortFieldType_NUMERIC;
708 // is not supported by StarOffice
711 break;
712 case XML_ELEMENT( TABLE, XML_ORDER ):
714 if (IsXMLToken(aIter, XML_ASCENDING))
715 pDatabaseRangeContext->SetSubTotalsAscending(true);
716 else
717 pDatabaseRangeContext->SetSubTotalsAscending(false);
719 break;
724 ScXMLSortGroupsContext::~ScXMLSortGroupsContext()
728 ScXMLSubTotalRuleContext::ScXMLSubTotalRuleContext( ScXMLImport& rImport,
729 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
730 ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
731 ScXMLImportContext( rImport ),
732 pDatabaseRangeContext(pTempDatabaseRangeContext)
734 if ( rAttrList.is() )
736 for (auto &aIter : *rAttrList)
738 switch (aIter.getToken())
740 case XML_ELEMENT( TABLE, XML_GROUP_BY_FIELD_NUMBER ):
741 aSubTotalRule.nSubTotalRuleGroupFieldNumber = static_cast<sal_Int16>(aIter.toInt32());
742 break;
748 ScXMLSubTotalRuleContext::~ScXMLSubTotalRuleContext()
752 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLSubTotalRuleContext::createFastChildContext(
753 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
755 SvXMLImportContext *pContext = nullptr;
756 sax_fastparser::FastAttributeList *pAttribList =
757 &sax_fastparser::castToFastAttributeList( xAttrList );
759 switch (nElement)
761 case XML_ELEMENT( TABLE, XML_SUBTOTAL_FIELD ):
763 pContext = new ScXMLSubTotalFieldContext( GetScImport(), pAttribList, this);
765 break;
768 return pContext;
771 void SAL_CALL ScXMLSubTotalRuleContext::endFastElement( sal_Int32 /*nElement*/ )
773 if (pDatabaseRangeContext)
774 pDatabaseRangeContext->AddSubTotalRule(aSubTotalRule);
777 ScXMLSubTotalFieldContext::ScXMLSubTotalFieldContext( ScXMLImport& rImport,
778 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
779 ScXMLSubTotalRuleContext* pTempSubTotalRuleContext) :
780 ScXMLImportContext( rImport ),
781 pSubTotalRuleContext(pTempSubTotalRuleContext)
783 if ( !rAttrList.is() )
784 return;
786 for (auto &aIter : *rAttrList)
788 switch (aIter.getToken())
790 case XML_ELEMENT( TABLE, XML_FIELD_NUMBER ):
791 sFieldNumber = aIter.toString();
792 break;
793 case XML_ELEMENT( TABLE, XML_FUNCTION ):
794 sFunction = aIter.toString();
795 break;
800 ScXMLSubTotalFieldContext::~ScXMLSubTotalFieldContext()
804 void SAL_CALL ScXMLSubTotalFieldContext::endFastElement( sal_Int32 /*nElement*/ )
806 sheet::SubTotalColumn aSubTotalColumn;
807 aSubTotalColumn.Column = sFieldNumber.toInt32();
808 aSubTotalColumn.Function = ScXMLConverter::GetFunctionFromString( sFunction );
809 pSubTotalRuleContext->AddSubTotalColumn(aSubTotalColumn);
812 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */