1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dptabdat.cxx,v $
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 ---------------------------------------------------------------
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"
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
;
59 using ::std::hash_map
;
61 // -----------------------------------------------------------------------
63 BOOL
ScDPItemData::IsCaseInsEqual( const ScDPItemData
& r
) const
65 //! pass Transliteration?
67 return bHasValue
? ( r
.bHasValue
&& rtl::math::approxEqual( fValue
, r
.fValue
) ) :
69 ScGlobal::GetpTransliteration()->isEqual( aString
, r
.aString
) );
72 size_t ScDPItemData::Hash() const
75 return (size_t) rtl::math::approxFloor( fValue
);
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
87 return rtl::math::approxEqual( fValue
, r
.fValue
);
91 else if ( r
.bHasValue
)
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
)
105 if ( rtl::math::approxEqual( rA
.fValue
, rB
.fValue
) )
107 else if ( rA
.fValue
< rB
.fValue
)
113 return -1; // values first
115 else if ( rB
.bHasValue
)
116 return 1; // values first
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
)
147 Date
aDate( 30,12,1899 ); //! get from source data (and cache here)
153 case SC_DAPI_HIERARCHY_QUARTER
:
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;
161 DBG_ERROR("GetDatePart: wrong level");
164 case SC_DAPI_HIERARCHY_WEEK
:
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;
172 DBG_ERROR("GetDatePart: wrong level");
176 DBG_ERROR("GetDatePart: wrong hierarchy");
179 nLastDateVal
= nDateVal
;
180 nLastHier
= nHierarchy
;
187 bool ScDPTableData::IsRepeatIfEmpty()
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");
219 BOOL
ScDPTableData::HasCommonElement( const ScDPItemData
&, long,
220 const ScDPItemData
&, long ) const
222 DBG_ERROR("HasCommonElement shouldn't be called for non-group data");
226 ScSimpleSharedString
& ScDPTableData::GetSharedString()
228 return mrSharedString
;
231 void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow
, const ScDPCacheTable
& rCacheTable
,
232 const CalcInfo
& rInfo
, CalcRowData
& rData
)
235 GetItemData(rCacheTable
, nRow
, rInfo
.aColLevelDims
, rData
.aColData
);
238 GetItemData(rCacheTable
, nRow
, rInfo
.aRowLevelDims
, rData
.aRowData
);
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);
253 rVal
.fValue
= pCell
->mbNumeric
? pCell
->mfValue
: 0.0;
254 rVal
.nType
= pCell
->mnType
;
257 rVal
.Set(0.0, SC_VALTYPE_EMPTY
);
261 void ScDPTableData::ProcessRowData(CalcInfo
& rInfo
, CalcRowData
& rData
, bool 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
))
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")));
313 const ScDPCacheCell
* pCell
= rCacheTable
.getCell(
314 static_cast<SCCOL
>(nDim
), static_cast<SCROW
>(nRow
), IsRepeatIfEmpty());
315 if (!pCell
|| pCell
->mnType
== SC_VALTYPE_EMPTY
)
318 const String
* pString
= GetSharedString().getString(pCell
->mnStrId
);
322 rData
.aString
= *pString
;
323 rData
.bHasValue
= false;
324 if (pCell
->mbNumeric
)
326 rData
.bHasValue
= true;
327 rData
.fValue
= pCell
->mfValue
;
332 // -----------------------------------------------------------------------