pidgin/plugins/disco/gtkdisco.c

changeset 41499
a80a41434f44
parent 41314
0dc72eacd8bf
child 41562
bfd0330f09fb
equal deleted inserted replaced
41498:ea40c778bf9d 41499:a80a41434f44
1 /* pidgin 1 /*
2 * Pidgin - Internet Messenger
3 * Copyright (C) Pidgin Developers <devel@pidgin.im>
2 * 4 *
3 * Pidgin is the legal property of its developers, whose names are too numerous 5 * Pidgin is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this 6 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution. 7 * source distribution.
6 * 8 *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 17 * GNU General Public License for more details.
16 * 18 *
17 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 20 * along with this program; if not, see <https://www.gnu.org/licenses/>.
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
20 */ 21 */
21 22
22 #ifdef HAVE_CONFIG_H 23 #ifdef HAVE_CONFIG_H
23 # include <config.h> 24 # include <config.h>
24 #endif 25 #endif
40 DESCRIPTION_COLUMN, 41 DESCRIPTION_COLUMN,
41 SERVICE_COLUMN, 42 SERVICE_COLUMN,
42 NUM_OF_COLUMNS 43 NUM_OF_COLUMNS
43 }; 44 };
44 45
46 static PidginDiscoList *
47 pidgin_disco_list_new(void) {
48 return g_rc_box_new0(PidginDiscoList);
49 }
50
45 static void 51 static void
46 pidgin_disco_list_destroy(PidginDiscoList *list) 52 pidgin_disco_list_destroy(PidginDiscoList *list)
47 { 53 {
48 g_hash_table_destroy(list->services); 54 g_hash_table_destroy(list->services);
49 if (list->dialog && list->dialog->discolist == list) 55 if (list->dialog && list->dialog->discolist == list) {
50 list->dialog->discolist = NULL; 56 list->dialog->discolist = NULL;
57 }
51 58
52 g_free((gchar*)list->server); 59 g_free((gchar*)list->server);
53 g_free(list);
54 } 60 }
55 61
56 PidginDiscoList *pidgin_disco_list_ref(PidginDiscoList *list) 62 PidginDiscoList *pidgin_disco_list_ref(PidginDiscoList *list)
57 { 63 {
58 g_return_val_if_fail(list != NULL, NULL); 64 g_return_val_if_fail(list != NULL, NULL);
59 65
60 ++list->ref; 66 purple_debug_misc("xmppdisco", "reffing list");
61 purple_debug_misc("xmppdisco", "reffing list, ref count now %d\n", list->ref); 67 return g_rc_box_acquire(list);
62
63 return list;
64 } 68 }
65 69
66 void pidgin_disco_list_unref(PidginDiscoList *list) 70 void pidgin_disco_list_unref(PidginDiscoList *list)
67 { 71 {
68 g_return_if_fail(list != NULL); 72 g_return_if_fail(list != NULL);
69 73
70 --list->ref; 74 purple_debug_misc("xmppdisco", "unreffing list");
71 75 g_rc_box_release_full(list, (GDestroyNotify)pidgin_disco_list_destroy);
72 purple_debug_misc("xmppdisco", "unreffing list, ref count now %d\n", list->ref);
73 if (list->ref == 0)
74 pidgin_disco_list_destroy(list);
75 } 76 }
76 77
77 void pidgin_disco_list_set_in_progress(PidginDiscoList *list, gboolean in_progress) 78 void pidgin_disco_list_set_in_progress(PidginDiscoList *list, gboolean in_progress)
78 { 79 {
79 PidginDiscoDialog *dialog = list->dialog; 80 PidginDiscoDialog *dialog = list->dialog;
80 81
81 if (!dialog) 82 if (!dialog) {
82 return; 83 return;
84 }
83 85
84 list->in_progress = in_progress; 86 list->in_progress = in_progress;
85 87
86 if (in_progress) { 88 if (in_progress) {
87 gtk_widget_set_sensitive(dialog->account_chooser, FALSE); 89 gtk_widget_set_sensitive(dialog->account_chooser, FALSE);
88 gtk_widget_set_sensitive(dialog->stop_button, TRUE); 90 g_simple_action_set_enabled(dialog->stop_action, TRUE);
89 gtk_widget_set_sensitive(dialog->browse_button, FALSE); 91 g_simple_action_set_enabled(dialog->browse_action, FALSE);
90 } else { 92 } else {
91 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(dialog->progress), 0.0); 93 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(dialog->progress), 0.0);
92 94
93 gtk_widget_set_sensitive(dialog->account_chooser, TRUE); 95 gtk_widget_set_sensitive(dialog->account_chooser, TRUE);
94 96
95 gtk_widget_set_sensitive(dialog->stop_button, FALSE); 97 g_simple_action_set_enabled(dialog->stop_action, FALSE);
96 gtk_widget_set_sensitive(dialog->browse_button, TRUE); 98 g_simple_action_set_enabled(dialog->browse_action, TRUE);
97 /* 99 /*
98 gtk_widget_set_sensitive(dialog->register_button, FALSE); 100 g_simple_action_set_enabled(dialog->register_action, FALSE);
99 gtk_widget_set_sensitive(dialog->add_button, FALSE); 101 g_simple_action_set_enabled(dialog->add_action, FALSE);
100 */ 102 */
101 } 103 }
102 } 104 }
103 105
104 static GdkPixbuf * 106 static GdkPixbuf *
146 dialog_select_account_cb(GtkWidget *chooser, PidginDiscoDialog *dialog) 148 dialog_select_account_cb(GtkWidget *chooser, PidginDiscoDialog *dialog)
147 { 149 {
148 PurpleAccount *account = pidgin_account_chooser_get_selected(PIDGIN_ACCOUNT_CHOOSER(chooser)); 150 PurpleAccount *account = pidgin_account_chooser_get_selected(PIDGIN_ACCOUNT_CHOOSER(chooser));
149 gboolean change = (account != dialog->account); 151 gboolean change = (account != dialog->account);
150 dialog->account = account; 152 dialog->account = account;
151 gtk_widget_set_sensitive(dialog->browse_button, account != NULL); 153 g_simple_action_set_enabled(dialog->browse_action, account != NULL);
152 154
153 if (change) { 155 if (change) {
154 g_clear_pointer(&dialog->discolist, pidgin_disco_list_unref); 156 g_clear_pointer(&dialog->discolist, pidgin_disco_list_unref);
155 } 157 }
156 } 158 }
157 159
158 static void register_button_cb(GtkWidget *unused, PidginDiscoDialog *dialog) 160 static void
159 { 161 activate_register(G_GNUC_UNUSED GSimpleAction *action,
160 xmpp_disco_service_register(dialog->selected); 162 G_GNUC_UNUSED GVariant *parameter,
163 gpointer data)
164 {
165 PidginDiscoDialog *dialog = data;
166 XmppDiscoService *service = dialog->selected;
167
168 g_return_if_fail(service != NULL);
169
170 xmpp_disco_service_register(service);
161 } 171 }
162 172
163 static void discolist_cancel_cb(PidginDiscoList *pdl, const char *server) 173 static void discolist_cancel_cb(PidginDiscoList *pdl, const char *server)
164 { 174 {
165 pdl->dialog->prompt_handle = NULL; 175 pdl->dialog->prompt_handle = NULL;
169 } 179 }
170 180
171 static void discolist_ok_cb(PidginDiscoList *pdl, const char *server) 181 static void discolist_ok_cb(PidginDiscoList *pdl, const char *server)
172 { 182 {
173 pdl->dialog->prompt_handle = NULL; 183 pdl->dialog->prompt_handle = NULL;
174 gtk_widget_set_sensitive(pdl->dialog->browse_button, TRUE); 184 g_simple_action_set_enabled(pdl->dialog->browse_action, TRUE);
175 185
176 if (!server || !*server) { 186 if (!server || !*server) {
177 purple_notify_error(my_plugin, _("Invalid Server"), _("Invalid Server"), 187 purple_notify_error(my_plugin, _("Invalid Server"), _("Invalid Server"),
178 NULL, purple_request_cpar_from_connection(pdl->pc)); 188 NULL, purple_request_cpar_from_connection(pdl->pc));
179 189
185 pdl->server = g_strdup(server); 195 pdl->server = g_strdup(server);
186 pidgin_disco_list_set_in_progress(pdl, TRUE); 196 pidgin_disco_list_set_in_progress(pdl, TRUE);
187 xmpp_disco_start(pdl); 197 xmpp_disco_start(pdl);
188 } 198 }
189 199
190 static void browse_button_cb(GtkWidget *button, PidginDiscoDialog *dialog) 200 static void
191 { 201 activate_browse(G_GNUC_UNUSED GSimpleAction *action,
202 G_GNUC_UNUSED GVariant *parameter,
203 gpointer data)
204 {
205 PidginDiscoDialog *dialog = data;
192 PurpleConnection *pc; 206 PurpleConnection *pc;
193 PidginDiscoList *pdl; 207 PidginDiscoList *pdl;
194 const char *username; 208 const char *username;
195 const char *at, *slash; 209 const char *at, *slash;
196 char *server = NULL; 210 char *server = NULL;
197 211
198 pc = purple_account_get_connection(dialog->account); 212 pc = purple_account_get_connection(dialog->account);
199 if (!pc) 213 if (!pc) {
200 return; 214 return;
201 215 }
202 gtk_widget_set_sensitive(dialog->browse_button, FALSE); 216
203 gtk_widget_set_sensitive(dialog->add_button, FALSE); 217 g_simple_action_set_enabled(dialog->browse_action, FALSE);
204 gtk_widget_set_sensitive(dialog->register_button, FALSE); 218 g_simple_action_set_enabled(dialog->add_action, FALSE);
219 g_simple_action_set_enabled(dialog->register_action, FALSE);
205 220
206 g_clear_pointer(&dialog->discolist, pidgin_disco_list_unref); 221 g_clear_pointer(&dialog->discolist, pidgin_disco_list_unref);
207 gtk_tree_store_clear(dialog->model); 222 gtk_tree_store_clear(dialog->model);
208 223
209 pdl = dialog->discolist = g_new0(PidginDiscoList, 1); 224 pdl = dialog->discolist = pidgin_disco_list_new();
210 pdl->services = g_hash_table_new_full(NULL, NULL, NULL, 225 pdl->services = g_hash_table_new_full(NULL, NULL, NULL,
211 (GDestroyNotify)gtk_tree_row_reference_free); 226 (GDestroyNotify)gtk_tree_row_reference_free);
212 pdl->pc = pc; 227 pdl->pc = pc;
213 /* We keep a copy... */ 228 /* We keep a copy... */
214 pidgin_disco_list_ref(pdl); 229 pidgin_disco_list_ref(pdl);
224 server = g_strdup(at + 1); 239 server = g_strdup(at + 1);
225 } else if (at && slash && at + 1 < slash) { 240 } else if (at && slash && at + 1 < slash) {
226 server = g_strdup_printf("%.*s", (int)(slash - (at + 1)), at + 1); 241 server = g_strdup_printf("%.*s", (int)(slash - (at + 1)), at + 1);
227 } 242 }
228 243
229 if (server == NULL) 244 if (server == NULL) {
230 /* This shouldn't ever happen since the account is connected */ 245 /* This shouldn't ever happen since the account is connected */
231 server = g_strdup("jabber.org"); 246 server = g_strdup("jabber.org");
247 }
232 248
233 /* Translators: The string "Enter an XMPP Server" is asking the user to 249 /* Translators: The string "Enter an XMPP Server" is asking the user to
234 type the name of an XMPP server which will then be queried */ 250 type the name of an XMPP server which will then be queried */
235 dialog->prompt_handle = purple_request_input(my_plugin, _("Server name request"), _("Enter an XMPP Server"), 251 dialog->prompt_handle = purple_request_input(my_plugin, _("Server name request"), _("Enter an XMPP Server"),
236 _("Select an XMPP server to query"), 252 _("Select an XMPP server to query"),
240 purple_request_cpar_from_connection(pc), pdl); 256 purple_request_cpar_from_connection(pc), pdl);
241 257
242 g_free(server); 258 g_free(server);
243 } 259 }
244 260
245 static void add_to_blist_cb(GtkWidget *unused, PidginDiscoDialog *dialog) 261 static void
246 { 262 activate_add_to_blist(G_GNUC_UNUSED GSimpleAction *action,
263 G_GNUC_UNUSED GVariant *parameter,
264 gpointer data)
265 {
266 PidginDiscoDialog *dialog = data;
247 XmppDiscoService *service = dialog->selected; 267 XmppDiscoService *service = dialog->selected;
248 PurpleAccount *account; 268 PurpleAccount *account;
249 const char *jid; 269 const char *jid;
250 270
251 g_return_if_fail(service != NULL); 271 g_return_if_fail(service != NULL);
252 272
253 account = purple_connection_get_account(service->list->pc); 273 account = purple_connection_get_account(service->list->pc);
254 jid = service->jid; 274 jid = service->jid;
255 275
256 if (service->type == XMPP_DISCO_SERVICE_TYPE_CHAT) 276 if (service->type == XMPP_DISCO_SERVICE_TYPE_CHAT) {
257 purple_blist_request_add_chat(account, NULL, NULL, jid); 277 purple_blist_request_add_chat(account, NULL, NULL, jid);
258 else 278 } else {
259 purple_blist_request_add_buddy(account, jid, NULL, NULL); 279 purple_blist_request_add_buddy(account, jid, NULL, NULL);
280 }
260 } 281 }
261 282
262 static gboolean 283 static gboolean
263 service_click_cb(GtkTreeView *tree, GdkEventButton *event, gpointer user_data) 284 service_click_cb(GtkTreeView *tree, GdkEventButton *event, gpointer user_data)
264 { 285 {
265 PidginDiscoDialog *dialog = user_data; 286 PidginDiscoDialog *dialog = user_data;
266 XmppDiscoService *service; 287 XmppDiscoService *service;
267 GtkWidget *menu;
268 GtkWidget *menuitem = NULL;
269 288
270 GtkTreePath *path; 289 GtkTreePath *path;
271 GtkTreeIter iter; 290 GtkTreeIter iter;
272 GValue val; 291 GValue val;
273 292
274 if (!gdk_event_triggers_context_menu((GdkEvent *)event)) 293 GdkRectangle rect;
294
295 if (!gdk_event_triggers_context_menu((GdkEvent *)event)) {
275 return FALSE; 296 return FALSE;
297 }
276 298
277 /* Figure out what was clicked */ 299 /* Figure out what was clicked */
278 if (!gtk_tree_view_get_path_at_pos(tree, event->x, event->y, &path, 300 if (!gtk_tree_view_get_path_at_pos(tree, event->x, event->y, &path,
279 NULL, NULL, NULL)) 301 NULL, NULL, NULL))
302 {
280 return FALSE; 303 return FALSE;
304 }
281 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path); 305 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path);
282 gtk_tree_path_free(path); 306 gtk_tree_path_free(path);
283 val.g_type = 0; 307 val.g_type = 0;
284 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter, 308 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter,
285 SERVICE_COLUMN, &val); 309 SERVICE_COLUMN, &val);
286 service = g_value_get_pointer(&val); 310 service = g_value_get_pointer(&val);
287 311
288 if (!service) 312 if (!service) {
289 return FALSE; 313 return FALSE;
290 314 }
291 menu = gtk_menu_new(); 315
292 316 gtk_tree_view_convert_bin_window_to_widget_coords(dialog->tree,
293 if (service->flags & XMPP_DISCO_ADD) { 317 (gint)event->x,
294 menuitem = gtk_menu_item_new_with_label(_("Add to Buddy List")); 318 (gint)event->y,
295 g_signal_connect(G_OBJECT(menuitem), "activate", 319 &rect.x, &rect.y);
296 G_CALLBACK(add_to_blist_cb), dialog); 320 rect.width = rect.height = 1;
297 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 321
298 } 322 gtk_popover_set_pointing_to(GTK_POPOVER(dialog->popover), &rect);
299 323 gtk_popover_popup(GTK_POPOVER(dialog->popover));
300 if (service->flags & XMPP_DISCO_REGISTER) { 324
301 menuitem = gtk_menu_item_new_with_label(_("Register"));
302 g_signal_connect(G_OBJECT(menuitem), "activate",
303 G_CALLBACK(register_button_cb), dialog);
304 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
305 }
306
307 gtk_widget_show_all(menu);
308 gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
309 return FALSE; 325 return FALSE;
310 } 326 }
311 327
312 static void 328 static void
313 selection_changed_cb(GtkTreeSelection *selection, PidginDiscoDialog *dialog) 329 selection_changed_cb(GtkTreeSelection *selection, PidginDiscoDialog *dialog)
314 { 330 {
315 GtkTreeIter iter; 331 GtkTreeIter iter;
316 GValue val; 332 GValue val;
333 gboolean allow_add = FALSE, allow_register = FALSE;
317 334
318 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) { 335 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
319 val.g_type = 0; 336 val.g_type = 0;
320 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter, 337 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter,
321 SERVICE_COLUMN, &val); 338 SERVICE_COLUMN, &val);
322 dialog->selected = g_value_get_pointer(&val); 339 dialog->selected = g_value_get_pointer(&val);
323 if (!dialog->selected) { 340 if (dialog->selected != NULL) {
324 gtk_widget_set_sensitive(dialog->add_button, FALSE); 341 allow_add = (dialog->selected->flags & XMPP_DISCO_ADD);
325 gtk_widget_set_sensitive(dialog->register_button, FALSE); 342 allow_register = (dialog->selected->flags & XMPP_DISCO_REGISTER);
326 return; 343 }
327 } 344 }
328 345
329 gtk_widget_set_sensitive(dialog->add_button, dialog->selected->flags & XMPP_DISCO_ADD); 346 g_simple_action_set_enabled(dialog->add_action, allow_add);
330 gtk_widget_set_sensitive(dialog->register_button, dialog->selected->flags & XMPP_DISCO_REGISTER); 347 g_simple_action_set_enabled(dialog->register_action, allow_register);
331 } else {
332 gtk_widget_set_sensitive(dialog->add_button, FALSE);
333 gtk_widget_set_sensitive(dialog->register_button, FALSE);
334 }
335 } 348 }
336 349
337 static void 350 static void
338 row_expanded_cb(GtkTreeView *tree, GtkTreeIter *arg1, GtkTreePath *rg2, 351 row_expanded_cb(GtkTreeView *tree, GtkTreeIter *arg1, GtkTreePath *rg2,
339 gpointer user_data) 352 gpointer user_data)
358 PidginDiscoDialog *dialog = user_data; 371 PidginDiscoDialog *dialog = user_data;
359 GtkTreeIter iter; 372 GtkTreeIter iter;
360 XmppDiscoService *service; 373 XmppDiscoService *service;
361 GValue val; 374 GValue val;
362 375
363 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, 376 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path)) {
364 path)) {
365 return; 377 return;
366 } 378 }
367 379
368 val.g_type = 0; 380 val.g_type = 0;
369 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter, 381 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter,
370 SERVICE_COLUMN, &val); 382 SERVICE_COLUMN, &val);
371 service = g_value_get_pointer(&val); 383 service = g_value_get_pointer(&val);
372 384
373 if (service->flags & XMPP_DISCO_BROWSE) { 385 if (service->flags & XMPP_DISCO_BROWSE) {
374 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(dialog->tree), 386 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(dialog->tree), path)) {
375 path)) { 387 gtk_tree_view_collapse_row(GTK_TREE_VIEW(dialog->tree), path);
376 gtk_tree_view_collapse_row(GTK_TREE_VIEW(dialog->tree),
377 path);
378 } else { 388 } else {
379 gtk_tree_view_expand_row(GTK_TREE_VIEW(dialog->tree), 389 gtk_tree_view_expand_row(GTK_TREE_VIEW(dialog->tree), path, FALSE);
380 path, FALSE);
381 } 390 }
382 } else if (service->flags & XMPP_DISCO_REGISTER) { 391 } else if (service->flags & XMPP_DISCO_REGISTER) {
383 register_button_cb(NULL, dialog); 392 g_action_activate(G_ACTION(dialog->register_action), NULL);
384 } else if (service->flags & XMPP_DISCO_ADD) { 393 } else if (service->flags & XMPP_DISCO_ADD) {
385 add_to_blist_cb(NULL, dialog); 394 g_action_activate(G_ACTION(dialog->add_action), NULL);
386 } 395 }
387 } 396 }
388 397
389 static void 398 static void
390 destroy_win_cb(GtkWidget *window, G_GNUC_UNUSED gpointer data) 399 destroy_win_cb(GtkWidget *window, G_GNUC_UNUSED gpointer data)
391 { 400 {
392 PidginDiscoDialog *dialog = PIDGIN_DISCO_DIALOG(window); 401 PidginDiscoDialog *dialog = PIDGIN_DISCO_DIALOG(window);
393 PidginDiscoList *list = dialog->discolist; 402 PidginDiscoList *list = dialog->discolist;
394 403
395 if (dialog->prompt_handle) 404 if (dialog->prompt_handle) {
396 purple_request_close(PURPLE_REQUEST_INPUT, dialog->prompt_handle); 405 purple_request_close(PURPLE_REQUEST_INPUT, dialog->prompt_handle);
406 }
397 407
398 if (list) { 408 if (list) {
399 list->dialog = NULL; 409 list->dialog = NULL;
400 410
401 if (list->in_progress) 411 if (list->in_progress) {
402 list->in_progress = FALSE; 412 list->in_progress = FALSE;
413 }
403 414
404 pidgin_disco_list_unref(list); 415 pidgin_disco_list_unref(list);
405 } 416 }
406 417
407 dialogs = g_list_remove(dialogs, dialog); 418 dialogs = g_list_remove(dialogs, dialog);
408 } 419 }
409 420
410 static void stop_button_cb(GtkButton *button, PidginDiscoDialog *dialog) 421 static void
411 { 422 activate_stop(G_GNUC_UNUSED GSimpleAction *action,
423 G_GNUC_UNUSED GVariant *parameter,
424 gpointer data)
425 {
426 PidginDiscoDialog *dialog = data;
427
412 pidgin_disco_list_set_in_progress(dialog->discolist, FALSE); 428 pidgin_disco_list_set_in_progress(dialog->discolist, FALSE);
413 } 429 }
414 430
415 static void close_button_cb(GtkButton *button, PidginDiscoDialog *dialog) 431 static void close_button_cb(GtkButton *button, PidginDiscoDialog *dialog)
416 { 432 {
489 case XMPP_DISCO_SERVICE_TYPE_OTHER: 505 case XMPP_DISCO_SERVICE_TYPE_OTHER:
490 type = _("Other"); 506 type = _("Other");
491 break; 507 break;
492 } 508 }
493 509
510 name = g_markup_escape_text(service->name, -1);
511 jid = g_markup_escape_text(service->jid, -1);
512 if (service->description != NULL) {
513 desc = g_markup_escape_text(service->description, -1);
514 }
515
494 markup = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>\n<b>%s:</b> %s%s%s", 516 markup = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>\n<b>%s:</b> %s%s%s",
495 name = g_markup_escape_text(service->name, -1), 517 name, type, jid,
496 type,
497 jid = g_markup_escape_text(service->jid, -1),
498 service->description ? _("\n<b>Description:</b> ") : "", 518 service->description ? _("\n<b>Description:</b> ") : "",
499 service->description ? desc = g_markup_escape_text(service->description, -1) : ""); 519 service->description ? desc : "");
500 520
501 gtk_tooltip_set_markup(tooltip, markup); 521 gtk_tooltip_set_markup(tooltip, markup);
502 gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, path); 522 gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, path);
503 523
504 g_free(markup); 524 g_free(markup);
519 PidginDiscoList *list = dialog->discolist; 539 PidginDiscoList *list = dialog->discolist;
520 540
521 if (list && list->pc == pc) { 541 if (list && list->pc == pc) {
522 PurpleAccount *account = NULL; 542 PurpleAccount *account = NULL;
523 543
524 if (list->in_progress) 544 if (list->in_progress) {
525 pidgin_disco_list_set_in_progress(list, FALSE); 545 pidgin_disco_list_set_in_progress(list, FALSE);
546 }
526 547
527 gtk_tree_store_clear(dialog->model); 548 gtk_tree_store_clear(dialog->model);
528 549
529 pidgin_disco_list_unref(list); 550 pidgin_disco_list_unref(list);
530 dialog->discolist = NULL; 551 dialog->discolist = NULL;
531 552
532 account = pidgin_account_chooser_get_selected( 553 account = pidgin_account_chooser_get_selected(
533 PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser)); 554 PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser));
534 555
535 gtk_widget_set_sensitive( 556 g_simple_action_set_enabled(dialog->browse_action, account != NULL);
536 dialog->browse_button, 557 g_simple_action_set_enabled(dialog->add_action, FALSE);
537 account != NULL); 558 g_simple_action_set_enabled(dialog->register_action, FALSE);
538
539 gtk_widget_set_sensitive(dialog->register_button, FALSE);
540 gtk_widget_set_sensitive(dialog->add_button, FALSE);
541 } 559 }
542 } 560 }
543 } 561 }
544 562
545 void pidgin_disco_dialogs_destroy_all(void) 563 void pidgin_disco_dialogs_destroy_all(void)
569 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog, 587 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
570 account_chooser); 588 account_chooser);
571 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog, 589 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
572 progress); 590 progress);
573 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog, 591 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
574 stop_button);
575 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
576 browse_button);
577 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
578 register_button);
579 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
580 add_button);
581 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
582 tree); 592 tree);
583 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog, 593 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
584 model); 594 model);
595 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
596 popover);
597 gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
598 popover_menu);
585 599
586 gtk_widget_class_bind_template_callback(widget_class, destroy_win_cb); 600 gtk_widget_class_bind_template_callback(widget_class, destroy_win_cb);
587 gtk_widget_class_bind_template_callback(widget_class, stop_button_cb);
588 gtk_widget_class_bind_template_callback(widget_class, browse_button_cb);
589 gtk_widget_class_bind_template_callback(widget_class,
590 register_button_cb);
591 gtk_widget_class_bind_template_callback(widget_class, add_to_blist_cb);
592 gtk_widget_class_bind_template_callback(widget_class, close_button_cb); 601 gtk_widget_class_bind_template_callback(widget_class, close_button_cb);
593 gtk_widget_class_bind_template_callback(widget_class, 602 gtk_widget_class_bind_template_callback(widget_class,
594 dialog_select_account_cb); 603 dialog_select_account_cb);
595 gtk_widget_class_bind_template_callback(widget_class, row_activated_cb); 604 gtk_widget_class_bind_template_callback(widget_class, row_activated_cb);
596 gtk_widget_class_bind_template_callback(widget_class, row_expanded_cb); 605 gtk_widget_class_bind_template_callback(widget_class, row_expanded_cb);
605 } 614 }
606 615
607 static void 616 static void
608 pidgin_disco_dialog_init(PidginDiscoDialog *dialog) 617 pidgin_disco_dialog_init(PidginDiscoDialog *dialog)
609 { 618 {
619 GActionEntry entries[] = {
620 { .name = "stop", .activate = activate_stop },
621 { .name = "browse", .activate = activate_browse },
622 { .name = "register", .activate = activate_register },
623 { .name = "add", .activate = activate_add_to_blist },
624 };
625 GSimpleActionGroup *action_group = NULL;
626 GActionMap *action_map = NULL;
627
610 dialogs = g_list_prepend(dialogs, dialog); 628 dialogs = g_list_prepend(dialogs, dialog);
611 629
612 gtk_widget_init_template(GTK_WIDGET(dialog)); 630 gtk_widget_init_template(GTK_WIDGET(dialog));
613 631
614 /* accounts dropdown list */ 632 /* accounts dropdown list */
615 dialog->account = pidgin_account_chooser_get_selected( 633 dialog->account = pidgin_account_chooser_get_selected(
616 PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser)); 634 PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser));
617 635
618 /* browse button */
619 gtk_widget_set_sensitive(dialog->browse_button, dialog->account != NULL);
620
621 gtk_widget_set_has_tooltip(GTK_WIDGET(dialog->tree), TRUE); 636 gtk_widget_set_has_tooltip(GTK_WIDGET(dialog->tree), TRUE);
622 g_signal_connect(G_OBJECT(dialog->tree), "query-tooltip", 637 g_signal_connect(G_OBJECT(dialog->tree), "query-tooltip",
623 G_CALLBACK(disco_query_tooltip), dialog); 638 G_CALLBACK(disco_query_tooltip), dialog);
639
640 action_group = g_simple_action_group_new();
641 action_map = G_ACTION_MAP(action_group);
642 g_action_map_add_action_entries(action_map, entries, G_N_ELEMENTS(entries),
643 dialog);
644
645 dialog->stop_action = G_SIMPLE_ACTION(
646 g_action_map_lookup_action(action_map, "stop"));
647 g_simple_action_set_enabled(dialog->stop_action, FALSE);
648
649 dialog->browse_action = G_SIMPLE_ACTION(
650 g_action_map_lookup_action(action_map, "browse"));
651 g_simple_action_set_enabled(dialog->browse_action, dialog->account != NULL);
652
653 dialog->register_action = G_SIMPLE_ACTION(
654 g_action_map_lookup_action(action_map, "register"));
655 g_simple_action_set_enabled(dialog->register_action, FALSE);
656
657 dialog->add_action = G_SIMPLE_ACTION(
658 g_action_map_lookup_action(action_map, "add"));
659 g_simple_action_set_enabled(dialog->add_action, FALSE);
660
661 gtk_widget_insert_action_group(GTK_WIDGET(dialog), "disco",
662 G_ACTION_GROUP(action_group));
663
664 gtk_popover_bind_model(GTK_POPOVER(dialog->popover), dialog->popover_menu,
665 NULL);
624 } 666 }
625 667
626 /****************************************************************************** 668 /******************************************************************************
627 * Public API 669 * Public API
628 *****************************************************************************/ 670 *****************************************************************************/
634 } 676 }
635 677
636 PidginDiscoDialog * 678 PidginDiscoDialog *
637 pidgin_disco_dialog_new(void) 679 pidgin_disco_dialog_new(void)
638 { 680 {
639 PidginDiscoDialog *dialog = 681 PidginDiscoDialog *dialog = g_object_new(PIDGIN_TYPE_DISCO_DIALOG, NULL);
640 g_object_new(PIDGIN_TYPE_DISCO_DIALOG, NULL);
641 gtk_widget_show_all(GTK_WIDGET(dialog)); 682 gtk_widget_show_all(GTK_WIDGET(dialog));
642 return dialog; 683 return dialog;
643 } 684 }
644 685
645 void pidgin_disco_add_service(PidginDiscoList *pdl, XmppDiscoService *service, XmppDiscoService *parent) 686 void pidgin_disco_add_service(PidginDiscoList *pdl, XmppDiscoService *service, XmppDiscoService *parent)
650 gboolean append = TRUE; 691 gboolean append = TRUE;
651 692
652 dialog = pdl->dialog; 693 dialog = pdl->dialog;
653 g_return_if_fail(dialog != NULL); 694 g_return_if_fail(dialog != NULL);
654 695
655 if (service != NULL) 696 if (service != NULL) {
656 purple_debug_info("xmppdisco", "Adding service \"%s\"\n", service->name); 697 purple_debug_info("xmppdisco", "Adding service \"%s\"", service->name);
657 else 698 } else {
658 purple_debug_info("xmppdisco", "Service \"%s\" has no childrens\n", parent->name); 699 purple_debug_info("xmppdisco", "Service \"%s\" has no children",
700 parent->name);
701 }
659 702
660 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(dialog->progress)); 703 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(dialog->progress));
661 704
662 if (parent) { 705 if (parent) {
663 GtkTreeRowReference *rr; 706 GtkTreeRowReference *rr;
675 &parent_iter)) { 718 &parent_iter)) {
676 PidginDiscoList *tmp; 719 PidginDiscoList *tmp;
677 gtk_tree_model_get( 720 gtk_tree_model_get(
678 GTK_TREE_MODEL(dialog->model), &child, 721 GTK_TREE_MODEL(dialog->model), &child,
679 SERVICE_COLUMN, &tmp, -1); 722 SERVICE_COLUMN, &tmp, -1);
680 if (!tmp) 723 if (!tmp) {
681 append = FALSE; 724 append = FALSE;
725 }
682 } 726 }
683 } 727 }
684 } 728 }
685 729
686 if (service == NULL) { 730 if (service == NULL) {
687 if (parent != NULL && !append) 731 if (parent != NULL && !append) {
688 gtk_tree_store_remove(dialog->model, &child); 732 gtk_tree_store_remove(dialog->model, &child);
733 }
689 return; 734 return;
690 } 735 }
691 736
692 if (append) { 737 if (append) {
693 gtk_tree_store_append(dialog->model, &iter, 738 gtk_tree_store_append(dialog->model, &iter,
714 759
715 gtk_tree_store_set(dialog->model, &iter, PIXBUF_COLUMN, pixbuf, 760 gtk_tree_store_set(dialog->model, &iter, PIXBUF_COLUMN, pixbuf,
716 NAME_COLUMN, service->name, DESCRIPTION_COLUMN, 761 NAME_COLUMN, service->name, DESCRIPTION_COLUMN,
717 service->description, SERVICE_COLUMN, service, -1); 762 service->description, SERVICE_COLUMN, service, -1);
718 763
719 if (pixbuf) 764 if (pixbuf) {
720 g_object_unref(pixbuf); 765 g_object_unref(pixbuf);
721 } 766 }
722 767 }
768

mercurial