1
# -*- coding: utf-8 -*-
2
# -----------------------------------------------------------------------------
3
# Getting Things Gnome! - a personal organizer for the GNOME desktop
4
# Copyright (c) 2008-2009 - Lionel Dricot & Bertrand Rousseau
6
# This program is free software: you can redistribute it and/or modify it under
7
# the terms of the GNU General Public License as published by the Free Software
8
# Foundation, either version 3 of the License, or (at your option) any later
11
# This program is distributed in the hope that it will be useful, but WITHOUT
12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16
# You should have received a copy of the GNU General Public License along with
17
# this program. If not, see <http://www.gnu.org/licenses/>.
18
# -----------------------------------------------------------------------------
24
from GTG.backends.backendsignals import BackendSignals
25
from GTG.tools.networkmanager import is_connection_up
29
class CustomInfoBar(gtk.InfoBar):
31
A gtk.InfoBar specialized for displaying errors and requests for
32
interaction coming from the backends
36
AUTHENTICATION_MESSAGE = _("The <b>%s</b> backend cannot login with the "
37
"supplied authentication data and has been"
38
" disabled. To retry the login, re-enable the backend.")
40
NETWORK_MESSAGE = _("Due to a network problem, I cannot contact "
41
"the <b>%s</b> backend.")
43
DBUS_MESSAGE = _("Cannot connect to DBUS, I've disabled "
44
"the <b>%s</b> backend.")
46
def __init__(self, req, browser, vmanager, backend_id):
48
Constructor, Prepares the infobar.
50
@param req: a Requester object
51
@param browser: a TaskBrowser object
52
@param vmanager: a ViewManager object
53
@param backend_id: the id of the backend linked to the infobar
55
super(CustomInfoBar, self).__init__()
57
self.browser = browser
58
self.vmanager = vmanager
59
self.backend_id = backend_id
60
self.backend = self.req.get_backend(backend_id)
62
def get_backend_id(self):
64
Getter function to return the id of the backend for which this
65
gtk.InfoBar was created
67
return self.backend_id
70
'''Setting up gtk widgets'''
71
content_hbox = self.get_content_area()
72
content_hbox.set_homogeneous(False)
73
self.label = gtk.Label()
74
self.label.set_line_wrap(True)
75
self.label.set_alignment(0.5, 0.5)
76
self.label.set_justify(gtk.JUSTIFY_FILL)
77
content_hbox.pack_start(self.label, True, True)
79
def _on_error_response(self, widget, event):
81
Signal callback executed when the user acknowledges the error displayed
84
@param widget: not used, here for compatibility with signals callbacks
85
@param event: the code of the gtk response
88
if event == gtk.RESPONSE_ACCEPT:
89
self.vmanager.configure_backend(backend_id = self.backend_id)
91
def set_error_code(self, error_code):
93
Sets this infobar to show an error to the user
95
@param error_code: the code of the error to show. Error codes are listed
99
self.connect("response", self._on_error_response)
100
backend_name = self.backend.get_human_name()
102
if error_code == BackendSignals.ERRNO_AUTHENTICATION:
103
self.set_message_type(gtk.MESSAGE_ERROR)
104
self.label.set_markup(self.AUTHENTICATION_MESSAGE % backend_name)
105
self.add_button(_('Configure backend'), gtk.RESPONSE_ACCEPT)
106
self.add_button(_('Ignore'), gtk.RESPONSE_CLOSE)
108
elif error_code == BackendSignals.ERRNO_NETWORK:
109
if not is_connection_up():
111
self.set_message_type(gtk.MESSAGE_WARNING)
112
self.label.set_markup(self.NETWORK_MESSAGE % backend_name)
113
#FIXME: use gtk stock button instead
114
self.add_button(_('Ok'), gtk.RESPONSE_CLOSE)
116
elif error_code == BackendSignals.ERRNO_DBUS:
117
self.set_message_type(gtk.MESSAGE_WARNING)
118
self.label.set_markup(self.DBUS_MESSAGE % backend_name)
119
self.add_button(_('Ok'), gtk.RESPONSE_CLOSE)
123
def set_interaction_request(self, description, interaction_type, callback):
125
Sets this infobar to request an interaction from the user
127
@param description: a string describing the interaction needed
128
@param interaction_type: a string describing the type of interaction
129
(yes/no, only confirm, ok/cancel...)
130
@param callback: the function to call when the user provides the
134
self.callback = callback
135
self.set_message_type(gtk.MESSAGE_INFO)
136
self.label.set_markup(description)
137
self.connect("response", self._on_interaction_response)
138
self.interaction_type = interaction_type
139
if interaction_type == BackendSignals().INTERACTION_CONFIRM:
140
self.add_button(_('Confirm'), gtk.RESPONSE_ACCEPT)
141
elif interaction_type == BackendSignals().INTERACTION_TEXT:
142
self.add_button(_('Continue'), gtk.RESPONSE_ACCEPT)
145
def _on_interaction_response(self, widget, event):
147
Signal callback executed when the user gives the feedback for a
148
requested interaction
150
@param widget: not used, here for compatibility with signals callbacks
151
@param event: the code of the gtk response
153
if event == gtk.RESPONSE_ACCEPT:
154
if self.interaction_type == BackendSignals().INTERACTION_TEXT:
155
self._prepare_textual_interaction()
157
elif self.interaction_type == BackendSignals().INTERACTION_CONFIRM:
159
threading.Thread(target = getattr(self.backend,
160
self.callback)).start()
162
def _prepare_textual_interaction(self):
164
Helper function. gtk calls to populate the infobar in the case of
168
= getattr(self.backend,
169
self.callback)("get_ui_dialog_text")
170
self.dialog = gtk.Window()#type = gtk.WINDOW_POPUP)
171
self.dialog.set_title(title)
172
self.dialog.set_transient_for(self.browser.window)
173
self.dialog.set_destroy_with_parent(True)
174
self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
175
self.dialog.set_modal(True)
176
# self.dialog.set_size_request(300,170)
178
self.dialog.add(vbox)
179
description_label = gtk.Label()
180
description_label.set_justify(gtk.JUSTIFY_FILL)
181
description_label.set_line_wrap(True)
182
description_label.set_markup(description)
183
align = gtk.Alignment(0.5, 0.5, 1, 1)
184
align.set_padding(10, 0, 20, 20)
185
align.add(description_label)
186
vbox.pack_start(align)
187
self.text_box = gtk.Entry()
188
self.text_box.set_size_request(-1, 40)
189
align = gtk.Alignment(0.5, 0.5, 1, 1)
190
align.set_padding(20, 20, 20, 20)
191
align.add(self.text_box)
192
vbox.pack_start(align)
193
button = gtk.Button(stock = gtk.STOCK_OK)
194
button.connect("clicked", self._on_text_confirmed)
195
button.set_size_request(-1, 40)
196
vbox.pack_start(button, False)
197
self.dialog.show_all()
200
def _on_text_confirmed(self, widget):
202
Signal callback, used when the interaction needs a textual input to be
203
completed (e.g, the twitter OAuth, requesting a pin)
205
@param widget: not used, here for signal callback compatibility
207
text = self.text_box.get_text()
208
self.dialog.destroy()
209
threading.Thread(target = getattr(self.backend, self.callback),
210
args = ("set_text", text)).start()