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 1 : return rItem.mbOr;
180 :
181 : // The next condition of this stack will get the current connection.
182 4 : ++rItem.mnCondCount;
183 :
184 4 : 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
189 : // uselessly stacked
190 : // <table:filter-or><table:filter-and>...</table:filter-and></table:filter-or>
191 : // for two conditions connected with AND.
192 4 : return false;
193 :
194 0 : std::vector<ConnStackItem>::reverse_iterator itr = maConnStack.rbegin();
195 0 : ++itr;
196 0 : return itr->mbOr; // connection of the last stack.
197 : }
198 :
199 1 : ScXMLAndContext::ScXMLAndContext( ScXMLImport& rImport,
200 : sal_uInt16 nPrfx,
201 : const OUString& rLName,
202 : const Reference<XAttributeList>& /* xAttrList */,
203 : ScQueryParam& rParam,
204 : ScXMLFilterContext* pTempFilterContext) :
205 : SvXMLImportContext( rImport, nPrfx, rLName ),
206 : mrQueryParam(rParam),
207 1 : pFilterContext(pTempFilterContext)
208 : {
209 1 : pFilterContext->OpenConnection(false);
210 1 : }
211 :
212 2 : ScXMLAndContext::~ScXMLAndContext()
213 : {
214 2 : }
215 :
216 1 : 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 )
220 : {
221 1 : SvXMLImportContext *pContext(0);
222 :
223 1 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
224 1 : switch( rTokenMap.Get( nPrefix, rLName ) )
225 : {
226 : case XML_TOK_FILTER_OR:
227 : {
228 : // not supported in StarOffice
229 : }
230 0 : break;
231 : case XML_TOK_FILTER_CONDITION:
232 : {
233 : pContext = new ScXMLConditionContext(
234 1 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, pFilterContext);
235 : }
236 1 : break;
237 : }
238 :
239 1 : if( !pContext )
240 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
241 :
242 1 : return pContext;
243 : }
244 :
245 1 : void ScXMLAndContext::EndElement()
246 : {
247 1 : pFilterContext->CloseConnection();
248 1 : }
249 :
250 3 : ScXMLOrContext::ScXMLOrContext( ScXMLImport& rImport,
251 : sal_uInt16 nPrfx,
252 : const OUString& rLName,
253 : const Reference<
254 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
255 : ScQueryParam& rParam,
256 : ScXMLFilterContext* pTempFilterContext) :
257 : SvXMLImportContext( rImport, nPrfx, rLName ),
258 : mrQueryParam(rParam),
259 3 : pFilterContext(pTempFilterContext)
260 : {
261 3 : pFilterContext->OpenConnection(true);
262 3 : }
263 :
264 6 : ScXMLOrContext::~ScXMLOrContext()
265 : {
266 6 : }
267 :
268 4 : 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 )
272 : {
273 4 : SvXMLImportContext *pContext(0);
274 :
275 4 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
276 4 : switch( rTokenMap.Get( nPrefix, rLName ) )
277 : {
278 : case XML_TOK_FILTER_AND:
279 : {
280 : pContext = new ScXMLAndContext(
281 0 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, pFilterContext);
282 : }
283 0 : break;
284 : case XML_TOK_FILTER_CONDITION:
285 : {
286 : pContext = new ScXMLConditionContext(
287 4 : GetScImport(), nPrefix, rLName, xAttrList, mrQueryParam, pFilterContext);
288 : }
289 4 : break;
290 : }
291 :
292 4 : if( !pContext )
293 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
294 :
295 4 : return pContext;
296 : }
297 :
298 3 : void ScXMLOrContext::EndElement()
299 : {
300 3 : pFilterContext->CloseConnection();
301 3 : }
302 :
303 5 : 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),
311 : nField(0),
312 5 : bIsCaseSensitive(false)
313 : {
314 5 : sDataType = GetXMLToken(XML_TEXT);
315 :
316 5 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
317 5 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
318 20 : for( sal_Int16 i=0; i < nAttrCount; ++i )
319 : {
320 15 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
321 30 : OUString aLocalName;
322 15 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
323 15 : sAttrName, &aLocalName );
324 30 : const OUString& sValue(xAttrList->getValueByIndex( i ));
325 :
326 15 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
327 : {
328 : case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
329 : {
330 5 : nField = sValue.toInt32();
331 : }
332 5 : break;
333 : case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
334 : {
335 0 : bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
336 : }
337 0 : break;
338 : case XML_TOK_CONDITION_ATTR_DATA_TYPE :
339 : {
340 0 : sDataType = sValue;
341 : }
342 0 : break;
343 : case XML_TOK_CONDITION_ATTR_VALUE :
344 : {
345 5 : sConditionValue = sValue;
346 : }
347 5 : break;
348 : case XML_TOK_CONDITION_ATTR_OPERATOR :
349 : {
350 5 : sOperator = sValue;
351 : }
352 5 : break;
353 : }
354 15 : }
355 5 : }
356 :
357 10 : ScXMLConditionContext::~ScXMLConditionContext()
358 : {
359 10 : }
360 :
361 8 : SvXMLImportContext *ScXMLConditionContext::CreateChildContext( sal_uInt16 nPrefix,
362 : const OUString& rLName,
363 : const Reference<XAttributeList>& xAttrList )
364 : {
365 8 : SvXMLImportContext *pContext = NULL;
366 :
367 8 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterConditionElemTokenMap());
368 8 : switch( rTokenMap.Get( nPrefix, rLName ) )
369 : {
370 : case XML_TOK_CONDITION_FILTER_SET_ITEM:
371 : {
372 : pContext = new ScXMLSetItemContext(
373 8 : GetScImport(), nPrefix, rLName, xAttrList, *this);
374 : }
375 8 : break;
376 : }
377 :
378 8 : if( !pContext )
379 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
380 :
381 8 : return pContext;
382 : }
383 :
384 5 : void ScXMLConditionContext::GetOperator(
385 : const OUString& aOpStr, ScQueryParam& rParam, ScQueryEntry& rEntry)
386 : {
387 5 : rParam.bRegExp = false;
388 5 : if (IsXMLToken(aOpStr, XML_MATCH))
389 : {
390 0 : rParam.bRegExp = true;
391 0 : rEntry.eOp = SC_EQUAL;
392 : }
393 5 : else if (IsXMLToken(aOpStr, XML_NOMATCH))
394 : {
395 0 : rParam.bRegExp = true;
396 0 : rEntry.eOp = SC_NOT_EQUAL;
397 : }
398 5 : else if (aOpStr == "=")
399 5 : rEntry.eOp = SC_EQUAL;
400 0 : else if (aOpStr == "!=")
401 0 : rEntry.eOp = SC_NOT_EQUAL;
402 0 : else if (IsXMLToken(aOpStr, XML_BOTTOM_PERCENT))
403 0 : rEntry.eOp = SC_BOTPERC;
404 0 : else if (IsXMLToken(aOpStr, XML_BOTTOM_VALUES))
405 0 : rEntry.eOp = SC_BOTVAL;
406 0 : else if (IsXMLToken(aOpStr, XML_EMPTY))
407 0 : rEntry.SetQueryByEmpty();
408 0 : else if (aOpStr == ">")
409 0 : rEntry.eOp = SC_GREATER;
410 0 : else if (aOpStr == ">=")
411 0 : rEntry.eOp = SC_GREATER_EQUAL;
412 0 : else if (aOpStr == "<")
413 0 : rEntry.eOp = SC_LESS;
414 0 : else if (aOpStr == "<=")
415 0 : rEntry.eOp = SC_LESS_EQUAL;
416 0 : else if (IsXMLToken(aOpStr, XML_NOEMPTY))
417 0 : rEntry.SetQueryByNonEmpty();
418 0 : else if (IsXMLToken(aOpStr, XML_TOP_PERCENT))
419 0 : rEntry.eOp = SC_TOPPERC;
420 0 : else if (IsXMLToken(aOpStr, XML_TOP_VALUES))
421 0 : rEntry.eOp = SC_TOPVAL;
422 0 : else if (IsXMLToken(aOpStr, XML_CONTAINS))
423 0 : rEntry.eOp = SC_CONTAINS;
424 0 : else if (IsXMLToken(aOpStr, XML_DOES_NOT_CONTAIN))
425 0 : rEntry.eOp = SC_DOES_NOT_CONTAIN;
426 0 : else if (IsXMLToken(aOpStr, XML_BEGINS_WITH))
427 0 : rEntry.eOp = SC_BEGINS_WITH;
428 0 : else if (IsXMLToken(aOpStr, XML_DOES_NOT_BEGIN_WITH))
429 0 : rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;
430 0 : else if (IsXMLToken(aOpStr, XML_ENDS_WITH))
431 0 : rEntry.eOp = SC_ENDS_WITH;
432 0 : else if (IsXMLToken(aOpStr, XML_DOES_NOT_END_WITH))
433 0 : rEntry.eOp = SC_DOES_NOT_END_WITH;
434 5 : }
435 :
436 8 : void ScXMLConditionContext::AddSetItem(const ScQueryEntry::Item& rItem)
437 : {
438 8 : maQueryItems.push_back(rItem);
439 8 : }
440 :
441 5 : void ScXMLConditionContext::EndElement()
442 : {
443 5 : ScQueryEntry& rEntry = mrQueryParam.AppendEntry();
444 :
445 : // We currently don't support per-condition case sensitivity.
446 5 : mrQueryParam.bCaseSens = bIsCaseSensitive;
447 :
448 5 : rEntry.bDoQuery = true;
449 5 : rEntry.eConnect = pFilterContext->GetConnection() ? SC_OR : SC_AND;
450 :
451 5 : GetOperator(sOperator, mrQueryParam, rEntry);
452 5 : SCCOLROW nStartPos = mrQueryParam.bByRow ? mrQueryParam.nCol1 : mrQueryParam.nRow1;
453 5 : rEntry.nField = nField + nStartPos;
454 :
455 5 : if (maQueryItems.empty())
456 : {
457 2 : ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
458 2 : if (IsXMLToken(sDataType, XML_NUMBER))
459 : {
460 0 : rItem.mfVal = sConditionValue.toDouble();
461 0 : rItem.meType = ScQueryEntry::ByValue;
462 : }
463 : else
464 : {
465 2 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
466 2 : rItem.maString = rPool.intern(sConditionValue);
467 2 : rItem.meType = ScQueryEntry::ByString;
468 : }
469 : }
470 : else
471 3 : rEntry.GetQueryItems().swap(maQueryItems);
472 5 : }
473 :
474 0 : const ScXMLImport& ScXMLSetItemContext::GetScImport() const
475 : {
476 0 : return static_cast<const ScXMLImport&>(GetImport());
477 : }
478 :
479 24 : ScXMLImport& ScXMLSetItemContext::GetScImport()
480 : {
481 24 : return static_cast<ScXMLImport&>(GetImport());
482 : }
483 :
484 8 : ScXMLSetItemContext::ScXMLSetItemContext(
485 : ScXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
486 : const Reference<XAttributeList>& xAttrList, ScXMLConditionContext& rParent) :
487 8 : SvXMLImportContext(rImport, nPrfx, rLName)
488 : {
489 8 : sal_Int32 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
490 8 : const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetFilterSetItemAttrTokenMap();
491 16 : for (sal_Int32 i = 0; i < nAttrCount; ++i)
492 : {
493 8 : const OUString& sAttrName = xAttrList->getNameByIndex(i);
494 16 : OUString aLocalName;
495 : sal_uInt16 nPrefix =
496 8 : GetScImport().GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
497 :
498 16 : const OUString& sValue = xAttrList->getValueByIndex(i);
499 :
500 8 : switch (rAttrTokenMap.Get(nPrefix, aLocalName))
501 : {
502 : case XML_TOK_FILTER_SET_ITEM_ATTR_VALUE:
503 : {
504 8 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
505 8 : ScQueryEntry::Item aItem;
506 8 : aItem.maString = rPool.intern(sValue);
507 8 : aItem.meType = ScQueryEntry::ByString;
508 8 : aItem.mfVal = 0.0;
509 8 : rParent.AddSetItem(aItem);
510 : }
511 8 : break;
512 : }
513 8 : }
514 8 : }
515 :
516 0 : SvXMLImportContext* ScXMLSetItemContext::CreateChildContext(
517 : sal_uInt16 nPrefix, const OUString& rLName,
518 : const Reference<XAttributeList>& /*xAttrList*/ )
519 : {
520 0 : return new SvXMLImportContext( GetImport(), nPrefix, rLName );;
521 : }
522 :
523 16 : ScXMLSetItemContext::~ScXMLSetItemContext()
524 : {
525 16 : }
526 :
527 8 : void ScXMLSetItemContext::EndElement()
528 : {
529 8 : }
530 :
531 1 : ScXMLDPFilterContext::ScXMLDPFilterContext( ScXMLImport& rImport,
532 : sal_uInt16 nPrfx,
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),
539 : aFilterFields(),
540 : nFilterFieldCount(0),
541 : bSkipDuplicates(false),
542 : bCopyOutputData(false),
543 : bUseRegularExpressions(false),
544 : bIsCaseSensitive(false),
545 : bConnectionOr(true),
546 : bNextConnectionOr(true),
547 1 : bConditionSourceRange(false)
548 : {
549 1 : ScDocument* pDoc(GetScImport().GetDocument());
550 :
551 1 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
552 1 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterAttrTokenMap());
553 2 : for( sal_Int16 i=0; i < nAttrCount; ++i )
554 : {
555 1 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
556 2 : OUString aLocalName;
557 1 : sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
558 1 : sAttrName, &aLocalName ));
559 2 : const OUString& sValue(xAttrList->getValueByIndex( i ));
560 :
561 1 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
562 : {
563 : case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS :
564 : {
565 0 : ScRange aScRange;
566 0 : sal_Int32 nOffset(0);
567 0 : if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
568 : {
569 0 : aOutputPosition = aScRange.aStart;
570 0 : bCopyOutputData = true;
571 : }
572 : }
573 0 : break;
574 : case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS :
575 : {
576 1 : sal_Int32 nOffset(0);
577 1 : if(ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
578 0 : bConditionSourceRange = true;
579 : }
580 1 : break;
581 : case XML_TOK_FILTER_ATTR_CONDITION_SOURCE :
582 : {
583 : // not supported by StarOffice
584 : }
585 0 : break;
586 : case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES :
587 : {
588 0 : bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE);
589 : }
590 0 : break;
591 : }
592 1 : }
593 1 : }
594 :
595 2 : ScXMLDPFilterContext::~ScXMLDPFilterContext()
596 : {
597 2 : }
598 :
599 1 : 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 )
603 : {
604 1 : SvXMLImportContext *pContext(0);
605 :
606 1 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
607 1 : switch( rTokenMap.Get( nPrefix, rLName ) )
608 : {
609 : case XML_TOK_FILTER_AND:
610 : {
611 : pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
612 1 : rLName, xAttrList, this);
613 : }
614 1 : break;
615 : case XML_TOK_FILTER_OR:
616 : {
617 : pContext = new ScXMLDPOrContext( GetScImport(), nPrefix,
618 0 : rLName, xAttrList, this);
619 : }
620 0 : break;
621 : case XML_TOK_FILTER_CONDITION:
622 : {
623 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
624 0 : rLName, xAttrList, this);
625 : }
626 0 : break;
627 : }
628 :
629 1 : if( !pContext )
630 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
631 :
632 1 : return pContext;
633 : }
634 :
635 1 : void ScXMLDPFilterContext::EndElement()
636 : {
637 1 : aFilterFields.bRegExp = bUseRegularExpressions;
638 1 : aFilterFields.bCaseSens = bIsCaseSensitive;
639 1 : aFilterFields.bDuplicate = !bSkipDuplicates;
640 1 : if (bCopyOutputData)
641 0 : pDataPilotTable->SetFilterOutputPosition(aOutputPosition);
642 :
643 1 : pDataPilotTable->SetSourceQueryParam(aFilterFields);
644 1 : if (bConditionSourceRange)
645 0 : pDataPilotTable->SetFilterSourceRange(aConditionSourceRangeAddress);
646 1 : }
647 :
648 2 : void ScXMLDPFilterContext::AddFilterField (const ScQueryEntry& aFilterField)
649 : {
650 2 : aFilterFields.Resize(nFilterFieldCount + 1);
651 2 : ScQueryEntry& rEntry(aFilterFields.GetEntry(nFilterFieldCount));
652 2 : rEntry = aFilterField;
653 2 : rEntry.bDoQuery = true;
654 2 : ++nFilterFieldCount;
655 2 : }
656 :
657 1 : ScXMLDPAndContext::ScXMLDPAndContext( ScXMLImport& rImport,
658 : sal_uInt16 nPrfx,
659 : const OUString& rLName,
660 : const ::com::sun::star::uno::Reference<
661 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
662 : ScXMLDPFilterContext* pTempFilterContext) :
663 1 : SvXMLImportContext( rImport, nPrfx, rLName )
664 : {
665 1 : pFilterContext = pTempFilterContext;
666 1 : pFilterContext->OpenConnection(false);
667 1 : }
668 :
669 2 : ScXMLDPAndContext::~ScXMLDPAndContext()
670 : {
671 2 : }
672 :
673 2 : 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 )
677 : {
678 2 : SvXMLImportContext *pContext(0);
679 :
680 2 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
681 2 : switch( rTokenMap.Get( nPrefix, rLName ) )
682 : {
683 : case XML_TOK_FILTER_OR:
684 : {
685 : // not supported in StarOffice
686 : }
687 0 : break;
688 : case XML_TOK_FILTER_CONDITION:
689 : {
690 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
691 2 : rLName, xAttrList, pFilterContext);
692 : }
693 2 : break;
694 : }
695 :
696 2 : if( !pContext )
697 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
698 :
699 2 : return pContext;
700 : }
701 :
702 1 : void ScXMLDPAndContext::EndElement()
703 : {
704 1 : pFilterContext->CloseConnection();
705 1 : }
706 :
707 0 : ScXMLDPOrContext::ScXMLDPOrContext( ScXMLImport& rImport,
708 : sal_uInt16 nPrfx,
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 0 : pFilterContext(pTempFilterContext)
715 : {
716 0 : pFilterContext->OpenConnection(true);
717 0 : }
718 :
719 0 : ScXMLDPOrContext::~ScXMLDPOrContext()
720 : {
721 0 : }
722 :
723 0 : 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 )
727 : {
728 0 : SvXMLImportContext *pContext(0);
729 :
730 0 : const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
731 0 : switch( rTokenMap.Get( nPrefix, rLName ) )
732 : {
733 : case XML_TOK_FILTER_AND:
734 : {
735 : pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
736 0 : rLName, xAttrList, pFilterContext);
737 : }
738 0 : break;
739 : case XML_TOK_FILTER_CONDITION:
740 : {
741 : pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
742 0 : rLName, xAttrList, pFilterContext);
743 : }
744 0 : break;
745 : }
746 :
747 0 : if( !pContext )
748 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
749 :
750 0 : return pContext;
751 : }
752 :
753 0 : void ScXMLDPOrContext::EndElement()
754 : {
755 0 : pFilterContext->CloseConnection();
756 0 : }
757 :
758 2 : ScXMLDPConditionContext::ScXMLDPConditionContext( ScXMLImport& rImport,
759 : sal_uInt16 nPrfx,
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 2 : sDataType(GetXMLToken(XML_TEXT)),
767 : nField(0),
768 4 : bIsCaseSensitive(false)
769 : {
770 :
771 2 : sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
772 2 : const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
773 10 : for( sal_Int16 i=0; i < nAttrCount; ++i )
774 : {
775 8 : const OUString& sAttrName(xAttrList->getNameByIndex( i ));
776 16 : OUString aLocalName;
777 8 : sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
778 8 : sAttrName, &aLocalName ));
779 16 : const OUString& sValue(xAttrList->getValueByIndex( i ));
780 :
781 8 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
782 : {
783 : case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
784 : {
785 2 : nField = sValue.toInt32();
786 : }
787 2 : break;
788 : case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
789 : {
790 0 : bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
791 : }
792 0 : break;
793 : case XML_TOK_CONDITION_ATTR_DATA_TYPE :
794 : {
795 2 : sDataType = sValue;
796 : }
797 2 : break;
798 : case XML_TOK_CONDITION_ATTR_VALUE :
799 : {
800 2 : sConditionValue = sValue;
801 : }
802 2 : break;
803 : case XML_TOK_CONDITION_ATTR_OPERATOR :
804 : {
805 2 : sOperator = sValue;
806 : }
807 2 : break;
808 : }
809 8 : }
810 2 : }
811 :
812 4 : ScXMLDPConditionContext::~ScXMLDPConditionContext()
813 : {
814 4 : }
815 :
816 0 : 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 */ )
820 : {
821 0 : return new SvXMLImportContext( GetImport(), nPrefix, rLName );
822 : }
823 :
824 2 : void ScXMLDPConditionContext::getOperatorXML(
825 : const OUString& sTempOperator, ScQueryOp& aFilterOperator, bool& bUseRegularExpressions)
826 : {
827 2 : bUseRegularExpressions = false;
828 2 : if (IsXMLToken(sTempOperator, XML_MATCH))
829 : {
830 0 : bUseRegularExpressions = true;
831 0 : aFilterOperator = SC_EQUAL;
832 : }
833 2 : else if (IsXMLToken(sTempOperator, XML_NOMATCH))
834 : {
835 0 : bUseRegularExpressions = true;
836 0 : aFilterOperator = SC_NOT_EQUAL;
837 : }
838 2 : else if (sTempOperator == "=")
839 0 : aFilterOperator = SC_EQUAL;
840 2 : else if (sTempOperator == "!=")
841 0 : aFilterOperator = SC_NOT_EQUAL;
842 2 : else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT))
843 0 : aFilterOperator = SC_BOTPERC;
844 2 : else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES))
845 0 : aFilterOperator = SC_BOTVAL;
846 2 : else if (sTempOperator == ">")
847 1 : aFilterOperator = SC_GREATER;
848 1 : else if (sTempOperator == ">=")
849 0 : aFilterOperator = SC_GREATER_EQUAL;
850 1 : else if (sTempOperator == "<")
851 0 : aFilterOperator = SC_LESS;
852 1 : else if (sTempOperator == "<=")
853 1 : aFilterOperator = SC_LESS_EQUAL;
854 0 : else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT))
855 0 : aFilterOperator = SC_TOPPERC;
856 0 : else if (IsXMLToken(sTempOperator, XML_TOP_VALUES))
857 0 : aFilterOperator = SC_TOPVAL;
858 2 : }
859 :
860 2 : void ScXMLDPConditionContext::EndElement()
861 : {
862 2 : ScQueryEntry aFilterField;
863 2 : if (pFilterContext->GetConnection())
864 1 : aFilterField.eConnect = SC_OR;
865 : else
866 1 : aFilterField.eConnect = SC_AND;
867 2 : pFilterContext->SetIsCaseSensitive(bIsCaseSensitive);
868 2 : if (IsXMLToken(sOperator, XML_EMPTY))
869 0 : aFilterField.SetQueryByEmpty();
870 2 : else if (IsXMLToken(sOperator, XML_NOEMPTY))
871 0 : aFilterField.SetQueryByNonEmpty();
872 : else
873 : {
874 2 : bool bUseRegularExpressions = false;
875 2 : getOperatorXML(sOperator, aFilterField.eOp, bUseRegularExpressions);
876 2 : pFilterContext->SetUseRegularExpressions(bUseRegularExpressions);
877 2 : aFilterField.nField = nField;
878 2 : ScQueryEntry::Item& rItem = aFilterField.GetQueryItem();
879 2 : svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool();
880 :
881 2 : if (IsXMLToken(sDataType, XML_NUMBER))
882 : {
883 2 : rItem.mfVal = sConditionValue.toDouble();
884 2 : rItem.maString = rPool.intern(sConditionValue);
885 2 : rItem.meType = ScQueryEntry::ByValue;
886 : }
887 : else
888 : {
889 0 : rItem.maString = rPool.intern(sConditionValue);
890 0 : rItem.meType = ScQueryEntry::ByString;
891 0 : rItem.mfVal = 0.0;
892 : }
893 : }
894 2 : pFilterContext->AddFilterField(aFilterField);
895 158 : }
896 :
897 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|