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 18 : ScXMLExportDatabaseRanges::ScXMLExportDatabaseRanges(ScXMLExport& rTempExport)
59 : : rExport(rTempExport),
60 18 : pDoc( NULL )
61 : {
62 18 : }
63 :
64 18 : ScXMLExportDatabaseRanges::~ScXMLExportDatabaseRanges()
65 : {
66 18 : }
67 :
68 18 : ScMyEmptyDatabaseRangesContainer ScXMLExportDatabaseRanges::GetEmptyDatabaseRanges()
69 : {
70 18 : ScMyEmptyDatabaseRangesContainer aSkipRanges;
71 18 : if (rExport.GetModel().is())
72 : {
73 18 : uno::Reference <beans::XPropertySet> xPropertySet (rExport.GetModel(), uno::UNO_QUERY);
74 18 : if (xPropertySet.is())
75 : {
76 18 : uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(OUString(SC_UNO_DATABASERNG)), uno::UNO_QUERY);
77 18 : rExport.CheckAttrList();
78 18 : if (xDatabaseRanges.is())
79 : {
80 18 : uno::Sequence <OUString> aRanges(xDatabaseRanges->getElementNames());
81 18 : sal_Int32 nDatabaseRangesCount = aRanges.getLength();
82 18 : 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 18 : }
110 18 : }
111 18 : }
112 : }
113 18 : 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 : mrExport.AddLanguageTagAttributes( XML_NAMESPACE_TABLE, XML_NAMESPACE_TABLE, aParam.aCollatorLocale, false);
329 0 : if (!aParam.aCollatorAlgorithm.isEmpty())
330 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aParam.aCollatorAlgorithm);
331 :
332 0 : SvXMLElementExport aElemS(mrExport, XML_NAMESPACE_TABLE, XML_SORT, true, true);
333 :
334 0 : ScRange aRange;
335 0 : rData.GetArea(aRange);
336 0 : SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
337 :
338 0 : for (size_t i = 0; i < nSortCount; ++i)
339 : {
340 : // Convert field value from absolute to relative.
341 0 : SCCOLROW nField = aParam.maKeyState[i].nField - nFieldStart;
342 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(nField));
343 :
344 0 : if (!aParam.maKeyState[i].bAscending)
345 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
346 :
347 0 : if (aParam.bUserDef)
348 : {
349 0 : OUStringBuffer aBuf;
350 0 : aBuf.appendAscii(SC_USERLIST);
351 0 : aBuf.append(aParam.nUserIndex);
352 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, aBuf.makeStringAndClear());
353 : }
354 : else
355 : {
356 : // Right now we only support automatic field type. In the
357 : // future we may support numeric or alphanumeric field type.
358 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_AUTOMATIC);
359 : }
360 :
361 0 : SvXMLElementExport aElemSb(mrExport, XML_NAMESPACE_TABLE, XML_SORT_BY, true, true);
362 0 : }
363 : }
364 :
365 0 : OUString getOperatorXML(const ScQueryEntry& rEntry, bool bRegExp) const
366 : {
367 0 : switch (rEntry.eOp)
368 : {
369 : case SC_BEGINS_WITH:
370 0 : return GetXMLToken(XML_BEGINS_WITH);
371 : case SC_BOTPERC:
372 0 : return GetXMLToken(XML_BOTTOM_PERCENT);
373 : case SC_BOTVAL:
374 0 : return GetXMLToken(XML_BOTTOM_VALUES);
375 : case SC_CONTAINS:
376 0 : return GetXMLToken(XML_CONTAINS);
377 : case SC_DOES_NOT_BEGIN_WITH:
378 0 : return GetXMLToken(XML_DOES_NOT_BEGIN_WITH);
379 : case SC_DOES_NOT_CONTAIN:
380 0 : return GetXMLToken(XML_DOES_NOT_CONTAIN);
381 : case SC_DOES_NOT_END_WITH:
382 0 : return GetXMLToken(XML_DOES_NOT_END_WITH);
383 : case SC_ENDS_WITH:
384 0 : return GetXMLToken(XML_ENDS_WITH);
385 : case SC_EQUAL:
386 : {
387 0 : if (rEntry.IsQueryByEmpty())
388 0 : return GetXMLToken(XML_EMPTY);
389 0 : else if (rEntry.IsQueryByNonEmpty())
390 0 : return GetXMLToken(XML_NOEMPTY);
391 :
392 0 : if (bRegExp)
393 0 : return GetXMLToken(XML_MATCH);
394 : else
395 0 : return OUString("=");
396 : }
397 : case SC_GREATER:
398 0 : return OUString(">");
399 : case SC_GREATER_EQUAL:
400 0 : return OUString(">=");
401 : case SC_LESS:
402 0 : return OUString("<");
403 : case SC_LESS_EQUAL:
404 0 : return OUString("<=");
405 : case SC_NOT_EQUAL:
406 0 : if (bRegExp)
407 0 : return GetXMLToken(XML_NOMATCH);
408 : else
409 0 : return OUString("!=");
410 : case SC_TOPPERC:
411 0 : return GetXMLToken(XML_TOP_PERCENT);
412 : case SC_TOPVAL:
413 0 : return GetXMLToken(XML_TOP_VALUES);
414 : default:
415 : ;
416 : }
417 0 : return OUString("=");
418 : }
419 :
420 : class WriteSetItem : public std::unary_function<ScQueryEntry::Item, void>
421 : {
422 : ScXMLExport& mrExport;
423 : public:
424 0 : WriteSetItem(ScXMLExport& r) : mrExport(r) {}
425 0 : void operator() (const ScQueryEntry::Item& rItem) const
426 : {
427 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString.getString());
428 0 : SvXMLElementExport aElem(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_SET_ITEM, true, true);
429 0 : }
430 : };
431 :
432 0 : void writeCondition(const ScQueryEntry& rEntry, SCCOLROW nFieldStart, bool bCaseSens, bool bRegExp)
433 : {
434 0 : const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
435 0 : if (rItems.empty())
436 : {
437 : OSL_FAIL("Query entry has no items at all! It must have at least one!");
438 0 : return;
439 : }
440 :
441 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(rEntry.nField - nFieldStart));
442 0 : if (bCaseSens)
443 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
444 :
445 0 : if (rItems.size() == 1)
446 : {
447 : // Single item condition.
448 0 : const ScQueryEntry::Item& rItem = rItems.front();
449 0 : if (rItem.meType == ScQueryEntry::ByString)
450 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString.getString());
451 : else
452 : {
453 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
454 0 : OUStringBuffer aBuf;
455 0 : ::sax::Converter::convertDouble(aBuf, rItem.mfVal);
456 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aBuf.makeStringAndClear());
457 : }
458 :
459 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(rEntry, bRegExp));
460 0 : SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true);
461 : }
462 : else
463 : {
464 : // Multi-item condition.
465 : OSL_ASSERT(rItems.size() > 1);
466 :
467 : // Store the 1st value for backward compatibility.
468 0 : const ScQueryEntry::Item& rItem = rItems.front();
469 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString.getString());
470 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, OUString("="));
471 0 : SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true);
472 :
473 0 : std::for_each(rItems.begin(), rItems.end(), WriteSetItem(mrExport));
474 : }
475 : }
476 :
477 0 : void writeFilter(const ScDBData& rData)
478 : {
479 0 : ScQueryParam aParam;
480 0 : rData.GetQueryParam(aParam);
481 0 : size_t nCount = 0;
482 0 : for (size_t n = aParam.GetEntryCount(); nCount < n; ++nCount)
483 : {
484 0 : if (!aParam.GetEntry(nCount).bDoQuery)
485 0 : break;
486 : }
487 :
488 0 : if (!nCount)
489 : // No filter criteria to save. Bail out.
490 0 : return;
491 :
492 0 : if (!aParam.bInplace)
493 : {
494 0 : OUString aAddrStr;
495 : ScRangeStringConverter::GetStringFromAddress(
496 0 : aAddrStr, ScAddress(aParam.nDestCol, aParam.nDestRow, aParam.nDestTab), mpDoc, ::formula::FormulaGrammar::CONV_OOO);
497 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aAddrStr);
498 : }
499 :
500 0 : ScRange aAdvSource;
501 0 : if (rData.GetAdvancedQuerySource(aAdvSource))
502 : {
503 0 : OUString aAddrStr;
504 : ScRangeStringConverter::GetStringFromRange(
505 0 : aAddrStr, aAdvSource, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
506 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, aAddrStr);
507 : }
508 :
509 0 : if (!aParam.bDuplicate)
510 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
511 :
512 0 : SvXMLElementExport aElemF(mrExport, XML_NAMESPACE_TABLE, XML_FILTER, true, true);
513 :
514 0 : bool bAnd = false;
515 0 : bool bOr = false;
516 :
517 0 : for (size_t i = 0; i < nCount; ++i)
518 : {
519 0 : const ScQueryEntry& rEntry = aParam.GetEntry(i);
520 0 : if (rEntry.eConnect == SC_AND)
521 0 : bAnd = true;
522 : else
523 0 : bOr = true;
524 : }
525 :
526 : // Note that export field index values are relative to the first field.
527 0 : ScRange aRange;
528 0 : rData.GetArea(aRange);
529 0 : SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
530 :
531 0 : if (bOr && !bAnd)
532 : {
533 0 : SvXMLElementExport aElemOr(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
534 0 : for (size_t i = 0; i < nCount; ++i)
535 0 : writeCondition(aParam.GetEntry(i), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
536 : }
537 0 : else if (bAnd && !bOr)
538 : {
539 0 : SvXMLElementExport aElemAnd(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, true, true);
540 0 : for (size_t i = 0; i < nCount; ++i)
541 0 : writeCondition(aParam.GetEntry(i), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
542 : }
543 0 : else if (nCount == 1)
544 : {
545 0 : writeCondition(aParam.GetEntry(0), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
546 : }
547 : else
548 : {
549 0 : SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
550 0 : ScQueryEntry aPrevEntry = aParam.GetEntry(0);
551 0 : ScQueryConnect eConnect = aParam.GetEntry(1).eConnect;
552 0 : bool bOpenAndElement = false;
553 0 : OUString aName = mrExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND));
554 :
555 0 : if (eConnect == SC_AND)
556 : {
557 0 : mrExport.StartElement(aName, true);
558 0 : bOpenAndElement = true;
559 : }
560 : else
561 0 : bOpenAndElement = false;
562 :
563 0 : for (size_t i = 1; i < nCount; ++i)
564 : {
565 0 : const ScQueryEntry& rEntry = aParam.GetEntry(i);
566 0 : if (eConnect != rEntry.eConnect)
567 : {
568 0 : eConnect = rEntry.eConnect;
569 0 : if (rEntry.eConnect == SC_AND)
570 : {
571 0 : mrExport.StartElement(aName, true );
572 0 : bOpenAndElement = true;
573 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
574 0 : aPrevEntry = rEntry;
575 0 : if (i == nCount - 1)
576 : {
577 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
578 0 : mrExport.EndElement(aName, true);
579 0 : bOpenAndElement = false;
580 : }
581 : }
582 : else
583 : {
584 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
585 0 : aPrevEntry = rEntry;
586 0 : if (bOpenAndElement)
587 : {
588 0 : mrExport.EndElement(aName, true);
589 0 : bOpenAndElement = false;
590 : }
591 0 : if (i == nCount - 1)
592 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
593 : }
594 : }
595 : else
596 : {
597 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
598 0 : aPrevEntry = rEntry;
599 0 : if (i == nCount - 1)
600 0 : writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
601 : }
602 : }
603 0 : if(bOpenAndElement)
604 0 : mrExport.EndElement(aName, true);
605 0 : }
606 : }
607 :
608 0 : void writeSubtotals(const ScDBData& rData)
609 : {
610 0 : ScSubTotalParam aParam;
611 0 : rData.GetSubTotalParam(aParam);
612 :
613 0 : size_t nCount = 0;
614 0 : for (; nCount < MAXSUBTOTAL; ++nCount)
615 : {
616 0 : if (!aParam.bGroupActive[nCount])
617 0 : break;
618 : }
619 :
620 0 : if (!nCount)
621 0 : return;
622 :
623 0 : if (!aParam.bIncludePattern)
624 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
625 :
626 0 : if (aParam.bPagebreak)
627 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TRUE);
628 :
629 0 : if (aParam.bCaseSens)
630 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
631 :
632 0 : SvXMLElementExport aElemSTRs(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, true, true);
633 :
634 0 : if (aParam.bDoSort)
635 : {
636 0 : if (!aParam.bAscending)
637 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
638 :
639 0 : if (aParam.bUserDef)
640 : {
641 0 : OUStringBuffer aBuf;
642 0 : aBuf.appendAscii(SC_USERLIST);
643 0 : aBuf.append(static_cast<sal_Int32>(aParam.nUserIndex));
644 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, aBuf.makeStringAndClear());
645 : }
646 0 : SvXMLElementExport aElemSGs(mrExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, true, true);
647 : }
648 :
649 0 : for (size_t i = 0; i < MAXSUBTOTAL; ++i)
650 : {
651 0 : if (!aParam.bGroupActive[i])
652 : // We're done!
653 0 : break;
654 :
655 0 : sal_Int32 nFieldCol = static_cast<sal_Int32>(aParam.nField[i]);
656 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, OUString::number(nFieldCol));
657 0 : SvXMLElementExport aElemSTR(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, true, true);
658 :
659 0 : for (SCCOL j = 0, n = aParam.nSubTotals[i]; j < n; ++j)
660 : {
661 0 : sal_Int32 nCol = static_cast<sal_Int32>(aParam.pSubTotals[i][j]);
662 0 : ScSubTotalFunc eFunc = aParam.pFunctions[i][j];
663 :
664 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(nCol));
665 0 : OUString aFuncStr;
666 0 : ScXMLConverter::GetStringFromFunction(aFuncStr, eFunc);
667 0 : mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, aFuncStr);
668 :
669 0 : SvXMLElementExport aElemSTF(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, true, true);
670 0 : }
671 0 : }
672 : }
673 : };
674 :
675 : }
676 :
677 18 : void ScXMLExportDatabaseRanges::WriteDatabaseRanges()
678 : {
679 : typedef ::std::map<SCTAB, const ScDBData*> SheetLocalDBs;
680 :
681 18 : pDoc = rExport.GetDocument();
682 18 : if (!pDoc)
683 18 : return;
684 :
685 : // Get sheet-local anonymous ranges.
686 18 : SCTAB nTabCount = pDoc->GetTableCount();
687 18 : SheetLocalDBs aSheetDBs;
688 40 : for (SCTAB i = 0; i < nTabCount; ++i)
689 : {
690 22 : const ScDBData* p = pDoc->GetAnonymousDBData(i);
691 22 : if (p)
692 0 : aSheetDBs.insert(SheetLocalDBs::value_type(i, p));
693 : }
694 :
695 18 : bool bHasRanges = !aSheetDBs.empty();
696 :
697 : // See if we have global ranges.
698 18 : ScDBCollection* pDBCollection = pDoc->GetDBCollection();
699 18 : if (pDBCollection)
700 : {
701 18 : if (!pDBCollection->getNamedDBs().empty() || !pDBCollection->getAnonDBs().empty())
702 0 : bHasRanges = true;
703 : }
704 :
705 18 : if (!bHasRanges)
706 : // No ranges to export. Bail out.
707 18 : return;
708 :
709 0 : SvXMLElementExport aElemDRs(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, true, true);
710 :
711 0 : WriteDatabaseRange func(rExport, pDoc);
712 :
713 0 : if (pDBCollection)
714 : {
715 : // Write global named ranges.
716 0 : func.setRangeType(ScDBCollection::GlobalNamed);
717 0 : const ScDBCollection::NamedDBs& rNamedDBs = pDBCollection->getNamedDBs();
718 0 : ::std::for_each(rNamedDBs.begin(), rNamedDBs.end(), func);
719 :
720 : // Add global anonymous DB ranges.
721 0 : func.setRangeType(ScDBCollection::GlobalAnonymous);
722 0 : const ScDBCollection::AnonDBs& rAnonDBs = pDBCollection->getAnonDBs();
723 0 : ::std::for_each(rAnonDBs.begin(), rAnonDBs.end(), func);
724 : }
725 :
726 : // Write sheet-local ranges.
727 0 : func.setRangeType(ScDBCollection::SheetAnonymous);
728 0 : ::std::for_each(aSheetDBs.begin(), aSheetDBs.end(), func);
729 : }
730 :
731 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|