New release.
[ussd-widget] / ussd-widget / src / usr / lib / hildon-desktop / ussd-widget.py
index 8bc65b6..4854980 100755 (executable)
@@ -5,11 +5,13 @@ import gtk
 import hildon
 import hildondesktop
 import os
-from subprocess import *
 import cairo
+import pango
 import time
 import re
 import gettext
+import fcntl
+from subprocess import *
 
 try :
        t = gettext.translation('ussd-widget', '/usr/share/locale')
@@ -20,38 +22,97 @@ except IOError:
                return arg
        _ = retme
 
+ussd_languages = ["German", "English", "Italian", "French", "Spanish", "Dutch", "Swedish", "Danish", "Portuguese", "Finnish", "Norwegian", "Greek", "Turkish", "Reserved1", "Reserved2", "Unspecified"]
+
 # 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
+# TODO interface for queryng from scripts. For example query from one widget can change color of another widget
 
 class USSD_Controller:
        def __init__( self, widget ) :
                self.widget = widget
-               self.default_config = ["", "", "", "", "", ""]
+               # number, parser, chain, interval, regexp, width, execute_at_start, retry pattern, font, [name, always show], language 
+               self.default_config = ["", "", "", 0, "", 0, True, [], pango.FontDescription("Nokia Sans 18"), [_("Click to update"), False], 15]
                self.config = self.default_config
                self.timeout_version = 0
