/************************************************************** * * 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 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include #include #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 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 xVR, ScDocument* pDoc ) : xVolRes( xVR ) { pDocs = new ScAddInDocs( 1, 1 ); pDocs->Insert( pDoc ); } ScAddInListener::~ScAddInListener() { delete pDocs; } // static ScAddInListener* ScAddInListener::Get( uno::Reference xVR ) { sheet::XVolatileResult* pComp = xVR.get(); sal_uLong nCount = aAllListeners.Count(); for (sal_uLong nPos=0; nPosxVolRes.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; jTrackFormulas(); 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 xRef( this ); if ( xVolRes.is() ) { xVolRes->removeResultListener( this ); xVolRes = NULL; } } //------------------------------------------------------------------------