diff options
Diffstat (limited to 'sc/source/core/tool/addinlis.cxx')
-rw-r--r-- | sc/source/core/tool/addinlis.cxx | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/sc/source/core/tool/addinlis.cxx b/sc/source/core/tool/addinlis.cxx new file mode 100644 index 000000000000..ad6b60073ccb --- /dev/null +++ b/sc/source/core/tool/addinlis.cxx @@ -0,0 +1,190 @@ +/************************************************************************* + * + * 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(); + + ULONG nCount = aAllListeners.Count(); + for (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 ) +{ + ULONG nPos = aAllListeners.Count(); + while (nPos) + { + // loop backwards because elements are removed + --nPos; + ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); + ScAddInDocs* p = pLst->pDocs; + USHORT 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(); + USHORT nCount = pDocs->Count(); + for ( USHORT 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; + } +} + + +//------------------------------------------------------------------------ + + + |