Create fancy custom toolbars with OOo Basic

Shared Libraries
Forum rules
For sharing working examples of macros / scripts. These can be in any script language supported by OpenOffice.org [Basic, Python, Netbean] or as source code files in Java or C# even - but requires the actual source code listing. This section is not for asking questions about writing your own macros.
Post Reply
ms777
Volunteer
Posts: 177
Joined: Mon Oct 08, 2007 1:33 am

Create fancy custom toolbars with OOo Basic

Post by ms777 »

Hi,

this code shows two examples for custom designed toolbars. These are just very simple examples, the methods shown allow you to have complete control over your toolbar items and make them as fancy as you want. You only need to know OO Basic.

The first example generates a toolbar with a simple drop down box, very similar e.g. to the standard font selection drop down box. Whenever the user changes the selection, a listener is called (CBOX_itemStateChanged). In its current version, it only adds a line to the first sheet in the calc document. Overwrite this method to implement your own needs.

The second example uses the standard OO dialog capabilities to show a non modal dialog in the toolbar. I use it with a simple dialog created on the fly, but it should also work with dialogs defined by the OO Basic dialog editor capabilities. With this technique, you can transform all OO dialogs into non modal toolbar dialogs

In order to run this Do not worry: In order to use the code you do not have to understand it ...
  • install the code in any module in the same document
  • install the subroutines into any other module in the same document
  • run the code
To switch between the two examples, change the sub LGCB_createItemWindow in the main code as outlined there

Have fun,

ms777

P.S. Thanks to Peter for his Toolbar routines http://www.oooforum.org/forum/viewtopic.phtml?t=50877

The main code:

Code: Select all

Global logRow
Global logSheet

Sub Main

'define the strings we need
toolbarResourceUrl = "private:resource/toolbar/custom_ms777"
toolbarUIName = "Combobox via interface combine"
itemLabel = "MyLabel"
itemCommandUrl = ".uno:ms777Combobox"
itemService = "ms777.ToolbarCombobox"

'for the logging ...
logRow = 0
logSheet = ThisComponent.sheets.getByIndex(0)
logSheet.getCellRangeByPosition(0,0,0,1000).clearContents(com.sun.star.sheet.CellFlags.STRING)


logMessage("Start")

'the to-be-combined interfaces XInitialization, XStatusListener, XUpdatable, XServiceInfo, XToolbarController
listXInitialization = createUnoListener("LGCB_","com.sun.star.lang.XInitialization")
listXUpdatable = createUnoListener("LGCB_","com.sun.star.util.XUpdatable")
listXToolbarController = createUnoListener("LGCB_","com.sun.star.frame.XToolbarController")
listXServiceInfo = createUnoListener("LGCB_","com.sun.star.lang.XServiceInfo")
listXStatusListener = createUnoListener("LGCB_","com.sun.star.frame.XStatusListener")


oScript = ThisComponent.getScriptProvider("").getScript("vnd.sun.star.script:listenercombiner.listenercombiner.bsh?language=BeanShell&location=document")
oScript.invoke(Array(itemService, listXInitialization, listXUpdatable, listXToolbarController, _
   listXServiceInfo, listXStatusListener), Array(), Array())


call createToolbar(toolbarResourceUrl, toolbarUIName, itemLabel, itemCommandUrl, itemService)

logMessage("End")

End Sub

sub logMessage(sMessage as String)
logSheet.getCellByPosition(0,logRow).String = sMessage
logRow = logRow + 1
end sub


' here start the subs which are combined to form the toolbar window

'com.sun.star.lang.XInitialization
sub LGCB_initialize(args() as Any)
logMessage("initialize")
end sub


'com.sun.star.util.XUpdatable
sub LGCB_update()
logMessage("update")
end sub

'com.sun.star.lang.XServiceInfo
function LGCB_getImplementationName() as String
logMessage("getImplementationName")
LGCB_getImplementationName = "ms777.ToolbarCombobox"
end function

function LGCB_supportsService(s as String) as Boolean
logMessage("supportsService")
LGCB_supportsService = (s = "ms777.ToolbarCombobox")
end function

function LGCB_getSupportedServiceNames() as Any
logMessage("getSupportedServiceNames")
LGCB_getSupportedServiceNames = Array("ms777.ToolbarCombobox")
end function

'com.sun.star.frame.XStatusListener
sub LGCB_statusChanged(state as com.sun.star.frame.FeatureStateEvent)
logMessage("statusChanged")
end sub

sub LGCB_disposing(source as com.sun.star.lang.EventObject)
logMessage("disposing")
end sub



'com.sun.star.frame.XToolbarController
sub LGCB_execute(KeyModifier as integer)
logMessage("execute")
end sub

sub LGCB_click()
logMessage("click")
end sub

sub LGCB_doubleClick()
logMessage("doubleclick")
end sub

function LGCB_createPopupWindow() as com.sun.star.awt.XWindow 
logMessage("createPopupWindow")
end function

function LGCB_createItemWindow(wParent as com.sun.star.awt.XWindow) as com.sun.star.awt.XWindow
logMessage("createItemWindow start")
LGCB_createItemWindow = generateCBOXWindow(wParent) 'for first example
'LGCB_createItemWindow = generateDialogWindow(wParent) 'for second example
logMessage("createItemWindow end")
end function



'--------------  first example: generate a combobox in the toolbar
' see my earlier post http://www.oooforum.org/forum/viewtopic.phtml?p=188664#188664

function generateCBOXWindow(wParent as com.sun.star.awt.XWindow) as com.sun.star.awt.XWindow
'the itemlistener, which is added to the toolbar combobox
listItemListener = createUnoListener("CBOX_", "com.sun.star.awt.XItemListener")
oWindow = makeAwtWindow(wParent, 0, 0, 230, 20, "combobox", com.sun.star.awt.WindowAttribute.SHOW or com.sun.star.awt.VclWindowPeerAttribute.DROPDOWN)
oWindow.addItemListener(listItemListener)
oWindow.setText("Enter Command Here")
oWindow.addItems(Array( "test", "foo", "bar", "test2", "foo2", "bar2" ), 0)
oWindow.setDropDownLineCount(6)
generateCBOXWindow = oWindow
end function


' the listener to get the combobox events back to OO Basic

sub CBOX_itemStateChanged(event as com.sun.star.awt.ItemEvent)
lSelected = event.selected
s = "selection change to item # " + lSelected
if lSelected >=0 then s = s & ": " & event.source.items(lSelected)
logMessage(s)
'xray event
end sub


'--------------  second example: hijack a normal OO Basic generated dialog

function generateDialogWindow(wParent as com.sun.star.awt.XWindow) as com.sun.star.awt.XWindow
 oDialog = generateRadioButtonDialog(Array("first option", "longer option text", "even much more longer option text"))
 wDialog = makeAwtWindow(wParent, 0, 0, oDialog.Size.width, oDialog.Size.height, "window", com.sun.star.awt.WindowAttribute.SHOW)
 wDialog.Background = &HFF000000 'transparent

 oControls = oDialog.Controls
 for k=0 to UBound(oControls)
   oControls(k).createPeer(wDialog.Toolkit, wDialog)
 next k

 generateDialogWindow = wDialog
end function

'generateRadioButtonDialog creates a dialog on the fly ...
'it expects an array of strings showing the options the user can select
'see http://www.oooforum.org/forum/viewtopic.phtml?p=205497#205497 for a standalone version
'and some (?) explanations
function generateRadioButtonDialog(astrOptions) as Any 
Dim lTab as Long

const lDeltaFromEdge = 5   'controls spacing from the window edge and between controls
const lButtonWidth  = 80
const lButtonHeight = 30
   
oActionListener = CreateUnoListener( "RBD_", "com.sun.star.awt.XActionListener" ) 
    
