143 lines
4.3 KiB
Python
143 lines
4.3 KiB
Python
# Class to display messages in an information line.
|
|
|
|
import string
|
|
import Tkinter
|
|
import Pmw
|
|
|
|
class MessageBar(Pmw.MegaWidget):
|
|
def __init__(self, parent = None, **kw):
|
|
|
|
# Define the megawidget options.
|
|
INITOPT = Pmw.INITOPT
|
|
defaultMessageTypes = {
|
|
# (priority, showtime, bells, logmessage)
|
|
'systemerror' : (5, 10, 2, 1),
|
|
'usererror' : (4, 5, 1, 0),
|
|
'busy' : (3, 0, 0, 0),
|
|
'systemevent' : (2, 5, 0, 0),
|
|
'userevent' : (2, 5, 0, 0),
|
|
'help' : (1, 5, 0, 0),
|
|
'state' : (0, 0, 0, 0),
|
|
}
|
|
optiondefs = (
|
|
('labelmargin', 0, INITOPT),
|
|
('labelpos', None, INITOPT),
|
|
('messagetypes', defaultMessageTypes, INITOPT),
|
|
('silent', 0, None),
|
|
('sticky', 'ew', INITOPT),
|
|
)
|
|
self.defineoptions(kw, optiondefs)
|
|
|
|
# Initialise the base class (after defining the options).
|
|
Pmw.MegaWidget.__init__(self, parent)
|
|
|
|
# Create the components.
|
|
interior = self.interior()
|
|
self._messageBarEntry = self.createcomponent('entry',
|
|
(), None,
|
|
Tkinter.Entry, (interior,))
|
|
|
|
# Can't always use 'disabled', since this greys out text in Tk 8.4.2
|
|
try:
|
|
self._messageBarEntry.configure(state = 'readonly')
|
|
except Tkinter.TclError:
|
|
self._messageBarEntry.configure(state = 'disabled')
|
|
|
|
self._messageBarEntry.grid(column=2, row=2, sticky=self['sticky'])
|
|
interior.grid_columnconfigure(2, weight=1)
|
|
interior.grid_rowconfigure(2, weight=1)
|
|
|
|
self.createlabel(interior)
|
|
|
|
# Initialise instance variables.
|
|
self._numPriorities = 0
|
|
for info in self['messagetypes'].values():
|
|
if self._numPriorities < info[0]:
|
|
self._numPriorities = info[0]
|
|
|
|
self._numPriorities = self._numPriorities + 1
|
|
self._timer = [None] * self._numPriorities
|
|
self._messagetext = [''] * self._numPriorities
|
|
self._activemessage = [0] * self._numPriorities
|
|
|
|
# Check keywords and initialise options.
|
|
self.initialiseoptions()
|
|
|
|
def destroy(self):
|
|
for timerId in self._timer:
|
|
if timerId is not None:
|
|
self.after_cancel(timerId)
|
|
self._timer = [None] * self._numPriorities
|
|
Pmw.MegaWidget.destroy(self)
|
|
|
|
def message(self, type, text):
|
|
# Display a message in the message bar.
|
|
|
|
(priority, showtime, bells, logmessage) = self['messagetypes'][type]
|
|
|
|
if not self['silent']:
|
|
for i in range(bells):
|
|
if i != 0:
|
|
self.after(100)
|
|
self.bell()
|
|
|
|
self._activemessage[priority] = 1
|
|
if text is None:
|
|
text = ''
|
|
self._messagetext[priority] = string.replace(text, '\n', ' ')
|
|
self._redisplayInfoMessage()
|
|
|
|
if logmessage:
|
|
# Should log this text to a text widget.
|
|
pass
|
|
|
|
if showtime > 0:
|
|
if self._timer[priority] is not None:
|
|
self.after_cancel(self._timer[priority])
|
|
|
|
# Define a callback to clear this message after a time.
|
|
def _clearmessage(self=self, priority=priority):
|
|
self._clearActivemessage(priority)
|
|
|
|
mseconds = int(showtime * 1000)
|
|
self._timer[priority] = self.after(mseconds, _clearmessage)
|
|
|
|
def helpmessage(self, text):
|
|
if text is None:
|
|
self.resetmessages('help')
|
|
else:
|
|
self.message('help', text)
|
|
|
|
def resetmessages(self, type):
|
|
priority = self['messagetypes'][type][0]
|
|
self._clearActivemessage(priority)
|
|
for messagetype, info in self['messagetypes'].items():
|
|
thisPriority = info[0]
|
|
showtime = info[1]
|
|
if thisPriority < priority and showtime != 0:
|
|
self._clearActivemessage(thisPriority)
|
|
|
|
def _clearActivemessage(self, priority):
|
|
self._activemessage[priority] = 0
|
|
if self._timer[priority] is not None:
|
|
self.after_cancel(self._timer[priority])
|
|
self._timer[priority] = None
|
|
self._redisplayInfoMessage()
|
|
|
|
def _redisplayInfoMessage(self):
|
|
text = ''
|
|
for priority in range(self._numPriorities - 1, -1, -1):
|
|
if self._activemessage[priority]:
|
|
text = self._messagetext[priority]
|
|
break
|
|
self._messageBarEntry.configure(state = 'normal')
|
|
self._messageBarEntry.delete(0, 'end')
|
|
self._messageBarEntry.insert('end', text)
|
|
|
|
# Can't always use 'disabled', since this greys out text in Tk 8.4.2
|
|
try:
|
|
self._messageBarEntry.configure(state = 'readonly')
|
|
except Tkinter.TclError:
|
|
self._messageBarEntry.configure(state = 'disabled')
|
|
|
|
Pmw.forwardmethods(MessageBar, Tkinter.Entry, '_messageBarEntry')
|