/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: dpsave.cxx,v $ * $Revision: 1.13.32.3 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" // INCLUDE --------------------------------------------------------------- #include "dpsave.hxx" #include "dpdimsave.hxx" #include "miscuno.hxx" #include "scerrors.hxx" #include "unonames.hxx" #include "global.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Any; using ::rtl::OUString; using ::rtl::OUStringHash; using ::std::hash_map; using ::std::auto_ptr; // ----------------------------------------------------------------------- #define SC_DPSAVEMODE_NO 0 #define SC_DPSAVEMODE_YES 1 #define SC_DPSAVEMODE_DONTKNOW 2 // ----------------------------------------------------------------------- //! move to a header file //! use names from unonames.hxx? #define DP_PROP_COLUMNGRAND "ColumnGrand" #define DP_PROP_FUNCTION "Function" #define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows" #define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension" #define DP_PROP_ISVISIBLE "IsVisible" #define DP_PROP_ORIENTATION "Orientation" #define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty" #define DP_PROP_ROWGRAND "RowGrand" #define DP_PROP_SHOWDETAILS "ShowDetails" #define DP_PROP_SHOWEMPTY "ShowEmpty" #define DP_PROP_SUBTOTALS "SubTotals" #define DP_PROP_USEDHIERARCHY "UsedHierarchy" #define DP_PROP_FILTER "Filter" #define DP_PROP_POSITION "Position" // ----------------------------------------------------------------------- void lcl_SetBoolProperty( const uno::Reference& xProp, const rtl::OUString& rName, sal_Bool bValue ) { //! move to ScUnoHelpFunctions? xProp->setPropertyValue( rName, uno::Any( &bValue, getBooleanCppuType() ) ); } // ----------------------------------------------------------------------- ScDPSaveMember::ScDPSaveMember(const String& 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.get()) 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 = bSet; } BOOL ScDPSaveMember::HasShowDetails() const { return nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW; } void ScDPSaveMember::SetShowDetails(BOOL bSet) { nShowDetailsMode = bSet; } void ScDPSaveMember::SetName( const String& 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(NULL); } void ScDPSaveMember::WriteToSource( const uno::Reference& xMember, sal_Int32 nPosition ) { uno::Reference xMembProp( xMember, uno::UNO_QUERY ); DBG_ASSERT( xMembProp.is(), "no properties at member" ); if ( xMembProp.is() ) { // exceptions are caught at ScDPSaveData::WriteToSource if ( nVisibleMode != SC_DPSAVEMODE_DONTKNOW ) lcl_SetBoolProperty( xMembProp, rtl::OUString::createFromAscii(DP_PROP_ISVISIBLE), (BOOL)nVisibleMode ); if ( nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW ) lcl_SetBoolProperty( xMembProp, rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode ); if (mpLayoutName.get()) ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_LAYOUTNAME, *mpLayoutName); if ( nPosition >= 0 ) ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, DP_PROP_POSITION, nPosition); } } // ----------------------------------------------------------------------- ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) : aName( rName ), pSelectedPage( NULL ), 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 USHORT[nSubTotalCount]; for (long nSub=0; nSubGetName(); 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.pSelectedPage) pSelectedPage = new String( *(r.pSelectedPage) ); else pSelectedPage = NULL; if (r.mpLayoutName.get()) mpLayoutName.reset(new OUString(*r.mpLayoutName)); if (r.mpSubtotalName.get()) 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 pSelectedPage; 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; iGetName(); MemberHash::iterator aExisting = maMemberHash.find( rName ); if ( aExisting == maMemberHash.end() ) { std::pair< const String, 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 String& 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(USHORT nNew) { nOrientation = nNew; } void ScDPSaveDimension::SetSubTotals(long nCount, const USHORT* pFuncs) { if (pSubTotalFuncs) delete [] pSubTotalFuncs; nSubTotalCount = nCount; if ( nCount && pFuncs ) { pSubTotalFuncs = new USHORT[nCount]; for (long i=0; iGetName())) 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(NULL); } 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 String* pPage ) { delete pSelectedPage; if (pPage) pSelectedPage = new String( *pPage ); else pSelectedPage = NULL; } BOOL ScDPSaveDimension::HasCurrentPage() const { return ( pSelectedPage != NULL ); } const String& ScDPSaveDimension::GetCurrentPage() const { if (pSelectedPage) return *pSelectedPage; return EMPTY_STRING; } ScDPSaveMember* ScDPSaveDimension::GetExistingMemberByName(const String& rName) { MemberHash::const_iterator res = maMemberHash.find (rName); if (res != maMemberHash.end()) return res->second; return NULL; } ScDPSaveMember* ScDPSaveDimension::GetMemberByName(const String& 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 String& 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& xDim ) { uno::Reference xDimProp( xDim, uno::UNO_QUERY ); DBG_ASSERT( 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( rtl::OUString::createFromAscii(DP_PROP_ORIENTATION), aAny ); sheet::GeneralFunction eFunc = (sheet::GeneralFunction)nFunction; aAny <<= eFunc; xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FUNCTION), aAny ); if ( nUsedHierarchy >= 0 ) { aAny <<= (INT32)nUsedHierarchy; xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY), aAny ); } if ( pReferenceValue ) { aAny <<= *pReferenceValue; xDimProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_REFVALUE), aAny ); } uno::Sequence aFilter; // set the selected page field only if the dimension is used as page dimension if ( pSelectedPage && nOrientation == sheet::DataPilotFieldOrientation_PAGE ) { // single filter field: first field equal to selected string sheet::TableFilterField aField( sheet::FilterConnection_AND, 0, sheet::FilterOperator_EQUAL, sal_False, 0.0, *pSelectedPage ); aFilter = uno::Sequence( &aField, 1 ); } // else keep empty sequence ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, DP_PROP_FILTER, aFilter); if (mpLayoutName.get()) ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_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_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 xHiers; uno::Reference xHierSupp( xDim, uno::UNO_QUERY ); if ( xHierSupp.is() ) { uno::Reference xHiersName = xHierSupp->getHierarchies(); xHiers = new ScNameToIndexAccess( xHiersName ); nHierCount = xHiers->getCount(); } sal_Bool bHasHiddenMember = false; for (long nHier=0; nHier xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) ); long nLevCount = 0; uno::Reference xLevels; uno::Reference xLevSupp( xHierarchy, uno::UNO_QUERY ); if ( xLevSupp.is() ) { uno::Reference xLevelsName = xLevSupp->getLevels(); xLevels = new ScNameToIndexAccess( xLevelsName ); nLevCount = xLevels->getCount(); } for (long nLev=0; nLev xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(nLev) ); uno::Reference xLevProp( xLevel, uno::UNO_QUERY ); DBG_ASSERT( xLevProp.is(), "no properties at level" ); if ( xLevProp.is() ) { uno::Any aAny; if ( !bSubTotalDefault ) { if ( !pSubTotalFuncs ) nSubTotalCount = 0; uno::Sequence aSeq(nSubTotalCount); sheet::GeneralFunction* pArray = aSeq.getArray(); for (long i=0; isetPropertyValue( rtl::OUString::createFromAscii(DP_PROP_SUBTOTALS), aAny ); } if ( nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW ) lcl_SetBoolProperty( xLevProp, rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY), (BOOL)nShowEmptyMode ); if ( pSortInfo ) ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_SORTING, *pSortInfo); if ( pAutoShowInfo ) ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_AUTOSHOW, *pAutoShowInfo); if ( pLayoutInfo ) ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_LAYOUT, *pLayoutInfo); // exceptions are caught at ScDPSaveData::WriteToSource } if ( nCount > 0 ) { uno::Reference xMembSupp( xLevel, uno::UNO_QUERY ); if ( xMembSupp.is() ) { uno::Reference 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; rtl::OUString aMemberName = pMember->GetName(); if ( xMembers->hasByName( aMemberName ) ) { uno::Reference 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_HAS_HIDDEN_MEMBER, bHasHiddenMember); } void ScDPSaveDimension::UpdateMemberVisibility(const hash_map& rData) { typedef hash_map DataMap; MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end(); for (; itrMem != itrMemEnd; ++itrMem) { ScDPSaveMember* pMem = *itrMem; const String& 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; } // ----------------------------------------------------------------------- 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) { if ( r.pDimensionData ) pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData ); else pDimensionData = NULL; long nCount = r.aDimList.Count(); for (long i=0; iequals(*r.mpGrandTotalName)) return false; } else if (r.mpGrandTotalName.get()) return false; return TRUE; } ScDPSaveData::~ScDPSaveData() { long nCount = aDimList.Count(); for (long i=0; iGetName() == rName && !pDim->IsDataLayout() ) return pDim; } ScDPSaveDimension* pNew = new ScDPSaveDimension( rName, FALSE ); aDimList.Insert( pNew, LIST_APPEND ); return pNew; } ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName) const { long nCount = aDimList.Count(); for (long i=0; iGetName() == rName && !pDim->IsDataLayout() ) return pDim; } return NULL; // don't create new } ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const String& rName) { long nCount = aDimList.Count(); for (long i=0; iGetName() == rName && !pDim->IsDataLayout() ) return DuplicateDimension(rName); } ScDPSaveDimension* pNew = new ScDPSaveDimension( rName, FALSE ); aDimList.Insert( pNew, LIST_APPEND ); return pNew; } ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension() { ScDPSaveDimension* pDim = GetExistingDataLayoutDimension(); if (pDim) return pDim; ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE ); aDimList.Insert( pNew, LIST_APPEND ); return pNew; } ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const { long nCount = aDimList.Count(); for (long i=0; iIsDataLayout() ) return pDim; } return NULL; } ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName) { // always insert new //! check if dimension is there? ScDPSaveDimension* pOld = GetDimensionByName( rName ); ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld ); pNew->SetDupFlag( TRUE ); aDimList.Insert( pNew, LIST_APPEND ); return pNew; } void ScDPSaveData::RemoveDimensionByName(const String& rName) { long nCount = aDimList.Count(); for (long i=0; iGetName() == rName && !pDim->IsDataLayout() ) { delete pDim; aDimList.Remove(i); break; } } } ScDPSaveDimension& ScDPSaveData::DuplicateDimension( const ScDPSaveDimension& rDim ) { ScDPSaveDimension* pNew = new ScDPSaveDimension( rDim ); pNew->SetDupFlag( TRUE ); aDimList.Insert( pNew, LIST_APPEND ); return *pNew; } ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(USHORT nOrientation) { // return the innermost dimension for the given orientation, // excluding data layout dimension ScDPSaveDimension* pInner = NULL; long nCount = aDimList.Count(); for (long i=0; i(aDimList.GetObject(i)); if ( pDim->GetOrientation() == nOrientation && !pDim->IsDataLayout() ) pInner = pDim; } return pInner; // the last matching one } ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation) { long nCount = aDimList.Count(); for (long i = 0; i < nCount; ++i) { ScDPSaveDimension* pDim = static_cast(aDimList.GetObject(i)); if (pDim->GetOrientation() == eOrientation && !pDim->IsDataLayout()) return pDim; } return NULL; } long ScDPSaveData::GetDataDimensionCount() const { long nDataCount = 0; long nCount = aDimList.Count(); for (long i=0; i(aDimList.GetObject(i)); if ( pDim->GetOrientation() == sheet::DataPilotFieldOrientation_DATA ) ++nDataCount; } return nDataCount; } void ScDPSaveData::SetPosition( ScDPSaveDimension* pDim, long nNew ) { // position (nNew) is counted within dimensions of the same orientation USHORT nOrient = pDim->GetOrientation(); aDimList.Remove( pDim ); ULONG nCount = aDimList.Count(); // after remove ULONG nInsPos = 0; while ( nNew > 0 && nInsPos < nCount ) { if ( ((ScDPSaveDimension*)aDimList.GetObject(nInsPos))->GetOrientation() == nOrient ) --nNew; ++nInsPos; } aDimList.Insert( pDim, nInsPos ); } void ScDPSaveData::SetColumnGrand(BOOL bSet) { nColumnGrandMode = bSet; } void ScDPSaveData::SetRowGrand(BOOL bSet) { nRowGrandMode = bSet; } void ScDPSaveData::SetIgnoreEmptyRows(BOOL bSet) { nIgnoreEmptyMode = bSet; } void ScDPSaveData::SetRepeatIfEmpty(BOOL bSet) { nRepeatEmptyMode = bSet; } void ScDPSaveData::SetFilterButton(BOOL bSet) { bFilterButton = bSet; } void ScDPSaveData::SetDrillDown(BOOL bSet) { bDrillDown = bSet; } void lcl_ResetOrient( const uno::Reference& xSource ) { sheet::DataPilotFieldOrientation eOrient = sheet::DataPilotFieldOrientation_HIDDEN; uno::Reference xDimsName = xSource->getDimensions(); uno::Reference xIntDims = new ScNameToIndexAccess( xDimsName ); long nIntCount = xIntDims->getCount(); for (long nIntDim=0; nIntDim xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) ); uno::Reference xDimProp( xIntDim, uno::UNO_QUERY ); if (xDimProp.is()) { uno::Any aAny; aAny <<= eOrient; xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_ORIENTATION), aAny ); } } } void ScDPSaveData::WriteToSource( const uno::Reference& xSource ) { if (!xSource.is()) return; // source options must be first! uno::Reference xSourceProp( xSource, uno::UNO_QUERY ); DBG_ASSERT( 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, rtl::OUString::createFromAscii(DP_PROP_IGNOREEMPTY), (BOOL)nIgnoreEmptyMode ); if ( nRepeatEmptyMode != SC_DPSAVEMODE_DONTKNOW ) lcl_SetBoolProperty( xSourceProp, rtl::OUString::createFromAscii(DP_PROP_REPEATIFEMPTY), (BOOL)nRepeatEmptyMode ); } catch(uno::Exception&) { // no error } const OUString* pGrandTotalName = GetGrandTotalName(); if (pGrandTotalName) ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_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 !!! lcl_ResetOrient( xSource ); long nCount = aDimList.Count(); for (long i=0; iGetName(); BOOL bData = pDim->IsDataLayout(); //! getByName for ScDPSource, including DataLayoutDimension !!!!!!!! uno::Reference xDimsName = xSource->getDimensions(); uno::Reference xIntDims = new ScNameToIndexAccess( xDimsName ); long nIntCount = xIntDims->getCount(); BOOL bFound = FALSE; for (long nIntDim=0; nIntDim xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) ); if ( bData ) { uno::Reference xDimProp( xIntDim, uno::UNO_QUERY ); if ( xDimProp.is() ) { bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp, rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) ); //! error checking -- is "IsDataLayoutDimension" property required?? } } else { uno::Reference xDimName( xIntDim, uno::UNO_QUERY ); if ( xDimName.is() && xDimName->getName() == aName ) bFound = TRUE; } if ( bFound ) { if ( pDim->GetDupFlag() ) { String aNewName = pDim->GetName(); // different name for each duplication of a (real) dimension... for (long j=0; j<=i; j++) //! Test !!!!!! aNewName += '*'; //! modify name at creation of SaveDimension uno::Reference xCloneable( xIntDim, uno::UNO_QUERY ); DBG_ASSERT( xCloneable.is(), "cannot clone dimension" ); if (xCloneable.is()) { uno::Reference xNew = xCloneable->createClone(); uno::Reference xNewName( xNew, uno::UNO_QUERY ); if (xNewName.is()) { xNewName->setName( aNewName ); pDim->WriteToSource( xNew ); } } } else pDim->WriteToSource( xIntDim ); } } DBG_ASSERT(bFound, "WriteToSource: Dimension not found"); } if ( xSourceProp.is() ) { if ( nColumnGrandMode != SC_DPSAVEMODE_DONTKNOW ) lcl_SetBoolProperty( xSourceProp, rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND), (BOOL)nColumnGrandMode ); if ( nRowGrandMode != SC_DPSAVEMODE_DONTKNOW ) lcl_SetBoolProperty( xSourceProp, rtl::OUString::createFromAscii(DP_PROP_ROWGRAND), (BOOL)nRowGrandMode ); } } catch(uno::Exception&) { DBG_ERROR("exception in WriteToSource"); } } BOOL ScDPSaveData::IsEmpty() const { long nCount = aDimList.Count(); for (long i=0; iGetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN && !pDim->IsDataLayout() ) return FALSE; } return TRUE; // no entries that are not hidden } 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 hash_map 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(); sal_uInt32 n = aDimList.Count(); for (sal_uInt32 i = 0; i < n; ++i) { ScDPSaveDimension* pDim = static_cast(aDimList.GetObject(i)); const String& rDimName = pDim->GetName(); if (!rDimName.Len()) // 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 TypedScStrCollection& rMembers = pData->GetColumnEntries(nDimIndex); sal_uInt16 nMemberCount = rMembers.GetCount(); for (sal_uInt16 j = 0; j < nMemberCount; ++j) { const String& rMemName = rMembers[j]->GetString(); if (pDim->GetExistingMemberByName(rMemName)) // this member instance already exists. nothing to do. continue; auto_ptr pNewMember(new ScDPSaveMember(rMemName)); pNewMember->SetIsVisible(true); pDim->AddMember(pNewMember.release()); } } mbDimensionMembersBuilt = true; } bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const { ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName); if (!pDim) return false; return pDim->HasInvisibleMember(); }