oDialogModel = createUnoService( "com.sun.star.awt.UnoControlDialogModel" ) 
oDialogControl = createUnoService( "com.sun.star.awt.UnoControlDialog" ) 
oDialogControl.setModel( oDialogModel ) 

lTab = 0

lRadioButtonMinHeight = -1
lRadioButtonMinWidth  = -1
  
for k=0 to UBound(astrOptions) 'insert radio buttons and find out max height and width
  oRadioButtonModel = oDialogModel.createInstance( "com.sun.star.awt.UnoControlRadioButtonModel" ) 
  setNameTabLabel(oRadioButtonModel, "RB" & k, lTab, astrOptions(k))	
  oDialogModel.insertByName( oRadioButtonModel.Name, oRadioButtonModel )
  PrefSize = oDialogControl.getControl( "RB" & k).PreferredSize
  if PrefSize.Width  > lRadioButtonMinWidth  then lRadioButtonMinWidth  =  PrefSize.Width
  if PrefSize.Height > lRadioButtonMinHeight then lRadioButtonMinHeight =  PrefSize.Height
  next k

for k=0 to UBound(astrOptions) 'set the size of the radiobutton controls, mark the first as set
  oRadioButtonControl = oDialogControl.getControl( "RB" & k)
  oRadioButtonControl.setPosSize(lDeltaFromEdge, lDeltaFromEdge*(k+1) + lRadioButtonMinHeight * k, lRadioButtonMinWidth, lRadioButtonMinHeight, com.sun.star.awt.PosSize.POSSIZE)
  if (k=0) then oRadioButtonControl.State = True
  next k


'insert the Accept Button    
oButtonModel = oDialogModel.createInstance( "com.sun.star.awt.UnoControlButtonModel" ) 
setNameTabLabel(oButtonModel, "Accept", lTab, "Accept")	
oDialogModel.insertByName( oButtonModel.Name, oButtonModel ) 
oButtonControl = oDialogControl.getControl( oButtonModel.Name )
oButtonControl.setPosSize(2*lDeltaFromEdge+lRadioButtonMinWidth, lDeltaFromEdge, lButtonWidth, lButtonHeight, com.sun.star.awt.PosSize.POSSIZE)
oButtonControl.addActionListener( oActionListener ) 

'now determine the size of the overall dialog   
lDialogWidth  =  3*lDeltaFromEdge + lRadioButtonMinWidth + lButtonWidth
lDialogHeight =  (UBound(astrOptions)+1)*(lRadioButtonMinHeight+lDeltaFromEdge) + lDeltaFromEdge
oDialogControl.setPosSize( 0, 0, lDialogWidth, lDialogHeight, com.sun.star.awt.PosSize.POSSIZE)

generateRadioButtonDialog = oDialogControl
end function 

sub setNameTabLabel(o, n as String, Tab as long, Label as String)
o.Name = n
o.TabIndex = Tab
o.Label = Label
Tab = Tab+1
end sub

Sub RBD_actionPerformed( oEvent As com.sun.star.awt.ActionEvent ) 
oDialogControl = oEvent.Source.Context
s = "Button " & oEvent.Source.Model.Name & " pressed"
oC = oDialogControl.Controls
for k=0 to UBound(oC)
  if HasUnoInterfaces(oC(k), "com.sun.star.awt.XRadioButton") then
    s = s & ", RadBut " & k & " state: " & oC(k).Model.State
  endif
next k
logMessage(s)
end sub

The subroutines required:

Code: Select all

sub createToolbar(toolbarResourceUrl as String, toolbarUIName as String, itemLabel as String, _
                  itemCommandUrl as String, itemService as String)
'I heavily borrowed from Peter http://www.oooforum.org/forum/viewtopic.phtml?t=50877 when writing this

