[ooo-build-commit] .: patches/dev300 patches/vba
Noel Power
noelp at kemper.freedesktop.org
Fri Aug 20 14:37:34 PDT 2010
patches/dev300/apply | 18
patches/vba/cws-vbasupportdev300-m2.diff |49817 ++++++++++++++++++++++
patches/vba/cws-vbasupportdev300.diff | 5168 --
patches/vba/vba-container-controls-m2.diff | 7950 +++
patches/vba/vba-container-controls.diff | 772
patches/vba/vba-oox-autocodename-m2.diff | 242
patches/vba/vba-oox-autocodename.diff | 80
patches/vba/vba-oox-olenameoverride-m2.diff | 465
patches/vba/vba-oox-olenameoverride.diff | 123
patches/vba/vba-use-ooxfilter-forcontrols-m2.diff | 623
patches/vba/vba-use-ooxfilter-forcontrols.diff | 50
11 files changed, 60200 insertions(+), 5108 deletions(-)
New commits:
commit c0c0ef14c7172c8d3143008c251e9cffc3e58eab
Author: Noel Power <noel.power at novell.com>
Date: Fri Aug 20 22:38:36 2010 +0100
commit vba patch adaption for m4
* patches/dev300/apply:
* patches/vba/cws-vbasupportdev300-m2.diff:
* patches/vba/cws-vbasupportdev300.diff:
* patches/vba/vba-container-controls-m2.diff:
* patches/vba/vba-container-controls.diff:
* patches/vba/vba-oox-autocodename-m2.diff:
* patches/vba/vba-oox-autocodename.diff:
* patches/vba/vba-oox-olenameoverride-m2.diff:
* patches/vba/vba-oox-olenameoverride.diff:
* patches/vba/vba-use-ooxfilter-forcontrols-m2.diff:
* patches/vba/vba-use-ooxfilter-forcontrols.diff:
diff --git a/patches/dev300/apply b/patches/dev300/apply
index 9a02d48..7d068a1 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -1566,6 +1566,9 @@ mono-climaker-bridgetest.diff
SectionOwner => noelpwer
# FIXME: half of the diff is somehow fixed to apply by pmladek
# few things need double checking
+[ VBAObjects < ooo330-m4 ]
+cws-vbasupportdev300-m2.diff
+[ VBAObjects >= ooo330-m4 ]
cws-vbasupportdev300.diff
# FIXME ooo330-m2 old version (m83) of the diff cws-vbasupportdev300_m83.diff, noelpwer
@@ -1573,6 +1576,9 @@ cws-vbasupportdev300.diff
# is disabled in vbasupportdev300 upstream )
cws-vbasupportdev300_m83-fix.diff, cbosdo
vba-enable-fieldrelatedbits.diff
+[ VBAObjects < ooo330-m4 ]
+vba-container-controls-m2.diff
+[ VBAObjects >= ooo330-m4 ]
vba-container-controls.diff
# need to adapt ooo-build wrt the changes intorduced into container_controls
oox-projectname-oobuild-specifix.diff
@@ -1580,9 +1586,15 @@ oox-projectname-oobuild-specifix.diff
oox-insert-module-bug.diff
# tweak oox filter to handle any passed generated code names
# there is a strange scenario with one cust doc where a code module is missing
+[ VBAObjects < ooo330-m4 ]
+vba-oox-autocodename-m2.diff, n#507768
+[ VBAObjects >= ooo330-m4 ]
vba-oox-autocodename.diff, n#507768
# tweak oox filter to handle strange scenario where there might be some
# missing codenmames in excel
+[ VBAObjects < ooo330-m4 ]
+vba-oox-olenameoverride-m2.diff, n#359933, n#403974
+[ VBAObjects >= ooo330-m4 ]
vba-oox-olenameoverride.diff, n#359933, n#403974
# fix strange ranges seperator regression problem
fix-name-range-separator.diff, n#597351
@@ -1591,10 +1603,16 @@ vbahelper-no-oox.diff
# misc changes to modify strange upstream changes
vba-misc-tweakupstream-m2.diff
# unoize msvbahelper to solve some dependency issues for split build
+# #FIXME disabled for m4
+[ VBAObjects < ooo330-m4 ]
vba-msvbahelper-splitbuilt.diff
+[VBAObjects]
# fix upstream introduced Application::Intersection problem
vba-fix-interesection.diff
# use oox filter exclusively for import of controls ( excel/word )
+[ VBAObjects < ooo330-m4 ]
+vba-use-ooxfilter-forcontrols-m2.diff
+[ VBAObjects >= ooo330-m4 ]
vba-use-ooxfilter-forcontrols.diff
# fix hlink & macro import/export for autoshapes and pictures
vba-fix-shapepic-hlinkmacro.diff
diff --git a/patches/vba/cws-vbasupportdev300-m2.diff b/patches/vba/cws-vbasupportdev300-m2.diff
new file mode 100644
index 0000000..e840c06
--- /dev/null
+++ b/patches/vba/cws-vbasupportdev300-m2.diff
@@ -0,0 +1,49817 @@
+diff --git basctl/source/basicide/baside2.cxx basctl/source/basicide/baside2.cxx
+index 1c9e37a..8d474c6 100644
+--- basctl/source/basicide/baside2.cxx
++++ basctl/source/basicide/baside2.cxx
+@@ -367,8 +367,9 @@ BOOL ModulWindow::BasicExecute()
+ }
+ else if ( !pMethod || ( nStart < nCurMethodStart ) )
+ {
++ nCurMethodStart = nStart;
+ pMethod = pM;
+- nCurMethodStart = nStart;
++ break;
+ }
+ }
+ if ( !pMethod )
+diff --git basctl/source/basicide/baside3.cxx basctl/source/basicide/baside3.cxx
+index e307720..fbd83c8 100644
+--- basctl/source/basicide/baside3.cxx
++++ basctl/source/basicide/baside3.cxx
+@@ -82,6 +82,7 @@
+ #include <com/sun/star/resource/XStringResourceResolver.hpp>
+ #include <com/sun/star/resource/StringResourceWithLocation.hpp>
+ #include <com/sun/star/task/XInteractionHandler.hpp>
++#include <com/sun/star/script/XVBACompat.hpp>
+
+ using namespace comphelper;
+ using namespace ::com::sun::star;
+@@ -112,8 +113,16 @@ DialogWindow::DialogWindow( Window* pParent, const ScriptDocument& rDocument, St
+ {
+ InitSettings( TRUE, TRUE, TRUE );
+
+- pEditor = new DlgEditor();
++ pEditor = new DlgEditor( rDocument.isDocument() ? rDocument.getDocument() : Reference< frame::XModel >() );
+ pEditor->SetWindow( this );
++ // set vba mode on DialogModel ( allows it to work in 100thmm instead of MAP_APPFONT )
++ if ( rDocument.isDocument() && rDocument.getDocument().is() )
++ {
++ uno::Reference< script::XVBACompat > xDocVBAMode( rDocument.getLibraryContainer( E_SCRIPTS ), uno::UNO_QUERY );
++ uno::Reference< script::XVBACompat > xDialogModelVBAMode( xDialogModel, uno::UNO_QUERY );
++ if ( xDocVBAMode.is() && xDialogModelVBAMode.is() )
++ xDialogModelVBAMode->setVBACompatModeOn( xDocVBAMode->getVBACompatModeOn() );
++ }
+ pEditor->SetDialog( xDialogModel );
+
+ // Undo einrichten
+@@ -728,7 +737,7 @@ BOOL DialogWindow::SaveDialog()
+ Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+- Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext );
++ Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, GetDocument().isDocument() ? GetDocument().getDocument() : Reference< frame::XModel >() );
+ Reference< XInputStream > xInput( xISP->createInputStream() );
+
+ Reference< XSimpleFileAccess > xSFI( xMSF->createInstance
+@@ -1010,7 +1019,7 @@ BOOL implImportDialog( Window* pWin, const String& rCurPath, const ScriptDocumen
+ Reference< beans::XPropertySet > xProps( xMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+- ::xmlscript::importDialogModel( xInput, xDialogModel, xContext );
++ ::xmlscript::importDialogModel( xInput, xDialogModel, xContext, rDocument.isDocument() ? rDocument.getDocument() : Reference< frame::XModel >() );
+
+ String aXmlDlgName;
+ Reference< beans::XPropertySet > xDialogModelPropSet( xDialogModel, UNO_QUERY );
+@@ -1236,7 +1245,7 @@ BOOL implImportDialog( Window* pWin, const String& rCurPath, const ScriptDocumen
+ }
+ }
+
+- Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext );
++ Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, rDocument.isDocument() ? rDocument.getDocument() : Reference< frame::XModel >() );
+ bool bSuccess = rDocument.insertDialog( aLibName, aNewDlgName, xISP );
+ if( bSuccess )
+ {
+@@ -1346,7 +1355,7 @@ void DialogWindow::StoreData()
+ Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+- Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext );
++ Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, GetDocument().isDocument() ? GetDocument().getDocument() : Reference< frame::XModel >() );
+ xLib->replaceByName( ::rtl::OUString( GetName() ), makeAny( xISP ) );
+ }
+ }
+diff --git basctl/source/basicide/basides3.cxx basctl/source/basicide/basides3.cxx
+index 1b71e43..6ec1dcd 100644
+--- basctl/source/basicide/basides3.cxx
++++ basctl/source/basicide/basides3.cxx
+@@ -96,7 +96,7 @@ DialogWindow* BasicIDEShell::CreateDlgWin( const ScriptDocument& rDocument, cons
+ Reference< beans::XPropertySet > xProps( xMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+- ::xmlscript::importDialogModel( xInput, xDialogModel, xContext );
++ ::xmlscript::importDialogModel( xInput, xDialogModel, xContext, rDocument.isDocument() ? rDocument.getDocument() : Reference< frame::XModel >() );
+ LocalizationMgr::setStringResourceAtDialog( rDocument, rLibName, aDlgName, xDialogModel );
+
+ // new dialog window
+diff --git basctl/source/basicide/moduldlg.cxx basctl/source/basicide/moduldlg.cxx
+index e2a2377..b00acdd 100644
+--- basctl/source/basicide/moduldlg.cxx
++++ basctl/source/basicide/moduldlg.cxx
+@@ -312,7 +312,7 @@ void BasicIDEShell::CopyDialogResources( Reference< io::XInputStreamProvider >&
+ Reference< beans::XPropertySet > xProps( xMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+- ::xmlscript::importDialogModel( xInput, xDialogModel, xContext );
++ ::xmlscript::importDialogModel( xInput, xDialogModel, xContext, rSourceDoc.isDocument() ? rSourceDoc.getDocument() : Reference< frame::XModel >() );
+
+ if( xDialogModel.is() )
+ {
+@@ -329,7 +329,7 @@ void BasicIDEShell::CopyDialogResources( Reference< io::XInputStreamProvider >&
+ {
+ LocalizationMgr::setResourceIDsForDialog( xDialogModel, xDestMgr );
+ }
+- io_xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext );
++ io_xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, rDestDoc.isDocument() ? rDestDoc.getDocument() : Reference< frame::XModel >() );
+ }
+ }
+
+diff --git basctl/source/basicide/scriptdocument.cxx basctl/source/basicide/scriptdocument.cxx
+index 5fc34d9..a35e58e 100644
+--- basctl/source/basicide/scriptdocument.cxx
++++ basctl/source/basicide/scriptdocument.cxx
+@@ -453,14 +453,12 @@ namespace basctl
+ bool ScriptDocument_Impl::isInVBAMode() const
+ {
+ bool bResult = false;
+-#ifdef FUTURE_VBA_CWS
+ if ( !isApplication() )
+ {
+ Reference< XVBACompat > xVBACompat( getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
+ if ( xVBACompat.is() )
+ bResult = xVBACompat->getVBACompatModeOn();
+ }
+-#endif
+ return bResult;
+ }
+
+@@ -678,7 +676,7 @@ namespace basctl
+ if ( !_rxExistingDialogModel.is() )
+ {
+ Reference< XInputStream > xInput( xISP->createInputStream(), UNO_QUERY_THROW );
+- ::xmlscript::importDialogModel( xInput, xDialogModel, aContext.getUNOContext() );
++ ::xmlscript::importDialogModel( xInput, xDialogModel, aContext.getUNOContext(), isDocument() ? getDocument() : Reference< XModel >() );
+ }
+
+ // set new name as property
+@@ -686,12 +684,12 @@ namespace basctl
+ xDlgPSet->setPropertyValue( DLGED_PROP_NAME, makeAny( _rNewName ) );
+
+ // export dialog model
+- xISP = ::xmlscript::exportDialogModel( xDialogModel, aContext.getUNOContext() );
++ xISP = ::xmlscript::exportDialogModel( xDialogModel, aContext.getUNOContext(), isDocument() ? getDocument() : Reference< XModel >() );
+ aElement <<= xISP;
+ }
+
+ // insert element by new name in container
+- else if ( _eType == E_SCRIPTS )
++ if ( _eType == E_SCRIPTS )
+ {
+ Reference< XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY );
+ if ( xVBAModuleInfo->hasModuleInfo( _rOldName ) )
+@@ -798,7 +796,7 @@ namespace basctl
+ xDlgPSet->setPropertyValue( DLGED_PROP_NAME, makeAny( _rDialogName ) );
+
+ // export dialog model
+- _out_rDialogProvider = ::xmlscript::exportDialogModel( xDialogModel, aContext.getUNOContext() );
++ _out_rDialogProvider = ::xmlscript::exportDialogModel( xDialogModel, aContext.getUNOContext(), isDocument() ? getDocument() : Reference< XModel >() );
+
+ // insert dialog into library
+ xLib->insertByName( _rDialogName, makeAny( _out_rDialogProvider ) );
+diff --git basctl/source/dlged/dlged.cxx basctl/source/dlged/dlged.cxx
+index 04bc7e5..020f934 100644
+--- basctl/source/dlged/dlged.cxx
++++ basctl/source/dlged/dlged.cxx
+@@ -205,7 +205,7 @@ BOOL DlgEditor::RemarkDialog()
+
+ //----------------------------------------------------------------------------
+
+-DlgEditor::DlgEditor()
++DlgEditor::DlgEditor( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel )
+ :pHScroll(NULL)
+ ,pVScroll(NULL)
+ ,pDlgEdModel(NULL)
+@@ -227,6 +227,7 @@ DlgEditor::DlgEditor()
+ ,bCreateOK(TRUE)
+ ,bDialogModelChanged(FALSE)
+ ,mnPaintGuard(0)
++ ,m_xDocument( xModel )
+ {
+ pDlgEdModel = new DlgEdModel();
+ pDlgEdModel->GetItemPool().FreezeIdRanges();
+@@ -835,7 +836,7 @@ void DlgEditor::Copy()
+ Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+- Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xClipDialogModel, xContext );
++ Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xClipDialogModel, xContext, m_xDocument );
+ Reference< XInputStream > xStream( xISP->createInputStream() );
+ Sequence< sal_Int8 > DialogModelBytes;
+ implCopyStreamToByteSequence( xStream, DialogModelBytes );
+@@ -868,7 +869,7 @@ void DlgEditor::Copy()
+ uno::Reference< resource::XStringResourceManager >
+ xStringResourceManager( xStringResourcePersistence, uno::UNO_QUERY );
+ LocalizationMgr::resetResourceForDialog( xClipDialogModel, xStringResourceManager );
+- Reference< XInputStreamProvider > xISP2 = ::xmlscript::exportDialogModel( xClipDialogModel, xContext );
++ Reference< XInputStreamProvider > xISP2 = ::xmlscript::exportDialogModel( xClipDialogModel, xContext, m_xDocument );
+ Reference< XInputStream > xStream2( xISP2->createInputStream() );
+ Sequence< sal_Int8 > NoResourceDialogModelBytes;
+ implCopyStreamToByteSequence( xStream2, NoResourceDialogModelBytes );
+@@ -1014,7 +1015,7 @@ void DlgEditor::Paste()
+ Reference< beans::XPropertySet > xProps( xMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+- ::xmlscript::importDialogModel( ::xmlscript::createInputStream( *((::rtl::ByteSequence*)(&DialogModelBytes)) ) , xClipDialogModel, xContext );
++ ::xmlscript::importDialogModel( ::xmlscript::createInputStream( *((::rtl::ByteSequence*)(&DialogModelBytes)) ) , xClipDialogModel, xContext, m_xDocument );
+ }
+
+ // get control models from clipboard dialog model
+diff --git basctl/source/dlged/dlgedobj.cxx basctl/source/dlged/dlgedobj.cxx
+index 50b54c6..a56985e 100644
+--- basctl/source/dlged/dlgedobj.cxx
++++ basctl/source/dlged/dlgedobj.cxx
+@@ -74,6 +74,22 @@ TYPEINIT1(DlgEdObj, SdrUnoObj);
+ DBG_NAME(DlgEdObj);
+
+ //----------------------------------------------------------------------------
++MapMode lcl_getMapModeForForm( DlgEdForm* pForm )
++{
++ MapMode aMode( MAP_APPFONT ); //Default
++ try
++ {
++ uno::Reference< beans::XPropertySet > xProps( pForm ? pForm->GetUnoControlModel() : NULL, uno::UNO_QUERY_THROW );
++ sal_Bool bVBAForm = sal_False;
++ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("VBAForm") ) ) >>= bVBAForm;
++ if ( bVBAForm )
++ aMode = MapMode( MAP_100TH_MM );
++ }
++ catch ( Exception& )
++ {
++ }
++ return aMode;
++}
+
+ DlgEdObj::DlgEdObj()
+ :SdrUnoObj(String(), sal_False)
+@@ -194,8 +210,9 @@ bool DlgEdObj::TransformSdrToControlCoordinates(
+ }
+
+ // convert pixel to logic units
+- aPos = pDevice->PixelToLogic( aPos, MapMode( MAP_APPFONT ) );
+- aSize = pDevice->PixelToLogic( aSize, MapMode( MAP_APPFONT ) );
++ MapMode aConvMode = lcl_getMapModeForForm( pForm );
++ aPos = pDevice->PixelToLogic( aPos, aConvMode );
++ aSize = pDevice->PixelToLogic( aSize, aConvMode );
+
+ // set out parameters
+ nXOut = aPos.Width();
+@@ -242,10 +259,10 @@ bool DlgEdObj::TransformSdrToFormCoordinates(
+ aSize.Width() -= aDeviceInfo.LeftInset + aDeviceInfo.RightInset;
+ aSize.Height() -= aDeviceInfo.TopInset + aDeviceInfo.BottomInset;
+ }
+-
++ MapMode aConvMode = lcl_getMapModeForForm( pForm );
+ // convert pixel to logic units
+- aPos = pDevice->PixelToLogic( aPos, MapMode( MAP_APPFONT ) );
+- aSize = pDevice->PixelToLogic( aSize, MapMode( MAP_APPFONT ) );
++ aPos = pDevice->PixelToLogic( aPos, aConvMode );
++ aSize = pDevice->PixelToLogic( aSize, aConvMode );
+
+ // set out parameters
+ nXOut = aPos.Width();
+@@ -287,9 +304,10 @@ bool DlgEdObj::TransformControlToSdrCoordinates(
+ DBG_ASSERT( pDevice, "DlgEdObj::TransformControlToSdrCoordinates: missing default device!" );
+ if ( !pDevice )
+ return false;
+- aPos = pDevice->LogicToPixel( aPos, MapMode( MAP_APPFONT ) );
+- aSize = pDevice->LogicToPixel( aSize, MapMode( MAP_APPFONT ) );
+- aFormPos = pDevice->LogicToPixel( aFormPos, MapMode( MAP_APPFONT ) );
++ MapMode aConvMode = lcl_getMapModeForForm( pForm );
++ aPos = pDevice->LogicToPixel( aPos, aConvMode );
++ aSize = pDevice->LogicToPixel( aSize, aConvMode );
++ aFormPos = pDevice->LogicToPixel( aFormPos, aConvMode );
+
+ // add form position
+ aPos.Width() += aFormPos.Width();
+@@ -333,14 +351,16 @@ bool DlgEdObj::TransformFormToSdrCoordinates(
+ DBG_ASSERT( pDevice, "DlgEdObj::TransformFormToSdrCoordinates: missing default device!" );
+ if ( !pDevice )
+ return false;
+- aPos = pDevice->LogicToPixel( aPos, MapMode( MAP_APPFONT ) );
+- aSize = pDevice->LogicToPixel( aSize, MapMode( MAP_APPFONT ) );
+
+ // take window borders into account
+ DlgEdForm* pForm = NULL;
+ if ( !lcl_getDlgEdForm( this, pForm ) )
+ return false;
+
++ MapMode aConvMode = lcl_getMapModeForForm( pForm );
++ aPos = pDevice->LogicToPixel( aPos, aConvMode );
++ aSize = pDevice->LogicToPixel( aSize, aConvMode );
++
+ // take window borders into account
+ Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
+ DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
+diff --git basctl/source/inc/dlged.hxx basctl/source/inc/dlged.hxx
+index a8adcda..a2ea57c 100644
+--- basctl/source/inc/dlged.hxx
++++ basctl/source/inc/dlged.hxx
+@@ -32,6 +32,7 @@
+ #include <com/sun/star/awt/XControlContainer.hpp>
+ #include <com/sun/star/datatransfer/DataFlavor.hpp>
+ #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
++#include <com/sun/star/frame/XModel.hpp>
+ #include <tools/link.hxx>
+ #include <tools/gen.hxx>
+ #include <vcl/timer.hxx>
+@@ -128,9 +129,11 @@ protected:
+ BOOL bDialogModelChanged;
+ Timer aMarkTimer;
+ long mnPaintGuard;
++ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > m_xDocument;
+
++ DlgEditor(); // not implemented
+ public:
+- DlgEditor();
++ DlgEditor( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel );
+ ~DlgEditor();
+
+ void SetWindow( Window* pWindow );
+diff --git basic/inc/basic/basmgr.hxx basic/inc/basic/basmgr.hxx
+index 886aa7f..58cf623 100644
+--- basic/inc/basic/basmgr.hxx
++++ basic/inc/basic/basmgr.hxx
+@@ -236,7 +236,7 @@ public:
+ takes the names of modules whose size exceeds the legacy limit
+ */
+ bool LegacyPsswdBinaryLimitExceeded( ::com::sun::star::uno::Sequence< rtl::OUString >& _out_rModuleNames );
+-
++ bool HasExeCode( const String& );
+ private:
+ BOOL IsReference( USHORT nLib );
+
+diff --git basic/inc/basic/sbmeth.hxx basic/inc/basic/sbmeth.hxx
+index 38319ac..89f88da 100644
+--- basic/inc/basic/sbmeth.hxx
++++ basic/inc/basic/sbmeth.hxx
+@@ -46,6 +46,7 @@ class SbMethod : public SbxMethod
+ friend class SbIfaceMapperMethod;
+
+ SbMethodImpl* mpSbMethodImpl; // Impl data
++ SbxVariable* mCaller; // caller
+ SbModule* pMod;
+ USHORT nDebugFlags;
+ USHORT nLine1, nLine2;
+@@ -72,7 +73,7 @@ public:
+ void GetLineRange( USHORT&, USHORT& );
+
+ // Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
+- virtual ErrCode Call( SbxValue* pRet = NULL );
++ virtual ErrCode Call( SbxValue* pRet = NULL, SbxVariable* pCaller = NULL );
+ virtual void Broadcast( ULONG nHintId );
+ };
+
+diff --git basic/inc/basic/sbmod.hxx basic/inc/basic/sbmod.hxx
+index 7f401ef..d818589 100644
+--- basic/inc/basic/sbmod.hxx
++++ 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;
+@@ -55,8 +57,12 @@ class SbModule : public SbxObject
+ friend class SbClassModuleObject;
+
+ SbModuleImpl* mpSbModuleImpl; // Impl data
++ std::vector< String > mModuleVariableNames;
++ SbModule();
++ SbModule(const SbModule&);
+
+ protected:
++ com::sun::star::uno::Reference< com::sun::star::script::XInvocation > mxWrapper;
+ ::rtl::OUString aOUSource;
+ String aComment;
+ SbiImage* pImage; // the Image
+@@ -126,12 +132,16 @@ public:
+ BOOL LoadBinaryData( SvStream& );
+ BOOL ExceedsLegacyModuleSize();
+ void fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg = NULL ) const;
++ bool HasExeCode();
+ BOOL IsVBACompat() const;
+ void SetVBACompat( BOOL bCompat );
+ INT32 GetModuleType() { return mnType; }
+ void SetModuleType( INT32 nType ) { mnType = nType; }
+ bool GetIsProxyModule() { return bIsProxyModule; }
+ bool createCOMWrapperForIface( ::com::sun::star::uno::Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject );
++ void AddVarName( const String& aName );
++ void RemoveVars();
++ ::com::sun::star::uno::Reference< ::com::sun::star::script::XInvocation > GetUnoModule();
+ };
+
+ #ifndef __SB_SBMODULEREF_HXX
+diff --git basic/inc/basic/sbuno.hxx basic/inc/basic/sbuno.hxx
+index 27fe320..c5e0209 100644
+--- basic/inc/basic/sbuno.hxx
++++ basic/inc/basic/sbuno.hxx
+@@ -38,6 +38,7 @@ SbxObjectRef GetSbUnoObject( const String& aName, const com::sun::star::uno::Any
+
+ // Force creation of all properties for debugging
+ void createAllObjectProperties( SbxObject* pObj );
++void SetSbUnoObjectDfltPropName( SbxObject* pObj );
+
+ ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
+
+diff --git basic/source/basmgr/basmgr.cxx basic/source/basmgr/basmgr.cxx
+index 247a833..d674dd4 100644
+--- basic/source/basmgr/basmgr.cxx
++++ basic/source/basmgr/basmgr.cxx
+@@ -1139,6 +1139,25 @@ void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager )
+ _rpManager = NULL;
+ }
+
++
++bool BasicManager::HasExeCode( const String& sLib )
++{
++ StarBASIC* pLib = GetLib(sLib);
++ if ( pLib )
++ {
++ SbxArray* pMods = pLib->GetModules();
++ USHORT nMods = pMods ? pMods->Count() : 0;
++ for( USHORT i = 0; i < nMods; i++ )
++ {
++ SbModule* p = (SbModule*) pMods->Get( i );
++ if ( p )
++ if ( p->HasExeCode() )
++ return true;
++ }
++ }
++ return false;
++}
++
+ void BasicManager::Init()
+ {
+ DBG_CHKTHIS( BasicManager, 0 );
+diff --git basic/source/classes/sb.cxx basic/source/classes/sb.cxx
+index 9be441e..ce29137 100755
+--- basic/source/classes/sb.cxx
++++ basic/source/classes/sb.cxx
+@@ -584,72 +584,7 @@ SbClassModuleObject::~SbClassModuleObject()
+ void SbClassModuleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+ {
+- bool bDone = false;
+-
+- const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+- if( pHint )
+- {
+- SbxVariable* pVar = pHint->GetVar();
+- SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar );
+- if( pProcProperty )
+- {
+- bDone = true;
+-
+- if( pHint->GetId() == SBX_HINT_DATAWANTED )
+- {
+- String aProcName;
+- aProcName.AppendAscii( "Property Get " );
+- aProcName += pProcProperty->GetName();
+-
+- SbxVariable* pMeth = Find( aProcName, SbxCLASS_METHOD );
+- if( pMeth )
+- {
+- SbxValues aVals;
+- aVals.eType = SbxVARIANT;
+- pMeth->Get( aVals );
+- pVar->Put( aVals );
+- }
+- }
+- else if( pHint->GetId() == SBX_HINT_DATACHANGED )
+- {
+- SbxVariable* pMeth = NULL;
+-
+- bool bSet = pProcProperty->isSet();
+- if( bSet )
+- {
+- pProcProperty->setSet( false );
+-
+- String aProcName;
+- aProcName.AppendAscii( "Property Set " );
+- aProcName += pProcProperty->GetName();
+- pMeth = Find( aProcName, SbxCLASS_METHOD );
+- }
+- if( !pMeth ) // Let
+- {
+- String aProcName;
+- aProcName.AppendAscii( "Property Let " );
+- aProcName += pProcProperty->GetName();
+- pMeth = Find( aProcName, SbxCLASS_METHOD );
+- }
+-
+- if( pMeth )
+- {
+- // Setup parameters
+- SbxArrayRef xArray = new SbxArray;
+- xArray->Put( pMeth, 0 ); // Method as parameter 0
+- xArray->Put( pVar, 1 );
+- pMeth->SetParameters( xArray );
+-
+- SbxValues aVals;
+- pMeth->Get( aVals );
+- pMeth->SetParameters( NULL );
+- }
+- }
+- }
+- }
+-
+- if( !bDone )
+- SbModule::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
++ SbModule::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+
+ SbxVariable* SbClassModuleObject::Find( const XubString& rName, SbxClassType t )
+@@ -1079,7 +1014,6 @@ SbxVariable* StarBASIC::Find( const String& rName, SbxClassType t )
+ INT32 nType = p->GetModuleType();
+ if ( nType == ModuleType::DOCUMENT || nType == ModuleType::FORM )
+ continue;
+-
+ // otherwise check if the element is available
+ // unset GBLSEARCH-Flag (due to Rekursion)
+ USHORT nGblFlag = p->GetFlags() & SBX_GBLSEARCH;
+diff --git basic/source/classes/sbunoobj.cxx basic/source/classes/sbunoobj.cxx
+index 291aaa4..b66e9f4 100755
+--- basic/source/classes/sbunoobj.cxx
++++ basic/source/classes/sbunoobj.cxx
+@@ -61,6 +61,7 @@
+ #include <com/sun/star/script/XInvocationAdapterFactory.hpp>
+ #include <com/sun/star/script/XTypeConverter.hpp>
+ #include <com/sun/star/script/XDefaultProperty.hpp>
++#include <com/sun/star/script/XDefaultMethod.hpp>
+ #include <com/sun/star/container/XNameAccess.hpp>
+ #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+ #include <com/sun/star/reflection/XIdlArray.hpp>
+@@ -71,7 +72,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/script/XAutomationInvocation.hpp>
+
+ using com::sun::star::uno::Reference;
+ using namespace com::sun::star::uno;
+@@ -157,6 +158,21 @@ SbxVariable* getDefaultProp( SbxVariable* pRef )
+ return pDefaultProp;
+ }
+
++void SetSbUnoObjectDfltPropName( SbxObject* pObj )
++{
++ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*) pObj);
++ if ( pUnoObj )
++ {
++ String sDfltPropName;
++
++ if ( SbUnoObject::getDefaultPropName( pUnoObj, sDfltPropName ) )
++ {
++ OSL_TRACE("SetSbUnoObjectDfltPropName setting dflt prop for %s", rtl::OUStringToOString( pObj->GetName(), RTL_TEXTENCODING_UTF8 ).getStr() );
++ pUnoObj->SetDfltProperty( sDfltPropName );
++ }
++ }
++}
++
+ Reference< XComponentContext > getComponentContext_Impl( void )
+ {
+ static Reference< XComponentContext > xContext;
+@@ -453,6 +469,32 @@ void implHandleWrappedTargetException( const Any& _rWrappedTargetException )
+ SbError nError( ERRCODE_BASIC_EXCEPTION );
+ ::rtl::OUStringBuffer aMessageBuf;
+
++ // Add for VBA, to get the correct error code and message.
++ if ( SbiRuntime::isVBAEnabled() )
++ {
++ if ( aExamine >>= aBasicError )
++ {
++ if ( aBasicError.ErrorCode != 0 )
++ {
++ nError = StarBASIC::GetSfxFromVBError( (USHORT) aBasicError.ErrorCode );
++ if ( nError == 0 )
++ {
++ nError = (SbError) aBasicError.ErrorCode;
++ }
++ aMessageBuf.append( aBasicError.ErrorMessageArgument );
++ aExamine.clear();
++ }
++ }
++
++ IndexOutOfBoundsException aIdxOutBndsExp;
++ if ( aExamine >>= aIdxOutBndsExp )
++ {
++ nError = SbERR_OUT_OF_RANGE;
++ aExamine.clear();
++ }
++ }
++ // End add
++
+ // strip any other WrappedTargetException instances, but this time preserve the error messages.
+ WrappedTargetException aWrapped;
+ sal_Int32 nLevel = 0;
+@@ -1502,6 +1544,103 @@ Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty
+ return aRetVal;
+ }
+
++void processAutomationParams( SbxArray* pParams, Sequence< Any >& args, bool bOLEAutomation, UINT32 nParamCount )
++{
++ AutomationNamedArgsSbxArray* pArgNamesArray = NULL;
++ if( bOLEAutomation )
++ pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams);
++
++ args.realloc( nParamCount );
++ Any* pAnyArgs = args.getArray();
++ bool bBlockConversionToSmallestType = pINST->IsCompatibility();
++ UINT32 i = 0;
++ if( pArgNamesArray )
++ {
++ Sequence< ::rtl::OUString >& rNameSeq = pArgNamesArray->getNames();
++ ::rtl::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 );
++
++ ::rtl::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] = sbxToUnoValueImpl( pParams->Get( (USHORT)(i+1) ),
++ bBlockConversionToSmallestType );
++ }
++ }
++
++}
++enum INVOKETYPE
++{
++ GetProp = 0,
++ SetProp,
++ Func
++};
++Any invokeAutomationMethod( const String& Name, Sequence< Any >& args, SbxArray* pParams, UINT32 nParamCount, Reference< XInvocation >& rxInvocation, INVOKETYPE invokeType = Func )
++{
++ Sequence< INT16 > OutParamIndex;
++ Sequence< Any > OutParam;
++
++ Any aRetAny;
++ switch( invokeType )
++ {
++ case Func:
++ aRetAny = rxInvocation->invoke( Name, args, OutParamIndex, OutParam );
++ break;
++ case GetProp:
++ {
++ Reference< XAutomationInvocation > xAutoInv( rxInvocation, UNO_QUERY );
++ aRetAny = xAutoInv->invokeGetProperty( Name, args, OutParamIndex, OutParam );
++ break;
++ }
++ case SetProp:
++ {
++ Reference< XAutomationInvocation > xAutoInv( rxInvocation, UNO_QUERY_THROW );
++ aRetAny = xAutoInv->invokePutProperty( Name, args, OutParamIndex, OutParam );
++ break;
++ }
++ default:
++ break; // should introduce an error here
++
++ }
++ const INT16* pIndices = OutParamIndex.getConstArray();
++ UINT32 nLen = OutParamIndex.getLength();
++ if( nLen )
++ {
++ const Any* pNewValues = OutParam.getConstArray();
++ for( UINT32 j = 0 ; j < nLen ; j++ )
++ {
++ INT16 iTarget = pIndices[ j ];
++ if( iTarget >= (INT16)nParamCount )
++ break;
++ unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pNewValues[ j ] );
++ }
++ }
++ return aRetAny;
++}
++
+ // Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
+ String Impl_GetInterfaceInfo( const Reference< XInterface >& x, const Reference< XIdlClass >& xClass, USHORT nRekLevel )
+ {
+@@ -2008,11 +2147,26 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ {
+ try
+ {
+- // Wert holen
+- Any aRetAny = mxInvocation->getValue( pProp->GetName() );
++ UINT32 nParamCount = pParams ? ((UINT32)pParams->Count() - 1) : 0;
++ sal_Bool bCanBeConsideredAMethod = mxInvocation->hasMethod( pProp->GetName() );
++ Any aRetAny;
++ if ( bCanBeConsideredAMethod && nParamCount )
++ {
++ // Automation properties have methods, so.. we need to invoke this through
++ // XInvocation
++ Sequence<Any> args;
++ processAutomationParams( pParams, args, true, nParamCount );
++ aRetAny = invokeAutomationMethod( pProp->GetName(), args, pParams, nParamCount, mxInvocation, GetProp );
++ }
++ else
++ // Wert holen
++ aRetAny = mxInvocation->getValue( pProp->GetName() );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
++ if( pParams && bCanBeConsideredAMethod )
++ pVar->SetParameters( NULL );
++
+ }
+ catch( const Exception& )
+ {
+@@ -2137,52 +2291,7 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ else if( bInvocation && 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< ::rtl::OUString >& rNameSeq = pArgNamesArray->getNames();
+- ::rtl::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 );
+-
+- ::rtl::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] = sbxToUnoValueImpl( pParams->Get( (USHORT)(i+1) ),
+- bBlockConversionToSmallestType );
+- }
+- }
++ processAutomationParams( pParams, args, bOLEAutomation, nParamCount );
+ }
+
+ // Methode callen
+@@ -2217,26 +2326,8 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+- Sequence< INT16 > OutParamIndex;
+- Sequence< Any > OutParam;
+- Any aRetAny = mxInvocation->invoke( pMeth->GetName(), args, OutParamIndex, OutParam );
+-
+- // Wert von Uno nach Sbx uebernehmen
++ Any aRetAny = invokeAutomationMethod( pMeth->GetName(), args, pParams, nParamCount, mxInvocation );
+ unoToSbxValue( pVar, aRetAny );
+-
+- const INT16* pIndices = OutParamIndex.getConstArray();
+- UINT32 nLen = OutParamIndex.getLength();
+- if( nLen )
+- {
+- const Any* pNewValues = OutParam.getConstArray();
+- for( UINT32 j = 0 ; j < nLen ; j++ )
+- {
+- INT16 iTarget = pIndices[ j ];
+- if( iTarget >= (INT16)nParamCount )
+- break;
+- unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pNewValues[ j ] );
+- }
+- }
+ }
+
+ // #55460, Parameter hier weghauen, da das in unoToSbxValue()
+@@ -3165,11 +3256,16 @@ getTypeDescriptorEnumeration( const ::rtl::OUString& sSearchRoot,
+
+ typedef std::hash_map< ::rtl::OUString, Any, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > VBAConstantsHash;
+
+-SbxVariable* getVBAConstant( const String& rName )
++VBAConstantHelper&
++VBAConstantHelper::instance()
++{
++ static VBAConstantHelper aHelper;
++ return aHelper;
++}
++
++void
++VBAConstantHelper::init()
+ {
+- SbxVariable* pConst = NULL;
+- static VBAConstantsHash aConstCache;
+- static bool isInited = false;
+ if ( !isInited )
+ {
+ Sequence< TypeClass > types(1);
+@@ -3177,39 +3273,77 @@ SbxVariable* getVBAConstant( const String& rName )
+ Reference< XTypeDescriptionEnumeration > xEnum = getTypeDescriptorEnumeration( defaultNameSpace, types, TypeDescriptionSearchDepth_INFINITE );
+
+ if ( !xEnum.is() )
+- return NULL;
++ return; //NULL;
+
+ while ( xEnum->hasMoreElements() )
+ {
+ Reference< XConstantsTypeDescription > xConstants( xEnum->nextElement(), UNO_QUERY );
+ if ( xConstants.is() )
+ {
++ // store constant group name
++ ::rtl::OUString sFullName = xConstants->getName();
++ sal_Int32 indexLastDot = sFullName.lastIndexOf('.');
++ ::rtl::OUString sLeafName( sFullName );
++ if ( indexLastDot > -1 )
++ sLeafName = sFullName.copy( indexLastDot + 1);
++ aConstCache.push_back( sLeafName ); // assume constant group names are unique
+ Sequence< Reference< XConstantTypeDescription > > aConsts = xConstants->getConstants();
+ Reference< XConstantTypeDescription >* pSrc = aConsts.getArray();
+ sal_Int32 nLen = aConsts.getLength();
+ for ( sal_Int32 index =0; index<nLen; ++pSrc, ++index )
+ {
++ // store constant member name
+ Reference< XConstantTypeDescription >& rXConst =
+ *pSrc;
+- ::rtl::OUString sFullName = rXConst->getName();
+- sal_Int32 indexLastDot = sFullName.lastIndexOf('.');
+- ::rtl::OUString sLeafName;
++ sFullName = rXConst->getName();
++ indexLastDot = sFullName.lastIndexOf('.');
++ sLeafName = sFullName;
+ if ( indexLastDot > -1 )
+ sLeafName = sFullName.copy( indexLastDot + 1);
+- aConstCache[ sLeafName.toAsciiLowerCase() ] = rXConst->getConstantValue();
++ aConstHash[ sLeafName.toAsciiLowerCase() ] = rXConst->getConstantValue();
+ }
+ }
+ }
+ isInited = true;
+ }
++}
++
++bool
++VBAConstantHelper::isVBAConstantType( const String& rName )
++{
++ init();
++ bool bConstant = false;
++ ::rtl::OUString sKey( rName );
++ VBAConstantsVector::const_iterator it = aConstCache.begin();
++
++ for( ; it != aConstCache.end(); it++ )
++ {
++ if( sKey.equalsIgnoreAsciiCase( *it ) )
++ {
++ bConstant = true;
++ break;
++ }
++ }
++ return bConstant;
++}
++
++SbxVariable*
++VBAConstantHelper::getVBAConstant( const String& rName )
++{
++ SbxVariable* pConst = NULL;
++ init();
++
+ ::rtl::OUString sKey( rName );
+- VBAConstantsHash::const_iterator it = aConstCache.find( sKey.toAsciiLowerCase() );
+- if ( it != aConstCache.end() )
++
++ VBAConstantsHash::const_iterator it = aConstHash.find( sKey.toAsciiLowerCase() );
++
++ if ( it != aConstHash.end() )
+ {
+ pConst = new SbxVariable( SbxVARIANT );
+ pConst->SetName( rName );
+ unoToSbxValue( pConst, it->second );
+ }
++
+ return pConst;
+ }
+
+diff --git basic/source/classes/sbxmod.cxx basic/source/classes/sbxmod.cxx
+index 79ab207..6e8e724 100644
+--- basic/source/classes/sbxmod.cxx
++++ basic/source/classes/sbxmod.cxx
+@@ -85,6 +85,361 @@ using namespace com::sun::star;
+ #include <com/sun/star/awt/XControl.hpp>
+ #include <cppuhelper/implbase1.hxx>
+ #include <comphelper/anytostring.hxx>
++#include <com/sun/star/document/XVbaMethodParameter.hpp> //liuchen 2009-7-21
++#include <com/sun/star/beans/XPropertySet.hpp>
++
++extern void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue ); //liuchen 2009-7-21
++extern ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar ); //liuchen 2009-7-21
++
++#include <com/sun/star/frame/XDesktop.hpp>
++#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;
++
++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 );
++ ~DocObjectWrapper();
++
++ virtual void SAL_CALL acquire() throw();
++ virtual void SAL_CALL release() throw();
++
++ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId()
++ throw ( com::sun::star::uno::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 )
++ {
++ sal_Int16 nType = pMod->GetModuleType();
++ 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)
+@@ -151,7 +506,6 @@ IMPL_LINK( AsyncQuitHandler, OnAsyncQuit, void*, /*pNull*/ )
+ return 0L;
+ }
+
+-#if 0
+ bool UnlockControllerHack( StarBASIC* pBasic )
+ {
+ bool bRes = false;
+@@ -177,7 +531,7 @@ bool UnlockControllerHack( StarBASIC* pBasic )
+ }
+ return bRes;
+ }
+-#endif
++
+ /////////////////////////////////////////////////////////////////////////////
+
+ // Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen
+@@ -199,14 +553,25 @@ 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
+ {
+ return BOOL( pImage != 0 );
+@@ -434,6 +799,64 @@ void SbModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ SbxVariable* pVar = pHint->GetVar();
+ SbProperty* pProp = PTR_CAST(SbProperty,pVar);
+ SbMethod* pMeth = PTR_CAST(SbMethod,pVar);
++ SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar );
++ if( pProcProperty )
++ {
++ if( pHint->GetId() == SBX_HINT_DATAWANTED )
++ {
++ String aProcName;
++ aProcName.AppendAscii( "Property Get " );
++ aProcName += pProcProperty->GetName();
++
++ SbxVariable* pPropMeth = Find( aProcName, SbxCLASS_METHOD );
++ if( pPropMeth )
++ {
++ // Setup parameters
++ pPropMeth->SetParameters( pVar->GetParameters() );
++
++ SbxValues aVals;
++ aVals.eType = SbxVARIANT;
++ pPropMeth->Get( aVals );
++ pVar->Put( aVals );
++ }
++ }
++ else if( pHint->GetId() == SBX_HINT_DATACHANGED )
++ {
++ SbxVariable* pPropMeth = NULL;
++
++ bool bSet = pProcProperty->isSet();
++ if( bSet )
++ {
++ pProcProperty->setSet( false );
++
++ String aProcName;
++ aProcName.AppendAscii( "Property Set " );
++ aProcName += pProcProperty->GetName();
++ pPropMeth = Find( aProcName, SbxCLASS_METHOD );
++ }
++ if( !pPropMeth ) // Let
++ {
++ String aProcName;
++ aProcName.AppendAscii( "Property Let " );
++ aProcName += pProcProperty->GetName();
++ pPropMeth = Find( aProcName, SbxCLASS_METHOD );
++ }
++
++ if( pPropMeth )
++ {
++ // Setup parameters
++ SbxArrayRef xArray = new SbxArray;
++ xArray->Put( pPropMeth, 0 ); // Method as parameter 0
++ xArray->Put( pVar, 1 );
++ pPropMeth->SetParameters( xArray );
++
++ SbxValues aVals;
++ pPropMeth->Get( aVals );
++ pPropMeth->SetParameters( NULL );
++ }
++ }
++ }
++
+ if( pProp )
+ {
+ if( pProp->GetModule() != this )
+@@ -488,6 +911,7 @@ void SbModule::SetSource32( const ::rtl::OUString& r )
+ aOUSource = r;
+ StartDefinitions();
+ SbiTokenizer aTok( r );
++ aTok.SetCompatible( IsVBACompat() );
+ while( !aTok.IsEof() )
+ {
+ SbiToken eEndTok = NIL;
+@@ -675,12 +1099,14 @@ void SbModule::SetVBACompat( BOOL bCompat )
+ // Ausfuehren eines BASIC-Unterprogramms
+ USHORT SbModule::Run( SbMethod* pMeth )
+ {
++ OSL_TRACE("About to run %s, vba compatmode is %d", rtl::OUStringToOString( pMeth->GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mbVBACompat );
+ static USHORT nMaxCallLevel = 0;
+ static String aMSOMacroRuntimeLibName = String::CreateFromAscii( "Launcher" );
+ static String aMSOMacroRuntimeAppSymbol = String::CreateFromAscii( "Application" );
+
+ USHORT nRes = 0;
+ BOOL bDelInst = BOOL( pINST == NULL );
++ bool bQuit = false;
+ StarBASICRef xBasic;
+ if( bDelInst )
+ {
+@@ -800,6 +1226,15 @@ USHORT SbModule::Run( SbMethod* pMeth )
+
+ delete pRt;
+ pMOD = pOldMod;
++ if ( pINST->nCallLvl == 0 && IsVBACompat() )
++ {
++ // VBA always ensure screenupdating is enabled after completing
++ StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
++ if ( pBasic && pBasic->IsDocBasic() )
++ {
++ UnlockControllerHack( pBasic );
++ }
++ }
+ if( bDelInst )
+ {
+ // #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
+@@ -827,10 +1262,8 @@ USHORT SbModule::Run( SbMethod* pMeth )
+
+ // VBA always ensure screenupdating is enabled after completing
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
+-#if 0
+ if ( pBasic && pBasic->IsDocBasic() && !pINST )
+ UnlockControllerHack( pBasic );
+-#endif
+ if( bDelInst )
+ {
+ // #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
+@@ -841,6 +1274,8 @@ USHORT SbModule::Run( SbMethod* pMeth )
+ pINST = NULL;
+ }
+ if ( pBasic && pBasic->IsDocBasic() && pBasic->IsQuitApplication() && !pINST )
++ bQuit = true;
++ if ( bQuit )
+ {
+ Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler, OnAsyncQuit ), NULL );
+ }
+@@ -884,6 +1319,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++ )
+@@ -1264,6 +1726,48 @@ BOOL SbModule::ExceedsLegacyModuleSize()
+ return false;
+ }
+
++class ErrorHdlResetter
++{
++ Link mErrHandler;
++ bool mbError;
++ public:
++ ErrorHdlResetter() : mbError( false )
++ {
++ // save error handler
++ mErrHandler = StarBASIC::GetGlobalErrorHdl();
++ // set new error handler
++ StarBASIC::SetGlobalErrorHdl( LINK( this, ErrorHdlResetter, BasicErrorHdl ) );
++ }
++ ~ErrorHdlResetter()
++ {
++ // restore error handler
++ StarBASIC::SetGlobalErrorHdl(mErrHandler);
++ }
++ DECL_LINK( BasicErrorHdl, StarBASIC * );
++ bool HasError() { return mbError; }
++};
++IMPL_LINK( ErrorHdlResetter, BasicErrorHdl, StarBASIC *, /*pBasic*/)
++{
++ mbError = true;
++ return 0;
++}
++
++bool SbModule::HasExeCode()
++{
++
++ ErrorHdlResetter aGblErrHdl;
++ // And empty Image always has the Global Chain set up
++ static const unsigned char pEmptyImage[] = { 0x45, 0x0 , 0x0, 0x0, 0x0 };
++ // lets be stricter for the moment than VBA
++
++ bool bRes = false;
++ if ( !IsCompiled() )
++ Compile();
++ if ( pImage && !( pImage->GetCodeSize() == 5 && ( memcmp( pImage->GetCode(), pEmptyImage, pImage->GetCodeSize() ) == 0 ) )
++ || aGblErrHdl.HasError() )
++ bRes = true;
++ return bRes;
++}
+
+ // Store only image, no source
+ BOOL SbModule::StoreBinaryData( SvStream& rStrm )
+@@ -1313,7 +1817,6 @@ BOOL SbModule::LoadBinaryData( SvStream& rStrm )
+ return bRet;
+ }
+
+-
+ BOOL SbModule::LoadCompleted()
+ {
+ SbxArray* p = GetMethods();
+@@ -1381,6 +1884,7 @@ SbMethod::SbMethod( const String& r, SbxDataType t, SbModule* p )
+ nLine1 =
+ nLine2 = 0;
+ refStatics = new SbxArray;
++ mCaller = 0;
+ // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
+ SetFlag( SBX_NO_MODIFY );
+ }
+@@ -1395,6 +1899,7 @@ SbMethod::SbMethod( const SbMethod& r )
+ nLine1 = r.nLine1;
+ nLine2 = r.nLine2;
+ refStatics = r.refStatics;
++ mCaller = r.mCaller;
+ SetFlag( SBX_NO_MODIFY );
+ }
+
+@@ -1463,8 +1968,13 @@ SbxInfo* SbMethod::GetInfo()
+ // Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
+ // #34191# Mit speziellem RefCounting, damit das Basic nicht durch CloseDocument()
+ // abgeschossen werden kann. Rueckgabewert wird als String geliefert.
+-ErrCode SbMethod::Call( SbxValue* pRet )
++ErrCode SbMethod::Call( SbxValue* pRet, SbxVariable* pCaller )
+ {
++ if ( pCaller )
++ {
++ OSL_TRACE("SbMethod::Call Have been passed a caller 0x%x", pCaller );
++ mCaller = pCaller;
++ }
+ // RefCount vom Modul hochzaehlen
+ SbModule* pMod_ = (SbModule*)GetParent();
+ pMod_->AddRef();
+@@ -1492,7 +2002,7 @@ ErrCode SbMethod::Call( SbxValue* pRet )
+ // Objekte freigeben
+ pMod_->ReleaseRef();
+ pBasic->ReleaseRef();
+-
++ mCaller = 0;
+ return nErr;
+ }
+
+@@ -1657,9 +2167,8 @@ public:
+ }
+
+ //liuchen 2009-7-21, support Excel VBA Form_QueryClose event
+- virtual void SAL_CALL windowClosing( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
++ virtual void SAL_CALL windowClosing( const lang::EventObject& e ) throw (uno::RuntimeException)
+ {
+-#if IN_THE_FUTURE
+ uno::Reference< awt::XDialog > xDialog( e.Source, uno::UNO_QUERY );
+ if ( xDialog.is() )
+ {
+@@ -1687,7 +2196,6 @@ public:
+ }
+
+ mpUserForm->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ) );
+-#endif
+ }
+ //liuchen 2009-7-21
+
+@@ -1749,14 +2257,13 @@ void SbUserFormModule::triggerMethod( const String& aMethodToRun )
+ Sequence< Any > aArguments;
+ triggerMethod( aMethodToRun, aArguments );
+ }
+-void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any >& /*aArguments*/)
++void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any >& aArguments)
+ {
+ OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun, RTL_TEXTENCODING_UTF8 ).getStr() );
+ // Search method
+ SbxVariable* pMeth = SbObjModule::Find( aMethodToRun, SbxCLASS_METHOD );
+ if( pMeth )
+ {
+-#if IN_THE_FUTURE
+ //liuchen 2009-7-21, support Excel VBA UserForm_QueryClose event with parameters
+ if ( aArguments.getLength() > 0 ) // Setup parameters
+ {
+@@ -1786,7 +2293,6 @@ void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any
+ }
+ else
+ //liuchen 2009-7-21
+-#endif
+ {
+ SbxValues aVals;
+ pMeth->Get( aVals );
+@@ -1939,7 +2445,7 @@ void SbUserFormModule::InitObject()
+ aArgs[ 0 ] = uno::Any();
+ aArgs[ 1 ] <<= m_xDialog;
+ aArgs[ 2 ] <<= m_xModel;
+- aArgs[ 3 ] <<= rtl::OUString( GetParent()->GetName() );
++ aArgs[ 3 ] <<= sProjectName;
+ 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
+diff --git basic/source/comp/codegen.cxx basic/source/comp/codegen.cxx
+index c7e8f11..be7c357 100644
+--- basic/source/comp/codegen.cxx
++++ basic/source/comp/codegen.cxx
+@@ -161,8 +161,6 @@ void SbiCodeGen::Save()
+ rMod.mnType = com::sun::star::script::ModuleType::NORMAL;
+ rMod.bIsProxyModule = false;
+ }
+- if( pParser->bText )
+- p->SetFlag( SBIMG_COMPARETEXT );
+ // GlobalCode-Flag
+ if( pParser->HasGlobalCode() )
+ p->SetFlag( SBIMG_INITCODE );
+@@ -242,6 +240,8 @@ void SbiCodeGen::Save()
+ if( nPass == 1 )
+ aPropName = aPropName.Copy( aIfaceName.Len() + 1 );
+ SbProcedureProperty* pProcedureProperty = NULL;
++ OSL_TRACE("*** getProcedureProperty for thing %s",
++ rtl::OUStringToOString( aPropName,RTL_TEXTENCODING_UTF8 ).getStr() );
+ pProcedureProperty = rMod.GetProcedureProperty( aPropName, ePropType );
+ }
+ if( nPass == 1 )
+diff --git basic/source/comp/dim.cxx basic/source/comp/dim.cxx
+index b5131c9..19d9d38 100644
+--- basic/source/comp/dim.cxx
++++ basic/source/comp/dim.cxx
+@@ -29,6 +29,8 @@
+ #include "precompiled_basic.hxx"
+ #include <basic/sbx.hxx>
+ #include "sbcomp.hxx"
++#include "sbunoobj.hxx"
++
+
+ SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
+
+@@ -153,7 +155,7 @@ void SbiParser::TypeDecl( SbiSymDef& rDef, BOOL bAsNewAlreadyParsed )
+ }
+ }
+ }
+- else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) )
++ else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) || ( IsVBASupportOn() && VBAConstantHelper::instance().isVBAConstantType( aCompleteName ) ) )
+ {
+ eType = SbxLONG;
+ break;
+@@ -423,7 +425,10 @@ void SbiParser::DefVar( SbiOpcode eOp, BOOL bStatic )
+ aExpr.Gen();
+ SbiOpcode eOp_ = pDef->IsNew() ? _CREATE : _TCREATE;
+ aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() );
+- aGen.Gen( _SET );
++ if ( bVBASupportOn )
++ aGen.Gen( _VBASET );
++ else
++ aGen.Gen( _SET );
+ }
+ }
+ else
+@@ -975,6 +980,24 @@ void SbiParser::DefDeclare( BOOL bPrivate )
+ }
+ }
+
++void SbiParser::Attribute()
++{
++ // TODO: Need to implement the method as an attributed object.
++ while( Next() != EQ )
++ {
++ String aSym( GetSym() );
++ if( Next() != DOT)
++ break;
++ }
++
++ if( eCurTok != EQ )
++ Error( SbERR_SYNTAX );
++ else
++ SbiExpression aValue( this );
++
++ // Don't generate any code - just discard it.
++}
++
+ // Aufruf einer SUB oder FUNCTION
+
+ void SbiParser::Call()
+diff --git basic/source/comp/exprtree.cxx basic/source/comp/exprtree.cxx
+index 604ac61..658c9bf 100644
+--- basic/source/comp/exprtree.cxx
++++ basic/source/comp/exprtree.cxx
+@@ -382,8 +382,12 @@ SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo )
+ // Typ SbxOBJECT sein
+ if( pDef->GetType() != SbxOBJECT && pDef->GetType() != SbxVARIANT )
+ {
+- pParser->Error( SbERR_BAD_DECLARATION, aSym );
+- bError = TRUE;
++ // defer error until runtime if in vba mode
++ if ( !pParser->IsVBASupportOn() )
++ {
++ pParser->Error( SbERR_BAD_DECLARATION, aSym );
++ bError = TRUE;
++ }
+ }
+ if( !bError )
+ pNd->aVar.pNext = ObjTerm( *pDef );
+@@ -589,7 +593,11 @@ SbiExprNode* SbiExpression::Unary()
+ eTok = NEG;
+ case NOT:
+ pParser->Next();
+- pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
++ // process something like "Do While Not "foo"="" "
++ if( pParser->IsVBASupportOn() )
++ pNd = new SbiExprNode( pParser, Like(), eTok, NULL );
++ else
++ pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
+ break;
+ case PLUS:
+ pParser->Next();
+@@ -745,7 +753,7 @@ SbiExprNode* SbiExpression::Like()
+ pNd = new SbiExprNode( pParser, pNd, eTok, Comp() ), nCount++;
+ }
+ // Mehrere Operatoren hintereinander gehen nicht
+- if( nCount > 1 )
++ if( nCount > 1 && !pParser->IsVBASupportOn() )
+ {
+ pParser->Error( SbERR_SYNTAX );
+ bError = TRUE;
+diff --git basic/source/comp/parser.cxx basic/source/comp/parser.cxx
+index 83e7bbd..81fd9d6 100644
+--- basic/source/comp/parser.cxx
++++ basic/source/comp/parser.cxx
+@@ -49,6 +49,7 @@ struct SbiStatement {
+ #define N FALSE
+
+ static SbiStatement StmntTable [] = {
++{ ATTRIBUTE, &SbiParser::Attribute, Y, Y, }, // ATTRIBUTE
+ { CALL, &SbiParser::Call, N, Y, }, // CALL
+ { CLOSE, &SbiParser::Close, N, Y, }, // CLOSE
+ { _CONST_, &SbiParser::Dim, Y, Y, }, // CONST
+@@ -387,6 +388,18 @@ BOOL SbiParser::Parse()
+ Next(); return TRUE;
+ }
+
++ // In vba it's possible to do Error.foobar ( even if it results in
++ // a runtime error
++ if ( eCurTok == _ERROR_ && IsVBASupportOn() ) // we probably need to define a subset of keywords where this madness applies e.g. if ( IsVBASupportOn() && SymbolCanBeRedined( eCurTok ) )
++ {
++ SbiTokenizer tokens( *(SbiTokenizer*)this );
++ tokens.Next();
++ if ( tokens.Peek() == DOT )
++ {
++ eCurTok = SYMBOL;
++ ePush = eCurTok;
++ }
++ }
+ // Kommt ein Symbol, ist es entweder eine Variable( LET )
+ // oder eine SUB-Prozedur( CALL ohne Klammern )
+ // DOT fuer Zuweisungen im WITH-Block: .A=5
+@@ -795,7 +808,7 @@ void SbiParser::Option()
+ bClassModule = TRUE;
+ aGen.GetModule().SetModuleType( com::sun::star::script::ModuleType::CLASS );
+ break;
+- case VBASUPPORT:
++ case VBASUPPORT: // Option VBASupport used to override the module mode ( in fact this must reset the mode
+ if( Next() == NUMBER )
+ {
+ if ( nVal == 1 || nVal == 0 )
+diff --git basic/source/comp/sbcomp.cxx basic/source/comp/sbcomp.cxx
+index c91624d..5bec939 100644
+--- basic/source/comp/sbcomp.cxx
++++ basic/source/comp/sbcomp.cxx
+@@ -131,6 +131,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++ )
+ {
+diff --git basic/source/comp/token.cxx basic/source/comp/token.cxx
+index 0069079..25dd885 100644
+--- basic/source/comp/token.cxx
++++ basic/source/comp/token.cxx
+@@ -58,6 +58,7 @@ static TokenTable aTokTable_Basic [] = { // Token-Tabelle:
+ { ANY, "Any" },
+ { APPEND, "Append" },
+ { AS, "As" },
++ { ATTRIBUTE,"Attribute" },
+ { BASE, "Base" },
+ { BINARY, "Binary" },
+ { TBOOLEAN, "Boolean" },
+diff --git basic/source/inc/dlgcont.hxx basic/source/inc/dlgcont.hxx
+index 7d22f4d..fe70a45 100644
+--- basic/source/inc/dlgcont.hxx
++++ basic/source/inc/dlgcont.hxx
+@@ -96,7 +96,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);
+-
++ // XLibraryQueryExecutable
++ virtual sal_Bool SAL_CALL HasExecutableCode(const rtl::OUString&)
++ throw (::com::sun::star::uno::RuntimeException);
+ // Service
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static();
+ static ::rtl::OUString getImplementationName_static();
+diff --git basic/source/inc/namecont.hxx basic/source/inc/namecont.hxx
+index 6db0b96..196b3d1 100644
+--- basic/source/inc/namecont.hxx
++++ basic/source/inc/namecont.hxx
+@@ -35,6 +35,7 @@
+ #include <com/sun/star/script/XStorageBasedLibraryContainer.hpp>
+ #include <com/sun/star/script/XLibraryContainerPassword.hpp>
+ #include <com/sun/star/script/XLibraryContainerExport.hpp>
++#include <com/sun/star/script/XLibraryQueryExecutable.hpp>
+ #include <com/sun/star/script/XLibraryContainer3.hpp>
+ #include <com/sun/star/container/XNameContainer.hpp>
+ #include <com/sun/star/container/XContainer.hpp>
+@@ -59,6 +60,7 @@
+
+ #include <cppuhelper/implbase2.hxx>
+ #include <cppuhelper/compbase8.hxx>
++#include <cppuhelper/compbase9.hxx>
+ #include <cppuhelper/interfacecontainer.hxx>
+ #include <com/sun/star/script/XVBACompat.hpp>
+
+@@ -67,13 +69,14 @@ class BasicManager;
+ namespace basic
+ {
+
+-typedef ::cppu::WeakComponentImplHelper8<
++typedef ::cppu::WeakComponentImplHelper9<
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::script::XStorageBasedLibraryContainer,
+ ::com::sun::star::script::XLibraryContainerPassword,
+ ::com::sun::star::script::XLibraryContainerExport,
+ ::com::sun::star::script::XLibraryContainer3,
+ ::com::sun::star::container::XContainer,
++ ::com::sun::star::script::XLibraryQueryExecutable,
+ ::com::sun::star::script::XVBACompat,
+ ::com::sun::star::lang::XServiceInfo > LibraryContainerHelper;
+
+diff --git basic/source/inc/parser.hxx basic/source/inc/parser.hxx
+index 4fb7b18..f9a159d 100644
+--- basic/source/inc/parser.hxx
++++ basic/source/inc/parser.hxx
+@@ -106,6 +106,7 @@ public:
+ void BadSyntax(); // Falsches SbiToken
+ void NoIf(); // ELSE/ELSE IF ohne IF
+ void Assign(); // LET
++ void Attribute(); // Attribute
+ void Call(); // CALL
+ void Close(); // CLOSE
+ void Declare(); // DECLARE
+diff --git basic/source/inc/runtime.hxx basic/source/inc/runtime.hxx
+index 96de7e5..b95b13c 100644
+--- basic/source/inc/runtime.hxx
++++ basic/source/inc/runtime.hxx
+@@ -203,7 +203,6 @@ class SbiInstance
+ BOOL bCompatibility; // Flag: TRUE = VBA runtime compatibility mode
+
+ ComponentVector_t ComponentVector;
+-
+ public:
+ SbiRuntime* pRun; // Call-Stack
+ SbiInstance* pNext; // Instanzen-Chain
+@@ -292,7 +291,9 @@ class SbiRuntime
+ SbxArrayRef refExprStk; // expression stack
+ SbxArrayRef refCaseStk; // CASE expression stack
+ SbxArrayRef refRedimpArray; // Array saved to use for REDIM PRESERVE
++ SbxVariableRef refRedim; // Array saved to use for REDIM
+ SbxVariableRef xDummyVar; // Ersatz fuer nicht gefundene Variablen
++ SbxVariable* mpExtCaller; // Caller ( external - e.g. button name, shape, range object etc. - only in vba mode )
+ SbiArgvStack* pArgvStk; // ARGV-Stack
+ SbiGosubStack* pGosubStk; // GOSUB stack
+ SbiForStack* pForStk; // FOR/NEXT-Stack
+@@ -462,6 +463,7 @@ public:
+ SbMethod* GetCaller();
+ SbxArray* GetLocals();
+ SbxArray* GetParams();
++ SbxVariable* GetExternalCaller(){ return mpExtCaller; }
+
+ SbxBase* FindElementExtern( const String& rName );
+ static bool isVBAEnabled();
+diff --git basic/source/inc/sbunoobj.hxx basic/source/inc/sbunoobj.hxx
+index b8993c1..edbe260 100644
+--- basic/source/inc/sbunoobj.hxx
++++ basic/source/inc/sbunoobj.hxx
+@@ -43,6 +43,7 @@
+ #include <com/sun/star/reflection/XServiceTypeDescription2.hpp>
+ #include <com/sun/star/reflection/XSingletonTypeDescription.hpp>
+ #include <rtl/ustring.hxx>
++#include <hash_map>
+
+ class SbUnoObject: public SbxObject
+ {
+@@ -320,6 +321,26 @@ public:
+ virtual void Clear();
+ };
+
++typedef std::hash_map< ::rtl::OUString, ::com::sun::star::uno::Any, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > VBAConstantsHash;
++
++typedef std::vector< rtl::OUString > VBAConstantsVector;
++
++class VBAConstantHelper
++{
++private:
++
++ VBAConstantsVector aConstCache;
++ VBAConstantsHash aConstHash;
++ bool isInited;
++ VBAConstantHelper():isInited( false ) {}
++ VBAConstantHelper(const VBAConstantHelper&);
++ void init();
++public:
++ static VBAConstantHelper& instance();
++ SbxVariable* getVBAConstant( const String& rName );
++ bool isVBAConstantType( const String& rName );
++};
++
+ #endif
+
+
+diff --git basic/source/inc/scriptcont.hxx basic/source/inc/scriptcont.hxx
+index 2c71183..2fdd79c 100644
+--- basic/source/inc/scriptcont.hxx
++++ basic/source/inc/scriptcont.hxx
+@@ -122,7 +122,9 @@ public:
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+-
++ // XLibraryQueryExecutable
++ virtual sal_Bool SAL_CALL HasExecutableCode(const rtl::OUString&)
++ throw (::com::sun::star::uno::RuntimeException);
+ // Methods XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+diff --git basic/source/inc/token.hxx basic/source/inc/token.hxx
+index 7c3ff75..068a107 100644
+--- basic/source/inc/token.hxx
++++ basic/source/inc/token.hxx
+@@ -72,7 +72,7 @@ enum SbiToken {
+ IF, _IN_, INPUT,
+ LET, LINE, LINEINPUT, LOCAL, LOOP, LPRINT, LSET,
+ NAME, NEW, NEXT,
+- ON, OPEN, OPTION, IMPLEMENTS,
++ ON, OPEN, OPTION, ATTRIBUTE, IMPLEMENTS,
+ PRINT, PRIVATE, PROPERTY, PUBLIC,
+ REDIM, REM, RESUME, RETURN, RSET,
+ SELECT, SET, SHARED, STATIC, STEP, STOP, SUB,
+diff --git basic/source/runtime/methods.cxx basic/source/runtime/methods.cxx
+index 41e7df4..105e885 100644
+--- basic/source/runtime/methods.cxx
++++ basic/source/runtime/methods.cxx
+@@ -48,6 +48,7 @@
+ #include <unotools/ucbstreamhelper.hxx>
+ #include <tools/wldcrd.hxx>
+ #include <i18npool/lang.h>
++#include <rtl/string.hxx>
+
+ #include "runtime.hxx"
+ #include "sbunoobj.hxx"
+@@ -75,13 +76,16 @@
+ #include <com/sun/star/io/XOutputStream.hpp>
+ #include <com/sun/star/io/XStream.hpp>
+ #include <com/sun/star/io/XSeekable.hpp>
+-
++#include <com/sun/star/script/XErrorQuery.hpp>
++#include <ooo/vba/XHelperInterface.hpp>
++#include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
+ using namespace comphelper;
+ using namespace osl;
+ using namespace com::sun::star::uno;
+ using namespace com::sun::star::lang;
+ using namespace com::sun::star::ucb;
+ using namespace com::sun::star::io;
++using namespace com::sun::star::script;
+
+ #endif /* _USE_UNO */
+
+@@ -103,6 +107,8 @@ using namespace com::sun::star::io;
+ #include <stdlib.h>
+ #include <ctype.h>
+
++SbxVariable* getDefaultProp( SbxVariable* pRef );
++
+ #if defined (WIN) || defined (WNT) || defined (OS2)
+ #include <direct.h> // _getdcwd get current work directory, _chdrive
+ #endif
+@@ -121,6 +127,10 @@ using namespace com::sun::star::io;
+ #include <io.h>
+ #endif
+
++using namespace rtl;
++
++#include <basic/sbobjmod.hxx>
++
+ #include <basic/sbobjmod.hxx>
+
+ static void FilterWhiteSpace( String& rStr )
+@@ -706,6 +716,36 @@ RTLFUNC(MkDir) // JSM
+ {
+ try
+ {
++ if ( SbiRuntime::isVBAEnabled() )
++ {
++ // If aPath is the folder name, not a path, then create the folder under current directory.
++ INetURLObject aTryPathURL( aPath );
++ ::rtl::OUString sPathURL = aTryPathURL.GetMainURL( INetURLObject::NO_DECODE );
++ if ( !sPathURL.getLength() )
++ {
++ File::getFileURLFromSystemPath( aPath, sPathURL );
++ }
++ INetURLObject aPathURL( sPathURL );
++ if ( !aPathURL.GetPath().getLength() )
++ {
++ ::rtl::OUString sCurDirURL;
++ SbxArrayRef pPar = new SbxArray;
++ SbxVariableRef pVar = new SbxVariable();
++ pPar->Put( pVar, 0 );
++ SbRtl_CurDir( pBasic, *pPar, FALSE );
++ String aCurPath = pPar->Get(0)->GetString();
++
++ File::getFileURLFromSystemPath( aCurPath, sCurDirURL );
++ INetURLObject aDirURL( sCurDirURL );
++ aDirURL.Append( aPath );
++ ::rtl::OUString aTmpPath = aDirURL.GetMainURL( INetURLObject::NO_DECODE );
++ if ( aTmpPath.getLength() > 0 )
++ {
++ aPath = aTmpPath;
++ }
++ }
++ }
++
+ xSFI->createFolder( getFullPath( aPath ) );
+ }
+ catch( Exception & )
+@@ -940,6 +980,26 @@ RTLFUNC(Hex)
+ }
+ }
+
++RTLFUNC(FuncCaller)
++{
++ (void)pBasic;
++ (void)bWrite;
++ if ( SbiRuntime::isVBAEnabled() && pINST && pINST->pRun )
++ {
++ if ( pINST->pRun->GetExternalCaller() )
++ *rPar.Get(0) = *pINST->pRun->GetExternalCaller();
++ else
++ {
++ SbxVariableRef pVar = new SbxVariable(SbxVARIANT);
++ *rPar.Get(0) = *pVar;
++ }
++ }
++ else
++ {
++ StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
++ }
++
++}
+ // InStr( [start],string,string,[compare] )
+
+ RTLFUNC(InStr)
+@@ -2411,7 +2471,18 @@ RTLFUNC(IsEmpty)
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+- rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
++ {
++ SbxVariable* pVar = NULL;
++ if( SbiRuntime::isVBAEnabled() )
++ pVar = getDefaultProp( rPar.Get(1) );
++ if ( pVar )
++ {
++ pVar->Broadcast( SBX_HINT_DATAWANTED );
++ rPar.Get( 0 )->PutBool( pVar->IsEmpty() );
++ }
++ else
++ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
++ }
+ }
+
+ RTLFUNC(IsError)
+@@ -2422,7 +2493,22 @@ RTLFUNC(IsError)
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+- rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
++ {
++ SbxVariable* pVar =rPar.Get( 1 );
++ SbUnoObject* pObj = PTR_CAST(SbUnoObject,pVar );
++ if ( !pObj )
++ {
++ if ( SbxBase* pBaseObj = pVar->GetObject() )
++ pObj = PTR_CAST(SbUnoObject, pBaseObj );
++ }
++ Reference< XErrorQuery > xError;
++ if ( pObj )
++ xError.set( pObj->getUnoAny(), UNO_QUERY );
++ if ( xError.is() )
++ rPar.Get( 0 )->PutBool( xError->hasError() );
++ else
++ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
++ }
+ }
+
+ RTLFUNC(IsNull)
+@@ -3542,6 +3628,13 @@ RTLFUNC(Shell)
+ NAMESPACE_VOS(OArgumentList) aArgList( pArgumentList, nParamCount );
+ bSucc = pApp->execute( eOptions, aArgList ) == NAMESPACE_VOS(OProcess)::E_None;
+ }
++ long nResult = 0;
++ NAMESPACE_VOS(OProcess)::TProcessInfo aInfo;
++ // We should return the identifier of the executing process when is running VBA, because method Shell(...) returns it in Excel.
++ if ( bSucc && SbiRuntime::isVBAEnabled() && pApp->getInfo( NAMESPACE_VOS(OProcess)::TData_Identifier, &aInfo ) == NAMESPACE_VOS(OProcess)::E_None )
++ {
++ nResult = aInfo.Ident;
++ }
+
+ /*
+ if( nParamCount == 0 )
+@@ -3556,7 +3649,7 @@ RTLFUNC(Shell)
+ if( !bSucc )
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ else
+- rPar.Get(0)->PutLong( 0 );
++ rPar.Get(0)->PutLong( nResult );
+ }
+ }
+
+@@ -3627,6 +3720,65 @@ String getBasicTypeName( SbxDataType eType )
+ return aRetStr;
+ }
+
++String getObjectTypeName( SbxVariable* pVar )
++{
++ rtl::OUString sRet( RTL_CONSTASCII_USTRINGPARAM("Object") );
++ if ( pVar )
++ {
++ SbxBase* pObj = pVar->GetObject();
++ if( !pObj )
++ sRet = String( RTL_CONSTASCII_USTRINGPARAM("Nothing") );
++ else
++ {
++ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pVar );
++ if ( !pUnoObj )
++ {
++ if ( SbxBase* pBaseObj = pVar->GetObject() )
++ pUnoObj = PTR_CAST(SbUnoObject, pBaseObj );
++ }
++ if ( pUnoObj )
++ {
++ Any aObj = pUnoObj->getUnoAny();
++ // For upstreaming unless we start to build oovbaapi by default
++ // we need to get detect the vba-ness of the object in some
++ // other way
++ // note: Automation objects do not support XServiceInfo
++ Reference< XServiceInfo > xServInfo( aObj, UNO_QUERY );
++ if ( xServInfo.is() )
++ {
++ // is this a VBA object ?
++ Reference< ooo::vba::XHelperInterface > xVBA( aObj, UNO_QUERY );
++ Sequence< rtl::OUString > sServices = xServInfo->getSupportedServiceNames();
++ if ( sServices.getLength() )
++ sRet = sServices[ 0 ];
++ }
++ else
++ {
++ Reference< com::sun::star::bridge::oleautomation::XAutomationObject > xAutoMation( aObj, UNO_QUERY );
++ if ( xAutoMation.is() )
++ {
++ Reference< XInvocation > xInv( aObj, UNO_QUERY );
++ if ( xInv.is() )
++ {
++ try
++ {
++ xInv->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("$GetTypeName") ) ) >>= sRet;
++ }
++ catch( Exception& )
++ {
++ }
++ }
++ }
++ }
++ sal_Int32 nDot = sRet.lastIndexOf( '.' );
++ if ( nDot != -1 && nDot < sRet.getLength() )
++ sRet = sRet.copy( nDot + 1 );
++ }
++ }
++ }
++ return sRet;
++}
++
+ RTLFUNC(TypeName)
+ {
+ (void)pBasic;
+@@ -3638,7 +3790,12 @@ RTLFUNC(TypeName)
+ {
+ SbxDataType eType = rPar.Get(1)->GetType();
+ BOOL bIsArray = ( ( eType & SbxARRAY ) != 0 );
+- String aRetStr = getBasicTypeName( eType );
++
++ String aRetStr;
++ if ( SbiRuntime::isVBAEnabled() && eType == SbxOBJECT )
++ aRetStr = getObjectTypeName( rPar.Get(1) );
++ else
++ aRetStr = getBasicTypeName( eType );
+ if( bIsArray )
+ aRetStr.AppendAscii( "()" );
+ rPar.Get(0)->PutString( aRetStr );
+diff --git basic/source/runtime/methods1.cxx basic/source/runtime/methods1.cxx
+index f22a52c..9d3b51a 100644
+--- basic/source/runtime/methods1.cxx
++++ basic/source/runtime/methods1.cxx
+@@ -78,11 +78,15 @@
+ #include <com/sun/star/uno/Sequence.hxx>
+ #include <com/sun/star/lang/XMultiServiceFactory.hpp>
+ #include <com/sun/star/i18n/XCalendar.hpp>
++#include <com/sun/star/sheet/XFunctionAccess.hpp>
+
+ using namespace comphelper;
++using namespace com::sun::star::sheet;
+ using namespace com::sun::star::uno;
+ using namespace com::sun::star::i18n;
+
++void unoToSbxValue( SbxVariable* pVar, const Any& aValue );
++Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, com::sun::star::beans::Property* pUnoProperty = NULL );
+
+ static Reference< XCalendar > getLocaleCalendar( void )
+ {
+@@ -2518,6 +2522,546 @@ RTLFUNC(Round)
+ rPar.Get(0)->PutDouble( dRes );
+ }
+
++void CallFunctionAccessFunction( const Sequence< Any >& aArgs, const rtl::OUString& sFuncName, SbxVariable* pRet )
++{
++ static Reference< XFunctionAccess > xFunc;
++ Any aRes;
++ try
++ {
++ if ( !xFunc.is() )
++ {
++ Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() );
++ if( xFactory.is() )
++ {
++ xFunc.set( xFactory->createInstance(::rtl::OUString::createFromAscii( "com.sun.star.sheet.FunctionAccess")), UNO_QUERY_THROW);
++ }
++ }
++ Any aRet = xFunc->callFunction( sFuncName, aArgs );
++
++ unoToSbxValue( pRet, aRet );
++
++ }
++ catch( Exception& )
++ {
++ StarBASIC::Error( SbERR_BAD_ARGUMENT );
++ }
++}
++
++RTLFUNC(SYD)
++{
++ (void)pBasic;
++ (void)bWrite;
++
++ ULONG nArgCount = rPar.Count()-1;
++
++ if ( nArgCount < 4 )
++ {
++ StarBASIC::Error( SbERR_BAD_ARGUMENT );
++ return;
++ }
++
++ // retrieve non-optional params
++
++ Sequence< Any > aParams( 4 );
++ aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
++ aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
++ aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
++ aParams[ 3 ] <<= makeAny( rPar.Get(4)->GetDouble() );
++
++ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SYD") ), rPar.Get( 0 ) );
++}
++
++RTLFUNC(SLN)
++{
++ (void)pBasic;
++ (void)bWrite;
++
++ ULONG nArgCount = rPar.Count()-1;
++
++ if ( nArgCount < 3 )
++ {
++ StarBASIC::Error( SbERR_BAD_ARGUMENT );
++ return;
++ }
++
++ // retrieve non-optional params
++
++ Sequence< Any > aParams( 3 );
++ aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
++ aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
++ aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
++
++ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SLN") ), rPar.Get( 0 ) );
++}
++
++RTLFUNC(Pmt)
++{
++ (void)pBasic;
++ (void)bWrite;
++
++ ULONG nArgCount = rPar.Count()-1;
++
++ if ( nArgCount < 3 || nArgCount > 5 )
++ {
++ StarBASIC::Error( SbERR_BAD_ARGUMENT );
++ return;
++ }
++ // retrieve non-optional params
++
++ double rate = rPar.Get(1)->GetDouble();
++ double nper = rPar.Get(2)->GetDouble();
++ double pmt = rPar.Get(3)->GetDouble();
++
++ // set default values for Optional args
++ double fv = 0;
++ double type = 0;
++
++ // fv
++ if ( nArgCount >= 4 )
++ {
++ if( rPar.Get(4)->GetType() != SbxEMPTY )
++ fv = rPar.Get(4)->GetDouble();
++ }
++ // type
++ if ( nArgCount >= 5 )
++ {
++ if( rPar.Get(5)->GetType() != SbxEMPTY )
++ type = rPar.Get(5)->GetDouble();
++ }
++
++ Sequence< Any > aParams( 5 );
++ aParams[ 0 ] <<= rate;
++ aParams[ 1 ] <<= nper;
++ aParams[ 2 ] <<= pmt;
++ aParams[ 3 ] <<= fv;
++ aParams[ 4 ] <<= type;
++
++ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Pmt") ), rPar.Get( 0 ) );
++}
++
++RTLFUNC(PPmt)
++{
++ (void)pBasic;
++ (void)bWrite;
++
++ ULONG nArgCount = rPar.Count()-1;
++
++ if ( nArgCount < 4 || nArgCount > 6 )
++ {
++ StarBASIC::Error( SbERR_BAD_ARGUMENT );
++ return;
++ }
++ // retrieve non-optional params
++
++ double rate = rPar.Get(1)->GetDouble();
++ double per = rPar.Get(2)->GetDouble();
++ double nper = rPar.Get(3)->GetDouble();
++ double pv = rPar.Get(4)->GetDouble();
++
++ // set default values for Optional args
++ double fv = 0;
++ double type = 0;
++
++ // fv
++ if ( nArgCount >= 5 )
++ {
++ if( rPar.Get(5)->GetType() != SbxEMPTY )
++ fv = rPar.Get(5)->GetDouble();
++ }
++ // type
++ if ( nArgCount >= 6 )
++ {
++ if( rPar.Get(6)->GetType() != SbxEMPTY )
++ type = rPar.Get(6)->GetDouble();
++ }
++
++ Sequence< Any > aParams( 6 );
++ aParams[ 0 ] <<= rate;
++ aParams[ 1 ] <<= per;
++ aParams[ 2 ] <<= nper;
++ aParams[ 3 ] <<= pv;
++ aParams[ 4 ] <<= fv;
++ aParams[ 5 ] <<= type;
++
++ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PPmt") ), rPar.Get( 0 ) );
++}
++
++RTLFUNC(PV)
++{
++ (void)pBasic;
++ (void)bWrite;
++
++ ULONG nArgCount = rPar.Count()-1;
++
++ if ( nArgCount < 3 || nArgCount > 5 )
++ {
++ StarBASIC::Error( SbERR_BAD_ARGUMENT );
++ return;
++ }
++ // retrieve non-optional params
++
++ double rate = rPar.Get(1)->GetDouble();
++ double nper = rPar.Get(2)->GetDouble();
++ double pmt = rPar.Get(3)->GetDouble();
++
++ // set default values for Optional args
++ double fv = 0;
++ double type = 0;
++
++ // fv
++ if ( nArgCount >= 4 )
++ {
++ if( rPar.Get(4)->GetType() != SbxEMPTY )
++ fv = rPar.Get(4)->GetDouble();
++ }
++ // type
++ if ( nArgCount >= 5 )
++ {
++ if( rPar.Get(5)->GetType() != SbxEMPTY )
++ type = rPar.Get(5)->GetDouble();
++ }
++
++ Sequence< Any > aParams( 5 );
++ aParams[ 0 ] <<= rate;
++ aParams[ 1 ] <<= nper;
++ aParams[ 2 ] <<= pmt;
++ aParams[ 3 ] <<= fv;
++ aParams[ 4 ] <<= type;
++
++ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PV") ), rPar.Get( 0 ) );
++}
++
++RTLFUNC(NPV)
++{
++ (void)pBasic;
++ (void)bWrite;
++
++ ULONG nArgCount = rPar.Count()-1;
++
++ if ( nArgCount < 1 || nArgCount > 2 )
++ {
++ StarBASIC::Error( SbERR_BAD_ARGUMENT );
++ return;
++ }
++
++ Sequence< Any > aParams( 2 );
++ aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
++ Any aValues = sbxToUnoValue( rPar.Get(2),
++ getCppuType( (Sequence<double>*)0 ) );
++
++ // convert for calc functions
++ Sequence< Sequence< double > > sValues(1);
++ aValues >>= sValues[ 0 ];
++ aValues <<= sValues;
++
++ aParams[ 1 ] <<= aValues;
++
++ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NPV") ), rPar.Get( 0 ) );
++}
++
++RTLFUNC(NPer)
++{
++ (void)pBasic;
++ (void)bWrite;
++
++ ULONG nArgCount = rPar.Count()-1;
++
++ if ( nArgCount < 3 || nArgCount > 5 )
++ {
++ StarBASIC::Error( SbERR_BAD_ARGUMENT );
++ return;
++ }
++ // retrieve non-optional params
++
++ double rate = rPar.Get(1)->GetDouble();
++ double pmt = rPar.Get(2)->GetDouble();
... etc. - the rest is truncated
More information about the ooo-build-commit
mailing list