Fix zimbie process. Add more logging.
authorAlexey Guseynov <kibergus@gmail.com>
Mon, 9 Apr 2012 19:50:43 +0000 (23:50 +0400)
committerAlexey Guseynov <kibergus@gmail.com>
Mon, 9 Apr 2012 19:50:43 +0000 (23:50 +0400)
ussd-widget/src/usr/lib/hildon-desktop/ussd-widget.py

index a84841c..8ac0d02 100755 (executable)
@@ -24,14 +24,19 @@ import gsmdecode
 import sys
 from dbus.mainloop.glib import DBusGMainLoop
 
+# Would be truncated on every reboot, and shouldn't write 
+# anythong if things go right way so it is OK not to have logrotate
+log = open("/var/log/ussd-widget.log")
+print >> sys.stderr, "Writing log to /var/log/ussd-widget.log"
+
 try :
-       t = gettext.translation('ussd-widget', '/usr/share/locale')
-       _ = t.ugettext
+    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
+    print >> log, "Translation file for your language not found"
+    def retme(arg):
+        return arg
+    _ = retme
 
 ussd_languages = ["German", "English", "Italian", "French", "Spanish", "Dutch", "Swedish", "Danish", "Portuguese", "Finnish", "Norwegian", "Greek", "Turkish", "Reserved1", "Reserved2", "Unspecified"]
 ussd_languages_localized = [_("German"), _("English"), _("Italian"), _("French"), _("Spanish"), _("Dutch"), _("Swedish"), _("Danish"), _("Portuguese"), _("Finnish"), _("Norwegian"), _("Greek"), _("Turkish"), _("Reserved1"), _("Reserved2"), _("Unspecified")]
