Update ooo320-m1
[ooovba.git] / sc / source / core / data / dpshttab.cxx
blob8ecf19a972b132130b6e5c629021f0f00213a6e0
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: dpshttab.cxx,v $
10 * $Revision: 1.12 $
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 <tools/debug.hxx>
39 #include <svtools/zforlist.hxx>
41 #include "dpshttab.hxx"
42 #include "dptabres.hxx"
43 #include "document.hxx"
44 #include "collect.hxx"
45 #include "cell.hxx"
46 #include "dpcachetable.hxx"
47 #include "dpobject.hxx"
48 #include "globstr.hrc"
50 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
52 #include <vector>
53 #include <set>
55 using namespace ::com::sun::star;
56 using ::com::sun::star::uno::Any;
57 using ::com::sun::star::uno::Sequence;
58 using ::std::vector;
59 using ::std::hash_map;
60 using ::std::hash_set;
62 // -----------------------------------------------------------------------
64 class ScSheetDPData_Impl
66 public:
67 ScDocument* pDoc;
68 ScRange aRange;
69 ScQueryParam aQuery;
70 BOOL* pSpecial; // to flag special handling of query parameters in ValidQuery.
71 BOOL bIgnoreEmptyRows;
72 BOOL bRepeatIfEmpty;
73 BOOL* pDateDim;
74 SCROW nNextRow; // for iterator, within range
76 ScDPCacheTable aCacheTable;
78 ScSheetDPData_Impl(ScDPCollection* p) :
79 pSpecial(NULL),
80 aCacheTable(p)
85 // -----------------------------------------------------------------------
87 ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ) :
88 ScDPTableData(pD)
90 pImpl = new ScSheetDPData_Impl(pD->GetDPCollection());
91 pImpl->pDoc = pD;
92 pImpl->aRange = rDesc.aSourceRange;
93 pImpl->aQuery = rDesc.aQueryParam;
94 pImpl->bIgnoreEmptyRows = FALSE;
95 pImpl->bRepeatIfEmpty = FALSE;
96 pImpl->pDateDim = NULL;
98 pImpl->nNextRow = pImpl->aRange.aStart.Row() + 1;
100 SCSIZE nEntryCount(pImpl->aQuery.GetEntryCount());
101 pImpl->pSpecial = new BOOL[nEntryCount];
102 for (SCSIZE j = 0; j < nEntryCount; ++j )
104 ScQueryEntry& rEntry = pImpl->aQuery.GetEntry(j);
105 if (rEntry.bDoQuery)
107 pImpl->pSpecial[j] = false;
108 if (!rEntry.bQueryByString)
110 if (*rEntry.pStr == EMPTY_STRING &&
111 ((rEntry.nVal == SC_EMPTYFIELDS) || (rEntry.nVal == SC_NONEMPTYFIELDS)))
112 pImpl->pSpecial[j] = true;
114 else
116 sal_uInt32 nIndex = 0;
117 rEntry.bQueryByString =
118 !(pD->GetFormatTable()->
119 IsNumberFormat(*rEntry.pStr, nIndex, rEntry.nVal));
125 ScSheetDPData::~ScSheetDPData()
127 delete[] pImpl->pDateDim;
128 delete[] pImpl->pSpecial;
129 delete pImpl;
132 void ScSheetDPData::DisposeData()
134 pImpl->aCacheTable.clear();
137 long ScSheetDPData::GetColumnCount()
139 CreateCacheTable();
140 return pImpl->aCacheTable.getColSize();
143 const TypedScStrCollection& ScSheetDPData::GetColumnEntries(long nColumn)
145 DBG_ASSERT(nColumn>=0 && nColumn < pImpl->aCacheTable.getColSize(), "ScSheetDPData: wrong column");
146 CreateCacheTable();
147 return pImpl->aCacheTable.getFieldEntries(nColumn);
150 String ScSheetDPData::getDimensionName(long nColumn)
152 CreateCacheTable();
153 if (getIsDataLayoutDimension(nColumn))
155 //! different internal and display names?
156 //return "Data";
157 return ScGlobal::GetRscString(STR_PIVOT_DATA);
159 else if (nColumn >= pImpl->aCacheTable.getColSize())
161 DBG_ERROR("getDimensionName: invalid dimension");
162 return String();
164 else
166 const String* pStr = pImpl->aCacheTable.getFieldName(nColumn);
167 if (pStr)
168 return *pStr;
169 else return String();
173 BOOL lcl_HasDateFormat( ScDocument* pDoc, const ScRange& rRange )
175 //! iterate formats in range?
177 ScAddress aPos = rRange.aStart;
178 aPos.SetRow( aPos.Row() + 1 ); // below title
179 ULONG nFormat = pDoc->GetNumberFormat( aPos );
180 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
181 return ( pFormatter->GetType(nFormat) & NUMBERFORMAT_DATE ) != 0;
184 BOOL ScSheetDPData::IsDateDimension(long nDim)
186 CreateCacheTable();
187 long nColCount = pImpl->aCacheTable.getColSize();
188 if (getIsDataLayoutDimension(nDim))
190 return FALSE;
192 else if (nDim >= nColCount)
194 DBG_ERROR("IsDateDimension: invalid dimension");
195 return FALSE;
197 else
199 if (!pImpl->pDateDim)
201 pImpl->pDateDim = new BOOL[nColCount];
202 ScRange aTestRange = pImpl->aRange;
203 for (long i = 0; i < nColCount; ++i)
205 SCCOL nCol = (SCCOL)( pImpl->aRange.aStart.Col() + i );
206 aTestRange.aStart.SetCol(nCol);
207 aTestRange.aEnd.SetCol(nCol);
208 pImpl->pDateDim[i] = lcl_HasDateFormat( pImpl->pDoc, aTestRange );
211 return pImpl->pDateDim[nDim];
215 UINT32 ScSheetDPData::GetNumberFormat(long nDim)
217 CreateCacheTable();
218 if (getIsDataLayoutDimension(nDim))
220 return 0;
222 else if (nDim >= pImpl->aCacheTable.getColSize())
224 DBG_ERROR("GetNumberFormat: invalid dimension");
225 return 0;
227 else
229 // is queried only once per dimension from ScDPOutput -> no need to cache
231 ScAddress aPos = pImpl->aRange.aStart;
232 aPos.SetCol( sal::static_int_cast<SCCOL>( aPos.Col() + nDim ) );
233 aPos.SetRow( aPos.Row() + 1 ); // below title
234 return pImpl->pDoc->GetNumberFormat( aPos );
238 BOOL ScSheetDPData::getIsDataLayoutDimension(long nColumn)
240 CreateCacheTable();
241 return (nColumn == pImpl->aCacheTable.getColSize());
244 void ScSheetDPData::SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty )
246 pImpl->bIgnoreEmptyRows = bIgnoreEmptyRows;
247 pImpl->bRepeatIfEmpty = bRepeatIfEmpty;
250 bool ScSheetDPData::IsRepeatIfEmpty()
252 return pImpl->bRepeatIfEmpty;
255 void ScSheetDPData::CreateCacheTable()
257 // Scan and store the data from the source range.
258 if (!pImpl->aCacheTable.empty())
259 // already cached.
260 return;
262 pImpl->aCacheTable.fillTable(pImpl->pDoc, pImpl->aRange, pImpl->aQuery, pImpl->pSpecial,
263 pImpl->bIgnoreEmptyRows);
266 void ScSheetDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims)
268 CreateCacheTable();
269 pImpl->aCacheTable.filterByPageDimension(
270 rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()));
273 void ScSheetDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData)
275 CreateCacheTable();
276 sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize();
277 if (!nRowSize)
278 return;
280 pImpl->aCacheTable.filterTable(
281 rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>());
284 void ScSheetDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
286 CreateCacheTable();
287 CalcResultsFromCacheTable(pImpl->aCacheTable, rInfo, bAutoShow);
290 const ScDPCacheTable& ScSheetDPData::GetCacheTable() const
292 return pImpl->aCacheTable;
295 // -----------------------------------------------------------------------