/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * 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 * <http://www.openoffice.org/license.html> * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include <tools/debug.hxx> #include <sfx2/objsh.hxx> #include "addinlis.hxx" #include "miscuno.hxx" // SC_IMPL_SERVICE_INFO #include "document.hxx" #include "brdcst.hxx" #include "unoguard.hxx" #include "sc.hrc" using namespace com::sun::star; //------------------------------------------------------------------------ //SMART_UNO_IMPLEMENTATION( ScAddInListener, UsrObject ); SC_SIMPLE_SERVICE_INFO( ScAddInListener, "ScAddInListener", "stardiv.one.sheet.AddInListener" ) //------------------------------------------------------------------------ List ScAddInListener::aAllListeners; //------------------------------------------------------------------------ // static ScAddInListener* ScAddInListener::CreateListener( uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) { ScAddInListener* pNew = new ScAddInListener( xVR, pDoc ); pNew->acquire(); // for aAllListeners aAllListeners.Insert( pNew, LIST_APPEND ); if ( xVR.is() ) xVR->addResultListener( pNew ); // after at least 1 ref exists! return pNew; } ScAddInListener::ScAddInListener( uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) : xVolRes( xVR ) { pDocs = new ScAddInDocs( 1, 1 ); pDocs->Insert( pDoc ); } ScAddInListener::~ScAddInListener() { delete pDocs; } // static ScAddInListener* ScAddInListener::Get( uno::Reference<sheet::XVolatileResult> xVR ) { sheet::XVolatileResult* pComp = xVR.get(); sal_uLong nCount = aAllListeners.Count(); for (sal_uLong nPos=0; nPos<nCount; nPos++) { ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); if ( pComp == (sheet::XVolatileResult*)pLst->xVolRes.get() ) return pLst; } return NULL; // not found } //! move to some container object? // static void ScAddInListener::RemoveDocument( ScDocument* pDocumentP ) { sal_uLong nPos = aAllListeners.Count(); while (nPos) { // loop backwards because elements are removed --nPos; ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); ScAddInDocs* p = pLst->pDocs; sal_uInt16 nFoundPos; if ( p->Seek_Entry( pDocumentP, &nFoundPos ) ) { p->Remove( nFoundPos ); if ( p->Count() == 0 ) { // this AddIn is no longer used // dont delete, just remove the ref for the list aAllListeners.Remove( nPos ); if ( pLst->xVolRes.is() ) pLst->xVolRes->removeResultListener( pLst ); pLst->release(); // Ref for aAllListeners - pLst may be deleted here } } } } //------------------------------------------------------------------------ // XResultListener void SAL_CALL ScAddInListener::modified( const ::com::sun::star::sheet::ResultEvent& aEvent ) throw(::com::sun::star::uno::RuntimeException) { ScUnoGuard aGuard; //! or generate a UserEvent aResult = aEvent.Value; // store result if ( !HasListeners() ) { //! remove from list and removeListener, as in RemoveDocument ??? #if 0 //! this will crash if called before first StartListening !!! aAllListeners.Remove( this ); if ( xVolRes.is() ) xVolRes->removeResultListener( this ); release(); // Ref for aAllListeners - this may be deleted here return; #endif } // notify document of changes Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) ); const ScDocument** ppDoc = (const ScDocument**) pDocs->GetData(); sal_uInt16 nCount = pDocs->Count(); for ( sal_uInt16 j=0; j<nCount; j++, ppDoc++ ) { ScDocument* pDoc = (ScDocument*)*ppDoc; pDoc->TrackFormulas(); pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) ); pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) ); } } // XEventListener void SAL_CALL ScAddInListener::disposing( const ::com::sun::star::lang::EventObject& /* Source */ ) throw(::com::sun::star::uno::RuntimeException) { // hold a ref so this is not deleted at removeResultListener uno::Reference<sheet::XResultListener> xRef( this ); if ( xVolRes.is() ) { xVolRes->removeResultListener( this ); xVolRes = NULL; } } //------------------------------------------------------------------------