@@ -40,1084 +45,1106 @@ ussd_languages_localized = [_("German"), _("English"), _("Italian"), _("French")
 # how TODO widget vertical minimum size policy
 
 class USSD_Controller:
-       def __init__( self, widget ) :
-               self.widget = widget
-               # number, parser, chain, interval, regexp, width, execute_at_start, retry pattern, font, name, language, show_message_box, message_box_parser, additional arguments, regexp group, use SMS listener, SMS number, SMS regexp, SMS timeout
-               self.default_config = ["", "", "", 0, "", 0, True, [], pango.FontDescription("Nokia Sans 18"), _("Click to update"), 15, False, "", "", 1, False, "", "", 60]
-               self.config = self.default_config
-               self.timeout_version = 0
-               self.retry_version = 0
-               self.retry_state = 0
-               self.sms_counter = 0
-               self.sms_reply = ""
-
-       def save_config( self ) :
-               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 for widget\n", "parser="+self.config[1], "\n"])
-               fconfig.writelines(["#Parser command for banner\n", "parser_box="+self.config[12], "\n"])
-               fconfig.writelines(["#Chain command\n", "chain="+self.config[2], "\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="+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], "\n"])
-               fconfig.writelines(["#Show banner\n", "show_box="+str(self.config[11]), "\n"])
-               fconfig.writelines(["#USSD reply language\n", "language="+str(self.config[10]), "\n"])
-               fconfig.writelines(["#Additional ussdquery.py arguments\n", "args="+self.config[13], "\n"])
-               fconfig.writelines(["#Regexp matching group\n", "reggroup="+str(self.config[14]), "\n"])
-               fconfig.writelines(["#Use SMS listener\n", "listen_sms="+str(self.config[15]), "\n"])
-               fconfig.writelines(["#Number,from which SMS should come\n", "sms_number="+self.config[16], "\n"])
-               fconfig.writelines(["#SMS RegExp pattern\n", "sms_regexp="+self.config[17], "\n"])
-               fconfig.writelines(["#SMS timeout\n", "sms_timeout="+str(self.config[18]), "\n"])
-               fconfig.close()
-
-               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
-                               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
-                                       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] == "parser_box" :
-                                       self.config[12] = line[1].strip()
-                               elif line[0] == "chain" :
-                                       self.config[2] = line[1].strip()
-                               elif line[0] == "interval" :
-                                       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" :
-                                       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] = line[1].strip()
-                               elif line[0] == "show_box" :
-                                       if line[1].strip() == "True" :
-                                               self.config[11] = True
-                                       else :
-                                               self.config[11] = 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}
-                               elif line[0] == "args" :
-                                       self.config[13] = line[1].strip()
-                               elif line[0] == "reggroup" :
-                                       try:
-                                               self.config[14] = int(line[1].strip())
-                                       except:
-                                               error = True
-                                               print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
-                                               continue
-                               elif line[0] == "listen_sms" :
-                                       if line[1].strip() == "True" :
-                                               self.config[15] = True
-                                       else :
-                                               self.config[15] = False
-                               elif line[0] == "sms_number" :
-                                       self.config[16] = line[1].strip()
-                               elif line[0] == "sms_regexp" :
-                                       self.config[17] = line[1].strip()
-                               elif line[0] == "sms_timeout" :
-                                       try:
-                                               self.config[18] = int(line[1].strip())
-                                       except:
-                                               error = True
-                                               print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
-                                               continue
-                               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, self.widget.get_bg_color(), self.widget.get_text_color(), self.id)
-
-               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
-               
-                       if not check_number(dialog.sms_number.get_text()):
-                               dialog.on_error_sms_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 = []
-
-                       break
-
-               self.config = [
-                       dialog.ussdNumber.get_text(), 
-                       dialog.parser.get_text(), 
-                       dialog.chain.get_text(), 
-                       dialog.update_interval.get_value(), 
-                       dialog.regexp.get_text(),
-                       dialog.widthEdit.get_value(),
-                       dialog.query_at_start.get_active(),
-                       retry,
-                       dialog.font,
-                       dialog.wname.get_text(),
-                       dialog.language.get_active(),
-                       dialog.show_box.get_active(),
-                       dialog.b_parser.get_text(),
-                       dialog.args.get_text(),
-                       dialog.reggroup.get_value(),
-                       dialog.sms_listener.get_active(),
-                       dialog.sms_number.get_text(),
-                       dialog.sms_regexp.get_text(),
-                       dialog.sms_timeout.get_value() 
-               ]
-
-               widget.set_bg_color(dialog.bg_color)
-               widget.set_text_color(dialog.text_color)
-
-               self.save_config()
-
-               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"))
-               return
-
-       def handle_sms(self, pdumsg, msgcenter, message, sendernumber):
-               # Timeout was recieved first
-               if self.sms_ready:
-                       return
-
-               if self.config[16] == "" or self.config[16] == sendernumber:
-                       pdu = gsmdecode.decode_pdu (pdumsg)
-                       if pdu != None :
-                               self.sms_reply += pdu['user_data']
-                               if not pdu['part']:
-                                       if self.config[17] == "" or re.search( self.config[17], message, re.MULTILINE | re.UNICODE ):
-                                               self.sms_ready = True
-                                               self.sms_signal.remove()
-                                               self.process_reply()
-
-       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.ussd_ready = True
-                       self.process_reply()
-                       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, language ):
-               self.cb_ready = 0
-               self.cb_reply = "";
-               p = subprocess.Popen(['/usr/bin/ussdquery.py', ussd_code, "-l", ussd_languages[language]] + smart_split_string(self.config[13],"%","&"), stdout=subprocess.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.ussd_ready = False
-                               self.sms_ready = False
-                               self.sms_reply = ""
-
-                               if self.config[15]:
-                                       self.sms_counter += 1
-                                       self.retry_timer = gobject.timeout_add (1000*self.config[18], self.sms_timeout, self.sms_counter)
-                                       
-                                       self.bus = dbus.SystemBus()
-                                       self.sms_signal = self.bus.add_signal_receiver(self.handle_sms, path='/com/nokia/phone/SMS',   dbus_interface='Phone.SMS', signal_name='IncomingSegment')
-
-                               self.call_external_script( self.config[0], self.config[10] )
-                       else :
-                               widget.processing = 0
-                               widget.error = 1
-                               widget.set_text(_("No config"), 0)
-
-       def process_reply( self ):
-               if not self.ussd_ready or not self.sms_ready and self.config[15]:
-                       return
-
-               reply = self.cb_reply.strip()
-               sms_reply = self.sms_reply.strip()
-               
-               if reply == "" or self.config[15] and sms_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
-                       # Apply regexp
-                       reresult1 = reresult2 = None
-                       if self.config[4] != "":
-                               reresult1 = re.search( self.config[4], reply, re.MULTILINE | re.UNICODE )
-                       if self.config[17] != "":
-                               reresult2 = re.search( self.config[17], sms_reply, re.MULTILINE | re.UNICODE )
-                       w_reply = b_reply = reply
-                       if self.widget.error == 0:
-                               # Pass to box parser
-                               if self.config[12] != "" and self.config[11]:
-                                       try:
-                                               p = subprocess.Popen(smart_split_string(self.config[12], reply, sms_reply, reresult1, reresult2), stdout=subprocess.PIPE)
-                                               b_reply = p.communicate()[0].strip()
-                                       except Exception, e:
-                                               print _("Couldn't exec banner parser:")+str(e)
-                                               self.widget.error = 1
-                               else:
-                                       if self.config[4] != "":
-                                               try :
-                                                       b_reply = reresult1.group( self.config[14] )
-                                               except Exception, e:
-                                                       self.widget.error = 1
-                                                       b_reply = _("Group not found: \n") + reply
-                                        
-                               # Pass to widget parser
-                               if self.config[1] != "":
-                                       try:
-                                               p = subprocess.Popen(smart_split_string(self.config[1], reply, sms_reply, reresult1, reresult2), stdout=subprocess.PIPE)
-                                               w_reply = p.communicate()[0].strip()
-                                       except Exception, e:
-                                               print _("Couldn't exec widget parser:")+str(e)
-                                               self.widget.error = 1
-                               else:
-                                       if self.config[4] != "":
-                                               try :
-                                                       w_reply = reresult1.group( self.config[14] )
-                                               except Exception, e:
-                                                       self.widget.error = 1
-                                                       w_reply = _("Group not found: \n") + reply
-                               # Pass to chain
-                               if self.config[2] != "":
-                                       try:
-                                               p = subprocess.Popen(smart_split_string(self.config[2], reply, sms_reply, reresult1, reresult2))
-                                       except Exception, e:
-                                               print _("Couldn't exec chain:")+str(e)
-                                               self.widget.error = 1
-                       if self.config[11]:
-                               banner = hildon.hildon_banner_show_information (self.widget, "", b_reply)
-                               banner.set_timeout (5000)
-                               b_reply
-                       self.widget.set_text(w_reply)
-               self.widget.processing = 0
-
-       def sms_timeout(self, version):
-               if version == self.sms_counter :
-                       self.sms_reply = ""
-                       self.sms_ready = True
-                       self.sms_signal.remove()
-                       self.process_reply()
-               return False
-
-       def timed_renew(self, version):
-               if version < self.timeout_version :
-                       return False
-               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] != 0 :
-                       self.timer = gobject.timeout_add (60000*self.config[3], self.timed_renew, self.timeout_version)
+    def __init__( self, widget ) :
+        self.widget = widget
+        # number, parser, chain, interval, regexp, width, execute_at_start,
+        # retry pattern, font, name, language, show_message_box,
+        # message_box_parser, additional arguments, regexp group, 
+        # use SMS listener, SMS number, SMS regexp, SMS timeout
+        self.default_config = ["", "", "", 0, "", 0, True, [],\
+            pango.FontDescription("Nokia Sans 18"), _("Click to update"),\
+            15, False, "", "", 1, False, "", "", 60]
+        self.config = self.default_config
+        self.timeout_version = 0
+        self.retry_version = 0
+        self.retry_state = 0
+        self.sms_counter = 0
+        self.sms_reply = ""
+
+    def save_config( self ) :
+        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 >> log, _("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 for widget\n", "parser="+self.config[1], "\n"])
+        fconfig.writelines(["#Parser command for banner\n", "parser_box="+self.config[12], "\n"])
+        fconfig.writelines(["#Chain command\n", "chain="+self.config[2], "\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="+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], "\n"])
+        fconfig.writelines(["#Show banner\n", "show_box="+str(self.config[11]), "\n"])
+        fconfig.writelines(["#USSD reply language\n", "language="+str(self.config[10]), "\n"])
+        fconfig.writelines(["#Additional ussdquery.py arguments\n", "args="+self.config[13], "\n"])
+        fconfig.writelines(["#Regexp matching group\n", "reggroup="+str(self.config[14]), "\n"])
+        fconfig.writelines(["#Use SMS listener\n", "listen_sms="+str(self.config[15]), "\n"])
+        fconfig.writelines(["#Number,from which SMS should come\n", "sms_number="+self.config[16], "\n"])
+        fconfig.writelines(["#SMS RegExp pattern\n", "sms_regexp="+self.config[17], "\n"])
+        fconfig.writelines(["#SMS timeout\n", "sms_timeout="+str(self.config[18]), "\n"])
+        fconfig.close()
+
+        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
+                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
+                    print >> log, _("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] == "parser_box" :
+                    self.config[12] = line[1].strip()
+                elif line[0] == "chain" :
+                    self.config[2] = line[1].strip()
+                elif line[0] == "interval" :
+                    try:
+                        self.config[3] = int(line[1].strip())
+                    except:
+                        error = True
+                        print >> log, _("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" :
+                    try:
+                        self.config[5] = int(line[1].strip())
+                    except:
+                        error = True
+                        print >> log, _("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 >> log, _("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 >> log, _("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 >> log, _("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 >> log, _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
+                elif line[0] == "name" :
+                    self.config[9] = line[1].strip()
+                elif line[0] == "show_box" :
+                    if line[1].strip() == "True" :
+                        self.config[11] = True
+                    else :
+                        self.config[11] = 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 >> log, _("Error reading config on line %(line)d. Unknown language code.")%{"line":i}
+                    except:
+                        error = True
+                        print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+                elif line[0] == "args" :
+                    self.config[13] = line[1].strip()
+                elif line[0] == "reggroup" :
+                    try:
+                        self.config[14] = int(line[1].strip())
+                    except:
+                        error = True
+                        print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+                        continue
+                elif line[0] == "listen_sms" :
+                    if line[1].strip() == "True" :
+                        self.config[15] = True
+                    else :
+                        self.config[15] = False
+                elif line[0] == "sms_number" :
+                    self.config[16] = line[1].strip()
+                elif line[0] == "sms_regexp" :
+                    self.config[17] = line[1].strip()
+                elif line[0] == "sms_timeout" :
+                    try:
+                        self.config[18] = int(line[1].strip())
+                    except:
+                        error = True
+                        print >> log, _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
+                        continue
+                else :
+                    error = True
+                    print >> log, _("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 >> log, _("IO error while reading config")
+
+            return self.default_config
+
+    def on_show_settings( self, widget ) :
+        dialog = UssdConfigDialog(self.config, self.widget.get_bg_color(), self.widget.get_text_color(), self.id)
+
+        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
+        
+            if not check_number(dialog.sms_number.get_text()):
+                dialog.on_error_sms_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 = []
+
+            break
+
+        self.config = [
+            dialog.ussdNumber.get_text(), 
+            dialog.parser.get_text(), 
+            dialog.chain.get_text(), 
+            dialog.update_interval.get_value(), 
+            dialog.regexp.get_text(),
+            dialog.widthEdit.get_value(),
+            dialog.query_at_start.get_active(),
+            retry,
+            dialog.font,
+            dialog.wname.get_text(),
+            dialog.language.get_active(),
+            dialog.show_box.get_active(),
+            dialog.b_parser.get_text(),
+            dialog.args.get_text(),
+            dialog.reggroup.get_value(),
+            dialog.sms_listener.get_active(),
+            dialog.sms_number.get_text(),
+            dialog.sms_regexp.get_text(),
+            dialog.sms_timeout.get_value() 
+        ]
+
+        widget.set_bg_color(dialog.bg_color)
+        widget.set_text_color(dialog.text_color)
+
+        self.save_config()
+
+        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"))
+        return
+
+    def handle_sms(self, pdumsg, msgcenter, message, sendernumber):
+        # Timeout was recieved first
+        if self.sms_ready:
+            return
+
+        if self.config[16] == "" or self.config[16] == sendernumber:
+            pdu = gsmdecode.decode_pdu (pdumsg)
+            if pdu != None :
+                self.sms_reply += pdu['user_data']
+                if not pdu['part']:
+                    if self.config[17] == "" or re.search( self.config[17], message, re.MULTILINE | re.UNICODE ):
+                        self.sms_ready = True
+                        self.sms_signal.remove()
+                        self.process_reply()
+
+    def callback_ussd_data(self, source, condition, process):
+        if condition == gobject.IO_IN or condition == gobject.IO_PRI:
+            data = source.read()
+            self.cb_reply += data
+            return True
+
+        if condition == gobject.IO_ERR:
+            print >> log, "Communication error occured"
+            # This will force widget to show error message
+            self.cb_reply = ""
+
+        if condition == gobject.IO_HUP:
+            # Pipe is broken, so ussd-query.py is already terminating
+            # and we wouldn't wait fot it too long
+            retcode = process.wait()
+            if retcode != 0:
+                self.cb_reply = ""
+
+        self.ussd_ready = True
+        self.process_reply()
+        return False
+
+    def callback_ussd_error(self, source, condition):
+        if condition == gobject.IO_IN or condition == gobject.IO_PRI:
+            self.error_message += source.read()
+        else:
+            if self.error_message != "":
+                print >> log, self.error_message
+
+    def call_external_script(self, ussd_code, language):
+        self.cb_reply = "";
+        process = subprocess.Popen(
+                    ['/usr/bin/ussdquery.py', ussd_code, "-l", ussd_languages[language]] +\
+                        smart_split_string(self.config[13],"%","&"),
+                    stdin=subprocess.PIPE,
+                    stdout=subprocess.PIPE, 
+                    stderr=subprocess.PIPE)
+        process.stdin.close()
+        gobject.io_add_watch(
+                    p.stdout, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR,
+                    self.callback_ussd_data,
+                    process)
+        self.error_message = "";
+        gobject.io_add_watch(
+                    p.stderr, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR,
+                    self.callback_ussd_error)
+
+    def ussd_renew(self, widget, event):
+        if self.widget.processing == 0:
+            if self.config :
+                widget.processing = 1
+                widget.set_text(_("Processing"), 0)
+
+                self.ussd_ready = False
+                self.sms_ready = False
+                self.sms_reply = ""
+
+                if self.config[15]:
+                    self.sms_counter += 1
+                    self.retry_timer = gobject.timeout_add (1000*self.config[18], self.sms_timeout, self.sms_counter)
+                    
+                    self.bus = dbus.SystemBus()
+                    self.sms_signal = self.bus.add_signal_receiver(self.handle_sms, path='/com/nokia/phone/SMS',   dbus_interface='Phone.SMS', signal_name='IncomingSegment')
+
+                self.call_external_script( self.config[0], self.config[10] )
+            else :
+                widget.processing = 0
+                widget.error = 1
+                widget.set_text(_("No config"), 0)
+
+    def process_reply( self ):
+        if not self.ussd_ready or not self.sms_ready and self.config[15]:
+            return
+
+        reply = self.cb_reply.strip()
+        sms_reply = self.sms_reply.strip()
+        
+        if reply == "" or self.config[15] and sms_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
+            # Apply regexp
+            reresult1 = reresult2 = None
+            if self.config[4] != "":
+                reresult1 = re.search( self.config[4], reply, re.MULTILINE | re.UNICODE )
+            if self.config[17] != "":
+                reresult2 = re.search( self.config[17], sms_reply, re.MULTILINE | re.UNICODE )
+            w_reply = b_reply = reply
+            if self.widget.error == 0:
+                # Pass to box parser
+                if self.config[12] != "" and self.config[11]:
+                    try:
+                        p = subprocess.Popen(smart_split_string(self.config[12], reply, sms_reply, reresult1, reresult2), stdout=subprocess.PIPE)
+                        b_reply = p.communicate()[0].strip()
+                    except Exception, e:
+                        print >> log, _("Couldn't exec banner parser:")+str(e)
+                        self.widget.error = 1
+                else:
+                    if self.config[4] != "":
+                        try :
+                            b_reply = reresult1.group( self.config[14] )
+                        except Exception, e:
+                            self.widget.error = 1
+                            b_reply = _("Group not found: \n") + reply
+                     
+                # Pass to widget parser
+                if self.config[1] != "":
+                    try:
+                        p = subprocess.Popen(smart_split_string(self.config[1], reply, sms_reply, reresult1, reresult2), stdout=subprocess.PIPE)
+                        w_reply = p.communicate()[0].strip()
+                    except Exception, e:
+                        print >> log, _("Couldn't exec widget parser:")+str(e)
+                        self.widget.error = 1
+                else:
+                    if self.config[4] != "":
+                        try :
+                            w_reply = reresult1.group( self.config[14] )
+                        except Exception, e:
+                            self.widget.error = 1
+                            w_reply = _("Group not found: \n") + reply
+                # Pass to chain
+                if self.config[2] != "":
+                    try:
+                        p = subprocess.Popen(smart_split_string(self.config[2], reply, sms_reply, reresult1, reresult2))
+                    except Exception, e:
+                        print >> log, _("Couldn't exec chain:")+str(e)
+                        self.widget.error = 1
+            if self.config[11]:
+                banner = hildon.hildon_banner_show_information (self.widget, "", b_reply)
+                banner.set_timeout (5000)
+                b_reply
+            self.widget.set_text(w_reply)
+        self.widget.processing = 0
+
+    def sms_timeout(self, version):
+        if version == self.sms_counter :
+            self.sms_reply = ""
+            self.sms_ready = True
+            self.sms_signal.remove()
+            self.process_reply()
+        return False
+
+    def timed_renew(self, version):
+        if version < self.timeout_version :
+            return False
+        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] != 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):
-               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
+    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, bg_color, text_color, id):
-               gtk.Dialog.__init__(self, _("USSD widget : "+id), 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])
-               self.parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
-               self.parser.set_text(config[1])
-               self.b_parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
-               self.b_parser.set_text(config[12])
-
-               self.chain = hildon.Entry(gtk.HILDON_SIZE_AUTO)
-               self.chain.set_text(config[2])
-               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.NumberEditor(0, 1000)
-               self.widthEdit.set_value(config[5])
-               self.retryEdit = hildon.Entry(gtk.HILDON_SIZE_AUTO)
-               self.args = hildon.Entry(gtk.HILDON_SIZE_AUTO)
-               self.args.set_text(config[13])
-               self.reggroup = hildon.NumberEditor(0, 255)
-               self.reggroup.set_value(config[14])
-               
-               selector = hildon.TouchSelector(text=True)
-               for i in ussd_languages_localized:
-                       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])
-               self.show_box = gtk.CheckButton(_("Enable banner. Parser:"))
-               self.show_box.connect("toggled", self.show_box_changed)
-               self.show_box.set_active(config[11])
-
-               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)
-               
-               bphelp = gtk.Button("?")
-               bphelp.connect("clicked", self.on_show_bphelp)
-
-               chelp = gtk.Button("?")
-               chelp.connect("clicked", self.on_show_chelp)
-
-               reghelp = gtk.Button("?")
-               reghelp.connect("clicked", self.on_show_reghelp)
-
-               retryhelp = gtk.Button("?")
-               retryhelp.connect("clicked", self.on_show_retryhelp)
-               
-               numberhelp = gtk.Button("?")
-               numberhelp.connect("clicked", self.on_show_number_help)
-
-               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.6)
-               numberLabel.set_size_request(100, -1)
-               numberhelp.set_size_request(1, -1)
-               self.ussdNumber.set_size_request(200, -1)
-               numberBox.add(numberLabel)
-               numberBox.add(numberhelp)
-               numberBox.add(self.ussdNumber)
-               vbox.add(numberBox)
-
-               vbox.add(self.query_at_start)
-
-               nameBox = gtk.HBox()
-               nameLabel = gtk.Label(_("Name"))
-               nameLabel.set_alignment(0,0.6)
-               nameLabel.set_size_request(100, -1)
-               self.wname.set_size_request(200, -1)
-               nameBox.add(nameLabel)
-               nameBox.add(self.wname)
-               vbox.add(nameBox)
-
-               parserBox = gtk.HBox()
-               parserLabel = gtk.Label(_("Parser for widget"))
-               parserLabel.set_alignment(0,0.6)
-               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)
-               
-               b_parserBox = gtk.HBox()
-               self.show_box.set_size_request(200, -1)
-               bphelp.set_size_request(10, -1)
-               b_parserBox.add(self.show_box)
-               b_parserBox.add(bphelp)
-               vbox.add(b_parserBox)
-               vbox.add(self.b_parser)
-               
-               chainBox = gtk.HBox()
-               chainLabel = gtk.Label(_("Chain"))
-               chainLabel.set_alignment(0,0.6)
-               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(_("Regular expression"))
-               regexpLabel.set_alignment(0,0.6)
-               regexpLabel.set_size_request(200, -1)
-               regexpGroupLabel = gtk.Label(_("Group"))
-               regexpGroupLabel.set_size_request(1, -1)
-               reghelp.set_size_request(10, -1)
-               regexpBox.add(regexpLabel)
-               regexpBox.add(reghelp)
-               regexpBox.add(regexpGroupLabel)
-               vbox.add(regexpBox)
-               self.reggroup.set_size_request(1,-1);
-               self.regexp.set_size_request(250,-1);
-               regexpInputBox = gtk.HBox()
-               regexpInputBox.add(self.regexp)
-               regexpInputBox.add(self.reggroup)
-               vbox.add(regexpInputBox)                
-
-               widthBox = gtk.HBox()
-               widthLabel = gtk.Label(_("Max. width"))
-               widthLabel.set_alignment(0,0.6)
-               symbolsLabel = gtk.Label(_("symbols"))
-               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)
-               widthBox.add(symbolsLabel)
-               vbox.add(widthBox)
-
-               updateBox = gtk.HBox()
-               updateLabel = gtk.Label(_("Update every"))
-               updateLabel.set_alignment(0,0.6)
-               minutesLabel = gtk.Label(_("minutes"))
-               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.6)
-               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)                
-               
-               argsLabel = gtk.Label(_("Additional ussdquery.py options"))
-               argsLabel.set_alignment(0,0.6)
-               vbox.add(argsLabel)
-               vbox.add(self.args)             
-               
-               viewBox = gtk.HBox()
-               viewBox.add(self.fontButton)
-               viewBox.add(self.textColorButton)
-               viewBox.add(self.colorButton)
-               vbox.add(viewBox)
-       
-               self.sms_box = gtk.VBox()       
-               self.sms_listener = gtk.CheckButton(_("Enable SMS listener."))
-               self.sms_listener.connect("toggled", self.sms_box_changed)
-               self.sms_listener.set_active(config[15])
-               vbox.add (self.sms_listener)
-
-               self.sms_number = hildon.Entry(gtk.HILDON_SIZE_AUTO)
-               self.sms_number.set_text(config[16])
-               smsNumberBox = gtk.HBox()
-               smsNumberLabel = gtk.Label(_("SMS number"))
-               smsNumberLabel.set_alignment(0,0.6)
-               smsNumberLabel.set_size_request(100, -1)
-               self.sms_number.set_size_request(200, -1)
-               smsNumberBox.add(smsNumberLabel)
-               smsNumberBox.add(self.sms_number)
-               self.sms_box.add(smsNumberBox)
-               
-               smsRegexpLabel = gtk.Label(_("Regular expression"))
-               smsRegexpLabel.set_alignment(0,0.6)
-               self.sms_box.add(smsRegexpLabel)
-               
-               self.sms_regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
-               self.sms_regexp.set_text(config[17])
-               self.sms_box.add(self.sms_regexp)
-
-               self.sms_timeout = hildon.NumberEditor(0, 9999)
-               self.sms_timeout.set_value(config[18])
-               sms_timeout_box = gtk.HBox()
-               timeoutLabel = gtk.Label(_("Timeout"))
-               timeoutLabel.set_alignment(0,0.6)
-               secondsLabel = gtk.Label(_("seconds"))
-               timeoutLabel.set_size_request(140, -1)
-               self.sms_timeout.set_size_request(50, -1)
-               secondsLabel.set_size_request(40, -1)
-               sms_timeout_box.add(timeoutLabel)
-               sms_timeout_box.add(self.sms_timeout)
-               sms_timeout_box.add(secondsLabel)
-               self.sms_box.add(sms_timeout_box)
-               
-               vbox.add(self.sms_box)
-
-               vbox.add(gtk.Label(_("DO NOT CHANGE. Unspecified is what you want.")))
-               vbox.add(self.language)
-
-               self.show_all()
-               self.show_box_changed(None)
-               self.sms_box_changed(None)
-               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 on widget.\n       Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n      Hint: use echo \"Your string %\" to prepend your string to reply."))
-               dialog.run()
-               dialog.destroy()
-
-       def on_show_bphelp(self, widget):
-               dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility, output of utility would be shown to you on banner.\n       Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n      Hint: use echo \"Your string %\" to prepend your string to reply."))
-               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%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n"))
-               dialog.run()
-               dialog.destroy()
-
-       def on_show_reghelp(self, widget):
-               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_show_number_help(self, widget):
-               dialog = pHelpDialog(_("Format help"), _("USSD number. To perform USSD menu navigation divide queries vith spacebars. For xample '*100# 1' means 1st entry in *100# menu."))
-               dialog.run()
-               dialog.destroy()
-       
-       def on_error_regexp(self, error):
-               dialog = pHelpDialog(_("Regexp syntax error"), error )
-               dialog.run()
-               dialog.destroy()
-
-       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 show_box_changed (self, event):
-               if self.show_box.get_active():
-                       self.b_parser.show()
-               else:
-                       self.b_parser.hide()
-
-       def sms_box_changed (self, event):
-               if self.sms_listener.get_active():
-                       self.sms_box.show()
-               else:
-                       self.sms_box.hide()
+    def __init__(self, config, bg_color, text_color, id):
+        gtk.Dialog.__init__(self, _("USSD widget : "+id), 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])
+        self.parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+        self.parser.set_text(config[1])
+        self.b_parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+        self.b_parser.set_text(config[12])
+
+        self.chain = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+        self.chain.set_text(config[2])
+        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.NumberEditor(0, 1000)
+        self.widthEdit.set_value(config[5])
+        self.retryEdit = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+        self.args = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+        self.args.set_text(config[13])
+        self.reggroup = hildon.NumberEditor(0, 255)
+        self.reggroup.set_value(config[14])
+        
+        selector = hildon.TouchSelector(text=True)
+        for i in ussd_languages_localized:
+            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])
+        self.show_box = gtk.CheckButton(_("Enable banner. Parser:"))
+        self.show_box.connect("toggled", self.show_box_changed)
+        self.show_box.set_active(config[11])
+
+        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)
+        
+        bphelp = gtk.Button("?")
+        bphelp.connect("clicked", self.on_show_bphelp)
+
+        chelp = gtk.Button("?")
+        chelp.connect("clicked", self.on_show_chelp)
+
+        reghelp = gtk.Button("?")
+        reghelp.connect("clicked", self.on_show_reghelp)
+
+        retryhelp = gtk.Button("?")
+        retryhelp.connect("clicked", self.on_show_retryhelp)
+        
+        numberhelp = gtk.Button("?")
+        numberhelp.connect("clicked", self.on_show_number_help)
+
+        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.6)
+        numberLabel.set_size_request(100, -1)
+        numberhelp.set_size_request(1, -1)
+        self.ussdNumber.set_size_request(200, -1)
+        numberBox.add(numberLabel)
+        numberBox.add(numberhelp)
+        numberBox.add(self.ussdNumber)
+        vbox.add(numberBox)
+
+        vbox.add(self.query_at_start)
+
+        nameBox = gtk.HBox()
+        nameLabel = gtk.Label(_("Name"))
+        nameLabel.set_alignment(0,0.6)
+        nameLabel.set_size_request(100, -1)
+        self.wname.set_size_request(200, -1)
+        nameBox.add(nameLabel)
+        nameBox.add(self.wname)
+        vbox.add(nameBox)
+
+        parserBox = gtk.HBox()
+        parserLabel = gtk.Label(_("Parser for widget"))
+        parserLabel.set_alignment(0,0.6)
+        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)
+        
+        b_parserBox = gtk.HBox()
+        self.show_box.set_size_request(200, -1)
+        bphelp.set_size_request(10, -1)
+        b_parserBox.add(self.show_box)
+        b_parserBox.add(bphelp)
+        vbox.add(b_parserBox)
+        vbox.add(self.b_parser)
+        
+        chainBox = gtk.HBox()
+        chainLabel = gtk.Label(_("Chain"))
+        chainLabel.set_alignment(0,0.6)
+        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(_("Regular expression"))
+        regexpLabel.set_alignment(0,0.6)
+        regexpLabel.set_size_request(200, -1)
+        regexpGroupLabel = gtk.Label(_("Group"))
+        regexpGroupLabel.set_size_request(1, -1)
+        reghelp.set_size_request(10, -1)
+        regexpBox.add(regexpLabel)
+        regexpBox.add(reghelp)
+        regexpBox.add(regexpGroupLabel)
+        vbox.add(regexpBox)
+        self.reggroup.set_size_request(1,-1);
+        self.regexp.set_size_request(250,-1);
+        regexpInputBox = gtk.HBox()
+        regexpInputBox.add(self.regexp)
+        regexpInputBox.add(self.reggroup)
+        vbox.add(regexpInputBox)        
+
+        widthBox = gtk.HBox()
+        widthLabel = gtk.Label(_("Max. width"))
+        widthLabel.set_alignment(0,0.6)
+        symbolsLabel = gtk.Label(_("symbols"))
+        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)
+        widthBox.add(symbolsLabel)
+        vbox.add(widthBox)
+
+        updateBox = gtk.HBox()
+        updateLabel = gtk.Label(_("Update every"))
+        updateLabel.set_alignment(0,0.6)
+        minutesLabel = gtk.Label(_("minutes"))
+        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.6)
+        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)        
+        
+        argsLabel = gtk.Label(_("Additional ussdquery.py options"))
+        argsLabel.set_alignment(0,0.6)
+        vbox.add(argsLabel)
+        vbox.add(self.args)        
+        
+        viewBox = gtk.HBox()
+        viewBox.add(self.fontButton)
+        viewBox.add(self.textColorButton)
+        viewBox.add(self.colorButton)
+        vbox.add(viewBox)
+    
+        self.sms_box = gtk.VBox()    
+        self.sms_listener = gtk.CheckButton(_("Enable SMS listener."))
+        self.sms_listener.connect("toggled", self.sms_box_changed)
+        self.sms_listener.set_active(config[15])
+        vbox.add (self.sms_listener)
+
+        self.sms_number = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+        self.sms_number.set_text(config[16])
+        smsNumberBox = gtk.HBox()
+        smsNumberLabel = gtk.Label(_("SMS number"))
+        smsNumberLabel.set_alignment(0,0.6)
+        smsNumberLabel.set_size_request(100, -1)
+        self.sms_number.set_size_request(200, -1)
+        smsNumberBox.add(smsNumberLabel)
+        smsNumberBox.add(self.sms_number)
+        self.sms_box.add(smsNumberBox)
+        
+        smsRegexpLabel = gtk.Label(_("Regular expression"))
+        smsRegexpLabel.set_alignment(0,0.6)
+        self.sms_box.add(smsRegexpLabel)
+        
+        self.sms_regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
+        self.sms_regexp.set_text(config[17])
+        self.sms_box.add(self.sms_regexp)
+
+        self.sms_timeout = hildon.NumberEditor(0, 9999)
+        self.sms_timeout.set_value(config[18])
+        sms_timeout_box = gtk.HBox()
+        timeoutLabel = gtk.Label(_("Timeout"))
+        timeoutLabel.set_alignment(0,0.6)
+        secondsLabel = gtk.Label(_("seconds"))
+        timeoutLabel.set_size_request(140, -1)
+        self.sms_timeout.set_size_request(50, -1)
+        secondsLabel.set_size_request(40, -1)
+        sms_timeout_box.add(timeoutLabel)
+        sms_timeout_box.add(self.sms_timeout)
+        sms_timeout_box.add(secondsLabel)
+        self.sms_box.add(sms_timeout_box)
+        
+        vbox.add(self.sms_box)
+
+        vbox.add(gtk.Label(_("DO NOT CHANGE. Unspecified is what you want.")))
+        vbox.add(self.language)
+
+        self.show_all()
+        self.show_box_changed(None)
+        self.sms_box_changed(None)
+        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 on widget.\n       Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n      Hint: use echo \"Your string %\" to prepend your string to reply."))
+        dialog.run()
+        dialog.destroy()
+
+    def on_show_bphelp(self, widget):
+        dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility, output of utility would be shown to you on banner.\n       Format:\n% would be replaced by reply\n%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n      Hint: use echo \"Your string %\" to prepend your string to reply."))
+        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%N with N'th regexp matching group\n& would be replaced with sms content\n&N with N'th sms regexp group\n\\ invalidates special meaming of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility\n"))
+        dialog.run()
+        dialog.destroy()
+
+    def on_show_reghelp(self, widget):
+        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_show_number_help(self, widget):
+        dialog = pHelpDialog(_("Format help"), _("USSD number. To perform USSD menu navigation divide queries vith spacebars. For xample '*100# 1' means 1st entry in *100# menu."))
+        dialog.run()
+        dialog.destroy()
+    
+    def on_error_regexp(self, error):
+        dialog = pHelpDialog(_("Regexp syntax error"), error )
+        dialog.run()
+        dialog.destroy()
+
+    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 show_box_changed (self, event):
+        if self.show_box.get_active():
+            self.b_parser.show()
+        else:
+            self.b_parser.hide()
+
+    def sms_box_changed (self, event):
+        if self.sms_listener.get_active():
+            self.sms_box.show()
+        else:
+            self.sms_box.hide()
 
 def smart_split_string (str, reply1, reply2, reres1 = None, reres2 = None) :
-       word = ""
-       result = []
-       # Is simbol backslashed?
-       bs = 0
-       # Quotes: 1 - ", 2 - ', 0 - no quotes
-       qs = 0
-       # Read out number
-       num = -1
-       # Current substitution simbol
-       subst = ''
-
-       for i in range(len(str)) :
-               if num>= 0:
-                       if str[i] in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] :
-                               num *= 10
-                               num += int(str[i])
-                               continue
-                       else:
-                               if subst == '&':
-                                       if reres2 != None and num != 0:
-                                               word += reres2.group(num)
-                                       else:
-                                               word += reply2
-                               else:
-                                       if reres1 != None and num != 0:
-                                               word += reres1.group(num)
-                                       else:
-                                               word += reply1
-                               ws = 0
-                               num = -1
-                               subst = ''
-                               # Delete backslash if it delimites usual numbers from % or &
-                               if str[i] == '\\' and i < len(str)-1 and str[i+1] in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] :
-                                       continue
-               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] == '%' or str[i] == '&') :
-                       subst = str[i]
-                       num = 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 subst == '&':
-               if reres2 != None and num != 0 and num != -1:
-                       word += reres2.group(num)
-               else:
-                       word += reply2
-       elif subst == '%':
-               if reres1 != None and num != 0 and num != -1:
-                       word += reres1.group(num)
-               else:
-                       word += reply1
-       if word != "" :
-               result.append(word)
-       return result 
+    word = ""
+    result = []
+    # Is simbol backslashed?
+    bs = 0
+    # Quotes: 1 - ", 2 - ', 0 - no quotes
+    qs = 0
+    # Read out number
+    num = -1
+    # Current substitution simbol
+    subst = ''
+
+    for i in range(len(str)) :
+        if num>= 0:
+            if str[i] in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] :
+                num *= 10
+                num += int(str[i])
+                continue
+            else:
+                if subst == '&':
+                    if reres2 != None and num != 0:
+                        word += reres2.group(num)
+                    else:
+                        word += reply2
+                else:
+                    if reres1 != None and num != 0:
+                        word += reres1.group(num)
+                    else:
+                        word += reply1
+                ws = 0
+                num = -1
+                subst = ''
+                # Delete backslash if it delimites usual numbers from % or &
+                if str[i] == '\\' and i < len(str)-1 and str[i+1] in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] :
+                    continue
+        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] == '%' or str[i] == '&') :
+            subst = str[i]
+            num = 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 subst == '&':
+        if reres2 != None and num != 0 and num != -1:
+            word += reres2.group(num)
+        else:
+            word += reply2
+    elif subst == '%':
+        if reres1 != None and num != 0 and num != -1:
+            word += reres1.group(num)
+        else:
+            word += reply1
+    if word != "" :
+        result.append(word)
+    return result 
 
 def check_regexp(regexp):
