From 41ba9eb0ce8d1bcf8cb3c1b3e6db2e5fc3bc4ea4 Mon Sep 17 00:00:00 2001
From: Tomeu Vizoso <tomeu@sugarlabs.org>
Date: Sun, 20 Sep 2009 17:04:17 +0200
Subject: [PATCH] Implement functionality of the cancel button #1361
---
extensions/cpsection/updater/model.py | 66 ++++++++++++++++++++++++++++----
extensions/cpsection/updater/view.py | 21 +++++++---
2 files changed, 72 insertions(+), 15 deletions(-)
diff --git a/extensions/cpsection/updater/model.py b/extensions/cpsection/updater/model.py
index 102edea..ff22736 100755
a
|
b
|
class UpdateModel(gobject.GObject): |
60 | 60 | self._bundles_to_update = None |
61 | 61 | self._total_bundles_to_update = 0 |
62 | 62 | self._downloader = None |
| 63 | self._cancelling = False |
63 | 64 | |
64 | 65 | def check_updates(self): |
65 | 66 | self.updates = [] |
… |
… |
class UpdateModel(gobject.GObject): |
85 | 86 | if version is not None and version > bundle.get_activity_version(): |
86 | 87 | self.updates.append(BundleUpdate(bundle, version, link, size)) |
87 | 88 | |
88 | | if self._bundles_to_check: |
| 89 | if self._cancelling: |
| 90 | self._cancel_checking() |
| 91 | elif self._bundles_to_check: |
89 | 92 | gobject.idle_add(self._check_next_update) |
90 | 93 | else: |
91 | 94 | total = len(bundleregistry.get_registry()) |
… |
… |
class UpdateModel(gobject.GObject): |
106 | 109 | self._download_next_update() |
107 | 110 | |
108 | 111 | def _download_next_update(self): |
| 112 | if self._cancelling: |
| 113 | self._cancel_updating() |
| 114 | return |
| 115 | |
109 | 116 | bundle_update = self._bundles_to_update.pop() |
110 | 117 | |
111 | 118 | total = self._total_bundles_to_update * 2 |
… |
… |
class UpdateModel(gobject.GObject): |
120 | 127 | |
121 | 128 | def __downloader_progress_cb(self, downloader, progress): |
122 | 129 | logging.debug('__downloader_progress_cb %r', progress) |
| 130 | |
| 131 | if self._cancelling: |
| 132 | self._cancel_updating() |
| 133 | return |
| 134 | |
123 | 135 | total = self._total_bundles_to_update * 2 |
124 | 136 | current = total - len(self._bundles_to_update) * 2 - 2 + progress |
125 | 137 | |
… |
… |
class UpdateModel(gobject.GObject): |
135 | 147 | def __downloader_error_cb(self, downloader, error_message): |
136 | 148 | logging.error('Error downloading update:\n%s', error_message) |
137 | 149 | |
138 | | total = self._total_bundles_to_update * 2 |
139 | | current = total - len(self._bundles_to_update) * 2 |
| 150 | if self._cancelling: |
| 151 | self._cancel_updating() |
| 152 | return |
| 153 | |
| 154 | total = self._total_bundles_to_update |
| 155 | current = total - len(self._bundles_to_update) |
140 | 156 | self.emit('progress', UpdateModel.ACTION_UPDATING, '', current, total) |
141 | 157 | |
142 | 158 | if self._bundles_to_update: |
… |
… |
class UpdateModel(gobject.GObject): |
145 | 161 | |
146 | 162 | def _install_update(self, bundle_update, local_file_path): |
147 | 163 | |
148 | | total = self._total_bundles_to_update * 2 |
149 | | current = total - len(self._bundles_to_update) * 2 - 1 |
| 164 | total = self._total_bundles_to_update |
| 165 | current = total - len(self._bundles_to_update) - 0.5 |
150 | 166 | |
151 | 167 | self.emit('progress', UpdateModel.ACTION_UPDATING, |
152 | 168 | bundle_update.bundle.get_name(), |
… |
… |
class UpdateModel(gobject.GObject): |
165 | 181 | finally: |
166 | 182 | jobject.destroy() |
167 | 183 | |
168 | | current += 1 |
169 | 184 | self.emit('progress', UpdateModel.ACTION_UPDATING, |
170 | 185 | bundle_update.bundle.get_name(), |
171 | | current, total) |
| 186 | current + 0.5, total) |
172 | 187 | |
173 | 188 | if self._bundles_to_update: |
174 | 189 | # do it in idle so the UI has a chance to refresh |
175 | 190 | gobject.idle_add(self._download_next_update) |
176 | 191 | |
177 | | def get_total_bundles_to_update(self): |
178 | | return self._total_bundles_to_update |
| 192 | def cancel(self): |
| 193 | self._cancelling = True |
| 194 | |
| 195 | def _cancel_checking(self): |
| 196 | logging.debug('UpdateModel._cancel_checking') |
| 197 | total = len(bundleregistry.get_registry()) |
| 198 | current = total - len(self._bundles_to_check) |
| 199 | self.emit('progress', UpdateModel.ACTION_CHECKING, '', current, current) |
| 200 | self._bundles_to_check = None |
| 201 | self._cancelling = False |
| 202 | |
| 203 | def _cancel_updating(self): |
| 204 | logging.debug('UpdateModel._cancel_updating') |
| 205 | current = self._total_bundles_to_update - len(self._bundles_to_update) - 1 |
| 206 | self.emit('progress', UpdateModel.ACTION_UPDATING, '', current, current) |
179 | 207 | |
| 208 | if self._downloader is not None: |
| 209 | self._downloader.cancel() |
| 210 | self._downloader = None |
| 211 | |
| 212 | self._total_bundles_to_update = 0 |
| 213 | self._bundles_to_update = None |
| 214 | self._cancelling = False |
180 | 215 | |
181 | 216 | class BundleUpdate(object): |
182 | 217 | |
… |
… |
class _Downloader(gobject.GObject): |
208 | 243 | self._input_file = gio.File(bundle_update.link) |
209 | 244 | self._output_file = None |
210 | 245 | self._downloaded_size = 0 |
| 246 | self._cancelling = False |
211 | 247 | |
212 | 248 | self._input_file.read_async(self.__file_read_async_cb) |
213 | 249 | |
| 250 | def cancel(self): |
| 251 | self._cancelling = True |
| 252 | |
214 | 253 | def __file_read_async_cb(self, gfile, result): |
| 254 | if self._cancelling: |
| 255 | return |
| 256 | |
215 | 257 | try: |
216 | 258 | self._input_stream = self._input_file.read_finish(result) |
217 | 259 | except: |
… |
… |
class _Downloader(gobject.GObject): |
226 | 268 | gobject.PRIORITY_LOW) |
227 | 269 | |
228 | 270 | def __read_async_cb(self, input_stream, result): |
| 271 | if self._cancelling: |
| 272 | return |
| 273 | |
229 | 274 | data = input_stream.read_finish(result) |
230 | 275 | |
231 | 276 | if data is None: |
… |
… |
class _Downloader(gobject.GObject): |
244 | 289 | self._write_next_buffer() |
245 | 290 | |
246 | 291 | def __write_async_cb(self, output_stream, result, user_data): |
| 292 | if self._cancelling: |
| 293 | return |
| 294 | |
247 | 295 | count = output_stream.write_finish(result) |
248 | 296 | |
249 | 297 | self._downloaded_size += count |
diff --git a/extensions/cpsection/updater/view.py b/extensions/cpsection/updater/view.py
index 9a77743..2164c0b 100644
a
|
b
|
|
18 | 18 | from gettext import gettext as _ |
19 | 19 | from gettext import ngettext |
20 | 20 | import locale |
| 21 | import logging |
21 | 22 | |
22 | 23 | import gobject |
23 | 24 | import gtk |
… |
… |
class ActivityUpdater(SectionView): |
97 | 98 | |
98 | 99 | if self._progress_pane is None: |
99 | 100 | self._progress_pane = ProgressPane() |
| 101 | self._progress_pane.cancel_button.connect('clicked', |
| 102 | self.__cancel_button_clicked_cb) |
100 | 103 | |
101 | 104 | self.pack_start(self._progress_pane, expand=True, fill=False) |
102 | 105 | self._progress_pane.show() |
… |
… |
class ActivityUpdater(SectionView): |
115 | 118 | self._finished_checking() |
116 | 119 | return |
117 | 120 | elif current == total: |
118 | | self._finished_updating() |
| 121 | self._finished_updating(int(current)) |
119 | 122 | return |
120 | 123 | |
121 | 124 | if action == UpdateModel.ACTION_CHECKING: |
… |
… |
class ActivityUpdater(SectionView): |
130 | 133 | self._progress_pane.set_progress(current / float(total)) |
131 | 134 | |
132 | 135 | def _finished_checking(self): |
| 136 | logging.debug('ActivityUpdater._finished_checking') |
133 | 137 | available_updates = len(self._model.updates) |
134 | 138 | if not available_updates: |
135 | 139 | top_message = _('Your software is up-to-date') |
… |
… |
class ActivityUpdater(SectionView): |
160 | 164 | self._top_label.set_markup('<big>%s</big>' % _('Installing updates...')) |
161 | 165 | self._model.update(self._update_box.get_bundles_to_update()) |
162 | 166 | |
163 | | def _finished_updating(self): |
164 | | installed_updates = self._model.get_total_bundles_to_update() |
| 167 | def __cancel_button_clicked_cb(self, button): |
| 168 | self._model.cancel() |
| 169 | |
| 170 | def _finished_updating(self, installed_updates): |
| 171 | logging.debug('ActivityUpdater._finished_updating') |
165 | 172 | top_message = ngettext('%s update was installed', |
166 | 173 | '%s updates were installed', installed_updates) |
167 | 174 | top_message = top_message % installed_updates |
… |
… |
class ActivityUpdater(SectionView): |
169 | 176 | self._top_label.set_markup('<big>%s</big>' % top_message) |
170 | 177 | self._clear_center() |
171 | 178 | |
| 179 | def undo(self): |
| 180 | self._model.cancel() |
172 | 181 | |
173 | 182 | class ProgressPane(gtk.VBox): |
174 | 183 | '''Container which replaces the `ActivityPane` during refresh or |
… |
… |
class ProgressPane(gtk.VBox): |
195 | 204 | self.pack_start(alignment_box) |
196 | 205 | alignment_box.show() |
197 | 206 | |
198 | | cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) |
199 | | alignment_box.add(cancel_button) |
200 | | cancel_button.show() |
| 207 | self.cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) |
| 208 | alignment_box.add(self.cancel_button) |
| 209 | self.cancel_button.show() |
201 | 210 | |
202 | 211 | def set_message(self, message): |
203 | 212 | self._label.set_text(message) |