1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sbxbase.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
35 #include <tools/shl.hxx>
36 #include <tools/stream.hxx>
38 #include <basic/sbx.hxx>
39 #include <basic/sbxfac.hxx>
40 #include <basic/sbxbase.hxx>
42 // AppData-Struktur fuer SBX:
44 SV_IMPL_PTRARR(SbxParams
,SbxParamInfo
*);
45 SV_IMPL_PTRARR(SbxFacs
,SbxFactory
*);
49 // SBX-Daten anfordern oder ggf. anlegen
50 // wir legen den Bereich einfach an und verzichten auf die Freigabe!
52 SbxAppData
* GetSbxData_Impl()
55 SbxAppData
** ppData
= (SbxAppData
**) ::GetAppData( SHL_SBX
);
56 SbxAppData
* p
= *ppData
;
58 p
= *ppData
= new SbxAppData
;
63 p
= *ppData
= new SbxAppData
;
68 SbxAppData::~SbxAppData()
71 delete pBasicFormater
;
75 //////////////////////////////// SbxBase /////////////////////////////////
81 DBG_CTOR( SbxBase
, 0 );
82 nFlags
= SBX_READWRITE
;
85 SbxBase::SbxBase( const SbxBase
& r
)
88 DBG_CTOR( SbxBase
, 0 );
97 SbxBase
& SbxBase::operator=( const SbxBase
& r
)
99 DBG_CHKTHIS( SbxBase
, 0 );
104 SbxDataType
SbxBase::GetType() const
106 DBG_CHKTHIS( SbxBase
, 0 );
110 SbxClassType
SbxBase::GetClass() const
112 DBG_CHKTHIS( SbxBase
, 0 );
113 return SbxCLASS_DONTCARE
;
116 void SbxBase::Clear()
118 DBG_CHKTHIS( SbxBase
, 0 );
121 BOOL
SbxBase::IsFixed() const
123 DBG_CHKTHIS( SbxBase
, 0 );
124 return IsSet( SBX_FIXED
);
127 void SbxBase::SetModified( BOOL b
)
129 DBG_CHKTHIS( SbxBase
, 0 );
130 if( IsSet( SBX_NO_MODIFY
) )
133 SetFlag( SBX_MODIFIED
);
135 ResetFlag( SBX_MODIFIED
);
138 SbxError
SbxBase::GetError()
140 return GetSbxData_Impl()->eSbxError
;
143 void SbxBase::SetError( SbxError e
)
145 SbxAppData
* p
= GetSbxData_Impl();
146 if( e
&& p
->eSbxError
== SbxERR_OK
)
150 BOOL
SbxBase::IsError()
152 return BOOL( GetSbxData_Impl()->eSbxError
!= SbxERR_OK
);
155 void SbxBase::ResetError()
157 GetSbxData_Impl()->eSbxError
= SbxERR_OK
;
160 void SbxBase::AddFactory( SbxFactory
* pFac
)
162 SbxAppData
* p
= GetSbxData_Impl();
163 const SbxFactory
* pTemp
= pFac
;
165 // AB, 6.3.96: HandleLast-Flag beruecksichtigen
166 USHORT nPos
= p
->aFacs
.Count(); // Einfuege-Position
167 if( !pFac
->IsHandleLast() ) // Nur, wenn nicht selbst HandleLast
169 // Neue Factory vor Factories mit HandleLast einordnen
171 (static_cast<SbxFactory
*>(p
->aFacs
.GetObject( nPos
-1 )))->IsHandleLast() )
174 p
->aFacs
.Insert( pTemp
, nPos
);
177 void SbxBase::RemoveFactory( SbxFactory
* pFac
)
179 SbxAppData
* p
= GetSbxData_Impl();
180 for( USHORT i
= 0; i
< p
->aFacs
.Count(); i
++ )
182 if( p
->aFacs
.GetObject( i
) == pFac
)
184 p
->aFacs
.Remove( i
, 1 ); break;
190 SbxBase
* SbxBase::Create( UINT16 nSbxId
, UINT32 nCreator
)
192 // #91626: Hack to skip old Basic dialogs
193 // Problem: There does not exist a factory any more,
194 // so we have to create a dummy SbxVariable instead
195 if( nSbxId
== 0x65 ) // Dialog Id
196 return new SbxVariable
;
199 if( nCreator
== SBXCR_SBX
)
202 case SBXID_VALUE
: return new SbxValue
;
203 case SBXID_VARIABLE
: return new SbxVariable
;
204 case SBXID_ARRAY
: return new SbxArray
;
205 case SBXID_DIMARRAY
: return new SbxDimArray
;
206 case SBXID_OBJECT
: return new SbxObject( aEmptyStr
);
207 case SBXID_COLLECTION
: return new SbxCollection( aEmptyStr
);
208 case SBXID_FIXCOLLECTION
:
209 return new SbxStdCollection( aEmptyStr
, aEmptyStr
);
210 case SBXID_METHOD
: return new SbxMethod( aEmptyStr
, SbxEMPTY
);
211 case SBXID_PROPERTY
: return new SbxProperty( aEmptyStr
, SbxEMPTY
);
213 // Unbekanter Typ: �ber die Factories gehen!
214 SbxAppData
* p
= GetSbxData_Impl();
215 SbxBase
* pNew
= NULL
;
216 for( USHORT i
= 0; i
< p
->aFacs
.Count(); i
++ )
218 SbxFactory
* pFac
= p
->aFacs
.GetObject( i
);
219 pNew
= pFac
->Create( nSbxId
, nCreator
);
226 ByteString
aMsg( "SBX: Keine Factory fuer SBX-ID " );
227 aMsg
+= ByteString::CreateFromInt32(nSbxId
);
228 DbgError( aMsg
.GetBuffer() );
234 SbxObject
* SbxBase::CreateObject( const XubString
& rClass
)
236 SbxAppData
* p
= GetSbxData_Impl();
237 SbxObject
* pNew
= NULL
;
238 for( USHORT i
= 0; i
< p
->aFacs
.Count(); i
++ )
240 pNew
= p
->aFacs
.GetObject( i
)->CreateObject( rClass
);
247 ByteString
aMsg( "SBX: Keine Factory fuer Objektklasse " );
248 ByteString
aClassStr( (const UniString
&)rClass
, RTL_TEXTENCODING_ASCII_US
);
250 DbgError( (const char*)aMsg
.GetBuffer() );
256 static BOOL bStaticEnableBroadcasting
= TRUE
;
258 // Sbx-Loesung als Ersatz fuer SfxBroadcaster::Enable()
259 void SbxBase::StaticEnableBroadcasting( BOOL bEnable
)
261 bStaticEnableBroadcasting
= bEnable
;
264 BOOL
SbxBase::StaticIsEnabledBroadcasting( void )
266 return bStaticEnableBroadcasting
;
270 SbxBase
* SbxBase::Load( SvStream
& rStrm
)
272 UINT16 nSbxId
, nFlags
, nVer
;
273 UINT32 nCreator
, nSize
;
274 rStrm
>> nCreator
>> nSbxId
>> nFlags
>> nVer
;
276 // Eine Dummheit meinerseits korrigieren:
277 if( nFlags
& SBX_RESERVED
)
278 nFlags
= ( nFlags
& ~SBX_RESERVED
) | SBX_GBLSEARCH
;
280 ULONG nOldPos
= rStrm
.Tell();
282 SbxBase
* p
= Create( nSbxId
, nCreator
);
286 if( p
->LoadData( rStrm
, nVer
) )
288 ULONG nNewPos
= rStrm
.Tell();
290 DBG_ASSERT( nOldPos
>= nNewPos
, "SBX: Zu viele Daten eingelesen" );
291 if( nOldPos
!= nNewPos
)
292 rStrm
.Seek( nOldPos
);
293 if( !p
->LoadCompleted() )
295 // Loeschen des Objekts
296 SbxBaseRef
aRef( p
);
302 rStrm
.SetError( SVSTREAM_FILEFORMAT_ERROR
);
303 // Loeschen des Objekts
304 SbxBaseRef
aRef( p
);
309 rStrm
.SetError( SVSTREAM_FILEFORMAT_ERROR
);
313 // Sbx-Objekt im Stream ueberspringen
314 void SbxBase::Skip( SvStream
& rStrm
)
316 UINT16 nSbxId
, nFlags
, nVer
;
317 UINT32 nCreator
, nSize
;
318 rStrm
>> nCreator
>> nSbxId
>> nFlags
>> nVer
;
320 ULONG nStartPos
= rStrm
.Tell();
323 rStrm
.Seek( nStartPos
+ nSize
);
326 BOOL
SbxBase::Store( SvStream
& rStrm
)
328 DBG_CHKTHIS( SbxBase
, 0 );
329 if( !( nFlags
& SBX_DONTSTORE
) )
331 rStrm
<< (UINT32
) GetCreator()
332 << (UINT16
) GetSbxId()
333 << (UINT16
) GetFlags()
334 << (UINT16
) GetVersion();
335 ULONG nOldPos
= rStrm
.Tell();
336 rStrm
<< (UINT32
) 0L;
337 BOOL bRes
= StoreData( rStrm
);
338 ULONG nNewPos
= rStrm
.Tell();
339 rStrm
.Seek( nOldPos
);
340 rStrm
<< (UINT32
) ( nNewPos
- nOldPos
);
341 rStrm
.Seek( nNewPos
);
342 if( rStrm
.GetError() != SVSTREAM_OK
)
345 bRes
= StoreCompleted();
352 BOOL
SbxBase::LoadData( SvStream
&, USHORT
)
354 DBG_CHKTHIS( SbxBase
, 0 );
358 BOOL
SbxBase::StoreData( SvStream
& ) const
360 DBG_CHKTHIS( SbxBase
, 0 );
364 BOOL
SbxBase::LoadPrivateData( SvStream
&, USHORT
)
366 DBG_CHKTHIS( SbxBase
, 0 );
370 BOOL
SbxBase::StorePrivateData( SvStream
& ) const
372 DBG_CHKTHIS( SbxBase
, 0 );
376 BOOL
SbxBase::LoadCompleted()
378 DBG_CHKTHIS( SbxBase
, 0 );
382 BOOL
SbxBase::StoreCompleted()
384 DBG_CHKTHIS( SbxBase
, 0 );
388 //////////////////////////////// SbxFactory ////////////////////////////////
390 SbxBase
* SbxFactory::Create( UINT16
, UINT32
)
395 SbxObject
* SbxFactory::CreateObject( const XubString
& )
400 ///////////////////////////////// SbxInfo //////////////////////////////////
405 void SbxInfo::AddParam
406 ( const XubString
& rName
, SbxDataType eType
, USHORT nFlags
)
408 const SbxParamInfo
* p
= new SbxParamInfo( rName
, eType
, nFlags
);
409 aParams
.Insert( p
, aParams
.Count() );
412 void SbxInfo::AddParam( const SbxParamInfo
& r
)
414 const SbxParamInfo
* p
= new SbxParamInfo
415 ( r
.aName
, r
.eType
, r
.nFlags
, r
.aTypeRef
);
416 aParams
.Insert( p
, aParams
.Count() );
419 const SbxParamInfo
* SbxInfo::GetParam( USHORT n
) const
421 if( n
< 1 || n
> aParams
.Count() )
424 return aParams
.GetObject( n
-1 );
427 BOOL
SbxInfo::LoadData( SvStream
& rStrm
, USHORT nVer
)
429 aParams
.Remove( 0, aParams
.Count() );
431 rStrm
.ReadByteString( aComment
, RTL_TEXTENCODING_ASCII_US
);
432 rStrm
.ReadByteString( aHelpFile
, RTL_TEXTENCODING_ASCII_US
);
433 rStrm
>> nHelpId
>> nParam
;
437 UINT16 nType
, nFlags
;
438 UINT32 nUserData
= 0;
439 rStrm
.ReadByteString( aName
, RTL_TEXTENCODING_ASCII_US
);
440 rStrm
>> nType
>> nFlags
;
443 AddParam( aName
, (SbxDataType
) nType
, nFlags
);
444 SbxParamInfo
* p
= aParams
.GetObject( aParams
.Count() - 1 );
445 p
->nUserData
= nUserData
;
450 BOOL
SbxInfo::StoreData( SvStream
& rStrm
) const
452 rStrm
.WriteByteString( aComment
, RTL_TEXTENCODING_ASCII_US
);
453 rStrm
.WriteByteString( aHelpFile
, RTL_TEXTENCODING_ASCII_US
);
454 rStrm
<< nHelpId
<< aParams
.Count();
455 for( USHORT i
= 0; i
< aParams
.Count(); i
++ )
457 SbxParamInfo
* p
= aParams
.GetObject( i
);
458 rStrm
.WriteByteString( p
->aName
, RTL_TEXTENCODING_ASCII_US
);
459 rStrm
<< (UINT16
) p
->eType
460 << (UINT16
) p
->nFlags
461 << (UINT32
) p
->nUserData
;