summaryrefslogtreecommitdiff
path: root/sot/source/base/object.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sot/source/base/object.cxx')
-rw-r--r--sot/source/base/object.cxx510
1 files changed, 510 insertions, 0 deletions
diff --git a/sot/source/base/object.cxx b/sot/source/base/object.cxx
new file mode 100644
index 000000000000..aa757a6eb364
--- /dev/null
+++ b/sot/source/base/object.cxx
@@ -0,0 +1,510 @@
+/*************************************************************************
+ *
+ * $RCSfile: object.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SOT_OBJECT_CXX
+
+#include <tools/debug.hxx>
+#include <object.hxx>
+#include <factory.hxx>
+#include <agg.hxx>
+#pragma hdrstop
+
+/************** class SvAggregateMemberList *****************************/
+/************************************************************************/
+PRV_SV_IMPL_OWNER_LIST(SvAggregateMemberList,SvAggregate);
+
+/************** class SotObject ******************************************/
+class SotObjectFactory : public SotFactory
+{
+public:
+ TYPEINFO();
+ SotObjectFactory( const SvGlobalName & rName,
+ const String & rClassName,
+ CreateInstanceType pCreateFuncP )
+ : SotFactory( rName, rClassName, pCreateFuncP )
+ {}
+};
+TYPEINIT1(SotObjectFactory,SotFactory);
+
+
+SO2_IMPL_BASIC_CLASS_DLL(SotObject,SotObjectFactory,
+ SvGlobalName( 0xf44b7830, 0xf83c, 0x11d0,
+ 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
+SO2_IMPL_INVARIANT(SotObject)
+
+/*************************************************************************
+|* SotObject::TestMemberObjRef()
+|*
+|* Beschreibung:
+*************************************************************************/
+void SotObject::TestMemberObjRef( BOOL /*bFree*/ )
+{
+}
+
+/*************************************************************************
+|* SotObject::TestMemberObjRef()
+|*
+|* Beschreibung:
+*************************************************************************/
+#ifdef TEST_INVARIANT
+void SotObject::TestMemberInvariant( BOOL /*bPrint*/ )
+{
+}
+#endif
+
+/*************************************************************************
+|* SotObject::SotObject()
+|*
+|* Beschreibung
+*************************************************************************/
+SotObject::SotObject()
+ : nStrongLockCount( 0 )
+ , nOwnerLockCount( 0 )
+ , pAggList ( NULL )
+ , bOwner ( TRUE )
+ , bSVObject ( FALSE )
+ , bInClose ( FALSE )
+{
+ SotFactory::IncSvObjectCount( this );
+}
+
+/*************************************************************************
+|*
+|* SotObject::~SotObject()
+|*
+|* Beschreibung
+|* Ersterstellung MM 05.06.94
+|* Letzte Aenderung MM 05.06.94
+|*
+*************************************************************************/
+SotObject::~SotObject()
+{
+ SotFactory::DecSvObjectCount( this );
+}
+
+/*************************************************************************
+|* SotObject::GetInterface()
+|*
+|* Beschreibung: Um so3 zu helfen
+*************************************************************************/
+IUnknown * SotObject::GetInterface( const SvGlobalName & )
+{
+ return NULL;
+}
+
+/*************************************************************************
+|* SotObject::IsSvClass()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotObject::IsSvObject() const
+{
+ return Owner() || bSVObject;
+}
+
+/*************************************************************************
+|* SotObject::QueryDelete()
+|*
+|* Beschreibung: Bei allen aggregierten Objekte muss der RefCount auf
+|* 0 gehen, damit das Gesammt-Objekt zerstoert wird. Das
+|* zerst”ren von Teilen ist verboten. Da der Aggregator
+|* (oder Cast-Verwalter) den Zaehler der aggregierten
+|* Objekte um 1 erhoeht, muss dies bei der Berechnung
+|* des 0-RefCounts beruecksichtigt werden.
+*************************************************************************/
+BOOL SotObject::ShouldDelete()
+{
+ if( !pAggList )
+ return TRUE;
+
+ SvAggregate & rMO = pAggList->GetObject( 0 );
+ if( rMO.bMainObj )
+ {
+ AddRef();
+ pAggList->GetObject( 0 ).pObj->ReleaseRef();
+ return FALSE;
+ }
+
+ ULONG i;
+ for( i = 1; i < pAggList->Count(); i++ )
+ {
+ SvAggregate & rAgg = pAggList->GetObject( i );
+ // Groesser 1, wegen AddRef() bei AddInterface
+ if( !rAgg.bFactory && rAgg.pObj->GetRefCount() > 1 )
+ {
+ // den eigenen hochzaehelen
+ AddRef();
+ // einen Aggregierten runterzaehlen
+ rAgg.pObj->ReleaseRef();
+ return FALSE;
+ }
+ }
+ AddNextRef(); // rekursion stoppen
+ for( i = pAggList->Count() -1; i > 0; i-- )
+ {
+ // Referenzen aufloesen
+ SvAggregate & rEle = pAggList->GetObject( i );
+ DBG_ASSERT( !rEle.bMainObj, "main object reference is opened" )
+ RemoveInterface( i );
+ }
+ delete pAggList;
+ pAggList = NULL;
+ // und zerstoeren, dies ist unabhaengig vom RefCount
+ return TRUE;
+}
+
+/*************************************************************************
+|* SotObject::QueryDelete()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::QueryDelete()
+{
+ if( ShouldDelete() )
+ SvRefBase::QueryDelete();
+}
+
+
+
+/*************************************************************************
+|* SotObject::GetAggList()
+|*
+|* Beschreibung
+*************************************************************************/
+SvAggregateMemberList & SotObject::GetAggList()
+{
+ if( !pAggList )
+ {
+ pAggList = new SvAggregateMemberList( 2, 1 );
+ pAggList->Append( SvAggregate() );
+ }
+ return *pAggList;
+}
+
+
+/*************************************************************************
+|* SotObject::RemoveInterface()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::RemoveInterface( ULONG nPos )
+{
+ SvAggregate & rAgg = pAggList->GetObject( nPos );
+ if( !rAgg.bFactory )
+ {
+ DBG_ASSERT( rAgg.pObj->pAggList, "no aggregation list" )
+ DBG_ASSERT( rAgg.pObj->pAggList->GetObject( 0 ).pObj == this,
+ "not owner of aggregated object" )
+ // sich selbst als Cast-Verwalter austragen
+ rAgg.pObj->pAggList->GetObject( 0 ) = SvAggregate();
+ // Referenz aufloesen
+ rAgg.pObj->ReleaseRef();
+ // Aus der eigenen List austragen
+ pAggList->Remove( nPos );
+ }
+}
+
+/*************************************************************************
+|* SotObject::RemoveInterface()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::RemoveInterface( SotObject * pObjP )
+{
+ DBG_ASSERT( pObjP, "null pointer" )
+ DBG_ASSERT( pAggList, "no aggregation list" )
+ for( ULONG i = 0; i < pAggList->Count(); i++ )
+ {
+ SvAggregate & rAgg = pAggList->GetObject( i );
+ if( !rAgg.bFactory && pObjP == rAgg.pObj )
+ RemoveInterface( i );
+ }
+ DBG_ASSERT( i < pAggList->Count(), "object not found" )
+}
+
+/*************************************************************************
+|* SotObject::AddInterface()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::AddInterface( SotObject * pObjP )
+{
+ pObjP->AddRef(); // Objekt festhalten
+ GetAggList();
+ pAggList->Append( SvAggregate( pObjP, FALSE ) );
+
+ // sich selbst als Typecast-Verwalter eintragen
+ SvAggregateMemberList & rAList = pObjP->GetAggList();
+ DBG_ASSERT( !rAList.GetObject( 0 ).bMainObj, "try to aggregate twice" )
+ rAList[ 0 ] = SvAggregate( this, TRUE );
+}
+
+/*************************************************************************
+|* SotObject::AddInterface()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::AddInterface( SotFactory * pFactP )
+{
+ GetAggList();
+ pAggList->Append( SvAggregate( pFactP ) );
+}
+
+/*************************************************************************
+|* SotObject::CreateAggObj()
+|*
+|* Beschreibung
+*************************************************************************/
+SotObjectRef SotObject::CreateAggObj( const SotFactory * )
+{
+ return SotObjectRef();
+}
+
+
+/*************************************************************************
+|* SotObject::DownAggCast()
+|*
+|* Beschreibung
+*************************************************************************/
+void * SotObject::DownAggCast( const SotFactory * pFact )
+{
+ void * pCast = NULL;
+ // geht den Pfad nur Richtung aggregierte Objekte
+ if( pAggList )
+ {
+ for( ULONG i = 1; !pCast || i < pAggList->Count(); i++ )
+ {
+ SvAggregate & rAgg = pAggList->GetObject( i );
+ if( rAgg.bFactory )
+ {
+ if( rAgg.pFact->Is( pFact ) )
+ {
+ // On-Demand erzeugen, wenn Typ gebraucht
+ SotObjectRef aObj( CreateAggObj( rAgg.pFact ) );
+ rAgg.bFactory = FALSE;
+ rAgg.pObj = aObj;
+ rAgg.pObj->AddRef();
+
+ // sich selbst als Typecast-Verwalter eintragen
+ SvAggregateMemberList & rAList = rAgg.pObj->GetAggList();
+ DBG_ASSERT( !rAList.GetObject( 0 ).bMainObj, "try to aggregate twice" )
+ rAList[ 0 ] = SvAggregate( this, TRUE );
+ }
+ }
+ if( !rAgg.bFactory )
+ {
+ // muss der (void *) auf Klasse pFact sein
+ pCast = rAgg.pObj->Cast( pFact );
+ if( !pCast )
+ pCast = rAgg.pObj->DownAggCast( pFact );
+ if( pCast )
+ break;
+ }
+ }
+ }
+ return pCast;
+}
+
+/*************************************************************************
+|* SotObject::AggCast()
+|*
+|* Beschreibung
+*************************************************************************/
+void * SotObject::AggCast( const SotFactory * pFact )
+{
+ void * pCast = NULL;
+ if( pAggList )
+ {
+ SvAggregate & rAgg = pAggList->GetObject( 0 );
+ if( rAgg.bMainObj )
+ return rAgg.pObj->AggCast( pFact );
+ pCast = Cast( pFact );
+ if( !pCast )
+ pCast = DownAggCast( pFact );
+ }
+ else
+ pCast = Cast( pFact );
+ return pCast;
+}
+
+/*************************************************************************
+|* SotObject::CastAndAddRef()
+|*
+|* Beschreibung
+*************************************************************************/
+void * SotObject::CastAndAddRef( const SotFactory * pFact )
+{
+ void * pCast = Cast( pFact );
+ if( pCast )
+ AddRef();
+ return pCast;
+}
+
+/*************************************************************************
+|* SotObject::GetMainObj()
+|*
+|* Beschreibung
+*************************************************************************/
+SotObject * SotObject::GetMainObj() const
+{
+ if( pAggList )
+ {
+ if( pAggList->GetObject( 0 ).bMainObj )
+ return pAggList->GetObject( 0 ).pObj->GetMainObj();
+ }
+ return (SotObject *)this;
+}
+
+//=========================================================================
+USHORT SotObject::FuzzyLock
+(
+ BOOL bLock, /* TRUE, lock. FALSE, unlock. */
+ BOOL bIntern, /* TRUE, es handelt sich um einen internen Lock.
+ FALSE, der Lock kam von aussen (Ole2, Ipc2) */
+ BOOL bClose /* TRUE, Close aufrufen wenn letzte Lock */
+)
+/* [Beschreibung]
+
+ Erlaubte Parameterkombinationen:
+ ( TRUE, TRUE, * ) -> interner Lock.
+ ( FALSE, TRUE, TRUE ) -> interner Unlock mit Close,
+ wenn LockCount() == 0
+ ( TRUE, FALSE, * ) -> externer Lock.
+ ( FALSE, FALSE, TRUE ) -> externer Unlock mit Close,
+ wenn LockCount() == 0
+ ( FALSE, FALSE, FALSE ) -> externer Unlock
+
+ F"ur !Owner() wird der Aufruf an das externe Objekt weitergeleitet.
+ F"ur diese muss das <IOleItemContainer>-Interface zur Vef"ugung stehen.
+ bIntern und bClose werden dann ignoriert.
+ Wenn der LockCount auf 0 wechselt, wird <SotObject::DoClose>
+ gerufen, wenn kein OwnerLock besteht.
+
+ [Anmerkung]
+
+*/
+{
+ SotObjectRef xHoldAlive( this );
+ USHORT nRet;
+ if( bLock )
+ {
+ AddRef();
+ nRet = ++nStrongLockCount;
+ }
+ else
+ {
+ nRet = --nStrongLockCount;
+ ReleaseRef();
+ }
+
+ if( !nRet && bClose && !nOwnerLockCount )
+ DoClose();
+ return nRet;
+}
+
+//=========================================================================
+void SotObject::OwnerLock
+(
+ BOOL bLock /* TRUE, lock. FALSE, unlock. */
+)
+/* [Beschreibung]
+
+ Wenn der OwnerLock auf Null dekrementiert, dann wird die Methode
+ DoClose gerufen. Dies geschieht unabh"angig vom Lock. bzw. RefCount.
+ Ist der OwnerLock-Z"ahler != Null, dann wird kein DoClose durch
+ <SotObject::FuzzyLock> gerufen.
+*/
+{
+ if( bLock )
+ {
+ nOwnerLockCount++;
+ AddRef();
+ }
+ else
+ {
+ if( 0 == --nOwnerLockCount )
+ DoClose();
+ ReleaseRef();
+ }
+}
+
+//=========================================================================
+BOOL SotObject::DoClose()
+{
+ BOOL bRet = FALSE;
+ if( !bInClose )
+ {
+ SotObjectRef xHoldAlive( this );
+ bInClose = TRUE;
+ bRet = Close();
+ bInClose = FALSE;
+ }
+ return bRet;
+}
+
+//=========================================================================
+BOOL SotObject::Close()
+{
+ return TRUE;
+}
+
+
+