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/xmlnmspe.hxx>
23 #include <xmloff/xmluconv.hxx>
24 #include <xmloff/nmspmap.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 {
67 }
68 
70  const ScQueryOp aFilterOperator, const utl::SearchParam::SearchType eSearchType)
71 {
72  switch (aFilterOperator)
73  {
74  case SC_EQUAL :
75  {
76  if (eSearchType == utl::SearchParam::SearchType::Regexp)
77  return GetXMLToken(XML_MATCH);
78  else
79  return "=";
80  }
81  case SC_NOT_EQUAL :
82  {
83  if (eSearchType == utl::SearchParam::SearchType::Regexp)
84  return GetXMLToken(XML_NOMATCH);
85  else
86  return "!=";
87  }
88  case SC_BOTPERC :
90  case SC_BOTVAL :
92  case SC_GREATER :
93  return ">";
94  case SC_GREATER_EQUAL :
95  return ">=";
96  case SC_LESS :
97  return "<";
98  case SC_LESS_EQUAL :
99  return "<=";
100  case SC_TOPPERC :
102  case SC_TOPVAL :
103  return GetXMLToken(XML_TOP_VALUES);
104  default:
105  OSL_FAIL("This FilterOperator is not supported.");
106  }
107  return "=";
108 }
109 
110 void ScXMLExportDataPilot::WriteDPCondition(const ScQueryEntry& aQueryEntry, bool bIsCaseSensitive,
111  utl::SearchParam::SearchType eSearchType)
112 {
113  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(aQueryEntry.nField));
114  if (bIsCaseSensitive)
116  const ScQueryEntry::Item& rItem = aQueryEntry.GetQueryItem();
117  OUString aQueryStr = rItem.maString.getString();
118  if (rItem.meType == ScQueryEntry::ByString)
119  {
121  }
122  else
123  {
126  }
127 
128  if (aQueryEntry.IsQueryByEmpty())
129  {
131  }
132  else if (aQueryEntry.IsQueryByNonEmpty())
133  {
135  }
136  else
139  getDPOperatorXML(aQueryEntry.eOp, eSearchType));
140 
142 }
143 
145 {
146  SCSIZE nQueryEntryCount = aQueryParam.GetEntryCount();
147  if (nQueryEntryCount <= 0)
148  return;
149 
150  bool bAnd(false);
151  bool bOr(false);
152  bool bHasEntries(true);
153  SCSIZE nEntries(0);
154  SCSIZE j;
155 
156  for ( j = 0; (j < nQueryEntryCount) && bHasEntries; ++j)
157  {
158  ScQueryEntry aEntry = aQueryParam.GetEntry(j);
159  if (aEntry.bDoQuery)
160  {
161  if (nEntries > 0)
162  {
163  if (aEntry.eConnect == SC_AND)
164  bAnd = true;
165  else
166  bOr = true;
167  }
168  ++nEntries;
169  }
170  else
171  bHasEntries = false;
172  }
173  nQueryEntryCount = nEntries;
174  if (!nQueryEntryCount)
175  return;
176 
177  if(!((aQueryParam.nCol1 == aQueryParam.nCol2) && (aQueryParam.nRow1 == aQueryParam.nRow2) &&
178  (static_cast<SCCOLROW>(aQueryParam.nCol1) == static_cast<SCCOLROW>(aQueryParam.nRow1)) &&
179  (aQueryParam.nCol1 == 0) && (aQueryParam.nTab == SCTAB_MAX)))
180  {
181  ScRange aConditionRange(aQueryParam.nCol1, aQueryParam.nRow1, aQueryParam.nTab,
182  aQueryParam.nCol2, aQueryParam.nRow2, aQueryParam.nTab);
183  OUString sConditionRange;
185  if (!sConditionRange.isEmpty())
187  }
188  if (!aQueryParam.bDuplicate)
192  if (nQueryEntryCount == 1)
193  {
194  WriteDPCondition(aQueryParam.GetEntry(0), aQueryParam.bCaseSens, aQueryParam.eSearchType);
195  }
196  else if (bOr && !bAnd)
197  {
199  for (j = 0; j < nQueryEntryCount; ++j)
200  {
201  WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.eSearchType);
202  }
203  }
204  else if (bAnd && !bOr)
205  {
207  for (j = 0; j < nQueryEntryCount; ++j)
208  {
209  WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.eSearchType);
210  }
211  }
212  else
213  {
215  ScQueryEntry aPrevFilterField(aQueryParam.GetEntry(0));
216  ScQueryConnect aConnection = aQueryParam.GetEntry(1).eConnect;
217  bool bOpenAndElement;
219  if (aConnection == SC_AND)
220  {
221  rExport.StartElement( aName, true );
222  bOpenAndElement = true;
223  }
224  else
225  bOpenAndElement = false;
226  for (j = 1; j < nQueryEntryCount; ++j)
227  {
228  if (aConnection != aQueryParam.GetEntry(j).eConnect)
229  {
230  aConnection = aQueryParam.GetEntry(j).eConnect;
231  if (aQueryParam.GetEntry(j).eConnect == SC_AND)
232  {
233  rExport.StartElement( aName, true );
234  bOpenAndElement = true;
235  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
236  aPrevFilterField = aQueryParam.GetEntry(j);
237  if (j == nQueryEntryCount - 1)
238  {
239  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
240  rExport.EndElement(aName, true);
241  bOpenAndElement = false;
242  }
243  }
244  else
245  {
246  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
247  aPrevFilterField = aQueryParam.GetEntry(j);
248  if (bOpenAndElement)
249  {
250  rExport.EndElement(aName, true);
251  bOpenAndElement = false;
252  }
253  if (j == nQueryEntryCount - 1)
254  {
255  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
256  }
257  }
258  }
259  else
260  {
261  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
262  aPrevFilterField = aQueryParam.GetEntry(j);
263  if (j == nQueryEntryCount - 1)
264  WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.eSearchType);
265  }
266  }
267  }
268 }
269 
271 {
272  const sheet::DataPilotFieldReference* pRef = pDim->GetReferenceValue();
273  if (pRef)
274  {
275  OUString sValueStr;
276  switch (pRef->ReferenceType)
277  {
279  sValueStr = GetXMLToken(XML_NONE);
280  break;
281  case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE :
282  sValueStr = GetXMLToken(XML_MEMBER_DIFFERENCE);
283  break;
284  case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE :
285  sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE);
286  break;
287  case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE :
289  break;
290  case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL :
291  sValueStr = GetXMLToken(XML_RUNNING_TOTAL);
292  break;
293  case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE :
294  sValueStr = GetXMLToken(XML_ROW_PERCENTAGE);
295  break;
296  case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE :
297  sValueStr = GetXMLToken(XML_COLUMN_PERCENTAGE);
298  break;
299  case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE :
300  sValueStr = GetXMLToken(XML_TOTAL_PERCENTAGE);
301  break;
302  case sheet::DataPilotFieldReferenceType::INDEX :
303  sValueStr = GetXMLToken(XML_INDEX);
304  break;
305  }
306  if (!sValueStr.isEmpty())
308 
309  if (!pRef->ReferenceField.isEmpty())
310  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NAME, pRef->ReferenceField);
311 
312  if (pRef->ReferenceItemType == sheet::DataPilotFieldReferenceItemType::NAMED)
313  {
315  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_NAME, pRef->ReferenceItemName);
316  }
317  else
318  {
319  sValueStr.clear();
320  switch(pRef->ReferenceItemType)
321  {
322  case sheet::DataPilotFieldReferenceItemType::PREVIOUS :
323  sValueStr = GetXMLToken(XML_PREVIOUS);
324  break;
325  case sheet::DataPilotFieldReferenceItemType::NEXT :
326  sValueStr = GetXMLToken(XML_NEXT);
327  break;
328  }
329  if (!sValueStr.isEmpty())
331  }
333  }
335 }
336 
338 {
339  const sheet::DataPilotFieldSortInfo* pSortInfo = pDim->GetSortInfo();
340  if (!pSortInfo)
341  return;
342 
343  if (pSortInfo->IsAscending)
345  else
347 
348  OUString sValueStr;
349  switch (pSortInfo->Mode)
350  {
352  sValueStr = GetXMLToken(XML_NONE);
353  break;
354  case sheet::DataPilotFieldSortMode::MANUAL:
355  sValueStr = GetXMLToken(XML_MANUAL);
356  break;
357  case sheet::DataPilotFieldSortMode::NAME:
358  sValueStr = GetXMLToken(XML_NAME);
359  break;
360  case sheet::DataPilotFieldSortMode::DATA:
361  sValueStr = GetXMLToken(XML_DATA);
362  if (!pSortInfo->Field.isEmpty())
364  break;
365  }
366  if (!sValueStr.isEmpty())
369 }
370 
372 {
373  const sheet::DataPilotFieldAutoShowInfo* pAutoInfo = pDim->GetAutoShowInfo();
374  if (!pAutoInfo)
375  return;
376 
377  if (pAutoInfo->IsEnabled)
379  else
381 
382  OUString sValueStr;
383  switch (pAutoInfo->ShowItemsMode)
384  {
385  case sheet::DataPilotFieldShowItemsMode::FROM_TOP:
386  sValueStr = GetXMLToken(XML_FROM_TOP);
387  break;
388  case sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM:
389  sValueStr = GetXMLToken(XML_FROM_BOTTOM);
390  break;
391  }
392  if (!sValueStr.isEmpty())
394 
395  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_COUNT, OUString::number(pAutoInfo->ItemCount));
396 
397  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pAutoInfo->DataField);
398 
400 }
401 
403 {
404  const sheet::DataPilotFieldLayoutInfo* pLayoutInfo = pDim->GetLayoutInfo();
405  if (!pLayoutInfo)
406  return;
407 
408  if (pLayoutInfo->AddEmptyLines)
410  else
412 
413  OUString sValueStr;
414  switch (pLayoutInfo->LayoutMode)
415  {
416  case sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT:
417  sValueStr = GetXMLToken(XML_TABULAR_LAYOUT);
418  break;
419  case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP:
421  break;
422  case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM:
424  break;
425  }
426  if (!sValueStr.isEmpty())
429 }
430 
432 {
433  sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
434  std::optional<OUString> pLayoutName;
436  // Export display names only for 1.2 extended or later.
437  pLayoutName = pDim->GetSubtotalName();
438 
439  if (nSubTotalCount <= 0)
440  return;
441 
444  for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
445  {
446  OUString sFunction;
447  sal_Int16 nFunc = static_cast<sal_Int16>(pDim->GetSubTotalFunc(nSubTotal));
448  ScXMLConverter::GetStringFromFunction( sFunction, nFunc);
450  if (pLayoutName && nFunc == sheet::GeneralFunction2::AUTO)
453  }
454 }
455 
457 {
458  const ScDPSaveDimension::MemberList &rMembers = pDim->GetMembers();
459  if (rMembers.empty())
460  return;
461 
464  for (const auto& rpMember : rMembers)
465  {
466  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rpMember->GetName());
467 
469  {
470  // Export display names only for ODF 1.2 extended or later.
471  const std::optional<OUString> & pLayoutName = rpMember->GetLayoutName();
472  if (pLayoutName)
474  }
475 
476  OUStringBuffer sBuffer;
477  ::sax::Converter::convertBool(sBuffer, rpMember->GetIsVisible());
478  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
479  ::sax::Converter::convertBool(sBuffer, rpMember->GetShowDetails());
480  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, sBuffer.makeStringAndClear());
483  }
484 }
485 
487 {
488  // #i114202# GetShowEmpty is only valid if HasShowEmpty is true.
489  if (pDim->HasShowEmpty())
490  {
491  OUStringBuffer sBuffer;
493  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, sBuffer.makeStringAndClear());
494  }
496  {
497  OUStringBuffer sBuffer;
499  rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_REPEAT_ITEM_LABELS, sBuffer.makeStringAndClear());
500  }
502 
503  WriteSubTotals(pDim);
504  WriteMembers(pDim);
505  WriteAutoShowInfo(pDim);
506  WriteSortInfo(pDim);
507  WriteLayoutInfo(pDim);
509 }
510 
512 {
513  switch(nPart)
514  {
515  case css::sheet::DataPilotFieldGroupBy::SECONDS :
516  {
518  }
519  break;
520  case css::sheet::DataPilotFieldGroupBy::MINUTES :
521  {
523  }
524  break;
525  case css::sheet::DataPilotFieldGroupBy::HOURS :
526  {
528  }
529  break;
530  case css::sheet::DataPilotFieldGroupBy::DAYS :
531  {
533  }
534  break;
535  case css::sheet::DataPilotFieldGroupBy::MONTHS :
536  {
538  }
539  break;
540  case css::sheet::DataPilotFieldGroupBy::QUARTERS :
541  {
543  }
544  break;
545  case css::sheet::DataPilotFieldGroupBy::YEARS :
546  {
548  }
549  break;
550  }
551 }
552 
554 {
555  OSL_ENSURE(rGroupInfo.mbEnable, "group dimension should be enabled");
556  if (rGroupInfo.mbDateValues)
557  {
558  if (rGroupInfo.mbAutoStart)
560  else
561  {
562  OUStringBuffer sDate;
564  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, sDate.makeStringAndClear());
565  }
566  if (rGroupInfo.mbAutoEnd)
568  else
569  {
570  OUStringBuffer sDate;
571  rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.mfEnd);
572  rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, sDate.makeStringAndClear());
573  }
574  }
575  else
576  {
577  if (rGroupInfo.mbAutoStart)
579  else
580  {
581  OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.mfStart,
582  rtl_math_StringFormat_Automatic,
583  rtl_math_DecimalPlaces_Max, '.', true));
585  }
586  if (rGroupInfo.mbAutoEnd)
588  else
589  {
590  OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.mfEnd,
591  rtl_math_StringFormat_Automatic,
592  rtl_math_DecimalPlaces_Max, '.', true));
594  }
595  }
596  OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.mfStep,
597  rtl_math_StringFormat_Automatic,
598  rtl_math_DecimalPlaces_Max, '.', true));
600 }
601 
603 {
604  if (pGroupDim)
605  {
606  OUString aSrcFieldName = ScDPUtil::getSourceDimensionName(pGroupDim->GetSourceDimName());
608  if (pGroupDim->GetDatePart())
609  {
610  WriteDatePart(pGroupDim->GetDatePart());
611  WriteNumGroupInfo(pGroupDim->GetDateInfo());
612  }
613  }
614 }
615 
617 {
618  if (pNumGroupDim)
619  {
620  if (pNumGroupDim->GetDatePart())
621  {
622  WriteDatePart(pNumGroupDim->GetDatePart());
623  WriteNumGroupInfo(pNumGroupDim->GetDateInfo());
624  }
625  else
626  {
627  WriteNumGroupInfo(pNumGroupDim->GetInfo());
628  }
629  }
630 }
631 
633 {
634  const ScDPSaveGroupDimension* pGroupDim = nullptr;
635  const ScDPSaveNumGroupDimension* pNumGroupDim = nullptr;
636  if (pDimData)
637  {
638  pGroupDim = pDimData->GetNamedGroupDim(pDim->GetName());
639  WriteGroupDimAttributes(pGroupDim);
640  pNumGroupDim = pDimData->GetNumGroupDim(pDim->GetName());
641  WriteNumGroupDim(pNumGroupDim);
642 
643  OSL_ENSURE((!pGroupDim || !pNumGroupDim), "there should be no NumGroup and Group at the same field");
644  }
645  if (!(pGroupDim || pNumGroupDim))
646  return;
647 
649  if (!pGroupDim)
650  return;
651 
652  if (pGroupDim->GetDatePart())
653  return;
654 
655  sal_Int32 nCount = pGroupDim->GetGroupCount();
656  for (sal_Int32 i = 0; i < nCount; ++i)
657  {
658  const ScDPSaveGroupItem& rGroup = pGroupDim->GetGroupByIndex( i );
661  sal_Int32 nElemCount = rGroup.GetElementCount();
662  for(sal_Int32 j = 0; j < nElemCount; ++j)
663  {
664  const OUString* pElem = rGroup.GetElementByIndex(j);
665  if (pElem)
666  {
669  }
670  }
671  }
672 }
673 
675 {
676  OUString aSrcDimName = ScDPUtil::getSourceDimensionName(pDim->GetName());
679  {
680  // Export display names only for ODF 1.2 extended or later.
681  const std::optional<OUString> & pLayoutName = pDim->GetLayoutName();
682  if (pLayoutName)
684  }
685 
686  if (pDim->IsDataLayout())
688  OUString sValueStr;
689  sheet::DataPilotFieldOrientation eOrientation = pDim->GetOrientation();
691  eOrientation);
692  if( !sValueStr.isEmpty() )
694  if (pDim->GetUsedHierarchy() != 1)
695  {
697  }
698  ScXMLConverter::GetStringFromFunction( sValueStr, static_cast<sal_Int16>(pDim->GetFunction()) );
700 
701  if (eOrientation == sheet::DataPilotFieldOrientation_PAGE)
702  {
704  {
706  }
708  }
709 
711  WriteLevels(pDim);
712  WriteFieldReference(pDim);
713  if( pDim->GetOrientation() != sheet::DataPilotFieldOrientation_DATA )
714  WriteGroupDimElements(pDim, pDimData);
715 }
716 
718 {
719  const ScDPSaveData::DimsType& rDimensions = pDPSave->GetDimensions();
720  for (auto const& iter : rDimensions)
721  {
722  WriteDimension(iter.get(),
723  pDPSave->GetExistingDimensionData());
724  }
725 }
726 
727 void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const std::optional<OUString> & pGrandTotal)
728 {
731  if (pGrandTotal)
733 
735 }
736 
738 {
740  if (!pDoc)
741  return;
742 
744  if (!pDPs)
745  return;
746 
747  size_t nDPCount = pDPs->GetCount();
748  if (!nDPCount)
749  return;
750 
753  for (size_t i = 0; i < nDPCount; ++i)
754  {
755  ScDPSaveData* pDPSave = (*pDPs)[i].GetSaveData();
756  if (!pDPSave)
757  continue;
758 
759  ScRange aOutRange((*pDPs)[i].GetOutRange());
760  OUString sTargetRangeAddress;
762  ScDocAttrIterator aAttrItr(pDoc, aOutRange.aStart.Tab(),
763  aOutRange.aStart.Col(), aOutRange.aStart.Row(),
764  aOutRange.aEnd.Col(), aOutRange.aEnd.Row());
765  SCCOL nCol;
766  SCROW nRow1, nRow2;
767  OUString sOUButtonList;
768  const ScPatternAttr* pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
769  while (pAttr)
770  {
771  const ScMergeFlagAttr& rItem = pAttr->GetItem(ATTR_MERGE_FLAG);
772  if (rItem.HasPivotButton())
773  {
774  for (SCROW nButtonRow = nRow1; nButtonRow <= nRow2; ++nButtonRow)
775  {
776  ScAddress aButtonAddr(nCol, nButtonRow, aOutRange.aStart.Tab());
778  sOUButtonList, aButtonAddr, pDoc, ::formula::FormulaGrammar::CONV_OOO, ' ', true );
779  }
780  }
781  pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
782  }
783  OUString sName((*pDPs)[i].GetName());
784  OUString sApplicationData((*pDPs)[i].GetTag());
785  bool bRowGrand = pDPSave->GetRowGrand();
786  bool bColumnGrand = pDPSave->GetColumnGrand();
791  if (!(bRowGrand && bColumnGrand))
792  {
793  if (bRowGrand)
795  else if (bColumnGrand)
797  else
799  }
800  if (pDPSave->GetIgnoreEmptyRows())
802  if (pDPSave->GetRepeatIfEmpty())
804  if (!pDPSave->GetFilterButton())
806  if (!pDPSave->GetDrillDown())
808  if ((*pDPs)[i].GetHeaderLayout())
810 
812 
813  // grand total elements.
814 
815  const std::optional<OUString> & pGrandTotalName = pDPSave->GetGrandTotalName();
817  {
818  // Use the new data-pilot-grand-total element.
819  if (bRowGrand && bColumnGrand)
820  {
821  WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
822  }
823  else
824  {
825  WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
826  WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
827  }
828  }
829 
831  if ((*pDPs)[i].IsSheetData())
832  {
833  const ScSheetSourceDesc* pSheetSource = (*pDPs)[i].GetSheetDesc();
834 
836  {
837  if (pSheetSource->HasRangeName())
838  { // ODF 1.3 OFFICE-3665
839  // FIXME this was wrongly exported to TABLE namespace since 2011
840  // so continue doing that in ODF 1.2 extended, for now
842  XML_NAMESPACE_TABLE, XML_NAME, pSheetSource->GetRangeName());
843  }
844  }
845 
846  OUString sCellRangeAddress;
848  sCellRangeAddress, pSheetSource->GetSourceRange(), pDoc,
850 
854  WriteDPFilter(pSheetSource->GetQueryParam());
855  }
856  else if ((*pDPs)[i].IsImportData())
857  {
858  const ScImportSourceDesc* pImpSource = (*pDPs)[i].GetImportSourceDesc();
859  switch (pImpSource->nType)
860  {
861  case sheet::DataImportMode_NONE : break;
862  case sheet::DataImportMode_QUERY :
863  {
868  }
869  break;
870  case sheet::DataImportMode_TABLE :
871  {
876  }
877  break;
878  case sheet::DataImportMode_SQL :
879  {
882  if (!pImpSource->bNative)
886  }
887  break;
888  default: break;
889  }
890  }
891  else if ((*pDPs)[i].IsServiceData())
892  {
893  const ScDPServiceDesc* pServSource = (*pDPs)[i].GetDPServiceDesc();
898  // #i111754# leave out password attribute as long as DataPilotSource doesn't specify the content
899  // rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PASSWORD, OUString(pServSource->aParPass));
902  }
903  WriteDimensions(pDPSave);
904  }
905 }
906 
907 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
const ScDPDimensionSaveData * GetExistingDimensionData() const
Definition: dpsave.hxx:348
const std::optional< OUString > & GetLayoutName() const
Definition: dpsave.cxx:384
bool GetRowGrand() const
Definition: dpsave.hxx:326
XML_DATA_PILOT_GRAND_TOTAL
XML_MEMBER_TYPE
XML_DISPLAY_NAME
OUString getString() const
ScAddress aStart
Definition: address.hxx:500
XML_DATA_PILOT_GROUPS
This class has to do with handling exclusively grouped dimensions? TODO: Find out what this class doe...
Definition: dpdimsave.hxx:160
XML_DISPLAY
SC_DLLPUBLIC size_t GetCount() const
Definition: dpobject.cxx:3677
XML_HOURS
SCROW Row() const
Definition: address.hxx:262
static bool convertBool(bool &rBool, const OUString &rString)
SC_DLLPUBLIC const std::optional< OUString > & GetGrandTotalName() const
Definition: dpsave.cxx:771
XML_BOTTOM_PERCENT
void WriteGroupDimAttributes(const ScDPSaveGroupDimension *pGroupDim)
XML_SQL_STATEMENT
XML_ASCENDING
XML_NAMED
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_COLUMN
XML_FIELD_NUMBER
XML_NAME
XML_ORDER
void WriteLevels(const ScDPSaveDimension *pDim)
const SvXMLUnitConverter & GetMM100UnitConverter() const
void CheckAttrList()
const css::sheet::DataPilotFieldLayoutInfo * GetLayoutInfo() const
Definition: dpsave.hxx:194
XML_ORIENTATION
long GetUsedHierarchy() const
Definition: dpsave.hxx:169
Classes to save Data Pilot settings that create new dimensions (fields).
Definition: dpdimsave.hxx:43
const OUString & GetGroupName() const
Definition: dpdimsave.hxx:62
bool HasPivotButton() const
Definition: attrib.cxx:147
XML_IGNORE_SELECTED_PAGE
SC_DLLPUBLIC ScDPCollection * GetDPCollection()
Definition: documen3.cxx:346
void WriteDatePart(sal_Int32 nPart)
XML_VALUE
const OUString & GetSourceDimName() const
Definition: dpdimsave.hxx:105
XML_DATABASE_SOURCE_QUERY
XML_ROW_PERCENTAGE
XML_IDENTIFY_CATEGORIES
void WriteSortInfo(const ScDPSaveDimension *pDim)
XML_DATA_PILOT_SUBTOTALS
void WriteDimensions(const ScDPSaveData *pDPSave)
SCCOLROW nField
Definition: queryentry.hxx:51
ScAddress aEnd
Definition: address.hxx:501
long GetSubTotalsCount() const
Definition: dpsave.hxx:149
XML_DATABASE_TABLE_NAME
XML_EMPTY
sal_Int32 GetDatePart() const
Definition: dpdimsave.hxx:149
bool IsQueryByEmpty() const
Definition: queryentry.cxx:84
bool IsDataLayout() const
Definition: dpsave.hxx:142
XML_FIELD_NAME
const ScDPNumGroupInfo & GetDateInfo() const
Definition: dpdimsave.hxx:150
XML_SECONDS
OUString aParSource
Definition: dpobject.hxx:72
XML_INDEX
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_MEMBER_PERCENTAGE
XML_DESCENDING
const Item & GetQueryItem() const
Definition: queryentry.cxx:118
XML_CELL_RANGE_ADDRESS
long GetGroupCount() const
Definition: dpdimsave.cxx:200
XML_DATABASE_SOURCE_SQL
const ScDPSaveGroupDimension * GetNamedGroupDim(const OUString &rGroupDimName) const
Definition: dpdimsave.cxx:637
XML_ROW
XML_DATA_PILOT_SORT_INFO
XML_FILTER_CONDITION
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:45
XML_FILTER_OR
void WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const std::optional< OUString > &pGrandTotal)
XML_OUTLINE_SUBTOTALS_TOP
int nCount
XML_TYPE
XML_DATA_PILOT_SUBTOTAL
SC_DLLPUBLIC SCSIZE GetEntryCount() const
Definition: queryparam.cxx:119
void AddAttribute(sal_uInt16 nPrefix, const char *pName, const OUString &rValue)
void StartElement(sal_uInt16 nPrefix, enum::xmloff::token::XMLTokenEnum eName, bool bIgnWSOutside)
SC_DLLPUBLIC const ScQueryEntry & GetEntry(SCSIZE n) const
Definition: queryparam.cxx:124
XML_SELECTED_PAGE
SCTAB Tab() const
Definition: address.hxx:271
XML_MEMBER_DIFFERENCE
SC_DLLPUBLIC const ScRange & GetSourceRange() const
Get the range that contains the source data.
Definition: dpshttab.cxx:229
ScGeneralFunction GetFunction() const
Definition: dpsave.hxx:165
bool HasShowEmpty() const
Definition: dpsave.cxx:328
XML_DATE_END
XML_QUERY_NAME
bool GetIgnoreEmptyRows() const
Definition: dpsave.hxx:330
XML_NOEMPTY
sal_Int32 GetDatePart() const
Definition: dpdimsave.hxx:107
size_t GetElementCount() const
Definition: dpdimsave.cxx:73
XML_FALSE
XML_MINUTES
const char * sName
void WriteMembers(const ScDPSaveDimension *pDim)
std::vector< ScDPSaveMember * > MemberList
Definition: dpsave.hxx:115
XML_OBJECT_NAME
bool GetRepeatItemLabels() const
Definition: dpsave.hxx:161
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:70
XML_DATA
XML_CASE_SENSITIVE
const ScQueryParam & GetQueryParam() const
Definition: dpshttab.hxx:63
OUString aParUser
Definition: dpobject.hxx:74
bool GetDrillDown() const
Definition: dpsave.hxx:342
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
XML_DATA_PILOT_GROUP
XML_FILTER_AND
XML_YEARS
XML_PARSE_SQL_STATEMENT
const ScDPSaveGroupItem & GetGroupByIndex(long nIndex) const
Definition: dpdimsave.cxx:205
const css::sheet::DataPilotFieldSortInfo * GetSortInfo() const
Definition: dpsave.hxx:186
void WriteDPFilter(const ScQueryParam &aQueryParam)
const OUString * GetElementByIndex(size_t nIndex) const
Definition: dpdimsave.cxx:78
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:132
bool IsQueryByNonEmpty() const
Definition: queryentry.cxx:106
sal_Int16 SCCOL
Definition: types.hxx:22
XML_PREVIOUS
XML_DATA_PILOT_TABLES
XML_HEADER_GRID_LAYOUT
XML_DATA_FIELD
XML_DRILL_DOWN_ON_DOUBLE_CLICK
void WriteNumGroupInfo(const ScDPNumGroupInfo &pGroupInfo)
static SC_DLLPUBLIC OUString getSourceDimensionName(const OUString &rName)
Definition: dputil.cxx:64
XML_DATA_PILOT_GROUP_MEMBER
XML_MONTHS
void convertDateTime(OUStringBuffer &rBuffer, const double &fDateTime, bool const bAddTimeIf0AM=false)
XML_MEMBER_PERCENTAGE_DIFFERENCE
XML_BOTH
bool GetRepeatIfEmpty() const
Definition: dpsave.hxx:334
XML_TOP_PERCENT
XML_DATABASE_NAME
XML_STEP
XML_MEMBER_NAME
XML_SHOW_EMPTY
const ScDPNumGroupInfo & GetDateInfo() const
Definition: dpdimsave.hxx:108
XML_DAYS
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
XML_DATA_PILOT_LEVEL
XML_TABULAR_LAYOUT
void WriteSubTotals(const ScDPSaveDimension *pDim)
OUString GetCurrentPage() const
Definition: dpsave.cxx:438
XML_FROM_TOP
XML_TOP_VALUES
OUString aDBName
Definition: dpsdbtab.hxx:36
svl::SharedString maString
Definition: queryentry.hxx:41
const SvXMLNamespaceMap & GetNamespaceMap() const
SCCOL Col() const
Definition: address.hxx:267
const std::optional< OUString > & GetSubtotalName() const
Definition: dpsave.cxx:358
bool GetFilterButton() const
Definition: dpsave.hxx:338
XML_IS_DATA_LAYOUT_FIELD
XML_SHOW_DETAILS
css::sheet::DataImportMode nType
Definition: dpsdbtab.hxx:38
XML_DATA_TYPE
OUString aObject
Definition: dpsdbtab.hxx:37
XML_SOURCE_CELL_RANGE
bool HasRangeName() const
Definition: dpshttab.cxx:264
XML_MEMBER_COUNT
bool GetColumnGrand() const
Definition: dpsave.hxx:322
XML_BOTTOM_VALUES
XML_NEXT
XML_SHOW_FILTER_BUTTON
ScDocument * GetDocument()
Definition: xmlexprt.hxx:240
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
XML_USER_NAME
sal_Int32 SCROW
Definition: types.hxx:18
void WriteGroupDimElements(const ScDPSaveDimension *pDim, const ScDPDimensionSaveData *pDimData)
XML_DATA_PILOT_MEMBERS
XML_MANUAL
const DimsType & GetDimensions() const
Definition: dpsave.hxx:270
void EndElement(sal_uInt16 nPrefix, enum::xmloff::token::XMLTokenEnum eName, bool bIgnWSInside)
XML_BUTTONS
XML_OPERATOR
XML_COLUMN_PERCENTAGE
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
XML_NUMBER
OUString aParName
Definition: dpobject.hxx:73
void WriteDimension(const ScDPSaveDimension *pDim, const ScDPDimensionSaveData *pDimData)
XML_FILTER
OUString aServiceName
Definition: dpobject.hxx:71
bool GetShowEmpty() const
Definition: dpsave.hxx:157
constexpr sal_uInt16 XML_NAMESPACE_TABLE
OUString aName
const OUString & GetName() const
Definition: dpsave.hxx:139
std::vector< std::unique_ptr< ScDPSaveDimension > > DimsType
Definition: dpsave.hxx:238
XML_SOURCE_FIELD_NAME
XML_NOMATCH
XML_DISPLAY_MEMBER_MODE
Represents a new group dimension whose dimension ID is higher than the highest source dimension ID...
Definition: dpdimsave.hxx:87
const OUString & GetRangeName() const
Definition: dpshttab.hxx:60
XML_START
XML_APPLICATION_DATA
XML_DATA_PILOT_TABLE
XML_DATA_PILOT_FIELD
const css::sheet::DataPilotFieldAutoShowInfo * GetAutoShowInfo() const
Definition: dpsave.hxx:190
XML_TARGET_RANGE_ADDRESS
XML_DATA_PILOT_FIELD_REFERENCE
XML_ENABLED
XML_SOURCE_NAME
ScQueryConnect eConnect
Definition: queryentry.hxx:53
ScXMLExportDataPilot(ScXMLExport &rExport)
constexpr sal_uInt16 XML_NAMESPACE_TABLE_EXT
ScQueryOp
Definition: global.hxx:821
XML_OUTLINE_SUBTOTALS_BOTTOM
XML_SORT_MODE
XML_NONE
XML_TRUE
const ScDPNumGroupInfo & GetInfo() const
Definition: dpdimsave.hxx:147
XML_FROM_BOTTOM
XML_CONDITION_SOURCE_RANGE_ADDRESS
static void GetStringFromFunction(OUString &rString, const sal_Int16 eFunction)
void WriteNumGroupDim(const ScDPSaveNumGroupDimension *pNumGroupDim)
XML_DATE_START
XML_MATCH
XML_RUNNING_TOTAL
XML_USED_HIERARCHY
constexpr sal_uInt16 XML_NAMESPACE_CALC_EXT
const ScDPSaveNumGroupDimension * GetNumGroupDim(const OUString &rGroupDimName) const
Definition: dpdimsave.cxx:652
void WriteLayoutInfo(const ScDPSaveDimension *pDim)
XML_IGNORE_EMPTY_ROWS
XML_ADD_EMPTY_LINES
XML_END
XML_SOURCE_SERVICE
XML_QUARTERS
XML_FUNCTION
const SCTAB SCTAB_MAX
Definition: address.hxx:58
XML_GRAND_TOTAL
static OUString getDPOperatorXML(const ScQueryOp aFilterOperator, const utl::SearchParam::SearchType eSearchType)
XML_DATA_PILOT_MEMBER
ScQueryOp eOp
Definition: queryentry.hxx:52
css::uno::Any const SvXMLExport & rExport
XML_AUTO
This class contains authoritative information on the internal reference used as the data source for d...
Definition: dpshttab.hxx:39
XML_DATA_PILOT_DISPLAY_INFO
XML_REPEAT_ITEM_LABELS
XML_DATABASE_SOURCE_TABLE
XML_GROUPED_BY
XML_TOTAL_PERCENTAGE
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)
utl::SearchParam::SearchType eSearchType
Definition: queryparam.hxx:44
const css::sheet::DataPilotFieldReference * GetReferenceValue() const
Definition: dpsave.hxx:181
XML_DATA_PILOT_LAYOUT_INFO
static void GetStringFromOrientation(OUString &rString, const css::sheet::DataPilotFieldOrientation eOrientation)
ScGeneralFunction GetSubTotalFunc(long nIndex) const
Definition: dpsave.hxx:152
XML_DISPLAY_DUPLICATES
XML_LAYOUT_MODE
ScQueryConnect
Definition: global.hxx:841