1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dptabsrc.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
37 // INCLUDE ---------------------------------------------------------------
45 #include <tools/debug.hxx>
46 #include <rtl/math.hxx>
47 #include <svtools/itemprop.hxx>
48 #include <svtools/intitem.hxx>
50 #include "scitems.hxx"
51 #include "document.hxx"
52 #include "docpool.hxx"
53 #include "patattr.hxx"
56 #include "dptabsrc.hxx"
57 #include "dptabres.hxx"
58 #include "dptabdat.hxx"
60 #include "collect.hxx"
61 #include "datauno.hxx" // ScDataUnoConversion
62 #include "unoguard.hxx"
63 #include "miscuno.hxx"
64 #include "unonames.hxx"
66 #include <com/sun/star/beans/PropertyAttribute.hpp>
67 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
68 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
69 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
70 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
71 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
72 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
73 #include <com/sun/star/table/CellAddress.hpp>
75 #include <unotools/collatorwrapper.hxx>
76 #include <unotools/calendarwrapper.hxx>
77 #include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
79 using namespace com::sun::star
;
82 using ::std::hash_map
;
83 using ::std::hash_set
;
84 using ::com::sun::star::uno::Reference
;
85 using ::com::sun::star::uno::Sequence
;
86 using ::com::sun::star::uno::Any
;
87 using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo
;
88 using ::rtl::OUString
;
90 // -----------------------------------------------------------------------
92 #define SC_MINCOUNT_LIMIT 1000000
94 // -----------------------------------------------------------------------
96 SC_SIMPLE_SERVICE_INFO( ScDPSource
, "ScDPSource", "com.sun.star.sheet.DataPilotSource" )
97 SC_SIMPLE_SERVICE_INFO( ScDPDimensions
, "ScDPDimensions", "com.sun.star.sheet.DataPilotSourceDimensions" )
98 SC_SIMPLE_SERVICE_INFO( ScDPDimension
, "ScDPDimension", "com.sun.star.sheet.DataPilotSourceDimension" )
99 SC_SIMPLE_SERVICE_INFO( ScDPHierarchies
, "ScDPHierarchies", "com.sun.star.sheet.DataPilotSourceHierarcies" )
100 SC_SIMPLE_SERVICE_INFO( ScDPHierarchy
, "ScDPHierarchy", "com.sun.star.sheet.DataPilotSourceHierarcy" )
101 SC_SIMPLE_SERVICE_INFO( ScDPLevels
, "ScDPLevels", "com.sun.star.sheet.DataPilotSourceLevels" )
102 SC_SIMPLE_SERVICE_INFO( ScDPLevel
, "ScDPLevel", "com.sun.star.sheet.DataPilotSourceLevel" )
103 SC_SIMPLE_SERVICE_INFO( ScDPMembers
, "ScDPMembers", "com.sun.star.sheet.DataPilotSourceMembers" )
104 SC_SIMPLE_SERVICE_INFO( ScDPMember
, "ScDPMember", "com.sun.star.sheet.DataPilotSourceMember" )
106 // -----------------------------------------------------------------------
108 // property maps for PropertySetInfo
109 // DataDescription / NumberFormat are internal
111 // -----------------------------------------------------------------------
113 //! move to a header?
114 BOOL
lcl_GetBoolFromAny( const uno::Any
& aAny
)
116 if ( aAny
.getValueTypeClass() == uno::TypeClass_BOOLEAN
)
117 return *(sal_Bool
*)aAny
.getValue();
121 void lcl_SetBoolInAny( uno::Any
& rAny
, BOOL bValue
)
123 rAny
.setValue( &bValue
, getBooleanCppuType() );
126 // -----------------------------------------------------------------------
128 ScDPSource::ScDPSource( ScDPTableData
* pD
) :
135 bColumnGrand( TRUE
), // default is true
137 bIgnoreEmptyRows( FALSE
),
138 bRepeatIfEmpty( FALSE
),
145 bResultOverflow( FALSE
),
146 mpGrandTotalName(NULL
)
148 pData
->SetEmptyFlags( bIgnoreEmptyRows
, bRepeatIfEmpty
);
151 ScDPSource::~ScDPSource()
154 pDimensions
->release(); // ref-counted
158 delete[] pColResults
;
159 delete[] pRowResults
;
166 void ScDPSource::SetGrandTotalName(const ::rtl::OUString
& rName
)
168 mpGrandTotalName
.reset(new ::rtl::OUString(rName
));
171 const ::rtl::OUString
* ScDPSource::GetGrandTotalName() const
173 return mpGrandTotalName
.get();
176 USHORT
ScDPSource::GetOrientation(long nColumn
)
179 for (i
=0; i
<nColDimCount
; i
++)
180 if (nColDims
[i
] == nColumn
)
181 return sheet::DataPilotFieldOrientation_COLUMN
;
182 for (i
=0; i
<nRowDimCount
; i
++)
183 if (nRowDims
[i
] == nColumn
)
184 return sheet::DataPilotFieldOrientation_ROW
;
185 for (i
=0; i
<nDataDimCount
; i
++)
186 if (nDataDims
[i
] == nColumn
)
187 return sheet::DataPilotFieldOrientation_DATA
;
188 for (i
=0; i
<nPageDimCount
; i
++)
189 if (nPageDims
[i
] == nColumn
)
190 return sheet::DataPilotFieldOrientation_PAGE
;
191 return sheet::DataPilotFieldOrientation_HIDDEN
;
194 long ScDPSource::GetDataDimensionCount()
196 return nDataDimCount
;
199 ScDPDimension
* ScDPSource::GetDataDimension(long nIndex
)
201 if (nIndex
< 0 || nIndex
>= nDataDimCount
)
204 long nDimIndex
= nDataDims
[nIndex
];
205 return GetDimensionsObject()->getByIndex(nDimIndex
);
208 String
ScDPSource::GetDataDimName( long nIndex
)
211 ScDPDimension
* pDim
= GetDataDimension(nIndex
);
213 aRet
= String(pDim
->getName());
217 long ScDPSource::GetPosition(long nColumn
)
220 for (i
=0; i
<nColDimCount
; i
++)
221 if (nColDims
[i
] == nColumn
)
223 for (i
=0; i
<nRowDimCount
; i
++)
224 if (nRowDims
[i
] == nColumn
)
226 for (i
=0; i
<nDataDimCount
; i
++)
227 if (nDataDims
[i
] == nColumn
)
229 for (i
=0; i
<nPageDimCount
; i
++)
230 if (nPageDims
[i
] == nColumn
)
235 BOOL
lcl_TestSubTotal( BOOL
& rAllowed
, long nColumn
, long* pArray
, long nCount
, ScDPSource
* pSource
)
237 for (long i
=0; i
<nCount
; i
++)
238 if (pArray
[i
] == nColumn
)
240 // no subtotals for data layout dim, no matter where
241 if ( pSource
->IsDataLayoutDimension(nColumn
) )
245 // no subtotals if no other dim but data layout follows
246 long nNextIndex
= i
+1;
247 if ( nNextIndex
< nCount
&& pSource
->IsDataLayoutDimension(pArray
[nNextIndex
]) )
249 if ( nNextIndex
>= nCount
)
253 return TRUE
; // found
258 BOOL
ScDPSource::SubTotalAllowed(long nColumn
)
260 //! cache this at ScDPResultData
261 BOOL bAllowed
= TRUE
;
262 if ( lcl_TestSubTotal( bAllowed
, nColumn
, nColDims
, nColDimCount
, this ) )
264 if ( lcl_TestSubTotal( bAllowed
, nColumn
, nRowDims
, nRowDimCount
, this ) )
269 void lcl_RemoveDim( long nRemove
, long* pDims
, long& rCount
)
271 for (long i
=0; i
<rCount
; i
++)
272 if ( pDims
[i
] == nRemove
)
274 for (long j
=i
; j
+1<rCount
; j
++)
275 pDims
[j
] = pDims
[j
+1];
281 void ScDPSource::SetOrientation(long nColumn
, USHORT nNew
)
283 //! change to no-op if new orientation is equal to old?
285 // remove from old list
286 lcl_RemoveDim( nColumn
, nColDims
, nColDimCount
);
287 lcl_RemoveDim( nColumn
, nRowDims
, nRowDimCount
);
288 lcl_RemoveDim( nColumn
, nDataDims
, nDataDimCount
);
289 lcl_RemoveDim( nColumn
, nPageDims
, nPageDimCount
);
294 case sheet::DataPilotFieldOrientation_COLUMN
:
295 nColDims
[nColDimCount
++] = nColumn
;
297 case sheet::DataPilotFieldOrientation_ROW
:
298 nRowDims
[nRowDimCount
++] = nColumn
;
300 case sheet::DataPilotFieldOrientation_DATA
:
301 nDataDims
[nDataDimCount
++] = nColumn
;
303 case sheet::DataPilotFieldOrientation_PAGE
:
304 nPageDims
[nPageDimCount
++] = nColumn
;
307 DBG_ERROR( "ScDPSource::SetOrientation: unexpected orientation" );
312 BOOL
ScDPSource::IsDataLayoutDimension(long nDim
)
314 return nDim
== pData
->GetColumnCount();
317 USHORT
ScDPSource::GetDataLayoutOrientation()
319 return GetOrientation(pData
->GetColumnCount());
322 BOOL
ScDPSource::IsDateDimension(long nDim
)
324 return pData
->IsDateDimension(nDim
);
327 ScDPDimensions
* ScDPSource::GetDimensionsObject()
331 pDimensions
= new ScDPDimensions(this);
332 pDimensions
->acquire(); // ref-counted
337 uno::Reference
<container::XNameAccess
> SAL_CALL
ScDPSource::getDimensions() throw(uno::RuntimeException
)
339 return GetDimensionsObject();
342 void ScDPSource::SetDupCount( long nNew
)
347 ScDPDimension
* ScDPSource::AddDuplicated(long /* nSource */, const String
& rNewName
)
349 DBG_ASSERT( pDimensions
, "AddDuplicated without dimensions?" );
353 long nOldDimCount
= pDimensions
->getCount();
354 for (long i
=0; i
<nOldDimCount
; i
++)
356 ScDPDimension
* pDim
= pDimensions
->getByIndex(i
);
357 if (pDim
&& String(pDim
->getName()) == rNewName
)
359 //! test if pDim is a duplicate of source
364 SetDupCount( nDupCount
+ 1 );
365 pDimensions
->CountChanged(); // uses nDupCount
367 return pDimensions
->getByIndex( pDimensions
->getCount() - 1 );
370 long ScDPSource::GetSourceDim(long nDim
)
372 // original source dimension or data layout dimension?
373 if ( nDim
<= pData
->GetColumnCount() )
376 if ( nDim
< pDimensions
->getCount() )
378 ScDPDimension
* pDimObj
= pDimensions
->getByIndex( nDim
);
381 long nSource
= pDimObj
->GetSourceDim();
387 DBG_ERROR("GetSourceDim: wrong dim");
391 uno::Sequence
< uno::Sequence
<sheet::DataResult
> > SAL_CALL
ScDPSource::getResults()
392 throw(uno::RuntimeException
)
394 CreateRes_Impl(); // create pColResRoot and pRowResRoot
396 if ( bResultOverflow
) // set in CreateRes_Impl
398 // no results available
399 throw uno::RuntimeException();
402 long nColCount
= pColResRoot
->GetSize(pResData
->GetColStartMeasure());
403 long nRowCount
= pRowResRoot
->GetSize(pResData
->GetRowStartMeasure());
405 // allocate full sequence
406 //! leave out empty rows???
408 uno::Sequence
< uno::Sequence
<sheet::DataResult
> > aSeq( nRowCount
);
409 uno::Sequence
<sheet::DataResult
>* pRowAry
= aSeq
.getArray();
410 for (long nRow
= 0; nRow
< nRowCount
; nRow
++)
412 uno::Sequence
<sheet::DataResult
> aColSeq( nColCount
);
413 // use default values of DataResult
414 pRowAry
[nRow
] = aColSeq
;
418 pRowResRoot
->FillDataResults( pColResRoot
, aSeq
, nSeqRow
, pResData
->GetRowStartMeasure() );
423 void SAL_CALL
ScDPSource::refresh() throw(uno::RuntimeException
)
428 void SAL_CALL
ScDPSource::addRefreshListener( const uno::Reference
<util::XRefreshListener
>& )
429 throw(uno::RuntimeException
)
431 DBG_ERROR("not implemented"); //! exception?
434 void SAL_CALL
ScDPSource::removeRefreshListener( const uno::Reference
<util::XRefreshListener
>& )
435 throw(uno::RuntimeException
)
437 DBG_ERROR("not implemented"); //! exception?
440 Sequence
< Sequence
<Any
> > SAL_CALL
ScDPSource::getDrillDownData(const Sequence
<sheet::DataPilotFieldFilter
>& aFilters
)
441 throw (uno::RuntimeException
)
443 long nColumnCount
= GetData()->GetColumnCount();
444 ScSimpleSharedString
& rSharedString
= GetData()->GetSharedString();
446 typedef hash_map
<String
, long, ScStringHashCode
> FieldNameMapType
;
447 FieldNameMapType aFieldNames
;
448 for (long i
= 0; i
< nColumnCount
; ++i
)
451 FieldNameMapType::value_type(GetData()->getDimensionName(i
), i
));
454 // collect ScDPItemData for each filtered column
455 vector
<ScDPCacheTable::Criterion
> aFilterCriteria
;
456 sal_Int32 nFilterCount
= aFilters
.getLength();
457 for (sal_Int32 i
= 0; i
< nFilterCount
; ++i
)
459 const sheet::DataPilotFieldFilter
& rFilter
= aFilters
[i
];
460 String
aFieldName( rFilter
.FieldName
);
461 for (long nCol
= 0; nCol
< nColumnCount
; ++nCol
)
463 if ( aFieldName
== pData
->getDimensionName(nCol
) )
465 ScDPDimension
* pDim
= GetDimensionsObject()->getByIndex( nCol
);
466 ScDPMembers
* pMembers
= pDim
->GetHierarchiesObject()->getByIndex(0)->
467 GetLevelsObject()->getByIndex(0)->GetMembersObject();
468 sal_Int32 nIndex
= pMembers
->GetIndexFromName( rFilter
.MatchValue
);
472 pMembers
->getByIndex(nIndex
)->FillItemData( aItem
);
473 aFilterCriteria
.push_back( ScDPCacheTable::Criterion() );
474 sal_Int32 nMatchStrId
= rSharedString
.getStringId(aItem
.aString
);
475 aFilterCriteria
.back().mnFieldIndex
= nCol
;
476 aFilterCriteria
.back().mpFilter
.reset(
477 new ScDPCacheTable::SingleFilter(rSharedString
, nMatchStrId
, aItem
.fValue
, aItem
.bHasValue
) );
483 // Take into account the visibilities of field members.
484 ScDPResultVisibilityData
aResVisData(rSharedString
, this);
485 pRowResRoot
->FillVisibilityData(aResVisData
);
486 pColResRoot
->FillVisibilityData(aResVisData
);
487 aResVisData
.fillFieldFilters(aFilterCriteria
);
489 Sequence
< Sequence
<Any
> > aTabData
;
490 hash_set
<sal_Int32
> aCatDims
;
491 GetCategoryDimensionIndices(aCatDims
);
492 pData
->GetDrillDownData(aFilterCriteria
, aCatDims
, aTabData
);
496 String
ScDPSource::getDataDescription()
498 CreateRes_Impl(); // create pResData
501 if ( pResData
->GetMeasureCount() == 1 )
503 bool bTotalResult
= false;
504 aRet
= pResData
->GetMeasureString( 0, TRUE
, SUBTOTAL_FUNC_NONE
, bTotalResult
);
507 // empty for more than one measure
512 BOOL
ScDPSource::getColumnGrand() const
517 void ScDPSource::setColumnGrand(BOOL bSet
)
522 BOOL
ScDPSource::getRowGrand() const
527 void ScDPSource::setRowGrand(BOOL bSet
)
532 BOOL
ScDPSource::getIgnoreEmptyRows() const
534 return bIgnoreEmptyRows
;
537 void ScDPSource::setIgnoreEmptyRows(BOOL bSet
)
539 bIgnoreEmptyRows
= bSet
;
540 pData
->SetEmptyFlags( bIgnoreEmptyRows
, bRepeatIfEmpty
);
543 BOOL
ScDPSource::getRepeatIfEmpty() const
545 return bRepeatIfEmpty
;
548 void ScDPSource::setRepeatIfEmpty(BOOL bSet
)
550 bRepeatIfEmpty
= bSet
;
551 pData
->SetEmptyFlags( bIgnoreEmptyRows
, bRepeatIfEmpty
);
554 void ScDPSource::validate() //! ???
559 void ScDPSource::disposeData()
565 DELETEZ(pColResRoot
);
566 DELETEZ(pRowResRoot
);
568 delete[] pColResults
;
569 delete[] pRowResults
;
572 aColLevelList
.Clear();
573 aRowLevelList
.Clear();
578 pDimensions
->release(); // ref-counted
579 pDimensions
= NULL
; // settings have to be applied (from SaveData) again!
584 nColDimCount
= nRowDimCount
= nDataDimCount
= nPageDimCount
= 0;
586 pData
->DisposeData(); // cached entries etc.
587 bResultOverflow
= FALSE
;
590 long lcl_CountMinMembers(const vector
<ScDPDimension
*>& ppDim
, const vector
<ScDPLevel
*>& ppLevel
, long nLevels
)
592 // Calculate the product of the member count for those consecutive levels that
593 // have the "show all" flag, one following level, and the data layout dimension.
597 BOOL bWasShowAll
= TRUE
;
603 if ( nPos
+1 < nLevels
&& ppDim
[nPos
] == ppDim
[nPos
+1] )
605 DBG_ERROR("lcl_CountMinMembers: multiple levels from one dimension not implemented");
610 if ( ppDim
[nPos
]->getIsDataLayoutDimension() )
612 // data layout dim doesn't interfere with "show all" flags
613 nDataCount
= ppLevel
[nPos
]->GetMembersObject()->getCount();
614 if ( nDataCount
== 0 )
617 else if ( bWasShowAll
) // "show all" set for all following levels?
620 if ( !ppLevel
[nPos
]->getShowEmpty() )
622 // this level is counted, following ones are not
628 long nThisCount
= ppLevel
[nPos
]->GetMembersObject()->getMinMembers();
629 if ( nThisCount
== 0 )
631 nTotal
= 1; // empty level -> start counting from here
632 //! start with visible elements in this level?
636 if ( nTotal
>= LONG_MAX
/ nThisCount
)
637 return LONG_MAX
; // overflow
638 nTotal
*= nThisCount
;
643 // always include data layout dim, even after restarting
644 if ( nTotal
>= LONG_MAX
/ nDataCount
)
645 return LONG_MAX
; // overflow
646 nTotal
*= nDataCount
;
651 long lcl_GetIndexFromName( const rtl::OUString rName
, const uno::Sequence
<rtl::OUString
>& rElements
)
653 long nCount
= rElements
.getLength();
654 const rtl::OUString
* pArray
= rElements
.getConstArray();
655 for (long nPos
=0; nPos
<nCount
; nPos
++)
656 if (pArray
[nPos
] == rName
)
659 return -1; // not found
662 void ScDPSource::FillCalcInfo(bool bIsRow
, ScDPTableData::CalcInfo
& rInfo
, bool &rHasAutoShow
)
664 long* nDims
= bIsRow
? nRowDims
: nColDims
;
665 long nDimCount
= bIsRow
? nRowDimCount
: nColDimCount
;
667 for (long i
= 0; i
< nDimCount
; ++i
)
669 ScDPDimension
* pDim
= GetDimensionsObject()->getByIndex( nDims
[i
] );
670 long nHierarchy
= pDim
->getUsedHierarchy();
671 if ( nHierarchy
>= pDim
->GetHierarchiesObject()->getCount() )
673 ScDPLevels
* pLevels
= pDim
->GetHierarchiesObject()->getByIndex(nHierarchy
)->GetLevelsObject();
674 long nCount
= pLevels
->getCount();
677 if ( pDim
->getIsDataLayoutDimension() && nDataDimCount
< 2 )
681 for (long j
= 0; j
< nCount
; ++j
)
683 ScDPLevel
* pLevel
= pLevels
->getByIndex(j
);
684 pLevel
->EvaluateSortOrder();
686 // no layout flags for column fields, only for row fields
687 pLevel
->SetEnableLayout( bIsRow
);
689 if ( pLevel
->GetAutoShow().IsEnabled
)
694 rInfo
.aRowLevelDims
.push_back(nDims
[i
]);
695 rInfo
.aRowDims
.push_back(pDim
);
696 rInfo
.aRowLevels
.push_back(pLevel
);
700 rInfo
.aColLevelDims
.push_back(nDims
[i
]);
701 rInfo
.aColDims
.push_back(pDim
);
702 rInfo
.aColLevels
.push_back(pLevel
);
705 pLevel
->GetMembersObject(); // initialize for groups
710 void ScDPSource::GetCategoryDimensionIndices(hash_set
<sal_Int32
>& rCatDims
)
712 hash_set
<sal_Int32
> aCatDims
;
713 for (long i
= 0; i
< nColDimCount
; ++i
)
715 sal_Int32 nDim
= static_cast<sal_Int32
>(nColDims
[i
]);
716 if (!IsDataLayoutDimension(nDim
))
717 aCatDims
.insert(nDim
);
720 for (long i
= 0; i
< nRowDimCount
; ++i
)
722 sal_Int32 nDim
= static_cast<sal_Int32
>(nRowDims
[i
]);
723 if (!IsDataLayoutDimension(nDim
))
724 aCatDims
.insert(nDim
);
727 for (long i
= 0; i
< nPageDimCount
; ++i
)
729 sal_Int32 nDim
= static_cast<sal_Int32
>(nPageDims
[i
]);
730 if (!IsDataLayoutDimension(nDim
))
731 aCatDims
.insert(nDim
);
734 rCatDims
.swap(aCatDims
);
737 void ScDPSource::FilterCacheTableByPageDimensions()
739 ScSimpleSharedString
& rSharedString
= GetData()->GetSharedString();
741 // filter table by page dimensions.
742 vector
<ScDPCacheTable::Criterion
> aCriteria
;
743 for (long i
= 0; i
< nPageDimCount
; ++i
)
745 ScDPDimension
* pDim
= GetDimensionsObject()->getByIndex(nPageDims
[i
]);
746 long nField
= pDim
->GetDimension();
748 ScDPMembers
* pMems
= pDim
->GetHierarchiesObject()->getByIndex(0)->
749 GetLevelsObject()->getByIndex(0)->GetMembersObject();
751 long nMemCount
= pMems
->getCount();
752 ScDPCacheTable::Criterion aFilter
;
753 aFilter
.mnFieldIndex
= static_cast<sal_Int32
>(nField
);
754 aFilter
.mpFilter
.reset(new ScDPCacheTable::GroupFilter(rSharedString
));
755 ScDPCacheTable::GroupFilter
* pGrpFilter
=
756 static_cast<ScDPCacheTable::GroupFilter
*>(aFilter
.mpFilter
.get());
757 for (long j
= 0; j
< nMemCount
; ++j
)
759 ScDPMember
* pMem
= pMems
->getByIndex(j
);
760 if (pMem
->getIsVisible())
763 pMem
->FillItemData(aData
);
764 pGrpFilter
->addMatchItem(aData
.aString
, aData
.fValue
, aData
.bHasValue
);
767 if (pGrpFilter
->getMatchItemCount() < static_cast<size_t>(nMemCount
))
768 // there is at least one invisible item. Add this filter criterion to the mix.
769 aCriteria
.push_back(aFilter
);
771 if (!pDim
|| !pDim
->HasSelectedPage())
774 const ScDPItemData
& rData
= pDim
->GetSelectedData();
775 aCriteria
.push_back(ScDPCacheTable::Criterion());
776 ScDPCacheTable::Criterion
& r
= aCriteria
.back();
777 r
.mnFieldIndex
= static_cast<sal_Int32
>(nField
);
778 sal_Int32 nStrId
= rSharedString
.getStringId(rData
.aString
);
780 new ScDPCacheTable::SingleFilter(rSharedString
, nStrId
, rData
.fValue
, rData
.bHasValue
));
782 if (!aCriteria
.empty())
784 hash_set
<sal_Int32
> aCatDims
;
785 GetCategoryDimensionIndices(aCatDims
);
786 pData
->FilterCacheTable(aCriteria
, aCatDims
);
790 void ScDPSource::CreateRes_Impl()
794 USHORT nDataOrient
= GetDataLayoutOrientation();
795 if ( nDataDimCount
> 1 && ( nDataOrient
!= sheet::DataPilotFieldOrientation_COLUMN
&&
796 nDataOrient
!= sheet::DataPilotFieldOrientation_ROW
) )
798 // if more than one data dimension, data layout orientation must be set
799 SetOrientation( pData
->GetColumnCount(), sheet::DataPilotFieldOrientation_ROW
);
800 nDataOrient
= sheet::DataPilotFieldOrientation_ROW
;
803 // TODO: Aggreate pDataNames, pDataRefValues, nDataRefOrient, and
804 // eDataFunctions into a structure and use vector instead of static
805 // or pointer arrays.
806 String
* pDataNames
= NULL
;
807 sheet::DataPilotFieldReference
* pDataRefValues
= NULL
;
808 ScSubTotalFunc eDataFunctions
[SC_DAPI_MAXFIELDS
];
809 USHORT nDataRefOrient
[SC_DAPI_MAXFIELDS
];
812 pDataNames
= new String
[nDataDimCount
];
813 pDataRefValues
= new sheet::DataPilotFieldReference
[nDataDimCount
];
816 ScDPTableData::CalcInfo aInfo
;
819 // LateInit (initialize only those rows/children that are used) can be used unless
820 // any data dimension needs reference values from column/row dimensions
821 BOOL bLateInit
= TRUE
;
823 // Go through all data dimensions (i.e. fields) and build their meta data
824 // so that they can be passed on to ScDPResultData instance later.
825 // TODO: aggregate all of data dimension info into a structure.
827 for (i
=0; i
<nDataDimCount
; i
++)
829 // Get function for each data field.
830 long nDimIndex
= nDataDims
[i
];
831 ScDPDimension
* pDim
= GetDimensionsObject()->getByIndex(nDimIndex
);
832 sheet::GeneralFunction eUser
= (sheet::GeneralFunction
)pDim
->getFunction();
833 if (eUser
== sheet::GeneralFunction_AUTO
)
835 //! test for numeric data
836 eUser
= sheet::GeneralFunction_SUM
;
839 // Map UNO's enum to internal enum ScSubTotalFunc.
840 eDataFunctions
[i
] = ScDataUnoConversion::GeneralToSubTotal( eUser
);
842 // Get reference field/item information.
843 pDataRefValues
[i
] = pDim
->GetReferenceValue();
844 nDataRefOrient
[i
] = sheet::DataPilotFieldOrientation_HIDDEN
; // default if not used
845 sal_Int32 eRefType
= pDataRefValues
[i
].ReferenceType
;
846 if ( eRefType
== sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE
||
847 eRefType
== sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE
||
848 eRefType
== sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE
||
849 eRefType
== sheet::DataPilotFieldReferenceType::RUNNING_TOTAL
)
851 long nColumn
= lcl_GetIndexFromName( pDataRefValues
[i
].ReferenceField
,
852 GetDimensionsObject()->getElementNames() );
855 nDataRefOrient
[i
] = GetOrientation( nColumn
);
856 // need fully initialized results to find reference values
857 // (both in column or row dimensions), so updated values or
858 // differences to 0 can be displayed even for empty results.
863 pDataNames
[i
] = String( pDim
->getName() ); //! label?
865 // asterisk is added to duplicated dimension names by ScDPSaveData::WriteToSource
866 //! modify user visible strings as in ScDPResultData::GetMeasureString instead!
868 pDataNames
[i
].EraseTrailingChars('*');
870 //! if the name is overridden by user, a flag must be set
871 //! so the user defined name replaces the function string and field name.
873 //! the complete name (function and field) must be stored at the dimension
875 long nSource
= ((ScDPDimension
*)pDim
)->GetSourceDim();
877 aInfo
.aDataSrcCols
.push_back(nSource
);
879 aInfo
.aDataSrcCols
.push_back(nDimIndex
);
882 pResData
= new ScDPResultData( this );
883 pResData
->SetMeasureData( nDataDimCount
, eDataFunctions
, pDataRefValues
, nDataRefOrient
, pDataNames
);
884 pResData
->SetDataLayoutOrientation(nDataOrient
);
885 pResData
->SetLateInit( bLateInit
);
888 delete[] pDataRefValues
;
890 bool bHasAutoShow
= false;
892 ScDPInitState aInitState
;
894 // Page field selections restrict the members shown in related fields
895 // (both in column and row fields). aInitState is filled with the page
896 // field selections, they are kept across the data iterator loop.
898 for (i
=0; i
<nPageDimCount
; i
++)
900 ScDPDimension
* pDim
= GetDimensionsObject()->getByIndex( nPageDims
[i
] );
901 if ( pDim
->HasSelectedPage() )
902 aInitState
.AddMember( nPageDims
[i
], pDim
->GetSelectedData() );
905 pColResRoot
= new ScDPResultMember( pResData
, NULL
, NULL
, NULL
, bColumnGrand
);
906 pRowResRoot
= new ScDPResultMember( pResData
, NULL
, NULL
, NULL
, bRowGrand
);
908 FillCalcInfo(false, aInfo
, bHasAutoShow
);
909 long nColLevelCount
= aInfo
.aColLevels
.size();
911 pColResRoot
->InitFrom( aInfo
.aColDims
, aInfo
.aColLevels
, 0, aInitState
);
912 pColResRoot
->SetHasElements();
914 FillCalcInfo(true, aInfo
, bHasAutoShow
);
915 long nRowLevelCount
= aInfo
.aRowLevels
.size();
917 if ( nRowLevelCount
> 0 )
919 // disable layout flags for the innermost row field (level)
920 aInfo
.aRowLevels
[nRowLevelCount
-1]->SetEnableLayout( FALSE
);
923 pRowResRoot
->InitFrom( aInfo
.aRowDims
, aInfo
.aRowLevels
, 0, aInitState
);
924 pRowResRoot
->SetHasElements();
926 // initialize members object also for all page dimensions (needed for numeric groups)
927 for (i
=0; i
<nPageDimCount
; i
++)
929 ScDPDimension
* pDim
= GetDimensionsObject()->getByIndex( nPageDims
[i
] );
930 long nHierarchy
= pDim
->getUsedHierarchy();
931 if ( nHierarchy
>= pDim
->GetHierarchiesObject()->getCount() )
934 ScDPLevels
* pLevels
= pDim
->GetHierarchiesObject()->getByIndex(nHierarchy
)->GetLevelsObject();
935 long nCount
= pLevels
->getCount();
936 for (long j
=0; j
<nCount
; j
++)
937 pLevels
->getByIndex(j
)->GetMembersObject(); // initialize for groups
940 // pre-check: calculate minimum number of result columns / rows from
941 // levels that have the "show all" flag set
943 long nMinColMembers
= lcl_CountMinMembers( aInfo
.aColDims
, aInfo
.aColLevels
, nColLevelCount
);
944 long nMinRowMembers
= lcl_CountMinMembers( aInfo
.aRowDims
, aInfo
.aRowLevels
, nRowLevelCount
);
946 if ( nMinColMembers
> SC_MINCOUNT_LIMIT
|| nMinRowMembers
> SC_MINCOUNT_LIMIT
)
948 // resulting table is too big -> abort before calculating
949 // (this relies on late init, so no members are allocated in InitFrom above)
951 bResultOverflow
= TRUE
;
955 FilterCacheTableByPageDimensions();
957 aInfo
.aPageDims
.reserve(nPageDimCount
);
958 for (i
= 0; i
< nPageDimCount
; ++i
)
959 aInfo
.aPageDims
.push_back(nPageDims
[i
]);
961 aInfo
.pInitState
= &aInitState
;
962 aInfo
.pColRoot
= pColResRoot
;
963 aInfo
.pRowRoot
= pRowResRoot
;
964 pData
->CalcResults(aInfo
, false);
966 // ----------------------------------------------------------------
967 // With all data processed, calculate the final results:
969 // UpdateDataResults calculates all original results from the collected values,
970 // and stores them as reference values if needed.
971 pRowResRoot
->UpdateDataResults( pColResRoot
, pResData
->GetRowStartMeasure() );
973 if ( bHasAutoShow
) // do the double calculation only if AutoShow is used
975 // Find the desired members and set bAutoHidden flag for the others
976 pRowResRoot
->DoAutoShow( pColResRoot
);
978 // Reset all results to empty, so they can be built again with data for the
979 // desired members only.
980 pColResRoot
->ResetResults( TRUE
);
981 pRowResRoot
->ResetResults( TRUE
);
982 pData
->CalcResults(aInfo
, true);
984 // Call UpdateDataResults again, with the new (limited) values.
985 pRowResRoot
->UpdateDataResults( pColResRoot
, pResData
->GetRowStartMeasure() );
988 // SortMembers does the sorting by a result dimension, using the orginal results,
989 // but not running totals etc.
990 pRowResRoot
->SortMembers( pColResRoot
);
992 // UpdateRunningTotals calculates running totals along column/row dimensions,
993 // differences from other members (named or relative), and column/row percentages
995 // Running totals and relative differences need to be done using the sorted values.
996 // Column/row percentages and index values must be done after sorting, because the
997 // results may no longer be in the right order (row total for percentage of row is
999 ScDPRunningTotalState
aRunning( pColResRoot
, pRowResRoot
);
1000 ScDPRowTotals aTotals
;
1001 pRowResRoot
->UpdateRunningTotals( pColResRoot
, pResData
->GetRowStartMeasure(), aRunning
, aTotals
);
1003 // ----------------------------------------------------------------
1008 void ScDPSource::DumpState( ScDocument
* pDoc
, const ScAddress
& rPos
)
1012 ScAddress
aDocPos( rPos
);
1014 if (pColResRoot
->GetChildDimension())
1015 pColResRoot
->GetChildDimension()->DumpState( NULL
, pDoc
, aDocPos
);
1016 pRowResRoot
->DumpState( pColResRoot
, pDoc
, aDocPos
);
1019 void ScDPSource::FillLevelList( USHORT nOrientation
, List
& rList
)
1024 long* pDimIndex
= NULL
;
1025 switch (nOrientation
)
1027 case sheet::DataPilotFieldOrientation_COLUMN
:
1028 pDimIndex
= nColDims
;
1029 nDimCount
= nColDimCount
;
1031 case sheet::DataPilotFieldOrientation_ROW
:
1032 pDimIndex
= nRowDims
;
1033 nDimCount
= nRowDimCount
;
1035 case sheet::DataPilotFieldOrientation_DATA
:
1036 pDimIndex
= nDataDims
;
1037 nDimCount
= nDataDimCount
;
1039 case sheet::DataPilotFieldOrientation_PAGE
:
1040 pDimIndex
= nPageDims
;
1041 nDimCount
= nPageDimCount
;
1044 DBG_ERROR( "ScDPSource::FillLevelList: unexpected orientation" );
1049 DBG_ERROR("invalid orientation");
1053 ScDPDimensions
* pDims
= GetDimensionsObject();
1054 for (long nDim
=0; nDim
<nDimCount
; nDim
++)
1056 ScDPDimension
* pDim
= pDims
->getByIndex(pDimIndex
[nDim
]);
1057 DBG_ASSERT( pDim
->getOrientation() == nOrientation
, "orientations are wrong" );
1059 ScDPHierarchies
* pHiers
= pDim
->GetHierarchiesObject();
1060 long nHierarchy
= pDim
->getUsedHierarchy();
1061 if ( nHierarchy
>= pHiers
->getCount() )
1063 ScDPHierarchy
* pHier
= pHiers
->getByIndex(nHierarchy
);
1064 ScDPLevels
* pLevels
= pHier
->GetLevelsObject();
1065 long nLevCount
= pLevels
->getCount();
1066 for (long nLev
=0; nLev
<nLevCount
; nLev
++)
1068 ScDPLevel
* pLevel
= pLevels
->getByIndex(nLev
);
1069 rList
.Insert( pLevel
, LIST_APPEND
);
1074 void ScDPSource::FillMemberResults()
1076 if ( !pColResults
&& !pRowResults
)
1080 if ( bResultOverflow
) // set in CreateRes_Impl
1082 // no results available -> abort (leave empty)
1083 // exception is thrown in ScDPSource::getResults
1087 FillLevelList( sheet::DataPilotFieldOrientation_COLUMN
, aColLevelList
);
1088 long nColLevelCount
= aColLevelList
.Count();
1091 long nColDimSize
= pColResRoot
->GetSize(pResData
->GetColStartMeasure());
1092 pColResults
= new uno::Sequence
<sheet::MemberResult
>[nColLevelCount
];
1093 for (long i
=0; i
<nColLevelCount
; i
++)
1094 pColResults
[i
].realloc(nColDimSize
);
1096 // ScDPResultDimension* pColResDim = pColResRoot->GetChildDimension();
1097 // pColResDim->FillMemberResults( pColResults, 0, pResData->GetColStartMeasure() );
1099 pColResRoot
->FillMemberResults( pColResults
, nPos
, pResData
->GetColStartMeasure(),
1103 FillLevelList( sheet::DataPilotFieldOrientation_ROW
, aRowLevelList
);
1104 long nRowLevelCount
= aRowLevelList
.Count();
1107 long nRowDimSize
= pRowResRoot
->GetSize(pResData
->GetRowStartMeasure());
1108 pRowResults
= new uno::Sequence
<sheet::MemberResult
>[nRowLevelCount
];
1109 for (long i
=0; i
<nRowLevelCount
; i
++)
1110 pRowResults
[i
].realloc(nRowDimSize
);
1112 // ScDPResultDimension* pRowResDim = pRowResRoot->GetChildDimension();
1113 // pRowResDim->FillMemberResults( pRowResults, 0, pResData->GetRowStartMeasure() );
1115 pRowResRoot
->FillMemberResults( pRowResults
, nPos
, pResData
->GetRowStartMeasure(),
1121 const uno::Sequence
<sheet::MemberResult
>* ScDPSource::GetMemberResults( ScDPLevel
* pLevel
)
1123 FillMemberResults();
1126 long nColCount
= aColLevelList
.Count();
1127 for (i
=0; i
<nColCount
; i
++)
1129 ScDPLevel
* pColLevel
= (ScDPLevel
*)aColLevelList
.GetObject(i
);
1130 if ( pColLevel
== pLevel
)
1131 return pColResults
+i
;
1133 long nRowCount
= aRowLevelList
.Count();
1134 for (i
=0; i
<nRowCount
; i
++)
1136 ScDPLevel
* pRowLevel
= (ScDPLevel
*)aRowLevelList
.GetObject(i
);
1137 if ( pRowLevel
== pLevel
)
1138 return pRowResults
+i
;
1145 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScDPSource::getPropertySetInfo()
1146 throw(uno::RuntimeException
)
1149 using beans::PropertyAttribute::READONLY
;
1151 static SfxItemPropertyMap aDPSourceMap_Impl
[] =
1153 {MAP_CHAR_LEN(SC_UNO_COLGRAND
), 0, &getBooleanCppuType(), 0, 0 },
1154 {MAP_CHAR_LEN(SC_UNO_DATADESC
), 0, &getCppuType((rtl::OUString
*)0), beans::PropertyAttribute::READONLY
, 0 },
1155 {MAP_CHAR_LEN(SC_UNO_IGNOREEM
), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
1156 {MAP_CHAR_LEN(SC_UNO_REPEATIF
), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
1157 {MAP_CHAR_LEN(SC_UNO_ROWGRAND
), 0, &getBooleanCppuType(), 0, 0 },
1158 {MAP_CHAR_LEN(SC_UNO_ROWFIELDCOUNT
), 0, &getCppuType(static_cast<sal_Int32
*>(0)), READONLY
, 0 },
1159 {MAP_CHAR_LEN(SC_UNO_COLUMNFIELDCOUNT
), 0, &getCppuType(static_cast<sal_Int32
*>(0)), READONLY
, 0 },
1160 {MAP_CHAR_LEN(SC_UNO_DATAFIELDCOUNT
), 0, &getCppuType(static_cast<sal_Int32
*>(0)), READONLY
, 0 },
1161 {MAP_CHAR_LEN(SC_UNO_GRANDTOTAL_NAME
), 0, &getCppuType(static_cast<OUString
*>(0)), 0, 0 },
1164 static uno::Reference
<beans::XPropertySetInfo
> aRef
=
1165 new SfxItemPropertySetInfo( aDPSourceMap_Impl
);
1169 void SAL_CALL
ScDPSource::setPropertyValue( const rtl::OUString
& aPropertyName
, const uno::Any
& aValue
)
1170 throw(beans::UnknownPropertyException
, beans::PropertyVetoException
,
1171 lang::IllegalArgumentException
, lang::WrappedTargetException
,
1172 uno::RuntimeException
)
1174 String aNameStr
= aPropertyName
;
1175 if ( aNameStr
.EqualsAscii( SC_UNO_COLGRAND
) )
1176 setColumnGrand( lcl_GetBoolFromAny( aValue
) );
1177 else if ( aNameStr
.EqualsAscii( SC_UNO_ROWGRAND
) )
1178 setRowGrand( lcl_GetBoolFromAny( aValue
) );
1179 else if ( aNameStr
.EqualsAscii( SC_UNO_IGNOREEM
) )
1180 setIgnoreEmptyRows( lcl_GetBoolFromAny( aValue
) );
1181 else if ( aNameStr
.EqualsAscii( SC_UNO_REPEATIF
) )
1182 setRepeatIfEmpty( lcl_GetBoolFromAny( aValue
) );
1183 else if (aNameStr
.EqualsAscii(SC_UNO_GRANDTOTAL_NAME
))
1186 if (aValue
>>= aName
)
1187 mpGrandTotalName
.reset(new OUString(aName
));
1191 DBG_ERROR("unknown property");
1192 //! THROW( UnknownPropertyException() );
1196 uno::Any SAL_CALL
ScDPSource::getPropertyValue( const rtl::OUString
& aPropertyName
)
1197 throw(beans::UnknownPropertyException
, lang::WrappedTargetException
,
1198 uno::RuntimeException
)
1201 String aNameStr
= aPropertyName
;
1202 if ( aNameStr
.EqualsAscii( SC_UNO_COLGRAND
) )
1203 lcl_SetBoolInAny( aRet
, getColumnGrand() );
1204 else if ( aNameStr
.EqualsAscii( SC_UNO_ROWGRAND
) )
1205 lcl_SetBoolInAny( aRet
, getRowGrand() );
1206 else if ( aNameStr
.EqualsAscii( SC_UNO_IGNOREEM
) )
1207 lcl_SetBoolInAny( aRet
, getIgnoreEmptyRows() );
1208 else if ( aNameStr
.EqualsAscii( SC_UNO_REPEATIF
) )
1209 lcl_SetBoolInAny( aRet
, getRepeatIfEmpty() );
1210 else if ( aNameStr
.EqualsAscii( SC_UNO_DATADESC
) ) // read-only
1211 aRet
<<= rtl::OUString( getDataDescription() );
1212 else if ( aNameStr
.EqualsAscii( SC_UNO_ROWFIELDCOUNT
) ) // read-only
1213 aRet
<<= static_cast<sal_Int32
>(nRowDimCount
);
1214 else if ( aNameStr
.EqualsAscii( SC_UNO_COLUMNFIELDCOUNT
) ) // read-only
1215 aRet
<<= static_cast<sal_Int32
>(nColDimCount
);
1216 else if ( aNameStr
.EqualsAscii( SC_UNO_DATAFIELDCOUNT
) ) // read-only
1217 aRet
<<= static_cast<sal_Int32
>(nDataDimCount
);
1218 else if (aNameStr
.EqualsAscii(SC_UNO_GRANDTOTAL_NAME
))
1220 if (mpGrandTotalName
.get())
1221 aRet
<<= *mpGrandTotalName
;
1225 DBG_ERROR("unknown property");
1226 //! THROW( UnknownPropertyException() );
1231 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPSource
)
1233 // -----------------------------------------------------------------------
1235 ScDPDimensions::ScDPDimensions( ScDPSource
* pSrc
) :
1241 // include data layout dimension and duplicated dimensions
1242 nDimCount
= pSource
->GetData()->GetColumnCount() + 1 + pSource
->GetDupCount();
1245 ScDPDimensions::~ScDPDimensions()
1251 for (long i
=0; i
<nDimCount
; i
++)
1253 ppDims
[i
]->release(); // ref-counted
1258 void ScDPDimensions::CountChanged()
1260 // include data layout dimension and duplicated dimensions
1261 long nNewCount
= pSource
->GetData()->GetColumnCount() + 1 + pSource
->GetDupCount();
1265 long nCopy
= Min( nNewCount
, nDimCount
);
1266 ScDPDimension
** ppNew
= new ScDPDimension
*[nNewCount
];
1268 for (i
=0; i
<nCopy
; i
++) // copy existing dims
1269 ppNew
[i
] = ppDims
[i
];
1270 for (i
=nCopy
; i
<nNewCount
; i
++) // clear additional pointers
1272 for (i
=nCopy
; i
<nDimCount
; i
++) // delete old dims if count is decreased
1274 ppDims
[i
]->release(); // ref-counted
1279 nDimCount
= nNewCount
;
1282 // very simple XNameAccess implementation using getCount/getByIndex
1284 uno::Any SAL_CALL
ScDPDimensions::getByName( const rtl::OUString
& aName
)
1285 throw(container::NoSuchElementException
,
1286 lang::WrappedTargetException
, uno::RuntimeException
)
1288 long nCount
= getCount();
1289 for (long i
=0; i
<nCount
; i
++)
1290 if ( getByIndex(i
)->getName() == aName
)
1292 uno::Reference
<container::XNamed
> xNamed
= getByIndex(i
);
1298 throw container::NoSuchElementException();
1299 // return uno::Any();
1302 uno::Sequence
<rtl::OUString
> SAL_CALL
ScDPDimensions::getElementNames() throw(uno::RuntimeException
)
1304 long nCount
= getCount();
1305 uno::Sequence
<rtl::OUString
> aSeq(nCount
);
1306 rtl::OUString
* pArr
= aSeq
.getArray();
1307 for (long i
=0; i
<nCount
; i
++)
1308 pArr
[i
] = getByIndex(i
)->getName();
1312 sal_Bool SAL_CALL
ScDPDimensions::hasByName( const rtl::OUString
& aName
) throw(uno::RuntimeException
)
1314 long nCount
= getCount();
1315 for (long i
=0; i
<nCount
; i
++)
1316 if ( getByIndex(i
)->getName() == aName
)
1321 uno::Type SAL_CALL
ScDPDimensions::getElementType() throw(uno::RuntimeException
)
1323 return getCppuType((uno::Reference
<container::XNamed
>*)0);
1326 sal_Bool SAL_CALL
ScDPDimensions::hasElements() throw(uno::RuntimeException
)
1328 return ( getCount() > 0 );
1331 // end of XNameAccess implementation
1333 long ScDPDimensions::getCount() const
1335 // in tabular data, every column of source data is a dimension
1340 ScDPDimension
* ScDPDimensions::getByIndex(long nIndex
) const
1342 if ( nIndex
>= 0 && nIndex
< nDimCount
)
1346 ((ScDPDimensions
*)this)->ppDims
= new ScDPDimension
*[nDimCount
];
1347 for (long i
=0; i
<nDimCount
; i
++)
1350 if ( !ppDims
[nIndex
] )
1352 ppDims
[nIndex
] = new ScDPDimension( pSource
, nIndex
);
1353 ppDims
[nIndex
]->acquire(); // ref-counted
1356 return ppDims
[nIndex
];
1359 return NULL
; //! exception?
1362 // -----------------------------------------------------------------------
1364 ScDPDimension::ScDPDimension( ScDPSource
* pSrc
, long nD
) :
1367 pHierarchies( NULL
),
1369 nFunction( SUBTOTAL_FUNC_SUM
), // sum is default
1371 mpSubtotalName(NULL
),
1373 bHasSelectedPage( FALSE
),
1374 pSelectedData( NULL
),
1375 mbHasHiddenMember(false)
1380 ScDPDimension::~ScDPDimension()
1385 pHierarchies
->release(); // ref-counted
1387 delete pSelectedData
;
1390 ScDPHierarchies
* ScDPDimension::GetHierarchiesObject()
1394 pHierarchies
= new ScDPHierarchies( pSource
, nDim
);
1395 pHierarchies
->acquire(); // ref-counted
1397 return pHierarchies
;
1400 const rtl::OUString
* ScDPDimension::GetLayoutName() const
1402 return mpLayoutName
.get();
1405 const rtl::OUString
* ScDPDimension::GetSubtotalName() const
1407 return mpSubtotalName
.get();
1410 uno::Reference
<container::XNameAccess
> SAL_CALL
ScDPDimension::getHierarchies()
1411 throw(uno::RuntimeException
)
1413 return GetHierarchiesObject();
1416 ::rtl::OUString SAL_CALL
ScDPDimension::getName() throw(uno::RuntimeException
)
1421 return pSource
->GetData()->getDimensionName( nDim
);
1424 void SAL_CALL
ScDPDimension::setName( const ::rtl::OUString
& rNewName
) throw(uno::RuntimeException
)
1426 // used after cloning
1427 aName
= String( rNewName
);
1430 USHORT
ScDPDimension::getOrientation() const
1432 return pSource
->GetOrientation( nDim
);
1435 void ScDPDimension::setOrientation(USHORT nNew
)
1437 pSource
->SetOrientation( nDim
, nNew
);
1440 long ScDPDimension::getPosition() const
1442 return pSource
->GetPosition( nDim
);
1445 void ScDPDimension::setPosition(long /* nNew */)
1450 BOOL
ScDPDimension::getIsDataLayoutDimension() const
1452 return pSource
->GetData()->getIsDataLayoutDimension( nDim
);
1455 USHORT
ScDPDimension::getFunction() const
1460 void ScDPDimension::setFunction(USHORT nNew
)
1465 long ScDPDimension::getUsedHierarchy() const
1470 void ScDPDimension::setUsedHierarchy(long /* nNew */)
1472 // #i52547# don't use the incomplete date hierarchy implementation - ignore the call
1473 // nUsedHier = nNew;
1476 ScDPDimension
* ScDPDimension::CreateCloneObject()
1478 DBG_ASSERT( nSourceDim
< 0, "recursive duplicate - not implemented" );
1480 //! set new name here, or temporary name ???
1481 String aNewName
= aName
;
1483 ScDPDimension
* pNew
= pSource
->AddDuplicated( nDim
, aNewName
);
1485 pNew
->aName
= aNewName
; //! here or in source?
1486 pNew
->nSourceDim
= nDim
; //! recursive?
1491 uno::Reference
<util::XCloneable
> SAL_CALL
ScDPDimension::createClone() throw(uno::RuntimeException
)
1493 return CreateCloneObject();
1496 BOOL
ScDPDimension::isDuplicated() const
1498 return (nSourceDim
>= 0);
1501 const sheet::DataPilotFieldReference
& ScDPDimension::GetReferenceValue() const
1503 return aReferenceValue
;
1506 const ScDPItemData
& ScDPDimension::GetSelectedData()
1508 if ( !pSelectedData
)
1510 // find the named member to initialize pSelectedData from it, with name and value
1512 long nLevel
= 0; // same as in ScDPObject::FillPageList
1514 long nHierarchy
= getUsedHierarchy();
1515 if ( nHierarchy
>= GetHierarchiesObject()->getCount() )
1517 ScDPLevels
* pLevels
= GetHierarchiesObject()->getByIndex(nHierarchy
)->GetLevelsObject();
1518 long nLevCount
= pLevels
->getCount();
1519 if ( nLevel
< nLevCount
)
1521 ScDPMembers
* pMembers
= pLevels
->getByIndex(nLevel
)->GetMembersObject();
1523 //! merge with ScDPMembers::getByName
1524 long nCount
= pMembers
->getCount();
1525 for (long i
=0; i
<nCount
&& !pSelectedData
; i
++)
1527 ScDPMember
* pMember
= pMembers
->getByIndex(i
);
1528 if ( pMember
->GetNameStr() == aSelectedPage
)
1530 pSelectedData
= new ScDPItemData();
1531 pMember
->FillItemData( *pSelectedData
);
1536 if ( !pSelectedData
)
1537 pSelectedData
= new ScDPItemData( aSelectedPage
, 0.0, FALSE
); // default - name only
1540 return *pSelectedData
;
1543 BOOL
ScDPDimension::IsValidPage( const ScDPItemData
& rData
)
1545 if ( bHasSelectedPage
)
1546 return rData
.IsCaseInsEqual( GetSelectedData() );
1548 return TRUE
; // no selection -> all data
1553 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScDPDimension::getPropertySetInfo()
1554 throw(uno::RuntimeException
)
1558 static SfxItemPropertyMap aDPDimensionMap_Impl
[] =
1560 {MAP_CHAR_LEN(SC_UNO_FILTER
), 0, &getCppuType((uno::Sequence
<sheet::TableFilterField
>*)0), 0, 0 },
1561 {MAP_CHAR_LEN(SC_UNO_FUNCTION
), 0, &getCppuType((sheet::GeneralFunction
*)0), 0, 0 },
1562 {MAP_CHAR_LEN(SC_UNO_ISDATALA
), 0, &getBooleanCppuType(), beans::PropertyAttribute::READONLY
, 0 },
1563 {MAP_CHAR_LEN(SC_UNO_NUMBERFO
), 0, &getCppuType((sal_Int32
*)0), beans::PropertyAttribute::READONLY
, 0 },
1564 {MAP_CHAR_LEN(SC_UNO_ORIENTAT
), 0, &getCppuType((sheet::DataPilotFieldOrientation
*)0), 0, 0 },
1565 {MAP_CHAR_LEN(SC_UNO_ORIGINAL
), 0, &getCppuType((uno::Reference
<container::XNamed
>*)0), beans::PropertyAttribute::READONLY
, 0 },
1566 {MAP_CHAR_LEN(SC_UNO_POSITION
), 0, &getCppuType((sal_Int32
*)0), 0, 0 },
1567 {MAP_CHAR_LEN(SC_UNO_REFVALUE
), 0, &getCppuType((sheet::DataPilotFieldReference
*)0), 0, 0 },
1568 {MAP_CHAR_LEN(SC_UNO_USEDHIER
), 0, &getCppuType((sal_Int32
*)0), 0, 0 },
1569 {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME
), 0, &getCppuType(static_cast<rtl::OUString
*>(0)), 0, 0 },
1570 {MAP_CHAR_LEN(SC_UNO_FIELD_SUBTOTALNAME
), 0, &getCppuType(static_cast<rtl::OUString
*>(0)), 0, 0 },
1571 {MAP_CHAR_LEN(SC_UNO_HAS_HIDDEN_MEMBER
), 0, &getBooleanCppuType(), 0, 0 },
1574 static uno::Reference
<beans::XPropertySetInfo
> aRef
=
1575 new SfxItemPropertySetInfo( aDPDimensionMap_Impl
);
1579 void SAL_CALL
ScDPDimension::setPropertyValue( const rtl::OUString
& aPropertyName
, const uno::Any
& aValue
)
1580 throw(beans::UnknownPropertyException
, beans::PropertyVetoException
,
1581 lang::IllegalArgumentException
, lang::WrappedTargetException
,
1582 uno::RuntimeException
)
1584 String aNameStr
= aPropertyName
;
1585 if ( aNameStr
.EqualsAscii( SC_UNO_POSITION
) )
1588 if (aValue
>>= nInt
)
1589 setPosition( nInt
);
1591 else if ( aNameStr
.EqualsAscii( SC_UNO_USEDHIER
) )
1594 if (aValue
>>= nInt
)
1595 setUsedHierarchy( nInt
);
1597 else if ( aNameStr
.EqualsAscii( SC_UNO_ORIENTAT
) )
1599 sheet::DataPilotFieldOrientation eEnum
;
1600 if (aValue
>>= eEnum
)
1601 setOrientation( sal::static_int_cast
<USHORT
>(eEnum
) );
1603 else if ( aNameStr
.EqualsAscii( SC_UNO_FUNCTION
) )
1605 sheet::GeneralFunction eEnum
;
1606 if (aValue
>>= eEnum
)
1607 setFunction( sal::static_int_cast
<USHORT
>(eEnum
) );
1609 else if ( aNameStr
.EqualsAscii( SC_UNO_REFVALUE
) )
1610 aValue
>>= aReferenceValue
;
1611 else if ( aNameStr
.EqualsAscii( SC_UNO_FILTER
) )
1614 uno::Sequence
<sheet::TableFilterField
> aSeq
;
1615 if (aValue
>>= aSeq
)
1617 sal_Int32 nLength
= aSeq
.getLength();
1620 aSelectedPage
.Erase();
1621 bHasSelectedPage
= FALSE
;
1624 else if ( nLength
== 1 )
1626 const sheet::TableFilterField
& rField
= aSeq
[0];
1627 if ( rField
.Field
== 0 && rField
.Operator
== sheet::FilterOperator_EQUAL
&& !rField
.IsNumeric
)
1629 aSelectedPage
= rField
.StringValue
;
1630 bHasSelectedPage
= TRUE
;
1637 DBG_ERROR("Filter property is not a single string");
1638 throw lang::IllegalArgumentException();
1640 DELETEZ( pSelectedData
); // invalid after changing aSelectedPage
1642 else if (aNameStr
.EqualsAscii(SC_UNO_LAYOUTNAME
))
1645 if (aValue
>>= aTmpName
)
1646 mpLayoutName
.reset(new OUString(aTmpName
));
1648 else if (aNameStr
.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME
))
1651 if (aValue
>>= aTmpName
)
1652 mpSubtotalName
.reset(new OUString(aTmpName
));
1654 else if (aNameStr
.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER
))
1655 aValue
>>= mbHasHiddenMember
;
1658 DBG_ERROR("unknown property");
1659 //! THROW( UnknownPropertyException() );
1663 uno::Any SAL_CALL
ScDPDimension::getPropertyValue( const rtl::OUString
& aPropertyName
)
1664 throw(beans::UnknownPropertyException
, lang::WrappedTargetException
,
1665 uno::RuntimeException
)
1668 String aNameStr
= aPropertyName
;
1669 if ( aNameStr
.EqualsAscii( SC_UNO_POSITION
) )
1670 aRet
<<= (sal_Int32
) getPosition();
1671 else if ( aNameStr
.EqualsAscii( SC_UNO_USEDHIER
) )
1672 aRet
<<= (sal_Int32
) getUsedHierarchy();
1673 else if ( aNameStr
.EqualsAscii( SC_UNO_ORIENTAT
) )
1675 sheet::DataPilotFieldOrientation eVal
= (sheet::DataPilotFieldOrientation
)getOrientation();
1678 else if ( aNameStr
.EqualsAscii( SC_UNO_FUNCTION
) )
1680 sheet::GeneralFunction eVal
= (sheet::GeneralFunction
)getFunction();
1683 else if ( aNameStr
.EqualsAscii( SC_UNO_REFVALUE
) )
1684 aRet
<<= aReferenceValue
;
1685 else if ( aNameStr
.EqualsAscii( SC_UNO_ISDATALA
) ) // read-only properties
1686 lcl_SetBoolInAny( aRet
, getIsDataLayoutDimension() );
1687 else if ( aNameStr
.EqualsAscii( SC_UNO_NUMBERFO
) )
1689 sal_Int32 nFormat
= 0;
1690 sheet::GeneralFunction eFunc
= (sheet::GeneralFunction
)getFunction();
1691 // #i63745# don't use source format for "count"
1692 if ( eFunc
!= sheet::GeneralFunction_COUNT
&& eFunc
!= sheet::GeneralFunction_COUNTNUMS
)
1693 nFormat
= pSource
->GetData()->GetNumberFormat( ( nSourceDim
>= 0 ) ? nSourceDim
: nDim
);
1696 else if ( aNameStr
.EqualsAscii( SC_UNO_ORIGINAL
) )
1698 uno::Reference
<container::XNamed
> xOriginal
;
1699 if (nSourceDim
>= 0)
1700 xOriginal
= pSource
->GetDimensionsObject()->getByIndex(nSourceDim
);
1703 else if ( aNameStr
.EqualsAscii( SC_UNO_FILTER
) )
1705 if ( bHasSelectedPage
)
1707 // single filter field: first field equal to selected string
1708 sheet::TableFilterField
aField( sheet::FilterConnection_AND
, 0,
1709 sheet::FilterOperator_EQUAL
, sal_False
, 0.0, aSelectedPage
);
1710 aRet
<<= uno::Sequence
<sheet::TableFilterField
>( &aField
, 1 );
1713 aRet
<<= uno::Sequence
<sheet::TableFilterField
>(0);
1715 else if (aNameStr
.EqualsAscii(SC_UNO_LAYOUTNAME
))
1716 aRet
<<= mpLayoutName
.get() ? *mpLayoutName
: OUString::createFromAscii("");
1717 else if (aNameStr
.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME
))
1718 aRet
<<= mpSubtotalName
.get() ? *mpSubtotalName
: OUString::createFromAscii("");
1719 else if (aNameStr
.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER
))
1720 aRet
<<= mbHasHiddenMember
;
1723 DBG_ERROR("unknown property");
1724 //! THROW( UnknownPropertyException() );
1729 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPDimension
)
1731 // -----------------------------------------------------------------------
1733 ScDPHierarchies::ScDPHierarchies( ScDPSource
* pSrc
, long nD
) :
1741 // date columns have 3 hierarchies (flat/quarter/week), other columns only one
1742 long nSrcDim
= pSource
->GetSourceDim( nDim
);
1743 if ( pSource
->IsDateDimension( nSrcDim
) )
1744 nHierCount
= SC_DAPI_DATE_HIERARCHIES
;
1749 // #i52547# don't offer the incomplete date hierarchy implementation
1753 ScDPHierarchies::~ScDPHierarchies()
1759 for (long i
=0; i
<nHierCount
; i
++)
1761 ppHiers
[i
]->release(); // ref-counted
1766 // very simple XNameAccess implementation using getCount/getByIndex
1768 uno::Any SAL_CALL
ScDPHierarchies::getByName( const rtl::OUString
& aName
)
1769 throw(container::NoSuchElementException
,
1770 lang::WrappedTargetException
, uno::RuntimeException
)
1772 long nCount
= getCount();
1773 for (long i
=0; i
<nCount
; i
++)
1774 if ( getByIndex(i
)->getName() == aName
)
1776 uno::Reference
<container::XNamed
> xNamed
= getByIndex(i
);
1782 throw container::NoSuchElementException();
1783 // return uno::Any();
1786 uno::Sequence
<rtl::OUString
> SAL_CALL
ScDPHierarchies::getElementNames() throw(uno::RuntimeException
)
1788 long nCount
= getCount();
1789 uno::Sequence
<rtl::OUString
> aSeq(nCount
);
1790 rtl::OUString
* pArr
= aSeq
.getArray();
1791 for (long i
=0; i
<nCount
; i
++)
1792 pArr
[i
] = getByIndex(i
)->getName();
1796 sal_Bool SAL_CALL
ScDPHierarchies::hasByName( const rtl::OUString
& aName
) throw(uno::RuntimeException
)
1798 long nCount
= getCount();
1799 for (long i
=0; i
<nCount
; i
++)
1800 if ( getByIndex(i
)->getName() == aName
)
1805 uno::Type SAL_CALL
ScDPHierarchies::getElementType() throw(uno::RuntimeException
)
1807 return getCppuType((uno::Reference
<container::XNamed
>*)0);
1810 sal_Bool SAL_CALL
ScDPHierarchies::hasElements() throw(uno::RuntimeException
)
1812 return ( getCount() > 0 );
1815 // end of XNameAccess implementation
1817 long ScDPHierarchies::getCount() const
1822 ScDPHierarchy
* ScDPHierarchies::getByIndex(long nIndex
) const
1824 // pass hierarchy index to new object in case the implementation
1825 // will be extended to more than one hierarchy
1827 if ( nIndex
>= 0 && nIndex
< nHierCount
)
1831 ((ScDPHierarchies
*)this)->ppHiers
= new ScDPHierarchy
*[nHierCount
];
1832 for (long i
=0; i
<nHierCount
; i
++)
1835 if ( !ppHiers
[nIndex
] )
1837 ppHiers
[nIndex
] = new ScDPHierarchy( pSource
, nDim
, nIndex
);
1838 ppHiers
[nIndex
]->acquire(); // ref-counted
1841 return ppHiers
[nIndex
];
1844 return NULL
; //! exception?
1847 // -----------------------------------------------------------------------
1849 ScDPHierarchy::ScDPHierarchy( ScDPSource
* pSrc
, long nD
, long nH
) :
1858 ScDPHierarchy::~ScDPHierarchy()
1863 pLevels
->release(); // ref-counted
1866 ScDPLevels
* ScDPHierarchy::GetLevelsObject()
1870 pLevels
= new ScDPLevels( pSource
, nDim
, nHier
);
1871 pLevels
->acquire(); // ref-counted
1876 uno::Reference
<container::XNameAccess
> SAL_CALL
ScDPHierarchy::getLevels()
1877 throw(uno::RuntimeException
)
1879 return GetLevelsObject();
1882 ::rtl::OUString SAL_CALL
ScDPHierarchy::getName() throw(uno::RuntimeException
)
1884 String aRet
; //! globstr-ID !!!!
1887 case SC_DAPI_HIERARCHY_FLAT
:
1888 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("flat"));
1889 break; //! name ???????
1890 case SC_DAPI_HIERARCHY_QUARTER
:
1891 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Quarter"));
1892 break; //! name ???????
1893 case SC_DAPI_HIERARCHY_WEEK
:
1894 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Week"));
1895 break; //! name ???????
1897 DBG_ERROR( "ScDPHierarchy::getName: unexpected hierarchy" );
1903 void SAL_CALL
ScDPHierarchy::setName( const ::rtl::OUString
& /* rNewName */ ) throw(uno::RuntimeException
)
1905 DBG_ERROR("not implemented"); //! exception?
1908 // -----------------------------------------------------------------------
1910 ScDPLevels::ScDPLevels( ScDPSource
* pSrc
, long nD
, long nH
) :
1918 // text columns have only one level
1920 long nSrcDim
= pSource
->GetSourceDim( nDim
);
1921 if ( pSource
->IsDateDimension( nSrcDim
) )
1925 case SC_DAPI_HIERARCHY_FLAT
: nLevCount
= SC_DAPI_FLAT_LEVELS
; break;
1926 case SC_DAPI_HIERARCHY_QUARTER
: nLevCount
= SC_DAPI_QUARTER_LEVELS
; break;
1927 case SC_DAPI_HIERARCHY_WEEK
: nLevCount
= SC_DAPI_WEEK_LEVELS
; break;
1929 DBG_ERROR("wrong hierarchy");
1937 ScDPLevels::~ScDPLevels()
1943 for (long i
=0; i
<nLevCount
; i
++)
1945 ppLevs
[i
]->release(); // ref-counted
1950 // very simple XNameAccess implementation using getCount/getByIndex
1952 uno::Any SAL_CALL
ScDPLevels::getByName( const rtl::OUString
& aName
)
1953 throw(container::NoSuchElementException
,
1954 lang::WrappedTargetException
, uno::RuntimeException
)
1956 long nCount
= getCount();
1957 for (long i
=0; i
<nCount
; i
++)
1958 if ( getByIndex(i
)->getName() == aName
)
1960 uno::Reference
<container::XNamed
> xNamed
= getByIndex(i
);
1966 throw container::NoSuchElementException();
1967 // return uno::Any();
1970 uno::Sequence
<rtl::OUString
> SAL_CALL
ScDPLevels::getElementNames() throw(uno::RuntimeException
)
1972 long nCount
= getCount();
1973 uno::Sequence
<rtl::OUString
> aSeq(nCount
);
1974 rtl::OUString
* pArr
= aSeq
.getArray();
1975 for (long i
=0; i
<nCount
; i
++)
1976 pArr
[i
] = getByIndex(i
)->getName();
1980 sal_Bool SAL_CALL
ScDPLevels::hasByName( const rtl::OUString
& aName
) throw(uno::RuntimeException
)
1982 long nCount
= getCount();
1983 for (long i
=0; i
<nCount
; i
++)
1984 if ( getByIndex(i
)->getName() == aName
)
1989 uno::Type SAL_CALL
ScDPLevels::getElementType() throw(uno::RuntimeException
)
1991 return getCppuType((uno::Reference
<container::XNamed
>*)0);
1994 sal_Bool SAL_CALL
ScDPLevels::hasElements() throw(uno::RuntimeException
)
1996 return ( getCount() > 0 );
1999 // end of XNameAccess implementation
2001 long ScDPLevels::getCount() const
2006 ScDPLevel
* ScDPLevels::getByIndex(long nIndex
) const
2008 if ( nIndex
>= 0 && nIndex
< nLevCount
)
2012 ((ScDPLevels
*)this)->ppLevs
= new ScDPLevel
*[nLevCount
];
2013 for (long i
=0; i
<nLevCount
; i
++)
2016 if ( !ppLevs
[nIndex
] )
2018 ppLevs
[nIndex
] = new ScDPLevel( pSource
, nDim
, nHier
, nIndex
);
2019 ppLevs
[nIndex
]->acquire(); // ref-counted
2022 return ppLevs
[nIndex
];
2025 return NULL
; //! exception?
2028 // -----------------------------------------------------------------------
2030 class ScDPGlobalMembersOrder
2036 ScDPGlobalMembersOrder( ScDPLevel
& rLev
, BOOL bAsc
) :
2040 ~ScDPGlobalMembersOrder() {}
2042 BOOL
operator()( sal_Int32 nIndex1
, sal_Int32 nIndex2
) const;
2045 BOOL
ScDPGlobalMembersOrder::operator()( sal_Int32 nIndex1
, sal_Int32 nIndex2
) const
2047 ScDPMembers
* pMembers
= rLevel
.GetMembersObject();
2048 ScDPMember
* pMember1
= pMembers
->getByIndex(nIndex1
);
2049 ScDPMember
* pMember2
= pMembers
->getByIndex(nIndex2
);
2051 sal_Int32 nCompare
= pMember1
->Compare( *pMember2
);
2053 return bAscending
? ( nCompare
< 0 ) : ( nCompare
> 0 );
2056 // -----------------------------------------------------------------------
2058 ScDPLevel::ScDPLevel( ScDPSource
* pSrc
, long nD
, long nH
, long nL
) :
2064 bShowEmpty( FALSE
),
2065 aSortInfo( EMPTY_STRING
, sal_True
, sheet::DataPilotFieldSortMode::NAME
), // default: sort by name
2068 bEnableLayout( FALSE
)
2071 // aSubTotals is empty
2074 ScDPLevel::~ScDPLevel()
2079 pMembers
->release(); // ref-counted
2082 void ScDPLevel::EvaluateSortOrder()
2084 switch (aSortInfo
.Mode
)
2086 case sheet::DataPilotFieldSortMode::DATA
:
2088 // find index of measure (index among data dimensions)
2090 String aDataFieldName
= aSortInfo
.Field
;
2091 long nMeasureCount
= pSource
->GetDataDimensionCount();
2092 for (long nMeasure
=0; nMeasure
<nMeasureCount
; nMeasure
++)
2094 if ( pSource
->GetDataDimName(nMeasure
) == aDataFieldName
)
2096 nSortMeasure
= nMeasure
;
2101 //! error if not found?
2104 case sheet::DataPilotFieldSortMode::MANUAL
:
2105 case sheet::DataPilotFieldSortMode::NAME
:
2107 ScDPMembers
* pLocalMembers
= GetMembersObject();
2108 long nCount
= pLocalMembers
->getCount();
2110 DBG_ASSERT( aGlobalOrder
.empty(), "sort twice?" );
2111 aGlobalOrder
.resize( nCount
);
2112 for (long nPos
=0; nPos
<nCount
; nPos
++)
2113 aGlobalOrder
[nPos
] = nPos
;
2115 // allow manual or name (manual is always ascending)
2116 BOOL bAscending
= ( aSortInfo
.Mode
== sheet::DataPilotFieldSortMode::MANUAL
|| aSortInfo
.IsAscending
);
2117 ScDPGlobalMembersOrder
aComp( *this, bAscending
);
2118 ::std::sort( aGlobalOrder
.begin(), aGlobalOrder
.end(), aComp
);
2123 if ( aAutoShowInfo
.IsEnabled
)
2125 // find index of measure (index among data dimensions)
2127 String aDataFieldName
= aAutoShowInfo
.DataField
;
2128 long nMeasureCount
= pSource
->GetDataDimensionCount();
2129 for (long nMeasure
=0; nMeasure
<nMeasureCount
; nMeasure
++)
2131 if ( pSource
->GetDataDimName(nMeasure
) == aDataFieldName
)
2133 nAutoMeasure
= nMeasure
;
2138 //! error if not found?
2142 void ScDPLevel::SetEnableLayout( BOOL bSet
)
2144 bEnableLayout
= bSet
;
2147 ScDPMembers
* ScDPLevel::GetMembersObject()
2151 pMembers
= new ScDPMembers( pSource
, nDim
, nHier
, nLev
);
2152 pMembers
->acquire(); // ref-counted
2157 uno::Reference
<container::XNameAccess
> SAL_CALL
ScDPLevel::getMembers() throw(uno::RuntimeException
)
2159 return GetMembersObject();
2162 uno::Sequence
<sheet::MemberResult
> SAL_CALL
ScDPLevel::getResults() throw(uno::RuntimeException
)
2164 const uno::Sequence
<sheet::MemberResult
>* pRes
= pSource
->GetMemberResults( this );
2168 return uno::Sequence
<sheet::MemberResult
>(0); //! Error?
2171 ::rtl::OUString SAL_CALL
ScDPLevel::getName() throw(uno::RuntimeException
)
2173 long nSrcDim
= pSource
->GetSourceDim( nDim
);
2174 if ( pSource
->IsDateDimension( nSrcDim
) )
2176 String aRet
; //! globstr-ID !!!!
2178 if ( nHier
== SC_DAPI_HIERARCHY_QUARTER
)
2182 case SC_DAPI_LEVEL_YEAR
:
2183 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Year"));
2185 case SC_DAPI_LEVEL_QUARTER
:
2186 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Quarter"));
2188 case SC_DAPI_LEVEL_MONTH
:
2189 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Month"));
2191 case SC_DAPI_LEVEL_DAY
:
2192 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Day"));
2195 DBG_ERROR( "ScDPLevel::getName: unexpected level" );
2199 else if ( nHier
== SC_DAPI_HIERARCHY_WEEK
)
2203 case SC_DAPI_LEVEL_YEAR
:
2204 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Year"));
2206 case SC_DAPI_LEVEL_WEEK
:
2207 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Week"));
2209 case SC_DAPI_LEVEL_WEEKDAY
:
2210 aRet
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Weekday"));
2213 DBG_ERROR( "ScDPLevel::getName: unexpected level" );
2221 ScDPDimension
* pDim
= pSource
->GetDimensionsObject()->getByIndex(nSrcDim
);
2223 return rtl::OUString();
2225 return pDim
->getName();
2228 void SAL_CALL
ScDPLevel::setName( const ::rtl::OUString
& /* rNewName */ ) throw(uno::RuntimeException
)
2230 DBG_ERROR("not implemented"); //! exception?
2233 uno::Sequence
<sheet::GeneralFunction
> ScDPLevel::getSubTotals() const
2235 //! separate functions for settings and evaluation?
2237 long nSrcDim
= pSource
->GetSourceDim( nDim
);
2238 if ( !pSource
->SubTotalAllowed( nSrcDim
) )
2239 return uno::Sequence
<sheet::GeneralFunction
>(0);
2244 void ScDPLevel::setSubTotals(const uno::Sequence
<sheet::GeneralFunction
>& rNew
)
2247 //! set "manual change" flag?
2250 BOOL
ScDPLevel::getShowEmpty() const
2255 void ScDPLevel::setShowEmpty(BOOL bSet
)
2262 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScDPLevel::getPropertySetInfo()
2263 throw(uno::RuntimeException
)
2267 static SfxItemPropertyMap aDPLevelMap_Impl
[] =
2269 //! change type of AutoShow/Layout/Sorting to API struct when available
2270 {MAP_CHAR_LEN(SC_UNO_AUTOSHOW
), 0, &getCppuType((sheet::DataPilotFieldAutoShowInfo
*)0), 0, 0 },
2271 {MAP_CHAR_LEN(SC_UNO_LAYOUT
), 0, &getCppuType((sheet::DataPilotFieldLayoutInfo
*)0), 0, 0 },
2272 {MAP_CHAR_LEN(SC_UNO_SHOWEMPT
), 0, &getBooleanCppuType(), 0, 0 },
2273 {MAP_CHAR_LEN(SC_UNO_SORTING
), 0, &getCppuType((sheet::DataPilotFieldSortInfo
*)0), 0, 0 },
2274 {MAP_CHAR_LEN(SC_UNO_SUBTOTAL
), 0, &getCppuType((uno::Sequence
<sheet::GeneralFunction
>*)0), 0, 0 },
2277 static uno::Reference
<beans::XPropertySetInfo
> aRef
=
2278 new SfxItemPropertySetInfo( aDPLevelMap_Impl
);
2282 void SAL_CALL
ScDPLevel::setPropertyValue( const rtl::OUString
& aPropertyName
, const uno::Any
& aValue
)
2283 throw(beans::UnknownPropertyException
, beans::PropertyVetoException
,
2284 lang::IllegalArgumentException
, lang::WrappedTargetException
,
2285 uno::RuntimeException
)
2287 String aNameStr
= aPropertyName
;
2288 if ( aNameStr
.EqualsAscii( SC_UNO_SHOWEMPT
) )
2289 setShowEmpty( lcl_GetBoolFromAny( aValue
) );
2290 else if ( aNameStr
.EqualsAscii( SC_UNO_SUBTOTAL
) )
2292 uno::Sequence
<sheet::GeneralFunction
> aSeq
;
2293 if ( aValue
>>= aSeq
)
2294 setSubTotals( aSeq
);
2296 else if ( aNameStr
.EqualsAscii( SC_UNO_SORTING
) )
2297 aValue
>>= aSortInfo
;
2298 else if ( aNameStr
.EqualsAscii( SC_UNO_AUTOSHOW
) )
2299 aValue
>>= aAutoShowInfo
;
2300 else if ( aNameStr
.EqualsAscii( SC_UNO_LAYOUT
) )
2301 aValue
>>= aLayoutInfo
;
2304 DBG_ERROR("unknown property");
2305 //! THROW( UnknownPropertyException() );
2309 uno::Any SAL_CALL
ScDPLevel::getPropertyValue( const rtl::OUString
& aPropertyName
)
2310 throw(beans::UnknownPropertyException
, lang::WrappedTargetException
,
2311 uno::RuntimeException
)
2314 String aNameStr
= aPropertyName
;
2315 if ( aNameStr
.EqualsAscii( SC_UNO_SHOWEMPT
) )
2316 lcl_SetBoolInAny( aRet
, getShowEmpty() );
2317 else if ( aNameStr
.EqualsAscii( SC_UNO_SUBTOTAL
) )
2319 uno::Sequence
<sheet::GeneralFunction
> aSeq
= getSubTotals(); //! avoid extra copy?
2322 else if ( aNameStr
.EqualsAscii( SC_UNO_SORTING
) )
2324 else if ( aNameStr
.EqualsAscii( SC_UNO_AUTOSHOW
) )
2325 aRet
<<= aAutoShowInfo
;
2326 else if ( aNameStr
.EqualsAscii( SC_UNO_LAYOUT
) )
2327 aRet
<<= aLayoutInfo
;
2328 else if (aNameStr
.EqualsAscii(SC_UNO_LAYOUTNAME
))
2330 // read only property
2331 long nSrcDim
= pSource
->GetSourceDim(nDim
);
2332 ScDPDimension
* pDim
= pSource
->GetDimensionsObject()->getByIndex(nSrcDim
);
2336 const OUString
* pLayoutName
= pDim
->GetLayoutName();
2340 aRet
<<= *pLayoutName
;
2344 DBG_ERROR("unknown property");
2345 //! THROW( UnknownPropertyException() );
2350 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPLevel
)
2352 // -----------------------------------------------------------------------
2354 USHORT
lcl_GetFirstStringPos( const TypedScStrCollection
& rColl
)
2357 USHORT nCount
= rColl
.GetCount();
2358 while ( nPos
< nCount
&& !rColl
[nPos
]->IsStrData() )
2363 ScDPMembers::ScDPMembers( ScDPSource
* pSrc
, long nD
, long nH
, long nL
) :
2372 long nSrcDim
= pSource
->GetSourceDim( nDim
);
2373 if ( pSource
->IsDataLayoutDimension(nSrcDim
) )
2374 nMbrCount
= pSource
->GetDataDimensionCount();
2375 else if ( nHier
!= SC_DAPI_HIERARCHY_FLAT
&& pSource
->IsDateDimension( nSrcDim
) )
2378 if ( nHier
== SC_DAPI_HIERARCHY_QUARTER
)
2382 case SC_DAPI_LEVEL_YEAR
:
2384 const TypedScStrCollection
& rStrings
= pSource
->GetData()->GetColumnEntries(nSrcDim
);
2385 USHORT nFirstString
= lcl_GetFirstStringPos( rStrings
);
2386 if ( nFirstString
> 0 )
2388 double fFirstVal
= rStrings
[0]->GetValue();
2389 double fLastVal
= rStrings
[nFirstString
-1]->GetValue();
2391 long nFirstYear
= pSource
->GetData()->GetDatePart(
2392 (long)::rtl::math::approxFloor( fFirstVal
),
2394 long nLastYear
= pSource
->GetData()->GetDatePart(
2395 (long)::rtl::math::approxFloor( fLastVal
),
2398 nMbrCount
= nLastYear
+ 1 - nFirstYear
;
2401 nMbrCount
= 0; // no values
2404 case SC_DAPI_LEVEL_QUARTER
: nMbrCount
= 4; break;
2405 case SC_DAPI_LEVEL_MONTH
: nMbrCount
= 12; break;
2406 case SC_DAPI_LEVEL_DAY
: nMbrCount
= 31; break;
2408 DBG_ERROR( "ScDPMembers::ScDPMembers: unexpected level" );
2412 else if ( nHier
== SC_DAPI_HIERARCHY_WEEK
)
2416 case SC_DAPI_LEVEL_YEAR
: nMbrCount
= 1; break; //! get years from source
2417 case SC_DAPI_LEVEL_WEEK
: nMbrCount
= 53; break;
2418 case SC_DAPI_LEVEL_WEEKDAY
: nMbrCount
= 7; break;
2420 DBG_ERROR( "ScDPMembers::ScDPMembers: unexpected level" );
2427 // StringCollection is cached at TableData
2428 const TypedScStrCollection
& rStrings
= pSource
->GetData()->GetColumnEntries(nSrcDim
);
2429 nMbrCount
= rStrings
.GetCount();
2433 ScDPMembers::~ScDPMembers()
2439 for (long i
=0; i
<nMbrCount
; i
++)
2441 ppMbrs
[i
]->release(); // ref-counted
2446 // XNameAccess implementation using getCount/getByIndex
2448 sal_Int32
ScDPMembers::GetIndexFromName( const ::rtl::OUString
& rName
) const
2450 if ( aHashMap
.empty() )
2452 // store the index for each name
2454 sal_Int32 nCount
= getCount();
2455 for (sal_Int32 i
=0; i
<nCount
; i
++)
2456 aHashMap
[ getByIndex(i
)->getName() ] = i
;
2459 ScDPMembersHashMap::const_iterator aIter
= aHashMap
.find( rName
);
2460 if ( aIter
!= aHashMap
.end() )
2461 return aIter
->second
; // found index
2463 return -1; // not found
2466 uno::Any SAL_CALL
ScDPMembers::getByName( const rtl::OUString
& aName
)
2467 throw(container::NoSuchElementException
,
2468 lang::WrappedTargetException
, uno::RuntimeException
)
2470 sal_Int32 nIndex
= GetIndexFromName( aName
);
2473 uno::Reference
<container::XNamed
> xNamed
= getByIndex(nIndex
);
2479 throw container::NoSuchElementException();
2480 // return uno::Any();
2483 uno::Sequence
<rtl::OUString
> SAL_CALL
ScDPMembers::getElementNames() throw(uno::RuntimeException
)
2485 // Return list of names in sorted order,
2486 // so it's displayed in that order in the field options dialog.
2487 // Sorting is done at the level object (parent of this).
2489 ScDPLevel
* pLevel
= pSource
->GetDimensionsObject()->getByIndex(nDim
)->
2490 GetHierarchiesObject()->getByIndex(nHier
)->GetLevelsObject()->getByIndex(nLev
);
2491 pLevel
->EvaluateSortOrder();
2492 const std::vector
<sal_Int32
>& rGlobalOrder
= pLevel
->GetGlobalOrder();
2493 bool bSort
= !rGlobalOrder
.empty();
2495 long nCount
= getCount();
2496 uno::Sequence
<rtl::OUString
> aSeq(nCount
);
2497 rtl::OUString
* pArr
= aSeq
.getArray();
2498 for (long i
=0; i
<nCount
; i
++)
2499 pArr
[i
] = getByIndex(bSort
? rGlobalOrder
[i
] : i
)->getName();
2503 sal_Bool SAL_CALL
ScDPMembers::hasByName( const rtl::OUString
& aName
) throw(uno::RuntimeException
)
2505 return ( GetIndexFromName( aName
) >= 0 );
2508 uno::Type SAL_CALL
ScDPMembers::getElementType() throw(uno::RuntimeException
)
2510 return getCppuType((uno::Reference
<container::XNamed
>*)0);
2513 sal_Bool SAL_CALL
ScDPMembers::hasElements() throw(uno::RuntimeException
)
2515 return ( getCount() > 0 );
2518 // end of XNameAccess implementation
2520 long ScDPMembers::getCount() const
2525 long ScDPMembers::getMinMembers() const
2527 // used in lcl_CountMinMembers
2532 for (long i
=0; i
<nMbrCount
; i
++)
2534 // count only visible with details (default is true for both)
2535 const ScDPMember
* pMbr
= ppMbrs
[i
];
2536 if ( !pMbr
|| ( pMbr
->getIsVisible() && pMbr
->getShowDetails() ) )
2541 nVisCount
= nMbrCount
; // default for all
2546 ScDPMember
* ScDPMembers::getByIndex(long nIndex
) const
2548 // result of GetColumnEntries must not change between ScDPMembers ctor
2549 // and all calls to getByIndex
2551 if ( nIndex
>= 0 && nIndex
< nMbrCount
)
2555 ((ScDPMembers
*)this)->ppMbrs
= new ScDPMember
*[nMbrCount
];
2556 for (long i
=0; i
<nMbrCount
; i
++)
2559 if ( !ppMbrs
[nIndex
] )
2562 long nSrcDim
= pSource
->GetSourceDim( nDim
);
2563 if ( pSource
->IsDataLayoutDimension(nSrcDim
) )
2565 // empty name (never shown, not used for lookup)
2566 pNew
= new ScDPMember( pSource
, nDim
, nHier
, nLev
,
2567 String(), 0.0, FALSE
);
2569 else if ( nHier
!= SC_DAPI_HIERARCHY_FLAT
&& pSource
->IsDateDimension( nSrcDim
) )
2574 if ( nLev
== SC_DAPI_LEVEL_YEAR
) // YEAR is in both hierarchies
2576 //! cache year range here!
2578 const TypedScStrCollection
& rStrings
= pSource
->GetData()->GetColumnEntries(nSrcDim
);
2579 double fFirstVal
= rStrings
[0]->GetValue();
2580 long nFirstYear
= pSource
->GetData()->GetDatePart(
2581 (long)::rtl::math::approxFloor( fFirstVal
),
2584 nVal
= nFirstYear
+ nIndex
;
2586 else if ( nHier
== SC_DAPI_HIERARCHY_WEEK
&& nLev
== SC_DAPI_LEVEL_WEEKDAY
)
2588 nVal
= nIndex
; // DayOfWeek is 0-based
2589 aName
= ScGlobal::pCalendar
->getDisplayName(
2590 ::com::sun::star::i18n::CalendarDisplayIndex::DAY
,
2591 sal::static_int_cast
<sal_Int16
>(nVal
), 0 );
2593 else if ( nHier
== SC_DAPI_HIERARCHY_QUARTER
&& nLev
== SC_DAPI_LEVEL_MONTH
)
2595 nVal
= nIndex
; // Month is 0-based
2596 aName
= ScGlobal::pCalendar
->getDisplayName(
2597 ::com::sun::star::i18n::CalendarDisplayIndex::MONTH
,
2598 sal::static_int_cast
<sal_Int16
>(nVal
), 0 );
2601 nVal
= nIndex
+ 1; // Quarter, Day, Week are 1-based
2604 aName
= String::CreateFromInt32(nVal
);
2606 pNew
= new ScDPMember( pSource
, nDim
, nHier
, nLev
, aName
, nVal
, TRUE
);
2610 const TypedScStrCollection
& rStrings
= pSource
->GetData()->GetColumnEntries(nSrcDim
);
2611 const TypedStrData
* pData
= rStrings
[(USHORT
)nIndex
];
2612 pNew
= new ScDPMember( pSource
, nDim
, nHier
, nLev
,
2613 pData
->GetString(), pData
->GetValue(), !pData
->IsStrData() );
2615 pNew
->acquire(); // ref-counted
2616 ppMbrs
[nIndex
] = pNew
;
2619 return ppMbrs
[nIndex
];
2622 return NULL
; //! exception?
2625 // -----------------------------------------------------------------------
2627 ScDPMember::ScDPMember( ScDPSource
* pSrc
, long nD
, long nH
, long nL
,
2628 const String
& rN
, double fV
, BOOL bHV
) :
2633 maData( rN
, fV
, bHV
),
2642 ScDPMember::~ScDPMember()
2647 BOOL
ScDPMember::IsNamedItem( const ScDPItemData
& r
) const
2649 long nSrcDim
= pSource
->GetSourceDim( nDim
);
2650 if ( nHier
!= SC_DAPI_HIERARCHY_FLAT
&& pSource
->IsDateDimension( nSrcDim
) && r
.bHasValue
)
2652 long nComp
= pSource
->GetData()->GetDatePart(
2653 (long)::rtl::math::approxFloor( r
.fValue
),
2656 // fValue is converted from integer, so simple comparison works
2657 return nComp
== maData
.fValue
;
2660 return r
.IsCaseInsEqual( maData
);
2663 sal_Int32
ScDPMember::Compare( const ScDPMember
& rOther
) const
2665 if ( nPosition
>= 0 )
2667 if ( rOther
.nPosition
>= 0 )
2669 DBG_ASSERT( nPosition
!= rOther
.nPosition
, "same position for two members" );
2670 return ( nPosition
< rOther
.nPosition
) ? -1 : 1;
2674 // only this has a position - members with specified positions come before those without
2678 else if ( rOther
.nPosition
>= 0 )
2680 // only rOther has a position
2684 // no positions set - compare names
2685 return ScDPItemData::Compare( maData
, rOther
.maData
);
2688 void ScDPMember::FillItemData( ScDPItemData
& rData
) const
2690 //! handle date hierarchy...
2695 const OUString
* ScDPMember::GetLayoutName() const
2697 return mpLayoutName
.get();
2700 String
ScDPMember::GetNameStr() const
2702 return maData
.aString
;
2705 ::rtl::OUString SAL_CALL
ScDPMember::getName() throw(uno::RuntimeException
)
2707 return maData
.aString
;
2710 void SAL_CALL
ScDPMember::setName( const ::rtl::OUString
& /* rNewName */ ) throw(uno::RuntimeException
)
2712 DBG_ERROR("not implemented"); //! exception?
2715 BOOL
ScDPMember::getIsVisible() const
2720 void ScDPMember::setIsVisible(BOOL bSet
)
2723 //! set "manual change" flag
2726 BOOL
ScDPMember::getShowDetails() const
2731 void ScDPMember::setShowDetails(BOOL bSet
)
2734 //! set "manual change" flag
2737 sal_Int32
ScDPMember::getPosition() const
2742 void ScDPMember::setPosition(sal_Int32 nNew
)
2749 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScDPMember::getPropertySetInfo()
2750 throw(uno::RuntimeException
)
2754 static SfxItemPropertyMap aDPMemberMap_Impl
[] =
2756 {MAP_CHAR_LEN(SC_UNO_ISVISIBL
), 0, &getBooleanCppuType(), 0, 0 },
2757 {MAP_CHAR_LEN(SC_UNO_POSITION
), 0, &getCppuType((sal_Int32
*)0), 0, 0 },
2758 {MAP_CHAR_LEN(SC_UNO_SHOWDETA
), 0, &getBooleanCppuType(), 0, 0 },
2759 {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME
), 0, &getCppuType(static_cast<rtl::OUString
*>(0)), 0, 0 },
2762 static uno::Reference
<beans::XPropertySetInfo
> aRef
=
2763 new SfxItemPropertySetInfo( aDPMemberMap_Impl
);
2767 void SAL_CALL
ScDPMember::setPropertyValue( const rtl::OUString
& aPropertyName
, const uno::Any
& aValue
)
2768 throw(beans::UnknownPropertyException
, beans::PropertyVetoException
,
2769 lang::IllegalArgumentException
, lang::WrappedTargetException
,
2770 uno::RuntimeException
)
2772 String aNameStr
= aPropertyName
;
2773 if ( aNameStr
.EqualsAscii( SC_UNO_ISVISIBL
) )
2774 setIsVisible( lcl_GetBoolFromAny( aValue
) );
2775 else if ( aNameStr
.EqualsAscii( SC_UNO_SHOWDETA
) )
2776 setShowDetails( lcl_GetBoolFromAny( aValue
) );
2777 else if ( aNameStr
.EqualsAscii( SC_UNO_POSITION
) )
2780 if (aValue
>>= nInt
)
2781 setPosition( nInt
);
2783 else if (aNameStr
.EqualsAscii(SC_UNO_LAYOUTNAME
))
2785 rtl::OUString aName
;
2786 if (aValue
>>= aName
)
2787 mpLayoutName
.reset(new rtl::OUString(aName
));
2791 DBG_ERROR("unknown property");
2792 //! THROW( UnknownPropertyException() );
2796 uno::Any SAL_CALL
ScDPMember::getPropertyValue( const rtl::OUString
& aPropertyName
)
2797 throw(beans::UnknownPropertyException
, lang::WrappedTargetException
,
2798 uno::RuntimeException
)
2801 String aNameStr
= aPropertyName
;
2802 if ( aNameStr
.EqualsAscii( SC_UNO_ISVISIBL
) )
2803 lcl_SetBoolInAny( aRet
, getIsVisible() );
2804 else if ( aNameStr
.EqualsAscii( SC_UNO_SHOWDETA
) )
2805 lcl_SetBoolInAny( aRet
, getShowDetails() );
2806 else if ( aNameStr
.EqualsAscii( SC_UNO_POSITION
) )
2807 aRet
<<= (sal_Int32
) getPosition();
2808 else if (aNameStr
.EqualsAscii(SC_UNO_LAYOUTNAME
))
2809 aRet
<<= mpLayoutName
.get() ? *mpLayoutName
: rtl::OUString();
2812 DBG_ERROR("unknown property");
2813 //! THROW( UnknownPropertyException() );
2818 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPMember
)