LCOV - code coverage report
Current view: top level - sc/source/ui/unoobj - dapiuno.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 1247 1875 66.5 %
Date: 2014-04-11 Functions: 191 258 74.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <algorithm>
      22             : #include <svl/smplhint.hxx>
      23             : #include <vcl/svapp.hxx>
      24             : 
      25             : #include "dapiuno.hxx"
      26             : #include "datauno.hxx"
      27             : #include "miscuno.hxx"
      28             : #include "convuno.hxx"
      29             : #include "docsh.hxx"
      30             : #include "tabvwsh.hxx"
      31             : #include "pivot.hxx"
      32             : #include "rangeutl.hxx"
      33             : #include "dpobject.hxx"
      34             : #include "dpshttab.hxx"
      35             : #include "dpsdbtab.hxx"
      36             : #include "dpsave.hxx"
      37             : #include "dbdocfun.hxx"
      38             : #include "unonames.hxx"
      39             : #include "dpgroup.hxx"
      40             : #include "dpdimsave.hxx"
      41             : #include "hints.hxx"
      42             : 
      43             : #include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
      44             : #include <com/sun/star/sheet/XLevelsSupplier.hpp>
      45             : #include <com/sun/star/sheet/XMembersSupplier.hpp>
      46             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      47             : #include <com/sun/star/sheet/DataImportMode.hpp>
      48             : #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
      49             : #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
      50             : #include <com/sun/star/sheet/DataPilotOutputRangeType.hpp>
      51             : #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
      52             : 
      53             : #include <comphelper/extract.hxx>
      54             : #include <comphelper/sequence.hxx>
      55             : #include <comphelper/servicehelper.hxx>
      56             : 
      57             : using namespace com::sun::star;
      58             : using namespace com::sun::star::sheet;
      59             : 
      60             : 
      61             : using ::com::sun::star::uno::Any;
      62             : using ::com::sun::star::uno::Exception;
      63             : using ::com::sun::star::uno::Reference;
      64             : using ::com::sun::star::uno::RuntimeException;
      65             : using ::com::sun::star::uno::Sequence;
      66             : using ::com::sun::star::uno::UNO_QUERY;
      67             : using ::com::sun::star::uno::UNO_QUERY_THROW;
      68             : 
      69             : using ::com::sun::star::container::ElementExistException;
      70             : using ::com::sun::star::container::NoSuchElementException;
      71             : using ::com::sun::star::container::XEnumeration;
      72             : using ::com::sun::star::container::XIndexAccess;
      73             : using ::com::sun::star::container::XNameAccess;
      74             : using ::com::sun::star::container::XNamed;
      75             : 
      76             : using ::com::sun::star::beans::PropertyVetoException;
      77             : using ::com::sun::star::beans::UnknownPropertyException;
      78             : using ::com::sun::star::beans::XPropertyChangeListener;
      79             : using ::com::sun::star::beans::XPropertySet;
      80             : using ::com::sun::star::beans::XPropertySetInfo;
      81             : using ::com::sun::star::beans::XVetoableChangeListener;
      82             : 
      83             : using ::com::sun::star::lang::IllegalArgumentException;
      84             : using ::com::sun::star::lang::IndexOutOfBoundsException;
      85             : using ::com::sun::star::lang::WrappedTargetException;
      86             : 
      87             : using ::com::sun::star::table::CellAddress;
      88             : using ::com::sun::star::table::CellRangeAddress;
      89             : 
      90             : namespace {
      91             : 
      92          54 : const SfxItemPropertyMapEntry* lcl_GetDataPilotDescriptorBaseMap()
      93             : {
      94             :     static const SfxItemPropertyMapEntry aDataPilotDescriptorBaseMap_Impl[] =
      95             :     {
      96           4 :         {OUString(SC_UNO_DP_COLGRAND),     0,  getBooleanCppuType(),  0, 0 },
      97           4 :         {OUString(SC_UNO_DP_DRILLDOWN),    0,  getBooleanCppuType(),  0, 0 },
      98           4 :         {OUString(SC_UNO_DP_GRANDTOTAL_NAME),0,getCppuType((OUString*)0), beans::PropertyAttribute::MAYBEVOID, 0 },
      99           4 :         {OUString(SC_UNO_DP_IGNORE_EMPTYROWS),   0,  getBooleanCppuType(),  0, 0 },
     100           4 :         {OUString(SC_UNO_DP_IMPORTDESC),   0,  getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
     101           4 :         {OUString(SC_UNO_DP_REPEATEMPTY),     0,  getBooleanCppuType(),  0, 0 },
     102           4 :         {OUString(SC_UNO_DP_ROWGRAND),     0,  getBooleanCppuType(),  0, 0 },
     103           4 :         {OUString(SC_UNO_DP_SERVICEARG),   0,  getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
     104           4 :         {OUString(SC_UNO_DP_SHOWFILTER),     0,  getBooleanCppuType(),  0, 0 },
     105           4 :         {OUString(SC_UNO_DP_SOURCESERVICE),   0,  getCppuType((OUString*)0), 0, 0 },
     106             :         { OUString(), 0, css::uno::Type(), 0, 0 }
     107          98 :     };
     108          54 :     return aDataPilotDescriptorBaseMap_Impl;
     109             : }
     110             : 
     111         126 : const SfxItemPropertyMapEntry* lcl_GetDataPilotFieldMap()
     112             : {
     113             :     using namespace ::com::sun::star::beans::PropertyAttribute;
     114             :     static const SfxItemPropertyMapEntry aDataPilotFieldMap_Impl[] =
     115             :     {
     116           4 :         {OUString(SC_UNONAME_AUTOSHOW),     0,  getCppuType((DataPilotFieldAutoShowInfo*)0),   MAYBEVOID, 0 },
     117           4 :         {OUString(SC_UNONAME_FUNCTION),     0,  getCppuType((GeneralFunction*)0),              0, 0 },
     118           4 :         {OUString(SC_UNONAME_GROUPINFO),    0,  getCppuType((DataPilotFieldGroupInfo*)0),      MAYBEVOID, 0 },
     119           4 :         {OUString(SC_UNONAME_HASAUTOSHOW),  0,  getBooleanCppuType(),                          0, 0 },
     120           4 :         {OUString(SC_UNONAME_HASLAYOUTINFO),0,  getBooleanCppuType(),                          0, 0 },
     121           4 :         {OUString(SC_UNONAME_HASREFERENCE), 0,  getBooleanCppuType(),                          0, 0 },
     122           4 :         {OUString(SC_UNONAME_HASSORTINFO),  0,  getBooleanCppuType(),                          0, 0 },
     123           4 :         {OUString(SC_UNONAME_ISGROUP),      0,  getBooleanCppuType(),                          0, 0 },
     124           4 :         {OUString(SC_UNONAME_LAYOUTINFO),   0,  getCppuType((DataPilotFieldLayoutInfo*)0),     MAYBEVOID, 0 },
     125           4 :         {OUString(SC_UNONAME_ORIENT),       0,  getCppuType((DataPilotFieldOrientation*)0),    MAYBEVOID, 0 },
     126           4 :         {OUString(SC_UNONAME_REFERENCE),    0,  getCppuType((DataPilotFieldReference*)0),      MAYBEVOID, 0 },
     127           4 :         {OUString(SC_UNONAME_SELPAGE),      0,  getCppuType((OUString*)0),                     0, 0 },
     128           4 :         {OUString(SC_UNONAME_SHOWEMPTY),    0,  getBooleanCppuType(),                          0, 0 },
     129           4 :         {OUString(SC_UNONAME_SORTINFO),     0,  getCppuType((DataPilotFieldSortInfo*)0),       MAYBEVOID, 0 },
     130           4 :         {OUString(SC_UNONAME_SUBTOTALS),    0,  getCppuType((Sequence<GeneralFunction>*)0),    0, 0 },
     131           4 :         {OUString(SC_UNONAME_USESELPAGE),   0,  getBooleanCppuType(),                          0, 0 },
     132             :         { OUString(), 0, css::uno::Type(), 0, 0 }
     133         194 :     };
     134         126 :     return aDataPilotFieldMap_Impl;
     135             : }
     136             : 
     137          15 : const SfxItemPropertyMapEntry* lcl_GetDataPilotItemMap()
     138             : {
     139             :     static const SfxItemPropertyMapEntry aDataPilotItemMap_Impl[] =
     140             :     {
     141           1 :         {OUString(SC_UNONAME_ISHIDDEN),     0,  getBooleanCppuType(),          0, 0 },
     142           1 :         {OUString(SC_UNONAME_POS),          0,  getCppuType((sal_Int32*)0),    0, 0 },
     143           1 :         {OUString(SC_UNONAME_SHOWDETAIL),   0,  getBooleanCppuType(),          0, 0 },
     144             :         { OUString(), 0, css::uno::Type(), 0, 0 }
     145          19 :     };
     146          15 :     return aDataPilotItemMap_Impl;
     147             : }
     148             : 
     149           0 : inline bool lclCheckValidDouble( double fValue, sal_Bool bAuto )
     150             : {
     151           0 :     return bAuto || ::rtl::math::isFinite( fValue );
     152             : }
     153             : 
     154           0 : bool lclCheckMinMaxStep( const DataPilotFieldGroupInfo& rInfo )
     155             : {
     156             :     return
     157           0 :         lclCheckValidDouble( rInfo.Start, rInfo.HasAutoStart ) &&
     158           0 :         lclCheckValidDouble( rInfo.End, rInfo.HasAutoEnd ) &&
     159           0 :         (rInfo.HasAutoStart || rInfo.HasAutoEnd || (rInfo.Start <= rInfo.End)) &&
     160           0 :         lclCheckValidDouble( rInfo.Step, false ) &&
     161           0 :         (0.0 <= rInfo.Step);
     162             : }
     163             : 
     164             : } // namespace
     165             : 
     166           0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotDescriptor, "ScDataPilotDescriptor", "stardiv::one::sheet::DataPilotDescriptor" )
     167           2 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldObj, "ScDataPilotFieldObj", "com.sun.star.sheet.DataPilotField" )
     168           0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldsObj, "ScDataPilotFieldsObj", "com.sun.star.sheet.DataPilotFields" )
     169           0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotTableObj, "ScDataPilotTableObj", "com.sun.star.sheet.DataPilotTable" )
     170           0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotTablesObj, "ScDataPilotTablesObj", "com.sun.star.sheet.DataPilotTables" )
     171           1 : SC_SIMPLE_SERVICE_INFO( ScDataPilotItemsObj, "ScDataPilotItemsObj", "com.sun.star.sheet.DataPilotItems" )
     172           3 : SC_SIMPLE_SERVICE_INFO( ScDataPilotItemObj, "ScDataPilotItemObj", "com.sun.star.sheet.DataPilotItem" )
     173             : 
     174           1 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupsObj, "ScDataPilotFieldGroupsObj", "com.sun.star.sheet.DataPilotFieldGroups" )
     175           1 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupObj, "ScDataPilotFieldGroupObj", "com.sun.star.sheet.DataPilotFieldGroup" )
     176           1 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupItemObj, "ScDataPilotFieldGroupItemObj", "com.sun.star.sheet.DataPilotFieldGroupItem" )
     177             : 
     178             : // name that is used in the API for the data layout field
     179             : #define SC_DATALAYOUT_NAME  "Data"
     180             : 
     181           0 : GeneralFunction ScDataPilotConversion::FirstFunc( sal_uInt16 nBits )
     182             : {
     183           0 :     if ( nBits & PIVOT_FUNC_SUM )       return GeneralFunction_SUM;
     184           0 :     if ( nBits & PIVOT_FUNC_COUNT )     return GeneralFunction_COUNT;
     185           0 :     if ( nBits & PIVOT_FUNC_AVERAGE )   return GeneralFunction_AVERAGE;
     186           0 :     if ( nBits & PIVOT_FUNC_MAX )       return GeneralFunction_MAX;
     187           0 :     if ( nBits & PIVOT_FUNC_MIN )       return GeneralFunction_MIN;
     188           0 :     if ( nBits & PIVOT_FUNC_PRODUCT )   return GeneralFunction_PRODUCT;
     189           0 :     if ( nBits & PIVOT_FUNC_COUNT_NUM ) return GeneralFunction_COUNTNUMS;
     190           0 :     if ( nBits & PIVOT_FUNC_STD_DEV )   return GeneralFunction_STDEV;
     191           0 :     if ( nBits & PIVOT_FUNC_STD_DEVP )  return GeneralFunction_STDEVP;
     192           0 :     if ( nBits & PIVOT_FUNC_STD_VAR )   return GeneralFunction_VAR;
     193           0 :     if ( nBits & PIVOT_FUNC_STD_VARP )  return GeneralFunction_VARP;
     194           0 :     if ( nBits & PIVOT_FUNC_AUTO )      return GeneralFunction_AUTO;
     195           0 :     return GeneralFunction_NONE;
     196             : }
     197             : 
     198           0 : sal_uInt16 ScDataPilotConversion::FunctionBit( GeneralFunction eFunc )
     199             : {
     200           0 :     sal_uInt16 nRet = PIVOT_FUNC_NONE;  // 0
     201           0 :     switch (eFunc)
     202             :     {
     203           0 :         case GeneralFunction_SUM:       nRet = PIVOT_FUNC_SUM;       break;
     204           0 :         case GeneralFunction_COUNT:     nRet = PIVOT_FUNC_COUNT;     break;
     205           0 :         case GeneralFunction_AVERAGE:   nRet = PIVOT_FUNC_AVERAGE;   break;
     206           0 :         case GeneralFunction_MAX:       nRet = PIVOT_FUNC_MAX;       break;
     207           0 :         case GeneralFunction_MIN:       nRet = PIVOT_FUNC_MIN;       break;
     208           0 :         case GeneralFunction_PRODUCT:   nRet = PIVOT_FUNC_PRODUCT;   break;
     209           0 :         case GeneralFunction_COUNTNUMS: nRet = PIVOT_FUNC_COUNT_NUM; break;
     210           0 :         case GeneralFunction_STDEV:     nRet = PIVOT_FUNC_STD_DEV;   break;
     211           0 :         case GeneralFunction_STDEVP:    nRet = PIVOT_FUNC_STD_DEVP;  break;
     212           0 :         case GeneralFunction_VAR:       nRet = PIVOT_FUNC_STD_VAR;   break;
     213           0 :         case GeneralFunction_VARP:      nRet = PIVOT_FUNC_STD_VARP;  break;
     214           0 :         case GeneralFunction_AUTO:      nRet = PIVOT_FUNC_AUTO;      break;
     215             :         default:
     216             :         {
     217             :             // added to avoid warnings
     218             :         }
     219             :     }
     220           0 :     return nRet;
     221             : }
     222             : 
     223           3 : void ScDataPilotConversion::FillGroupInfo( DataPilotFieldGroupInfo& rInfo, const ScDPNumGroupInfo& rGroupInfo )
     224             : {
     225           3 :     rInfo.HasDateValues = rGroupInfo.mbDateValues;
     226           3 :     rInfo.HasAutoStart  = rGroupInfo.mbAutoStart;
     227           3 :     rInfo.Start         = rGroupInfo.mfStart;
     228           3 :     rInfo.HasAutoEnd    = rGroupInfo.mbAutoEnd;
     229           3 :     rInfo.End           = rGroupInfo.mfEnd;
     230           3 :     rInfo.Step          = rGroupInfo.mfStep;
     231           3 : }
     232             : 
     233         641 : static ScDPObject* lcl_GetDPObject( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
     234             : {
     235         641 :     if (pDocShell)
     236             :     {
     237         641 :         ScDocument* pDoc = pDocShell->GetDocument();
     238         641 :         ScDPCollection* pColl = pDoc->GetDPCollection();
     239         641 :         if ( pColl )
     240             :         {
     241         641 :             size_t nCount = pColl->GetCount();
     242        1083 :             for (size_t i=0; i<nCount; ++i)
     243             :             {
     244        1082 :                 ScDPObject* pDPObj = (*pColl)[i];
     245        2164 :                 if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
     246        1082 :                      pDPObj->GetName() == rName )
     247         640 :                     return pDPObj;
     248             :             }
     249             :         }
     250             :     }
     251           1 :     return NULL;    // nicht gefunden
     252             : }
     253             : 
     254           0 : static OUString lcl_CreatePivotName( ScDocShell* pDocShell )
     255             : {
     256           0 :     if (pDocShell)
     257             :     {
     258           0 :         ScDocument* pDoc = pDocShell->GetDocument();
     259           0 :         ScDPCollection* pColl = pDoc->GetDPCollection();
     260           0 :         if ( pColl )
     261           0 :             return pColl->CreateNewName();
     262             :     }
     263           0 :     return OUString();                    // sollte nicht vorkommen
     264             : }
     265             : 
     266          60 : static sal_Int32 lcl_GetObjectIndex( ScDPObject* pDPObj, const ScFieldIdentifier& rFieldId )
     267             : {
     268             :     // used for items - nRepeat in identifier can be ignored
     269          60 :     if ( pDPObj )
     270             :     {
     271          60 :         sal_Int32 nCount = pDPObj->GetDimCount();
     272          60 :         for ( sal_Int32 nDim = 0; nDim < nCount; ++nDim )
     273             :         {
     274          60 :             bool bIsDataLayout = false;
     275          60 :             OUString aDimName( pDPObj->GetDimName( nDim, bIsDataLayout ) );
     276          60 :             if ( rFieldId.mbDataLayout ? bIsDataLayout : (aDimName == rFieldId.maFieldName) )
     277          60 :                 return nDim;
     278           0 :         }
     279             :     }
     280           0 :     return -1;  // none
     281             : }
     282             : 
     283          44 : ScDataPilotTablesObj::ScDataPilotTablesObj(ScDocShell* pDocSh, SCTAB nT) :
     284             :     pDocShell( pDocSh ),
     285          44 :     nTab( nT )
     286             : {
     287          44 :     pDocShell->GetDocument()->AddUnoObject(*this);
     288          44 : }
     289             : 
     290         132 : ScDataPilotTablesObj::~ScDataPilotTablesObj()
     291             : {
     292          44 :     if (pDocShell)
     293          23 :         pDocShell->GetDocument()->RemoveUnoObject(*this);
     294          88 : }
     295             : 
     296         245 : void ScDataPilotTablesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
     297             : {
     298             :     //! Referenz-Update
     299             : 
     300         396 :     if ( rHint.ISA( SfxSimpleHint ) &&
     301         151 :             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
     302             :     {
     303          21 :         pDocShell = NULL;       // ungueltig geworden
     304             :     }
     305         245 : }
     306             : 
     307             : // XDataPilotTables
     308             : 
     309          12 : ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nIndex )
     310             : {
     311          12 :     if (pDocShell)
     312             :     {
     313          12 :         ScDocument* pDoc = pDocShell->GetDocument();
     314          12 :         ScDPCollection* pColl = pDoc->GetDPCollection();
     315          12 :         if ( pColl )
     316             :         {
     317             :             //  count tables on this sheet
     318          12 :             sal_Int32 nFound = 0;
     319          12 :             size_t nCount = pColl->GetCount();
     320          14 :             for (size_t i=0; i<nCount; ++i)
     321             :             {
     322          12 :                 ScDPObject* pDPObj = (*pColl)[i];
     323          12 :                 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
     324             :                 {
     325          12 :                     if ( nFound == nIndex )
     326             :                     {
     327          10 :                         OUString aName = pDPObj->GetName();
     328          10 :                         return new ScDataPilotTableObj( pDocShell, nTab, aName );
     329             :                     }
     330           2 :                     ++nFound;
     331             :                 }
     332             :             }
     333             :         }
     334             :     }
     335           2 :     return NULL;
     336             : }
     337             : 
     338          28 : ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByName_Impl(const OUString& rName)
     339             : {
     340          28 :     if (hasByName(rName))
     341          27 :         return new ScDataPilotTableObj( pDocShell, nTab, rName );
     342           1 :     return 0;
     343             : }
     344             : 
     345          17 : Reference<XDataPilotDescriptor> SAL_CALL ScDataPilotTablesObj::createDataPilotDescriptor()
     346             :                                             throw(RuntimeException, std::exception)
     347             : {
     348          17 :     SolarMutexGuard aGuard;
     349          17 :     if (pDocShell)
     350          17 :         return new ScDataPilotDescriptor(pDocShell);
     351           0 :     return NULL;
     352             : }
     353             : 
     354         391 : static bool lcl_IsDuplicated( const Reference<XPropertySet> xDimProps )
     355             : {
     356             :     try
     357             :     {
     358         391 :         Any aAny = xDimProps->getPropertyValue( OUString( SC_UNO_DP_ORIGINAL ) );
     359         782 :         Reference< XNamed > xOriginal( aAny, UNO_QUERY );
     360         782 :         return xOriginal.is();
     361             :     }
     362           0 :     catch( Exception& )
     363             :     {
     364             :     }
     365           0 :     return false;
     366             : }
     367             : 
     368         117 : static OUString lcl_GetOriginalName( const Reference< XNamed > xDim )
     369             : {
     370         117 :     Reference< XNamed > xOriginal;
     371             : 
     372         234 :     Reference< XPropertySet > xDimProps( xDim, UNO_QUERY );
     373         117 :     if ( xDimProps.is() )
     374             :     {
     375             :         try
     376             :         {
     377         117 :             Any aAny = xDimProps->getPropertyValue(OUString(SC_UNO_DP_ORIGINAL));
     378         117 :             aAny >>= xOriginal;
     379             :         }
     380           0 :         catch( Exception& )
     381             :         {
     382             :         }
     383             :     }
     384             : 
     385         117 :     if ( !xOriginal.is() )
     386         117 :         xOriginal = xDim;
     387             : 
     388         234 :     return xOriginal->getName();
     389             : }
     390             : 
     391          18 : void SAL_CALL ScDataPilotTablesObj::insertNewByName( const OUString& aNewName,
     392             :     const CellAddress& aOutputAddress,
     393             :     const Reference<XDataPilotDescriptor>& xDescriptor )
     394             :         throw(RuntimeException, std::exception)
     395             : {
     396          18 :     SolarMutexGuard aGuard;
     397          35 :     if (!xDescriptor.is()) return;
     398             : 
     399             :     // inserting with already existing name?
     400          18 :     if ( !aNewName.isEmpty() && hasByName( aNewName ) )
     401           1 :         throw RuntimeException();       // no other exceptions specified
     402             : 
     403          17 :     sal_Bool bDone = false;
     404          17 :     ScDataPilotDescriptorBase* pImp = ScDataPilotDescriptorBase::getImplementation( xDescriptor );
     405          17 :     if ( pDocShell && pImp )
     406             :     {
     407          17 :         ScDPObject* pNewObj = pImp->GetDPObject();
     408             : 
     409          17 :         if (pNewObj)
     410             :         {
     411             :             ScRange aOutputRange((SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet,
     412          17 :                                 (SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet);
     413          17 :             pNewObj->SetOutRange(aOutputRange);
     414          17 :             OUString aName = aNewName;
     415          17 :             if (aName.isEmpty())
     416           0 :                 aName = lcl_CreatePivotName( pDocShell );
     417          17 :             pNewObj->SetName(aName);
     418          34 :             OUString aTag = xDescriptor->getTag();
     419          17 :             pNewObj->SetTag(aTag);
     420             : 
     421             :     // todo: handle double fields (for more information see ScDPObject
     422             : 
     423          34 :             ScDBDocFunc aFunc(*pDocShell);
     424          34 :             bDone = aFunc.CreatePivotTable(*pNewObj, true, true);
     425             :         }
     426             :     }
     427             : 
     428          17 :     if (!bDone)
     429           0 :         throw RuntimeException();       // no other exceptions specified
     430             : }
     431             : 
     432           2 : void SAL_CALL ScDataPilotTablesObj::removeByName( const OUString& aName )
     433             :                                         throw(RuntimeException, std::exception)
     434             : {
     435           2 :     SolarMutexGuard aGuard;
     436           4 :     OUString aNameStr(aName);
     437           2 :     ScDPObject* pDPObj = lcl_GetDPObject( pDocShell, nTab, aNameStr );
     438           2 :     if (pDPObj && pDocShell)
     439             :     {
     440           1 :         ScDBDocFunc aFunc(*pDocShell);
     441           1 :         aFunc.RemovePivotTable(*pDPObj, true, true);  // remove - incl. undo etc.
     442             :     }
     443             :     else
     444           3 :         throw RuntimeException();       // no other exceptions specified
     445           1 : }
     446             : 
     447             : // XEnumerationAccess
     448             : 
     449           2 : Reference< XEnumeration > SAL_CALL ScDataPilotTablesObj::createEnumeration() throw(RuntimeException, std::exception)
     450             : {
     451           2 :     SolarMutexGuard aGuard;
     452           2 :     return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotTablesEnumeration"));
     453             : }
     454             : 
     455             : // XIndexAccess
     456             : 
     457           4 : sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException, std::exception)
     458             : {
     459           4 :     SolarMutexGuard aGuard;
     460           4 :     if ( pDocShell )
     461             :     {
     462           4 :         ScDocument* pDoc = pDocShell->GetDocument();
     463           4 :         ScDPCollection* pColl = pDoc->GetDPCollection();
     464           4 :         if ( pColl )
     465             :         {
     466             :             //  count tables on this sheet
     467             : 
     468           4 :             sal_uInt16 nFound = 0;
     469           4 :             size_t nCount = pColl->GetCount();
     470           8 :             for (size_t i=0; i<nCount; ++i)
     471             :             {
     472           4 :                 ScDPObject* pDPObj = (*pColl)[i];
     473           4 :                 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
     474           4 :                     ++nFound;
     475             :             }
     476           4 :             return nFound;
     477             :         }
     478             :     }
     479             : 
     480           0 :     return 0;
     481             : }
     482             : 
     483          12 : Any SAL_CALL ScDataPilotTablesObj::getByIndex( sal_Int32 nIndex )
     484             :         throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
     485             : {
     486          12 :     SolarMutexGuard aGuard;
     487          24 :     Reference<XDataPilotTable2> xTable(GetObjectByIndex_Impl(nIndex));
     488          12 :     if (!xTable.is())
     489           2 :         throw IndexOutOfBoundsException();
     490          22 :     return Any( xTable );
     491             : }
     492             : 
     493           1 : uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(RuntimeException, std::exception)
     494             : {
     495           1 :     SolarMutexGuard aGuard;
     496           1 :     return getCppuType((Reference<XDataPilotTable2>*)0);
     497             : }
     498             : 
     499           1 : sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(RuntimeException, std::exception)
     500             : {
     501           1 :     SolarMutexGuard aGuard;
     502           1 :     return ( getCount() != 0 );
     503             : }
     504             : 
     505             : // XNameAccess
     506             : 
     507          28 : Any SAL_CALL ScDataPilotTablesObj::getByName( const OUString& aName )
     508             :         throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
     509             : {
     510          28 :     SolarMutexGuard aGuard;
     511          56 :     Reference<XDataPilotTable2> xTable(GetObjectByName_Impl(aName));
     512          28 :     if (!xTable.is())
     513           1 :         throw NoSuchElementException();
     514          55 :     return Any( xTable );
     515             : }
     516             : 
     517          10 : Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames()
     518             :                                                 throw(RuntimeException, std::exception)
     519             : {
     520          10 :     SolarMutexGuard aGuard;
     521          10 :     if (pDocShell)
     522             :     {
     523          10 :         ScDocument* pDoc = pDocShell->GetDocument();
     524          10 :         ScDPCollection* pColl = pDoc->GetDPCollection();
     525          10 :         if ( pColl )
     526             :         {
     527             :             //  count tables on this sheet
     528             : 
     529          10 :             sal_uInt16 nFound = 0;
     530          10 :             size_t nCount = pColl->GetCount();
     531             :             size_t i;
     532          20 :             for (i=0; i<nCount; ++i)
     533             :             {
     534          10 :                 ScDPObject* pDPObj = (*pColl)[i];
     535          10 :                 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
     536          10 :                     ++nFound;
     537             :             }
     538             : 
     539          10 :             sal_uInt16 nPos = 0;
     540          10 :             Sequence<OUString> aSeq(nFound);
     541          10 :             OUString* pAry = aSeq.getArray();
     542          20 :             for (i=0; i<nCount; ++i)
     543             :             {
     544          10 :                 ScDPObject* pDPObj = (*pColl)[i];
     545          10 :                 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
     546          10 :                     pAry[nPos++] = pDPObj->GetName();
     547             :             }
     548             : 
     549          10 :             return aSeq;
     550             :         }
     551             :     }
     552           0 :     return Sequence<OUString>(0);
     553             : }
     554             : 
     555          60 : sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName )
     556             :                                         throw(RuntimeException, std::exception)
     557             : {
     558          60 :     SolarMutexGuard aGuard;
     559          60 :     if (pDocShell)
     560             :     {
     561          60 :         ScDocument* pDoc = pDocShell->GetDocument();
     562          60 :         ScDPCollection* pColl = pDoc->GetDPCollection();
     563          60 :         if ( pColl )
     564             :         {
     565          60 :             size_t nCount = pColl->GetCount();
     566          71 :             for (size_t i=0; i<nCount; ++i)
     567             :             {
     568          40 :                 ScDPObject* pDPObj = (*pColl)[i];
     569          80 :                 if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
     570          40 :                      pDPObj->GetName() == aName )
     571          29 :                     return true;
     572             :             }
     573             :         }
     574             :     }
     575          31 :     return false;
     576             : }
     577             : 
     578          54 : ScDataPilotDescriptorBase::ScDataPilotDescriptorBase(ScDocShell* pDocSh) :
     579             :     maPropSet( lcl_GetDataPilotDescriptorBaseMap() ),
     580          54 :     pDocShell( pDocSh )
     581             : {
     582          54 :     pDocShell->GetDocument()->AddUnoObject(*this);
     583          54 : }
     584             : 
     585         106 : ScDataPilotDescriptorBase::~ScDataPilotDescriptorBase()
     586             : {
     587          53 :     if (pDocShell)
     588          22 :         pDocShell->GetDocument()->RemoveUnoObject(*this);
     589          53 : }
     590             : 
     591          83 : Any SAL_CALL ScDataPilotDescriptorBase::queryInterface( const uno::Type& rType )
     592             :                                                 throw(RuntimeException, std::exception)
     593             : {
     594          83 :     SC_QUERYINTERFACE( XDataPilotDescriptor )
     595          60 :     SC_QUERYINTERFACE( XPropertySet )
     596          60 :     SC_QUERYINTERFACE( XDataPilotDataLayoutFieldSupplier )
     597          60 :     SC_QUERYINTERFACE( XNamed )                 // base of XDataPilotDescriptor
     598          57 :     SC_QUERYINTERFACE( lang::XUnoTunnel )
     599          40 :     SC_QUERYINTERFACE( lang::XTypeProvider )
     600          40 :     SC_QUERYINTERFACE( lang::XServiceInfo )
     601             : 
     602          40 :     return OWeakObject::queryInterface( rType );
     603             : }
     604             : 
     605         641 : void SAL_CALL ScDataPilotDescriptorBase::acquire() throw()
     606             : {
     607         641 :     OWeakObject::acquire();
     608         641 : }
     609             : 
     610         640 : void SAL_CALL ScDataPilotDescriptorBase::release() throw()
     611             : {
     612         640 :     OWeakObject::release();
     613         640 : }
     614             : 
     615           0 : Sequence< uno::Type > SAL_CALL ScDataPilotDescriptorBase::getTypes()
     616             :                                                     throw(RuntimeException, std::exception)
     617             : {
     618           0 :     static Sequence< uno::Type > aTypes;
     619           0 :     if ( aTypes.getLength() == 0 )
     620             :     {
     621           0 :         aTypes.realloc( 6 );
     622           0 :         uno::Type* pPtr = aTypes.getArray();
     623           0 :         pPtr[ 0 ] = getCppuType( (const Reference< XDataPilotDescriptor >*)0 );
     624           0 :         pPtr[ 1 ] = getCppuType( (const Reference< XPropertySet >*)0 );
     625           0 :         pPtr[ 2 ] = getCppuType( (const Reference< XDataPilotDataLayoutFieldSupplier >*)0 );
     626           0 :         pPtr[ 3 ] = getCppuType( (const Reference< lang::XUnoTunnel >*)0 );
     627           0 :         pPtr[ 4 ] = getCppuType( (const Reference< lang::XTypeProvider >*)0 );
     628           0 :         pPtr[ 5 ] = getCppuType( (const Reference< lang::XServiceInfo >*)0 );
     629             :     }
     630           0 :     return aTypes;
     631             : }
     632             : 
     633           0 : Sequence<sal_Int8> SAL_CALL ScDataPilotDescriptorBase::getImplementationId()
     634             :                                                     throw(RuntimeException, std::exception)
     635             : {
     636           0 :     return css::uno::Sequence<sal_Int8>();
     637             : }
     638             : 
     639         492 : void ScDataPilotDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
     640             : {
     641             :     //! Referenz-Update?
     642             : 
     643         794 :     if ( rHint.ISA( SfxSimpleHint ) &&
     644         302 :             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
     645             :     {
     646          32 :         pDocShell = NULL;       // ungueltig geworden
     647             :     }
     648         492 : }
     649             : 
     650             : // XDataPilotDescriptor
     651             : 
     652           4 : CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange()
     653             :                                             throw(RuntimeException, std::exception)
     654             : {
     655           4 :     SolarMutexGuard aGuard;
     656             : 
     657           4 :     ScDPObject* pDPObject(GetDPObject());
     658           4 :     if (!pDPObject)
     659           0 :         throw RuntimeException();
     660             : 
     661           4 :     CellRangeAddress aRet;
     662           4 :     if (pDPObject->IsSheetData())
     663           4 :         ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->GetSourceRange() );
     664           4 :     return aRet;
     665             : }
     666             : 
     667          19 : void SAL_CALL ScDataPilotDescriptorBase::setSourceRange( const CellRangeAddress& aSourceRange ) throw(RuntimeException, std::exception)
     668             : {
     669          19 :     SolarMutexGuard aGuard;
     670             : 
     671          19 :     ScDPObject* pDPObject = GetDPObject();
     672          19 :     if (!pDPObject)
     673           0 :         throw RuntimeException();
     674             : 
     675          38 :     ScSheetSourceDesc aSheetDesc(pDocShell->GetDocument());
     676          19 :     if (pDPObject->IsSheetData())
     677          19 :         aSheetDesc = *pDPObject->GetSheetDesc();
     678             : 
     679          19 :     ScRange aRange;
     680          19 :     ScUnoConversion::FillScRange(aRange, aSourceRange);
     681          19 :     aSheetDesc.SetSourceRange(aRange);
     682          19 :     pDPObject->SetSheetDesc( aSheetDesc );
     683          38 :     SetDPObject( pDPObject );
     684          19 : }
     685             : 
     686           3 : Reference<XSheetFilterDescriptor> SAL_CALL ScDataPilotDescriptorBase::getFilterDescriptor()
     687             :                                                 throw(RuntimeException, std::exception)
     688             : {
     689           3 :     SolarMutexGuard aGuard;
     690           3 :     return new ScDataPilotFilterDescriptor( pDocShell, this );
     691             : }
     692             : 
     693          44 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataPilotFields()
     694             :                                                 throw(RuntimeException, std::exception)
     695             : {
     696          44 :     SolarMutexGuard aGuard;
     697          44 :     return new ScDataPilotFieldsObj( *this );
     698             : }
     699             : 
     700           2 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getColumnFields()
     701             :                                                 throw(RuntimeException, std::exception)
     702             : {
     703           2 :     SolarMutexGuard aGuard;
     704           2 :     return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_COLUMN );
     705             : }
     706             : 
     707           8 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getRowFields()
     708             :                                                 throw(RuntimeException, std::exception)
     709             : {
     710           8 :     SolarMutexGuard aGuard;
     711           8 :     return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_ROW );
     712             : }
     713             : 
     714           2 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getPageFields()
     715             :                                                 throw(RuntimeException, std::exception)
     716             : {
     717           2 :     SolarMutexGuard aGuard;
     718           2 :     return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_PAGE );
     719             : }
     720             : 
     721           2 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataFields()
     722             :                                                 throw(RuntimeException, std::exception)
     723             : {
     724           2 :     SolarMutexGuard aGuard;
     725           2 :     return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_DATA );
     726             : }
     727             : 
     728           1 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getHiddenFields()
     729             :                                                 throw(RuntimeException, std::exception)
     730             : {
     731           1 :     SolarMutexGuard aGuard;
     732           1 :     return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_HIDDEN );
     733             : }
     734             : 
     735             : // XPropertySet
     736           0 : Reference< XPropertySetInfo > SAL_CALL ScDataPilotDescriptorBase::getPropertySetInfo(  )
     737             :                                                 throw(RuntimeException, std::exception)
     738             : {
     739           0 :     SolarMutexGuard aGuard;
     740             :     static Reference<XPropertySetInfo> aRef =
     741           0 :         new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
     742           0 :     return aRef;
     743             : }
     744             : 
     745           0 : void SAL_CALL ScDataPilotDescriptorBase::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
     746             :         throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException,
     747             :                 WrappedTargetException, RuntimeException, std::exception)
     748             : {
     749           0 :     SolarMutexGuard aGuard;
     750           0 :     ScDPObject* pDPObject = GetDPObject();
     751           0 :     if (pDPObject)
     752             :     {
     753           0 :         ScDPSaveData* pOldData = pDPObject->GetSaveData();
     754             :         OSL_ENSURE(pOldData, "Here should be a SaveData");
     755           0 :         if ( pOldData )
     756             :         {
     757           0 :             ScDPSaveData aNewData( *pOldData );
     758             : 
     759           0 :             OUString aNameString = aPropertyName;
     760           0 :             if ( aNameString.equalsAscii( SC_UNO_DP_COLGRAND ) )
     761             :             {
     762           0 :                 aNewData.SetColumnGrand(::cppu::any2bool( aValue ));
     763             :             }
     764           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_IGNORE_EMPTYROWS ) )
     765             :             {
     766           0 :                 aNewData.SetIgnoreEmptyRows(::cppu::any2bool( aValue ));
     767             :             }
     768           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_REPEATEMPTY ) )
     769             :             {
     770           0 :                 aNewData.SetRepeatIfEmpty(::cppu::any2bool( aValue ));
     771             :             }
     772           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_ROWGRAND ) )
     773             :             {
     774           0 :                 aNewData.SetRowGrand(::cppu::any2bool( aValue ));
     775             :             }
     776           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_SHOWFILTER ) )
     777             :             {
     778           0 :                 aNewData.SetFilterButton(::cppu::any2bool( aValue ));
     779             :             }
     780           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_DRILLDOWN ) )
     781             :             {
     782           0 :                 aNewData.SetDrillDown(::cppu::any2bool( aValue ));
     783             :             }
     784           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_GRANDTOTAL_NAME ) )
     785             :             {
     786           0 :                 OUString aStrVal;
     787           0 :                 if ( aValue >>= aStrVal )
     788           0 :                     aNewData.SetGrandTotalName(aStrVal);
     789             :             }
     790           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_IMPORTDESC ) )
     791             :             {
     792           0 :                 uno::Sequence<beans::PropertyValue> aArgSeq;
     793           0 :                 if ( aValue >>= aArgSeq )
     794             :                 {
     795           0 :                     ScImportSourceDesc aImportDesc(pDocShell->GetDocument());
     796             : 
     797           0 :                     const ScImportSourceDesc* pOldDesc = pDPObject->GetImportSourceDesc();
     798           0 :                     if (pOldDesc)
     799           0 :                         aImportDesc = *pOldDesc;
     800             : 
     801           0 :                     ScImportParam aParam;
     802           0 :                     ScImportDescriptor::FillImportParam( aParam, aArgSeq );
     803             : 
     804           0 :                     sal_uInt16 nNewType = sheet::DataImportMode_NONE;
     805           0 :                     if ( aParam.bImport )
     806             :                     {
     807           0 :                         if ( aParam.bSql )
     808           0 :                             nNewType = sheet::DataImportMode_SQL;
     809           0 :                         else if ( aParam.nType == ScDbQuery )
     810           0 :                             nNewType = sheet::DataImportMode_QUERY;
     811             :                         else
     812           0 :                             nNewType = sheet::DataImportMode_TABLE;
     813             :                     }
     814           0 :                     aImportDesc.nType   = nNewType;
     815           0 :                     aImportDesc.aDBName = aParam.aDBName;
     816           0 :                     aImportDesc.aObject = aParam.aStatement;
     817           0 :                     aImportDesc.bNative = aParam.bNative;
     818             : 
     819           0 :                     pDPObject->SetImportDesc( aImportDesc );
     820           0 :                 }
     821             :             }
     822           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_SOURCESERVICE ) )
     823             :             {
     824           0 :                 OUString aStrVal;
     825           0 :                 if ( aValue >>= aStrVal )
     826             :                 {
     827           0 :                     OUString aEmpty;
     828           0 :                     ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
     829             : 
     830           0 :                     const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
     831           0 :                     if (pOldDesc)
     832           0 :                         aServiceDesc = *pOldDesc;
     833             : 
     834           0 :                     aServiceDesc.aServiceName = aStrVal;
     835             : 
     836           0 :                     pDPObject->SetServiceData( aServiceDesc );
     837           0 :                 }
     838             :             }
     839           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_SERVICEARG ) )
     840             :             {
     841           0 :                 uno::Sequence<beans::PropertyValue> aArgSeq;
     842           0 :                 if ( aValue >>= aArgSeq )
     843             :                 {
     844           0 :                     OUString aEmpty;
     845           0 :                     ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
     846             : 
     847           0 :                     const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
     848           0 :                     if (pOldDesc)
     849           0 :                         aServiceDesc = *pOldDesc;
     850             : 
     851           0 :                     OUString aStrVal;
     852           0 :                     sal_Int32 nArgs = aArgSeq.getLength();
     853           0 :                     for (sal_Int32 nArgPos=0; nArgPos<nArgs; ++nArgPos)
     854             :                     {
     855           0 :                         const beans::PropertyValue& rProp = aArgSeq[nArgPos];
     856           0 :                         OUString aPropName(rProp.Name);
     857             : 
     858           0 :                         if (aPropName.equalsAscii( SC_UNO_DP_SOURCENAME ))
     859             :                         {
     860           0 :                             if ( rProp.Value >>= aStrVal )
     861           0 :                                 aServiceDesc.aParSource = aStrVal;
     862             :                         }
     863           0 :                         else if (aPropName.equalsAscii( SC_UNO_DP_OBJECTNAME ))
     864             :                         {
     865           0 :                             if ( rProp.Value >>= aStrVal )
     866           0 :                                 aServiceDesc.aParName = aStrVal;
     867             :                         }
     868           0 :                         else if (aPropName.equalsAscii( SC_UNO_DP_USERNAME ))
     869             :                         {
     870           0 :                             if ( rProp.Value >>= aStrVal )
     871           0 :                                 aServiceDesc.aParUser = aStrVal;
     872             :                         }
     873           0 :                         else if (aPropName.equalsAscii( SC_UNO_DP_PASSWORD ))
     874             :                         {
     875           0 :                             if ( rProp.Value >>= aStrVal )
     876           0 :                                 aServiceDesc.aParPass = aStrVal;
     877             :                         }
     878           0 :                     }
     879             : 
     880           0 :                     pDPObject->SetServiceData( aServiceDesc );
     881           0 :                 }
     882             :             }
     883             :             else
     884           0 :                 throw UnknownPropertyException();
     885             : 
     886           0 :             pDPObject->SetSaveData( aNewData );
     887             :         }
     888             : 
     889           0 :         SetDPObject(pDPObject);
     890           0 :     }
     891           0 : }
     892             : 
     893           0 : Any SAL_CALL ScDataPilotDescriptorBase::getPropertyValue( const OUString& aPropertyName )
     894             :         throw (UnknownPropertyException, WrappedTargetException,
     895             :                RuntimeException, std::exception)
     896             : {
     897           0 :     SolarMutexGuard aGuard;
     898           0 :     Any aRet;
     899             : 
     900           0 :     ScDPObject* pDPObject(GetDPObject());
     901           0 :     if (pDPObject)
     902             :     {
     903           0 :         ScDPSaveData* pOldData = pDPObject->GetSaveData();
     904             :         OSL_ENSURE(pOldData, "Here should be a SaveData");
     905           0 :         if ( pOldData )
     906             :         {
     907           0 :             ScDPSaveData aNewData( *pOldData );
     908             : 
     909           0 :             OUString aNameString = aPropertyName;
     910           0 :             if ( aNameString.equalsAscii( SC_UNO_DP_COLGRAND ) )
     911             :             {
     912           0 :                 aRet <<= aNewData.GetColumnGrand();
     913             :             }
     914           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_IGNORE_EMPTYROWS ) )
     915             :             {
     916           0 :                 aRet <<= aNewData.GetIgnoreEmptyRows();
     917             :             }
     918           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_REPEATEMPTY ) )
     919             :             {
     920           0 :                 aRet <<= aNewData.GetRepeatIfEmpty();
     921             :             }
     922           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_ROWGRAND ) )
     923             :             {
     924           0 :                 aRet <<= aNewData.GetRowGrand();
     925             :             }
     926           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_SHOWFILTER ) )
     927             :             {
     928           0 :                 aRet <<= aNewData.GetFilterButton();
     929             :             }
     930           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_DRILLDOWN ) )
     931             :             {
     932           0 :                 aRet <<= aNewData.GetDrillDown();
     933             :             }
     934           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_GRANDTOTAL_NAME ) )
     935             :             {
     936           0 :                 const OUString* pGrandTotalName = aNewData.GetGrandTotalName();
     937           0 :                 if (pGrandTotalName)
     938           0 :                     aRet <<= *pGrandTotalName;      // same behavior as in ScDPSource
     939             :             }
     940           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_IMPORTDESC ) )
     941             :             {
     942           0 :                 const ScImportSourceDesc* pImportDesc = pDPObject->GetImportSourceDesc();
     943           0 :                 if ( pImportDesc )
     944             :                 {
     945             :                     // fill ScImportParam so ScImportDescriptor::FillProperties can be used
     946           0 :                     ScImportParam aParam;
     947           0 :                     aParam.bImport    = ( pImportDesc->nType != sheet::DataImportMode_NONE );
     948           0 :                     aParam.aDBName    = pImportDesc->aDBName;
     949           0 :                     aParam.aStatement = pImportDesc->aObject;
     950           0 :                     aParam.bNative    = pImportDesc->bNative;
     951           0 :                     aParam.bSql       = ( pImportDesc->nType == sheet::DataImportMode_SQL );
     952           0 :                     aParam.nType      = static_cast<sal_uInt8>(( pImportDesc->nType == sheet::DataImportMode_QUERY ) ? ScDbQuery : ScDbTable);
     953             : 
     954           0 :                     uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
     955           0 :                     ScImportDescriptor::FillProperties( aSeq, aParam );
     956           0 :                     aRet <<= aSeq;
     957             :                 }
     958             :                 else
     959             :                 {
     960             :                     // empty sequence
     961           0 :                     uno::Sequence<beans::PropertyValue> aEmpty(0);
     962           0 :                     aRet <<= aEmpty;
     963             :                 }
     964             :             }
     965           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_SOURCESERVICE ) )
     966             :             {
     967           0 :                 OUString aServiceName;
     968           0 :                 const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
     969           0 :                 if (pServiceDesc)
     970           0 :                     aServiceName = pServiceDesc->aServiceName;
     971           0 :                 aRet <<= aServiceName;      // empty string if no ServiceDesc set
     972             :             }
     973           0 :             else if ( aNameString.equalsAscii( SC_UNO_DP_SERVICEARG ) )
     974             :             {
     975           0 :                 const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
     976           0 :                 if (pServiceDesc)
     977             :                 {
     978           0 :                     uno::Sequence<beans::PropertyValue> aSeq( 4 );
     979           0 :                     beans::PropertyValue* pArray = aSeq.getArray();
     980           0 :                     pArray[0].Name = OUString( SC_UNO_DP_SOURCENAME );
     981           0 :                     pArray[0].Value <<= pServiceDesc->aParSource;
     982           0 :                     pArray[1].Name = OUString( SC_UNO_DP_OBJECTNAME );
     983           0 :                     pArray[1].Value <<= pServiceDesc->aParName;
     984           0 :                     pArray[2].Name = OUString( SC_UNO_DP_USERNAME );
     985           0 :                     pArray[2].Value <<= pServiceDesc->aParUser;
     986           0 :                     pArray[3].Name = OUString( SC_UNO_DP_PASSWORD );
     987           0 :                     pArray[3].Value <<= pServiceDesc->aParPass;
     988           0 :                     aRet <<= aSeq;
     989             :                 }
     990             :                 else
     991             :                 {
     992             :                     // empty sequence
     993           0 :                     uno::Sequence<beans::PropertyValue> aEmpty(0);
     994           0 :                     aRet <<= aEmpty;
     995             :                 }
     996             :             }
     997             :             else
     998           0 :                 throw UnknownPropertyException();
     999             :         }
    1000             :     }
    1001             : 
    1002           0 :     return aRet;
    1003             : }
    1004             : 
    1005           0 : void SAL_CALL ScDataPilotDescriptorBase::addPropertyChangeListener(
    1006             :         const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* xListener */ )
    1007             :         throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1008             : {
    1009           0 : }
    1010             : 
    1011           0 : void SAL_CALL ScDataPilotDescriptorBase::removePropertyChangeListener(
    1012             :         const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* aListener */ )
    1013             :         throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1014             : {
    1015           0 : }
    1016             : 
    1017           0 : void SAL_CALL ScDataPilotDescriptorBase::addVetoableChangeListener(
    1018             :         const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
    1019             :         throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1020             : {
    1021           0 : }
    1022             : 
    1023           0 : void SAL_CALL ScDataPilotDescriptorBase::removeVetoableChangeListener(
    1024             :         const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
    1025             :         throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1026             : {
    1027           0 : }
    1028             : 
    1029             : // XDataPilotDataLayoutFieldSupplier
    1030             : 
    1031           0 : Reference< XDataPilotField > SAL_CALL ScDataPilotDescriptorBase::getDataLayoutField()
    1032             :     throw (RuntimeException, std::exception)
    1033             : {
    1034           0 :     SolarMutexGuard aGuard;
    1035           0 :     if( ScDPObject* pDPObject = GetDPObject() )
    1036             :     {
    1037           0 :         if( ScDPSaveData* pSaveData = pDPObject->GetSaveData() )
    1038             :         {
    1039           0 :             if( pSaveData->GetDataLayoutDimension() )
    1040             :             {
    1041           0 :                 ScFieldIdentifier aFieldId( OUString( SC_DATALAYOUT_NAME ), 0, true );
    1042           0 :                 return new ScDataPilotFieldObj( *this, aFieldId );
    1043             :             }
    1044             :         }
    1045             :     }
    1046           0 :     return 0;
    1047             : }
    1048             : 
    1049             : // XUnoTunnel
    1050             : 
    1051          17 : sal_Int64 SAL_CALL ScDataPilotDescriptorBase::getSomething(
    1052             :                 const Sequence<sal_Int8 >& rId ) throw(RuntimeException, std::exception)
    1053             : {
    1054          34 :     if ( rId.getLength() == 16 &&
    1055          17 :           0 == memcmp( getUnoTunnelId().getConstArray(),
    1056          34 :                                     rId.getConstArray(), 16 ) )
    1057             :     {
    1058          17 :         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
    1059             :     }
    1060           0 :     return 0;
    1061             : }
    1062             : 
    1063             : namespace
    1064             : {
    1065             :     class theScDataPilotDescriptorBaseUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScDataPilotDescriptorBaseUnoTunnelId> {};
    1066             : }
    1067             : 
    1068          34 : const Sequence<sal_Int8>& ScDataPilotDescriptorBase::getUnoTunnelId()
    1069             : {
    1070          34 :     return theScDataPilotDescriptorBaseUnoTunnelId::get().getSeq();
    1071             : }
    1072             : 
    1073          17 : ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation(
    1074             :                                 const Reference<XDataPilotDescriptor> xObj )
    1075             : {
    1076          17 :     ScDataPilotDescriptorBase* pRet = NULL;
    1077          17 :     Reference<lang::XUnoTunnel> xUT( xObj, UNO_QUERY );
    1078          17 :     if (xUT.is())
    1079          17 :         pRet = reinterpret_cast<ScDataPilotDescriptorBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
    1080          17 :     return pRet;
    1081             : }
    1082             : 
    1083          37 : ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const OUString& rN) :
    1084             :     ScDataPilotDescriptorBase( pDocSh ),
    1085             :     nTab( nT ),
    1086             :     aName( rN ),
    1087          37 :     aModifyListeners( 0 )
    1088             : {
    1089          37 : }
    1090             : 
    1091          74 : ScDataPilotTableObj::~ScDataPilotTableObj()
    1092             : {
    1093          74 : }
    1094             : 
    1095          71 : Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType )
    1096             :                                                 throw(RuntimeException, std::exception)
    1097             : {
    1098             :     // since we manually do resolve the query for XDataPilotTable2
    1099             :     // we also need to do the same for XDataPilotTable
    1100          71 :     SC_QUERYINTERFACE( XDataPilotTable )
    1101          53 :     SC_QUERYINTERFACE( XDataPilotTable2 )
    1102          49 :     SC_QUERYINTERFACE( XModifyBroadcaster )
    1103             : 
    1104          49 :     return ScDataPilotDescriptorBase::queryInterface( rType );
    1105             : }
    1106             : 
    1107         392 : void SAL_CALL ScDataPilotTableObj::acquire() throw()
    1108             : {
    1109         392 :     ScDataPilotDescriptorBase::acquire();
    1110         392 : }
    1111             : 
    1112         392 : void SAL_CALL ScDataPilotTableObj::release() throw()
    1113             : {
    1114         392 :     ScDataPilotDescriptorBase::release();
    1115         392 : }
    1116             : 
    1117           0 : Sequence< uno::Type > SAL_CALL ScDataPilotTableObj::getTypes() throw(RuntimeException, std::exception)
    1118             : {
    1119           0 :     static Sequence< uno::Type > aTypes;
    1120           0 :     if ( aTypes.getLength() == 0 )
    1121             :     {
    1122           0 :         Sequence< uno::Type > aParentTypes = ScDataPilotDescriptorBase::getTypes();
    1123           0 :         sal_Int32 nParentLen = aParentTypes.getLength();
    1124           0 :         const uno::Type* pParentPtr = aParentTypes.getConstArray();
    1125             : 
    1126           0 :         aTypes.realloc( nParentLen + 2 );
    1127           0 :         uno::Type* pPtr = aTypes.getArray();
    1128           0 :         for (sal_Int32 i = 0; i < nParentLen; ++i)
    1129           0 :             pPtr[ i ] = pParentPtr[ i ];               // parent types first
    1130             : 
    1131           0 :         pPtr[ nParentLen ] = getCppuType( (const Reference< XDataPilotTable2 >*)0 );
    1132           0 :         pPtr[ nParentLen+1 ] = getCppuType( (const Reference< XModifyBroadcaster >*)0 );
    1133             :     }
    1134           0 :     return aTypes;
    1135             : }
    1136             : 
    1137           0 : Sequence<sal_Int8> SAL_CALL ScDataPilotTableObj::getImplementationId()
    1138             :                                                     throw(RuntimeException, std::exception)
    1139             : {
    1140           0 :     return css::uno::Sequence<sal_Int8>();
    1141             : }
    1142             : 
    1143             : 
    1144         585 : ScDPObject* ScDataPilotTableObj::GetDPObject() const
    1145             : {
    1146         585 :     return lcl_GetDPObject(GetDocShell(), nTab, aName);
    1147             : }
    1148             : 
    1149          21 : void ScDataPilotTableObj::SetDPObject( ScDPObject* pDPObject )
    1150             : {
    1151          21 :     ScDocShell* pDocSh = GetDocShell();
    1152          21 :     ScDPObject* pDPObj = lcl_GetDPObject(pDocSh, nTab, aName);
    1153          21 :     if ( pDPObj && pDocSh )
    1154             :     {
    1155          21 :         ScDBDocFunc aFunc(*pDocSh);
    1156          21 :         aFunc.DataPilotUpdate( pDPObj, pDPObject, true, true );
    1157             :     }
    1158          21 : }
    1159             : 
    1160             : // "rest of XDataPilotDescriptor"
    1161             : 
    1162           6 : OUString SAL_CALL ScDataPilotTableObj::getName() throw(RuntimeException, std::exception)
    1163             : {
    1164           6 :     SolarMutexGuard aGuard;
    1165           6 :     ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
    1166           6 :     if (pDPObj)
    1167           6 :         return pDPObj->GetName();
    1168           0 :     return OUString();
    1169             : }
    1170             : 
    1171           4 : void SAL_CALL ScDataPilotTableObj::setName( const OUString& aNewName )
    1172             :                                                 throw(RuntimeException, std::exception)
    1173             : {
    1174           4 :     SolarMutexGuard aGuard;
    1175           4 :     ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
    1176           4 :     if (pDPObj)
    1177             :     {
    1178             :         //! test for existing names !!!
    1179             : 
    1180           4 :         OUString aString(aNewName);
    1181           4 :         pDPObj->SetName( aString );     //! Undo - DBDocFunc ???
    1182           4 :         aName = aString;
    1183             : 
    1184             :         //  DataPilotUpdate would do too much (output table is not changed)
    1185           4 :         GetDocShell()->SetDocumentModified();
    1186           4 :     }
    1187           4 : }
    1188             : 
    1189           2 : OUString SAL_CALL ScDataPilotTableObj::getTag() throw(RuntimeException, std::exception)
    1190             : {
    1191           2 :     SolarMutexGuard aGuard;
    1192           2 :     ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
    1193           2 :     if (pDPObj)
    1194           2 :         return pDPObj->GetTag();
    1195           0 :     return OUString();
    1196             : }
    1197             : 
    1198           2 : void SAL_CALL ScDataPilotTableObj::setTag( const OUString& aNewTag )
    1199             :                                                 throw(RuntimeException, std::exception)
    1200             : {
    1201           2 :     SolarMutexGuard aGuard;
    1202           2 :     ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
    1203           2 :     if (pDPObj)
    1204             :     {
    1205           2 :         pDPObj->SetTag( aNewTag );      //! Undo - DBDocFunc ???
    1206             : 
    1207             :         //  DataPilotUpdate would do too much (output table is not changed)
    1208           2 :         GetDocShell()->SetDocumentModified();
    1209           2 :     }
    1210           2 : }
    1211             : 
    1212             : // XDataPilotTable
    1213             : 
    1214           2 : CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeException, std::exception)
    1215             : {
    1216           2 :     SolarMutexGuard aGuard;
    1217           2 :     CellRangeAddress aRet;
    1218           2 :     ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
    1219           2 :     if (pDPObj)
    1220             :     {
    1221           2 :         ScRange aRange(pDPObj->GetOutRange());
    1222           2 :         aRet.Sheet       = aRange.aStart.Tab();
    1223           2 :         aRet.StartColumn = aRange.aStart.Col();
    1224           2 :         aRet.StartRow    = aRange.aStart.Row();
    1225           2 :         aRet.EndColumn   = aRange.aEnd.Col();
    1226           2 :         aRet.EndRow      = aRange.aEnd.Row();
    1227             :     }
    1228           2 :     return aRet;
    1229             : }
    1230             : 
    1231           2 : void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException, std::exception)
    1232             : {
    1233           2 :     SolarMutexGuard aGuard;
    1234           2 :     ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
    1235           2 :     if (pDPObj)
    1236             :     {
    1237           2 :         ScDBDocFunc aFunc(*GetDocShell());
    1238           2 :         aFunc.RefreshPivotTables(pDPObj, true);
    1239           2 :     }
    1240           2 : }
    1241             : 
    1242          97 : Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr)
    1243             :     throw (RuntimeException, std::exception)
    1244             : {
    1245          97 :     SolarMutexGuard aGuard;
    1246          97 :     Sequence< Sequence<Any> > aTabData;
    1247          97 :     ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
    1248          97 :     ScDPObject* pObj = GetDPObject();
    1249          97 :     if (!pObj)
    1250           0 :         throw RuntimeException();
    1251             : 
    1252          97 :     pObj->GetDrillDownData(aAddr2, aTabData);
    1253          97 :     return aTabData;
    1254             : }
    1255             : 
    1256         266 : DataPilotTablePositionData SAL_CALL ScDataPilotTableObj::getPositionData(const CellAddress& aAddr)
    1257             :     throw (RuntimeException, std::exception)
    1258             : {
    1259         266 :     SolarMutexGuard aGuard;
    1260         266 :     DataPilotTablePositionData aPosData;
    1261         266 :     ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
    1262         266 :     ScDPObject* pObj = GetDPObject();
    1263         266 :     if (!pObj)
    1264           0 :         throw RuntimeException();
    1265             : 
    1266         266 :     pObj->GetPositionData(aAddr2, aPosData);
    1267         266 :     return aPosData;
    1268             : }
    1269             : 
    1270          36 : void SAL_CALL ScDataPilotTableObj::insertDrillDownSheet(const CellAddress& aAddr)
    1271             :     throw (RuntimeException, std::exception)
    1272             : {
    1273          36 :     SolarMutexGuard aGuard;
    1274          36 :     ScDPObject* pDPObj = GetDPObject();
    1275          36 :     if (!pDPObj)
    1276           0 :         throw RuntimeException();
    1277          36 :     ScTabViewShell* pViewSh = GetDocShell()->GetBestViewShell();
    1278          36 :     if (!pViewSh)
    1279           0 :         throw RuntimeException();
    1280             : 
    1281          72 :     Sequence<DataPilotFieldFilter> aFilters;
    1282             :     pDPObj->GetDataFieldPositionData(
    1283          36 :         ScAddress(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet), aFilters);
    1284          72 :     pViewSh->ShowDataPilotSourceData(*pDPObj, aFilters);
    1285          36 : }
    1286             : 
    1287          19 : CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
    1288             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    1289             : {
    1290          19 :     SolarMutexGuard aGuard;
    1291          19 :     if (nType < 0 || nType > DataPilotOutputRangeType::RESULT)
    1292           4 :         throw IllegalArgumentException();
    1293             : 
    1294          15 :     CellRangeAddress aRet;
    1295          15 :     if (ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName))
    1296          15 :         ScUnoConversion::FillApiRange( aRet, pDPObj->GetOutputRangeByType( nType ) );
    1297          19 :     return aRet;
    1298             : }
    1299             : 
    1300           0 : void SAL_CALL ScDataPilotTableObj::addModifyListener( const uno::Reference<util::XModifyListener>& aListener )
    1301             :     throw (uno::RuntimeException, std::exception)
    1302             : {
    1303           0 :     SolarMutexGuard aGuard;
    1304             : 
    1305           0 :     uno::Reference<util::XModifyListener> *pObj = new uno::Reference<util::XModifyListener>( aListener );
    1306           0 :     aModifyListeners.push_back( pObj );
    1307             : 
    1308           0 :     if ( aModifyListeners.size() == 1 )
    1309             :     {
    1310           0 :         acquire();  // don't lose this object (one ref for all listeners)
    1311           0 :     }
    1312           0 : }
    1313             : 
    1314           0 : void SAL_CALL ScDataPilotTableObj::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
    1315             :     throw (uno::RuntimeException, std::exception)
    1316             : {
    1317           0 :     SolarMutexGuard aGuard;
    1318             : 
    1319           0 :     acquire();      // in case the listeners have the last ref - released below
    1320             : 
    1321           0 :     sal_uInt16 nCount = aModifyListeners.size();
    1322           0 :     for ( sal_uInt16 n=nCount; n--; )
    1323             :     {
    1324           0 :         uno::Reference<util::XModifyListener>& rObj = aModifyListeners[n];
    1325           0 :         if ( rObj == aListener )
    1326             :         {
    1327           0 :             aModifyListeners.erase( aModifyListeners.begin() + n );
    1328             : 
    1329           0 :             if ( aModifyListeners.empty() )
    1330             :             {
    1331           0 :                 release();      // release the ref for the listeners
    1332             :             }
    1333             : 
    1334           0 :             break;
    1335             :         }
    1336             :     }
    1337             : 
    1338           0 :     release();      // might delete this object
    1339           0 : }
    1340             : 
    1341         254 : void ScDataPilotTableObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
    1342             : {
    1343         288 :     if ( rHint.ISA(ScDataPilotModifiedHint) &&
    1344          34 :          static_cast<const ScDataPilotModifiedHint&>(rHint).GetName() == aName )
    1345             :     {
    1346          27 :         Refreshed_Impl();
    1347             :     }
    1348         227 :     else if ( rHint.ISA( ScUpdateRefHint ) )
    1349             :     {
    1350          64 :         ScRange aRange( 0, 0, nTab );
    1351          64 :         ScRangeList aRanges;
    1352          64 :         aRanges.Append( aRange );
    1353          64 :         const ScUpdateRefHint& rRef = static_cast< const ScUpdateRefHint& >( rHint );
    1354         128 :         if ( aRanges.UpdateReference( rRef.GetMode(), GetDocShell()->GetDocument(), rRef.GetRange(),
    1355         192 :                  rRef.GetDx(), rRef.GetDy(), rRef.GetDz() ) &&
    1356          64 :              aRanges.size() == 1 )
    1357             :         {
    1358          64 :             const ScRange* pRange = aRanges.front();
    1359          64 :             if ( pRange )
    1360             :             {
    1361          64 :                 nTab = pRange->aStart.Tab();
    1362             :             }
    1363          64 :         }
    1364             :     }
    1365             : 
    1366         254 :     ScDataPilotDescriptorBase::Notify( rBC, rHint );
    1367         254 : }
    1368             : 
    1369          27 : void ScDataPilotTableObj::Refreshed_Impl()
    1370             : {
    1371          27 :     lang::EventObject aEvent;
    1372          27 :     aEvent.Source.set((cppu::OWeakObject*)this);
    1373             : 
    1374             :     // the EventObject holds a Ref to this object until after the listener calls
    1375             : 
    1376          27 :     ScDocument* pDoc = GetDocShell()->GetDocument();
    1377          27 :     for ( sal_uInt16 n=0; n<aModifyListeners.size(); n++ )
    1378          27 :         pDoc->AddUnoListenerCall( aModifyListeners[n], aEvent );
    1379          27 : }
    1380             : 
    1381          17 : ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) :
    1382             :     ScDataPilotDescriptorBase( pDocSh ),
    1383          17 :     mpDPObject(new ScDPObject(pDocSh ? pDocSh->GetDocument() : NULL) )
    1384             : {
    1385          17 :     ScDPSaveData aSaveData;
    1386             :     // set defaults like in ScPivotParam constructor
    1387          17 :      aSaveData.SetColumnGrand( true );
    1388          17 :     aSaveData.SetRowGrand( true );
    1389          17 :     aSaveData.SetIgnoreEmptyRows( false );
    1390          17 :     aSaveData.SetRepeatIfEmpty( false );
    1391          17 :     mpDPObject->SetSaveData(aSaveData);
    1392          34 :     ScSheetSourceDesc aSheetDesc(pDocSh ? pDocSh->GetDocument() : NULL);
    1393          17 :     mpDPObject->SetSheetDesc(aSheetDesc);
    1394          34 :     mpDPObject->GetSource();
    1395          17 : }
    1396             : 
    1397          48 : ScDataPilotDescriptor::~ScDataPilotDescriptor()
    1398             : {
    1399          16 :     delete mpDPObject;
    1400          32 : }
    1401             : 
    1402         348 : ScDPObject* ScDataPilotDescriptor::GetDPObject() const
    1403             : {
    1404         348 :     return mpDPObject;
    1405             : }
    1406             : 
    1407         100 : void ScDataPilotDescriptor::SetDPObject( ScDPObject* pDPObject )
    1408             : {
    1409         100 :     if (mpDPObject != pDPObject)
    1410             :     {
    1411           0 :         delete mpDPObject;
    1412           0 :         mpDPObject = pDPObject;
    1413             :         OSL_FAIL("replace DPObject should not happen");
    1414             :     }
    1415         100 : }
    1416             : 
    1417             : // "rest of XDataPilotDescriptor"
    1418             : 
    1419           0 : OUString SAL_CALL ScDataPilotDescriptor::getName() throw(RuntimeException, std::exception)
    1420             : {
    1421           0 :     SolarMutexGuard aGuard;
    1422           0 :     return mpDPObject->GetName();
    1423             : }
    1424             : 
    1425           0 : void SAL_CALL ScDataPilotDescriptor::setName( const OUString& aNewName )
    1426             :                                                 throw(RuntimeException, std::exception)
    1427             : {
    1428           0 :     SolarMutexGuard aGuard;
    1429           0 :     mpDPObject->SetName( aNewName );
    1430           0 : }
    1431             : 
    1432          17 : OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(RuntimeException, std::exception)
    1433             : {
    1434          17 :     SolarMutexGuard aGuard;
    1435          17 :     return mpDPObject->GetTag();
    1436             : }
    1437             : 
    1438           0 : void SAL_CALL ScDataPilotDescriptor::setTag( const OUString& aNewTag )
    1439             :                                                 throw(RuntimeException, std::exception)
    1440             : {
    1441           0 :     SolarMutexGuard aGuard;
    1442           0 :     mpDPObject->SetTag( aNewTag );
    1443           0 : }
    1444             : 
    1445          59 : ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent ) :
    1446          59 :     mrParent( rParent )
    1447             : {
    1448          59 :     mrParent.acquire();
    1449          59 : }
    1450             : 
    1451         146 : ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
    1452             :     mrParent( rParent ),
    1453         146 :     maFieldId( rFieldId )
    1454             : {
    1455         146 :     mrParent.acquire();
    1456         146 : }
    1457             : 
    1458         408 : ScDataPilotChildObjBase::~ScDataPilotChildObjBase()
    1459             : {
    1460         204 :     mrParent.release();
    1461         204 : }
    1462             : 
    1463         492 : ScDPObject* ScDataPilotChildObjBase::GetDPObject() const
    1464             : {
    1465         492 :     return mrParent.GetDPObject();
    1466             : }
    1467             : 
    1468         101 : void ScDataPilotChildObjBase::SetDPObject( ScDPObject* pDPObject )
    1469             : {
    1470         101 :     mrParent.SetDPObject( pDPObject );
    1471         101 : }
    1472             : 
    1473         254 : ScDPSaveDimension* ScDataPilotChildObjBase::GetDPDimension( ScDPObject** ppDPObject ) const
    1474             : {
    1475         254 :     if( ScDPObject* pDPObj = GetDPObject() )
    1476             :     {
    1477         254 :         if( ppDPObject ) *ppDPObject = pDPObj;
    1478         254 :         if( ScDPSaveData* pSaveData = pDPObj->GetSaveData() )
    1479             :         {
    1480         254 :             if( maFieldId.mbDataLayout )
    1481         256 :                 return pSaveData->GetDataLayoutDimension();
    1482             : 
    1483         252 :             if( maFieldId.mnFieldIdx == 0 )
    1484         252 :                 return pSaveData->GetDimensionByName( maFieldId.maFieldName );
    1485             : 
    1486             :             // find dimension with specified index (search in duplicated dimensions)
    1487           0 :             const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
    1488             : 
    1489           0 :             sal_Int32 nFoundIdx = 0;
    1490           0 :             boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
    1491           0 :             for(it = rDimensions.begin(); it != rDimensions.end(); ++it)
    1492             :             {
    1493           0 :                 if( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
    1494             :                 {
    1495           0 :                     if( nFoundIdx == maFieldId.mnFieldIdx )
    1496           0 :                         return const_cast<ScDPSaveDimension*>(&(*it));
    1497           0 :                     ++nFoundIdx;
    1498             :                 }
    1499             :             }
    1500             :         }
    1501             :     }
    1502           0 :     return 0;
    1503             : }
    1504             : 
    1505          27 : sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
    1506             : {
    1507          27 :     sal_Int32 nRet = 0;
    1508          27 :     Reference<XNameAccess> xMembersNA = GetMembers();
    1509          27 :     if (xMembersNA.is())
    1510             :     {
    1511          27 :         Reference< XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
    1512          27 :         nRet = xMembersIA->getCount();
    1513             :     }
    1514          27 :     return nRet;
    1515             : }
    1516             : 
    1517          58 : Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
    1518             : {
    1519          58 :     Reference< XNameAccess > xMembersNA;
    1520          58 :     if( ScDPObject* pDPObj = GetDPObject() )
    1521          58 :         pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
    1522          58 :     return xMembersNA;
    1523             : }
    1524             : 
    1525           4 : ScDocShell* ScDataPilotChildObjBase::GetDocShell() const
    1526             : {
    1527           4 :     return mrParent.GetDocShell();
    1528             : }
    1529             : 
    1530          44 : ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent ) :
    1531          44 :     ScDataPilotChildObjBase( rParent )
    1532             : {
    1533          44 : }
    1534             : 
    1535          15 : ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent, DataPilotFieldOrientation eOrient ) :
    1536             :     ScDataPilotChildObjBase( rParent ),
    1537          15 :     maOrient( eOrient )
    1538             : {
    1539          15 : }
    1540             : 
    1541         118 : ScDataPilotFieldsObj::~ScDataPilotFieldsObj()
    1542             : {
    1543         118 : }
    1544             : 
    1545          48 : static sal_Int32 lcl_GetFieldCount( const Reference<XDimensionsSupplier>& rSource, const Any& rOrient )
    1546             : {
    1547          48 :     if (!rSource.is())
    1548           0 :         throw RuntimeException();
    1549             : 
    1550          48 :     sal_Int32 nRet = 0;
    1551             : 
    1552          48 :     Reference<XNameAccess> xDimsName(rSource->getDimensions());
    1553          96 :     Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
    1554          48 :     sal_Int32 nIntCount = xIntDims->getCount();
    1555          48 :     if (rOrient.hasValue())
    1556             :     {
    1557             :         // all fields of the specified orientation, including duplicated
    1558          28 :         Reference<XPropertySet> xDim;
    1559         205 :         for (sal_Int32 i = 0; i < nIntCount; ++i)
    1560             :         {
    1561         177 :             xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
    1562         177 :             if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
    1563          39 :                 ++nRet;
    1564          28 :         }
    1565             :     }
    1566             :     else
    1567             :     {
    1568             :         // count all non-duplicated fields
    1569             : 
    1570          20 :         Reference<XPropertySet> xDim;
    1571         140 :         for (sal_Int32 i = 0; i < nIntCount; ++i)
    1572             :         {
    1573         120 :             xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
    1574         120 :             if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
    1575         120 :                 ++nRet;
    1576          20 :         }
    1577             :     }
    1578             : 
    1579          96 :     return nRet;
    1580             : }
    1581             : 
    1582         119 : static sal_Bool lcl_GetFieldDataByIndex( const Reference<XDimensionsSupplier>& rSource,
    1583             :                                 const Any& rOrient, SCSIZE nIndex, ScFieldIdentifier& rFieldId )
    1584             : {
    1585         119 :     if (!rSource.is())
    1586           0 :         throw RuntimeException();
    1587             : 
    1588         119 :     sal_Bool bOk = false;
    1589         119 :     SCSIZE nPos = 0;
    1590         119 :     sal_Int32 nDimIndex = 0;
    1591             : 
    1592         119 :     Reference<XNameAccess> xDimsName(rSource->getDimensions());
    1593         238 :     Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
    1594         119 :     sal_Int32 nIntCount = xIntDims->getCount();
    1595         238 :     Reference<XPropertySet> xDim;
    1596         119 :     if (rOrient.hasValue())
    1597             :     {
    1598          26 :         sal_Int32 i = 0;
    1599         139 :         while (i < nIntCount && !bOk)
    1600             :         {
    1601          87 :             xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
    1602          87 :             if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
    1603             :             {
    1604          35 :                 if (nPos == nIndex)
    1605             :                 {
    1606          26 :                     bOk = sal_True;
    1607          26 :                     nDimIndex = i;
    1608             :                 }
    1609             :                 else
    1610           9 :                     ++nPos;
    1611             :             }
    1612          87 :             ++i;
    1613             :         }
    1614             :     }
    1615             :     else
    1616             :     {
    1617          93 :         sal_Int32 i = 0;
    1618         431 :         while (i < nIntCount && !bOk)
    1619             :         {
    1620         245 :             xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
    1621         245 :             if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
    1622             :             {
    1623         245 :                 if (nPos == nIndex)
    1624             :                 {
    1625          91 :                     bOk = sal_True;
    1626          91 :                     nDimIndex = i;
    1627             :                 }
    1628             :                 else
    1629         154 :                     ++nPos;
    1630             :             }
    1631         245 :             ++i;
    1632             :         }
    1633             :     }
    1634             : 
    1635         119 :     if ( bOk )
    1636             :     {
    1637         117 :         xDim.set( xIntDims->getByIndex(nDimIndex), UNO_QUERY );
    1638         117 :         Reference<XNamed> xDimName( xDim, UNO_QUERY );
    1639         117 :         if ( xDimName.is() )
    1640             :         {
    1641         117 :             OUString sOriginalName( lcl_GetOriginalName( xDimName ) );
    1642         117 :             rFieldId.maFieldName = sOriginalName;
    1643             :             rFieldId.mbDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDim,
    1644         117 :                         OUString(SC_UNO_DP_ISDATALAYOUT) );
    1645             : 
    1646         117 :             sal_Int32 nRepeat = 0;
    1647         117 :             if ( rOrient.hasValue() && lcl_IsDuplicated( xDim ) )
    1648             :             {
    1649             :                 // find the repeat count
    1650             :                 // (this relies on the original dimension always being before the duplicates)
    1651             : 
    1652           0 :                 Reference<XNamed> xPrevName;
    1653           0 :                 for (sal_Int32 i = 0; i < nDimIndex; ++i)
    1654             :                 {
    1655           0 :                     xPrevName.set( xIntDims->getByIndex(i), UNO_QUERY );
    1656           0 :                     if ( xPrevName.is() && lcl_GetOriginalName( xPrevName ) == sOriginalName )
    1657           0 :                         ++nRepeat;
    1658           0 :                 }
    1659             :             }
    1660         117 :             rFieldId.mnFieldIdx = nRepeat;
    1661             :         }
    1662             :         else
    1663           0 :             bOk = false;
    1664             :     }
    1665             : 
    1666         238 :     return bOk;
    1667             : }
    1668             : 
    1669          11 : static sal_Bool lcl_GetFieldDataByName( ScDPObject* pDPObj, const OUString& rFieldName, ScFieldIdentifier& rFieldId )
    1670             : {
    1671             :     // "By name" is always the first match.
    1672             :     // The name "Data" always refers to the data layout field.
    1673          11 :     rFieldId.maFieldName = rFieldName;
    1674          11 :     rFieldId.mnFieldIdx = 0;
    1675          11 :     rFieldId.mbDataLayout = rFieldName == SC_DATALAYOUT_NAME;
    1676             : 
    1677          11 :     pDPObj->GetSource();    // IsDimNameInUse doesn't update source data
    1678             : 
    1679             :     // check if the named field exists (not for data layout)
    1680          11 :     return rFieldId.mbDataLayout || pDPObj->IsDimNameInUse( rFieldName );
    1681             : }
    1682             : 
    1683             : // XDataPilotFields
    1684             : 
    1685         119 : ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
    1686             : {
    1687             : // TODO
    1688         119 :     if (ScDPObject* pObj = GetDPObject())
    1689             :     {
    1690         119 :         ScFieldIdentifier aFieldId;
    1691         119 :         if (lcl_GetFieldDataByIndex( pObj->GetSource(), maOrient, nIndex, aFieldId ))
    1692         117 :             return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
    1693             :     }
    1694           2 :     return 0;
    1695             : }
    1696             : 
    1697          11 : ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const OUString& aName) const
    1698             : {
    1699          11 :     if (ScDPObject* pDPObj = GetDPObject())
    1700             :     {
    1701          11 :         ScFieldIdentifier aFieldId;
    1702          11 :         if (lcl_GetFieldDataByName( pDPObj, aName, aFieldId ))
    1703           9 :             return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
    1704             :     }
    1705           2 :     return 0;
    1706             : }
    1707             : 
    1708             : // XEnumerationAccess
    1709             : 
    1710           2 : Reference<XEnumeration> SAL_CALL ScDataPilotFieldsObj::createEnumeration()
    1711             :                                                     throw(RuntimeException, std::exception)
    1712             : {
    1713           2 :     SolarMutexGuard aGuard;
    1714           2 :     return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotFieldsEnumeration"));
    1715             : }
    1716             : 
    1717             : // XIndexAccess
    1718             : 
    1719          47 : sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(RuntimeException, std::exception)
    1720             : {
    1721          47 :     SolarMutexGuard aGuard;
    1722             : // TODO
    1723          47 :     ScDPObject* pDPObj = GetDPObject();
    1724          47 :     return pDPObj ? lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) : 0;
    1725             : }
    1726             : 
    1727         119 : Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex )
    1728             :         throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
    1729             : {
    1730         119 :     SolarMutexGuard aGuard;
    1731         238 :     Reference< XPropertySet > xField( GetObjectByIndex_Impl( nIndex ) );
    1732         119 :     if (!xField.is())
    1733           2 :         throw IndexOutOfBoundsException();
    1734         236 :     return Any( xField );
    1735             : }
    1736             : 
    1737           1 : uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(RuntimeException, std::exception)
    1738             : {
    1739           1 :     SolarMutexGuard aGuard;
    1740           1 :     return getCppuType((Reference<XPropertySet>*)0);
    1741             : }
    1742             : 
    1743           1 : sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(RuntimeException, std::exception)
    1744             : {
    1745           1 :     SolarMutexGuard aGuard;
    1746           1 :     return ( getCount() != 0 );
    1747             : }
    1748             : 
    1749           9 : Any SAL_CALL ScDataPilotFieldsObj::getByName( const OUString& aName )
    1750             :         throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
    1751             : {
    1752           9 :     SolarMutexGuard aGuard;
    1753          18 :     Reference<XPropertySet> xField(GetObjectByName_Impl(aName));
    1754           9 :     if (!xField.is())
    1755           1 :         throw NoSuchElementException();
    1756          17 :     return Any( xField );
    1757             : }
    1758             : 
    1759           1 : Sequence<OUString> SAL_CALL ScDataPilotFieldsObj::getElementNames()
    1760             :                                                 throw(RuntimeException, std::exception)
    1761             : {
    1762           1 :     SolarMutexGuard aGuard;
    1763             : // TODO
    1764           1 :     if (ScDPObject* pDPObj = GetDPObject())
    1765             :     {
    1766           1 :         Sequence< OUString > aSeq( lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) );
    1767           1 :         OUString* pAry = aSeq.getArray();
    1768             : 
    1769           1 :         const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pDPObj->GetSaveData()->GetDimensions();
    1770           1 :         boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
    1771           1 :         for (it = rDimensions.begin(); it != rDimensions.end(); ++it)
    1772             :         {
    1773           0 :             if(maOrient.hasValue() && (it->GetOrientation() == maOrient.get< DataPilotFieldOrientation >()))
    1774             :             {
    1775           0 :                 *pAry = it->GetName();
    1776           0 :                 ++pAry;
    1777             :             }
    1778             :         }
    1779           1 :         return aSeq;
    1780             :     }
    1781           0 :     return Sequence<OUString>();
    1782             : }
    1783             : 
    1784           2 : sal_Bool SAL_CALL ScDataPilotFieldsObj::hasByName( const OUString& aName )
    1785             :                                         throw(RuntimeException, std::exception)
    1786             : {
    1787           2 :     SolarMutexGuard aGuard;
    1788             : 
    1789           2 :     return GetObjectByName_Impl(aName) != NULL;
    1790             : }
    1791             : 
    1792           0 : ScDataPilotFieldObj::ScDataPilotFieldObj(
    1793             :         ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
    1794             :     ScDataPilotChildObjBase( rParent, rFieldId ),
    1795           0 :     maPropSet( lcl_GetDataPilotFieldMap() )
    1796             : {
    1797           0 : }
    1798             : 
    1799         126 : ScDataPilotFieldObj::ScDataPilotFieldObj( ScDataPilotDescriptorBase& rParent,
    1800             :         const ScFieldIdentifier& rFieldId, const Any& rOrient ) :
    1801             :     ScDataPilotChildObjBase( rParent, rFieldId ),
    1802             :     maPropSet( lcl_GetDataPilotFieldMap() ),
    1803         126 :     maOrient( rOrient )
    1804             : {
    1805         126 : }
    1806             : 
    1807         250 : ScDataPilotFieldObj::~ScDataPilotFieldObj()
    1808             : {
    1809         250 : }
    1810             : 
    1811             : // XNamed
    1812             : 
    1813          55 : OUString SAL_CALL ScDataPilotFieldObj::getName()
    1814             :     throw (RuntimeException, std::exception)
    1815             : {
    1816          55 :     SolarMutexGuard aGuard;
    1817          55 :     OUString aName;
    1818          55 :     if( ScDPSaveDimension* pDim = GetDPDimension() )
    1819             :     {
    1820          55 :         if( pDim->IsDataLayout() )
    1821           0 :             aName = OUString( SC_DATALAYOUT_NAME );
    1822             :         else
    1823             :         {
    1824          55 :             const OUString* pLayoutName = pDim->GetLayoutName();
    1825          55 :             if (pLayoutName)
    1826           2 :                 aName = *pLayoutName;
    1827             :             else
    1828          53 :                 aName = pDim->GetName();
    1829             :         }                                                                }
    1830          55 :     return aName;
    1831             : }
    1832             : 
    1833           4 : void SAL_CALL ScDataPilotFieldObj::setName(const OUString& rName)
    1834             :     throw (RuntimeException, std::exception)
    1835             : {
    1836           4 :     SolarMutexGuard aGuard;
    1837           4 :     ScDPObject* pDPObj = 0;
    1838           4 :     ScDPSaveDimension* pDim = GetDPDimension( &pDPObj );
    1839           4 :     if( pDim && !pDim->IsDataLayout() )
    1840             :     {
    1841           4 :         pDim->SetLayoutName(rName);
    1842           4 :         SetDPObject( pDPObj );
    1843           4 :     }
    1844           4 : }
    1845             : 
    1846             : // XPropertySet
    1847             : 
    1848           2 : Reference<XPropertySetInfo> SAL_CALL ScDataPilotFieldObj::getPropertySetInfo()
    1849             :                                                         throw(RuntimeException, std::exception)
    1850             : {
    1851           2 :     SolarMutexGuard aGuard;
    1852             :     static Reference<XPropertySetInfo> aRef(
    1853           2 :         new SfxItemPropertySetInfo( maPropSet.getPropertyMap() ));
    1854           2 :     return aRef;
    1855             : }
    1856             : 
    1857         102 : void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
    1858             :         throw (UnknownPropertyException, PropertyVetoException,
    1859             :                IllegalArgumentException, WrappedTargetException,
    1860             :                RuntimeException, std::exception)
    1861             : {
    1862         102 :     SolarMutexGuard aGuard;
    1863         204 :     OUString aNameString(aPropertyName);
    1864         102 :     if ( aNameString.equalsAscii( SC_UNONAME_FUNCTION ) )
    1865             :     {
    1866             :         // #i109350# use GetEnumFromAny because it also allows sal_Int32
    1867             :         GeneralFunction eFunction = (GeneralFunction)
    1868          15 :                             ScUnoHelpFunctions::GetEnumFromAny( aValue );
    1869          15 :         setFunction( eFunction );
    1870             :     }
    1871          87 :     else if ( aNameString.equalsAscii( SC_UNONAME_SUBTOTALS ) )
    1872             :     {
    1873           4 :         Sequence< GeneralFunction > aSubtotals;
    1874           4 :         if( aValue >>= aSubtotals )
    1875           4 :             setSubtotals( aSubtotals );
    1876             :     }
    1877          83 :     else if ( aNameString.equalsAscii( SC_UNONAME_ORIENT ) )
    1878             :     {
    1879             :         //! test for correct enum type?
    1880             :         DataPilotFieldOrientation eOrient = (DataPilotFieldOrientation)
    1881          57 :                             ScUnoHelpFunctions::GetEnumFromAny( aValue );
    1882          57 :         setOrientation( eOrient );
    1883             :     }
    1884          26 :     else if ( aNameString.equalsAscii( SC_UNONAME_SELPAGE ) )
    1885             :     {
    1886           2 :         OUString sCurrentPage;
    1887           2 :         if (aValue >>= sCurrentPage)
    1888           2 :             setCurrentPage(sCurrentPage);
    1889             :     }
    1890          24 :     else if ( aNameString.equalsAscii( SC_UNONAME_USESELPAGE ) )
    1891             :     {
    1892           2 :         setUseCurrentPage(cppu::any2bool(aValue));
    1893             :     }
    1894          22 :     else if ( aNameString.equalsAscii( SC_UNONAME_HASAUTOSHOW ) )
    1895             :     {
    1896           3 :         if (!cppu::any2bool(aValue))
    1897           1 :             setAutoShowInfo(NULL);
    1898             :     }
    1899          19 :     else if ( aNameString.equalsAscii( SC_UNONAME_AUTOSHOW ) )
    1900             :     {
    1901           1 :         DataPilotFieldAutoShowInfo aInfo;
    1902           1 :         if (aValue >>= aInfo)
    1903           1 :             setAutoShowInfo(&aInfo);
    1904             :     }
    1905          18 :     else if ( aNameString.equalsAscii( SC_UNONAME_HASLAYOUTINFO ) )
    1906             :     {
    1907           3 :         if (!cppu::any2bool(aValue))
    1908           1 :             setLayoutInfo(NULL);
    1909             :     }
    1910          15 :     else if ( aNameString.equalsAscii( SC_UNONAME_LAYOUTINFO ) )
    1911             :     {
    1912           1 :         DataPilotFieldLayoutInfo aInfo;
    1913           1 :         if (aValue >>= aInfo)
    1914           1 :             setLayoutInfo(&aInfo);
    1915             :     }
    1916          14 :     else if ( aNameString.equalsAscii( SC_UNONAME_HASREFERENCE ) )
    1917             :     {
    1918           3 :         if (!cppu::any2bool(aValue))
    1919           1 :             setReference(NULL);
    1920             :     }
    1921          11 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFERENCE ) )
    1922             :     {
    1923           1 :         DataPilotFieldReference aRef;
    1924           1 :         if (aValue >>= aRef)
    1925           1 :             setReference(&aRef);
    1926             :     }
    1927          10 :     else if ( aNameString.equalsAscii( SC_UNONAME_HASSORTINFO ) )
    1928             :     {
    1929           3 :         if (!cppu::any2bool(aValue))
    1930           1 :             setSortInfo(NULL);
    1931             :     }
    1932           7 :     else if ( aNameString.equalsAscii( SC_UNONAME_SORTINFO ) )
    1933             :     {
    1934           1 :         DataPilotFieldSortInfo aInfo;
    1935           1 :         if (aValue >>= aInfo)
    1936           1 :             setSortInfo(&aInfo);
    1937             :     }
    1938           6 :     else if ( aNameString.equalsAscii( SC_UNONAME_ISGROUP ) )
    1939             :     {
    1940           2 :         if (!cppu::any2bool(aValue))
    1941           0 :             setGroupInfo(NULL);
    1942             :     }
    1943           4 :     else if ( aNameString.equalsAscii( SC_UNONAME_GROUPINFO ) )
    1944             :     {
    1945           0 :         DataPilotFieldGroupInfo aInfo;
    1946           0 :         if (aValue >>= aInfo)
    1947           0 :             setGroupInfo(&aInfo);
    1948             :     }
    1949           4 :     else if ( aNameString.equalsAscii( SC_UNONAME_SHOWEMPTY ) )
    1950             :     {
    1951           3 :         setShowEmpty(cppu::any2bool(aValue));
    1952         102 :     }
    1953         102 : }
    1954             : 
    1955          86 : Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName )
    1956             :         throw (UnknownPropertyException, WrappedTargetException,
    1957             :                RuntimeException, std::exception)
    1958             : {
    1959          86 :     SolarMutexGuard aGuard;
    1960         172 :     OUString aNameString(aPropertyName);
    1961          86 :     Any aRet;
    1962             : 
    1963          86 :     if ( aNameString.equalsAscii( SC_UNONAME_FUNCTION ) )
    1964           7 :         aRet <<= getFunction();
    1965          79 :     else if ( aNameString.equalsAscii( SC_UNONAME_SUBTOTALS ) )
    1966          10 :         aRet <<= getSubtotals();
    1967          69 :     else if ( aNameString.equalsAscii( SC_UNONAME_ORIENT ) )
    1968          12 :         aRet <<= getOrientation();
    1969          57 :     else if ( aNameString.equalsAscii( SC_UNONAME_SELPAGE ) )
    1970           4 :         aRet <<= getCurrentPage();
    1971          53 :     else if ( aNameString.equalsAscii( SC_UNONAME_USESELPAGE ) )
    1972           4 :         aRet <<= getUseCurrentPage();
    1973          49 :     else if ( aNameString.equalsAscii( SC_UNONAME_HASAUTOSHOW ) )
    1974           6 :         aRet <<= (getAutoShowInfo() != NULL);
    1975          43 :     else if ( aNameString.equalsAscii( SC_UNONAME_AUTOSHOW ) )
    1976             :     {
    1977           1 :         const DataPilotFieldAutoShowInfo* pInfo = getAutoShowInfo();
    1978           1 :         if (pInfo)
    1979           1 :             aRet <<= DataPilotFieldAutoShowInfo(*pInfo);
    1980             :     }
    1981          42 :     else if ( aNameString.equalsAscii( SC_UNONAME_HASLAYOUTINFO ) )
    1982           6 :         aRet <<= (getLayoutInfo() != NULL);
    1983          36 :     else if ( aNameString.equalsAscii( SC_UNONAME_LAYOUTINFO ) )
    1984             :     {
    1985           1 :         const DataPilotFieldLayoutInfo* pInfo = getLayoutInfo();
    1986           1 :         if (pInfo)
    1987           1 :             aRet <<= DataPilotFieldLayoutInfo(*pInfo);
    1988             :     }
    1989          35 :     else if ( aNameString.equalsAscii( SC_UNONAME_HASREFERENCE ) )
    1990           6 :         aRet <<= (getReference() != NULL);
    1991          29 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFERENCE ) )
    1992             :     {
    1993           1 :         const DataPilotFieldReference* pRef = getReference();
    1994           1 :         if (pRef)
    1995           1 :             aRet <<= DataPilotFieldReference(*pRef);
    1996             :     }
    1997          28 :     else if ( aNameString.equalsAscii( SC_UNONAME_HASSORTINFO ) )
    1998           6 :         aRet <<= (getSortInfo() != NULL);
    1999          22 :     else if ( aNameString.equalsAscii( SC_UNONAME_SORTINFO ) )
    2000             :     {
    2001           1 :         const DataPilotFieldSortInfo* pInfo = getSortInfo();
    2002           1 :         if (pInfo)
    2003           1 :             aRet <<= DataPilotFieldSortInfo(*pInfo);
    2004             :     }
    2005          21 :     else if ( aNameString.equalsAscii( SC_UNONAME_ISGROUP ) )
    2006          11 :         aRet <<= (hasGroupInfo());
    2007          10 :     else if ( aNameString.equalsAscii( SC_UNONAME_GROUPINFO ) )
    2008             :     {
    2009           3 :         aRet <<= getGroupInfo();
    2010             :     }
    2011           7 :     else if ( aNameString.equalsAscii( SC_UNONAME_SHOWEMPTY ) )
    2012           7 :         aRet <<= getShowEmpty();
    2013             : 
    2014         172 :     return aRet;
    2015             : }
    2016             : 
    2017             : // XDatePilotField
    2018             : 
    2019           5 : Reference<XIndexAccess> SAL_CALL ScDataPilotFieldObj::getItems()
    2020             :                 throw (RuntimeException, std::exception)
    2021             : {
    2022           5 :     SolarMutexGuard aGuard;
    2023           5 :     if (!mxItems.is())
    2024           5 :         mxItems.set( new ScDataPilotItemsObj( mrParent, maFieldId ) );
    2025           5 :     return mxItems;
    2026             : }
    2027             : 
    2028           0 : SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj )
    2029             : 
    2030          12 : DataPilotFieldOrientation ScDataPilotFieldObj::getOrientation() const
    2031             : {
    2032          12 :     SolarMutexGuard aGuard;
    2033          12 :     ScDPSaveDimension* pDim = GetDPDimension();
    2034          12 :     return pDim ? static_cast< DataPilotFieldOrientation >( pDim->GetOrientation() ) : DataPilotFieldOrientation_HIDDEN;
    2035             : }
    2036             : 
    2037          57 : void ScDataPilotFieldObj::setOrientation(DataPilotFieldOrientation eNew)
    2038             : {
    2039          57 :     SolarMutexGuard aGuard;
    2040          57 :     if (maOrient.hasValue() && (eNew == maOrient.get< DataPilotFieldOrientation >()))
    2041          57 :         return;
    2042             : 
    2043          57 :     ScDPObject* pDPObj = 0;
    2044          57 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2045             :     {
    2046          57 :         ScDPSaveData* pSaveData = pDPObj->GetSaveData();
    2047             : 
    2048             :         /*  If the field was taken from getDataPilotFields(), don't reset the
    2049             :             orientation for an existing use, but create a duplicated field
    2050             :             instead (for "Data" orientation only). */
    2051         228 :         if ( !maOrient.hasValue() && !maFieldId.mbDataLayout &&
    2052         121 :              (pDim->GetOrientation() != DataPilotFieldOrientation_HIDDEN) &&
    2053           7 :              (eNew == DataPilotFieldOrientation_DATA) )
    2054             :         {
    2055             : 
    2056           0 :             ScDPSaveDimension* pNewDim = 0;
    2057             : 
    2058             :             // look for existing duplicate with orientation "hidden"
    2059             : 
    2060           0 :             sal_Int32 nFound = 0;
    2061           0 :             const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
    2062           0 :             boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
    2063           0 :             for ( it = rDimensions.begin(); it != rDimensions.end() && !pNewDim; ++it )
    2064             :             {
    2065           0 :                 if ( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
    2066             :                 {
    2067           0 :                     if ( it->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
    2068           0 :                         pNewDim = const_cast<ScDPSaveDimension*>(&(*it));      // use this one
    2069             :                     else
    2070           0 :                         ++nFound;               // count existing non-hidden occurrences
    2071             :                 }
    2072             :             }
    2073             : 
    2074           0 :             if ( !pNewDim )     // if none found, create a new duplicated dimension
    2075           0 :                 pNewDim = &pSaveData->DuplicateDimension( *pDim );
    2076             : 
    2077           0 :             maFieldId.mnFieldIdx = nFound;      // keep accessing the new one
    2078           0 :             pDim = pNewDim;
    2079             :         }
    2080             : 
    2081          57 :         pDim->SetOrientation(sal::static_int_cast<sal_uInt16>(eNew));
    2082             : 
    2083             :         // move changed field behind all other fields (make it the last field in dimension)
    2084          57 :         pSaveData->SetPosition( pDim, pSaveData->GetDimensions().size() );
    2085             : 
    2086          57 :         SetDPObject( pDPObj );
    2087             : 
    2088          57 :         maOrient <<= eNew;   // modifying the same object's orientation again doesn't create another duplicate
    2089          57 :     }
    2090             : }
    2091             : 
    2092           7 : GeneralFunction ScDataPilotFieldObj::getFunction() const
    2093             : {
    2094           7 :     SolarMutexGuard aGuard;
    2095           7 :     GeneralFunction eRet = GeneralFunction_NONE;
    2096           7 :     if( ScDPSaveDimension* pDim = GetDPDimension() )
    2097             :     {
    2098           7 :         if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
    2099             :         {
    2100             :             // for non-data fields, property Function is the subtotals
    2101           5 :             long nSubCount = pDim->GetSubTotalsCount();
    2102           5 :             if ( nSubCount > 0 )
    2103           4 :                 eRet = (GeneralFunction)pDim->GetSubTotalFunc(0);    // always use the first one
    2104             :             // else keep NONE
    2105             :         }
    2106             :         else
    2107           2 :             eRet = (GeneralFunction)pDim->GetFunction();
    2108             :     }
    2109           7 :     return eRet;
    2110             : }
    2111             : 
    2112          15 : void ScDataPilotFieldObj::setFunction(GeneralFunction eNewFunc)
    2113             : {
    2114          15 :     SolarMutexGuard aGuard;
    2115          15 :     ScDPObject* pDPObj = 0;
    2116          15 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2117             :     {
    2118          15 :         if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
    2119             :         {
    2120             :             // for non-data fields, property Function is the subtotals
    2121          14 :             if ( eNewFunc == GeneralFunction_NONE )
    2122           0 :                 pDim->SetSubTotals( 0, NULL );
    2123             :             else
    2124             :             {
    2125          14 :                 sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( eNewFunc );
    2126          14 :                 pDim->SetSubTotals( 1, &nFunc );
    2127             :             }
    2128             :         }
    2129             :         else
    2130           1 :             pDim->SetFunction( sal::static_int_cast<sal_uInt16>( eNewFunc ) );
    2131          15 :         SetDPObject( pDPObj );
    2132          15 :     }
    2133          15 : }
    2134             : 
    2135          10 : Sequence< GeneralFunction > ScDataPilotFieldObj::getSubtotals() const
    2136             : {
    2137          10 :     SolarMutexGuard aGuard;
    2138          10 :     Sequence< GeneralFunction > aRet;
    2139          10 :     if( ScDPSaveDimension* pDim = GetDPDimension() )
    2140             :     {
    2141          10 :         if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
    2142             :         {
    2143             :             // for non-data fields, property Functions is the sequence of subtotals
    2144           5 :             sal_Int32 nCount = static_cast< sal_Int32 >( pDim->GetSubTotalsCount() );
    2145           5 :             if ( nCount > 0 )
    2146             :             {
    2147           4 :                 aRet.realloc( nCount );
    2148           8 :                 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
    2149           4 :                     aRet[ nIdx ] = (GeneralFunction)pDim->GetSubTotalFunc( nIdx );
    2150             :             }
    2151             :         }
    2152             :     }
    2153          10 :     return aRet;
    2154             : }
    2155             : 
    2156           4 : void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubtotals )
    2157             : {
    2158           4 :     SolarMutexGuard aGuard;
    2159           4 :     ScDPObject* pDPObj = 0;
    2160           4 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2161             :     {
    2162           4 :         if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
    2163             :         {
    2164           2 :             sal_Int32 nCount = rSubtotals.getLength();
    2165           2 :             if( nCount == 1 )
    2166             :             {
    2167             :                 // count 1: all values are allowed (including NONE and AUTO)
    2168           2 :                 if( rSubtotals[ 0 ] == GeneralFunction_NONE )
    2169           1 :                     pDim->SetSubTotals( 0, NULL );
    2170             :                 else
    2171             :                 {
    2172           1 :                     sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( rSubtotals[ 0 ] );
    2173           1 :                     pDim->SetSubTotals( 1, &nFunc );
    2174             :                 }
    2175             :             }
    2176           0 :             else if( nCount > 1 )
    2177             :             {
    2178             :                 // set multiple functions, ignore NONE and AUTO in this case
    2179           0 :                 ::std::vector< sal_uInt16 > aSubt;
    2180           0 :                 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
    2181             :                 {
    2182           0 :                     GeneralFunction eFunc = rSubtotals[ nIdx ];
    2183           0 :                     if( (eFunc != GeneralFunction_NONE) && (eFunc != GeneralFunction_AUTO) )
    2184             :                     {
    2185             :                         // do not insert functions twice
    2186           0 :                         sal_uInt16 nFunc = static_cast< sal_uInt16 >( eFunc );
    2187           0 :                         if( ::std::find( aSubt.begin(), aSubt.end(), nFunc ) == aSubt.end() )
    2188           0 :                             aSubt.push_back( nFunc );
    2189             :                     }
    2190             :                 }
    2191             :                 // set values from vector to ScDPSaveDimension
    2192           0 :                 if ( aSubt.empty() )
    2193           0 :                     pDim->SetSubTotals( 0, NULL );
    2194             :                 else
    2195           0 :                     pDim->SetSubTotals( static_cast< long >( aSubt.size() ), &aSubt.front() );
    2196             :             }
    2197             :         }
    2198           4 :         SetDPObject( pDPObj );
    2199           4 :     }
    2200           4 : }
    2201             : 
    2202           4 : OUString ScDataPilotFieldObj::getCurrentPage() const
    2203             : {
    2204           4 :     return OUString();
    2205             : }
    2206             : 
    2207           2 : void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage )
    2208             : {
    2209           2 :     SolarMutexGuard aGuard;
    2210           2 :     ScDPObject* pDPObj = 0;
    2211           2 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2212             :     {
    2213           2 :         pDim->SetCurrentPage( &rPage );
    2214           2 :         SetDPObject( pDPObj );
    2215           2 :     }
    2216           2 : }
    2217             : 
    2218           4 : bool ScDataPilotFieldObj::getUseCurrentPage() const
    2219             : {
    2220           4 :     return false;
    2221             : }
    2222             : 
    2223           2 : void ScDataPilotFieldObj::setUseCurrentPage( bool bUse )
    2224             : {
    2225           2 :     SolarMutexGuard aGuard;
    2226           2 :     ScDPObject* pDPObj = 0;
    2227           2 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2228             :     {
    2229           2 :         if( bUse )
    2230             :         {
    2231             :             /*  It is somehow useless to set the property "HasSelectedPage" to
    2232             :                 true, because it is still needed to set an explicit page name. */
    2233           2 :             const OUString aPage;
    2234           2 :             pDim->SetCurrentPage( &aPage );
    2235             :         }
    2236             :         else
    2237           0 :             pDim->SetCurrentPage( 0 );
    2238           2 :         SetDPObject( pDPObj );
    2239           2 :     }
    2240           2 : }
    2241             : 
    2242           7 : const DataPilotFieldAutoShowInfo* ScDataPilotFieldObj::getAutoShowInfo()
    2243             : {
    2244           7 :     SolarMutexGuard aGuard;
    2245           7 :     ScDPSaveDimension* pDim = GetDPDimension();
    2246           7 :     return pDim ? pDim->GetAutoShowInfo() : 0;
    2247             : }
    2248             : 
    2249           2 : void ScDataPilotFieldObj::setAutoShowInfo( const DataPilotFieldAutoShowInfo* pInfo )
    2250             : {
    2251           2 :     SolarMutexGuard aGuard;
    2252           2 :     ScDPObject* pDPObj = 0;
    2253           2 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2254             :     {
    2255           2 :         pDim->SetAutoShowInfo( pInfo );
    2256           2 :         SetDPObject( pDPObj );
    2257           2 :     }
    2258           2 : }
    2259             : 
    2260           7 : const DataPilotFieldLayoutInfo* ScDataPilotFieldObj::getLayoutInfo()
    2261             : {
    2262           7 :     SolarMutexGuard aGuard;
    2263           7 :     ScDPSaveDimension* pDim = GetDPDimension();
    2264           7 :     return pDim ? pDim->GetLayoutInfo() : 0;
    2265             : }
    2266             : 
    2267           2 : void ScDataPilotFieldObj::setLayoutInfo( const DataPilotFieldLayoutInfo* pInfo )
    2268             : {
    2269           2 :     SolarMutexGuard aGuard;
    2270           2 :     ScDPObject* pDPObj = 0;
    2271           2 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2272             :     {
    2273           2 :         pDim->SetLayoutInfo( pInfo );
    2274           2 :         SetDPObject( pDPObj );
    2275           2 :     }
    2276           2 : }
    2277             : 
    2278           7 : const DataPilotFieldReference* ScDataPilotFieldObj::getReference()
    2279             : {
    2280           7 :     SolarMutexGuard aGuard;
    2281           7 :     ScDPSaveDimension* pDim = GetDPDimension();
    2282           7 :     return pDim ? pDim->GetReferenceValue() : 0;
    2283             : }
    2284             : 
    2285           2 : void ScDataPilotFieldObj::setReference( const DataPilotFieldReference* pInfo )
    2286             : {
    2287           2 :     SolarMutexGuard aGuard;
    2288           2 :     ScDPObject* pDPObj = 0;
    2289           2 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2290             :     {
    2291           2 :         pDim->SetReferenceValue( pInfo );
    2292           2 :         SetDPObject( pDPObj );
    2293           2 :     }
    2294           2 : }
    2295             : 
    2296           7 : const DataPilotFieldSortInfo* ScDataPilotFieldObj::getSortInfo()
    2297             : {
    2298           7 :     SolarMutexGuard aGuard;
    2299           7 :     ScDPSaveDimension* pDim = GetDPDimension();
    2300           7 :     return pDim ? pDim->GetSortInfo() : 0;
    2301             : }
    2302             : 
    2303           2 : void ScDataPilotFieldObj::setSortInfo( const DataPilotFieldSortInfo* pInfo )
    2304             : {
    2305           2 :     SolarMutexGuard aGuard;
    2306           2 :     ScDPObject* pDPObj = 0;
    2307           2 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2308             :     {
    2309           2 :         pDim->SetSortInfo( pInfo );
    2310           2 :         SetDPObject( pDPObj );
    2311           2 :     }
    2312           2 : }
    2313             : 
    2314           7 : bool ScDataPilotFieldObj::getShowEmpty() const
    2315             : {
    2316           7 :     SolarMutexGuard aGuard;
    2317           7 :     ScDPSaveDimension* pDim = GetDPDimension();
    2318           7 :     return pDim && pDim->GetShowEmpty();
    2319             : }
    2320             : 
    2321           3 : void ScDataPilotFieldObj::setShowEmpty( bool bShow )
    2322             : {
    2323           3 :     SolarMutexGuard aGuard;
    2324           3 :     ScDPObject* pDPObj = 0;
    2325           3 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2326             :     {
    2327           3 :         pDim->SetShowEmpty( bShow );
    2328           3 :         SetDPObject( pDPObj );
    2329           3 :     }
    2330           3 : }
    2331             : 
    2332          11 : bool ScDataPilotFieldObj::hasGroupInfo()
    2333             : {
    2334          11 :     SolarMutexGuard aGuard;
    2335          11 :     ScDPObject* pDPObj = 0;
    2336          11 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2337          11 :         if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
    2338           6 :             return pDimData->GetNamedGroupDim( pDim->GetName() ) || pDimData->GetNumGroupDim( pDim->GetName() );
    2339           5 :     return false;
    2340             : }
    2341             : 
    2342           3 : DataPilotFieldGroupInfo ScDataPilotFieldObj::getGroupInfo()
    2343             : {
    2344           3 :     SolarMutexGuard aGuard;
    2345           3 :     DataPilotFieldGroupInfo aInfo;
    2346           3 :     ScDPObject* pDPObj = 0;
    2347           3 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2348             :     {
    2349           3 :         if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
    2350             :         {
    2351           3 :             if( const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( pDim->GetName() ) )
    2352             :             {
    2353             :                 // grouped by ...
    2354           3 :                 aInfo.GroupBy = pGroupDim->GetDatePart();
    2355             : 
    2356             :                 // find source field
    2357             :                 try
    2358             :                 {
    2359           3 :                     Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
    2360           3 :                     aInfo.SourceField.set( xFields->getByName( pGroupDim->GetSourceDimName() ), UNO_QUERY );
    2361             :                 }
    2362           0 :                 catch( Exception& )
    2363             :                 {
    2364             :                 }
    2365             : 
    2366           3 :                 ScDataPilotConversion::FillGroupInfo( aInfo, pGroupDim->GetDateInfo() );
    2367           3 :                 if( pGroupDim->GetDatePart() == 0 )
    2368             :                 {
    2369             :                     // fill vector of group and group member information
    2370           3 :                     ScFieldGroups aGroups;
    2371           6 :                     for( sal_Int32 nIdx = 0, nCount = pGroupDim->GetGroupCount(); nIdx < nCount; ++nIdx )
    2372             :                     {
    2373           3 :                         if( const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( nIdx ) )
    2374             :                         {
    2375           3 :                             ScFieldGroup aGroup;
    2376           3 :                             aGroup.maName = pGroup->GetGroupName();
    2377           9 :                             for( sal_Int32 nMemIdx = 0, nMemCount = pGroup->GetElementCount(); nMemIdx < nMemCount; ++nMemIdx )
    2378           6 :                                 if (const OUString* pMem = pGroup->GetElementByIndex(nMemIdx))
    2379           6 :                                     aGroup.maMembers.push_back( *pMem );
    2380           3 :                             aGroups.push_back( aGroup );
    2381             :                         }
    2382             :                     }
    2383           3 :                     aInfo.Groups = new ScDataPilotFieldGroupsObj( aGroups );
    2384             :                 }
    2385             :             }
    2386           0 :             else if( const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( pDim->GetName() ) )
    2387             :             {
    2388           0 :                 if (pNumGroupDim->GetDatePart())
    2389             :                 {
    2390           0 :                     ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetDateInfo() );
    2391           0 :                     aInfo.GroupBy = pNumGroupDim->GetDatePart();
    2392             :                 }
    2393             :                 else
    2394             :                 {
    2395           0 :                     ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetInfo() );
    2396             :                 }
    2397             :             }
    2398             :         }
    2399             :     }
    2400           3 :     return aInfo;
    2401             : }
    2402             : 
    2403           0 : void ScDataPilotFieldObj::setGroupInfo( const DataPilotFieldGroupInfo* pInfo )
    2404             : {
    2405           0 :     SolarMutexGuard aGuard;
    2406           0 :     ScDPObject* pDPObj = 0;
    2407           0 :     if( /*ScDPSaveDimension* pDim =*/ GetDPDimension( &pDPObj ) )
    2408             :     {
    2409           0 :         ScDPSaveData* pSaveData = pDPObj->GetSaveData();
    2410           0 :         if( pInfo && lclCheckMinMaxStep( *pInfo ) )
    2411             :         {
    2412           0 :             ScDPNumGroupInfo aInfo;
    2413           0 :             aInfo.mbEnable = true;
    2414           0 :             aInfo.mbDateValues = pInfo->HasDateValues;
    2415           0 :             aInfo.mbAutoStart = pInfo->HasAutoStart;
    2416           0 :             aInfo.mbAutoEnd = pInfo->HasAutoEnd;
    2417           0 :             aInfo.mfStart = pInfo->Start;
    2418           0 :             aInfo.mfEnd = pInfo->End;
    2419           0 :             aInfo.mfStep = pInfo->Step;
    2420           0 :             Reference< XNamed > xNamed( pInfo->SourceField, UNO_QUERY );
    2421           0 :             if( xNamed.is() )
    2422             :             {
    2423           0 :                 ScDPSaveGroupDimension aGroupDim( xNamed->getName(), getName() );
    2424           0 :                 if( pInfo->GroupBy )
    2425           0 :                     aGroupDim.SetDateInfo(aInfo, pInfo->GroupBy);
    2426             :                 else
    2427             :                 {
    2428           0 :                     Reference<XIndexAccess> xIndex(pInfo->Groups, UNO_QUERY);
    2429           0 :                     if (xIndex.is())
    2430             :                     {
    2431           0 :                         sal_Int32 nCount(xIndex->getCount());
    2432           0 :                         for(sal_Int32 i = 0; i < nCount; i++)
    2433             :                         {
    2434           0 :                             Reference<XNamed> xGroupNamed(xIndex->getByIndex(i), UNO_QUERY);
    2435           0 :                             if (xGroupNamed.is())
    2436             :                             {
    2437           0 :                                 ScDPSaveGroupItem aItem(xGroupNamed->getName());
    2438           0 :                                 Reference<XIndexAccess> xGroupIndex(xGroupNamed, UNO_QUERY);
    2439           0 :                                 if (xGroupIndex.is())
    2440             :                                 {
    2441           0 :                                     sal_Int32 nItemCount(xGroupIndex->getCount());
    2442           0 :                                     for (sal_Int32 j = 0; j < nItemCount; ++j)
    2443             :                                     {
    2444           0 :                                         Reference<XNamed> xItemNamed(xGroupIndex->getByIndex(j), UNO_QUERY);
    2445           0 :                                         if (xItemNamed.is())
    2446           0 :                                             aItem.AddElement(xItemNamed->getName());
    2447           0 :                                     }
    2448             :                                 }
    2449           0 :                                 aGroupDim.AddGroupItem(aItem);
    2450             :                             }
    2451           0 :                         }
    2452           0 :                     }
    2453             :                 }
    2454             : 
    2455             :                 // get dimension savedata or create new if none
    2456           0 :                 ScDPDimensionSaveData& rDimSaveData = *pSaveData->GetDimensionData();
    2457           0 :                 rDimSaveData.ReplaceGroupDimension( aGroupDim );
    2458             :             }
    2459             :             else    // no source field in group info -> numeric group
    2460             :             {
    2461           0 :                 ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData();     // created if not there
    2462             : 
    2463           0 :                 ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( getName() );
    2464           0 :                 if ( pExisting )
    2465             :                 {
    2466           0 :                     if (pInfo->GroupBy)
    2467           0 :                         pExisting->SetDateInfo(aInfo, pInfo->GroupBy);
    2468             :                     // modify existing group dimension
    2469           0 :                     pExisting->SetGroupInfo( aInfo );
    2470             :                 }
    2471           0 :                 else if (pInfo->GroupBy)
    2472             :                 {
    2473             :                     // create new group dimension
    2474           0 :                     ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo, pInfo->GroupBy );
    2475           0 :                     pDimData->AddNumGroupDimension( aNumGroupDim );
    2476             :                 }
    2477             :                 else
    2478             :                 {
    2479             :                     // create new group dimension
    2480           0 :                     ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo );
    2481           0 :                     pDimData->AddNumGroupDimension( aNumGroupDim );
    2482             :                 }
    2483           0 :             }
    2484             :         }
    2485             :         else    // null passed as argument
    2486             :         {
    2487           0 :             pSaveData->SetDimensionData( 0 );
    2488             :         }
    2489             : 
    2490           0 :         pDPObj->SetSaveData( *pSaveData );
    2491           0 :         SetDPObject( pDPObj );
    2492           0 :     }
    2493           0 : }
    2494             : 
    2495           0 : bool ScDataPilotFieldObj::HasString(const Sequence< OUString >& rItems, const OUString& aString)
    2496             : {
    2497           0 :     bool bRet = false;
    2498             : 
    2499           0 :     sal_Int32 nCount(rItems.getLength());
    2500           0 :     sal_Int32 nItem(0);
    2501           0 :     while (nItem < nCount && !bRet)
    2502             :     {
    2503           0 :         bRet = rItems[nItem] == aString;
    2504           0 :         ++nItem;
    2505             :     }
    2506             : 
    2507           0 :     return bRet;
    2508             : }
    2509             : 
    2510             : // XDataPilotFieldGrouping
    2511           4 : Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( const Sequence< OUString >& rItems )
    2512             :          throw (RuntimeException, IllegalArgumentException,
    2513             :                 std::exception)
    2514             : {
    2515           4 :     SolarMutexGuard aGuard;
    2516             : 
    2517           4 :     Reference< XDataPilotField > xRet;
    2518           8 :     OUString sNewDim;
    2519             : 
    2520           4 :     if( !rItems.hasElements() )
    2521           0 :         throw IllegalArgumentException();
    2522             : 
    2523           4 :     ScDPObject* pDPObj = 0;
    2524           4 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2525             :     {
    2526           4 :         OUString aDimName = pDim->GetName();
    2527             : 
    2528           8 :         ScDPSaveData aSaveData = *pDPObj->GetSaveData();
    2529           4 :         ScDPDimensionSaveData* pDimData = aSaveData.GetDimensionData();     // created if not there
    2530             : 
    2531             :         // find original base
    2532           8 :         OUString aBaseDimName( aDimName );
    2533           4 :         const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
    2534           4 :         if ( pBaseGroupDim )
    2535             :         {
    2536             :             // any entry's SourceDimName is the original base
    2537           0 :             aBaseDimName = pBaseGroupDim->GetSourceDimName();
    2538             :         }
    2539             : 
    2540             :         // find existing group dimension
    2541             :         // (using the selected dim, can be intermediate group dim)
    2542           4 :         ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
    2543             : 
    2544             :         // remove the selected items from their groups
    2545             :         // (empty groups are removed, too)
    2546           4 :         sal_Int32 nEntryCount = rItems.getLength();
    2547             :         sal_Int32 nEntry;
    2548           4 :         if ( pGroupDimension )
    2549             :         {
    2550           0 :             for (nEntry=0; nEntry<nEntryCount; nEntry++)
    2551             :             {
    2552           0 :                 const OUString& aEntryName = rItems[nEntry];
    2553           0 :                 if ( pBaseGroupDim )
    2554             :                 {
    2555             :                     // for each selected (intermediate) group, remove all its items
    2556             :                     // (same logic as for adding, below)
    2557           0 :                     const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
    2558           0 :                     if ( pBaseGroup )
    2559           0 :                         pBaseGroup->RemoveElementsFromGroups( *pGroupDimension );   // remove all elements
    2560             :                     else
    2561           0 :                         pGroupDimension->RemoveFromGroups( aEntryName );
    2562             :                 }
    2563             :                 else
    2564           0 :                     pGroupDimension->RemoveFromGroups( aEntryName );
    2565             :             }
    2566             :         }
    2567             : 
    2568           4 :         ScDPSaveGroupDimension* pNewGroupDim = 0;
    2569           4 :         if ( !pGroupDimension )
    2570             :         {
    2571             :             // create a new group dimension
    2572           4 :             sNewDim = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
    2573           4 :             pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, sNewDim );
    2574             : 
    2575           4 :             pGroupDimension = pNewGroupDim;     // make changes to the new dim if none existed
    2576             : 
    2577           4 :             if ( pBaseGroupDim )
    2578             :             {
    2579             :                 // If it's a higher-order group dimension, pre-allocate groups for all
    2580             :                 // non-selected original groups, so the individual base members aren't
    2581             :                 // used for automatic groups (this would make the original groups hard
    2582             :                 // to find).
    2583             :                 //! Also do this when removing groups?
    2584             :                 //! Handle this case dynamically with automatic groups?
    2585             : 
    2586           0 :                 long nGroupCount = pBaseGroupDim->GetGroupCount();
    2587           0 :                 for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
    2588             :                 {
    2589           0 :                     const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
    2590             : 
    2591           0 :                     if (!HasString(rItems, pBaseGroup->GetGroupName()))    //! ignore case?
    2592             :                     {
    2593             :                         // add an additional group for each item that is not in the selection
    2594           0 :                         ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
    2595           0 :                         aGroup.AddElementsFromGroup( *pBaseGroup );
    2596           0 :                         pGroupDimension->AddGroupItem( aGroup );
    2597             :                     }
    2598             :                 }
    2599             :             }
    2600             :         }
    2601           8 :         OUString aGroupDimName = pGroupDimension->GetGroupDimName();
    2602             : 
    2603             :         //! localized prefix string
    2604           8 :         OUString aGroupName = pGroupDimension->CreateGroupName( OUString( "Group" ) );
    2605           8 :         ScDPSaveGroupItem aGroup( aGroupName );
    2606           8 :         Reference< XNameAccess > xMembers = GetMembers();
    2607           4 :         if (!xMembers.is())
    2608             :         {
    2609           0 :             delete pNewGroupDim;
    2610           0 :             throw RuntimeException();
    2611             :         }
    2612             : 
    2613          15 :         for (nEntry=0; nEntry<nEntryCount; nEntry++)
    2614             :         {
    2615          11 :             OUString aEntryName(rItems[nEntry]);
    2616             : 
    2617          11 :             if (!xMembers->hasByName(aEntryName))
    2618             :             {
    2619           0 :                 delete pNewGroupDim;
    2620           0 :                 throw IllegalArgumentException();
    2621             :             }
    2622             : 
    2623          11 :             if ( pBaseGroupDim )
    2624             :             {
    2625             :                 // for each selected (intermediate) group, add all its items
    2626           0 :                 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
    2627           0 :                 if ( pBaseGroup )
    2628           0 :                     aGroup.AddElementsFromGroup( *pBaseGroup );
    2629             :                 else
    2630           0 :                     aGroup.AddElement( aEntryName );    // no group found -> automatic group, add the item itself
    2631             :             }
    2632             :             else
    2633          11 :                 aGroup.AddElement( aEntryName );        // no group dimension, add all items directly
    2634          11 :         }
    2635             : 
    2636           4 :         pGroupDimension->AddGroupItem( aGroup );
    2637             : 
    2638           4 :         if ( pNewGroupDim )
    2639             :         {
    2640           4 :             pDimData->AddGroupDimension( *pNewGroupDim );
    2641           4 :             delete pNewGroupDim;        // AddGroupDimension copies the object
    2642             :             // don't access pGroupDimension after here
    2643             :         }
    2644           4 :         pGroupDimension = pNewGroupDim = NULL;
    2645             : 
    2646             :         // set orientation
    2647           4 :         ScDPSaveDimension* pSaveDimension = aSaveData.GetDimensionByName( aGroupDimName );
    2648           4 :         if ( pSaveDimension->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
    2649             :         {
    2650           4 :             ScDPSaveDimension* pOldDimension = aSaveData.GetDimensionByName( aDimName );
    2651           4 :             pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
    2652           4 :             long nPosition = 0;     //! before (immediate) base
    2653           4 :             aSaveData.SetPosition( pSaveDimension, nPosition );
    2654             :         }
    2655             : 
    2656             :         // apply changes
    2657           4 :         pDPObj->SetSaveData( aSaveData );
    2658           8 :         ScDBDocFunc(*GetDocShell()).RefreshPivotTableGroups(pDPObj);
    2659             :     }
    2660             : 
    2661             :     // if new grouping field has been created (on first group), return it
    2662           4 :     if( !sNewDim.isEmpty() )
    2663             :     {
    2664           4 :         Reference< XNameAccess > xFields(mrParent.getDataPilotFields(), UNO_QUERY);
    2665           4 :         if (xFields.is())
    2666             :         {
    2667             :             try
    2668             :             {
    2669           4 :                 xRet.set(xFields->getByName(sNewDim), UNO_QUERY);
    2670             :                 OSL_ENSURE(xRet.is(), "there is a name, so there should be also a field");
    2671             :             }
    2672           0 :             catch (const container::NoSuchElementException&)
    2673             :             {
    2674             :                 // Avoid throwing exception that's not specified in the method signature.
    2675           0 :                 throw RuntimeException();
    2676             :             }
    2677           4 :         }
    2678             :     }
    2679           8 :     return xRet;
    2680             : }
    2681             : 
    2682           0 : Reference < XDataPilotField > SAL_CALL ScDataPilotFieldObj::createDateGroup( const DataPilotFieldGroupInfo& rInfo )
    2683             :         throw (RuntimeException, IllegalArgumentException,
    2684             :                std::exception)
    2685             : {
    2686           0 :     SolarMutexGuard aGuard;
    2687             :     using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
    2688             : 
    2689             :     // check min/max/step, HasDateValues must be set always
    2690           0 :     if( !rInfo.HasDateValues || !lclCheckMinMaxStep( rInfo ) )
    2691           0 :         throw IllegalArgumentException();
    2692             :     // only a single date flag is allowed
    2693           0 :     if( (rInfo.GroupBy == 0) || (rInfo.GroupBy > YEARS) || ((rInfo.GroupBy & (rInfo.GroupBy - 1)) != 0) )
    2694           0 :         throw IllegalArgumentException();
    2695             :     // step must be zero, if something else than DAYS is specified
    2696           0 :     if( rInfo.Step >= ((rInfo.GroupBy == DAYS) ? 32768.0 : 1.0) )
    2697           0 :         throw IllegalArgumentException();
    2698             : 
    2699           0 :     OUString aGroupDimName;
    2700           0 :     ScDPObject* pDPObj = 0;
    2701           0 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    2702             :     {
    2703           0 :         ScDPNumGroupInfo aInfo;
    2704           0 :         aInfo.mbEnable = true;
    2705           0 :         aInfo.mbDateValues = (rInfo.GroupBy == DAYS) && (rInfo.Step >= 1.0);
    2706           0 :         aInfo.mbAutoStart = rInfo.HasAutoStart;
    2707           0 :         aInfo.mbAutoEnd = rInfo.HasAutoEnd;
    2708           0 :         aInfo.mfStart = rInfo.Start;
    2709           0 :         aInfo.mfEnd = rInfo.End;
    2710           0 :         aInfo.mfStep = static_cast< sal_Int32 >( rInfo.Step );
    2711             : 
    2712             :         // create a local copy of the entire save data (will be written back below)
    2713           0 :         ScDPSaveData aSaveData = *pDPObj->GetSaveData();
    2714             :         // get or create dimension save data
    2715           0 :         ScDPDimensionSaveData& rDimData = *aSaveData.GetDimensionData();
    2716             : 
    2717             :         // find source dimension name
    2718           0 :         const OUString& rDimName = pDim->GetName();
    2719           0 :         const ScDPSaveGroupDimension* pGroupDim = rDimData.GetNamedGroupDim( rDimName );
    2720           0 :         OUString aSrcDimName = pGroupDim ? pGroupDim->GetSourceDimName() : rDimName;
    2721             : 
    2722             :         // find a group dimension for the base field, or get numeric grouping
    2723           0 :         pGroupDim = rDimData.GetFirstNamedGroupDim( aSrcDimName );
    2724           0 :         const ScDPSaveNumGroupDimension* pNumGroupDim = rDimData.GetNumGroupDim( aSrcDimName );
    2725             : 
    2726             :         // do not group by dates, if named groups or numeric grouping is present
    2727           0 :         bool bHasNamedGrouping = pGroupDim && !pGroupDim->GetDateInfo().mbEnable;
    2728           0 :         bool bHasNumGrouping = pNumGroupDim && pNumGroupDim->GetInfo().mbEnable && !pNumGroupDim->GetInfo().mbDateValues && !pNumGroupDim->GetDateInfo().mbEnable;
    2729           0 :         if( bHasNamedGrouping || bHasNumGrouping )
    2730           0 :             throw IllegalArgumentException();
    2731             : 
    2732           0 :         if( aInfo.mbDateValues )  // create day ranges grouping
    2733             :         {
    2734             :             // first remove all named group dimensions
    2735           0 :             while( pGroupDim )
    2736             :             {
    2737           0 :                 OUString aGroupDimName2 = pGroupDim->GetGroupDimName();
    2738             :                 // find next group dimension before deleting this group
    2739           0 :                 pGroupDim = rDimData.GetNextNamedGroupDim( aGroupDimName2 );
    2740             :                 // remove from dimension save data
    2741           0 :                 rDimData.RemoveGroupDimension( aGroupDimName2 );
    2742             :                 // also remove save data settings for the dimension that no longer exists
    2743           0 :                 aSaveData.RemoveDimensionByName( aGroupDimName2 );
    2744           0 :             }
    2745             :             // create or replace the number grouping dimension
    2746           0 :             ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo );
    2747           0 :             rDimData.ReplaceNumGroupDimension( aNumGroupDim );
    2748             :         }
    2749             :         else    // create date grouping
    2750             :         {
    2751             :             // collect all existing date flags
    2752           0 :             sal_Int32 nDateParts = rDimData.CollectDateParts( aSrcDimName );
    2753           0 :             if( nDateParts == 0 )
    2754             :             {
    2755             :                 // insert numeric group dimension, if no date groups exist yet (or replace day range grouping)
    2756           0 :                 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo, rInfo.GroupBy );
    2757           0 :                 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
    2758             :             }
    2759           0 :             else if( (nDateParts & rInfo.GroupBy) == 0 )    // do nothing if date field exists already
    2760             :             {
    2761             :                 // create new named group dimension for additional date groups
    2762           0 :                 aGroupDimName = rDimData.CreateDateGroupDimName( rInfo.GroupBy, *pDPObj, true, 0 );
    2763           0 :                 ScDPSaveGroupDimension aGroupDim( aSrcDimName, aGroupDimName, aInfo, rInfo.GroupBy );
    2764           0 :                 rDimData.AddGroupDimension( aGroupDim );
    2765             : 
    2766             :                 // set orientation of new named group dimension
    2767           0 :                 ScDPSaveDimension& rSaveDim = *aSaveData.GetDimensionByName( aGroupDimName );
    2768           0 :                 if( rSaveDim.GetOrientation() == DataPilotFieldOrientation_HIDDEN )
    2769             :                 {
    2770           0 :                     ScDPSaveDimension& rOldDim = *aSaveData.GetDimensionByName( aSrcDimName );
    2771           0 :                     rSaveDim.SetOrientation( rOldDim.GetOrientation() );
    2772           0 :                     aSaveData.SetPosition( &rSaveDim, 0 );  //! before (immediate) base
    2773           0 :                 }
    2774             :             }
    2775             :         }
    2776             : 
    2777             :         // apply changes
    2778           0 :         pDPObj->SetSaveData( aSaveData );
    2779           0 :         SetDPObject( pDPObj );
    2780             :     }
    2781             : 
    2782             :     // return the UNO object of the new dimension, after writing back saved data
    2783           0 :     Reference< XDataPilotField > xRet;
    2784           0 :     if( !aGroupDimName.isEmpty() )
    2785             :         try
    2786             :         {
    2787           0 :            Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
    2788           0 :            xRet.set( xFields->getByName( aGroupDimName ), UNO_QUERY );
    2789             :         }
    2790           0 :         catch( Exception& )
    2791             :         {
    2792             :         }
    2793           0 :     return xRet;
    2794             : }
    2795             : 
    2796             : namespace {
    2797             : 
    2798           0 : bool lclExtractGroupMembers( ScFieldGroupMembers& rMembers, const Any& rElement )
    2799             : {
    2800             :     // allow empty value to create a new group
    2801           0 :     if( !rElement.hasValue() )
    2802           0 :         return true;
    2803             : 
    2804             :     // try to extract a simple sequence of strings
    2805           0 :     Sequence< OUString > aSeq;
    2806           0 :     if( rElement >>= aSeq )
    2807             :     {
    2808           0 :         if( aSeq.hasElements() )
    2809           0 :             rMembers.insert( rMembers.end(), aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength() );
    2810           0 :         return true;
    2811             :     }
    2812             : 
    2813             :     // try to use XIndexAccess providing objects that support XNamed
    2814           0 :     Reference< XIndexAccess > xItemsIA( rElement, UNO_QUERY );
    2815           0 :     if( xItemsIA.is() )
    2816             :     {
    2817           0 :         for( sal_Int32 nIdx = 0, nCount = xItemsIA->getCount(); nIdx < nCount; ++nIdx )
    2818             :         {
    2819             :             try // getByIndex() should not throw, but we cannot be sure
    2820             :             {
    2821           0 :                 Reference< XNamed > xItemName( xItemsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
    2822           0 :                 rMembers.push_back( xItemName->getName() );
    2823             :             }
    2824           0 :             catch( Exception& )
    2825             :             {
    2826             :                 // ignore exceptions, go ahead with next element in the array
    2827             :             }
    2828             :         }
    2829           0 :         return true;
    2830             :     }
    2831             : 
    2832             :     // nothing valid inside the Any -> return false
    2833           0 :     return false;
    2834             : }
    2835             : 
    2836             : } // namespace
    2837             : 
    2838           3 : ScDataPilotFieldGroupsObj::ScDataPilotFieldGroupsObj( const ScFieldGroups& rGroups ) :
    2839           3 :     maGroups( rGroups )
    2840             : {
    2841           3 : }
    2842             : 
    2843           6 : ScDataPilotFieldGroupsObj::~ScDataPilotFieldGroupsObj()
    2844             : {
    2845           6 : }
    2846             : 
    2847             : // XNameAccess
    2848             : 
    2849           2 : Any SAL_CALL ScDataPilotFieldGroupsObj::getByName( const OUString& rName )
    2850             :         throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
    2851             : {
    2852           2 :     SolarMutexGuard aGuard;
    2853           2 :     if( implFindByName( rName ) == maGroups.end() )
    2854           1 :         throw NoSuchElementException();
    2855           1 :     return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, rName ) ) );
    2856             : }
    2857             : 
    2858           1 : Sequence< OUString > SAL_CALL ScDataPilotFieldGroupsObj::getElementNames() throw(RuntimeException, std::exception)
    2859             : {
    2860           1 :     SolarMutexGuard aGuard;
    2861           1 :     Sequence< OUString > aSeq;
    2862           1 :     if( !maGroups.empty() )
    2863             :     {
    2864           1 :         aSeq.realloc( static_cast< sal_Int32 >( maGroups.size() ) );
    2865           1 :         OUString* pName = aSeq.getArray();
    2866           2 :         for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt, ++pName )
    2867           1 :             *pName = aIt->maName;
    2868             :     }
    2869           1 :     return aSeq;
    2870             : }
    2871             : 
    2872           2 : sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasByName( const OUString& rName ) throw(RuntimeException, std::exception)
    2873             : {
    2874           2 :     SolarMutexGuard aGuard;
    2875           2 :     return implFindByName( rName ) != maGroups.end();
    2876             : }
    2877             : 
    2878             : // XNameReplace
    2879             : 
    2880           0 : void SAL_CALL ScDataPilotFieldGroupsObj::replaceByName( const OUString& rName, const Any& rElement )
    2881             :         throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
    2882             : {
    2883           0 :     SolarMutexGuard aGuard;
    2884             : 
    2885           0 :     if( rName.isEmpty() )
    2886           0 :         throw IllegalArgumentException();
    2887             : 
    2888           0 :     ScFieldGroups::iterator aIt = implFindByName( rName );
    2889           0 :     if( aIt == maGroups.end() )
    2890           0 :         throw NoSuchElementException();
    2891             : 
    2892             :     // read all item names provided by the passed object
    2893           0 :     ScFieldGroupMembers aMembers;
    2894           0 :     if( !lclExtractGroupMembers( aMembers, rElement ) )
    2895           0 :         throw IllegalArgumentException();
    2896             : 
    2897             :     // copy and forget, faster than vector assignment
    2898           0 :     aIt->maMembers.swap( aMembers );
    2899           0 : }
    2900             : 
    2901             : // XNameContainer
    2902             : 
    2903           0 : void SAL_CALL ScDataPilotFieldGroupsObj::insertByName( const OUString& rName, const Any& rElement )
    2904             :         throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
    2905             : {
    2906           0 :     SolarMutexGuard aGuard;
    2907             : 
    2908           0 :     if( rName.isEmpty() )
    2909           0 :         throw IllegalArgumentException();
    2910             : 
    2911           0 :     ScFieldGroups::iterator aIt = implFindByName( rName );
    2912           0 :     if( aIt != maGroups.end() )
    2913           0 :         throw ElementExistException();
    2914             : 
    2915             :     // read all item names provided by the passed object
    2916           0 :     ScFieldGroupMembers aMembers;
    2917           0 :     if( !lclExtractGroupMembers( aMembers, rElement ) )
    2918           0 :         throw IllegalArgumentException();
    2919             : 
    2920             :     // create the new entry if no error has been occurred
    2921           0 :     maGroups.resize( maGroups.size() + 1 );
    2922           0 :     ScFieldGroup& rGroup = maGroups.back();
    2923           0 :     rGroup.maName = rName;
    2924           0 :     rGroup.maMembers.swap( aMembers );
    2925           0 : }
    2926             : 
    2927           0 : void SAL_CALL ScDataPilotFieldGroupsObj::removeByName( const OUString& rName )
    2928             :         throw (NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
    2929             : {
    2930           0 :     SolarMutexGuard aGuard;
    2931             : 
    2932           0 :     if( rName.isEmpty() )
    2933           0 :         throw IllegalArgumentException();
    2934             : 
    2935           0 :     ScFieldGroups::iterator aIt = implFindByName( rName );
    2936           0 :     if( aIt == maGroups.end() )
    2937           0 :         throw NoSuchElementException();
    2938             : 
    2939           0 :     maGroups.erase( aIt );
    2940           0 : }
    2941             : 
    2942             : // XIndexAccess
    2943             : 
    2944           1 : sal_Int32 SAL_CALL ScDataPilotFieldGroupsObj::getCount() throw(RuntimeException, std::exception)
    2945             : {
    2946           1 :     SolarMutexGuard aGuard;
    2947           1 :     return static_cast< sal_Int32 >( maGroups.size() );
    2948             : }
    2949             : 
    2950           6 : Any SAL_CALL ScDataPilotFieldGroupsObj::getByIndex( sal_Int32 nIndex )
    2951             :         throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
    2952             : {
    2953           6 :     SolarMutexGuard aGuard;
    2954           6 :     if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( maGroups.size() )))
    2955           1 :         throw IndexOutOfBoundsException();
    2956           5 :     return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, maGroups[ nIndex ].maName ) ) );
    2957             : }
    2958             : 
    2959             : // XEnumerationAccess
    2960             : 
    2961           1 : Reference<XEnumeration> SAL_CALL ScDataPilotFieldGroupsObj::createEnumeration() throw(RuntimeException, std::exception)
    2962             : {
    2963           1 :     SolarMutexGuard aGuard;
    2964           1 :     return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupsEnumeration" ) );
    2965             : }
    2966             : 
    2967             : // XElementAccess
    2968             : 
    2969           1 : uno::Type SAL_CALL ScDataPilotFieldGroupsObj::getElementType() throw(RuntimeException, std::exception)
    2970             : {
    2971           1 :     SolarMutexGuard aGuard;
    2972           1 :     return getCppuType( (Reference< XNameAccess >*)0 );
    2973             : }
    2974             : 
    2975           1 : sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasElements() throw(RuntimeException, std::exception)
    2976             : {
    2977           1 :     SolarMutexGuard aGuard;
    2978           1 :     return !maGroups.empty();
    2979             : }
    2980             : 
    2981             : // implementation
    2982             : 
    2983           9 : ScFieldGroup& ScDataPilotFieldGroupsObj::getFieldGroup( const OUString& rName ) throw(RuntimeException)
    2984             : {
    2985           9 :     SolarMutexGuard aGuard;
    2986           9 :     ScFieldGroups::iterator aIt = implFindByName( rName );
    2987           9 :     if( aIt == maGroups.end() )
    2988           0 :         throw RuntimeException();
    2989           9 :      return *aIt;
    2990             : }
    2991             : 
    2992           2 : void ScDataPilotFieldGroupsObj::renameFieldGroup( const OUString& rOldName, const OUString& rNewName ) throw(RuntimeException)
    2993             : {
    2994           2 :     SolarMutexGuard aGuard;
    2995           2 :     ScFieldGroups::iterator aOldIt = implFindByName( rOldName );
    2996           2 :     ScFieldGroups::iterator aNewIt = implFindByName( rNewName );
    2997             :     // new name must not exist yet
    2998           2 :     if( (aOldIt == maGroups.end()) || ((aNewIt != maGroups.end()) && (aNewIt != aOldIt)) )
    2999           0 :         throw RuntimeException();
    3000           2 :     aOldIt->maName = rNewName;
    3001           2 : }
    3002             : 
    3003          17 : ScFieldGroups::iterator ScDataPilotFieldGroupsObj::implFindByName( const OUString& rName )
    3004             : {
    3005          21 :     for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt )
    3006          17 :         if( aIt->maName == rName )
    3007          13 :             return aIt;
    3008           4 :     return maGroups.end();
    3009             : }
    3010             : 
    3011             : namespace {
    3012             : 
    3013           2 : OUString lclExtractMember( const Any& rElement )
    3014             : {
    3015           2 :     if( rElement.has< OUString >() )
    3016           2 :         return rElement.get< OUString >();
    3017             : 
    3018           0 :     Reference< XNamed > xNamed( rElement, UNO_QUERY );
    3019           0 :     if( xNamed.is() )
    3020           0 :         return xNamed->getName();
    3021             : 
    3022           0 :     return OUString();
    3023             : }
    3024             : 
    3025             : } // namespace
    3026             : 
    3027           6 : ScDataPilotFieldGroupObj::ScDataPilotFieldGroupObj( ScDataPilotFieldGroupsObj& rParent, const OUString& rGroupName ) :
    3028             :     mrParent( rParent ),
    3029           6 :     maGroupName( rGroupName )
    3030             : {
    3031           6 :     mrParent.acquire();
    3032           6 : }
    3033             : 
    3034          18 : ScDataPilotFieldGroupObj::~ScDataPilotFieldGroupObj()
    3035             : {
    3036           6 :     mrParent.release();
    3037          12 : }
    3038             : 
    3039             : // XNameAccess
    3040             : 
    3041           1 : Any SAL_CALL ScDataPilotFieldGroupObj::getByName( const OUString& rName )
    3042             :         throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
    3043             : {
    3044           1 :     SolarMutexGuard aGuard;
    3045           1 :     ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
    3046           1 :     ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
    3047           1 :     if( aIt == rMembers.end() )
    3048           0 :         throw NoSuchElementException();
    3049           1 :     return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, *aIt ) ) );
    3050             : }
    3051             : 
    3052           0 : Sequence< OUString > SAL_CALL ScDataPilotFieldGroupObj::getElementNames() throw(RuntimeException, std::exception)
    3053             : {
    3054           0 :     SolarMutexGuard aGuard;
    3055           0 :     return ::comphelper::containerToSequence( mrParent.getFieldGroup( maGroupName ).maMembers );
    3056             : }
    3057             : 
    3058           0 : sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasByName( const OUString& rName ) throw(RuntimeException, std::exception)
    3059             : {
    3060           0 :     SolarMutexGuard aGuard;
    3061           0 :     ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
    3062           0 :     return ::std::find( rMembers.begin(), rMembers.end(), rName ) != rMembers.end();
    3063             : }
    3064             : 
    3065             : // XNameReplace
    3066             : 
    3067           2 : void SAL_CALL ScDataPilotFieldGroupObj::replaceByName( const OUString& rName, const Any& rElement )
    3068             :         throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
    3069             : {
    3070           2 :     SolarMutexGuard aGuard;
    3071             : 
    3072             :     // it should be possible to quickly rename an item -> accept string or XNamed
    3073           4 :     OUString aNewName = lclExtractMember( rElement );
    3074           2 :     if( rName.isEmpty() || aNewName.isEmpty() )
    3075           0 :         throw IllegalArgumentException();
    3076           2 :     if( rName == aNewName )
    3077           2 :         return;
    3078             : 
    3079           2 :     ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
    3080           2 :     ScFieldGroupMembers::iterator aOldIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
    3081           2 :     ScFieldGroupMembers::iterator aNewIt = ::std::find( rMembers.begin(), rMembers.end(), aNewName );
    3082             :     // throw if passed member name does not exist
    3083           2 :     if( aOldIt == rMembers.end() )
    3084           0 :         throw NoSuchElementException();
    3085             :     // throw if new name already exists
    3086           2 :     if( aNewIt != rMembers.end() )
    3087           0 :         throw IllegalArgumentException();
    3088           4 :     *aOldIt = aNewName;
    3089             : }
    3090             : 
    3091             : // XNameContainer
    3092             : 
    3093           0 : void SAL_CALL ScDataPilotFieldGroupObj::insertByName( const OUString& rName, const Any& /*rElement*/ )
    3094             :         throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
    3095             : {
    3096           0 :     SolarMutexGuard aGuard;
    3097             : 
    3098             :     // we will ignore the passed element and just try to insert the name
    3099           0 :     if( rName.isEmpty() )
    3100           0 :         throw IllegalArgumentException();
    3101             : 
    3102           0 :     ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
    3103           0 :     ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
    3104             :     // throw if passed name already exists
    3105           0 :     if( aIt != rMembers.end() )
    3106           0 :         throw IllegalArgumentException();
    3107           0 :     rMembers.push_back( rName );
    3108           0 : }
    3109             : 
    3110           0 : void SAL_CALL ScDataPilotFieldGroupObj::removeByName( const OUString& rName )
    3111             :         throw (NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
    3112             : {
    3113           0 :     SolarMutexGuard aGuard;
    3114             : 
    3115           0 :     if( rName.isEmpty() )
    3116           0 :         throw IllegalArgumentException();
    3117           0 :     ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
    3118           0 :     ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
    3119             :     // throw if passed name does not exist
    3120           0 :     if( aIt == rMembers.end() )
    3121           0 :         throw NoSuchElementException();
    3122           0 :     rMembers.erase( aIt );
    3123           0 : }
    3124             : 
    3125             : // XIndexAccess
    3126             : 
    3127           1 : sal_Int32 SAL_CALL ScDataPilotFieldGroupObj::getCount() throw(RuntimeException, std::exception)
    3128             : {
    3129           1 :     SolarMutexGuard aGuard;
    3130           1 :     return static_cast< sal_Int32 >( mrParent.getFieldGroup( maGroupName ).maMembers.size() );
    3131             : }
    3132             : 
    3133           4 : Any SAL_CALL ScDataPilotFieldGroupObj::getByIndex( sal_Int32 nIndex )
    3134             :         throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
    3135             : {
    3136           4 :     SolarMutexGuard aGuard;
    3137           4 :     ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
    3138           4 :     if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( rMembers.size() )))
    3139           1 :         throw IndexOutOfBoundsException();
    3140           3 :     return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, rMembers[ nIndex ] ) ) );
    3141             : }
    3142             : 
    3143             : // XEnumerationAccess
    3144             : 
    3145           1 : Reference< XEnumeration > SAL_CALL ScDataPilotFieldGroupObj::createEnumeration() throw(RuntimeException, std::exception)
    3146             : {
    3147           1 :     SolarMutexGuard aGuard;
    3148           1 :     return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupEnumeration" ) );
    3149             : }
    3150             : 
    3151             : // XElementAccess
    3152             : 
    3153           1 : uno::Type SAL_CALL ScDataPilotFieldGroupObj::getElementType() throw(RuntimeException, std::exception)
    3154             : {
    3155           1 :     SolarMutexGuard aGuard;
    3156           1 :     return getCppuType( (Reference< XNamed >*)0 );
    3157             : }
    3158             : 
    3159           1 : sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasElements() throw(RuntimeException, std::exception)
    3160             : {
    3161           1 :     SolarMutexGuard aGuard;
    3162           1 :     return !mrParent.getFieldGroup( maGroupName ).maMembers.empty();
    3163             : }
    3164             : 
    3165             : // XNamed
    3166             : 
    3167           3 : OUString SAL_CALL ScDataPilotFieldGroupObj::getName() throw(RuntimeException, std::exception)
    3168             : {
    3169           3 :     SolarMutexGuard aGuard;
    3170           3 :     return maGroupName;
    3171             : }
    3172             : 
    3173           2 : void SAL_CALL ScDataPilotFieldGroupObj::setName( const OUString& rName ) throw(RuntimeException, std::exception)
    3174             : {
    3175           2 :     SolarMutexGuard aGuard;
    3176           2 :     mrParent.renameFieldGroup( maGroupName, rName );
    3177             :     // if call to renameFieldGroup() did not throw, remember the new name
    3178           2 :     maGroupName = rName;
    3179           2 : }
    3180             : 
    3181           4 : ScDataPilotFieldGroupItemObj::ScDataPilotFieldGroupItemObj( ScDataPilotFieldGroupObj& rParent, const OUString& rName ) :
    3182             :     mrParent( rParent ),
    3183           4 :     maName( rName )
    3184             : {
    3185           4 :     mrParent.acquire();
    3186           4 : }
    3187             : 
    3188          12 : ScDataPilotFieldGroupItemObj::~ScDataPilotFieldGroupItemObj()
    3189             : {
    3190           4 :     mrParent.release();
    3191           8 : }
    3192             : 
    3193             : // XNamed
    3194             : 
    3195           3 : OUString SAL_CALL ScDataPilotFieldGroupItemObj::getName() throw(RuntimeException, std::exception)
    3196             : {
    3197           3 :     SolarMutexGuard aGuard;
    3198           3 :     return maName;
    3199             : }
    3200             : 
    3201           2 : void SAL_CALL ScDataPilotFieldGroupItemObj::setName( const OUString& rName ) throw(RuntimeException, std::exception)
    3202             : {
    3203           2 :     SolarMutexGuard aGuard;
    3204           2 :     mrParent.replaceByName( maName, Any( rName ) );
    3205             :     // if call to replaceByName() did not throw, remember the new name
    3206           2 :     maName = rName;
    3207           2 : }
    3208             : 
    3209           5 : ScDataPilotItemsObj::ScDataPilotItemsObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
    3210           5 :     ScDataPilotChildObjBase( rParent, rFieldId )
    3211             : {
    3212           5 : }
    3213             : 
    3214          10 : ScDataPilotItemsObj::~ScDataPilotItemsObj()
    3215             : {
    3216          10 : }
    3217             : 
    3218             : // XDataPilotItems
    3219             : 
    3220          17 : ScDataPilotItemObj* ScDataPilotItemsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
    3221             : {
    3222          17 :     return ((0 <= nIndex) && (nIndex < GetMemberCount())) ?
    3223          32 :         new ScDataPilotItemObj( mrParent, maFieldId, nIndex ) : 0;
    3224             : }
    3225             : 
    3226             : // XNameAccess
    3227             : 
    3228           2 : Any SAL_CALL ScDataPilotItemsObj::getByName( const OUString& aName )
    3229             :         throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
    3230             : {
    3231           2 :     SolarMutexGuard aGuard;
    3232           4 :     Reference<XNameAccess> xMembers = GetMembers();
    3233           2 :     if (xMembers.is())
    3234             :     {
    3235           2 :         Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
    3236           2 :         sal_Int32 nCount = xMembersIndex->getCount();
    3237           2 :         sal_Bool bFound(false);
    3238           2 :         sal_Int32 nItem = 0;
    3239           9 :         while (nItem < nCount && !bFound )
    3240             :         {
    3241           6 :             Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
    3242           6 :             if (xMember.is() && (aName == xMember->getName()))
    3243           1 :                 return Any( Reference< XPropertySet >( GetObjectByIndex_Impl( nItem ) ) );
    3244           5 :             ++nItem;
    3245           5 :         }
    3246           1 :         if (!bFound)
    3247           1 :             throw NoSuchElementException();
    3248             :     }
    3249           2 :     return Any();
    3250             : }
    3251             : 
    3252           2 : Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
    3253             :                                                 throw(RuntimeException, std::exception)
    3254             : {
    3255           2 :     SolarMutexGuard aGuard;
    3256           2 :     Sequence< OUString > aSeq;
    3257           2 :     if( ScDPObject* pDPObj = GetDPObject() )
    3258           2 :         pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
    3259           2 :     return aSeq;
    3260             : }
    3261             : 
    3262           2 : sal_Bool SAL_CALL ScDataPilotItemsObj::hasByName( const OUString& aName )
    3263             :                                         throw(RuntimeException, std::exception)
    3264             : {
    3265           2 :     SolarMutexGuard aGuard;
    3266           2 :     sal_Bool bFound = false;
    3267           4 :     Reference<XNameAccess> xMembers = GetMembers();
    3268           2 :     if (xMembers.is())
    3269             :     {
    3270           2 :         Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
    3271           2 :         sal_Int32 nCount = xMembersIndex->getCount();
    3272           2 :         sal_Int32 nItem = 0;
    3273          10 :         while (nItem < nCount && !bFound )
    3274             :         {
    3275           6 :             Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
    3276           6 :             if (xMember.is() && aName == xMember->getName())
    3277           1 :                 bFound = sal_True;
    3278             :             else
    3279           5 :                 nItem++;
    3280           8 :         }
    3281             :     }
    3282           4 :     return bFound;
    3283             : }
    3284             : 
    3285             : // XEnumerationAccess
    3286             : 
    3287           2 : Reference<XEnumeration> SAL_CALL ScDataPilotItemsObj::createEnumeration()
    3288             :                                                     throw(RuntimeException, std::exception)
    3289             : {
    3290           2 :     SolarMutexGuard aGuard;
    3291           2 :     return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotItemsEnumeration"));
    3292             : }
    3293             : 
    3294             : // XIndexAccess
    3295             : 
    3296          10 : sal_Int32 SAL_CALL ScDataPilotItemsObj::getCount() throw(RuntimeException, std::exception)
    3297             : {
    3298          10 :     SolarMutexGuard aGuard;
    3299          10 :     return GetMemberCount();
    3300             : }
    3301             : 
    3302          16 : Any SAL_CALL ScDataPilotItemsObj::getByIndex( sal_Int32 nIndex )
    3303             :         throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
    3304             : {
    3305          16 :     SolarMutexGuard aGuard;
    3306          32 :     Reference< XPropertySet > xItem( GetObjectByIndex_Impl( nIndex ) );
    3307          16 :     if (!xItem.is())
    3308           2 :         throw IndexOutOfBoundsException();
    3309          30 :     return Any( xItem );
    3310             : }
    3311             : 
    3312           1 : uno::Type SAL_CALL ScDataPilotItemsObj::getElementType() throw(RuntimeException, std::exception)
    3313             : {
    3314           1 :     SolarMutexGuard aGuard;
    3315           1 :     return getCppuType((Reference<XPropertySet>*)0);
    3316             : }
    3317             : 
    3318           2 : sal_Bool SAL_CALL ScDataPilotItemsObj::hasElements() throw(RuntimeException, std::exception)
    3319             : {
    3320           2 :     SolarMutexGuard aGuard;
    3321           2 :     return ( getCount() != 0 );
    3322             : }
    3323             : 
    3324          15 : ScDataPilotItemObj::ScDataPilotItemObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId, sal_Int32 nIndex ) :
    3325             :     ScDataPilotChildObjBase( rParent, rFieldId ),
    3326             :     maPropSet( lcl_GetDataPilotItemMap() ),
    3327          15 :     mnIndex( nIndex )
    3328             : {
    3329          15 : }
    3330             : 
    3331          30 : ScDataPilotItemObj::~ScDataPilotItemObj()
    3332             : {
    3333          30 : }
    3334             : 
    3335             :                             // XNamed
    3336           1 : OUString SAL_CALL ScDataPilotItemObj::getName() throw(RuntimeException, std::exception)
    3337             : {
    3338           1 :     SolarMutexGuard aGuard;
    3339           1 :     OUString sRet;
    3340           2 :     Reference<XNameAccess> xMembers = GetMembers();
    3341           1 :     if (xMembers.is())
    3342             :     {
    3343           1 :         Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
    3344           1 :         sal_Int32 nCount = xMembersIndex->getCount();
    3345           1 :         if (mnIndex < nCount)
    3346             :         {
    3347           1 :             Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
    3348           1 :             sRet = xMember->getName();
    3349           1 :         }
    3350             :     }
    3351           2 :     return sRet;
    3352             : }
    3353             : 
    3354           0 : void SAL_CALL ScDataPilotItemObj::setName( const OUString& /* aName */ )
    3355             :                                 throw(RuntimeException, std::exception)
    3356             : {
    3357           0 : }
    3358             : 
    3359             :                             // XPropertySet
    3360             : Reference< XPropertySetInfo >
    3361           5 :                             SAL_CALL ScDataPilotItemObj::getPropertySetInfo(  )
    3362             :                                 throw(RuntimeException, std::exception)
    3363             : {
    3364           5 :     SolarMutexGuard aGuard;
    3365             :     static Reference<XPropertySetInfo> aRef =
    3366           5 :         new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
    3367           5 :     return aRef;
    3368             : }
    3369             : 
    3370           7 : void SAL_CALL ScDataPilotItemObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
    3371             :         throw (UnknownPropertyException, PropertyVetoException,
    3372             :                IllegalArgumentException, WrappedTargetException,
    3373             :                RuntimeException, std::exception)
    3374             : {
    3375           7 :     SolarMutexGuard aGuard;
    3376           7 :     ScDPObject* pDPObj = 0;
    3377           7 :     if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
    3378             :     {
    3379           7 :         Reference<XNameAccess> xMembers = GetMembers();
    3380           7 :         if( xMembers.is() )
    3381             :         {
    3382           7 :             Reference<XIndexAccess> xMembersIndex( new ScNameToIndexAccess( xMembers ) );
    3383           7 :             sal_Int32 nCount = xMembersIndex->getCount();
    3384           7 :             if( mnIndex < nCount )
    3385             :             {
    3386           7 :                 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
    3387          14 :                 OUString sName(xMember->getName());
    3388           7 :                 ScDPSaveMember* pMember = pDim->GetMemberByName(sName);
    3389           7 :                 if (pMember)
    3390             :                 {
    3391           7 :                     bool bGetNewIndex = false;
    3392           7 :                     if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
    3393           3 :                         pMember->SetShowDetails(cppu::any2bool(aValue));
    3394           4 :                     else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
    3395           3 :                         pMember->SetIsVisible(!cppu::any2bool(aValue));
    3396           1 :                     else if ( aPropertyName == SC_UNONAME_POS )
    3397             :                     {
    3398           1 :                         sal_Int32 nNewPos = 0;
    3399           1 :                         if ( ( aValue >>= nNewPos ) && nNewPos >= 0 && nNewPos < nCount )
    3400             :                         {
    3401           0 :                             pDim->SetMemberPosition( sName, nNewPos );
    3402             :                             // get new effective index (depends on sorting mode, which isn't modified)
    3403           0 :                             bGetNewIndex = true;
    3404             :                         }
    3405             :                         else
    3406           1 :                             throw IllegalArgumentException();
    3407             :                     }
    3408           6 :                     SetDPObject( pDPObj );
    3409             : 
    3410           6 :                     if ( bGetNewIndex )     // after SetDPObject, get the new index
    3411             :                     {
    3412           0 :                         OUString aOUName( sName );
    3413           0 :                         Sequence< OUString > aItemNames = xMembers->getElementNames();
    3414           0 :                         sal_Int32 nItemCount = aItemNames.getLength();
    3415           0 :                         for (sal_Int32 nItem=0; nItem<nItemCount; ++nItem)
    3416           0 :                             if (aItemNames[nItem] == aOUName)
    3417           0 :                                 mnIndex = nItem;
    3418             :                     }
    3419           7 :                 }
    3420           7 :             }
    3421           7 :         }
    3422           7 :     }
    3423           6 : }
    3424             : 
    3425          15 : Any SAL_CALL ScDataPilotItemObj::getPropertyValue( const OUString& aPropertyName )
    3426             :         throw (UnknownPropertyException, WrappedTargetException,
    3427             :                RuntimeException, std::exception)
    3428             : {
    3429          15 :     SolarMutexGuard aGuard;
    3430          15 :     Any aRet;
    3431          15 :     if( ScDPSaveDimension* pDim = GetDPDimension() )
    3432             :     {
    3433          15 :         Reference< XNameAccess > xMembers = GetMembers();
    3434          15 :         if( xMembers.is() )
    3435             :         {
    3436          15 :             Reference< XIndexAccess > xMembersIndex( new ScNameToIndexAccess( xMembers ) );
    3437          15 :             sal_Int32 nCount = xMembersIndex->getCount();
    3438          15 :             if( mnIndex < nCount )
    3439             :             {
    3440          15 :                 Reference< XNamed > xMember( xMembersIndex->getByIndex( mnIndex ), UNO_QUERY );
    3441          30 :                 OUString sName( xMember->getName() );
    3442          15 :                 ScDPSaveMember* pMember = pDim->GetExistingMemberByName( sName );
    3443          15 :                 if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
    3444             :                 {
    3445           7 :                     if (pMember && pMember->HasShowDetails())
    3446             :                     {
    3447           6 :                         aRet <<= (bool)pMember->GetShowDetails();
    3448             :                     }
    3449             :                     else
    3450             :                     {
    3451           1 :                         Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
    3452           1 :                         if( xMemberProps.is() )
    3453           1 :                             aRet = xMemberProps->getPropertyValue( OUString( SC_UNO_DP_SHOWDETAILS ) );
    3454             :                         else
    3455           0 :                             aRet <<= true;
    3456             :                     }
    3457             :                 }
    3458           8 :                 else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
    3459             :                 {
    3460           7 :                     if (pMember && pMember->HasIsVisible())
    3461             :                     {
    3462           6 :                         aRet <<= !pMember->GetIsVisible();
    3463             :                     }
    3464             :                     else
    3465             :                     {
    3466           1 :                         Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
    3467           1 :                         if( xMemberProps.is() )
    3468           1 :                             aRet <<= !cppu::any2bool( xMemberProps->getPropertyValue( OUString( SC_UNO_DP_ISVISIBLE ) ) );
    3469             :                         else
    3470           0 :                             aRet <<= false;
    3471             :                     }
    3472             :                 }
    3473           1 :                 else if ( aPropertyName == SC_UNONAME_POS )
    3474             :                 {
    3475           1 :                     aRet <<= mnIndex;
    3476          15 :                 }
    3477          15 :             }
    3478          15 :         }
    3479             :     }
    3480          15 :     return aRet;
    3481             : }
    3482             : 
    3483           0 : void SAL_CALL ScDataPilotItemObj::addPropertyChangeListener(
    3484             :         const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* xListener */ )
    3485             :         throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    3486             : {
    3487           0 : }
    3488             : 
    3489           0 : void SAL_CALL ScDataPilotItemObj::removePropertyChangeListener(
    3490             :         const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* aListener */ )
    3491             :         throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    3492             : {
    3493           0 : }
    3494             : 
    3495           0 : void SAL_CALL ScDataPilotItemObj::addVetoableChangeListener(
    3496             :         const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
    3497             :         throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    3498             : {
    3499           0 : }
    3500             : 
    3501           0 : void SAL_CALL ScDataPilotItemObj::removeVetoableChangeListener(
    3502             :         const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
    3503             :         throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    3504             : {
    3505         102 : }
    3506             : 
    3507             : 
    3508             : 
    3509             : 
    3510             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10