blob: bd68245e040078c735c6e81fa06a1fc572a3a0c3 [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 <sfx2/objsh.hxx>
#include "adiasync.hxx"
#include "brdcst.hxx"
#include "global.hxx"
#include "document.hxx"
#include "sc.hrc" // FID_DATACHANGED
#include <osl/thread.h>
//------------------------------------------------------------------------
ScAddInAsyncs theAddInAsyncTbl;
static ScAddInAsync aSeekObj;
SV_IMPL_OP_PTRARR_SORT( ScAddInAsyncs, ScAddInAsyncPtr );
SV_IMPL_PTRARR_SORT( ScAddInDocs, ScAddInDocPtr );
extern "C" {
void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData )
{
ScAddInAsync::CallBack( sal_uLong( nHandle ), pData );
}
}
ScAddInAsync::ScAddInAsync() :
SvtBroadcaster(),
nHandle( 0 )
{ // nur fuer aSeekObj !
}
ScAddInAsync::ScAddInAsync( sal_uLong nHandleP, sal_uInt16 nIndex, ScDocument* pDoc ) :
SvtBroadcaster(),
pStr( NULL ),
nHandle( nHandleP ),
bValid( sal_False )
{
pDocs = new ScAddInDocs( 1, 1 );
pDocs->Insert( pDoc );
pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex);
eType = pFuncData->GetAsyncType();
theAddInAsyncTbl.Insert( this );
}
ScAddInAsync::~ScAddInAsync()
{
// aSeekObj hat das alles nicht, Handle 0 gibt es sonst nicht
if ( nHandle )
{
// im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear
pFuncData->Unadvice( (double)nHandle );
if ( eType == PTR_STRING && pStr ) // mit Typvergleich wg. Union!
delete pStr;
delete pDocs;
}
}
ScAddInAsync* ScAddInAsync::Get( sal_uLong nHandleP )
{
sal_uInt16 nPos;
ScAddInAsync* pRet = 0;
aSeekObj.nHandle = nHandleP;
if ( theAddInAsyncTbl.Seek_Entry( &aSeekObj, &nPos ) )
pRet = theAddInAsyncTbl[ nPos ];
aSeekObj.nHandle = 0;
return pRet;
}
void ScAddInAsync::CallBack( sal_uLong nHandleP, void* pData )
{
ScAddInAsync* p;
if ( (p = Get( nHandleP )) == NULL )
return;
// keiner mehr dran? Unadvice und weg damit
if ( !p->HasListeners() )
{
// nicht im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear
theAddInAsyncTbl.Remove( p );
delete p;
return ;
}
switch ( p->eType )
{
case PTR_DOUBLE :
p->nVal = *(double*)pData;
break;
case PTR_STRING :
if ( p->pStr )
*p->pStr = String( (sal_Char*)pData, osl_getThreadTextEncoding() );
else
p->pStr = new String( (sal_Char*)pData, osl_getThreadTextEncoding() );
break;
default :
DBG_ERROR( "unbekannter AsyncType" );
return;
}
p->bValid = sal_True;
p->Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) );
const ScDocument** ppDoc = (const ScDocument**) p->pDocs->GetData();
sal_uInt16 nCount = p->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) );
}
}
void ScAddInAsync::RemoveDocument( ScDocument* pDocumentP )
{
sal_uInt16 nPos = theAddInAsyncTbl.Count();
if ( nPos )
{
const ScAddInAsync** ppAsync =
(const ScAddInAsync**) theAddInAsyncTbl.GetData() + nPos - 1;
for ( ; nPos-- >0; ppAsync-- )
{ // rueckwaerts wg. Pointer-Aufrueckerei im Array
ScAddInDocs* p = ((ScAddInAsync*)*ppAsync)->pDocs;
sal_uInt16 nFoundPos;
if ( p->Seek_Entry( pDocumentP, &nFoundPos ) )
{
p->Remove( nFoundPos );
if ( p->Count() == 0 )
{ // dieses AddIn wird nicht mehr benutzt
ScAddInAsync* pAsync = (ScAddInAsync*)*ppAsync;
theAddInAsyncTbl.Remove( nPos );
delete pAsync;
ppAsync = (const ScAddInAsync**) theAddInAsyncTbl.GetData()
+ nPos;
}
}
}
}
}