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