From 9ea4c3f42b063efdc3ecbff8026f7ddab0e36dec Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Mon, 9 Jul 2012 09:16:59 +0100 Subject: [PATCH] Updated preferences box to support Python 3, PyGObject and GTK 3 Note: the popup menu does not appear yet for some reason. --- zeroinstall/0launch-gui/dialog.py | 3 +- zeroinstall/0launch-gui/main.py | 14 +++++--- zeroinstall/0launch-gui/preferences.py | 30 ++++++++++------- zeroinstall/gtkui/gtk.py | 61 ++++++++++++++++++++++++++++++++++ zeroinstall/gtkui/gtkutils.py | 2 +- zeroinstall/gtkui/help_box.py | 9 ++--- 6 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 zeroinstall/gtkui/gtk.py diff --git a/zeroinstall/0launch-gui/dialog.py b/zeroinstall/0launch-gui/dialog.py index 862b1e6..57f1067 100644 --- a/zeroinstall/0launch-gui/dialog.py +++ b/zeroinstall/0launch-gui/dialog.py @@ -1,9 +1,8 @@ # Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. -import gtk import os -from zeroinstall.gtkui import gtkutils +from zeroinstall.gtkui import gtkutils, gtk last_error = None diff --git a/zeroinstall/0launch-gui/main.py b/zeroinstall/0launch-gui/main.py index 2e1340b..30b35b3 100644 --- a/zeroinstall/0launch-gui/main.py +++ b/zeroinstall/0launch-gui/main.py @@ -63,7 +63,7 @@ def run_gui(args): "\nFor more information about these matters, see the file named COPYING.")) sys.exit(0) - import gtk + from zeroinstall.gtkui import gtk if gtk.gdk.get_display() is None: print("Failed to connect to display. Aborting.", file=sys.stderr) sys.exit(1) @@ -78,10 +78,14 @@ def run_gui(args): config.stores.stores.append(zerostore.Store(os.path.abspath(x))) if len(args) < 1: - import preferences - box = preferences.show_preferences(config) - box.connect('destroy', gtk.main_quit) - gtk.main() + @tasks.async + def prefs_main(): + import preferences + box = preferences.show_preferences(config) + done = tasks.Blocker('close preferences') + box.connect('destroy', lambda w: done.trigger()) + yield done + tasks.wait_for_blocker(prefs_main()) sys.exit(0) interface_uri = args[0] diff --git a/zeroinstall/0launch-gui/preferences.py b/zeroinstall/0launch-gui/preferences.py index 5762cad..218d6c1 100644 --- a/zeroinstall/0launch-gui/preferences.py +++ b/zeroinstall/0launch-gui/preferences.py @@ -1,7 +1,8 @@ # Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. -import gtk +import sys +from zeroinstall.gtkui import gtk from dialog import Template from zeroinstall import _ from zeroinstall.gtkui import help_box @@ -46,8 +47,10 @@ class Preferences: '%d seconds' % config.freshness)) times.append(config.freshness) freshness = widgets.get_widget('freshness') + freshness_model = freshness.get_model() for level in freshness_levels: - freshness.append_text(str(level)) + i = freshness_model.append() + freshness_model.set_value(i, 0, str(level)) freshness.set_active(times.index(config.freshness)) def set_freshness(combo, freshness = freshness): # (pygtk bug?) config.freshness = freshness_levels[freshness.get_active()].time @@ -64,7 +67,7 @@ class Preferences: # Responses self.window.set_default_response(gtk.RESPONSE_CLOSE) - self.window.default_widget.grab_focus() + self.window.get_default_widget().grab_focus() def response(dialog, resp): if resp in (gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT): @@ -90,16 +93,16 @@ class KeyList: def update_keys(): # Remember which ones are open expanded_elements = set() - def add_row(tv, path): + def add_row(tv, path, unused = None): if len(path) == 1: domain = self.trusted_keys[path][0] expanded_elements.add(domain) - tv.map_expanded_rows(add_row) + tv.map_expanded_rows(add_row, None) self.trusted_keys.clear() domains = {} - keys = gpg.load_keys(trust.trust_db.keys.keys()) + keys = gpg.load_keys(list(trust.trust_db.keys.keys())) for fingerprint in keys: for domain in trust.trust_db.keys[fingerprint]: @@ -111,11 +114,11 @@ class KeyList: for key in domains[domain]: self.trusted_keys.append(iter, [key.name, key]) - def may_expand(model, path, iter): - if len(path) == 1: + def may_expand(model, path, iter, unused): + if gtk.path_depth(path) == 1: if model[iter][0] in expanded_elements: tv.expand_row(path, False) - self.trusted_keys.foreach(may_expand) + self.trusted_keys.foreach(may_expand, None) trust.trust_db.watchers.append(update_keys) tv.connect('destroy', lambda w: trust.trust_db.watchers.remove(update_keys)) @@ -132,11 +135,11 @@ class KeyList: if not pos: return False path, col, x, y = pos - if len(path) != 2: + if gtk.path_depth(path) != 2: return False - domain = self.trusted_keys[path[:-1]][0] key = self.trusted_keys[path][1] + domain = self.trusted_keys[gtk.path_parent(path)][0] menu = gtk.Menu() @@ -146,7 +149,10 @@ class KeyList: item.show() menu.append(item) - menu.popup(None, None, None, bev.button, bev.time) + if sys.version_info[0] > 2: + menu.popup(None, None, None, None, bev.button, bev.time) + else: + menu.popup(None, None, None, bev.button, bev.time) return True return False tv.connect('button-press-event', trusted_keys_button_press) diff --git a/zeroinstall/gtkui/gtk.py b/zeroinstall/gtkui/gtk.py new file mode 100644 index 0000000..09a8df1 --- /dev/null +++ b/zeroinstall/gtkui/gtk.py @@ -0,0 +1,61 @@ +"""Compatibility wrapper to make Python 3's GTK look more like Python 2's version. +@since: 1.10 +""" + +# Copyright (C) 2012, Thomas Leonard +# See the README file for details, or visit http://0install.net. + +from __future__ import absolute_import +import sys + +if sys.version_info[0] > 2: + # Python 3 + + from gi.repository import Gdk as gdk + from gi.repository.Gdk import Screen + + from gi.repository.Gtk import MessageType, ResponseType, WindowPosition, PolicyType, ShadowType, WrapMode + from gi.repository.Gtk import Dialog, ScrolledWindow, TextView, TreePath + from gi.repository.Gtk import Builder, Menu + from gi.repository.Gtk import TreeStore, TreeViewColumn, CellRendererText + from gi.repository.Gtk import STOCK_CLOSE + from gi.repository.Gtk import MenuItem as GtkMenuItem + + MESSAGE_ERROR = MessageType.ERROR + + RESPONSE_CANCEL = ResponseType.CANCEL + RESPONSE_CLOSE = ResponseType.CLOSE + RESPONSE_HELP = ResponseType.HELP + RESPONSE_DELETE_EVENT = ResponseType.DELETE_EVENT + + WIN_POS_CENTER = WindowPosition.CENTER + POLICY_AUTOMATIC = PolicyType.AUTOMATIC + POLICY_ALWAYS = PolicyType.ALWAYS + SHADOW_IN = ShadowType.IN + WRAP_WORD = WrapMode.WORD + + gdk.screen_width = Screen.get_default().get_width + gdk.screen_height = Screen.get_default().get_height + + gdk.BUTTON_PRESS = gdk.EventType.BUTTON_PRESS + + def MenuItem(label): + item = GtkMenuItem() + item.set_label(label) + return item + + def path_depth(path): + return path.get_depth() + + def path_parent(path): + parent = path.copy() + parent.up() + return parent +else: + from gtk import * # Python 2 + + def path_depth(path): + return len(path) + + def path_parent(path): + return path[:-1] diff --git a/zeroinstall/gtkui/gtkutils.py b/zeroinstall/gtkui/gtkutils.py index 97af3ad..b3ca171 100644 --- a/zeroinstall/gtkui/gtkutils.py +++ b/zeroinstall/gtkui/gtkutils.py @@ -3,7 +3,7 @@ # Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. -import gtk +from zeroinstall.gtkui import gtk from zeroinstall.support import tasks class Template: diff --git a/zeroinstall/gtkui/help_box.py b/zeroinstall/gtkui/help_box.py index 0d6715c..1c13600 100644 --- a/zeroinstall/gtkui/help_box.py +++ b/zeroinstall/gtkui/help_box.py @@ -2,7 +2,8 @@ # Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. -import gtk +from zeroinstall.gtkui import gtk +import sys class HelpBox: """A dialog for showing longish help texts. @@ -27,16 +28,16 @@ class HelpBox: assert not self.box self.box = box = gtk.Dialog() - self.box.set_has_separator(False) + if sys.version_info[0] < 3: + self.box.set_has_separator(False) self.box.set_position(gtk.WIN_POS_CENTER) box.set_title(self.title) - box.set_has_separator(False) swin = gtk.ScrolledWindow(None, None) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) swin.set_shadow_type(gtk.SHADOW_IN) swin.set_border_width(2) - box.vbox.pack_start(swin, True, True) + box.get_content_area().pack_start(swin, True, True, 0) text = gtk.TextView() text.set_left_margin(4) -- 2.11.4.GIT