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 "dpmacros.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 :
68 0 : struct ScDPServiceDesc
69 : {
70 : ::rtl::OUString aServiceName;
71 : ::rtl::OUString aParSource;
72 : ::rtl::OUString aParName;
73 : ::rtl::OUString aParUser;
74 : ::rtl::OUString aParPass;
75 :
76 : ScDPServiceDesc( const ::rtl::OUString& rServ, const ::rtl::OUString& rSrc, const ::rtl::OUString& rNam,
77 : const ::rtl::OUString& rUser, const ::rtl::OUString& rPass );
78 :
79 : bool operator== ( const ScDPServiceDesc& rOther ) const;
80 : };
81 :
82 :
83 : class SC_DLLPUBLIC ScDPObject
84 : {
85 : private:
86 : ScDocument* pDoc;
87 : // settings
88 : ScDPSaveData* pSaveData;
89 : ::rtl::OUString aTableName;
90 : ::rtl::OUString aTableTag;
91 : ScRange aOutRange;
92 : ScSheetSourceDesc* pSheetDesc; // for sheet data
93 : ScImportSourceDesc* pImpDesc; // for database data
94 : ScDPServiceDesc* pServDesc; // for external service
95 : ::boost::shared_ptr<ScDPTableData> mpTableData;
96 : // cached data
97 : com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier> xSource;
98 : ScDPOutput* pOutput;
99 : sal_uInt16 mnAutoFormatIndex;
100 : long nHeaderRows; // page fields plus filter button
101 : bool mbHeaderLayout:1; // true : grid, false : standard
102 : bool bAllowMove:1;
103 : bool bAlive:1; // false if only used to hold settings
104 : bool bSettingsChanged:1;
105 : bool mbEnableGetPivotData:1;
106 :
107 : SC_DLLPRIVATE ScDPTableData* GetTableData();
108 : SC_DLLPRIVATE void CreateObjects();
109 : SC_DLLPRIVATE void CreateOutput();
110 : SC_DLLPRIVATE void ClearSource();
111 : SC_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 : void EnableGetPivotData(bool b);
122 :
123 : /**
124 : * When a DP object is "alive", it has table output on a sheet. This flag
125 : * doesn't really change the behavior of the object, but is used only for
126 : * testing purposes.
127 : */
128 : void SetAlive(bool bSet);
129 : void SetAllowMove(bool bSet);
130 :
131 : void InvalidateData();
132 : void ClearTableData();
133 : void ReloadGroupTableData();
134 :
135 : void Output( const ScAddress& rPos );
136 : ScRange GetNewOutputRange( bool& rOverflow );
137 : const ScRange GetOutputRangeByType( sal_Int32 nType );
138 :
139 : void SetSaveData(const ScDPSaveData& rData);
140 17 : ScDPSaveData* GetSaveData() const { return pSaveData; }
141 :
142 : void SetOutRange(const ScRange& rRange);
143 56 : const ScRange& GetOutRange() const { return aOutRange; }
144 :
145 : void SetHeaderLayout(bool bUseGrid);
146 : bool GetHeaderLayout() const;
147 :
148 : void SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate = false);
149 : void SetImportDesc(const ScImportSourceDesc& rDesc);
150 : void SetServiceData(const ScDPServiceDesc& rDesc);
151 :
152 : void WriteSourceDataTo( ScDPObject& rDest ) const;
153 : void WriteTempDataTo( ScDPObject& rDest ) const;
154 :
155 14 : const ScSheetSourceDesc* GetSheetDesc() const { return pSheetDesc; }
156 0 : const ScImportSourceDesc* GetImportSourceDesc() const { return pImpDesc; }
157 0 : const ScDPServiceDesc* GetDPServiceDesc() const { return pServDesc; }
158 :
159 : com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier> GetSource();
160 :
161 : bool IsSheetData() const;
162 0 : bool IsImportData() const { return(pImpDesc != NULL); }
163 0 : bool IsServiceData() const { return(pServDesc != NULL); }
164 :
165 : void SetName(const ::rtl::OUString& rNew);
166 16 : const ::rtl::OUString& GetName() const { return aTableName; }
167 : void SetTag(const ::rtl::OUString& rNew);
168 0 : const ::rtl::OUString& GetTag() const { return aTableTag; }
169 :
170 : /**
171 : * Data description cell displays the description of a data dimension if
172 : * and only if there is only one data dimension. It's usually located at
173 : * the upper-left corner of the table output.
174 : */
175 : bool IsDataDescriptionCell(const ScAddress& rPos);
176 :
177 : bool IsDimNameInUse(const ::rtl::OUString& rName) const;
178 : ::rtl::OUString GetDimName( long nDim, bool& rIsDataLayout, sal_Int32* pFlags = NULL );
179 : bool IsDuplicated( long nDim );
180 : long GetDimCount();
181 : void GetHeaderPositionData(const ScAddress& rPos, ::com::sun::star::sheet::DataPilotTableHeaderData& rData);
182 : long GetHeaderDim( const ScAddress& rPos, sal_uInt16& rOrient );
183 : bool GetHeaderDrag( const ScAddress& rPos, bool bMouseLeft, bool bMouseTop,
184 : long nDragDim,
185 : Rectangle& rPosRect, sal_uInt16& rOrient, long& rDimPos );
186 : bool IsFilterButton( const ScAddress& rPos );
187 :
188 : bool GetPivotData( ScDPGetPivotDataField& rTarget, /* returns result */
189 : const std::vector< ScDPGetPivotDataField >& rFilters );
190 : bool ParseFilters( ScDPGetPivotDataField& rTarget,
191 : std::vector< ScDPGetPivotDataField >& rFilters,
192 : const ::rtl::OUString& rFilterList );
193 :
194 : void GetMemberResultNames(ScDPUniqueStringSet& rNames, long nDimension);
195 :
196 : void ToggleDetails(const ::com::sun::star::sheet::DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj);
197 :
198 : bool FillOldParam(ScPivotParam& rParam) const;
199 : bool FillLabelData(sal_Int32 nDim, ScDPLabelData& Labels);
200 : bool FillLabelData(ScPivotParam& rParam);
201 :
202 : bool GetHierarchiesNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xHiers );
203 : bool GetHierarchies( sal_Int32 nDim, com::sun::star::uno::Sequence< rtl::OUString >& rHiers );
204 :
205 : sal_Int32 GetUsedHierarchy( sal_Int32 nDim );
206 :
207 : bool GetMembersNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers );
208 : bool GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers );
209 :
210 : bool GetMemberNames( sal_Int32 nDim, ::com::sun::star::uno::Sequence< ::rtl::OUString >& rNames );
211 : bool GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector<ScDPLabelData::Member>& rMembers );
212 :
213 : void UpdateReference( UpdateRefMode eUpdateRefMode,
214 : const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
215 : bool RefsEqual( const ScDPObject& r ) const;
216 : void WriteRefsTo( ScDPObject& r ) const;
217 :
218 : void GetPositionData(const ScAddress& rPos, ::com::sun::star::sheet::DataPilotTablePositionData& rPosData);
219 :
220 : bool GetDataFieldPositionData(const ScAddress& rPos,
221 : ::com::sun::star::uno::Sequence<
222 : ::com::sun::star::sheet::DataPilotFieldFilter >& rFilters);
223 :
224 : void GetDrillDownData(const ScAddress& rPos,
225 : ::com::sun::star::uno::Sequence<
226 : ::com::sun::star::uno::Sequence<
227 : ::com::sun::star::uno::Any > >& rTableData);
228 :
229 : // apply drop-down attribute, initialize nHeaderRows, without accessing the source
230 : // (button attribute must be present)
231 : void RefreshAfterLoad();
232 :
233 : void BuildAllDimensionMembers();
234 :
235 : /**
236 : * Remove in the save data entries for members that don't exist anymore.
237 : * This is called during pivot table refresh.
238 : */
239 : bool SyncAllDimensionMembers();
240 :
241 : static bool HasRegisteredSources();
242 : static com::sun::star::uno::Sequence<rtl::OUString> GetRegisteredSources();
243 : static com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier>
244 : CreateSource( const ScDPServiceDesc& rDesc );
245 :
246 : static void ConvertOrientation(
247 : ScDPSaveData& rSaveData,
248 : const ScPivotFieldVector& rFields, sal_uInt16 nOrient,
249 : const com::sun::star::uno::Reference<
250 : com::sun::star::sheet::XDimensionsSupplier>& xSource,
251 : const ScDPLabelDataVector& rLabels,
252 : const ScPivotFieldVector* pRefColFields = NULL,
253 : const ScPivotFieldVector* pRefRowFields = NULL,
254 : const ScPivotFieldVector* pRefPageFields = NULL );
255 :
256 : static bool IsOrientationAllowed( sal_uInt16 nOrient, sal_Int32 nDimFlags );
257 :
258 : #if DEBUG_PIVOT_TABLE
259 : void DumpCache() const;
260 : #endif
261 : };
262 :
263 :
264 : class ScDPCollection
265 : {
266 : friend class ScDPCache;
267 : public:
268 :
269 : /**
270 : * Stores and manages all caches from internal sheets.
271 : */
272 25 : class SheetCaches
273 : {
274 : friend class ScDPCollection;
275 : typedef boost::ptr_map<size_t, ScDPCache> CachesType;
276 : typedef std::vector<ScRange> RangeIndexType;
277 : CachesType maCaches;
278 : RangeIndexType maRanges;
279 : ScDocument* mpDoc;
280 : public:
281 : SheetCaches(ScDocument* pDoc);
282 : bool hasCache(const ScRange& rRange) const;
283 : const ScDPCache* getCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData);
284 : size_t size() const;
285 :
286 : void updateReference(
287 : UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz);
288 :
289 : private:
290 : ScDPCache* getExistingCache(const ScRange& rRange);
291 :
292 : void updateCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData, std::set<ScDPObject*>& rRefs);
293 : bool remove(const ScDPCache* p);
294 : };
295 :
296 : /**
297 : * Data caches for range name based source data.
298 : */
299 25 : class NameCaches
300 : {
301 : friend class ScDPCollection;
302 : typedef ::boost::ptr_map<rtl::OUString, ScDPCache> CachesType;
303 : CachesType maCaches;
304 : ScDocument* mpDoc;
305 : public:
306 : NameCaches(ScDocument* pDoc);
307 : bool hasCache(const rtl::OUString& rName) const;
308 : const ScDPCache* getCache(
309 : const ::rtl::OUString& rName, const ScRange& rRange, const ScDPDimensionSaveData* pDimData);
310 : size_t size() const;
311 : private:
312 : ScDPCache* getExistingCache(const rtl::OUString& rName);
313 :
314 : void updateCache(
315 : const rtl::OUString& rName, const ScRange& rRange,
316 : const ScDPDimensionSaveData* pDimData, std::set<ScDPObject*>& rRefs);
317 : bool remove(const ScDPCache* p);
318 : };
319 :
320 : /**
321 : * Defines connection type to external data source. Used as a key to look
322 : * up database cache.
323 : */
324 0 : struct DBType
325 : {
326 : sal_Int32 mnSdbType;
327 : ::rtl::OUString maDBName;
328 : ::rtl::OUString maCommand;
329 : DBType(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
330 :
331 : struct less : public ::std::binary_function<DBType, DBType, bool>
332 : {
333 : bool operator() (const DBType& left, const DBType& right) const;
334 : };
335 : };
336 :
337 : /**
338 : * Data caches for external database sources.
339 : */
340 25 : class DBCaches
341 : {
342 : friend class ScDPCollection;
343 : typedef ::boost::ptr_map<DBType, ScDPCache, DBType::less> CachesType;
344 : CachesType maCaches;
345 : ScDocument* mpDoc;
346 : public:
347 : DBCaches(ScDocument* pDoc);
348 : bool hasCache(sal_Int32 nSdbType, const rtl::OUString& rDBName, const rtl::OUString& rCommand) const;
349 : const ScDPCache* getCache(
350 : sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand,
351 : const ScDPDimensionSaveData* pDimData);
352 :
353 : private:
354 : ScDPCache* getExistingCache(
355 : sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
356 :
357 : com::sun::star::uno::Reference<com::sun::star::sdbc::XRowSet> createRowSet(
358 : sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
359 :
360 : void updateCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand,
361 : const ScDPDimensionSaveData* pDimData, 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 ::rtl::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 : ::rtl::OUString CreateNewName( sal_uInt16 nMin = 1 ) const;
395 :
396 : void FreeTable(ScDPObject* pDPObj);
397 : SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj);
398 :
399 : bool HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const;
400 :
401 : SheetCaches& GetSheetCaches();
402 : NameCaches& GetNameCaches();
403 : DBCaches& GetDBCaches();
404 :
405 : private:
406 : /** Only to be called from ScDPCache::RemoveReference(). */
407 : void RemoveCache(const ScDPCache* pCache);
408 :
409 : void GetAllTables(const ScRange& rSrcRange, std::set<ScDPObject*>& rRefs) const;
410 : void GetAllTables(const rtl::OUString& rSrcName, std::set<ScDPObject*>& rRefs) const;
411 : void GetAllTables(
412 : sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand,
413 : std::set<ScDPObject*>& rRefs) const;
414 :
415 : private:
416 : typedef ::boost::ptr_vector<ScDPObject> TablesType;
417 :
418 : ScDocument* mpDoc;
419 : TablesType maTables;
420 : SheetCaches maSheetCaches;
421 : NameCaches maNameCaches;
422 : DBCaches maDBCaches;
423 : };
424 :
425 : bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right);
426 :
427 : #endif
428 :
429 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|