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

Generated by: LCOV version 1.10