[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