28#include <osl/diagnose.h>
32#include <document.hxx>
38#include <stlsheet.hxx>
40#include <unonames.hxx>
45#include <com/sun/star/beans/XPropertySet.hpp>
46#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
47#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
48#include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
49#include <com/sun/star/sheet/DataPilotTableResultData.hpp>
50#include <com/sun/star/sheet/MemberResultFlags.hpp>
51#include <com/sun/star/sheet/DataResultFlags.hpp>
52#include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
53#include <com/sun/star/sheet/GeneralFunction2.hpp>
54#include <com/sun/star/sheet/MemberResult.hpp>
55#include <com/sun/star/sheet/XDataPilotMemberResults.hpp>
56#include <com/sun/star/sheet/XDataPilotResults.hpp>
57#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
58#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
59#include <com/sun/star/sheet/XLevelsSupplier.hpp>
60#include <com/sun/star/sheet/XMembersAccess.hpp>
61#include <com/sun/star/sheet/XMembersSupplier.hpp>
62#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
63#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
73using ::com::sun::star::beans::XPropertySet;
74using ::com::sun::star::uno::Sequence;
75using ::com::sun::star::uno::UNO_QUERY;
76using ::com::sun::star::uno::Reference;
77using ::com::sun::star::sheet::DataPilotTablePositionData;
78using ::com::sun::star::sheet::DataPilotTableResultData;
80#define SC_DP_FRAME_INNER_BOLD 20
81#define SC_DP_FRAME_OUTER_BOLD 40
83#define SC_DP_FRAME_COLOR Color(0,0,0)
100 OUString aName, OUString aCaption,
bool bHasHiddenMember,
bool bDataLayout,
bool bPageDim) :
113 struct ScDPOutLevelDataComparator
127 ::std::vector< bool > mbNeedLineCols;
128 ::std::vector< SCCOL > mnCols;
130 ::std::vector< bool > mbNeedLineRows;
131 ::std::vector< SCROW > mnRows;
136 SCCOL mnDataStartCol;
137 SCROW mnDataStartRow;
142 ScDPOutputImpl(
ScDocument* pDoc, sal_uInt16 nTab,
149 bool AddRow(
SCROW nRow );
150 bool AddCol(
SCCOL nCol );
152 void OutputDataArea();
153 void OutputBlockFrame (
SCCOL nStartCol,
SCROW nStartRow,
SCCOL nEndCol,
SCROW nEndRow,
bool bHori =
false );
157void ScDPOutputImpl::OutputDataArea()
159 AddRow( mnDataStartRow );
160 AddCol( mnDataStartCol );
162 mnCols.push_back( mnTabEndCol+1);
163 mnRows.push_back( mnTabEndRow+1);
165 bool bAllRows = ( ( mnTabEndRow - mnDataStartRow + 2 ) ==
static_cast<SCROW>(mnRows.size()) );
167 std::sort( mnCols.begin(), mnCols.end());
168 std::sort( mnRows.begin(), mnRows.end());
170 for(
SCCOL nCol = 0; nCol < static_cast<SCCOL>(mnCols.size())-1; nCol ++ )
174 if ( nCol <
static_cast<SCCOL>(mnCols.size())-2)
176 for (
SCROW i = nCol%2; i < static_cast<SCROW>(mnRows.size())-2;
i +=2 )
177 OutputBlockFrame( mnCols[nCol], mnRows[i], mnCols[nCol+1]-1, mnRows[i+1]-1 );
178 if ( mnRows.size()>=2 )
179 OutputBlockFrame( mnCols[nCol], mnRows[mnRows.size()-2], mnCols[nCol+1]-1, mnRows[mnRows.size()-1]-1 );
183 for (
SCROW i = 0 ; i < static_cast<SCROW>(mnRows.size())-1;
i++ )
184 OutputBlockFrame( mnCols[nCol], mnRows[i], mnCols[nCol+1]-1, mnRows[i+1]-1 );
188 OutputBlockFrame( mnCols[nCol], mnRows.front(), mnCols[nCol+1]-1, mnRows.back()-1, bAllRows );
191 if ( mnTabStartCol != mnDataStartCol )
193 if ( mnTabStartRow != mnDataStartRow )
194 OutputBlockFrame( mnTabStartCol, mnTabStartRow, mnDataStartCol-1, mnDataStartRow-1 );
195 OutputBlockFrame( mnTabStartCol, mnDataStartRow, mnDataStartCol-1, mnTabEndRow );
198 OutputBlockFrame( mnDataStartCol, mnTabStartRow, mnTabEndCol, mnDataStartRow-1 );
201ScDPOutputImpl::ScDPOutputImpl(
ScDocument* pDoc, sal_uInt16 nTab,
210 mnTabStartCol( nTabStartCol ),
211 mnTabStartRow( nTabStartRow ),
212 mnDataStartCol ( nDataStartCol ),
213 mnDataStartRow ( nDataStartRow ),
214 mnTabEndCol( nTabEndCol ),
215 mnTabEndRow( nTabEndRow )
217 mbNeedLineCols.resize( nTabEndCol-nDataStartCol+1,
false );
218 mbNeedLineRows.resize( nTabEndRow-nDataStartRow+1,
false );
222bool ScDPOutputImpl::AddRow(
SCROW nRow )
224 if ( !mbNeedLineRows[ nRow - mnDataStartRow ] )
226 mbNeedLineRows[ nRow - mnDataStartRow ] =
true;
227 mnRows.push_back( nRow );
234bool ScDPOutputImpl::AddCol(
SCCOL nCol )
237 if ( !mbNeedLineCols[ nCol - mnDataStartCol ] )
239 mbNeedLineCols[ nCol - mnDataStartCol ] =
true;
240 mnCols.push_back( nCol );
247void ScDPOutputImpl::OutputBlockFrame (
SCCOL nStartCol,
SCROW nStartRow,
SCCOL nEndCol,
SCROW nEndRow,
bool bHori )
255 if ( nStartCol == mnTabStartCol )
256 aBox.SetLine(&aOutLine, SvxBoxItemLine::LEFT);
258 aBox.SetLine(&aLine, SvxBoxItemLine::LEFT);
260 if ( nStartRow == mnTabStartRow )
261 aBox.SetLine(&aOutLine, SvxBoxItemLine::TOP);
263 aBox.SetLine(&aLine, SvxBoxItemLine::TOP);
265 if ( nEndCol == mnTabEndCol )
266 aBox.SetLine(&aOutLine, SvxBoxItemLine::RIGHT);
268 aBox.SetLine(&aLine, SvxBoxItemLine::RIGHT);
270 if ( nEndRow == mnTabEndRow )
271 aBox.SetLine(&aOutLine, SvxBoxItemLine::BOTTOM);
273 aBox.SetLine(&aLine, SvxBoxItemLine::BOTTOM);
276 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::VERT,
false );
279 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::HORI);
280 aBoxInfo.SetLine( &aLine, SvxBoxInfoItemLine::HORI );
283 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::HORI,
false );
285 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::DISTANCE,
false);
287 mpDoc->ApplyFrameAreaTab(
ScRange(nStartCol, nStartRow, mnTab, nEndCol, nEndRow , mnTab), aBox, aBoxInfo);
295 if ( nCol1 > nCol2 || nRow1 > nRow2 )
297 OSL_FAIL(
"SetStyleById: invalid range");
301 OUString aStyleName =
ScResId(pStrId);
308 pStyle =
static_cast<ScStyleSheet*
>( &pStlPool->
Make( aStyleName, SfxStyleFamily::Para,
309 SfxStyleSearchBits::UserDefined ) );
312 if (pStrId == STR_PIVOT_STYLENAME_RESULT || pStrId == STR_PIVOT_STYLENAME_TITLE){
317 if (pStrId == STR_PIVOT_STYLENAME_CATEGORY || pStrId == STR_PIVOT_STYLENAME_TITLE)
330 aBox.SetLine(&aLine, SvxBoxItemLine::LEFT);
331 aBox.SetLine(&aLine, SvxBoxItemLine::TOP);
332 aBox.SetLine(&aLine, SvxBoxItemLine::RIGHT);
333 aBox.SetLine(&aLine, SvxBoxItemLine::BOTTOM);
335 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::HORI,
false);
336 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::VERT,
false);
337 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::DISTANCE,
false);
342void lcl_FillNumberFormats( std::unique_ptr<sal_uInt32[]>& rFormats, sal_Int32& rCount,
343 const uno::Reference<sheet::XDataPilotMemberResults>& xLevRes,
344 const uno::Reference<container::XIndexAccess>& xDims )
352 uno::Sequence<sheet::MemberResult> aResult = xLevRes->getResults();
361 std::vector <OUString> aDataNames;
362 std::vector <sal_uInt32> aDataFormats;
367 uno::Reference<uno::XInterface> xDim(xDims->getByIndex(nDim), uno::UNO_QUERY);
368 uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
369 uno::Reference<container::XNamed> xDimName( xDim, uno::UNO_QUERY );
370 if ( xDimProp.is() && xDimName.is() )
372 sheet::DataPilotFieldOrientation eDimOrient =
375 sheet::DataPilotFieldOrientation_HIDDEN );
376 if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
378 aDataNames.push_back(xDimName->getName());
382 aDataFormats.push_back(nFormat);
387 if (aDataFormats.empty())
390 const sheet::MemberResult* pArray = aResult.getConstArray();
393 sal_uInt32* pNumFmt =
new sal_uInt32[nSize];
394 if (aDataFormats.size() == 1)
399 pNumFmt[nPos] = nFormat;
407 if ( !(pArray[nPos].Flags & sheet::MemberResultFlags::CONTINUE) )
410 sal_uInt32 nFormat = 0;
411 for (
size_t i=0;
i<aDataFormats.size();
i++)
412 if (aName == aDataNames[i])
414 nFormat = aDataFormats[
i];
417 pNumFmt[
nPos] = nFormat;
421 rFormats.reset( pNumFmt );
425sal_uInt32 lcl_GetFirstNumberFormat(
const uno::Reference<container::XIndexAccess>& xDims )
430 uno::Reference<beans::XPropertySet> xDimProp(xDims->getByIndex(nDim), uno::UNO_QUERY);
433 sheet::DataPilotFieldOrientation eDimOrient =
436 sheet::DataPilotFieldOrientation_HIDDEN );
437 if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
451bool lcl_MemberEmpty(
const uno::Sequence<sheet::MemberResult>& rSeq )
455 return std::none_of(rSeq.begin(), rSeq.end(),
456 [](
const sheet::MemberResult& rMem) {
457 return rMem.Flags & sheet::MemberResultFlags::HASMEMBER; });
464uno::Sequence<sheet::MemberResult> getVisiblePageMembersAsResults(
const uno::Reference<uno::XInterface>& xLevel )
467 return uno::Sequence<sheet::MemberResult>();
469 uno::Reference<sheet::XMembersSupplier> xMSupplier(xLevel, UNO_QUERY);
470 if (!xMSupplier.is())
471 return uno::Sequence<sheet::MemberResult>();
473 uno::Reference<sheet::XMembersAccess> xNA = xMSupplier->getMembers();
475 return uno::Sequence<sheet::MemberResult>();
477 std::vector<sheet::MemberResult> aRes;
478 const uno::Sequence<OUString> aNames = xNA->getElementNames();
479 for (
const OUString& rName : aNames)
481 xNA->getByName(rName);
483 uno::Reference<beans::XPropertySet> xMemPS(xNA->getByName(rName), UNO_QUERY);
488 if (aCaption.isEmpty())
496 aRes.emplace_back(rName, aCaption, 0, std::numeric_limits<double>::quiet_NaN());
502 return uno::Sequence<sheet::MemberResult>();
510 const ScAddress& rPos,
bool bFilter,
bool bExpandCollapse ) :
512 xSource(
std::move( xSrc )),
522 bResultsError(false),
524 bSizeOverflow(false),
525 mbHeaderLayout(false),
526 mbHasCompactRowField(false),
527 mbExpandCollapse(bExpandCollapse)
532 uno::Reference<sheet::XDataPilotResults> xResult(
xSource, uno::UNO_QUERY );
533 if (
xSource.is() && xResult.is() )
537 uno::Reference<container::XIndexAccess> xDims =
542 uno::Reference<uno::XInterface> xDim(xDims->getByIndex(nDim), uno::UNO_QUERY);
543 uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
544 uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDim, uno::UNO_QUERY );
545 if ( xDimProp.is() && xDimSupp.is() )
547 sheet::DataPilotFieldOrientation eDimOrient =
550 sheet::DataPilotFieldOrientation_HIDDEN );
560 if ( eDimOrient != sheet::DataPilotFieldOrientation_HIDDEN )
562 uno::Reference<container::XIndexAccess> xHiers =
567 if ( nHierarchy >= xHiers->getCount() )
570 uno::Reference<sheet::XLevelsSupplier> xHierSupp(xHiers->getByIndex(nHierarchy),
572 if ( xHierSupp.is() )
574 uno::Reference<container::XIndexAccess> xLevels =
579 uno::Reference<uno::XInterface> xLevel(xLevels->getByIndex(nLev),
581 uno::Reference<container::XNamed> xLevNam( xLevel, uno::UNO_QUERY );
582 uno::Reference<sheet::XDataPilotMemberResults> xLevRes(
583 xLevel, uno::UNO_QUERY );
584 if ( xLevNam.is() && xLevRes.is() )
586 OUString
aName = xLevNam->getName();
587 Reference<XPropertySet> xPropSet(xLevel, UNO_QUERY);
594 switch ( eDimOrient )
596 case sheet::DataPilotFieldOrientation_COLUMN:
598 uno::Sequence<sheet::MemberResult> aResult = xLevRes->getResults();
599 if (!lcl_MemberEmpty(aResult))
602 aCaption, bHasHiddenMember, bIsDataLayout,
false);
607 case sheet::DataPilotFieldOrientation_ROW:
609 uno::Sequence<sheet::MemberResult> aResult = xLevRes->getResults();
614 bool bSkip = lcl_MemberEmpty(aResult) && bIsDataLayout;
617 bool bFieldCompact =
false;
622 bFieldCompact = (
aLayoutInfo.LayoutMode == sheet::DataPilotFieldLayoutMode::COMPACT_LAYOUT);
624 catch (uno::Exception&)
628 aCaption, bHasHiddenMember, bIsDataLayout,
false);
636 case sheet::DataPilotFieldOrientation_PAGE:
638 uno::Sequence<sheet::MemberResult> aResult = getVisiblePageMembersAsResults(xLevel);
641 aCaption, bHasHiddenMember,
false,
true);
654 OSL_ENSURE( nLevCount == 1,
"data layout: multiple levels?" );
655 if ( eDimOrient == sheet::DataPilotFieldOrientation_COLUMN )
657 else if ( eDimOrient == sheet::DataPilotFieldOrientation_ROW )
664 else if ( bIsDataLayout )
681 aData = xResult->getResults();
683 catch (
const uno::RuntimeException&)
691 uno::Reference<beans::XPropertySet> xSrcProp(
xSource, uno::UNO_QUERY );
692 if ( !xSrcProp.is() )
702 catch(
const uno::Exception&)
720 if ( nFlags & sheet::DataResultFlags::ERROR )
722 pDoc->
SetError( nCol, nRow, nTab, FormulaError::NoValue );
724 else if ( nFlags & sheet::DataResultFlags::HASDATA )
730 OSL_ENSURE(
bSizesValid,
"DataCell: !bSizesValid" );
731 sal_uInt32 nFormat = 0;
732 bool bApplyFormat =
false;
770 const sheet::MemberResult& rData,
bool bColHeader,
tools::Long nLevel )
774 if ( nFlags & sheet::MemberResultFlags::HASMEMBER )
776 bool bNumeric = (nFlags & sheet::MemberResultFlags::NUMERIC) != 0;
777 if (bNumeric && std::isfinite( rData.Value))
793 if ( !(nFlags & sheet::MemberResultFlags::SUBTOTAL) )
796 ScDPOutputImpl outputimp(
pDoc, nTab,
805 STR_PIVOT_STYLENAME_TITLE );
807 STR_PIVOT_STYLENAME_RESULT );
813 STR_PIVOT_STYLENAME_TITLE );
815 STR_PIVOT_STYLENAME_RESULT );
821 pDoc->
SetString(nCol, nRow, nTab,
ScResId(bRowField ? STR_PIVOT_ROW_LABELS : STR_PIVOT_COL_LABELS));
826 if (rData.mbHasHiddenMember)
836 lcl_SetStyleById(
pDoc, nTab, nCol, nRow, nCol, nRow, STR_PIVOT_STYLENAME_FIELDNAME );
850 lcl_SetFrame(
pDoc,nTab, nCol,nRow, nCol,nRow, 20 );
871 lcl_SetStyleById(
pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLENAME_FIELDNAME );
905 const uno::Sequence<sheet::DataResult>* pRowAry =
aData.getConstArray();
957 return DataPilotTablePositionType::NOT_IN_TABLE;
963 return DataPilotTablePositionType::NOT_IN_TABLE;
967 return DataPilotTablePositionType::RESULT;
972 if (bInColHeader && bInRowHeader)
974 return DataPilotTablePositionType::OTHER;
981 return DataPilotTablePositionType::OTHER;
989 return DataPilotTablePositionType::OTHER;
995 const uno::Sequence<sheet::DataResult>* pRowAry =
aData.getConstArray();
1013 for (
size_t nField=0; nField<
pPageFields.size(); ++nField)
1019 SCCOL nFldCol = nHdrCol + 1;
1021 OUString aPageValue =
ScResId(SCSTR_ALL);
1022 const uno::Sequence<sheet::MemberResult>& rRes =
pPageFields[nField].maResult;
1023 sal_Int32
n = rRes.getLength();
1026 if (rRes[0].
Caption.isEmpty())
1027 aPageValue =
ScResId(STR_EMPTYDATA);
1029 aPageValue = rRes[0].Caption;
1032 aPageValue =
ScResId(SCSTR_MULTIPLE);
1036 pDoc->
SetString(nFldCol, nHdrRow, nTab, aPageValue, &aParam);
1038 lcl_SetFrame(
pDoc,nTab, nFldCol,nHdrRow, nFldCol,nHdrRow, 20 );
1054 STR_PIVOT_STYLENAME_TOP );
1056 STR_PIVOT_STYLENAME_INNER );
1059 ScDPOutputImpl outputimp(
pDoc, nTab,
1063 for (
size_t nField=0; nField<nNumColFields; nField++)
1072 const uno::Sequence<sheet::MemberResult> rSequence =
pColFields[nField].maResult;
1073 const sheet::MemberResult* pArray = rSequence.getConstArray();
1074 tools::Long nThisColCount = rSequence.getLength();
1075 OSL_ENSURE( nThisColCount ==
nColCount,
"count mismatch" );
1076 for (
tools::Long nCol=0; nCol<nThisColCount; nCol++)
1079 HeaderCell( nColPos, nRowPos, nTab, pArray[nCol],
true, nField );
1080 if ( ( pArray[nCol].
Flags & sheet::MemberResultFlags::HASMEMBER ) &&
1081 !( pArray[nCol].
Flags & sheet::MemberResultFlags::SUBTOTAL ) )
1084 while ( nEnd+1 < nThisColCount && ( pArray[nEnd+1].
Flags & sheet::MemberResultFlags::CONTINUE ) )
1091 outputimp.AddCol( nColPos );
1092 if ( nColPos + 1 == nEndColPos )
1093 outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos+1,
true );
1096 outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos );
1098 lcl_SetStyleById(
pDoc, nTab, nColPos,nRowPos, nEndColPos,
nDataStartRow-1, STR_PIVOT_STYLENAME_CATEGORY );
1101 lcl_SetStyleById(
pDoc, nTab, nColPos,nRowPos, nColPos,
nDataStartRow-1, STR_PIVOT_STYLENAME_CATEGORY );
1103 else if ( pArray[nCol].
Flags & sheet::MemberResultFlags::SUBTOTAL )
1104 outputimp.AddCol( nColPos );
1114 std::vector<bool> vbSetBorder;
1116 size_t nFieldColOffset = 0;
1117 size_t nFieldIndentLevel = 0;
1119 for (
size_t nField=0; nField<nNumRowFields; nField++)
1130 const uno::Sequence<sheet::MemberResult> rSequence =
pRowFields[nField].maResult;
1131 const sheet::MemberResult* pArray = rSequence.getConstArray();
1132 sal_Int32 nThisRowCount = rSequence.getLength();
1133 OSL_ENSURE( nThisRowCount ==
nRowCount,
"count mismatch" );
1134 for (sal_Int32 nRow=0; nRow<nThisRowCount; nRow++)
1136 const sheet::MemberResult& rData = pArray[nRow];
1137 const bool bHasMember = (rData.Flags & sheet::MemberResultFlags::HASMEMBER);
1138 const bool bSubtotal = (rData.Flags & sheet::MemberResultFlags::SUBTOTAL);
1140 HeaderCell( nColPos, nRowPos, nTab, rData,
false, nFieldColOffset );
1141 if (bHasMember && !bSubtotal)
1146 while ( nEnd+1 < nThisRowCount && ( pArray[nEnd+1].
Flags & sheet::MemberResultFlags::CONTINUE ) )
1149 outputimp.AddRow( nRowPos );
1150 if ( !vbSetBorder[ nRow ] )
1152 outputimp.OutputBlockFrame( nColPos, nRowPos,
nTabEndCol, nEndRowPos );
1153 vbSetBorder[ nRow ] =
true;
1155 outputimp.OutputBlockFrame( nColPos, nRowPos, nColPos, nEndRowPos );
1158 outputimp.OutputBlockFrame( nColPos+1, nRowPos, nColPos+1, nEndRowPos );
1160 lcl_SetStyleById(
pDoc, nTab, nColPos, nRowPos,
nDataStartCol-1,nEndRowPos, STR_PIVOT_STYLENAME_CATEGORY );
1164 lcl_SetStyleById(
pDoc, nTab, nColPos, nRowPos,
nDataStartCol-1,nRowPos, STR_PIVOT_STYLENAME_CATEGORY );
1169 bool bLast =
nRowDims == (nField + 1);
1172 bool bHasContinue = (!bLast && nRow + 1 < nThisRowCount
1173 && (pArray[nRow + 1].Flags & sheet::MemberResultFlags::CONTINUE));
1183 else if ( bSubtotal )
1184 outputimp.AddRow( nRowPos );
1194 nFieldIndentLevel = 0;
1198 ++nFieldIndentLevel;
1213 for (sal_Int32 nRow=0; nRow<
nRowCount; nRow++)
1216 const sheet::DataResult* pColAry = pRowAry[nRow].getConstArray();
1217 sal_Int32 nThisColCount = pRowAry[nRow].getLength();
1218 OSL_ENSURE( nThisColCount ==
nColCount,
"count mismatch" );
1219 for (sal_Int32 nCol=0; nCol<nThisColCount; nCol++)
1222 DataCell( nColPos, nRowPos, nTab, pColAry[nCol] );
1226 outputimp.OutputDataArea();
1236 switch (nRegionType)
1238 case DataPilotOutputRangeType::RESULT:
1243 OSL_ENSURE(nRegionType == DataPilotOutputRangeType::WHOLE,
"ScDPOutput::GetOutputRange: unknown region type");
1263 void insertNames(
ScDPUniqueStringSet& rNames,
const uno::Sequence<sheet::MemberResult>& rMemberResults)
1265 for (
const sheet::MemberResult& rMemberResult : rMemberResults)
1267 if (rMemberResult.Flags & sheet::MemberResultFlags::HASMEMBER)
1268 rNames.insert(rMemberResult.Name);
1279 auto lFindDimension = [nDimension](
const ScDPOutLevelData& rField) {
return rField.mnDim == nDimension; };
1286 insertNames(rNames, colit->maResult);
1295 insertNames(rNames, rowit->maResult);
1307void lcl_GetTableVars( sal_Int32& rGrandTotalCols, sal_Int32& rGrandTotalRows, sal_Int32& rDataLayoutIndex,
1308 std::vector<OUString>& rDataNames, std::vector<OUString>& rGivenNames,
1309 sheet::DataPilotFieldOrientation& rDataOrient,
1310 const uno::Reference<sheet::XDimensionsSupplier>& xSource )
1312 rDataLayoutIndex = -1;
1313 rGrandTotalCols = 0;
1314 rGrandTotalRows = 0;
1315 rDataOrient = sheet::DataPilotFieldOrientation_HIDDEN;
1317 uno::Reference<beans::XPropertySet> xSrcProp( xSource, uno::UNO_QUERY );
1321 rGrandTotalCols = 1;
1326 rGrandTotalRows = 1;
1328 if ( !xSource.is() )
1333 sal_Int32 nDataCount = 0;
1335 uno::Reference<container::XIndexAccess> xDims =
new ScNameToIndexAccess( xSource->getDimensions() );
1339 uno::Reference<uno::XInterface> xDim(xDims->getByIndex(nDim), uno::UNO_QUERY);
1340 uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1341 if ( xDimProp.is() )
1343 sheet::DataPilotFieldOrientation eDimOrient =
1346 sheet::DataPilotFieldOrientation_HIDDEN );
1350 rDataLayoutIndex = nDim;
1351 rDataOrient = eDimOrient;
1353 if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
1355 OUString aSourceName;
1356 OUString aGivenName;
1364 OUString strLayoutName;
1366 if( ( aValue >>= strLayoutName ) && !strLayoutName.isEmpty() )
1367 aGivenName = strLayoutName;
1370 catch(
const uno::Exception&)
1373 rDataNames.push_back( aSourceName );
1374 rGivenNames.push_back( aGivenName );
1381 if ( ( rDataOrient == sheet::DataPilotFieldOrientation_COLUMN ) && bColGrand )
1382 rGrandTotalCols = nDataCount;
1383 else if ( ( rDataOrient == sheet::DataPilotFieldOrientation_ROW ) && bRowGrand )
1384 rGrandTotalRows = nDataCount;
1393 nRowFieldStart = nCol;
1394 nRowFieldEnd = nCol + 1;
1400 nRowFieldStart = nRowFieldEnd = 0;
1404 nRowFieldStart = -1;
1407 sal_Int32 nField = 0;
1411 if (nCurCol == nCol && nRowFieldStart == -1)
1412 nRowFieldStart = nField;
1419 if (nCurCol == (nCol + 1) && nRowFieldStart != -1 && nRowFieldEnd == -1)
1421 nRowFieldEnd = nField;
1426 if (nRowFieldStart != -1 && nRowFieldEnd == -1 && nCurCol == nCol)
1429 if (nRowFieldStart == -1 || nRowFieldEnd == -1)
1431 SAL_WARN(
"sc.core",
"ScDPOutput::GetRowFieldRange : unable to find field range for nCol = " << nCol);
1432 nRowFieldStart = nRowFieldEnd = 0;
1442 sal_Int32 nStartField = 0;
1443 sal_Int32 nEndField = 0;
1446 for (sal_Int32 nField = nEndField - 1; nField >= nStartField; --nField)
1448 const uno::Sequence<sheet::MemberResult> rSequence =
pRowFields[nField].maResult;
1449 const sheet::MemberResult* pArray = rSequence.getConstArray();
1450 sal_Int32 nThisRowCount = rSequence.getLength();
1452 if (nRow >= 0 && nRow < nThisRowCount)
1454 const sheet::MemberResult& rData = pArray[nRow];
1455 if ((rData.Flags & sheet::MemberResultFlags::HASMEMBER)
1456 && !(rData.Flags & sheet::MemberResultFlags::SUBTOTAL))
1481 switch (rPosData.PositionType)
1483 case DataPilotTablePositionType::RESULT:
1485 vector<DataPilotFieldFilter> aFilters;
1488 DataPilotTableResultData aResData;
1490 aResData.DataFieldIndex = 0;
1491 Reference<beans::XPropertySet> xPropSet(
xSource, UNO_QUERY);
1496 if (nDataFieldCount > 0)
1497 aResData.DataFieldIndex = (nRow -
nDataStartRow) % nDataFieldCount;
1505 rPosData.PositionData <<= aResData;
1516 const uno::Sequence<sheet::MemberResult> rSequence =
pColFields[nField].maResult;
1517 if (!rSequence.hasElements())
1519 const sheet::MemberResult* pArray = rSequence.getConstArray();
1523 while (nItem > 0 && ( pArray[nItem].
Flags & sheet::MemberResultFlags::CONTINUE) )
1529 DataPilotTableHeaderData aHeaderData;
1530 aHeaderData.MemberName = pArray[nItem].Name;
1531 aHeaderData.Flags = pArray[nItem].Flags;
1532 aHeaderData.Dimension =
static_cast<sal_Int32
>(
pColFields[nField].mnDim);
1533 aHeaderData.Hierarchy =
static_cast<sal_Int32
>(
pColFields[nField].mnHier);
1534 aHeaderData.Level =
static_cast<sal_Int32
>(
pColFields[nField].mnLevel);
1536 rPosData.PositionData <<= aHeaderData;
1547 const uno::Sequence<sheet::MemberResult> rSequence =
pRowFields[nField].maResult;
1548 if (!rSequence.hasElements())
1550 const sheet::MemberResult* pArray = rSequence.getConstArray();
1554 while ( nItem > 0 && (pArray[nItem].
Flags & sheet::MemberResultFlags::CONTINUE) )
1560 DataPilotTableHeaderData aHeaderData;
1561 aHeaderData.MemberName = pArray[nItem].Name;
1562 aHeaderData.Flags = pArray[nItem].Flags;
1563 aHeaderData.Dimension =
static_cast<sal_Int32
>(
pRowFields[nField].mnDim);
1564 aHeaderData.Hierarchy =
static_cast<sal_Int32
>(
pRowFields[nField].mnHier);
1565 aHeaderData.Level =
static_cast<sal_Int32
>(
pRowFields[nField].mnLevel);
1567 rPosData.PositionData <<= aHeaderData;
1576 Reference<beans::XPropertySet> xPropSet(
xSource, UNO_QUERY);
1582 if (nDataFieldCount == 0)
1587 sal_Int32 nGrandTotalCols;
1588 sal_Int32 nGrandTotalRows;
1589 sal_Int32 nDataLayoutIndex;
1590 std::vector<OUString> aDataNames;
1591 std::vector<OUString> aGivenNames;
1592 sheet::DataPilotFieldOrientation eDataOrient;
1593 lcl_GetTableVars( nGrandTotalCols, nGrandTotalRows, nDataLayoutIndex, aDataNames, aGivenNames, eDataOrient,
xSource );
1610 bool bFilterByCol = (nCol <= static_cast<SCCOL>(
nTabEndCol - nGrandTotalCols));
1611 bool bFilterByRow = (nRow <= static_cast<SCROW>(
nTabEndRow - nGrandTotalRows));
1614 for (
size_t nColField = 0; nColField <
pColFields.size() && bFilterByCol; ++nColField)
1616 if (
pColFields[nColField].mnDim == nDataLayoutIndex)
1620 sheet::DataPilotFieldFilter
filter;
1623 const uno::Sequence<sheet::MemberResult> rSequence =
pColFields[nColField].maResult;
1624 const sheet::MemberResult* pArray = rSequence.getConstArray();
1626 OSL_ENSURE(
nDataStartCol + rSequence.getLength() - 1 ==
nTabEndCol,
"ScDPOutput::GetDataFieldCellData: error in geometric assumption");
1630 while ( nItem > 0 && (pArray[nItem].
Flags & sheet::MemberResultFlags::CONTINUE) )
1633 filter.MatchValueName = pArray[nItem].Name;
1634 rFilters.push_back(
filter);
1638 for (
size_t nRowField = 0; nRowField <
pRowFields.size() && bFilterByRow; ++nRowField)
1640 if (
pRowFields[nRowField].mnDim == nDataLayoutIndex)
1644 sheet::DataPilotFieldFilter
filter;
1647 const uno::Sequence<sheet::MemberResult> rSequence =
pRowFields[nRowField].maResult;
1648 const sheet::MemberResult* pArray = rSequence.getConstArray();
1650 OSL_ENSURE(
nDataStartRow + rSequence.getLength() - 1 ==
nTabEndRow,
"ScDPOutput::GetDataFieldCellData: error in geometric assumption");
1654 while ( nItem > 0 && (pArray[nItem].
Flags & sheet::MemberResultFlags::CONTINUE) )
1657 filter.MatchValueName = pArray[nItem].Name;
1658 rFilters.push_back(
filter);
1666OUString lcl_GetDataFieldName( std::u16string_view rSourceName, sal_Int16 eFunc )
1671 case sheet::GeneralFunction2::SUM: pStrId = STR_FUN_TEXT_SUM;
break;
1673 case sheet::GeneralFunction2::COUNTNUMS: pStrId = STR_FUN_TEXT_COUNT;
break;
1674 case sheet::GeneralFunction2::AVERAGE: pStrId = STR_FUN_TEXT_AVG;
break;
1675 case sheet::GeneralFunction2::MEDIAN: pStrId = STR_FUN_TEXT_MEDIAN;
break;
1676 case sheet::GeneralFunction2::MAX: pStrId = STR_FUN_TEXT_MAX;
break;
1677 case sheet::GeneralFunction2::MIN: pStrId = STR_FUN_TEXT_MIN;
break;
1678 case sheet::GeneralFunction2::PRODUCT: pStrId = STR_FUN_TEXT_PRODUCT;
break;
1679 case sheet::GeneralFunction2::STDEV:
1680 case sheet::GeneralFunction2::STDEVP: pStrId = STR_FUN_TEXT_STDDEV;
break;
1681 case sheet::GeneralFunction2::VAR:
1682 case sheet::GeneralFunction2::VARP: pStrId = STR_FUN_TEXT_VAR;
break;
1684 case sheet::GeneralFunction2::AUTO:
break;
1693 return ScResId(pStrId) +
" - " + rSourceName;
1699 OUString& rSourceName, OUString& rGivenName,
const uno::Reference<uno::XInterface>& xDim )
1701 uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1702 uno::Reference<container::XNamed> xDimName( xDim, uno::UNO_QUERY );
1703 if ( !(xDimProp.is() && xDimName.is()) )
1716 rGivenName = lcl_GetDataFieldName( rSourceName, eFunc );
1747 rOrient = sheet::DataPilotFieldOrientation_COLUMN;
1756 rOrient = sheet::DataPilotFieldOrientation_ROW;
1766 rOrient = sheet::DataPilotFieldOrientation_PAGE;
1773 rOrient = sheet::DataPilotFieldOrientation_HIDDEN;
1809 bool bFound =
false;
1810 bool bBeforeDrag =
false;
1811 bool bAfterDrag =
false;
1817 if ( nField <
nPos )
1819 else if ( nField >
nPos )
1843 rOrient = sheet::DataPilotFieldOrientation_COLUMN;
1863 bool bFound =
false;
1864 bool bBeforeDrag =
false;
1865 bool bAfterDrag =
false;
1871 if ( nField <
nPos )
1873 else if ( nField >
nPos )
1897 rOrient = sheet::DataPilotFieldOrientation_ROW;
1919 bool bFound =
false;
1920 bool bBeforeDrag =
false;
1921 bool bAfterDrag =
false;
1927 if ( nField <
nPos )
1929 else if ( nField >
nPos )
1953 rOrient = sheet::DataPilotFieldOrientation_PAGE;
@ DpCollapse
dp table output
@ DpExpand
dp compact layout collapse button
@ HiddenMember
dp button with popup arrow
@ ButtonPopup2
dp compact layout expand button
bool GetHeaderDrag(const ScAddress &rPos, bool bMouseLeft, bool bMouseTop, tools::Long nDragDim, tools::Rectangle &rPosRect, css::sheet::DataPilotFieldOrientation &rOrient, tools::Long &rDimPos)
void HeaderCell(SCCOL nCol, SCROW nRow, SCTAB nTab, const css::sheet::MemberResult &rData, bool bColHeader, tools::Long nLevel)
bool GetHeaderLayout() const
ScRange GetOutputRange(sal_Int32 nRegionType=css::sheet::DataPilotOutputRangeType::WHOLE)
Refresh?
void MultiFieldCell(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bRowField)
bool mbHasCompactRowField
std::unique_ptr< sal_uInt32[]> pRowNumFmt
SCCOL GetColumnsForRowFields() const
Computes number of columns needed to write row fields.
void GetPositionData(const ScAddress &rPos, css::sheet::DataPilotTablePositionData &rPosData)
void GetMemberResultNames(ScDPUniqueStringSet &rNames, tools::Long nDimension)
css::uno::Sequence< css::uno::Sequence< css::sheet::DataResult > > aData
void SetPosition(const ScAddress &rPos)
css::uno::Reference< css::sheet::XDimensionsSupplier > xSource
bool GetDataResultPositionData(::std::vector< css::sheet::DataPilotFieldFilter > &rFilters, const ScAddress &rPos)
Get filtering criteria based on the position of the cell within data field region.
void FieldCell(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScDPOutLevelData &rData, bool bInTable)
sal_Int32 GetRowFieldCompact(SCCOL nColQuery, SCROW nRowQuery) const
Find row field index from row position in case of compact layout.
tools::Long GetHeaderDim(const ScAddress &rPos, css::sheet::DataPilotFieldOrientation &rOrient)
std::vector< ScDPOutLevelData > pColFields
bool IsFilterButton(const ScAddress &rPos)
std::vector< bool > aRowCompactFlags
ScDPOutput(ScDocument *pD, css::uno::Reference< css::sheet::XDimensionsSupplier > xSrc, const ScAddress &rPos, bool bFilter, bool bExpandCollapse)
std::vector< ScDPOutLevelData > pPageFields
static void GetDataDimensionNames(OUString &rSourceName, OUString &rGivenName, const css::uno::Reference< css::uno::XInterface > &xDim)
OUString aDataDescription
std::unique_ptr< sal_uInt32[]> pColNumFmt
void GetRowFieldRange(SCCOL nCol, sal_Int32 &nRowFieldStart, sal_Int32 &nRowFieldEnd) const
Returns the range of row fields that are contained by table's row fields column nCol.
std::vector< ScDPOutLevelData > pRowFields
sal_Int32 GetHeaderRows() const
void SetHeaderLayout(bool bUseGrid)
void DataCell(SCCOL nCol, SCROW nRow, SCTAB nTab, const css::sheet::DataResult &rData)
sal_Int32 GetPositionType(const ScAddress &rPos)
Query which sub-area of the table the cell is in.
static SC_DLLPUBLIC OUString getSourceDimensionName(std::u16string_view rName)
void ApplyFrameAreaTab(const ScRange &rRange, const SvxBoxItem &rLineOuter, const SvxBoxInfoItem &rLineInner)
SC_DLLPUBLIC SCCOL MaxCol() const
SC_DLLPUBLIC SCROW MaxRow() const
SC_DLLPUBLIC bool ApplyFlagsTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, ScMF nFlags)
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
void SetError(SCCOL nCol, SCROW nRow, SCTAB nTab, const FormulaError nError)
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
SC_DLLPUBLIC void ApplyAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, const SfxPoolItem &rAttr)
SC_DLLPUBLIC ScStyleSheetPool * GetStyleSheetPool() const
SC_DLLPUBLIC void DeleteAreaTab(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, InsertDeleteFlags nDelFlag)
SC_DLLPUBLIC void ApplyStyleAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScStyleSheet &rStyle)
virtual SfxStyleSheetBase & Make(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits nMask=SfxStyleSearchBits::All) override
virtual SC_DLLPUBLIC SfxItemSet & GetItemSet() override
virtual bool SetParent(const OUString &rParentName) override
static bool GetBoolProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName, bool bDefault=false)
static EnumT GetEnumProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName, EnumT nDefault)
static sal_Int16 GetShortProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName, sal_Int16 nDefault)
static OUString GetStringProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName, const OUString &rDefault)
static sal_Int32 GetLongProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName)
static css::uno::Sequence< ValueType > VectorToSequence(const std::vector< ValueType > &rVector)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All)
#define SC_DP_FRAME_OUTER_BOLD
#define SC_DP_FRAME_COLOR
#define SC_DP_FRAME_INNER_BOLD
static void lcl_DoFilterButton(ScDocument *pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab)
std::unordered_set< OUString > ScDPUniqueStringSet
#define SAL_WARN(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
const PPTXLayoutInfo aLayoutInfo[LAYOUT_SIZE]
OUString ScResId(TranslateId aId)
constexpr TypedWhichId< SvxWeightItem > ATTR_FONT_WEIGHT(102)
constexpr TypedWhichId< SvxWeightItem > ATTR_CJK_FONT_WEIGHT(113)
constexpr TypedWhichId< SvxHorJustifyItem > ATTR_HOR_JUSTIFY(129)
constexpr TypedWhichId< SvxBoxInfoItem > ATTR_BORDER_INNER(151)
constexpr TypedWhichId< SvxBoxItem > ATTR_BORDER(150)
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALUE_FORMAT(146)
constexpr TypedWhichId< SvxWeightItem > ATTR_CTL_FONT_WEIGHT(118)
uno::Sequence< sheet::MemberResult > maResult
Prevailing number format used in the source data.
ScDPOutLevelData(tools::Long nDim, tools::Long nHier, tools::Long nLevel, tools::Long nDimPos, sal_uInt32 nSrcNumFmt, const uno::Sequence< sheet::MemberResult > &aResult, OUString aName, OUString aCaption, bool bHasHiddenMember, bool bDataLayout, bool bPageDim)
OUString maCaption
Name is the internal field name.
bool mbHasHiddenMember
Caption is the name visible in the output table.
Store parameters used in the ScDocument::SetString() method.
bool mbHandleApostrophe
When true, treat input with a leading apostrophe as an escape character for all content,...
void setTextInput()
Call this whenever you need to unconditionally set input as text, no matter what the input is.
void setNumericInput()
Call this whenever you need to maximize the chance of input being detected as a numeric value (number...
bool mbDetectNumberFormat
Specify which number formats are detected: mbDetectNumberFormat=true && mbDetectScientificNumberForma...
@ Always
Set Text number format if the input string can be parsed as a number or formula text.
TextFormatPolicy meSetTextNumFormat
Determine when to set the 'Text' number format to the cell where the input string is being set.
constexpr OUStringLiteral SC_UNO_DP_HAS_HIDDEN_MEMBER
constexpr OUStringLiteral SC_UNONAME_NUMFMT
constexpr OUStringLiteral SC_UNO_DP_COLGRAND
constexpr OUStringLiteral SC_UNO_DP_POSITION
constexpr OUStringLiteral SC_UNO_DP_DATAFIELDCOUNT
constexpr OUStringLiteral SC_UNO_DP_ISDATALAYOUT
constexpr OUStringLiteral SC_UNO_DP_LAYOUTNAME
constexpr OUStringLiteral SC_UNO_DP_FUNCTION2
constexpr OUStringLiteral SC_UNO_DP_DATADESC
constexpr OUStringLiteral SC_UNO_DP_ROWGRAND
#define SC_UNO_DP_NUMBERFO
constexpr OUStringLiteral SC_UNO_DP_USEDHIERARCHY
constexpr OUStringLiteral SC_UNO_DP_ORIENTATION
constexpr OUStringLiteral SC_UNO_DP_ISVISIBLE
constexpr OUStringLiteral SC_UNO_DP_LAYOUT