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 }