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