LCOV - code coverage report
Current view: top level - basic/source/sbx - sbxobj.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 212 496 42.7 %
Date: 2014-04-11 Functions: 45 63 71.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <sal/config.h>
      21             : 
      22             : #include <iomanip>
      23             : 
      24             : #include <tools/stream.hxx>
      25             : #include <basic/sbx.hxx>
      26             : #include "sbxres.hxx"
      27             : #include <svl/brdcst.hxx>
      28             : 
      29      103106 : TYPEINIT1(SbxMethod,SbxVariable)
      30       66139 : TYPEINIT1(SbxProperty,SbxVariable)
      31      127870 : TYPEINIT2(SbxObject,SbxVariable,SfxListener)
      32             : 
      33         156 : static OUString pNameProp;          // Name-Property
      34         156 : static OUString pParentProp;        // Parent-Property
      35             : 
      36             : static sal_uInt16 nNameHash = 0, nParentHash = 0;
      37             : 
      38             : 
      39             : 
      40       18788 : SbxObject::SbxObject( const OUString& rClass )
      41       18788 :          : SbxVariable( SbxOBJECT ), aClassName( rClass )
      42             : {
      43       18788 :     aData.pObj = this;
      44       18788 :     if( !nNameHash )
      45             :     {
      46          76 :         pNameProp = OUString::createFromAscii(GetSbxRes( STRING_NAMEPROP ));
      47          76 :         pParentProp = OUString::createFromAscii(GetSbxRes( STRING_PARENTPROP ));
      48          76 :         nNameHash = MakeHashCode( pNameProp );
      49          76 :         nParentHash = MakeHashCode( pParentProp );
      50             :     }
      51       18788 :     SbxObject::Clear();
      52       18788 :     SbxObject::SetName( rClass );
      53       18788 : }
      54             : 
      55           0 : SbxObject::SbxObject( const SbxObject& rObj )
      56           0 :     : SvRefBase( rObj ), SbxVariable( rObj.GetType() ),
      57           0 :       SfxListener( rObj )
      58             : {
      59           0 :     *this = rObj;
      60           0 : }
      61             : 
      62           0 : SbxObject& SbxObject::operator=( const SbxObject& r )
      63             : {
      64           0 :     if( &r != this )
      65             :     {
      66           0 :         SbxVariable::operator=( r );
      67           0 :         aClassName = r.aClassName;
      68           0 :         pMethods   = new SbxArray;
      69           0 :         pProps     = new SbxArray;
      70           0 :         pObjs      = new SbxArray( SbxOBJECT );
      71             :         // The arrays were copied, the content taken over
      72           0 :         *pMethods  = *r.pMethods;
      73           0 :         *pProps    = *r.pProps;
      74           0 :         *pObjs     = *r.pObjs;
      75             :         // Because the variables were taken over, this is OK
      76           0 :         pDfltProp  = r.pDfltProp;
      77           0 :         SetName( r.GetName() );
      78           0 :         SetFlags( r.GetFlags() );
      79           0 :         SetModified( true );
      80             :     }
      81           0 :     return *this;
      82             : }
      83             : 
      84       27150 : static void CheckParentsOnDelete( SbxObject* pObj, SbxArray* p )
      85             : {
      86       37155 :     for( sal_uInt16 i = 0; i < p->Count(); i++ )
      87             :     {
      88       10005 :         SbxVariableRef& rRef = p->GetRef( i );
      89       10005 :         if( rRef->IsBroadcaster() )
      90             :         {
      91       10005 :             pObj->EndListening( rRef->GetBroadcaster(), true );
      92             :         }
      93             :         // does the element have more then one reference and still a Listener?
      94       10005 :         if( rRef->GetRefCount() > 1 )
      95             :         {
      96         279 :             rRef->SetParent( NULL );
      97             :             DBG_ASSERT( !rRef->IsBroadcaster() || rRef->GetBroadcaster().GetListenerCount(), "Object element with dangling parent" );
      98             :         }
      99             :     }
     100       27150 : }
     101             : 
     102       20998 : SbxObject::~SbxObject()
     103             : {
     104        9050 :     CheckParentsOnDelete( this, pProps );
     105        9050 :     CheckParentsOnDelete( this, pMethods );
     106        9050 :     CheckParentsOnDelete( this, pObjs );
     107             : 
     108             :     // avoid handling in ~SbxVariable as SBX_DIM_AS_NEW == SBX_GBLSEARCH
     109        9050 :     ResetFlag( SBX_DIM_AS_NEW );
     110       11948 : }
     111             : 
     112       15918 : SbxDataType SbxObject::GetType() const
     113             : {
     114       15918 :     return SbxOBJECT;
     115             : }
     116             : 
     117      342599 : SbxClassType SbxObject::GetClass() const
     118             : {
     119      342599 :     return SbxCLASS_OBJECT;
     120             : }
     121             : 
     122       18788 : void SbxObject::Clear()
     123             : {
     124       18788 :     pMethods   = new SbxArray;
     125       18788 :     pProps     = new SbxArray;
     126       18788 :     pObjs      = new SbxArray( SbxOBJECT );
     127             :     SbxVariable* p;
     128       18788 :     p = Make( pNameProp, SbxCLASS_PROPERTY, SbxSTRING );
     129       18788 :     p->SetFlag( SBX_DONTSTORE );
     130       18788 :     p = Make( pParentProp, SbxCLASS_PROPERTY, SbxOBJECT );
     131       18788 :     p->ResetFlag( SBX_WRITE );
     132       18788 :     p->SetFlag( SBX_DONTSTORE );
     133       18788 :     pDfltProp  = NULL;
     134       18788 :     SetModified( false );
     135       18788 : }
     136             : 
     137       38749 : void SbxObject::SFX_NOTIFY( SfxBroadcaster&, const TypeId&,
     138             :                             const SfxHint& rHint, const TypeId& )
     139             : {
     140       38749 :     const SbxHint* p = PTR_CAST(SbxHint,&rHint);
     141       38749 :     if( p )
     142             :     {
     143       38749 :         sal_uLong nId = p->GetId();
     144       38749 :         bool bRead  = ( nId == SBX_HINT_DATAWANTED );
     145       38749 :         bool bWrite = ( nId == SBX_HINT_DATACHANGED );
     146       38749 :         SbxVariable* pVar = p->GetVar();
     147       38749 :         if( bRead || bWrite )
     148             :         {
     149       38172 :             OUString aVarName( pVar->GetName() );
     150       38172 :             sal_uInt16 nHash_ = MakeHashCode( aVarName );
     151       38172 :             if( nHash_ == nNameHash && aVarName.equalsIgnoreAsciiCase( pNameProp ) )
     152             :             {
     153           0 :                 if( bRead )
     154             :                 {
     155           0 :                     pVar->PutString( GetName() );
     156             :                 }
     157             :                 else
     158             :                 {
     159           0 :                     SetName( pVar->GetOUString() );
     160             :                 }
     161             :             }
     162       38172 :             else if( nHash_ == nParentHash && aVarName.equalsIgnoreAsciiCase( pParentProp ) )
     163             :             {
     164           0 :                 SbxObject* p_ = GetParent();
     165           0 :                 if( !p_ )
     166             :                 {
     167           0 :                     p_ = this;
     168             :                 }
     169           0 :                 pVar->PutObject( p_ );
     170       38172 :             }
     171             :         }
     172             :     }
     173       38749 : }
     174             : 
     175         148 : bool SbxObject::IsClass( const OUString& rName ) const
     176             : {
     177         148 :     return aClassName.equalsIgnoreAsciiCase( rName );
     178             : }
     179             : 
     180           0 : SbxVariable* SbxObject::FindUserData( sal_uInt32 nData )
     181             : {
     182           0 :     if( !GetAll( SbxCLASS_DONTCARE ) )
     183             :     {
     184           0 :         return NULL;
     185             :     }
     186           0 :     SbxVariable* pRes = pMethods->FindUserData( nData );
     187           0 :     if( !pRes )
     188             :     {
     189           0 :         pRes = pProps->FindUserData( nData );
     190             :     }
     191           0 :     if( !pRes )
     192             :     {
     193           0 :         pRes = pObjs->FindUserData( nData );
     194             :     }
     195             :     // Search in the parents?
     196           0 :     if( !pRes && IsSet( SBX_GBLSEARCH ) )
     197             :     {
     198           0 :         SbxObject* pCur = this;
     199           0 :         while( !pRes && pCur->pParent )
     200             :         {
     201             :             // I myself was already searched!
     202           0 :             sal_uInt16 nOwn = pCur->GetFlags();
     203           0 :             pCur->ResetFlag( SBX_EXTSEARCH );
     204             :             // I search already global!
     205           0 :             sal_uInt16 nPar = pCur->pParent->GetFlags();
     206           0 :             pCur->pParent->ResetFlag( SBX_GBLSEARCH );
     207           0 :             pRes = pCur->pParent->FindUserData( nData );
     208           0 :             pCur->SetFlags( nOwn );
     209           0 :             pCur->pParent->SetFlags( nPar );
     210           0 :             pCur = pCur->pParent;
     211             :         }
     212             :     }
     213           0 :     return pRes;
     214             : }
     215             : 
     216      760334 : SbxVariable* SbxObject::Find( const OUString& rName, SbxClassType t )
     217             : {
     218             : #ifdef DBG_UTIL
     219             :     static int nLvl = 1;
     220             :     static const char* pCls[] = { "DontCare","Array","Value","Variable","Method","Property","Object" };
     221             :     SAL_INFO(
     222             :         "basic.sbx",
     223             :         "search" << std::setw(nLvl) << " "
     224             :             << (t >= SbxCLASS_DONTCARE && t <= SbxCLASS_OBJECT
     225             :                 ? pCls[t - 1] : "Unknown class")
     226             :             << " " << rName << " in " << SbxVariable::GetName());
     227             :     ++nLvl;
     228             : #endif
     229             : 
     230      760334 :     if( !GetAll( t ) )
     231             :     {
     232           0 :         return NULL;
     233             :     }
     234      760334 :     SbxVariable* pRes = NULL;
     235      760334 :     pObjs->SetFlag( SBX_EXTSEARCH );
     236      760334 :     if( t == SbxCLASS_DONTCARE )
     237             :     {
     238      537505 :         pRes = pMethods->Find( rName, SbxCLASS_METHOD );
     239      537505 :         if( !pRes )
     240             :         {
     241      535289 :             pRes = pProps->Find( rName, SbxCLASS_PROPERTY );
     242             :         }
     243      537505 :         if( !pRes )
     244             :         {
     245      504479 :             pRes = pObjs->Find( rName, t );
     246             :         }
     247             :     }
     248             :     else
     249             :     {
     250      222829 :         SbxArray* pArray = NULL;
     251      222829 :         switch( t )
     252             :         {
     253             :         case SbxCLASS_VARIABLE:
     254        8548 :         case SbxCLASS_PROPERTY: pArray = pProps;    break;
     255        2919 :         case SbxCLASS_METHOD:   pArray = pMethods;  break;
     256      211362 :         case SbxCLASS_OBJECT:   pArray = pObjs;     break;
     257           0 :         default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
     258             :         }
     259      222829 :         if( pArray )
     260             :         {
     261      222829 :             pRes = pArray->Find( rName, t );
     262             :         }
     263             :     }
     264             :     // Extended Search in the Object-Array?
     265             :     // For objects and DontCare the array of objects has already been searched
     266      760334 :     if( !pRes && ( t == SbxCLASS_METHOD || t == SbxCLASS_PROPERTY ) )
     267        8201 :         pRes = pObjs->Find( rName, t );
     268             :     // Search in the parents?
     269      760334 :     if( !pRes && IsSet( SBX_GBLSEARCH ) )
     270             :     {
     271       29056 :         SbxObject* pCur = this;
     272       88019 :         while( !pRes && pCur->pParent )
     273             :         {
     274             :             // I myself was already searched!
     275       29907 :             sal_uInt16 nOwn = pCur->GetFlags();
     276       29907 :             pCur->ResetFlag( SBX_EXTSEARCH );
     277             :             // I search already global!
     278       29907 :             sal_uInt16 nPar = pCur->pParent->GetFlags();
     279       29907 :             pCur->pParent->ResetFlag( SBX_GBLSEARCH );
     280       29907 :             pRes = pCur->pParent->Find( rName, t );
     281       29907 :             pCur->SetFlags( nOwn );
     282       29907 :             pCur->pParent->SetFlags( nPar );
     283       29907 :             pCur = pCur->pParent;
     284             :         }
     285             :     }
     286             : #ifdef DBG_UTIL
     287             :     --nLvl;
     288             :     SAL_INFO_IF(
     289             :         pRes, "basic.sbx",
     290             :         "found" << std::setw(nLvl) << " " << rName << " in "
     291             :             << SbxVariable::GetName());
     292             : #endif
     293      760334 :     return pRes;
     294             : }
     295             : 
     296             : // Abbreviated version: The parent-string will be searched
     297             : // The whole thing recursive, because Call() might be overloaded
     298             : // Qualified names are allowed
     299             : 
     300          18 : bool SbxObject::Call( const OUString& rName, SbxArray* pParam )
     301             : {
     302          18 :     SbxVariable* pMeth = FindQualified( rName, SbxCLASS_DONTCARE);
     303          18 :     if( pMeth && pMeth->ISA(SbxMethod) )
     304             :     {
     305             :         // FindQualified() might have struck already!
     306          18 :         if( pParam )
     307             :         {
     308          18 :             pMeth->SetParameters( pParam );
     309             :         }
     310          18 :         pMeth->Broadcast( SBX_HINT_DATAWANTED );
     311          18 :         pMeth->SetParameters( NULL );
     312          18 :         return true;
     313             :     }
     314           0 :     SetError( SbxERR_NO_METHOD );
     315           0 :     return false;
     316             : }
     317             : 
     318         100 : SbxProperty* SbxObject::GetDfltProperty()
     319             : {
     320         100 :     if ( !pDfltProp && !aDfltPropName.isEmpty() )
     321             :     {
     322          88 :         pDfltProp = (SbxProperty*) Find( aDfltPropName, SbxCLASS_PROPERTY );
     323          88 :         if( !pDfltProp )
     324             :         {
     325           0 :             pDfltProp = (SbxProperty*) Make( aDfltPropName, SbxCLASS_PROPERTY, SbxVARIANT );
     326             :         }
     327             :     }
     328         100 :     return pDfltProp;
     329             : }
     330        1213 : void SbxObject::SetDfltProperty( const OUString& rName )
     331             : {
     332        1213 :     if ( rName != aDfltPropName )
     333             :     {
     334        1213 :         pDfltProp = NULL;
     335             :     }
     336        1213 :     aDfltPropName = rName;
     337        1213 :     SetModified( true );
     338        1213 : }
     339             : 
     340             : // Search of an already available variable. If it was located,
     341             : // the index will be set, otherwise the Count of the Array will be returned.
     342             : // In any case the correct Array will be returned.
     343             : 
     344       36793 : SbxArray* SbxObject::FindVar( SbxVariable* pVar, sal_uInt16& nArrayIdx )
     345             : {
     346       36793 :     SbxArray* pArray = NULL;
     347       36793 :     if( pVar ) switch( pVar->GetClass() )
     348             :     {
     349             :     case SbxCLASS_VARIABLE:
     350       25492 :     case SbxCLASS_PROPERTY: pArray = pProps;    break;
     351           0 :     case SbxCLASS_METHOD:   pArray = pMethods;  break;
     352       11301 :     case SbxCLASS_OBJECT:   pArray = pObjs;     break;
     353           0 :     default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
     354             :     }
     355       36793 :     if( pArray )
     356             :     {
     357       36793 :         nArrayIdx = pArray->Count();
     358             :         // Is the variable per name available?
     359       36793 :         pArray->ResetFlag( SBX_EXTSEARCH );
     360       36793 :         SbxVariable* pOld = pArray->Find( pVar->GetName(), pVar->GetClass() );
     361       36793 :         if( pOld )
     362             :         {
     363       77657 :             for( sal_uInt16 i = 0; i < pArray->Count(); i++ )
     364             :             {
     365       77657 :                 SbxVariableRef& rRef = pArray->GetRef( i );
     366       77657 :                 if( (SbxVariable*) rRef == pOld )
     367             :                 {
     368       29548 :                     nArrayIdx = i; break;
     369             :                 }
     370             :             }
     371             :         }
     372             :     }
     373       36793 :     return pArray;
     374             : }
     375             : 
     376             : // If a new object will be established, this object will be indexed,
     377             : // if an object of this name exists already.
     378             : 
     379       50828 : SbxVariable* SbxObject::Make( const OUString& rName, SbxClassType ct, SbxDataType dt )
     380             : {
     381             :     // Is the object already available?
     382       50828 :     SbxArray* pArray = NULL;
     383       50828 :     switch( ct )
     384             :     {
     385             :     case SbxCLASS_VARIABLE:
     386       37762 :     case SbxCLASS_PROPERTY: pArray = pProps;    break;
     387       13066 :     case SbxCLASS_METHOD:   pArray = pMethods;  break;
     388           0 :     case SbxCLASS_OBJECT:   pArray = pObjs;     break;
     389           0 :     default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
     390             :     }
     391       50828 :     if( !pArray )
     392             :     {
     393           0 :         return NULL;
     394             :     }
     395             :     // Collections may contain objects of the same name
     396       50828 :     if( !( ct == SbxCLASS_OBJECT && ISA(SbxCollection) ) )
     397             :     {
     398       50828 :         SbxVariable* pRes = pArray->Find( rName, ct );
     399       50828 :         if( pRes )
     400             :         {
     401           0 :             return pRes;
     402             :         }
     403             :     }
     404       50828 :     SbxVariable* pVar = NULL;
     405       50828 :     switch( ct )
     406             :     {
     407             :     case SbxCLASS_VARIABLE:
     408             :     case SbxCLASS_PROPERTY:
     409       37762 :         pVar = new SbxProperty( rName, dt );
     410       37762 :         break;
     411             :     case SbxCLASS_METHOD:
     412       13066 :         pVar = new SbxMethod( rName, dt );
     413       13066 :         break;
     414             :     case SbxCLASS_OBJECT:
     415           0 :         pVar = CreateObject( rName );
     416           0 :         break;
     417             :     default:
     418           0 :         break;
     419             :     }
     420       50828 :     pVar->SetParent( this );
     421       50828 :     pArray->Put( pVar, pArray->Count() );
     422       50828 :     SetModified( true );
     423             :     // The object listen always
     424       50828 :     StartListening( pVar->GetBroadcaster(), true );
     425       50828 :     Broadcast( SBX_HINT_OBJECTCHANGED );
     426       50828 :     return pVar;
     427             : }
     428             : 
     429           0 : SbxObject* SbxObject::MakeObject( const OUString& rName, const OUString& rClass )
     430             : {
     431             :     // Is the object already available?
     432           0 :     if( !ISA(SbxCollection) )
     433             :     {
     434           0 :         SbxVariable* pRes = pObjs->Find( rName, SbxCLASS_OBJECT );
     435           0 :         if( pRes )
     436             :         {
     437           0 :             return PTR_CAST(SbxObject,pRes);
     438             :         }
     439             :     }
     440           0 :     SbxObject* pVar = CreateObject( rClass );
     441           0 :     if( pVar )
     442             :     {
     443           0 :         pVar->SetName( rName );
     444           0 :         pVar->SetParent( this );
     445           0 :         pObjs->Put( pVar, pObjs->Count() );
     446           0 :         SetModified( true );
     447             :         // The object listen always
     448           0 :         StartListening( pVar->GetBroadcaster(), true );
     449           0 :         Broadcast( SBX_HINT_OBJECTCHANGED );
     450             :     }
     451           0 :     return pVar;
     452             : }
     453             : 
     454       11130 : void SbxObject::Insert( SbxVariable* pVar )
     455             : {
     456             :     sal_uInt16 nIdx;
     457       11130 :     SbxArray* pArray = FindVar( pVar, nIdx );
     458       11130 :     if( pArray )
     459             :     {
     460             :         // Into with it. But you should pay attention at the Pointer!
     461       11130 :         if( nIdx < pArray->Count() )
     462             :         {
     463             :             // Then this element exists already
     464             :             // There are objects of the same name allowed at collections
     465        4056 :             if( pArray == pObjs && ISA(SbxCollection) )
     466             :             {
     467           0 :                 nIdx = pArray->Count();
     468             :             }
     469             :             else
     470             :             {
     471        4056 :                 SbxVariable* pOld = pArray->Get( nIdx );
     472             :                 // already inside: overwrite
     473        4056 :                 if( pOld == pVar )
     474             :                 {
     475           0 :                     return;
     476             :                 }
     477        4056 :                 EndListening( pOld->GetBroadcaster(), true );
     478        4056 :                 if( pVar->GetClass() == SbxCLASS_PROPERTY )
     479             :                 {
     480           0 :                     if( pOld == pDfltProp )
     481             :                     {
     482           0 :                         pDfltProp = (SbxProperty*) pVar;
     483             :                     }
     484             :                 }
     485             :             }
     486             :         }
     487       11130 :         StartListening( pVar->GetBroadcaster(), true );
     488       11130 :         pArray->Put( pVar, nIdx );
     489       11130 :         if( pVar->GetParent() != this )
     490             :         {
     491       10461 :             pVar->SetParent( this );
     492             :         }
     493       11130 :         SetModified( true );
     494       11130 :         Broadcast( SBX_HINT_OBJECTCHANGED );
     495             : #ifdef DBG_UTIL
     496             :         static const char* pCls[] =
     497             :             { "DontCare","Array","Value","Variable","Method","Property","Object" };
     498             :         OUString aVarName( pVar->GetName() );
     499             :         if ( aVarName.isEmpty() && pVar->ISA(SbxObject) )
     500             :         {
     501             :             aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
     502             :         }
     503             :         SAL_INFO(
     504             :             "basic.sbx",
     505             :             "insert "
     506             :                 << ((pVar->GetClass() >= SbxCLASS_DONTCARE
     507             :                      && pVar->GetClass() <= SbxCLASS_OBJECT)
     508             :                     ? pCls[pVar->GetClass() - 1] : "Unknown class")
     509             :                 << " " << aVarName << " in " << SbxVariable::GetName());
     510             : #endif
     511             :     }
     512             : }
     513             : 
     514             : // Optimisation, Insertion without checking about
     515             : // double entry and without broadcasts, will only be used in SO2/auto.cxx
     516        2220 : void SbxObject::QuickInsert( SbxVariable* pVar )
     517             : {
     518        2220 :     SbxArray* pArray = NULL;
     519        2220 :     if( pVar )
     520             :     {
     521        2220 :         switch( pVar->GetClass() )
     522             :         {
     523             :         case SbxCLASS_VARIABLE:
     524        1230 :         case SbxCLASS_PROPERTY: pArray = pProps;    break;
     525         990 :         case SbxCLASS_METHOD:   pArray = pMethods;  break;
     526           0 :         case SbxCLASS_OBJECT:   pArray = pObjs;     break;
     527           0 :         default: DBG_ASSERT( !this, "Invalid SBX-Class" ); break;
     528             :         }
     529             :     }
     530        2220 :     if( pArray )
     531             :     {
     532        2220 :         StartListening( pVar->GetBroadcaster(), true );
     533        2220 :         pArray->Put( pVar, pArray->Count() );
     534        2220 :         if( pVar->GetParent() != this )
     535             :         {
     536        2220 :             pVar->SetParent( this );
     537             :         }
     538        2220 :         SetModified( true );
     539             : #ifdef DBG_UTIL
     540             :         static const char* pCls[] =
     541             :             { "DontCare","Array","Value","Variable","Method","Property","Object" };
     542             :         OUString aVarName( pVar->GetName() );
     543             :         if ( aVarName.isEmpty() && pVar->ISA(SbxObject) )
     544             :         {
     545             :             aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
     546             :         }
     547             :         SAL_INFO(
     548             :             "basic.sbx",
     549             :             "insert "
     550             :                 << ((pVar->GetClass() >= SbxCLASS_DONTCARE
     551             :                      && pVar->GetClass() <= SbxCLASS_OBJECT)
     552             :                     ? pCls[pVar->GetClass() - 1] : "Unknown class")
     553             :                 << " " << aVarName << " in " << SbxVariable::GetName());
     554             : #endif
     555             :     }
     556        2220 : }
     557             : 
     558       25492 : void SbxObject::Remove( const OUString& rName, SbxClassType t )
     559             : {
     560       25492 :     Remove( SbxObject::Find( rName, t ) );
     561       25492 : }
     562             : 
     563       25663 : void SbxObject::Remove( SbxVariable* pVar )
     564             : {
     565             :     sal_uInt16 nIdx;
     566       25663 :     SbxArray* pArray = FindVar( pVar, nIdx );
     567       25663 :     if( pArray && nIdx < pArray->Count() )
     568             :     {
     569             : #ifdef DBG_UTIL
     570             :         OUString aVarName( pVar->GetName() );
     571             :         if ( aVarName.isEmpty() && pVar->ISA(SbxObject) )
     572             :         {
     573             :             aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
     574             :         }
     575             :         SAL_INFO(
     576             :             "basic.sbx",
     577             :             "remove " << aVarName << " in " << SbxVariable::GetName());
     578             : #endif
     579       25492 :         SbxVariableRef pVar_ = pArray->Get( nIdx );
     580       25492 :         if( pVar_->IsBroadcaster() )
     581             :         {
     582       25492 :             EndListening( pVar_->GetBroadcaster(), true );
     583             :         }
     584       25492 :         if( (SbxVariable*) pVar_ == pDfltProp )
     585             :         {
     586           0 :             pDfltProp = NULL;
     587             :         }
     588       25492 :         pArray->Remove( nIdx );
     589       25492 :         if( pVar_->GetParent() == this )
     590             :         {
     591       25492 :             pVar_->SetParent( NULL );
     592             :         }
     593       25492 :         SetModified( true );
     594       25492 :         Broadcast( SBX_HINT_OBJECTCHANGED );
     595             :     }
     596       25663 : }
     597             : 
     598           0 : static bool LoadArray( SvStream& rStrm, SbxObject* pThis, SbxArray* pArray )
     599             : {
     600           0 :     SbxArrayRef p = (SbxArray*) SbxBase::Load( rStrm );
     601           0 :     if( !p.Is() )
     602             :     {
     603           0 :         return false;
     604             :     }
     605           0 :     for( sal_uInt16 i = 0; i < p->Count(); i++ )
     606             :     {
     607           0 :         SbxVariableRef& r = p->GetRef( i );
     608           0 :         SbxVariable* pVar = r;
     609           0 :         if( pVar )
     610             :         {
     611           0 :             pVar->SetParent( pThis );
     612           0 :             pThis->StartListening( pVar->GetBroadcaster(), true );
     613             :         }
     614             :     }
     615           0 :     pArray->Merge( p );
     616           0 :     return true;
     617             : }
     618             : 
     619             : // The load of an object is additive!
     620             : 
     621           0 : bool SbxObject::LoadData( SvStream& rStrm, sal_uInt16 nVer )
     622             : {
     623             :     // Help for the read in of old objects: just return TRUE,
     624             :     // LoadPrivateData() has to set the default status up
     625           0 :     if( !nVer )
     626             :     {
     627           0 :         return true;
     628             :     }
     629           0 :     pDfltProp = NULL;
     630           0 :     if( !SbxVariable::LoadData( rStrm, nVer ) )
     631             :     {
     632           0 :         return false;
     633             :     }
     634             :     // If it contains no alien object, insert ourselves
     635           0 :     if( aData.eType == SbxOBJECT && !aData.pObj )
     636             :     {
     637           0 :         aData.pObj = this;
     638             :     }
     639             :     sal_uInt32 nSize;
     640           0 :     OUString aDfltProp;
     641           0 :     aClassName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rStrm, RTL_TEXTENCODING_ASCII_US);
     642           0 :     aDfltProp = read_uInt16_lenPrefixed_uInt8s_ToOUString(rStrm, RTL_TEXTENCODING_ASCII_US);
     643           0 :     sal_Size nPos = rStrm.Tell();
     644           0 :     rStrm.ReadUInt32( nSize );
     645           0 :     if( !LoadPrivateData( rStrm, nVer ) )
     646             :     {
     647           0 :         return false;
     648             :     }
     649           0 :     sal_Size nNewPos = rStrm.Tell();
     650           0 :     nPos += nSize;
     651             :     DBG_ASSERT( nPos >= nNewPos, "SBX: Loaded too much data" );
     652           0 :     if( nPos != nNewPos )
     653             :     {
     654           0 :         rStrm.Seek( nPos );
     655             :     }
     656           0 :     if( !LoadArray( rStrm, this, pMethods ) ||
     657           0 :         !LoadArray( rStrm, this, pProps ) ||
     658           0 :         !LoadArray( rStrm, this, pObjs ) )
     659             :     {
     660           0 :         return false;
     661             :     }
     662             :     // Set properties
     663           0 :     if( !aDfltProp.isEmpty() )
     664             :     {
     665           0 :         pDfltProp = (SbxProperty*) pProps->Find( aDfltProp, SbxCLASS_PROPERTY );
     666             :     }
     667           0 :     SetModified( false );
     668           0 :     return true;
     669             : }
     670             : 
     671           0 : bool SbxObject::StoreData( SvStream& rStrm ) const
     672             : {
     673           0 :     if( !SbxVariable::StoreData( rStrm ) )
     674             :     {
     675           0 :         return false;
     676             :     }
     677           0 :     OUString aDfltProp;
     678           0 :     if( pDfltProp )
     679             :     {
     680           0 :         aDfltProp = pDfltProp->GetName();
     681             :     }
     682           0 :     write_uInt16_lenPrefixed_uInt8s_FromOUString(rStrm, aClassName, RTL_TEXTENCODING_ASCII_US);
     683           0 :     write_uInt16_lenPrefixed_uInt8s_FromOUString(rStrm, aDfltProp, RTL_TEXTENCODING_ASCII_US);
     684           0 :     sal_Size nPos = rStrm.Tell();
     685           0 :     rStrm.WriteUInt32( (sal_uInt32) 0L );
     686           0 :     if( !StorePrivateData( rStrm ) )
     687             :     {
     688           0 :         return false;
     689             :     }
     690           0 :     sal_Size nNew = rStrm.Tell();
     691           0 :     rStrm.Seek( nPos );
     692           0 :     rStrm.WriteUInt32( (sal_uInt32) ( nNew - nPos ) );
     693           0 :     rStrm.Seek( nNew );
     694           0 :     if( !pMethods->Store( rStrm ) )
     695             :     {
     696           0 :         return false;
     697             :     }
     698           0 :     if( !pProps->Store( rStrm ) )
     699             :     {
     700           0 :         return false;
     701             :     }
     702           0 :     if( !pObjs->Store( rStrm ) )
     703             :     {
     704           0 :         return false;
     705             :     }
     706           0 :     ((SbxObject*) this)->SetModified( false );
     707           0 :     return true;
     708             : }
     709             : 
     710           0 : OUString SbxObject::GenerateSource( const OUString &rLinePrefix,
     711             :                                     const SbxObject* )
     712             : {
     713             :     // Collect the properties in a String
     714           0 :     OUString aSource;
     715           0 :     SbxArrayRef xProps( GetProperties() );
     716           0 :     bool bLineFeed = false;
     717           0 :     for ( sal_uInt16 nProp = 0; nProp < xProps->Count(); ++nProp )
     718             :     {
     719           0 :         SbxPropertyRef xProp = (SbxProperty*) xProps->Get(nProp);
     720           0 :         OUString aPropName( xProp->GetName() );
     721           0 :         if ( xProp->CanWrite() &&
     722           0 :              !( xProp->GetHashCode() == nNameHash &&
     723           0 :                 aPropName.equalsIgnoreAsciiCase(pNameProp)))
     724             :         {
     725             :             // Insert a break except in front of the first property
     726           0 :             if ( bLineFeed )
     727             :             {
     728           0 :                 aSource += "\n";
     729             :             }
     730             :             else
     731             :             {
     732           0 :                 bLineFeed = true;
     733             :             }
     734           0 :             aSource += rLinePrefix;
     735           0 :             aSource += ".";
     736           0 :             aSource += aPropName;
     737           0 :             aSource += " = ";
     738             : 
     739             :             // convert the property value to text
     740           0 :             switch ( xProp->GetType() )
     741             :             {
     742             :             case SbxEMPTY:
     743             :             case SbxNULL:
     744             :                 // no value
     745           0 :                 break;
     746             : 
     747             :             case SbxSTRING:
     748             :                 // Strings in quotation mark
     749           0 :                 aSource += "\"";
     750           0 :                 aSource += xProp->GetOUString();
     751           0 :                 aSource += "\"";
     752           0 :                 break;
     753             : 
     754             :             default:
     755             :                 // miscellaneous, such as e.g. numbers directly
     756           0 :                 aSource += xProp->GetOUString();
     757           0 :                 break;
     758             :             }
     759             :         }
     760           0 :     }
     761           0 :     return aSource;
     762             : }
     763             : 
     764           0 : static bool CollectAttrs( const SbxBase* p, OUString& rRes )
     765             : {
     766           0 :     OUString aAttrs;
     767           0 :     if( p->IsHidden() )
     768             :     {
     769           0 :         aAttrs = "Hidden";
     770             :     }
     771           0 :     if( p->IsSet( SBX_EXTSEARCH ) )
     772             :     {
     773           0 :         if( !aAttrs.isEmpty() )
     774             :         {
     775           0 :             aAttrs += ",";
     776             :         }
     777           0 :         aAttrs += "ExtSearch";
     778             :     }
     779           0 :     if( !p->IsVisible() )
     780             :     {
     781           0 :         if( !aAttrs.isEmpty() )
     782             :         {
     783           0 :             aAttrs += ",";
     784             :         }
     785           0 :         aAttrs += "Invisible";
     786             :     }
     787           0 :     if( p->IsSet( SBX_DONTSTORE ) )
     788             :     {
     789           0 :         if( !aAttrs.isEmpty() )
     790             :         {
     791           0 :             aAttrs += ",";
     792             :         }
     793           0 :         aAttrs += "DontStore";
     794             :     }
     795           0 :     if( !aAttrs.isEmpty() )
     796             :     {
     797           0 :         rRes = " (";
     798           0 :         rRes += aAttrs;
     799           0 :         rRes += ")";
     800           0 :         return true;
     801             :     }
     802             :     else
     803             :     {
     804           0 :         rRes = "";
     805           0 :         return false;
     806           0 :     }
     807             : }
     808             : 
     809           0 : void SbxObject::Dump( SvStream& rStrm, bool bFill )
     810             : {
     811             :     // Shifting
     812             :     static sal_uInt16 nLevel = 0;
     813           0 :     if ( nLevel > 10 )
     814             :     {
     815           0 :         rStrm.WriteCharPtr( "<too deep>" ) << endl;
     816           0 :         return;
     817             :     }
     818           0 :     ++nLevel;
     819           0 :     OUString aIndent("");
     820           0 :     for ( sal_uInt16 n = 1; n < nLevel; ++n )
     821             :     {
     822           0 :         aIndent += "    ";
     823             :     }
     824             :     // if necessary complete the object
     825           0 :     if ( bFill )
     826             :     {
     827           0 :         GetAll( SbxCLASS_DONTCARE );
     828             :     }
     829             :     // Output the data of the object itself
     830           0 :     OString aNameStr(OUStringToOString(GetName(), RTL_TEXTENCODING_ASCII_US));
     831           0 :     OString aClassNameStr(OUStringToOString(aClassName, RTL_TEXTENCODING_ASCII_US));
     832           0 :     rStrm.WriteCharPtr( "Object( " )
     833           0 :          .WriteCharPtr( OString::number(reinterpret_cast<sal_Int64>(this)).getStr() ).WriteCharPtr( "=='" )
     834           0 :          .WriteCharPtr(  aNameStr.isEmpty() ?  "<unnamed>" : aNameStr.getStr()  ).WriteCharPtr( "', " )
     835           0 :          .WriteCharPtr( "of class '" ).WriteCharPtr( aClassNameStr.getStr() ).WriteCharPtr( "', " )
     836           0 :          .WriteCharPtr( "counts " )
     837           0 :          .WriteCharPtr( OString::number(GetRefCount()).getStr() )
     838           0 :          .WriteCharPtr( " refs, " );
     839           0 :     if ( GetParent() )
     840             :     {
     841           0 :         OString aParentNameStr(OUStringToOString(GetName(), RTL_TEXTENCODING_ASCII_US));
     842           0 :         rStrm.WriteCharPtr( "in parent " )
     843           0 :              .WriteCharPtr( OString::number(reinterpret_cast<sal_Int64>(GetParent())).getStr() )
     844           0 :              .WriteCharPtr( "=='" ).WriteCharPtr(  aParentNameStr.isEmpty() ? "<unnamed>" : aParentNameStr.getStr()   ).WriteCharPtr( "'" );
     845             :     }
     846             :     else
     847             :     {
     848           0 :         rStrm.WriteCharPtr( "no parent " );
     849             :     }
     850           0 :     rStrm.WriteCharPtr( " )" ) << endl;
     851           0 :     OString aIndentNameStr(OUStringToOString(aIndent, RTL_TEXTENCODING_ASCII_US));
     852           0 :     rStrm.WriteCharPtr( aIndentNameStr.getStr() ).WriteCharPtr( "{" ) << endl;
     853             : 
     854             :     // Flags
     855           0 :     OUString aAttrs;
     856           0 :     if( CollectAttrs( this, aAttrs ) )
     857             :     {
     858           0 :         OString aAttrStr(OUStringToOString(aAttrs, RTL_TEXTENCODING_ASCII_US));
     859           0 :         rStrm.WriteCharPtr( aIndentNameStr.getStr() ).WriteCharPtr( "- Flags: " ).WriteCharPtr( aAttrStr.getStr() ) << endl;
     860             :     }
     861             : 
     862             :     // Methods
     863           0 :     rStrm.WriteCharPtr( aIndentNameStr.getStr() ).WriteCharPtr( "- Methods:" ) << endl;
     864           0 :     for( sal_uInt16 i = 0; i < pMethods->Count(); i++ )
     865             :     {
     866           0 :         SbxVariableRef& r = pMethods->GetRef( i );
     867           0 :         SbxVariable* pVar = r;
     868           0 :         if( pVar )
     869             :         {
     870           0 :             OUString aLine( aIndent );
     871           0 :             aLine += "  - ";
     872           0 :             aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
     873           0 :             OUString aAttrs2;
     874           0 :             if( CollectAttrs( pVar, aAttrs2 ) )
     875             :             {
     876           0 :                 aLine += aAttrs2;
     877             :             }
     878           0 :             if( !pVar->IsA( TYPE(SbxMethod) ) )
     879             :             {
     880           0 :                 aLine += "  !! Not a Method !!";
     881             :             }
     882           0 :             write_uInt16_lenPrefixed_uInt8s_FromOUString(rStrm, aLine, RTL_TEXTENCODING_ASCII_US);
     883             : 
     884             :             // Output also the object at object-methods
     885           0 :             if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
     886           0 :                     pVar->GetValues_Impl().pObj &&
     887           0 :                     pVar->GetValues_Impl().pObj != this &&
     888           0 :                     pVar->GetValues_Impl().pObj != GetParent() )
     889             :             {
     890           0 :                 rStrm.WriteCharPtr( " contains " );
     891           0 :                 ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
     892             :             }
     893             :             else
     894             :             {
     895           0 :                 rStrm << endl;
     896           0 :             }
     897             :         }
     898             :     }
     899             : 
     900             :     // Properties
     901           0 :     rStrm.WriteCharPtr( aIndentNameStr.getStr() ).WriteCharPtr( "- Properties:" ) << endl;
     902             :     {
     903           0 :         for( sal_uInt16 i = 0; i < pProps->Count(); i++ )
     904             :         {
     905           0 :             SbxVariableRef& r = pProps->GetRef( i );
     906           0 :             SbxVariable* pVar = r;
     907           0 :             if( pVar )
     908             :             {
     909           0 :                 OUString aLine( aIndent );
     910           0 :                 aLine += "  - ";
     911           0 :                 aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
     912           0 :                 OUString aAttrs3;
     913           0 :                 if( CollectAttrs( pVar, aAttrs3 ) )
     914             :                 {
     915           0 :                     aLine += aAttrs3;
     916             :                 }
     917           0 :                 if( !pVar->IsA( TYPE(SbxProperty) ) )
     918             :                 {
     919           0 :                     aLine += "  !! Not a Property !!";
     920             :                 }
     921           0 :                 write_uInt16_lenPrefixed_uInt8s_FromOUString(rStrm, aLine, RTL_TEXTENCODING_ASCII_US);
     922             : 
     923             :                 // output also the object at object properties
     924           0 :                 if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
     925           0 :                         pVar->GetValues_Impl().pObj &&
     926           0 :                         pVar->GetValues_Impl().pObj != this &&
     927           0 :                         pVar->GetValues_Impl().pObj != GetParent() )
     928             :                 {
     929           0 :                     rStrm.WriteCharPtr( " contains " );
     930           0 :                     ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
     931             :                 }
     932             :                 else
     933             :                 {
     934           0 :                     rStrm << endl;
     935           0 :                 }
     936             :             }
     937             :         }
     938             :     }
     939             : 
     940             :     // Objects
     941           0 :     rStrm.WriteCharPtr( aIndentNameStr.getStr() ).WriteCharPtr( "- Objects:" ) << endl;
     942             :     {
     943           0 :         for( sal_uInt16 i = 0; i < pObjs->Count(); i++ )
     944             :         {
     945           0 :             SbxVariableRef& r = pObjs->GetRef( i );
     946           0 :             SbxVariable* pVar = r;
     947           0 :             if ( pVar )
     948             :             {
     949           0 :                 rStrm.WriteCharPtr( aIndentNameStr.getStr() ).WriteCharPtr( "  - Sub" );
     950           0 :                 if ( pVar->ISA(SbxObject) )
     951             :                 {
     952           0 :                     ((SbxObject*) pVar)->Dump( rStrm, bFill );
     953             :                 }
     954           0 :                 else if ( pVar->ISA(SbxVariable) )
     955             :                 {
     956           0 :                     ((SbxVariable*) pVar)->Dump( rStrm, bFill );
     957             :                 }
     958             :             }
     959             :         }
     960             :     }
     961             : 
     962           0 :     rStrm.WriteCharPtr( aIndentNameStr.getStr() ).WriteCharPtr( "}" ) << endl << endl;
     963           0 :     --nLevel;
     964             : }
     965             : 
     966       14490 : SbxMethod::SbxMethod( const OUString& r, SbxDataType t )
     967       14490 :     : SbxVariable( t )
     968             : {
     969       14490 :     SetName( r );
     970       14490 : }
     971             : 
     972        5264 : SbxMethod::SbxMethod( const SbxMethod& r )
     973        5264 :     : SvRefBase( r ), SbxVariable( r )
     974             : {
     975        5264 : }
     976             : 
     977       20932 : SbxMethod::~SbxMethod()
     978             : {
     979       20932 : }
     980             : 
     981       12077 : SbxClassType SbxMethod::GetClass() const
     982             : {
     983       12077 :     return SbxCLASS_METHOD;
     984             : }
     985             : 
     986       39104 : SbxProperty::SbxProperty( const OUString& r, SbxDataType t )
     987       39104 :     : SbxVariable( t )
     988             : {
     989       39104 :     SetName( r );
     990       39104 : }
     991             : 
     992       92042 : SbxProperty::~SbxProperty()
     993             : {
     994       92042 : }
     995             : 
     996      111559 : SbxClassType SbxProperty::GetClass() const
     997             : {
     998      111559 :     return SbxCLASS_PROPERTY;
     999         468 : }
    1000             : 
    1001             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10