xref: /aoo41x/main/sc/source/core/data/dpshttab.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 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir // INCLUDE --------------------------------------------------------------
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <tools/debug.hxx>
32cdf0e10cSrcweir #include <svl/zforlist.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "dpshttab.hxx"
35cdf0e10cSrcweir #include "dptabres.hxx"
36cdf0e10cSrcweir #include "document.hxx"
37cdf0e10cSrcweir #include "collect.hxx"
38cdf0e10cSrcweir #include "cell.hxx"
39cdf0e10cSrcweir #include "dpcachetable.hxx"
40cdf0e10cSrcweir #include "dpobject.hxx"
41cdf0e10cSrcweir #include "globstr.hrc"
42cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
43cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
44cdf0e10cSrcweir #include "dpglobal.hxx"
45cdf0e10cSrcweir // End Comments
46cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include <vector>
49cdf0e10cSrcweir #include <set>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir using namespace ::com::sun::star;
52cdf0e10cSrcweir using ::com::sun::star::uno::Any;
53cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
54cdf0e10cSrcweir using ::std::vector;
55cdf0e10cSrcweir using ::std::hash_map;
56cdf0e10cSrcweir using ::std::hash_set;
57cdf0e10cSrcweir 
58cdf0e10cSrcweir // -----------------------------------------------------------------------
59cdf0e10cSrcweir 
ScSheetDPData(ScDocument * pD,const ScSheetSourceDesc & rDesc,long nCacheId)60cdf0e10cSrcweir ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc , long nCacheId) :
61cdf0e10cSrcweir     ScDPTableData(pD, rDesc.GetCacheId( pD, nCacheId) ), // DataPilot Migration - Cache&&Performance
62cdf0e10cSrcweir 	aQuery ( rDesc.aQueryParam  ),
63cdf0e10cSrcweir 	pSpecial(NULL),
64cdf0e10cSrcweir 	bIgnoreEmptyRows( sal_False ),
65cdf0e10cSrcweir 	bRepeatIfEmpty(sal_False),
66cdf0e10cSrcweir     aCacheTable( pD, GetCacheId() )     // base class ID is initialized with the GetCacheId call above
67cdf0e10cSrcweir {
68cdf0e10cSrcweir     SCSIZE nEntryCount( aQuery.GetEntryCount());
69cdf0e10cSrcweir     pSpecial = new sal_Bool[nEntryCount];
70cdf0e10cSrcweir     for (SCSIZE j = 0; j < nEntryCount; ++j )
71cdf0e10cSrcweir     {
72cdf0e10cSrcweir         ScQueryEntry& rEntry = aQuery.GetEntry(j);
73cdf0e10cSrcweir         if (rEntry.bDoQuery)
74cdf0e10cSrcweir         {
75cdf0e10cSrcweir            pSpecial[j] = false;
76cdf0e10cSrcweir             if (!rEntry.bQueryByString)
77cdf0e10cSrcweir             {
78cdf0e10cSrcweir                 if (*rEntry.pStr == EMPTY_STRING &&
79cdf0e10cSrcweir                    ((rEntry.nVal == SC_EMPTYFIELDS) || (rEntry.nVal == SC_NONEMPTYFIELDS)))
80cdf0e10cSrcweir                     pSpecial[j] = true;
81cdf0e10cSrcweir             }
82cdf0e10cSrcweir             else
83cdf0e10cSrcweir             {
84cdf0e10cSrcweir 		        sal_uInt32 nIndex = 0;
85cdf0e10cSrcweir 		        rEntry.bQueryByString =
86cdf0e10cSrcweir 					        !(pD->GetFormatTable()->
87cdf0e10cSrcweir 						        IsNumberFormat(*rEntry.pStr, nIndex, rEntry.nVal));
88cdf0e10cSrcweir             }
89cdf0e10cSrcweir     	}
90cdf0e10cSrcweir     }
91cdf0e10cSrcweir }
92cdf0e10cSrcweir 
~ScSheetDPData()93cdf0e10cSrcweir ScSheetDPData::~ScSheetDPData()
94cdf0e10cSrcweir {
95cdf0e10cSrcweir 	 delete[] pSpecial;
96cdf0e10cSrcweir }
97cdf0e10cSrcweir 
DisposeData()98cdf0e10cSrcweir void ScSheetDPData::DisposeData()
99cdf0e10cSrcweir {
100cdf0e10cSrcweir     aCacheTable.clear();
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
GetColumnCount()103cdf0e10cSrcweir long ScSheetDPData::GetColumnCount()
104cdf0e10cSrcweir {
105cdf0e10cSrcweir     CreateCacheTable();
106cdf0e10cSrcweir     return aCacheTable.getColSize();
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
getDimensionName(long nColumn)109cdf0e10cSrcweir String ScSheetDPData::getDimensionName(long nColumn)
110cdf0e10cSrcweir {
111cdf0e10cSrcweir     CreateCacheTable();
112cdf0e10cSrcweir 	if (getIsDataLayoutDimension(nColumn))
113cdf0e10cSrcweir 	{
114cdf0e10cSrcweir 		//!	different internal and display names?
115cdf0e10cSrcweir 		//return "Data";
116cdf0e10cSrcweir 		return ScGlobal::GetRscString(STR_PIVOT_DATA);
117cdf0e10cSrcweir 	}
118cdf0e10cSrcweir     else if (nColumn >= aCacheTable.getColSize())
119cdf0e10cSrcweir 	{
120cdf0e10cSrcweir 		DBG_ERROR("getDimensionName: invalid dimension");
121cdf0e10cSrcweir 		return String();
122cdf0e10cSrcweir 	}
123cdf0e10cSrcweir 	else
124cdf0e10cSrcweir 	{
125cdf0e10cSrcweir 		return  aCacheTable.getFieldName((SCCOL)nColumn);
126cdf0e10cSrcweir 	}
127cdf0e10cSrcweir }
128cdf0e10cSrcweir 
IsDateDimension(long nDim)129cdf0e10cSrcweir sal_Bool ScSheetDPData::IsDateDimension(long nDim)
130cdf0e10cSrcweir {
131cdf0e10cSrcweir 	CreateCacheTable();
132cdf0e10cSrcweir 	long nColCount = aCacheTable.getColSize();
133cdf0e10cSrcweir 	if (getIsDataLayoutDimension(nDim))
134cdf0e10cSrcweir 	{
135cdf0e10cSrcweir 		return sal_False;
136cdf0e10cSrcweir 	}
137cdf0e10cSrcweir 	else if (nDim >= nColCount)
138cdf0e10cSrcweir 	{
139cdf0e10cSrcweir 		DBG_ERROR("IsDateDimension: invalid dimension");
140cdf0e10cSrcweir 		return sal_False;
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir 	else
143cdf0e10cSrcweir 	{
144cdf0e10cSrcweir 		return aCacheTable.GetCache()->IsDateDimension( nDim);
145cdf0e10cSrcweir 	}
146cdf0e10cSrcweir }
147cdf0e10cSrcweir 
GetNumberFormat(long nDim)148cdf0e10cSrcweir sal_uLong ScSheetDPData::GetNumberFormat(long nDim)
149cdf0e10cSrcweir {
150cdf0e10cSrcweir 	CreateCacheTable();
151cdf0e10cSrcweir 	if (getIsDataLayoutDimension(nDim))
152cdf0e10cSrcweir 	{
153cdf0e10cSrcweir 		return 0;
154cdf0e10cSrcweir 	}
155cdf0e10cSrcweir 	else if (nDim >= GetCacheTable().getColSize())
156cdf0e10cSrcweir 	{
157cdf0e10cSrcweir 		DBG_ERROR("GetNumberFormat: invalid dimension");
158cdf0e10cSrcweir 		return 0;
159cdf0e10cSrcweir 	}
160cdf0e10cSrcweir 	else
161cdf0e10cSrcweir 	{
162cdf0e10cSrcweir 		return GetCacheTable().GetCache()->GetNumberFormat( nDim );
163cdf0e10cSrcweir 	}
164cdf0e10cSrcweir }
GetNumberFormatByIdx(NfIndexTableOffset eIdx)165cdf0e10cSrcweir sal_uInt32	ScDPTableData::GetNumberFormatByIdx( NfIndexTableOffset eIdx )
166cdf0e10cSrcweir {
167cdf0e10cSrcweir 	if( !mpDoc )
168cdf0e10cSrcweir 		return 0;
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 	if ( SvNumberFormatter* pFormatter = mpDoc->GetFormatTable() )
171cdf0e10cSrcweir 		return pFormatter->GetFormatIndex( eIdx, LANGUAGE_SYSTEM );
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 	return 0;
174cdf0e10cSrcweir }
175cdf0e10cSrcweir 
getIsDataLayoutDimension(long nColumn)176cdf0e10cSrcweir sal_Bool ScSheetDPData::getIsDataLayoutDimension(long nColumn)
177cdf0e10cSrcweir {
178cdf0e10cSrcweir     CreateCacheTable();
179cdf0e10cSrcweir     return (nColumn ==(long)( aCacheTable.getColSize()));
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
SetEmptyFlags(sal_Bool bIgnoreEmptyRowsP,sal_Bool bRepeatIfEmptyP)182cdf0e10cSrcweir void ScSheetDPData::SetEmptyFlags( sal_Bool bIgnoreEmptyRowsP, sal_Bool bRepeatIfEmptyP )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir     bIgnoreEmptyRows = bIgnoreEmptyRowsP;
185cdf0e10cSrcweir     bRepeatIfEmpty   = bRepeatIfEmptyP;
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
IsRepeatIfEmpty()188cdf0e10cSrcweir bool ScSheetDPData::IsRepeatIfEmpty()
189cdf0e10cSrcweir {
190cdf0e10cSrcweir     return bRepeatIfEmpty;
191cdf0e10cSrcweir }
192cdf0e10cSrcweir 
CreateCacheTable()193cdf0e10cSrcweir void ScSheetDPData::CreateCacheTable()
194cdf0e10cSrcweir {
195cdf0e10cSrcweir     // Scan and store the data from the source range.
196cdf0e10cSrcweir     if (!aCacheTable.empty())
197cdf0e10cSrcweir         // already cached.
198cdf0e10cSrcweir         return;
199cdf0e10cSrcweir 
200cdf0e10cSrcweir     aCacheTable.fillTable( aQuery, pSpecial,
201cdf0e10cSrcweir                                 bIgnoreEmptyRows, bRepeatIfEmpty );
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
FilterCacheTable(const vector<ScDPCacheTable::Criterion> & rCriteria,const hash_set<sal_Int32> & rCatDims)204cdf0e10cSrcweir void ScSheetDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims)
205cdf0e10cSrcweir {
206cdf0e10cSrcweir     CreateCacheTable();
207cdf0e10cSrcweir     aCacheTable.filterByPageDimension(
208cdf0e10cSrcweir         rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()));
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
GetDrillDownData(const vector<ScDPCacheTable::Criterion> & rCriteria,const hash_set<sal_Int32> & rCatDims,Sequence<Sequence<Any>> & rData)211cdf0e10cSrcweir void ScSheetDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData)
212cdf0e10cSrcweir {
213cdf0e10cSrcweir     CreateCacheTable();
214cdf0e10cSrcweir     sal_Int32 nRowSize = aCacheTable.getRowSize();
215cdf0e10cSrcweir     if (!nRowSize)
216cdf0e10cSrcweir         return;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir     aCacheTable.filterTable(
219cdf0e10cSrcweir         rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>());
220cdf0e10cSrcweir }
221cdf0e10cSrcweir 
CalcResults(CalcInfo & rInfo,bool bAutoShow)222cdf0e10cSrcweir void ScSheetDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
223cdf0e10cSrcweir {
224cdf0e10cSrcweir     CreateCacheTable();
225cdf0e10cSrcweir     CalcResultsFromCacheTable(aCacheTable, rInfo, bAutoShow);
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
GetCacheTable() const228cdf0e10cSrcweir const ScDPCacheTable& ScSheetDPData::GetCacheTable() const
229cdf0e10cSrcweir {
230cdf0e10cSrcweir     return aCacheTable;
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 
234cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-5
235cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
CreateCache(ScDocument * pDoc,long nID) const236cdf0e10cSrcweir ScDPTableDataCache* ScSheetSourceDesc::CreateCache( ScDocument* pDoc , long nID ) const
237cdf0e10cSrcweir {
238cdf0e10cSrcweir     if ( pDoc )
239cdf0e10cSrcweir     {
240cdf0e10cSrcweir         ScDPTableDataCache* pCache =  GetExistDPObjectCache( pDoc );
241cdf0e10cSrcweir         if ( pCache && ( nID < 0 || nID == pCache->GetId() ) )
242cdf0e10cSrcweir             return pCache;
243cdf0e10cSrcweir 
244cdf0e10cSrcweir         sal_uLong nErrId = CheckValidate( pDoc );
245cdf0e10cSrcweir         if ( !nErrId )
246cdf0e10cSrcweir         {
247cdf0e10cSrcweir             pCache = new ScDPTableDataCache( pDoc );
248cdf0e10cSrcweir 
249cdf0e10cSrcweir             pCache->InitFromDoc( pDoc, aSourceRange );
250cdf0e10cSrcweir             pCache->SetId( nID );
251cdf0e10cSrcweir             pDoc->AddDPObjectCache( pCache );
252cdf0e10cSrcweir 
253cdf0e10cSrcweir             DBG_TRACE1("Create a cache id = %d \n", pCache->GetId() );
254cdf0e10cSrcweir         }
255cdf0e10cSrcweir         else
256cdf0e10cSrcweir             DBG_ERROR( "\n Error Create Cache" );
257cdf0e10cSrcweir         return pCache;
258cdf0e10cSrcweir     }
259cdf0e10cSrcweir     return NULL;
260cdf0e10cSrcweir }
261cdf0e10cSrcweir 
GetExistDPObjectCache(ScDocument * pDoc) const262cdf0e10cSrcweir ScDPTableDataCache* ScSheetSourceDesc::GetExistDPObjectCache ( ScDocument* pDoc  ) const
263cdf0e10cSrcweir {
264cdf0e10cSrcweir     return pDoc->GetUsedDPObjectCache( aSourceRange );
265cdf0e10cSrcweir }
GetCache(ScDocument * pDoc,long nID) const266cdf0e10cSrcweir ScDPTableDataCache* ScSheetSourceDesc::GetCache( ScDocument* pDoc, long nID ) const
267cdf0e10cSrcweir {
268cdf0e10cSrcweir     ScDPTableDataCache* pCache = pDoc->GetDPObjectCache( nID );
269cdf0e10cSrcweir     if ( NULL == pCache && pDoc )
270cdf0e10cSrcweir         pCache = GetExistDPObjectCache( pDoc );
271cdf0e10cSrcweir     if ( NULL == pCache )
272cdf0e10cSrcweir         pCache = CreateCache( pDoc );
273cdf0e10cSrcweir     return pCache;
274cdf0e10cSrcweir }
275cdf0e10cSrcweir 
GetCacheId(ScDocument * pDoc,long nID) const276cdf0e10cSrcweir long ScSheetSourceDesc:: GetCacheId( ScDocument* pDoc, long nID ) const
277cdf0e10cSrcweir {
278cdf0e10cSrcweir 	ScDPTableDataCache* pCache = GetCache( pDoc,  nID);
279cdf0e10cSrcweir 	if ( NULL == pCache )
280cdf0e10cSrcweir 		return -1;
281cdf0e10cSrcweir 	else
282cdf0e10cSrcweir 		return pCache->GetId();
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
CheckValidate(ScDocument * pDoc) const285cdf0e10cSrcweir sal_uLong ScSheetSourceDesc::CheckValidate( ScDocument* pDoc ) const
286cdf0e10cSrcweir {
287cdf0e10cSrcweir     ScRange aSrcRange( aSourceRange);
288cdf0e10cSrcweir     if ( !pDoc )
289cdf0e10cSrcweir         return STR_ERR_DATAPILOTSOURCE;
290cdf0e10cSrcweir 
291cdf0e10cSrcweir     // #i116457# Empty column titles were allowed before 3.3, and might be useful for hidden columns with annotations.
292cdf0e10cSrcweir     // Be compatible with 3.2: Allow empty titles, create columns with empty names, hide them in the dialogs.
293cdf0e10cSrcweir 
294cdf0e10cSrcweir     if( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), aSrcRange.aStart.Col(), aSrcRange.aStart.Row()+1, aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row() ) )
295cdf0e10cSrcweir     {
296cdf0e10cSrcweir         return STR_PIVOT_ONLYONEROWERR;
297cdf0e10cSrcweir     }
298cdf0e10cSrcweir     return 0;
299cdf0e10cSrcweir }
300cdf0e10cSrcweir // End Comments
301cdf0e10cSrcweir 
302cdf0e10cSrcweir // -----------------------------------------------------------------------
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 
310