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: 508 707 71.9 %
Date: 2012-12-17 Functions: 61 90 67.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #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        1384 : 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        1384 :     xProp->setPropertyValue( rName, uno::Any( &bValue, getBooleanCppuType() ) );
      71        1384 : }
      72             : 
      73         106 : ScDPSaveMember::ScDPSaveMember(const ::rtl::OUString& rName) :
      74             :     aName( rName ),
      75             :     mpLayoutName(NULL),
      76             :     nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
      77         106 :     nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
      78             : {
      79         106 : }
      80             : 
      81        1200 : ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) :
      82             :     aName( r.aName ),
      83             :     mpLayoutName(NULL),
      84             :     nVisibleMode( r.nVisibleMode ),
      85        1200 :     nShowDetailsMode( r.nShowDetailsMode )
      86             : {
      87        1200 :     if (r.mpLayoutName)
      88           0 :         mpLayoutName.reset(new OUString(*r.mpLayoutName));
      89        1200 : }
      90             : 
      91        1230 : ScDPSaveMember::~ScDPSaveMember()
      92             : {
      93        1230 : }
      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         114 : void ScDPSaveMember::SetIsVisible(bool bSet)
     111             : {
     112         114 :     nVisibleMode = bSet;
     113         114 : }
     114             : 
     115           0 : bool ScDPSaveMember::HasShowDetails() const
     116             : {
     117           0 :     return nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW;
     118             : }
     119             : 
     120          76 : void ScDPSaveMember::SetShowDetails(bool bSet)
     121             : {
     122          76 :     nShowDetailsMode = bSet;
     123          76 : }
     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         466 : void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
     149             : {
     150         466 :     uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
     151             :     OSL_ENSURE( xMembProp.is(), "no properties at member" );
     152         466 :     if ( xMembProp.is() )
     153             :     {
     154             :         // exceptions are caught at ScDPSaveData::WriteToSource
     155             : 
     156         466 :         if ( nVisibleMode != SC_DPSAVEMODE_DONTKNOW )
     157             :             lcl_SetBoolProperty( xMembProp,
     158         466 :                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISVISIBLE)), (bool)nVisibleMode );
     159             : 
     160         466 :         if ( nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW )
     161             :             lcl_SetBoolProperty( xMembProp,
     162         400 :                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_SHOWDETAILS)), (bool)nShowDetailsMode );
     163             : 
     164         466 :         if (mpLayoutName)
     165           0 :             ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_DP_LAYOUTNAME, *mpLayoutName);
     166             : 
     167         466 :         if ( nPosition >= 0 )
     168         104 :             ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_DP_POSITION, nPosition);
     169         466 :     }
     170         466 : }
     171             : 
     172         156 : 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         156 :     pLayoutInfo( NULL )
     189             : {
     190         156 : }
     191             : 
     192         550 : 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         550 :     pSubTotalFuncs( NULL )
     205             : {
     206         550 :     if ( nSubTotalCount && r.pSubTotalFuncs )
     207             :     {
     208         100 :         pSubTotalFuncs = new sal_uInt16[nSubTotalCount];
     209         200 :         for (long nSub=0; nSub<nSubTotalCount; nSub++)
     210         100 :             pSubTotalFuncs[nSub] = r.pSubTotalFuncs[nSub];
     211             :     }
     212             : 
     213        1750 :     for (MemberList::const_iterator i=r.maMemberList.begin(); i != r.maMemberList.end() ; ++i)
     214             :     {
     215        1200 :         const ::rtl::OUString& rName =  (*i)->GetName();
     216        1200 :         ScDPSaveMember* pNew = new ScDPSaveMember( **i );
     217        1200 :         maMemberHash[rName] = pNew;
     218        1200 :         maMemberList.push_back( pNew );
     219             :     }
     220         550 :     if (r.pReferenceValue)
     221           6 :         pReferenceValue = new sheet::DataPilotFieldReference( *(r.pReferenceValue) );
     222             :     else
     223         544 :         pReferenceValue = NULL;
     224         550 :     if (r.pSortInfo)
     225         248 :         pSortInfo = new sheet::DataPilotFieldSortInfo( *(r.pSortInfo) );
     226             :     else
     227         302 :         pSortInfo = NULL;
     228         550 :     if (r.pAutoShowInfo)
     229         272 :         pAutoShowInfo = new sheet::DataPilotFieldAutoShowInfo( *(r.pAutoShowInfo) );
     230             :     else
     231         278 :         pAutoShowInfo = NULL;
     232         550 :     if (r.pLayoutInfo)
     233         260 :         pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) );
     234             :     else
     235         290 :         pLayoutInfo = NULL;
     236         550 :     if (r.mpLayoutName)
     237           0 :         mpLayoutName.reset(new OUString(*r.mpLayoutName));
     238         550 :     if (r.mpSubtotalName)
     239           0 :         mpSubtotalName.reset(new OUString(*r.mpSubtotalName));
     240         550 : }
     241             : 
     242        1336 : ScDPSaveDimension::~ScDPSaveDimension()
     243             : {
     244        1898 :     for (MemberHash::const_iterator i=maMemberHash.begin(); i != maMemberHash.end() ; ++i)
     245        1230 :         delete i->second;
     246         668 :     delete pReferenceValue;
     247         668 :     delete pSortInfo;
     248         668 :     delete pAutoShowInfo;
     249         668 :     delete pLayoutInfo;
     250         668 :     delete [] pSubTotalFuncs;
     251         668 : }
     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         104 : void ScDPSaveDimension::AddMember(ScDPSaveMember* pMember)
     321             : {
     322         104 :     const ::rtl::OUString & rName = pMember->GetName();
     323         104 :     MemberHash::iterator aExisting = maMemberHash.find( rName );
     324         104 :     if ( aExisting == maMemberHash.end() )
     325             :     {
     326         104 :         std::pair< const ::rtl::OUString, ScDPSaveMember *> key( rName, pMember );
     327         104 :         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         104 :     maMemberList.push_back( pMember );
     336         104 : }
     337             : 
     338           2 : 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           2 :     aName = rNew;
     344           2 : }
     345             : 
     346         160 : void ScDPSaveDimension::SetOrientation(sal_uInt16 nNew)
     347             : {
     348         160 :     nOrientation = nNew;
     349         160 : }
     350             : 
     351           6 : void ScDPSaveDimension::SetSubTotals(long nCount, const sal_uInt16* pFuncs)
     352             : {
     353           6 :     if (pSubTotalFuncs)
     354           0 :         delete [] pSubTotalFuncs;
     355           6 :     nSubTotalCount = nCount;
     356           6 :     if ( nCount && pFuncs )
     357             :     {
     358           6 :         pSubTotalFuncs = new sal_uInt16[nCount];
     359          12 :         for (long i=0; i<nCount; i++)
     360          12 :             pSubTotalFuncs[i] = pFuncs[i];
     361             :     }
     362             :     else
     363           0 :         pSubTotalFuncs = NULL;
     364             : 
     365           6 :     bSubTotalDefault = false;
     366           6 : }
     367             : 
     368           0 : bool ScDPSaveDimension::HasShowEmpty() const
     369             : {
     370           0 :     return nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW;
     371             : }
     372             : 
     373          54 : void ScDPSaveDimension::SetShowEmpty(bool bSet)
     374             : {
     375          54 :     nShowEmptyMode = bSet;
     376          54 : }
     377             : 
     378          70 : void ScDPSaveDimension::SetFunction(sal_uInt16 nNew)
     379             : {
     380          70 :     nFunction = nNew;
     381          70 : }
     382             : 
     383         112 : void ScDPSaveDimension::SetUsedHierarchy(long nNew)
     384             : {
     385         112 :     nUsedHierarchy = nNew;
     386         112 : }
     387             : 
     388           0 : void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
     389             : {
     390           0 :     mpSubtotalName.reset(new OUString(rName));
     391           0 : }
     392             : 
     393         360 : const OUString* ScDPSaveDimension::GetSubtotalName() const
     394             : {
     395         360 :     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          22 : const OUString* ScDPSaveDimension::GetLayoutName() const
     425             : {
     426          22 :     return mpLayoutName.get();
     427             : }
     428             : 
     429           0 : void ScDPSaveDimension::RemoveLayoutName()
     430             : {
     431           0 :     mpLayoutName.reset(NULL);
     432           0 : }
     433             : 
     434          36 : void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
     435             : {
     436          36 :     delete pReferenceValue;
     437          36 :     if (pNew)
     438           2 :         pReferenceValue = new sheet::DataPilotFieldReference(*pNew);
     439             :     else
     440          34 :         pReferenceValue = NULL;
     441          36 : }
     442             : 
     443          68 : void ScDPSaveDimension::SetSortInfo(const sheet::DataPilotFieldSortInfo* pNew)
     444             : {
     445          68 :     delete pSortInfo;
     446          68 :     if (pNew)
     447          66 :         pSortInfo = new sheet::DataPilotFieldSortInfo(*pNew);
     448             :     else
     449           2 :         pSortInfo = NULL;
     450          68 : }
     451             : 
     452          68 : void ScDPSaveDimension::SetAutoShowInfo(const sheet::DataPilotFieldAutoShowInfo* pNew)
     453             : {
     454          68 :     delete pAutoShowInfo;
     455          68 :     if (pNew)
     456          66 :         pAutoShowInfo = new sheet::DataPilotFieldAutoShowInfo(*pNew);
     457             :     else
     458           2 :         pAutoShowInfo = NULL;
     459          68 : }
     460             : 
     461          68 : void ScDPSaveDimension::SetLayoutInfo(const sheet::DataPilotFieldLayoutInfo* pNew)
     462             : {
     463          68 :     delete pLayoutInfo;
     464          68 :     if (pNew)
     465          66 :         pLayoutInfo = new sheet::DataPilotFieldLayoutInfo(*pNew);
     466             :     else
     467           2 :         pLayoutInfo = NULL;
     468          68 : }
     469             : 
     470           4 : 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           4 :     MemberList::iterator it = maMemberList.begin(), itEnd = maMemberList.end();
     476          12 :     for (; it != itEnd; ++it)
     477             :     {
     478           8 :         ScDPSaveMember* pMem = *it;
     479           8 :         bool bVisible = !pPage || pMem->GetName() == *pPage;
     480           8 :         pMem->SetIsVisible(bVisible);
     481             :     }
     482           4 : }
     483             : 
     484          28 : ScDPSaveMember* ScDPSaveDimension::GetExistingMemberByName(const ::rtl::OUString& rName)
     485             : {
     486          28 :     MemberHash::const_iterator res = maMemberHash.find (rName);
     487          28 :     if (res != maMemberHash.end())
     488           0 :         return res->second;
     489          28 :     return NULL;
     490             : }
     491             : 
     492           2 : ScDPSaveMember* ScDPSaveDimension::GetMemberByName(const ::rtl::OUString& rName)
     493             : {
     494           2 :     MemberHash::const_iterator res = maMemberHash.find (rName);
     495           2 :     if (res != maMemberHash.end())
     496           0 :         return res->second;
     497             : 
     498           2 :     ScDPSaveMember* pNew = new ScDPSaveMember( rName );
     499           2 :     maMemberHash[rName] = pNew;
     500           2 :     maMemberList.push_back( pNew );
     501           2 :     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         360 : void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xDim )
     517             : {
     518         360 :     uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
     519             :     OSL_ENSURE( xDimProp.is(), "no properties at dimension" );
     520         360 :     if ( xDimProp.is() )
     521             :     {
     522             :         // exceptions are caught at ScDPSaveData::WriteToSource
     523         360 :         uno::Any aAny;
     524             : 
     525         360 :         sheet::DataPilotFieldOrientation eOrient = (sheet::DataPilotFieldOrientation)nOrientation;
     526         360 :         aAny <<= eOrient;
     527         360 :         xDimProp->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ORIENTATION)), aAny );
     528             : 
     529         360 :         sheet::GeneralFunction eFunc = (sheet::GeneralFunction)nFunction;
     530         360 :         aAny <<= eFunc;
     531         360 :         xDimProp->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_FUNCTION)), aAny );
     532             : 
     533         360 :         if ( nUsedHierarchy >= 0 )
     534             :         {
     535         220 :             aAny <<= (sal_Int32)nUsedHierarchy;
     536         220 :             xDimProp->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_USEDHIERARCHY)), aAny );
     537             :         }
     538             : 
     539         360 :         if ( pReferenceValue )
     540             :         {
     541           2 :             aAny <<= *pReferenceValue;
     542           2 :             xDimProp->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_REFVALUE)), aAny );
     543             :         }
     544             : 
     545         360 :         if (mpLayoutName)
     546           0 :             ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_LAYOUTNAME, *mpLayoutName);
     547             : 
     548         360 :         const OUString* pSubTotalName = GetSubtotalName();
     549         360 :         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         360 :     long nCount = maMemberHash.size();
     558             : 
     559         360 :     long nHierCount = 0;
     560         360 :     uno::Reference<container::XIndexAccess> xHiers;
     561         360 :     uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
     562         360 :     if ( xHierSupp.is() )
     563             :     {
     564         360 :         uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
     565         360 :         xHiers = new ScNameToIndexAccess( xHiersName );
     566         360 :         nHierCount = xHiers->getCount();
     567             :     }
     568             : 
     569         360 :     bool bHasHiddenMember = false;
     570             : 
     571         720 :     for (long nHier=0; nHier<nHierCount; nHier++)
     572             :     {
     573         360 :         uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) );
     574             : 
     575         360 :         long nLevCount = 0;
     576         360 :         uno::Reference<container::XIndexAccess> xLevels;
     577         360 :         uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHierarchy, uno::UNO_QUERY );
     578         360 :         if ( xLevSupp.is() )
     579             :         {
     580         360 :             uno::Reference<container::XNameAccess> xLevelsName = xLevSupp->getLevels();
     581         360 :             xLevels = new ScNameToIndexAccess( xLevelsName );
     582         360 :             nLevCount = xLevels->getCount();
     583             :         }
     584             : 
     585         720 :         for (long nLev=0; nLev<nLevCount; nLev++)
     586             :         {
     587         360 :             uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(nLev) );
     588         360 :             uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
     589             :             OSL_ENSURE( xLevProp.is(), "no properties at level" );
     590         360 :             if ( xLevProp.is() )
     591             :             {
     592         360 :                 uno::Any aAny;
     593         360 :                 if ( !bSubTotalDefault )
     594             :                 {
     595          40 :                     if ( !pSubTotalFuncs )
     596           0 :                         nSubTotalCount = 0;
     597             : 
     598          40 :                     uno::Sequence<sheet::GeneralFunction> aSeq(nSubTotalCount);
     599          40 :                     sheet::GeneralFunction* pArray = aSeq.getArray();
     600          80 :                     for (long i=0; i<nSubTotalCount; i++)
     601          40 :                         pArray[i] = (sheet::GeneralFunction)pSubTotalFuncs[i];
     602          40 :                     aAny <<= aSeq;
     603          40 :                     xLevProp->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_SUBTOTAL)), aAny );
     604             :                 }
     605         360 :                 if ( nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW )
     606             :                     lcl_SetBoolProperty( xLevProp,
     607         150 :                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_SHOWEMPTY)), (bool)nShowEmptyMode );
     608             : 
     609         360 :                 if ( pSortInfo )
     610         142 :                     ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_SORTING, *pSortInfo);
     611             : 
     612         360 :                 if ( pAutoShowInfo )
     613         150 :                     ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_AUTOSHOW, *pAutoShowInfo);
     614             : 
     615         360 :                 if ( pLayoutInfo )
     616         146 :                     ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_LAYOUT, *pLayoutInfo);
     617             : 
     618             :                 // exceptions are caught at ScDPSaveData::WriteToSource
     619             :             }
     620             : 
     621         360 :             if ( nCount > 0 )
     622             :             {
     623         112 :                 uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevel, uno::UNO_QUERY );
     624         112 :                 if ( xMembSupp.is() )
     625             :                 {
     626         112 :                     uno::Reference<container::XNameAccess> xMembers = xMembSupp->getMembers();
     627         112 :                     if ( xMembers.is() )
     628             :                     {
     629         112 :                         sal_Int32 nPosition = -1; // set position only in manual mode
     630         112 :                         if ( !pSortInfo || pSortInfo->Mode == sheet::DataPilotFieldSortMode::MANUAL )
     631          32 :                             nPosition = 0;
     632             : 
     633         598 :                         for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; ++i)
     634             :                         {
     635         486 :                             ScDPSaveMember* pMember = *i;
     636         486 :                             if (!pMember->GetIsVisible())
     637           6 :                                 bHasHiddenMember = true;
     638         486 :                             rtl::OUString aMemberName = pMember->GetName();
     639         486 :                             if ( xMembers->hasByName( aMemberName ) )
     640             :                             {
     641             :                                 uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
     642         466 :                                     xMembers->getByName( aMemberName ) );
     643         466 :                                 pMember->WriteToSource( xMemberInt, nPosition );
     644             : 
     645         466 :                                 if ( nPosition >= 0 )
     646         104 :                                     ++nPosition; // increase if initialized
     647             :                             }
     648             :                             // missing member is no error
     649         486 :                         }
     650         112 :                     }
     651         112 :                 }
     652             :             }
     653         360 :         }
     654         360 :     }
     655             : 
     656         360 :     if (xDimProp.is())
     657         360 :         ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_HAS_HIDDEN_MEMBER, bHasHiddenMember);
     658         360 : }
     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          26 : bool ScDPSaveDimension::HasInvisibleMember() const
     675             : {
     676          26 :     MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
     677          72 :     for (; itrMem != itrMemEnd; ++itrMem)
     678             :     {
     679          46 :         const ScDPSaveMember* pMem = *itrMem;
     680          46 :         if (!pMem->GetIsVisible())
     681           0 :             return true;
     682             :     }
     683          26 :     return false;
     684             : }
     685             : 
     686          24 : void ScDPSaveDimension::RemoveObsoleteMembers(const MemberSetType& rMembers)
     687             : {
     688          24 :     maMemberHash.clear();
     689          24 :     MemberList aNew;
     690          24 :     MemberList::iterator it = maMemberList.begin(), itEnd = maMemberList.end();
     691          24 :     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          24 :     maMemberList.swap(aNew);
     708          24 : }
     709             : 
     710          70 : 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          70 :     mpGrandTotalName(NULL)
     720             : {
     721          70 : }
     722             : 
     723         138 : 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         138 :     mpGrandTotalName(NULL)
     732             : {
     733         138 :     if ( r.pDimensionData )
     734           2 :         pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData );
     735             :     else
     736         136 :         pDimensionData = NULL;
     737             : 
     738         138 :     aDimList = r.aDimList.clone();
     739             : 
     740         138 :     if (r.mpGrandTotalName)
     741           0 :         mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
     742         138 : }
     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         332 : ScDPSaveData::~ScDPSaveData()
     789             : {
     790         166 :     delete pDimensionData;
     791         166 : }
     792             : 
     793           0 : void ScDPSaveData::SetGrandTotalName(const OUString& rName)
     794             : {
     795           0 :     mpGrandTotalName.reset(new OUString(rName));
     796           0 : }
     797             : 
     798          92 : const OUString* ScDPSaveData::GetGrandTotalName() const
     799             : {
     800          92 :     return mpGrandTotalName.get();
     801             : }
     802             : 
     803          10 : const ScDPSaveData::DimsType& ScDPSaveData::GetDimensions() const
     804             : {
     805          10 :     return aDimList;
     806             : }
     807             : 
     808          32 : void ScDPSaveData::GetAllDimensionsByOrientation(
     809             :     sheet::DataPilotFieldOrientation eOrientation, std::vector<const ScDPSaveDimension*>& rDims) const
     810             : {
     811          32 :     std::vector<const ScDPSaveDimension*> aDims;
     812          32 :     DimsType::const_iterator it = aDimList.begin(), itEnd = aDimList.end();
     813         210 :     for (; it != itEnd; ++it)
     814             :     {
     815         178 :         const ScDPSaveDimension& rDim = *it;
     816         178 :         if (rDim.GetOrientation() != static_cast<sal_uInt16>(eOrientation))
     817         132 :             continue;
     818             : 
     819          46 :         aDims.push_back(&rDim);
     820             :     }
     821             : 
     822          32 :     rDims.swap(aDims);
     823          32 : }
     824             : 
     825          40 : void ScDPSaveData::AddDimension(ScDPSaveDimension* pDim)
     826             : {
     827          40 :     if (!pDim)
     828          40 :         return;
     829             : 
     830          40 :     CheckDuplicateName(*pDim);
     831          40 :     aDimList.push_back(pDim);
     832             : }
     833             : 
     834         100 : ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const ::rtl::OUString& rName)
     835             : {
     836         100 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     837         264 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     838             :     {
     839         248 :         if (iter->GetName() == rName && !iter->IsDataLayout() )
     840          84 :             return const_cast<ScDPSaveDimension*>(&(*iter));
     841             :     }
     842             : 
     843          16 :     return AppendNewDimension(rName, false);
     844             : }
     845             : 
     846          36 : ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const ::rtl::OUString& rName) const
     847             : {
     848          36 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     849         116 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     850             :     {
     851          82 :         if (iter->GetName() == rName && !iter->IsDataLayout() )
     852           2 :             return const_cast<ScDPSaveDimension*>(&(*iter));
     853             :     }
     854          34 :     return NULL; // don't create new
     855             : }
     856             : 
     857          74 : ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const ::rtl::OUString& rName)
     858             : {
     859          74 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     860         142 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     861             :     {
     862          70 :         if (iter->GetName() == rName && !iter->IsDataLayout() )
     863           2 :             return DuplicateDimension(rName);
     864             :     }
     865             : 
     866          72 :     return AppendNewDimension(rName, false);
     867             : }
     868             : 
     869          32 : ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
     870             : {
     871          32 :     ScDPSaveDimension* pDim = GetExistingDataLayoutDimension();
     872          32 :     if (pDim)
     873           2 :         return pDim;
     874             : 
     875          30 :     return AppendNewDimension(rtl::OUString(), true);
     876             : }
     877             : 
     878          34 : ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const
     879             : {
     880          34 :     boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
     881         136 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     882             :     {
     883         106 :         if ( iter->IsDataLayout() )
     884           4 :             return const_cast<ScDPSaveDimension*>(&(*iter));
     885             :     }
     886          30 :     return NULL;
     887             : }
     888             : 
     889           2 : ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const ::rtl::OUString& rName)
     890             : {
     891             :     // always insert new
     892             : 
     893           2 :     ScDPSaveDimension* pOld = GetExistingDimensionByName(rName);
     894           2 :     if (!pOld)
     895           0 :         return NULL;
     896             : 
     897           2 :     ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld );
     898           2 :     AddDimension(pNew);
     899           2 :     return pNew;
     900             : }
     901             : 
     902           4 : void ScDPSaveData::RemoveDimensionByName(const ::rtl::OUString& rName)
     903             : {
     904           4 :     boost::ptr_vector<ScDPSaveDimension>::iterator iter;
     905          12 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
     906             :     {
     907           6 :         if (iter->GetName() != rName || iter->IsDataLayout())
     908           2 :             continue;
     909             : 
     910           4 :         aDimList.erase(iter);
     911           4 :         RemoveDuplicateNameCount(rName);
     912           4 :         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          18 : void ScDPSaveData::SetPosition( ScDPSaveDimension* pDim, long nNew )
     964             : {
     965             :     // position (nNew) is counted within dimensions of the same orientation
     966             : 
     967          18 :     sal_uInt16 nOrient = pDim->GetOrientation();
     968             : 
     969          18 :     boost::ptr_vector<ScDPSaveDimension>::iterator it;
     970          68 :     for ( it = aDimList.begin(); it != aDimList.end(); ++it)
     971             :     {
     972          68 :         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          18 :             aDimList.release(it).release();
     978          18 :             break;
     979             :         }
     980             :     }
     981             : 
     982          18 :     boost::ptr_vector<ScDPSaveDimension>::iterator iterInsert = aDimList.begin();
     983          56 :     while ( nNew > 0 && iterInsert != aDimList.end())
     984             :     {
     985          20 :         if (iterInsert->GetOrientation() == nOrient )
     986           0 :             --nNew;
     987             : 
     988          20 :         ++iterInsert;
     989             :     }
     990             : 
     991          18 :     aDimList.insert(iterInsert,pDim);
     992          18 : }
     993             : 
     994          36 : void ScDPSaveData::SetColumnGrand(bool bSet)
     995             : {
     996          36 :     nColumnGrandMode = bSet;
     997          36 : }
     998             : 
     999          36 : void ScDPSaveData::SetRowGrand(bool bSet)
    1000             : {
    1001          36 :     nRowGrandMode = bSet;
    1002          36 : }
    1003             : 
    1004          38 : void ScDPSaveData::SetIgnoreEmptyRows(bool bSet)
    1005             : {
    1006          38 :     nIgnoreEmptyMode = bSet;
    1007          38 : }
    1008             : 
    1009          36 : void ScDPSaveData::SetRepeatIfEmpty(bool bSet)
    1010             : {
    1011          36 :     nRepeatEmptyMode = bSet;
    1012          36 : }
    1013             : 
    1014          36 : void ScDPSaveData::SetFilterButton(bool bSet)
    1015             : {
    1016          36 :     bFilterButton = bSet;
    1017          36 : }
    1018             : 
    1019          36 : void ScDPSaveData::SetDrillDown(bool bSet)
    1020             : {
    1021          36 :     bDrillDown = bSet;
    1022          36 : }
    1023             : 
    1024          92 : static void lcl_ResetOrient( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
    1025             : {
    1026          92 :     sheet::DataPilotFieldOrientation eOrient = sheet::DataPilotFieldOrientation_HIDDEN;
    1027             : 
    1028          92 :     uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
    1029          92 :     uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
    1030          92 :     long nIntCount = xIntDims->getCount();
    1031         548 :     for (long nIntDim=0; nIntDim<nIntCount; nIntDim++)
    1032             :     {
    1033         456 :         uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
    1034         456 :         uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
    1035         456 :         if (xDimProp.is())
    1036             :         {
    1037         456 :             uno::Any aAny;
    1038         456 :             aAny <<= eOrient;
    1039         456 :             xDimProp->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ORIENTATION)), aAny );
    1040             :         }
    1041         548 :     }
    1042          92 : }
    1043             : 
    1044          92 : void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
    1045             : {
    1046          92 :     if (!xSource.is())
    1047          92 :         return;
    1048             : 
    1049             :     // source options must be first!
    1050             : 
    1051          92 :     uno::Reference<beans::XPropertySet> xSourceProp( xSource, uno::UNO_QUERY );
    1052             :     OSL_ENSURE( xSourceProp.is(), "no properties at source" );
    1053          92 :     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          92 :             if ( nIgnoreEmptyMode != SC_DPSAVEMODE_DONTKNOW )
    1061             :                 lcl_SetBoolProperty( xSourceProp,
    1062          92 :                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_IGNOREEMPTY)), (bool)nIgnoreEmptyMode );
    1063          92 :             if ( nRepeatEmptyMode != SC_DPSAVEMODE_DONTKNOW )
    1064             :                 lcl_SetBoolProperty( xSourceProp,
    1065          92 :                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_REPEATEMPTY)), (bool)nRepeatEmptyMode );
    1066             :         }
    1067           0 :         catch(uno::Exception&)
    1068             :         {
    1069             :             // no error
    1070             :         }
    1071             : 
    1072          92 :         const OUString* pGrandTotalName = GetGrandTotalName();
    1073          92 :         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          92 :         lcl_ResetOrient( xSource );
    1086             : 
    1087          92 :         uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
    1088          92 :         uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
    1089          92 :         long nIntCount = xIntDims->getCount();
    1090             : 
    1091          92 :         boost::ptr_vector<ScDPSaveDimension>::iterator iter = aDimList.begin();
    1092         454 :         for (long i = 0; iter != aDimList.end(); ++iter, ++i)
    1093             :         {
    1094         362 :             rtl::OUString aName = iter->GetName();
    1095         362 :             rtl::OUString aCoreName = ScDPUtil::getSourceDimensionName(aName);
    1096             : 
    1097             :             OSL_TRACE( "%s", aName.getStr() );
    1098             : 
    1099         362 :             bool bData = iter->IsDataLayout();
    1100             : 
    1101             :             //! getByName for ScDPSource, including DataLayoutDimension !!!!!!!!
    1102             : 
    1103         362 :             bool bFound = false;
    1104        1400 :             for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
    1105             :             {
    1106        1038 :                 uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
    1107        1038 :                 if ( bData )
    1108             :                 {
    1109         324 :                     uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
    1110         324 :                     if ( xDimProp.is() )
    1111             :                     {
    1112             :                         bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
    1113         324 :                                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ISDATALAYOUT)) );
    1114             :                         //! error checking -- is "IsDataLayoutDimension" property required??
    1115         324 :                     }
    1116             :                 }
    1117             :                 else
    1118             :                 {
    1119         714 :                     uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
    1120         714 :                     if (xDimName.is() && xDimName->getName() == aCoreName)
    1121         290 :                         bFound = true;
    1122             :                 }
    1123             : 
    1124        1038 :                 if (bFound)
    1125             :                 {
    1126         360 :                     if (iter->GetDupFlag())
    1127             :                     {
    1128           4 :                         uno::Reference<util::XCloneable> xCloneable(xIntDim, uno::UNO_QUERY);
    1129             :                         OSL_ENSURE(xCloneable.is(), "cannot clone dimension");
    1130           4 :                         if (xCloneable.is())
    1131             :                         {
    1132           4 :                             uno::Reference<util::XCloneable> xNew = xCloneable->createClone();
    1133           4 :                             uno::Reference<container::XNamed> xNewName(xNew, uno::UNO_QUERY);
    1134           4 :                             if (xNewName.is())
    1135             :                             {
    1136           4 :                                 xNewName->setName(aName);
    1137           4 :                                 iter->WriteToSource(xNew);
    1138           4 :                             }
    1139           4 :                         }
    1140             :                     }
    1141             :                     else
    1142         356 :                         iter->WriteToSource( xIntDim );
    1143             :                 }
    1144        1038 :             }
    1145             :             OSL_ENSURE(bFound, "WriteToSource: Dimension not found");
    1146         362 :         }
    1147             : 
    1148          92 :         if ( xSourceProp.is() )
    1149             :         {
    1150          92 :             if ( nColumnGrandMode != SC_DPSAVEMODE_DONTKNOW )
    1151             :                 lcl_SetBoolProperty( xSourceProp,
    1152          92 :                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_COLGRAND)), (bool)nColumnGrandMode );
    1153          92 :             if ( nRowGrandMode != SC_DPSAVEMODE_DONTKNOW )
    1154             :                 lcl_SetBoolProperty( xSourceProp,
    1155          92 :                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_ROWGRAND)), (bool)nRowGrandMode );
    1156          92 :         }
    1157             :     }
    1158           0 :     catch(uno::Exception&)
    1159             :     {
    1160             :         OSL_FAIL("exception in WriteToSource");
    1161          92 :     }
    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           2 : void ScDPSaveData::RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames )
    1176             : {
    1177           2 :     if (!pDimensionData)
    1178             :         // No group dimensions exist.  Nothing to do.
    1179           2 :         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           2 :     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           2 :     const ScDPSaveGroupDimension* pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
    1189           8 :     while ( pExistingGroup )
    1190             :     {
    1191           4 :         rtl::OUString aGroupDimName = pExistingGroup->GetGroupDimName();
    1192           4 :         pDimensionData->RemoveGroupDimension(aGroupDimName);     // pExistingGroup is deleted
    1193             : 
    1194             :         // also remove SaveData settings for the dimension that no longer exists
    1195           4 :         RemoveDimensionByName(aGroupDimName);
    1196             : 
    1197           4 :         if (pDeletedNames)
    1198           0 :             pDeletedNames->push_back(aGroupDimName);
    1199             : 
    1200             :         // see if there are more group dimensions
    1201           4 :         pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
    1202             : 
    1203           4 :         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           4 :     }
    1210             : }
    1211             : 
    1212          10 : ScDPDimensionSaveData* ScDPSaveData::GetDimensionData()
    1213             : {
    1214          10 :     if (!pDimensionData)
    1215           8 :         pDimensionData = new ScDPDimensionSaveData;
    1216          10 :     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           2 : void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
    1229             : {
    1230           2 :     if (mbDimensionMembersBuilt)
    1231           2 :         return;
    1232             : 
    1233             :     // First, build a dimension name-to-index map.
    1234             :     typedef boost::unordered_map<OUString, long, ::rtl::OUStringHash> NameIndexMap;
    1235           2 :     NameIndexMap aMap;
    1236           2 :     long nColCount = pData->GetColumnCount();
    1237          12 :     for (long i = 0; i < nColCount; ++i)
    1238          10 :         aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i));
    1239             : 
    1240           2 :     NameIndexMap::const_iterator itrEnd = aMap.end();
    1241             : 
    1242           2 :     boost::ptr_vector<ScDPSaveDimension>::iterator iter;
    1243          14 :     for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
    1244             :     {
    1245          12 :         const ::rtl::OUString& rDimName = iter->GetName();
    1246          12 :         if (rDimName.isEmpty())
    1247             :             // empty dimension name. It must be data layout.
    1248           2 :             continue;
    1249             : 
    1250          10 :         NameIndexMap::const_iterator itr = aMap.find(rDimName);
    1251          10 :         if (itr == itrEnd)
    1252             :             // dimension name not in the data. This should never happen!
    1253           0 :             continue;
    1254             : 
    1255          10 :         long nDimIndex = itr->second;
    1256          10 :         const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
    1257          10 :         size_t mMemberCount = rMembers.size();
    1258          38 :         for (size_t j = 0; j < mMemberCount; ++j)
    1259             :         {
    1260          28 :             const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] );
    1261          28 :             rtl::OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData);
    1262          28 :             if (iter->GetExistingMemberByName(aMemName))
    1263             :                 // this member instance already exists. nothing to do.
    1264           0 :                 continue;
    1265             : 
    1266          28 :             auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName));
    1267          28 :             pNewMember->SetIsVisible(true);
    1268          28 :             iter->AddMember(pNewMember.release());
    1269          28 :         }
    1270             :     }
    1271             : 
    1272           2 :     mbDimensionMembersBuilt = true;
    1273             : }
    1274             : 
    1275           8 : 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           8 :     NameIndexMap aMap;
    1281           8 :     long nColCount = pData->GetColumnCount();
    1282          48 :     for (long i = 0; i < nColCount; ++i)
    1283          40 :         aMap.insert(NameIndexMap::value_type(pData->getDimensionName(i), i));
    1284             : 
    1285           8 :     NameIndexMap::const_iterator itMapEnd = aMap.end();
    1286             : 
    1287           8 :     DimsType::iterator it = aDimList.begin(), itEnd = aDimList.end();
    1288          32 :     for (it = aDimList.begin(); it != itEnd; ++it)
    1289             :     {
    1290          24 :         const ::rtl::OUString& rDimName = it->GetName();
    1291          24 :         if (rDimName.isEmpty())
    1292             :             // empty dimension name. It must be data layout.
    1293           0 :             continue;
    1294             : 
    1295          24 :         NameIndexMap::const_iterator itMap = aMap.find(rDimName);
    1296          24 :         if (itMap == itMapEnd)
    1297             :             // dimension name not in the data. This should never happen!
    1298           0 :             continue;
    1299             : 
    1300          24 :         ScDPSaveDimension::MemberSetType aMemNames;
    1301          24 :         long nDimIndex = itMap->second;
    1302          24 :         const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
    1303          24 :         size_t nMemberCount = rMembers.size();
    1304         140 :         for (size_t j = 0; j < nMemberCount; ++j)
    1305             :         {
    1306         116 :             const ScDPItemData* pMemberData = pData->GetMemberById(nDimIndex, rMembers[j]);
    1307         116 :             rtl::OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData);
    1308         116 :             aMemNames.insert(aMemName);
    1309         116 :         }
    1310             : 
    1311          24 :         it->RemoveObsoleteMembers(aMemNames);
    1312          32 :     }
    1313           8 : }
    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          40 : void ScDPSaveData::CheckDuplicateName(ScDPSaveDimension& rDim)
    1325             : {
    1326          40 :     const rtl::OUString aName = ScDPUtil::getSourceDimensionName(rDim.GetName());
    1327          40 :     DupNameCountType::iterator it = maDupNameCounts.find(aName);
    1328          40 :     if (it != maDupNameCounts.end())
    1329             :     {
    1330           2 :         rDim.SetName(ScDPUtil::createDuplicateDimensionName(aName, ++it->second));
    1331           2 :         rDim.SetDupFlag(true);
    1332             :     }
    1333             :     else
    1334             :         // New name.
    1335          38 :         maDupNameCounts.insert(DupNameCountType::value_type(aName, 0));
    1336          40 : }
    1337             : 
    1338           4 : void ScDPSaveData::RemoveDuplicateNameCount(const rtl::OUString& rName)
    1339             : {
    1340           4 :     rtl::OUString aCoreName = rName;
    1341           4 :     if (ScDPUtil::isDuplicateDimension(rName))
    1342           0 :         aCoreName = ScDPUtil::getSourceDimensionName(rName);
    1343             : 
    1344           4 :     DupNameCountType::iterator it = maDupNameCounts.find(aCoreName);
    1345           4 :     if (it == maDupNameCounts.end())
    1346             :         return;
    1347             : 
    1348           4 :     if (!it->second)
    1349             :     {
    1350           4 :         maDupNameCounts.erase(it);
    1351             :         return;
    1352             :     }
    1353             : 
    1354           0 :     --it->second;
    1355           4 :     return;
    1356             : }
    1357             : 
    1358         118 : ScDPSaveDimension* ScDPSaveData::AppendNewDimension(const rtl::OUString& rName, bool bDataLayout)
    1359             : {
    1360         118 :     if (ScDPUtil::isDuplicateDimension(rName))
    1361             :         // This call is for original dimensions only.
    1362           0 :         return NULL;
    1363             : 
    1364         118 :     ScDPSaveDimension* pNew = new ScDPSaveDimension(rName, bDataLayout);
    1365         118 :     aDimList.push_back(pNew);
    1366         118 :     if (!maDupNameCounts.count(rName))
    1367         118 :         maDupNameCounts.insert(DupNameCountType::value_type(rName, 0));
    1368             : 
    1369         118 :     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         102 : }
    1390             : 
    1391             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10