1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 28 29 //------------------------------------------------------------------------ 30 31 #include <sfx2/objsh.hxx> 32 33 #include "adiasync.hxx" 34 #include "brdcst.hxx" 35 #include "global.hxx" 36 #include "document.hxx" 37 #include "sc.hrc" // FID_DATACHANGED 38 #include <osl/thread.h> 39 40 41 //------------------------------------------------------------------------ 42 43 ScAddInAsyncs theAddInAsyncTbl; 44 static ScAddInAsync aSeekObj; 45 46 47 SV_IMPL_OP_PTRARR_SORT( ScAddInAsyncs, ScAddInAsyncPtr ); 48 49 SV_IMPL_PTRARR_SORT( ScAddInDocs, ScAddInDocPtr ); 50 51 extern "C" { 52 void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData ) 53 { 54 ScAddInAsync::CallBack( sal_uLong( nHandle ), pData ); 55 } 56 } 57 58 59 60 ScAddInAsync::ScAddInAsync() : 61 SvtBroadcaster(), 62 nHandle( 0 ) 63 { // nur fuer aSeekObj ! 64 } 65 66 67 68 ScAddInAsync::ScAddInAsync( sal_uLong nHandleP, sal_uInt16 nIndex, ScDocument* pDoc ) : 69 SvtBroadcaster(), 70 pStr( NULL ), 71 nHandle( nHandleP ), 72 bValid( sal_False ) 73 { 74 pDocs = new ScAddInDocs( 1, 1 ); 75 pDocs->Insert( pDoc ); 76 pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex); 77 eType = pFuncData->GetAsyncType(); 78 theAddInAsyncTbl.Insert( this ); 79 } 80 81 82 83 ScAddInAsync::~ScAddInAsync() 84 { 85 // aSeekObj hat das alles nicht, Handle 0 gibt es sonst nicht 86 if ( nHandle ) 87 { 88 // im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear 89 pFuncData->Unadvice( (double)nHandle ); 90 if ( eType == PTR_STRING && pStr ) // mit Typvergleich wg. Union! 91 delete pStr; 92 delete pDocs; 93 } 94 } 95 96 97 98 ScAddInAsync* ScAddInAsync::Get( sal_uLong nHandleP ) 99 { 100 sal_uInt16 nPos; 101 ScAddInAsync* pRet = 0; 102 aSeekObj.nHandle = nHandleP; 103 if ( theAddInAsyncTbl.Seek_Entry( &aSeekObj, &nPos ) ) 104 pRet = theAddInAsyncTbl[ nPos ]; 105 aSeekObj.nHandle = 0; 106 return pRet; 107 } 108 109 110 111 void ScAddInAsync::CallBack( sal_uLong nHandleP, void* pData ) 112 { 113 ScAddInAsync* p; 114 if ( (p = Get( nHandleP )) == NULL ) 115 return; 116 // keiner mehr dran? Unadvice und weg damit 117 if ( !p->HasListeners() ) 118 { 119 // nicht im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear 120 theAddInAsyncTbl.Remove( p ); 121 delete p; 122 return ; 123 } 124 switch ( p->eType ) 125 { 126 case PTR_DOUBLE : 127 p->nVal = *(double*)pData; 128 break; 129 case PTR_STRING : 130 if ( p->pStr ) 131 *p->pStr = String( (sal_Char*)pData, osl_getThreadTextEncoding() ); 132 else 133 p->pStr = new String( (sal_Char*)pData, osl_getThreadTextEncoding() ); 134 break; 135 default : 136 DBG_ERROR( "unbekannter AsyncType" ); 137 return; 138 } 139 p->bValid = sal_True; 140 p->Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) ); 141 142 const ScDocument** ppDoc = (const ScDocument**) p->pDocs->GetData(); 143 sal_uInt16 nCount = p->pDocs->Count(); 144 for ( sal_uInt16 j=0; j<nCount; j++, ppDoc++ ) 145 { 146 ScDocument* pDoc = (ScDocument*)*ppDoc; 147 pDoc->TrackFormulas(); 148 pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) ); 149 pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) ); 150 } 151 } 152 153 154 155 void ScAddInAsync::RemoveDocument( ScDocument* pDocumentP ) 156 { 157 sal_uInt16 nPos = theAddInAsyncTbl.Count(); 158 if ( nPos ) 159 { 160 const ScAddInAsync** ppAsync = 161 (const ScAddInAsync**) theAddInAsyncTbl.GetData() + nPos - 1; 162 for ( ; nPos-- >0; ppAsync-- ) 163 { // rueckwaerts wg. Pointer-Aufrueckerei im Array 164 ScAddInDocs* p = ((ScAddInAsync*)*ppAsync)->pDocs; 165 sal_uInt16 nFoundPos; 166 if ( p->Seek_Entry( pDocumentP, &nFoundPos ) ) 167 { 168 p->Remove( nFoundPos ); 169 if ( p->Count() == 0 ) 170 { // dieses AddIn wird nicht mehr benutzt 171 ScAddInAsync* pAsync = (ScAddInAsync*)*ppAsync; 172 theAddInAsyncTbl.Remove( nPos ); 173 delete pAsync; 174 ppAsync = (const ScAddInAsync**) theAddInAsyncTbl.GetData() 175 + nPos; 176 } 177 } 178 } 179 } 180 } 181 182 183 184