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 "xmlfilti.hxx"
21 #include "xmlimprt.hxx"
23 #include "convuno.hxx"
24 #include "XMLConverter.hxx"
25 #include "rangeutl.hxx"
26 #include "queryentry.hxx"
27 #include "document.hxx"
29 #include <svl/sharedstringpool.hxx>
30 #include <xmloff/xmltkmap.hxx>
31 #include <xmloff/nmspmap.hxx>
32 #include <xmloff/xmltoken.hxx>
34 using namespace com::sun::star
;
35 using namespace xmloff::token
;
37 using ::com::sun::star::uno::Reference
;
38 using ::com::sun::star::xml::sax::XAttributeList
;
40 ScXMLFilterContext::ConnStackItem::ConnStackItem(bool bOr
) : mbOr(bOr
), mnCondCount(0) {}
42 ScXMLFilterContext::ScXMLFilterContext( ScXMLImport
& rImport
,
44 const OUString
& rLName
,
45 const Reference
<XAttributeList
>& xAttrList
,
47 ScXMLDatabaseRangeContext
* pTempDatabaseRangeContext
) :
48 SvXMLImportContext( rImport
, nPrfx
, rLName
),
50 pDatabaseRangeContext(pTempDatabaseRangeContext
),
51 bSkipDuplicates(false),
52 bCopyOutputData(false),
53 bConditionSourceRange(false)
55 ScDocument
* pDoc(GetScImport().GetDocument());
57 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
58 const SvXMLTokenMap
& rAttrTokenMap
= GetScImport().GetFilterAttrTokenMap();
59 for( sal_Int16 i
=0; i
< nAttrCount
; ++i
)
61 const OUString
& sAttrName(xAttrList
->getNameByIndex( i
));
63 sal_uInt16 nPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName(
64 sAttrName
, &aLocalName
);
65 const OUString
& sValue(xAttrList
->getValueByIndex( i
));
67 switch( rAttrTokenMap
.Get( nPrefix
, aLocalName
) )
69 case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS
:
73 if (ScRangeStringConverter::GetRangeFromString( aScRange
, sValue
, pDoc
, ::formula::FormulaGrammar::CONV_OOO
, nOffset
))
75 ScUnoConversion::FillApiAddress( aOutputPosition
, aScRange
.aStart
);
76 bCopyOutputData
= true;
80 case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS
:
83 if (ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress
, sValue
, pDoc
, ::formula::FormulaGrammar::CONV_OOO
, nOffset
))
84 bConditionSourceRange
= true;
87 case XML_TOK_FILTER_ATTR_CONDITION_SOURCE
:
89 // not supported by StarOffice
92 case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES
:
94 bSkipDuplicates
= !IsXMLToken(sValue
, XML_TRUE
);
101 ScXMLFilterContext::~ScXMLFilterContext()
105 SvXMLImportContext
*ScXMLFilterContext::CreateChildContext( sal_uInt16 nPrefix
,
106 const OUString
& rLName
,
107 const ::com::sun::star::uno::Reference
<
108 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
110 SvXMLImportContext
*pContext(0);
112 const SvXMLTokenMap
& rTokenMap(GetScImport().GetFilterElemTokenMap());
113 switch( rTokenMap
.Get( nPrefix
, rLName
) )
115 case XML_TOK_FILTER_AND
:
117 pContext
= new ScXMLAndContext(
118 GetScImport(), nPrefix
, rLName
, xAttrList
, mrQueryParam
, this);
121 case XML_TOK_FILTER_OR
:
123 pContext
= new ScXMLOrContext(
124 GetScImport(), nPrefix
, rLName
, xAttrList
, mrQueryParam
, this);
127 case XML_TOK_FILTER_CONDITION
:
129 pContext
= new ScXMLConditionContext(
130 GetScImport(), nPrefix
, rLName
, xAttrList
, mrQueryParam
, this);
136 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
141 void ScXMLFilterContext::EndElement()
143 mrQueryParam
.bInplace
= !bCopyOutputData
;
144 mrQueryParam
.bDuplicate
= !bSkipDuplicates
;
148 mrQueryParam
.nDestCol
= aOutputPosition
.Column
;
149 mrQueryParam
.nDestRow
= aOutputPosition
.Row
;
150 mrQueryParam
.nDestTab
= aOutputPosition
.Sheet
;
153 if (bConditionSourceRange
)
154 pDatabaseRangeContext
->SetFilterConditionSourceRangeAddress(aConditionSourceRangeAddress
);
157 void ScXMLFilterContext::OpenConnection(bool b
)
159 maConnStack
.push_back(ConnStackItem(b
));
162 void ScXMLFilterContext::CloseConnection()
164 maConnStack
.pop_back();
167 bool ScXMLFilterContext::GetConnection()
169 // For condition items in each stack, the first one gets the connection of
170 // the last stack, while the rest of them get that of the current stack.
172 if (maConnStack
.empty())
173 // This should never happen.
176 ConnStackItem
& rItem
= maConnStack
.back();
177 if (rItem
.mnCondCount
)
178 // secondary item gets the current connection.
181 // The next condition of this stack will get the current connection.
184 if (maConnStack
.size() < 2)
185 // There is no last stack. Likely the first condition in the first
186 // stack whose connection is not used. Default in
187 // ScQueryEntry::eConnect is SC_AND, so return false (AND instead of
188 // OR) here. Otherwise, when saving the document again, we'd write a
190 // <table:filter-or><table:filter-and>...</table:filter-and></table:filter-or>
191 // for two conditions connected with AND.
194 std::vector
<ConnStackItem
>::reverse_iterator itr
= maConnStack
.rbegin();
196 return itr
->mbOr
; // connection of the last stack.
199 ScXMLAndContext::ScXMLAndContext( ScXMLImport
& rImport
,
201 const OUString
& rLName
,
202 const Reference
<XAttributeList
>& /* xAttrList */,
203 ScQueryParam
& rParam
,
204 ScXMLFilterContext
* pTempFilterContext
) :
205 SvXMLImportContext( rImport
, nPrfx
, rLName
),
206 mrQueryParam(rParam
),
207 pFilterContext(pTempFilterContext
)
209 pFilterContext
->OpenConnection(false);
212 ScXMLAndContext::~ScXMLAndContext()
216 SvXMLImportContext
*ScXMLAndContext::CreateChildContext( sal_uInt16 nPrefix
,
217 const OUString
& rLName
,
218 const ::com::sun::star::uno::Reference
<
219 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
221 SvXMLImportContext
*pContext(0);
223 const SvXMLTokenMap
& rTokenMap(GetScImport().GetFilterElemTokenMap());
224 switch( rTokenMap
.Get( nPrefix
, rLName
) )
226 case XML_TOK_FILTER_OR
:
228 // not supported in StarOffice
231 case XML_TOK_FILTER_CONDITION
:
233 pContext
= new ScXMLConditionContext(
234 GetScImport(), nPrefix
, rLName
, xAttrList
, mrQueryParam
, pFilterContext
);
240 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
245 void ScXMLAndContext::EndElement()
247 pFilterContext
->CloseConnection();
250 ScXMLOrContext::ScXMLOrContext( ScXMLImport
& rImport
,
252 const OUString
& rLName
,
254 ::com::sun::star::xml::sax::XAttributeList
>& /* xAttrList */,
255 ScQueryParam
& rParam
,
256 ScXMLFilterContext
* pTempFilterContext
) :
257 SvXMLImportContext( rImport
, nPrfx
, rLName
),
258 mrQueryParam(rParam
),
259 pFilterContext(pTempFilterContext
)
261 pFilterContext
->OpenConnection(true);
264 ScXMLOrContext::~ScXMLOrContext()
268 SvXMLImportContext
*ScXMLOrContext::CreateChildContext( sal_uInt16 nPrefix
,
269 const OUString
& rLName
,
270 const ::com::sun::star::uno::Reference
<
271 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
273 SvXMLImportContext
*pContext(0);
275 const SvXMLTokenMap
& rTokenMap(GetScImport().GetFilterElemTokenMap());
276 switch( rTokenMap
.Get( nPrefix
, rLName
) )
278 case XML_TOK_FILTER_AND
:
280 pContext
= new ScXMLAndContext(
281 GetScImport(), nPrefix
, rLName
, xAttrList
, mrQueryParam
, pFilterContext
);
284 case XML_TOK_FILTER_CONDITION
:
286 pContext
= new ScXMLConditionContext(
287 GetScImport(), nPrefix
, rLName
, xAttrList
, mrQueryParam
, pFilterContext
);
293 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
298 void ScXMLOrContext::EndElement()
300 pFilterContext
->CloseConnection();
303 ScXMLConditionContext::ScXMLConditionContext(
304 ScXMLImport
& rImport
, sal_uInt16 nPrfx
, const OUString
& rLName
,
305 const Reference
<XAttributeList
>& xAttrList
,
306 ScQueryParam
& rParam
,
307 ScXMLFilterContext
* pTempFilterContext
) :
308 SvXMLImportContext( rImport
, nPrfx
, rLName
),
309 mrQueryParam(rParam
),
310 pFilterContext(pTempFilterContext
),
312 bIsCaseSensitive(false)
314 sDataType
= GetXMLToken(XML_TEXT
);
316 sal_Int16
nAttrCount(xAttrList
.is() ? xAttrList
->getLength() : 0);
317 const SvXMLTokenMap
& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
318 for( sal_Int16 i
=0; i
< nAttrCount
; ++i
)
320 const OUString
& sAttrName(xAttrList
->getNameByIndex( i
));
322 sal_uInt16 nPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName(
323 sAttrName
, &aLocalName
);
324 const OUString
& sValue(xAttrList
->getValueByIndex( i
));
326 switch( rAttrTokenMap
.Get( nPrefix
, aLocalName
) )
328 case XML_TOK_CONDITION_ATTR_FIELD_NUMBER
:
330 nField
= sValue
.toInt32();
333 case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE
:
335 bIsCaseSensitive
= IsXMLToken(sValue
, XML_TRUE
);
338 case XML_TOK_CONDITION_ATTR_DATA_TYPE
:
343 case XML_TOK_CONDITION_ATTR_VALUE
:
345 sConditionValue
= sValue
;
348 case XML_TOK_CONDITION_ATTR_OPERATOR
:
357 ScXMLConditionContext::~ScXMLConditionContext()
361 SvXMLImportContext
*ScXMLConditionContext::CreateChildContext( sal_uInt16 nPrefix
,
362 const OUString
& rLName
,
363 const Reference
<XAttributeList
>& xAttrList
)
365 SvXMLImportContext
*pContext
= NULL
;
367 const SvXMLTokenMap
& rTokenMap(GetScImport().GetFilterConditionElemTokenMap());
368 switch( rTokenMap
.Get( nPrefix
, rLName
) )
370 case XML_TOK_CONDITION_FILTER_SET_ITEM
:
372 pContext
= new ScXMLSetItemContext(
373 GetScImport(), nPrefix
, rLName
, xAttrList
, *this);
379 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
384 void ScXMLConditionContext::GetOperator(
385 const OUString
& aOpStr
, ScQueryParam
& rParam
, ScQueryEntry
& rEntry
)
387 rParam
.bRegExp
= false;
388 if (IsXMLToken(aOpStr
, XML_MATCH
))
390 rParam
.bRegExp
= true;
391 rEntry
.eOp
= SC_EQUAL
;
393 else if (IsXMLToken(aOpStr
, XML_NOMATCH
))
395 rParam
.bRegExp
= true;
396 rEntry
.eOp
= SC_NOT_EQUAL
;
398 else if (aOpStr
== "=")
399 rEntry
.eOp
= SC_EQUAL
;
400 else if (aOpStr
== "!=")
401 rEntry
.eOp
= SC_NOT_EQUAL
;
402 else if (IsXMLToken(aOpStr
, XML_BOTTOM_PERCENT
))
403 rEntry
.eOp
= SC_BOTPERC
;
404 else if (IsXMLToken(aOpStr
, XML_BOTTOM_VALUES
))
405 rEntry
.eOp
= SC_BOTVAL
;
406 else if (IsXMLToken(aOpStr
, XML_EMPTY
))
407 rEntry
.SetQueryByEmpty();
408 else if (aOpStr
== ">")
409 rEntry
.eOp
= SC_GREATER
;
410 else if (aOpStr
== ">=")
411 rEntry
.eOp
= SC_GREATER_EQUAL
;
412 else if (aOpStr
== "<")
413 rEntry
.eOp
= SC_LESS
;
414 else if (aOpStr
== "<=")
415 rEntry
.eOp
= SC_LESS_EQUAL
;
416 else if (IsXMLToken(aOpStr
, XML_NOEMPTY
))
417 rEntry
.SetQueryByNonEmpty();
418 else if (IsXMLToken(aOpStr
, XML_TOP_PERCENT
))
419 rEntry
.eOp
= SC_TOPPERC
;
420 else if (IsXMLToken(aOpStr
, XML_TOP_VALUES
))
421 rEntry
.eOp
= SC_TOPVAL
;
422 else if (IsXMLToken(aOpStr
, XML_CONTAINS
))
423 rEntry
.eOp
= SC_CONTAINS
;
424 else if (IsXMLToken(aOpStr
, XML_DOES_NOT_CONTAIN
))
425 rEntry
.eOp
= SC_DOES_NOT_CONTAIN
;
426 else if (IsXMLToken(aOpStr
, XML_BEGINS_WITH
))
427 rEntry
.eOp
= SC_BEGINS_WITH
;
428 else if (IsXMLToken(aOpStr
, XML_DOES_NOT_BEGIN_WITH
))
429 rEntry
.eOp
= SC_DOES_NOT_BEGIN_WITH
;
430 else if (IsXMLToken(aOpStr
, XML_ENDS_WITH
))
431 rEntry
.eOp
= SC_ENDS_WITH
;
432 else if (IsXMLToken(aOpStr
, XML_DOES_NOT_END_WITH
))
433 rEntry
.eOp
= SC_DOES_NOT_END_WITH
;
436 void ScXMLConditionContext::AddSetItem(const ScQueryEntry::Item
& rItem
)
438 maQueryItems
.push_back(rItem
);
441 void ScXMLConditionContext::EndElement()
443 ScQueryEntry
& rEntry
= mrQueryParam
.AppendEntry();
445 // We currently don't support per-condition case sensitivity.
446 mrQueryParam
.bCaseSens
= bIsCaseSensitive
;
448 rEntry
.bDoQuery
= true;
449 rEntry
.eConnect
= pFilterContext
->GetConnection() ? SC_OR
: SC_AND
;
451 GetOperator(sOperator
, mrQueryParam
, rEntry
);
452 SCCOLROW nStartPos
= mrQueryParam
.bByRow
? mrQueryParam
.nCol1
: mrQueryParam
.nRow1
;
453 rEntry
.nField
= nField
+ nStartPos
;
455 if (maQueryItems
.empty())
457 ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
458 if (IsXMLToken(sDataType
, XML_NUMBER
))
460 rItem
.mfVal
= sConditionValue
.toDouble();
461 rItem
.meType
= ScQueryEntry::ByValue
;
465 svl::SharedStringPool
& rPool
= GetScImport().GetDocument()->GetSharedStringPool();
466 rItem
.maString
= rPool
.intern(sConditionValue
);
467 rItem
.meType
= ScQueryEntry::ByString
;
471 rEntry
.GetQueryItems().swap(maQueryItems
);
474 const ScXMLImport
& ScXMLSetItemContext::GetScImport() const
476 return static_cast<const ScXMLImport
&>(GetImport());
479 ScXMLImport
& ScXMLSetItemContext::GetScImport()
481 return static_cast<ScXMLImport
&>(GetImport());
484 ScXMLSetItemContext::ScXMLSetItemContext(
485 ScXMLImport
& rImport
, sal_uInt16 nPrfx
, const OUString
& rLName
,
486 const Reference
<XAttributeList
>& xAttrList
, ScXMLConditionContext
& rParent
) :
487 SvXMLImportContext(rImport
, nPrfx
, rLName
)
489 sal_Int32 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
490 const SvXMLTokenMap
& rAttrTokenMap
= GetScImport().GetFilterSetItemAttrTokenMap();
491 for (sal_Int32 i
= 0; i
< nAttrCount
; ++i
)
493 const OUString
& sAttrName
= xAttrList
->getNameByIndex(i
);
496 GetScImport().GetNamespaceMap().GetKeyByAttrName(sAttrName
, &aLocalName
);
498 const OUString
& sValue
= xAttrList
->getValueByIndex(i
);
500 switch (rAttrTokenMap
.Get(nPrefix
, aLocalName
))
502 case XML_TOK_FILTER_SET_ITEM_ATTR_VALUE
:
504 svl::SharedStringPool
& rPool
= GetScImport().GetDocument()->GetSharedStringPool();
505 ScQueryEntry::Item aItem
;
506 aItem
.maString
= rPool
.intern(sValue
);
507 aItem
.meType
= ScQueryEntry::ByString
;
509 rParent
.AddSetItem(aItem
);
516 SvXMLImportContext
* ScXMLSetItemContext::CreateChildContext(
517 sal_uInt16 nPrefix
, const OUString
& rLName
,
518 const Reference
<XAttributeList
>& /*xAttrList*/ )
520 return new SvXMLImportContext( GetImport(), nPrefix
, rLName
);;
523 ScXMLSetItemContext::~ScXMLSetItemContext()
527 void ScXMLSetItemContext::EndElement()
531 ScXMLDPFilterContext::ScXMLDPFilterContext( ScXMLImport
& rImport
,
533 const OUString
& rLName
,
534 const ::com::sun::star::uno::Reference
<
535 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
,
536 ScXMLDataPilotTableContext
* pTempDataPilotTableContext
) :
537 SvXMLImportContext( rImport
, nPrfx
, rLName
),
538 pDataPilotTable(pTempDataPilotTableContext
),
540 nFilterFieldCount(0),
541 bSkipDuplicates(false),
542 bCopyOutputData(false),
543 bUseRegularExpressions(false),
544 bIsCaseSensitive(false),
546 bNextConnectionOr(true),
547 bConditionSourceRange(false)
549 ScDocument
* pDoc(GetScImport().GetDocument());
551 sal_Int16
nAttrCount(xAttrList
.is() ? xAttrList
->getLength() : 0);
552 const SvXMLTokenMap
& rAttrTokenMap(GetScImport().GetFilterAttrTokenMap());
553 for( sal_Int16 i
=0; i
< nAttrCount
; ++i
)
555 const OUString
& sAttrName(xAttrList
->getNameByIndex( i
));
557 sal_uInt16
nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
558 sAttrName
, &aLocalName
));
559 const OUString
& sValue(xAttrList
->getValueByIndex( i
));
561 switch( rAttrTokenMap
.Get( nPrefix
, aLocalName
) )
563 case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS
:
566 sal_Int32
nOffset(0);
567 if (ScRangeStringConverter::GetRangeFromString( aScRange
, sValue
, pDoc
, ::formula::FormulaGrammar::CONV_OOO
, nOffset
))
569 aOutputPosition
= aScRange
.aStart
;
570 bCopyOutputData
= true;
574 case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS
:
576 sal_Int32
nOffset(0);
577 if(ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress
, sValue
, pDoc
, ::formula::FormulaGrammar::CONV_OOO
, nOffset
))
578 bConditionSourceRange
= true;
581 case XML_TOK_FILTER_ATTR_CONDITION_SOURCE
:
583 // not supported by StarOffice
586 case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES
:
588 bSkipDuplicates
= !IsXMLToken(sValue
, XML_TRUE
);
595 ScXMLDPFilterContext::~ScXMLDPFilterContext()
599 SvXMLImportContext
*ScXMLDPFilterContext::CreateChildContext( sal_uInt16 nPrefix
,
600 const OUString
& rLName
,
601 const ::com::sun::star::uno::Reference
<
602 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
604 SvXMLImportContext
*pContext(0);
606 const SvXMLTokenMap
& rTokenMap(GetScImport().GetFilterElemTokenMap());
607 switch( rTokenMap
.Get( nPrefix
, rLName
) )
609 case XML_TOK_FILTER_AND
:
611 pContext
= new ScXMLDPAndContext( GetScImport(), nPrefix
,
612 rLName
, xAttrList
, this);
615 case XML_TOK_FILTER_OR
:
617 pContext
= new ScXMLDPOrContext( GetScImport(), nPrefix
,
618 rLName
, xAttrList
, this);
621 case XML_TOK_FILTER_CONDITION
:
623 pContext
= new ScXMLDPConditionContext( GetScImport(), nPrefix
,
624 rLName
, xAttrList
, this);
630 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
635 void ScXMLDPFilterContext::EndElement()
637 aFilterFields
.bRegExp
= bUseRegularExpressions
;
638 aFilterFields
.bCaseSens
= bIsCaseSensitive
;
639 aFilterFields
.bDuplicate
= !bSkipDuplicates
;
641 pDataPilotTable
->SetFilterOutputPosition(aOutputPosition
);
643 pDataPilotTable
->SetSourceQueryParam(aFilterFields
);
644 if (bConditionSourceRange
)
645 pDataPilotTable
->SetFilterSourceRange(aConditionSourceRangeAddress
);
648 void ScXMLDPFilterContext::AddFilterField (const ScQueryEntry
& aFilterField
)
650 aFilterFields
.Resize(nFilterFieldCount
+ 1);
651 ScQueryEntry
& rEntry(aFilterFields
.GetEntry(nFilterFieldCount
));
652 rEntry
= aFilterField
;
653 rEntry
.bDoQuery
= true;
657 ScXMLDPAndContext::ScXMLDPAndContext( ScXMLImport
& rImport
,
659 const OUString
& rLName
,
660 const ::com::sun::star::uno::Reference
<
661 ::com::sun::star::xml::sax::XAttributeList
>& /* xAttrList */,
662 ScXMLDPFilterContext
* pTempFilterContext
) :
663 SvXMLImportContext( rImport
, nPrfx
, rLName
)
665 pFilterContext
= pTempFilterContext
;
666 pFilterContext
->OpenConnection(false);
669 ScXMLDPAndContext::~ScXMLDPAndContext()
673 SvXMLImportContext
*ScXMLDPAndContext::CreateChildContext( sal_uInt16 nPrefix
,
674 const OUString
& rLName
,
675 const ::com::sun::star::uno::Reference
<
676 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
678 SvXMLImportContext
*pContext(0);
680 const SvXMLTokenMap
& rTokenMap(GetScImport().GetFilterElemTokenMap());
681 switch( rTokenMap
.Get( nPrefix
, rLName
) )
683 case XML_TOK_FILTER_OR
:
685 // not supported in StarOffice
688 case XML_TOK_FILTER_CONDITION
:
690 pContext
= new ScXMLDPConditionContext( GetScImport(), nPrefix
,
691 rLName
, xAttrList
, pFilterContext
);
697 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
702 void ScXMLDPAndContext::EndElement()
704 pFilterContext
->CloseConnection();
707 ScXMLDPOrContext::ScXMLDPOrContext( ScXMLImport
& rImport
,
709 const OUString
& rLName
,
710 const ::com::sun::star::uno::Reference
<
711 ::com::sun::star::xml::sax::XAttributeList
>& /* xAttrList */,
712 ScXMLDPFilterContext
* pTempFilterContext
) :
713 SvXMLImportContext( rImport
, nPrfx
, rLName
),
714 pFilterContext(pTempFilterContext
)
716 pFilterContext
->OpenConnection(true);
719 ScXMLDPOrContext::~ScXMLDPOrContext()
723 SvXMLImportContext
*ScXMLDPOrContext::CreateChildContext( sal_uInt16 nPrefix
,
724 const OUString
& rLName
,
725 const ::com::sun::star::uno::Reference
<
726 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
728 SvXMLImportContext
*pContext(0);
730 const SvXMLTokenMap
& rTokenMap(GetScImport().GetFilterElemTokenMap());
731 switch( rTokenMap
.Get( nPrefix
, rLName
) )
733 case XML_TOK_FILTER_AND
:
735 pContext
= new ScXMLDPAndContext( GetScImport(), nPrefix
,
736 rLName
, xAttrList
, pFilterContext
);
739 case XML_TOK_FILTER_CONDITION
:
741 pContext
= new ScXMLDPConditionContext( GetScImport(), nPrefix
,
742 rLName
, xAttrList
, pFilterContext
);
748 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
753 void ScXMLDPOrContext::EndElement()
755 pFilterContext
->CloseConnection();
758 ScXMLDPConditionContext::ScXMLDPConditionContext( ScXMLImport
& rImport
,
760 const OUString
& rLName
,
761 const ::com::sun::star::uno::Reference
<
762 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
,
763 ScXMLDPFilterContext
* pTempFilterContext
) :
764 SvXMLImportContext( rImport
, nPrfx
, rLName
),
765 pFilterContext(pTempFilterContext
),
766 sDataType(GetXMLToken(XML_TEXT
)),
768 bIsCaseSensitive(false)
771 sal_Int16
nAttrCount(xAttrList
.is() ? xAttrList
->getLength() : 0);
772 const SvXMLTokenMap
& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
773 for( sal_Int16 i
=0; i
< nAttrCount
; ++i
)
775 const OUString
& sAttrName(xAttrList
->getNameByIndex( i
));
777 sal_uInt16
nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
778 sAttrName
, &aLocalName
));
779 const OUString
& sValue(xAttrList
->getValueByIndex( i
));
781 switch( rAttrTokenMap
.Get( nPrefix
, aLocalName
) )
783 case XML_TOK_CONDITION_ATTR_FIELD_NUMBER
:
785 nField
= sValue
.toInt32();
788 case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE
:
790 bIsCaseSensitive
= IsXMLToken(sValue
, XML_TRUE
);
793 case XML_TOK_CONDITION_ATTR_DATA_TYPE
:
798 case XML_TOK_CONDITION_ATTR_VALUE
:
800 sConditionValue
= sValue
;
803 case XML_TOK_CONDITION_ATTR_OPERATOR
:
812 ScXMLDPConditionContext::~ScXMLDPConditionContext()
816 SvXMLImportContext
*ScXMLDPConditionContext::CreateChildContext( sal_uInt16 nPrefix
,
817 const OUString
& rLName
,
818 const ::com::sun::star::uno::Reference
<
819 ::com::sun::star::xml::sax::XAttributeList
>& /* xAttrList */ )
821 return new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
824 void ScXMLDPConditionContext::getOperatorXML(
825 const OUString
& sTempOperator
, ScQueryOp
& aFilterOperator
, bool& bUseRegularExpressions
)
827 bUseRegularExpressions
= false;
828 if (IsXMLToken(sTempOperator
, XML_MATCH
))
830 bUseRegularExpressions
= true;
831 aFilterOperator
= SC_EQUAL
;
833 else if (IsXMLToken(sTempOperator
, XML_NOMATCH
))
835 bUseRegularExpressions
= true;
836 aFilterOperator
= SC_NOT_EQUAL
;
838 else if (sTempOperator
== "=")
839 aFilterOperator
= SC_EQUAL
;
840 else if (sTempOperator
== "!=")
841 aFilterOperator
= SC_NOT_EQUAL
;
842 else if (IsXMLToken(sTempOperator
, XML_BOTTOM_PERCENT
))
843 aFilterOperator
= SC_BOTPERC
;
844 else if (IsXMLToken(sTempOperator
, XML_BOTTOM_VALUES
))
845 aFilterOperator
= SC_BOTVAL
;
846 else if (sTempOperator
== ">")
847 aFilterOperator
= SC_GREATER
;
848 else if (sTempOperator
== ">=")
849 aFilterOperator
= SC_GREATER_EQUAL
;
850 else if (sTempOperator
== "<")
851 aFilterOperator
= SC_LESS
;
852 else if (sTempOperator
== "<=")
853 aFilterOperator
= SC_LESS_EQUAL
;
854 else if (IsXMLToken(sTempOperator
, XML_TOP_PERCENT
))
855 aFilterOperator
= SC_TOPPERC
;
856 else if (IsXMLToken(sTempOperator
, XML_TOP_VALUES
))
857 aFilterOperator
= SC_TOPVAL
;
860 void ScXMLDPConditionContext::EndElement()
862 ScQueryEntry aFilterField
;
863 if (pFilterContext
->GetConnection())
864 aFilterField
.eConnect
= SC_OR
;
866 aFilterField
.eConnect
= SC_AND
;
867 pFilterContext
->SetIsCaseSensitive(bIsCaseSensitive
);
868 if (IsXMLToken(sOperator
, XML_EMPTY
))
869 aFilterField
.SetQueryByEmpty();
870 else if (IsXMLToken(sOperator
, XML_NOEMPTY
))
871 aFilterField
.SetQueryByNonEmpty();
874 bool bUseRegularExpressions
= false;
875 getOperatorXML(sOperator
, aFilterField
.eOp
, bUseRegularExpressions
);
876 pFilterContext
->SetUseRegularExpressions(bUseRegularExpressions
);
877 aFilterField
.nField
= nField
;
878 ScQueryEntry::Item
& rItem
= aFilterField
.GetQueryItem();
879 svl::SharedStringPool
& rPool
= GetScImport().GetDocument()->GetSharedStringPool();
881 if (IsXMLToken(sDataType
, XML_NUMBER
))
883 rItem
.mfVal
= sConditionValue
.toDouble();
884 rItem
.maString
= rPool
.intern(sConditionValue
);
885 rItem
.meType
= ScQueryEntry::ByValue
;
889 rItem
.maString
= rPool
.intern(sConditionValue
);
890 rItem
.meType
= ScQueryEntry::ByString
;
894 pFilterContext
->AddFilterField(aFilterField
);
897 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */