1# Class to display messages in an information line. 2 3import string 4import Tkinter 5import Pmw 6 7class MessageBar(Pmw.MegaWidget): 8 def __init__(self, parent = None, **kw): 9 10 # Define the megawidget options. 11 INITOPT = Pmw.INITOPT 12 defaultMessageTypes = { 13 # (priority, showtime, bells, logmessage) 14 'systemerror' : (5, 10, 2, 1), 15 'usererror' : (4, 5, 1, 0), 16 'busy' : (3, 0, 0, 0), 17 'systemevent' : (2, 5, 0, 0), 18 'userevent' : (2, 5, 0, 0), 19 'help' : (1, 5, 0, 0), 20 'state' : (0, 0, 0, 0), 21 } 22 optiondefs = ( 23 ('labelmargin', 0, INITOPT), 24 ('labelpos', None, INITOPT), 25 ('messagetypes', defaultMessageTypes, INITOPT), 26 ('silent', 0, None), 27 ('sticky', 'ew', INITOPT), 28 ) 29 self.defineoptions(kw, optiondefs) 30 31 # Initialise the base class (after defining the options). 32 Pmw.MegaWidget.__init__(self, parent) 33 34 # Create the components. 35 interior = self.interior() 36 self._messageBarEntry = self.createcomponent('entry', 37 (), None, 38 Tkinter.Entry, (interior,)) 39 40 # Can't always use 'disabled', since this greys out text in Tk 8.4.2 41 try: 42 self._messageBarEntry.configure(state = 'readonly') 43 except Tkinter.TclError: 44 self._messageBarEntry.configure(state = 'disabled') 45 46 self._messageBarEntry.grid(column=2, row=2, sticky=self['sticky']) 47 interior.grid_columnconfigure(2, weight=1) 48 interior.grid_rowconfigure(2, weight=1) 49 50 self.createlabel(interior) 51 52 # Initialise instance variables. 53 self._numPriorities = 0 54 for info in self['messagetypes'].values(): 55 if self._numPriorities < info[0]: 56 self._numPriorities = info[0] 57 58 self._numPriorities = self._numPriorities + 1 59 self._timer = [None] * self._numPriorities 60 self._messagetext = [''] * self._numPriorities 61 self._activemessage = [0] * self._numPriorities 62 63 # Check keywords and initialise options. 64 self.initialiseoptions() 65 66 def destroy(self): 67 for timerId in self._timer: 68 if timerId is not None: 69 self.after_cancel(timerId) 70 self._timer = [None] * self._numPriorities 71 Pmw.MegaWidget.destroy(self) 72 73 def message(self, type, text): 74 # Display a message in the message bar. 75 76 (priority, showtime, bells, logmessage) = self['messagetypes'][type] 77 78 if not self['silent']: 79 for i in range(bells): 80 if i != 0: 81 self.after(100) 82 self.bell() 83 84 self._activemessage[priority] = 1 85 if text is None: 86 text = '' 87 self._messagetext[priority] = string.replace(text, '\n', ' ') 88 self._redisplayInfoMessage() 89 90 if logmessage: 91 # Should log this text to a text widget. 92 pass 93 94 if showtime > 0: 95 if self._timer[priority] is not None: 96 self.after_cancel(self._timer[priority]) 97 98 # Define a callback to clear this message after a time. 99 def _clearmessage(self=self, priority=priority): 100 self._clearActivemessage(priority) 101 102 mseconds = int(showtime * 1000) 103 self._timer[priority] = self.after(mseconds, _clearmessage) 104 105 def helpmessage(self, text): 106 if text is None: 107 self.resetmessages('help') 108 else: 109 self.message('help', text) 110 111 def resetmessages(self, type): 112 priority = self['messagetypes'][type][0] 113 self._clearActivemessage(priority) 114 for messagetype, info in self['messagetypes'].items(): 115 thisPriority = info[0] 116 showtime = info[1] 117 if thisPriority < priority and showtime != 0: 118 self._clearActivemessage(thisPriority) 119 120 def _clearActivemessage(self, priority): 121 self._activemessage[priority] = 0 122 if self._timer[priority] is not None: 123 self.after_cancel(self._timer[priority]) 124 self._timer[priority] = None 125 self._redisplayInfoMessage() 126 127 def _redisplayInfoMessage(self): 128 text = '' 129 for priority in range(self._numPriorities - 1, -1, -1): 130 if self._activemessage[priority]: 131 text = self._messagetext[priority] 132 break 133 self._messageBarEntry.configure(state = 'normal') 134 self._messageBarEntry.delete(0, 'end') 135 self._messageBarEntry.insert('end', text) 136 137 # Can't always use 'disabled', since this greys out text in Tk 8.4.2 138 try: 139 self._messageBarEntry.configure(state = 'readonly') 140 except Tkinter.TclError: 141 self._messageBarEntry.configure(state = 'disabled') 142 143Pmw.forwardmethods(MessageBar, Tkinter.Entry, '_messageBarEntry') 144