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

Generated by: LCOV version 1.11