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 "XMLExportDatabaseRanges.hxx"
21 : #include <xmloff/xmltoken.hxx>
22 : #include <xmloff/xmlnmspe.hxx>
23 : #include <xmloff/nmspmap.hxx>
24 : #include <sax/tools/converter.hxx>
25 : #include "xmlexprt.hxx"
26 : #include "XMLExportIterator.hxx"
27 : #include "XMLConverter.hxx"
28 : #include "unonames.hxx"
29 : #include "dbdata.hxx"
30 : #include "document.hxx"
31 : #include "globstr.hrc"
32 : #include "globalnames.hxx"
33 : #include "XMLExportSharedData.hxx"
34 : #include "rangeutl.hxx"
35 : #include "subtotalparam.hxx"
36 : #include "queryparam.hxx"
37 : #include "queryentry.hxx"
38 :
39 : #include "svx/dataaccessdescriptor.hxx"
40 :
41 : #include <com/sun/star/sheet/DataImportMode.hpp>
42 : #include <com/sun/star/table/TableSortField.hpp>
43 : #include <com/sun/star/table/TableSortFieldType.hpp>
44 : #include <com/sun/star/sheet/XSubTotalField.hpp>
45 : #include <com/sun/star/sheet/XDatabaseRanges.hpp>
46 : #include <com/sun/star/sheet/XDatabaseRange.hpp>
47 : #include <com/sun/star/table/TableOrientation.hpp>
48 : #include <comphelper/extract.hxx>
49 :
50 : #include <map>
51 :
52 : //! not found in unonames.hxx
53 : #define SC_USERLIST "UserList"
54 :
55 : using namespace com::sun::star;
56 : using namespace xmloff::token;
57 :
58 8 : ScXMLExportDatabaseRanges::ScXMLExportDatabaseRanges(ScXMLExport& rTempExport)
59 : : rExport(rTempExport),
60 8 : pDoc( NULL )
61 : {
62 8 : }
63 :
64 8 : ScXMLExportDatabaseRanges::~ScXMLExportDatabaseRanges()
65 : {
66 8 : }
67 :
68 8 : ScMyEmptyDatabaseRangesContainer ScXMLExportDatabaseRanges::GetEmptyDatabaseRanges()
69 : {
70 8 : ScMyEmptyDatabaseRangesContainer aSkipRanges;
71 8 : if (rExport.GetModel().is())
72 : {
73 8 : uno::Reference <beans::XPropertySet> xPropertySet (rExport.GetModel(), uno::UNO_QUERY);
74 8 : if (xPropertySet.is())
75 : {
76 8 : uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(OUString(SC_UNO_DATABASERNG)), uno::UNO_QUERY);
77 8 : rExport.CheckAttrList();
78 8 : if (xDatabaseRanges.is())
79 : {
80 8 : uno::Sequence <OUString> aRanges(xDatabaseRanges->getElementNames());
81 8 : sal_Int32 nDatabaseRangesCount = aRanges.getLength();
82 8 : for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i)
83 : {
84 0 : OUString sDatabaseRangeName(aRanges[i]);
85 0 : uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
86 0 : if (xDatabaseRange.is())
87 : {
88 0 : uno::Reference <beans::XPropertySet> xDatabaseRangePropertySet (xDatabaseRange, uno::UNO_QUERY);
89 0 : if (xDatabaseRangePropertySet.is() &&
90 0 : ::cppu::any2bool(xDatabaseRangePropertySet->getPropertyValue(OUString(SC_UNONAME_STRIPDAT))))
91 : {
92 0 : uno::Sequence <beans::PropertyValue> aImportProperties(xDatabaseRange->getImportDescriptor());
93 0 : sal_Int32 nLength = aImportProperties.getLength();
94 0 : sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
95 0 : for (sal_Int32 j = 0; j < nLength; ++j)
96 0 : if ( aImportProperties[j].Name == SC_UNONAME_SRCTYPE )
97 0 : aImportProperties[j].Value >>= nSourceType;
98 0 : if (nSourceType != sheet::DataImportMode_NONE)
99 : {
100 0 : table::CellRangeAddress aArea = xDatabaseRange->getDataArea();
101 0 : aSkipRanges.AddNewEmptyDatabaseRange(aArea);
102 :
103 : // #105276#; set last row/column so default styles are collected
104 0 : rExport.GetSharedData()->SetLastColumn(aArea.Sheet, aArea.EndColumn);
105 0 : rExport.GetSharedData()->SetLastRow(aArea.Sheet, aArea.EndRow);
106 0 : }
107 0 : }
108 : }
109 8 : }
110 8 : }
111 8 : }
112 : }
113 8 : return aSkipRanges;
114 : }
115 :
116 : namespace {
117 :
118 : class WriteDatabaseRange : public ::std::unary_function<ScDBData, void>
119 : {
120 : ScXMLExport& mrExport;
121 : ScDocument* mpDoc;
122 : sal_Int32 mnCounter;
123 : ScDBCollection::RangeType meRangeType;
124 : public:
125 :
126 0 : WriteDatabaseRange(ScXMLExport& rExport, ScDocument* pDoc) :
127 0 : mrExport(rExport), mpDoc(pDoc), mnCounter(0), meRangeType(ScDBCollection::GlobalNamed) {}
128 :
129 0 : void setRangeType(ScDBCollection::RangeType eNew)
130 : {
131 0 : meRangeType = eNew;
132 0 : }
133 :
134 0 : void operator() (const ::std::pair<SCTAB, const ScDBData*>& r)
135 : {
136 0 : if (meRangeType != ScDBCollection::SheetAnonymous)
137 0 : return;
138 :
139 : // name
140 0 : OUStringBuffer aBuf;
141 0 : aBuf.appendAscii(STR_DB_LOCAL_NONAME);
142 0 : aBuf.append(static_cast<sal_Int32>(r.first)); // appended number equals sheet index on import.
143 :
144 0 : write(aBuf.makeStringAndClear(), *r.second);
145 : }
146 :
147 0 : void operator() (const ScDBData& rData)
148 : {
149 0 : if (meRangeType == ScDBCollection::GlobalAnonymous)
150 : {
151 : // name
152 0 : OUStringBuffer aBuf;
153 0 : aBuf.appendAscii(STR_DB_GLOBAL_NONAME);
154 0 : aBuf.append(++mnCounter); // 1-based, for entirely arbitrary reasons. The numbers are ignored on import.
155 :
156 0 : write(aBuf.makeStringAndClear(), rData);
157 : }
158 0 : else if (meRangeType == ScDBCollection::GlobalNamed)
159 0 : write(rData.GetName(), rData);
160 0 : }
161 :
162 : private:
163 0 : void write(const OUString& rName, const ScDBData& rData)
164 : {
165 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rName);
166 :
167 : // range
168 0 : ScRange aRange;
169 0 : rData.GetArea(aRange);
170 0 : OUString aRangeStr;
171 : ScRangeStringConverter::GetStringFromRange(
172 0 : aRangeStr, aRange, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
173 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aRangeStr);
174 :
175 : // various boolean flags.
176 0 : if (rData.HasImportSelection())
177 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TRUE);
178 0 : if (rData.HasAutoFilter())
179 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TRUE);
180 0 : if (rData.IsKeepFmt())
181 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TRUE);
182 0 : if (rData.IsDoSize())
183 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_FALSE);
184 0 : if (rData.IsStripData())
185 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_FALSE);
186 :
187 0 : ScQueryParam aQueryParam;
188 0 : rData.GetQueryParam(aQueryParam);
189 0 : if (!aQueryParam.bHasHeader)
190 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_FALSE);
191 :
192 0 : ScSortParam aSortParam;
193 0 : rData.GetSortParam(aSortParam);
194 0 : if (!aSortParam.bByRow)
195 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_COLUMN);
196 :
197 0 : sal_Int32 nRefresh = rData.GetRefreshDelay();
198 0 : if (nRefresh)
199 : {
200 0 : OUStringBuffer aBuf;
201 : ::sax::Converter::convertDuration(aBuf,
202 0 : static_cast<double>(nRefresh) / 86400.0);
203 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, aBuf.makeStringAndClear());
204 : }
205 :
206 0 : SvXMLElementExport aElemDR(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, true, true);
207 :
208 0 : writeImport(rData);
209 0 : writeFilter(rData);
210 0 : writeSort(rData);
211 0 : writeSubtotals(rData);
212 0 : }
213 :
214 0 : void writeImport(const ScDBData& rData)
215 : {
216 0 : ScImportParam aParam;
217 0 : rData.GetImportParam(aParam);
218 :
219 0 : OUString sDatabaseName;
220 0 : OUString sConRes;
221 :
222 0 : ::svx::ODataAccessDescriptor aDescriptor;
223 0 : aDescriptor.setDataSource(aParam.aDBName);
224 0 : if (aDescriptor.has(::svx::daDataSource))
225 : {
226 0 : sDatabaseName = aParam.aDBName;
227 : }
228 0 : else if (aDescriptor.has(::svx::daConnectionResource))
229 : {
230 0 : sConRes = aParam.aDBName;
231 : }
232 :
233 0 : sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
234 0 : if (aParam.bImport)
235 : {
236 0 : if (aParam.bSql)
237 0 : nSourceType = sheet::DataImportMode_SQL;
238 0 : else if (aParam.nType == ScDbQuery)
239 0 : nSourceType = sheet::DataImportMode_QUERY;
240 : else
241 0 : nSourceType = sheet::DataImportMode_TABLE;
242 : }
243 :
244 0 : switch (nSourceType)
245 : {
246 0 : case sheet::DataImportMode_NONE : break;
247 : case sheet::DataImportMode_QUERY :
248 : {
249 0 : if (!sDatabaseName.isEmpty())
250 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
251 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, aParam.aStatement);
252 0 : SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, true, true);
253 0 : if (!sConRes.isEmpty())
254 : {
255 0 : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
256 0 : SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
257 0 : }
258 : }
259 0 : break;
260 : case sheet::DataImportMode_TABLE :
261 : {
262 0 : if (!sDatabaseName.isEmpty())
263 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
264 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, aParam.aStatement);
265 0 : SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, true, true);
266 0 : if (!sConRes.isEmpty())
267 : {
268 0 : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
269 0 : SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
270 0 : }
271 : }
272 0 : break;
273 : case sheet::DataImportMode_SQL :
274 : {
275 0 : if (!sDatabaseName.isEmpty())
276 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
277 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, aParam.aStatement);
278 0 : if (!aParam.bNative)
279 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
280 0 : SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, true, true);
281 0 : if (!sConRes.isEmpty())
282 : {
283 0 : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
284 0 : SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
285 0 : }
286 : }
287 0 : break;
288 : default:
289 : {
290 : // added to avoid warnings
291 : }
292 0 : }
293 0 : }
294 :
295 0 : void writeSort(const ScDBData& rData)
296 : {
297 0 : ScSortParam aParam;
298 0 : rData.GetSortParam(aParam);
299 :
300 : // Count sort items first.
301 0 : size_t nSortCount = 0;
302 0 : for (; nSortCount < aParam.GetSortKeyCount(); ++nSortCount)
303 : {
304 0 : if (!aParam.maKeyState[nSortCount].bDoSort)
305 0 : break;
306 : }
307 :
308 0 : if (!nSortCount)
309 : // Nothing to export.
310 0 : return;
311 :
312 0 : ScAddress aOutPos(aParam.nDestCol, aParam.nDestRow, aParam.nDestTab);
313 :
314 0 : if (!aParam.bIncludePattern)
315 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
316 :
317 0 : if (!aParam.bInplace)
318 : {
319 0 : OUString aStr;
320 : ScRangeStringConverter::GetStringFromAddress(
321 0 : aStr, aOutPos, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
322 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aStr);
323 : }
324 :
325 0 : if (aParam.bCaseSens)
326 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
327 :
328 0 : if (!aParam.aCollatorLocale.Language.isEmpty())
329 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aParam.aCollatorLocale.Language);
330 0 : if (!aParam.aCollatorLocale.Country.isEmpty())
331 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aParam.aCollatorLocale.Country);
332 0 : if (!aParam.aCollatorAlgorithm.isEmpty())
333 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aParam.aCollatorAlgorithm);
334 :
335 0 : SvXMLElementExport aElemS(mrExport, XML_NAMESPACE_TABLE, XML_SORT, true, true);
336 :
337 0 : ScRange aRange;
338 0 : rData.GetArea(aRange);
339 0 : SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
340 :
341 0 : for (size_t i = 0; i < nSortCount; ++i)
342 : {
343 : // Convert field value from absolute to relative.
344 0 : SCCOLROW nField = aParam.maKeyState[i].nField - nFieldStart;
345 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(nField));
346 :
347 0 : if (!aParam.maKeyState[i].bAscending)
348 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
349 :
350 0 : if (aParam.bUserDef)
351 : {
352 0 : OUStringBuffer aBuf;
353 0 : aBuf.appendAscii(SC_USERLIST);
354 0 : aBuf.append(aParam.nUserIndex);
355 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, aBuf.makeStringAndClear());
356 : }
357 : else
358 : {
359 : // Right now we only support automatic field type. In the
360 : // future we may support numeric or alphanumeric field type.
361 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_AUTOMATIC);
362 : }
363 :
364 0 : SvXMLElementExport aElemSb(mrExport, XML_NAMESPACE_TABLE, XML_SORT_BY, true, true);
365 0 : }
366 : }
367 :
368 0 : OUString getOperatorXML(const ScQueryEntry& rEntry, bool bRegExp) const
369 : {
370 0 : switch (rEntry.eOp)
371 : {
372 : case SC_BEGINS_WITH:
373 0 : return GetXMLToken(XML_BEGINS_WITH);
374 : case SC_BOTPERC:
375 0 : return GetXMLToken(XML_BOTTOM_PERCENT);
376 : case SC_BOTVAL:
377 0 : return GetXMLToken(XML_BOTTOM_VALUES);
378 : case SC_CONTAINS:
379 0 : return GetXMLToken(XML_CONTAINS);
380 : case SC_DOES_NOT_BEGIN_WITH:
381 0 : return GetXMLToken(XML_DOES_NOT_BEGIN_WITH);
382 : case SC_DOES_NOT_CONTAIN:
383 0 : return GetXMLToken(XML_DOES_NOT_CONTAIN);
384 : case SC_DOES_NOT_END_WITH:
385 0 : return GetXMLToken(XML_DOES_NOT_END_WITH);
386 : case SC_ENDS_WITH:
387 0 : return GetXMLToken(XML_ENDS_WITH);
388 : case SC_EQUAL:
389 : {
390 0 : if (rEntry.IsQueryByEmpty())
391 0 : return GetXMLToken(XML_EMPTY);
392 0 : else if (rEntry.IsQueryByNonEmpty())
393 0 : return GetXMLToken(XML_NOEMPTY);
394 :
395 0 : if (bRegExp)
396 0 : return GetXMLToken(XML_MATCH);
397 : else
398 0 : return OUString("=");
399 : }
400 : case SC_GREATER:
401 0 : return OUString(">");
402 : case SC_GREATER_EQUAL:
403 0 : return OUString(">=");
404 : case SC_LESS:
405 0 : return OUString("<");
406 : case SC_LESS_EQUAL:
407 0 : return OUString("<=");
408 : case SC_NOT_EQUAL:
409 0 : if (bRegExp)
410 0 : return GetXMLToken(XML_NOMATCH);
411 : else
412 0 : return OUString("!=");
413 : case SC_TOPPERC:
414 0 : return GetXMLToken(XML_TOP_PERCENT);
415 : case SC_TOPVAL:
416 0 : return GetXMLToken(XML_TOP_VALUES);
417 : default:
418 : ;
419 : }
420 0 : return OUString("=");
421 : }
422 :
423 : class WriteSetItem : public std::unary_function<ScQueryEntry::Item, void>
424 : {
425 : ScXMLExport& mrExport;
426 : public:
427 0 : WriteSetItem(ScXMLExport& r) : mrExport(r) {}
428 0 : void operator() (const ScQueryEntry::Item& rItem) const
429 : {
430 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString);
431 0 : SvXMLElementExport aElem(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_SET_ITEM, true, true);
432 0 : }
433 : };
434 :
435 0 : void writeCondition(const ScQueryEntry& rEntry, SCCOLROW nFieldStart, bool bCaseSens, bool bRegExp)
436 : {
437 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(rEntry.nField - nFieldStart));
438 0 : if (bCaseSens)
439 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
440 :
441 0 : const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
442 0 : if (rItems.empty())
443 : {
444 : OSL_FAIL("Query entry has no items at all! It must have at least one!");
445 0 : return;
446 : }
447 :
448 0 : else if (rItems.size() == 1)
449 : {
450 : // Single item condition.
451 0 : const ScQueryEntry::Item& rItem = rItems.front();
452 0 : if (rItem.meType == ScQueryEntry::ByString)
453 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString);
454 : else
455 : {
456 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
457 0 : OUStringBuffer aBuf;
458 0 : ::sax::Converter::convertDouble(aBuf, rItem.mfVal);
459 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aBuf.makeStringAndClear());
460 : }
461 :
462 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(rEntry, bRegExp));
463 0 : SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true);
464 : }
465 : else
466 : {
467 : // Multi-item condition.
468 : OSL_ASSERT(rItems.size() > 1);
469 :
470 : // Store the 1st value for backward compatibility.
471 0 : const ScQueryEntry::Item& rItem = rItems.front();
472 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString);
473 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, OUString("="));
474 0 : SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true);
475 :
476 0 : std::for_each(rItems.begin(), rItems.end(), WriteSetItem(mrExport));
477 : }
478 : }
479 :
480 0 : void writeFilter(const ScDBData& rData)
481 : {
482 0 : ScQueryParam aParam;
483 0 : rData.GetQueryParam(aParam);
484 0 : size_t nCount = 0;
485 0 : for (size_t n = aParam.GetEntryCount(); nCount < n; ++nCount)
486 : {
487 0 : if (!aParam.GetEntry(nCount).bDoQuery)
488 0 : break;
489 : }
490 :
491 0 : if (!nCount)
492 : // No filter criteria to save. Bail out.
493 0 : return;
494 :
495 0 : if (!aParam.bInplace)
496 : {
497 0 : OUString aAddrStr;
498 : ScRangeStringConverter::GetStringFromAddress(
499 0 : aAddrStr, ScAddress(aParam.nDestCol, aParam.nDestRow, aParam.nDestTab), mpDoc, ::formula::FormulaGrammar::CONV_OOO);
500 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aAddrStr);
501 : }
502 :
503 0 : ScRange aAdvSource;
504 0 : if (rData.GetAdvancedQuerySource(aAdvSource))
505 : {
506 0 : OUString aAddrStr;
507 : ScRangeStringConverter::GetStringFromRange(
508 0 : aAddrStr, aAdvSource, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
509 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, aAddrStr);
510 : }
511 :
512 0 : if (!aParam.bDuplicate)
513 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
514 :
515 0 : SvXMLElementExport aElemF(mrExport, XML_NAMESPACE_TABLE, XML_FILTER, true, true);
516 :
517 0 : bool bAnd = false;
518 0 : bool bOr = false;
519 :
520 0 : for (size_t i = 0; i < nCount; ++i)
521 : {
522 0 : const ScQueryEntry& rEntry = aParam.GetEntry(i);
523 0 : if (rEntry.eConnect == SC_AND)
524 0 : bAnd = true;
525 : else
526 0 : bOr = true;
527 : }
528 :
529 : // Note that export field index values are relative to the first field.
530 0 : ScRange aRange;
531 0 : rData.GetArea(aRange);
532 0 : SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
533 :
534 0 : if (bOr && !bAnd)
535 : {
536 0 : SvXMLElementExport aElemOr(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
537 0 : for (size_t i = 0; i < nCount; ++i)
538 0 : writeCondition(aParam.GetEntry(i), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
539 : }
540 0 : else if (bAnd && !bOr)
541 : {
542 0 : SvXMLElementExport aElemAnd(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, true, true);
543 0 : for (size_t i = 0; i < nCount; ++i)
544 0 : writeCondition(aParam.GetEntry(i), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
545 : }
546 0 : else if (nCount == 1)
547 : {
548 0 : writeCondition(aParam.GetEntry(0), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
549 : }
550 : else
551 : {
552 0 : SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
553 0 : ScQueryEntry aPrevEntry = aParam.GetEntry(0);
554 0 : ScQueryConnect eConnect = aParam.GetEntry(1).eConnect;
555 0 : bool bOpenAndElement = false;
556 0 : OUString aName = mrExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND));
557 :
558 0 : if (eConnect == SC_AND)
559 : {
560 0 : mrExport.StartElement(aName, true);
561 0 : bOpenAndElement = true;
562 : }
563 : else
564 0 : bOpenAndElement = false;
565 :
566 0 : for (size_t i = 1; i < nCount; ++i)
567 : {
568 0 : const ScQueryEntry& rEntry = aParam.GetEntry(i);
569 0 : if (eConnect != rEntry.eConnect)
570 : {
571 0 : eConnect = rEntry.eConnect;
572 0 : if (rEntry.eConnect == SC_AND)
573 : {
574 0 : mrExport.StartElement(aName, true );
575 0 : bOpenAndElement = true;
576 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
577 0 : aPrevEntry = rEntry;
578 0 : if (i == nCount - 1)
579 : {
580 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
581 0 : mrExport.EndElement(aName, true);
582 0 : bOpenAndElement = false;
583 : }
584 : }
585 : else
586 : {
587 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
588 0 : aPrevEntry = rEntry;
589 0 : if (bOpenAndElement)
590 : {
591 0 : mrExport.EndElement(aName, true);
592 0 : bOpenAndElement = false;
593 : }
594 0 : if (i == nCount - 1)
595 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
596 : }
597 : }
598 : else
599 : {
600 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
601 0 : aPrevEntry = rEntry;
602 0 : if (i == nCount - 1)
603 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
604 : }
605 : }
606 0 : if(bOpenAndElement)
607 0 : mrExport.EndElement(aName, true);
608 0 : }
609 : }
610 :
611 0 : void writeSubtotals(const ScDBData& rData)
612 : {
613 0 : ScSubTotalParam aParam;
614 0 : rData.GetSubTotalParam(aParam);
615 :
616 0 : size_t nCount = 0;
617 0 : for (; nCount < MAXSUBTOTAL; ++nCount)
618 : {
619 0 : if (!aParam.bGroupActive[nCount])
620 0 : break;
621 : }
622 :
623 0 : if (!nCount)
624 0 : return;
625 :
626 0 : if (!aParam.bIncludePattern)
627 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
628 :
629 0 : if (aParam.bPagebreak)
630 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TRUE);
631 :
632 0 : if (aParam.bCaseSens)
633 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
634 :
635 0 : SvXMLElementExport aElemSTRs(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, true, true);
636 :
637 0 : if (aParam.bDoSort)
638 : {
639 0 : if (!aParam.bAscending)
640 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
641 :
642 0 : if (aParam.bUserDef)
643 : {
644 0 : OUStringBuffer aBuf;
645 0 : aBuf.appendAscii(SC_USERLIST);
646 0 : aBuf.append(static_cast<sal_Int32>(aParam.nUserIndex));
647 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, aBuf.makeStringAndClear());
648 : }
649 0 : SvXMLElementExport aElemSGs(mrExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, true, true);
650 : }
651 :
652 0 : for (size_t i = 0; i < MAXSUBTOTAL; ++i)
653 : {
654 0 : if (!aParam.bGroupActive[i])
655 : // We're done!
656 0 : break;
657 :
658 0 : sal_Int32 nFieldCol = static_cast<sal_Int32>(aParam.nField[i]);
659 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, OUString::valueOf(nFieldCol));
660 0 : SvXMLElementExport aElemSTR(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, true, true);
661 :
662 0 : for (SCCOL j = 0, n = aParam.nSubTotals[i]; j < n; ++j)
663 : {
664 0 : sal_Int32 nCol = static_cast<sal_Int32>(aParam.pSubTotals[i][j]);
665 0 : ScSubTotalFunc eFunc = aParam.pFunctions[i][j];
666 :
667 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(nCol));
668 0 : OUString aFuncStr;
669 0 : ScXMLConverter::GetStringFromFunction(aFuncStr, eFunc);
670 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, aFuncStr);
671 :
672 0 : SvXMLElementExport aElemSTF(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, true, true);
673 0 : }
674 0 : }
675 : }
676 : };
677 :
678 : }
679 :
680 8 : void ScXMLExportDatabaseRanges::WriteDatabaseRanges()
681 : {
682 : typedef ::std::map<SCTAB, const ScDBData*> SheetLocalDBs;
683 :
684 8 : pDoc = rExport.GetDocument();
685 8 : if (!pDoc)
686 8 : return;
687 :
688 : // Get sheet-local anonymous ranges.
689 8 : SCTAB nTabCount = pDoc->GetTableCount();
690 8 : SheetLocalDBs aSheetDBs;
691 17 : for (SCTAB i = 0; i < nTabCount; ++i)
692 : {
693 9 : const ScDBData* p = pDoc->GetAnonymousDBData(i);
694 9 : if (p)
695 0 : aSheetDBs.insert(SheetLocalDBs::value_type(i, p));
696 : }
697 :
698 8 : bool bHasRanges = !aSheetDBs.empty();
699 :
700 : // See if we have global ranges.
701 8 : ScDBCollection* pDBCollection = pDoc->GetDBCollection();
702 8 : if (pDBCollection)
703 : {
704 8 : if (!pDBCollection->getNamedDBs().empty() || !pDBCollection->getAnonDBs().empty())
705 0 : bHasRanges = true;
706 : }
707 :
708 8 : if (!bHasRanges)
709 : // No ranges to export. Bail out.
710 8 : return;
711 :
712 0 : SvXMLElementExport aElemDRs(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, true, true);
713 :
714 0 : WriteDatabaseRange func(rExport, pDoc);
715 :
716 0 : if (pDBCollection)
717 : {
718 : // Write global named ranges.
719 0 : func.setRangeType(ScDBCollection::GlobalNamed);
720 0 : const ScDBCollection::NamedDBs& rNamedDBs = pDBCollection->getNamedDBs();
721 0 : ::std::for_each(rNamedDBs.begin(), rNamedDBs.end(), func);
722 :
723 : // Add global anonymous DB ranges.
724 0 : func.setRangeType(ScDBCollection::GlobalAnonymous);
725 0 : const ScDBCollection::AnonDBs& rAnonDBs = pDBCollection->getAnonDBs();
726 0 : ::std::for_each(rAnonDBs.begin(), rAnonDBs.end(), func);
727 : }
728 :
729 : // Write sheet-local ranges.
730 0 : func.setRangeType(ScDBCollection::SheetAnonymous);
731 0 : ::std::for_each(aSheetDBs.begin(), aSheetDBs.end(), func);
732 : }
733 :
734 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|