~ubuntu-branches/ubuntu/oneiric/bzrtools/oneiric

« back to all changes in this revision

Viewing changes to userinteractor.py

  • Committer: Bazaar Package Importer
  • Author(s): Gustavo Franco
  • Date: 2006-11-28 12:21:48 UTC
  • mfrom: (1.2.1 upstream) (4.1.6 edgy)
  • Revision ID: james.westby@ubuntu.com-20061128122148-vm1b9aq2yu0r8yrf
Tags: 0.11.0-1
New upstream release. (Closes: #389605)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import sys
 
2
 
 
3
class UserOption:
 
4
    def __init__(self, char, action, help, default=False):
 
5
        self.char = char
 
6
        self.action = action
 
7
        self.default = default
 
8
        self.help = help
 
9
 
 
10
class UserInteractor(object):
 
11
    # Special actions
 
12
    RESTART = 0
 
13
    QUIT = 1
 
14
    FINISH = 2
 
15
 
 
16
    def __init__(self):
 
17
        self.items = []
 
18
 
 
19
    def add_item(self, item):
 
20
        self.items.append(item)
 
21
        self.__total_items = len(self.items)
 
22
 
 
23
    def set_items(self, item_list):
 
24
        self.items = item_list
 
25
        self.__total_items = len(self.items)
 
26
 
 
27
    def set_item_callback(self, cb):
 
28
        self.item_callback = cb
 
29
 
 
30
    def set_start_callback(self, cb):
 
31
        self.start_callback = cb
 
32
 
 
33
    def set_end_callback(self, cb):
 
34
        self.end_callback = cb
 
35
 
 
36
    def set_prompt(self, prompt):
 
37
        self.prompt = prompt
 
38
 
 
39
    def set_options(self, opt_list):
 
40
        self._options = []
 
41
        self._option_dict = {}
 
42
        for option in opt_list:
 
43
            self.add_option(option)
 
44
 
 
45
    def add_option(self, option):
 
46
        self._options.append(option)
 
47
        self._option_dict[option.char] = option
 
48
 
 
49
    def get_option(self, char):
 
50
        return self._option_dict[char]
 
51
 
 
52
    def __do_action(self, action, item):
 
53
        if type(action) is int:
 
54
            if action == self.QUIT:
 
55
                self.__quit = True
 
56
                self.__finished = True
 
57
            elif action == self.RESTART:
 
58
                self.__restart = True
 
59
                self.__finished = False
 
60
            elif action == self.FINISH:
 
61
                self.__finished = True
 
62
            return True
 
63
        else:
 
64
            return action(item)
 
65
 
 
66
    def __select_loop(self):
 
67
        i = 0
 
68
        self.start_callback()
 
69
        while i < len(self.items):
 
70
                item = self.items[i]
 
71
 
 
72
                self.item_callback(item, i + 1)
 
73
 
 
74
                if self.__ask_once(item, i + 1):
 
75
                    i += 1
 
76
 
 
77
                if self.__quit or self.__finished:
 
78
                    break
 
79
 
 
80
    def interact(self):
 
81
        self.__quit = False
 
82
        self.__finished = False
 
83
 
 
84
        while not self.__quit and not self.__finished:
 
85
            self.__restart = False
 
86
 
 
87
            self.__select_loop()
 
88
            if self.__quit:
 
89
                break
 
90
 
 
91
            if self.end_callback():
 
92
                break
 
93
 
 
94
            self.__finished = False
 
95
 
 
96
            self.__ask_once(None, self.__total_items)
 
97
            while not self.__finished and not self.__restart:
 
98
                self.__ask_once(None, -1)
 
99
 
 
100
        return not self.__quit
 
101
 
 
102
    def __ask_once(self, item, count):
 
103
        args = {'count': count, 'total' : self.__total_items}
 
104
 
 
105
        while True:
 
106
            sys.stdout.write(self.prompt % args)
 
107
            sys.stdout.write(' [')
 
108
            for opt in self._options:
 
109
                if opt.default:
 
110
                    default = opt
 
111
                sys.stdout.write(opt.char)
 
112
            sys.stdout.write('?] (%s): ' % default.char)
 
113
 
 
114
            response = self.__getchar()
 
115
 
 
116
            # default, which we see as newline, is 'n'
 
117
            if response in ['\n', '\r', '\r\n']:
 
118
                response = default.char
 
119
 
 
120
            print response # because echo is off
 
121
 
 
122
            for opt in self._options:
 
123
                if opt.char == response:
 
124
                    return self.__do_action(opt.action, item)
 
125
 
 
126
            self.__show_help()
 
127
 
 
128
        return False # keep pychecker happy
 
129
 
 
130
    def __show_help(self):
 
131
        for opt in self._options:
 
132
            print '  %s - %s' % (opt.char, opt.help)
 
133
 
 
134
    if sys.platform == "win32":
 
135
        def __getchar(self):
 
136
            import msvcrt
 
137
            return msvcrt.getch()
 
138
    else:
 
139
        def __getchar(self):
 
140
            import tty
 
141
            import termios
 
142
            fd = sys.stdin.fileno()
 
143
            settings = termios.tcgetattr(fd)
 
144
            try:
 
145
                tty.setraw(fd)
 
146
                ch = sys.stdin.read(1)
 
147
            finally:
 
148
                termios.tcsetattr(fd, termios.TCSADRAIN, settings)
 
149
            return ch