src/mn-authenticated-mailbox-properties.gob (8903B) - raw
1 /*
2 * Mail Notification
3 * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 %headertop{
21 #include <gtk/gtk.h>
22 #include "mn-mailbox-properties.h"
23 %}
24
25 %privateheader{
26 #include "mn-authenticated-mailbox.h"
27 %}
28
29 %{
30 #include <glib/gi18n.h>
31 #include "mn-mailbox-properties-private.h"
32 #include "mn-util.h"
33 %}
34
35 class MN:Authenticated:Mailbox:Properties from MN:Mailbox:Properties (abstract)
36 {
37 protected GtkWidget *account_vbox;
38 protected GtkWidget *username_vbox;
39 protected GtkWidget *username_label;
40 protected GtkWidget *username_entry;
41 protected GtkWidget *password_vbox;
42 protected GtkWidget *password_label;
43 protected GtkWidget *password_entry unrefwith g_object_unref;
44 private GtkWidget *password_operation_label unrefwith g_object_unref;
45 private GtkWidget *password_widget;
46
47 private MNAuthenticatedMailbox *mailbox_setting_password;
48 private gpointer get_password_request;
49
50 init (self)
51 {
52 MNMailboxProperties *properties = MN_MAILBOX_PROPERTIES(self);
53 const char *username;
54
55 /* translators: header capitalization */
56 self->account_vbox = mn_mailbox_properties_add_general_section(properties, _("Account"));
57
58 self->username_vbox = self_field_new(self,
59 _("_Username:"),
60 &self->username_label,
61 &self->username_entry);
62 self->password_vbox = self_field_new(self,
63 _("_Password:"),
64 &self->password_label,
65 &self->password_entry);
66
67 selfp->password_operation_label = gtk_label_new(NULL);
68 gtk_misc_set_alignment(GTK_MISC(selfp->password_operation_label), 0.0, 0.5);
69
70 /*
71 * These two widgets will alternate in their parent container so
72 * we need to reference them.
73 */
74 g_object_ref_sink(self->password_entry);
75 g_object_ref_sink(selfp->password_operation_label);
76
77 selfp->password_widget = self->password_entry;
78
79 /* defaults to the login name */
80 username = g_get_user_name();
81 if (username)
82 gtk_entry_set_text(GTK_ENTRY(self->username_entry), username);
83
84 gtk_entry_set_visibility(GTK_ENTRY(self->password_entry), FALSE);
85 }
86
87 /* dispose and not finalize because we use unrefwith above */
88 dispose (self)
89 {
90 self_clear_mailbox_callbacks(self);
91 }
92
93 protected GtkWidget *
94 field_new (self,
95 const char *mnemonic (check null),
96 GtkWidget **label,
97 GtkWidget **entry (check null))
98 {
99 GtkWidget *hbox;
100 GtkWidget *_label;
101
102 _label = gtk_label_new_with_mnemonic(mnemonic);
103 gtk_misc_set_alignment(GTK_MISC(_label), 0.0, 0.5);
104
105 *entry = gtk_entry_new();
106 gtk_label_set_mnemonic_widget(GTK_LABEL(_label), *entry);
107
108 hbox = gtk_hbox_new(FALSE, 12);
109 gtk_box_pack_start(GTK_BOX(hbox), _label, FALSE, FALSE, 0);
110 gtk_box_pack_start(GTK_BOX(hbox), *entry, TRUE, TRUE, 0);
111 gtk_widget_show_all(hbox);
112
113 gtk_size_group_add_widget(MN_MAILBOX_PROPERTIES(self)->label_size_group, _label);
114
115 if (label)
116 *label = _label;
117
118 return hbox;
119 }
120
121 override (MN:Mailbox:Properties) void
122 set_mailbox (MNMailboxProperties *properties, MNMailbox *mailbox)
123 {
124 Self *self = SELF(properties);
125 MNAuthenticatedMailbox *auth_mailbox = MN_AUTHENTICATED_MAILBOX(mailbox);
126
127 self_clear_mailbox_callbacks(self);
128
129 gtk_entry_set_text(GTK_ENTRY(self->username_entry), auth_mailbox->username);
130
131 /*
132 * If the password is currently being saved, wait for that
133 * operation to finish before querying the keyring for the
134 * password.
135 */
136 if (mn_authenticated_mailbox_get_setting_password(auth_mailbox))
137 {
138 selfp->mailbox_setting_password = g_object_ref(auth_mailbox);
139 g_signal_connect(auth_mailbox, "notify::setting-password", G_CALLBACK(self_setting_password_notify_h), self);
140 self_set_password_operation(self, _("Saving password to keyring..."));
141 }
142 else
143 self_get_password(self, auth_mailbox);
144 }
145
146 private void
147 clear_mailbox_callbacks (self)
148 {
149 if (selfp->mailbox_setting_password)
150 {
151 g_signal_handlers_disconnect_by_func(selfp->mailbox_setting_password, self_setting_password_notify_h, self);
152 g_object_unref(selfp->mailbox_setting_password);
153 selfp->mailbox_setting_password = NULL;
154 }
155
156 if (selfp->get_password_request)
157 {
158 gnome_keyring_cancel_request(selfp->get_password_request);
159 selfp->get_password_request = NULL;
160 }
161 }
162
163 private void
164 setting_password_notify_h (GObject *object,
165 GParamSpec *pspec,
166 gpointer user_data)
167 {
168 Self *self = user_data;
169 MNAuthenticatedMailbox *mailbox = MN_AUTHENTICATED_MAILBOX(object);
170
171 /*
172 * If the password save operation is finished, we can query the
173 * keyring for the password.
174 */
175 if (! mn_authenticated_mailbox_get_setting_password(mailbox))
176 {
177 g_signal_handlers_disconnect_by_func(mailbox, self_setting_password_notify_h, self);
178 self_get_password(self, mailbox);
179 }
180 }
181
182 private void
183 get_password (self, MN:Authenticated:Mailbox *mailbox (check null))
184 {
185 self_set_password_operation(self, _("Retrieving password from keyring..."));
186
187 selfp->get_password_request = mn_authenticated_mailbox_get_password(mailbox,
188 self_get_password_cb,
189 self);
190 }
191
192 private void
193 get_password_cb (GnomeKeyringResult result, GList *list, gpointer data)
194 {
195 Self *self = data;
196 const char *password = NULL;
197
198 /*
199 * If the request was cancelled, it is either from dispose() and
200 * self might already have been finalized (since this is a main
201 * loop callback), or it is from set_mailbox() and the password
202 * will be retrieved again. In both cases we must do nothing.
203 */
204 if (result == GNOME_KEYRING_RESULT_CANCELLED)
205 return;
206
207 selfp->get_password_request = NULL;
208
209 if (result == GNOME_KEYRING_RESULT_OK && list)
210 {
211 GnomeKeyringNetworkPasswordData *password_data = list->data;
212 password = password_data->password;
213 }
214
215 GDK_THREADS_ENTER();
216
217 gtk_entry_set_text(GTK_ENTRY(self->password_entry), password ? password : "");
218 self_set_password_operation(self, NULL);
219
220 /* do not call gdk_flush(), we're normally in the main thread */
221 GDK_THREADS_LEAVE();
222 }
223
224 override (MN:Mailbox:Properties) MNMailbox *
225 get_mailbox (MNMailboxProperties *properties)
226 {
227 Self *self = SELF(properties);
228 MNMailbox *mailbox;
229 MNAuthenticatedMailbox *auth_mailbox;
230 const char *username;
231 const char *password;
232
233 mailbox = PARENT_HANDLER(properties);
234 auth_mailbox = MN_AUTHENTICATED_MAILBOX(mailbox);
235
236 username = gtk_entry_get_text(GTK_ENTRY(self->username_entry));
237 password = gtk_entry_get_text(GTK_ENTRY(self->password_entry));
238
239 auth_mailbox->username = g_strdup(username);
240 if (*password)
241 auth_mailbox->password = g_strdup(password);
242
243 return mailbox;
244 }
245
246 private void
247 set_password_operation (self, const char *operation)
248 {
249 GtkWidget *password_widget;
250
251 gtk_label_set_text(GTK_LABEL(selfp->password_operation_label), operation);
252
253 if (operation)
254 password_widget = selfp->password_operation_label;
255 else
256 password_widget = self->password_entry;
257
258 if (password_widget != selfp->password_widget)
259 {
260 gtk_container_remove(GTK_CONTAINER(self->password_vbox), selfp->password_widget);
261
262 gtk_box_pack_start(GTK_BOX(self->password_vbox), password_widget, TRUE, TRUE, 0);
263 gtk_widget_show(password_widget);
264 selfp->password_widget = password_widget;
265
266 mn_mailbox_properties_notify_complete(MN_MAILBOX_PROPERTIES(self));
267 }
268 }
269
270 protected void
271 get_contents (self,
272 const char **username,
273 const char **password)
274 {
275 if (username)
276 {
277 const char *_username;
278
279 _username = gtk_entry_get_text(GTK_ENTRY(self->username_entry));
280 *username = *_username ? _username : NULL;
281 }
282 if (password)
283 {
284 const char *_password;
285
286 _password = gtk_entry_get_text(GTK_ENTRY(self->password_entry));
287 *password = *_password ? _password : NULL;
288 }
289 }
290
291 protected gboolean
292 is_complete (self)
293 {
294 const char *username;
295
296 if (selfp->password_widget == selfp->password_operation_label)
297 return FALSE;
298
299 username = gtk_entry_get_text(GTK_ENTRY(self->username_entry));
300
301 return *username != 0;
302 }
303 }