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

Generated by: LCOV version 1.10