Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "xmlfilti.hxx"
21 : #include "xmlimprt.hxx"
22 : #include "docuno.hxx"
23 : #include "convuno.hxx"
24 : #include "XMLConverter.hxx"
25 : #include "rangeutl.hxx"
26 : #include "queryentry.hxx"
27 : #include "document.hxx"
28 :
29 : #include "svl/sharedstringpool.hxx"
30 : #include <xmloff/xmltkmap.hxx>
31 : #include <xmloff/nmspmap.hxx>
32 : #include <xmloff/xmltoken.hxx>
33 :
34 : using namespace com::sun::star;
35 : using namespace xmloff::token;
36 :
37 : using ::com::sun::star::uno::Reference;
38 : using ::com::sun::star::xml::sax::XAttributeList;
39 :
40 4 : ScXMLFilterContext::ConnStackItem::ConnStackItem(bool bOr) : mbOr(bOr), mnCondCount(0) {}
41 :
42 4 : ScXMLFilterContext::ScXMLFilterContext( ScXMLImport& rImport,
43 : sal_uInt16 nPrfx,
44 : const OUString& rLName,
45 : const Reference<XAttributeList>& xAttrList,
46 : ScQueryParam& rParam,
47 : ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
48 : SvXMLImportContext( rImport, nPrfx, rLName ),
49 : mrQueryParam(rParam),
50 : pDatabaseRangeContext(pTempDatabaseRangeContext),
51 : bSkipDuplicates(false),
52 : bCopyOutputData(false),
53 4 : bConditionSourceRange(false)
54 : {
55 4 : ScDocument* pDoc(GetScImport().GetDocument());
56 :
57 4 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
58 4 : const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetFilterAttrTokenMap();
59 4 : for( sal_Int16 i=0; i < nAttrCount; ++i )
60 : {
61 0 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
62 0 : OUString aLocalName;
63 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
64 0 : sAttrName, &aLocalName );
65 0 : const OUString& sValue(xAttrList->getValueByIndex( i ));
66 :
67 0 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
68 : {
69 : case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS :
70 : {
71 0 : ScRange aScRange;
72 0 : sal_Int32 nOffset(0);
73 0 : if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
74 : {
75 0 : ScUnoConversion::FillApiAddress( aOutputPosition, aScRange.aStart );
76 0 : bCopyOutputData = true;
77 : }
78 : }
79 0 : break;
80 : case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS :
81 : {
82 0 : sal_Int32 nOffset(0);
83 0 : if (ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
84 0 : bConditionSourceRange = true;
85 : }
86 0 : break;
87 : case XML_TOK_FILTER_ATTR_CONDITION_SOURCE :
88 : {
89 : // not supported by StarOffice
90 : }
91 0 : break;
92 : case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES :
93 : {
94 0 : bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE);
95 : }
96 0 : break;
97 : }
98 0 : }
99 4 : }
100 :
101 8 : ScXMLFilterContext::~ScXMLFilterContext()
102 : {
103 8 : }
104 :
105 4 : 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 )
109 : {
110 4 : SvXMLImportContext *pContext(0);
111 :
112 4 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
113 4 : switch( rTokenMap.Get( nPrefix, rLName ) )
114 : {
115 : case XML_TOK_FILTER_AND:
116 : {
117 : pContext = new ScXMLAndContext(
118 1 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, this);
119 : }
120 1 : break;
121 : case XML_TOK_FILTER_OR:
122 : {
123 : pContext = new ScXMLOrContext(
124 3 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, this);
125 : }
126 3 : break;
127 : case XML_TOK_FILTER_CONDITION:
128 : {
129 : pContext = new ScXMLConditionContext(
130 0 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, this);
131 : }
132 0 : break;
133 : }
134 :
135 4 : if( !pContext )
136 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
137 :
138 4 : return pContext;
139 : }
140 :
141 4 : void ScXMLFilterContext::EndElement()
142 : {
143 4 : mrQueryParam.bInplace = !bCopyOutputData;
144 4 : mrQueryParam.bDuplicate = !bSkipDuplicates;
145 :
146 4 : if (bCopyOutputData)
147 : {
148 0 : mrQueryParam.nDestCol = aOutputPosition.Column;
149 0 : mrQueryParam.nDestRow = aOutputPosition.Row;
150 0 : mrQueryParam.nDestTab = aOutputPosition.Sheet;
151 : }
152 :
153 4 : if (bConditionSourceRange)
154 0 : pDatabaseRangeContext->SetFilterConditionSourceRangeAddress(aConditionSourceRangeAddress);
155 4 : }
156 :
157 4 : void ScXMLFilterContext::OpenConnection(bool b)
158 : {
159 4 : maConnStack.push_back(ConnStackItem(b));
160 4 : }
161 :
162 4 : void ScXMLFilterContext::CloseConnection()
163 : {
164 4 : maConnStack.pop_back();
165 4 : }
166 :
167 5 : bool ScXMLFilterContext::GetConnection()
168 : {
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.
171 :
172 5 : if (maConnStack.empty())
173 : // This should never happen.
174 0 : return true;
175 :
176 5 : ConnStackItem& rItem = maConnStack.back();
177 5 : if (rItem.mnCondCount)
178 : // secondary item gets the current connection.
179 0 : return rItem.mbOr;
180 :
181 5 : if (maConnStack.size() < 2)
182 : // There is no last stack. Likely the first condition in the first
183 : // stack whose connection is not used.
184 5 : return true;
185 :
186 0 : ++rItem.mnCondCount;
187 0 : std::vector<ConnStackItem>::reverse_iterator itr = maConnStack.rbegin();
188 0 : ++itr;
189 0 : return itr->mbOr; // connection of the last stack.
190 : }
191 :
192 1 : ScXMLAndContext::ScXMLAndContext( ScXMLImport& rImport,
193 : sal_uInt16 nPrfx,
194 : const OUString& rLName,
195 : const Reference<XAttributeList>& /* xAttrList */,
196 : ScQueryParam& rParam,
197 : ScXMLFilterContext* pTempFilterContext) :
198 : SvXMLImportContext( rImport, nPrfx, rLName ),
199 : mrQueryParam(rParam),
200 1 : pFilterContext(pTempFilterContext)
201 : {
202 1 : pFilterContext->OpenConnection(false);
203 1 : }
204 :
205 2 : ScXMLAndContext::~ScXMLAndContext()
206 : {
207 2 : }
208 :
209 1 : SvXMLImportContext *ScXMLAndContext::CreateChildContext( sal_uInt16 nPrefix,
210 : const OUString& rLName,
211 : const ::com::sun::star::uno::Reference<
212 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
213 : {
214 1 : SvXMLImportContext *pContext(0);
215 :
216 1 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
217 1 : switch( rTokenMap.Get( nPrefix, rLName ) )
218 : {
219 : case XML_TOK_FILTER_OR:
220 : {
221 : // not supported in StarOffice
222 : }
223 0 : break;
224 : case XML_TOK_FILTER_CONDITION:
225 : {
226 : pContext = new ScXMLConditionContext(
227 1 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, pFilterContext);
228 : }
229 1 : break;
230 : }
231 :
232 1 : if( !pContext )
233 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
234 :
235 1 : return pContext;
236 : }
237 :
238 1 : void ScXMLAndContext::EndElement()
239 : {
240 1 : pFilterContext->CloseConnection();
241 1 : }
242 :
243 3 : ScXMLOrContext::ScXMLOrContext( ScXMLImport& rImport,
244 : sal_uInt16 nPrfx,
245 : const OUString& rLName,
246 : const Reference<
247 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
248 : ScQueryParam& rParam,
249 : ScXMLFilterContext* pTempFilterContext) :
250 : SvXMLImportContext( rImport, nPrfx, rLName ),
251 : mrQueryParam(rParam),
252 3 : pFilterContext(pTempFilterContext)
253 : {
254 3 : pFilterContext->OpenConnection(true);
255 3 : }
256 :
257 6 : ScXMLOrContext::~ScXMLOrContext()
258 : {
259 6 : }
260 :
261 4 : SvXMLImportContext *ScXMLOrContext::CreateChildContext( sal_uInt16 nPrefix,
262 : const OUString& rLName,
263 : const ::com::sun::star::uno::Reference<
264 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
265 : {
266 4 : SvXMLImportContext *pContext(0);
267 :
268 4 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
269 4 : switch( rTokenMap.Get( nPrefix, rLName ) )
270 : {
271 : case XML_TOK_FILTER_AND:
272 : {
273 : pContext = new ScXMLAndContext(
274 0 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, pFilterContext);
275 : }
276 0 : break;
277 : case XML_TOK_FILTER_CONDITION:
278 : {
279 : pContext = new ScXMLConditionContext(
280 4 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, pFilterContext);
281 : }
282 4 : break;
283 : }
284 :
285 4 : if( !pContext )
286 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
287 :
288 4 : return pContext;
289 : }
290 :
291 3 : void ScXMLOrContext::EndElement()
292 : {
293 3 : pFilterContext->CloseConnection();
294 3 : }
295 :
296 5 : ScXMLConditionContext::ScXMLConditionContext(
297 : ScXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
298 : const Reference<XAttributeList>& xAttrList,
299 : ScQueryParam& rParam,
300 : ScXMLFilterContext* pTempFilterContext) :
301 : SvXMLImportContext( rImport, nPrfx, rLName ),
302 : mrQueryParam(rParam),
303 : pFilterContext(pTempFilterContext),
304 : nField(0),
305 5 : bIsCaseSensitive(false)
306 : {
307 5 : sDataType = GetXMLToken(XML_TEXT);
308 :
309 5 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
310 5 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
311 20 : for( sal_Int16 i=0; i < nAttrCount; ++i )
312 : {
313 15 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
314 30 : OUString aLocalName;
315 15 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
316 15 : sAttrName, &aLocalName );
317 30 : const OUString& sValue(xAttrList->getValueByIndex( i ));
318 :
319 15 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
320 : {
321 : case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
322 : {
323 5 : nField = sValue.toInt32();
324 : }
325 5 : break;
326 : case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
327 : {
328 0 : bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
329 : }
330 0 : break;
331 : case XML_TOK_CONDITION_ATTR_DATA_TYPE :
332 : {
333 0 : sDataType = sValue;
334 : }
335 0 : break;
336 : case XML_TOK_CONDITION_ATTR_VALUE :
337 : {
338 5 : sConditionValue = sValue;
339 : }
340 5 : break;
341 : case XML_TOK_CONDITION_ATTR_OPERATOR :
342 : {
343 5 : sOperator = sValue;
344 : }
345 5 : break;
346 : }
347 15 : }
348 5 : }
349 :
350 10 : ScXMLConditionContext::~ScXMLConditionContext()
351 : {
352 10 : }
353 :
354 8 : SvXMLImportContext *ScXMLConditionContext::CreateChildContext( sal_uInt16 nPrefix,
355 : const OUString& rLName,
356 : const Reference<XAttributeList>& xAttrList )
357 : {
358 8 : SvXMLImportContext *pContext = NULL;
359 :
360 8 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterConditionElemTokenMap());
361 8 : switch( rTokenMap.Get( nPrefix, rLName ) )
362 : {
363 : case XML_TOK_CONDITION_FILTER_SET_ITEM:
364 : {
365 : pContext = new ScXMLSetItemContext(
366 8 : GetScImport(), nPrefix, rLName, xAttrList, *this);
367 : }
368 8 : break;
369 : }
370 :
371 8 : if( !pContext )
372 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
373 :
374 8 : return pContext;
375 : }
376 :
377 5 : void ScXMLConditionContext::GetOperator(
378 : const OUString& aOpStr, ScQueryParam& rParam, ScQueryEntry& rEntry) const
379 : {
380 5 : rParam.bRegExp = false;
381 5 : if (IsXMLToken(aOpStr, XML_MATCH))
382 : {
383 0 : rParam.bRegExp = true;
384 0 : rEntry.eOp = SC_EQUAL;
385 : }
386 5 : else if (IsXMLToken(aOpStr, XML_NOMATCH))
387 : {
388 0 : rParam.bRegExp = true;
389 0 : rEntry.eOp = SC_NOT_EQUAL;
390 : }
391 5 : else if (aOpStr.equalsAscii("="))
392 5 : rEntry.eOp = SC_EQUAL;
393 0 : else if (aOpStr.equalsAscii("!="))
394 0 : rEntry.eOp = SC_NOT_EQUAL;
395 0 : else if (IsXMLToken(aOpStr, XML_BOTTOM_PERCENT))
396 0 : rEntry.eOp = SC_BOTPERC;
397 0 : else if (IsXMLToken(aOpStr, XML_BOTTOM_VALUES))
398 0 : rEntry.eOp = SC_BOTVAL;
399 0 : else if (IsXMLToken(aOpStr, XML_EMPTY))
400 0 : rEntry.SetQueryByEmpty();
401 0 : else if (aOpStr.equalsAscii(">"))
402 0 : rEntry.eOp = SC_GREATER;
403 0 : else if (aOpStr.equalsAscii(">="))
404 0 : rEntry.eOp = SC_GREATER_EQUAL;
405 0 : else if (aOpStr.equalsAscii("<"))
406 0 : rEntry.eOp = SC_LESS;
407 0 : else if (aOpStr.equalsAscii("<="))
408 0 : rEntry.eOp = SC_LESS_EQUAL;
409 0 : else if (IsXMLToken(aOpStr, XML_NOEMPTY))
410 0 : rEntry.SetQueryByNonEmpty();
411 0 : else if (IsXMLToken(aOpStr, XML_TOP_PERCENT))
412 0 : rEntry.eOp = SC_TOPPERC;
413 0 : else if (IsXMLToken(aOpStr, XML_TOP_VALUES))
414 0 : rEntry.eOp = SC_TOPVAL;
415 0 : else if (IsXMLToken(aOpStr, XML_CONTAINS))
416 0 : rEntry.eOp = SC_CONTAINS;
417 0 : else if (IsXMLToken(aOpStr, XML_DOES_NOT_CONTAIN))
418 0 : rEntry.eOp = SC_DOES_NOT_CONTAIN;
419 0 : else if (IsXMLToken(aOpStr, XML_BEGINS_WITH))
420 0 : rEntry.eOp = SC_BEGINS_WITH;
421 0 : else if (IsXMLToken(aOpStr, XML_DOES_NOT_BEGIN_WITH))
422 0 : rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;
423 0 : else if (IsXMLToken(aOpStr, XML_ENDS_WITH))
424 0 : rEntry.eOp = SC_ENDS_WITH;
425 0 : else if (IsXMLToken(aOpStr, XML_DOES_NOT_END_WITH))
426 0 : rEntry.eOp = SC_DOES_NOT_END_WITH;
427 5 : }
428 :
429 8 : void ScXMLConditionContext::AddSetItem(const ScQueryEntry::Item& rItem)
430 : {
431 8 : maQueryItems.push_back(rItem);
432 8 : }
433 :
434 5 : void ScXMLConditionContext::EndElement()
435 : {
436 5 : ScQueryEntry& rEntry = mrQueryParam.AppendEntry();
437 :
438 : // We currently don't support per-condition case sensitivity.
439 5 : mrQueryParam.bCaseSens = bIsCaseSensitive;
440 :
441 5 : rEntry.bDoQuery = true;
442 5 : rEntry.eConnect = pFilterContext->GetConnection() ? SC_OR : SC_AND;
443 :
444 5 : GetOperator(sOperator, mrQueryParam, rEntry);
445 5 : SCCOLROW nStartPos = mrQueryParam.bByRow ? mrQueryParam.nCol1 : mrQueryParam.nRow1;
446 5 : rEntry.nField = nField + nStartPos;
447 :
448 5 : if (maQueryItems.empty())
449 : {
450 2 : ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
451 2 : if (IsXMLToken(sDataType, XML_NUMBER))
452 : {
453 0 : rItem.mfVal = sConditionValue.toDouble();
454 0 : rItem.meType = ScQueryEntry::ByValue;
455 : }
456 : else
457 : {
458 2 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
459 2 : rItem.maString = rPool.intern(sConditionValue);
460 2 : rItem.meType = ScQueryEntry::ByString;
461 : }
462 : }
463 : else
464 3 : rEntry.GetQueryItems().swap(maQueryItems);
465 5 : }
466 :
467 0 : const ScXMLImport& ScXMLSetItemContext::GetScImport() const
468 : {
469 0 : return static_cast<const ScXMLImport&>(GetImport());
470 : }
471 :
472 24 : ScXMLImport& ScXMLSetItemContext::GetScImport()
473 : {
474 24 : return static_cast<ScXMLImport&>(GetImport());
475 : }
476 :
477 8 : ScXMLSetItemContext::ScXMLSetItemContext(
478 : ScXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
479 : const Reference<XAttributeList>& xAttrList, ScXMLConditionContext& rParent) :
480 8 : SvXMLImportContext(rImport, nPrfx, rLName)
481 : {
482 8 : sal_Int32 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
483 8 : const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetFilterSetItemAttrTokenMap();
484 16 : for (sal_Int32 i = 0; i < nAttrCount; ++i)
485 : {
486 8 : const OUString& sAttrName = xAttrList->getNameByIndex(i);
487 16 : OUString aLocalName;
488 : sal_uInt16 nPrefix =
489 8 : GetScImport().GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
490 :
491 16 : const OUString& sValue = xAttrList->getValueByIndex(i);
492 :
493 8 : switch (rAttrTokenMap.Get(nPrefix, aLocalName))
494 : {
495 : case XML_TOK_FILTER_SET_ITEM_ATTR_VALUE:
496 : {
497 8 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
498 8 : ScQueryEntry::Item aItem;
499 8 : aItem.maString = rPool.intern(sValue);
500 8 : aItem.meType = ScQueryEntry::ByString;
501 8 : aItem.mfVal = 0.0;
502 8 : rParent.AddSetItem(aItem);
503 : }
504 8 : break;
505 : }
506 8 : }
507 8 : }
508 :
509 0 : SvXMLImportContext* ScXMLSetItemContext::CreateChildContext(
510 : sal_uInt16 nPrefix, const OUString& rLName,
511 : const Reference<XAttributeList>& /*xAttrList*/ )
512 : {
513 0 : return new SvXMLImportContext( GetImport(), nPrefix, rLName );;
514 : }
515 :
516 16 : ScXMLSetItemContext::~ScXMLSetItemContext()
517 : {
518 16 : }
519 :
520 8 : void ScXMLSetItemContext::EndElement()
521 : {
522 8 : }
523 :
524 1 : ScXMLDPFilterContext::ScXMLDPFilterContext( ScXMLImport& rImport,
525 : sal_uInt16 nPrfx,
526 : const OUString& rLName,
527 : const ::com::sun::star::uno::Reference<
528 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
529 : ScXMLDataPilotTableContext* pTempDataPilotTableContext) :
530 : SvXMLImportContext( rImport, nPrfx, rLName ),
531 : pDataPilotTable(pTempDataPilotTableContext),
532 : aFilterFields(),
533 : nFilterFieldCount(0),
534 : bSkipDuplicates(false),
535 : bCopyOutputData(false),
536 : bUseRegularExpressions(false),
537 : bConnectionOr(true),
538 : bNextConnectionOr(true),
539 1 : bConditionSourceRange(false)
540 : {
541 1 : ScDocument* pDoc(GetScImport().GetDocument());
542 :
543 1 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
544 1 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterAttrTokenMap());
545 2 : for( sal_Int16 i=0; i < nAttrCount; ++i )
546 : {
547 1 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
548 2 : OUString aLocalName;
549 1 : sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
550 1 : sAttrName, &aLocalName ));
551 2 : const OUString& sValue(xAttrList->getValueByIndex( i ));
552 :
553 1 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
554 : {
555 : case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS :
556 : {
557 0 : ScRange aScRange;
558 0 : sal_Int32 nOffset(0);
559 0 : if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
560 : {
561 0 : aOutputPosition = aScRange.aStart;
562 0 : bCopyOutputData = true;
563 : }
564 : }
565 0 : break;
566 : case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS :
567 : {
568 1 : sal_Int32 nOffset(0);
569 1 : if(ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
570 0 : bConditionSourceRange = true;
571 : }
572 1 : break;
573 : case XML_TOK_FILTER_ATTR_CONDITION_SOURCE :
574 : {
575 : // not supported by StarOffice
576 : }
577 0 : break;
578 : case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES :
579 : {
580 0 : bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE);
581 : }
582 0 : break;
583 : }
584 1 : }
585 1 : }
586 :
587 2 : ScXMLDPFilterContext::~ScXMLDPFilterContext()
588 : {
589 2 : }
590 :
591 1 : SvXMLImportContext *ScXMLDPFilterContext::CreateChildContext( sal_uInt16 nPrefix,
592 : const OUString& rLName,
593 : const ::com::sun::star::uno::Reference<
594 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
595 : {
596 1 : SvXMLImportContext *pContext(0);
597 :
598 1 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
599 1 : switch( rTokenMap.Get( nPrefix, rLName ) )
600 : {
601 : case XML_TOK_FILTER_AND:
602 : {
603 : pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
604 1 : rLName, xAttrList, this);
605 : }
606 1 : break;
607 : case XML_TOK_FILTER_OR:
608 : {
609 : pContext = new ScXMLDPOrContext( GetScImport(), nPrefix,
610 0 : rLName, xAttrList, this);
611 : }
612 0 : break;
613 : case XML_TOK_FILTER_CONDITION:
614 : {
615 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
616 0 : rLName, xAttrList, this);
617 : }
618 0 : break;
619 : }
620 :
621 1 : if( !pContext )
622 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
623 :
624 1 : return pContext;
625 : }
626 :
627 1 : void ScXMLDPFilterContext::EndElement()
628 : {
629 1 : aFilterFields.bRegExp = bUseRegularExpressions;
630 1 : aFilterFields.bCaseSens = bIsCaseSensitive;
631 1 : aFilterFields.bDuplicate = !bSkipDuplicates;
632 1 : if (bCopyOutputData)
633 0 : pDataPilotTable->SetFilterOutputPosition(aOutputPosition);
634 :
635 1 : pDataPilotTable->SetSourceQueryParam(aFilterFields);
636 1 : if (bConditionSourceRange)
637 0 : pDataPilotTable->SetFilterSourceRange(aConditionSourceRangeAddress);
638 1 : }
639 :
640 2 : void ScXMLDPFilterContext::AddFilterField (const ScQueryEntry& aFilterField)
641 : {
642 2 : aFilterFields.Resize(nFilterFieldCount + 1);
643 2 : ScQueryEntry& rEntry(aFilterFields.GetEntry(nFilterFieldCount));
644 2 : rEntry = aFilterField;
645 2 : rEntry.bDoQuery = true;
646 2 : ++nFilterFieldCount;
647 2 : }
648 :
649 1 : ScXMLDPAndContext::ScXMLDPAndContext( ScXMLImport& rImport,
650 : sal_uInt16 nPrfx,
651 : const OUString& rLName,
652 : const ::com::sun::star::uno::Reference<
653 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
654 : ScXMLDPFilterContext* pTempFilterContext) :
655 1 : SvXMLImportContext( rImport, nPrfx, rLName )
656 : {
657 1 : pFilterContext = pTempFilterContext;
658 1 : pFilterContext->OpenConnection(false);
659 1 : }
660 :
661 2 : ScXMLDPAndContext::~ScXMLDPAndContext()
662 : {
663 2 : }
664 :
665 2 : SvXMLImportContext *ScXMLDPAndContext::CreateChildContext( sal_uInt16 nPrefix,
666 : const OUString& rLName,
667 : const ::com::sun::star::uno::Reference<
668 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
669 : {
670 2 : SvXMLImportContext *pContext(0);
671 :
672 2 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
673 2 : switch( rTokenMap.Get( nPrefix, rLName ) )
674 : {
675 : case XML_TOK_FILTER_OR:
676 : {
677 : // not supported in StarOffice
678 : }
679 0 : break;
680 : case XML_TOK_FILTER_CONDITION:
681 : {
682 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
683 2 : rLName, xAttrList, pFilterContext);
684 : }
685 2 : break;
686 : }
687 :
688 2 : if( !pContext )
689 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
690 :
691 2 : return pContext;
692 : }
693 :
694 1 : void ScXMLDPAndContext::EndElement()
695 : {
696 1 : pFilterContext->CloseConnection();
697 1 : }
698 :
699 0 : ScXMLDPOrContext::ScXMLDPOrContext( ScXMLImport& rImport,
700 : sal_uInt16 nPrfx,
701 : const OUString& rLName,
702 : const ::com::sun::star::uno::Reference<
703 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
704 : ScXMLDPFilterContext* pTempFilterContext) :
705 : SvXMLImportContext( rImport, nPrfx, rLName ),
706 0 : pFilterContext(pTempFilterContext)
707 : {
708 0 : pFilterContext->OpenConnection(true);
709 0 : }
710 :
711 0 : ScXMLDPOrContext::~ScXMLDPOrContext()
712 : {
713 0 : }
714 :
715 0 : SvXMLImportContext *ScXMLDPOrContext::CreateChildContext( sal_uInt16 nPrefix,
716 : const OUString& rLName,
717 : const ::com::sun::star::uno::Reference<
718 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
719 : {
720 0 : SvXMLImportContext *pContext(0);
721 :
722 0 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
723 0 : switch( rTokenMap.Get( nPrefix, rLName ) )
724 : {
725 : case XML_TOK_FILTER_AND:
726 : {
727 : pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
728 0 : rLName, xAttrList, pFilterContext);
729 : }
730 0 : break;
731 : case XML_TOK_FILTER_CONDITION:
732 : {
733 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
734 0 : rLName, xAttrList, pFilterContext);
735 : }
736 0 : break;
737 : }
738 :
739 0 : if( !pContext )
740 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
741 :
742 0 : return pContext;
743 : }
744 :
745 0 : void ScXMLDPOrContext::EndElement()
746 : {
747 0 : pFilterContext->CloseConnection();
748 0 : }
749 :
750 2 : ScXMLDPConditionContext::ScXMLDPConditionContext( ScXMLImport& rImport,
751 : sal_uInt16 nPrfx,
752 : const OUString& rLName,
753 : const ::com::sun::star::uno::Reference<
754 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
755 : ScXMLDPFilterContext* pTempFilterContext) :
756 : SvXMLImportContext( rImport, nPrfx, rLName ),
757 : pFilterContext(pTempFilterContext),
758 2 : sDataType(GetXMLToken(XML_TEXT)),
759 4 : bIsCaseSensitive(false)
760 : {
761 :
762 2 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
763 2 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
764 10 : for( sal_Int16 i=0; i < nAttrCount; ++i )
765 : {
766 8 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
767 16 : OUString aLocalName;
768 8 : sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
769 8 : sAttrName, &aLocalName ));
770 16 : const OUString& sValue(xAttrList->getValueByIndex( i ));
771 :
772 8 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
773 : {
774 : case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
775 : {
776 2 : nField = sValue.toInt32();
777 : }
778 2 : break;
779 : case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
780 : {
781 0 : bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
782 : }
783 0 : break;
784 : case XML_TOK_CONDITION_ATTR_DATA_TYPE :
785 : {
786 2 : sDataType = sValue;
787 : }
788 2 : break;
789 : case XML_TOK_CONDITION_ATTR_VALUE :
790 : {
791 2 : sConditionValue = sValue;
792 : }
793 2 : break;
794 : case XML_TOK_CONDITION_ATTR_OPERATOR :
795 : {
796 2 : sOperator = sValue;
797 : }
798 2 : break;
799 : }
800 8 : }
801 2 : }
802 :
803 4 : ScXMLDPConditionContext::~ScXMLDPConditionContext()
804 : {
805 4 : }
806 :
807 0 : SvXMLImportContext *ScXMLDPConditionContext::CreateChildContext( sal_uInt16 nPrefix,
808 : const OUString& rLName,
809 : const ::com::sun::star::uno::Reference<
810 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
811 : {
812 0 : return new SvXMLImportContext( GetImport(), nPrefix, rLName );
813 : }
814 :
815 2 : void ScXMLDPConditionContext::getOperatorXML(
816 : const OUString& sTempOperator, ScQueryOp& aFilterOperator, bool& bUseRegularExpressions) const
817 : {
818 2 : bUseRegularExpressions = false;
819 2 : if (IsXMLToken(sTempOperator, XML_MATCH))
820 : {
821 0 : bUseRegularExpressions = true;
822 0 : aFilterOperator = SC_EQUAL;
823 : }
824 2 : else if (IsXMLToken(sTempOperator, XML_NOMATCH))
825 : {
826 0 : bUseRegularExpressions = true;
827 0 : aFilterOperator = SC_NOT_EQUAL;
828 : }
829 2 : else if (sTempOperator.equalsAscii("="))
830 0 : aFilterOperator = SC_EQUAL;
831 2 : else if (sTempOperator.equalsAscii("!="))
832 0 : aFilterOperator = SC_NOT_EQUAL;
833 2 : else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT))
834 0 : aFilterOperator = SC_BOTPERC;
835 2 : else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES))
836 0 : aFilterOperator = SC_BOTVAL;
837 2 : else if (sTempOperator.equalsAscii(">"))
838 1 : aFilterOperator = SC_GREATER;
839 1 : else if (sTempOperator.equalsAscii(">="))
840 0 : aFilterOperator = SC_GREATER_EQUAL;
841 1 : else if (sTempOperator.equalsAscii("<"))
842 0 : aFilterOperator = SC_LESS;
843 1 : else if (sTempOperator.equalsAscii("<="))
844 1 : aFilterOperator = SC_LESS_EQUAL;
845 0 : else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT))
846 0 : aFilterOperator = SC_TOPPERC;
847 0 : else if (IsXMLToken(sTempOperator, XML_TOP_VALUES))
848 0 : aFilterOperator = SC_TOPVAL;
849 2 : }
850 :
851 2 : void ScXMLDPConditionContext::EndElement()
852 : {
853 2 : ScQueryEntry aFilterField;
854 2 : if (pFilterContext->GetConnection())
855 1 : aFilterField.eConnect = SC_OR;
856 : else
857 1 : aFilterField.eConnect = SC_AND;
858 2 : pFilterContext->SetIsCaseSensitive(bIsCaseSensitive);
859 2 : if (IsXMLToken(sOperator, XML_EMPTY))
860 0 : aFilterField.SetQueryByEmpty();
861 2 : else if (IsXMLToken(sOperator, XML_NOEMPTY))
862 0 : aFilterField.SetQueryByNonEmpty();
863 : else
864 : {
865 2 : bool bUseRegularExpressions = false;
866 2 : getOperatorXML(sOperator, aFilterField.eOp, bUseRegularExpressions);
867 2 : pFilterContext->SetUseRegularExpressions(bUseRegularExpressions);
868 2 : aFilterField.nField = nField;
869 2 : ScQueryEntry::Item& rItem = aFilterField.GetQueryItem();
870 2 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
871 :
872 2 : if (IsXMLToken(sDataType, XML_NUMBER))
873 : {
874 2 : rItem.mfVal = sConditionValue.toDouble();
875 2 : rItem.maString = rPool.intern(sConditionValue);
876 2 : rItem.meType = ScQueryEntry::ByValue;
877 : }
878 : else
879 : {
880 0 : rItem.maString = rPool.intern(sConditionValue);
881 0 : rItem.meType = ScQueryEntry::ByString;
882 0 : rItem.mfVal = 0.0;
883 : }
884 : }
885 2 : pFilterContext->AddFilterField(aFilterField);
886 104 : }
887 :
888 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|