home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2006 June / PCpro_2006_06.ISO / files / freeware / openvip.exe / {app} / logging.py < prev    next >
Encoding:
Python Source  |  2003-06-03  |  7.9 KB  |  242 lines

  1. #
  2. # This file is part of OpenVIP (http://openvip.sourceforge.net)
  3. #
  4. # Copyright (C) 2002-2003
  5. # Michal Dvorak, Jiri Sedlar, Antonin Slavik, Vaclav Slavik, Jozef Smizansky
  6. #
  7. # This program is licensed under GNU General Public License version 2;
  8. # see file COPYING in the top level directory for details.
  9. #
  10. # $Id: logging.py,v 1.12 2003/06/03 21:01:13 vaclavslavik Exp $
  11. #
  12. # Classes for logging and progress indication
  13. #
  14.  
  15. import openvip
  16. import thread
  17. from wxPython.wx import *
  18. import App
  19.  
  20. _mainThreadID = thread.get_ident()
  21.  
  22.  
  23. # --------------------------------------------------------------------
  24. # Progress bar widgets:
  25. # --------------------------------------------------------------------
  26.  
  27. class GaugeMixin:
  28.     def OnCancel(self, event):
  29.         self.cancelled = True
  30.         self.cancel.Enable(False)
  31.     def update(self, value):        
  32.         self.progress.SetValue(int(100*value))
  33.         if self.exclusive:
  34.             wxGetApp().Yield(True)
  35.         return not self.cancelled
  36.     def info(self, msg):
  37.         self.infostr.SetLabel(msg)
  38.     def stop(self):
  39.         self.Destroy()
  40.  
  41. class BigGauge(wxDialog, GaugeMixin):
  42.     def __init__(self, exclusive=True, cancellable=True):
  43.         self.exclusive = exclusive
  44.         self.cancellable = cancellable
  45.         wxDialog.__init__(self, App.mainFrame, -1, 'Progress')
  46.         self.infostr = wxStaticText(self, -1, '')
  47.         self.progress = wxGauge(self, -1, 100,
  48.                                 size=(300,-1),
  49.                                 style=wxGA_SMOOTH|wxGA_HORIZONTAL)
  50.         sizer = wxBoxSizer(wxVERTICAL)
  51.         sizer.Add(self.infostr, 0, wxEXPAND | wxALL, 5)
  52.         sizer.Add(self.progress, 0, wxEXPAND | wxALL, 5)
  53.         if cancellable:
  54.             self.cancel = wxButton(self, wxID_CANCEL, 'Cancel')
  55.             sizer.Add(self.cancel, 0, wxALIGN_RIGHT | wxALL, 10)
  56.             EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
  57.         self.SetSizer(sizer)
  58.         sizer.SetSizeHints(self)
  59.         sizer.Fit(self)
  60.         self.SetAutoLayout(True)
  61.         self.cancelled = False
  62.         self.Show(True)
  63.         if exclusive:
  64.             self.disabler = wxWindowDisabler(self)
  65.  
  66. class StatusbarGauge(wxDialog, GaugeMixin):
  67.     def __init__(self, cancellable=True):
  68.         self.exclusive = False
  69.         self.cancellable = cancellable
  70.         wxDialog.__init__(self, App.mainFrame, -1, 'Progress')
  71.         self.infostr = wxStaticText(self, -1, '', size=(80,-1),
  72.                                     style=wxST_NO_AUTORESIZE)
  73.         self.progress = wxGauge(self, -1, 100,
  74.                                 size=(150,-1),
  75.                                 style=wxGA_SMOOTH|wxGA_HORIZONTAL)
  76.         sizer = wxBoxSizer(wxHORIZONTAL)
  77.         sizer.Add(self.infostr, 0, wxALIGN_CENTRE_VERTICAL|wxALL, 1)
  78.         sizer.Add(self.progress, 1, wxEXPAND | wxALL, 1)
  79.         if cancellable:
  80.             self.cancel = wxButton(self, wxID_CANCEL, 'X',
  81.                                    style=wxBU_EXACTFIT)
  82.             sizer.Add(self.cancel, 0, wxEXPAND | wxALL, 1)
  83.             EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
  84.         self.SetSizer(sizer)
  85.         sizer.SetSizeHints(self)
  86.         sizer.Fit(self)
  87.         self.SetAutoLayout(True)
  88.         self.cancelled = False
  89.         self.Show(True)
  90.  
  91.  
  92. # --------------------------------------------------------------------
  93. # UI callback class and event, for multithreaded progress info:
  94. # --------------------------------------------------------------------
  95.  
  96. wxEVT_PROGRESS_UPDATE = wxNewEventType()
  97.  
  98. def EVT_PROGRESS_UPDATE(win, func):
  99.     win.Connect(-1, -1, wxEVT_PROGRESS_UPDATE, func)
  100.  
  101. class ProgressUpdateEvent(wxPyEvent):
  102.     def __init__(self, func, arg):
  103.         wxPyEvent.__init__(self)
  104.         self.SetEventType(wxEVT_PROGRESS_UPDATE)
  105.         self.func = func
  106.         self.arg = arg
  107.  
  108. class UICallbackEvtHandler(wxEvtHandler):
  109.     def __init__(self, parent):
  110.         wxEvtHandler.__init__(self)
  111.         EVT_PROGRESS_UPDATE(self, self.OnUpdate)
  112.         self.parent = parent
  113.     def OnUpdate(self, event):
  114.         if event.func != None:
  115.             event.func(event.arg)
  116.         else:
  117.             self.parent.UpdateGauge()
  118.  
  119.  
  120. # --------------------------------------------------------------------
  121. # UI callback class:
  122. # --------------------------------------------------------------------
  123.  
  124. def _mainThread():
  125.     return thread.get_ident() == _mainThreadID
  126.  
  127. class Status:
  128.     def __init__(self):
  129.         self.value = 0.0
  130.         self.shown = False
  131.         self.text = ''
  132.  
  133. class UICallback(openvip.UICallback):
  134.     """This is openvip.UICallback implementation suitable for use in 
  135.        wxPython applications."""
  136.     def __init__(self,
  137.                  background=False, docked=False, cancellable=False,
  138.                  progress=True):
  139.         """Ctor.
  140.            background:  for use with background renderer
  141.            cancellable: the user can cancel operation
  142.            docked:      use more compact 'docked' version of progress bar
  143.            progress:    show progressbar? (Otherwise only logging is done.)
  144.            """
  145.         self.gauge = None
  146.         self.progress = progress
  147.         self.handler = UICallbackEvtHandler(self)
  148.         self.keepGoing = True
  149.         self.background = background
  150.         self.docked = docked
  151.         self.cancellable = cancellable
  152.         self.gaugeStatus = Status()
  153.  
  154.     def show_gauge(self):
  155.         if not self.progress: return
  156.         self.gaugeStatus.shown = True
  157.         if _mainThread(): self.UpdateGauge()
  158.         else:             self.__postEvent()
  159.     
  160.     def update_gauge(self, value):
  161.         if not self.progress: return
  162.         self.gaugeStatus.value = value
  163.         if _mainThread(): self.UpdateGauge()
  164.         else:             self.__postEvent()
  165.         return self.keepGoing
  166.  
  167.     def hide_gauge(self):
  168.         if not self.progress: return
  169.         self.gaugeStatus.shown = False
  170.         if _mainThread(): self.UpdateGauge()
  171.         else:             self.__postEvent()
  172.  
  173.     def set_gauge_text(self, msg):
  174.         if not self.progress: return
  175.         if _mainThread():
  176.             self.gauge.info(msg)
  177.         else:
  178.             self.__postEvent(self.set_gauge_text, msg)
  179.         
  180.     def log_info(self, msg):
  181.         if _mainThread():
  182.             wxLogVerbose(msg)
  183.         else:
  184.             self.__postEvent(self.log_info, msg)
  185.  
  186.     def log_error(self, msg):
  187.         if _mainThread():
  188.             wxLogError(msg)
  189.         else:
  190.             self.__postEvent(self.log_error, msg)
  191.  
  192.     def log_warning(self, msg):
  193.         if _mainThread():
  194.             wxLogWarning(msg)
  195.         else:
  196.             self.__postEvent(self.log_warning, msg)
  197.  
  198.     def __postEvent(self, func=None, arg=None):
  199.         evt = ProgressUpdateEvent(func, arg)
  200.         wxPostEvent(self.handler, evt)
  201.  
  202.     def UpdateGauge(self):
  203.         if self.gauge == None and self.gaugeStatus.shown:
  204.             if self.docked:
  205.                 self.gauge = StatusbarGauge(cancellable=self.cancellable)
  206.             else:
  207.                 self.gauge = BigGauge(cancellable=self.cancellable,
  208.                                       exclusive=not self.background)
  209.         if self.gauge != None:
  210.             self.keepGoing = self.gauge.update(self.gaugeStatus.value)
  211.         if self.gauge != None and (not self.gaugeStatus.shown):
  212.             self.gauge.stop()
  213.             self.gauge = None
  214.  
  215.  
  216.  
  217.  
  218.  
  219. # --------------------------------------------------------------------
  220. # Testing code
  221. # --------------------------------------------------------------------
  222. if __name__ == '__main__':   
  223.     import sys, thread
  224.     def work(x,y,f=None):
  225.         x.show_gauge()
  226.         for i in range(y):
  227.             x.set_gauge_text('Working: %i %%' % i)
  228.             if not x.update_gauge(float(i)/y):
  229.                 break
  230.             wxUsleep(40)
  231.             if f!=None:f()
  232.         x.hide_gauge()
  233.     class MyApp(wxApp):
  234.         def OnInit(self):
  235.             t = (UICallback(docked=True,background=True),100)
  236.             thread.start_new_thread(work, t)
  237.             x=UICallback(cancellable=True)
  238.             work(x,400, wxYield)
  239.             return False
  240.     app = MyApp(0)
  241.     app.MainLoop()
  242.