merge the formfield patch from ooo-build
[ooovba.git] / sc / source / core / data / dptabdat.cxx
blob42a8b13ed731aa14223a21aa56073b03714e8159
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dptabdat.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include <stdio.h>
39 #include <rtl/math.hxx>
40 #include <tools/debug.hxx>
41 #include <tools/date.hxx>
42 #include <unotools/transliterationwrapper.hxx>
43 #include <unotools/collatorwrapper.hxx>
45 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
47 #include "dptabdat.hxx"
48 #include "global.hxx"
49 #include "dpcachetable.hxx"
50 #include "dptabres.hxx"
51 #include "document.hxx"
52 #include "dpobject.hxx"
54 using namespace ::com::sun::star;
55 using ::com::sun::star::uno::Sequence;
56 using ::com::sun::star::uno::Any;
57 using ::std::vector;
58 using ::std::set;
59 using ::std::hash_map;
61 // -----------------------------------------------------------------------
63 BOOL ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const
65 //! pass Transliteration?
66 //! inline?
67 return bHasValue ? ( r.bHasValue && rtl::math::approxEqual( fValue, r.fValue ) ) :
68 ( !r.bHasValue &&
69 ScGlobal::GetpTransliteration()->isEqual( aString, r.aString ) );
72 size_t ScDPItemData::Hash() const
74 if ( bHasValue )
75 return (size_t) rtl::math::approxFloor( fValue );
76 else
77 // If we do unicode safe case insensitive hash we can drop
78 // ScDPItemData::operator== and use ::IsCasInsEqual
79 return rtl_ustr_hashCode_WithLength( aString.GetBuffer(), aString.Len() );
82 BOOL ScDPItemData::operator==( const ScDPItemData& r ) const
84 if ( bHasValue )
86 if ( r.bHasValue )
87 return rtl::math::approxEqual( fValue, r.fValue );
88 else
89 return FALSE;
91 else if ( r.bHasValue )
92 return FALSE;
93 else
94 // need exact equality until we have a safe case insensitive string hash
95 return aString == r.aString;
98 sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA,
99 const ScDPItemData& rB )
101 if ( rA.bHasValue )
103 if ( rB.bHasValue )
105 if ( rtl::math::approxEqual( rA.fValue, rB.fValue ) )
106 return 0;
107 else if ( rA.fValue < rB.fValue )
108 return -1;
109 else
110 return 1;
112 else
113 return -1; // values first
115 else if ( rB.bHasValue )
116 return 1; // values first
117 else
118 return ScGlobal::GetCollator()->compareString( rA.aString, rB.aString );
121 // ---------------------------------------------------------------------------
123 ScDPTableData::CalcInfo::CalcInfo() :
124 bRepeatIfEmpty(false)
128 // ---------------------------------------------------------------------------
130 ScDPTableData::ScDPTableData(ScDocument* pDoc) :
131 mrSharedString(pDoc->GetDPCollection()->GetSharedString())
133 nLastDateVal = nLastHier = nLastLevel = nLastRet = -1; // invalid
135 //! reset before new calculation (in case the base date is changed)
138 ScDPTableData::~ScDPTableData()
142 long ScDPTableData::GetDatePart( long nDateVal, long nHierarchy, long nLevel )
144 if ( nDateVal == nLastDateVal && nHierarchy == nLastHier && nLevel == nLastLevel )
145 return nLastRet;
147 Date aDate( 30,12,1899 ); //! get from source data (and cache here)
148 aDate += nDateVal;
150 long nRet = 0;
151 switch (nHierarchy)
153 case SC_DAPI_HIERARCHY_QUARTER:
154 switch (nLevel)
156 case 0: nRet = aDate.GetYear(); break;
157 case 1: nRet = (aDate.GetMonth()-1) / 3 + 1; break;
158 case 2: nRet = aDate.GetMonth(); break;
159 case 3: nRet = aDate.GetDay(); break;
160 default:
161 DBG_ERROR("GetDatePart: wrong level");
163 break;
164 case SC_DAPI_HIERARCHY_WEEK:
165 switch (nLevel)
167 //! use settings for different definitions
168 case 0: nRet = aDate.GetYear(); break; //!...
169 case 1: nRet = aDate.GetWeekOfYear(); break;
170 case 2: nRet = (long)aDate.GetDayOfWeek(); break;
171 default:
172 DBG_ERROR("GetDatePart: wrong level");
174 break;
175 default:
176 DBG_ERROR("GetDatePart: wrong hierarchy");
179 nLastDateVal = nDateVal;
180 nLastHier = nHierarchy;
181 nLastLevel = nLevel;
182 nLastRet = nRet;
184 return nRet;
187 bool ScDPTableData::IsRepeatIfEmpty()
189 return false;
192 UINT32 ScDPTableData::GetNumberFormat(long)
194 return 0; // default format
197 BOOL ScDPTableData::IsBaseForGroup(long) const
199 return FALSE; // always false
202 long ScDPTableData::GetGroupBase(long) const
204 return -1; // always none
207 BOOL ScDPTableData::IsNumOrDateGroup(long) const
209 return FALSE; // always false
212 BOOL ScDPTableData::IsInGroup( const ScDPItemData&, long,
213 const ScDPItemData&, long ) const
215 DBG_ERROR("IsInGroup shouldn't be called for non-group data");
216 return FALSE;
219 BOOL ScDPTableData::HasCommonElement( const ScDPItemData&, long,
220 const ScDPItemData&, long ) const
222 DBG_ERROR("HasCommonElement shouldn't be called for non-group data");
223 return FALSE;
226 ScSimpleSharedString& ScDPTableData::GetSharedString()
228 return mrSharedString;
231 void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTable& rCacheTable,
232 const CalcInfo& rInfo, CalcRowData& rData)
234 // column dimensions
235 GetItemData(rCacheTable, nRow, rInfo.aColLevelDims, rData.aColData);
237 // row dimensions
238 GetItemData(rCacheTable, nRow, rInfo.aRowLevelDims, rData.aRowData);
240 // page dimensions
241 GetItemData(rCacheTable, nRow, rInfo.aPageDims, rData.aPageData);
243 sal_Int32 n = rInfo.aDataSrcCols.size();
244 for (sal_Int32 i = 0; i < n; ++i)
246 long nDim = rInfo.aDataSrcCols[i];
247 rData.aValues.push_back( ScDPValueData() );
248 ScDPValueData& rVal = rData.aValues.back();
249 const ScDPCacheCell* pCell = rCacheTable.getCell(
250 static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false);
251 if (pCell)
253 rVal.fValue = pCell->mbNumeric ? pCell->mfValue : 0.0;
254 rVal.nType = pCell->mnType;
256 else
257 rVal.Set(0.0, SC_VALTYPE_EMPTY);
261 void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAutoShow)
263 if (!bAutoShow)
265 rInfo.pColRoot->LateInitFrom(rInfo.aColDims, rInfo.aColLevels, rData.aColData, 0, *rInfo.pInitState);
266 rInfo.pRowRoot->LateInitFrom(rInfo.aRowDims, rInfo.aRowLevels, rData.aRowData, 0, *rInfo.pInitState);
269 if ( ( !rInfo.pColRoot->GetChildDimension() || rInfo.pColRoot->GetChildDimension()->IsValidEntry(rData.aColData) ) &&
270 ( !rInfo.pRowRoot->GetChildDimension() || rInfo.pRowRoot->GetChildDimension()->IsValidEntry(rData.aRowData) ) )
272 //! single process method with ColMembers, RowMembers and data !!!
273 if (rInfo.pColRoot->GetChildDimension())
275 vector<ScDPItemData> aEmptyData;
276 rInfo.pColRoot->GetChildDimension()->ProcessData(rData.aColData, NULL, aEmptyData, rData.aValues);
279 rInfo.pRowRoot->ProcessData(rData.aRowData, rInfo.pColRoot->GetChildDimension(),
280 rData.aColData, rData.aValues);
284 void ScDPTableData::CalcResultsFromCacheTable(const ScDPCacheTable& rCacheTable, CalcInfo& rInfo, bool bAutoShow)
286 sal_Int32 nRowSize = rCacheTable.getRowSize();
287 for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
289 if (!rCacheTable.isRowActive(nRow))
290 continue;
292 CalcRowData aData;
293 FillRowDataFromCacheTable(nRow, rCacheTable, rInfo, aData);
294 ProcessRowData(rInfo, aData, bAutoShow);
298 void ScDPTableData::GetItemData(const ScDPCacheTable& rCacheTable, sal_Int32 nRow,
299 const vector<long>& rDims, vector<ScDPItemData>& rItemData)
301 sal_Int32 nDimSize = rDims.size();
302 for (sal_Int32 i = 0; i < nDimSize; ++i)
304 long nDim = rDims[i];
305 rItemData.push_back( ScDPItemData() );
306 ScDPItemData& rData = rItemData.back();
307 if (getIsDataLayoutDimension(nDim))
309 rData.SetString(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("x")));
310 continue;
313 const ScDPCacheCell* pCell = rCacheTable.getCell(
314 static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty());
315 if (!pCell || pCell->mnType == SC_VALTYPE_EMPTY)
316 continue;
318 const String* pString = GetSharedString().getString(pCell->mnStrId);
319 if (!pString)
320 continue;
322 rData.aString = *pString;
323 rData.bHasValue = false;
324 if (pCell->mbNumeric)
326 rData.bHasValue = true;
327 rData.fValue = pCell->mfValue;
332 // -----------------------------------------------------------------------