diff options
Diffstat (limited to 'extensions/cpsection/updater/view.py')
-rw-r--r-- | extensions/cpsection/updater/view.py | 398 |
1 files changed, 0 insertions, 398 deletions
diff --git a/extensions/cpsection/updater/view.py b/extensions/cpsection/updater/view.py deleted file mode 100644 index 891f552..0000000 --- a/extensions/cpsection/updater/view.py +++ /dev/null @@ -1,398 +0,0 @@ -# Copyright (C) 2008, One Laptop Per Child -# Copyright (C) 2009, Tomeu Vizoso -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from gettext import gettext as _ -from gettext import ngettext -import locale -import logging - -import gobject -import gtk - -from sugar.graphics import style -from sugar.graphics.icon import Icon, CellRendererIcon - -from jarabe.controlpanel.sectionview import SectionView - -from model import UpdateModel - -_DEBUG_VIEW_ALL = True - - -class ActivityUpdater(SectionView): - - def __init__(self, model, alerts): - SectionView.__init__(self) - - self._model = UpdateModel() - self._model.connect('progress', self.__progress_cb) - - self.set_spacing(style.DEFAULT_SPACING) - self.set_border_width(style.DEFAULT_SPACING * 2) - - self._top_label = gtk.Label() - self._top_label.set_line_wrap(True) - self._top_label.set_justify(gtk.JUSTIFY_LEFT) - self._top_label.props.xalign = 0 - self.pack_start(self._top_label, expand=False) - self._top_label.show() - - separator = gtk.HSeparator() - self.pack_start(separator, expand=False) - separator.show() - - bottom_label = gtk.Label() - bottom_label.set_line_wrap(True) - bottom_label.set_justify(gtk.JUSTIFY_LEFT) - bottom_label.props.xalign = 0 - bottom_label.set_markup( - _('Software updates correct errors, eliminate security ' \ - 'vulnerabilities, and provide new features.')) - self.pack_start(bottom_label, expand=False) - bottom_label.show() - - self._update_box = None - self._progress_pane = None - - self._refresh() - - def _switch_to_update_box(self): - if self._update_box in self.get_children(): - return - - if self._progress_pane in self.get_children(): - self.remove(self._progress_pane) - self._progress_pane = None - - if self._update_box is None: - self._update_box = UpdateBox(self._model) - self._update_box.refresh_button.connect('clicked', - self.__refresh_button_clicked_cb) - self._update_box.install_button.connect('clicked', - self.__install_button_clicked_cb) - - self.pack_start(self._update_box, expand=True, fill=True) - self._update_box.show() - - def _switch_to_progress_pane(self): - if self._progress_pane in self.get_children(): - return - - if self._update_box in self.get_children(): - self.remove(self._update_box) - self._update_box = None - - 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() - - def _clear_center(self): - if self._progress_pane in self.get_children(): - self.remove(self._progress_pane) - self._progress_pane = None - - if self._update_box in self.get_children(): - self.remove(self._update_box) - self._update_box = None - - def __progress_cb(self, model, action, bundle_name, current, total): - if current == total and action == UpdateModel.ACTION_CHECKING: - self._finished_checking() - return - elif current == total: - self._finished_updating(int(current)) - return - - if action == UpdateModel.ACTION_CHECKING: - message = _('%s...') % bundle_name - elif action == UpdateModel.ACTION_DOWNLOADING: - message = _('Downloading %s...') % bundle_name - elif action == UpdateModel.ACTION_UPDATING: - message = _('Updating %s...') % bundle_name - - self._switch_to_progress_pane() - self._progress_pane.set_message(message) - 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') - else: - top_message = ngettext('You can install %s update', - 'You can install %s updates', - available_updates) - top_message = top_message % available_updates - top_message = gobject.markup_escape_text(top_message) - - self._top_label.set_markup('<big>%s</big>' % top_message) - - if not available_updates: - self._clear_center() - else: - self._switch_to_update_box() - self._update_box.refresh() - - def __refresh_button_clicked_cb(self, button): - self._refresh() - - def _refresh(self): - top_message = _('Checking for updates...') - self._top_label.set_markup('<big>%s</big>' % top_message) - self._model.check_updates() - - def __install_button_clicked_cb(self, button): - text = '<big>%s</big>' % _('Installing updates...') - self._top_label.set_markup(text) - self._model.update(self._update_box.get_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 - top_message = gobject.markup_escape_text(top_message) - self._top_label.set_markup('<big>%s</big>' % top_message) - self._clear_center() - - def undo(self): - self._model.cancel() - - -class ProgressPane(gtk.VBox): - """Container which replaces the `ActivityPane` during refresh or - install.""" - - def __init__(self): - gtk.VBox.__init__(self) - self.set_spacing(style.DEFAULT_PADDING) - self.set_border_width(style.DEFAULT_SPACING * 2) - - self._progress = gtk.ProgressBar() - self.pack_start(self._progress) - self._progress.show() - - self._label = gtk.Label() - self._label.set_line_wrap(True) - self._label.set_property('xalign', 0.5) - self._label.modify_fg(gtk.STATE_NORMAL, - style.COLOR_BUTTON_GREY.get_gdk_color()) - self.pack_start(self._label) - self._label.show() - - alignment_box = gtk.Alignment(xalign=0.5, yalign=0.5) - self.pack_start(alignment_box) - alignment_box.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) - - def set_progress(self, fraction): - self._progress.props.fraction = fraction - - -class UpdateBox(gtk.VBox): - - def __init__(self, model): - gtk.VBox.__init__(self) - - self._model = model - - self.set_spacing(style.DEFAULT_PADDING) - - scrolled_window = gtk.ScrolledWindow() - scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.pack_start(scrolled_window) - scrolled_window.show() - - self._update_list = UpdateList(model) - self._update_list.props.model.connect('row-changed', - self.__row_changed_cb) - scrolled_window.add(self._update_list) - self._update_list.show() - - bottom_box = gtk.HBox() - bottom_box.set_spacing(style.DEFAULT_SPACING) - self.pack_start(bottom_box, expand=False) - bottom_box.show() - - self._size_label = gtk.Label() - self._size_label.props.xalign = 0 - self._size_label.set_justify(gtk.JUSTIFY_LEFT) - bottom_box.pack_start(self._size_label, expand=True) - self._size_label.show() - - self.refresh_button = gtk.Button(stock=gtk.STOCK_REFRESH) - bottom_box.pack_start(self.refresh_button, expand=False) - self.refresh_button.show() - - self.install_button = gtk.Button(_('Install selected')) - self.install_button.props.image = Icon(icon_name='emblem-downloads', - icon_size=gtk.ICON_SIZE_BUTTON) - bottom_box.pack_start(self.install_button, expand=False) - self.install_button.show() - - self._update_total_size_label() - - def refresh(self): - self._update_list.refresh() - - def __row_changed_cb(self, list_model, path, iterator): - self._update_total_size_label() - self._update_install_button() - - def _update_total_size_label(self): - total_size = 0 - for row in self._update_list.props.model: - if row[UpdateListModel.SELECTED]: - total_size += row[UpdateListModel.SIZE] - - markup = _('Download size: %s') % _format_size(total_size) - self._size_label.set_markup(markup) - - def _update_install_button(self): - for row in self._update_list.props.model: - if row[UpdateListModel.SELECTED]: - self.install_button.props.sensitive = True - return - self.install_button.props.sensitive = False - - def get_bundles_to_update(self): - bundles_to_update = [] - for row in self._update_list.props.model: - if row[UpdateListModel.SELECTED]: - bundles_to_update.append(row[UpdateListModel.BUNDLE_ID]) - return bundles_to_update - - -class UpdateList(gtk.TreeView): - - def __init__(self, model): - list_model = UpdateListModel(model) - gtk.TreeView.__init__(self, list_model) - - self.set_reorderable(False) - self.set_enable_search(False) - self.set_headers_visible(False) - - toggle_renderer = gtk.CellRendererToggle() - toggle_renderer.props.activatable = True - toggle_renderer.props.xpad = style.DEFAULT_PADDING - toggle_renderer.props.indicator_size = style.zoom(26) - toggle_renderer.connect('toggled', self.__toggled_cb) - - toggle_column = gtk.TreeViewColumn() - toggle_column.pack_start(toggle_renderer) - toggle_column.add_attribute(toggle_renderer, 'active', - UpdateListModel.SELECTED) - self.append_column(toggle_column) - - icon_renderer = CellRendererIcon(self) - icon_renderer.props.width = style.STANDARD_ICON_SIZE - icon_renderer.props.height = style.STANDARD_ICON_SIZE - icon_renderer.props.size = style.STANDARD_ICON_SIZE - icon_renderer.props.xpad = style.DEFAULT_PADDING - icon_renderer.props.ypad = style.DEFAULT_PADDING - icon_renderer.props.stroke_color = style.COLOR_TOOLBAR_GREY.get_svg() - icon_renderer.props.fill_color = style.COLOR_TRANSPARENT.get_svg() - - icon_column = gtk.TreeViewColumn() - icon_column.pack_start(icon_renderer) - icon_column.add_attribute(icon_renderer, 'file-name', - UpdateListModel.ICON_FILE_NAME) - self.append_column(icon_column) - - text_renderer = gtk.CellRendererText() - - description_column = gtk.TreeViewColumn() - description_column.pack_start(text_renderer) - description_column.add_attribute(text_renderer, 'markup', - UpdateListModel.DESCRIPTION) - self.append_column(description_column) - - def __toggled_cb(self, cell_renderer, path): - row = self.props.model[path] - row[UpdateListModel.SELECTED] = not row[UpdateListModel.SELECTED] - - def refresh(self): - pass - - -class UpdateListModel(gtk.ListStore): - - BUNDLE_ID = 0 - SELECTED = 1 - ICON_FILE_NAME = 2 - DESCRIPTION = 3 - SIZE = 4 - - def __init__(self, model): - gtk.ListStore.__init__(self, str, bool, str, str, int) - - for bundle_update in model.updates: - row = [None] * 5 - row[self.BUNDLE_ID] = bundle_update.bundle.get_bundle_id() - row[self.SELECTED] = False - row[self.ICON_FILE_NAME] = bundle_update.bundle.get_icon() - - if bundle_update.package_type == 'update': - row[self.SELECTED] = True - details = _('From version %(current)s to %(new)s (Size: %(size)s)') - details = details % \ - {'current': bundle_update.bundle.get_activity_version(), - 'new': bundle_update.version, - 'size': _format_size(bundle_update.size)} - elif bundle_update.package_type == 'new': - details = _('Install new activity version %(new)s (Size: %(size)s)') - details = details % \ - {'new': bundle_update.version, - 'size': _format_size(bundle_update.size)} - - row[self.DESCRIPTION] = '<b>%s</b>\n%s' % \ - (bundle_update.bundle.get_name(), details) - - row[self.SIZE] = bundle_update.size - - self.append(row) - - -def _format_size(size): - """Convert a given size in bytes to a nicer better readable unit""" - if size == 0: - # TRANS: download size is 0 - return _('None') - elif size < 1024: - # TRANS: download size of very small updates - return _('1 KB') - elif size < 1024 * 1024: - # TRANS: download size of small updates, e.g. '250 KB' - return locale.format_string(_('%.0f KB'), size / 1024.0) - else: - # TRANS: download size of updates, e.g. '2.3 MB' - return locale.format_string(_('%.1f MB'), size / 1024.0 / 1024) |