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