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 <rtl/strbuf.hxx>
25 #include <osl/diagnose.h>
28 #include <globals.hxx>
29 #include <database.hxx>
31 TYPEINIT1( SvClassElement
, SvPersistBase
);
33 SvClassElement::SvClassElement()
37 TYPEINIT1( SvMetaClass
, SvMetaType
);
38 SvMetaClass::SvMetaClass()
39 : aAutomation( true, false )
43 void SvMetaClass::ReadAttributesSvIdl( SvIdlDataBase
& rBase
,
44 SvTokenStream
& rInStm
)
46 SvMetaType::ReadAttributesSvIdl( rBase
, rInStm
);
47 aAutomation
.ReadSvIdl( SvHash_Automation(), rInStm
);
50 void SvMetaClass::ReadContextSvIdl( SvIdlDataBase
& rBase
,
51 SvTokenStream
& rInStm
)
53 sal_uInt32 nTokPos
= rInStm
.Tell();
54 SvToken
* pTok
= rInStm
.GetToken_Next();
56 if( pTok
->Is( SvHash_import() ) )
58 SvMetaClass
* pClass
= rBase
.ReadKnownClass( rInStm
);
61 SvClassElementRef xEle
= new SvClassElement();
62 xEle
->SetClass( pClass
);
63 aClassList
.push_back( xEle
);
65 if( rInStm
.Read( '[' ) )
67 pTok
= rInStm
.GetToken_Next();
68 if( pTok
->Is( SvHash_Automation() ) )
70 if( rInStm
.Read( ']' ) )
72 if( xAutomationInterface
.Is() )
75 rBase
.SetError( "Automation already set",
77 rBase
.WriteError( rInStm
);
79 xAutomationInterface
= pClass
;
80 xEle
->SetAutomation( true );
85 rBase
.SetError( "missing ]", rInStm
.GetToken() );
86 rBase
.WriteError( rInStm
);
92 rBase
.SetError( "only attribute Automation allowed",
94 rBase
.WriteError( rInStm
);
97 pTok
= rInStm
.GetToken();
98 if( pTok
->IsString() )
100 xEle
->SetPrefix( pTok
->GetString() );
101 rInStm
.GetToken_Next();
108 rBase
.SetError( "unknown imported interface", rInStm
.GetToken() );
109 rBase
.WriteError( rInStm
);
114 rInStm
.Seek( nTokPos
);
115 SvMetaType
* pType
= rBase
.ReadKnownType( rInStm
);
118 SvMetaAttributeRef xAttr
;
119 if( !pType
|| pType
->IsItem() )
121 xAttr
= new SvMetaSlot( pType
);
122 if( xAttr
->ReadSvIdl( rBase
, rInStm
) )
123 bOk
= xAttr
->Test( rBase
, rInStm
);
127 xAttr
= new SvMetaAttribute( pType
);
128 if( xAttr
->ReadSvIdl( rBase
, rInStm
) )
129 bOk
= xAttr
->Test( rBase
, rInStm
);
133 bOk
= TestAttribute( rBase
, rInStm
, *xAttr
);
136 if( !xAttr
->GetSlotId().IsSet() )
138 SvNumberIdentifier aI
;
139 aI
.SetValue( rBase
.GetUniqueId() );
140 xAttr
->SetSlotId( aI
);
142 aAttrList
.push_back( xAttr
);
146 rInStm
.Seek( nTokPos
);
149 bool SvMetaClass::ReadSvIdl( SvIdlDataBase
& rBase
, SvTokenStream
& rInStm
)
151 sal_uLong nTokPos
= rInStm
.Tell();
152 if( SvMetaType::ReadHeaderSvIdl( rBase
, rInStm
) && GetType() == TYPE_CLASS
)
155 if( rInStm
.Read( ':' ) )
157 aSuperClass
= rBase
.ReadKnownClass( rInStm
);
158 bOk
= aSuperClass
.Is();
162 rBase
.SetError( "unknown super class",
164 rBase
.WriteError( rInStm
);
169 rBase
.Write(OString('.'));
170 bOk
= SvMetaName::ReadSvIdl( rBase
, rInStm
);
175 rInStm
.Seek( nTokPos
);
179 bool SvMetaClass::TestAttribute( SvIdlDataBase
& rBase
, SvTokenStream
& rInStm
,
180 SvMetaAttribute
& rAttr
) const
182 if ( !rAttr
.GetRef() && rAttr
.IsA( TYPE( SvMetaSlot
) ) )
184 OSL_FAIL( "Neuer Slot : " );
185 OSL_FAIL( rAttr
.GetSlotId().getString().getStr() );
188 for( sal_uLong n
= 0; n
< aAttrList
.size(); n
++ )
190 SvMetaAttribute
* pS
= aAttrList
[n
];
191 if( pS
->GetName().getString() == rAttr
.GetName().getString() )
193 // values have to match
194 if( pS
->GetSlotId().GetValue() != rAttr
.GetSlotId().GetValue() )
196 OSL_FAIL( "Same Name in MetaClass : " );
197 OSL_FAIL( pS
->GetName().getString().getStr() );
198 OSL_FAIL( pS
->GetSlotId().getString().getStr() );
199 OSL_FAIL( rAttr
.GetSlotId().getString().getStr() );
201 OStringBuffer
aStr("Attribute's ");
202 aStr
.append(pS
->GetName().getString());
203 aStr
.append(" with different id's");
204 rBase
.SetError(aStr
.makeStringAndClear(), rInStm
.GetToken());
205 rBase
.WriteError( rInStm
);
211 sal_uInt32 nId1
= pS
->GetSlotId().GetValue();
212 sal_uInt32 nId2
= rAttr
.GetSlotId().GetValue();
213 if( nId1
== nId2
&& nId1
!= 0 )
215 OSL_FAIL( "Gleiche Id in MetaClass : " );
216 OSL_FAIL(OString::number(pS
->GetSlotId().GetValue()).getStr());
217 OSL_FAIL( pS
->GetSlotId().getString().getStr() );
218 OSL_FAIL( rAttr
.GetSlotId().getString().getStr() );
220 OStringBuffer
aStr("Attribute ");
221 aStr
.append(pS
->GetName().getString());
222 aStr
.append(" and Attribute ");
223 aStr
.append(rAttr
.GetName().getString());
224 aStr
.append(" with equal id's");
225 rBase
.SetError(aStr
.makeStringAndClear(), rInStm
.GetToken());
226 rBase
.WriteError( rInStm
);
231 SvMetaClass
* pSC
= aSuperClass
;
233 return pSC
->TestAttribute( rBase
, rInStm
, rAttr
);
237 sal_uInt16
SvMetaClass::WriteSlotParamArray( SvIdlDataBase
& rBase
,
238 SvSlotElementList
& rSlotList
,
241 sal_uInt16 nCount
= 0;
242 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
244 SvSlotElement
*pEle
= rSlotList
[ i
];
245 SvMetaSlot
*pAttr
= pEle
->xSlot
;
246 nCount
= nCount
+ pAttr
->WriteSlotParamArray( rBase
, rOutStm
);
252 sal_uInt16
SvMetaClass::WriteSlots( const OString
& rShellName
,
253 sal_uInt16 nCount
, SvSlotElementList
& rSlotList
,
254 SvIdlDataBase
& rBase
,
257 sal_uInt16 nSCount
= 0;
258 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
260 SvSlotElement
* pEle
= rSlotList
[ i
];
261 SvMetaSlot
* pAttr
= pEle
->xSlot
;
262 nSCount
= nSCount
+ pAttr
->WriteSlotMap( rShellName
, nCount
+ nSCount
,
270 void SvMetaClass::InsertSlots( SvSlotElementList
& rList
, std::vector
<sal_uLong
>& rSuperList
,
271 SvMetaClassList
&rClassList
,
272 const OString
& rPrefix
, SvIdlDataBase
& rBase
)
274 // was this class already written?
275 for ( size_t i
= 0, n
= rClassList
.size(); i
< n
; ++i
)
276 if ( rClassList
[ i
] == this )
279 rClassList
.push_back( this );
281 // write all direct attributes
283 for( n
= 0; n
< aAttrList
.size(); n
++ )
285 SvMetaAttribute
* pAttr
= aAttrList
[n
];
287 sal_uLong nId
= pAttr
->GetSlotId().GetValue();
289 std::vector
<sal_uLong
>::iterator iter
= std::find(rSuperList
.begin(),
290 rSuperList
.end(),nId
);
292 if( iter
== rSuperList
.end() )
294 // Write only if not already written by subclass or
295 // imported interface.
296 rSuperList
.push_back(nId
);
297 pAttr
->Insert(rList
, rPrefix
, rBase
);
301 // All Interfaces already imported by SuperShells should not be
303 // It is prohibited that Shell and SuperShell directly import the same
305 if( IsShell() && aSuperClass
.Is() )
306 aSuperClass
->FillClasses( rClassList
);
308 // Write all attributes of the imported classes, as long as they have
309 // not already been imported by the superclass.
310 for( n
= 0; n
< aClassList
.size(); n
++ )
312 SvClassElement
* pEle
= aClassList
[n
];
313 SvMetaClass
* pCl
= pEle
->GetClass();
314 OStringBuffer
rPre(rPrefix
);
315 if( !rPre
.isEmpty() && !pEle
->GetPrefix().isEmpty() )
317 rPre
.append(pEle
->GetPrefix());
319 // first of all write direct imported interfaces
320 pCl
->InsertSlots( rList
, rSuperList
, rClassList
,
321 rPre
.makeStringAndClear(), rBase
);
324 // only write superclass if no shell and not in the list
325 if( !IsShell() && aSuperClass
.Is() )
327 aSuperClass
->InsertSlots( rList
, rSuperList
, rClassList
, rPrefix
, rBase
);
331 void SvMetaClass::FillClasses( SvMetaClassList
& rList
)
334 for ( size_t i
= 0, n
= rList
.size(); i
< n
; ++i
)
335 if ( rList
[ i
] == this )
338 rList
.push_back( this );
341 for( sal_uInt32 n
= 0; n
< aClassList
.size(); n
++ )
343 SvClassElement
* pEle
= aClassList
[n
];
344 SvMetaClass
* pCl
= pEle
->GetClass();
345 pCl
->FillClasses( rList
);
349 if( aSuperClass
.Is() )
350 aSuperClass
->FillClasses( rList
);
354 void SvMetaClass::WriteSlotStubs( const OString
& rShellName
,
355 SvSlotElementList
& rSlotList
,
356 ByteStringList
& rList
,
359 // write all attributes
360 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
362 SvSlotElement
*pEle
= rSlotList
[ i
];
363 SvMetaSlot
*pAttr
= pEle
->xSlot
;
364 pAttr
->WriteSlotStubs( rShellName
, rList
, rOutStm
);
368 void SvMetaClass::WriteSfx( SvIdlDataBase
& rBase
, SvStream
& rOutStm
)
370 WriteStars( rOutStm
);
372 rOutStm
.WriteCharPtr( "#ifdef " ).WriteCharPtr( GetName().getString().getStr() ) << endl
;
373 rOutStm
.WriteCharPtr( "#undef ShellClass" ) << endl
;
374 rOutStm
.WriteCharPtr( "#undef " ).WriteCharPtr( GetName().getString().getStr() ) << endl
;
375 rOutStm
.WriteCharPtr( "#define ShellClass " ).WriteCharPtr( GetName().getString().getStr() ) << endl
;
377 // no slotmaps get written for interfaces
380 rOutStm
.WriteCharPtr( "#endif" ) << endl
<< endl
;
383 // write parameter array
384 rOutStm
.WriteCharPtr("static SfxFormalArgument a").WriteCharPtr(GetName().getString().getStr()).WriteCharPtr("Args_Impl[] =") << endl
;
385 rOutStm
.WriteChar('{') << endl
;
387 std::vector
<sal_uLong
> aSuperList
;
388 SvMetaClassList classList
;
389 SvSlotElementList aSlotList
;
390 InsertSlots(aSlotList
, aSuperList
, classList
, OString(), rBase
);
391 for ( size_t i
= 0, n
= aSlotList
.size(); i
< n
; ++i
)
393 SvSlotElement
*pEle
= aSlotList
[ i
];
394 SvMetaSlot
*pSlot
= pEle
->xSlot
;
395 pSlot
->SetListPos( i
);
398 size_t nSlotCount
= aSlotList
.size();
400 // write all attributes
401 sal_uInt16 nArgCount
= WriteSlotParamArray( rBase
, aSlotList
, rOutStm
);
403 Back2Delemitter( rOutStm
);
406 // at leaast one dummy
407 WriteTab( rOutStm
, 1 );
408 rOutStm
.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl
;
411 rOutStm
.WriteCharPtr( "};" ) << endl
<< endl
;
413 ByteStringList aStringList
;
414 WriteSlotStubs( GetName().getString(), aSlotList
, aStringList
, rOutStm
);
415 for ( size_t i
= 0, n
= aStringList
.size(); i
< n
; ++i
)
416 delete aStringList
[ i
];
422 rOutStm
.WriteCharPtr("static SfxSlot a").WriteCharPtr(GetName().getString().getStr()).WriteCharPtr("Slots_Impl[] =") << endl
;
423 rOutStm
.WriteChar( '{' ) << endl
;
425 // write all attributes
426 WriteSlots( GetName().getString(), 0, aSlotList
, rBase
, rOutStm
);
428 Back2Delemitter( rOutStm
);
431 // at least one dummy
432 WriteTab( rOutStm
, 1 );
433 rOutStm
.WriteCharPtr( "SFX_SLOT_ARG(" ).WriteCharPtr( GetName().getString().getStr() )
434 .WriteCharPtr( ", 0, 0, " )
435 .WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE," )
436 .WriteCharPtr( "SFX_STUB_PTR_STATE_NONE," )
437 .WriteCharPtr( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl
;
440 rOutStm
.WriteCharPtr( "};" ) << endl
;
441 rOutStm
.WriteCharPtr( "#endif" ) << endl
<< endl
;
443 for( size_t i
= 0, n
= aSlotList
.size(); i
< n
; ++i
)
445 SvSlotElement
* pEle
= aSlotList
[ i
];
446 SvMetaSlot
* pAttr
= pEle
->xSlot
;
447 pAttr
->ResetSlotPointer();
450 for( size_t i
= 0, n
= aSlotList
.size(); i
< n
; ++i
)
451 delete aSlotList
[ i
];
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */