bump product version to 5.0.4.1
[LibreOffice.git] / idl / source / objects / object.cxx
blob320faa9d3ffe383250fd3f8b245f9ce2dcda1859
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 .
21 #include <ctype.h>
22 #include <stdio.h>
24 #include <rtl/strbuf.hxx>
25 #include <osl/diagnose.h>
27 #include <object.hxx>
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 );
59 if( pClass )
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() )
74 // set error
75 rBase.SetError( "Automation already set",
76 rInStm.GetToken() );
77 rBase.WriteError( rInStm );
79 xAutomationInterface = pClass;
80 xEle->SetAutomation( true );
82 else
84 // set error
85 rBase.SetError( "missing ]", rInStm.GetToken() );
86 rBase.WriteError( rInStm );
89 else
91 // set error
92 rBase.SetError( "only attribute Automation allowed",
93 rInStm.GetToken() );
94 rBase.WriteError( rInStm );
97 pTok = rInStm.GetToken();
98 if( pTok->IsString() )
100 xEle->SetPrefix( pTok->GetString() );
101 rInStm.GetToken_Next();
103 return;
105 else
107 // set error
108 rBase.SetError( "unknown imported interface", rInStm.GetToken() );
109 rBase.WriteError( rInStm );
112 else
114 rInStm.Seek( nTokPos );
115 SvMetaType * pType = rBase.ReadKnownType( rInStm );
117 bool bOk = false;
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 );
125 else
127 xAttr = new SvMetaAttribute( pType );
128 if( xAttr->ReadSvIdl( rBase, rInStm ) )
129 bOk = xAttr->Test( rBase, rInStm );
132 if( bOk )
133 bOk = TestAttribute( rBase, rInStm, *xAttr );
134 if( bOk )
136 if( !xAttr->GetSlotId().IsSet() )
138 SvNumberIdentifier aI;
139 aI.SetValue( rBase.GetUniqueId() );
140 xAttr->SetSlotId( aI );
142 aAttrList.push_back( xAttr );
143 return;
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 )
154 bool bOk = true;
155 if( rInStm.Read( ':' ) )
157 aSuperClass = rBase.ReadKnownClass( rInStm );
158 bOk = aSuperClass.Is();
159 if( !bOk )
161 // set error
162 rBase.SetError( "unknown super class",
163 rInStm.GetToken() );
164 rBase.WriteError( rInStm );
167 if( bOk )
169 rBase.Write(OString('.'));
170 bOk = SvMetaName::ReadSvIdl( rBase, rInStm );
172 if( bOk )
173 return bOk;
175 rInStm.Seek( nTokPos );
176 return false;
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 );
206 return false;
209 else
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 );
227 return false;
231 SvMetaClass * pSC = aSuperClass;
232 if( pSC )
233 return pSC->TestAttribute( rBase, rInStm, rAttr );
234 return true;
237 sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase,
238 SvSlotElementList & rSlotList,
239 SvStream & rOutStm )
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 );
249 return nCount;
252 sal_uInt16 SvMetaClass::WriteSlots( const OString& rShellName,
253 sal_uInt16 nCount, SvSlotElementList & rSlotList,
254 SvIdlDataBase & rBase,
255 SvStream & rOutStm )
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,
263 rSlotList, i, rBase,
264 rOutStm );
267 return 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 )
277 return;
279 rClassList.push_back( this );
281 // write all direct attributes
282 sal_uLong n;
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
302 // written any more.
303 // It is prohibited that Shell and SuperShell directly import the same
304 //class.
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() )
316 rPre.append('.');
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 )
333 // Am I not yet in?
334 for ( size_t i = 0, n = rList.size(); i < n; ++i )
335 if ( rList[ i ] == this )
336 return;
338 rList.push_back( this );
340 // my imports
341 for( sal_uInt32 n = 0; n < aClassList.size(); n++ )
343 SvClassElement * pEle = aClassList[n];
344 SvMetaClass * pCl = pEle->GetClass();
345 pCl->FillClasses( rList );
348 // my superclass
349 if( aSuperClass.Is() )
350 aSuperClass->FillClasses( rList );
354 void SvMetaClass::WriteSlotStubs( const OString& rShellName,
355 SvSlotElementList & rSlotList,
356 ByteStringList & rList,
357 SvStream & rOutStm )
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 );
371 // define class
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
378 if( !IsShell() )
380 rOutStm.WriteCharPtr( "#endif" ) << endl << endl;
381 return;
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 );
402 if( nArgCount )
403 Back2Delemitter( rOutStm );
404 else
406 // at leaast one dummy
407 WriteTab( rOutStm, 1 );
408 rOutStm.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl;
410 rOutStm << 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 ];
417 aStringList.clear();
419 rOutStm << endl;
421 // write slotmap
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 );
427 if( nSlotCount )
428 Back2Delemitter( rOutStm );
429 else
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;
439 rOutStm << 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 ];
452 aSlotList.clear();
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */