[gnome-applets/wip/dont-use-deprecated: 86/87] invest-applet: further moved to pygobject API of Gtk, Gdk, ...



commit 7a42fdb4a5a817c2e09b15f18f35716191237e5f
Author: Enrico Minack <enrico-minack gmx de>
Date:   Fri Apr 1 19:30:11 2011 -0400

    invest-applet: further moved to pygobject API of Gtk, Gdk, ...

 invest-applet/data/Invest_Applet.xml  |   14 +---
 invest-applet/data/financialchart.ui  |    4 +-
 invest-applet/invest/__init__.py      |   46 +++++++++--
 invest-applet/invest/about.py         |    9 ++-
 invest-applet/invest/applet.py        |  144 ++++++++++++---------------------
 invest-applet/invest/chart.py         |   89 ++++++++++++--------
 invest-applet/invest/help.py          |    4 +-
 invest-applet/invest/invest-applet.py |   34 +++++---
 invest-applet/invest/preferences.py   |   20 +++--
 invest-applet/invest/quotes.py        |  107 ++++++++++++++++---------
 invest-applet/invest/widgets.py       |   42 +++++-----
 11 files changed, 282 insertions(+), 231 deletions(-)
---
diff --git a/invest-applet/data/Invest_Applet.xml b/invest-applet/data/Invest_Applet.xml
index 832f6b8..5e7f712 100644
--- a/invest-applet/data/Invest_Applet.xml
+++ b/invest-applet/data/Invest_Applet.xml
@@ -1,10 +1,4 @@
-<Root>
-	<popups>
-		<popup name="button3">
-			<menuitem name="Refresh" verb="Refresh" _label="_Refresh" pixtype="stock" pixname="gtk-refresh"/>
-			<menuitem name="Prefs" verb="Prefs" _label="_Preferences" pixtype="stock" pixname="gtk-properties"/>
-			<menuitem name="Help" verb="Help" _label="_Help"          pixtype="stock" pixname="gtk-help"/>
-			<menuitem name="About" verb="About" _label="_About"       pixtype="stock" pixname="gtk-about"/>
-		</popup>
-	</popups>
-</Root>
+<menuitem name="Refresh" action="Refresh" />
+<menuitem name="Prefs" action="Prefs" />
+<menuitem name="Help" action="Help" />
+<menuitem name="About" action="About" />
diff --git a/invest-applet/data/financialchart.ui b/invest-applet/data/financialchart.ui
index 1de0f38..1f418d7 100644
--- a/invest-applet/data/financialchart.ui
+++ b/invest-applet/data/financialchart.ui
@@ -194,7 +194,7 @@
               </packing>
             </child>
             <child>
-              <object class="GtkComboBox" id="t">
+              <object class="GtkComboBoxText" id="t">
                 <property name="visible">True</property>
                 <property name="add_tearoffs">False</property>
                 <property name="focus_on_click">True</property>
@@ -316,7 +316,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkComboBox" id="q">
+                  <object class="GtkComboBoxText" id="q">
                     <property name="visible">True</property>
                     <property name="add_tearoffs">False</property>
                     <property name="focus_on_click">True</property>
diff --git a/invest-applet/invest/__init__.py b/invest-applet/invest/__init__.py
index 29fb7d6..9977a3b 100644
--- a/invest-applet/invest/__init__.py
+++ b/invest-applet/invest/__init__.py
@@ -1,25 +1,49 @@
-import os, sys
+import os, sys, traceback
 from os.path import join, exists, isdir, isfile, dirname, abspath, expanduser
 from types import ListType
 import datetime
 
-import gtk, gtk.gdk, gconf, gobject
+import pygtk
+pygtk.require('2.0')
+from gi.repository import GObject, Gtk, Gdk, GConf
+
 import cPickle
 
 import networkmanager
 
+import random
+
+
 # Autotools set the actual data_dir in defs.py
 from defs import *
 
-DEBUGGING = False
+DEBUGGING = True
+
+LOGFILE = open('/tmp/investapplet.%d.log' % random.randint(1000000, 9999999), 'w')
+
 
 # central debugging and error method
 def debug(msg):
 	if DEBUGGING:
-		print "%s: %s" % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), msg)
+		msg = "%s: %s" % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), msg)
+		print msg
+		LOGFILE.write(msg + "\n")
 
 def error(msg):
-	print "%s: ERROR: %s" % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), msg)
+	msg = "%s: ERROR: %s" % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), msg)
+	print msg
+	LOGFILE.write(msg + "\n")
+
+
+def exceptionhandler(t, value, tb):
+	print "%s occurred: %s" % (t.__name__, value)
+	for elem in traceback.extract_tb(tb):
+		print "\t%s:%d in %s: %s" % (elem[0], elem[1], elem[2], elem[3])
+
+# redirect uncaught exceptions to this exception handler
+debug("Installing default exception handler")
+sys.excepthook = exceptionhandler
+
 
 
 # Allow to use uninstalled invest ---------------------------------------------
@@ -55,7 +79,7 @@ if not exists(USER_INVEST_DIR):
 os.chdir(expanduser("~"))
 
 #Gconf client
-GCONF_CLIENT = gconf.client_get_default()
+GCONF_CLIENT = GConf.Client.get_default()
 
 # GConf directory for invest in window mode and shared settings
 GCONF_DIR = "/apps/invest"
@@ -152,6 +176,7 @@ CONFIG_FILE = join(USER_INVEST_DIR, "config.pickle")
 try:
 	CONFIG = cPickle.load(file(CONFIG_FILE))
 except Exception, msg:
+	error("Could not load the configuration from %s: %s" % (CONFIG_FILE, msg) )
 	CONFIG = {}       # default configuration
 
 
@@ -202,12 +227,17 @@ def get_gnome_proxy_retry(client, attempts, sleep):
 		# we did not succeed, schedule retry
 		if attempts > 0:
 			error("Retrying to contact GConfd in %d seconds" % sleep)
-			gobject.timeout_add(sleep * 1000, get_gnome_proxy_retry, client, attempts, sleep)
+			GObject.timeout_add(sleep * 1000, get_gnome_proxy_retry, client, attempts, sleep)
 
 # use gconf to get proxy config
-client = gconf.client_get_default()
+debug("Detecting proxy settings")
+client = GConf.Client.get_default()
 get_gnome_proxy(client)
 
 
 # connect to Network Manager to identify current network connectivity
+debug("Connecting to the NetworkManager")
 nm = networkmanager.NetworkManager()
+
+debug("Finished __init__")
+
diff --git a/invest-applet/invest/about.py b/invest-applet/invest/about.py
index e2829e8..0fa8533 100644
--- a/invest-applet/invest/about.py
+++ b/invest-applet/invest/about.py
@@ -3,16 +3,19 @@ from os.path import join
 from gettext import gettext as _
 from invest.defs import VERSION
 import invest
-import gtk, gtk.gdk
+
+import pygtk
+pygtk.require('2.0')
+from gi.repository import Gtk, Gdk, GdkPixbuf
 
 invest_logo = None
 try:
