Bump version to 24.04.3.4
[LibreOffice.git] / idl / source / objects / object.cxx
blob908ef3d165487b9bc0db0e623caed2e8a91364b2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <algorithm>
24 #include <rtl/strbuf.hxx>
25 #include <sal/log.hxx>
27 #include <object.hxx>
28 #include <globals.hxx>
29 #include <database.hxx>
30 #include <slot.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 );
50 if( !pClass )
51 throw SvParseException( rInStm, "unknown imported interface"_ostr );
52 SvClassElement aEle;
53 aEle.SetClass( pClass );
54 aClassElementList.push_back( aEle );
56 rTok = rInStm.GetToken();
57 if( rTok.IsString() )
59 aEle.SetPrefix( rTok.GetString() );
60 rInStm.GetToken_Next();
62 return;
64 else
66 rInStm.Seek( nTokPos );
67 SvMetaType * pType = rBase.ReadKnownType( rInStm );
69 bool bOk = false;
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 );
77 else
79 xAttr = new SvMetaAttribute( pType );
80 if( xAttr->ReadSvIdl( rBase, rInStm ) )
81 bOk = xAttr->Test( rInStm );
84 if( bOk )
85 bOk = TestAttribute( rBase, rInStm, *xAttr );
86 if( bOk )
88 if( !xAttr->GetSlotId().IsSet() )
90 SvIdentifier aI;
91 aI.SetValue( rBase.GetUniqueId() );
92 xAttr->SetSlotId( aI );
94 aAttrList.push_back( xAttr.get() );
95 return;
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");
119 else
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();
131 if( pSC )
132 return pSC->TestAttribute( rBase, rInStm, rAttr );
133 return true;
136 sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase,
137 SvSlotElementList & rSlotList,
138 SvStream & rOutStm )
140 sal_uInt16 nCount = 0;
141 for ( const auto& pAttr : rSlotList )
143 nCount = nCount + pAttr->WriteSlotParamArray( rBase, rOutStm );
146 return nCount;
149 sal_uInt16 SvMetaClass::WriteSlots( std::string_view rShellName,
150 SvSlotElementList & rSlotList,
151 SvIdlDataBase & rBase,
152 SvStream & rOutStm )
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,
159 rSlotList, i, rBase,
160 rOutStm );
163 return 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() )
172 return;
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
194 // written any more.
195 // It is prohibited that Shell and SuperShell directly import the same
196 // class.
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() )
208 rPre.append('.');
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 )
225 // Am I not yet in?
226 if ( std::find( rClassList.begin(), rClassList.end(), this ) != rClassList.end() )
227 return;
229 rClassList.push_back( this );
231 // my imports
232 for( auto& rElement : aClassElementList )
234 SvMetaClass * pCl = rElement.GetClass();
235 pCl->FillClasses( rClassList );
238 // my superclass
239 if( aSuperClass.is() )
240 aSuperClass->FillClasses( rClassList );
244 void SvMetaClass::WriteSlotStubs( std::string_view rShellName,
245 SvSlotElementList & rSlotList,
246 std::vector<OString> & rList,
247 SvStream & rOutStm )
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 );
259 // define class
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;
269 return;
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 );
289 if( nArgCount )
290 Back2Delimiter( rOutStm );
291 else
293 // at least one dummy
294 WriteTab( rOutStm, 1 );
295 rOutStm.WriteOString("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl;
297 rOutStm << endl;
298 rOutStm.WriteOString( "};" ) << endl << endl;
300 std::vector<OString> aStringList;
301 WriteSlotStubs( GetName(), aSlotList, aStringList, rOutStm );
302 aStringList.clear();
304 rOutStm << endl;
306 // write slotmap
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 );
312 if( nSlotCount )
313 Back2Delimiter( rOutStm );
314 else
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;
324 rOutStm << endl;
325 rOutStm.WriteOString( "};" ) << endl;
326 rOutStm.WriteOString( "#endif" ) << endl << endl;
328 for( auto& pAttr : aSlotList )
330 pAttr->ResetSlotPointer();
333 aSlotList.clear();
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */