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