Index: sc/inc/dptabdat.hxx
===================================================================
RCS file: /cvs/sc/sc/inc/dptabdat.hxx,v
retrieving revision 1.5
diff -u -w -p -r1.5 dptabdat.hxx
--- sc/inc/dptabdat.hxx	8 Sep 2005 17:36:18 -0000	1.5
+++ sc/inc/dptabdat.hxx	19 May 2006 14:50:21 -0000
@@ -82,8 +82,14 @@ struct ScDPItemData
 					aString(rS), fValue(fV), bHasValue( bHV ) {}
 
 	void		SetString( const String& rS ) { aString = rS; bHasValue = FALSE; }
-
 	BOOL		IsCaseInsEqual( const ScDPItemData& r ) const;
+
+	size_t		Hash() const;
+
+	// exact equality
+	BOOL		operator==( const ScDPItemData& r ) const;
+	// case insensitive equality
+	static sal_Int32	Compare( const ScDPItemData& rA, const ScDPItemData& rB );
 };
 
 #define SC_VALTYPE_EMPTY	0
Index: sc/inc/dptabres.hxx
===================================================================
RCS file: /cvs/sc/sc/inc/dptabres.hxx,v
retrieving revision 1.5
diff -u -w -p -r1.5 dptabres.hxx
--- sc/inc/dptabres.hxx	8 Sep 2005 17:36:34 -0000	1.5
+++ sc/inc/dptabres.hxx	19 May 2006 14:50:22 -0000
@@ -59,6 +59,8 @@
 #ifndef SC_SCGLOB_HXX
 #include "global.hxx"		// enum ScSubTotalFunc
 #endif
