Files
loongoffice/sc/source/core/data/dpsave.cxx
Markus Mohrhard 37e6631cc5 remove whitespace
Change-Id: Ib15413e73409cc33de01fa92a47b9d1237cfc4b2
2014-06-25 05:41:10 +02:00

1509 lines
46 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "dpsave.hxx"
#include "dpdimsave.hxx"
#include "miscuno.hxx"
#include "scerrors.hxx"
#include "unonames.hxx"
#include "global.hxx"
#include "dptabsrc.hxx"
#include "dputil.hxx"
#include <sal/types.h>
#include <comphelper/string.hxx>
#include <com/sun/star/sheet/GeneralFunction.hpp>
#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
#include <com/sun/star/sheet/TableFilterField.hpp>
#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
#include <com/sun/star/sheet/XLevelsSupplier.hpp>
#include <com/sun/star/sheet/XMembersSupplier.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
using namespace com::sun::star;
using namespace com::sun::star::sheet;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Any;
using ::std::auto_ptr;
#define SC_DPSAVEMODE_DONTKNOW 2
static void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
const OUString& rName, bool bValue )
{
//! move to ScUnoHelpFunctions?
xProp->setPropertyValue( rName, uno::Any( &bValue, getBooleanCppuType() ) );
}
ScDPSaveMember::ScDPSaveMember(const OUString& rName) :
aName( rName ),
mpLayoutName(NULL),
nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
{
}
ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) :
aName( r.aName ),
mpLayoutName(NULL),
nVisibleMode( r.nVisibleMode ),
nShowDetailsMode( r.nShowDetailsMode )
{
if (r.mpLayoutName)
mpLayoutName.reset(new OUString(*r.mpLayoutName));
}
ScDPSaveMember::~ScDPSaveMember()
{
}
bool ScDPSaveMember::operator== ( const ScDPSaveMember& r ) const
{
if ( aName != r.aName ||
nVisibleMode != r.nVisibleMode ||
nShowDetailsMode != r.nShowDetailsMode )
return false;
return true;
}
bool ScDPSaveMember::HasIsVisible() const
{
return nVisibleMode != SC_DPSAVEMODE_DONTKNOW;
}
void ScDPSaveMember::SetIsVisible(bool bSet)
{
nVisibleMode = sal_uInt16(bSet);
}
bool ScDPSaveMember::HasShowDetails() const
{
return nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW;
}
void ScDPSaveMember::SetShowDetails(bool bSet)
{
nShowDetailsMode = sal_uInt16(bSet);
}
void ScDPSaveMember::SetName( const OUString& rNew )
{
// Used only if the source member was renamed (groups).
// For UI renaming of members, a layout name must be used.
aName = rNew;
}
void ScDPSaveMember::SetLayoutName( const OUString& rName )
{
mpLayoutName.reset(new OUString(rName));
}
const OUString* ScDPSaveMember::GetLayoutName() const
{
return mpLayoutName.get();
}
void ScDPSaveMember::RemoveLayoutName()
{
mpLayoutName.reset();
}
void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
{
uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
OSL_ENSURE( xMembProp.is(), "no properties at member" );
if ( xMembProp.is() )
{
// exceptions are caught at ScDPSaveData::WriteToSource
if ( nVisibleMode != SC_DPSAVEMODE_DONTKNOW )
lcl_SetBoolProperty( xMembProp,
OUString(SC_UNO_DP_ISVISIBLE), (bool)nVisibleMode );
if ( nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW )
lcl_SetBoolProperty( xMembProp,
OUString(SC_UNO_DP_SHOWDETAILS), (bool)nShowDetailsMode );
if (mpLayoutName)
ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_DP_LAYOUTNAME, *mpLayoutName);
if ( nPosition >= 0 )
ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_DP_POSITION, nPosition);
}
}
#if DEBUG_PIVOT_TABLE
void ScDPSaveMember::Dump(int nIndent) const
{
std::string aIndent(nIndent*4, ' ');
cout << aIndent << "* member name: '" << aName << "'" << endl;
cout << aIndent << " + layout name: ";
if (mpLayoutName)
cout << "'" << *mpLayoutName << "'";
else
cout << "(none)";
cout << endl;
cout << aIndent << " + visibility: ";
if (nVisibleMode == SC_DPSAVEMODE_DONTKNOW)
cout << "(unknown)";
else
cout << (nVisibleMode ? "visible" : "hidden");
cout << endl;
}
#endif
ScDPSaveDimension::ScDPSaveDimension(const OUString& rName, bool bDataLayout) :
aName( rName ),
mpLayoutName(NULL),
mpSubtotalName(NULL),
bIsDataLayout( bDataLayout ),
bDupFlag( false ),
nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ),
nFunction( sheet::GeneralFunction_AUTO ),
nUsedHierarchy( -1 ),
nShowEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
bSubTotalDefault( true ),
nSubTotalCount( 0 ),
pSubTotalFuncs( NULL ),
pReferenceValue( NULL ),
pSortInfo( NULL ),
pAutoShowInfo( NULL ),
pLayoutInfo( NULL )
{
}
ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
aName( r.aName ),
mpLayoutName(NULL),
mpSubtotalName(NULL),
bIsDataLayout( r.bIsDataLayout ),
bDupFlag( r.bDupFlag ),
nOrientation( r.nOrientation ),
nFunction( r.nFunction ),
nUsedHierarchy( r.nUsedHierarchy ),
nShowEmptyMode( r.nShowEmptyMode ),
bSubTotalDefault( r.bSubTotalDefault ),
nSubTotalCount( r.nSubTotalCount ),
pSubTotalFuncs( NULL )
{
if ( nSubTotalCount && r.pSubTotalFuncs )
{
pSubTotalFuncs = new sal_uInt16[nSubTotalCount];
for (long nSub=0; nSub<nSubTotalCount; nSub++)
pSubTotalFuncs[nSub] = r.pSubTotalFuncs[nSub];
}
for (MemberList::const_iterator i=r.maMemberList.begin(); i != r.maMemberList.end() ; ++i)
{
const OUString& rName = (*i)->GetName();
ScDPSaveMember* pNew = new ScDPSaveMember( **i );
maMemberHash[rName] = pNew;
maMemberList.push_back( pNew );
}
if (r.pReferenceValue)
pReferenceValue = new sheet::DataPilotFieldReference( *(r.pReferenceValue) );
else
pReferenceValue = NULL;
if (r.pSortInfo)
pSortInfo = new sheet::DataPilotFieldSortInfo( *(r.pSortInfo) );
else
pSortInfo = NULL;
if (r.pAutoShowInfo)
pAutoShowInfo = new sheet::DataPilotFieldAutoShowInfo( *(r.pAutoShowInfo) );
else
pAutoShowInfo = NULL;
if (r.pLayoutInfo)
pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) );
else
pLayoutInfo = NULL;
if (r.mpLayoutName)
mpLayoutName.reset(new OUString(*r.mpLayoutName));
if (r.mpSubtotalName)
mpSubtotalName.reset(new OUString(*r.mpSubtotalName));
}
ScDPSaveDimension::~ScDPSaveDimension()
{
for (MemberHash::const_iterator i=maMemberHash.begin(); i != maMemberHash.end() ; ++i)
delete i->second;
delete pReferenceValue;
delete pSortInfo;
delete pAutoShowInfo;
delete pLayoutInfo;
delete [] pSubTotalFuncs;
}
bool ScDPSaveDimension::operator== ( const ScDPSaveDimension& r ) const
{
if ( aName != r.aName ||
bIsDataLayout != r.bIsDataLayout ||
bDupFlag != r.bDupFlag ||
nOrientation != r.nOrientation ||
nFunction != r.nFunction ||
nUsedHierarchy != r.nUsedHierarchy ||
nShowEmptyMode != r.nShowEmptyMode ||
bSubTotalDefault != r.bSubTotalDefault ||
nSubTotalCount != r.nSubTotalCount )
return false;
if ( nSubTotalCount && ( !pSubTotalFuncs || !r.pSubTotalFuncs ) ) // should not happen
return false;
long i;
for (i=0; i<nSubTotalCount; i++)
if ( pSubTotalFuncs[i] != r.pSubTotalFuncs[i] )
return false;
if (maMemberHash.size() != r.maMemberHash.size() )
return false;
MemberList::const_iterator a=maMemberList.begin();
MemberList::const_iterator b=r.maMemberList.begin();
for (; a != maMemberList.end() ; ++a, ++b)
if (!(**a == **b))
return false;
if( pReferenceValue && r.pReferenceValue )
{
if ( !(*pReferenceValue == *r.pReferenceValue) )
{
return false;
}
}
else if ( pReferenceValue || r.pReferenceValue )
{
return false;
}
if( this->pSortInfo && r.pSortInfo )
{
if ( !(*this->pSortInfo == *r.pSortInfo) )
{
return false;
}
}
else if ( this->pSortInfo || r.pSortInfo )
{
return false;
}
if( this->pAutoShowInfo && r.pAutoShowInfo )
{
if ( !(*this->pAutoShowInfo == *r.pAutoShowInfo) )
{
return false;
}
}
else if ( this->pAutoShowInfo || r.pAutoShowInfo )
{
return false;
}
return true;
}
void ScDPSaveDimension::AddMember(ScDPSaveMember* pMember)
{
const OUString & rName = pMember->GetName();
MemberHash::iterator aExisting = maMemberHash.find( rName );
if ( aExisting == maMemberHash.end() )
{
std::pair< const OUString, ScDPSaveMember *> key( rName, pMember );
maMemberHash.insert ( key );
}
else
{
maMemberList.remove( aExisting->second );
delete aExisting->second;
aExisting->second = pMember;
}
maMemberList.push_back( pMember );
}
void ScDPSaveDimension::SetName( const OUString& rNew )
{
// Used only if the source dim was renamed (groups).
// For UI renaming of dimensions, the layout name must be used.
aName = rNew;
}
void ScDPSaveDimension::SetOrientation(sal_uInt16 nNew)
{
nOrientation = nNew;
}
void ScDPSaveDimension::SetSubTotals(long nCount, const sal_uInt16* pFuncs)
{
if (pSubTotalFuncs)
delete [] pSubTotalFuncs;
nSubTotalCount = nCount;
if ( nCount && pFuncs )
{
pSubTotalFuncs = new sal_uInt16[nCount];
for (long i=0; i<nCount; i++)
pSubTotalFuncs[i] = pFuncs[i];
}
else
pSubTotalFuncs = NULL;
bSubTotalDefault = false;
}
bool ScDPSaveDimension::HasShowEmpty() const
{
return nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW;
}
void ScDPSaveDimension::SetShowEmpty(bool bSet)
{
nShowEmptyMode = sal_uInt16(bSet);
}
void ScDPSaveDimension::SetFunction(sal_uInt16 nNew)
{
nFunction = nNew;
}
void ScDPSaveDimension::SetUsedHierarchy(long nNew)
{
nUsedHierarchy = nNew;
}
void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
{
mpSubtotalName.reset(new OUString(rName));
}
const OUString* ScDPSaveDimension::GetSubtotalName() const
{
return mpSubtotalName.get();
}
void ScDPSaveDimension::RemoveSubtotalName()
{
mpSubtotalName.reset();
}
bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const
{
MemberList::const_iterator itr = maMemberList.begin(), itrEnd = maMemberList.end();
for (; itr != itrEnd; ++itr)
{
const ScDPSaveMember* pMem = *itr;
if (rName.equalsIgnoreAsciiCase(pMem->GetName()))
return true;
const OUString* pLayoutName = pMem->GetLayoutName();
if (pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName))
return true;
}
return false;
}
void ScDPSaveDimension::SetLayoutName(const OUString& rName)
{
mpLayoutName.reset(new OUString(rName));
}
const OUString* ScDPSaveDimension::GetLayoutName() const
{
return mpLayoutName.get();
}
void ScDPSaveDimension::RemoveLayoutName()
{
mpLayoutName.reset();
}
void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
{
delete pReferenceValue;
if (pNew)
pReferenceValue = new sheet::DataPilotFieldReference(*pNew);
else
pReferenceValue = NULL;
}
void ScDPSaveDimension::SetSortInfo(const sheet::DataPilotFieldSortInfo* pNew)
{
delete pSortInfo;
if (pNew)
pSortInfo = new sheet::DataPilotFieldSortInfo(*pNew);
else
pSortInfo = NULL;
}
void ScDPSaveDimension::SetAutoShowInfo(const sheet::DataPilotFieldAutoShowInfo* pNew)
{
delete pAutoShowInfo;
if (pNew)
pAutoShowInfo = new sheet::DataPilotFieldAutoShowInfo(*pNew);
else
pAutoShowInfo = NULL;
}
void ScDPSaveDimension::SetLayoutInfo(const sheet::DataPilotFieldLayoutInfo* pNew)
{
delete pLayoutInfo;
if (pNew)
pLayoutInfo = new sheet::DataPilotFieldLayoutInfo(*pNew);
else
pLayoutInfo = NULL;
}
void ScDPSaveDimension::SetCurrentPage( const OUString* pPage )
{
// We use member's visibility attribute to filter by page dimension.
// pPage == NULL -> all members visible.
MemberList::iterator it = maMemberList.begin(), itEnd = maMemberList.end();
for (; it != itEnd; ++it)
{
ScDPSaveMember* pMem = *it;
bool bVisible = !pPage || pMem->GetName() == *pPage;
pMem->SetIsVisible(bVisible);
}
}
ScDPSaveMember* ScDPSaveDimension::GetExistingMemberByName(const OUString& rName)
{
MemberHash::const_iterator res = maMemberHash.find (rName);
if (res != maMemberHash.end())
return res->second;
return NULL;
}
ScDPSaveMember* ScDPSaveDimension::GetMemberByName(const OUString& rName)
{
MemberHash::const_iterator res = maMemberHash.find (rName);
if (res != maMemberHash.end())
return res->second;
ScDPSaveMember* pNew = new ScDPSaveMember( rName );
maMemberHash[rName] = pNew;
maMemberList.push_back( pNew );
return pNew;
}
void ScDPSaveDimension::SetMemberPosition( const OUString& rName, sal_Int32 nNewPos )
{
ScDPSaveMember* pMember = GetMemberByName( rName ); // make sure it exists and is in the hash
maMemberList.remove( pMember );
MemberList::iterator aIter = maMemberList.begin();
for (sal_Int32 i=0; i<nNewPos && aIter != maMemberList.end(); i++)
++aIter;
maMemberList.insert( aIter, pMember );
}
void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xDim )
{
uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
OSL_ENSURE( xDimProp.is(), "no properties at dimension" );
if ( xDimProp.is() )
{
// exceptions are caught at ScDPSaveData::WriteToSource
uno::Any aAny;
sheet::DataPilotFieldOrientation eOrient = (sheet::DataPilotFieldOrientation)nOrientation;
aAny <<= eOrient;
xDimProp->setPropertyValue( OUString(SC_UNO_DP_ORIENTATION), aAny );
sheet::GeneralFunction eFunc = (sheet::GeneralFunction)nFunction;
aAny <<= eFunc;
xDimProp->setPropertyValue( OUString(SC_UNO_DP_FUNCTION), aAny );
if ( nUsedHierarchy >= 0 )
{
aAny <<= (sal_Int32)nUsedHierarchy;
xDimProp->setPropertyValue( OUString(SC_UNO_DP_USEDHIERARCHY), aAny );
}
if ( pReferenceValue )
{
aAny <<= *pReferenceValue;
xDimProp->setPropertyValue( OUString(SC_UNO_DP_REFVALUE), aAny );
}
if (mpLayoutName)
ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_LAYOUTNAME, *mpLayoutName);
const OUString* pSubTotalName = GetSubtotalName();
if (pSubTotalName)
// Custom subtotal name, with '?' being replaced by the visible field name later.
ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_FIELD_SUBTOTALNAME, *pSubTotalName);
}
// Level loop outside of maMemberList loop
// because SubTotals have to be set independently of known members
long nCount = maMemberHash.size();
long nHierCount = 0;
uno::Reference<container::XIndexAccess> xHiers;
uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
if ( xHierSupp.is() )
{
uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
xHiers = new ScNameToIndexAccess( xHiersName );
nHierCount = xHiers->getCount();
}
bool bHasHiddenMember = false;
for (long nHier=0; nHier<nHierCount; nHier++)
{
uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) );
long nLevCount = 0;
uno::Reference<container::XIndexAccess> xLevels;
uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHierarchy, uno::UNO_QUERY );
if ( xLevSupp.is() )
{
uno::Reference<container::XNameAccess> xLevelsName = xLevSupp->getLevels();
xLevels = new ScNameToIndexAccess( xLevelsName );
nLevCount = xLevels->getCount();
}
for (long nLev=0; nLev<nLevCount; nLev++)
{
uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(nLev) );
uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
OSL_ENSURE( xLevProp.is(), "no properties at level" );
if ( xLevProp.is() )
{
uno::Any aAny;
if ( !bSubTotalDefault )
{
if ( !pSubTotalFuncs )
nSubTotalCount = 0;
uno::Sequence<sheet::GeneralFunction> aSeq(nSubTotalCount);
sheet::GeneralFunction* pArray = aSeq.getArray();
for (long i=0; i<nSubTotalCount; i++)
pArray[i] = (sheet::GeneralFunction)pSubTotalFuncs[i];
aAny <<= aSeq;
xLevProp->setPropertyValue( OUString(SC_UNO_DP_SUBTOTAL), aAny );
}
if ( nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW )
lcl_SetBoolProperty( xLevProp,
OUString(SC_UNO_DP_SHOWEMPTY), (bool)nShowEmptyMode );
if ( pSortInfo )
ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_SORTING, *pSortInfo);
if ( pAutoShowInfo )
ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_AUTOSHOW, *pAutoShowInfo);
if ( pLayoutInfo )
ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_DP_LAYOUT, *pLayoutInfo);
// exceptions are caught at ScDPSaveData::WriteToSource
}
if ( nCount > 0 )
{
uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevel, uno::UNO_QUERY );
if ( xMembSupp.is() )
{
uno::Reference<container::XNameAccess> xMembers = xMembSupp->getMembers();
if ( xMembers.is() )
{
sal_Int32 nPosition = -1; // set position only in manual mode
if ( !pSortInfo || pSortInfo->Mode == sheet::DataPilotFieldSortMode::MANUAL )
nPosition = 0;
for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; ++i)
{
ScDPSaveMember* pMember = *i;
if (!pMember->GetIsVisible())
bHasHiddenMember = true;
OUString aMemberName = pMember->GetName();
if ( xMembers->hasByName( aMemberName ) )
{
uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
xMembers->getByName( aMemberName ) );
pMember->WriteToSource( xMemberInt, nPosition );
if ( nPosition >= 0 )
++nPosition; // increase if initialized
}
// missing member is no error
}
}
}
}
}
}
if (xDimProp.is())
ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_HAS_HIDDEN_MEMBER, bHasHiddenMember);
}
void ScDPSaveDimension::UpdateMemberVisibility(const boost::unordered_map<OUString, bool, OUStringHash>& rData)
{
typedef boost::unordered_map<OUString, bool, OUStringHash> DataMap;
MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
for (; itrMem != itrMemEnd; ++itrMem)
{
ScDPSaveMember* pMem = *itrMem;
const OUString& rMemName = pMem->GetName();
DataMap::const_iterator itr = rData.find(rMemName);
if (itr != rData.end())
pMem->SetIsVisible(itr->second);
}
}
bool ScDPSaveDimension::HasInvisibleMember() const
{
MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
for (; itrMem != itrMemEnd; ++itrMem)
{
const ScDPSaveMember* pMem = *itrMem;
if (!pMem->GetIsVisible())
return true;
}
return false;
}
void ScDPSaveDimension::RemoveObsoleteMembers(const MemberSetType& rMembers)
{
maMemberHash.clear();
MemberList aNew;
MemberList::iterator it = maMemberList.begin(), itEnd = maMemberList.end();
for (; it != itEnd; ++it)
{
ScDPSaveMember* pMem = *it;
if (rMembers.count(pMem->GetName()))
{
// This member still exists.
maMemberHash.insert(MemberHash::value_type(pMem->GetName(), pMem));
aNew.push_back(pMem);
}
else
{
// This member no longer exists.
delete pMem;
}
}
maMemberList.swap(aNew);
}
#if DEBUG_PIVOT_TABLE
void ScDPSaveDimension::Dump(int nIndent) const
{
static const char* pOrientNames[] = { "hidden", "column", "row", "page", "data" };
std::string aIndent(nIndent*4, ' ');
cout << aIndent << "* dimension name: '" << aName << "'" << endl;
cout << aIndent << " + orientation: ";
if (nOrientation <= 4)
cout << pOrientNames[nOrientation];
else
cout << "(invalid)";
cout << endl;
cout << aIndent << " + layout name: ";
if (mpLayoutName)
cout << "'" << *mpLayoutName << "'";
else
cout << "(none)";
cout << endl;
cout << aIndent << " + subtotal name: ";
if (mpSubtotalName)
cout << "'" << *mpSubtotalName << "'";
else
cout << "(none)";
cout << endl;
cout << aIndent << " + is data layout: " << (bIsDataLayout ? "yes" : "no") << endl;
cout << aIndent << " + is duplicate: " << (bDupFlag ? "yes" : "no") << endl;
MemberList::const_iterator itMem = maMemberList.begin(), itMemEnd = maMemberList.end();
for (; itMem != itMemEnd; ++itMem)
{
ScDPSaveMember* pMem = *itMem;
pMem->Dump(nIndent+1);
}
cout << endl; // blank line
}
#endif
ScDPSaveData::ScDPSaveData() :
pDimensionData( NULL ),
nColumnGrandMode( SC_DPSAVEMODE_DONTKNOW ),
nRowGrandMode( SC_DPSAVEMODE_DONTKNOW ),
nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
bFilterButton( true ),
bDrillDown( true ),
mbDimensionMembersBuilt(false),
mpGrandTotalName(NULL)
{
}
ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
nColumnGrandMode( r.nColumnGrandMode ),
nRowGrandMode( r.nRowGrandMode ),
nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
nRepeatEmptyMode( r.nRepeatEmptyMode ),
bFilterButton( r.bFilterButton ),
bDrillDown( r.bDrillDown ),
mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
mpGrandTotalName(NULL),
mpDimOrder(NULL)
{
if ( r.pDimensionData )
pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData );
else
pDimensionData = NULL;
aDimList = r.aDimList.clone();
if (r.mpGrandTotalName)
mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
}
ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
{
if ( &r != this )
{
this->~ScDPSaveData();
new( this ) ScDPSaveData ( r );
}
return *this;
}
bool ScDPSaveData::operator== ( const ScDPSaveData& r ) const
{
if ( nColumnGrandMode != r.nColumnGrandMode ||
nRowGrandMode != r.nRowGrandMode ||
nIgnoreEmptyMode != r.nIgnoreEmptyMode ||
nRepeatEmptyMode != r.nRepeatEmptyMode ||
bFilterButton != r.bFilterButton ||
bDrillDown != r.bDrillDown ||
mbDimensionMembersBuilt != r.mbDimensionMembersBuilt)
return false;
if ( pDimensionData || r.pDimensionData )
if ( !pDimensionData || !r.pDimensionData || !( *pDimensionData == *r.pDimensionData ) )
return false;
if ( aDimList.size() != r.aDimList.size() )
return false;
if (aDimList != r.aDimList)
return false;
if (mpGrandTotalName)
{
if (!r.mpGrandTotalName)
return false;
if (!mpGrandTotalName->equals(*r.mpGrandTotalName))
return false;
}
else if (r.mpGrandTotalName)
return false;
return true;
}
ScDPSaveData::~ScDPSaveData()
{
delete pDimensionData;
}
void ScDPSaveData::SetGrandTotalName(const OUString& rName)
{
mpGrandTotalName.reset(new OUString(rName));
}
const OUString* ScDPSaveData::GetGrandTotalName() const
{
return mpGrandTotalName.get();
}
namespace {
class DimOrderInserter : std::unary_function<const ScDPSaveDimension*, void>
{
ScDPSaveData::DimOrderType& mrNames;
public:
DimOrderInserter(ScDPSaveData::DimOrderType& rNames) : mrNames(rNames) {}
void operator() (const ScDPSaveDimension* pDim)
{
size_t nRank = mrNames.size();
mrNames.insert(
ScDPSaveData::DimOrderType::value_type(pDim->GetName(), nRank));
}
};
}
const ScDPSaveData::DimOrderType& ScDPSaveData::GetDimensionSortOrder() const
{
if (!mpDimOrder)
{
mpDimOrder.reset(new DimOrderType);
std::vector<const ScDPSaveDimension*> aRowDims, aColDims;
GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aRowDims);
GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aColDims);
std::for_each(aRowDims.begin(), aRowDims.end(), DimOrderInserter(*mpDimOrder));
std::for_each(aColDims.begin(), aColDims.end(), DimOrderInserter(*mpDimOrder));
}
return *mpDimOrder;
}
void ScDPSaveData::GetAllDimensionsByOrientation(
sheet::DataPilotFieldOrientation eOrientation, std::vector<const ScDPSaveDimension*>& rDims) const
{
std::vector<const ScDPSaveDimension*> aDims;
DimsType::const_iterator it = aDimList.begin(), itEnd = aDimList.end();
for (; it != itEnd; ++it)
{
const ScDPSaveDimension& rDim = *it;
if (rDim.GetOrientation() != static_cast<sal_uInt16>(eOrientation))
continue;
aDims.push_back(&rDim);
}
rDims.swap(aDims);
}
void ScDPSaveData::AddDimension(ScDPSaveDimension* pDim)
{
if (!pDim)
return;
CheckDuplicateName(*pDim);
aDimList.push_back(pDim);
DimensionsChanged();
}
ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const OUString& rName)
{
boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
if (iter->GetName() == rName && !iter->IsDataLayout() )
return const_cast<ScDPSaveDimension*>(&(*iter));
}
return AppendNewDimension(rName, false);
}
ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const OUString& rName) const
{
boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
if (iter->GetName() == rName && !iter->IsDataLayout() )
return const_cast<ScDPSaveDimension*>(&(*iter));
}
return NULL; // don't create new
}
ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const OUString& rName)
{
boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
if (iter->GetName() == rName && !iter->IsDataLayout() )
return DuplicateDimension(rName);
}
return AppendNewDimension(rName, false);
}
ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
{
ScDPSaveDimension* pDim = GetExistingDataLayoutDimension();
if (pDim)
return pDim;
return AppendNewDimension(OUString(), true);
}
ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const
{
boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
if ( iter->IsDataLayout() )
return const_cast<ScDPSaveDimension*>(&(*iter));
}
return NULL;
}
ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const OUString& rName)
{
// always insert new
ScDPSaveDimension* pOld = GetExistingDimensionByName(rName);
if (!pOld)
return NULL;
ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld );
AddDimension(pNew);
return pNew;
}
void ScDPSaveData::RemoveDimensionByName(const OUString& rName)
{
boost::ptr_vector<ScDPSaveDimension>::iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
if (iter->GetName() != rName || iter->IsDataLayout())
continue;
aDimList.erase(iter);
RemoveDuplicateNameCount(rName);
DimensionsChanged();
return;
}
}
ScDPSaveDimension& ScDPSaveData::DuplicateDimension( const ScDPSaveDimension& rDim )
{
ScDPSaveDimension* pNew = new ScDPSaveDimension( rDim );
AddDimension(pNew);
return *pNew;
}
ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(sal_uInt16 nOrientation)
{
// return the innermost dimension for the given orientation,
// excluding data layout dimension
boost::ptr_vector<ScDPSaveDimension>::const_reverse_iterator iter;
for (iter = aDimList.rbegin(); iter != aDimList.rend(); ++iter)
{
if (iter->GetOrientation() == nOrientation && !iter->IsDataLayout())
return const_cast<ScDPSaveDimension*>(&(*iter));
}
return NULL;
}
ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
{
boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
if (iter->GetOrientation() == eOrientation && !iter->IsDataLayout())
return const_cast<ScDPSaveDimension*>(&(*iter));
}
return NULL;
}
long ScDPSaveData::GetDataDimensionCount() const
{
long nDataCount = 0;
boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
if (iter->GetOrientation() == sheet::DataPilotFieldOrientation_DATA)
++nDataCount;
}
return nDataCount;
}
void ScDPSaveData::SetPosition( ScDPSaveDimension* pDim, long nNew )
{
// position (nNew) is counted within dimensions of the same orientation
sal_uInt16 nOrient = pDim->GetOrientation();
boost::ptr_vector<ScDPSaveDimension>::iterator it;
for ( it = aDimList.begin(); it != aDimList.end(); ++it)
{
if (pDim == &(*it))
{
// Tell ptr_vector to give up ownership of this element. Don't
// delete this instance as it is re-inserted into the container
// later.
aDimList.release(it).release();
break;
}
}
boost::ptr_vector<ScDPSaveDimension>::iterator iterInsert = aDimList.begin();
while ( nNew > 0 && iterInsert != aDimList.end())
{
if (iterInsert->GetOrientation() == nOrient )
--nNew;
++iterInsert;
}
aDimList.insert(iterInsert,pDim);
DimensionsChanged();
}
void ScDPSaveData::SetColumnGrand(bool bSet)
{
nColumnGrandMode = sal_uInt16(bSet);
}
void ScDPSaveData::SetRowGrand(bool bSet)
{
nRowGrandMode = sal_uInt16(bSet);
}
void ScDPSaveData::SetIgnoreEmptyRows(bool bSet)
{
nIgnoreEmptyMode = sal_uInt16(bSet);
}
void ScDPSaveData::SetRepeatIfEmpty(bool bSet)
{
nRepeatEmptyMode = sal_uInt16(bSet);
}
void ScDPSaveData::SetFilterButton(bool bSet)
{
bFilterButton = bSet;
}
void ScDPSaveData::SetDrillDown(bool bSet)
{
bDrillDown = bSet;
}
static void lcl_ResetOrient( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
{
sheet::DataPilotFieldOrientation eOrient = sheet::DataPilotFieldOrientation_HIDDEN;
uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
long nIntCount = xIntDims->getCount();
for (long nIntDim=0; nIntDim<nIntCount; nIntDim++)
{
uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
if (xDimProp.is())
{
uno::Any aAny;
aAny <<= eOrient;
xDimProp->setPropertyValue( OUString(SC_UNO_DP_ORIENTATION), aAny );
}
}
}
void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
{
if (!xSource.is())
return;
// source options must be first!
uno::Reference<beans::XPropertySet> xSourceProp( xSource, uno::UNO_QUERY );
OSL_ENSURE( xSourceProp.is(), "no properties at source" );
if ( xSourceProp.is() )
{
// source options are not available for external sources
//! use XPropertySetInfo to test for availability?
try
{
if ( nIgnoreEmptyMode != SC_DPSAVEMODE_DONTKNOW )
lcl_SetBoolProperty( xSourceProp,
OUString(SC_UNO_DP_IGNOREEMPTY), (bool)nIgnoreEmptyMode );
if ( nRepeatEmptyMode != SC_DPSAVEMODE_DONTKNOW )
lcl_SetBoolProperty( xSourceProp,
OUString(SC_UNO_DP_REPEATEMPTY), (bool)nRepeatEmptyMode );
}
catch(uno::Exception&)
{
// no error
}
const OUString* pGrandTotalName = GetGrandTotalName();
if (pGrandTotalName)
ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_DP_GRANDTOTAL_NAME, *pGrandTotalName);
}
// exceptions in the other calls are errors
try
{
// reset all orientations
//! "forgetSettings" or similar at source ?????
//! reset all duplicated dimensions, or reuse them below !!!
OSL_FAIL( "ScDPSaveData::WriteToSource" );
lcl_ResetOrient( xSource );
uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
long nIntCount = xIntDims->getCount();
boost::ptr_vector<ScDPSaveDimension>::iterator iter = aDimList.begin();
for (long i = 0; iter != aDimList.end(); ++iter, ++i)
{
OUString aName = iter->GetName();
OUString aCoreName = ScDPUtil::getSourceDimensionName(aName);
OSL_TRACE( "%s", aName.getStr() );
bool bData = iter->IsDataLayout();
//! getByName for ScDPSource, including DataLayoutDimension !!!!!!!!
bool bFound = false;
for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
{
uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
if ( bData )
{
uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
if ( xDimProp.is() )
{
bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
OUString(SC_UNO_DP_ISDATALAYOUT) );
//! error checking -- is "IsDataLayoutDimension" property required??
}
}
else
{
uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
if (xDimName.is() && xDimName->getName() == aCoreName)
bFound = true;
}
if (bFound)
{
if (iter->GetDupFlag())
{
uno::Reference<util::XCloneable> xCloneable(xIntDim, uno::UNO_QUERY);
OSL_ENSURE(xCloneable.is(), "cannot clone dimension");
if (xCloneable.is())
{
uno::Reference<util::XCloneable> xNew = xCloneable->createClone();
uno::Reference<container::XNamed> xNewName(xNew, uno::UNO_QUERY);
if (xNewName.is())
{
xNewName->setName(aName);
iter->WriteToSource(xNew);
}
}
}
else
iter->WriteToSource( xIntDim );
}
}
OSL_ENSURE(bFound, "WriteToSource: Dimension not found");
}
if ( xSourceProp.is() )
{
if ( nColumnGrandMode != SC_DPSAVEMODE_DONTKNOW )
lcl_SetBoolProperty( xSourceProp,
OUString(SC_UNO_DP_COLGRAND), (bool)nColumnGrandMode );
if ( nRowGrandMode != SC_DPSAVEMODE_DONTKNOW )
lcl_SetBoolProperty( xSourceProp,
OUString(SC_UNO_DP_ROWGRAND), (bool)nRowGrandMode );
}
}
catch(uno::Exception&)
{
OSL_FAIL("exception in WriteToSource");
}
}
bool ScDPSaveData::IsEmpty() const
{
boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
if (iter->GetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN && !iter->IsDataLayout())
return false;
}
return true; // no entries that are not hidden
}
void ScDPSaveData::RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames )
{
if (!pDimensionData)
// No group dimensions exist. Nothing to do.
return;
// Remove numeric group dimension (exists once at most). No need to delete
// anything in save data (grouping was done inplace in an existing base
// dimension).
pDimensionData->RemoveNumGroupDimension(rSrcDimName);
// Remove named group dimension(s). Dimensions have to be removed from
// dimension save data and from save data too.
const ScDPSaveGroupDimension* pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
while ( pExistingGroup )
{
OUString aGroupDimName = pExistingGroup->GetGroupDimName();
pDimensionData->RemoveGroupDimension(aGroupDimName); // pExistingGroup is deleted
// also remove SaveData settings for the dimension that no longer exists
RemoveDimensionByName(aGroupDimName);
if (pDeletedNames)
pDeletedNames->push_back(aGroupDimName);
// see if there are more group dimensions
pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
{
// still get the same group dimension?
OSL_FAIL("couldn't remove group dimension");
pExistingGroup = NULL; // avoid endless loop
}
}
}
ScDPDimensionSaveData* ScDPSaveData::GetDimensionData()
{
if (!pDimensionData)
pDimensionData = new ScDPDimensionSaveData;
return pDimensionData;
}
void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData* pNew )
{
delete pDimensionData;
if ( pNew )
pDimensionData = new ScDPDimensionSaveData( *pNew );
else
pDimensionData = NULL;
}
void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
{
if (mbDimensionMembersBuilt)
return;
// First, build a dimension name-to-index map.
typedef boost::unordered_map<OUString, long, OUStringHash> NameIndexMap;
NameIndexMap aMap;
long nColCount = pData->GetColumnCount();
for (long i = 0; i < nColCount; ++i)
aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i));
NameIndexMap::const_iterator itrEnd = aMap.end();
boost::ptr_vector<ScDPSaveDimension>::iterator iter;
for (iter = aDimList.begin(); iter != aDimList.end(); ++iter)
{
const OUString& rDimName = iter->GetName();
if (rDimName.isEmpty())
// empty dimension name. It must be data layout.
continue;
NameIndexMap::const_iterator itr = aMap.find(rDimName);
if (itr == itrEnd)
// dimension name not in the data. This should never happen!
continue;
long nDimIndex = itr->second;
const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
size_t mMemberCount = rMembers.size();
for (size_t j = 0; j < mMemberCount; ++j)
{
const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] );
OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData);
if (iter->GetExistingMemberByName(aMemName))
// this member instance already exists. nothing to do.
continue;
auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName));
pNewMember->SetIsVisible(true);
iter->AddMember(pNewMember.release());
}
}
mbDimensionMembersBuilt = true;
}
void ScDPSaveData::SyncAllDimensionMembers(ScDPTableData* pData)
{
typedef boost::unordered_map<OUString, long, OUStringHash> NameIndexMap;
// First, build a dimension name-to-index map.
NameIndexMap aMap;
long nColCount = pData->GetColumnCount();
for (long i = 0; i < nColCount; ++i)
aMap.insert(NameIndexMap::value_type(pData->getDimensionName(i), i));
NameIndexMap::const_iterator itMapEnd = aMap.end();
DimsType::iterator it = aDimList.begin(), itEnd = aDimList.end();
for (it = aDimList.begin(); it != itEnd; ++it)
{
const OUString& rDimName = it->GetName();
if (rDimName.isEmpty())
// empty dimension name. It must be data layout.
continue;
NameIndexMap::const_iterator itMap = aMap.find(rDimName);
if (itMap == itMapEnd)
// dimension name not in the data. This should never happen!
continue;
ScDPSaveDimension::MemberSetType aMemNames;
long nDimIndex = itMap->second;
const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
size_t nMemberCount = rMembers.size();
for (size_t j = 0; j < nMemberCount; ++j)
{
const ScDPItemData* pMemberData = pData->GetMemberById(nDimIndex, rMembers[j]);
OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData);
aMemNames.insert(aMemName);
}
it->RemoveObsoleteMembers(aMemNames);
}
}
bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
{
ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName);
if (!pDim)
return false;
return pDim->HasInvisibleMember();
}
#if DEBUG_PIVOT_TABLE
void ScDPSaveData::Dump() const
{
DimsType::const_iterator itDim = aDimList.begin(), itDimEnd = aDimList.end();
for (; itDim != itDimEnd; ++itDim)
{
const ScDPSaveDimension& rDim = *itDim;
rDim.Dump();
}
}
#endif
void ScDPSaveData::CheckDuplicateName(ScDPSaveDimension& rDim)
{
const OUString aName = ScDPUtil::getSourceDimensionName(rDim.GetName());
DupNameCountType::iterator it = maDupNameCounts.find(aName);
if (it != maDupNameCounts.end())
{
rDim.SetName(ScDPUtil::createDuplicateDimensionName(aName, ++it->second));
rDim.SetDupFlag(true);
}
else
// New name.
maDupNameCounts.insert(DupNameCountType::value_type(aName, 0));
}
void ScDPSaveData::RemoveDuplicateNameCount(const OUString& rName)
{
OUString aCoreName = rName;
if (ScDPUtil::isDuplicateDimension(rName))
aCoreName = ScDPUtil::getSourceDimensionName(rName);
DupNameCountType::iterator it = maDupNameCounts.find(aCoreName);
if (it == maDupNameCounts.end())
return;
if (!it->second)
{
maDupNameCounts.erase(it);
return;
}
--it->second;
return;
}
ScDPSaveDimension* ScDPSaveData::AppendNewDimension(const OUString& rName, bool bDataLayout)
{
if (ScDPUtil::isDuplicateDimension(rName))
// This call is for original dimensions only.
return NULL;
ScDPSaveDimension* pNew = new ScDPSaveDimension(rName, bDataLayout);
aDimList.push_back(pNew);
if (!maDupNameCounts.count(rName))
maDupNameCounts.insert(DupNameCountType::value_type(rName, 0));
DimensionsChanged();
return pNew;
}
void ScDPSaveData::DimensionsChanged()
{
mpDimOrder.reset();
}
bool operator == (const ::com::sun::star::sheet::DataPilotFieldSortInfo &l, const ::com::sun::star::sheet::DataPilotFieldSortInfo &r )
{
return l.Field == r.Field && l.IsAscending == r.IsAscending && l.Mode == r.Mode;
}
bool operator == (const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &l, const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &r )
{
return l.IsEnabled == r.IsEnabled &&
l.ShowItemsMode == r.ShowItemsMode &&
l.ItemCount == r.ItemCount &&
l.DataField == r.DataField;
}
bool operator == (const ::com::sun::star::sheet::DataPilotFieldReference &l, const ::com::sun::star::sheet::DataPilotFieldReference &r )
{
return l.ReferenceType == r.ReferenceType &&
l.ReferenceField == r.ReferenceField &&
l.ReferenceItemType == r.ReferenceItemType &&
l.ReferenceItemName == r.ReferenceItemName;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */