update ooo310-m15
[ooovba.git] / applied_patches / 0368-vba-userform.diff
blob1ee74682464146ad30f864fe984c5f260e6ca6f0
1 diff --git basic/inc/basic/sbmod.hxx basic/inc/basic/sbmod.hxx
2 index e676a49..ab496bc 100644
3 --- basic/inc/basic/sbmod.hxx
4 +++ basic/inc/basic/sbmod.hxx
5 @@ -59,6 +59,8 @@ class SbModule : public SbxObject
6 friend class SbClassModuleObject;
8 SbModuleImpl* mpSbModuleImpl; // Impl data
9 + SbModule();
10 + SbModule(const SbModule&);
12 protected:
13 ::rtl::OUString aOUSource;
14 diff --git basic/inc/basic/sbobjmod.hxx basic/inc/basic/sbobjmod.hxx
15 index cb581c1..96cbe9b 100644
16 --- basic/inc/basic/sbobjmod.hxx
17 +++ basic/inc/basic/sbobjmod.hxx
18 @@ -41,6 +41,7 @@
19 #include <com/sun/star/script/ModuleInfo.hpp>
20 #include <com/sun/star/lang/XEventListener.hpp>
21 #include <com/sun/star/awt/XDialog.hpp>
22 +#include <com/sun/star/frame/XModel.hpp>
24 namespace css = ::com::sun::star;
26 @@ -48,6 +49,8 @@ namespace css = ::com::sun::star;
28 class SbObjModule : public SbModule
30 + SbObjModule( const SbObjModule& );
31 + SbObjModule();
32 public:
33 TYPEINFO();
34 SbObjModule( const com::sun::star::script::ModuleInfo& mInfo, bool bIsVbaCompatible );
35 @@ -56,6 +59,32 @@ public:
36 void SetUnoObject( const com::sun::star::uno::Any& aObj )throw ( com::sun::star::uno::RuntimeException ) ;
39 +class SbUserFormModule : public SbObjModule
41 + css::uno::Reference<css::lang::XEventListener> m_DialogListener;
42 + css::uno::Reference<css::awt::XDialog> m_xDialog;
43 + css::uno::Reference<css::frame::XModel> m_xModel;
44 + String sFormName;
45 + bool mbInit;
46 + SbUserFormModule( const SbUserFormModule& );
47 + SbUserFormModule();
49 +protected:
50 + virtual void InitObject();
51 +public:
52 + TYPEINFO();
53 + SbUserFormModule( const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat );
54 + virtual SbxVariable* Find( const XubString& rName, SbxClassType t );
55 + void ResetApiObj();
56 + void Unload();
57 + void load();
58 + void triggerMethod( const String& );
59 + void triggerActivateEvent();
60 + void triggerDeActivateEvent();
61 + void triggerInitializeEvent();
62 + void triggerTerminateEvent();
63 +};
65 #ifndef __SB_SBOBJMODULEREF_HXX
66 #define __SB_SBOBJMODULEREF_HXX
68 diff --git basic/source/classes/sb.cxx basic/source/classes/sb.cxx
69 index 5226d3f..e47234f 100644
70 --- basic/source/classes/sb.cxx
71 +++ basic/source/classes/sb.cxx
72 @@ -715,6 +715,9 @@ SbModule* StarBASIC::MakeModule32( const
73 p = new SbModule( mInfo.ModuleName, isVBAEnabled() );
74 p->SetModuleType( com::sun::star::script::ModuleType::Class );
75 break;
76 + case ModuleType::Form:
77 + p = new SbUserFormModule( mInfo, isVBAEnabled() );
78 + break;
79 default:
80 p = new SbModule( mInfo.ModuleName, isVBAEnabled() );
82 @@ -900,9 +903,8 @@ SbxVariable* StarBASIC::Find( const Stri
83 // Only variables qualified by the Module Name e.g. Sheet1.foo
84 // should work for Documant && Class type Modules
85 INT32 nType = p->GetModuleType();
86 - //if ( nType == com::sun::star::script::ModuleType::Class || nType == com::sun::star::script::ModuleType::Document )
87 - if ( nType == com::sun::star::script::ModuleType::Document )
88 - continue;
89 + if ( nType == com::sun::star::script::ModuleType::Document || nType == com::sun::star::script::ModuleType::Form )
90 + continue;
91 // Sonst testen, ob das Element vorhanden ist
92 // GBLSEARCH-Flag rausnehmen (wg. Rekursion)
93 USHORT nGblFlag = p->GetFlags() & SBX_GBLSEARCH;
94 diff --git basic/source/classes/sbxmod.cxx basic/source/classes/sbxmod.cxx
95 index 8ea4b64..d3dd8d5 100644
96 --- basic/source/classes/sbxmod.cxx
97 +++ basic/source/classes/sbxmod.cxx
98 @@ -73,7 +73,6 @@
99 #include <com/sun/star/awt/XDialogProvider.hpp>
100 #include <com/sun/star/awt/XTopWindow.hpp>
101 #include <com/sun/star/awt/XControl.hpp>
102 -#include <com/sun/star/frame/XModel.hpp>
103 #include <cppuhelper/implbase1.hxx>
104 #include <comphelper/anytostring.hxx>
106 @@ -86,6 +85,7 @@ TYPEINIT1(SbProcedureProperty,SbxPropert
107 TYPEINIT1(SbJScriptModule,SbModule)
108 TYPEINIT1(SbJScriptMethod,SbMethod)
109 TYPEINIT1(SbObjModule,SbModule)
110 +TYPEINIT1(SbUserFormModule,SbObjModule)
112 SV_DECL_VARARR(SbiBreakpoints,USHORT,4,4)
113 SV_IMPL_VARARR(SbiBreakpoints,USHORT)
114 @@ -2272,6 +2272,242 @@ SbObjModule::Find( const XubString& rNam
115 pVar = SbModule::Find( rName, t );
116 return pVar;
119 +typedef ::cppu::WeakImplHelper1< awt::XTopWindowListener > EventListener_BASE;
121 +class FormObjEventListenerImpl : public EventListener_BASE
123 + SbUserFormModule* mpUserForm;
124 + uno::Reference< lang::XComponent > mxComponent;
125 + bool mbDisposed;
126 + sal_Bool mbOpened;
127 + sal_Bool mbActivated;
128 + sal_Bool mbShowing;
129 + FormObjEventListenerImpl(); // not defined
130 + FormObjEventListenerImpl(const FormObjEventListenerImpl&); // not defined
131 +public:
132 + FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent ) : mpUserForm( pUserForm ), mxComponent( xComponent) , mbDisposed( false ), mbOpened( sal_False ), mbActivated( sal_False ), mbShowing( sal_False )
134 + if ( mxComponent.is() );
136 + uno::Reference< awt::XTopWindow > xList( mxComponent, uno::UNO_QUERY_THROW );;
137 + //uno::Reference< awt::XWindow > xList( mxComponent, uno::UNO_QUERY_THROW );;
138 + OSL_TRACE("*********** Registering the listener");
139 + xList->addTopWindowListener( this );
143 + ~FormObjEventListenerImpl()
145 + removeListener();
147 + sal_Bool isShowing() { return mbShowing; }
148 + void removeListener()
150 + try
152 + if ( mxComponent.is() && !mbDisposed )
154 + uno::Reference< awt::XTopWindow > xList( mxComponent, uno::UNO_QUERY_THROW );;
155 + OSL_TRACE("*********** Removing the listener");
156 + xList->removeTopWindowListener( this );
157 + mxComponent = NULL;
160 + catch( uno::Exception& ) {}
161 + }
162 + virtual void SAL_CALL windowOpened( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
164 + if ( mpUserForm )
166 + mbOpened = sal_True;
167 + mbShowing = sal_True;
168 + if ( mbActivated )
170 + mbOpened = mbActivated = sal_False;
171 + mpUserForm->triggerActivateEvent();
175 + virtual void SAL_CALL windowClosing( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) {}
176 + virtual void SAL_CALL windowClosed( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) { mbOpened = sal_False; mbShowing = sal_False; }
177 + virtual void SAL_CALL windowMinimized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) {}
178 + virtual void SAL_CALL windowNormalized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException){}
179 + virtual void SAL_CALL windowActivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
181 + if ( mpUserForm )
183 + mbActivated = sal_True;
184 + if ( mbOpened )
186 + mbOpened = mbActivated = sal_False;
187 + mpUserForm->triggerActivateEvent();
192 + virtual void SAL_CALL windowDeactivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
194 + if ( mpUserForm )
195 + mpUserForm->triggerDeActivateEvent();
199 + virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException)
201 + OSL_TRACE("** Userform/Dialog disposing");
202 + mbDisposed = true;
203 + uno::Any aSource;
204 + aSource <<= Source;
205 + mxComponent = NULL;
206 + if ( mpUserForm )
207 + mpUserForm->ResetApiObj();
211 +SbUserFormModule::SbUserFormModule( const com::sun::star::script::ModuleInfo& mInfo, bool bIsCompat )
212 + :SbObjModule( mInfo, bIsCompat ), mbInit( false )
214 + m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW );
217 +void SbUserFormModule::ResetApiObj()
219 + if ( m_xDialog.is() ) // probably someone close the dialog window
221 + triggerTerminateEvent();
223 + pDocObject = NULL;
224 + m_xDialog = NULL;
227 +void SbUserFormModule::triggerMethod( const String& aMethodToRun )
229 + OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun, RTL_TEXTENCODING_UTF8 ).getStr() );
230 + // Search method
231 + SbxVariable* pMeth = SbObjModule::Find( aMethodToRun, SbxCLASS_METHOD );
232 + if( pMeth )
234 + SbxValues aVals;
235 + pMeth->Get( aVals );
239 +void SbUserFormModule::triggerActivateEvent( void )
241 + OSL_TRACE("**** entering SbUserFormModule::triggerActivate");
242 + triggerMethod( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm_activate") ) );
243 + OSL_TRACE("**** leaving SbUserFormModule::triggerActivate");
246 +void SbUserFormModule::triggerDeActivateEvent( void )
248 + OSL_TRACE("**** SbUserFormModule::triggerDeActivate");
249 + triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_DeActivate") ) );
252 +void SbUserFormModule::triggerInitializeEvent( void )
255 + if ( mbInit )
256 + return;
257 + OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent");
258 + static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Initialize") );
259 + triggerMethod( aInitMethodName );
260 + mbInit = true;
263 +void SbUserFormModule::triggerTerminateEvent( void )
265 + OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent");
266 + static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Terminate") );
267 + triggerMethod( aTermMethodName );
268 + mbInit=false;
271 +void SbUserFormModule::load()
273 + OSL_TRACE("** load() ");
274 + // forces a load
275 + if ( !pDocObject )
276 + InitObject();
278 +void SbUserFormModule::Unload()
280 + OSL_TRACE("** Unload() ");
281 + if ( m_xDialog.is() )
283 + triggerTerminateEvent();
285 + // Search method
286 + SbxVariable* pMeth = SbObjModule::Find( String( RTL_CONSTASCII_USTRINGPARAM( "UnloadObject" ) ), SbxCLASS_METHOD );
287 + if( pMeth )
289 + OSL_TRACE("Attempting too run the UnloadObjectMethod");
290 + m_xDialog = NULL; //release ref to the uno object
291 + SbxValues aVals;
292 + FormObjEventListenerImpl* pFormListener = dynamic_cast< FormObjEventListenerImpl* >( m_DialogListener.get() );
293 + bool bWaitForDispose = true; // assume dialog is showing
294 + if ( pFormListener )
296 + bWaitForDispose = pFormListener->isShowing();
297 + OSL_TRACE("Showing %d", bWaitForDispose );
299 + pMeth->Get( aVals);
300 + if ( !bWaitForDispose )
302 + // we've either already got a dispose or we'er never going to get one
303 + ResetApiObj();
304 + } // else wait for dispose
305 + OSL_TRACE("UnloadObject completed ( we hope )");
309 +void SbUserFormModule::InitObject()
311 + try
314 + if ( m_xModel.is() )
316 + uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
317 + uno::Sequence< uno::Any > aArgs(1);
318 + aArgs[ 0 ] <<= m_xModel;
319 + rtl::OUString sDialogUrl( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:" ) );
320 + sDialogUrl = sDialogUrl.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ) ).concat( rtl::OUString( '.') ).concat( GetName() ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?location=document") ) );
322 + uno::Reference< awt::XDialogProvider > xProvider( xFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.DialogProvider")), aArgs ), uno::UNO_QUERY_THROW );
323 + m_xDialog = xProvider->createDialog( sDialogUrl );
325 + // create vba api object
326 + aArgs.realloc( 3 );
327 + aArgs[ 0 ] = uno::Any();
328 + aArgs[ 1 ] <<= m_xDialog;
329 + aArgs[ 2 ] <<= m_xModel;
330 + pDocObject = new SbUnoObject( GetName(), uno::makeAny( xFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.UserForm")), aArgs ) ) );
331 + uno::Reference< lang::XComponent > xComponent( aArgs[ 1 ], uno::UNO_QUERY_THROW );
332 + // remove old listener if it exists
333 + FormObjEventListenerImpl* pFormListener = dynamic_cast< FormObjEventListenerImpl* >( m_DialogListener.get() );
334 + if ( pFormListener )
335 + pFormListener->removeListener();
336 + m_DialogListener = new FormObjEventListenerImpl( this, xComponent );
338 + triggerInitializeEvent();
339 + }
341 + catch( uno::Exception& e )
347 +SbxVariable*
348 +SbUserFormModule::Find( const XubString& rName, SbxClassType t )
350 + if ( !pDocObject && !GetSbData()->bRunInit )
351 + InitObject();
352 + return SbObjModule::Find( rName, t );
354 /////////////////////////////////////////////////////////////////////////
356 SbProperty::SbProperty( const String& r, SbxDataType t, SbModule* p )
357 diff --git basic/source/runtime/methods.cxx basic/source/runtime/methods.cxx
358 index 792bce2..a0c3cad 100644
359 --- basic/source/runtime/methods.cxx
360 +++ basic/source/runtime/methods.cxx
361 @@ -126,6 +126,8 @@ using namespace com::sun::star::io;
363 using namespace rtl;
365 +#include <basic/sbobjmod.hxx>
367 static void FilterWhiteSpace( String& rStr )
369 rStr.EraseAllChars( ' ' );
370 @@ -4135,7 +4137,12 @@ RTLFUNC(Load)
372 // Diesen Call einfach an das Object weiterreichen
373 SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
374 - if( pObj && pObj->IsA( TYPE( SbxObject ) ) )
375 + if( pObj && pObj->IsA( TYPE( SbUserFormModule ) ) )
377 + SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj;
378 + pFormModule->load();
380 + else if( pObj && pObj->IsA( TYPE( SbxObject ) ) )
382 SbxVariable* pVar = ((SbxObject*)pObj)->
383 Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD );
384 @@ -4158,7 +4165,12 @@ RTLFUNC(Unload)
386 // Diesen Call einfach an das Object weitereichen
387 SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
388 - if( pObj && pObj->IsA( TYPE( SbxObject ) ) )
389 + if( pObj && pObj->IsA( TYPE( SbUserFormModule ) ) )
391 + SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj;
392 + pFormModule->Unload();
394 + else if( pObj && pObj->IsA( TYPE( SbxObject ) ) )
396 SbxVariable* pVar = ((SbxObject*)pObj)->
397 Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD );