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 <sal/log.hxx>
28 #include <globals.hxx>
29 #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( const auto &pS
: aAttrList
)
111 if( pS
->GetName() == rAttr
.GetName() )
113 // values have to match
114 if( pS
->GetSlotId().GetValue() != rAttr
.GetSlotId().GetValue() )
116 throw SvParseException( rInStm
, "Attribute's " + pS
->GetName() + " with different id's");
121 sal_uInt32 nId1
= pS
->GetSlotId().GetValue();
122 sal_uInt32 nId2
= rAttr
.GetSlotId().GetValue();
123 if( nId1
== nId2
&& nId1
!= 0 )
125 OString aStr
= "Attribute " + pS
->GetName() + " and Attribute " + rAttr
.GetName() + " with equal id's";
126 throw SvParseException(rInStm
, aStr
);
130 SvMetaClass
* pSC
= aSuperClass
.get();
132 return pSC
->TestAttribute( rBase
, rInStm
, rAttr
);
136 sal_uInt16
SvMetaClass::WriteSlotParamArray( SvIdlDataBase
& rBase
,
137 SvSlotElementList
& rSlotList
,
140 sal_uInt16 nCount
= 0;
141 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
143 SvMetaSlot
*pAttr
= rSlotList
[ i
];
144 nCount
= nCount
+ pAttr
->WriteSlotParamArray( rBase
, rOutStm
);
150 sal_uInt16
SvMetaClass::WriteSlots( std::string_view rShellName
,
151 SvSlotElementList
& rSlotList
,
152 SvIdlDataBase
& rBase
,
155 sal_uInt16 nSCount
= 0;
156 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
158 SvMetaSlot
* pAttr
= rSlotList
[ i
];
159 nSCount
= nSCount
+ pAttr
->WriteSlotMap( rShellName
, nSCount
,
167 void SvMetaClass::InsertSlots( SvSlotElementList
& rList
, std::vector
<sal_uInt32
>& rSuperList
,
168 SvMetaClassList
&rClassList
,
169 const OString
& rPrefix
, SvIdlDataBase
& rBase
)
171 // was this class already written?
172 for ( size_t i
= 0, n
= rClassList
.size(); i
< n
; ++i
)
173 if ( rClassList
[ i
] == this )
176 rClassList
.push_back( this );
178 // write all direct attributes
180 for( n
= 0; n
< aAttrList
.size(); n
++ )
182 SvMetaAttribute
* pAttr
= aAttrList
[n
];
184 sal_uInt32 nId
= pAttr
->GetSlotId().GetValue();
186 std::vector
<sal_uInt32
>::iterator iter
= std::find(rSuperList
.begin(),
187 rSuperList
.end(),nId
);
189 if( iter
== rSuperList
.end() )
191 // Write only if not already written by subclass or
192 // imported interface.
193 rSuperList
.push_back(nId
);
194 pAttr
->Insert(rList
);
198 // All Interfaces already imported by SuperShell should not be
200 // It is prohibited that Shell and SuperShell directly import the same
202 if( GetMetaTypeType() == MetaTypeType::Shell
&& aSuperClass
.is() )
203 aSuperClass
->FillClasses( rClassList
);
205 // Write all attributes of the imported classes, as long as they have
206 // not already been imported by the superclass.
207 for( n
= 0; n
< aClassElementList
.size(); n
++ )
209 SvClassElement
& rElement
= aClassElementList
[n
];
210 SvMetaClass
* pCl
= rElement
.GetClass();
211 OStringBuffer
rPre(rPrefix
.getLength() + 1 + rElement
.GetPrefix().getLength());
212 rPre
.append(rPrefix
);
213 if( !rPre
.isEmpty() && !rElement
.GetPrefix().isEmpty() )
215 rPre
.append(rElement
.GetPrefix());
217 // first of all write direct imported interfaces
218 pCl
->InsertSlots( rList
, rSuperList
, rClassList
,
219 rPre
.makeStringAndClear(), rBase
);
222 // only write superclass if no shell and not in the list
223 if( GetMetaTypeType() != MetaTypeType::Shell
&& aSuperClass
.is() )
225 aSuperClass
->InsertSlots( rList
, rSuperList
, rClassList
, rPrefix
, rBase
);
229 void SvMetaClass::FillClasses( SvMetaClassList
& rList
)
232 for ( size_t i
= 0, n
= rList
.size(); i
< n
; ++i
)
233 if ( rList
[ i
] == this )
236 rList
.push_back( this );
239 for( size_t n
= 0; n
< aClassElementList
.size(); n
++ )
241 SvClassElement
& rElement
= aClassElementList
[n
];
242 SvMetaClass
* pCl
= rElement
.GetClass();
243 pCl
->FillClasses( rList
);
247 if( aSuperClass
.is() )
248 aSuperClass
->FillClasses( rList
);
252 void SvMetaClass::WriteSlotStubs( std::string_view rShellName
,
253 SvSlotElementList
& rSlotList
,
254 std::vector
<OString
> & rList
,
257 // write all attributes
258 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
260 SvMetaSlot
*pAttr
= rSlotList
[ i
];
261 pAttr
->WriteSlotStubs( rShellName
, rList
, rOutStm
);
265 void SvMetaClass::WriteSfx( SvIdlDataBase
& rBase
, SvStream
& rOutStm
)
267 WriteStars( rOutStm
);
269 rOutStm
.WriteOString( "#ifdef ShellClass_" ).WriteOString( GetName() ) << endl
;
270 rOutStm
.WriteOString( "#undef ShellClass" ) << endl
;
271 rOutStm
.WriteOString( "#undef ShellClass_" ).WriteOString( GetName() ) << endl
;
272 rOutStm
.WriteOString( "#define ShellClass " ).WriteOString( GetName() ) << endl
;
274 // no slotmaps get written for interfaces
275 if( GetMetaTypeType() != MetaTypeType::Shell
)
277 rOutStm
.WriteOString( "#endif" ) << endl
<< endl
;
280 // write parameter array
281 rOutStm
.WriteOString("static SfxFormalArgument a").WriteOString(GetName()).WriteOString("Args_Impl[] =") << endl
;
282 rOutStm
.WriteChar('{') << endl
;
284 std::vector
<sal_uInt32
> aSuperList
;
285 SvMetaClassList classList
;
286 SvSlotElementList aSlotList
;
287 InsertSlots(aSlotList
, aSuperList
, classList
, OString(), rBase
);
288 for ( size_t i
= 0, n
= aSlotList
.size(); i
< n
; ++i
)
290 SvMetaSlot
*pSlot
= aSlotList
[ i
];
291 pSlot
->SetListPos( i
);
294 size_t nSlotCount
= aSlotList
.size();
296 // write all attributes
297 sal_uInt16 nArgCount
= WriteSlotParamArray( rBase
, aSlotList
, rOutStm
);
299 Back2Delimiter( rOutStm
);
302 // at least one dummy
303 WriteTab( rOutStm
, 1 );
304 rOutStm
.WriteOString("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl
;
307 rOutStm
.WriteOString( "};" ) << endl
<< endl
;
309 std::vector
<OString
> aStringList
;
310 WriteSlotStubs( GetName(), aSlotList
, aStringList
, rOutStm
);
316 rOutStm
.WriteOString("static SfxSlot a").WriteOString(GetName()).WriteOString("Slots_Impl[] =") << endl
;
317 rOutStm
.WriteChar( '{' ) << endl
;
319 // write all attributes
320 WriteSlots( GetName(), aSlotList
, rBase
, rOutStm
);
322 Back2Delimiter( rOutStm
);
325 // at least one dummy
326 WriteTab( rOutStm
, 1 );
327 rOutStm
.WriteOString( "SFX_SLOT_ARG(" ).WriteOString( GetName() )
328 .WriteOString( ", 0, SfxGroupId::NONE, " )
329 .WriteOString( "SFX_STUB_PTR_EXEC_NONE," )
330 .WriteOString( "SFX_STUB_PTR_STATE_NONE," )
331 .WriteOString( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl
;
334 rOutStm
.WriteOString( "};" ) << endl
;
335 rOutStm
.WriteOString( "#endif" ) << endl
<< endl
;
337 for( size_t i
= 0, n
= aSlotList
.size(); i
< n
; ++i
)
339 SvMetaSlot
* pAttr
= aSlotList
[ i
];
340 pAttr
->ResetSlotPointer();
346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */