diff options
130 files changed, 3584 insertions, 1122 deletions
diff --git a/basic/inc/basic/sbmod.hxx b/basic/inc/basic/sbmod.hxx index cf888adf9dcf..abb482f7bfe5 100644 --- a/basic/inc/basic/sbmod.hxx +++ b/basic/inc/basic/sbmod.hxx @@ -28,10 +28,12 @@ #ifndef _SB_SBMOD_HXX #define _SB_SBMOD_HXX +#include <com/sun/star/script/XInvocation.hpp> #include <basic/sbdef.hxx> #include <basic/sbxobj.hxx> #include <basic/sbxdef.hxx> #include <rtl/ustring.hxx> +#include <vector> class SbMethod; class SbProperty; @@ -42,6 +44,7 @@ class SbProcedureProperty; class SbIfaceMapperMethod; class SbClassModuleObject; +struct ClassModuleRunInitItem; struct SbClassData; class SbModuleImpl; @@ -55,8 +58,10 @@ class SbModule : public SbxObject friend class SbClassModuleObject; SbModuleImpl* mpSbModuleImpl; // Impl data + std::vector< String > mModuleVariableNames; protected: + com::sun::star::uno::Reference< com::sun::star::script::XInvocation > mxWrapper; ::rtl::OUString aOUSource; String aComment; SbiImage* pImage; // the Image @@ -67,6 +72,7 @@ protected: SbxObjectRef pDocObject; // an impl object ( used by Document Modules ) bool bIsProxyModule; + static void implProcessModuleRunInit( ClassModuleRunInitItem& rItem ); void StartDefinitions(); SbMethod* GetMethod( const String&, SbxDataType ); SbProperty* GetProperty( const String&, SbxDataType ); @@ -130,7 +136,10 @@ public: void SetVBACompat( BOOL bCompat ); INT32 GetModuleType() { return mnType; } void SetModuleType( INT32 nType ) { mnType = nType; } - bool GetIsProxyModule() { return bIsProxyModule; } + bool isProxyModule() { return bIsProxyModule; } + void AddVarName( const String& aName ); + void RemoveVars(); + ::com::sun::star::uno::Reference< ::com::sun::star::script::XInvocation > GetUnoModule(); bool createCOMWrapperForIface( ::com::sun::star::uno::Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject ); }; diff --git a/basic/inc/basic/sbobjmod.hxx b/basic/inc/basic/sbobjmod.hxx index 3d638a475f9a..9ff46d1931f3 100644 --- a/basic/inc/basic/sbobjmod.hxx +++ b/basic/inc/basic/sbobjmod.hxx @@ -36,6 +36,7 @@ #ifndef _SB_OBJMOD_HXX #define _SB_OBJMOD_HXX +#include <rtl/ref.hxx> #include <basic/sbmod.hxx> #include <basic/sbstar.hxx> #include <com/sun/star/script/ModuleInfo.hpp> @@ -60,10 +61,12 @@ public: void SetUnoObject( const com::sun::star::uno::Any& aObj )throw ( com::sun::star::uno::RuntimeException ) ; }; +class FormObjEventListenerImpl; + class SbUserFormModule : public SbObjModule { com::sun::star::script::ModuleInfo m_mInfo; - css::uno::Reference<css::lang::XEventListener> m_DialogListener; + ::rtl::Reference< FormObjEventListenerImpl > m_DialogListener; css::uno::Reference<css::awt::XDialog> m_xDialog; css::uno::Reference<css::frame::XModel> m_xModel; String sFormName; @@ -76,16 +79,19 @@ class SbUserFormModule : public SbObjModule public: TYPEINFO(); SbUserFormModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat ); + virtual ~SbUserFormModule(); virtual SbxVariable* Find( const XubString& rName, SbxClassType t ); void ResetApiObj(); void Unload(); - void load(); + void Load(); void triggerMethod( const String& ); void triggerMethod( const String&, css::uno::Sequence< css::uno::Any >& ); void triggerActivateEvent(); - void triggerDeActivateEvent(); + void triggerDeactivateEvent(); void triggerInitializeEvent(); void triggerTerminateEvent(); + void triggerLayoutEvent(); + void triggerResizeEvent(); class SbUserFormModuleInstance* CreateInstance(); }; diff --git a/basic/inc/basic/sbxvar.hxx b/basic/inc/basic/sbxvar.hxx index 4d9d19b52a59..0cddcbdf8d17 100644 --- a/basic/inc/basic/sbxvar.hxx +++ b/basic/inc/basic/sbxvar.hxx @@ -178,7 +178,7 @@ struct SbxValues sal_uInt64 uInt64; int nInt; unsigned int nUInt; - String* pString; + ::rtl::OUString* pOUString; SbxDecimal* pDecimal; SbxBase* pObj; @@ -212,7 +212,7 @@ struct SbxValues SbxValues( double _nDouble ): nDouble( _nDouble ), eType(SbxDOUBLE) {} SbxValues( int _nInt ): nInt( _nInt ), eType(SbxINT) {} SbxValues( unsigned int _nUInt ): nUInt( _nUInt ), eType(SbxUINT) {} - SbxValues( const String* _pString ): pString( (String*) _pString ), eType(SbxSTRING) {} + SbxValues( const ::rtl::OUString* _pString ): pOUString( (::rtl::OUString*)_pString ), eType(SbxSTRING) {} SbxValues( SbxBase* _pObj ): pObj( _pObj ), eType(SbxOBJECT) {} SbxValues( sal_Unicode* _pChar ): pChar( _pChar ), eType(SbxLPSTR) {} SbxValues( void* _pData ): pData( _pData ), eType(SbxPOINTER) {} @@ -237,7 +237,8 @@ class SbxValue : public SbxBase SbxValue* TheRealValue() const; protected: SbxValues aData; // Data - String aPic; // Picture-String + ::rtl::OUString aPic; // Picture-String + String aToolString; // tool string copy virtual void Broadcast( ULONG ); // Broadcast-Call virtual ~SbxValue(); @@ -303,6 +304,7 @@ public: UINT16 GetErr() const; const String& GetString() const; const String& GetCoreString() const; + ::rtl::OUString GetOUString() const; SbxDecimal* GetDecimal() const; SbxBase* GetObject() const; BOOL HasObject() const; @@ -325,8 +327,8 @@ public: BOOL PutDate( double ); BOOL PutBool( BOOL ); BOOL PutErr( USHORT ); - BOOL PutStringExt( const String& ); // with extended analysis (International, "TRUE"/"FALSE") - BOOL PutString( const String& ); + BOOL PutStringExt( const ::rtl::OUString& ); // with extended analysis (International, "TRUE"/"FALSE") + BOOL PutString( const ::rtl::OUString& ); BOOL PutString( const sal_Unicode* ); // Type = SbxSTRING BOOL PutpChar( const sal_Unicode* ); // Type = SbxLPSTR BOOL PutDecimal( SbxDecimal* pDecimal ); diff --git a/basic/source/basmgr/basmgr.cxx b/basic/source/basmgr/basmgr.cxx index b76a2b5e249e..84763468e64c 100644 --- a/basic/source/basmgr/basmgr.cxx +++ b/basic/source/basmgr/basmgr.cxx @@ -67,8 +67,8 @@ #include <com/sun/star/script/XStarBasicLibraryInfo.hpp> #include <com/sun/star/script/XLibraryContainerPassword.hpp> #include <com/sun/star/script/ModuleInfo.hpp> -#include <com/sun/star/script/XVBAModuleInfo.hpp> -#include <com/sun/star/script/XVBACompat.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> +#include <com/sun/star/script/vba/XVBAModuleInfo.hpp> #include <cppuhelper/implbase1.hxx> @@ -240,7 +240,7 @@ void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr, Any aElement = xLibNameAccess->getByName( aModuleName ); ::rtl::OUString aMod; aElement >>= aMod; - Reference< XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, UNO_QUERY ); + Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, UNO_QUERY ); if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) ) { ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aModuleName ); @@ -285,9 +285,9 @@ void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent StarBASIC* pLib = mpMgr->GetLib( aName ); if ( pLib ) { - Reference<XVBACompat> xVBACompat( xScriptCont, UNO_QUERY ); + Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, UNO_QUERY ); if ( xVBACompat.is() ) - pLib->SetVBAEnabled( xVBACompat->getVBACompatModeOn() ); + pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() ); } } else @@ -302,7 +302,7 @@ void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent { ::rtl::OUString aMod; Event.Element >>= aMod; - Reference< XVBAModuleInfo > xVBAModuleInfo( Event.Source, UNO_QUERY ); + Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, UNO_QUERY ); if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) ) { ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aName ); diff --git a/basic/source/classes/disas.cxx b/basic/source/classes/disas.cxx index 7317005d74fe..a837a3dc4f24 100644 --- a/basic/source/classes/disas.cxx +++ b/basic/source/classes/disas.cxx @@ -35,6 +35,7 @@ #include "sb.hxx" #include "iosys.hxx" #include "disas.hxx" +#include "sbtrace.hxx" static const char* pOp1[] = { @@ -153,6 +154,7 @@ static const char* pOp3[] = { "DCREATE_REDIMP", // Change dimensions of a user defined Object-Array (+StringId+StringId) "FIND_CM", // Search inside a class module (CM) to enable global search in time "PUBLIC_P", // Module global Variable (persisted between calls)(+StringID+Typ) + "FIND_STATIC", // local static var lookup (+StringID+Typ) }; static const char** pOps[3] = { pOp1, pOp2, pOp3 }; @@ -220,6 +222,7 @@ static const Func pOperand3[] = { &SbiDisas::Str2Op, // Redimensionate User defined Object-Array (+StringId+StringId) &SbiDisas::VarOp, // FIND_CM &SbiDisas::VarDefOp, // PUBLIC_P + &SbiDisas::VarOp, // FIND_STATIC }; // TODO: Why as method? Isn't a simple define sufficient? @@ -359,6 +362,11 @@ BOOL SbiDisas::DisasLine( String& rText ) rText.Erase(); if( !Fetch() ) return FALSE; + +#ifdef DBG_TRACE_BASIC + String aTraceStr_STMNT; +#endif + // New line? if( eOp == _STMNT && nOp1 != nLine ) { @@ -391,8 +399,13 @@ BOOL SbiDisas::DisasLine( String& rText ) rText.AppendAscii( "; " ); rText += s; rText.AppendAscii( _crlf() ); + +#ifdef DBG_TRACE_BASIC + aTraceStr_STMNT = s; +#endif } } + // Label? const char* p = ""; if( cLabels[ nPC >> 3 ] & ( 1 << ( nPC & 7 ) ) ) @@ -430,20 +443,29 @@ BOOL SbiDisas::DisasLine( String& rText ) rText.AppendAscii( _crlf() ); } snprintf( cBuf, sizeof(cBuf), pMask[ nParts ], nPC, (USHORT) eOp, nOp1, nOp2 ); - rText.AppendAscii( cBuf ); + + String aPCodeStr; + aPCodeStr.AppendAscii( cBuf ); int n = eOp; if( eOp >= SbOP2_START ) n -= SbOP2_START; else if( eOp >= SbOP1_START ) n -= SbOP1_START; - rText += '\t'; - rText.AppendAscii( pOps[ nParts-1 ][ n ] ); - rText += '\t'; + aPCodeStr += '\t'; + aPCodeStr.AppendAscii( pOps[ nParts-1 ][ n ] ); + aPCodeStr += '\t'; switch( nParts ) { - case 2: (this->*( pOperand2[ n ] ) )( rText ); break; - case 3: (this->*( pOperand3[ n ] ) )( rText ); break; + case 2: (this->*( pOperand2[ n ] ) )( aPCodeStr ); break; + case 3: (this->*( pOperand3[ n ] ) )( aPCodeStr ); break; } + + rText += aPCodeStr; + +#ifdef DBG_TRACE_BASIC + dbg_RegisterTraceTextForPC( pMod, nPC, aTraceStr_STMNT, aPCodeStr ); +#endif + return TRUE; } diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx index 79c5f78601ea..056c2ea38c4c 100755 --- a/basic/source/classes/sb.cxx +++ b/basic/source/classes/sb.cxx @@ -57,6 +57,7 @@ #include <vos/mutex.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include "errobject.hxx" +#include <hash_map> #include <com/sun/star/script/ModuleType.hpp> #include <com/sun/star/script/ModuleInfo.hpp> @@ -339,27 +340,18 @@ SbxBase* SbFormFactory::Create( UINT16, UINT32 ) SbxObject* SbFormFactory::CreateObject( const String& rClassName ) { - static String aLoadMethodName( RTL_CONSTASCII_USTRINGPARAM("load") ); - - SbxObject* pRet = NULL; - SbModule* pMod = pMOD; - if( pMod ) + if( SbModule* pMod = pMOD ) { - SbxVariable* pVar = pMod->Find( rClassName, SbxCLASS_OBJECT ); - if( pVar ) + if( SbxVariable* pVar = pMod->Find( rClassName, SbxCLASS_OBJECT ) ) { - SbxBase* pObj = pVar->GetObject(); - SbUserFormModule* pFormModule = PTR_CAST( SbUserFormModule, pObj ); - - if( pFormModule != NULL ) + if( SbUserFormModule* pFormModule = PTR_CAST( SbUserFormModule, pVar->GetObject() ) ) { - pFormModule->load(); - SbUserFormModuleInstance* pFormInstance = pFormModule->CreateInstance(); - pRet = pFormInstance; + pFormModule->Load(); + return pFormModule->CreateInstance(); } } } - return pRet; + return 0; } @@ -561,6 +553,39 @@ SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule ) USHORT nFlags_ = pProp->GetFlags(); pProp->SetFlag( SBX_NO_BROADCAST ); SbxProperty* pNewProp = new SbxProperty( *pProp ); + + // Special handling for modules instances and collections, they need + // to be instantiated, otherwise all refer to the same base object + SbxDataType eVarType = pProp->GetType(); + if( eVarType == SbxOBJECT ) + { + SbxBase* pObjBase = pProp->GetObject(); + SbxObject* pObj = PTR_CAST(SbxObject,pObjBase); + if( pObj != NULL ) + { + String aObjClass = pObj->GetClassName(); + (void)aObjClass; + + SbClassModuleObject* pClassModuleObj = PTR_CAST(SbClassModuleObject,pObjBase); + if( pClassModuleObj != NULL ) + { + SbModule* pLclClassModule = pClassModuleObj->getClassModule(); + SbClassModuleObject* pNewObj = new SbClassModuleObject( pLclClassModule ); + pNewObj->SetName( pProp->GetName() ); + pNewObj->SetParent( pLclClassModule->pParent ); + pNewProp->PutObject( pNewObj ); + } + else if( aObjClass.EqualsIgnoreCaseAscii( "Collection" ) ) + { + String aCollectionName( RTL_CONSTASCII_USTRINGPARAM("Collection") ); + BasicCollection* pNewCollection = new BasicCollection( aCollectionName ); + pNewCollection->SetName( pProp->GetName() ); + pNewCollection->SetParent( pClassModule->pParent ); + pNewProp->PutObject( pNewCollection ); + } + } + } + pNewProp->ResetFlag( SBX_NO_BROADCAST ); pNewProp->SetParent( this ); pProps->PutDirect( pNewProp, i ); @@ -569,11 +594,13 @@ SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule ) } } SetModuleType( ModuleType::CLASS ); + mbVBACompat = pClassModule->mbVBACompat; } SbClassModuleObject::~SbClassModuleObject() { - triggerTerminateEvent(); + if( StarBASIC::IsRunning() ) + triggerTerminateEvent(); // Must be deleted by base class dtor because this data // is not owned by the SbClassModuleObject object @@ -606,7 +633,28 @@ void SbClassModuleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType { SbxValues aVals; aVals.eType = SbxVARIANT; - pMeth->Get( aVals ); + + SbxArray* pArg = pVar->GetParameters(); + USHORT nVarParCount = (pArg != NULL) ? pArg->Count() : 0; + if( nVarParCount > 1 ) + { + SbxArrayRef xMethParameters = new SbxArray; + xMethParameters->Put( pMeth, 0 ); // Method as parameter 0 + for( USHORT i = 1 ; i < nVarParCount ; ++i ) + { + SbxVariable* pPar = pArg->Get( i ); + xMethParameters->Put( pPar, i ); + } + + pMeth->SetParameters( xMethParameters ); + pMeth->Get( aVals ); + pMeth->SetParameters( NULL ); + } + else + { + pMeth->Get( aVals ); + } + pVar->Put( aVals ); } } @@ -712,6 +760,7 @@ SbClassData::SbClassData( void ) void SbClassData::clear( void ) { mxIfaces->Clear(); + maRequiredTypes.clear(); } SbClassFactory::SbClassFactory( void ) @@ -967,6 +1016,72 @@ SbModule* StarBASIC::FindModule( const String& rName ) return NULL; } + +struct ClassModuleRunInitItem +{ + SbModule* m_pModule; + bool m_bProcessing; + bool m_bRunInitDone; + //ModuleVector m_vModulesDependingOnThisModule; + + ClassModuleRunInitItem( void ) + : m_pModule( NULL ) + , m_bProcessing( false ) + , m_bRunInitDone( false ) + {} + ClassModuleRunInitItem( SbModule* pModule ) + : m_pModule( pModule ) + , m_bProcessing( false ) + , m_bRunInitDone( false ) + {} +}; + +typedef std::hash_map< ::rtl::OUString, ClassModuleRunInitItem, + ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleInitDependencyMap; + +static ModuleInitDependencyMap* GpMIDMap = NULL; + +void SbModule::implProcessModuleRunInit( ClassModuleRunInitItem& rItem ) +{ + ModuleInitDependencyMap& rMIDMap = *GpMIDMap; + + rItem.m_bProcessing = true; + + //bool bAnyDependencies = true; + SbModule* pModule = rItem.m_pModule; + if( pModule->pClassData != NULL ) + { + StringVector& rReqTypes = pModule->pClassData->maRequiredTypes; + if( rReqTypes.size() > 0 ) + { + for( StringVector::iterator it = rReqTypes.begin() ; it != rReqTypes.end() ; ++it ) + { + String& rStr = *it; + + // Is required type a class module? + ModuleInitDependencyMap::iterator itFind = rMIDMap.find( rStr ); + if( itFind != rMIDMap.end() ) + { + ClassModuleRunInitItem& rParentItem = itFind->second; + if( rParentItem.m_bProcessing ) + { + // TODO: raise error? + DBG_ERROR( "Cyclic module dependency detected" ); + continue; + } + + if( !rParentItem.m_bRunInitDone ) + implProcessModuleRunInit( rParentItem ); + } + } + } + } + + pModule->RunInit(); + rItem.m_bRunInitDone = true; + rItem.m_bProcessing = false; +} + // Run Init-Code of all modules (including inserted libraries) void StarBASIC::InitAllModules( StarBASIC* pBasicNotToInit ) { @@ -980,10 +1095,33 @@ void StarBASIC::InitAllModules( StarBASIC* pBasicNotToInit ) // compile modules first then RunInit ( otherwise there is // can be order dependency, e.g. classmodule A has a member // of of type classmodule B and classmodule B hasn't been compiled yet ) + + // Consider required types to init in right order. Class modules + // that are required by other modules have to be initialized first. + ModuleInitDependencyMap aMIDMap; + GpMIDMap = &aMIDMap; + for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ ) + { + SbModule* pModule = (SbModule*)pModules->Get( nMod ); + String aModuleName = pModule->GetName(); + if( pModule->isProxyModule() ) + aMIDMap[aModuleName] = ClassModuleRunInitItem( pModule ); + } + + ModuleInitDependencyMap::iterator it; + for( it = aMIDMap.begin() ; it != aMIDMap.end(); ++it ) + { + ClassModuleRunInitItem& rItem = it->second; + SbModule::implProcessModuleRunInit( rItem ); + } + GpMIDMap = NULL; + + // Call RunInit on standard modules for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ ) { SbModule* pModule = (SbModule*)pModules->Get( nMod ); - pModule->RunInit(); + if( !pModule->isProxyModule() ) + pModule->RunInit(); } // Check all objects if they are BASIC, @@ -1948,7 +2086,7 @@ void BasicCollection::CollItem( SbxArray* pPar_ ) if( nIndex >= 0 && nIndex < (INT32)xItemArray->Count32() ) pRes = xItemArray->Get32( nIndex ); if( !pRes ) - SetError( SbxERR_BAD_INDEX ); + SetError( SbERR_BAD_ARGUMENT ); else *(pPar_->Get(0)) = *pRes; } @@ -1966,6 +2104,6 @@ void BasicCollection::CollRemove( SbxArray* pPar_ ) if( nIndex >= 0 && nIndex < (INT32)xItemArray->Count32() ) xItemArray->Remove32( nIndex ); else - SetError( SbxERR_BAD_INDEX ); + SetError( SbERR_BAD_ARGUMENT ); } diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx index e51a0c09270b..c9123b06341b 100755 --- a/basic/source/classes/sbunoobj.cxx +++ b/basic/source/classes/sbunoobj.cxx @@ -71,6 +71,7 @@ #include <com/sun/star/bridge/oleautomation/Date.hpp> #include <com/sun/star/bridge/oleautomation/Decimal.hpp> #include <com/sun/star/bridge/oleautomation/Currency.hpp> +#include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp> using com::sun::star::uno::Reference; @@ -300,7 +301,12 @@ SbUnoObject* createOLEObject_Impl( const String& aType ) SbUnoObject* pUnoObj = NULL; if( xOLEFactory.is() ) { - Reference< XInterface > xOLEObject = xOLEFactory->createInstance( aType ); + // some type names available in VBA can not be directly used in COM + ::rtl::OUString aOLEType = aType; + if ( aOLEType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SAXXMLReader30" ) ) ) ) + aOLEType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Msxml2.SAXXMLReader.3.0" ) ); + + Reference< XInterface > xOLEObject = xOLEFactory->createInstance( aOLEType ); if( xOLEObject.is() ) { Any aAny; @@ -911,7 +917,7 @@ Type getUnoTypeForSbxBaseType( SbxDataType eType ) case SbxVARIANT: aRetType = ::getCppuType( (Any*)0 ); break; //case SbxDATAOBJECT: break; case SbxCHAR: aRetType = ::getCppuType( (sal_Unicode*)0 ); break; - case SbxBYTE: aRetType = ::getCppuType( (sal_Int16*)0 ); break; + case SbxBYTE: aRetType = ::getCppuType( (sal_Int8*)0 ); break; case SbxUSHORT: aRetType = ::getCppuType( (sal_uInt16*)0 ); break; case SbxULONG: aRetType = ::getCppuType( (sal_uInt32*)0 ); break; //case SbxLONG64: break; @@ -1460,7 +1466,7 @@ Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty aRetVal.setValue( &c , getCharCppuType() ); break; } - case TypeClass_STRING: aRetVal <<= ::rtl::OUString( pVar->GetString() ); break; + case TypeClass_STRING: aRetVal <<= pVar->GetOUString(); break; case TypeClass_FLOAT: aRetVal <<= pVar->GetSingle(); break; case TypeClass_DOUBLE: aRetVal <<= pVar->GetDouble(); break; //case TypeClass_OCTET: break; @@ -2265,6 +2271,7 @@ Reference< XInvocation > createDynamicInvocationFor( const Any& aAny ); SbUnoObject::SbUnoObject( const String& aName_, const Any& aUnoObj_ ) : SbxObject( aName_ ) , bNeedIntrospection( TRUE ) + , bIgnoreNativeCOMObjectMembers( FALSE ) { static Reference< XIntrospection > xIntrospection; @@ -2310,6 +2317,12 @@ SbUnoObject::SbUnoObject( const String& aName_, const Any& aUnoObj_ ) bNeedIntrospection = FALSE; return; } + + // Ignore introspection based members for COM objects to avoid + // hiding of equally named COM symbols, e.g. XInvocation::getValue + Reference< oleautomation::XAutomationObject > xAutomationObject( aUnoObj_, UNO_QUERY ); + if( xAutomationObject.is() ) + bIgnoreNativeCOMObjectMembers = TRUE; } maTmpUnoObj = aUnoObj_; @@ -2553,7 +2566,7 @@ SbxVariable* SbUnoObject::Find( const String& rName, SbxClassType t ) if( !pRes ) { ::rtl::OUString aUName( rName ); - if( mxUnoAccess.is() ) + if( mxUnoAccess.is() && !bIgnoreNativeCOMObjectMembers ) { if( mxExactName.is() ) { @@ -2713,10 +2726,12 @@ void SbUnoObject::implCreateAll( void ) // Instrospection besorgen Reference< XIntrospectionAccess > xAccess = mxUnoAccess; - if( !xAccess.is() ) + if( !xAccess.is() || bIgnoreNativeCOMObjectMembers ) { if( mxInvocation.is() ) xAccess = mxInvocation->getIntrospection(); + else if( bIgnoreNativeCOMObjectMembers ) + return; } if( !xAccess.is() ) return; diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx index 1b49a376c9bd..8b1069bbeab3 100644 --- a/basic/source/classes/sbxmod.cxx +++ b/basic/source/classes/sbxmod.cxx @@ -45,6 +45,7 @@ #include "runtime.hxx" #include "token.hxx" #include "sbunoobj.hxx" +#include "sbtrace.hxx" //#include <basic/hilight.hxx> @@ -53,9 +54,10 @@ #include <basic/basrdll.hxx> #include <vos/mutex.hxx> #include <basic/sbobjmod.hxx> +#include <cppuhelper/implbase2.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/script/ModuleType.hpp> -#include <com/sun/star/script/XVBACompat.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> #include <com/sun/star/beans/XPropertySet.hpp> using namespace com::sun::star; @@ -76,15 +78,362 @@ using namespace com::sun::star; #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <comphelper/processfactory.hxx> #include <vcl/svapp.hxx> +#include <map> +#include <com/sun/star/reflection/XProxyFactory.hpp> +#include <cppuhelper/implbase1.hxx> +#include <basic/sbobjmod.hxx> +#include <com/sun/star/uno/XAggregation.hpp> +#include <map> +#include <com/sun/star/script/XInvocation.hpp> + using namespace ::com::sun::star; +using namespace com::sun::star::lang; +using namespace com::sun::star::reflection; +using namespace com::sun::star::beans; +using namespace com::sun::star::script; + #include <com/sun/star/script/XLibraryContainer.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/awt/XDialogProvider.hpp> #include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/XWindow.hpp> #include <com/sun/star/awt/XControl.hpp> #include <cppuhelper/implbase1.hxx> #include <comphelper/anytostring.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + +typedef ::cppu::WeakImplHelper1< XInvocation > DocObjectWrapper_BASE; +typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap; +::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar ); +void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue ); + +class DocObjectWrapper : public DocObjectWrapper_BASE +{ + Reference< XAggregation > m_xAggProxy; + Reference< XInvocation > m_xAggInv; + Reference< XTypeProvider > m_xAggregateTypeProv; + Sequence< Type > m_Types; + SbModule* m_pMod; + SbMethodRef getMethod( const rtl::OUString& aName ) throw (RuntimeException); + SbPropertyRef getProperty( const rtl::OUString& aName ) throw (RuntimeException); + String mName; // for debugging + +public: + DocObjectWrapper( SbModule* pMod ); + virtual ~DocObjectWrapper(); + + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (RuntimeException) + { + if( !m_xAggregateTypeProv.is() ) + throw RuntimeException(); + return m_xAggregateTypeProv->getImplementationId(); + } + + virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection( ) throw (RuntimeException); + + virtual Any SAL_CALL invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException); + virtual void SAL_CALL setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException); + virtual Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException); + virtual ::sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException); + virtual Any SAL_CALL queryInterface( const Type& aType ) throw ( RuntimeException ); + + virtual Sequence< Type > SAL_CALL getTypes() throw ( RuntimeException ); +}; + +DocObjectWrapper::DocObjectWrapper( SbModule* pVar ) : m_pMod( pVar ), mName( pVar->GetName() ) +{ + SbObjModule* pMod = PTR_CAST(SbObjModule,pVar); + if ( pMod ) + { + if ( pMod->GetModuleType() == ModuleType::DOCUMENT ) + { + Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + // Use proxy factory service to create aggregatable proxy. + SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pMod->GetObject() ); + Reference< XInterface > xIf; + if ( pUnoObj ) + { + Any aObj = pUnoObj->getUnoAny(); + aObj >>= xIf; + if ( xIf.is() ) + { + m_xAggregateTypeProv.set( xIf, UNO_QUERY ); + m_xAggInv.set( xIf, UNO_QUERY ); + } + } + if ( xIf.is() ) + { + try + { + Reference< XMultiComponentFactory > xMFac( xFactory, UNO_QUERY_THROW ); + Reference< XPropertySet> xPSMPropertySet( xMFac, UNO_QUERY_THROW ); + Reference< XComponentContext > xCtx; + xPSMPropertySet->getPropertyValue( + String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xCtx; + Reference< XProxyFactory > xProxyFac( xMFac->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.ProxyFactory" ) ), xCtx ), UNO_QUERY_THROW ); + m_xAggProxy = xProxyFac->createProxy( xIf ); + } + catch( Exception& ) + { + OSL_ENSURE( false, "DocObjectWrapper::DocObjectWrapper: Caught exception!" ); + } + } + + if ( m_xAggProxy.is() ) + { + osl_incrementInterlockedCount( &m_refCount ); + + /* i35609 - Fix crash on Solaris. The setDelegator call needs + to be in its own block to ensure that all temporary Reference + instances that are acquired during the call are released + before m_refCount is decremented again */ + { + m_xAggProxy->setDelegator( static_cast< cppu::OWeakObject * >( this ) ); + } + + osl_decrementInterlockedCount( &m_refCount ); + } + } + } +} + +void SAL_CALL +DocObjectWrapper::acquire() throw () +{ + osl_incrementInterlockedCount( &m_refCount ); + OSL_TRACE("DocObjectWrapper::acquire(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount ); +} +void SAL_CALL +DocObjectWrapper::release() throw () +{ + if ( osl_decrementInterlockedCount( &m_refCount ) == 0 ) + { + OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount ); + delete this; + } + else + OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount ); +} + +DocObjectWrapper::~DocObjectWrapper() +{ +} + +Sequence< Type > SAL_CALL DocObjectWrapper::getTypes() + throw ( RuntimeException ) +{ + if ( m_Types.getLength() == 0 ) + { + Sequence< Type > sTypes; + if ( m_xAggregateTypeProv.is() ) + sTypes = m_xAggregateTypeProv->getTypes(); + m_Types.realloc( sTypes.getLength() + 1 ); + Type* pPtr = m_Types.getArray(); + for ( int i=0; i<m_Types.getLength(); ++i, ++pPtr ) + { + if ( i == 0 ) + *pPtr = XInvocation::static_type( NULL ); + else + *pPtr = sTypes[ i - 1 ]; + } + } + return m_Types; +} + +Reference< XIntrospectionAccess > SAL_CALL +DocObjectWrapper::getIntrospection( ) throw (RuntimeException) +{ + return NULL; +} + +Any SAL_CALL +DocObjectWrapper::invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException) +{ + if ( m_xAggInv.is() && m_xAggInv->hasMethod( aFunctionName ) ) + return m_xAggInv->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam ); + SbMethodRef pMethod = getMethod( aFunctionName ); + if ( !pMethod ) + throw RuntimeException(); + // check number of parameters + sal_Int32 nParamsCount = aParams.getLength(); + SbxInfo* pInfo = pMethod->GetInfo(); + if ( pInfo ) + { + sal_Int32 nSbxOptional = 0; + USHORT n = 1; + for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) ) + { + if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 ) + ++nSbxOptional; + else + nSbxOptional = 0; + } + sal_Int32 nSbxCount = n - 1; + if ( nParamsCount < nSbxCount - nSbxOptional ) + { + throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "wrong number of parameters!" ) ), Reference< XInterface >() ); + } + } + // set parameters + SbxArrayRef xSbxParams; + if ( nParamsCount > 0 ) + { + xSbxParams = new SbxArray; + const Any* pParams = aParams.getConstArray(); + for ( sal_Int32 i = 0; i < nParamsCount; ++i ) + { + SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT ); + unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] ); + xSbxParams->Put( xSbxVar, static_cast< USHORT >( i ) + 1 ); + + // Enable passing by ref + if ( xSbxVar->GetType() != SbxVARIANT ) + xSbxVar->SetFlag( SBX_FIXED ); + } + } + if ( xSbxParams.Is() ) + pMethod->SetParameters( xSbxParams ); + + // call method + SbxVariableRef xReturn = new SbxVariable; + ErrCode nErr = SbxERR_OK; + + nErr = pMethod->Call( xReturn ); + Any aReturn; + // get output parameters + if ( xSbxParams.Is() ) + { + SbxInfo* pInfo_ = pMethod->GetInfo(); + if ( pInfo_ ) + { + OutParamMap aOutParamMap; + for ( USHORT n = 1, nCount = xSbxParams->Count(); n < nCount; ++n ) + { + const SbxParamInfo* pParamInfo = pInfo_->GetParam( n ); + if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 ) + { + SbxVariable* pVar = xSbxParams->Get( n ); + if ( pVar ) + { + SbxVariableRef xVar = pVar; + aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) ); + } + } + } + sal_Int32 nOutParamCount = aOutParamMap.size(); + aOutParamIndex.realloc( nOutParamCount ); + aOutParam.realloc( nOutParamCount ); + sal_Int16* pOutParamIndex = aOutParamIndex.getArray(); + Any* pOutParam = aOutParam.getArray(); + for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam ) + { + *pOutParamIndex = aIt->first; + *pOutParam = aIt->second; + } + } + } + + // get return value + aReturn = sbxToUnoValue( xReturn ); + + pMethod->SetParameters( NULL ); + + return aReturn; +} + +void SAL_CALL +DocObjectWrapper::setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException) +{ + if ( m_xAggInv.is() && m_xAggInv->hasProperty( aPropertyName ) ) + return m_xAggInv->setValue( aPropertyName, aValue ); + + SbPropertyRef pProperty = getProperty( aPropertyName ); + if ( !pProperty.Is() ) + throw UnknownPropertyException(); + unoToSbxValue( (SbxVariable*) pProperty, aValue ); +} + +Any SAL_CALL +DocObjectWrapper::getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException) +{ + if ( m_xAggInv.is() && m_xAggInv->hasProperty( aPropertyName ) ) + return m_xAggInv->getValue( aPropertyName ); + + SbPropertyRef pProperty = getProperty( aPropertyName ); + if ( !pProperty.Is() ) + throw UnknownPropertyException(); + + SbxVariable* pProp = ( SbxVariable* ) pProperty; + if ( pProp->GetType() == SbxEMPTY ) + pProperty->Broadcast( SBX_HINT_DATAWANTED ); + + Any aRet = sbxToUnoValue( pProp ); + return aRet; +} + +::sal_Bool SAL_CALL +DocObjectWrapper::hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException) +{ + if ( m_xAggInv.is() && m_xAggInv->hasMethod( aName ) ) + return sal_True; + return getMethod( aName ).Is(); +} + +::sal_Bool SAL_CALL +DocObjectWrapper::hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException) +{ + sal_Bool bRes = sal_False; + if ( m_xAggInv.is() && m_xAggInv->hasProperty( aName ) ) + bRes = sal_True; + else bRes = getProperty( aName ).Is(); + return bRes; +} + +Any SAL_CALL DocObjectWrapper::queryInterface( const Type& aType ) + throw ( RuntimeException ) +{ + Any aRet = DocObjectWrapper_BASE::queryInterface( aType ); + if ( aRet.hasValue() ) + return aRet; + else if ( m_xAggProxy.is() ) + aRet = m_xAggProxy->queryAggregation( aType ); + return aRet; +} + +SbMethodRef DocObjectWrapper::getMethod( const rtl::OUString& aName ) throw (RuntimeException) +{ + SbMethodRef pMethod = NULL; + if ( m_pMod ) + { + USHORT nSaveFlgs = m_pMod->GetFlags(); + // Limit search to this module + m_pMod->ResetFlag( SBX_GBLSEARCH ); + pMethod = (SbMethod*) m_pMod->SbModule::Find( aName, SbxCLASS_METHOD ); + m_pMod->SetFlags( nSaveFlgs ); + } + + return pMethod; +} + +SbPropertyRef DocObjectWrapper::getProperty( const rtl::OUString& aName ) throw (RuntimeException) +{ + SbPropertyRef pProperty = NULL; + if ( m_pMod ) + { + USHORT nSaveFlgs = m_pMod->GetFlags(); + // Limit search to this module. + m_pMod->ResetFlag( SBX_GBLSEARCH ); + pProperty = (SbProperty*)m_pMod->SbModule::Find( aName, SbxCLASS_PROPERTY ); + m_pMod->SetFlag( nSaveFlgs ); + } + + return pProperty; +} TYPEINIT1(SbModule,SbxObject) TYPEINIT1(SbMethod,SbxMethod) @@ -112,9 +461,9 @@ bool getDefaultVBAMode( StarBASIC* pb ) uno::Reference< beans::XPropertySet > xProp( aDoc, uno::UNO_QUERY ); if ( xProp.is() ) { - uno::Reference< script::XVBACompat > xVBAMode( xProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BasicLibraries") ) ), uno::UNO_QUERY ); + uno::Reference< script::vba::XVBACompatibility > xVBAMode( xProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BasicLibraries") ) ), uno::UNO_QUERY ); if ( xVBAMode.is() ) - bResult = ( xVBAMode->getVBACompatModeOn() == sal_True ); + bResult = xVBAMode->getVBACompatibilityMode() == sal_True; } } } @@ -199,12 +548,24 @@ SbModule::SbModule( const String& rName, BOOL bVBACompat ) SbModule::~SbModule() { + OSL_TRACE("Module named %s is destructing", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr() ); if( pImage ) delete pImage; if( pBreaks ) delete pBreaks; if( pClassData ) delete pClassData; + mxWrapper = NULL; +} + +uno::Reference< script::XInvocation > +SbModule::GetUnoModule() +{ + if ( !mxWrapper.is() ) + mxWrapper = new DocObjectWrapper( this ); + + OSL_TRACE("Module named %s returning wrapper mxWrapper (0x%x)", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mxWrapper.get() ); + return mxWrapper; } BOOL SbModule::IsCompiled() const @@ -684,6 +1045,9 @@ USHORT SbModule::Run( SbMethod* pMeth ) StarBASICRef xBasic; if( bDelInst ) { +#ifdef DBG_TRACE_BASIC + dbg_InitTrace(); +#endif // #32779: Basic waehrend der Ausfuehrung festhalten xBasic = (StarBASIC*) GetParent(); @@ -762,18 +1126,28 @@ USHORT SbModule::Run( SbMethod* pMeth ) SbModule* pOldMod = pMOD; pMOD = this; SbiRuntime* pRt = new SbiRuntime( this, pMeth, pMeth->nStart ); + +#ifdef DBG_TRACE_BASIC + dbg_traceNotifyCall( this, pMeth, pINST->nCallLvl ); +#endif + pRt->pNext = pINST->pRun; if( pRt->pNext ) pRt->pNext->block(); pINST->pRun = pRt; if ( mbVBACompat ) - { + { pINST->EnableCompatibility( TRUE ); - } + } while( pRt->Step() ) {} if( pRt->pNext ) pRt->pNext->unblock(); +#ifdef DBG_TRACE_BASIC + bool bLeave = true; + dbg_traceNotifyCall( this, pMeth, pINST->nCallLvl, bLeave ); +#endif + // #63710 Durch ein anderes Thread-Handling bei Events kann es passieren, // dass show-Aufruf an einem Dialog zurueckkehrt (durch schliessen des // Dialogs per UI), BEVOR ein per Event ausgeloester weitergehender Call, @@ -867,9 +1241,20 @@ void SbModule::RunInit() pMOD = this; // Der Init-Code beginnt immer hier SbiRuntime* pRt = new SbiRuntime( this, NULL, 0 ); + +#ifdef DBG_TRACE_BASIC + dbg_traceNotifyCall( this, NULL, 0 ); +#endif + pRt->pNext = pINST->pRun; pINST->pRun = pRt; while( pRt->Step() ) {} + +#ifdef DBG_TRACE_BASIC + bool bLeave = true; + dbg_traceNotifyCall( this, NULL, 0, bLeave ); +#endif + pINST->pRun = pRt->pNext; delete pRt; pMOD = pOldMod; @@ -884,6 +1269,33 @@ void SbModule::RunInit() } // Mit private/dim deklarierte Variablen loeschen + +void SbModule::AddVarName( const String& aName ) +{ + // see if the name is added allready + std::vector< String >::iterator it_end = mModuleVariableNames.end(); + for ( std::vector< String >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it ) + { + if ( aName == *it ) + return; + } + mModuleVariableNames.push_back( aName ); +} + +void SbModule::RemoveVars() +{ + std::vector< String >::iterator it_end = mModuleVariableNames.end(); + for ( std::vector< String >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it ) + { + // We don't want a Find being called in a derived class ( e.g. + // SbUserform because it could trigger say an initialise event + // which would cause basic to be re-run in the middle of the init ( and remember RemoveVars is called from compile and we don't want code to run as part of the compile ) + SbxVariableRef p = SbModule::Find( *it, SbxCLASS_PROPERTY ); + if( p.Is() ) + Remove (p); + } +} + void SbModule::ClearPrivateVars() { for( USHORT i = 0 ; i < pProps->Count() ; i++ ) @@ -1600,9 +2012,9 @@ SbObjModule::Find( const XubString& rName, SbxClassType t ) return pVar; } -typedef ::cppu::WeakImplHelper1< awt::XTopWindowListener > EventListener_BASE; +typedef ::cppu::WeakImplHelper2< awt::XTopWindowListener, awt::XWindowListener > FormObjEventListener_BASE; -class FormObjEventListenerImpl : public EventListener_BASE +class FormObjEventListenerImpl : public FormObjEventListener_BASE { SbUserFormModule* mpUserForm; uno::Reference< lang::XComponent > mxComponent; @@ -1612,39 +2024,57 @@ class FormObjEventListenerImpl : public EventListener_BASE sal_Bool mbShowing; FormObjEventListenerImpl(); // not defined FormObjEventListenerImpl(const FormObjEventListenerImpl&); // not defined + public: - FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent ) : mpUserForm( pUserForm ), mxComponent( xComponent) , mbDisposed( false ), mbOpened( sal_False ), mbActivated( sal_False ), mbShowing( sal_False ) + FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent ) : + mpUserForm( pUserForm ), mxComponent( xComponent) , + mbDisposed( false ), mbOpened( sal_False ), mbActivated( sal_False ), mbShowing( sal_False ) { if ( mxComponent.is() ) { - uno::Reference< awt::XTopWindow > xList( mxComponent, uno::UNO_QUERY_THROW );; - OSL_TRACE("*********** Registering the listener"); - xList->addTopWindowListener( this ); + OSL_TRACE("*********** Registering the listeners"); + try + { + uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->addTopWindowListener( this ); + } + catch( uno::Exception& ) {} + try + { + uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->addWindowListener( this ); + } + catch( uno::Exception& ) {} } } - ~FormObjEventListenerImpl() + virtual ~FormObjEventListenerImpl() { removeListener(); } - sal_Bool isShowing() { return mbShowing; } + + sal_Bool isShowing() const { return mbShowing; } + void removeListener() { - try + if ( mxComponent.is() && !mbDisposed ) { - if ( mxComponent.is() && !mbDisposed ) + OSL_TRACE("*********** Removing the listeners"); + try + { + uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeTopWindowListener( this ); + } + catch( uno::Exception& ) {} + try { - uno::Reference< awt::XTopWindow > xList( mxComponent, uno::UNO_QUERY_THROW );; - OSL_TRACE("*********** Removing the listener"); - xList->removeTopWindowListener( this ); - mxComponent = NULL; + uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeWindowListener( this ); } + catch( uno::Exception& ) {} } - catch( uno::Exception& ) {} + mxComponent.clear(); } + virtual void SAL_CALL windowOpened( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) { - if ( mpUserForm ) + if ( mpUserForm ) { mbOpened = sal_True; mbShowing = sal_True; @@ -1691,12 +2121,23 @@ public: } //liuchen 2009-7-21 - virtual void SAL_CALL windowClosed( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) { mbOpened = sal_False; mbShowing = sal_False; } - virtual void SAL_CALL windowMinimized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) {} - virtual void SAL_CALL windowNormalized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException){} + virtual void SAL_CALL windowClosed( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { + mbOpened = sal_False; + mbShowing = sal_False; + } + + virtual void SAL_CALL windowMinimized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { + } + + virtual void SAL_CALL windowNormalized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { + } + virtual void SAL_CALL windowActivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) { - if ( mpUserForm ) + if ( mpUserForm ) { mbActivated = sal_True; if ( mbOpened ) @@ -1709,18 +2150,38 @@ public: virtual void SAL_CALL windowDeactivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) { - if ( mpUserForm ) - mpUserForm->triggerDeActivateEvent(); + if ( mpUserForm ) + mpUserForm->triggerDeactivateEvent(); + } + + virtual void SAL_CALL windowResized( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException) + { + if ( mpUserForm ) + { + mpUserForm->triggerResizeEvent(); + mpUserForm->triggerLayoutEvent(); + } } + virtual void SAL_CALL windowMoved( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException) + { + if ( mpUserForm ) + mpUserForm->triggerLayoutEvent(); + } + + virtual void SAL_CALL windowShown( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { + } + + virtual void SAL_CALL windowHidden( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { + } - virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException) + virtual void SAL_CALL disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) { OSL_TRACE("** Userform/Dialog disposing"); mbDisposed = true; - uno::Any aSource; - aSource <<= Source; - mxComponent = NULL; + mxComponent.clear(); if ( mpUserForm ) mpUserForm->ResetApiObj(); } @@ -1734,6 +2195,10 @@ SbUserFormModule::SbUserFormModule( const String& rName, const com::sun::star::s m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW ); } +SbUserFormModule::~SbUserFormModule() +{ +} + void SbUserFormModule::ResetApiObj() { if ( m_xDialog.is() ) // probably someone close the dialog window @@ -1796,23 +2261,22 @@ void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any void SbUserFormModule::triggerActivateEvent( void ) { - OSL_TRACE("**** entering SbUserFormModule::triggerActivate"); - triggerMethod( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm_activate") ) ); - OSL_TRACE("**** leaving SbUserFormModule::triggerActivate"); + OSL_TRACE("**** entering SbUserFormModule::triggerActivate"); + triggerMethod( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm_Activate") ) ); + OSL_TRACE("**** leaving SbUserFormModule::triggerActivate"); } -void SbUserFormModule::triggerDeActivateEvent( void ) +void SbUserFormModule::triggerDeactivateEvent( void ) { - OSL_TRACE("**** SbUserFormModule::triggerDeActivate"); - triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_DeActivate") ) ); + OSL_TRACE("**** SbUserFormModule::triggerDeactivate"); + triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_Deactivate") ) ); } void SbUserFormModule::triggerInitializeEvent( void ) - { if ( mbInit ) return; - OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent"); + OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent"); static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Initialize") ); triggerMethod( aInitMethodName ); mbInit = true; @@ -1820,12 +2284,24 @@ void SbUserFormModule::triggerInitializeEvent( void ) void SbUserFormModule::triggerTerminateEvent( void ) { - OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent"); + OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent"); static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Terminate") ); triggerMethod( aTermMethodName ); mbInit=false; } +void SbUserFormModule::triggerLayoutEvent( void ) +{ + static String aMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Layout") ); + triggerMethod( aMethodName ); +} + +void SbUserFormModule::triggerResizeEvent( void ) +{ + static String aMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Resize") ); + triggerMethod( aMethodName ); +} + SbUserFormModuleInstance* SbUserFormModule::CreateInstance() { SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBACompat() ); @@ -1853,7 +2329,7 @@ SbxVariable* SbUserFormModuleInstance::Find( const XubString& rName, SbxClassTyp } -void SbUserFormModule::load() +void SbUserFormModule::Load() { OSL_TRACE("** load() "); // forces a load @@ -1891,21 +2367,20 @@ void SbUserFormModule::Unload() if( pMeth ) { OSL_TRACE("Attempting too run the UnloadObjectMethod"); - m_xDialog = NULL; //release ref to the uno object + m_xDialog.clear(); //release ref to the uno object SbxValues aVals; - FormObjEventListenerImpl* pFormListener = dynamic_cast< FormObjEventListenerImpl* >( m_DialogListener.get() ); bool bWaitForDispose = true; // assume dialog is showing - if ( pFormListener ) + if ( m_DialogListener.get() ) { - bWaitForDispose = pFormListener->isShowing(); + bWaitForDispose = m_DialogListener->isShowing(); OSL_TRACE("Showing %d", bWaitForDispose ); } pMeth->Get( aVals); - if ( !bWaitForDispose ) - { - // we've either already got a dispose or we'er never going to get one + if ( !bWaitForDispose ) + { + // we've either already got a dispose or we'er never going to get one ResetApiObj(); - } // else wait for dispose + } // else wait for dispose OSL_TRACE("UnloadObject completed ( we hope )"); } } @@ -1943,9 +2418,8 @@ void SbUserFormModule::InitObject() pDocObject = new SbUnoObject( GetName(), uno::makeAny( xVBAFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.UserForm")), aArgs ) ) ); uno::Reference< lang::XComponent > xComponent( aArgs[ 1 ], uno::UNO_QUERY_THROW ); // remove old listener if it exists - FormObjEventListenerImpl* pFormListener = dynamic_cast< FormObjEventListenerImpl* >( m_DialogListener.get() ); - if ( pFormListener ) - pFormListener->removeListener(); + if ( m_DialogListener.get() ) + m_DialogListener->removeListener(); m_DialogListener = new FormObjEventListenerImpl( this, xComponent ); triggerInitializeEvent(); diff --git a/basic/source/comp/codegen.cxx b/basic/source/comp/codegen.cxx index 46f829b382e8..93fb18baf86e 100644 --- a/basic/source/comp/codegen.cxx +++ b/basic/source/comp/codegen.cxx @@ -138,11 +138,10 @@ void SbiCodeGen::Save() pCLASSFAC->AddClassModule( &rMod ); nIfaceCount = pParser->aIfaceVector.size(); + if( !rMod.pClassData ) + rMod.pClassData = new SbClassData; if( nIfaceCount ) { - if( !rMod.pClassData ) - rMod.pClassData = new SbClassData; - for( int i = 0 ; i < nIfaceCount ; i++ ) { const String& rIfaceName = pParser->aIfaceVector[i]; @@ -152,6 +151,8 @@ void SbiCodeGen::Save() pIfaces->Insert( pIfaceVar, pIfaces->Count() ); } } + + rMod.pClassData->maRequiredTypes = pParser->aRequiredTypes; } else { @@ -161,6 +162,7 @@ void SbiCodeGen::Save() rMod.mnType = com::sun::star::script::ModuleType::NORMAL; rMod.bIsProxyModule = false; } + if( pParser->bText ) p->SetFlag( SBIMG_COMPARETEXT ); // GlobalCode-Flag @@ -257,6 +259,10 @@ void SbiCodeGen::Save() if( !pProc->IsPublic() ) pMeth->SetFlag( SBX_PRIVATE ); + // Declare? -> Hidden + if( pProc->GetLib().Len() > 0 ) + pMeth->SetFlag( SBX_HIDDEN ); + pMeth->nStart = pProc->GetAddr(); pMeth->nLine1 = pProc->GetLine1(); pMeth->nLine2 = pProc->GetLine2(); diff --git a/basic/source/comp/dim.cxx b/basic/source/comp/dim.cxx index bff3d22dd9b0..59d77e3f3757 100644 --- a/basic/source/comp/dim.cxx +++ b/basic/source/comp/dim.cxx @@ -161,6 +161,9 @@ void SbiParser::TypeDecl( SbiSymDef& rDef, BOOL bAsNewAlreadyParsed ) // In den String-Pool uebernehmen rDef.SetTypeId( aGblStrings.Add( aCompleteName ) ); + + if( rDef.IsNew() && pProc == NULL ) + aRequiredTypes.push_back( aCompleteName ); } eType = SbxOBJECT; break; @@ -874,7 +877,7 @@ SbiProcDef* SbiParser::ProcDecl( BOOL bDecl ) } if( bCompatible && Peek() == PARAMARRAY ) { - if( bByVal || bByVal || bOptional ) + if( bByVal || bOptional ) Error( SbERR_UNEXPECTED, PARAMARRAY ); Next(); bParamArray = TRUE; @@ -946,6 +949,8 @@ void SbiParser::DefDeclare( BOOL bPrivate ) Error( SbERR_UNEXPECTED, eCurTok ); else { + bool bFunction = (eCurTok == FUNCTION); + SbiProcDef* pDef = ProcDecl( TRUE ); if( pDef ) { @@ -970,7 +975,70 @@ void SbiParser::DefDeclare( BOOL bPrivate ) aPublics.Add( pDef ); if ( pDef ) + { pDef->SetPublic( !bPrivate ); + + // New declare handling + if( pDef->GetLib().Len() > 0 ) + { + if( bNewGblDefs && nGblChain == 0 ) + { + nGblChain = aGen.Gen( _JUMP, 0 ); + bNewGblDefs = FALSE; + } + + USHORT nSavLine = nLine; + aGen.Statement(); + pDef->Define(); + pDef->SetLine1( nSavLine ); + pDef->SetLine2( nSavLine ); + + SbiSymPool& rPool = pDef->GetParams(); + USHORT nParCount = rPool.GetSize(); + + SbxDataType eType = pDef->GetType(); + if( bFunction ) + aGen.Gen( _PARAM, 0, sal::static_int_cast< UINT16 >( eType ) ); + + if( nParCount > 1 ) + { + aGen.Gen( _ARGC ); + + for( USHORT i = 1 ; i < nParCount ; ++i ) + { + SbiSymDef* pParDef = rPool.Get( i ); + SbxDataType eParType = pParDef->GetType(); + + aGen.Gen( _PARAM, i, sal::static_int_cast< UINT16 >( eParType ) ); + aGen.Gen( _ARGV ); + + USHORT nTyp = sal::static_int_cast< USHORT >( pParDef->GetType() ); + if( pParDef->IsByVal() ) + { + // Reset to avoid additional byval in call to wrapper function + pParDef->SetByVal( FALSE ); + nTyp |= 0x8000; + } + aGen.Gen( _ARGTYP, nTyp ); + } + } + + aGen.Gen( _LIB, aGblStrings.Add( pDef->GetLib() ) ); + + SbiOpcode eOp = pDef->IsCdecl() ? _CALLC : _CALL; + USHORT nId = pDef->GetId(); + if( pDef->GetAlias().Len() ) + nId = ( nId & 0x8000 ) | aGblStrings.Add( pDef->GetAlias() ); + if( nParCount > 1 ) + nId |= 0x8000; + aGen.Gen( eOp, nId, sal::static_int_cast< UINT16 >( eType ) ); + + if( bFunction ) + aGen.Gen( _PUT ); + + aGen.Gen( _LEAVE ); + } + } } } } diff --git a/basic/source/comp/exprgen.cxx b/basic/source/comp/exprgen.cxx index 60869307aecf..3e034af204f5 100644 --- a/basic/source/comp/exprgen.cxx +++ b/basic/source/comp/exprgen.cxx @@ -115,13 +115,8 @@ void SbiExprNode::Gen( RecursiveMode eRecMode ) } else { - SbiProcDef* pProc = aVar.pDef->GetProcDef(); - // per DECLARE definiert? - if( pProc && pProc->GetLib().Len() ) - eOp = pProc->IsCdecl() ? _CALLC : _CALL; - else - eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL : - (aVar.pDef->IsGlobal() ? _FIND_G : _FIND); + eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL : + (aVar.pDef->IsGlobal() ? _FIND_G : _FIND); } if( eOp == _FIND ) @@ -187,17 +182,6 @@ void SbiExprNode::GenElement( SbiOpcode eOp ) aVar.pPar->Gen(); } - SbiProcDef* pProc = aVar.pDef->GetProcDef(); - // per DECLARE definiert? - if( pProc ) - { - // Dann evtl. einen LIB-Befehl erzeugen - if( pProc->GetLib().Len() ) - pGen->Gen( _LIB, pGen->GetParser()->aGblStrings.Add( pProc->GetLib() ) ); - // und den Aliasnamen nehmen - if( pProc->GetAlias().Len() ) - nId = ( nId & 0x8000 ) | pGen->GetParser()->aGblStrings.Add( pProc->GetAlias() ); - } pGen->Gen( eOp, nId, sal::static_int_cast< UINT16 >( GetType() ) ); if( aVar.pvMorePar ) @@ -223,13 +207,8 @@ void SbiExprList::Gen() { pParser->aGen.Gen( _ARGC ); // AB 10.1.96: Typ-Anpassung bei DECLARE - USHORT nCount = 1, nParAnz = 0; - SbiSymPool* pPool = NULL; - if( pProc ) - { - pPool = &pProc->GetParams(); - nParAnz = pPool->GetSize(); - } + USHORT nCount = 1 /*, nParAnz = 0*/; +// SbiSymPool* pPool = NULL; for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ ) { pExpr->Gen(); @@ -239,6 +218,7 @@ void SbiExprList::Gen() USHORT nSid = pParser->aGblStrings.Add( pExpr->GetName() ); pParser->aGen.Gen( _ARGN, nSid ); + /* TODO: Check after Declare concept change // AB 10.1.96: Typanpassung bei named -> passenden Parameter suchen if( pProc ) { @@ -246,39 +226,26 @@ void SbiExprList::Gen() pParser->Error( SbERR_NO_NAMED_ARGS ); // Spaeter, wenn Named Args bei DECLARE moeglich - /* - for( USHORT i = 1 ; i < nParAnz ; i++ ) - { - SbiSymDef* pDef = pPool->Get( i ); - const String& rName = pDef->GetName(); - if( rName.Len() ) - { - if( pExpr->GetName().ICompare( rName ) - == COMPARE_EQUAL ) - { - pParser->aGen.Gen( _ARGTYP, pDef->GetType() ); - break; - } - } - } - */ + //for( USHORT i = 1 ; i < nParAnz ; i++ ) + //{ + // SbiSymDef* pDef = pPool->Get( i ); + // const String& rName = pDef->GetName(); + // if( rName.Len() ) + // { + // if( pExpr->GetName().ICompare( rName ) + // == COMPARE_EQUAL ) + // { + // pParser->aGen.Gen( _ARGTYP, pDef->GetType() ); + // break; + // } + // } + //} } + */ } else { pParser->aGen.Gen( _ARGV ); - - // Funktion mit DECLARE -> Typ-Anpassung - if( pProc && nCount < nParAnz ) - { - SbiSymDef* pDef = pPool->Get( nCount ); - USHORT nTyp = sal::static_int_cast< USHORT >( - pDef->GetType() ); - // Zustzliches Flag fr BYVAL einbauen - if( pDef->IsByVal() ) - nTyp |= 0x8000; - pParser->aGen.Gen( _ARGTYP, nTyp ); - } } } } diff --git a/basic/source/comp/exprtree.cxx b/basic/source/comp/exprtree.cxx index 0cf0d9870378..7a4ea5965558 100644 --- a/basic/source/comp/exprtree.cxx +++ b/basic/source/comp/exprtree.cxx @@ -338,15 +338,6 @@ SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo ) // damit erwischen wir n% = 5 : print n eType = eDefType; } - // Funktion? - if( pDef->GetProcDef() ) - { - SbiProcDef* pProc = pDef->GetProcDef(); - if( pPar && pProc->GetLib().Len() ) // DECLARE benutzt? - pPar->SetProc( pProc ); - // Wenn keine Pars, vorerst nichts machen - // Pruefung auf Typ-Anzahl waere denkbar - } // Typcheck bei Variablen: // ist explizit im Scanner etwas anderes angegeben? // Bei Methoden ist dies OK! @@ -868,7 +859,6 @@ SbiExprList::SbiExprList( SbiParser* p ) { pParser = p; pFirst = NULL; - pProc = NULL; nExpr = nDim = 0; bError = @@ -1009,13 +999,8 @@ SbiParameters::SbiParameters( SbiParser* p, BOOL bStandaloneExpression, BOOL bPa else pExpr = new SbiExpression( pParser ); - if( bByVal ) - { - if( !pExpr->IsLvalue() ) - pParser->Error( SbERR_LVALUE_EXPECTED ); - else - pExpr->SetByVal(); - } + if( bByVal && pExpr->IsLvalue() ) + pExpr->SetByVal(); //pExpr = bConst ? new SbiConstExpression( pParser ) // : new SbiExpression( pParser ); diff --git a/basic/source/comp/makefile.mk b/basic/source/comp/makefile.mk index bd3c750df355..d65f6a431e43 100644 --- a/basic/source/comp/makefile.mk +++ b/basic/source/comp/makefile.mk @@ -34,39 +34,26 @@ TARGET=comp .INCLUDE : settings.mk -CXXFILES= \ - sbcomp.cxx \ - dim.cxx \ - exprtree.cxx \ - exprnode.cxx \ - exprgen.cxx \ - codegen.cxx \ - io.cxx \ - loops.cxx \ - parser.cxx \ - scanner.cxx \ - token.cxx \ - symtbl.cxx \ - buffer.cxx - SLOFILES= \ - $(SLO)$/sbcomp.obj \ + $(SLO)$/buffer.obj \ + $(SLO)$/codegen.obj \ $(SLO)$/dim.obj \ - $(SLO)$/exprtree.obj \ - $(SLO)$/exprnode.obj \ $(SLO)$/exprgen.obj \ - $(SLO)$/codegen.obj \ + $(SLO)$/exprnode.obj \ + $(SLO)$/exprtree.obj \ $(SLO)$/io.obj \ $(SLO)$/loops.obj \ $(SLO)$/parser.obj \ + $(SLO)$/sbcomp.obj \ $(SLO)$/scanner.obj \ - $(SLO)$/token.obj \ $(SLO)$/symtbl.obj \ - $(SLO)$/buffer.obj + $(SLO)$/token.obj EXCEPTIONSFILES= \ - $(SLO)$/parser.obj \ - $(SLO)$/exprtree.obj + $(SLO)$/codegen.obj \ + $(SLO)$/dim.obj \ + $(SLO)$/exprtree.obj \ + $(SLO)$/parser.obj # --- Targets -------------------------------------------------------------- diff --git a/basic/source/comp/sbcomp.cxx b/basic/source/comp/sbcomp.cxx index 6e4f7ddf126e..5b7e5c70591d 100644..100755 --- a/basic/source/comp/sbcomp.cxx +++ b/basic/source/comp/sbcomp.cxx @@ -31,10 +31,310 @@ #include <basic/sbx.hxx> #include "sbcomp.hxx" #include "image.hxx" +#include "sbtrace.hxx" +//========================================================================== +// Tracing, for debugging only + +// To activate tracing enable in sbtrace.hxx +#ifdef DBG_TRACE_BASIC + +#include <hash_map> + +// Trace Settings +static const char* GpTraceFileName = "d:\\zBasic.Asm\\BasicTrace.txt"; +static const bool GbIncludePCodes = false; +static const int GnIndentPerCallLevel = 4; +static const int GnIndentForPCode = 2; + +struct TraceTextData +{ + rtl::OString m_aTraceStr_STMNT; + rtl::OString m_aTraceStr_PCode; +}; +typedef std::hash_map< sal_Int32, TraceTextData > PCToTextDataMap; +typedef std::hash_map< ::rtl::OUString, PCToTextDataMap*, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleTraceMap; + +ModuleTraceMap GaModuleTraceMap; +ModuleTraceMap& rModuleTraceMap = GaModuleTraceMap; + +static void lcl_PrepareTraceForModule( SbModule* pModule ) +{ + String aModuleName = pModule->GetName(); + ModuleTraceMap::iterator it = rModuleTraceMap.find( aModuleName ); + if( it != rModuleTraceMap.end() ) + { + PCToTextDataMap* pInnerMap = it->second; + delete pInnerMap; + rModuleTraceMap.erase( it ); + } + + String aDisassemblyStr; + pModule->Disassemble( aDisassemblyStr ); +} + +static void lcl_lineOut( const char* pFileName, const char* pStr, const char* pPreStr = NULL ) +{ + const char* pPrintFirst = (pPreStr != NULL) ? pPreStr : ""; + FILE* pFile = fopen( pFileName, "a+" ); + if( pFile != NULL ) + { + fprintf( pFile, "%s%s\n", pPrintFirst, pStr ); + fclose( pFile ); + } +} + +const char* lcl_getSpaces( int nSpaceCount ) +{ + static sal_Char Spaces[] = " " + " " + " "; + static int nAvailableSpaceCount = strlen( Spaces ); + static sal_Char* pSpacesEnd = Spaces + nAvailableSpaceCount; + + if( nSpaceCount > nAvailableSpaceCount ) + nSpaceCount = nAvailableSpaceCount; + + return pSpacesEnd - nSpaceCount; +} + +static rtl::OString lcl_toOStringSkipLeadingWhites( const String& aStr ) +{ + static sal_Char Buffer[1000]; + + rtl::OString aOStr = OUStringToOString( rtl::OUString( aStr ), RTL_TEXTENCODING_ASCII_US ); + const sal_Char* pStr = aOStr.getStr(); + + // Skip whitespace + sal_Char c = *pStr; + while( c == ' ' || c == '\t' ) + { + pStr++; + c = *pStr; + } + + int nLen = strlen( pStr ); + strncpy( Buffer, pStr, nLen ); + Buffer[nLen] = 0; + + rtl::OString aORetStr( Buffer ); + return aORetStr; +} + +String dumpMethodParameters( SbMethod* pMethod ) +{ + String aStr; + if( pMethod == NULL ) + return aStr; + + SbxError eOld = SbxBase::GetError(); + + SbxArray* pParams = pMethod->GetParameters(); + SbxInfo* pInfo = pMethod->GetInfo(); + if ( pParams ) + { + aStr += '('; + // 0 is sub itself + for ( USHORT nParam = 1; nParam < pParams->Count(); nParam++ ) + { + SbxVariable* pVar = pParams->Get( nParam ); + DBG_ASSERT( pVar, "Parameter?!" ); + if ( pVar->GetName().Len() ) + aStr += pVar->GetName(); + else if ( pInfo ) + { + const SbxParamInfo* pParam = pInfo->GetParam( nParam ); + if ( pParam ) + aStr += pParam->aName; + } + aStr += '='; + if( pVar->GetType() & SbxARRAY ) + aStr += String( RTL_CONSTASCII_USTRINGPARAM( "..." ) ); + else + aStr += pVar->GetString(); + if ( nParam < ( pParams->Count() - 1 ) ) + aStr += String( RTL_CONSTASCII_USTRINGPARAM( ", " ) ); + } + aStr += ')'; + } + + SbxBase::ResetError(); + if( eOld != SbxERR_OK ) + SbxBase::SetError( eOld ); + + return aStr; +} + +// Public functions +void dbg_InitTrace( void ) +{ + FILE* pFile = fopen( GpTraceFileName, "w" ); + if( pFile != NULL ) + fclose( pFile ); +} + +void dbg_traceStep( SbModule* pModule, UINT32 nPC, INT32 nCallLvl ) +{ + SbModule* pTraceMod = pModule; + if( pTraceMod->ISA(SbClassModuleObject) ) + { + SbClassModuleObject* pClassModuleObj = (SbClassModuleObject*)(SbxBase*)pTraceMod; + pTraceMod = pClassModuleObj->getClassModule(); + } + + String aModuleName = pTraceMod->GetName(); + ModuleTraceMap::iterator it = rModuleTraceMap.find( aModuleName ); + if( it == rModuleTraceMap.end() ) + { + const char* pModuleNameStr = OUStringToOString( rtl::OUString( aModuleName ), RTL_TEXTENCODING_ASCII_US ).getStr(); + char Buffer[200]; + sprintf( Buffer, "TRACE ERROR: Unknown module \"%s\"", pModuleNameStr ); + lcl_lineOut( GpTraceFileName, Buffer ); + return; + } + + PCToTextDataMap* pInnerMap = it->second; + if( pInnerMap == NULL ) + { + lcl_lineOut( GpTraceFileName, "TRACE INTERNAL ERROR: No inner map" ); + return; + } + + PCToTextDataMap::iterator itInner = pInnerMap->find( nPC ); + if( itInner == pInnerMap->end() ) + { + const char* pModuleNameStr = OUStringToOString( rtl::OUString( aModuleName ), RTL_TEXTENCODING_ASCII_US ).getStr(); + char Buffer[200]; + sprintf( Buffer, "TRACE ERROR: No info for PC = %d in module \"%s\"", nPC, pModuleNameStr ); + lcl_lineOut( GpTraceFileName, Buffer ); + return; + } + + //nCallLvl--; + //if( nCallLvl < 0 ) + // nCallLvl = 0; + int nIndent = nCallLvl * GnIndentPerCallLevel; + + const TraceTextData& rTraceTextData = itInner->second; + const rtl::OString& rStr_STMNT = rTraceTextData.m_aTraceStr_STMNT; + if( rStr_STMNT.getLength() ) + lcl_lineOut( GpTraceFileName, rStr_STMNT.getStr(), lcl_getSpaces( nIndent ) ); + + if( !GbIncludePCodes ) + return; + + nIndent += GnIndentForPCode; + const rtl::OString& rStr_PCode = rTraceTextData.m_aTraceStr_PCode; + if( rStr_PCode.getLength() ) + lcl_lineOut( GpTraceFileName, rStr_PCode.getStr(), lcl_getSpaces( nIndent ) ); +} + +void dbg_traceNotifyCall( SbModule* pModule, SbMethod* pMethod, INT32 nCallLvl, bool bLeave ) +{ + static const char* pSeparator = "' ================================================================================"; + + SbModule* pTraceMod = pModule; + SbClassModuleObject* pClassModuleObj = NULL; + if( pTraceMod->ISA(SbClassModuleObject) ) + { + pClassModuleObj = (SbClassModuleObject*)(SbxBase*)pTraceMod; + pTraceMod = pClassModuleObj->getClassModule(); + } + + if( nCallLvl > 0 ) + nCallLvl--; + int nIndent = nCallLvl * GnIndentPerCallLevel; + if( !bLeave ) + { + lcl_lineOut( GpTraceFileName, "" ); + lcl_lineOut( GpTraceFileName, pSeparator, lcl_getSpaces( nIndent ) ); + } + + String aStr; + if( bLeave ) + { + lcl_lineOut( GpTraceFileName, "}", lcl_getSpaces( nIndent ) ); + aStr.AppendAscii( "' Leaving " ); + } + else + { + aStr.AppendAscii( "Entering " ); + } + String aModuleName = pTraceMod->GetName(); + aStr += aModuleName; + if( pMethod != NULL ) + { + aStr.AppendAscii( "::" ); + String aMethodName = pMethod->GetName(); + aStr += aMethodName; + } + else + { + aStr.AppendAscii( "/RunInit" ); + } + + if( pClassModuleObj != NULL ) + { + aStr.AppendAscii( "[this=" ); + aStr += pClassModuleObj->GetName(); + aStr.AppendAscii( "]" ); + } + if( !bLeave ) + aStr += dumpMethodParameters( pMethod ); + + lcl_lineOut( GpTraceFileName, OUStringToOString( rtl::OUString( aStr ), RTL_TEXTENCODING_ASCII_US ).getStr(), lcl_getSpaces( nIndent ) ); + if( !bLeave ) + lcl_lineOut( GpTraceFileName, "{", lcl_getSpaces( nIndent ) ); + + if( bLeave ) + lcl_lineOut( GpTraceFileName, "" ); +} + +void dbg_traceNotifyError( SbError nTraceErr, const String& aTraceErrMsg, bool bTraceErrHandled, INT32 nCallLvl ) +{ + rtl::OString aOTraceErrMsg = OUStringToOString( rtl::OUString( aTraceErrMsg ), RTL_TEXTENCODING_ASCII_US ); + + char Buffer[200]; + const char* pHandledStr = bTraceErrHandled ? " / HANDLED" : ""; + sprintf( Buffer, "*** ERROR%s, Id = %d, Msg = \"%s\" ***", pHandledStr, (int)nTraceErr, aOTraceErrMsg.getStr() ); + int nIndent = nCallLvl * GnIndentPerCallLevel; + lcl_lineOut( GpTraceFileName, Buffer, lcl_getSpaces( nIndent ) ); +} + +void dbg_RegisterTraceTextForPC( SbModule* pModule, UINT32 nPC, + const String& aTraceStr_STMNT, const String& aTraceStr_PCode ) +{ + String aModuleName = pModule->GetName(); + ModuleTraceMap::iterator it = rModuleTraceMap.find( aModuleName ); + PCToTextDataMap* pInnerMap; + if( it == rModuleTraceMap.end() ) + { + pInnerMap = new PCToTextDataMap(); + rModuleTraceMap[ aModuleName ] = pInnerMap; + } + else + { + pInnerMap = it->second; + } + + TraceTextData aData; + + rtl::OString aOTraceStr_STMNT = lcl_toOStringSkipLeadingWhites( aTraceStr_STMNT ); + aData.m_aTraceStr_STMNT = aOTraceStr_STMNT; + + rtl::OString aOTraceStr_PCode = lcl_toOStringSkipLeadingWhites( aTraceStr_PCode ); + aData.m_aTraceStr_PCode = aOTraceStr_PCode; + + (*pInnerMap)[nPC] = aData; +} + +#endif + + +//========================================================================== // For debugging only -// #define DBG_SAVE_DISASSEMBLY +//#define DBG_SAVE_DISASSEMBLY #ifdef DBG_SAVE_DISASSEMBLY static bool dbg_bDisassemble = true; @@ -67,7 +367,7 @@ void dbg_SaveDisassembly( SbModule* pModule ) ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY ); if( xSFI.is() ) { - String aFile( RTL_CONSTASCII_USTRINGPARAM("file:///d:/BasicAsm_") ); + String aFile( RTL_CONSTASCII_USTRINGPARAM("file:///d:/zBasic.Asm/Asm_") ); StarBASIC* pBasic = (StarBASIC*)pModule->GetParent(); if( pBasic ) { @@ -99,6 +399,7 @@ void dbg_SaveDisassembly( SbModule* pModule ) } #endif + // Diese Routine ist hier definiert, damit der Compiler als eigenes Segment // geladen werden kann. @@ -131,6 +432,7 @@ BOOL SbModule::Compile() if( bRet ) { pBasic->ClearAllModuleVars(); + RemoveVars(); // remove 'this' Modules variables // clear all method statics for( USHORT i = 0; i < pMethods->Count(); i++ ) { @@ -154,6 +456,10 @@ BOOL SbModule::Compile() dbg_SaveDisassembly( this ); #endif +#ifdef DBG_TRACE_BASIC + lcl_PrepareTraceForModule( this ); +#endif + return bRet; } diff --git a/basic/source/inc/expr.hxx b/basic/source/inc/expr.hxx index 9b8f51d09dea..851d0d6f1fe5 100644 --- a/basic/source/inc/expr.hxx +++ b/basic/source/inc/expr.hxx @@ -234,7 +234,6 @@ class SbiExprList { // Basisklasse fuer Parameter und Dims protected: SbiParser* pParser; // Parser SbiExpression* pFirst; // Expressions - SbiProcDef* pProc; // DECLARE-Funktion (Parameter-Anpassung) short nExpr; // Anzahl Expressions short nDim; // Anzahl Dimensionen BOOL bError; // TRUE: Fehler @@ -249,8 +248,6 @@ public: SbiExpression* Get( short ); BOOL Test( const SbiProcDef& ); // Parameter-Checks void Gen(); // Code-Erzeugung - // Setzen einer Funktionsdefinition zum Abgleich der Parameter - void SetProc( SbiProcDef* p ) { pProc = p; } void addExpression( SbiExpression* pExpr ); }; diff --git a/basic/source/inc/namecont.hxx b/basic/source/inc/namecont.hxx index ac1199f6c233..7fd6eb06f607 100644 --- a/basic/source/inc/namecont.hxx +++ b/basic/source/inc/namecont.hxx @@ -60,7 +60,7 @@ #include <cppuhelper/implbase2.hxx> #include <cppuhelper/compbase8.hxx> #include <cppuhelper/interfacecontainer.hxx> -#include <com/sun/star/script/XVBACompat.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> class BasicManager; @@ -74,7 +74,7 @@ typedef ::cppu::WeakComponentImplHelper8< ::com::sun::star::script::XLibraryContainerExport, ::com::sun::star::script::XLibraryContainer3, ::com::sun::star::container::XContainer, - ::com::sun::star::script::XVBACompat, + ::com::sun::star::script::vba::XVBACompatibility, ::com::sun::star::lang::XServiceInfo > LibraryContainerHelper; typedef ::cppu::WeakImplHelper2< ::com::sun::star::container::XNameContainer, @@ -507,9 +507,9 @@ public: throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException) = 0; - // Methods XVBACompat - virtual ::sal_Bool SAL_CALL getVBACompatModeOn() throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setVBACompatModeOn( ::sal_Bool _vbacompatmodeon ) throw (::com::sun::star::uno::RuntimeException); + // Methods XVBACompatibility + virtual ::sal_Bool SAL_CALL getVBACompatibilityMode() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon ) throw (::com::sun::star::uno::RuntimeException); }; class LibraryContainerMethodGuard diff --git a/basic/source/inc/parser.hxx b/basic/source/inc/parser.hxx index 1161c4ed259d..733a65db7f61 100644 --- a/basic/source/inc/parser.hxx +++ b/basic/source/inc/parser.hxx @@ -34,7 +34,7 @@ #include <vector> -typedef ::std::vector< String > IfaceVector; +typedef ::std::vector< String > StringVector; struct SbiParseStack; @@ -81,7 +81,8 @@ public: BOOL bText; // OPTION COMPARE TEXT BOOL bExplicit; // TRUE: OPTION EXPLICIT BOOL bClassModule; // TRUE: OPTION ClassModule - IfaceVector aIfaceVector; // Holds all interfaces implemented by a class module + StringVector aIfaceVector; // Holds all interfaces implemented by a class module + StringVector aRequiredTypes; // Types used in Dim As New <type> outside subs SbxDataType eDefTypes[26]; // DEFxxx-Datentypen SbiParser( StarBASIC*, SbModule* ); diff --git a/basic/source/inc/sbintern.hxx b/basic/source/inc/sbintern.hxx index 59cfe21d25a8..4c54e2301bd5 100644 --- a/basic/source/inc/sbintern.hxx +++ b/basic/source/inc/sbintern.hxx @@ -50,10 +50,16 @@ public: virtual SbxObject* CreateObject( const String& ); }; +typedef ::std::vector< String > StringVector; + struct SbClassData { SbxArrayRef mxIfaces; + // types this module depends on because of use in Dim As New <type> + // needed for initialization order of class modules + StringVector maRequiredTypes; + SbClassData( void ); ~SbClassData( void ) { clear(); } diff --git a/basic/source/inc/sbtrace.hxx b/basic/source/inc/sbtrace.hxx new file mode 100755 index 000000000000..e8a482c2f6e9 --- /dev/null +++ b/basic/source/inc/sbtrace.hxx @@ -0,0 +1,42 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SBTRACE_HXX +#define _SBTRACE_HXX + +// #define DBG_TRACE_BASIC + +#ifdef DBG_TRACE_BASIC +void dbg_InitTrace( void ); +void dbg_traceStep( SbModule* pModule, UINT32 nPC, INT32 nCallLvl ); +void dbg_traceNotifyCall( SbModule* pModule, SbMethod* pMethod, INT32 nCallLvl, bool bLeave = false ); +void dbg_traceNotifyError( SbError nTraceErr, const String& aTraceErrMsg, bool bTraceErrHandled, INT32 nCallLvl ); +void dbg_RegisterTraceTextForPC( SbModule* pModule, UINT32 nPC, + const String& aTraceStr_STMNT, const String& aTraceStr_PCode ); +#endif + +#endif diff --git a/basic/source/inc/sbunoobj.hxx b/basic/source/inc/sbunoobj.hxx index 2d9836e3530e..78afa9783ca8 100644 --- a/basic/source/inc/sbunoobj.hxx +++ b/basic/source/inc/sbunoobj.hxx @@ -52,6 +52,7 @@ class SbUnoObject: public SbxObject ::com::sun::star::uno::Reference< ::com::sun::star::beans::XExactName > mxExactName; ::com::sun::star::uno::Reference< ::com::sun::star::beans::XExactName > mxExactNameInvocation; BOOL bNeedIntrospection; + BOOL bIgnoreNativeCOMObjectMembers; ::com::sun::star::uno::Any maTmpUnoObj; // Only to save obj for doIntrospection! // Hilfs-Methode zum Anlegen der dbg_-Properties diff --git a/basic/source/inc/scriptcont.hxx b/basic/source/inc/scriptcont.hxx index d184a2d558e2..091fbc24cdbe 100644 --- a/basic/source/inc/scriptcont.hxx +++ b/basic/source/inc/scriptcont.hxx @@ -30,7 +30,7 @@ #include "namecont.hxx" #include <basic/basmgr.hxx> -#include <com/sun/star/script/XVBAModuleInfo.hpp> +#include <com/sun/star/script/vba/XVBAModuleInfo.hpp> #include <comphelper/uno3.hxx> class BasicManager; @@ -141,7 +141,7 @@ public: //============================================================================ typedef std::hash_map< ::rtl::OUString, ::com::sun::star::script::ModuleInfo, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleInfoMap; -typedef ::cppu::ImplHelper1 < ::com::sun::star::script::XVBAModuleInfo +typedef ::cppu::ImplHelper1 < ::com::sun::star::script::vba::XVBAModuleInfo > SfxScriptLibrary_BASE; class SfxScriptLibrary : public SfxLibrary diff --git a/basic/source/inc/symtbl.hxx b/basic/source/inc/symtbl.hxx index 9bd8cfd49754..f2fbaa0ac1f1 100644 --- a/basic/source/inc/symtbl.hxx +++ b/basic/source/inc/symtbl.hxx @@ -159,7 +159,8 @@ public: void SetOptional() { bOpt = TRUE; } void SetParamArray() { bParamArray = TRUE; } void SetWithEvents() { bWithEvents = TRUE; } - void SetByVal() { bByVal = TRUE; } + void SetByVal( BOOL bByVal_ = TRUE ) + { bByVal = bByVal_; } void SetStatic( BOOL bAsStatic = TRUE ) { bStatic = bAsStatic; } void SetNew() { bNew = TRUE; } void SetDefinedAs() { bAs = TRUE; } diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx index 36fbda5c9097..1a60a5d79a45 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -4134,8 +4134,7 @@ RTLFUNC(Load) { if( pObj->IsA( TYPE( SbUserFormModule ) ) ) { - SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj; - pFormModule->load(); + ((SbUserFormModule*)pObj)->Load(); } else if( pObj->IsA( TYPE( SbxObject ) ) ) { diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx index 8c7da2403705..62e9c388f5c5 100644 --- a/basic/source/runtime/methods1.cxx +++ b/basic/source/runtime/methods1.cxx @@ -528,11 +528,13 @@ RTLFUNC(DoEvents) (void)pBasic; (void)bWrite; (void)rPar; - Timer aTimer; - aTimer.SetTimeout( 1 ); - aTimer.Start(); - while ( aTimer.IsActive() ) - Application::Yield(); + // Dummy implementation as the following code leads + // to performance problems for unknown reasons + //Timer aTimer; + //aTimer.SetTimeout( 1 ); + //aTimer.Start(); + //while ( aTimer.IsActive() ) + // Application::Reschedule(); } RTLFUNC(GetGUIVersion) @@ -1586,8 +1588,6 @@ RTLFUNC(Join) } -typedef ::std::vector< String > StringVector; - RTLFUNC(Split) { (void)pBasic; diff --git a/basic/source/runtime/props.cxx b/basic/source/runtime/props.cxx index cec74444e7a2..663d12fbcd72 100644 --- a/basic/source/runtime/props.cxx +++ b/basic/source/runtime/props.cxx @@ -76,6 +76,13 @@ RTLFUNC(False) rPar.Get(0)->PutBool( FALSE ); } +RTLFUNC(Empty) +{ + (void)pBasic; + (void)bWrite; + (void)rPar; +} + RTLFUNC(Nothing) { (void)pBasic; diff --git a/basic/source/runtime/rtlproto.hxx b/basic/source/runtime/rtlproto.hxx index 1a1ae4f32283..5437654f69a0 100644 --- a/basic/source/runtime/rtlproto.hxx +++ b/basic/source/runtime/rtlproto.hxx @@ -38,6 +38,7 @@ extern RTLFUNC(Date); extern RTLFUNC(Err); extern RTLFUNC(Erl); extern RTLFUNC(False); +extern RTLFUNC(Empty); extern RTLFUNC(Nothing); extern RTLFUNC(Null); extern RTLFUNC(True); diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index c3419adbfdb3..1bb6fb82e113 100755 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -44,6 +44,7 @@ #include <com/sun/star/container/XEnumerationAccess.hpp> #include "sbunoobj.hxx" #include "errobject.hxx" +#include "sbtrace.hxx" using namespace ::com::sun::star; @@ -720,6 +721,12 @@ BOOL SbiRuntime::Step() if( pInst->IsReschedule() && bStaticGlobalEnableReschedule ) Application::Reschedule(); } + +#ifdef DBG_TRACE_BASIC + UINT32 nPC = ( pCode - (const BYTE* )pImg->GetCode() ); + dbg_traceStep( pMod, nPC, pINST->nCallLvl ); +#endif + SbiOpcode eOp = (SbiOpcode ) ( *pCode++ ); UINT32 nOp1, nOp2; if( eOp <= SbOP0_END ) @@ -756,6 +763,11 @@ BOOL SbiRuntime::Step() // (insbesondere nicht nach Compiler-Fehlern zur Laufzeit) if( nError && bRun ) { +#ifdef DBG_TRACE_BASIC + SbError nTraceErr = nError; + String aTraceErrMsg = GetSbData()->aErrMsg; + bool bTraceErrHandled = true; +#endif SbError err = nError; ClearExprStack(); nError = 0; @@ -836,12 +848,19 @@ BOOL SbiRuntime::Step() // Kein Error-Hdl gefunden -> altes Vorgehen else { +#ifdef DBG_TRACE_BASIC + bTraceErrHandled = false; +#endif pInst->Abort(); } // ALT: Nur // pInst->Abort(); } + +#ifdef DBG_TRACE_BASIC + dbg_traceNotifyError( nTraceErr, aTraceErrMsg, bTraceErrHandled, pINST->nCallLvl ); +#endif } } return bRun; diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx index 60d2e9cf448d..4455901bfeba 100644 --- a/basic/source/runtime/stdobj.cxx +++ b/basic/source/runtime/stdobj.cxx @@ -221,6 +221,7 @@ static Methods aMethods[] = { { "FileSpec", SbxSTRING, 0,NULL,0 }, { "DumpAll", SbxINTEGER, _OPT, NULL,0 }, +{ "Empty", SbxVARIANT, _CPROP, RTLNAME(Empty),0 }, { "EqualUnoObjects",SbxBOOL, 2 | _FUNCTION, RTLNAME(EqualUnoObjects),0 }, { "Variant", SbxVARIANT, 0,NULL,0 }, { "Variant", SbxVARIANT, 0,NULL,0 }, diff --git a/basic/source/runtime/step0.cxx b/basic/source/runtime/step0.cxx index 1d9333ff7555..06a8bb19af00 100644 --- a/basic/source/runtime/step0.cxx +++ b/basic/source/runtime/step0.cxx @@ -312,9 +312,21 @@ void SbiRuntime::StepIS() { SbxVariableRef refVar1 = PopVar(); SbxVariableRef refVar2 = PopVar(); - BOOL bRes = BOOL( - refVar1->GetType() == SbxOBJECT - && refVar2->GetType() == SbxOBJECT ); + + SbxDataType eType1 = refVar1->GetType(); + SbxDataType eType2 = refVar2->GetType(); + if ( eType1 == SbxEMPTY ) + { + refVar1->Broadcast( SBX_HINT_DATAWANTED ); + eType1 = refVar1->GetType(); + } + if ( eType2 == SbxEMPTY ) + { + refVar2->Broadcast( SBX_HINT_DATAWANTED ); + eType2 = refVar2->GetType(); + } + + BOOL bRes = BOOL( eType1 == SbxOBJECT && eType2 == SbxOBJECT ); if ( bVBAEnabled && !bRes ) Error( SbERR_INVALID_USAGE_OBJECT ); bRes = ( bRes && refVar1->GetObject() == refVar2->GetObject() ); @@ -419,139 +431,143 @@ void SbiRuntime::StepPUT() void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, bool bHandleDefaultProp ) { // #67733 Typen mit Array-Flag sind auch ok - SbxDataType eValType = refVal->GetType(); + + // Check var, !object is no error for sure if, only if type is fixed SbxDataType eVarType = refVar->GetType(); - if( (eValType != SbxOBJECT - && eValType != SbxEMPTY -// seems like when using the default method its possible for objects -// to be empty ( no broadcast has taken place yet ) or the actual value is - - && !bHandleDefaultProp - && !(eValType & SbxARRAY)) || - (eVarType != SbxOBJECT - && eVarType != SbxEMPTY - && !bHandleDefaultProp - && !(eVarType & SbxARRAY) ) ) + if( !bHandleDefaultProp && eVarType != SbxOBJECT && !(eVarType & SbxARRAY) && refVar->IsFixed() ) { Error( SbERR_INVALID_USAGE_OBJECT ); + return; } - else + + // Check value, !object is no error for sure if, only if type is fixed + SbxDataType eValType = refVal->GetType(); +// bool bGetValObject = false; + if( !bHandleDefaultProp && eValType != SbxOBJECT && !(eValType & SbxARRAY) && refVal->IsFixed() ) + { + Error( SbERR_INVALID_USAGE_OBJECT ); + return; + } + + // Getting in here causes problems with objects with default properties + // if they are SbxEMPTY I guess + if ( !bHandleDefaultProp || ( bHandleDefaultProp && eValType == SbxOBJECT ) ) { - // Getting in here causes problems with objects with default properties - // if they are SbxEMPTY I guess - if ( !bHandleDefaultProp || ( bHandleDefaultProp && refVal->GetType() == SbxOBJECT ) ) + // Auf refVal GetObject fuer Collections ausloesen + SbxBase* pObjVarObj = refVal->GetObject(); + if( pObjVarObj ) { - // Auf refVal GetObject fuer Collections ausloesen - SbxBase* pObjVarObj = refVal->GetObject(); - if( pObjVarObj ) - { - SbxVariableRef refObjVal = PTR_CAST(SbxObject,pObjVarObj); + SbxVariableRef refObjVal = PTR_CAST(SbxObject,pObjVarObj); - // #67733 Typen mit Array-Flag sind auch ok - if( refObjVal ) - refVal = refObjVal; - else if( !(eValType & SbxARRAY) ) - refVal = NULL; - } + // #67733 Typen mit Array-Flag sind auch ok + if( refObjVal ) + refVal = refObjVal; + else if( !(eValType & SbxARRAY) ) + refVal = NULL; } + } - // #52896 Wenn Uno-Sequences bzw. allgemein Arrays einer als - // Object deklarierten Variable zugewiesen werden, kann hier - // refVal ungueltig sein! - if( !refVal ) + // #52896 Wenn Uno-Sequences bzw. allgemein Arrays einer als + // Object deklarierten Variable zugewiesen werden, kann hier + // refVal ungueltig sein! + if( !refVal ) + { + Error( SbERR_INVALID_USAGE_OBJECT ); + } + else + { + // Store auf die eigene Methode (innerhalb einer Function)? + BOOL bFlagsChanged = FALSE; + USHORT n = 0; + if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) { - Error( SbERR_INVALID_USAGE_OBJECT ); + bFlagsChanged = TRUE; + n = refVar->GetFlags(); + refVar->SetFlag( SBX_WRITE ); } - else - { - // Store auf die eigene Methode (innerhalb einer Function)? - BOOL bFlagsChanged = FALSE; - USHORT n = 0; - if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) - { - bFlagsChanged = TRUE; - n = refVar->GetFlags(); - refVar->SetFlag( SBX_WRITE ); - } - SbProcedureProperty* pProcProperty = PTR_CAST(SbProcedureProperty,(SbxVariable*)refVar); - if( pProcProperty ) - pProcProperty->setSet( true ); + SbProcedureProperty* pProcProperty = PTR_CAST(SbProcedureProperty,(SbxVariable*)refVar); + if( pProcProperty ) + pProcProperty->setSet( true ); - if ( bHandleDefaultProp ) + if ( bHandleDefaultProp ) + { + // get default properties for lhs & rhs where necessary + // SbxVariable* defaultProp = NULL; unused variable + bool bLHSHasDefaultProp = false; + // LHS try determine if a default prop exists + if ( refVar->GetType() == SbxOBJECT ) { - // get default properties for lhs & rhs where necessary - // SbxVariable* defaultProp = NULL; unused variable - bool bLHSHasDefaultProp = false; - // LHS try determine if a default prop exists - if ( refVar->GetType() == SbxOBJECT ) + SbxVariable* pDflt = getDefaultProp( refVar ); + if ( pDflt ) { - SbxVariable* pDflt = getDefaultProp( refVar ); - if ( pDflt ) - { - refVar = pDflt; - bLHSHasDefaultProp = true; - } + refVar = pDflt; + bLHSHasDefaultProp = true; } - // RHS only get a default prop is the rhs has one - if ( refVal->GetType() == SbxOBJECT ) - { - // check if lhs is a null object - // if it is then use the object not the default property - SbxObject* pObj = NULL; + } + // RHS only get a default prop is the rhs has one + if ( refVal->GetType() == SbxOBJECT ) + { + // check if lhs is a null object + // if it is then use the object not the default property + SbxObject* pObj = NULL; - pObj = PTR_CAST(SbxObject,(SbxVariable*)refVar); + pObj = PTR_CAST(SbxObject,(SbxVariable*)refVar); - // calling GetObject on a SbxEMPTY variable raises - // object not set errors, make sure its an Object - if ( !pObj && refVar->GetType() == SbxOBJECT ) - { - SbxBase* pObjVarObj = refVar->GetObject(); - pObj = PTR_CAST(SbxObject,pObjVarObj); - } - SbxVariable* pDflt = NULL; - if ( pObj || bLHSHasDefaultProp ) - // lhs is either a valid object || or has a defaultProp - pDflt = getDefaultProp( refVal ); - if ( pDflt ) - refVal = pDflt; + // calling GetObject on a SbxEMPTY variable raises + // object not set errors, make sure its an Object + if ( !pObj && refVar->GetType() == SbxOBJECT ) + { + SbxBase* pObjVarObj = refVar->GetObject(); + pObj = PTR_CAST(SbxObject,pObjVarObj); } + SbxVariable* pDflt = NULL; + if ( pObj || bLHSHasDefaultProp ) + // lhs is either a valid object || or has a defaultProp + pDflt = getDefaultProp( refVal ); + if ( pDflt ) + refVal = pDflt; } + } - // Handle withevents - BOOL bWithEvents = refVar->IsSet( SBX_WITH_EVENTS ); + // Handle withevents + BOOL bWithEvents = refVar->IsSet( SBX_WITH_EVENTS ); + if ( bWithEvents ) + { Reference< XInterface > xComListener; - if( bWithEvents ) + + SbxBase* pObj = refVal->GetObject(); + SbUnoObject* pUnoObj = (pObj != NULL) ? PTR_CAST(SbUnoObject,pObj) : NULL; + if( pUnoObj != NULL ) { - SbxBase* pObj = refVal->GetObject(); - SbUnoObject* pUnoObj = (pObj != NULL) ? PTR_CAST(SbUnoObject,pObj) : NULL; - if( pUnoObj != NULL ) - { - Any aControlAny = pUnoObj->getUnoAny(); - String aDeclareClassName = refVar->GetDeclareClassName(); - ::rtl::OUString aVBAType = aDeclareClassName; - ::rtl::OUString aPrefix = refVar->GetName(); - SbxObjectRef xScopeObj = refVar->GetParent(); - xComListener = createComListener( aControlAny, aVBAType, aPrefix, xScopeObj ); - } + Any aControlAny = pUnoObj->getUnoAny(); + String aDeclareClassName = refVar->GetDeclareClassName(); + ::rtl::OUString aVBAType = aDeclareClassName; + ::rtl::OUString aPrefix = refVar->GetName(); + SbxObjectRef xScopeObj = refVar->GetParent(); + xComListener = createComListener( aControlAny, aVBAType, aPrefix, xScopeObj ); + + refVal->SetDeclareClassName( aDeclareClassName ); + refVal->SetComListener( xComListener ); // Hold reference } *refVar = *refVal; - - if( bWithEvents ) - refVar->SetComListener( xComListener ); // Hold reference - - // lhs is a property who's value is currently (Empty e.g. no broadcast yet) - // in this case if there is a default prop involved the value of the - // default property may infact be void so the type will also be SbxEMPTY - // in this case we do not want to call checkUnoStructCopy 'cause that will - // cause an error also - if ( !bHandleDefaultProp || ( bHandleDefaultProp && ( refVar->GetType() != SbxEMPTY ) ) ) - // #67607 Uno-Structs kopieren - checkUnoStructCopy( refVal, refVar ); - if( bFlagsChanged ) - refVar->SetFlags( n ); } + else + { + *refVar = *refVal; + } + + // lhs is a property who's value is currently (Empty e.g. no broadcast yet) + // in this case if there is a default prop involved the value of the + // default property may infact be void so the type will also be SbxEMPTY + // in this case we do not want to call checkUnoStructCopy 'cause that will + // cause an error also + if ( !bHandleDefaultProp || ( bHandleDefaultProp && ( refVar->GetType() != SbxEMPTY ) ) ) + // #67607 Uno-Structs kopieren + checkUnoStructCopy( refVal, refVar ); + if( bFlagsChanged ) + refVar->SetFlags( n ); } } diff --git a/basic/source/runtime/step2.cxx b/basic/source/runtime/step2.cxx index 72ea67dd8db4..587b0ae7a590 100644..100755 --- a/basic/source/runtime/step2.cxx +++ b/basic/source/runtime/step2.cxx @@ -263,8 +263,10 @@ SbxVariable* SbiRuntime::FindElement pElem = pNew; } // Index-Access bei UnoObjekten beruecksichtigen - /* - else if( pElem->ISA(SbUnoProperty) ) + // definitely we want this for VBA where properties are often + // collections ( which need index access ), but lets only do + // this if we actually have params following + else if( bVBAEnabled && pElem->ISA(SbUnoProperty) && pElem->GetParameters() ) { // pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen SbxVariableRef refTemp = pElem; @@ -274,7 +276,6 @@ SbxVariable* SbiRuntime::FindElement pElem->SetParameters( NULL ); // sonst bleibt Ref auf sich selbst pElem = pNew; } - */ } return CheckArray( pElem ); } @@ -377,7 +378,8 @@ void SbiRuntime::SetupArgs( SbxVariable* p, UINT32 nOp1 ) bool bError_ = true; SbUnoMethod* pUnoMethod = PTR_CAST(SbUnoMethod,p); - if( pUnoMethod ) + SbUnoProperty* pUnoProperty = PTR_CAST(SbUnoProperty,p); + if( pUnoMethod || pUnoProperty ) { SbUnoObject* pParentUnoObj = PTR_CAST( SbUnoObject,p->GetParent() ); if( pParentUnoObj ) @@ -677,7 +679,18 @@ void SbiRuntime::StepPARAM( UINT32 nOp1, UINT32 nOp2 ) while( iLoop >= nParamCount ) { p = new SbxVariable(); - p->PutErr( 448 ); // Wie in VB: Error-Code 448 (SbERR_NAMED_NOT_FOUND) + + if( SbiRuntime::isVBAEnabled() && + (t == SbxOBJECT || t == SbxSTRING) ) + { + if( t == SbxOBJECT ) + p->PutObject( NULL ); + else + p->PutString( String() ); + } + else + p->PutErr( 448 ); // Wie in VB: Error-Code 448 (SbERR_NAMED_NOT_FOUND) + refParams->Put( p, iLoop ); iLoop--; } @@ -1157,15 +1170,26 @@ void SbiRuntime::StepGLOBAL( UINT32 nOp1, UINT32 nOp2 ) StepPUBLIC_Impl( nOp1, nOp2, true ); String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); - SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);; - BOOL bFlag = rBasic.IsSet( SBX_NO_MODIFY ); + SbxDataType t = (SbxDataType)(nOp2 & 0xffff); + + // Store module scope variables at module scope + // in non vba mode these are stored at the library level :/ + // not sure if this really should not be enabled for ALL basic + SbxObject* pStorage = &rBasic; + if ( SbiRuntime::isVBAEnabled() ) + { + pStorage = pMod; + pMod->AddVarName( aName ); + } + + BOOL bFlag = pStorage->IsSet( SBX_NO_MODIFY ); rBasic.SetFlag( SBX_NO_MODIFY ); - SbxVariableRef p = rBasic.Find( aName, SbxCLASS_PROPERTY ); + SbxVariableRef p = pStorage->Find( aName, SbxCLASS_PROPERTY ); if( p.Is() ) - rBasic.Remove (p); - p = rBasic.Make( aName, SbxCLASS_PROPERTY, t ); + pStorage->Remove (p); + p = pStorage->Make( aName, SbxCLASS_PROPERTY, t ); if( !bFlag ) - rBasic.ResetFlag( SBX_NO_MODIFY ); + pStorage->ResetFlag( SBX_NO_MODIFY ); if( p ) { p->SetFlag( SBX_DONTSTORE ); diff --git a/basic/source/sbx/sbxbool.cxx b/basic/source/sbx/sbxbool.cxx index 728b8e1472b0..3216e401b707 100644 --- a/basic/source/sbx/sbxbool.cxx +++ b/basic/source/sbx/sbxbool.cxx @@ -87,21 +87,20 @@ enum SbxBOOL ImpGetBool( const SbxValues* p ) case SbxSTRING: case SbxLPSTR: nRes = SbxFALSE; - if( p->pString ) + if ( p->pOUString ) { - if( p->pString->EqualsIgnoreCaseAscii( SbxRes( STRING_TRUE ) ) ) + if( p->pOUString->equalsIgnoreAsciiCase( SbxRes( STRING_TRUE ) ) ) nRes = SbxTRUE; - else if( !p->pString->EqualsIgnoreCaseAscii( SbxRes( STRING_FALSE ) ) ) + else if( p->pOUString->equalsIgnoreAsciiCase( SbxRes( STRING_FALSE ) ) ) { // Jetzt kann es noch in eine Zahl konvertierbar sein BOOL bError = TRUE; double n; SbxDataType t; USHORT nLen = 0; - String s( *p->pString ); - if( ImpScan( s, n, t, &nLen ) == SbxERR_OK ) + if( ImpScan( *p->pOUString, n, t, &nLen ) == SbxERR_OK ) { - if( nLen == s.Len() ) + if( nLen == p->pOUString->getLength() ) { bError = FALSE; if( n != 0.0 ) @@ -202,9 +201,10 @@ void ImpPutBool( SbxValues* p, INT16 n ) case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; - *p->pString = SbxRes( n ? STRING_TRUE : STRING_FALSE ); + if ( !p->pOUString ) + p->pOUString = new ::rtl::OUString( SbxRes( n ? STRING_TRUE : STRING_FALSE ) ); + else + *p->pOUString = SbxRes( n ? STRING_TRUE : STRING_FALSE ); break; case SbxOBJECT: diff --git a/basic/source/sbx/sbxbyte.cxx b/basic/source/sbx/sbxbyte.cxx index 8485b7105e21..e13c63967fc3 100644 --- a/basic/source/sbx/sbxbyte.cxx +++ b/basic/source/sbx/sbxbyte.cxx @@ -165,13 +165,13 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else if( d > SbxMAXBYTE ) { @@ -279,9 +279,9 @@ void ImpPutByte( SbxValues* p, BYTE n ) case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; - ImpCvtNum( (double) n, 0, *p->pString ); + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; + ImpCvtNum( (double) n, 0, *p->pOUString ); break; case SbxOBJECT: { diff --git a/basic/source/sbx/sbxchar.cxx b/basic/source/sbx/sbxchar.cxx index f9bca67a28d9..bd4ce91f451b 100644 --- a/basic/source/sbx/sbxchar.cxx +++ b/basic/source/sbx/sbxchar.cxx @@ -39,7 +39,7 @@ using namespace rtl; xub_Unicode ImpGetChar( const SbxValues* p ) { SbxValues aTmp; - xub_Unicode nRes; + xub_Unicode nRes = 0; start: switch( +p->eType ) { @@ -156,13 +156,11 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - nRes = 0; - else + if ( p->pOUString ) { double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else if( d > SbxMAXCHAR ) { @@ -274,9 +272,10 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; - *p->pString = n; + if ( !p->pOUString ) + p->pOUString = new ::rtl::OUString( n ); + else + *p->pOUString = ::rtl::OUString( n ); break; case SbxOBJECT: { diff --git a/basic/source/sbx/sbxconv.hxx b/basic/source/sbx/sbxconv.hxx index c1ada75286ab..16fec542cded 100644 --- a/basic/source/sbx/sbxconv.hxx +++ b/basic/source/sbx/sbxconv.hxx @@ -33,13 +33,13 @@ class SbxArray; // SBXSCAN.CXX -extern void ImpCvtNum( double nNum, short nPrec, String& rRes, BOOL bCoreString=FALSE ); +extern void ImpCvtNum( double nNum, short nPrec, ::rtl::OUString& rRes, BOOL bCoreString=FALSE ); extern SbxError ImpScan - ( const String& rSrc, double& nVal, SbxDataType& rType, USHORT* pLen, + ( const ::rtl::OUString& rSrc, double& nVal, SbxDataType& rType, USHORT* pLen, BOOL bAllowIntntl=FALSE, BOOL bOnlyIntntl=FALSE ); // mit erweiterter Auswertung (International, "TRUE"/"FALSE") -extern BOOL ImpConvStringExt( String& rSrc, SbxDataType eTargetType ); +extern BOOL ImpConvStringExt( ::rtl::OUString& rSrc, SbxDataType eTargetType ); // SBXINT.CXX @@ -116,9 +116,9 @@ void ImpPutDate( SbxValues*, double ); // SBXSTR.CXX -String ImpGetString( const SbxValues* ); -String ImpGetCoreString( const SbxValues* ); -void ImpPutString( SbxValues*, const String* ); +::rtl::OUString ImpGetString( const SbxValues* ); +::rtl::OUString ImpGetCoreString( const SbxValues* ); +void ImpPutString( SbxValues*, const ::rtl::OUString* ); // SBXCHAR.CXX @@ -145,7 +145,7 @@ enum SbxBOOL ImpGetBool( const SbxValues* ); void ImpPutBool( SbxValues*, INT16 ); // ByteArry <--> String -SbxArray* StringToByteArray(const String& rStr); -String ByteArrayToString(SbxArray* pArr); +SbxArray* StringToByteArray(const ::rtl::OUString& rStr); +::rtl::OUString ByteArrayToString(SbxArray* pArr); #endif diff --git a/basic/source/sbx/sbxcurr.cxx b/basic/source/sbx/sbxcurr.cxx index 74380f84a75f..e27b11d5166c 100644 --- a/basic/source/sbx/sbxcurr.cxx +++ b/basic/source/sbx/sbxcurr.cxx @@ -37,8 +37,8 @@ #include <basic/sbxvar.hxx> #include "sbxconv.hxx" -static String ImpCurrencyToString( const SbxINT64& ); -static SbxINT64 ImpStringToCurrency( const String& ); +static ::rtl::OUString ImpCurrencyToString( const SbxINT64& ); +static SbxINT64 ImpStringToCurrency( const ::rtl::OUString& ); SbxINT64 ImpGetCurrency( const SbxValues* p ) { @@ -121,10 +121,10 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes.SetNull(); else - nRes = ImpStringToCurrency( *p->pString ); + nRes = ImpStringToCurrency( *p->pOUString ); break; case SbxOBJECT: { @@ -224,10 +224,10 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; - *p->pString = ImpCurrencyToString( r ); + *p->pOUString = ImpCurrencyToString( r ); break; case SbxOBJECT: { @@ -319,7 +319,7 @@ start: // Hilfs-Funktionen zur Wandlung -static String ImpCurrencyToString( const SbxINT64 &r ) +static ::rtl::OUString ImpCurrencyToString( const SbxINT64 &r ) { BigInt a10000 = 10000; @@ -331,20 +331,20 @@ static String ImpCurrencyToString( const SbxINT64 &r ) aFrac %= a10000; aFrac += a10000; - String aString; + ::rtl::OUString aString; if( r.nHigh < 0 ) - aString = '-'; + aString = ::rtl::OUString( (sal_Unicode)'-' ); aString += aInt.GetString(); - aString += '.'; + aString += ::rtl::OUString( (sal_Unicode)'.' ); aString += aFrac.GetString().GetBuffer()+1; return aString; } -static SbxINT64 ImpStringToCurrency( const String &r ) +static SbxINT64 ImpStringToCurrency( const ::rtl::OUString &r ) { int nDec = 4; String aStr; - const sal_Unicode* p = r.GetBuffer(); + const sal_Unicode* p = r.getStr(); if( *p == '-' ) aStr += *p++; diff --git a/basic/source/sbx/sbxdate.cxx b/basic/source/sbx/sbxdate.cxx index ce532fed0482..3a0636e4e7fc 100644 --- a/basic/source/sbx/sbxdate.cxx +++ b/basic/source/sbx/sbxdate.cxx @@ -86,7 +86,7 @@ double ImpGetDate( const SbxValues* p ) case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { @@ -126,7 +126,7 @@ double ImpGetDate( const SbxValues* p ) pFormatter->PutandConvertEntry( aStr, nCheckPos, nType, nIndex, LANGUAGE_GERMAN, eLangType ); - BOOL bSuccess = pFormatter->IsNumberFormat( *p->pString, nIndex, nRes ); + BOOL bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes ); if ( bSuccess ) { short nType_ = pFormatter->GetType( nIndex ); @@ -248,8 +248,8 @@ start: case SbxLPSTR: #ifndef DOS { - if( !p->pString ) - p->pString = new XubString; + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; Color* pColor; LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); @@ -299,7 +299,9 @@ start: nIndex, LANGUAGE_GERMAN, eLangType ); - pFormatter->GetOutputString( n, nIndex, *p->pString, &pColor ); + String aTmpString; + pFormatter->GetOutputString( n, nIndex, aTmpString, &pColor ); + *p->pOUString = aTmpString; delete pFormatter; #endif break; diff --git a/basic/source/sbx/sbxdbl.cxx b/basic/source/sbx/sbxdbl.cxx index 460f331c59b8..be55d3409131 100644 --- a/basic/source/sbx/sbxdbl.cxx +++ b/basic/source/sbx/sbxdbl.cxx @@ -76,7 +76,7 @@ double ImpGetDouble( const SbxValues* p ) case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) { nRes = 0; if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour @@ -86,7 +86,7 @@ double ImpGetDouble( const SbxValues* p ) { double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) { nRes = 0; if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour @@ -188,9 +188,9 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; - ImpCvtNum( (double) n, 14, *p->pString, bCoreString ); + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; + ImpCvtNum( (double) n, 14, *p->pOUString, bCoreString ); break; case SbxOBJECT: { diff --git a/basic/source/sbx/sbxdec.cxx b/basic/source/sbx/sbxdec.cxx index 319b0aac366c..2191d91c8d82 100644 --- a/basic/source/sbx/sbxdec.cxx +++ b/basic/source/sbx/sbxdec.cxx @@ -211,7 +211,7 @@ void SbxDecimal::setUInt( unsigned int val ) // sbxscan.cxx void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep ); -bool SbxDecimal::setString( String* pString ) +bool SbxDecimal::setString( ::rtl::OUString* pOUString ) { static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ); @@ -224,11 +224,11 @@ bool SbxDecimal::setString( String* pString ) HRESULT hResult; if( cDecimalSep != '.' || cThousandSep != ',' ) { - int nLen = pString->Len(); + int nLen = pOUString->getLength(); sal_Unicode* pBuffer = new sal_Unicode[nLen + 1]; pBuffer[nLen] = 0; - const sal_Unicode* pSrc = pString->GetBuffer(); + const sal_Unicode* pSrc = pOUString->getStr(); int i; for( i = 0 ; i < nLen ; ++i ) pBuffer[i] = pSrc[i]; @@ -248,7 +248,7 @@ bool SbxDecimal::setString( String* pString ) } else { - hResult = VarDecFromStr( (OLECHAR*)pString->GetBuffer(), nLANGID, 0, &maDec ); + hResult = VarDecFromStr( (OLECHAR*)pOUString->getStr(), nLANGID, 0, &maDec ); } bRet = ( hResult == S_OK ); return bRet; @@ -373,7 +373,7 @@ bool SbxDecimal::setSingle( float val ) { (void)val; return false; } bool SbxDecimal::setDouble( double val ) { (void)val; return false; } void SbxDecimal::setInt( int val ) { (void)val; } void SbxDecimal::setUInt( unsigned int val ) { (void)val; } -bool SbxDecimal::setString( String* pString ) { (void)pString; return false; } +bool SbxDecimal::setString( ::rtl::OUString* pOUString ) { (void)pOUString; return false; } bool SbxDecimal::getChar( sal_Unicode& rVal ) { (void)rVal; return false; } bool SbxDecimal::getByte( BYTE& rVal ) { (void)rVal; return false; } @@ -388,7 +388,7 @@ bool SbxDecimal::getUInt( unsigned int& rVal ) { (void)rVal; return false; } #endif -bool SbxDecimal::getString( String& rString ) +bool SbxDecimal::getString( ::rtl::OUString& rString ) { #ifdef WIN32 static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ); @@ -528,7 +528,7 @@ start: case SbxLPSTR: case SbxSTRING: case SbxBYREF | SbxSTRING: - pnDecRes->setString( p->pString ); break; + pnDecRes->setString( p->pOUString ); break; case SbxOBJECT: { SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); @@ -670,10 +670,10 @@ start: case SbxLPSTR: case SbxSTRING: case SbxBYREF | SbxSTRING: - if( !p->pString ) - p->pString = new XubString; + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; // ImpCvtNum( (double) n, 0, *p->pString ); - pDec->getString( *p->pString ); + pDec->getString( *p->pOUString ); break; case SbxOBJECT: { diff --git a/basic/source/sbx/sbxdec.hxx b/basic/source/sbx/sbxdec.hxx index 03f97bec5992..cd80bbad282e 100644 --- a/basic/source/sbx/sbxdec.hxx +++ b/basic/source/sbx/sbxdec.hxx @@ -85,7 +85,7 @@ public: bool setDouble( double val ); void setInt( int val ); void setUInt( unsigned int val ); - bool setString( String* pString ); + bool setString( ::rtl::OUString* pOUString ); void setDecimal( SbxDecimal* pDecimal ) { #ifdef WIN32 @@ -106,7 +106,7 @@ public: bool getDouble( double& rVal ); bool getInt( int& rVal ); bool getUInt( unsigned int& rVal ); - bool getString( String& rString ); + bool getString( ::rtl::OUString& rString ); bool operator -= ( const SbxDecimal &r ); bool operator += ( const SbxDecimal &r ); diff --git a/basic/source/sbx/sbxint.cxx b/basic/source/sbx/sbxint.cxx index 406b8599e568..47c38aecb1c2 100644 --- a/basic/source/sbx/sbxint.cxx +++ b/basic/source/sbx/sbxint.cxx @@ -154,13 +154,13 @@ start: case SbxLPSTR: case SbxSTRING: case SbxBYREF | SbxSTRING: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else if( d > SbxMAXINT ) { @@ -275,9 +275,9 @@ start: case SbxLPSTR: case SbxSTRING: case SbxBYREF | SbxSTRING: - if( !p->pString ) - p->pString = new XubString; - ImpCvtNum( (double) n, 0, *p->pString ); + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; + ImpCvtNum( (double) n, 0, *p->pOUString ); break; case SbxOBJECT: { @@ -456,20 +456,19 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { - ::rtl::OUString aOUStr( *p->pString ); ::rtl::OString aOStr = ::rtl::OUStringToOString - ( aOUStr, RTL_TEXTENCODING_ASCII_US ); + ( *p->pOUString, RTL_TEXTENCODING_ASCII_US ); nRes = aOStr.toInt64(); if( nRes == 0 ) { // Check if really 0 or invalid conversion double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else nRes = ImpDoubleToSalInt64( d ); @@ -575,13 +574,12 @@ start: case SbxSTRING: case SbxLPSTR: { - if( !p->pString ) - p->pString = new XubString; + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; ::rtl::OString aOStr = ::rtl::OString::valueOf( n ); - ::rtl::OUString aOUStr = ::rtl::OStringToOUString + (*p->pOUString) = ::rtl::OStringToOUString ( aOStr, RTL_TEXTENCODING_ASCII_US ); - (*p->pString) = aOUStr; break; } case SbxOBJECT: @@ -745,20 +743,19 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { - ::rtl::OUString aOUStr( *p->pString ); ::rtl::OString aOStr = ::rtl::OUStringToOString - ( aOUStr, RTL_TEXTENCODING_ASCII_US ); + ( *p->pOUString, RTL_TEXTENCODING_ASCII_US ); sal_Int64 n64 = aOStr.toInt64(); if( n64 == 0 ) { // Check if really 0 or invalid conversion double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else if( d > SbxMAXSALUINT64 ) { @@ -879,16 +876,15 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; if( n > SbxMAXSALINT64 ) SbxBase::SetError( SbxERR_CONVERSION ); else { ::rtl::OString aOStr = ::rtl::OString::valueOf( (sal_Int64)n ); - ::rtl::OUString aOUStr = ::rtl::OStringToOUString + (*p->pOUString) = ::rtl::OStringToOUString ( aOStr, RTL_TEXTENCODING_ASCII_US ); - (*p->pString) = aOUStr; } break; case SbxOBJECT: diff --git a/basic/source/sbx/sbxlng.cxx b/basic/source/sbx/sbxlng.cxx index c84b087dfc33..1cf2d84061f9 100644 --- a/basic/source/sbx/sbxlng.cxx +++ b/basic/source/sbx/sbxlng.cxx @@ -119,13 +119,13 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else if( d > SbxMAXLNG ) { @@ -240,9 +240,9 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; - ImpCvtNum( (double) n, 0, *p->pString ); + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; + ImpCvtNum( (double) n, 0, *p->pOUString ); break; case SbxOBJECT: { diff --git a/basic/source/sbx/sbxres.cxx b/basic/source/sbx/sbxres.cxx index f42c400afd91..369349e72069 100644 --- a/basic/source/sbx/sbxres.cxx +++ b/basic/source/sbx/sbxres.cxx @@ -86,6 +86,6 @@ const char* GetSbxRes( USHORT nId ) } SbxRes::SbxRes( USHORT nId ) - : XubString( String::CreateFromAscii( GetSbxRes( nId ) ) ) + : ::rtl::OUString( ::rtl::OUString::createFromAscii( GetSbxRes( nId ) ) ) {} diff --git a/basic/source/sbx/sbxres.hxx b/basic/source/sbx/sbxres.hxx index 8cd0ad26e951..8ed3c7054278 100644 --- a/basic/source/sbx/sbxres.hxx +++ b/basic/source/sbx/sbxres.hxx @@ -75,7 +75,7 @@ #define SBXRES_MAX 44 -class SbxRes : public String +class SbxRes : public ::rtl::OUString { public: SbxRes( USHORT ); diff --git a/basic/source/sbx/sbxscan.cxx b/basic/source/sbx/sbxscan.cxx index 3d45818e6401..b8aad9bbf2e4 100644 --- a/basic/source/sbx/sbxscan.cxx +++ b/basic/source/sbx/sbxscan.cxx @@ -71,10 +71,10 @@ void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep ) // Das ganze gibt auch noch einen Konversionsfehler, wenn der Datentyp // Fixed ist und das ganze nicht hineinpasst! -SbxError ImpScan( const XubString& rWSrc, double& nVal, SbxDataType& rType, +SbxError ImpScan( const ::rtl::OUString& rWSrc, double& nVal, SbxDataType& rType, USHORT* pLen, BOOL bAllowIntntl, BOOL bOnlyIntntl ) { - ByteString aBStr( rWSrc, RTL_TEXTENCODING_ASCII_US ); + ::rtl::OString aBStr( ::rtl::OUStringToOString( rWSrc, RTL_TEXTENCODING_ASCII_US ) ); // Bei International Komma besorgen char cIntntlComma, cIntntl1000; @@ -100,7 +100,7 @@ SbxError ImpScan( const XubString& rWSrc, double& nVal, SbxDataType& rType, cIntntl1000 = (char)cThousandSep; } - const char* pStart = aBStr.GetBuffer(); + const char* pStart = aBStr.getStr(); const char* p = pStart; char buf[ 80 ], *q = buf; BOOL bRes = TRUE; @@ -391,7 +391,7 @@ static void myftoa( double nNum, char * pBuf, short nPrec, short nExpWidth, #pragma warning(disable: 4748) // "... because optimizations are disabled ..." #endif -void ImpCvtNum( double nNum, short nPrec, XubString& rRes, BOOL bCoreString ) +void ImpCvtNum( double nNum, short nPrec, ::rtl::OUString& rRes, BOOL bCoreString ) { char *q; char cBuf[ 40 ], *p = cBuf; @@ -415,18 +415,18 @@ void ImpCvtNum( double nNum, short nPrec, XubString& rRes, BOOL bCoreString ) if( *p == cDecimalSep ) p--; while( *q ) *++p = *q++; *++p = 0; - rRes = String::CreateFromAscii( cBuf ); + rRes = ::rtl::OUString::createFromAscii( cBuf ); } #ifdef _MSC_VER #pragma optimize( "", on ) #endif -BOOL ImpConvStringExt( XubString& rSrc, SbxDataType eTargetType ) +BOOL ImpConvStringExt( ::rtl::OUString& rSrc, SbxDataType eTargetType ) { // Merken, ob ueberhaupt was geaendert wurde BOOL bChanged = FALSE; - String aNewString; + ::rtl::OUString aNewString; // Nur Spezial-Flle behandeln, als Default tun wir nichts switch( eTargetType ) @@ -436,7 +436,7 @@ BOOL ImpConvStringExt( XubString& rSrc, SbxDataType eTargetType ) case SbxDOUBLE: case SbxCURRENCY: { - ByteString aBStr( rSrc, RTL_TEXTENCODING_ASCII_US ); + ::rtl::OString aBStr( ::rtl::OUStringToOString( rSrc, RTL_TEXTENCODING_ASCII_US ) ); // Komma besorgen sal_Unicode cDecimalSep, cThousandSep; @@ -446,10 +446,11 @@ BOOL ImpConvStringExt( XubString& rSrc, SbxDataType eTargetType ) // Ersetzen, wenn DecimalSep kein '.' (nur den ersten) if( cDecimalSep != (sal_Unicode)'.' ) { - USHORT nPos = aNewString.Search( cDecimalSep ); - if( nPos != STRING_NOTFOUND ) + sal_Int32 nPos = aNewString.indexOf( cDecimalSep ); + if( nPos != -1 ) { - aNewString.SetChar( nPos, '.' ); + sal_Unicode* pStr = (sal_Unicode*)aNewString.getStr(); + pStr[nPos] = (sal_Unicode)'.'; bChanged = TRUE; } } @@ -459,15 +460,15 @@ BOOL ImpConvStringExt( XubString& rSrc, SbxDataType eTargetType ) // Bei BOOL TRUE und FALSE als String pruefen case SbxBOOL: { - if( rSrc.EqualsIgnoreCaseAscii( "true" ) ) + if( rSrc.equalsIgnoreAsciiCaseAscii( "true" ) ) { - aNewString = String::CreateFromInt32(SbxTRUE); + aNewString = ::rtl::OUString::valueOf( (sal_Int32)SbxTRUE ); bChanged = TRUE; } else - if( rSrc.EqualsIgnoreCaseAscii( "false" ) ) + if( rSrc.equalsIgnoreAsciiCaseAscii( "false" ) ) { - aNewString = String::CreateFromInt32(SbxFALSE); + aNewString = ::rtl::OUString::valueOf( (sal_Int32)SbxFALSE ); bChanged = TRUE; } break; @@ -935,7 +936,11 @@ void SbxValue::Format( XubString& rRes, const XubString* pFmt ) const //old: printfmtnum( GetDouble(), rRes, *pFmt ); } else - ImpCvtNum( GetDouble(), nComma, rRes ); + { + ::rtl::OUString aTmpString( rRes ); + ImpCvtNum( GetDouble(), nComma, aTmpString ); + rRes = aTmpString; + } break; case SbxSTRING: if( pFmt ) diff --git a/basic/source/sbx/sbxsng.cxx b/basic/source/sbx/sbxsng.cxx index 82507dbe15e9..70ef1653666b 100644 --- a/basic/source/sbx/sbxsng.cxx +++ b/basic/source/sbx/sbxsng.cxx @@ -112,13 +112,13 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else if( d > SbxMAXSNG ) { @@ -237,9 +237,9 @@ start: case SbxSTRING: case SbxLPSTR: { - if( !p->pString ) - p->pString = new XubString; - ImpCvtNum( (double) n, 6, *p->pString ); + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; + ImpCvtNum( (double) n, 6, *p->pOUString ); break; } case SbxOBJECT: diff --git a/basic/source/sbx/sbxstr.cxx b/basic/source/sbx/sbxstr.cxx index 6deb2da29ba1..b4156a116ddc 100644 --- a/basic/source/sbx/sbxstr.cxx +++ b/basic/source/sbx/sbxstr.cxx @@ -44,12 +44,12 @@ using namespace rtl; // Die Konversion eines Items auf String wird ueber die Put-Methoden // der einzelnen Datentypen abgewickelt, um doppelten Code zu vermeiden. -XubString ImpGetString( const SbxValues* p ) +::rtl::OUString ImpGetString( const SbxValues* p ) { SbxValues aTmp; - XubString aRes; + ::rtl::OUString aRes; aTmp.eType = SbxSTRING; - aTmp.pString = &aRes; + aTmp.pOUString = &aRes; switch( +p->eType ) { case SbxNULL: @@ -86,8 +86,8 @@ XubString ImpGetString( const SbxValues* p ) case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( p->pString ) - aRes = *p->pString; + if ( p->pOUString ) + *aTmp.pOUString = *p->pOUString; break; case SbxOBJECT: { @@ -109,7 +109,7 @@ XubString ImpGetString( const SbxValues* p ) case SbxERROR: // Hier wird der String "Error n" erzeugt aRes = SbxRes( STRING_ERRORMSG ); - aRes += p->nUShort; break; + aRes += ::rtl::OUString( p->nUShort ); break; case SbxDATE: ImpPutDate( &aTmp, p->nDouble ); break; @@ -145,7 +145,7 @@ XubString ImpGetString( const SbxValues* p ) } // AB 10.4.97, neue Funktion fuer SbxValue::GetCoreString() -XubString ImpGetCoreString( const SbxValues* p ) +::rtl::OUString ImpGetCoreString( const SbxValues* p ) { // Vorerst nur fuer double if( ( p->eType & (~SbxBYREF) ) == SbxDOUBLE ) @@ -153,7 +153,6 @@ XubString ImpGetCoreString( const SbxValues* p ) SbxValues aTmp; XubString aRes; aTmp.eType = SbxSTRING; - aTmp.pString = &aRes; if( p->eType == SbxDOUBLE ) ImpPutDouble( &aTmp, p->nDouble, /*bCoreString=*/TRUE ); else @@ -164,15 +163,15 @@ XubString ImpGetCoreString( const SbxValues* p ) return ImpGetString( p ); } -void ImpPutString( SbxValues* p, const XubString* n ) +void ImpPutString( SbxValues* p, const ::rtl::OUString* n ) { SbxValues aTmp; aTmp.eType = SbxSTRING; - XubString* pTmp = NULL; + ::rtl::OUString* pTmp = NULL; // Sicherheitshalber, falls ein NULL-Ptr kommt if( !n ) - n = pTmp = new XubString; - aTmp.pString = (XubString*) n; + n = pTmp = new ::rtl::OUString; + aTmp.pOUString = (::rtl::OUString*)n; switch( +p->eType ) { case SbxCHAR: @@ -209,14 +208,15 @@ void ImpPutString( SbxValues* p, const XubString* n ) case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( n->Len() ) + if( n->getLength() ) { - if( !p->pString ) - p->pString = new XubString; - *p->pString = *n; + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString( *n ); + else + *p->pOUString = *n; } else - delete p->pString, p->pString = NULL; + delete p->pOUString, p->pOUString = NULL; break; case SbxOBJECT: { @@ -258,18 +258,18 @@ void ImpPutString( SbxValues* p, const XubString* n ) } // Convert string to an array of bytes, preserving unicode (2bytes per character) -SbxArray* StringToByteArray(const String& rStr) +SbxArray* StringToByteArray(const ::rtl::OUString& rStr) { - USHORT nArraySize = rStr.Len() * 2; - const sal_Unicode* pSrc = rStr.GetBuffer(); + sal_Int32 nArraySize = rStr.getLength() * 2; + const sal_Unicode* pSrc = rStr.getStr(); SbxDimArray* pArray = new SbxDimArray(SbxBYTE); bool bIncIndex = ( IsBaseIndexOne() && SbiRuntime::isVBAEnabled() ); if( nArraySize ) { if( bIncIndex ) - pArray->AddDim( 1, nArraySize ); + pArray->AddDim32( 1, nArraySize ); else - pArray->AddDim( 0, nArraySize-1 ); + pArray->AddDim32( 0, nArraySize-1 ); } else { @@ -290,7 +290,7 @@ SbxArray* StringToByteArray(const String& rStr) } // Convert an array of bytes to string (2bytes per character) -String ByteArrayToString(SbxArray* pArr) +::rtl::OUString ByteArrayToString(SbxArray* pArr) { USHORT nCount = pArr->Count(); OUStringBuffer aStrBuf; @@ -315,7 +315,5 @@ String ByteArrayToString(SbxArray* pArr) aStrBuf.append(aChar); } - String aStr(aStrBuf.makeStringAndClear()); - - return aStr; + return aStrBuf.makeStringAndClear(); } diff --git a/basic/source/sbx/sbxuint.cxx b/basic/source/sbx/sbxuint.cxx index ce0aea70b062..5b75a24d6d26 100644 --- a/basic/source/sbx/sbxuint.cxx +++ b/basic/source/sbx/sbxuint.cxx @@ -151,13 +151,13 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else if( d > SbxMAXUINT ) { @@ -272,9 +272,9 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; - ImpCvtNum( (double) n, 0, *p->pString ); + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; + ImpCvtNum( (double) n, 0, *p->pOUString ); break; case SbxOBJECT: { diff --git a/basic/source/sbx/sbxulng.cxx b/basic/source/sbx/sbxulng.cxx index 3dd81b8c616d..e0f6f3fa421d 100644 --- a/basic/source/sbx/sbxulng.cxx +++ b/basic/source/sbx/sbxulng.cxx @@ -127,13 +127,13 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) + if( !p->pOUString ) nRes = 0; else { double d; SbxDataType t; - if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK ) + if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK ) nRes = 0; else if( d > SbxMAXULNG ) { @@ -246,9 +246,9 @@ start: case SbxBYREF | SbxSTRING: case SbxSTRING: case SbxLPSTR: - if( !p->pString ) - p->pString = new XubString; - ImpCvtNum( (double) n, 0, *p->pString ); + if( !p->pOUString ) + p->pOUString = new ::rtl::OUString; + ImpCvtNum( (double) n, 0, *p->pOUString ); break; case SbxOBJECT: { diff --git a/basic/source/sbx/sbxvalue.cxx b/basic/source/sbx/sbxvalue.cxx index 7ee31af70556..4ea4836b701b 100644 --- a/basic/source/sbx/sbxvalue.cxx +++ b/basic/source/sbx/sbxvalue.cxx @@ -236,7 +236,7 @@ SbxValue::SbxValue( SbxDataType t, void* p ) : SbxBase() case SbxSINGLE: n |= SbxBYREF; aData.pSingle = (float*) p; break; case SbxDATE: case SbxDOUBLE: n |= SbxBYREF; aData.pDouble = (double*) p; break; - case SbxSTRING: n |= SbxBYREF; aData.pString = (XubString*) p; break; + case SbxSTRING: n |= SbxBYREF; aData.pOUString = (::rtl::OUString*) p; break; case SbxERROR: case SbxUSHORT: case SbxBOOL: n |= SbxBYREF; aData.pUShort = (UINT16*) p; break; @@ -280,8 +280,8 @@ SbxValue::SbxValue( const SbxValue& r ) switch( aData.eType ) { case SbxSTRING: - if( aData.pString ) - aData.pString = new XubString( *aData.pString ); + if( aData.pOUString ) + aData.pOUString = new ::rtl::OUString( *aData.pOUString ); break; case SbxOBJECT: if( aData.pObj ) @@ -309,7 +309,7 @@ SbxValue& SbxValue::operator=( const SbxValue& r ) && aData.pObj && ( aData.pObj->GetType() == (SbxARRAY | SbxBYTE) ) && (r.aData.eType == SbxSTRING) ) { - String aStr = r.GetString(); + ::rtl::OUString aStr = r.GetString(); SbxArray* pArr = StringToByteArray(aStr); PutObject(pArr); return *this; @@ -323,7 +323,7 @@ SbxValue& SbxValue::operator=( const SbxValue& r ) SbxArray* pArr = PTR_CAST(SbxArray, pObj); if( pArr ) { - String aStr = ByteArrayToString( pArr ); + ::rtl::OUString aStr = ByteArrayToString( pArr ); PutString(aStr); return *this; } @@ -385,7 +385,7 @@ void SbxValue::Clear() case SbxVOID: break; case SbxSTRING: - delete aData.pString; aData.pString = NULL; + delete aData.pOUString; aData.pOUString = NULL; break; case SbxOBJECT: if( aData.pObj ) @@ -551,9 +551,9 @@ BOOL SbxValue::Get( SbxValues& rRes ) const case SbxULONG: rRes.nULong = ImpGetULong( &p->aData ); break; case SbxLPSTR: case SbxSTRING: p->aPic = ImpGetString( &p->aData ); - rRes.pString = &p->aPic; break; + rRes.pOUString = &p->aPic; break; case SbxCoreSTRING: p->aPic = ImpGetCoreString( &p->aData ); - rRes.pString = &p->aPic; break; + rRes.pOUString = &p->aPic; break; case SbxINT: #if SAL_TYPES_SIZEOFINT == 2 rRes.nInt = (int) ImpGetInteger( &p->aData ); @@ -618,13 +618,11 @@ const XubString& SbxValue::GetString() const SbxValues aRes; aRes.eType = SbxSTRING; if( Get( aRes ) ) - // Geht in Ordnung, da Ptr eine Kopie ist - return *aRes.pString; + ((SbxValue*) this)->aToolString = *aRes.pOUString; else - { - ((SbxValue*) this)->aPic.Erase(); - return aPic; - } + ((SbxValue*) this)->aToolString.Erase(); + + return aToolString; } const XubString& SbxValue::GetCoreString() const @@ -632,13 +630,22 @@ const XubString& SbxValue::GetCoreString() const SbxValues aRes; aRes.eType = SbxCoreSTRING; if( Get( aRes ) ) - // Geht in Ordnung, da Ptr eine Kopie ist - return *aRes.pString; + ((SbxValue*) this)->aToolString = *aRes.pOUString; else - { - ((SbxValue*) this)->aPic.Erase(); - return aPic; - } + ((SbxValue*) this)->aToolString.Erase(); + + return aToolString; +} + +::rtl::OUString SbxValue::GetOUString() const +{ + ::rtl::OUString aResult; + SbxValues aRes; + aRes.eType = SbxSTRING; + if( Get( aRes ) ) + aResult = *aRes.pOUString; + + return aResult; } BOOL SbxValue::HasObject() const @@ -727,7 +734,7 @@ BOOL SbxValue::Put( const SbxValues& rVal ) case SbxUSHORT: ImpPutUShort( &p->aData, rVal.nUShort ); break; case SbxULONG: ImpPutULong( &p->aData, rVal.nULong ); break; case SbxLPSTR: - case SbxSTRING: ImpPutString( &p->aData, rVal.pString ); break; + case SbxSTRING: ImpPutString( &p->aData, rVal.pOUString ); break; case SbxINT: #if SAL_TYPES_SIZEOFINT == 2 ImpPutInteger( &p->aData, (INT16) rVal.nInt ); @@ -803,10 +810,10 @@ BOOL SbxValue::Put( const SbxValues& rVal ) // werden koennen, wenn Floats mit ',' als Dezimaltrenner oder BOOLs // explizit mit "TRUE" oder "FALSE" angegeben werden. // Implementierung in ImpConvStringExt (SBXSCAN.CXX) -BOOL SbxValue::PutStringExt( const XubString& r ) +BOOL SbxValue::PutStringExt( const ::rtl::OUString& r ) { // Kopieren, bei Unicode gleich konvertieren - String aStr( r ); + ::rtl::OUString aStr( r ); // Eigenen Typ bestimmen (nicht wie in Put() mit TheRealValue(), // Objekte werden sowieso nicht behandelt) @@ -820,9 +827,9 @@ BOOL SbxValue::PutStringExt( const XubString& r ) // sonst Original (Unicode bleibt erhalten) BOOL bRet; if( ImpConvStringExt( aStr, eTargetType ) ) - aRes.pString = (XubString*)&aStr; + aRes.pOUString = (::rtl::OUString*)&aStr; else - aRes.pString = (XubString*)&r; + aRes.pOUString = (::rtl::OUString*)&r; // #34939: Bei Strings. die eine Zahl enthalten und wenn this einen // Num-Typ hat, Fixed-Flag setzen, damit der Typ nicht veraendert wird @@ -851,10 +858,10 @@ BOOL SbxValue::PutStringExt( const XubString& r ) BOOL SbxValue::PutString( const xub_Unicode* p ) { - XubString aVal( p ); + ::rtl::OUString aVal( p ); SbxValues aRes; aRes.eType = SbxSTRING; - aRes.pString = &aVal; + aRes.pOUString = &aVal; Put( aRes ); return BOOL( !IsError() ); } @@ -909,19 +916,19 @@ BOOL SbxValue::fillAutomationDecimal BOOL SbxValue::PutpChar( const xub_Unicode* p ) { - XubString aVal( p ); + ::rtl::OUString aVal( p ); SbxValues aRes; aRes.eType = SbxLPSTR; - aRes.pString = &aVal; + aRes.pOUString = &aVal; Put( aRes ); return BOOL( !IsError() ); } -BOOL SbxValue::PutString( const XubString& r ) +BOOL SbxValue::PutString( const ::rtl::OUString& r ) { SbxValues aRes; aRes.eType = SbxSTRING; - aRes.pString = (XubString*) &r; + aRes.pOUString = (::rtl::OUString*) &r; Put( aRes ); return BOOL( !IsError() ); } @@ -986,14 +993,14 @@ BOOL SbxValue::ImpIsNumeric( BOOL bOnlyIntntl ) const SbxDataType t = GetType(); if( t == SbxSTRING ) { - if( aData.pString ) + if( aData.pOUString ) { - XubString s( *aData.pString ); + ::rtl::OUString s( *aData.pOUString ); double n; SbxDataType t2; USHORT nLen = 0; if( ImpScan( s, n, t2, &nLen, /*bAllowIntntl*/FALSE, bOnlyIntntl ) == SbxERR_OK ) - return BOOL( nLen == s.Len() ); + return BOOL( nLen == s.getLength() ); } return FALSE; } @@ -1046,7 +1053,7 @@ BOOL SbxValue::SetType( SbxDataType t ) switch( aData.eType ) { case SbxSTRING: - delete aData.pString; + delete aData.pOUString; break; case SbxOBJECT: if( aData.pObj && aData.pObj != this ) @@ -1163,14 +1170,14 @@ BOOL SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp ) Get( aL ); // #30576: Erstmal testen, ob Wandlung geklappt hat - if( aL.pString != NULL && aR.pString != NULL ) + if( aL.pOUString != NULL && aR.pOUString != NULL ) { - *aL.pString += *aR.pString; + *aL.pOUString += *aR.pOUString; } // Nicht einmal Left OK? - else if( aL.pString == NULL ) + else if( aL.pOUString == NULL ) { - aL.pString = new String(); + aL.pOUString = new ::rtl::OUString(); } Put( aL ); } @@ -1493,17 +1500,17 @@ BOOL SbxValue::Compare( SbxOperator eOp, const SbxValue& rOp ) const if( Get( aL ) && rOp.Get( aR ) ) switch( eOp ) { case SbxEQ: - bRes = BOOL( *aL.pString == *aR.pString ); break; + bRes = BOOL( *aL.pOUString == *aR.pOUString ); break; case SbxNE: - bRes = BOOL( *aL.pString != *aR.pString ); break; + bRes = BOOL( *aL.pOUString != *aR.pOUString ); break; case SbxLT: - bRes = BOOL( *aL.pString < *aR.pString ); break; + bRes = BOOL( *aL.pOUString < *aR.pOUString ); break; case SbxGT: - bRes = BOOL( *aL.pString > *aR.pString ); break; + bRes = BOOL( *aL.pOUString > *aR.pOUString ); break; case SbxLE: - bRes = BOOL( *aL.pString <= *aR.pString ); break; + bRes = BOOL( *aL.pOUString <= *aR.pOUString ); break; case SbxGE: - bRes = BOOL( *aL.pString >= *aR.pString ); break; + bRes = BOOL( *aL.pOUString >= *aR.pOUString ); break; default: SetError( SbxERR_NOTIMP ); } @@ -1668,9 +1675,9 @@ BOOL SbxValue::LoadData( SvStream& r, USHORT ) XubString aVal; r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US ); if( aVal.Len() ) - aData.pString = new XubString( aVal ); + aData.pOUString = new ::rtl::OUString( aVal ); else - aData.pString = NULL; // JSM 22.09.1995 + aData.pOUString = NULL; // JSM 22.09.1995 break; } case SbxERROR: @@ -1781,9 +1788,9 @@ BOOL SbxValue::StoreData( SvStream& r ) const break; } case SbxSTRING: - if( aData.pString ) + if( aData.pOUString ) { - r.WriteByteString( *aData.pString, RTL_TEXTENCODING_ASCII_US ); + r.WriteByteString( *aData.pOUString, RTL_TEXTENCODING_ASCII_US ); } else { diff --git a/basic/source/sbx/sbxvar.cxx b/basic/source/sbx/sbxvar.cxx index 20060f1f7493..58e3c1ae92c2 100644 --- a/basic/source/sbx/sbxvar.cxx +++ b/basic/source/sbx/sbxvar.cxx @@ -239,9 +239,9 @@ const XubString& SbxVariable::GetName( SbxNameType t ) const if( i ) aTmp += ','; if( q->nFlags & SBX_OPTIONAL ) - aTmp += SbxRes( STRING_OPTIONAL ); + aTmp += String( SbxRes( STRING_OPTIONAL ) ); if( q->eType & SbxBYREF ) - aTmp += SbxRes( STRING_BYREF ); + aTmp += String( SbxRes( STRING_BYREF ) ); aTmp += q->aName; cType = ' '; // Kurzer Typ? Dann holen, evtl. ist dieser 0. @@ -263,12 +263,12 @@ const XubString& SbxVariable::GetName( SbxNameType t ) const // langer Typ? if( t != SbxNAME_SHORT ) { - aTmp += SbxRes( STRING_AS ); + aTmp += String( SbxRes( STRING_AS ) ); if( nt < 32 ) - aTmp += SbxRes( - sal::static_int_cast< USHORT >( STRING_TYPES + nt ) ); + aTmp += String( SbxRes( + sal::static_int_cast< USHORT >( STRING_TYPES + nt ) ) ); else - aTmp += SbxRes( STRING_ANY ); + aTmp += String( SbxRes( STRING_ANY ) ); } } } @@ -276,15 +276,15 @@ const XubString& SbxVariable::GetName( SbxNameType t ) const // Langer Typ? Dann holen if( t == SbxNAME_LONG_TYPES && et != SbxEMPTY ) { - aTmp += SbxRes( STRING_AS ); + aTmp += String( SbxRes( STRING_AS ) ); if( et < 32 ) - aTmp += SbxRes( - sal::static_int_cast< USHORT >( STRING_TYPES + et ) ); + aTmp += String( SbxRes( + sal::static_int_cast< USHORT >( STRING_TYPES + et ) ) ); else - aTmp += SbxRes( STRING_ANY ); + aTmp += String( SbxRes( STRING_ANY ) ); } - ((SbxVariable*) this)->aPic = aTmp; - return aPic; + ((SbxVariable*) this)->aToolString = aTmp; + return aToolString; } // Einen simplen Hashcode erzeugen: Es werden die ersten 6 Zeichen gewertet. @@ -431,9 +431,10 @@ BOOL SbxVariable::LoadData( SvStream& rStrm, USHORT nVer ) if( nType == SbxNULL && GetClass() == SbxCLASS_METHOD ) nType = SbxEMPTY; SbxValues aTmp; - XubString aVal; + String aTmpString; + ::rtl::OUString aVal; aTmp.eType = aData.eType = (SbxDataType) nType; - aTmp.pString = &aVal; + aTmp.pOUString = &aVal; switch( nType ) { case SbxBOOL: @@ -445,10 +446,10 @@ BOOL SbxVariable::LoadData( SvStream& rStrm, USHORT nVer ) case SbxSINGLE: { // Floats als ASCII - rStrm.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US ); + rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US ); double d; SbxDataType t; - if( ImpScan( aVal, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE ) + if( ImpScan( aTmpString, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE ) { aTmp.nSingle = 0; return FALSE; @@ -460,9 +461,9 @@ BOOL SbxVariable::LoadData( SvStream& rStrm, USHORT nVer ) case SbxDOUBLE: { // Floats als ASCII - rStrm.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US ); + rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US ); SbxDataType t; - if( ImpScan( aVal, aTmp.nDouble, t, NULL ) != SbxERR_OK ) + if( ImpScan( aTmpString, aTmp.nDouble, t, NULL ) != SbxERR_OK ) { aTmp.nDouble = 0; return FALSE; @@ -470,7 +471,8 @@ BOOL SbxVariable::LoadData( SvStream& rStrm, USHORT nVer ) break; } case SbxSTRING: - rStrm.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US ); + rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US ); + aVal = aTmpString; break; case SbxEMPTY: case SbxNULL: diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx index e1ad8b6b4308..c31aed1f8ef7 100644 --- a/basic/source/uno/namecont.cxx +++ b/basic/source/uno/namecont.cxx @@ -2793,7 +2793,6 @@ OUString SfxLibraryContainer::expand_url( const OUString& url ) } } - //XLibraryContainer3 OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException) @@ -2808,12 +2807,13 @@ OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString } -::sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatModeOn() throw (RuntimeException) +// XVBACompatibility +::sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode() throw (RuntimeException) { return mbVBACompat; } -void SAL_CALL SfxLibraryContainer::setVBACompatModeOn( ::sal_Bool _vbacompatmodeon ) throw (RuntimeException) +void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon ) throw (RuntimeException) { BasicManager* pBasMgr = getBasicManager(); if( pBasMgr ) diff --git a/basic/source/uno/scriptcont.cxx b/basic/source/uno/scriptcont.cxx index 5622adc19af1..f7091d1c1a0b 100644 --- a/basic/source/uno/scriptcont.cxx +++ b/basic/source/uno/scriptcont.cxx @@ -216,8 +216,7 @@ void SAL_CALL SfxScriptLibraryContainer::writeLibraryElement Any aElement = xLib->getByName( aElementName ); aElement >>= aMod.aCode; - Reference < script::XVBAModuleInfo > xModInfo( xLib, UNO_QUERY ); - + Reference< script::vba::XVBAModuleInfo > xModInfo( xLib, UNO_QUERY ); if( xModInfo.is() && xModInfo->hasModuleInfo( aElementName ) ) { script::ModuleInfo aModInfo = xModInfo->getModuleInfo( aElementName ); @@ -312,9 +311,9 @@ Any SAL_CALL SfxScriptLibraryContainer::importLibraryElement // aMod.aName ignored if( aMod.aModuleType.getLength() > 0 ) { - if( !getVBACompatModeOn() ) + if( !getVBACompatibilityMode() ) { - setVBACompatModeOn( sal_True ); + setVBACompatibilityMode( sal_True ); Any aGlobs; Sequence< Any > aArgs(1); @@ -381,8 +380,7 @@ Any SAL_CALL SfxScriptLibraryContainer::importLibraryElement } } - Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, - UNO_QUERY ); + Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY ); if( xVBAModuleInfo.is() ) { if( xVBAModuleInfo->hasModuleInfo( aElementName ) ) diff --git a/configmgr/source/rootaccess.cxx b/configmgr/source/rootaccess.cxx index 95a346d720c2..f5d0bb137202 100644 --- a/configmgr/source/rootaccess.cxx +++ b/configmgr/source/rootaccess.cxx @@ -96,11 +96,12 @@ void RootAccess::initBroadcaster( for (ChangesListeners::iterator i(changesListeners_.begin()); i != changesListeners_.end(); ++i) { + cppu::OWeakObject* pSource = static_cast< cppu::OWeakObject * >(this); + css::uno::Reference< css::uno::XInterface > xBase( pSource, css::uno::UNO_QUERY ); broadcaster->addChangesNotification( *i, css::util::ChangesEvent( - static_cast< cppu::OWeakObject * >(this), - css::uno::makeAny(pathRepresentation_), set)); + pSource, makeAny( xBase ), set)); } } } diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index cabec4a05691..cf19af655a1b 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -28,6 +28,9 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_desktop.hxx" +#include <cstdlib> +#include <vector> + #include <memory> #include <unistd.h> #include "app.hxx" @@ -119,6 +122,7 @@ #include <osl/file.hxx> #include <osl/signal.h> #include <rtl/uuid.h> +#include <rtl/uri.hxx> #include <unotools/pathoptions.hxx> #include <svl/languageoptions.hxx> #include <unotools/internaloptions.hxx> @@ -155,6 +159,11 @@ #include "langselect.hxx" +#if defined MACOSX +#include <errno.h> +#include <sys/wait.h> +#endif + #define DEFINE_CONST_UNICODE(CONSTASCII) UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII)) #define U2S(STRING) ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8) @@ -460,6 +469,194 @@ void ReplaceStringHookProc( UniString& rStr ) } } +static const char pLastSyncFileName[] = "lastsynchronized"; +static const sal_Int32 nStrLenLastSync = 16; + +static bool needsSynchronization( + ::rtl::OUString const & baseSynchronizedURL, ::rtl::OUString const & userSynchronizedURL ) +{ + bool bNeedsSync( false ); + + ::osl::DirectoryItem itemUserFile; + ::osl::File::RC err1 = + ::osl::DirectoryItem::get(userSynchronizedURL, itemUserFile); + + //If it does not exist, then there is nothing to be done + if (err1 == ::osl::File::E_NOENT) + { + return true; + } + else if (err1 != ::osl::File::E_None) + { + OSL_ENSURE(0, "Cannot access lastsynchronized in user layer"); + return true; //sync just in case + } + + //If last synchronized does not exist in base layer, then do nothing + ::osl::DirectoryItem itemBaseFile; + ::osl::File::RC err2 = ::osl::DirectoryItem::get(baseSynchronizedURL, itemBaseFile); + if (err2 == ::osl::File::E_NOENT) + { + return true; + + } + else if (err2 != ::osl::File::E_None) + { + OSL_ENSURE(0, "Cannot access file lastsynchronized in base layer"); + return true; //sync just in case + } + + //compare the modification time of the extension folder and the last + //modified file + ::osl::FileStatus statUser(FileStatusMask_ModifyTime); + ::osl::FileStatus statBase(FileStatusMask_ModifyTime); + if (itemUserFile.getFileStatus(statUser) == ::osl::File::E_None) + { + if (itemBaseFile.getFileStatus(statBase) == ::osl::File::E_None) + { + TimeValue timeUser = statUser.getModifyTime(); + TimeValue timeBase = statBase.getModifyTime(); + + if (timeUser.Seconds < timeBase.Seconds) + bNeedsSync = true; + } + else + { + OSL_ASSERT(0); + bNeedsSync = true; + } + } + else + { + OSL_ASSERT(0); + bNeedsSync = true; + } + + return bNeedsSync; +} + +static ::rtl::OUString getBrandSharePreregBundledPathURL() +{ + ::rtl::OUString url( + RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/share/prereg/bundled")); + + ::rtl::Bootstrap::expandMacros(url); + return url; +} + +static ::rtl::OUString getUserBundledExtPathURL() +{ + ::rtl::OUString folder( RTL_CONSTASCII_USTRINGPARAM( "$BUNDLED_EXTENSIONS_USER" )); + ::rtl::Bootstrap::expandMacros(folder); + + return folder; +} + +static ::rtl::OUString getLastSyncFileURLFromBrandInstallation() +{ + ::rtl::OUString aURL = getBrandSharePreregBundledPathURL(); + ::sal_Int32 nLastIndex = aURL.lastIndexOf('/'); + + ::rtl::OUStringBuffer aTmp( aURL ); + + if ( nLastIndex != aURL.getLength()-1 ) + aTmp.appendAscii( "/" ); + aTmp.appendAscii( pLastSyncFileName ); + + return aTmp.makeStringAndClear(); +} + +static ::rtl::OUString getLastSyncFileURLFromUserInstallation() +{ + ::rtl::OUString aUserBundledPathURL = getUserBundledExtPathURL(); + ::sal_Int32 nLastIndex = aUserBundledPathURL.lastIndexOf('/'); + + ::rtl::OUStringBuffer aTmp( aUserBundledPathURL ); + + if ( nLastIndex != aUserBundledPathURL.getLength()-1 ) + aTmp.appendAscii( "/" ); + aTmp.appendAscii( pLastSyncFileName ); + + return aTmp.makeStringAndClear(); +} + +static osl::FileBase::RC copy_bundled_recursive( + const rtl::OUString& srcUnqPath, + const rtl::OUString& dstUnqPath, + sal_Int32 TypeToCopy ) +throw() +{ + osl::FileBase::RC err = osl::FileBase::E_None; + + if( TypeToCopy == -1 ) // Document + { + err = osl::File::copy( srcUnqPath,dstUnqPath ); + } + else if( TypeToCopy == +1 ) // Folder + { + osl::Directory aDir( srcUnqPath ); + aDir.open(); + + err = osl::Directory::create( dstUnqPath ); + osl::FileBase::RC next = err; + if( err == osl::FileBase::E_None || + err == osl::FileBase::E_EXIST ) + { + err = osl::FileBase::E_None; + sal_Int32 n_Mask = FileStatusMask_FileURL | FileStatusMask_FileName | FileStatusMask_Type; + + osl::DirectoryItem aDirItem; + + while( err == osl::FileBase::E_None && ( next = aDir.getNextItem( aDirItem ) ) == osl::FileBase::E_None ) + { + sal_Bool IsDoc = false; + sal_Bool bFilter = false; + osl::FileStatus aFileStatus( n_Mask ); + aDirItem.getFileStatus( aFileStatus ); + if( aFileStatus.isValid( FileStatusMask_Type ) ) + IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular; + + // Getting the information for the next recursive copy + sal_Int32 newTypeToCopy = IsDoc ? -1 : +1; + + rtl::OUString newSrcUnqPath; + if( aFileStatus.isValid( FileStatusMask_FileURL ) ) + newSrcUnqPath = aFileStatus.getFileURL(); + + rtl::OUString newDstUnqPath = dstUnqPath; + rtl::OUString tit; + if( aFileStatus.isValid( FileStatusMask_FileName ) ) + { + ::rtl::OUString aFileName = aFileStatus.getFileName(); + tit = rtl::Uri::encode( aFileName, + rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ); + + // Special treatment for "lastsychronized" file. Must not be + // copied from the bundled folder! + if ( IsDoc && aFileName.equalsAscii( pLastSyncFileName )) + bFilter = true; + } + + if( newDstUnqPath.lastIndexOf( sal_Unicode('/') ) != newDstUnqPath.getLength()-1 ) + newDstUnqPath += rtl::OUString::createFromAscii( "/" ); + + newDstUnqPath += tit; + + if (( newSrcUnqPath != dstUnqPath ) && !bFilter ) + err = copy_bundled_recursive( newSrcUnqPath,newDstUnqPath, newTypeToCopy ); + } + + if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT ) + err = next; + } + aDir.close(); + } + + return err; +} + Desktop::Desktop() : m_bServicesRegistered( false ) , m_aBootstrapError( BE_OK ) @@ -477,6 +674,24 @@ void Desktop::Init() RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" ); SetBootstrapStatus(BS_OK); + // Check for lastsynchronized file for bundled extensions in the user directory + // and test if synchronzation is necessary! + { + ::rtl::OUString aUserLastSyncFilePathURL = getLastSyncFileURLFromUserInstallation(); + ::rtl::OUString aPreregSyncFilePathURL = getLastSyncFileURLFromBrandInstallation(); + + if ( needsSynchronization( aPreregSyncFilePathURL, aUserLastSyncFilePathURL )) + { + rtl::OUString aUserPath = getUserBundledExtPathURL(); + rtl::OUString aPreregBundledPath = getBrandSharePreregBundledPathURL(); + + // copy bundled folder to the user directory + osl::FileBase::RC rc = osl::Directory::createPath(aUserPath); + (void) rc; + copy_bundled_recursive( aPreregBundledPath, aUserPath, +1 ); + } + } + // create service factory... Reference < XMultiServiceFactory > rSMgr = CreateApplicationServiceManager(); if( rSMgr.is() ) @@ -1117,28 +1332,79 @@ sal_Bool Desktop::SaveTasks() sal_False); } -#ifdef MACOSX -static void DoRestart() -{ - oslProcess process; - oslProcessError error; - OUString sExecutableFile; - - osl_getExecutableFile( &sExecutableFile.pData ); - - error = osl_executeProcess( - sExecutableFile.pData, - NULL, - 0, - 0, - NULL, - NULL, - NULL, - 0, - &process - ); -} +namespace { + +void restartOnMac(bool passArguments) { +#if defined MACOSX + OfficeIPCThread::DisableOfficeIPCThread(); + rtl::OUString execUrl; + OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None); + rtl::OUString execPath; + rtl::OString execPath8; + if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath) + != osl::FileBase::E_None) || + !execPath.convertToString( + &execPath8, osl_getThreadTextEncoding(), + (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | + RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) + { + std::abort(); + } + std::vector< rtl::OString > args; + args.push_back(execPath8); + bool wait = false; + if (passArguments) { + sal_uInt32 n = osl_getCommandArgCount(); + for (sal_uInt32 i = 0; i < n; ++i) { + rtl::OUString arg; + OSL_VERIFY(osl_getCommandArg(i, &arg.pData) == osl_Process_E_None); + if (arg.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("-accept="))) { + wait = true; + } + rtl::OString arg8; + if (!arg.convertToString( + &arg8, osl_getThreadTextEncoding(), + (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | + RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) + { + std::abort(); + } + args.push_back(arg8); + } + } + std::vector< char const * > argPtrs; + for (std::vector< rtl::OString >::iterator i(args.begin()); i != args.end(); + ++i) + { + argPtrs.push_back(i->getStr()); + } + argPtrs.push_back(0); + execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0])); + if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6 + pid_t pid = fork(); + if (pid == 0) { + execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0])); + } else if (pid > 0) { + // Two simultaneously running soffice processes lead to two dock + // icons, so avoid waiting here unless it must be assumed that the + // process invoking soffice itself wants to wait for soffice to + // finish: + if (!wait) { + return; + } + int stat; + if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) { + _exit(WEXITSTATUS(stat)); + } + } + } + std::abort(); +#else + (void) passArguments; // avoid warnings #endif +} + +} USHORT Desktop::Exception(USHORT nError) { @@ -1209,9 +1475,7 @@ USHORT Desktop::Exception(USHORT nError) OfficeIPCThread::DisableOfficeIPCThread(); if( pSignalHandler ) DELETEZ( pSignalHandler ); -#ifdef MACOSX - DoRestart(); -#endif + restartOnMac(false); _exit( ExitHelper::E_CRASH_WITH_RESTART ); } else @@ -1294,6 +1558,9 @@ void Desktop::Main() std::auto_ptr<SvtLanguageOptions> pLanguageOptions; std::auto_ptr<SvtPathOptions> pPathOptions; + sal_Bool bRestartRequested( sal_False ); + sal_Bool bUseSystemFileDialog(sal_True); + int nAcquireCount( 0 ); Reference < css::document::XEventListener > xGlobalBroadcaster; try { @@ -1423,6 +1690,13 @@ void Desktop::Main() ( xSMgr->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.frame.GlobalEventBroadcaster" ) ), UNO_QUERY ); + /* ensure existance of a default window that messages can be dispatched to + This is for the benefit of testtool which uses PostUserEvent extensively + and else can deadlock while creating this window from another tread while + the main thread is not yet in the event loop. + */ + Application::GetDefaultDevice(); + // initialize test-tool library (if available) RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ tools::InitTestToolLib" ); tools::InitTestToolLib(); @@ -1487,58 +1761,80 @@ void Desktop::Main() impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData); RTL_LOGFILE_CONTEXT_TRACE( aLog, "} impl_checkRecoveryState" ); - if ( - (pCmdLineArgs->IsEmptyOrAcceptOnly() ) && - (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) && - (!bExistsRecoveryData ) && - (!bExistsSessionData ) && - (!Application::AnyInput( INPUT_APPEVENT ) ) - ) + Reference< ::com::sun::star::task::XRestartManager > xRestartManager; { - RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create BackingComponent" ); - Reference< XFrame > xDesktopFrame( xSMgr->createInstance( - OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY ); - if (xDesktopFrame.is()) + ::comphelper::ComponentContext aContext( xSMgr ); + xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY ); + } + + // check whether the shutdown is caused by restart + bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) ); + + if ( pCmdLineArgs->IsHeadless() ) + { + // Ensure that we use not the system file dialogs as + // headless mode relies on Application::EnableHeadlessMode() + // which does only work for VCL dialogs!! + SvtMiscOptions aMiscOptions; + bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog(); + aMiscOptions.SetUseSystemFileDialog( sal_False ); + } + + if ( !bRestartRequested ) + { + if ( + (pCmdLineArgs->IsEmptyOrAcceptOnly() ) && + (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) && + (!bExistsRecoveryData ) && + (!bExistsSessionData ) && + (!Application::AnyInput( INPUT_APPEVENT ) ) + ) { -// SetSplashScreenProgress(60); - Reference< XFrame > xBackingFrame; - Reference< ::com::sun::star::awt::XWindow > xContainerWindow; - - xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0); - if (xBackingFrame.is()) - xContainerWindow = xBackingFrame->getContainerWindow(); - if (xContainerWindow.is()) + RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create BackingComponent" ); + Reference< XFrame > xDesktopFrame( xSMgr->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY ); + if (xDesktopFrame.is()) { - // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank" - // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior, - // otherwise documents loaded into this frame will later on miss functionality depending on the style. - Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); - OSL_ENSURE( pContainerWindow, "Desktop::Main: no implementation access to the frame's container window!" ); - pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT ); - - SetSplashScreenProgress(75); - Sequence< Any > lArgs(1); - lArgs[0] <<= xContainerWindow; - - Reference< XController > xBackingComp( - xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs), - UNO_QUERY); -// SetSplashScreenProgress(80); - if (xBackingComp.is()) + // SetSplashScreenProgress(60); + Reference< XFrame > xBackingFrame; + Reference< ::com::sun::star::awt::XWindow > xContainerWindow; + + xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0); + if (xBackingFrame.is()) + xContainerWindow = xBackingFrame->getContainerWindow(); + if (xContainerWindow.is()) { - Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY); - // Attention: You MUST(!) call setComponent() before you call attachFrame(). - // Because the backing component set the property "IsBackingMode" of the frame - // to true inside attachFrame(). But setComponent() reset this state everytimes ... - xBackingFrame->setComponent(xBackingWin, xBackingComp); - SetSplashScreenProgress(100); - xBackingComp->attachFrame(xBackingFrame); - CloseSplashScreen(); - xContainerWindow->setVisible(sal_True); + // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank" + // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior, + // otherwise documents loaded into this frame will later on miss functionality depending on the style. + Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + OSL_ENSURE( pContainerWindow, "Desktop::Main: no implementation access to the frame's container window!" ); + pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT ); + + SetSplashScreenProgress(75); + Sequence< Any > lArgs(1); + lArgs[0] <<= xContainerWindow; + + Reference< XController > xBackingComp( + xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs), + UNO_QUERY); + // SetSplashScreenProgress(80); + if (xBackingComp.is()) + { + Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY); + // Attention: You MUST(!) call setComponent() before you call attachFrame(). + // Because the backing component set the property "IsBackingMode" of the frame + // to true inside attachFrame(). But setComponent() reset this state everytimes ... + xBackingFrame->setComponent(xBackingWin, xBackingComp); + SetSplashScreenProgress(100); + xBackingComp->attachFrame(xBackingFrame); + CloseSplashScreen(); + xContainerWindow->setVisible(sal_True); + } } } + RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create BackingComponent" ); } - RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create BackingComponent" ); } } catch ( com::sun::star::lang::WrappedTargetException& wte ) @@ -1573,114 +1869,100 @@ void Desktop::Main() aOptions.SetVCLSettings(); // SetSplashScreenProgress(60); - Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) ); - - sal_Bool bTerminateRequested = sal_False; - - // Preload function depends on an initialized sfx application! - SetSplashScreenProgress(75); - - sal_Bool bUseSystemFileDialog(sal_True); - if ( pCmdLineArgs->IsHeadless() ) + if ( !bRestartRequested ) { - // Ensure that we use not the system file dialogs as - // headless mode relies on Application::EnableHeadlessMode() - // which does only work for VCL dialogs!! - SvtMiscOptions aMiscOptions; - bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog(); - aMiscOptions.SetUseSystemFileDialog( sal_False ); - } + Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) ); - // use system window dialogs - Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG ); + sal_Bool bTerminateRequested = sal_False; -// SetSplashScreenProgress(80); + // Preload function depends on an initialized sfx application! + SetSplashScreenProgress(75); - if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() && - !pCmdLineArgs->IsNoQuickstart() ) - InitializeQuickstartMode( xSMgr ); + // use system window dialogs + Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG ); - RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) createInstance com.sun.star.frame.Desktop" ); - try - { - Reference< XDesktop > xDesktop( xSMgr->createInstance( - OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY ); - if ( xDesktop.is() ) - xDesktop->addTerminateListener( new OfficeIPCThreadController ); - SetSplashScreenProgress(100); - } - catch ( com::sun::star::uno::Exception& e ) - { - FatalError( MakeStartupErrorMessage(e.Message) ); - return; - } - /* - catch ( ... ) - { - FatalError( MakeStartupErrorMessage( - OUString::createFromAscii( - "Unknown error during startup (TD/Desktop service).\nInstallation could be damaged."))); - return; - } - */ + // SetSplashScreenProgress(80); - // Release solar mutex just before we wait for our client to connect - int nAcquireCount = 0; - ::vos::IMutex& rMutex = Application::GetSolarMutex(); - if ( rMutex.tryToAcquire() ) - nAcquireCount = Application::ReleaseSolarMutex() - 1; + if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() && + !pCmdLineArgs->IsNoQuickstart() ) + InitializeQuickstartMode( xSMgr ); - // Post user event to startup first application component window - // We have to send this OpenClients message short before execute() to - // minimize the risk that this message overtakes type detection contruction!! - Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) ); + RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) createInstance com.sun.star.frame.Desktop" ); + try + { + Reference< XDesktop > xDesktop( xSMgr->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY ); + if ( xDesktop.is() ) + xDesktop->addTerminateListener( new OfficeIPCThreadController ); + SetSplashScreenProgress(100); + } + catch ( com::sun::star::uno::Exception& e ) + { + FatalError( MakeStartupErrorMessage(e.Message) ); + return; + } + /* + catch ( ... ) + { + FatalError( MakeStartupErrorMessage( + OUString::createFromAscii( + "Unknown error during startup (TD/Desktop service).\nInstallation could be damaged."))); + return; + } + */ - // Post event to enable acceptors - Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) ); + // Post user event to startup first application component window + // We have to send this OpenClients message short before execute() to + // minimize the risk that this message overtakes type detection contruction!! + Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) ); - // The configuration error handler currently is only for startup - aConfigErrHandler.deactivate(); + // Post event to enable acceptors + Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) ); - // Acquire solar mutex just before we enter our message loop - if ( nAcquireCount ) - Application::AcquireSolarMutex( nAcquireCount ); + // The configuration error handler currently is only for startup + aConfigErrHandler.deactivate(); - // call Application::Execute to process messages in vcl message loop - RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Application::Execute()" ); + // Acquire solar mutex just before we enter our message loop + if ( nAcquireCount ) + Application::AcquireSolarMutex( nAcquireCount ); - Reference< ::com::sun::star::task::XRestartManager > xRestartManager; - try - { - // The JavaContext contains an interaction handler which is used when - // the creation of a Java Virtual Machine fails - com::sun::star::uno::ContextLayer layer2( - new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) ); + // call Application::Execute to process messages in vcl message loop + RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Application::Execute()" ); - ::comphelper::ComponentContext aContext( xSMgr ); - xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY ); - if ( !xRestartManager.is() || !xRestartManager->isRestartRequested( sal_True ) ) + Reference< ::com::sun::star::task::XRestartManager > xRestartManager; + try { - // if this run of the office is triggered by restart, some additional actions should be done - DoRestartActionsIfNecessary( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoQuickstart() ); + // The JavaContext contains an interaction handler which is used when + // the creation of a Java Virtual Machine fails + com::sun::star::uno::ContextLayer layer2( + new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) ); - Execute(); + ::comphelper::ComponentContext aContext( xSMgr ); + xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY ); + if ( !xRestartManager.is() || !xRestartManager->isRestartRequested( sal_True ) ) + { + // if this run of the office is triggered by restart, some additional actions should be done + DoRestartActionsIfNecessary( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoQuickstart() ); + + Execute(); + } + } + catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg) + { + OfficeIPCThread::SetDowning(); + FatalError( MakeStartupErrorMessage(exFilterCfg.Message) ); + } + catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg) + { + OfficeIPCThread::SetDowning(); + FatalError( MakeStartupErrorMessage(exAnyCfg.Message) ); } - } - catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg) - { - OfficeIPCThread::SetDowning(); - FatalError( MakeStartupErrorMessage(exFilterCfg.Message) ); - } - catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg) - { - OfficeIPCThread::SetDowning(); - FatalError( MakeStartupErrorMessage(exAnyCfg.Message) ); - } - // check whether the shutdown is caused by restart - sal_Bool bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) ); - if ( bRestartRequested ) - SetRestartState(); + // check whether the shutdown is caused by restart + sal_Bool bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) ); + if ( bRestartRequested ) + SetRestartState(); + } if (xGlobalBroadcaster.is()) { @@ -1716,9 +1998,7 @@ void Desktop::Main() RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::Main" ); if ( bRestartRequested ) { -#ifdef MACOSX - DoRestart(); -#endif + restartOnMac(true); // wouldn't the solution be more clean if SalMain returns the exit code to the system? _exit( ExitHelper::E_NORMAL_RESTART ); } diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.cxx b/desktop/source/deployment/gui/dp_gui_dialog2.cxx index 87f70e449b9d..78b29624b16e 100755..100644 --- a/desktop/source/deployment/gui/dp_gui_dialog2.cxx +++ b/desktop/source/deployment/gui/dp_gui_dialog2.cxx @@ -372,11 +372,13 @@ MENU_COMMAND ExtBoxWithBtns_Impl::ShowPopupMenu( const Point & rPos, const long if ( ! GetEntryData( nPos )->m_bLocked ) { - if ( GetEntryData( nPos )->m_eState == REGISTERED ) - aPopup.InsertItem( CMD_DISABLE, DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) ); - else if ( GetEntryData( nPos )->m_eState != NOT_AVAILABLE ) - aPopup.InsertItem( CMD_ENABLE, DialogHelper::getResourceString( RID_CTX_ITEM_ENABLE ) ); - + if ( GetEntryData( nPos )->m_bUser ) + { + if ( GetEntryData( nPos )->m_eState == REGISTERED ) + aPopup.InsertItem( CMD_DISABLE, DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) ); + else if ( GetEntryData( nPos )->m_eState != NOT_AVAILABLE ) + aPopup.InsertItem( CMD_ENABLE, DialogHelper::getResourceString( RID_CTX_ITEM_ENABLE ) ); + } aPopup.InsertItem( CMD_REMOVE, DialogHelper::getResourceString( RID_CTX_ITEM_REMOVE ) ); } diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx index de9d97db2b48..c82973f1b680 100644 --- a/desktop/source/deployment/manager/dp_extensionmanager.cxx +++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx @@ -1136,6 +1136,14 @@ sal_Bool ExtensionManager::synchronize( bModified |= m_bundledRepository->synchronize(xAbortChannel, xCmdEnv); progressBundled.update(OUSTR("\n\n")); + //Always determine the active extension. This is necessary for the + //first-start optimization. The setup creates the registration data for the + //bundled extensions (brand_layer/share/prereg/bundled), which is copied to the user + //installation (user_installation/extension/bundled) when a user starts OOo + //for the first time after running setup. All bundled extensions are registered + //at that moment. However, extensions with the same identifier can be in the + //shared or user repository, in which case the respective bundled extensions must + //be revoked. try { const uno::Sequence<uno::Sequence<Reference<deploy::XPackage> > > diff --git a/desktop/source/deployment/manager/dp_properties.cxx b/desktop/source/deployment/manager/dp_properties.cxx index df579944c6e4..9a181d1573e5 100644 --- a/desktop/source/deployment/manager/dp_properties.cxx +++ b/desktop/source/deployment/manager/dp_properties.cxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * diff --git a/desktop/source/deployment/manager/dp_properties.hxx b/desktop/source/deployment/manager/dp_properties.hxx index 97fc8b8c5394..a1b953ce8376 100644 --- a/desktop/source/deployment/manager/dp_properties.hxx +++ b/desktop/source/deployment/manager/dp_properties.hxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_manager.h,v $ - * $Revision: 1.17 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx index fe3490903043..cfdac4068130 100644 --- a/desktop/source/deployment/misc/dp_misc.cxx +++ b/desktop/source/deployment/misc/dp_misc.cxx @@ -589,6 +589,11 @@ void TRACE(::rtl::OString const & sText) void syncRepositories(Reference<ucb::XCommandEnvironment> const & xCmdEnv) { + OUString sDisable; + ::rtl::Bootstrap::get( OUSTR( "DISABLE_EXTENSION_SYNCHRONIZATION" ), sDisable, OUString() ); + if (sDisable.getLength() > 0) + return; + Reference<deployment::XExtensionManager> xExtensionManager; //synchronize shared before bundled otherewise there are //more revoke and registration calls. diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.cxx b/desktop/source/deployment/registry/configuration/dp_configuration.cxx index 9ea6e8227340..3c6680065db5 100644 --- a/desktop/source/deployment/registry/configuration/dp_configuration.cxx +++ b/desktop/source/deployment/registry/configuration/dp_configuration.cxx @@ -359,16 +359,11 @@ void BackendImpl::configmgrini_verify_init( do { OUString token( line.getToken( 0, ' ', index ).trim() ); if (token.getLength() > 0) { - // cleanup, check if existing: - if (create_ucb_content( - 0, expandUnoRcTerm(token), xCmdEnv, - false /* no throw */ )) { - //The file may not exist anymore if a shared or bundled - //extension was removed, but it can still be in the configmgrini. - //After running XExtensionManager::synchronize, the configmgrini is - //cleaned up - m_xcs_files.push_back( token ); - } + //The file may not exist anymore if a shared or bundled + //extension was removed, but it can still be in the configmgrini. + //After running XExtensionManager::synchronize, the configmgrini is + //cleaned up + m_xcs_files.push_back( token ); } } while (index >= 0); @@ -378,31 +373,15 @@ void BackendImpl::configmgrini_verify_init( sal_Int32 index = sizeof ("DATA=") - 1; do { OUString token( line.getToken( 0, ' ', index ).trim() ); - if (token.getLength() > 0) { + if (token.getLength() > 0) + { if (token[ 0 ] == '?') token = token.copy( 1 ); - // cleanup, check if existing: - if (create_ucb_content( - 0, expandUnoRcTerm(token), - xCmdEnv, false /* no throw */ )) { - //The file may not exist anymore if a shared or bundled - //extension was removed, but it can still be in the configmgrini. - //After running XExtensionManager::synchronize, the configmgrini is - //cleaned up - m_xcu_files.push_back( token ); - } - else - { - //Check if it was removed. Only when the file contained %origin, so that - //a new file was writen in the user installation (e.g. $BUNDLED_EXTENSIONS_USER) - //See also ConfigurationBackendDb.iniEntry - ::std::list<OUString> iniEntries = getAllIniEntries(); - if (::std::find(iniEntries.begin(), iniEntries.end(), token) - != iniEntries.end()) - m_xcu_files.push_back( token ); - else - OSL_ENSURE(0, "Extension manager: Invalid configmgr.ini entry."); - } + //The file may not exist anymore if a shared or bundled + //extension was removed, but it can still be in the configmgrini. + //After running XExtensionManager::synchronize, the configmgrini is + //cleaned up + m_xcu_files.push_back( token ); } } while (index >= 0); @@ -502,6 +481,8 @@ bool BackendImpl::removeFromConfigmgrIni( { //in case the xcu contained %origin% then the configmr.ini contains the //url to the file in the user installation (e.g. $BUNDLED_EXTENSIONS_USER) + //However, m_url (getURL()) contains the URL for the file in the actual + //extension installatation. ::boost::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_); if (data) i = std::find(rSet.begin(), rSet.end(), data->iniEntry); @@ -757,10 +738,17 @@ void BackendImpl::PackageImpl::processPackage_( } that->m_registeredPackages->erase(i->first); } - ::ucbhelper::Content( - makeURL( that->getCachePath(), OUSTR("registry") ), - xCmdEnv ).executeCommand( - OUSTR("delete"), Any( true /* delete physically */ ) ); + try + { + ::ucbhelper::Content( + makeURL( that->getCachePath(), OUSTR("registry") ), + xCmdEnv ).executeCommand( + OUSTR("delete"), Any( true /* delete physically */ ) ); + } + catch(Exception&) + { + OSL_ASSERT(0); + } } that->deleteDataFromDb(getURL()); diff --git a/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx index 845ba88cb813..2a02c6d8efa0 100644 --- a/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx +++ b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_package.cxx,v $ - * $Revision: 1.34.16.2 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx index 1b6c4f8973a4..7023897bd8de 100644 --- a/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx +++ b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_backend.h,v $ - * $Revision: 1.18 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/deployment/registry/dp_registry.cxx b/desktop/source/deployment/registry/dp_registry.cxx index c5e440a2a825..0f309a5b729f 100644 --- a/desktop/source/deployment/registry/dp_registry.cxx +++ b/desktop/source/deployment/registry/dp_registry.cxx @@ -129,7 +129,9 @@ public: virtual Reference<deployment::XPackage> SAL_CALL bindPackage( OUString const & url, OUString const & mediaType, sal_Bool bRemoved, OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ) - throw (deployment::DeploymentException, CommandFailedException, + throw (deployment::DeploymentException, + deployment::InvalidRemovedParameterException, + CommandFailedException, lang::IllegalArgumentException, RuntimeException); virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL getSupportedPackageTypes() throw (RuntimeException); @@ -461,7 +463,8 @@ void PackageRegistryImpl::update() throw (RuntimeException) Reference<deployment::XPackage> PackageRegistryImpl::bindPackage( OUString const & url, OUString const & mediaType_, sal_Bool bRemoved, OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ) - throw (deployment::DeploymentException, CommandFailedException, + throw (deployment::DeploymentException, deployment::InvalidRemovedParameterException, + CommandFailedException, lang::IllegalArgumentException, RuntimeException) { check(); diff --git a/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx b/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx index 976a6281a2bd..ff1044910985 100644 --- a/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx +++ b/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_package.cxx,v $ - * $Revision: 1.34.16.2 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx b/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx index 4f17eeda24a6..80cd33771a34 100644 --- a/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx +++ b/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_backend.h,v $ - * $Revision: 1.18 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx b/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx index 3bf67e0c050b..8ec9a39d5050 100644 --- a/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx +++ b/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_package.cxx,v $ - * $Revision: 1.34.16.2 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx b/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx index edf7dfdfc284..c7b730fd1b99 100644 --- a/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx +++ b/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_backend.h,v $ - * $Revision: 1.18 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/deployment/registry/package/dp_package.cxx b/desktop/source/deployment/registry/package/dp_package.cxx index 2ad6478b665c..feb55d0af3bf 100644 --- a/desktop/source/deployment/registry/package/dp_package.cxx +++ b/desktop/source/deployment/registry/package/dp_package.cxx @@ -866,14 +866,10 @@ void BackendImpl::PackageImpl::processPackage_( try { xPackage->registerPackage( startup, xSubAbortChannel, xCmdEnv ); } - catch (RuntimeException &) { - throw; - } - catch (ucb::CommandAbortedException &) { - throw; - } - catch (Exception &) { - // CommandFailedException, DeploymentException: + catch (Exception &) + { + //We even try a rollback if the user cancelled the action (CommandAbortedException) + //in order to prevent invalid database entries. Any exc( ::cppu::getCaughtException() ); // try to handle exception, notify: bool approve = false, abort = false; @@ -904,14 +900,8 @@ void BackendImpl::PackageImpl::processPackage_( bundle[ pos ]->revokePackage( xSubAbortChannel, xCmdEnv ); } - catch (RuntimeException &) { - throw; - } - catch (ucb::CommandAbortedException &) { - throw; - } - catch (Exception &) { - // bundle rollback error: + catch (Exception &) + { OSL_ENSURE( 0, ::rtl::OUStringToOString( ::comphelper::anyToString( ::cppu::getCaughtException() ), diff --git a/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx b/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx index ce0d3029084d..9a84a7286027 100644 --- a/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx +++ b/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_package.cxx,v $ - * $Revision: 1.34.16.2 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx b/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx index 9d227f8b64b8..7feaeba5568b 100644 --- a/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx +++ b/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dp_backend.h,v $ - * $Revision: 1.18 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/migration/services/cexportsoo3.cxx b/desktop/source/migration/services/cexportsoo3.cxx index 20b8232044e9..695b6b810808 100755..100644 --- a/desktop/source/migration/services/cexportsoo3.cxx +++ b/desktop/source/migration/services/cexportsoo3.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: cexports.cxx,v $ - * $Revision: 1.9 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/migration/services/oo3extensionmigration.cxx b/desktop/source/migration/services/oo3extensionmigration.cxx index 2e3a8d1d518c..3e9836fa2e84 100644 --- a/desktop/source/migration/services/oo3extensionmigration.cxx +++ b/desktop/source/migration/services/oo3extensionmigration.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: extensionmigration.cxx,v $ - * $Revision: 1.2 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/migration/services/oo3extensionmigration.hxx b/desktop/source/migration/services/oo3extensionmigration.hxx index 03995652888c..fb58692c81ee 100644 --- a/desktop/source/migration/services/oo3extensionmigration.hxx +++ b/desktop/source/migration/services/oo3extensionmigration.hxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: extensionmigration.hxx,v $ - * $Revision: 1.2 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx index a9a0c8271373..4545ed862271 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_app.cxx +++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx @@ -39,6 +39,7 @@ #include "osl/thread.h" #include "osl/process.h" #include "osl/conditn.hxx" +#include "osl/file.hxx" #include "cppuhelper/implbase1.hxx" #include "cppuhelper/exc_hlp.hxx" #include "comphelper/anytostring.hxx" @@ -377,6 +378,29 @@ extern "C" int unopkg_main() if (e != osl_File_E_None && e != osl_File_E_NOENT) throw Exception(OUSTR("Could not delete ") + extensionUnorc, 0); } + else if (subCommand.equals(OUSTR("sync"))) + { + //sync is private!!!! Only for bundled extensions!!! + //For performance reasons unopkg sync is called during the setup and + //creates the registration data for the repository of the bundled + //extensions. It is then copied to the user installation during + //startup of OOo (userdata/extensions/bundled). The registration + //data is in the brand installation and must be removed when + //uninstalling OOo. We do this here, before UNO is + //bootstrapped. Otherwies files could be locked by this process. + + //If there is no folder left in + //$BRAND_BASE_DIR/share/extensions + //then we can delete the registration data at + //$BUNDLED_EXTENSIONS_USER + if (hasNoFolder(OUSTR("$BRAND_BASE_DIR/share/extensions"))) + { + removeFolder(OUSTR("$BUNDLED_EXTENSIONS_USER")); + //return otherwise we create the registration data again + return 0; + } + + } xComponentContext = getUNO( disposeGuard, option_verbose, option_shared, subcmd_gui, @@ -587,6 +611,15 @@ extern "C" int unopkg_main() xDialog->startExecuteModal(xListener); dialogEnded.wait(); } + else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("sync"))) + { + //This sub command may be removed later and is only there to have a + //possibility to start extension synching without any output. + //This is just here so we do not get an error, because of an unknown + //sub-command. We do synching before + //the sub-commands are processed. + + } else { dp_misc::writeConsoleError( diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx index 3272810afee2..d7b6e1ca2336 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx +++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx @@ -528,5 +528,110 @@ Reference<XComponentContext> getUNO( return xComponentContext; } +//Determines if a folder does not contains a folder. +//Return false may also mean that the status could not be determined +//because some error occurred. +bool hasNoFolder(OUString const & folderUrl) +{ + bool ret = false; + OUString url = folderUrl; + ::rtl::Bootstrap::expandMacros(url); + ::osl::Directory dir(url); + osl::File::RC rc = dir.open(); + if (rc == osl::File::E_None) + { + bool bFolderExist = false; + osl::DirectoryItem i; + osl::File::RC rcNext = osl::File::E_None; + while ( (rcNext = dir.getNextItem(i)) == osl::File::E_None) + { + osl::FileStatus stat(FileStatusMask_Type); + if (i.getFileStatus(stat) == osl::File::E_None) + { + if (stat.getFileType() == osl::FileStatus::Directory) + { + bFolderExist = true; + break; + } + } + else + { + dp_misc::writeConsole( + OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n")); + break; + } + i = osl::DirectoryItem(); + } + + if (rcNext == osl::File::E_NOENT || + rcNext == osl::File::E_None) + { + if (!bFolderExist) + ret = true; + } + else + { + dp_misc::writeConsole( + OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n")); + } + + dir.close(); + } + else + { + dp_misc::writeConsole( + OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n")); + } + return ret; } +void removeFolder(OUString const & folderUrl) +{ + OUString url = folderUrl; + ::rtl::Bootstrap::expandMacros(url); + ::osl::Directory dir(url); + ::osl::File::RC rc = dir.open(); + if (rc == osl::File::E_None) + { + ::osl::DirectoryItem i; + ::osl::File::RC rcNext = ::osl::File::E_None; + while ( (rcNext = dir.getNextItem(i)) == ::osl::File::E_None) + { + ::osl::FileStatus stat(FileStatusMask_Type | FileStatusMask_FileURL); + if (i.getFileStatus(stat) == ::osl::File::E_None) + { + ::osl::FileStatus::Type t = stat.getFileType(); + if (t == ::osl::FileStatus::Directory) + { + //remove folder + removeFolder(stat.getFileURL()); + } + else if (t == ::osl::FileStatus::Regular) + { + //remove file + ::osl::File::remove(stat.getFileURL()); + } + else + { + OSL_ASSERT(0); + } + } + else + { + dp_misc::writeConsole( + OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n")); + break; + } + i = ::osl::DirectoryItem(); + } + dir.close(); + ::osl::Directory::remove(url); + } + else + { + dp_misc::writeConsole( + OUSTR("unopkg: Error while removing ") + url + OUSTR("\n")); + } +} + +} diff --git a/desktop/source/pkgchk/unopkg/unopkg_shared.h b/desktop/source/pkgchk/unopkg/unopkg_shared.h index 43f77513b10c..4975cc4c087b 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_shared.h +++ b/desktop/source/pkgchk/unopkg/unopkg_shared.h @@ -178,5 +178,11 @@ css::uno::Reference<css::uno::XComponentContext> getUNO( DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui, css::uno::Reference<css::uno::XComponentContext> & out_LocalComponentContext); +bool hasNoFolder(::rtl::OUString const & folderUrl); + +void removeFolder(::rtl::OUString const & folderUrl); + } + + diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index ede5acacc698..c8f5e2948665 100755 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -51,6 +51,7 @@ #include <com/sun/star/i18n/CharacterIteratorMode.hpp> #include <com/sun/star/i18n/WordType.hpp> #include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp> +#include <com/sun/star/uno/Sequence.hxx> #include <i18npool/lang.h> #include <vos/ref.hxx> @@ -1002,6 +1003,8 @@ public: void SetAutoCompleteText( const String& rStr, sal_Bool bUpdateTipWindow ); EditSelection TransliterateText( const EditSelection& rSelection, sal_Int32 nTransliterationMode ); + short ReplaceTextOnly( ContentNode* pNode, USHORT nCurrentStart, xub_StrLen nLen, const String& rText, const ::com::sun::star::uno::Sequence< sal_Int32 >& rOffsets ); + void SetAsianCompressionMode( USHORT n ); USHORT GetAsianCompressionMode() const { return nAsianCompressionMode; } diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx index 482cd6d71338..46a0668394f2 100755 --- a/editeng/source/editeng/impedit4.cxx +++ b/editeng/source/editeng/impedit4.cxx @@ -76,6 +76,9 @@ #include <com/sun/star/linguistic2/XThesaurus.hpp> #include <com/sun/star/linguistic2/XMeaning.hpp> #include <com/sun/star/i18n/ScriptType.hpp> +#include <com/sun/star/i18n/WordType.hpp> +#include <com/sun/star/i18n/TransliterationModules.hpp> +#include <com/sun/star/i18n/TransliterationModulesExtra.hpp> #include <unotools/transliterationwrapper.hxx> #include <unotools/textsearch.hxx> #include <comphelper/processfactory.hxx> @@ -83,6 +86,8 @@ #include <svtools/rtfkeywd.hxx> #include <editeng/edtdlg.hxx> +#include <vector> + using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; @@ -1458,7 +1463,11 @@ Reference< XSpellChecker1 > ImpEditEngine::GetSpeller() SpellInfo * ImpEditEngine::CreateSpellInfo( const EditSelection &rSel, bool bMultipleDocs ) { - pSpellInfo = new SpellInfo; + if (!pSpellInfo) + pSpellInfo = new SpellInfo; + else + *pSpellInfo = SpellInfo(); // reset to default values + pSpellInfo->bMultipleDoc = bMultipleDocs; EditSelection aSentenceSel( SelectSentence( rSel ) ); // pSpellInfo->aSpellStart = CreateEPaM( aSentenceSel.Min() ); @@ -2023,7 +2032,6 @@ bool ImpEditEngine::SpellSentence(EditView& rEditView, #else bool bRet = false; EditSelection aCurSel( rEditView.pImpEditView->GetEditSelection() ); - //the pSpellInfo has to be created on demand if(!pSpellInfo) pSpellInfo = CreateSpellInfo( aCurSel, true ); pSpellInfo->aCurSentenceStart = aCurSel.Min(); @@ -2191,8 +2199,12 @@ void ImpEditEngine::ApplyChangedSentence(EditView& rEditView, { #ifdef SVX_LIGHT #else + // Note: rNewPortions.size() == 0 is valid and happens when the whole + // sentence got removed in the dialog + DBG_ASSERT(pSpellInfo, "pSpellInfo not initialized"); - if(pSpellInfo) + if (pSpellInfo && + pSpellInfo->aLastSpellPortions.size() > 0) // no portions -> no text to be changed { // get current paragraph length to calculate later on how the sentence length changed, // in order to place the cursor at the end of the sentence again @@ -2202,6 +2214,10 @@ void ImpEditEngine::ApplyChangedSentence(EditView& rEditView, UndoActionStart( EDITUNDO_INSERT ); if(pSpellInfo->aLastSpellPortions.size() == rNewPortions.size()) { + DBG_ASSERT( rNewPortions.size() > 0, "rNewPortions should not be empty here" ); + DBG_ASSERT( pSpellInfo->aLastSpellPortions.size() == pSpellInfo->aLastSpellContentSelections.size(), + "aLastSpellPortions and aLastSpellContentSelections size mismatch" ); + //the simple case: the same number of elements on both sides //each changed element has to be applied to the corresponding source element svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.end(); @@ -2252,6 +2268,8 @@ void ImpEditEngine::ApplyChangedSentence(EditView& rEditView, } else { + DBG_ASSERT( pSpellInfo->aLastSpellContentSelections.size() > 0, "aLastSpellContentSelections should not be empty here" ); + //select the complete sentence SpellContentSelections::const_iterator aCurrentEndPosition = pSpellInfo->aLastSpellContentSelections.end(); --aCurrentEndPosition; @@ -2798,8 +2816,23 @@ void ImpEditEngine::SetAutoCompleteText( const String& rStr, sal_Bool bClearTipW #endif // !SVX_LIGHT } + +struct TransliterationChgData +{ + USHORT nStart; + xub_StrLen nLen; + EditSelection aSelection; + String aNewText; + uno::Sequence< sal_Int32 > aOffsets; +}; + + EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection, sal_Int32 nTransliterationMode ) { + uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() ); + if (!_xBI.is()) + return rSelection; + EditSelection aSel( rSelection ); aSel.Adjust( aEditDoc ); @@ -2808,8 +2841,8 @@ EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection, EditSelection aNewSel( aSel ); - USHORT nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() ); - USHORT nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() ); + const USHORT nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() ); + const USHORT nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() ); BOOL bChanges = FALSE; BOOL bLenChanged = FALSE; @@ -2832,83 +2865,266 @@ EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection, USHORT nCurrentEnd = nEndPos; sal_uInt16 nLanguage = LANGUAGE_SYSTEM; - do - { - if ( bConsiderLanguage ) + // since we don't use Hiragana/Katakana or half-width/full-width transliterations here + // it is fine to use ANYWORD_IGNOREWHITESPACES. (ANY_WORD btw is broken and will + // occasionaly miss words in consecutive sentences). Also with ANYWORD_IGNOREWHITESPACES + // text like 'just-in-time' will be converted to 'Just-In-Time' which seems to be the + // proper thing to do. + const sal_Int16 nWordType = i18n::WordType::ANYWORD_IGNOREWHITESPACES; + + //! In order to have less trouble with changing text size, e.g. because + //! of ligatures or � (German small sz) being resolved, we need to process + //! the text replacements from end to start. + //! This way the offsets for the yet to be changed words will be + //! left unchanged by the already replaced text. + //! For this we temporarily save the changes to be done in this vector + std::vector< TransliterationChgData > aChanges; + TransliterationChgData aChgData; + + if (nTransliterationMode == i18n::TransliterationModulesExtra::TITLE_CASE) + { + // for 'capitalize every word' we need to iterate over each word + + i18n::Boundary aSttBndry; + i18n::Boundary aEndBndry; + aSttBndry = _xBI->getWordBoundary( + *pNode, nStartPos, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nStartPos + 1 ) ) ), + nWordType, TRUE /*prefer forward direction*/); + aEndBndry = _xBI->getWordBoundary( + *pNode, nEndPos, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nEndPos + 1 ) ) ), + nWordType, FALSE /*prefer backward direction*/); + + // prevent backtracking to the previous word if selection is at word boundary + if (aSttBndry.endPos <= nStartPos) + { + aSttBndry = _xBI->nextWord( + *pNode, aSttBndry.endPos, + SvxCreateLocale( GetLanguage( EditPaM( pNode, aSttBndry.endPos + 1 ) ) ), + nWordType); + } + // prevent advancing to the next word if selection is at word boundary + if (aEndBndry.startPos >= nEndPos) { - nLanguage = GetLanguage( EditPaM( pNode, nCurrentStart+1 ), &nCurrentEnd ); - if ( nCurrentEnd > nEndPos ) - nCurrentEnd = nEndPos; + aEndBndry = _xBI->previousWord( + *pNode, aEndBndry.startPos, + SvxCreateLocale( GetLanguage( EditPaM( pNode, aEndBndry.startPos + 1 ) ) ), + nWordType); } - xub_StrLen nLen = nCurrentEnd - nCurrentStart; + i18n::Boundary aCurWordBndry( aSttBndry ); + while (aCurWordBndry.startPos <= aEndBndry.startPos) + { + nCurrentStart = (xub_StrLen)aCurWordBndry.startPos; + nCurrentEnd = (xub_StrLen)aCurWordBndry.endPos; + sal_Int32 nLen = nCurrentEnd - nCurrentStart; + DBG_ASSERT( nLen > 0, "invalid word length of 0" ); +#if OSL_DEBUG_LEVEL > 1 + String aText( pNode->Copy( nCurrentStart, nLen ) ); +#endif + + Sequence< sal_Int32 > aOffsets; + String aNewText( aTranslitarationWrapper.transliterate( *pNode, + GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ), + nCurrentStart, nLen, &aOffsets )); - Sequence <sal_Int32> aOffsets; - String aNewText( aTranslitarationWrapper.transliterate( *pNode, nLanguage, nCurrentStart, nLen, &aOffsets ) ); + if (!pNode->Equals( aNewText, nCurrentStart, nLen )) + { + aChgData.nStart = nCurrentStart; + aChgData.nLen = nLen; + aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) ); + aChgData.aNewText = aNewText; + aChgData.aOffsets = aOffsets; + aChanges.push_back( aChgData ); + } +#if OSL_DEBUG_LEVEL > 1 + String aSelTxt ( GetSelected( aChgData.aSelection ) ); + (void) aSelTxt; +#endif - if( ( nLen != aNewText.Len() ) || !pNode->Equals( aNewText, nCurrentStart, nLen ) ) + aCurWordBndry = _xBI->nextWord( *pNode, nCurrentEnd, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentEnd + 1 ) ) ), + nWordType); + } + DBG_ASSERT( nCurrentEnd >= aEndBndry.endPos, "failed to reach end of transliteration" ); + } + else if (nTransliterationMode == i18n::TransliterationModulesExtra::SENTENCE_CASE) + { + // for 'sentence case' we need to iterate sentence by sentence + + sal_Int32 nLastStart = _xBI->beginOfSentence( + *pNode, nEndPos, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nEndPos + 1 ) ) ) ); + sal_Int32 nLastEnd = _xBI->endOfSentence( + *pNode, nLastStart, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nLastStart + 1 ) ) ) ); + + // extend nCurrentStart, nCurrentEnd to the current sentence boundaries + nCurrentStart = _xBI->beginOfSentence( + *pNode, nStartPos, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nStartPos + 1 ) ) ) ); + nCurrentEnd = _xBI->endOfSentence( + *pNode, nCurrentStart, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ) ) ); + + // prevent backtracking to the previous sentence if selection starts at end of a sentence + if (nCurrentEnd <= nStartPos) { - bChanges = TRUE; - if ( nLen != aNewText.Len() ) - bLenChanged = TRUE; + // now nCurrentStart is probably located on a non-letter word. (unless we + // are in Asian text with no spaces...) + // Thus to get the real sentence start we should locate the next real word, + // that is one found by DICTIONARY_WORD + i18n::Boundary aBndry = _xBI->nextWord( *pNode, nCurrentEnd, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentEnd + 1 ) ) ), + i18n::WordType::DICTIONARY_WORD); + + // now get new current sentence boundaries + nCurrentStart = _xBI->beginOfSentence( + *pNode, aBndry.startPos, + SvxCreateLocale( GetLanguage( EditPaM( pNode, aBndry.startPos + 1 ) ) ) ); + nCurrentEnd = _xBI->endOfSentence( + *pNode, nCurrentStart, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ) ) ); + } + // prevent advancing to the next sentence if selection ends at start of a sentence + if (nLastStart >= nEndPos) + { + // now nCurrentStart is probably located on a non-letter word. (unless we + // are in Asian text with no spaces...) + // Thus to get the real sentence start we should locate the previous real word, + // that is one found by DICTIONARY_WORD + i18n::Boundary aBndry = _xBI->previousWord( *pNode, nLastStart, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nLastStart + 1 ) ) ), + i18n::WordType::DICTIONARY_WORD); + nLastEnd = _xBI->endOfSentence( + *pNode, aBndry.startPos, + SvxCreateLocale( GetLanguage( EditPaM( pNode, aBndry.startPos + 1 ) ) ) ); + if (nCurrentEnd > nLastEnd) + nCurrentEnd = nLastEnd; + } -#ifndef SVX_LIGHT - // Create UndoAction on Demand.... - if ( !pUndo && IsUndoEnabled() && !IsInUndo() ) - { - ESelection aESel( CreateESel( aSel ) ); - pUndo = new EditUndoTransliteration( this, aESel, nTransliterationMode ); + while (nCurrentStart < nLastEnd) + { + sal_Int32 nLen = nCurrentEnd - nCurrentStart; + DBG_ASSERT( nLen > 0, "invalid word length of 0" ); +#if OSL_DEBUG_LEVEL > 1 + String aText( pNode->Copy( nCurrentStart, nLen ) ); +#endif - if ( ( nStartNode == nEndNode ) && !aSel.Min().GetNode()->GetCharAttribs().HasAttrib( aSel.Min().GetIndex(), aSel.Max().GetIndex() ) ) - pUndo->SetText( aSel.Min().GetNode()->Copy( aSel.Min().GetIndex(), aSel.Max().GetIndex()-aSel.Min().GetIndex() ) ); - else - pUndo->SetText( CreateBinTextObject( aSel, NULL ) ); + Sequence< sal_Int32 > aOffsets; + String aNewText( aTranslitarationWrapper.transliterate( *pNode, + GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ), + nCurrentStart, nLen, &aOffsets )); + + if (!pNode->Equals( aNewText, nCurrentStart, nLen )) + { + aChgData.nStart = nCurrentStart; + aChgData.nLen = nLen; + aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) ); + aChgData.aNewText = aNewText; + aChgData.aOffsets = aOffsets; + aChanges.push_back( aChgData ); } -#endif - // Change text without loosing the attributes - USHORT nCharsAfterTransliteration = - sal::static_int_cast< USHORT >(aOffsets.getLength()); - const sal_Int32* pOffsets = aOffsets.getConstArray(); - short nDiffs = 0; - for ( USHORT n = 0; n < nCharsAfterTransliteration; n++ ) + i18n::Boundary aFirstWordBndry; + aFirstWordBndry = _xBI->nextWord( + *pNode, nCurrentEnd, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentEnd + 1 ) ) ), + nWordType); + nCurrentStart = aFirstWordBndry.startPos; + nCurrentEnd = _xBI->endOfSentence( + *pNode, nCurrentStart, + SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ) ) ); + } + DBG_ASSERT( nCurrentEnd >= nLastEnd, "failed to reach end of transliteration" ); + } + else + { + do + { + if ( bConsiderLanguage ) { - USHORT nCurrentPos = nCurrentStart+n; - sal_Int32 nDiff = (nCurrentPos-nDiffs) - pOffsets[n]; + nLanguage = GetLanguage( EditPaM( pNode, nCurrentStart+1 ), &nCurrentEnd ); + if ( nCurrentEnd > nEndPos ) + nCurrentEnd = nEndPos; + } - if ( !nDiff ) - { - DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" ); - pNode->SetChar( nCurrentPos, aNewText.GetChar(n) ); - } - else if ( nDiff < 0 ) - { - // Replace first char, delete the rest... - DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" ); - pNode->SetChar( nCurrentPos, aNewText.GetChar(n) ); + xub_StrLen nLen = nCurrentEnd - nCurrentStart; - DBG_ASSERT( (nCurrentPos+1) < pNode->Len(), "TransliterateText - String smaller than expected!" ); - GetEditDoc().RemoveChars( EditPaM( pNode, nCurrentPos+1 ), sal::static_int_cast< USHORT >(-nDiff) ); - } - else - { - DBG_ASSERT( nDiff == 1, "TransliterateText - Diff other than expected! But should work..." ); - GetEditDoc().InsertText( EditPaM( pNode, nCurrentPos ), aNewText.GetChar(n) ); + Sequence< sal_Int32 > aOffsets; + String aNewText( aTranslitarationWrapper.transliterate( *pNode, nLanguage, nCurrentStart, nLen, &aOffsets ) ); - } - nDiffs = sal::static_int_cast< short >(nDiffs + nDiff); + if (!pNode->Equals( aNewText, nCurrentStart, nLen )) + { + aChgData.nStart = nCurrentStart; + aChgData.nLen = nLen; + aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) ); + aChgData.aNewText = aNewText; + aChgData.aOffsets = aOffsets; + aChanges.push_back( aChgData ); } - if ( nNode == nEndNode ) - aNewSel.Max().GetIndex() = - aNewSel.Max().GetIndex() + nDiffs; + nCurrentStart = nCurrentEnd; + } while( nCurrentEnd < nEndPos ); + } + + if (aChanges.size() > 0) + { +#ifndef SVX_LIGHT + // Create a single UndoAction on Demand for all the changes ... + if ( !pUndo && IsUndoEnabled() && !IsInUndo() ) + { + // adjust selection to include all changes + for (size_t i = 0; i < aChanges.size(); ++i) + { + const EditSelection &rSel = aChanges[i].aSelection; + if (aSel.Min().GetNode() == rSel.Min().GetNode() && + aSel.Min().GetIndex() > rSel.Min().GetIndex()) + aSel.Min().SetIndex( rSel.Min().GetIndex() ); + if (aSel.Max().GetNode() == rSel.Max().GetNode() && + aSel.Max().GetIndex() < rSel.Max().GetIndex()) + aSel.Max().SetIndex( rSel.Max().GetIndex() ); + } + aNewSel = aSel; + + ESelection aESel( CreateESel( aSel ) ); + pUndo = new EditUndoTransliteration( this, aESel, nTransliterationMode ); + + const bool bSingleNode = aSel.Min().GetNode()== aSel.Max().GetNode(); + const bool bHasAttribs = aSel.Min().GetNode()->GetCharAttribs().HasAttrib( aSel.Min().GetIndex(), aSel.Max().GetIndex() ); + if (bSingleNode && !bHasAttribs) + pUndo->SetText( aSel.Min().GetNode()->Copy( aSel.Min().GetIndex(), aSel.Max().GetIndex()-aSel.Min().GetIndex() ) ); + else + pUndo->SetText( CreateBinTextObject( aSel, NULL ) ); + } +#endif - ParaPortion* pParaPortion = GetParaPortions()[nNode]; - pParaPortion->MarkSelectionInvalid( nCurrentStart, std::max< USHORT >( nCurrentStart+nLen, nCurrentStart+aNewText.Len() ) ); + // now apply the changes from end to start to leave the offsets of the + // yet unchanged text parts remain the same. + for (size_t i = 0; i < aChanges.size(); ++i) + { + const TransliterationChgData &rData = aChanges[ aChanges.size() - 1 - i ]; + + bChanges = TRUE; + if (rData.nLen != rData.aNewText.Len()) + bLenChanged = TRUE; + // Change text without loosing the attributes + USHORT nDiffs = ReplaceTextOnly( rData.aSelection.Min().GetNode(), + rData.nStart, rData.nLen, rData.aNewText, rData.aOffsets ); + + // adjust selection in end node to possibly changed size + if (aSel.Max().GetNode() == rData.aSelection.Max().GetNode()) + aNewSel.Max().GetIndex() = aNewSel.Max().GetIndex() + nDiffs; + + USHORT nSelNode = aEditDoc.GetPos( rData.aSelection.Min().GetNode() ); + ParaPortion* pParaPortion = GetParaPortions()[nSelNode]; + pParaPortion->MarkSelectionInvalid( rData.nStart, + std::max< USHORT >( rData.nStart + rData.nLen, + rData.nStart + rData.aNewText.Len() ) ); } - nCurrentStart = nCurrentEnd; - } while( nCurrentEnd < nEndPos ); + } // if (aChanges.size() > 0) } #ifndef SVX_LIGHT @@ -2932,6 +3148,52 @@ EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection, return aNewSel; } + +short ImpEditEngine::ReplaceTextOnly( + ContentNode* pNode, + USHORT nCurrentStart, xub_StrLen nLen, + const String& rNewText, + const uno::Sequence< sal_Int32 >& rOffsets ) +{ + (void) nLen; + + // Change text without loosing the attributes + USHORT nCharsAfterTransliteration = + sal::static_int_cast< USHORT >(rOffsets.getLength()); + const sal_Int32* pOffsets = rOffsets.getConstArray(); + short nDiffs = 0; + for ( USHORT n = 0; n < nCharsAfterTransliteration; n++ ) + { + USHORT nCurrentPos = nCurrentStart+n; + sal_Int32 nDiff = (nCurrentPos-nDiffs) - pOffsets[n]; + + if ( !nDiff ) + { + DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" ); + pNode->SetChar( nCurrentPos, rNewText.GetChar(n) ); + } + else if ( nDiff < 0 ) + { + // Replace first char, delete the rest... + DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" ); + pNode->SetChar( nCurrentPos, rNewText.GetChar(n) ); + + DBG_ASSERT( (nCurrentPos+1) < pNode->Len(), "TransliterateText - String smaller than expected!" ); + GetEditDoc().RemoveChars( EditPaM( pNode, nCurrentPos+1 ), sal::static_int_cast< USHORT >(-nDiff) ); + } + else + { + DBG_ASSERT( nDiff == 1, "TransliterateText - Diff other than expected! But should work..." ); + GetEditDoc().InsertText( EditPaM( pNode, nCurrentPos ), rNewText.GetChar(n) ); + + } + nDiffs = sal::static_int_cast< short >(nDiffs + nDiff); + } + + return nDiffs; +} + + void ImpEditEngine::SetAsianCompressionMode( USHORT n ) { if ( n != nAsianCompressionMode ) diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx index 64343517c69f..f969a8033f08 100644 --- a/editeng/source/misc/svxacorr.cxx +++ b/editeng/source/misc/svxacorr.cxx @@ -1243,27 +1243,25 @@ ULONG SvxAutoCorrect::AutoCorrect( SvxAutoCorrDoc& rDoc, const String& rTxt, else if ( bIsNextRun && !IsAutoCorrectChar( cChar ) ) { // Remove the NBSP if it wasn't an autocorrection - if ( NeedsHardspaceAutocorr( rTxt.GetChar( nInsPos - 1 ) ) && + if ( nInsPos != 0 && NeedsHardspaceAutocorr( rTxt.GetChar( nInsPos - 1 ) ) && cChar != ' ' && cChar != '\t' && cChar != CHAR_HARDBLANK ) { // Look for the last HARD_SPACE xub_StrLen nPos = nInsPos - 1; - bool bFound = false; - while ( nPos != STRING_NOTFOUND && !bFound ) + bool bContinue = true; + while ( bContinue ) { - sal_Unicode cTmpChar = rTxt.GetChar( nPos ); + const sal_Unicode cTmpChar = rTxt.GetChar( nPos ); if ( cTmpChar == CHAR_HARDBLANK ) - bFound = true; - else if ( !NeedsHardspaceAutocorr( cTmpChar ) ) - nPos = STRING_NOTFOUND; + { + rDoc.Delete( nPos, nPos + 1 ); + nRet = AddNonBrkSpace; + bContinue = false; + } + else if ( !NeedsHardspaceAutocorr( cTmpChar ) || nPos == 0 ) + bContinue = false; nPos--; } - - if ( bFound && nPos != STRING_NOTFOUND ) - { - rDoc.Delete( nPos + 1, nPos + 2 ); - nRet = AddNonBrkSpace; - } } } } diff --git a/formula/inc/formula/errorcodes.hxx b/formula/inc/formula/errorcodes.hxx index f9b04e012fab..f08af17e095e 100644 --- a/formula/inc/formula/errorcodes.hxx +++ b/formula/inc/formula/errorcodes.hxx @@ -64,7 +64,8 @@ const USHORT errInterpOverflow = 527; // Not displayed, temporary for TrackFormulas, // Cell depends on another cell that has errCircularReference const USHORT errTrackFromCircRef = 528; -// Interpreter internal: existing cell has no value but value queried +// ScInterpreter internal: no numeric value but numeric queried. If this is +// set as mnStringNoValueError no error is generated but 0 returned. const USHORT errCellNoValue = 529; // Interpreter: needed AddIn not found const USHORT errNoAddin = 530; @@ -74,6 +75,11 @@ const USHORT errNoMacro = 531; const USHORT errDivisionByZero = 532; // #DIV/0! // Compiler: a non-simple (str,err,val) value was put in an array const USHORT errNestedArray = 533; +// ScInterpreter internal: no numeric value but numeric queried. If this is +// temporarily (!) set as mnStringNoValueError, the error is generated and can +// be used to distinguish that condition from all other (inherited) errors. Do +// not use for anything else! Never push or inherit the error otherwise! +const USHORT errNotNumericString = 534; // Interpreter: NA() not available condition, not a real error const USHORT NOTAVAILABLE = 0x7fff; diff --git a/framework/source/accelerators/acceleratorconfiguration.cxx b/framework/source/accelerators/acceleratorconfiguration.cxx index 15070eed7c98..b81ef5aecf0e 100644 --- a/framework/source/accelerators/acceleratorconfiguration.cxx +++ b/framework/source/accelerators/acceleratorconfiguration.cxx @@ -96,6 +96,8 @@ #include <svtools/acceleratorexecute.hxx> +#include <stdio.h> + //_______________________________________________ // const @@ -1248,7 +1250,6 @@ void SAL_CALL XCUBasedAcceleratorConfiguration::changesOccurred(const css::util: const sal_Int32 c = aEvent.Changes.getLength(); sal_Int32 i = 0; - for (i=0; i<c; ++i) { const css::util::ElementChange& aChange = aEvent.Changes[i]; @@ -1264,27 +1265,25 @@ void SAL_CALL XCUBasedAcceleratorConfiguration::changesOccurred(const css::util: aChange.Accessor >>= sOrgPath; sPath = sOrgPath; - ::rtl::OUString sPrimarySecondary = ::utl::extractFirstFromConfigurationPath(sPath); - sPath = ::utl::dropPrefixFromConfigurationPath(sPath, sPrimarySecondary); - - ::rtl::OUString sGlobalModules = ::utl::extractFirstFromConfigurationPath(sPath); - sPath = ::utl::dropPrefixFromConfigurationPath(sPath, sGlobalModules); + ::rtl::OUString sPrimarySecondary = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); + ::rtl::OUString sGlobalModules = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) ) { ::rtl::OUString sModule; - sKey = ::utl::extractFirstFromConfigurationPath(sPath); - if ( sKey.getLength() ) + sKey = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); + if (( sKey.getLength() > 0 ) && ( sPath.getLength() > 0 )) reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey); } else if ( sGlobalModules.equals(CFG_ENTRY_MODULES) ) { - ::rtl::OUString sModule = ::utl::extractFirstFromConfigurationPath(sPath); - ::rtl::OUString sDropModule = ::rtl::OUString::createFromAscii("Module['") + sModule + ::rtl::OUString::createFromAscii("']"); - sPath = ::utl::dropPrefixFromConfigurationPath(sPath, sDropModule); - sKey = ::utl::extractFirstFromConfigurationPath(sPath); - if ( sKey.getLength() ) + ::rtl::OUString sModule = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); + sKey = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); + + if (( sKey.getLength() > 0 ) && ( sPath.getLength() > 0 )) + { reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey); + } } } } @@ -1385,8 +1384,8 @@ void XCUBasedAcceleratorConfiguration::impl_ts_load( sal_Bool bPreferred, const aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1; else if (sToken[k].equalsAscii("MOD2")) aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2; - else if (sToken[k].equalsAscii("MOD3")) - aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3; + else if (sToken[k].equalsAscii("MOD3")) + aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3; else { bValid = sal_False; diff --git a/officecfg/registry/data/org/openoffice/Office/Math.xcu b/officecfg/registry/data/org/openoffice/Office/Math.xcu index 6778873e3386..b65c2422c433 100644..100755 --- a/officecfg/registry/data/org/openoffice/Office/Math.xcu +++ b/officecfg/registry/data/org/openoffice/Office/Math.xcu @@ -48,6 +48,8 @@ <value>0</value> </prop> </node> + + <!-- only used for symbols with the 'Greek' symbol set name --> <node oor:name="Id2" oor:op="replace"> <prop oor:name="Name"> <value>OpenSymbol</value> @@ -65,10 +67,11 @@ <value>0</value> </prop> <prop oor:name="Italic"> - <value>2</value> + <value>0</value> </prop> </node> </node> + <node oor:name="SymbolList"> <node oor:name="alpha" oor:op="replace"> <prop oor:name="Char"> diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu index 33e5109405d0..5c72d948436f 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE oor:component-data SYSTEM "../../../../../component-update.dtd"> <oor:component-data oor:name="CalcCommands" oor:package="org.openoffice.Office.UI" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <node oor:name="UserInterface"> @@ -160,6 +160,14 @@ <value xml:lang="en-US">~Select...</value> </prop> </node> + <node oor:name=".uno:TableEvents" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Sheet ~Events...</value> + </prop> + <prop oor:name="ContextLabel" oor:type="xs:string"> + <value xml:lang="en-US">~Events...</value> + </prop> + </node> <node oor:name=".uno:DataPilotFilter" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">DataPilot Filter</value> diff --git a/officecfg/registry/schema/org/openoffice/Office/Math.xcs b/officecfg/registry/schema/org/openoffice/Office/Math.xcs index caa8726b7c72..31f6e00a230a 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Math.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Math.xcs @@ -402,7 +402,28 @@ </info> <value>false</value> </prop> - <prop oor:name="ScaleNormalBracket" oor:type="xs:boolean"> + <prop oor:name="GreekCharStyle" oor:type="xs:short"> + <!-- UIHints: n/a yet --> + <info> + <author>TL</author> + <desc>Specifies the default layout for symbols from the 'Greek' symbol set.</desc> + <label>Greek character style</label> + </info> + <constraints> + <minInclusive oor:value="0"> + <info> + <desc>Specifies the minimum value allowed</desc> + </info> + </minInclusive> + <maxInclusive oor:value="2"> + <info> + <desc>Specifies the maximum value allowed</desc> + </info> + </maxInclusive> + </constraints> + <value>0</value> + </prop> + <prop oor:name="ScaleNormalBracket" oor:type="xs:boolean"> <!-- OldPath: Math/StandardFormat --> <!-- OldLocation: Soffice.cfg --> <!-- UIHints: Format - Spacing - Category - Brackets - Scale all brackets --> diff --git a/officecfg/registry/schema/org/openoffice/Office/OOoImprovement/Settings.xcs b/officecfg/registry/schema/org/openoffice/Office/OOoImprovement/Settings.xcs index 7b0b221f15a9..7ff91464727d 100755 --- a/officecfg/registry/schema/org/openoffice/Office/OOoImprovement/Settings.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/OOoImprovement/Settings.xcs @@ -15,7 +15,7 @@ OpenOffice.org Improvement Program. If this is zero the user will get asked. </desc> </info> - <value>2</value> + <value>1</value> </prop> <prop oor:name="InvitationAccepted" oor:type="xs:boolean"> <info> diff --git a/oovbaapi/ooo/vba/XApplicationBase.idl b/oovbaapi/ooo/vba/XApplicationBase.idl index 7f59ddb75247..d9d32e02f2ce 100644 --- a/oovbaapi/ooo/vba/XApplicationBase.idl +++ b/oovbaapi/ooo/vba/XApplicationBase.idl @@ -24,21 +24,15 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef __ooo_vba_XApplicationBase_idl__ #define __ooo_vba_XApplicationBase_idl__ -#ifndef __com_sun_star_uno_XInterface_idl__ -#include <com/sun/star/uno/XInterface.idl> -#endif - -#ifndef __ooo_vba_XHelperInterface_idl__ #include <ooo/vba/XHelperInterface.idl> -#endif module ooo { module vba { -//============================================================================= - +//============================================================================= interface XApplicationBase { @@ -47,8 +41,9 @@ interface XApplicationBase [attribute] boolean ScreenUpdating; [attribute] boolean DisplayStatusBar; [attribute] boolean Interactive; + [attribute] boolean Visible; + [attribute, readonly] string Version; - //mbn [attribute, readonly] any VBE; [attribute, readonly] any VBProjects; @@ -61,6 +56,8 @@ interface XApplicationBase void Undo(); }; +//============================================================================= + }; }; #endif diff --git a/oovbaapi/ooo/vba/excel/XApplication.idl b/oovbaapi/ooo/vba/excel/XApplication.idl index 39693a37511c..6f513ae64577 100644 --- a/oovbaapi/ooo/vba/excel/XApplication.idl +++ b/oovbaapi/ooo/vba/excel/XApplication.idl @@ -64,6 +64,7 @@ interface XApplication [attribute] any CutCopyMode; [attribute] any StatusBar; [attribute] long Cursor; + [attribute] boolean EnableEvents; void setDefaultFilePath([in] string DefaultFilePath) raises(com::sun::star::script::BasicErrorException); diff --git a/oovbaapi/ooo/vba/excel/XGlobals.idl b/oovbaapi/ooo/vba/excel/XGlobals.idl index 6ed51b2aa4c4..d79196b00927 100644 --- a/oovbaapi/ooo/vba/excel/XGlobals.idl +++ b/oovbaapi/ooo/vba/excel/XGlobals.idl @@ -42,6 +42,10 @@ #ifndef __ooo_vba_XAssistant_idl__ #include <ooo/vba/XAssistant.idl> #endif +#ifndef __ooo_vba_excel_XApplication_idl__ +#include <ooo/vba/excel/XApplication.idl> +#endif + module ooo { module vba { module excel { interface XRange; @@ -55,6 +59,9 @@ interface XGlobals: com::sun::star::uno::XInterface [attribute, readonly] ooo::vba::XAssistant Assistant; [attribute, readonly] any Selection; [attribute, readonly] XWorkbook ThisWorkbook; + [attribute, readonly] ooo::vba::excel::XApplication Excel; + [attribute, readonly] any Debug; + void Calculate() raises(com::sun::star::script::BasicErrorException); XRange Cells([in] any RowIndex, [in] any ColumnIndex); diff --git a/oovbaapi/ooo/vba/excel/XWorksheet.idl b/oovbaapi/ooo/vba/excel/XWorksheet.idl index 271cd81d4d0e..3eb8337798d6 100644 --- a/oovbaapi/ooo/vba/excel/XWorksheet.idl +++ b/oovbaapi/ooo/vba/excel/XWorksheet.idl @@ -66,12 +66,14 @@ interface XWorksheet [attribute, readonly] boolean ProtectionMode; [attribute, readonly] boolean ProtectContents; [attribute, readonly] boolean ProtectDrawingObjects; + [attribute, readonly] boolean ProtectScenarios; [attribute, readonly] XRange UsedRange; [attribute, readonly] XWorksheet Next; [attribute, readonly] XWorksheet Previous; [attribute, readonly] string CodeName; [attribute, readonly] short Index; [attribute] long EnableSelection; + [attribute] boolean AutoFilterMode; void Activate(); void Calculate( ); @@ -114,6 +116,7 @@ interface XWorksheet XRange Rows([in] any aIndex); XRange Columns([in] any aIndex); any Hyperlinks( [in] any aIndex ); + any Names( [in] any Index ); any Evaluate( [in] string Name); diff --git a/oovbaapi/ooo/vba/excel/makefile.mk b/oovbaapi/ooo/vba/excel/makefile.mk index 12dcf025e489..251588086701 100644 --- a/oovbaapi/ooo/vba/excel/makefile.mk +++ b/oovbaapi/ooo/vba/excel/makefile.mk @@ -29,7 +29,7 @@ PRJ=..$/..$/.. PRJNAME=oovapi TARGET=excel -PACKAGE=ooo$/vba$/Excel +PACKAGE=ooo$/vba$/excel # --- Settings ----------------------------------------------------- .INCLUDE : $(PRJ)$/util$/makefile.pmk diff --git a/oovbaapi/ooo/vba/makefile.mk b/oovbaapi/ooo/vba/makefile.mk index 75f6465bf4c0..4f6d378cfe3f 100644 --- a/oovbaapi/ooo/vba/makefile.mk +++ b/oovbaapi/ooo/vba/makefile.mk @@ -61,9 +61,8 @@ IDLFILES=\ XFontBase.idl\ XDialogsBase.idl\ XDialogBase.idl\ - XPageSetupBase.idl \ - XVBAAppService.idl\ - XVBADocService.idl\ + XPageSetupBase.idl + # ------------------------------------------------------------------ .ENDIF .INCLUDE : target.mk diff --git a/oovbaapi/ooo/vba/word/makefile.mk b/oovbaapi/ooo/vba/word/makefile.mk index e3a19e678414..543e99f7c538 100644 --- a/oovbaapi/ooo/vba/word/makefile.mk +++ b/oovbaapi/ooo/vba/word/makefile.mk @@ -29,7 +29,7 @@ PRJ=..$/..$/.. PRJNAME=oovapi TARGET=word -PACKAGE=ooo$/vba$/Word +PACKAGE=ooo$/vba$/word # --- Settings ----------------------------------------------------- .INCLUDE : $(PRJ)$/util$/makefile.pmk diff --git a/oovbaapi/prj/d.lst b/oovbaapi/prj/d.lst index ac5924e2d684..86e801a15d93 100644 --- a/oovbaapi/prj/d.lst +++ b/oovbaapi/prj/d.lst @@ -8,7 +8,7 @@ mkdir: %COMMON_DEST%\idl%_EXT%\ooo\vba\word ..\%__SRC%\ucr\oovbaapi.db %_DEST%\bin%_EXT%\oovbaapi.rdb -..\ooo\vba\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\ +..\ooo\vba\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba ..\ooo\vba\constants\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\constants ..\ooo\vba\excel\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\excel ..\ooo\vba\msforms\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\msforms diff --git a/scripting/source/basprov/basmodnode.cxx b/scripting/source/basprov/basmodnode.cxx index 22f9e40571a4..fe6ed69fccab 100644 --- a/scripting/source/basprov/basmodnode.cxx +++ b/scripting/source/basprov/basmodnode.cxx @@ -97,14 +97,22 @@ namespace basprov if ( pMethods ) { sal_Int32 nCount = pMethods->Count(); - aChildNodes.realloc( nCount ); + sal_Int32 nRealCount = 0; + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Get( static_cast< USHORT >( i ) ) ); + if ( pMethod && !pMethod->IsHidden() ) + ++nRealCount; + } + aChildNodes.realloc( nRealCount ); Reference< browse::XBrowseNode >* pChildNodes = aChildNodes.getArray(); + sal_Int32 iTarget = 0; for ( sal_Int32 i = 0; i < nCount; ++i ) { SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Get( static_cast< USHORT >( i ) ) ); - if ( pMethod ) - pChildNodes[i] = static_cast< browse::XBrowseNode* >( new BasicMethodNodeImpl( m_xContext, m_sScriptingContext, pMethod, m_bIsAppScript ) ); + if ( pMethod && !pMethod->IsHidden() ) + pChildNodes[iTarget++] = static_cast< browse::XBrowseNode* >( new BasicMethodNodeImpl( m_xContext, m_sScriptingContext, pMethod, m_bIsAppScript ) ); } } } diff --git a/scripting/source/basprov/basprov.cxx b/scripting/source/basprov/basprov.cxx index abd61f6c1285..69cc6f40cd3d 100644 --- a/scripting/source/basprov/basprov.cxx +++ b/scripting/source/basprov/basprov.cxx @@ -412,7 +412,7 @@ namespace basprov if ( pMethods ) { SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Find( aMethod, SbxCLASS_METHOD ) ); - if ( pMethod ) + if ( pMethod && !pMethod->IsHidden() ) { if ( m_pDocBasicManager == pBasicMgr ) xScript = new BasicScriptImpl( aDescription, pMethod, *m_pDocBasicManager, m_xInvocationContext ); diff --git a/sfx2/inc/sfx2/objsh.hxx b/sfx2/inc/sfx2/objsh.hxx index 63eb9e8c876f..9473ac126bd7 100755..100644 --- a/sfx2/inc/sfx2/objsh.hxx +++ b/sfx2/inc/sfx2/objsh.hxx @@ -293,6 +293,7 @@ public: sal_Bool IsReadOnlyUI() const; void SetNoName(); sal_Bool IsInModalMode() const; + sal_Bool IsInPrepareClose() const; //<!--Added by PengYunQuan for Validity Cell Range Picker virtual sal_Bool AcceptStateUpdate() const; //-->Added by PengYunQuan for Validity Cell Range Picker @@ -346,6 +347,9 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage ); virtual void UpdateLinks(); + // called for a few slots like SID_SAVE[AS]DOC, SID_PRINTDOC[DIRECT], derived classes may abort the action + virtual sal_Bool QuerySlotExecutable( USHORT nSlotId ); + sal_Bool SaveChildren(BOOL bObjectsOnly=FALSE); sal_Bool SaveAsChildren( SfxMedium &rMedium ); sal_Bool SwitchChildrenPersistance( diff --git a/sfx2/source/dialog/securitypage.cxx b/sfx2/source/dialog/securitypage.cxx index d32ee843cbf2..2ac8f6a43fee 100755..100644 --- a/sfx2/source/dialog/securitypage.cxx +++ b/sfx2/source/dialog/securitypage.cxx @@ -245,6 +245,36 @@ SfxSecurityPage_Impl::SfxSecurityPage_Impl( SfxSecurityPage &rTabPage, const Sfx m_aRecordChangesCB.SetStyle( m_aRecordChangesCB.GetStyle() | WB_EARLYTOGGLE ); m_aRecordChangesCB.SetToggleHdl( LINK( this, SfxSecurityPage_Impl, RecordChangesCBToggleHdl ) ); m_aChangeProtectionPB.SetClickHdl( LINK( this, SfxSecurityPage_Impl, ChangeProtectionPBHdl ) ); + + + // #i112277: for the time being (OOO 3.3) the following options should not + // be available. In the long run however it is planned to implement the yet + // missing functionality. Thus now we hide them and move the remaining ones up. + m_aNewPasswordToOpenFL.Hide(); + m_aNewPasswordToOpenFT.Hide(); + m_aNewPasswordToOpenED.Hide(); + m_aConfirmPasswordToOpenFT.Hide(); + m_aConfirmPasswordToOpenED.Hide(); + m_aNewPasswordInfoFT.Hide(); + m_aNewPasswordToModifyFL.Hide(); + m_aNewPasswordToModifyFT.Hide(); + m_aNewPasswordToModifyED.Hide(); + m_aConfirmPasswordToModifyFT.Hide(); + m_aConfirmPasswordToModifyED.Hide(); + const long nDelta = m_aOptionsFL.GetPosPixel().Y() - m_aNewPasswordToOpenFL.GetPosPixel().Y(); + Point aPos; + aPos = m_aOptionsFL.GetPosPixel(); + aPos.Y() -= nDelta; + m_aOptionsFL.SetPosPixel( aPos ); + aPos = m_aOpenReadonlyCB.GetPosPixel(); + aPos.Y() -= nDelta; + m_aOpenReadonlyCB.SetPosPixel( aPos ); + aPos = m_aRecordChangesCB.GetPosPixel(); + aPos.Y() -= nDelta; + m_aRecordChangesCB.SetPosPixel( aPos ); + aPos = m_aChangeProtectionPB.GetPosPixel(); + aPos.Y() -= nDelta; + m_aChangeProtectionPB.SetPosPixel( aPos ); } diff --git a/sfx2/source/dialog/securitypage.src b/sfx2/source/dialog/securitypage.src index fee60404d01c..fee60404d01c 100755..100644 --- a/sfx2/source/dialog/securitypage.src +++ b/sfx2/source/dialog/securitypage.src diff --git a/sfx2/source/doc/DocumentMetadataAccess.cxx b/sfx2/source/doc/DocumentMetadataAccess.cxx index 9625ea958830..df0781be8877 100644 --- a/sfx2/source/doc/DocumentMetadataAccess.cxx +++ b/sfx2/source/doc/DocumentMetadataAccess.cxx @@ -45,6 +45,8 @@ #include <rtl/uuid.h> #include <rtl/ustrbuf.hxx> +#include <rtl/uri.hxx> +#include <rtl/bootstrap.hxx> #include <comphelper/interaction.hxx> #include <comphelper/makesequence.hxx> @@ -136,6 +138,24 @@ uno::Reference<rdf::XURI> createBaseURI( throw uno::RuntimeException(); } + // #i108078# workaround non-hierarchical vnd.sun.star.expand URIs + // this really should be done somewhere else, not here. + ::rtl::OUString pkgURI(i_rPkgURI); + if (pkgURI.matchIgnoreAsciiCaseAsciiL( + RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:"))) + { + // expand it here (makeAbsolute requires hierarchical URI) + pkgURI = pkgURI.copy( RTL_CONSTASCII_LENGTH("vnd.sun.star.expand:") ); + if (pkgURI.getLength() != 0) { + pkgURI = ::rtl::Uri::decode( + pkgURI, rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8); + if (pkgURI.getLength() == 0) { + throw uno::RuntimeException(); + } + ::rtl::Bootstrap::expandMacros(pkgURI); + } + } + const uno::Reference<lang::XMultiComponentFactory> xServiceFactory( i_xContext->getServiceManager(), uno::UNO_SET_THROW); const uno::Reference<uri::XUriReferenceFactory> xUriFactory( @@ -146,11 +166,12 @@ uno::Reference<rdf::XURI> createBaseURI( uno::Reference< uri::XUriReference > xBaseURI; const uno::Reference< uri::XUriReference > xPkgURI( - xUriFactory->parse(i_rPkgURI), uno::UNO_SET_THROW ); + xUriFactory->parse(pkgURI), uno::UNO_SET_THROW ); xPkgURI->clearFragment(); + // need to know whether the storage is a FileSystemStorage // XServiceInfo would be better, but it is not implemented -// if ( i_rPkgURI.getLength() && ::utl::UCBContentHelper::IsFolder(i_rPkgURI) ) +// if ( pkgURI.getLength() && ::utl::UCBContentHelper::IsFolder(pkgURI) ) if (true) { xBaseURI.set( xPkgURI, uno::UNO_SET_THROW ); #if 0 diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index c063546da1c7..066f366b09bd 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -489,6 +489,13 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) case SID_SAVEASDOC: case SID_SAVEDOC: { + // derived class may decide to abort this + if( !QuerySlotExecutable( nId ) ) + { + rReq.SetReturnValue( SfxBoolItem( 0, FALSE ) ); + return; + } + //!! detaillierte Auswertung eines Fehlercodes SfxObjectShellRef xLock( this ); @@ -895,7 +902,7 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) rReq.Done(); } -//-------------------------------------------------------------------- +//------------------------------------------------------------------------- void SfxObjectShell::GetState_Impl(SfxItemSet &rSet) { diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index bfe27ee71d97..e3b04f72caf7 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -195,6 +195,13 @@ sal_Bool SfxObjectShell::SaveAs( SfxMedium& rMedium ) //------------------------------------------------------------------------- +sal_Bool SfxObjectShell::QuerySlotExecutable( USHORT /*nSlotId*/ ) +{ + return sal_True; +} + +//------------------------------------------------------------------------- + sal_Bool GetPasswd_Impl( const SfxItemSet* pSet, ::rtl::OUString& rPasswd ) { const SfxPoolItem* pItem = NULL; diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx index f202266dd74e..b7567b89f02f 100755..100644 --- a/sfx2/source/doc/objxtor.cxx +++ b/sfx2/source/doc/objxtor.cxx @@ -526,6 +526,13 @@ SfxObjectShell* SfxObjectShell::Current() return pFrame ? pFrame->GetObjectShell() : 0; } +//------------------------------------------------------------------------- + +sal_Bool SfxObjectShell::IsInPrepareClose() const +{ + return pImp->bInPrepareClose; +} + //------------------------------------------------------------------------ struct BoolEnv_Impl diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index 9e9e09ebcdf5..fe4ffa50f67d 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -978,6 +978,8 @@ sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& aArgs.remove( "BreakMacroSignature" ); aArgs.remove( "Stream" ); aArgs.remove( "InputStream" ); + aArgs.remove( "URL" ); + aArgs.remove( "Frame" ); // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here @@ -989,6 +991,10 @@ sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& SfxAllItemSet aSet( pObjectShell->GetPool() ); TransformParameters( SID_OPENDOC, rArgs, aSet ); + // the arguments are not allowed to reach the medium + aSet.ClearItem( SID_FILE_NAME ); + aSet.ClearItem( SID_FILLFRAME ); + pMedium->GetItemSet()->Put( aSet ); SFX_ITEMSET_ARG( &aSet, pItem, SfxStringItem, SID_FILTER_NAME, sal_False ); if ( pItem ) diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 035fd3f794de..ed924623c700 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -813,6 +813,13 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) xNewObj->SetModifyPasswordEntered( sal_False ); xNewObj->SetReadOnly(); } + else if ( rReq.GetSlot() == SID_EDITDOC && bForEdit && !xNewObj->IsReadOnlyMedium() ) + { + // the filter might request setting of the document to readonly state + // but in case of SID_EDITDOC it should not happen if the document + // can be opened for editing + xNewObj->SetReadOnlyUI( sal_False ); + } if ( xNewObj->IsDocShared() ) { @@ -2144,6 +2151,8 @@ SfxViewShell* SfxViewFrame::LoadViewIntoFrame_Impl( const SfxObjectShell& i_rDoc aTransformLoadArgs.remove( "Hidden" ); ::rtl::OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "private:object" ) ); + if ( !sURL.getLength() ) + sURL = i_rDoc.GetFactory().GetFactoryURL(); Reference< XComponentLoader > xLoader( i_rFrame, UNO_QUERY_THROW ); xLoader->loadComponentFromURL( sURL, ::rtl::OUString::createFromAscii( "_self" ), 0, diff --git a/sfx2/source/view/viewprn.cxx b/sfx2/source/view/viewprn.cxx index 5b317e4b770b..4ed0173be8e1 100644 --- a/sfx2/source/view/viewprn.cxx +++ b/sfx2/source/view/viewprn.cxx @@ -700,6 +700,14 @@ void SfxViewShell::ExecPrint_Impl( SfxRequest &rReq ) case SID_PRINTDOCDIRECT: { SfxObjectShell* pDoc = GetObjectShell(); + + // derived class may decide to abort this + if( !pDoc->QuerySlotExecutable( nId ) ) + { + rReq.SetReturnValue( SfxBoolItem( 0, FALSE ) ); + return; + } + bool bDetectHidden = ( !bSilent && pDoc ); if ( bDetectHidden && pDoc->QueryHiddenInformation( WhenPrinting, NULL ) != RET_YES ) break; diff --git a/svx/inc/svx/dialogs.hrc b/svx/inc/svx/dialogs.hrc index d193652b57fc..fd7561bb7192 100755 --- a/svx/inc/svx/dialogs.hrc +++ b/svx/inc/svx/dialogs.hrc @@ -956,7 +956,9 @@ #define RID_SVXSTR_OUTLINENUM_DESCRIPTION_6 (RID_SVXSTR_OUTLINENUM_DESCRIPTIONS + 6)//? #define RID_SVXSTR_OUTLINENUM_DESCRIPTION_7 (RID_SVXSTR_OUTLINENUM_DESCRIPTIONS + 7)//? -#define RID_SVXSTR_NEXTFREE (RID_SVX_START + 1190) +#define RID_SVXSTR_FINDBAR_FIND (RID_SVX_START + 1190) + +#define RID_SVXSTR_NEXTFREE (RID_SVX_START + 1191) // ---------------------------------------------------------------------------- // if we have _a_lot_ time, we should group the resource ids by type, instead diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index fffcac00e46c..ee9e8f48634b 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -1063,8 +1063,7 @@ void SdrMarkView::AddDragModeHdl(SdrDragMode eMode) /** handle mouse over effects for handles */ BOOL SdrMarkView::MouseMove(const MouseEvent& rMEvt, Window* pWin) { - const ULONG nHdlCount = aHdl.GetHdlCount(); - if( nHdlCount ) + if(aHdl.GetHdlCount()) { SdrHdl* pMouseOverHdl = 0; if( !rMEvt.IsLeaveWindow() && pWin ) @@ -1074,6 +1073,8 @@ BOOL SdrMarkView::MouseMove(const MouseEvent& rMEvt, Window* pWin) } // notify last mouse over handle that he lost the mouse + const ULONG nHdlCount = aHdl.GetHdlCount(); + for(ULONG nHdl = 0; nHdl < nHdlCount; nHdl++ ) { SdrHdl* pCurrentHdl = GetHdl(nHdl); diff --git a/svx/source/tbxctrls/makefile.mk b/svx/source/tbxctrls/makefile.mk index 73a178d97594..a9ea745f3cc0 100644 --- a/svx/source/tbxctrls/makefile.mk +++ b/svx/source/tbxctrls/makefile.mk @@ -74,6 +74,7 @@ SRC1FILES = \ lboxctrl.src \ linectrl.src \ tbcontrl.src \ + tbunosearchcontrollers.src \ tbxdraw.src \ grafctrl.src diff --git a/svx/source/tbxctrls/tbunosearchcontrollers.cxx b/svx/source/tbxctrls/tbunosearchcontrollers.cxx index 5dcaf6fd5e72..e446d3d3b9d5 100644 --- a/svx/source/tbxctrls/tbunosearchcontrollers.cxx +++ b/svx/source/tbxctrls/tbunosearchcontrollers.cxx @@ -29,6 +29,8 @@ #include "precompiled_svx.hxx" #include "tbunosearchcontrollers.hxx" +#include <svx/dialogs.hrc> +#include <svx/dialmgr.hxx> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> @@ -91,7 +93,7 @@ FindTextFieldControl::~FindTextFieldControl() void FindTextFieldControl::InitControls_Impl() { - SetText( String( ::rtl::OUString::createFromAscii("Find") ) ); + SetText( SVX_RESSTR( RID_SVXSTR_FINDBAR_FIND ) ); SetControlForeground(GetSettings().GetStyleSettings().GetDisableColor()); EnableAutocomplete(TRUE, TRUE); @@ -174,7 +176,7 @@ long FindTextFieldControl::PreNotify( NotifyEvent& rNEvt ) case EVENT_LOSEFOCUS: if ( GetText().Len() == 0 ) { - SetText( String( ::rtl::OUString::createFromAscii("Find") ) ); + SetText( SVX_RESSTR( RID_SVXSTR_FINDBAR_FIND ) ); SetControlForeground(GetSettings().GetStyleSettings().GetDisableColor()); m_bToClearTextField = sal_True; } diff --git a/svx/source/tbxctrls/tbunosearchcontrollers.src b/svx/source/tbxctrls/tbunosearchcontrollers.src new file mode 100644 index 000000000000..9a256ae0cabb --- /dev/null +++ b/svx/source/tbxctrls/tbunosearchcontrollers.src @@ -0,0 +1,33 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <svx/dialogs.hrc> + +String RID_SVXSTR_FINDBAR_FIND +{ + Text [ en-US ] = "Find" ; +}; diff --git a/ucb/source/ucp/package/makefile.mk b/ucb/source/ucp/package/makefile.mk index 8c6dcda31829..a8cdf7430703 100644 --- a/ucb/source/ucp/package/makefile.mk +++ b/ucb/source/ucp/package/makefile.mk @@ -68,6 +68,7 @@ SHL1IMPLIB=i$(TARGET) SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1STDLIBS=\ + $(COMPHELPERLIB) \ $(CPPUHELPERLIB) \ $(CPPULIB) \ $(SALLIB) \ diff --git a/ucb/source/ucp/package/pkguri.cxx b/ucb/source/ucp/package/pkguri.cxx index feb8daec7905..8424ed906e92 100644 --- a/ucb/source/ucp/package/pkguri.cxx +++ b/ucb/source/ucp/package/pkguri.cxx @@ -36,6 +36,7 @@ #include "rtl/ustrbuf.hxx" #include "osl/diagnose.h" +#include "comphelper/storagehelper.hxx" #include "../inc/urihelper.hxx" @@ -85,7 +86,7 @@ void PackageUri::init() const if ( ( m_aUri.getLength() < PACKAGE_URL_SCHEME_LENGTH + 4 ) ) { // error, but remember that we did a init(). - m_aPath = rtl::OUString::createFromAscii( "/" ); + m_aPath = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); return; } @@ -100,7 +101,7 @@ void PackageUri::init() const != sal_Unicode( '/' ) ) ) { // error, but remember that we did a init(). - m_aPath = rtl::OUString::createFromAscii( "/" ); + m_aPath = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); return; } @@ -128,8 +129,8 @@ void PackageUri::init() const { m_aParam += ( m_aParam.getLength() - ? ::rtl::OUString::createFromAscii( "&purezip" ) - : ::rtl::OUString::createFromAscii( "?purezip" ) ); + ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "&purezip" ) ) + : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "?purezip" ) ) ); } aPureUri = aPureUri.replaceAt( 0, @@ -143,7 +144,7 @@ void PackageUri::init() const // Only <scheme>:/// - Empty authority // error, but remember that we did a init(). - m_aPath = rtl::OUString::createFromAscii( "/" ); + m_aPath = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); return; } else if ( nEnd == ( aPureUri.getLength() - 1 ) ) @@ -154,7 +155,7 @@ void PackageUri::init() const // Only <scheme>://// or <scheme>://<something>// // error, but remember that we did a init(). - m_aPath = rtl::OUString::createFromAscii( "/" ); + m_aPath = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); return; } @@ -175,7 +176,7 @@ void PackageUri::init() const nStart, aPureUri.getLength() - nStart, aNormPackage ); m_aPackage = ::ucb_impl::urihelper::decodeSegment( aNormPackage ); - m_aPath = rtl::OUString::createFromAscii( "/" ); + m_aPath = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); m_aUri = m_aUri.replaceAt( 0, ( nParam >= 0 ) ? nParam @@ -193,16 +194,19 @@ void PackageUri::init() const { m_aPath = aPureUri.copy( nEnd + 1 ); - // Empty path segments or encoded slashes? - if ( m_aPath.indexOf( - rtl::OUString::createFromAscii( "//" ) ) != -1 - || m_aPath.indexOf( - rtl::OUString::createFromAscii( "%2F" ) ) != -1 - || m_aPath.indexOf( - rtl::OUString::createFromAscii( "%2f" ) ) != -1 ) + // Unexpected sequences of characters: + // - empty path segments + // - encoded slashes + // - parent folder segments ".." + // - current folder segments "." + if ( m_aPath.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "//" ) ) ) != -1 + || m_aPath.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "%2F" ) ) ) != -1 + || m_aPath.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "%2f" ) ) ) != -1 + || ::comphelper::OStorageHelper::PathHasSegment( m_aPath, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".." ) ) ) + || ::comphelper::OStorageHelper::PathHasSegment( m_aPath, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) ) ) { // error, but remember that we did a init(). - m_aPath = rtl::OUString::createFromAscii( "/" ); + m_aPath = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); return; } @@ -239,7 +243,7 @@ void PackageUri::init() const else { // error, but remember that we did a init(). - m_aPath = rtl::OUString::createFromAscii( "/" ); + m_aPath = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); } } } diff --git a/vbahelper/inc/vbahelper/vbaapplicationbase.hxx b/vbahelper/inc/vbahelper/vbaapplicationbase.hxx index e2a5a3bff5da..6902bc7b5042 100644 --- a/vbahelper/inc/vbahelper/vbaapplicationbase.hxx +++ b/vbahelper/inc/vbahelper/vbaapplicationbase.hxx @@ -53,17 +53,20 @@ public: virtual void SAL_CALL setScreenUpdating(sal_Bool bUpdate) throw (css::uno::RuntimeException); virtual sal_Bool SAL_CALL getDisplayStatusBar() throw (css::uno::RuntimeException); virtual void SAL_CALL setDisplayStatusBar(sal_Bool bDisplayStatusBar) throw (css::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL getInteractive() throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setInteractive( ::sal_Bool bInteractive ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL getInteractive() throw (css::uno::RuntimeException); + virtual void SAL_CALL setInteractive( ::sal_Bool bInteractive ) throw (css::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException); + virtual void SAL_CALL setVisible( ::sal_Bool bVisible ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL CommandBars( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getVersion() throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getVBE() throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getVBProjects() throw (css::uno::RuntimeException); + virtual void SAL_CALL Run( const ::rtl::OUString& MacroName, const css::uno::Any& varg1, const css::uno::Any& varg2, const css::uno::Any& varg3, const css::uno::Any& varg4, const css::uno::Any& varg5, const css::uno::Any& varg6, const css::uno::Any& varg7, const css::uno::Any& varg8, const css::uno::Any& varg9, const css::uno::Any& varg10, const css::uno::Any& varg11, const css::uno::Any& varg12, const css::uno::Any& varg13, const css::uno::Any& varg14, const css::uno::Any& varg15, const css::uno::Any& varg16, const css::uno::Any& varg17, const css::uno::Any& varg18, const css::uno::Any& varg19, const css::uno::Any& varg20, const css::uno::Any& varg21, const css::uno::Any& varg22, const css::uno::Any& varg23, const css::uno::Any& varg24, const css::uno::Any& varg25, const css::uno::Any& varg26, const css::uno::Any& varg27, const css::uno::Any& varg28, const css::uno::Any& varg29, const css::uno::Any& varg30 ) throw (css::uno::RuntimeException); - virtual void SAL_CALL OnTime( const ::com::sun::star::uno::Any& aEarliestTime, const ::rtl::OUString& aFunction, const ::com::sun::star::uno::Any& aLatestTime, const ::com::sun::star::uno::Any& aSchedule ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL OnTime( const css::uno::Any& aEarliestTime, const ::rtl::OUString& aFunction, const css::uno::Any& aLatestTime, const css::uno::Any& aSchedule ) throw (css::uno::RuntimeException); virtual float SAL_CALL CentimetersToPoints( float _Centimeters ) throw (css::uno::RuntimeException); - virtual void SAL_CALL Undo( ) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL Quit( ) throw (::com::sun::star::uno::RuntimeException); - virtual css::uno::Any SAL_CALL getVBE() throw (css::uno::RuntimeException); - virtual css::uno::Any SAL_CALL SAL_CALL getVBProjects() throw (css::uno::RuntimeException); + virtual void SAL_CALL Undo() throw (css::uno::RuntimeException); + virtual void SAL_CALL Quit() throw (css::uno::RuntimeException); // XHelperInterface virtual rtl::OUString& getServiceImplName(); diff --git a/vbahelper/inc/vbahelper/vbacollectionimpl.hxx b/vbahelper/inc/vbahelper/vbacollectionimpl.hxx index 36102116c7b3..5bd58b44adaf 100644 --- a/vbahelper/inc/vbahelper/vbacollectionimpl.hxx +++ b/vbahelper/inc/vbahelper/vbacollectionimpl.hxx @@ -133,11 +133,12 @@ protected: class VBAHELPER_DLLPUBLIC EnumerationHelperImpl : public EnumerationHelper_BASE { protected: + css::uno::WeakReference< ov::XHelperInterface > m_xParent; css::uno::Reference< css::uno::XComponentContext > m_xContext; css::uno::Reference< css::container::XEnumeration > m_xEnumeration; public: - EnumerationHelperImpl( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XEnumeration >& xEnumeration ) throw ( css::uno::RuntimeException ) : m_xContext( xContext ), m_xEnumeration( xEnumeration ) { } + EnumerationHelperImpl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XEnumeration >& xEnumeration ) throw ( css::uno::RuntimeException ) : m_xParent( xParent ), m_xContext( xContext ), m_xEnumeration( xEnumeration ) { } virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (css::uno::RuntimeException) { return m_xEnumeration->hasMoreElements(); } }; diff --git a/vbahelper/inc/vbahelper/vbadocumentbase.hxx b/vbahelper/inc/vbahelper/vbadocumentbase.hxx index 7131e1963b26..2588b7da1720 100644 --- a/vbahelper/inc/vbahelper/vbadocumentbase.hxx +++ b/vbahelper/inc/vbahelper/vbadocumentbase.hxx @@ -52,9 +52,7 @@ public: virtual ::rtl::OUString SAL_CALL getFullName() throw (css::uno::RuntimeException); virtual sal_Bool SAL_CALL getSaved() throw (css::uno::RuntimeException); virtual void SAL_CALL setSaved( sal_Bool bSave ) throw (css::uno::RuntimeException); - - virtual css::uno::Any SAL_CALL getVBProject() throw (css::uno::RuntimeException); // Michhael E. Bohn - + virtual css::uno::Any SAL_CALL getVBProject() throw (css::uno::RuntimeException); // Methods virtual void SAL_CALL Close( const css::uno::Any &bSaveChanges, diff --git a/vbahelper/inc/vbahelper/vbaeventshelperbase.hxx b/vbahelper/inc/vbahelper/vbaeventshelperbase.hxx new file mode 100755 index 000000000000..89d355db71f9 --- /dev/null +++ b/vbahelper/inc/vbahelper/vbaeventshelperbase.hxx @@ -0,0 +1,162 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef VBAHELPER_VBAEVENTSHELPERBASE_HXX +#define VBAHELPER_VBAEVENTSHELPERBASE_HXX + +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> +#include <cppuhelper/implbase2.hxx> +#include <map> +#include <deque> +#include "vbahelper/vbahelper.hxx" + +namespace com { namespace sun { namespace star { + namespace uno { class XComponentContext; } +} } } + +// ============================================================================ + +typedef ::cppu::WeakImplHelper2< css::script::vba::XVBAEventProcessor, css::lang::XEventListener > VbaEventsHelperBase_BASE; + +class VBAHELPER_DLLPUBLIC VbaEventsHelperBase : public VbaEventsHelperBase_BASE +{ +public: + VbaEventsHelperBase( + const css::uno::Sequence< css::uno::Any >& rArgs, + const css::uno::Reference< css::uno::XComponentContext >& xContext ); + virtual ~VbaEventsHelperBase(); + + // XVBAEventProcessor + virtual sal_Bool SAL_CALL hasVbaEventHandler( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + virtual void SAL_CALL processVbaEvent( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException, css::script::provider::ScriptFrameworkErrorException, css::util::VetoException, css::uno::RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& aSource ) throw (css::uno::RuntimeException); + +protected: + // ------------------------------------------------------------------------ + + enum EventHandlerType { EVENTHANDLER_GLOBAL, EVENTHANDLER_DOCUMENT }; + struct EventHandlerInfo + { + sal_Int32 mnEventId; + ::rtl::OUString maMacroName; + EventHandlerType meType; + sal_Int32 mnCancelIndex; + css::uno::Any maUserData; + }; + + /** Registers a supported event handler. + + @param nEventId Event identifier from com.sun.star.script.vba.EventIdentifier. + @param pcMacroName Name of the associated VBA event handler macro. + @param eType Document event or global event. + @param nCancelIndex 0-based index of Cancel parameter, or -1. + @param rUserData User data for free usage in derived implementations. */ + void registerEventHandler( + sal_Int32 nEventId, + const sal_Char* pcMacroName, + EventHandlerType eType = EVENTHANDLER_DOCUMENT, + sal_Int32 nCancelIndex = -1, + const css::uno::Any& rUserData = css::uno::Any() ); + + /** Throws, if the passed sequence does not contain a value at the specified index. */ + static inline void checkArgument( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException) + { if( rArgs.getLength() <= nIndex ) throw css::lang::IllegalArgumentException(); } + + /** Throws, if the passed sequence does not contain a value of a specific at the specified index. */ + template< typename Type > + static inline void checkArgumentType( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException) + { if( (rArgs.getLength() <= nIndex) || !rArgs[ nIndex ].has< Type >() ) throw css::lang::IllegalArgumentException(); } + + // ------------------------------------------------------------------------ + + struct EventQueueEntry + { + sal_Int32 mnEventId; + css::uno::Sequence< css::uno::Any > maArgs; + inline /*implicit*/ EventQueueEntry( sal_Int32 nEventId ) : mnEventId( nEventId ) {} + inline EventQueueEntry( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ) : mnEventId( nEventId ), maArgs( rArgs ) {} + }; + typedef ::std::deque< EventQueueEntry > EventQueue; + + /** Derived classes return whether event processing is enabled. Throws if + the instance is in an invalid state. */ + virtual bool implEventsEnabled() throw (css::uno::RuntimeException) = 0; + + /** Derived classes do additional prpeparations and return whether the + event handler has to be called. */ + virtual bool implPrepareEvent( + EventQueue& rEventQueue, + const EventHandlerInfo& rInfo, + const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::uno::RuntimeException) = 0; + + /** Derived classes have to return the argument list for the specified VBA event handler. */ + virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( + const EventHandlerInfo& rInfo, + const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException) = 0; + + /** Derived classes may do additional postprocessing. Called even if the + event handler does not exist, or if an error occured during execution. */ + virtual void implPostProcessEvent( + EventQueue& rEventQueue, + const EventHandlerInfo& rInfo, + bool bSuccess, + bool bCancel ) throw (css::uno::RuntimeException) = 0; + + /** Derived classes have to return the name of the Basic document module. */ + virtual ::rtl::OUString implGetDocumentModuleName( + const EventHandlerInfo& rInfo, + const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException) = 0; + +private: + /** Returns the event handler info struct for the specified event, or throws. */ + const EventHandlerInfo& getEventHandlerInfo( sal_Int32 nEventId ) const throw (css::lang::IllegalArgumentException); + + /** Searches the event handler in the document and returns its full script path. */ + ::rtl::OUString getEventHandlerPath( + const EventHandlerInfo& rInfo, + const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException); + + /** Removes this instance from all broadcasters. */ + void stopListening(); + +protected: + css::uno::Reference< css::frame::XModel > mxModel; + SfxObjectShell* mpShell; + +private: + typedef ::std::map< sal_Int32, EventHandlerInfo > EventHandlerMap; + + EventHandlerMap maEvents; + bool mbDisposed; +}; + +// ============================================================================ + +#endif diff --git a/vbahelper/inc/vbahelper/vbaglobalbase.hxx b/vbahelper/inc/vbahelper/vbaglobalbase.hxx index e75cbb7e7af8..61aaa1d65657 100644 --- a/vbahelper/inc/vbahelper/vbaglobalbase.hxx +++ b/vbahelper/inc/vbahelper/vbaglobalbase.hxx @@ -32,16 +32,16 @@ typedef InheritedHelperInterfaceImpl1< ov::XGlobalsBase > Globals_BASE; class VBAHELPER_DLLPUBLIC VbaGlobalsBase : public Globals_BASE - { protected: + rtl::OUString msDocCtxName; bool hasServiceName( const rtl::OUString& serviceName ); void init( const css::uno::Sequence< css::beans::PropertyValue >& aInitArgs ); public: VbaGlobalsBase( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const rtl::OUString& sDocCtxName ); - virtual ~VbaGlobalsBase(){}; + virtual ~VbaGlobalsBase(); // XMultiServiceFactory virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (css::uno::Exception, css::uno::RuntimeException); virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const css::uno::Sequence< css::uno::Any >& Arguments ) throw (css::uno::Exception, css::uno::RuntimeException); diff --git a/vbahelper/inc/vbahelper/vbahelper.hxx b/vbahelper/inc/vbahelper/vbahelper.hxx index 33613bb76091..ccabb9114f2d 100644 --- a/vbahelper/inc/vbahelper/vbahelper.hxx +++ b/vbahelper/inc/vbahelper/vbahelper.hxx @@ -63,6 +63,7 @@ namespace ooo throw css::lang::IllegalArgumentException(); return aSomething; } + VBAHELPER_DLLPUBLIC css::uno::Reference< css::uno::XInterface > getUnoDocModule( const String& aModName, SfxObjectShell* pShell ); VBAHELPER_DLLPUBLIC SfxObjectShell* getSfxObjShell( const css::uno::Reference< css::frame::XModel >& xModel ) throw ( css::uno::RuntimeException); VBAHELPER_DLLPUBLIC css::uno::Reference< css::uno::XInterface > createVBAUnoAPIService( SfxObjectShell* pShell, const sal_Char* _pAsciiName ) throw (css::uno::RuntimeException); @@ -89,6 +90,13 @@ namespace ooo VBAHELPER_DLLPUBLIC void PrintOutHelper( SfxViewShell* pViewShell, const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName, sal_Bool bSelection ); VBAHELPER_DLLPUBLIC void PrintPreviewHelper( const css::uno::Any& EnableChanges, SfxViewShell* ); + /** Extracts a boolean value from the passed Any, which may contain sal_Bool or an integer or floating-point value. + Returns false, if the Any is empty or contains an incompatible type. */ + VBAHELPER_DLLPUBLIC bool extractBoolFromAny( bool& rbValue, const css::uno::Any& rAny ); + /** Extracts a boolean value from the passed Any, which may contain sal_Bool or an integer or floating-point value. + Throws, if the Any is empty or contains an incompatible type. */ + VBAHELPER_DLLPUBLIC bool extractBoolFromAny( const css::uno::Any& rAny ) throw (css::uno::RuntimeException); + VBAHELPER_DLLPUBLIC rtl::OUString getAnyAsString( const css::uno::Any& pvargItem ) throw ( css::uno::RuntimeException ); VBAHELPER_DLLPUBLIC rtl::OUString VBAToRegexp(const rtl::OUString &rIn, bool bForLike = false); // needs to be in an uno service ( already this code is duplicated in basic ) VBAHELPER_DLLPUBLIC double getPixelTo100thMillimeterConversionFactor( css::uno::Reference< css::awt::XDevice >& xDevice, sal_Bool bVertical); diff --git a/vbahelper/inc/vbahelper/vbahelperinterface.hxx b/vbahelper/inc/vbahelper/vbahelperinterface.hxx index 21339631e1ed..b095b5cd2823 100644 --- a/vbahelper/inc/vbahelper/vbahelperinterface.hxx +++ b/vbahelper/inc/vbahelper/vbahelperinterface.hxx @@ -28,6 +28,8 @@ #define OOVBAAPI_VBA_HELPERINTERFACE_HXX #include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase3.hxx> #include <ooo/vba/XHelperInterface.hpp> #include <vbahelper/vbahelper.hxx> #include <com/sun/star/container/XNameAccess.hpp> @@ -68,6 +70,7 @@ protected: css::uno::Reference< css::uno::XComponentContext > mxContext; public: InheritedHelperInterfaceImpl() {} + InheritedHelperInterfaceImpl( const css::uno::Reference< css::uno::XComponentContext >& xContext ) : mxContext( xContext ) {} InheritedHelperInterfaceImpl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : mxParent( xParent ), mxContext( xContext ) {} virtual rtl::OUString& getServiceImplName() = 0; virtual css::uno::Sequence<rtl::OUString> getServiceNames() = 0; @@ -86,7 +89,6 @@ public: return xNameAccess->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Application" ) ) ); } - // XServiceInfo Methods virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (css::uno::RuntimeException) { return getServiceImplName(); } virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (css::uno::RuntimeException) @@ -101,19 +103,39 @@ public: } virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (css::uno::RuntimeException) { - css::uno::Sequence< rtl::OUString > aNames = getServiceNames();; + css::uno::Sequence< rtl::OUString > aNames = getServiceNames(); return aNames; } }; template< typename Ifc1 > class VBAHELPER_DLLPUBLIC InheritedHelperInterfaceImpl1 : public InheritedHelperInterfaceImpl< ::cppu::WeakImplHelper1< Ifc1 > > +{ + typedef InheritedHelperInterfaceImpl< ::cppu::WeakImplHelper1< Ifc1 > > Base; +public: + InheritedHelperInterfaceImpl1< Ifc1 >() {} + InheritedHelperInterfaceImpl1< Ifc1 >( const css::uno::Reference< css::uno::XComponentContext >& xContext ) : Base( xContext ) {} + InheritedHelperInterfaceImpl1< Ifc1 >( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : Base( xParent, xContext ) {} +}; +template< typename Ifc1, typename Ifc2 > +class VBAHELPER_DLLPUBLIC InheritedHelperInterfaceImpl2 : public InheritedHelperInterfaceImpl< ::cppu::WeakImplHelper2< Ifc1, Ifc2 > > { -typedef InheritedHelperInterfaceImpl< ::cppu::WeakImplHelper1< Ifc1 > > Base; + typedef InheritedHelperInterfaceImpl< ::cppu::WeakImplHelper2< Ifc1, Ifc2 > > Base; public: - InheritedHelperInterfaceImpl1< Ifc1 > ( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : Base( xParent, xContext ) {} + InheritedHelperInterfaceImpl2< Ifc1, Ifc2 >() {} + InheritedHelperInterfaceImpl2< Ifc1, Ifc2 >( const css::uno::Reference< css::uno::XComponentContext >& xContext ) : Base( xContext ) {} + InheritedHelperInterfaceImpl2< Ifc1, Ifc2 >( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : Base( xParent, xContext ) {} +}; +template< typename Ifc1, typename Ifc2, typename Ifc3 > +class VBAHELPER_DLLPUBLIC InheritedHelperInterfaceImpl3 : public InheritedHelperInterfaceImpl< ::cppu::WeakImplHelper3< Ifc1, Ifc2, Ifc3 > > +{ + typedef InheritedHelperInterfaceImpl< ::cppu::WeakImplHelper3< Ifc1, Ifc2, Ifc3 > > Base; +public: + InheritedHelperInterfaceImpl3< Ifc1, Ifc2, Ifc3 >() {} + InheritedHelperInterfaceImpl3< Ifc1, Ifc2, Ifc3 >( const css::uno::Reference< css::uno::XComponentContext >& xContext ) : Base( xContext ) {} + InheritedHelperInterfaceImpl3< Ifc1, Ifc2, Ifc3 >( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : Base( xParent, xContext ) {} }; // ============================================================================ diff --git a/vbahelper/prj/d.lst b/vbahelper/prj/d.lst index d683e97c8b90..2d20ab1f982d 100644 --- a/vbahelper/prj/d.lst +++ b/vbahelper/prj/d.lst @@ -26,3 +26,4 @@ mkdir: %_DEST%\inc%_EXT%\basic ..\inc\vbahelper\vbatextframe.hxx %_DEST%\inc%_EXT%\vbahelper\vbatextframe.hxx ..\inc\vbahelper\vbashaperange.hxx %_DEST%\inc%_EXT%\vbahelper\vbashaperange.hxx ..\inc\vbahelper\vbapagesetupbase.hxx %_DEST%\inc%_EXT%\vbahelper\vbapagesetupbase.hxx +..\inc\vbahelper\vbaeventshelperbase.hxx %_DEST%\inc%_EXT%\vbahelper\vbaeventshelperbase.hxx diff --git a/vbahelper/source/msforms/vbacontrols.cxx b/vbahelper/source/msforms/vbacontrols.cxx index 1284b36be463..8d01687ef905 100644 --- a/vbahelper/source/msforms/vbacontrols.cxx +++ b/vbahelper/source/msforms/vbacontrols.cxx @@ -74,12 +74,20 @@ private: public: ControlArrayWrapper( const uno::Reference< awt::XControl >& xDialog ) { - mxDialog.set( xDialog, uno::UNO_QUERY_THROW ); - uno::Sequence< uno::Reference< awt::XControl > > sXControls = mxDialog->getControls(); + try + { + mxDialog.set( xDialog, uno::UNO_QUERY_THROW ); + uno::Sequence< uno::Reference< awt::XControl > > sXControls = mxDialog->getControls(); - msNames.realloc( sXControls.getLength() ); - for ( sal_Int32 i = 0; i < sXControls.getLength(); ++i ) - SetArrayElementTo( sXControls[ i ], i ); + msNames.realloc( sXControls.getLength() ); + for ( sal_Int32 i = 0; i < sXControls.getLength(); ++i ) + SetArrayElementTo( sXControls[ i ], i ); + } + catch( uno::Exception& ) + { + // accept the case when the dialog already does not exist + // in this case the wrapper should work in dummy mode + } } static rtl::OUString getControlName( const uno::Reference< awt::XControl >& xCtrl ) @@ -186,7 +194,7 @@ ScVbaControls::ScVbaControls( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< awt::XControl >& xDialog ) : ControlsImpl_BASE( xParent, xContext, lcl_controlsWrapper( xDialog ) ) { - mxDialog.set( xDialog, uno::UNO_QUERY_THROW ); + mxDialog.set( xDialog, uno::UNO_QUERY ); } uno::Reference< container::XEnumeration > @@ -349,13 +357,16 @@ void SAL_CALL ScVbaControls::Remove( const uno::Any& StringKeyOrIndex ) } catch( uno::RuntimeException& ) { - throw; + // the exceptions are not rethrown, impossibility to find or remove the control is currently not reported + // since in most cases it means just that the controls is already not there, the VBA seems to do it in the same way + + // throw; } catch( uno::Exception& e ) { - throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not create AXControl!" ) ), - uno::Reference< uno::XInterface >(), - uno::makeAny( e ) ); + // throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not create AXControl!" ) ), + // uno::Reference< uno::XInterface >(), + // uno::makeAny( e ) ); } } diff --git a/vbahelper/source/msforms/vbauserform.cxx b/vbahelper/source/msforms/vbauserform.cxx index 1ce403fc19c3..a1333e0a655b 100644 --- a/vbahelper/source/msforms/vbauserform.cxx +++ b/vbahelper/source/msforms/vbauserform.cxx @@ -153,28 +153,41 @@ void SAL_CALL ScVbaUserForm::setValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue ) throw (beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) { uno::Any aObject = getValue( aPropertyName ); - // The Object *must* support XDefaultProperty here because getValue will - // only return properties that are Objects ( e.g. controls ) - // e.g. Userform1.aControl = something - // 'aControl' has to support XDefaultProperty to make sense here - uno::Reference< script::XDefaultProperty > xDfltProp( aObject, uno::UNO_QUERY_THROW ); - rtl::OUString aDfltPropName = xDfltProp->getDefaultPropertyName(); - uno::Reference< beans::XIntrospectionAccess > xUnoAccess( getIntrospectionAccess( aObject ) ); - uno::Reference< beans::XPropertySet > xPropSet( xUnoAccess->queryAdapter( ::getCppuType( (const uno::Reference< beans::XPropertySet > *)0 ) ), uno::UNO_QUERY_THROW ); - xPropSet->setPropertyValue( aDfltPropName, aValue ); + + // in case the dialog is already closed the VBA implementation should not throw exceptions + if ( aObject.hasValue() ) + { + // The Object *must* support XDefaultProperty here because getValue will + // only return properties that are Objects ( e.g. controls ) + // e.g. Userform1.aControl = something + // 'aControl' has to support XDefaultProperty to make sense here + uno::Reference< script::XDefaultProperty > xDfltProp( aObject, uno::UNO_QUERY_THROW ); + rtl::OUString aDfltPropName = xDfltProp->getDefaultPropertyName(); + uno::Reference< beans::XIntrospectionAccess > xUnoAccess( getIntrospectionAccess( aObject ) ); + uno::Reference< beans::XPropertySet > xPropSet( xUnoAccess->queryAdapter( ::getCppuType( (const uno::Reference< beans::XPropertySet > *)0 ) ), uno::UNO_QUERY_THROW ); + xPropSet->setPropertyValue( aDfltPropName, aValue ); + } } uno::Any SAL_CALL ScVbaUserForm::getValue( const ::rtl::OUString& aPropertyName ) throw (beans::UnknownPropertyException, uno::RuntimeException) { - uno::Reference< awt::XControl > xDialogControl( m_xDialog, uno::UNO_QUERY_THROW ); - uno::Reference< awt::XControlContainer > xContainer( m_xDialog, uno::UNO_QUERY_THROW ); - uno::Reference< awt::XControl > xControl = xContainer->getControl( aPropertyName ); - ScVbaControlFactory aFac( mxContext, xControl, m_xModel ); - uno::Reference< msforms::XControl > xVBAControl( aFac.createControl( xDialogControl->getModel() ) ); - ScVbaControl* pControl = dynamic_cast< ScVbaControl* >( xVBAControl.get() ); - pControl->setGeometryHelper( new UserFormGeometryHelper( mxContext, xControl ) ); - return uno::makeAny( xVBAControl ); + uno::Any aResult; + + // in case the dialog is already closed the VBA implementation should not throw exceptions + if ( m_xDialog.is() ) + { + uno::Reference< awt::XControl > xDialogControl( m_xDialog, uno::UNO_QUERY_THROW ); + uno::Reference< awt::XControlContainer > xContainer( m_xDialog, uno::UNO_QUERY_THROW ); + uno::Reference< awt::XControl > xControl = xContainer->getControl( aPropertyName ); + ScVbaControlFactory aFac( mxContext, xControl, m_xModel ); + uno::Reference< msforms::XControl > xVBAControl( aFac.createControl( xDialogControl->getModel() ) ); + ScVbaControl* pControl = dynamic_cast< ScVbaControl* >( xVBAControl.get() ); + pControl->setGeometryHelper( new UserFormGeometryHelper( mxContext, xControl ) ); + aResult = uno::makeAny( xVBAControl ); + } + + return aResult; } ::sal_Bool SAL_CALL @@ -185,7 +198,9 @@ ScVbaUserForm::hasMethod( const ::rtl::OUString& /*aName*/ ) throw (uno::Runtime uno::Any SAL_CALL ScVbaUserForm::Controls( const uno::Any& index ) throw (uno::RuntimeException) { - uno::Reference< awt::XControl > xDialogControl( m_xDialog, uno::UNO_QUERY_THROW ); + // if the dialog already closed we should do nothing, but the VBA will call methods of the Controls objects + // thus we have to provide a dummy object in this case + uno::Reference< awt::XControl > xDialogControl( m_xDialog, uno::UNO_QUERY ); uno::Reference< XCollection > xControls( new ScVbaControls( this, mxContext, xDialogControl ) ); if ( index.hasValue() ) return uno::makeAny( xControls->Item( index, uno::Any() ) ); diff --git a/vbahelper/source/vbahelper/makefile.mk b/vbahelper/source/vbahelper/makefile.mk index 47ad44b3d0ed..22ed40a3adfa 100644 --- a/vbahelper/source/vbahelper/makefile.mk +++ b/vbahelper/source/vbahelper/makefile.mk @@ -65,6 +65,8 @@ SLOFILES=\ $(SLO)$/vbashaperange.obj \ $(SLO)$/vbatextframe.obj \ $(SLO)$/vbapagesetupbase.obj \ + $(SLO)$/vbaeventshelperbase.obj + # --- Targets ------------------------------------------------------- .INCLUDE : target.mk diff --git a/vbahelper/source/vbahelper/vbaapplicationbase.cxx b/vbahelper/source/vbahelper/vbaapplicationbase.cxx index 6d2c51066ca2..326c150edade 100644 --- a/vbahelper/source/vbahelper/vbaapplicationbase.cxx +++ b/vbahelper/source/vbahelper/vbaapplicationbase.cxx @@ -24,39 +24,37 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #include "vbahelper/vbaapplicationbase.hxx" + #include <com/sun/star/container/XIndexAccess.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> //Michael E. Bohn -#include <com/sun/star/lang/XMultiComponentFactory.hpp> //Michael E. Bohn -#include <com/sun/star/lang/XComponent.hpp> //Michael E. Bohn -#include <com/sun/star/container/XEnumeration.hpp> //Michael E. Bohn +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/container/XEnumeration.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> #include <com/sun/star/frame/XDesktop.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/document/XDocumentInfoSupplier.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> -#include <com/sun/star/document/XEmbeddedScripts.hpp> //Michael E. Bohn -#include <ooo/vba/XVBAAppService.hpp> //Michael E. Bohn +#include <com/sun/star/document/XEmbeddedScripts.hpp> #include <com/sun/star/awt/XWindow2.hpp> - -#include "vbacommandbars.hxx" +#include <hash_map> #include <filter/msfilter/msvbahelper.hxx> #include <tools/datetime.hxx> -// start basic includes #include <basic/sbx.hxx> #include <basic/sbstar.hxx> #include <basic/sbuno.hxx> #include <basic/sbmeth.hxx> #include <basic/sbmod.hxx> -// end basic includes -#include <hash_map> +#include "vbacommandbars.hxx" -using namespace com::sun::star; -using namespace ooo::vba; +using namespace ::com::sun::star; +using namespace ::ooo::vba; #define OFFICEVERSION "11.0" @@ -162,6 +160,9 @@ typedef ::std::hash_map< VbaTimerInfo, VbaTimer*, VbaTimerInfoHash, ::std::equal struct VbaApplicationBase_Impl { VbaTimerHashMap m_aTimerHash; + sal_Bool mbVisible; + + inline VbaApplicationBase_Impl() : mbVisible( sal_True ) {} virtual ~VbaApplicationBase_Impl() { @@ -185,7 +186,6 @@ VbaApplicationBase::VbaApplicationBase( const uno::Reference< uno::XComponentCon VbaApplicationBase::~VbaApplicationBase() { - m_pImpl = 0; delete m_pImpl; } @@ -268,6 +268,16 @@ void SAL_CALL VbaApplicationBase::setInteractive( ::sal_Bool bInteractive ) xWindow->setEnable( bInteractive ); } +sal_Bool SAL_CALL VbaApplicationBase::getVisible() throw (uno::RuntimeException) +{ + return m_pImpl->mbVisible; // dummy implementation +} + +void SAL_CALL VbaApplicationBase::setVisible( sal_Bool bVisible ) throw (uno::RuntimeException) +{ + m_pImpl->mbVisible = bVisible; // dummy implementation +} + uno::Any SAL_CALL VbaApplicationBase::CommandBars( const uno::Any& aIndex ) throw (uno::RuntimeException) { @@ -407,63 +417,50 @@ float SAL_CALL VbaApplicationBase::CentimetersToPoints( float _Centimeters ) thr return ( _Centimeters * rate ); } -// inserted by Michael E. Bohn uno::Any SAL_CALL VbaApplicationBase::getVBE() throw (uno::RuntimeException) { - uno::Any aAny; - uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); - try - { - uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAAppService" )),mxContext); - uno::Reference < ::ooo::vba::XVBAAppService > xVBAAppService (xInterface, ::uno::UNO_QUERY_THROW ); - if (xVBAAppService.is()){ - uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); - return xVBAAppService->getVBE( this, mxContext, xModel); - } - - }catch(uno::Exception* e) - { - } - return aAny; + try // return empty object on error + { + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< XHelperInterface >( this ); + aArgs[ 1 ] <<= getCurrentDocument(); + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< uno::XInterface > xVBE = xServiceManager->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBE" ) ), aArgs, mxContext ); + return uno::Any( xVBE ); + } + catch( uno::Exception& ) + { + } + return uno::Any(); } uno::Any SAL_CALL VbaApplicationBase::getVBProjects() throw (uno::RuntimeException) { - uno::Any aAny; - uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); - try - { - uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAAppService" )),mxContext); - uno::Reference < ::ooo::vba::XVBAAppService > xVBAAppService (xInterface, ::uno::UNO_QUERY_THROW ); - if (xVBAAppService.is()){ - uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); - uno::Reference< document::XEmbeddedScripts > xEnbeddedScripts ( xModel, uno::UNO_QUERY_THROW ); - uno::Reference< script::XStorageBasedLibraryContainer > xMacroStorageBasedLibraryContainer = xEnbeddedScripts->getBasicLibraries(); - uno::Reference< script::XStorageBasedLibraryContainer > xDialogStorageBasedLibraryContainer = xEnbeddedScripts->getDialogLibraries(); - uno::Reference< script::XLibraryContainer > xMacroLibraryContainer ( xMacroStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); - uno::Reference< script::XLibraryContainer > xDialogLibraryContainer( xDialogStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); - return xVBAAppService->getVBProjects(this, mxContext, xModel, xMacroLibraryContainer, xDialogLibraryContainer); - } - - }catch(uno::Exception* e) - { - } - return aAny; - - - + try // return empty object on error + { + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< XHelperInterface >( this ); + aArgs[ 1 ] <<= getCurrentDocument(); + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< uno::XInterface > xVBProjects = xServiceManager->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBProjects" ) ), aArgs, mxContext ); + return uno::Any( xVBProjects ); + } + catch( uno::Exception& ) + { + } + return uno::Any(); } - - - rtl::OUString& VbaApplicationBase::getServiceImplName() { static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("VbaApplicationBase") ); return sImplName; } + uno::Sequence<rtl::OUString> VbaApplicationBase::getServiceNames() { diff --git a/vbahelper/source/vbahelper/vbadocumentbase.cxx b/vbahelper/source/vbahelper/vbadocumentbase.cxx index f27f2de53c8a..65f7f4bcfbeb 100644 --- a/vbahelper/source/vbahelper/vbadocumentbase.cxx +++ b/vbahelper/source/vbahelper/vbadocumentbase.cxx @@ -24,9 +24,9 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <vbahelper/vbadocumentbase.hxx> -#include <vbahelper/helperdecl.hxx> -#include <comphelper/unwrapargs.hxx> + +#include "vbahelper/vbadocumentbase.hxx" +#include "vbahelper/helperdecl.hxx" #include <com/sun/star/util/XModifiable.hpp> #include <com/sun/star/util/XProtectable.hpp> @@ -35,8 +35,8 @@ #include <com/sun/star/frame/XFrame.hpp> #include <com/sun/star/document/XEmbeddedScripts.hpp> //Michael E. Bohn #include <com/sun/star/beans/XPropertySet.hpp> -#include <ooo/vba/XVBADocService.hpp> +#include <comphelper/unwrapargs.hxx> #include <tools/urlobj.hxx> #include <osl/file.hxx> @@ -206,40 +206,25 @@ VbaDocumentBase::Activate() throw (uno::RuntimeException) xFrame->activate(); } -// ---- Michael E.Bohn Start----- - uno::Any SAL_CALL VbaDocumentBase::getVBProject() throw (uno::RuntimeException) - { - uno::Any aAny; - uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); - try - { - uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBADocService" )),mxContext); - uno::Reference < ::ooo::vba::XVBADocService > xVBADocService (xInterface, ::uno::UNO_QUERY_THROW ); - if (xVBADocService.is()){ - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - uno::Reference< document::XEmbeddedScripts > xEnbeddedScripts ( xModel, uno::UNO_QUERY_THROW ); - uno::Reference< script::XStorageBasedLibraryContainer > xMacroStorageBasedLibraryContainer = xEnbeddedScripts->getBasicLibraries(); - uno::Reference< script::XStorageBasedLibraryContainer > xDialogStorageBasedLibraryContainer = xEnbeddedScripts->getDialogLibraries(); - uno::Reference< script::XLibraryContainer > xMacroLibraryContainer ( xMacroStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); - uno::Reference< script::XLibraryContainer > xDialogLibraryContainer( xDialogStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); - - return xVBADocService->getVBProject( this, mxContext, xModel, xMacroLibraryContainer, xDialogLibraryContainer ); - } - - }catch(uno::Exception* e) - { - } - return aAny; - + try // return empty object on error + { + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< XHelperInterface >( this ); + aArgs[ 1 ] <<= mxModel; + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< uno::XInterface > xVBProjects = xServiceManager->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBProject" ) ), aArgs, mxContext ); + return uno::Any( xVBProjects ); + } + catch( uno::Exception& ) + { + } + return uno::Any(); } - -// ---- Michael E.Bohn End ----- - - rtl::OUString& VbaDocumentBase::getServiceImplName() { diff --git a/vbahelper/source/vbahelper/vbaeventshelperbase.cxx b/vbahelper/source/vbahelper/vbaeventshelperbase.cxx new file mode 100755 index 000000000000..16a8671df601 --- /dev/null +++ b/vbahelper/source/vbahelper/vbaeventshelperbase.cxx @@ -0,0 +1,218 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbahelper/vbaeventshelperbase.hxx" +#include <filter/msfilter/msvbahelper.hxx> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +// ============================================================================ + +VbaEventsHelperBase::VbaEventsHelperBase( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& /*xContext*/ ) : + mpShell( 0 ), + mbDisposed( false ) +{ + try + { + mxModel = getXSomethingFromArgs< frame::XModel >( rArgs, 0, false ); + mpShell = getSfxObjShell( mxModel ); + + // add dispose listener + uno::Reference< lang::XComponent > xComponent( mxModel, uno::UNO_QUERY_THROW ); + xComponent->addEventListener( this ); + } + catch( uno::Exception& ) + { + } +} + +VbaEventsHelperBase::~VbaEventsHelperBase() +{ + stopListening(); +} + +sal_Bool SAL_CALL VbaEventsHelperBase::hasVbaEventHandler( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs ) + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + // getEventHandlerInfo() throws, if unknown event dentifier has been passed + const EventHandlerInfo& rInfo = getEventHandlerInfo( nEventId ); + // getEventHandlerPath() searches for the macro in the document + return getEventHandlerPath( rInfo, rArgs ).getLength() > 0; +} + +void SAL_CALL VbaEventsHelperBase::processVbaEvent( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs ) + throw (lang::IllegalArgumentException, script::provider::ScriptFrameworkErrorException, util::VetoException, uno::RuntimeException) +{ + /* Derived classes may add new event identifiers to be processed while + processing the original event. All unprocessed events are collected in + a queue. First element in the queue is the next event to be processed. */ + EventQueue aEventQueue; + aEventQueue.push_back( EventQueueEntry( nEventId, rArgs ) ); + + /* bEnabled will track if event processing is enabled. Every event handler + may disable handling of other events. */ + bool bEnabled = true; + + /* bCancel will contain the current Cancel value. It is possible that + multiple events will try to modify the Cancel value. Every event + handler receives the Cancel value of the previous event handler. */ + bool bCancel = false; + + /* bSuccess will change to true if at least one event handler has been + executed successfully. */ + bool bSuccess = false; + + /* Loop as long as there are more events to be processed, and as event + handling is still enabled. Derived classes may add new events to be + processed in the virtual implPrepareEvent() function. */ + while( bEnabled && !aEventQueue.empty() ) + { + /* Check that all class members are available, and that we are not + disposed (this may have happened at any time during execution of + the last event handler). */ + if( mbDisposed || !mxModel.is() || !mpShell ) + throw uno::RuntimeException(); + + // get info for next event + const EventHandlerInfo& rInfo = getEventHandlerInfo( aEventQueue.front().mnEventId ); + uno::Sequence< uno::Any > aEventArgs = aEventQueue.front().maArgs; + aEventQueue.pop_front(); + + // let derived classes decide whether event processing is still enabled + bEnabled = implEventsEnabled(); + // let derived classes prepare the event, they may add new events for next iteration + if( bEnabled && implPrepareEvent( aEventQueue, rInfo, aEventArgs ) ) + { + // search the event handler macro in the document + ::rtl::OUString aMacroPath = getEventHandlerPath( rInfo, aEventArgs ); + bool bEventSuccess = false; + if( aMacroPath.getLength() > 0 ) + { + // build the argument list + uno::Sequence< uno::Any > aVbaArgs = implBuildArgumentList( rInfo, aEventArgs ); + // insert current cancel value + if( rInfo.mnCancelIndex >= 0 ) + { + if( rInfo.mnCancelIndex >= aVbaArgs.getLength() ) + throw lang::IllegalArgumentException(); + aVbaArgs[ rInfo.mnCancelIndex ] <<= bCancel; + } + // execute the event handler + uno::Any aRet, aCaller; + bEventSuccess = executeMacro( mpShell, aMacroPath, aVbaArgs, aRet, aCaller ); + // extract new cancel value + if( rInfo.mnCancelIndex >= 0 ) + { + if( rInfo.mnCancelIndex >= aVbaArgs.getLength() ) + throw lang::IllegalArgumentException(); + // cancel value may be boolean or any integer type, Any(bool) does not extract to sal_Int32 + bool bNewCancel = false; + sal_Int32 nNewCancel = 0; + if( aVbaArgs[ rInfo.mnCancelIndex ] >>= bNewCancel ) + bCancel = bNewCancel; + else if( aVbaArgs[ rInfo.mnCancelIndex ] >>= nNewCancel ) + bCancel = nNewCancel != 0; + } + } + // post processing (also, if event handler does not exist, or on error + implPostProcessEvent( aEventQueue, rInfo, bEventSuccess, bCancel ); + // global success, if at least one event handler succeeded + bSuccess |= bEventSuccess; + } + } + + // if event handlers want to cancel the event, do so regardless of any errors + if( bCancel ) + throw util::VetoException(); + + // if no event handler finished successfully, throw + if( !bSuccess ) + throw script::provider::ScriptFrameworkErrorException(); +} + +void SAL_CALL VbaEventsHelperBase::disposing( const lang::EventObject& /*aSource*/ ) throw (uno::RuntimeException) +{ + OSL_TRACE( "VbaEventsHelperBase::disposing" ); + stopListening(); + mbDisposed = true; +} + +// protected ------------------------------------------------------------------ + +void VbaEventsHelperBase::registerEventHandler( sal_Int32 nEventId, + const sal_Char* pcMacroName, EventHandlerType eType, sal_Int32 nCancelIndex, const uno::Any& rUserData ) +{ + EventHandlerInfo& rInfo = maEvents[ nEventId ]; + rInfo.mnEventId = nEventId; + rInfo.maMacroName = ::rtl::OUString::createFromAscii( pcMacroName ); + rInfo.meType = eType; + rInfo.mnCancelIndex = nCancelIndex; + rInfo.maUserData = rUserData; +} + +// private -------------------------------------------------------------------- + +const VbaEventsHelperBase::EventHandlerInfo& VbaEventsHelperBase::getEventHandlerInfo( + sal_Int32 nEventId ) const throw (lang::IllegalArgumentException) +{ + EventHandlerMap::const_iterator aIt = maEvents.find( nEventId ); + if( aIt == maEvents.end() ) + throw lang::IllegalArgumentException(); + return aIt->second; +} + +::rtl::OUString VbaEventsHelperBase::getEventHandlerPath( const EventHandlerInfo& rInfo, + const uno::Sequence< uno::Any >& rArgs ) const throw (lang::IllegalArgumentException) +{ + ::rtl::OUString aMacroName; + switch( rInfo.meType ) + { + case EVENTHANDLER_GLOBAL: + aMacroName = rInfo.maMacroName; + break; + case EVENTHANDLER_DOCUMENT: + aMacroName = ::rtl::OUStringBuffer( implGetDocumentModuleName( rInfo, rArgs ) ). + append( sal_Unicode( '.' ) ).append( rInfo.maMacroName ).makeStringAndClear(); + break; + } + return resolveVBAMacro( mpShell, aMacroName ).ResolvedMacro(); +} + +void VbaEventsHelperBase::stopListening() +{ + if( !mbDisposed ) try + { + uno::Reference< lang::XComponent > xComponent( mxModel, uno::UNO_QUERY_THROW ); + xComponent->removeEventListener( this ); + } + catch( uno::Exception& ) + { + } +} + +// ============================================================================ diff --git a/vbahelper/source/vbahelper/vbaglobalbase.cxx b/vbahelper/source/vbahelper/vbaglobalbase.cxx index c7c33b93b1a3..e0df37583df5 100644 --- a/vbahelper/source/vbahelper/vbaglobalbase.cxx +++ b/vbahelper/source/vbahelper/vbaglobalbase.cxx @@ -35,22 +35,50 @@ using namespace ooo::vba; rtl::OUString sApplication( RTL_CONSTASCII_USTRINGPARAM("Application") ); +// special key to return the Application +rtl::OUString sAppService( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.Application") ); + VbaGlobalsBase::VbaGlobalsBase( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sDocCtxName ) -: Globals_BASE( xParent, xContext ) +: Globals_BASE( xParent, xContext ), msDocCtxName( sDocCtxName ) { // overwrite context with custom one ( that contains the application ) + // wrap the service manager as we don't want the disposing context to tear down the 'normal' ServiceManager ( or at least thats what the code appears like it wants to do ) + uno::Any aSrvMgr; + if ( xContext.is() && xContext->getServiceManager().is() ) + { + aSrvMgr = uno::makeAny( xContext->getServiceManager()->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.OServiceManagerWrapper") ), xContext ) ); + } + ::cppu::ContextEntry_Init aHandlerContextInfo[] = { ::cppu::ContextEntry_Init( sApplication, uno::Any() ), ::cppu::ContextEntry_Init( sDocCtxName, uno::Any() ), + ::cppu::ContextEntry_Init( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.lang.theServiceManager" ) ), aSrvMgr ) }; - - mxContext = ::cppu::createComponentContext( aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ), xContext ); - + // don't pass a delegate, this seems to introduce yet another cyclic dependency ( and + // some strange behavior + mxContext = ::cppu::createComponentContext( aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ), NULL ); } +VbaGlobalsBase::~VbaGlobalsBase() +{ + try + { + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + if ( xNameContainer.is() ) + { + // release document reference ( we don't wan't the component context trying to dispose that ) + xNameContainer->removeByName( msDocCtxName ); + // release application reference, as it is holding onto the context + xNameContainer->removeByName( sApplication ); + } + } + catch ( const uno::Exception& ) + { + } +} void VbaGlobalsBase::init( const uno::Sequence< beans::PropertyValue >& aInitArgs ) @@ -74,19 +102,30 @@ uno::Reference< uno::XInterface > SAL_CALL VbaGlobalsBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (uno::Exception, uno::RuntimeException) { uno::Reference< uno::XInterface > xReturn; - - if ( hasServiceName( aServiceSpecifier ) ) + if ( aServiceSpecifier.equals( sAppService ) ) + { + // try to extract the Application from the context + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + xNameContainer->getByName( sApplication ) >>= xReturn; + } + else if ( hasServiceName( aServiceSpecifier ) ) xReturn = mxContext->getServiceManager()->createInstanceWithContext( aServiceSpecifier, mxContext ); return xReturn; } uno::Reference< uno::XInterface > SAL_CALL -VbaGlobalsBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const uno::Sequence< uno::Any >& Arguments ) throw (uno::Exception, uno::RuntimeException) +VbaGlobalsBase::createInstanceWithArguments( const ::rtl::OUString& aServiceSpecifier, const uno::Sequence< uno::Any >& Arguments ) throw (uno::Exception, uno::RuntimeException) { uno::Reference< uno::XInterface > xReturn; - if ( hasServiceName( ServiceSpecifier ) ) - xReturn = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( ServiceSpecifier, Arguments, mxContext ); + if ( aServiceSpecifier.equals( sAppService ) ) + { + // try to extract the Application from the context + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + xNameContainer->getByName( sApplication ) >>= xReturn; + } + else if ( hasServiceName( aServiceSpecifier ) ) + xReturn = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( aServiceSpecifier, Arguments, mxContext ); return xReturn; } diff --git a/vbahelper/source/vbahelper/vbahelper.cxx b/vbahelper/source/vbahelper/vbahelper.cxx index 1953d0772f3c..14f4e3ff1363 100644 --- a/vbahelper/source/vbahelper/vbahelper.cxx +++ b/vbahelper/source/vbahelper/vbahelper.cxx @@ -625,6 +625,30 @@ void PrintOutHelper( SfxViewShell* pViewShell, const uno::Any& From, const uno:: dispatchExecute( pViewShell, SID_VIEWSHELL1 ); } +bool extractBoolFromAny( bool& rbValue, const uno::Any& rAny ) +{ + if( rAny >>= rbValue ) return true; + + sal_Int64 nSigned = 0; + if( rAny >>= nSigned ) { rbValue = nSigned != 0; return true; } + + sal_uInt64 nUnsigned = 0; + if( rAny >>= nUnsigned ) { rbValue = nUnsigned > 0; return true; } + + double fDouble = 0.0; + if( rAny >>= fDouble ) { rbValue = fDouble != 0.0; return true; } + + return false; +} + +bool extractBoolFromAny( const uno::Any& rAny ) throw (uno::RuntimeException) +{ + bool bValue = false; + if( extractBoolFromAny( bValue, rAny ) ) + return bValue; + throw uno::RuntimeException(); +} + rtl::OUString getAnyAsString( const uno::Any& pvargItem ) throw ( uno::RuntimeException ) { uno::Type aType = pvargItem.getValueType(); @@ -1404,6 +1428,26 @@ void UserFormGeometryHelper::setHeight( double nHeight ) return points; } + uno::Reference< uno::XInterface > getUnoDocModule( const String& aModName, SfxObjectShell* pShell ) + { + uno::Reference< uno::XInterface > xIf; + if ( pShell ) + { + rtl::OUString sProj( RTL_CONSTASCII_USTRINGPARAM("Standard") ); + BasicManager* pBasMgr = pShell->GetBasicManager(); + if ( pBasMgr && pBasMgr->GetName().Len() ) + sProj = pShell->GetBasicManager()->GetName(); + StarBASIC* pBasic = pShell->GetBasicManager()->GetLib( sProj ); + if ( pBasic ) + { + SbModule* pMod = pBasic->FindModule( aModName ); + if ( pMod ) + xIf = pMod->GetUnoModule(); + } + } + return xIf; + } + SfxObjectShell* getSfxObjShell( const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) { SfxObjectShell* pFoundShell = NULL; diff --git a/xmloff/inc/xmloff/xmltoken.hxx b/xmloff/inc/xmloff/xmltoken.hxx index d892c10f4f5d..f4843d54ace1 100644 --- a/xmloff/inc/xmloff/xmltoken.hxx +++ b/xmloff/inc/xmloff/xmltoken.hxx @@ -3107,6 +3107,9 @@ namespace xmloff { namespace token { XML_N_CHART_EXT, XML_COORDINATE_REGION, + XML_DIAGONAL_BL_TR_WIDTHS, + XML_DIAGONAL_TL_BR_WIDTHS, + XML_TOKEN_END }; diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 2e92c4a6a97d..a3d4a0c48d02 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -3107,6 +3107,9 @@ namespace xmloff { namespace token { TOKEN( "http://openoffice.org/2010/chart", XML_N_CHART_EXT ), TOKEN( "coordinate-region", XML_COORDINATE_REGION ), + TOKEN( "diagonal-bl-tr-widths", XML_DIAGONAL_BL_TR_WIDTHS ), + TOKEN( "diagonal-tl-br-widths", XML_DIAGONAL_TL_BR_WIDTHS ), + #if OSL_DEBUG_LEVEL > 0 { 0, NULL, NULL, XML_TOKEN_END } #else |