From 3546b5b1bbe059281e86660c555d1b64a8f69342 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sun, 20 Sep 2009 15:04:17 +0000 Subject: Implement functionality of the cancel button #1361 --- diff --git a/extensions/cpsection/updater/model.py b/extensions/cpsection/updater/model.py index 102edea..ff22736 100755 --- a/extensions/cpsection/updater/model.py +++ b/extensions/cpsection/updater/model.py @@ -60,6 +60,7 @@ class UpdateModel(gobject.GObject): self._bundles_to_update = None self._total_bundles_to_update = 0 self._downloader = None + self._cancelling = False def check_updates(self): self.updates = [] @@ -85,7 +86,9 @@ class UpdateModel(gobject.GObject): if version is not None and version > bundle.get_activity_version(): self.updates.append(BundleUpdate(bundle, version, link, size)) - if self._bundles_to_check: + if self._cancelling: + self._cancel_checking() + elif self._bundles_to_check: gobject.idle_add(self._check_next_update) else: total = len(bundleregistry.get_registry()) @@ -106,6 +109,10 @@ class UpdateModel(gobject.GObject): self._download_next_update() def _download_next_update(self): + if self._cancelling: + self._cancel_updating() + return + bundle_update = self._bundles_to_update.pop() total = self._total_bundles_to_update * 2 @@ -120,6 +127,11 @@ class UpdateModel(gobject.GObject): def __downloader_progress_cb(self, downloader, progress): logging.debug('__downloader_progress_cb %r', progress) + + if self._cancelling: + self._cancel_updating() + return + total = self._total_bundles_to_update * 2 current = total - len(self._bundles_to_update) * 2 - 2 + progress @@ -135,8 +147,12 @@ class UpdateModel(gobject.GObject): def __downloader_error_cb(self, downloader, error_message): logging.error('Error downloading update:\n%s', error_message) - total = self._total_bundles_to_update * 2 - current = total - len(self._bundles_to_update) * 2 + if self._cancelling: + self._cancel_updating() + return + + total = self._total_bundles_to_update + current = total - len(self._bundles_to_update) self.emit('progress', UpdateModel.ACTION_UPDATING, '', current, total) if self._bundles_to_update: @@ -145,8 +161,8 @@ class UpdateModel(gobject.GObject): def _install_update(self, bundle_update, local_file_path): - total = self._total_bundles_to_update * 2 - current = total - len(self._bundles_to_update) * 2 - 1 + total = self._total_bundles_to_update + current = total - len(self._bundles_to_update) - 0.5 self.emit('progress', UpdateModel.ACTION_UPDATING, bundle_update.bundle.get_name(), @@ -165,18 +181,37 @@ class UpdateModel(gobject.GObject): finally: jobject.destroy() - current += 1 self.emit('progress', UpdateModel.ACTION_UPDATING, bundle_update.bundle.get_name(), - current, total) + current + 0.5, total) if self._bundles_to_update: # do it in idle so the UI has a chance to refresh gobject.idle_add(self._download_next_update) - def get_total_bundles_to_update(self): - return self._total_bundles_to_update + def cancel(self): + self._cancelling = True + + def _cancel_checking(self): + logging.debug('UpdateModel._cancel_checking') + total = len(bundleregistry.get_registry()) + current = total - len(self._bundles_to_check) + self.emit('progress', UpdateModel.ACTION_CHECKING, '', current, current) + self._bundles_to_check = None + self._cancelling = False + + def _cancel_updating(self): + logging.debug('UpdateModel._cancel_updating') + current = self._total_bundles_to_update - len(self._bundles_to_update) - 1 + self.emit('progress', UpdateModel.ACTION_UPDATING, '', current, current) + if self._downloader is not None: + self._downloader.cancel() + self._downloader = None + + self._total_bundles_to_update = 0 + self._bundles_to_update = None + self._cancelling = False class BundleUpdate(object): @@ -208,10 +243,17 @@ class _Downloader(gobject.GObject): self._input_file = gio.File(bundle_update.link) self._output_file = None self._downloaded_size = 0 + self._cancelling = False self._input_file.read_async(self.__file_read_async_cb) + def cancel(self): + self._cancelling = True + def __file_read_async_cb(self, gfile, result): + if self._cancelling: + return + try: self._input_stream = self._input_file.read_finish(result) except: @@ -226,6 +268,9 @@ class _Downloader(gobject.GObject): gobject.PRIORITY_LOW) def __read_async_cb(self, input_stream, result): + if self._cancelling: + return + data = input_stream.read_finish(result) if data is None: @@ -244,6 +289,9 @@ class _Downloader(gobject.GObject): self._write_next_buffer() def __write_async_cb(self, output_stream, result, user_data): + if self._cancelling: + return + count = output_stream.write_finish(result) self._downloaded_size += count diff --git a/extensions/cpsection/updater/view.py b/extensions/cpsection/updater/view.py index 9a77743..2164c0b 100644 --- a/extensions/cpsection/updater/view.py +++ b/extensions/cpsection/updater/view.py @@ -18,6 +18,7 @@ from gettext import gettext as _ from gettext import ngettext import locale +import logging import gobject import gtk @@ -97,6 +98,8 @@ class ActivityUpdater(SectionView): if self._progress_pane is None: self._progress_pane = ProgressPane() + self._progress_pane.cancel_button.connect('clicked', + self.__cancel_button_clicked_cb) self.pack_start(self._progress_pane, expand=True, fill=False) self._progress_pane.show() @@ -115,7 +118,7 @@ class ActivityUpdater(SectionView): self._finished_checking() return elif current == total: - self._finished_updating() + self._finished_updating(int(current)) return if action == UpdateModel.ACTION_CHECKING: @@ -130,6 +133,7 @@ class ActivityUpdater(SectionView): self._progress_pane.set_progress(current / float(total)) def _finished_checking(self): + logging.debug('ActivityUpdater._finished_checking') available_updates = len(self._model.updates) if not available_updates: top_message = _('Your software is up-to-date') @@ -160,8 +164,11 @@ class ActivityUpdater(SectionView): self._top_label.set_markup('%s' % _('Installing updates...')) self._model.update(self._update_box.get_bundles_to_update()) - def _finished_updating(self): - installed_updates = self._model.get_total_bundles_to_update() + def __cancel_button_clicked_cb(self, button): + self._model.cancel() + + def _finished_updating(self, installed_updates): + logging.debug('ActivityUpdater._finished_updating') top_message = ngettext('%s update was installed', '%s updates were installed', installed_updates) top_message = top_message % installed_updates @@ -169,6 +176,8 @@ class ActivityUpdater(SectionView): self._top_label.set_markup('%s' % top_message) self._clear_center() + def undo(self): + self._model.cancel() class ProgressPane(gtk.VBox): '''Container which replaces the `ActivityPane` during refresh or @@ -195,9 +204,9 @@ class ProgressPane(gtk.VBox): self.pack_start(alignment_box) alignment_box.show() - cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) - alignment_box.add(cancel_button) - cancel_button.show() + self.cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) + alignment_box.add(self.cancel_button) + self.cancel_button.show() def set_message(self, message): self._label.set_text(message) -- cgit v0.9.1