update ooo310-m15
[ooovba.git] / sc / source / core / data / dpshttab.cxx
blob5f545cd69730ff7b8869690fad7b2b0e03e8afb9
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 BOOL lcl_HasQuery( const ScQueryParam& rParam )
145 return rParam.GetEntryCount() > 0 &&
146 rParam.GetEntry(0).bDoQuery;
149 const TypedScStrCollection& ScSheetDPData::GetColumnEntries(long nColumn)
151 DBG_ASSERT(nColumn>=0 && nColumn < pImpl->aCacheTable.getColSize(), "ScSheetDPData: wrong column");
152 CreateCacheTable();
153 return pImpl->aCacheTable.getFieldEntries(nColumn);
156 String ScSheetDPData::getDimensionName(long nColumn)
158 CreateCacheTable();
159 if (getIsDataLayoutDimension(nColumn))
161 //! different internal and display names?
162 //return "Data";
163 return ScGlobal::GetRscString(STR_PIVOT_DATA);
165 else if (nColumn >= pImpl->aCacheTable.getColSize())
167 DBG_ERROR("getDimensionName: invalid dimension");
168 return String();
170 else
172 const String* pStr = pImpl->aCacheTable.getFieldName(nColumn);
173 if (pStr)
174 return *pStr;
175 else return String();
179 BOOL lcl_HasDateFormat( ScDocument* pDoc, const ScRange& rRange )
181 //! iterate formats in range?
183 ScAddress aPos = rRange.aStart;
184 aPos.SetRow( aPos.Row() + 1 ); // below title
185 ULONG nFormat = pDoc->GetNumberFormat( aPos );
186 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
187 return ( pFormatter->GetType(nFormat) & NUMBERFORMAT_DATE ) != 0;
190 BOOL ScSheetDPData::IsDateDimension(long nDim)
192 CreateCacheTable();
193 long nColCount = pImpl->aCacheTable.getColSize();
194 if (getIsDataLayoutDimension(nDim))
196 return FALSE;
198 else if (nDim >= nColCount)
200 DBG_ERROR("IsDateDimension: invalid dimension");
201 return FALSE;
203 else
205 if (!pImpl->pDateDim)
207 pImpl->pDateDim = new BOOL[nColCount];
208 ScRange aTestRange = pImpl->aRange;
209 for (long i = 0; i < nColCount; ++i)
211 SCCOL nCol = (SCCOL)( pImpl->aRange.aStart.Col() + i );
212 aTestRange.aStart.SetCol(nCol);
213 aTestRange.aEnd.SetCol(nCol);
214 pImpl->pDateDim[i] = lcl_HasDateFormat( pImpl->pDoc, aTestRange );
217 return pImpl->pDateDim[nDim];
221 UINT32 ScSheetDPData::GetNumberFormat(long nDim)
223 CreateCacheTable();
224 if (getIsDataLayoutDimension(nDim))
226 return 0;
228 else if (nDim >= pImpl->aCacheTable.getColSize())
230 DBG_ERROR("GetNumberFormat: invalid dimension");
231 return 0;
233 else
235 // is queried only once per dimension from ScDPOutput -> no need to cache
237 ScAddress aPos = pImpl->aRange.aStart;
238 aPos.SetCol( sal::static_int_cast<SCCOL>( aPos.Col() + nDim ) );
239 aPos.SetRow( aPos.Row() + 1 ); // below title
240 return pImpl->pDoc->GetNumberFormat( aPos );
244 BOOL ScSheetDPData::getIsDataLayoutDimension(long nColumn)
246 CreateCacheTable();
247 return (nColumn == pImpl->aCacheTable.getColSize());
250 void ScSheetDPData::SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty )
252 pImpl->bIgnoreEmptyRows = bIgnoreEmptyRows;
253 pImpl->bRepeatIfEmpty = bRepeatIfEmpty;
256 bool ScSheetDPData::IsRepeatIfEmpty()
258 return pImpl->bRepeatIfEmpty;
261 void ScSheetDPData::CreateCacheTable()
263 // Scan and store the data from the source range.
264 if (!pImpl->aCacheTable.empty())
265 // already cached.
266 return;
268 pImpl->aCacheTable.fillTable(pImpl->pDoc, pImpl->aRange, pImpl->aQuery, pImpl->pSpecial,
269 pImpl->bIgnoreEmptyRows);
272 void ScSheetDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims)
274 CreateCacheTable();
275 pImpl->aCacheTable.filterByPageDimension(
276 rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()));
279 void ScSheetDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData)
281 CreateCacheTable();
282 sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize();
283 if (!nRowSize)
284 return;
286 pImpl->aCacheTable.filterTable(
287 rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>());
290 void ScSheetDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
292 CreateCacheTable();
293 CalcResultsFromCacheTable(pImpl->aCacheTable, rInfo, bAutoShow);
296 const ScDPCacheTable& ScSheetDPData::GetCacheTable() const
298 return pImpl->aCacheTable;
301 // -----------------------------------------------------------------------