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 53 ScDPTableData::CalcInfo::CalcInfo() : 54 bRepeatIfEmpty(false) 55 { 56 } 57 58 // --------------------------------------------------------------------------- 59 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 69 ScDPTableData::~ScDPTableData() 70 { 71 } 72 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 118 bool ScDPTableData::IsRepeatIfEmpty() 119 { 120 return false; 121 } 122 123 sal_uLong ScDPTableData::GetNumberFormat(long) 124 { 125 return 0; // default format 126 } 127 128 sal_Bool ScDPTableData::IsBaseForGroup(long) const 129 { 130 return sal_False; // always false 131 } 132 133 long ScDPTableData::GetGroupBase(long) const 134 { 135 return -1; // always none 136 } 137 138 sal_Bool ScDPTableData::IsNumOrDateGroup(long) const 139 { 140 return sal_False; // always false 141 } 142 143 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 150 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 } 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 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 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 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 266 long ScDPTableData::GetMembersCount( long nDim ) 267 { 268 if ( nDim > MAXCOL ) 269 return 0; 270 return GetCacheTable().getFieldEntries( nDim ).size(); 271 } 272 273 long ScDPTableData::GetCacheId() const 274 { 275 return mnCacheId; 276 } 277 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 288 const ScDPItemData* ScDPTableData::GetMemberById( long nDim, long nId) 289 { 290 291 return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nId); 292 } 293 294 SCROW ScDPTableData::GetIdOfItemData( long nDim, const ScDPItemData& rData ) 295 { 296 return GetCacheTable().GetCache()->GetIdByItemData((SCCOL) nDim, rData ); 297 } 298 299 const std::vector< SCROW >& ScDPTableData::GetColumnEntries( long nColumn ) 300 { 301 return GetCacheTable().getFieldEntries( nColumn ); 302 } 303 304 long ScDPTableData::GetSourceDim( long nDim ) 305 { 306 return nDim; 307 308 } 309 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