Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "dpobject.hxx"
30 : : #include "dptabsrc.hxx"
31 : : #include "dpsave.hxx"
32 : : #include "dpdimsave.hxx"
33 : : #include "dpoutput.hxx"
34 : : #include "dpshttab.hxx"
35 : : #include "dpsdbtab.hxx"
36 : : #include "dpgroup.hxx"
37 : : #include "document.hxx"
38 : : #include "rechead.hxx"
39 : : #include "pivot.hxx" // PIVOT_DATA_FIELD
40 : : #include "dapiuno.hxx" // ScDataPilotConversion
41 : : #include "miscuno.hxx"
42 : : #include "scerrors.hxx"
43 : : #include "refupdat.hxx"
44 : : #include "scresid.hxx"
45 : : #include "sc.hrc"
46 : : #include "attrib.hxx"
47 : : #include "scitems.hxx"
48 : : #include "unonames.hxx"
49 : : #include "dpglobal.hxx"
50 : : #include "globstr.hrc"
51 : : #include "queryentry.hxx"
52 : : #include "dputil.hxx"
53 : :
54 : : #include <com/sun/star/beans/XPropertySet.hpp>
55 : : #include <com/sun/star/sdb/XCompletedExecution.hpp>
56 : : #include <com/sun/star/sdbc/DataType.hpp>
57 : : #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
58 : : #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
59 : : #include <com/sun/star/sdbc/XRow.hpp>
60 : : #include <com/sun/star/sdbc/XRowSet.hpp>
61 : : #include <com/sun/star/sheet/GeneralFunction.hpp>
62 : : #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
63 : : #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
64 : : #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
65 : : #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
66 : : #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
67 : : #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
68 : : #include <com/sun/star/sheet/DimensionFlags.hpp>
69 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
70 : : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
71 : : #include <com/sun/star/lang/XSingleComponentFactory.hpp>
72 : : #include <com/sun/star/lang/XInitialization.hpp>
73 : : #include <com/sun/star/container/XContentEnumerationAccess.hpp>
74 : : #include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
75 : :
76 : : #include <comphelper/processfactory.hxx>
77 : : #include <comphelper/string.hxx>
78 : : #include <comphelper/types.hxx>
79 : : #include <sal/macros.h>
80 : : #include <tools/debug.hxx>
81 : : #include <tools/diagnose_ex.h>
82 : : #include <svl/zforlist.hxx> // IsNumberFormat
83 : : #include <vcl/msgbox.hxx>
84 : :
85 : : #include <vector>
86 : : #include <memory>
87 : :
88 : : using namespace com::sun::star;
89 : : using ::std::vector;
90 : : using ::std::unary_function;
91 : : using ::boost::shared_ptr;
92 : : using ::com::sun::star::uno::Sequence;
93 : : using ::com::sun::star::uno::Reference;
94 : : using ::com::sun::star::uno::UNO_QUERY;
95 : : using ::com::sun::star::uno::Any;
96 : : using ::com::sun::star::uno::Exception;
97 : : using ::com::sun::star::lang::XComponent;
98 : : using ::com::sun::star::sheet::DataPilotTableHeaderData;
99 : : using ::com::sun::star::sheet::DataPilotTablePositionData;
100 : : using ::com::sun::star::sheet::XDimensionsSupplier;
101 : : using ::com::sun::star::beans::XPropertySet;
102 : : using ::rtl::OUString;
103 : :
104 : : #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet"
105 : : #define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler"
106 : :
107 : : #define SC_DBPROP_DATASOURCENAME "DataSourceName"
108 : : #define SC_DBPROP_COMMAND "Command"
109 : : #define SC_DBPROP_COMMANDTYPE "CommandType"
110 : :
111 : : // -----------------------------------------------------------------------
112 : :
113 : : #define SCDPSOURCE_SERVICE "com.sun.star.sheet.DataPilotSource"
114 : :
115 : : namespace {
116 : :
117 : : const double D_TIMEFACTOR = 86400.0;
118 : :
119 : : /**
120 : : * Database connection implementation for UNO database API. Note that in
121 : : * the UNO database API, column index is 1-based, whereas the interface
122 : : * requires that column index be 0-based.
123 : : */
124 [ # # ]: 0 : class DBConnector : public ScDPCache::DBConnector
125 : : {
126 : : ScDPCache& mrCache;
127 : :
128 : : uno::Reference<sdbc::XRowSet> mxRowSet;
129 : : uno::Reference<sdbc::XRow> mxRow;
130 : : uno::Reference<sdbc::XResultSetMetaData> mxMetaData;
131 : : Date maNullDate;
132 : :
133 : : public:
134 : : DBConnector(ScDPCache& rCache, const uno::Reference<sdbc::XRowSet>& xRowSet, const Date& rNullDate);
135 : :
136 : : bool isValid() const;
137 : :
138 : : virtual void getValue(long nCol, ScDPItemData &rData, short& rNumType) const;
139 : : virtual OUString getColumnLabel(long nCol) const;
140 : : virtual long getColumnCount() const;
141 : : virtual bool first();
142 : : virtual bool next();
143 : : virtual void finish();
144 : : };
145 : :
146 : 0 : DBConnector::DBConnector(ScDPCache& rCache, const uno::Reference<sdbc::XRowSet>& xRowSet, const Date& rNullDate) :
147 : 0 : mrCache(rCache), mxRowSet(xRowSet), maNullDate(rNullDate)
148 : : {
149 [ # # ]: 0 : Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp(mxRowSet, UNO_QUERY);
150 [ # # ]: 0 : if (xMetaSupp.is())
151 [ # # ][ # # ]: 0 : mxMetaData = xMetaSupp->getMetaData();
[ # # ]
152 : :
153 [ # # ]: 0 : mxRow.set(mxRowSet, UNO_QUERY);
154 : 0 : }
155 : :
156 : 0 : bool DBConnector::isValid() const
157 : : {
158 [ # # ][ # # ]: 0 : return mxRowSet.is() && mxRow.is() && mxMetaData.is();
[ # # ]
159 : : }
160 : :
161 : 0 : bool DBConnector::first()
162 : : {
163 : 0 : return mxRowSet->first();
164 : : }
165 : :
166 : 0 : bool DBConnector::next()
167 : : {
168 : 0 : return mxRowSet->next();
169 : : }
170 : :
171 : 0 : void DBConnector::finish()
172 : : {
173 : 0 : mxRowSet->beforeFirst();
174 : 0 : }
175 : :
176 : 0 : long DBConnector::getColumnCount() const
177 : : {
178 : 0 : return mxMetaData->getColumnCount();
179 : : }
180 : :
181 : 0 : OUString DBConnector::getColumnLabel(long nCol) const
182 : : {
183 : 0 : return mxMetaData->getColumnLabel(nCol+1);
184 : : }
185 : :
186 : 0 : void DBConnector::getValue(long nCol, ScDPItemData &rData, short& rNumType) const
187 : : {
188 : 0 : rNumType = NUMBERFORMAT_NUMBER;
189 : 0 : sal_Int32 nType = mxMetaData->getColumnType(nCol+1);
190 : :
191 : : try
192 : : {
193 : 0 : double fValue = 0.0;
194 [ # # # # : 0 : switch (nType)
# # ]
195 : : {
196 : : case sdbc::DataType::BIT:
197 : : case sdbc::DataType::BOOLEAN:
198 : : {
199 : 0 : rNumType = NUMBERFORMAT_LOGICAL;
200 [ # # ][ # # ]: 0 : fValue = mxRow->getBoolean(nCol+1) ? 1 : 0;
[ # # ]
201 [ # # ]: 0 : rData.SetValue(fValue);
202 : 0 : break;
203 : : }
204 : : case sdbc::DataType::TINYINT:
205 : : case sdbc::DataType::SMALLINT:
206 : : case sdbc::DataType::INTEGER:
207 : : case sdbc::DataType::BIGINT:
208 : : case sdbc::DataType::FLOAT:
209 : : case sdbc::DataType::REAL:
210 : : case sdbc::DataType::DOUBLE:
211 : : case sdbc::DataType::NUMERIC:
212 : : case sdbc::DataType::DECIMAL:
213 : : {
214 : : //! do the conversion here?
215 [ # # ][ # # ]: 0 : fValue = mxRow->getDouble(nCol+1);
216 [ # # ]: 0 : rData.SetValue(fValue);
217 : 0 : break;
218 : : }
219 : : case sdbc::DataType::DATE:
220 : : {
221 : 0 : rNumType = NUMBERFORMAT_DATE;
222 : :
223 [ # # ][ # # ]: 0 : util::Date aDate = mxRow->getDate(nCol+1);
224 [ # # ]: 0 : fValue = Date(aDate.Day, aDate.Month, aDate.Year) - maNullDate;
225 [ # # ]: 0 : rData.SetValue(fValue);
226 : : break;
227 : : }
228 : : case sdbc::DataType::TIME:
229 : : {
230 : 0 : rNumType = NUMBERFORMAT_TIME;
231 : :
232 [ # # ][ # # ]: 0 : util::Time aTime = mxRow->getTime(nCol+1);
233 : : fValue = ( aTime.Hours * 3600 + aTime.Minutes * 60 +
234 : 0 : aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
235 [ # # ]: 0 : rData.SetValue(fValue);
236 : : break;
237 : : }
238 : : case sdbc::DataType::TIMESTAMP:
239 : : {
240 : 0 : rNumType = NUMBERFORMAT_DATETIME;
241 : :
242 [ # # ][ # # ]: 0 : util::DateTime aStamp = mxRow->getTimestamp(nCol+1);
243 [ # # ]: 0 : fValue = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - maNullDate ) +
244 : : ( aStamp.Hours * 3600 + aStamp.Minutes * 60 +
245 : 0 : aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
246 [ # # ]: 0 : rData.SetValue(fValue);
247 : : break;
248 : : }
249 : : case sdbc::DataType::CHAR:
250 : : case sdbc::DataType::VARCHAR:
251 : : case sdbc::DataType::LONGVARCHAR:
252 : : case sdbc::DataType::SQLNULL:
253 : : case sdbc::DataType::BINARY:
254 : : case sdbc::DataType::VARBINARY:
255 : : case sdbc::DataType::LONGVARBINARY:
256 : : default:
257 [ # # ][ # # ]: 0 : rData.SetString(mrCache.InternString(mxRow->getString(nCol+1)));
[ # # ][ # # ]
258 : : }
259 : : }
260 [ # # ]: 0 : catch (uno::Exception&)
261 : : {
262 [ # # ]: 0 : rData.SetEmpty();
263 : : }
264 : 0 : }
265 : :
266 : : }
267 : :
268 : 0 : sal_uInt16 lcl_GetDataGetOrientation( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
269 : : {
270 : 0 : long nRet = sheet::DataPilotFieldOrientation_HIDDEN;
271 [ # # ]: 0 : if ( xSource.is() )
272 : : {
273 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
274 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
[ # # ]
275 [ # # ][ # # ]: 0 : long nIntCount = xIntDims->getCount();
276 : 0 : sal_Bool bFound = false;
277 [ # # ][ # # ]: 0 : for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
[ # # ]
278 : : {
279 : : uno::Reference<uno::XInterface> xIntDim =
280 [ # # ][ # # ]: 0 : ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
[ # # ]
281 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
282 [ # # ]: 0 : if ( xDimProp.is() )
283 : : {
284 : : bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
285 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISDATALAYOUT)) );
286 : : //! error checking -- is "IsDataLayoutDimension" property required??
287 [ # # ]: 0 : if (bFound)
288 : : nRet = ScUnoHelpFunctions::GetEnumProperty(
289 : : xDimProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ORIENTATION)),
290 [ # # ][ # # ]: 0 : sheet::DataPilotFieldOrientation_HIDDEN );
291 : : }
292 : 0 : }
293 : : }
294 : 0 : return static_cast< sal_uInt16 >( nRet );
295 : : }
296 : :
297 : 0 : ScDPServiceDesc::ScDPServiceDesc(
298 : : const OUString& rServ, const OUString& rSrc, const OUString& rNam,
299 : : const OUString& rUser, const OUString& rPass ) :
300 : : aServiceName( rServ ),
301 : : aParSource( rSrc ),
302 : : aParName( rNam ),
303 : : aParUser( rUser ),
304 : 0 : aParPass( rPass ) {}
305 : :
306 : 0 : bool ScDPServiceDesc::operator== ( const ScDPServiceDesc& rOther ) const
307 : : {
308 : 0 : return aServiceName == rOther.aServiceName &&
309 : 0 : aParSource == rOther.aParSource &&
310 : 0 : aParName == rOther.aParName &&
311 : 0 : aParUser == rOther.aParUser &&
312 [ # # ][ # # : 0 : aParPass == rOther.aParPass;
# # # # #
# ]
313 : : }
314 : :
315 : 64 : ScDPObject::ScDPObject( ScDocument* pD ) :
316 : : pDoc( pD ),
317 : : pSaveData( NULL ),
318 : : pSheetDesc( NULL ),
319 : : pImpDesc( NULL ),
320 : : pServDesc( NULL ),
321 : : mpTableData(static_cast<ScDPTableData*>(NULL)),
322 : : pOutput( NULL ),
323 : : mnAutoFormatIndex( 65535 ),
324 : : nHeaderRows( 0 ),
325 : : mbHeaderLayout(false),
326 : : bAllowMove(false),
327 : : bAlive(false),
328 : : bSettingsChanged(false),
329 [ + - ]: 64 : mbEnableGetPivotData(true)
330 : : {
331 : 64 : }
332 : :
333 : 169 : ScDPObject::ScDPObject(const ScDPObject& r) :
334 : : pDoc( r.pDoc ),
335 : : pSaveData( NULL ),
336 : : aTableName( r.aTableName ),
337 : : aTableTag( r.aTableTag ),
338 : : aOutRange( r.aOutRange ),
339 : : pSheetDesc( NULL ),
340 : : pImpDesc( NULL ),
341 : : pServDesc( NULL ),
342 : : mpTableData(static_cast<ScDPTableData*>(NULL)),
343 : : pOutput( NULL ),
344 : : mnAutoFormatIndex( r.mnAutoFormatIndex ),
345 : : nHeaderRows( r.nHeaderRows ),
346 : : mbHeaderLayout( r.mbHeaderLayout ),
347 : : bAllowMove(false),
348 : : bAlive(false),
349 : : bSettingsChanged(false),
350 [ + - ]: 169 : mbEnableGetPivotData(r.mbEnableGetPivotData)
351 : : {
352 [ + - ]: 169 : if (r.pSaveData)
353 [ + - ][ + - ]: 169 : pSaveData = new ScDPSaveData(*r.pSaveData);
354 [ + - ]: 169 : if (r.pSheetDesc)
355 [ + - ][ + - ]: 169 : pSheetDesc = new ScSheetSourceDesc(*r.pSheetDesc);
356 [ - + ]: 169 : if (r.pImpDesc)
357 [ # # ]: 0 : pImpDesc = new ScImportSourceDesc(*r.pImpDesc);
358 [ - + ]: 169 : if (r.pServDesc)
359 [ # # ]: 0 : pServDesc = new ScDPServiceDesc(*r.pServDesc);
360 : : // xSource (and pOutput) is not copied
361 : 169 : }
362 : :
363 [ + - ]: 232 : ScDPObject::~ScDPObject()
364 : : {
365 [ + + ][ + - ]: 232 : delete pOutput;
366 [ + - ][ + - ]: 232 : delete pSaveData;
367 [ + - ][ + - ]: 232 : delete pSheetDesc;
368 [ - + ]: 232 : delete pImpDesc;
369 [ - + ]: 232 : delete pServDesc;
370 [ + - ]: 232 : ClearTableData();
371 : 232 : }
372 : :
373 : 234 : void ScDPObject::EnableGetPivotData(bool b)
374 : : {
375 : 234 : mbEnableGetPivotData = b;
376 : 234 : }
377 : :
378 : 83 : void ScDPObject::SetAlive(bool bSet)
379 : : {
380 : 83 : bAlive = bSet;
381 : 83 : }
382 : :
383 : 55 : void ScDPObject::SetAllowMove(bool bSet)
384 : : {
385 : 55 : bAllowMove = bSet;
386 : 55 : }
387 : :
388 : 90 : void ScDPObject::SetSaveData(const ScDPSaveData& rData)
389 : : {
390 [ + + ]: 90 : if ( pSaveData != &rData ) // API implementation modifies the original SaveData object
391 : : {
392 [ + + ]: 72 : delete pSaveData;
393 [ + - ]: 72 : pSaveData = new ScDPSaveData( rData );
394 : : }
395 : :
396 : 90 : InvalidateData(); // re-init source from SaveData
397 : 90 : }
398 : :
399 : 6 : void ScDPObject::SetHeaderLayout (bool bUseGrid)
400 : : {
401 : 6 : mbHeaderLayout = bUseGrid;
402 : 6 : }
403 : :
404 : 0 : bool ScDPObject::GetHeaderLayout() const
405 : : {
406 : 0 : return mbHeaderLayout;
407 : : }
408 : :
409 : 134 : void ScDPObject::SetOutRange(const ScRange& rRange)
410 : : {
411 : 134 : aOutRange = rRange;
412 : :
413 [ + + ]: 134 : if ( pOutput )
414 : 70 : pOutput->SetPosition( rRange.aStart );
415 : 134 : }
416 : :
417 : 92 : void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc)
418 : : {
419 [ + + ][ + - ]: 92 : if ( pSheetDesc && rDesc == *pSheetDesc )
[ - + ][ + - ]
420 : 92 : return; // nothing to do
421 : :
422 [ - + ]: 92 : DELETEZ( pImpDesc );
423 [ - + ]: 92 : DELETEZ( pServDesc );
424 : :
425 [ + + ][ + - ]: 92 : delete pSheetDesc;
426 [ + - ][ + - ]: 92 : pSheetDesc = new ScSheetSourceDesc(rDesc);
427 : :
428 : : // make valid QueryParam
429 : :
430 [ + - ]: 92 : const ScRange& rSrcRange = pSheetDesc->GetSourceRange();
431 [ + - ][ + - ]: 92 : ScQueryParam aParam = pSheetDesc->GetQueryParam();
432 : 92 : aParam.nCol1 = rSrcRange.aStart.Col();
433 : 92 : aParam.nRow1 = rSrcRange.aStart.Row();
434 : 92 : aParam.nCol2 = rSrcRange.aEnd.Col();
435 : 92 : aParam.nRow2 = rSrcRange.aEnd.Row();
436 : 92 : aParam.bHasHeader = true;
437 [ + - ]: 92 : pSheetDesc->SetQueryParam(aParam);
438 : :
439 [ + - ][ + - ]: 92 : ClearTableData(); // new source must be created
440 : : }
441 : :
442 : 0 : void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc)
443 : : {
444 [ # # ][ # # ]: 0 : if ( pImpDesc && rDesc == *pImpDesc )
[ # # ]
445 : 0 : return; // nothing to do
446 : :
447 [ # # ]: 0 : DELETEZ( pSheetDesc );
448 [ # # ]: 0 : DELETEZ( pServDesc );
449 : :
450 [ # # ]: 0 : delete pImpDesc;
451 : 0 : pImpDesc = new ScImportSourceDesc(rDesc);
452 : :
453 : 0 : ClearTableData(); // new source must be created
454 : : }
455 : :
456 : 0 : void ScDPObject::SetServiceData(const ScDPServiceDesc& rDesc)
457 : : {
458 [ # # ][ # # ]: 0 : if ( pServDesc && rDesc == *pServDesc )
[ # # ]
459 : 0 : return; // nothing to do
460 : :
461 [ # # ]: 0 : DELETEZ( pSheetDesc );
462 [ # # ]: 0 : DELETEZ( pImpDesc );
463 : :
464 [ # # ]: 0 : delete pServDesc;
465 : 0 : pServDesc = new ScDPServiceDesc(rDesc);
466 : :
467 : 0 : ClearTableData(); // new source must be created
468 : : }
469 : :
470 : 0 : void ScDPObject::WriteSourceDataTo( ScDPObject& rDest ) const
471 : : {
472 [ # # ]: 0 : if ( pSheetDesc )
473 : 0 : rDest.SetSheetDesc( *pSheetDesc );
474 [ # # ]: 0 : else if ( pImpDesc )
475 : 0 : rDest.SetImportDesc( *pImpDesc );
476 [ # # ]: 0 : else if ( pServDesc )
477 : 0 : rDest.SetServiceData( *pServDesc );
478 : :
479 : : // name/tag are not source data, but needed along with source data
480 : :
481 : 0 : rDest.aTableName = aTableName;
482 : 0 : rDest.aTableTag = aTableTag;
483 : 0 : }
484 : :
485 : 0 : void ScDPObject::WriteTempDataTo( ScDPObject& rDest ) const
486 : : {
487 : 0 : rDest.nHeaderRows = nHeaderRows;
488 : 0 : }
489 : :
490 : 235 : bool ScDPObject::IsSheetData() const
491 : : {
492 : 235 : return ( pSheetDesc != NULL );
493 : : }
494 : :
495 : 72 : void ScDPObject::SetName(const OUString& rNew)
496 : : {
497 : 72 : aTableName = rNew;
498 : 72 : }
499 : :
500 : 29 : void ScDPObject::SetTag(const OUString& rNew)
501 : : {
502 : 29 : aTableTag = rNew;
503 : 29 : }
504 : :
505 : 0 : bool ScDPObject::IsDataDescriptionCell(const ScAddress& rPos)
506 : : {
507 [ # # ]: 0 : if (!pSaveData)
508 : 0 : return false;
509 : :
510 [ # # ]: 0 : long nDataDimCount = pSaveData->GetDataDimensionCount();
511 [ # # ]: 0 : if (nDataDimCount != 1)
512 : : // There has to be exactly one data dimension for the description to
513 : : // appear at top-left corner.
514 : 0 : return false;
515 : :
516 [ # # ]: 0 : CreateOutput();
517 [ # # ]: 0 : ScRange aTabRange = pOutput->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE);
518 : 0 : return (rPos == aTabRange.aStart);
519 : : }
520 : :
521 : 440 : uno::Reference<sheet::XDimensionsSupplier> ScDPObject::GetSource()
522 : : {
523 : 440 : CreateObjects();
524 : 440 : return xSource;
525 : : }
526 : :
527 : 969 : void ScDPObject::CreateOutput()
528 : : {
529 : 969 : CreateObjects();
530 [ + + ]: 969 : if (!pOutput)
531 : : {
532 [ + - ][ + - ]: 140 : sal_Bool bFilterButton = IsSheetData() && pSaveData && pSaveData->GetFilterButton();
[ + + ]
533 [ + - ]: 140 : pOutput = new ScDPOutput( pDoc, xSource, aOutRange.aStart, bFilterButton );
534 : 140 : pOutput->SetHeaderLayout ( mbHeaderLayout );
535 : :
536 : 140 : long nOldRows = nHeaderRows;
537 : 140 : nHeaderRows = pOutput->GetHeaderRows();
538 : :
539 [ # # ][ - + ]: 140 : if ( bAllowMove && nHeaderRows != nOldRows )
540 : : {
541 : 0 : long nDiff = nOldRows - nHeaderRows;
542 [ # # ]: 0 : if ( nOldRows == 0 )
543 : 0 : --nDiff;
544 [ # # ]: 0 : if ( nHeaderRows == 0 )
545 : 0 : ++nDiff;
546 : :
547 : 0 : long nNewRow = aOutRange.aStart.Row() + nDiff;
548 [ # # ]: 0 : if ( nNewRow < 0 )
549 : 0 : nNewRow = 0;
550 : :
551 : 0 : ScAddress aStart( aOutRange.aStart );
552 : 0 : aStart.SetRow(nNewRow);
553 [ # # ]: 0 : pOutput->SetPosition( aStart );
554 : :
555 : : //! modify aOutRange?
556 : :
557 : 0 : bAllowMove = false; // use only once
558 : : }
559 : : }
560 : 969 : }
561 : :
562 : : namespace {
563 : :
564 : : class DisableGetPivotData
565 : : {
566 : : ScDPObject& mrDPObj;
567 : : bool mbOldState;
568 : : public:
569 : 117 : DisableGetPivotData(ScDPObject& rObj, bool bOld) : mrDPObj(rObj), mbOldState(bOld)
570 : : {
571 : 117 : mrDPObj.EnableGetPivotData(false);
572 : 117 : }
573 : :
574 : 117 : ~DisableGetPivotData()
575 : : {
576 : 117 : mrDPObj.EnableGetPivotData(mbOldState);
577 : 117 : }
578 : : };
579 : :
580 : : }
581 : :
582 : 179 : ScDPTableData* ScDPObject::GetTableData()
583 : : {
584 [ + + ]: 179 : if (!mpTableData)
585 : : {
586 [ + - ]: 117 : shared_ptr<ScDPTableData> pData;
587 : 117 : const ScDPDimensionSaveData* pDimData = NULL;
588 [ + - ]: 117 : if (pSaveData)
589 : 117 : pDimData = pSaveData->GetExistingDimensionData();
590 : :
591 [ - + ]: 117 : if ( pImpDesc )
592 : : {
593 : : // database data
594 [ # # ]: 0 : const ScDPCache* pCache = pImpDesc->CreateCache(pDimData);
595 [ # # ]: 0 : if (pCache)
596 : : {
597 [ # # ]: 0 : pCache->AddReference(this);
598 [ # # ][ # # ]: 0 : pData.reset(new ScDatabaseDPData(pDoc, *pImpDesc, pCache));
[ # # ]
599 : : }
600 : : }
601 : : else
602 : : {
603 : : // cell data
604 [ - + ]: 117 : if (!pSheetDesc)
605 : : {
606 : : OSL_FAIL("no source descriptor");
607 [ # # ][ # # ]: 0 : pSheetDesc = new ScSheetSourceDesc(pDoc); // dummy defaults
608 : : }
609 : :
610 : : {
611 : : // Temporarily disable GETPIVOTDATA to avoid having
612 : : // GETPIVOTDATA called onto itself from within the source
613 : : // range.
614 [ + - ]: 117 : DisableGetPivotData aSwitch(*this, mbEnableGetPivotData);
615 [ + - ]: 117 : const ScDPCache* pCache = pSheetDesc->CreateCache(pDimData);
616 [ + - ]: 117 : if (pCache)
617 : : {
618 [ + - ]: 117 : pCache->AddReference(this);
619 [ + - ][ + - ]: 117 : pData.reset(new ScSheetDPData(pDoc, *pSheetDesc, pCache));
[ + - ]
620 [ + - ]: 117 : }
621 : : }
622 : : }
623 : :
624 : : // grouping (for cell or database data)
625 [ + - ][ + + ]: 117 : if (pData && pDimData)
[ + + ]
626 : : {
627 [ + - ][ + - ]: 6 : shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(pData, pDoc));
[ + - ]
628 [ + - ]: 6 : pDimData->WriteToData(*pGroupData);
629 [ + - ][ + - ]: 6 : pData = pGroupData;
630 : : }
631 : :
632 [ + - ][ + - ]: 117 : mpTableData = pData; // after SetCacheId
633 : : }
634 : :
635 : 179 : return mpTableData.get();
636 : : }
637 : :
638 : 1412 : void ScDPObject::CreateObjects()
639 : : {
640 [ + + ]: 1412 : if (!xSource.is())
641 : : {
642 : : //! cache DPSource and/or Output?
643 : :
644 : : OSL_ENSURE( bAlive, "CreateObjects on non-inserted DPObject" );
645 : :
646 [ + + ]: 171 : DELETEZ( pOutput ); // not valid when xSource is changed
647 : :
648 [ - + ]: 171 : if ( pServDesc )
649 : : {
650 [ # # ]: 0 : xSource = CreateSource( *pServDesc );
651 : : }
652 : :
653 [ + - ]: 171 : if ( !xSource.is() ) // database or sheet data, or error in CreateSource
654 : : {
655 : : OSL_ENSURE( !pServDesc, "DPSource could not be created" );
656 : 171 : ScDPTableData* pData = GetTableData();
657 [ + - ]: 171 : if (pData)
658 : : {
659 [ + - ]: 171 : if (pSaveData)
660 : : // Make sure to transfer these flags to the table data
661 : : // since they may have changed.
662 : 171 : pData->SetEmptyFlags(pSaveData->GetIgnoreEmptyRows(), pSaveData->GetRepeatIfEmpty());
663 : :
664 : 171 : pData->ReloadCacheTable();
665 [ + - # # ]: 171 : ScDPSource* pSource = new ScDPSource( pData );
666 [ + - ]: 171 : xSource = pSource;
667 : : }
668 : : }
669 : :
670 [ + - ]: 171 : if (pSaveData)
671 : 171 : pSaveData->WriteToSource( xSource );
672 : : }
673 [ + + ]: 1241 : else if (bSettingsChanged)
674 : : {
675 [ + - ][ + - ]: 6 : DELETEZ( pOutput ); // not valid when xSource is changed
676 : :
677 [ + - ]: 6 : uno::Reference<util::XRefreshable> xRef( xSource, uno::UNO_QUERY );
678 [ + - ]: 6 : if (xRef.is())
679 : : {
680 : : try
681 : : {
682 [ + - ][ + - ]: 6 : xRef->refresh();
683 : : }
684 [ # # ]: 0 : catch(uno::Exception&)
685 : : {
686 : : OSL_FAIL("exception in refresh");
687 : : }
688 : : }
689 : :
690 [ + - ]: 6 : if (pSaveData)
691 [ + - ]: 6 : pSaveData->WriteToSource( xSource );
692 : : }
693 : 1412 : bSettingsChanged = false;
694 : 1412 : }
695 : :
696 : 206 : void ScDPObject::InvalidateData()
697 : : {
698 : 206 : bSettingsChanged = true;
699 : 206 : }
700 : :
701 : 353 : void ScDPObject::ClearTableData()
702 : : {
703 : 353 : ClearSource();
704 : :
705 [ + + ]: 353 : if (mpTableData)
706 : 117 : mpTableData->GetCacheTable().getCache()->RemoveReference(this);
707 : 353 : mpTableData.reset();
708 : 353 : }
709 : :
710 : 89 : void ScDPObject::ReloadGroupTableData()
711 : : {
712 : 89 : ClearSource();
713 : :
714 [ + + ]: 89 : if (!mpTableData)
715 : : // Table data not built yet. No need to reload the group data.
716 : 31 : return;
717 : :
718 [ - + ]: 58 : if (!pSaveData)
719 : : // How could it not have the save data... but whatever.
720 : 0 : return;
721 : :
722 : 58 : const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData();
723 [ - + ][ + + ]: 58 : if (!pDimData || !pDimData->HasGroupDimensions())
[ + + ]
724 : : // No group dimensions exist.
725 : 44 : return;
726 : :
727 [ - + ]: 14 : ScDPGroupTableData* pData = dynamic_cast<ScDPGroupTableData*>(mpTableData.get());
728 [ + + ]: 14 : if (pData)
729 : : {
730 : : // This is already a group table data. Salvage the source data and
731 : : // re-create a new group data.
732 [ + - ]: 6 : shared_ptr<ScDPTableData> pSource = pData->GetSourceTableData();
733 [ + - ][ + - ]: 6 : shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(pSource, pDoc));
[ + - ]
734 [ + - ]: 6 : pDimData->WriteToData(*pGroupData);
735 [ + - ][ + - ]: 6 : mpTableData = pGroupData;
[ + - ]
736 : : }
737 : : else
738 : : {
739 : : // This is a source data. Create a group data based on it.
740 [ + - ][ + - ]: 8 : shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(mpTableData, pDoc));
[ + - ]
741 [ + - ]: 8 : pDimData->WriteToData(*pGroupData);
742 [ + - ][ + - ]: 8 : mpTableData = pGroupData;
743 : : }
744 : :
745 : 89 : bSettingsChanged = true;
746 : : }
747 : :
748 : 442 : void ScDPObject::ClearSource()
749 : : {
750 [ + - ]: 442 : Reference< XComponent > xObjectComp( xSource, UNO_QUERY );
751 [ - + ]: 442 : if (xObjectComp.is())
752 : : {
753 : : try
754 : : {
755 [ # # ][ # # ]: 0 : xObjectComp->dispose();
756 : : }
757 [ # # ]: 0 : catch( const Exception& )
758 : : {
759 : : DBG_UNHANDLED_EXCEPTION();
760 : : }
761 : : }
762 [ + - ]: 442 : xSource = NULL;
763 [ # # ]: 442 : }
764 : :
765 : 134 : ScRange ScDPObject::GetNewOutputRange( bool& rOverflow )
766 : : {
767 : 134 : CreateOutput(); // create xSource and pOutput if not already done
768 : :
769 : 134 : rOverflow = pOutput->HasError(); // range overflow or exception from source
770 [ - + ]: 134 : if ( rOverflow )
771 : 0 : return ScRange( aOutRange.aStart );
772 : : else
773 : : {
774 : : // don't store the result in aOutRange, because nothing has been output yet
775 : 134 : return pOutput->GetOutputRange();
776 : : }
777 : : }
778 : :
779 : 140 : void ScDPObject::Output( const ScAddress& rPos )
780 : : {
781 : : // clear old output area
782 : 140 : pDoc->DeleteAreaTab( aOutRange.aStart.Col(), aOutRange.aStart.Row(),
783 : 140 : aOutRange.aEnd.Col(), aOutRange.aEnd.Row(),
784 : 420 : aOutRange.aStart.Tab(), IDF_ALL );
785 : 140 : pDoc->RemoveFlagsTab( aOutRange.aStart.Col(), aOutRange.aStart.Row(),
786 : 140 : aOutRange.aEnd.Col(), aOutRange.aEnd.Row(),
787 : 420 : aOutRange.aStart.Tab(), SC_MF_AUTO );
788 : :
789 : 140 : CreateOutput(); // create xSource and pOutput if not already done
790 : :
791 : 140 : pOutput->SetPosition( rPos );
792 : :
793 : 140 : pOutput->Output();
794 : :
795 : : // aOutRange is always the range that was last output to the document
796 : 140 : aOutRange = pOutput->GetOutputRange();
797 : 140 : const ScAddress& s = aOutRange.aStart;
798 : 140 : const ScAddress& e = aOutRange.aEnd;
799 : 140 : pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
800 : 140 : }
801 : :
802 : 27 : const ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType )
803 : : {
804 : 27 : CreateOutput();
805 : :
806 [ - + ]: 27 : if (pOutput->HasError())
807 : 0 : return ScRange(aOutRange.aStart);
808 : :
809 : 27 : return pOutput->GetOutputRange(nType);
810 : : }
811 : :
812 : 14 : sal_Bool lcl_HasButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
813 : : {
814 : 14 : return ((const ScMergeFlagAttr*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->HasButton();
815 : : }
816 : :
817 : 6 : void ScDPObject::RefreshAfterLoad()
818 : : {
819 : : // apply drop-down attribute, initialize nHeaderRows, without accessing the source
820 : : // (button attribute must be present)
821 : :
822 : : // simple test: block of button cells at the top, followed by an empty cell
823 : :
824 : 6 : SCCOL nFirstCol = aOutRange.aStart.Col();
825 : 6 : SCROW nFirstRow = aOutRange.aStart.Row();
826 : 6 : SCTAB nTab = aOutRange.aStart.Tab();
827 : :
828 : 6 : SCROW nInitial = 0;
829 : 6 : SCROW nOutRows = aOutRange.aEnd.Row() + 1 - aOutRange.aStart.Row();
830 [ + - ][ + + ]: 14 : while ( nInitial + 1 < nOutRows && lcl_HasButton( pDoc, nFirstCol, nFirstRow + nInitial, nTab ) )
[ + + ]
831 : 8 : ++nInitial;
832 : :
833 [ + - + - : 18 : if ( nInitial + 1 < nOutRows &&
+ + ][ + + ]
834 : 6 : pDoc->IsBlockEmpty( nTab, nFirstCol, nFirstRow + nInitial, nFirstCol, nFirstRow + nInitial ) &&
835 : 6 : aOutRange.aEnd.Col() > nFirstCol )
836 : : {
837 : 4 : sal_Bool bFilterButton = IsSheetData(); // when available, filter button setting must be checked here
838 : :
839 [ + - ]: 4 : SCROW nSkip = bFilterButton ? 1 : 0;
840 [ + + ]: 6 : for (SCROW nPos=nSkip; nPos<nInitial; nPos++)
841 [ + - ]: 2 : pDoc->ApplyAttr( nFirstCol + 1, nFirstRow + nPos, nTab, ScMergeFlagAttr(SC_MF_AUTO) );
842 : :
843 : 4 : nHeaderRows = nInitial;
844 : : }
845 : : else
846 : 2 : nHeaderRows = 0; // nothing found, no drop-down lists
847 : 6 : }
848 : :
849 : 0 : void ScDPObject::BuildAllDimensionMembers()
850 : : {
851 [ # # ]: 0 : if (!pSaveData)
852 : 0 : return;
853 : :
854 : : // #i111857# don't always create empty mpTableData for external service.
855 : : // Ideally, xSource should be used instead of mpTableData.
856 [ # # ]: 0 : if (pServDesc)
857 : 0 : return;
858 : :
859 : 0 : pSaveData->BuildAllDimensionMembers(GetTableData());
860 : : }
861 : :
862 : 8 : void ScDPObject::SyncAllDimensionMembers()
863 : : {
864 [ - + ]: 8 : if (!pSaveData)
865 : 0 : return;
866 : :
867 : : // #i111857# don't always create empty mpTableData for external service.
868 : : // Ideally, xSource should be used instead of mpTableData.
869 [ - + ]: 8 : if (pServDesc)
870 : 0 : return;
871 : :
872 : 8 : ScDPTableData* pData = GetTableData();
873 : : // Refresh the cache wrapper since the cache may have changed.
874 : 8 : pData->SetEmptyFlags(pSaveData->GetIgnoreEmptyRows(), pSaveData->GetRepeatIfEmpty());
875 : 8 : pData->ReloadCacheTable();
876 : 8 : pSaveData->SyncAllDimensionMembers(pData);
877 : : }
878 : :
879 : 3 : bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence<OUString>& rNames )
880 : : {
881 [ + - ]: 3 : vector<ScDPLabelData::Member> aMembers;
882 [ + - ][ + - ]: 3 : if (!GetMembers(nDim, GetUsedHierarchy(nDim), aMembers))
[ - + ]
883 : 0 : return false;
884 : :
885 : 3 : size_t n = aMembers.size();
886 [ + - ]: 3 : rNames.realloc(n);
887 [ + + ]: 18 : for (size_t i = 0; i < n; ++i)
888 [ + - ]: 15 : rNames[i] = aMembers[i].maName;
889 : :
890 : 3 : return true;
891 : : }
892 : :
893 : 12 : bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelData::Member>& rMembers )
894 : : {
895 : 12 : Reference< container::XNameAccess > xMembersNA;
896 [ - + ][ + - ]: 12 : if (!GetMembersNA( nDim, nHier, xMembersNA ))
897 : 0 : return false;
898 : :
899 [ + - ][ + - ]: 12 : Reference<container::XIndexAccess> xMembersIA( new ScNameToIndexAccess(xMembersNA) );
[ + - ]
900 [ + - ][ + - ]: 12 : sal_Int32 nCount = xMembersIA->getCount();
901 [ + - ]: 12 : vector<ScDPLabelData::Member> aMembers;
902 [ + - ]: 12 : aMembers.reserve(nCount);
903 : :
904 [ + + ]: 93 : for (sal_Int32 i = 0; i < nCount; ++i)
905 : : {
906 [ + - ][ + - ]: 81 : Reference<container::XNamed> xMember(xMembersIA->getByIndex(i), UNO_QUERY);
[ + - ]
907 [ + - ]: 81 : ScDPLabelData::Member aMem;
908 : :
909 [ + - ]: 81 : if (xMember.is())
910 [ + - ][ + - ]: 81 : aMem.maName = xMember->getName();
911 : :
912 [ + - ]: 81 : Reference<beans::XPropertySet> xMemProp(xMember, UNO_QUERY);
913 [ + - ]: 81 : if (xMemProp.is())
914 : : {
915 [ + - ][ + - ]: 81 : aMem.mbVisible = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISVISIBLE)));
916 [ + - ][ + - ]: 81 : aMem.mbShowDetails = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_SHOWDETAILS)));
917 : :
918 : : aMem.maLayoutName = ScUnoHelpFunctions::GetStringProperty(
919 [ + - ][ + - ]: 81 : xMemProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_LAYOUTNAME)), OUString());
920 : : }
921 : :
922 [ + - ]: 81 : aMembers.push_back(aMem);
923 : 81 : }
924 : 12 : rMembers.swap(aMembers);
925 : 12 : return true;
926 : : }
927 : :
928 : 70 : void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
929 : : const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
930 : : {
931 : : // Output area
932 : :
933 : 70 : SCCOL nCol1 = aOutRange.aStart.Col();
934 : 70 : SCROW nRow1 = aOutRange.aStart.Row();
935 : 70 : SCTAB nTab1 = aOutRange.aStart.Tab();
936 : 70 : SCCOL nCol2 = aOutRange.aEnd.Col();
937 : 70 : SCROW nRow2 = aOutRange.aEnd.Row();
938 : 70 : SCTAB nTab2 = aOutRange.aEnd.Tab();
939 : :
940 : : ScRefUpdateRes eRes =
941 : : ScRefUpdate::Update( pDoc, eUpdateRefMode,
942 : 140 : rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
943 : 140 : rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
944 [ + - ]: 210 : nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
945 [ + - ]: 70 : if ( eRes != UR_NOTHING )
946 [ + - ]: 70 : SetOutRange( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
947 : :
948 : : // sheet source data
949 : :
950 [ + - ]: 70 : if ( pSheetDesc )
951 : : {
952 [ + - ]: 70 : const OUString& rRangeName = pSheetDesc->GetRangeName();
953 [ + + ]: 70 : if (!rRangeName.isEmpty())
954 : : // Source range is a named range. No need to update.
955 : 70 : return;
956 : :
957 [ + - ]: 67 : const ScRange& rSrcRange = pSheetDesc->GetSourceRange();
958 : 67 : nCol1 = rSrcRange.aStart.Col();
959 : 67 : nRow1 = rSrcRange.aStart.Row();
960 : 67 : nTab1 = rSrcRange.aStart.Tab();
961 : 67 : nCol2 = rSrcRange.aEnd.Col();
962 : 67 : nRow2 = rSrcRange.aEnd.Row();
963 : 67 : nTab2 = rSrcRange.aEnd.Tab();
964 : :
965 : : eRes = ScRefUpdate::Update( pDoc, eUpdateRefMode,
966 : 134 : rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
967 : 134 : rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
968 [ + - ]: 201 : nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
969 [ + - ]: 67 : if ( eRes != UR_NOTHING )
970 : : {
971 [ + - ]: 67 : SCsCOL nDiffX = nCol1 - pSheetDesc->GetSourceRange().aStart.Col();
972 [ + - ]: 67 : SCsROW nDiffY = nRow1 - pSheetDesc->GetSourceRange().aStart.Row();
973 : :
974 [ + - ][ + - ]: 67 : ScQueryParam aParam = pSheetDesc->GetQueryParam();
975 : 67 : aParam.nCol1 = sal::static_int_cast<SCCOL>( aParam.nCol1 + nDiffX );
976 : 67 : aParam.nCol2 = sal::static_int_cast<SCCOL>( aParam.nCol2 + nDiffX );
977 : 67 : aParam.nRow1 += nDiffY; //! used?
978 : 67 : aParam.nRow2 += nDiffY; //! used?
979 [ + - ]: 67 : SCSIZE nEC = aParam.GetEntryCount();
980 [ + + ]: 603 : for (SCSIZE i=0; i<nEC; i++)
981 [ + - ][ + + ]: 536 : if (aParam.GetEntry(i).bDoQuery)
982 [ + - ]: 64 : aParam.GetEntry(i).nField += nDiffX;
983 : :
984 [ + - ]: 67 : pSheetDesc->SetQueryParam(aParam);
985 [ + - ][ + - ]: 70 : pSheetDesc->SetSourceRange(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
986 : : }
987 : : }
988 : : }
989 : :
990 : 0 : bool ScDPObject::RefsEqual( const ScDPObject& r ) const
991 : : {
992 [ # # ]: 0 : if ( aOutRange != r.aOutRange )
993 : 0 : return false;
994 : :
995 [ # # ][ # # ]: 0 : if ( pSheetDesc && r.pSheetDesc )
996 : : {
997 [ # # ]: 0 : if ( pSheetDesc->GetSourceRange() != r.pSheetDesc->GetSourceRange() )
998 : 0 : return false;
999 : : }
1000 [ # # ][ # # ]: 0 : else if ( pSheetDesc || r.pSheetDesc )
1001 : : {
1002 : : OSL_FAIL("RefsEqual: SheetDesc set at only one object");
1003 : 0 : return false;
1004 : : }
1005 : :
1006 : 0 : return true;
1007 : : }
1008 : :
1009 : 0 : void ScDPObject::WriteRefsTo( ScDPObject& r ) const
1010 : : {
1011 : 0 : r.SetOutRange( aOutRange );
1012 [ # # ]: 0 : if ( pSheetDesc )
1013 : 0 : r.SetSheetDesc( *pSheetDesc );
1014 : 0 : }
1015 : :
1016 : 388 : void ScDPObject::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
1017 : : {
1018 : 388 : CreateOutput();
1019 : 388 : pOutput->GetPositionData(rPos, rPosData);
1020 : 388 : }
1021 : :
1022 : 158 : bool ScDPObject::GetDataFieldPositionData(
1023 : : const ScAddress& rPos, Sequence<sheet::DataPilotFieldFilter>& rFilters)
1024 : : {
1025 [ + - ]: 158 : CreateOutput();
1026 : :
1027 [ + - ]: 158 : vector<sheet::DataPilotFieldFilter> aFilters;
1028 [ + - ][ - + ]: 158 : if (!pOutput->GetDataResultPositionData(aFilters, rPos))
1029 : 0 : return false;
1030 : :
1031 : 158 : sal_Int32 n = static_cast<sal_Int32>(aFilters.size());
1032 [ + - ]: 158 : rFilters.realloc(n);
1033 [ + + ]: 718 : for (sal_Int32 i = 0; i < n; ++i)
1034 [ + - ]: 560 : rFilters[i] = aFilters[i];
1035 : :
1036 : 158 : return true;
1037 : : }
1038 : :
1039 : 122 : void ScDPObject::GetDrillDownData(const ScAddress& rPos, Sequence< Sequence<Any> >& rTableData)
1040 : : {
1041 [ + - ]: 122 : CreateOutput();
1042 : :
1043 [ + - ]: 122 : Reference<sheet::XDrillDownDataSupplier> xDrillDownData(xSource, UNO_QUERY);
1044 [ - + ]: 122 : if (!xDrillDownData.is())
1045 : : return;
1046 : :
1047 [ + - ]: 122 : Sequence<sheet::DataPilotFieldFilter> filters;
1048 [ + - ][ - + ]: 122 : if (!GetDataFieldPositionData(rPos, filters))
1049 : : return;
1050 : :
1051 [ + - ][ + - ]: 122 : rTableData = xDrillDownData->getDrillDownData(filters);
[ + - ][ + - ]
[ + - ][ - + ]
[ + - ]
1052 : : }
1053 : :
1054 : 26 : bool ScDPObject::IsDimNameInUse(const OUString& rName) const
1055 : : {
1056 [ + + ]: 26 : if (!xSource.is())
1057 : 6 : return false;
1058 : :
1059 [ + - ][ + - ]: 20 : Reference<container::XNameAccess> xDims = xSource->getDimensions();
1060 [ + - ][ + - ]: 20 : Sequence<OUString> aDimNames = xDims->getElementNames();
1061 : 20 : sal_Int32 n = aDimNames.getLength();
1062 [ + + ]: 96 : for (sal_Int32 i = 0; i < n; ++i)
1063 : : {
1064 [ + - ]: 86 : const OUString& rDimName = aDimNames[i];
1065 [ + + ]: 86 : if (rDimName.equalsIgnoreAsciiCase(rName))
1066 : 8 : return true;
1067 : :
1068 [ + - ][ + - ]: 78 : Reference<beans::XPropertySet> xPropSet(xDims->getByName(rDimName), UNO_QUERY);
[ + - ]
1069 [ - + ]: 78 : if (!xPropSet.is())
1070 : 0 : continue;
1071 : :
1072 : : OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
1073 [ + - ][ + - ]: 78 : xPropSet, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_LAYOUTNAME)), OUString());
1074 [ + + ]: 78 : if (aLayoutName.equalsIgnoreAsciiCase(rName))
1075 : 78 : return true;
1076 [ + + ]: 86 : }
[ + + - ]
1077 [ + - ]: 26 : return false;
1078 : : }
1079 : :
1080 : 63 : OUString ScDPObject::GetDimName( long nDim, bool& rIsDataLayout, sal_Int32* pFlags )
1081 : : {
1082 : 63 : rIsDataLayout = false;
1083 : 63 : OUString aRet;
1084 : :
1085 [ + - ]: 63 : if ( xSource.is() )
1086 : : {
1087 [ + - ][ + - ]: 63 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1088 [ + - ][ + - ]: 63 : uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
[ + - ]
1089 [ + - ][ + - ]: 63 : long nDimCount = xDims->getCount();
1090 [ + - ]: 63 : if ( nDim < nDimCount )
1091 : : {
1092 : : uno::Reference<uno::XInterface> xIntDim =
1093 [ + - ][ + - ]: 63 : ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
[ + - ]
1094 [ + - ]: 63 : uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
1095 [ + - ]: 63 : uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
1096 [ + - ][ + - ]: 63 : if ( xDimName.is() && xDimProp.is() )
[ + - ]
1097 : : {
1098 : : sal_Bool bData = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1099 [ + - ][ + - ]: 63 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISDATALAYOUT)) );
[ # # ]
1100 : : //! error checking -- is "IsDataLayoutDimension" property required??
1101 : :
1102 : 63 : rtl::OUString aName;
1103 : : try
1104 : : {
1105 [ + - ][ + - ]: 63 : aName = xDimName->getName();
1106 : : }
1107 [ # # ]: 0 : catch(uno::Exception&)
1108 : : {
1109 : : }
1110 [ - + ]: 63 : if ( bData )
1111 : 0 : rIsDataLayout = true;
1112 : : else
1113 : 63 : aRet = aName;
1114 : :
1115 [ - + ]: 63 : if (pFlags)
1116 : : *pFlags = ScUnoHelpFunctions::GetLongProperty( xDimProp,
1117 [ # # ][ # # ]: 63 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_FLAGS)), 0 );
1118 : 63 : }
1119 : 63 : }
1120 : : }
1121 : :
1122 : 63 : return aRet;
1123 : : }
1124 : :
1125 : 0 : bool ScDPObject::IsDuplicated( long nDim )
1126 : : {
1127 : 0 : bool bDuplicated = false;
1128 [ # # ]: 0 : if ( xSource.is() )
1129 : : {
1130 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1131 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
[ # # ]
1132 [ # # ][ # # ]: 0 : long nDimCount = xDims->getCount();
1133 [ # # ]: 0 : if ( nDim < nDimCount )
1134 : : {
1135 : : uno::Reference<uno::XInterface> xIntDim =
1136 [ # # ][ # # ]: 0 : ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
[ # # ]
1137 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
1138 [ # # ]: 0 : if ( xDimProp.is() )
1139 : : {
1140 : : try
1141 : : {
1142 [ # # ]: 0 : uno::Any aOrigAny = xDimProp->getPropertyValue(
1143 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ORIGINAL)) );
1144 : 0 : uno::Reference<uno::XInterface> xIntOrig;
1145 [ # # ][ # # ]: 0 : if ( (aOrigAny >>= xIntOrig) && xIntOrig.is() )
[ # # ][ # # ]
1146 [ # # ]: 0 : bDuplicated = true;
1147 : : }
1148 [ # # ]: 0 : catch(uno::Exception&)
1149 : : {
1150 : : }
1151 : 0 : }
1152 : 0 : }
1153 : : }
1154 : 0 : return bDuplicated;
1155 : : }
1156 : :
1157 : 63 : long ScDPObject::GetDimCount()
1158 : : {
1159 : 63 : long nRet = 0;
1160 [ + - ]: 63 : if ( xSource.is() )
1161 : : {
1162 : : try
1163 : : {
1164 [ + - ][ + - ]: 63 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1165 [ + - ]: 63 : if ( xDimsName.is() )
1166 [ + - ][ + - ]: 63 : nRet = xDimsName->getElementNames().getLength();
[ + - ][ # # ]
1167 : : }
1168 : 0 : catch(uno::Exception&)
1169 : : {
1170 : : }
1171 : : }
1172 : 63 : return nRet;
1173 : : }
1174 : :
1175 : 0 : void ScDPObject::FillPageList( std::vector<rtl::OUString>& rStrings, long nField )
1176 : : {
1177 : : //! merge members access with ToggleDetails?
1178 : :
1179 : : //! convert field index to dimension index?
1180 : :
1181 : : OSL_ENSURE( xSource.is(), "no source" );
1182 [ # # ]: 0 : if ( !xSource.is() ) return;
1183 : :
1184 : 0 : uno::Reference<container::XNamed> xDim;
1185 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1186 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
[ # # ]
1187 [ # # ][ # # ]: 0 : long nIntCount = xIntDims->getCount();
1188 [ # # ]: 0 : if ( nField < nIntCount )
1189 : : {
1190 : : uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface(
1191 [ # # ][ # # ]: 0 : xIntDims->getByIndex(nField) );
[ # # ]
1192 [ # # ][ # # ]: 0 : xDim = uno::Reference<container::XNamed>( xIntDim, uno::UNO_QUERY );
1193 : : }
1194 : : OSL_ENSURE( xDim.is(), "dimension not found" );
1195 [ # # ]: 0 : if ( !xDim.is() ) return;
1196 : :
1197 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1198 : : long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
1199 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_USEDHIERARCHY)) );
1200 : 0 : long nLevel = 0;
1201 : :
1202 : 0 : long nHierCount = 0;
1203 : 0 : uno::Reference<container::XIndexAccess> xHiers;
1204 [ # # ]: 0 : uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
1205 [ # # ]: 0 : if ( xHierSupp.is() )
1206 : : {
1207 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
1208 [ # # ][ # # ]: 0 : xHiers = new ScNameToIndexAccess( xHiersName );
[ # # ]
1209 [ # # ][ # # ]: 0 : nHierCount = xHiers->getCount();
1210 : : }
1211 : 0 : uno::Reference<uno::XInterface> xHier;
1212 [ # # ]: 0 : if ( nHierarchy < nHierCount )
1213 [ # # ][ # # ]: 0 : xHier = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHierarchy) );
[ # # ][ # # ]
1214 : : OSL_ENSURE( xHier.is(), "hierarchy not found" );
1215 [ # # ]: 0 : if ( !xHier.is() ) return;
1216 : :
1217 : 0 : long nLevCount = 0;
1218 : 0 : uno::Reference<container::XIndexAccess> xLevels;
1219 [ # # ]: 0 : uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHier, uno::UNO_QUERY );
1220 [ # # ]: 0 : if ( xLevSupp.is() )
1221 : : {
1222 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xLevsName = xLevSupp->getLevels();
1223 [ # # ][ # # ]: 0 : xLevels = new ScNameToIndexAccess( xLevsName );
[ # # ]
1224 [ # # ][ # # ]: 0 : nLevCount = xLevels->getCount();
1225 : : }
1226 : 0 : uno::Reference<uno::XInterface> xLevel;
1227 [ # # ]: 0 : if ( nLevel < nLevCount )
1228 [ # # ][ # # ]: 0 : xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(nLevel) );
[ # # ][ # # ]
1229 : : OSL_ENSURE( xLevel.is(), "level not found" );
1230 [ # # ]: 0 : if ( !xLevel.is() ) return;
1231 : :
1232 : 0 : uno::Reference<container::XNameAccess> xMembers;
1233 [ # # ]: 0 : uno::Reference<sheet::XMembersSupplier> xMbrSupp( xLevel, uno::UNO_QUERY );
1234 [ # # ]: 0 : if ( xMbrSupp.is() )
1235 [ # # ][ # # ]: 0 : xMembers = xMbrSupp->getMembers();
[ # # ]
1236 : : OSL_ENSURE( xMembers.is(), "members not found" );
1237 [ # # ]: 0 : if ( !xMembers.is() ) return;
1238 : :
1239 [ # # ][ # # ]: 0 : uno::Sequence<rtl::OUString> aNames = xMembers->getElementNames();
1240 : 0 : long nNameCount = aNames.getLength();
1241 : 0 : const rtl::OUString* pNameArr = aNames.getConstArray();
1242 [ # # ]: 0 : for (long nPos = 0; nPos < nNameCount; ++nPos)
1243 : : {
1244 : : // Make sure to insert only visible members.
1245 [ # # ][ # # ]: 0 : Reference<XPropertySet> xPropSet(xMembers->getByName(pNameArr[nPos]), UNO_QUERY);
[ # # ]
1246 : 0 : sal_Bool bVisible = false;
1247 [ # # ]: 0 : if (xPropSet.is())
1248 : : {
1249 [ # # ][ # # ]: 0 : Any any = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISVISIBLE)));
[ # # ]
1250 : 0 : any >>= bVisible;
1251 : : }
1252 : :
1253 [ # # ]: 0 : if (bVisible)
1254 : : {
1255 : : // use the order from getElementNames
1256 [ # # ]: 0 : rStrings.push_back(pNameArr[nPos]);
1257 : : }
1258 : 0 : }
1259 : :
1260 : : // add "-all-" entry to the top (unsorted)
1261 [ # # ][ # # ]: 0 : rStrings.insert(rStrings.begin(), SC_RESSTR(SCSTR_ALL));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1262 : : }
1263 : :
1264 : 0 : void ScDPObject::GetHeaderPositionData(const ScAddress& rPos, DataPilotTableHeaderData& rData)
1265 : : {
1266 : : using namespace ::com::sun::star::sheet::DataPilotTablePositionType;
1267 : :
1268 [ # # ]: 0 : CreateOutput(); // create xSource and pOutput if not already done
1269 : :
1270 : : // Reset member values to invalid state.
1271 : 0 : rData.Dimension = rData.Hierarchy = rData.Level = -1;
1272 : 0 : rData.Flags = 0;
1273 : :
1274 : 0 : DataPilotTablePositionData aPosData;
1275 [ # # ]: 0 : pOutput->GetPositionData(rPos, aPosData);
1276 : 0 : const sal_Int32 nPosType = aPosData.PositionType;
1277 [ # # ][ # # ]: 0 : if (nPosType == COLUMN_HEADER || nPosType == ROW_HEADER)
1278 [ # # ]: 0 : aPosData.PositionData >>= rData;
1279 : 0 : }
1280 : :
1281 : : // Returns sal_True on success and stores the result in rTarget
1282 : 0 : bool ScDPObject::GetPivotData( ScDPGetPivotDataField& rTarget,
1283 : : const std::vector< ScDPGetPivotDataField >& rFilters )
1284 : : {
1285 [ # # ]: 0 : if (!mbEnableGetPivotData)
1286 : 0 : return false;
1287 : :
1288 : 0 : CreateOutput(); // create xSource and pOutput if not already done
1289 : 0 : return pOutput->GetPivotData( rTarget, rFilters );
1290 : : }
1291 : :
1292 : 0 : bool ScDPObject::IsFilterButton( const ScAddress& rPos )
1293 : : {
1294 : 0 : CreateOutput(); // create xSource and pOutput if not already done
1295 : :
1296 : 0 : return pOutput->IsFilterButton( rPos );
1297 : : }
1298 : :
1299 : 0 : long ScDPObject::GetHeaderDim( const ScAddress& rPos, sal_uInt16& rOrient )
1300 : : {
1301 : 0 : CreateOutput(); // create xSource and pOutput if not already done
1302 : :
1303 : 0 : return pOutput->GetHeaderDim( rPos, rOrient );
1304 : : }
1305 : :
1306 : 0 : bool ScDPObject::GetHeaderDrag( const ScAddress& rPos, bool bMouseLeft, bool bMouseTop, long nDragDim,
1307 : : Rectangle& rPosRect, sal_uInt16& rOrient, long& rDimPos )
1308 : : {
1309 : 0 : CreateOutput(); // create xSource and pOutput if not already done
1310 : :
1311 : 0 : return pOutput->GetHeaderDrag( rPos, bMouseLeft, bMouseTop, nDragDim, rPosRect, rOrient, rDimPos );
1312 : : }
1313 : :
1314 : 0 : void ScDPObject::GetMemberResultNames(ScDPUniqueStringSet& rNames, long nDimension)
1315 : : {
1316 : 0 : CreateOutput(); // create xSource and pOutput if not already done
1317 : :
1318 : 0 : pOutput->GetMemberResultNames(rNames, nDimension); // used only with table data -> level not needed
1319 : 0 : }
1320 : :
1321 : 0 : bool lcl_Dequote( const String& rSource, xub_StrLen nStartPos, xub_StrLen& rEndPos, String& rResult )
1322 : : {
1323 : : // nStartPos has to point to opening quote
1324 : :
1325 : 0 : bool bRet = false;
1326 : 0 : const sal_Unicode cQuote = '\'';
1327 : :
1328 [ # # ]: 0 : if ( rSource.GetChar(nStartPos) == cQuote )
1329 : : {
1330 : 0 : rtl::OUStringBuffer aBuffer;
1331 : 0 : xub_StrLen nPos = nStartPos + 1;
1332 : 0 : const xub_StrLen nLen = rSource.Len();
1333 : :
1334 [ # # ]: 0 : while ( nPos < nLen )
1335 : : {
1336 : 0 : const sal_Unicode cNext = rSource.GetChar(nPos);
1337 [ # # ]: 0 : if ( cNext == cQuote )
1338 : : {
1339 [ # # ][ # # ]: 0 : if ( nPos+1 < nLen && rSource.GetChar(nPos+1) == cQuote )
[ # # ]
1340 : : {
1341 : : // double quote is used for an embedded quote
1342 [ # # ]: 0 : aBuffer.append( cNext ); // append one quote
1343 : 0 : ++nPos; // skip the next one
1344 : : }
1345 : : else
1346 : : {
1347 : : // end of quoted string
1348 [ # # ][ # # ]: 0 : rResult = aBuffer.makeStringAndClear();
1349 : 0 : rEndPos = nPos + 1; // behind closing quote
1350 : 0 : return true;
1351 : : }
1352 : : }
1353 : : else
1354 [ # # ]: 0 : aBuffer.append( cNext );
1355 : :
1356 : 0 : ++nPos;
1357 [ # # ]: 0 : }
1358 : : // no closing quote before the end of the string -> error (bRet still false)
1359 : : }
1360 : :
1361 : 0 : return bRet;
1362 : : }
1363 : :
1364 : : struct ScGetPivotDataFunctionEntry
1365 : : {
1366 : : const sal_Char* pName;
1367 : : sheet::GeneralFunction eFunc;
1368 : : };
1369 : :
1370 : 0 : bool lcl_ParseFunction( const String& rList, xub_StrLen nStartPos, xub_StrLen& rEndPos, sheet::GeneralFunction& rFunc )
1371 : : {
1372 : : static const ScGetPivotDataFunctionEntry aFunctions[] =
1373 : : {
1374 : : // our names
1375 : : { "Sum", sheet::GeneralFunction_SUM },
1376 : : { "Count", sheet::GeneralFunction_COUNT },
1377 : : { "Average", sheet::GeneralFunction_AVERAGE },
1378 : : { "Max", sheet::GeneralFunction_MAX },
1379 : : { "Min", sheet::GeneralFunction_MIN },
1380 : : { "Product", sheet::GeneralFunction_PRODUCT },
1381 : : { "CountNums", sheet::GeneralFunction_COUNTNUMS },
1382 : : { "StDev", sheet::GeneralFunction_STDEV },
1383 : : { "StDevp", sheet::GeneralFunction_STDEVP },
1384 : : { "Var", sheet::GeneralFunction_VAR },
1385 : : { "VarP", sheet::GeneralFunction_VARP },
1386 : : // compatibility names
1387 : : { "Count Nums", sheet::GeneralFunction_COUNTNUMS },
1388 : : { "StdDev", sheet::GeneralFunction_STDEV },
1389 : : { "StdDevp", sheet::GeneralFunction_STDEVP }
1390 : : };
1391 : :
1392 : 0 : const xub_StrLen nListLen = rList.Len();
1393 [ # # ][ # # ]: 0 : while ( nStartPos < nListLen && rList.GetChar(nStartPos) == ' ' )
[ # # ]
1394 : 0 : ++nStartPos;
1395 : :
1396 : 0 : bool bParsed = false;
1397 : 0 : bool bFound = false;
1398 [ # # ]: 0 : String aFuncStr;
1399 : 0 : xub_StrLen nFuncEnd = 0;
1400 [ # # ][ # # ]: 0 : if ( nStartPos < nListLen && rList.GetChar(nStartPos) == '\'' )
[ # # ]
1401 [ # # ]: 0 : bParsed = lcl_Dequote( rList, nStartPos, nFuncEnd, aFuncStr );
1402 : : else
1403 : : {
1404 [ # # ]: 0 : nFuncEnd = rList.Search( static_cast<sal_Unicode>(']'), nStartPos );
1405 [ # # ]: 0 : if ( nFuncEnd != STRING_NOTFOUND )
1406 : : {
1407 [ # # ][ # # ]: 0 : aFuncStr = rList.Copy( nStartPos, nFuncEnd - nStartPos );
[ # # ]
1408 : 0 : bParsed = true;
1409 : : }
1410 : : }
1411 : :
1412 [ # # ]: 0 : if ( bParsed )
1413 : : {
1414 [ # # ][ # # ]: 0 : aFuncStr = comphelper::string::strip(aFuncStr, ' ');
[ # # ]
1415 : :
1416 : 0 : const sal_Int32 nFuncCount = sizeof(aFunctions) / sizeof(aFunctions[0]);
1417 [ # # ][ # # ]: 0 : for ( sal_Int32 nFunc=0; nFunc<nFuncCount && !bFound; nFunc++ )
[ # # ]
1418 : : {
1419 [ # # ][ # # ]: 0 : if ( aFuncStr.EqualsIgnoreCaseAscii( aFunctions[nFunc].pName ) )
1420 : : {
1421 : 0 : rFunc = aFunctions[nFunc].eFunc;
1422 : 0 : bFound = true;
1423 : :
1424 [ # # ][ # # ]: 0 : while ( nFuncEnd < nListLen && rList.GetChar(nFuncEnd) == ' ' )
[ # # ]
1425 : 0 : ++nFuncEnd;
1426 : 0 : rEndPos = nFuncEnd;
1427 : : }
1428 : : }
1429 : : }
1430 : :
1431 [ # # ]: 0 : return bFound;
1432 : : }
1433 : :
1434 : 0 : bool lcl_IsAtStart( const String& rList, const String& rSearch, sal_Int32& rMatched,
1435 : : bool bAllowBracket, sheet::GeneralFunction* pFunc )
1436 : : {
1437 : 0 : sal_Int32 nMatchList = 0;
1438 : 0 : sal_Int32 nMatchSearch = 0;
1439 : 0 : sal_Unicode cFirst = rList.GetChar(0);
1440 [ # # ][ # # ]: 0 : if ( cFirst == '\'' || cFirst == '[' )
1441 : : {
1442 : : // quoted string or string in brackets must match completely
1443 : :
1444 [ # # ]: 0 : String aDequoted;
1445 : 0 : xub_StrLen nQuoteEnd = 0;
1446 : 0 : bool bParsed = false;
1447 : :
1448 [ # # ]: 0 : if ( cFirst == '\'' )
1449 [ # # ]: 0 : bParsed = lcl_Dequote( rList, 0, nQuoteEnd, aDequoted );
1450 [ # # ]: 0 : else if ( cFirst == '[' )
1451 : : {
1452 : : // skip spaces after the opening bracket
1453 : :
1454 : 0 : xub_StrLen nStartPos = 1;
1455 : 0 : const xub_StrLen nListLen = rList.Len();
1456 [ # # ][ # # ]: 0 : while ( nStartPos < nListLen && rList.GetChar(nStartPos) == ' ' )
[ # # ]
1457 : 0 : ++nStartPos;
1458 : :
1459 [ # # ]: 0 : if ( rList.GetChar(nStartPos) == '\'' ) // quoted within the brackets?
1460 : : {
1461 [ # # ][ # # ]: 0 : if ( lcl_Dequote( rList, nStartPos, nQuoteEnd, aDequoted ) )
1462 : : {
1463 : : // after the quoted string, there must be the closing bracket, optionally preceded by spaces,
1464 : : // and/or a function name
1465 [ # # ][ # # ]: 0 : while ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ' ' )
[ # # ]
1466 : 0 : ++nQuoteEnd;
1467 : :
1468 : : // semicolon separates function name
1469 [ # # ][ # # ]: 0 : if ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ';' && pFunc )
[ # # ][ # # ]
1470 : : {
1471 : 0 : xub_StrLen nFuncEnd = 0;
1472 [ # # ][ # # ]: 0 : if ( lcl_ParseFunction( rList, nQuoteEnd + 1, nFuncEnd, *pFunc ) )
1473 : 0 : nQuoteEnd = nFuncEnd;
1474 : : }
1475 [ # # ][ # # ]: 0 : if ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ']' )
[ # # ]
1476 : : {
1477 : 0 : ++nQuoteEnd; // include the closing bracket for the matched length
1478 : 0 : bParsed = true;
1479 : : }
1480 : : }
1481 : : }
1482 : : else
1483 : : {
1484 : : // implicit quoting to the closing bracket
1485 : :
1486 [ # # ]: 0 : xub_StrLen nClosePos = rList.Search( static_cast<sal_Unicode>(']'), nStartPos );
1487 [ # # ]: 0 : if ( nClosePos != STRING_NOTFOUND )
1488 : : {
1489 : 0 : xub_StrLen nNameEnd = nClosePos;
1490 [ # # ]: 0 : xub_StrLen nSemiPos = rList.Search( static_cast<sal_Unicode>(';'), nStartPos );
1491 [ # # ][ # # ]: 0 : if ( nSemiPos != STRING_NOTFOUND && nSemiPos < nClosePos && pFunc )
[ # # ]
1492 : : {
1493 : 0 : xub_StrLen nFuncEnd = 0;
1494 [ # # ][ # # ]: 0 : if ( lcl_ParseFunction( rList, nSemiPos + 1, nFuncEnd, *pFunc ) )
1495 : 0 : nNameEnd = nSemiPos;
1496 : : }
1497 : :
1498 [ # # ][ # # ]: 0 : aDequoted = rList.Copy( nStartPos, nNameEnd - nStartPos );
[ # # ]
1499 : : // spaces before the closing bracket or semicolon
1500 [ # # ][ # # ]: 0 : aDequoted = comphelper::string::stripEnd(aDequoted, ' ');
[ # # ]
1501 : 0 : nQuoteEnd = nClosePos + 1;
1502 : 0 : bParsed = true;
1503 : : }
1504 : : }
1505 : : }
1506 : :
1507 [ # # ][ # # ]: 0 : if ( bParsed && ScGlobal::GetpTransliteration()->isEqual( aDequoted, rSearch ) )
[ # # ][ # # ]
[ # # ]
1508 : : {
1509 : 0 : nMatchList = nQuoteEnd; // match count in the list string, including quotes
1510 : 0 : nMatchSearch = rSearch.Len();
1511 [ # # ]: 0 : }
1512 : : }
1513 : : else
1514 : : {
1515 : : // otherwise look for search string at the start of rList
1516 : 0 : ScGlobal::GetpTransliteration()->equals( rList, 0, rList.Len(), nMatchList,
1517 [ # # ][ # # ]: 0 : rSearch, 0, rSearch.Len(), nMatchSearch );
1518 : : }
1519 : :
1520 [ # # ]: 0 : if ( nMatchSearch == rSearch.Len() )
1521 : : {
1522 : : // search string is at start of rList - look for following space or end of string
1523 : :
1524 : 0 : bool bValid = false;
1525 [ # # ]: 0 : if ( sal::static_int_cast<xub_StrLen>(nMatchList) >= rList.Len() )
1526 : 0 : bValid = true;
1527 : : else
1528 : : {
1529 : 0 : sal_Unicode cNext = rList.GetChar(sal::static_int_cast<xub_StrLen>(nMatchList));
1530 [ # # ][ # # ]: 0 : if ( cNext == ' ' || ( bAllowBracket && cNext == '[' ) )
[ # # ]
1531 : 0 : bValid = true;
1532 : : }
1533 : :
1534 [ # # ]: 0 : if ( bValid )
1535 : : {
1536 : 0 : rMatched = nMatchList;
1537 : 0 : return true;
1538 : : }
1539 : : }
1540 : :
1541 : 0 : return false;
1542 : : }
1543 : :
1544 : 0 : bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget,
1545 : : std::vector< ScDPGetPivotDataField >& rFilters,
1546 : : const OUString& rFilterList )
1547 : : {
1548 : : // parse the string rFilterList into parameters for GetPivotData
1549 : :
1550 [ # # ]: 0 : CreateObjects(); // create xSource if not already done
1551 : :
1552 [ # # ]: 0 : std::vector<String> aDataNames; // data fields (source name)
1553 [ # # ]: 0 : std::vector<String> aGivenNames; // data fields (compound name)
1554 [ # # ]: 0 : std::vector<String> aFieldNames; // column/row/data fields
1555 [ # # ]: 0 : std::vector< uno::Sequence<rtl::OUString> > aFieldValues;
1556 : :
1557 : : //
1558 : : // get all the field and item names
1559 : : //
1560 : :
1561 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1562 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
[ # # ]
1563 [ # # ][ # # ]: 0 : sal_Int32 nDimCount = xIntDims->getCount();
1564 [ # # ]: 0 : for ( sal_Int32 nDim = 0; nDim<nDimCount; nDim++ )
1565 : : {
1566 [ # # ][ # # ]: 0 : uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nDim) );
[ # # ]
1567 [ # # ]: 0 : uno::Reference<container::XNamed> xDim( xIntDim, uno::UNO_QUERY );
1568 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1569 [ # # ]: 0 : uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDim, uno::UNO_QUERY );
1570 : : sal_Bool bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1571 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISDATALAYOUT)) );
1572 : : sal_Int32 nOrient = ScUnoHelpFunctions::GetEnumProperty(
1573 : : xDimProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ORIENTATION)),
1574 [ # # ][ # # ]: 0 : sheet::DataPilotFieldOrientation_HIDDEN );
1575 [ # # ]: 0 : if ( !bDataLayout )
1576 : : {
1577 [ # # ]: 0 : if ( nOrient == sheet::DataPilotFieldOrientation_DATA )
1578 : : {
1579 : 0 : rtl::OUString aSourceName;
1580 : 0 : rtl::OUString aGivenName;
1581 [ # # ]: 0 : ScDPOutput::GetDataDimensionNames( aSourceName, aGivenName, xIntDim );
1582 [ # # ][ # # ]: 0 : aDataNames.push_back( aSourceName );
[ # # ]
1583 [ # # ][ # # ]: 0 : aGivenNames.push_back( aGivenName );
[ # # ]
1584 : : }
1585 [ # # ]: 0 : else if ( nOrient != sheet::DataPilotFieldOrientation_HIDDEN )
1586 : : {
1587 : : // get level names, as in ScDPOutput
1588 : :
1589 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
[ # # ][ # # ]
[ # # ]
1590 : : sal_Int32 nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
1591 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_USEDHIERARCHY)) );
1592 [ # # ][ # # ]: 0 : if ( nHierarchy >= xHiers->getCount() )
[ # # ]
1593 : 0 : nHierarchy = 0;
1594 : :
1595 : : uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface(
1596 [ # # ][ # # ]: 0 : xHiers->getByIndex(nHierarchy) );
[ # # ]
1597 [ # # ]: 0 : uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
1598 [ # # ]: 0 : if ( xHierSupp.is() )
1599 : : {
1600 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() );
[ # # ][ # # ]
[ # # ]
1601 [ # # ][ # # ]: 0 : sal_Int32 nLevCount = xLevels->getCount();
1602 [ # # ]: 0 : for (sal_Int32 nLev=0; nLev<nLevCount; nLev++)
1603 : : {
1604 : : uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface(
1605 [ # # ][ # # ]: 0 : xLevels->getByIndex(nLev) );
[ # # ]
1606 [ # # ]: 0 : uno::Reference<container::XNamed> xLevNam( xLevel, uno::UNO_QUERY );
1607 [ # # ]: 0 : uno::Reference<sheet::XMembersSupplier> xLevSupp( xLevel, uno::UNO_QUERY );
1608 [ # # ][ # # ]: 0 : if ( xLevNam.is() && xLevSupp.is() )
[ # # ]
1609 : : {
1610 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xMembers = xLevSupp->getMembers();
1611 : :
1612 [ # # ][ # # ]: 0 : String aFieldName( xLevNam->getName() );
[ # # ]
1613 [ # # ][ # # ]: 0 : uno::Sequence<rtl::OUString> aMemberNames( xMembers->getElementNames() );
1614 : :
1615 [ # # ]: 0 : aFieldNames.push_back( aFieldName );
1616 [ # # ][ # # ]: 0 : aFieldValues.push_back( aMemberNames );
[ # # ]
1617 : : }
1618 : 0 : }
1619 : 0 : }
1620 : : }
1621 : : }
1622 : 0 : }
1623 : :
1624 : : //
1625 : : // compare and build filters
1626 : : //
1627 : :
1628 : 0 : SCSIZE nDataFields = aDataNames.size();
1629 : 0 : SCSIZE nFieldCount = aFieldNames.size();
1630 : : OSL_ENSURE( aGivenNames.size() == nDataFields && aFieldValues.size() == nFieldCount, "wrong count" );
1631 : :
1632 : 0 : bool bError = false;
1633 : 0 : bool bHasData = false;
1634 [ # # ][ # # ]: 0 : String aRemaining(comphelper::string::strip(rFilterList, ' '));
1635 [ # # ][ # # ]: 0 : while ( aRemaining.Len() && !bError )
[ # # ]
1636 : : {
1637 : 0 : bool bUsed = false;
1638 : :
1639 : : // look for data field name
1640 : :
1641 [ # # ][ # # ]: 0 : for ( SCSIZE nDataPos=0; nDataPos<nDataFields && !bUsed; nDataPos++ )
[ # # ]
1642 : : {
1643 [ # # ]: 0 : String aFound;
1644 : 0 : sal_Int32 nMatched = 0;
1645 [ # # ][ # # ]: 0 : if ( lcl_IsAtStart( aRemaining, aDataNames[nDataPos], nMatched, false, NULL ) )
[ # # ]
1646 [ # # ][ # # ]: 0 : aFound = aDataNames[nDataPos];
1647 [ # # ][ # # ]: 0 : else if ( lcl_IsAtStart( aRemaining, aGivenNames[nDataPos], nMatched, false, NULL ) )
[ # # ]
1648 [ # # ][ # # ]: 0 : aFound = aGivenNames[nDataPos];
1649 : :
1650 [ # # ]: 0 : if ( aFound.Len() )
1651 : : {
1652 [ # # ]: 0 : rTarget.maFieldName = aFound;
1653 [ # # ]: 0 : aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
1654 : 0 : bHasData = true;
1655 : 0 : bUsed = true;
1656 : : }
1657 [ # # ]: 0 : }
1658 : :
1659 : : // look for field name
1660 : :
1661 [ # # ]: 0 : String aSpecField;
1662 : 0 : bool bHasFieldName = false;
1663 [ # # ]: 0 : if ( !bUsed )
1664 : : {
1665 : 0 : sal_Int32 nMatched = 0;
1666 [ # # ][ # # ]: 0 : for ( SCSIZE nField=0; nField<nFieldCount && !bHasFieldName; nField++ )
[ # # ]
1667 : : {
1668 [ # # ][ # # ]: 0 : if ( lcl_IsAtStart( aRemaining, aFieldNames[nField], nMatched, true, NULL ) )
[ # # ]
1669 : : {
1670 [ # # ][ # # ]: 0 : aSpecField = aFieldNames[nField];
1671 [ # # ]: 0 : aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
1672 [ # # ][ # # ]: 0 : aRemaining = comphelper::string::stripStart(aRemaining, ' ');
[ # # ]
1673 : :
1674 : : // field name has to be followed by item name in brackets
1675 [ # # ]: 0 : if ( aRemaining.GetChar(0) == '[' )
1676 : : {
1677 : 0 : bHasFieldName = true;
1678 : : // bUsed remains false - still need the item
1679 : : }
1680 : : else
1681 : : {
1682 : 0 : bUsed = true;
1683 : 0 : bError = true;
1684 : : }
1685 : : }
1686 : : }
1687 : : }
1688 : :
1689 : : // look for field item
1690 : :
1691 [ # # ]: 0 : if ( !bUsed )
1692 : : {
1693 : 0 : bool bItemFound = false;
1694 : 0 : sal_Int32 nMatched = 0;
1695 [ # # ]: 0 : String aFoundName;
1696 [ # # ]: 0 : String aFoundValue;
1697 : 0 : sheet::GeneralFunction eFunc = sheet::GeneralFunction_NONE;
1698 : 0 : sheet::GeneralFunction eFoundFunc = sheet::GeneralFunction_NONE;
1699 : :
1700 [ # # ]: 0 : for ( SCSIZE nField=0; nField<nFieldCount; nField++ )
1701 : : {
1702 : : // If a field name is given, look in that field only, otherwise in all fields.
1703 : : // aSpecField is initialized from aFieldNames array, so exact comparison can be used.
1704 [ # # ][ # # ]: 0 : if ( !bHasFieldName || aFieldNames[nField] == aSpecField )
[ # # ][ # # ]
[ # # ]
1705 : : {
1706 : 0 : const uno::Sequence<rtl::OUString>& rItems = aFieldValues[nField];
1707 : 0 : sal_Int32 nItemCount = rItems.getLength();
1708 : 0 : const rtl::OUString* pItemArr = rItems.getConstArray();
1709 [ # # ]: 0 : for ( sal_Int32 nItem=0; nItem<nItemCount; nItem++ )
1710 : : {
1711 [ # # ][ # # ]: 0 : if ( lcl_IsAtStart( aRemaining, pItemArr[nItem], nMatched, false, &eFunc ) )
[ # # ][ # # ]
1712 : : {
1713 [ # # ]: 0 : if ( bItemFound )
1714 : 0 : bError = true; // duplicate (also across fields)
1715 : : else
1716 : : {
1717 [ # # ][ # # ]: 0 : aFoundName = aFieldNames[nField];
1718 [ # # ]: 0 : aFoundValue = pItemArr[nItem];
1719 : 0 : eFoundFunc = eFunc;
1720 : 0 : bItemFound = true;
1721 : 0 : bUsed = true;
1722 : : }
1723 : : }
1724 : : }
1725 : : }
1726 : : }
1727 : :
1728 [ # # ][ # # ]: 0 : if ( bItemFound && !bError )
1729 : : {
1730 : 0 : ScDPGetPivotDataField aField;
1731 [ # # ]: 0 : aField.maFieldName = aFoundName;
1732 : 0 : aField.meFunction = eFoundFunc;
1733 : 0 : aField.mbValIsStr = true;
1734 [ # # ]: 0 : aField.maValStr = aFoundValue;
1735 : 0 : aField.mnValNum = 0.0;
1736 [ # # ]: 0 : rFilters.push_back( aField );
1737 : :
1738 [ # # ]: 0 : aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
1739 [ # # ][ # # ]: 0 : }
1740 : : }
1741 : :
1742 [ # # ]: 0 : if ( !bUsed )
1743 : 0 : bError = true;
1744 : :
1745 : : // remove any number of spaces between entries
1746 [ # # ][ # # ]: 0 : aRemaining = comphelper::string::stripStart(aRemaining, ' ');
[ # # ]
1747 [ # # ]: 0 : }
1748 : :
1749 [ # # ][ # # ]: 0 : if ( !bError && !bHasData && aDataNames.size() == 1 )
[ # # ][ # # ]
1750 : : {
1751 : : // if there's only one data field, its name need not be specified
1752 [ # # ][ # # ]: 0 : rTarget.maFieldName = aDataNames[0];
1753 : 0 : bHasData = true;
1754 : : }
1755 : :
1756 [ # # ][ # # ]: 0 : return bHasData && !bError;
[ # # ]
1757 : : }
1758 : :
1759 : 0 : void ScDPObject::ToggleDetails(const DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj)
1760 : : {
1761 [ # # ]: 0 : CreateObjects(); // create xSource if not already done
1762 : :
1763 : : // find dimension name
1764 : :
1765 : 0 : uno::Reference<container::XNamed> xDim;
1766 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1767 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
[ # # ]
1768 [ # # ][ # # ]: 0 : long nIntCount = xIntDims->getCount();
1769 [ # # ]: 0 : if ( rElemDesc.Dimension < nIntCount )
1770 : : {
1771 : : uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface(
1772 [ # # ][ # # ]: 0 : xIntDims->getByIndex(rElemDesc.Dimension) );
[ # # ]
1773 [ # # ][ # # ]: 0 : xDim = uno::Reference<container::XNamed>( xIntDim, uno::UNO_QUERY );
1774 : : }
1775 : : OSL_ENSURE( xDim.is(), "dimension not found" );
1776 [ # # ]: 0 : if ( !xDim.is() ) return;
1777 [ # # ][ # # ]: 0 : String aDimName = xDim->getName();
[ # # ]
1778 : :
1779 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1780 : : sal_Bool bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1781 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISDATALAYOUT)) );
1782 [ # # ]: 0 : if (bDataLayout)
1783 : : {
1784 : : // the elements of the data layout dimension can't be found by their names
1785 : : // -> don't change anything
1786 : : return;
1787 : : }
1788 : :
1789 : : // query old state
1790 : :
1791 : 0 : long nHierCount = 0;
1792 : 0 : uno::Reference<container::XIndexAccess> xHiers;
1793 [ # # ]: 0 : uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
1794 [ # # ]: 0 : if ( xHierSupp.is() )
1795 : : {
1796 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
1797 [ # # ][ # # ]: 0 : xHiers = new ScNameToIndexAccess( xHiersName );
[ # # ]
1798 [ # # ][ # # ]: 0 : nHierCount = xHiers->getCount();
1799 : : }
1800 : 0 : uno::Reference<uno::XInterface> xHier;
1801 [ # # ]: 0 : if ( rElemDesc.Hierarchy < nHierCount )
1802 [ # # ][ # # ]: 0 : xHier = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(rElemDesc.Hierarchy) );
[ # # ][ # # ]
1803 : : OSL_ENSURE( xHier.is(), "hierarchy not found" );
1804 [ # # ]: 0 : if ( !xHier.is() ) return;
1805 : :
1806 : 0 : long nLevCount = 0;
1807 : 0 : uno::Reference<container::XIndexAccess> xLevels;
1808 [ # # ]: 0 : uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHier, uno::UNO_QUERY );
1809 [ # # ]: 0 : if ( xLevSupp.is() )
1810 : : {
1811 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xLevsName = xLevSupp->getLevels();
1812 [ # # ][ # # ]: 0 : xLevels = new ScNameToIndexAccess( xLevsName );
[ # # ]
1813 [ # # ][ # # ]: 0 : nLevCount = xLevels->getCount();
1814 : : }
1815 : 0 : uno::Reference<uno::XInterface> xLevel;
1816 [ # # ]: 0 : if ( rElemDesc.Level < nLevCount )
1817 [ # # ][ # # ]: 0 : xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(rElemDesc.Level) );
[ # # ][ # # ]
1818 : : OSL_ENSURE( xLevel.is(), "level not found" );
1819 [ # # ]: 0 : if ( !xLevel.is() ) return;
1820 : :
1821 : 0 : uno::Reference<container::XNameAccess> xMembers;
1822 [ # # ]: 0 : uno::Reference<sheet::XMembersSupplier> xMbrSupp( xLevel, uno::UNO_QUERY );
1823 [ # # ]: 0 : if ( xMbrSupp.is() )
1824 [ # # ][ # # ]: 0 : xMembers = xMbrSupp->getMembers();
[ # # ]
1825 : :
1826 : 0 : sal_Bool bFound = false;
1827 : 0 : sal_Bool bShowDetails = sal_True;
1828 : :
1829 [ # # ]: 0 : if ( xMembers.is() )
1830 : : {
1831 [ # # ][ # # ]: 0 : if ( xMembers->hasByName(rElemDesc.MemberName) )
[ # # ]
1832 : : {
1833 : : uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
1834 [ # # ][ # # ]: 0 : xMembers->getByName(rElemDesc.MemberName) );
[ # # ]
1835 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xMbrProp( xMemberInt, uno::UNO_QUERY );
1836 [ # # ]: 0 : if ( xMbrProp.is() )
1837 : : {
1838 : : bShowDetails = ScUnoHelpFunctions::GetBoolProperty( xMbrProp,
1839 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_SHOWDETAILS)) );
1840 : : //! don't set bFound if property is unknown?
1841 : 0 : bFound = sal_True;
1842 : 0 : }
1843 : : }
1844 : : }
1845 : :
1846 : : OSL_ENSURE( bFound, "member not found" );
1847 : : (void)bFound;
1848 : :
1849 : : //! use Hierarchy and Level in SaveData !!!!
1850 : :
1851 : : // modify pDestObj if set, this object otherwise
1852 [ # # ]: 0 : ScDPSaveData* pModifyData = pDestObj ? ( pDestObj->pSaveData ) : pSaveData;
1853 : : OSL_ENSURE( pModifyData, "no data?" );
1854 [ # # ]: 0 : if ( pModifyData )
1855 : : {
1856 [ # # ]: 0 : const String aName = rElemDesc.MemberName;
1857 : : pModifyData->GetDimensionByName(aDimName)->
1858 [ # # ][ # # ]: 0 : GetMemberByName(aName)->SetShowDetails( !bShowDetails ); // toggle
[ # # ][ # # ]
[ # # ]
1859 : :
1860 [ # # ]: 0 : if ( pDestObj )
1861 [ # # ]: 0 : pDestObj->InvalidateData(); // re-init source from SaveData
1862 : : else
1863 [ # # ][ # # ]: 0 : InvalidateData(); // re-init source from SaveData
1864 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1865 : : }
1866 : :
1867 : 0 : long lcl_FindName( const rtl::OUString& rString, const uno::Reference<container::XNameAccess>& xCollection )
1868 : : {
1869 [ # # ]: 0 : if ( xCollection.is() )
1870 : : {
1871 [ # # ][ # # ]: 0 : uno::Sequence<rtl::OUString> aSeq = xCollection->getElementNames();
1872 : 0 : long nCount = aSeq.getLength();
1873 : 0 : const rtl::OUString* pArr = aSeq.getConstArray();
1874 [ # # ]: 0 : for (long nPos=0; nPos<nCount; nPos++)
1875 [ # # ]: 0 : if ( pArr[nPos] == rString )
1876 [ # # ][ # # ]: 0 : return nPos;
1877 : : }
1878 : 0 : return -1; // not found
1879 : : }
1880 : :
1881 : 0 : sal_uInt16 lcl_FirstSubTotal( const uno::Reference<beans::XPropertySet>& xDimProp ) // PIVOT_FUNC mask
1882 : : {
1883 [ # # ]: 0 : uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
1884 [ # # ][ # # ]: 0 : if ( xDimProp.is() && xDimSupp.is() )
[ # # ]
1885 : : {
1886 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
[ # # ][ # # ]
[ # # ]
1887 : : long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
1888 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_USEDHIERARCHY)) );
1889 [ # # ][ # # ]: 0 : if ( nHierarchy >= xHiers->getCount() )
[ # # ]
1890 : 0 : nHierarchy = 0;
1891 : :
1892 : : uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface(
1893 [ # # ][ # # ]: 0 : xHiers->getByIndex(nHierarchy) );
[ # # ]
1894 [ # # ]: 0 : uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
1895 [ # # ]: 0 : if ( xHierSupp.is() )
1896 : : {
1897 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() );
[ # # ][ # # ]
[ # # ]
1898 : : uno::Reference<uno::XInterface> xLevel =
1899 [ # # ][ # # ]: 0 : ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex( 0 ) );
[ # # ]
1900 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
1901 [ # # ]: 0 : if ( xLevProp.is() )
1902 : : {
1903 : 0 : uno::Any aSubAny;
1904 : : try
1905 : : {
1906 [ # # ]: 0 : aSubAny = xLevProp->getPropertyValue(
1907 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_SUBTOTAL)) );
[ # # ]
1908 : : }
1909 [ # # ]: 0 : catch(uno::Exception&)
1910 : : {
1911 : : }
1912 [ # # ]: 0 : uno::Sequence<sheet::GeneralFunction> aSeq;
1913 [ # # ][ # # ]: 0 : if ( aSubAny >>= aSeq )
1914 : : {
1915 : 0 : sal_uInt16 nMask = 0;
1916 : 0 : const sheet::GeneralFunction* pArray = aSeq.getConstArray();
1917 : 0 : long nCount = aSeq.getLength();
1918 [ # # ]: 0 : for (long i=0; i<nCount; i++)
1919 [ # # ]: 0 : nMask |= ScDataPilotConversion::FunctionBit(pArray[i]);
1920 : 0 : return nMask;
1921 [ # # ][ # # ]: 0 : }
[ # # ]
1922 [ # # ][ # # ]: 0 : }
[ # # ]
1923 [ # # ][ # # ]: 0 : }
[ # # ]
1924 : : }
1925 : :
1926 : : OSL_FAIL("FirstSubTotal: NULL");
1927 : 0 : return 0;
1928 : : }
1929 : :
1930 : 0 : sal_uInt16 lcl_CountBits( sal_uInt16 nBits )
1931 : : {
1932 [ # # ]: 0 : if (!nBits) return 0;
1933 : :
1934 : 0 : sal_uInt16 nCount = 0;
1935 : 0 : sal_uInt16 nMask = 1;
1936 [ # # ]: 0 : for (sal_uInt16 i=0; i<16; i++)
1937 : : {
1938 [ # # ]: 0 : if ( nBits & nMask )
1939 : 0 : ++nCount;
1940 : 0 : nMask <<= 1;
1941 : : }
1942 : 0 : return nCount;
1943 : : }
1944 : :
1945 : : namespace {
1946 : :
1947 : : class FindByColumn : public std::unary_function<PivotField, bool>
1948 : : {
1949 : : SCsCOL mnCol;
1950 : : sal_uInt16 mnMask;
1951 : : public:
1952 : 0 : FindByColumn(SCsCOL nCol, sal_uInt16 nMask) : mnCol(nCol), mnMask(nMask) {}
1953 : 0 : bool operator() (const PivotField& r) const
1954 : : {
1955 [ # # ][ # # ]: 0 : return r.nCol == mnCol && r.nFuncMask == mnMask;
1956 : : }
1957 : : };
1958 : :
1959 : : }
1960 : :
1961 : 0 : void lcl_FillOldFields(
1962 : : vector<PivotField>& rFields,
1963 : : const uno::Reference<sheet::XDimensionsSupplier>& xSource,
1964 : : sal_uInt16 nOrient, bool bAddData )
1965 : : {
1966 [ # # ]: 0 : vector<PivotField> aFields;
1967 : :
1968 : 0 : bool bDataFound = false;
1969 : :
1970 : : //! merge multiple occurrences (data field with different functions)
1971 : : //! force data field in one dimension
1972 : :
1973 [ # # ]: 0 : vector<long> aPos;
1974 : :
1975 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1976 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
[ # # ]
1977 [ # # ][ # # ]: 0 : long nDimCount = xDims->getCount();
1978 [ # # ]: 0 : for (long nDim = 0; nDim < nDimCount; ++nDim)
1979 : : {
1980 : : // Get dimension object.
1981 : : uno::Reference<uno::XInterface> xIntDim =
1982 [ # # ][ # # ]: 0 : ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
[ # # ]
1983 : :
1984 : : // dimension properties
1985 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
1986 : :
1987 : : // dimension orientation, hidden by default.
1988 : : long nDimOrient = ScUnoHelpFunctions::GetEnumProperty(
1989 : : xDimProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ORIENTATION)),
1990 [ # # ][ # # ]: 0 : sheet::DataPilotFieldOrientation_HIDDEN );
1991 : :
1992 [ # # ][ # # ]: 0 : if ( xDimProp.is() && nDimOrient == nOrient )
[ # # ]
1993 : : {
1994 : : // Let's take this dimension.
1995 : :
1996 : : // function mask.
1997 : 0 : sal_uInt16 nMask = 0;
1998 [ # # ]: 0 : if ( nOrient == sheet::DataPilotFieldOrientation_DATA )
1999 : : {
2000 : : sheet::GeneralFunction eFunc = (sheet::GeneralFunction)ScUnoHelpFunctions::GetEnumProperty(
2001 : : xDimProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_FUNCTION)),
2002 [ # # ][ # # ]: 0 : sheet::GeneralFunction_NONE );
2003 [ # # ]: 0 : if ( eFunc == sheet::GeneralFunction_AUTO )
2004 : : {
2005 : : //! test for numeric data
2006 : 0 : eFunc = sheet::GeneralFunction_SUM;
2007 : : }
2008 [ # # ]: 0 : nMask = ScDataPilotConversion::FunctionBit(eFunc);
2009 : : }
2010 : : else
2011 [ # # ]: 0 : nMask = lcl_FirstSubTotal( xDimProp ); // from first hierarchy
2012 : :
2013 : : // is this data layout dimension?
2014 : : bool bDataLayout = ScUnoHelpFunctions::GetBoolProperty(
2015 [ # # ][ # # ]: 0 : xDimProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISDATALAYOUT)));
2016 : :
2017 : : // is this dimension cloned?
2018 : 0 : long nDupSource = -1;
2019 : : try
2020 : : {
2021 [ # # ]: 0 : uno::Any aOrigAny = xDimProp->getPropertyValue(
2022 [ # # ][ # # ]: 0 : OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ORIGINAL_POS)));
[ # # ]
2023 : 0 : sal_Int32 nTmp = 0;
2024 [ # # ]: 0 : if (aOrigAny >>= nTmp)
2025 : 0 : nDupSource = static_cast<sal_Int32>(nTmp);
2026 : : }
2027 [ # # ]: 0 : catch(uno::Exception&)
2028 : : {
2029 : : }
2030 : :
2031 : 0 : sal_uInt8 nDupCount = 0;
2032 [ # # ]: 0 : if (nDupSource >= 0)
2033 : : {
2034 : : // this dimension is cloned.
2035 : :
2036 : : SCsCOL nCompCol; // ID of the original dimension.
2037 [ # # ]: 0 : if ( bDataLayout )
2038 : 0 : nCompCol = PIVOT_DATA_FIELD;
2039 : : else
2040 : 0 : nCompCol = static_cast<SCsCOL>(nDupSource); //! seek source column from name
2041 : :
2042 [ # # ]: 0 : vector<PivotField>::iterator it = std::find_if(aFields.begin(), aFields.end(), FindByColumn(nCompCol, nMask));
2043 [ # # ][ # # ]: 0 : if (it != aFields.end())
2044 : 0 : nDupCount = it->mnDupCount + 1;
2045 : : }
2046 : :
2047 [ # # ][ # # ]: 0 : aFields.push_back(PivotField());
2048 [ # # ]: 0 : PivotField& rField = aFields.back();
2049 [ # # ]: 0 : if (bDataLayout)
2050 : : {
2051 : 0 : rField.nCol = PIVOT_DATA_FIELD;
2052 : 0 : bDataFound = true;
2053 : : }
2054 : : else
2055 : : {
2056 : 0 : rField.mnOriginalDim = nDupSource;
2057 : 0 : rField.nCol = static_cast<SCCOL>(nDim); //! seek source column from name
2058 : : }
2059 : :
2060 : 0 : rField.nFuncMask = nMask;
2061 : 0 : rField.mnDupCount = nDupCount;
2062 : : long nPos = ScUnoHelpFunctions::GetLongProperty(
2063 [ # # ][ # # ]: 0 : xDimProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_POSITION)));
2064 [ # # ]: 0 : aPos.push_back(nPos);
2065 : :
2066 : : try
2067 : : {
2068 [ # # ]: 0 : if (nOrient == sheet::DataPilotFieldOrientation_DATA)
2069 [ # # ]: 0 : xDimProp->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_REFVALUE)))
2070 [ # # ][ # # ]: 0 : >>= rField.maFieldRef;
[ # # ][ # # ]
2071 : : }
2072 [ # # ]: 0 : catch (uno::Exception&)
2073 : : {
2074 : : }
2075 : : }
2076 : 0 : }
2077 : :
2078 : : // sort by getPosition() value
2079 : :
2080 : 0 : size_t nOutCount = aFields.size();
2081 [ # # ]: 0 : if (nOutCount >= 1)
2082 : : {
2083 [ # # ]: 0 : for (size_t i = 0; i < nOutCount - 1; ++i)
2084 : : {
2085 [ # # ]: 0 : for (size_t j = 0; j + i < nOutCount - 1; ++j)
2086 : : {
2087 [ # # ][ # # ]: 0 : if ( aPos[j+1] < aPos[j] )
[ # # ]
2088 : : {
2089 [ # # ][ # # ]: 0 : std::swap( aPos[j], aPos[j+1] );
2090 [ # # ]: 0 : std::swap( aFields[j], aFields[j+1] );
2091 : : }
2092 : : }
2093 : : }
2094 : : }
2095 : :
2096 [ # # ][ # # ]: 0 : if (bAddData && !bDataFound)
2097 [ # # ][ # # ]: 0 : aFields.push_back(PivotField(PIVOT_DATA_FIELD, 0));
2098 : :
2099 : 0 : rFields.swap(aFields);
2100 : 0 : }
2101 : :
2102 : 0 : bool ScDPObject::FillOldParam(ScPivotParam& rParam) const
2103 : : {
2104 [ # # ]: 0 : ((ScDPObject*)this)->CreateObjects(); // xSource is needed for field numbers
2105 : :
2106 [ # # ]: 0 : if (!xSource.is())
2107 : 0 : return false;
2108 : :
2109 : 0 : rParam.nCol = aOutRange.aStart.Col();
2110 : 0 : rParam.nRow = aOutRange.aStart.Row();
2111 : 0 : rParam.nTab = aOutRange.aStart.Tab();
2112 : : // ppLabelArr / nLabels is not changed
2113 : :
2114 [ # # ]: 0 : bool bAddData = ( lcl_GetDataGetOrientation( xSource ) == sheet::DataPilotFieldOrientation_HIDDEN );
2115 : : lcl_FillOldFields(
2116 [ # # ]: 0 : rParam.maPageFields, xSource, sheet::DataPilotFieldOrientation_PAGE, false);
2117 : : lcl_FillOldFields(
2118 [ # # ]: 0 : rParam.maColFields, xSource, sheet::DataPilotFieldOrientation_COLUMN, bAddData);
2119 : : lcl_FillOldFields(
2120 [ # # ]: 0 : rParam.maRowFields, xSource, sheet::DataPilotFieldOrientation_ROW, false);
2121 : : lcl_FillOldFields(
2122 [ # # ]: 0 : rParam.maDataFields, xSource, sheet::DataPilotFieldOrientation_DATA, false);
2123 : :
2124 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xProp( xSource, uno::UNO_QUERY );
2125 [ # # ]: 0 : if (xProp.is())
2126 : : {
2127 : : try
2128 : : {
2129 : : rParam.bMakeTotalCol = ScUnoHelpFunctions::GetBoolProperty( xProp,
2130 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_COLGRAND)), true );
2131 : : rParam.bMakeTotalRow = ScUnoHelpFunctions::GetBoolProperty( xProp,
2132 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ROWGRAND)), true );
2133 : :
2134 : : // following properties may be missing for external sources
2135 : : rParam.bIgnoreEmptyRows = ScUnoHelpFunctions::GetBoolProperty( xProp,
2136 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_IGNOREEMPTY)) );
2137 : : rParam.bDetectCategories = ScUnoHelpFunctions::GetBoolProperty( xProp,
2138 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_REPEATEMPTY)) );
[ # # ]
2139 : : }
2140 [ # # ]: 0 : catch(uno::Exception&)
2141 : : {
2142 : : // no error
2143 : : }
2144 : : }
2145 : 0 : return true;
2146 : : }
2147 : :
2148 : 9 : void lcl_FillLabelData( ScDPLabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
2149 : : {
2150 [ + - ]: 9 : uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
2151 [ + - ][ - + ]: 9 : if (!xDimProp.is() || !xDimSupp.is())
[ - + ]
2152 : : return;
2153 : :
2154 [ + - ][ + - ]: 9 : uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
[ + - ][ + - ]
[ + - ]
2155 : : long nHierarchy = ScUnoHelpFunctions::GetLongProperty(
2156 [ + - ][ + - ]: 9 : xDimProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_USEDHIERARCHY)));
2157 [ + - ][ - + ]: 9 : if ( nHierarchy >= xHiers->getCount() )
[ + - ]
2158 : 0 : nHierarchy = 0;
2159 : 9 : rData.mnUsedHier = nHierarchy;
2160 : :
2161 : : uno::Reference<uno::XInterface> xHier =
2162 [ + - ][ + - ]: 9 : ScUnoHelpFunctions::AnyToInterface(xHiers->getByIndex(nHierarchy));
[ + - ]
2163 : :
2164 [ + - ]: 9 : uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
2165 [ - + ]: 9 : if (!xHierSupp.is())
2166 : : return;
2167 : :
2168 : : uno::Reference<container::XIndexAccess> xLevels =
2169 [ + - ][ + - ]: 9 : new ScNameToIndexAccess( xHierSupp->getLevels() );
[ + - ][ + - ]
[ + - ]
2170 : :
2171 : : uno::Reference<uno::XInterface> xLevel =
2172 [ + - ][ + - ]: 9 : ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(0) );
[ + - ]
2173 [ + - ]: 9 : uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
2174 [ - + ]: 9 : if (!xLevProp.is())
2175 : : return;
2176 : :
2177 : : rData.mbShowAll = ScUnoHelpFunctions::GetBoolProperty(
2178 [ + - ][ + - ]: 9 : xLevProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_SHOWEMPTY)));
2179 : :
2180 : : try
2181 : : {
2182 [ + - ]: 9 : xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_DP_SORTING ) ) )
2183 [ + - ][ + - ]: 9 : >>= rData.maSortInfo;
[ + - ]
2184 [ + - ]: 9 : xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_DP_LAYOUT ) ) )
2185 [ + - ][ + - ]: 9 : >>= rData.maLayoutInfo;
[ + - ]
2186 [ + - ]: 9 : xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_DP_AUTOSHOW ) ) )
2187 [ + - ][ + - ]: 9 : >>= rData.maShowInfo;
[ + - ][ # # ]
2188 : : }
2189 [ # # ]: 0 : catch(uno::Exception&)
2190 : : {
2191 [ - + ][ - + ]: 9 : }
[ - + ][ - + ]
[ - + ][ - + ]
[ + - ]
2192 : : }
2193 : :
2194 : 12 : bool ScDPObject::FillLabelDataForDimension(
2195 : : const uno::Reference<container::XIndexAccess>& xDims, sal_Int32 nDim, ScDPLabelData& rLabelData)
2196 : : {
2197 : : uno::Reference<uno::XInterface> xIntDim =
2198 [ + - ][ + - ]: 12 : ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
[ + - ]
2199 [ + - ]: 12 : uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
2200 [ + - ]: 12 : uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
2201 : :
2202 [ + - ][ - + ]: 12 : if (!xDimName.is() || !xDimProp.is())
[ - + ]
2203 : 0 : return false;
2204 : :
2205 : : bool bData = ScUnoHelpFunctions::GetBoolProperty(
2206 [ + - ][ + - ]: 12 : xDimProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISDATALAYOUT)));
2207 : : //! error checking -- is "IsDataLayoutDimension" property required??
2208 : :
2209 : 12 : sal_Int32 nOrigPos = -1;
2210 : 12 : rtl::OUString aFieldName;
2211 : : try
2212 : : {
2213 [ + - ][ + - ]: 12 : aFieldName = xDimName->getName();
2214 [ + - ]: 12 : uno::Any aOrigAny = xDimProp->getPropertyValue(
2215 [ + - ][ + - ]: 12 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ORIGINAL_POS)));
[ # # ]
2216 : 12 : aOrigAny >>= nOrigPos;
2217 : : }
2218 [ # # ]: 0 : catch(uno::Exception&)
2219 : : {
2220 : : }
2221 : :
2222 : : OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
2223 [ + - ][ + - ]: 12 : xDimProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_LAYOUTNAME)), OUString());
2224 : :
2225 : : OUString aSubtotalName = ScUnoHelpFunctions::GetStringProperty(
2226 [ + - ][ + - ]: 12 : xDimProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_FIELD_SUBTOTALNAME)), OUString());
2227 : :
2228 : 12 : bool bIsValue = true; //! check
2229 [ + - ]: 12 : aFieldName = ScDPUtil::getSourceDimensionName(aFieldName);
2230 : :
2231 : 12 : rLabelData.maName = aFieldName;
2232 : 12 : rLabelData.mnCol = static_cast<SCCOL>(nDim);
2233 : 12 : rLabelData.mbDataLayout = bData;
2234 : 12 : rLabelData.mbIsValue = bIsValue;
2235 : :
2236 [ + + ]: 12 : if (!bData)
2237 : : {
2238 : 9 : rLabelData.mnOriginalDim = static_cast<long>(nOrigPos);
2239 : 9 : rLabelData.maLayoutName = aLayoutName;
2240 : 9 : rLabelData.maSubtotalName = aSubtotalName;
2241 [ + + ]: 9 : if (nOrigPos >= 0)
2242 : : // This is a duplicated dimension. Use the original dimension index.
2243 : 3 : nDim = nOrigPos;
2244 [ + - ]: 9 : GetHierarchies(nDim, rLabelData.maHiers);
2245 [ + - ][ + - ]: 9 : GetMembers(nDim, GetUsedHierarchy(nDim), rLabelData.maMembers);
2246 [ + - ]: 9 : lcl_FillLabelData(rLabelData, xDimProp);
2247 : : rLabelData.mnFlags = ScUnoHelpFunctions::GetLongProperty(
2248 [ + - ][ + - ]: 9 : xDimProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_FLAGS)), 0);
2249 : : }
2250 : 12 : return true;
2251 : : }
2252 : :
2253 : 0 : bool ScDPObject::FillLabelData(sal_Int32 nDim, ScDPLabelData& rLabels)
2254 : : {
2255 [ # # ]: 0 : CreateObjects();
2256 [ # # ]: 0 : if (!xSource.is())
2257 : 0 : return false;
2258 : :
2259 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
2260 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
[ # # ]
2261 [ # # ][ # # ]: 0 : sal_Int32 nDimCount = xDims->getCount();
2262 [ # # ]: 0 : if ( nDimCount > SC_DP_MAX_FIELDS )
2263 : 0 : nDimCount = SC_DP_MAX_FIELDS;
2264 [ # # ][ # # ]: 0 : if (!nDimCount || nDim >= nDimCount)
2265 : 0 : return false;
2266 : :
2267 [ # # ]: 0 : return FillLabelDataForDimension(xDims, nDim, rLabels);
2268 : : }
2269 : :
2270 : 3 : bool ScDPObject::FillLabelData(ScPivotParam& rParam)
2271 : : {
2272 [ + - ]: 3 : rParam.maLabelArray.clear();
2273 : :
2274 [ + - ]: 3 : CreateObjects();
2275 [ - + ]: 3 : if (!xSource.is())
2276 : 0 : return false;
2277 : :
2278 [ + - ][ + - ]: 3 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
2279 [ + - ][ + - ]: 3 : uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
[ + - ]
2280 [ + - ][ + - ]: 3 : sal_Int32 nDimCount = xDims->getCount();
2281 [ - + ]: 3 : if ( nDimCount > SC_DP_MAX_FIELDS )
2282 : 0 : nDimCount = SC_DP_MAX_FIELDS;
2283 [ - + ]: 3 : if (!nDimCount)
2284 : 0 : return false;
2285 : :
2286 [ + + ]: 15 : for (sal_Int32 nDim = 0; nDim < nDimCount; ++nDim)
2287 : : {
2288 [ + - ][ + - ]: 12 : std::auto_ptr<ScDPLabelData> pNewLabel(new ScDPLabelData);
2289 [ + - ]: 12 : FillLabelDataForDimension(xDims, nDim, *pNewLabel);
2290 [ + - ][ + - ]: 12 : rParam.maLabelArray.push_back(pNewLabel);
2291 [ + - ]: 12 : }
2292 : :
2293 : 3 : return true;
2294 : : }
2295 : :
2296 : 9 : bool ScDPObject::GetHierarchiesNA( sal_Int32 nDim, uno::Reference< container::XNameAccess >& xHiers )
2297 : : {
2298 : 9 : bool bRet = false;
2299 [ + - ][ + - ]: 9 : uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
[ + - ]
2300 [ + - ][ + - ]: 9 : uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
[ + - ]
2301 [ + - ]: 9 : if( xIntDims.is() )
2302 : : {
2303 [ + - ][ + - ]: 9 : uno::Reference<sheet::XHierarchiesSupplier> xHierSup(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
[ + - ]
2304 [ + - ]: 9 : if (xHierSup.is())
2305 : : {
2306 [ + - ][ + - ]: 9 : xHiers.set( xHierSup->getHierarchies() );
[ + - ]
2307 : 9 : bRet = xHiers.is();
2308 : 9 : }
2309 : : }
2310 : 9 : return bRet;
2311 : : }
2312 : :
2313 : 9 : bool ScDPObject::GetHierarchies( sal_Int32 nDim, uno::Sequence< rtl::OUString >& rHiers )
2314 : : {
2315 : 9 : bool bRet = false;
2316 : 9 : uno::Reference< container::XNameAccess > xHiersNA;
2317 [ + - ][ + - ]: 9 : if( GetHierarchiesNA( nDim, xHiersNA ) )
2318 : : {
2319 [ + - ][ + - ]: 9 : rHiers = xHiersNA->getElementNames();
[ + - ][ + - ]
2320 : 9 : bRet = true;
2321 : : }
2322 : 9 : return bRet;
2323 : : }
2324 : :
2325 : 72 : sal_Int32 ScDPObject::GetUsedHierarchy( sal_Int32 nDim )
2326 : : {
2327 : 72 : sal_Int32 nHier = 0;
2328 [ + - ][ + - ]: 72 : uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
[ + - ]
2329 [ + - ][ + - ]: 72 : uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
[ + - ]
2330 [ + - ][ + - ]: 72 : uno::Reference<beans::XPropertySet> xDim(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
[ + - ]
2331 [ + - ]: 72 : if (xDim.is())
2332 [ + - ][ + - ]: 72 : nHier = ScUnoHelpFunctions::GetLongProperty( xDim, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_DP_USEDHIERARCHY ) ) );
2333 : 72 : return nHier;
2334 : : }
2335 : :
2336 : 60 : bool ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< container::XNameAccess >& xMembers )
2337 : : {
2338 : 60 : return GetMembersNA( nDim, GetUsedHierarchy( nDim ), xMembers );
2339 : : }
2340 : :
2341 : 72 : bool ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< container::XNameAccess >& xMembers )
2342 : : {
2343 : 72 : bool bRet = false;
2344 [ + - ][ + - ]: 72 : uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
[ + - ]
2345 [ + - ][ + - ]: 72 : uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
[ + - ]
2346 [ + - ][ + - ]: 72 : uno::Reference<beans::XPropertySet> xDim(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
[ + - ]
2347 [ + - ]: 72 : if (xDim.is())
2348 : : {
2349 [ + - ]: 72 : uno::Reference<sheet::XHierarchiesSupplier> xHierSup(xDim, uno::UNO_QUERY);
2350 [ + - ]: 72 : if (xHierSup.is())
2351 : : {
2352 [ + - ][ + - ]: 72 : uno::Reference<container::XIndexAccess> xHiers(new ScNameToIndexAccess(xHierSup->getHierarchies()));
[ + - ][ + - ]
[ + - ]
2353 [ + - ][ + - ]: 72 : uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHiers->getByIndex(nHier), uno::UNO_QUERY );
[ + - ]
2354 [ + - ]: 72 : if ( xLevSupp.is() )
2355 : : {
2356 [ + - ][ + - ]: 72 : uno::Reference<container::XIndexAccess> xLevels(new ScNameToIndexAccess( xLevSupp->getLevels()));
[ + - ][ + - ]
[ + - ]
2357 [ + - ]: 72 : if (xLevels.is())
2358 : : {
2359 [ + - ][ + - ]: 72 : sal_Int32 nLevCount = xLevels->getCount();
2360 [ + - ]: 72 : if (nLevCount > 0)
2361 : : {
2362 [ + - ][ + - ]: 72 : uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevels->getByIndex(0), uno::UNO_QUERY );
[ + - ]
2363 [ + - ]: 72 : if ( xMembSupp.is() )
2364 : : {
2365 [ + - ][ + - ]: 72 : xMembers.set(xMembSupp->getMembers());
[ + - ]
2366 : 72 : bRet = true;
2367 : 72 : }
2368 : : }
2369 : 72 : }
2370 : 72 : }
2371 : 72 : }
2372 : : }
2373 : 72 : return bRet;
2374 : : }
2375 : :
2376 : : //------------------------------------------------------------------------
2377 : : // convert old pivot tables into new datapilot tables
2378 : :
2379 : : namespace {
2380 : :
2381 : 0 : rtl::OUString lcl_GetDimName( const uno::Reference<sheet::XDimensionsSupplier>& xSource, long nDim )
2382 : : {
2383 : 0 : rtl::OUString aName;
2384 [ # # ]: 0 : if ( xSource.is() )
2385 : : {
2386 [ # # ][ # # ]: 0 : uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
2387 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
[ # # ]
2388 [ # # ][ # # ]: 0 : long nDimCount = xDims->getCount();
2389 [ # # ]: 0 : if ( nDim < nDimCount )
2390 : : {
2391 : : uno::Reference<uno::XInterface> xIntDim =
2392 [ # # ][ # # ]: 0 : ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
[ # # ][ # # ]
2393 [ # # ]: 0 : uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
2394 [ # # ]: 0 : if (xDimName.is())
2395 : : {
2396 : : try
2397 : : {
2398 [ # # ][ # # ]: 0 : aName = xDimName->getName();
2399 : : }
2400 [ # # ]: 0 : catch(uno::Exception&)
2401 : : {
2402 : : }
2403 : 0 : }
2404 : 0 : }
2405 : : }
2406 : 0 : return aName;
2407 : : }
2408 : :
2409 : 0 : bool hasFieldColumn(const vector<PivotField>* pRefFields, SCCOL nCol)
2410 : : {
2411 [ # # ]: 0 : if (!pRefFields)
2412 : 0 : return false;
2413 : :
2414 : 0 : vector<PivotField>::const_iterator itr = pRefFields->begin(), itrEnd = pRefFields->end();
2415 [ # # ][ # # ]: 0 : for (; itr != itrEnd; ++itr)
2416 : : {
2417 [ # # ]: 0 : if (itr->nCol == nCol)
2418 : : // This array of fields contains the specified column.
2419 : 0 : return true;
2420 : : }
2421 : 0 : return false;
2422 : : }
2423 : :
2424 : : class FindByOriginalDim : public std::unary_function<PivotField, bool>
2425 : : {
2426 : : long mnDim;
2427 : : public:
2428 : 0 : FindByOriginalDim(long nDim) : mnDim(nDim) {}
2429 : 0 : bool operator() (const PivotField& r) const
2430 : : {
2431 : 0 : return mnDim == r.getOriginalDim();
2432 : : }
2433 : : };
2434 : :
2435 : : }
2436 : :
2437 : 0 : void ScDPObject::ConvertOrientation(
2438 : : ScDPSaveData& rSaveData, const vector<PivotField>& rFields, sal_uInt16 nOrient,
2439 : : const Reference<XDimensionsSupplier>& xSource,
2440 : : const ScDPLabelDataVec& rLabels,
2441 : : vector<PivotField>* pRefColFields, vector<PivotField>* pRefRowFields, vector<PivotField>* pRefPageFields )
2442 : : {
2443 : : // xSource must be set
2444 : : OSL_ENSURE( xSource.is(), "missing string source" );
2445 : :
2446 : 0 : vector<PivotField>::const_iterator itr, itrBeg = rFields.begin(), itrEnd = rFields.end();
2447 [ # # ][ # # ]: 0 : for (itr = itrBeg; itr != itrEnd; ++itr)
2448 : : {
2449 : 0 : const PivotField& rField = *itr;
2450 : :
2451 [ # # ]: 0 : long nCol = rField.getOriginalDim();
2452 : 0 : sal_uInt16 nFuncs = rField.nFuncMask;
2453 : 0 : const sheet::DataPilotFieldReference& rFieldRef = rField.maFieldRef;
2454 : :
2455 : 0 : ScDPSaveDimension* pDim = NULL;
2456 [ # # ]: 0 : if ( nCol == PIVOT_DATA_FIELD )
2457 [ # # ]: 0 : pDim = rSaveData.GetDataLayoutDimension();
2458 : : else
2459 : : {
2460 [ # # ]: 0 : rtl::OUString aDocStr = lcl_GetDimName( xSource, nCol ); // cols must start at 0
2461 [ # # ]: 0 : if (!aDocStr.isEmpty())
2462 [ # # ]: 0 : pDim = rSaveData.GetDimensionByName(aDocStr);
2463 : : else
2464 : 0 : pDim = NULL;
2465 : : }
2466 : :
2467 [ # # ]: 0 : if (!pDim)
2468 : 0 : continue;
2469 : :
2470 [ # # ]: 0 : if ( nOrient == sheet::DataPilotFieldOrientation_DATA ) // set summary function
2471 : : {
2472 : : // generate an individual entry for each function
2473 : 0 : bool bFirst = true;
2474 : :
2475 : : // if a dimension is used for column/row/page and data,
2476 : : // use duplicated dimensions for all data occurrences
2477 [ # # ][ # # ]: 0 : if (hasFieldColumn(pRefColFields, nCol))
2478 : 0 : bFirst = false;
2479 : :
2480 [ # # ][ # # ]: 0 : if (bFirst && hasFieldColumn(pRefRowFields, nCol))
[ # # ][ # # ]
2481 : 0 : bFirst = false;
2482 : :
2483 [ # # ][ # # ]: 0 : if (bFirst && hasFieldColumn(pRefPageFields, nCol))
[ # # ][ # # ]
2484 : 0 : bFirst = false;
2485 : :
2486 [ # # ]: 0 : if (bFirst)
2487 : : {
2488 : : // if set via api, a data column may occur several times
2489 : : // (if the function hasn't been changed yet) -> also look for duplicate data column
2490 [ # # ][ # # ]: 0 : bFirst = std::find_if(itrBeg, itr, FindByOriginalDim(nCol)) == itr;
2491 : : }
2492 : :
2493 [ # # ]: 0 : sheet::GeneralFunction eFunc = ScDataPilotConversion::FirstFunc(rField.nFuncMask);
2494 [ # # ]: 0 : if (!bFirst)
2495 [ # # ]: 0 : pDim = rSaveData.DuplicateDimension(pDim->GetName());
2496 [ # # ]: 0 : pDim->SetOrientation(nOrient);
2497 [ # # ]: 0 : pDim->SetFunction(sal::static_int_cast<sal_uInt16>(eFunc));
2498 : :
2499 [ # # ]: 0 : if( rFieldRef.ReferenceType == sheet::DataPilotFieldReferenceType::NONE )
2500 [ # # ]: 0 : pDim->SetReferenceValue(0);
2501 : : else
2502 [ # # ]: 0 : pDim->SetReferenceValue(&rFieldRef);
2503 : : }
2504 : : else // set SubTotals
2505 : : {
2506 [ # # ]: 0 : pDim->SetOrientation( nOrient );
2507 : :
2508 : : sal_uInt16 nFuncArray[16];
2509 : 0 : sal_uInt16 nFuncCount = 0;
2510 : 0 : sal_uInt16 nMask = 1;
2511 [ # # ]: 0 : for (sal_uInt16 nBit=0; nBit<16; nBit++)
2512 : : {
2513 [ # # ]: 0 : if ( nFuncs & nMask )
2514 [ # # ]: 0 : nFuncArray[nFuncCount++] = sal::static_int_cast<sal_uInt16>(ScDataPilotConversion::FirstFunc( nMask ));
2515 : 0 : nMask *= 2;
2516 : : }
2517 [ # # ]: 0 : pDim->SetSubTotals( nFuncCount, nFuncArray );
2518 : :
2519 : : // ShowEmpty was implicit in old tables,
2520 : : // must be set for data layout dimension (not accessible in dialog)
2521 [ # # ]: 0 : if ( nCol == PIVOT_DATA_FIELD )
2522 [ # # ]: 0 : pDim->SetShowEmpty( true );
2523 : : }
2524 : :
2525 : 0 : size_t nDimIndex = rField.nCol;
2526 [ # # ]: 0 : pDim->RemoveLayoutName();
2527 [ # # ]: 0 : pDim->RemoveSubtotalName();
2528 [ # # ]: 0 : if (nDimIndex < rLabels.size())
2529 : : {
2530 [ # # ]: 0 : const ScDPLabelData& rLabel = rLabels[nDimIndex];
2531 [ # # ]: 0 : if (!rLabel.maLayoutName.isEmpty())
2532 [ # # ]: 0 : pDim->SetLayoutName(rLabel.maLayoutName);
2533 [ # # ]: 0 : if (!rLabel.maSubtotalName.isEmpty())
2534 [ # # ]: 0 : pDim->SetSubtotalName(rLabel.maSubtotalName);
2535 : : }
2536 : : }
2537 : 0 : }
2538 : :
2539 : 0 : bool ScDPObject::IsOrientationAllowed( sal_uInt16 nOrient, sal_Int32 nDimFlags )
2540 : : {
2541 : 0 : bool bAllowed = true;
2542 [ # # # # : 0 : switch (nOrient)
# ]
2543 : : {
2544 : : case sheet::DataPilotFieldOrientation_PAGE:
2545 : 0 : bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_PAGE_ORIENTATION ) == 0;
2546 : 0 : break;
2547 : : case sheet::DataPilotFieldOrientation_COLUMN:
2548 : 0 : bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_COLUMN_ORIENTATION ) == 0;
2549 : 0 : break;
2550 : : case sheet::DataPilotFieldOrientation_ROW:
2551 : 0 : bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_ROW_ORIENTATION ) == 0;
2552 : 0 : break;
2553 : : case sheet::DataPilotFieldOrientation_DATA:
2554 : 0 : bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_DATA_ORIENTATION ) == 0;
2555 : 0 : break;
2556 : : default:
2557 : : {
2558 : : // allowed to remove from previous orientation
2559 : : }
2560 : : }
2561 : 0 : return bAllowed;
2562 : : }
2563 : :
2564 : : // -----------------------------------------------------------------------
2565 : :
2566 : 0 : bool ScDPObject::HasRegisteredSources()
2567 : : {
2568 : 0 : bool bFound = false;
2569 : :
2570 [ # # ]: 0 : uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
2571 [ # # ]: 0 : uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
2572 [ # # ]: 0 : if ( xEnAc.is() )
2573 : : {
2574 [ # # ]: 0 : uno::Reference<container::XEnumeration> xEnum = xEnAc->createContentEnumeration(
2575 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SCDPSOURCE_SERVICE )) );
2576 [ # # ][ # # ]: 0 : if ( xEnum.is() && xEnum->hasMoreElements() )
[ # # ][ # # ]
[ # # ]
2577 : 0 : bFound = true;
2578 : : }
2579 : :
2580 : 0 : return bFound;
2581 : : }
2582 : :
2583 : 0 : uno::Sequence<rtl::OUString> ScDPObject::GetRegisteredSources()
2584 : : {
2585 [ # # ]: 0 : uno::Sequence<rtl::OUString> aSeq(0);
2586 : :
2587 : : // use implementation names...
2588 : :
2589 [ # # ]: 0 : uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
2590 [ # # ]: 0 : uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
2591 [ # # ]: 0 : if ( xEnAc.is() )
2592 : : {
2593 [ # # ]: 0 : uno::Reference<container::XEnumeration> xEnum = xEnAc->createContentEnumeration(
2594 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SCDPSOURCE_SERVICE )) );
2595 [ # # ]: 0 : if ( xEnum.is() )
2596 : : {
2597 : 0 : long nCount = 0;
2598 [ # # ][ # # ]: 0 : while ( xEnum->hasMoreElements() )
[ # # ]
2599 : : {
2600 [ # # ][ # # ]: 0 : uno::Any aAddInAny = xEnum->nextElement();
2601 : : // if ( aAddInAny.getReflection()->getTypeClass() == TypeClass_INTERFACE )
2602 : : {
2603 : 0 : uno::Reference<uno::XInterface> xIntFac;
2604 [ # # ]: 0 : aAddInAny >>= xIntFac;
2605 [ # # ]: 0 : if ( xIntFac.is() )
2606 : : {
2607 [ # # ]: 0 : uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
2608 [ # # ]: 0 : if ( xInfo.is() )
2609 : : {
2610 [ # # ][ # # ]: 0 : rtl::OUString sName = xInfo->getImplementationName();
2611 : :
2612 [ # # ]: 0 : aSeq.realloc( nCount+1 );
2613 [ # # ]: 0 : aSeq.getArray()[nCount] = sName;
2614 : 0 : ++nCount;
2615 : 0 : }
2616 : 0 : }
2617 : : }
2618 : 0 : }
2619 : 0 : }
2620 : : }
2621 : :
2622 : 0 : return aSeq;
2623 : : }
2624 : :
2625 : : // use getContext from addincol.cxx
2626 : : uno::Reference<uno::XComponentContext> getContext(uno::Reference<lang::XMultiServiceFactory> xMSF);
2627 : :
2628 : 0 : uno::Reference<sheet::XDimensionsSupplier> ScDPObject::CreateSource( const ScDPServiceDesc& rDesc )
2629 : : {
2630 : 0 : rtl::OUString aImplName = rDesc.aServiceName;
2631 [ # # ]: 0 : uno::Reference<sheet::XDimensionsSupplier> xRet = NULL;
2632 : :
2633 [ # # ]: 0 : uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
2634 [ # # ]: 0 : uno::Reference<container::XContentEnumerationAccess> xEnAc(xManager, uno::UNO_QUERY);
2635 [ # # ]: 0 : if (!xEnAc.is())
2636 : : return xRet;
2637 : :
2638 : : uno::Reference<container::XEnumeration> xEnum =
2639 [ # # ][ # # ]: 0 : xEnAc->createContentEnumeration(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SCDPSOURCE_SERVICE)));
[ # # ]
2640 [ # # ]: 0 : if (!xEnum.is())
2641 : : return xRet;
2642 : :
2643 [ # # ][ # # ]: 0 : while (xEnum->hasMoreElements() && !xRet.is())
[ # # ][ # # ]
[ # # ]
2644 : : {
2645 [ # # ][ # # ]: 0 : uno::Any aAddInAny = xEnum->nextElement();
2646 : 0 : uno::Reference<uno::XInterface> xIntFac;
2647 [ # # ]: 0 : aAddInAny >>= xIntFac;
2648 [ # # ]: 0 : if (!xIntFac.is())
2649 : 0 : continue;
2650 : :
2651 [ # # ]: 0 : uno::Reference<lang::XServiceInfo> xInfo(xIntFac, uno::UNO_QUERY);
2652 [ # # ][ # # ]: 0 : if (!xInfo.is() || xInfo->getImplementationName() != aImplName)
[ # # ][ # # ]
[ # # ]
[ # # # # ]
2653 : 0 : continue;
2654 : :
2655 : : try
2656 : : {
2657 : : // #i113160# try XSingleComponentFactory in addition to (old) XSingleServiceFactory,
2658 : : // passing the context to the component (see ScUnoAddInCollection::Initialize)
2659 : :
2660 : 0 : uno::Reference<uno::XInterface> xInterface;
2661 [ # # ]: 0 : uno::Reference<uno::XComponentContext> xCtx = getContext(xManager);
2662 [ # # ]: 0 : uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY );
2663 [ # # ][ # # ]: 0 : if (xCtx.is() && xCFac.is())
[ # # ]
2664 [ # # ][ # # ]: 0 : xInterface = xCFac->createInstanceWithContext(xCtx);
[ # # ]
2665 : :
2666 [ # # ]: 0 : if (!xInterface.is())
2667 : : {
2668 [ # # ]: 0 : uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
2669 [ # # ]: 0 : if ( xFac.is() )
2670 [ # # ][ # # ]: 0 : xInterface = xFac->createInstance();
[ # # ]
2671 : : }
2672 : :
2673 [ # # ]: 0 : uno::Reference<lang::XInitialization> xInit( xInterface, uno::UNO_QUERY );
2674 [ # # ]: 0 : if (xInit.is())
2675 : : {
2676 : : // initialize
2677 [ # # ]: 0 : uno::Sequence<uno::Any> aSeq(4);
2678 [ # # ]: 0 : uno::Any* pArray = aSeq.getArray();
2679 [ # # ]: 0 : pArray[0] <<= rtl::OUString( rDesc.aParSource );
2680 [ # # ]: 0 : pArray[1] <<= rtl::OUString( rDesc.aParName );
2681 [ # # ]: 0 : pArray[2] <<= rtl::OUString( rDesc.aParUser );
2682 [ # # ]: 0 : pArray[3] <<= rtl::OUString( rDesc.aParPass );
2683 [ # # ][ # # ]: 0 : xInit->initialize( aSeq );
[ # # ]
2684 : : }
2685 [ # # ][ # # ]: 0 : xRet = uno::Reference<sheet::XDimensionsSupplier>( xInterface, uno::UNO_QUERY );
[ # # ]
2686 : : }
2687 [ # # ]: 0 : catch(uno::Exception&)
2688 : : {
2689 : : }
2690 [ # # ][ # # ]: 0 : }
[ # # ]
2691 : :
2692 : 0 : return xRet;
2693 : : }
2694 : :
2695 : : #if DEBUG_PIVOT_TABLE
2696 : : void ScDPObject::DumpCache() const
2697 : : {
2698 : : if (!mpTableData)
2699 : : return;
2700 : :
2701 : : const ScDPCache* pCache = mpTableData->GetCacheTable().getCache();
2702 : : if (!pCache)
2703 : : return;
2704 : :
2705 : : pCache->Dump();
2706 : : }
2707 : : #endif
2708 : :
2709 [ + - ]: 194 : ScDPCollection::SheetCaches::SheetCaches(ScDocument* pDoc) : mpDoc(pDoc) {}
2710 : :
2711 : : namespace {
2712 : :
2713 : : struct FindInvalidRange : public std::unary_function<ScRange, bool>
2714 : : {
2715 : 35 : bool operator() (const ScRange& r) const
2716 : : {
2717 : 35 : return !r.IsValid();
2718 : : }
2719 : : };
2720 : :
2721 : : }
2722 : :
2723 : 39 : bool ScDPCollection::SheetCaches::hasCache(const ScRange& rRange) const
2724 : : {
2725 [ + - ]: 39 : RangeIndexType::const_iterator it = std::find(maRanges.begin(), maRanges.end(), rRange);
2726 [ + - ][ + + ]: 39 : if (it == maRanges.end())
2727 : 14 : return false;
2728 : :
2729 : : // Already cached.
2730 [ + - ]: 25 : size_t nIndex = std::distance(maRanges.begin(), it);
2731 [ + - ]: 25 : CachesType::const_iterator itCache = maCaches.find(nIndex);
2732 [ + - ][ + - ]: 39 : return itCache != maCaches.end();
2733 : : }
2734 : :
2735 : 120 : const ScDPCache* ScDPCollection::SheetCaches::getCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData)
2736 : : {
2737 [ + - ]: 120 : RangeIndexType::iterator it = std::find(maRanges.begin(), maRanges.end(), rRange);
2738 [ + - ][ + + ]: 120 : if (it != maRanges.end())
2739 : : {
2740 : : // Already cached.
2741 [ + - ]: 31 : size_t nIndex = std::distance(maRanges.begin(), it);
2742 [ + - ]: 31 : CachesType::iterator itCache = maCaches.find(nIndex);
2743 [ + - ][ + - ]: 31 : if (itCache == maCaches.end())
[ - + ]
2744 : : {
2745 : : OSL_FAIL("Cache pool and index pool out-of-sync !!!");
2746 : 0 : return NULL;
2747 : : }
2748 : :
2749 [ + - ]: 31 : return itCache->second;
2750 : : }
2751 : :
2752 : : // Not cached. Create a new cache.
2753 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2754 [ + - ][ + - ]: 89 : ::std::auto_ptr<ScDPCache> pCache(new ScDPCache(mpDoc));
2755 : : SAL_WNODEPRECATED_DECLARATIONS_POP
2756 [ + - ]: 89 : pCache->InitFromDoc(mpDoc, rRange);
2757 [ - + ]: 89 : if (pDimData)
2758 [ # # ]: 0 : pDimData->WriteToCache(*pCache);
2759 : :
2760 : : // Get the smallest available range index.
2761 [ + - ]: 89 : it = std::find_if(maRanges.begin(), maRanges.end(), FindInvalidRange());
2762 : :
2763 : 89 : size_t nIndex = maRanges.size();
2764 [ + + ][ + - ]: 89 : if (it == maRanges.end())
2765 : : {
2766 : : // All range indices are valid. Append a new index.
2767 [ + - ]: 60 : maRanges.push_back(rRange);
2768 : : }
2769 : : else
2770 : : {
2771 : : // Slot with invalid range. Re-use this slot.
2772 : 29 : *it = rRange;
2773 [ + - ]: 29 : nIndex = std::distance(maRanges.begin(), it);
2774 : : }
2775 : :
2776 : 89 : const ScDPCache* p = pCache.get();
2777 [ + - ][ + - ]: 89 : maCaches.insert(nIndex, pCache);
2778 [ + - ]: 120 : return p;
2779 : : }
2780 : :
2781 : 11 : ScDPCache* ScDPCollection::SheetCaches::getExistingCache(const ScRange& rRange)
2782 : : {
2783 [ + - ]: 11 : RangeIndexType::iterator it = std::find(maRanges.begin(), maRanges.end(), rRange);
2784 [ + - ][ - + ]: 11 : if (it == maRanges.end())
2785 : : // Not cached.
2786 : 0 : return NULL;
2787 : :
2788 : : // Already cached.
2789 [ + - ]: 11 : size_t nIndex = std::distance(maRanges.begin(), it);
2790 [ + - ]: 11 : CachesType::iterator itCache = maCaches.find(nIndex);
2791 [ + - ][ + - ]: 11 : if (itCache == maCaches.end())
[ - + ]
2792 : : {
2793 : : OSL_FAIL("Cache pool and index pool out-of-sync !!!");
2794 : 0 : return NULL;
2795 : : }
2796 : :
2797 [ + - ]: 11 : return itCache->second;
2798 : : }
2799 : :
2800 : 48 : size_t ScDPCollection::SheetCaches::size() const
2801 : : {
2802 : 48 : return maCaches.size();
2803 : : }
2804 : :
2805 : 93 : void ScDPCollection::SheetCaches::updateReference(
2806 : : UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz)
2807 : : {
2808 [ + + ]: 93 : if (maRanges.empty())
2809 : : // No caches.
2810 : 93 : return;
2811 : :
2812 : 68 : RangeIndexType::iterator it = maRanges.begin(), itEnd = maRanges.end();
2813 [ + - ][ + + ]: 193 : for (; it != itEnd; ++it)
2814 : : {
2815 : 100 : const ScRange& rKeyRange = *it;
2816 : 100 : SCCOL nCol1 = rKeyRange.aStart.Col();
2817 : 100 : SCROW nRow1 = rKeyRange.aStart.Row();
2818 : 100 : SCTAB nTab1 = rKeyRange.aStart.Tab();
2819 : 100 : SCCOL nCol2 = rKeyRange.aEnd.Col();
2820 : 100 : SCROW nRow2 = rKeyRange.aEnd.Row();
2821 : 100 : SCTAB nTab2 = rKeyRange.aEnd.Tab();
2822 : :
2823 : : ScRefUpdateRes eRes = ScRefUpdate::Update(
2824 : : mpDoc, eMode,
2825 : 200 : r.aStart.Col(), r.aStart.Row(), r.aStart.Tab(),
2826 : 200 : r.aEnd.Col(), r.aEnd.Row(), r.aEnd.Tab(), nDx, nDy, nDz,
2827 [ + - ]: 300 : nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2828 : :
2829 [ + + ]: 100 : if (eRes != UR_NOTHING)
2830 : : {
2831 : : // range updated.
2832 : 35 : ScRange aNew(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2833 : 35 : *it = aNew;
2834 : : }
2835 : : }
2836 : : }
2837 : :
2838 : 8 : void ScDPCollection::SheetCaches::updateCache(
2839 : : const ScRange& rRange, const ScDPDimensionSaveData* pDimData, std::set<ScDPObject*>& rRefs)
2840 : : {
2841 [ + - ]: 8 : RangeIndexType::iterator it = std::find(maRanges.begin(), maRanges.end(), rRange);
2842 [ + - ][ - + ]: 8 : if (it == maRanges.end())
2843 : : {
2844 : : // Not cached. Nothing to do.
2845 : 0 : rRefs.clear();
2846 : : return;
2847 : : }
2848 : :
2849 [ + - ]: 8 : size_t nIndex = std::distance(maRanges.begin(), it);
2850 [ + - ]: 8 : CachesType::iterator itCache = maCaches.find(nIndex);
2851 [ + - ][ + - ]: 8 : if (itCache == maCaches.end())
[ - + ]
2852 : : {
2853 : : OSL_FAIL("Cache pool and index pool out-of-sync !!!");
2854 : 0 : rRefs.clear();
2855 : : return;
2856 : : }
2857 : :
2858 [ + - ]: 8 : ScDPCache& rCache = *itCache->second;
2859 [ + - ]: 8 : rCache.InitFromDoc(mpDoc, rRange);
2860 [ - + ]: 8 : if (pDimData)
2861 [ # # ]: 0 : pDimData->WriteToCache(rCache);
2862 : :
2863 [ + - ][ + - ]: 8 : std::set<ScDPObject*> aRefs(rCache.GetAllReferences());
2864 [ + - ]: 8 : rRefs.swap(aRefs);
2865 : : }
2866 : :
2867 : 76 : bool ScDPCollection::SheetCaches::remove(const ScDPCache* p)
2868 : : {
2869 [ + - ][ + - ]: 76 : CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end();
2870 [ + - ][ + - ]: 81 : for (; it != itEnd; ++it)
[ + + ]
2871 : : {
2872 [ + - ][ + + ]: 78 : if (it->second == p)
2873 : : {
2874 [ + - ]: 73 : size_t idx = it->first;
2875 [ + - ]: 73 : maCaches.erase(it);
2876 : 73 : maRanges[idx].SetInvalid();
2877 : 73 : return true;
2878 : : }
2879 : : }
2880 : 76 : return false;
2881 : : }
2882 : :
2883 : 194 : ScDPCollection::NameCaches::NameCaches(ScDocument* pDoc) : mpDoc(pDoc) {}
2884 : :
2885 : 3 : bool ScDPCollection::NameCaches::hasCache(const OUString& rName) const
2886 : : {
2887 : 3 : return maCaches.count(rName) != 0;
2888 : : }
2889 : :
2890 : 3 : const ScDPCache* ScDPCollection::NameCaches::getCache(
2891 : : const OUString& rName, const ScRange& rRange, const ScDPDimensionSaveData* pDimData)
2892 : : {
2893 [ + - ][ + - ]: 3 : CachesType::const_iterator itr = maCaches.find(rName);
2894 [ + - ][ + - ]: 3 : if (itr != maCaches.end())
[ - + ]
2895 : : // already cached.
2896 [ # # ]: 0 : return itr->second;
2897 : :
2898 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2899 [ + - ][ + - ]: 3 : ::std::auto_ptr<ScDPCache> pCache(new ScDPCache(mpDoc));
2900 : : SAL_WNODEPRECATED_DECLARATIONS_POP
2901 [ + - ]: 3 : pCache->InitFromDoc(mpDoc, rRange);
2902 [ - + ]: 3 : if (pDimData)
2903 [ # # ]: 0 : pDimData->WriteToCache(*pCache);
2904 : :
2905 : 3 : const ScDPCache* p = pCache.get();
2906 [ + - ][ + - ]: 3 : maCaches.insert(rName, pCache);
2907 [ + - ]: 3 : return p;
2908 : : }
2909 : :
2910 : 0 : ScDPCache* ScDPCollection::NameCaches::getExistingCache(const OUString& rName)
2911 : : {
2912 [ # # ]: 0 : CachesType::iterator itr = maCaches.find(rName);
2913 [ # # ][ # # ]: 0 : return itr != maCaches.end() ? itr->second : NULL;
[ # # ][ # # ]
[ # # ][ # # ]
2914 : : }
2915 : :
2916 : 9 : size_t ScDPCollection::NameCaches::size() const
2917 : : {
2918 : 9 : return maCaches.size();
2919 : : }
2920 : :
2921 : 0 : void ScDPCollection::NameCaches::updateCache(
2922 : : const OUString& rName, const ScRange& rRange, const ScDPDimensionSaveData* pDimData,
2923 : : std::set<ScDPObject*>& rRefs)
2924 : : {
2925 [ # # ]: 0 : CachesType::iterator itr = maCaches.find(rName);
2926 [ # # ][ # # ]: 0 : if (itr == maCaches.end())
[ # # ]
2927 : : {
2928 : 0 : rRefs.clear();
2929 : 0 : return;
2930 : : }
2931 : :
2932 [ # # ]: 0 : ScDPCache& rCache = *itr->second;
2933 [ # # ]: 0 : rCache.InitFromDoc(mpDoc, rRange);
2934 [ # # ]: 0 : if (pDimData)
2935 [ # # ]: 0 : pDimData->WriteToCache(rCache);
2936 : :
2937 [ # # ][ # # ]: 0 : std::set<ScDPObject*> aRefs(rCache.GetAllReferences());
2938 [ # # ]: 0 : rRefs.swap(aRefs);
2939 : : }
2940 : :
2941 : 3 : bool ScDPCollection::NameCaches::remove(const ScDPCache* p)
2942 : : {
2943 [ + - ][ + - ]: 3 : CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end();
2944 [ # # ][ + - ]: 3 : for (; it != itEnd; ++it)
[ + - ]
2945 : : {
2946 [ + - ][ + - ]: 3 : if (it->second == p)
2947 : : {
2948 [ + - ]: 3 : maCaches.erase(it);
2949 : 3 : return true;
2950 : : }
2951 : : }
2952 : 3 : return false;
2953 : : }
2954 : :
2955 : 0 : ScDPCollection::DBType::DBType(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) :
2956 : 0 : mnSdbType(nSdbType), maDBName(rDBName), maCommand(rCommand) {}
2957 : :
2958 : 0 : bool ScDPCollection::DBType::less::operator() (const DBType& left, const DBType& right) const
2959 : : {
2960 : 0 : return left < right;
2961 : : }
2962 : :
2963 : 194 : ScDPCollection::DBCaches::DBCaches(ScDocument* pDoc) : mpDoc(pDoc) {}
2964 : :
2965 : 0 : bool ScDPCollection::DBCaches::hasCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) const
2966 : : {
2967 : 0 : DBType aType(nSdbType, rDBName, rCommand);
2968 [ # # ]: 0 : CachesType::const_iterator itr = maCaches.find(aType);
2969 [ # # ][ # # ]: 0 : return itr != maCaches.end();
2970 : : }
2971 : :
2972 : 0 : const ScDPCache* ScDPCollection::DBCaches::getCache(
2973 : : sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand,
2974 : : const ScDPDimensionSaveData* pDimData)
2975 : : {
2976 : 0 : DBType aType(nSdbType, rDBName, rCommand);
2977 [ # # ][ # # ]: 0 : CachesType::const_iterator itr = maCaches.find(aType);
2978 [ # # ][ # # ]: 0 : if (itr != maCaches.end())
[ # # ]
2979 : : // already cached.
2980 [ # # ]: 0 : return itr->second;
2981 : :
2982 [ # # ]: 0 : uno::Reference<sdbc::XRowSet> xRowSet = createRowSet(nSdbType, rDBName, rCommand);
2983 [ # # ]: 0 : if (!xRowSet.is())
2984 : 0 : return NULL;
2985 : :
2986 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2987 [ # # ][ # # ]: 0 : ::std::auto_ptr<ScDPCache> pCache(new ScDPCache(mpDoc));
2988 : : SAL_WNODEPRECATED_DECLARATIONS_POP
2989 [ # # ][ # # ]: 0 : SvNumberFormatter aFormat(mpDoc->GetServiceManager(), ScGlobal::eLnge);
2990 [ # # ][ # # ]: 0 : DBConnector aDB(*pCache, xRowSet, *aFormat.GetNullDate());
2991 [ # # ]: 0 : if (!aDB.isValid())
2992 : 0 : return NULL;
2993 : :
2994 [ # # ][ # # ]: 0 : if (!pCache->InitFromDataBase(aDB))
2995 : : {
2996 : : // initialization failed.
2997 [ # # ]: 0 : comphelper::disposeComponent(xRowSet);
2998 : 0 : return NULL;
2999 : : }
3000 : :
3001 [ # # ]: 0 : if (pDimData)
3002 [ # # ]: 0 : pDimData->WriteToCache(*pCache);
3003 : :
3004 [ # # ]: 0 : ::comphelper::disposeComponent(xRowSet);
3005 : 0 : const ScDPCache* p = pCache.get();
3006 [ # # ][ # # ]: 0 : maCaches.insert(aType, pCache);
3007 [ # # ][ # # ]: 0 : return p;
3008 : : }
3009 : :
3010 : 0 : ScDPCache* ScDPCollection::DBCaches::getExistingCache(
3011 : : sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand)
3012 : : {
3013 : 0 : DBType aType(nSdbType, rDBName, rCommand);
3014 [ # # ]: 0 : CachesType::iterator itr = maCaches.find(aType);
3015 [ # # ][ # # ]: 0 : return itr != maCaches.end() ? itr->second : NULL;
[ # # ][ # # ]
[ # # ][ # # ]
3016 : : }
3017 : :
3018 : 0 : uno::Reference<sdbc::XRowSet> ScDPCollection::DBCaches::createRowSet(
3019 : : sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand)
3020 : : {
3021 : 0 : uno::Reference<sdbc::XRowSet> xRowSet;
3022 : : try
3023 : : {
3024 : : xRowSet = uno::Reference<sdbc::XRowSet>(
3025 [ # # ][ # # ]: 0 : comphelper::getProcessServiceFactory()->createInstance(
3026 : 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SERVICE_ROWSET))),
3027 [ # # ][ # # ]: 0 : UNO_QUERY);
[ # # ][ # # ]
3028 : :
3029 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xRowProp(xRowSet, UNO_QUERY);
3030 : : OSL_ENSURE( xRowProp.is(), "can't get RowSet" );
3031 [ # # ]: 0 : if (!xRowProp.is())
3032 : : {
3033 [ # # ]: 0 : xRowSet.set(NULL);
3034 : : return xRowSet;
3035 : : }
3036 : :
3037 : : //
3038 : : // set source parameters
3039 : : //
3040 : 0 : uno::Any aAny;
3041 [ # # ]: 0 : aAny <<= rDBName;
3042 [ # # ]: 0 : xRowProp->setPropertyValue(
3043 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_DATASOURCENAME)), aAny );
3044 : :
3045 [ # # ]: 0 : aAny <<= rCommand;
3046 [ # # ]: 0 : xRowProp->setPropertyValue(
3047 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMAND)), aAny );
3048 : :
3049 [ # # ]: 0 : aAny <<= nSdbType;
3050 [ # # ]: 0 : xRowProp->setPropertyValue(
3051 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMANDTYPE)), aAny );
3052 : :
3053 [ # # ]: 0 : uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
3054 [ # # ]: 0 : if ( xExecute.is() )
3055 : : {
3056 : : uno::Reference<task::XInteractionHandler> xHandler(
3057 [ # # ][ # # ]: 0 : comphelper::getProcessServiceFactory()->createInstance(
3058 : 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_SERVICE_INTHANDLER )) ),
3059 [ # # ][ # # ]: 0 : uno::UNO_QUERY);
[ # # ]
3060 [ # # ][ # # ]: 0 : xExecute->executeWithCompletion( xHandler );
3061 : : }
3062 : : else
3063 [ # # ][ # # ]: 0 : xRowSet->execute();
3064 : :
3065 : 0 : return xRowSet;
3066 : : }
3067 [ # # # # : 0 : catch ( const sdbc::SQLException& rError )
# ]
3068 : : {
3069 : : //! store error message
3070 [ # # # # : 0 : InfoBox aInfoBox( 0, String(rError.Message) );
# # ]
3071 [ # # # # ]: 0 : aInfoBox.Execute();
3072 : : }
3073 [ # # ]: 0 : catch ( uno::Exception& )
3074 : : {
3075 : : OSL_FAIL("Unexpected exception in database");
3076 : : }
3077 : :
3078 [ # # ]: 0 : xRowSet.set(NULL);
3079 : 0 : return xRowSet;
3080 : : }
3081 : :
3082 : 0 : void ScDPCollection::DBCaches::updateCache(
3083 : : sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand,
3084 : : const ScDPDimensionSaveData* pDimData, std::set<ScDPObject*>& rRefs)
3085 : : {
3086 : 0 : DBType aType(nSdbType, rDBName, rCommand);
3087 [ # # ]: 0 : CachesType::iterator it = maCaches.find(aType);
3088 [ # # ][ # # ]: 0 : if (it == maCaches.end())
[ # # ]
3089 : : {
3090 : : // not cached.
3091 : 0 : rRefs.clear();
3092 : : return;
3093 : : }
3094 : :
3095 [ # # ]: 0 : ScDPCache& rCache = *it->second;
3096 : :
3097 [ # # ]: 0 : uno::Reference<sdbc::XRowSet> xRowSet = createRowSet(nSdbType, rDBName, rCommand);
3098 [ # # ]: 0 : if (!xRowSet.is())
3099 : : {
3100 : 0 : rRefs.clear();
3101 : : return;
3102 : : }
3103 : :
3104 [ # # ][ # # ]: 0 : SvNumberFormatter aFormat(mpDoc->GetServiceManager(), ScGlobal::eLnge);
3105 [ # # ][ # # ]: 0 : DBConnector aDB(rCache, xRowSet, *aFormat.GetNullDate());
3106 [ # # ]: 0 : if (!aDB.isValid())
3107 : : return;
3108 : :
3109 [ # # ][ # # ]: 0 : if (!rCache.InitFromDataBase(aDB))
3110 : : {
3111 : : // initialization failed.
3112 : 0 : rRefs.clear();
3113 [ # # ]: 0 : comphelper::disposeComponent(xRowSet);
3114 : : return;
3115 : : }
3116 : :
3117 [ # # ]: 0 : if (pDimData)
3118 [ # # ]: 0 : pDimData->WriteToCache(rCache);
3119 : :
3120 [ # # ]: 0 : comphelper::disposeComponent(xRowSet);
3121 [ # # ][ # # ]: 0 : std::set<ScDPObject*> aRefs(rCache.GetAllReferences());
3122 [ # # ][ # # ]: 0 : aRefs.swap(rRefs);
[ # # ][ # # ]
[ # # ][ # # ]
3123 : : }
3124 : :
3125 : 0 : bool ScDPCollection::DBCaches::remove(const ScDPCache* p)
3126 : : {
3127 [ # # ][ # # ]: 0 : CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end();
3128 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
3129 : : {
3130 [ # # ][ # # ]: 0 : if (it->second == p)
3131 : : {
3132 [ # # ]: 0 : maCaches.erase(it);
3133 : 0 : return true;
3134 : : }
3135 : : }
3136 : 0 : return false;
3137 : : }
3138 : :
3139 : 158 : ScDPCollection::ScDPCollection(ScDocument* pDocument) :
3140 : : mpDoc( pDocument ),
3141 : : maSheetCaches(pDocument),
3142 : : maNameCaches(pDocument),
3143 [ + - ][ + - ]: 158 : maDBCaches(pDocument)
[ + - ]
3144 : : {
3145 : 158 : }
3146 : :
3147 : 36 : ScDPCollection::ScDPCollection(const ScDPCollection& r) :
3148 : : mpDoc(r.mpDoc),
3149 : : maSheetCaches(r.mpDoc),
3150 : : maNameCaches(r.mpDoc),
3151 [ + - ][ + - ]: 36 : maDBCaches(r.mpDoc)
[ + - ]
3152 : : {
3153 : 36 : }
3154 : :
3155 [ + - ][ + - ]: 142 : ScDPCollection::~ScDPCollection()
[ + - ]
3156 : : {
3157 [ + - ]: 142 : maTables.clear();
3158 : 142 : }
3159 : :
3160 : : namespace {
3161 : :
3162 : : /**
3163 : : * Unary predicate to match DP objects by the table ID.
3164 : : */
3165 : : class MatchByTable : public unary_function<ScDPObject, bool>
3166 : : {
3167 : : SCTAB mnTab;
3168 : : public:
3169 : 58 : MatchByTable(SCTAB nTab) : mnTab(nTab) {}
3170 : :
3171 : 32 : bool operator() (const ScDPObject& rObj) const
3172 : : {
3173 : 32 : return rObj.GetOutRange().aStart.Tab() == mnTab;
3174 : : }
3175 : : };
3176 : :
3177 : : }
3178 : :
3179 : 13 : sal_uLong ScDPCollection::ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs)
3180 : : {
3181 [ - + ]: 13 : if (!pDPObj)
3182 : 0 : return STR_ERR_DATAPILOTSOURCE;
3183 : :
3184 : 13 : const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
3185 : 13 : const ScDPDimensionSaveData* pDimData = NULL;
3186 [ + - ]: 13 : if (pSaveData)
3187 : 13 : pDimData = pSaveData->GetExistingDimensionData();
3188 : :
3189 [ + - ]: 13 : if (pDPObj->IsSheetData())
3190 : : {
3191 : : // data source is internal sheet.
3192 : 13 : const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
3193 [ - + ]: 13 : if (!pDesc)
3194 : 0 : return STR_ERR_DATAPILOTSOURCE;
3195 : :
3196 : 13 : sal_uLong nErrId = pDesc->CheckSourceRange();
3197 [ - + ]: 13 : if (nErrId)
3198 : 0 : return nErrId;
3199 : :
3200 [ - + ]: 13 : if (pDesc->HasRangeName())
3201 : : {
3202 : : // cache by named range
3203 : 0 : ScDPCollection::NameCaches& rCaches = GetNameCaches();
3204 [ # # ]: 0 : if (rCaches.hasCache(pDesc->GetRangeName()))
3205 : 0 : rCaches.updateCache(pDesc->GetRangeName(), pDesc->GetSourceRange(), pDimData, rRefs);
3206 : : else
3207 : : {
3208 : : // Not cached yet. Collect all tables that use this named
3209 : : // range as data source.
3210 : 0 : GetAllTables(pDesc->GetRangeName(), rRefs);
3211 : : }
3212 : : }
3213 : : else
3214 : : {
3215 : : // cache by cell range
3216 : 13 : ScDPCollection::SheetCaches& rCaches = GetSheetCaches();
3217 [ + + ]: 13 : if (rCaches.hasCache(pDesc->GetSourceRange()))
3218 : 8 : rCaches.updateCache(pDesc->GetSourceRange(), pDimData, rRefs);
3219 : : else
3220 : : {
3221 : : // Not cached yet. Collect all tables that use this range as
3222 : : // data source.
3223 : 5 : GetAllTables(pDesc->GetSourceRange(), rRefs);
3224 : : }
3225 : : }
3226 : : }
3227 [ # # ]: 0 : else if (pDPObj->IsImportData())
3228 : : {
3229 : : // data source is external database.
3230 : 0 : const ScImportSourceDesc* pDesc = pDPObj->GetImportSourceDesc();
3231 [ # # ]: 0 : if (!pDesc)
3232 : 0 : return STR_ERR_DATAPILOTSOURCE;
3233 : :
3234 : 0 : ScDPCollection::DBCaches& rCaches = GetDBCaches();
3235 [ # # ]: 0 : if (rCaches.hasCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject))
3236 : : rCaches.updateCache(
3237 : 0 : pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, pDimData, rRefs);
3238 : : else
3239 : : {
3240 : : // Not cached yet. Collect all tables that use this range as
3241 : : // data source.
3242 : 0 : GetAllTables(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, rRefs);
3243 : : }
3244 : : }
3245 : 13 : return 0;
3246 : : }
3247 : :
3248 : 17 : bool ScDPCollection::ReloadGroupsInCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs)
3249 : : {
3250 [ - + ]: 17 : if (!pDPObj)
3251 : 0 : return false;
3252 : :
3253 : 17 : const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
3254 [ - + ]: 17 : if (!pSaveData)
3255 : 0 : return false;
3256 : :
3257 : : // Note: Unlike reloading cache, when modifying the group dimensions the
3258 : : // cache may not have all its references when this method is called.
3259 : : // Therefore, we need to always call GetAllTables to get its correct
3260 : : // references even when the cache exists. This may become a non-issue
3261 : : // if/when we implement loading and saving of pivot caches.
3262 : :
3263 : 17 : ScDPCache* pCache = NULL;
3264 : :
3265 [ + - ]: 17 : if (pDPObj->IsSheetData())
3266 : : {
3267 : : // data source is internal sheet.
3268 : 17 : const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
3269 [ - + ]: 17 : if (!pDesc)
3270 : 0 : return false;
3271 : :
3272 [ - + ]: 17 : if (pDesc->HasRangeName())
3273 : : {
3274 : : // cache by named range
3275 : 0 : ScDPCollection::NameCaches& rCaches = GetNameCaches();
3276 [ # # ]: 0 : if (rCaches.hasCache(pDesc->GetRangeName()))
3277 : 0 : pCache = rCaches.getExistingCache(pDesc->GetRangeName());
3278 : : else
3279 : : {
3280 : : // Not cached yet. Cache the source dimensions. Groups will
3281 : : // be added below.
3282 : : pCache = const_cast<ScDPCache*>(
3283 : 0 : rCaches.getCache(pDesc->GetRangeName(), pDesc->GetSourceRange(), NULL));
3284 : : }
3285 : 0 : GetAllTables(pDesc->GetRangeName(), rRefs);
3286 : : }
3287 : : else
3288 : : {
3289 : : // cache by cell range
3290 : 17 : ScDPCollection::SheetCaches& rCaches = GetSheetCaches();
3291 [ + + ]: 17 : if (rCaches.hasCache(pDesc->GetSourceRange()))
3292 : 11 : pCache = rCaches.getExistingCache(pDesc->GetSourceRange());
3293 : : else
3294 : : {
3295 : : // Not cached yet. Cache the source dimensions. Groups will
3296 : : // be added below.
3297 : : pCache = const_cast<ScDPCache*>(
3298 : 6 : rCaches.getCache(pDesc->GetSourceRange(), NULL));
3299 : : }
3300 : 17 : GetAllTables(pDesc->GetSourceRange(), rRefs);
3301 : : }
3302 : : }
3303 [ # # ]: 0 : else if (pDPObj->IsImportData())
3304 : : {
3305 : : // data source is external database.
3306 : 0 : const ScImportSourceDesc* pDesc = pDPObj->GetImportSourceDesc();
3307 [ # # ]: 0 : if (!pDesc)
3308 : 0 : return false;
3309 : :
3310 : 0 : ScDPCollection::DBCaches& rCaches = GetDBCaches();
3311 [ # # ]: 0 : if (rCaches.hasCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject))
3312 : : pCache = rCaches.getExistingCache(
3313 : 0 : pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject);
3314 : : else
3315 : : {
3316 : : // Not cached yet. Cache the source dimensions. Groups will
3317 : : // be added below.
3318 : : pCache = const_cast<ScDPCache*>(
3319 : 0 : rCaches.getCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, NULL));
3320 : : }
3321 : 0 : GetAllTables(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, rRefs);
3322 : : }
3323 : :
3324 [ - + ]: 17 : if (!pCache)
3325 : 0 : return false;
3326 : :
3327 : : // Clear the existing group data from the cache, and rebuild it from the
3328 : : // dimension data.
3329 : 17 : pCache->ClearGroupFields();
3330 : 17 : const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData();
3331 [ + - ]: 17 : if (pDimData)
3332 : 17 : pDimData->WriteToCache(*pCache);
3333 : 17 : return true;
3334 : : }
3335 : :
3336 : 58 : void ScDPCollection::DeleteOnTab( SCTAB nTab )
3337 : : {
3338 [ + - ]: 58 : maTables.erase_if(MatchByTable(nTab));
3339 : 58 : }
3340 : :
3341 : 93 : void ScDPCollection::UpdateReference( UpdateRefMode eUpdateRefMode,
3342 : : const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
3343 : : {
3344 [ + - ][ + - ]: 93 : TablesType::iterator itr = maTables.begin(), itrEnd = maTables.end();
3345 [ + - ][ + - ]: 163 : for (; itr != itrEnd; ++itr)
[ + + ]
3346 [ + - ][ + - ]: 70 : itr->UpdateReference(eUpdateRefMode, r, nDx, nDy, nDz);
3347 : :
3348 : : // Update the source ranges of the caches.
3349 [ + - ]: 93 : maSheetCaches.updateReference(eUpdateRefMode, r, nDx, nDy, nDz);
3350 : 93 : }
3351 : :
3352 : 0 : void ScDPCollection::CopyToTab( SCTAB nOld, SCTAB nNew )
3353 : : {
3354 [ # # ]: 0 : TablesType aAdded;
3355 [ # # ][ # # ]: 0 : TablesType::const_iterator it = maTables.begin(), itEnd = maTables.end();
[ # # ][ # # ]
3356 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
3357 : : {
3358 [ # # ]: 0 : const ScDPObject& rObj = *it;
3359 : 0 : ScRange aOutRange = rObj.GetOutRange();
3360 [ # # ]: 0 : if (aOutRange.aStart.Tab() != nOld)
3361 : 0 : continue;
3362 : :
3363 : 0 : ScAddress& s = aOutRange.aStart;
3364 : 0 : ScAddress& e = aOutRange.aEnd;
3365 : 0 : s.SetTab(nNew);
3366 : 0 : e.SetTab(nNew);
3367 [ # # ][ # # ]: 0 : std::auto_ptr<ScDPObject> pNew(new ScDPObject(rObj));
3368 [ # # ]: 0 : pNew->SetOutRange(aOutRange);
3369 [ # # ]: 0 : mpDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
3370 [ # # ][ # # ]: 0 : aAdded.push_back(pNew);
3371 [ # # ]: 0 : }
3372 : :
3373 [ # # ][ # # ]: 0 : maTables.transfer(maTables.end(), aAdded.begin(), aAdded.end(), aAdded);
[ # # ][ # # ]
[ # # ]
3374 : 0 : }
3375 : :
3376 : 36 : bool ScDPCollection::RefsEqual( const ScDPCollection& r ) const
3377 : : {
3378 [ + + ]: 36 : if (maTables.size() != r.maTables.size())
3379 : 16 : return false;
3380 : :
3381 [ + - ][ + - ]: 20 : TablesType::const_iterator itr = maTables.begin(), itr2 = r.maTables.begin(), itrEnd = maTables.end();
[ + - ]
3382 [ # # ][ # # ]: 20 : for (; itr != itrEnd; ++itr, ++itr2)
[ + - ][ - + ]
3383 [ # # ][ # # ]: 0 : if (!itr->RefsEqual(*itr2))
[ # # ][ # # ]
3384 : 0 : return false;
3385 : :
3386 : 36 : return true;
3387 : : }
3388 : :
3389 : 0 : void ScDPCollection::WriteRefsTo( ScDPCollection& r ) const
3390 : : {
3391 [ # # ]: 0 : if ( maTables.size() == r.maTables.size() )
3392 : : {
3393 : : //! assert equal names?
3394 [ # # ][ # # ]: 0 : TablesType::const_iterator itr = maTables.begin(), itrEnd = maTables.end();
3395 [ # # ]: 0 : TablesType::iterator itr2 = r.maTables.begin();
3396 [ # # ][ # # ]: 0 : for (; itr != itrEnd; ++itr, ++itr2)
[ # # ][ # # ]
3397 [ # # ][ # # ]: 0 : itr->WriteRefsTo(*itr2);
[ # # ]
3398 : : }
3399 : : else
3400 : : {
3401 : : // #i8180# If data pilot tables were deleted with their sheet,
3402 : : // this collection contains extra entries that must be restored.
3403 : : // Matching objects are found by their names.
3404 : 0 : size_t nSrcSize = maTables.size();
3405 : 0 : size_t nDestSize = r.maTables.size();
3406 : : OSL_ENSURE( nSrcSize >= nDestSize, "WriteRefsTo: missing entries in document" );
3407 [ # # ]: 0 : for (size_t nSrcPos = 0; nSrcPos < nSrcSize; ++nSrcPos)
3408 : : {
3409 : 0 : const ScDPObject& rSrcObj = maTables[nSrcPos];
3410 : 0 : const OUString& aName = rSrcObj.GetName();
3411 : 0 : bool bFound = false;
3412 [ # # ][ # # ]: 0 : for (size_t nDestPos = 0; nDestPos < nDestSize && !bFound; ++nDestPos)
[ # # ]
3413 : : {
3414 : 0 : ScDPObject& rDestObj = r.maTables[nDestPos];
3415 [ # # ]: 0 : if (rDestObj.GetName() == aName)
3416 : : {
3417 : 0 : rSrcObj.WriteRefsTo(rDestObj); // found object, copy refs
3418 : 0 : bFound = true;
3419 : : }
3420 : : }
3421 : :
3422 [ # # ]: 0 : if (!bFound)
3423 : : {
3424 : : // none found, re-insert deleted object (see ScUndoDataPilot::Undo)
3425 : :
3426 [ # # ]: 0 : ScDPObject* pDestObj = new ScDPObject(rSrcObj);
3427 : 0 : pDestObj->SetAlive(true);
3428 : 0 : r.InsertNewTable(pDestObj);
3429 : : }
3430 : : }
3431 : : OSL_ENSURE( maTables.size() == r.maTables.size(), "WriteRefsTo: couldn't restore all entries" );
3432 : : }
3433 : 0 : }
3434 : :
3435 : 1328 : size_t ScDPCollection::GetCount() const
3436 : : {
3437 : 1328 : return maTables.size();
3438 : : }
3439 : :
3440 : 1801 : ScDPObject* ScDPCollection::operator [](size_t nIndex)
3441 : : {
3442 : 1801 : return &maTables[nIndex];
3443 : : }
3444 : :
3445 : 0 : const ScDPObject* ScDPCollection::operator [](size_t nIndex) const
3446 : : {
3447 : 0 : return &maTables[nIndex];
3448 : : }
3449 : :
3450 : 25 : const ScDPObject* ScDPCollection::GetByName(const OUString& rName) const
3451 : : {
3452 [ + - ][ + - ]: 25 : TablesType::const_iterator itr = maTables.begin(), itrEnd = maTables.end();
3453 [ + - ][ + - ]: 29 : for (; itr != itrEnd; ++itr)
[ + + ]
3454 [ + - ][ - + ]: 4 : if (itr->GetName() == rName)
3455 [ # # ]: 0 : return &(*itr);
3456 : :
3457 : 25 : return NULL;
3458 : : }
3459 : :
3460 : 39 : OUString ScDPCollection::CreateNewName( sal_uInt16 nMin ) const
3461 : : {
3462 [ + - ]: 39 : OUString aBase(RTL_CONSTASCII_USTRINGPARAM("DataPilot"));
3463 : :
3464 : 39 : size_t n = maTables.size();
3465 [ + - ]: 78 : for (size_t nAdd = 0; nAdd <= n; ++nAdd) // nCount+1 tries
3466 : : {
3467 : 39 : ::rtl::OUStringBuffer aBuf;
3468 [ + - ]: 39 : aBuf.append(aBase);
3469 [ + - ]: 39 : aBuf.append(static_cast<sal_Int32>(nMin + nAdd));
3470 [ + - ]: 39 : OUString aNewName = aBuf.makeStringAndClear();
3471 : 39 : bool bFound = false;
3472 [ + - ][ + - ]: 39 : TablesType::const_iterator itr = maTables.begin(), itrEnd = maTables.end();
3473 [ + - ][ + - ]: 78 : for (; itr != itrEnd; ++itr)
[ + + ]
3474 : : {
3475 [ + - ][ - + ]: 39 : if (itr->GetName() == aNewName)
3476 : : {
3477 : 0 : bFound = true;
3478 : 0 : break;
3479 : : }
3480 : : }
3481 [ + - ]: 39 : if (!bFound)
3482 : 39 : return aNewName; // found unused Name
3483 [ + - ][ - + ]: 39 : }
3484 : 39 : return OUString(); // should not happen
3485 : : }
3486 : :
3487 : 43 : void ScDPCollection::FreeTable(ScDPObject* pDPObj)
3488 : : {
3489 : 43 : const ScRange& rOutRange = pDPObj->GetOutRange();
3490 : 43 : const ScAddress& s = rOutRange.aStart;
3491 : 43 : const ScAddress& e = rOutRange.aEnd;
3492 [ + - ]: 43 : mpDoc->RemoveFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
3493 [ + - ][ + - ]: 43 : TablesType::iterator itr = maTables.begin(), itrEnd = maTables.end();
3494 [ + - ][ + - ]: 44 : for (; itr != itrEnd; ++itr)
[ + - ]
3495 : : {
3496 [ + - ]: 44 : ScDPObject* p = &(*itr);
3497 [ + + ]: 44 : if (p == pDPObj)
3498 : : {
3499 [ + - ]: 43 : maTables.erase(itr);
3500 : 43 : break;
3501 : : }
3502 : : }
3503 : 43 : }
3504 : :
3505 : 67 : bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj)
3506 : : {
3507 : 67 : const ScRange& rOutRange = pDPObj->GetOutRange();
3508 : 67 : const ScAddress& s = rOutRange.aStart;
3509 : 67 : const ScAddress& e = rOutRange.aEnd;
3510 : 67 : mpDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
3511 : :
3512 : 67 : maTables.push_back(pDPObj);
3513 : 67 : return true;
3514 : : }
3515 : :
3516 : 863 : bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const
3517 : : {
3518 : : const ScMergeFlagAttr* pMergeAttr = static_cast<const ScMergeFlagAttr*>(
3519 : 863 : mpDoc->GetAttr(nCol, nRow, nTab, ATTR_MERGE_FLAG));
3520 : :
3521 [ - + ]: 863 : if (!pMergeAttr)
3522 : 0 : return false;
3523 : :
3524 : 863 : return pMergeAttr->HasDPTable();
3525 : : }
3526 : :
3527 : 201 : ScDPCollection::SheetCaches& ScDPCollection::GetSheetCaches()
3528 : : {
3529 : 201 : return maSheetCaches;
3530 : : }
3531 : :
3532 : 15 : ScDPCollection::NameCaches& ScDPCollection::GetNameCaches()
3533 : : {
3534 : 15 : return maNameCaches;
3535 : : }
3536 : :
3537 : 0 : ScDPCollection::DBCaches& ScDPCollection::GetDBCaches()
3538 : : {
3539 : 0 : return maDBCaches;
3540 : : }
3541 : :
3542 : 76 : void ScDPCollection::RemoveCache(const ScDPCache* pCache)
3543 : : {
3544 [ + + ]: 76 : if (maSheetCaches.remove(pCache))
3545 : : // sheet cache removed.
3546 : 73 : return;
3547 : :
3548 [ + - ]: 3 : if (maNameCaches.remove(pCache))
3549 : : // named range cache removed.
3550 : 3 : return;
3551 : :
3552 [ # # ]: 0 : if (maDBCaches.remove(pCache))
3553 : : // database cache removed.
3554 : 76 : return;
3555 : : }
3556 : :
3557 : 22 : void ScDPCollection::GetAllTables(const ScRange& rSrcRange, std::set<ScDPObject*>& rRefs) const
3558 : : {
3559 [ + - ]: 22 : std::set<ScDPObject*> aRefs;
3560 [ + - ][ + - ]: 22 : TablesType::const_iterator it = maTables.begin(), itEnd = maTables.end();
3561 [ + - ][ + - ]: 46 : for (; it != itEnd; ++it)
[ + + ]
3562 : : {
3563 [ + - ]: 24 : const ScDPObject& rObj = *it;
3564 [ + - ][ - + ]: 24 : if (!rObj.IsSheetData())
3565 : : // Source is not a sheet range.
3566 : 0 : continue;
3567 : :
3568 : 24 : const ScSheetSourceDesc* pDesc = rObj.GetSheetDesc();
3569 [ - + ]: 24 : if (!pDesc)
3570 : 0 : continue;
3571 : :
3572 [ + - ][ - + ]: 24 : if (pDesc->HasRangeName())
3573 : : // This table has a range name as its source.
3574 : 0 : continue;
3575 : :
3576 [ + - ][ - + ]: 24 : if (pDesc->GetSourceRange() != rSrcRange)
3577 : : // Different source range.
3578 : 0 : continue;
3579 : :
3580 [ + - ]: 24 : aRefs.insert(const_cast<ScDPObject*>(&rObj));
3581 : : }
3582 : :
3583 [ + - ]: 22 : rRefs.swap(aRefs);
3584 : 22 : }
3585 : :
3586 : 0 : void ScDPCollection::GetAllTables(const rtl::OUString& rSrcName, std::set<ScDPObject*>& rRefs) const
3587 : : {
3588 [ # # ]: 0 : std::set<ScDPObject*> aRefs;
3589 [ # # ][ # # ]: 0 : TablesType::const_iterator it = maTables.begin(), itEnd = maTables.end();
3590 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
3591 : : {
3592 [ # # ]: 0 : const ScDPObject& rObj = *it;
3593 [ # # ][ # # ]: 0 : if (!rObj.IsSheetData())
3594 : : // Source is not a sheet range.
3595 : 0 : continue;
3596 : :
3597 : 0 : const ScSheetSourceDesc* pDesc = rObj.GetSheetDesc();
3598 [ # # ]: 0 : if (!pDesc)
3599 : 0 : continue;
3600 : :
3601 [ # # ][ # # ]: 0 : if (!pDesc->HasRangeName())
3602 : : // This table probably has a sheet range as its source.
3603 : 0 : continue;
3604 : :
3605 [ # # ][ # # ]: 0 : if (pDesc->GetRangeName() != rSrcName)
3606 : : // Different source name.
3607 : 0 : continue;
3608 : :
3609 [ # # ]: 0 : aRefs.insert(const_cast<ScDPObject*>(&rObj));
3610 : : }
3611 : :
3612 [ # # ]: 0 : rRefs.swap(aRefs);
3613 : 0 : }
3614 : :
3615 : 0 : void ScDPCollection::GetAllTables(
3616 : : sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand,
3617 : : std::set<ScDPObject*>& rRefs) const
3618 : : {
3619 [ # # ]: 0 : std::set<ScDPObject*> aRefs;
3620 [ # # ][ # # ]: 0 : TablesType::const_iterator it = maTables.begin(), itEnd = maTables.end();
3621 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
3622 : : {
3623 [ # # ]: 0 : const ScDPObject& rObj = *it;
3624 [ # # ]: 0 : if (!rObj.IsImportData())
3625 : : // Source data is not a database.
3626 : 0 : continue;
3627 : :
3628 : 0 : const ScImportSourceDesc* pDesc = rObj.GetImportSourceDesc();
3629 [ # # ]: 0 : if (!pDesc)
3630 : 0 : continue;
3631 : :
3632 [ # # ][ # # ]: 0 : if (!pDesc->aDBName.equals(rDBName) || !pDesc->aObject.equals(rCommand) || pDesc->GetCommandType() != nSdbType)
[ # # ][ # # ]
[ # # ]
3633 : : // Different database source.
3634 : 0 : continue;
3635 : :
3636 [ # # ]: 0 : aRefs.insert(const_cast<ScDPObject*>(&rObj));
3637 : : }
3638 : :
3639 [ # # ]: 0 : rRefs.swap(aRefs);
3640 : 0 : }
3641 : :
3642 : 0 : bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right)
3643 : : {
3644 [ # # ]: 0 : if (left.mnSdbType != right.mnSdbType)
3645 : 0 : return left.mnSdbType < right.mnSdbType;
3646 : :
3647 [ # # ]: 0 : if (!left.maDBName.equals(right.maDBName))
3648 : 0 : return left.maDBName < right.maDBName;
3649 : :
3650 : 0 : return left.maCommand < right.maCommand;
3651 [ + - ][ + - ]: 153 : }
3652 : :
3653 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|