1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 33 //------------------------------------------------------------------------ 34 35 #include <sfx2/objsh.hxx> 36 37 #include "adiasync.hxx" 38 #include "brdcst.hxx" 39 #include "global.hxx" 40 #include "document.hxx" 41 #include "sc.hrc" // FID_DATACHANGED 42 #include <osl/thread.h> 43 44 45 //------------------------------------------------------------------------ 46 47 ScAddInAsyncs theAddInAsyncTbl; 48 static ScAddInAsync aSeekObj; 49 50 51 SV_IMPL_OP_PTRARR_SORT( ScAddInAsyncs, ScAddInAsyncPtr ); 52 53 SV_IMPL_PTRARR_SORT( ScAddInDocs, ScAddInDocPtr ); 54 55 extern "C" { 56 void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData ) 57 { 58 ScAddInAsync::CallBack( sal_uLong( nHandle ), pData ); 59 } 60 } 61 62 63 64 ScAddInAsync::ScAddInAsync() : 65 SvtBroadcaster(), 66 nHandle( 0 ) 67 { // nur fuer aSeekObj ! 68 } 69 70 71 72 ScAddInAsync::ScAddInAsync( sal_uLong nHandleP, sal_uInt16 nIndex, ScDocument* pDoc ) : 73 SvtBroadcaster(), 74 pStr( NULL ), 75 nHandle( nHandleP ), 76 bValid( sal_False ) 77 { 78 pDocs = new ScAddInDocs( 1, 1 ); 79 pDocs->Insert( pDoc ); 80 pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex); 81 eType = pFuncData->GetAsyncType(); 82 theAddInAsyncTbl.Insert( this ); 83 } 84 85 86 87 ScAddInAsync::~ScAddInAsync() 88 { 89 // aSeekObj hat das alles nicht, Handle 0 gibt es sonst nicht 90 if ( nHandle ) 91 { 92 // im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear 93 pFuncData->Unadvice( (double)nHandle ); 94 if ( eType == PTR_STRING && pStr ) // mit Typvergleich wg. Union! 95 delete pStr; 96 delete pDocs; 97 } 98 } 99 100 101 102 ScAddInAsync* ScAddInAsync::Get( sal_uLong nHandleP ) 103 { 104 sal_uInt16 nPos; 105 ScAddInAsync* pRet = 0; 106 aSeekObj.nHandle = nHandleP; 107 if ( theAddInAsyncTbl.Seek_Entry( &aSeekObj, &nPos ) ) 108 pRet = theAddInAsyncTbl[ nPos ]; 109 aSeekObj.nHandle = 0; 110 return pRet; 111 } 112 113 114 115 void ScAddInAsync::CallBack( sal_uLong nHandleP, void* pData ) 116 { 117 ScAddInAsync* p; 118 if ( (p = Get( nHandleP )) == NULL ) 119 return; 120 // keiner mehr dran? Unadvice und weg damit 121 if ( !p->HasListeners() ) 122 { 123 // nicht im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear 124 theAddInAsyncTbl.Remove( p ); 125 delete p; 126 return ; 127 } 128 switch ( p->eType ) 129 { 130 case PTR_DOUBLE : 131 p->nVal = *(double*)pData; 132 break; 133 case PTR_STRING : 134 if ( p->pStr ) 135 *p->pStr = String( (sal_Char*)pData, osl_getThreadTextEncoding() ); 136 else 137 p->pStr = new String( (sal_Char*)pData, osl_getThreadTextEncoding() ); 138 break; 139 default : 140 DBG_ERROR( "unbekannter AsyncType" ); 141 return; 142 } 143 p->bValid = sal_True; 144 p->Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) ); 145 146 const ScDocument** ppDoc = (const ScDocument**) p->pDocs->GetData(); 147 sal_uInt16 nCount = p->pDocs->Count(); 148 for ( sal_uInt16 j=0; j<nCount; j++, ppDoc++ ) 149 { 150 ScDocument* pDoc = (ScDocument*)*ppDoc; 151 pDoc->TrackFormulas(); 152 pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) ); 153 pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) ); 154 } 155 } 156 157 158 159 void ScAddInAsync::RemoveDocument( ScDocument* pDocumentP ) 160 { 161 sal_uInt16 nPos = theAddInAsyncTbl.Count(); 162 if ( nPos ) 163 { 164 const ScAddInAsync** ppAsync = 165 (const ScAddInAsync**) theAddInAsyncTbl.GetData() + nPos - 1; 166 for ( ; nPos-- >0; ppAsync-- ) 167 { // rueckwaerts wg. Pointer-Aufrueckerei im Array 168 ScAddInDocs* p = ((ScAddInAsync*)*ppAsync)->pDocs; 169 sal_uInt16 nFoundPos; 170 if ( p->Seek_Entry( pDocumentP, &nFoundPos ) ) 171 { 172 p->Remove( nFoundPos ); 173 if ( p->Count() == 0 ) 174 { // dieses AddIn wird nicht mehr benutzt 175 ScAddInAsync* pAsync = (ScAddInAsync*)*ppAsync; 176 theAddInAsyncTbl.Remove( nPos ); 177 delete pAsync; 178 ppAsync = (const ScAddInAsync**) theAddInAsyncTbl.GetData() 179 + nPos; 180 } 181 } 182 } 183 } 184 } 185 186 187 188