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 .
24 #include <tools/debug.hxx>
27 #include <globals.hxx>
28 #include <database.hxx>
30 TYPEINIT1( SvMetaAttribute
, SvMetaReference
);
31 SvMetaAttribute::SvMetaAttribute()
32 : aAutomation( true, false )
33 , aExport( true, false )
34 , aIsCollection ( false, false )
35 , aReadOnlyDoc ( true, false )
36 , aHidden( false, false )
41 SvMetaAttribute::SvMetaAttribute( SvMetaType
* pType
)
43 , aAutomation( true, false )
44 , aExport( true, false )
45 , aIsCollection ( false, false)
46 , aReadOnlyDoc ( true, false)
47 , aHidden( false, false )
52 SvMetaType
* SvMetaAttribute::GetType() const
54 if( aType
.Is() || !GetRef() ) return aType
;
55 return static_cast<SvMetaAttribute
*>(GetRef())->GetType();
58 const SvNumberIdentifier
& SvMetaAttribute::GetSlotId() const
60 if( aSlotId
.IsSet() || !GetRef() ) return aSlotId
;
61 return static_cast<SvMetaAttribute
*>(GetRef())->GetSlotId();
64 bool SvMetaAttribute::GetReadonly() const
66 if( aReadonly
.IsSet() || !GetRef() ) return aReadonly
;
67 return static_cast<SvMetaAttribute
*>(GetRef())->GetReadonly();
70 bool SvMetaAttribute::GetExport() const
72 if( aExport
.IsSet() || !GetRef() ) return aExport
;
73 return static_cast<SvMetaAttribute
*>(GetRef())->GetExport();
76 bool SvMetaAttribute::GetHidden() const
78 // when export is set, but hidden is not the default is used
79 if ( aExport
.IsSet() && !aHidden
.IsSet() )
81 else if( aHidden
.IsSet() || !GetRef() )
84 return static_cast<SvMetaAttribute
*>(GetRef())->GetHidden();
87 bool SvMetaAttribute::GetAutomation() const
89 if( aAutomation
.IsSet() || !GetRef() ) return aAutomation
;
90 return static_cast<SvMetaAttribute
*>(GetRef())->GetAutomation();
93 bool SvMetaAttribute::GetIsCollection() const
95 if( aIsCollection
.IsSet() || !GetRef() )
100 return static_cast<SvMetaSlot
*>(GetRef())->GetIsCollection();
103 bool SvMetaAttribute::GetReadOnlyDoc() const
105 if( aReadOnlyDoc
.IsSet() || !GetRef() ) return aReadOnlyDoc
;
106 return static_cast<SvMetaSlot
*>(GetRef())->GetReadOnlyDoc();
109 bool SvMetaAttribute::IsMethod() const
111 SvMetaType
* pType
= GetType();
112 DBG_ASSERT( pType
, "no type for attribute" );
113 return pType
->GetType() == TYPE_METHOD
;
116 bool SvMetaAttribute::IsVariable() const
118 SvMetaType
* pType
= GetType();
119 return pType
->GetType() != TYPE_METHOD
;
122 OString
SvMetaAttribute::GetMangleName( bool ) const
124 return GetName().getString();
127 bool SvMetaAttribute::Test( SvIdlDataBase
& rBase
,
128 SvTokenStream
& rInStm
)
131 if( GetType()->IsItem() && !GetSlotId().IsSet() )
133 rBase
.SetError( "slot without id declared", rInStm
.GetToken() );
134 rBase
.WriteError( rInStm
);
140 bool SvMetaAttribute::ReadSvIdl( SvIdlDataBase
& rBase
,
141 SvTokenStream
& rInStm
)
143 sal_uInt32 nTokPos
= rInStm
.Tell();
145 // no type in ctor passed on
146 aType
= rBase
.ReadKnownType( rInStm
);
150 ReadNameSvIdl( rBase
, rInStm
);
151 aSlotId
.ReadSvIdl( rBase
, rInStm
);
154 SvToken
* pTok
= rInStm
.GetToken();
155 if( bOk
&& pTok
->IsChar() && pTok
->GetChar() == '(' )
157 SvMetaTypeRef xT
= new SvMetaType();
158 xT
->SetRef( GetType() );
160 bOk
= aType
->ReadMethodArgs( rBase
, rInStm
);
163 bOk
= SvMetaName::ReadSvIdl( rBase
, rInStm
);
167 SvToken
*pTok
= rInStm
.GetToken();
168 rBase
.SetError( "unknown type of token. Each new SID needs an "
169 "item statement in an SDI file, eg. "
170 "SfxVoidItem FooItem " + pTok
->GetTokenAsString() +
171 " ... which describes the slot more fully", pTok
);
175 rInStm
.Seek( nTokPos
);
179 void SvMetaAttribute::ReadAttributesSvIdl( SvIdlDataBase
& rBase
,
180 SvTokenStream
& rInStm
)
182 SvMetaReference::ReadAttributesSvIdl( rBase
, rInStm
);
183 aSlotId
.ReadSvIdl( rBase
, SvHash_SlotId(), rInStm
);
184 aExport
.ReadSvIdl( SvHash_Export(), rInStm
);
185 aHidden
.ReadSvIdl( SvHash_Hidden(), rInStm
);
186 aAutomation
.ReadSvIdl( SvHash_Automation(), rInStm
);
187 aIsCollection
.ReadSvIdl( SvHash_IsCollection(), rInStm
);
188 aReadOnlyDoc
.ReadSvIdl( SvHash_ReadOnlyDoc(), rInStm
);
189 if( aReadonly
.ReadSvIdl( SvHash_Readonly(), rInStm
) )
191 if( GetType()->GetType() == TYPE_METHOD
)
194 rBase
.SetError( "Readonly in function attribute", rInStm
.GetToken() );
195 rBase
.WriteError( rInStm
);
200 sal_uLong
SvMetaAttribute::MakeSfx( OStringBuffer
& rAttrArray
)
202 SvMetaType
* pType
= GetType();
203 DBG_ASSERT( pType
, "no type for attribute" );
204 SvMetaType
* pBaseType
= pType
->GetBaseType();
205 DBG_ASSERT( pBaseType
, "no base type for attribute" );
206 if( pBaseType
->GetType() == TYPE_STRUCT
)
207 return pBaseType
->MakeSfx( rAttrArray
);
210 rAttrArray
.append('{');
211 rAttrArray
.append(GetSlotId().getString());
212 rAttrArray
.append(",\"");
213 rAttrArray
.append(GetName().getString());
214 rAttrArray
.append("\"}");
219 void SvMetaAttribute::Insert (SvSlotElementList
&, const OString
&, SvIdlDataBase
&)
223 TYPEINIT1( SvMetaType
, SvMetaExtern
);
225 : aCall0( CALL_VALUE, false ) \
226 , aCall1( CALL_VALUE, false ) \
227 , aSbxDataType( 0, false ) \
228 , pAttrList( NULL ) \
229 , nType( TYPE_BASE ) \
231 , bIsShell( false ) \
234 SvMetaType::SvMetaType()
239 SvMetaType::SvMetaType( const OString
& rName
, char cPC
,
240 const OString
& rCName
)
245 aCName
.setString(rCName
);
248 SvMetaType::SvMetaType( const OString
& rName
,
249 const OString
& rSbxName
,
250 const OString
& rOdlName
,
252 const OString
& rCName
,
253 const OString
& rBasicName
,
254 const OString
& rBasicPostfix
)
258 aSbxName
.setString(rSbxName
);
259 aOdlName
.setString(rOdlName
);
261 aCName
.setString(rCName
);
262 aBasicName
.setString(rBasicName
);
263 aBasicPostfix
.setString(rBasicPostfix
);
266 SvMetaType::~SvMetaType() {
270 SvMetaAttributeMemberList
& SvMetaType::GetAttrList() const
273 const_cast<SvMetaType
*>(this)->pAttrList
= new SvMetaAttributeMemberList();
277 void SvMetaType::SetType( int nT
)
280 if( nType
== TYPE_ENUM
)
282 aOdlName
.setString("short");
284 else if( nType
== TYPE_CLASS
)
286 OStringBuffer
aTmp(C_PREF
);
287 aTmp
.append("Object *");
288 aCName
.setString(aTmp
.makeStringAndClear());
292 SvMetaType
* SvMetaType::GetBaseType() const
294 if( GetRef() && GetType() == TYPE_BASE
)
295 return static_cast<SvMetaType
*>(GetRef())->GetBaseType();
296 return const_cast<SvMetaType
*>(this);
299 SvMetaType
* SvMetaType::GetReturnType() const
301 DBG_ASSERT( GetType() == TYPE_METHOD
, "no method" );
302 DBG_ASSERT( GetRef(), "no return type" );
303 return static_cast<SvMetaType
*>(GetRef());
306 const OString
& SvMetaType::GetBasicName() const
308 if( aBasicName
.IsSet() || !GetRef() )
309 return aBasicName
.getString();
311 return static_cast<SvMetaType
*>(GetRef())->GetBasicName();
314 bool SvMetaType::GetIn() const
316 if( aIn
.IsSet() || !GetRef() )
319 return static_cast<SvMetaType
*>(GetRef())->GetIn();
322 bool SvMetaType::GetOut() const
324 if( aOut
.IsSet() || !GetRef() )
327 return static_cast<SvMetaType
*>(GetRef())->GetOut();
330 void SvMetaType::SetCall0( int e
)
333 if( aCall0
== CALL_VALUE
&& aCall1
== CALL_VALUE
)
335 if( GetType() == TYPE_POINTER
)
336 SetType( TYPE_BASE
);
340 DBG_ASSERT( nType
== TYPE_POINTER
|| nType
== TYPE_BASE
,
341 "set no base type to pointer" );
342 SetType( TYPE_POINTER
);
346 int SvMetaType::GetCall0() const
348 if( aCall0
.IsSet() || !GetRef() )
351 return static_cast<SvMetaType
*>(GetRef())->GetCall0();
354 void SvMetaType::SetCall1( int e
)
357 if( aCall0
== CALL_VALUE
&& aCall1
== CALL_VALUE
)
359 if( GetType() == TYPE_POINTER
)
360 SetType( TYPE_BASE
);
364 DBG_ASSERT( nType
== TYPE_POINTER
|| nType
== TYPE_BASE
,
365 "set no base type to pointer" );
366 SetType( TYPE_POINTER
);
370 int SvMetaType::GetCall1() const
372 if( aCall1
.IsSet() || !GetRef() )
375 return static_cast<SvMetaType
*>(GetRef())->GetCall1();
378 const OString
& SvMetaType::GetSvName() const
380 if( aSvName
.IsSet() || !GetRef() )
381 return aSvName
.getString();
383 return static_cast<SvMetaType
*>(GetRef())->GetSvName();
386 const OString
& SvMetaType::GetSbxName() const
388 if( aSbxName
.IsSet() || !GetRef() )
389 return aSbxName
.getString();
391 return static_cast<SvMetaType
*>(GetRef())->GetSbxName();
394 const OString
& SvMetaType::GetOdlName() const
396 if( aOdlName
.IsSet() || !GetRef() )
397 return aOdlName
.getString();
399 return static_cast<SvMetaType
*>(GetRef())->GetOdlName();
402 const OString
& SvMetaType::GetCName() const
404 if( aCName
.IsSet() || !GetRef() )
405 return aCName
.getString();
407 return static_cast<SvMetaType
*>(GetRef())->GetCName();
410 bool SvMetaType::SetName( const OString
& rName
, SvIdlDataBase
* pBase
)
412 aSvName
.setString(rName
);
413 aSbxName
.setString(rName
);
414 aCName
.setString(rName
);
415 if( GetType() != TYPE_ENUM
)
416 aOdlName
.setString(rName
);
417 return SvMetaReference::SetName( rName
, pBase
);
420 bool SvMetaType::ReadHeaderSvIdl( SvIdlDataBase
& rBase
,
421 SvTokenStream
& rInStm
)
424 sal_uInt32 nTokPos
= rInStm
.Tell();
425 SvToken
* pTok
= rInStm
.GetToken_Next();
427 if( pTok
->Is( SvHash_interface() )
428 || pTok
->Is( SvHash_shell() ) )
430 if( pTok
->Is( SvHash_shell() ) )
432 SetType( TYPE_CLASS
);
433 bOk
= ReadNamesSvIdl( rBase
, rInStm
);
436 else if( pTok
->Is( SvHash_struct() ) )
438 SetType( TYPE_STRUCT
);
439 bOk
= ReadNamesSvIdl( rBase
, rInStm
);
441 else if( pTok
->Is( SvHash_union() ) )
443 SetType( TYPE_UNION
);
444 if( ReadNameSvIdl( rBase
, rInStm
) )
447 else if( pTok
->Is( SvHash_enum() ) )
449 SetType( TYPE_ENUM
);
450 bOk
= ReadNameSvIdl( rBase
, rInStm
);
452 else if( pTok
->Is( SvHash_typedef() )
453 || pTok
->Is( SvHash_item() ) )
455 if( pTok
->Is( SvHash_item() ) )
458 SvMetaType
* pType
= rBase
.ReadKnownType( rInStm
);
462 if( ReadNameSvIdl( rBase
, rInStm
) )
464 if( rInStm
.Read( '(' ) )
466 DoReadContextSvIdl( rBase
, rInStm
);
467 if( rInStm
.Read( ')' ) )
469 SetType( TYPE_METHOD
);
481 OString
aStr("wrong typedef: ");
482 rBase
.SetError( aStr
, rInStm
.GetToken() );
483 rBase
.WriteError( rInStm
);
489 rInStm
.Seek( nTokPos
);
493 bool SvMetaType::ReadSvIdl( SvIdlDataBase
& rBase
,
494 SvTokenStream
& rInStm
)
496 if( ReadHeaderSvIdl( rBase
, rInStm
) )
498 rBase
.Write(OString('.'));
499 return SvMetaExtern::ReadSvIdl( rBase
, rInStm
);
504 bool SvMetaType::ReadNamesSvIdl( SvIdlDataBase
& rBase
,
505 SvTokenStream
& rInStm
)
507 bool bOk
= ReadNameSvIdl( rBase
, rInStm
);
512 void SvMetaType::ReadAttributesSvIdl( SvIdlDataBase
& rBase
,
513 SvTokenStream
& rInStm
)
515 SvMetaExtern::ReadAttributesSvIdl( rBase
, rInStm
);
516 aSvName
.ReadSvIdl( SvHash_SvName(), rInStm
);
517 aSbxName
.ReadSvIdl( SvHash_SbxName(), rInStm
);
518 aOdlName
.ReadSvIdl( SvHash_OdlName(), rInStm
);
521 void SvMetaType::ReadContextSvIdl( SvIdlDataBase
& rBase
,
522 SvTokenStream
& rInStm
)
524 SvMetaAttributeRef xAttr
= new SvMetaAttribute();
525 if( xAttr
->ReadSvIdl( rBase
, rInStm
) )
527 if( xAttr
->Test( rBase
, rInStm
) )
528 GetAttrList().push_back( xAttr
);
532 sal_uLong
SvMetaType::MakeSfx( OStringBuffer
& rAttrArray
)
536 if( GetBaseType()->GetType() == TYPE_STRUCT
)
538 sal_uLong nAttrCount
= GetAttrCount();
539 // write the single attributes
540 for( sal_uLong n
= 0; n
< nAttrCount
; n
++ )
542 nC
+= (*pAttrList
)[n
]->MakeSfx( rAttrArray
);
543 if( n
+1 < nAttrCount
)
544 rAttrArray
.append(", ");
550 void SvMetaType::WriteSfxItem(
551 const OString
& rItemName
, SvIdlDataBase
& rBase
, SvStream
& rOutStm
)
553 WriteStars( rOutStm
);
554 OStringBuffer
aVarName(" a");
555 aVarName
.append(rItemName
).append("_Impl");
557 OStringBuffer
aTypeName("SfxType");
558 OStringBuffer aAttrArray
;
559 sal_uLong nAttrCount
= MakeSfx( aAttrArray
);
561 OString::number(nAttrCount
));
562 aTypeName
.append(aAttrCount
);
564 bool bExport
= false, bReturn
= false;
565 // these are exported from sfx library
566 if (rItemName
== "SfxBoolItem" ||
567 rItemName
== "SfxStringItem" ||
568 rItemName
== "SfxUInt16Item" ||
569 rItemName
== "SfxUInt32Item" ||
570 rItemName
== "SfxVoidItem")
573 if (!rBase
.sSlotMapFile
.endsWith("sfxslots.hxx"))
577 rOutStm
.WriteCharPtr( "extern " );
579 rOutStm
.WriteCharPtr( "SFX2_DLLPUBLIC " );
580 rOutStm
.WriteCharPtr( aTypeName
.getStr() )
581 .WriteCharPtr( aVarName
.getStr() ).WriteChar( ';' ) << endl
;
585 // write the implementation part
586 rOutStm
.WriteCharPtr( "#ifdef SFX_TYPEMAP" ) << endl
;
587 rOutStm
.WriteCharPtr( "#if !defined(_WIN32) && ((defined(DISABLE_DYNLOADING) && (defined(ANDROID) || defined(IOS))) || STATIC_LINKING)" ) << endl
;
588 rOutStm
.WriteCharPtr( "__attribute__((__weak__))" ) << endl
;
589 rOutStm
.WriteCharPtr( "#endif" ) << endl
;
591 rOutStm
.WriteCharPtr( "SFX2_DLLPUBLIC " );
592 rOutStm
.WriteCharPtr( aTypeName
.getStr() ).WriteCharPtr( aVarName
.getStr() )
593 .WriteCharPtr( " = " ) << endl
;
594 rOutStm
.WriteChar( '{' ) << endl
;
595 rOutStm
.WriteCharPtr( "\tTYPE(" ).WriteCharPtr( rItemName
.getStr() ).WriteCharPtr( "), " )
596 .WriteCharPtr( aAttrCount
.getStr() );
599 rOutStm
.WriteCharPtr( ", { " );
600 // write the single attributes
601 rOutStm
.WriteCharPtr( aAttrArray
.getStr() );
602 rOutStm
.WriteCharPtr( " }" );
605 rOutStm
.WriteCharPtr( "};" ) << endl
;
606 rOutStm
.WriteCharPtr( "#endif" ) << endl
<< endl
;
609 void SvMetaType::WriteSfx( SvIdlDataBase
& rBase
, SvStream
& rOutStm
)
613 if( GetBaseType()->GetType() == TYPE_STRUCT
)
614 GetBaseType()->WriteSfxItem( GetName().getString(), rBase
, rOutStm
);
616 WriteSfxItem( GetName().getString(), rBase
, rOutStm
);
620 bool SvMetaType::ReadMethodArgs( SvIdlDataBase
& rBase
,
621 SvTokenStream
& rInStm
)
623 sal_uInt32 nTokPos
= rInStm
.Tell();
624 if( rInStm
.Read( '(' ) )
626 DoReadContextSvIdl( rBase
, rInStm
);
627 if( rInStm
.Read( ')' ) )
629 SetType( TYPE_METHOD
);
633 rInStm
.Seek( nTokPos
);
637 OString
SvMetaType::GetParserString() const
639 SvMetaType
* pBT
= GetBaseType();
641 return pBT
->GetParserString();
643 int type
= GetType();
646 if( TYPE_METHOD
== type
|| TYPE_STRUCT
== type
)
648 sal_uLong nAttrCount
= GetAttrCount();
649 // write the single attributes
650 for( sal_uLong n
= 0; n
< nAttrCount
; n
++ )
652 SvMetaAttribute
* pT
= (*pAttrList
)[n
];
653 aPStr
+= pT
->GetType()->GetParserString();
657 aPStr
= OString(GetParserChar());
661 TYPEINIT1( SvMetaTypeString
, SvMetaType
);
662 SvMetaTypeString::SvMetaTypeString()
663 : SvMetaType( "String", "SbxSTRING", "BSTR", 's', "char *", "String", "$" )
667 TYPEINIT1( SvMetaEnumValue
, SvMetaName
);
668 SvMetaEnumValue::SvMetaEnumValue()
672 bool SvMetaEnumValue::ReadSvIdl( SvIdlDataBase
& rBase
,
673 SvTokenStream
& rInStm
)
675 if( !ReadNameSvIdl( rBase
, rInStm
) )
680 TYPEINIT1( SvMetaTypeEnum
, SvMetaType
);
681 SvMetaTypeEnum::SvMetaTypeEnum()
683 SetBasicName("Integer");
688 OString
getCommonSubPrefix(const OString
&rA
, const OString
&rB
)
690 sal_Int32 nMax
= std::min(rA
.getLength(), rB
.getLength());
694 if (rA
[nI
] != rB
[nI
])
698 return rA
.copy(0, nI
);
702 void SvMetaTypeEnum::ReadContextSvIdl( SvIdlDataBase
& rBase
,
703 SvTokenStream
& rInStm
)
705 sal_uInt32 nTokPos
= rInStm
.Tell();
707 SvMetaEnumValueRef aEnumVal
= new SvMetaEnumValue();
708 bool bOk
= aEnumVal
->ReadSvIdl( rBase
, rInStm
);
711 if( aEnumValueList
.empty() )
714 aPrefix
= aEnumVal
->GetName().getString();
718 aPrefix
= getCommonSubPrefix(aPrefix
, aEnumVal
->GetName().getString());
720 aEnumValueList
.push_back( aEnumVal
);
723 rInStm
.Seek( nTokPos
);
726 bool SvMetaTypeEnum::ReadSvIdl( SvIdlDataBase
& rBase
,
727 SvTokenStream
& rInStm
)
729 sal_uInt32 nTokPos
= rInStm
.Tell();
730 if( SvMetaType::ReadHeaderSvIdl( rBase
, rInStm
)
731 && GetType() == TYPE_ENUM
)
733 if( SvMetaName::ReadSvIdl( rBase
, rInStm
) )
736 rInStm
.Seek( nTokPos
);
740 TYPEINIT1( SvMetaTypevoid
, SvMetaType
);
741 SvMetaTypevoid::SvMetaTypevoid()
742 : SvMetaType( "void", "SbxVOID", "void", 'v', "void", "", "" )
746 OString
SvMetaAttribute::Compare( SvMetaAttribute
* pAttr
)
752 if ( aType
->GetType() == TYPE_METHOD
)
754 // Test only when the attribute is a method not if it has one!
755 if ( pAttr
->GetType()->GetType() != TYPE_METHOD
)
756 aStr
.append(" IsMethod\n");
757 else if ( aType
->GetReturnType() &&
758 aType
->GetReturnType()->GetType() != pAttr
->GetType()->GetReturnType()->GetType() )
760 aStr
.append(" ReturnType\n");
763 if ( aType
->GetAttrCount() )
765 sal_uLong nCount
= aType
->GetAttrCount();
766 SvMetaAttributeMemberList
& rList
= aType
->GetAttrList();
767 SvMetaAttributeMemberList
& rOtherList
= pAttr
->GetType()->GetAttrList();
768 if ( pAttr
->GetType()->GetAttrCount() != nCount
)
770 aStr
.append(" AttributeCount\n");
774 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
776 SvMetaAttribute
*pAttr1
= rList
[n
];
777 SvMetaAttribute
*pAttr2
= rOtherList
[n
];
778 pAttr1
->Compare( pAttr2
);
784 if ( GetType()->GetType() != pAttr
->GetType()->GetType() )
785 aStr
.append(" Type\n");
787 if ( !GetType()->GetSvName().equals( pAttr
->GetType()->GetSvName() ) )
788 aStr
.append(" ItemType\n");
791 if ( GetExport() != pAttr
->GetExport() )
792 aStr
.append(" Export\n");
794 if ( GetAutomation() != pAttr
->GetAutomation() )
795 aStr
.append(" Automation\n");
797 if ( GetIsCollection() != pAttr
->GetIsCollection() )
798 aStr
.append(" IsCollection\n");
800 if ( GetReadOnlyDoc() != pAttr
->GetReadOnlyDoc() )
801 aStr
.append(" ReadOnlyDoc\n");
803 if ( GetExport() && GetReadonly() != pAttr
->GetReadonly() )
804 aStr
.append(" Readonly\n");
806 return aStr
.makeStringAndClear();
809 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */