comparison src/gtkaccount.c @ 11789:1c53ff1e7a0d

[gaim-migrate @ 14080] In the accounts list, add or remove accounts to and from the list store based on the account-added and account-removed signals. This fixes a possible crash or two, I think, and allows for adding accounts without the accounts list being open. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 24 Oct 2005 04:50:12 +0000
parents 141368559673
children 41d84ac57cb6
comparison
equal deleted inserted replaced
11788:12d093e3a580 11789:1c53ff1e7a0d
78 GtkListStore *model; 78 GtkListStore *model;
79 GtkTreeIter drag_iter; 79 GtkTreeIter drag_iter;
80 80
81 GtkTreeViewColumn *screenname_col; 81 GtkTreeViewColumn *screenname_col;
82 82
83 GHashTable *account_pref_wins;
84
85 } AccountsWindow; 83 } AccountsWindow;
86 84
87 typedef struct 85 typedef struct
88 { 86 {
89 GaimGtkAccountDialogType type; 87 GaimGtkAccountDialogType type;
153 151
154 } GaimGtkPulseData; 152 } GaimGtkPulseData;
155 153
156 154
157 static AccountsWindow *accounts_window = NULL; 155 static AccountsWindow *accounts_window = NULL;
158 156 static GHashTable *account_pref_wins;
159 static void add_account(AccountsWindow *dialog, GaimAccount *account); 157
158 static void add_account_to_liststore(GaimAccount *account, gpointer user_data);
160 static void set_account(GtkListStore *store, GtkTreeIter *iter, 159 static void set_account(GtkListStore *store, GtkTreeIter *iter,
161 GaimAccount *account); 160 GaimAccount *account);
162 static char* 161 static char*
163 convert_buddy_icon(GaimPlugin *plugin, const char *path); 162 convert_buddy_icon(GaimPlugin *plugin, const char *path);
164 163
1374 1373
1375 static void 1374 static void
1376 account_win_destroy_cb(GtkWidget *w, GdkEvent *event, 1375 account_win_destroy_cb(GtkWidget *w, GdkEvent *event,
1377 AccountPrefsDialog *dialog) 1376 AccountPrefsDialog *dialog)
1378 { 1377 {
1379 if (accounts_window != NULL) 1378 g_hash_table_remove(account_pref_wins, dialog->account);
1380 g_hash_table_remove(accounts_window->account_pref_wins, dialog->account);
1381 1379
1382 gtk_widget_destroy(dialog->window); 1380 gtk_widget_destroy(dialog->window);
1383 1381
1384 if (dialog->user_split_entries != NULL) 1382 if (dialog->user_split_entries != NULL)
1385 g_list_free(dialog->user_split_entries); 1383 g_list_free(dialog->user_split_entries);
1423 GaimProxyInfo *proxy_info = NULL; 1421 GaimProxyInfo *proxy_info = NULL;
1424 GList *l, *l2; 1422 GList *l, *l2;
1425 const char *value; 1423 const char *value;
1426 char *username; 1424 char *username;
1427 char *tmp; 1425 char *tmp;
1428 size_t index;
1429 gboolean new = FALSE; 1426 gboolean new = FALSE;
1430 GtkTreeIter iter;
1431 GaimAccount *account; 1427 GaimAccount *account;
1432 1428
1433 if (dialog->account == NULL) 1429 if (dialog->account == NULL)
1434 { 1430 {
1435 const char *screenname; 1431 const char *screenname;
1508 1504
1509 gaim_account_set_username(account, username); 1505 gaim_account_set_username(account, username);
1510 g_free(username); 1506 g_free(username);
1511 1507
1512 /* Add the protocol settings */ 1508 /* Add the protocol settings */
1513 1509 if (dialog->prpl_info) {
1514 if(dialog->prpl_info) {
1515 for (l = dialog->prpl_info->protocol_options, 1510 for (l = dialog->prpl_info->protocol_options,
1516 l2 = dialog->protocol_opt_entries; 1511 l2 = dialog->protocol_opt_entries;
1517 l != NULL && l2 != NULL; 1512 l != NULL && l2 != NULL;
1518 l = l->next, l2 = l2->next) { 1513 l = l->next, l2 = l2->next) {
1519 1514
1598 gaim_proxy_info_set_password(proxy_info, value); 1593 gaim_proxy_info_set_password(proxy_info, value);
1599 else 1594 else
1600 gaim_proxy_info_set_password(proxy_info, NULL); 1595 gaim_proxy_info_set_password(proxy_info, NULL);
1601 } 1596 }
1602 1597
1603 /* Adds the account to the list, or modify the existing entry. */ 1598 /* We no longer need the data from the dialog window */
1604 if (accounts_window != NULL) {
1605 index = g_list_index(gaim_accounts_get_all(), account);
1606
1607 if (index != -1 &&
1608 (gtk_tree_model_iter_nth_child(
1609 GTK_TREE_MODEL(accounts_window->model), &iter,
1610 NULL, index))) {
1611
1612 set_account(accounts_window->model, &iter,
1613 account);
1614 }
1615 else {
1616 add_account(accounts_window, account);
1617 gaim_accounts_add(account);
1618 }
1619 }
1620
1621 account_win_destroy_cb(NULL, NULL, dialog); 1599 account_win_destroy_cb(NULL, NULL, dialog);
1622 1600
1623 gaim_signal_emit(gaim_gtk_account_get_handle(), "account-modified", account); 1601 /* If this is a new account, add it to our list */
1602 if (new)
1603 gaim_accounts_add(account);
1604 else
1605 gaim_signal_emit(gaim_gtk_account_get_handle(), "account-modified", account);
1624 1606
1625 /* TODO: This doesn't work quite right yet. */ 1607 /* TODO: This doesn't work quite right yet. */
1626 if (new) { 1608 if (new) {
1627 const char *current_savedstatus_name; 1609 const char *current_savedstatus_name;
1628 const GaimSavedStatus *saved_status; 1610 const GaimSavedStatus *saved_status;
1676 GtkWidget *dbox; 1658 GtkWidget *dbox;
1677 GtkWidget *notebook; 1659 GtkWidget *notebook;
1678 GtkWidget *button; 1660 GtkWidget *button;
1679 1661
1680 if (accounts_window != NULL && account != NULL && 1662 if (accounts_window != NULL && account != NULL &&
1681 (dialog = g_hash_table_lookup(accounts_window->account_pref_wins, 1663 (dialog = g_hash_table_lookup(account_pref_wins, account)) != NULL)
1682 account)) != NULL)
1683 { 1664 {
1684 gtk_window_present(GTK_WINDOW(dialog->window)); 1665 gtk_window_present(GTK_WINDOW(dialog->window));
1685 return; 1666 return;
1686 } 1667 }
1687 1668
1688 dialog = g_new0(AccountPrefsDialog, 1); 1669 dialog = g_new0(AccountPrefsDialog, 1);
1689 1670
1690 if (accounts_window != NULL && account != NULL) 1671 if (accounts_window != NULL && account != NULL)
1691 { 1672 {
1692 g_hash_table_insert(accounts_window->account_pref_wins, 1673 g_hash_table_insert(account_pref_wins, account, dialog);
1693 account, dialog);
1694 } 1674 }
1695 1675
1696 dialog->account = account; 1676 dialog->account = account;
1697 dialog->type = type; 1677 dialog->type = type;
1698 dialog->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 1678 dialog->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1821 1801
1822 /************************************************************************** 1802 /**************************************************************************
1823 * Accounts Dialog 1803 * Accounts Dialog
1824 **************************************************************************/ 1804 **************************************************************************/
1825 static void 1805 static void
1826 signed_on_off_cb(GaimConnection *gc, AccountsWindow *dialog) 1806 signed_on_off_cb(GaimConnection *gc, gpointer user_data)
1827 { 1807 {
1828 GaimAccount *account = gaim_connection_get_account(gc); 1808 GaimAccount *account;
1829 GaimGtkPulseData *pulse_data; 1809 GaimGtkPulseData *pulse_data;
1830 GtkTreeModel *model = GTK_TREE_MODEL(dialog->model); 1810 GtkTreeModel *model;
1831 GtkTreeIter iter; 1811 GtkTreeIter iter;
1832 GdkPixbuf *pixbuf, *scale = NULL; 1812 GdkPixbuf *pixbuf, *scale = NULL;
1833 size_t index = g_list_index(gaim_accounts_get_all(), account); 1813 size_t index;
1814
1815 /* Don't need to do anything if the accounts window is not visible */
1816 if (accounts_window == NULL)
1817 return;
1818
1819 account = gaim_connection_get_account(gc);
1820 model = GTK_TREE_MODEL(accounts_window->model);
1821 index = g_list_index(gaim_accounts_get_all(), account);
1834 1822
1835 if (gtk_tree_model_iter_nth_child(model, &iter, NULL, index)) 1823 if (gtk_tree_model_iter_nth_child(model, &iter, NULL, index))
1836 { 1824 {
1837 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, 1825 gtk_tree_model_get(GTK_TREE_MODEL(accounts_window->model), &iter,
1838 COLUMN_PULSE_DATA, &pulse_data, -1); 1826 COLUMN_PULSE_DATA, &pulse_data, -1);
1839 1827
1840 if (pulse_data != NULL) 1828 if (pulse_data != NULL)
1841 { 1829 {
1842 if (pulse_data->timeout > 0) 1830 if (pulse_data->timeout > 0)
1855 GDK_INTERP_BILINEAR); 1843 GDK_INTERP_BILINEAR);
1856 1844
1857 if (gaim_account_is_disconnected(account)) 1845 if (gaim_account_is_disconnected(account))
1858 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); 1846 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE);
1859 } 1847 }
1860 gtk_list_store_set(dialog->model, &iter, 1848 gtk_list_store_set(accounts_window->model, &iter,
1861 COLUMN_ICON, scale, 1849 COLUMN_ICON, scale,
1862 COLUMN_PULSE_DATA, NULL, 1850 COLUMN_PULSE_DATA, NULL,
1863 -1); 1851 -1);
1864 1852
1865 1853
1866 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf)); 1854 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf));
1867 if (scale != NULL) g_object_unref(G_OBJECT(scale)); 1855 if (scale != NULL) g_object_unref(G_OBJECT(scale));
1868 } 1856 }
1857 }
1858
1859 /*
1860 * Get the GtkTreeIter of the specified account in the
1861 * GtkListStore
1862 */
1863 static gboolean
1864 accounts_window_find_account_in_treemodel(GtkTreeIter *iter, GaimAccount *account)
1865 {
1866 GtkTreeModel *model;
1867 GaimAccount *cur;
1868
1869 g_return_val_if_fail(account != NULL, FALSE);
1870 g_return_val_if_fail(accounts_window != NULL, FALSE);
1871
1872 model = GTK_TREE_MODEL(accounts_window->model);
1873
1874 if (!gtk_tree_model_get_iter_first(model, iter))
1875 return FALSE;
1876
1877 gtk_tree_model_get(model, iter, COLUMN_DATA, &cur, -1);
1878 if (cur == account)
1879 return TRUE;
1880
1881 while (gtk_tree_model_iter_next(model, iter))
1882 {
1883 gtk_tree_model_get(model, iter, COLUMN_DATA, &cur, -1);
1884 if (cur == account)
1885 return TRUE;
1886 }
1887
1888 return FALSE;
1889 }
1890
1891 static void
1892 account_removed_cb(GaimAccount *account, gpointer user_data)
1893 {
1894 AccountPrefsDialog *dialog;
1895 GtkTreeIter iter;
1896
1897 /* If the account was being modified, close the edit window */
1898 if ((dialog = g_hash_table_lookup(account_pref_wins, account)) != NULL)
1899 account_win_destroy_cb(NULL, NULL, dialog);
1900
1901 if (accounts_window == NULL)
1902 return;
1903
1904 /* Remove the account from the GtkListStore */
1905 if (accounts_window_find_account_in_treemodel(&iter, account))
1906 gtk_list_store_remove(accounts_window->model, &iter);
1869 } 1907 }
1870 1908
1871 static void 1909 static void
1872 drag_data_get_cb(GtkWidget *widget, GdkDragContext *ctx, 1910 drag_data_get_cb(GtkWidget *widget, GdkDragContext *ctx,
1873 GtkSelectionData *data, guint info, guint time, 1911 GtkSelectionData *data, guint info, guint time,
2061 } 2099 }
2062 2100
2063 static void 2101 static void
2064 delete_account_cb(GaimAccount *account) 2102 delete_account_cb(GaimAccount *account)
2065 { 2103 {
2066 size_t index;
2067 GtkTreeIter iter;
2068
2069 index = g_list_index(gaim_accounts_get_all(), account);
2070
2071 if (accounts_window != NULL)
2072 {
2073 AccountPrefsDialog *dialog;
2074
2075 if (gtk_tree_model_iter_nth_child(
2076 GTK_TREE_MODEL(accounts_window->model), &iter, NULL, index))
2077 {
2078 gtk_list_store_remove(accounts_window->model, &iter);
2079 }
2080
2081 if ((dialog = g_hash_table_lookup(accounts_window->account_pref_wins,
2082 account)) != NULL)
2083 {
2084 account_win_destroy_cb(NULL, NULL, dialog);
2085 }
2086 }
2087
2088 gaim_accounts_delete(account); 2104 gaim_accounts_delete(account);
2089 } 2105 }
2090 2106
2091 static void 2107 static void
2092 ask_delete_account_sel(GtkTreeModel *model, GtkTreePath *path, 2108 ask_delete_account_sel(GtkTreeModel *model, GtkTreePath *path,
2238 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf)); 2254 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf));
2239 if (scale != NULL) g_object_unref(G_OBJECT(scale)); 2255 if (scale != NULL) g_object_unref(G_OBJECT(scale));
2240 } 2256 }
2241 2257
2242 static void 2258 static void
2243 add_account(AccountsWindow *dialog, GaimAccount *account) 2259 add_account_to_liststore(GaimAccount *account, gpointer user_data)
2244 { 2260 {
2245 GtkTreeIter iter; 2261 GtkTreeIter iter;
2246 2262
2247 gtk_list_store_append(dialog->model, &iter); 2263 if (accounts_window == NULL)
2248 2264 return;
2249 set_account(dialog->model, &iter, account); 2265
2266 gtk_list_store_append(accounts_window->model, &iter);
2267
2268 set_account(accounts_window->model, &iter, account);
2250 } 2269 }
2251 2270
2252 static void 2271 static void
2253 populate_accounts_list(AccountsWindow *dialog) 2272 populate_accounts_list(AccountsWindow *dialog)
2254 { 2273 {
2255 GList *l; 2274 GList *l;
2256 2275
2257 gtk_list_store_clear(dialog->model); 2276 gtk_list_store_clear(dialog->model);
2258 2277
2259 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) 2278 for (l = gaim_accounts_get_all(); l != NULL; l = l->next)
2260 add_account(dialog, (GaimAccount *)l->data); 2279 add_account_to_liststore((GaimAccount *)l->data, NULL);
2261 } 2280 }
2262 2281
2263 #if !GTK_CHECK_VERSION(2,2,0) 2282 #if !GTK_CHECK_VERSION(2,2,0)
2264 static void 2283 static void
2265 get_selected_helper(GtkTreeModel *model, GtkTreePath *path, 2284 get_selected_helper(GtkTreeModel *model, GtkTreePath *path,
2392 return; 2411 return;
2393 } 2412 }
2394 2413
2395 accounts_window = dialog = g_new0(AccountsWindow, 1); 2414 accounts_window = dialog = g_new0(AccountsWindow, 1);
2396 2415
2397 accounts_window->account_pref_wins =
2398 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
2399
2400 width = gaim_prefs_get_int("/gaim/gtk/accounts/dialog/width"); 2416 width = gaim_prefs_get_int("/gaim/gtk/accounts/dialog/width");
2401 height = gaim_prefs_get_int("/gaim/gtk/accounts/dialog/height"); 2417 height = gaim_prefs_get_int("/gaim/gtk/accounts/dialog/height");
2402 2418
2403 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); 2419 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2404 gtk_window_set_default_size(GTK_WINDOW(win), width, height); 2420 gtk_window_set_default_size(GTK_WINDOW(win), width, height);
2462 gtk_widget_show(button); 2478 gtk_widget_show(button);
2463 2479
2464 g_signal_connect(G_OBJECT(button), "clicked", 2480 g_signal_connect(G_OBJECT(button), "clicked",
2465 G_CALLBACK(close_accounts_cb), dialog); 2481 G_CALLBACK(close_accounts_cb), dialog);
2466 2482
2467 /* Setup some gaim signal handlers. */
2468 gaim_signal_connect(gaim_connections_get_handle(), "signed-on",
2469 dialog, GAIM_CALLBACK(signed_on_off_cb), dialog);
2470 gaim_signal_connect(gaim_connections_get_handle(), "signed-off",
2471 dialog, GAIM_CALLBACK(signed_on_off_cb), dialog);
2472 2483
2473 gtk_widget_show(win); 2484 gtk_widget_show(win);
2474 } 2485 }
2475 2486
2476 void 2487 void
2478 { 2489 {
2479 if (accounts_window == NULL) 2490 if (accounts_window == NULL)
2480 return; 2491 return;
2481 2492
2482 gaim_signals_disconnect_by_handle(accounts_window); 2493 gaim_signals_disconnect_by_handle(accounts_window);
2483
2484 g_hash_table_destroy(accounts_window->account_pref_wins);
2485 2494
2486 g_free(accounts_window); 2495 g_free(accounts_window);
2487 accounts_window = NULL; 2496 accounts_window = NULL;
2488 2497
2489 /* See if we're the main window here. */ 2498 /* See if we're the main window here. */
2598 2607
2599 gaim_signal_register(gaim_gtk_account_get_handle(), "account-modified", 2608 gaim_signal_register(gaim_gtk_account_get_handle(), "account-modified",
2600 gaim_marshal_VOID__POINTER, NULL, 1, 2609 gaim_marshal_VOID__POINTER, NULL, 1,
2601 gaim_value_new(GAIM_TYPE_SUBTYPE, 2610 gaim_value_new(GAIM_TYPE_SUBTYPE,
2602 GAIM_SUBTYPE_ACCOUNT)); 2611 GAIM_SUBTYPE_ACCOUNT));
2612
2613 /* Setup some gaim signal handlers. */
2614 gaim_signal_connect(gaim_connections_get_handle(), "signed-on",
2615 gaim_gtk_account_get_handle(),
2616 GAIM_CALLBACK(signed_on_off_cb), NULL);
2617 gaim_signal_connect(gaim_connections_get_handle(), "signed-off",
2618 gaim_gtk_account_get_handle(),
2619 GAIM_CALLBACK(signed_on_off_cb), NULL);
2620 gaim_signal_connect(gaim_accounts_get_handle(), "account-added",
2621 gaim_gtk_account_get_handle(),
2622 GAIM_CALLBACK(add_account_to_liststore), NULL);
2623 gaim_signal_connect(gaim_accounts_get_handle(), "account-removed",
2624 gaim_gtk_account_get_handle(),
2625 GAIM_CALLBACK(account_removed_cb), NULL);
2626
2627 account_pref_wins =
2628 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
2603 } 2629 }
2604 2630
2605 void 2631 void
2606 gaim_gtk_account_uninit(void) 2632 gaim_gtk_account_uninit(void)
2607 { 2633 {
2634 /*
2635 * TODO: Need to free all the dialogs in here. Could probably create
2636 * a callback function to use for the free-some-data-function
2637 * parameter of g_hash_table_new_full, above.
2638 */
2639 g_hash_table_destroy(account_pref_wins);
2640
2641 gaim_signals_disconnect_by_handle(gaim_gtk_account_get_handle());
2608 gaim_signals_unregister_by_instance(gaim_gtk_account_get_handle()); 2642 gaim_signals_unregister_by_instance(gaim_gtk_account_get_handle());
2609 } 2643 }
2644