xref: /aoo41x/main/sc/source/core/data/dptablecache.cxx (revision 0deba7fb)
1d0626817SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3d0626817SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4d0626817SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5d0626817SAndrew Rist  * distributed with this work for additional information
6d0626817SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7d0626817SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8d0626817SAndrew Rist  * "License"); you may not use this file except in compliance
9d0626817SAndrew Rist  * with the License.  You may obtain a copy of the License at
10d0626817SAndrew Rist  *
11d0626817SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12d0626817SAndrew Rist  *
13d0626817SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14d0626817SAndrew Rist  * software distributed under the License is distributed on an
15d0626817SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16d0626817SAndrew Rist  * KIND, either express or implied.  See the License for the
17d0626817SAndrew Rist  * specific language governing permissions and limitations
18d0626817SAndrew Rist  * under the License.
19d0626817SAndrew Rist  *
20d0626817SAndrew Rist  *************************************************************/
21d0626817SAndrew Rist 
22d0626817SAndrew Rist 
23cdf0e10cSrcweir  // MARKER(update_precomp.py): autogen include statement, do not remove
24cdf0e10cSrcweir #include "precompiled_sc.hxx"
25cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
26cdf0e10cSrcweir #include "dptablecache.hxx"
27cdf0e10cSrcweir #include "dptabdat.hxx"
28cdf0e10cSrcweir #include "document.hxx"
29cdf0e10cSrcweir #include "cell.hxx"
30cdf0e10cSrcweir #include "globstr.hrc"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <rtl/math.hxx>
33cdf0e10cSrcweir #include "queryparam.hxx"
34cdf0e10cSrcweir #include "dpglobal.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "docoptio.hxx" //for ValidQuery
37cdf0e10cSrcweir #include <unotools/textsearch.hxx> //for ValidQuery
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp>
40cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
41cdf0e10cSrcweir #include <com/sun/star/sdbc/XRowSet.hpp>
42cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
43cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
44cdf0e10cSrcweir const double D_TIMEFACTOR = 86400.0;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir using namespace ::com::sun::star;
47cdf0e10cSrcweir 
48cdf0e10cSrcweir using ::com::sun::star::uno::Exception;
49cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
50cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY;
51cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY_THROW;
52b4df81e3SWang Lei 
53cdf0e10cSrcweir // -----------------------------------------------------------------------
54cdf0e10cSrcweir namespace
55cdf0e10cSrcweir {
lcl_isDate(sal_uLong nNumType)56cdf0e10cSrcweir 	sal_Bool lcl_isDate( sal_uLong nNumType )
57cdf0e10cSrcweir 	{
58cdf0e10cSrcweir 		return ( (nNumType & NUMBERFORMAT_DATE) != 0 )? 1:0 ;
59cdf0e10cSrcweir 	}
60cdf0e10cSrcweir 
lcl_Search(const std::vector<ScDPItemData * > & list,const::std::vector<SCROW> & rOrder,const ScDPItemData & item,SCROW & rIndex)61cdf0e10cSrcweir 	sal_Bool lcl_Search( const std::vector<ScDPItemData*>& list, const ::std::vector<SCROW>& rOrder, const ScDPItemData& item, SCROW& rIndex)
62cdf0e10cSrcweir 	{
63cdf0e10cSrcweir 		rIndex = list.size();
64cdf0e10cSrcweir 		sal_Bool bFound = sal_False;
65cdf0e10cSrcweir 		SCROW nLo = 0;
66cdf0e10cSrcweir 		SCROW nHi = list.size() - 1;
67cdf0e10cSrcweir 		SCROW nIndex;
68cdf0e10cSrcweir 		long nCompare;
69cdf0e10cSrcweir 		while (nLo <= nHi)
70cdf0e10cSrcweir 		{
71cdf0e10cSrcweir 			nIndex = (nLo + nHi) / 2;
72cdf0e10cSrcweir 			nCompare = ScDPItemData::Compare( *list[rOrder[nIndex]], item );
73cdf0e10cSrcweir 			if (nCompare < 0)
74cdf0e10cSrcweir 				nLo = nIndex + 1;
75cdf0e10cSrcweir 			else
76cdf0e10cSrcweir 			{
77cdf0e10cSrcweir 				nHi = nIndex - 1;
78cdf0e10cSrcweir 				if (nCompare == 0)
79cdf0e10cSrcweir 				{
80cdf0e10cSrcweir 					bFound = sal_True;
81cdf0e10cSrcweir 					nLo = nIndex;
82cdf0e10cSrcweir 				}
83cdf0e10cSrcweir 			}
84cdf0e10cSrcweir 		}
85cdf0e10cSrcweir 		rIndex = nLo;
86cdf0e10cSrcweir 		return bFound;
87cdf0e10cSrcweir 	}
88cdf0e10cSrcweir 
lcl_GetItemValue(const Reference<sdbc::XRow> & xRow,sal_Int32 nType,long nCol,const Date & rNullDate)89cdf0e10cSrcweir 	ScDPItemData*  lcl_GetItemValue(const Reference<sdbc::XRow>& xRow, sal_Int32 nType, long nCol,
90cdf0e10cSrcweir 	              const Date& rNullDate )
91cdf0e10cSrcweir     {
92cdf0e10cSrcweir         short nNumType = NUMBERFORMAT_NUMBER;
93cdf0e10cSrcweir         try
94cdf0e10cSrcweir         {
95cdf0e10cSrcweir             String rStr = xRow->getString(nCol);
96cdf0e10cSrcweir             double fValue = 0.0;
97cdf0e10cSrcweir             switch (nType)
98cdf0e10cSrcweir             {
99cdf0e10cSrcweir             case sdbc::DataType::BIT:
100cdf0e10cSrcweir             case sdbc::DataType::BOOLEAN:
101cdf0e10cSrcweir                 {
102cdf0e10cSrcweir                     nNumType = NUMBERFORMAT_LOGICAL;
103cdf0e10cSrcweir                     fValue  = xRow->getBoolean(nCol) ? 1 : 0;
104cdf0e10cSrcweir                     return new ScDPItemData( rStr, fValue,sal_True,nNumType);
105cdf0e10cSrcweir                 }
106cdf0e10cSrcweir                 //break;
107cdf0e10cSrcweir 
108cdf0e10cSrcweir             case sdbc::DataType::TINYINT:
109cdf0e10cSrcweir             case sdbc::DataType::SMALLINT:
110cdf0e10cSrcweir             case sdbc::DataType::INTEGER:
111cdf0e10cSrcweir             case sdbc::DataType::BIGINT:
112cdf0e10cSrcweir             case sdbc::DataType::FLOAT:
113cdf0e10cSrcweir             case sdbc::DataType::REAL:
114cdf0e10cSrcweir             case sdbc::DataType::DOUBLE:
115cdf0e10cSrcweir             case sdbc::DataType::NUMERIC:
116cdf0e10cSrcweir             case sdbc::DataType::DECIMAL:
117cdf0e10cSrcweir                 {
118cdf0e10cSrcweir                     //! do the conversion here?
119cdf0e10cSrcweir                     fValue = xRow->getDouble(nCol);
120cdf0e10cSrcweir                     return new ScDPItemData( rStr, fValue,sal_True);
121cdf0e10cSrcweir                 }
122cdf0e10cSrcweir                 //break;
123cdf0e10cSrcweir 
124cdf0e10cSrcweir             case sdbc::DataType::DATE:
125cdf0e10cSrcweir                 {
126cdf0e10cSrcweir                     nNumType = NUMBERFORMAT_DATE;
127cdf0e10cSrcweir 
128cdf0e10cSrcweir                     util::Date aDate = xRow->getDate(nCol);
129cdf0e10cSrcweir                     fValue = Date(aDate.Day, aDate.Month, aDate.Year) - rNullDate;
130cdf0e10cSrcweir                     return new ScDPItemData( rStr, fValue, sal_True, nNumType );
131cdf0e10cSrcweir                 }
132cdf0e10cSrcweir                 //break;
133cdf0e10cSrcweir 
134cdf0e10cSrcweir             case sdbc::DataType::TIME:
135cdf0e10cSrcweir                 {
136cdf0e10cSrcweir                     nNumType = NUMBERFORMAT_TIME;
137cdf0e10cSrcweir 
138cdf0e10cSrcweir                     util::Time aTime = xRow->getTime(nCol);
139cdf0e10cSrcweir                     fValue = ( aTime.Hours * 3600 + aTime.Minutes * 60 +
140cdf0e10cSrcweir                         aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
141cdf0e10cSrcweir                     return new ScDPItemData( rStr,fValue, sal_True, nNumType );
142cdf0e10cSrcweir                 }
143cdf0e10cSrcweir                 //break;
144cdf0e10cSrcweir 
145cdf0e10cSrcweir             case sdbc::DataType::TIMESTAMP:
146cdf0e10cSrcweir                 {
147cdf0e10cSrcweir                     nNumType = NUMBERFORMAT_DATETIME;
148cdf0e10cSrcweir 
149cdf0e10cSrcweir                     util::DateTime aStamp = xRow->getTimestamp(nCol);
150cdf0e10cSrcweir                     fValue = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - rNullDate ) +
151cdf0e10cSrcweir                         ( aStamp.Hours * 3600 + aStamp.Minutes * 60 +
152cdf0e10cSrcweir                         aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
153cdf0e10cSrcweir                     return new ScDPItemData( rStr,fValue, sal_True, nNumType );
154cdf0e10cSrcweir                 }
155cdf0e10cSrcweir                 //break;
156cdf0e10cSrcweir             case sdbc::DataType::CHAR:
157cdf0e10cSrcweir             case sdbc::DataType::VARCHAR:
158cdf0e10cSrcweir             case sdbc::DataType::LONGVARCHAR:
159cdf0e10cSrcweir             case sdbc::DataType::SQLNULL:
160cdf0e10cSrcweir             case sdbc::DataType::BINARY:
161cdf0e10cSrcweir             case sdbc::DataType::VARBINARY:
162cdf0e10cSrcweir             case sdbc::DataType::LONGVARBINARY:
163cdf0e10cSrcweir             default:
164cdf0e10cSrcweir                 return new ScDPItemData ( rStr );
165cdf0e10cSrcweir                 //break;
166cdf0e10cSrcweir             }
167cdf0e10cSrcweir         }
168cdf0e10cSrcweir         catch (uno::Exception&)
169cdf0e10cSrcweir         {
170cdf0e10cSrcweir         }
171cdf0e10cSrcweir         catch ( ... )
172cdf0e10cSrcweir         {
173cdf0e10cSrcweir 
174cdf0e10cSrcweir         }
175cdf0e10cSrcweir 	  return NULL;
176cdf0e10cSrcweir     }
177cdf0e10cSrcweir }
178cdf0e10cSrcweir // Wang Xu Ming -- 12/23/2008
179cdf0e10cSrcweir //Refactor cache data
ScDPItemData(const String & rS,double fV,sal_Bool bHV,const sal_uLong nNumFormatP,sal_Bool bData)180cdf0e10cSrcweir ScDPItemData::ScDPItemData( const String& rS, double fV/* = 0.0*/, sal_Bool bHV/* = sal_False*/, const sal_uLong nNumFormatP /*= 0*/ , sal_Bool bData/* = sal_True*/) :
181cdf0e10cSrcweir nNumFormat( nNumFormatP ), aString(rS), fValue(fV),
182cdf0e10cSrcweir mbFlag( (MK_VAL*!!bHV) | (MK_DATA*!!bData) | (MK_ERR*!!sal_False) | (MK_DATE*!!lcl_isDate( nNumFormat ) ) )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir }
185cdf0e10cSrcweir 
ScDPItemData(ScDocument * pDoc,SCROW nRow,sal_uInt16 nCol,sal_uInt16 nDocTab)186cdf0e10cSrcweir ScDPItemData::ScDPItemData( ScDocument* pDoc, SCROW nRow, sal_uInt16 nCol, sal_uInt16 nDocTab  ):
187cdf0e10cSrcweir         nNumFormat( 0 ), fValue(0.0), mbFlag( 0 )
188cdf0e10cSrcweir {
189cdf0e10cSrcweir 	String aDocStr;
190cdf0e10cSrcweir 	pDoc->GetString( nCol, nRow, nDocTab, aDocStr );
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 	SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 	ScAddress aPos( nCol, nRow, nDocTab );
195cdf0e10cSrcweir 	ScBaseCell* pCell = pDoc->GetCell( aPos );
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 	if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetErrCode() )
198cdf0e10cSrcweir     {
199*0deba7fbSSteve Yin         SetString ( aDocStr );
200*0deba7fbSSteve Yin         //bErr = sal_True;
201cdf0e10cSrcweir         mbFlag |= MK_ERR;
202cdf0e10cSrcweir     }
203cdf0e10cSrcweir 	else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) )
204cdf0e10cSrcweir 	{
205cdf0e10cSrcweir 		double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab));
206cdf0e10cSrcweir         nNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) );
207cdf0e10cSrcweir 		sal_uLong nFormat = NUMBERFORMAT_NUMBER;
208cdf0e10cSrcweir 		if ( pFormatter )
209cdf0e10cSrcweir             nFormat = pFormatter->GetType( nNumFormat );
210cdf0e10cSrcweir 		aString = aDocStr;
211cdf0e10cSrcweir 		fValue = fVal;
212cdf0e10cSrcweir 		mbFlag |= MK_VAL|MK_DATA;
213cdf0e10cSrcweir 		lcl_isDate( nFormat ) ? ( mbFlag |= MK_DATE ) : (mbFlag &= ~MK_DATE);
214cdf0e10cSrcweir 	}
215cdf0e10cSrcweir 	else if ( pDoc->HasData( nCol,nRow, nDocTab ) )
216cdf0e10cSrcweir 		SetString ( aDocStr );
217cdf0e10cSrcweir }
218cdf0e10cSrcweir // End Comments
219cdf0e10cSrcweir 
IsCaseInsEqual(const ScDPItemData & r) const220cdf0e10cSrcweir sal_Bool ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const
221cdf0e10cSrcweir { //TODO: indified Date?
222cdf0e10cSrcweir     //! pass Transliteration?
223cdf0e10cSrcweir 	//!	inline?
224cdf0e10cSrcweir 	return IsValue() ? ( r.IsValue() && rtl::math::approxEqual( fValue, r.fValue ) ) :
225cdf0e10cSrcweir 					   ( !r.IsValue() &&
226cdf0e10cSrcweir                         ScGlobal::GetpTransliteration()->isEqual( aString, r.aString ) );
227cdf0e10cSrcweir }
228cdf0e10cSrcweir 
Hash() const229cdf0e10cSrcweir size_t ScDPItemData::Hash() const
230cdf0e10cSrcweir {
231cdf0e10cSrcweir     if ( IsValue() )
232cdf0e10cSrcweir 		return (size_t) rtl::math::approxFloor( fValue );
233cdf0e10cSrcweir     else
234cdf0e10cSrcweir 		// If we do unicode safe case insensitive hash we can drop
235cdf0e10cSrcweir 		// ScDPItemData::operator== and use ::IsCasInsEqual
236cdf0e10cSrcweir 		return rtl_ustr_hashCode_WithLength( aString.GetBuffer(), aString.Len() );
237cdf0e10cSrcweir }
238cdf0e10cSrcweir 
operator ==(const ScDPItemData & r) const239cdf0e10cSrcweir sal_Bool ScDPItemData::operator==( const ScDPItemData& r ) const
240cdf0e10cSrcweir {
241cdf0e10cSrcweir     if ( IsValue() )
242cdf0e10cSrcweir     {
243cdf0e10cSrcweir 		if( (HasDatePart() != r.HasDatePart())  || (HasDatePart() && mnDatePart != r.mnDatePart) )
244cdf0e10cSrcweir 			return sal_False;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir // Wang Xu Ming -- 1/9/2009
247cdf0e10cSrcweir // Add Data Cache Support.
248cdf0e10cSrcweir // Identify date
249cdf0e10cSrcweir 		if ( IsDate() != r.IsDate() )
250cdf0e10cSrcweir 			return sal_False;
251cdf0e10cSrcweir       else
252cdf0e10cSrcweir 		if ( r.IsValue() )
253cdf0e10cSrcweir             return rtl::math::approxEqual( fValue, r.fValue );
254cdf0e10cSrcweir         else
255cdf0e10cSrcweir             return sal_False;
256cdf0e10cSrcweir // End Comments
257cdf0e10cSrcweir     }
258cdf0e10cSrcweir     else if ( r.IsValue() )
259cdf0e10cSrcweir 		return sal_False;
260cdf0e10cSrcweir     else
261cdf0e10cSrcweir 		// need exact equality until we have a safe case insensitive string hash
262cdf0e10cSrcweir         return aString == r.aString;
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
Compare(const ScDPItemData & rA,const ScDPItemData & rB)265cdf0e10cSrcweir sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA,
266cdf0e10cSrcweir 								 const ScDPItemData& rB )
267cdf0e10cSrcweir {
268cdf0e10cSrcweir     if ( rA.IsValue() )
269cdf0e10cSrcweir     {
270cdf0e10cSrcweir         if ( rB.IsValue() )
271cdf0e10cSrcweir         {
272cdf0e10cSrcweir             if ( rtl::math::approxEqual( rA.fValue, rB.fValue ) )
273cdf0e10cSrcweir 			{
274cdf0e10cSrcweir // Wang Xu Ming -- 1/9/2009
275cdf0e10cSrcweir // Add Data Cache Support.
276cdf0e10cSrcweir // Date > number
277cdf0e10cSrcweir 				if ( rA.IsDate() == rB.IsDate() )
278cdf0e10cSrcweir 					return 0;
279cdf0e10cSrcweir 				else
280cdf0e10cSrcweir 					return rA.IsDate() ? 1: -1;
281cdf0e10cSrcweir // End Comments
282cdf0e10cSrcweir 			}
283cdf0e10cSrcweir 			else if ( rA.fValue < rB.fValue )
284cdf0e10cSrcweir 				return -1;
285cdf0e10cSrcweir 			else
286cdf0e10cSrcweir 				return 1;
287cdf0e10cSrcweir         }
288cdf0e10cSrcweir         else
289cdf0e10cSrcweir             return -1;           // values first
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir     else if ( rB.IsValue() )
292cdf0e10cSrcweir         return 1;                // values first
293cdf0e10cSrcweir     else
294cdf0e10cSrcweir         return ScGlobal::GetCollator()->compareString( rA.aString, rB.aString );
295cdf0e10cSrcweir }
296*0deba7fbSSteve Yin 
297cdf0e10cSrcweir #ifdef DEBUG
dump() const298cdf0e10cSrcweir void	ScDPItemData::dump() const
299cdf0e10cSrcweir {
300cdf0e10cSrcweir 	DBG_TRACE1( "Numberformat= %o",  nNumFormat );
301cdf0e10cSrcweir 	DBG_TRACESTR(aString );
302cdf0e10cSrcweir 	DBG_TRACE1( "fValue= %f", fValue );
303cdf0e10cSrcweir 	DBG_TRACE1( "mbFlag= %d", mbFlag);
304cdf0e10cSrcweir }
305cdf0e10cSrcweir #endif
306cdf0e10cSrcweir 
CreateTypeString()307cdf0e10cSrcweir TypedStrData*  ScDPItemData::CreateTypeString( )
308cdf0e10cSrcweir {
309cdf0e10cSrcweir 	if ( IsValue() )
310cdf0e10cSrcweir 		return new TypedStrData( aString, fValue, SC_STRTYPE_VALUE );
311cdf0e10cSrcweir 	else
312cdf0e10cSrcweir 		return new TypedStrData( aString );
313cdf0e10cSrcweir }
314cdf0e10cSrcweir 
GetType() const315cdf0e10cSrcweir sal_uInt8 ScDPItemData::GetType() const
316cdf0e10cSrcweir {
317cdf0e10cSrcweir 
318cdf0e10cSrcweir 	if ( IsHasErr() )
319cdf0e10cSrcweir 		return SC_VALTYPE_ERROR;
320cdf0e10cSrcweir 	else if ( !IsHasData() )
321cdf0e10cSrcweir 		return SC_VALTYPE_EMPTY;
322cdf0e10cSrcweir 	else if ( IsValue())
323cdf0e10cSrcweir 		return SC_VALTYPE_VALUE;
324cdf0e10cSrcweir 	else
325cdf0e10cSrcweir 		return SC_VALTYPE_STRING;
326cdf0e10cSrcweir 
327cdf0e10cSrcweir }
328cdf0e10cSrcweir 
IsHasData() const329cdf0e10cSrcweir sal_Bool ScDPItemData::IsHasData() const
330cdf0e10cSrcweir {
331cdf0e10cSrcweir 	return !!(mbFlag&MK_DATA);
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
IsHasErr() const334cdf0e10cSrcweir sal_Bool ScDPItemData::IsHasErr() const
335cdf0e10cSrcweir {
336cdf0e10cSrcweir 	return !!(mbFlag&MK_ERR);
337cdf0e10cSrcweir }
338cdf0e10cSrcweir 
IsValue() const339cdf0e10cSrcweir sal_Bool ScDPItemData::IsValue() const
340cdf0e10cSrcweir {
341cdf0e10cSrcweir 	return !!(mbFlag&MK_VAL);
342cdf0e10cSrcweir }
343cdf0e10cSrcweir 
GetString() const344cdf0e10cSrcweir String ScDPItemData::GetString() const
345cdf0e10cSrcweir {
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 	return aString;
348cdf0e10cSrcweir }
349cdf0e10cSrcweir 
GetValue() const350cdf0e10cSrcweir double ScDPItemData::GetValue() const
351cdf0e10cSrcweir {
352cdf0e10cSrcweir 	return fValue;
353cdf0e10cSrcweir }
GetNumFormat() const354cdf0e10cSrcweir sal_uLong  ScDPItemData::GetNumFormat() const
355cdf0e10cSrcweir {
356cdf0e10cSrcweir 	return nNumFormat;
357cdf0e10cSrcweir }
358cdf0e10cSrcweir 
HasStringData() const359cdf0e10cSrcweir sal_Bool ScDPItemData::HasStringData() const
360cdf0e10cSrcweir 
361cdf0e10cSrcweir {
362cdf0e10cSrcweir 	return IsHasData()&&!IsHasErr()&&!IsValue();
363cdf0e10cSrcweir }
IsDate() const364cdf0e10cSrcweir sal_Bool ScDPItemData::IsDate() const
365cdf0e10cSrcweir {
366cdf0e10cSrcweir 	return !!(mbFlag&MK_DATE);
367cdf0e10cSrcweir }
HasDatePart() const368cdf0e10cSrcweir sal_Bool ScDPItemData::HasDatePart() const
369cdf0e10cSrcweir {
370cdf0e10cSrcweir 	return !!(mbFlag&MK_DATEPART);
371cdf0e10cSrcweir }
SetDate(sal_Bool b)372cdf0e10cSrcweir void ScDPItemData::SetDate( sal_Bool b )
373cdf0e10cSrcweir {
374cdf0e10cSrcweir 	b ? ( mbFlag |= MK_DATE ) : ( mbFlag &= ~MK_DATE );
375cdf0e10cSrcweir }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir // -----------------------------------------------------------------------
378cdf0e10cSrcweir //class ScDPTableDataCache
379cdf0e10cSrcweir //To cache the pivot table data source
380cdf0e10cSrcweir 
operator ==(const ScDPTableDataCache & r) const381cdf0e10cSrcweir sal_Bool ScDPTableDataCache::operator== ( const ScDPTableDataCache& r ) const
382cdf0e10cSrcweir {
383cdf0e10cSrcweir 	if ( GetColumnCount() == r.GetColumnCount() )
384cdf0e10cSrcweir 	{
385cdf0e10cSrcweir 		for ( SCCOL i = 0 ; i < GetColumnCount(); i++ )
386cdf0e10cSrcweir 		{	//check dim names
387cdf0e10cSrcweir 			if ( GetDimensionName( i ) != r.GetDimensionName( i ) )
388cdf0e10cSrcweir 				return sal_False;
389cdf0e10cSrcweir 			//check rows count
390cdf0e10cSrcweir 			if ( GetRowCount() != r.GetRowCount() )
391cdf0e10cSrcweir 				return sal_False;
392cdf0e10cSrcweir 			//check dim member values
393cdf0e10cSrcweir 			size_t nMembersCount = GetDimMemberValues( i ).size();
394cdf0e10cSrcweir 			if ( GetDimMemberValues( i ).size() == r. GetDimMemberValues( i ).size() )
395cdf0e10cSrcweir 			{
396cdf0e10cSrcweir 				for ( size_t j = 0; j < nMembersCount; j++ )
397cdf0e10cSrcweir 				{
398cdf0e10cSrcweir 					if ( *( GetDimMemberValues( i )[j] ) == *( r.GetDimMemberValues( i )[j] ) )
399cdf0e10cSrcweir 						continue;
400cdf0e10cSrcweir 					else
401cdf0e10cSrcweir 						return sal_False;
402cdf0e10cSrcweir 				}
403cdf0e10cSrcweir 			}
404cdf0e10cSrcweir 			else
405cdf0e10cSrcweir 				return sal_False;
406cdf0e10cSrcweir 			//check source table index
407cdf0e10cSrcweir 			for ( SCROW k=0 ; k < GetRowCount(); k ++ )
408cdf0e10cSrcweir 			{
409cdf0e10cSrcweir 				if ( GetItemDataId( i, k, sal_False ) == r.GetItemDataId( i,k,sal_False) )
410cdf0e10cSrcweir 					continue;
411cdf0e10cSrcweir 				else
412cdf0e10cSrcweir 					return sal_False;
413cdf0e10cSrcweir 			}
414cdf0e10cSrcweir 		}
415cdf0e10cSrcweir 	}
416cdf0e10cSrcweir 	return sal_True;
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
ScDPTableDataCache(ScDocument * pDoc)419cdf0e10cSrcweir ScDPTableDataCache::ScDPTableDataCache(  ScDocument* pDoc  ) :
420cdf0e10cSrcweir mpDoc( pDoc ),
421cdf0e10cSrcweir mnColumnCount ( 0 ),
422cdf0e10cSrcweir mpTableDataValues ( NULL ),
423cdf0e10cSrcweir mpSourceData ( NULL ),
424cdf0e10cSrcweir mpGlobalOrder( NULL ),
425cdf0e10cSrcweir mpIndexOrder( NULL)
426cdf0e10cSrcweir {
427cdf0e10cSrcweir 	mnID = -1;
428cdf0e10cSrcweir }
429cdf0e10cSrcweir 
~ScDPTableDataCache()430cdf0e10cSrcweir ScDPTableDataCache::~ScDPTableDataCache()
431cdf0e10cSrcweir {
432cdf0e10cSrcweir 	if ( IsValid() )
433cdf0e10cSrcweir 	{
434cdf0e10cSrcweir // Wang Xu Ming -- 2/17/2009
435cdf0e10cSrcweir // Performance issue
436cdf0e10cSrcweir 		sal_uInt16 nCol;
437cdf0e10cSrcweir 		for (  nCol=0; nCol < GetColumnCount() ; nCol++ )
438cdf0e10cSrcweir 		{
439cdf0e10cSrcweir 			for ( sal_uLong row = 0 ;  row < mpTableDataValues[nCol].size(); row++ )
440cdf0e10cSrcweir 				delete mpTableDataValues[nCol][row];
441cdf0e10cSrcweir 		}
442cdf0e10cSrcweir 		for ( nCol =0; nCol < mrLabelNames.size(); nCol++ )
443cdf0e10cSrcweir 				delete mrLabelNames[nCol];
444cdf0e10cSrcweir // End Comments
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 		mnColumnCount = 0;
447cdf0e10cSrcweir 		delete [] mpTableDataValues;
448cdf0e10cSrcweir 		mpTableDataValues = NULL;
449cdf0e10cSrcweir 		delete [] mpSourceData;
450cdf0e10cSrcweir 		mpSourceData = NULL;
451cdf0e10cSrcweir 		delete [] mpGlobalOrder;
452cdf0e10cSrcweir 		mpGlobalOrder = NULL;
453cdf0e10cSrcweir 		delete [] mpIndexOrder;
454cdf0e10cSrcweir 		mpIndexOrder = NULL;
455cdf0e10cSrcweir 	}
456cdf0e10cSrcweir }
457cdf0e10cSrcweir 
458cdf0e10cSrcweir // -----------------------------------------------------------------------
AddRow(ScDPItemData * pRow,sal_uInt16 nCount)459cdf0e10cSrcweir void ScDPTableDataCache::AddRow( ScDPItemData* pRow, sal_uInt16 nCount )
460cdf0e10cSrcweir {
461cdf0e10cSrcweir 	DBG_ASSERT( pRow , " empty pointer" );
462cdf0e10cSrcweir 	if ( !mrLabelNames.size() )
463cdf0e10cSrcweir 	{
464cdf0e10cSrcweir 		mnColumnCount= nCount;
465cdf0e10cSrcweir 		mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ];
466cdf0e10cSrcweir 		mpSourceData	  = new std::vector<SCROW>[ mnColumnCount ];
467cdf0e10cSrcweir 		mpGlobalOrder	  = new	std::vector<SCROW>[ mnColumnCount ];
468cdf0e10cSrcweir 		mpIndexOrder	  = new std::vector<SCROW>[ mnColumnCount ];
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < nCount ; i ++ )
471cdf0e10cSrcweir 			AddLabel( new ScDPItemData( pRow[i] ) );
472cdf0e10cSrcweir 	}
473cdf0e10cSrcweir 	else
474cdf0e10cSrcweir 	{
475cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < nCount && i < mnColumnCount; i ++ )
4764f68f4a1SWang Lei 			AddData( i, new ScDPItemData( pRow[i] ) );
477cdf0e10cSrcweir 	}
478cdf0e10cSrcweir }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir // -----------------------------------------------------------------------
IsValid() const481cdf0e10cSrcweir bool  ScDPTableDataCache::IsValid() const
482cdf0e10cSrcweir { //TODO: continue check valid
483cdf0e10cSrcweir 	return mpTableDataValues!=NULL && mpSourceData!= NULL && mnColumnCount>0;
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir // -----------------------------------------------------------------------
487cdf0e10cSrcweir 
488cdf0e10cSrcweir namespace {
489cdf0e10cSrcweir 
490cdf0e10cSrcweir /**
491cdf0e10cSrcweir  * While the macro interpret level is incremented, the formula cells are
492cdf0e10cSrcweir  * (semi-)guaranteed to be interpreted.
493cdf0e10cSrcweir  */
494cdf0e10cSrcweir class MacroInterpretIncrementer
495cdf0e10cSrcweir {
496cdf0e10cSrcweir public:
MacroInterpretIncrementer(ScDocument * pDoc)497cdf0e10cSrcweir     MacroInterpretIncrementer(ScDocument* pDoc) :
498cdf0e10cSrcweir         mpDoc(pDoc)
499cdf0e10cSrcweir     {
500cdf0e10cSrcweir         mpDoc->IncMacroInterpretLevel();
501cdf0e10cSrcweir     }
~MacroInterpretIncrementer()502cdf0e10cSrcweir     ~MacroInterpretIncrementer()
503cdf0e10cSrcweir     {
504cdf0e10cSrcweir         mpDoc->DecMacroInterpretLevel();
505cdf0e10cSrcweir     }
506cdf0e10cSrcweir private:
507cdf0e10cSrcweir     ScDocument* mpDoc;
508cdf0e10cSrcweir };
509cdf0e10cSrcweir 
510cdf0e10cSrcweir }
511cdf0e10cSrcweir 
512cdf0e10cSrcweir // -----------------------------------------------------------------------
InitFromDoc(ScDocument * pDoc,const ScRange & rRange)513cdf0e10cSrcweir bool ScDPTableDataCache::InitFromDoc(  ScDocument* pDoc, const ScRange& rRange )
514cdf0e10cSrcweir {
515cdf0e10cSrcweir     // Make sure the formula cells within the data range are interpreted
516cdf0e10cSrcweir     // during this call, for this method may be called from the interpretation
517cdf0e10cSrcweir     // of GETPIVOTDATA, which disables nested formula interpretation without
518cdf0e10cSrcweir     // increasing the macro level.
519cdf0e10cSrcweir     MacroInterpretIncrementer aMacroInc(pDoc);
520cdf0e10cSrcweir 
521cdf0e10cSrcweir 	//
522cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();	// start of data
523cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
524cdf0e10cSrcweir 	sal_uInt16 nStartCol = rRange.aStart.Col();
525cdf0e10cSrcweir 	sal_uInt16 nEndCol = rRange.aEnd.Col();
526cdf0e10cSrcweir 	sal_uInt16 nDocTab = rRange.aStart.Tab();
527cdf0e10cSrcweir 
528cdf0e10cSrcweir 	//init
529cdf0e10cSrcweir  	long nOldColumCount = mnColumnCount;
530cdf0e10cSrcweir 	mnColumnCount = nEndCol - nStartCol + 1;
531cdf0e10cSrcweir 	if ( IsValid() )
532cdf0e10cSrcweir 	{
533cdf0e10cSrcweir 		for ( sal_uInt16 nCol=0; nCol < nOldColumCount ; nCol++ )
534cdf0e10cSrcweir 		{
535cdf0e10cSrcweir 			for ( sal_uLong row = 0 ;  row < mpTableDataValues[nCol].size(); row++ )
536cdf0e10cSrcweir 				delete mpTableDataValues[nCol][row];
537cdf0e10cSrcweir 			delete mrLabelNames[nCol];
538cdf0e10cSrcweir 		}
539cdf0e10cSrcweir 		delete [] mpTableDataValues;
540cdf0e10cSrcweir 		delete [] mpSourceData;
541cdf0e10cSrcweir 		delete [] mpGlobalOrder;
542cdf0e10cSrcweir 		delete [] mpIndexOrder;
543cdf0e10cSrcweir 		mrLabelNames.clear();
544cdf0e10cSrcweir 	}
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 	mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ];
547cdf0e10cSrcweir 	mpSourceData	  = new std::vector<SCROW>[ mnColumnCount ];
548cdf0e10cSrcweir 	mpGlobalOrder	  = new	std::vector<SCROW>[ mnColumnCount ];
549cdf0e10cSrcweir 	mpIndexOrder	  = new std::vector<SCROW>[ mnColumnCount ];
550b4df81e3SWang Lei     pDoc->FillDPCache( this, nDocTab, nStartCol, nEndCol, nStartRow, nEndRow );
551cdf0e10cSrcweir 	return sal_True;
552cdf0e10cSrcweir }
553cdf0e10cSrcweir 
554cdf0e10cSrcweir // -----------------------------------------------------------------------
InitFromDataBase(const Reference<sdbc::XRowSet> & xRowSet,const Date & rNullDate)555cdf0e10cSrcweir bool ScDPTableDataCache::InitFromDataBase (const Reference<sdbc::XRowSet>& xRowSet, const Date& rNullDate)
556cdf0e10cSrcweir {
557cdf0e10cSrcweir   if (!xRowSet.is())
558cdf0e10cSrcweir         // Dont' even waste time to go any further.
559cdf0e10cSrcweir         return false;
560cdf0e10cSrcweir 	try
561cdf0e10cSrcweir     {
562cdf0e10cSrcweir         Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp(xRowSet, UNO_QUERY_THROW);
563cdf0e10cSrcweir         Reference<sdbc::XResultSetMetaData> xMeta = xMetaSupp->getMetaData();
564cdf0e10cSrcweir         if (!xMeta.is())
565cdf0e10cSrcweir             return false;
566cdf0e10cSrcweir 
567cdf0e10cSrcweir    	long nOldColumCount = mnColumnCount;
568cdf0e10cSrcweir 	mnColumnCount = xMeta->getColumnCount();
569cdf0e10cSrcweir 	if ( IsValid() )
570cdf0e10cSrcweir 	{
571cdf0e10cSrcweir 		for ( sal_uInt16 nCol=0; nCol < nOldColumCount ; nCol++ )
572cdf0e10cSrcweir 		{
573cdf0e10cSrcweir 			for ( sal_uLong row = 0 ;  row < mpTableDataValues[nCol].size(); row++ )
574cdf0e10cSrcweir 				delete mpTableDataValues[nCol][row];
575cdf0e10cSrcweir 			delete mrLabelNames[nCol];
576cdf0e10cSrcweir 		}
577cdf0e10cSrcweir 		delete [] mpTableDataValues;
578cdf0e10cSrcweir 		delete [] mpSourceData;
579cdf0e10cSrcweir 		delete [] mpGlobalOrder;
580cdf0e10cSrcweir 		delete [] mpIndexOrder;
581cdf0e10cSrcweir 		mrLabelNames.clear();
582cdf0e10cSrcweir 	}
583cdf0e10cSrcweir         // Get column titles and types.
584cdf0e10cSrcweir 	mrLabelNames.reserve(mnColumnCount);
585cdf0e10cSrcweir 	mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ];
586cdf0e10cSrcweir 	mpSourceData	  = new std::vector<SCROW>[ mnColumnCount ];
587cdf0e10cSrcweir 	mpGlobalOrder	  = new	std::vector<SCROW>[ mnColumnCount ];
588cdf0e10cSrcweir 	mpIndexOrder	  = new std::vector<SCROW>[ mnColumnCount ];
589cdf0e10cSrcweir 
590cdf0e10cSrcweir     std::vector<sal_Int32> aColTypes(mnColumnCount);
591cdf0e10cSrcweir 
592cdf0e10cSrcweir         for (sal_Int32 nCol = 0; nCol < mnColumnCount; ++nCol)
593cdf0e10cSrcweir         {
594cdf0e10cSrcweir             String aColTitle = xMeta->getColumnLabel(nCol+1);
595cdf0e10cSrcweir             aColTypes[nCol]  = xMeta->getColumnType(nCol+1);
596cdf0e10cSrcweir            AddLabel( new ScDPItemData( aColTitle) );
597cdf0e10cSrcweir         }
598cdf0e10cSrcweir 
599cdf0e10cSrcweir         // Now get the data rows.
600cdf0e10cSrcweir         Reference<sdbc::XRow> xRow(xRowSet, UNO_QUERY_THROW);
601cdf0e10cSrcweir         xRowSet->first();
602cdf0e10cSrcweir         do
603cdf0e10cSrcweir         {
604cdf0e10cSrcweir             for (sal_Int32 nCol = 0; nCol < mnColumnCount; ++nCol)
605cdf0e10cSrcweir             {
606cdf0e10cSrcweir                ScDPItemData * pNew =  lcl_GetItemValue( xRow, aColTypes[nCol], nCol+1, rNullDate );
607cdf0e10cSrcweir                 if ( pNew )
6084f68f4a1SWang Lei                     AddData(  nCol , pNew );
609cdf0e10cSrcweir             }
610cdf0e10cSrcweir         }
611cdf0e10cSrcweir         while (xRowSet->next());
612cdf0e10cSrcweir 
613cdf0e10cSrcweir 	xRowSet->beforeFirst();
614cdf0e10cSrcweir 
615cdf0e10cSrcweir 	return true;
616cdf0e10cSrcweir     }
617cdf0e10cSrcweir     catch (const Exception&)
618cdf0e10cSrcweir     {
619cdf0e10cSrcweir     	return false;
620cdf0e10cSrcweir     }
621cdf0e10cSrcweir }
622cdf0e10cSrcweir // -----------------------------------------------------------------------
GetDimNumType(SCCOL nDim) const623cdf0e10cSrcweir sal_uLong ScDPTableDataCache::GetDimNumType( SCCOL nDim) const
624cdf0e10cSrcweir {
625cdf0e10cSrcweir 	DBG_ASSERT( IsValid(), "  IsValid() == false " );
626cdf0e10cSrcweir 	DBG_ASSERT( nDim < mnColumnCount && nDim >=0, " dimention out of bound " );
627cdf0e10cSrcweir 	if ( mpTableDataValues[nDim].size()==0 )
628cdf0e10cSrcweir 		return NUMBERFORMAT_UNDEFINED;
629cdf0e10cSrcweir 	else
630cdf0e10cSrcweir 		return GetNumType(mpTableDataValues[nDim][0]->nNumFormat);
631cdf0e10cSrcweir }
632cdf0e10cSrcweir 
633cdf0e10cSrcweir // -----------------------------------------------------------------------
ValidQuery(SCROW nRow,const ScQueryParam & rParam,sal_Bool * pSpecial)634cdf0e10cSrcweir bool ScDPTableDataCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, sal_Bool *pSpecial)
635cdf0e10cSrcweir { //Copied and modified from ScTable::ValidQuery
636cdf0e10cSrcweir 		if (!rParam.GetEntry(0).bDoQuery)
637cdf0e10cSrcweir 			return sal_True;
638cdf0e10cSrcweir 		sal_Bool	bMatchWholeCell = mpDoc->GetDocOptions().IsMatchWholeCell();
639cdf0e10cSrcweir 
640cdf0e10cSrcweir 		//---------------------------------------------------------------
641cdf0e10cSrcweir 
642cdf0e10cSrcweir 		const SCSIZE nFixedBools = 32;
643cdf0e10cSrcweir 		sal_Bool aBool[nFixedBools];
644cdf0e10cSrcweir 		sal_Bool aTest[nFixedBools];
645cdf0e10cSrcweir 		SCSIZE nEntryCount = rParam.GetEntryCount();
646cdf0e10cSrcweir 		sal_Bool* pPasst = ( nEntryCount <= nFixedBools ? &aBool[0] : new sal_Bool[nEntryCount] );
647cdf0e10cSrcweir 		sal_Bool* pTest = ( nEntryCount <= nFixedBools ? &aTest[0] : new sal_Bool[nEntryCount] );
648cdf0e10cSrcweir 
649cdf0e10cSrcweir 		long	nPos = -1;
650cdf0e10cSrcweir 		SCSIZE	i	 = 0;
651cdf0e10cSrcweir 		CollatorWrapper* pCollator = (rParam.bCaseSens ? ScGlobal::GetCaseCollator() :
652cdf0e10cSrcweir 			ScGlobal::GetCollator() );
653cdf0e10cSrcweir 		::utl::TransliterationWrapper* pTransliteration = (rParam.bCaseSens ?
654cdf0e10cSrcweir 			ScGlobal::GetCaseTransliteration() : ScGlobal::GetpTransliteration());
655cdf0e10cSrcweir 
656cdf0e10cSrcweir 		while ( (i < nEntryCount) && rParam.GetEntry(i).bDoQuery )
657cdf0e10cSrcweir 		{
658cdf0e10cSrcweir 			ScQueryEntry& rEntry = rParam.GetEntry(i);
659cdf0e10cSrcweir 			// we can only handle one single direct query
660cdf0e10cSrcweir             // #i115431# nField in QueryParam is the sheet column, not the field within the source range
661cdf0e10cSrcweir             SCCOL nQueryCol = (SCCOL)rEntry.nField;
662cdf0e10cSrcweir             if ( nQueryCol < rParam.nCol1 )
663cdf0e10cSrcweir                 nQueryCol = rParam.nCol1;
664cdf0e10cSrcweir             if ( nQueryCol > rParam.nCol2 )
665cdf0e10cSrcweir                 nQueryCol = rParam.nCol2;
666cdf0e10cSrcweir             SCCOL nSourceField = nQueryCol - rParam.nCol1;
667cdf0e10cSrcweir             SCROW nId = GetItemDataId( nSourceField, nRow, sal_False );
668cdf0e10cSrcweir             const ScDPItemData* pCellData = GetItemDataById( nSourceField, nId );
669cdf0e10cSrcweir 
670cdf0e10cSrcweir 			sal_Bool bOk = sal_False;
671cdf0e10cSrcweir 			sal_Bool bTestEqual = sal_False;
672cdf0e10cSrcweir 
673cdf0e10cSrcweir 			if ( pSpecial && pSpecial[i] )
674cdf0e10cSrcweir 			{
675cdf0e10cSrcweir 				if (rEntry.nVal == SC_EMPTYFIELDS)
676cdf0e10cSrcweir 					bOk = ! pCellData->IsHasData();
677cdf0e10cSrcweir 				else // if (rEntry.nVal == SC_NONEMPTYFIELDS)
678cdf0e10cSrcweir 					bOk =  pCellData->IsHasData();
679cdf0e10cSrcweir 			}
680cdf0e10cSrcweir 			else if ( !rEntry.bQueryByString && pCellData->IsValue() )
681cdf0e10cSrcweir 			{	// by Value
682cdf0e10cSrcweir 				double nCellVal = pCellData->GetValue();
683cdf0e10cSrcweir 
684cdf0e10cSrcweir 				switch (rEntry.eOp)
685cdf0e10cSrcweir 				{
686cdf0e10cSrcweir 					case SC_EQUAL :
687cdf0e10cSrcweir 						bOk = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
688cdf0e10cSrcweir 						break;
689cdf0e10cSrcweir 					case SC_LESS :
690cdf0e10cSrcweir 						bOk = (nCellVal < rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
691cdf0e10cSrcweir 						break;
692cdf0e10cSrcweir 					case SC_GREATER :
693cdf0e10cSrcweir 						bOk = (nCellVal > rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
694cdf0e10cSrcweir 						break;
695cdf0e10cSrcweir 					case SC_LESS_EQUAL :
696cdf0e10cSrcweir 						bOk = (nCellVal < rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
697cdf0e10cSrcweir 						break;
698cdf0e10cSrcweir 					case SC_GREATER_EQUAL :
699cdf0e10cSrcweir 						bOk = (nCellVal > rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
700cdf0e10cSrcweir 						break;
701cdf0e10cSrcweir 					case SC_NOT_EQUAL :
702cdf0e10cSrcweir 						bOk = !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
703cdf0e10cSrcweir 						break;
704cdf0e10cSrcweir                   		       default:
705cdf0e10cSrcweir                        			 bOk= sal_False;
706cdf0e10cSrcweir                       			  break;
707cdf0e10cSrcweir 				}
708cdf0e10cSrcweir 			}
709cdf0e10cSrcweir 			else if ( (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)
710cdf0e10cSrcweir 					|| (rEntry.bQueryByString
711cdf0e10cSrcweir 						&& pCellData->HasStringData() )
712cdf0e10cSrcweir 				)
713cdf0e10cSrcweir 			{	// by String
714cdf0e10cSrcweir 				String	aCellStr = pCellData->GetString();
715cdf0e10cSrcweir 
716cdf0e10cSrcweir 				sal_Bool bRealRegExp = (rParam.bRegExp && ((rEntry.eOp == SC_EQUAL)
717cdf0e10cSrcweir 					|| (rEntry.eOp == SC_NOT_EQUAL)));
718cdf0e10cSrcweir 				sal_Bool bTestRegExp = sal_False;
719cdf0e10cSrcweir 				if ( bRealRegExp || bTestRegExp )
720cdf0e10cSrcweir 				{
721cdf0e10cSrcweir 					xub_StrLen nStart = 0;
722cdf0e10cSrcweir 					xub_StrLen nEnd   = aCellStr.Len();
723cdf0e10cSrcweir 					sal_Bool bMatch = (sal_Bool) rEntry.GetSearchTextPtr( rParam.bCaseSens )
724cdf0e10cSrcweir 						->SearchFrwrd( aCellStr, &nStart, &nEnd );
725cdf0e10cSrcweir 					// from 614 on, nEnd is behind the found text
726cdf0e10cSrcweir 					if ( bMatch && bMatchWholeCell
727cdf0e10cSrcweir 							&& (nStart != 0 || nEnd != aCellStr.Len()) )
728cdf0e10cSrcweir 						bMatch = sal_False;    // RegExp must match entire cell string
729cdf0e10cSrcweir 					if ( bRealRegExp )
730cdf0e10cSrcweir 						bOk = ((rEntry.eOp == SC_NOT_EQUAL) ? !bMatch : bMatch);
731cdf0e10cSrcweir 					else
732cdf0e10cSrcweir 						bTestEqual = bMatch;
733cdf0e10cSrcweir 				}
734cdf0e10cSrcweir 				if ( !bRealRegExp )
735cdf0e10cSrcweir 				{
736cdf0e10cSrcweir 					if ( rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL )
737cdf0e10cSrcweir 					{
738cdf0e10cSrcweir 						if ( bMatchWholeCell )
739cdf0e10cSrcweir 						{
740cdf0e10cSrcweir                         				bOk = pTransliteration->isEqual( aCellStr, *rEntry.pStr );
741*0deba7fbSSteve Yin 
742cdf0e10cSrcweir 							String aStr = *rEntry.pStr;//"f*"
743cdf0e10cSrcweir 							//use another way to find "*" in aStr
744cdf0e10cSrcweir 							sal_Bool bHasStar = sal_False;
745cdf0e10cSrcweir 							xub_StrLen nIndex;
746cdf0e10cSrcweir 							if( ( nIndex = aStr.Search('*') ) != STRING_NOTFOUND )
747cdf0e10cSrcweir 								bHasStar = sal_True;
748cdf0e10cSrcweir 							if(bHasStar && (nIndex>0))
749cdf0e10cSrcweir 							{
750cdf0e10cSrcweir 								for(i=0;(i<nIndex) && (i< aCellStr.Len()) ; i++)
751cdf0e10cSrcweir 								{
752cdf0e10cSrcweir 									if(aCellStr.GetChar( (sal_uInt16)i ) == aStr.GetChar((sal_uInt16) i ))
753cdf0e10cSrcweir 									{
754cdf0e10cSrcweir 										bOk=1;
755cdf0e10cSrcweir 									}
756cdf0e10cSrcweir 									else
757cdf0e10cSrcweir 									{
758cdf0e10cSrcweir 										bOk=0;
759cdf0e10cSrcweir 										break;
760cdf0e10cSrcweir 									}
761cdf0e10cSrcweir 								}
762cdf0e10cSrcweir 							}
763cdf0e10cSrcweir 							//end modified
764cdf0e10cSrcweir 							//Added end,20060808
765cdf0e10cSrcweir 						}
766cdf0e10cSrcweir 						else
767cdf0e10cSrcweir 						{
768cdf0e10cSrcweir 							::com::sun::star::uno::Sequence< sal_Int32 > xOff;
769cdf0e10cSrcweir 							String aCell( pTransliteration->transliterate(
770cdf0e10cSrcweir 								aCellStr, ScGlobal::eLnge, 0, aCellStr.Len(),
771cdf0e10cSrcweir 								&xOff ) );
772cdf0e10cSrcweir 							String aQuer( pTransliteration->transliterate(
773cdf0e10cSrcweir 								*rEntry.pStr, ScGlobal::eLnge, 0, rEntry.pStr->Len(),
774cdf0e10cSrcweir 								&xOff ) );
775cdf0e10cSrcweir 							bOk = (aCell.Search( aQuer ) != STRING_NOTFOUND);
776cdf0e10cSrcweir 						}
777cdf0e10cSrcweir 						if ( rEntry.eOp == SC_NOT_EQUAL )
778cdf0e10cSrcweir 							bOk = !bOk;
779cdf0e10cSrcweir 					}
780cdf0e10cSrcweir 					else
781cdf0e10cSrcweir 					{   // use collator here because data was probably sorted
782cdf0e10cSrcweir 						sal_Int32 nCompare = pCollator->compareString(
783cdf0e10cSrcweir 							aCellStr, *rEntry.pStr );
784cdf0e10cSrcweir 						switch (rEntry.eOp)
785cdf0e10cSrcweir 						{
786cdf0e10cSrcweir 							case SC_LESS :
787cdf0e10cSrcweir 								bOk = (nCompare < 0);
788cdf0e10cSrcweir 								break;
789cdf0e10cSrcweir 							case SC_GREATER :
790cdf0e10cSrcweir 								bOk = (nCompare > 0);
791cdf0e10cSrcweir 								break;
792cdf0e10cSrcweir 							case SC_LESS_EQUAL :
793cdf0e10cSrcweir 								bOk = (nCompare <= 0);
794cdf0e10cSrcweir 								break;
795cdf0e10cSrcweir 							case SC_GREATER_EQUAL :
796cdf0e10cSrcweir 								bOk = (nCompare >= 0);
797cdf0e10cSrcweir 								break;
798cdf0e10cSrcweir                             case SC_NOT_EQUAL:
799cdf0e10cSrcweir                                 DBG_ASSERT( false , "SC_NOT_EQUAL");
800cdf0e10cSrcweir                                 break;
801cdf0e10cSrcweir                             case SC_TOPVAL:
802cdf0e10cSrcweir                             case SC_BOTVAL:
803cdf0e10cSrcweir                             case SC_TOPPERC:
804cdf0e10cSrcweir                             case SC_BOTPERC:
805cdf0e10cSrcweir                             default:
806cdf0e10cSrcweir                                 break;
807cdf0e10cSrcweir 						}
808cdf0e10cSrcweir 					}
809cdf0e10cSrcweir 				}
810cdf0e10cSrcweir 			}
811cdf0e10cSrcweir 
812cdf0e10cSrcweir 			if (nPos == -1)
813cdf0e10cSrcweir 			{
814cdf0e10cSrcweir 				nPos++;
815cdf0e10cSrcweir 				pPasst[nPos] = bOk;
816cdf0e10cSrcweir 				pTest[nPos] = bTestEqual;
817cdf0e10cSrcweir 			}
818cdf0e10cSrcweir 			else
819cdf0e10cSrcweir 			{
820cdf0e10cSrcweir 				if (rEntry.eConnect == SC_AND)
821cdf0e10cSrcweir 				{
822cdf0e10cSrcweir 					pPasst[nPos] = pPasst[nPos] && bOk;
823cdf0e10cSrcweir 					pTest[nPos] = pTest[nPos] && bTestEqual;
824cdf0e10cSrcweir 				}
825cdf0e10cSrcweir 				else
826cdf0e10cSrcweir 				{
827cdf0e10cSrcweir 					nPos++;
828cdf0e10cSrcweir 					pPasst[nPos] = bOk;
829cdf0e10cSrcweir 					pTest[nPos] = bTestEqual;
830cdf0e10cSrcweir 				}
831cdf0e10cSrcweir 			}
832cdf0e10cSrcweir 			i++;
833cdf0e10cSrcweir 		}
834cdf0e10cSrcweir 
835cdf0e10cSrcweir 		for ( long j=1; j <= nPos; j++ )
836cdf0e10cSrcweir 		{
837cdf0e10cSrcweir 			pPasst[0] = pPasst[0] || pPasst[j];
838cdf0e10cSrcweir 			pTest[0] = pTest[0] || pTest[j];
839cdf0e10cSrcweir 		}
840cdf0e10cSrcweir 
841cdf0e10cSrcweir 		sal_Bool bRet = pPasst[0];
842cdf0e10cSrcweir 		if ( pPasst != &aBool[0] )
843cdf0e10cSrcweir 			delete [] pPasst;
844cdf0e10cSrcweir 		if ( pTest != &aTest[0] )
845cdf0e10cSrcweir 			delete [] pTest;
846cdf0e10cSrcweir 
847cdf0e10cSrcweir 		return bRet;
848cdf0e10cSrcweir }
849cdf0e10cSrcweir 
850cdf0e10cSrcweir // -----------------------------------------------------------------------
IsRowEmpty(SCROW nRow) const851cdf0e10cSrcweir bool ScDPTableDataCache::IsRowEmpty( SCROW nRow ) const
852cdf0e10cSrcweir {
853cdf0e10cSrcweir 	return 	mbEmptyRow[ nRow ];
854cdf0e10cSrcweir 
855cdf0e10cSrcweir }
856cdf0e10cSrcweir 
857cdf0e10cSrcweir // -----------------------------------------------------------------------
IsEmptyMember(SCROW nRow,sal_uInt16 nColumn) const858cdf0e10cSrcweir bool ScDPTableDataCache::IsEmptyMember( SCROW nRow, sal_uInt16 nColumn ) const
859cdf0e10cSrcweir {
860cdf0e10cSrcweir 	return !GetItemDataById( nColumn, GetItemDataId( nColumn, nRow, sal_False ) )->IsHasData();
861cdf0e10cSrcweir }
862cdf0e10cSrcweir 
AddData(long nDim,ScDPItemData * pitemData,bool bCheckDate)8637a6646f1SWang Lei sal_Bool ScDPTableDataCache::AddData(long nDim, ScDPItemData* pitemData, bool bCheckDate )
864cdf0e10cSrcweir {
865cdf0e10cSrcweir 	DBG_ASSERT( IsValid(), "  IsValid() == false " );
866cdf0e10cSrcweir 	DBG_ASSERT( nDim < mnColumnCount && nDim >=0 , "dimension out of bound" );
867cdf0e10cSrcweir 	SCROW nIndex = 0;
868cdf0e10cSrcweir 
869cdf0e10cSrcweir 	sal_Bool	bInserted = sal_False;
8707a6646f1SWang Lei 	if( true == bCheckDate)
871cdf0e10cSrcweir 	pitemData->SetDate( lcl_isDate( GetNumType( pitemData->nNumFormat ) ) );
872cdf0e10cSrcweir 	if ( !lcl_Search( mpTableDataValues[nDim], mpGlobalOrder[nDim], *pitemData, nIndex ) )
873cdf0e10cSrcweir 	{
874cdf0e10cSrcweir 		mpTableDataValues[nDim].push_back( pitemData );
875cdf0e10cSrcweir 		mpGlobalOrder[nDim].insert( mpGlobalOrder[nDim].begin()+nIndex, mpTableDataValues[nDim].size()-1  );
876cdf0e10cSrcweir 		DBG_ASSERT( (size_t) mpGlobalOrder[nDim][nIndex] == mpTableDataValues[nDim].size()-1 ,"ScDPTableDataCache::AddData ");
877cdf0e10cSrcweir 		mpSourceData[nDim].push_back( mpTableDataValues[nDim].size()-1 );
878cdf0e10cSrcweir 		bInserted = sal_True;
879cdf0e10cSrcweir 	}
880cdf0e10cSrcweir 	else
881cdf0e10cSrcweir 		mpSourceData[nDim].push_back( mpGlobalOrder[nDim][nIndex] );
882cdf0e10cSrcweir //init empty row tag
883cdf0e10cSrcweir 	size_t  nCurRow = mpSourceData[nDim].size() -1 ;
884cdf0e10cSrcweir 
885cdf0e10cSrcweir 	while ( mbEmptyRow.size() <= nCurRow )
886cdf0e10cSrcweir 		mbEmptyRow.push_back( sal_True );
887cdf0e10cSrcweir 
888cdf0e10cSrcweir 	if ( pitemData->IsHasData() )
889cdf0e10cSrcweir 		mbEmptyRow[ nCurRow ] = sal_False;
890cdf0e10cSrcweir 
891cdf0e10cSrcweir 	if ( !bInserted )
892cdf0e10cSrcweir 		delete pitemData;
893cdf0e10cSrcweir 
894cdf0e10cSrcweir 	return sal_True;
895cdf0e10cSrcweir }
896cdf0e10cSrcweir 
GetDimensionName(sal_uInt16 nColumn) const897cdf0e10cSrcweir String ScDPTableDataCache::GetDimensionName( sal_uInt16 nColumn ) const
898cdf0e10cSrcweir {
899cdf0e10cSrcweir     DBG_ASSERT( /* nColumn>=0 && */ nColumn < mrLabelNames.size()-1 , "ScDPTableDataCache::GetDimensionName");
900cdf0e10cSrcweir 	DBG_ASSERT( mrLabelNames.size() == static_cast <sal_uInt16> (mnColumnCount+1), "ScDPTableDataCache::GetDimensionName");
901cdf0e10cSrcweir 	if ( static_cast<size_t>(nColumn+1) < mrLabelNames.size() )
902cdf0e10cSrcweir 	{
903cdf0e10cSrcweir 		return mrLabelNames[nColumn+1]->aString;
904cdf0e10cSrcweir 	}
905cdf0e10cSrcweir 	else
906cdf0e10cSrcweir 		return String();
907cdf0e10cSrcweir }
908cdf0e10cSrcweir 
909b4df81e3SWang Lei 
AddLabel(ScDPItemData * pData)910cdf0e10cSrcweir void ScDPTableDataCache::AddLabel(ScDPItemData *pData)
911cdf0e10cSrcweir {
912cdf0e10cSrcweir 	DBG_ASSERT( IsValid(), "  IsValid() == false " );
913cdf0e10cSrcweir 
914cdf0e10cSrcweir 	if ( mrLabelNames.size() == 0 )
915cdf0e10cSrcweir 		mrLabelNames.push_back( new ScDPItemData(  ScGlobal::GetRscString(STR_PIVOT_DATA) ) );
916cdf0e10cSrcweir 
917cdf0e10cSrcweir 
918cdf0e10cSrcweir 	//reset name if needed
919cdf0e10cSrcweir 	String strNewName = pData->aString;
920cdf0e10cSrcweir 
921cdf0e10cSrcweir     // #i116457# don't modify empty column titles
922cdf0e10cSrcweir     if ( strNewName.Len() )
923cdf0e10cSrcweir     {
924cdf0e10cSrcweir         sal_Bool bFound = sal_False;
925cdf0e10cSrcweir         long nIndex = 1;
926cdf0e10cSrcweir         do
927cdf0e10cSrcweir         {
928cdf0e10cSrcweir             for ( long i= mrLabelNames.size()-1; i>=0; i-- )
929cdf0e10cSrcweir             {
930cdf0e10cSrcweir                 if( mrLabelNames[i]->aString == strNewName )
931cdf0e10cSrcweir                 {
932cdf0e10cSrcweir                     strNewName  =  pData->aString;
933cdf0e10cSrcweir                     strNewName += String::CreateFromInt32( nIndex );
934cdf0e10cSrcweir                     nIndex ++ ;
935cdf0e10cSrcweir                     bFound = sal_True;
936cdf0e10cSrcweir                 }
937cdf0e10cSrcweir             }
938cdf0e10cSrcweir             bFound = !bFound;
939cdf0e10cSrcweir         }
940cdf0e10cSrcweir         while ( !bFound );
941cdf0e10cSrcweir     }
942cdf0e10cSrcweir 
943cdf0e10cSrcweir 	pData->aString = strNewName;
944cdf0e10cSrcweir 	mrLabelNames.push_back( pData );
945cdf0e10cSrcweir }
946cdf0e10cSrcweir 
GetItemDataId(sal_uInt16 nDim,SCROW nRow,sal_Bool bRepeatIfEmpty) const947cdf0e10cSrcweir SCROW ScDPTableDataCache::GetItemDataId(sal_uInt16 nDim, SCROW nRow, sal_Bool bRepeatIfEmpty) const
948cdf0e10cSrcweir { //
949cdf0e10cSrcweir 	DBG_ASSERT( IsValid(), "  IsValid() == false " );
950cdf0e10cSrcweir 	DBG_ASSERT( /* nDim >= 0 && */ nDim < mnColumnCount, "ScDPTableDataCache::GetItemDataId " );
951cdf0e10cSrcweir 
952cdf0e10cSrcweir 	if ( bRepeatIfEmpty )
953cdf0e10cSrcweir 	{
954cdf0e10cSrcweir 		while ( nRow >0 && !mpTableDataValues[nDim][ mpSourceData[nDim][nRow] ]->IsHasData() )
955cdf0e10cSrcweir 		--nRow;
956cdf0e10cSrcweir 	}
957cdf0e10cSrcweir 
958cdf0e10cSrcweir 	return mpSourceData[nDim][nRow];
959cdf0e10cSrcweir }
960cdf0e10cSrcweir 
GetItemDataById(long nDim,SCROW nId) const961cdf0e10cSrcweir const ScDPItemData* ScDPTableDataCache::GetItemDataById(long nDim, SCROW nId) const
962cdf0e10cSrcweir {
963cdf0e10cSrcweir     if ( nId >= GetRowCount()  )
964cdf0e10cSrcweir 		return maAdditionalDatas.getData( nId - GetRowCount() );
965cdf0e10cSrcweir 
966cdf0e10cSrcweir 	if (  (size_t)nId >= mpTableDataValues[nDim].size() || nDim >= mnColumnCount  || nId < 0  )
967cdf0e10cSrcweir 		return NULL;
968cdf0e10cSrcweir 	else
969cdf0e10cSrcweir 		return mpTableDataValues[nDim][nId];
970cdf0e10cSrcweir }
971cdf0e10cSrcweir 
GetRowCount() const972cdf0e10cSrcweir SCROW ScDPTableDataCache::GetRowCount() const
973cdf0e10cSrcweir {
974cdf0e10cSrcweir 	if ( IsValid() )
975cdf0e10cSrcweir 		return mpSourceData[0].size();
976cdf0e10cSrcweir 	else
977cdf0e10cSrcweir 		return 0;
978cdf0e10cSrcweir }
979cdf0e10cSrcweir 
GetDimMemberValues(SCCOL nDim) const980cdf0e10cSrcweir const std::vector<ScDPItemData*>& ScDPTableDataCache::GetDimMemberValues(SCCOL nDim) const
981cdf0e10cSrcweir {
982cdf0e10cSrcweir 	DBG_ASSERT( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount ");
983cdf0e10cSrcweir 	return mpTableDataValues[nDim];
984cdf0e10cSrcweir }
985cdf0e10cSrcweir 
GetSortedItemDataId(SCCOL nDim,SCROW nOrder) const986cdf0e10cSrcweir SCROW ScDPTableDataCache::GetSortedItemDataId(SCCOL nDim, SCROW nOrder) const
987cdf0e10cSrcweir {
988cdf0e10cSrcweir 	DBG_ASSERT ( IsValid(), "IsValid");
989cdf0e10cSrcweir 	DBG_ASSERT( nDim>=0 && nDim < mnColumnCount,  "nDim < mnColumnCount");
990cdf0e10cSrcweir 	DBG_ASSERT( nOrder >= 0 && (size_t) nOrder < mpGlobalOrder[nDim].size(), "nOrder < mpGlobalOrder[nDim].size()" );
991cdf0e10cSrcweir 
992cdf0e10cSrcweir 	return mpGlobalOrder[nDim][nOrder];
993cdf0e10cSrcweir }
994cdf0e10cSrcweir 
GetNumType(sal_uLong nFormat) const995cdf0e10cSrcweir sal_uLong ScDPTableDataCache::GetNumType(sal_uLong nFormat) const
996cdf0e10cSrcweir {
997cdf0e10cSrcweir 	SvNumberFormatter* pFormatter = mpDoc->GetFormatTable();
998cdf0e10cSrcweir 	sal_uLong nType = NUMBERFORMAT_NUMBER;
999cdf0e10cSrcweir 	if ( pFormatter )
1000cdf0e10cSrcweir 		nType = pFormatter->GetType( nFormat );
1001cdf0e10cSrcweir 	return nType;
1002cdf0e10cSrcweir }
1003cdf0e10cSrcweir 
GetNumberFormat(long nDim) const1004cdf0e10cSrcweir sal_uLong ScDPTableDataCache::GetNumberFormat( long nDim ) const
1005cdf0e10cSrcweir {
1006cdf0e10cSrcweir 	if ( nDim >= mnColumnCount )
1007cdf0e10cSrcweir 		return 0;
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir     // #i113411# take the number format from the first value entry
1010cdf0e10cSrcweir     size_t nSize = mpTableDataValues[nDim].size();
1011cdf0e10cSrcweir     size_t nPos = 0;
1012cdf0e10cSrcweir     while ( nPos < nSize && mpTableDataValues[nDim][nPos]->GetType() != SC_VALTYPE_VALUE )
1013cdf0e10cSrcweir         ++nPos;
1014cdf0e10cSrcweir     if ( nPos < nSize )
1015cdf0e10cSrcweir         return mpTableDataValues[nDim][nPos]->nNumFormat;
1016cdf0e10cSrcweir     return 0;
1017cdf0e10cSrcweir }
1018cdf0e10cSrcweir 
IsDateDimension(long nDim) const1019cdf0e10cSrcweir sal_Bool ScDPTableDataCache::IsDateDimension( long nDim ) const
1020cdf0e10cSrcweir {
1021cdf0e10cSrcweir 	if ( nDim >= mnColumnCount )
1022cdf0e10cSrcweir 		return false;
1023cdf0e10cSrcweir 	else if ( mpTableDataValues[nDim].size()==0 )
1024cdf0e10cSrcweir 		return false;
1025cdf0e10cSrcweir 	else
1026cdf0e10cSrcweir 		return mpTableDataValues[nDim][0]->IsDate();
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir 
GetDimMemberCount(SCCOL nDim) const1030cdf0e10cSrcweir SCROW ScDPTableDataCache::GetDimMemberCount( SCCOL nDim ) const
1031cdf0e10cSrcweir {
1032cdf0e10cSrcweir 	DBG_ASSERT( nDim>=0 && nDim < mnColumnCount ," ScDPTableDataCache::GetDimMemberCount : out of bound ");
1033cdf0e10cSrcweir 	return mpTableDataValues[nDim].size();
1034cdf0e10cSrcweir }
1035cdf0e10cSrcweir 
GetSortedItemData(SCCOL nDim,SCROW nOrder) const1036cdf0e10cSrcweir const ScDPItemData* ScDPTableDataCache::GetSortedItemData(SCCOL nDim, SCROW nOrder) const
1037cdf0e10cSrcweir {
1038cdf0e10cSrcweir 	SCROW n = GetSortedItemDataId( nDim, nOrder );
1039cdf0e10cSrcweir 	return GetItemDataById( nDim, n );
1040cdf0e10cSrcweir }
1041cdf0e10cSrcweir 
GetDimensionIndex(String sName) const1042cdf0e10cSrcweir SCCOL ScDPTableDataCache::GetDimensionIndex(String sName) const
1043cdf0e10cSrcweir {
1044*0deba7fbSSteve Yin 	for ( size_t n = 1; n < mrLabelNames.size(); n ++ ) //defects, label name map wrong
1045cdf0e10cSrcweir 	{
1046cdf0e10cSrcweir 		if ( mrLabelNames[n]->GetString() == sName )
1047cdf0e10cSrcweir 			return (SCCOL)(n-1);
1048cdf0e10cSrcweir 	}
1049cdf0e10cSrcweir 	return -1;
1050cdf0e10cSrcweir }
1051cdf0e10cSrcweir 
GetIdByItemData(long nDim,String sItemData) const1052cdf0e10cSrcweir SCROW ScDPTableDataCache::GetIdByItemData(long nDim, String sItemData ) const
1053cdf0e10cSrcweir {
1054cdf0e10cSrcweir 	if ( nDim < mnColumnCount && nDim >=0 )
1055cdf0e10cSrcweir 	{
1056cdf0e10cSrcweir 		for ( size_t n = 0; n< mpTableDataValues[nDim].size(); n++ )
1057cdf0e10cSrcweir 		{
1058cdf0e10cSrcweir 			if ( mpTableDataValues[nDim][n]->GetString() == sItemData )
1059cdf0e10cSrcweir 				return n;
1060cdf0e10cSrcweir 		}
1061cdf0e10cSrcweir 	}
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 	ScDPItemData rData ( sItemData );
1064cdf0e10cSrcweir 	return  GetRowCount() +maAdditionalDatas.getDataId(rData);
1065cdf0e10cSrcweir }
1066cdf0e10cSrcweir 
GetIdByItemData(long nDim,const ScDPItemData & rData) const1067cdf0e10cSrcweir SCROW ScDPTableDataCache::GetIdByItemData( long nDim, const ScDPItemData& rData  ) const
1068cdf0e10cSrcweir {
1069cdf0e10cSrcweir 	if ( nDim < mnColumnCount && nDim >=0 )
1070cdf0e10cSrcweir 	{
1071cdf0e10cSrcweir 		for ( size_t n = 0; n< mpTableDataValues[nDim].size(); n++ )
1072cdf0e10cSrcweir 		{
1073cdf0e10cSrcweir 			if ( *mpTableDataValues[nDim][n] == rData )
1074cdf0e10cSrcweir 				return n;
1075cdf0e10cSrcweir 		}
1076cdf0e10cSrcweir 	}
1077cdf0e10cSrcweir 	return  GetRowCount() + maAdditionalDatas.getDataId(rData);
1078cdf0e10cSrcweir }
1079cdf0e10cSrcweir 
GetAdditionalItemID(String sItemData)1080cdf0e10cSrcweir SCROW ScDPTableDataCache::GetAdditionalItemID ( String sItemData )
1081cdf0e10cSrcweir {
1082cdf0e10cSrcweir 	ScDPItemData rData ( sItemData );
1083cdf0e10cSrcweir 	return GetAdditionalItemID( rData );
1084cdf0e10cSrcweir }
1085cdf0e10cSrcweir 
GetAdditionalItemID(const ScDPItemData & rData)1086cdf0e10cSrcweir SCROW ScDPTableDataCache::GetAdditionalItemID( const ScDPItemData& rData )
1087cdf0e10cSrcweir {
1088cdf0e10cSrcweir 	return GetRowCount() + maAdditionalDatas.insertData( rData );
1089cdf0e10cSrcweir }
1090cdf0e10cSrcweir 
1091cdf0e10cSrcweir 
GetOrder(long nDim,SCROW nIndex) const1092cdf0e10cSrcweir SCROW ScDPTableDataCache::GetOrder(long nDim, SCROW nIndex) const
1093cdf0e10cSrcweir {
1094cdf0e10cSrcweir 	DBG_ASSERT( IsValid(), "  IsValid() == false " );
1095cdf0e10cSrcweir 	DBG_ASSERT( nDim >=0 && nDim < mnColumnCount, "ScDPTableDataCache::GetOrder : out of bound" );
1096cdf0e10cSrcweir 
1097cdf0e10cSrcweir 	if ( mpIndexOrder[nDim].size() !=  mpGlobalOrder[nDim].size() )
1098cdf0e10cSrcweir 	{ //not inited
1099cdf0e10cSrcweir 		SCROW i  = 0;
1100cdf0e10cSrcweir 		mpIndexOrder[nDim].resize(  mpGlobalOrder[nDim].size(), 0 );
1101cdf0e10cSrcweir 		for ( size_t n = 0 ; n<  mpGlobalOrder[nDim].size(); n++ )
1102cdf0e10cSrcweir 		{
1103cdf0e10cSrcweir 			i =  mpGlobalOrder[nDim][n];
1104cdf0e10cSrcweir 			mpIndexOrder[nDim][ i ] = n;
1105cdf0e10cSrcweir 		}
1106cdf0e10cSrcweir 	}
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir 	DBG_ASSERT( nIndex>=0 && (size_t)nIndex < mpIndexOrder[nDim].size() , "ScDPTableDataCache::GetOrder");
1109cdf0e10cSrcweir 	return  mpIndexOrder[nDim][nIndex];
1110cdf0e10cSrcweir }
1111cdf0e10cSrcweir 
GetDoc() const1112cdf0e10cSrcweir ScDocument*  ScDPTableDataCache::GetDoc() const
1113cdf0e10cSrcweir {
1114cdf0e10cSrcweir 	return mpDoc;
1115cdf0e10cSrcweir };
1116cdf0e10cSrcweir 
GetColumnCount() const1117cdf0e10cSrcweir long ScDPTableDataCache::GetColumnCount() const
1118cdf0e10cSrcweir {
1119cdf0e10cSrcweir 	return mnColumnCount;
1120cdf0e10cSrcweir }
GetId() const1121cdf0e10cSrcweir long	ScDPTableDataCache::GetId() const
1122cdf0e10cSrcweir {
1123cdf0e10cSrcweir 	return mnID;
1124cdf0e10cSrcweir }
1125