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

Generated by: LCOV version 1.10