LCOV - code coverage report
Current view: top level - sc/source/core/data - dpobject.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 701 1807 38.8 %
Date: 2012-08-25 Functions: 84 153 54.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 648 3401 19.1 %

           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: */

Generated by: LCOV version 1.10