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

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 9053779 was 3fc01c5, checked in by Jae Cho <jhjcho@…>, 13 years ago

fixing pylint warnings

  • Property mode set to 100644
File size: 14.6 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_message(self, event):
324        """
325        display received message on the statusbar
326        """
327        if hasattr(event, "status"):
328            self.SetStatusText(text=str(event.status), event=event)
329       
330 
331    def set_gauge(self, event):
332        """
333        change the state of the gauge according the state of the current job
334        """
335        if not hasattr(event, "type"):
336            return
337        type = event.type
338        self.gauge.Show(True)
339        if type.lower() == "start":
340            self.nb_start += 1
341            #self.timer.Stop()
342            self.progress += 5
343            self.gauge.SetValue(int(self.progress)) 
344            self.progress += 5
345            if self.progress < self.gauge.GetRange() - 20:
346                self.gauge.SetValue(int(self.progress)) 
347        if type.lower() == "progress":
348            self.nb_progress += 1
349            self.timer.Start(1)
350            self.gauge.Pulse()
351        if type.lower() == "update":
352            self.progress += 5
353            if self.progress < self.gauge.GetRange()- 20:
354                self.gauge.SetValue(int(self.progress))   
355        if type.lower() == "stop":
356            self.nb_stop += 1
357            self.gauge.Show(True)
358            if self.enable_clear_gauge():
359                self.timer.Stop()
360                self.progress = 0
361                self.gauge.SetValue(100) 
362                self.timer_stop.Start(5) 
363                   
364    def set_status(self, event):
365        """
366        Update the status bar .
367       
368        :param type: type of message send.
369            type  must be in ["start","progress","update","stop"]
370        :param msg: the message itself  as string
371        :param thread: if updatting using a thread status
372       
373        """
374        self.set_message(event=event)
375        self.set_icon(event=event)
376        self.set_gauge(event=event)
377   
378    def _onMonitor(self, event):
379        """
380        Pop up a frame with messages sent to the status bar
381        """
382        self.frame.Show(False)
383        self.frame.Show(True)
384       
385       
386class SPageStatusbar(wxStatusB):
387    def __init__(self, parent, timeout=None, *args, **kwds):
388        wxStatusB.__init__(self, parent, *args, **kwds)
389        self.SetFieldsCount(1) 
390        self.timeout = timeout
391        width, height = parent.GetSizeTuple()
392        self.gauge = wx.Gauge(self, style=wx.GA_HORIZONTAL, 
393                              size=(width, height/10))
394        rect = self.GetFieldRect(0)
395        self.gauge.SetPosition((rect.x , rect.y ))
396        if self.timeout is not None:
397            self.gauge.SetRange(int(self.timeout))
398        self.timer = wx.Timer(self, -1) 
399        self.Bind(wx.EVT_TIMER, self._on_time, self.timer) 
400        self.timer.Start(1)
401        self.pos = 0
402       
403    def _on_time(self, evt): 
404        """
405        Update the progress bar while the timer is running
406       
407        :param evt: wx.EVT_TIMER
408 
409        """ 
410        # Check stop flag that can be set from non main thread
411        if self.timeout is None and self.timer.IsRunning(): 
412            self.gauge.Pulse()
413           
414       
415if __name__ == "__main__":
416    app = wx.PySimpleApp()
417    frame = wx.Frame(None, wx.ID_ANY, 'test frame')
418    #statusBar = StatusBar(frame, wx.ID_ANY)
419    statusBar = SPageStatusbar(frame)
420    frame.SetStatusBar(statusBar)
421    frame.Show(True)
422    #event = MessageEvent()
423    #event.type = "progress"
424    #event.status  = "statusbar...."
425    #event.info = "error"
426    #statusBar.set_status(event=event)
427    app.MainLoop()
428
Note: See TracBrowser for help on using the repository browser.