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 "XMLExportDataPilot.hxx"
31 #include <xmloff/xmltoken.hxx>
32 #include <xmloff/xmlnmspe.hxx>
33 #include <xmloff/xmluconv.hxx>
34 #include <xmloff/nmspmap.hxx>
35 #include <rtl/math.hxx>
36 #include "xmlexprt.hxx"
37 #include "XMLConverter.hxx"
38 #include "document.hxx"
39 #include "dpobject.hxx"
40 #include "dociter.hxx"
41 #include "attrib.hxx"
42 #include "patattr.hxx"
43 #include "scitems.hxx"
44 #include "dpsave.hxx"
45 #include "dpshttab.hxx"
46 #include "dpsdbtab.hxx"
47 #include "dpdimsave.hxx"
48 #include "dpgroup.hxx"
49 #include "rangeutl.hxx"
50 #include <com/sun/star/sheet/DataImportMode.hpp>
51 #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
52 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
53 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
54 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
55 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
56 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
57 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
58 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
59 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
60 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
61
62 using namespace com::sun::star;
63 using namespace xmloff::token;
64 using ::rtl::OUString;
65
ScXMLExportDataPilot(ScXMLExport & rTempExport)66 ScXMLExportDataPilot::ScXMLExportDataPilot(ScXMLExport& rTempExport)
67 : rExport(rTempExport),
68 pDoc( NULL )
69 {
70 }
71
~ScXMLExportDataPilot()72 ScXMLExportDataPilot::~ScXMLExportDataPilot()
73 {
74 }
75
getDPOperatorXML(const ScQueryOp aFilterOperator,const sal_Bool bUseRegularExpressions,const sal_Bool bIsString,const double dVal,const String & sVal) const76 rtl::OUString ScXMLExportDataPilot::getDPOperatorXML(const ScQueryOp aFilterOperator, const sal_Bool bUseRegularExpressions,
77 const sal_Bool bIsString, const double dVal, const String& sVal) const
78 {
79 switch (aFilterOperator)
80 {
81 case SC_EQUAL :
82 {
83 rtl::OUString sReturn;
84 if (bUseRegularExpressions)
85 sReturn = GetXMLToken(XML_MATCH);
86 else
87 sReturn = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
88
89 if (!bIsString && sVal == EMPTY_STRING)
90 {
91 if (dVal == SC_EMPTYFIELDS)
92 sReturn = GetXMLToken(XML_EMPTY);
93 else if (dVal == SC_NONEMPTYFIELDS)
94 sReturn = GetXMLToken(XML_NOEMPTY);
95 }
96
97 return sReturn;
98 }
99 case SC_NOT_EQUAL :
100 {
101 if (bUseRegularExpressions)
102 return GetXMLToken(XML_NOMATCH);
103 else
104 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
105 }
106 case SC_BOTPERC :
107 return GetXMLToken(XML_BOTTOM_PERCENT);
108 case SC_BOTVAL :
109 return GetXMLToken(XML_BOTTOM_VALUES);
110 case SC_GREATER :
111 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
112 case SC_GREATER_EQUAL :
113 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
114 case SC_LESS :
115 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
116 case SC_LESS_EQUAL :
117 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
118 case SC_TOPPERC :
119 return GetXMLToken(XML_TOP_PERCENT);
120 case SC_TOPVAL :
121 return GetXMLToken(XML_TOP_VALUES);
122 default:
123 DBG_ERROR("This FilterOperator is not supported.");
124 }
125 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
126 }
127
WriteDPCondition(const ScQueryEntry & aQueryEntry,sal_Bool bIsCaseSensitive,sal_Bool bUseRegularExpressions)128 void ScXMLExportDataPilot::WriteDPCondition(const ScQueryEntry& aQueryEntry, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions)
129 {
130 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(sal_Int32(aQueryEntry.nField)));
131 if (bIsCaseSensitive)
132 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
133 if (aQueryEntry.bQueryByString)
134 {
135 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, *aQueryEntry.pStr);
136 }
137 else
138 {
139 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
140 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rtl::OUString(*aQueryEntry.pStr));
141 }
142 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getDPOperatorXML(aQueryEntry.eOp, bUseRegularExpressions,
143 aQueryEntry.bQueryByString, aQueryEntry.nVal, *aQueryEntry.pStr));
144 SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True);
145 }
146
WriteDPFilter(const ScQueryParam & aQueryParam)147 void ScXMLExportDataPilot::WriteDPFilter(const ScQueryParam& aQueryParam)
148 {
149 SCSIZE nQueryEntryCount = aQueryParam.GetEntryCount();
150 if (nQueryEntryCount > 0)
151 {
152 sal_Bool bAnd(sal_False);
153 sal_Bool bOr(sal_False);
154 sal_Bool bHasEntries(sal_True);
155 SCSIZE nEntries(0);
156 SCSIZE j;
157
158 for ( j = 0; (j < nQueryEntryCount) && bHasEntries; ++j)
159 {
160 ScQueryEntry aEntry = aQueryParam.GetEntry(j);
161 if (aEntry.bDoQuery)
162 {
163 if (nEntries > 0)
164 {
165 if (aEntry.eConnect == SC_AND)
166 bAnd = sal_True;
167 else
168 bOr = sal_True;
169 }
170 ++nEntries;
171 }
172 else
173 bHasEntries = sal_False;
174 }
175 nQueryEntryCount = nEntries;
176 if (nQueryEntryCount)
177 {
178 // There is never a target range in a data pilot.
179 /* if (!aQueryParam.bInplace)
180 {
181 ScAddress aTargetAddress(aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab);
182 rtl::OUString sAddress;
183 ScXMLConverter::GetStringFromAddress( sAddress, aTargetAddress, pDoc );
184 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sAddress);
185 }*/
186 if(!((aQueryParam.nCol1 == aQueryParam.nCol2) && (aQueryParam.nRow1 == aQueryParam.nRow2) &&
187 (static_cast<SCCOLROW>(aQueryParam.nCol1) == static_cast<SCCOLROW>(aQueryParam.nRow1)) &&
188 (aQueryParam.nCol1 == 0) && (aQueryParam.nTab == SCTAB_MAX)))
189 {
190 ScRange aConditionRange(aQueryParam.nCol1, aQueryParam.nRow1, aQueryParam.nTab,
191 aQueryParam.nCol2, aQueryParam.nRow2, aQueryParam.nTab);
192 rtl::OUString sConditionRange;
193 ScRangeStringConverter::GetStringFromRange( sConditionRange, aConditionRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
194 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, sConditionRange);
195 }
196 if (!aQueryParam.bDuplicate)
197 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
198 SvXMLElementExport aElemDPF(rExport, XML_NAMESPACE_TABLE, XML_FILTER, sal_True, sal_True);
199 rExport.CheckAttrList();
200 if (nQueryEntryCount == 1)
201 {
202 WriteDPCondition(aQueryParam.GetEntry(0), aQueryParam.bCaseSens, aQueryParam.bRegExp);
203 }
204 else if (bOr && !bAnd)
205 {
206 SvXMLElementExport aElemOr(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
207 for (j = 0; j < nQueryEntryCount; ++j)
208 {
209 WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.bRegExp);
210 }
211 }
212 else if (bAnd && !bOr)
213 {
214 SvXMLElementExport aElemAnd(rExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, sal_True, sal_True);
215 for (j = 0; j < nQueryEntryCount; ++j)
216 {
217 WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.bRegExp);
218 }
219 }
220 else
221 {
222 SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
223 ScQueryEntry aPrevFilterField(aQueryParam.GetEntry(0));
224 ScQueryConnect aConnection = aQueryParam.GetEntry(1).eConnect;
225 sal_Bool bOpenAndElement;
226 rtl::OUString aName(rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND)));
227 if (aConnection == SC_AND)
228 {
229 rExport.StartElement( aName, sal_True );
230 bOpenAndElement = sal_True;
231 }
232 else
233 bOpenAndElement = sal_False;
234 for (j = 1; j < nQueryEntryCount; ++j)
235 {
236 if (aConnection != aQueryParam.GetEntry(j).eConnect)
237 {
238 aConnection = aQueryParam.GetEntry(j).eConnect;
239 if (aQueryParam.GetEntry(j).eConnect == SC_AND)
240 {
241 rExport.StartElement( aName, sal_True );
242 bOpenAndElement = sal_True;
243 WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
244 aPrevFilterField = aQueryParam.GetEntry(j);
245 if (j == nQueryEntryCount - 1)
246 {
247 WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
248 rExport.EndElement(aName, sal_True);
249 bOpenAndElement = sal_False;
250 }
251 }
252 else
253 {
254 WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
255 aPrevFilterField = aQueryParam.GetEntry(j);
256 if (bOpenAndElement)
257 {
258 rExport.EndElement(aName, sal_True);
259 bOpenAndElement = sal_False;
260 }
261 if (j == nQueryEntryCount - 1)
262 {
263 WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
264 }
265 }
266 }
267 else
268 {
269 WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
270 aPrevFilterField = aQueryParam.GetEntry(j);
271 if (j == nQueryEntryCount - 1)
272 WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
273 }
274 }
275 }
276 }
277 }
278 }
279
WriteFieldReference(ScDPSaveDimension * pDim)280 void ScXMLExportDataPilot::WriteFieldReference(ScDPSaveDimension* pDim)
281 {
282 const sheet::DataPilotFieldReference* pRef = pDim->GetReferenceValue();
283 if (pRef)
284 {
285 rtl::OUString sValueStr;
286 switch (pRef->ReferenceType)
287 {
288 case sheet::DataPilotFieldReferenceType::NONE :
289 sValueStr = GetXMLToken(XML_NONE);
290 break;
291 case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE :
292 sValueStr = GetXMLToken(XML_MEMBER_DIFFERENCE);
293 break;
294 case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE :
295 sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE);
296 break;
297 case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE :
298 sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE_DIFFERENCE);
299 break;
300 case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL :
301 sValueStr = GetXMLToken(XML_RUNNING_TOTAL);
302 break;
303 case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE :
304 sValueStr = GetXMLToken(XML_ROW_PERCENTAGE);
305 break;
306 case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE :
307 sValueStr = GetXMLToken(XML_COLUMN_PERCENTAGE);
308 break;
309 case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE :
310 sValueStr = GetXMLToken(XML_TOTAL_PERCENTAGE);
311 break;
312 case sheet::DataPilotFieldReferenceType::INDEX :
313 sValueStr = GetXMLToken(XML_INDEX);
314 break;
315 }
316 if (sValueStr.getLength())
317 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, sValueStr);
318
319 if (pRef->ReferenceField.getLength())
320 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NAME, pRef->ReferenceField);
321
322 if (pRef->ReferenceItemType == sheet::DataPilotFieldReferenceItemType::NAMED)
323 {
324 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_TYPE, XML_NAMED);
325 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_NAME, pRef->ReferenceItemName);
326 }
327 else
328 {
329 sValueStr = rtl::OUString();
330 switch(pRef->ReferenceItemType)
331 {
332 case sheet::DataPilotFieldReferenceItemType::PREVIOUS :
333 sValueStr = GetXMLToken(XML_PREVIOUS);
334 break;
335 case sheet::DataPilotFieldReferenceItemType::NEXT :
336 sValueStr = GetXMLToken(XML_NEXT);
337 break;
338 }
339 if (sValueStr.getLength())
340 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_TYPE, sValueStr);
341 }
342 SvXMLElementExport aElemDPFR(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD_REFERENCE, sal_True, sal_True);
343 }
344 rExport.CheckAttrList();
345 }
346
WriteSortInfo(ScDPSaveDimension * pDim)347 void ScXMLExportDataPilot::WriteSortInfo(ScDPSaveDimension* pDim)
348 {
349 const sheet::DataPilotFieldSortInfo* pSortInfo = pDim->GetSortInfo();
350 if (pSortInfo)
351 {
352 if (pSortInfo->IsAscending)
353 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_ASCENDING);
354 else
355 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
356
357 rtl::OUString sValueStr;
358 switch (pSortInfo->Mode)
359 {
360 case sheet::DataPilotFieldSortMode::NONE:
361 sValueStr = GetXMLToken(XML_NONE);
362 break;
363 case sheet::DataPilotFieldSortMode::MANUAL:
364 sValueStr = GetXMLToken(XML_MANUAL);
365 break;
366 case sheet::DataPilotFieldSortMode::NAME:
367 sValueStr = GetXMLToken(XML_NAME);
368 break;
369 case sheet::DataPilotFieldSortMode::DATA:
370 sValueStr = GetXMLToken(XML_DATA);
371 if (pSortInfo->Field.getLength())
372 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pSortInfo->Field);
373 break;
374 }
375 if (sValueStr.getLength())
376 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SORT_MODE, sValueStr);
377 SvXMLElementExport aElemDPLSI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SORT_INFO, sal_True, sal_True);
378 }
379 }
380
WriteAutoShowInfo(ScDPSaveDimension * pDim)381 void ScXMLExportDataPilot::WriteAutoShowInfo(ScDPSaveDimension* pDim)
382 {
383 const sheet::DataPilotFieldAutoShowInfo* pAutoInfo = pDim->GetAutoShowInfo();
384 if (pAutoInfo)
385 {
386 if (pAutoInfo->IsEnabled)
387 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ENABLED, XML_TRUE);
388 else
389 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ENABLED, XML_FALSE);
390
391 rtl::OUString sValueStr;
392 switch (pAutoInfo->ShowItemsMode)
393 {
394 case sheet::DataPilotFieldShowItemsMode::FROM_TOP:
395 sValueStr = GetXMLToken(XML_FROM_TOP);
396 break;
397 case sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM:
398 sValueStr = GetXMLToken(XML_FROM_BOTTOM);
399 break;
400 }
401 if (sValueStr.getLength())
402 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_MEMBER_MODE, sValueStr);
403
404 rtl::OUStringBuffer sBuffer;
405 SvXMLUnitConverter::convertNumber(sBuffer, pAutoInfo->ItemCount);
406 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_COUNT, sBuffer.makeStringAndClear());
407
408 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pAutoInfo->DataField);
409
410 SvXMLElementExport aElemDPLAI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_DISPLAY_INFO, sal_True, sal_True);
411 }
412 }
413
WriteLayoutInfo(ScDPSaveDimension * pDim)414 void ScXMLExportDataPilot::WriteLayoutInfo(ScDPSaveDimension* pDim)
415 {
416 const sheet::DataPilotFieldLayoutInfo* pLayoutInfo = pDim->GetLayoutInfo();
417 if (pLayoutInfo)
418 {
419 if (pLayoutInfo->AddEmptyLines)
420 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ADD_EMPTY_LINES, XML_TRUE);
421 else
422 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ADD_EMPTY_LINES, XML_FALSE);
423
424 rtl::OUString sValueStr;
425 switch (pLayoutInfo->LayoutMode)
426 {
427 case sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT:
428 sValueStr = GetXMLToken(XML_TABULAR_LAYOUT);
429 break;
430 case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP:
431 sValueStr = GetXMLToken(XML_OUTLINE_SUBTOTALS_TOP);
432 break;
433 case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM:
434 sValueStr = GetXMLToken(XML_OUTLINE_SUBTOTALS_BOTTOM);
435 break;
436 }
437 if (sValueStr.getLength())
438 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LAYOUT_MODE, sValueStr);
439 SvXMLElementExport aElemDPLLI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LAYOUT_INFO, sal_True, sal_True);
440 }
441 }
442
WriteSubTotals(ScDPSaveDimension * pDim)443 void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
444 {
445 using sheet::GeneralFunction;
446
447 sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
448 const OUString* pLayoutName = NULL;
449 if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
450 // Export display names only for 1.2 extended or later.
451 pLayoutName = pDim->GetSubtotalName();
452
453 if (nSubTotalCount > 0)
454 {
455 SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True);
456 rExport.CheckAttrList();
457 for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
458 {
459 rtl::OUString sFunction;
460 GeneralFunction nFunc = static_cast<GeneralFunction>(pDim->GetSubTotalFunc(nSubTotal));
461 ScXMLConverter::GetStringFromFunction( sFunction, nFunc);
462 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
463 if (pLayoutName && nFunc == sheet::GeneralFunction_AUTO)
464 rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
465 SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True);
466 }
467 }
468 }
469
WriteMembers(ScDPSaveDimension * pDim)470 void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim)
471 {
472 const ScDPSaveDimension::MemberList &rMembers = pDim->GetMembers();
473 if (rMembers.begin() != rMembers.end())
474 {
475 SvXMLElementExport aElemDPMs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBERS, sal_True, sal_True);
476 rExport.CheckAttrList();
477 for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++)
478 {
479 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName()));
480
481 if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
482 {
483 // Export display names only for ODF 1.2 extended or later.
484 const OUString* pLayoutName = (*i)->GetLayoutName();
485 if (pLayoutName)
486 rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
487 }
488
489 rtl::OUStringBuffer sBuffer;
490 SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible());
491 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
492 SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetShowDetails());
493 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, sBuffer.makeStringAndClear());
494 SvXMLElementExport aElemDPM(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, sal_True, sal_True);
495 rExport.CheckAttrList();
496 }
497 }
498 }
499
WriteLevels(ScDPSaveDimension * pDim)500 void ScXMLExportDataPilot::WriteLevels(ScDPSaveDimension* pDim)
501 {
502 // #i114202# GetShowEmpty is only valid if HasShowEmpty is true.
503 if (pDim->HasShowEmpty())
504 {
505 rtl::OUStringBuffer sBuffer;
506 SvXMLUnitConverter::convertBool(sBuffer, pDim->GetShowEmpty());
507 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, sBuffer.makeStringAndClear());
508 }
509 SvXMLElementExport aElemDPL(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LEVEL, sal_True, sal_True);
510
511 WriteSubTotals(pDim);
512 WriteMembers(pDim);
513 WriteAutoShowInfo(pDim);
514 WriteSortInfo(pDim);
515 WriteLayoutInfo(pDim);
516 rExport.CheckAttrList();
517 }
518
WriteDatePart(sal_Int32 nPart)519 void ScXMLExportDataPilot::WriteDatePart(sal_Int32 nPart)
520 {
521 switch(nPart)
522 {
523 case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS :
524 {
525 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_SECONDS);
526 }
527 break;
528 case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES :
529 {
530 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_MINUTES);
531 }
532 break;
533 case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS :
534 {
535 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_HOURS);
536 }
537 break;
538 case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS :
539 {
540 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_DAYS);
541 }
542 break;
543 case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS :
544 {
545 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_MONTHS);
546 }
547 break;
548 case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS :
549 {
550 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_QUARTERS);
551 }
552 break;
553 case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS :
554 {
555 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_YEARS);
556 }
557 break;
558 }
559 }
560
WriteNumGroupInfo(const ScDPNumGroupInfo & rGroupInfo)561 void ScXMLExportDataPilot::WriteNumGroupInfo(const ScDPNumGroupInfo& rGroupInfo)
562 {
563 DBG_ASSERT(rGroupInfo.Enable, "group dimension should be enabled");
564 if (rGroupInfo.DateValues)
565 {
566 if (rGroupInfo.AutoStart)
567 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, XML_AUTO);
568 else
569 {
570 rtl::OUStringBuffer sDate;
571 rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.Start);
572 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, sDate.makeStringAndClear());
573 }
574 if (rGroupInfo.AutoEnd)
575 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, XML_AUTO);
576 else
577 {
578 rtl::OUStringBuffer sDate;
579 rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.End);
580 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, sDate.makeStringAndClear());
581 }
582 }
583 else
584 {
585 if (rGroupInfo.AutoStart)
586 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START, XML_AUTO);
587 else
588 {
589 rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.Start,
590 rtl_math_StringFormat_Automatic,
591 rtl_math_DecimalPlaces_Max, '.', sal_True));
592 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START, sValue);
593 }
594 if (rGroupInfo.AutoEnd)
595 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END, XML_AUTO);
596 else
597 {
598 rtl::OUStringBuffer sDate;
599 rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.End,
600 rtl_math_StringFormat_Automatic,
601 rtl_math_DecimalPlaces_Max, '.', sal_True));
602 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END, sValue);
603 }
604 }
605 rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.Step,
606 rtl_math_StringFormat_Automatic,
607 rtl_math_DecimalPlaces_Max, '.', sal_True));
608 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STEP, sValue);
609 }
610
WriteGroupDimAttributes(const ScDPSaveGroupDimension * pGroupDim)611 void ScXMLExportDataPilot::WriteGroupDimAttributes(const ScDPSaveGroupDimension* pGroupDim)
612 {
613 if (pGroupDim)
614 {
615 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_GROUP_FIELD, XML_TRUE);
616 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, pGroupDim->GetSourceDimName());
617 if (pGroupDim->GetDatePart())
618 {
619 WriteDatePart(pGroupDim->GetDatePart());
620 WriteNumGroupInfo(pGroupDim->GetDateInfo());
621 }
622 }
623 }
624
WriteNumGroupDim(const ScDPSaveNumGroupDimension * pNumGroupDim)625 void ScXMLExportDataPilot::WriteNumGroupDim(const ScDPSaveNumGroupDimension* pNumGroupDim)
626 {
627 if (pNumGroupDim)
628 {
629 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_GROUP_FIELD, XML_TRUE);
630 if (pNumGroupDim->GetDatePart())
631 {
632 WriteDatePart(pNumGroupDim->GetDatePart());
633 WriteNumGroupInfo(pNumGroupDim->GetDateInfo());
634 }
635 else
636 {
637 WriteNumGroupInfo(pNumGroupDim->GetInfo());
638 }
639 }
640 }
641
WriteGroupDimElements(ScDPSaveDimension * pDim,const ScDPDimensionSaveData * pDimData)642 void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
643 {
644 const ScDPSaveGroupDimension* pGroupDim = NULL;
645 const ScDPSaveNumGroupDimension* pNumGroupDim = NULL;
646 if (pDimData)
647 {
648 pGroupDim = pDimData->GetNamedGroupDim(pDim->GetName());
649 WriteGroupDimAttributes(pGroupDim);
650 pNumGroupDim = pDimData->GetNumGroupDim(pDim->GetName());
651 WriteNumGroupDim(pNumGroupDim);
652
653 DBG_ASSERT((!pGroupDim || !pNumGroupDim), "there should be no NumGroup and Group at the same field");
654 }
655 if (pGroupDim || pNumGroupDim)
656 {
657 SvXMLElementExport aElemDPGs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUPS, sal_True, sal_True);
658 if (pGroupDim)
659 {
660 if (!pGroupDim->GetDatePart())
661 {
662 sal_Int32 nCount = pGroupDim->GetGroupCount();
663 for (sal_Int32 i = 0; i < nCount; ++i)
664 {
665 const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( i );
666 if (pGroup)
667 {
668 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, pGroup->GetGroupName());
669 SvXMLElementExport aElemDPG(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUP, sal_True, sal_True);
670 sal_Int32 nElemCount = pGroup->GetElementCount();
671 for(sal_Int32 j = 0; j < nElemCount; ++j)
672 {
673 const String* pElem = pGroup->GetElementByIndex( j );
674 if (pElem)
675 {
676 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, *pElem);
677 SvXMLElementExport aElemDPM(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, sal_True, sal_True);
678 }
679 }
680 }
681 }
682 }
683 }
684 }
685 }
686
WriteDimension(ScDPSaveDimension * pDim,const ScDPDimensionSaveData * pDimData)687 void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
688 {
689 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName()));
690 if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
691 {
692 // Export display names only for ODF 1.2 extended or later.
693 const OUString* pLayoutName = pDim->GetLayoutName();
694 if (pLayoutName)
695 rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
696 }
697
698 if (pDim->IsDataLayout())
699 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE);
700 rtl::OUString sValueStr;
701 ScXMLConverter::GetStringFromOrientation( sValueStr,
702 (sheet::DataPilotFieldOrientation) pDim->GetOrientation() );
703 if( sValueStr.getLength() )
704 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, sValueStr );
705 if (pDim->GetOrientation() == sheet::DataPilotFieldOrientation_PAGE)
706 if (pDim->HasCurrentPage())
707 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, pDim->GetCurrentPage());
708 if (pDim->GetUsedHierarchy() != 1)
709 {
710 rtl::OUStringBuffer sBuffer;
711 SvXMLUnitConverter::convertNumber(sBuffer, pDim->GetUsedHierarchy());
712 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, sBuffer.makeStringAndClear());
713 }
714 ScXMLConverter::GetStringFromFunction( sValueStr,
715 (sheet::GeneralFunction) pDim->GetFunction() );
716 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sValueStr);
717
718 SvXMLElementExport aElemDPF(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD, sal_True, sal_True);
719 WriteFieldReference(pDim);
720 WriteLevels(pDim);
721 if( pDim->GetOrientation() != sheet::DataPilotFieldOrientation_DATA )
722 WriteGroupDimElements(pDim, pDimData);
723 }
724
WriteDimensions(ScDPSaveData * pDPSave)725 void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave)
726 {
727 List aDimensions = pDPSave->GetDimensions();
728 sal_Int32 nDimCount = aDimensions.Count();
729 for (sal_Int32 nDim = 0; nDim < nDimCount; nDim++)
730 {
731 WriteDimension((ScDPSaveDimension*)aDimensions.GetObject(nDim), pDPSave->GetExistingDimensionData());
732 }
733 }
734
WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient,bool bVisible,const OUString * pGrandTotal)735 void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal)
736 {
737 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE);
738 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient);
739 if (pGrandTotal)
740 rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal);
741
742 SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE_EXT, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True);
743 }
744
WriteDataPilots(const uno::Reference<sheet::XSpreadsheetDocument> &)745 void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreadsheetDocument>& /* xSpreadDoc */)
746 {
747 pDoc = rExport.GetDocument();
748 if (pDoc)
749 {
750 ScDPCollection* pDPs = pDoc->GetDPCollection();
751 if (pDPs)
752 {
753 sal_Int16 nDPCount = pDPs->GetCount();
754 if (nDPCount > 0)
755 {
756 SvXMLElementExport aElemDPs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLES, sal_True, sal_True);
757 rExport.CheckAttrList();
758 for (sal_Int16 i = 0; i < nDPCount; ++i)
759 {
760 ScDPSaveData* pDPSave = (*pDPs)[i]->GetSaveData();
761 if (pDPSave)
762 {
763 ScRange aOutRange((*pDPs)[i]->GetOutRange());
764 rtl::OUString sTargetRangeAddress;
765 ScRangeStringConverter::GetStringFromRange( sTargetRangeAddress, aOutRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
766 ScDocAttrIterator aAttrItr(pDoc, aOutRange.aStart.Tab(),
767 aOutRange.aStart.Col(), aOutRange.aStart.Row(),
768 aOutRange.aEnd.Col(), aOutRange.aEnd.Row());
769 SCCOL nCol;
770 SCROW nRow1, nRow2;
771 rtl::OUString sOUButtonList;
772 const ScPatternAttr* pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
773 while (pAttr)
774 {
775 ScMergeFlagAttr& rItem = (ScMergeFlagAttr&)pAttr->GetItem(ATTR_MERGE_FLAG);
776 if (rItem.HasButton())
777 {
778 for (SCROW nButtonRow = nRow1; nButtonRow <= nRow2; ++nButtonRow)
779 {
780 ScAddress aButtonAddr(nCol, nButtonRow, aOutRange.aStart.Tab());
781 ScRangeStringConverter::GetStringFromAddress(
782 sOUButtonList, aButtonAddr, pDoc, ::formula::FormulaGrammar::CONV_OOO, ' ', sal_True );
783 }
784 }
785 pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
786 }
787 rtl::OUString sName((*pDPs)[i]->GetName());
788 rtl::OUString sApplicationData((*pDPs)[i]->GetTag());
789 sal_Bool bRowGrand = pDPSave->GetRowGrand();
790 sal_Bool bColumnGrand = pDPSave->GetColumnGrand();
791 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sName);
792 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_APPLICATION_DATA, sApplicationData);
793 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sTargetRangeAddress);
794 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BUTTONS, sOUButtonList);
795 if (!(bRowGrand && bColumnGrand))
796 {
797 if (bRowGrand)
798 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_ROW);
799 else if (bColumnGrand)
800 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_COLUMN);
801 else
802 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_NONE);
803 }
804 if (pDPSave->GetIgnoreEmptyRows())
805 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IGNORE_EMPTY_ROWS, XML_TRUE);
806 if (pDPSave->GetRepeatIfEmpty())
807 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IDENTIFY_CATEGORIES, XML_TRUE);
808 if (!pDPSave->GetFilterButton())
809 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_FILTER_BUTTON, XML_FALSE);
810 if (!pDPSave->GetDrillDown())
811 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_FALSE);
812 SvXMLElementExport aElemDP(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, sal_True, sal_True);
813
814 // grand total elements.
815
816 const OUString* pGrandTotalName = pDPSave->GetGrandTotalName();
817 if (pGrandTotalName && rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
818 {
819 // Use the new data-pilot-grand-total element.
820 if (bRowGrand && bColumnGrand)
821 {
822 WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
823 }
824 else
825 {
826 WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
827 WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
828 }
829 }
830
831 rExport.CheckAttrList();
832 if ((*pDPs)[i]->IsSheetData())
833 {
834 const ScSheetSourceDesc* pSheetSource = (*pDPs)[i]->GetSheetDesc();
835 rtl::OUString sCellRangeAddress;
836 ScRangeStringConverter::GetStringFromRange( sCellRangeAddress, pSheetSource->aSourceRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
837 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sCellRangeAddress);
838 SvXMLElementExport aElemSCR(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, sal_True, sal_True);
839 rExport.CheckAttrList();
840 WriteDPFilter(pSheetSource->aQueryParam);
841 }
842 else if ((*pDPs)[i]->IsImportData())
843 {
844 const ScImportSourceDesc* pImpSource = (*pDPs)[i]->GetImportSourceDesc();
845 switch (pImpSource->nType)
846 {
847 case sheet::DataImportMode_NONE : break;
848 case sheet::DataImportMode_QUERY :
849 {
850 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
851 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, rtl::OUString(pImpSource->aObject));
852 SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, sal_True, sal_True);
853 rExport.CheckAttrList();
854 }
855 break;
856 case sheet::DataImportMode_TABLE :
857 {
858 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
859 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, rtl::OUString(pImpSource->aObject));
860 SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, sal_True, sal_True);
861 rExport.CheckAttrList();
862 }
863 break;
864 case sheet::DataImportMode_SQL :
865 {
866 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
867 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, rtl::OUString(pImpSource->aObject));
868 if (!pImpSource->bNative)
869 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
870 SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, sal_True, sal_True);
871 rExport.CheckAttrList();
872 }
873 break;
874 }
875 }
876 else if ((*pDPs)[i]->IsServiceData())
877 {
878 const ScDPServiceDesc* pServSource = (*pDPs)[i]->GetDPServiceDesc();
879 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString(pServSource->aServiceName));
880 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_NAME, rtl::OUString(pServSource->aParSource));
881 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OBJECT_NAME, rtl::OUString(pServSource->aParName));
882 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USER_NAME, rtl::OUString(pServSource->aParUser));
883 // #i111754# leave out password attribute as long as DataPilotSource doesn't specify the content
884 // rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PASSWORD, rtl::OUString(pServSource->aParPass));
885 SvXMLElementExport aElemSD(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, sal_True, sal_True);
886 rExport.CheckAttrList();
887 }
888 WriteDimensions(pDPSave);
889 }
890 }
891 }
892 }
893 }
894 }
895