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