diff options
Diffstat (limited to 'idl/source/objects/object.cxx')
-rw-r--r-- | idl/source/objects/object.cxx | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/idl/source/objects/object.cxx b/idl/source/objects/object.cxx new file mode 100644 index 000000000..a424bb748 --- /dev/null +++ b/idl/source/objects/object.cxx @@ -0,0 +1,347 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <algorithm> + +#include <rtl/strbuf.hxx> +#include <osl/diagnose.h> +#include <sal/log.hxx> + +#include <object.hxx> +#include <globals.hxx> +#include <database.hxx> + + +SvClassElement::SvClassElement() +{ +}; + +SvMetaClass::SvMetaClass() +{ +} + +void SvMetaClass::ReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( SvHash_import() ) ) + { + SvMetaClass * pClass = rBase.ReadKnownClass( rInStm ); + if( !pClass ) + throw SvParseException( rInStm, "unknown imported interface" ); + SvClassElement aEle; + aEle.SetClass( pClass ); + aClassElementList.push_back( aEle ); + + rTok = rInStm.GetToken(); + if( rTok.IsString() ) + { + aEle.SetPrefix( rTok.GetString() ); + rInStm.GetToken_Next(); + } + return; + } + else + { + rInStm.Seek( nTokPos ); + SvMetaType * pType = rBase.ReadKnownType( rInStm ); + + bool bOk = false; + tools::SvRef<SvMetaAttribute> xAttr; + if( !pType || pType->IsItem() ) + { + xAttr = new SvMetaSlot( pType ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + bOk = xAttr->Test( rInStm ); + } + else + { + xAttr = new SvMetaAttribute( pType ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + bOk = xAttr->Test( rInStm ); + } + + if( bOk ) + bOk = TestAttribute( rBase, rInStm, *xAttr ); + if( bOk ) + { + if( !xAttr->GetSlotId().IsSet() ) + { + SvIdentifier aI; + aI.SetValue( rBase.GetUniqueId() ); + xAttr->SetSlotId( aI ); + } + aAttrList.push_back( xAttr.get() ); + return; + } + } + rInStm.Seek( nTokPos ); +} + +bool SvMetaClass::TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm, + SvMetaAttribute & rAttr ) const +{ + if ( !rAttr.GetRef() && dynamic_cast<const SvMetaSlot *>(&rAttr) ) + { + SAL_WARN( "idl", "new slot : " << rAttr.GetSlotId().getString() ); + } + + for( sal_uLong n = 0; n < aAttrList.size(); n++ ) + { + SvMetaAttribute * pS = aAttrList[n]; + if( pS->GetName() == rAttr.GetName() ) + { + // values have to match + if( pS->GetSlotId().GetValue() != rAttr.GetSlotId().GetValue() ) + { + throw SvParseException( rInStm, "Attribute's " + pS->GetName() + " with different id's"); + } + } + else + { + sal_uInt32 nId1 = pS->GetSlotId().GetValue(); + sal_uInt32 nId2 = rAttr.GetSlotId().GetValue(); + if( nId1 == nId2 && nId1 != 0 ) + { + OString aStr = "Attribute " + pS->GetName() + " and Attribute " + rAttr.GetName() + " with equal id's"; + throw SvParseException(rInStm, aStr); + } + } + } + SvMetaClass * pSC = aSuperClass.get(); + if( pSC ) + return pSC->TestAttribute( rBase, rInStm, rAttr ); + return true; +} + +sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase, + SvSlotElementList & rSlotList, + SvStream & rOutStm ) +{ + sal_uInt16 nCount = 0; + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pAttr = rSlotList[ i ]; + nCount = nCount + pAttr->WriteSlotParamArray( rBase, rOutStm ); + } + + return nCount; +} + +sal_uInt16 SvMetaClass::WriteSlots( const OString& rShellName, + SvSlotElementList & rSlotList, + SvIdlDataBase & rBase, + SvStream & rOutStm ) +{ + sal_uInt16 nSCount = 0; + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot * pAttr = rSlotList[ i ]; + nSCount = nSCount + pAttr->WriteSlotMap( rShellName, nSCount, + rSlotList, i, rBase, + rOutStm ); + } + + return nSCount; +} + +void SvMetaClass::InsertSlots( SvSlotElementList& rList, std::vector<sal_uLong>& rSuperList, + SvMetaClassList &rClassList, + const OString& rPrefix, SvIdlDataBase& rBase) +{ + // was this class already written? + for ( size_t i = 0, n = rClassList.size(); i < n ; ++i ) + if ( rClassList[ i ] == this ) + return; + + rClassList.push_back( this ); + + // write all direct attributes + sal_uLong n; + for( n = 0; n < aAttrList.size(); n++ ) + { + SvMetaAttribute * pAttr = aAttrList[n]; + + sal_uLong nId = pAttr->GetSlotId().GetValue(); + + std::vector<sal_uLong>::iterator iter = std::find(rSuperList.begin(), + rSuperList.end(),nId); + + if( iter == rSuperList.end() ) + { + // Write only if not already written by subclass or + // imported interface. + rSuperList.push_back(nId); + pAttr->Insert(rList); + } + } + + // All Interfaces already imported by SuperShell should not be + // written any more. + // It is prohibited that Shell and SuperShell directly import the same + // class. + if( GetMetaTypeType() == MetaTypeType::Shell && aSuperClass.is() ) + aSuperClass->FillClasses( rClassList ); + + // Write all attributes of the imported classes, as long as they have + // not already been imported by the superclass. + for( n = 0; n < aClassElementList.size(); n++ ) + { + SvClassElement& rElement = aClassElementList[n]; + SvMetaClass * pCl = rElement.GetClass(); + OStringBuffer rPre(rPrefix.getLength() + 1 + rElement.GetPrefix().getLength()); + rPre.append(rPrefix); + if( !rPre.isEmpty() && !rElement.GetPrefix().isEmpty() ) + rPre.append('.'); + rPre.append(rElement.GetPrefix()); + + // first of all write direct imported interfaces + pCl->InsertSlots( rList, rSuperList, rClassList, + rPre.makeStringAndClear(), rBase ); + } + + // only write superclass if no shell and not in the list + if( GetMetaTypeType() != MetaTypeType::Shell && aSuperClass.is() ) + { + aSuperClass->InsertSlots( rList, rSuperList, rClassList, rPrefix, rBase ); + } +} + +void SvMetaClass::FillClasses( SvMetaClassList & rList ) +{ + // Am I not yet in? + for ( size_t i = 0, n = rList.size(); i < n; ++i ) + if ( rList[ i ] == this ) + return; + + rList.push_back( this ); + + // my imports + for( size_t n = 0; n < aClassElementList.size(); n++ ) + { + SvClassElement& rElement = aClassElementList[n]; + SvMetaClass * pCl = rElement.GetClass(); + pCl->FillClasses( rList ); + } + + // my superclass + if( aSuperClass.is() ) + aSuperClass->FillClasses( rList ); +} + + +void SvMetaClass::WriteSlotStubs( const OString& rShellName, + SvSlotElementList & rSlotList, + std::vector<OString> & rList, + SvStream & rOutStm ) +{ + // write all attributes + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pAttr = rSlotList[ i ]; + pAttr->WriteSlotStubs( rShellName, rList, rOutStm ); + } +} + +void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + WriteStars( rOutStm ); + // define class + rOutStm.WriteCharPtr( "#ifdef ShellClass_" ).WriteOString( GetName() ) << endl; + rOutStm.WriteCharPtr( "#undef ShellClass" ) << endl; + rOutStm.WriteCharPtr( "#undef ShellClass_" ).WriteOString( GetName() ) << endl; + rOutStm.WriteCharPtr( "#define ShellClass " ).WriteOString( GetName() ) << endl; + + // no slotmaps get written for interfaces + if( GetMetaTypeType() != MetaTypeType::Shell ) + { + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; + return; + } + // write parameter array + rOutStm.WriteCharPtr("static SfxFormalArgument a").WriteOString(GetName()).WriteCharPtr("Args_Impl[] =") << endl; + rOutStm.WriteChar('{') << endl; + + std::vector<sal_uLong> aSuperList; + SvMetaClassList classList; + SvSlotElementList aSlotList; + InsertSlots(aSlotList, aSuperList, classList, OString(), rBase); + for ( size_t i = 0, n = aSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pSlot = aSlotList[ i ]; + pSlot->SetListPos( i ); + } + + size_t nSlotCount = aSlotList.size(); + + // write all attributes + sal_uInt16 nArgCount = WriteSlotParamArray( rBase, aSlotList, rOutStm ); + if( nArgCount ) + Back2Delimiter( rOutStm ); + else + { + // at least one dummy + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl; + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl << endl; + + std::vector<OString> aStringList; + WriteSlotStubs( GetName(), aSlotList, aStringList, rOutStm ); + aStringList.clear(); + + rOutStm << endl; + + // write slotmap + rOutStm.WriteCharPtr("static SfxSlot a").WriteOString(GetName()).WriteCharPtr("Slots_Impl[] =") << endl; + rOutStm.WriteChar( '{' ) << endl; + + // write all attributes + WriteSlots( GetName(), aSlotList, rBase, rOutStm ); + if( nSlotCount ) + Back2Delimiter( rOutStm ); + else + { + // at least one dummy + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr( "SFX_SLOT_ARG(" ).WriteOString( GetName() ) + .WriteCharPtr( ", 0, SfxGroupId::NONE, " ) + .WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE," ) + .WriteCharPtr( "SFX_STUB_PTR_STATE_NONE," ) + .WriteCharPtr( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl; + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; + + for( size_t i = 0, n = aSlotList.size(); i < n; ++i ) + { + SvMetaSlot* pAttr = aSlotList[ i ]; + pAttr->ResetSlotPointer(); + } + + aSlotList.clear(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |