xref: /trunk/main/sc/source/core/data/dptabdat.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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