1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "dptabdat.hxx"
23 #include "dpfilteredcache.hxx"
24 #include "dptabres.hxx"
25 #include "document.hxx"
26 #include "dpobject.hxx"
29 #include <rtl/math.hxx>
30 #include <osl/diagnose.h>
31 #include <tools/date.hxx>
32 #include <unotools/transliterationwrapper.hxx>
33 #include <unotools/collatorwrapper.hxx>
35 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
37 using namespace ::com::sun::star
;
38 using ::com::sun::star::uno::Sequence
;
39 using ::com::sun::star::uno::Any
;
42 ScDPTableData::CalcInfo::CalcInfo() :
50 ScDPTableData::ScDPTableData(ScDocument
* pDoc
) :
53 nLastDateVal
= nLastHier
= nLastLevel
= nLastRet
= -1; // invalid
55 //TODO: reset before new calculation (in case the base date is changed)
58 ScDPTableData::~ScDPTableData()
62 OUString
ScDPTableData::GetFormattedString(long nDim
, const ScDPItemData
& rItem
) const
64 const ScDPCache
& rCache
= GetCacheTable().getCache();
65 return rCache
.GetFormattedString(nDim
, rItem
);
68 long ScDPTableData::GetDatePart( long nDateVal
, long nHierarchy
, long nLevel
)
70 if ( nDateVal
== nLastDateVal
&& nHierarchy
== nLastHier
&& nLevel
== nLastLevel
)
73 Date
aDate( 30,12,1899 ); //TODO: get from source data (and cache here)
79 case SC_DAPI_HIERARCHY_QUARTER
:
82 case 0: nRet
= aDate
.GetYear(); break;
83 case 1: nRet
= (aDate
.GetMonth()-1) / 3 + 1; break;
84 case 2: nRet
= aDate
.GetMonth(); break;
85 case 3: nRet
= aDate
.GetDay(); break;
87 OSL_FAIL("GetDatePart: wrong level");
90 case SC_DAPI_HIERARCHY_WEEK
:
93 //TODO: use settings for different definitions
94 case 0: nRet
= aDate
.GetYear(); break; //!...
95 case 1: nRet
= aDate
.GetWeekOfYear(); break;
96 case 2: nRet
= (long)aDate
.GetDayOfWeek(); break;
98 OSL_FAIL("GetDatePart: wrong level");
102 OSL_FAIL("GetDatePart: wrong hierarchy");
105 nLastDateVal
= nDateVal
;
106 nLastHier
= nHierarchy
;
113 bool ScDPTableData::IsRepeatIfEmpty()
118 sal_uLong
ScDPTableData::GetNumberFormat(long)
120 return 0; // default format
123 bool ScDPTableData::IsBaseForGroup(long) const
125 return false; // always false
128 long ScDPTableData::GetGroupBase(long) const
130 return -1; // always none
133 bool ScDPTableData::IsNumOrDateGroup(long) const
135 return false; // always false
138 bool ScDPTableData::IsInGroup( const ScDPItemData
&, long,
139 const ScDPItemData
&, long ) const
141 OSL_FAIL("IsInGroup shouldn't be called for non-group data");
145 bool ScDPTableData::HasCommonElement( const ScDPItemData
&, long,
146 const ScDPItemData
&, long ) const
148 OSL_FAIL("HasCommonElement shouldn't be called for non-group data");
151 void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow
, const ScDPFilteredCache
& rCacheTable
,
152 const CalcInfo
& rInfo
, CalcRowData
& rData
)
155 GetItemData(rCacheTable
, nRow
, rInfo
.aColLevelDims
, rData
.aColData
);
158 GetItemData(rCacheTable
, nRow
, rInfo
.aRowLevelDims
, rData
.aRowData
);
161 GetItemData(rCacheTable
, nRow
, rInfo
.aPageDims
, rData
.aPageData
);
163 long nCacheColumnCount
= rCacheTable
.getCache().GetColumnCount();
164 sal_Int32 n
= rInfo
.aDataSrcCols
.size();
165 for (sal_Int32 i
= 0; i
< n
; ++i
)
167 long nDim
= rInfo
.aDataSrcCols
[i
];
168 rData
.aValues
.push_back( ScDPValue() );
169 // #i111435# GetItemData needs dimension indexes including groups,
170 // so the index must be checked here (groups aren't useful as data fields).
171 if ( nDim
< nCacheColumnCount
)
173 ScDPValue
& rVal
= rData
.aValues
.back();
174 rCacheTable
.getValue( rVal
, static_cast<SCCOL
>(nDim
), static_cast<SCROW
>(nRow
), false);
179 void ScDPTableData::ProcessRowData(CalcInfo
& rInfo
, const CalcRowData
& rData
, bool bAutoShow
)
183 LateInitParams
aColParams(rInfo
.aColDims
, rInfo
.aColLevels
, false);
184 LateInitParams
aRowParams(rInfo
.aRowDims
, rInfo
.aRowLevels
, true);
185 // root always init child
186 aColParams
.SetInitChild(true);
187 aColParams
.SetInitAllChildren( false);
188 aRowParams
.SetInitChild(true);
189 aRowParams
.SetInitAllChildren( false);
191 rInfo
.pColRoot
->LateInitFrom(aColParams
, rData
.aColData
, 0, *rInfo
.pInitState
);
192 rInfo
.pRowRoot
->LateInitFrom(aRowParams
, rData
.aRowData
, 0, *rInfo
.pInitState
);
195 if ( ( !rInfo
.pColRoot
->GetChildDimension() || rInfo
.pColRoot
->GetChildDimension()->IsValidEntry(rData
.aColData
) ) &&
196 ( !rInfo
.pRowRoot
->GetChildDimension() || rInfo
.pRowRoot
->GetChildDimension()->IsValidEntry(rData
.aRowData
) ) )
198 //TODO: single process method with ColMembers, RowMembers and data !!!
199 if (rInfo
.pColRoot
->GetChildDimension())
201 vector
<SCROW
> aEmptyData
;
202 rInfo
.pColRoot
->GetChildDimension()->ProcessData(rData
.aColData
, NULL
, aEmptyData
, rData
.aValues
);
205 rInfo
.pRowRoot
->ProcessData(rData
.aRowData
, rInfo
.pColRoot
->GetChildDimension(),
206 rData
.aColData
, rData
.aValues
);
210 void ScDPTableData::CalcResultsFromCacheTable(const ScDPFilteredCache
& rCacheTable
, CalcInfo
& rInfo
, bool bAutoShow
)
212 sal_Int32 nRowSize
= rCacheTable
.getRowSize();
213 for (sal_Int32 nRow
= 0; nRow
< nRowSize
; ++nRow
)
216 if (!rCacheTable
.isRowActive(nRow
, &nLastRow
))
223 FillRowDataFromCacheTable(nRow
, rCacheTable
, rInfo
, aData
);
224 ProcessRowData(rInfo
, aData
, bAutoShow
);
228 void ScDPTableData::GetItemData(const ScDPFilteredCache
& rCacheTable
, sal_Int32 nRow
,
229 const vector
<long>& rDims
, vector
<SCROW
>& rItemData
)
231 sal_Int32 nDimSize
= rDims
.size();
232 for (sal_Int32 i
= 0; i
< nDimSize
; ++i
)
234 long nDim
= rDims
[i
];
236 if (getIsDataLayoutDimension(nDim
))
238 rItemData
.push_back( -1 );
242 nDim
= GetSourceDim( nDim
);
243 if ( nDim
>= rCacheTable
.getCache().GetColumnCount() )
246 SCROW nId
= rCacheTable
.getCache().GetItemDataId( static_cast<SCCOL
>(nDim
), static_cast<SCROW
>(nRow
), IsRepeatIfEmpty());
247 rItemData
.push_back( nId
);
251 long ScDPTableData::GetMembersCount( long nDim
)
255 return GetCacheTable().getFieldEntries( nDim
).size();
258 const ScDPItemData
* ScDPTableData::GetMemberByIndex( long nDim
, long nIndex
)
260 if ( nIndex
>= GetMembersCount( nDim
) )
263 const ::std::vector
<SCROW
>& nMembers
= GetCacheTable().getFieldEntries( nDim
);
265 return GetCacheTable().getCache().GetItemDataById( (SCCOL
) nDim
, (SCROW
)nMembers
[nIndex
] );
268 const ScDPItemData
* ScDPTableData::GetMemberById( long nDim
, long nId
)
270 return GetCacheTable().getCache().GetItemDataById(nDim
, static_cast<SCROW
>(nId
));
273 const std::vector
< SCROW
>& ScDPTableData::GetColumnEntries( long nColumn
)
275 return GetCacheTable().getFieldEntries( nColumn
);
278 long ScDPTableData::GetSourceDim( long nDim
)
284 long ScDPTableData::Compare( long nDim
, long nDataId1
, long nDataId2
)
286 if ( getIsDataLayoutDimension(nDim
) )
289 long n1
= ScDPFilteredCache::getOrder(nDim
, nDataId1
);
290 long n2
= ScDPFilteredCache::getOrder(nDim
, nDataId2
);
299 #if DEBUG_PIVOT_TABLE
300 void ScDPTableData::Dump() const
305 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */