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

Generated by: LCOV version 1.11