xref: /aoo42x/main/sc/source/core/data/dpcachetable.cxx (revision b3f79822)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b3f79822SAndrew Rist  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19*b3f79822SAndrew Rist  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
24cdf0e10cSrcweir #include "precompiled_sc.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "dpcachetable.hxx"
27cdf0e10cSrcweir #include "document.hxx"
28cdf0e10cSrcweir #include "address.hxx"
29cdf0e10cSrcweir #include "cell.hxx"
30cdf0e10cSrcweir #include "dptabdat.hxx"
31cdf0e10cSrcweir #include "dptabsrc.hxx"
32cdf0e10cSrcweir #include "dpobject.hxx"
33cdf0e10cSrcweir #include "queryparam.hxx"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <com/sun/star/i18n/LocaleDataItem.hpp>
36cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp>
37cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
38cdf0e10cSrcweir #include <com/sun/star/sdbc/XRowSet.hpp>
39cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
40cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
41cdf0e10cSrcweir #include <com/sun/star/util/Date.hpp>
42cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
43cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include <memory>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir using namespace ::com::sun::star;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir using ::rtl::OUString;
50cdf0e10cSrcweir using ::std::vector;
51cdf0e10cSrcweir using ::std::pair;
52cdf0e10cSrcweir using ::std::hash_map;
53cdf0e10cSrcweir using ::std::hash_set;
54cdf0e10cSrcweir using ::std::auto_ptr;
55cdf0e10cSrcweir using ::com::sun::star::i18n::LocaleDataItem;
56cdf0e10cSrcweir using ::com::sun::star::uno::Exception;
57cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
58cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
59cdf0e10cSrcweir using ::com::sun::star::uno::Any;
60cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY;
61cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY_THROW;
62cdf0e10cSrcweir using ::com::sun::star::sheet::DataPilotFieldFilter;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir 
lcl_HasQueryEntry(const ScQueryParam & rParam)65cdf0e10cSrcweir static sal_Bool lcl_HasQueryEntry( const ScQueryParam& rParam )
66cdf0e10cSrcweir {
67cdf0e10cSrcweir     return rParam.GetEntryCount() > 0 &&
68cdf0e10cSrcweir             rParam.GetEntry(0).bDoQuery;
69cdf0e10cSrcweir }
70cdf0e10cSrcweir 
71cdf0e10cSrcweir // ----------------------------------------------------------------------------
72cdf0e10cSrcweir 
FilterItem()73cdf0e10cSrcweir ScDPCacheTable::FilterItem::FilterItem() :
74cdf0e10cSrcweir     mfValue(0.0),
75cdf0e10cSrcweir     mbHasValue(false)
76cdf0e10cSrcweir {
77cdf0e10cSrcweir }
match(const ScDPItemData & rCellData) const78cdf0e10cSrcweir bool  ScDPCacheTable::FilterItem::match( const  ScDPItemData& rCellData ) const
79cdf0e10cSrcweir {
80cdf0e10cSrcweir 	if (rCellData.GetString()!= maString &&
81cdf0e10cSrcweir 		(!rCellData.IsValue()|| rCellData.GetValue()!=  mfValue))
82cdf0e10cSrcweir 	        return false;
83cdf0e10cSrcweir 	return true;
84cdf0e10cSrcweir }
85cdf0e10cSrcweir // ----------------------------------------------------------------------------
86cdf0e10cSrcweir 
SingleFilter(String aString,double fValue,bool bHasValue)87cdf0e10cSrcweir ScDPCacheTable::SingleFilter::SingleFilter(String aString, double fValue, bool bHasValue)
88cdf0e10cSrcweir {
89cdf0e10cSrcweir     maItem.maString = aString;
90cdf0e10cSrcweir     maItem.mfValue      = fValue;
91cdf0e10cSrcweir     maItem.mbHasValue   = bHasValue;
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
match(const ScDPItemData & rCellData) const94cdf0e10cSrcweir bool ScDPCacheTable::SingleFilter::match( const  ScDPItemData& rCellData ) const
95cdf0e10cSrcweir {
96cdf0e10cSrcweir       return maItem.match(rCellData);
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
getMatchString()99cdf0e10cSrcweir const String ScDPCacheTable::SingleFilter::getMatchString()
100cdf0e10cSrcweir {
101cdf0e10cSrcweir     return maItem.maString;
102cdf0e10cSrcweir }
103cdf0e10cSrcweir 
getMatchValue() const104cdf0e10cSrcweir double ScDPCacheTable::SingleFilter::getMatchValue() const
105cdf0e10cSrcweir {
106cdf0e10cSrcweir     return maItem.mfValue;
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
hasValue() const109cdf0e10cSrcweir bool ScDPCacheTable::SingleFilter::hasValue() const
110cdf0e10cSrcweir {
111cdf0e10cSrcweir     return maItem.mbHasValue;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir // ----------------------------------------------------------------------------
115cdf0e10cSrcweir 
GroupFilter()116cdf0e10cSrcweir ScDPCacheTable::GroupFilter::GroupFilter()
117cdf0e10cSrcweir {
118cdf0e10cSrcweir }
119cdf0e10cSrcweir 
match(const ScDPItemData & rCellData) const120cdf0e10cSrcweir bool ScDPCacheTable::GroupFilter::match( const  ScDPItemData& rCellData ) const
121cdf0e10cSrcweir {
122cdf0e10cSrcweir 	vector<FilterItem>::const_iterator itrEnd = maItems.end();
123cdf0e10cSrcweir 	    for (vector<FilterItem>::const_iterator itr = maItems.begin(); itr != itrEnd; ++itr)
124cdf0e10cSrcweir 	    {
125cdf0e10cSrcweir 	        bool bMatch = itr->match( rCellData);
126cdf0e10cSrcweir 	        if (bMatch)
127cdf0e10cSrcweir 	            return  true;
128cdf0e10cSrcweir 	    }
129cdf0e10cSrcweir 	    return false;
130cdf0e10cSrcweir }
131cdf0e10cSrcweir 
addMatchItem(const String & rStr,double fVal,bool bHasValue)132cdf0e10cSrcweir void ScDPCacheTable::GroupFilter::addMatchItem(const String& rStr, double fVal, bool bHasValue)
133cdf0e10cSrcweir {
134cdf0e10cSrcweir     FilterItem aItem;
135cdf0e10cSrcweir     aItem.maString = rStr;
136cdf0e10cSrcweir     aItem.mfValue = fVal;
137cdf0e10cSrcweir     aItem.mbHasValue = bHasValue;
138cdf0e10cSrcweir     maItems.push_back(aItem);
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
getMatchItemCount() const141cdf0e10cSrcweir size_t ScDPCacheTable::GroupFilter::getMatchItemCount() const
142cdf0e10cSrcweir {
143cdf0e10cSrcweir     return maItems.size();
144cdf0e10cSrcweir }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir // ----------------------------------------------------------------------------
147cdf0e10cSrcweir 
Criterion()148cdf0e10cSrcweir ScDPCacheTable::Criterion::Criterion() :
149cdf0e10cSrcweir     mnFieldIndex(-1),
150cdf0e10cSrcweir     mpFilter(static_cast<FilterBase*>(NULL))
151cdf0e10cSrcweir {
152cdf0e10cSrcweir }
153cdf0e10cSrcweir 
154cdf0e10cSrcweir // ----------------------------------------------------------------------------
155cdf0e10cSrcweir 
ScDPCacheTable(ScDocument * pDoc,long nId)156cdf0e10cSrcweir ScDPCacheTable::ScDPCacheTable( ScDocument* pDoc,long nId ) :
157cdf0e10cSrcweir 	mpCache( NULL ),
158cdf0e10cSrcweir 	mpNoneCache( NULL )
159cdf0e10cSrcweir {
160cdf0e10cSrcweir  	if ( nId >= 0 )
161cdf0e10cSrcweir 		mpCache = pDoc->GetDPObjectCache( nId );
162cdf0e10cSrcweir 	else
163cdf0e10cSrcweir 	{ //create a temp cache object
164cdf0e10cSrcweir 		InitNoneCache( NULL );
165cdf0e10cSrcweir 	}
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
~ScDPCacheTable()168cdf0e10cSrcweir ScDPCacheTable::~ScDPCacheTable()
169cdf0e10cSrcweir {
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
getRowSize() const172cdf0e10cSrcweir sal_Int32 ScDPCacheTable::getRowSize() const
173cdf0e10cSrcweir {
174cdf0e10cSrcweir 	return GetCache()->GetRowCount();
175cdf0e10cSrcweir }
176cdf0e10cSrcweir 
getColSize() const177cdf0e10cSrcweir sal_Int32 ScDPCacheTable::getColSize() const
178cdf0e10cSrcweir {
179cdf0e10cSrcweir 	return GetCache()->GetColumnCount();
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
fillTable(const ScQueryParam & rQuery,sal_Bool * pSpecial,bool bIgnoreEmptyRows,bool bRepeatIfEmpty)182cdf0e10cSrcweir void ScDPCacheTable::fillTable(  const ScQueryParam& rQuery, sal_Bool* pSpecial,
183cdf0e10cSrcweir                                bool bIgnoreEmptyRows, bool bRepeatIfEmpty )
184cdf0e10cSrcweir {
185cdf0e10cSrcweir 	if ( mpCache == NULL )
186cdf0e10cSrcweir 		InitNoneCache( NULL );
187cdf0e10cSrcweir //check cache
188cdf0e10cSrcweir    const SCROW	nRowCount = getRowSize();
189cdf0e10cSrcweir    const SCCOL  nColCount = (SCCOL) getColSize();
190cdf0e10cSrcweir    if ( nRowCount <= 0 || nColCount <= 0)
191cdf0e10cSrcweir         return;
192cdf0e10cSrcweir 
193cdf0e10cSrcweir     maRowsVisible.clear();
194cdf0e10cSrcweir     maRowsVisible.reserve(nRowCount);
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     // Initialize field entries container.
198cdf0e10cSrcweir     maFieldEntries.clear();
199cdf0e10cSrcweir     maFieldEntries.reserve(nColCount);
200cdf0e10cSrcweir 
201cdf0e10cSrcweir     // Data rows
202cdf0e10cSrcweir     for (SCCOL nCol = 0; nCol < nColCount; ++nCol)
203cdf0e10cSrcweir     {
204cdf0e10cSrcweir 		SCROW nMemCount = GetCache()->GetDimMemberCount( nCol );
205cdf0e10cSrcweir 		if ( nMemCount )
206cdf0e10cSrcweir 		{
207cdf0e10cSrcweir 			std::vector< SCROW > pAdded( nMemCount, -1 );
208cdf0e10cSrcweir 
209cdf0e10cSrcweir 			for (SCROW nRow = 0; nRow < nRowCount; ++nRow )
210cdf0e10cSrcweir 			{
211cdf0e10cSrcweir 				SCROW nIndex = GetCache()->GetItemDataId( nCol, nRow, bRepeatIfEmpty );
212cdf0e10cSrcweir 				SCROW nOrder = GetCache()->GetOrder( nCol, nIndex );
213cdf0e10cSrcweir 
214cdf0e10cSrcweir                 if ( nCol == 0 )
215cdf0e10cSrcweir                          maRowsVisible.push_back(false);
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 				if ( lcl_HasQueryEntry(rQuery) &&
218cdf0e10cSrcweir 					!GetCache()->ValidQuery( nRow , rQuery, pSpecial ) )
219cdf0e10cSrcweir 					continue;
220cdf0e10cSrcweir 				if ( bIgnoreEmptyRows &&  GetCache()->IsRowEmpty( nRow ) )
221cdf0e10cSrcweir 					continue;
222cdf0e10cSrcweir 				// Insert a new row into cache table.
223cdf0e10cSrcweir 				if ( nCol == 0 )
224cdf0e10cSrcweir 					 maRowsVisible.back() = true;
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 				pAdded[nOrder] = nIndex;
227cdf0e10cSrcweir 			}
228cdf0e10cSrcweir 			maFieldEntries.push_back( vector<SCROW>() );
229cdf0e10cSrcweir 			for ( SCROW nRow = 0; nRow < nMemCount; nRow++ )
230cdf0e10cSrcweir 			{
231cdf0e10cSrcweir 				if ( pAdded[nRow] != -1 )
232cdf0e10cSrcweir 					maFieldEntries.back().push_back( pAdded[nRow] );
233cdf0e10cSrcweir 			}
234cdf0e10cSrcweir         }
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
fillTable()238cdf0e10cSrcweir void ScDPCacheTable::fillTable()
239cdf0e10cSrcweir {
240cdf0e10cSrcweir 	if ( mpCache == NULL )
241cdf0e10cSrcweir 		InitNoneCache( NULL );
242cdf0e10cSrcweir //check cache
243cdf0e10cSrcweir    const SCROW	nRowCount = getRowSize();
244cdf0e10cSrcweir    const SCCOL  nColCount = (SCCOL) getColSize();
245cdf0e10cSrcweir    if ( nRowCount <= 0 || nColCount <= 0)
246cdf0e10cSrcweir         return;
247cdf0e10cSrcweir 
248cdf0e10cSrcweir     maRowsVisible.clear();
249cdf0e10cSrcweir     maRowsVisible.reserve(nRowCount);
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 
252cdf0e10cSrcweir     // Initialize field entries container.
253cdf0e10cSrcweir     maFieldEntries.clear();
254cdf0e10cSrcweir     maFieldEntries.reserve(nColCount);
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     // Data rows
257cdf0e10cSrcweir     for (SCCOL nCol = 0; nCol < nColCount; ++nCol)
258cdf0e10cSrcweir     {
259cdf0e10cSrcweir 		SCROW nMemCount = GetCache()->GetDimMemberCount( nCol );
260cdf0e10cSrcweir 		if ( nMemCount )
261cdf0e10cSrcweir 		{
262cdf0e10cSrcweir 			std::vector< SCROW > pAdded( nMemCount, -1 );
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 			for (SCROW nRow = 0; nRow < nRowCount; ++nRow )
265cdf0e10cSrcweir 			{
266cdf0e10cSrcweir 				SCROW nIndex = GetCache()->GetItemDataId( nCol, nRow, false );
267cdf0e10cSrcweir 				SCROW nOrder = GetCache()->GetOrder( nCol, nIndex );
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 				if ( nCol == 0 )
270cdf0e10cSrcweir 				     maRowsVisible.push_back(true);
271cdf0e10cSrcweir 
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 				pAdded[nOrder] = nIndex;
274cdf0e10cSrcweir 			}
275cdf0e10cSrcweir 			maFieldEntries.push_back( vector<SCROW>() );
276cdf0e10cSrcweir 			for ( SCROW nRow = 0; nRow < nMemCount; nRow++ )
277cdf0e10cSrcweir 			{
278cdf0e10cSrcweir 				if ( pAdded[nRow] != -1 )
279cdf0e10cSrcweir 					maFieldEntries.back().push_back( pAdded[nRow] );
280cdf0e10cSrcweir 			}
281cdf0e10cSrcweir         }
282cdf0e10cSrcweir     }
283cdf0e10cSrcweir         return;
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
isRowActive(sal_Int32 nRow) const286cdf0e10cSrcweir bool ScDPCacheTable::isRowActive(sal_Int32 nRow) const
287cdf0e10cSrcweir {
288cdf0e10cSrcweir     if (nRow < 0 || static_cast<size_t>(nRow) >= maRowsVisible.size())
289cdf0e10cSrcweir         // row index out of bound
290cdf0e10cSrcweir         return false;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     return maRowsVisible[nRow];
293cdf0e10cSrcweir }
294cdf0e10cSrcweir 
filterByPageDimension(const vector<Criterion> & rCriteria,const hash_set<sal_Int32> & rRepeatIfEmptyDims)295cdf0e10cSrcweir void ScDPCacheTable::filterByPageDimension(const vector<Criterion>& rCriteria, const hash_set<sal_Int32>& rRepeatIfEmptyDims)
296cdf0e10cSrcweir {
297cdf0e10cSrcweir     sal_Int32 nRowSize = getRowSize();
298cdf0e10cSrcweir     if (nRowSize != static_cast<sal_Int32>(maRowsVisible.size()))
299cdf0e10cSrcweir     {
300cdf0e10cSrcweir         // sizes of the two tables differ!
301cdf0e10cSrcweir         return;
302cdf0e10cSrcweir     }
303cdf0e10cSrcweir 
304bfbd599dSEike Rathke     // #i117661# If maRowsVisible is already false from source filtering, don't set to true again.
305bfbd599dSEike Rathke     // filterByPageDimension is called only once after initializing with fillTable
306bfbd599dSEike Rathke     // (this is enforced in ScDPSource::FilterCacheTableByPageDimensions).
307bfbd599dSEike Rathke 
308cdf0e10cSrcweir     for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
309bfbd599dSEike Rathke         maRowsVisible[nRow] = maRowsVisible[nRow] && isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims);
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
getCell(SCCOL nCol,SCROW nRow,bool bRepeatIfEmpty) const312cdf0e10cSrcweir const ScDPItemData* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const
313cdf0e10cSrcweir {
314cdf0e10cSrcweir    SCROW nId= GetCache()->GetItemDataId(nCol, nRow, bRepeatIfEmpty);
315cdf0e10cSrcweir    return GetCache()->GetItemDataById( nCol, nId );
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
getValue(ScDPValueData & rVal,SCCOL nCol,SCROW nRow,bool bRepeatIfEmpty) const318cdf0e10cSrcweir void  ScDPCacheTable::getValue( ScDPValueData& rVal, SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const
319cdf0e10cSrcweir {
320cdf0e10cSrcweir 	const ScDPItemData* pData = getCell( nCol, nRow, bRepeatIfEmpty );
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 	if (pData)
323cdf0e10cSrcweir 	{
324cdf0e10cSrcweir 		rVal.fValue = pData->IsValue() ? pData->GetValue() : 0.0;
325cdf0e10cSrcweir 		rVal.nType = pData->GetType();
326cdf0e10cSrcweir 	}
327cdf0e10cSrcweir 	else
328cdf0e10cSrcweir 		rVal.Set(0.0, SC_VALTYPE_EMPTY);
329cdf0e10cSrcweir }
getFieldName(SCCOL nIndex) const330cdf0e10cSrcweir String ScDPCacheTable::getFieldName(SCCOL  nIndex) const
331cdf0e10cSrcweir {
332cdf0e10cSrcweir 	return (GetCache()->GetDimensionName( nIndex ));
333cdf0e10cSrcweir }
334cdf0e10cSrcweir 
getFieldIndex(const String & rStr) const335cdf0e10cSrcweir sal_Int32 ScDPCacheTable::getFieldIndex(const String& rStr) const
336cdf0e10cSrcweir {
337cdf0e10cSrcweir 	return GetCache()->GetDimensionIndex( rStr );
338cdf0e10cSrcweir }
339cdf0e10cSrcweir 
getFieldEntries(sal_Int32 nColumn) const340cdf0e10cSrcweir const ::std::vector<SCROW>&  ScDPCacheTable::getFieldEntries( sal_Int32 nColumn ) const
341cdf0e10cSrcweir {
342cdf0e10cSrcweir 	 if (nColumn < 0 || static_cast<size_t>(nColumn) >= maFieldEntries.size())
343cdf0e10cSrcweir     {
344cdf0e10cSrcweir         // index out of bound.  Hopefully this code will never be reached.
345cdf0e10cSrcweir         static const ::std::vector<SCROW> emptyEntries;
346cdf0e10cSrcweir         return emptyEntries;
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir 	 return maFieldEntries[nColumn];
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
filterTable(const vector<Criterion> & rCriteria,Sequence<Sequence<Any>> & rTabData,const hash_set<sal_Int32> & rRepeatIfEmptyDims)351cdf0e10cSrcweir void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< Sequence<Any> >& rTabData,
352cdf0e10cSrcweir                                  const hash_set<sal_Int32>& rRepeatIfEmptyDims)
353cdf0e10cSrcweir {
354cdf0e10cSrcweir     sal_Int32 nRowSize = getRowSize();
355cdf0e10cSrcweir     sal_Int32 nColSize = getColSize();
356cdf0e10cSrcweir 
357cdf0e10cSrcweir     if (!nRowSize)
358cdf0e10cSrcweir         // no data to filter.
359cdf0e10cSrcweir         return;
360cdf0e10cSrcweir 
361cdf0e10cSrcweir     // Row first, then column.
362cdf0e10cSrcweir     vector< Sequence<Any> > tableData;
363cdf0e10cSrcweir     tableData.reserve(nRowSize+1);
364cdf0e10cSrcweir 
365cdf0e10cSrcweir     // Header first.
366cdf0e10cSrcweir     Sequence<Any> headerRow(nColSize);
367cdf0e10cSrcweir     for (SCCOL  nCol = 0; nCol < nColSize; ++nCol)
368cdf0e10cSrcweir     {
369cdf0e10cSrcweir         OUString str;
370cdf0e10cSrcweir 		str = getFieldName( nCol);
371cdf0e10cSrcweir         Any any;
372cdf0e10cSrcweir         any <<= str;
373cdf0e10cSrcweir         headerRow[nCol] = any;
374cdf0e10cSrcweir     }
375cdf0e10cSrcweir     tableData.push_back(headerRow);
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
379cdf0e10cSrcweir     {
380cdf0e10cSrcweir         if (!maRowsVisible[nRow])
381cdf0e10cSrcweir             // This row is filtered out.
382cdf0e10cSrcweir             continue;
383cdf0e10cSrcweir 
384cdf0e10cSrcweir         if (!isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims))
385cdf0e10cSrcweir             continue;
386cdf0e10cSrcweir 
387cdf0e10cSrcweir         // Insert this row into table.
388cdf0e10cSrcweir 
389cdf0e10cSrcweir         Sequence<Any> row(nColSize);
390cdf0e10cSrcweir         for (SCCOL nCol = 0; nCol < nColSize; ++nCol)
391cdf0e10cSrcweir         {
392cdf0e10cSrcweir             Any any;
393cdf0e10cSrcweir             bool bRepeatIfEmpty = rRepeatIfEmptyDims.count(nCol) > 0;
394cdf0e10cSrcweir             // Wang Xu Ming - DataPilot migration
395cdf0e10cSrcweir 			const ScDPItemData* pData= getCell(nCol, nRow, bRepeatIfEmpty);
396cdf0e10cSrcweir 			if ( pData->IsValue() )
397cdf0e10cSrcweir                 any <<= pData->GetValue();
398cdf0e10cSrcweir             else
399cdf0e10cSrcweir             {
400cdf0e10cSrcweir             	  OUString string (pData->GetString() );
401cdf0e10cSrcweir                   any <<= string;
402cdf0e10cSrcweir             }
403cdf0e10cSrcweir             row[nCol] = any;
404cdf0e10cSrcweir         }
405cdf0e10cSrcweir         tableData.push_back(row);
406cdf0e10cSrcweir     }
407cdf0e10cSrcweir 
408cdf0e10cSrcweir     // convert vector to Seqeunce
409cdf0e10cSrcweir     sal_Int32 nTabSize = static_cast<sal_Int32>(tableData.size());
410cdf0e10cSrcweir     rTabData.realloc(nTabSize);
411cdf0e10cSrcweir     for (sal_Int32 i = 0; i < nTabSize; ++i)
412cdf0e10cSrcweir         rTabData[i] = tableData[i];
413cdf0e10cSrcweir }
414cdf0e10cSrcweir 
clear()415cdf0e10cSrcweir void ScDPCacheTable::clear()
416cdf0e10cSrcweir {
417cdf0e10cSrcweir 	maFieldEntries.clear();
418cdf0e10cSrcweir 	maRowsVisible.clear();
419cdf0e10cSrcweir }
420cdf0e10cSrcweir 
swap(ScDPCacheTable & rOther)421cdf0e10cSrcweir void ScDPCacheTable::swap(ScDPCacheTable& rOther)
422cdf0e10cSrcweir {
423cdf0e10cSrcweir     maFieldEntries.swap(rOther.maFieldEntries);
424cdf0e10cSrcweir     maRowsVisible.swap(rOther.maRowsVisible);
425cdf0e10cSrcweir }
426cdf0e10cSrcweir 
empty() const427cdf0e10cSrcweir bool ScDPCacheTable::empty() const
428cdf0e10cSrcweir {
429cdf0e10cSrcweir 	return ( mpCache == NULL&& mpNoneCache == NULL ) || maFieldEntries.size()==0;
430cdf0e10cSrcweir }
431cdf0e10cSrcweir 
isRowQualified(sal_Int32 nRow,const vector<Criterion> & rCriteria,const hash_set<sal_Int32> & rRepeatIfEmptyDims) const432cdf0e10cSrcweir bool ScDPCacheTable::isRowQualified(sal_Int32 nRow, const vector<Criterion>& rCriteria,
433cdf0e10cSrcweir                                     const hash_set<sal_Int32>& rRepeatIfEmptyDims) const
434cdf0e10cSrcweir {
435cdf0e10cSrcweir     sal_Int32 nColSize = getColSize();
436cdf0e10cSrcweir     vector<Criterion>::const_iterator itrEnd = rCriteria.end();
437cdf0e10cSrcweir     for (vector<Criterion>::const_iterator itr = rCriteria.begin(); itr != itrEnd; ++itr)
438cdf0e10cSrcweir     {
439cdf0e10cSrcweir         if (itr->mnFieldIndex >= nColSize)
440cdf0e10cSrcweir             // specified field is outside the source data columns.  Don't
441cdf0e10cSrcweir             // use this criterion.
442cdf0e10cSrcweir             continue;
443cdf0e10cSrcweir 
444cdf0e10cSrcweir         // Check if the 'repeat if empty' flag is set for this field.
445cdf0e10cSrcweir         bool bRepeatIfEmpty = rRepeatIfEmptyDims.count(itr->mnFieldIndex) > 0;
446cdf0e10cSrcweir 		const ScDPItemData* pCellData = getCell(static_cast<SCCOL>(itr->mnFieldIndex), nRow, bRepeatIfEmpty);
447cdf0e10cSrcweir         if (!itr->mpFilter->match(*pCellData))
448cdf0e10cSrcweir             return false;
449cdf0e10cSrcweir     }
450cdf0e10cSrcweir     return true;
451cdf0e10cSrcweir }
452cdf0e10cSrcweir 
453cdf0e10cSrcweir 
InitNoneCache(ScDocument * pDoc)454cdf0e10cSrcweir void ScDPCacheTable::InitNoneCache( ScDocument* pDoc )
455cdf0e10cSrcweir {
456cdf0e10cSrcweir 	mpCache = NULL;
457cdf0e10cSrcweir 	if ( mpNoneCache )
458cdf0e10cSrcweir 		delete mpNoneCache;
459cdf0e10cSrcweir 	mpNoneCache = new ScDPTableDataCache( pDoc );
460cdf0e10cSrcweir }
461cdf0e10cSrcweir 
GetCache() const462cdf0e10cSrcweir ScDPTableDataCache* ScDPCacheTable::GetCache() const
463cdf0e10cSrcweir {
464cdf0e10cSrcweir 	if ( mpCache )
465cdf0e10cSrcweir 		return mpCache;
466cdf0e10cSrcweir 	return mpNoneCache;
467cdf0e10cSrcweir }
468cdf0e10cSrcweir // End Comments
469