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