summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2004-03-17 12:35:23 +0000
committerOliver Bolte <obo@openoffice.org>2004-03-17 12:35:23 +0000
commit9cdb73ff28c4cd6380412468f34ff10e46292a07 (patch)
treed7c8f62808653da3317184495b1e6bb1103d6749 /basic
parentd4294c127ade247ffbc20619966f2a9360924d31 (diff)
INTEGRATION: CWS jl5vba (1.25.94); FILE MERGED
2004/01/20 15:48:58 ab 1.25.94.1: #111934# Merge to src680, for tasks see merge message for CWS ab02vba (1.25.6)
Diffstat (limited to 'basic')
-rw-r--r--basic/source/classes/sbunoobj.cxx413
1 files changed, 328 insertions, 85 deletions
diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx
index b127407c0ce2..a8c0181bf379 100644
--- a/basic/source/classes/sbunoobj.cxx
+++ b/basic/source/classes/sbunoobj.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: sbunoobj.cxx,v $
*
- * $Revision: 1.26 $
+ * $Revision: 1.27 $
*
- * last change: $Author: obo $ $Date: 2004-03-17 09:37:16 $
+ * last change: $Author: obo $ $Date: 2004-03-17 13:35:23 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -107,6 +107,10 @@
#include <com/sun/star/reflection/XIdlReflection.hpp>
#include <com/sun/star/reflection/XIdlClassProvider.hpp>
#include <com/sun/star/reflection/XTypeDescription.hpp>
+#include <com/sun/star/bridge/oleautomation/NamedArgument.hpp>
+#include <com/sun/star/bridge/oleautomation/Date.hpp>
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+#include <com/sun/star/bridge/oleautomation/Currency.hpp>
using namespace com::sun::star::uno;
@@ -115,6 +119,7 @@ using namespace com::sun::star::reflection;
using namespace com::sun::star::beans;
using namespace com::sun::star::script;
using namespace com::sun::star::container;
+using namespace com::sun::star::bridge;
using namespace cppu;
using namespace rtl;
@@ -251,6 +256,40 @@ Reference< XTypeConverter > getTypeConverter_Impl( void )
return xTypeConverter;
}
+
+// #111851 factory function to create an OLE object
+SbUnoObject* createOLEObject_Impl( const String& aType )
+{
+ static Reference< XMultiServiceFactory > xOLEFactory;
+ static bool bNeedsInit = true;
+
+ if( bNeedsInit )
+ {
+ bNeedsInit = false;
+
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
+ xOLEFactory = Reference<XMultiServiceFactory>(
+ xSMgr->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.OleObjectFactory")),
+ xContext ), UNO_QUERY );
+ }
+ }
+
+ SbUnoObject* pUnoObj = NULL;
+ if( xOLEFactory.is() )
+ {
+ Reference< XInterface > xOLEObject = xOLEFactory->createInstance( aType );
+ Any aAny;
+ aAny <<= xOLEObject;
+ pUnoObj = new SbUnoObject( aType, aAny );
+ }
+ return pUnoObj;
+}
+
+
String implGetExceptionMsg( Exception& e, const String& aExceptionType_ );
Any convertAny( const Any& rVal, const Type& aDestType )
@@ -445,6 +484,42 @@ void unoToSbxValue( SbxVariable* pVar, const Any& aValue )
case TypeClass_INTERFACE:
case TypeClass_STRUCT:
{
+ if( eTypeClass == TypeClass_STRUCT )
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ oleautomation::Date aDate;
+ if( (aValue >>= aDate) )
+ {
+ pVar->PutDate( aDate.Value );
+ break;
+ }
+ else
+ {
+ oleautomation::Decimal aDecimal;
+ if( (aValue >>= aDecimal) )
+ {
+ pVar->PutDecimal( aDecimal );
+ break;
+ }
+ else
+ {
+ oleautomation::Currency aCurrency;
+ if( (aValue >>= aCurrency) )
+ {
+ sal_Int64 nValue64 = aCurrency.Value;
+ SbxINT64 aInt64;
+ aInt64.nHigh = nValue64 >> 32;
+ aInt64.nLow = (UINT32)( nValue64 & 0xffffffff );
+ pVar->PutCurrency( aInt64 );
+ break;
+ }
+ }
+ }
+ }
+ }
+
// SbUnoObject instanzieren
String aName;
SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aValue );
@@ -579,8 +654,17 @@ Type getUnoTypeForSbxBaseType( SbxDataType eType )
case SbxLONG: aRetType = ::getCppuType( (sal_Int32*)0 ); break;
case SbxSINGLE: aRetType = ::getCppuType( (float*)0 ); break;
case SbxDOUBLE: aRetType = ::getCppuType( (double*)0 ); break;
- //case SbxCURRENCY: break;
- case SbxDATE: aRetType = ::getCppuType( (double*)0 ); break;
+ case SbxCURRENCY: aRetType = ::getCppuType( (oleautomation::Currency*)0 ); break;
+ case SbxDECIMAL: aRetType = ::getCppuType( (oleautomation::Decimal*)0 ); break;
+ case SbxDATE: {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ aRetType = ::getCppuType( (double*)0 );
+ else
+ aRetType = ::getCppuType( (oleautomation::Date*)0 );
+ }
+ break;
+ // case SbxDATE: aRetType = ::getCppuType( (double*)0 ); break;
case SbxSTRING: aRetType = ::getCppuType( (OUString*)0 ); break;
//case SbxOBJECT: break;
//case SbxERROR: break;
@@ -623,8 +707,9 @@ Type getUnoTypeForSbxValue( SbxValue* pVal )
SbxBaseRef xObj = (SbxBase*)pVal->GetObject();
if( !xObj )
{
- aRetType = ::getCppuType( (const Reference< XInterface > *)0 );
+ // #109936 No error any more
// StarBASIC::Error( SbERR_INVALID_OBJECT );
+ aRetType = getCppuType( static_cast<Reference<XInterface> *>(0) );
return aRetType;
}
@@ -703,7 +788,7 @@ Type getUnoTypeForSbxValue( SbxValue* pVal )
Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );
// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
-Any sbxToUnoValue( SbxVariable* pVar )
+Any sbxToUnoValueImpl( SbxVariable* pVar, bool bBlockConversionToSmallestType = false )
{
SbxDataType eBaseType = pVar->SbxValue::GetType();
if( eBaseType == SbxOBJECT )
@@ -716,62 +801,71 @@ Any sbxToUnoValue( SbxVariable* pVar )
Type aType = getUnoTypeForSbxValue( pVar );
TypeClass eType = aType.getTypeClass();
- // #79615 Choose "smallest" represention for int values
- // because up cast is allowed, downcast not
- switch( eType )
+ if( !bBlockConversionToSmallestType )
{
- case TypeClass_FLOAT:
- case TypeClass_DOUBLE:
+ // #79615 Choose "smallest" represention for int values
+ // because up cast is allowed, downcast not
+ switch( eType )
{
- double d = pVar->GetDouble();
- if( d == floor( d ) )
+ case TypeClass_FLOAT:
+ case TypeClass_DOUBLE:
+ {
+ double d = pVar->GetDouble();
+ if( d == floor( d ) )
+ {
+ if( d >= -128 && d <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ else if( d >= SbxMININT && d <= SbxMAXINT )
+ aType = ::getCppuType( (sal_Int16*)0 );
+ else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
+ aType = ::getCppuType( (sal_Int32*)0 );
+ }
+ break;
+ }
+ case TypeClass_SHORT:
+ {
+ sal_Int16 n = pVar->GetInteger();
+ if( n >= -128 && n <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ break;
+ }
+ case TypeClass_LONG:
{
- if( d >= -128 && d <= 127 )
+ sal_Int32 n = pVar->GetLong();
+ if( n >= -128 && n <= 127 )
aType = ::getCppuType( (sal_Int8*)0 );
- else if( d >= SbxMININT && d <= SbxMAXINT )
+ else if( n >= SbxMININT && n <= SbxMAXINT )
aType = ::getCppuType( (sal_Int16*)0 );
- else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
- aType = ::getCppuType( (sal_Int32*)0 );
+ break;
+ }
+ case TypeClass_UNSIGNED_SHORT:
+ {
+ sal_uInt16 n = pVar->GetUShort();
+ if( n <= 255 )
+ aType = ::getCppuType( (sal_uInt8*)0 );
+ break;
+ }
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 n = pVar->GetLong();
+ if( n <= 255 )
+ aType = ::getCppuType( (sal_uInt8*)0 );
+ else if( n <= SbxMAXUINT )
+ aType = ::getCppuType( (sal_uInt16*)0 );
+ break;
}
- break;
- }
- case TypeClass_SHORT:
- {
- sal_Int16 n = pVar->GetInteger();
- if( n >= -128 && n <= 127 )
- aType = ::getCppuType( (sal_Int8*)0 );
- break;
- }
- case TypeClass_LONG:
- {
- sal_Int32 n = pVar->GetLong();
- if( n >= -128 && n <= 127 )
- aType = ::getCppuType( (sal_Int8*)0 );
- else if( n >= SbxMININT && n <= SbxMAXINT )
- aType = ::getCppuType( (sal_Int16*)0 );
- break;
- }
- case TypeClass_UNSIGNED_SHORT:
- {
- sal_uInt16 n = pVar->GetUShort();
- if( n <= 255 )
- aType = ::getCppuType( (sal_uInt8*)0 );
- break;
- }
- case TypeClass_UNSIGNED_LONG:
- {
- sal_uInt32 n = pVar->GetLong();
- if( n <= 255 )
- aType = ::getCppuType( (sal_uInt8*)0 );
- else if( n <= SbxMAXUINT )
- aType = ::getCppuType( (sal_uInt16*)0 );
- break;
}
}
return sbxToUnoValue( pVar, aType );
}
+// Map old interface
+Any sbxToUnoValue( SbxVariable* pVar )
+{
+ return sbxToUnoValueImpl( pVar );
+}
+
// Konvertierung von Sbx nach Uno mit bekannter Zielklasse
Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty )
{
@@ -812,9 +906,51 @@ Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty
}
else
{
+ // #112368 Special conversion for Decimal, Currency and Date
+ if( eType == TypeClass_STRUCT )
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ if( rType == ::getCppuType( (oleautomation::Decimal*)0 ) )
+ {
+ oleautomation::Decimal aDecimal;
+ pVar->fillAutomationDecimal( aDecimal );
+ aRetVal <<= aDecimal;
+ break;
+ }
+ else if( rType == ::getCppuType( (oleautomation::Currency*)0 ) )
+ {
+ SbxINT64 aInt64 = pVar->GetCurrency();
+ oleautomation::Currency aCurrency;
+ sal_Int64& rnValue64 = aCurrency.Value;
+ rnValue64 = aInt64.nHigh;
+ rnValue64 <<= 32;
+ rnValue64 |= aInt64.nLow;
+ aRetVal <<= aCurrency;
+ break;
+ }
+ else if( rType == ::getCppuType( (oleautomation::Date*)0 ) )
+ {
+ oleautomation::Date aDate;
+ aDate.Value = pVar->GetDate();
+ aRetVal <<= aDate;
+ break;
+ }
+ }
+ }
+
SbxBaseRef pObj = (SbxBase*)pVar->GetObject();
if( pObj && pObj->ISA(SbUnoObject) )
+ {
aRetVal = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
+ }
+ else
+ {
+ // #109936 NULL object -> NULL XInterface
+ Reference<XInterface> xInt;
+ aRetVal <<= xInt;
+ }
}
}
break;
@@ -908,7 +1044,7 @@ Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty
// Bei Any die Klassen-unabhaengige Konvertierungs-Routine nutzen
case TypeClass_ANY:
{
- aRetVal = sbxToUnoValue( pVar );
+ aRetVal = sbxToUnoValueImpl( pVar );
}
break;
@@ -1110,6 +1246,7 @@ String Dbg_SbxDataType2String( SbxDataType eType )
case SbxSINGLE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSINGLE") ); break;
case SbxDOUBLE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDOUBLE") ); break;
case SbxCURRENCY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCURRENCY") ); break;
+ case SbxDECIMAL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDECIMAL") ); break;
case SbxDATE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATE") ); break;
case SbxSTRING: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSTRING") ); break;
case SbxOBJECT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxOBJECT") ); break;
@@ -1306,6 +1443,8 @@ String Impl_DumpMethods( const String& rClassName, SbUnoObject* pUnoObj )
return aRet;
}
+TYPEINIT1(AutomationNamedArgsSbxArray,SbxArray)
+
// Implementation SbUnoObject
void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
const SfxHint& rHint, const TypeId& rHintType )
@@ -1445,7 +1584,7 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
else if( mxInvocation.is() )
{
// Wert von Uno nach Sbx uebernehmen
- Any aAnyValue = sbxToUnoValue( pVar );
+ Any aAnyValue = sbxToUnoValueImpl( pVar );
try
{
// Wert setzen
@@ -1470,28 +1609,52 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
{
if( pHint->GetId() == SBX_HINT_DATAWANTED )
{
- UINT32 nParamCount = 0;
+ // Anzahl Parameter -1 wegen Param0 == this
+ UINT32 nParamCount = pParams ? ((UINT32)pParams->Count() - 1) : 0;
Sequence<Any> args;
BOOL bOutParams = FALSE;
UINT32 i;
- if( pParams )
- {
- // Anzahl Parameter -1 wegen Param0 == this
- nParamCount = (UINT32)pParams->Count() - 1;
- args.realloc( nParamCount );
- Any* pAnyArgs = args.getArray();
- if( mxUnoAccess.is() )
+ if( mxUnoAccess.is() )
+ {
+ // Infos holen
+ const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+ UINT32 nUnoParamCount = rInfoSeq.getLength();
+ UINT32 nAllocParamCount = nParamCount;
+
+ // Ueberschuessige Parameter ignorieren, Alternative: Error schmeissen
+ if( nParamCount > nUnoParamCount )
{
- // Infos holen
- const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
- const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
- UINT32 nUnoParamCount = rInfoSeq.getLength();
-
- // Ueberschuessige Parameter ignorieren, Alternative: Error schmeissen
- if( nParamCount > nUnoParamCount )
- nParamCount = nUnoParamCount;
+ nParamCount = nUnoParamCount;
+ nAllocParamCount = nParamCount;
+ }
+ else if( nParamCount < nUnoParamCount )
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ // Check types
+ bool bError = false;
+ for( i = nParamCount ; i < nUnoParamCount ; i++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[i];
+ const Reference< XIdlClass >& rxClass = rInfo.aType;
+ if( rxClass->getTypeClass() != TypeClass_ANY )
+ {
+ bError = true;
+ StarBASIC::Error( SbERR_NOT_OPTIONAL );
+ }
+ }
+ if( !bError )
+ nAllocParamCount = nUnoParamCount;
+ }
+ }
+ if( nAllocParamCount > 0 )
+ {
+ args.realloc( nAllocParamCount );
+ Any* pAnyArgs = args.getArray();
for( i = 0 ; i < nParamCount ; i++ )
{
const ParamInfo& rInfo = pParamInfos[i];
@@ -1512,12 +1675,54 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
}
}
}
- else if( mxInvocation.is() )
+ }
+ else if( pParams && mxInvocation.is() )
+ {
+ bool bOLEAutomation = true;
+ // TODO: bOLEAutomation = xOLEAutomation.is()
+
+ AutomationNamedArgsSbxArray* pArgNamesArray = NULL;
+ if( bOLEAutomation )
+ pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams);
+
+ args.realloc( nParamCount );
+ Any* pAnyArgs = args.getArray();
+ bool bBlockConversionToSmallestType = pINST->IsCompatibility();
+ if( pArgNamesArray )
+ {
+ Sequence< OUString >& rNameSeq = pArgNamesArray->getNames();
+ OUString* pNames = rNameSeq.getArray();
+
+ Any aValAny;
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ USHORT iSbx = (USHORT)(i+1);
+
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ aValAny = sbxToUnoValueImpl( pParams->Get( iSbx ),
+ bBlockConversionToSmallestType );
+
+ OUString aParamName = pNames[iSbx];
+ if( aParamName.getLength() )
+ {
+ oleautomation::NamedArgument aNamedArgument;
+ aNamedArgument.Name = aParamName;
+ aNamedArgument.Value = aValAny;
+ pAnyArgs[i] <<= aNamedArgument;
+ }
+ else
+ {
+ pAnyArgs[i] = aValAny;
+ }
+ }
+ }
+ else
{
for( i = 0 ; i < nParamCount ; i++ )
{
// ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
- pAnyArgs[i] = sbxToUnoValue( pParams->Get( (USHORT)(i+1) ) );
+ pAnyArgs[i] = sbxToUnoValueImpl( pParams->Get( (USHORT)(i+1) ),
+ bBlockConversionToSmallestType );
}
}
}
@@ -1828,13 +2033,40 @@ SbUnoMethod::~SbUnoMethod()
pNext->pPrev = pPrev;
}
+SbxInfo* SbUnoMethod::GetInfo()
+{
+ if( !pInfo && m_xUnoMethod.is() )
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ pInfo = new SbxInfo();
+
+ const Sequence<ParamInfo>& rInfoSeq = getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+ UINT32 nParamCount = rInfoSeq.getLength();
+
+ for( int i = 0 ; i < nParamCount ; i++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[i];
+ OUString aParamName = rInfo.aName;
+
+ // const Reference< XIdlClass >& rxClass = rInfo.aType;
+ SbxDataType t = SbxVARIANT;
+ USHORT nFlags = SBX_READ;
+ pInfo->AddParam( aParamName, t, nFlags );
+ }
+ }
+ }
+ return pInfo;
+}
+
const Sequence<ParamInfo>& SbUnoMethod::getParamInfos( void )
{
- if( !pParamInfoSeq )
+ if( !pParamInfoSeq && m_xUnoMethod.is() )
{
- Sequence<ParamInfo> aTmp = m_xUnoMethod->getParameterInfos() ;
+ Sequence<ParamInfo> aTmp = m_xUnoMethod->getParameterInfos() ;
pParamInfoSeq = new Sequence<ParamInfo>( aTmp );
- //pParamInfoSeq = new Sequence<ParamInfo>( m_xUnoMethod->getParameterInfos() );
}
return *pParamInfoSeq;
}
@@ -1985,19 +2217,30 @@ SbxVariable* SbUnoObject::Find( const XubString& rName, SbxClassType t )
}
else if( mxInvocation.is() )
{
- if( mxInvocation->hasProperty( aUName ) )
+ try
{
- // Property anlegen und reinbraten
- SbxVariableRef xVarRef = new SbUnoProperty( aUName, SbxVARIANT, aDummyProp, 0 );
- QuickInsert( (SbxVariable*)xVarRef );
- pRes = xVarRef;
+ if( mxInvocation->hasProperty( aUName ) )
+ {
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( aUName, SbxVARIANT, aDummyProp, 0 );
+ QuickInsert( (SbxVariable*)xVarRef );
+ pRes = xVarRef;
+ }
+ else if( mxInvocation->hasMethod( aUName ) )
+ {
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod );
+ QuickInsert( (SbxVariable*)xMethRef );
+ pRes = xMethRef;
+ }
}
- else if( mxInvocation->hasMethod( aUName ) )
+ catch( RuntimeException& e )
{
- // SbUnoMethode anlegen und reinbraten
- SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod );
- QuickInsert( (SbxVariable*)xMethRef );
- pRes = xMethRef;
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
}
}
}
@@ -2611,7 +2854,7 @@ void BasicAllListener_Impl::firing_impl( const AllEventObject& Event, Any* pRet
// #95792 Avoid a second call
USHORT nFlags = pVar->GetFlags();
pVar->SetFlag( SBX_NO_BROADCAST );
- *pRet = sbxToUnoValue( pVar );
+ *pRet = sbxToUnoValueImpl( pVar );
pVar->SetFlags( nFlags );
}
}
@@ -2920,7 +3163,7 @@ void RTL_Impl_CreateUnoValue( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite )
// Preconvert value
- Any aVal = sbxToUnoValue( pVal );
+ Any aVal = sbxToUnoValueImpl( pVal );
Any aConvertedVal = convertAny( aVal, aDestType );
/*