-	invest_logo = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest_neutral.svg"), 96, 96)
+	invest_logo = GdkPixbuf.Pixbuf.new_from_file_at_size(join(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,
diff --git a/invest-applet/invest/applet.py b/invest-applet/invest/applet.py
index 4cd5ad7..9b490b2 100644
--- a/invest-applet/invest/applet.py
+++ b/invest-applet/invest/applet.py
@@ -1,41 +1,63 @@
 import os, time
 from os.path import *
-import gnomeapplet, gtk, gtk.gdk, gconf, gobject
-gobject.threads_init()
+
+import pygtk
+pygtk.require('2.0')
+from gi.repository import GObject, Gtk, Gdk, GdkPixbuf, GConf, PanelApplet
+GObject.threads_init()
+
 from gettext import gettext as _
-import gconf
 
 import invest, invest.about, invest.chart, invest.preferences, invest.defs
 from invest.quotes import QuoteUpdater
 from invest.widgets import *
 
-gtk.window_set_default_icon_from_file(join(invest.ART_DATA_DIR, "invest_neutral.svg"))
+Gtk.Window.set_default_icon_from_file(join(invest.ART_DATA_DIR, "invest_neutral.svg"))
 
 class InvestApplet:
 	def __init__(self, applet):
+		invest.debug("init 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
+		invest.debug("defining menu actions");
+		menu_actions = [("InvestAbout", Gtk.STOCK_HELP, "About", None, None, self.on_about), 
+				("InvestHelp", Gtk.STOCK_HELP, "Help", None, None, self.on_help),
+				("InvestPrefs", Gtk.STOCK_PREFERENCES, "Prefs", None, None, self.on_preferences),
+				("InvestRefresh", Gtk.STOCK_REFRESH, "Refresh", None, None, self.on_refresh)
+				]
+
+		invest.debug("creating action group")
+		actiongroup = Gtk.ActionGroup.new("InvestAppletActions")
+
+		invest.debug("setting translationd domain to %s " % invest.defs.GETTEXT_PACKAGE)
+		actiongroup.set_translation_domain(invest.defs.GETTEXT_PACKAGE)
+
+		# arguments: entries (array of action descriptions), n (the number of entries), userdata (passed to the action callbacks)
+		invest.debug("adding action menue to action group")
+		# actiongroup.add_actions(menu_actions, len(menu_actions), None)
+		actiongroup.add_actions(menu_actions, None)
+
+		invest.debug("setting up menu from file");
+		self.applet.setup_menu_from_file ("/home/enrico/git/gnome-applets/invest-applet/data/Invest_Applet.xml", actiongroup);
+
+		invest.debug("creating icon");
+		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()
 
 	def new_ilw(self):
 		self.quotes_updater = QuoteUpdater(self.set_applet_icon,
 						   self.set_applet_tooltip)
+		invest.debug("creating InvestWidget");
 		self.investwidget = InvestWidget(self.quotes_updater)
+		invest.debug("creating InvestListWindow");
 		self.ilw = InvestmentsListWindow(self.applet, self.investwidget)
 
 	def reload_ilw(self):
@@ -43,7 +65,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 (invest.STOCKS) == 0:
 				# a) We aren't configured yet
@@ -51,7 +73,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(_("<b>No stock quotes are currently available</b>"))
 				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 +82,37 @@ 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, data):
 		invest.about.show_about()
 	
-	def on_help(self, component, verb):
+	def on_help(self, action, data):
 		invest.help.show_help()
 
-	def on_preferences(self, component, verb):
+	def on_preferences(self, action, data):
 		invest.preferences.show_preferences(self)
 		self.reload_ilw()
 	
-	def on_refresh(self, component, verb):
+	def on_refresh(self, action, data):
 		self.quotes_updater.refresh()
 
 	def set_applet_icon(self, change):
 		if change == 1:
-			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest-22_up.png"), -1,-1)
+			pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(invest.ART_DATA_DIR, "invest-22_up.png"), -1,-1)
 		elif change == 0:
-			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest-22_neutral.png"), -1,-1)
+			pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(invest.ART_DATA_DIR, "invest-22_neutral.png"), -1,-1)
 		else:
-			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest-22_down.png"), -1,-1)
+			pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(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)
+# throws an exception, but shouldn't
+#		Gtk.Window.__init__(self, Gtk.WindowType.TOPLEVEL)
+		Gtk.Window.__init__(self)
+		self.set_type_hint(Gdk.WindowTypeHint.DOCK)
 		self.stick()
 		self.set_resizable(False)
 		self.set_border_width(6)
@@ -117,69 +141,5 @@ class InvestmentsListWindow(gtk.Window):
 		Calculates the position and moves the window to it.
 		"""
 		self.realize()
+		self.set_gravity(Gdk.Gravity.SOUTH_WEST)
 
-		# Get our own dimensions & position
-		#(wx, wy) = self.get_origin()
-		(ax, ay) = self.applet.window.get_origin()
-
-		(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))
-
-		if self.alignment == gnomeapplet.ORIENT_LEFT:
-				x = ax - ww
-				y = ay
-
-				if (y + wh > monitor.y + monitor.height):
-					y = monitor.y + monitor.height - wh
-
-				if (y < 0):
-					y = 0
-				
-				if (y + wh > monitor.height / 2):
-					gravity = gtk.gdk.GRAVITY_SOUTH_WEST
-				else:
-					gravity = gtk.gdk.GRAVITY_NORTH_WEST
-					
-		elif self.alignment == gnomeapplet.ORIENT_RIGHT:
-				x = ax + aw
-				y = ay
-
-				if (y + wh > monitor.y + monitor.height):
-					y = monitor.y + monitor.height - wh
-				
-				if (y < 0):
-					y = 0
-				
-				if (y + wh > monitor.height / 2):
-					gravity = gtk.gdk.GRAVITY_SOUTH_EAST
-				else:
-					gravity = gtk.gdk.GRAVITY_NORTH_EAST
-
-		elif self.alignment == gnomeapplet.ORIENT_DOWN:
-				x = ax
-				y = ay + ah
-
-				if (x + ww > monitor.x + monitor.width):
-					x = monitor.x + monitor.width - ww
-
-				if (x < 0):
-					x = 0
-
-				gravity = gtk.gdk.GRAVITY_NORTH_WEST
-		elif self.alignment == gnomeapplet.ORIENT_UP:
-				x = ax
-				y = ay - wh
-
-				if (x + ww > monitor.x + monitor.width):
-					x = monitor.x + monitor.width - ww
-
-				if (x < 0):
-					x = 0
-
-				gravity = gtk.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 15803b6..68169e1 100644
--- a/invest-applet/invest/chart.py
+++ b/invest-applet/invest/chart.py
@@ -1,7 +1,9 @@
 #!/usr/bin/env python
 
-import gtk, gtk.gdk
-import gobject
+import pygtk
+pygtk.require('2.0')
+from gi.repository import GObject, Gtk, Gdk, GdkPixbuf
+
 import os
 import invest
 from gettext import gettext as _
@@ -11,54 +13,68 @@ from os.path import join
 import urllib
 from threading import Thread
 import time
+import ctypes
 
-AUTOREFRESH_TIMEOUT = 20*60*1000 # 15 minutes
+AUTOREFRESH_TIMEOUT = 15*60*1000 # 15 minutes
 
 # based on http://www.johnstowers.co.nz/blog/index.php/2007/03/12/threading-and-pygtk/
-class _IdleObject(gobject.GObject):
-	"""
-	Override gobject.GObject to always emit signals in the main thread
-	by emmitting on an idle handler
-	"""
-	def __init__(self):
-		gobject.GObject.__init__(self)
-
-	def emit(self, *args):
-		gobject.idle_add(gobject.GObject.emit,self,*args)
+#class _IdleObject(GObject.Object):
+#	"""
+#	Override GObject.Object to always emit signals in the main thread
+#	by emmitting on an idle handler
+#	"""
+#	def __init__(self):
+#		GObject.Object.__init__(self)
+#
+#	def emit(self, *args):
+#		GObject.idle_add(GObject.Object.emit,self,*args)
+#
+#class ImageRetriever(Thread, _IdleObject):
+class ImageRetriever(Thread):
+#	"""
+#	Thread which uses gobject signals to return information
+#	to the GUI.
+#	"""
+#	__gsignals__ =  { 
+#			"completed": (
+#				GObject.SignalFlags.RUN_LAST, GObject.TYPE_NONE, []),
+#			# FIXME: should we be making use of this?
+#			#"progress": (
+#			#	gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
+#			#	gobject.TYPE_FLOAT])        #percent complete
+#			}
 
-class ImageRetriever(Thread, _IdleObject):
-	"""
-	Thread which uses gobject signals to return information
-	to the GUI.
-	"""
-	__gsignals__ =  { 
-			"completed": (
-				gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
-			# FIXME: should we be making use of this?
-			#"progress": (
-			#	gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
-			#	gobject.TYPE_FLOAT])        #percent complete
-			}
+	completed_callback = None
+	completed_callback_arg = None
 
 	def __init__(self, image_url):
 		Thread.__init__(self)
-		_IdleObject.__init__(self)	
+#		_IdleObject.__init__(self)	
 		self.image_url = image_url
 		self.retrieved = False
 		
 	def run(self):
-		self.image = gtk.Image()
+		if self.completed_callback == None:
+			invest.debug("Completed callback not set before ImageRetriever got started")
+		
+		self.image = Gtk.Image()
 		try: sock = urllib.urlopen(self.image_url, proxies = invest.PROXY)
 		except Exception, msg:
 			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())
+			loader.write(sock.read(), -1) 
 			sock.close()
 			loader.close()
 			self.retrieved = True
-		self.emit("completed")
+#		self.emit("completed")
+		if self.completed_callback != None:
+			invest.debug("Calling ImageRetriever callback %s with arg %s" % (self.completed_callback, self.completed_callback_arg))
+			if self.completed_callback_arg == None:
+				self.completed_callback(self)
+			else:
+				self.completed_callback(self, self.completed_callback_arg)
 
 # p:
 #  eX = Exponential Moving Average
@@ -107,7 +123,7 @@ class FinancialChart:
 		win.set_title(_("Financial Chart"))
 		
 		try:
