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"_ostr
);
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 ( const auto& pAttr
: rSlotList
)
143 nCount
= nCount
+ pAttr
->WriteSlotParamArray( rBase
, rOutStm
);
149 sal_uInt16
SvMetaClass::WriteSlots( std::string_view rShellName
,
150 SvSlotElementList
& rSlotList
,
151 SvIdlDataBase
& rBase
,
154 sal_uInt16 nSCount
= 0;
155 for ( size_t i
= 0, n
= rSlotList
.size(); i
< n
; ++i
)
157 SvMetaSlot
* pAttr
= rSlotList
[ i
];
158 nSCount
= nSCount
+ pAttr
->WriteSlotMap( rShellName
, nSCount
,
166 void SvMetaClass::InsertSlots( SvSlotElementList
& rList
, std::vector
<sal_uInt32
>& rSuperList
,
167 SvMetaClassList
&rClassList
,
168 const OString
& rPrefix
, SvIdlDataBase
& rBase
)
170 // was this class already written?
171 if ( std::find( rClassList
.begin(), rClassList
.end(), this ) != rClassList
.end() )
174 rClassList
.push_back( this );
176 // write all direct attributes
177 for( const auto& pAttr
: aAttrList
)
179 sal_uInt32 nId
= pAttr
->GetSlotId().GetValue();
181 std::vector
<sal_uInt32
>::iterator iter
= std::find(rSuperList
.begin(),
182 rSuperList
.end(),nId
);
184 if( iter
== rSuperList
.end() )
186 // Write only if not already written by subclass or
187 // imported interface.
188 rSuperList
.push_back(nId
);
189 pAttr
->Insert(rList
);
193 // All Interfaces already imported by SuperShell should not be
195 // It is prohibited that Shell and SuperShell directly import the same
197 if( GetMetaTypeType() == MetaTypeType::Shell
&& aSuperClass
.is() )
198 aSuperClass
->FillClasses( rClassList
);
200 // Write all attributes of the imported classes, as long as they have
201 // not already been imported by the superclass.
202 for( auto& rElement
: aClassElementList
)
204 SvMetaClass
* pCl
= rElement
.GetClass();
205 OStringBuffer
rPre(rPrefix
.getLength() + 1 + rElement
.GetPrefix().getLength());
206 rPre
.append(rPrefix
);
207 if( !rPre
.isEmpty() && !rElement
.GetPrefix().isEmpty() )
209 rPre
.append(rElement
.GetPrefix());
211 // first of all write direct imported interfaces
212 pCl
->InsertSlots( rList
, rSuperList
, rClassList
,
213 rPre
.makeStringAndClear(), rBase
);
216 // only write superclass if no shell and not in the list
217 if( GetMetaTypeType() != MetaTypeType::Shell
&& aSuperClass
.is() )
219 aSuperClass
->InsertSlots( rList
, rSuperList
, rClassList
, rPrefix
, rBase
);
223 void SvMetaClass::FillClasses( SvMetaClassList
& rClassList
)
226 if ( std::find( rClassList
.begin(), rClassList
.end(), this ) != rClassList
.end() )
229 rClassList
.push_back( this );
232 for( auto& rElement
: aClassElementList
)
234 SvMetaClass
* pCl
= rElement
.GetClass();
235 pCl
->FillClasses( rClassList
);
239 if( aSuperClass
.is() )
240 aSuperClass
->FillClasses( rClassList
);
244 void SvMetaClass::WriteSlotStubs( std::string_view rShellName
,
245 SvSlotElementList
& rSlotList
,
246 std::vector
<OString
> & rList
,
249 // write all attributes
250 for ( const auto& pAttr
: rSlotList
)
252 pAttr
->WriteSlotStubs( rShellName
, rList
, rOutStm
);
256 void SvMetaClass::WriteSfx( SvIdlDataBase
& rBase
, SvStream
& rOutStm
)
258 WriteStars( rOutStm
);
260 rOutStm
.WriteOString( "#ifdef ShellClass_" ).WriteOString( GetName() ) << endl
;
261 rOutStm
.WriteOString( "#undef ShellClass" ) << endl
;
262 rOutStm
.WriteOString( "#undef ShellClass_" ).WriteOString( GetName() ) << endl
;
263 rOutStm
.WriteOString( "#define ShellClass " ).WriteOString( GetName() ) << endl
;
265 // no slotmaps get written for interfaces
266 if( GetMetaTypeType() != MetaTypeType::Shell
)
268 rOutStm
.WriteOString( "#endif" ) << endl
<< endl
;
271 // write parameter array
272 rOutStm
.WriteOString("static SfxFormalArgument a").WriteOString(GetName()).WriteOString("Args_Impl[] =") << endl
;
273 rOutStm
.WriteChar('{') << endl
;
275 std::vector
<sal_uInt32
> aSuperList
;
276 SvMetaClassList classList
;
277 SvSlotElementList aSlotList
;
278 InsertSlots(aSlotList
, aSuperList
, classList
, OString(), rBase
);
279 for ( size_t i
= 0, n
= aSlotList
.size(); i
< n
; ++i
)
281 SvMetaSlot
*pSlot
= aSlotList
[ i
];
282 pSlot
->SetListPos( i
);
285 size_t nSlotCount
= aSlotList
.size();
287 // write all attributes
288 sal_uInt16 nArgCount
= WriteSlotParamArray( rBase
, aSlotList
, rOutStm
);
290 Back2Delimiter( rOutStm
);
293 // at least one dummy
294 WriteTab( rOutStm
, 1 );
295 rOutStm
.WriteOString("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl
;
298 rOutStm
.WriteOString( "};" ) << endl
<< endl
;
300 std::vector
<OString
> aStringList
;
301 WriteSlotStubs( GetName(), aSlotList
, aStringList
, rOutStm
);
307 rOutStm
.WriteOString("static SfxSlot a").WriteOString(GetName()).WriteOString("Slots_Impl[] =") << endl
;
308 rOutStm
.WriteChar( '{' ) << endl
;
310 // write all attributes
311 WriteSlots( GetName(), aSlotList
, rBase
, rOutStm
);
313 Back2Delimiter( rOutStm
);
316 // at least one dummy
317 WriteTab( rOutStm
, 1 );
318 rOutStm
.WriteOString( "SFX_SLOT_ARG(" ).WriteOString( GetName() )
319 .WriteOString( ", 0, SfxGroupId::NONE, " )
320 .WriteOString( "SFX_STUB_PTR_EXEC_NONE," )
321 .WriteOString( "SFX_STUB_PTR_STATE_NONE," )
322 .WriteOString( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl
;
325 rOutStm
.WriteOString( "};" ) << endl
;
326 rOutStm
.WriteOString( "#endif" ) << endl
<< endl
;
328 for( auto& pAttr
: aSlotList
)
330 pAttr
->ResetSlotPointer();
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */