xref: /trunk/main/sc/source/core/tool/adiasync.cxx (revision b3f79822)
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