+               self.retry_version = 0
+               self.retry_state = 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"])
+               configname = os.getenv("HOME")+"/.ussdWidget.conf"
+               # Aquire lock
+               lockf = open(configname+".lock", 'a')
+               fcntl.flock(lockf,fcntl.LOCK_EX)
+
+               oldconfig=""
+               try:
+                       fconfig = open(configname,"r")
+                       #Read configuration of other instances
+                       my_section = False
+                       for line in fconfig :
+                               if line[0] == '%':
+                                       my_section = line[1:].strip() == self.id
+                               if not my_section:
+                                       oldconfig += line
+                       fconfig.close()
+               except:
+                       print _("Couldn't read previous config")
+
+               fconfig = open(configname,"w")
+               fconfig.seek(0)
+               fconfig.write(oldconfig)
+               fconfig.write("%"+self.id+"\n");
+               fconfig.writelines(["# 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(["#Update interval in minutes\n", "interval="+str(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.writelines(["#Widget width\n", "width="+str(self.config[5]), "\n"])
+               fconfig.writelines(["#Execute query at start\n", "query_at_start="+str(self.config[6]), "\n"])
+               fconfig.writelines(["#Retry pattern\n"])
+               fconfig.write("retry=")
+               first = True
+               for i in self.config[7]:
+                       if not first:
+                               fconfig.write ("-")
+                       fconfig.write(str(i))
+                       first = False
+               fconfig.write("\n")
+               fconfig.writelines(["#Font description\n", "font="+self.config[8].to_string(), "\n"])
+               fconfig.writelines(["#Font color\n", "text_color="+self.widget.get_text_color().to_string(), "\n"])
+               fconfig.writelines(["#Background color\n", "bg_color="+self.widget.get_bg_color().to_string(), "\n"])
+               fconfig.writelines(["#Widget name\n", "name="+self.config[9][0], "\n"])
+               fconfig.writelines(["#Always show widget name\n", "show_name="+str(self.config[9][1]), "\n"])
+               fconfig.writelines(["#USSD reply language\n", "language="+str(self.config[10]), "\n"])
                fconfig.close()
 
-       def get_config( self ):
+               fcntl.flock(lockf,fcntl.LOCK_UN)
+               lockf.close()
+
+       def get_config(self):
+               return self.config
+
+       def read_config( self, id ):
                try :
+                       self.id = id
                        config = open(os.getenv("HOME")+"/.ussdWidget.conf","r")
 
                        error = False
                        i = 0
+                       my_section = False
                        for line in config :
                                i += 1 
                                if line[0] == '#':
                                        continue
-                               line=line.split('=', 2)
+                               if line[0] == '%':
+                                       my_section = line[1:].strip() == id
+                                       continue
+
+                               if not my_section:
+                                       # This is config for another instace
+                                       continue
+
+                               line=line.split('=', 1)
                                
                                if len(line) != 2 :
                                        error = True
@@ -64,11 +125,78 @@ class USSD_Controller:
                                elif line[0] == "chain" :
                                        self.config[2] = line[1].strip()
                                elif line[0] == "interval" :
-                                       self.config[3] = line[1].strip()
+                                       try:
+                                               self.config[3] = int(line[1].strip())
+                                       except:
+                                               error = True
+                                               print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+                                               continue
                                elif line[0] == "regexp" :
                                        self.config[4] = line[1].strip()
                                elif line[0] == "width" :
-                                       self.config[5] = line[1].strip()
+                                       try:
+                                               self.config[5] = int(line[1].strip())
+                                       except:
+                                               error = True
+                                               print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+                                               continue
+                               elif line[0] == "query_at_start" :
+                                       if line[1].strip() == "True" :
+                                               self.config[6] = True
+                                       else :
+                                               self.config[6] = False
+                               elif line[0] == "retry" :
+                                       line[1] = line[1].strip()
+                                       if line[1] != "":
+                                               line[1] = line[1].split("-")
+                                               i = 0
+                                               while i < len(line[1]) :
+                                                       try:
+                                                               line[1][i] = int(line[1][i])
+                                                       except:
+                                                               error = True
+                                                               print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+                                                       i += 1
+                                               self.config[7] = line[1]
+                                       else:
+                                               self.config[7] = []
+                                               continue
+                               elif line[0] == "font" :
+                                       try:
+                                               self.config[8] = pango.FontDescription(line[1].strip())
+                                       except:
+                                               error = True
+                                               print _("Error reading config on line %(line)d. Pango font description expected.")%{"line":i}
+                                               continue
+                               elif line[0] == "bg_color" :
+                                       try:
+                                               self.widget.set_bg_color(gtk.gdk.color_parse(line[1].strip()))
+                                       except:
+                                               error = True
+                                               print _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
+                               elif line[0] == "text_color" :
+                                       try:
+                                               self.widget.set_text_color(gtk.gdk.color_parse(line[1].strip()))
+                                       except:
+                                               error = True
+                                               print _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
+                               elif line[0] == "name" :
+                                       self.config[9][0] = line[1].strip()
+                               elif line[0] == "show_name" :
+                                       if line[1].strip() == "True" :
+                                               self.config[9][1] = True
+                                       else :
+                                               self.config[9][1] = False
+                               elif line[0] == "language" :
+                                       try:
+                                               if int(line[1].strip()) >=0 and int(line[1].strip()) < len(ussd_languages):
+                                                       self.config[10] = int(line[1].strip())
+                                               else:
+                                                       error = True
+                                                       print _("Error reading config on line %(line)d. Unknown language code.")%{"line":i}
+                                       except:
+                                               error = True
+                                               print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
                                else :
                                        error = True
                                        print _("Error reading config on line %(line)d. Unexpected variable: ")%{"line":i}+line[0]
@@ -86,39 +214,71 @@ class USSD_Controller:
                        self.widget.set_text (_("Config error"), 0)
                        print _("IO error while reading config")
 
-                       return self.default.config
+                       return self.default_config
 
        def on_show_settings( self, widget ) :
-               dialog = UssdConfigDialog(self.config)
-               dialog.run()
+               dialog = UssdConfigDialog(self.config, self.widget.get_bg_color(), self.widget.get_text_color())
+
+               while True:
+                       if dialog.run() != gtk.RESPONSE_OK :
+                               dialog.destroy()
+                               return
+
+                       test = check_regexp(dialog.regexp.get_text()) 
+                       if test :
+                               dialog.on_error_regexp(test)
+                               continue
+
+                       # Check, that we have ussd number
+                       if not check_number(dialog.ussdNumber.get_text()):
+                               dialog.on_error_ussd_number()
+                               continue
+
+                       # Parse retry pattern
+                       retry = dialog.retryEdit.get_text().strip()
+                       if retry != "" :
+                               retry = retry.split("-")
+                               i = 0
+                               while i < len(retry) :
+                                       try:
+                                               retry[i] = int(retry[i])
+                                       except:
+                                               dialog.on_error_retry_pattern()
+                                               break 
+                                       i += 1
+                       
+                               if i < len(retry):
+                                       continue
+                       else :
+                               retry = []
 
-               if check_regexp( dialog.regexp.get_text() ) :
-                       return
+                       break
 
-# 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.update_interval.get_value(), 
                        dialog.regexp.get_text(),
-                       dialog.widthEdit.get_text()
+                       dialog.widthEdit.get_value(),
+                       dialog.query_at_start.get_active(),
+                       retry,
+                       dialog.font,
+                       [dialog.wname.get_text(), dialog.show_name.get_active()],
+                       dialog.language.get_active()
                ]
 
+               widget.set_bg_color(dialog.bg_color)
+               widget.set_text_color(dialog.text_color)
+
                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)
