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