-       try :
-               re.compile( regexp )
-       except Exception, e:
-                       return str(e)
-       return False
+    try :
+        re.compile( regexp )
+    except Exception, e:
+            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
+    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 ================
 
 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.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
-
-               colormap = self.get_screen().get_rgba_colormap()
-               self.set_colormap (colormap)
-
-               self.controller = USSD_Controller(self)
-                
+    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
+
+        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.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()
-
-               DBusGMainLoop(set_as_default=True)
-               bus = dbus.SystemBus()
-               signal = bus.add_signal_receiver(self.set_bg_color_text, path='/su/kibergus/ussd_widget',   dbus_interface='su.kibergus.ussd_widget', signal_name='set_bg_color')
-               signal = bus.add_signal_receiver(self.set_text_color_text, path='/su/kibergus/ussd_widget',   dbus_interface='su.kibergus.ussd_widget', signal_name='set_text_color')
-               signal = bus.add_signal_receiver(self.ussd_renew, path='/su/kibergus/ussd_widget',   dbus_interface='su.kibergus.ussd_widget', signal_name='renew')
-
-       def do_show(self):
-               config = self.controller.read_config(self.get_applet_id())
-               self.set_width(config[5])
-               self.set_text(config[9])                
-               if config[6]:
-                       self.controller.ussd_renew(self, None)
-
-               self.label.modify_font(config[8])
-               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)
-               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
-               
-               config = self.controller.get_config()
-               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 ussd_renew(self, id):
-               if id == self.get_applet_id():
-                       self.controller.ussd_renew(self, None)
-
-       def set_bg_color_text(self, id, color):
-               if id == self.get_applet_id():
-                       try :
-                               self.set_bg_color(gtk.gdk.color_parse(color.strip()))
-                       except:
-                               print _("Unable to parse colour specification")
-                       self.queue_draw()
-
-       def set_text_color_text(self, id, color):
-               if id == self.get_applet_id():
-                       try:
-                               self.set_text_color(gtk.gdk.color_parse(color.strip()))
-                       except:
-                               print _("Unable to parse colour specification")
-                       self.queue_draw()
-
-       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()
-
-               # 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=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 ()
-
-               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)
+        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.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()
+
+        DBusGMainLoop(set_as_default=True)
+        bus = dbus.SystemBus()
+        signal = bus.add_signal_receiver(self.set_bg_color_text, path='/su/kibergus/ussd_widget',   dbus_interface='su.kibergus.ussd_widget', signal_name='set_bg_color')
+        signal = bus.add_signal_receiver(self.set_text_color_text, path='/su/kibergus/ussd_widget',   dbus_interface='su.kibergus.ussd_widget', signal_name='set_text_color')
+        signal = bus.add_signal_receiver(self.ussd_renew, path='/su/kibergus/ussd_widget',   dbus_interface='su.kibergus.ussd_widget', signal_name='renew')
+
+    def do_show(self):
+        config = self.controller.read_config(self.get_applet_id())
+        self.set_width(config[5])
+        self.set_text(config[9])        
+        if config[6]:
+            self.controller.ussd_renew(self, None)
+
+        self.label.modify_font(config[8])
+        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)
+        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
+        
+        config = self.controller.get_config()
+        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 ussd_renew(self, id):
+        if id == self.get_applet_id():
+            self.controller.ussd_renew(self, None)
+
+    def set_bg_color_text(self, id, color):
+        if id == self.get_applet_id():
+            try :
+                self.set_bg_color(gtk.gdk.color_parse(color.strip()))
+            except:
+                print >> log, _("Unable to parse colour specification")
+            self.queue_draw()
+
+    def set_text_color_text(self, id, color):
+        if id == self.get_applet_id():
+            try:
+                self.set_text_color(gtk.gdk.color_parse(color.strip()))
+            except:
+                print >> log, _("Unable to parse colour specification")
+            self.queue_draw()
+
+    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()
+
+        # 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=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 ()
+
+        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
 
 # The code below is just for testing purposes.
 # It allows to run the widget as a standalone process.
 if __name__ == "__main__":
-       plugin_id = "ussd-widget.console"
-       if len(sys.argv) == 2:
-               try:
-                       plugin_id = "ussd-widget.desktop-"+str(int(sys.argv[1]))
-               except:
-                       print "Plugin id must be integer"
-                       sys.exit(-1)
-
-       import gobject
-       gobject.type_register(hd_plugin_type)
-       obj = gobject.new(hd_plugin_type, plugin_id=plugin_id)
-       obj.show_all()
-       gtk.main()
+    plugin_id = "ussd-widget.console"
+    if len(sys.argv) == 2:
+        try:
+            plugin_id = "ussd-widget.desktop-"+str(int(sys.argv[1]))
+        except:
+            print >> log, "Plugin id must be integer"
+            sys.exit(-1)
+
+    import gobject
+    gobject.type_register(hd_plugin_type)
+    obj = gobject.new(hd_plugin_type, plugin_id=plugin_id)
+    obj.show_all()
+    gtk.main()