OO-Snippets: Create a dialog at runtime

Commons

Keywordscreate, dialog, runtime
LanguageooRexx
ApplicationOffice
AuthorsJosef Frysak (initial)
Supported Versions2.4.1  
Supported OSAll  
QuestionHow to create a dialog at runtime?
Answer

Every element in a dialog and the dialog itself are Control Model objects.

Therefore create a "UnoControlDialogModel" which represents a dialog window.

It is able to hold other Control Models like the "UnoControlFixedTextModel"

or the "UnoControlButtonModel", which can be created using the

"XMultiServiceFactory" interface of the dialog. After creating these elements

they must be added to the dialog by creating a control object of the

dialog and using its "XControlContainer" interface. Also create a Toolkit

service and with it create a Windowpeer for the dialog. Next create a new

"Frame" object and use it to initiate the previously created windowpeer. This

will allow the dialog to close properly.

To notice the interaction with the user (i.e.: pressing the button) of a

ooRexx macro, it is also necessary to register specific listeners to the

corresponding elements. The interaction events can then be retrieved by

calling "bsf.pollEventText()" function.

For further details see http://wi.wu-wien.ac.at/rgf/diplomarbeiten/BakkStuff/2008/200809_Frysak/200809_Frysak_Automating_OOo_ooRexx_Nutshells.pdf.

Code-Snippet-Listing (snippet-source)

-- try to get a script context, will be .nil, if script was not invoked by OOo
x_ScriptContext = uno.getScriptContext()
if (x_ScriptContext <> .nil) then
do
   -- invoked by OOo as a macro

   -- get context
   x_ComponentContext = x_ScriptContext~getComponentContext
   -- get desktop (an XDesktop)
   x_Desktop  = x_ScriptContext~getDesktop
   -- get current document
   x_Document = x_ScriptContext~getDocument
end
else  
do
   -- called from outside of OOo, create a connection

   -- connect to Open Office and get component context
   x_ComponentContext = UNO.connect()
   -- create a desktop service and its interface
   service = "com.sun.star.frame.Desktop"
   s_Desktop = x_ComponentContext~getServiceManager~XMultiServiceFactory~createInstance(service)
   x_Desktop = s_Desktop~XDesktop
   -- get the last active document
   x_Document = x_Desktop~getCurrentComponent()  
end




/* 
***********************************
* Dialog Window
***********************************
*/

x_MultiServiceFactory = x_ComponentContext~getServiceManager()~XMultiServiceFactory

o_Dialog = x_MultiServiceFactory~createInstance("com.sun.star.awt.UnoControlDialogModel")

o_Dialog.Properties = o_Dialog~XPropertyset

o_Dialog.Properties~setPropertyValue("PositionX", box("int", 64))
o_Dialog.Properties~setPropertyValue("PositionY", box("int", 64))
o_Dialog.Properties~setPropertyValue("Width",     box("int", 256))
o_Dialog.Properties~setPropertyValue("Height",    box("int", (128-8)))
o_Dialog.Properties~setPropertyValue("Title",     "How much do you like ooRexx?")

o_Dialog.Factory = o_Dialog~XMultiServiceFactory
o_Dialog.Container = o_Dialog~XNameContainer

o_Dialog.Control = x_MultiServiceFactory~createInstance("com.sun.star.awt.UnoControlDialog")~XControl
o_Dialog.Control~setModel(o_Dialog~XControlModel)
o_Dialog.ControlContainer = o_Dialog.Control~XControlContainer

s_Toolkit = x_MultiServiceFactory~createInstance("com.sun.star.awt.Toolkit")
x_Toolkit = s_Toolkit~XToolkit

o_Dialog.Control~createPeer(x_Toolkit, .nil)

-- needed to let the Dialog dispose, if just displayed but not executed
s_Frame = x_MultiServiceFactory~createInstance("com.sun.star.frame.Frame")
x_Frame = s_Frame~XFrame

x_Frame~initialize(o_Dialog.Control~XWindow)


/* 
***********************************
* Label1
***********************************
*/

o_Label1 = o_Dialog.Factory~createInstance("com.sun.star.awt.UnoControlFixedTextModel")
o_Label1.Properties = o_Label1~XPropertySet

o_Label1.Properties~setPropertyValue("PositionX", box("int", 8))
o_Label1.Properties~setPropertyValue("PositionY", box("int", 40))
o_Label1.Properties~setPropertyValue("Width",     box("int", (256-16)))
o_Label1.Properties~setPropertyValue("Height",    box("int", 32))
o_Label1.Properties~setPropertyValue("Name",      "Label1")
o_Label1.Properties~setPropertyValue("TabIndex",  box("short", 1))
o_Label1.Properties~setPropertyValue("Label",     "Prefix1")

o_Dialog.Container~insertByName("Label1", o_Label1);

/*
***********************************
* Button1
***********************************
*/

o_Button1 = o_Dialog.Factory~createInstance("com.sun.star.awt.UnoControlButtonModel")
o_Button1.Properties = o_Button1~XPropertySet

o_Button1.Properties~setPropertyValue("PositionX", box("int", 8))
o_Button1.Properties~setPropertyValue("PositionY", box("int", 8))
o_Button1.Properties~setPropertyValue("Width",     box("int", (256-16)))
o_Button1.Properties~setPropertyValue("Height",    box("int", 32))
o_Button1.Properties~setPropertyValue("Name",      "Button1")
o_Button1.Properties~setPropertyValue("TabIndex",  box("short", 0))
o_Button1.Properties~setPropertyValue("Label",     "Click Me")

o_Dialog.Container~insertByName("Button1", o_Button1);
o_Button1.Control = o_Dialog.ControlContainer~getControl("Button1")

-- o_Button1.Control~XButton~bsf.addEventListener("action", "",               "noAction")
o_Button1.Control~XButton~bsf.addEventListener("action", "actionPerformed","Action")
o_Button1.Control~XButton~bsf.addEventListener("action", "disposing",      "close")


-- change mouse pointer apperance, whilst moving over label
-- define cursortypes
CursorWait = bsf.getConstant("com.sun.star.awt.SystemPointer", "WAIT")
CursorGo = bsf.getConstant("com.sun.star.awt.SystemPointer", "ARROW")

-- change cursortype
s_Pointer = x_MultiServiceFactory~createInstance("com.sun.star.awt.Pointer")
x_Pointer = s_Pointer~XPointer

cursorstate = 1


-- do not call "o_Dialog.Control~XDialog~execute()" otherwise
-- you do not have instant Listener report
o_Dialog.Control~XWindow~setVisible(.true)

-- .bsf.dialog~messageBox(output, "Currently Selected Text:", "information")
--   call Syssleep 1

do forever
-- somehow not calling Syssleep will create an error when calling this makro
-- by menu: tools -> macros -> run macro
   call Syssleep 0.5
   eventText=bsf.pollEventText(100) -- timeout of 100/1000 sec

   if eventText="close" then leave;   -- disposed
   if eventText="Action" then
   do
      if cursorstate then
      do
         x_Pointer~SetType(CursorWait)
         o_Button1.Control~getPeer()~setPointer(x_Pointer)
         cursorstate = 0
      end
      else
      do
         x_Pointer~SetType(CursorGo)
         o_Button1.Control~getPeer()~setPointer(x_Pointer)
         cursorstate = 1
      end
   end
end

o_Dialog.Control~XComponent~dispose()

::requires UNO.CLS

Changelog

DateUserModification
2008-10-131Initial version

and