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
10cdf0e10cSrcweir *
11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
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.
19cdf0e10cSrcweir *
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