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