1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
)
42 pNameProp
= OUString::createFromAscii(GetSbxRes( STRING_NAMEPROP
));
43 pParentProp
= OUString::createFromAscii(GetSbxRes( STRING_PARENTPROP
));
44 nNameHash
= MakeHashCode( pNameProp
);
45 nParentHash
= MakeHashCode( pParentProp
);
48 SbxObject::SetName( rClass
);
51 SbxObject::SbxObject( const SbxObject
& rObj
)
52 : SvRefBase( rObj
), SbxVariable( rObj
.GetType() ),
58 SbxObject
& SbxObject::operator=( const SbxObject
& r
)
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
;
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
);
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 // does 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
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
);
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
);
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
);
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
) )
151 pVar
->PutString( GetName() );
155 SetName( pVar
->GetOUString() );
158 else if( nHash_
== nParentHash
&& aVarName
.equalsIgnoreAsciiCase( pParentProp
) )
160 SbxObject
* p_
= GetParent();
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
) )
182 SbxVariable
* pRes
= pMethods
->FindUserData( nData
);
185 pRes
= pProps
->FindUserData( nData
);
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!
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
;
212 SbxVariable
* SbxObject::Find( const OUString
& rName
, SbxClassType t
)
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",
221 ( t
>= SbxCLASS_DONTCARE
&& t
<= SbxCLASS_OBJECT
)
222 ? pCls
[ t
-1 ] : "Unknown class", aNameStr1
.getStr(), aNameStr2
.getStr() );
229 SbxVariable
* pRes
= NULL
;
230 pObjs
->SetFlag( SBX_EXTSEARCH
);
231 if( t
== SbxCLASS_DONTCARE
)
233 pRes
= pMethods
->Find( rName
, SbxCLASS_METHOD
);
236 pRes
= pProps
->Find( rName
, SbxCLASS_PROPERTY
);
240 pRes
= pObjs
->Find( rName
, t
);
245 SbxArray
* pArray
= NULL
;
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;
256 pRes
= pArray
->Find( rName
, t
);
259 // Extended Search in the Object-Array?
260 // For objects and DontCare the array of objects has already been searched
261 if( !pRes
&& ( t
== SbxCLASS_METHOD
|| t
== SbxCLASS_PROPERTY
) )
262 pRes
= pObjs
->Find( rName
, t
);
263 // Search in the parents?
264 if( !pRes
&& IsSet( SBX_GBLSEARCH
) )
266 SbxObject
* pCur
= this;
267 while( !pRes
&& pCur
->pParent
)
269 // I myself was already searched!
270 sal_uInt16 nOwn
= pCur
->GetFlags();
271 pCur
->ResetFlag( SBX_EXTSEARCH
);
272 // I search already global!
273 sal_uInt16 nPar
= pCur
->pParent
->GetFlags();
274 pCur
->pParent
->ResetFlag( SBX_GBLSEARCH
);
275 pRes
= pCur
->pParent
->Find( rName
, t
);
276 pCur
->SetFlags( nOwn
);
277 pCur
->pParent
->SetFlags( nPar
);
278 pCur
= pCur
->pParent
;
285 OString
aNameStr3(OUStringToOString(rName
, RTL_TEXTENCODING_ASCII_US
));
286 OString
aNameStr4(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US
));
287 DbgOutf( "SBX: Found %.*s %s in %s",
288 nLvl
, " ", aNameStr3
.getStr(), aNameStr4
.getStr() );
294 // Abbreviated version: The parent-string will be searched
295 // The whole thing recursive, because Call() might be overloaded
296 // Qualified names are allowed
298 sal_Bool
SbxObject::Call( const OUString
& rName
, SbxArray
* pParam
)
300 SbxVariable
* pMeth
= FindQualified( rName
, SbxCLASS_DONTCARE
);
301 if( pMeth
&& pMeth
->ISA(SbxMethod
) )
303 // FindQualified() might have struck already!
306 pMeth
->SetParameters( pParam
);
308 pMeth
->Broadcast( SBX_HINT_DATAWANTED
);
309 pMeth
->SetParameters( NULL
);
312 SetError( SbxERR_NO_METHOD
);
316 SbxProperty
* SbxObject::GetDfltProperty()
318 if ( !pDfltProp
&& !aDfltPropName
.isEmpty() )
320 pDfltProp
= (SbxProperty
*) Find( aDfltPropName
, SbxCLASS_PROPERTY
);
323 pDfltProp
= (SbxProperty
*) Make( aDfltPropName
, SbxCLASS_PROPERTY
, SbxVARIANT
);
328 void SbxObject::SetDfltProperty( const OUString
& rName
)
330 if ( rName
!= aDfltPropName
)
334 aDfltPropName
= rName
;
335 SetModified( sal_True
);
338 // Search of an already available variable. If it was located,
339 // the index will be set, otherwise the Count of the Array will be returned.
340 // In any case the correct Array will be returned.
342 SbxArray
* SbxObject::FindVar( SbxVariable
* pVar
, sal_uInt16
& nArrayIdx
)
344 SbxArray
* pArray
= NULL
;
345 if( pVar
) switch( pVar
->GetClass() )
347 case SbxCLASS_VARIABLE
:
348 case SbxCLASS_PROPERTY
: pArray
= pProps
; break;
349 case SbxCLASS_METHOD
: pArray
= pMethods
; break;
350 case SbxCLASS_OBJECT
: pArray
= pObjs
; break;
351 default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
355 nArrayIdx
= pArray
->Count();
356 // Is the variable per name available?
357 pArray
->ResetFlag( SBX_EXTSEARCH
);
358 SbxVariable
* pOld
= pArray
->Find( pVar
->GetName(), pVar
->GetClass() );
361 for( sal_uInt16 i
= 0; i
< pArray
->Count(); i
++ )
363 SbxVariableRef
& rRef
= pArray
->GetRef( i
);
364 if( (SbxVariable
*) rRef
== pOld
)
366 nArrayIdx
= i
; break;
374 // If a new object will be established, this object will be indexed,
375 // if an object of this name exists already.
377 SbxVariable
* SbxObject::Make( const OUString
& rName
, SbxClassType ct
, SbxDataType dt
)
379 // Is the object already available?
380 SbxArray
* pArray
= NULL
;
383 case SbxCLASS_VARIABLE
:
384 case SbxCLASS_PROPERTY
: pArray
= pProps
; break;
385 case SbxCLASS_METHOD
: pArray
= pMethods
; break;
386 case SbxCLASS_OBJECT
: pArray
= pObjs
; break;
387 default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
393 // Collections may contain objects of the same name
394 if( !( ct
== SbxCLASS_OBJECT
&& ISA(SbxCollection
) ) )
396 SbxVariable
* pRes
= pArray
->Find( rName
, ct
);
402 SbxVariable
* pVar
= NULL
;
405 case SbxCLASS_VARIABLE
:
406 case SbxCLASS_PROPERTY
:
407 pVar
= new SbxProperty( rName
, dt
);
409 case SbxCLASS_METHOD
:
410 pVar
= new SbxMethod( rName
, dt
);
412 case SbxCLASS_OBJECT
:
413 pVar
= CreateObject( rName
);
418 pVar
->SetParent( this );
419 pArray
->Put( pVar
, pArray
->Count() );
420 SetModified( sal_True
);
421 // The object listen always
422 StartListening( pVar
->GetBroadcaster(), sal_True
);
423 Broadcast( SBX_HINT_OBJECTCHANGED
);
427 SbxObject
* SbxObject::MakeObject( const OUString
& rName
, const OUString
& rClass
)
429 // Is the object already available?
430 if( !ISA(SbxCollection
) )
432 SbxVariable
* pRes
= pObjs
->Find( rName
, SbxCLASS_OBJECT
);
435 return PTR_CAST(SbxObject
,pRes
);
438 SbxObject
* pVar
= CreateObject( rClass
);
441 pVar
->SetName( rName
);
442 pVar
->SetParent( this );
443 pObjs
->Put( pVar
, pObjs
->Count() );
444 SetModified( sal_True
);
445 // The object listen always
446 StartListening( pVar
->GetBroadcaster(), sal_True
);
447 Broadcast( SBX_HINT_OBJECTCHANGED
);
452 void SbxObject::Insert( SbxVariable
* pVar
)
455 SbxArray
* pArray
= FindVar( pVar
, nIdx
);
458 // Into with it. But you should pay attention at the Pointer!
459 if( nIdx
< pArray
->Count() )
461 // Then this element exists already
462 // There are objects of the same name allowed at collections
463 if( pArray
== pObjs
&& ISA(SbxCollection
) )
465 nIdx
= pArray
->Count();
469 SbxVariable
* pOld
= pArray
->Get( nIdx
);
470 // already inside: overwrite
475 EndListening( pOld
->GetBroadcaster(), sal_True
);
476 if( pVar
->GetClass() == SbxCLASS_PROPERTY
)
478 if( pOld
== pDfltProp
)
480 pDfltProp
= (SbxProperty
*) pVar
;
485 StartListening( pVar
->GetBroadcaster(), sal_True
);
486 pArray
->Put( pVar
, nIdx
);
487 if( pVar
->GetParent() != this )
489 pVar
->SetParent( this );
491 SetModified( sal_True
);
492 Broadcast( SBX_HINT_OBJECTCHANGED
);
494 static const char* pCls
[] =
495 { "DontCare","Array","Value","Variable","Method","Property","Object" };
496 OUString
aVarName( pVar
->GetName() );
497 if ( aVarName
.isEmpty() && pVar
->ISA(SbxObject
) )
499 aVarName
= PTR_CAST(SbxObject
,pVar
)->GetClassName();
501 OString
aNameStr1(OUStringToOString(aVarName
, RTL_TEXTENCODING_ASCII_US
));
502 OString
aNameStr2(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US
));
503 DbgOutf( "SBX: Insert %s %s in %s",
504 ( pVar
->GetClass() >= SbxCLASS_DONTCARE
&&
505 pVar
->GetClass() <= SbxCLASS_OBJECT
)
506 ? pCls
[ pVar
->GetClass()-1 ] : "Unknown class", aNameStr1
.getStr(), aNameStr2
.getStr() );
511 // Optimisation, Insertion without checking about
512 // double entry and without broadcasts, will only be used in SO2/auto.cxx
513 void SbxObject::QuickInsert( SbxVariable
* pVar
)
515 SbxArray
* pArray
= NULL
;
518 switch( pVar
->GetClass() )
520 case SbxCLASS_VARIABLE
:
521 case SbxCLASS_PROPERTY
: pArray
= pProps
; break;
522 case SbxCLASS_METHOD
: pArray
= pMethods
; break;
523 case SbxCLASS_OBJECT
: pArray
= pObjs
; break;
524 default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
529 StartListening( pVar
->GetBroadcaster(), sal_True
);
530 pArray
->Put( pVar
, pArray
->Count() );
531 if( pVar
->GetParent() != this )
533 pVar
->SetParent( this );
535 SetModified( sal_True
);
537 static const char* pCls
[] =
538 { "DontCare","Array","Value","Variable","Method","Property","Object" };
539 OUString
aVarName( pVar
->GetName() );
540 if ( aVarName
.isEmpty() && pVar
->ISA(SbxObject
) )
542 aVarName
= PTR_CAST(SbxObject
,pVar
)->GetClassName();
544 OString
aNameStr1(OUStringToOString(aVarName
, RTL_TEXTENCODING_ASCII_US
));
545 OString
aNameStr2(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US
));
546 DbgOutf( "SBX: Insert %s %s in %s",
547 ( pVar
->GetClass() >= SbxCLASS_DONTCARE
&&
548 pVar
->GetClass() <= SbxCLASS_OBJECT
)
549 ? pCls
[ pVar
->GetClass()-1 ] : "Unknown class", aNameStr1
.getStr(), aNameStr2
.getStr() );
554 void SbxObject::Remove( const OUString
& rName
, SbxClassType t
)
556 Remove( SbxObject::Find( rName
, t
) );
559 void SbxObject::Remove( SbxVariable
* pVar
)
562 SbxArray
* pArray
= FindVar( pVar
, nIdx
);
563 if( pArray
&& nIdx
< pArray
->Count() )
566 OUString
aVarName( pVar
->GetName() );
567 if ( aVarName
.isEmpty() && pVar
->ISA(SbxObject
) )
569 aVarName
= PTR_CAST(SbxObject
,pVar
)->GetClassName();
571 OString
aNameStr1(OUStringToOString(aVarName
, RTL_TEXTENCODING_ASCII_US
));
572 OString
aNameStr2(OUStringToOString(SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US
));
573 DbgOutf( "SBX: Remove %s in %s",
574 aNameStr1
.getStr(), aNameStr2
.getStr() );
576 SbxVariableRef pVar_
= pArray
->Get( nIdx
);
577 if( pVar_
->IsBroadcaster() )
579 EndListening( pVar_
->GetBroadcaster(), sal_True
);
581 if( (SbxVariable
*) pVar_
== pDfltProp
)
585 pArray
->Remove( nIdx
);
586 if( pVar_
->GetParent() == this )
588 pVar_
->SetParent( NULL
);
590 SetModified( sal_True
);
591 Broadcast( SBX_HINT_OBJECTCHANGED
);
595 static bool LoadArray( SvStream
& rStrm
, SbxObject
* pThis
, SbxArray
* pArray
)
597 SbxArrayRef p
= (SbxArray
*) SbxBase::Load( rStrm
);
602 for( sal_uInt16 i
= 0; i
< p
->Count(); i
++ )
604 SbxVariableRef
& r
= p
->GetRef( i
);
605 SbxVariable
* pVar
= r
;
608 pVar
->SetParent( pThis
);
609 pThis
->StartListening( pVar
->GetBroadcaster(), sal_True
);
616 // The load of an object is additive!
618 sal_Bool
SbxObject::LoadData( SvStream
& rStrm
, sal_uInt16 nVer
)
620 // Help for the read in of old objects: just return TRUE,
621 // LoadPrivateData() has to set the default status up
627 if( !SbxVariable::LoadData( rStrm
, nVer
) )
631 // If it contains no alien object, insert ourselves
632 if( aData
.eType
== SbxOBJECT
&& !aData
.pObj
)
638 aClassName
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(rStrm
, RTL_TEXTENCODING_ASCII_US
);
639 aDfltProp
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(rStrm
, RTL_TEXTENCODING_ASCII_US
);
640 sal_uIntPtr nPos
= rStrm
.Tell();
642 if( !LoadPrivateData( rStrm
, nVer
) )
646 sal_uIntPtr nNewPos
= rStrm
.Tell();
648 DBG_ASSERT( nPos
>= nNewPos
, "SBX: Loaded too much data" );
649 if( nPos
!= nNewPos
)
653 if( !LoadArray( rStrm
, this, pMethods
) ||
654 !LoadArray( rStrm
, this, pProps
) ||
655 !LoadArray( rStrm
, this, pObjs
) )
660 if( !aDfltProp
.isEmpty() )
662 pDfltProp
= (SbxProperty
*) pProps
->Find( aDfltProp
, SbxCLASS_PROPERTY
);
664 SetModified( sal_False
);
668 sal_Bool
SbxObject::StoreData( SvStream
& rStrm
) const
670 if( !SbxVariable::StoreData( rStrm
) )
677 aDfltProp
= pDfltProp
->GetName();
679 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(rStrm
, aClassName
, RTL_TEXTENCODING_ASCII_US
);
680 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(rStrm
, aDfltProp
, RTL_TEXTENCODING_ASCII_US
);
681 sal_uIntPtr nPos
= rStrm
.Tell();
682 rStrm
<< (sal_uInt32
) 0L;
683 if( !StorePrivateData( rStrm
) )
687 sal_uIntPtr nNew
= rStrm
.Tell();
689 rStrm
<< (sal_uInt32
) ( nNew
- nPos
);
691 if( !pMethods
->Store( rStrm
) )
695 if( !pProps
->Store( rStrm
) )
699 if( !pObjs
->Store( rStrm
) )
703 ((SbxObject
*) this)->SetModified( sal_False
);
707 OUString
SbxObject::GenerateSource( const OUString
&rLinePrefix
,
710 // Collect the properties in a String
712 SbxArrayRef
xProps( GetProperties() );
713 bool bLineFeed
= false;
714 for ( sal_uInt16 nProp
= 0; nProp
< xProps
->Count(); ++nProp
)
716 SbxPropertyRef xProp
= (SbxProperty
*) xProps
->Get(nProp
);
717 OUString
aPropName( xProp
->GetName() );
718 if ( xProp
->CanWrite() &&
719 !( xProp
->GetHashCode() == nNameHash
&&
720 aPropName
.equalsIgnoreAsciiCase(pNameProp
)))
722 // Insert a break except in front of the first property
731 aSource
+= rLinePrefix
;
733 aSource
+= aPropName
;
736 // convert the property value to text
737 switch ( xProp
->GetType() )
745 // Strings in quotation mark
747 aSource
+= xProp
->GetOUString();
752 // miscellaneous, such as e.g. numbers directly
753 aSource
+= xProp
->GetOUString();
761 static bool CollectAttrs( const SbxBase
* p
, OUString
& rRes
)
768 if( p
->IsSet( SBX_EXTSEARCH
) )
770 if( !aAttrs
.isEmpty() )
774 aAttrs
+= "ExtSearch";
776 if( !p
->IsVisible() )
778 if( !aAttrs
.isEmpty() )
782 aAttrs
+= "Invisible";
784 if( p
->IsSet( SBX_DONTSTORE
) )
786 if( !aAttrs
.isEmpty() )
790 aAttrs
+= "DontStore";
792 if( !aAttrs
.isEmpty() )
806 void SbxObject::Dump( SvStream
& rStrm
, sal_Bool bFill
)
809 static sal_uInt16 nLevel
= 0;
812 rStrm
<< "<too deep>" << endl
;
816 OUString
aIndent("");
817 for ( sal_uInt16 n
= 1; n
< nLevel
; ++n
)
821 // if necessary complete the object
824 GetAll( SbxCLASS_DONTCARE
);
826 // Output the data of the object itself
827 OString
aNameStr(OUStringToOString(GetName(), RTL_TEXTENCODING_ASCII_US
));
828 OString
aClassNameStr(OUStringToOString(aClassName
, RTL_TEXTENCODING_ASCII_US
));
830 << OString::number(reinterpret_cast<sal_Int64
>(this)).getStr()<< "=='"
831 << ( aNameStr
.isEmpty() ? "<unnamed>" : aNameStr
.getStr() ) << "', "
832 << "of class '" << aClassNameStr
.getStr() << "', "
834 << OString::number(GetRefCount()).getStr()
838 OString
aParentNameStr(OUStringToOString(GetName(), RTL_TEXTENCODING_ASCII_US
));
839 rStrm
<< "in parent "
840 << OString::number(reinterpret_cast<sal_Int64
>(GetParent())).getStr()
841 << "=='" << ( aParentNameStr
.isEmpty() ? "<unnamed>" : aParentNameStr
.getStr() ) << "'";
845 rStrm
<< "no parent ";
847 rStrm
<< " )" << endl
;
848 OString
aIndentNameStr(OUStringToOString(aIndent
, RTL_TEXTENCODING_ASCII_US
));
849 rStrm
<< aIndentNameStr
.getStr() << "{" << endl
;
853 if( CollectAttrs( this, aAttrs
) )
855 OString
aAttrStr(OUStringToOString(aAttrs
, RTL_TEXTENCODING_ASCII_US
));
856 rStrm
<< aIndentNameStr
.getStr() << "- Flags: " << aAttrStr
.getStr() << endl
;
860 rStrm
<< aIndentNameStr
.getStr() << "- Methods:" << endl
;
861 for( sal_uInt16 i
= 0; i
< pMethods
->Count(); i
++ )
863 SbxVariableRef
& r
= pMethods
->GetRef( i
);
864 SbxVariable
* pVar
= r
;
867 OUString
aLine( aIndent
);
869 aLine
+= pVar
->GetName( SbxNAME_SHORT_TYPES
);
871 if( CollectAttrs( pVar
, aAttrs2
) )
875 if( !pVar
->IsA( TYPE(SbxMethod
) ) )
877 aLine
+= " !! Not a Method !!";
879 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(rStrm
, aLine
, RTL_TEXTENCODING_ASCII_US
);
881 // Output also the object at object-methods
882 if ( pVar
->GetValues_Impl().eType
== SbxOBJECT
&&
883 pVar
->GetValues_Impl().pObj
&&
884 pVar
->GetValues_Impl().pObj
!= this &&
885 pVar
->GetValues_Impl().pObj
!= GetParent() )
887 rStrm
<< " contains ";
888 ((SbxObject
*) pVar
->GetValues_Impl().pObj
)->Dump( rStrm
, bFill
);
898 rStrm
<< aIndentNameStr
.getStr() << "- Properties:" << endl
;
900 for( sal_uInt16 i
= 0; i
< pProps
->Count(); i
++ )
902 SbxVariableRef
& r
= pProps
->GetRef( i
);
903 SbxVariable
* pVar
= r
;
906 OUString
aLine( aIndent
);
908 aLine
+= pVar
->GetName( SbxNAME_SHORT_TYPES
);
910 if( CollectAttrs( pVar
, aAttrs3
) )
914 if( !pVar
->IsA( TYPE(SbxProperty
) ) )
916 aLine
+= " !! Not a Property !!";
918 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(rStrm
, aLine
, RTL_TEXTENCODING_ASCII_US
);
920 // output also the object at object properties
921 if ( pVar
->GetValues_Impl().eType
== SbxOBJECT
&&
922 pVar
->GetValues_Impl().pObj
&&
923 pVar
->GetValues_Impl().pObj
!= this &&
924 pVar
->GetValues_Impl().pObj
!= GetParent() )
926 rStrm
<< " contains ";
927 ((SbxObject
*) pVar
->GetValues_Impl().pObj
)->Dump( rStrm
, bFill
);
938 rStrm
<< aIndentNameStr
.getStr() << "- Objects:" << endl
;
940 for( sal_uInt16 i
= 0; i
< pObjs
->Count(); i
++ )
942 SbxVariableRef
& r
= pObjs
->GetRef( i
);
943 SbxVariable
* pVar
= r
;
946 rStrm
<< aIndentNameStr
.getStr() << " - Sub";
947 if ( pVar
->ISA(SbxObject
) )
949 ((SbxObject
*) pVar
)->Dump( rStrm
, bFill
);
951 else if ( pVar
->ISA(SbxVariable
) )
953 ((SbxVariable
*) pVar
)->Dump( rStrm
, bFill
);
959 rStrm
<< aIndentNameStr
.getStr() << "}" << endl
<< endl
;
963 SbxMethod::SbxMethod( const OUString
& r
, SbxDataType t
)
969 SbxMethod::SbxMethod( const SbxMethod
& r
)
970 : SvRefBase( r
), SbxVariable( r
)
974 SbxMethod::~SbxMethod()
978 SbxClassType
SbxMethod::GetClass() const
980 return SbxCLASS_METHOD
;
983 SbxProperty::SbxProperty( const OUString
& r
, SbxDataType t
)
989 SbxProperty::~SbxProperty()
993 SbxClassType
SbxProperty::GetClass() const
995 return SbxCLASS_PROPERTY
;
998 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */