I have a chart in a calc spreadsheet and I'd like to display the chart in a dialog box using a Python macro.
I'm comfortable with Python, and have no problem using Python to create the dialog window with radio buttons, listboxes, imageboxes and whatever, but I'm completely stumped with how to get a chart into the dialog.
Can anyone point me in the right direction?
[Solved] [Python] Display Calc chart in dialog
[Solved] [Python] Display Calc chart in dialog
Last edited by kiloran on Tue Jun 16, 2020 8:55 pm, edited 1 time in total.
--kiloran
LibreOffice 6 on Windows 10 and Linux Mint
LibreOffice 6 on Windows 10 and Linux Mint
Re: [Python] Display Calc chart in dialog
A Basic module which generates a dialog showing a push button and 2 documents side by side.
Code: Select all
REM ***** BASIC *****
global component1
global component2
Sub Main
component1 = Null
component2 = Null
' Get an AWT toolkit.
' OOo's AWT, not a Java AWT.
oAwtToolkit = CreateUnoService( "com.sun.star.awt.Toolkit" )
' Create a top level window.
oWindow = CreateTopWindow( oAwtToolkit, 100, 200, 800, 700 )
' Create a sub-window.
oSubWindow = CreateSubWindow( oAwtToolkit, oWindow, 100, 200, 300, 400 )
' Create a sub-window.
oSubWindow2 = CreateSubWindow( oAwtToolkit, oWindow, 450, 200, 300, 400 )
' Create a Window Listener
oTopWindowListener = CreateUnoListener( "TopWindowListener_","com.sun.star.awt.XTopWindowListener" )
oWindow.addTopWindowListener(oTopWindowListener)
' At this point, you should check out the interfaces
' and all of the methods that they give you for
' manipulating this new oWindow.
' See comment in CreateTopWindow() below.
' Change the background color of the window to baby blue.
oWindow.setBackground( RGB( 240, 240, 255 ) )
' At this point, if you stop the program, you will have a
' new OOo window on the screen, but you cannot do anything
' with it. You cannot even close it!
' In fact, you have to kill the OOo process, as even OOo
' cannot close this window since it has no Frame and
' therefore is not integrated into the desktop environment.
' So I had to go on writing additional code....
' Create a new frame.
oFrame = CreateUnoService( "com.sun.star.frame.Frame" )
' Initialize this frame with our new window.
oFrame.initialize( oWindow )
' Tell the frame that its parent is the Desktop.
oFrame.setCreator( StarDesktop )
' At this point you have a window that can be resized, moved, or closed.
' Create a new frame.
oSubFrame = CreateUnoService( "com.sun.star.frame.Frame" )
' Initialize this frame with our new window.
oSubFrame.initialize( oSubWindow )
' Tell the frame that its parent is the Desktop.
oSubFrame.setCreator( StarDesktop )
' Create a new frame.
oSubFrame2 = CreateUnoService( "com.sun.star.frame.Frame" )
' Initialize this frame with our new window.
oSubFrame2.initialize( oSubWindow2 )
' Tell the frame that its parent is the Desktop.
oSubFrame2.setCreator( StarDesktop )
' add subframe to main frame
oFrame.getFrames().append(oSubFrame)
oFrame.getFrames().append(oSubFrame2)
frames = oFrame.getFrames()
'wait(500)
'msgbox "Num Frames: " & frames.getCount()
' Note that if you wanted to, you could now load a component
' into your newly created window!
component1 = oSubFrame.loadComponentFromURL( "private:factory/simpress","_self", 0, Array() )
' Note that if you wanted to, you could now load a component
' into your newly created window!
component2 = oSubFrame2.loadComponentFromURL( "private:factory/scalc","_self", 0, Array() )
' Create a new button.
oBtnCtrl = MakeButtonCtrl( oAwtToolkit, oWindow, "Meow",_
MakeRectangle( 20, 30, 100, 40 ) )
' Create a menu.
' CreateMenuBar( oWindow )
' menubar to be provided later....
' okay, well maybe not, see below...
'wait(10 * 1000) ' wait ten seconds
'msgbox "Click okay to close first frame..."
'component1.close(false)
'msgbox "Click okay to close second frame..."
'component2.close(false)
exit sub
Main_error:
msgbox "error!"
resume next
End Sub
Sub TopWindowListener_TopWindowListener(oEventObject)
End Sub
Sub TopWindowListener_windowClosing(oEventObject)
'msgbox "window closing!"
'wait(1000)
'msgbox "Click okay to close first frame..."
if not isNull(component1) then
component1.close(false)
end if
'msgbox "Click okay to close second frame..."
if not isNull(component2) then
component2.close(false)
end if
'wait(10000)
End Sub
Sub TopWindowListener_windowClosed(oEventObject)
End Sub
Sub TopWindowListener_windowMinimized(oEventObject)
End Sub
Sub TopWindowListener_windowNormalized(oEventObject)
End Sub
Sub TopWindowListener_windowActivated(oEventObject)
End Sub
Sub TopWindowListener_windowDeactivated(oEventObject)
End Sub
Sub TopWindowListener_disposing(oEventObject)
'msgbox "Disposing..."
'wait(1000)
End Sub
Function CreateTopWindow( oAwtToolkit, x, y, w, h )
oWindowDesc = CreateUnoStruct( "com.sun.star.awt.WindowDescriptor" )
With oWindowDesc
' specifies a top level window on the desktop. It is also a container.
.Type = com.sun.star.awt.WindowClass.TOP
' is a modal top level window on the desktop. It is also a container.
' .Type = com.sun.star.awt.WindowClass.MODALTOP
' is a container that may contain other components. It is not a top window.
' .Type = com.sun.star.awt.WindowClass.CONTAINER
' is the simplest window. It can be a container.
' .Type = com.sun.star.awt.WindowClass.SIMPLE
' specifies the name of the component service.
' A zero length name means that the vcl creates a blank top,
' a container, or a simple window.
.WindowServiceName = ""
' specifies the parent of the component.
' If Parent == 0 && ParentIndex == -1 , then the window is on the desktop.
' .Parent = null
' .Parent = createUnoValue( "com.sun.star.awt.XWindowPeer", 0 )
' .Parent = oAwtToolkit.getDesktopWindow()
' specifies the index of the parent window, if available.
' If Parent == 0 and this struct is a member of an array,
' then this is the offset from the beginning of the array to the parent.
' A value of -1 means desktop.
' .ParentIndex = -1
' specifies the position and size of the window.
' This member is ignored if the window attribute is
' WindowAttribute::FULLSIZE .
.Bounds = MakeRectangle( x, y, w, h )
' specifies the window attributes.
.WindowAttributes = 0
' specifies that the window is initially visible.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.SHOW
' specifies that the window fills the complete desktop area.
' .WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.FULLSIZE
' specifies that the window is optimum size.
' .WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.OPTIMUMSIZE
' specifies that the window is minimum size.
' .WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.MINSIZE
' specifies that the window has visible borders.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.BORDER
' specifies that the size of the window can be changed by the user.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.SIZEABLE
' specifies that the window can be moved by the user.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.MOVEABLE
' specifies that the window can be closed by the user.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.CLOSEABLE
'[ DEPRECATED ] specifies that the window should support the XSystemDependentWindowPeer interface.
' .WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.SYSTEMDEPENDENT
End With
oXWindowPeer = oAwtToolkit.createWindow( oWindowDesc )
' Look at the capabilities that these interfaces give you
' for manipulating your newly created window.
' Interfaces supported by oXWindowPeer...
' com.sun.star.awt.XTopWindow
' com.sun.star.awt.XWindow
' com.sun.star.awt.XWindowPeer
' com.sun.star.awt.XVclContainer
' com.sun.star.awt.XVclContainerPeer
' com.sun.star.awt.XVclWindowPeer
' com.sun.star.awt.XLayoutConstraints
' com.sun.star.awt.XView
' com.sun.star.awt.XDevice
' com.sun.star.lang.XEventListener
' com.sun.star.lang.XComponent
' com.sun.star.lang.XTypeProvider
' com.sun.star.accessibility.XAccessible
'
' Properties...
' <object> MenuBar
' <array> Windows
' <array> Group
' <object> PosSize
' Boolean Visible
' Boolean Enable
' <object> Toolkit
' <object> Pointer
' Long Background
' Boolean DesignMode
' Long Foreground
' <object> ControlFont
' <object> MinimumSize
' <object> PreferredSize
' <object> AccessibleContext
' <object> Graphics
' <object> Size
' <object> Info
' <array> FontDescriptors
CreateTopWindow = oXWindowPeer
End Function
Function CreateSubWindow( oAwtToolkit, parentWindow, x, y, w, h )
oWindowDesc = CreateUnoStruct( "com.sun.star.awt.WindowDescriptor" )
With oWindowDesc
' specifies a top level window on the desktop. It is also a container.
' .Type = com.sun.star.awt.WindowClass.TOP
' is a modal top level window on the desktop. It is also a container.
' .Type = com.sun.star.awt.WindowClass.MODALTOP
' is a container that may contain other components. It is not a top window.
' .Type = com.sun.star.awt.WindowClass.CONTAINER
' is the simplest window. It can be a container.
.Type = com.sun.star.awt.WindowClass.SIMPLE
' specifies the name of the component service.
' A zero length name means that the vcl creates a blank top,
' a container, or a simple window.
.WindowServiceName = ""
' specifies the parent of the component.
' If Parent == 0 && ParentIndex == -1 , then the window is on the desktop.
' .Parent = 0
' .Parent = createUnoValue( "com.sun.star.awt.XWindowPeer", 0 )
' .Parent = oAwtToolkit.getDesktopWindow()
.Parent = parentWindow
' specifies the index of the parent window, if available.
' If Parent == 0 and this struct is a member of an array,
' then this is the offset from the beginning of the array to the parent.
' A value of -1 means desktop.
' .ParentIndex = -1
' specifies the position and size of the window.
' This member is ignored if the window attribute is
' WindowAttribute::FULLSIZE .
.Bounds = MakeRectangle( x, y, w, h )
' specifies the window attributes.
.WindowAttributes = 0
' specifies that the window is initially visible.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.SHOW
' specifies that the window fills the complete desktop area.
' .WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.FULLSIZE
' specifies that the window is optimum size.
' .WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.OPTIMUMSIZE
' specifies that the window is minimum size.
' .WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.MINSIZE
' specifies that the window has visible borders.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.BORDER
' specifies that the size of the window can be changed by the user.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.SIZEABLE
' specifies that the window can be moved by the user.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.MOVEABLE
' specifies that the window can be closed by the user.
.WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.CLOSEABLE
'[ DEPRECATED ] specifies that the window should support the XSystemDependentWindowPeer interface.
' .WindowAttributes = .WindowAttributes + com.sun.star.awt.WindowAttribute.SYSTEMDEPENDENT
End With
oXWindowPeer = oAwtToolkit.createWindow( oWindowDesc )
' Look at the capabilities that these interfaces give you
' for manipulating your newly created window.
' Interfaces supported by oXWindowPeer...
' com.sun.star.awt.XTopWindow
' com.sun.star.awt.XWindow
' com.sun.star.awt.XWindowPeer
' com.sun.star.awt.XVclContainer
' com.sun.star.awt.XVclContainerPeer
' com.sun.star.awt.XVclWindowPeer
' com.sun.star.awt.XLayoutConstraints
' com.sun.star.awt.XView
' com.sun.star.awt.XDevice
' com.sun.star.lang.XEventListener
' com.sun.star.lang.XComponent
' com.sun.star.lang.XTypeProvider
' com.sun.star.accessibility.XAccessible
'
' Properties...
' <object> MenuBar
' <array> Windows
' <array> Group
' <object> PosSize
' Boolean Visible
' Boolean Enable
' <object> Toolkit
' <object> Pointer
' Long Background
' Boolean DesignMode
' Long Foreground
' <object> ControlFont
' <object> MinimumSize
' <object> PreferredSize
' <object> AccessibleContext
' <object> Graphics
' <object> Size
' <object> Info
' <array> FontDescriptors
CreateSubWindow = oXWindowPeer
End Function
Function MakeButtonCtrl( oAwtToolkit, oWindow, Optional cLabel, Optional oPosSizeRect )
' Create a new button model.
oButtonModel = CreateUnoService( "com.sun.star.awt.UnoControlButtonModel")
' Create a new button control.
oButtonCtrl = CreateUnoService( "com.sun.star.awt.UnoControlButton" )
' Tell the control that it has a model.
oButtonCtrl.setModel( oButtonModel )
' Tell the control to create its window peer.
' (To understand what this means, it is helpful to
' read some Java documention about how Java's AWT works
' even though we're not working with Java AWT here.)
' Basically, this puts something visible onto the window.
oButtonCtrl.createPeer( oAwtToolkit, oWindow )
If Not IsMissing( cName ) Then
oButtonModel.Label = cLabel
oButtonModel.ImageURL = "file:///c:/tmp/test-small.jpg"
EndIf
If Not IsMissing( oPosSizeRect ) Then
oButtonCtrl.setPosSize( _
oPosSizeRect.X, oPosSizeRect.Y,_
oPosSizeRect.Width, oPosSizeRect.Height,_
com.sun.star.awt.PosSize.POSSIZE )
EndIf
MakeButtonCtrl = oButtonCtrl
End Function
' ripped from my library....
Function MakeRectangle( ByVal nX As Long, ByVal nY As Long,_
ByVal nWidth As Long, ByVal nHeight As Long ) As com.sun.star.awt.Rectangle
oRectangle = createUnoStruct( "com.sun.star.awt.Rectangle" )
With oRectangle
.X = nX
.Y = nY
.Width = nWidth
.Height = nHeight
End With
MakeRectangle() = oRectangle
End Function
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Re: [Python] Display Calc chart in dialog
Another option is to export the chart as a picture and then load it into an image control in the dialog.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
-
- Posts: 145
- Joined: Mon Jun 13, 2016 10:50 am
Re: [Python] Display Calc chart in dialog
Hi,
Here's two examples, based on JeJe suggestion.
The first uses a dialog designed with the basic gui editor.
The second creates the dialog from scratch. The later code :
Regards.
Here's two examples, based on JeJe suggestion.
The first uses a dialog designed with the basic gui editor.
The second creates the dialog from scratch. The later code :
Code: Select all
def createdialog2(event=None):
doc = XSCRIPTCONTEXT.getDocument()
# get the chart image
sheet = doc.Sheets[0]
chart_bitmap = sheet.Charts[0].EmbeddedObject.DrawPage[0].Bitmap
chart_width = chart_bitmap.Size.Width
chart_height = chart_bitmap.Size.Height
# create the dialog
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.ServiceManager
dlg_model = smgr.createInstance("com.sun.star.awt.UnoControlDialogModel")
dlg = smgr.createInstance("com.sun.star.awt.UnoControlDialog")
dlg.setModel(dlg_model)
dlg.setPosSize(50, 50, chart_width+2*10, chart_height+6*10, 15)
dlg.Title = "Chart dialog"
# create OK button
OKbtn_model = smgr.createInstance("com.sun.star.awt.UnoControlButtonModel")
OKbtn_model.setPropertyValues(("DefaultButton", "PushButtonType"), (True, 1))
OKbtn = smgr.createInstance("com.sun.star.awt.UnoControlButton")
OKbtn.setModel(OKbtn_model)
OKbtn.setPosSize(10, chart_height+2*10, 10*10, 3*10, 15)
dlg.addControl("OKbtn", OKbtn)
# create picto control
picto_model = smgr.createInstance("com.sun.star.awt.UnoControlImageControlModel")
picto_model.Graphic = chart_bitmap
picto = smgr.createInstance("com.sun.star.awt.UnoControlImageControl")
picto.setModel(picto_model)
picto.setPosSize(10, 10, chart_width, chart_height, 15)
dlg.addControl("picto", picto)
# execute
dlg.setVisible(True)
dlg.execute()
dlg.dispose()
- Attachments
-
- chartdialog.ods
- LibreOffice only
- (21.97 KiB) Downloaded 249 times
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
Re: [Python] Display Calc chart in dialog
I got a runtime error on pushing the buttons - maybe that's because I don't use Python. But adapting the beginning of hubert lambert's code to Basic it works great... if anyone wants that...
Code: Select all
REM ***** BASIC *****
Sub Main
doc = thiscomponent
sheet = doc.Sheets(0)
chart_bitmap = sheet.Charts(0).EmbeddedObject.DrawPage(0).Bitmap
chart_width = chart_bitmap.Size.Width
chart_height = chart_bitmap.Size.Height
dlg = loaddialog("Standard","Dialog1")
dlg.getcontrol("picto").setpossize 0,0,chart_width,chart_height,12
dlg.getcontrol("picto").model.graphic = chart_bitmap
dlg.execute
end sub
Function LoadDialog(oLibraryName as String, oDialogName as String)
Dim oLib as Object
DialogLibraries.LoadLibrary(oLibraryName)
oLib = DialogLibraries.GetByName(oLibraryname)
LoadDialog() = CreateUnoDialog(oLib.GetByName(oDialogName))
End Function
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Re: [Solved][Python] Display Calc chart in dialog
That's brilliant, Hubert. Works perfectly on my Windows 10 and LibreOffice 6. Many many thanks.hubert lambert wrote:Hi,
Here's two examples, based on JeJe suggestion.
The first uses a dialog designed with the basic gui editor.
The second creates the dialog from scratch.
Regards.
And thanks to all for the other responses. I got rather sidetracked in recent weeks due to a failing SSD in my laptop. I had to replace it and then rebuild all my software. I think I'm now ready to get working on this again
--kiloran
LibreOffice 6 on Windows 10 and Linux Mint
LibreOffice 6 on Windows 10 and Linux Mint