source: sasview/sansguiframe/src/sans/guiframe/gui_statusbar.py @ 699df7f

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 699df7f was 7d89e50, checked in by Jae Cho <jhjcho@…>, 12 years ago

added error dialog function call

  • Property mode set to 100644
File size: 15.0 KB
Line 
1import wx
2import sys
3from wx import StatusBar as wxStatusB
4from wx.lib import newevent
5import wx.richtext
6import time
7from sans.guiframe.gui_style import GUIFRAME_ICON
8#numner of fields of the status bar
9NB_FIELDS = 4
10#position of the status bar's fields
11ICON_POSITION = 0
12MSG_POSITION  = 1
13GAUGE_POSITION  = 2
14CONSOLE_POSITION  = 3
15BUTTON_SIZE = 40
16
17CONSOLE_WIDTH = 500
18CONSOLE_HEIGHT = 300
19if sys.platform.count("win32") > 0:
20    FONT_VARIANT = 0
21else:
22    FONT_VARIANT = 1
23
24class ConsolePanel(wx.Panel):
25    """
26    """
27    def __init__(self, parent, *args, **kwargs):
28        """
29        """
30        wx.Panel.__init__(self, parent=parent, *args, **kwargs)
31        self.parent = parent
32        self.sizer = wx.BoxSizer(wx.VERTICAL)
33       
34        self.msg_txt = wx.richtext.RichTextCtrl(self, size=(CONSOLE_WIDTH-40,
35                                                CONSOLE_HEIGHT-60),
36                                   style=wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER)
37       
38        self.msg_txt.SetEditable(False)
39        self.msg_txt.SetValue('No message available')
40        self.sizer.Add(self.msg_txt, 1, wx.EXPAND|wx.ALL, 10)
41        self.SetSizer(self.sizer)
42       
43    def set_message(self, status="", event=None):
44        """
45        """
46        status = str(status)
47        if status.strip() == "":
48            return
49        color = (0, 0, 0) #black
50        icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_INFORMATION,
51                                                 wx.ART_TOOLBAR)
52        if hasattr(event, "info"):
53            icon_type = event.info.lower()
54            if icon_type == "warning":
55                color = (0, 0, 255) # blue
56                icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_WARNING,
57                                                      wx.ART_TOOLBAR)
58            if icon_type == "error":
59                color = (255, 0, 0) # red
60                icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_ERROR, 
61                                                     wx.ART_TOOLBAR)
62            if icon_type == "info":
63                icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_INFORMATION,
64                                                     wx.ART_TOOLBAR)
65        self.msg_txt.Newline()
66        self.msg_txt.WriteBitmap(icon_bmp)
67        self.msg_txt.BeginTextColour(color)
68        self.msg_txt.WriteText("\t")
69        self.msg_txt.AppendText(status)
70        self.msg_txt.EndTextColour()
71       
72           
73       
74class Console(wx.Frame):
75    """
76    """
77    def __init__(self, parent=None, status="", *args, **kwds):
78        kwds["size"] = (CONSOLE_WIDTH, CONSOLE_HEIGHT)
79        kwds["title"] = "Console"
80        wx.Frame.__init__(self, parent=parent, *args, **kwds)
81        self.SetWindowVariant(FONT_VARIANT)
82        self.panel = ConsolePanel(self)
83        self.panel.set_message(status=status)
84        wx.EVT_CLOSE(self, self.Close)
85       
86       
87    def set_multiple_messages(self, messages=[]):
88        """
89        """
90        if messages:
91            for status in messages:
92                self.panel.set_message(status=status)
93               
94    def set_message(self, status, event=None):
95        """
96        """
97        self.panel.set_message(status=str(status), event=event)
98       
99    def Close(self, event):
100        """
101        """
102        self.Hide()
103       
104class StatusBar(wxStatusB):
105    """
106        Application status bar
107    """
108    def __init__(self, parent, id):
109        wxStatusB.__init__(self, parent, id)
110        self.parent = parent
111        self.parent.SetStatusBarPane(MSG_POSITION)
112
113        #Layout of status bar
114        width, height = wx.ArtProvider.GetSizeHint(wx.ART_TOOLBAR)       
115        self.SetFieldsCount(NB_FIELDS) 
116        # Leave some space for the resize handle in the last field
117        self.SetStatusWidths([width+4, -2, -1, width+15])
118        self.SetMinHeight(height)
119       
120        rect = self.GetFieldRect(ICON_POSITION)
121        if rect.height > height:
122            height = rect.GetHeight() 
123            width = rect.GetWidth()
124       
125        #display default message
126        self.msg_position = MSG_POSITION
127       
128        # Create progress bar
129        gauge_width = 5 * width
130        self.gauge = wx.Gauge(self, size=(gauge_width, height),
131                               style=wx.GA_HORIZONTAL)
132        self.gauge.Hide()
133       
134        # Create status bar icon reflecting the type of status
135        # for the last message
136        self.bitmap_bt_warning = \
137            wx.BitmapButton(self, -1,
138                            size=(width, height),
139                            style=wx.NO_BORDER)
140               
141        # Create the button used to show the console dialog
142        console_bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, 
143                                               wx.ART_TOOLBAR,
144                                               size = (width, height))
145        self.bitmap_bt_console = wx.BitmapButton(self, -1, 
146                                 size=(width, height),
147                                 style=wx.NO_BORDER)
148        self.bitmap_bt_console.SetBitmapLabel(console_bmp)
149        console_hint = "History of status bar messages"
150        self.bitmap_bt_console.SetToolTipString(console_hint)
151        self.bitmap_bt_console.Bind(wx.EVT_BUTTON, self._onMonitor,
152                                            id=self.bitmap_bt_console.GetId())
153       
154        self.reposition()
155        ## Current progress value of the bar
156        self.nb_start = 0
157        self.nb_progress = 0
158        self.nb_stop = 0
159        self.frame = None
160        self.list_msg = []
161        self.frame = Console(parent=self)
162        if hasattr(self.frame, "IsIconized"):
163            if not self.frame.IsIconized():
164                try:
165                    icon = self.parent.GetIcon()
166                    self.frame.SetIcon(icon)
167                except:
168                    try:
169                        FRAME_ICON = wx.Icon(GUIFRAME_ICON.FRAME_ICON_PATH,
170                                              wx.BITMAP_TYPE_ICON)
171                        self.frame.SetIcon(FRAME_ICON)
172                    except:
173                        pass
174        self.frame.set_multiple_messages(self.list_msg)
175        self.frame.Hide()
176        self.progress = 0     
177        self.timer = wx.Timer(self, -1) 
178        self.timer_stop = wx.Timer(self, -1) 
179        self.thread = None
180        self.Bind(wx.EVT_TIMER, self._on_time, self.timer) 
181        self.Bind(wx.EVT_TIMER, self._on_time_stop, self.timer_stop) 
182        self.Bind(wx.EVT_SIZE, self.OnSize)
183        self.Bind(wx.EVT_IDLE, self.OnIdle)
184       
185    def reposition(self):
186        """
187            Place the various fields in their proper position
188        """
189        rect = self.GetFieldRect(GAUGE_POSITION)
190        self.gauge.SetPosition((rect.x, rect.y))
191        rect = self.GetFieldRect(ICON_POSITION)
192        self.bitmap_bt_warning.SetPosition((rect.x, rect.y))
193        rect = self.GetFieldRect(CONSOLE_POSITION)
194        self.bitmap_bt_console.SetPosition((rect.x, rect.y))
195        self.sizeChanged = False
196       
197    def OnIdle(self, event):
198        """
199        """
200        if self.sizeChanged:
201            self.reposition()
202           
203    def OnSize(self, evt):
204        """
205        """
206        self.reposition() 
207        self.sizeChanged = True
208       
209    def get_msg_position(self):
210        """
211        """
212        return self.msg_position
213   
214    def SetStatusText(self, text="", number=MSG_POSITION, event=None):
215        """
216        """
217        wxStatusB.SetStatusText(self, text, number)
218        self.list_msg.append(text)
219        icon_bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_TOOLBAR)
220        self.bitmap_bt_warning.SetBitmapLabel(icon_bmp)
221     
222        if self.frame is not None :
223            self.frame.set_message(status=text, event=event)
224       
225    def PopStatusText(self, *args, **kwds):
226        """
227        Override status bar
228        """
229        wxStatusB.PopStatusText(self, field=MSG_POSITION)
230       
231    def PushStatusText(self, *args, **kwds):
232        """
233        PushStatusText
234        """
235        text = "PushStatusText: What is this string?"
236        wxStatusB.PushStatusText(self, field=MSG_POSITION, string=text)
237       
238    def enable_clear_gauge(self):
239        """
240        clear the progress bar
241        """
242        flag = True
243        # Why we do this?
244        #if (self.nb_start <= self.nb_stop) or \
245        #    (self.nb_progress <= self.nb_stop):
246        #    flag = True
247        return flag
248   
249    def _on_time_stop(self, evt): 
250        """
251        Clear the progress bar
252       
253        :param evt: wx.EVT_TIMER
254 
255        """ 
256        count = 0
257        while(count <= 100):
258            count += 1
259        self.timer_stop.Stop() 
260        self.clear_gauge(msg="")
261        self.nb_progress = 0 
262        self.nb_start = 0 
263        self.nb_stop = 0
264       
265    def _on_time(self, evt): 
266        """
267        Update the progress bar while the timer is running
268       
269        :param evt: wx.EVT_TIMER
270 
271        """ 
272        # Check stop flag that can be set from non main thread
273        if self.timer.IsRunning(): 
274            self.gauge.Pulse()
275   
276    def clear_gauge(self, msg=""):
277        """
278        Hide the gauge
279        """
280        self.progress = 0
281        self.gauge.SetValue(0)
282        self.gauge.Hide() 
283         
284    def set_icon(self, event):
285        """
286        Display icons related to the type of message sent to the statusbar
287        when available. No icon is displayed if the message is empty
288        """
289        if hasattr(event, "status"):
290            status = str(event.status)
291            if status.strip() == "":
292                return
293        else:
294            return
295        if not hasattr(event, "info"):
296            return 
297       
298        # Get the size of the button images
299        width, height = wx.ArtProvider.GetSizeHint(wx.ART_TOOLBAR)       
300
301        # Get the size of the field and choose the size of the
302        # image accordingly
303        rect = self.GetFieldRect(ICON_POSITION)
304        if rect.height > height:
305            height = rect.GetHeight()
306            width = rect.GetWidth()
307       
308        msg = event.info.lower()
309        if msg == "warning":
310            icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_WARNING, wx.ART_TOOLBAR,
311                                                 size = (height,height))
312            self.bitmap_bt_warning.SetBitmapLabel(icon_bmp)
313        elif msg == "error":
314            icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_ERROR, wx.ART_TOOLBAR,
315                                                 size = (height,height))
316            self.bitmap_bt_warning.SetBitmapLabel(icon_bmp)
317        else:
318            icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_INFORMATION,
319                                                 wx.ART_TOOLBAR,
320                                                 size = (height,height))
321            self.bitmap_bt_warning.SetBitmapLabel(icon_bmp)
322   
323    def set_dialog(self, event):
324        """
325        Display dialogbox
326        """
327        if not hasattr(event, "info"):
328            return 
329        msg = event.info.lower()
330        if msg == "error":
331            e_msg = "Error(s) Occurred:\n"
332            e_msg += event.status
333            wx.MessageBox(e_msg, style=wx.ICON_ERROR)
334
335    def set_message(self, event):
336        """
337        display received message on the statusbar
338        """
339        if hasattr(event, "status"):
340            self.SetStatusText(text=str(event.status), event=event)
341       
342 
343    def set_gauge(self, event):
344        """
345        change the state of the gauge according the state of the current job
346        """
347        if not hasattr(event, "type"):
348            return
349        type = event.type
350        self.gauge.Show(True)
351        if type.lower() == "start":
352            self.nb_start += 1
353            #self.timer.Stop()
354            self.progress += 5
355            self.gauge.SetValue(int(self.progress)) 
356            self.progress += 5
357            if self.progress < self.gauge.GetRange() - 20:
358                self.gauge.SetValue(int(self.progress)) 
359        if type.lower() == "progress":
360            self.nb_progress += 1
361            self.timer.Start(1)
362            self.gauge.Pulse()
363        if type.lower() == "update":
364            self.progress += 5
365            if self.progress < self.gauge.GetRange()- 20:
366                self.gauge.SetValue(int(self.progress))   
367        if type.lower() == "stop":
368            self.nb_stop += 1
369            self.gauge.Show(True)
370            if self.enable_clear_gauge():
371                self.timer.Stop()
372                self.progress = 0
373                self.gauge.SetValue(100) 
374                self.timer_stop.Start(5) 
375                   
376    def set_status(self, event):
377        """
378        Update the status bar .
379       
380        :param type: type of message send.
381            type  must be in ["start","progress","update","stop"]
382        :param msg: the message itself  as string
383        :param thread: if updatting using a thread status
384       
385        """
386        self.set_message(event=event)
387        self.set_icon(event=event)
388        self.set_gauge(event=event)
389        # dialog on error
390        self.set_dialog(event=event)
391       
392    def _onMonitor(self, event):
393        """
394        Pop up a frame with messages sent to the status bar
395        """
396        self.frame.Show(False)
397        self.frame.Show(True)
398       
399       
400class SPageStatusbar(wxStatusB):
401    def __init__(self, parent, timeout=None, *args, **kwds):
402        wxStatusB.__init__(self, parent, *args, **kwds)
403        self.SetFieldsCount(1) 
404        self.timeout = timeout
405        width, height = parent.GetSizeTuple()
406        self.gauge = wx.Gauge(self, style=wx.GA_HORIZONTAL, 
407                              size=(width, height/10))
408        rect = self.GetFieldRect(0)
409        self.gauge.SetPosition((rect.x , rect.y ))
410        if self.timeout is not None:
411            self.gauge.SetRange(int(self.timeout))
412        self.timer = wx.Timer(self, -1) 
413        self.Bind(wx.EVT_TIMER, self._on_time, self.timer) 
414        self.timer.Start(1)
415        self.pos = 0
416       
417    def _on_time(self, evt): 
418        """
419        Update the progress bar while the timer is running
420       
421        :param evt: wx.EVT_TIMER
422 
423        """ 
424        # Check stop flag that can be set from non main thread
425        if self.timeout is None and self.timer.IsRunning(): 
426            self.gauge.Pulse()
427           
428       
429if __name__ == "__main__":
430    app = wx.PySimpleApp()
431    frame = wx.Frame(None, wx.ID_ANY, 'test frame')
432    #statusBar = StatusBar(frame, wx.ID_ANY)
433    statusBar = SPageStatusbar(frame)
434    frame.SetStatusBar(statusBar)
435    frame.Show(True)
436    #event = MessageEvent()
437    #event.type = "progress"
438    #event.status  = "statusbar...."
439    #event.info = "error"
440    #statusBar.set_status(event=event)
441    app.MainLoop()
442
Note: See TracBrowser for help on using the repository browser.