/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basic.hxx" #include #include #include #include #include // AppData-Struktur fuer SBX: SV_IMPL_PTRARR(SbxParams,SbxParamInfo*); SV_IMPL_PTRARR(SbxFacs,SbxFactory*); TYPEINIT0(SbxBase) // SBX-Daten anfordern oder ggf. anlegen // wir legen den Bereich einfach an und verzichten auf die Freigabe! SbxAppData* GetSbxData_Impl() { SbxAppData** ppData = (SbxAppData**) ::GetAppData( SHL_SBX ); SbxAppData* p = *ppData; if( !p ) p = *ppData = new SbxAppData; return p; } SbxAppData::~SbxAppData() { if( pBasicFormater ) delete pBasicFormater; } //////////////////////////////// SbxBase ///////////////////////////////// DBG_NAME(SbxBase); SbxBase::SbxBase() { DBG_CTOR( SbxBase, 0 ); nFlags = SBX_READWRITE; } SbxBase::SbxBase( const SbxBase& r ) : SvRefBase( r ) { DBG_CTOR( SbxBase, 0 ); nFlags = r.nFlags; } SbxBase::~SbxBase() { DBG_DTOR(SbxBase,0); } SbxBase& SbxBase::operator=( const SbxBase& r ) { DBG_CHKTHIS( SbxBase, 0 ); nFlags = r.nFlags; return *this; } SbxDataType SbxBase::GetType() const { DBG_CHKTHIS( SbxBase, 0 ); return SbxEMPTY; } SbxClassType SbxBase::GetClass() const { DBG_CHKTHIS( SbxBase, 0 ); return SbxCLASS_DONTCARE; } void SbxBase::Clear() { DBG_CHKTHIS( SbxBase, 0 ); } sal_Bool SbxBase::IsFixed() const { DBG_CHKTHIS( SbxBase, 0 ); return IsSet( SBX_FIXED ); } void SbxBase::SetModified( sal_Bool b ) { DBG_CHKTHIS( SbxBase, 0 ); if( IsSet( SBX_NO_MODIFY ) ) return; if( b ) SetFlag( SBX_MODIFIED ); else ResetFlag( SBX_MODIFIED ); } SbxError SbxBase::GetError() { return GetSbxData_Impl()->eSbxError; } void SbxBase::SetError( SbxError e ) { SbxAppData* p = GetSbxData_Impl(); if( e && p->eSbxError == SbxERR_OK ) p->eSbxError = e; } sal_Bool SbxBase::IsError() { return sal_Bool( GetSbxData_Impl()->eSbxError != SbxERR_OK ); } void SbxBase::ResetError() { GetSbxData_Impl()->eSbxError = SbxERR_OK; } void SbxBase::AddFactory( SbxFactory* pFac ) { SbxAppData* p = GetSbxData_Impl(); const SbxFactory* pTemp = pFac; // AB, 6.3.96: HandleLast-Flag beruecksichtigen sal_uInt16 nPos = p->aFacs.Count(); // Einfuege-Position if( !pFac->IsHandleLast() ) // Nur, wenn nicht selbst HandleLast { // Neue Factory vor Factories mit HandleLast einordnen while( nPos > 0 && (static_cast(p->aFacs.GetObject( nPos-1 )))->IsHandleLast() ) nPos--; } p->aFacs.Insert( pTemp, nPos ); } void SbxBase::RemoveFactory( SbxFactory* pFac ) { SbxAppData* p = GetSbxData_Impl(); for( sal_uInt16 i = 0; i < p->aFacs.Count(); i++ ) { if( p->aFacs.GetObject( i ) == pFac ) { p->aFacs.Remove( i, 1 ); break; } } } SbxBase* SbxBase::Create( sal_uInt16 nSbxId, sal_uInt32 nCreator ) { // #91626: Hack to skip old Basic dialogs // Problem: There does not exist a factory any more, // so we have to create a dummy SbxVariable instead if( nSbxId == 0x65 ) // Dialog Id return new SbxVariable; XubString aEmptyStr; if( nCreator == SBXCR_SBX ) switch( nSbxId ) { case SBXID_VALUE: return new SbxValue; case SBXID_VARIABLE: return new SbxVariable; case SBXID_ARRAY: return new SbxArray; case SBXID_DIMARRAY: return new SbxDimArray; case SBXID_OBJECT: return new SbxObject( aEmptyStr ); case SBXID_COLLECTION: return new SbxCollection( aEmptyStr ); case SBXID_FIXCOLLECTION: return new SbxStdCollection( aEmptyStr, aEmptyStr ); case SBXID_METHOD: return new SbxMethod( aEmptyStr, SbxEMPTY ); case SBXID_PROPERTY: return new SbxProperty( aEmptyStr, SbxEMPTY ); } // Unbekanter Typ: ber die Factories gehen! SbxAppData* p = GetSbxData_Impl(); SbxBase* pNew = NULL; for( sal_uInt16 i = 0; i < p->aFacs.Count(); i++ ) { SbxFactory* pFac = p->aFacs.GetObject( i ); pNew = pFac->Create( nSbxId, nCreator ); if( pNew ) break; } #ifdef DBG_UTIL if( !pNew ) { ByteString aMsg( "SBX: Keine Factory fuer SBX-ID " ); aMsg += ByteString::CreateFromInt32(nSbxId); DbgError( aMsg.GetBuffer() ); } #endif return pNew; } SbxObject* SbxBase::CreateObject( const XubString& rClass ) { SbxAppData* p = GetSbxData_Impl(); SbxObject* pNew = NULL; for( sal_uInt16 i = 0; i < p->aFacs.Count(); i++ ) { pNew = p->aFacs.GetObject( i )->CreateObject( rClass ); if( pNew ) break; } #ifdef DBG_UTIL if( !pNew ) { ByteString aMsg( "SBX: Keine Factory fuer Objektklasse " ); ByteString aClassStr( (const UniString&)rClass, RTL_TEXTENCODING_ASCII_US ); aMsg += aClassStr; DbgError( (const char*)aMsg.GetBuffer() ); } #endif return pNew; } static sal_Bool bStaticEnableBroadcasting = sal_True; // Sbx-Loesung als Ersatz fuer SfxBroadcaster::Enable() void SbxBase::StaticEnableBroadcasting( sal_Bool bEnable ) { bStaticEnableBroadcasting = bEnable; } sal_Bool SbxBase::StaticIsEnabledBroadcasting( void ) { return bStaticEnableBroadcasting; } SbxBase* SbxBase::Load( SvStream& rStrm ) { sal_uInt16 nSbxId, nFlags, nVer; sal_uInt32 nCreator, nSize; rStrm >> nCreator >> nSbxId >> nFlags >> nVer; // Eine Dummheit meinerseits korrigieren: if( nFlags & SBX_RESERVED ) nFlags = ( nFlags & ~SBX_RESERVED ) | SBX_GBLSEARCH; sal_uIntPtr nOldPos = rStrm.Tell(); rStrm >> nSize; SbxBase* p = Create( nSbxId, nCreator ); if( p ) { p->nFlags = nFlags; if( p->LoadData( rStrm, nVer ) ) { sal_uIntPtr nNewPos = rStrm.Tell(); nOldPos += nSize; DBG_ASSERT( nOldPos >= nNewPos, "SBX: Zu viele Daten eingelesen" ); if( nOldPos != nNewPos ) rStrm.Seek( nOldPos ); if( !p->LoadCompleted() ) { // Loeschen des Objekts SbxBaseRef aRef( p ); p = NULL; } } else { rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR ); // Loeschen des Objekts SbxBaseRef aRef( p ); p = NULL; } } else rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR ); return p; } // Sbx-Objekt im Stream ueberspringen void SbxBase::Skip( SvStream& rStrm ) { sal_uInt16 nSbxId, nFlags, nVer; sal_uInt32 nCreator, nSize; rStrm >> nCreator >> nSbxId >> nFlags >> nVer; sal_uIntPtr nStartPos = rStrm.Tell(); rStrm >> nSize; rStrm.Seek( nStartPos + nSize ); } sal_Bool SbxBase::Store( SvStream& rStrm ) { DBG_CHKTHIS( SbxBase, 0 ); if( !( nFlags & SBX_DONTSTORE ) ) { rStrm << (sal_uInt32) GetCreator() << (sal_uInt16) GetSbxId() << (sal_uInt16) GetFlags() << (sal_uInt16) GetVersion(); sal_uIntPtr nOldPos = rStrm.Tell(); rStrm << (sal_uInt32) 0L; sal_Bool bRes = StoreData( rStrm ); sal_uIntPtr nNewPos = rStrm.Tell(); rStrm.Seek( nOldPos ); rStrm << (sal_uInt32) ( nNewPos - nOldPos ); rStrm.Seek( nNewPos ); if( rStrm.GetError() != SVSTREAM_OK ) bRes = sal_False; if( bRes ) bRes = StoreCompleted(); return bRes; } else return sal_True; } sal_Bool SbxBase::LoadData( SvStream&, sal_uInt16 ) { DBG_CHKTHIS( SbxBase, 0 ); return sal_False; } sal_Bool SbxBase::StoreData( SvStream& ) const { DBG_CHKTHIS( SbxBase, 0 ); return sal_False; } sal_Bool SbxBase::LoadPrivateData( SvStream&, sal_uInt16 ) { DBG_CHKTHIS( SbxBase, 0 ); return sal_True; } sal_Bool SbxBase::StorePrivateData( SvStream& ) const { DBG_CHKTHIS( SbxBase, 0 ); return sal_True; } sal_Bool SbxBase::LoadCompleted() { DBG_CHKTHIS( SbxBase, 0 ); return sal_True; } sal_Bool SbxBase::StoreCompleted() { DBG_CHKTHIS( SbxBase, 0 ); return sal_True; } //////////////////////////////// SbxFactory //////////////////////////////// SbxBase* SbxFactory::Create( sal_uInt16, sal_uInt32 ) { return NULL; } SbxObject* SbxFactory::CreateObject( const XubString& ) { return NULL; } ///////////////////////////////// SbxInfo ////////////////////////////////// SbxInfo::~SbxInfo() {} void SbxInfo::AddParam ( const XubString& rName, SbxDataType eType, sal_uInt16 nFlags ) { const SbxParamInfo* p = new SbxParamInfo( rName, eType, nFlags ); aParams.Insert( p, aParams.Count() ); } void SbxInfo::AddParam( const SbxParamInfo& r ) { const SbxParamInfo* p = new SbxParamInfo ( r.aName, r.eType, r.nFlags, r.aTypeRef ); aParams.Insert( p, aParams.Count() ); } const SbxParamInfo* SbxInfo::GetParam( sal_uInt16 n ) const { if( n < 1 || n > aParams.Count() ) return NULL; else return aParams.GetObject( n-1 ); } sal_Bool SbxInfo::LoadData( SvStream& rStrm, sal_uInt16 nVer ) { aParams.Remove( 0, aParams.Count() ); sal_uInt16 nParam; rStrm.ReadByteString( aComment, RTL_TEXTENCODING_ASCII_US ); rStrm.ReadByteString( aHelpFile, RTL_TEXTENCODING_ASCII_US ); rStrm >> nHelpId >> nParam; while( nParam-- ) { XubString aName; sal_uInt16 nType, nFlags; sal_uInt32 nUserData = 0; rStrm.ReadByteString( aName, RTL_TEXTENCODING_ASCII_US ); rStrm >> nType >> nFlags; if( nVer > 1 ) rStrm >> nUserData; AddParam( aName, (SbxDataType) nType, nFlags ); SbxParamInfo* p = aParams.GetObject( aParams.Count() - 1 ); p->nUserData = nUserData; } return sal_True; } sal_Bool SbxInfo::StoreData( SvStream& rStrm ) const { rStrm.WriteByteString( aComment, RTL_TEXTENCODING_ASCII_US ); rStrm.WriteByteString( aHelpFile, RTL_TEXTENCODING_ASCII_US ); rStrm << nHelpId << aParams.Count(); for( sal_uInt16 i = 0; i < aParams.Count(); i++ ) { SbxParamInfo* p = aParams.GetObject( i ); rStrm.WriteByteString( p->aName, RTL_TEXTENCODING_ASCII_US ); rStrm << (sal_uInt16) p->eType << (sal_uInt16) p->nFlags << (sal_uInt32) p->nUserData; } return sal_True; }