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 8 : ScXMLFilterContext::ConnStackItem::ConnStackItem(bool bOr) : mbOr(bOr), mnCondCount(0) {}
41 :
42 8 : 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 8 : bConditionSourceRange(false)
54 : {
55 8 : ScDocument* pDoc(GetScImport().GetDocument());
56 :
57 8 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
58 8 : const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetFilterAttrTokenMap();
59 8 : 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 8 : }
100 :
101 16 : ScXMLFilterContext::~ScXMLFilterContext()
102 : {
103 16 : }
104 :
105 8 : 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 8 : SvXMLImportContext *pContext(0);
111 :
112 8 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
113 8 : switch( rTokenMap.Get( nPrefix, rLName ) )
114 : {
115 : case XML_TOK_FILTER_AND:
116 : {
117 : pContext = new ScXMLAndContext(
118 2 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, this);
119 : }
120 2 : break;
121 : case XML_TOK_FILTER_OR:
122 : {
123 : pContext = new ScXMLOrContext(
124 6 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, this);
125 : }
126 6 : 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 8 : if( !pContext )
136 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
137 :
138 8 : return pContext;
139 : }
140 :
141 8 : void ScXMLFilterContext::EndElement()
142 : {
143 8 : mrQueryParam.bInplace = !bCopyOutputData;
144 8 : mrQueryParam.bDuplicate = !bSkipDuplicates;
145 :
146 8 : if (bCopyOutputData)
147 : {
148 0 : mrQueryParam.nDestCol = aOutputPosition.Column;
149 0 : mrQueryParam.nDestRow = aOutputPosition.Row;
150 0 : mrQueryParam.nDestTab = aOutputPosition.Sheet;
151 : }
152 :
153 8 : if (bConditionSourceRange)
154 0 : pDatabaseRangeContext->SetFilterConditionSourceRangeAddress(aConditionSourceRangeAddress);
155 8 : }
156 :
157 8 : void ScXMLFilterContext::OpenConnection(bool b)
158 : {
159 8 : maConnStack.push_back(ConnStackItem(b));
160 8 : }
161 :
162 8 : void ScXMLFilterContext::CloseConnection()
163 : {
164 8 : maConnStack.pop_back();
165 8 : }
166 :
167 10 : 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 10 : if (maConnStack.empty())
173 : // This should never happen.
174 0 : return true;
175 :
176 10 : ConnStackItem& rItem = maConnStack.back();
177 10 : if (rItem.mnCondCount)
178 : // secondary item gets the current connection.
179 0 : return rItem.mbOr;
180 :
181 10 : 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 10 : 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 2 : 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 2 : pFilterContext(pTempFilterContext)
201 : {
202 2 : pFilterContext->OpenConnection(false);
203 2 : }
204 :
205 4 : ScXMLAndContext::~ScXMLAndContext()
206 : {
207 4 : }
208 :
209 2 : 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 2 : SvXMLImportContext *pContext(0);
215 :
216 2 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
217 2 : 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 2 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, pFilterContext);
228 : }
229 2 : break;
230 : }
231 :
232 2 : if( !pContext )
233 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
234 :
235 2 : return pContext;
236 : }
237 :
238 2 : void ScXMLAndContext::EndElement()
239 : {
240 2 : pFilterContext->CloseConnection();
241 2 : }
242 :
243 6 : 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 6 : pFilterContext(pTempFilterContext)
253 : {
254 6 : pFilterContext->OpenConnection(true);
255 6 : }
256 :
257 12 : ScXMLOrContext::~ScXMLOrContext()
258 : {
259 12 : }
260 :
261 8 : 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 8 : SvXMLImportContext *pContext(0);
267 :
268 8 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
269 8 : 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 8 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, pFilterContext);
281 : }
282 8 : break;
283 : }
284 :
285 8 : if( !pContext )
286 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
287 :
288 8 : return pContext;
289 : }
290 :
291 6 : void ScXMLOrContext::EndElement()
292 : {
293 6 : pFilterContext->CloseConnection();
294 6 : }
295 :
296 10 : 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 10 : bIsCaseSensitive(false)
306 : {
307 10 : sDataType = GetXMLToken(XML_TEXT);
308 :
309 10 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
310 10 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
311 40 : for( sal_Int16 i=0; i < nAttrCount; ++i )
312 : {
313 30 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
314 60 : OUString aLocalName;
315 30 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
316 30 : sAttrName, &aLocalName );
317 60 : const OUString& sValue(xAttrList->getValueByIndex( i ));
318 :
319 30 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
320 : {
321 : case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
322 : {
323 10 : nField = sValue.toInt32();
324 : }
325 10 : 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 10 : sConditionValue = sValue;
339 : }
340 10 : break;
341 : case XML_TOK_CONDITION_ATTR_OPERATOR :
342 : {
343 10 : sOperator = sValue;
344 : }
345 10 : break;
346 : }
347 30 : }
348 10 : }
349 :
350 20 : ScXMLConditionContext::~ScXMLConditionContext()
351 : {
352 20 : }
353 :
354 16 : SvXMLImportContext *ScXMLConditionContext::CreateChildContext( sal_uInt16 nPrefix,
355 : const OUString& rLName,
356 : const Reference<XAttributeList>& xAttrList )
357 : {
358 16 : SvXMLImportContext *pContext = NULL;
359 :
360 16 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterConditionElemTokenMap());
361 16 : switch( rTokenMap.Get( nPrefix, rLName ) )
362 : {
363 : case XML_TOK_CONDITION_FILTER_SET_ITEM:
364 : {
365 : pContext = new ScXMLSetItemContext(
366 16 : GetScImport(), nPrefix, rLName, xAttrList, *this);
367 : }
368 16 : break;
369 : }
370 :
371 16 : if( !pContext )
372 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
373 :
374 16 : return pContext;
375 : }
376 :
377 10 : void ScXMLConditionContext::GetOperator(
378 : const OUString& aOpStr, ScQueryParam& rParam, ScQueryEntry& rEntry) const
379 : {
380 10 : rParam.bRegExp = false;
381 10 : if (IsXMLToken(aOpStr, XML_MATCH))
382 : {
383 0 : rParam.bRegExp = true;
384 0 : rEntry.eOp = SC_EQUAL;
385 : }
386 10 : else if (IsXMLToken(aOpStr, XML_NOMATCH))
387 : {
388 0 : rParam.bRegExp = true;
389 0 : rEntry.eOp = SC_NOT_EQUAL;
390 : }
391 10 : else if (aOpStr.equalsAscii("="))
392 10 : 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 10 : }
428 :
429 16 : void ScXMLConditionContext::AddSetItem(const ScQueryEntry::Item& rItem)
430 : {
431 16 : maQueryItems.push_back(rItem);
432 16 : }
433 :
434 10 : void ScXMLConditionContext::EndElement()
435 : {
436 10 : ScQueryEntry& rEntry = mrQueryParam.AppendEntry();
437 :
438 : // We currently don't support per-condition case sensitivity.
439 10 : mrQueryParam.bCaseSens = bIsCaseSensitive;
440 :
441 10 : rEntry.bDoQuery = true;
442 10 : rEntry.eConnect = pFilterContext->GetConnection() ? SC_OR : SC_AND;
443 :
444 10 : GetOperator(sOperator, mrQueryParam, rEntry);
445 10 : SCCOLROW nStartPos = mrQueryParam.bByRow ? mrQueryParam.nCol1 : mrQueryParam.nRow1;
446 10 : rEntry.nField = nField + nStartPos;
447 :
448 10 : if (maQueryItems.empty())
449 : {
450 4 : ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
451 4 : if (IsXMLToken(sDataType, XML_NUMBER))
452 : {
453 0 : rItem.mfVal = sConditionValue.toDouble();
454 0 : rItem.meType = ScQueryEntry::ByValue;
455 : }
456 : else
457 : {
458 4 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
459 4 : rItem.maString = rPool.intern(sConditionValue);
460 4 : rItem.meType = ScQueryEntry::ByString;
461 : }
462 : }
463 : else
464 6 : rEntry.GetQueryItems().swap(maQueryItems);
465 10 : }
466 :
467 0 : const ScXMLImport& ScXMLSetItemContext::GetScImport() const
468 : {
469 0 : return static_cast<const ScXMLImport&>(GetImport());
470 : }
471 :
472 48 : ScXMLImport& ScXMLSetItemContext::GetScImport()
473 : {
474 48 : return static_cast<ScXMLImport&>(GetImport());
475 : }
476 :
477 16 : ScXMLSetItemContext::ScXMLSetItemContext(
478 : ScXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
479 : const Reference<XAttributeList>& xAttrList, ScXMLConditionContext& rParent) :
480 16 : SvXMLImportContext(rImport, nPrfx, rLName)
481 : {
482 16 : sal_Int32 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
483 16 : const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetFilterSetItemAttrTokenMap();
484 32 : for (sal_Int32 i = 0; i < nAttrCount; ++i)
485 : {
486 16 : const OUString& sAttrName = xAttrList->getNameByIndex(i);
487 32 : OUString aLocalName;
488 : sal_uInt16 nPrefix =
489 16 : GetScImport().GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
490 :
491 32 : const OUString& sValue = xAttrList->getValueByIndex(i);
492 :
493 16 : switch (rAttrTokenMap.Get(nPrefix, aLocalName))
494 : {
495 : case XML_TOK_FILTER_SET_ITEM_ATTR_VALUE:
496 : {
497 16 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
498 16 : ScQueryEntry::Item aItem;
499 16 : aItem.maString = rPool.intern(sValue);
500 16 : aItem.meType = ScQueryEntry::ByString;
501 16 : aItem.mfVal = 0.0;
502 16 : rParent.AddSetItem(aItem);
503 : }
504 16 : break;
505 : }
506 16 : }
507 16 : }
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 32 : ScXMLSetItemContext::~ScXMLSetItemContext()
517 : {
518 32 : }
519 :
520 16 : void ScXMLSetItemContext::EndElement()
521 : {
522 16 : }
523 :
524 2 : 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 : bIsCaseSensitive(false),
538 : bConnectionOr(true),
539 : bNextConnectionOr(true),
540 2 : bConditionSourceRange(false)
541 : {
542 2 : ScDocument* pDoc(GetScImport().GetDocument());
543 :
544 2 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
545 2 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterAttrTokenMap());
546 4 : for( sal_Int16 i=0; i < nAttrCount; ++i )
547 : {
548 2 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
549 4 : OUString aLocalName;
550 2 : sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
551 2 : sAttrName, &aLocalName ));
552 4 : const OUString& sValue(xAttrList->getValueByIndex( i ));
553 :
554 2 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
555 : {
556 : case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS :
557 : {
558 0 : ScRange aScRange;
559 0 : sal_Int32 nOffset(0);
560 0 : if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
561 : {
562 0 : aOutputPosition = aScRange.aStart;
563 0 : bCopyOutputData = true;
564 : }
565 : }
566 0 : break;
567 : case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS :
568 : {
569 2 : sal_Int32 nOffset(0);
570 2 : if(ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
571 0 : bConditionSourceRange = true;
572 : }
573 2 : break;
574 : case XML_TOK_FILTER_ATTR_CONDITION_SOURCE :
575 : {
576 : // not supported by StarOffice
577 : }
578 0 : break;
579 : case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES :
580 : {
581 0 : bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE);
582 : }
583 0 : break;
584 : }
585 2 : }
586 2 : }
587 :
588 4 : ScXMLDPFilterContext::~ScXMLDPFilterContext()
589 : {
590 4 : }
591 :
592 2 : SvXMLImportContext *ScXMLDPFilterContext::CreateChildContext( sal_uInt16 nPrefix,
593 : const OUString& rLName,
594 : const ::com::sun::star::uno::Reference<
595 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
596 : {
597 2 : SvXMLImportContext *pContext(0);
598 :
599 2 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
600 2 : switch( rTokenMap.Get( nPrefix, rLName ) )
601 : {
602 : case XML_TOK_FILTER_AND:
603 : {
604 : pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
605 2 : rLName, xAttrList, this);
606 : }
607 2 : break;
608 : case XML_TOK_FILTER_OR:
609 : {
610 : pContext = new ScXMLDPOrContext( GetScImport(), nPrefix,
611 0 : rLName, xAttrList, this);
612 : }
613 0 : break;
614 : case XML_TOK_FILTER_CONDITION:
615 : {
616 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
617 0 : rLName, xAttrList, this);
618 : }
619 0 : break;
620 : }
621 :
622 2 : if( !pContext )
623 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
624 :
625 2 : return pContext;
626 : }
627 :
628 2 : void ScXMLDPFilterContext::EndElement()
629 : {
630 2 : aFilterFields.bRegExp = bUseRegularExpressions;
631 2 : aFilterFields.bCaseSens = bIsCaseSensitive;
632 2 : aFilterFields.bDuplicate = !bSkipDuplicates;
633 2 : if (bCopyOutputData)
634 0 : pDataPilotTable->SetFilterOutputPosition(aOutputPosition);
635 :
636 2 : pDataPilotTable->SetSourceQueryParam(aFilterFields);
637 2 : if (bConditionSourceRange)
638 0 : pDataPilotTable->SetFilterSourceRange(aConditionSourceRangeAddress);
639 2 : }
640 :
641 4 : void ScXMLDPFilterContext::AddFilterField (const ScQueryEntry& aFilterField)
642 : {
643 4 : aFilterFields.Resize(nFilterFieldCount + 1);
644 4 : ScQueryEntry& rEntry(aFilterFields.GetEntry(nFilterFieldCount));
645 4 : rEntry = aFilterField;
646 4 : rEntry.bDoQuery = true;
647 4 : ++nFilterFieldCount;
648 4 : }
649 :
650 2 : ScXMLDPAndContext::ScXMLDPAndContext( ScXMLImport& rImport,
651 : sal_uInt16 nPrfx,
652 : const OUString& rLName,
653 : const ::com::sun::star::uno::Reference<
654 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
655 : ScXMLDPFilterContext* pTempFilterContext) :
656 2 : SvXMLImportContext( rImport, nPrfx, rLName )
657 : {
658 2 : pFilterContext = pTempFilterContext;
659 2 : pFilterContext->OpenConnection(false);
660 2 : }
661 :
662 4 : ScXMLDPAndContext::~ScXMLDPAndContext()
663 : {
664 4 : }
665 :
666 4 : SvXMLImportContext *ScXMLDPAndContext::CreateChildContext( sal_uInt16 nPrefix,
667 : const OUString& rLName,
668 : const ::com::sun::star::uno::Reference<
669 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
670 : {
671 4 : SvXMLImportContext *pContext(0);
672 :
673 4 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
674 4 : switch( rTokenMap.Get( nPrefix, rLName ) )
675 : {
676 : case XML_TOK_FILTER_OR:
677 : {
678 : // not supported in StarOffice
679 : }
680 0 : break;
681 : case XML_TOK_FILTER_CONDITION:
682 : {
683 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
684 4 : rLName, xAttrList, pFilterContext);
685 : }
686 4 : break;
687 : }
688 :
689 4 : if( !pContext )
690 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
691 :
692 4 : return pContext;
693 : }
694 :
695 2 : void ScXMLDPAndContext::EndElement()
696 : {
697 2 : pFilterContext->CloseConnection();
698 2 : }
699 :
700 0 : ScXMLDPOrContext::ScXMLDPOrContext( ScXMLImport& rImport,
701 : sal_uInt16 nPrfx,
702 : const OUString& rLName,
703 : const ::com::sun::star::uno::Reference<
704 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
705 : ScXMLDPFilterContext* pTempFilterContext) :
706 : SvXMLImportContext( rImport, nPrfx, rLName ),
707 0 : pFilterContext(pTempFilterContext)
708 : {
709 0 : pFilterContext->OpenConnection(true);
710 0 : }
711 :
712 0 : ScXMLDPOrContext::~ScXMLDPOrContext()
713 : {
714 0 : }
715 :
716 0 : SvXMLImportContext *ScXMLDPOrContext::CreateChildContext( sal_uInt16 nPrefix,
717 : const OUString& rLName,
718 : const ::com::sun::star::uno::Reference<
719 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
720 : {
721 0 : SvXMLImportContext *pContext(0);
722 :
723 0 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
724 0 : switch( rTokenMap.Get( nPrefix, rLName ) )
725 : {
726 : case XML_TOK_FILTER_AND:
727 : {
728 : pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
729 0 : rLName, xAttrList, pFilterContext);
730 : }
731 0 : break;
732 : case XML_TOK_FILTER_CONDITION:
733 : {
734 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
735 0 : rLName, xAttrList, pFilterContext);
736 : }
737 0 : break;
738 : }
739 :
740 0 : if( !pContext )
741 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
742 :
743 0 : return pContext;
744 : }
745 :
746 0 : void ScXMLDPOrContext::EndElement()
747 : {
748 0 : pFilterContext->CloseConnection();
749 0 : }
750 :
751 4 : ScXMLDPConditionContext::ScXMLDPConditionContext( ScXMLImport& rImport,
752 : sal_uInt16 nPrfx,
753 : const OUString& rLName,
754 : const ::com::sun::star::uno::Reference<
755 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
756 : ScXMLDPFilterContext* pTempFilterContext) :
757 : SvXMLImportContext( rImport, nPrfx, rLName ),
758 : pFilterContext(pTempFilterContext),
759 4 : sDataType(GetXMLToken(XML_TEXT)),
760 : nField(0),
761 8 : bIsCaseSensitive(false)
762 : {
763 :
764 4 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
765 4 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
766 20 : for( sal_Int16 i=0; i < nAttrCount; ++i )
767 : {
768 16 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
769 32 : OUString aLocalName;
770 16 : sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
771 16 : sAttrName, &aLocalName ));
772 32 : const OUString& sValue(xAttrList->getValueByIndex( i ));
773 :
774 16 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
775 : {
776 : case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
777 : {
778 4 : nField = sValue.toInt32();
779 : }
780 4 : break;
781 : case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
782 : {
783 0 : bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
784 : }
785 0 : break;
786 : case XML_TOK_CONDITION_ATTR_DATA_TYPE :
787 : {
788 4 : sDataType = sValue;
789 : }
790 4 : break;
791 : case XML_TOK_CONDITION_ATTR_VALUE :
792 : {
793 4 : sConditionValue = sValue;
794 : }
795 4 : break;
796 : case XML_TOK_CONDITION_ATTR_OPERATOR :
797 : {
798 4 : sOperator = sValue;
799 : }
800 4 : break;
801 : }
802 16 : }
803 4 : }
804 :
805 8 : ScXMLDPConditionContext::~ScXMLDPConditionContext()
806 : {
807 8 : }
808 :
809 0 : SvXMLImportContext *ScXMLDPConditionContext::CreateChildContext( sal_uInt16 nPrefix,
810 : const OUString& rLName,
811 : const ::com::sun::star::uno::Reference<
812 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
813 : {
814 0 : return new SvXMLImportContext( GetImport(), nPrefix, rLName );
815 : }
816 :
817 4 : void ScXMLDPConditionContext::getOperatorXML(
818 : const OUString& sTempOperator, ScQueryOp& aFilterOperator, bool& bUseRegularExpressions) const
819 : {
820 4 : bUseRegularExpressions = false;
821 4 : if (IsXMLToken(sTempOperator, XML_MATCH))
822 : {
823 0 : bUseRegularExpressions = true;
824 0 : aFilterOperator = SC_EQUAL;
825 : }
826 4 : else if (IsXMLToken(sTempOperator, XML_NOMATCH))
827 : {
828 0 : bUseRegularExpressions = true;
829 0 : aFilterOperator = SC_NOT_EQUAL;
830 : }
831 4 : else if (sTempOperator.equalsAscii("="))
832 0 : aFilterOperator = SC_EQUAL;
833 4 : else if (sTempOperator.equalsAscii("!="))
834 0 : aFilterOperator = SC_NOT_EQUAL;
835 4 : else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT))
836 0 : aFilterOperator = SC_BOTPERC;
837 4 : else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES))
838 0 : aFilterOperator = SC_BOTVAL;
839 4 : else if (sTempOperator.equalsAscii(">"))
840 2 : aFilterOperator = SC_GREATER;
841 2 : else if (sTempOperator.equalsAscii(">="))
842 0 : aFilterOperator = SC_GREATER_EQUAL;
843 2 : else if (sTempOperator.equalsAscii("<"))
844 0 : aFilterOperator = SC_LESS;
845 2 : else if (sTempOperator.equalsAscii("<="))
846 2 : aFilterOperator = SC_LESS_EQUAL;
847 0 : else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT))
848 0 : aFilterOperator = SC_TOPPERC;
849 0 : else if (IsXMLToken(sTempOperator, XML_TOP_VALUES))
850 0 : aFilterOperator = SC_TOPVAL;
851 4 : }
852 :
853 4 : void ScXMLDPConditionContext::EndElement()
854 : {
855 4 : ScQueryEntry aFilterField;
856 4 : if (pFilterContext->GetConnection())
857 2 : aFilterField.eConnect = SC_OR;
858 : else
859 2 : aFilterField.eConnect = SC_AND;
860 4 : pFilterContext->SetIsCaseSensitive(bIsCaseSensitive);
861 4 : if (IsXMLToken(sOperator, XML_EMPTY))
862 0 : aFilterField.SetQueryByEmpty();
863 4 : else if (IsXMLToken(sOperator, XML_NOEMPTY))
864 0 : aFilterField.SetQueryByNonEmpty();
865 : else
866 : {
867 4 : bool bUseRegularExpressions = false;
868 4 : getOperatorXML(sOperator, aFilterField.eOp, bUseRegularExpressions);
869 4 : pFilterContext->SetUseRegularExpressions(bUseRegularExpressions);
870 4 : aFilterField.nField = nField;
871 4 : ScQueryEntry::Item& rItem = aFilterField.GetQueryItem();
872 4 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
873 :
874 4 : if (IsXMLToken(sDataType, XML_NUMBER))
875 : {
876 4 : rItem.mfVal = sConditionValue.toDouble();
877 4 : rItem.maString = rPool.intern(sConditionValue);
878 4 : rItem.meType = ScQueryEntry::ByValue;
879 : }
880 : else
881 : {
882 0 : rItem.maString = rPool.intern(sConditionValue);
883 0 : rItem.meType = ScQueryEntry::ByString;
884 0 : rItem.mfVal = 0.0;
885 : }
886 : }
887 4 : pFilterContext->AddFilterField(aFilterField);
888 232 : }
889 :
890 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|