1
2 """
3
4 @author: Fabio Erculiani <lxnay@sabayonlinux.org>
5 @contact: lxnay@sabayonlinux.org
6 @copyright: Fabio Erculiani
7 @license: GPL-2
8
9 B{Entropy Framework Output module}.
10
11 This module contains Entropy (user) Output classes and routines.
12
13 """
14 import sys, os
15 import curses
16 from entropy.const import etpUi, const_convert_to_rawstring, const_isstring
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 range(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 range(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 Return whether current stdout is a TTY.
161
162 @return: tty? => True
163 @rtype: bool
164 """
165 fn = sys.stdout.fileno()
166 return os.isatty(fn)
167
169 """
170 Set new xterm title.
171
172 @param mystr: new xterm title
173 @type mystr: string
174 @keyword raw: write title in raw mode
175 @type raw: bool
176 """
177 if dotitles and "TERM" in os.environ and sys.stderr.isatty():
178 myt = os.environ["TERM"]
179 legal_terms = ["xterm", "Eterm", "aterm", "rxvt", "screen", "kterm", "rxvt-unicode", "gnome"]
180 if myt in legal_terms:
181 if not raw:
182 mystr = "\x1b]0;%s\x07" % mystr
183 try:
184 sys.stderr.write(mystr)
185 except UnicodeEncodeError:
186 sys.stderr.write(mystr.encode('utf-8'))
187 sys.stderr.flush()
188
189 default_xterm_title = None
190
192 """
193 Reset xterm title to default.
194 """
195 global default_xterm_title
196 if default_xterm_title is None:
197 prompt_command = os.getenv('PROMPT_COMMAND')
198 if not prompt_command:
199 default_xterm_title = ""
200 elif prompt_command is not None:
201 from entropy.tools import getstatusoutput
202 default_xterm_title = getstatusoutput(prompt_command)[1]
203 else:
204 pwd = os.getenv('PWD', '')
205 home = os.getenv('HOME', '')
206 if home != '' and pwd.startswith(home):
207 pwd = '~' + pwd[len(home):]
208 default_xterm_title = '\x1b]0;%s@%s:%s\x07' % (
209 os.getenv('LOGNAME', ''),
210 os.getenv('HOSTNAME', '').split('.', 1)[0],
211 pwd)
212 xtermTitle(default_xterm_title)
213
215 """
216 Turn off title setting. In this way, xterm title won't be touched.
217 """
218 global dotitles
219 dotitles=0
220
222 """
223 Turn off colorization process-wide.
224 """
225 os.environ['ETP_NO_COLOR'] = "1"
226 global havecolor
227 havecolor=0
228
229 nc = os.getenv("ETP_NO_COLOR")
230 if nc:
231 nocolor()
232
234 """
235 Reset terminal color currently set.
236 """
237 return codes["reset"]
238
240 """
241 Colorize text with given color key using bash/terminal codes.
242
243 @param color_key: color identifier available in entropy.output.codes
244 @type color_key: string
245 @return: coloured text
246 @rtype: string
247 """
248 if etpUi['mute']:
249 return text
250 global havecolor
251 if havecolor:
252 return codes[color_key] + text + codes["reset"]
253 return text
254
256 """
257 Make text bold using bash/terminal codes.
258
259 @param text: text to colorize
260 @type text: string
261 @return: colorized text
262 @rtype: string
263 """
264 return colorize("bold", text)
265
267 """
268 Make text white using bash/terminal codes.
269
270 @param text: text to colorize
271 @type text: string
272 @return: colorized text
273 @rtype: string
274 """
275 return colorize("white", text)
276
278 """
279 Make text teal using bash/terminal codes.
280
281 @param text: text to colorize
282 @type text: string
283 @return: colorized text
284 @rtype: string
285 """
286 return colorize("teal", text)
287
289 """
290 Make text turquoise using bash/terminal codes.
291
292 @param text: text to colorize
293 @type text: string
294 @return: colorized text
295 @rtype: string
296 """
297 return colorize("turquoise", text)
298
300 """
301 Make text darkteal using bash/terminal codes.
302
303 @param text: text to colorize
304 @type text: string
305 @return: colorized text
306 @rtype: string
307 """
308 return colorize("darkteal", text)
309
311 """
312 Make text purple using bash/terminal codes.
313
314 @param text: text to colorize
315 @type text: string
316 @return: colorized text
317 @rtype: string
318 """
319 return colorize("purple", text)
320
322 """
323 Make text blue using bash/terminal codes.
324
325 @param text: text to colorize
326 @type text: string
327 @return: colorized text
328 @rtype: string
329 """
330 return colorize("blue", text)
331
333 """
334 Make text darkblue using bash/terminal codes.
335
336 @param text: text to colorize
337 @type text: string
338 @return: colorized text
339 @rtype: string
340 """
341 return colorize("darkblue", text)
342
344 """
345 Make text green using bash/terminal codes.
346
347 @param text: text to colorize
348 @type text: string
349 @return: colorized text
350 @rtype: string
351 """
352 return colorize("green", text)
353
355 """
356 Make text darkgreen using bash/terminal codes.
357
358 @param text: text to colorize
359 @type text: string
360 @return: colorized text
361 @rtype: string
362 """
363 return colorize("darkgreen", text)
364
366 """
367 Make text yellow using bash/terminal codes.
368
369 @param text: text to colorize
370 @type text: string
371 @return: colorized text
372 @rtype: string
373 """
374 return colorize("yellow", text)
375
377 """
378 Make text brown using bash/terminal codes.
379
380 @param text: text to colorize
381 @type text: string
382 @return: colorized text
383 @rtype: string
384 """
385 return colorize("brown", text)
386
388 """
389 Make text darkyellow using bash/terminal codes.
390
391 @param text: text to colorize
392 @type text: string
393 @return: colorized text
394 @rtype: string
395 """
396 return colorize("darkyellow", text)
397
399 """
400 Make text red using bash/terminal codes.
401
402 @param text: text to colorize
403 @type text: string
404 @return: colorized text
405 @rtype: string
406 """
407 return colorize("red", text)
408
410 """
411 Make text darkred using bash/terminal codes.
412
413 @param text: text to colorize
414 @type text: string
415 @return: colorized text
416 @rtype: string
417 """
418 return colorize("darkred", text)
419
421 """
422 Colorize package atoms with standard colors.
423
424 @param atom: atom string
425 @type atom: string
426 @return: colorized string
427 @rtype: string
428 """
429 out = atom.split("/")
430 return blue(out[0])+"/"+red(out[1])
431
433 """
434 Function used by Entropy text client (will be moved from here) to
435 print the menu output given a properly formatted list.
436 This method is not intended for general used and will be moved away from
437 here.
438 """
439 if args == None:
440 args = []
441
442 def orig_myfunc(x):
443 return x
444 def orig_myfunc_desc(x):
445 return x
446
447 try:
448 i = args.index("--help")
449 del args[i]
450 command = args.pop(0)
451 except ValueError:
452 command = None
453 except IndexError:
454 command = None
455 section_found = False
456 search_depth = 1
457
458
459 for item in data:
460 myfunc = orig_myfunc
461 myfunc_desc = orig_myfunc_desc
462
463 if not item:
464 if command == None or section_found:
465 writechar("\n")
466 else:
467 n_ident = item[0]
468 name = item[1]
469 n_d_ident = item[2]
470 desc = item[3]
471 if command != None:
472
473 if name == command and n_ident == search_depth:
474 try:
475 command = args.pop(0)
476 search_depth = n_ident + 1
477 except IndexError:
478 command = "##unused_from_now_on"
479 section_found = True
480 indent_level = n_ident
481 elif section_found:
482 if n_ident <= indent_level:
483 return
484 else:
485 continue
486
487 if n_ident == 0:
488 writechar(" ")
489
490 while n_ident > 0:
491 n_ident -= 1
492 writechar("\t")
493 n_ident = item[0]
494
495
496 if n_ident == 0:
497 myfunc = darkgreen
498 elif n_ident == 1:
499 myfunc = blue
500 myfunc_desc = darkgreen
501 elif n_ident == 2:
502 if not name.startswith("--"):
503 myfunc = red
504 myfunc_desc = brown
505 elif n_ident == 3:
506 myfunc = darkblue
507 myfunc_desc = purple
508 func_out = myfunc(name)
509 print_generic(func_out, end = "")
510
511
512 if desc:
513 while n_d_ident > 0:
514 n_d_ident -= 1
515 writechar("\t")
516 desc = myfunc_desc(desc)
517 print_generic(desc, end = "")
518 writechar("\n")
519
521 """
522 Print to stdout the terminal code to push back cursor at the beginning
523 of the line.
524 """
525 if havecolor:
526 sys.stdout.write(stuff['ESC'] + '[2K')
527 _flush_stdouterr()
528
532
534 if not const_isstring(msg):
535 msg = repr(msg)
536 try:
537 sys.stdout.write(msg)
538 except UnicodeEncodeError:
539 msg = msg.encode('utf-8')
540 if sys.hexversion >= 0x3000000:
541 sys.stdout.buffer.write(msg)
542 else:
543 sys.stdout.write(msg)
544
545 -def _print_prio(msg, color_func, back = False, flush = True, end = '\n'):
546 if etpUi['mute']:
547 return
548 if not back:
549 setcols()
550 reset_cursor()
551 if is_stdout_a_tty():
552 writechar("\r")
553 if back:
554 msg = color_func(">>") + " " + msg
555 else:
556 msg = color_func(">>") + " " + msg + end
557
558 _stdout_write(msg)
559 if flush:
560 _flush_stdouterr()
561
562 -def print_error(msg, back = False, flush = True, end = '\n'):
563 """
564 Service function used by Entropy text client (will be moved from here)
565 to write error messages to stdout (not stderr, atm).
566 NOTE: don't use this directly but rather subclass TextInterface class.
567
568 @param msg: text message to print
569 @type msg: string
570 @keyword back: move text cursor back to the beginning of the line
571 @type back: bool
572 @keyword flush: flush stdout and stderr
573 @type flush: bool
574 @return: None
575 @rtype: None
576 """
577 return _print_prio(msg, darkred, back = back, flush = flush, end = end)
578
579 -def print_info(msg, back = False, flush = True, end = '\n'):
580 """
581 Service function used by Entropy text client (will be moved from here)
582 to write info messages to stdout (not stderr, atm).
583 NOTE: don't use this directly but rather subclass TextInterface class.
584
585 @param msg: text message to print
586 @type msg: string
587 @keyword back: move text cursor back to the beginning of the line
588 @type back: bool
589 @keyword flush: flush stdout and stderr
590 @type flush: bool
591 @return: None
592 @rtype: None
593 """
594 return _print_prio(msg, darkgreen, back = back, flush = flush, end = end)
595
597 """
598 Service function used by Entropy text client (will be moved from here)
599 to write warning messages to stdout (not stderr, atm).
600 NOTE: don't use this directly but rather subclass TextInterface class.
601
602 @param msg: text message to print
603 @type msg: string
604 @keyword back: move text cursor back to the beginning of the line
605 @type back: bool
606 @keyword flush: flush stdout and stderr
607 @type flush: bool
608 @return: None
609 @rtype: None
610 """
611 return _print_prio(msg, brown, back = back, flush = flush, end = end)
612
614 """
615 Service function used by Entropy text client (will be moved from here)
616 to write generic messages to stdout (not stderr, atm).
617 NOTE: don't use this directly but rather subclass TextInterface class.
618 """
619 if etpUi['mute']:
620 return
621
622
623 for msg in args:
624 _stdout_write(msg)
625 sys.stdout.write(" ")
626
627 end = kwargs.get('end', '\n')
628 _stdout_write(end)
629 _flush_stdouterr()
630
632 """
633 Write characters to stdout (will be moved from here).
634
635 @param chars: chars to write
636 @type chars: string
637 """
638 if etpUi['mute']:
639 return
640 try:
641 sys.stdout.write(chars)
642 sys.stdout.flush()
643 except IOError as e:
644 if e.errno == 32:
645 return
646 raise
647
648 -def readtext(request, password = False):
649 """
650 Read text from stdin and return it (will be moved from here).
651
652 @param request: textual request to print
653 @type request: string
654 @keyword password: if you are requesting a password, set this to True
655 @type password: bool
656 @return: text read back from stdin
657 @rtype: string
658 """
659 xtermTitle(_("Entropy needs your attention"))
660 if password:
661 from getpass import getpass
662 try:
663 text = getpass(request+" ")
664 except UnicodeEncodeError:
665 text = getpass(request.encode('utf-8')+" ")
666 else:
667 try:
668 sys.stdout.write(request)
669 except UnicodeEncodeError:
670 sys.stdout.write(request.encode('utf-8'))
671 _flush_stdouterr()
672 text = _my_raw_input()
673 return text
674
689
691
692 """
693 TextInterface is a base class for handling the communication between
694 user and Entropy-based applications.
695
696 This class works for text-based applications, it must be inherited
697 from subclasses and its methods reimplemented to make Entropy working
698 on situations where a terminal is not used as UI (Graphical applications,
699 web-based interfaces, remote interfaces, etc).
700
701 Every part of Entropy is using the methods in this class to communicate
702 with the user, channel is bi-directional.
703
704 """
705
706 - def updateProgress(self, text, header = "", footer = "", back = False,
707 importance = 0, type = "info", count = None, percent = False):
708
709 """
710 Text output print function. By default text is written to stdout.
711
712 @param text: text to write to stdout
713 @type text: string
714 @keyword header: text header (decoration?)
715 @type header: string
716 @keyword footer: text footer (decoration?)
717 @type footer: string
718 @keyword back: push back cursor to the beginning of the line
719 @type back: bool
720 @keyword importance: message importance (default valid values:
721 0, 1, 2, 3
722 @type importance: int
723 @keyword type: message type (default valid values: "info", "warning",
724 "error")
725 @type type: string
726 @keyword count: tuple of lengh 2, containing count information to make
727 function print something like "(10/100) doing stuff". In this case
728 tuple would be: (10, 100,)
729 @type count: tuple
730 @keyword percent: determine whether "count" argument should be printed
731 as percentual value (for values like (10, 100,), "(10%) doing stuff"
732 will be printed.
733 @keyword percent: bool
734 @return: None
735 @rtype: None
736 """
737
738 if etpUi['quiet'] or etpUi['mute']:
739 return
740
741 _flush_stdouterr()
742
743 myfunc = print_info
744 if type == "warning":
745 myfunc = print_warning
746 elif type == "error":
747 myfunc = print_error
748
749 count_str = ""
750 if count:
751 if len(count) > 1:
752 if percent:
753 percent_str = str(round((float(count[0])/count[1])*100, 1))
754 count_str = " ("+percent_str+"%) "
755 else:
756 count_str = " (%s/%s) " % (red(str(count[0])),
757 blue(str(count[1])),)
758
759 myfunc(header+count_str+text+footer, back = back, flush = False)
760 _flush_stdouterr()
761
762 - def askQuestion(self, question, importance = 0, responses = None):
763
764 """
765 Questions asking function. It asks the user to answer the question given
766 by choosing between a preset list of answers given by the "reposonses"
767 argument.
768
769 @param question: question text
770 @type question: string
771 @keyword importance: question importance (no default valid values)
772 @type importance: int
773 @keyword responses: list of valid answers which user has to choose from
774 @type responses: tuple or list
775 @return: None
776 @rtype: None
777 """
778
779 if responses is None:
780 responses = (_("Yes"), _("No"),)
781
782 colours = [green, red, blue, darkgreen, darkred, darkblue,
783 brown, purple]
784 colours_len = len(colours)
785
786 try:
787 sys.stdout.write(darkgreen(question) + " ")
788 except UnicodeEncodeError:
789 sys.stdout.write(darkgreen(question.encode('utf-8')) + " ")
790 _flush_stdouterr()
791
792 try:
793 while True:
794
795 xtermTitle(_("Entropy got a question for you"))
796 _flush_stdouterr()
797 answer_items = [colours[x % colours_len](responses[x]) \
798 for x in range(len(responses))]
799 response = _my_raw_input("["+"/".join(answer_items)+"] ")
800 _flush_stdouterr()
801
802 for key in responses:
803 if response.upper() == key[:len(response)].upper():
804 xtermTitleReset()
805 return key
806 _flush_stdouterr()
807
808 except (EOFError, KeyboardInterrupt):
809 msg = "%s.\n" % (_("Interrupted"),)
810 try:
811 sys.stdout.write(msg)
812 except UnicodeEncodeError:
813 sys.stdout.write(msg.encode("utf-8"))
814 xtermTitleReset()
815 raise SystemExit(100)
816
817 xtermTitleReset()
818 _flush_stdouterr()
819
820 - def inputBox(self, title, input_parameters, cancel_button = True):
821 """
822 Generic input box (form) creator and data collector.
823
824 @param title: input box title
825 @type title: string
826 @param input_parameters: list of properly formatted tuple items.
827 @type input_parameters: list
828 @keyword cancel_button: make possible to "cancel" the input request.
829 @type cancel_button: bool
830 @return: dict containing input box answers
831 @rtype: dict
832
833 input_parameters supported items:
834
835 [input id], [input text title], [input verification callback], [
836 no text echo?]
837 ('identifier 1', 'input text 1', input_verification_callback, False)
838
839 ('item_3', ('checkbox', 'Checkbox option (boolean request) - please choose',),
840 input_verification_callback, True)
841
842 ('item_4', ('combo', ('Select your favorite option', ['option 1', 'option 2', 'option 3']),),
843 input_verification_callback, True)
844
845 ('item_4',('list',('Setup your list',['default list item 1', 'default list item 2']),),
846 input_verification_callback, True)
847
848 """
849 results = {}
850 if title:
851 try:
852 sys.stdout.write(title + "\n")
853 except UnicodeEncodeError:
854 sys.stdout.write(title.encode('utf-8') + "\n")
855 _flush_stdouterr()
856
857 def option_chooser(option_data):
858 mydict = {}
859 counter = 1
860 option_text, option_list = option_data
861 self.updateProgress(option_text)
862 for item in option_list:
863 mydict[counter] = item
864 txt = "[%s] %s" % (darkgreen(str(counter)), blue(item),)
865 self.updateProgress(txt)
866 counter += 1
867 while True:
868 myresult = readtext("%s:" % (_('Selected number'),)).decode('utf-8')
869 try:
870 myresult = int(myresult)
871 except ValueError:
872 continue
873 selected = mydict.get(myresult)
874 if selected != None:
875 return myresult, selected
876
877 def list_editor(option_data, can_cancel, callback):
878
879 def selaction():
880 self.updateProgress('')
881 self.updateProgress(darkred(_("Please select an option")))
882 if can_cancel:
883 self.updateProgress(" ("+blue("-1")+") "+darkred(_("Discard all")))
884 self.updateProgress(" ("+blue("0")+") "+darkgreen(_("Confirm")))
885 self.updateProgress(" ("+blue("1")+") "+brown(_("Add item")))
886 self.updateProgress(" ("+blue("2")+") "+darkblue(_("Remove item")))
887 self.updateProgress(" ("+blue("3")+") "+darkgreen(_("Show current list")))
888
889 self.updateProgress('')
890 action = readtext(darkgreen(_("Your choice (type a number and press enter):"))+" ")
891 return action
892
893 mydict = {}
894 counter = 1
895 valid_actions = [0, 1, 2, 3]
896 if can_cancel: valid_actions.insert(0, -1)
897 option_text, option_list = option_data
898 txt = "%s:" % (blue(option_text),)
899 self.updateProgress(txt)
900
901 for item in option_list:
902 mydict[counter] = item
903 txt = "[%s] %s" % (darkgreen(str(counter)), blue(item),)
904 self.updateProgress(txt)
905 counter += 1
906
907 def show_current_list():
908 for key in sorted(mydict):
909 txt = "[%s] %s" % (darkgreen(str(key)), blue(mydict[key]),)
910 self.updateProgress(txt)
911
912 while True:
913 try:
914 action = int(selaction())
915 except (ValueError, TypeError,):
916 self.updateProgress(_("You don't have typed a number."), type = "warning")
917 continue
918 if action not in valid_actions:
919 self.updateProgress(_("Invalid action."), type = "warning")
920 continue
921 if action == -1:
922 raise KeyboardInterrupt
923 elif action == 0:
924 break
925 elif action == 1:
926 while True:
927 try:
928 s_el = readtext(darkred(_("String to add:"))+" ")
929 if not callback(s_el):
930 raise ValueError
931 mydict[counter] = s_el
932 counter += 1
933 except (ValueError,):
934 self.updateProgress(_("Invalid string."), type = "warning")
935 continue
936 break
937 show_current_list()
938 continue
939 elif action == 2:
940 while True:
941 try:
942 s_el = int(readtext(darkred(_("Element number to remove:"))+" "))
943 if s_el not in mydict:
944 raise ValueError
945 del mydict[s_el]
946 except (ValueError, TypeError,):
947 self.updateProgress(_("Invalid element."), type = "warning")
948 continue
949 break
950 show_current_list()
951 continue
952 elif action == 3:
953 show_current_list()
954 continue
955 break
956
957 mylist = [mydict[x] for x in sorted(mydict)]
958 return mylist
959
960 for identifier, input_text, callback, password in input_parameters:
961 while True:
962 use_cb = True
963 try:
964 if isinstance(input_text, tuple):
965 myresult = False
966 input_type, data = input_text
967 if input_type == "checkbox":
968 answer = self.askQuestion(data)
969 if answer == "Yes": myresult = True
970 elif input_type == "combo":
971 myresult = option_chooser(data)
972 elif input_type == "list":
973 use_cb = False
974 myresult = list_editor(data, cancel_button, callback)
975 else:
976 myresult = readtext(input_text+":", password = password).decode('utf-8')
977 except (KeyboardInterrupt, EOFError,):
978 if not cancel_button:
979 continue
980 return None
981 valid = True
982 if use_cb:
983 valid = callback(myresult)
984 if valid:
985 results[identifier] = myresult
986 break
987 return results
988
989
990
991 - def cycleDone(self):
992 """
993 Not actually implemented. Can be useful for external applications and
994 its used to determine when a certain transaction is done.
995 """
996 pass
997
998 - def setTitle(self, title):
999 """
1000 Set application title.
1001
1002 @param title: new application title
1003 @type title: string
1004 """
1005 xtermTitle(title)
1006
1007 - def setTotalCycles(self, total):
1008 """
1009 Not actually implemented. Can be useful for external applications and
1010 its used to set the amount of logical transactions that this interface
1011 has to go through.
1012 """
1013 pass
1014
1015 - def nocolor(self):
1016 """
1017 Disable coloured output. Used for terminals.
1018 """
1019 nocolor()
1020
1021 - def notitles(self):
1022 """
1023 Disable the ability to effectively set the application title.
1024 """
1025 notitles()
1026