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 <tools/stream.hxx>
21 : #include <svl/brdcst.hxx>
22 :
23 : #include <basic/sbx.hxx>
24 : #include "runtime.hxx"
25 : #include "sbxres.hxx"
26 : #include "sbxconv.hxx"
27 : #include "sbunoobj.hxx"
28 : #include <math.h>
29 : #include <ctype.h>
30 :
31 : #include <com/sun/star/uno/XInterface.hpp>
32 : using namespace com::sun::star::uno;
33 :
34 : ///////////////////////////// SbxVariable
35 :
36 0 : TYPEINIT1(SbxVariable,SbxValue)
37 0 : TYPEINIT1(SbxHint,SfxSimpleHint)
38 :
39 : ///////////////////////////// SbxVariableImpl
40 :
41 0 : class SbxVariableImpl
42 : {
43 : friend class SbxVariable;
44 : OUString m_aDeclareClassName;
45 : Reference< XInterface > m_xComListener;
46 : StarBASIC* m_pComListenerParentBasic;
47 :
48 0 : SbxVariableImpl( void )
49 0 : : m_pComListenerParentBasic( NULL )
50 0 : {}
51 0 : SbxVariableImpl( const SbxVariableImpl& r )
52 : : m_aDeclareClassName( r.m_aDeclareClassName )
53 : , m_xComListener( r.m_xComListener )
54 0 : , m_pComListenerParentBasic( r.m_pComListenerParentBasic )
55 : {
56 0 : }
57 : };
58 :
59 :
60 : ///////////////////////////// Constructors
61 :
62 0 : SbxVariable::SbxVariable() : SbxValue()
63 : {
64 0 : mpSbxVariableImpl = NULL;
65 0 : pCst = NULL;
66 0 : pParent = NULL;
67 0 : nUserData = 0;
68 0 : nHash = 0;
69 0 : }
70 :
71 0 : SbxVariable::SbxVariable( const SbxVariable& r )
72 : : SvRefBase( r ),
73 : SbxValue( r ),
74 : mpPar( r.mpPar ),
75 0 : pInfo( r.pInfo )
76 : {
77 0 : mpSbxVariableImpl = NULL;
78 0 : if( r.mpSbxVariableImpl != NULL )
79 : {
80 0 : mpSbxVariableImpl = new SbxVariableImpl( *r.mpSbxVariableImpl );
81 : #ifndef DISABLE_SCRIPTING
82 0 : if( mpSbxVariableImpl->m_xComListener.is() )
83 : {
84 0 : registerComListenerVariableForBasic( this, mpSbxVariableImpl->m_pComListenerParentBasic );
85 : }
86 : #endif
87 : }
88 0 : pCst = NULL;
89 0 : if( r.CanRead() )
90 : {
91 0 : pParent = r.pParent;
92 0 : nUserData = r.nUserData;
93 0 : maName = r.maName;
94 0 : nHash = r.nHash;
95 : }
96 : else
97 : {
98 0 : pParent = NULL;
99 0 : nUserData = 0;
100 0 : nHash = 0;
101 : }
102 0 : }
103 :
104 0 : SbxVariable::SbxVariable( SbxDataType t, void* p ) : SbxValue( t, p )
105 : {
106 0 : mpSbxVariableImpl = NULL;
107 0 : pCst = NULL;
108 0 : pParent = NULL;
109 0 : nUserData = 0;
110 0 : nHash = 0;
111 0 : }
112 :
113 0 : SbxVariable::~SbxVariable()
114 : {
115 : #ifndef DISABLE_SCRIPTING
116 0 : if( IsSet( SBX_DIM_AS_NEW ))
117 : {
118 0 : removeDimAsNewRecoverItem( this );
119 : }
120 : #endif
121 0 : delete mpSbxVariableImpl;
122 0 : delete pCst;
123 0 : }
124 :
125 : ////////////////////////////// Broadcasting
126 :
127 0 : SfxBroadcaster& SbxVariable::GetBroadcaster()
128 : {
129 0 : if( !pCst )
130 : {
131 0 : pCst = new SfxBroadcaster;
132 : }
133 0 : return *pCst;
134 : }
135 :
136 0 : SbxArray* SbxVariable::GetParameters() const
137 : {
138 0 : return mpPar;
139 : }
140 :
141 0 : SbxObject* SbxVariable::GetParent()
142 : {
143 0 : return pParent;
144 : }
145 :
146 : // Perhaps some day one could cut the parameter 0.
147 : // then the copying will be dropped ...
148 :
149 0 : void SbxVariable::Broadcast( sal_uIntPtr nHintId )
150 : {
151 0 : if( pCst && !IsSet( SBX_NO_BROADCAST ) )
152 : {
153 : // Because the method could be called from outside, check the
154 : // rights here again
155 0 : if( nHintId & SBX_HINT_DATAWANTED )
156 : {
157 0 : if( !CanRead() )
158 : {
159 0 : return;
160 : }
161 : }
162 0 : if( nHintId & SBX_HINT_DATACHANGED )
163 : {
164 0 : if( !CanWrite() )
165 : {
166 0 : return;
167 : }
168 : }
169 : // Avoid further broadcasting
170 0 : SfxBroadcaster* pSave = pCst;
171 0 : pCst = NULL;
172 0 : sal_uInt16 nSaveFlags = GetFlags();
173 0 : SetFlag( SBX_READWRITE );
174 0 : if( mpPar.Is() )
175 : {
176 : // Register this as element 0, but don't change over the parent!
177 0 : mpPar->GetRef( 0 ) = this;
178 : }
179 0 : pSave->Broadcast( SbxHint( nHintId, this ) );
180 0 : delete pCst; // who knows already, onto which thoughts someone comes?
181 0 : pCst = pSave;
182 0 : SetFlags( nSaveFlags );
183 : }
184 : }
185 :
186 0 : SbxInfo* SbxVariable::GetInfo()
187 : {
188 0 : if( !pInfo )
189 : {
190 0 : Broadcast( SBX_HINT_INFOWANTED );
191 0 : if( pInfo.Is() )
192 : {
193 0 : SetModified( true );
194 : }
195 : }
196 0 : return pInfo;
197 : }
198 :
199 0 : void SbxVariable::SetInfo( SbxInfo* p )
200 : {
201 0 : pInfo = p;
202 0 : }
203 :
204 0 : void SbxVariable::SetParameters( SbxArray* p )
205 : {
206 0 : mpPar = p;
207 0 : }
208 :
209 :
210 : /////////////////////////// Name of the variables
211 :
212 0 : void SbxVariable::SetName( const OUString& rName )
213 : {
214 0 : maName = rName;
215 0 : nHash = MakeHashCode( rName );
216 0 : }
217 :
218 0 : const OUString& SbxVariable::GetName( SbxNameType t ) const
219 : {
220 : static const char cSuffixes[] = " %&!#@ $";
221 0 : if( t == SbxNAME_NONE )
222 : {
223 0 : return maName;
224 : }
225 : // Request parameter-information (not for objects)
226 0 : ((SbxVariable*)this)->GetInfo();
227 : // Append nothing, if it is a simple property (no empty brackets)
228 0 : if( !pInfo || ( pInfo->aParams.empty() && GetClass() == SbxCLASS_PROPERTY ))
229 : {
230 0 : return maName;
231 : }
232 0 : sal_Unicode cType = ' ';
233 0 : OUString aTmp( maName );
234 : // short type? Then fetch it, posible this is 0.
235 0 : SbxDataType et = GetType();
236 0 : if( t == SbxNAME_SHORT_TYPES )
237 : {
238 0 : if( et <= SbxSTRING )
239 : {
240 0 : cType = cSuffixes[ et ];
241 : }
242 0 : if( cType != ' ' )
243 : {
244 0 : aTmp += OUString(sal_Unicode(cType));
245 : }
246 : }
247 0 : aTmp += "(";
248 :
249 0 : for(SbxParams::const_iterator i = pInfo->aParams.begin(); i != pInfo->aParams.end(); ++i)
250 : {
251 0 : int nt = i->eType & 0x0FFF;
252 0 : if( i != pInfo->aParams.begin() )
253 : {
254 0 : aTmp += ",";
255 : }
256 0 : if( i->nFlags & SBX_OPTIONAL )
257 : {
258 0 : aTmp += OUString( SbxRes( STRING_OPTIONAL ) );
259 : }
260 0 : if( i->eType & SbxBYREF )
261 : {
262 0 : aTmp += OUString( SbxRes( STRING_BYREF ) );
263 : }
264 0 : aTmp += i->aName;
265 0 : cType = ' ';
266 : // short type? Then fetch it, posible this is 0.
267 0 : if( t == SbxNAME_SHORT_TYPES )
268 : {
269 0 : if( nt <= SbxSTRING )
270 : {
271 0 : cType = cSuffixes[ nt ];
272 : }
273 : }
274 0 : if( cType != ' ' )
275 : {
276 0 : aTmp += OUString((sal_Unicode)cType);
277 0 : if( i->eType & SbxARRAY )
278 : {
279 0 : aTmp += "()";
280 : }
281 : }
282 : else
283 : {
284 0 : if( i->eType & SbxARRAY )
285 : {
286 0 : aTmp += "()";
287 : }
288 : // long type?
289 0 : if( t != SbxNAME_SHORT )
290 : {
291 0 : aTmp += OUString( SbxRes( STRING_AS ) );
292 0 : if( nt < 32 )
293 : {
294 0 : aTmp += OUString( SbxRes( sal::static_int_cast< sal_uInt16 >( STRING_TYPES + nt ) ) );
295 : }
296 : else
297 : {
298 0 : aTmp += OUString( SbxRes( STRING_ANY ) );
299 : }
300 : }
301 : }
302 : }
303 0 : aTmp += ")";
304 : // Long type? Then fetch it
305 0 : if( t == SbxNAME_LONG_TYPES && et != SbxEMPTY )
306 : {
307 0 : aTmp += OUString( SbxRes( STRING_AS ) );
308 0 : if( et < 32 )
309 : {
310 0 : aTmp += OUString( SbxRes( sal::static_int_cast< sal_uInt16 >( STRING_TYPES + et ) ) );
311 : }
312 : else
313 : {
314 0 : aTmp += OUString( SbxRes( STRING_ANY ) );
315 : }
316 : }
317 0 : ((SbxVariable*) this)->aToolString = aTmp;
318 0 : return aToolString;
319 : }
320 :
321 : // Create a simple hashcode: the first six characters were evaluated.
322 :
323 0 : sal_uInt16 SbxVariable::MakeHashCode( const OUString& rName )
324 : {
325 0 : sal_uInt16 n = 0;
326 0 : sal_Int32 i = 0;
327 0 : sal_uInt16 nLen = rName.getLength();
328 0 : if( nLen > 6 )
329 : {
330 0 : nLen = 6;
331 : }
332 0 : while( nLen-- )
333 : {
334 0 : sal_uInt8 c = (sal_uInt8)rName[i++];
335 : // If we have a commen sigen break!!
336 0 : if( c >= 0x80 )
337 : {
338 0 : return 0;
339 : }
340 0 : n = sal::static_int_cast< sal_uInt16 >( ( n << 3 ) + toupper( c ) );
341 : }
342 0 : return n;
343 : }
344 :
345 : ////////////////////////////// Operators
346 :
347 0 : SbxVariable& SbxVariable::operator=( const SbxVariable& r )
348 : {
349 0 : SbxValue::operator=( r );
350 0 : delete mpSbxVariableImpl;
351 0 : if( r.mpSbxVariableImpl != NULL )
352 : {
353 0 : mpSbxVariableImpl = new SbxVariableImpl( *r.mpSbxVariableImpl );
354 : #ifndef DISABLE_SCRIPTING
355 0 : if( mpSbxVariableImpl->m_xComListener.is() )
356 : {
357 0 : registerComListenerVariableForBasic( this, mpSbxVariableImpl->m_pComListenerParentBasic );
358 : }
359 : #endif
360 : }
361 : else
362 : {
363 0 : mpSbxVariableImpl = NULL;
364 : }
365 0 : return *this;
366 : }
367 :
368 : //////////////////////////////// Conversion
369 :
370 0 : SbxDataType SbxVariable::GetType() const
371 : {
372 0 : if( aData.eType == SbxOBJECT )
373 : {
374 0 : return aData.pObj ? aData.pObj->GetType() : SbxOBJECT;
375 : }
376 0 : else if( aData.eType == SbxVARIANT )
377 : {
378 0 : return aData.pObj ? aData.pObj->GetType() : SbxVARIANT;
379 : }
380 : else
381 : {
382 0 : return aData.eType;
383 : }
384 : }
385 :
386 0 : SbxClassType SbxVariable::GetClass() const
387 : {
388 0 : return SbxCLASS_VARIABLE;
389 : }
390 :
391 0 : void SbxVariable::SetModified( bool b )
392 : {
393 0 : if( IsSet( SBX_NO_MODIFY ) )
394 : {
395 0 : return;
396 : }
397 0 : SbxBase::SetModified( b );
398 0 : if( pParent && pParent != this ) //??? HotFix: Recursion out here MM
399 : {
400 0 : pParent->SetModified( b );
401 : }
402 : }
403 :
404 0 : void SbxVariable::SetParent( SbxObject* p )
405 : {
406 : #ifdef DBG_UTIL
407 : // Will the parent of a SbxObject be set?
408 : if ( p && ISA(SbxObject) )
409 : {
410 : // then this had to be a child of the new parent
411 : bool bFound = false;
412 : SbxArray *pChildren = p->GetObjects();
413 : if ( pChildren )
414 : {
415 : for ( sal_uInt16 nIdx = 0; !bFound && nIdx < pChildren->Count(); ++nIdx )
416 : {
417 : bFound = ( this == pChildren->Get(nIdx) );
418 : }
419 : }
420 : SAL_WARN_IF(
421 : !bFound, "basic.sbx",
422 : "dangling: [" << GetName() << "].SetParent([" << p->GetName()
423 : << "])");
424 : }
425 : #endif
426 :
427 0 : pParent = p;
428 0 : }
429 :
430 0 : SbxVariableImpl* SbxVariable::getImpl( void )
431 : {
432 0 : if( mpSbxVariableImpl == NULL )
433 : {
434 0 : mpSbxVariableImpl = new SbxVariableImpl();
435 : }
436 0 : return mpSbxVariableImpl;
437 : }
438 :
439 0 : const OUString& SbxVariable::GetDeclareClassName( void )
440 : {
441 0 : SbxVariableImpl* pImpl = getImpl();
442 0 : return pImpl->m_aDeclareClassName;
443 : }
444 :
445 0 : void SbxVariable::SetDeclareClassName( const OUString& rDeclareClassName )
446 : {
447 0 : SbxVariableImpl* pImpl = getImpl();
448 0 : pImpl->m_aDeclareClassName = rDeclareClassName;
449 0 : }
450 :
451 0 : void SbxVariable::SetComListener( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xComListener,
452 : StarBASIC* pParentBasic )
453 : {
454 0 : SbxVariableImpl* pImpl = getImpl();
455 0 : pImpl->m_xComListener = xComListener;
456 0 : pImpl->m_pComListenerParentBasic = pParentBasic;
457 : #ifndef DISABLE_SCRIPTING
458 0 : registerComListenerVariableForBasic( this, pParentBasic );
459 : #endif
460 0 : }
461 :
462 0 : void SbxVariable::ClearComListener( void )
463 : {
464 0 : SbxVariableImpl* pImpl = getImpl();
465 0 : pImpl->m_xComListener.clear();
466 0 : }
467 :
468 :
469 : ////////////////////////////// Loading/Saving
470 :
471 0 : bool SbxVariable::LoadData( SvStream& rStrm, sal_uInt16 nVer )
472 : {
473 : sal_uInt16 nType;
474 : sal_uInt8 cMark;
475 0 : rStrm.ReadUChar( cMark );
476 0 : if( cMark == 0xFF )
477 : {
478 0 : if( !SbxValue::LoadData( rStrm, nVer ) )
479 : {
480 0 : return false;
481 : }
482 0 : maName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rStrm,
483 0 : RTL_TEXTENCODING_ASCII_US);
484 : sal_uInt32 nTemp;
485 0 : rStrm.ReadUInt32( nTemp );
486 0 : nUserData = nTemp;
487 : }
488 : else
489 : {
490 0 : rStrm.SeekRel( -1L );
491 0 : rStrm.ReadUInt16( nType );
492 0 : maName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rStrm,
493 0 : RTL_TEXTENCODING_ASCII_US);
494 : sal_uInt32 nTemp;
495 0 : rStrm.ReadUInt32( nTemp );
496 0 : nUserData = nTemp;
497 : // correction: old methods have instead of SbxNULL now SbxEMPTY
498 0 : if( nType == SbxNULL && GetClass() == SbxCLASS_METHOD )
499 : {
500 0 : nType = SbxEMPTY;
501 : }
502 0 : SbxValues aTmp;
503 0 : OUString aTmpString;
504 0 : OUString aVal;
505 0 : aTmp.eType = aData.eType = (SbxDataType) nType;
506 0 : aTmp.pOUString = &aVal;
507 0 : switch( nType )
508 : {
509 : case SbxBOOL:
510 : case SbxERROR:
511 : case SbxINTEGER:
512 0 : rStrm.ReadInt16( aTmp.nInteger ); break;
513 : case SbxLONG:
514 0 : rStrm.ReadInt32( aTmp.nLong ); break;
515 : case SbxSINGLE:
516 : {
517 : // Floats as ASCII
518 0 : aTmpString = read_uInt16_lenPrefixed_uInt8s_ToOUString(
519 0 : rStrm, RTL_TEXTENCODING_ASCII_US);
520 : double d;
521 : SbxDataType t;
522 0 : if( ImpScan( aTmpString, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE )
523 : {
524 0 : aTmp.nSingle = 0;
525 0 : return false;
526 : }
527 0 : aTmp.nSingle = (float) d;
528 0 : break;
529 : }
530 : case SbxDATE:
531 : case SbxDOUBLE:
532 : {
533 : // Floats as ASCII
534 0 : aTmpString = read_uInt16_lenPrefixed_uInt8s_ToOUString(rStrm,
535 0 : RTL_TEXTENCODING_ASCII_US);
536 : SbxDataType t;
537 0 : if( ImpScan( aTmpString, aTmp.nDouble, t, NULL ) != SbxERR_OK )
538 : {
539 0 : aTmp.nDouble = 0;
540 0 : return false;
541 : }
542 0 : break;
543 : }
544 : case SbxSTRING:
545 0 : aVal = read_uInt16_lenPrefixed_uInt8s_ToOUString(rStrm,
546 0 : RTL_TEXTENCODING_ASCII_US);
547 0 : break;
548 : case SbxEMPTY:
549 : case SbxNULL:
550 0 : break;
551 : default:
552 0 : aData.eType = SbxNULL;
553 : DBG_ASSERT( !this, "Loaded a non-supported data type" );
554 0 : return false;
555 : }
556 : // putt value
557 0 : if( nType != SbxNULL && nType != SbxEMPTY && !Put( aTmp ) )
558 : {
559 0 : return false;
560 0 : }
561 : }
562 0 : rStrm.ReadUChar( cMark );
563 : // cMark is also a version number!
564 : // 1: initial version
565 : // 2: with nUserData
566 0 : if( cMark )
567 : {
568 0 : if( cMark > 2 )
569 : {
570 0 : return false;
571 : }
572 0 : pInfo = new SbxInfo;
573 0 : pInfo->LoadData( rStrm, (sal_uInt16) cMark );
574 : }
575 : // Load private data only, if it is a SbxVariable
576 0 : if( GetClass() == SbxCLASS_VARIABLE && !LoadPrivateData( rStrm, nVer ) )
577 : {
578 0 : return false;
579 : }
580 0 : ((SbxVariable*) this)->Broadcast( SBX_HINT_DATACHANGED );
581 0 : nHash = MakeHashCode( maName );
582 0 : SetModified( true );
583 0 : return true;
584 : }
585 :
586 0 : bool SbxVariable::StoreData( SvStream& rStrm ) const
587 : {
588 0 : rStrm.WriteUChar( (sal_uInt8) 0xFF ); // Marker
589 : bool bValStore;
590 0 : if( this->IsA( TYPE(SbxMethod) ) )
591 : {
592 : // #50200 Avoid that objects , which during the runtime
593 : // as return-value are saved in the method as a value were saved
594 0 : SbxVariable* pThis = (SbxVariable*)this;
595 0 : sal_uInt16 nSaveFlags = GetFlags();
596 0 : pThis->SetFlag( SBX_WRITE );
597 0 : pThis->SbxValue::Clear();
598 0 : pThis->SetFlags( nSaveFlags );
599 :
600 : // So that the method will not be executed in any case!
601 : // CAST, to avoid const!
602 0 : pThis->SetFlag( SBX_NO_BROADCAST );
603 0 : bValStore = SbxValue::StoreData( rStrm );
604 0 : pThis->ResetFlag( SBX_NO_BROADCAST );
605 : }
606 : else
607 : {
608 0 : bValStore = SbxValue::StoreData( rStrm );
609 : }
610 0 : if( !bValStore )
611 : {
612 0 : return false;
613 : }
614 : write_uInt16_lenPrefixed_uInt8s_FromOUString(rStrm, maName,
615 0 : RTL_TEXTENCODING_ASCII_US);
616 0 : rStrm.WriteUInt32( (sal_uInt32)nUserData );
617 0 : if( pInfo.Is() )
618 : {
619 0 : rStrm.WriteUChar( (sal_uInt8) 2 ); // Version 2: with UserData!
620 0 : pInfo->StoreData( rStrm );
621 : }
622 : else
623 : {
624 0 : rStrm.WriteUChar( (sal_uInt8) 0 );
625 : }
626 : // Save private data only, if it is a SbxVariable
627 0 : if( GetClass() == SbxCLASS_VARIABLE )
628 : {
629 0 : return StorePrivateData( rStrm );
630 : }
631 : else
632 : {
633 0 : return true;
634 : }
635 : }
636 :
637 : ////////////////////////////// SbxInfo
638 :
639 0 : SbxInfo::SbxInfo() : aHelpFile(), nHelpId( 0 ), aParams()
640 0 : {}
641 :
642 0 : SbxInfo::SbxInfo( const OUString& r, sal_uInt32 n )
643 0 : : aHelpFile( r ), nHelpId( n ), aParams()
644 0 : {}
645 :
646 : ////////////////////////////// SbxAlias
647 :
648 0 : SbxAlias::SbxAlias( const SbxAlias& r )
649 : : SvRefBase( r ), SbxVariable( r ),
650 0 : SfxListener( r ), xAlias( r.xAlias )
651 0 : {}
652 :
653 0 : SbxAlias& SbxAlias::operator=( const SbxAlias& r )
654 : {
655 0 : xAlias = r.xAlias;
656 0 : return *this;
657 : }
658 :
659 0 : SbxAlias::~SbxAlias()
660 : {
661 0 : if( xAlias.Is() )
662 : {
663 0 : EndListening( xAlias->GetBroadcaster() );
664 : }
665 0 : }
666 :
667 0 : void SbxAlias::Broadcast( sal_uIntPtr nHt )
668 : {
669 0 : if( xAlias.Is() )
670 : {
671 0 : xAlias->SetParameters( GetParameters() );
672 0 : if( nHt == SBX_HINT_DATAWANTED )
673 : {
674 0 : SbxVariable::operator=( *xAlias );
675 : }
676 0 : else if( nHt == SBX_HINT_DATACHANGED || nHt == SBX_HINT_CONVERTED )
677 : {
678 0 : *xAlias = *this;
679 : }
680 0 : else if( nHt == SBX_HINT_INFOWANTED )
681 : {
682 0 : xAlias->Broadcast( nHt );
683 0 : pInfo = xAlias->GetInfo();
684 : }
685 : }
686 0 : }
687 :
688 0 : void SbxAlias::SFX_NOTIFY( SfxBroadcaster&, const TypeId&,
689 : const SfxHint& rHint, const TypeId& )
690 : {
691 0 : const SbxHint* p = PTR_CAST(SbxHint,&rHint);
692 0 : if( p && p->GetId() == SBX_HINT_DYING )
693 : {
694 0 : xAlias.Clear();
695 : // delete the alias?
696 0 : if( pParent )
697 : {
698 0 : pParent->Remove( this );
699 : }
700 : }
701 0 : }
702 :
703 0 : void SbxVariable::Dump( SvStream& rStrm, bool bFill )
704 : {
705 0 : OString aBNameStr(OUStringToOString(GetName( SbxNAME_SHORT_TYPES ), RTL_TEXTENCODING_ASCII_US));
706 0 : rStrm.WriteCharPtr( "Variable( " )
707 0 : .WriteCharPtr( OString::number(reinterpret_cast<sal_Int64>(this)).getStr() ).WriteCharPtr( "==" )
708 0 : .WriteCharPtr( aBNameStr.getStr() );
709 0 : OString aBParentNameStr(OUStringToOString(GetParent()->GetName(), RTL_TEXTENCODING_ASCII_US));
710 0 : if ( GetParent() )
711 : {
712 0 : rStrm.WriteCharPtr( " in parent '" ).WriteCharPtr( aBParentNameStr.getStr() ).WriteCharPtr( "'" );
713 : }
714 : else
715 : {
716 0 : rStrm.WriteCharPtr( " no parent" );
717 : }
718 0 : rStrm.WriteCharPtr( " ) " );
719 :
720 : // output also the object at object-vars
721 0 : if ( GetValues_Impl().eType == SbxOBJECT &&
722 0 : GetValues_Impl().pObj &&
723 0 : GetValues_Impl().pObj != this &&
724 0 : GetValues_Impl().pObj != GetParent() )
725 : {
726 0 : rStrm.WriteCharPtr( " contains " );
727 0 : ((SbxObject*) GetValues_Impl().pObj)->Dump( rStrm, bFill );
728 : }
729 : else
730 : {
731 0 : rStrm << endl;
732 0 : }
733 0 : }
734 :
735 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|