summaryrefslogtreecommitdiffstats
path: root/idl/source/objects/object.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'idl/source/objects/object.cxx')
-rw-r--r--idl/source/objects/object.cxx347
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: */