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" {
ScAddInAsyncCallBack(double & nHandle,void * pData)52 void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData )
53 {
54 ScAddInAsync::CallBack( sal_uLong( nHandle ), pData );
55 }
56 }
57
58
59
ScAddInAsync()60 ScAddInAsync::ScAddInAsync() :
61 SvtBroadcaster(),
62 nHandle( 0 )
63 { // nur fuer aSeekObj !
64 }
65
66
67
ScAddInAsync(sal_uLong nHandleP,sal_uInt16 nIndex,ScDocument * pDoc)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
~ScAddInAsync()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
Get(sal_uLong nHandleP)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
CallBack(sal_uLong nHandleP,void * pData)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
RemoveDocument(ScDocument * pDocumentP)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