thom314 OOo Enthusiast


Joined: 03 Aug 2005 Posts: 186 Location: Denver, Colorado
|
Posted: Mon Jul 17, 2006 11:19 pm Post subject: Hijacking Dialogs - FilePicker Preview (Again) |
|
|
This code demonstrates the ability to hijack an OO dialog like the "Insert picture" dialog so that you can use it in your own macro to do your own desired action. I intercept the posting of the dialog with a top window listener, add a new button to the dialog, and then use that button to dismiss the dialog and return control to the subroutine that posted the dialog. The posting subroutine has access to the dialog's return value.
I believe that this approach could be used for any OO dialog. In fact, you could use the "Start Application" event to set a Top Window listener from the very startup of OO and, as OO dialogs are posted, identify the dialogs that you are interested in and selectively add or subtract features.
I have gotten the ideas for this from many contributors to the forums but especially ms777. See http://www.oooforum.org/forum/viewtopic.phtml?t=38165 and http://www.oooforum.org/forum/viewtopic.phtml?t=38771
| Code: |
REM ***** BASIC *****
Option Explicit
REM This code demonstrates hijacking of OO dialogs so that you can
REM use them in your own macros and
REM do whatever you want with the result versus letting OO do what
REM it wants. This example is for posting the "Insert picture" dialog
REM and intercepting the results.
Private sFileUrl As String
Sub HijackTheInsertPictureDialog
REM create a frame dispatcher so we can post the dialog
Dim oFrame As Variant : Dim oDispatcher As Variant
oFrame = ThisComponent.CurrentController.Frame
oDispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
REM create a top window listener so that we can intercept the dialog
Dim oAwtToolkit As Variant : Dim oTopListener As Variant
oAwtToolkit = oFrame.ContainerWindow.Toolkit
oTopListener = createUnoListener("TopWindow_", "com.sun.star.awt.XTopWindowListener")
REM now post the dialog
oAwtToolkit.addTopWindowListener( oTopListener )
oDispatcher.executeDispatch(oFrame, ".uno:InsertGraphic", "", 0, Array())
oAwtToolkit.removeTopWindowListener( oTopListener )
REM and here are the results!
If sFileUrl = "" Then
MsgBox "you cancelled!"
Else
MsgBox sFileUrl
End If
End Sub
Private beenDone As Boolean ' just a safety measure
Private oPictureDialog As Variant
Sub TopWindow_windowOpened( event as Object)
REM TopWindow listeners can be dangerous, so take some precautions
If beenDone Then Exit Sub
beenDone = TRUE
REM the "Insert picture" dialog is the event source
oPictureDialog = event.Source
REM disable the existing "Open" button which is accessible child 8
Dim oOldOpenButton As Variant
oOldOpenButton = oPictureDialog.AccessibleContext.getAccessibleChild( 8 )
oOldOpenButton.setEnable( FALSE )
REM now get an awt toolkit so we can construct our own "Open" button
Dim oAwtToolkit As Variant
oAwtToolkit = oOldOpenButton.Toolkit
REM make a new "Open" button placed on top of the old "Open" button
Dim oNewOpenButtonCtrl As Variant : Dim oNewOpenButtonModel As Variant
oNewOpenButtonCtrl = CreateUnoService( "com.sun.star.awt.UnoControlButton" )
oNewOpenButtonModel = CreateUnoService( "com.sun.star.awt.UnoControlButtonModel" )
oNewOpenButtonCtrl.setModel( oNewOpenButtonModel )
oNewOpenButtonCtrl.createPeer( oAwtToolkit, oOldOpenButton )
oNewOpenButtonModel.Label = "Open"
oNewOpenButtonCtrl.setPosSize( 0, 0,_
oOldOpenButton.PosSize.Width, oOldOpenButton.PosSize.Height,_
com.sun.star.awt.PosSize.POSSIZE )
REM and finally, add a button action listener
Dim vActionListener As Variant
vActionListener = CreateUnoListener( "NewOpenButton_", "com.sun.star.awt.XActionListener" )
oNewOpenButtonCtrl.addActionListener( vActionListener )
end sub
sub TopWindow_windowClosing(e as Object)
end sub
sub TopWindow_windowClosed(e as Object)
end sub
sub TopWindow_windowMinimized(e as Object)
end sub
sub TopWindow_windowNormalized(e as Object)
end sub
sub TopWindow_windowActivated(e as Object)
end sub
sub TopWindow_windowDeactivated(e as Object)
end sub
Sub NewOpenButton_actionPerformed(oAction)
REM the CANCEL button is subchild 9
REM the File Path text is subchild 15
REM the File Name text is subchild 1, subchild 0
REM set the sFileUrl return variable
With oPictureDialog.AccessibleContext
If .getAccessibleChild(1).AccessibleContext.getAccessibleChild(0).Text = "" Then Exit Sub
sFileUrl = .getAccessibleChild(15).Text & "\" & _
.getAccessibleChild(1).AccessibleContext.getAccessibleChild(0).Text
End With
REM error check
If NOT FileExists( sFileUrl ) Then
MsgBox sFileUrl & " does not exist!", 16
sFileUrl = ""
Exit Sub
End If
REM do the CANCEL action to dismiss the dialog and return control to the routine that
REM posted the dialog
oPictureDialog.AccessibleContext.getAccessibleChild(9).AccessibleContext.doAccessibleAction(0)
End Sub
|
Note: editted the actionPerformed subroutine 18 July 2006 to add some error checking of the user's input. Behavior now matches the normal Insert Picture dialog.
Last edited by thom314 on Tue Jul 18, 2006 6:02 pm; edited 2 times in total |
|
thom314 OOo Enthusiast


Joined: 03 Aug 2005 Posts: 186 Location: Denver, Colorado
|
Posted: Tue Jul 18, 2006 12:37 am Post subject: |
|
|
One note of caution to this technique. I use the Accessibility interface for the dialog. This example was built and tested on OO 2.0. It is possible that the accessible child tree structure could be different on OO 1.x or OO 3.x . If that is the case then the accessible child indices would need to be adjusted.
Plus, you need to be using the native OO dialogs and not the operating system's ones. |
|