from subprocess import *
import cairo
import time
-from threading import *
import re
+import gettext
+
+try :
+ t = gettext.translation('ussd-widget', '/usr/share/locale')
+ _ = t.ugettext
+except IOError:
+ print "Translation file for your language not found"
+ def retme(arg):
+ return arg
+ _ = retme
+
+# TODO Cutt off too long messages and show them in separate dialog
+# how TODO widget vertical minimum size policy
+# TODO make multiple widgets coexist on desktop
+
+class USSD_Controller:
+ def __init__( self, widget ) :
+ self.widget = widget
+ self.default_config = ["", "", "", "", "", ""]
+ self.config = self.default_config
+ self.timeout_version = 0
+
+ def save_config( self ) :
+ fconfig = open(os.getenv("HOME")+"/.ussdWidget.conf","w")
+ fconfig.writelines(["# Parameters are taken by line number, do not move them\n", "# USSD query to be run by widget\n", "number="+self.config[0], "\n"])
+ fconfig.writelines(["#Parser command\n", "parser="+self.config[1], "\n"])
+ fconfig.writelines(["#Chain command\n", "chain="+self.config[2], "\n"])
+ fconfig.writelines(["#Update interval in minutes\n", "interval="+self.config[3], "\n"])
+ fconfig.writelines(["#RegExp pattern\n", "regexp="+self.config[4], "\n"])
+ fconfig.writelines(["#Widget width\n", "width="+self.config[5], "\n"])
+ fconfig.close()
+
+ def get_config( self ):
+ try :
+ config = open(os.getenv("HOME")+"/.ussdWidget.conf","r")
+
+ error = False
+ i = 0
+ for line in config :
+ i += 1
+ if line[0] == '#':
+ continue
+ line=line.split('=', 2)
+
+ if len(line) != 2 :
+ error = True
+ print _("Error reading config on line %(line)d. = or # expected.")%{"line":i}
+ continue
+ if line[0] == "number" :
+ self.config[0] = line[1].strip()
+ elif line[0] == "parser" :
+ self.config[1] = line[1].strip()
+ elif line[0] == "chain" :
+ self.config[2] = line[1].strip()
+ elif line[0] == "interval" :
+ self.config[3] = line[1].strip()
+ elif line[0] == "regexp" :
+ self.config[4] = line[1].strip()
+ elif line[0] == "width" :
+ self.config[5] = line[1].strip()
+ else :
+ error = True
+ print _("Error reading config on line %(line)d. Unexpected variable: ")%{"line":i}+line[0]
+ continue
+
+ config.close()
+
+ if error :
+ self.widget.error = 1
+ self.widget.set_text (_("Config error"), 5000)
+
+ return self.config
+ except IOError:
+ self.widget.error = 1
+ self.widget.set_text (_("Config error"), 0)
+ print _("IO error while reading config")
+
+ return self.default.config
+
+ def on_show_settings( self, widget ) :
+ dialog = UssdConfigDialog(self.config)
+ dialog.run()
+
+ if check_regexp( dialog.regexp.get_text() ) :
+ return
+
+# TODO Check, that we have ussd number
+ #if dialog.ussdNumber
+# TODO check, that width and interval are integers
+ self.config = [
+ dialog.ussdNumber.get_text(),
+ dialog.parser.get_text(),
+ dialog.chain.get_text(),
+ dialog.update_interval.get_text(),
+ dialog.regexp.get_text(),
+ dialog.widthEdit.get_text()
+ ]
+
+ self.save_config()
+
+ if self.config[5] != "" :
+# FIXME use methods instead of accessing properties, move to widget, execute on startup
+ self.widget.label.set_width_chars (int(self.config[5]))
+ else :
+ self.widget.label.set_width_chars(-1)
+
+ self.reset_timed_renew()
+
+ dialog.destroy()
+
+ # Before running this function widget wasn't configured
+ if self.config == self.default_config:
+ self.widget.set_text(_("Click to update"))
+ return
+
+ def callback_ussd_data( self, source, condition ):
+ if condition == gobject.IO_IN or condition == gobject.IO_PRI :
+ data = source.read( )
+ if len( data ) > 0 :
+ self.cb_reply += data
+ return True
+ else :
+ self.cb_ready = 1
+ return False
+
+ elif condition == gobject.IO_HUP or condition == gobject.IO_ERR :
+ self.cb_ready = 1
+ self.process_reply()
+ return False
+
+ print (_("serious problems in program logic"))
+ return False
+
+
+ def call_external_script( self, ussd_code ):
+ self.cb_ready = 0
+ self.cb_reply = "";
+ p = Popen(['/usr/bin/ussdquery.py', ussd_code], stdout=PIPE)
+ gobject.io_add_watch( p.stdout, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR , self.callback_ussd_data )
+
+ def ussd_renew(self, widget, event):
+ if self.widget.processing == 0:
+ if self.config :
+ widget.processing = 1
+ widget.set_text(_("Processing"), 0)
+ self.call_external_script( self.config[0] )
+ else :
+ widget.processing = 0
+ widget.error = 1
+ widget.set_text(_("No config"), 0)
+
+ def process_reply( self ):
+ reply = self.cb_reply.strip()
+
+ if reply == "" :
+ self.widget.error = 1
+ self.widget.set_text (_("Error"), 5000)
+ else :
+ self.widget.error = 0
+ # Pass to parser
+ if self.config[1] != "":
+ p = Popen(smart_split_string(self.config[1], reply), stdout=PIPE)
+ reply = p.communicate(reply+"\n")[0].strip()
+ # Pass to chain
+ if self.config[2] != "":
+ p = Popen(smart_split_string(self.config[2], reply))
+ # Apply regexp
+ if self.config[4] != "":
+ try :
+ r = re.match( self.config[4], reply ).group( 1 )
+ except Exception, e:
+ r = _("Regexp Error: ") + str( e ) + "\n" + reply
+
+ if r :
+ reply = r
+ self.widget.set_text(reply)
+ self.widget.processing = 0
+
+ def timed_renew(self, version):
+ if version < self.timeout_version :
+ return False
+ self.ussd_renew(self.widget, None)
+ return True
+
+ def reset_timed_renew (self) :
+ self.timeout_version += 1
+ if self.config[3] != "" :
+ self.timer = gobject.timeout_add (60000*int(self.config[3]), self.timed_renew, self.timeout_version)
class pHelpDialog(gtk.Dialog):
- def __init__(self, heading, text):
- gtk.Dialog.__init__(self, heading, None,
- gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
- ("OK", gtk.RESPONSE_OK))
- self.vbox.add(gtk.Label(text))
- self.show_all()
- self.parent
+ def __init__(self, heading, text):
+ gtk.Dialog.__init__(self, heading, None,
+ gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
+ (_("OK").encode("utf-8"), gtk.RESPONSE_OK))
+ label = gtk.Label(text)
+ label.set_line_wrap (True)
+ self.vbox.add(label)
+ self.show_all()
+ self.parent
class UssdConfigDialog(gtk.Dialog):
- def __init__(self, config):
- gtk.Dialog.__init__(self, "USSD widget", None,
- gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
- ("Save", gtk.RESPONSE_OK))
- self.ussdNumber = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.ussdNumber.set_text(config[0])
- self.parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.parser.set_text(config[1])
- self.chain = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.chain.set_text(config[2])
- self.update_interval = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.update_interval.set_text(config[3])
- self.regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
- self.regexp.set_text(config[4])
-
- phelp = gtk.Button("?")
- phelp.connect("clicked", on_show_phelp)
-
- chelp = gtk.Button("?")
- chelp.connect("clicked", on_show_chelp)
-
- reghelp = gtk.Button("?")
- reghelp.connect("clicked", on_show_reghelp)
-
- numberBox = gtk.HBox()
- numberBox.add(gtk.Label("USSD number"))
- numberBox.add(self.ussdNumber)
- self.vbox.add(numberBox)
-
- parserBox = gtk.HBox()
- parserBox.add(gtk.Label("Parser"))
- parserBox.add(phelp)
- parserBox.add(self.parser)
- self.vbox.add(parserBox)
-
- chainBox = gtk.HBox()
- chainBox.add(gtk.Label("Chain"))
- chainBox.add(chelp)
- chainBox.add(self.chain)
- self.vbox.add(chainBox)
-
- updateBox = gtk.HBox()
- updateBox.add(gtk.Label("Update every "))
- updateBox.add(self.update_interval)
- updateBox.add(gtk.Label(" minutes (BROKEN)"))
- self.vbox.add(updateBox)
-
- regexpBox = gtk.HBox()
- regexpBox.add(gtk.Label("RegExp"))
- regexpBox.add(reghelp)
- regexpBox.add(self.regexp)
- self.vbox.add(regexpBox)
-
- self.show_all()
- self.parent
+ def __init__(self, config):
+ gtk.Dialog.__init__(self, _("USSD widget"), None,
+ gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
+ (_("Save").encode("utf-8"), gtk.RESPONSE_OK))
+ self.set_size_request(-1, 400)
+ self.ussdNumber = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.ussdNumber.set_text(config[0])
+ self.parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.parser.set_text(config[1])
+ self.chain = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.chain.set_text(config[2])
+ self.update_interval = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.update_interval.set_text(config[3])
+ self.regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.regexp.set_text(config[4])
+ self.widthEdit = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+ self.widthEdit.set_text(config[5])
+
+ phelp = gtk.Button("?")
+ phelp.connect("clicked", self.on_show_phelp)
+
+ chelp = gtk.Button("?")
+ chelp.connect("clicked", self.on_show_chelp)
+
+ reghelp = gtk.Button("?")
+ reghelp.connect("clicked", self.on_show_reghelp)
+
+ area = hildon.PannableArea()
+ self.vbox.add(area)
+ vbox = gtk.VBox()
+ area.add_with_viewport(vbox)
+
+ numberBox = gtk.HBox()
+ numberLabel = gtk.Label(_("USSD number"))
+ numberLabel.set_alignment(0,0)
+ numberLabel.set_size_request(100, -1)
+ self.ussdNumber.set_size_request(200, -1)
+ numberBox.add(numberLabel)
+ numberBox.add(self.ussdNumber)
+ vbox.add(numberBox)
+
+ parserBox = gtk.HBox()
+ parserLabel = gtk.Label(_("Parser"))
+ parserLabel.set_alignment(0,0)
+ parserLabel.set_size_request(200, -1)
+ phelp.set_size_request(10, -1)
+ parserBox.add(parserLabel)
+ parserBox.add(phelp)
+ vbox.add(parserBox)
+ vbox.add(self.parser)
+
+ chainBox = gtk.HBox()
+ chainLabel = gtk.Label(_("Chain"))
+ chainLabel.set_alignment(0,0)
+ chainLabel.set_size_request(200, -1)
+ chelp.set_size_request(10, -1)
+ chainBox.add(chainLabel)
+ chainBox.add(chelp)
+ vbox.add(chainBox)
+ vbox.add(self.chain)
+
+ regexpBox = gtk.HBox()
+ regexpLabel = gtk.Label(_("RegExp"))
+ regexpLabel.set_alignment(0,0)
+ regexpLabel.set_size_request(200, -1)
+ reghelp.set_size_request(10, -1)
+ regexpBox.add(regexpLabel)
+ regexpBox.add(reghelp)
+ vbox.add(regexpBox)
+ vbox.add(self.regexp)
+
+ widthBox = gtk.HBox()
+ widthLabel = gtk.Label(_("Max. width"))
+ widthLabel.set_alignment(0,0)
+ symbolsLabel = gtk.Label(_("symbols"))
+ widthLabel.set_size_request(150, -1)
+ self.widthEdit.set_size_request(30, -1)
+ symbolsLabel.set_size_request(40,-1)
+ widthBox.add(widthLabel)
+ widthBox.add(self.widthEdit)
+ widthBox.add(symbolsLabel)
+ vbox.add(widthBox)
+
+ updateBox = gtk.HBox()
+ updateLabel = gtk.Label(_("Update every"))
+ updateLabel.set_alignment(0,0)
+ minutesLabel = gtk.Label(_("minutes"))
+ updateLabel.set_size_request(150, -1)
+ self.update_interval.set_size_request(30, -1)
+ minutesLabel.set_size_request(40, -1)
+ updateBox.add(updateLabel)
+ updateBox.add(self.update_interval)
+ updateBox.add(minutesLabel)
+ vbox.add(updateBox)
+
+ self.show_all()
+ self.parent
+
+ #============ Dialog helper functions =============
+ def on_show_phelp(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility, output of utility would be shown to you.\n Format:\n% would be replaced by reply\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility"))
+ dialog.run()
+ dialog.destroy()
+
+ def on_show_chelp(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility after parser utility. May be used for logging, statistics etc.\n Format:\n% would be replaced by reply\n\\ invalidates special meaning of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility"))
+ dialog.run()
+ dialog.destroy()
+
+ def on_show_reghelp(self, widget):
+ dialog = pHelpDialog(_("Format help"), _("standard python regexps"))
+ dialog.run()
+ dialog.destroy()
+
+ def on_error_regexp(self, error):
+ dialog = pHelpDialog(_("Regexp syntax error"), error )
+ dialog.run()
+ dialog.destroy()
+
+ # TODO Use this for reporting error on wrong ussd number
+ def on_error_ussd_number(self, error):
+ dialog = pHelpDialog(_("Incorrect USSD number"), error )
+ dialog.run()
+ dialog.destroy()
+
def smart_split_string (str, query) :
- word = ""
- result = []
- # Is simbol backslashed?
- bs = 0
- # Quotes: 1 - ", 2 - ', 0 - no quotes
- qs = 0
- for i in range(len(str)) :
- if bs == 0 and (str[i] == '"' and qs == 1 or str[i] == "'" and qs == 2) :
- qs = 0
- elif bs == 0 and qs == 0 and (str[i] == '"' or str[i] == "'") :
- if str[i] == '"':
- qs = 1
- else :
- qs = 2
- elif bs == 0 and str[i] == '\\' :
- bs = 1
- elif bs == 0 and str[i] == '%' :
- word += query
- ws = 0
- else :
- if bs == 1 and str[i] != '\\' and str[i] != '"' and str[i] != "'" :
- word += "\\"
- if qs == 0 and (str[i] == " " or str[i] == "\t") :
- if word != "" :
- result.append(word)
- word = ""
- else :
- word += str[i]
- bs = 0
- if word != "" :
- result.append(word)
- return result
-
-def get_config():
- try :
- config = open(os.getenv("HOME")+"/.ussdWidget.conf","r")
- config.readline()
- config.readline()
- number = config.readline().strip()
- config.readline()
- parser = config.readline().strip()
- config.readline()
- chain = config.readline().strip()
- config.readline()
- interval = config.readline().strip()
- config.readline()
- regexp = config.readline().strip()
- config.close()
- return [number, parser, chain, interval, regexp]
- except IOError:
- return None
-
-def set_config(config):
- fconfig = open(os.getenv("HOME")+"/.ussdWidget.conf","w")
- fconfig.writelines(["# Parameters are taken by line number, do not move them\n", "# USSD query to be run by widget\n", config[0], "\n"])
- fconfig.writelines(["Parser command\n", config[1], "\n"])
- fconfig.writelines(["Chain command\n", config[2], "\n"])
- fconfig.writelines(["Update interval in minutes\n", config[3], "\n"])
- fconfig.writelines(["RegExp pattern\n", config[4], "\n"])
- fconfig.close()
+ word = ""
+ result = []
+ # Is simbol backslashed?
+ bs = 0
+ # Quotes: 1 - ", 2 - ', 0 - no quotes
+ qs = 0
+ for i in range(len(str)) :
+ if bs == 0 and (str[i] == '"' and qs == 1 or str[i] == "'" and qs == 2) :
+ qs = 0
+ elif bs == 0 and qs == 0 and (str[i] == '"' or str[i] == "'") :
+ if str[i] == '"':
+ qs = 1
+ else :
+ qs = 2
+ elif bs == 0 and str[i] == '\\' :
+ bs = 1
+ elif bs == 0 and str[i] == '%' :
+ word += query
+ ws = 0
+ else :
+ if bs == 1 and str[i] != '\\' and str[i] != '"' and str[i] != "'" :
+ word += "\\"
+ if qs == 0 and (str[i] == " " or str[i] == "\t") :
+ if word != "" :
+ result.append(word)
+ word = ""
+ else :
+ word += str[i]
+ bs = 0
+ if word != "" :
+ result.append(word)
+ return result
def check_regexp(regexp):
try :
- re.compile( regexp )
+ re.compile( regexp )
except Exception, e:
- on_error_regexp( str( e ) )
- return 1
+ on_error_regexp( str( e ) )
+ return 1
return 0
-#def timed_renewer(Thread):
-# def __init__ (self, widget, period):
-# self.widget = widget
-# self.period = period
-# self.version = widget.timerversion
-#
-# def run (self):
-# while widget.timerversion == version:
-# ussd_renew(widget, None)
-# time.sleep(period)
-
-def ussd_renew(widget, event):
- if widget.process == None or widget.process.isAlive() == False :
- widget.process = ussd_renewer (widget)
- # See bug https://bugs.maemo.org/show_bug.cgi?id=7809
- widget.process.run()
-
-class ussd_renewer ():#Thread):
- def __init__ (self, widget):
-# Thread.__init__ (self)
- self.widget = widget
- self.daemon = True
-
-# stub while thread but is not fixed
- def isAlive(self):
- return False
-
- def run(self):
- widget = self.widget
- config = get_config()
- widget.processing = 1
- last_text = widget.label.get_text()
- widget.label.set_text("Processing")
- widget.queue_draw()
- gtk.main_iteration ()
-
- if config :
- p = Popen(['/usr/bin/ussdquery.py', config[0]], stdout=PIPE)
- reply = p.communicate()[0].strip()
- if reply == "" :
- reply = " Error "
- widget.error = 1
- # Show previous text in 5 seconds
- widget.timer = gobject.timeout_add (5000, error_return, widget, last_text)
- else :
- widget.error = 0
- if config[1] != "":
- p = Popen(smart_split_string(config[1], reply), stdout=PIPE)
- reply = p.communicate(reply+"\n")[0].strip()
- if config[2] != "":
- p = Popen(smart_split_string(config[2], reply))
- if config[4] != "":
- try :
- r = re.match( config[4], reply ).group( 1 )
- except Exception, e:
- r = "Regexp Error: " + str( e )
-
- if r :
- reply = r
- else :
- reply = " Bad config "
- widget.processing = 0
- widget.label.set_text(reply)
- widget.queue_draw()
- gtk.main_iteration ()
-
-def error_return(widget, text) :
- if widget.processing == 0 and widget.error == 1:
- widget.label.set_text(text)
- return False
-
-def on_show_settings(widget):
- config = get_config()
- if config == None :
- config = ["", "", "", "", ""]
-
- dialog = UssdConfigDialog(config)
- dialog.run()
-
- if check_regexp( dialog.regexp.get_text() ) :
- return
-
- set_config ([dialog.ussdNumber.get_text(), dialog.parser.get_text(), dialog.chain.get_text(), dialog.update_interval.get_text(), dialog.regexp.get_text()])
-
-# Doesn't work in hildon-home
-# widget.timerversion += 1
-# if dialog.update_interval.get_text() != "" :
-# ussd_renewer (widget, 60000*int(dialog.update_interval.get_text()))
-
- dialog.destroy()
-
- if config == ["", "", "", "", ""] :
- widget.label.set_text("Click to update")
-
-def on_show_phelp(widget):
- dialog = pHelpDialog("Format help", "Reply would be passed to specified utility, output\n of utility would be shown to you.\n Format:\n% would be replaced by reply\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility")
- dialog.run()
- dialog.destroy()
-
-def on_show_chelp(widget):
- dialog = pHelpDialog("Format help", "Reply would be passed to specified utility after\nparser utility. May be used for logging, statistics etc.\n Format:\n% would be replaced by reply\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility")
- dialog.run()
- dialog.destroy()
-
-def on_show_reghelp(widget):
- dialog = pHelpDialog("Format help", "standard python regexps")
- dialog.run()
- dialog.destroy()
-
-def on_error_regexp(error):
- dialog = pHelpDialog( "Regexp syntax error", error )
- dialog.run()
- dialog.destroy()
+#=============== The widget itself ================
def get_color(logicalcolorname):
- settings = gtk.settings_get_default()
- color_style = gtk.rc_get_style_by_paths(settings, 'GtkButton', 'osso-logical-colors', gtk.Button)
- return color_style.lookup_color(logicalcolorname)
+ settings = gtk.settings_get_default()
+ color_style = gtk.rc_get_style_by_paths(settings, 'GtkButton', 'osso-logical-colors', gtk.Button)
+ return color_style.lookup_color(logicalcolorname)
class UssdWidgetPlugin(hildondesktop.HomePluginItem):
- def __init__(self):
- hildondesktop.HomePluginItem.__init__(self)
-
- self.process = None
- self.timerversion = 0 # Because threads in pyton are crap
- self.processing = 0
- self.error = 0
-
- colormap = self.get_screen().get_rgba_colormap()
- self.set_colormap (colormap)
-
- config = get_config()
-
- self.connect("button-press-event", ussd_renew)
-
- self.label = gtk.Label()
- self.label.set_padding(15, 10)
- self.label.set_size_request(-1,-1)
- self.set_size_request(-1,-1)
-
- self.vbox = gtk.HBox()
- self.vbox.add(self.label)
- self.add(self.vbox)
-
- self.set_settings(True)
- self.connect("show-settings", on_show_settings)
-
- self.vbox.show_all()
-
- if config :
- self.label.set_label("Data not available")
-# Should be uncommented only after thread bug fixed
-# ussd_renew (self, None)
-# Doesn't work in hildon-home
-# if config[3] != "" :
-# timed_renewer (self, 60000*int(config[3]))
- else :
- self.label.set_label("Configure me")
-
- def _expose(self, event):
- cr = self.window.cairo_create()
-
- # draw rounded rect
- width, height = self.allocation[2], self.allocation[3]
-
- #/* a custom shape, that could be wrapped in a function */
- x0 = 0 #/*< parameters like cairo_rectangle */
- y0 = 0
-
- radius = min(15, width/2, height/2) #/*< and an approximate curvature radius */
-
- x1 = x0 + width
- y1 = y0 + height
-
- cr.move_to (x0, y0 + radius)
- cr.arc (x0 + radius, y0 + radius, radius, 3.14, 1.5 * 3.14)
- cr.line_to (x1 - radius, y0)
- cr.arc (x1 - radius, y0 + radius, radius, 1.5 * 3.14, 0.0)
- cr.line_to (x1 , y1 - radius)
- cr.arc (x1 - radius, y1 - radius, radius, 0.0, 0.5 * 3.14)
- cr.line_to (x0 + radius, y1)
- cr.arc (x0 + radius, y1 - radius, radius, 0.5 * 3.14, 3.14)
-
- cr.close_path ()
-
- fg_color = get_color("ActiveTextColor")
-
- if self.processing :
- bg_color=fg_color
- else :
- bg_color=gtk.gdk.color_parse('#000000')
-
- cr.set_source_rgba (bg_color.red / 65535.0, bg_color.green/65535.0, bg_color.blue/65535.0, 0.7)
- cr.fill_preserve ()
-
- if self.error :
- cr.set_source_rgba (1.0, 0.0, 0.0, 0.5)
- else :
- cr.set_source_rgba (fg_color.red / 65535.0, fg_color.green / 65535.0, fg_color.blue / 65535.0, 0.7)
- cr.stroke ()
-
- def do_expose_event(self, event):
- self.chain(event)
- self._expose (event)
- self.vbox.do_expose_event (self, event)
+ def __init__(self):
+ hildondesktop.HomePluginItem.__init__(self)
+
+ self.processing = 0
+ self.error = 0
+ self.timeout_version = 0
+
+ colormap = self.get_screen().get_rgba_colormap()
+ self.set_colormap (colormap)
+
+ self.controller = USSD_Controller(self)
+
+# TODO Click event would be better
+ self.connect("button-press-event", self.controller.ussd_renew)
+
+ self.vbox = gtk.HBox()
+ self.add(self.vbox)
+
+ self.set_settings(True)
+ self.connect("show-settings", self.controller.on_show_settings)
+ self.label = gtk.Label("")
+ self.set_text(_("Click to update"))
+
+ self.vbox.add(self.label)
+ self.vbox.set_child_packing(self.label, False, False, 0, gtk.PACK_START)
+ self.label.set_padding(15, 10)
+ self.label.set_size_request(-1,-1)
+ self.set_size_request(-1,-1)
+ self.label.set_line_wrap (True)
+
+ self.vbox.show_all()
+ self.controller.get_config()
+ self.controller.reset_timed_renew()
+
+ def error_return (self):
+ if self.error == 1 and self.processing == 0:
+ self.set_text(self.text)
+ return False
+
+ # showfor =
+ # -1 - This is a permanent text message
+ # 0 - This is service message, but it shouldn't be hidden automatically
+ # >0 - This is service message, show permament message after showfor milliseconds
+ def set_text(self, text, showfor=-1):
+ if showfor > 0 :
+ # Show previous text after 5 seconds
+ gobject.timeout_add (showfor, self.error_return)
+ else :
+ if showfor == -1 :
+ self.text = text
+ self.label.set_text(text)
+
+ def get_text(self):
+ return self.text
+
+ def _expose(self, event):
+ cr = self.window.cairo_create()
+
+ # draw rounded rect
+ width, height = self.label.allocation[2], self.label.allocation[3]
+
+ #/* a custom shape, that could be wrapped in a function */
+ x0 = 0 #/*< parameters like cairo_rectangle */
+ y0 = 0
+
+ radius = min(15, width/2, height/2) #/*< and an approximate curvature radius */
+
+ x1 = x0 + width
+ y1 = y0 + height
+
+ cr.move_to (x0, y0 + radius)
+ cr.arc (x0 + radius, y0 + radius, radius, 3.14, 1.5 * 3.14)
+ cr.line_to (x1 - radius, y0)
+ cr.arc (x1 - radius, y0 + radius, radius, 1.5 * 3.14, 0.0)
+ cr.line_to (x1 , y1 - radius)
+ cr.arc (x1 - radius, y1 - radius, radius, 0.0, 0.5 * 3.14)
+ cr.line_to (x0 + radius, y1)
+ cr.arc (x0 + radius, y1 - radius, radius, 0.5 * 3.14, 3.14)
+
+ cr.close_path ()
+
+ fg_color = get_color("ActiveTextColor")
+
+ if self.processing :
+ bg_color=fg_color
+ else :
+ bg_color=gtk.gdk.color_parse('#000000')
+
+ cr.set_source_rgba (bg_color.red / 65535.0, bg_color.green/65535.0, bg_color.blue/65535.0, 0.7)
+ cr.fill_preserve ()
+
+ if self.error :
+ cr.set_source_rgba (1.0, 0.0, 0.0, 0.5)
+ else :
+ cr.set_source_rgba (fg_color.red / 65535.0, fg_color.green / 65535.0, fg_color.blue / 65535.0, 0.7)
+ cr.stroke ()
+
+ def do_expose_event(self, event):
+ self.chain(event)
+ self._expose (event)
+ self.vbox.do_expose_event (self, event)
hd_plugin_type = UssdWidgetPlugin
-gtk.gdk.threads_init()
# The code below is just for testing purposes.
# It allows to run the widget as a standalone process.
if __name__ == "__main__":
- gobject.type_register(hd_plugin_type)
- obj = gobject.new(hd_plugin_type, plugin_id="plugin_id")
- obj.show_all()
- gtk.gdk.threads_init()
- gtk.main()
+ import gobject
+ gobject.type_register(hd_plugin_type)
+ obj = gobject.new(hd_plugin_type, plugin_id="plugin_id")
+ obj.show_all()
+ gtk.main()