+#include <hash_map>
+#include <vector>
 
 namespace com { namespace sun { namespace star { namespace sheet {
     struct DataPilotFieldReference;
@@ -309,7 +311,7 @@ private:
 	ScDPResultData*			pResultData;
 	ScDPDimension*			pParentDim;				//! Ref
 	ScDPLevel*				pParentLevel;			//! Ref
-	ScDPMember*				pMemberDesc;			//! Ref
+	const ScDPMember*		pMemberDesc;			//! Ref
 	ScDPResultDimension*	pChildDimension;
 	ScDPDataMember*			pDataRoot;
 	BOOL					bHasElements;
@@ -341,6 +343,7 @@ public:
 	long				GetSubTotalCount( long* pUserSubStart = NULL ) const;
 
 	BOOL				IsNamedItem( const ScDPItemData& r ) const;
+	BOOL				IsValidEntry( const ScDPItemData* pMembers ) const;
 
 	void				SetHasElements()	{ bHasElements = TRUE; }
 	void                SetAutoHidden()     { bAutoHidden = TRUE; }
@@ -379,8 +382,8 @@ public:
 
 	ScDPDataMember*			GetDataRoot() const				{ return pDataRoot; }
 
-	ScDPDimension*			GetParentDim()		{ return pParentDim; }			//! Ref
-	ScDPLevel*				GetParentLevel()	{ return pParentLevel; }		//! Ref
+	const ScDPDimension*			GetParentDim() const			{ return pParentDim; }		//! Ref
+	const ScDPLevel*				GetParentLevel() const			{ return pParentLevel; }	//! Ref
 
 	ScDPAggData*		GetColTotal( long nMeasure ) const;
 };
@@ -389,17 +392,17 @@ class ScDPDataMember
 {
 private:
 	ScDPResultData*			pResultData;
-	ScDPResultMember*		pResultMember;			//! Ref?
+	const ScDPResultMember*		pResultMember;			//! Ref?
 	ScDPDataDimension*		pChildDimension;
 	ScDPAggData				aAggregate;
 
 	void				UpdateValues( const ScDPValueData* pValues, const ScDPSubTotalState& rSubState );
 
 public:
-						ScDPDataMember( ScDPResultData* pData, ScDPResultMember* pRes );
+						ScDPDataMember( ScDPResultData* pData, const ScDPResultMember* pRes );
 						~ScDPDataMember();
 
-	void				InitFrom( ScDPResultDimension* pDim );
+	void				InitFrom( const ScDPResultDimension* pDim );
 
 	String				GetName() const;
 	BOOL				IsVisible() const;
@@ -453,9 +456,18 @@ SV_DECL_PTRARR_DEL(ScDPDataMembers, ScDP
 
 class ScDPResultDimension
 {
+public :
+	struct MemberHashFunc : public std::unary_function< const ScDPItemData &, size_t >
+	{
+		size_t operator() (const ScDPItemData &rData) const { return rData.Hash(); }
+	};
+	typedef	std::vector <ScDPResultMember *>							MemberArray;
+	typedef	std::hash_map <ScDPItemData, ScDPResultMember *, MemberHashFunc>	MemberHash;
+
 private:
 	ScDPResultData*			pResultData;
-	ScDPResultMembers		aMembers;
+	MemberArray				maMemberArray;
+	MemberHash				maMemberHash;
 	BOOL                    bInitialized;
 	String					aDimensionName;		//! or ptr to IntDimension?
 	BOOL					bIsDataLayout;		//! or ptr to IntDimension?
@@ -468,6 +480,7 @@ private:
 	long                    nAutoMeasure;
 	long                    nAutoCount;
 
+	ScDPResultMember* 		FindMember( const ScDPItemData& rData ) const;
 public:
 						ScDPResultDimension( ScDPResultData* pData );
 						~ScDPResultDimension();
@@ -520,7 +533,8 @@ public:
 
 						//	for ScDPDataDimension::InitFrom
 	long				GetMemberCount() const;
-	ScDPResultMember*	GetMember(long n) const;
+	const ScDPResultMember*	GetMember(long n) const;
+	ScDPResultMember*		GetMember(long n);
 
 	const ScMemberSortOrder& GetMemberOrder() const     { return aMemberOrder; }
 	ScMemberSortOrder&  GetMemberOrder()                { return aMemberOrder; }
@@ -544,7 +558,7 @@ class ScDPDataDimension
 {
 private:
 	ScDPResultData*		pResultData;
-	ScDPResultDimension* pResultDimension;  // column
+	const ScDPResultDimension* pResultDimension;  // column
 	ScDPDataMembers		aMembers;
 	BOOL				bIsDataLayout;		//! or ptr to IntDimension?
 
@@ -552,7 +566,7 @@ public:
 						ScDPDataDimension( ScDPResultData* pData );
 						~ScDPDataDimension();
 
-	void				InitFrom( ScDPResultDimension* pDim );		// recursive
+	void				InitFrom( const ScDPResultDimension* pDim );		// recursive
 	void				ProcessData( const ScDPItemData* pDataMembers, const ScDPValueData* pValues,
 									const ScDPSubTotalState& rSubState );
 
Index: sc/inc/dptabsrc.hxx
===================================================================
RCS file: /cvs/sc/sc/inc/dptabsrc.hxx,v
retrieving revision 1.7
diff -u -w -p -r1.7 dptabsrc.hxx
--- sc/inc/dptabsrc.hxx	8 Sep 2005 17:36:50 -0000	1.7
+++ sc/inc/dptabsrc.hxx	19 May 2006 14:50:22 -0000
@@ -116,6 +116,9 @@
 #include <cppuhelper/implbase5.hxx>
 #endif
 
+#ifndef SC_DPTABDAT_HXX
+#include "dptabdat.hxx"
+#endif
 
 class ScDPResultMember;
 class ScDPResultData;
@@ -762,10 +765,8 @@ private:
 	long			nHier;
 	long			nLev;
 
-	String			aName;				// name for api etc.
+	ScDPItemData	maData;
 //	String			aCaption;			// visible name (changeable by user)
-	double			fValue;				// used internally for matching
-	BOOL			bHasValue;			// TRUE if this is a value
 
 	BOOL			bVisible;
 	BOOL			bShowDet;
Index: sc/source/core/data/dptabdat.cxx
===================================================================
RCS file: /cvs/sc/sc/source/core/data/dptabdat.cxx,v
retrieving revision 1.9
diff -u -w -p -r1.9 dptabdat.cxx
--- sc/source/core/data/dptabdat.cxx	8 Sep 2005 18:24:11 -0000	1.9
+++ sc/source/core/data/dptabdat.cxx	19 May 2006 14:50:23 -0000
@@ -47,6 +47,9 @@
 #ifndef _UNOTOOLS_TRANSLITERATIONWRAPPER_HXX
 #include <unotools/transliterationwrapper.hxx>
 #endif
+#ifndef _UNOTOOLS_COLLATORWRAPPER_HXX
+#include <unotools/collatorwrapper.hxx>
+#endif
 
 #include "dptabdat.hxx"
 #include "global.hxx"
@@ -60,6 +63,55 @@ BOOL ScDPItemData::IsCaseInsEqual( const
 	return bHasValue ? ( r.bHasValue && rtl::math::approxEqual( fValue, r.fValue ) ) :
 					   ( !r.bHasValue &&
                         ScGlobal::pTransliteration->isEqual( aString, r.aString ) );
+}
+
+size_t ScDPItemData::Hash() const
+{
+    if ( bHasValue )
+		return (size_t) rtl::math::approxFloor( fValue );
+    else
+		// If we do unicode safe case insensitive hash we can drop
+		// ScDPItemData::operator== and use ::IsCasInsEqual
+		return rtl_ustr_hashCode_WithLength( aString.GetBuffer(), aString.Len() );
+}
+
+BOOL ScDPItemData::operator==( const ScDPItemData& r ) const
+{
+    if ( bHasValue )
+    {
+        if ( r.bHasValue )
+            return rtl::math::approxEqual( fValue, r.fValue );
+        else
+            return FALSE;
+    }
+    else if ( bHasValue )
+		return FALSE;
+    else
+		// need exact equality until we have a safe case insensitive string hash
+        return aString == r.aString;
+}
+
+sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA,
+								 const ScDPItemData& rB )
+{
+    if ( rA.bHasValue )
+    {
+        if ( rB.bHasValue )
+        {
+            if ( rtl::math::approxEqual( rA.fValue, rB.fValue ) )
+				return 0;
+			else if ( rA.fValue < rB.fValue )
+				return -1;
+			else
+				return 1;
+        }
+        else
+            return -1;           // values first
+    }
+    else if ( rB.bHasValue )
+        return 1;                // values first
+    else
+        return ScGlobal::pCollator->compareString( rA.aString, rB.aString );
 }
 
 // -----------------------------------------------------------------------
Index: sc/source/core/data/dptabres.cxx
===================================================================
RCS file: /cvs/sc/sc/source/core/data/dptabres.cxx,v
retrieving revision 1.7
diff -u -w -p -r1.7 dptabres.cxx
--- sc/source/core/data/dptabres.cxx	8 Sep 2005 18:24:27 -0000	1.7
+++ sc/source/core/data/dptabres.cxx	19 May 2006 14:50:23 -0000
@@ -48,9 +48,9 @@
 
 #include <algorithm>
 
+#include "dptabdat.hxx"
 #include "dptabres.hxx"
 #include "dptabsrc.hxx"
-#include "dptabdat.hxx"
 #include "global.hxx"
 #include "subtotal.hxx"
 #include "globstr.hrc"
@@ -131,7 +131,7 @@ public:
     BOOL operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const;
 };
 
-BOOL lcl_IsLess( ScDPDataMember* pDataMember1, ScDPDataMember* pDataMember2, long nMeasure, BOOL bAscending )
+static BOOL lcl_IsLess( const ScDPDataMember* pDataMember1, const ScDPDataMember* pDataMember2, long nMeasure, BOOL bAscending )
 {
     // members can be NULL if used for rows
 
@@ -162,7 +162,7 @@ BOOL lcl_IsLess( ScDPDataMember* pDataMe
     }
 }
 
-BOOL lcl_IsEqual( ScDPDataMember* pDataMember1, ScDPDataMember* pDataMember2, long nMeasure )
+static BOOL lcl_IsEqual( const ScDPDataMember* pDataMember1, const ScDPDataMember* pDataMember2, long nMeasure )
 {
     // members can be NULL if used for rows
 
@@ -195,13 +195,13 @@ BOOL lcl_IsEqual( ScDPDataMember* pDataM
 
 BOOL ScDPRowMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const
 {
-    ScDPResultMember* pMember1 = rDimension.GetMember(nIndex1);
-    ScDPResultMember* pMember2 = rDimension.GetMember(nIndex2);
+    const ScDPResultMember* pMember1 = rDimension.GetMember(nIndex1);
+    const ScDPResultMember* pMember2 = rDimension.GetMember(nIndex2);
 
     //  GetDataRoot can be NULL if there was no data.
     //  IsVisible == FALSE can happen after AutoShow.
-    ScDPDataMember* pDataMember1 = pMember1->IsVisible() ? pMember1->GetDataRoot() : NULL;
-    ScDPDataMember* pDataMember2 = pMember2->IsVisible() ? pMember2->GetDataRoot() : NULL;
+    const ScDPDataMember* pDataMember1 = pMember1->IsVisible() ? pMember1->GetDataRoot() : NULL;
+    const ScDPDataMember* pDataMember2 = pMember2->IsVisible() ? pMember2->GetDataRoot() : NULL;
 
     return lcl_IsLess( pDataMember1, pDataMember2, nMeasure, bAscending );
 }
@@ -692,7 +692,7 @@ ScDPAggData* ScDPRowTotals::GetGrandTota
 
 // -----------------------------------------------------------------------
 
-ScSubTotalFunc lcl_GetForceFunc( ScDPLevel* pLevel, long nFuncNo )
+static ScSubTotalFunc lcl_GetForceFunc( const ScDPLevel* pLevel, long nFuncNo )
 {
 	ScSubTotalFunc eRet = SUBTOTAL_FUNC_NONE;
 	if ( pLevel )
@@ -943,6 +943,17 @@ BOOL ScDPResultMember::IsNamedItem( cons
 		return ((ScDPMember*)pMemberDesc)->IsNamedItem( r );
 	return FALSE;
 }
+BOOL ScDPResultMember::IsValidEntry( const ScDPItemData* pMembers ) const
+{
+	if ( !IsValid() )
+		return FALSE;
+
+	const ScDPResultDimension* pChildDim = GetChildDimension();
+	if (pChildDim)
+		return pChildDim->IsValidEntry( pMembers + 1 );
+	else
+		return TRUE;
+}
 
 void ScDPResultMember::InitFrom( ScDPDimension** ppDim, ScDPLevel** ppLev, ScDPInitState& rInitState )
 {
@@ -1561,7 +1572,7 @@ ScDPAggData* ScDPResultMember::GetColTot
 
 // -----------------------------------------------------------------------
 
-ScDPDataMember::ScDPDataMember( ScDPResultData* pData, ScDPResultMember* pRes ) :
+ScDPDataMember::ScDPDataMember( ScDPResultData* pData, const ScDPResultMember* pRes ) :
 	pResultData( pData ),
 	pResultMember( pRes ),
 	pChildDimension( NULL )
@@ -1606,7 +1617,7 @@ BOOL ScDPDataMember::HasHiddenDetails() 
 		return FALSE;
 }
 
-void ScDPDataMember::InitFrom( ScDPResultDimension* pDim )
+void ScDPDataMember::InitFrom( const ScDPResultDimension* pDim )
 {
 	if ( !pChildDimension )
 		pChildDimension = new ScDPDataDimension(pResultData);
@@ -1671,7 +1682,7 @@ void ScDPDataMember::ProcessData( const 
 	{
 		if ( pChildDimension )
 		{
-			ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
+			const ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
 			aLocalSubState.nColSubTotalFunc = nUserPos;
 			aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
 		}
@@ -1828,7 +1839,7 @@ void ScDPDataMember::FillDataRow( const 
 			{
 				if ( pChildDimension )
 				{
-					ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
+					const ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
 					aLocalSubState.nColSubTotalFunc = nUserPos;
 					aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
 				}
@@ -1904,7 +1915,7 @@ void ScDPDataMember::UpdateDataRow( cons
     {
         if ( pChildDimension )
         {
-            ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
+            const ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
             aLocalSubState.nColSubTotalFunc = nUserPos;
             aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
         }
@@ -2016,7 +2027,7 @@ void ScDPDataMember::UpdateRunningTotals
             {
                 if ( pChildDimension )
                 {
-                    ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
+                    const ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
                     aLocalSubState.nColSubTotalFunc = nUserPos;
                     aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
                 }
@@ -2057,7 +2068,7 @@ void ScDPDataMember::UpdateRunningTotals
                             BOOL bRefDimInCol = ( nRefOrient == sheet::DataPilotFieldOrientation_COLUMN );
                             BOOL bRefDimInRow = ( nRefOrient == sheet::DataPilotFieldOrientation_ROW );
 
-                            ScDPResultDimension* pSelectDim = NULL;
+                            const ScDPResultDimension* pSelectDim = NULL;
                             long nRowPos = 0;
                             long nColPos = 0;
 
@@ -2110,7 +2121,7 @@ void ScDPDataMember::UpdateRunningTotals
                                 long nMyIndex = bRefDimInCol ? pColIndexes[nColPos] : pRowIndexes[nRowPos];
                                 if ( nMyIndex >= 0 && nMyIndex < pSelectDim->GetMemberCount() )
                                 {
-                                    ScDPResultMember* pMyRefMember = pSelectDim->GetMember(nMyIndex);
+                                    const ScDPResultMember* pMyRefMember = pSelectDim->GetMember(nMyIndex);
                                     if ( pMyRefMember && pMyRefMember->HasHiddenDetails() )
                                     {
                                         pSelectDim = NULL;          // don't calculate
@@ -2485,6 +2496,28 @@ ScDPResultDimension::ScDPResultDimension
 
 ScDPResultDimension::~ScDPResultDimension()
 {
+	for( int i = maMemberArray.size () ; i-- > 0 ; )
+		delete maMemberArray[i];
+}
+
+ScDPResultMember *ScDPResultDimension::FindMember( const ScDPItemData& rData ) const
+{
+	if( bIsDataLayout )
+		return maMemberArray[0];
+	MemberHash::const_iterator aRes = maMemberHash.find( rData );
+	if( aRes != maMemberHash.end() )
+		return aRes->second;
+
+	unsigned int i;
+	unsigned int nCount = maMemberArray.size();
+	ScDPResultMember* pResultMember;
+	for( i = 0; i < nCount ; i++ )
+	{
+		pResultMember = maMemberArray[i];
+		if ( pResultMember->IsNamedItem( rData ) )
+			return pResultMember;
+	}
+	return NULL;
 }
 
 void ScDPResultDimension::InitFrom( ScDPDimension** ppDim, ScDPLevel** ppLev, ScDPInitState& rInitState )
@@ -2531,14 +2564,20 @@ void ScDPResultDimension::InitFrom( ScDP
 			ScDPMember* pMember = pMembers->getByIndex(nSorted);
             if ( aCompare.IsIncluded( *pMember ) )
             {
-    			ScDPResultMember* pNew = new ScDPResultMember( pResultData, pThisDim,
+				std::pair< ScDPItemData, ScDPResultMember *> key;
+
+				key.second = new ScDPResultMember( pResultData, pThisDim,
     											pThisLevel, pMember, FALSE );
-    			aMembers.Insert( pNew, aMembers.Count() );
+    			maMemberArray.push_back( key.second );
 
-                ScDPItemData aMemberData;
-                pMember->FillItemData( aMemberData );
-                rInitState.AddMember( nDimSource, ScDPItemData( aMemberData ) );
-    			pNew->InitFrom( ppChildDim, ppChildLev, rInitState );
+				// honour order of maMemberArray and only insert if it does not
+				// already exist
+                pMember->FillItemData( key.first );
+				if ( maMemberHash.end() == maMemberHash.find( key.first ) )
+					maMemberHash.insert ( key );
+
+                rInitState.AddMember( nDimSource, key.first );
+    			key.second->InitFrom( ppChildDim, ppChildLev, rInitState );
     			rInitState.RemoveMember();
             }
 		}
@@ -2598,9 +2637,17 @@ void ScDPResultDimension::LateInitFrom( 
 				ScDPMember* pMember = pMembers->getByIndex(nSorted);
                 if ( aCompare.IsIncluded( *pMember ) )
                 {
-    				ScDPResultMember* pNew = new ScDPResultMember( pResultData, pThisDim,
+					std::pair< ScDPItemData, ScDPResultMember *> key;
+
+    				key.second = new ScDPResultMember( pResultData, pThisDim,
     												pThisLevel, pMember, FALSE );
-    				aMembers.Insert( pNew, aMembers.Count() );
+    				maMemberArray.push_back( key.second );
+
+					// honour order of maMemberArray and only insert if it does not
+					// already exist
+					pMember->FillItemData( key.first );
+					if ( maMemberHash.end() == maMemberHash.find( key.first ) )
+						maMemberHash.insert ( key );
                 }
 			}
 			bInitialized = TRUE;    // don't call again, even if no members were included
@@ -2609,20 +2656,29 @@ void ScDPResultDimension::LateInitFrom( 
 		//	initialize only specific member (or all if "show empty" flag is set)
 
 		BOOL bShowEmpty = pThisLevel->getShowEmpty();
-		long nCount = aMembers.Count();
+		if ( bIsDataLayout || bShowEmpty )
+		{
+			long nCount = maMemberArray.size();
 		for (long i=0; i<nCount; i++)
 		{
-			ScDPResultMember* pResultMember = aMembers[(USHORT)i];
-			if ( bIsDataLayout || bShowEmpty || pResultMember->IsNamedItem( rThisData ) )
+				ScDPResultMember* pResultMember = maMemberArray[i];
+				ScDPItemData aMemberData;
+				pResultMember->FillItemData( aMemberData );
+				rInitState.AddMember( nDimSource, aMemberData );
+				pResultMember->LateInitFrom( ppChildDim, ppChildLev, pChildData, rInitState );
+				rInitState.RemoveMember();
+			}
+		}
+		else
+		{
+			ScDPResultMember* pResultMember = FindMember( rThisData );
+			if( NULL != pResultMember )
 			{
                 ScDPItemData aMemberData;
                 pResultMember->FillItemData( aMemberData );
                 rInitState.AddMember( nDimSource, aMemberData );
 				pResultMember->LateInitFrom( ppChildDim, ppChildLev, pChildData, rInitState );
     			rInitState.RemoveMember();
-
-				if ( !bIsDataLayout && !bShowEmpty )
-					break;
 			}
 		}
 	}
@@ -2631,19 +2687,19 @@ void ScDPResultDimension::LateInitFrom( 
 long ScDPResultDimension::GetSize(long nMeasure) const
 {
 	long nTotal = 0;
-	long nMemberCount = aMembers.Count();
+	long nMemberCount = maMemberArray.size();
 	if (bIsDataLayout)
 	{
 		DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
 					"DataLayout dimension twice?");
 		//	repeat first member...
-		nTotal = nMemberCount * aMembers[0]->GetSize(0);	// all measures have equal size
+		nTotal = nMemberCount * maMemberArray[0]->GetSize(0);	// all measures have equal size
 	}
 	else
 	{
 		//	add all members
 		for (long nMem=0; nMem<nMemberCount; nMem++)
-			nTotal += aMembers[(USHORT)nMem]->GetSize(nMeasure);
+			nTotal += maMemberArray[nMem]->GetSize(nMeasure);
 	}
 	return nTotal;
 }
@@ -2651,23 +2707,9 @@ long ScDPResultDimension::GetSize(long n
 BOOL ScDPResultDimension::IsValidEntry( const ScDPItemData* pMembers ) const
 {
     // the ScDPItemData array must contain enough entries for all dimensions - this isn't checked
-
-	long nCount = aMembers.Count();
-	for (long i=0; i<nCount; i++)
-	{
-		ScDPResultMember* pMember = aMembers[(USHORT)i];
-		if ( bIsDataLayout || pMember->IsNamedItem( *pMembers ) )
-		{
-			if ( !pMember->IsValid() )
-				return FALSE;
-
-			ScDPResultDimension* pChildDim = pMember->GetChildDimension();
-			if (pChildDim)
-				return pChildDim->IsValidEntry( pMembers + 1 );
-			else
-				return TRUE;
-		}
-	}
+	const ScDPResultMember* pMember = FindMember( *pMembers );
+	if( NULL != pMember )
+		return pMember->IsValidEntry( pMembers );
 
 	DBG_ERROR("IsValidEntry: Member not found");
 	return FALSE;
@@ -2678,19 +2720,12 @@ void ScDPResultDimension::ProcessData( c
 							const ScDPValueData* pValues )
 {
     // the ScDPItemData array must contain enough entries for all dimensions - this isn't checked
-
-	long nCount = aMembers.Count();
-	for (long i=0; i<nCount; i++)
-	{
-		ScDPResultMember* pMember = aMembers[(USHORT)i];
-
-		// always first member for data layout dim
-		if ( bIsDataLayout || pMember->IsNamedItem( *pMembers ) )
+	ScDPResultMember* pMember = FindMember( *pMembers );
+	if( NULL != pMember )
 		{
 			pMember->ProcessData( pMembers + 1, pDataDim, pDataMembers, pValues );
 			return;
 		}
-	}
 
 	DBG_ERROR("ProcessData: Member not found");
 }
@@ -2699,19 +2734,19 @@ void ScDPResultDimension::FillMemberResu
 												long nStart, long nMeasure )
 {
 	long nPos = nStart;
-	long nCount = aMembers.Count();
+	long nCount = maMemberArray.size();
 
 	for (long i=0; i<nCount; i++)
 	{
 	    long nSorted = aMemberOrder.empty() ? i : aMemberOrder[i];
 
-		ScDPResultMember* pMember = aMembers[(USHORT)nSorted];
+		ScDPResultMember* pMember = maMemberArray[nSorted];
 		//	in data layout dimension, use first member with different measures/names
 		if ( bIsDataLayout )
 		{
 			String aMbrName = pResultData->GetMeasureDimensionName( nSorted );
 			String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE );
-			aMembers[0]->FillMemberResults( pSequences, nPos, nSorted, FALSE, &aMbrName, &aMbrCapt );
+			maMemberArray[0]->FillMemberResults( pSequences, nPos, nSorted, FALSE, &aMbrName, &aMbrCapt );
 		}
 		else if ( pMember->IsVisible() )
 			pMember->FillMemberResults( pSequences, nPos, nMeasure, FALSE, NULL, NULL );
@@ -2725,7 +2760,7 @@ void ScDPResultDimension::FillDataResult
 {
 	long nMemberRow = nRow;
 	long nMemberMeasure = nMeasure;
-	long nCount = aMembers.Count();
+	long nCount = maMemberArray.size();
 	for (long i=0; i<nCount; i++)
 	{
 	    long nSorted = aMemberOrder.empty() ? i : aMemberOrder[i];
@@ -2735,11 +2770,11 @@ void ScDPResultDimension::FillDataResult
 		{
 			DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
 						"DataLayout dimension twice?");
-			pMember = aMembers[0];
+			pMember = maMemberArray[0];
 			nMemberMeasure = nSorted;
 		}
 		else
-			pMember = aMembers[(USHORT)nSorted];
+			pMember = maMemberArray[nSorted];
 
 		if ( pMember->IsVisible() )
 			pMember->FillDataResults( pRefMember, rSequence, nMemberRow, nMemberMeasure );
@@ -2750,7 +2785,7 @@ void ScDPResultDimension::FillDataResult
 void ScDPResultDimension::UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const
 {
     long nMemberMeasure = nMeasure;
-    long nCount = aMembers.Count();
+    long nCount = maMemberArray.size();
     for (long i=0; i<nCount; i++)
     {
         const ScDPResultMember* pMember;
@@ -2758,11 +2793,11 @@ void ScDPResultDimension::UpdateDataResu
         {
             DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
                         "DataLayout dimension twice?");
-            pMember = aMembers[0];
+			pMember = maMemberArray[0];
             nMemberMeasure = i;
         }
         else
-            pMember = aMembers[(USHORT)i];
+			pMember = maMemberArray[i];
 
         if ( pMember->IsVisible() )
             pMember->UpdateDataResults( pRefMember, nMemberMeasure );
@@ -2771,7 +2806,7 @@ void ScDPResultDimension::UpdateDataResu
 
 void ScDPResultDimension::SortMembers( ScDPResultMember* pRefMember )
 {
-    long nCount = aMembers.Count();
+    long nCount = maMemberArray.size();
 
     if ( bSortByData )
     {
@@ -2792,7 +2827,7 @@ void ScDPResultDimension::SortMembers( S
     long nLoopCount = bIsDataLayout ? 1 : nCount;
     for (long i=0; i<nLoopCount; i++)
     {
-        ScDPResultMember* pMember = aMembers[(USHORT)i];
+        ScDPResultMember* pMember = maMemberArray[i];
         if ( pMember->IsVisible() )
             pMember->SortMembers( pRefMember );
     }
@@ -2800,7 +2835,7 @@ void ScDPResultDimension::SortMembers( S
 
 void ScDPResultDimension::DoAutoShow( ScDPResultMember* pRefMember )
 {
-    long nCount = aMembers.Count();
+    long nCount = maMemberArray.size();
 
     // handle children first, before changing the visible state
 
@@ -2808,7 +2843,7 @@ void ScDPResultDimension::DoAutoShow( Sc
     long nLoopCount = bIsDataLayout ? 1 : nCount;
     for (long i=0; i<nLoopCount; i++)
     {
-        ScDPResultMember* pMember = aMembers[(USHORT)i];
+        ScDPResultMember* pMember = maMemberArray[i];
         if ( pMember->IsVisible() )
             pMember->DoAutoShow( pRefMember );
     }
@@ -2829,16 +2864,16 @@ void ScDPResultDimension::DoAutoShow( Sc
         // look for equal values to the last included one
 
         long nIncluded = nAutoCount;
-        ScDPResultMember* pMember1 = aMembers[(USHORT)aAutoOrder[nIncluded - 1]];
-        ScDPDataMember* pDataMember1 = pMember1->IsVisible() ? pMember1->GetDataRoot() : NULL;
+        const ScDPResultMember* pMember1 = maMemberArray[aAutoOrder[nIncluded - 1]];
+        const ScDPDataMember* pDataMember1 = pMember1->IsVisible() ? pMember1->GetDataRoot() : NULL;
         BOOL bContinue = TRUE;
         while ( bContinue )
         {
             bContinue = FALSE;
             if ( nIncluded < nCount )
             {
-                ScDPResultMember* pMember2 = aMembers[(USHORT)aAutoOrder[nIncluded]];
-                ScDPDataMember* pDataMember2 = pMember2->IsVisible() ? pMember2->GetDataRoot() : NULL;
+                const ScDPResultMember* pMember2 = maMemberArray[aAutoOrder[nIncluded]];
+                const ScDPDataMember* pDataMember2 = pMember2->IsVisible() ? pMember2->GetDataRoot() : NULL;
 
                 if ( lcl_IsEqual( pDataMember1, pDataMember2, nAutoMeasure ) )
                 {
@@ -2852,7 +2887,7 @@ void ScDPResultDimension::DoAutoShow( Sc
 
         for (nPos = nIncluded; nPos < nCount; nPos++)
         {
-            ScDPResultMember* pMember = aMembers[(USHORT)aAutoOrder[nPos]];
+            ScDPResultMember* pMember = maMemberArray[aAutoOrder[nPos]];
             pMember->SetAutoHidden();
         }
     }
@@ -2860,11 +2895,11 @@ void ScDPResultDimension::DoAutoShow( Sc
 
 void ScDPResultDimension::ResetResults()
 {
-    long nCount = aMembers.Count();
+    long nCount = maMemberArray.size();
     for (long i=0; i<nCount; i++)
     {
         // sort order doesn't matter
-        ScDPResultMember* pMember = aMembers[(USHORT)( bIsDataLayout ? 0 : i )];
+        ScDPResultMember* pMember = maMemberArray[bIsDataLayout ? 0 : i];
         pMember->ResetResults( FALSE );
     }
 }
@@ -2877,22 +2912,22 @@ long ScDPResultDimension::GetSortedIndex
 void ScDPResultDimension::UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure,
                                                 ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const
 {
+	const ScDPResultMember* pMember;
     long nMemberMeasure = nMeasure;
-    long nCount = aMembers.Count();
+    long nCount = maMemberArray.size();
     for (long i=0; i<nCount; i++)
     {
 	    long nSorted = aMemberOrder.empty() ? i : aMemberOrder[i];
 
-        const ScDPResultMember* pMember;
         if (bIsDataLayout)
         {
             DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
                         "DataLayout dimension twice?");
-            pMember = aMembers[0];
+            pMember = maMemberArray[0];
             nMemberMeasure = nSorted;
         }
         else
-            pMember = aMembers[(USHORT)nSorted];
+            pMember = maMemberArray[nSorted];
 
         if ( pMember->IsVisible() )
         {
@@ -2916,7 +2951,7 @@ ScDPDataMember* ScDPResultDimension::Get
     ScDPDataMember* pColMember = NULL;
 
     BOOL bFirstExisting = ( pRelativePos == NULL && pName == NULL );
-    long nMemberCount = aMembers.Count();
+    long nMemberCount = maMemberArray.size();
     long nMemberIndex = 0;      // unsorted
     long nDirection = 1;        // forward if no relative position is used
     if ( pRelativePos )
@@ -2930,14 +2965,14 @@ ScDPDataMember* ScDPResultDimension::Get
     {
         // search for named member
 
-        ScDPResultMember* pRowMember = aMembers[(USHORT)GetSortedIndex(nMemberIndex)];
+        const ScDPResultMember* pRowMember = maMemberArray[GetSortedIndex(nMemberIndex)];
 
         //! use ScDPItemData, as in ScDPDimension::IsValidPage?
         while ( pRowMember && pRowMember->GetName() != *pName )
         {
             ++nMemberIndex;
             if ( nMemberIndex < nMemberCount )
-                pRowMember = aMembers[(USHORT)GetSortedIndex(nMemberIndex)];
+                pRowMember = maMemberArray[GetSortedIndex(nMemberIndex)];
             else
                 pRowMember = NULL;
         }
@@ -2946,7 +2981,7 @@ ScDPDataMember* ScDPResultDimension::Get
     BOOL bContinue = TRUE;
     while ( bContinue && nMemberIndex >= 0 && nMemberIndex < nMemberCount )
     {
-        ScDPResultMember* pRowMember = aMembers[(USHORT)GetSortedIndex(nMemberIndex)];
+        const ScDPResultMember* pRowMember = maMemberArray[GetSortedIndex(nMemberIndex)];
 
         // get child members by given indexes
 
@@ -3006,7 +3041,7 @@ ScDPDataMember* ScDPResultDimension::Get
 
     // get own row member using all indexes
 
-    ScDPResultMember* pRowMember = rRunning.GetRowResRoot();
+    const ScDPResultMember* pRowMember = rRunning.GetRowResRoot();
     ScDPDataMember* pColMember = NULL;
 
     const long* pNextRowIndex = pRowIndexes;
@@ -3123,10 +3158,10 @@ void ScDPResultDimension::DumpState( con
 
     SCROW nStartRow = rPos.Row();
 
-    long nCount = bIsDataLayout ? 1 : aMembers.Count();
+    long nCount = bIsDataLayout ? 1 : maMemberArray.size();
     for (long i=0; i<nCount; i++)
     {
-        const ScDPResultMember* pMember = aMembers[(USHORT)i];
+        const ScDPResultMember* pMember = maMemberArray[i];
         pMember->DumpState( pRefMember, pDoc, rPos );
     }
 
@@ -3135,18 +3170,22 @@ void ScDPResultDimension::DumpState( con
 
 long ScDPResultDimension::GetMemberCount() const
 {
-	return aMembers.Count();
+	return maMemberArray.size();
 }
 
-ScDPResultMember* ScDPResultDimension::GetMember(long n) const
+const ScDPResultMember* ScDPResultDimension::GetMember(long n) const
+{
+	return maMemberArray[n];
+}
+ScDPResultMember* ScDPResultDimension::GetMember(long n)
 {
-	return aMembers[(USHORT)n];
+	return maMemberArray[n];
 }
 
 ScDPResultDimension* ScDPResultDimension::GetFirstChildDimension() const
 {
-	if ( aMembers.Count() > 0 )
-		return aMembers[0]->GetChildDimension();
+	if ( maMemberArray.size() > 0 )
+		return maMemberArray[0]->GetChildDimension();
 	else
 		return NULL;
 }
@@ -3164,7 +3203,7 @@ ScDPDataDimension::~ScDPDataDimension()
 {
 }
 
-void ScDPDataDimension::InitFrom( ScDPResultDimension* pDim )
+void ScDPDataDimension::InitFrom( const ScDPResultDimension* pDim )
 {
 	if (!pDim)
 		return;
@@ -3175,7 +3214,7 @@ void ScDPDataDimension::InitFrom( ScDPRe
 	long nCount = pDim->GetMemberCount();
 	for (long i=0; i<nCount; i++)
 	{
-		ScDPResultMember* pResMem = pDim->GetMember(i);
+		const ScDPResultMember* pResMem = pDim->GetMember(i);
 
 		ScDPDataMember* pNew = new ScDPDataMember( pResultData, pResMem );
 		aMembers.Insert( pNew, aMembers.Count() );
@@ -3185,7 +3224,7 @@ void ScDPDataDimension::InitFrom( ScDPRe
 			//	with LateInit, pResMem hasn't necessarily been initialized yet,
 			//	so InitFrom for the new result member is called from its ProcessData method
 
-			ScDPResultDimension* pChildDim = pResMem->GetChildDimension();
+			const ScDPResultDimension* pChildDim = pResMem->GetChildDimension();
 			if ( pChildDim )
 				pNew->InitFrom( pChildDim );
 		}
Index: sc/source/core/data/dptabsrc.cxx
===================================================================
RCS file: /cvs/sc/sc/source/core/data/dptabsrc.cxx,v
retrieving revision 1.14
diff -u -w -p -r1.14 dptabsrc.cxx
--- sc/source/core/data/dptabsrc.cxx	7 Nov 2005 14:41:01 -0000	1.14
+++ sc/source/core/data/dptabsrc.cxx	19 May 2006 14:50:24 -0000
@@ -2399,9 +2399,7 @@ ScDPMember::ScDPMember( ScDPSource* pSrc
 	nDim( nD ),
 	nHier( nH ),
 	nLev( nL ),
-	aName( rN ),
-	fValue( fV ),
-	bHasValue( bHV ),
+	maData( rN, fV, bHV ),
 	bVisible( TRUE ),
 	bShowDet( TRUE )
 {
@@ -2423,54 +2421,32 @@ BOOL ScDPMember::IsNamedItem( const ScDP
 										nHier, nLev );
 
 		//	fValue is converted from integer, so simple comparison works
-		return nComp == fValue;
+		return nComp == maData.fValue;
 	}
 
-	return r.IsCaseInsEqual( ScDPItemData( aName, fValue, bHasValue ) );
+	return r.IsCaseInsEqual( maData );
 }
 
 sal_Int32 ScDPMember::Compare( const ScDPMember& rOther ) const
 {
-    sal_Int32 nResult;
-    if ( bHasValue )
-    {
-        if ( rOther.bHasValue )
-        {
-            if ( rtl::math::approxEqual( fValue, rOther.fValue ) )
-				nResult = 0;
-			else if ( fValue < rOther.fValue )
-				nResult = -1;
-			else
-				nResult = 1;
-        }
-        else
-            nResult = -1;           // values first
-    }
-    else if ( rOther.bHasValue )
-        nResult = 1;                // values first
-    else
-        nResult = ScGlobal::pCollator->compareString( aName, rOther.aName );
-
-    return nResult;
+	return ScDPItemData::Compare( maData, rOther.maData );
 }
 
 void ScDPMember::FillItemData( ScDPItemData& rData ) const
 {
 	//!	handle date hierarchy...
 
-	rData.aString   = aName;
-	rData.fValue    = fValue;
-	rData.bHasValue = bHasValue;
+	rData = maData;
 }
 
 String ScDPMember::GetNameStr() const
 {
-	return aName;
+	return maData.aString;
 }
 
 ::rtl::OUString SAL_CALL ScDPMember::getName() throw(uno::RuntimeException)
 {
-	return aName;
+	return maData.aString;
 }
 
 void SAL_CALL ScDPMember::setName( const ::rtl::OUString& rNewName ) throw(uno::RuntimeException)
