fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / basic / source / sbx / sbxobj.cxx
blob625917eb2fab357bfc31baa1586d7b25ddac1e5b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/stream.hxx>
21 #include <basic/sbx.hxx>
22 #include "sbxres.hxx"
23 #include <svl/brdcst.hxx>
25 TYPEINIT1(SbxMethod,SbxVariable)
26 TYPEINIT1(SbxProperty,SbxVariable)
27 TYPEINIT2(SbxObject,SbxVariable,SfxListener)
29 static OUString pNameProp; // Name-Property
30 static OUString pParentProp; // Parent-Property
32 static sal_uInt16 nNameHash = 0, nParentHash = 0;
36 SbxObject::SbxObject( const OUString& rClass )
37 : SbxVariable( SbxOBJECT ), aClassName( rClass )
39 aData.pObj = this;
40 if( !nNameHash )
42 pNameProp = OUString::createFromAscii(GetSbxRes( STRING_NAMEPROP ));
43 pParentProp = OUString::createFromAscii(GetSbxRes( STRING_PARENTPROP ));
44 nNameHash = MakeHashCode( pNameProp );
45 nParentHash = MakeHashCode( pParentProp );
47 SbxObject::Clear();
48 SbxObject::SetName( rClass );
51 SbxObject::SbxObject( const SbxObject& rObj )
52 : SvRefBase( rObj ), SbxVariable( rObj.GetType() ),
53 SfxListener( rObj )
55 *this = rObj;
58 SbxObject& SbxObject::operator=( const SbxObject& r )
60 if( &r != this )
62 SbxVariable::operator=( r );
63 aClassName = r.aClassName;
64 pMethods = new SbxArray;
65 pProps = new SbxArray;
66 pObjs = new SbxArray( SbxOBJECT );
67 // The arrays were copied, the content taken over
68 *pMethods = *r.pMethods;
69 *pProps = *r.pProps;
70 *pObjs = *r.pObjs;
71 // Because the variables were taken over, this is OK
72 pDfltProp = r.pDfltProp;
73 SetName( r.GetName() );
74 SetFlags( r.GetFlags() );
75 SetModified( sal_True );
77 return *this;
80 static void CheckParentsOnDelete( SbxObject* pObj, SbxArray* p )
82 for( sal_uInt16 i = 0; i < p->Count(); i++ )
84 SbxVariableRef& rRef = p->GetRef( i );
85 if( rRef->IsBroadcaster() )
87 pObj->EndListening( rRef->GetBroadcaster(), sal_True );
89 // Did the element have more then one reference and still a Listener?
90 if( rRef->GetRefCount() > 1 )
92 rRef->SetParent( NULL );
93 DBG_ASSERT( !rRef->IsBroadcaster() || rRef->GetBroadcaster().GetListenerCount(), "Object element with dangling parent" );
98 SbxObject::~SbxObject()
100 CheckParentsOnDelete( this, pProps );
101 CheckParentsOnDelete( this, pMethods );
102 CheckParentsOnDelete( this, pObjs );
104 // avoid handling in ~SbxVariable as SBX_DIM_AS_NEW == SBX_GBLSEARCH
105 ResetFlag( SBX_DIM_AS_NEW );
108 SbxDataType SbxObject::GetType() const
110 return SbxOBJECT;
113 SbxClassType SbxObject::GetClass() const
115 return SbxCLASS_OBJECT;
118 void SbxObject::Clear()
120 pMethods = new SbxArray;
121 pProps = new SbxArray;
122 pObjs = new SbxArray( SbxOBJECT );
123 SbxVariable* p;
124 p = Make( pNameProp, SbxCLASS_PROPERTY, SbxSTRING );
125 p->SetFlag( SBX_DONTSTORE );
126 p = Make( pParentProp, SbxCLASS_PROPERTY, SbxOBJECT );
127 p->ResetFlag( SBX_WRITE );
128 p->SetFlag( SBX_DONTSTORE );
129 pDfltProp = NULL;
130 SetModified( sal_False );
133 void SbxObject::SFX_NOTIFY( SfxBroadcaster&, const TypeId&,
134 const SfxHint& rHint, const TypeId& )
136 const SbxHint* p = PTR_CAST(SbxHint,&rHint);
137 if( p )
139 sal_uIntPtr nId = p->GetId();
140 bool bRead = ( nId == SBX_HINT_DATAWANTED );
141 bool bWrite = ( nId == SBX_HINT_DATACHANGED );
142 SbxVariable* pVar = p->GetVar();
143 if( bRead || bWrite )
145 OUString aVarName( pVar->GetName() );
146 sal_uInt16 nHash_ = MakeHashCode( aVarName );
147 if( nHash_ == nNameHash && aVarName.equalsIgnoreAsciiCase( pNameProp ) )
149 if( bRead )
151 pVar->PutString( GetName() );
153 else
155 SetName( pVar->GetOUString() );
158 else if( nHash_ == nParentHash && aVarName.equalsIgnoreAsciiCase( pParentProp ) )
160 SbxObject* p_ = GetParent();
161 if( !p_ )
163 p_ = this;
165 pVar->PutObject( p_ );
171 sal_Bool SbxObject::IsClass( const OUString& rName ) const
173 return sal_Bool( aClassName.equalsIgnoreAsciiCase( rName ) );
176 SbxVariable* SbxObject::FindUserData( sal_uInt32 nData )
178 if( !GetAll( SbxCLASS_DONTCARE ) )
180 return NULL;
182 SbxVariable* pRes = pMethods->FindUserData( nData );
183 if( !pRes )
185 pRes = pProps->FindUserData( nData );
187 if( !pRes )
189 pRes = pObjs->FindUserData( nData );
191 // Search in the parents?
192 if( !pRes && IsSet( SBX_GBLSEARCH ) )
194 SbxObject* pCur = this;
195 while( !pRes && pCur->pParent )
197 // I myself was already searched through!
198 sal_uInt16 nOwn = pCur->GetFlags();
199 pCur->ResetFlag( SBX_EXTSEARCH );
200 // I search already global!
201 sal_uInt16 nPar = pCur->pParent->GetFlags();
202 pCur->pParent->ResetFlag( SBX_GBLSEARCH );
203 pRes = pCur->pParent->FindUserData( nData );
204 pCur->SetFlags( nOwn );
205 pCur->pParent->SetFlags( nPar );
206 pCur = pCur->pParent;
209 return pRes;
212 SbxVariable* SbxObject::Find( const OUString& rName, SbxClassType t )
214 #ifdef DBG_UTIL
215 static sal_uInt16 nLvl = 0;
216 static const char* pCls[] = { "DontCare","Array","Value","Variable","Method","Property","Object" };
217 OString aNameStr1(OUStringToOString(rName, RTL_TEXTENCODING_ASCII_US));
218 OString aNameStr2(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US));
219 DbgOutf( "SBX: Search %.*s %s %s in %s",
220 nLvl++, " ",
221 ( t >= SbxCLASS_DONTCARE && t <= SbxCLASS_OBJECT )
222 ? pCls[ t-1 ] : "Unknown class", aNameStr1.getStr(), aNameStr2.getStr() );
223 #endif
225 if( !GetAll( t ) )
227 return NULL;
229 SbxVariable* pRes = NULL;
230 pObjs->SetFlag( SBX_EXTSEARCH );
231 if( t == SbxCLASS_DONTCARE )
233 pRes = pMethods->Find( rName, SbxCLASS_METHOD );
234 if( !pRes )
236 pRes = pProps->Find( rName, SbxCLASS_PROPERTY );
238 if( !pRes )
240 pRes = pObjs->Find( rName, t );
243 else
245 SbxArray* pArray = NULL;
246 switch( t )
248 case SbxCLASS_VARIABLE:
249 case SbxCLASS_PROPERTY: pArray = pProps; break;
250 case SbxCLASS_METHOD: pArray = pMethods; break;
251 case SbxCLASS_OBJECT: pArray = pObjs; break;
252 default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
254 if( pArray )
256 pRes = pArray->Find( rName, t );
259 // ExtendedsSearch in the Object-Array?
260 // For objects and DontCare is the array of objects already
261 // searched through
262 if( !pRes && ( t == SbxCLASS_METHOD || t == SbxCLASS_PROPERTY ) )
263 pRes = pObjs->Find( rName, t );
264 // Search in the parents?
265 if( !pRes && IsSet( SBX_GBLSEARCH ) )
267 SbxObject* pCur = this;
268 while( !pRes && pCur->pParent )
270 // I myself was already searched through!
271 sal_uInt16 nOwn = pCur->GetFlags();
272 pCur->ResetFlag( SBX_EXTSEARCH );
273 // I search already global!
274 sal_uInt16 nPar = pCur->pParent->GetFlags();
275 pCur->pParent->ResetFlag( SBX_GBLSEARCH );
276 pRes = pCur->pParent->Find( rName, t );
277 pCur->SetFlags( nOwn );
278 pCur->pParent->SetFlags( nPar );
279 pCur = pCur->pParent;
282 #ifdef DBG_UTIL
283 nLvl--;
284 if( pRes )
286 OString aNameStr3(OUStringToOString(rName, RTL_TEXTENCODING_ASCII_US));
287 OString aNameStr4(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US));
288 DbgOutf( "SBX: Found %.*s %s in %s",
289 nLvl, " ", aNameStr3.getStr(), aNameStr4.getStr() );
291 #endif
292 return pRes;
295 // Abbreviated version: The parent-string will be searched through
296 // The whole thing recursive, because Call() might be overloaded
297 // Qualified names are allowed
299 sal_Bool SbxObject::Call( const OUString& rName, SbxArray* pParam )
301 SbxVariable* pMeth = FindQualified( rName, SbxCLASS_DONTCARE);
302 if( pMeth && pMeth->ISA(SbxMethod) )
304 // FindQualified() might have been stroked!
305 if( pParam )
307 pMeth->SetParameters( pParam );
309 pMeth->Broadcast( SBX_HINT_DATAWANTED );
310 pMeth->SetParameters( NULL );
311 return sal_True;
313 SetError( SbxERR_NO_METHOD );
314 return sal_False;
317 SbxProperty* SbxObject::GetDfltProperty()
319 if ( !pDfltProp && !aDfltPropName.isEmpty() )
321 pDfltProp = (SbxProperty*) Find( aDfltPropName, SbxCLASS_PROPERTY );
322 if( !pDfltProp )
324 pDfltProp = (SbxProperty*) Make( aDfltPropName, SbxCLASS_PROPERTY, SbxVARIANT );
327 return pDfltProp;
329 void SbxObject::SetDfltProperty( const OUString& rName )
331 if ( rName != aDfltPropName )
333 pDfltProp = NULL;
335 aDfltPropName = rName;
336 SetModified( sal_True );
339 // Search of a already available variable. If she was located,
340 // the index will be set, elsewise will be delivered the Count of the Array.
341 // In any case it will be delivered the correct Array.
343 SbxArray* SbxObject::FindVar( SbxVariable* pVar, sal_uInt16& nArrayIdx )
345 SbxArray* pArray = NULL;
346 if( pVar ) switch( pVar->GetClass() )
348 case SbxCLASS_VARIABLE:
349 case SbxCLASS_PROPERTY: pArray = pProps; break;
350 case SbxCLASS_METHOD: pArray = pMethods; break;
351 case SbxCLASS_OBJECT: pArray = pObjs; break;
352 default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
354 if( pArray )
356 nArrayIdx = pArray->Count();
357 // Is the variable per name available?
358 pArray->ResetFlag( SBX_EXTSEARCH );
359 SbxVariable* pOld = pArray->Find( pVar->GetName(), pVar->GetClass() );
360 if( pOld )
362 for( sal_uInt16 i = 0; i < pArray->Count(); i++ )
364 SbxVariableRef& rRef = pArray->GetRef( i );
365 if( (SbxVariable*) rRef == pOld )
367 nArrayIdx = i; break;
372 return pArray;
375 // If a new object will be established, this object will be indexed,
376 // if an object of this name exists already.
378 SbxVariable* SbxObject::Make( const OUString& rName, SbxClassType ct, SbxDataType dt )
380 // Is the object already available?
381 SbxArray* pArray = NULL;
382 switch( ct )
384 case SbxCLASS_VARIABLE:
385 case SbxCLASS_PROPERTY: pArray = pProps; break;
386 case SbxCLASS_METHOD: pArray = pMethods; break;
387 case SbxCLASS_OBJECT: pArray = pObjs; break;
388 default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
390 if( !pArray )
392 return NULL;
394 // Collections may contain objects of the same name
395 if( !( ct == SbxCLASS_OBJECT && ISA(SbxCollection) ) )
397 SbxVariable* pRes = pArray->Find( rName, ct );
398 if( pRes )
400 return pRes;
403 SbxVariable* pVar = NULL;
404 switch( ct )
406 case SbxCLASS_VARIABLE:
407 case SbxCLASS_PROPERTY:
408 pVar = new SbxProperty( rName, dt );
409 break;
410 case SbxCLASS_METHOD:
411 pVar = new SbxMethod( rName, dt );
412 break;
413 case SbxCLASS_OBJECT:
414 pVar = CreateObject( rName );
415 break;
416 default:
417 break;
419 pVar->SetParent( this );
420 pArray->Put( pVar, pArray->Count() );
421 SetModified( sal_True );
422 // The object listen always
423 StartListening( pVar->GetBroadcaster(), sal_True );
424 Broadcast( SBX_HINT_OBJECTCHANGED );
425 return pVar;
428 SbxObject* SbxObject::MakeObject( const OUString& rName, const OUString& rClass )
430 // Is the object already available?
431 if( !ISA(SbxCollection) )
433 SbxVariable* pRes = pObjs->Find( rName, SbxCLASS_OBJECT );
434 if( pRes )
436 return PTR_CAST(SbxObject,pRes);
439 SbxObject* pVar = CreateObject( rClass );
440 if( pVar )
442 pVar->SetName( rName );
443 pVar->SetParent( this );
444 pObjs->Put( pVar, pObjs->Count() );
445 SetModified( sal_True );
446 // The object listen always
447 StartListening( pVar->GetBroadcaster(), sal_True );
448 Broadcast( SBX_HINT_OBJECTCHANGED );
450 return pVar;
453 void SbxObject::Insert( SbxVariable* pVar )
455 sal_uInt16 nIdx;
456 SbxArray* pArray = FindVar( pVar, nIdx );
457 if( pArray )
459 // Into with it. But you should pay attention at the Pointer!
460 if( nIdx < pArray->Count() )
462 // Then this element exists already
463 // There are objects of the same name allowed at collections
464 if( pArray == pObjs && ISA(SbxCollection) )
466 nIdx = pArray->Count();
468 else
470 SbxVariable* pOld = pArray->Get( nIdx );
471 // already inside: overwrite
472 if( pOld == pVar )
474 return;
476 EndListening( pOld->GetBroadcaster(), sal_True );
477 if( pVar->GetClass() == SbxCLASS_PROPERTY )
479 if( pOld == pDfltProp )
481 pDfltProp = (SbxProperty*) pVar;
486 StartListening( pVar->GetBroadcaster(), sal_True );
487 pArray->Put( pVar, nIdx );
488 if( pVar->GetParent() != this )
490 pVar->SetParent( this );
492 SetModified( sal_True );
493 Broadcast( SBX_HINT_OBJECTCHANGED );
494 #ifdef DBG_UTIL
495 static const char* pCls[] =
496 { "DontCare","Array","Value","Variable","Method","Property","Object" };
497 OUString aVarName( pVar->GetName() );
498 if ( aVarName.isEmpty() && pVar->ISA(SbxObject) )
500 aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
502 OString aNameStr1(OUStringToOString(aVarName, RTL_TEXTENCODING_ASCII_US));
503 OString aNameStr2(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US));
504 DbgOutf( "SBX: Insert %s %s in %s",
505 ( pVar->GetClass() >= SbxCLASS_DONTCARE &&
506 pVar->GetClass() <= SbxCLASS_OBJECT )
507 ? pCls[ pVar->GetClass()-1 ] : "Unknown class", aNameStr1.getStr(), aNameStr2.getStr() );
508 #endif
512 // Optimisation, Insertion without checking about
513 // double entry and without broadcasts, will only be used in SO2/auto.cxx
514 void SbxObject::QuickInsert( SbxVariable* pVar )
516 SbxArray* pArray = NULL;
517 if( pVar )
519 switch( pVar->GetClass() )
521 case SbxCLASS_VARIABLE:
522 case SbxCLASS_PROPERTY: pArray = pProps; break;
523 case SbxCLASS_METHOD: pArray = pMethods; break;
524 case SbxCLASS_OBJECT: pArray = pObjs; break;
525 default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
528 if( pArray )
530 StartListening( pVar->GetBroadcaster(), sal_True );
531 pArray->Put( pVar, pArray->Count() );
532 if( pVar->GetParent() != this )
534 pVar->SetParent( this );
536 SetModified( sal_True );
537 #ifdef DBG_UTIL
538 static const char* pCls[] =
539 { "DontCare","Array","Value","Variable","Method","Property","Object" };
540 OUString aVarName( pVar->GetName() );
541 if ( aVarName.isEmpty() && pVar->ISA(SbxObject) )
543 aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
545 OString aNameStr1(OUStringToOString(aVarName, RTL_TEXTENCODING_ASCII_US));
546 OString aNameStr2(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US));
547 DbgOutf( "SBX: Insert %s %s in %s",
548 ( pVar->GetClass() >= SbxCLASS_DONTCARE &&
549 pVar->GetClass() <= SbxCLASS_OBJECT )
550 ? pCls[ pVar->GetClass()-1 ] : "Unknown class", aNameStr1.getStr(), aNameStr2.getStr() );
551 #endif
555 void SbxObject::Remove( const OUString& rName, SbxClassType t )
557 Remove( SbxObject::Find( rName, t ) );
560 void SbxObject::Remove( SbxVariable* pVar )
562 sal_uInt16 nIdx;
563 SbxArray* pArray = FindVar( pVar, nIdx );
564 if( pArray && nIdx < pArray->Count() )
566 #ifdef DBG_UTIL
567 OUString aVarName( pVar->GetName() );
568 if ( aVarName.isEmpty() && pVar->ISA(SbxObject) )
570 aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
572 OString aNameStr1(OUStringToOString(aVarName, RTL_TEXTENCODING_ASCII_US));
573 OString aNameStr2(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US));
574 DbgOutf( "SBX: Remove %s in %s",
575 aNameStr1.getStr(), aNameStr2.getStr() );
576 #endif
577 SbxVariableRef pVar_ = pArray->Get( nIdx );
578 if( pVar_->IsBroadcaster() )
580 EndListening( pVar_->GetBroadcaster(), sal_True );
582 if( (SbxVariable*) pVar_ == pDfltProp )
584 pDfltProp = NULL;
586 pArray->Remove( nIdx );
587 if( pVar_->GetParent() == this )
589 pVar_->SetParent( NULL );
591 SetModified( sal_True );
592 Broadcast( SBX_HINT_OBJECTCHANGED );
596 static sal_Bool LoadArray( SvStream& rStrm, SbxObject* pThis, SbxArray* pArray )
598 SbxArrayRef p = (SbxArray*) SbxBase::Load( rStrm );
599 if( !p.Is() )
601 return sal_False;
603 for( sal_uInt16 i = 0; i < p->Count(); i++ )
605 SbxVariableRef& r = p->GetRef( i );
606 SbxVariable* pVar = r;
607 if( pVar )
609 pVar->SetParent( pThis );
610 pThis->StartListening( pVar->GetBroadcaster(), sal_True );
613 pArray->Merge( p );
614 return sal_True;
617 // The load of an object is additive!
619 sal_Bool SbxObject::LoadData( SvStream& rStrm, sal_uInt16 nVer )
621 // Help for the read in of old objects: just TRUE back,
622 // LoadPrivateData() had to set the default status up
623 if( !nVer )
625 return sal_True;
627 pDfltProp = NULL;
628 if( !SbxVariable::LoadData( rStrm, nVer ) )
630 return sal_False;
632 // If it contains no alien object, insert ourselves
633 if( aData.eType == SbxOBJECT && !aData.pObj )
635 aData.pObj = this;
637 sal_uInt32 nSize;
638 OUString aDfltProp;
639 aClassName = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rStrm, RTL_TEXTENCODING_ASCII_US);
640 aDfltProp = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rStrm, RTL_TEXTENCODING_ASCII_US);
641 sal_uIntPtr nPos = rStrm.Tell();
642 rStrm >> nSize;
643 if( !LoadPrivateData( rStrm, nVer ) )
645 return sal_False;
647 sal_uIntPtr nNewPos = rStrm.Tell();
648 nPos += nSize;
649 DBG_ASSERT( nPos >= nNewPos, "SBX: Loaded too much data" );
650 if( nPos != nNewPos )
652 rStrm.Seek( nPos );
654 if( !LoadArray( rStrm, this, pMethods ) ||
655 !LoadArray( rStrm, this, pProps ) ||
656 !LoadArray( rStrm, this, pObjs ) )
658 return sal_False;
660 // Set properties
661 if( !aDfltProp.isEmpty() )
663 pDfltProp = (SbxProperty*) pProps->Find( aDfltProp, SbxCLASS_PROPERTY );
665 SetModified( sal_False );
666 return sal_True;
669 sal_Bool SbxObject::StoreData( SvStream& rStrm ) const
671 if( !SbxVariable::StoreData( rStrm ) )
673 return sal_False;
675 OUString aDfltProp;
676 if( pDfltProp )
678 aDfltProp = pDfltProp->GetName();
680 write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rStrm, aClassName, RTL_TEXTENCODING_ASCII_US);
681 write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rStrm, aDfltProp, RTL_TEXTENCODING_ASCII_US);
682 sal_uIntPtr nPos = rStrm.Tell();
683 rStrm << (sal_uInt32) 0L;
684 if( !StorePrivateData( rStrm ) )
686 return sal_False;
688 sal_uIntPtr nNew = rStrm.Tell();
689 rStrm.Seek( nPos );
690 rStrm << (sal_uInt32) ( nNew - nPos );
691 rStrm.Seek( nNew );
692 if( !pMethods->Store( rStrm ) )
694 return sal_False;
696 if( !pProps->Store( rStrm ) )
698 return sal_False;
700 if( !pObjs->Store( rStrm ) )
702 return sal_False;
704 ((SbxObject*) this)->SetModified( sal_False );
705 return sal_True;
708 OUString SbxObject::GenerateSource( const OUString &rLinePrefix,
709 const SbxObject* )
711 // Collect the properties in a String
712 OUString aSource;
713 SbxArrayRef xProps( GetProperties() );
714 bool bLineFeed = false;
715 for ( sal_uInt16 nProp = 0; nProp < xProps->Count(); ++nProp )
717 SbxPropertyRef xProp = (SbxProperty*) xProps->Get(nProp);
718 OUString aPropName( xProp->GetName() );
719 if ( xProp->CanWrite() &&
720 !( xProp->GetHashCode() == nNameHash &&
721 aPropName.equalsIgnoreAsciiCase(pNameProp)))
723 // Insert a break except in front of the first property
724 if ( bLineFeed )
726 aSource += "\n";
728 else
730 bLineFeed = true;
732 aSource += rLinePrefix;
733 aSource += ".";
734 aSource += aPropName;
735 aSource += " = ";
737 // Display the property value textual
738 switch ( xProp->GetType() )
740 case SbxEMPTY:
741 case SbxNULL:
742 // no value
743 break;
745 case SbxSTRING:
746 // Strings in quotation mark
747 aSource += "\"";
748 aSource += xProp->GetOUString();
749 aSource += "\"";
750 break;
752 default:
753 // miscellaneous, such as e.g.numerary directly
754 aSource += xProp->GetOUString();
755 break;
759 return aSource;
762 static sal_Bool CollectAttrs( const SbxBase* p, OUString& rRes )
764 OUString aAttrs;
765 if( p->IsHidden() )
767 aAttrs = "Hidden";
769 if( p->IsSet( SBX_EXTSEARCH ) )
771 if( !aAttrs.isEmpty() )
773 aAttrs += ",";
775 aAttrs += "ExtSearch";
777 if( !p->IsVisible() )
779 if( !aAttrs.isEmpty() )
781 aAttrs += ",";
783 aAttrs += "Invisible";
785 if( p->IsSet( SBX_DONTSTORE ) )
787 if( !aAttrs.isEmpty() )
789 aAttrs += ",";
791 aAttrs += "DontStore";
793 if( !aAttrs.isEmpty() )
795 rRes = " (";
796 rRes += aAttrs;
797 rRes += ")";
798 return sal_True;
800 else
802 rRes = "";
803 return sal_False;
807 void SbxObject::Dump( SvStream& rStrm, sal_Bool bFill )
809 // Shifting
810 static sal_uInt16 nLevel = 0;
811 if ( nLevel > 10 )
813 rStrm << "<too deep>" << endl;
814 return;
816 ++nLevel;
817 OUString aIndent("");
818 for ( sal_uInt16 n = 1; n < nLevel; ++n )
820 aIndent += " ";
822 // if necessary complete the object
823 if ( bFill )
825 GetAll( SbxCLASS_DONTCARE );
827 // Output the data of the object itself
828 OString aNameStr(OUStringToOString(GetName(), RTL_TEXTENCODING_ASCII_US));
829 OString aClassNameStr(OUStringToOString(aClassName, RTL_TEXTENCODING_ASCII_US));
830 rStrm << "Object( "
831 << OString::valueOf(reinterpret_cast<sal_Int64>(this)).getStr()<< "=='"
832 << ( aNameStr.isEmpty() ? "<unnamed>" : aNameStr.getStr() ) << "', "
833 << "of class '" << aClassNameStr.getStr() << "', "
834 << "counts "
835 << OString::number(GetRefCount()).getStr()
836 << " refs, ";
837 if ( GetParent() )
839 OString aParentNameStr(OUStringToOString(GetName(), RTL_TEXTENCODING_ASCII_US));
840 rStrm << "in parent "
841 << OString::valueOf(reinterpret_cast<sal_Int64>(GetParent())).getStr()
842 << "=='" << ( aParentNameStr.isEmpty() ? "<unnamed>" : aParentNameStr.getStr() ) << "'";
844 else
846 rStrm << "no parent ";
848 rStrm << " )" << endl;
849 OString aIndentNameStr(OUStringToOString(aIndent, RTL_TEXTENCODING_ASCII_US));
850 rStrm << aIndentNameStr.getStr() << "{" << endl;
852 // Flags
853 OUString aAttrs;
854 if( CollectAttrs( this, aAttrs ) )
856 OString aAttrStr(OUStringToOString(aAttrs, RTL_TEXTENCODING_ASCII_US));
857 rStrm << aIndentNameStr.getStr() << "- Flags: " << aAttrStr.getStr() << endl;
860 // Methods
861 rStrm << aIndentNameStr.getStr() << "- Methods:" << endl;
862 for( sal_uInt16 i = 0; i < pMethods->Count(); i++ )
864 SbxVariableRef& r = pMethods->GetRef( i );
865 SbxVariable* pVar = r;
866 if( pVar )
868 OUString aLine( aIndent );
869 aLine += " - ";
870 aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
871 OUString aAttrs2;
872 if( CollectAttrs( pVar, aAttrs2 ) )
874 aLine += aAttrs2;
876 if( !pVar->IsA( TYPE(SbxMethod) ) )
878 aLine += " !! Not a Method !!";
880 write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rStrm, aLine, RTL_TEXTENCODING_ASCII_US);
882 // Output also the object at object-methods
883 if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
884 pVar->GetValues_Impl().pObj &&
885 pVar->GetValues_Impl().pObj != this &&
886 pVar->GetValues_Impl().pObj != GetParent() )
888 rStrm << " contains ";
889 ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
891 else
893 rStrm << endl;
898 // Properties
899 rStrm << aIndentNameStr.getStr() << "- Properties:" << endl;
901 for( sal_uInt16 i = 0; i < pProps->Count(); i++ )
903 SbxVariableRef& r = pProps->GetRef( i );
904 SbxVariable* pVar = r;
905 if( pVar )
907 OUString aLine( aIndent );
908 aLine += " - ";
909 aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
910 OUString aAttrs3;
911 if( CollectAttrs( pVar, aAttrs3 ) )
913 aLine += aAttrs3;
915 if( !pVar->IsA( TYPE(SbxProperty) ) )
917 aLine += " !! Not a Property !!";
919 write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rStrm, aLine, RTL_TEXTENCODING_ASCII_US);
921 // output also the object at object properties
922 if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
923 pVar->GetValues_Impl().pObj &&
924 pVar->GetValues_Impl().pObj != this &&
925 pVar->GetValues_Impl().pObj != GetParent() )
927 rStrm << " contains ";
928 ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
930 else
932 rStrm << endl;
938 // Objects
939 rStrm << aIndentNameStr.getStr() << "- Objects:" << endl;
941 for( sal_uInt16 i = 0; i < pObjs->Count(); i++ )
943 SbxVariableRef& r = pObjs->GetRef( i );
944 SbxVariable* pVar = r;
945 if ( pVar )
947 rStrm << aIndentNameStr.getStr() << " - Sub";
948 if ( pVar->ISA(SbxObject) )
950 ((SbxObject*) pVar)->Dump( rStrm, bFill );
952 else if ( pVar->ISA(SbxVariable) )
954 ((SbxVariable*) pVar)->Dump( rStrm, bFill );
960 rStrm << aIndentNameStr.getStr() << "}" << endl << endl;
961 --nLevel;
964 SbxMethod::SbxMethod( const OUString& r, SbxDataType t )
965 : SbxVariable( t )
967 SetName( r );
970 SbxMethod::SbxMethod( const SbxMethod& r )
971 : SvRefBase( r ), SbxVariable( r )
975 SbxMethod::~SbxMethod()
979 SbxClassType SbxMethod::GetClass() const
981 return SbxCLASS_METHOD;
984 SbxProperty::SbxProperty( const OUString& r, SbxDataType t )
985 : SbxVariable( t )
987 SetName( r );
990 SbxProperty::~SbxProperty()
994 SbxClassType SbxProperty::GetClass() const
996 return SbxCLASS_PROPERTY;
999 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */