pidgin/pidginaccountsmenu.c

changeset 41465
fc9819029e9d
parent 41464
979c8cc3413a
child 41466
557aad2bc415
equal deleted inserted replaced
41464:979c8cc3413a 41465:fc9819029e9d
1 /*
2 * Pidgin - Internet Messenger
3 * Copyright (C) Pidgin Developers <devel@pidgin.im>
4 *
5 * Pidgin is the legal property of its developers, whose names are too numerous
6 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * source distribution.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23 #include "pidginaccountsmenu.h"
24
25 #include <purple.h>
26
27 #include "pidginaccountactionsmenu.h"
28
29 #include "pidgincore.h"
30
31 struct _PidginAccountsMenu {
32 GtkMenu parent;
33
34 GtkWidget *enable_account;
35 GtkWidget *disabled_menu;
36 GtkWidget *separator;
37
38 GHashTable *account_items;
39 GHashTable *disabled_items;
40 };
41
42 /******************************************************************************
43 * GSignal Handlers
44 *****************************************************************************/
45 static void
46 pidgin_accounts_menu_enable_account(GtkMenuItem *item, gpointer data) {
47 PurpleAccount *account = PURPLE_ACCOUNT(data);
48
49 purple_account_set_enabled(account, TRUE);
50 }
51
52 /******************************************************************************
53 * Helpers
54 *****************************************************************************/
55 static GtkWidget *
56 pidgin_accounts_menu_create_account_menu_item(PidginAccountsMenu *menu,
57 PurpleAccount *account)
58 {
59 GtkWidget *item = NULL;
60 const gchar *account_name = purple_account_get_username(account);
61 const gchar *protocol_name = purple_account_get_protocol_name(account);
62 gchar *label = g_strdup_printf("%s (%s)", account_name, protocol_name);
63
64 item = gtk_menu_item_new_with_label(label);
65 g_free(label);
66 gtk_widget_show(item);
67
68 return item;
69 }
70
71 static void
72 pidgin_accounts_menu_add_enabled_account(PidginAccountsMenu *menu,
73 PurpleAccount *account)
74 {
75 GtkWidget *item = NULL, *submenu = NULL;
76 gpointer data = NULL;
77 gboolean found = FALSE;
78
79 /* if the account is in the disabled list, delete its widget */
80 found = g_hash_table_lookup_extended(menu->disabled_items, account, NULL,
81 &data);
82 if(found) {
83 g_clear_pointer(&data, gtk_widget_destroy);
84 g_hash_table_remove(menu->disabled_items, account);
85
86 if(g_hash_table_size(menu->disabled_items) == 0) {
87 gtk_widget_set_sensitive(menu->enable_account, FALSE);
88 }
89 }
90
91 item = pidgin_accounts_menu_create_account_menu_item(menu, account);
92 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
93 g_hash_table_insert(menu->account_items,
94 g_object_ref(G_OBJECT(account)),
95 item);
96
97 /* create the submenu and attach it to item right away, this allows us to
98 * reuse item for the submenu items.
99 */
100 submenu = pidgin_account_actions_menu_new(account);
101 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
102 }
103
104 static void
105 pidgin_accounts_menu_add_disabled_account(PidginAccountsMenu *menu,
106 PurpleAccount *account)
107 {
108 GtkWidget *item = NULL;
109 gpointer data = NULL;
110 gboolean found = FALSE;
111
112 /* if the account is in the enabled list, delete its widget */
113 found = g_hash_table_lookup_extended(menu->account_items, account, NULL,
114 &data);
115 if(found) {
116 g_clear_pointer(&data, gtk_widget_destroy);
117 g_hash_table_remove(menu->account_items, account);
118 }
119
120 item = pidgin_accounts_menu_create_account_menu_item(menu, account);
121 g_signal_connect(G_OBJECT(item), "activate",
122 G_CALLBACK(pidgin_accounts_menu_enable_account), account);
123 gtk_menu_shell_append(GTK_MENU_SHELL(menu->disabled_menu), item);
124
125 g_hash_table_insert(menu->disabled_items,
126 g_object_ref(G_OBJECT(account)),
127 item);
128
129 /* We know there's at least one item in the menu, so make sure it is
130 * sensitive.
131 */
132 gtk_widget_set_sensitive(menu->enable_account, TRUE);
133 }
134
135 static void
136 pidgin_accounts_menu_foreach_cb(PurpleAccount *account, gpointer data) {
137 PidginAccountsMenu *menu = PIDGIN_ACCOUNTS_MENU(data);
138
139 if(purple_account_get_enabled(account)) {
140 pidgin_accounts_menu_add_enabled_account(menu, account);
141 } else {
142 pidgin_accounts_menu_add_disabled_account(menu, account);
143 }
144 }
145
146 static void
147 pidgin_accounts_menu_add_current(PidginAccountsMenu *menu) {
148 PurpleAccountManager *manager = NULL;
149
150 manager = purple_account_manager_get_default();
151 purple_account_manager_foreach(manager, pidgin_accounts_menu_foreach_cb,
152 menu);
153 }
154
155 /******************************************************************************
156 * Purple Signal Callbacks
157 *****************************************************************************/
158 static void
159 pidgin_accounts_menu_account_status_changed(PurpleAccount *account,
160 gpointer d)
161 {
162 PidginAccountsMenu *menu = PIDGIN_ACCOUNTS_MENU(d);
163 gpointer data = NULL;
164
165 data = g_hash_table_lookup(menu->account_items, account);
166 if(GTK_IS_WIDGET(data)) {
167 gtk_menu_item_set_submenu(GTK_MENU_ITEM(data),
168 pidgin_account_actions_menu_new(account));
169 }
170 }
171
172 static void
173 pidgin_accounts_menu_account_enabled(PurpleAccount *account, gpointer data) {
174 pidgin_accounts_menu_add_enabled_account(PIDGIN_ACCOUNTS_MENU(data),
175 account);
176 }
177
178 static void
179 pidgin_accounts_menu_account_disabled(PurpleAccount *account, gpointer data) {
180 pidgin_accounts_menu_add_disabled_account(PIDGIN_ACCOUNTS_MENU(data),
181 account);
182 }
183
184 /******************************************************************************
185 * GObject Implementation
186 *****************************************************************************/
187 G_DEFINE_TYPE(PidginAccountsMenu, pidgin_accounts_menu, GTK_TYPE_MENU)
188
189 static void
190 pidgin_accounts_menu_init(PidginAccountsMenu *menu) {
191 gpointer handle;
192
193 /* initialize our template */
194 gtk_widget_init_template(GTK_WIDGET(menu));
195
196 /* create our storage for the items */
197 menu->account_items = g_hash_table_new_full(g_direct_hash, g_direct_equal,
198 g_object_unref, NULL);
199 menu->disabled_items = g_hash_table_new_full(g_direct_hash, g_direct_equal,
200 g_object_unref, NULL);
201
202 /* add all of the existing accounts */
203 pidgin_accounts_menu_add_current(menu);
204
205 /* finally connect to the purple signals to stay up to date */
206 handle = purple_accounts_get_handle();
207 purple_signal_connect(handle, "account-signed-on", menu,
208 G_CALLBACK(pidgin_accounts_menu_account_status_changed),
209 menu);
210 purple_signal_connect(handle, "account-signed-off", menu,
211 G_CALLBACK(pidgin_accounts_menu_account_status_changed),
212 menu);
213 purple_signal_connect(handle, "account-actions-changed", menu,
214 G_CALLBACK(pidgin_accounts_menu_account_status_changed),
215 menu);
216 purple_signal_connect(handle, "account-enabled", menu,
217 G_CALLBACK(pidgin_accounts_menu_account_enabled),
218 menu);
219 purple_signal_connect(handle, "account-disabled", menu,
220 G_CALLBACK(pidgin_accounts_menu_account_disabled),
221 menu);
222 };
223
224 static void
225 pidgin_accounts_menu_finalize(GObject *obj) {
226 PidginAccountsMenu *menu = PIDGIN_ACCOUNTS_MENU(obj);
227
228 purple_signals_disconnect_by_handle(obj);
229
230 g_hash_table_destroy(menu->account_items);
231 g_hash_table_destroy(menu->disabled_items);
232
233 G_OBJECT_CLASS(pidgin_accounts_menu_parent_class)->finalize(obj);
234 }
235
236 static void
237 pidgin_accounts_menu_class_init(PidginAccountsMenuClass *klass) {
238 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
239 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
240
241 obj_class->finalize = pidgin_accounts_menu_finalize;
242
243 gtk_widget_class_set_template_from_resource(
244 widget_class,
245 "/im/pidgin/Pidgin3/Accounts/menu.ui"
246 );
247
248 gtk_widget_class_bind_template_child(widget_class, PidginAccountsMenu,
249 enable_account);
250 gtk_widget_class_bind_template_child(widget_class, PidginAccountsMenu,
251 disabled_menu);
252 gtk_widget_class_bind_template_child(widget_class, PidginAccountsMenu,
253 separator);
254 }
255
256 /******************************************************************************
257 * Public API
258 *****************************************************************************/
259 GtkWidget *
260 pidgin_accounts_menu_new(void) {
261 return GTK_WIDGET(g_object_new(PIDGIN_TYPE_ACCOUNTS_MENU, NULL));
262 }
263

mercurial