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/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>
46 using namespace com::sun::star
;
47 using namespace xmloff::token
;
49 ScXMLDatabaseRangesContext::ScXMLDatabaseRangesContext( ScXMLImport
& rImport
) :
50 ScXMLImportContext( rImport
)
53 rImport
.LockSolarMutex();
56 ScXMLDatabaseRangesContext::~ScXMLDatabaseRangesContext()
58 GetScImport().UnlockSolarMutex();
61 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
ScXMLDatabaseRangesContext::createFastChildContext(
63 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
65 SvXMLImportContext
*pContext
= nullptr;
66 sax_fastparser::FastAttributeList
*pAttribList
=
67 sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList
);
71 case XML_ELEMENT( TABLE
, XML_DATABASE_RANGE
):
73 pContext
= new ScXMLDatabaseRangeContext( GetScImport(), pAttribList
);
79 pContext
= new SvXMLImportContext( GetImport() );
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
),
91 nSubTotalsUserListIndex(0),
94 bContainsSubTotal(false),
101 bSubTotalsBindFormatsToContent(false),
102 bSubTotalsIsCaseSensitive(false),
103 bSubTotalsInsertPageBreaks(false),
104 bSubTotalsSortGroups(false),
105 bSubTotalsEnabledUserList(false),
106 bSubTotalsAscending(true),
107 bFilterConditionSourceRange(false),
110 meRangeType(ScDBCollection::GlobalNamed
)
112 nSourceType
= sheet::DataImportMode_NONE
;
115 for( auto &aIter
: *rAttrList
)
117 switch( aIter
.getToken() )
119 case XML_ELEMENT( TABLE
, XML_NAME
):
121 sDatabaseRangeName
= aIter
.toString();
124 case XML_ELEMENT( TABLE
, XML_IS_SELECTION
):
126 bIsSelection
= IsXMLToken( aIter
, XML_TRUE
);
129 case XML_ELEMENT( TABLE
, XML_ON_UPDATE_KEEP_STYLES
):
131 bKeepFormats
= IsXMLToken( aIter
, XML_TRUE
);
134 case XML_ELEMENT( TABLE
, XML_ON_UPDATE_KEEP_SIZE
):
136 bMoveCells
= !IsXMLToken( aIter
, XML_TRUE
);
139 case XML_ELEMENT( TABLE
, XML_HAS_PERSISTENT_DATA
):
141 bStripData
= !IsXMLToken( aIter
, XML_TRUE
);
144 case XML_ELEMENT( TABLE
, XML_ORIENTATION
):
146 bByRow
= !IsXMLToken( aIter
, XML_COLUMN
);
147 mpQueryParam
->bByRow
= bByRow
;
150 case XML_ELEMENT( TABLE
, XML_CONTAINS_HEADER
):
152 bHasHeader
= IsXMLToken( aIter
, XML_TRUE
);
153 mpQueryParam
->bHasHeader
= bHasHeader
;
156 case XML_ELEMENT( TABLE
, XML_DISPLAY_FILTER_BUTTONS
):
158 bAutoFilter
= IsXMLToken( aIter
, XML_TRUE
);
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;
170 case XML_ELEMENT( TABLE
, XML_REFRESH_DELAY
):
173 if (::sax::Converter::convertDuration( fTime
, aIter
.toString() ))
174 nRefresh
= std::max( static_cast<sal_Int32
>(fTime
* 86400.0), sal_Int32(0) );
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
);
206 case XML_ELEMENT( TABLE
, XML_DATABASE_SOURCE_SQL
):
208 pContext
= new ScXMLSourceSQLContext( GetScImport(), pAttribList
, this);
211 case XML_ELEMENT( TABLE
, XML_DATABASE_SOURCE_TABLE
):
213 pContext
= new ScXMLSourceTableContext( GetScImport(), pAttribList
, this);
216 case XML_ELEMENT( TABLE
, XML_DATABASE_SOURCE_QUERY
):
218 pContext
= new ScXMLSourceQueryContext( GetScImport(), pAttribList
, this);
221 case XML_ELEMENT( TABLE
, XML_FILTER
):
223 pContext
= new ScXMLFilterContext(
224 GetScImport(), pAttribList
, *mpQueryParam
, this);
227 case XML_ELEMENT( TABLE
, XML_SORT
):
229 bContainsSort
= true;
230 pContext
= new ScXMLSortContext( GetScImport(), pAttribList
, this);
233 case XML_ELEMENT( TABLE
, XML_SUBTOTAL_RULES
):
235 bContainsSubTotal
= true;
236 pContext
= new ScXMLSubTotalRulesContext( GetScImport(), pAttribList
, this);
242 pContext
= new SvXMLImportContext( GetImport() );
247 std::unique_ptr
<ScDBData
> ScXMLDatabaseRangeContext::ConvertToDBData(const OUString
& rName
)
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
;
276 case sheet::DataImportMode_NONE
:
277 aParam
.bImport
= false;
279 case sheet::DataImportMode_SQL
:
280 aParam
.bImport
= true;
283 case sheet::DataImportMode_TABLE
:
284 aParam
.bImport
= true;
286 aParam
.nType
= ScDbTable
;
288 case sheet::DataImportMode_QUERY
:
289 aParam
.bImport
= true;
291 aParam
.nType
= ScDbQuery
;
294 OSL_FAIL("Unknown data import mode");
295 aParam
.bImport
= false;
297 pData
->SetImportParam(aParam
);
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
;
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
)
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
;
335 for (const auto& rSubTotalRule
: aSubTotalRules
)
337 if (nPos
>= MAXSUBTOTAL
)
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
;
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
));
362 aParam
.pSubTotals
[nPos
] = nullptr;
363 aParam
.pFunctions
[nPos
] = nullptr;
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());
383 bool setAutoFilterFlags(ScDocument
& rDoc
, const ScDBData
& rData
)
385 if (!rData
.HasAutoFilter())
388 // Set autofilter flags so that the buttons get displayed.
390 rData
.GetArea(aRange
);
392 aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aStart
.Row(),
393 aRange
.aStart
.Tab(), ScMF::Auto
);
399 void SAL_CALL
ScXMLDatabaseRangeContext::endFastElement( sal_Int32
/*nElement*/ )
401 ScDocument
* pDoc
= GetScImport().GetDocument();
405 if (meRangeType
== ScDBCollection::SheetAnonymous
)
407 ::std::unique_ptr
<ScDBData
> pData(ConvertToDBData(STR_DB_LOCAL_NONAME
));
412 pData
->GetArea(aRange
);
414 setAutoFilterFlags(*pDoc
, *pData
);
415 pDoc
->SetAnonymousDBData(aRange
.aStart
.Tab(), std::move(pData
));
419 else if (meRangeType
== ScDBCollection::GlobalAnonymous
)
421 ::std::unique_ptr
<ScDBData
> pData(ConvertToDBData(STR_DB_GLOBAL_NONAME
));
426 pData
->GetArea(aRange
);
428 if (setAutoFilterFlags(*pDoc
, *pData
))
429 pDoc
->SetAnonymousDBData(aRange
.aStart
.Tab(), std::move(pData
));
431 pDoc
->GetDBCollection()->getAnonDBs().insert(pData
.release());
435 else if (meRangeType
== ScDBCollection::GlobalNamed
)
437 ::std::unique_ptr
<ScDBData
> pData(ConvertToDBData(sDatabaseRangeName
));
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();
462 case XML_ELEMENT( TABLE
, XML_SQL_STATEMENT
):
463 pDatabaseRangeContext
->SetSourceObject(aIter
.toString());
465 case XML_ELEMENT( TABLE
, XML_PARSE_SQL_STATEMENT
):
466 pDatabaseRangeContext
->SetNative(IsXMLToken(aIter
, XML_TRUE
));
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
);
491 pContext
= new SvXMLImportContext( GetImport() );
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();
517 case XML_ELEMENT( TABLE
, XML_TABLE_NAME
):
518 case XML_ELEMENT( TABLE
, XML_DATABASE_TABLE_NAME
):
519 pDatabaseRangeContext
->SetSourceObject(aIter
.toString());
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
);
544 pContext
= new SvXMLImportContext( GetImport() );
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();
570 case XML_ELEMENT( TABLE
, XML_QUERY_NAME
):
571 pDatabaseRangeContext
->SetSourceObject(aIter
.toString());
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
);
596 pContext
= new SvXMLImportContext( GetImport() );
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
)
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
));
642 case XML_ELEMENT( TABLE
, XML_CASE_SENSITIVE
):
643 pDatabaseRangeContext
->SetSubTotalsIsCaseSensitive(IsXMLToken(aIter
, XML_TRUE
));
645 case XML_ELEMENT( TABLE
, XML_PAGE_BREAKS_ON_GROUP_CHANGE
):
646 pDatabaseRangeContext
->SetSubTotalsInsertPageBreaks(IsXMLToken(aIter
, XML_TRUE
));
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
);
666 case XML_ELEMENT( TABLE
, XML_SORT_GROUPS
):
668 pContext
= new ScXMLSortGroupsContext( GetScImport(), pAttribList
, pDatabaseRangeContext
);
671 case XML_ELEMENT( TABLE
, XML_SUBTOTAL_RULE
):
673 pContext
= new ScXMLSubTotalRuleContext( GetScImport(), pAttribList
, pDatabaseRangeContext
);
679 pContext
= new SvXMLImportContext( GetImport() );
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()));
710 //if (IsXMLToken(aIter, XML_AUTOMATIC))
711 //aSortField.FieldType = util::SortFieldType_AUTOMATIC;
712 // is not supported by StarOffice
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
726 case XML_ELEMENT( TABLE
, XML_ORDER
):
728 if (IsXMLToken(aIter
, XML_ASCENDING
))
729 pDatabaseRangeContext
->SetSubTotalsAscending(true);
731 pDatabaseRangeContext
->SetSubTotalsAscending(false);
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());
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
);
776 case XML_ELEMENT( TABLE
, XML_SUBTOTAL_FIELD
):
778 pContext
= new ScXMLSubTotalFieldContext( GetScImport(), pAttribList
, this);
784 pContext
= new SvXMLImportContext( GetImport() );
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();
810 case XML_ELEMENT( TABLE
, XML_FUNCTION
):
811 sFunction
= aIter
.toString();
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: */