-			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest_neutral.svg"), 96,96)
+			pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(invest.ART_DATA_DIR, "invest_neutral.svg"), 96,96)
 			self.ui.get_object("plot").set_from_pixbuf(pixbuf)
 		except Exception, msg:
 			invest.debug("Could not load 'invest-neutral.svg' file: %s" % msg)
@@ -224,7 +240,8 @@ class FinancialChart:
 		progress.show()
 		
 		image_retriever = ImageRetriever(url)
-		image_retriever.connect("completed", self.on_retriever_completed)
+#		image_retriever.connect("completed", self.on_retriever_completed)
+		image_retriever.completed_callback = self.on_retriever_completed
 		image_retriever.start()
 
 		# Update timer if needed
@@ -241,14 +258,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(invest.BUILDER_DATA_DIR, "financialchart.ui"))
 	chart = FinancialChart(ui)
 	ui.get_object("s").set_text(' '.join(tickers))
diff --git a/invest-applet/invest/help.py b/invest-applet/invest/help.py
index 7dfaabf..49c3668 100644
--- a/invest-applet/invest/help.py
+++ b/invest-applet/invest/help.py
@@ -1,5 +1,7 @@
 # -*- coding: utf-8 -*-
-import gtk, gtk.gdk
+import pygtk
+pygtk.require('2.0')
+from gi.repository import Gtk, Gdk
 
 def show_help():
 	gtk.show_uri(None, "ghelp:invest-applet", gtk.gdk.CURRENT_TIME)
diff --git a/invest-applet/invest/invest-applet.py b/invest-applet/invest/invest-applet.py
index da1fb05..ac2cef8 100755
--- a/invest-applet/invest/invest-applet.py
+++ b/invest-applet/invest/invest-applet.py
@@ -1,8 +1,9 @@
 #!/usr/bin/env python
 #
 
-import gobject
-import gtk, gnomeapplet
+import pygtk
+pygtk.require('2.0')
+from gi.repository import GObject, Gtk, PanelApplet
 
 import getopt, sys
 from os.path import *
@@ -30,19 +31,22 @@ locale.textdomain(invest.defs.GETTEXT_PACKAGE)
 
 from gettext import gettext as _
 
-def applet_factory(applet, iid):
-	invest.debug('Starting invest instance: %s %s'% ( applet, iid ))
+def applet_factory(applet, iid, data):
+	invest.debug('Starting invest instance: %s %s %s'% ( applet, iid, data ))
 	invest.applet.InvestApplet(applet)
 	return True
 
 # Return a standalone window that holds the applet
 def build_window():
-	app = gtk.Window(gtk.WINDOW_TOPLEVEL)
+	invest.debug("Creating panel applet container")
+	PanelApplet.Container.new()
+	invest.debug("Creating gtk window")
+	app = Gtk.Window.new(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 = gnomeapplet.Applet()
+	applet = PanelApplet.Applet()
 	applet_factory(applet, None)
 	applet.reparent(app)
 
@@ -87,12 +91,14 @@ if __name__ == "__main__":
 			standalone = True
 
 	if standalone:
+		invest.debug("Starting standalone applet")
 		build_window()
-		gtk.main()
+		Gtk.main()
 	else:
-		gnomeapplet.bonobo_factory(
-			"OAFIID:Invest_Applet_Factory",
-			gnomeapplet.Applet.__gtype__,
-			invest.defs.PACKAGE,
-			invest.defs.VERSION,
-			applet_factory)
+		invest.debug("Starting applet factory")
+		PanelApplet.Applet.factory_main(
+			"InvestAppletFactory",	# id
+			PanelApplet.Applet.__gtype__,	# gtype
+			applet_factory,			# factory callback
+			None)				# factory data pointer
+
diff --git a/invest-applet/invest/preferences.py b/invest-applet/invest/preferences.py
index 2485e16..8e1097e 100644
--- a/invest-applet/invest/preferences.py
+++ b/invest-applet/invest/preferences.py
@@ -1,14 +1,18 @@
 from gettext import gettext as _
 import locale
 from os.path import join
-import gtk, gobject, gconf
+
+import pygtk
+pygtk.require('2.0')
+from gi.repository import GObject, Gtk, GConf
+
 import 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(invest.BUILDER_DATA_DIR, "prefs-dialog.ui"))
 
 		self.dialog = self.ui.get_object("preferences")
@@ -29,14 +33,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():
@@ -107,12 +111,12 @@ 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.set_sort_column_id(column)
diff --git a/invest-applet/invest/quotes.py b/invest-applet/invest/quotes.py
index 2b8918f..9672f57 100644
--- a/invest-applet/invest/quotes.py
+++ b/invest-applet/invest/quotes.py
@@ -1,5 +1,9 @@
 from os.path import join
-import gnomeapplet, gtk, gtk.gdk, gconf, gobject
+
+import pygtk
+pygtk.require('2.0')
+from gi.repository import GObject, Gtk, Gdk, GdkPixbuf, GConf, PanelApplet
+
 from gettext import gettext as _
 import csv
 import locale
@@ -19,40 +23,50 @@ 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):
-	"""
-	Override gobject.GObject to always emit signals in the main thread
-	by emmitting on an idle handler
-	"""
-	def __init__(self):
-		gobject.GObject.__init__(self)
-
-	def emit(self, *args):
-		gobject.idle_add(gobject.GObject.emit,self,*args)
-
-class QuotesRetriever(Thread, _IdleObject):
-	"""
-	Thread which uses gobject signals to return information
-	to the GUI.
-	"""
-	__gsignals__ =  {
-			"completed": (
-				gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
-			# FIXME: We don't monitor progress, yet ...
-			#"progress": (
-			#	gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
-			#	gobject.TYPE_FLOAT])        #percent complete
-			}
+#class _IdleObject(GObject.Object):
+#	"""
+#	Override gobject.Object to always emit signals in the main thread
+#	by emmitting on an idle handler
+#	"""
+#	def __init__(self):
+#		GObject.Object.__init__(self)
+#
+#	def emit(self, *args):
+#		GObject.idle_add(GObject.Object.emit,self,*args)
+#
+#class QuotesRetriever(Thread, _IdleObject):
+class QuotesRetriever(Thread):
+#	"""
+#	Thread which uses gobject signals to return information
+#	to the GUI.
+#	"""
+#	__gsignals__ =  {
+#			"completed": (
+#				GObject.SignalFlags.RUN_LAST, GObject.TYPE_NONE, []),
+#			# FIXME: We don't monitor progress, yet ...
+#			#"progress": (
+#			#	gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
+#			#	gobject.TYPE_FLOAT])        #percent complete
+#			}
+
+	completed_callback = None
+	completed_callback_arg = None
 
 	def __init__(self, tickers):
 		Thread.__init__(self)
-		_IdleObject.__init__(self)
+#		_IdleObject.__init__(self)
 		self.tickers = tickers
 		self.retrieved = False
 		self.data = []
 		self.currencies = []
+		invest.debug("QuotesRetriever created");
 
 	def run(self):
+		invest.debug("QuotesRetriever started");
+
+		if self.completed_callback == None:
+			invest.debug("Completed callback not set before QuotesRetriever got started")
+		
 		quotes_url = QUOTES_URL % {"s": self.tickers}
 		try:
 			quotes_file = urlopen(quotes_url, proxies = invest.PROXY)
@@ -62,34 +76,42 @@ class QuotesRetriever(Thread, _IdleObject):
 			invest.debug("Error while retrieving quotes data (url = %s): %s" % (quotes_url, msg))
 		else:
 			self.retrieved = True
-		self.emit("completed")
+
+#		self.emit("completed")
+		if self.completed_callback != None:
+			invest.debug("Calling ImageRetriever callback %s with arg %s" % (self.completed_callback, self.completed_callback_arg))
+			if self.completed_callback_arg == None:
+				self.completed_callback(self)
+			else:
+				self.completed_callback(self, self.completed_callback_arg)
 
 
-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
+		invest.debug("setting NM callback");
 		invest.nm.set_statechange_callback(self.nm_state_changed)
 
 	def set_update_interval(self, interval):
 		if self.timeout_id != None:
 			invest.debug("Canceling refresh timer")
-			gobject.source_remove(self.timeout_id)
+			GObject.source_remove(self.timeout_id)
 			self.timeout_id = None
 		if interval > 0:
 			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
@@ -108,12 +130,18 @@ class QuoteUpdater(gtk.ListStore):
 			return False
 
 		if len(invest.STOCKS) == 0:
+			invest.debug("No stocks configured")
 			return True
 
 		tickers = '+'.join(invest.STOCKS.keys())
+		invest.debug("creating quores retriever")
 		quotes_retriever = QuotesRetriever(tickers)
-		quotes_retriever.connect("completed", self.on_retriever_completed)
+#		quotes_retriever.connect("completed", self.on_retriever_completed)
+		invest.debug("adding callback")
+		quotes_retriever.completed_callback = self.on_retriever_completed
+		invest.debug("starting")
 		quotes_retriever.start()
+		invest.debug("started")
 
 		return True
 
@@ -127,7 +155,9 @@ class QuoteUpdater(gtk.ListStore):
 		return locale.format("%+.2f", value, True, True)
 
 	def on_retriever_completed(self, retriever):
+		invest.debug("retriever completed");
 		if retriever.retrieved == False:
+			invest.debug("retrieval failed");
 			tooltip = [_('Invest could not connect to Yahoo! Finance')]
 			if self.last_updated != None:
 				# Translators: %s is an hour (%H:%M)
@@ -275,7 +305,7 @@ 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(invest.STOCKS[ticker]["purchases"], val["trade"])
 					row = self.insert(0, [ticker, label, val["currency"], False, balance, change, val["trade"], val["variation_pct"], pb])
@@ -284,7 +314,8 @@ class QuoteUpdater(gtk.ListStore):
 				url = 'http://ichart.yahoo.com/h?s=%s' % ticker
 
 				image_retriever = invest.chart.ImageRetriever(url)
-				image_retriever.connect("completed", self.set_pb_callback, row)
+				image_retriever.completed_callback = self.set_pb_callback
+				image_retriever.completed_callback_arg = row
 				image_retriever.start()
 
 				quotes_change += val['variation_pct']
@@ -328,7 +359,7 @@ class QuoteUpdater(gtk.ListStore):
 			if len(symbols) > 0:
 				tickers = '+'.join(symbols)
 				quotes_retriever = QuotesRetriever(tickers)
-				quotes_retriever.connect("completed", self.on_currency_retriever_completed)
+				quotes_retriever.completed_callback = self.on_currency_retriever_completed
 				quotes_retriever.start()
 
 	def convert_currencies(self, quotes):
@@ -404,5 +435,5 @@ class QuoteUpdater(gtk.ListStore):
 					break
 		return res
 
-if gtk.pygtk_version < (2,8,0):
-	gobject.type_register(QuoteUpdater)
+#if Gtk.version < (2,8,0):
+#	gobject.type_register(QuoteUpdater)
diff --git a/invest-applet/invest/widgets.py b/invest-applet/invest/widgets.py
index 13a2ec9..16bfb92 100644
--- a/invest-applet/invest/widgets.py
+++ b/invest-applet/invest/widgets.py
@@ -1,6 +1,10 @@
 import os, time
 from os.path import *
-import gnomeapplet, gtk, gtk.gdk, gconf, gobject, pango
+
+import pygtk
+pygtk.require('2.0')
+from gi.repository import GObject, Gtk, Gdk, GdkPixbuf, GConf, PanelApplet, Pango
+
 from gettext import gettext as _
 import locale
 import csv
@@ -35,9 +39,9 @@ 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)
@@ -54,10 +58,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 +69,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,10 +105,10 @@ class InvestWidget(gtk.TreeView):
 		return locale.format("%+.2f", value, True, True) + " " + currency
 
 
-	def _getcelldata_label(self, column, cell, model, iter):
+	def _getcelldata_label(self, column, cell, model, iter, userdata):
 		cell.set_property('text', model[iter][model.LABEL])
 
-	def _getcelldata_value(self, column, cell, model, iter):
+	def _getcelldata_value(self, column, cell, model, iter, userdata):
 		cell.set_property('text', self.format_currency(model[iter][model.VALUE], model[iter][model.CURRENCY]))
 
 	def is_selected(self, model, iter):
@@ -120,14 +124,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',
 			"<span foreground='%s'>%s</span>" %
 			(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 +142,7 @@ class InvestWidget(gtk.TreeView):
 				"<span foreground='%s'>%s</span>" %
 				(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:
@@ -190,9 +194,9 @@ class InvestWidget(gtk.TreeView):
 #
 #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 +206,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 +251,4 @@ class InvestTrend(gtk.Image):
 
 		self.set_color(color, opacity)
 
-gobject.type_register(InvestTrend)
+GObject.type_register(InvestTrend)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]