1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_basic.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include <tools/stream.hxx> 33*cdf0e10cSrcweir #include "svl/brdcst.hxx" 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include <basic/sbx.hxx> 36*cdf0e10cSrcweir #include <basic/sbxbase.hxx> 37*cdf0e10cSrcweir #include "sbxres.hxx" 38*cdf0e10cSrcweir #include "sbxconv.hxx" 39*cdf0e10cSrcweir #include <math.h> 40*cdf0e10cSrcweir #include <ctype.h> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp" 43*cdf0e10cSrcweir using namespace com::sun::star::uno; 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir ///////////////////////////// SbxVariable ////////////////////////////// 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir TYPEINIT1(SbxVariable,SbxValue) 48*cdf0e10cSrcweir TYPEINIT1(SbxHint,SfxSimpleHint) 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir extern sal_uInt32 nVarCreator; // in SBXBASE.CXX, fuer LoadData() 51*cdf0e10cSrcweir #ifdef DBG_UTIL 52*cdf0e10cSrcweir static sal_uIntPtr nVar = 0; 53*cdf0e10cSrcweir #endif 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir ///////////////////////////// SbxVariableImpl //////////////////////////// 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir class SbxVariableImpl 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir friend class SbxVariable; 60*cdf0e10cSrcweir String m_aDeclareClassName; 61*cdf0e10cSrcweir Reference< XInterface > m_xComListener; 62*cdf0e10cSrcweir StarBASIC* m_pComListenerParentBasic; 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir SbxVariableImpl( void ) 65*cdf0e10cSrcweir : m_pComListenerParentBasic( NULL ) 66*cdf0e10cSrcweir {} 67*cdf0e10cSrcweir SbxVariableImpl( const SbxVariableImpl& r ) 68*cdf0e10cSrcweir : m_aDeclareClassName( r.m_aDeclareClassName ) 69*cdf0e10cSrcweir , m_xComListener( r.m_xComListener ) 70*cdf0e10cSrcweir , m_pComListenerParentBasic( r.m_pComListenerParentBasic ) 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir } 73*cdf0e10cSrcweir }; 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir ///////////////////////////// Konstruktoren ////////////////////////////// 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir SbxVariable::SbxVariable() : SbxValue() 79*cdf0e10cSrcweir { 80*cdf0e10cSrcweir mpSbxVariableImpl = NULL; 81*cdf0e10cSrcweir pCst = NULL; 82*cdf0e10cSrcweir pParent = NULL; 83*cdf0e10cSrcweir nUserData = 0; 84*cdf0e10cSrcweir nHash = 0; 85*cdf0e10cSrcweir #ifdef DBG_UTIL 86*cdf0e10cSrcweir DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar ); 87*cdf0e10cSrcweir GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND ); 88*cdf0e10cSrcweir #endif 89*cdf0e10cSrcweir } 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir void registerComListenerVariableForBasic( SbxVariable* pVar, StarBASIC* pBasic ); 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir SbxVariable::SbxVariable( const SbxVariable& r ) 94*cdf0e10cSrcweir : SvRefBase( r ), SbxValue( r ), mpPar( r.mpPar ), pInfo( r.pInfo ) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir mpSbxVariableImpl = NULL; 97*cdf0e10cSrcweir if( r.mpSbxVariableImpl != NULL ) 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir mpSbxVariableImpl = new SbxVariableImpl( *r.mpSbxVariableImpl ); 100*cdf0e10cSrcweir if( mpSbxVariableImpl->m_xComListener.is() ) 101*cdf0e10cSrcweir registerComListenerVariableForBasic( this, mpSbxVariableImpl->m_pComListenerParentBasic ); 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir pCst = NULL; 104*cdf0e10cSrcweir if( r.CanRead() ) 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir pParent = r.pParent; 107*cdf0e10cSrcweir nUserData = r.nUserData; 108*cdf0e10cSrcweir maName = r.maName; 109*cdf0e10cSrcweir nHash = r.nHash; 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir else 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir pParent = NULL; 114*cdf0e10cSrcweir nUserData = 0; 115*cdf0e10cSrcweir nHash = 0; 116*cdf0e10cSrcweir } 117*cdf0e10cSrcweir #ifdef DBG_UTIL 118*cdf0e10cSrcweir static sal_Char const aCellsStr[] = "Cells"; 119*cdf0e10cSrcweir if ( maName.EqualsAscii( aCellsStr ) ) 120*cdf0e10cSrcweir maName.AssignAscii( aCellsStr, sizeof( aCellsStr )-1 ); 121*cdf0e10cSrcweir DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar ); 122*cdf0e10cSrcweir GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND ); 123*cdf0e10cSrcweir #endif 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir SbxVariable::SbxVariable( SbxDataType t, void* p ) : SbxValue( t, p ) 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir mpSbxVariableImpl = NULL; 129*cdf0e10cSrcweir pCst = NULL; 130*cdf0e10cSrcweir pParent = NULL; 131*cdf0e10cSrcweir nUserData = 0; 132*cdf0e10cSrcweir nHash = 0; 133*cdf0e10cSrcweir #ifdef DBG_UTIL 134*cdf0e10cSrcweir DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar ); 135*cdf0e10cSrcweir GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND ); 136*cdf0e10cSrcweir #endif 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir void removeDimAsNewRecoverItem( SbxVariable* pVar ); 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir SbxVariable::~SbxVariable() 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir #ifdef DBG_UTIL 144*cdf0e10cSrcweir ByteString aBStr( (const UniString&)maName, RTL_TEXTENCODING_ASCII_US ); 145*cdf0e10cSrcweir DbgOutf( "SbxVariable::Dtor %lx (%s)", (void*)this, aBStr.GetBuffer() ); 146*cdf0e10cSrcweir static sal_Char const aCellsStr[] = "Cells"; 147*cdf0e10cSrcweir if ( maName.EqualsAscii( aCellsStr ) ) 148*cdf0e10cSrcweir maName.AssignAscii( aCellsStr, sizeof( aCellsStr )-1 ); 149*cdf0e10cSrcweir GetSbxData_Impl()->aVars.Remove( this ); 150*cdf0e10cSrcweir #endif 151*cdf0e10cSrcweir if( IsSet( SBX_DIM_AS_NEW )) 152*cdf0e10cSrcweir removeDimAsNewRecoverItem( this ); 153*cdf0e10cSrcweir delete mpSbxVariableImpl; 154*cdf0e10cSrcweir delete pCst; 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir ////////////////////////////// Broadcasting ////////////////////////////// 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir SfxBroadcaster& SbxVariable::GetBroadcaster() 160*cdf0e10cSrcweir { 161*cdf0e10cSrcweir if( !pCst ) 162*cdf0e10cSrcweir pCst = new SfxBroadcaster; 163*cdf0e10cSrcweir return *pCst; 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir // Eines Tages kann man vielleicht den Parameter 0 schleifen, 167*cdf0e10cSrcweir // dann entfaellt die Kopiererei... 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir void SbxVariable::Broadcast( sal_uIntPtr nHintId ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir if( pCst && !IsSet( SBX_NO_BROADCAST ) && StaticIsEnabledBroadcasting() ) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir // Da die Methode von aussen aufrufbar ist, hier noch einmal 174*cdf0e10cSrcweir // die Berechtigung testen 175*cdf0e10cSrcweir if( nHintId & SBX_HINT_DATAWANTED ) 176*cdf0e10cSrcweir if( !CanRead() ) 177*cdf0e10cSrcweir return; 178*cdf0e10cSrcweir if( nHintId & SBX_HINT_DATACHANGED ) 179*cdf0e10cSrcweir if( !CanWrite() ) 180*cdf0e10cSrcweir return; 181*cdf0e10cSrcweir // Weitere Broadcasts verhindern 182*cdf0e10cSrcweir SfxBroadcaster* pSave = pCst; 183*cdf0e10cSrcweir pCst = NULL; 184*cdf0e10cSrcweir sal_uInt16 nSaveFlags = GetFlags(); 185*cdf0e10cSrcweir SetFlag( SBX_READWRITE ); 186*cdf0e10cSrcweir if( mpPar.Is() ) 187*cdf0e10cSrcweir // this, als Element 0 eintragen, aber den Parent nicht umsetzen! 188*cdf0e10cSrcweir mpPar->GetRef( 0 ) = this; 189*cdf0e10cSrcweir pSave->Broadcast( SbxHint( nHintId, this ) ); 190*cdf0e10cSrcweir delete pCst; // wer weiss schon, auf welche Gedanken mancher kommt? 191*cdf0e10cSrcweir pCst = pSave; 192*cdf0e10cSrcweir SetFlags( nSaveFlags ); 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir SbxInfo* SbxVariable::GetInfo() 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir if( !pInfo ) 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir Broadcast( SBX_HINT_INFOWANTED ); 201*cdf0e10cSrcweir if( pInfo.Is() ) 202*cdf0e10cSrcweir SetModified( sal_True ); 203*cdf0e10cSrcweir } 204*cdf0e10cSrcweir return pInfo; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir void SbxVariable::SetInfo( SbxInfo* p ) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir pInfo = p; 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir void SbxVariable::SetParameters( SbxArray* p ) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir mpPar = p; 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir /////////////////////////// Name der Variablen /////////////////////////// 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir void SbxVariable::SetName( const XubString& rName ) 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir maName = rName; 223*cdf0e10cSrcweir nHash = MakeHashCode( rName ); 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir const XubString& SbxVariable::GetName( SbxNameType t ) const 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir static char cSuffixes[] = " %&!#@ $"; 229*cdf0e10cSrcweir if( t == SbxNAME_NONE ) 230*cdf0e10cSrcweir return maName; 231*cdf0e10cSrcweir // Parameter-Infos anfordern (nicht fuer Objekte) 232*cdf0e10cSrcweir ((SbxVariable*)this)->GetInfo(); 233*cdf0e10cSrcweir // Nix anfuegen, wenn einfache Property (keine leeren Klammern) 234*cdf0e10cSrcweir if( !pInfo 235*cdf0e10cSrcweir || ( !pInfo->aParams.Count() && GetClass() == SbxCLASS_PROPERTY ) ) 236*cdf0e10cSrcweir return maName; 237*cdf0e10cSrcweir xub_Unicode cType = ' '; 238*cdf0e10cSrcweir XubString aTmp( maName ); 239*cdf0e10cSrcweir // Kurzer Typ? Dann holen, evtl. ist dieser 0. 240*cdf0e10cSrcweir SbxDataType et = GetType(); 241*cdf0e10cSrcweir if( t == SbxNAME_SHORT_TYPES ) 242*cdf0e10cSrcweir { 243*cdf0e10cSrcweir if( et <= SbxSTRING ) 244*cdf0e10cSrcweir cType = cSuffixes[ et ]; 245*cdf0e10cSrcweir if( cType != ' ' ) 246*cdf0e10cSrcweir aTmp += cType; 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir aTmp += '('; 249*cdf0e10cSrcweir for( sal_uInt16 i = 0; i < pInfo->aParams.Count(); i++ ) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir const SbxParamInfo* q = pInfo->aParams.GetObject( i ); 252*cdf0e10cSrcweir int nt = q->eType & 0x0FFF; 253*cdf0e10cSrcweir if( i ) 254*cdf0e10cSrcweir aTmp += ','; 255*cdf0e10cSrcweir if( q->nFlags & SBX_OPTIONAL ) 256*cdf0e10cSrcweir aTmp += String( SbxRes( STRING_OPTIONAL ) ); 257*cdf0e10cSrcweir if( q->eType & SbxBYREF ) 258*cdf0e10cSrcweir aTmp += String( SbxRes( STRING_BYREF ) ); 259*cdf0e10cSrcweir aTmp += q->aName; 260*cdf0e10cSrcweir cType = ' '; 261*cdf0e10cSrcweir // Kurzer Typ? Dann holen, evtl. ist dieser 0. 262*cdf0e10cSrcweir if( t == SbxNAME_SHORT_TYPES ) 263*cdf0e10cSrcweir { 264*cdf0e10cSrcweir if( nt <= SbxSTRING ) 265*cdf0e10cSrcweir cType = cSuffixes[ nt ]; 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir if( cType != ' ' ) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir aTmp += cType; 270*cdf0e10cSrcweir if( q->eType & SbxARRAY ) 271*cdf0e10cSrcweir aTmp.AppendAscii( "()" ); 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir else 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir if( q->eType & SbxARRAY ) 276*cdf0e10cSrcweir aTmp.AppendAscii( "()" ); 277*cdf0e10cSrcweir // langer Typ? 278*cdf0e10cSrcweir if( t != SbxNAME_SHORT ) 279*cdf0e10cSrcweir { 280*cdf0e10cSrcweir aTmp += String( SbxRes( STRING_AS ) ); 281*cdf0e10cSrcweir if( nt < 32 ) 282*cdf0e10cSrcweir aTmp += String( SbxRes( 283*cdf0e10cSrcweir sal::static_int_cast< sal_uInt16 >( STRING_TYPES + nt ) ) ); 284*cdf0e10cSrcweir else 285*cdf0e10cSrcweir aTmp += String( SbxRes( STRING_ANY ) ); 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir aTmp += ')'; 290*cdf0e10cSrcweir // Langer Typ? Dann holen 291*cdf0e10cSrcweir if( t == SbxNAME_LONG_TYPES && et != SbxEMPTY ) 292*cdf0e10cSrcweir { 293*cdf0e10cSrcweir aTmp += String( SbxRes( STRING_AS ) ); 294*cdf0e10cSrcweir if( et < 32 ) 295*cdf0e10cSrcweir aTmp += String( SbxRes( 296*cdf0e10cSrcweir sal::static_int_cast< sal_uInt16 >( STRING_TYPES + et ) ) ); 297*cdf0e10cSrcweir else 298*cdf0e10cSrcweir aTmp += String( SbxRes( STRING_ANY ) ); 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir ((SbxVariable*) this)->aToolString = aTmp; 301*cdf0e10cSrcweir return aToolString; 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir // Einen simplen Hashcode erzeugen: Es werden die ersten 6 Zeichen gewertet. 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir sal_uInt16 SbxVariable::MakeHashCode( const XubString& rName ) 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir sal_uInt16 n = 0; 309*cdf0e10cSrcweir sal_uInt16 nLen = rName.Len(); 310*cdf0e10cSrcweir if( nLen > 6 ) 311*cdf0e10cSrcweir nLen = 6; 312*cdf0e10cSrcweir const xub_Unicode* p = rName.GetBuffer(); 313*cdf0e10cSrcweir while( nLen-- ) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir sal_uInt8 c = (sal_uInt8)*p; 316*cdf0e10cSrcweir p++; 317*cdf0e10cSrcweir // Falls wir ein Schweinezeichen haben, abbrechen!! 318*cdf0e10cSrcweir if( c >= 0x80 ) 319*cdf0e10cSrcweir return 0; 320*cdf0e10cSrcweir n = sal::static_int_cast< sal_uInt16 >( ( n << 3 ) + toupper( c ) ); 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir return n; 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir ////////////////////////////// Operatoren //////////////////////////////// 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir SbxVariable& SbxVariable::operator=( const SbxVariable& r ) 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir SbxValue::operator=( r ); 330*cdf0e10cSrcweir delete mpSbxVariableImpl; 331*cdf0e10cSrcweir if( r.mpSbxVariableImpl != NULL ) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir mpSbxVariableImpl = new SbxVariableImpl( *r.mpSbxVariableImpl ); 334*cdf0e10cSrcweir if( mpSbxVariableImpl->m_xComListener.is() ) 335*cdf0e10cSrcweir registerComListenerVariableForBasic( this, mpSbxVariableImpl->m_pComListenerParentBasic ); 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir else 338*cdf0e10cSrcweir mpSbxVariableImpl = NULL; 339*cdf0e10cSrcweir return *this; 340*cdf0e10cSrcweir } 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir //////////////////////////////// Konversion //////////////////////////////// 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir SbxDataType SbxVariable::GetType() const 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir if( aData.eType == SbxOBJECT ) 347*cdf0e10cSrcweir return aData.pObj ? aData.pObj->GetType() : SbxOBJECT; 348*cdf0e10cSrcweir else if( aData.eType == SbxVARIANT ) 349*cdf0e10cSrcweir return aData.pObj ? aData.pObj->GetType() : SbxVARIANT; 350*cdf0e10cSrcweir else 351*cdf0e10cSrcweir return aData.eType; 352*cdf0e10cSrcweir } 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir SbxClassType SbxVariable::GetClass() const 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir return SbxCLASS_VARIABLE; 357*cdf0e10cSrcweir } 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir void SbxVariable::SetModified( sal_Bool b ) 360*cdf0e10cSrcweir { 361*cdf0e10cSrcweir if( IsSet( SBX_NO_MODIFY ) ) 362*cdf0e10cSrcweir return; 363*cdf0e10cSrcweir SbxBase::SetModified( b ); 364*cdf0e10cSrcweir if( pParent && pParent != this ) //??? HotFix: Rekursion raus MM 365*cdf0e10cSrcweir pParent->SetModified( b ); 366*cdf0e10cSrcweir } 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir void SbxVariable::SetParent( SbxObject* p ) 369*cdf0e10cSrcweir { 370*cdf0e10cSrcweir #ifdef DBG_UTIL 371*cdf0e10cSrcweir // wird der Parent eines SbxObjects gesetzt? 372*cdf0e10cSrcweir if ( p && ISA(SbxObject) ) 373*cdf0e10cSrcweir { 374*cdf0e10cSrcweir // dann mu\s dieses auch Child vom neuen Parent sein 375*cdf0e10cSrcweir sal_Bool bFound = sal_False; 376*cdf0e10cSrcweir SbxArray *pChilds = p->GetObjects(); 377*cdf0e10cSrcweir if ( pChilds ) 378*cdf0e10cSrcweir { 379*cdf0e10cSrcweir for ( sal_uInt16 nIdx = 0; !bFound && nIdx < pChilds->Count(); ++nIdx ) 380*cdf0e10cSrcweir bFound = ( this == pChilds->Get(nIdx) ); 381*cdf0e10cSrcweir } 382*cdf0e10cSrcweir if ( !bFound ) 383*cdf0e10cSrcweir { 384*cdf0e10cSrcweir String aMsg = String::CreateFromAscii( "dangling: [" ); 385*cdf0e10cSrcweir aMsg += GetName(); 386*cdf0e10cSrcweir aMsg.AppendAscii( "].SetParent([" ); 387*cdf0e10cSrcweir aMsg += p->GetName(); 388*cdf0e10cSrcweir aMsg.AppendAscii( "])" ); 389*cdf0e10cSrcweir ByteString aBStr( (const UniString&)aMsg, RTL_TEXTENCODING_ASCII_US ); 390*cdf0e10cSrcweir DbgOut( aBStr.GetBuffer(), DBG_OUT_WARNING, __FILE__, __LINE__); 391*cdf0e10cSrcweir } 392*cdf0e10cSrcweir } 393*cdf0e10cSrcweir #endif 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir pParent = p; 396*cdf0e10cSrcweir } 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir SbxVariableImpl* SbxVariable::getImpl( void ) 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir if( mpSbxVariableImpl == NULL ) 401*cdf0e10cSrcweir mpSbxVariableImpl = new SbxVariableImpl(); 402*cdf0e10cSrcweir return mpSbxVariableImpl; 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir const String& SbxVariable::GetDeclareClassName( void ) 406*cdf0e10cSrcweir { 407*cdf0e10cSrcweir SbxVariableImpl* pImpl = getImpl(); 408*cdf0e10cSrcweir return pImpl->m_aDeclareClassName; 409*cdf0e10cSrcweir } 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir void SbxVariable::SetDeclareClassName( const String& rDeclareClassName ) 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir SbxVariableImpl* pImpl = getImpl(); 414*cdf0e10cSrcweir pImpl->m_aDeclareClassName = rDeclareClassName; 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir void SbxVariable::SetComListener( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xComListener, 418*cdf0e10cSrcweir StarBASIC* pParentBasic ) 419*cdf0e10cSrcweir { 420*cdf0e10cSrcweir SbxVariableImpl* pImpl = getImpl(); 421*cdf0e10cSrcweir pImpl->m_xComListener = xComListener; 422*cdf0e10cSrcweir pImpl->m_pComListenerParentBasic = pParentBasic; 423*cdf0e10cSrcweir registerComListenerVariableForBasic( this, pParentBasic ); 424*cdf0e10cSrcweir } 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir void SbxVariable::ClearComListener( void ) 427*cdf0e10cSrcweir { 428*cdf0e10cSrcweir SbxVariableImpl* pImpl = getImpl(); 429*cdf0e10cSrcweir pImpl->m_xComListener.clear(); 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir ////////////////////////////// Laden/Speichern ///////////////////////////// 434*cdf0e10cSrcweir 435*cdf0e10cSrcweir sal_Bool SbxVariable::LoadData( SvStream& rStrm, sal_uInt16 nVer ) 436*cdf0e10cSrcweir { 437*cdf0e10cSrcweir sal_uInt16 nType; 438*cdf0e10cSrcweir sal_uInt8 cMark; 439*cdf0e10cSrcweir rStrm >> cMark; 440*cdf0e10cSrcweir if( cMark == 0xFF ) 441*cdf0e10cSrcweir { 442*cdf0e10cSrcweir if( !SbxValue::LoadData( rStrm, nVer ) ) 443*cdf0e10cSrcweir return sal_False; 444*cdf0e10cSrcweir rStrm.ReadByteString( maName, RTL_TEXTENCODING_ASCII_US ); 445*cdf0e10cSrcweir sal_uInt32 nTemp; 446*cdf0e10cSrcweir rStrm >> nTemp; 447*cdf0e10cSrcweir nUserData = nTemp; 448*cdf0e10cSrcweir } 449*cdf0e10cSrcweir else 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir rStrm.SeekRel( -1L ); 452*cdf0e10cSrcweir rStrm >> nType; 453*cdf0e10cSrcweir rStrm.ReadByteString( maName, RTL_TEXTENCODING_ASCII_US ); 454*cdf0e10cSrcweir sal_uInt32 nTemp; 455*cdf0e10cSrcweir rStrm >> nTemp; 456*cdf0e10cSrcweir nUserData = nTemp; 457*cdf0e10cSrcweir // Korrektur: Alte Methoden haben statt SbxNULL jetzt SbxEMPTY 458*cdf0e10cSrcweir if( nType == SbxNULL && GetClass() == SbxCLASS_METHOD ) 459*cdf0e10cSrcweir nType = SbxEMPTY; 460*cdf0e10cSrcweir SbxValues aTmp; 461*cdf0e10cSrcweir String aTmpString; 462*cdf0e10cSrcweir ::rtl::OUString aVal; 463*cdf0e10cSrcweir aTmp.eType = aData.eType = (SbxDataType) nType; 464*cdf0e10cSrcweir aTmp.pOUString = &aVal; 465*cdf0e10cSrcweir switch( nType ) 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir case SbxBOOL: 468*cdf0e10cSrcweir case SbxERROR: 469*cdf0e10cSrcweir case SbxINTEGER: 470*cdf0e10cSrcweir rStrm >> aTmp.nInteger; break; 471*cdf0e10cSrcweir case SbxLONG: 472*cdf0e10cSrcweir rStrm >> aTmp.nLong; break; 473*cdf0e10cSrcweir case SbxSINGLE: 474*cdf0e10cSrcweir { 475*cdf0e10cSrcweir // Floats als ASCII 476*cdf0e10cSrcweir rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US ); 477*cdf0e10cSrcweir double d; 478*cdf0e10cSrcweir SbxDataType t; 479*cdf0e10cSrcweir if( ImpScan( aTmpString, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE ) 480*cdf0e10cSrcweir { 481*cdf0e10cSrcweir aTmp.nSingle = 0; 482*cdf0e10cSrcweir return sal_False; 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir aTmp.nSingle = (float) d; 485*cdf0e10cSrcweir break; 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir case SbxDATE: 488*cdf0e10cSrcweir case SbxDOUBLE: 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir // Floats als ASCII 491*cdf0e10cSrcweir rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US ); 492*cdf0e10cSrcweir SbxDataType t; 493*cdf0e10cSrcweir if( ImpScan( aTmpString, aTmp.nDouble, t, NULL ) != SbxERR_OK ) 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir aTmp.nDouble = 0; 496*cdf0e10cSrcweir return sal_False; 497*cdf0e10cSrcweir } 498*cdf0e10cSrcweir break; 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir case SbxSTRING: 501*cdf0e10cSrcweir rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US ); 502*cdf0e10cSrcweir aVal = aTmpString; 503*cdf0e10cSrcweir break; 504*cdf0e10cSrcweir case SbxEMPTY: 505*cdf0e10cSrcweir case SbxNULL: 506*cdf0e10cSrcweir break; 507*cdf0e10cSrcweir default: 508*cdf0e10cSrcweir aData.eType = SbxNULL; 509*cdf0e10cSrcweir DBG_ASSERT( !this, "Nicht unterstuetzer Datentyp geladen" ); 510*cdf0e10cSrcweir return sal_False; 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir // Wert putten 513*cdf0e10cSrcweir if( nType != SbxNULL && nType != SbxEMPTY && !Put( aTmp ) ) 514*cdf0e10cSrcweir return sal_False; 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir rStrm >> cMark; 517*cdf0e10cSrcweir // cMark ist auch eine Versionsnummer! 518*cdf0e10cSrcweir // 1: initial version 519*cdf0e10cSrcweir // 2: mit nUserData 520*cdf0e10cSrcweir if( cMark ) 521*cdf0e10cSrcweir { 522*cdf0e10cSrcweir if( cMark > 2 ) 523*cdf0e10cSrcweir return sal_False; 524*cdf0e10cSrcweir pInfo = new SbxInfo; 525*cdf0e10cSrcweir pInfo->LoadData( rStrm, (sal_uInt16) cMark ); 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir // Privatdaten nur laden, wenn es eine SbxVariable ist 528*cdf0e10cSrcweir if( GetClass() == SbxCLASS_VARIABLE && !LoadPrivateData( rStrm, nVer ) ) 529*cdf0e10cSrcweir return sal_False; 530*cdf0e10cSrcweir ((SbxVariable*) this)->Broadcast( SBX_HINT_DATACHANGED ); 531*cdf0e10cSrcweir nHash = MakeHashCode( maName ); 532*cdf0e10cSrcweir SetModified( sal_True ); 533*cdf0e10cSrcweir return sal_True; 534*cdf0e10cSrcweir } 535*cdf0e10cSrcweir 536*cdf0e10cSrcweir sal_Bool SbxVariable::StoreData( SvStream& rStrm ) const 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir rStrm << (sal_uInt8) 0xFF; // Marker 539*cdf0e10cSrcweir sal_Bool bValStore; 540*cdf0e10cSrcweir if( this->IsA( TYPE(SbxMethod) ) ) 541*cdf0e10cSrcweir { 542*cdf0e10cSrcweir // #50200 Verhindern, dass Objekte, die zur Laufzeit als Return-Wert 543*cdf0e10cSrcweir // in der Methode als Value gespeichert sind, mit gespeichert werden 544*cdf0e10cSrcweir SbxVariable* pThis = (SbxVariable*)this; 545*cdf0e10cSrcweir sal_uInt16 nSaveFlags = GetFlags(); 546*cdf0e10cSrcweir pThis->SetFlag( SBX_WRITE ); 547*cdf0e10cSrcweir pThis->SbxValue::Clear(); 548*cdf0e10cSrcweir pThis->SetFlags( nSaveFlags ); 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir // Damit die Methode in keinem Fall ausgefuehrt wird! 551*cdf0e10cSrcweir // CAST, um const zu umgehen! 552*cdf0e10cSrcweir pThis->SetFlag( SBX_NO_BROADCAST ); 553*cdf0e10cSrcweir bValStore = SbxValue::StoreData( rStrm ); 554*cdf0e10cSrcweir pThis->ResetFlag( SBX_NO_BROADCAST ); 555*cdf0e10cSrcweir } 556*cdf0e10cSrcweir else 557*cdf0e10cSrcweir bValStore = SbxValue::StoreData( rStrm ); 558*cdf0e10cSrcweir if( !bValStore ) 559*cdf0e10cSrcweir return sal_False; 560*cdf0e10cSrcweir // if( !SbxValue::StoreData( rStrm ) ) 561*cdf0e10cSrcweir // return sal_False; 562*cdf0e10cSrcweir rStrm.WriteByteString( maName, RTL_TEXTENCODING_ASCII_US ); 563*cdf0e10cSrcweir rStrm << (sal_uInt32)nUserData; 564*cdf0e10cSrcweir if( pInfo.Is() ) 565*cdf0e10cSrcweir { 566*cdf0e10cSrcweir rStrm << (sal_uInt8) 2; // Version 2: mit UserData! 567*cdf0e10cSrcweir pInfo->StoreData( rStrm ); 568*cdf0e10cSrcweir } 569*cdf0e10cSrcweir else 570*cdf0e10cSrcweir rStrm << (sal_uInt8) 0; 571*cdf0e10cSrcweir // Privatdaten nur speichern, wenn es eine SbxVariable ist 572*cdf0e10cSrcweir if( GetClass() == SbxCLASS_VARIABLE ) 573*cdf0e10cSrcweir return StorePrivateData( rStrm ); 574*cdf0e10cSrcweir else 575*cdf0e10cSrcweir return sal_True; 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir ////////////////////////////// SbxInfo /////////////////////////////////// 579*cdf0e10cSrcweir 580*cdf0e10cSrcweir SbxInfo::SbxInfo() : aHelpFile(), nHelpId( 0 ), aParams() 581*cdf0e10cSrcweir {} 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir SbxInfo::SbxInfo( const String& r, sal_uInt32 n ) 584*cdf0e10cSrcweir : aHelpFile( r ), nHelpId( n ), aParams() 585*cdf0e10cSrcweir {} 586*cdf0e10cSrcweir 587*cdf0e10cSrcweir ////////////////////////////// SbxAlias ////////////////////////////////// 588*cdf0e10cSrcweir 589*cdf0e10cSrcweir SbxAlias::SbxAlias( const XubString& rName, SbxVariable* p ) 590*cdf0e10cSrcweir : SbxVariable(), xAlias( p ) 591*cdf0e10cSrcweir { 592*cdf0e10cSrcweir SetName( rName ); 593*cdf0e10cSrcweir SetFlags( p->GetFlags() ); 594*cdf0e10cSrcweir SetFlag( SBX_DONTSTORE ); 595*cdf0e10cSrcweir aData.eType = p->GetType(); 596*cdf0e10cSrcweir StartListening( p->GetBroadcaster() ); 597*cdf0e10cSrcweir } 598*cdf0e10cSrcweir 599*cdf0e10cSrcweir SbxAlias::SbxAlias( const SbxAlias& r ) 600*cdf0e10cSrcweir : SvRefBase( r ), SbxVariable( r ), 601*cdf0e10cSrcweir SfxListener( r ), xAlias( r.xAlias ) 602*cdf0e10cSrcweir {} 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir SbxAlias& SbxAlias::operator=( const SbxAlias& r ) 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir xAlias = r.xAlias; 607*cdf0e10cSrcweir return *this; 608*cdf0e10cSrcweir } 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir SbxAlias::~SbxAlias() 611*cdf0e10cSrcweir { 612*cdf0e10cSrcweir if( xAlias.Is() ) 613*cdf0e10cSrcweir EndListening( xAlias->GetBroadcaster() ); 614*cdf0e10cSrcweir } 615*cdf0e10cSrcweir 616*cdf0e10cSrcweir void SbxAlias::Broadcast( sal_uIntPtr nHt ) 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir if( xAlias.Is() && StaticIsEnabledBroadcasting() ) 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir xAlias->SetParameters( GetParameters() ); 621*cdf0e10cSrcweir if( nHt == SBX_HINT_DATAWANTED ) 622*cdf0e10cSrcweir SbxVariable::operator=( *xAlias ); 623*cdf0e10cSrcweir else if( nHt == SBX_HINT_DATACHANGED || nHt == SBX_HINT_CONVERTED ) 624*cdf0e10cSrcweir *xAlias = *this; 625*cdf0e10cSrcweir else if( nHt == SBX_HINT_INFOWANTED ) 626*cdf0e10cSrcweir { 627*cdf0e10cSrcweir xAlias->Broadcast( nHt ); 628*cdf0e10cSrcweir pInfo = xAlias->GetInfo(); 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir } 632*cdf0e10cSrcweir 633*cdf0e10cSrcweir void SbxAlias::SFX_NOTIFY( SfxBroadcaster&, const TypeId&, 634*cdf0e10cSrcweir const SfxHint& rHint, const TypeId& ) 635*cdf0e10cSrcweir { 636*cdf0e10cSrcweir const SbxHint* p = PTR_CAST(SbxHint,&rHint); 637*cdf0e10cSrcweir if( p && p->GetId() == SBX_HINT_DYING ) 638*cdf0e10cSrcweir { 639*cdf0e10cSrcweir xAlias.Clear(); 640*cdf0e10cSrcweir // Alias loeschen? 641*cdf0e10cSrcweir if( pParent ) 642*cdf0e10cSrcweir pParent->Remove( this ); 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir void SbxVariable::Dump( SvStream& rStrm, sal_Bool bFill ) 647*cdf0e10cSrcweir { 648*cdf0e10cSrcweir ByteString aBNameStr( (const UniString&)GetName( SbxNAME_SHORT_TYPES ), RTL_TEXTENCODING_ASCII_US ); 649*cdf0e10cSrcweir rStrm << "Variable( " 650*cdf0e10cSrcweir << ByteString::CreateFromInt64( (sal_uIntPtr) this ).GetBuffer() << "==" 651*cdf0e10cSrcweir << aBNameStr.GetBuffer(); 652*cdf0e10cSrcweir ByteString aBParentNameStr( (const UniString&)GetParent()->GetName(), RTL_TEXTENCODING_ASCII_US ); 653*cdf0e10cSrcweir if ( GetParent() ) 654*cdf0e10cSrcweir rStrm << " in parent '" << aBParentNameStr.GetBuffer() << "'"; 655*cdf0e10cSrcweir else 656*cdf0e10cSrcweir rStrm << " no parent"; 657*cdf0e10cSrcweir rStrm << " ) "; 658*cdf0e10cSrcweir 659*cdf0e10cSrcweir // bei Object-Vars auch das Object ausgeben 660*cdf0e10cSrcweir if ( GetValues_Impl().eType == SbxOBJECT && 661*cdf0e10cSrcweir GetValues_Impl().pObj && 662*cdf0e10cSrcweir GetValues_Impl().pObj != this && 663*cdf0e10cSrcweir GetValues_Impl().pObj != GetParent() ) 664*cdf0e10cSrcweir { 665*cdf0e10cSrcweir rStrm << " contains "; 666*cdf0e10cSrcweir ((SbxObject*) GetValues_Impl().pObj)->Dump( rStrm, bFill ); 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir else 669*cdf0e10cSrcweir rStrm << endl; 670*cdf0e10cSrcweir } 671*cdf0e10cSrcweir 672