update dev300-m58
[ooovba.git] / sot / source / base / object.cxx
blob68a5e1bdda6d28196a6974a1c971fc9eb8e2b52b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: object.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sot.hxx"
34 #define _SOT_OBJECT_CXX
36 #include <tools/debug.hxx>
37 #include <sot/object.hxx>
38 #include <sot/factory.hxx>
39 #include <agg.hxx>
41 /************** class SvAggregateMemberList *****************************/
42 /************************************************************************/
43 PRV_SV_IMPL_OWNER_LIST(SvAggregateMemberList,SvAggregate);
45 /************** class SotObject ******************************************/
46 class SotObjectFactory : public SotFactory
48 public:
49 TYPEINFO();
50 SotObjectFactory( const SvGlobalName & rName,
51 const String & rClassName,
52 CreateInstanceType pCreateFuncP )
53 : SotFactory( rName, rClassName, pCreateFuncP )
56 TYPEINIT1(SotObjectFactory,SotFactory);
59 SO2_IMPL_BASIC_CLASS_DLL(SotObject,SotObjectFactory,
60 SvGlobalName( 0xf44b7830, 0xf83c, 0x11d0,
61 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
62 SO2_IMPL_INVARIANT(SotObject)
64 /*************************************************************************
65 |* SotObject::TestMemberObjRef()
67 |* Beschreibung:
68 *************************************************************************/
69 void SotObject::TestMemberObjRef( BOOL /*bFree*/ )
73 /*************************************************************************
74 |* SotObject::TestMemberObjRef()
76 |* Beschreibung:
77 *************************************************************************/
78 #ifdef TEST_INVARIANT
79 void SotObject::TestMemberInvariant( BOOL /*bPrint*/ )
82 #endif
84 /*************************************************************************
85 |* SotObject::SotObject()
87 |* Beschreibung
88 *************************************************************************/
89 SotObject::SotObject()
90 : pAggList ( NULL )
91 , nStrongLockCount( 0 )
92 , nOwnerLockCount( 0 )
93 , bOwner ( TRUE )
94 , bSVObject ( FALSE )
95 , bInClose ( FALSE )
97 SotFactory::IncSvObjectCount( this );
100 /*************************************************************************
102 |* SotObject::~SotObject()
104 |* Beschreibung
105 |* Ersterstellung MM 05.06.94
106 |* Letzte Aenderung MM 05.06.94
108 *************************************************************************/
109 SotObject::~SotObject()
111 SotFactory::DecSvObjectCount( this );
114 /*************************************************************************
115 |* SotObject::GetInterface()
117 |* Beschreibung: Um so3 zu helfen
118 *************************************************************************/
119 IUnknown * SotObject::GetInterface( const SvGlobalName & )
121 return NULL;
124 /*************************************************************************
125 |* SotObject::IsSvClass()
127 |* Beschreibung
128 *************************************************************************/
129 BOOL SotObject::IsSvObject() const
131 return Owner() || bSVObject;
134 /*************************************************************************
135 |* SotObject::QueryDelete()
137 |* Beschreibung: Bei allen aggregierten Objekte muss der RefCount auf
138 |* 0 gehen, damit das Gesammt-Objekt zerstoert wird. Das
139 |* zerst�ren von Teilen ist verboten. Da der Aggregator
140 |* (oder Cast-Verwalter) den Zaehler der aggregierten
141 |* Objekte um 1 erhoeht, muss dies bei der Berechnung
142 |* des 0-RefCounts beruecksichtigt werden.
143 *************************************************************************/
144 BOOL SotObject::ShouldDelete()
146 if( !pAggList )
147 return TRUE;
149 SvAggregate & rMO = pAggList->GetObject( 0 );
150 if( rMO.bMainObj )
152 AddRef();
153 pAggList->GetObject( 0 ).pObj->ReleaseRef();
154 return FALSE;
157 ULONG i;
158 for( i = 1; i < pAggList->Count(); i++ )
160 SvAggregate & rAgg = pAggList->GetObject( i );
161 // Groesser 1, wegen AddRef() bei AddInterface
162 if( !rAgg.bFactory && rAgg.pObj->GetRefCount() > 1 )
164 // den eigenen hochzaehelen
165 AddRef();
166 // einen Aggregierten runterzaehlen
167 rAgg.pObj->ReleaseRef();
168 return FALSE;
171 AddNextRef(); // rekursion stoppen
172 for( i = pAggList->Count() -1; i > 0; i-- )
174 // Referenzen aufloesen
175 DBG_ASSERT( !pAggList->GetObject( i ).bMainObj, "main object reference is opened" );
176 RemoveInterface( i );
178 delete pAggList;
179 pAggList = NULL;
180 // und zerstoeren, dies ist unabhaengig vom RefCount
181 return TRUE;
184 /*************************************************************************
185 |* SotObject::QueryDelete()
187 |* Beschreibung
188 *************************************************************************/
189 void SotObject::QueryDelete()
191 if( ShouldDelete() )
192 SvRefBase::QueryDelete();
197 /*************************************************************************
198 |* SotObject::GetAggList()
200 |* Beschreibung
201 *************************************************************************/
202 SvAggregateMemberList & SotObject::GetAggList()
204 if( !pAggList )
206 pAggList = new SvAggregateMemberList( 2, 1 );
207 pAggList->Append( SvAggregate() );
209 return *pAggList;
213 /*************************************************************************
214 |* SotObject::RemoveInterface()
216 |* Beschreibung
217 *************************************************************************/
218 void SotObject::RemoveInterface( ULONG nPos )
220 SvAggregate & rAgg = pAggList->GetObject( nPos );
221 if( !rAgg.bFactory )
223 DBG_ASSERT( rAgg.pObj->pAggList, "no aggregation list" );
224 DBG_ASSERT( rAgg.pObj->pAggList->GetObject( 0 ).pObj == this,
225 "not owner of aggregated object" );
226 // sich selbst als Cast-Verwalter austragen
227 rAgg.pObj->pAggList->GetObject( 0 ) = SvAggregate();
228 // Referenz aufloesen
229 rAgg.pObj->ReleaseRef();
230 // Aus der eigenen List austragen
231 pAggList->Remove( nPos );
235 /*************************************************************************
236 |* SotObject::RemoveInterface()
238 |* Beschreibung
239 *************************************************************************/
240 void SotObject::RemoveInterface( SotObject * pObjP )
242 DBG_ASSERT( pObjP, "null pointer" );
243 DBG_ASSERT( pAggList, "no aggregation list" );
244 ULONG i;
245 for( i = 0; i < pAggList->Count(); i++ )
247 SvAggregate & rAgg = pAggList->GetObject( i );
248 if( !rAgg.bFactory && pObjP == rAgg.pObj )
249 RemoveInterface( i );
251 DBG_ASSERT( i < pAggList->Count(), "object not found" );
254 /*************************************************************************
255 |* SotObject::AddInterface()
257 |* Beschreibung
258 *************************************************************************/
259 void SotObject::AddInterface( SotObject * pObjP )
261 pObjP->AddRef(); // Objekt festhalten
262 GetAggList();
263 pAggList->Append( SvAggregate( pObjP, FALSE ) );
265 // sich selbst als Typecast-Verwalter eintragen
266 SvAggregateMemberList & rAList = pObjP->GetAggList();
267 DBG_ASSERT( !rAList.GetObject( 0 ).bMainObj, "try to aggregate twice" );
268 rAList[ 0 ] = SvAggregate( this, TRUE );
271 /*************************************************************************
272 |* SotObject::AddInterface()
274 |* Beschreibung
275 *************************************************************************/
276 void SotObject::AddInterface( SotFactory * pFactP )
278 GetAggList();
279 pAggList->Append( SvAggregate( pFactP ) );
282 /*************************************************************************
283 |* SotObject::CreateAggObj()
285 |* Beschreibung
286 *************************************************************************/
287 SotObjectRef SotObject::CreateAggObj( const SotFactory * )
289 return SotObjectRef();
293 /*************************************************************************
294 |* SotObject::DownAggCast()
296 |* Beschreibung
297 *************************************************************************/
298 void * SotObject::DownAggCast( const SotFactory * pFact )
300 void * pCast = NULL;
301 // geht den Pfad nur Richtung aggregierte Objekte
302 if( pAggList )
304 for( ULONG i = 1; !pCast || i < pAggList->Count(); i++ )
306 SvAggregate & rAgg = pAggList->GetObject( i );
307 if( rAgg.bFactory )
309 if( rAgg.pFact->Is( pFact ) )
311 // On-Demand erzeugen, wenn Typ gebraucht
312 SotObjectRef aObj( CreateAggObj( rAgg.pFact ) );
313 rAgg.bFactory = FALSE;
314 rAgg.pObj = aObj;
315 rAgg.pObj->AddRef();
317 // sich selbst als Typecast-Verwalter eintragen
318 SvAggregateMemberList & rAList = rAgg.pObj->GetAggList();
319 DBG_ASSERT( !rAList.GetObject( 0 ).bMainObj, "try to aggregate twice" );
320 rAList[ 0 ] = SvAggregate( this, TRUE );
323 if( !rAgg.bFactory )
325 // muss der (void *) auf Klasse pFact sein
326 pCast = rAgg.pObj->Cast( pFact );
327 if( !pCast )
328 pCast = rAgg.pObj->DownAggCast( pFact );
329 if( pCast )
330 break;
334 return pCast;
337 /*************************************************************************
338 |* SotObject::AggCast()
340 |* Beschreibung
341 *************************************************************************/
342 void * SotObject::AggCast( const SotFactory * pFact )
344 void * pCast = NULL;
345 if( pAggList )
347 SvAggregate & rAgg = pAggList->GetObject( 0 );
348 if( rAgg.bMainObj )
349 return rAgg.pObj->AggCast( pFact );
350 pCast = Cast( pFact );
351 if( !pCast )
352 pCast = DownAggCast( pFact );
354 else
355 pCast = Cast( pFact );
356 return pCast;
359 /*************************************************************************
360 |* SotObject::CastAndAddRef()
362 |* Beschreibung
363 *************************************************************************/
364 void * SotObject::CastAndAddRef( const SotFactory * pFact )
366 void * pCast = Cast( pFact );
367 if( pCast )
368 AddRef();
369 return pCast;
372 /*************************************************************************
373 |* SotObject::GetMainObj()
375 |* Beschreibung
376 *************************************************************************/
377 SotObject * SotObject::GetMainObj() const
379 if( pAggList )
381 if( pAggList->GetObject( 0 ).bMainObj )
382 return pAggList->GetObject( 0 ).pObj->GetMainObj();
384 return (SotObject *)this;
387 //=========================================================================
388 USHORT SotObject::FuzzyLock
390 BOOL bLock, /* TRUE, lock. FALSE, unlock. */
391 BOOL /*bIntern*/, /* TRUE, es handelt sich um einen internen Lock.
392 FALSE, der Lock kam von aussen (Ole2, Ipc2) */
393 BOOL bClose /* TRUE, Close aufrufen wenn letzte Lock */
395 /* [Beschreibung]
397 Erlaubte Parameterkombinationen:
398 ( TRUE, TRUE, * ) -> interner Lock.
399 ( FALSE, TRUE, TRUE ) -> interner Unlock mit Close,
400 wenn LockCount() == 0
401 ( TRUE, FALSE, * ) -> externer Lock.
402 ( FALSE, FALSE, TRUE ) -> externer Unlock mit Close,
403 wenn LockCount() == 0
404 ( FALSE, FALSE, FALSE ) -> externer Unlock
406 F"ur !Owner() wird der Aufruf an das externe Objekt weitergeleitet.
407 F"ur diese muss das <IOleItemContainer>-Interface zur Vef"ugung stehen.
408 bIntern und bClose werden dann ignoriert.
409 Wenn der LockCount auf 0 wechselt, wird <SotObject::DoClose>
410 gerufen, wenn kein OwnerLock besteht.
412 [Anmerkung]
416 SotObjectRef xHoldAlive( this );
417 USHORT nRet;
418 if( bLock )
420 AddRef();
421 nRet = ++nStrongLockCount;
423 else
425 nRet = --nStrongLockCount;
426 ReleaseRef();
429 if( !nRet && bClose && !nOwnerLockCount )
430 DoClose();
431 return nRet;
434 //=========================================================================
435 void SotObject::OwnerLock
437 BOOL bLock /* TRUE, lock. FALSE, unlock. */
439 /* [Beschreibung]
441 Wenn der OwnerLock auf Null dekrementiert, dann wird die Methode
442 DoClose gerufen. Dies geschieht unabh"angig vom Lock. bzw. RefCount.
443 Ist der OwnerLock-Z"ahler != Null, dann wird kein DoClose durch
444 <SotObject::FuzzyLock> gerufen.
447 if( bLock )
449 nOwnerLockCount++;
450 AddRef();
452 else if ( nOwnerLockCount )
454 if( 0 == --nOwnerLockCount )
455 DoClose();
456 ReleaseRef();
460 void SotObject::RemoveOwnerLock()
462 if ( nOwnerLockCount )
464 --nOwnerLockCount;
465 ReleaseRef();
467 else {
468 DBG_ERROR("OwnerLockCount underflow!");
472 //=========================================================================
473 BOOL SotObject::DoClose()
475 BOOL bRet = FALSE;
476 if( !bInClose )
478 SotObjectRef xHoldAlive( this );
479 bInClose = TRUE;
480 bRet = Close();
481 bInClose = FALSE;
483 return bRet;
486 //=========================================================================
487 BOOL SotObject::Close()
489 return TRUE;