/************************************************************************* * * $RCSfile: dapiuno.cxx,v $ * * $Revision: 1.8 $ * * last change: $Author: sab $ $Date: 2002-09-11 09:52:11 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (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.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #ifdef PCH #include "ui_pch.hxx" #endif #pragma hdrstop #include #include #include "dapiuno.hxx" #include "datauno.hxx" #include "miscuno.hxx" #include "docsh.hxx" #include "pivot.hxx" #include "rangeutl.hxx" #include "unoguard.hxx" #include "dpobject.hxx" #include "dpshttab.hxx" #include "dpsave.hxx" #include "dbdocfun.hxx" #include "unonames.hxx" using namespace com::sun::star; //------------------------------------------------------------------------ const SfxItemPropertyMap* lcl_GetDataPilotFieldMap() { static SfxItemPropertyMap aDataPilotFieldMap_Impl[] = { {MAP_CHAR_LEN(SC_UNONAME_FUNCTION), 0, &getCppuType((sheet::GeneralFunction*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNONAME_ORIENT), 0, &getCppuType((sheet::DataPilotFieldOrientation*)0), 0, 0 }, {0,0,0,0} }; return aDataPilotFieldMap_Impl; } //------------------------------------------------------------------------ SC_SIMPLE_SERVICE_INFO( ScDataPilotDescriptor, "ScDataPilotDescriptor", "stardiv::one::sheet::DataPilotDescriptor" ) SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldObj, "ScDataPilotFieldObj", "com.sun.star.sheet.DataPilotField" ) SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldsObj, "ScDataPilotFieldsObj", "com.sun.star.sheet.DataPilotFields" ) SC_SIMPLE_SERVICE_INFO( ScDataPilotTableObj, "ScDataPilotTableObj", "com.sun.star.sheet.DataPilotTable" ) SC_SIMPLE_SERVICE_INFO( ScDataPilotTablesObj, "ScDataPilotTablesObj", "com.sun.star.sheet.DataPilotTables" ) //------------------------------------------------------------------------ //! irgendwann ueberall die neuen enum-Werte benutzen #define DATA_PILOT_HIDDEN sheet::DataPilotFieldOrientation_HIDDEN #define DATA_PILOT_COLUMN sheet::DataPilotFieldOrientation_COLUMN #define DATA_PILOT_ROW sheet::DataPilotFieldOrientation_ROW #define DATA_PILOT_PAGE sheet::DataPilotFieldOrientation_PAGE #define DATA_PILOT_DATA sheet::DataPilotFieldOrientation_DATA //------------------------------------------------------------------------ USHORT lcl_BitCount( USHORT nBits ) { if (!nBits) return 0; USHORT nCount = 0; USHORT nMask = 1; for (USHORT i=0; i<16; i++) { if ( nBits & nMask ) ++nCount; nMask <<= 1; } return nCount; } USHORT lcl_DataCount( const ScPivotParam& rParam ) { USHORT nRet = 0; for ( USHORT i=0; iGetDocument(); ScDPCollection* pColl = pDoc->GetDPCollection(); if ( pColl ) { USHORT nCount = pColl->GetCount(); for (USHORT i=0; iIsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab && pDPObj->GetName() == rName ) return pDPObj; } } } return NULL; // nicht gefunden } String lcl_ColumnTitle( ScDocument* pDoc, USHORT nCol, USHORT nRow, USHORT nTab ) { // Spaltennamen, wie sie in der Pivottabelle angezeigt werden String aStr; pDoc->GetString(nCol, nRow, nTab, aStr); if (aStr.Len() == 0) aStr = ColToAlpha( nCol ); return aStr; } sheet::GeneralFunction ScDataPilotConversion::FirstFunc( USHORT nBits ) { if ( nBits & PIVOT_FUNC_SUM ) return sheet::GeneralFunction_SUM; if ( nBits & PIVOT_FUNC_COUNT ) return sheet::GeneralFunction_COUNT; if ( nBits & PIVOT_FUNC_AVERAGE ) return sheet::GeneralFunction_AVERAGE; if ( nBits & PIVOT_FUNC_MAX ) return sheet::GeneralFunction_MAX; if ( nBits & PIVOT_FUNC_MIN ) return sheet::GeneralFunction_MIN; if ( nBits & PIVOT_FUNC_PRODUCT ) return sheet::GeneralFunction_PRODUCT; if ( nBits & PIVOT_FUNC_COUNT_NUM ) return sheet::GeneralFunction_COUNTNUMS; if ( nBits & PIVOT_FUNC_STD_DEV ) return sheet::GeneralFunction_STDEV; if ( nBits & PIVOT_FUNC_STD_DEVP ) return sheet::GeneralFunction_STDEVP; if ( nBits & PIVOT_FUNC_STD_VAR ) return sheet::GeneralFunction_VAR; if ( nBits & PIVOT_FUNC_STD_VARP ) return sheet::GeneralFunction_VARP; if ( nBits & PIVOT_FUNC_AUTO ) return sheet::GeneralFunction_AUTO; return sheet::GeneralFunction_NONE; } USHORT ScDataPilotConversion::FunctionBit( sheet::GeneralFunction eFunc ) { USHORT nRet = PIVOT_FUNC_NONE; // 0 switch (eFunc) { case sheet::GeneralFunction_SUM: nRet = PIVOT_FUNC_SUM; break; case sheet::GeneralFunction_COUNT: nRet = PIVOT_FUNC_COUNT; break; case sheet::GeneralFunction_AVERAGE: nRet = PIVOT_FUNC_AVERAGE; break; case sheet::GeneralFunction_MAX: nRet = PIVOT_FUNC_MAX; break; case sheet::GeneralFunction_MIN: nRet = PIVOT_FUNC_MIN; break; case sheet::GeneralFunction_PRODUCT: nRet = PIVOT_FUNC_PRODUCT; break; case sheet::GeneralFunction_COUNTNUMS: nRet = PIVOT_FUNC_COUNT_NUM; break; case sheet::GeneralFunction_STDEV: nRet = PIVOT_FUNC_STD_DEV; break; case sheet::GeneralFunction_STDEVP: nRet = PIVOT_FUNC_STD_DEVP; break; case sheet::GeneralFunction_VAR: nRet = PIVOT_FUNC_STD_VAR; break; case sheet::GeneralFunction_VARP: nRet = PIVOT_FUNC_STD_VARP; break; case sheet::GeneralFunction_AUTO: nRet = PIVOT_FUNC_AUTO; break; } return nRet; } String lcl_CreatePivotName( ScDocShell* pDocShell ) { if (pDocShell) { ScDocument* pDoc = pDocShell->GetDocument(); ScDPCollection* pColl = pDoc->GetDPCollection(); if ( pColl ) return pColl->CreateNewName(); } return String(); // sollte nicht vorkommen } void lcl_SetLayoutNamesToObject( ScDocument* pDoc, const ScPivotParam& rParam, const ScArea& rSrcArea, ScDPObject& rObject ) { // set layout names from LabelData to SaveData //! reset old names? (renamed columns) ScDPSaveData* pOldData = rObject.GetSaveData(); if ( pOldData && rSrcArea.nColEnd >= rSrcArea.nColStart ) { ScDPSaveData aNewData( *pOldData ); USHORT nRow = rSrcArea.nRowStart; USHORT nTab = rSrcArea.nTab; USHORT nCount = rSrcArea.nColEnd - rSrcArea.nColStart + 1; for (USHORT nField = 0; nField < nCount; nField++) { USHORT nCol = rSrcArea.nColStart + nField; String aSourceName = lcl_ColumnTitle( pDoc, nCol, nRow, nTab ); if ( nField < rParam.nLabels && rParam.ppLabelArr && rParam.ppLabelArr[nField] && rParam.ppLabelArr[nField]->pStrColName && rParam.ppLabelArr[nField]->pStrColName->Len() ) { String aLayoutName = *rParam.ppLabelArr[nField]->pStrColName; // create SaveDimension if not there ScDPSaveDimension* pDim = aNewData.GetDimensionByName( aSourceName ); if (pDim) pDim->SetLayoutName( &aLayoutName ); } else { // reset layout name if one was set ScDPSaveDimension* pDim = aNewData.GetExistingDimensionByName( aSourceName ); if (pDim) pDim->ResetLayoutName(); } } rObject.SetSaveData( aNewData ); } } void lcl_SetLayoutNamesToParam( ScPivotParam& rParam, ScDocument* pDoc, const ScArea& rSrcArea, const ScDPObject& rObject ) { // set layout names from SaveData to LabelData ScDPSaveData* pSaveData = rObject.GetSaveData(); if ( pSaveData && rSrcArea.nColEnd >= rSrcArea.nColStart ) { BOOL bAnyFound = FALSE; USHORT nNewCount = rSrcArea.nColEnd - rSrcArea.nColStart + 1; LabelData** ppNewData = new LabelData*[nNewCount]; USHORT nRow = rSrcArea.nRowStart; USHORT nTab = rSrcArea.nTab; for (USHORT nField = 0; nField < nNewCount; nField++) { USHORT nCol = rSrcArea.nColStart + nField; String aSourceName = lcl_ColumnTitle( pDoc, nCol, nRow, nTab ); String aLayoutName; ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName( aSourceName ); if ( pDim && pDim->HasLayoutName() ) { aLayoutName = pDim->GetLayoutName(); if (aLayoutName.Len()) bAnyFound = TRUE; } ppNewData[nField] = new LabelData( aLayoutName, 0, FALSE ); } if ( bAnyFound ) rParam.SetLabelData( ppNewData, nNewCount ); // SetLabelData copies data - ppNewData must be deleted for (USHORT i=0; iGetDocument()->AddUnoObject(*this); } ScDataPilotTablesObj::~ScDataPilotTablesObj() { if (pDocShell) pDocShell->GetDocument()->RemoveUnoObject(*this); } void ScDataPilotTablesObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) { //! Referenz-Update if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) { pDocShell = NULL; // ungueltig geworden } } // XDataPilotTables ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl(USHORT nIndex) { if (pDocShell) { ScDocument* pDoc = pDocShell->GetDocument(); ScDPCollection* pColl = pDoc->GetDPCollection(); if ( pColl ) { // count tables on this sheet // api only handles sheet data at this time //! allow all data sources!!! USHORT nFound = 0; USHORT nCount = pColl->GetCount(); for (USHORT i=0; iIsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab ) { if ( nFound == nIndex ) { String aName = pDPObj->GetName(); return new ScDataPilotTableObj( pDocShell, nTab, aName ); } ++nFound; } } } } return NULL; } ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByName_Impl(const rtl::OUString& aName) { if (hasByName(aName)) { String aNamStr = aName; return new ScDataPilotTableObj( pDocShell, nTab, aNamStr ); } return NULL; } uno::Reference SAL_CALL ScDataPilotTablesObj::createDataPilotDescriptor() throw(uno::RuntimeException) { ScUnoGuard aGuard; if (pDocShell) return new ScDataPilotDescriptor(pDocShell); return NULL; } void SAL_CALL ScDataPilotTablesObj::insertNewByName( const rtl::OUString& aNewName, const table::CellAddress& aOutputAddress, const uno::Reference& xDescriptor ) throw(uno::RuntimeException) { ScUnoGuard aGuard; if (!xDescriptor.is()) return; // inserting with already existing name? if ( aNewName.getLength() && hasByName( aNewName ) ) throw uno::RuntimeException(); // no other exceptions specified BOOL bDone = FALSE; ScDataPilotDescriptorBase* pImp = ScDataPilotDescriptorBase::getImplementation( xDescriptor ); if ( pDocShell && pImp ) { ScPivotParam aParam; ScQueryParam aQuery; ScArea aSrcArea; pImp->GetParam( aParam, aQuery, aSrcArea ); aParam.nCol = (USHORT)aOutputAddress.Column; aParam.nRow = (USHORT)aOutputAddress.Row; aParam.nTab = aOutputAddress.Sheet; // in den Uno-Objekten sind alle Fields in den Descriptoren innerhalb des Bereichs gezaehlt short nFieldStart = aSrcArea.nColStart; USHORT i; for ( i=0; igetTag(); ScDocument* pDoc = pDocShell->GetDocument(); ScPivot* pNewPivot = new ScPivot( pDoc ); pNewPivot->SetName( aName ); pNewPivot->SetTag( aTag ); pNewPivot->SetParam( aParam, aQuery, aSrcArea ); ScDPObject* pNewObj = new ScDPObject( pDoc ); pNewObj->InitFromOldPivot( *pNewPivot, pDoc, TRUE ); lcl_SetLayoutNamesToObject( pDoc, aParam, aSrcArea, *pNewObj ); ScDBDocFunc aFunc(*pDocShell); bDone = aFunc.DataPilotUpdate( NULL, pNewObj, TRUE, TRUE ); delete pNewObj; // DataPilotUpdate copies settings from "new" object delete pNewPivot; } if (!bDone) throw uno::RuntimeException(); // no other exceptions specified } void SAL_CALL ScDataPilotTablesObj::removeByName( const rtl::OUString& aName ) throw(uno::RuntimeException) { ScUnoGuard aGuard; String aNameStr = aName; ScDPObject* pDPObj = lcl_GetDPObject( pDocShell, nTab, aNameStr ); if (pDPObj && pDocShell) { ScDBDocFunc aFunc(*pDocShell); aFunc.DataPilotUpdate( pDPObj, NULL, TRUE, TRUE ); // remove - incl. undo etc. } else throw uno::RuntimeException(); // no other exceptions specified } // XEnumerationAccess uno::Reference SAL_CALL ScDataPilotTablesObj::createEnumeration() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DataPilotTablesEnumeration"))); } // XIndexAccess sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(uno::RuntimeException) { ScUnoGuard aGuard; if ( pDocShell ) { ScDocument* pDoc = pDocShell->GetDocument(); ScDPCollection* pColl = pDoc->GetDPCollection(); if ( pColl ) { // count tables on this sheet // api only handles sheet data at this time //! allow all data sources!!! USHORT nFound = 0; USHORT nCount = pColl->GetCount(); for (USHORT i=0; iIsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab ) ++nFound; } return nFound; } } return 0; } uno::Any SAL_CALL ScDataPilotTablesObj::getByIndex( sal_Int32 nIndex ) throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) { ScUnoGuard aGuard; uno::Reference xTable = GetObjectByIndex_Impl((USHORT)nIndex); uno::Any aAny; if (xTable.is()) aAny <<= xTable; else throw lang::IndexOutOfBoundsException(); return aAny; } uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(uno::RuntimeException) { ScUnoGuard aGuard; return getCppuType((uno::Reference*)0); } sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(uno::RuntimeException) { ScUnoGuard aGuard; return ( getCount() != 0 ); } // XNameAccess uno::Any SAL_CALL ScDataPilotTablesObj::getByName( const rtl::OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { ScUnoGuard aGuard; uno::Reference xTable = GetObjectByName_Impl(aName); uno::Any aAny; if (xTable.is()) aAny <<= xTable; else throw container::NoSuchElementException(); return aAny; } uno::Sequence SAL_CALL ScDataPilotTablesObj::getElementNames() throw(uno::RuntimeException) { ScUnoGuard aGuard; if (pDocShell) { ScDocument* pDoc = pDocShell->GetDocument(); ScDPCollection* pColl = pDoc->GetDPCollection(); if ( pColl ) { // count tables on this sheet // api only handles sheet data at this time //! allow all data sources!!! USHORT nFound = 0; USHORT nCount = pColl->GetCount(); USHORT i; for (i=0; iIsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab ) ++nFound; } USHORT nPos = 0; uno::Sequence aSeq(nFound); rtl::OUString* pAry = aSeq.getArray(); for (i=0; iIsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab ) pAry[nPos++] = pDPObj->GetName(); } return aSeq; } } return uno::Sequence(0); } sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException) { ScUnoGuard aGuard; if (pDocShell) { ScDocument* pDoc = pDocShell->GetDocument(); ScDPCollection* pColl = pDoc->GetDPCollection(); if ( pColl ) { String aNamStr = aName; USHORT nCount = pColl->GetCount(); for (USHORT i=0; iIsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab && pDPObj->GetName() == aNamStr ) return TRUE; } } } return FALSE; } //------------------------------------------------------------------------ ScDataPilotDescriptorBase::ScDataPilotDescriptorBase(ScDocShell* pDocSh) : pDocShell( pDocSh ) { pDocShell->GetDocument()->AddUnoObject(*this); } ScDataPilotDescriptorBase::~ScDataPilotDescriptorBase() { if (pDocShell) pDocShell->GetDocument()->RemoveUnoObject(*this); } uno::Any SAL_CALL ScDataPilotDescriptorBase::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException) { SC_QUERYINTERFACE( sheet::XDataPilotDescriptor ) SC_QUERYINTERFACE( container::XNamed ) // base of XDataPilotDescriptor SC_QUERYINTERFACE( lang::XUnoTunnel ) SC_QUERYINTERFACE( lang::XTypeProvider ) SC_QUERYINTERFACE( lang::XServiceInfo ) return OWeakObject::queryInterface( rType ); } void SAL_CALL ScDataPilotDescriptorBase::acquire() throw() { OWeakObject::acquire(); } void SAL_CALL ScDataPilotDescriptorBase::release() throw() { OWeakObject::release(); } uno::Sequence SAL_CALL ScDataPilotDescriptorBase::getTypes() throw(uno::RuntimeException) { static uno::Sequence aTypes; if ( aTypes.getLength() == 0 ) { aTypes.realloc(4); uno::Type* pPtr = aTypes.getArray(); pPtr[0] = getCppuType((const uno::Reference*)0); pPtr[1] = getCppuType((const uno::Reference*)0); pPtr[2] = getCppuType((const uno::Reference*)0); pPtr[3] = getCppuType((const uno::Reference*)0); } return aTypes; } uno::Sequence SAL_CALL ScDataPilotDescriptorBase::getImplementationId() throw(uno::RuntimeException) { static uno::Sequence< sal_Int8 > aId; if( aId.getLength() == 0 ) { aId.realloc( 16 ); rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True ); } return aId; } void ScDataPilotDescriptorBase::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) { //! Referenz-Update? if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) { pDocShell = NULL; // ungueltig geworden } } // XDataPilotDescriptor table::CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange() throw(uno::RuntimeException) { ScUnoGuard aGuard; ScPivotParam aParam; ScQueryParam aQuery; ScArea aSrcArea; GetParam( aParam, aQuery, aSrcArea ); table::CellRangeAddress aRet; aRet.Sheet = aSrcArea.nTab; aRet.StartColumn = aSrcArea.nColStart; aRet.StartRow = aSrcArea.nRowStart; aRet.EndColumn = aSrcArea.nColEnd; aRet.EndRow = aSrcArea.nRowEnd; return aRet; } void SAL_CALL ScDataPilotDescriptorBase::setSourceRange( const table::CellRangeAddress& aSourceRange ) throw(uno::RuntimeException) { ScUnoGuard aGuard; ScPivotParam aParam; ScQueryParam aQuery; ScArea aSrcArea; GetParam( aParam, aQuery, aSrcArea ); aSrcArea.nTab = aSourceRange.Sheet; aSrcArea.nColStart = (USHORT)aSourceRange.StartColumn; aSrcArea.nRowStart = (USHORT)aSourceRange.StartRow; aSrcArea.nColEnd = (USHORT)aSourceRange.EndColumn; aSrcArea.nRowEnd = (USHORT)aSourceRange.EndRow; SetParam( aParam, aQuery, aSrcArea ); } uno::Reference SAL_CALL ScDataPilotDescriptorBase::getFilterDescriptor() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScDataPilotFilterDescriptor( pDocShell, this ); } uno::Reference SAL_CALL ScDataPilotDescriptorBase::getDataPilotFields() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScDataPilotFieldsObj( this, SC_FIELDORIENT_ALL ); } uno::Reference SAL_CALL ScDataPilotDescriptorBase::getColumnFields() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScDataPilotFieldsObj( this, DATA_PILOT_COLUMN ); } uno::Reference SAL_CALL ScDataPilotDescriptorBase::getRowFields() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScDataPilotFieldsObj( this, DATA_PILOT_ROW ); } uno::Reference SAL_CALL ScDataPilotDescriptorBase::getPageFields() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScDataPilotFieldsObj( this, DATA_PILOT_PAGE ); } uno::Reference SAL_CALL ScDataPilotDescriptorBase::getDataFields() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScDataPilotFieldsObj( this, DATA_PILOT_DATA ); } uno::Reference SAL_CALL ScDataPilotDescriptorBase::getHiddenFields() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScDataPilotFieldsObj( this, DATA_PILOT_HIDDEN ); } // XUnoTunnel sal_Int64 SAL_CALL ScDataPilotDescriptorBase::getSomething( const uno::Sequence& rId ) throw(uno::RuntimeException) { if ( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) { return (sal_Int64)this; } return 0; } // static const uno::Sequence& ScDataPilotDescriptorBase::getUnoTunnelId() { static uno::Sequence * pSeq = 0; if( !pSeq ) { osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); if( !pSeq ) { static uno::Sequence< sal_Int8 > aSeq( 16 ); rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); pSeq = &aSeq; } } return *pSeq; } // static ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation( const uno::Reference xObj ) { ScDataPilotDescriptorBase* pRet = NULL; uno::Reference xUT( xObj, uno::UNO_QUERY ); if (xUT.is()) pRet = (ScDataPilotDescriptorBase*) xUT->getSomething( getUnoTunnelId() ); return pRet; } //------------------------------------------------------------------------ ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, USHORT nT, const String& rN) : ScDataPilotDescriptorBase( pDocSh ), nTab( nT ), aName( rN ) { } ScDataPilotTableObj::~ScDataPilotTableObj() { } uno::Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException) { SC_QUERYINTERFACE( sheet::XDataPilotTable ) return ScDataPilotDescriptorBase::queryInterface( rType ); } void SAL_CALL ScDataPilotTableObj::acquire() throw() { ScDataPilotDescriptorBase::acquire(); } void SAL_CALL ScDataPilotTableObj::release() throw() { ScDataPilotDescriptorBase::release(); } uno::Sequence SAL_CALL ScDataPilotTableObj::getTypes() throw(uno::RuntimeException) { static uno::Sequence aTypes; if ( aTypes.getLength() == 0 ) { uno::Sequence aParentTypes = ScDataPilotDescriptorBase::getTypes(); long nParentLen = aParentTypes.getLength(); const uno::Type* pParentPtr = aParentTypes.getConstArray(); aTypes.realloc( nParentLen + 1 ); uno::Type* pPtr = aTypes.getArray(); pPtr[nParentLen + 0] = getCppuType((const uno::Reference*)0); for (long i=0; i SAL_CALL ScDataPilotTableObj::getImplementationId() throw(uno::RuntimeException) { static uno::Sequence< sal_Int8 > aId; if( aId.getLength() == 0 ) { aId.realloc( 16 ); rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True ); } return aId; } // --- void ScDataPilotTableObj::GetParam( ScPivotParam& rParam, ScQueryParam& rQuery, ScArea& rSrcArea ) const { ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); if (pDPObj) { const ScSheetSourceDesc* pSheetDesc = pDPObj->GetSheetDesc(); if ( pSheetDesc ) { // FALSE -> fields are counted within the source range pDPObj->FillOldParam( rParam, FALSE ); rSrcArea = ScArea( pSheetDesc->aSourceRange.aStart.Tab(), pSheetDesc->aSourceRange.aStart.Col(), pSheetDesc->aSourceRange.aStart.Row(), pSheetDesc->aSourceRange.aEnd.Col(), pSheetDesc->aSourceRange.aEnd.Row() ); rQuery = pSheetDesc->aQueryParam; // in the Uno objects all fields in descriptors are counted within the source range // fields in ScPivotParam are correct (bForFile=FALSE in FillOldParam), // ScQueryParam still has to be adjusted: short nFieldStart = rSrcArea.nColStart; USHORT nQueryCount = rQuery.GetEntryCount(); for ( USHORT i=0; i= nFieldStart) rEntry.nField -= nFieldStart; } lcl_SetLayoutNamesToParam( rParam, GetDocShell()->GetDocument(), rSrcArea, *pDPObj ); } } } void ScDataPilotTableObj::SetParam( const ScPivotParam& rParam, const ScQueryParam& rQuery, const ScArea& rSrcArea ) { ScDocShell* pDocShell = GetDocShell(); ScDPObject* pDPObj = lcl_GetDPObject(pDocShell, nTab, aName); if ( pDPObj && pDocShell ) { // in den Uno-Objekten sind alle Fields in den Descriptoren innerhalb des Bereichs gezaehlt ScPivotParam aNewParam( rParam ); short nFieldStart = rSrcArea.nColStart; USHORT i; for ( i=0; iGetDocument(); ScPivot* pNew = new ScPivot( pDoc ); pNew->SetName( pDPObj->GetName() ); pNew->SetTag( pDPObj->GetTag() ); pNew->SetParam( aNewParam, aNewQuery, rSrcArea ); ScDPObject* pNewObj = new ScDPObject( pDoc ); pNewObj->InitFromOldPivot( *pNew, pDoc, TRUE ); lcl_SetLayoutNamesToObject( pDoc, aNewParam, rSrcArea, *pNewObj ); ScDBDocFunc aFunc(*pDocShell); aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, TRUE ); delete pNewObj; // DataPilotUpdate copies settings from "new" object delete pNew; } } // "rest of XDataPilotDescriptor" rtl::OUString SAL_CALL ScDataPilotTableObj::getName() throw(uno::RuntimeException) { ScUnoGuard aGuard; ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); if (pDPObj) return pDPObj->GetName(); return rtl::OUString(); } void SAL_CALL ScDataPilotTableObj::setName( const rtl::OUString& aNewName ) throw(uno::RuntimeException) { ScUnoGuard aGuard; ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); if (pDPObj) { //! test for existing names !!! String aString = aNewName; pDPObj->SetName( aString ); //! Undo - DBDocFunc ??? aName = aString; // DataPilotUpdate would do too much (output table is not changed) GetDocShell()->SetDocumentModified(); } } rtl::OUString SAL_CALL ScDataPilotTableObj::getTag() throw(uno::RuntimeException) { ScUnoGuard aGuard; ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); if (pDPObj) return pDPObj->GetTag(); return rtl::OUString(); } void SAL_CALL ScDataPilotTableObj::setTag( const ::rtl::OUString& aNewTag ) throw(uno::RuntimeException) { ScUnoGuard aGuard; ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); if (pDPObj) { String aString = aNewTag; pDPObj->SetTag( aString ); //! Undo - DBDocFunc ??? // DataPilotUpdate would do too much (output table is not changed) GetDocShell()->SetDocumentModified(); } } // XDataPilotTable table::CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(uno::RuntimeException) { ScUnoGuard aGuard; table::CellRangeAddress aRet; ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); if (pDPObj) { ScRange aRange = pDPObj->GetOutRange(); aRet.Sheet = aRange.aStart.Tab(); aRet.StartColumn = aRange.aStart.Col(); aRet.StartRow = aRange.aStart.Row(); aRet.EndColumn = aRange.aEnd.Col(); aRet.EndRow = aRange.aEnd.Row(); } return aRet; } void SAL_CALL ScDataPilotTableObj::refresh() throw(uno::RuntimeException) { ScUnoGuard aGuard; ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); if (pDPObj) { ScDPObject* pNew = new ScDPObject(*pDPObj); ScDBDocFunc aFunc(*GetDocShell()); aFunc.DataPilotUpdate( pDPObj, pNew, TRUE, TRUE ); delete pNew; // DataPilotUpdate copies settings from "new" object } } //------------------------------------------------------------------------ ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) : ScDataPilotDescriptorBase( pDocSh ) { } ScDataPilotDescriptor::~ScDataPilotDescriptor() { } void ScDataPilotDescriptor::GetParam( ScPivotParam& rParam, ScQueryParam& rQuery, ScArea& rSrcArea ) const { // Fields sind und bleiben innerhalb des Bereichs rParam = aParam; rQuery = aQuery; rSrcArea = aSrcArea; } void ScDataPilotDescriptor::SetParam( const ScPivotParam& rParam, const ScQueryParam& rQuery, const ScArea& rSrcArea ) { // Fields sind und bleiben innerhalb des Bereichs aParam = rParam; aQuery = rQuery; aSrcArea = rSrcArea; } // "rest of XDataPilotDescriptor" rtl::OUString SAL_CALL ScDataPilotDescriptor::getName() throw(uno::RuntimeException) { ScUnoGuard aGuard; return aNameStr; } void SAL_CALL ScDataPilotDescriptor::setName( const rtl::OUString& aNewName ) throw(uno::RuntimeException) { ScUnoGuard aGuard; aNameStr = String( aNewName ); } rtl::OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(uno::RuntimeException) { ScUnoGuard aGuard; return aTagStr; } void SAL_CALL ScDataPilotDescriptor::setTag( const ::rtl::OUString& aNewTag ) throw(uno::RuntimeException) { ScUnoGuard aGuard; aTagStr = String( aNewTag ); } //------------------------------------------------------------------------ ScDataPilotFieldsObj::ScDataPilotFieldsObj(ScDataPilotDescriptorBase* pPar, USHORT nTy) : pParent( pPar ), nType( nTy ) { pParent->acquire(); } ScDataPilotFieldsObj::~ScDataPilotFieldsObj() { pParent->release(); } USHORT lcl_GetFieldCount( const ScPivotParam& rParam, const ScArea& rSrcArea, USHORT nType ) { USHORT nRet = 0; USHORT nDataCount = lcl_DataCount(rParam); // Daten-Feld bei Spalten oder Zeile, wenn mehr als 1 Eintrag USHORT i; switch (nType) { case SC_FIELDORIENT_ALL: // Anzahl Spalten im Datenbereich // plus eins fuer das Datenfeld (immer) nRet = rSrcArea.nColEnd - rSrcArea.nColStart + 2; break; case DATA_PILOT_HIDDEN: { //! Datenfeld auch hier? USHORT nColCount = rSrcArea.nColEnd - rSrcArea.nColStart + 1; for (USHORT nSrcField=0; nSrcField 1 ) ++nRet; break; case DATA_PILOT_ROW: for (i=0; i 1 ) ++nRet; break; case DATA_PILOT_PAGE: nRet = 0; // Page-Fields sind nicht implementiert break; case DATA_PILOT_DATA: nRet = nDataCount; break; } return nRet; } BOOL lcl_GetFieldDataByIndex( const ScPivotParam& rParam, const ScArea& rSrcArea, USHORT nType, USHORT nIndex, USHORT& rField ) { BOOL bOk = FALSE; USHORT nPos = 0; USHORT nDataCount = lcl_DataCount(rParam); // Daten-Feld bei Spalten oder Zeile, wenn mehr als 1 Eintrag USHORT i; switch (nType) { case SC_FIELDORIENT_ALL: { USHORT nSourceCount = rSrcArea.nColEnd - rSrcArea.nColStart + 1; if ( nIndex < nSourceCount ) { rField = nIndex; bOk = TRUE; } else if ( nIndex == nSourceCount ) { rField = PIVOT_DATA_FIELD; bOk = TRUE; } } break; case DATA_PILOT_HIDDEN: { //! Datenfeld auch hier? USHORT nColCount = rSrcArea.nColEnd - rSrcArea.nColStart + 1; for (USHORT nSrcField=0; nSrcField 1 ) { if ( nPos == nIndex ) { rField = rParam.aColArr[i].nCol; bOk = TRUE; } ++nPos; } break; case DATA_PILOT_ROW: for (i=0; i 1 ) { if ( nPos == nIndex ) { rField = rParam.aRowArr[i].nCol; bOk = TRUE; } ++nPos; } break; case DATA_PILOT_PAGE: break; // Page-Fields sind nicht implementiert case DATA_PILOT_DATA: { USHORT nArrayPos, nFuncBit; if ( lcl_GetDataArrayPos( rParam, nIndex, nArrayPos, nFuncBit ) ) { rField = rParam.aDataArr[nArrayPos].nCol; bOk = TRUE; } } break; } return bOk; } String lcl_FieldName( ScDocShell* pDocSh, const ScPivotParam& rParam, const ScArea& rSrcArea, USHORT nField ) { String aRet; if ( nField == PIVOT_DATA_FIELD ) aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Data")); //! ??? else { USHORT nCol = rSrcArea.nColStart + nField; if ( pDocSh && nCol <= rSrcArea.nColEnd ) { USHORT nRow = rSrcArea.nRowStart; aRet = lcl_ColumnTitle( pDocSh->GetDocument(), nCol, nRow, rSrcArea.nTab ); // layout names from SaveData are in PivotParam LabelData if ( nField < rParam.nLabels && rParam.ppLabelArr && rParam.ppLabelArr[nField] && rParam.ppLabelArr[nField]->pStrColName && rParam.ppLabelArr[nField]->pStrColName->Len() ) aRet = *rParam.ppLabelArr[nField]->pStrColName; } } return aRet; } void lcl_SetFieldName( ScPivotParam& rParam, USHORT nField, const String& rNewName ) { USHORT nNewCount = Max( rParam.nLabels, (USHORT)( nField + 1 ) ); USHORT i; LabelData** ppNewData = new LabelData*[nNewCount]; for (i=0; iGetParam( aParam, aQuery, aSrcArea ); USHORT nField = 0; BOOL bOk = lcl_GetFieldDataByIndex( aParam, aSrcArea, nType, nIndex, nField ); if (bOk) return new ScDataPilotFieldObj( pParent, nField, nType, nIndex ); return NULL; } ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const rtl::OUString& aName) const { String aNameStr = aName; ScPivotParam aParam; ScQueryParam aQuery; ScArea aSrcArea; pParent->GetParam( aParam, aQuery, aSrcArea ); ScDocShell* pDocSh = pParent->GetDocShell(); USHORT nCount = lcl_GetFieldCount( aParam, aSrcArea, nType ); USHORT nField = 0; for (USHORT i=0; i SAL_CALL ScDataPilotFieldsObj::createEnumeration() throw(uno::RuntimeException) { ScUnoGuard aGuard; return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DataPilotFieldsEnumeration"))); } // XIndexAccess sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(uno::RuntimeException) { ScUnoGuard aGuard; ScPivotParam aParam; ScQueryParam aQuery; ScArea aSrcArea; pParent->GetParam( aParam, aQuery, aSrcArea ); return lcl_GetFieldCount( aParam, aSrcArea, nType ); } uno::Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex ) throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) { ScUnoGuard aGuard; uno::Reference xField = GetObjectByIndex_Impl((USHORT)nIndex); uno::Any aAny; if (xField.is()) aAny <<= xField; else throw lang::IndexOutOfBoundsException(); return aAny; } uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(uno::RuntimeException) { ScUnoGuard aGuard; return getCppuType((uno::Reference*)0); } sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(uno::RuntimeException) { ScUnoGuard aGuard; return ( getCount() != 0 ); } uno::Any SAL_CALL ScDataPilotFieldsObj::getByName( const rtl::OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { ScUnoGuard aGuard; uno::Reference xField = GetObjectByName_Impl(aName); uno::Any aAny; if (xField.is()) aAny <<= xField; else throw container::NoSuchElementException(); return aAny; } uno::Sequence SAL_CALL ScDataPilotFieldsObj::getElementNames() throw(uno::RuntimeException) { ScUnoGuard aGuard; ScPivotParam aParam; ScQueryParam aQuery; ScArea aSrcArea; pParent->GetParam( aParam, aQuery, aSrcArea ); ScDocShell* pDocSh = pParent->GetDocShell(); USHORT nCount = lcl_GetFieldCount( aParam, aSrcArea, nType ); USHORT nField = 0; uno::Sequence aSeq(nCount); rtl::OUString* pAry = aSeq.getArray(); for (USHORT i=0; iGetParam( aParam, aQuery, aSrcArea ); ScDocShell* pDocSh = pParent->GetDocShell(); USHORT nCount = lcl_GetFieldCount( aParam, aSrcArea, nType ); USHORT nField = 0; for (USHORT i=0; iacquire(); } ScDataPilotFieldObj::~ScDataPilotFieldObj() { pParent->release(); } // XNamed rtl::OUString SAL_CALL ScDataPilotFieldObj::getName() throw(uno::RuntimeException) { ScUnoGuard aGuard; ScPivotParam aParam; ScQueryParam aQuery; ScArea aSrcArea; pParent->GetParam( aParam, aQuery, aSrcArea ); String aRet = lcl_FieldName( pParent->GetDocShell(), aParam, aSrcArea, nField ); return aRet; } void SAL_CALL ScDataPilotFieldObj::setName( const rtl::OUString& aNewName ) throw(uno::RuntimeException) { ScPivotParam aParam; ScQueryParam aQuery; ScArea aSrcArea; pParent->GetParam( aParam, aQuery, aSrcArea ); if ( nField == PIVOT_DATA_FIELD ) { //! ... ??? } else lcl_SetFieldName( aParam, nField, aNewName ); pParent->SetParam( aParam, aQuery, aSrcArea ); } uno::Reference SAL_CALL ScDataPilotFieldObj::getPropertySetInfo() throw(uno::RuntimeException) { ScUnoGuard aGuard; static uno::Reference aRef = new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ); return aRef; } void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue ) throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) { ScUnoGuard aGuard; String aNameString = aPropertyName; if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) ) { //! test for correct enum type? sheet::GeneralFunction eFunction = (sheet::GeneralFunction) ScUnoHelpFunctions::GetEnumFromAny( aValue ); setFunction( eFunction ); } else if ( aNameString.EqualsAscii( SC_UNONAME_ORIENT ) ) { //! test for correct enum type? sheet::DataPilotFieldOrientation eOrient = (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumFromAny( aValue ); setOrientation( eOrient ); } } uno::Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const rtl::OUString& aPropertyName ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { ScUnoGuard aGuard; String aNameString = aPropertyName; uno::Any aRet; if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) ) { sheet::GeneralFunction eFunction = getFunction(); aRet <<= eFunction; } else if ( aNameString.EqualsAscii( SC_UNONAME_ORIENT ) ) { sheet::DataPilotFieldOrientation eOrient = getOrientation(); aRet <<= eOrient; } return aRet; } SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj ) void lcl_FindUsage( const ScPivotParam& rParam, USHORT nField, USHORT& rType, USHORT& rPos ) { USHORT i; for (i=0; iGetParam( aParam, aQuery, aSrcArea ); USHORT nType = nSourceType; USHORT nPos = nSourcePos; if ( nType == SC_FIELDORIENT_ALL ) lcl_FindUsage( aParam, nField, nType, nPos ); if ( nType == SC_FIELDORIENT_ALL ) // bei FindUsage nicht gefunden nType = DATA_PILOT_HIDDEN; // nicht verwendet return (sheet::DataPilotFieldOrientation)nType; } void lcl_RemoveField( PivotField* pFields, USHORT& rCount, USHORT nField ) { for (USHORT i=0; iGetParam( aParam, aQuery, aSrcArea ); // aus altem Array entfernen switch (nSourceType) { case DATA_PILOT_COLUMN: if ( nSourcePos < aParam.nColCount ) { for (USHORT i=nSourcePos; i+1