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 <sal/config.h>
24 #include <rtl/strbuf.hxx>
25 #include <osl/diagnose.h>
26 #include <sal/log.hxx>
29 #include <globals.hxx>
30 #include <database.hxx>
33 SvClassElement::SvClassElement()
37 SvMetaClass::SvMetaClass()
41 void SvMetaClass::ReadContextSvIdl( SvIdlDataBase
& rBase
,
42 SvTokenStream
& rInStm
)
44 sal_uInt32 nTokPos
= rInStm
.Tell();
45 SvToken
& rTok
= rInStm
.GetToken_Next();
47 if( rTok
.Is( SvHash_import() ) )
49 SvMetaClass
* pClass
= rBase
.ReadKnownClass( rInStm
);
51 throw SvParseException( rInStm
, "unknown imported interface" );
53 aEle
.SetClass( pClass
);
54 aClassElementList
.push_back( aEle
);
56 rTok
= rInStm
.GetToken();
59 aEle
.SetPrefix( rTok
.GetString() );
60 rInStm
.GetToken_Next();
66 rInStm
.Seek( nTokPos
);
67 SvMetaType
* pType
= rBase
.ReadKnownType( rInStm
);
70 tools::SvRef
<SvMetaAttribute
> xAttr
;
71 if( !pType
|| pType
->IsItem() )
73 xAttr
= new SvMetaSlot( pType
);
74 if( xAttr
->ReadSvIdl( rBase
, rInStm
) )
75 bOk
= xAttr
->Test( rInStm
);
79 xAttr
= new SvMetaAttribute( pType
);
80 if( xAttr
->ReadSvIdl( rBase
, rInStm
) )
81 bOk
= xAttr
->Test( rInStm
);
85 bOk
= TestAttribute( rBase
, rInStm
, *xAttr
);
88 if( !xAttr
->GetSlotId().IsSet() )
91 aI
.SetValue( rBase
.GetUniqueId() );
92 xAttr
->SetSlotId( aI
);
94 aAttrList
.push_back( xAttr
.get() );
98 rInStm
.Seek( nTokPos
);
101 bool SvMetaClass::TestAttribute( SvIdlDataBase
& rBase
, SvTokenStream
& rInStm
,
102 SvMetaAttribute
& rAttr
) const
104 if ( !rAttr
.GetRef() && dynamic_cast<const SvMetaSlot
*>(&rAttr
) )
106 SAL_WARN( "idl", "new slot : " << rAttr
.GetSlotId().getString() );
109 for( sal_uLong n
= 0; n
< aAttrList
.size(); n
++ )
111 SvMetaAttribute
* pS
= aAttrList
[n
];
112 if( pS
->GetName() == rAttr
.GetName() )
114 // values have to match
115 if( pS
->GetSlotId().GetValue() != rAttr
.GetSlotId().GetValue() )
117 throw SvParseException( rInStm
, "Attribute's " + pS
->GetName() + " with different id's");
122 sal_uInt32 nId1
= pS
->GetSlotId().GetValue();
123 sal_uInt32 nId2
= rAttr
.GetSlotId().GetValue();
124 if( nId1
== nId2
&& nId1
!= 0 )
126 OString aStr
= "Attribute " + pS
->GetName() + " and Attribute " + rAttr
.GetName() + " with equal id's";
127 throw SvParseException(rInStm
, aStr
);
131 SvMetaClass
* pSC
= aSuperClass
.get();
133 return pSC
->TestAttribute( rBase
, rInStm
, rAttr
);
137 sal_uInt16
SvMetaClass::WriteSlotParamArray( SvIdlDataBase
& rBase
,
138 SvSlotElementList
& rSlotList
,
141 sal_uInt16 nCount
= 0;
142 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
144 SvMetaSlot
*pAttr
= rSlotList
[ i
];
145 nCount
= nCount
+ pAttr
->WriteSlotParamArray( rBase
, rOutStm
);
151 sal_uInt16
SvMetaClass::WriteSlots( const OString
& rShellName
,
152 SvSlotElementList
& rSlotList
,
153 SvIdlDataBase
& rBase
,
156 sal_uInt16 nSCount
= 0;
157 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
159 SvMetaSlot
* pAttr
= rSlotList
[ i
];
160 nSCount
= nSCount
+ pAttr
->WriteSlotMap( rShellName
, nSCount
,
168 void SvMetaClass::InsertSlots( SvSlotElementList
& rList
, std::vector
<sal_uLong
>& rSuperList
,
169 SvMetaClassList
&rClassList
,
170 const OString
& rPrefix
, SvIdlDataBase
& rBase
)
172 // was this class already written?
173 for ( size_t i
= 0, n
= rClassList
.size(); i
< n
; ++i
)
174 if ( rClassList
[ i
] == this )
177 rClassList
.push_back( this );
179 // write all direct attributes
181 for( n
= 0; n
< aAttrList
.size(); n
++ )
183 SvMetaAttribute
* pAttr
= aAttrList
[n
];
185 sal_uLong nId
= pAttr
->GetSlotId().GetValue();
187 std::vector
<sal_uLong
>::iterator iter
= std::find(rSuperList
.begin(),
188 rSuperList
.end(),nId
);
190 if( iter
== rSuperList
.end() )
192 // Write only if not already written by subclass or
193 // imported interface.
194 rSuperList
.push_back(nId
);
195 pAttr
->Insert(rList
);
199 // All Interfaces already imported by SuperShell should not be
201 // It is prohibited that Shell and SuperShell directly import the same
203 if( GetMetaTypeType() == MetaTypeType::Shell
&& aSuperClass
.is() )
204 aSuperClass
->FillClasses( rClassList
);
206 // Write all attributes of the imported classes, as long as they have
207 // not already been imported by the superclass.
208 for( n
= 0; n
< aClassElementList
.size(); n
++ )
210 SvClassElement
& rElement
= aClassElementList
[n
];
211 SvMetaClass
* pCl
= rElement
.GetClass();
212 OStringBuffer
rPre(rPrefix
.getLength() + 1 + rElement
.GetPrefix().getLength());
213 rPre
.append(rPrefix
);
214 if( !rPre
.isEmpty() && !rElement
.GetPrefix().isEmpty() )
216 rPre
.append(rElement
.GetPrefix());
218 // first of all write direct imported interfaces
219 pCl
->InsertSlots( rList
, rSuperList
, rClassList
,
220 rPre
.makeStringAndClear(), rBase
);
223 // only write superclass if no shell and not in the list
224 if( GetMetaTypeType() != MetaTypeType::Shell
&& aSuperClass
.is() )
226 aSuperClass
->InsertSlots( rList
, rSuperList
, rClassList
, rPrefix
, rBase
);
230 void SvMetaClass::FillClasses( SvMetaClassList
& rList
)
233 for ( size_t i
= 0, n
= rList
.size(); i
< n
; ++i
)
234 if ( rList
[ i
] == this )
237 rList
.push_back( this );
240 for( size_t n
= 0; n
< aClassElementList
.size(); n
++ )
242 SvClassElement
& rElement
= aClassElementList
[n
];
243 SvMetaClass
* pCl
= rElement
.GetClass();
244 pCl
->FillClasses( rList
);
248 if( aSuperClass
.is() )
249 aSuperClass
->FillClasses( rList
);
253 void SvMetaClass::WriteSlotStubs( const OString
& rShellName
,
254 SvSlotElementList
& rSlotList
,
255 std::vector
<OString
> & rList
,
258 // write all attributes
259 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
261 SvMetaSlot
*pAttr
= rSlotList
[ i
];
262 pAttr
->WriteSlotStubs( rShellName
, rList
, rOutStm
);
266 void SvMetaClass::WriteSfx( SvIdlDataBase
& rBase
, SvStream
& rOutStm
)
268 WriteStars( rOutStm
);
270 rOutStm
.WriteCharPtr( "#ifdef ShellClass_" ).WriteOString( GetName() ) << endl
;
271 rOutStm
.WriteCharPtr( "#undef ShellClass" ) << endl
;
272 rOutStm
.WriteCharPtr( "#undef ShellClass_" ).WriteOString( GetName() ) << endl
;
273 rOutStm
.WriteCharPtr( "#define ShellClass " ).WriteOString( GetName() ) << endl
;
275 // no slotmaps get written for interfaces
276 if( GetMetaTypeType() != MetaTypeType::Shell
)
278 rOutStm
.WriteCharPtr( "#endif" ) << endl
<< endl
;
281 // write parameter array
282 rOutStm
.WriteCharPtr("static SfxFormalArgument a").WriteOString(GetName()).WriteCharPtr("Args_Impl[] =") << endl
;
283 rOutStm
.WriteChar('{') << endl
;
285 std::vector
<sal_uLong
> aSuperList
;
286 SvMetaClassList classList
;
287 SvSlotElementList aSlotList
;
288 InsertSlots(aSlotList
, aSuperList
, classList
, OString(), rBase
);
289 for ( size_t i
= 0, n
= aSlotList
.size(); i
< n
; ++i
)
291 SvMetaSlot
*pSlot
= aSlotList
[ i
];
292 pSlot
->SetListPos( i
);
295 size_t nSlotCount
= aSlotList
.size();
297 // write all attributes
298 sal_uInt16 nArgCount
= WriteSlotParamArray( rBase
, aSlotList
, rOutStm
);
300 Back2Delimiter( rOutStm
);
303 // at least one dummy
304 WriteTab( rOutStm
, 1 );
305 rOutStm
.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl
;
308 rOutStm
.WriteCharPtr( "};" ) << endl
<< endl
;
310 std::vector
<OString
> aStringList
;
311 WriteSlotStubs( GetName(), aSlotList
, aStringList
, rOutStm
);
317 rOutStm
.WriteCharPtr("static SfxSlot a").WriteOString(GetName()).WriteCharPtr("Slots_Impl[] =") << endl
;
318 rOutStm
.WriteChar( '{' ) << endl
;
320 // write all attributes
321 WriteSlots( GetName(), aSlotList
, rBase
, rOutStm
);
323 Back2Delimiter( rOutStm
);
326 // at least one dummy
327 WriteTab( rOutStm
, 1 );
328 rOutStm
.WriteCharPtr( "SFX_SLOT_ARG(" ).WriteOString( GetName() )
329 .WriteCharPtr( ", 0, SfxGroupId::NONE, " )
330 .WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE," )
331 .WriteCharPtr( "SFX_STUB_PTR_STATE_NONE," )
332 .WriteCharPtr( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl
;
335 rOutStm
.WriteCharPtr( "};" ) << endl
;
336 rOutStm
.WriteCharPtr( "#endif" ) << endl
<< endl
;
338 for( size_t i
= 0, n
= aSlotList
.size(); i
< n
; ++i
)
340 SvMetaSlot
* pAttr
= aSlotList
[ i
];
341 pAttr
->ResetSlotPointer();
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */