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