1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
27 #include <datauno.hxx>
29 #include <unonames.hxx>
30 #include "XMLConverter.hxx"
31 #include <rangeutl.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>
47 using namespace com::sun::star
;
48 using namespace xmloff::token
;
50 ScXMLDatabaseRangesContext::ScXMLDatabaseRangesContext( ScXMLImport
& rImport
) :
51 ScXMLImportContext( rImport
)
54 rImport
.LockSolarMutex();
57 ScXMLDatabaseRangesContext::~ScXMLDatabaseRangesContext()
59 GetScImport().UnlockSolarMutex();
62 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
ScXMLDatabaseRangesContext::createFastChildContext(
64 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
66 SvXMLImportContext
*pContext
= nullptr;
67 sax_fastparser::FastAttributeList
*pAttribList
=
68 &sax_fastparser::castToFastAttributeList( xAttrList
);
72 case XML_ELEMENT( TABLE
, XML_DATABASE_RANGE
):
74 pContext
= new ScXMLDatabaseRangeContext( GetScImport(), pAttribList
);
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
),
89 nSubTotalsUserListIndex(0),
92 bContainsSubTotal(false),
99 bSubTotalsBindFormatsToContent(false),
100 bSubTotalsIsCaseSensitive(false),
101 bSubTotalsInsertPageBreaks(false),
102 bSubTotalsSortGroups(false),
103 bSubTotalsEnabledUserList(false),
104 bSubTotalsAscending(true),
105 bFilterConditionSourceRange(false),
108 meRangeType(ScDBCollection::GlobalNamed
)
112 for( auto &aIter
: *rAttrList
)
114 switch( aIter
.getToken() )
116 case XML_ELEMENT( TABLE
, XML_NAME
):
118 sDatabaseRangeName
= aIter
.toString();
121 case XML_ELEMENT( TABLE
, XML_IS_SELECTION
):
123 bIsSelection
= IsXMLToken( aIter
, XML_TRUE
);
126 case XML_ELEMENT( TABLE
, XML_ON_UPDATE_KEEP_STYLES
):
128 bKeepFormats
= IsXMLToken( aIter
, XML_TRUE
);
131 case XML_ELEMENT( TABLE
, XML_ON_UPDATE_KEEP_SIZE
):
133 bMoveCells
= !IsXMLToken( aIter
, XML_TRUE
);
136 case XML_ELEMENT( TABLE
, XML_HAS_PERSISTENT_DATA
):
138 bStripData
= !IsXMLToken( aIter
, XML_TRUE
);
141 case XML_ELEMENT( TABLE
, XML_ORIENTATION
):
143 bByRow
= !IsXMLToken( aIter
, XML_COLUMN
);
144 mpQueryParam
->bByRow
= bByRow
;
147 case XML_ELEMENT( TABLE
, XML_CONTAINS_HEADER
):
149 bHasHeader
= IsXMLToken( aIter
, XML_TRUE
);
150 mpQueryParam
->bHasHeader
= bHasHeader
;
153 case XML_ELEMENT( TABLE
, XML_DISPLAY_FILTER_BUTTONS
):
155 bAutoFilter
= IsXMLToken( aIter
, XML_TRUE
);
158 case XML_ELEMENT( TABLE
, XML_TARGET_RANGE_ADDRESS
):
160 ScDocument
* pDoc
= GetScImport().GetDocument();
162 sal_Int32 nOffset
= 0;
163 if (!ScRangeStringConverter::GetRangeFromString(
164 maRange
, aIter
.toString(), *pDoc
, ::formula::FormulaGrammar::CONV_OOO
, nOffset
))
165 mbValidRange
= false;
168 case XML_ELEMENT( TABLE
, XML_REFRESH_DELAY
):
171 if (::sax::Converter::convertDuration( fTime
, aIter
.toView() ))
172 nRefresh
= std::max( static_cast<sal_Int32
>(fTime
* 86400.0), sal_Int32(0) );
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
);
204 case XML_ELEMENT( TABLE
, XML_DATABASE_SOURCE_SQL
):
206 pContext
= new ScXMLSourceSQLContext( GetScImport(), pAttribList
, this);
209 case XML_ELEMENT( TABLE
, XML_DATABASE_SOURCE_TABLE
):
211 pContext
= new ScXMLSourceTableContext( GetScImport(), pAttribList
, this);
214 case XML_ELEMENT( TABLE
, XML_DATABASE_SOURCE_QUERY
):
216 pContext
= new ScXMLSourceQueryContext( GetScImport(), pAttribList
, this);
219 case XML_ELEMENT( TABLE
, XML_FILTER
):
221 pContext
= new ScXMLFilterContext(
222 GetScImport(), pAttribList
, *mpQueryParam
, this);
225 case XML_ELEMENT( TABLE
, XML_SORT
):
227 bContainsSort
= true;
228 pContext
= new ScXMLSortContext( GetScImport(), pAttribList
, this);
231 case XML_ELEMENT( TABLE
, XML_SUBTOTAL_RULES
):
233 bContainsSubTotal
= true;
234 pContext
= new ScXMLSubTotalRulesContext( GetScImport(), pAttribList
, this);
242 std::unique_ptr
<ScDBData
> ScXMLDatabaseRangeContext::ConvertToDBData(const OUString
& rName
)
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
;
273 case sheet::DataImportMode_NONE
:
274 aParam
.bImport
= false;
276 case sheet::DataImportMode_SQL
:
277 aParam
.bImport
= true;
280 case sheet::DataImportMode_TABLE
:
281 aParam
.bImport
= true;
283 aParam
.nType
= ScDbTable
;
285 case sheet::DataImportMode_QUERY
:
286 aParam
.bImport
= true;
288 aParam
.nType
= ScDbQuery
;
291 OSL_FAIL("Unknown data import mode");
292 aParam
.bImport
= false;
294 pData
->SetImportParam(aParam
);
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
;
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
)
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
;
332 for (const auto& rSubTotalRule
: aSubTotalRules
)
334 if (nPos
>= MAXSUBTOTAL
)
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
;
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
));
359 aParam
.pSubTotals
[nPos
].reset();
360 aParam
.pFunctions
[nPos
].reset();
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());
380 bool setAutoFilterFlags(ScDocument
& rDoc
, const ScDBData
& rData
)
382 if (!rData
.HasAutoFilter())
385 // Set autofilter flags so that the buttons get displayed.
387 rData
.GetArea(aRange
);
389 aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aStart
.Row(),
390 aRange
.aStart
.Tab(), ScMF::Auto
);
396 void SAL_CALL
ScXMLDatabaseRangeContext::endFastElement( sal_Int32
/*nElement*/ )
398 ScDocument
* pDoc
= GetScImport().GetDocument();
402 if (meRangeType
== ScDBCollection::SheetAnonymous
)
404 ::std::unique_ptr
<ScDBData
> pData(ConvertToDBData(STR_DB_LOCAL_NONAME
));
409 pData
->GetArea(aRange
);
411 setAutoFilterFlags(*pDoc
, *pData
);
412 pDoc
->SetAnonymousDBData(aRange
.aStart
.Tab(), std::move(pData
));
416 else if (meRangeType
== ScDBCollection::GlobalAnonymous
)
418 ::std::unique_ptr
<ScDBData
> pData(ConvertToDBData(STR_DB_GLOBAL_NONAME
));
423 pData
->GetArea(aRange
);
425 if (setAutoFilterFlags(*pDoc
, *pData
))
426 pDoc
->SetAnonymousDBData(aRange
.aStart
.Tab(), std::move(pData
));
428 pDoc
->GetDBCollection()->getAnonDBs().insert(pData
.release());
432 else if (meRangeType
== ScDBCollection::GlobalNamed
)
434 ::std::unique_ptr
<ScDBData
> pData(ConvertToDBData(sDatabaseRangeName
));
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();
459 case XML_ELEMENT( TABLE
, XML_SQL_STATEMENT
):
460 pDatabaseRangeContext
->SetSourceObject(aIter
.toString());
462 case XML_ELEMENT( TABLE
, XML_PARSE_SQL_STATEMENT
):
463 pDatabaseRangeContext
->SetNative(IsXMLToken(aIter
, XML_TRUE
));
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
);
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();
511 case XML_ELEMENT( TABLE
, XML_TABLE_NAME
):
512 case XML_ELEMENT( TABLE
, XML_DATABASE_TABLE_NAME
):
513 pDatabaseRangeContext
->SetSourceObject(aIter
.toString());
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
);
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();
561 case XML_ELEMENT( TABLE
, XML_QUERY_NAME
):
562 pDatabaseRangeContext
->SetSourceObject(aIter
.toString());
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
);
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
)
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() )
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
));
631 case XML_ELEMENT( TABLE
, XML_CASE_SENSITIVE
):
632 pDatabaseRangeContext
->SetSubTotalsIsCaseSensitive(IsXMLToken(aIter
, XML_TRUE
));
634 case XML_ELEMENT( TABLE
, XML_PAGE_BREAKS_ON_GROUP_CHANGE
):
635 pDatabaseRangeContext
->SetSubTotalsInsertPageBreaks(IsXMLToken(aIter
, XML_TRUE
));
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
);
654 case XML_ELEMENT( TABLE
, XML_SORT_GROUPS
):
656 pContext
= new ScXMLSortGroupsContext( GetScImport(), pAttribList
, pDatabaseRangeContext
);
659 case XML_ELEMENT( TABLE
, XML_SUBTOTAL_RULE
):
661 pContext
= new ScXMLSubTotalRuleContext( GetScImport(), pAttribList
, pDatabaseRangeContext
);
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() )
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
)));
696 //if (IsXMLToken(aIter, XML_AUTOMATIC))
697 //aSortField.FieldType = util::SortFieldType_AUTOMATIC;
698 // is not supported by StarOffice
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
712 case XML_ELEMENT( TABLE
, XML_ORDER
):
714 if (IsXMLToken(aIter
, XML_ASCENDING
))
715 pDatabaseRangeContext
->SetSubTotalsAscending(true);
717 pDatabaseRangeContext
->SetSubTotalsAscending(false);
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());
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
);
761 case XML_ELEMENT( TABLE
, XML_SUBTOTAL_FIELD
):
763 pContext
= new ScXMLSubTotalFieldContext( GetScImport(), pAttribList
, this);
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() )
786 for (auto &aIter
: *rAttrList
)
788 switch (aIter
.getToken())
790 case XML_ELEMENT( TABLE
, XML_FIELD_NUMBER
):
791 sFieldNumber
= aIter
.toString();
793 case XML_ELEMENT( TABLE
, XML_FUNCTION
):
794 sFunction
= aIter
.toString();
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: */