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