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