'register the itemService at the Toolbarfactory
oo = createUnoService("com.sun.star.frame.ToolbarControllerFactory")
if oo.hasController( itemCommandUrl, "") then oo.deregisterController( itemCommandUrl, "")
oo.registerController( itemCommandUrl, "", itemService)

'delete toolbar if existing
oLM = ThisComponent.CurrentController.Frame.Layoutmanager
if not IsNull(oLM.getElement(toolbarResourceUrl)) then oLM.destroyElement(toolbarResourceUrl)

'create toolbar
oLM.createElement(toolbarResourceUrl)

'insert one component into toolbar and set the UIName
oEL = oLM.getElement(toolbarResourceUrl)
oToolbarSettings = oEL.getSettings(true)
Dim aItem(1) as new com.sun.star.beans.PropertyValue 
aItem(0).Name = "CommandURL" 
aItem(0).Value = itemCommandUrl 
aItem(1).Name = "Label" 
aItem(1).Value = itemLabel 

oToolbarSettings.insertByIndex( 0, aItem ) 
oToolbarSettings.UIName = toolbarUIName 
oEL.setSettings(oToolbarSettings)
oEL.updateSettings
oLM.showElement(toolbarResourceUrl)

'make sure that the toolbar is docked in a separate new line in the docking area
cDockArea = com.sun.star.ui.DockingArea.DOCKINGAREA_TOP 
Dim aPos as New com.sun.star.awt.Point 
aPos.X = 0 
aPos.Y = 0 
oLM.dockWindow(toolbarResourceUrl,cDockArea,aPos) 

end sub


function makeAwtWindow(wParent as com.sun.star.awt.XWindow, x as integer, y as integer, width as integer, height as integer, wServiceName as String, wAttribute as long) as com.sun.star.awt.XWindow
oToolkit = createUnoService("com.sun.star.awt.Toolkit")

' create WindowDescriptor
Dim rBounds as new com.sun.star.awt.Rectangle
rBounds.X = x
rBounds.Y = y
rBounds.width = width
rBounds.height = height

Dim wd as new com.sun.star.awt.WindowDescriptor
wd.Type = com.sun.star.awt.WindowClass.SIMPLE
'wd.Type = com.sun.star.awt.WindowClass.CONTAINER
wd.Parent = wParent
wd.Bounds = rBounds
wd.ParentIndex = -1
wd.WindowAttributes = wAttribute
wd.WindowServiceName = wServiceName

makeAwtWindow = oToolkit.createWindow(wd)
end function
Last edited by ms777 on Sat Jun 20, 2015 2:09 pm, edited 1 time in total.
TerryE
Volunteer
Posts: 1402
Joined: Sat Oct 06, 2007 10:13 pm
Location: UK

Re: Create fancy custom toolbars with OOBasic

Post by TerryE »

Placeholder for Change Control and to remove topic from "View unanswered posts" list.
Ubuntu 11.04-x64 + LibreOffice 3 and MS free except the boss's Notebook which runs XP + OOo 3.3.
taipeihugo
Posts: 2
Joined: Sat May 23, 2015 4:48 am

Re: Create fancy custom toolbars with OOo Basic

Post by taipeihugo »

when the program run to
oo = createUnoService("com.sun.star.frame.ToolBarControllerFactory")
I got oo values is null,please tell me why,thanks.
OpenOffice 4.1.1 on Linux mint 17
ms777
Volunteer
Posts: 177
Joined: Mon Oct 08, 2007 1:33 am

Re: Create fancy custom toolbars with OOo Basic

Post by ms777 »

Hi,

8 years later ... wow !

If you change "com.sun.star.frame.ToolBarControllerFactory" to "com.sun.star.frame.ToolbarControllerFactory" it should work again

Cheers,

ms777
taipeihugo
Posts: 2
Joined: Sat May 23, 2015 4:48 am

Re: Create fancy custom toolbars with OOo Basic

Post by taipeihugo »

thank you ms777。^^
OpenOffice 4.1.1 on Linux mint 17
Post Reply