diff options
author | Pootle daemon <pootle@pootle.sugarlabs.org> | 2012-10-14 04:32:24 (GMT) |
---|---|---|
committer | Pootle daemon <pootle@pootle.sugarlabs.org> | 2012-10-14 04:32:24 (GMT) |
commit | c784518437f78ab9da945d60fbff88520943000c (patch) | |
tree | 0ecb0795eb781069418a1629df09b3b84cd796a5 | |
parent | 722a12b5076dbd7cd5b21ec524f8f8e62e283e17 (diff) | |
parent | 8158de9ac9f0fc6bba0891e47d17fcf46ebb4028 (diff) |
Merge branch 'master' of git.sugarlabs.org:sugar-update-control/mainline
-rw-r--r-- | setup.py | 2 | ||||
-rwxr-xr-x | src/model.py | 42 | ||||
-rwxr-xr-x | src/view.py | 260 | ||||
-rw-r--r-- | sugar-update-control.spec | 6 |
4 files changed, 146 insertions, 164 deletions
@@ -3,7 +3,7 @@ from DistUtilsExtra.command import * # gettext support from distutils.core import setup setup(name='sugar-update-control', - version="0.24", + version="0.25", description='Sugar update control panel', author='C. Scott Ananian', author_email='cscott@laptop.org', diff --git a/src/model.py b/src/model.py index 303f337..35896e2 100755 --- a/src/model.py +++ b/src/model.py @@ -8,7 +8,7 @@ This module implements the non-GUI portions of the activity updater, including in particular the master list of groups, activities, whether updates are needed, and the URL at which to find the updated activity. -Because `UpdateList` inherits from `gtk.ListStore` so that it plays +Because `UpdateList` inherits from `Gtk.ListStore` so that it plays nicely with a GUI, this module requires `gtk`. Those of you without DISPLAY set will have to put up with a GtkWarning that the display couldn't be opened. Sorry. @@ -23,8 +23,10 @@ _DEBUG_CHECK_VERSIONS = False # default timeout for HTTP connections, in seconds HTTP_TIMEOUT=30 -import gtk -import gobject +from gi.repository import Rsvg +from gi.repository import Gtk +from gi.repository import GdkPixbuf +from gi.repository import GObject import locale import os @@ -44,7 +46,7 @@ import bitfrost.update.actutils as actutils import bitfrost.update.microformat as microformat import bitfrost.util.urlrange as urlrange -from sugar.bundle.bundleversion import NormalizedVersion +from sugar3.bundle.bundleversion import NormalizedVersion # weak dependency on inhibit_suspend from olpc-update package try: @@ -72,21 +74,21 @@ def _humanize_size(bytes): return locale.format_string(_("%.1f MB"), bytes / 1024 / 1024) def _svg2pixbuf(icon_data): - """Convert the given `icon_data` SVG string to a `gtk.gdk.Pixbuf` + """Convert the given `icon_data` SVG string to a `GdkPixbuf.Pixbuf` with maximum size 55x55.""" - import re, rsvg + import re # substitute black/white for icon color entities. for entity, value in [('stroke_color','#808080'), ('fill_color','#eee')]: xml = '<!ENTITY %s "%s">' % (entity, value) icon_data = re.sub('<!ENTITY %s .*>' % entity, xml, icon_data) - h = rsvg.Handle(data=icon_data) + h = Rsvg.Handle.new_from_data(icon_data) if h.get_property('width') > 55 or h.get_property('height') > 55: # lame! scale it. print "WARNING: oversize icon (%dx%d), scaling." % \ (h.get_property('width'), h.get_property('height')) del h - pbl = gtk.gdk.PixbufLoader() + pbl = GdkPixbuf.PixbufLoader() pbl.set_size(55, 55) pbl.write(icon_data) pbl.close() @@ -176,28 +178,28 @@ _column_name_map = dict((k,v) for k,v in globals().items() if k not in _column_name_map and k!='_column_name_map') """Mapping from column names to indices.""" -class UpdateList(gtk.ListStore): +class UpdateList(Gtk.ListStore): """Model which provides backing storage for the activity list treeview.""" __gproperties__ = { - 'is_valid': (gobject.TYPE_BOOLEAN, 'is valid', + 'is_valid': (GObject.TYPE_BOOLEAN, 'is valid', 'true iff the UpdateList has been properly refreshed', - False, gobject.PARAM_READABLE), - 'saw_network_failure': (gobject.TYPE_BOOLEAN, 'saw network failure', + False, GObject.PARAM_READABLE), + 'saw_network_failure': (GObject.TYPE_BOOLEAN, 'saw network failure', 'true iff at least one network IO error '+ 'occurred when the UpdateList was last '+ 'refreshed', - False, gobject.PARAM_READABLE), - 'saw_network_success': (gobject.TYPE_BOOLEAN, 'saw network success', + False, GObject.PARAM_READABLE), + 'saw_network_success': (GObject.TYPE_BOOLEAN, 'saw network success', 'true iff at least one network operation '+ 'completed successfully when the UpdateList '+ 'was last refreshed', - False, gobject.PARAM_READABLE), + False, GObject.PARAM_READABLE), } def __init__(self, skip_icons=False): - gtk.ListStore.__init__(self, + Gtk.ListStore.__init__(self, # column types - str, object, gtk.gdk.Pixbuf, + str, object, GdkPixbuf.Pixbuf, str, str, long, bool, bool, str, str, bool, int) self._skip_icons = skip_icons @@ -214,7 +216,7 @@ class UpdateList(gtk.ListStore): global _column_name_map # defaults for each column row = [None, None, None, - None, 0, 0, + None, "0", 0, True, True, None, None, False, 0] # set entries in the row based on kwargs for k,v in kwargs.items(): @@ -315,7 +317,7 @@ class UpdateList(gtk.ListStore): GROUP_NUM=group_num, UPDATE_EXISTS=True, UPDATE_URL=url, - UPDATE_VERSION=version, + UPDATE_VERSION=str(version), DESCRIPTION_BIG=tmp_desc) steps_total[0] += 1 # new activity? else: @@ -834,7 +836,7 @@ def set_install_update(which): from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) # we'll fetch the main loop, but we don't actually have to run it. - loop = gobject.MainLoop() + loop = GObject.MainLoop() from jarabe.model.bundleregistry import get_registry registry = get_registry() def reporthook(n, row): diff --git a/src/view.py b/src/view.py index 11c9f78..32cb580 100755 --- a/src/view.py +++ b/src/view.py @@ -7,10 +7,11 @@ Checks for updates to activities and installs them.""" from __future__ import with_statement from __future__ import division -import pygtk -pygtk.require('2.0') -import gtk, gobject -gtk.gdk.threads_init() +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GLib +from gi.repository import GObject +GLib.threads_init() import gettext import os @@ -21,7 +22,7 @@ import gettext _ = lambda msg: gettext.dgettext('sugar-update-control', msg) import bitfrost.update.actutils as actutils -from sugar.graphics import style +from sugar3.graphics import style from jarabe.controlpanel.sectionview import SectionView from jarabe.controlpanel.inlinealert import InlineAlert @@ -29,29 +30,6 @@ from jarabe.controlpanel.inlinealert import InlineAlert import model from model import _humanize_size, _svg2pixbuf, inhibit_suspend -# COMPATIBILITY HACK: work around trac #8532 by forcibly removing the -# SIGCHLD handler (and the necessity for one) -import sugar.activity.activityfactory -if hasattr(sugar.activity.activityfactory, '_sigchild_handler'): - from ctypes import CDLL, Structure, c_voidp, c_int, c_ulong, pointer - import signal - libc = CDLL("libc.so.6") - SA_NOCLDWAIT = 2 # according to /usr/include/bits/sigaction.h - class SIGACTION(Structure): - _fields_ = [('sa_handler', c_voidp), - ('sa_sigaction', c_voidp), - ('sa_mask', c_ulong), # sigset_t - ('sa_flags', c_int), - ('sa_restorer', c_voidp)] - desired = SIGACTION(None, # SIG_DFL, according to /usr/include/asm-generic/signal.h - None, - 0, - SA_NOCLDWAIT, - None) - libc.sigaction(signal.SIGCHLD, pointer(desired), None) -# END COMPATIBILITY HACK - - # configuration constants needed for control panel framework CLASS = 'ActivityUpdater' ICON = 'module-updater' @@ -61,32 +39,32 @@ TITLE = _('Software update') _DEBUG_VIEW_ALL=False """View even activities with no pending updates.""" -_e = gobject.markup_escape_text +_e = GObject.markup_escape_text """Useful abbreviation.""" def _make_button(label_text, stock=None, name=None): """Convenience function to make labelled buttons with images.""" - b = gtk.Button() - hbox = gtk.HBox() + b = Gtk.Button() + hbox = Gtk.HBox() hbox.set_spacing(style.DEFAULT_PADDING) - i = gtk.Image() + i = Gtk.Image() if stock is not None: - i.set_from_stock(stock, gtk.ICON_SIZE_BUTTON) + i.set_from_stock(stock, Gtk.IconSize.BUTTON) if name is not None: - i.set_from_icon_name(name, gtk.ICON_SIZE_BUTTON) - hbox.pack_start(i, expand=False) - l = gtk.Label(label_text) - hbox.pack_start(l, expand=False) + i.set_from_icon_name(name, Gtk.IconSize.BUTTON) + hbox.pack_start(i, False, True, 0) + l = Gtk.Label(label=label_text) + hbox.pack_start(l, False, True, 0) b.add(hbox) return b ### Pieces of the activity updater view; factored to make the UI structure ### more apparent in `ActivityUpdater.__init__`. -class ActivityListView(gtk.ScrolledWindow): +class ActivityListView(Gtk.ScrolledWindow): """List view at the top, showing activities, versions, and sizes.""" def __init__(self, activity_updater, activity_pane): - gtk.ScrolledWindow.__init__(self) + GObject.GObject.__init__(self) self.activity_updater = activity_updater self.activity_pane = activity_pane @@ -94,10 +72,10 @@ class ActivityListView(gtk.ScrolledWindow): self.ftreestore = self.activity_updater.activity_list.filter_new() if not _DEBUG_VIEW_ALL: self.ftreestore.set_visible_column(model.UPDATE_EXISTS) - self.treeview = gtk.TreeView(self.ftreestore) + self.treeview = Gtk.TreeView(self.ftreestore) # create some cell renderers. - crbool = gtk.CellRendererToggle() + crbool = Gtk.CellRendererToggle() crbool.set_property('activatable', True) crbool.set_property('xpad', style.DEFAULT_PADDING) # indicator size should be themeable, but is not. @@ -111,32 +89,32 @@ class ActivityListView(gtk.ScrolledWindow): self.activity_pane._refresh_update_size() crbool.connect('toggled', toggled_cb, self) - cricon = gtk.CellRendererPixbuf() + cricon = Gtk.CellRendererPixbuf() cricon.set_property('width', style.STANDARD_ICON_SIZE) cricon.set_property('height', style.STANDARD_ICON_SIZE) - crtext = gtk.CellRendererText() + crtext = Gtk.CellRendererText() crtext.set_property('xpad', style.DEFAULT_PADDING) crtext.set_property('ypad', style.DEFAULT_PADDING) # create the TreeViewColumn to display the data def view_func_maker(propname): - def view_func(cell_layout, renderer, m, it): + def view_func(cell_layout, renderer, m, it, user_data=None): renderer.set_property(propname, not m.get_value(it, model.IS_HEADER)) return view_func hide_func = view_func_maker('visible') insens_func = view_func_maker('sensitive') - self.column_install = gtk.TreeViewColumn('Install', crbool) + self.column_install = Gtk.TreeViewColumn('Install', crbool) self.column_install.add_attribute(crbool, 'active', model.UPDATE_SELECTED) self.column_install.set_cell_data_func(crbool, hide_func) - self.column = gtk.TreeViewColumn('Name') - self.column.pack_start(cricon, expand=False) - self.column.pack_start(crtext, expand=True) + self.column = Gtk.TreeViewColumn('Name') + self.column.pack_start(cricon, False) + self.column.pack_start(crtext, True) self.column.add_attribute(cricon, 'pixbuf', model.ACTIVITY_ICON) self.column.set_resizable(True) self.column.set_cell_data_func(cricon, hide_func) - def markup_func(cell_layout, renderer, m, it): + def markup_func(cell_layout, renderer, m, it, user_data): s = '<b>%s</b>' % _e(m.get_value(it, model.DESCRIPTION_BIG)) if m.get_value(it, model.IS_HEADER): s = '<big>%s</big>' % s @@ -163,9 +141,9 @@ class ActivityListView(gtk.ScrolledWindow): is_valid_cb) is_valid_cb(self.activity_updater.activity_list, None) - # now put this all inside ourself (a gtk.ScrolledWindow) + # now put this all inside ourself (a Gtk.ScrolledWindow) self.add_with_viewport(self.treeview) - self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) def unlink_model(self): self.treeview.set_model(None) @@ -177,19 +155,19 @@ class ActivityListView(gtk.ScrolledWindow): """ Show a context menu if a right click was performed on an update entry """ - if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3: activity_list = self.activity_updater.activity_list def cb(__, f): f() self.activity_pane._refresh_update_size() - menu = gtk.Menu() - item_select_none = gtk.MenuItem(_("_Uncheck All")) + menu = Gtk.Menu() + item_select_none = Gtk.MenuItem(_("_Uncheck All")) item_select_none.connect("activate", cb, activity_list.unselect_all) menu.add(item_select_none) if activity_list.updates_available() == 0: item_select_none.set_property("sensitive", False) - item_select_all = gtk.MenuItem(_("_Check All")) + item_select_all = Gtk.MenuItem(_("_Check All")) item_select_all.connect("activate", cb, activity_list.select_all) menu.add(item_select_all) @@ -198,10 +176,10 @@ class ActivityListView(gtk.ScrolledWindow): return True return False -class GroupListView(gtk.VBox): +class GroupListView(Gtk.VBox): """List view in expander at bottom, showing groups and urls.""" def __init__(self, activity_updater): - gtk.VBox.__init__(self) + GObject.GObject.__init__(self) self.set_spacing(style.DEFAULT_PADDING) self.activity_updater = activity_updater @@ -211,22 +189,24 @@ class GroupListView(gtk.VBox): return m.get_value(it, model.IS_HEADER) and \ m.get_value(it, model.UPDATE_URL) is not None self.fgroupstore.set_visible_func(group_visibility) - self.groupview = gtk.TreeView(self.fgroupstore) + self.groupview = Gtk.TreeView(self.fgroupstore) self.groupview.set_headers_visible(False) self.groupview.set_rules_hint(True) self.groupview.set_enable_search(False) self.groupview.set_reorderable(False) # we'll write own DnD funcs below - TARGETS = gtk.target_list_add_text_targets(info=0) - TARGETS = gtk.target_list_add_uri_targets(list=TARGETS, info=1) - self.groupview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, - TARGETS, - gtk.gdk.ACTION_DEFAULT - |gtk.gdk.ACTION_COPY - |gtk.gdk.ACTION_MOVE) - self.groupview.enable_model_drag_dest(TARGETS, - gtk.gdk.ACTION_DEFAULT - |gtk.gdk.ACTION_COPY - |gtk.gdk.ACTION_MOVE) + # FIXME: port to GTK3 + #TARGETS = Gtk.TargetList() + #TARGETS.add_text_targets(0) + #TARGETS.add_uri_targets(1) + #self.groupview.enable_model_drag_source( Gdk.ModifierType.BUTTON1_MASK, + # TARGETS, + # Gdk.DragAction.DEFAULT + # |Gdk.DragAction.COPY + # |Gdk.DragAction.MOVE) + #self.groupview.enable_model_drag_dest(TARGETS, + # Gdk.DragAction.DEFAULT + # |Gdk.DragAction.COPY + # |Gdk.DragAction.MOVE) def drag_data_get_data(groupview, context, drag_selection, target_id, etime): selection = groupview.get_selection() m, it = selection.get_selected() @@ -256,46 +236,46 @@ class GroupListView(gtk.VBox): path = self.fgroupstore.convert_path_to_child_path(path) desired_group_num = self.activity_updater\ .activity_list[path][model.GROUP_NUM] - if position == gtk.TREE_VIEW_DROP_AFTER \ - or position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER: + if position == Gtk.TreeViewDropPosition.AFTER \ + or position == Gtk.TreeViewDropPosition.INTO_OR_AFTER: desired_group_num += 1 if not same_widget: self.activity_updater.activity_list.add_group(gurl) success = self.activity_updater.activity_list\ .move_group(gurl, desired_group_num) - want_delete = (context.action == gtk.gdk.ACTION_MOVE) and \ + want_delete = (context.action == Gdk.DragAction.MOVE) and \ not same_widget # we'll handle the delete ourselves context.finish(success, want_delete and success, etime) return True # don't invoke parent. self.groupview.connect("drag_data_get", drag_data_get_data) self.groupview.connect("drag_data_received", drag_data_received_data) self.groupview.connect("drag_drop", drag_drop) - crtext = gtk.CellRendererText() - column = gtk.TreeViewColumn('Name', crtext) + crtext = Gtk.CellRendererText() + column = Gtk.TreeViewColumn('Name', crtext) def group_name_markup(cell_layout, renderer, m, it): renderer.set_property('markup', '<b>%s</b>\n<small>%s</small>' % \ (_e(m.get_value(it, model.DESCRIPTION_BIG)), _e(m.get_value(it, model.UPDATE_URL)))) column.set_cell_data_func(crtext, group_name_markup) self.groupview.append_column(column) - scrolled_window = gtk.ScrolledWindow() + scrolled_window = Gtk.ScrolledWindow() scrolled_window.add_with_viewport(self.groupview) - scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - hbox2 = gtk.HBox() + hbox2 = Gtk.HBox() hbox2.set_spacing(style.DEFAULT_PADDING) - label = gtk.Label(_('Group URL:')) - hbox2.pack_start(label, expand=False) - self.group_entry = gtk.Entry() - hbox2.pack_start(self.group_entry, expand=True) - self.group_add_button = gtk.Button(stock=gtk.STOCK_ADD) - self.group_del_button = gtk.Button(stock=gtk.STOCK_REMOVE) + label = Gtk.Label(label=_('Group URL:')) + hbox2.pack_start(label, False, True, 0) + self.group_entry = Gtk.Entry() + hbox2.pack_start(self.group_entry, True, True, 0) + self.group_add_button = Gtk.Button(stock=Gtk.STOCK_ADD) + self.group_del_button = Gtk.Button(stock=Gtk.STOCK_REMOVE) self.group_del_button.set_sensitive(False) - hbox2.pack_start(self.group_add_button, expand=False) - hbox2.pack_start(self.group_del_button, expand=False) + hbox2.pack_start(self.group_add_button, False, True, 0) + hbox2.pack_start(self.group_del_button, False, True, 0) selection = self.groupview.get_selection() - selection.set_mode(gtk.SELECTION_SINGLE) + selection.set_mode(Gtk.SelectionMode.SINGLE) def group_select_cb(selection): (m, it) = selection.get_selected() if it is None: return @@ -317,8 +297,8 @@ class GroupListView(gtk.VBox): self.group_add_button.connect('clicked', self._add_group_cb, self) self.group_del_button.connect('clicked', self._del_group_cb, self) - self.pack_start(scrolled_window, expand=True) - self.pack_start(hbox2, expand=False) + self.pack_start(scrolled_window, True, True, 0) + self.pack_start(hbox2, False, True, 0) def _add_group_cb(self, widget, event, data=None): success = self.activity_updater.activity_list\ @@ -340,21 +320,21 @@ class GroupListView(gtk.VBox): self.fgroupstore.refilter() self.groupview.set_model(self.fgroupstore) -class ActivityPane(gtk.VBox): +class ActivityPane(Gtk.VBox): """Container for the activity and group lists.""" def __init__(self, activity_updater): - gtk.VBox.__init__(self) + GObject.GObject.__init__(self) self.activity_updater = activity_updater self.set_spacing(style.DEFAULT_PADDING) ## activity list at top - vpaned = gtk.VPaned() + vpaned = Gtk.VPaned() self.activities = ActivityListView(activity_updater, self) vpaned.pack1(self.activities, resize=True, shrink=False) ## expander/group list view at bottom - self.expander = gtk.Expander(label=_('Modify activity groups')) + self.expander = Gtk.Expander(label=_('Modify activity groups')) self.expander.set_use_markup(True) def expander_callback(expander, __): if not expander.get_expanded(): # when groups are collapsed... @@ -363,25 +343,25 @@ class ActivityPane(gtk.VBox): self.groups = GroupListView(activity_updater) self.expander.add(self.groups) vpaned.pack2(self.expander, resize=False, shrink=False) - self.pack_start(vpaned, expand=True) + self.pack_start(vpaned, True, True, 0) ### Install/refresh buttons below these. - button_box = gtk.HBox() + button_box = Gtk.HBox() button_box.set_spacing(style.DEFAULT_SPACING) - hbox = gtk.HBox() - hbox.pack_end(button_box, expand=False) - self.size_label = gtk.Label() + hbox = Gtk.HBox() + hbox.pack_end(button_box, False, True, 0) + self.size_label = Gtk.Label() self.size_label.set_property('xalign', 0) - self.size_label.set_justify(gtk.JUSTIFY_LEFT) - hbox.pack_start(self.size_label, expand=True) - self.pack_end(hbox, expand=False) - self.check_button = gtk.Button(stock=gtk.STOCK_REFRESH) + self.size_label.set_justify(Gtk.Justification.LEFT) + hbox.pack_start(self.size_label, True, True, 0) + self.pack_end(hbox, False, True, 0) + self.check_button = Gtk.Button(stock=Gtk.STOCK_REFRESH) self.check_button.connect('clicked', activity_updater.refresh_cb, self) - button_box.pack_start(self.check_button, expand=False) + button_box.pack_start(self.check_button, False, True, 0) self.install_button = _make_button(_("Install selected"), name='emblem-downloads') self.install_button.connect('clicked', activity_updater.download_cb, self) - button_box.pack_start(self.install_button, expand=False) + button_box.pack_start(self.install_button, False, True, 0) def is_valid_cb(activity_list, __): self.install_button.set_sensitive(activity_list.is_valid()) activity_updater.activity_list.connect('notify::is-valid', is_valid_cb) @@ -409,40 +389,40 @@ class ActivityPane(gtk.VBox): (self.activity_updater.expander, False)]: widget.set_property('visible', v) -class ProgressPane(gtk.VBox): +class ProgressPane(Gtk.VBox): """Container which replaces the `ActivityPane` during refresh or install.""" def __init__(self, activity_updater): self.activity_updater = activity_updater - gtk.VBox.__init__(self) + GObject.GObject.__init__(self) self.set_spacing(style.DEFAULT_PADDING) self.set_border_width(style.DEFAULT_SPACING * 2) - self.bar = gtk.ProgressBar() - self.label = gtk.Label() + self.bar = Gtk.ProgressBar() + self.label = Gtk.Label() self.label.set_line_wrap(True) self.label.set_property('xalign', 0.5) # center the label. - self.label.modify_fg(gtk.STATE_NORMAL, + self.label.modify_fg(Gtk.StateType.NORMAL, style.COLOR_BUTTON_GREY.get_gdk_color()) - self.icon = gtk.Image() + self.icon = Gtk.Image() self.icon.set_property('height-request', style.STANDARD_ICON_SIZE) # make an HBox to center the various buttons. - hbox = gtk.HBox() - self.cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) - self.refresh_button = gtk.Button(stock=gtk.STOCK_REFRESH) + hbox = Gtk.HBox() + self.cancel_button = Gtk.Button(stock=Gtk.STOCK_CANCEL) + self.refresh_button = Gtk.Button(stock=Gtk.STOCK_REFRESH) self.try_again_button = _make_button(_('Try again'), - stock=gtk.STOCK_REFRESH) + stock=Gtk.STOCK_REFRESH) for widget,cb in [(self.cancel_button, activity_updater.cancel_cb), (self.refresh_button, activity_updater.refresh_cb), (self.try_again_button, activity_updater.refresh_cb)]: widget.connect('clicked', cb, activity_updater) - hbox.pack_start(widget, expand=True, fill=False) + hbox.pack_start(widget, True, False, 0) - self.pack_start(self.icon) - self.pack_start(self.bar) - self.pack_start(self.label) - self.pack_start(hbox) + self.pack_start(self.icon, True, True, 0) + self.pack_start(self.bar, True, True, 0) + self.pack_start(self.label, True, True, 0) + self.pack_start(hbox, True, True, 0) def update(self, n, extra=None, icon=None): """Update the status of the progress pane. `n` should be a float @@ -503,40 +483,40 @@ class ActivityUpdater(SectionView): self.set_border_width(style.DEFAULT_SPACING * 2) # top labels. - self.top_label = gtk.Label() + self.top_label = Gtk.Label() self.top_label.set_line_wrap(True) - self.top_label.set_justify(gtk.JUSTIFY_LEFT) + self.top_label.set_justify(Gtk.Justification.LEFT) self.top_label.set_property('xalign',0) self.top_label.set_markup('<big>%s</big>'%_('Checking for updates...')) - bottom_label = gtk.Label() + bottom_label = Gtk.Label() bottom_label.set_line_wrap(True) # doesn't really work right =( - bottom_label.set_justify(gtk.JUSTIFY_LEFT) + bottom_label.set_justify(Gtk.Justification.LEFT) bottom_label.set_property('xalign', 0) bottom_label.set_markup(_('Software updates correct errors, eliminate security vulnerabilities, and provide new features.')) - vbox2 = gtk.VBox() - vbox2.pack_start(self.top_label, expand=False) - vbox2.pack_start(gtk.HSeparator(), expand=False) - vbox2.pack_start(bottom_label, expand=True) - self.pack_start(vbox2, expand=False) + vbox2 = Gtk.VBox() + vbox2.pack_start(self.top_label, False, True, 0) + vbox2.pack_start(Gtk.HSeparator(), False, False, 0) + vbox2.pack_start(bottom_label, True, True, 0) + self.pack_start(vbox2, False, True, 0) # activity/group pane #### self.activity_list = model.UpdateList() self.activity_pane = ActivityPane(self) - self.pack_start(self.activity_pane, expand=True) + self.pack_start(self.activity_pane, True, True, 0) # progress pane ########### self.progress_pane = ProgressPane(self) - self.pack_start(self.progress_pane, expand=True, fill=False) + self.pack_start(self.progress_pane, True, False, 0) # special little extension to progress pane. - self.expander = gtk.Expander(label=_('Modify activity groups')) + self.expander = Gtk.Expander(label=_('Modify activity groups')) def expander_cb(expander, param_): if expander.get_expanded(): self.activity_pane.switch() self.activity_pane.expander.set_expanded(True) expander.set_expanded(False) self.expander.connect("notify::expanded", expander_cb) - self.pack_end(self.expander, expand=False) + self.pack_end(self.expander, False, True, 0) # show our work! self.show_all() @@ -545,14 +525,14 @@ class ActivityUpdater(SectionView): def download_cb(self, widget, event, data=None): """Invoked when the 'ok' button is clicked.""" - from sugar.bundle.activitybundle import ActivityBundle + from sugar3.bundle.activitybundle import ActivityBundle self.top_label.set_markup('<big>%s</big>' % _('Downloading updates...')) self.progress_pane.switch_to_download_progress() self._progress_cb(0, _('Starting download...')) self._cancel_func = lambda: self.activity_list.cancel_download() def progress_cb(n, extra=None, icon=None): - gobject.idle_add(self._progress_cb, n, extra, icon) + GObject.idle_add(self._progress_cb, n, extra, icon) @inhibit_suspend def do_download(): # ensure main loop is dbus-registered @@ -587,7 +567,7 @@ class ActivityUpdater(SectionView): os.unlink(f) counts[0]+=1 # refresh when we're done. - gobject.idle_add(self.refresh_cb, None, None, False) + GObject.idle_add(self.refresh_cb, None, None, False) Thread(target=do_download).start() def cancel_cb(self, widget, event, data=None): @@ -607,11 +587,11 @@ class ActivityUpdater(SectionView): # freeze notify queue for activity_list to prevent thread problems. self.activity_list.freeze_notify() def progress_cb(n, extra=None): - gobject.idle_add(self._progress_cb, n, extra) + GObject.idle_add(self._progress_cb, n, extra) @inhibit_suspend def do_refresh(): self.activity_list.refresh(progress_cb, clear_cache=clear_cache) - gobject.idle_add(self._refresh_done_cb) + GObject.idle_add(self._refresh_done_cb) Thread(target=do_refresh).start() return False @@ -655,15 +635,15 @@ class ActivityUpdater(SectionView): return False # destroy me! def destroy(self, widget, data=None): - gtk.main_quit() + Gtk.main_quit() def main(self): """Start gtk main loop.""" - gtk.main() + Gtk.main() def _main(): """Testing code; runs updater standalone.""" - window = gtk.Window(gtk.WINDOW_TOPLEVEL) + window = Gtk.Window(Gtk.WindowType.TOPLEVEL) window.set_title(TITLE) window.set_size_request(425, 400) au = ActivityUpdater(None, None) @@ -673,7 +653,7 @@ def _main(): window.add(au) au.set_border_width(style.DEFAULT_SPACING) # our window is smaller here. window.show() - gtk.main() + Gtk.main() # set PYTHONPATH to /usr/share/sugar/shell before invoking. if __name__ == '__main__': _main () diff --git a/sugar-update-control.spec b/sugar-update-control.spec index 2cae0cf..94aebed 100644 --- a/sugar-update-control.spec +++ b/sugar-update-control.spec @@ -2,14 +2,14 @@ Summary: Activity update control panel for Sugar Name: sugar-update-control -Version: 0.24 -Release: 2%{?dist} +Version: 0.25 +Release: 1%{?dist} License: GPLv2+ Group: System Environment/Base URL: http://git.sugarlabs.org/projects/sugar-update-control Source0: http://download.sugarlabs.org/sources/honey/sugar-update-control/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Requires: sugar >= 0.83.0, bitfrost-sugar +Requires: sugar >= 0.95.0, bitfrost-sugar BuildRequires: gettext BuildRequires: intltool BuildRequires: python-devel |