1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27
28
29 // INCLUDE ---------------------------------------------------------------
30 #include "XMLExportDatabaseRanges.hxx"
31 #include <xmloff/xmltoken.hxx>
32 #include <xmloff/xmlnmspe.hxx>
33 #include <xmloff/xmluconv.hxx>
34 #include <xmloff/nmspmap.hxx>
35 #include "xmlexprt.hxx"
36 #include "XMLExportIterator.hxx"
37 #include "XMLConverter.hxx"
38 #include "unonames.hxx"
39 #include "dbcolect.hxx"
40 #include "document.hxx"
41 #include "globstr.hrc"
42 #include "XMLExportSharedData.hxx"
43 #include "rangeutl.hxx"
44 #include <com/sun/star/sheet/DataImportMode.hpp>
45 #include <com/sun/star/table/TableSortField.hpp>
46 #include <com/sun/star/table/TableSortFieldType.hpp>
47 #include <com/sun/star/sheet/XSubTotalField.hpp>
48 #include <com/sun/star/sheet/XDatabaseRanges.hpp>
49 #include <com/sun/star/sheet/XDatabaseRange.hpp>
50 #include <com/sun/star/table/TableOrientation.hpp>
51 #include <tools/debug.hxx>
52 #include <comphelper/extract.hxx>
53
54 //! not found in unonames.hxx
55 #define SC_USERLIST "UserList"
56 #define SC_SORTASCENDING "SortAscending"
57 #define SC_ENABLEUSERSORTLIST "EnableUserSortList"
58 #define SC_USERSORTLISTINDEX "UserSortListIndex"
59
60 using namespace com::sun::star;
61 using namespace xmloff::token;
62
ScXMLExportDatabaseRanges(ScXMLExport & rTempExport)63 ScXMLExportDatabaseRanges::ScXMLExportDatabaseRanges(ScXMLExport& rTempExport)
64 : rExport(rTempExport),
65 pDoc( NULL )
66 {
67 }
68
~ScXMLExportDatabaseRanges()69 ScXMLExportDatabaseRanges::~ScXMLExportDatabaseRanges()
70 {
71 }
72
GetEmptyDatabaseRanges()73 ScMyEmptyDatabaseRangesContainer ScXMLExportDatabaseRanges::GetEmptyDatabaseRanges()
74 {
75 ScMyEmptyDatabaseRangesContainer aSkipRanges;
76 if (rExport.GetModel().is())
77 {
78 sal_Int32 nSkipRangesCount = 0;
79 uno::Reference <beans::XPropertySet> xPropertySet (rExport.GetModel(), uno::UNO_QUERY);
80 if (xPropertySet.is())
81 {
82 uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
83 rExport.CheckAttrList();
84 if (xDatabaseRanges.is())
85 {
86 uno::Sequence <rtl::OUString> aRanges(xDatabaseRanges->getElementNames());
87 sal_Int32 nDatabaseRangesCount = aRanges.getLength();
88 for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i)
89 {
90 rtl::OUString sDatabaseRangeName(aRanges[i]);
91 uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
92 if (xDatabaseRange.is())
93 {
94 uno::Reference <beans::XPropertySet> xDatabaseRangePropertySet (xDatabaseRange, uno::UNO_QUERY);
95 if (xDatabaseRangePropertySet.is() &&
96 ::cppu::any2bool(xDatabaseRangePropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)))))
97 {
98 uno::Sequence <beans::PropertyValue> aImportProperties(xDatabaseRange->getImportDescriptor());
99 sal_Int32 nLength = aImportProperties.getLength();
100 sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
101 for (sal_Int32 j = 0; j < nLength; ++j)
102 if (aImportProperties[j].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE)))
103 aImportProperties[j].Value >>= nSourceType;
104 if (nSourceType != sheet::DataImportMode_NONE)
105 {
106 table::CellRangeAddress aArea = xDatabaseRange->getDataArea();
107 aSkipRanges.AddNewEmptyDatabaseRange(aArea);
108
109 // #105276#; set last row/column so default styles are collected
110 rExport.GetSharedData()->SetLastColumn(aArea.Sheet, aArea.EndColumn);
111 rExport.GetSharedData()->SetLastRow(aArea.Sheet, aArea.EndRow);
112 }
113 }
114 }
115 }
116 if (nSkipRangesCount > 1)
117 aSkipRanges.Sort();
118 }
119 }
120 }
121 return aSkipRanges;
122 }
123
WriteImportDescriptor(const uno::Sequence<beans::PropertyValue> aImportDescriptor)124 void ScXMLExportDatabaseRanges::WriteImportDescriptor(const uno::Sequence <beans::PropertyValue> aImportDescriptor)
125 {
126 sal_Int32 nProperties = aImportDescriptor.getLength();
127 rtl::OUString sDatabaseName;
128 rtl::OUString sConRes;
129 rtl::OUString sSourceObject;
130 sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
131 sal_Bool bNative = sal_False;
132 for (sal_Int16 i = 0; i < nProperties; ++i)
133 {
134 if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_DBNAME)))
135 aImportDescriptor[i].Value >>= sDatabaseName;
136 else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONRES)))
137 aImportDescriptor[i].Value >>= sConRes;
138 else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCOBJ)))
139 aImportDescriptor[i].Value >>= sSourceObject;
140 else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE)))
141 aImportDescriptor[i].Value >>= nSourceType;
142 else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISNATIVE)))
143 bNative = ::cppu::any2bool(aImportDescriptor[i].Value);
144 }
145 switch (nSourceType)
146 {
147 case sheet::DataImportMode_NONE : break;
148 case sheet::DataImportMode_QUERY :
149 {
150 if (sDatabaseName.getLength())
151 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
152 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, sSourceObject);
153 SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, sal_True, sal_True);
154 if (sConRes.getLength())
155 {
156 rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
157 SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
158 }
159 rExport.CheckAttrList();
160 }
161 break;
162 case sheet::DataImportMode_TABLE :
163 {
164 if (sDatabaseName.getLength())
165 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
166 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sSourceObject);
167 SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, sal_True, sal_True);
168 if (sConRes.getLength())
169 {
170 rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
171 SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
172 }
173 rExport.CheckAttrList();
174 }
175 break;
176 case sheet::DataImportMode_SQL :
177 {
178 if (sDatabaseName.getLength())
179 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
180 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, sSourceObject);
181 if (!bNative)
182 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
183 SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, sal_True, sal_True);
184 if (sConRes.getLength())
185 {
186 rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
187 SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
188 }
189 rExport.CheckAttrList();
190 }
191 break;
192 default:
193 {
194 // added to avoid warnings
195 }
196 }
197 }
198
getOperatorXML(const long aFilterOperator,const sal_Bool bUseRegularExpressions) const199 rtl::OUString ScXMLExportDatabaseRanges::getOperatorXML(const long aFilterOperator, const sal_Bool bUseRegularExpressions) const
200 {
201 switch (aFilterOperator)
202 {
203 case sheet::FilterOperator2::EQUAL :
204 {
205 if (bUseRegularExpressions)
206 return GetXMLToken(XML_MATCH);
207 else
208 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
209 }
210 case sheet::FilterOperator2::NOT_EQUAL :
211 {
212 if (bUseRegularExpressions)
213 return GetXMLToken(XML_NOMATCH);
214 else
215 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
216 }
217 case sheet::FilterOperator2::BOTTOM_PERCENT :
218 return GetXMLToken(XML_BOTTOM_PERCENT);
219 case sheet::FilterOperator2::BOTTOM_VALUES :
220 return GetXMLToken(XML_BOTTOM_VALUES);
221 case sheet::FilterOperator2::EMPTY :
222 return GetXMLToken(XML_EMPTY);
223 case sheet::FilterOperator2::GREATER :
224 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
225 case sheet::FilterOperator2::GREATER_EQUAL :
226 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
227 case sheet::FilterOperator2::LESS :
228 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
229 case sheet::FilterOperator2::LESS_EQUAL :
230 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
231 case sheet::FilterOperator2::NOT_EMPTY :
232 return GetXMLToken(XML_NOEMPTY);
233 case sheet::FilterOperator2::TOP_PERCENT :
234 return GetXMLToken(XML_TOP_PERCENT);
235 case sheet::FilterOperator2::TOP_VALUES :
236 return GetXMLToken(XML_TOP_VALUES);
237 case sheet::FilterOperator2::CONTAINS :
238 return GetXMLToken(XML_CONTAINS);
239 case sheet::FilterOperator2::DOES_NOT_CONTAIN :
240 return GetXMLToken(XML_DOES_NOT_CONTAIN);
241 case sheet::FilterOperator2::BEGINS_WITH :
242 return GetXMLToken(XML_BEGINS_WITH);
243 case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH :
244 return GetXMLToken(XML_DOES_NOT_BEGIN_WITH);
245 case sheet::FilterOperator2::ENDS_WITH :
246 return GetXMLToken(XML_ENDS_WITH);
247 case sheet::FilterOperator2::DOES_NOT_END_WITH :
248 return GetXMLToken(XML_DOES_NOT_END_WITH);
249 default:
250 {
251 // added to avoid warnings
252 }
253 }
254 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
255 }
256
WriteCondition(const sheet::TableFilterField2 & aFilterField,sal_Bool bIsCaseSensitive,sal_Bool bUseRegularExpressions)257 void ScXMLExportDatabaseRanges::WriteCondition(const sheet::TableFilterField2& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions)
258 {
259 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aFilterField.Field));
260 if (bIsCaseSensitive)
261 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
262 if (aFilterField.IsNumeric)
263 {
264 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
265 rtl::OUStringBuffer sBuffer;
266 rExport.GetMM100UnitConverter().convertDouble(sBuffer, aFilterField.NumericValue);
267 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, sBuffer.makeStringAndClear());
268 }
269 else
270 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aFilterField.StringValue);
271 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(aFilterField.Operator, bUseRegularExpressions));
272 SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True);
273 }
274
WriteFilterDescriptor(const uno::Reference<sheet::XSheetFilterDescriptor2> & xSheetFilterDescriptor,const rtl::OUString sDatabaseRangeName)275 void ScXMLExportDatabaseRanges::WriteFilterDescriptor(const uno::Reference <sheet::XSheetFilterDescriptor2>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName)
276 {
277 uno::Sequence< sheet::TableFilterField2 > aTableFilterFields( xSheetFilterDescriptor->getFilterFields2() );
278 sal_Int32 nTableFilterFields = aTableFilterFields.getLength();
279 if (nTableFilterFields > 0)
280 {
281 uno::Reference <beans::XPropertySet> xPropertySet (xSheetFilterDescriptor, uno::UNO_QUERY);
282 if (xPropertySet.is())
283 {
284 if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COPYOUT)))))
285 {
286 table::CellAddress aOutputPosition;
287 if (xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OUTPOS))) >>= aOutputPosition)
288 {
289 rtl::OUString sOUCellAddress;
290 ScRangeStringConverter::GetStringFromAddress( sOUCellAddress, aOutputPosition, pDoc, ::formula::FormulaGrammar::CONV_OOO );
291 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUCellAddress);
292 }
293 }
294 ScDBCollection* pDBCollection = pDoc->GetDBCollection();
295 sal_uInt16 nIndex;
296 pDBCollection->SearchName(sDatabaseRangeName, nIndex);
297 ScDBData* pDBData = (*pDBCollection)[nIndex];
298 ScRange aAdvSource;
299 if (pDBData->GetAdvancedQuerySource(aAdvSource))
300 {
301 rtl::OUString sOUCellAddress;
302 ScRangeStringConverter::GetStringFromRange( sOUCellAddress, aAdvSource, pDoc, ::formula::FormulaGrammar::CONV_OOO );
303 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, sOUCellAddress);
304 }
305
306 if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SKIPDUP)))))
307 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
308 SvXMLElementExport aElemF(rExport, XML_NAMESPACE_TABLE, XML_FILTER, sal_True, sal_True);
309 rExport.CheckAttrList();
310 sal_Bool bIsCaseSensitive = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE))));
311 sal_Bool bUseRegularExpressions = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_USEREGEX))));
312 sal_Bool bAnd = sal_False;
313 sal_Bool bOr = sal_False;
314 for (sal_Int32 i = 1; i < nTableFilterFields; ++i)
315 {
316 if (aTableFilterFields[i].Connection == sheet::FilterConnection_AND)
317 bAnd = sal_True;
318 else
319 bOr = sal_True;
320 }
321 if (bOr && !bAnd)
322 {
323 SvXMLElementExport aElemOr(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
324 for (sal_Int32 i = 0; i < nTableFilterFields; ++i)
325 {
326 WriteCondition(aTableFilterFields[i], bIsCaseSensitive, bUseRegularExpressions);
327 }
328 }
329 else if (bAnd && !bOr)
330 {
331 SvXMLElementExport aElemAnd(rExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, sal_True, sal_True);
332 for (sal_Int32 i = 0; i < nTableFilterFields; ++i)
333 {
334 WriteCondition(aTableFilterFields[i], bIsCaseSensitive, bUseRegularExpressions);
335 }
336 }
337 else if (nTableFilterFields == 1)
338 {
339 WriteCondition(aTableFilterFields[0], bIsCaseSensitive, bUseRegularExpressions);
340 }
341 else
342 {
343 SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
344 sheet::TableFilterField2 aPrevFilterField = aTableFilterFields[0];
345 sheet::FilterConnection aConnection = aTableFilterFields[1].Connection;
346 sal_Bool bOpenAndElement;
347 rtl::OUString aName = rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND));
348 if (aConnection == sheet::FilterConnection_AND)
349 {
350 rExport.StartElement( aName, sal_True);
351 bOpenAndElement = sal_True;
352 }
353 else
354 bOpenAndElement = sal_False;
355 for (sal_Int32 i = 1; i < nTableFilterFields; ++i)
356 {
357 if (aConnection != aTableFilterFields[i].Connection)
358 {
359 aConnection = aTableFilterFields[i].Connection;
360 if (aTableFilterFields[i].Connection == sheet::FilterConnection_AND)
361 {
362 rExport.StartElement( aName, sal_True );
363 bOpenAndElement = sal_True;
364 WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
365 aPrevFilterField = aTableFilterFields[i];
366 if (i == nTableFilterFields - 1)
367 {
368 WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
369 rExport.EndElement(aName, sal_True);
370 bOpenAndElement = sal_False;
371 }
372 }
373 else
374 {
375 WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
376 aPrevFilterField = aTableFilterFields[i];
377 if (bOpenAndElement)
378 {
379 rExport.EndElement(aName, sal_True);
380 bOpenAndElement = sal_False;
381 }
382 if (i == nTableFilterFields - 1)
383 {
384 WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
385 }
386 }
387 }
388 else
389 {
390 WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
391 aPrevFilterField = aTableFilterFields[i];
392 if (i == nTableFilterFields - 1)
393 WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
394 }
395 }
396 if(bOpenAndElement)
397 rExport.EndElement(aName, sal_True);
398 }
399 }
400 }
401 }
402
WriteSortDescriptor(const uno::Sequence<beans::PropertyValue> aSortProperties)403 void ScXMLExportDatabaseRanges::WriteSortDescriptor(const uno::Sequence <beans::PropertyValue> aSortProperties)
404 {
405 uno::Sequence <table::TableSortField> aSortFields;
406 sal_Bool bBindFormatsToContent (sal_True);
407 sal_Bool bCopyOutputData (sal_False);
408 // sal_Bool bIsCaseSensitive (sal_False);
409 sal_Bool bIsUserListEnabled (sal_False);
410 table::CellAddress aOutputPosition;
411 sal_Int32 nUserListIndex = 0;
412 sal_Int32 nProperties = aSortProperties.getLength();
413 sal_Int32 i;
414 for (i = 0; i < nProperties; ++i)
415 {
416 if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_BINDFMT) == 0)
417 bBindFormatsToContent = ::cppu::any2bool(aSortProperties[i].Value);
418 else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COPYOUT) == 0)
419 bCopyOutputData = ::cppu::any2bool(aSortProperties[i].Value);
420 // no longer supported
421 /* else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_ISCASE) == 0)
422 bIsCaseSensitive = ::cppu::any2bool(aSortProperties[i].Value);*/
423 else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_ISULIST) == 0)
424 bIsUserListEnabled = ::cppu::any2bool(aSortProperties[i].Value);
425 else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_OUTPOS) == 0)
426 aSortProperties[i].Value >>= aOutputPosition;
427 else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_UINDEX) == 0)
428 aSortProperties[i].Value >>= nUserListIndex;
429 else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_SORTFLD) == 0)
430 aSortProperties[i].Value >>= aSortFields;
431 // no longer supported
432 /* else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COLLLOC) == 0)
433 aSortProperties[i].Value >>= aCollatorLocale;
434 else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COLLALG) == 0)
435 aSortProperties[i].Value >>= sCollatorAlgorithm;*/
436 }
437 sal_Int32 nSortFields = aSortFields.getLength();
438 if (nSortFields > 0)
439 {
440 if (!bBindFormatsToContent)
441 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
442 if (bCopyOutputData)
443 {
444 rtl::OUString sOUCellAddress;
445 ScRangeStringConverter::GetStringFromAddress( sOUCellAddress, aOutputPosition, pDoc, ::formula::FormulaGrammar::CONV_OOO );
446 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUCellAddress);
447 }
448 // no longer supported
449 // if (bIsCaseSensitive)
450 // rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
451
452 if (aSortFields[0].IsCaseSensitive)
453 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
454 #ifdef DBG_UTIL
455 sal_Bool bCaseSensitive(aSortFields[0].IsCaseSensitive);
456 for (i = 1; i < nSortFields; ++i)
457 {
458 DBG_ASSERT(bCaseSensitive == aSortFields[i].IsCaseSensitive, "seems that it is now possible to have every field case sensitive");
459 }
460 #endif
461 // no longer supported
462 /* if (aCollatorLocale.Language.getLength())
463 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aCollatorLocale.Language);
464 if (aCollatorLocale.Country.getLength())
465 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aCollatorLocale.Country);
466 if (sCollatorAlgorithm.getLength())
467 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, sCollatorAlgorithm);*/
468 if (aSortFields[0].CollatorLocale.Language.getLength())
469 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aSortFields[0].CollatorLocale.Language);
470 if (aSortFields[0].CollatorLocale.Country.getLength())
471 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aSortFields[0].CollatorLocale.Country);
472 if (aSortFields[0].CollatorAlgorithm.getLength())
473 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aSortFields[0].CollatorAlgorithm);
474 #ifdef DBG_UTIL
475 rtl::OUString sLanguage(aSortFields[0].CollatorLocale.Language);
476 rtl::OUString sCountry(aSortFields[0].CollatorLocale.Country);
477 rtl::OUString sAlgorithm(aSortFields[0].CollatorAlgorithm);
478 for (i = 1; i < nSortFields; ++i)
479 {
480 DBG_ASSERT(sLanguage == aSortFields[i].CollatorLocale.Language, "seems that it is now possible to have every field localized");
481 DBG_ASSERT(sCountry == aSortFields[i].CollatorLocale.Country, "seems that it is now possible to have every field localized");
482 DBG_ASSERT(sAlgorithm == aSortFields[i].CollatorAlgorithm, "seems that it is now possible to have every field localized");
483 }
484 #endif
485 SvXMLElementExport aElemS(rExport, XML_NAMESPACE_TABLE, XML_SORT, sal_True, sal_True);
486 rExport.CheckAttrList();
487 for (i = 0; i < nSortFields; ++i)
488 {
489 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aSortFields[i].Field));
490 if (!aSortFields[i].IsAscending)
491 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
492 if (!bIsUserListEnabled)
493 {
494 switch (aSortFields[i].FieldType)
495 {
496 case table::TableSortFieldType_ALPHANUMERIC :
497 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TEXT);
498 break;
499 case table::TableSortFieldType_AUTOMATIC :
500 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_AUTOMATIC);
501 break;
502 case table::TableSortFieldType_NUMERIC :
503 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
504 break;
505 default:
506 {
507 // added to avoid warnings
508 }
509 }
510 }
511 else
512 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERLIST)) + rtl::OUString::valueOf(nUserListIndex));
513 SvXMLElementExport aElemSb(rExport, XML_NAMESPACE_TABLE, XML_SORT_BY, sal_True, sal_True);
514 rExport.CheckAttrList();
515 }
516 }
517 }
518
WriteSubTotalDescriptor(const com::sun::star::uno::Reference<com::sun::star::sheet::XSubTotalDescriptor> xSubTotalDescriptor,const rtl::OUString sDatabaseRangeName)519 void ScXMLExportDatabaseRanges::WriteSubTotalDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSubTotalDescriptor> xSubTotalDescriptor, const rtl::OUString sDatabaseRangeName)
520 {
521 uno::Reference <container::XIndexAccess> xIndexAccess (xSubTotalDescriptor, uno::UNO_QUERY);
522 if (xIndexAccess.is())
523 {
524 sal_Int32 nSubTotalFields = xIndexAccess->getCount();
525 if (nSubTotalFields > 0)
526 {
527 uno::Reference <beans::XPropertySet> xPropertySet (xSubTotalDescriptor, uno::UNO_QUERY);
528 // sal_Bool bEnableUserSortList = sal_False;
529 // sal_Bool bSortAscending = sal_True;
530 // sal_Int32 nUserSortListIndex = 0;
531 if (xPropertySet.is())
532 {
533 if (!::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BINDFMT)))))
534 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
535 if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INSBRK)))))
536 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TRUE);
537 if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)))))
538 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
539 // bSortAscending = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SORTASCENDING))));
540 // if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ENABLEUSERSORTLIST)))))
541 // xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERSORTLISTINDEX))) >>= nUserSortListIndex;
542 }
543 SvXMLElementExport aElemSTRs(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, sal_True, sal_True);
544 rExport.CheckAttrList();
545 {
546 ScDBCollection* pDBCollection = pDoc->GetDBCollection();
547 sal_uInt16 nIndex;
548 pDBCollection->SearchName(sDatabaseRangeName, nIndex);
549 ScDBData* pDBData = (*pDBCollection)[nIndex];
550 ScSubTotalParam aSubTotalParam;
551 pDBData->GetSubTotalParam(aSubTotalParam);
552 if (aSubTotalParam.bDoSort)
553 {
554 if (!aSubTotalParam.bAscending)
555 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
556 if (aSubTotalParam.bUserDef)
557 {
558 rtl::OUString sUserList(RTL_CONSTASCII_USTRINGPARAM(SC_USERLIST));
559 sUserList += rtl::OUString::valueOf(aSubTotalParam.nUserIndex);
560 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, sUserList);
561 }
562 SvXMLElementExport aElemSGs(rExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, sal_True, sal_True);
563 rExport.CheckAttrList();
564 }
565 }
566 for (sal_Int32 i = 0; i < nSubTotalFields; ++i)
567 {
568 uno::Reference <sheet::XSubTotalField> xSubTotalField(xIndexAccess->getByIndex(i), uno::UNO_QUERY);
569 if (xSubTotalField.is())
570 {
571 sal_Int32 nGroupColumn = xSubTotalField->getGroupColumn();
572 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, rtl::OUString::valueOf(nGroupColumn));
573 SvXMLElementExport aElemSTR(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, sal_True, sal_True);
574 rExport.CheckAttrList();
575 uno::Sequence <sheet::SubTotalColumn> aSubTotalColumns = xSubTotalField->getSubTotalColumns();
576 sal_Int32 nSubTotalColumns = aSubTotalColumns.getLength();
577 for (sal_Int32 j = 0; j < nSubTotalColumns; ++j)
578 {
579 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aSubTotalColumns[j].Column));
580 rtl::OUString sFunction;
581 ScXMLConverter::GetStringFromFunction( sFunction, aSubTotalColumns[j].Function );
582 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
583 SvXMLElementExport aElemSTF(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, sal_True, sal_True);
584 rExport.CheckAttrList();
585 }
586 }
587 }
588 }
589 }
590 }
591
WriteDatabaseRanges(const com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheetDocument> & xSpreadDoc)592 void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc)
593 {
594 pDoc = rExport.GetDocument();
595 if (pDoc)
596 {
597 uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
598 if (xPropertySet.is())
599 {
600 uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
601 rExport.CheckAttrList();
602 if (xDatabaseRanges.is())
603 {
604 uno::Sequence <rtl::OUString> aRanges(xDatabaseRanges->getElementNames());
605 sal_Int32 nDatabaseRangesCount = aRanges.getLength();
606 if (nDatabaseRangesCount > 0)
607 {
608 SvXMLElementExport aElemDRs(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, sal_True, sal_True);
609 for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i)
610 {
611 rtl::OUString sDatabaseRangeName(aRanges[i]);
612 uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
613 if (xDatabaseRange.is())
614 {
615 rtl::OUString sOUUnbenannt (ScGlobal::GetRscString(STR_DB_NONAME));
616 if (sOUUnbenannt != sDatabaseRangeName)
617 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sDatabaseRangeName);
618 table::CellRangeAddress aRangeAddress(xDatabaseRange->getDataArea());
619 rtl::OUString sOUAddress;
620 ScRangeStringConverter::GetStringFromRange( sOUAddress, aRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO );
621 rExport.AddAttribute (XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUAddress);
622 ScDBCollection* pDBCollection = pDoc->GetDBCollection();
623 sal_uInt16 nIndex;
624 pDBCollection->SearchName(sDatabaseRangeName, nIndex);
625 ScDBData* pDBData = (*pDBCollection)[nIndex];
626 if (pDBData->HasImportSelection())
627 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TRUE);
628 if (pDBData->HasAutoFilter())
629 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TRUE);
630 uno::Reference <beans::XPropertySet> xPropertySetDatabaseRange (xDatabaseRange, uno::UNO_QUERY);
631 if (xPropertySetDatabaseRange.is())
632 {
633 if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_KEEPFORM)))))
634 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TRUE);
635 if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_MOVCELLS)))))
636 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_FALSE);
637 if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)))))
638 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_FALSE);
639 }
640
641 uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
642 xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY );
643 uno::Sequence <beans::PropertyValue> aSortProperties(xDatabaseRange->getSortDescriptor());
644 if (xSheetFilterDescriptor.is())
645 {
646 uno::Reference <beans::XPropertySet> xFilterProperties (xSheetFilterDescriptor, uno::UNO_QUERY);
647 if (xFilterProperties.is())
648 {
649 if (!::cppu::any2bool(xFilterProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONTHDR)))))
650 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_FALSE);
651
652 // #98317#; there is no orientation on the filter
653 /* table::TableOrientation eFilterOrient(table::TableOrientation_ROWS);
654 if (::cppu::any2bool(xFilterProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT)))))
655 eFilterOrient = table::TableOrientation_ROWS;*/
656
657 sal_Bool bSortColumns(sal_True);
658 sal_Bool bFound(sal_False);
659 sal_Int32 nProperty(0);
660 while (!bFound && (nProperty < aSortProperties.getLength()))
661 {
662 if (aSortProperties[nProperty].Name.compareToAscii(SC_UNONAME_ISSORTCOLUMNS) == 0)
663 {
664 bSortColumns = ::cppu::any2bool(aSortProperties[nProperty].Value);
665 bFound = sal_True;
666 }
667 else
668 ++nProperty;
669 }
670
671 if (bSortColumns)
672 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_COLUMN);
673 }
674 }
675 sal_Int32 nRefresh( pDBData->GetRefreshDelay() );
676 if( nRefresh )
677 {
678 rtl::OUStringBuffer sBuffer;
679 SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 );
680 rExport.AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() );
681 }
682 SvXMLElementExport aElemDR(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, sal_True, sal_True);
683 rExport.CheckAttrList();
684 WriteImportDescriptor(xDatabaseRange->getImportDescriptor());
685 if (xSheetFilterDescriptor.is())
686 WriteFilterDescriptor(xSheetFilterDescriptor, sDatabaseRangeName);
687 WriteSortDescriptor(aSortProperties);
688 WriteSubTotalDescriptor(xDatabaseRange->getSubTotalDescriptor(), sDatabaseRangeName);
689 }
690 }
691 }
692 }
693 }
694 }
695 }
696