Package gen :: Package utils :: Module progressmon
[frames] | no frames]

Source Code for Module gen.utils.progressmon

  1  # 
  2  # Gramps - a GTK+/GNOME based genealogy program 
  3  # 
  4  # Copyright (C) 2007  Richard Taylor 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 19  # 
 20   
 21  """ 
 22  This module provides a progess dialog for displaying the status of  
 23  long running operations. 
 24  """ 
 25  import logging 
 26  log = logging.getLogger(".gen") 
 27   
 28  from gettext import gettext as _ 
 29   
30 -class _StatusObjectFacade(object):
31 """This provides a simple structure for recording the information 32 needs about a status object.""" 33
34 - def __init__(self, status_obj, heartbeat_cb_id=None, end_cb_id=None):
35 """ 36 @param status_obj: 37 @type status_obj: L{gen.utils.LongOpStatus} 38 39 @param heartbeat_cb_id: (default: None) 40 @type heartbeat_cb_id: int 41 42 @param end_cb_id: (default: None) 43 @type end_cb_id: int 44 """ 45 self.status_obj = status_obj 46 self.heartbeat_cb_id = heartbeat_cb_id 47 self.end_cb_id = end_cb_id 48 self.pbar_idx = None 49 self.active = False
50
51 -class ProgressMonitor(object):
52 """A dialog for displaying the status of long running operations. 53 54 It will work with L{gen.utils.LongOpStatus} objects to track the 55 progress of long running operations. If the operations is going to 56 take longer than I{popup_time} it will pop up a dialog with a 57 progress bar so that the user gets some feedback about what is 58 happening. 59 """ 60 61 __default_popup_time = 5 # seconds 62
63 - def __init__(self, dialog_class, dialog_class_params=(), 64 title=_("Progress Information"), 65 popup_time = None):
66 """ 67 @param dialog_class: A class used to display the progress dialog. 68 @type dialog_class: _GtkProgressDialog or the same interface. 69 70 @param dialog_class_params: A tuple that will be used as the initial 71 arguments to the dialog_class, this might be used for passing in 72 a parent window handle. 73 @type dialog_class_params: tuple 74 75 @param title: The title of the progress dialog 76 @type title: string 77 78 @param popup_time: number of seconds to wait before popup. 79 @type popup_time: int 80 """ 81 self._dialog_class = dialog_class 82 self._dialog_class_params = dialog_class_params 83 self._title = title 84 self._popup_time = popup_time 85 86 if self._popup_time == None: 87 self._popup_time = self.__class__.__default_popup_time 88 89 self._status_stack = [] # list of current status objects 90 self._dlg = None
91
92 - def _get_dlg(self):
93 if self._dlg == None: 94 self._dlg = self._dialog_class(self._dialog_class_params, 95 self._title) 96 97 #self._dlg.show() 98 99 return self._dlg
100
101 - def add_op(self, op_status):
102 """Add a new status object to the progress dialog. 103 104 @param op_status: the status object. 105 @type op_status: L{gen.utils.LongOpStatus} 106 """ 107 108 log.debug("adding op to Progress Monitor") 109 facade = _StatusObjectFacade(op_status) 110 self._status_stack.append(facade) 111 idx = len(self._status_stack)-1 112 113 # wrap up the op_status object idx into the callback calls 114 def heartbeat_cb(): 115 self._heartbeat(idx)
116 def end_cb(): 117 self._end(idx)
118 119 facade.heartbeat_cb_id = op_status.connect('op-heartbeat', 120 heartbeat_cb) 121 facade.end_cb_id = op_status.connect('op-end', end_cb) 122
123 - def _heartbeat(self, idx):
124 # check the estimated time to complete to see if we need 125 # to pop up a progress dialog. 126 127 log.debug("heartbeat in ProgressMonitor") 128 129 facade = self._status_stack[idx] 130 131 if facade.status_obj.estimated_secs_to_complete() > self._popup_time: 132 facade.active = True 133 134 if facade.active: 135 dlg = self._get_dlg() 136 137 if facade.pbar_idx == None: 138 facade.pbar_idx = dlg.add(facade.status_obj) 139 140 dlg.show() 141 dlg.step(facade.pbar_idx)
142
143 - def _end(self, idx):
144 # hide any progress dialog 145 # remove the status object from the stack 146 147 log.debug("received end in ProgressMonitor") 148 facade = self._status_stack[idx] 149 if facade.active: 150 dlg = self._get_dlg() 151 152 if len(self._status_stack) == 1: 153 dlg.hide() 154 155 dlg.remove(facade.pbar_idx) 156 157 facade.status_obj.disconnect(facade.heartbeat_cb_id) 158 facade.status_obj.disconnect(facade.end_cb_id) 159 del self._status_stack[idx]
160