blob: b692fd9cdc7581193076966d80058338b65a365b [file] [log] [blame]
/**************************************************************
*
* 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 <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;
}
}
//------------------------------------------------------------------------