LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/ui/unoobj - dapiuno.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1247 1874 66.5 %
Date: 2013-07-09 Functions: 187 255 73.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10