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>
21 #include <dpcache.hxx>
22 #include <dpfilteredcache.hxx>
23 #include <dptabres.hxx>
25 #include <osl/diagnose.h>
26 #include <tools/date.hxx>
29 using namespace ::com::sun::star
;
32 ScDPTableData::CalcInfo::CalcInfo() :
33 pInitState( nullptr ),
39 ScDPTableData::ScDPTableData(const ScDocument
* pDoc
) :
42 nLastDateVal
= nLastHier
= nLastLevel
= nLastRet
= -1; // invalid
44 //TODO: reset before new calculation (in case the base date is changed)
47 ScDPTableData::~ScDPTableData()
51 OUString
ScDPTableData::GetFormattedString(sal_Int32 nDim
, const ScDPItemData
& rItem
, bool bLocaleIndependent
) const
53 const ScDPCache
& rCache
= GetCacheTable().getCache();
54 return rCache
.GetFormattedString(nDim
, rItem
, bLocaleIndependent
);
57 tools::Long
ScDPTableData::GetDatePart( tools::Long nDateVal
, tools::Long nHierarchy
, tools::Long nLevel
)
59 if ( nDateVal
== nLastDateVal
&& nHierarchy
== nLastHier
&& nLevel
== nLastLevel
)
62 Date
aDate( 30,12,1899 ); //TODO: get from source data (and cache here)
63 aDate
.AddDays( nDateVal
);
68 case SC_DAPI_HIERARCHY_QUARTER
:
71 case 0: nRet
= aDate
.GetYear(); break;
72 case 1: nRet
= (aDate
.GetMonth()-1) / 3 + 1; break;
73 case 2: nRet
= aDate
.GetMonth(); break;
74 case 3: nRet
= aDate
.GetDay(); break;
76 OSL_FAIL("GetDatePart: wrong level");
79 case SC_DAPI_HIERARCHY_WEEK
:
82 //TODO: use settings for different definitions
83 case 0: nRet
= aDate
.GetYear(); break; //!...
84 case 1: nRet
= aDate
.GetWeekOfYear(); break;
85 case 2: nRet
= static_cast<tools::Long
>(aDate
.GetDayOfWeek()); break;
87 OSL_FAIL("GetDatePart: wrong level");
91 OSL_FAIL("GetDatePart: wrong hierarchy");
94 nLastDateVal
= nDateVal
;
95 nLastHier
= nHierarchy
;
102 bool ScDPTableData::IsRepeatIfEmpty()
107 sal_uInt32
ScDPTableData::GetNumberFormat(sal_Int32
)
109 return 0; // default format
112 bool ScDPTableData::IsBaseForGroup(sal_Int32
) const
114 return false; // always false
117 sal_Int32
ScDPTableData::GetGroupBase(sal_Int32
) const
119 return -1; // always none
122 bool ScDPTableData::IsNumOrDateGroup(sal_Int32
) const
124 return false; // always false
127 bool ScDPTableData::IsInGroup( const ScDPItemData
&, sal_Int32
,
128 const ScDPItemData
&, sal_Int32
) const
130 OSL_FAIL("IsInGroup shouldn't be called for non-group data");
134 bool ScDPTableData::HasCommonElement( const ScDPItemData
&, sal_Int32
,
135 const ScDPItemData
&, sal_Int32
) const
137 OSL_FAIL("HasCommonElement shouldn't be called for non-group data");
140 void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow
, const ScDPFilteredCache
& rCacheTable
,
141 const CalcInfo
& rInfo
, CalcRowData
& rData
)
144 GetItemData(rCacheTable
, nRow
, rInfo
.aColLevelDims
, rData
.aColData
);
147 GetItemData(rCacheTable
, nRow
, rInfo
.aRowLevelDims
, rData
.aRowData
);
150 GetItemData(rCacheTable
, nRow
, rInfo
.aPageDims
, rData
.aPageData
);
152 tools::Long nCacheColumnCount
= rCacheTable
.getCache().GetColumnCount();
153 sal_Int32 n
= rInfo
.aDataSrcCols
.size();
154 for (sal_Int32 i
= 0; i
< n
; ++i
)
156 tools::Long nDim
= rInfo
.aDataSrcCols
[i
];
157 rData
.aValues
.emplace_back( );
158 // #i111435# GetItemData needs dimension indexes including groups,
159 // so the index must be checked here (groups aren't useful as data fields).
160 if ( nDim
< nCacheColumnCount
)
162 ScDPValue
& rVal
= rData
.aValues
.back();
163 rCacheTable
.getValue( rVal
, static_cast<SCCOL
>(nDim
), static_cast<SCROW
>(nRow
));
168 void ScDPTableData::ProcessRowData(CalcInfo
& rInfo
, const CalcRowData
& rData
, bool bAutoShow
)
172 LateInitParams
aColParams(rInfo
.aColDims
, rInfo
.aColLevels
, false);
173 LateInitParams
aRowParams(rInfo
.aRowDims
, rInfo
.aRowLevels
, true);
174 // root always init child
175 aColParams
.SetInitChild(true);
176 aColParams
.SetInitAllChildren( false);
177 aRowParams
.SetInitChild(true);
178 aRowParams
.SetInitAllChildren( false);
180 rInfo
.pColRoot
->LateInitFrom(aColParams
, rData
.aColData
, 0, *rInfo
.pInitState
);
181 rInfo
.pRowRoot
->LateInitFrom(aRowParams
, rData
.aRowData
, 0, *rInfo
.pInitState
);
184 if ( ( !rInfo
.pColRoot
->GetChildDimension() || rInfo
.pColRoot
->GetChildDimension()->IsValidEntry(rData
.aColData
) ) &&
185 ( !rInfo
.pRowRoot
->GetChildDimension() || rInfo
.pRowRoot
->GetChildDimension()->IsValidEntry(rData
.aRowData
) ) )
187 //TODO: single process method with ColMembers, RowMembers and data !!!
188 if (rInfo
.pColRoot
->GetChildDimension())
190 vector
<SCROW
> aEmptyData
;
191 rInfo
.pColRoot
->GetChildDimension()->ProcessData(rData
.aColData
, nullptr, aEmptyData
, rData
.aValues
);
194 rInfo
.pRowRoot
->ProcessData(rData
.aRowData
, rInfo
.pColRoot
->GetChildDimension(),
195 rData
.aColData
, rData
.aValues
);
199 void ScDPTableData::CalcResultsFromCacheTable(const ScDPFilteredCache
& rCacheTable
, CalcInfo
& rInfo
, bool bAutoShow
)
201 sal_Int32 nRowSize
= rCacheTable
.getRowSize();
202 for (sal_Int32 nRow
= 0; nRow
< nRowSize
; ++nRow
)
205 if (!rCacheTable
.isRowActive(nRow
, &nLastRow
))
212 FillRowDataFromCacheTable(nRow
, rCacheTable
, rInfo
, aData
);
213 ProcessRowData(rInfo
, aData
, bAutoShow
);
217 void ScDPTableData::GetItemData(const ScDPFilteredCache
& rCacheTable
, sal_Int32 nRow
,
218 const vector
<sal_Int32
>& rDims
, vector
<SCROW
>& rItemData
)
220 sal_Int32 nDimSize
= rDims
.size();
221 rItemData
.reserve(rItemData
.size() + nDimSize
);
222 for (sal_Int32 i
= 0; i
< nDimSize
; ++i
)
224 sal_Int32 nDim
= rDims
[i
];
226 if (getIsDataLayoutDimension(nDim
))
228 rItemData
.push_back( -1 );
232 nDim
= GetSourceDim( nDim
);
233 if ( nDim
>= rCacheTable
.getCache().GetColumnCount() )
236 SCROW nId
= rCacheTable
.getCache().GetItemDataId( static_cast<SCCOL
>(nDim
), static_cast<SCROW
>(nRow
), IsRepeatIfEmpty());
237 rItemData
.push_back( nId
);
241 sal_Int32
ScDPTableData::GetMembersCount( sal_Int32 nDim
)
245 return GetCacheTable().getFieldEntries( nDim
).size();
248 const ScDPItemData
* ScDPTableData::GetMemberByIndex( sal_Int32 nDim
, sal_Int32 nIndex
)
250 if ( nIndex
>= GetMembersCount( nDim
) )
253 const ::std::vector
<SCROW
>& nMembers
= GetCacheTable().getFieldEntries( nDim
);
255 return GetCacheTable().getCache().GetItemDataById( static_cast<SCCOL
>(nDim
), static_cast<SCROW
>(nMembers
[nIndex
]) );
258 const ScDPItemData
* ScDPTableData::GetMemberById( sal_Int32 nDim
, sal_Int32 nId
)
260 return GetCacheTable().getCache().GetItemDataById(nDim
, static_cast<SCROW
>(nId
));
263 const std::vector
< SCROW
>& ScDPTableData::GetColumnEntries( sal_Int32 nColumn
)
265 return GetCacheTable().getFieldEntries( nColumn
);
268 sal_Int32
ScDPTableData::GetSourceDim( sal_Int32 nDim
)
273 sal_Int32
ScDPTableData::Compare( sal_Int32 nDim
, sal_Int32 nDataId1
, sal_Int32 nDataId2
)
275 if ( getIsDataLayoutDimension(nDim
) )
278 if ( nDataId1
> nDataId2
)
280 else if ( nDataId1
== nDataId2
)
287 void ScDPTableData::Dump() const
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */