1 """
2
3 @author: Fabio Erculiani <lxnay@sabayonlinux.org>
4 @contact: lxnay@sabayonlinux.org
5 @copyright: Fabio Erculiani
6 @license: GPL-2
7
8 B{Entropy Framework Output module}.
9
10 This module contains Entropy (user) Output classes and routines.
11
12 """
13
14 import sys, os
15 import curses
16 from entropy.const import etpUi
17 from entropy.exceptions import IncorrectParameter
18 from entropy.i18n import _
19 stuff = {}
20 stuff['cols'] = 30
21 try:
22 curses.setupterm()
23 stuff['cols'] = curses.tigetnum('cols')
24 except:
25 pass
26 stuff['cleanline'] = ""
28 stuff['cleanline'] = ""
29 count = stuff['cols']
30 while count:
31 stuff['cleanline'] += ' '
32 count -= 1
33 setcols()
34 stuff['cursor'] = False
35 stuff['ESC'] = chr(27)
36
37 havecolor=1
38 global dotitles
39 dotitles=1
40
41 esc_seq = "\x1b["
42
43 g_attr = {}
44 g_attr["normal"] = 0
45
46 g_attr["bold"] = 1
47 g_attr["faint"] = 2
48 g_attr["standout"] = 3
49 g_attr["underline"] = 4
50 g_attr["blink"] = 5
51 g_attr["overline"] = 6
52 g_attr["reverse"] = 7
53 g_attr["invisible"] = 8
54
55 g_attr["no-attr"] = 22
56 g_attr["no-standout"] = 23
57 g_attr["no-underline"] = 24
58 g_attr["no-blink"] = 25
59 g_attr["no-overline"] = 26
60 g_attr["no-reverse"] = 27
61
62
63 g_attr["black"] = 30
64 g_attr["red"] = 31
65 g_attr["green"] = 32
66 g_attr["yellow"] = 33
67 g_attr["blue"] = 34
68 g_attr["magenta"] = 35
69 g_attr["cyan"] = 36
70 g_attr["white"] = 37
71
72 g_attr["default"] = 39
73 g_attr["bg_black"] = 40
74 g_attr["bg_red"] = 41
75 g_attr["bg_green"] = 42
76 g_attr["bg_yellow"] = 43
77 g_attr["bg_blue"] = 44
78 g_attr["bg_magenta"] = 45
79 g_attr["bg_cyan"] = 46
80 g_attr["bg_white"] = 47
81 g_attr["bg_default"] = 49
82
83
84
85 -def color(fg, bg="default", attr=["normal"]):
86 mystr = esc_seq[:] + "%02d" % g_attr[fg]
87 for x in [bg]+attr:
88 mystr += ";%02d" % g_attr[x]
89 return mystr+"m"
90
91
92
93 codes={}
94 codes["reset"] = esc_seq + "39;49;00m"
95
96 codes["bold"] = esc_seq + "01m"
97 codes["faint"] = esc_seq + "02m"
98 codes["standout"] = esc_seq + "03m"
99 codes["underline"] = esc_seq + "04m"
100 codes["blink"] = esc_seq + "05m"
101 codes["overline"] = esc_seq + "06m"
102
103 ansi_color_codes = []
104 for x in xrange(30, 38):
105 ansi_color_codes.append("%im" % x)
106 ansi_color_codes.append("%i;01m" % x)
107
108 rgb_ansi_colors = ['0x000000', '0x555555', '0xAA0000', '0xFF5555', '0x00AA00',
109 '0x55FF55', '0xAA5500', '0xFFFF55', '0x0000AA', '0x5555FF', '0xAA00AA',
110 '0xFF55FF', '0x00AAAA', '0x55FFFF', '0xAAAAAA', '0xFFFFFF']
111
112 for x in xrange(len(rgb_ansi_colors)):
113 codes[rgb_ansi_colors[x]] = esc_seq + ansi_color_codes[x]
114
115 del x
116
117 codes["black"] = codes["0x000000"]
118 codes["darkgray"] = codes["0x555555"]
119
120 codes["red"] = codes["0xFF5555"]
121 codes["darkred"] = codes["0xAA0000"]
122
123 codes["green"] = codes["0x55FF55"]
124 codes["darkgreen"] = codes["0x00AA00"]
125
126 codes["yellow"] = codes["0xFFFF55"]
127 codes["brown"] = codes["0xAA5500"]
128
129 codes["blue"] = codes["0x5555FF"]
130 codes["darkblue"] = codes["0x0000AA"]
131
132 codes["fuchsia"] = codes["0xFF55FF"]
133 codes["purple"] = codes["0xAA00AA"]
134
135 codes["turquoise"] = codes["0x55FFFF"]
136 codes["teal"] = codes["0x00AAAA"]
137
138 codes["white"] = codes["0xFFFFFF"]
139 codes["lightgray"] = codes["0xAAAAAA"]
140
141 codes["darkteal"] = codes["turquoise"]
142 codes["darkyellow"] = codes["brown"]
143 codes["fuscia"] = codes["fuchsia"]
144 codes["white"] = codes["bold"]
145
146
147 codes["GOOD"] = codes["green"]
148 codes["WARN"] = codes["yellow"]
149 codes["BAD"] = codes["red"]
150 codes["HILITE"] = codes["teal"]
151 codes["BRACKET"] = codes["blue"]
152
153
154 codes["INFORM"] = codes["darkgreen"]
155 codes["UNMERGE_WARN"] = codes["red"]
156 codes["MERGE_LIST_PROGRESS"] = codes["yellow"]
157
159 """
160 Set new xterm title.
161
162 @param mystr: new xterm title
163 @type mystr: string
164 @keyword raw: write title in raw mode
165 @type raw: bool
166 """
167 if dotitles and "TERM" in os.environ and sys.stderr.isatty():
168 myt = os.environ["TERM"]
169 legal_terms = ["xterm","Eterm","aterm","rxvt","screen","kterm","rxvt-unicode","gnome"]
170 if myt in legal_terms:
171 if not raw:
172 mystr = "\x1b]0;%s\x07" % mystr
173 try:
174 sys.stderr.write(mystr)
175 except UnicodeEncodeError:
176 sys.stderr.write(mystr.encode('utf-8'))
177 sys.stderr.flush()
178
179 default_xterm_title = None
180
182 """
183 Reset xterm title to default.
184 """
185 global default_xterm_title
186 if default_xterm_title is None:
187 prompt_command = os.getenv('PROMPT_COMMAND')
188 if prompt_command == "":
189 default_xterm_title = ""
190 elif prompt_command is not None:
191 from entropy.tools import getstatusoutput
192 default_xterm_title = getstatusoutput(prompt_command)[1]
193 else:
194 pwd = os.getenv('PWD','')
195 home = os.getenv('HOME', '')
196 if home != '' and pwd.startswith(home):
197 pwd = '~' + pwd[len(home):]
198 default_xterm_title = '\x1b]0;%s@%s:%s\x07' % (
199 os.getenv('LOGNAME', ''),
200 os.getenv('HOSTNAME', '').split('.', 1)[0],
201 pwd)
202 xtermTitle(default_xterm_title)
203
205 """
206 Turn off title setting. In this way, xterm title won't be touched.
207 """
208 global dotitles
209 dotitles=0
210
212 """
213 Turn off colorization process-wide.
214 """
215 os.environ['ETP_NO_COLOR'] = "1"
216 global havecolor
217 havecolor=0
218
219 nc = os.getenv("ETP_NO_COLOR")
220 if nc:
221 nocolor()
222
224 """
225 Reset terminal color currently set.
226 """
227 return codes["reset"]
228
230 """
231 Colorize text with given color key using bash/terminal codes.
232
233 @param color_key: color identifier available in entropy.output.codes
234 @type color_key: string
235 @return: coloured text
236 @rtype: string
237 """
238 if etpUi['mute']:
239 return text
240 global havecolor
241 if havecolor:
242 return codes[color_key] + text + codes["reset"]
243 return text
244
246 """
247 Make text bold using bash/terminal codes.
248
249 @param text: text to colorize
250 @type text: string
251 @return: colorized text
252 @rtype: string
253 """
254 return colorize("bold", text)
255
257 """
258 Make text white using bash/terminal codes.
259
260 @param text: text to colorize
261 @type text: string
262 @return: colorized text
263 @rtype: string
264 """
265 return colorize("white", text)
266
268 """
269 Make text teal using bash/terminal codes.
270
271 @param text: text to colorize
272 @type text: string
273 @return: colorized text
274 @rtype: string
275 """
276 return colorize("teal", text)
277
279 """
280 Make text turquoise using bash/terminal codes.
281
282 @param text: text to colorize
283 @type text: string
284 @return: colorized text
285 @rtype: string
286 """
287 return colorize("turquoise", text)
288
290 """
291 Make text darkteal using bash/terminal codes.
292
293 @param text: text to colorize
294 @type text: string
295 @return: colorized text
296 @rtype: string
297 """
298 return colorize("darkteal", text)
299
301 """
302 Make text purple using bash/terminal codes.
303
304 @param text: text to colorize
305 @type text: string
306 @return: colorized text
307 @rtype: string
308 """
309 return colorize("purple", text)
310
312 """
313 Make text blue using bash/terminal codes.
314
315 @param text: text to colorize
316 @type text: string
317 @return: colorized text
318 @rtype: string
319 """
320 return colorize("blue", text)
321
323 """
324 Make text darkblue using bash/terminal codes.
325
326 @param text: text to colorize
327 @type text: string
328 @return: colorized text
329 @rtype: string
330 """
331 return colorize("darkblue", text)
332
334 """
335 Make text green using bash/terminal codes.
336
337 @param text: text to colorize
338 @type text: string
339 @return: colorized text
340 @rtype: string
341 """
342 return colorize("green", text)
343
345 """
346 Make text darkgreen using bash/terminal codes.
347
348 @param text: text to colorize
349 @type text: string
350 @return: colorized text
351 @rtype: string
352 """
353 return colorize("darkgreen", text)
354
356 """
357 Make text yellow using bash/terminal codes.
358
359 @param text: text to colorize
360 @type text: string
361 @return: colorized text
362 @rtype: string
363 """
364 return colorize("yellow", text)
365
367 """
368 Make text brown using bash/terminal codes.
369
370 @param text: text to colorize
371 @type text: string
372 @return: colorized text
373 @rtype: string
374 """
375 return colorize("brown", text)
376
378 """
379 Make text darkyellow using bash/terminal codes.
380
381 @param text: text to colorize
382 @type text: string
383 @return: colorized text
384 @rtype: string
385 """
386 return colorize("darkyellow", text)
387
389 """
390 Make text red using bash/terminal codes.
391
392 @param text: text to colorize
393 @type text: string
394 @return: colorized text
395 @rtype: string
396 """
397 return colorize("red", text)
398
400 """
401 Make text darkred using bash/terminal codes.
402
403 @param text: text to colorize
404 @type text: string
405 @return: colorized text
406 @rtype: string
407 """
408 return colorize("darkred", text)
409
411 """
412 Colorize package atoms with standard colors.
413
414 @param atom: atom string
415 @type atom: string
416 @return: colorized string
417 @rtype: string
418 """
419 out = atom.split("/")
420 return blue(out[0])+"/"+red(out[1])
421
423 """
424 Function used by Entropy text client (will be moved from here) to
425 print the menu output given a properly formatted list.
426 This method is not intended for general used and will be moved away from
427 here.
428 """
429 if args == None:
430 args = []
431
432 def orig_myfunc(x):
433 return x
434 def orig_myfunc_desc(x):
435 return x
436
437 try:
438 i = args.index("--help")
439 del args[i]
440 command = args.pop(0)
441 except ValueError:
442 command = None
443 except IndexError:
444 command = None
445 section_found = False
446 search_depth = 1
447
448
449 for item in data:
450 myfunc = orig_myfunc
451 myfunc_desc = orig_myfunc_desc
452
453 if not item:
454 if command == None or section_found:
455 writechar("\n")
456 else:
457 n_ident = item[0]
458 name = item[1]
459 n_d_ident = item[2]
460 desc = item[3]
461 if command != None:
462
463 if name == command and n_ident == search_depth:
464 try:
465 command = args.pop(0)
466 search_depth = n_ident + 1
467 except IndexError:
468 command = "##unused_from_now_on"
469 section_found = True
470 indent_level = n_ident
471 elif section_found:
472 if n_ident <= indent_level:
473 return
474 else:
475 continue
476
477 if n_ident == 0:
478 writechar(" ")
479
480 while n_ident > 0:
481 n_ident -= 1
482 writechar("\t")
483 n_ident = item[0]
484
485
486 if n_ident == 0:
487 myfunc = darkgreen
488 elif n_ident == 1:
489 myfunc = blue
490 myfunc_desc = darkgreen
491 elif n_ident == 2:
492 if not name.startswith("--"):
493 myfunc = red
494 myfunc_desc = brown
495 elif n_ident == 3:
496 myfunc = darkblue
497 myfunc_desc = purple
498 try:
499 print myfunc(name),
500 except UnicodeEncodeError:
501 print myfunc(name.encode('utf-8')),
502
503
504 if desc:
505 while n_d_ident > 0:
506 n_d_ident -= 1
507 writechar("\t")
508 try:
509 print myfunc_desc(desc),
510 except UnicodeEncodeError:
511 print myfunc_desc(desc.encode('utf-8')),
512 writechar("\n")
513
515 """
516 Print to stdout the terminal code to push back cursor at the beginning
517 of the line.
518 """
519 if havecolor:
520 sys.stdout.write(stuff['ESC'] + '[2K')
521 _flush_stdouterr()
522
526
528 """
529 Service function used by Entropy text client (will be moved from here)
530 to write error messages to stdout (not stderr, atm).
531 NOTE: don't use this directly but rather subclass TextInterface class.
532
533 @param msg: text message to print
534 @type msg: string
535 @keyword back: move text cursor back to the beginning of the line
536 @type back: bool
537 @keyword flush: flush stdout and stderr
538 @type flush: bool
539 @return: None
540 @rtype: None
541 """
542 if etpUi['mute']:
543 return
544 if not back:
545 setcols()
546 reset_cursor()
547 writechar("\r")
548 if back:
549 try:
550 print darkred(">>"),msg,
551 except UnicodeEncodeError:
552 print darkred(">>"),msg.encode('utf-8'),
553 else:
554 try:
555 print darkred(">>"),msg
556 except UnicodeEncodeError:
557 print darkred(">>"),msg.encode('utf-8')
558 if flush:
559 _flush_stdouterr()
560
562 """
563 Service function used by Entropy text client (will be moved from here)
564 to write info messages to stdout (not stderr, atm).
565 NOTE: don't use this directly but rather subclass TextInterface class.
566
567 @param msg: text message to print
568 @type msg: string
569 @keyword back: move text cursor back to the beginning of the line
570 @type back: bool
571 @keyword flush: flush stdout and stderr
572 @type flush: bool
573 @return: None
574 @rtype: None
575 """
576 if etpUi['mute']:
577 return
578 if not back:
579 setcols()
580 reset_cursor()
581 writechar("\r")
582 if back:
583 try:
584 print darkgreen(">>"),msg,
585 except UnicodeEncodeError:
586 print darkgreen(">>"),msg.encode('utf-8'),
587 else:
588 try:
589 print darkgreen(">>"),msg
590 except UnicodeEncodeError:
591 print darkgreen(">>"),msg.encode('utf-8')
592 if flush:
593 _flush_stdouterr()
594
596 """
597 Service function used by Entropy text client (will be moved from here)
598 to write warning messages to stdout (not stderr, atm).
599 NOTE: don't use this directly but rather subclass TextInterface class.
600
601 @param msg: text message to print
602 @type msg: string
603 @keyword back: move text cursor back to the beginning of the line
604 @type back: bool
605 @keyword flush: flush stdout and stderr
606 @type flush: bool
607 @return: None
608 @rtype: None
609 """
610 if etpUi['mute']:
611 return
612 if not back:
613 setcols()
614 reset_cursor()
615 writechar("\r")
616 if back:
617 try:
618 print red(">>"),msg,
619 except UnicodeEncodeError:
620 print red(">>"),msg.encode('utf-8'),
621 else:
622 try:
623 print red(">>"),msg
624 except UnicodeEncodeError:
625 print red(">>"),msg.encode('utf-8')
626 if flush:
627 _flush_stdouterr()
628
630 """
631 Service function used by Entropy text client (will be moved from here)
632 to write generic messages to stdout (not stderr, atm).
633 NOTE: don't use this directly but rather subclass TextInterface class.
634
635 @param msg: text message to print
636 @type msg: string
637 @return: None
638 @rtype: None
639 """
640 if etpUi['mute']:
641 return
642
643
644 try:
645 print msg
646 except UnicodeEncodeError:
647 print msg.encode('utf-8')
648 _flush_stdouterr()
649
651 """
652 Write characters to stdout (will be moved from here).
653
654 @param chars: chars to write
655 @type chars: string
656 """
657 if etpUi['mute']:
658 return
659 try:
660 sys.stdout.write(chars)
661 sys.stdout.flush()
662 except IOError, e:
663 if e.errno == 32:
664 return
665 raise
666
667 -def readtext(request, password = False):
668 """
669 Read text from stdin and return it (will be moved from here).
670
671 @param request: textual request to print
672 @type request: string
673 @keyword password: if you are requesting a password, set this to True
674 @type password: bool
675 @return: text read back from stdin
676 @rtype: string
677 """
678 xtermTitle(_("Entropy needs your attention"))
679 if password:
680 from getpass import getpass
681 try:
682 text = getpass(request+" ")
683 except UnicodeEncodeError:
684 text = getpass(request.encode('utf-8')+" ")
685 else:
686 try:
687 print request,"",
688 except UnicodeEncodeError:
689 print request.encode('utf-8'),"",
690 _flush_stdouterr()
691 text = _my_raw_input()
692 return text
693
708
710
711 """
712 TextInterface is a base class for handling the communication between
713 user and Entropy-based applications.
714
715 This class works for text-based applications, it must be inherited
716 from subclasses and its methods reimplemented to make Entropy working
717 on situations where a terminal is not used as UI (Graphical applications,
718 web-based interfaces, remote interfaces, etc).
719
720 Every part of Entropy is using the methods in this class to communicate
721 with the user, channel is bi-directional.
722
723 """
724
725 - def updateProgress(self, text, header = "", footer = "", back = False,
726 importance = 0, type = "info", count = None, percent = False):
727
728 """
729 Text output print function. By default text is written to stdout.
730
731 @param text: text to write to stdout
732 @type text: string
733 @keyword header: text header (decoration?)
734 @type header: string
735 @keyword footer: text footer (decoration?)
736 @type footer: string
737 @keyword back: push back cursor to the beginning of the line
738 @type back: bool
739 @keyword importance: message importance (default valid values:
740 0, 1, 2, 3
741 @type importance: int
742 @keyword type: message type (default valid values: "info", "warning",
743 "error")
744 @type type: string
745 @keyword count: tuple of lengh 2, containing count information to make
746 function print something like "(10/100) doing stuff". In this case
747 tuple would be: (10, 100,)
748 @type count: tuple
749 @keyword percent: determine whether "count" argument should be printed
750 as percentual value (for values like (10, 100,), "(10%) doing stuff"
751 will be printed.
752 @keyword percent: bool
753 @return: None
754 @rtype: None
755 """
756
757 if etpUi['quiet'] or etpUi['mute']:
758 return
759
760 _flush_stdouterr()
761
762 myfunc = print_info
763 if type == "warning":
764 myfunc = print_warning
765 elif type == "error":
766 myfunc = print_error
767
768 count_str = ""
769 if count:
770 if len(count) > 1:
771 if percent:
772 percent_str = str(round((float(count[0])/count[1])*100,1))
773 count_str = " ("+percent_str+"%) "
774 else:
775 count_str = " (%s/%s) " % (red(str(count[0])),
776 blue(str(count[1])),)
777
778 myfunc(header+count_str+text+footer, back = back, flush = False)
779 _flush_stdouterr()
780
781 - def askQuestion(self, question, importance = 0, responses = None):
782
783 """
784 Questions asking function. It asks the user to answer the question given
785 by choosing between a preset list of answers given by the "reposonses"
786 argument.
787
788 @param question: question text
789 @type question: string
790 @keyword importance: question importance (no default valid values)
791 @type importance: int
792 @keyword responses: list of valid answers which user has to choose from
793 @type responses: tuple or list
794 @return: None
795 @rtype: None
796 """
797
798 if responses is None:
799 responses = (_("Yes"),_("No"),)
800
801 colours = [green, red, blue, darkgreen, darkred, darkblue,
802 brown, purple]
803 colours_len = len(colours)
804
805 try:
806 print darkgreen(question),
807 except UnicodeEncodeError:
808 print darkgreen(question.encode('utf-8')),
809 _flush_stdouterr()
810
811 try:
812 while 1:
813
814 xtermTitle(_("Entropy got a question for you"))
815 _flush_stdouterr()
816 answer_items = [colours[x % colours_len](responses[x]) \
817 for x in xrange(len(responses))]
818 response = _my_raw_input("["+"/".join(answer_items)+"] ")
819 _flush_stdouterr()
820
821 for key in responses:
822 if response.upper() == key[:len(response)].upper():
823 xtermTitleReset()
824 return key
825 _flush_stdouterr()
826
827 except (EOFError, KeyboardInterrupt):
828 print "%s." % (_("Interrupted"),)
829 xtermTitleReset()
830 raise SystemExit(100)
831
832 xtermTitleReset()
833 _flush_stdouterr()
834
835 - def inputBox(self, title, input_parameters, cancel_button = True):
836 """
837 Generic input box (form) creator and data collector.
838
839 @param title: input box title
840 @type title: string
841 @param input_parameters: list of properly formatted tuple items.
842 @type input_parameters: list
843 @keyword cancel_button: make possible to "cancel" the input request.
844 @type cancel_button: bool
845 @return: dict containing input box answers
846 @rtype: dict
847
848 input_parameters supported items:
849
850 [input id], [input text title], [input verification callback], [
851 no text echo?]
852 ('identifier 1', 'input text 1', input_verification_callback, False)
853
854 ('item_3', ('checkbox', 'Checkbox option (boolean request) - please choose',),
855 input_verification_callback, True)
856
857 ('item_4', ('combo', ('Select your favorite option', ['option 1', 'option 2', 'option 3']),),
858 input_verification_callback, True)
859
860 ('item_4',('list',('Setup your list',['default list item 1', 'default list item 2']),),
861 input_verification_callback, True)
862
863 """
864 results = {}
865 if title:
866 try:
867 print title
868 except UnicodeEncodeError:
869 print title.encode('utf-8')
870 _flush_stdouterr()
871
872 def option_chooser(option_data):
873 mydict = {}
874 counter = 1
875 option_text, option_list = option_data
876 self.updateProgress(option_text)
877 for item in option_list:
878 mydict[counter] = item
879 txt = "[%s] %s" % (darkgreen(str(counter)), blue(item),)
880 self.updateProgress(txt)
881 counter += 1
882 while 1:
883 myresult = readtext("%s:" % (_('Selected number'),)).decode('utf-8')
884 try:
885 myresult = int(myresult)
886 except ValueError:
887 continue
888 selected = mydict.get(myresult)
889 if selected != None:
890 return myresult, selected
891
892 def list_editor(option_data, can_cancel, callback):
893
894 def selaction():
895 self.updateProgress('')
896 self.updateProgress(darkred(_("Please select an option")))
897 if can_cancel:
898 self.updateProgress(" ("+blue("-1")+") "+darkred(_("Discard all")))
899 self.updateProgress(" ("+blue("0")+") "+darkgreen(_("Confirm")))
900 self.updateProgress(" ("+blue("1")+") "+brown(_("Add item")))
901 self.updateProgress(" ("+blue("2")+") "+darkblue(_("Remove item")))
902 self.updateProgress(" ("+blue("3")+") "+darkgreen(_("Show current list")))
903
904 self.updateProgress('')
905 action = readtext(darkgreen(_("Your choice (type a number and press enter):"))+" ")
906 return action
907
908 mydict = {}
909 counter = 1
910 valid_actions = [0,1,2,3]
911 if can_cancel: valid_actions.insert(0,-1)
912 option_text, option_list = option_data
913 txt = "%s:" % (blue(option_text),)
914 self.updateProgress(txt)
915
916 for item in option_list:
917 mydict[counter] = item
918 txt = "[%s] %s" % (darkgreen(str(counter)), blue(item),)
919 self.updateProgress(txt)
920 counter += 1
921
922 def show_current_list():
923 for key in sorted(mydict):
924 txt = "[%s] %s" % (darkgreen(str(key)), blue(mydict[key]),)
925 self.updateProgress(txt)
926
927 while 1:
928 try:
929 action = int(selaction())
930 except (ValueError,TypeError,):
931 self.updateProgress(_("You don't have typed a number."), type = "warning")
932 continue
933 if action not in valid_actions:
934 self.updateProgress(_("Invalid action."), type = "warning")
935 continue
936 if action == -1:
937 raise KeyboardInterrupt
938 elif action == 0:
939 break
940 elif action == 1:
941 while 1:
942 try:
943 s_el = readtext(darkred(_("String to add:"))+" ")
944 if not callback(s_el):
945 raise ValueError
946 mydict[counter] = s_el
947 counter += 1
948 except (ValueError,):
949 self.updateProgress(_("Invalid string."), type = "warning")
950 continue
951 break
952 show_current_list()
953 continue
954 elif action == 2:
955 while 1:
956 try:
957 s_el = int(readtext(darkred(_("Element number to remove:"))+" "))
958 if s_el not in mydict:
959 raise ValueError
960 del mydict[s_el]
961 except (ValueError,TypeError,):
962 self.updateProgress(_("Invalid element."), type = "warning")
963 continue
964 break
965 show_current_list()
966 continue
967 elif action == 3:
968 show_current_list()
969 continue
970 break
971
972 mylist = [mydict[x] for x in sorted(mydict)]
973 return mylist
974
975 for identifier, input_text, callback, password in input_parameters:
976 while 1:
977 use_cb = True
978 try:
979 if isinstance(input_text,tuple):
980 myresult = False
981 input_type, data = input_text
982 if input_type == "checkbox":
983 answer = self.askQuestion(data)
984 if answer == "Yes": myresult = True
985 elif input_type == "combo":
986 myresult = option_chooser(data)
987 elif input_type == "list":
988 use_cb = False
989 myresult = list_editor(data, cancel_button, callback)
990 else:
991 myresult = readtext(input_text+":", password = password).decode('utf-8')
992 except (KeyboardInterrupt,EOFError,):
993 if not cancel_button:
994 continue
995 return None
996 valid = True
997 if use_cb:
998 valid = callback(myresult)
999 if valid:
1000 results[identifier] = myresult
1001 break
1002 return results
1003
1004
1005
1006 - def cycleDone(self):
1007 """
1008 Not actually implemented. Can be useful for external applications and
1009 its used to determine when a certain transaction is done.
1010 """
1011 pass
1012
1013 - def setTitle(self, title):
1014 """
1015 Set application title.
1016
1017 @param title: new application title
1018 @type title: string
1019 """
1020 xtermTitle(title)
1021
1022 - def setTotalCycles(self, total):
1023 """
1024 Not actually implemented. Can be useful for external applications and
1025 its used to set the amount of logical transactions that this interface
1026 has to go through.
1027 """
1028 pass
1029
1030 - def nocolor(self):
1031 """
1032 Disable coloured output. Used for terminals.
1033 """
1034 nocolor()
1035
1036 - def notitles(self):
1037 """
1038 Disable the ability to effectively set the application title.
1039 """
1040 notitles()
1041