LibreOffice Module sc (master)  1
XMLExportDataPilot.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "XMLExportDataPilot.hxx"
21 #include <xmloff/xmltoken.hxx>
22 #include <xmloff/xmlnamespace.hxx>
23 #include <xmloff/xmluconv.hxx>
24 #include <xmloff/namespacemap.hxx>
25 #include <sax/tools/converter.hxx>
26 #include <rtl/math.hxx>
27 #include <osl/diagnose.h>
28 #include "xmlexprt.hxx"
29 #include "XMLConverter.hxx"
30 #include <document.hxx>
31 #include <dpobject.hxx>
32 #include <dociter.hxx>
33 #include <attrib.hxx>
34 #include <patattr.hxx>
35 #include <scitems.hxx>
36 #include <dpsave.hxx>
37 #include <dpshttab.hxx>
38 #include <dpsdbtab.hxx>
39 #include <dpdimsave.hxx>
40 #include <dputil.hxx>
41 #include <rangeutl.hxx>
42 #include <queryentry.hxx>
43 #include <com/sun/star/sheet/DataImportMode.hpp>
44 #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
45 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
46 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
47 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
48 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
49 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
50 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
51 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
52 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
53 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
54 #include <com/sun/star/sheet/GeneralFunction2.hpp>
55 
56 using namespace com::sun::star;
57 using namespace xmloff::token;
58 
60  : rExport(rTempExport),
61  pDoc( nullptr )
62 {
63 }
64 
66  const ScQueryOp aFilterOperator, const utl::SearchParam::SearchType eSearchType)
67 {
68  switch (aFilterOperator)
69  {
70  case SC_EQUAL :
71  {
72  if (eSearchType == utl::SearchParam::SearchType::Regexp)
73  return GetXMLToken(XML_MATCH);
74  else
75  return "=";
76  }
77  case SC_NOT_EQUAL :
78  {
79  if (eSearchType == utl::SearchParam::SearchType::Regexp)
80  return GetXMLToken(XML_NOMATCH);
81  else
82  return "!=";
83  }
84  case SC_BOTPERC :
86  case SC_BOTVAL :
88  case SC_GREATER :
89  return ">";
90  case SC_GREATER_EQUAL :
91  return ">=";
92  case SC_LESS :
93  return "<";
94  case SC_LESS_EQUAL :
95  return "<=";
96  case SC_TOPPERC :
98  case SC_TOPVAL :
100  default:
101  OSL_FAIL("This FilterOperator is not supported.");
102  }
103  return "=";
104 }
105 
106 void ScXMLExportDataPilot::WriteDPCondition(const ScQueryEntry& aQueryEntry, bool bIsCaseSensitive,
107  utl::SearchParam::SearchType eSearchType)
108 {
109  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(aQueryEntry.nField));
110  if (bIsCaseSensitive)
112  const ScQueryEntry::Item& rItem = aQueryEntry.GetQueryItem();
113  OUString aQueryStr = rItem.maString.getString();
114  if (rItem.meType == ScQueryEntry::ByString)
115  {
117  }
118  else
119  {
122  }
123 
124  if (aQueryEntry.IsQueryByEmpty())
125  {
127  }
128  else if (aQueryEntry.IsQueryByNonEmpty())
129  {
131  }
132  else
135  getDPOperatorXML(aQueryEntry.eOp, eSearchType));
136 
138 }
139 
141 {
142  SCSIZE nQueryEntryCount = aQueryParam.GetEntryCount();
143  if (nQueryEntryCount <= 0)
144  return;
145 
146  bool bAnd(false);
147  bool bOr(false);
148  bool bHasEntries(true);
149  SCSIZE nEntries(0);
150  SCSIZE j;
151 
152  for ( j = 0; (j < nQueryEntryCount) && bHasEntries; ++j)
153  {
154  ScQueryEntry aEntry = aQueryParam.GetEntry(j);
155  if (aEntry.bDoQuery)
156  {
157  if (nEntries > 0)
158  {
159  if (aEntry.eConnect == SC_AND)
160  bAnd = true;
161  else
162  bOr = true;
163  }
164  ++nEntries;
165  }
166  else
167  bHasEntries = false;
168  }
169  nQueryEntryCount = nEntries;
170  if (!nQueryEntryCount)
171  return;
172 
173  if(!((aQueryParam.nCol1 == aQueryParam.nCol2) && (aQueryParam.nRow1 == aQueryParam.nRow2) &&
174  (static_cast<SCCOLROW>(aQueryParam.nCol1) == static_cast<SCCOLROW>(aQueryParam.nRow1)) &&
175  (aQueryParam.nCol1 == 0) && (aQueryParam.nTab == SCTAB_MAX)))
176  {
177  ScRange aConditionRange(aQueryParam.nCol1, aQueryParam.nRow1, aQueryParam.nTab,
178  aQueryParam.nCol2, aQueryParam.nRow2, aQueryParam.nTab);
179  OUString sConditionRange;
181  if (!sConditionRange.isEmpty())
183  }
184  if (!aQueryParam.bDuplicate)
188  if (nQueryEntryCount == 1)
189  {
190  WriteDPCondition(aQueryParam.GetEntry(0), aQueryParam.bCaseSens, aQueryParam.eSearchType);
191  }
192  else if (bOr && !bAnd)
193  {
195  for (j = 0; j < nQueryEntryCount; ++j)
196  {
197  WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.eSearchType);
198  }
199  }
200  else if (bAnd && !bOr)
201  {
203  for (j = 0; j < nQueryEntryCount; ++j)
204  {
205  WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.eSearchType);
206  }
207  }
208  else
209  {
211  ScQueryEntry aPrevFilterField(aQueryParam.GetEntry(0));
212  ScQueryConnect aConnection = aQueryParam.GetEntry(1).eConnect;
213  bool bOpenAndElement;
215  if (aConnection == SC_AND)
216  {
217  rExport.StartElement( aName, true );
218  bOpenAndElement = true;
219  }
220  else
221  bOpenAndElement = false;
222  for (j = 1; j < nQueryEntryCount; ++j)
223  {
224  if (aConnection != aQueryParam.GetEntry(j).eConnect)
225  {
226  aConnection = aQueryParam.GetEntry(j).eConnect;
227  if (aQueryParam.GetEntry(j).eConnect == SC_AND)
228  {
229  rExport.StartElement( aName, true );
230  bOpenAndElement = true;
231  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
232  aPrevFilterField = aQueryParam.GetEntry(j);
233  if (j == nQueryEntryCount - 1)
234  {
235  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
236  rExport.EndElement(aName, true);
237  bOpenAndElement = false;
238  }
239  }
240  else
241  {
242  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
243  aPrevFilterField = aQueryParam.GetEntry(j);
244  if (bOpenAndElement)
245  {
246  rExport.EndElement(aName, true);
247  bOpenAndElement = false;
248  }
249  if (j == nQueryEntryCount - 1)
250  {
251  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
252  }
253  }
254  }
255  else
256  {
257  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
258  aPrevFilterField = aQueryParam.GetEntry(j);
259  if (j == nQueryEntryCount - 1)
260  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
261  }
262  }
263  }
264 }
265 
267 {
268  const sheet::DataPilotFieldReference* pRef = pDim->GetReferenceValue();
269  if (pRef)
270  {
271  OUString sValueStr;
272  switch (pRef->ReferenceType)
273  {
275  sValueStr = GetXMLToken(XML_NONE);
276  break;
277  case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE :
278  sValueStr = GetXMLToken(XML_MEMBER_DIFFERENCE);
279  break;
280  case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE :
281  sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE);
282  break;
283  case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE :
285  break;
286  case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL :
287  sValueStr = GetXMLToken(XML_RUNNING_TOTAL);
288  break;
289  case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE :
290  sValueStr = GetXMLToken(XML_ROW_PERCENTAGE);
291  break;
292  case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE :
293  sValueStr = GetXMLToken(XML_COLUMN_PERCENTAGE);
294  break;
295  case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE :
296  sValueStr = GetXMLToken(XML_TOTAL_PERCENTAGE);
297  break;
298  case sheet::DataPilotFieldReferenceType::INDEX :
299  sValueStr = GetXMLToken(XML_INDEX);
300  break;
301  }
302  if (!sValueStr.isEmpty())
304 
305  if (!pRef->ReferenceField.isEmpty())
306  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NAME, pRef->ReferenceField);
307 
308  if (pRef->ReferenceItemType == sheet::DataPilotFieldReferenceItemType::NAMED)
309  {
311  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_NAME, pRef->ReferenceItemName);
312  }
313  else
314  {
315  sValueStr.clear();
316  switch(pRef->ReferenceItemType)
317  {
318  case sheet::DataPilotFieldReferenceItemType::PREVIOUS :
319  sValueStr = GetXMLToken(XML_PREVIOUS);
320  break;
321  case sheet::DataPilotFieldReferenceItemType::NEXT :
322  sValueStr = GetXMLToken(XML_NEXT);
323  break;
324  }
325  if (!sValueStr.isEmpty())
327  }
329  }
331 }
332 
334 {
335  const sheet::DataPilotFieldSortInfo* pSortInfo = pDim->GetSortInfo();
336  if (!pSortInfo)
337  return;
338 
339  if (pSortInfo->IsAscending)
341  else
343 
344  OUString sValueStr;
345  switch (pSortInfo->Mode)
346  {
348  sValueStr = GetXMLToken(XML_NONE);
349  break;
350  case sheet::DataPilotFieldSortMode::MANUAL:
351  sValueStr = GetXMLToken(XML_MANUAL);
352  break;
353  case sheet::DataPilotFieldSortMode::NAME:
354  sValueStr = GetXMLToken(XML_NAME);
355  break;
356  case sheet::DataPilotFieldSortMode::DATA:
357  sValueStr = GetXMLToken(XML_DATA);
358  if (!pSortInfo->Field.isEmpty())
360  break;
361  }
362  if (!sValueStr.isEmpty())
365 }
366 
368 {
369  const sheet::DataPilotFieldAutoShowInfo* pAutoInfo = pDim->GetAutoShowInfo();
370  if (!pAutoInfo)
371  return;
372 
373  if (pAutoInfo->IsEnabled)
375  else
377 
378  OUString sValueStr;
379  switch (pAutoInfo->ShowItemsMode)
380  {
381  case sheet::DataPilotFieldShowItemsMode::FROM_TOP:
382  sValueStr = GetXMLToken(XML_FROM_TOP);
383  break;
384  case sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM:
385  sValueStr = GetXMLToken(XML_FROM_BOTTOM);
386  break;
387  }
388  if (!sValueStr.isEmpty())
390 
391  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_COUNT, OUString::number(pAutoInfo->ItemCount));
392 
393  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pAutoInfo->DataField);
394 
396 }
397 
399 {
400  const sheet::DataPilotFieldLayoutInfo* pLayoutInfo = pDim->GetLayoutInfo();
401  if (!pLayoutInfo)
402  return;
403 
404  if (pLayoutInfo->AddEmptyLines)
406  else
408 
409  OUString sValueStr;
410  switch (pLayoutInfo->LayoutMode)
411  {
412  case sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT:
413  sValueStr = GetXMLToken(XML_TABULAR_LAYOUT);
414  break;
415  case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP:
417  break;
418  case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM:
420  break;
421  }
422  if (!sValueStr.isEmpty())
425 }
426 
428 {
429  sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
430  std::optional<OUString> pLayoutName;
432  // Export display names only for 1.2 extended or later.
433  pLayoutName = pDim->GetSubtotalName();
434 
435  if (nSubTotalCount <= 0)
436  return;
437 
440  for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
441  {
442  sal_Int16 nFunc = static_cast<sal_Int16>(pDim->GetSubTotalFunc(nSubTotal));
443  OUString sFunction = ScXMLConverter::GetStringFromFunction(nFunc);
445  if (pLayoutName && nFunc == sheet::GeneralFunction2::AUTO)
448  }
449 }
450 
452 {
453  const ScDPSaveDimension::MemberList &rMembers = pDim->GetMembers();
454  if (rMembers.empty())
455  return;
456 
459  for (const auto& rpMember : rMembers)
460  {
461  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rpMember->GetName());
462 
464  {
465  // Export display names only for ODF 1.2 extended or later.
466  const std::optional<OUString> & pLayoutName = rpMember->GetLayoutName();
467  if (pLayoutName)
469  }
470 
471  OUStringBuffer sBuffer;
472  ::sax::Converter::convertBool(sBuffer, rpMember->GetIsVisible());
473  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
474  ::sax::Converter::convertBool(sBuffer, rpMember->GetShowDetails());
475  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, sBuffer.makeStringAndClear());
478  }
479 }
480 
482 {
483  // #i114202# GetShowEmpty is only valid if HasShowEmpty is true.
484  if (pDim->HasShowEmpty())
485  {
486  OUStringBuffer sBuffer;
488  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, sBuffer.makeStringAndClear());
489  }
491  {
492  OUStringBuffer sBuffer;
494  rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_REPEAT_ITEM_LABELS, sBuffer.makeStringAndClear());
495  }
497 
498  WriteSubTotals(pDim);
499  WriteMembers(pDim);
500  WriteAutoShowInfo(pDim);
501  WriteSortInfo(pDim);
502  WriteLayoutInfo(pDim);
504 }
505 
507 {
508  switch(nPart)
509  {
510  case css::sheet::DataPilotFieldGroupBy::SECONDS :
511  {
513  }
514  break;
515  case css::sheet::DataPilotFieldGroupBy::MINUTES :
516  {
518  }
519  break;
520  case css::sheet::DataPilotFieldGroupBy::HOURS :
521  {
523  }
524  break;
525  case css::sheet::DataPilotFieldGroupBy::DAYS :
526  {
528  }
529  break;
530  case css::sheet::DataPilotFieldGroupBy::MONTHS :
531  {
533  }
534  break;
535  case css::sheet::DataPilotFieldGroupBy::QUARTERS :
536  {
538  }
539  break;
540  case css::sheet::DataPilotFieldGroupBy::YEARS :
541  {
543  }
544  break;
545  }
546 }
547 
549 {
550  OSL_ENSURE(rGroupInfo.mbEnable, "group dimension should be enabled");
551  if (rGroupInfo.mbDateValues)
552  {
553  if (rGroupInfo.mbAutoStart)
555  else
556  {
557  OUStringBuffer sDate;
559  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, sDate.makeStringAndClear());
560  }
561  if (rGroupInfo.mbAutoEnd)
563  else
564  {
565  OUStringBuffer sDate;
566  rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.mfEnd);
567  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, sDate.makeStringAndClear());
568  }
569  }
570  else
571  {
572  if (rGroupInfo.mbAutoStart)
574  else
575  {
576  OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.mfStart,
577  rtl_math_StringFormat_Automatic,
578  rtl_math_DecimalPlaces_Max, '.', true));
580  }
581  if (rGroupInfo.mbAutoEnd)
583  else
584  {
585  OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.mfEnd,
586  rtl_math_StringFormat_Automatic,
587  rtl_math_DecimalPlaces_Max, '.', true));
589  }
590  }
591  OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.mfStep,
592  rtl_math_StringFormat_Automatic,
593  rtl_math_DecimalPlaces_Max, '.', true));
595 }
596 
598 {
599  if (pGroupDim)
600  {
601  OUString aSrcFieldName = ScDPUtil::getSourceDimensionName(pGroupDim->GetSourceDimName());
603  if (pGroupDim->GetDatePart())
604  {
605  WriteDatePart(pGroupDim->GetDatePart());
606  WriteNumGroupInfo(pGroupDim->GetDateInfo());
607  }
608  }
609 }
610 
612 {
613  if (pNumGroupDim)
614  {
615  if (pNumGroupDim->GetDatePart())
616  {
617  WriteDatePart(pNumGroupDim->GetDatePart());
618  WriteNumGroupInfo(pNumGroupDim->GetDateInfo());
619  }
620  else
621  {
622  WriteNumGroupInfo(pNumGroupDim->GetInfo());
623  }
624  }
625 }
626 
628 {
629  const ScDPSaveGroupDimension* pGroupDim = nullptr;
630  const ScDPSaveNumGroupDimension* pNumGroupDim = nullptr;
631  if (pDimData)
632  {
633  pGroupDim = pDimData->GetNamedGroupDim(pDim->GetName());
634  WriteGroupDimAttributes(pGroupDim);
635  pNumGroupDim = pDimData->GetNumGroupDim(pDim->GetName());
636  WriteNumGroupDim(pNumGroupDim);
637 
638  OSL_ENSURE((!pGroupDim || !pNumGroupDim), "there should be no NumGroup and Group at the same field");
639  }
640  if (!(pGroupDim || pNumGroupDim))
641  return;
642 
644  if (!pGroupDim)
645  return;
646 
647  if (pGroupDim->GetDatePart())
648  return;
649 
650  sal_Int32 nCount = pGroupDim->GetGroupCount();
651  for (sal_Int32 i = 0; i < nCount; ++i)
652  {
653  const ScDPSaveGroupItem& rGroup = pGroupDim->GetGroupByIndex( i );
656  sal_Int32 nElemCount = rGroup.GetElementCount();
657  for(sal_Int32 j = 0; j < nElemCount; ++j)
658  {
659  const OUString* pElem = rGroup.GetElementByIndex(j);
660  if (pElem)
661  {
664  }
665  }
666  }
667 }
668 
670 {
671  OUString aSrcDimName = ScDPUtil::getSourceDimensionName(pDim->GetName());
674  {
675  // Export display names only for ODF 1.2 extended or later.
676  const std::optional<OUString> & pLayoutName = pDim->GetLayoutName();
677  if (pLayoutName)
679  }
680 
681  if (pDim->IsDataLayout())
683  sheet::DataPilotFieldOrientation eOrientation = pDim->GetOrientation();
684  OUString sValueStr = ScXMLConverter::GetStringFromOrientation(eOrientation);
685  if( !sValueStr.isEmpty() )
687  if (pDim->GetUsedHierarchy() != 1)
688  {
690  }
691  sValueStr = ScXMLConverter::GetStringFromFunction( static_cast<sal_Int16>(pDim->GetFunction()) );
693 
694  if (eOrientation == sheet::DataPilotFieldOrientation_PAGE)
695  {
697  {
699  }
701  }
702 
704  WriteLevels(pDim);
705  WriteFieldReference(pDim);
706  if( pDim->GetOrientation() != sheet::DataPilotFieldOrientation_DATA )
707  WriteGroupDimElements(pDim, pDimData);
708 }
709 
711 {
712  const ScDPSaveData::DimsType& rDimensions = pDPSave->GetDimensions();
713  for (auto const& iter : rDimensions)
714  {
715  WriteDimension(iter.get(),
716  pDPSave->GetExistingDimensionData());
717  }
718 }
719 
720 void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const std::optional<OUString> & pGrandTotal)
721 {
724  if (pGrandTotal)
726 
728 }
729 
731 {
733  if (!pDoc)
734  return;
735 
737  if (!pDPs)
738  return;
739 
740  size_t nDPCount = pDPs->GetCount();
741  if (!nDPCount)
742  return;
743 
746  for (size_t i = 0; i < nDPCount; ++i)
747  {
748  ScDPSaveData* pDPSave = (*pDPs)[i].GetSaveData();
749  if (!pDPSave)
750  continue;
751 
752  ScRange aOutRange((*pDPs)[i].GetOutRange());
753  OUString sTargetRangeAddress;
755  ScDocAttrIterator aAttrItr(*pDoc, aOutRange.aStart.Tab(),
756  aOutRange.aStart.Col(), aOutRange.aStart.Row(),
757  aOutRange.aEnd.Col(), aOutRange.aEnd.Row());
758  SCCOL nCol;
759  SCROW nRow1, nRow2;
760  OUString sOUButtonList;
761  const ScPatternAttr* pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
762  while (pAttr)
763  {
764  const ScMergeFlagAttr& rItem = pAttr->GetItem(ATTR_MERGE_FLAG);
765  if (rItem.HasPivotButton())
766  {
767  for (SCROW nButtonRow = nRow1; nButtonRow <= nRow2; ++nButtonRow)
768  {
769  ScAddress aButtonAddr(nCol, nButtonRow, aOutRange.aStart.Tab());
771  sOUButtonList, aButtonAddr, pDoc, ::formula::FormulaGrammar::CONV_OOO, ' ', true );
772  }
773  }
774  pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
775  }
776  OUString sName((*pDPs)[i].GetName());
777  OUString sApplicationData((*pDPs)[i].GetTag());
778  bool bRowGrand = pDPSave->GetRowGrand();
779  bool bColumnGrand = pDPSave->GetColumnGrand();
784  if (!(bRowGrand && bColumnGrand))
785  {
786  if (bRowGrand)
788  else if (bColumnGrand)
790  else
792  }
793  if (pDPSave->GetIgnoreEmptyRows())
795  if (pDPSave->GetRepeatIfEmpty())
797  if (!pDPSave->GetFilterButton())
799  if (!pDPSave->GetDrillDown())
801  if ((*pDPs)[i].GetHeaderLayout())
803 
805 
806  // grand total elements.
807 
808  const std::optional<OUString> & pGrandTotalName = pDPSave->GetGrandTotalName();
810  {
811  // Use the new data-pilot-grand-total element.
812  if (bRowGrand && bColumnGrand)
813  {
814  WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
815  }
816  else
817  {
818  WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
819  WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
820  }
821  }
822 
824  if ((*pDPs)[i].IsSheetData())
825  {
826  const ScSheetSourceDesc* pSheetSource = (*pDPs)[i].GetSheetDesc();
827 
829  {
830  if (pSheetSource->HasRangeName())
831  { // ODF 1.3 OFFICE-3665
832  // FIXME this was wrongly exported to TABLE namespace since 2011
833  // so continue doing that in ODF 1.2 extended, for now
835  XML_NAMESPACE_TABLE, XML_NAME, pSheetSource->GetRangeName());
836  }
837  }
838 
839  OUString sCellRangeAddress;
841  sCellRangeAddress, pSheetSource->GetSourceRange(), pDoc,
843 
847  WriteDPFilter(pSheetSource->GetQueryParam());
848  }
849  else if ((*pDPs)[i].IsImportData())
850  {
851  const ScImportSourceDesc* pImpSource = (*pDPs)[i].GetImportSourceDesc();
852  switch (pImpSource->nType)
853  {
854  case sheet::DataImportMode_NONE : break;
855  case sheet::DataImportMode_QUERY :
856  {
861  }
862  break;
863  case sheet::DataImportMode_TABLE :
864  {
869  }
870  break;
871  case sheet::DataImportMode_SQL :
872  {
875  if (!pImpSource->bNative)
879  }
880  break;
881  default: break;
882  }
883  }
884  else if ((*pDPs)[i].IsServiceData())
885  {
886  const ScDPServiceDesc* pServSource = (*pDPs)[i].GetDPServiceDesc();
891  // #i111754# leave out password attribute as long as DataPilotSource doesn't specify the content
892  // rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PASSWORD, OUString(pServSource->aParPass));
895  }
896  WriteDimensions(pDPSave);
897  }
898 }
899 
900 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XML_SELECTED_PAGE
XML_DATA_PILOT_FIELD
XML_IGNORE_EMPTY_ROWS
XML_NUMBER
const ScDPDimensionSaveData * GetExistingDimensionData() const
Definition: dpsave.hxx:348
XML_DATE_START
static OUString GetStringFromFunction(const sal_Int16 eFunction)
const std::optional< OUString > & GetLayoutName() const
Definition: dpsave.cxx:385
bool GetRowGrand() const
Definition: dpsave.hxx:326
XML_DAYS
OUString getString() const
ScAddress aStart
Definition: address.hxx:497
This class has to do with handling exclusively grouped dimensions? TODO: Find out what this class doe...
Definition: dpdimsave.hxx:163
XML_MEMBER_PERCENTAGE_DIFFERENCE
XML_DRILL_DOWN_ON_DOUBLE_CLICK
XML_FIELD_NUMBER
SC_DLLPUBLIC size_t GetCount() const
Definition: dpobject.cxx:3679
SCROW Row() const
Definition: address.hxx:274
SC_DLLPUBLIC const std::optional< OUString > & GetGrandTotalName() const
Definition: dpsave.cxx:771
XML_NOMATCH
void WriteGroupDimAttributes(const ScDPSaveGroupDimension *pGroupDim)
const Item & GetQueryItem() const
Definition: queryentry.hxx:85
XML_SOURCE_NAME
XML_SECONDS
XML_DATABASE_SOURCE_QUERY
XML_DATA_PILOT_TABLE
const MemberList & GetMembers() const
Definition: dpsave.hxx:128
static void GetStringFromRange(OUString &rString, const ScRange &rRange, const ScDocument *pDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ', bool bAppendStr=false, ScRefFlags nFormatFlags=ScRefFlags::VALID|ScRefFlags::TAB_3D)
css::sheet::DataPilotFieldOrientation GetOrientation() const
Definition: dpsave.hxx:202
XML_FIELD_NAME
XML_MATCH
XML_AUTO
void WriteLevels(const ScDPSaveDimension *pDim)
const SvXMLUnitConverter & GetMM100UnitConverter() const
ScGeneralFunction GetSubTotalFunc(tools::Long nIndex) const
Definition: dpsave.hxx:152
void CheckAttrList()
const css::sheet::DataPilotFieldLayoutInfo * GetLayoutInfo() const
Definition: dpsave.hxx:194
XML_MEMBER_TYPE
XML_MANUAL
Classes to save Data Pilot settings that create new dimensions (fields).
Definition: dpdimsave.hxx:46
const OUString & GetGroupName() const
Definition: dpdimsave.hxx:65
bool HasPivotButton() const
Definition: attrib.cxx:148
XML_DESCENDING
SC_DLLPUBLIC ScDPCollection * GetDPCollection()
Definition: documen3.cxx:365
void WriteDatePart(sal_Int32 nPart)
XML_TOP_VALUES
const OUString & GetSourceDimName() const
Definition: dpdimsave.hxx:108
void WriteSortInfo(const ScDPSaveDimension *pDim)
void WriteDimensions(const ScDPSaveData *pDPSave)
XML_DISPLAY_MEMBER_MODE
SCCOLROW nField
Definition: queryentry.hxx:61
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
ScAddress aEnd
Definition: address.hxx:498
XML_DATABASE_TABLE_NAME
XML_DATA_PILOT_SUBTOTAL
XML_VALUE
sal_Int32 GetDatePart() const
Definition: dpdimsave.hxx:152
bool IsQueryByEmpty() const
Definition: queryentry.cxx:87
bool IsDataLayout() const
Definition: dpsave.hxx:142
XML_IDENTIFY_CATEGORIES
const ScDPNumGroupInfo & GetDateInfo() const
Definition: dpdimsave.hxx:153
OUString aParSource
Definition: dpobject.hxx:72
XML_DATA_PILOT_SORT_INFO
XML_DATA_TYPE
static void GetStringFromAddress(OUString &rString, const ScAddress &rAddress, const ScDocument *pDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ', bool bAppendStr=false, ScRefFlags nFormatFlags=ScRefFlags::VALID|ScRefFlags::TAB_3D)
Range to String core.
XML_EMPTY
XML_DATA_PILOT_MEMBER
XML_DATA_PILOT_FIELD_REFERENCE
constexpr sal_uInt16 XML_NAMESPACE_CALC_EXT
tools::Long GetUsedHierarchy() const
Definition: dpsave.hxx:169
XML_COLUMN
XML_DATA_PILOT_TABLES
XML_MEMBER_DIFFERENCE
XML_INDEX
const ScDPSaveGroupDimension * GetNamedGroupDim(const OUString &rGroupDimName) const
Definition: dpdimsave.cxx:635
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
void WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const std::optional< OUString > &pGrandTotal)
XML_OUTLINE_SUBTOTALS_TOP
XML_SHOW_DETAILS
XML_ORDER
XML_DATA_PILOT_MEMBERS
XML_USER_NAME
int nCount
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
SC_DLLPUBLIC SCSIZE GetEntryCount() const
Definition: queryparam.cxx:110
XML_ROW_PERCENTAGE
void StartElement(sal_uInt16 nPrefix, enum::xmloff::token::XMLTokenEnum eName, bool bIgnWSOutside)
SC_DLLPUBLIC const ScQueryEntry & GetEntry(SCSIZE n) const
Definition: queryparam.cxx:115
SCTAB Tab() const
Definition: address.hxx:283
XML_DATA_PILOT_LAYOUT_INFO
SC_DLLPUBLIC const ScRange & GetSourceRange() const
Get the range that contains the source data.
Definition: dpshttab.cxx:230
ScGeneralFunction GetFunction() const
Definition: dpsave.hxx:165
XML_NAMED
bool HasShowEmpty() const
Definition: dpsave.cxx:329
virtual OUString GetName() const override
XML_DISPLAY_NAME
XML_FUNCTION
XML_MINUTES
bool GetIgnoreEmptyRows() const
Definition: dpsave.hxx:330
XML_NOEMPTY
sal_Int32 GetDatePart() const
Definition: dpdimsave.hxx:110
size_t GetElementCount() const
Definition: dpdimsave.cxx:71
const char * sName
void WriteMembers(const ScDPSaveDimension *pDim)
std::vector< ScDPSaveMember * > MemberList
Definition: dpsave.hxx:115
static SC_DLLPUBLIC OUString getSourceDimensionName(std::u16string_view rName)
Definition: dputil.cxx:66
XML_DATA
bool GetRepeatItemLabels() const
Definition: dpsave.hxx:161
XML_DATA_PILOT_SUBTOTALS
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:72
const ScQueryParam & GetQueryParam() const
Definition: dpshttab.hxx:63
OUString aParUser
Definition: dpobject.hxx:74
XML_DATA_FIELD
bool GetDrillDown() const
Definition: dpsave.hxx:342
tools::Long GetGroupCount() const
Definition: dpdimsave.cxx:198
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
XML_FILTER_AND
XML_RUNNING_TOTAL
const ScDPSaveGroupItem & GetGroupByIndex(tools::Long nIndex) const
Definition: dpdimsave.cxx:203
XML_END
const css::sheet::DataPilotFieldSortInfo * GetSortInfo() const
Definition: dpsave.hxx:186
constexpr sal_uInt16 XML_NAMESPACE_TABLE_EXT
tools::Long GetSubTotalsCount() const
Definition: dpsave.hxx:149
void WriteDPFilter(const ScQueryParam &aQueryParam)
XML_SQL_STATEMENT
XML_START
const OUString * GetElementByIndex(size_t nIndex) const
Definition: dpdimsave.cxx:76
int i
void WriteFieldReference(const ScDPSaveDimension *pDim)
void WriteAutoShowInfo(const ScDPSaveDimension *pDim)
Represents a group dimension that introduces a new hierarchy for an existing dimension.
Definition: dpdimsave.hxx:135
bool IsQueryByNonEmpty() const
Definition: queryentry.cxx:109
XML_ORIENTATION
XML_DATABASE_SOURCE_SQL
sal_Int16 SCCOL
Definition: types.hxx:21
void WriteNumGroupInfo(const ScDPNumGroupInfo &pGroupInfo)
XML_SOURCE_SERVICE
void convertDateTime(OUStringBuffer &rBuffer, const double &fDateTime, bool const bAddTimeIf0AM=false)
XML_QUERY_NAME
XML_DATA_PILOT_GROUP_MEMBER
bool GetRepeatIfEmpty() const
Definition: dpsave.hxx:334
XML_MEMBER_PERCENTAGE
XML_SORT_MODE
XML_DISPLAY
XML_STEP
XML_TOP_PERCENT
XML_TOTAL_PERCENTAGE
const ScDPNumGroupInfo & GetDateInfo() const
Definition: dpdimsave.hxx:111
XML_OPERATOR
XML_TARGET_RANGE_ADDRESS
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
XML_ENABLED
void WriteSubTotals(const ScDPSaveDimension *pDim)
XML_FILTER_OR
OUString GetCurrentPage() const
Definition: dpsave.cxx:439
XML_SHOW_EMPTY
OUString aDBName
Definition: dpsdbtab.hxx:35
svl::SharedString maString
Definition: queryentry.hxx:49
XML_DATE_END
const SvXMLNamespaceMap & GetNamespaceMap() const
XML_ADD_EMPTY_LINES
SCCOL Col() const
Definition: address.hxx:279
XML_FROM_BOTTOM
const std::optional< OUString > & GetSubtotalName() const
Definition: dpsave.cxx:359
bool GetFilterButton() const
Definition: dpsave.hxx:338
XML_PREVIOUS
static bool convertBool(bool &rBool, std::u16string_view rString)
css::sheet::DataImportMode nType
Definition: dpsdbtab.hxx:37
OUString aObject
Definition: dpsdbtab.hxx:36
XML_CELL_RANGE_ADDRESS
bool HasRangeName() const
Definition: dpshttab.cxx:265
XML_TRUE
XML_TABULAR_LAYOUT
bool GetColumnGrand() const
Definition: dpsave.hxx:322
XML_MEMBER_COUNT
XML_HEADER_GRID_LAYOUT
XML_QUARTERS
ScDocument * GetDocument()
Definition: xmlexprt.hxx:240
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
sal_Int32 SCROW
Definition: types.hxx:17
void WriteGroupDimElements(const ScDPSaveDimension *pDim, const ScDPDimensionSaveData *pDimData)
XML_OBJECT_NAME
XML_GRAND_TOTAL
XML_FALSE
constexpr sal_uInt16 XML_NAMESPACE_TABLE
XML_NEXT
const DimsType & GetDimensions() const
Definition: dpsave.hxx:270
XML_DATA_PILOT_GROUP
void EndElement(sal_uInt16 nPrefix, enum::xmloff::token::XMLTokenEnum eName, bool bIgnWSInside)
XML_GROUPED_BY
XML_FROM_TOP
XML_PARSE_SQL_STATEMENT
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
XML_YEARS
OUString aParName
Definition: dpobject.hxx:73
void WriteDimension(const ScDPSaveDimension *pDim, const ScDPDimensionSaveData *pDimData)
XML_ROW
OUString aServiceName
Definition: dpobject.hxx:71
XML_NONE
XML_BOTTOM_VALUES
bool GetShowEmpty() const
Definition: dpsave.hxx:157
XML_TYPE
OUString aName
const OUString & GetName() const
Definition: dpsave.hxx:139
std::vector< std::unique_ptr< ScDPSaveDimension > > DimsType
Definition: dpsave.hxx:238
XML_CASE_SENSITIVE
XML_DATABASE_SOURCE_TABLE
Represents a new group dimension whose dimension ID is higher than the highest source dimension ID...
Definition: dpdimsave.hxx:90
const OUString & GetRangeName() const
Definition: dpshttab.hxx:60
const css::sheet::DataPilotFieldAutoShowInfo * GetAutoShowInfo() const
Definition: dpsave.hxx:190
XML_SHOW_FILTER_BUTTON
XML_MEMBER_NAME
XML_BOTH
XML_DATA_PILOT_DISPLAY_INFO
ScQueryConnect eConnect
Definition: queryentry.hxx:63
ScXMLExportDataPilot(ScXMLExport &rExport)
ScQueryOp
Definition: global.hxx:817
XML_DATA_PILOT_LEVEL
XML_LAYOUT_MODE
XML_DISPLAY_DUPLICATES
const ScDPNumGroupInfo & GetInfo() const
Definition: dpdimsave.hxx:150
XML_BUTTONS
void WriteNumGroupDim(const ScDPSaveNumGroupDimension *pNumGroupDim)
XML_FILTER
XML_SOURCE_CELL_RANGE
XML_DATA_PILOT_GRAND_TOTAL
XML_SOURCE_FIELD_NAME
const ScDPSaveNumGroupDimension * GetNumGroupDim(const OUString &rGroupDimName) const
Definition: dpdimsave.cxx:650
XML_IS_DATA_LAYOUT_FIELD
void WriteLayoutInfo(const ScDPSaveDimension *pDim)
XML_ASCENDING
XML_REPEAT_ITEM_LABELS
const SCTAB SCTAB_MAX
Definition: address.hxx:57
XML_DATABASE_NAME
static OUString getDPOperatorXML(const ScQueryOp aFilterOperator, const utl::SearchParam::SearchType eSearchType)
ScQueryOp eOp
Definition: queryentry.hxx:62
static OUString GetStringFromOrientation(const css::sheet::DataPilotFieldOrientation eOrientation)
XML_OUTLINE_SUBTOTALS_BOTTOM
XML_USED_HIERARCHY
XML_DATA_PILOT_GROUPS
This class contains authoritative information on the internal reference used as the data source for d...
Definition: dpshttab.hxx:39
XML_FILTER_CONDITION
XML_MONTHS
XML_APPLICATION_DATA
Each instance of this struct represents a single filtering criteria.
Definition: queryentry.hxx:33
void WriteDPCondition(const ScQueryEntry &aQueryEntry, bool bIsCaseSensitive, utl::SearchParam::SearchType eSearchType)
XML_COLUMN_PERCENTAGE
utl::SearchParam::SearchType eSearchType
Definition: queryparam.hxx:43
const css::sheet::DataPilotFieldReference * GetReferenceValue() const
Definition: dpsave.hxx:181
XML_BOTTOM_PERCENT
XML_IGNORE_SELECTED_PAGE
XML_CONDITION_SOURCE_RANGE_ADDRESS
XML_HOURS
XML_NAME
ScQueryConnect
Definition: global.hxx:837