Refinements to ProgressMeter and ProgressMonitor for cancelling
svn: r13720
This commit is contained in:
		| @@ -101,11 +101,12 @@ class GtkProgressDialog(gtk.Dialog): | |||||||
|         self.vbox.pack_start(pbar, expand=False, fill=False) |         self.vbox.pack_start(pbar, expand=False, fill=False) | ||||||
|          |          | ||||||
|         pbar.show() |         pbar.show() | ||||||
|          |         # this seems to cause an infinite loop: | ||||||
|         self.resize_children() |         #self.resize_children() | ||||||
|         self._process_events() |  | ||||||
|              |              | ||||||
|         self._progress_bars.append(pbar) |         self._progress_bars.append(pbar) | ||||||
|  |         # This is a bad idea; could cause deletes while adding: | ||||||
|  |         #self._process_events() | ||||||
|         return len(self._progress_bars)-1 |         return len(self._progress_bars)-1 | ||||||
|      |      | ||||||
|     def remove(self, pbar_idx): |     def remove(self, pbar_idx): | ||||||
| @@ -114,6 +115,7 @@ class GtkProgressDialog(gtk.Dialog): | |||||||
|         :param pbar_idx: the index as returned from L{add} |         :param pbar_idx: the index as returned from L{add} | ||||||
|         :type pbar_idx: int |         :type pbar_idx: int | ||||||
|         """ |         """ | ||||||
|  |         if pbar_idx is not None: | ||||||
|             pbar = self._progress_bars[pbar_idx] |             pbar = self._progress_bars[pbar_idx] | ||||||
|             self.vbox.remove(pbar) |             self.vbox.remove(pbar) | ||||||
|             del self._progress_bars[pbar_idx] |             del self._progress_bars[pbar_idx] | ||||||
| @@ -158,30 +160,40 @@ if __name__ == '__main__': | |||||||
|     def test(a, b): |     def test(a, b): | ||||||
|         d = ProgressMonitor(GtkProgressDialog) |         d = ProgressMonitor(GtkProgressDialog) | ||||||
|          |          | ||||||
|         s = LongOpStatus("Doing very long operation", 100, 10) |         s = LongOpStatus("Doing very long operation", 100, 10, can_cancel=True) | ||||||
|      |      | ||||||
|         d.add_op(s) |         d.add_op(s) | ||||||
|          |          | ||||||
|         for i in xrange(0, 99): |         for i in xrange(0, 99): | ||||||
|  |             if s.should_cancel(): | ||||||
|  |                 break | ||||||
|             time.sleep(0.1) |             time.sleep(0.1) | ||||||
|             if i == 30: |             if i == 30: | ||||||
|                 t = LongOpStatus("doing a shorter one", 100, 10,  |                 t = LongOpStatus("doing a shorter one", 100, 10,  | ||||||
|                                  can_cancel=True) |                                  can_cancel=True) | ||||||
|                 d.add_op(t) |                 d.add_op(t) | ||||||
|                 for j in xrange(0, 99): |                 for j in xrange(0, 99): | ||||||
|  |                     if s.should_cancel():  | ||||||
|  |                         t.cancel() | ||||||
|  |                         break | ||||||
|                     if t.should_cancel(): |                     if t.should_cancel(): | ||||||
|                         break |                         break | ||||||
|                     time.sleep(0.1) |                     time.sleep(0.1) | ||||||
|                     t.heartbeat() |                     t.heartbeat() | ||||||
|  |                 if not t.was_cancelled(): | ||||||
|                     t.end() |                     t.end() | ||||||
|             if i == 60: |             if i == 60: | ||||||
|                 t = LongOpStatus("doing another shorter one", 100, 10) |                 t = LongOpStatus("doing another shorter one", 100, 10) | ||||||
|                 d.add_op(t) |                 d.add_op(t) | ||||||
|                 for j in xrange(0, 99): |                 for j in xrange(0, 99): | ||||||
|  |                     if s.should_cancel(): | ||||||
|  |                         t.cancel() | ||||||
|  |                         break | ||||||
|                     time.sleep(0.1) |                     time.sleep(0.1) | ||||||
|                     t.heartbeat() |                     t.heartbeat() | ||||||
|                 t.end() |                 t.end() | ||||||
|             s.heartbeat() |             s.heartbeat() | ||||||
|  |         if not s.was_cancelled(): | ||||||
|             s.end() |             s.end() | ||||||
|      |      | ||||||
|     w = gtk.Window(gtk.WINDOW_TOPLEVEL) |     w = gtk.Window(gtk.WINDOW_TOPLEVEL) | ||||||
|   | |||||||
| @@ -88,7 +88,8 @@ class ProgressMeter(object): | |||||||
|     MODE_FRACTION = 0 |     MODE_FRACTION = 0 | ||||||
|     MODE_ACTIVITY = 1 |     MODE_ACTIVITY = 1 | ||||||
|      |      | ||||||
|     def __init__(self, title, header=''): |     def __init__(self, title, header='', can_cancel=False,  | ||||||
|  |                  cancel_callback=None): | ||||||
|         """ |         """ | ||||||
|         Specify the title and the current pass header. |         Specify the title and the current pass header. | ||||||
|         """ |         """ | ||||||
| @@ -97,8 +98,17 @@ class ProgressMeter(object): | |||||||
|         self.__pbar_max = 100.0 |         self.__pbar_max = 100.0 | ||||||
|         self.__pbar_index = 0.0 |         self.__pbar_index = 0.0 | ||||||
|         self.__old_val = -1 |         self.__old_val = -1 | ||||||
|  |         self.__can_cancel = can_cancel | ||||||
|  |         self.__cancelled = False | ||||||
|  |         if cancel_callback: | ||||||
|  |             self.__cancel_callback = cancel_callback | ||||||
|  |         else: | ||||||
|  |             self.__cancel_callback = self.handle_cancel | ||||||
|          |          | ||||||
|         self.__dialog = gtk.Dialog() |         self.__dialog = gtk.Dialog() | ||||||
|  |         if self.__can_cancel: | ||||||
|  |             self.__dialog.connect('delete_event', self.__cancel_callback) | ||||||
|  |         else: | ||||||
|             self.__dialog.connect('delete_event', self.__warn) |             self.__dialog.connect('delete_event', self.__warn) | ||||||
|         self.__dialog.set_has_separator(False) |         self.__dialog.set_has_separator(False) | ||||||
|         self.__dialog.set_title(title) |         self.__dialog.set_title(title) | ||||||
| @@ -118,10 +128,31 @@ class ProgressMeter(object): | |||||||
|         self.__pbar = gtk.ProgressBar() |         self.__pbar = gtk.ProgressBar() | ||||||
|         self.__dialog.vbox.add(self.__pbar) |         self.__dialog.vbox.add(self.__pbar) | ||||||
|  |  | ||||||
|  |         if self.__can_cancel: | ||||||
|  |             self.__dialog.set_size_request(350, 170) | ||||||
|  |             self.__cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) | ||||||
|  |             self.__cancel_button.connect('clicked', self.__cancel_callback) | ||||||
|  |             self.__dialog.vbox.add(self.__cancel_button) | ||||||
|  |          | ||||||
|         self.__dialog.show_all() |         self.__dialog.show_all() | ||||||
|         if header == '': |         if header == '': | ||||||
|             self.__lbl.hide() |             self.__lbl.hide() | ||||||
|  |  | ||||||
|  |     def handle_cancel(self, *args, **kwargs): | ||||||
|  |         """ | ||||||
|  |         Default cancel handler (if enabled). | ||||||
|  |         """ | ||||||
|  |         self.__cancel_button.set_sensitive(False) | ||||||
|  |         self.__lbl.set_label(_("Cancelling...")) | ||||||
|  |         self.__cancelled = True | ||||||
|  |  | ||||||
|  |     def get_cancelled(self): | ||||||
|  |         """ | ||||||
|  |         Returns cancelled setting. True if progress meter has been | ||||||
|  |         cancelled. | ||||||
|  |         """ | ||||||
|  |         return self.__cancelled | ||||||
|  |  | ||||||
|     def set_pass(self, header="", total=100, mode=MODE_FRACTION): |     def set_pass(self, header="", total=100, mode=MODE_FRACTION): | ||||||
|         """ |         """ | ||||||
|         Reset for another pass. Provide a new header and define number |         Reset for another pass. Provide a new header and define number | ||||||
| @@ -132,6 +163,8 @@ class ProgressMeter(object): | |||||||
|         self.__pbar_max = total |         self.__pbar_max = total | ||||||
|         self.__pbar_index = 0.0 |         self.__pbar_index = 0.0 | ||||||
|          |          | ||||||
|  |         # If it is cancelling, don't overwite that message: | ||||||
|  |         if not self.__cancelled: | ||||||
|             self.__lbl.set_text(header) |             self.__lbl.set_text(header) | ||||||
|             if header == '': |             if header == '': | ||||||
|                 self.__lbl.hide() |                 self.__lbl.hide() | ||||||
| @@ -171,6 +204,8 @@ class ProgressMeter(object): | |||||||
|         while gtk.events_pending(): |         while gtk.events_pending(): | ||||||
|             gtk.main_iteration() |             gtk.main_iteration() | ||||||
|  |  | ||||||
|  |         return self.__cancelled | ||||||
|  |  | ||||||
|     def set_header(self, text): |     def set_header(self, text): | ||||||
|         self.__lbl.set_text(text) |         self.__lbl.set_text(text) | ||||||
|         while gtk.events_pending(): |         while gtk.events_pending(): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user