Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef SC_DPOBJECT_HXX
21 : #define SC_DPOBJECT_HXX
22 :
23 : #include "scdllapi.h"
24 : #include "global.hxx"
25 : #include "address.hxx"
26 : #include "dpoutput.hxx"
27 : #include "dptypes.hxx"
28 : #include "pivot.hxx"
29 : #include "calcmacros.hxx"
30 :
31 : #include <com/sun/star/sheet/XDimensionsSupplier.hpp>
32 :
33 : #include <set>
34 : #include <vector>
35 :
36 : #include <boost/ptr_container/ptr_list.hpp>
37 : #include <boost/ptr_container/ptr_vector.hpp>
38 : #include <boost/ptr_container/ptr_map.hpp>
39 : #include <boost/shared_ptr.hpp>
40 :
41 : namespace com { namespace sun { namespace star {
42 :
43 : namespace container {
44 : class XIndexAccess;
45 : }
46 :
47 : namespace sdbc {
48 : class XRowSet;
49 : }
50 :
51 : namespace sheet {
52 : struct DataPilotTablePositionData;
53 : struct DataPilotTableHeaderData;
54 : struct DataPilotFieldFilter;
55 : }
56 : }}}
57 :
58 : class Rectangle;
59 : class ScDPSaveData;
60 : class ScDPOutput;
61 : struct ScPivotParam;
62 : struct ScImportSourceDesc;
63 : class ScSheetSourceDesc;
64 : struct ScPivotField;
65 : class ScDPTableData;
66 : class ScDPDimensionSaveData;
67 : class ScRangeList;
68 :
69 0 : struct ScDPServiceDesc
70 : {
71 : OUString aServiceName;
72 : OUString aParSource;
73 : OUString aParName;
74 : OUString aParUser;
75 : OUString aParPass;
76 :
77 : ScDPServiceDesc( const OUString& rServ, const OUString& rSrc, const OUString& rNam,
78 : const OUString& rUser, const OUString& rPass );
79 :
80 : bool operator== ( const ScDPServiceDesc& rOther ) const;
81 : };
82 :
83 :
84 : class SC_DLLPUBLIC ScDPObject
85 : {
86 : private:
87 : ScDocument* pDoc;
88 : // settings
89 : ScDPSaveData* pSaveData;
90 : OUString aTableName;
91 : OUString aTableTag;
92 : ScRange aOutRange;
93 : ScSheetSourceDesc* pSheetDesc; // for sheet data
94 : ScImportSourceDesc* pImpDesc; // for database data
95 : ScDPServiceDesc* pServDesc; // for external service
96 : ::boost::shared_ptr<ScDPTableData> mpTableData;
97 : // cached data
98 : com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier> xSource;
99 : ScDPOutput* pOutput;
100 : sal_uInt16 mnAutoFormatIndex;
101 : long nHeaderRows; // page fields plus filter button
102 : bool mbHeaderLayout:1; // true : grid, false : standard
103 : bool bAllowMove:1;
104 : bool bSettingsChanged:1;
105 : bool mbEnableGetPivotData:1;
106 :
107 : SAL_DLLPRIVATE ScDPTableData* GetTableData();
108 : SAL_DLLPRIVATE void CreateObjects();
109 : SAL_DLLPRIVATE void CreateOutput();
110 : SAL_DLLPRIVATE void ClearSource();
111 : SAL_DLLPRIVATE bool FillLabelDataForDimension(
112 : const com::sun::star::uno::Reference<
113 : com::sun::star::container::XIndexAccess>& xDims,
114 : sal_Int32 nDim, ScDPLabelData& rLabelData);
115 :
116 : public:
117 : ScDPObject(ScDocument* pD);
118 : ScDPObject(const ScDPObject& r);
119 : ~ScDPObject();
120 :
121 : ScDPObject& operator= (const ScDPObject& r);
122 :
123 : void EnableGetPivotData(bool b);
124 :
125 : void SetAllowMove(bool bSet);
126 :
127 : void InvalidateData();
128 : void Clear();
129 : void ClearTableData();
130 : void ReloadGroupTableData();
131 :
132 : void Output( const ScAddress& rPos );
133 : ScRange GetNewOutputRange( bool& rOverflow );
134 : const ScRange GetOutputRangeByType( sal_Int32 nType );
135 :
136 : void SetSaveData(const ScDPSaveData& rData);
137 0 : ScDPSaveData* GetSaveData() const { return pSaveData; }
138 :
139 : void SetOutRange(const ScRange& rRange);
140 0 : const ScRange& GetOutRange() const { return aOutRange; }
141 :
142 : void SetHeaderLayout(bool bUseGrid);
143 : bool GetHeaderLayout() const;
144 :
145 : void SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate = false);
146 : void SetImportDesc(const ScImportSourceDesc& rDesc);
147 : void SetServiceData(const ScDPServiceDesc& rDesc);
148 :
149 : void WriteSourceDataTo( ScDPObject& rDest ) const;
150 : void WriteTempDataTo( ScDPObject& rDest ) const;
151 :
152 0 : const ScSheetSourceDesc* GetSheetDesc() const { return pSheetDesc; }
153 0 : const ScImportSourceDesc* GetImportSourceDesc() const { return pImpDesc; }
154 0 : const ScDPServiceDesc* GetDPServiceDesc() const { return pServDesc; }
155 :
156 : com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier> GetSource();
157 :
158 : bool IsSheetData() const;
159 0 : bool IsImportData() const { return(pImpDesc != NULL); }
160 0 : bool IsServiceData() const { return(pServDesc != NULL); }
161 :
162 : void SetName(const OUString& rNew);
163 0 : const OUString& GetName() const { return aTableName; }
164 : void SetTag(const OUString& rNew);
165 0 : const OUString& GetTag() const { return aTableTag; }
166 :
167 : /**
168 : * Data description cell displays the description of a data dimension if
169 : * and only if there is only one data dimension. It's usually located at
170 : * the upper-left corner of the table output.
171 : */
172 : bool IsDataDescriptionCell(const ScAddress& rPos);
173 :
174 : bool IsDimNameInUse(const OUString& rName) const;
175 : OUString GetDimName( long nDim, bool& rIsDataLayout, sal_Int32* pFlags = NULL );
176 : bool IsDuplicated( long nDim );
177 : long GetDimCount();
178 : void GetHeaderPositionData(const ScAddress& rPos, ::com::sun::star::sheet::DataPilotTableHeaderData& rData);
179 : long GetHeaderDim( const ScAddress& rPos, sal_uInt16& rOrient );
180 : bool GetHeaderDrag( const ScAddress& rPos, bool bMouseLeft, bool bMouseTop,
181 : long nDragDim,
182 : Rectangle& rPosRect, sal_uInt16& rOrient, long& rDimPos );
183 : bool IsFilterButton( const ScAddress& rPos );
184 :
185 : double GetPivotData(
186 : const OUString& rDataFieldName,
187 : std::vector<com::sun::star::sheet::DataPilotFieldFilter>& rFilters);
188 :
189 : bool ParseFilters(
190 : OUString& rDataFieldName,
191 : std::vector<com::sun::star::sheet::DataPilotFieldFilter>& rFilters,
192 : std::vector<com::sun::star::sheet::GeneralFunction>& rFilterFuncs,
193 : const OUString& rFilterList );
194 :
195 : void GetMemberResultNames(ScDPUniqueStringSet& rNames, long nDimension);
196 :
197 : void ToggleDetails(const ::com::sun::star::sheet::DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj);
198 :
199 : bool FillOldParam(ScPivotParam& rParam) const;
200 : bool FillLabelData(sal_Int32 nDim, ScDPLabelData& Labels);
201 : bool FillLabelData(ScPivotParam& rParam);
202 :
203 : bool GetHierarchiesNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xHiers );
204 : bool GetHierarchies( sal_Int32 nDim, com::sun::star::uno::Sequence< OUString >& rHiers );
205 :
206 : sal_Int32 GetUsedHierarchy( sal_Int32 nDim );
207 :
208 : bool GetMembersNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers );
209 : bool GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers );
210 :
211 : bool GetMemberNames( sal_Int32 nDim, ::com::sun::star::uno::Sequence< OUString >& rNames );
212 : bool GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector<ScDPLabelData::Member>& rMembers );
213 :
214 : void UpdateReference( UpdateRefMode eUpdateRefMode,
215 : const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
216 : bool RefsEqual( const ScDPObject& r ) const;
217 : void WriteRefsTo( ScDPObject& r ) const;
218 :
219 : void GetPositionData(const ScAddress& rPos, ::com::sun::star::sheet::DataPilotTablePositionData& rPosData);
220 :
221 : bool GetDataFieldPositionData(const ScAddress& rPos,
222 : ::com::sun::star::uno::Sequence<
223 : ::com::sun::star::sheet::DataPilotFieldFilter >& rFilters);
224 :
225 : void GetDrillDownData(const ScAddress& rPos,
226 : ::com::sun::star::uno::Sequence<
227 : ::com::sun::star::uno::Sequence<
228 : ::com::sun::star::uno::Any > >& rTableData);
229 :
230 : // apply drop-down attribute, initialize nHeaderRows, without accessing the source
231 : // (button attribute must be present)
232 : void RefreshAfterLoad();
233 :
234 : void BuildAllDimensionMembers();
235 :
236 : /**
237 : * Remove in the save data entries for members that don't exist anymore.
238 : * This is called during pivot table refresh.
239 : */
240 : bool SyncAllDimensionMembers();
241 :
242 : static bool HasRegisteredSources();
243 : static com::sun::star::uno::Sequence<OUString> GetRegisteredSources();
244 : static com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier>
245 : CreateSource( const ScDPServiceDesc& rDesc );
246 :
247 : static void ConvertOrientation(
248 : ScDPSaveData& rSaveData,
249 : const ScPivotFieldVector& rFields, sal_uInt16 nOrient,
250 : const com::sun::star::uno::Reference<
251 : com::sun::star::sheet::XDimensionsSupplier>& xSource,
252 : const ScDPLabelDataVector& rLabels,
253 : const ScPivotFieldVector* pRefColFields = NULL,
254 : const ScPivotFieldVector* pRefRowFields = NULL,
255 : const ScPivotFieldVector* pRefPageFields = NULL );
256 :
257 : static bool IsOrientationAllowed( sal_uInt16 nOrient, sal_Int32 nDimFlags );
258 :
259 : #if DEBUG_PIVOT_TABLE
260 : void DumpCache() const;
261 : #endif
262 : };
263 :
264 :
265 : class ScDPCollection
266 : {
267 : friend class ScDPCache;
268 : public:
269 :
270 : /**
271 : * Stores and manages all caches from internal sheets.
272 : */
273 0 : class SheetCaches
274 : {
275 : friend class ScDPCollection;
276 : typedef boost::ptr_map<size_t, ScDPCache> CachesType;
277 : typedef std::vector<ScRange> RangeIndexType;
278 : CachesType maCaches;
279 : RangeIndexType maRanges;
280 : ScDocument* mpDoc;
281 : public:
282 : SheetCaches(ScDocument* pDoc);
283 : bool hasCache(const ScRange& rRange) const;
284 : const ScDPCache* getCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData);
285 : SC_DLLPUBLIC size_t size() const;
286 :
287 : void updateReference(
288 : UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz);
289 :
290 : SC_DLLPUBLIC ScDPCache* getExistingCache(const ScRange& rRange);
291 :
292 : void updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs);
293 : bool remove(const ScDPCache* p);
294 : };
295 :
296 : /**
297 : * Data caches for range name based source data.
298 : */
299 0 : class NameCaches
300 : {
301 : friend class ScDPCollection;
302 : typedef ::boost::ptr_map<OUString, ScDPCache> CachesType;
303 : CachesType maCaches;
304 : ScDocument* mpDoc;
305 : public:
306 : NameCaches(ScDocument* pDoc);
307 : bool hasCache(const OUString& rName) const;
308 : const ScDPCache* getCache(
309 : const OUString& rName, const ScRange& rRange, const ScDPDimensionSaveData* pDimData);
310 : size_t size() const;
311 : private:
312 : ScDPCache* getExistingCache(const OUString& rName);
313 :
314 : void updateCache(
315 : const OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs);
316 : bool remove(const ScDPCache* p);
317 : };
318 :
319 : /**
320 : * Defines connection type to external data source. Used as a key to look
321 : * up database cache.
322 : */
323 0 : struct DBType
324 : {
325 : sal_Int32 mnSdbType;
326 : OUString maDBName;
327 : OUString maCommand;
328 : DBType(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand);
329 :
330 : struct less : public ::std::binary_function<DBType, DBType, bool>
331 : {
332 : bool operator() (const DBType& left, const DBType& right) const;
333 : };
334 : };
335 :
336 : /**
337 : * Data caches for external database sources.
338 : */
339 0 : class DBCaches
340 : {
341 : friend class ScDPCollection;
342 : typedef ::boost::ptr_map<DBType, ScDPCache, DBType::less> CachesType;
343 : CachesType maCaches;
344 : ScDocument* mpDoc;
345 : public:
346 : DBCaches(ScDocument* pDoc);
347 : bool hasCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) const;
348 : const ScDPCache* getCache(
349 : sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand,
350 : const ScDPDimensionSaveData* pDimData);
351 :
352 : private:
353 : ScDPCache* getExistingCache(
354 : sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand);
355 :
356 : com::sun::star::uno::Reference<com::sun::star::sdbc::XRowSet> createRowSet(
357 : sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand);
358 :
359 : void updateCache(
360 : sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand,
361 : std::set<ScDPObject*>& rRefs);
362 : bool remove(const ScDPCache* p);
363 : };
364 :
365 : ScDPCollection(ScDocument* pDocument);
366 : ScDPCollection(const ScDPCollection& r);
367 : ~ScDPCollection();
368 :
369 : sal_uLong ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs);
370 : bool ReloadGroupsInCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs);
371 :
372 : SC_DLLPUBLIC size_t GetCount() const;
373 : SC_DLLPUBLIC ScDPObject* operator[](size_t nIndex);
374 : SC_DLLPUBLIC const ScDPObject* operator[](size_t nIndex) const;
375 :
376 : const ScDPObject* GetByName(const OUString& rName) const;
377 :
378 : void DeleteOnTab( SCTAB nTab );
379 : void UpdateReference( UpdateRefMode eUpdateRefMode,
380 : const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
381 : void CopyToTab( SCTAB nOld, SCTAB nNew );
382 : bool RefsEqual( const ScDPCollection& r ) const;
383 : void WriteRefsTo( ScDPCollection& r ) const;
384 :
385 : /**
386 : * Create a new name that's not yet used by any existing data pilot
387 : * objects. All data pilot names are 'DataPilot' + <num>, and the nMin
388 : * specifies the minimum number allowed.
389 : *
390 : * @param nMin minimum number allowed.
391 : *
392 : * @return new name for data pilot object.
393 : */
394 : OUString CreateNewName( sal_uInt16 nMin = 1 ) const;
395 :
396 : void FreeTable(ScDPObject* pDPObj);
397 : SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj);
398 :
399 : SC_DLLPUBLIC SheetCaches& GetSheetCaches();
400 : NameCaches& GetNameCaches();
401 : DBCaches& GetDBCaches();
402 :
403 : ScRangeList GetAllTableRanges( SCTAB nTab ) const;
404 : bool IntersectsTableByColumns( SCCOL nCol1, SCCOL nCol2, SCROW nRow, SCTAB nTab ) const;
405 : bool IntersectsTableByRows( SCCOL nCol, SCROW nRow1, SCROW nRow2, SCTAB nTab ) const;
406 : bool HasTable( const ScRange& rRange ) const;
407 :
408 : #if DEBUG_PIVOT_TABLE
409 : void DumpTables() const;
410 : #endif
411 :
412 : private:
413 : /** Only to be called from ScDPCache::RemoveReference(). */
414 : void RemoveCache(const ScDPCache* pCache);
415 :
416 : void GetAllTables(const ScRange& rSrcRange, std::set<ScDPObject*>& rRefs) const;
417 : void GetAllTables(const OUString& rSrcName, std::set<ScDPObject*>& rRefs) const;
418 : void GetAllTables(
419 : sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand,
420 : std::set<ScDPObject*>& rRefs) const;
421 :
422 : private:
423 : typedef ::boost::ptr_vector<ScDPObject> TablesType;
424 :
425 : ScDocument* mpDoc;
426 : TablesType maTables;
427 : SheetCaches maSheetCaches;
428 : NameCaches maNameCaches;
429 : DBCaches maDBCaches;
430 : };
431 :
432 : bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right);
433 :
434 : #endif
435 :
436 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|