-               
+               widget.set_width(self.config[5])        
                self.reset_timed_renew()
-               
+               self.widget.label.modify_font(self.config[8])
+
                dialog.destroy()
-    
+
                # Before running this function widget wasn't configured
                if self.config == self.default_config:
                        self.widget.set_text(_("Click to update"))
@@ -140,13 +300,17 @@ class USSD_Controller:
                        return False
 
                print (_("serious problems in program logic"))
+               # This will force widget to show error message
+               self.cb_reply = ""
+               self.cb_ready = 1
+               self.process_reply()
                return False
 
 
-       def call_external_script( self, ussd_code ):
+       def call_external_script( self, ussd_code, language ):
                self.cb_ready = 0
                self.cb_reply = "";
-               p = Popen(['/usr/bin/ussdquery.py', ussd_code], stdout=PIPE)
+               p = Popen(['/usr/bin/ussdquery.py', ussd_code, ussd_languages[language]], 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):
@@ -154,7 +318,7 @@ class USSD_Controller:
                        if self.config :
                                widget.processing = 1
                                widget.set_text(_("Processing"), 0)
-                               self.call_external_script( self.config[0] )
+                               self.call_external_script( self.config[0], self.config[10] )
                        else :
                                widget.processing = 0
                                widget.error = 1
@@ -166,6 +330,12 @@ class USSD_Controller:
                if reply == "" :
                        self.widget.error = 1
                        self.widget.set_text (_("Error"), 5000)
+                       if self.retry_state == len(self.config[7]):
+                               self.retry_version += 1
+                               self.retry_state = 0
+                       else :
+                               self.retry_timer = gobject.timeout_add (1000*self.config[7][self.retry_state], self.retry_renew, self.retry_version)
+                               self.retry_state += 1
                else :
                        self.widget.error = 0
                        # Pass to parser
@@ -193,10 +363,16 @@ class USSD_Controller:
                self.ussd_renew(self.widget, None)
                return True
 
+       def retry_renew(self,version):
+               if self.widget.error == 0 or self.widget.processing == 1 or version < self.retry_version :
+                       return False
+               self.ussd_renew(self.widget, None)
+               return False
+
        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)
+               if self.config[3] != 0 :
+                       self.timer = gobject.timeout_add (60000*self.config[3], self.timed_renew, self.timeout_version)
 
 class pHelpDialog(gtk.Dialog):
        def __init__(self, heading, text):
@@ -210,10 +386,15 @@ class pHelpDialog(gtk.Dialog):
                self.parent
 
 class UssdConfigDialog(gtk.Dialog):
-       def __init__(self, config):
+       def __init__(self, config, bg_color, text_color):
                gtk.Dialog.__init__(self, _("USSD widget"), None, 
                        gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
                        (_("Save").encode("utf-8"), gtk.RESPONSE_OK))
+
+               self.font = config[8]
+               self.bg_color = bg_color
+               self.text_color = text_color
+
                self.set_size_request(-1, 400)
                self.ussdNumber = hildon.Entry(gtk.HILDON_SIZE_AUTO)
                self.ussdNumber.set_text(config[0])
@@ -221,13 +402,48 @@ class UssdConfigDialog(gtk.Dialog):
                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.update_interval = hildon.NumberEditor(0, 9999)
+               self.update_interval.set_value(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])
-
+               self.widthEdit = hildon.NumberEditor(0, 1000)
+               self.widthEdit.set_value(config[5])
+               self.retryEdit = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+
+
+               #selector = hildon.hildon_touch_selector_new_text()
+               selector = hildon.TouchSelector(text=True)
+               for i in ussd_languages:
+                       selector.append_text(i)
+               self.language = hildon.PickerButton(gtk.HILDON_SIZE_AUTO, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
+               self.language.set_selector(selector)
+               self.language.set_active(config[10])
+               self.language.set_title(_("USSD reply language"))
+               self.language.set_size_request(-1, -1)
+
+               self.wname = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+               self.wname.set_text(config[9][0])
+               self.show_name = gtk.CheckButton(_("Always show name"))
+               self.show_name.set_active(config[9][1])
+
+               text = ""
+               for i in config[7]:
+                       if text != "":
+                               text += "-"
+                       text += str(i)
+               self.retryEdit.set_text(text)
+
+               self.query_at_start = gtk.CheckButton(_("Execute query on start"))
+               self.query_at_start.set_active(config[6])
+
+               self.fontButton = gtk.Button(_("Font"))
+               self.fontButton.connect("clicked", self.on_show_font_selection)
+
+               self.colorButton = gtk.Button(_("Background color"))
+               self.colorButton.connect("clicked", self.on_show_color_selection)
+               self.textColorButton = gtk.Button(_("Text color"))
+               self.textColorButton.connect("clicked", self.on_show_text_color_selection)
+               
                phelp = gtk.Button("?")
                phelp.connect("clicked", self.on_show_phelp)
 
@@ -237,6 +453,9 @@ class UssdConfigDialog(gtk.Dialog):
                reghelp = gtk.Button("?")
                reghelp.connect("clicked", self.on_show_reghelp)
 
+               retryhelp = gtk.Button("?")
+               retryhelp.connect("clicked", self.on_show_retryhelp)
+
                area = hildon.PannableArea()
                self.vbox.add(area)
                vbox = gtk.VBox()
@@ -251,6 +470,17 @@ class UssdConfigDialog(gtk.Dialog):
                numberBox.add(self.ussdNumber)
                vbox.add(numberBox)
 
+               vbox.add(self.language)
+
+               vbox.add(self.query_at_start)
+
+               nameBox = gtk.HBox()
+               self.show_name.set_size_request(100, -1)
+               self.wname.set_size_request(100, -1)
+               nameBox.add(self.show_name)
+               nameBox.add(self.wname)
+               vbox.add(nameBox)
+
                parserBox = gtk.HBox()
                parserLabel = gtk.Label(_("Parser"))
                parserLabel.set_alignment(0,0)
@@ -285,8 +515,8 @@ class UssdConfigDialog(gtk.Dialog):
                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)
+               widthLabel.set_size_request(140, -1)
+               self.widthEdit.set_size_request(50, -1)
                symbolsLabel.set_size_request(40,-1)
                widthBox.add(widthLabel)
                widthBox.add(self.widthEdit)
@@ -297,14 +527,30 @@ class UssdConfigDialog(gtk.Dialog):
                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)
+               updateLabel.set_size_request(140, -1)
+               self.update_interval.set_size_request(50, -1)
                minutesLabel.set_size_request(40, -1)
                updateBox.add(updateLabel)
                updateBox.add(self.update_interval)
                updateBox.add(minutesLabel)
                vbox.add(updateBox)
 
+               retryBox = gtk.HBox()
+               retryLabel = gtk.Label(_("Retry pattern"))
+               retryLabel.set_alignment(0,0)
+               retryLabel.set_size_request(200, -1)
+               retryhelp.set_size_request(10, -1)
+               retryBox.add(retryLabel)
+               retryBox.add(retryhelp)
+               vbox.add(retryBox)
+               vbox.add(self.retryEdit)                
+               
+               viewBox = gtk.HBox()
+               viewBox.add(self.fontButton)
+               viewBox.add(self.textColorButton)
+               viewBox.add(self.colorButton)
+               vbox.add(viewBox)
+
                self.show_all()
                self.parent
 
@@ -320,21 +566,54 @@ class UssdConfigDialog(gtk.Dialog):
                dialog.destroy()
 
        def on_show_reghelp(self, widget):
-               dialog = pHelpDialog(_("Format help"), _("standard python regexps"))
+               dialog = pHelpDialog(_("Format help"), _("Standard python regexps. Use\n (.+?[\d\,\.]+)\n to delete everything after first number."))
                dialog.run()
                dialog.destroy()
 
+       def on_show_retryhelp(self, widget):
+               dialog = pHelpDialog(_("Format help"), _("Pauses between attemps (in seconds), delimited by -. For example 15-15-300 means \"In case of failure wait 15 seconds, try again, on failure wait 15 more secodns and try again, on failure make last attempt after 5 minutes\""))
+               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 )
+       def on_error_ussd_number(self):
+               dialog = pHelpDialog(_("Incorrect USSD number"), _("USSD number should contain only digits, +, * or #") )
                dialog.run()
                dialog.destroy()
 
