/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to ui.py

  • Committer: Szilveszter Farkas (Phanatic)
  • Date: 2007-04-06 17:48:23 UTC
  • mto: (188.2.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 190.
  • Revision ID: szilveszter.farkas@gmail.com-20070406174823-bclt7vsgn2nkcas2
Implemented init functionality.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2006 Szilveszter Farkas <szilveszter.farkas@gmail.com>
2
 
# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
3
2
 
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
19
18
"""GTK UI
20
19
"""
21
20
 
22
 
from gi.repository import Gtk
 
21
import gtk
 
22
import sys
23
23
 
 
24
import bzrlib.progress
24
25
from bzrlib.ui import UIFactory
25
26
 
26
27
 
27
 
def main_iteration(function):
28
 
    def with_main_iteration(self, *args, **kwargs):
29
 
        result = function(self, *args, **kwargs)
30
 
        while Gtk.events_pending():
31
 
            Gtk.main_iteration_do(False)
32
 
        return result
33
 
    return with_main_iteration
34
 
 
35
 
 
36
 
class PromptDialog(Gtk.MessageDialog):
37
 
    """Prompt the user for a yes/no answer."""
38
 
 
39
 
    def __init__(self, prompt, parent=None):
40
 
        super(PromptDialog, self).__init__(
41
 
            parent, Gtk.DialogFlags.DESTROY_WITH_PARENT,
42
 
            Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, prompt)
43
 
 
44
 
 
45
 
class InfoDialog(Gtk.MessageDialog):
46
 
    """Show the user an informational message."""
47
 
 
48
 
    MESSAGE_TYPE = Gtk.MessageType.INFO
49
 
 
50
 
    def __init__(self, prompt, parent=None):
51
 
        super(InfoDialog, self).__init__(
52
 
            parent, Gtk.DialogFlags.DESTROY_WITH_PARENT,
53
 
            self.MESSAGE_TYPE, Gtk.ButtonsType.CLOSE, prompt)
54
 
 
55
 
 
56
 
class WarningDialog(InfoDialog):
57
 
    """Show the user a warning message."""
58
 
 
59
 
    MESSAGE_TYPE = Gtk.MessageType.WARNING
60
 
 
61
 
 
62
 
class ErrorDialog(InfoDialog):
63
 
    """Show the user a warning message."""
64
 
 
65
 
    MESSAGE_TYPE = Gtk.MessageType.ERROR
66
 
 
67
 
 
68
 
class GtkProgressBar(Gtk.ProgressBar):
69
 
 
70
 
    def __init__(self):
 
28
class PromptDialog(gtk.Dialog):
 
29
    """ Prompt the user for a yes/no answer. """
 
30
    def __init__(self, prompt):
 
31
        gtk.Dialog.__init__(self)
 
32
        
 
33
        label = gtk.Label(prompt)
 
34
        self.vbox.pack_start(label, padding=10)
 
35
        
 
36
        self.vbox.show_all()
 
37
 
 
38
        self.add_buttons(gtk.STOCK_YES, gtk.RESPONSE_YES, gtk.STOCK_NO, gtk.RESPONSE_NO)
 
39
 
 
40
 
 
41
class GtkProgressBar(gtk.ProgressBar):
 
42
    def __init__(self, stack):
71
43
        super(GtkProgressBar, self).__init__()
72
44
        self.set_fraction(0.0)
73
 
        self.current = None
74
 
        self.total = None
75
 
 
76
 
    @main_iteration
 
45
        self._stack = stack
 
46
 
 
47
    def finished(self):
 
48
        self._stack.remove(self)
 
49
 
 
50
    def clear(self):
 
51
        pass
 
52
 
77
53
    def tick(self):
78
 
        self.show()
79
54
        self.pulse()
80
55
 
81
 
    @main_iteration
82
 
    def update(self, msg=None, current_cnt=None, total_cnt=None):
83
 
        self.show()
84
 
        if current_cnt is not None:
85
 
            self.current = current_cnt
86
 
        if total_cnt is not None:
87
 
            self.total = total_cnt
 
56
    def update(self, msg=None, current=None, total=None):
88
57
        if msg is not None:
89
58
            self.set_text(msg)
90
 
        if None not in (self.current, self.total):
91
 
            fraction = float(self.current) / self.total
92
 
            if fraction < 0.0 or fraction > 1.0:
93
 
                raise ValueError
94
 
            self.set_fraction(fraction)
95
 
 
96
 
    @main_iteration
97
 
    def finished(self):
98
 
        self.set_fraction(0.0)
99
 
        self.current = None
100
 
        self.total = None
101
 
        self.hide()
102
 
 
103
 
    def clear(self):
104
 
        self.finished()
105
 
 
106
 
 
107
 
class ProgressContainerMixin:
108
 
    """Expose GtkProgressBar methods to a container class."""
109
 
 
110
 
    def tick(self, *args, **kwargs):
111
 
        self.show_all()
112
 
        self.pb.tick(*args, **kwargs)
113
 
 
114
 
    def update(self, *args, **kwargs):
115
 
        self.show_all()
116
 
        self.pb.update(*args, **kwargs)
117
 
 
118
 
    def finished(self):
119
 
        self.hide()
120
 
        self.pb.finished()
121
 
 
122
 
    def clear(self):
123
 
        self.hide()
124
 
        self.pb.clear()
125
 
 
126
 
 
127
 
class ProgressBarWindow(ProgressContainerMixin, Gtk.Window):
128
 
 
 
59
        self.set_fraction(1.0 * current / total)
 
60
        while gtk.events_pending():
 
61
            gtk.main_iteration()
 
62
 
 
63
 
 
64
class GtkProgressBarStack(gtk.Window):
129
65
    def __init__(self):
130
 
        super(ProgressBarWindow, self).__init__(type=Gtk.WindowType.TOPLEVEL)
 
66
        super(GtkProgressBarStack, self).__init__(type=gtk.WINDOW_TOPLEVEL)
131
67
        self.set_border_width(0)
132
68
        self.set_title("Progress")
133
 
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
134
 
        self.pb = GtkProgressBar()
135
 
        self.add(self.pb)
136
 
        self.resize(250, 15)
 
69
        self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
 
70
        self.vbox = gtk.VBox()
 
71
        self.add(self.vbox)
137
72
        self.set_resizable(False)
138
73
 
139
 
 
140
 
class ProgressPanel(ProgressContainerMixin, Gtk.Box):
141
 
 
142
 
    def __init__(self):
143
 
        super(ProgressPanel, self).__init__(Gtk.Orientation.HORIZONTAL, 5)
144
 
        image_loading = Gtk.Image.new_from_stock(Gtk.STOCK_REFRESH,
145
 
                                                 Gtk.IconSize.BUTTON)
146
 
        image_loading.show()
147
 
 
148
 
        self.pb = GtkProgressBar()
149
 
        self.set_border_width(5)
150
 
        self.pack_start(image_loading, False, False, 0)
151
 
        self.pack_start(self.pb, True, True, 0)
152
 
 
153
 
 
154
 
class PasswordDialog(Gtk.Dialog):
 
74
    def _adapt_size(self):
 
75
        self.resize(250, 15 * len(self.vbox.get_children()))
 
76
 
 
77
    def get_nested(self):
 
78
        nested = GtkProgressBar(self)
 
79
        self.vbox.pack_start(nested)
 
80
        self._adapt_size()
 
81
        self.show_all()
 
82
        return nested
 
83
 
 
84
    def remove(self, pb):
 
85
        self.vbox.remove(pb)
 
86
 
 
87
 
 
88
class PasswordDialog(gtk.Dialog):
155
89
    """ Prompt the user for a password. """
156
 
 
157
90
    def __init__(self, prompt):
158
 
        super(PasswordDialog, self).__init__()
159
 
 
160
 
        label = Gtk.Label(label=prompt)
161
 
        self.get_content_area().pack_start(label, True, True, 10)
162
 
 
163
 
        self.entry = Gtk.Entry()
 
91
        gtk.Dialog.__init__(self)
 
92
        
 
93
        label = gtk.Label(prompt)
 
94
        self.vbox.pack_start(label, padding=10)
 
95
        
 
96
        self.entry = gtk.Entry()
164
97
        self.entry.set_visibility(False)
165
 
        self.get_content_area().pack_end(self.entry, False, False, 10)
166
 
 
167
 
        self.get_content_area().show_all()
168
 
 
169
 
        self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK,
170
 
                         Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
171
 
 
 
98
        self.vbox.pack_end(self.entry, padding=10)
 
99
        
 
100
        self.vbox.show_all()
 
101
        
 
102
        self.add_buttons(gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
 
103
    
172
104
    def _get_passwd(self):
173
105
        return self.entry.get_text()
174
106
 
178
110
class GtkUIFactory(UIFactory):
179
111
    """A UI factory for GTK user interfaces."""
180
112
 
181
 
    def __init__(self):
182
 
        """Create a GtkUIFactory"""
 
113
    def __init__(self,
 
114
                 stdout=None,
 
115
                 stderr=None):
 
116
        """Create a GtkUIFactory.
 
117
 
 
118
        """
183
119
        super(GtkUIFactory, self).__init__()
184
 
        self.set_progress_bar_widget(None)
185
 
 
186
 
    def set_progress_bar_widget(self, widget):
187
 
        self._progress_bar_widget = widget
 
120
        if stdout is None:
 
121
            self.stdout = sys.stdout
 
122
        else:
 
123
            self.stdout = stdout
 
124
        if stderr is None:
 
125
            self.stderr = sys.stderr
 
126
        else:
 
127
            self.stderr = stderr
 
128
        self._progress_bar_stack = None
188
129
 
189
130
    def get_boolean(self, prompt):
190
131
        """GtkDialog with yes/no answers"""
191
132
        dialog = PromptDialog(prompt)
192
133
        response = dialog.run()
193
134
        dialog.destroy()
194
 
        return (response == Gtk.ResponseType.YES)
195
 
 
196
 
    def show_message(self, msg):
197
 
        """See UIFactory.show_message."""
198
 
        dialog = InfoDialog(msg)
199
 
        dialog.run()
200
 
        dialog.destroy()
201
 
 
202
 
    def show_warning(self, msg):
203
 
        """See UIFactory.show_warning."""
204
 
        dialog = WarningDialog(msg)
205
 
        dialog.run()
206
 
        dialog.destroy()
207
 
 
208
 
    def show_error(self, msg):
209
 
        """See UIFactory.show_error."""
210
 
        dialog = ErrorDialog(msg)
211
 
        dialog.run()
212
 
        dialog.destroy()
213
 
 
214
 
    def show_user_warning(self, warning_id, **message_args):
215
 
        """See UIFactory.show_user_warning."""
216
 
        if warning_id not in self.suppressed_warnings:
217
 
            message = self.format_user_warning(warning_id, message_args)
218
 
            self.show_warning(message)
219
 
 
 
135
        return (response == gtk.RESPONSE_YES)
 
136
        
220
137
    def get_password(self, prompt='', **kwargs):
221
138
        """Prompt the user for a password.
222
139
 
224
141
        :param kwargs: Arguments which will be expanded into the prompt.
225
142
                       This lets front ends display different things if
226
143
                       they so choose.
227
 
        :return: The password string, return None if the user
 
144
        :return: The password string, return None if the user 
228
145
                 canceled the request.
229
146
        """
230
147
        dialog = PasswordDialog(prompt % kwargs)
231
148
        response = dialog.run()
232
149
        passwd = dialog.passwd
233
150
        dialog.destroy()
234
 
        if response == Gtk.ResponseType.OK:
 
151
        if response == gtk.RESPONSE_OK:
235
152
            return passwd
236
153
        else:
237
154
            return None
238
155
 
239
 
    def _progress_all_finished(self):
240
 
        """See UIFactory._progress_all_finished."""
241
 
        pbw = self._progress_bar_widget
242
 
        if pbw:
243
 
            pbw.finished()
244
 
 
245
 
    def _ensure_progress_widget(self):
246
 
        if self._progress_bar_widget is None:
247
 
            # Default to a window since nobody gave us a better means to report
248
 
            # progress.
249
 
            self.set_progress_bar_widget(ProgressBarWindow())
250
 
 
251
 
    def _progress_updated(self, task):
252
 
        """See UIFactory._progress_updated."""
253
 
        self._ensure_progress_widget()
254
 
        self._progress_bar_widget.update(task.msg,
255
 
                                         task.current_cnt, task.total_cnt)
256
 
 
257
 
    def report_transport_activity(self, transport, byte_count, direction):
258
 
        """See UIFactory.report_transport_activity."""
259
 
        self._ensure_progress_widget()
260
 
        self._progress_bar_widget.tick()
 
156
    def nested_progress_bar(self):
 
157
        """Return a nested progress bar.
 
158
        """
 
159
        if self._progress_bar_stack is None:
 
160
            self._progress_bar_stack = GtkProgressBarStack()
 
161
        return self._progress_bar_stack.get_nested()
 
162
 
 
163
    def set_progress_bar_vbox(self, vbox):
 
164
        """Change the vbox to put progress bars in.
 
165
        """
 
166
        self._progress_bar_stack = vbox
 
167
 
 
168
    def clear_term(self):
 
169
        """Prepare the terminal for output.
 
170
 
 
171
        It has no sense when talking about GTK."""
 
172
        pass