LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - dpsave.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 533 751 71.0 %
Date: 2013-07-09 Functions: 65 94 69.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "dpsave.hxx"
      21             : #include "dpdimsave.hxx"
      22             : #include "miscuno.hxx"
      23             : #include "scerrors.hxx"
      24             : #include "unonames.hxx"
      25             : #include "global.hxx"
      26             : #include "dptabsrc.hxx"
      27             : #include "dputil.hxx"
      28             : 
      29             : #include <sal/types.h>
      30             : #include "comphelper/string.hxx"
      31             : 
      32             : #include <com/sun/star/sheet/GeneralFunction.hpp>
      33             : #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
      34             : #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
      35             : #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
      36             : #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
      37             : #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
      38             : #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
      39             : #include <com/sun/star/sheet/TableFilterField.hpp>
      40             : #include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
      41             : #include <com/sun/star/sheet/XLevelsSupplier.hpp>
      42             : #include <com/sun/star/sheet/XMembersSupplier.hpp>
      43             : #include <com/sun/star/container/XNamed.hpp>
      44             : #include <com/sun/star/util/XCloneable.hpp>
      45             : 
      46             : #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
      47             : #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
      48             : 
      49             : #include <boost/unordered_map.hpp>
      50             : #include <boost/unordered_set.hpp>
      51             : 
      52             : using namespace com::sun::star;
      53             : using namespace com::sun::star::sheet;
      54             : using ::com::sun::star::uno::Reference;
      55             : using ::com::sun::star::uno::Any;
      56             : using ::std::auto_ptr;
      57             : 
      58             : #define SC_DPSAVEMODE_DONTKNOW 2
      59             : 
      60         955 : static void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
      61             :                             const OUString& rName, sal_Bool bValue )
      62             : {
      63             :     //! move to ScUnoHelpFunctions?
      64             : 
      65         955 :     xProp->setPropertyValue( rName, uno::Any( &bValue, getBooleanCppuType() ) );
      66         955 : }
      67             : 
      68          54 : ScDPSaveMember::ScDPSaveMember(const OUString& rName) :
      69             :     aName( rName ),
      70             :     mpLayoutName(NULL),
      71             :     nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
      72          54 :     nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
      73             : {
      74          54 : }
      75             : 
      76         620 : ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) :
      77             :     aName( r.aName ),
      78             :     mpLayoutName(NULL),
      79             :     nVisibleMode( r.nVisibleMode ),
      80         620 :     nShowDetailsMode( r.nShowDetailsMode )
      81             : {
      82         620 :     if (r.mpLayoutName)
      83           0 :         mpLayoutName.reset(new OUString(*r.mpLayoutName));
      84         620 : }
      85             : 
      86         674 : ScDPSaveMember::~ScDPSaveMember()
      87             : {
      88         674 : }
      89             : 
      90           0 : bool ScDPSaveMember::operator== ( const ScDPSaveMember& r ) const
      91             : {
      92           0 :     if ( aName            != r.aName           ||
      93           0 :          nVisibleMode     != r.nVisibleMode    ||
      94           0 :          nShowDetailsMode != r.nShowDetailsMode )
      95           0 :         return false;
      96             : 
      97           0 :     return true;
      98             : }
      99             : 
     100           7 : bool ScDPSaveMember::HasIsVisible() const
     101             : {
     102           7 :     return nVisibleMode != SC_DPSAVEMODE_DONTKNOW;
     103             : }
     104             : 
     105          60 : void ScDPSaveMember::SetIsVisible(bool bSet)
     106             : {
     107          60 :     nVisibleMode = bSet;
     108          60 : }
     109             : 
     110           6 : bool ScDPSaveMember::HasShowDetails() const
     111             : {
     112           6 :     return nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW;
     113             : }
     114             : 
     115          41 : void ScDPSaveMember::SetShowDetails(bool bSet)
     116             : {
     117          41 :     nShowDetailsMode = bSet;
     118          41 : }
     119             : 
     120           0 : void ScDPSaveMember::SetName( const OUString& rNew )
     121             : {
     122             :     // Used only if the source member was renamed (groups).
     123             :     // For UI renaming of members, a layout name must be used.
     124             : 
     125           0 :     aName = rNew;
     126           0 : }
     127             : 
     128           0 : void ScDPSaveMember::SetLayoutName( const OUString& rName )
     129             : {
     130           0 :     mpLayoutName.reset(new OUString(rName));
     131           0 : }
     132             : 
     133           0 : const OUString* ScDPSaveMember::GetLayoutName() const
     134             : {
     135           0 :     return mpLayoutName.get();
     136             : }
     137             : 
     138           0 : void ScDPSaveMember::RemoveLayoutName()
     139             : {
     140           0 :     mpLayoutName.reset(NULL);
     141           0 : }
     142             : 
     143         233 : void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
     144             : {
     145         233 :     uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
     146             :     OSL_ENSURE( xMembProp.is(), "no properties at member" );
     147         233 :     if ( xMembProp.is() )
     148             :     {
     149             :         // exceptions are caught at ScDPSaveData::WriteToSource
     150             : 
     151         233 :         if ( nVisibleMode != SC_DPSAVEMODE_DONTKNOW )
     152             :             lcl_SetBoolProperty( xMembProp,
     153         233 :                     OUString(SC_UNO_DP_ISVISIBLE), (bool)nVisibleMode );
     154             : 
     155         233 :         if ( nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW )
     156             :             lcl_SetBoolProperty( xMembProp,
     157         200 :                     OUString(SC_UNO_DP_SHOWDETAILS), (bool)nShowDetailsMode );
     158             : 
     159         233 :         if (mpLayoutName)
     160           0 :             ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_DP_LAYOUTNAME, *mpLayoutName);
     161             : 
     162         233 :         if ( nPosition >= 0 )
     163          52 :             ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_DP_POSITION, nPosition);
     164         233 :     }
     165         233 : }
     166             : 
     167         134 : ScDPSaveDimension::ScDPSaveDimension(const OUString& rName, bool bDataLayout) :
     168             :     aName( rName ),
     169             :     mpLayoutName(NULL),
     170             :     mpSubtotalName(NULL),
     171             :     bIsDataLayout( bDataLayout ),
     172             :     bDupFlag( false ),
     173             :     nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ),
     174             :     nFunction( sheet::GeneralFunction_AUTO ),
     175             :     nUsedHierarchy( -1 ),
     176             :     nShowEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
     177             :     bSubTotalDefault( true ),
     178             :     nSubTotalCount( 0 ),
     179             :     pSubTotalFuncs( NULL ),
     180             :     pReferenceValue( NULL ),
     181             :     pSortInfo( NULL ),
     182             :     pAutoShowInfo( NULL ),
     183         134 :     pLayoutInfo( NULL )
     184             : {
     185         134 : }
     186             : 
     187         497 : ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
     188             :     aName( r.aName ),
     189             :     mpLayoutName(NULL),
     190             :     mpSubtotalName(NULL),
     191             :     bIsDataLayout( r.bIsDataLayout ),
     192             :     bDupFlag( r.bDupFlag ),
     193             :     nOrientation( r.nOrientation ),
     194             :     nFunction( r.nFunction ),
     195             :     nUsedHierarchy( r.nUsedHierarchy ),
     196             :     nShowEmptyMode( r.nShowEmptyMode ),
     197             :     bSubTotalDefault( r.bSubTotalDefault ),
     198             :     nSubTotalCount( r.nSubTotalCount ),
     199         497 :     pSubTotalFuncs( NULL )
     200             : {
     201         497 :     if ( nSubTotalCount && r.pSubTotalFuncs )
     202             :     {
     203         106 :         pSubTotalFuncs = new sal_uInt16[nSubTotalCount];
     204         212 :         for (long nSub=0; nSub<nSubTotalCount; nSub++)
     205         106 :             pSubTotalFuncs[nSub] = r.pSubTotalFuncs[nSub];
     206             :     }
     207             : 
     208        1117 :     for (MemberList::const_iterator i=r.maMemberList.begin(); i != r.maMemberList.end() ; ++i)
     209             :     {
     210         620 :         const OUString& rName =  (*i)->GetName();
     211         620 :         ScDPSaveMember* pNew = new ScDPSaveMember( **i );
     212         620 :         maMemberHash[rName] = pNew;
     213         620 :         maMemberList.push_back( pNew );
     214             :     }
     215         497 :     if (r.pReferenceValue)
     216           8 :         pReferenceValue = new sheet::DataPilotFieldReference( *(r.pReferenceValue) );
     217             :     else
     218         489 :         pReferenceValue = NULL;
     219         497 :     if (r.pSortInfo)
     220         136 :         pSortInfo = new sheet::DataPilotFieldSortInfo( *(r.pSortInfo) );
     221             :     else
     222         361 :         pSortInfo = NULL;
     223         497 :     if (r.pAutoShowInfo)
     224         148 :         pAutoShowInfo = new sheet::DataPilotFieldAutoShowInfo( *(r.pAutoShowInfo) );
     225             :     else
     226         349 :         pAutoShowInfo = NULL;
     227         497 :     if (r.pLayoutInfo)
     228         142 :         pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) );
     229             :     else
     230         355 :         pLayoutInfo = NULL;
     231         497 :     if (r.mpLayoutName)
     232           0 :         mpLayoutName.reset(new OUString(*r.mpLayoutName));
     233         497 :     if (r.mpSubtotalName)
     234           0 :         mpSubtotalName.reset(new OUString(*r.mpSubtotalName));
     235         497 : }
     236             : 
     237        1256 : ScDPSaveDimension::~ScDPSaveDimension()
     238             : {
     239        1302 :     for (MemberHash::const_iterator i=maMemberHash.begin(); i != maMemberHash.end() ; ++i)
     240         674 :         delete i->second;
     241         628 :     delete pReferenceValue;
     242         628 :     delete pSortInfo;
     243         628 :     delete pAutoShowInfo;
     244         628 :     delete pLayoutInfo;
     245         628 :     delete [] pSubTotalFuncs;
     246         628 : }
     247             : 
     248           0 : bool ScDPSaveDimension::operator== ( const ScDPSaveDimension& r ) const
     249             : {
     250           0 :     if ( aName            != r.aName            ||
     251           0 :          bIsDataLayout    != r.bIsDataLayout    ||
     252           0 :          bDupFlag         != r.bDupFlag         ||
     253           0 :          nOrientation     != r.nOrientation     ||
     254           0 :          nFunction        != r.nFunction        ||
     255           0 :          nUsedHierarchy   != r.nUsedHierarchy   ||
     256           0 :          nShowEmptyMode   != r.nShowEmptyMode   ||
     257           0 :          bSubTotalDefault != r.bSubTotalDefault ||
     258           0 :          nSubTotalCount   != r.nSubTotalCount    )
     259           0 :         return false;
     260             : 
     261           0 :     if ( nSubTotalCount && ( !pSubTotalFuncs || !r.pSubTotalFuncs ) ) // should not happen
     262           0 :         return false;
     263             : 
     264             :     long i;
     265           0 :     for (i=0; i<nSubTotalCount; i++)
     266           0 :         if ( pSubTotalFuncs[i] != r.pSubTotalFuncs[i] )
     267           0 :             return false;
     268             : 
     269           0 :     if (maMemberHash.size() != r.maMemberHash.size() )
     270           0 :         return false;
     271             : 
     272           0 :     MemberList::const_iterator a=maMemberList.begin();
     273           0 :     MemberList::const_iterator b=r.maMemberList.begin();
     274           0 :     for (; a != maMemberList.end() ; ++a, ++b)
     275           0 :         if (!(**a == **b))
     276           0 :             return false;
     277             : 
     278           0 :     if( pReferenceValue && r.pReferenceValue )
     279             :     {
     280           0 :         if ( !(*pReferenceValue == *r.pReferenceValue) )
     281             :         {
     282           0 :             return false;
     283             :         }
     284             :     }
     285           0 :     else if ( pReferenceValue || r.pReferenceValue )
     286             :     {
     287           0 :         return false;
     288             :     }
     289           0 :     if( this->pSortInfo && r.pSortInfo )
     290             :     {
     291           0 :         if ( !(*this->pSortInfo == *r.pSortInfo) )
     292             :         {
     293           0 :             return false;
     294             :         }
     295             :     }
     296           0 :     else if ( this->pSortInfo || r.pSortInfo )
     297             :     {
     298           0 :         return false;
     299             :     }
     300           0 :     if( this->pAutoShowInfo && r.pAutoShowInfo )
     301             :     {
     302           0 :         if ( !(*this->pAutoShowInfo == *r.pAutoShowInfo) )
     303             :         {
     304           0 :             return false;
     305             :         }
     306             :     }
     307           0 :     else if ( this->pAutoShowInfo || r.pAutoShowInfo )
     308             :     {
     309           0 :         return false;
     310             :     }
     311             : 
     312           0 :     return true;
     313             : }
     314             : 
     315          52 : void ScDPSaveDimension::AddMember(ScDPSaveMember* pMember)
     316             : {
     317          52 :     const OUString & rName = pMember->GetName();
     318          52 :     MemberHash::iterator aExisting = maMemberHash.find( rName );
     319          52 :     if ( aExisting == maMemberHash.end() )
     320             :     {
     321          52 :         std::pair< const OUString, ScDPSaveMember *> key( rName, pMember );
     322          52 :         maMemberHash.insert ( key );
     323             :     }
     324             :     else
     325             :     {
     326           0 :         maMemberList.remove( aExisting->second );
     327           0 :         delete aExisting->second;
     328           0 :         aExisting->second = pMember;
     329             :     }
     330          52 :     maMemberList.push_back( pMember );
     331          52 : }
     332             : 
     333           1 : void ScDPSaveDimension::SetName( const OUString& rNew )
     334             : {
     335             :     // Used only if the source dim was renamed (groups).
     336             :     // For UI renaming of dimensions, the layout name must be used.
     337             : 
     338           1 :     aName = rNew;
     339           1 : }
     340             : 
     341         141 : void ScDPSaveDimension::SetOrientation(sal_uInt16 nNew)
     342             : {
     343         141 :     nOrientation = nNew;
     344         141 : }
     345             : 
     346          19 : void ScDPSaveDimension::SetSubTotals(long nCount, const sal_uInt16* pFuncs)
     347             : {
     348          19 :     if (pSubTotalFuncs)
     349           3 :         delete [] pSubTotalFuncs;
     350          19 :     nSubTotalCount = nCount;
     351          19 :     if ( nCount && pFuncs )
     352             :     {
     353          18 :         pSubTotalFuncs = new sal_uInt16[nCount];
     354          36 :         for (long i=0; i<nCount; i++)
     355          36 :             pSubTotalFuncs[i] = pFuncs[i];
     356             :     }
     357             :     else
     358           1 :         pSubTotalFuncs = NULL;
     359             : 
     360          19 :     bSubTotalDefault = false;
     361          19 : }
     362             : 
     363           0 : bool ScDPSaveDimension::HasShowEmpty() const
     364             : {
     365           0 :     return nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW;
     366             : }
     367             : 
     368          32 : void ScDPSaveDimension::SetShowEmpty(bool bSet)
     369             : {
     370          32 :     nShowEmptyMode = bSet;
     371          32 : }
     372             : 
     373          39 : void ScDPSaveDimension::SetFunction(sal_uInt16 nNew)
     374             : {
     375          39 :     nFunction = nNew;
     376          39 : }
     377             : 
     378          60 : void ScDPSaveDimension::SetUsedHierarchy(long nNew)
     379             : {
     380          60 :     nUsedHierarchy = nNew;
     381          60 : }
     382             : 
     383           0 : void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
     384             : {
     385           0 :     mpSubtotalName.reset(new OUString(rName));
     386           0 : }
     387             : 
     388         275 : const OUString* ScDPSaveDimension::GetSubtotalName() const
     389             : {
     390         275 :     return mpSubtotalName.get();
     391             : }
     392             : 
     393           0 : void ScDPSaveDimension::RemoveSubtotalName()
     394             : {
     395           0 :     mpSubtotalName.reset();
     396           0 : }
     397             : 
     398           0 : bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const
     399             : {
     400           0 :     MemberList::const_iterator itr = maMemberList.begin(), itrEnd = maMemberList.end();
     401           0 :     for (; itr != itrEnd; ++itr)
     402             :     {
     403           0 :         const ScDPSaveMember* pMem = *itr;
     404           0 :         if (rName.equalsIgnoreAsciiCase(pMem->GetName()))
     405           0 :             return true;
     406             : 
     407           0 :         const OUString* pLayoutName = pMem->GetLayoutName();
     408           0 :         if (pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName))
     409           0 :             return true;
     410             :     }
     411           0 :     return false;
     412             : }
     413             : 
     414           4 : void ScDPSaveDimension::SetLayoutName(const OUString& rName)
     415             : {
     416           4 :     mpLayoutName.reset(new OUString(rName));
     417           4 : }
     418             : 
     419          55 : const OUString* ScDPSaveDimension::GetLayoutName() const
     420             : {
     421          55 :     return mpLayoutName.get();
     422             : }
     423             : 
     424           0 : void ScDPSaveDimension::RemoveLayoutName()
     425             : {
     426           0 :     mpLayoutName.reset(NULL);
     427           0 : }
     428             : 
     429          25 : void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
     430             : {
     431          25 :     delete pReferenceValue;
     432          25 :     if (pNew)
     433           6 :         pReferenceValue = new sheet::DataPilotFieldReference(*pNew);
     434             :     else
     435          19 :         pReferenceValue = NULL;
     436          25 : }
     437             : 
     438          36 : void ScDPSaveDimension::SetSortInfo(const sheet::DataPilotFieldSortInfo* pNew)
     439             : {
     440          36 :     delete pSortInfo;
     441          36 :     if (pNew)
     442          35 :         pSortInfo = new sheet::DataPilotFieldSortInfo(*pNew);
     443             :     else
     444           1 :         pSortInfo = NULL;
     445          36 : }
     446             : 
     447          36 : void ScDPSaveDimension::SetAutoShowInfo(const sheet::DataPilotFieldAutoShowInfo* pNew)
     448             : {
     449          36 :     delete pAutoShowInfo;
     450          36 :     if (pNew)
     451          35 :         pAutoShowInfo = new sheet::DataPilotFieldAutoShowInfo(*pNew);
     452             :     else
     453           1 :         pAutoShowInfo = NULL;
     454          36 : }
     455             : 
     456          36 : void ScDPSaveDimension::SetLayoutInfo(const sheet::DataPilotFieldLayoutInfo* pNew)
     457             : {
     458          36 :     delete pLayoutInfo;
     459          36 :     if (pNew)
     460          35 :         pLayoutInfo = new sheet::DataPilotFieldLayoutInfo(*pNew);
     461             :     else
     462           1 :         pLayoutInfo = NULL;
     463          36 : }
     464             : 
     465           6 : void ScDPSaveDimension::SetCurrentPage( const OUString* pPage )
     466             : {
     467             :     // We use member's visibility attribute to filter by page dimension.
     468             : 
     469             :     // pPage == NULL -> all members visible.
     470           6 :     MemberList::iterator it = maMemberList.begin(), itEnd = maMemberList.end();
     471          10 :     for (; it != itEnd; ++it)
     472             :     {
     473           4 :         ScDPSaveMember* pMem = *it;
     474           4 :         bool bVisible = !pPage || pMem->GetName() == *pPage;
     475           4 :         pMem->SetIsVisible(bVisible);
     476             :     }
     477           6 : }
     478             : 
     479          29 : ScDPSaveMember* ScDPSaveDimension::GetExistingMemberByName(const OUString& rName)
     480             : {
     481          29 :     MemberHash::const_iterator res = maMemberHash.find (rName);
     482          29 :     if (res != maMemberHash.end())
     483          14 :         return res->second;
     484          15 :     return NULL;
     485             : }
     486             : 
     487           8 : ScDPSaveMember* ScDPSaveDimension::GetMemberByName(const OUString& rName)
     488             : {
     489           8 :     MemberHash::const_iterator res = maMemberHash.find (rName);
     490           8 :     if (res != maMemberHash.end())
     491           6 :         return res->second;
     492             : 
     493           2 :     ScDPSaveMember* pNew = new ScDPSaveMember( rName );
     494           2 :     maMemberHash[rName] = pNew;
     495           2 :     maMemberList.push_back( pNew );
     496           2 :     return pNew;
     497             : }
     498             : 
     499           0 : void ScDPSaveDimension::SetMemberPosition( const OUString& rName, sal_Int32 nNewPos )
     500             : {
     501           0 :     ScDPSaveMember* pMember = GetMemberByName( rName ); // make sure it exists and is in the hash
     502             : 
     503           0 :     maMemberList.remove( pMember );
     504             : 
     505           0 :     MemberList::iterator aIter = maMemberList.begin();
     506           0 :     for (sal_Int32 i=0; i<nNewPos && aIter != maMemberList.end(); i++)
     507           0 :         ++aIter;
     508           0 :     maMemberList.insert( aIter, pMember );
     509           0 : }
     510             : 
     511         275 : void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xDim )
     512             : {
     513         275 :     uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
     514             :     OSL_ENSURE( xDimProp.is(), "no properties at dimension" );
     515         275 :     if ( xDimProp.is() )
     516             :     {
     517             :         // exceptions are caught at ScDPSaveData::WriteToSource
     518         275 :         uno::Any aAny;
     519             : 
     520         275 :         sheet::DataPilotFieldOrientation eOrient = (sheet::DataPilotFieldOrientation)nOrientation;
     521         275 :         aAny <<= eOrient;
     522         275 :         xDimProp->setPropertyValue( OUString(SC_UNO_DP_ORIENTATION), aAny );
     523             : 
     524         275 :         sheet::GeneralFunction eFunc = (sheet::GeneralFunction)nFunction;
     525         275 :         aAny <<= eFunc;
     526         275 :         xDimProp->setPropertyValue( OUString(SC_UNO_DP_FUNCTION), aAny );
     527             : 
     528         275 :         if ( nUsedHierarchy >= 0 )
     529             :         {
     530         124 :             aAny <<= (sal_Int32)nUsedHierarchy;
     531         124 :             xDimProp->setPropertyValue( OUString(SC_UNO_DP_USEDHIERARCHY), aAny );
     532             :         }
     533             : 
     534         275 :         if ( pReferenceValue )
     535             :         {
     536           6 :             aAny <<= *pReferenceValue;
     537           6 :             xDimProp->setPropertyValue( OUString(SC_UNO_DP_REFVALUE), aAny );
     538             :         }
     539             : 
     540         275 :         if (mpLayoutName)
     541           0 :             ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_LAYOUTNAME, *mpLayoutName);
     542             : 
     543         275 :         const OUString* pSubTotalName = GetSubtotalName();
     544         275 :         if (pSubTotalName)
     545             :             // Custom subtotal name, with '?' being replaced by the visible field name later.
     546           0 :             ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_FIELD_SUBTOTALNAME, *pSubTotalName);
     547             :     }
     548             : 
     549             :     // Level loop outside of maMemberList loop
     550             :     // because SubTotals have to be set independently of known members
     551             : 
     552         275 :     long nCount = maMemberHash.size();
     553             : 
     554         275 :     long nHierCount = 0;
     555         550 :     uno::Reference<container::XIndexAccess> xHiers;
     556         550 :     uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
     557         275 :     if ( xHierSupp.is() )
     558             :     {
     559         275 :         uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
     560         275 :         xHiers = new ScNameToIndexAccess( xHiersName );
     561         275 :         nHierCount = xHiers->getCount();
     562             :     }
     563             : 
     564         275 :     bool bHasHiddenMember = false;
     565             : 
     566         550 :     for (long nHier=0; nHier<nHierCount; nHier++)
     567             :     {
     568         275 :         uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) );
     569             : 
     570         275 :         long nLevCount = 0;
     571         550 :         uno::Reference<container::XIndexAccess> xLevels;
     572         550 :         uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHierarchy, uno::UNO_QUERY );
     573         275 :         if ( xLevSupp.is() )
     574             :         {
     575         275 :             uno::Reference<container::XNameAccess> xLevelsName = xLevSupp->getLevels();
     576         275 :             xLevels = new ScNameToIndexAccess( xLevelsName );
     577         275 :             nLevCount = xLevels->getCount();
     578             :         }
     579             : 
     580         550 :         for (long nLev=0; nLev<nLevCount; nLev++)
     581             :         {
     582         275 :             uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(nLev) );
     583         550 :             uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
     584             :             OSL_ENSURE( xLevProp.is(), "no properties at level" );
     585         275 :             if ( xLevProp.is() )
     586             :             {
     587         275 :                 uno::Any aAny;
     588         275 :                 if ( !bSubTotalDefault )
     589             :                 {
     590          41 :                     if ( !pSubTotalFuncs )
     591           0 :                         nSubTotalCount = 0;
     592             : 
     593          41 :                     uno::Sequence<sheet::GeneralFunction> aSeq(nSubTotalCount);
     594          41 :                     sheet::GeneralFunction* pArray = aSeq.getArray();
     595          82 :                     for (long i=0; i<nSubTotalCount; i++)
     596          41 :                         pArray[i] = (sheet::GeneralFunction)pSubTotalFuncs[i];
     597          41 :                     aAny <<= aSeq;
     598          41 :                     xLevProp->setPropertyValue( OUString(SC_UNO_DP_SUBTOTAL), aAny );
     599             :                 }
     600         275 :                 if ( nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW )
     601             :                     lcl_SetBoolProperty( xLevProp,
     602          82 :                         OUString(SC_UNO_DP_SHOWEMPTY), (bool)nShowEmptyMode );
     603             : 
     604         275 :                 if ( pSortInfo )
     605          78 :                     ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_SORTING, *pSortInfo);
     606             : 
     607         275 :                 if ( pAutoShowInfo )
     608          82 :                     ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_AUTOSHOW, *pAutoShowInfo);
     609             : 
     610         275 :                 if ( pLayoutInfo )
     611          80 :                     ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_LAYOUT, *pLayoutInfo);
     612             : 
     613             :                 // exceptions are caught at ScDPSaveData::WriteToSource
     614             :             }
     615             : 
     616         275 :             if ( nCount > 0 )
     617             :             {
     618          56 :                 uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevel, uno::UNO_QUERY );
     619          56 :                 if ( xMembSupp.is() )
     620             :                 {
     621          56 :                     uno::Reference<container::XNameAccess> xMembers = xMembSupp->getMembers();
     622          56 :                     if ( xMembers.is() )
     623             :                     {
     624          56 :                         sal_Int32 nPosition = -1; // set position only in manual mode
     625          56 :                         if ( !pSortInfo || pSortInfo->Mode == sheet::DataPilotFieldSortMode::MANUAL )
     626          16 :                             nPosition = 0;
     627             : 
     628         299 :                         for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; ++i)
     629             :                         {
     630         243 :                             ScDPSaveMember* pMember = *i;
     631         243 :                             if (!pMember->GetIsVisible())
     632           3 :                                 bHasHiddenMember = true;
     633         243 :                             OUString aMemberName = pMember->GetName();
     634         243 :                             if ( xMembers->hasByName( aMemberName ) )
     635             :                             {
     636             :                                 uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
     637         233 :                                     xMembers->getByName( aMemberName ) );
     638         233 :                                 pMember->WriteToSource( xMemberInt, nPosition );
     639             : 
     640         233 :                                 if ( nPosition >= 0 )
     641          52 :                                     ++nPosition; // increase if initialized
     642             :                             }
     643             :                             // missing member is no error
     644         243 :                         }
     645          56 :                     }
     646          56 :                 }
     647             :             }
     648         275 :         }
     649         275 :     }
     650             : 
     651         275 :     if (xDimProp.is())
     652         550 :         ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_HAS_HIDDEN_MEMBER, bHasHiddenMember);
     653         275 : }
     654             : 
     655           0 : void ScDPSaveDimension::UpdateMemberVisibility(const boost::unordered_map<OUString, bool, OUStringHash>& rData)
     656             : {
     657             :     typedef boost::unordered_map<OUString, bool, OUStringHash> DataMap;
     658           0 :     MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
     659           0 :     for (; itrMem != itrMemEnd; ++itrMem)
     660             :     {
     661           0 :         ScDPSaveMember* pMem = *itrMem;
     662           0 :         const OUString& rMemName = pMem->GetName();
     663           0 :         DataMap::const_iterator itr = rData.find(rMemName);
     664           0 :         if (itr != rData.end())
     665           0 :             pMem->SetIsVisible(itr->second);
     666             :     }
     667           0 : }
     668             : 
     669          13 : bool ScDPSaveDimension::HasInvisibleMember() const
     670             : {
     671          13 :     MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
     672          36 :     for (; itrMem != itrMemEnd; ++itrMem)
     673             :     {
     674          23 :         const ScDPSaveMember* pMem = *itrMem;
     675          23 :         if (!pMem->GetIsVisible())
     676           0 :             return true;
     677             :     }
     678          13 :     return false;
     679             : }
     680             : 
     681         141 : void ScDPSaveDimension::RemoveObsoleteMembers(const MemberSetType& rMembers)
     682             : {
     683         141 :     maMemberHash.clear();
     684         141 :     MemberList aNew;
     685         141 :     MemberList::iterator it = maMemberList.begin(), itEnd = maMemberList.end();
     686         321 :     for (; it != itEnd; ++it)
     687             :     {
     688         180 :         ScDPSaveMember* pMem = *it;
     689         180 :         if (rMembers.count(pMem->GetName()))
     690             :         {
     691             :             // This member still exists.
     692         180 :             maMemberHash.insert(MemberHash::value_type(pMem->GetName(), pMem));
     693         180 :             aNew.push_back(pMem);
     694             :         }
     695             :         else
     696             :         {
     697             :             // This member no longer exists.
     698           0 :             delete pMem;
     699             :         }
     700             :     }
     701             : 
     702         141 :     maMemberList.swap(aNew);
     703         141 : }
     704             : 
     705          68 : ScDPSaveData::ScDPSaveData() :
     706             :     pDimensionData( NULL ),
     707             :     nColumnGrandMode( SC_DPSAVEMODE_DONTKNOW ),
     708             :     nRowGrandMode( SC_DPSAVEMODE_DONTKNOW ),
     709             :     nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
     710             :     nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
     711             :     bFilterButton( true ),
     712             :     bDrillDown( true ),
     713             :     mbDimensionMembersBuilt(false),
     714          68 :     mpGrandTotalName(NULL)
     715             : {
     716          68 : }
     717             : 
     718         163 : ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
     719             :     nColumnGrandMode( r.nColumnGrandMode ),
     720             :     nRowGrandMode( r.nRowGrandMode ),
     721             :     nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
     722             :     nRepeatEmptyMode( r.nRepeatEmptyMode ),
     723             :     bFilterButton( r.bFilterButton ),
     724             :     bDrillDown( r.bDrillDown ),
     725             :     mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
     726             :     mpGrandTotalName(NULL),
     727         163 :     mpDimOrder(NULL)
     728             : {
     729         163 :     if ( r.pDimensionData )
     730           8 :         pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData );
     731             :     else
     732         155 :         pDimensionData = NULL;
     733             : 
     734         163 :     aDimList = r.aDimList.clone();
     735             : 
     736         163 :     if (r.mpGrandTotalName)
     737           0 :         mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
     738         163 : }
     739             : 
     740           0 : ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
     741             : {
     742           0 :     if ( &r != this )
     743             :     {
     744           0 :         this->~ScDPSaveData();
     745           0 :         new( this ) ScDPSaveData ( r );
     746             :     }
     747           0 :     return *this;
     748             : }
     749             : 
     750           0 : bool ScDPSaveData::operator== ( const ScDPSaveData& r ) const
     751             : {
     752           0 :     if ( nColumnGrandMode != r.nColumnGrandMode ||
     753           0 :          nRowGrandMode    != r.nRowGrandMode    ||
     754           0 :          nIgnoreEmptyMode != r.nIgnoreEmptyMode ||
     755           0 :          nRepeatEmptyMode != r.nRepeatEmptyMode ||
     756           0 :          bFilterButton    != r.bFilterButton    ||
     757           0 :          bDrillDown       != r.bDrillDown       ||
     758           0 :          mbDimensionMembersBuilt != r.mbDimensionMembersBuilt)
     759           0 :         return false;
     760             : 
     761           0 :     if ( pDimensionData || r.pDimensionData )
     762           0 :         if ( !pDimensionData || !r.pDimensionData || !( *pDimensionData == *r.pDimensionData ) )
     763           0 :             return false;
     764             : 
     765           0 :     if ( aDimList.size() != r.aDimList.size() )
     766           0 :         return false;
     767             : 
     768           0 :     if (aDimList != r.aDimList)
     769           0 :         return false;
     770             : 
     771           0 :     if (mpGrandTotalName)
     772             :     {
     773           0 :         if (!r.mpGrandTotalName)
     774           0 :             return false;
     775           0 :         if (!mpGrandTotalName->equals(*r.mpGrandTotalName))
     776           0 :             return false;
     777             :     }
     778           0 :     else if (r.mpGrandTotalName)
     779           0 :         return false;
     780             : 
     781           0 :     return true;
     782             : }
     783             : 
     784         414 : ScDPSaveData::~ScDPSaveData()
     785             : {
     786         207 :     delete pDimensionData;
     787         207 : }
     788             : 
     789           0 : void ScDPSaveData::SetGrandTotalName(const OUString& rName)
     790             : {
     791           0 :     mpGrandTotalName.reset(new OUString(rName));
     792           0 : }
     793             : 
     794         110 : const OUString* ScDPSaveData::GetGrandTotalName() const
     795             : {
     796         110 :     return mpGrandTotalName.get();
     797             : }
     798             : 
     799          58 : const ScDPSaveData::DimsType& ScDPSaveData::GetDimensions() const
     800             : {
     801          58 :     return aDimList;
     802             : }
     803             : 
     804             : namespace {
     805             : 
     806             : class DimOrderInserter : std::unary_function<const ScDPSaveDimension*, void>
     807             : {
     808             :     ScDPSaveData::DimOrderType& mrNames;
     809             : public:
     810           0 :     DimOrderInserter(ScDPSaveData::DimOrderType& rNames) : mrNames(rNames) {}
     811             : 
     812           0 :     void operator() (const ScDPSaveDimension* pDim)
     813             :     {
     814           0 :         size_t nRank = mrNames.size();
     815             :         mrNames.insert(
     816           0 :             ScDPSaveData::DimOrderType::value_type(pDim->GetName(), nRank));
     817           0 :     }
     818             : };
     819             : 
     820             : }
     821             : 
     822           0 : const ScDPSaveData::DimOrderType& ScDPSaveData::GetDimensionSortOrder() const
     823             : {
     824           0 :     if (!mpDimOrder)
     825             :     {
     826           0 :         mpDimOrder.reset(new DimOrderType);
     827           0 :         std::vector<const ScDPSaveDimension*> aRowDims, aColDims;
     828           0 :         GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aRowDims);
     829           0 :         GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aColDims);
     830             : 
     831           0 :         std::for_each(aRowDims.begin(), aRowDims.end(), DimOrderInserter(*mpDimOrder));
     832           0 :         std::for_each(aColDims.begin(), aColDims.end(), DimOrderInserter(*mpDimOrder));
     833             :     }
     834           0 :     return *mpDimOrder;
     835             : }
     836             : 
     837          16 : void ScDPSaveData::GetAllDimensionsByOrientation(
     838             :     sheet::DataPilotFieldOrientation eOrientation, std::vector<const ScDPSaveDimension*>& rDims) const
     839             : {
     840          16 :     std::vector<const ScDPSaveDimension*> aDims;
     841          16 :     DimsType::const_iterator it = aDimList.begin(), itEnd = aDimList.end();
     842         105 :     for (; it != itEnd; ++it)
     843             :     {
     844          89 :         const ScDPSaveDimension& rDim = *it;
     845          89 :         if (rDim.GetOrientation() != static_cast<sal_uInt16>(eOrientation))
     846          66 :             continue;
     847             : 
     848          23 :         aDims.push_back(&rDim);
     849             :     }
     850             : 
     851          16 :     rDims.swap(aDims);
     852          16 : }
     853             : 
     854          20 : void ScDPSaveData::AddDimension(ScDPSaveDimension* pDim)
     855             : {
     856          20 :     if (!pDim)
     857          20 :         return;
     858             : 
     859          20 :     CheckDuplicateName(*pDim);
     860          20 :     aDimList.push_back(pDim);
     861             : 
     862          20 :     DimensionsChanged();
     863             : }
     864             : 
     865         266 : ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const OUString& rName)
     866             : {
     867         266 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     868         527 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     869             :     {
     870         470 :         if (iter->GetName() == rName && !iter->IsDataLayout() )
     871         209 :             return const_cast<ScDPSaveDimension*>(&(*iter));
     872             :     }
     873             : 
     874          57 :     return AppendNewDimension(rName, false);
     875             : }
     876             : 
     877          18 : ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const OUString& rName) const
     878             : {
     879          18 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     880          58 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     881             :     {
     882          41 :         if (iter->GetName() == rName && !iter->IsDataLayout() )
     883           1 :             return const_cast<ScDPSaveDimension*>(&(*iter));
     884             :     }
     885          17 :     return NULL; // don't create new
     886             : }
     887             : 
     888          41 : ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const OUString& rName)
     889             : {
     890          41 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     891          77 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     892             :     {
     893          37 :         if (iter->GetName() == rName && !iter->IsDataLayout() )
     894           1 :             return DuplicateDimension(rName);
     895             :     }
     896             : 
     897          40 :     return AppendNewDimension(rName, false);
     898             : }
     899             : 
     900          19 : ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
     901             : {
     902          19 :     ScDPSaveDimension* pDim = GetExistingDataLayoutDimension();
     903          19 :     if (pDim)
     904           1 :         return pDim;
     905             : 
     906          18 :     return AppendNewDimension(OUString(), true);
     907             : }
     908             : 
     909          20 : ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const
     910             : {
     911          20 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     912          80 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     913             :     {
     914          62 :         if ( iter->IsDataLayout() )
     915           2 :             return const_cast<ScDPSaveDimension*>(&(*iter));
     916             :     }
     917          18 :     return NULL;
     918             : }
     919             : 
     920           1 : ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const OUString& rName)
     921             : {
     922             :     // always insert new
     923             : 
     924           1 :     ScDPSaveDimension* pOld = GetExistingDimensionByName(rName);
     925           1 :     if (!pOld)
     926           0 :         return NULL;
     927             : 
     928           1 :     ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld );
     929           1 :     AddDimension(pNew);
     930           1 :     return pNew;
     931             : }
     932             : 
     933           2 : void ScDPSaveData::RemoveDimensionByName(const OUString& rName)
     934             : {
     935           2 :     boost::ptr_vector<ScDPSaveDimension>::iterator iter;
     936           3 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     937             :     {
     938           3 :         if (iter->GetName() != rName || iter->IsDataLayout())
     939           1 :             continue;
     940             : 
     941           2 :         aDimList.erase(iter);
     942           2 :         RemoveDuplicateNameCount(rName);
     943           2 :         DimensionsChanged();
     944           4 :         return;
     945             :     }
     946             : }
     947             : 
     948           0 : ScDPSaveDimension& ScDPSaveData::DuplicateDimension( const ScDPSaveDimension& rDim )
     949             : {
     950           0 :     ScDPSaveDimension* pNew = new ScDPSaveDimension( rDim );
     951           0 :     AddDimension(pNew);
     952           0 :     return *pNew;
     953             : }
     954             : 
     955           0 : ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(sal_uInt16 nOrientation)
     956             : {
     957             :     // return the innermost dimension for the given orientation,
     958             :     // excluding data layout dimension
     959             : 
     960           0 :     boost::ptr_vector<ScDPSaveDimension>::const_reverse_iterator iter;
     961           0 :     for (iter = aDimList.rbegin(); iter != aDimList.rend(); ++iter)
     962             :     {
     963           0 :         if (iter->GetOrientation() == nOrientation && !iter->IsDataLayout())
     964           0 :             return const_cast<ScDPSaveDimension*>(&(*iter));
     965             :     }
     966             : 
     967           0 :     return NULL;
     968             : }
     969             : 
     970           0 : ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
     971             : {
     972           0 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     973           0 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     974             :     {
     975           0 :         if (iter->GetOrientation() == eOrientation && !iter->IsDataLayout())
     976           0 :             return const_cast<ScDPSaveDimension*>(&(*iter));
     977             :     }
     978           0 :     return NULL;
     979             : }
     980             : 
     981           0 : long ScDPSaveData::GetDataDimensionCount() const
     982             : {
     983           0 :     long nDataCount = 0;
     984             : 
     985           0 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     986           0 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     987             :     {
     988           0 :         if (iter->GetOrientation() == sheet::DataPilotFieldOrientation_DATA)
     989           0 :             ++nDataCount;
     990             :     }
     991             : 
     992           0 :     return nDataCount;
     993             : }
     994             : 
     995          64 : void ScDPSaveData::SetPosition( ScDPSaveDimension* pDim, long nNew )
     996             : {
     997             :     // position (nNew) is counted within dimensions of the same orientation
     998             : 
     999          64 :     sal_uInt16 nOrient = pDim->GetOrientation();
    1000             : 
    1001          64 :     boost::ptr_vector<ScDPSaveDimension>::iterator it;
    1002         177 :     for ( it = aDimList.begin(); it != aDimList.end(); ++it)
    1003             :     {
    1004         177 :         if (pDim == &(*it))
    1005             :         {
    1006             :             // Tell ptr_vector to give up ownership of this element.  Don't
    1007             :             // delete this instance as it is re-inserted into the container
    1008             :             // later.
    1009          64 :             aDimList.release(it).release();
    1010          64 :             break;
    1011             :         }
    1012             :     }
    1013             : 
    1014          64 :     boost::ptr_vector<ScDPSaveDimension>::iterator iterInsert = aDimList.begin();
    1015         217 :     while ( nNew > 0 && iterInsert != aDimList.end())
    1016             :     {
    1017          89 :         if (iterInsert->GetOrientation() == nOrient )
    1018           2 :             --nNew;
    1019             : 
    1020          89 :         ++iterInsert;
    1021             :     }
    1022             : 
    1023          64 :     aDimList.insert(iterInsert,pDim);
    1024          64 :     DimensionsChanged();
    1025          64 : }
    1026             : 
    1027          37 : void ScDPSaveData::SetColumnGrand(bool bSet)
    1028             : {
    1029          37 :     nColumnGrandMode = bSet;
    1030          37 : }
    1031             : 
    1032          37 : void ScDPSaveData::SetRowGrand(bool bSet)
    1033             : {
    1034          37 :     nRowGrandMode = bSet;
    1035          37 : }
    1036             : 
    1037          38 : void ScDPSaveData::SetIgnoreEmptyRows(bool bSet)
    1038             : {
    1039          38 :     nIgnoreEmptyMode = bSet;
    1040          38 : }
    1041             : 
    1042          37 : void ScDPSaveData::SetRepeatIfEmpty(bool bSet)
    1043             : {
    1044          37 :     nRepeatEmptyMode = bSet;
    1045          37 : }
    1046             : 
    1047          20 : void ScDPSaveData::SetFilterButton(bool bSet)
    1048             : {
    1049          20 :     bFilterButton = bSet;
    1050          20 : }
    1051             : 
    1052          20 : void ScDPSaveData::SetDrillDown(bool bSet)
    1053             : {
    1054          20 :     bDrillDown = bSet;
    1055          20 : }
    1056             : 
    1057         110 : static void lcl_ResetOrient( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
    1058             : {
    1059         110 :     sheet::DataPilotFieldOrientation eOrient = sheet::DataPilotFieldOrientation_HIDDEN;
    1060             : 
    1061         110 :     uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
    1062         220 :     uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
    1063         110 :     long nIntCount = xIntDims->getCount();
    1064         615 :     for (long nIntDim=0; nIntDim<nIntCount; nIntDim++)
    1065             :     {
    1066         505 :         uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
    1067        1010 :         uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
    1068         505 :         if (xDimProp.is())
    1069             :         {
    1070         505 :             uno::Any aAny;
    1071         505 :             aAny <<= eOrient;
    1072         505 :             xDimProp->setPropertyValue( OUString(SC_UNO_DP_ORIENTATION), aAny );
    1073             :         }
    1074         615 :     }
    1075         110 : }
    1076             : 
    1077         110 : void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
    1078             : {
    1079         110 :     if (!xSource.is())
    1080         110 :         return;
    1081             : 
    1082             :     // source options must be first!
    1083             : 
    1084         110 :     uno::Reference<beans::XPropertySet> xSourceProp( xSource, uno::UNO_QUERY );
    1085             :     OSL_ENSURE( xSourceProp.is(), "no properties at source" );
    1086         110 :     if ( xSourceProp.is() )
    1087             :     {
    1088             :         // source options are not available for external sources
    1089             :         //! use XPropertySetInfo to test for availability?
    1090             : 
    1091             :         try
    1092             :         {
    1093         110 :             if ( nIgnoreEmptyMode != SC_DPSAVEMODE_DONTKNOW )
    1094             :                 lcl_SetBoolProperty( xSourceProp,
    1095         110 :                     OUString(SC_UNO_DP_IGNOREEMPTY), (bool)nIgnoreEmptyMode );
    1096         110 :             if ( nRepeatEmptyMode != SC_DPSAVEMODE_DONTKNOW )
    1097             :                 lcl_SetBoolProperty( xSourceProp,
    1098         110 :                     OUString(SC_UNO_DP_REPEATEMPTY), (bool)nRepeatEmptyMode );
    1099             :         }
    1100           0 :         catch(uno::Exception&)
    1101             :         {
    1102             :             // no error
    1103             :         }
    1104             : 
    1105         110 :         const OUString* pGrandTotalName = GetGrandTotalName();
    1106         110 :         if (pGrandTotalName)
    1107           0 :             ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_DP_GRANDTOTAL_NAME, *pGrandTotalName);
    1108             :     }
    1109             : 
    1110             :     // exceptions in the other calls are errors
    1111             :     try
    1112             :     {
    1113             :         // reset all orientations
    1114             :         //! "forgetSettings" or similar at source ?????
    1115             :         //! reset all duplicated dimensions, or reuse them below !!!
    1116             :         OSL_FAIL( "ScDPSaveData::WriteToSource" );
    1117             : 
    1118         110 :         lcl_ResetOrient( xSource );
    1119             : 
    1120         110 :         uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
    1121         220 :         uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
    1122         110 :         long nIntCount = xIntDims->getCount();
    1123             : 
    1124         110 :         boost::ptr_vector<ScDPSaveDimension>::iterator iter = aDimList.begin();
    1125         386 :         for (long i = 0; iter != aDimList.end(); ++iter, ++i)
    1126             :         {
    1127         276 :             OUString aName = iter->GetName();
    1128         552 :             OUString aCoreName = ScDPUtil::getSourceDimensionName(aName);
    1129             : 
    1130             :             OSL_TRACE( "%s", aName.getStr() );
    1131             : 
    1132         276 :             bool bData = iter->IsDataLayout();
    1133             : 
    1134             :             //! getByName for ScDPSource, including DataLayoutDimension !!!!!!!!
    1135             : 
    1136         276 :             bool bFound = false;
    1137        1039 :             for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
    1138             :             {
    1139         763 :                 uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
    1140         763 :                 if ( bData )
    1141             :                 {
    1142         183 :                     uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
    1143         183 :                     if ( xDimProp.is() )
    1144             :                     {
    1145             :                         bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
    1146         183 :                                     OUString(SC_UNO_DP_ISDATALAYOUT) );
    1147             :                         //! error checking -- is "IsDataLayoutDimension" property required??
    1148         183 :                     }
    1149             :                 }
    1150             :                 else
    1151             :                 {
    1152         580 :                     uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
    1153         580 :                     if (xDimName.is() && xDimName->getName() == aCoreName)
    1154         233 :                         bFound = true;
    1155             :                 }
    1156             : 
    1157         763 :                 if (bFound)
    1158             :                 {
    1159         275 :                     if (iter->GetDupFlag())
    1160             :                     {
    1161           2 :                         uno::Reference<util::XCloneable> xCloneable(xIntDim, uno::UNO_QUERY);
    1162             :                         OSL_ENSURE(xCloneable.is(), "cannot clone dimension");
    1163           2 :                         if (xCloneable.is())
    1164             :                         {
    1165           2 :                             uno::Reference<util::XCloneable> xNew = xCloneable->createClone();
    1166           4 :                             uno::Reference<container::XNamed> xNewName(xNew, uno::UNO_QUERY);
    1167           2 :                             if (xNewName.is())
    1168             :                             {
    1169           2 :                                 xNewName->setName(aName);
    1170           2 :                                 iter->WriteToSource(xNew);
    1171           2 :                             }
    1172           2 :                         }
    1173             :                     }
    1174             :                     else
    1175         273 :                         iter->WriteToSource( xIntDim );
    1176             :                 }
    1177         763 :             }
    1178             :             OSL_ENSURE(bFound, "WriteToSource: Dimension not found");
    1179         276 :         }
    1180             : 
    1181         110 :         if ( xSourceProp.is() )
    1182             :         {
    1183         110 :             if ( nColumnGrandMode != SC_DPSAVEMODE_DONTKNOW )
    1184             :                 lcl_SetBoolProperty( xSourceProp,
    1185         110 :                     OUString(SC_UNO_DP_COLGRAND), (bool)nColumnGrandMode );
    1186         110 :             if ( nRowGrandMode != SC_DPSAVEMODE_DONTKNOW )
    1187             :                 lcl_SetBoolProperty( xSourceProp,
    1188         110 :                     OUString(SC_UNO_DP_ROWGRAND), (bool)nRowGrandMode );
    1189         110 :         }
    1190             :     }
    1191           0 :     catch(uno::Exception&)
    1192             :     {
    1193             :         OSL_FAIL("exception in WriteToSource");
    1194         110 :     }
    1195             : }
    1196             : 
    1197           0 : bool ScDPSaveData::IsEmpty() const
    1198             : {
    1199           0 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
    1200           0 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
    1201             :     {
    1202           0 :         if (iter->GetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN && !iter->IsDataLayout())
    1203           0 :             return false;
    1204             :     }
    1205           0 :     return true; // no entries that are not hidden
    1206             : }
    1207             : 
    1208           1 : void ScDPSaveData::RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames )
    1209             : {
    1210           1 :     if (!pDimensionData)
    1211             :         // No group dimensions exist.  Nothing to do.
    1212           1 :         return;
    1213             : 
    1214             :     // Remove numeric group dimension (exists once at most). No need to delete
    1215             :     // anything in save data (grouping was done inplace in an existing base
    1216             :     // dimension).
    1217           1 :     pDimensionData->RemoveNumGroupDimension(rSrcDimName);
    1218             : 
    1219             :     // Remove named group dimension(s). Dimensions have to be removed from
    1220             :     // dimension save data and from save data too.
    1221           1 :     const ScDPSaveGroupDimension* pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
    1222           4 :     while ( pExistingGroup )
    1223             :     {
    1224           2 :         OUString aGroupDimName = pExistingGroup->GetGroupDimName();
    1225           2 :         pDimensionData->RemoveGroupDimension(aGroupDimName);     // pExistingGroup is deleted
    1226             : 
    1227             :         // also remove SaveData settings for the dimension that no longer exists
    1228           2 :         RemoveDimensionByName(aGroupDimName);
    1229             : 
    1230           2 :         if (pDeletedNames)
    1231           0 :             pDeletedNames->push_back(aGroupDimName);
    1232             : 
    1233             :         // see if there are more group dimensions
    1234           2 :         pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
    1235             : 
    1236           2 :         if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
    1237             :         {
    1238             :             // still get the same group dimension?
    1239             :             OSL_FAIL("couldn't remove group dimension");
    1240           0 :             pExistingGroup = NULL;      // avoid endless loop
    1241             :         }
    1242           2 :     }
    1243             : }
    1244             : 
    1245           8 : ScDPDimensionSaveData* ScDPSaveData::GetDimensionData()
    1246             : {
    1247           8 :     if (!pDimensionData)
    1248           7 :         pDimensionData = new ScDPDimensionSaveData;
    1249           8 :     return pDimensionData;
    1250             : }
    1251             : 
    1252           0 : void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData* pNew )
    1253             : {
    1254           0 :     delete pDimensionData;
    1255           0 :     if ( pNew )
    1256           0 :         pDimensionData = new ScDPDimensionSaveData( *pNew );
    1257             :     else
    1258           0 :         pDimensionData = NULL;
    1259           0 : }
    1260             : 
    1261           1 : void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
    1262             : {
    1263           1 :     if (mbDimensionMembersBuilt)
    1264           1 :         return;
    1265             : 
    1266             :     // First, build a dimension name-to-index map.
    1267             :     typedef boost::unordered_map<OUString, long, OUStringHash> NameIndexMap;
    1268           1 :     NameIndexMap aMap;
    1269           1 :     long nColCount = pData->GetColumnCount();
    1270           6 :     for (long i = 0; i < nColCount; ++i)
    1271           5 :         aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i));
    1272             : 
    1273           1 :     NameIndexMap::const_iterator itrEnd = aMap.end();
    1274             : 
    1275           1 :     boost::ptr_vector<ScDPSaveDimension>::iterator iter;
    1276           7 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
    1277             :     {
    1278           6 :         const OUString& rDimName = iter->GetName();
    1279           6 :         if (rDimName.isEmpty())
    1280             :             // empty dimension name. It must be data layout.
    1281           2 :             continue;
    1282             : 
    1283           5 :         NameIndexMap::const_iterator itr = aMap.find(rDimName);
    1284           5 :         if (itr == itrEnd)
    1285             :             // dimension name not in the data. This should never happen!
    1286           0 :             continue;
    1287             : 
    1288           5 :         long nDimIndex = itr->second;
    1289           5 :         const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
    1290           5 :         size_t mMemberCount = rMembers.size();
    1291          19 :         for (size_t j = 0; j < mMemberCount; ++j)
    1292             :         {
    1293          14 :             const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] );
    1294          14 :             OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData);
    1295          14 :             if (iter->GetExistingMemberByName(aMemName))
    1296             :                 // this member instance already exists. nothing to do.
    1297           0 :                 continue;
    1298             : 
    1299          28 :             auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName));
    1300          14 :             pNewMember->SetIsVisible(true);
    1301          14 :             iter->AddMember(pNewMember.release());
    1302          14 :         }
    1303             :     }
    1304             : 
    1305           1 :     mbDimensionMembersBuilt = true;
    1306             : }
    1307             : 
    1308          47 : void ScDPSaveData::SyncAllDimensionMembers(ScDPTableData* pData)
    1309             : {
    1310             :     typedef boost::unordered_map<OUString, long, OUStringHash> NameIndexMap;
    1311             : 
    1312             :     // First, build a dimension name-to-index map.
    1313          47 :     NameIndexMap aMap;
    1314          47 :     long nColCount = pData->GetColumnCount();
    1315         279 :     for (long i = 0; i < nColCount; ++i)
    1316         232 :         aMap.insert(NameIndexMap::value_type(pData->getDimensionName(i), i));
    1317             : 
    1318          47 :     NameIndexMap::const_iterator itMapEnd = aMap.end();
    1319             : 
    1320          47 :     DimsType::iterator it = aDimList.begin(), itEnd = aDimList.end();
    1321         199 :     for (it = aDimList.begin(); it != itEnd; ++it)
    1322             :     {
    1323         152 :         const OUString& rDimName = it->GetName();
    1324         152 :         if (rDimName.isEmpty())
    1325             :             // empty dimension name. It must be data layout.
    1326          21 :             continue;
    1327             : 
    1328         142 :         NameIndexMap::const_iterator itMap = aMap.find(rDimName);
    1329         142 :         if (itMap == itMapEnd)
    1330             :             // dimension name not in the data. This should never happen!
    1331           1 :             continue;
    1332             : 
    1333         141 :         ScDPSaveDimension::MemberSetType aMemNames;
    1334         141 :         long nDimIndex = itMap->second;
    1335         141 :         const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
    1336         141 :         size_t nMemberCount = rMembers.size();
    1337         812 :         for (size_t j = 0; j < nMemberCount; ++j)
    1338             :         {
    1339         671 :             const ScDPItemData* pMemberData = pData->GetMemberById(nDimIndex, rMembers[j]);
    1340         671 :             OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData);
    1341         671 :             aMemNames.insert(aMemName);
    1342         671 :         }
    1343             : 
    1344         141 :         it->RemoveObsoleteMembers(aMemNames);
    1345         188 :     }
    1346          47 : }
    1347             : 
    1348           0 : bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
    1349             : {
    1350           0 :     ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName);
    1351           0 :     if (!pDim)
    1352           0 :         return false;
    1353             : 
    1354           0 :     return pDim->HasInvisibleMember();
    1355             : }
    1356             : 
    1357          20 : void ScDPSaveData::CheckDuplicateName(ScDPSaveDimension& rDim)
    1358             : {
    1359          20 :     const OUString aName = ScDPUtil::getSourceDimensionName(rDim.GetName());
    1360          20 :     DupNameCountType::iterator it = maDupNameCounts.find(aName);
    1361          20 :     if (it != maDupNameCounts.end())
    1362             :     {
    1363           1 :         rDim.SetName(ScDPUtil::createDuplicateDimensionName(aName, ++it->second));
    1364           1 :         rDim.SetDupFlag(true);
    1365             :     }
    1366             :     else
    1367             :         // New name.
    1368          19 :         maDupNameCounts.insert(DupNameCountType::value_type(aName, 0));
    1369          20 : }
    1370             : 
    1371           2 : void ScDPSaveData::RemoveDuplicateNameCount(const OUString& rName)
    1372             : {
    1373           2 :     OUString aCoreName = rName;
    1374           2 :     if (ScDPUtil::isDuplicateDimension(rName))
    1375           0 :         aCoreName = ScDPUtil::getSourceDimensionName(rName);
    1376             : 
    1377           2 :     DupNameCountType::iterator it = maDupNameCounts.find(aCoreName);
    1378           2 :     if (it == maDupNameCounts.end())
    1379           0 :         return;
    1380             : 
    1381           2 :     if (!it->second)
    1382             :     {
    1383           2 :         maDupNameCounts.erase(it);
    1384           2 :         return;
    1385             :     }
    1386             : 
    1387           0 :     --it->second;
    1388           0 :     return;
    1389             : }
    1390             : 
    1391         115 : ScDPSaveDimension* ScDPSaveData::AppendNewDimension(const OUString& rName, bool bDataLayout)
    1392             : {
    1393         115 :     if (ScDPUtil::isDuplicateDimension(rName))
    1394             :         // This call is for original dimensions only.
    1395           0 :         return NULL;
    1396             : 
    1397         115 :     ScDPSaveDimension* pNew = new ScDPSaveDimension(rName, bDataLayout);
    1398         115 :     aDimList.push_back(pNew);
    1399         115 :     if (!maDupNameCounts.count(rName))
    1400         115 :         maDupNameCounts.insert(DupNameCountType::value_type(rName, 0));
    1401             : 
    1402         115 :     DimensionsChanged();
    1403         115 :     return pNew;
    1404             : }
    1405             : 
    1406         201 : void ScDPSaveData::DimensionsChanged()
    1407             : {
    1408         201 :     mpDimOrder.reset();
    1409         201 : }
    1410             : 
    1411           0 : bool operator == (const ::com::sun::star::sheet::DataPilotFieldSortInfo &l, const ::com::sun::star::sheet::DataPilotFieldSortInfo &r )
    1412             : {
    1413           0 :     return l.Field == r.Field && l.IsAscending == r.IsAscending && l.Mode == r.Mode;
    1414             : }
    1415           0 : bool operator == (const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &l, const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &r )
    1416             : {
    1417           0 :     return l.IsEnabled == r.IsEnabled &&
    1418           0 :         l.ShowItemsMode == r.ShowItemsMode &&
    1419           0 :         l.ItemCount == r.ItemCount &&
    1420           0 :         l.DataField == r.DataField;
    1421             : }
    1422           0 : bool operator == (const ::com::sun::star::sheet::DataPilotFieldReference &l, const ::com::sun::star::sheet::DataPilotFieldReference &r )
    1423             : {
    1424           0 :     return l.ReferenceType == r.ReferenceType &&
    1425           0 :         l.ReferenceField == r.ReferenceField &&
    1426           0 :         l.ReferenceItemType == r.ReferenceItemType &&
    1427           0 :         l.ReferenceItemName == r.ReferenceItemName;
    1428          93 : }
    1429             : 
    1430             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10