+       def on_error_retry_pattern(self):
+               dialog = pHelpDialog(_("Incorrect retry pattern"), _("Retry pattern should contain only numbers, delimited by -") )
+               dialog.run()
+               dialog.destroy()
+
+       def on_show_color_selection (self, event):
+               colorDialog = gtk.ColorSelectionDialog(_("Choose background color"))
+               colorDialog.colorsel.set_current_color(self.bg_color)
+               if colorDialog.run() == gtk.RESPONSE_OK :
+                       self.bg_color = colorDialog.colorsel.get_current_color()
+               colorDialog.destroy()
+
+       def on_show_text_color_selection (self, event):
+               colorDialog = gtk.ColorSelectionDialog(_("Choose text color"))
+               colorDialog.colorsel.set_current_color(self.text_color)
+               if colorDialog.run() == gtk.RESPONSE_OK :
+                       self.text_color = colorDialog.colorsel.get_current_color()
+               colorDialog.destroy()
+       
+       def on_show_font_selection (self, event):
+               fontDialog = gtk.FontSelectionDialog(_("Choose a font"))
+               fontDialog.set_font_name(self.font.to_string())
+
+               if fontDialog.run() != gtk.RESPONSE_OK :
+                       fontDialog.destroy()
+                       return
+
+               self.font = pango.FontDescription (fontDialog.get_font_name())
+               fontDialog.destroy()
 
 def smart_split_string (str, query) :
        word = ""
@@ -374,9 +653,14 @@ def check_regexp(regexp):
        try :
                re.compile( regexp )
        except Exception, e:
-                       on_error_regexp( str( e ) )
-                       return 1
-       return 0
+                       return str(e)
+       return False
+
+def check_number(number):
+       for s in number :
+               if not (s in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "+", "*", "#"]) :
+                       return False
+       return True
 
 #=============== The widget itself ================
 
@@ -388,8 +672,10 @@ def get_color(logicalcolorname):
 class UssdWidgetPlugin(hildondesktop.HomePluginItem):
        def __init__(self):
                hildondesktop.HomePluginItem.__init__(self)
-               
+       
                self.processing = 0
+               self.bg_color=gtk.gdk.color_parse('#000000')
+               self.text_color=gtk.gdk.color_parse('#ffffff')
                self.error = 0
                self.timeout_version = 0
 
@@ -407,7 +693,6 @@ class UssdWidgetPlugin(hildondesktop.HomePluginItem):
                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)
@@ -417,9 +702,17 @@ class UssdWidgetPlugin(hildondesktop.HomePluginItem):
                self.label.set_line_wrap (True)
 
                self.vbox.show_all()
-               self.controller.get_config()
-               self.controller.reset_timed_renew()
 
+       def do_show(self):
+               config = self.controller.read_config(self.get_applet_id())
+               self.set_width(config[5])
+               self.set_text("")               
+               if config[6]:
+                       self.controller.ussd_renew(self, None)
+
+               self.controller.reset_timed_renew()
+               hildondesktop.HomePluginItem.do_show(self)
+       
        def error_return (self):
                if self.error == 1 and self.processing == 0:
                        self.set_text(self.text)
@@ -436,11 +729,34 @@ class UssdWidgetPlugin(hildondesktop.HomePluginItem):
                else :
                        if showfor == -1 :
                                self.text = text
+               
+               config = self.controller.get_config()
+               if config[9][1] or text == "":
+                       text = config[9][0]+text
                self.label.set_text(text)
 
        def get_text(self):
                return self.text
 
+       def set_width(self, width):
+               if width != 0:
+                       self.label.set_width_chars (width)
+               else :
+                       self.label.set_width_chars(-1)
+
+       def set_bg_color(self, color):
+               self.bg_color = color
+
+       def get_bg_color(self):
+               return self.bg_color
+
+       def set_text_color(self, color):
+               self.label.modify_fg(gtk.STATE_NORMAL, color)           
+               self.text_color = color
+
+       def get_text_color(self):
+               return self.text_color
+
        def _expose(self, event):
                cr = self.window.cairo_create()
 
@@ -472,7 +788,7 @@ class UssdWidgetPlugin(hildondesktop.HomePluginItem):
                if self.processing :
                        bg_color=fg_color
                else :
-                       bg_color=gtk.gdk.color_parse('#000000')
+                       bg_color=self.bg_color
 
                cr.set_source_rgba (bg_color.red / 65535.0, bg_color.green/65535.0, bg_color.blue/65535.0, 0.7)
                cr.fill_preserve ()