source: sasview/sansguiframe/src/sans/guiframe/gui_statusbar.py @ 95b513c

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 95b513c 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
RevLine 
[010c251]1import wx
[804a7db]2import sys
[010c251]3from wx import StatusBar as wxStatusB
4from wx.lib import newevent
[2d98490]5import wx.richtext
[a195ac9]6import time
[07dd0b4]7from sans.guiframe.gui_style import GUIFRAME_ICON
[010c251]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
[2d98490]17CONSOLE_WIDTH = 500
[199fdec]18CONSOLE_HEIGHT = 300
[804a7db]19if sys.platform.count("win32") > 0:
20    FONT_VARIANT = 0
21else:
22    FONT_VARIANT = 1
[010c251]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)
[2d98490]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       
[010c251]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       
[2d98490]43    def set_message(self, status="", event=None):
[010c251]44        """
45        """
[2d98490]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           
[010c251]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)
[804a7db]81        self.SetWindowVariant(FONT_VARIANT)
[010c251]82        self.panel = ConsolePanel(self)
83        self.panel.set_message(status=status)
[bfa73ca]84        wx.EVT_CLOSE(self, self.Close)
[783940c]85       
[010c251]86       
87    def set_multiple_messages(self, messages=[]):
88        """
89        """
90        if messages:
91            for status in messages:
[2d98490]92                self.panel.set_message(status=status)
[010c251]93               
[2d98490]94    def set_message(self, status, event=None):
[bfa73ca]95        """
96        """
[2d98490]97        self.panel.set_message(status=str(status), event=event)
[bfa73ca]98       
99    def Close(self, event):
[010c251]100        """
101        """
[bfa73ca]102        self.Hide()
[010c251]103       
104class StatusBar(wxStatusB):
105    """
[6e4d543]106        Application status bar
[010c251]107    """
[6e4d543]108    def __init__(self, parent, id):
109        wxStatusB.__init__(self, parent, id)
[010c251]110        self.parent = parent
111        self.parent.SetStatusBarPane(MSG_POSITION)
[6e4d543]112
[010c251]113        #Layout of status bar
[b716dd8]114        width, height = wx.ArtProvider.GetSizeHint(wx.ART_TOOLBAR)       
[010c251]115        self.SetFieldsCount(NB_FIELDS) 
[6e4d543]116        # Leave some space for the resize handle in the last field
[b716dd8]117        self.SetStatusWidths([width+4, -2, -1, width+15])
118        self.SetMinHeight(height)
[6e4d543]119       
[fa11fe1]120        rect = self.GetFieldRect(ICON_POSITION)
[b716dd8]121        if rect.height > height:
122            height = rect.GetHeight() 
123            width = rect.GetWidth()
[fa11fe1]124       
[010c251]125        #display default message
126        self.msg_position = MSG_POSITION
[6e4d543]127       
128        # Create progress bar
[804a7db]129        gauge_width = 5 * width
130        self.gauge = wx.Gauge(self, size=(gauge_width, height),
[010c251]131                               style=wx.GA_HORIZONTAL)
132        self.gauge.Hide()
[6e4d543]133       
134        # Create status bar icon reflecting the type of status
135        # for the last message
[9690fbf]136        self.bitmap_bt_warning = \
137            wx.BitmapButton(self, -1,
[b716dd8]138                            size=(width, height),
[a781312]139                            style=wx.NO_BORDER)
[6e4d543]140               
141        # Create the button used to show the console dialog
[9690fbf]142        console_bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, 
143                                               wx.ART_TOOLBAR,
[b716dd8]144                                               size = (width, height))
[010c251]145        self.bitmap_bt_console = wx.BitmapButton(self, -1, 
[b716dd8]146                                 size=(width, height),
[a781312]147                                 style=wx.NO_BORDER)
[010c251]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())
[bfa73ca]153       
[010c251]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 = []
[bfa73ca]161        self.frame = Console(parent=self)
[07dd0b4]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
[bfa73ca]174        self.frame.set_multiple_messages(self.list_msg)
175        self.frame.Hide()
[010c251]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        """
[b716dd8]187            Place the various fields in their proper position
[010c251]188        """
189        rect = self.GetFieldRect(GAUGE_POSITION)
[6e4d543]190        self.gauge.SetPosition((rect.x, rect.y))
[010c251]191        rect = self.GetFieldRect(ICON_POSITION)
[6e4d543]192        self.bitmap_bt_warning.SetPosition((rect.x, rect.y))
[010c251]193        rect = self.GetFieldRect(CONSOLE_POSITION)
[6e4d543]194        self.bitmap_bt_console.SetPosition((rect.x, rect.y))
[010c251]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   
[2d98490]214    def SetStatusText(self, text="", number=MSG_POSITION, event=None):
[010c251]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)
[bfa73ca]221     
222        if self.frame is not None :
[2d98490]223            self.frame.set_message(status=text, event=event)
[bfa73ca]224       
[010c251]225    def PopStatusText(self, *args, **kwds):
226        """
227        Override status bar
228        """
229        wxStatusB.PopStatusText(self, field=MSG_POSITION)
[986da97]230       
[010c251]231    def PushStatusText(self, *args, **kwds):
232        """
[3fc01c5]233        PushStatusText
[010c251]234        """
[3fc01c5]235        text = "PushStatusText: What is this string?"
236        wxStatusB.PushStatusText(self, field=MSG_POSITION, string=text)
[010c251]237       
238    def enable_clear_gauge(self):
239        """
240        clear the progress bar
241        """
[940aca7]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
[010c251]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        """
[2d98490]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
[010c251]288        """
[2d98490]289        if hasattr(event, "status"):
[07dd0b4]290            status = str(event.status)
[2d98490]291            if status.strip() == "":
292                return
293        else:
294            return
[010c251]295        if not hasattr(event, "info"):
296            return 
[6e4d543]297       
[b716dd8]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
[6e4d543]303        rect = self.GetFieldRect(ICON_POSITION)
[b716dd8]304        if rect.height > height:
305            height = rect.GetHeight()
306            width = rect.GetWidth()
[6e4d543]307       
[010c251]308        msg = event.info.lower()
309        if msg == "warning":
[6e4d543]310            icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_WARNING, wx.ART_TOOLBAR,
311                                                 size = (height,height))
[010c251]312            self.bitmap_bt_warning.SetBitmapLabel(icon_bmp)
[6e4d543]313        elif msg == "error":
314            icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_ERROR, wx.ART_TOOLBAR,
315                                                 size = (height,height))
[010c251]316            self.bitmap_bt_warning.SetBitmapLabel(icon_bmp)
[6e4d543]317        else:
[010c251]318            icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_INFORMATION,
[6e4d543]319                                                 wx.ART_TOOLBAR,
320                                                 size = (height,height))
[010c251]321            self.bitmap_bt_warning.SetBitmapLabel(icon_bmp)
322   
[7d89e50]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
[010c251]335    def set_message(self, event):
336        """
337        display received message on the statusbar
338        """
339        if hasattr(event, "status"):
[2d98490]340            self.SetStatusText(text=str(event.status), event=event)
[bfa73ca]341       
342 
[010c251]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()
[804a7db]354            self.progress += 5
[010c251]355            self.gauge.SetValue(int(self.progress)) 
[804a7db]356            self.progress += 5
[010c251]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":
[804a7db]364            self.progress += 5
[010c251]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
[3c965fd]373                self.gauge.SetValue(100) 
[804a7db]374                self.timer_stop.Start(5) 
[010c251]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)
[7d89e50]389        # dialog on error
390        self.set_dialog(event=event)
391       
[010c251]392    def _onMonitor(self, event):
393        """
394        Pop up a frame with messages sent to the status bar
395        """
[96683dc]396        self.frame.Show(False)
[010c251]397        self.frame.Show(True)
398       
399       
[7a955a9]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
[43cc1ad2]405        width, height = parent.GetSizeTuple()
406        self.gauge = wx.Gauge(self, style=wx.GA_HORIZONTAL, 
407                              size=(width, height/10))
[7a955a9]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       
[010c251]429if __name__ == "__main__":
430    app = wx.PySimpleApp()
431    frame = wx.Frame(None, wx.ID_ANY, 'test frame')
[7a955a9]432    #statusBar = StatusBar(frame, wx.ID_ANY)
433    statusBar = SPageStatusbar(frame)
[010c251]434    frame.SetStatusBar(statusBar)
435    frame.Show(True)
[7a955a9]436    #event = MessageEvent()
437    #event.type = "progress"
438    #event.status  = "statusbar...."
439    #event.info = "error"
440    #statusBar.set_status(event=event)
[010c251]441    app.MainLoop()
442
Note: See TracBrowser for help on using the repository browser.