1# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- 2# 3# This file is part of the LibreOffice project. 4# 5# This Source Code Form is subject to the terms of the Mozilla Public 6# License, v. 2.0. If a copy of the MPL was not distributed with this 7# file, You can obtain one at http://mozilla.org/MPL/2.0/. 8# 9 10# prepare Python environment - Add the path of this class 11from os import path 12from sys import modules 13from sys import path as syspath 14 15# pyUNO program itself 16import uno, unohelper 17 18# UNO GUI toolkit 19from com.sun.star.awt.WindowClass import TOP, SIMPLE 20from com.sun.star.awt.PushButtonType import STANDARD as standard 21from com.sun.star.awt.PushButtonType import OK as ok 22from com.sun.star.awt.PushButtonType import CANCEL as cancel 23from com.sun.star.awt.PushButtonType import HELP as help 24from com.sun.star.awt.TextAlign import CENTER as center 25from com.sun.star.awt.TextAlign import LEFT as left 26from com.sun.star.awt.TextAlign import RIGHT as right 27 28# used UNO listeners 29from com.sun.star.awt import XActionListener 30 31class MsgBox(unohelper.Base): 32 """Inspect UNO object, link to sdk and recursive calls""" 33 34 def __init__(self, aContext): 35 """acontext : a Valid UNO context 36 """ 37 38 self.VERSION = '0.1' 39 self.ctx = aContext 40 self.smgr = aContext.ServiceManager 41 # UI Dialog object 42 self.dialog=None 43 # List of opened Listeners 44 self.lst_listeners={} 45 #UI parameters 46 self.ButtonSize = 50 47 self.boxSize = 200 48 self.lineHeight = 10 49 self.fromBroxSize = False 50 self.numberOfLines = -1 51 52 self.Buttons = [] 53 self.Response = '' 54 55 return 56 57 ##################################################### 58 # GUI definition # 59 ##################################################### 60 def _createBox(self): 61 """Create the Box""" 62 63 # computes parameters of the message dialog 64 if self.numberOfLines == -1: 65 #calculate 66 numberOfLines = len(self.message.split(chr(10))) 67 else: 68 numberOfLines = self.numberOfLines 69 70 numberOfButtons = len(self.Buttons) 71 self.ButtonSpace = self.ButtonSize/2 72 if self.fromBroxSize: 73 # button size is calculated from boxsize 74 size = (2 * self.boxSize) / (3 * numberOfButtons + 1) 75 self.ButtonSize = size 76 self.ButtonSpace = self.ButtonSize/2 77 else: 78 # boxsize is calculated from buttonsize 79 self.boxSize = numberOfButtons * (self.ButtonSize + 80 self.ButtonSpace) + self.ButtonSpace 81 82 # create the dialog model and set the properties 83 dialog_model = self.smgr.createInstanceWithContext( 84 'com.sun.star.awt.UnoControlDialogModel', 85 self.ctx) 86 dialog_model.PositionX = 50 87 dialog_model.Step = 1 88 dialog_model.TabIndex = 7 89 dialog_model.Width = self.boxSize#numberOfButtons * (self.ButtonSize + 90 # self.ButtonSpace) + 25 91 dialog_model.Height = 10 + self.lineHeight * numberOfLines + 10 + 12 + 10 92 dialog_model.PositionY = 63 93 dialog_model.Sizeable = True 94 dialog_model.Closeable = False 95 96 dialog = self.smgr.createInstanceWithContext( 97 'com.sun.star.awt.UnoControlDialog', self.ctx) 98 99 # label Label0 100 label = dialog_model.createInstance( 101 'com.sun.star.awt.UnoControlFixedTextModel') 102 label.PositionX = 10 103 label.TabIndex = 9 104 label.Width = dialog_model.Width - label.PositionX 105 label.Height = self.lineHeight* numberOfLines 106 label.PositionY = 10 107 label.Align = left 108 label.MultiLine = True 109 label.Label = self.message 110 dialog_model.insertByName('Label0', label) 111 112 nb = 0 113 for buttonName in self.Buttons: 114 nb +=1 115 button = dialog_model.createInstance( 116 'com.sun.star.awt.UnoControlButtonModel') 117 button.PositionX = nb * self.ButtonSpace + (nb-1)* self.ButtonSize 118 button.TabIndex = 8 119 button.Height = 12 120 button.Width = self.ButtonSize 121 button.PositionY = 10 + label.Height + 10 122 button.PushButtonType = standard 123 if nb == 1: 124 button.DefaultButton = True 125 else: 126 button.DefaultButton = False 127 button.Label = buttonName 128 dialog_model.insertByName('Btn' + str(nb), button ) 129 130 if not dialog.getModel(): 131 dialog.setModel(dialog_model) 132 133 # UNO toolkit definition 134 toolkit = self.smgr.createInstanceWithContext('com.sun.star.awt.Toolkit', self.ctx) 135 a_rect = uno.createUnoStruct( 'com.sun.star.awt.Rectangle' ) 136 a_rect.X = 50 137 dialog.setTitle ( self.title ) 138 a_rect.Width = 270 139 a_rect.Height = 261 140 a_rect.Y = 63 141 win_descriptor = uno.createUnoStruct('com.sun.star.awt.WindowDescriptor') 142 win_descriptor.Type = TOP 143 win_descriptor.ParentIndex = -1 144 win_descriptor.Bounds = a_rect 145 peer = toolkit.createWindow( win_descriptor ) 146 dialog.createPeer( toolkit, peer ) 147 148 return dialog 149 150 def _addListeners(self): 151 """Add listeners to dialog""" 152 nb = 0 153 for buttonName in self.Buttons: 154 nb +=1 155 a_control = self.dialog.getControl('Btn'+str(nb)) 156 the_listener = ButtonListener(self) 157 a_control.addActionListener(the_listener) 158 self.lst_listeners['Btn'+str(nb)] = the_listener 159 return 160 161 def _removeListeners(self): 162 """ remove listeners on exiting""" 163 nb = 0 164 for buttonName in self.Buttons: 165 nb +=1 166 a_control = self.dialog.getControl('Btn'+str(nb)) 167 a_control.removeActionListener(self.lst_listeners['Btn'+str(nb)]) 168 return 169 170 def show(self, message, decoration, title): 171 self.message = message 172 self.decoration = decoration 173 self.title = title 174 # Create GUI 175 self.dialog = self._createBox() 176 self._addListeners() 177 #execute the dialog --> blocking call 178 self.dialog.execute() 179 #end --> release listeners and dispose dialog 180 self._removeListeners() 181 self.dialog.dispose() 182 return self.Response 183 184 def addButton(self, caption): 185 self.Buttons.append(caption) 186 return 187 188 def renderFromBoxSize(self, size = 150): 189 self.boxSize = size 190 self.fromBroxSize = True 191 return 192 193 def renderFromButtonSize(self, size = 50): 194 self.ButtonSize = size 195 self.fromBroxSize = False 196 return 197 198class ButtonListener(unohelper.Base, XActionListener): 199 """Stops the MessageBox, sets the button label as returned value""" 200 def __init__(self, caller): 201 self.caller = caller 202 203 def disposing(self, eventObject): 204 pass 205 206 def actionPerformed(self, actionEvent): 207 button = actionEvent.Source 208 self.caller.Response = button.Model.Label 209 self.caller.dialog.endExecute() 210 return 211 212### TEST 213if __name__ == '__main__': 214 # get the uno component context from the PyUNO runtime 215 localContext = uno.getComponentContext() 216 217 # create the UnoUrlResolver 218 resolver = localContext.ServiceManager.createInstanceWithContext( 219 "com.sun.star.bridge.UnoUrlResolver", localContext ) 220 221 # connect to the running office 222 # LibO has to be launched in listen mode as 223 # ./soffice "--accept=socket,host=localhost,port=2002;urp;" 224 ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" ) 225 myBox = MsgBox(ctx) 226 myBox.addButton("Yes") 227 myBox.addButton("No") 228 myBox.addButton("May be") 229 myBox.renderFromBoxSize(150) 230 myBox.numberOflines = 2 231 232 print(myBox.show("A very long message A very long message A very long message A very long message A very long message A very long message A very long message A very long message A very long message A very long message " + chr(10)+chr(10)+"Do you agree ?",0,"Dialog title")) 233 234 myBox = MsgBox(ctx) 235 myBox.addButton("oK") 236 myBox.renderFromButtonSize() 237 myBox.numberOflines = 2 238 239 print(myBox.show("A small message",0,"Dialog title")) 240 241# vim: set shiftwidth=4 softtabstop=4 expandtab: 242