xref: /trunk/main/sc/source/core/data/dptabdat.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 <stdio.h>
36 #include <rtl/math.hxx>
37 #include <tools/debug.hxx>
38 #include <tools/date.hxx>
39 #include <unotools/transliterationwrapper.hxx>
40 #include <unotools/collatorwrapper.hxx>
41 
42 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
43 
44 #include "dptabdat.hxx"
45 #include "global.hxx"
46 #include "dpcachetable.hxx"
47 #include "dptabres.hxx"
48 #include "document.hxx"
49 #include "dpobject.hxx"
50 
51 using namespace ::com::sun::star;
52 using ::com::sun::star::uno::Sequence;
53 using ::com::sun::star::uno::Any;
54 using ::std::vector;
55 // ---------------------------------------------------------------------------
56 
57 ScDPTableData::CalcInfo::CalcInfo() :
58     bRepeatIfEmpty(false)
59 {
60 }
61 
62 // ---------------------------------------------------------------------------
63 
64 ScDPTableData::ScDPTableData(ScDocument* pDoc, long nCacheId ) :
65     mnCacheId( nCacheId ),
66     mpDoc ( pDoc )
67 {
68 	nLastDateVal = nLastHier = nLastLevel = nLastRet = -1;		// invalid
69 
70 	//!	reset before new calculation (in case the base date is changed)
71 }
72 
73 ScDPTableData::~ScDPTableData()
74 {
75 }
76 
77 long ScDPTableData::GetDatePart( long nDateVal, long nHierarchy, long nLevel )
78 {
79 	if ( nDateVal == nLastDateVal && nHierarchy == nLastHier && nLevel == nLastLevel )
80 		return nLastRet;
81 
82 	Date aDate( 30,12,1899 );					//! get from source data (and cache here)
83 	aDate += nDateVal;
84 
85 	long nRet = 0;
86 	switch (nHierarchy)
87 	{
88 		case SC_DAPI_HIERARCHY_QUARTER:
89 			switch (nLevel)
90 			{
91 				case 0:	nRet = aDate.GetYear();					break;
92 				case 1:	nRet = (aDate.GetMonth()-1) / 3 + 1;	break;
93 				case 2:	nRet = aDate.GetMonth();				break;
94 				case 3:	nRet = aDate.GetDay();					break;
95 				default:
96 					DBG_ERROR("GetDatePart: wrong level");
97 			}
98 			break;
99 		case SC_DAPI_HIERARCHY_WEEK:
100 			switch (nLevel)
101 			{
102 				//!	use settings for different definitions
103 				case 0:	nRet = aDate.GetYear();					break;		//!...
104 				case 1:	nRet = aDate.GetWeekOfYear();			break;
105 				case 2:	nRet = (long)aDate.GetDayOfWeek();		break;
106 				default:
107 					DBG_ERROR("GetDatePart: wrong level");
108 			}
109 			break;
110 		default:
111 			DBG_ERROR("GetDatePart: wrong hierarchy");
112 	}
113 
114 	nLastDateVal = nDateVal;
115 	nLastHier	 = nHierarchy;
116 	nLastLevel	 = nLevel;
117 	nLastRet	 = nRet;
118 
119 	return nRet;
120 }
121 
122 bool ScDPTableData::IsRepeatIfEmpty()
123 {
124     return false;
125 }
126 
127 sal_uLong ScDPTableData::GetNumberFormat(long)
128 {
129 	return 0;			// default format
130 }
131 
132 sal_Bool ScDPTableData::IsBaseForGroup(long) const
133 {
134     return sal_False;       // always false
135 }
136 
137 long ScDPTableData::GetGroupBase(long) const
138 {
139     return -1;          // always none
140 }
141 
142 sal_Bool ScDPTableData::IsNumOrDateGroup(long) const
143 {
144     return sal_False;       // always false
145 }
146 
147 sal_Bool ScDPTableData::IsInGroup( const ScDPItemData&, long,
148                                const ScDPItemData&, long ) const
149 {
150     DBG_ERROR("IsInGroup shouldn't be called for non-group data");
151     return sal_False;
152 }
153 
154 sal_Bool ScDPTableData::HasCommonElement( const ScDPItemData&, long,
155                                       const ScDPItemData&, long ) const
156 {
157     DBG_ERROR("HasCommonElement shouldn't be called for non-group data");
158     return sal_False;
159 }
160 void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTable& rCacheTable,
161                                         const CalcInfo& rInfo, CalcRowData& rData)
162 {
163     // column dimensions
164     GetItemData(rCacheTable, nRow, rInfo.aColLevelDims, rData.aColData);
165 
166     // row dimensions
167     GetItemData(rCacheTable, nRow, rInfo.aRowLevelDims, rData.aRowData);
168 
169     // page dimensions
170     GetItemData(rCacheTable, nRow, rInfo.aPageDims, rData.aPageData);
171 
172     long nCacheColumnCount = rCacheTable.GetCache()->GetColumnCount();
173     sal_Int32 n = rInfo.aDataSrcCols.size();
174     for (sal_Int32 i = 0; i < n; ++i)
175     {
176         long nDim = rInfo.aDataSrcCols[i];
177         rData.aValues.push_back( ScDPValueData() );
178         // #i111435# GetItemData needs dimension indexes including groups,
179         // so the index must be checked here (groups aren't useful as data fields).
180         if ( nDim < nCacheColumnCount )
181         {
182             ScDPValueData& rVal = rData.aValues.back();
183             rCacheTable.getValue( rVal, static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false);
184         }
185     }
186 }
187 
188 void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAutoShow)
189 {
190         // Wang Xu Ming -- 2009-6-16
191         // DataPilot Migration
192     if (!bAutoShow)
193     {
194 	        LateInitParams  aColParams( rInfo.aColDims, rInfo.aColLevels, sal_False );
195 	        LateInitParams  aRowParams ( rInfo.aRowDims, rInfo.aRowLevels, sal_True );
196             // root always init child
197             aColParams.SetInitChild( sal_True );
198             aColParams.SetInitAllChildren( sal_False);
199             aRowParams.SetInitChild( sal_True );
200             aRowParams.SetInitAllChildren( sal_False);
201 
202             rInfo.pColRoot->LateInitFrom( aColParams, rData.aColData,0, *rInfo.pInitState);
203             rInfo.pRowRoot->LateInitFrom( aRowParams, rData.aRowData, 0, *rInfo.pInitState);
204     }
205         // End Comments
206 
207     if ( ( !rInfo.pColRoot->GetChildDimension() || rInfo.pColRoot->GetChildDimension()->IsValidEntry(rData.aColData) ) &&
208          ( !rInfo.pRowRoot->GetChildDimension() || rInfo.pRowRoot->GetChildDimension()->IsValidEntry(rData.aRowData) ) )
209     {
210         //! single process method with ColMembers, RowMembers and data !!!
211         if (rInfo.pColRoot->GetChildDimension())
212         {
213 // Wang Xu Ming -- 2009-6-10
214 // DataPilot Migration
215             vector</*ScDPItemData*/ SCROW > aEmptyData;
216             rInfo.pColRoot->GetChildDimension()->ProcessData(rData.aColData, NULL, aEmptyData, rData.aValues);
217 // End Comments
218         }
219 
220         rInfo.pRowRoot->ProcessData(rData.aRowData, rInfo.pColRoot->GetChildDimension(),
221                                     rData.aColData, rData.aValues);
222     }
223 }
224 
225 void ScDPTableData::CalcResultsFromCacheTable(const ScDPCacheTable& rCacheTable, CalcInfo& rInfo, bool bAutoShow)
226 {
227     sal_Int32 nRowSize = rCacheTable.getRowSize();
228     for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
229     {
230         if (!rCacheTable.isRowActive(nRow))
231             continue;
232 
233         CalcRowData aData;
234         FillRowDataFromCacheTable(nRow, rCacheTable, rInfo, aData);
235         ProcessRowData(rInfo, aData, bAutoShow);
236     }
237 }
238 
239 // Wang Xu Ming -- 2009-6-10
240 // DataPilot Migration
241 void ScDPTableData::GetItemData(const ScDPCacheTable& rCacheTable, sal_Int32 nRow,
242                                 const vector<long>& rDims, vector< SCROW/*ScDPItemData*/>& rItemData)
243 // End Comments
244 {
245     sal_Int32 nDimSize = rDims.size();
246     for (sal_Int32 i = 0; i < nDimSize; ++i)
247     {
248         long nDim = rDims[i];
249 
250 		if (getIsDataLayoutDimension(nDim))
251 		{
252 			rItemData.push_back( -1 );
253 			continue;
254 		}
255 
256 		nDim = GetSourceDim( nDim );
257 		if ( nDim >= rCacheTable.GetCache()->GetColumnCount() )
258 		   continue;
259 
260         SCROW nId= rCacheTable.GetCache()->GetItemDataId( static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty());
261         rItemData.push_back( nId );
262 
263     }
264 }
265 
266 // -----------------------------------------------------------------------
267 
268 // Wang Xu Ming -- 2009-6-8
269 // DataPilot Migration
270 long ScDPTableData::GetMembersCount( long nDim )
271 {
272 	if ( nDim > MAXCOL )
273 		return 0;
274 	return GetCacheTable().getFieldEntries( nDim ).size();
275 }
276 
277 long ScDPTableData::GetCacheId() const
278 {
279 	return mnCacheId;
280 }
281 
282 const ScDPItemData* ScDPTableData::GetMemberByIndex( long nDim, long nIndex )
283 {
284 	if ( nIndex >= GetMembersCount( nDim ) )
285 		return NULL;
286 
287 	const ::std::vector<SCROW>& nMembers = GetCacheTable().getFieldEntries( nDim );
288 
289 	return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nMembers[nIndex] );
290 }
291 
292 const ScDPItemData* ScDPTableData::GetMemberById( long nDim, long nId)
293 {
294 
295 	return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nId);
296 }
297 
298 SCROW 	ScDPTableData::GetIdOfItemData( long  nDim, const ScDPItemData& rData )
299 {
300         return GetCacheTable().GetCache()->GetIdByItemData((SCCOL) nDim, rData );
301  }
302 
303 const std::vector< SCROW >& ScDPTableData::GetColumnEntries( long nColumn )
304 {
305     return GetCacheTable().getFieldEntries( nColumn );
306 }
307 
308 long ScDPTableData::GetSourceDim( long nDim )
309 {
310 	return nDim;
311 
312 }
313 
314  long ScDPTableData::Compare( long nDim, long nDataId1, long nDataId2)
315 {
316 	if ( getIsDataLayoutDimension(nDim) )
317 		return 0;
318 
319 	long n1 = GetCacheTable().GetCache()->GetOrder( nDim, nDataId1);
320 	long n2 = GetCacheTable().GetCache()->GetOrder( nDim, nDataId2);
321 	if ( n1 > n2 )
322 		return 1;
323 	else if ( n1 == n2 )
324 		return 0;
325 	else
326 		return -1;
327 }
328 // End Comments
329 // -----------------------------------------------------------------------
330