From 540e2e460c8155a22b10c1712eec71c9bf25aea9 Mon Sep 17 00:00:00 2001 From: Stefano Karapetsas Date: Mon, 3 Dec 2012 23:48:48 +0100 Subject: invest-applet: port to gobject introspection there is an issue to fix with self.applet.window.get_origin in applet.py --- invest-applet/data/Invest_Applet.server.in.in | 25 --- invest-applet/data/Invest_Applet.xml | 15 +- invest-applet/data/MATE_GtikApplet.server | 18 -- invest-applet/data/Makefile.am | 52 ++--- ...te.applets.InvestApplet.mate-panel-applet.in.in | 17 ++ ...ate.panel.applet.InvestAppletFactory.service.in | 3 + invest-applet/invest/__init__.py | 63 +++--- invest-applet/invest/about.py | 13 +- invest-applet/invest/applet.py | 100 +++++---- invest-applet/invest/chart.py | 34 +-- invest-applet/invest/defs.py.in | 1 + invest-applet/invest/help.py | 10 +- invest-applet/invest/invest-applet.py | 31 +-- invest-applet/invest/mate-invest-chart | 10 +- invest-applet/invest/preferences.py | 40 ++-- invest-applet/invest/quotes.py | 47 +++-- invest-applet/invest/widgets.py | 67 +++--- invest-applet/pygi-mate-convert.sh | 234 +++++++++++++++++++++ 18 files changed, 514 insertions(+), 266 deletions(-) delete mode 100644 invest-applet/data/Invest_Applet.server.in.in delete mode 100644 invest-applet/data/MATE_GtikApplet.server create mode 100644 invest-applet/data/org.mate.applets.InvestApplet.mate-panel-applet.in.in create mode 100644 invest-applet/data/org.mate.panel.applet.InvestAppletFactory.service.in create mode 100755 invest-applet/pygi-mate-convert.sh (limited to 'invest-applet') diff --git a/invest-applet/data/Invest_Applet.server.in.in b/invest-applet/data/Invest_Applet.server.in.in deleted file mode 100644 index fe4c6da5..00000000 --- a/invest-applet/data/Invest_Applet.server.in.in +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/invest-applet/data/Invest_Applet.xml b/invest-applet/data/Invest_Applet.xml index 832f6b83..d4a3e611 100644 --- a/invest-applet/data/Invest_Applet.xml +++ b/invest-applet/data/Invest_Applet.xml @@ -1,10 +1,5 @@ - - - - - - - - - - + + + + + diff --git a/invest-applet/data/MATE_GtikApplet.server b/invest-applet/data/MATE_GtikApplet.server deleted file mode 100644 index 73f0717b..00000000 --- a/invest-applet/data/MATE_GtikApplet.server +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/invest-applet/data/Makefile.am b/invest-applet/data/Makefile.am index e304109a..333040df 100644 --- a/invest-applet/data/Makefile.am +++ b/invest-applet/data/Makefile.am @@ -1,26 +1,38 @@ SUBDIRS = art # ****************************************************************************** -# Panel applet matecomponent stuff +# Panel applet DBUS stuff # ****************************************************************************** -serverdir = $(libdir)/matecomponent/servers -server_in_files = Invest_Applet.server.in -server_DATA = \ - $(server_in_files:.server.in=.server) \ - MATE_GtikApplet.server +servicedir = $(datadir)/dbus-1/services +service_in_files = org.mate.panel.applet.InvestAppletFactory.service.in +service_DATA = $(service_in_files:.service.in=.service) + +org.mate.panel.applet.InvestAppletFactory.service: $(service_in_files) + $(AM_V_GEN)sed \ + -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \ + $< > $@ # ****************************************************************************** -# MateConf Schemas +# Panel stuff # ****************************************************************************** -# MateConf Preference Schemas -#schemadir = $(MATECONF_SCHEMA_FILE_DIR) -#schema_in_files = deskbar-applet.schemas.in -#schema_DATA = $(schema_in_files:.schemas.in=.schemas) + +appletdir = $(datadir)/mate-panel/applets +applet_in_files = org.mate.applets.InvestApplet.mate-panel-applet.in +applet_DATA = $(applet_in_files:.mate-panel-applet.in=.mate-panel-applet) + +$(applet_in_files): $(applet_in_files).in Makefile + $(AM_V_GEN)sed \ + -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \ + -e "s|\@VERSION\@|$(PACKAGE_VERSION)|" \ + $< > $@ + +%.mate-panel-applet: %.mate-panel-applet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache # ****************************************************************************** # Misc data # ****************************************************************************** -uidir = $(datadir)/mate-2.0/ui + +uidir = $(datadir)/mate-applets ui_DATA = \ Invest_Applet.xml builder_DATA = \ @@ -32,26 +44,14 @@ investbindir = $(libdir)/invest-applet # ****************************************************************************** # Build rules # ****************************************************************************** -@INTLTOOL_SERVER_RULE@ -@INTLTOOL_SCHEMAS_RULE@ - -$(server_in_files): $(server_in_files:.server.in=.server.in.in) - sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@ - -#if MATECONF_SCHEMAS_INSTALL -#install-data-local: install-schemas -#install-schemas: -# MATECONF_CONFIG_SOURCE=$(MATECONF_SCHEMA_CONFIG_SOURCE) \ -# $(MATECONFTOOL) --makefile-install-rule $(schema_DATA) -#endif DISTCLEANFILES = \ $(server_in_files) \ $(server_in_files:.server.in=.server) EXTRA_DIST = \ - Invest_Applet.server.in.in \ - MATE_GtikApplet.server \ + org.mate.applets.InvestApplet.mate-panel-applet.in.in \ + $(service_in_files) \ $(ui_DATA) \ $(builder_DATA) diff --git a/invest-applet/data/org.mate.applets.InvestApplet.mate-panel-applet.in.in b/invest-applet/data/org.mate.applets.InvestApplet.mate-panel-applet.in.in new file mode 100644 index 00000000..00a83afb --- /dev/null +++ b/invest-applet/data/org.mate.applets.InvestApplet.mate-panel-applet.in.in @@ -0,0 +1,17 @@ +[Applet Factory] +Id=InvestAppletFactory +Location=@LIBEXECDIR@/invest-applet +_Name=Invest Applet Factory +_Description=Factory for creating the invest applet. + +[InvestApplet] +_Name=Invest +_Description=Track your invested money. +Icon=invest-applet +BonoboId=OAFIID:Invest_Applet_Factory +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=mate-applets +X-MATE-Bugzilla-Component=invest +X-MATE-Bugzilla-Version=@VERSION@ +X-MATE-Bugzilla-OtherBinaries=invest-applet + diff --git a/invest-applet/data/org.mate.panel.applet.InvestAppletFactory.service.in b/invest-applet/data/org.mate.panel.applet.InvestAppletFactory.service.in new file mode 100644 index 00000000..353c578a --- /dev/null +++ b/invest-applet/data/org.mate.panel.applet.InvestAppletFactory.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.mate.panel.applet.InvestAppletFactory +Exec=@LIBEXECDIR@/invest-applet diff --git a/invest-applet/invest/__init__.py b/invest-applet/invest/__init__.py index 101881f5..beb299c1 100644 --- a/invest-applet/invest/__init__.py +++ b/invest-applet/invest/__init__.py @@ -3,7 +3,13 @@ from os.path import join, exists, isdir, isfile, dirname, abspath, expanduser from types import ListType import datetime -import gtk, gtk.gdk, mateconf, gobject +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +from gi.repository import Gio + import cPickle import networkmanager @@ -54,19 +60,6 @@ if not exists(USER_INVEST_DIR): # when presenting save/open dialogs os.chdir(expanduser("~")) -#Gconf client -MATECONF_CLIENT = mateconf.client_get_default() - -# MateConf directory for invest in window mode and shared settings -MATECONF_DIR = "/apps/invest" - -# MateConf key for list of enabled handlers, when uninstalled, use a debug key to not conflict -# with development version -#MATECONF_ENABLED_HANDLERS = MATECONF_DIR + "/enabled_handlers" - -# Preload mateconf directories -#MATECONF_CLIENT.add_dir(MATECONF_DIR, mateconf.CLIENT_PRELOAD_RECURSIVE) - # tests whether the given stocks are in the old labelless format def labelless_stock_format(stocks): if len(stocks) == 0: @@ -161,32 +154,30 @@ PROXY = None # borrowed from Ross Burton # http://burtonini.com/blog/computers/postr # extended by exception handling and retry scheduling -def get_mate_proxy(client): - sleep = 10 # sleep between attempts for 10 seconds - attempts = 3 # try to get configuration from mateconf at most three times - get_mate_proxy_retry(client, attempts, sleep) - -def get_mate_proxy_retry(client, attempts, sleep): - # decrease attempts counter - attempts -= 1 +def get_gnome_proxy(): # sanity check if we still need to look for proxy configuration global PROXY if PROXY != None: return - # try to get config from mateconfd + # try to get config from gsettings try: - if client.get_bool("/system/http_proxy/use_http_proxy"): - host = client.get_string("/system/http_proxy/host") - port = client.get_int("/system/http_proxy/port") + proxy_settings = Gio.Settings.new("org.gnome.system.proxy") + proxy_http_settings = Gio.Settings.new("org.gnome.system.proxy.http") + + proxy_mode = proxy_settings.get_enum("mode") + + if proxy_mode == 1: + host = proxy_http_settings.get_string("host") + port = proxy_http_settings.get_int("port") if host is None or host == "" or port == 0: - # mate proxy is not valid, stop here + # system proxy is not valid, stop here return - if client.get_bool("/system/http_proxy/use_authentication"): - user = client.get_string("/system/http_proxy/authentication_user") - password = client.get_string("/system/http_proxy/authentication_password") + if proxy_http_settings.get_boolean("use-authentication"): + user = proxy_http_settings.get_string("authentication-user") + password = proxy_http_settings.get_string("authentication-password") if user and user != "": url = "http://%s:%s@%s:%d" % (user, password, host, port) else: @@ -198,15 +189,9 @@ def get_mate_proxy_retry(client, attempts, sleep): PROXY = {'http': url} except Exception, msg: - error("Failed to get proxy configuration from MateConfd:\n%s" % msg) - # we did not succeed, schedule retry - if attempts > 0: - error("Retrying to contact MateConfd in %d seconds" % sleep) - gobject.timeout_add(sleep * 1000, get_mate_proxy_retry, client, attempts, sleep) - -# use mateconf to get proxy config -client = mateconf.client_get_default() -get_mate_proxy(client) + error("Failed to get proxy configuration from GSettings:\n%s" % msg) + +get_gnome_proxy() # connect to Network Manager to identify current network connectivity diff --git a/invest-applet/invest/about.py b/invest-applet/invest/about.py index 2b7293f4..9599c687 100644 --- a/invest-applet/invest/about.py +++ b/invest-applet/invest/about.py @@ -3,16 +3,21 @@ from os.path import join from gettext import gettext as _ from mate_invest.defs import VERSION import mate_invest -import gtk, gtk.gdk + +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GdkPixbuf invest_logo = None try: - invest_logo = gtk.gdk.pixbuf_new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest_neutral.svg"), 96, 96) + invest_logo = GdkPixbuf.Pixbuf.new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest_neutral.svg"), 96, 96) except Exception, msg: pass def show_about(): - about = gtk.AboutDialog() + about = Gtk.AboutDialog() infos = { "program-name" : _("Invest"), "logo" : invest_logo, @@ -21,7 +26,7 @@ def show_about(): "copyright" : "Copyright © 2004-2005 Raphael Slinckx.\nCopyright © 2009-2010 Enrico Minack." } - about.set_authors(["Raphael Slinckx ", "Enrico Minack "]) +# about.set_authors("Raphael Slinckx \nEnrico Minack ") # about.set_artists([]) # about.set_documenters([]) diff --git a/invest-applet/invest/applet.py b/invest-applet/invest/applet.py index 8b134e67..1a7cbc90 100644 --- a/invest-applet/invest/applet.py +++ b/invest-applet/invest/applet.py @@ -1,34 +1,46 @@ import os, time from os.path import * -import mateapplet, gtk, gtk.gdk, mateconf, gobject -gobject.threads_init() + +import gi +gi.require_version("Gtk", "2.0") + +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GdkPixbuf +from gi.repository import GObject +from gi.repository import MatePanelApplet + +GObject.threads_init() from gettext import gettext as _ -import mateconf import mate_invest, mate_invest.about, mate_invest.chart, mate_invest.preferences, mate_invest.defs from mate_invest.quotes import QuoteUpdater from mate_invest.widgets import * -gtk.window_set_default_icon_from_file(join(mate_invest.ART_DATA_DIR, "invest_neutral.svg")) +Gtk.Window.set_default_icon_from_file(join(mate_invest.ART_DATA_DIR, "invest_neutral.svg")) -class InvestApplet: +class InvestApplet(MatePanelApplet.Applet): def __init__(self, applet): self.applet = applet - self.applet.setup_menu_from_file ( - None, "Invest_Applet.xml", - None, [("About", self.on_about), - ("Help", self.on_help), - ("Prefs", self.on_preferences), - ("Refresh", self.on_refresh) - ]) - - evbox = gtk.HBox() - self.applet_icon = gtk.Image() + + # name, stock_id, label, accellerator, tooltip, callback + menu_actions = [("About", Gtk.STOCK_HELP, _("About"), None, None, self.on_about), + ("Help", Gtk.STOCK_HELP, _("Help"), None, None, self.on_help), + ("Prefs", Gtk.STOCK_PREFERENCES, _("Preferences"), None, None, self.on_preferences), + ("Refresh", Gtk.STOCK_REFRESH, _("Refresh"), None, None, self.on_refresh) + ] + actiongroup = Gtk.ActionGroup.new("InvestAppletActions") + actiongroup.set_translation_domain(mate_invest.defs.GETTEXT_PACKAGE) + actiongroup.add_actions(menu_actions, None) + self.applet.setup_menu_from_file (join(mate_invest.defs.PKGDATADIR, "Invest_Applet.xml"), actiongroup) + + evbox = Gtk.HBox() + self.applet_icon = Gtk.Image() self.set_applet_icon(0) self.applet_icon.show() evbox.add(self.applet_icon) self.applet.add(evbox) - self.applet.connect("button-press-event",self.button_clicked) + self.applet.connect("button-press-event", self.button_clicked) self.applet.show_all() self.new_ilw() @@ -43,7 +55,7 @@ class InvestApplet: self.new_ilw() def button_clicked(self, widget,event): - if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1: + if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 1: # Three cases... if len (mate_invest.STOCKS) == 0: # a) We aren't configured yet @@ -51,7 +63,7 @@ class InvestApplet: self.reload_ilw() elif not self.quotes_updater.quotes_valid: # b) We can't get the data (e.g. offline) - alert = gtk.MessageDialog(buttons=gtk.BUTTONS_CLOSE) + alert = Gtk.MessageDialog(buttons=Gtk.ButtonsType.CLOSE) alert.set_markup(_("No stock quotes are currently available")) alert.format_secondary_text(_("The server could not be contacted. The computer is either offline or the servers are down. Try again later.")) alert.run() @@ -60,35 +72,35 @@ class InvestApplet: # c) Everything is normal: pop-up the window self.ilw.toggle_show() - def on_about(self, component, verb): + def on_about(self, action): mate_invest.about.show_about() - def on_help(self, component, verb): + def on_help(self, action): mate_invest.help.show_help() - def on_preferences(self, component, verb): + def on_preferences(self, action): mate_invest.preferences.show_preferences(self) self.reload_ilw() - def on_refresh(self, component, verb): + def on_refresh(self, action): self.quotes_updater.refresh() def set_applet_icon(self, change): if change == 1: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest-22_up.png"), -1,-1) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest-22_up.png"), -1,-1) elif change == 0: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest-22_neutral.png"), -1,-1) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest-22_neutral.png"), -1,-1) else: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest-22_down.png"), -1,-1) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest-22_down.png"), -1,-1) self.applet_icon.set_from_pixbuf(pixbuf) def set_applet_tooltip(self, text): self.applet_icon.set_tooltip_text(text) -class InvestmentsListWindow(gtk.Window): +class InvestmentsListWindow(Gtk.Window): def __init__(self, applet, list): - gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) - self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK) + Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL) + self.set_type_hint(Gdk.WindowTypeHint.DOCK) self.stick() self.set_resizable(False) self.set_border_width(6) @@ -106,7 +118,7 @@ class InvestmentsListWindow(gtk.Window): def toggle_show(self): if self.hidden == True: self.update_position() - self.show() + self.show_all() self.hidden = False elif self.hidden == False: self.hide() @@ -120,15 +132,19 @@ class InvestmentsListWindow(gtk.Window): # Get our own dimensions & position #(wx, wy) = self.get_origin() - (ax, ay) = self.applet.window.get_origin() + ax=0 + ay=0 + #FIXME this doesnt work with gir + self.applet.window.get_origin(ax, ay) (ww, wh) = self.get_size () (aw, ah) = self.applet.window.get_size () - screen = self.applet.window.get_screen() - monitor = screen.get_monitor_geometry (screen.get_monitor_at_window (self.applet.window)) + screen = self.applet.get_screen() + monitor = Gdk.Rectangle(0, 0, 0, 0) + screen.get_monitor_geometry (screen.get_monitor_at_window (self.applet.window), monitor) - if self.alignment == mateapplet.ORIENT_LEFT: + if self.alignment == MatePanelApplet.AppletOrient.LEFT: x = ax - ww y = ay @@ -139,11 +155,11 @@ class InvestmentsListWindow(gtk.Window): y = 0 if (y + wh > monitor.height / 2): - gravity = gtk.gdk.GRAVITY_SOUTH_WEST + gravity = Gdk.Gravity.SOUTH_WEST else: - gravity = gtk.gdk.GRAVITY_NORTH_WEST + gravity = Gdk.Gravity.NORTH_WEST - elif self.alignment == mateapplet.ORIENT_RIGHT: + elif self.alignment == MatePanelApplet.AppletOrient.RIGHT: x = ax + aw y = ay @@ -154,11 +170,11 @@ class InvestmentsListWindow(gtk.Window): y = 0 if (y + wh > monitor.height / 2): - gravity = gtk.gdk.GRAVITY_SOUTH_EAST + gravity = Gdk.Gravity.SOUTH_EAST else: - gravity = gtk.gdk.GRAVITY_NORTH_EAST + gravity = Gdk.Gravity.NORTH_EAST - elif self.alignment == mateapplet.ORIENT_DOWN: + elif self.alignment == MatePanelApplet.AppletOrient.DOWN: x = ax y = ay + ah @@ -168,8 +184,8 @@ class InvestmentsListWindow(gtk.Window): if (x < 0): x = 0 - gravity = gtk.gdk.GRAVITY_NORTH_WEST - elif self.alignment == mateapplet.ORIENT_UP: + gravity = Gdk.Gravity.NORTH_WEST + elif self.alignment == MatePanelApplet.AppletOrient.UP: x = ax y = ay - wh @@ -179,7 +195,7 @@ class InvestmentsListWindow(gtk.Window): if (x < 0): x = 0 - gravity = gtk.gdk.GRAVITY_SOUTH_WEST + gravity = Gdk.Gravity.SOUTH_WEST self.move(x, y) self.set_gravity(gravity) diff --git a/invest-applet/invest/chart.py b/invest-applet/invest/chart.py index 358c51df..e13e0686 100644 --- a/invest-applet/invest/chart.py +++ b/invest-applet/invest/chart.py @@ -1,7 +1,11 @@ #!/usr/bin/env python -import gtk, gtk.gdk -import gobject +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GdkPixbuf +from gi.repository import GObject import os import mate_invest from gettext import gettext as _ @@ -15,16 +19,16 @@ import time AUTOREFRESH_TIMEOUT = 20*60*1000 # 15 minutes # based on http://www.johnstowers.co.nz/blog/index.php/2007/03/12/threading-and-pygtk/ -class _IdleObject(gobject.GObject): +class _IdleObject(GObject.GObject): """ - Override gobject.GObject to always emit signals in the main thread + Override GObject.GObject to always emit signals in the main thread by emmitting on an idle handler """ def __init__(self): - gobject.GObject.__init__(self) + GObject.GObject.__init__(self) def emit(self, *args): - gobject.idle_add(gobject.GObject.emit,self,*args) + GObject.idle_add(GObject.GObject.emit,self,*args) class ImageRetriever(Thread, _IdleObject): """ @@ -33,11 +37,11 @@ class ImageRetriever(Thread, _IdleObject): """ __gsignals__ = { "completed": ( - gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []), + GObject.SignalFlags.RUN_LAST, None, []), # FIXME: should we be making use of this? #"progress": ( - # gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [ - # gobject.TYPE_FLOAT]) #percent complete + # GObject.SignalFlags.RUN_LAST, None, [ + # GObject.TYPE_FLOAT]) #percent complete } def __init__(self, image_url): @@ -47,12 +51,12 @@ class ImageRetriever(Thread, _IdleObject): self.retrieved = False def run(self): - self.image = gtk.Image() + self.image = Gtk.Image() try: sock = urllib.urlopen(self.image_url, proxies = mate_invest.PROXY) except Exception, msg: mate_invest.debug("Error while opening %s: %s" % (self.image_url, msg)) else: - loader = gtk.gdk.PixbufLoader() + loader = GdkPixbuf.PixbufLoader() loader.connect("closed", lambda loader: self.image.set_from_pixbuf(loader.get_pixbuf())) loader.write(sock.read()) sock.close() @@ -107,7 +111,7 @@ class FinancialChart: win.set_title(_("Financial Chart")) try: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest_neutral.svg"), 96,96) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(mate_invest.ART_DATA_DIR, "invest_neutral.svg"), 96,96) self.ui.get_object("plot").set_from_pixbuf(pixbuf) except Exception, msg: mate_invest.debug("Could not load 'invest-neutral.svg' file: %s" % msg) @@ -241,14 +245,14 @@ class FinancialChart: def on_autorefresh_toggled(self, autorefresh): if self.autorefresh_id != 0: - gobject.source_remove(self.autorefresh_id) + GObject.source_remove(self.autorefresh_id) self.autorefresh_id = 0 if autorefresh.get_active(): - self.autorefresh_id = gobject.timeout_add(AUTOREFRESH_TIMEOUT, self.on_refresh_chart, True) + self.autorefresh_id = GObject.timeout_add(AUTOREFRESH_TIMEOUT, self.on_refresh_chart, True) def show_chart(tickers): - ui = gtk.Builder(); + ui = Gtk.Builder(); ui.add_from_file(os.path.join(mate_invest.BUILDER_DATA_DIR, "financialchart.ui")) chart = FinancialChart(ui) ui.get_object("s").set_text(' '.join(tickers)) diff --git a/invest-applet/invest/defs.py.in b/invest-applet/invest/defs.py.in index 769e957c..3985ea38 100644 --- a/invest-applet/invest/defs.py.in +++ b/invest-applet/invest/defs.py.in @@ -7,3 +7,4 @@ GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@" MATELOCALEDIR = "@MATELOCALEDIR@" BUILDERDIR = "@BUILDERDIR@" NETWORKMANAGER_VERSION = "@NETWORKMANAGER_VERSION@" +PKGDATADIR = "@PKGDATADIR@" diff --git a/invest-applet/invest/help.py b/invest-applet/invest/help.py index 7dfaabf0..a283a230 100644 --- a/invest-applet/invest/help.py +++ b/invest-applet/invest/help.py @@ -1,8 +1,12 @@ # -*- coding: utf-8 -*- -import gtk, gtk.gdk + +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk +from gi.repository import Gdk def show_help(): - gtk.show_uri(None, "ghelp:invest-applet", gtk.gdk.CURRENT_TIME) + Gtk.show_uri(None, "ghelp:invest-applet", Gdk.CURRENT_TIME) def show_help_section(id): - gtk.show_uri(None, "ghelp:invest-applet?%s" % id, gtk.gdk.CURRENT_TIME) + Gtk.show_uri(None, "ghelp:invest-applet?%s" % id, Gdk.CURRENT_TIME) diff --git a/invest-applet/invest/invest-applet.py b/invest-applet/invest/invest-applet.py index 92a2b960..4fa883fc 100755 --- a/invest-applet/invest/invest-applet.py +++ b/invest-applet/invest/invest-applet.py @@ -1,8 +1,11 @@ #!/usr/bin/env python # -import gobject -import gtk, mateapplet +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk +from gi.repository import GObject +from gi.repository import MatePanelApplet import getopt, sys from os.path import * @@ -30,20 +33,20 @@ locale.textdomain(mate_invest.defs.GETTEXT_PACKAGE) from gettext import gettext as _ -def applet_factory(applet, iid): +def applet_factory(applet, iid, data): mate_invest.debug('Starting invest instance: %s %s'% ( applet, iid )) mate_invest.applet.InvestApplet(applet) return True # Return a standalone window that holds the applet def build_window(): - app = gtk.Window(gtk.WINDOW_TOPLEVEL) + app = Gtk.Window(Gtk.WindowType.TOPLEVEL) app.set_title(_("Invest Applet")) - app.connect("destroy", gtk.main_quit) + app.connect("destroy", Gtk.main_quit) app.set_property('resizable', False) - applet = mateapplet.Applet() - applet_factory(applet, None) + applet = MatePanelApplet.Applet() + applet_factory(applet, None, None) applet.reparent(app) app.show_all() @@ -88,11 +91,11 @@ if __name__ == "__main__": if standalone: build_window() - gtk.main() + Gtk.main() else: - mateapplet.matecomponent_factory( - "OAFIID:Invest_Applet_Factory", - mateapplet.Applet.__gtype__, - mate_invest.defs.PACKAGE, - mate_invest.defs.VERSION, - applet_factory) + MatePanelApplet.Applet.factory_main( + "InvestAppletFactory", + True, + MatePanelApplet.Applet.__gtype__, + applet_factory, + None) diff --git a/invest-applet/invest/mate-invest-chart b/invest-applet/invest/mate-invest-chart index ea025de8..5c8ed9d3 100755 --- a/invest-applet/invest/mate-invest-chart +++ b/invest-applet/invest/mate-invest-chart @@ -1,6 +1,10 @@ #!/usr/bin/env python -import sys, mate_invest.chart, gtk +import sys, mate_invest.chart + +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk # Prepare i18n import gettext, locale @@ -11,5 +15,5 @@ locale.textdomain(mate_invest.defs.GETTEXT_PACKAGE) if __name__ == "__main__": win = mate_invest.chart.show_chart(sys.argv[1:]) - win.connect("destroy", lambda x: gtk.main_quit()) - gtk.main() + win.connect("destroy", lambda x: Gtk.main_quit()) + Gtk.main() diff --git a/invest-applet/invest/preferences.py b/invest-applet/invest/preferences.py index 03a9147f..f531a51e 100644 --- a/invest-applet/invest/preferences.py +++ b/invest-applet/invest/preferences.py @@ -1,14 +1,17 @@ from gettext import gettext as _ import locale from os.path import join -import gtk, gobject, mateconf +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk +from gi.repository import GObject import mate_invest import currencies import cPickle class PrefsDialog: def __init__(self, applet): - self.ui = gtk.Builder() + self.ui = Gtk.Builder() self.ui.add_from_file(join(mate_invest.BUILDER_DATA_DIR, "prefs-dialog.ui")) self.dialog = self.ui.get_object("preferences") @@ -29,14 +32,14 @@ class PrefsDialog: self.typs = (str, str, float, float, float, float) self.names = (_("Symbol"), _("Label"), _("Amount"), _("Price"), _("Commission"), _("Currency Rate")) - store = gtk.ListStore(*self.typs) - store.set_sort_column_id(0, gtk.SORT_ASCENDING) + store = Gtk.ListStore(*self.typs) + store.set_sort_column_id(0, Gtk.SortType.ASCENDING) self.treeview.set_model(store) self.model = store - completion = gtk.EntryCompletion() + completion = Gtk.EntryCompletion() self.currency.set_completion(completion) - liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) + liststore = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) completion.set_model(liststore) completion.set_text_column(0) for code, label in self.currencies.items(): @@ -66,7 +69,7 @@ class PrefsDialog: exchange = purchase["exchange"] else: exchange = 0.0 - store.append([key, label, purchase["amount"], purchase["bought"], purchase["comission"], exchange]) + store.append([key, label, float(purchase["amount"]), float(purchase["bought"]), float(purchase["comission"]), float(exchange)]) self.sync_ui() @@ -88,16 +91,16 @@ class PrefsDialog: def get_cell_data(self, column, cell, model, iter, data): typ, col = data + val = model[iter][col] if typ == int: - cell.set_property('text', "%d" % typ(model[iter][col])) + cell.set_property('text', "%d" % typ(val)) elif typ == float: # provide float numbers with at least 2 fractional digits - val = model[iter][col] digits = self.fraction_digits(val) fmt = "%%.%df" % max(digits, 2) cell.set_property('text', self.format(fmt, val)) else: - cell.set_property('text', typ(model[iter][col])) + cell.set_property('text', typ(val)) # determine the number of non zero digits in the fraction of the value def fraction_digits(self, value): @@ -107,17 +110,16 @@ class PrefsDialog: return len(text) - text.find(".") - 1 def create_cell (self, view, column, name, typ): - cell_description = gtk.CellRendererText () + cell_description = Gtk.CellRendererText () if typ == float: cell_description.set_property("xalign", 1.0) cell_description.set_property("editable", True) cell_description.connect("edited", self.on_cell_edited, column, typ) - column_description = gtk.TreeViewColumn (name, cell_description) + column_description = Gtk.TreeViewColumn (name, cell_description) if typ == str: - column_description.set_attributes (cell_description, text=column) + #column_description.add_attribute (cell_description, column, 0) column_description.set_sort_column_id(column) - if typ == float: - column_description.set_cell_data_func(cell_description, self.get_cell_data, (float, column)) + column_description.set_cell_data_func(cell_description, self.get_cell_data, (typ, column)) view.append_column(column_description) def add_exchange_column(self): @@ -140,7 +142,7 @@ class PrefsDialog: mate_invest.STOCKS = {} - def save_symbol(model, path, iter): + def save_symbol(model, path, iter, data): #if int(model[iter][1]) == 0 or float(model[iter][2]) < 0.0001: # return @@ -153,7 +155,7 @@ class PrefsDialog: "comission": float(model[iter][4]), "exchange": float(model[iter][5]) }) - self.model.foreach(save_symbol) + self.model.foreach(save_symbol, None) try: cPickle.dump(mate_invest.STOCKS, file(mate_invest.STOCKS_FILE, 'w')) mate_invest.debug('Stocks written to file') @@ -164,7 +166,7 @@ class PrefsDialog: if self.currency_code != None and len(self.currency_code) == 3: mate_invest.CONFIG['currency'] = self.currency_code try: - cPickle.dump(invest.CONFIG, file(mate_invest.CONFIG_FILE, 'w')) + cPickle.dump(mate_invest.CONFIG, file(mate_invest.CONFIG_FILE, 'w')) mate_invest.debug('Configuration written to file') except Exception, msg: mate_invest.debug('Could not save configuration file: %s' % msg) @@ -173,7 +175,7 @@ class PrefsDialog: pass def on_add_stock(self, w): - iter = self.model.append(["GOOG", "Google Inc.", 0, 0, 0, 0]) + iter = self.model.append(["GOOG", "Google Inc.", 0.0, 0.0, 0.0, 0.0]) path = self.model.get_path(iter) self.treeview.set_cursor(path, self.treeview.get_column(0), True) diff --git a/invest-applet/invest/quotes.py b/invest-applet/invest/quotes.py index 9f916eb1..44943b1d 100644 --- a/invest-applet/invest/quotes.py +++ b/invest-applet/invest/quotes.py @@ -1,5 +1,10 @@ from os.path import join -import mateapplet, gtk, gtk.gdk, mateconf, gobject +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GdkPixbuf +from gi.repository import GObject from gettext import gettext as _ import csv import locale @@ -19,16 +24,16 @@ QUOTES_URL="http://finance.yahoo.com/d/quotes.csv?s=%(s)s&f=snc4l1d1t1c1ohgv&e=. QUOTES_CSV_FIELDS=["ticker", "label", "currency", ("trade", float), "date", "time", ("variation", float), ("open", float), ("high", float), ("low", float), ("volume", int)] # based on http://www.johnstowers.co.nz/blog/index.php/2007/03/12/threading-and-pygtk/ -class _IdleObject(gobject.GObject): +class _IdleObject(GObject.GObject): """ - Override gobject.GObject to always emit signals in the main thread + Override GObject.GObject to always emit signals in the main thread by emmitting on an idle handler """ def __init__(self): - gobject.GObject.__init__(self) + GObject.GObject.__init__(self) def emit(self, *args): - gobject.idle_add(gobject.GObject.emit,self,*args) + GObject.idle_add(GObject.GObject.emit,self,*args) class QuotesRetriever(Thread, _IdleObject): """ @@ -37,11 +42,11 @@ class QuotesRetriever(Thread, _IdleObject): """ __gsignals__ = { "completed": ( - gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []), + GObject.SignalFlags.RUN_LAST, None, []), # FIXME: We don't monitor progress, yet ... #"progress": ( - # gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [ - # gobject.TYPE_FLOAT]) #percent complete + # GObject.SignalFlags.RUN_LAST, None, [ + # GObject.TYPE_FLOAT]) #percent complete } def __init__(self, tickers): @@ -65,18 +70,18 @@ class QuotesRetriever(Thread, _IdleObject): self.emit("completed") -class QuoteUpdater(gtk.ListStore): +class QuoteUpdater(Gtk.ListStore): updated = False last_updated = None quotes_valid = False timeout_id = None SYMBOL, LABEL, CURRENCY, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION_PCT, PB = range(9) def __init__ (self, change_icon_callback, set_tooltip_callback): - gtk.ListStore.__init__ (self, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, bool, float, float, float, float, gtk.gdk.Pixbuf) + Gtk.ListStore.__init__ (self, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, bool, float, float, float, float, GdkPixbuf.Pixbuf) self.set_update_interval(AUTOREFRESH_TIMEOUT) self.change_icon_callback = change_icon_callback self.set_tooltip_callback = set_tooltip_callback - self.set_sort_column_id(1, gtk.SORT_ASCENDING) + self.set_sort_column_id(1, Gtk.SortType.ASCENDING) self.refresh() # tell the network manager to notify me when network status changes @@ -85,11 +90,11 @@ class QuoteUpdater(gtk.ListStore): def set_update_interval(self, interval): if self.timeout_id != None: mate_invest.debug("Canceling refresh timer") - gobject.source_remove(self.timeout_id) + GObject.source_remove(self.timeout_id) self.timeout_id = None if interval > 0: mate_invest.debug("Setting refresh timer to %s:%02d.%03d" % ( interval / 60000, interval % 60000 / 1000, interval % 1000) ) - self.timeout_id = gobject.timeout_add(interval, self.refresh) + self.timeout_id = GObject.timeout_add(interval, self.refresh) def nm_state_changed(self): # when nm is online but we do not have an update timer, create it and refresh @@ -275,10 +280,10 @@ class QuoteUpdater(gtk.ListStore): break if is_simple_quote: - row = self.insert(0, [ticker, label, val["currency"], True, 0, 0, val["trade"], val["variation_pct"], pb]) + row = self.insert(0, [ticker, label, val["currency"], True, 0.0, 0.0, val["trade"], val["variation_pct"], pb]) else: (balance, change) = self.balance(mate_invest.STOCKS[ticker]["purchases"], val["trade"]) - row = self.insert(0, [ticker, label, val["currency"], False, balance, change, val["trade"], val["variation_pct"], pb]) + row = self.insert(0, [ticker, label, val["currency"], False, float(balance), float(change), val["trade"], val["variation_pct"], pb]) self.add_balance_change(balance, change, val["currency"]) if len(ticker.split('.')) == 2: @@ -364,15 +369,15 @@ class QuoteUpdater(gtk.ListStore): ticker = self.get_value(iter, self.SYMBOL) value = self.get_value(iter, self.VALUE) (balance, change) = self.balance(mate_invest.STOCKS[ticker]["purchases"], value, rates[currency]) - self.set(iter, self.BALANCE, balance) - self.set(iter, self.BALANCE_PCT, change) + self.set_value(iter, self.BALANCE, balance) + self.set_value(iter, self.BALANCE_PCT, change) self.add_balance_change(balance, change, target_currency) # now, convert the value value = self.get_value(iter, self.VALUE) value *= rates[currency] - self.set(iter, self.VALUE, value) - self.set(iter, self.CURRENCY, target_currency) + self.set_value(iter, self.VALUE, value) + self.set_value(iter, self.CURRENCY, target_currency) else: # consider non-converted stocks here @@ -406,5 +411,5 @@ class QuoteUpdater(gtk.ListStore): break return res -if gtk.pygtk_version < (2,8,0): - gobject.type_register(QuoteUpdater) +#if Gtk.pygtk_version < (2,8,0): +# GObject.type_register(QuoteUpdater) diff --git a/invest-applet/invest/widgets.py b/invest-applet/invest/widgets.py index 0a897e30..d7ff9228 100644 --- a/invest-applet/invest/widgets.py +++ b/invest-applet/invest/widgets.py @@ -1,6 +1,13 @@ import os, time from os.path import * -import mateapplet, gtk, gtk.gdk, mateconf, gobject, pango + +import gi +gi.require_version("Gtk", "2.0") +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +from gi.repository import Pango + from gettext import gettext as _ import locale import csv @@ -35,12 +42,12 @@ MEDIUM = -1 TICKER_TIMEOUT = 10000#3*60*1000# -class InvestWidget(gtk.TreeView): +class InvestWidget(Gtk.TreeView): def __init__(self, quotes_updater): - gtk.TreeView.__init__(self) + Gtk.TreeView.__init__(self) self.set_property("rules-hint", True) - self.set_reorderable(True) - self.set_hover_selection(True) +# self.set_property("reorderable", True) + self.set_property("hover-selection", True) simple_quotes_only = quotes_updater.simple_quotes_only() @@ -54,10 +61,10 @@ class InvestWidget(gtk.TreeView): self._getcelldata_balancepct] for i, col_name in enumerate(col_names): if i < 3: - cell = gtk.CellRendererText() + cell = Gtk.CellRendererText() if i > 0: cell.set_property("xalign", 1.0) - column = gtk.TreeViewColumn (col_name, cell) + column = Gtk.TreeViewColumn (col_name, cell) if i == 0: column.set_sort_column_id(quotes_updater.LABEL) elif i == 2: @@ -65,15 +72,15 @@ class InvestWidget(gtk.TreeView): column.set_cell_data_func(cell, col_cellgetdata_functions[i]) self.append_column(column) elif i == 3: - cell_pb = gtk.CellRendererPixbuf() - column = gtk.TreeViewColumn (col_name, cell_pb, pixbuf=quotes_updater.PB) + cell_pb = Gtk.CellRendererPixbuf() + column = Gtk.TreeViewColumn (col_name, cell_pb, pixbuf=quotes_updater.PB) self.append_column(column) else: # add the last two column only if we have any positions if simple_quotes_only == False: - cell = gtk.CellRendererText() + cell = Gtk.CellRendererText() cell.set_property("xalign", 1.0) - column = gtk.TreeViewColumn (col_name, cell) + column = Gtk.TreeViewColumn (col_name, cell) if i == 4: column.set_sort_column_id(quotes_updater.BALANCE) elif i == 5: @@ -101,11 +108,17 @@ class InvestWidget(gtk.TreeView): return locale.format("%+.2f", value, True, True) + " " + currency - def _getcelldata_label(self, column, cell, model, iter): - cell.set_property('text', model[iter][model.LABEL]) + def _getcelldata_label(self, column, cell, model, iter, userdata): + label = model[iter][model.LABEL] + cell.set_property('text', label) - def _getcelldata_value(self, column, cell, model, iter): - cell.set_property('text', self.format_currency(model[iter][model.VALUE], model[iter][model.CURRENCY])) + def _getcelldata_value(self, column, cell, model, iter, userdata): + value = model[iter][model.VALUE]; + currency = model[iter][model.CURRENCY]; + if value == None or currency == None: + cell.set_property('text', "") + else: + cell.set_property('text', self.format_currency(value, currency)) def is_selected(self, model, iter): m, it = self.get_selection().get_selected() @@ -120,14 +133,14 @@ class InvestWidget(gtk.TreeView): intensity = LIGHT return palette[intensity] - def _getcelldata_variation(self, column, cell, model, iter): + def _getcelldata_variation(self, column, cell, model, iter, userdata): color = self.get_color(model, iter, model.VARIATION_PCT) change_pct = self.format_percent(model[iter][model.VARIATION_PCT]) cell.set_property('markup', "%s" % (color, change_pct)) - def _getcelldata_balance(self, column, cell, model, iter): + def _getcelldata_balance(self, column, cell, model, iter, userdata): is_ticker_only = model[iter][model.TICKER_ONLY] color = self.get_color(model, iter, model.BALANCE) if is_ticker_only: @@ -138,7 +151,7 @@ class InvestWidget(gtk.TreeView): "%s" % (color, balance)) - def _getcelldata_balancepct(self, column, cell, model, iter): + def _getcelldata_balancepct(self, column, cell, model, iter, userdata): is_ticker_only = model[iter][model.TICKER_ONLY] color = self.get_color(model, iter, model.BALANCE_PCT) if is_ticker_only: @@ -156,12 +169,12 @@ class InvestWidget(gtk.TreeView): mate_invest.chart.show_chart([ticker]) -#class InvestTicker(gtk.Label): +#class InvestTicker(Gtk.Label): # def __init__(self): -# gtk.Label.__init__(self, _("Waiting...")) +# Gtk.Label.__init__(self, _("Waiting...")) # # self.quotes = [] -# gobject.timeout_add(TICKER_TIMEOUT, self.scroll_quotes) +# GObject.timeout_add(TICKER_TIMEOUT, self.scroll_quotes) # # get_quotes_updater().connect('quotes-updated', self.on_quotes_update) # @@ -188,11 +201,11 @@ class InvestWidget(gtk.TreeView): # # return True # -#gobject.type_register(InvestTicker) +#GObject.type_register(InvestTicker) -class InvestTrend(gtk.Image): +class InvestTrend(Gtk.Image): def __init__(self): - gtk.Image.__init__(self) + Gtk.Image.__init__(self) self.pixbuf = None self.previous_allocation = (0,0) self.connect('size-allocate', self.on_size_allocate) @@ -202,14 +215,14 @@ class InvestTrend(gtk.Image): if self.previous_allocation == (allocation.width, allocation.height): return - self.pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, allocation.height, allocation.height) + self.pixbuf = GdkPixbuf.Pixbuf(GdkPixbuf.Colorspace.RGB, True, 8, allocation.height, allocation.height) self.set_color("grey") self.previous_allocation = (allocation.width, allocation.height) def set_color(self, color, opacity=0xFF): if self.pixbuf != None: try: - color = pango.Color(color) + color = Pango.Color(color) factor = float(0xFF)/0xFFFF self.pixbuf.fill( int(color.red*factor)<<24|int(color.green*factor)<<16|int(color.blue*factor)<<8|opacity) @@ -247,4 +260,4 @@ class InvestTrend(gtk.Image): self.set_color(color, opacity) -gobject.type_register(InvestTrend) +GObject.type_register(InvestTrend) diff --git a/invest-applet/pygi-mate-convert.sh b/invest-applet/pygi-mate-convert.sh new file mode 100755 index 00000000..33875c6d --- /dev/null +++ b/invest-applet/pygi-mate-convert.sh @@ -0,0 +1,234 @@ +#!/bin/sh + +# adapted from +# http://git.gnome.org/browse/pygobject/tree/pygi-convert.sh + +if [ -n "$1" ]; then + FILES_TO_CONVERT="$@" +else + FILES_TO_CONVERT="$(find . -name '*.py')" +fi + +for f in $FILES_TO_CONVERT; do + perl -i -0 \ + -pe "s/import pygtk/import gi/g;" \ + -pe "s/pygtk.require\('2.0'\)/gi.require_version\('Gtk', '3.0'\)/g;" \ + -pe "s/import gtk\n/from gi.repository import Gtk\n/g;" \ + -pe "s/(? 0/self._content.get_children\(\)/g;" \ + -pe "s/len\(self.menu.get_children\(\)\) > 0/self.menu.get_children\(\)/g;" \ + -pe "s/import gobject\n/from gi.repository import GObject\n/g;" \ + -pe "s/Gtk\..*\.__init__/gobject.GObject.__init__/g;" \ +\ + -pe "s/rsvg.Handle\s*\(data=([^,\)]+)\)/Rsvg.Handle.new_from_data(\1)/g;" \ +\ + -pe "s/from gtk import gdk\n/from gi.repository import Gdk\n/g;" \ + -pe "s/import gtk.gdk as gdk\n/from gi.repository import Gdk\n/g;" \ + -pe "s/Gtk.gdk.x11_/GdkX11.x11_/g;" \ + -pe "s/Gtk.gdk\./Gdk\./g;" \ + -pe "s/(?