2 # -*- coding: utf-8 -*-
14 from subprocess import *
17 t = gettext.translation('ussd-widget', '/usr/share/locale')
20 print "Translation file for your language not found"
25 ussd_languages = ["German", "English", "Italian", "French", "Spanish", "Dutch", "Swedish", "Danish", "Portuguese", "Finnish", "Norwegian", "Greek", "Turkish", "Reserved1", "Reserved2", "Unspecified"]
26 ussd_languages_localized = [_("German"), _("English"), _("Italian"), _("French"), _("Spanish"), _("Dutch"), _("Swedish"), _("Danish"), _("Portuguese"), _("Finnish"), _("Norwegian"), _("Greek"), _("Turkish"), _("Reserved1"), _("Reserved2"), _("Unspecified")]
28 # TODO Cutt off too long messages and show them in separate dialog
29 # how TODO widget vertical minimum size policy
30 # TODO interface for queryng from scripts. For example query from one widget can change color of another widget
32 class USSD_Controller:
33 def __init__( self, widget ) :
35 # number, parser, chain, interval, regexp, width, execute_at_start, retry pattern, font, name, language, show_message_box, message_box_parser, additional arguments, regexp group
36 self.default_config = ["", "", "", 0, "", 0, True, [], pango.FontDescription("Nokia Sans 18"), _("Click to update"), 15, False, "", "", 1]
37 self.config = self.default_config
38 self.timeout_version = 0
39 self.retry_version = 0
42 def save_config( self ) :
43 configname = os.getenv("HOME")+"/.ussdWidget.conf"
45 lockf = open(configname+".lock", 'a')
46 fcntl.flock(lockf,fcntl.LOCK_EX)
50 fconfig = open(configname,"r")
51 #Read configuration of other instances
55 my_section = line[1:].strip() == self.id
60 print _("Couldn't read previous config")
62 fconfig = open(configname,"w")
64 fconfig.write(oldconfig)
65 fconfig.write("%"+self.id+"\n");
66 fconfig.writelines(["# USSD query to be run by widget\n", "number="+self.config[0], "\n"])
67 fconfig.writelines(["#Parser command for widget\n", "parser="+self.config[1], "\n"])
68 fconfig.writelines(["#Parser command for banner\n", "parser_box="+self.config[12], "\n"])
69 fconfig.writelines(["#Chain command\n", "chain="+self.config[2], "\n"])
70 fconfig.writelines(["#Update interval in minutes\n", "interval="+str(self.config[3]), "\n"])
71 fconfig.writelines(["#RegExp pattern\n", "regexp="+self.config[4], "\n"])
72 fconfig.writelines(["#Widget width\n", "width="+str(self.config[5]), "\n"])
73 fconfig.writelines(["#Execute query at start\n", "query_at_start="+str(self.config[6]), "\n"])
74 fconfig.writelines(["#Retry pattern\n"])
75 fconfig.write("retry=")
77 for i in self.config[7]:
83 fconfig.writelines(["#Font description\n", "font="+self.config[8].to_string(), "\n"])
84 fconfig.writelines(["#Font color\n", "text_color="+self.widget.get_text_color().to_string(), "\n"])
85 fconfig.writelines(["#Background color\n", "bg_color="+self.widget.get_bg_color().to_string(), "\n"])
86 fconfig.writelines(["#Widget name\n", "name="+self.config[9], "\n"])
87 fconfig.writelines(["#Show banner\n", "show_box="+str(self.config[11]), "\n"])
88 fconfig.writelines(["#USSD reply language\n", "language="+str(self.config[10]), "\n"])
89 fconfig.writelines(["#Additional ussdquery.py arguments\n", "args="+self.config[13], "\n"])
90 fconfig.writelines(["#Regexp matching group\n", "reggroup="+self.config[14], "\n"])
93 fcntl.flock(lockf,fcntl.LOCK_UN)
99 def read_config( self, id ):
102 config = open(os.getenv("HOME")+"/.ussdWidget.conf","r")
112 my_section = line[1:].strip() == id
116 # This is config for another instace
119 line=line.split('=', 1)
123 print _("Error reading config on line %(line)d. = or # expected.")%{"line":i}
125 if line[0] == "number" :
126 self.config[0] = line[1].strip()
127 elif line[0] == "parser" :
128 self.config[1] = line[1].strip()
129 elif line[0] == "parser_box" :
130 self.config[12] = line[1].strip()
131 elif line[0] == "chain" :
132 self.config[2] = line[1].strip()
133 elif line[0] == "interval" :
135 self.config[3] = int(line[1].strip())
138 print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
140 elif line[0] == "regexp" :
141 self.config[4] = line[1].strip()
142 elif line[0] == "width" :
144 self.config[5] = int(line[1].strip())
147 print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
149 elif line[0] == "query_at_start" :
150 if line[1].strip() == "True" :
151 self.config[6] = True
153 self.config[6] = False
154 elif line[0] == "retry" :
155 line[1] = line[1].strip()
157 line[1] = line[1].split("-")
159 while i < len(line[1]) :
161 line[1][i] = int(line[1][i])
164 print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
166 self.config[7] = line[1]
170 elif line[0] == "font" :
172 self.config[8] = pango.FontDescription(line[1].strip())
175 print _("Error reading config on line %(line)d. Pango font description expected.")%{"line":i}
177 elif line[0] == "bg_color" :
179 self.widget.set_bg_color(gtk.gdk.color_parse(line[1].strip()))
182 print _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
183 elif line[0] == "text_color" :
185 self.widget.set_text_color(gtk.gdk.color_parse(line[1].strip()))
188 print _("Error reading config on line %(line)d. Expected color definition.")%{"line":i}
189 elif line[0] == "name" :
190 self.config[9] = line[1].strip()
191 elif line[0] == "show_box" :
192 if line[1].strip() == "True" :
193 self.config[11] = True
195 self.config[11] = False
196 elif line[0] == "language" :
198 if int(line[1].strip()) >=0 and int(line[1].strip()) < len(ussd_languages):
199 self.config[10] = int(line[1].strip())
202 print _("Error reading config on line %(line)d. Unknown language code.")%{"line":i}
205 print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
206 elif line[0] == "args" :
207 self.config[13] = line[1].strip()
208 elif line[0] == "reggroup" :
210 self.config[14] = int(line[1].strip())
213 print _("Error reading config on line %(line)d. Integer expected.")%{"line":i}
217 print _("Error reading config on line %(line)d. Unexpected variable: ")%{"line":i}+line[0]
223 self.widget.error = 1
224 self.widget.set_text (_("Config error"), 5000)
228 self.widget.error = 1
229 self.widget.set_text (_("Config error"), 0)
230 print _("IO error while reading config")
232 return self.default_config
234 def on_show_settings( self, widget ) :
235 dialog = UssdConfigDialog(self.config, self.widget.get_bg_color(), self.widget.get_text_color())
238 if dialog.run() != gtk.RESPONSE_OK :
242 test = check_regexp(dialog.regexp.get_text())
244 dialog.on_error_regexp(test)
247 # Check, that we have ussd number
248 if not check_number(dialog.ussdNumber.get_text()):
249 dialog.on_error_ussd_number()
252 # Parse retry pattern
253 retry = dialog.retryEdit.get_text().strip()
255 retry = retry.split("-")
257 while i < len(retry) :
259 retry[i] = int(retry[i])
261 dialog.on_error_retry_pattern()
273 dialog.ussdNumber.get_text(),
274 dialog.parser.get_text(),
275 dialog.chain.get_text(),
276 dialog.update_interval.get_value(),
277 dialog.regexp.get_text(),
278 dialog.widthEdit.get_value(),
279 dialog.query_at_start.get_active(),
282 dialog.wname.get_text(),
283 dialog.language.get_active(),
284 dialog.show_box.get_active(),
285 dialog.b_parser.get_text(),
286 dialog.args.get_text(),
287 dialog.reggroup.get_value()
290 widget.set_bg_color(dialog.bg_color)
291 widget.set_text_color(dialog.text_color)
295 widget.set_width(self.config[5])
296 self.reset_timed_renew()
297 self.widget.label.modify_font(self.config[8])
301 # Before running this function widget wasn't configured
302 if self.config == self.default_config:
303 self.widget.set_text(_("Click to update"))
306 def callback_ussd_data( self, source, condition ):
307 if condition == gobject.IO_IN or condition == gobject.IO_PRI :
308 data = source.read( )
310 self.cb_reply += data
316 elif condition == gobject.IO_HUP or condition == gobject.IO_ERR :
321 print (_("serious problems in program logic"))
322 # This will force widget to show error message
329 def call_external_script( self, ussd_code, language ):
332 p = Popen(['/usr/bin/ussdquery.py', ussd_code, "-l", ussd_languages[language]] + smart_split_string(self.config[13],"%"), stdout=PIPE)
333 gobject.io_add_watch( p.stdout, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR , self.callback_ussd_data )
335 def ussd_renew(self, widget, event):
336 if self.widget.processing == 0:
338 widget.processing = 1
339 widget.set_text(_("Processing"), 0)
340 self.call_external_script( self.config[0], self.config[10] )
342 widget.processing = 0
344 widget.set_text(_("No config"), 0)
346 def process_reply( self ):
347 reply = self.cb_reply.strip()
350 self.widget.error = 1
351 self.widget.set_text (_("Error"), 5000)
352 if self.retry_state == len(self.config[7]):
353 self.retry_version += 1
356 self.retry_timer = gobject.timeout_add (1000*self.config[7][self.retry_state], self.retry_renew, self.retry_version)
357 self.retry_state += 1
359 self.widget.error = 0
361 if self.config[4] != "":
363 reply = re.search( self.config[4], reply, re.MULTILINE | re.UNICODE ).group( self.config[14] )
365 self.widget.error = 1
366 reply = _("Regexp Error: ") + str( e ) + "\n" + reply
367 w_reply = b_reply = reply
368 if self.widget.error == 0:
370 if self.config[12] != "" and self.config[11]:
372 p = Popen(smart_split_string(self.config[12], reply), stdout=PIPE)
373 b_reply = p.communicate()[0].strip()
375 print _("Couldn't exec banner parser:")+str(e)
376 self.widget.error = 1
377 # Pass to widget parser
378 if self.config[1] != "":
380 p = Popen(smart_split_string(self.config[1], reply), stdout=PIPE)
381 w_reply = p.communicate()[0].strip()
383 print _("Couldn't exec widget parser:")+str(e)
384 self.widget.error = 1
386 if self.config[2] != "":
388 p = Popen(smart_split_string(self.config[2], reply))
390 print _("Couldn't exec chain:")+str(e)
391 self.widget.error = 1
393 banner = hildon.hildon_banner_show_information (self.widget, "", b_reply)
394 banner.set_timeout (5000)
396 self.widget.set_text(w_reply)
397 self.widget.processing = 0
399 def timed_renew(self, version):
400 if version < self.timeout_version :
402 self.ussd_renew(self.widget, None)
405 def retry_renew(self,version):
406 if self.widget.error == 0 or self.widget.processing == 1 or version < self.retry_version :
408 self.ussd_renew(self.widget, None)
411 def reset_timed_renew (self) :
412 self.timeout_version += 1
413 if self.config[3] != 0 :
414 self.timer = gobject.timeout_add (60000*self.config[3], self.timed_renew, self.timeout_version)
416 class pHelpDialog(gtk.Dialog):
417 def __init__(self, heading, text):
418 gtk.Dialog.__init__(self, heading, None,
419 gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
420 (_("OK").encode("utf-8"), gtk.RESPONSE_OK))
421 label = gtk.Label(text)
422 label.set_line_wrap (True)
427 class UssdConfigDialog(gtk.Dialog):
428 def __init__(self, config, bg_color, text_color):
429 gtk.Dialog.__init__(self, _("USSD widget"), None,
430 gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR,
431 (_("Save").encode("utf-8"), gtk.RESPONSE_OK))
433 self.font = config[8]
434 self.bg_color = bg_color
435 self.text_color = text_color
437 self.set_size_request(-1, 400)
438 self.ussdNumber = hildon.Entry(gtk.HILDON_SIZE_AUTO)
439 self.ussdNumber.set_text(config[0])
440 self.parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
441 self.parser.set_text(config[1])
442 self.b_parser = hildon.Entry(gtk.HILDON_SIZE_AUTO)
443 self.b_parser.set_text(config[12])
445 self.chain = hildon.Entry(gtk.HILDON_SIZE_AUTO)
446 self.chain.set_text(config[2])
447 self.update_interval = hildon.NumberEditor(0, 9999)
448 self.update_interval.set_value(config[3])
449 self.regexp = hildon.Entry(gtk.HILDON_SIZE_AUTO)
450 self.regexp.set_text(config[4])
451 self.widthEdit = hildon.NumberEditor(0, 1000)
452 self.widthEdit.set_value(config[5])
453 self.retryEdit = hildon.Entry(gtk.HILDON_SIZE_AUTO)
454 self.args = hildon.Entry(gtk.HILDON_SIZE_AUTO)
455 self.args.set_text(config[13])
456 self.reggroup = hildon.NumberEditor(0, 255)
457 self.reggroup.set_value(config[14])
459 selector = hildon.TouchSelector(text=True)
460 for i in ussd_languages_localized:
461 selector.append_text(i)
462 self.language = hildon.PickerButton(gtk.HILDON_SIZE_AUTO, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
463 self.language.set_selector(selector)
464 self.language.set_active(config[10])
465 self.language.set_title(_("USSD reply language"))
466 self.language.set_size_request(-1, -1)
468 self.wname = hildon.Entry(gtk.HILDON_SIZE_AUTO)
469 self.wname.set_text(config[9])
470 self.show_box = gtk.CheckButton(_("Enable banner. Parser:"))
471 self.show_box.set_active(config[11])
478 self.retryEdit.set_text(text)
480 self.query_at_start = gtk.CheckButton(_("Execute query on start"))
481 self.query_at_start.set_active(config[6])
483 self.fontButton = gtk.Button(_("Font"))
484 self.fontButton.connect("clicked", self.on_show_font_selection)
486 self.colorButton = gtk.Button(_("Background color"))
487 self.colorButton.connect("clicked", self.on_show_color_selection)
488 self.textColorButton = gtk.Button(_("Text color"))
489 self.textColorButton.connect("clicked", self.on_show_text_color_selection)
491 phelp = gtk.Button("?")
492 phelp.connect("clicked", self.on_show_phelp)
494 bphelp = gtk.Button("?")
495 bphelp.connect("clicked", self.on_show_bphelp)
497 chelp = gtk.Button("?")
498 chelp.connect("clicked", self.on_show_chelp)
500 reghelp = gtk.Button("?")
501 reghelp.connect("clicked", self.on_show_reghelp)
503 retryhelp = gtk.Button("?")
504 retryhelp.connect("clicked", self.on_show_retryhelp)
506 numberhelp = gtk.Button("?")
507 numberhelp.connect("clicked", self.on_show_number_help)
509 area = hildon.PannableArea()
512 area.add_with_viewport(vbox)
514 numberBox = gtk.HBox()
515 numberLabel = gtk.Label(_("USSD number"))
516 numberLabel.set_alignment(0,0.6)
517 numberLabel.set_size_request(100, -1)
518 numberhelp.set_size_request(1, -1)
519 self.ussdNumber.set_size_request(200, -1)
520 numberBox.add(numberLabel)
521 numberBox.add(numberhelp)
522 numberBox.add(self.ussdNumber)
525 vbox.add(self.query_at_start)
528 nameLabel = gtk.Label(_("Name"))
529 nameLabel.set_alignment(0,0.6)
530 nameLabel.set_size_request(100, -1)
531 self.wname.set_size_request(200, -1)
532 nameBox.add(nameLabel)
533 nameBox.add(self.wname)
536 parserBox = gtk.HBox()
537 parserLabel = gtk.Label(_("Parser for widget"))
538 parserLabel.set_alignment(0,0.6)
539 parserLabel.set_size_request(200, -1)
540 phelp.set_size_request(10, -1)
541 parserBox.add(parserLabel)
544 vbox.add(self.parser)
546 b_parserBox = gtk.HBox()
547 self.show_box.set_size_request(200, -1)
548 bphelp.set_size_request(10, -1)
549 b_parserBox.add(self.show_box)
550 b_parserBox.add(bphelp)
551 vbox.add(b_parserBox)
552 vbox.add(self.b_parser)
554 chainBox = gtk.HBox()
555 chainLabel = gtk.Label(_("Chain"))
556 chainLabel.set_alignment(0,0.6)
557 chainLabel.set_size_request(200, -1)
558 chelp.set_size_request(10, -1)
559 chainBox.add(chainLabel)
564 regexpBox = gtk.HBox()
565 regexpLabel = gtk.Label(_("Regular expression"))
566 regexpLabel.set_alignment(0,0.6)
567 regexpLabel.set_size_request(200, -1)
568 regexpGroupLabel = gtk.Label(_("Group"))
569 regexpGroupLabel.set_size_request(1, -1)
570 reghelp.set_size_request(10, -1)
571 regexpBox.add(regexpLabel)
572 regexpBox.add(reghelp)
573 regexpBox.add(regexpGroupLabel)
575 self.reggroup.set_size_request(1,-1);
576 self.regexp.set_size_request(250,-1);
577 regexpInputBox = gtk.HBox()
578 regexpInputBox.add(self.regexp)
579 regexpInputBox.add(self.reggroup)
580 vbox.add(regexpInputBox)
582 widthBox = gtk.HBox()
583 widthLabel = gtk.Label(_("Max. width"))
584 widthLabel.set_alignment(0,0.6)
585 symbolsLabel = gtk.Label(_("symbols"))
586 widthLabel.set_size_request(140, -1)
587 self.widthEdit.set_size_request(50, -1)
588 symbolsLabel.set_size_request(40,-1)
589 widthBox.add(widthLabel)
590 widthBox.add(self.widthEdit)
591 widthBox.add(symbolsLabel)
594 updateBox = gtk.HBox()
595 updateLabel = gtk.Label(_("Update every"))
596 updateLabel.set_alignment(0,0.6)
597 minutesLabel = gtk.Label(_("minutes"))
598 updateLabel.set_size_request(140, -1)
599 self.update_interval.set_size_request(50, -1)
600 minutesLabel.set_size_request(40, -1)
601 updateBox.add(updateLabel)
602 updateBox.add(self.update_interval)
603 updateBox.add(minutesLabel)
606 retryBox = gtk.HBox()
607 retryLabel = gtk.Label(_("Retry pattern"))
608 retryLabel.set_alignment(0,0.6)
609 retryLabel.set_size_request(200, -1)
610 retryhelp.set_size_request(10, -1)
611 retryBox.add(retryLabel)
612 retryBox.add(retryhelp)
614 vbox.add(self.retryEdit)
616 argsLabel = gtk.Label(_("Additional ussdquery.py options"))
617 argsLabel.set_alignment(0,0.6)
622 viewBox.add(self.fontButton)
623 viewBox.add(self.textColorButton)
624 viewBox.add(self.colorButton)
627 vbox.add(gtk.Label(_("DO NOT CHANGE. Unspecified is what you want.")))
628 vbox.add(self.language)
633 #============ Dialog helper functions =============
634 def on_show_phelp(self, widget):
635 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\\ 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."))
639 def on_show_bphelp(self, widget):
640 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\\ 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."))
644 def on_show_chelp(self, widget):
645 dialog = pHelpDialog(_("Format help"), _("Reply would be passed to specified utility after parser utility. May be used for logging, statistics etc.\n Format:\n% would be replaced by reply\n\\ invalidates special meaning of following symbol\n\" and ' work as usual\nspace delimits command line parameters of utility"))
649 def on_show_reghelp(self, widget):
650 dialog = pHelpDialog(_("Format help"), _("Standard python regexps. Use\n (.+?[\d\,\.]+)\n to delete everything after first number."))
654 def on_show_retryhelp(self, widget):
655 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\""))
659 def on_show_number_help(self, widget):
660 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."))
664 def on_error_regexp(self, error):
665 dialog = pHelpDialog(_("Regexp syntax error"), error )
669 def on_error_ussd_number(self):
670 dialog = pHelpDialog(_("Incorrect USSD number"), _("USSD number should contain only digits, +, * or #") )
674 def on_error_retry_pattern(self):
675 dialog = pHelpDialog(_("Incorrect retry pattern"), _("Retry pattern should contain only numbers, delimited by -") )
679 def on_show_color_selection (self, event):
680 colorDialog = gtk.ColorSelectionDialog(_("Choose background color"))
681 colorDialog.colorsel.set_current_color(self.bg_color)
682 if colorDialog.run() == gtk.RESPONSE_OK :
683 self.bg_color = colorDialog.colorsel.get_current_color()
684 colorDialog.destroy()
686 def on_show_text_color_selection (self, event):
687 colorDialog = gtk.ColorSelectionDialog(_("Choose text color"))
688 colorDialog.colorsel.set_current_color(self.text_color)
689 if colorDialog.run() == gtk.RESPONSE_OK :
690 self.text_color = colorDialog.colorsel.get_current_color()
691 colorDialog.destroy()
693 def on_show_font_selection (self, event):
694 fontDialog = gtk.FontSelectionDialog(_("Choose a font"))
695 fontDialog.set_font_name(self.font.to_string())
697 if fontDialog.run() != gtk.RESPONSE_OK :
701 self.font = pango.FontDescription (fontDialog.get_font_name())
704 def smart_split_string (str, query) :
707 # Is simbol backslashed?
709 # Quotes: 1 - ", 2 - ', 0 - no quotes
711 for i in range(len(str)) :
712 if bs == 0 and (str[i] == '"' and qs == 1 or str[i] == "'" and qs == 2) :
714 elif bs == 0 and qs == 0 and (str[i] == '"' or str[i] == "'") :
719 elif bs == 0 and str[i] == '\\' :
721 elif bs == 0 and str[i] == '%' :
725 if bs == 1 and str[i] != '\\' and str[i] != '"' and str[i] != "'" :
727 if qs == 0 and (str[i] == " " or str[i] == "\t") :
738 def check_regexp(regexp):
745 def check_number(number):
747 if not (s in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "+", "*", "#", " "]) :
751 #=============== The widget itself ================
753 def get_color(logicalcolorname):
754 settings = gtk.settings_get_default()
755 color_style = gtk.rc_get_style_by_paths(settings, 'GtkButton', 'osso-logical-colors', gtk.Button)
756 return color_style.lookup_color(logicalcolorname)
758 class UssdWidgetPlugin(hildondesktop.HomePluginItem):
760 hildondesktop.HomePluginItem.__init__(self)
763 self.bg_color=gtk.gdk.color_parse('#000000')
764 self.text_color=gtk.gdk.color_parse('#ffffff')
766 self.timeout_version = 0
768 colormap = self.get_screen().get_rgba_colormap()
769 self.set_colormap (colormap)
771 self.controller = USSD_Controller(self)
773 # TODO Click event would be better
774 self.connect("button-press-event", self.controller.ussd_renew)
776 self.vbox = gtk.HBox()
779 self.set_settings(True)
780 self.connect("show-settings", self.controller.on_show_settings)
781 self.label = gtk.Label("")
783 self.vbox.add(self.label)
784 self.vbox.set_child_packing(self.label, False, False, 0, gtk.PACK_START)
785 self.label.set_padding(15, 10)
786 self.label.set_size_request(-1,-1)
787 self.set_size_request(-1,-1)
788 self.label.set_line_wrap (True)
793 config = self.controller.read_config(self.get_applet_id())
794 self.set_width(config[5])
795 self.set_text(config[9])
797 self.controller.ussd_renew(self, None)
799 self.label.modify_font(config[8])
800 self.controller.reset_timed_renew()
801 hildondesktop.HomePluginItem.do_show(self)
803 def error_return (self):
804 if self.error == 1 and self.processing == 0:
805 self.set_text(self.text)
809 # -1 - This is a permanent text message
810 # 0 - This is service message, but it shouldn't be hidden automatically
811 # >0 - This is service message, show permament message after showfor milliseconds
812 def set_text(self, text, showfor=-1):
814 # Show previous text after 5 seconds
815 gobject.timeout_add (showfor, self.error_return)
820 config = self.controller.get_config()
821 self.label.set_text(text)
826 def set_width(self, width):
828 self.label.set_width_chars (width)
830 self.label.set_width_chars(-1)
832 def set_bg_color(self, color):
833 self.bg_color = color
835 def get_bg_color(self):
838 def set_text_color(self, color):
839 self.label.modify_fg(gtk.STATE_NORMAL, color)
840 self.text_color = color
842 def get_text_color(self):
843 return self.text_color
845 def _expose(self, event):
846 cr = self.window.cairo_create()
849 width, height = self.label.allocation[2], self.label.allocation[3]
851 #/* a custom shape, that could be wrapped in a function */
852 x0 = 0 #/*< parameters like cairo_rectangle */
855 radius = min(15, width/2, height/2) #/*< and an approximate curvature radius */
860 cr.move_to (x0, y0 + radius)
861 cr.arc (x0 + radius, y0 + radius, radius, 3.14, 1.5 * 3.14)
862 cr.line_to (x1 - radius, y0)
863 cr.arc (x1 - radius, y0 + radius, radius, 1.5 * 3.14, 0.0)
864 cr.line_to (x1 , y1 - radius)
865 cr.arc (x1 - radius, y1 - radius, radius, 0.0, 0.5 * 3.14)
866 cr.line_to (x0 + radius, y1)
867 cr.arc (x0 + radius, y1 - radius, radius, 0.5 * 3.14, 3.14)
871 fg_color = get_color("ActiveTextColor")
876 bg_color=self.bg_color
878 cr.set_source_rgba (bg_color.red / 65535.0, bg_color.green/65535.0, bg_color.blue/65535.0, 0.7)
882 cr.set_source_rgba (1.0, 0.0, 0.0, 0.5)
884 cr.set_source_rgba (fg_color.red / 65535.0, fg_color.green / 65535.0, fg_color.blue / 65535.0, 0.7)
887 def do_expose_event(self, event):
890 self.vbox.do_expose_event (self, event)
892 hd_plugin_type = UssdWidgetPlugin
894 # The code below is just for testing purposes.
895 # It allows to run the widget as a standalone process.
896 if __name__ == "__main__":
898 gobject.type_register(hd_plugin_type)
899 obj = gobject.new(hd_plugin_type, plugin_id="plugin_id")