| 20 * along with this program; if not, see <https://www.gnu.org/licenses/>. |
20 * along with this program; if not, see <https://www.gnu.org/licenses/>. |
| 21 */ |
21 */ |
| 22 |
22 |
| 23 #include <glib/gi18n-lib.h> |
23 #include <glib/gi18n-lib.h> |
| 24 |
24 |
| |
25 #include <adwaita.h> |
| |
26 |
| 25 #include "pidginaccounteditor.h" |
27 #include "pidginaccounteditor.h" |
| 26 |
28 |
| 27 #include "pidginproxyoptions.h" |
29 #include "pidginprotocolchooser.h" |
| 28 |
30 |
| 29 struct _PidginAccountEditor { |
31 struct _PidginAccountEditor { |
| 30 GtkDialog parent; |
32 GtkDialog parent; |
| 31 |
33 |
| 32 PurpleAccount *account; |
34 PurpleAccount *account; |
| 33 |
35 |
| 34 GtkWidget *notebook; |
36 /* Login Options */ |
| |
37 GtkWidget *login_options; |
| |
38 GtkWidget *protocol; |
| |
39 GtkWidget *username; |
| |
40 |
| |
41 GList *user_split_entries; |
| |
42 GList *user_split_rows; |
| |
43 |
| |
44 /* User Options */ |
| |
45 GtkWidget *alias; |
| |
46 |
| |
47 GtkFileChooserNative *avatar_dialog; |
| |
48 GdkPixbuf *avatar_pixbuf; |
| |
49 GtkWidget *avatar_row; |
| |
50 GtkWidget *use_custom_avatar; |
| |
51 GtkWidget *avatar; |
| |
52 |
| |
53 /* Advanced Options */ |
| |
54 GtkWidget *advanced_group; |
| |
55 GtkWidget *advanced_toggle; |
| |
56 |
| |
57 GList *advanced_entries; |
| |
58 GList *advanced_rows; |
| |
59 |
| |
60 /* Proxy Options */ |
| |
61 GtkWidget *proxy_type; |
| 35 GtkWidget *proxy_options; |
62 GtkWidget *proxy_options; |
| |
63 GtkWidget *proxy_host; |
| |
64 GtkWidget *proxy_port; |
| |
65 GtkWidget *proxy_username; |
| |
66 GtkWidget *proxy_password; |
| 36 }; |
67 }; |
| 37 |
68 |
| 38 enum { |
69 enum { |
| 39 PROP_0, |
70 PROP_0, |
| 40 PROP_ACCOUNT, |
71 PROP_ACCOUNT, |
| 41 N_PROPERTIES, |
72 N_PROPERTIES, |
| 42 }; |
73 }; |
| 43 static GParamSpec *properties[N_PROPERTIES] = {NULL, }; |
74 static GParamSpec *properties[N_PROPERTIES] = {NULL, }; |
| 44 |
75 |
| |
76 |
| |
77 /****************************************************************************** |
| |
78 * Prototypes |
| |
79 *****************************************************************************/ |
| |
80 static void pidgin_account_editor_connection_changed_cb(GObject *obj, |
| |
81 GParamSpec *pspec, |
| |
82 gpointer data); |
| |
83 |
| 45 /****************************************************************************** |
84 /****************************************************************************** |
| 46 * Helpers |
85 * Helpers |
| 47 *****************************************************************************/ |
86 *****************************************************************************/ |
| 48 static void |
87 static void |
| |
88 pidgin_account_editor_add_user_split(gpointer data, gpointer user_data) { |
| |
89 PurpleAccountUserSplit *split = data; |
| |
90 PidginAccountEditor *editor = user_data; |
| |
91 GtkWidget *entry = NULL; |
| |
92 |
| |
93 if(!purple_account_user_split_is_constant(split)) { |
| |
94 GtkWidget *row = NULL; |
| |
95 |
| |
96 row = adw_action_row_new(); |
| |
97 editor->user_split_rows = g_list_append(editor->user_split_rows, row); |
| |
98 adw_preferences_group_add(ADW_PREFERENCES_GROUP(editor->login_options), |
| |
99 row); |
| |
100 |
| |
101 adw_preferences_row_set_title(ADW_PREFERENCES_ROW(row), |
| |
102 purple_account_user_split_get_text(split)); |
| |
103 |
| |
104 entry = gtk_entry_new(); |
| |
105 gtk_widget_set_hexpand(entry, TRUE); |
| |
106 gtk_widget_set_valign(entry, GTK_ALIGN_CENTER); |
| |
107 adw_action_row_add_suffix(ADW_ACTION_ROW(row), entry); |
| |
108 adw_action_row_set_activatable_widget(ADW_ACTION_ROW(row), entry); |
| |
109 } |
| |
110 |
| |
111 editor->user_split_entries = g_list_append(editor->user_split_entries, |
| |
112 entry); |
| |
113 } |
| |
114 |
| |
115 static gboolean |
| |
116 pidgin_account_editor_update_login_options(PidginAccountEditor *editor, |
| |
117 PurpleProtocol *protocol) |
| |
118 { |
| |
119 GList *user_splits = NULL; |
| |
120 GList *split_item = NULL; |
| |
121 GList *entry_item = NULL; |
| |
122 gchar *username = NULL; |
| |
123 |
| |
124 /* Clear out the old user splits from our list. */ |
| |
125 g_clear_pointer(&editor->user_split_entries, g_list_free); |
| |
126 |
| |
127 /* Now remove the rows we added to the preference group for each non |
| |
128 * constant user split. |
| |
129 */ |
| |
130 while(editor->user_split_rows != NULL) { |
| |
131 adw_preferences_group_remove(ADW_PREFERENCES_GROUP(editor->login_options), |
| |
132 editor->user_split_rows->data); |
| |
133 |
| |
134 editor->user_split_rows = g_list_delete_link(editor->user_split_rows, |
| |
135 editor->user_split_rows); |
| |
136 } |
| |
137 |
| |
138 /* Add the user splits for the protocol. */ |
| |
139 user_splits = purple_protocol_get_user_splits(protocol); |
| |
140 g_list_foreach(user_splits, pidgin_account_editor_add_user_split, editor); |
| |
141 |
| |
142 /* If we have an account, populate its values. */ |
| |
143 if(PURPLE_IS_ACCOUNT(editor->account)) { |
| |
144 /* The username will be split apart below and eventually set as the text |
| |
145 * in the username entry. |
| |
146 */ |
| |
147 username = g_strdup(purple_account_get_username(editor->account)); |
| |
148 } |
| |
149 |
| |
150 /* Filling out the user splits is a pain. If we have an account, we created |
| |
151 * a copy of the username above. We then iterate the user splits backwards |
| |
152 * so we can insert a null terminator at the start of each split we find in |
| |
153 * the username. |
| |
154 */ |
| |
155 split_item = g_list_last(user_splits); |
| |
156 entry_item = g_list_last(editor->user_split_entries); |
| |
157 while(split_item != NULL && entry_item != NULL) { |
| |
158 GtkWidget *entry = entry_item->data; |
| |
159 PurpleAccountUserSplit *split = split_item->data; |
| |
160 gchar *ptr = NULL; |
| |
161 const gchar *value = NULL; |
| |
162 |
| |
163 if(username != NULL) { |
| |
164 gchar sep = purple_account_user_split_get_separator(split); |
| |
165 |
| |
166 if(purple_account_user_split_get_reverse(split)) { |
| |
167 ptr = strrchr(username, sep); |
| |
168 } else { |
| |
169 ptr = strchr(username, sep); |
| |
170 } |
| |
171 |
| |
172 if(ptr != NULL) { |
| |
173 /* Insert a null terminator in place of the separator. */ |
| |
174 *ptr = '\0'; |
| |
175 |
| |
176 /* Set the value to the first byte after the separator. */ |
| |
177 value = ptr + 1; |
| |
178 } |
| |
179 } |
| |
180 |
| |
181 if(value == NULL) { |
| |
182 value = purple_account_user_split_get_default_value(split); |
| |
183 } |
| |
184 |
| |
185 if(value != NULL && GTK_IS_ENTRY(entry)) { |
| |
186 gtk_editable_set_text(GTK_EDITABLE(entry), value); |
| |
187 } |
| |
188 |
| |
189 split_item = split_item->prev; |
| |
190 entry_item = entry_item->prev; |
| |
191 } |
| |
192 |
| |
193 /* Free the user splits. */ |
| |
194 g_list_free_full(user_splits, |
| |
195 (GDestroyNotify)purple_account_user_split_destroy); |
| |
196 |
| |
197 /* Set the username entry to the remaining text in username and free our |
| |
198 * copy of said username. |
| |
199 */ |
| |
200 if(username != NULL) { |
| |
201 gtk_editable_set_text(GTK_EDITABLE(editor->username), username); |
| |
202 g_free(username); |
| |
203 return TRUE; |
| |
204 } |
| |
205 |
| |
206 return FALSE; |
| |
207 } |
| |
208 |
| |
209 static void |
| |
210 pidgin_account_editor_update_user_options(PidginAccountEditor *editor, |
| |
211 PurpleProtocol *protocol) |
| |
212 { |
| |
213 PurpleBuddyIconSpec *icon_spec = NULL; |
| |
214 PurpleImage *image = NULL; |
| |
215 gboolean show_avatar_opts = TRUE; |
| |
216 const gchar *svalue = ""; |
| |
217 gboolean use_global = TRUE; |
| |
218 |
| |
219 /* Check if the protocol supports avatars. */ |
| |
220 icon_spec = purple_protocol_get_icon_spec(protocol); |
| |
221 show_avatar_opts = (icon_spec != NULL && icon_spec->format != NULL); |
| |
222 purple_buddy_icon_spec_free(icon_spec); |
| |
223 |
| |
224 gtk_widget_set_visible(editor->avatar_row, show_avatar_opts); |
| |
225 |
| |
226 /* Determine our values. */ |
| |
227 if(editor->account != NULL) { |
| |
228 svalue = purple_account_get_private_alias(editor->account); |
| |
229 image = purple_buddy_icons_find_account_icon(editor->account); |
| |
230 use_global = purple_account_get_bool(editor->account, |
| |
231 "use-global-buddyicon", TRUE); |
| |
232 } |
| |
233 |
| |
234 if(svalue == NULL) { |
| |
235 svalue = ""; |
| |
236 } |
| |
237 |
| |
238 gtk_editable_set_text(GTK_EDITABLE(editor->alias), svalue); |
| |
239 gtk_switch_set_active(GTK_SWITCH(editor->use_custom_avatar), !use_global); |
| |
240 |
| |
241 g_clear_object(&editor->avatar_pixbuf); |
| |
242 if(PURPLE_IS_IMAGE(image)) { |
| |
243 editor->avatar_pixbuf = purple_gdk_pixbuf_from_image(image); |
| |
244 gtk_image_set_from_pixbuf(GTK_IMAGE(editor->avatar), |
| |
245 editor->avatar_pixbuf); |
| |
246 } else { |
| |
247 gtk_image_set_from_icon_name(GTK_IMAGE(editor->avatar), |
| |
248 "select-avatar"); |
| |
249 } |
| |
250 } |
| |
251 |
| |
252 static gboolean |
| |
253 pidgin_account_editor_advanced_option_use_default(PidginAccountEditor *editor) { |
| |
254 PurpleProtocol *protocol = NULL; |
| |
255 |
| |
256 /* If this is the new dialog, use the default value. */ |
| |
257 if(!PURPLE_IS_ACCOUNT(editor->account)) { |
| |
258 return TRUE; |
| |
259 } |
| |
260 |
| |
261 /* If we have an existing account, check if the protocol has changed. */ |
| |
262 protocol = pidgin_protocol_chooser_get_protocol(PIDGIN_PROTOCOL_CHOOSER(editor->protocol)); |
| |
263 if(protocol != purple_account_get_protocol(editor->account)) { |
| |
264 return TRUE; |
| |
265 } |
| |
266 |
| |
267 return FALSE; |
| |
268 } |
| |
269 |
| |
270 static GtkWidget * |
| |
271 pidgin_account_editor_add_advanced_boolean(PidginAccountEditor *editor, |
| |
272 PurpleAccountOption *option) |
| |
273 { |
| |
274 GtkWidget *row = NULL; |
| |
275 GtkWidget *toggle = NULL; |
| |
276 gboolean value = FALSE; |
| |
277 gchar *title = NULL; |
| |
278 |
| |
279 if(pidgin_account_editor_advanced_option_use_default(editor)) { |
| |
280 value = purple_account_option_get_default_bool(option); |
| |
281 } else { |
| |
282 const gchar *setting = purple_account_option_get_setting(option); |
| |
283 gboolean def_value = purple_account_option_get_default_bool(option); |
| |
284 |
| |
285 value = purple_account_get_bool(editor->account, setting, def_value); |
| |
286 } |
| |
287 |
| |
288 /* Create the row and set its title with a mnemonic. */ |
| |
289 row = adw_action_row_new(); |
| |
290 g_object_bind_property(editor->advanced_toggle, "active", row, "visible", |
| |
291 G_BINDING_SYNC_CREATE); |
| |
292 adw_preferences_row_set_use_underline(ADW_PREFERENCES_ROW(row), TRUE); |
| |
293 title = g_strdup_printf("_%s", purple_account_option_get_text(option)); |
| |
294 adw_preferences_row_set_title(ADW_PREFERENCES_ROW(row), title); |
| |
295 g_free(title); |
| |
296 |
| |
297 adw_preferences_group_add(ADW_PREFERENCES_GROUP(editor->advanced_group), |
| |
298 row); |
| |
299 |
| |
300 /* Add the row to the editor's list of advanced rows. */ |
| |
301 editor->advanced_rows = g_list_append(editor->advanced_rows, row); |
| |
302 |
| |
303 /* Create the input widget. */ |
| |
304 toggle = gtk_switch_new(); |
| |
305 gtk_switch_set_active(GTK_SWITCH(toggle), value); |
| |
306 gtk_widget_set_valign(toggle, GTK_ALIGN_CENTER); |
| |
307 adw_action_row_add_suffix(ADW_ACTION_ROW(row), toggle); |
| |
308 adw_action_row_set_activatable_widget(ADW_ACTION_ROW(row), toggle); |
| |
309 |
| |
310 return toggle; |
| |
311 } |
| |
312 |
| |
313 static GtkWidget * |
| |
314 pidgin_account_editor_add_advanced_int(PidginAccountEditor *editor, |
| |
315 PurpleAccountOption *option) |
| |
316 { |
| |
317 GtkWidget *row = NULL; |
| |
318 GtkWidget *entry = NULL; |
| |
319 gint value = 0; |
| |
320 gchar *title = NULL; |
| |
321 gchar *svalue = NULL; |
| |
322 |
| |
323 if(pidgin_account_editor_advanced_option_use_default(editor)) { |
| |
324 value = purple_account_option_get_default_int(option); |
| |
325 } else { |
| |
326 const gchar *setting = purple_account_option_get_setting(option); |
| |
327 gint def_value = purple_account_option_get_default_int(option); |
| |
328 |
| |
329 value = purple_account_get_int(editor->account, setting, def_value); |
| |
330 } |
| |
331 |
| |
332 /* Create the row and set its title with a mnemonic. */ |
| |
333 row = adw_action_row_new(); |
| |
334 g_object_bind_property(editor->advanced_toggle, "active", row, "visible", |
| |
335 G_BINDING_SYNC_CREATE); |
| |
336 adw_preferences_row_set_use_underline(ADW_PREFERENCES_ROW(row), TRUE); |
| |
337 title = g_strdup_printf("_%s", purple_account_option_get_text(option)); |
| |
338 adw_preferences_row_set_title(ADW_PREFERENCES_ROW(row), title); |
| |
339 g_free(title); |
| |
340 |
| |
341 adw_preferences_group_add(ADW_PREFERENCES_GROUP(editor->advanced_group), |
| |
342 row); |
| |
343 |
| |
344 /* Add the row to the editor's list of advanced rows. */ |
| |
345 editor->advanced_rows = g_list_append(editor->advanced_rows, row); |
| |
346 |
| |
347 /* Create the input widget. */ |
| |
348 entry = gtk_entry_new(); |
| |
349 gtk_entry_set_input_purpose(GTK_ENTRY(entry), GTK_INPUT_PURPOSE_DIGITS); |
| |
350 svalue = g_strdup_printf("%d", value); |
| |
351 gtk_editable_set_text(GTK_EDITABLE(entry), svalue); |
| |
352 g_free(svalue); |
| |
353 |
| |
354 gtk_widget_set_hexpand(entry, TRUE); |
| |
355 gtk_widget_set_valign(entry, GTK_ALIGN_CENTER); |
| |
356 adw_action_row_add_suffix(ADW_ACTION_ROW(row), entry); |
| |
357 adw_action_row_set_activatable_widget(ADW_ACTION_ROW(row), entry); |
| |
358 |
| |
359 return entry; |
| |
360 } |
| |
361 |
| |
362 static GtkWidget * |
| |
363 pidgin_account_editor_add_advanced_string(PidginAccountEditor *editor, |
| |
364 PurpleAccountOption *option) |
| |
365 { |
| |
366 GtkWidget *row = NULL; |
| |
367 GtkWidget *entry = NULL; |
| |
368 gchar *title = NULL; |
| |
369 const gchar *value = NULL; |
| |
370 |
| |
371 if(pidgin_account_editor_advanced_option_use_default(editor)) { |
| |
372 value = purple_account_option_get_default_string(option); |
| |
373 } else { |
| |
374 const gchar *setting = purple_account_option_get_setting(option); |
| |
375 const gchar *def_value = NULL; |
| |
376 |
| |
377 def_value = purple_account_option_get_default_string(option); |
| |
378 |
| |
379 value = purple_account_get_string(editor->account, setting, def_value); |
| |
380 } |
| |
381 |
| |
382 /* Create the row and set its title with a mnemonic. */ |
| |
383 row = adw_action_row_new(); |
| |
384 g_object_bind_property(editor->advanced_toggle, "active", row, "visible", |
| |
385 G_BINDING_SYNC_CREATE); |
| |
386 adw_preferences_row_set_use_underline(ADW_PREFERENCES_ROW(row), TRUE); |
| |
387 title = g_strdup_printf("_%s", purple_account_option_get_text(option)); |
| |
388 adw_preferences_row_set_title(ADW_PREFERENCES_ROW(row), title); |
| |
389 g_free(title); |
| |
390 |
| |
391 adw_preferences_group_add(ADW_PREFERENCES_GROUP(editor->advanced_group), |
| |
392 row); |
| |
393 |
| |
394 /* Add the row to the editor's list of advanced rows. */ |
| |
395 editor->advanced_rows = g_list_append(editor->advanced_rows, row); |
| |
396 |
| |
397 /* Create the input widget. */ |
| |
398 if(purple_account_option_string_get_masked(option)) { |
| |
399 entry = gtk_password_entry_new(); |
| |
400 } else { |
| |
401 entry = gtk_entry_new(); |
| |
402 } |
| |
403 |
| |
404 if(value != NULL) { |
| |
405 gtk_editable_set_text(GTK_EDITABLE(entry), value); |
| |
406 } |
| |
407 gtk_widget_set_hexpand(entry, TRUE); |
| |
408 gtk_widget_set_valign(entry, GTK_ALIGN_CENTER); |
| |
409 adw_action_row_add_suffix(ADW_ACTION_ROW(row), entry); |
| |
410 adw_action_row_set_activatable_widget(ADW_ACTION_ROW(row), entry); |
| |
411 |
| |
412 return entry; |
| |
413 } |
| |
414 |
| |
415 static GtkWidget * |
| |
416 pidgin_account_editor_add_advanced_list(PidginAccountEditor *editor, |
| |
417 PurpleAccountOption *option) |
| |
418 { |
| |
419 GtkWidget *row = NULL; |
| |
420 GtkStringList *model = NULL; |
| |
421 GList *data = NULL; |
| |
422 GList *items = NULL; |
| |
423 gchar *title = NULL; |
| |
424 const gchar *value = FALSE; |
| |
425 guint index = 0; |
| |
426 guint position = 0; |
| |
427 |
| |
428 if(pidgin_account_editor_advanced_option_use_default(editor)) { |
| |
429 value = purple_account_option_get_default_list_value(option); |
| |
430 } else { |
| |
431 const gchar *setting = purple_account_option_get_setting(option); |
| |
432 const gchar *def_value = NULL; |
| |
433 |
| |
434 def_value = purple_account_option_get_default_list_value(option); |
| |
435 |
| |
436 value = purple_account_get_string(editor->account, setting, def_value); |
| |
437 } |
| |
438 |
| |
439 /* Create the row and set its title with a mnemonic. */ |
| |
440 row = adw_combo_row_new(); |
| |
441 g_object_bind_property(editor->advanced_toggle, "active", row, "visible", |
| |
442 G_BINDING_SYNC_CREATE); |
| |
443 adw_preferences_row_set_use_underline(ADW_PREFERENCES_ROW(row), TRUE); |
| |
444 adw_combo_row_set_use_subtitle(ADW_COMBO_ROW(row), TRUE); |
| |
445 title = g_strdup_printf("_%s", purple_account_option_get_text(option)); |
| |
446 adw_preferences_row_set_title(ADW_PREFERENCES_ROW(row), title); |
| |
447 g_free(title); |
| |
448 |
| |
449 adw_preferences_group_add(ADW_PREFERENCES_GROUP(editor->advanced_group), |
| |
450 row); |
| |
451 |
| |
452 /* Add the row to the editor's list of advanced rows. */ |
| |
453 editor->advanced_rows = g_list_append(editor->advanced_rows, row); |
| |
454 |
| |
455 /* Create the model and data for the expression. */ |
| |
456 items = purple_account_option_get_list(option); |
| |
457 model = gtk_string_list_new(NULL); |
| |
458 |
| |
459 for(GList *l = items; l != NULL; l = l->next) { |
| |
460 PurpleKeyValuePair *kvp = l->data; |
| |
461 |
| |
462 if(kvp != NULL) { |
| |
463 if(purple_strequal(kvp->value, value)) { |
| |
464 position = index; |
| |
465 } |
| |
466 |
| |
467 data = g_list_append(data, kvp->value); |
| |
468 gtk_string_list_append(model, kvp->key); |
| |
469 } |
| |
470 |
| |
471 index++; |
| |
472 } |
| |
473 |
| |
474 adw_combo_row_set_model(ADW_COMBO_ROW(row), G_LIST_MODEL(model)); |
| |
475 adw_combo_row_set_selected(ADW_COMBO_ROW(row), position); |
| |
476 g_object_set_data_full(G_OBJECT(row), "keys", data, |
| |
477 (GDestroyNotify)g_list_free); |
| |
478 |
| |
479 return row; |
| |
480 } |
| |
481 |
| |
482 static void |
| |
483 pidgin_account_editor_add_advanced_option(PidginAccountEditor *editor, |
| |
484 PurpleAccountOption *option) |
| |
485 { |
| |
486 PurplePrefType type; |
| |
487 GtkWidget *widget = NULL; |
| |
488 |
| |
489 type = purple_account_option_get_pref_type(option); |
| |
490 switch(type) { |
| |
491 case PURPLE_PREF_BOOLEAN: |
| |
492 widget = pidgin_account_editor_add_advanced_boolean(editor, option); |
| |
493 break; |
| |
494 case PURPLE_PREF_INT: |
| |
495 widget = pidgin_account_editor_add_advanced_int(editor, option); |
| |
496 break; |
| |
497 case PURPLE_PREF_STRING: |
| |
498 widget = pidgin_account_editor_add_advanced_string(editor, option); |
| |
499 break; |
| |
500 case PURPLE_PREF_STRING_LIST: |
| |
501 widget = pidgin_account_editor_add_advanced_list(editor, option); |
| |
502 break; |
| |
503 default: |
| |
504 purple_debug_error("PidginAccountEditor", |
| |
505 "Invalid Account Option pref type (%d)", type); |
| |
506 break; |
| |
507 } |
| |
508 |
| |
509 if(GTK_IS_WIDGET(widget)) { |
| |
510 g_object_set_data_full(G_OBJECT(widget), "option", option, |
| |
511 (GDestroyNotify)purple_account_option_destroy); |
| |
512 |
| |
513 editor->advanced_entries = g_list_append(editor->advanced_entries, |
| |
514 widget); |
| |
515 } else { |
| |
516 purple_account_option_destroy(option); |
| |
517 } |
| |
518 } |
| |
519 |
| |
520 static void |
| |
521 pidgin_account_editor_update_advanced_options(PidginAccountEditor *editor, |
| |
522 PurpleProtocol *protocol) |
| |
523 { |
| |
524 GList *options = NULL; |
| |
525 |
| |
526 g_clear_pointer(&editor->advanced_entries, g_list_free); |
| |
527 while(editor->advanced_rows != NULL) { |
| |
528 adw_preferences_group_remove(ADW_PREFERENCES_GROUP(editor->advanced_group), |
| |
529 GTK_WIDGET(editor->advanced_rows->data)); |
| |
530 |
| |
531 editor->advanced_rows = g_list_delete_link(editor->advanced_rows, |
| |
532 editor->advanced_rows); |
| |
533 } |
| |
534 |
| |
535 if(!PURPLE_IS_PROTOCOL(protocol)) { |
| |
536 gtk_widget_set_visible(editor->advanced_group, FALSE); |
| |
537 |
| |
538 return; |
| |
539 } |
| |
540 |
| |
541 options = purple_protocol_get_account_options(protocol); |
| |
542 if(options == NULL) { |
| |
543 gtk_widget_set_visible(editor->advanced_group, FALSE); |
| |
544 |
| |
545 return; |
| |
546 } |
| |
547 |
| |
548 /* Iterate the options and call our helper which will take ownership of the |
| |
549 * option itself, but we'll delete the list item as we go. |
| |
550 */ |
| |
551 while(options != NULL) { |
| |
552 pidgin_account_editor_add_advanced_option(editor, options->data); |
| |
553 |
| |
554 options = g_list_delete_link(options, options); |
| |
555 } |
| |
556 |
| |
557 gtk_widget_set_visible(editor->advanced_group, TRUE); |
| |
558 } |
| |
559 |
| |
560 static void |
| |
561 pidgin_account_editor_update_proxy_options(PidginAccountEditor *editor) { |
| |
562 PurpleProxyInfo *info = NULL; |
| |
563 GListModel *model = NULL; |
| |
564 const gchar *svalue = NULL; |
| |
565 gint ivalue = 0; |
| |
566 guint position = 0; |
| |
567 |
| |
568 if(!PURPLE_IS_ACCOUNT(editor->account)) { |
| |
569 return; |
| |
570 } |
| |
571 |
| |
572 info = purple_account_get_proxy_info(editor->account); |
| |
573 |
| |
574 switch(purple_proxy_info_get_proxy_type(info)) { |
| |
575 case PURPLE_PROXY_TYPE_USE_GLOBAL: |
| |
576 svalue = "global"; |
| |
577 break; |
| |
578 case PURPLE_PROXY_TYPE_NONE: |
| |
579 svalue = "none"; |
| |
580 break; |
| |
581 case PURPLE_PROXY_TYPE_SOCKS4: |
| |
582 svalue = "socks4"; |
| |
583 break; |
| |
584 case PURPLE_PROXY_TYPE_SOCKS5: |
| |
585 svalue = "socks5"; |
| |
586 break; |
| |
587 case PURPLE_PROXY_TYPE_TOR: |
| |
588 svalue = "tor"; |
| |
589 break; |
| |
590 case PURPLE_PROXY_TYPE_HTTP: |
| |
591 svalue = "http"; |
| |
592 break; |
| |
593 case PURPLE_PROXY_TYPE_USE_ENVVAR: |
| |
594 svalue = "envvar"; |
| |
595 break; |
| |
596 } |
| |
597 |
| |
598 model = adw_combo_row_get_model(ADW_COMBO_ROW(editor->proxy_type)); |
| |
599 for(guint i = 0; i < g_list_model_get_n_items(model); i++) { |
| |
600 GtkStringObject *obj = g_list_model_get_item(model, i); |
| |
601 if(purple_strequal(svalue, gtk_string_object_get_string(obj))) { |
| |
602 position = i; |
| |
603 break; |
| |
604 } |
| |
605 } |
| |
606 adw_combo_row_set_selected(ADW_COMBO_ROW(editor->proxy_type), position); |
| |
607 |
| |
608 svalue = purple_proxy_info_get_hostname(info); |
| |
609 if(svalue == NULL) { |
| |
610 svalue = ""; |
| |
611 } |
| |
612 gtk_editable_set_text(GTK_EDITABLE(editor->proxy_host), svalue); |
| |
613 |
| |
614 ivalue = purple_proxy_info_get_port(info); |
| |
615 gtk_spin_button_set_value(GTK_SPIN_BUTTON(editor->proxy_port), |
| |
616 (gdouble)ivalue); |
| |
617 |
| |
618 svalue = purple_proxy_info_get_username(info); |
| |
619 if(svalue == NULL) { |
| |
620 svalue = ""; |
| |
621 } |
| |
622 gtk_editable_set_text(GTK_EDITABLE(editor->proxy_username), svalue); |
| |
623 |
| |
624 svalue = purple_proxy_info_get_password(info); |
| |
625 if(svalue == NULL) { |
| |
626 svalue = ""; |
| |
627 } |
| |
628 gtk_editable_set_text(GTK_EDITABLE(editor->proxy_password), svalue); |
| |
629 } |
| |
630 |
| |
631 static void |
| |
632 pidgin_account_editor_update(PidginAccountEditor *editor) { |
| |
633 PurpleProtocol *protocol = NULL; |
| |
634 gboolean sensitive = FALSE; |
| |
635 |
| |
636 if(PURPLE_IS_ACCOUNT(editor->account)) { |
| |
637 PurpleConnection *connection = NULL; |
| |
638 |
| |
639 connection = purple_account_get_connection(editor->account); |
| |
640 if(PURPLE_IS_CONNECTION(connection)) { |
| |
641 gtk_widget_set_sensitive(editor->protocol, FALSE); |
| |
642 } |
| |
643 } |
| |
644 |
| |
645 protocol = pidgin_protocol_chooser_get_protocol(PIDGIN_PROTOCOL_CHOOSER(editor->protocol)); |
| |
646 |
| |
647 sensitive = pidgin_account_editor_update_login_options(editor, protocol); |
| |
648 pidgin_account_editor_update_user_options(editor, protocol); |
| |
649 pidgin_account_editor_update_advanced_options(editor, protocol); |
| |
650 pidgin_account_editor_update_proxy_options(editor); |
| |
651 |
| |
652 gtk_dialog_set_response_sensitive(GTK_DIALOG(editor), GTK_RESPONSE_APPLY, |
| |
653 sensitive); |
| |
654 } |
| |
655 |
| |
656 static void |
| |
657 pidgin_account_editor_login_options_update_editable(PidginAccountEditor *editor) |
| |
658 { |
| |
659 PurpleConnection *connection = NULL; |
| |
660 gboolean editable = TRUE; |
| |
661 |
| |
662 if(PURPLE_IS_ACCOUNT(editor->account)) { |
| |
663 |
| |
664 connection = purple_account_get_connection(editor->account); |
| |
665 |
| |
666 /* If we have an active connection, we need to disable everything |
| |
667 * related to the protocol and username. |
| |
668 */ |
| |
669 if(PURPLE_IS_CONNECTION(connection)) { |
| |
670 PidginProtocolChooser *chooser = NULL; |
| |
671 PurpleProtocol *connected_protocol = NULL; |
| |
672 PurpleProtocol *selected_protocol = NULL; |
| |
673 editable = FALSE; |
| |
674 |
| |
675 /* Check if the user changed the protocol. If they did, switch it |
| |
676 * back and update the editor to reflect what settings are active. |
| |
677 */ |
| |
678 connected_protocol = purple_connection_get_protocol(connection); |
| |
679 |
| |
680 chooser = PIDGIN_PROTOCOL_CHOOSER(editor->protocol); |
| |
681 selected_protocol = pidgin_protocol_chooser_get_protocol(chooser); |
| |
682 if(connected_protocol != selected_protocol) { |
| |
683 pidgin_protocol_chooser_set_protocol(chooser, connected_protocol); |
| |
684 pidgin_account_editor_update(editor); |
| |
685 } |
| |
686 } |
| |
687 |
| |
688 } |
| |
689 |
| |
690 gtk_widget_set_sensitive(editor->protocol, editable); |
| |
691 gtk_editable_set_editable(GTK_EDITABLE(editor->username), editable); |
| |
692 for(GList *l = editor->user_split_entries; l != NULL; l = l->next) { |
| |
693 GtkWidget *widget = l->data; |
| |
694 |
| |
695 gtk_editable_set_editable(GTK_EDITABLE(widget), editable); |
| |
696 } |
| |
697 } |
| |
698 |
| |
699 static void |
| 49 pidgin_account_editor_set_account(PidginAccountEditor *editor, |
700 pidgin_account_editor_set_account(PidginAccountEditor *editor, |
| 50 PurpleAccount *account) |
701 PurpleAccount *account) |
| 51 { |
702 { |
| 52 if(g_set_object(&editor->account, account)) { |
703 if(g_set_object(&editor->account, account)) { |
| 53 PurpleProxyInfo *proxy_info = NULL; |
|
| 54 |
|
| 55 if(PURPLE_IS_ACCOUNT(account)) { |
704 if(PURPLE_IS_ACCOUNT(account)) { |
| 56 proxy_info = purple_account_get_proxy_info(account); |
705 g_signal_connect(account, "notify::connection", |
| 57 } |
706 G_CALLBACK(pidgin_account_editor_connection_changed_cb), |
| 58 |
707 editor); |
| 59 pidgin_proxy_options_set_info(PIDGIN_PROXY_OPTIONS(editor->proxy_options), |
708 } |
| 60 proxy_info); |
|
| 61 |
709 |
| 62 g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_ACCOUNT]); |
710 g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_ACCOUNT]); |
| 63 } |
711 } |
| |
712 |
| |
713 pidgin_account_editor_update(editor); |
| |
714 } |
| |
715 |
| |
716 static gboolean |
| |
717 pidgin_account_editor_save_login_options(PidginAccountEditor *editor) { |
| |
718 PurpleProtocol *protocol = NULL; |
| |
719 GList *split_item = NULL, *entry_item = NULL; |
| |
720 GString *username = NULL; |
| |
721 const gchar *protocol_id = NULL; |
| |
722 gboolean new_account = FALSE; |
| |
723 |
| |
724 protocol = pidgin_protocol_chooser_get_protocol(PIDGIN_PROTOCOL_CHOOSER(editor->protocol)); |
| |
725 protocol_id = purple_protocol_get_id(protocol); |
| |
726 |
| |
727 username = g_string_new(gtk_editable_get_text(GTK_EDITABLE(editor->username))); |
| |
728 |
| |
729 split_item = purple_protocol_get_user_splits(protocol); |
| |
730 entry_item = editor->user_split_entries; |
| |
731 while(split_item != NULL && entry_item != NULL) { |
| |
732 PurpleAccountUserSplit *split = split_item->data; |
| |
733 GtkEntry *entry = entry_item->data; |
| |
734 const gchar *value = ""; |
| |
735 gchar sep = '\0'; |
| |
736 |
| |
737 sep = purple_account_user_split_get_separator(split); |
| |
738 g_string_append_c(username, sep); |
| |
739 |
| |
740 if(GTK_IS_ENTRY(entry)) { |
| |
741 value = gtk_editable_get_text(GTK_EDITABLE(entry)); |
| |
742 } |
| |
743 |
| |
744 if(value == NULL || *value == '\0') { |
| |
745 value = purple_account_user_split_get_default_value(split); |
| |
746 } |
| |
747 |
| |
748 g_string_append(username, value); |
| |
749 |
| |
750 split_item = split_item->next; |
| |
751 entry_item = entry_item->next; |
| |
752 } |
| |
753 |
| |
754 if(!PURPLE_IS_ACCOUNT(editor->account)) { |
| |
755 editor->account = purple_account_new(username->str, protocol_id); |
| |
756 new_account = TRUE; |
| |
757 } else { |
| |
758 purple_account_set_username(editor->account, username->str); |
| |
759 purple_account_set_protocol_id(editor->account, protocol_id); |
| |
760 } |
| |
761 |
| |
762 g_string_free(username, TRUE); |
| |
763 |
| |
764 return new_account; |
| |
765 } |
| |
766 |
| |
767 static void |
| |
768 pidgin_account_editor_save_user_options(PidginAccountEditor *editor) { |
| |
769 const gchar *svalue = NULL; |
| |
770 gboolean bvalue = FALSE; |
| |
771 |
| |
772 /* Set the alias. */ |
| |
773 svalue = gtk_editable_get_text(GTK_EDITABLE(editor->alias)); |
| |
774 if(*svalue == '\0') { |
| |
775 svalue = NULL; |
| |
776 } |
| |
777 purple_account_set_private_alias(editor->account, svalue); |
| |
778 |
| |
779 /* Set whether or not to use the global avatar. */ |
| |
780 bvalue = gtk_switch_get_active(GTK_SWITCH(editor->use_custom_avatar)); |
| |
781 purple_account_set_bool(editor->account, "use-global-buddyicon", !bvalue); |
| |
782 |
| |
783 if(bvalue) { |
| |
784 if(GDK_IS_PIXBUF(editor->avatar_pixbuf)) { |
| |
785 # warning implement this when buddy icons do not suck so bad. |
| |
786 } else { |
| |
787 purple_buddy_icons_set_account_icon(editor->account, NULL, 0); |
| |
788 } |
| |
789 } else { |
| |
790 # warning set the global buddy icon when buddy icons do not suck so bad. |
| |
791 } |
| |
792 } |
| |
793 |
| |
794 static void |
| |
795 pidgin_account_editor_save_advanced_options(PidginAccountEditor *editor) { |
| |
796 for(GList *l = editor->advanced_entries; l != NULL; l = l->next) { |
| |
797 GtkWidget *widget = l->data; |
| |
798 PurpleAccountOption *option = NULL; |
| |
799 GList *keys = NULL; |
| |
800 const gchar *setting = NULL; |
| |
801 const gchar *svalue = NULL; |
| |
802 gboolean bvalue = FALSE; |
| |
803 gint ivalue = 0; |
| |
804 guint selected = 0; |
| |
805 |
| |
806 option = g_object_get_data(G_OBJECT(widget), "option"); |
| |
807 setting = purple_account_option_get_setting(option); |
| |
808 |
| |
809 switch(purple_account_option_get_pref_type(option)) { |
| |
810 case PURPLE_PREF_STRING: |
| |
811 svalue = gtk_editable_get_text(GTK_EDITABLE(widget)); |
| |
812 purple_account_set_string(editor->account, setting, svalue); |
| |
813 break; |
| |
814 case PURPLE_PREF_INT: |
| |
815 svalue = gtk_editable_get_text(GTK_EDITABLE(widget)); |
| |
816 ivalue = atoi(svalue); |
| |
817 purple_account_set_int(editor->account, setting, ivalue); |
| |
818 break; |
| |
819 case PURPLE_PREF_BOOLEAN: |
| |
820 bvalue = gtk_switch_get_active(GTK_SWITCH(widget)); |
| |
821 purple_account_set_bool(editor->account, setting, bvalue); |
| |
822 break; |
| |
823 case PURPLE_PREF_STRING_LIST: |
| |
824 keys = g_object_get_data(G_OBJECT(widget), "keys"); |
| |
825 selected = adw_combo_row_get_selected(ADW_COMBO_ROW(widget)); |
| |
826 svalue = g_list_nth_data(keys, selected); |
| |
827 purple_account_set_string(editor->account, setting, svalue); |
| |
828 break; |
| |
829 default: |
| |
830 break; |
| |
831 } |
| |
832 } |
| |
833 } |
| |
834 |
| |
835 static void |
| |
836 pidgin_account_editor_save_proxy(PidginAccountEditor *editor, |
| |
837 gboolean new_account) |
| |
838 { |
| |
839 PurpleProxyInfo *info = NULL; |
| |
840 PurpleProxyType type = PURPLE_PROXY_TYPE_NONE; |
| |
841 GObject *item = NULL; |
| |
842 const gchar *svalue = NULL; |
| |
843 gint ivalue = 0; |
| |
844 |
| |
845 /* Build the ProxyInfo object */ |
| |
846 if(new_account) { |
| |
847 info = purple_proxy_info_new(); |
| |
848 purple_account_set_proxy_info(editor->account, info); |
| |
849 } else { |
| |
850 info = purple_account_get_proxy_info(editor->account); |
| |
851 } |
| |
852 |
| |
853 item = adw_combo_row_get_selected_item(ADW_COMBO_ROW(editor->proxy_type)); |
| |
854 svalue = gtk_string_object_get_string(GTK_STRING_OBJECT(item)); |
| |
855 if(purple_strequal(svalue, "global")) { |
| |
856 type = PURPLE_PROXY_TYPE_USE_GLOBAL; |
| |
857 } else if(purple_strequal(svalue, "none")) { |
| |
858 type = PURPLE_PROXY_TYPE_NONE; |
| |
859 } else if(purple_strequal(svalue, "socks4")) { |
| |
860 type = PURPLE_PROXY_TYPE_SOCKS4; |
| |
861 } else if(purple_strequal(svalue, "socks5")) { |
| |
862 type = PURPLE_PROXY_TYPE_SOCKS5; |
| |
863 } else if(purple_strequal(svalue, "tor")) { |
| |
864 type = PURPLE_PROXY_TYPE_TOR; |
| |
865 } else if(purple_strequal(svalue, "http")) { |
| |
866 type = PURPLE_PROXY_TYPE_HTTP; |
| |
867 } else if(purple_strequal(svalue, "envvar")) { |
| |
868 type = PURPLE_PROXY_TYPE_USE_ENVVAR; |
| |
869 } |
| |
870 purple_proxy_info_set_proxy_type(info, type); |
| |
871 |
| |
872 svalue = gtk_editable_get_text(GTK_EDITABLE(editor->proxy_host)); |
| |
873 purple_proxy_info_set_hostname(info, svalue); |
| |
874 |
| |
875 ivalue = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editor->proxy_port)); |
| |
876 purple_proxy_info_set_port(info, ivalue); |
| |
877 |
| |
878 svalue = gtk_editable_get_text(GTK_EDITABLE(editor->proxy_username)); |
| |
879 purple_proxy_info_set_username(info, svalue); |
| |
880 |
| |
881 svalue = gtk_editable_get_text(GTK_EDITABLE(editor->proxy_password)); |
| |
882 purple_proxy_info_set_password(info, svalue); |
| 64 } |
883 } |
| 65 |
884 |
| 66 static void |
885 static void |
| 67 pidgin_account_editor_save_account(PidginAccountEditor *editor) { |
886 pidgin_account_editor_save_account(PidginAccountEditor *editor) { |
| 68 PurpleAccountManager *manager = NULL; |
|
| 69 PurpleProxyInfo *info = NULL; |
|
| 70 gboolean new_account = FALSE; |
887 gboolean new_account = FALSE; |
| 71 |
888 |
| 72 manager = purple_account_manager_get_default(); |
889 new_account = pidgin_account_editor_save_login_options(editor); |
| 73 |
890 pidgin_account_editor_save_user_options(editor); |
| 74 if(!PURPLE_IS_ACCOUNT(editor->account)) { |
891 pidgin_account_editor_save_advanced_options(editor); |
| 75 editor->account = purple_account_new("undefined", "undefined"); |
892 pidgin_account_editor_save_proxy(editor, new_account); |
| 76 new_account = TRUE; |
|
| 77 } |
|
| 78 |
|
| 79 info = pidgin_proxy_options_get_info(PIDGIN_PROXY_OPTIONS(editor->proxy_options)); |
|
| 80 purple_account_set_proxy_info(editor->account, info); |
|
| 81 |
893 |
| 82 /* If this is a new account, add it to the account manager and bring it |
894 /* If this is a new account, add it to the account manager and bring it |
| 83 * online. |
895 * online. |
| 84 */ |
896 */ |
| 85 if(new_account) { |
897 if(new_account) { |
| |
898 PurpleAccountManager *manager = NULL; |
| 86 const PurpleSavedStatus *saved_status; |
899 const PurpleSavedStatus *saved_status; |
| |
900 |
| |
901 manager = purple_account_manager_get_default(); |
| 87 |
902 |
| 88 purple_account_manager_add(manager, editor->account); |
903 purple_account_manager_add(manager, editor->account); |
| 89 |
904 |
| 90 saved_status = purple_savedstatus_get_current(); |
905 saved_status = purple_savedstatus_get_current(); |
| 91 if (saved_status != NULL) { |
906 if (saved_status != NULL) { |