xref: /trunk/main/basic/source/sbx/sbxobj.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_basic.hxx"
30*cdf0e10cSrcweir #include <tools/stream.hxx>
31*cdf0e10cSrcweir #include <vcl/sound.hxx>
32*cdf0e10cSrcweir #include <basic/sbx.hxx>
33*cdf0e10cSrcweir #include <basic/sbxbase.hxx>
34*cdf0e10cSrcweir #include "sbxres.hxx"
35*cdf0e10cSrcweir #include <svl/brdcst.hxx>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir TYPEINIT1(SbxMethod,SbxVariable)
38*cdf0e10cSrcweir TYPEINIT1(SbxProperty,SbxVariable)
39*cdf0e10cSrcweir TYPEINIT2(SbxObject,SbxVariable,SfxListener)
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir static const char* pNameProp;               // Name-Property
42*cdf0e10cSrcweir static const char* pParentProp;             // Parent-Property
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir static sal_uInt16 nNameHash = 0, nParentHash = 0;
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir SbxObject::SbxObject( const XubString& rClass )
51*cdf0e10cSrcweir          : SbxVariable( SbxOBJECT ), aClassName( rClass )
52*cdf0e10cSrcweir {
53*cdf0e10cSrcweir     aData.pObj = this;
54*cdf0e10cSrcweir     if( !nNameHash )
55*cdf0e10cSrcweir     {
56*cdf0e10cSrcweir         pNameProp = GetSbxRes( STRING_NAMEPROP );
57*cdf0e10cSrcweir         pParentProp = GetSbxRes( STRING_PARENTPROP );
58*cdf0e10cSrcweir         nNameHash = MakeHashCode( String::CreateFromAscii( pNameProp ) );
59*cdf0e10cSrcweir         nParentHash = MakeHashCode( String::CreateFromAscii( pParentProp ) );
60*cdf0e10cSrcweir     }
61*cdf0e10cSrcweir     SbxObject::Clear();
62*cdf0e10cSrcweir     SbxObject::SetName( rClass );
63*cdf0e10cSrcweir }
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir SbxObject::SbxObject( const SbxObject& rObj )
66*cdf0e10cSrcweir     : SvRefBase( rObj ), SbxVariable( rObj.GetType() ),
67*cdf0e10cSrcweir       SfxListener( rObj )
68*cdf0e10cSrcweir {
69*cdf0e10cSrcweir     *this = rObj;
70*cdf0e10cSrcweir }
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir SbxObject& SbxObject::operator=( const SbxObject& r )
73*cdf0e10cSrcweir {
74*cdf0e10cSrcweir     if( &r != this )
75*cdf0e10cSrcweir     {
76*cdf0e10cSrcweir         SbxVariable::operator=( r );
77*cdf0e10cSrcweir         aClassName = r.aClassName;
78*cdf0e10cSrcweir         pMethods   = new SbxArray;
79*cdf0e10cSrcweir         pProps     = new SbxArray;
80*cdf0e10cSrcweir         pObjs      = new SbxArray( SbxOBJECT );
81*cdf0e10cSrcweir         // Die Arrays werden kopiert, die Inhalte uebernommen
82*cdf0e10cSrcweir         *pMethods  = *r.pMethods;
83*cdf0e10cSrcweir         *pProps    = *r.pProps;
84*cdf0e10cSrcweir         *pObjs     = *r.pObjs;
85*cdf0e10cSrcweir         // Da die Variablen uebernommen wurden, ist dies OK
86*cdf0e10cSrcweir         pDfltProp  = r.pDfltProp;
87*cdf0e10cSrcweir         SetName( r.GetName() );
88*cdf0e10cSrcweir         SetFlags( r.GetFlags() );
89*cdf0e10cSrcweir         SetModified( sal_True );
90*cdf0e10cSrcweir     }
91*cdf0e10cSrcweir     return *this;
92*cdf0e10cSrcweir }
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir static void CheckParentsOnDelete( SbxObject* pObj, SbxArray* p )
95*cdf0e10cSrcweir {
96*cdf0e10cSrcweir     for( sal_uInt16 i = 0; i < p->Count(); i++ )
97*cdf0e10cSrcweir     {
98*cdf0e10cSrcweir         SbxVariableRef& rRef = p->GetRef( i );
99*cdf0e10cSrcweir         if( rRef->IsBroadcaster() )
100*cdf0e10cSrcweir             pObj->EndListening( rRef->GetBroadcaster(), sal_True );
101*cdf0e10cSrcweir         // Hat das Element mehr als eine Referenz und noch einen Listener?
102*cdf0e10cSrcweir         if( rRef->GetRefCount() > 1 )
103*cdf0e10cSrcweir         {
104*cdf0e10cSrcweir             rRef->SetParent( NULL );
105*cdf0e10cSrcweir             DBG_ASSERT( !rRef->IsBroadcaster() || rRef->GetBroadcaster().GetListenerCount(), "Object element with dangling parent" );
106*cdf0e10cSrcweir         }
107*cdf0e10cSrcweir     }
108*cdf0e10cSrcweir }
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir SbxObject::~SbxObject()
111*cdf0e10cSrcweir {
112*cdf0e10cSrcweir     CheckParentsOnDelete( this, pProps );
113*cdf0e10cSrcweir     CheckParentsOnDelete( this, pMethods );
114*cdf0e10cSrcweir     CheckParentsOnDelete( this, pObjs );
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir     // avoid handling in ~SbxVariable as SBX_DIM_AS_NEW == SBX_GBLSEARCH
117*cdf0e10cSrcweir     ResetFlag( SBX_DIM_AS_NEW );
118*cdf0e10cSrcweir }
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir SbxDataType SbxObject::GetType() const
121*cdf0e10cSrcweir {
122*cdf0e10cSrcweir     return SbxOBJECT;
123*cdf0e10cSrcweir }
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir SbxClassType SbxObject::GetClass() const
126*cdf0e10cSrcweir {
127*cdf0e10cSrcweir     return SbxCLASS_OBJECT;
128*cdf0e10cSrcweir }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir void SbxObject::Clear()
131*cdf0e10cSrcweir {
132*cdf0e10cSrcweir     pMethods   = new SbxArray;
133*cdf0e10cSrcweir     pProps     = new SbxArray;
134*cdf0e10cSrcweir     pObjs      = new SbxArray( SbxOBJECT );
135*cdf0e10cSrcweir     SbxVariable* p;
136*cdf0e10cSrcweir     p = Make( String::CreateFromAscii( pNameProp ), SbxCLASS_PROPERTY, SbxSTRING );
137*cdf0e10cSrcweir     p->SetFlag( SBX_DONTSTORE );
138*cdf0e10cSrcweir     p = Make( String::CreateFromAscii( pParentProp ), SbxCLASS_PROPERTY, SbxOBJECT );
139*cdf0e10cSrcweir     p->ResetFlag( SBX_WRITE );
140*cdf0e10cSrcweir     p->SetFlag( SBX_DONTSTORE );
141*cdf0e10cSrcweir     pDfltProp  = NULL;
142*cdf0e10cSrcweir     SetModified( sal_False );
143*cdf0e10cSrcweir }
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir void SbxObject::SFX_NOTIFY( SfxBroadcaster&, const TypeId&,
146*cdf0e10cSrcweir                             const SfxHint& rHint, const TypeId& )
147*cdf0e10cSrcweir {
148*cdf0e10cSrcweir     const SbxHint* p = PTR_CAST(SbxHint,&rHint);
149*cdf0e10cSrcweir     if( p )
150*cdf0e10cSrcweir     {
151*cdf0e10cSrcweir         sal_uIntPtr nId = p->GetId();
152*cdf0e10cSrcweir         sal_Bool bRead  = sal_Bool( nId == SBX_HINT_DATAWANTED );
153*cdf0e10cSrcweir         sal_Bool bWrite = sal_Bool( nId == SBX_HINT_DATACHANGED );
154*cdf0e10cSrcweir         SbxVariable* pVar = p->GetVar();
155*cdf0e10cSrcweir         if( bRead || bWrite )
156*cdf0e10cSrcweir         {
157*cdf0e10cSrcweir             XubString aVarName( pVar->GetName() );
158*cdf0e10cSrcweir             sal_uInt16 nHash_ = MakeHashCode( aVarName );
159*cdf0e10cSrcweir             if( nHash_ == nNameHash
160*cdf0e10cSrcweir              && aVarName.EqualsIgnoreCaseAscii( pNameProp ) )
161*cdf0e10cSrcweir             {
162*cdf0e10cSrcweir                 if( bRead )
163*cdf0e10cSrcweir                     pVar->PutString( GetName() );
164*cdf0e10cSrcweir                 else
165*cdf0e10cSrcweir                     SetName( pVar->GetString() );
166*cdf0e10cSrcweir             }
167*cdf0e10cSrcweir             else if( nHash_ == nParentHash
168*cdf0e10cSrcweir              && aVarName.EqualsIgnoreCaseAscii( pParentProp ) )
169*cdf0e10cSrcweir             {
170*cdf0e10cSrcweir                 SbxObject* p_ = GetParent();
171*cdf0e10cSrcweir                 if( !p_ )
172*cdf0e10cSrcweir                     p_ = this;
173*cdf0e10cSrcweir                 pVar->PutObject( p_ );
174*cdf0e10cSrcweir             }
175*cdf0e10cSrcweir         }
176*cdf0e10cSrcweir     }
177*cdf0e10cSrcweir }
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir sal_Bool SbxObject::IsClass( const XubString& rName ) const
180*cdf0e10cSrcweir {
181*cdf0e10cSrcweir     return sal_Bool( aClassName.EqualsIgnoreCaseAscii( rName ) );
182*cdf0e10cSrcweir }
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir SbxVariable* SbxObject::FindUserData( sal_uInt32 nData )
185*cdf0e10cSrcweir {
186*cdf0e10cSrcweir     if( !GetAll( SbxCLASS_DONTCARE ) )
187*cdf0e10cSrcweir         return NULL;
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir     SbxVariable* pRes = pMethods->FindUserData( nData );
190*cdf0e10cSrcweir     if( !pRes )
191*cdf0e10cSrcweir         pRes = pProps->FindUserData( nData );
192*cdf0e10cSrcweir     if( !pRes )
193*cdf0e10cSrcweir         pRes = pObjs->FindUserData( nData );
194*cdf0e10cSrcweir     // Search in den Parents?
195*cdf0e10cSrcweir     if( !pRes && IsSet( SBX_GBLSEARCH ) )
196*cdf0e10cSrcweir     {
197*cdf0e10cSrcweir         SbxObject* pCur = this;
198*cdf0e10cSrcweir         while( !pRes && pCur->pParent )
199*cdf0e10cSrcweir         {
200*cdf0e10cSrcweir             // Ich selbst bin schon durchsucht worden!
201*cdf0e10cSrcweir             sal_uInt16 nOwn = pCur->GetFlags();
202*cdf0e10cSrcweir             pCur->ResetFlag( SBX_EXTSEARCH );
203*cdf0e10cSrcweir             // Ich suche bereits global!
204*cdf0e10cSrcweir             sal_uInt16 nPar = pCur->pParent->GetFlags();
205*cdf0e10cSrcweir             pCur->pParent->ResetFlag( SBX_GBLSEARCH );
206*cdf0e10cSrcweir             pRes = pCur->pParent->FindUserData( nData );
207*cdf0e10cSrcweir             pCur->SetFlags( nOwn );
208*cdf0e10cSrcweir             pCur->pParent->SetFlags( nPar );
209*cdf0e10cSrcweir             pCur = pCur->pParent;
210*cdf0e10cSrcweir         }
211*cdf0e10cSrcweir     }
212*cdf0e10cSrcweir     return pRes;
213*cdf0e10cSrcweir }
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir SbxVariable* SbxObject::Find( const XubString& rName, SbxClassType t )
216*cdf0e10cSrcweir {
217*cdf0e10cSrcweir #ifdef DBG_UTIL
218*cdf0e10cSrcweir     static sal_uInt16 nLvl = 0;
219*cdf0e10cSrcweir     static const char* pCls[] =
220*cdf0e10cSrcweir     { "DontCare","Array","Value","Variable","Method","Property","Object" };
221*cdf0e10cSrcweir     ByteString aNameStr1( (const UniString&)rName, RTL_TEXTENCODING_ASCII_US );
222*cdf0e10cSrcweir     ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
223*cdf0e10cSrcweir     DbgOutf( "SBX: Search %.*s %s %s in %s",
224*cdf0e10cSrcweir         nLvl++, "                              ",
225*cdf0e10cSrcweir         ( t >= SbxCLASS_DONTCARE && t <= SbxCLASS_OBJECT )
226*cdf0e10cSrcweir          ? pCls[ t-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
227*cdf0e10cSrcweir #endif
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir     if( !GetAll( t ) )
230*cdf0e10cSrcweir         return NULL;
231*cdf0e10cSrcweir     SbxVariable* pRes = NULL;
232*cdf0e10cSrcweir     pObjs->SetFlag( SBX_EXTSEARCH );
233*cdf0e10cSrcweir     if( t == SbxCLASS_DONTCARE )
234*cdf0e10cSrcweir     {
235*cdf0e10cSrcweir         pRes = pMethods->Find( rName, SbxCLASS_METHOD );
236*cdf0e10cSrcweir         if( !pRes )
237*cdf0e10cSrcweir             pRes = pProps->Find( rName, SbxCLASS_PROPERTY );
238*cdf0e10cSrcweir         if( !pRes )
239*cdf0e10cSrcweir             pRes = pObjs->Find( rName, t );
240*cdf0e10cSrcweir     }
241*cdf0e10cSrcweir     else
242*cdf0e10cSrcweir     {
243*cdf0e10cSrcweir         SbxArray* pArray = NULL;
244*cdf0e10cSrcweir         switch( t )
245*cdf0e10cSrcweir         {
246*cdf0e10cSrcweir             case SbxCLASS_VARIABLE:
247*cdf0e10cSrcweir             case SbxCLASS_PROPERTY: pArray = pProps;    break;
248*cdf0e10cSrcweir             case SbxCLASS_METHOD:   pArray = pMethods;  break;
249*cdf0e10cSrcweir             case SbxCLASS_OBJECT:   pArray = pObjs;     break;
250*cdf0e10cSrcweir             default:
251*cdf0e10cSrcweir                 DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
252*cdf0e10cSrcweir         }
253*cdf0e10cSrcweir         if( pArray )
254*cdf0e10cSrcweir             pRes = pArray->Find( rName, t );
255*cdf0e10cSrcweir     }
256*cdf0e10cSrcweir     // Extended Search im Objekt-Array?
257*cdf0e10cSrcweir     // Fuer Objekte und DontCare ist das Objektarray bereits
258*cdf0e10cSrcweir     // durchsucht worden
259*cdf0e10cSrcweir     if( !pRes && ( t == SbxCLASS_METHOD || t == SbxCLASS_PROPERTY ) )
260*cdf0e10cSrcweir         pRes = pObjs->Find( rName, t );
261*cdf0e10cSrcweir     // Search in den Parents?
262*cdf0e10cSrcweir     if( !pRes && IsSet( SBX_GBLSEARCH ) )
263*cdf0e10cSrcweir     {
264*cdf0e10cSrcweir         SbxObject* pCur = this;
265*cdf0e10cSrcweir         while( !pRes && pCur->pParent )
266*cdf0e10cSrcweir         {
267*cdf0e10cSrcweir             // Ich selbst bin schon durchsucht worden!
268*cdf0e10cSrcweir             sal_uInt16 nOwn = pCur->GetFlags();
269*cdf0e10cSrcweir             pCur->ResetFlag( SBX_EXTSEARCH );
270*cdf0e10cSrcweir             // Ich suche bereits global!
271*cdf0e10cSrcweir             sal_uInt16 nPar = pCur->pParent->GetFlags();
272*cdf0e10cSrcweir             pCur->pParent->ResetFlag( SBX_GBLSEARCH );
273*cdf0e10cSrcweir             pRes = pCur->pParent->Find( rName, t );
274*cdf0e10cSrcweir             pCur->SetFlags( nOwn );
275*cdf0e10cSrcweir             pCur->pParent->SetFlags( nPar );
276*cdf0e10cSrcweir             pCur = pCur->pParent;
277*cdf0e10cSrcweir         }
278*cdf0e10cSrcweir     }
279*cdf0e10cSrcweir #ifdef DBG_UTIL
280*cdf0e10cSrcweir     nLvl--;
281*cdf0e10cSrcweir     if( pRes )
282*cdf0e10cSrcweir     {
283*cdf0e10cSrcweir         ByteString aNameStr3( (const UniString&)rName, RTL_TEXTENCODING_ASCII_US );
284*cdf0e10cSrcweir         ByteString aNameStr4( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
285*cdf0e10cSrcweir         DbgOutf( "SBX: Found %.*s %s in %s",
286*cdf0e10cSrcweir             nLvl, "                              ", aNameStr3.GetBuffer(), aNameStr4.GetBuffer() );
287*cdf0e10cSrcweir     }
288*cdf0e10cSrcweir #endif
289*cdf0e10cSrcweir     return pRes;
290*cdf0e10cSrcweir }
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir // Kurzform: Die Parent-Kette wird durchsucht
293*cdf0e10cSrcweir // Das ganze rekursiv, da Call() ueberladen sein kann
294*cdf0e10cSrcweir // Qualified Names sind zugelassen
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir sal_Bool SbxObject::Call( const XubString& rName, SbxArray* pParam )
297*cdf0e10cSrcweir {
298*cdf0e10cSrcweir     SbxVariable* pMeth = FindQualified( rName, SbxCLASS_DONTCARE);
299*cdf0e10cSrcweir     if( pMeth && pMeth->ISA(SbxMethod) )
300*cdf0e10cSrcweir     {
301*cdf0e10cSrcweir         // FindQualified() koennte schon zugeschlagen haben!
302*cdf0e10cSrcweir         if( pParam )
303*cdf0e10cSrcweir             pMeth->SetParameters( pParam );
304*cdf0e10cSrcweir         pMeth->Broadcast( SBX_HINT_DATAWANTED );
305*cdf0e10cSrcweir         pMeth->SetParameters( NULL );
306*cdf0e10cSrcweir         return sal_True;
307*cdf0e10cSrcweir     }
308*cdf0e10cSrcweir     SetError( SbxERR_NO_METHOD );
309*cdf0e10cSrcweir     return sal_False;
310*cdf0e10cSrcweir }
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir SbxProperty* SbxObject::GetDfltProperty()
313*cdf0e10cSrcweir {
314*cdf0e10cSrcweir     if ( !pDfltProp && aDfltPropName.Len() )
315*cdf0e10cSrcweir     {
316*cdf0e10cSrcweir         pDfltProp = (SbxProperty*) Find( aDfltPropName, SbxCLASS_PROPERTY );
317*cdf0e10cSrcweir         if( !pDfltProp )
318*cdf0e10cSrcweir             pDfltProp = (SbxProperty*) Make( aDfltPropName, SbxCLASS_PROPERTY, SbxVARIANT );
319*cdf0e10cSrcweir     }
320*cdf0e10cSrcweir     return pDfltProp;
321*cdf0e10cSrcweir }
322*cdf0e10cSrcweir void SbxObject::SetDfltProperty( const XubString& rName )
323*cdf0e10cSrcweir {
324*cdf0e10cSrcweir     if ( rName != aDfltPropName )
325*cdf0e10cSrcweir         pDfltProp = NULL;
326*cdf0e10cSrcweir     aDfltPropName = rName;
327*cdf0e10cSrcweir     SetModified( sal_True );
328*cdf0e10cSrcweir }
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir void SbxObject::SetDfltProperty( SbxProperty* p )
331*cdf0e10cSrcweir {
332*cdf0e10cSrcweir     if( p )
333*cdf0e10cSrcweir     {
334*cdf0e10cSrcweir         sal_uInt16 n;
335*cdf0e10cSrcweir         SbxArray* pArray = FindVar( p, n );
336*cdf0e10cSrcweir         pArray->Put( p, n );
337*cdf0e10cSrcweir         if( p->GetParent() != this )
338*cdf0e10cSrcweir             p->SetParent( this );
339*cdf0e10cSrcweir         Broadcast( SBX_HINT_OBJECTCHANGED );
340*cdf0e10cSrcweir     }
341*cdf0e10cSrcweir     pDfltProp = p;
342*cdf0e10cSrcweir     SetModified( sal_True );
343*cdf0e10cSrcweir }
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir // Suchen einer bereits vorhandenen Variablen. Falls sie gefunden wurde,
346*cdf0e10cSrcweir // wird der Index gesetzt, sonst wird der Count des Arrays geliefert.
347*cdf0e10cSrcweir // In jedem Fall wird das korrekte Array geliefert.
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir SbxArray* SbxObject::FindVar( SbxVariable* pVar, sal_uInt16& nArrayIdx )
350*cdf0e10cSrcweir {
351*cdf0e10cSrcweir     SbxArray* pArray = NULL;
352*cdf0e10cSrcweir     if( pVar ) switch( pVar->GetClass() )
353*cdf0e10cSrcweir     {
354*cdf0e10cSrcweir         case SbxCLASS_VARIABLE:
355*cdf0e10cSrcweir         case SbxCLASS_PROPERTY: pArray = pProps;    break;
356*cdf0e10cSrcweir         case SbxCLASS_METHOD:   pArray = pMethods;  break;
357*cdf0e10cSrcweir         case SbxCLASS_OBJECT:   pArray = pObjs;     break;
358*cdf0e10cSrcweir         default:
359*cdf0e10cSrcweir             DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
360*cdf0e10cSrcweir     }
361*cdf0e10cSrcweir     if( pArray )
362*cdf0e10cSrcweir     {
363*cdf0e10cSrcweir         nArrayIdx = pArray->Count();
364*cdf0e10cSrcweir         // ist die Variable per Name vorhanden?
365*cdf0e10cSrcweir         pArray->ResetFlag( SBX_EXTSEARCH );
366*cdf0e10cSrcweir         SbxVariable* pOld = pArray->Find( pVar->GetName(), pVar->GetClass() );
367*cdf0e10cSrcweir         if( pOld )
368*cdf0e10cSrcweir           for( sal_uInt16 i = 0; i < pArray->Count(); i++ )
369*cdf0e10cSrcweir         {
370*cdf0e10cSrcweir             SbxVariableRef& rRef = pArray->GetRef( i );
371*cdf0e10cSrcweir             if( (SbxVariable*) rRef == pOld )
372*cdf0e10cSrcweir             {
373*cdf0e10cSrcweir                 nArrayIdx = i; break;
374*cdf0e10cSrcweir             }
375*cdf0e10cSrcweir         }
376*cdf0e10cSrcweir     }
377*cdf0e10cSrcweir     return pArray;
378*cdf0e10cSrcweir }
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir // Falls ein neues Objekt eingerichtet wird, wird es, falls es bereits
381*cdf0e10cSrcweir // eines mit diesem Namen gibt, indiziert.
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir SbxVariable* SbxObject::Make( const XubString& rName, SbxClassType ct, SbxDataType dt )
384*cdf0e10cSrcweir {
385*cdf0e10cSrcweir     // Ist das Objekt bereits vorhanden?
386*cdf0e10cSrcweir     SbxArray* pArray = NULL;
387*cdf0e10cSrcweir     switch( ct )
388*cdf0e10cSrcweir     {
389*cdf0e10cSrcweir         case SbxCLASS_VARIABLE:
390*cdf0e10cSrcweir         case SbxCLASS_PROPERTY: pArray = pProps;    break;
391*cdf0e10cSrcweir         case SbxCLASS_METHOD:   pArray = pMethods;  break;
392*cdf0e10cSrcweir         case SbxCLASS_OBJECT:   pArray = pObjs;     break;
393*cdf0e10cSrcweir         default:
394*cdf0e10cSrcweir             DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
395*cdf0e10cSrcweir     }
396*cdf0e10cSrcweir     if( !pArray )
397*cdf0e10cSrcweir         return NULL;
398*cdf0e10cSrcweir     // Collections duerfen gleichnamige Objekte enthalten
399*cdf0e10cSrcweir     if( !( ct == SbxCLASS_OBJECT && ISA(SbxCollection) ) )
400*cdf0e10cSrcweir     {
401*cdf0e10cSrcweir         SbxVariable* pRes = pArray->Find( rName, ct );
402*cdf0e10cSrcweir         if( pRes )
403*cdf0e10cSrcweir         {
404*cdf0e10cSrcweir /* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
405*cdf0e10cSrcweir #ifdef DBG_UTIL
406*cdf0e10cSrcweir             if( pRes->GetHashCode() != nNameHash
407*cdf0e10cSrcweir              && pRes->GetHashCode() != nParentHash )
408*cdf0e10cSrcweir             {
409*cdf0e10cSrcweir                 XubString aMsg( "SBX-Element \"" );
410*cdf0e10cSrcweir                 aMsg += pRes->GetName();
411*cdf0e10cSrcweir                 aMsg += "\"\n in Objekt \"";
412*cdf0e10cSrcweir                 aMsg += GetName();
413*cdf0e10cSrcweir                 aMsg += "\" bereits vorhanden";
414*cdf0e10cSrcweir                 DbgError( (const char*)aMsg.GetStr() );
415*cdf0e10cSrcweir             }
416*cdf0e10cSrcweir #endif
417*cdf0e10cSrcweir */
418*cdf0e10cSrcweir             return pRes;
419*cdf0e10cSrcweir         }
420*cdf0e10cSrcweir     }
421*cdf0e10cSrcweir     SbxVariable* pVar = NULL;
422*cdf0e10cSrcweir     switch( ct )
423*cdf0e10cSrcweir     {
424*cdf0e10cSrcweir         case SbxCLASS_VARIABLE:
425*cdf0e10cSrcweir         case SbxCLASS_PROPERTY:
426*cdf0e10cSrcweir             pVar = new SbxProperty( rName, dt );
427*cdf0e10cSrcweir             break;
428*cdf0e10cSrcweir         case SbxCLASS_METHOD:
429*cdf0e10cSrcweir             pVar = new SbxMethod( rName, dt );
430*cdf0e10cSrcweir             break;
431*cdf0e10cSrcweir         case SbxCLASS_OBJECT:
432*cdf0e10cSrcweir             pVar = CreateObject( rName );
433*cdf0e10cSrcweir             break;
434*cdf0e10cSrcweir         default: break;
435*cdf0e10cSrcweir     }
436*cdf0e10cSrcweir     pVar->SetParent( this );
437*cdf0e10cSrcweir     pArray->Put( pVar, pArray->Count() );
438*cdf0e10cSrcweir     SetModified( sal_True );
439*cdf0e10cSrcweir     // Das Objekt lauscht immer
440*cdf0e10cSrcweir     StartListening( pVar->GetBroadcaster(), sal_True );
441*cdf0e10cSrcweir     Broadcast( SBX_HINT_OBJECTCHANGED );
442*cdf0e10cSrcweir     return pVar;
443*cdf0e10cSrcweir }
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir SbxObject* SbxObject::MakeObject( const XubString& rName, const XubString& rClass )
446*cdf0e10cSrcweir {
447*cdf0e10cSrcweir     // Ist das Objekt bereits vorhanden?
448*cdf0e10cSrcweir     if( !ISA(SbxCollection) )
449*cdf0e10cSrcweir     {
450*cdf0e10cSrcweir         SbxVariable* pRes = pObjs->Find( rName, SbxCLASS_OBJECT );
451*cdf0e10cSrcweir         if( pRes )
452*cdf0e10cSrcweir         {
453*cdf0e10cSrcweir /* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
454*cdf0e10cSrcweir #ifdef DBG_UTIL
455*cdf0e10cSrcweir             if( pRes->GetHashCode() != nNameHash
456*cdf0e10cSrcweir              && pRes->GetHashCode() != nParentHash )
457*cdf0e10cSrcweir             {
458*cdf0e10cSrcweir                 XubString aMsg( "SBX-Objekt \"" );
459*cdf0e10cSrcweir                 aMsg += pRes->GetName();
460*cdf0e10cSrcweir                 aMsg += "\"\n in Objekt \"";
461*cdf0e10cSrcweir                 aMsg += GetName();
462*cdf0e10cSrcweir                 aMsg += "\" bereits vorhanden";
463*cdf0e10cSrcweir                 DbgError( (const char*)aMsg.GetStr() );
464*cdf0e10cSrcweir             }
465*cdf0e10cSrcweir #endif
466*cdf0e10cSrcweir */
467*cdf0e10cSrcweir             return PTR_CAST(SbxObject,pRes);
468*cdf0e10cSrcweir         }
469*cdf0e10cSrcweir     }
470*cdf0e10cSrcweir     SbxObject* pVar = CreateObject( rClass );
471*cdf0e10cSrcweir     if( pVar )
472*cdf0e10cSrcweir     {
473*cdf0e10cSrcweir         pVar->SetName( rName );
474*cdf0e10cSrcweir         pVar->SetParent( this );
475*cdf0e10cSrcweir         pObjs->Put( pVar, pObjs->Count() );
476*cdf0e10cSrcweir         SetModified( sal_True );
477*cdf0e10cSrcweir         // Das Objekt lauscht immer
478*cdf0e10cSrcweir         StartListening( pVar->GetBroadcaster(), sal_True );
479*cdf0e10cSrcweir         Broadcast( SBX_HINT_OBJECTCHANGED );
480*cdf0e10cSrcweir     }
481*cdf0e10cSrcweir     return pVar;
482*cdf0e10cSrcweir }
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir void SbxObject::Insert( SbxVariable* pVar )
485*cdf0e10cSrcweir {
486*cdf0e10cSrcweir     sal_uInt16 nIdx;
487*cdf0e10cSrcweir     SbxArray* pArray = FindVar( pVar, nIdx );
488*cdf0e10cSrcweir     if( pArray )
489*cdf0e10cSrcweir     {
490*cdf0e10cSrcweir         // Hinein damit. Man sollte allerdings auf die Pointer aufpassen!
491*cdf0e10cSrcweir         if( nIdx < pArray->Count() )
492*cdf0e10cSrcweir         {
493*cdf0e10cSrcweir             // dann gibt es dieses Element bereits
494*cdf0e10cSrcweir             // Bei Collections duerfen gleichnamige Objekte hinein
495*cdf0e10cSrcweir             if( pArray == pObjs && ISA(SbxCollection) )
496*cdf0e10cSrcweir                 nIdx = pArray->Count();
497*cdf0e10cSrcweir             else
498*cdf0e10cSrcweir             {
499*cdf0e10cSrcweir                 SbxVariable* pOld = pArray->Get( nIdx );
500*cdf0e10cSrcweir                 // schon drin: ueberschreiben
501*cdf0e10cSrcweir                 if( pOld == pVar )
502*cdf0e10cSrcweir                     return;
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir /* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
505*cdf0e10cSrcweir #ifdef DBG_UTIL
506*cdf0e10cSrcweir                 if( pOld->GetHashCode() != nNameHash
507*cdf0e10cSrcweir                  && pOld->GetHashCode() != nParentHash )
508*cdf0e10cSrcweir                 {
509*cdf0e10cSrcweir                     XubString aMsg( "SBX-Element \"" );
510*cdf0e10cSrcweir                     aMsg += pVar->GetName();
511*cdf0e10cSrcweir                     aMsg += "\"\n in Objekt \"";
512*cdf0e10cSrcweir                     aMsg += GetName();
513*cdf0e10cSrcweir                     aMsg += "\" bereits vorhanden";
514*cdf0e10cSrcweir                     DbgError( (const char*)aMsg.GetStr() );
515*cdf0e10cSrcweir                 }
516*cdf0e10cSrcweir #endif
517*cdf0e10cSrcweir */
518*cdf0e10cSrcweir                 EndListening( pOld->GetBroadcaster(), sal_True );
519*cdf0e10cSrcweir                 if( pVar->GetClass() == SbxCLASS_PROPERTY )
520*cdf0e10cSrcweir                 {
521*cdf0e10cSrcweir                     if( pOld == pDfltProp )
522*cdf0e10cSrcweir                         pDfltProp = (SbxProperty*) pVar;
523*cdf0e10cSrcweir                 }
524*cdf0e10cSrcweir             }
525*cdf0e10cSrcweir         }
526*cdf0e10cSrcweir         StartListening( pVar->GetBroadcaster(), sal_True );
527*cdf0e10cSrcweir         pArray->Put( pVar, nIdx );
528*cdf0e10cSrcweir         if( pVar->GetParent() != this )
529*cdf0e10cSrcweir             pVar->SetParent( this );
530*cdf0e10cSrcweir         SetModified( sal_True );
531*cdf0e10cSrcweir         Broadcast( SBX_HINT_OBJECTCHANGED );
532*cdf0e10cSrcweir #ifdef DBG_UTIL
533*cdf0e10cSrcweir     static const char* pCls[] =
534*cdf0e10cSrcweir     { "DontCare","Array","Value","Variable","Method","Property","Object" };
535*cdf0e10cSrcweir     XubString aVarName( pVar->GetName() );
536*cdf0e10cSrcweir     if ( !aVarName.Len() && pVar->ISA(SbxObject) )
537*cdf0e10cSrcweir         aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
538*cdf0e10cSrcweir     ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
539*cdf0e10cSrcweir     ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
540*cdf0e10cSrcweir     DbgOutf( "SBX: Insert %s %s in %s",
541*cdf0e10cSrcweir         ( pVar->GetClass() >= SbxCLASS_DONTCARE &&
542*cdf0e10cSrcweir           pVar->GetClass() <= SbxCLASS_OBJECT )
543*cdf0e10cSrcweir             ? pCls[ pVar->GetClass()-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
544*cdf0e10cSrcweir #endif
545*cdf0e10cSrcweir     }
546*cdf0e10cSrcweir }
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir // AB 23.4.1997, Optimierung, Einfuegen ohne Ueberpruefung auf doppelte
549*cdf0e10cSrcweir // Eintraege und ohne Broadcasts, wird nur in SO2/auto.cxx genutzt
550*cdf0e10cSrcweir void SbxObject::QuickInsert( SbxVariable* pVar )
551*cdf0e10cSrcweir {
552*cdf0e10cSrcweir     SbxArray* pArray = NULL;
553*cdf0e10cSrcweir     if( pVar )
554*cdf0e10cSrcweir     {
555*cdf0e10cSrcweir         switch( pVar->GetClass() )
556*cdf0e10cSrcweir         {
557*cdf0e10cSrcweir             case SbxCLASS_VARIABLE:
558*cdf0e10cSrcweir             case SbxCLASS_PROPERTY: pArray = pProps;    break;
559*cdf0e10cSrcweir             case SbxCLASS_METHOD:   pArray = pMethods;  break;
560*cdf0e10cSrcweir             case SbxCLASS_OBJECT:   pArray = pObjs;     break;
561*cdf0e10cSrcweir             default:
562*cdf0e10cSrcweir                 DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
563*cdf0e10cSrcweir         }
564*cdf0e10cSrcweir     }
565*cdf0e10cSrcweir     if( pArray )
566*cdf0e10cSrcweir     {
567*cdf0e10cSrcweir         StartListening( pVar->GetBroadcaster(), sal_True );
568*cdf0e10cSrcweir         pArray->Put( pVar, pArray->Count() );
569*cdf0e10cSrcweir         if( pVar->GetParent() != this )
570*cdf0e10cSrcweir             pVar->SetParent( this );
571*cdf0e10cSrcweir         SetModified( sal_True );
572*cdf0e10cSrcweir #ifdef DBG_UTIL
573*cdf0e10cSrcweir     static const char* pCls[] =
574*cdf0e10cSrcweir     { "DontCare","Array","Value","Variable","Method","Property","Object" };
575*cdf0e10cSrcweir     XubString aVarName( pVar->GetName() );
576*cdf0e10cSrcweir     if ( !aVarName.Len() && pVar->ISA(SbxObject) )
577*cdf0e10cSrcweir         aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
578*cdf0e10cSrcweir     ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
579*cdf0e10cSrcweir     ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
580*cdf0e10cSrcweir     DbgOutf( "SBX: Insert %s %s in %s",
581*cdf0e10cSrcweir         ( pVar->GetClass() >= SbxCLASS_DONTCARE &&
582*cdf0e10cSrcweir           pVar->GetClass() <= SbxCLASS_OBJECT )
583*cdf0e10cSrcweir             ? pCls[ pVar->GetClass()-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
584*cdf0e10cSrcweir #endif
585*cdf0e10cSrcweir     }
586*cdf0e10cSrcweir }
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir // AB 23.3.1997, Spezial-Methode, gleichnamige Controls zulassen
589*cdf0e10cSrcweir void SbxObject::VCPtrInsert( SbxVariable* pVar )
590*cdf0e10cSrcweir {
591*cdf0e10cSrcweir     SbxArray* pArray = NULL;
592*cdf0e10cSrcweir     if( pVar )
593*cdf0e10cSrcweir     {
594*cdf0e10cSrcweir         switch( pVar->GetClass() )
595*cdf0e10cSrcweir         {
596*cdf0e10cSrcweir             case SbxCLASS_VARIABLE:
597*cdf0e10cSrcweir             case SbxCLASS_PROPERTY: pArray = pProps;    break;
598*cdf0e10cSrcweir             case SbxCLASS_METHOD:   pArray = pMethods;  break;
599*cdf0e10cSrcweir             case SbxCLASS_OBJECT:   pArray = pObjs;     break;
600*cdf0e10cSrcweir             default:
601*cdf0e10cSrcweir                 DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
602*cdf0e10cSrcweir         }
603*cdf0e10cSrcweir     }
604*cdf0e10cSrcweir     if( pArray )
605*cdf0e10cSrcweir     {
606*cdf0e10cSrcweir         StartListening( pVar->GetBroadcaster(), sal_True );
607*cdf0e10cSrcweir         pArray->Put( pVar, pArray->Count() );
608*cdf0e10cSrcweir         if( pVar->GetParent() != this )
609*cdf0e10cSrcweir             pVar->SetParent( this );
610*cdf0e10cSrcweir         SetModified( sal_True );
611*cdf0e10cSrcweir         Broadcast( SBX_HINT_OBJECTCHANGED );
612*cdf0e10cSrcweir     }
613*cdf0e10cSrcweir }
614*cdf0e10cSrcweir 
615*cdf0e10cSrcweir void SbxObject::Remove( const XubString& rName, SbxClassType t )
616*cdf0e10cSrcweir {
617*cdf0e10cSrcweir     Remove( SbxObject::Find( rName, t ) );
618*cdf0e10cSrcweir }
619*cdf0e10cSrcweir 
620*cdf0e10cSrcweir void SbxObject::Remove( SbxVariable* pVar )
621*cdf0e10cSrcweir {
622*cdf0e10cSrcweir     sal_uInt16 nIdx;
623*cdf0e10cSrcweir     SbxArray* pArray = FindVar( pVar, nIdx );
624*cdf0e10cSrcweir     if( pArray && nIdx < pArray->Count() )
625*cdf0e10cSrcweir     {
626*cdf0e10cSrcweir #ifdef DBG_UTIL
627*cdf0e10cSrcweir     XubString aVarName( pVar->GetName() );
628*cdf0e10cSrcweir     if ( !aVarName.Len() && pVar->ISA(SbxObject) )
629*cdf0e10cSrcweir         aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
630*cdf0e10cSrcweir     ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
631*cdf0e10cSrcweir     ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
632*cdf0e10cSrcweir #endif
633*cdf0e10cSrcweir         SbxVariableRef pVar_ = pArray->Get( nIdx );
634*cdf0e10cSrcweir         if( pVar_->IsBroadcaster() )
635*cdf0e10cSrcweir             EndListening( pVar_->GetBroadcaster(), sal_True );
636*cdf0e10cSrcweir         if( (SbxVariable*) pVar_ == pDfltProp )
637*cdf0e10cSrcweir             pDfltProp = NULL;
638*cdf0e10cSrcweir         pArray->Remove( nIdx );
639*cdf0e10cSrcweir         if( pVar_->GetParent() == this )
640*cdf0e10cSrcweir             pVar_->SetParent( NULL );
641*cdf0e10cSrcweir         SetModified( sal_True );
642*cdf0e10cSrcweir         Broadcast( SBX_HINT_OBJECTCHANGED );
643*cdf0e10cSrcweir     }
644*cdf0e10cSrcweir }
645*cdf0e10cSrcweir 
646*cdf0e10cSrcweir // AB 23.3.1997, Loeschen per Pointer fuer Controls (doppelte Namen!)
647*cdf0e10cSrcweir void SbxObject::VCPtrRemove( SbxVariable* pVar )
648*cdf0e10cSrcweir {
649*cdf0e10cSrcweir     sal_uInt16 nIdx;
650*cdf0e10cSrcweir     // Neu FindVar-Methode, sonst identisch mit normaler Methode
651*cdf0e10cSrcweir     SbxArray* pArray = VCPtrFindVar( pVar, nIdx );
652*cdf0e10cSrcweir     if( pArray && nIdx < pArray->Count() )
653*cdf0e10cSrcweir     {
654*cdf0e10cSrcweir         SbxVariableRef xVar = pArray->Get( nIdx );
655*cdf0e10cSrcweir         if( xVar->IsBroadcaster() )
656*cdf0e10cSrcweir             EndListening( xVar->GetBroadcaster(), sal_True );
657*cdf0e10cSrcweir         if( (SbxVariable*) xVar == pDfltProp )
658*cdf0e10cSrcweir             pDfltProp = NULL;
659*cdf0e10cSrcweir         pArray->Remove( nIdx );
660*cdf0e10cSrcweir         if( xVar->GetParent() == this )
661*cdf0e10cSrcweir             xVar->SetParent( NULL );
662*cdf0e10cSrcweir         SetModified( sal_True );
663*cdf0e10cSrcweir         Broadcast( SBX_HINT_OBJECTCHANGED );
664*cdf0e10cSrcweir     }
665*cdf0e10cSrcweir }
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir // AB 23.3.1997, Zugehoerige Spezial-Methode, nur ueber Pointer suchen
668*cdf0e10cSrcweir SbxArray* SbxObject::VCPtrFindVar( SbxVariable* pVar, sal_uInt16& nArrayIdx )
669*cdf0e10cSrcweir {
670*cdf0e10cSrcweir     SbxArray* pArray = NULL;
671*cdf0e10cSrcweir     if( pVar ) switch( pVar->GetClass() )
672*cdf0e10cSrcweir     {
673*cdf0e10cSrcweir         case SbxCLASS_VARIABLE:
674*cdf0e10cSrcweir         case SbxCLASS_PROPERTY: pArray = pProps;    break;
675*cdf0e10cSrcweir         case SbxCLASS_METHOD:   pArray = pMethods;  break;
676*cdf0e10cSrcweir         case SbxCLASS_OBJECT:   pArray = pObjs;     break;
677*cdf0e10cSrcweir         default:
678*cdf0e10cSrcweir             DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
679*cdf0e10cSrcweir     }
680*cdf0e10cSrcweir     if( pArray )
681*cdf0e10cSrcweir     {
682*cdf0e10cSrcweir         nArrayIdx = pArray->Count();
683*cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < pArray->Count(); i++ )
684*cdf0e10cSrcweir         {
685*cdf0e10cSrcweir             SbxVariableRef& rRef = pArray->GetRef( i );
686*cdf0e10cSrcweir             if( (SbxVariable*) rRef == pVar )
687*cdf0e10cSrcweir             {
688*cdf0e10cSrcweir                 nArrayIdx = i; break;
689*cdf0e10cSrcweir             }
690*cdf0e10cSrcweir         }
691*cdf0e10cSrcweir     }
692*cdf0e10cSrcweir     return pArray;
693*cdf0e10cSrcweir }
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir void SbxObject::SetPos( SbxVariable* pVar, sal_uInt16 nPos )
698*cdf0e10cSrcweir {
699*cdf0e10cSrcweir     sal_uInt16 nIdx;
700*cdf0e10cSrcweir     SbxArray* pArray = FindVar( pVar, nIdx );
701*cdf0e10cSrcweir     if( pArray )
702*cdf0e10cSrcweir     {
703*cdf0e10cSrcweir         if( nPos >= pArray->Count() )
704*cdf0e10cSrcweir             nPos = pArray->Count() - 1;
705*cdf0e10cSrcweir         if( nIdx < ( pArray->Count() - 1 ) )
706*cdf0e10cSrcweir         {
707*cdf0e10cSrcweir             SbxVariableRef refVar = pArray->Get( nIdx );
708*cdf0e10cSrcweir             pArray->Remove( nIdx );
709*cdf0e10cSrcweir             pArray->Insert( refVar, nPos );
710*cdf0e10cSrcweir         }
711*cdf0e10cSrcweir     }
712*cdf0e10cSrcweir //  SetModified( sal_True );
713*cdf0e10cSrcweir //  Broadcast( SBX_HINT_OBJECTCHANGED );
714*cdf0e10cSrcweir }
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir static sal_Bool LoadArray( SvStream& rStrm, SbxObject* pThis, SbxArray* pArray )
717*cdf0e10cSrcweir {
718*cdf0e10cSrcweir     SbxArrayRef p = (SbxArray*) SbxBase::Load( rStrm );
719*cdf0e10cSrcweir     if( !p.Is() )
720*cdf0e10cSrcweir         return sal_False;
721*cdf0e10cSrcweir     for( sal_uInt16 i = 0; i < p->Count(); i++ )
722*cdf0e10cSrcweir     {
723*cdf0e10cSrcweir         SbxVariableRef& r = p->GetRef( i );
724*cdf0e10cSrcweir         SbxVariable* pVar = r;
725*cdf0e10cSrcweir         if( pVar )
726*cdf0e10cSrcweir         {
727*cdf0e10cSrcweir             pVar->SetParent( pThis );
728*cdf0e10cSrcweir             pThis->StartListening( pVar->GetBroadcaster(), sal_True );
729*cdf0e10cSrcweir         }
730*cdf0e10cSrcweir     }
731*cdf0e10cSrcweir     pArray->Merge( p );
732*cdf0e10cSrcweir     return sal_True;
733*cdf0e10cSrcweir }
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir // Der Load eines Objekts ist additiv!
736*cdf0e10cSrcweir 
737*cdf0e10cSrcweir sal_Bool SbxObject::LoadData( SvStream& rStrm, sal_uInt16 nVer )
738*cdf0e10cSrcweir {
739*cdf0e10cSrcweir     // Hilfe fuer das Einlesen alter Objekte: einfach sal_True zurueck,
740*cdf0e10cSrcweir     // LoadPrivateData() muss Default-Zustand herstellen
741*cdf0e10cSrcweir     if( !nVer )
742*cdf0e10cSrcweir         return sal_True;
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir     pDfltProp = NULL;
745*cdf0e10cSrcweir     if( !SbxVariable::LoadData( rStrm, nVer ) )
746*cdf0e10cSrcweir         return sal_False;
747*cdf0e10cSrcweir     // Wenn kein fremdes Objekt enthalten ist, uns selbst eintragen
748*cdf0e10cSrcweir     if( aData.eType == SbxOBJECT && !aData.pObj )
749*cdf0e10cSrcweir         aData.pObj = this;
750*cdf0e10cSrcweir     sal_uInt32 nSize;
751*cdf0e10cSrcweir     XubString aDfltProp;
752*cdf0e10cSrcweir     rStrm.ReadByteString( aClassName, RTL_TEXTENCODING_ASCII_US );
753*cdf0e10cSrcweir     rStrm.ReadByteString( aDfltProp, RTL_TEXTENCODING_ASCII_US );
754*cdf0e10cSrcweir     sal_uIntPtr nPos = rStrm.Tell();
755*cdf0e10cSrcweir     rStrm >> nSize;
756*cdf0e10cSrcweir     if( !LoadPrivateData( rStrm, nVer ) )
757*cdf0e10cSrcweir         return sal_False;
758*cdf0e10cSrcweir     sal_uIntPtr nNewPos = rStrm.Tell();
759*cdf0e10cSrcweir     nPos += nSize;
760*cdf0e10cSrcweir     DBG_ASSERT( nPos >= nNewPos, "SBX: Zu viele Daten eingelesen" );
761*cdf0e10cSrcweir     if( nPos != nNewPos )
762*cdf0e10cSrcweir         rStrm.Seek( nPos );
763*cdf0e10cSrcweir     if( !LoadArray( rStrm, this, pMethods )
764*cdf0e10cSrcweir      || !LoadArray( rStrm, this, pProps )
765*cdf0e10cSrcweir      || !LoadArray( rStrm, this, pObjs ) )
766*cdf0e10cSrcweir         return sal_False;
767*cdf0e10cSrcweir     // Properties setzen
768*cdf0e10cSrcweir     if( aDfltProp.Len() )
769*cdf0e10cSrcweir         pDfltProp = (SbxProperty*) pProps->Find( aDfltProp, SbxCLASS_PROPERTY );
770*cdf0e10cSrcweir     SetModified( sal_False );
771*cdf0e10cSrcweir     return sal_True;
772*cdf0e10cSrcweir }
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir sal_Bool SbxObject::StoreData( SvStream& rStrm ) const
775*cdf0e10cSrcweir {
776*cdf0e10cSrcweir     if( !SbxVariable::StoreData( rStrm ) )
777*cdf0e10cSrcweir         return sal_False;
778*cdf0e10cSrcweir     XubString aDfltProp;
779*cdf0e10cSrcweir     if( pDfltProp )
780*cdf0e10cSrcweir         aDfltProp = pDfltProp->GetName();
781*cdf0e10cSrcweir     rStrm.WriteByteString( aClassName, RTL_TEXTENCODING_ASCII_US );
782*cdf0e10cSrcweir     rStrm.WriteByteString( aDfltProp, RTL_TEXTENCODING_ASCII_US );
783*cdf0e10cSrcweir     sal_uIntPtr nPos = rStrm.Tell();
784*cdf0e10cSrcweir     rStrm << (sal_uInt32) 0L;
785*cdf0e10cSrcweir     if( !StorePrivateData( rStrm ) )
786*cdf0e10cSrcweir         return sal_False;
787*cdf0e10cSrcweir     sal_uIntPtr nNew = rStrm.Tell();
788*cdf0e10cSrcweir     rStrm.Seek( nPos );
789*cdf0e10cSrcweir     rStrm << (sal_uInt32) ( nNew - nPos );
790*cdf0e10cSrcweir     rStrm.Seek( nNew );
791*cdf0e10cSrcweir     if( !pMethods->Store( rStrm ) )
792*cdf0e10cSrcweir         return sal_False;
793*cdf0e10cSrcweir     if( !pProps->Store( rStrm ) )
794*cdf0e10cSrcweir         return sal_False;
795*cdf0e10cSrcweir     if( !pObjs->Store( rStrm ) )
796*cdf0e10cSrcweir         return sal_False;
797*cdf0e10cSrcweir     ((SbxObject*) this)->SetModified( sal_False );
798*cdf0e10cSrcweir     return sal_True;
799*cdf0e10cSrcweir }
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir XubString SbxObject::GenerateSource( const XubString &rLinePrefix,
802*cdf0e10cSrcweir                                   const SbxObject* )
803*cdf0e10cSrcweir {
804*cdf0e10cSrcweir     // Properties in einem String einsammeln
805*cdf0e10cSrcweir     XubString aSource;
806*cdf0e10cSrcweir     SbxArrayRef xProps( GetProperties() );
807*cdf0e10cSrcweir     bool bLineFeed = false;
808*cdf0e10cSrcweir     for ( sal_uInt16 nProp = 0; nProp < xProps->Count(); ++nProp )
809*cdf0e10cSrcweir     {
810*cdf0e10cSrcweir         SbxPropertyRef xProp = (SbxProperty*) xProps->Get(nProp);
811*cdf0e10cSrcweir         XubString aPropName( xProp->GetName() );
812*cdf0e10cSrcweir         if ( xProp->CanWrite()
813*cdf0e10cSrcweir          && !( xProp->GetHashCode() == nNameHash
814*cdf0e10cSrcweir             && aPropName.EqualsIgnoreCaseAscii( pNameProp ) ) )
815*cdf0e10cSrcweir         {
816*cdf0e10cSrcweir             // ausser vor dem ersten Property immer einen Umbruch einfuegen
817*cdf0e10cSrcweir             if ( bLineFeed )
818*cdf0e10cSrcweir                 aSource.AppendAscii( "\n" );
819*cdf0e10cSrcweir             else
820*cdf0e10cSrcweir                 bLineFeed = true;
821*cdf0e10cSrcweir 
822*cdf0e10cSrcweir             aSource += rLinePrefix;
823*cdf0e10cSrcweir             aSource += '.';
824*cdf0e10cSrcweir             aSource += aPropName;
825*cdf0e10cSrcweir             aSource.AppendAscii( " = " );
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir             // den Property-Wert textuell darstellen
828*cdf0e10cSrcweir             switch ( xProp->GetType() )
829*cdf0e10cSrcweir             {
830*cdf0e10cSrcweir                 case SbxEMPTY:
831*cdf0e10cSrcweir                 case SbxNULL:
832*cdf0e10cSrcweir                     // kein Wert
833*cdf0e10cSrcweir                     break;
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir                 case SbxSTRING:
836*cdf0e10cSrcweir                 {
837*cdf0e10cSrcweir                     // Strings in Anf"uhrungszeichen
838*cdf0e10cSrcweir                     aSource.AppendAscii( "\"" );
839*cdf0e10cSrcweir                     aSource += xProp->GetString();
840*cdf0e10cSrcweir                     aSource.AppendAscii( "\"" );
841*cdf0e10cSrcweir                     break;
842*cdf0e10cSrcweir                 }
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir                 default:
845*cdf0e10cSrcweir                 {
846*cdf0e10cSrcweir                     // sonstiges wie z.B. Zahlen direkt
847*cdf0e10cSrcweir                     aSource += xProp->GetString();
848*cdf0e10cSrcweir                     break;
849*cdf0e10cSrcweir                 }
850*cdf0e10cSrcweir             }
851*cdf0e10cSrcweir         }
852*cdf0e10cSrcweir     }
853*cdf0e10cSrcweir     return aSource;
854*cdf0e10cSrcweir }
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir static sal_Bool CollectAttrs( const SbxBase* p, XubString& rRes )
857*cdf0e10cSrcweir {
858*cdf0e10cSrcweir     XubString aAttrs;
859*cdf0e10cSrcweir     if( p->IsHidden() )
860*cdf0e10cSrcweir         aAttrs.AssignAscii( "Hidden" );
861*cdf0e10cSrcweir     if( p->IsSet( SBX_EXTSEARCH ) )
862*cdf0e10cSrcweir     {
863*cdf0e10cSrcweir         if( aAttrs.Len() )
864*cdf0e10cSrcweir             aAttrs += ',';
865*cdf0e10cSrcweir         aAttrs.AppendAscii( "ExtSearch" );
866*cdf0e10cSrcweir     }
867*cdf0e10cSrcweir     if( !p->IsVisible() )
868*cdf0e10cSrcweir     {
869*cdf0e10cSrcweir         if( aAttrs.Len() )
870*cdf0e10cSrcweir             aAttrs += ',';
871*cdf0e10cSrcweir         aAttrs.AppendAscii( "Invisible" );
872*cdf0e10cSrcweir     }
873*cdf0e10cSrcweir     if( p->IsSet( SBX_DONTSTORE ) )
874*cdf0e10cSrcweir     {
875*cdf0e10cSrcweir         if( aAttrs.Len() )
876*cdf0e10cSrcweir             aAttrs += ',';
877*cdf0e10cSrcweir         aAttrs.AppendAscii( "DontStore" );
878*cdf0e10cSrcweir     }
879*cdf0e10cSrcweir     if( aAttrs.Len() )
880*cdf0e10cSrcweir     {
881*cdf0e10cSrcweir         rRes.AssignAscii( " (" );
882*cdf0e10cSrcweir         rRes += aAttrs;
883*cdf0e10cSrcweir         rRes += ')';
884*cdf0e10cSrcweir         return sal_True;
885*cdf0e10cSrcweir     }
886*cdf0e10cSrcweir     else
887*cdf0e10cSrcweir     {
888*cdf0e10cSrcweir         rRes.Erase();
889*cdf0e10cSrcweir         return sal_False;
890*cdf0e10cSrcweir     }
891*cdf0e10cSrcweir }
892*cdf0e10cSrcweir 
893*cdf0e10cSrcweir void SbxObject::Dump( SvStream& rStrm, sal_Bool bFill )
894*cdf0e10cSrcweir {
895*cdf0e10cSrcweir     // Einr"uckung
896*cdf0e10cSrcweir     static sal_uInt16 nLevel = 0;
897*cdf0e10cSrcweir     if ( nLevel > 10 )
898*cdf0e10cSrcweir     {
899*cdf0e10cSrcweir         rStrm << "<too deep>" << endl;
900*cdf0e10cSrcweir         return;
901*cdf0e10cSrcweir     }
902*cdf0e10cSrcweir     ++nLevel;
903*cdf0e10cSrcweir     String aIndent;
904*cdf0e10cSrcweir     for ( sal_uInt16 n = 1; n < nLevel; ++n )
905*cdf0e10cSrcweir         aIndent.AppendAscii( "    " );
906*cdf0e10cSrcweir 
907*cdf0e10cSrcweir     // ggf. Objekt vervollst"andigen
908*cdf0e10cSrcweir     if ( bFill )
909*cdf0e10cSrcweir         GetAll( SbxCLASS_DONTCARE );
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir     // Daten des Objekts selbst ausgeben
912*cdf0e10cSrcweir     ByteString aNameStr( (const UniString&)GetName(), RTL_TEXTENCODING_ASCII_US );
913*cdf0e10cSrcweir     ByteString aClassNameStr( (const UniString&)aClassName, RTL_TEXTENCODING_ASCII_US );
914*cdf0e10cSrcweir     rStrm << "Object( "
915*cdf0e10cSrcweir           << ByteString::CreateFromInt64( (sal_uIntPtr) this ).GetBuffer() << "=='"
916*cdf0e10cSrcweir           << ( aNameStr.Len() ? aNameStr.GetBuffer() : "<unnamed>" ) << "', "
917*cdf0e10cSrcweir           << "of class '" << aClassNameStr.GetBuffer() << "', "
918*cdf0e10cSrcweir           << "counts "
919*cdf0e10cSrcweir           << ByteString::CreateFromInt64( GetRefCount() ).GetBuffer()
920*cdf0e10cSrcweir           << " refs, ";
921*cdf0e10cSrcweir     if ( GetParent() )
922*cdf0e10cSrcweir     {
923*cdf0e10cSrcweir         ByteString aParentNameStr( (const UniString&)GetName(), RTL_TEXTENCODING_ASCII_US );
924*cdf0e10cSrcweir         rStrm << "in parent "
925*cdf0e10cSrcweir               << ByteString::CreateFromInt64( (sal_uIntPtr) GetParent() ).GetBuffer()
926*cdf0e10cSrcweir               << "=='" << ( aParentNameStr.Len() ? aParentNameStr.GetBuffer() : "<unnamed>" ) << "'";
927*cdf0e10cSrcweir     }
928*cdf0e10cSrcweir     else
929*cdf0e10cSrcweir         rStrm << "no parent ";
930*cdf0e10cSrcweir     rStrm << " )" << endl;
931*cdf0e10cSrcweir     ByteString aIndentNameStr( (const UniString&)aIndent, RTL_TEXTENCODING_ASCII_US );
932*cdf0e10cSrcweir     rStrm << aIndentNameStr.GetBuffer() << "{" << endl;
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir     // Flags
935*cdf0e10cSrcweir     XubString aAttrs;
936*cdf0e10cSrcweir     if( CollectAttrs( this, aAttrs ) )
937*cdf0e10cSrcweir     {
938*cdf0e10cSrcweir         ByteString aAttrStr( (const UniString&)aAttrs, RTL_TEXTENCODING_ASCII_US );
939*cdf0e10cSrcweir         rStrm << aIndentNameStr.GetBuffer() << "- Flags: " << aAttrStr.GetBuffer() << endl;
940*cdf0e10cSrcweir     }
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir     // Methods
943*cdf0e10cSrcweir     rStrm << aIndentNameStr.GetBuffer() << "- Methods:" << endl;
944*cdf0e10cSrcweir     for( sal_uInt16 i = 0; i < pMethods->Count(); i++ )
945*cdf0e10cSrcweir     {
946*cdf0e10cSrcweir         SbxVariableRef& r = pMethods->GetRef( i );
947*cdf0e10cSrcweir         SbxVariable* pVar = r;
948*cdf0e10cSrcweir         if( pVar )
949*cdf0e10cSrcweir         {
950*cdf0e10cSrcweir             XubString aLine( aIndent );
951*cdf0e10cSrcweir             aLine.AppendAscii( "  - " );
952*cdf0e10cSrcweir             aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
953*cdf0e10cSrcweir             XubString aAttrs2;
954*cdf0e10cSrcweir             if( CollectAttrs( pVar, aAttrs2 ) )
955*cdf0e10cSrcweir                 aLine += aAttrs2;
956*cdf0e10cSrcweir             if( !pVar->IsA( TYPE(SbxMethod) ) )
957*cdf0e10cSrcweir                 aLine.AppendAscii( "  !! Not a Method !!" );
958*cdf0e10cSrcweir             rStrm.WriteByteString( aLine, RTL_TEXTENCODING_ASCII_US );
959*cdf0e10cSrcweir 
960*cdf0e10cSrcweir             // bei Object-Methods auch das Object ausgeben
961*cdf0e10cSrcweir             if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
962*cdf0e10cSrcweir                     pVar->GetValues_Impl().pObj &&
963*cdf0e10cSrcweir                     pVar->GetValues_Impl().pObj != this &&
964*cdf0e10cSrcweir                     pVar->GetValues_Impl().pObj != GetParent() )
965*cdf0e10cSrcweir             {
966*cdf0e10cSrcweir                 rStrm << " contains ";
967*cdf0e10cSrcweir                 ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
968*cdf0e10cSrcweir             }
969*cdf0e10cSrcweir             else
970*cdf0e10cSrcweir                 rStrm << endl;
971*cdf0e10cSrcweir         }
972*cdf0e10cSrcweir     }
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir     // Properties
975*cdf0e10cSrcweir     rStrm << aIndentNameStr.GetBuffer() << "- Properties:" << endl;
976*cdf0e10cSrcweir     {
977*cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < pProps->Count(); i++ )
978*cdf0e10cSrcweir         {
979*cdf0e10cSrcweir             SbxVariableRef& r = pProps->GetRef( i );
980*cdf0e10cSrcweir             SbxVariable* pVar = r;
981*cdf0e10cSrcweir             if( pVar )
982*cdf0e10cSrcweir             {
983*cdf0e10cSrcweir                 XubString aLine( aIndent );
984*cdf0e10cSrcweir                 aLine.AppendAscii( "  - " );
985*cdf0e10cSrcweir                 aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
986*cdf0e10cSrcweir                 XubString aAttrs3;
987*cdf0e10cSrcweir                 if( CollectAttrs( pVar, aAttrs3 ) )
988*cdf0e10cSrcweir                     aLine += aAttrs3;
989*cdf0e10cSrcweir                 if( !pVar->IsA( TYPE(SbxProperty) ) )
990*cdf0e10cSrcweir                     aLine.AppendAscii( "  !! Not a Property !!" );
991*cdf0e10cSrcweir                 rStrm.WriteByteString( aLine, RTL_TEXTENCODING_ASCII_US );
992*cdf0e10cSrcweir 
993*cdf0e10cSrcweir                 // bei Object-Properties auch das Object ausgeben
994*cdf0e10cSrcweir                 if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
995*cdf0e10cSrcweir                         pVar->GetValues_Impl().pObj &&
996*cdf0e10cSrcweir                         pVar->GetValues_Impl().pObj != this &&
997*cdf0e10cSrcweir                         pVar->GetValues_Impl().pObj != GetParent() )
998*cdf0e10cSrcweir                 {
999*cdf0e10cSrcweir                     rStrm << " contains ";
1000*cdf0e10cSrcweir                     ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
1001*cdf0e10cSrcweir                 }
1002*cdf0e10cSrcweir                 else
1003*cdf0e10cSrcweir                     rStrm << endl;
1004*cdf0e10cSrcweir             }
1005*cdf0e10cSrcweir         }
1006*cdf0e10cSrcweir     }
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir     // Objects
1009*cdf0e10cSrcweir     rStrm << aIndentNameStr.GetBuffer() << "- Objects:" << endl;
1010*cdf0e10cSrcweir     {
1011*cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < pObjs->Count(); i++ )
1012*cdf0e10cSrcweir         {
1013*cdf0e10cSrcweir             SbxVariableRef& r = pObjs->GetRef( i );
1014*cdf0e10cSrcweir             SbxVariable* pVar = r;
1015*cdf0e10cSrcweir             if ( pVar )
1016*cdf0e10cSrcweir             {
1017*cdf0e10cSrcweir                 rStrm << aIndentNameStr.GetBuffer() << "  - Sub";
1018*cdf0e10cSrcweir                 if ( pVar->ISA(SbxObject) )
1019*cdf0e10cSrcweir                     ((SbxObject*) pVar)->Dump( rStrm, bFill );
1020*cdf0e10cSrcweir                 else if ( pVar->ISA(SbxVariable) )
1021*cdf0e10cSrcweir                     ((SbxVariable*) pVar)->Dump( rStrm, bFill );
1022*cdf0e10cSrcweir             }
1023*cdf0e10cSrcweir         }
1024*cdf0e10cSrcweir     }
1025*cdf0e10cSrcweir 
1026*cdf0e10cSrcweir     rStrm << aIndentNameStr.GetBuffer() << "}" << endl << endl;
1027*cdf0e10cSrcweir     --nLevel;
1028*cdf0e10cSrcweir }
1029*cdf0e10cSrcweir 
1030*cdf0e10cSrcweir SvDispatch* SbxObject::GetSvDispatch()
1031*cdf0e10cSrcweir {
1032*cdf0e10cSrcweir     return NULL;
1033*cdf0e10cSrcweir }
1034*cdf0e10cSrcweir 
1035*cdf0e10cSrcweir sal_Bool SbxMethod::Run( SbxValues* pValues )
1036*cdf0e10cSrcweir {
1037*cdf0e10cSrcweir     SbxValues aRes;
1038*cdf0e10cSrcweir     if( !pValues )
1039*cdf0e10cSrcweir         pValues = &aRes;
1040*cdf0e10cSrcweir     pValues->eType = SbxVARIANT;
1041*cdf0e10cSrcweir     return Get( *pValues );
1042*cdf0e10cSrcweir }
1043*cdf0e10cSrcweir 
1044*cdf0e10cSrcweir SbxClassType SbxMethod::GetClass() const
1045*cdf0e10cSrcweir {
1046*cdf0e10cSrcweir     return SbxCLASS_METHOD;
1047*cdf0e10cSrcweir }
1048*cdf0e10cSrcweir 
1049*cdf0e10cSrcweir SbxClassType SbxProperty::GetClass() const
1050*cdf0e10cSrcweir {
1051*cdf0e10cSrcweir     return SbxCLASS_PROPERTY;
1052*cdf0e10cSrcweir }
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir void SbxObject::GarbageCollection( sal_uIntPtr nObjects )
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir /*  [Beschreibung]
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir     Diese statische Methode durchsucht die n"achsten 'nObjects' der zur Zeit
1059*cdf0e10cSrcweir     existierenden <SbxObject>-Instanzen nach zyklischen Referenzen, die sich
1060*cdf0e10cSrcweir     nur noch selbst am Leben erhalten. Ist 'nObjects==0', dann werden
1061*cdf0e10cSrcweir     alle existierenden durchsucht.
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir     zur Zeit nur implementiert: Object -> Parent-Property -> Parent -> Object
1064*cdf0e10cSrcweir */
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir {
1067*cdf0e10cSrcweir     (void)nObjects;
1068*cdf0e10cSrcweir 
1069*cdf0e10cSrcweir     static sal_Bool bInGarbageCollection = sal_False;
1070*cdf0e10cSrcweir     if ( bInGarbageCollection )
1071*cdf0e10cSrcweir         return;
1072*cdf0e10cSrcweir     bInGarbageCollection = sal_True;
1073*cdf0e10cSrcweir 
1074*cdf0e10cSrcweir #if 0
1075*cdf0e10cSrcweir     // erstes Object dieser Runde anspringen
1076*cdf0e10cSrcweir     sal_Bool bAll = !nObjects;
1077*cdf0e10cSrcweir     if ( bAll )
1078*cdf0e10cSrcweir         rObjects.First();
1079*cdf0e10cSrcweir     SbxObject *pObj = rObjects.GetCurObject();
1080*cdf0e10cSrcweir     if ( !pObj )
1081*cdf0e10cSrcweir         pObj = rObjects.First();
1082*cdf0e10cSrcweir 
1083*cdf0e10cSrcweir     while ( pObj && 0 != nObjects-- )
1084*cdf0e10cSrcweir     {
1085*cdf0e10cSrcweir         // hat der Parent nur noch 1 Ref-Count?
1086*cdf0e10cSrcweir         SbxObject *pParent = PTR_CAST( SbxObject, pObj->GetParent() );
1087*cdf0e10cSrcweir         if ( pParent && 1 == pParent->GetRefCount() )
1088*cdf0e10cSrcweir         {
1089*cdf0e10cSrcweir             // dann alle Properies des Objects durchsuchen
1090*cdf0e10cSrcweir             SbxArray *pProps = pObj->GetProperties();
1091*cdf0e10cSrcweir             for ( sal_uInt16 n = 0; n < pProps->Count(); ++n )
1092*cdf0e10cSrcweir             {
1093*cdf0e10cSrcweir                 // verweist die Property auf den Parent des Object?
1094*cdf0e10cSrcweir                 SbxVariable *pProp = pProps->Get(n);
1095*cdf0e10cSrcweir                 const SbxValues &rValues = pProp->GetValues_Impl();
1096*cdf0e10cSrcweir                 if ( SbxOBJECT == rValues.eType &&
1097*cdf0e10cSrcweir                      pParent == rValues.pObj )
1098*cdf0e10cSrcweir                 {
1099*cdf0e10cSrcweir #ifdef DBG_UTIL
1100*cdf0e10cSrcweir                     DbgOutf( "SBX: %s.%s with Object %s was garbage",
1101*cdf0e10cSrcweir                              pObj->GetName().GetStr(),
1102*cdf0e10cSrcweir                              pProp->GetName().GetStr(),
1103*cdf0e10cSrcweir                              pParent->GetName().GetStr() );
1104*cdf0e10cSrcweir #endif
1105*cdf0e10cSrcweir                     // dann freigeben
1106*cdf0e10cSrcweir                     pProp->SbxValue::Clear();
1107*cdf0e10cSrcweir                     Sound::Beep();
1108*cdf0e10cSrcweir                     break;
1109*cdf0e10cSrcweir                 }
1110*cdf0e10cSrcweir             }
1111*cdf0e10cSrcweir         }
1112*cdf0e10cSrcweir 
1113*cdf0e10cSrcweir         // zum n"achsten
1114*cdf0e10cSrcweir         pObj = rObjects.Next();
1115*cdf0e10cSrcweir         if ( !bAll && !pObj )
1116*cdf0e10cSrcweir             pObj = rObjects.First();
1117*cdf0e10cSrcweir     }
1118*cdf0e10cSrcweir #endif
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir // AB 28.10. Zur 507a vorerst raus, da SfxBroadcaster::Enable() wegfaellt
1121*cdf0e10cSrcweir #if 0
1122*cdf0e10cSrcweir #ifdef DBG_UTIL
1123*cdf0e10cSrcweir     SbxVarList_Impl &rVars = GetSbxData_Impl()->aVars;
1124*cdf0e10cSrcweir     DbgOutf( "SBX: garbage collector done, %lu objects remainding",
1125*cdf0e10cSrcweir              rVars.Count() );
1126*cdf0e10cSrcweir     if ( rVars.Count() > 200 && rVars.Count() < 210 )
1127*cdf0e10cSrcweir     {
1128*cdf0e10cSrcweir         SvFileStream aStream( "d:\\tmp\\dump.sbx", STREAM_STD_WRITE );
1129*cdf0e10cSrcweir         SfxBroadcaster::Enable(sal_False);
1130*cdf0e10cSrcweir         for ( sal_uIntPtr n = 0; n < rVars.Count(); ++n )
1131*cdf0e10cSrcweir         {
1132*cdf0e10cSrcweir             SbxVariable *pVar = rVars.GetObject(n);
1133*cdf0e10cSrcweir             SbxObject *pObj = PTR_CAST(SbxObject, pVar);
1134*cdf0e10cSrcweir             sal_uInt16 nFlags = pVar->GetFlags();
1135*cdf0e10cSrcweir             pVar->SetFlag(SBX_NO_BROADCAST);
1136*cdf0e10cSrcweir             if ( pObj )
1137*cdf0e10cSrcweir                 pObj->Dump(aStream);
1138*cdf0e10cSrcweir             else if ( !pVar->GetParent() || !pVar->GetParent()->ISA(SbxObject) )
1139*cdf0e10cSrcweir                 pVar->Dump(aStream);
1140*cdf0e10cSrcweir             pVar->SetFlags(nFlags);
1141*cdf0e10cSrcweir         }
1142*cdf0e10cSrcweir         SfxBroadcaster::Enable(sal_True);
1143*cdf0e10cSrcweir     }
1144*cdf0e10cSrcweir #endif
1145*cdf0e10cSrcweir #endif
1146*cdf0e10cSrcweir     bInGarbageCollection = sal_False;
1147*cdf0e10cSrcweir }
1148*cdf0e10cSrcweir 
1149