Mercurial > pidgin
annotate src/gtkblist.c @ 11986:bfbb1798535e
[gaim-migrate @ 14279]
Switch to using the unicode character 0x25cf instead of an asterisk as
our password masking character.
In the words of the great Christian Hammond, "By the way, isn't it
about time we replace the asterisk in masked entries with that unicode
character for the round filled circle ("?")? The asterisk is so 1980s."
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Sat, 05 Nov 2005 23:42:35 +0000 |
| parents | 39f2aa4350d8 |
| children | 9ccbd9f8e8c6 |
| rev | line source |
|---|---|
| 5228 | 1 /* |
|
10297
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10288
diff
changeset
|
2 * @file gtkblist.c GTK+ BuddyList API |
|
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10288
diff
changeset
|
3 * @ingroup gtkui |
|
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10288
diff
changeset
|
4 * |
| 5228 | 5 * gaim |
| 6 * | |
| 8046 | 7 * Gaim is the legal property of its developers, whose names are too numerous |
| 8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 9 * source distribution. | |
| 5228 | 10 * |
| 11 * This program is free software; you can redistribute it and/or modify | |
| 12 * it under the terms of the GNU General Public License as published by | |
| 13 * the Free Software Foundation; either version 2 of the License, or | |
| 14 * (at your option) any later version. | |
| 15 * | |
| 16 * This program is distributed in the hope that it will be useful, | |
| 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 19 * GNU General Public License for more details. | |
| 20 * | |
| 21 * You should have received a copy of the GNU General Public License | |
| 22 * along with this program; if not, write to the Free Software | |
| 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 24 * | |
| 25 */ | |
| 9791 | 26 #include "internal.h" |
| 27 #include "gtkgaim.h" | |
| 7620 | 28 |
| 29 #include "account.h" | |
| 9015 | 30 #include "connection.h" |
| 7620 | 31 #include "core.h" |
| 32 #include "debug.h" | |
| 33 #include "notify.h" | |
| 34 #include "prpl.h" | |
| 35 #include "prefs.h" | |
| 8986 | 36 #include "plugin.h" |
| 7620 | 37 #include "request.h" |
| 38 #include "signals.h" | |
|
10297
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10288
diff
changeset
|
39 #include "gtkstock.h" |
| 7620 | 40 #include "util.h" |
| 41 | |
| 42 #include "gtkaccount.h" | |
| 43 #include "gtkblist.h" | |
| 44 #include "gtkconv.h" | |
| 45 #include "gtkdebug.h" | |
| 9709 | 46 #include "gtkdialogs.h" |
| 7620 | 47 #include "gtkft.h" |
| 48 #include "gtklog.h" | |
| 49 #include "gtkpounce.h" | |
| 11740 | 50 #include "gtkplugin.h" |
| 7620 | 51 #include "gtkprefs.h" |
| 52 #include "gtkprivacy.h" | |
| 8113 | 53 #include "gtkroomlist.h" |
| 10643 | 54 #include "gtkstatusbox.h" |
| 7620 | 55 #include "gtkutils.h" |
| 56 | |
| 5228 | 57 #include <gdk/gdkkeysyms.h> |
| 58 #include <gtk/gtk.h> | |
| 7620 | 59 #include <gdk/gdk.h> |
| 60 | |
| 61 typedef struct | |
| 62 { | |
| 63 GaimAccount *account; | |
| 64 | |
| 65 GtkWidget *window; | |
| 66 GtkWidget *combo; | |
| 67 GtkWidget *entry; | |
| 68 GtkWidget *entry_for_alias; | |
| 69 GtkWidget *account_box; | |
| 70 | |
| 71 } GaimGtkAddBuddyData; | |
| 72 | |
| 73 typedef struct | |
| 74 { | |
| 9811 | 75 GaimAccount *account; |
| 9812 | 76 gchar *default_chat_name; |
| 9811 | 77 |
| 78 GtkWidget *window; | |
| 7620 | 79 GtkWidget *account_menu; |
| 80 GtkWidget *alias_entry; | |
| 81 GtkWidget *group_combo; | |
| 82 GtkWidget *entries_box; | |
| 83 GtkSizeGroup *sg; | |
| 84 | |
| 85 GList *entries; | |
| 86 | |
| 87 } GaimGtkAddChatData; | |
| 88 | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
89 typedef struct |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
90 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
91 GaimAccount *account; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
92 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
93 GtkWidget *window; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
94 GtkWidget *account_menu; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
95 GtkWidget *entries_box; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
96 GtkSizeGroup *sg; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
97 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
98 GList *entries; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
99 } GaimGtkJoinChatData; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
100 |
| 7620 | 101 |
| 9949 | 102 static GtkWidget *protomenu = NULL; |
| 5228 | 103 |
| 11796 | 104 static GList *gaim_gtk_blist_sort_methods = NULL; |
| 5422 | 105 static struct gaim_gtk_blist_sort_method *current_sort_method = NULL; |
| 7620 | 106 static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); |
| 107 | |
| 108 /* The functions we use for sorting aren't available in gtk 2.0.x, and | |
| 109 * segfault in 2.2.0. 2.2.1 is known to work, so I'll require that */ | |
| 110 #if GTK_CHECK_VERSION(2,2,1) | |
| 111 static GtkTreeIter sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
| 112 static GtkTreeIter sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
| 113 static GtkTreeIter sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
| 114 #endif | |
| 115 static GaimGtkBuddyList *gtkblist = NULL; | |
| 5228 | 116 |
| 117 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); | |
| 7620 | 118 static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node); |
| 5234 | 119 static char *gaim_get_tooltip_text(GaimBlistNode *node); |
| 5228 | 120 static char *item_factory_translate_func (const char *path, gpointer func_data); |
| 5273 | 121 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter); |
| 7620 | 122 static void redo_buddy_list(GaimBuddyList *list, gboolean remove); |
| 123 static void gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node); | |
| 124 | |
|
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
125 static void gaim_gtk_blist_tooltip_destroy(); |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
126 |
| 5256 | 127 struct _gaim_gtk_blist_node { |
| 128 GtkTreeRowReference *row; | |
| 7620 | 129 gboolean contact_expanded; |
| 11910 | 130 gboolean recent_signonoff; |
| 131 gint recent_signonoff_timer; | |
| 5256 | 132 }; |
| 133 | |
|
10968
e0d5038fbb7e
[gaim-migrate @ 12789]
Christopher O'Brien <siege@pidgin.im>
parents:
10924
diff
changeset
|
134 |
| 10118 | 135 static char dim_grey_string[8] = ""; |
| 10144 | 136 static char *dim_grey() |
| 10118 | 137 { |
| 138 if (!gtkblist) | |
| 139 return "dim grey"; | |
| 140 if (!dim_grey_string[0]) { | |
| 141 GtkStyle *style = gtk_widget_get_style(gtkblist->treeview); | |
| 142 snprintf(dim_grey_string, sizeof(dim_grey_string), "#%02x%02x%02x", | |
| 143 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
| 144 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
| 145 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | |
| 146 } | |
| 147 return dim_grey_string; | |
| 148 } | |
| 10144 | 149 |
| 5228 | 150 /*************************************************** |
| 151 * Callbacks * | |
| 152 ***************************************************/ | |
| 153 | |
| 154 static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) | |
| 155 { | |
|
11709
cae2fb7e8594
[gaim-migrate @ 14000]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11692
diff
changeset
|
156 gaim_core_quit(); |
| 5228 | 157 |
| 158 /* we handle everything, event should not propogate further */ | |
| 159 return TRUE; | |
| 160 } | |
| 161 | |
| 162 static gboolean gtk_blist_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) | |
| 163 { | |
| 164 /* unfortunately GdkEventConfigure ignores the window gravity, but * | |
| 165 * the only way we have of setting the position doesn't. we have to * | |
| 7620 | 166 * call get_position because it does pay attention to the gravity. * |
| 167 * this is inefficient and I agree it sucks, but it's more likely * | |
| 168 * to work correctly. - Robot101 */ | |
| 5228 | 169 gint x, y; |
| 170 | |
| 171 /* check for visibility because when we aren't visible, this will * | |
| 172 * give us bogus (0,0) coordinates. - xOr */ | |
| 7620 | 173 if (GTK_WIDGET_VISIBLE(w)) |
| 5228 | 174 gtk_window_get_position(GTK_WINDOW(w), &x, &y); |
| 7620 | 175 else |
| 176 return FALSE; /* carry on normally */ | |
| 177 | |
| 178 /* don't save if nothing changed */ | |
| 179 if (x == gaim_prefs_get_int("/gaim/gtk/blist/x") && | |
| 180 y == gaim_prefs_get_int("/gaim/gtk/blist/y") && | |
| 181 event->width == gaim_prefs_get_int("/gaim/gtk/blist/width") && | |
| 182 event->height == gaim_prefs_get_int("/gaim/gtk/blist/height")) { | |
| 183 | |
| 184 return FALSE; /* carry on normally */ | |
| 5228 | 185 } |
| 186 | |
| 7620 | 187 /* don't save off-screen positioning */ |
| 188 if (x + event->width < 0 || | |
| 9811 | 189 y + event->height < 0 || |
| 190 x > gdk_screen_width() || | |
| 191 y > gdk_screen_height()) { | |
| 7620 | 192 |
| 193 return FALSE; /* carry on normally */ | |
| 194 } | |
| 195 | |
| 196 /* store the position */ | |
| 197 gaim_prefs_set_int("/gaim/gtk/blist/x", x); | |
| 198 gaim_prefs_set_int("/gaim/gtk/blist/y", y); | |
| 199 gaim_prefs_set_int("/gaim/gtk/blist/width", event->width); | |
| 200 gaim_prefs_set_int("/gaim/gtk/blist/height", event->height); | |
| 201 | |
| 5228 | 202 /* continue to handle event normally */ |
| 203 return FALSE; | |
| 204 } | |
| 205 | |
| 7620 | 206 static void gtk_blist_menu_info_cb(GtkWidget *w, GaimBuddy *b) |
| 5228 | 207 { |
| 208 serv_get_info(b->account->gc, b->name); | |
| 209 } | |
| 210 | |
| 7620 | 211 static void gtk_blist_menu_im_cb(GtkWidget *w, GaimBuddy *b) |
| 5228 | 212 { |
| 9728 | 213 gaim_gtkdialogs_im_with_user(b->account, b->name); |
| 5228 | 214 } |
| 215 | |
| 9466 | 216 static void gtk_blist_menu_send_file_cb(GtkWidget *w, GaimBuddy *b) |
| 217 { | |
| 218 serv_send_file(b->account->gc, b->name, NULL); | |
| 219 } | |
| 220 | |
| 7620 | 221 static void gtk_blist_menu_autojoin_cb(GtkWidget *w, GaimChat *chat) |
| 222 { | |
| 7693 | 223 gaim_blist_node_set_bool((GaimBlistNode*)chat, "gtk-autojoin", |
| 224 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))); | |
| 7620 | 225 } |
| 226 | |
| 227 static void gtk_blist_menu_join_cb(GtkWidget *w, GaimChat *chat) | |
| 5228 | 228 { |
| 5234 | 229 serv_join_chat(chat->account->gc, chat->components); |
| 230 } | |
| 231 | |
| 11016 | 232 static void gtk_blist_renderer_edited_cb(GtkCellRendererText *text_rend, char *arg1, |
| 233 char *arg2, gpointer nada) | |
| 234 { | |
| 235 GtkTreeIter iter; | |
| 236 GtkTreePath *path; | |
| 237 GValue val = {0,}; | |
| 238 GaimBlistNode *node; | |
| 239 | |
| 240 path = gtk_tree_path_new_from_string (arg1); | |
| 241 gtk_tree_model_get_iter (GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
| 242 gtk_tree_path_free (path); | |
| 243 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
| 244 node = g_value_get_pointer(&val); | |
| 245 gtk_tree_view_set_enable_search (GTK_TREE_VIEW(gtkblist->treeview), TRUE); | |
| 246 g_object_set(G_OBJECT(gtkblist->text_rend), "editable", FALSE, NULL); | |
| 247 switch (node->type){ | |
| 248 case GAIM_BLIST_CONTACT_NODE: | |
| 249 gaim_blist_alias_buddy(gaim_contact_get_priority_buddy((GaimContact*)node), arg2); | |
| 250 break; | |
| 251 case GAIM_BLIST_BUDDY_NODE: | |
| 252 gaim_blist_alias_buddy((GaimBuddy*)node, arg2); | |
| 253 break; | |
| 254 case GAIM_BLIST_GROUP_NODE: | |
| 255 gaim_blist_rename_group((GaimGroup*)node, arg2); | |
| 256 break; | |
| 257 case GAIM_BLIST_CHAT_NODE: | |
| 258 gaim_blist_alias_chat((GaimChat*)node, arg2); | |
| 259 break; | |
| 260 default: | |
| 261 break; | |
| 262 } | |
| 263 } | |
| 264 | |
| 5234 | 265 static void gtk_blist_menu_alias_cb(GtkWidget *w, GaimBlistNode *node) |
| 266 { | |
| 11016 | 267 GtkTreeIter iter; |
| 268 GtkTreePath *path; | |
| 11258 | 269 const char *text = NULL; |
| 11494 | 270 |
| 11258 | 271 if (!(get_iter_from_node(node, &iter))) { |
| 11016 | 272 /* This is either a bug, or the buddy is in a collapsed contact */ |
| 273 node = node->parent; | |
| 274 if (!get_iter_from_node(node, &iter)) | |
| 275 /* Now it's definitely a bug */ | |
| 276 return; | |
| 277 } | |
| 11258 | 278 |
| 279 switch (node->type) { | |
| 280 case GAIM_BLIST_BUDDY_NODE: | |
| 281 text = gaim_buddy_get_alias((GaimBuddy *)node); | |
| 282 break; | |
| 283 case GAIM_BLIST_CONTACT_NODE: | |
| 284 text = gaim_buddy_get_alias(gaim_contact_get_priority_buddy((GaimContact *)node)); | |
| 285 break; | |
| 286 case GAIM_BLIST_GROUP_NODE: | |
| 287 text = ((GaimGroup *)node)->name; | |
| 288 break; | |
| 289 case GAIM_BLIST_CHAT_NODE: | |
| 290 text = gaim_chat_get_name((GaimChat *)node); | |
| 291 break; | |
| 292 default: | |
| 293 g_return_if_reached(); | |
| 294 } | |
| 295 | |
| 296 gtk_tree_store_set(gtkblist->treemodel, &iter, NAME_COLUMN, text, -1); | |
| 297 | |
| 11016 | 298 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); |
| 299 g_object_set(G_OBJECT(gtkblist->text_rend), "editable", TRUE, NULL); | |
| 300 gtk_tree_view_set_enable_search (GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
| 301 gtk_widget_grab_focus(gtkblist->treeview); | |
| 302 gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtkblist->treeview), path, gtkblist->text_column, TRUE); | |
| 303 gtk_tree_path_free(path); | |
| 5228 | 304 } |
| 305 | |
| 7620 | 306 static void gtk_blist_menu_bp_cb(GtkWidget *w, GaimBuddy *b) |
| 5228 | 307 { |
| 7620 | 308 gaim_gtkpounce_dialog_show(b->account, b->name, NULL); |
| 5228 | 309 } |
| 310 | |
| 9917 | 311 static void gtk_blist_menu_showlog_cb(GtkWidget *w, GaimBlistNode *node) |
| 5228 | 312 { |
| 9917 | 313 GaimLogType type; |
| 314 GaimAccount *account; | |
| 315 char *name = NULL; | |
| 10663 | 316 |
| 9917 | 317 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
| 318 GaimBuddy *b = (GaimBuddy*) node; | |
| 319 type = GAIM_LOG_IM; | |
| 320 name = g_strdup(b->name); | |
| 321 account = b->account; | |
| 322 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { | |
| 323 GaimChat *c = (GaimChat*) node; | |
| 324 GaimPluginProtocolInfo *prpl_info = NULL; | |
| 325 type = GAIM_LOG_CHAT; | |
| 326 account = c->account; | |
| 327 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gaim_find_prpl(gaim_account_get_protocol_id(account))); | |
| 328 if (prpl_info && prpl_info->get_chat_name) { | |
| 329 name = prpl_info->get_chat_name(c->components); | |
| 330 } | |
| 10663 | 331 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { |
| 332 gaim_gtk_log_show_contact((GaimContact *)node); | |
| 333 return; | |
| 9917 | 334 } else |
| 335 return; | |
| 336 | |
| 337 if (name && account) { | |
| 338 gaim_gtk_log_show(type, name, account); | |
| 339 g_free(name); | |
| 340 } | |
| 7620 | 341 } |
| 342 | |
| 5228 | 343 static void gtk_blist_show_systemlog_cb() |
| 344 { | |
| 8573 | 345 gaim_gtk_syslog_show(); |
| 5228 | 346 } |
| 347 | |
| 348 static void gtk_blist_show_onlinehelp_cb() | |
| 349 { | |
|
10240
95ca0db2d01d
[gaim-migrate @ 11377]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
10229
diff
changeset
|
350 gaim_notify_uri(NULL, GAIM_WEBSITE "documentation.php"); |
| 5228 | 351 } |
| 352 | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
353 static void |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
354 do_join_chat(GaimGtkJoinChatData *data) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
355 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
356 if (data) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
357 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
358 GHashTable *components = |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
359 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
360 GList *tmp; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
361 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
362 for (tmp = data->entries; tmp != NULL; tmp = tmp->next) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
363 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
364 if (g_object_get_data(tmp->data, "is_spin")) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
365 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
366 g_hash_table_replace(components, |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
367 g_strdup(g_object_get_data(tmp->data, "identifier")), |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
368 g_strdup_printf("%d", |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
369 gtk_spin_button_get_value_as_int(tmp->data))); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
370 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
371 else |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
372 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
373 g_hash_table_replace(components, |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
374 g_strdup(g_object_get_data(tmp->data, "identifier")), |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
375 g_strdup(gtk_entry_get_text(tmp->data))); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
376 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
377 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
378 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
379 serv_join_chat(gaim_account_get_connection(data->account), components); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
380 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
381 g_hash_table_destroy(components); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
382 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
383 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
384 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
385 static void |
| 8940 | 386 do_joinchat(GtkWidget *dialog, int id, GaimGtkJoinChatData *info) |
| 387 { | |
| 388 switch(id) | |
| 389 { | |
| 390 case GTK_RESPONSE_OK: | |
| 391 do_join_chat(info); | |
| 392 | |
| 393 break; | |
| 394 } | |
| 395 | |
| 396 gtk_widget_destroy(GTK_WIDGET(dialog)); | |
| 397 g_list_free(info->entries); | |
| 398 g_free(info); | |
| 399 } | |
| 400 | |
| 10475 | 401 /* |
| 402 * Check the values of all the text entry boxes. If any required input | |
| 403 * strings are empty then don't allow the user to click on "OK." | |
| 404 */ | |
| 405 static void | |
| 406 joinchat_set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data) | |
| 407 { | |
| 408 GaimGtkJoinChatData *data; | |
| 409 GList *tmp; | |
| 410 const char *text; | |
| 411 gboolean required; | |
| 412 gboolean sensitive = TRUE; | |
| 413 | |
| 414 data = user_data; | |
| 415 | |
| 416 for (tmp = data->entries; tmp != NULL; tmp = tmp->next) | |
| 417 { | |
| 418 if (!g_object_get_data(tmp->data, "is_spin")) | |
| 419 { | |
| 420 required = GPOINTER_TO_INT(g_object_get_data(tmp->data, "required")); | |
| 421 text = gtk_entry_get_text(tmp->data); | |
| 422 if (required && (*text == '\0')) | |
| 423 sensitive = FALSE; | |
| 424 } | |
| 425 } | |
| 426 | |
| 427 gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_OK, sensitive); | |
| 428 } | |
| 429 | |
| 8940 | 430 static void |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
431 rebuild_joinchat_entries(GaimGtkJoinChatData *data) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
432 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
433 GaimConnection *gc; |
| 9959 | 434 GList *list = NULL, *tmp = NULL; |
| 9770 | 435 GHashTable *defaults = NULL; |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
436 struct proto_chat_entry *pce; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
437 gboolean focus = TRUE; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
438 |
| 10127 | 439 g_return_if_fail(data->account != NULL); |
| 440 | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
441 gc = gaim_account_get_connection(data->account); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
442 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
443 while (GTK_BOX(data->entries_box)->children) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
444 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
445 gtk_container_remove(GTK_CONTAINER(data->entries_box), |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
446 ((GtkBoxChild *)GTK_BOX(data->entries_box)->children->data)->widget); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
447 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
448 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
449 if (data->entries != NULL) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
450 g_list_free(data->entries); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
451 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
452 data->entries = NULL; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
453 |
| 9987 | 454 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) |
| 9959 | 455 list = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
456 |
| 9770 | 457 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) |
| 458 defaults = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, NULL); | |
| 459 | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
460 for (tmp = list; tmp; tmp = tmp->next) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
461 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
462 GtkWidget *label; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
463 GtkWidget *rowbox; |
| 10475 | 464 GtkWidget *input; |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
465 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
466 pce = tmp->data; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
467 |
| 11243 | 468 rowbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
469 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
470 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
471 label = gtk_label_new_with_mnemonic(pce->label); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
472 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
473 gtk_size_group_add_widget(data->sg, label); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
474 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
475 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
476 if (pce->is_int) |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
477 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
478 GtkObject *adjust; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
479 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
480 1, 10, 10); |
| 10475 | 481 input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); |
| 482 gtk_widget_set_size_request(input, 50, -1); | |
| 483 gtk_box_pack_end(GTK_BOX(rowbox), input, FALSE, FALSE, 0); | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
484 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
485 else |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
486 { |
| 9770 | 487 char *value; |
| 10475 | 488 input = gtk_entry_new(); |
| 489 gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE); | |
| 9770 | 490 value = g_hash_table_lookup(defaults, pce->identifier); |
| 491 if (value != NULL) | |
| 10475 | 492 gtk_entry_set_text(GTK_ENTRY(input), value); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
493 if (pce->secret) |
| 11986 | 494 { |
| 10475 | 495 gtk_entry_set_visibility(GTK_ENTRY(input), FALSE); |
| 11986 | 496 gtk_entry_set_invisible_char(GTK_ENTRY(input), GAIM_INVISIBLE_CHAR); |
| 497 } | |
| 10475 | 498 gtk_box_pack_end(GTK_BOX(rowbox), input, TRUE, TRUE, 0); |
| 499 g_signal_connect(G_OBJECT(input), "changed", | |
| 500 G_CALLBACK(joinchat_set_sensitive_if_input_cb), data); | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
501 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
502 |
| 10475 | 503 /* Do the following for any type of input widget */ |
| 504 if (focus) | |
| 505 { | |
| 506 gtk_widget_grab_focus(input); | |
| 507 focus = FALSE; | |
| 508 } | |
| 509 gtk_label_set_mnemonic_widget(GTK_LABEL(label), input); | |
| 510 gaim_set_accessible_label(input, label); | |
| 511 g_object_set_data(G_OBJECT(input), "identifier", pce->identifier); | |
| 512 g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int)); | |
| 513 g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required)); | |
| 514 data->entries = g_list_append(data->entries, input); | |
| 515 | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
516 g_free(pce); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
517 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
518 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
519 g_list_free(list); |
| 10475 | 520 g_hash_table_destroy(defaults); |
| 521 | |
| 522 /* Set whether the "OK" button should be clickable initially */ | |
| 523 joinchat_set_sensitive_if_input_cb(NULL, data); | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
524 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
525 gtk_widget_show_all(data->entries_box); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
526 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
527 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
528 static void |
| 8940 | 529 joinchat_select_account_cb(GObject *w, GaimAccount *account, |
| 10475 | 530 GaimGtkJoinChatData *data) |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
531 { |
| 9460 | 532 if (strcmp(gaim_account_get_protocol_id(data->account), |
| 10475 | 533 gaim_account_get_protocol_id(account)) == 0) |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
534 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
535 data->account = account; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
536 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
537 else |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
538 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
539 data->account = account; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
540 rebuild_joinchat_entries(data); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
541 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
542 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
543 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
544 static gboolean |
| 9987 | 545 chat_account_filter_func(GaimAccount *account) |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
546 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
547 GaimConnection *gc = gaim_account_get_connection(account); |
| 8940 | 548 GaimPluginProtocolInfo *prpl_info = NULL; |
| 549 | |
| 550 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
| 551 | |
| 552 return (prpl_info->chat_info != NULL); | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
553 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
554 |
| 8940 | 555 gboolean |
| 556 gaim_gtk_blist_joinchat_is_showable() | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
557 { |
| 8940 | 558 GList *c; |
| 559 GaimConnection *gc; | |
| 560 | |
| 561 for (c = gaim_connections_get_all(); c != NULL; c = c->next) { | |
| 562 gc = c->data; | |
| 563 | |
| 9987 | 564 if (chat_account_filter_func(gaim_connection_get_account(gc))) |
| 8940 | 565 return TRUE; |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
566 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
567 |
| 8940 | 568 return FALSE; |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
569 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
570 |
|
8305
57bdd25752c1
[gaim-migrate @ 9029]
Christian Hammond <chipx86@chipx86.com>
parents:
8303
diff
changeset
|
571 void |
| 8940 | 572 gaim_gtk_blist_joinchat_show(void) |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
573 { |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
574 GtkWidget *hbox, *vbox; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
575 GtkWidget *rowbox; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
576 GtkWidget *label; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
577 GaimGtkBuddyList *gtkblist; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
578 GtkWidget *img = NULL; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
579 GaimGtkJoinChatData *data = NULL; |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
580 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
581 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
582 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
583 GTK_ICON_SIZE_DIALOG); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
584 data = g_new0(GaimGtkJoinChatData, 1); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
585 |
| 8975 | 586 data->window = gtk_dialog_new_with_buttons(_("Join a Chat"), |
| 587 NULL, GTK_DIALOG_NO_SEPARATOR, | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
588 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
| 8308 | 589 GAIM_STOCK_CHAT, GTK_RESPONSE_OK, NULL); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
590 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); |
| 11243 | 591 gtk_container_set_border_width(GTK_CONTAINER(data->window), GAIM_HIG_BOX_SPACE); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
592 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); |
| 11243 | 593 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BORDER); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
594 gtk_container_set_border_width( |
| 11243 | 595 GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BOX_SPACE); |
| 8975 | 596 gtk_window_set_role(GTK_WINDOW(data->window), "join_chat"); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
597 |
| 11243 | 598 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
599 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
600 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
601 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
602 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
603 vbox = gtk_vbox_new(FALSE, 5); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
604 gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
605 gtk_container_add(GTK_CONTAINER(hbox), vbox); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
606 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
607 label = gtk_label_new(_("Please enter the appropriate information " |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
608 "about the chat you would like to join.\n")); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
609 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
610 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
611 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
612 |
| 11243 | 613 rowbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
614 gtk_box_pack_start(GTK_BOX(vbox), rowbox, TRUE, TRUE, 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
615 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
616 data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
617 |
| 8940 | 618 label = gtk_label_new_with_mnemonic(_("_Account:")); |
| 619 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 620 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
| 621 gtk_size_group_add_widget(data->sg, label); | |
| 622 | |
| 623 data->account_menu = gaim_gtk_account_option_menu_new(NULL, FALSE, | |
| 624 G_CALLBACK(joinchat_select_account_cb), | |
| 9987 | 625 chat_account_filter_func, data); |
| 8940 | 626 gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0); |
| 627 gtk_label_set_mnemonic_widget(GTK_LABEL(label), | |
| 628 GTK_WIDGET(data->account_menu)); | |
| 629 gaim_set_accessible_label (data->account_menu, label); | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
630 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
631 data->entries_box = gtk_vbox_new(FALSE, 5); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
632 gtk_container_add(GTK_CONTAINER(vbox), data->entries_box); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
633 gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
634 |
| 8940 | 635 data->account = gaim_gtk_account_option_menu_get_selected(data->account_menu); |
| 636 | |
|
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
637 rebuild_joinchat_entries(data); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
638 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
639 g_signal_connect(G_OBJECT(data->window), "response", |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
640 G_CALLBACK(do_joinchat), data); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
641 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
642 g_object_unref(data->sg); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
643 |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
644 gtk_widget_show_all(data->window); |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
645 } |
|
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
646 |
| 5228 | 647 static void gtk_blist_row_expanded_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { |
| 648 GaimBlistNode *node; | |
| 649 GValue val = {0,}; | |
| 650 | |
| 651 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val); | |
| 652 | |
| 653 node = g_value_get_pointer(&val); | |
| 654 | |
| 655 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
| 7693 | 656 gaim_blist_node_set_bool(node, "collapsed", FALSE); |
| 5228 | 657 } |
| 658 } | |
| 659 | |
| 660 static void gtk_blist_row_collapsed_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { | |
| 661 GaimBlistNode *node; | |
| 662 GValue val = {0,}; | |
| 663 | |
| 664 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val); | |
| 665 | |
| 666 node = g_value_get_pointer(&val); | |
| 667 | |
| 668 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
| 7693 | 669 gaim_blist_node_set_bool(node, "collapsed", TRUE); |
| 7620 | 670 } else if(GAIM_BLIST_NODE_IS_CONTACT(node)) { |
| 671 gaim_gtk_blist_collapse_contact_cb(NULL, node); | |
| 5228 | 672 } |
| 673 } | |
| 674 | |
| 675 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) { | |
| 676 GaimBlistNode *node; | |
| 677 GtkTreeIter iter; | |
| 678 GValue val = { 0, }; | |
| 679 | |
| 680 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
| 681 | |
| 682 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
| 683 node = g_value_get_pointer(&val); | |
| 684 | |
| 7620 | 685 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) { |
| 686 GaimBuddy *buddy; | |
| 687 | |
| 688 if(GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 689 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
| 690 else | |
| 691 buddy = (GaimBuddy*)node; | |
| 692 | |
| 9728 | 693 gaim_gtkdialogs_im_with_user(buddy->account, buddy->name); |
| 5234 | 694 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
| 7620 | 695 serv_join_chat(((GaimChat *)node)->account->gc, ((GaimChat *)node)->components); |
| 5228 | 696 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
| 697 if (gtk_tree_view_row_expanded(tv, path)) | |
| 698 gtk_tree_view_collapse_row(tv, path); | |
| 699 else | |
| 700 gtk_tree_view_expand_row(tv,path,FALSE); | |
| 701 } | |
| 702 } | |
| 703 | |
| 5234 | 704 static void gaim_gtk_blist_add_chat_cb() |
| 705 { | |
| 706 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
| 707 GtkTreeIter iter; | |
| 708 GaimBlistNode *node; | |
| 709 | |
| 710 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ | |
| 711 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
| 7620 | 712 if (GAIM_BLIST_NODE_IS_BUDDY(node)) |
| 9754 | 713 gaim_blist_request_add_chat(NULL, (GaimGroup*)node->parent->parent, NULL, NULL); |
| 7620 | 714 if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node)) |
| 9754 | 715 gaim_blist_request_add_chat(NULL, (GaimGroup*)node->parent, NULL, NULL); |
| 5234 | 716 else if (GAIM_BLIST_NODE_IS_GROUP(node)) |
| 9754 | 717 gaim_blist_request_add_chat(NULL, (GaimGroup*)node, NULL, NULL); |
| 5234 | 718 } |
| 719 else { | |
| 9754 | 720 gaim_blist_request_add_chat(NULL, NULL, NULL, NULL); |
| 5234 | 721 } |
| 722 } | |
| 723 | |
| 5228 | 724 static void gaim_gtk_blist_add_buddy_cb() |
| 725 { | |
| 726 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
| 727 GtkTreeIter iter; | |
| 728 GaimBlistNode *node; | |
| 729 | |
| 730 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ | |
| 731 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
| 7620 | 732 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
| 733 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node->parent->parent)->name, | |
| 734 NULL); | |
| 735 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) | |
| 736 || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
| 737 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node->parent)->name, NULL); | |
| 738 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
| 739 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node)->name, NULL); | |
| 740 } | |
| 5228 | 741 } |
| 742 else { | |
| 7620 | 743 gaim_blist_request_add_buddy(NULL, NULL, NULL, NULL); |
| 744 } | |
| 745 } | |
| 746 | |
| 747 static void | |
| 748 gaim_gtk_blist_remove_cb (GtkWidget *w, GaimBlistNode *node) | |
| 749 { | |
| 750 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
| 9730 | 751 gaim_gtkdialogs_remove_buddy((GaimBuddy*)node); |
| 7620 | 752 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
| 9730 | 753 gaim_gtkdialogs_remove_chat((GaimChat*)node); |
| 7620 | 754 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
| 9730 | 755 gaim_gtkdialogs_remove_group((GaimGroup*)node); |
| 7620 | 756 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { |
| 9730 | 757 gaim_gtkdialogs_remove_contact((GaimContact*)node); |
| 5228 | 758 } |
| 759 } | |
| 760 | |
| 761 static void | |
| 7620 | 762 gaim_gtk_blist_expand_contact_cb(GtkWidget *w, GaimBlistNode *node) |
| 5228 | 763 { |
| 7620 | 764 struct _gaim_gtk_blist_node *gtknode; |
| 9632 | 765 GtkTreeIter iter, parent; |
| 7620 | 766 GaimBlistNode *bnode; |
| 10325 | 767 GtkTreePath *path; |
| 7620 | 768 |
| 769 if(!GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 770 return; | |
| 771 | |
| 772 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
| 773 | |
| 774 gtknode->contact_expanded = TRUE; | |
| 775 | |
| 776 for(bnode = node->child; bnode; bnode = bnode->next) { | |
| 777 gaim_gtk_blist_update(NULL, bnode); | |
| 778 } | |
| 10353 | 779 |
| 9632 | 780 /* This ensures that the bottom buddy is visible, i.e. not scrolled off the alignment */ |
| 781 get_iter_from_node(node, &parent); | |
| 10353 | 782 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter, &parent, |
| 9811 | 783 gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &parent) -1); |
| 9632 | 784 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); |
| 785 /* Let the treeview draw so it knows where to scroll */ | |
| 786 while (gtk_events_pending()) | |
| 787 gtk_main_iteration(); | |
| 10353 | 788 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(gtkblist->treeview), path, NULL, FALSE, 0, 0); |
| 789 | |
| 9632 | 790 |
| 7620 | 791 gaim_gtk_blist_update(NULL, node); |
| 9632 | 792 gtk_tree_path_free(path); |
| 7620 | 793 } |
| 794 | |
| 795 static void | |
| 796 gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node) | |
| 797 { | |
| 798 GaimBlistNode *bnode; | |
| 799 struct _gaim_gtk_blist_node *gtknode; | |
| 800 | |
| 801 if(!GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 802 return; | |
| 803 | |
| 804 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
| 805 | |
| 806 gtknode->contact_expanded = FALSE; | |
| 807 | |
| 808 for(bnode = node->child; bnode; bnode = bnode->next) { | |
| 809 gaim_gtk_blist_update(NULL, bnode); | |
| 5228 | 810 } |
| 811 } | |
| 812 | |
| 9030 | 813 |
| 814 static void | |
| 815 blist_node_menu_cb(GtkMenuItem *item, GaimBlistNode *node) | |
| 816 { | |
| 11638 | 817 void (*callback)(GaimBlistNode *, gpointer); |
| 818 gpointer data; | |
| 819 callback = g_object_get_data(G_OBJECT(item), "gaimcallback"); | |
| 820 data = g_object_get_data(G_OBJECT(item), "gaimcallbackdata"); | |
| 821 if (callback) | |
| 822 callback(node, data); | |
| 9030 | 823 } |
| 824 | |
| 825 | |
| 826 static void | |
|
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
827 append_blist_node_action(GtkWidget *menu, GaimBlistNodeAction *act, |
| 9030 | 828 GaimBlistNode *node, gboolean *dup_separator) |
| 5228 | 829 { |
| 9030 | 830 if(act == NULL) { |
| 831 if(! *dup_separator) { | |
| 832 gaim_separator(menu); | |
| 833 *dup_separator = TRUE; | |
| 834 } | |
| 835 } else { | |
| 836 GtkWidget *menuitem; | |
| 837 | |
|
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
838 if (act->children == NULL) { |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
839 *dup_separator = FALSE; |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
840 |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
841 menuitem = gtk_menu_item_new_with_mnemonic(act->label); |
|
11038
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
842 if (act->callback != NULL) { |
|
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
843 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", |
| 11638 | 844 act->callback); |
| 845 g_object_set_data(G_OBJECT(menuitem), "gaimcallbackdata", | |
| 846 act->data); | |
|
11038
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
847 g_signal_connect(G_OBJECT(menuitem), "activate", |
|
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
848 G_CALLBACK(blist_node_menu_cb), node); |
|
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
849 } else { |
|
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
850 gtk_widget_set_sensitive(menuitem, FALSE); |
|
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
851 } |
|
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
852 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
853 } else { |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
854 GtkWidget *submenu = NULL; |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
855 GList *l = NULL; |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
856 |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
857 menuitem = gtk_menu_item_new_with_mnemonic(act->label); |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
858 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
859 |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
860 submenu = gtk_menu_new(); |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
861 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
862 |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
863 for (l = act->children; l; l = l->next) { |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
864 GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
865 |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
866 append_blist_node_action(submenu, act, node, dup_separator); |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
867 } |
| 11638 | 868 g_list_free(act->children); |
| 869 act->children = NULL; | |
|
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
870 } |
| 11638 | 871 g_free(act); |
| 9030 | 872 } |
| 5228 | 873 } |
| 874 | |
| 9030 | 875 |
| 9051 | 876 void |
|
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
877 gaim_gtk_append_blist_node_proto_menu(GtkWidget *menu, GaimConnection *gc, |
|
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
878 GaimBlistNode *node) |
| 9030 | 879 { |
| 880 GList *l, *ll; | |
| 881 gboolean dup_separator = FALSE; | |
| 882 GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
| 883 | |
| 884 if(!prpl_info || !prpl_info->blist_node_menu) | |
| 885 return; | |
| 886 | |
| 887 for(l = ll = prpl_info->blist_node_menu(node); l; l = l->next) { | |
| 888 GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; | |
| 889 append_blist_node_action(menu, act, node, &dup_separator); | |
| 890 } | |
| 891 g_list_free(ll); | |
| 892 } | |
| 893 | |
| 894 | |
| 9051 | 895 void |
| 896 gaim_gtk_append_blist_node_extended_menu (GtkWidget *menu, GaimBlistNode *node) | |
| 9030 | 897 { |
| 898 GList *l, *ll; | |
| 899 gboolean dup_separator = FALSE; | |
| 900 | |
| 901 for(l = ll = gaim_blist_node_get_extended_menu(node); l; l = l->next) { | |
| 902 GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; | |
| 903 append_blist_node_action(menu, act, node, &dup_separator); | |
| 904 } | |
| 905 g_list_free(ll); | |
| 906 } | |
| 907 | |
| 908 | |
| 9774 | 909 void |
| 10484 | 910 gaim_gtk_blist_make_buddy_menu(GtkWidget *menu, GaimBuddy *buddy, gboolean sub) { |
| 9774 | 911 GaimPluginProtocolInfo *prpl_info; |
| 10663 | 912 GaimContact *contact; |
| 913 gboolean contact_expanded = FALSE; | |
| 9774 | 914 |
| 915 g_return_if_fail(menu); | |
| 916 g_return_if_fail(buddy); | |
| 917 | |
| 918 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(buddy->account->gc->prpl); | |
| 919 | |
| 10663 | 920 contact = gaim_buddy_get_contact(buddy); |
| 921 if (contact) { | |
| 922 contact_expanded = ((struct _gaim_gtk_blist_node *)(((GaimBlistNode*)contact)->ui_data))->contact_expanded; | |
| 923 } | |
| 924 | |
| 7620 | 925 if (prpl_info && prpl_info->get_info) { |
| 8137 | 926 gaim_new_item_from_stock(menu, _("Get _Info"), GAIM_STOCK_INFO, |
| 9774 | 927 G_CALLBACK(gtk_blist_menu_info_cb), buddy, 0, 0, NULL); |
| 7620 | 928 } |
| 8137 | 929 gaim_new_item_from_stock(menu, _("I_M"), GAIM_STOCK_IM, |
| 9774 | 930 G_CALLBACK(gtk_blist_menu_im_cb), buddy, 0, 0, NULL); |
| 9466 | 931 if (prpl_info && prpl_info->send_file) { |
| 9774 | 932 if (!prpl_info->can_receive_file || |
| 933 prpl_info->can_receive_file(buddy->account->gc, buddy->name)) | |
| 934 { | |
| 935 gaim_new_item_from_stock(menu, _("_Send File"), | |
| 936 GAIM_STOCK_FILE_TRANSFER, | |
| 937 G_CALLBACK(gtk_blist_menu_send_file_cb), | |
| 938 buddy, 0, 0, NULL); | |
| 9466 | 939 } |
| 940 } | |
| 7620 | 941 gaim_new_item_from_stock(menu, _("Add Buddy _Pounce"), NULL, |
| 9774 | 942 G_CALLBACK(gtk_blist_menu_bp_cb), buddy, 0, 0, NULL); |
| 10663 | 943 |
| 944 if(((GaimBlistNode*)buddy)->parent->child->next && !sub && !contact_expanded) { | |
| 945 gaim_new_item_from_stock(menu, _("View _Log"), NULL, | |
| 946 G_CALLBACK(gtk_blist_menu_showlog_cb), | |
| 947 contact, 0, 0, NULL); | |
| 948 } else if (!sub) { | |
| 949 gaim_new_item_from_stock(menu, _("View _Log"), NULL, | |
| 950 G_CALLBACK(gtk_blist_menu_showlog_cb), buddy, 0, 0, NULL); | |
| 951 } | |
| 9774 | 952 |
| 953 gaim_gtk_append_blist_node_proto_menu(menu, buddy->account->gc, | |
| 954 (GaimBlistNode *)buddy); | |
| 955 gaim_gtk_append_blist_node_extended_menu(menu, (GaimBlistNode *)buddy); | |
| 7620 | 956 |
| 957 gaim_separator(menu); | |
| 9030 | 958 |
| 10663 | 959 if(((GaimBlistNode*)buddy)->parent->child->next && !sub && !contact_expanded) { |
| 9925 | 960 gaim_new_item_from_stock(menu, _("_Alias Buddy..."), GAIM_STOCK_ALIAS, |
| 961 G_CALLBACK(gtk_blist_menu_alias_cb), buddy, 0, 0, NULL); | |
| 962 gaim_new_item_from_stock(menu, _("_Remove Buddy"), GTK_STOCK_REMOVE, | |
| 963 G_CALLBACK(gaim_gtk_blist_remove_cb), buddy, 0, 0, NULL); | |
| 964 gaim_new_item_from_stock(menu, _("Alias Contact..."), GAIM_STOCK_ALIAS, | |
| 965 G_CALLBACK(gtk_blist_menu_alias_cb), | |
| 10663 | 966 contact, 0, 0, NULL); |
| 9925 | 967 gaim_new_item_from_stock(menu, _("Remove Contact"), GTK_STOCK_REMOVE, |
| 968 G_CALLBACK(gaim_gtk_blist_remove_cb), | |
| 10663 | 969 contact, 0, 0, NULL); |
| 9925 | 970 } else { |
| 971 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, | |
| 972 G_CALLBACK(gtk_blist_menu_alias_cb), buddy, 0, 0, NULL); | |
| 973 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, | |
| 974 G_CALLBACK(gaim_gtk_blist_remove_cb), buddy, | |
| 975 0, 0, NULL); | |
| 976 } | |
| 7620 | 977 } |
| 978 | |
| 9774 | 979 static gboolean |
| 980 gtk_blist_key_press_cb(GtkWidget *tv, GdkEventKey *event, gpointer data) { | |
| 7620 | 981 GaimBlistNode *node; |
| 982 GValue val = { 0, }; | |
| 983 GtkTreeIter iter; | |
| 984 GtkTreeSelection *sel; | |
| 985 | |
| 986 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
| 987 if(!gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
| 988 return FALSE; | |
| 989 | |
| 990 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
| 991 NODE_COLUMN, &val); | |
| 992 node = g_value_get_pointer(&val); | |
| 993 | |
| 994 if(event->state & GDK_CONTROL_MASK && | |
| 995 (event->keyval == 'o' || event->keyval == 'O')) { | |
| 996 GaimBuddy *buddy; | |
| 997 | |
| 998 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
| 999 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
| 1000 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
| 1001 buddy = (GaimBuddy*)node; | |
| 1002 } else { | |
| 1003 return FALSE; | |
| 1004 } | |
| 1005 if(buddy) | |
| 1006 serv_get_info(buddy->account->gc, buddy->name); | |
| 1007 } | |
| 1008 | |
| 1009 return FALSE; | |
| 1010 } | |
| 1011 | |
| 9013 | 1012 |
| 8143 | 1013 static GtkWidget * |
| 8952 | 1014 create_group_menu (GaimBlistNode *node, GaimGroup *g) |
| 8143 | 1015 { |
| 1016 GtkWidget *menu; | |
| 1017 | |
| 1018 menu = gtk_menu_new(); | |
| 1019 gaim_new_item_from_stock(menu, _("Add a _Buddy"), GTK_STOCK_ADD, | |
| 1020 G_CALLBACK(gaim_gtk_blist_add_buddy_cb), node, 0, 0, NULL); | |
| 1021 gaim_new_item_from_stock(menu, _("Add a C_hat"), GTK_STOCK_ADD, | |
| 1022 G_CALLBACK(gaim_gtk_blist_add_chat_cb), node, 0, 0, NULL); | |
| 1023 gaim_new_item_from_stock(menu, _("_Delete Group"), GTK_STOCK_REMOVE, | |
| 1024 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
| 1025 gaim_new_item_from_stock(menu, _("_Rename"), NULL, | |
| 11016 | 1026 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
| 8952 | 1027 |
| 9051 | 1028 gaim_gtk_append_blist_node_extended_menu(menu, node); |
| 8952 | 1029 |
| 8143 | 1030 return menu; |
| 1031 } | |
| 1032 | |
| 8586 | 1033 |
| 8143 | 1034 static GtkWidget * |
| 9774 | 1035 create_chat_menu(GaimBlistNode *node, GaimChat *c) { |
| 8143 | 1036 GtkWidget *menu; |
| 9030 | 1037 gboolean autojoin; |
| 8143 | 1038 |
| 1039 menu = gtk_menu_new(); | |
| 9030 | 1040 autojoin = (gaim_blist_node_get_bool(node, "gtk-autojoin") || |
| 1041 (gaim_blist_node_get_string(node, "gtk-autojoin") != NULL)); | |
| 1042 | |
| 8143 | 1043 gaim_new_item_from_stock(menu, _("_Join"), GAIM_STOCK_CHAT, |
| 9030 | 1044 G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL); |
| 8143 | 1045 gaim_new_check_item(menu, _("Auto-Join"), |
| 9030 | 1046 G_CALLBACK(gtk_blist_menu_autojoin_cb), node, autojoin); |
| 9917 | 1047 gaim_new_item_from_stock(menu, _("View _Log"), NULL, |
| 1048 G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL); | |
| 9030 | 1049 |
| 9051 | 1050 gaim_gtk_append_blist_node_proto_menu(menu, c->account->gc, node); |
| 1051 gaim_gtk_append_blist_node_extended_menu(menu, node); | |
| 8586 | 1052 |
| 1053 gaim_separator(menu); | |
| 9030 | 1054 |
|
8302
462ead6fc1a0
[gaim-migrate @ 9026]
Christian Hammond <chipx86@chipx86.com>
parents:
8259
diff
changeset
|
1055 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, |
| 8143 | 1056 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
| 1057 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, | |
| 1058 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
| 8586 | 1059 |
| 8143 | 1060 return menu; |
| 1061 } | |
| 1062 | |
| 1063 static GtkWidget * | |
| 1064 create_contact_menu (GaimBlistNode *node) | |
| 1065 { | |
| 1066 GtkWidget *menu; | |
| 1067 | |
| 1068 menu = gtk_menu_new(); | |
| 10663 | 1069 |
| 1070 gaim_new_item_from_stock(menu, _("View _Log"), NULL, | |
| 1071 G_CALLBACK(gtk_blist_menu_showlog_cb), | |
| 1072 node, 0, 0, NULL); | |
| 1073 | |
| 1074 gaim_separator(menu); | |
| 1075 | |
|
8302
462ead6fc1a0
[gaim-migrate @ 9026]
Christian Hammond <chipx86@chipx86.com>
parents:
8259
diff
changeset
|
1076 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, |
| 8143 | 1077 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
| 10663 | 1078 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, |
| 1079 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
| 1080 | |
| 1081 gaim_separator(menu); | |
| 1082 | |
| 8143 | 1083 gaim_new_item_from_stock(menu, _("_Collapse"), GTK_STOCK_ZOOM_OUT, |
| 1084 G_CALLBACK(gaim_gtk_blist_collapse_contact_cb), | |
| 1085 node, 0, 0, NULL); | |
| 9051 | 1086 |
| 1087 gaim_gtk_append_blist_node_extended_menu(menu, node); | |
| 1088 | |
| 8143 | 1089 return menu; |
| 1090 } | |
| 1091 | |
| 1092 static GtkWidget * | |
| 9774 | 1093 create_buddy_menu(GaimBlistNode *node, GaimBuddy *b) { |
| 8143 | 1094 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; |
| 1095 GtkWidget *menu; | |
| 1096 GtkWidget *menuitem; | |
| 1097 gboolean show_offline = gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies"); | |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1098 |
| 8143 | 1099 menu = gtk_menu_new(); |
| 10484 | 1100 gaim_gtk_blist_make_buddy_menu(menu, b, FALSE); |
| 8143 | 1101 |
| 1102 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
| 1103 gaim_separator(menu); | |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1104 |
| 8143 | 1105 if(gtknode->contact_expanded) { |
| 1106 gaim_new_item_from_stock(menu, _("_Collapse"), | |
| 1107 GTK_STOCK_ZOOM_OUT, | |
| 1108 G_CALLBACK(gaim_gtk_blist_collapse_contact_cb), | |
| 1109 node, 0, 0, NULL); | |
| 1110 } else { | |
| 1111 gaim_new_item_from_stock(menu, _("_Expand"), | |
| 1112 GTK_STOCK_ZOOM_IN, | |
| 1113 G_CALLBACK(gaim_gtk_blist_expand_contact_cb), node, | |
| 1114 0, 0, NULL); | |
| 1115 } | |
| 1116 if(node->child->next) { | |
| 1117 GaimBlistNode *bnode; | |
| 1118 | |
| 1119 for(bnode = node->child; bnode; bnode = bnode->next) { | |
| 1120 GaimBuddy *buddy = (GaimBuddy*)bnode; | |
| 9340 | 1121 GdkPixbuf *buf; |
| 8143 | 1122 GtkWidget *submenu; |
| 1123 GtkWidget *image; | |
| 1124 | |
| 1125 if(buddy == b) | |
| 1126 continue; | |
| 1127 if(!buddy->account->gc) | |
| 1128 continue; | |
| 1129 if(!show_offline && !GAIM_BUDDY_IS_ONLINE(buddy)) | |
| 1130 continue; | |
| 1131 | |
| 1132 menuitem = gtk_image_menu_item_new_with_label(buddy->name); | |
| 9340 | 1133 buf = gaim_gtk_blist_get_status_icon(bnode, |
| 1134 GAIM_STATUS_ICON_SMALL); | |
| 1135 image = gtk_image_new_from_pixbuf(buf); | |
| 1136 g_object_unref(G_OBJECT(buf)); | |
| 8143 | 1137 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), |
| 9811 | 1138 image); |
| 8143 | 1139 gtk_widget_show(image); |
| 1140 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
| 1141 gtk_widget_show(menuitem); | |
| 1142 | |
| 1143 submenu = gtk_menu_new(); | |
| 1144 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
| 1145 gtk_widget_show(submenu); | |
| 1146 | |
| 10484 | 1147 gaim_gtk_blist_make_buddy_menu(submenu, buddy, TRUE); |
| 8143 | 1148 } |
| 1149 } | |
| 1150 } | |
| 1151 return menu; | |
| 1152 } | |
| 1153 | |
| 1154 static gboolean | |
| 1155 gaim_gtk_blist_show_context_menu(GaimBlistNode *node, | |
| 1156 GtkMenuPositionFunc func, | |
| 1157 GtkWidget *tv, | |
| 1158 guint button, | |
| 1159 guint32 time) | |
| 1160 { | |
| 1161 struct _gaim_gtk_blist_node *gtknode; | |
| 1162 GtkWidget *menu = NULL; | |
| 1163 gboolean handled = FALSE; | |
| 1164 | |
| 1165 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
| 1166 | |
| 1167 /* Create a menu based on the thing we right-clicked on */ | |
| 1168 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
| 8952 | 1169 GaimGroup *g = (GaimGroup *)node; |
| 9774 | 1170 |
| 8952 | 1171 menu = create_group_menu(node, g); |
| 8143 | 1172 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
| 8586 | 1173 GaimChat *c = (GaimChat *)node; |
| 9774 | 1174 |
| 1175 menu = create_chat_menu(node, c); | |
| 8143 | 1176 } else if ((GAIM_BLIST_NODE_IS_CONTACT(node)) && (gtknode->contact_expanded)) { |
| 1177 menu = create_contact_menu(node); | |
| 1178 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
| 1179 GaimBuddy *b; | |
| 1180 | |
| 1181 if (GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 1182 b = gaim_contact_get_priority_buddy((GaimContact*)node); | |
| 1183 else | |
| 1184 b = (GaimBuddy *)node; | |
| 1185 | |
| 9774 | 1186 menu = create_buddy_menu(node, b); |
| 8143 | 1187 } |
| 1188 | |
|
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1189 #ifdef _WIN32 |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1190 /* Unhook the tooltip-timeout since we don't want a tooltip |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1191 * to appear and obscure the context menu we are about to show |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1192 This is a workaround for GTK+ bug 107320. */ |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1193 if (gtkblist->timeout) { |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1194 g_source_remove(gtkblist->timeout); |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1195 gtkblist->timeout = 0; |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1196 } |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1197 #endif |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1198 |
| 8143 | 1199 /* Now display the menu */ |
| 1200 if (menu != NULL) { | |
| 1201 gtk_widget_show_all(menu); | |
| 1202 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, func, tv, button, time); | |
| 1203 handled = TRUE; | |
| 1204 } | |
| 1205 | |
| 1206 return handled; | |
| 1207 } | |
| 1208 | |
| 1209 static gboolean gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_data) | |
| 5228 | 1210 { |
| 1211 GtkTreePath *path; | |
| 1212 GaimBlistNode *node; | |
| 1213 GValue val = { 0, }; | |
| 1214 GtkTreeIter iter; | |
| 1215 GtkTreeSelection *sel; | |
| 1216 GaimPlugin *prpl = NULL; | |
| 1217 GaimPluginProtocolInfo *prpl_info = NULL; | |
| 7620 | 1218 struct _gaim_gtk_blist_node *gtknode; |
| 1219 gboolean handled = FALSE; | |
| 5228 | 1220 |
| 1221 /* Here we figure out which node was clicked */ | |
| 1222 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL)) | |
| 1223 return FALSE; | |
| 1224 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
| 8143 | 1225 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); |
| 5228 | 1226 node = g_value_get_pointer(&val); |
| 7620 | 1227 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; |
| 1228 | |
| 8143 | 1229 /* Right click draws a context menu */ |
| 1230 if ((event->button == 3) && (event->type == GDK_BUTTON_PRESS)) { | |
| 1231 handled = gaim_gtk_blist_show_context_menu(node, NULL, tv, 3, event->time); | |
| 1232 | |
| 1233 /* CTRL+middle click expands or collapse a contact */ | |
| 1234 } else if ((event->button == 2) && (event->type == GDK_BUTTON_PRESS) && | |
| 1235 (event->state & GDK_CONTROL_MASK) && (GAIM_BLIST_NODE_IS_CONTACT(node))) { | |
| 1236 if (gtknode->contact_expanded) | |
| 7620 | 1237 gaim_gtk_blist_collapse_contact_cb(NULL, node); |
| 1238 else | |
| 1239 gaim_gtk_blist_expand_contact_cb(NULL, node); | |
| 1240 handled = TRUE; | |
| 8143 | 1241 |
| 1242 /* Double middle click gets info */ | |
| 1243 } else if ((event->button == 2) && (event->type == GDK_2BUTTON_PRESS) && | |
| 1244 ((GAIM_BLIST_NODE_IS_CONTACT(node)) || (GAIM_BLIST_NODE_IS_BUDDY(node)))) { | |
| 7620 | 1245 GaimBuddy *b; |
| 1246 if(GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 1247 b = gaim_contact_get_priority_buddy((GaimContact*)node); | |
| 1248 else | |
| 1249 b = (GaimBuddy *)node; | |
| 1250 | |
| 7956 | 1251 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
| 5228 | 1252 if (prpl != NULL) |
| 1253 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
| 1254 | |
| 8143 | 1255 if (prpl && prpl_info->get_info) |
| 1256 serv_get_info(b->account->gc, b->name); | |
| 1257 handled = TRUE; | |
| 5228 | 1258 } |
| 1259 | |
| 8143 | 1260 #if (1) |
| 1261 /* | |
|
10814
364a2ef907ae
[gaim-migrate @ 12468]
Luke Schierer <lschiere@pidgin.im>
parents:
10780
diff
changeset
|
1262 * This code only exists because GTK+ doesn't work. If we return |
| 8143 | 1263 * FALSE here, as would be normal the event propoagates down and |
| 1264 * somehow gets interpreted as the start of a drag event. | |
| 1265 * | |
| 1266 * Um, isn't it _normal_ to return TRUE here? Since the event | |
| 1267 * was handled? --Mark | |
| 1268 */ | |
| 7620 | 1269 if(handled) { |
| 1270 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
| 1271 gtk_tree_selection_select_path(sel, path); | |
| 1272 gtk_tree_path_free(path); | |
| 1273 return TRUE; | |
| 1274 } | |
| 5228 | 1275 #endif |
| 7753 | 1276 gtk_tree_path_free(path); |
| 8143 | 1277 |
| 7620 | 1278 return FALSE; |
| 5228 | 1279 } |
| 1280 | |
| 8143 | 1281 static gboolean |
| 1282 gaim_gtk_blist_popup_menu_cb(GtkWidget *tv, void *user_data) | |
| 1283 { | |
| 1284 GaimBlistNode *node; | |
| 1285 GValue val = { 0, }; | |
| 1286 GtkTreeIter iter; | |
| 1287 GtkTreeSelection *sel; | |
| 1288 gboolean handled = FALSE; | |
| 1289 | |
| 1290 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
| 1291 if (!gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
| 1292 return FALSE; | |
| 1293 | |
| 1294 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), | |
| 1295 &iter, NODE_COLUMN, &val); | |
| 1296 node = g_value_get_pointer(&val); | |
| 1297 | |
| 1298 /* Shift+F10 draws a context menu */ | |
| 1299 handled = gaim_gtk_blist_show_context_menu(node, gaim_gtk_treeview_popup_menu_position_func, tv, 0, GDK_CURRENT_TIME); | |
| 1300 | |
| 1301 return handled; | |
| 1302 } | |
| 1303 | |
| 11796 | 1304 static void gaim_gtk_blist_buddy_details_cb(gpointer data, guint action, GtkWidget *item) |
| 1305 { | |
| 1306 gaim_prefs_set_bool("/gaim/gtk/blist/show_buddy_icons", | |
| 1307 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item))); | |
| 1308 } | |
| 1309 | |
| 5228 | 1310 static void gaim_gtk_blist_show_empty_groups_cb(gpointer data, guint action, GtkWidget *item) |
| 1311 { | |
| 7620 | 1312 gaim_prefs_set_bool("/gaim/gtk/blist/show_empty_groups", |
| 1313 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item))); | |
| 5228 | 1314 } |
| 1315 | |
| 1316 static void gaim_gtk_blist_edit_mode_cb(gpointer callback_data, guint callback_action, | |
| 1317 GtkWidget *checkitem) { | |
| 1318 if(gtkblist->window->window) { | |
| 1319 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); | |
| 1320 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
| 1321 while (gtk_events_pending()) | |
| 1322 gtk_main_iteration(); | |
| 1323 gdk_cursor_unref(cursor); | |
| 1324 } | |
| 1325 | |
| 7620 | 1326 gaim_prefs_set_bool("/gaim/gtk/blist/show_offline_buddies", |
| 1327 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem))); | |
| 5228 | 1328 |
| 1329 if(gtkblist->window->window) { | |
| 1330 GdkCursor *cursor = gdk_cursor_new(GDK_LEFT_PTR); | |
| 1331 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
| 1332 gdk_cursor_unref(cursor); | |
| 1333 } | |
| 1334 } | |
| 1335 | |
| 10074 | 1336 static void gaim_gtk_blist_mute_sounds_cb(gpointer data, guint action, GtkWidget *item) |
| 1337 { | |
| 1338 gaim_prefs_set_bool("/gaim/gtk/sound/mute", GTK_CHECK_MENU_ITEM(item)->active); | |
| 1339 } | |
| 1340 | |
| 1341 static void gaim_gtk_blist_mute_pref_cb(const char *name, GaimPrefType type, gpointer value, gpointer data) | |
| 1342 { | |
| 1343 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(gtkblist->ift, | |
| 1344 N_("/Tools/Mute Sounds"))), (gboolean)GPOINTER_TO_INT(value)); | |
| 1345 } | |
| 1346 | |
| 1347 static void gaim_gtk_blist_sound_method_pref_cb(const char *name, GaimPrefType type, gpointer value, gpointer data) | |
| 1348 { | |
| 1349 gboolean sensitive = TRUE; | |
| 1350 | |
| 1351 if(!strcmp(value, "none")) | |
| 1352 sensitive = FALSE; | |
| 1353 | |
| 1354 gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), sensitive); | |
| 1355 } | |
| 1356 | |
| 8089 | 1357 static void |
| 1358 add_buddies_from_vcard(const char *prpl_id, GaimGroup *group, GList *list, | |
| 1359 const char *alias) | |
| 1360 { | |
| 1361 GList *l; | |
| 1362 GaimAccount *account = NULL; | |
| 1363 GaimConnection *gc; | |
| 1364 | |
| 1365 if (list == NULL) | |
| 1366 return; | |
| 1367 | |
| 1368 for (l = gaim_connections_get_all(); l != NULL; l = l->next) | |
| 1369 { | |
| 1370 gc = (GaimConnection *)l->data; | |
| 1371 account = gaim_connection_get_account(gc); | |
| 1372 | |
| 1373 if (!strcmp(gaim_account_get_protocol_id(account), prpl_id)) | |
| 1374 break; | |
| 1375 | |
| 1376 account = NULL; | |
| 1377 } | |
| 1378 | |
| 1379 if (account != NULL) | |
| 1380 { | |
| 1381 for (l = list; l != NULL; l = l->next) | |
| 1382 { | |
| 1383 gaim_blist_request_add_buddy(account, l->data, | |
| 1384 (group ? group->name : NULL), | |
| 1385 alias); | |
| 1386 } | |
| 1387 } | |
| 1388 | |
| 1389 g_list_foreach(list, (GFunc)g_free, NULL); | |
| 1390 g_list_free(list); | |
| 1391 } | |
| 1392 | |
| 1393 static gboolean | |
| 1394 parse_vcard(const char *vcard, GaimGroup *group) | |
| 1395 { | |
| 1396 char *temp_vcard; | |
| 1397 char *s, *c; | |
| 1398 char *alias = NULL; | |
| 1399 GList *aims = NULL; | |
| 1400 GList *icqs = NULL; | |
| 1401 GList *yahoos = NULL; | |
| 1402 GList *msns = NULL; | |
| 1403 GList *jabbers = NULL; | |
| 1404 | |
| 1405 s = temp_vcard = g_strdup(vcard); | |
| 1406 | |
| 1407 while (*s != '\0' && strncmp(s, "END:vCard", strlen("END:vCard"))) | |
| 1408 { | |
| 1409 char *field, *value; | |
| 1410 | |
| 1411 field = s; | |
| 1412 | |
| 1413 /* Grab the field */ | |
| 1414 while (*s != '\r' && *s != '\n' && *s != '\0' && *s != ':') | |
| 1415 s++; | |
| 1416 | |
| 1417 if (*s == '\r') s++; | |
| 1418 if (*s == '\n') | |
| 1419 { | |
| 1420 s++; | |
| 1421 continue; | |
| 1422 } | |
| 1423 | |
| 1424 if (*s != '\0') *s++ = '\0'; | |
| 1425 | |
| 1426 if ((c = strchr(field, ';')) != NULL) | |
| 1427 *c = '\0'; | |
| 1428 | |
| 1429 /* Proceed to the end of the line */ | |
| 1430 value = s; | |
| 1431 | |
| 1432 while (*s != '\r' && *s != '\n' && *s != '\0') | |
| 1433 s++; | |
| 1434 | |
| 1435 if (*s == '\r') *s++ = '\0'; | |
| 1436 if (*s == '\n') *s++ = '\0'; | |
| 1437 | |
| 1438 /* We only want to worry about a few fields here. */ | |
| 1439 if (!strcmp(field, "FN")) | |
| 1440 alias = g_strdup(value); | |
| 1441 else if (!strcmp(field, "X-AIM") || !strcmp(field, "X-ICQ") || | |
| 1442 !strcmp(field, "X-YAHOO") || !strcmp(field, "X-MSN") || | |
| 1443 !strcmp(field, "X-JABBER")) | |
| 1444 { | |
| 1445 char **values = g_strsplit(value, ":", 0); | |
| 1446 char **im; | |
| 1447 | |
| 1448 for (im = values; *im != NULL; im++) | |
| 1449 { | |
| 1450 if (!strcmp(field, "X-AIM")) | |
| 1451 aims = g_list_append(aims, g_strdup(*im)); | |
| 1452 else if (!strcmp(field, "X-ICQ")) | |
| 1453 icqs = g_list_append(icqs, g_strdup(*im)); | |
| 1454 else if (!strcmp(field, "X-YAHOO")) | |
| 1455 yahoos = g_list_append(yahoos, g_strdup(*im)); | |
| 1456 else if (!strcmp(field, "X-MSN")) | |
| 1457 msns = g_list_append(msns, g_strdup(*im)); | |
| 1458 else if (!strcmp(field, "X-JABBER")) | |
| 1459 jabbers = g_list_append(jabbers, g_strdup(*im)); | |
| 1460 } | |
| 1461 | |
| 1462 g_strfreev(values); | |
| 1463 } | |
| 1464 } | |
| 1465 | |
| 1466 g_free(temp_vcard); | |
| 1467 | |
| 1468 if (aims == NULL && icqs == NULL && yahoos == NULL && | |
| 1469 msns == NULL && jabbers == NULL) | |
| 1470 { | |
| 1471 if (alias != NULL) | |
| 1472 g_free(alias); | |
| 1473 | |
| 1474 return FALSE; | |
| 1475 } | |
| 1476 | |
| 1477 add_buddies_from_vcard("prpl-oscar", group, aims, alias); | |
| 1478 add_buddies_from_vcard("prpl-oscar", group, icqs, alias); | |
| 1479 add_buddies_from_vcard("prpl-yahoo", group, yahoos, alias); | |
| 1480 add_buddies_from_vcard("prpl-msn", group, msns, alias); | |
| 1481 add_buddies_from_vcard("prpl-jabber", group, jabbers, alias); | |
| 1482 | |
| 1483 if (alias != NULL) | |
| 1484 g_free(alias); | |
| 1485 | |
| 1486 return TRUE; | |
| 1487 } | |
| 1488 | |
|
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1489 #ifdef _WIN32 |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1490 static void gaim_gtk_blist_drag_begin(GtkWidget *widget, |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1491 GdkDragContext *drag_context, gpointer user_data) |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1492 { |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1493 gaim_gtk_blist_tooltip_destroy(); |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1494 |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1495 |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1496 /* Unhook the tooltip-timeout since we don't want a tooltip |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1497 * to appear and obscure the dragging operation. |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1498 * This is a workaround for GTK+ bug 107320. */ |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1499 if (gtkblist->timeout) { |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1500 g_source_remove(gtkblist->timeout); |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1501 gtkblist->timeout = 0; |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1502 } |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1503 } |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1504 #endif |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1505 |
| 9811 | 1506 static void gaim_gtk_blist_drag_data_get_cb(GtkWidget *widget, |
| 1507 GdkDragContext *dc, | |
| 1508 GtkSelectionData *data, | |
| 1509 guint info, | |
| 1510 guint time, | |
|
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1511 gpointer null) |
| 5228 | 1512 { |
|
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1513 |
| 8089 | 1514 if (data->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE)) |
| 1515 { | |
| 5228 | 1516 GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); |
| 1517 GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref); | |
| 1518 GtkTreeIter iter; | |
| 1519 GaimBlistNode *node = NULL; | |
| 1520 GValue val = {0}; | |
| 5273 | 1521 if(!sourcerow) |
| 1522 return; | |
| 5228 | 1523 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, sourcerow); |
| 1524 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
| 1525 node = g_value_get_pointer(&val); | |
| 1526 gtk_selection_data_set (data, | |
| 1527 gdk_atom_intern ("GAIM_BLIST_NODE", FALSE), | |
| 1528 8, /* bits */ | |
| 1529 (void*)&node, | |
| 1530 sizeof (node)); | |
| 5273 | 1531 |
| 5228 | 1532 gtk_tree_path_free(sourcerow); |
| 1533 } | |
| 8089 | 1534 else if (data->target == gdk_atom_intern("application/x-im-contact", FALSE)) |
| 1535 { | |
| 7706 | 1536 GtkTreeRowReference *ref; |
| 1537 GtkTreePath *sourcerow; | |
| 1538 GtkTreeIter iter; | |
| 1539 GaimBlistNode *node = NULL; | |
| 1540 GaimBuddy *buddy; | |
| 1541 GaimConnection *gc; | |
| 1542 GValue val = {0}; | |
| 1543 GString *str; | |
| 1544 const char *protocol; | |
| 1545 char *mime_str; | |
| 1546 | |
| 1547 ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); | |
| 1548 sourcerow = gtk_tree_row_reference_get_path(ref); | |
| 1549 | |
| 1550 if (!sourcerow) | |
| 1551 return; | |
| 1552 | |
| 1553 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
| 1554 sourcerow); | |
| 1555 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
| 1556 NODE_COLUMN, &val); | |
| 1557 | |
| 1558 node = g_value_get_pointer(&val); | |
| 1559 | |
| 1560 if (GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 1561 { | |
| 1562 buddy = gaim_contact_get_priority_buddy((GaimContact *)node); | |
| 1563 } | |
| 1564 else if (!GAIM_BLIST_NODE_IS_BUDDY(node)) | |
| 1565 { | |
| 1566 gtk_tree_path_free(sourcerow); | |
| 1567 return; | |
| 1568 } | |
| 1569 else | |
| 1570 { | |
| 1571 buddy = (GaimBuddy *)node; | |
| 1572 } | |
| 1573 | |
| 1574 gc = gaim_account_get_connection(buddy->account); | |
| 1575 | |
| 1576 if (gc == NULL) | |
| 1577 { | |
| 1578 gtk_tree_path_free(sourcerow); | |
| 1579 return; | |
| 1580 } | |
| 1581 | |
| 1582 protocol = | |
| 1583 GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->list_icon(buddy->account, | |
| 1584 buddy); | |
| 1585 | |
| 1586 str = g_string_new(NULL); | |
| 1587 g_string_printf(str, | |
| 1588 "MIME-Version: 1.0\r\n" | |
| 1589 "Content-Type: application/x-im-contact\r\n" | |
| 1590 "X-IM-Protocol: %s\r\n" | |
| 1591 "X-IM-Username: %s\r\n", | |
| 1592 protocol, | |
| 1593 buddy->name); | |
| 1594 | |
| 1595 if (buddy->alias != NULL) | |
| 1596 { | |
| 1597 g_string_append_printf(str, | |
| 1598 "X-IM-Alias: %s\r\n", | |
| 1599 buddy->alias); | |
| 1600 } | |
| 1601 | |
| 1602 str = g_string_append(str, "\r\n"); | |
| 1603 | |
| 1604 mime_str = g_string_free(str, FALSE); | |
| 1605 | |
| 1606 gtk_selection_data_set(data, | |
| 1607 gdk_atom_intern("application/x-im-contact", FALSE), | |
| 1608 8, /* bits */ | |
| 11137 | 1609 (const guchar *)mime_str, |
| 7706 | 1610 strlen(mime_str) + 1); |
| 1611 | |
| 1612 g_free(mime_str); | |
| 1613 gtk_tree_path_free(sourcerow); | |
| 1614 } | |
| 5228 | 1615 } |
| 1616 | |
| 1617 static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | |
| 1618 GtkSelectionData *sd, guint info, guint t) | |
| 7620 | 1619 { |
| 5228 | 1620 if (sd->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE) && sd->data) { |
| 1621 GaimBlistNode *n = NULL; | |
| 1622 GtkTreePath *path = NULL; | |
| 1623 GtkTreeViewDropPosition position; | |
| 1624 memcpy(&n, sd->data, sizeof(n)); | |
| 1625 if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) { | |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1626 /* if we're here, I think it means the drop is ok */ |
| 7642 | 1627 GtkTreeIter iter; |
| 5228 | 1628 GaimBlistNode *node; |
| 1629 GValue val = {0}; | |
| 7620 | 1630 struct _gaim_gtk_blist_node *gtknode; |
| 1631 | |
| 1632 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
| 1633 &iter, path); | |
| 1634 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
| 1635 &iter, NODE_COLUMN, &val); | |
| 5228 | 1636 node = g_value_get_pointer(&val); |
| 7620 | 1637 gtknode = node->ui_data; |
| 1638 | |
| 1639 if (GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
| 1640 GaimContact *c = (GaimContact*)n; | |
| 1641 if (GAIM_BLIST_NODE_IS_CONTACT(node) && gtknode->contact_expanded) { | |
| 1642 gaim_blist_merge_contact(c, node); | |
| 1643 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) || | |
| 5234 | 1644 GAIM_BLIST_NODE_IS_CHAT(node)) { |
| 5228 | 1645 switch(position) { |
| 1646 case GTK_TREE_VIEW_DROP_AFTER: | |
| 1647 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
| 7620 | 1648 gaim_blist_add_contact(c, (GaimGroup*)node->parent, |
| 1649 node); | |
| 1650 break; | |
| 1651 case GTK_TREE_VIEW_DROP_BEFORE: | |
| 1652 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
| 1653 gaim_blist_add_contact(c, (GaimGroup*)node->parent, | |
| 1654 node->prev); | |
| 1655 break; | |
| 1656 } | |
| 1657 } else if(GAIM_BLIST_NODE_IS_GROUP(node)) { | |
| 1658 gaim_blist_add_contact(c, (GaimGroup*)node, NULL); | |
| 1659 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
| 1660 gaim_blist_merge_contact(c, node); | |
| 1661 } | |
| 1662 } else if (GAIM_BLIST_NODE_IS_BUDDY(n)) { | |
| 1663 GaimBuddy *b = (GaimBuddy*)n; | |
| 1664 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
| 1665 switch(position) { | |
| 1666 case GTK_TREE_VIEW_DROP_AFTER: | |
| 1667 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
| 1668 gaim_blist_add_buddy(b, (GaimContact*)node->parent, | |
| 1669 (GaimGroup*)node->parent->parent, node); | |
| 5228 | 1670 break; |
| 1671 case GTK_TREE_VIEW_DROP_BEFORE: | |
| 1672 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
| 7620 | 1673 gaim_blist_add_buddy(b, (GaimContact*)node->parent, |
| 1674 (GaimGroup*)node->parent->parent, | |
| 1675 node->prev); | |
| 5228 | 1676 break; |
| 1677 } | |
| 7620 | 1678 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { |
| 1679 gaim_blist_add_buddy(b, NULL, (GaimGroup*)node->parent, | |
| 1680 NULL); | |
| 5228 | 1681 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
| 7620 | 1682 gaim_blist_add_buddy(b, NULL, (GaimGroup*)node, NULL); |
| 1683 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
| 1684 if(gtknode->contact_expanded) { | |
| 1685 switch(position) { | |
| 1686 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
| 1687 case GTK_TREE_VIEW_DROP_AFTER: | |
| 1688 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
| 1689 gaim_blist_add_buddy(b, (GaimContact*)node, | |
| 1690 (GaimGroup*)node->parent, NULL); | |
| 1691 break; | |
| 1692 case GTK_TREE_VIEW_DROP_BEFORE: | |
| 1693 gaim_blist_add_buddy(b, NULL, | |
| 1694 (GaimGroup*)node->parent, node->prev); | |
| 1695 break; | |
| 1696 } | |
| 1697 } else { | |
| 1698 switch(position) { | |
| 1699 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
| 1700 case GTK_TREE_VIEW_DROP_AFTER: | |
| 1701 gaim_blist_add_buddy(b, NULL, | |
| 1702 (GaimGroup*)node->parent, NULL); | |
| 1703 break; | |
| 1704 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
| 1705 case GTK_TREE_VIEW_DROP_BEFORE: | |
| 1706 gaim_blist_add_buddy(b, NULL, | |
| 1707 (GaimGroup*)node->parent, node->prev); | |
| 1708 break; | |
| 1709 } | |
| 1710 } | |
| 5228 | 1711 } |
| 5234 | 1712 } else if (GAIM_BLIST_NODE_IS_CHAT(n)) { |
| 7620 | 1713 GaimChat *chat = (GaimChat *)n; |
| 1714 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
| 1715 switch(position) { | |
| 1716 case GTK_TREE_VIEW_DROP_AFTER: | |
| 1717 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
| 1718 gaim_blist_add_chat(chat, | |
| 1719 (GaimGroup*)node->parent->parent, node); | |
| 1720 break; | |
| 1721 case GTK_TREE_VIEW_DROP_BEFORE: | |
| 1722 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
| 1723 gaim_blist_add_chat(chat, | |
| 1724 (GaimGroup*)node->parent->parent, | |
| 1725 node->prev); | |
| 1726 break; | |
| 1727 } | |
| 1728 } else if(GAIM_BLIST_NODE_IS_CONTACT(node) || | |
| 5234 | 1729 GAIM_BLIST_NODE_IS_CHAT(node)) { |
| 1730 switch(position) { | |
| 1731 case GTK_TREE_VIEW_DROP_AFTER: | |
| 1732 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
| 7620 | 1733 gaim_blist_add_chat(chat, (GaimGroup*)node->parent, node); |
| 5234 | 1734 break; |
| 1735 case GTK_TREE_VIEW_DROP_BEFORE: | |
| 1736 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
| 7620 | 1737 gaim_blist_add_chat(chat, (GaimGroup*)node->parent, node->prev); |
| 5234 | 1738 break; |
| 1739 } | |
| 1740 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
| 7620 | 1741 gaim_blist_add_chat(chat, (GaimGroup*)node, NULL); |
| 5234 | 1742 } |
| 5228 | 1743 } else if (GAIM_BLIST_NODE_IS_GROUP(n)) { |
| 7620 | 1744 GaimGroup *g = (GaimGroup*)n; |
| 5228 | 1745 if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
| 1746 switch (position) { | |
| 1747 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
| 1748 case GTK_TREE_VIEW_DROP_AFTER: | |
| 1749 gaim_blist_add_group(g, node); | |
| 1750 break; | |
| 1751 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
| 1752 case GTK_TREE_VIEW_DROP_BEFORE: | |
| 1753 gaim_blist_add_group(g, node->prev); | |
| 1754 break; | |
| 1755 } | |
| 7620 | 1756 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
| 1757 gaim_blist_add_group(g, node->parent->parent); | |
| 1758 } else if(GAIM_BLIST_NODE_IS_CONTACT(node) || | |
| 5234 | 1759 GAIM_BLIST_NODE_IS_CHAT(node)) { |
| 5228 | 1760 gaim_blist_add_group(g, node->parent); |
| 1761 } | |
| 1762 } | |
| 1763 | |
| 1764 gtk_tree_path_free(path); | |
| 7620 | 1765 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); |
| 5228 | 1766 } |
| 1767 } | |
| 7706 | 1768 else if (sd->target == gdk_atom_intern("application/x-im-contact", |
| 1769 FALSE) && sd->data) | |
| 1770 { | |
| 1771 GaimGroup *group = NULL; | |
| 1772 GtkTreePath *path = NULL; | |
| 1773 GtkTreeViewDropPosition position; | |
|
7712
2823111061ba
[gaim-migrate @ 8357]
Christian Hammond <chipx86@chipx86.com>
parents:
7706
diff
changeset
|
1774 GaimAccount *account; |
| 7706 | 1775 char *protocol = NULL; |
| 1776 char *username = NULL; | |
| 1777 char *alias = NULL; | |
| 1778 | |
| 1779 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
| 1780 x, y, &path, &position)) | |
| 1781 { | |
| 1782 GtkTreeIter iter; | |
| 1783 GaimBlistNode *node; | |
| 1784 GValue val = {0}; | |
| 1785 | |
| 1786 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
| 1787 &iter, path); | |
| 1788 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
| 1789 &iter, NODE_COLUMN, &val); | |
| 1790 node = g_value_get_pointer(&val); | |
| 1791 | |
| 1792 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
| 1793 { | |
| 1794 group = (GaimGroup *)node->parent->parent; | |
| 1795 } | |
| 1796 else if (GAIM_BLIST_NODE_IS_CHAT(node) || | |
| 1797 GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 1798 { | |
| 1799 group = (GaimGroup *)node->parent; | |
| 1800 } | |
| 1801 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
| 1802 { | |
| 1803 group = (GaimGroup *)node; | |
| 1804 } | |
| 1805 } | |
| 1806 | |
| 11137 | 1807 if (gaim_gtk_parse_x_im_contact((const char *)sd->data, FALSE, &account, |
|
7712
2823111061ba
[gaim-migrate @ 8357]
Christian Hammond <chipx86@chipx86.com>
parents:
7706
diff
changeset
|
1808 &protocol, &username, &alias)) |
| 7706 | 1809 { |
| 1810 if (account == NULL) | |
| 1811 { | |
| 1812 gaim_notify_error(NULL, NULL, | |
| 1813 _("You are not currently signed on with an account that " | |
| 1814 "can add that buddy."), NULL); | |
| 1815 } | |
| 1816 else | |
| 1817 { | |
| 1818 gaim_blist_request_add_buddy(account, username, | |
| 1819 (group ? group->name : NULL), | |
| 1820 alias); | |
| 1821 } | |
| 1822 } | |
| 1823 | |
| 1824 if (username != NULL) g_free(username); | |
| 1825 if (protocol != NULL) g_free(protocol); | |
| 1826 if (alias != NULL) g_free(alias); | |
| 1827 | |
| 1828 if (path != NULL) | |
| 1829 gtk_tree_path_free(path); | |
| 1830 | |
| 1831 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); | |
| 1832 } | |
| 8089 | 1833 else if (sd->target == gdk_atom_intern("text/x-vcard", FALSE) && sd->data) |
| 1834 { | |
| 1835 gboolean result; | |
| 1836 GaimGroup *group = NULL; | |
| 1837 GtkTreePath *path = NULL; | |
| 1838 GtkTreeViewDropPosition position; | |
| 1839 | |
| 1840 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
| 1841 x, y, &path, &position)) | |
| 1842 { | |
| 1843 GtkTreeIter iter; | |
| 1844 GaimBlistNode *node; | |
| 1845 GValue val = {0}; | |
| 1846 | |
| 1847 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
| 1848 &iter, path); | |
| 1849 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
| 1850 &iter, NODE_COLUMN, &val); | |
| 1851 node = g_value_get_pointer(&val); | |
| 1852 | |
| 1853 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
| 1854 { | |
| 1855 group = (GaimGroup *)node->parent->parent; | |
| 1856 } | |
| 1857 else if (GAIM_BLIST_NODE_IS_CHAT(node) || | |
| 1858 GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 1859 { | |
| 1860 group = (GaimGroup *)node->parent; | |
| 1861 } | |
| 1862 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
| 1863 { | |
| 1864 group = (GaimGroup *)node; | |
| 1865 } | |
| 1866 } | |
| 1867 | |
| 11137 | 1868 result = parse_vcard((const gchar *)sd->data, group); |
| 8089 | 1869 |
| 1870 gtk_drag_finish(dc, result, (dc->action == GDK_ACTION_MOVE), t); | |
| 9525 | 1871 } else if (sd->target == gdk_atom_intern("text/uri-list", FALSE) && sd->data) { |
| 9495 | 1872 GtkTreePath *path = NULL; |
| 1873 GtkTreeViewDropPosition position; | |
| 1874 | |
| 1875 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
| 9811 | 1876 x, y, &path, &position)) |
| 9495 | 1877 { |
| 1878 GtkTreeIter iter; | |
| 1879 GaimBlistNode *node; | |
| 1880 GValue val = {0}; | |
|
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
1881 |
| 9495 | 1882 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), |
| 1883 &iter, path); | |
| 1884 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
| 1885 &iter, NODE_COLUMN, &val); | |
| 1886 node = g_value_get_pointer(&val); | |
|
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
1887 |
| 9495 | 1888 if (GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CONTACT(node)) { |
| 1889 GaimBuddy *b = GAIM_BLIST_NODE_IS_BUDDY(node) ? (GaimBuddy*)node : gaim_contact_get_priority_buddy((GaimContact*)node); | |
| 10229 | 1890 gaim_dnd_file_manage(sd, b->account, b->name); |
| 1891 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); | |
| 1892 } else { | |
| 1893 gtk_drag_finish(dc, FALSE, FALSE, t); | |
| 9495 | 1894 } |
|
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
1895 } |
| 8089 | 1896 } |
| 5228 | 1897 } |
| 1898 | |
| 10482 | 1899 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(GaimBlistNode *node, |
| 1900 gboolean scaled, gboolean greyed) | |
| 1901 { | |
| 10483 | 1902 GdkPixbuf *buf, *ret = NULL; |
| 10482 | 1903 GdkPixbufLoader *loader; |
| 1904 GaimBuddyIcon *icon; | |
| 11137 | 1905 const guchar *data; |
| 1906 gsize len; | |
| 10482 | 1907 GaimBuddy *buddy = (GaimBuddy *)node; |
| 1908 | |
| 1909 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
| 1910 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
| 1911 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
| 1912 buddy = (GaimBuddy*)node; | |
| 1913 } else { | |
| 1914 return NULL; | |
| 1915 } | |
| 1916 | |
| 1917 #if 0 | |
| 1918 if (!gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) | |
| 1919 return NULL; | |
| 1920 #endif | |
| 1921 | |
| 1922 if (!(icon = gaim_buddy_get_icon(buddy))) | |
| 1923 if (!(icon = gaim_buddy_icons_find(buddy->account, buddy->name))) /* Not sure I like this...*/ | |
| 1924 return NULL; | |
| 1925 | |
| 1926 loader = gdk_pixbuf_loader_new(); | |
| 1927 data = gaim_buddy_icon_get_data(icon, &len); | |
| 1928 gdk_pixbuf_loader_write(loader, data, len, NULL); | |
| 1929 buf = gdk_pixbuf_loader_get_pixbuf(loader); | |
| 1930 if (buf) | |
| 1931 g_object_ref(G_OBJECT(buf)); | |
| 1932 gdk_pixbuf_loader_close(loader, NULL); | |
| 1933 g_object_unref(G_OBJECT(loader)); | |
| 1934 | |
| 1935 if (buf) { | |
| 10544 | 1936 GaimAccount *account = gaim_buddy_get_account(buddy); |
| 1937 GaimPluginProtocolInfo *prpl_info = NULL; | |
| 1938 int orig_width, orig_height; | |
| 1939 int scale_width, scale_height; | |
| 1940 | |
| 1941 if(account && account->gc) | |
| 1942 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(account->gc->prpl); | |
| 1943 | |
| 10482 | 1944 if (greyed) { |
| 1945 GaimPresence *presence = gaim_buddy_get_presence(buddy); | |
| 1946 if (!GAIM_BUDDY_IS_ONLINE(buddy)) | |
| 1947 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE); | |
| 1948 if (gaim_presence_is_idle(presence)) | |
| 1949 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE); | |
| 1950 } | |
| 1951 | |
| 10544 | 1952 /* i'd use the gaim_gtk_buddy_icon_get_scale_size() thing, |
| 1953 * but it won't tell me the original size, which I need for scaling | |
| 1954 * purposes */ | |
| 1955 scale_width = orig_width = gdk_pixbuf_get_width(buf); | |
| 1956 scale_height = orig_height = gdk_pixbuf_get_height(buf); | |
| 1957 | |
| 1958 gaim_buddy_icon_get_scale_size(prpl_info ? &prpl_info->icon_spec : NULL, &scale_width, &scale_height); | |
| 1959 | |
| 10482 | 1960 if (scaled) { |
| 10544 | 1961 if(scale_height > scale_width) { |
| 1962 scale_width = 30.0 * (double)scale_width / (double)scale_height; | |
| 1963 scale_height = 30; | |
| 1964 } else { | |
| 1965 scale_height = 30.0 * (double)scale_height / (double)scale_width; | |
| 1966 scale_width = 30; | |
| 1967 } | |
| 1968 | |
| 1969 ret = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 30, 30); | |
| 1970 gdk_pixbuf_fill(ret, 0x00000000); | |
| 1971 gdk_pixbuf_scale(buf, ret, (30-scale_width)/2, (30-scale_height)/2, scale_width, scale_height, (30-scale_width)/2, (30-scale_height)/2, (double)scale_width/(double)orig_width, (double)scale_height/(double)orig_height, GDK_INTERP_BILINEAR); | |
| 10483 | 1972 } else { |
| 1973 ret = gdk_pixbuf_scale_simple(buf,scale_width,scale_height, GDK_INTERP_BILINEAR); | |
| 1974 } | |
| 10544 | 1975 g_object_unref(G_OBJECT(buf)); |
| 10482 | 1976 } |
| 1977 | |
| 10483 | 1978 return ret; |
| 10482 | 1979 } |
| 1980 | |
| 11890 | 1981 struct tooltip_data { |
| 1982 PangoLayout *layout; | |
| 1983 GdkPixbuf *status_icon; | |
| 1984 GdkPixbuf *avatar; | |
| 11892 | 1985 int avatar_width; |
| 1986 int width; | |
| 1987 int height; | |
| 11890 | 1988 }; |
| 1989 | |
| 1990 static struct tooltip_data * create_tip_for_node(GaimBlistNode *node) | |
| 1991 { | |
| 1992 struct tooltip_data *td = g_new0(struct tooltip_data, 1); | |
| 1993 char *tooltip_text = gaim_get_tooltip_text(node); | |
| 1994 | |
| 1995 td->status_icon = gaim_gtk_blist_get_status_icon(node, GAIM_STATUS_ICON_LARGE); | |
| 1996 td->avatar = gaim_gtk_blist_get_buddy_icon(node, FALSE, FALSE); | |
| 1997 | |
| 1998 td->layout = gtk_widget_create_pango_layout(gtkblist->tipwindow, NULL); | |
| 1999 pango_layout_set_markup(td->layout, tooltip_text, strlen(tooltip_text)); | |
| 2000 pango_layout_set_wrap(td->layout, PANGO_WRAP_WORD); | |
| 2001 pango_layout_set_width(td->layout, 300000); | |
| 11983 | 2002 |
| 11892 | 2003 pango_layout_get_size (td->layout, &td->width, &td->height); |
| 2004 td->width = PANGO_PIXELS(td->width) + 38 + 8; | |
| 2005 td->height = MAX(PANGO_PIXELS(td->height) + 8, 38); | |
| 2006 | |
| 2007 if(td->avatar) { | |
| 2008 td->avatar_width = gdk_pixbuf_get_width(td->avatar); | |
| 2009 td->width += td->avatar_width + 8; | |
| 2010 td->height = MAX(td->height, gdk_pixbuf_get_height(td->avatar) + 8); | |
| 2011 } | |
| 11890 | 2012 |
| 2013 return td; | |
| 2014 } | |
| 2015 | |
| 5234 | 2016 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, GaimBlistNode *node) |
| 5228 | 2017 { |
| 2018 GtkStyle *style; | |
| 11892 | 2019 int current_height, max_width; |
| 11890 | 2020 GList *l; |
| 2021 | |
| 2022 if(gtkblist->tooltipdata == NULL) | |
| 7620 | 2023 return; |
| 2024 | |
| 11890 | 2025 style = gtkblist->tipwindow->style; |
| 2026 gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, | |
| 2027 NULL, gtkblist->tipwindow, "tooltip", 0, 0, -1, -1); | |
| 2028 | |
| 11892 | 2029 max_width = 0; |
| 2030 for(l = gtkblist->tooltipdata; l; l = l->next) | |
| 2031 { | |
| 2032 struct tooltip_data *td = l->data; | |
| 2033 max_width = MAX(max_width, td->width); | |
| 2034 } | |
| 2035 | |
| 11890 | 2036 current_height = 0; |
| 2037 for(l = gtkblist->tooltipdata; l; l = l->next) | |
| 10482 | 2038 { |
| 11890 | 2039 struct tooltip_data *td = l->data; |
| 5228 | 2040 |
| 2041 #if GTK_CHECK_VERSION(2,2,0) | |
| 11890 | 2042 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, |
| 2043 0, 0, 4, current_height + 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); | |
| 2044 if(td->avatar) | |
| 2045 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, | |
| 11892 | 2046 td->avatar, 0, 0, max_width - (td->avatar_width + 4), current_height + 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); |
| 5228 | 2047 #else |
| 11890 | 2048 gdk_pixbuf_render_to_drawable(td->status_icon, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 4, current_height + 4, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); |
| 2049 if(td->avatar) | |
| 2050 gdk_pixbuf_render_to_drawable(td->avatar, | |
| 11983 | 2051 GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, |
| 11892 | 2052 max_width - (td->avatar_width + 4), |
| 11890 | 2053 current_height + 4, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); |
| 5228 | 2054 #endif |
| 2055 | |
| 11890 | 2056 gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE, |
| 2057 NULL, gtkblist->tipwindow, "tooltip", 38 + 4, current_height + 4, td->layout); | |
| 2058 | |
| 11895 | 2059 current_height += td->height; |
| 2060 | |
| 11894 | 2061 if(l->next) |
| 11895 | 2062 gtk_paint_hline(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, NULL, NULL, NULL, 4, max_width - 4, current_height-2); |
| 11890 | 2063 } |
| 5228 | 2064 } |
| 2065 | |
| 8254 | 2066 static void gaim_gtk_blist_tooltip_destroy() |
| 2067 { | |
| 11890 | 2068 while(gtkblist->tooltipdata) { |
| 2069 struct tooltip_data *td = gtkblist->tooltipdata->data; | |
| 2070 | |
| 2071 if(td->avatar) | |
| 2072 g_object_unref(td->avatar); | |
| 2073 if(td->status_icon) | |
| 2074 g_object_unref(td->status_icon); | |
| 2075 g_object_unref(td->layout); | |
| 2076 g_free(td); | |
| 2077 gtkblist->tooltipdata = g_list_delete_link(gtkblist->tooltipdata, gtkblist->tooltipdata); | |
| 2078 } | |
| 11636 | 2079 |
| 8254 | 2080 if (gtkblist->tipwindow == NULL) |
| 2081 return; | |
| 2082 | |
| 2083 gtk_widget_destroy(gtkblist->tipwindow); | |
| 2084 gtkblist->tipwindow = NULL; | |
| 2085 } | |
| 2086 | |
| 10354 | 2087 static gboolean gaim_gtk_blist_expand_timeout(GtkWidget *tv) |
| 2088 { | |
| 2089 GtkTreePath *path; | |
| 2090 GtkTreeIter iter; | |
| 2091 GaimBlistNode *node; | |
| 2092 GValue val = {0}; | |
| 2093 struct _gaim_gtk_blist_node *gtknode; | |
| 2094 | |
| 2095 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->tip_rect.x, gtkblist->tip_rect.y, &path, NULL, NULL, NULL)) | |
| 2096 return FALSE; | |
| 2097 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
| 2098 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
| 2099 node = g_value_get_pointer(&val); | |
| 2100 | |
| 10504 | 2101 if(!GAIM_BLIST_NODE_IS_CONTACT(node)) { |
| 2102 gtk_tree_path_free(path); | |
| 10354 | 2103 return FALSE; |
| 10504 | 2104 } |
| 10354 | 2105 |
| 2106 gtknode = node->ui_data; | |
| 2107 | |
| 2108 if (!gtknode->contact_expanded) { | |
| 2109 GtkTreeIter i; | |
|
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
2110 |
| 10354 | 2111 gaim_gtk_blist_expand_contact_cb(NULL, node); |
|
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
2112 |
| 10354 | 2113 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->contact_rect); |
| 2114 gdk_drawable_get_size(GDK_DRAWABLE(tv->window), &(gtkblist->contact_rect.width), NULL); | |
| 2115 gtkblist->mouseover_contact = node; | |
| 2116 gtk_tree_path_down (path); | |
| 2117 while (gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &i, path)) { | |
| 2118 GdkRectangle rect; | |
| 2119 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, &rect); | |
| 2120 gtkblist->contact_rect.height += rect.height; | |
| 2121 gtk_tree_path_next(path); | |
| 2122 } | |
| 2123 } | |
| 2124 gtk_tree_path_free(path); | |
| 2125 return FALSE; | |
| 2126 } | |
| 2127 | |
| 11890 | 2128 static gboolean buddy_is_displayable(GaimBuddy *buddy) |
| 2129 { | |
| 11910 | 2130 struct _gaim_gtk_blist_node *gtknode; |
| 2131 | |
| 2132 if(!buddy) | |
| 2133 return FALSE; | |
| 2134 | |
| 2135 gtknode = ((GaimBlistNode*)buddy)->ui_data; | |
| 2136 | |
| 2137 return (gaim_account_is_connected(buddy->account) && | |
| 11890 | 2138 (gaim_presence_is_online(buddy->presence) || |
| 11910 | 2139 (gtknode && gtknode->recent_signonoff) || |
| 2140 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies") || | |
| 2141 gaim_blist_node_get_bool((GaimBlistNode*)buddy, "show_offline"))); | |
| 11890 | 2142 } |
| 2143 | |
| 5228 | 2144 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv) |
| 2145 { | |
| 2146 GtkTreePath *path; | |
| 2147 GtkTreeIter iter; | |
| 2148 GaimBlistNode *node; | |
| 2149 GValue val = {0}; | |
| 9869 | 2150 int scr_w, scr_h, w, h, x, y; |
| 2151 #if GTK_CHECK_VERSION(2,2,0) | |
| 2152 int mon_num; | |
| 2153 GdkScreen *screen = NULL; | |
| 2154 #endif | |
| 7636 | 2155 gboolean tooltip_top = FALSE; |
| 2156 struct _gaim_gtk_blist_node *gtknode; | |
| 9773 | 2157 GdkRectangle mon_size; |
| 5228 | 2158 |
| 11636 | 2159 /* |
| 2160 * Attempt to free the previous tooltip. I have a feeling | |
| 2161 * this is never needed... but just in case. | |
| 2162 */ | |
| 2163 gaim_gtk_blist_tooltip_destroy(); | |
| 2164 | |
| 7636 | 2165 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->tip_rect.x, gtkblist->tip_rect.y, &path, NULL, NULL, NULL)) |
| 5228 | 2166 return FALSE; |
| 2167 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
| 2168 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
| 2169 node = g_value_get_pointer(&val); | |
| 7620 | 2170 |
| 10504 | 2171 gtk_tree_path_free(path); |
| 2172 | |
| 11890 | 2173 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP); |
| 2174 | |
| 2175 if(GAIM_BLIST_NODE_IS_CHAT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
| 2176 struct tooltip_data *td = create_tip_for_node(node); | |
| 2177 gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td); | |
| 11892 | 2178 w = td->width; |
| 2179 h = td->height; | |
| 11890 | 2180 } else if(GAIM_BLIST_NODE_IS_CONTACT(node)) { |
| 2181 GaimBlistNode *child; | |
| 2182 w = h = 0; | |
| 2183 for(child = node->child; child; child = child->next) | |
| 2184 { | |
| 2185 if(GAIM_BLIST_NODE_IS_BUDDY(child) && buddy_is_displayable((GaimBuddy*)child)) { | |
| 2186 struct tooltip_data *td = create_tip_for_node(child); | |
| 2187 gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td); | |
| 11892 | 2188 w = MAX(w, td->width); |
| 2189 h += td->height; | |
| 11890 | 2190 } |
| 2191 } | |
| 2192 } else { | |
| 2193 gtk_widget_destroy(gtkblist->tipwindow); | |
| 11892 | 2194 gtkblist->tipwindow = NULL; |
| 5234 | 2195 return FALSE; |
| 11890 | 2196 } |
| 2197 | |
| 2198 if (gtkblist->tooltipdata == NULL) { | |
| 2199 gtk_widget_destroy(gtkblist->tipwindow); | |
| 11892 | 2200 gtkblist->tipwindow = NULL; |
| 11890 | 2201 return FALSE; |
| 2202 } | |
| 5228 | 2203 |
| 7636 | 2204 gtknode = node->ui_data; |
| 2205 | |
| 5234 | 2206 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); |
| 2207 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); | |
| 2208 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); | |
| 2209 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", | |
| 11890 | 2210 G_CALLBACK(gaim_gtk_blist_paint_tip), NULL); |
| 5234 | 2211 gtk_widget_ensure_style (gtkblist->tipwindow); |
| 7837 | 2212 |
| 9773 | 2213 |
| 9869 | 2214 #if GTK_CHECK_VERSION(2,2,0) |
| 9773 | 2215 gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, NULL); |
| 2216 mon_num = gdk_screen_get_monitor_at_point(screen, x, y); | |
| 2217 gdk_screen_get_monitor_geometry(screen, mon_num, &mon_size); | |
| 2218 | |
| 2219 scr_w = mon_size.width + mon_size.x; | |
| 2220 scr_h = mon_size.height + mon_size.y; | |
| 9869 | 2221 #else |
| 2222 scr_w = gdk_screen_width(); | |
| 2223 scr_h = gdk_screen_height(); | |
| 2224 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
| 2225 mon_size.x = 0; | |
| 2226 mon_size.y = 0; | |
| 2227 #endif | |
| 9773 | 2228 |
| 9869 | 2229 #if GTK_CHECK_VERSION(2,2,0) |
| 10046 | 2230 if (w > mon_size.width) |
| 9773 | 2231 w = mon_size.width - 10; |
| 2232 | |
| 10046 | 2233 if (h > mon_size.height) |
| 9773 | 2234 h = mon_size.height - 10; |
| 9869 | 2235 #endif |
| 9773 | 2236 |
| 5234 | 2237 if (GTK_WIDGET_NO_WINDOW(gtkblist->window)) |
| 2238 y+=gtkblist->window->allocation.y; | |
| 2239 | |
| 2240 x -= ((w >> 1) + 4); | |
| 5228 | 2241 |
| 7636 | 2242 if ((y + h + 4) > scr_h || tooltip_top) |
| 7620 | 2243 y = y - h - 5; |
| 5234 | 2244 else |
| 2245 y = y + 6; | |
| 7620 | 2246 |
| 9773 | 2247 if (y < mon_size.y) |
| 2248 y = mon_size.y; | |
| 2249 | |
| 2250 if (y != mon_size.y) { | |
| 7719 | 2251 if ((x + w) > scr_w) |
| 2252 x -= (x + w + 5) - scr_w; | |
| 9773 | 2253 else if (x < mon_size.x) |
| 2254 x = mon_size.x; | |
| 7719 | 2255 } else { |
| 2256 x -= (w / 2 + 10); | |
| 9773 | 2257 if (x < mon_size.x) |
| 2258 x = mon_size.x; | |
| 7719 | 2259 } |
| 2260 | |
| 5234 | 2261 gtk_widget_set_size_request(gtkblist->tipwindow, w, h); |
| 2262 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y); | |
| 2263 gtk_widget_show(gtkblist->tipwindow); | |
| 5228 | 2264 |
| 2265 return FALSE; | |
| 2266 } | |
| 2267 | |
| 10354 | 2268 static gboolean gaim_gtk_blist_drag_motion_cb(GtkWidget *tv, GdkDragContext *drag_context, |
| 2269 gint x, gint y, guint time, gpointer user_data) | |
| 2270 { | |
| 2271 GtkTreePath *path; | |
| 2272 int delay; | |
| 2273 | |
| 2274 delay = 500; | |
| 2275 | |
| 2276 if (gtkblist->drag_timeout) { | |
| 2277 if ((y > gtkblist->tip_rect.y) && ((y - gtkblist->tip_rect.height) < gtkblist->tip_rect.y)) | |
| 2278 return FALSE; | |
| 2279 /* We've left the cell. Remove the timeout and create a new one below */ | |
| 2280 g_source_remove(gtkblist->drag_timeout); | |
| 2281 } | |
| 2282 | |
| 2283 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), x, y, &path, NULL, NULL, NULL); | |
| 2284 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->tip_rect); | |
| 2285 | |
| 2286 if (path) | |
| 2287 gtk_tree_path_free(path); | |
| 2288 gtkblist->drag_timeout = g_timeout_add(delay, (GSourceFunc)gaim_gtk_blist_expand_timeout, tv); | |
| 2289 | |
| 2290 if (gtkblist->mouseover_contact) { | |
| 2291 if ((y < gtkblist->contact_rect.y) || ((y - gtkblist->contact_rect.height) > gtkblist->contact_rect.y)) { | |
| 2292 gaim_gtk_blist_collapse_contact_cb(NULL, gtkblist->mouseover_contact); | |
| 2293 gtkblist->mouseover_contact = NULL; | |
| 2294 } | |
| 2295 } | |
| 2296 | |
| 2297 return FALSE; | |
| 2298 } | |
| 2299 | |
| 5228 | 2300 static gboolean gaim_gtk_blist_motion_cb (GtkWidget *tv, GdkEventMotion *event, gpointer null) |
| 2301 { | |
| 2302 GtkTreePath *path; | |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2303 int delay; |
|
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2304 |
|
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2305 delay = gaim_prefs_get_int("/gaim/gtk/blist/tooltip_delay"); |
|
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2306 |
|
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2307 if (delay == 0) |
|
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2308 return FALSE; |
| 8083 | 2309 |
| 5228 | 2310 if (gtkblist->timeout) { |
| 7636 | 2311 if ((event->y > gtkblist->tip_rect.y) && ((event->y - gtkblist->tip_rect.height) < gtkblist->tip_rect.y)) |
| 5228 | 2312 return FALSE; |
| 2313 /* We've left the cell. Remove the timeout and create a new one below */ | |
| 8254 | 2314 gaim_gtk_blist_tooltip_destroy(); |
| 5228 | 2315 g_source_remove(gtkblist->timeout); |
| 2316 } | |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2317 |
| 5228 | 2318 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL); |
| 7636 | 2319 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->tip_rect); |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2320 |
| 5228 | 2321 if (path) |
| 2322 gtk_tree_path_free(path); | |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2323 gtkblist->timeout = g_timeout_add(delay, (GSourceFunc)gaim_gtk_blist_tooltip_timeout, tv); |
| 7636 | 2324 |
| 2325 if (gtkblist->mouseover_contact) { | |
| 2326 if ((event->y < gtkblist->contact_rect.y) || ((event->y - gtkblist->contact_rect.height) > gtkblist->contact_rect.y)) { | |
| 2327 gaim_gtk_blist_collapse_contact_cb(NULL, gtkblist->mouseover_contact); | |
| 2328 gtkblist->mouseover_contact = NULL; | |
| 2329 } | |
| 2330 } | |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2331 |
| 5228 | 2332 return FALSE; |
| 2333 } | |
| 2334 | |
| 2335 static void gaim_gtk_blist_leave_cb (GtkWidget *w, GdkEventCrossing *e, gpointer n) | |
| 2336 { | |
| 8083 | 2337 |
| 5228 | 2338 if (gtkblist->timeout) { |
| 2339 g_source_remove(gtkblist->timeout); | |
| 2340 gtkblist->timeout = 0; | |
| 2341 } | |
|
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
2342 |
| 10354 | 2343 if (gtkblist->drag_timeout) { |
| 2344 g_source_remove(gtkblist->drag_timeout); | |
| 2345 gtkblist->drag_timeout = 0; | |
| 2346 } | |
| 2347 | |
| 8254 | 2348 gaim_gtk_blist_tooltip_destroy(); |
| 7720 | 2349 |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2350 if (gtkblist->mouseover_contact && |
| 9811 | 2351 !((e->x > gtkblist->contact_rect.x) && (e->x < (gtkblist->contact_rect.x + gtkblist->contact_rect.width)) && |
| 2352 (e->y > gtkblist->contact_rect.y) && (e->y < (gtkblist->contact_rect.y + gtkblist->contact_rect.height)))) { | |
| 2353 gaim_gtk_blist_collapse_contact_cb(NULL, gtkblist->mouseover_contact); | |
| 7636 | 2354 gtkblist->mouseover_contact = NULL; |
| 2355 } | |
| 5228 | 2356 } |
| 2357 | |
| 2358 static void | |
| 2359 toggle_debug(void) | |
| 2360 { | |
| 7620 | 2361 gaim_prefs_set_bool("/gaim/gtk/debug/enabled", |
| 2362 !gaim_prefs_get_bool("/gaim/gtk/debug/enabled")); | |
| 5228 | 2363 } |
| 2364 | |
| 2365 | |
| 2366 /*************************************************** | |
| 2367 * Crap * | |
| 2368 ***************************************************/ | |
| 2369 static GtkItemFactoryEntry blist_menu[] = | |
| 2370 { | |
| 2371 /* Buddies menu */ | |
| 2372 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, | |
| 9714 | 2373 { N_("/Buddies/New Instant _Message..."), "<CTL>M", gaim_gtkdialogs_im, 0, "<StockItem>", GAIM_STOCK_IM }, |
| 8940 | 2374 { N_("/Buddies/Join a _Chat..."), "<CTL>C", gaim_gtk_blist_joinchat_show, 0, "<StockItem>", GAIM_STOCK_CHAT }, |
| 9714 | 2375 { N_("/Buddies/Get User _Info..."), "<CTL>I", gaim_gtkdialogs_info, 0, "<StockItem>", GAIM_STOCK_INFO }, |
| 2376 { N_("/Buddies/View User _Log..."), "<CTL>L", gaim_gtkdialogs_log, 0, NULL }, | |
| 5228 | 2377 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" }, |
| 11025 | 2378 { N_("/Buddies/Show _Offline Buddies"), NULL, gaim_gtk_blist_edit_mode_cb, 1, "<CheckItem>"}, |
| 2379 { N_("/Buddies/Show _Empty Groups"), NULL, gaim_gtk_blist_show_empty_groups_cb, 1, "<CheckItem>"}, | |
| 11796 | 2380 { N_("/Buddies/Show Buddy _Details"), NULL, gaim_gtk_blist_buddy_details_cb, 1, "<CheckItem>"}, |
|
11798
01c3eec6ea3c
[gaim-migrate @ 14089]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11797
diff
changeset
|
2381 { N_("/Buddies/Sort Buddies"), NULL, NULL, 0, "<Branch>" }, |
| 11796 | 2382 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" }, |
| 7853 | 2383 { N_("/Buddies/_Add Buddy..."), "<CTL>B", gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD }, |
| 2384 { N_("/Buddies/Add C_hat..."), NULL, gaim_gtk_blist_add_chat_cb, 0, "<StockItem>", GTK_STOCK_ADD }, | |
| 2385 { N_("/Buddies/Add _Group..."), NULL, gaim_blist_request_add_group, 0, "<StockItem>", GTK_STOCK_ADD }, | |
| 11796 | 2386 { "/Buddies/sep3", NULL, NULL, 0, "<Separator>" }, |
| 7620 | 2387 { N_("/Buddies/_Quit"), "<CTL>Q", gaim_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT }, |
| 5228 | 2388 |
|
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2389 /* Tools */ |
| 5228 | 2390 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, |
| 2391 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" }, | |
| 8845 | 2392 { N_("/Tools/Account Ac_tions"), NULL, NULL, 0, "<Branch>" }, |
| 5228 | 2393 { "/Tools/sep1", NULL, NULL, 0, "<Separator>" }, |
| 7620 | 2394 { N_("/Tools/A_ccounts"), "<CTL>A", gaim_gtk_accounts_window_show, 0, "<StockItem>", GAIM_STOCK_ACCOUNTS }, |
| 10325 | 2395 { N_("/Tools/Pr_eferences"), "<CTL>P", gaim_gtk_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES }, |
| 11740 | 2396 { N_("/Tools/P_lugins"), NULL, gaim_gtk_plugin_dialog_show, 0, NULL }, |
| 10694 | 2397 { N_("/Tools/Pr_ivacy"), NULL, gaim_gtk_privacy_dialog_show, 0, "<StockItem>", GTK_STOCK_DIALOG_ERROR }, |
|
10019
8cc6f0bfa215
[gaim-migrate @ 10943]
Luke Schierer <lschiere@pidgin.im>
parents:
10018
diff
changeset
|
2398 { N_("/Tools/_File Transfers"), "<CTL>T", gaim_show_xfer_dialog, 0, "<StockItem>", GAIM_STOCK_FILE_TRANSFER }, |
| 10694 | 2399 { N_("/Tools/R_oom List"), NULL, gaim_gtk_roomlist_dialog_show, 0, "<StockItem>", GTK_STOCK_INDEX }, |
| 10325 | 2400 { "/Tools/sep2", NULL, NULL, 0, "<Separator>" }, |
| 10074 | 2401 { N_("/Tools/Mute _Sounds"), "<CTL>S", gaim_gtk_blist_mute_sounds_cb, 0, "<CheckItem>"}, |
| 7620 | 2402 { N_("/Tools/View System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, NULL }, |
| 5228 | 2403 |
| 2404 /* Help */ | |
| 2405 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, | |
| 2406 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP }, | |
| 7620 | 2407 { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, NULL }, |
| 9753 | 2408 { N_("/Help/_About"), NULL, gaim_gtkdialogs_about, 0, "<StockItem>", GAIM_STOCK_ABOUT }, |
| 5228 | 2409 }; |
| 2410 | |
| 2411 /********************************************************* | |
| 2412 * Private Utility functions * | |
| 2413 *********************************************************/ | |
| 2414 | |
| 5234 | 2415 static char *gaim_get_tooltip_text(GaimBlistNode *node) |
| 5228 | 2416 { |
| 10475 | 2417 GString *str = g_string_new(""); |
| 5237 | 2418 GaimPlugin *prpl; |
| 2419 GaimPluginProtocolInfo *prpl_info = NULL; | |
| 10475 | 2420 char *tmp; |
| 2421 | |
| 2422 if (GAIM_BLIST_NODE_IS_CHAT(node)) | |
| 2423 { | |
| 2424 GaimChat *chat; | |
| 2425 GList *cur; | |
| 5274 | 2426 struct proto_chat_entry *pce; |
| 10475 | 2427 char *name, *value; |
| 2428 | |
| 2429 chat = (GaimChat *)node; | |
| 7956 | 2430 prpl = gaim_find_prpl(gaim_account_get_protocol_id(chat->account)); |
| 5274 | 2431 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
| 2432 | |
| 10475 | 2433 tmp = g_markup_escape_text(gaim_chat_get_name(chat), -1); |
| 2434 g_string_append_printf(str, "<span size='larger' weight='bold'>%s</span>", tmp); | |
| 2435 g_free(tmp); | |
| 2436 | |
| 2437 if (g_list_length(gaim_connections_get_all()) > 1) | |
| 2438 { | |
| 2439 tmp = g_markup_escape_text(chat->account->username, -1); | |
| 2440 g_string_append_printf(str, _("\n<b>Account:</b> %s"), tmp); | |
| 2441 g_free(tmp); | |
| 2442 } | |
| 2443 | |
| 9959 | 2444 if (prpl_info->chat_info != NULL) |
| 10475 | 2445 cur = prpl_info->chat_info(chat->account->gc); |
| 2446 else | |
| 2447 cur = NULL; | |
| 2448 | |
| 2449 while (cur != NULL) | |
| 2450 { | |
| 2451 pce = cur->data; | |
| 2452 | |
| 2453 if (!pce->secret && (!pce->required && | |
| 2454 g_hash_table_lookup(chat->components, pce->identifier) == NULL)) | |
| 2455 { | |
| 2456 tmp = gaim_text_strip_mnemonic(pce->label); | |
| 2457 name = g_markup_escape_text(tmp, -1); | |
| 2458 g_free(tmp); | |
| 2459 value = g_markup_escape_text(g_hash_table_lookup( | |
| 2460 chat->components, pce->identifier), -1); | |
|
10924
7a82d86ab44a
[gaim-migrate @ 12695]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10918
diff
changeset
|
2461 g_string_append_printf(str, "\n<b>%s</b> %s", |
|
7a82d86ab44a
[gaim-migrate @ 12695]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10918
diff
changeset
|
2462 name ? name : "", |
|
7a82d86ab44a
[gaim-migrate @ 12695]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10918
diff
changeset
|
2463 value ? value : ""); |
| 10475 | 2464 g_free(name); |
| 8020 | 2465 g_free(value); |
| 2466 } | |
| 10475 | 2467 |
| 5274 | 2468 g_free(pce); |
| 10475 | 2469 cur = g_list_remove(cur, pce); |
| 5274 | 2470 } |
| 10475 | 2471 } |
| 2472 else if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) | |
| 2473 { | |
| 2474 GaimContact *c; | |
| 7620 | 2475 GaimBuddy *b; |
| 9944 | 2476 GaimPresence *presence; |
| 10475 | 2477 char *tmp; |
| 9944 | 2478 gboolean idle; |
| 10567 | 2479 time_t idle_secs, signon; |
| 10475 | 2480 |
| 2481 if (GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 2482 { | |
| 2483 c = (GaimContact *)node; | |
| 2484 b = gaim_contact_get_priority_buddy(c); | |
| 2485 } | |
| 2486 else | |
| 2487 { | |
| 7620 | 2488 b = (GaimBuddy *)node; |
| 10475 | 2489 c = gaim_buddy_get_contact(b); |
| 7620 | 2490 } |
| 2491 | |
| 7956 | 2492 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
| 5234 | 2493 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
| 2494 | |
| 10475 | 2495 presence = gaim_buddy_get_presence(b); |
| 2496 | |
| 2497 /* Buddy Name */ | |
| 2498 tmp = g_markup_escape_text(gaim_buddy_get_name(b), -1); | |
| 2499 g_string_append_printf(str, "<span size='larger' weight='bold'>%s</span>", tmp); | |
| 2500 g_free(tmp); | |
| 2501 | |
| 2502 /* Account */ | |
| 2503 if (g_list_length(gaim_connections_get_all()) > 1) | |
| 2504 { | |
| 2505 tmp = g_markup_escape_text(gaim_account_get_username( | |
| 2506 gaim_buddy_get_account(b)), -1); | |
| 2507 g_string_append_printf(str, _("\n<b>Account:</b> %s"), tmp); | |
| 2508 g_free(tmp); | |
| 2509 } | |
| 2510 | |
| 2511 /* Contact Alias */ | |
| 2512 if (GAIM_BLIST_NODE_IS_CONTACT(node) && | |
| 10499 | 2513 (c->alias != NULL)) |
| 10475 | 2514 { |
| 10499 | 2515 tmp = g_markup_escape_text(c->alias, -1); |
| 10475 | 2516 g_string_append_printf(str, _("\n<b>Contact Alias:</b> %s"), tmp); |
| 2517 g_free(tmp); | |
| 2518 } | |
| 2519 | |
| 2520 /* Alias */ | |
| 2521 if ((b->alias != NULL) && (b->alias[0] != '\0')) | |
| 2522 { | |
| 2523 tmp = g_markup_escape_text(b->alias, -1); | |
| 2524 g_string_append_printf(str, _("\n<b>Alias:</b> %s"), tmp); | |
| 2525 g_free(tmp); | |
| 2526 } | |
| 2527 | |
| 2528 /* Nickname/Server Alias */ | |
| 2529 if (b->server_alias != NULL) | |
| 2530 { | |
| 2531 tmp = g_markup_escape_text(b->server_alias, -1); | |
| 2532 g_string_append_printf(str, _("\n<b>Nickname:</b> %s"), tmp); | |
| 2533 g_free(tmp); | |
| 2534 } | |
| 2535 | |
| 2536 /* Logged In */ | |
| 10567 | 2537 signon = gaim_presence_get_login_time(presence); |
|
10992
2bda44d66641
[gaim-migrate @ 12830]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10968
diff
changeset
|
2538 if (GAIM_BUDDY_IS_ONLINE(b) && signon > 0) |
| 10475 | 2539 { |
| 10567 | 2540 tmp = gaim_str_seconds_to_string(time(NULL) - signon); |
| 10475 | 2541 g_string_append_printf(str, _("\n<b>Logged In:</b> %s"), tmp); |
| 2542 g_free(tmp); | |
| 2543 } | |
| 2544 | |
| 2545 /* Idle */ | |
| 2546 idle = gaim_presence_is_idle(presence); | |
| 2547 if (idle) | |
| 2548 { | |
| 2549 idle_secs = gaim_presence_get_idle_time(presence); | |
| 2550 if (idle_secs > 0) | |
| 2551 { | |
| 2552 tmp = gaim_str_seconds_to_string(time(NULL) - idle_secs); | |
| 2553 g_string_append_printf(str, _("\n<b>Idle:</b> %s"), tmp); | |
| 2554 g_free(tmp); | |
| 2555 } | |
| 2556 } | |
| 2557 | |
| 2558 /* Last Seen */ | |
| 11910 | 2559 if (!GAIM_BUDDY_IS_ONLINE(b)) |
| 10475 | 2560 { |
| 11023 | 2561 struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode *)c)->ui_data; |
| 2562 GaimBlistNode *bnode; | |
| 2563 int lastseen = 0; | |
| 2564 | |
| 2565 if (!gtknode->contact_expanded || GAIM_BLIST_NODE_IS_CONTACT(node)) | |
| 2566 { | |
|
11437
1c20849fc716
[gaim-migrate @ 13674]
Richard Laager <rlaager@wiktel.com>
parents:
11436
diff
changeset
|
2567 /* We're either looking at a buddy for a collapsed contact or |
|
11438
5451fe2d89c0
[gaim-migrate @ 13675]
Richard Laager <rlaager@wiktel.com>
parents:
11437
diff
changeset
|
2568 * an expanded contact itself so we show the most recent |
| 11023 | 2569 * (largest) last_seen time for any of the buddies under |
| 2570 * the contact. */ | |
| 2571 for (bnode = ((GaimBlistNode *)c)->child ; bnode != NULL ; bnode = bnode->next) | |
| 2572 { | |
| 2573 int value = gaim_blist_node_get_int(bnode, "last_seen"); | |
| 2574 if (value > lastseen) | |
| 2575 lastseen = value; | |
| 2576 } | |
| 2577 } | |
| 2578 else | |
| 2579 { | |
| 2580 /* We're dealing with a buddy under an expanded contact, | |
| 2581 * so we show the last_seen time for the buddy. */ | |
| 2582 lastseen = gaim_blist_node_get_int(&b->node, "last_seen"); | |
| 2583 } | |
| 2584 | |
| 10475 | 2585 if (lastseen > 0) |
| 2586 { | |
| 2587 tmp = gaim_str_seconds_to_string(time(NULL) - lastseen); | |
| 2588 g_string_append_printf(str, _("\n<b>Last Seen:</b> %s ago"), tmp); | |
| 2589 g_free(tmp); | |
| 5234 | 2590 } |
| 2591 } | |
| 2592 | |
| 10475 | 2593 |
| 2594 /* Offline? */ | |
| 2595 if (!GAIM_BUDDY_IS_ONLINE(b)) { | |
| 2596 g_string_append_printf(str, _("\n<b>Status:</b> Offline")); | |
| 2597 } | |
|
10992
2bda44d66641
[gaim-migrate @ 12830]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10968
diff
changeset
|
2598 |
|
2bda44d66641
[gaim-migrate @ 12830]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10968
diff
changeset
|
2599 if (prpl_info && prpl_info->tooltip_text) |
| 10475 | 2600 { |
| 2601 /* Additional text from the PRPL */ | |
| 2602 const char *end; | |
| 2603 tmp = prpl_info->tooltip_text(b); | |
| 2604 | |
| 2605 if (tmp && !g_utf8_validate(tmp, -1, &end)) | |
| 2606 { | |
| 2607 char *new = g_strndup(tmp, g_utf8_pointer_to_offset(tmp, end)); | |
| 2608 g_free(tmp); | |
| 2609 tmp = new; | |
| 2610 } | |
| 2611 | |
| 11634 | 2612 if (tmp != NULL) |
| 2613 g_string_append(str, tmp); | |
| 10476 | 2614 g_free(tmp); |
| 10475 | 2615 } |
| 2616 | |
| 2617 /* These are Easter Eggs. Patches to remove them will be rejected. */ | |
| 2618 if (!g_ascii_strcasecmp(b->name, "robflynn")) | |
| 2619 g_string_append(str, _("\n<b>Description:</b> Spooky")); | |
| 2620 if (!g_ascii_strcasecmp(b->name, "seanegn")) | |
| 2621 g_string_append(str, _("\n<b>Status:</b> Awesome")); | |
| 2622 if (!g_ascii_strcasecmp(b->name, "chipx86")) | |
| 2623 g_string_append(str, _("\n<b>Status:</b> Rockin'")); | |
| 5234 | 2624 } |
| 10475 | 2625 |
| 8824 | 2626 gaim_signal_emit(gaim_gtk_blist_get_handle(), |
| 10477 | 2627 "drawing-tooltip", node, str); |
| 10475 | 2628 |
| 2629 return g_string_free(str, FALSE); | |
| 5228 | 2630 } |
| 2631 | |
| 7620 | 2632 struct _emblem_data { |
| 9954 | 2633 const char *filename; |
| 7620 | 2634 int x; |
| 2635 int y; | |
| 2636 }; | |
| 2637 | |
| 9944 | 2638 GdkPixbuf * |
| 2639 gaim_gtk_blist_get_status_icon(GaimBlistNode *node, GaimStatusIconSize size) | |
| 5228 | 2640 { |
| 7620 | 2641 GdkPixbuf *scale, *status = NULL; |
| 2642 int i, scalesize = 30; | |
| 2643 char *filename; | |
| 5228 | 2644 const char *protoname = NULL; |
| 7620 | 2645 struct _gaim_gtk_blist_node *gtknode = node->ui_data; |
| 11910 | 2646 struct _gaim_gtk_blist_node *gtkbuddynode = NULL; |
| 7620 | 2647 struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15}, |
| 2648 {NULL, 0, 0}, {NULL, 15, 0}}; | |
| 9944 | 2649 GaimPresence *presence = NULL; |
| 7620 | 2650 GaimBuddy *buddy = NULL; |
| 2651 GaimChat *chat = NULL; | |
| 2652 | |
| 2653 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
| 11910 | 2654 if(!gtknode->contact_expanded) { |
| 7620 | 2655 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); |
| 11910 | 2656 gtkbuddynode = ((GaimBlistNode*)buddy)->ui_data; |
| 2657 } | |
| 7620 | 2658 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
| 2659 buddy = (GaimBuddy*)node; | |
| 11910 | 2660 gtkbuddynode = node->ui_data; |
| 7620 | 2661 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { |
| 2662 chat = (GaimChat*)node; | |
| 2663 } else { | |
| 5228 | 2664 return NULL; |
| 5234 | 2665 } |
| 2666 | |
| 7620 | 2667 if(buddy || chat) { |
| 2668 GaimAccount *account; | |
| 2669 GaimPlugin *prpl; | |
| 2670 GaimPluginProtocolInfo *prpl_info; | |
| 2671 | |
| 2672 if(buddy) | |
| 2673 account = buddy->account; | |
| 2674 else | |
| 2675 account = chat->account; | |
| 2676 | |
| 7956 | 2677 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
| 7620 | 2678 if(!prpl) |
| 2679 return NULL; | |
| 2680 | |
| 2681 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
| 2682 | |
| 2683 if(prpl_info && prpl_info->list_icon) { | |
| 2684 protoname = prpl_info->list_icon(account, buddy); | |
| 2685 } | |
| 2686 if(prpl_info && prpl_info->list_emblems && buddy) { | |
| 11924 | 2687 if(gtknode && !gtknode->recent_signonoff) |
| 7620 | 2688 prpl_info->list_emblems(buddy, &emblems[0].filename, |
| 2689 &emblems[1].filename, &emblems[2].filename, | |
| 2690 &emblems[3].filename); | |
| 2691 } | |
| 5234 | 2692 } |
| 5228 | 2693 |
| 7620 | 2694 if(size == GAIM_STATUS_ICON_SMALL) { |
| 5228 | 2695 scalesize = 15; |
| 7620 | 2696 /* So that only the se icon will composite */ |
| 2697 emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL; | |
| 5228 | 2698 } |
| 2699 | |
| 11917 | 2700 if(buddy && GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { |
| 7620 | 2701 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); |
| 11917 | 2702 } else if(buddy && !GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { |
| 7620 | 2703 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL); |
| 2704 } else if(buddy || chat) { | |
| 5228 | 2705 char *image = g_strdup_printf("%s.png", protoname); |
| 2706 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
| 2707 g_free(image); | |
| 7620 | 2708 } else { |
| 2709 /* gaim dude */ | |
| 2710 filename = g_build_filename(DATADIR, "pixmaps", "gaim.png", NULL); | |
| 5228 | 2711 } |
| 7620 | 2712 |
| 2713 status = gdk_pixbuf_new_from_file(filename, NULL); | |
| 2714 g_free(filename); | |
| 2715 | |
| 2716 if(!status) | |
| 2717 return NULL; | |
| 2718 | |
| 2719 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, | |
| 2720 GDK_INTERP_BILINEAR); | |
| 2721 g_object_unref(status); | |
| 2722 | |
| 2723 for(i=0; i<4; i++) { | |
| 2724 if(emblems[i].filename) { | |
| 2725 GdkPixbuf *emblem; | |
| 2726 char *image = g_strdup_printf("%s.png", emblems[i].filename); | |
| 2727 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
| 2728 g_free(image); | |
| 2729 emblem = gdk_pixbuf_new_from_file(filename, NULL); | |
| 2730 g_free(filename); | |
| 2731 if(emblem) { | |
| 2732 if(i == 0 && size == GAIM_STATUS_ICON_SMALL) { | |
| 2733 gdk_pixbuf_composite(emblem, | |
| 2734 scale, 5, 5, | |
| 2735 10, 10, | |
| 2736 5, 5, | |
| 2737 .6, .6, | |
| 2738 GDK_INTERP_BILINEAR, | |
| 2739 255); | |
| 2740 } else { | |
| 2741 gdk_pixbuf_composite(emblem, | |
| 2742 scale, emblems[i].x, emblems[i].y, | |
| 2743 15, 15, | |
| 2744 emblems[i].x, emblems[i].y, | |
| 2745 1, 1, | |
| 2746 GDK_INTERP_BILINEAR, | |
| 2747 255); | |
| 2748 } | |
| 2749 g_object_unref(emblem); | |
| 2750 } | |
| 5228 | 2751 } |
| 2752 } | |
| 7620 | 2753 |
| 2754 if(buddy) { | |
| 9944 | 2755 presence = gaim_buddy_get_presence(buddy); |
| 2756 | |
| 2757 if (!GAIM_BUDDY_IS_ONLINE(buddy)) | |
| 7620 | 2758 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); |
| 10118 | 2759 else if (gaim_presence_is_idle(presence)) |
| 9944 | 2760 { |
| 7620 | 2761 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.25, FALSE); |
| 9944 | 2762 } |
|
11111
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2763 |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2764 if (!gaim_privacy_check(buddy->account, gaim_buddy_get_name(buddy))) |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2765 { |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2766 GdkPixbuf *emblem; |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2767 char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "blocked.png", NULL); |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2768 |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2769 emblem = gdk_pixbuf_new_from_file(filename, NULL); |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2770 g_free(filename); |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2771 |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2772 if (emblem) |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2773 { |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2774 gdk_pixbuf_composite(emblem, scale, |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2775 0, 0, scalesize, scalesize, |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2776 0, 0, |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2777 (double)scalesize / gdk_pixbuf_get_width(emblem), |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2778 (double)scalesize / gdk_pixbuf_get_height(emblem), |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2779 GDK_INTERP_BILINEAR, |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2780 224); |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2781 g_object_unref(emblem); |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2782 } |
|
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2783 } |
| 5228 | 2784 } |
| 7620 | 2785 |
| 5228 | 2786 return scale; |
| 2787 } | |
| 2788 | |
| 7620 | 2789 static gchar *gaim_gtk_blist_get_name_markup(GaimBuddy *b, gboolean selected) |
| 5228 | 2790 { |
| 7620 | 2791 const char *name; |
| 2792 char *esc, *text = NULL; | |
| 5228 | 2793 GaimPlugin *prpl; |
| 2794 GaimPluginProtocolInfo *prpl_info = NULL; | |
| 7620 | 2795 GaimContact *contact; |
| 9944 | 2796 GaimPresence *presence; |
| 7620 | 2797 struct _gaim_gtk_blist_node *gtkcontactnode = NULL; |
| 11257 | 2798 char *idletime = NULL, *statustext = NULL; |
| 5228 | 2799 time_t t; |
| 7620 | 2800 /* XXX Clean up this crap */ |
| 2801 | |
| 2802 contact = (GaimContact*)((GaimBlistNode*)b)->parent; | |
| 2803 if(contact) | |
| 2804 gtkcontactnode = ((GaimBlistNode*)contact)->ui_data; | |
| 2805 | |
| 2806 if(gtkcontactnode && !gtkcontactnode->contact_expanded && contact->alias) | |
| 2807 name = contact->alias; | |
| 2808 else | |
| 9620 | 2809 name = gaim_buddy_get_alias(b); |
| 7620 | 2810 esc = g_markup_escape_text(name, strlen(name)); |
| 2811 | |
| 7956 | 2812 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
| 5228 | 2813 |
| 2814 if (prpl != NULL) | |
| 2815 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
| 2816 | |
| 9944 | 2817 presence = gaim_buddy_get_presence(b); |
| 2818 | |
| 7620 | 2819 if (!gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { |
| 9944 | 2820 |
| 10118 | 2821 if ((gaim_presence_is_idle(presence) || !GAIM_BUDDY_IS_ONLINE(b)) && !selected) |
| 9944 | 2822 { |
| 10118 | 2823 text = g_strdup_printf("<span color='%s'>%s</span>", |
| 2824 dim_grey(), esc); | |
| 5228 | 2825 g_free(esc); |
| 2826 return text; | |
| 7620 | 2827 } |
| 9944 | 2828 else |
| 5228 | 2829 return esc; |
| 2830 } | |
| 2831 | |
|
8122
36674144c510
[gaim-migrate @ 8826]
Christian Hammond <chipx86@chipx86.com>
parents:
8113
diff
changeset
|
2832 if (prpl_info && prpl_info->status_text && b->account->gc) { |
| 5228 | 2833 char *tmp = prpl_info->status_text(b); |
| 2834 const char *end; | |
| 2835 | |
| 2836 if(tmp && !g_utf8_validate(tmp, -1, &end)) { | |
| 2837 char *new = g_strndup(tmp, | |
| 2838 g_utf8_pointer_to_offset(tmp, end)); | |
| 2839 g_free(tmp); | |
| 2840 tmp = new; | |
| 2841 } | |
| 2842 | |
| 10288 | 2843 #if !GTK_CHECK_VERSION(2,6,0) |
| 5228 | 2844 if(tmp) { |
| 2845 char buf[32]; | |
| 2846 char *c = tmp; | |
| 2847 int length = 0, vis=0; | |
| 2848 gboolean inside = FALSE; | |
| 2849 g_strdelimit(tmp, "\n", ' '); | |
| 11920 | 2850 gaim_str_strip_char(tmp, '\r'); |
| 5228 | 2851 |
| 2852 while(*c && vis < 20) { | |
| 2853 if(*c == '&') | |
| 2854 inside = TRUE; | |
| 2855 else if(*c == ';') | |
| 2856 inside = FALSE; | |
| 2857 if(!inside) | |
| 2858 vis++; | |
| 7620 | 2859 c = g_utf8_next_char(c); /* this is fun */ |
| 5228 | 2860 } |
| 2861 | |
| 7620 | 2862 length = c - tmp; |
| 2863 | |
| 5228 | 2864 if(vis == 20) |
| 2865 g_snprintf(buf, sizeof(buf), "%%.%ds...", length); | |
| 2866 else | |
| 2867 g_snprintf(buf, sizeof(buf), "%%s "); | |
| 2868 | |
| 2869 statustext = g_strdup_printf(buf, tmp); | |
| 2870 | |
| 2871 g_free(tmp); | |
| 2872 } | |
| 10288 | 2873 #else |
| 2874 statustext = tmp; | |
| 2875 #endif | |
| 5228 | 2876 } |
| 2877 | |
| 10351 | 2878 if (gaim_presence_is_idle(presence)) { |
| 9944 | 2879 time_t idle_secs = gaim_presence_get_idle_time(presence); |
| 2880 | |
| 10351 | 2881 if (idle_secs > 0) { |
| 9944 | 2882 int ihrs, imin; |
| 2883 | |
| 2884 time(&t); | |
| 2885 ihrs = (t - idle_secs) / 3600; | |
| 2886 imin = ((t - idle_secs) / 60) % 60; | |
| 2887 | |
| 2888 if (ihrs) | |
|
11134
f78e7e982cf4
[gaim-migrate @ 13195]
Richard Laager <rlaager@wiktel.com>
parents:
11111
diff
changeset
|
2889 idletime = g_strdup_printf(_("Idle (%dh %02dm) "), ihrs, imin); |
| 9944 | 2890 else |
| 2891 idletime = g_strdup_printf(_("Idle (%dm) "), imin); | |
| 2892 } | |
| 5228 | 2893 else |
| 9944 | 2894 idletime = g_strdup(_("Idle ")); |
| 5228 | 2895 } |
| 2896 | |
| 2897 if(!GAIM_BUDDY_IS_ONLINE(b) && !statustext) | |
| 7620 | 2898 statustext = g_strdup(_("Offline ")); |
| 2899 | |
| 10118 | 2900 if (gaim_presence_is_idle(presence) && !selected) { |
| 2901 text = g_strdup_printf("<span color='%s'>%s</span>\n" | |
| 11257 | 2902 "<span color='%s' size='smaller'>%s%s%s</span>", |
| 10118 | 2903 dim_grey(), esc, dim_grey(), |
| 5228 | 2904 statustext != NULL ? statustext : "", |
|
11134
f78e7e982cf4
[gaim-migrate @ 13195]
Richard Laager <rlaager@wiktel.com>
parents:
11111
diff
changeset
|
2905 (idletime != NULL && statustext != NULL) ? " - " : "", |
| 11257 | 2906 idletime != NULL ? idletime : ""); |
| 2907 } else if (statustext == NULL && idletime == NULL && GAIM_BUDDY_IS_ONLINE(b)) { | |
| 5228 | 2908 text = g_strdup(esc); |
| 2909 } else { | |
| 10118 | 2910 if (selected) |
| 2911 text = g_strdup_printf("%s\n" | |
| 11257 | 2912 "<span size='smaller'>%s%s%s</span>", esc, |
| 10118 | 2913 statustext != NULL ? statustext : "", |
|
11134
f78e7e982cf4
[gaim-migrate @ 13195]
Richard Laager <rlaager@wiktel.com>
parents:
11111
diff
changeset
|
2914 (idletime != NULL && statustext != NULL) ? " - " : "", |
| 11257 | 2915 idletime != NULL ? idletime : ""); |
| 10118 | 2916 else |
| 2917 text = g_strdup_printf("%s\n" | |
| 11257 | 2918 "<span color='%s' size='smaller'>%s%s%s</span>", esc, |
| 10144 | 2919 dim_grey(), |
| 10118 | 2920 statustext != NULL ? statustext : "", |
|
11134
f78e7e982cf4
[gaim-migrate @ 13195]
Richard Laager <rlaager@wiktel.com>
parents:
11111
diff
changeset
|
2921 (idletime != NULL && statustext != NULL) ? " - " : "", |
| 11257 | 2922 idletime != NULL ? idletime : ""); |
| 5228 | 2923 } |
| 2924 if (idletime) | |
| 2925 g_free(idletime); | |
| 2926 if (statustext) | |
| 2927 g_free(statustext); | |
| 2928 if (esc) | |
| 2929 g_free(esc); | |
| 2930 | |
| 2931 return text; | |
| 2932 } | |
| 2933 | |
| 2934 static void gaim_gtk_blist_restore_position() | |
| 2935 { | |
| 7620 | 2936 int blist_x, blist_y, blist_width, blist_height; |
| 2937 | |
| 2938 blist_width = gaim_prefs_get_int("/gaim/gtk/blist/width"); | |
| 2939 | |
| 2940 /* if the window exists, is hidden, we're saving positions, and the | |
| 2941 * position is sane... */ | |
| 2942 if (gtkblist && gtkblist->window && | |
| 2943 !GTK_WIDGET_VISIBLE(gtkblist->window) && blist_width != 0) { | |
| 2944 | |
| 2945 blist_x = gaim_prefs_get_int("/gaim/gtk/blist/x"); | |
| 2946 blist_y = gaim_prefs_get_int("/gaim/gtk/blist/y"); | |
| 2947 blist_height = gaim_prefs_get_int("/gaim/gtk/blist/height"); | |
| 2948 | |
| 5228 | 2949 /* ...check position is on screen... */ |
| 7620 | 2950 if (blist_x >= gdk_screen_width()) |
| 2951 blist_x = gdk_screen_width() - 100; | |
| 2952 else if (blist_x + blist_width < 0) | |
| 2953 blist_x = 100; | |
| 2954 | |
| 2955 if (blist_y >= gdk_screen_height()) | |
| 2956 blist_y = gdk_screen_height() - 100; | |
| 2957 else if (blist_y + blist_height < 0) | |
| 2958 blist_y = 100; | |
| 2959 | |
| 5228 | 2960 /* ...and move it back. */ |
| 7620 | 2961 gtk_window_move(GTK_WINDOW(gtkblist->window), blist_x, blist_y); |
| 2962 gtk_window_resize(GTK_WINDOW(gtkblist->window), blist_width, blist_height); | |
| 5228 | 2963 } |
| 2964 } | |
| 2965 | |
| 7620 | 2966 static gboolean gaim_gtk_blist_refresh_timer(GaimBuddyList *list) |
| 5228 | 2967 { |
| 7620 | 2968 GaimBlistNode *gnode, *cnode; |
| 2969 | |
| 2970 for(gnode = list->root; gnode; gnode = gnode->next) { | |
| 2971 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
| 5234 | 2972 continue; |
| 7620 | 2973 for(cnode = gnode->child; cnode; cnode = cnode->next) { |
| 2974 if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { | |
| 9944 | 2975 GaimBuddy *buddy; |
| 2976 | |
| 2977 buddy = gaim_contact_get_priority_buddy((GaimContact*)cnode); | |
| 10012 | 2978 |
| 2979 if (buddy && | |
| 2980 gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) | |
| 9944 | 2981 gaim_gtk_blist_update(list, cnode); |
| 7620 | 2982 } |
| 5228 | 2983 } |
| 2984 } | |
| 2985 | |
| 2986 /* keep on going */ | |
| 2987 return TRUE; | |
| 2988 } | |
| 2989 | |
| 7620 | 2990 static void gaim_gtk_blist_hide_node(GaimBuddyList *list, GaimBlistNode *node) |
| 5260 | 2991 { |
| 2992 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
| 2993 GtkTreeIter iter; | |
| 2994 | |
| 2995 if (!gtknode || !gtknode->row || !gtkblist) | |
| 2996 return; | |
| 2997 | |
| 2998 if(gtkblist->selected_node == node) | |
| 2999 gtkblist->selected_node = NULL; | |
| 3000 | |
| 3001 if (get_iter_from_node(node, &iter)) { | |
| 3002 gtk_tree_store_remove(gtkblist->treemodel, &iter); | |
| 7620 | 3003 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node) |
| 3004 || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
| 5260 | 3005 gaim_gtk_blist_update(list, node->parent); |
| 3006 } | |
| 3007 } | |
| 3008 gtk_tree_row_reference_free(gtknode->row); | |
| 3009 gtknode->row = NULL; | |
| 3010 } | |
| 3011 | |
| 10352 | 3012 static const char *require_connection[] = |
| 7620 | 3013 { |
| 10352 | 3014 N_("/Buddies/New Instant Message..."), |
| 3015 N_("/Buddies/Join a Chat..."), | |
| 3016 N_("/Buddies/Get User Info..."), | |
| 3017 N_("/Buddies/Add Buddy..."), | |
| 3018 N_("/Buddies/Add Chat..."), | |
| 3019 N_("/Buddies/Add Group..."), | |
| 3020 }; | |
| 3021 | |
| 10357 | 3022 static const int require_connection_size = sizeof(require_connection) |
| 3023 / sizeof(*require_connection); | |
| 10352 | 3024 |
| 3025 /** | |
| 3026 * Rebuild dynamic menus and make menu items sensitive/insensitive | |
| 3027 * where appropriate. | |
| 3028 */ | |
| 3029 static void | |
| 3030 update_menu_bar(GaimGtkBuddyList *gtkblist) | |
| 3031 { | |
| 8937 | 3032 GtkWidget *widget; |
| 10352 | 3033 gboolean sensitive; |
| 3034 int i; | |
| 3035 | |
| 3036 g_return_if_fail(gtkblist != NULL); | |
|
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3037 |
| 7620 | 3038 gaim_gtk_blist_update_protocol_actions(); |
| 8235 | 3039 gaim_gtkpounce_menu_build(gtkblist->bpmenu); |
| 8937 | 3040 |
| 10352 | 3041 sensitive = (gaim_connections_get_all() != NULL); |
| 3042 | |
| 10357 | 3043 for (i = 0; i < require_connection_size; i++) |
| 10352 | 3044 { |
| 3045 widget = gtk_item_factory_get_widget(gtkblist->ift, require_connection[i]); | |
| 3046 gtk_widget_set_sensitive(widget, sensitive); | |
| 3047 } | |
| 3048 | |
| 8940 | 3049 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Join a Chat...")); |
| 3050 gtk_widget_set_sensitive(widget, gaim_gtk_blist_joinchat_is_showable()); | |
| 3051 | |
| 8937 | 3052 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Room List")); |
| 8939 | 3053 gtk_widget_set_sensitive(widget, gaim_gtk_roomlist_is_showable()); |
| 8938 | 3054 |
| 3055 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Privacy")); | |
| 3056 gtk_widget_set_sensitive(widget, gaim_gtk_privacy_is_showable()); | |
| 7620 | 3057 } |
| 3058 | |
| 10352 | 3059 static void |
| 3060 sign_on_off_cb(GaimConnection *gc, GaimBuddyList *blist) | |
| 3061 { | |
| 3062 GaimGtkBuddyList *gtkblist = GAIM_GTK_BLIST(blist); | |
| 3063 | |
| 3064 update_menu_bar(gtkblist); | |
| 3065 } | |
| 8986 | 3066 |
| 3067 static void | |
| 3068 plugin_changed_cb(GaimPlugin *p, gpointer *data) | |
| 3069 { | |
| 3070 gaim_gtk_blist_update_plugin_actions(); | |
| 3071 } | |
| 3072 | |
| 5228 | 3073 /********************************************************************************** |
| 3074 * Public API Functions * | |
| 3075 **********************************************************************************/ | |
| 9774 | 3076 |
| 7620 | 3077 static void gaim_gtk_blist_new_list(GaimBuddyList *blist) |
| 5228 | 3078 { |
| 7620 | 3079 GaimGtkBuddyList *gtkblist; |
| 3080 | |
| 3081 gtkblist = g_new0(GaimGtkBuddyList, 1); | |
| 3082 blist->ui_data = gtkblist; | |
| 5228 | 3083 } |
| 3084 | |
| 5256 | 3085 static void gaim_gtk_blist_new_node(GaimBlistNode *node) |
| 3086 { | |
| 3087 node->ui_data = g_new0(struct _gaim_gtk_blist_node, 1); | |
| 3088 } | |
| 3089 | |
| 11018 | 3090 gboolean gaim_gtk_blist_node_is_contact_expanded(GaimBlistNode *node) |
| 3091 { | |
| 3092 if GAIM_BLIST_NODE_IS_BUDDY(node) | |
| 3093 node = node->parent; | |
| 3094 | |
| 3095 g_return_val_if_fail(GAIM_BLIST_NODE_IS_CONTACT(node), FALSE); | |
| 3096 | |
| 3097 return ((struct _gaim_gtk_blist_node *)node->ui_data)->contact_expanded; | |
| 3098 } | |
| 3099 | |
| 5228 | 3100 void gaim_gtk_blist_update_columns() |
| 3101 { | |
| 3102 if(!gtkblist) | |
| 3103 return; | |
| 3104 | |
| 7620 | 3105 if (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { |
| 5228 | 3106 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, TRUE); |
| 3107 gtk_tree_view_column_set_visible(gtkblist->idle_column, FALSE); | |
| 3108 } else { | |
| 10351 | 3109 gtk_tree_view_column_set_visible(gtkblist->idle_column, TRUE); |
| 5228 | 3110 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, FALSE); |
| 3111 } | |
| 3112 } | |
| 3113 | |
| 10433 | 3114 enum { |
| 3115 DRAG_BUDDY, | |
| 3116 DRAG_ROW, | |
| 3117 DRAG_VCARD, | |
| 3118 DRAG_TEXT, | |
| 3119 DRAG_URI, | |
| 3120 NUM_TARGETS | |
| 3121 }; | |
| 5228 | 3122 |
| 3123 static char * | |
| 3124 item_factory_translate_func (const char *path, gpointer func_data) | |
| 3125 { | |
| 7620 | 3126 return _((char *)path); |
| 5228 | 3127 } |
| 3128 | |
| 5422 | 3129 void gaim_gtk_blist_setup_sort_methods() |
| 3130 { | |
|
11798
01c3eec6ea3c
[gaim-migrate @ 14089]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11797
diff
changeset
|
3131 gaim_gtk_blist_sort_method_reg("none", _("Manually"), sort_method_none); |
| 7620 | 3132 #if GTK_CHECK_VERSION(2,2,1) |
|
11798
01c3eec6ea3c
[gaim-migrate @ 14089]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11797
diff
changeset
|
3133 gaim_gtk_blist_sort_method_reg("alphabetical", _("Alphabetically"), sort_method_alphabetical); |
| 7620 | 3134 gaim_gtk_blist_sort_method_reg("status", _("By status"), sort_method_status); |
| 3135 gaim_gtk_blist_sort_method_reg("log_size", _("By log size"), sort_method_log); | |
| 3136 #endif | |
| 3137 gaim_gtk_blist_sort_method_set(gaim_prefs_get_string("/gaim/gtk/blist/sort_type")); | |
| 3138 } | |
| 3139 | |
| 10433 | 3140 static void _prefs_change_redo_list() |
| 3141 { | |
| 7620 | 3142 redo_buddy_list(gaim_get_blist(), TRUE); |
| 3143 } | |
| 3144 | |
| 3145 static void _prefs_change_sort_method(const char *pref_name, GaimPrefType type, | |
| 10433 | 3146 gpointer val, gpointer data) |
| 3147 { | |
| 7620 | 3148 if(!strcmp(pref_name, "/gaim/gtk/blist/sort_type")) |
| 3149 gaim_gtk_blist_sort_method_set(val); | |
| 3150 } | |
| 3151 | |
| 10433 | 3152 /* |
| 3153 * "This is so dead sexy." | |
| 3154 * "Two thumbs up." | |
| 3155 * "Best movie of the year." | |
| 3156 * | |
| 3157 * This is the function that handles CTRL+F searching in the buddy list. | |
| 3158 * It finds the top-most buddy/group/chat/whatever containing the | |
| 3159 * entered string. | |
| 3160 * | |
| 3161 * It's somewhat ineffecient, because we strip all the HTML from the | |
| 3162 * "name" column of the buddy list (because the GtkTreeModel does not | |
| 3163 * contain the screen name in a non-markedup format). But the alternative | |
| 3164 * is to add an extra column to the GtkTreeModel. And this function is | |
| 3165 * used rarely, so it shouldn't matter TOO much. | |
| 3166 */ | |
| 3167 static gboolean | |
| 3168 _search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data) | |
| 3169 { | |
| 10435 | 3170 gboolean result; |
| 10433 | 3171 gchar *enteredstring; |
| 10439 | 3172 gchar *withmarkup; |
| 10433 | 3173 gchar *nomarkup; |
| 11490 | 3174 gchar *normalized; |
| 10435 | 3175 |
| 3176 gtk_tree_model_get(model, iter, column, &withmarkup, -1); | |
| 10433 | 3177 |
| 11490 | 3178 enteredstring = g_utf8_casefold(gaim_normalize(NULL, key), -1); |
| 10433 | 3179 nomarkup = gaim_markup_strip_html(withmarkup); |
| 11490 | 3180 normalized = g_utf8_casefold(gaim_normalize(NULL, nomarkup), -1); |
| 10433 | 3181 |
| 3182 result = (g_strstr_len(normalized, strlen(normalized), enteredstring) == NULL); | |
| 3183 | |
| 10439 | 3184 g_free(withmarkup); |
| 10433 | 3185 g_free(enteredstring); |
| 3186 g_free(nomarkup); | |
| 11490 | 3187 g_free(normalized); |
| 10433 | 3188 |
| 3189 return result; | |
| 3190 } | |
| 3191 | |
| 7620 | 3192 static void gaim_gtk_blist_show(GaimBuddyList *list) |
| 5228 | 3193 { |
| 10087 | 3194 void *handle; |
| 5228 | 3195 GtkCellRenderer *rend; |
| 3196 GtkTreeViewColumn *column; | |
|
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3197 GtkWidget *menu; |
| 5228 | 3198 GtkWidget *sw; |
| 11983 | 3199 GtkWidget *vpane; |
| 5228 | 3200 GtkAccelGroup *accel_group; |
| 3201 GtkTreeSelection *selection; | |
| 9556 | 3202 GtkTargetEntry dte[] = {{"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW}, |
| 8089 | 3203 {"application/x-im-contact", 0, DRAG_BUDDY}, |
| 9495 | 3204 {"text/x-vcard", 0, DRAG_VCARD }, |
| 9525 | 3205 {"text/uri-list", 0, DRAG_URI}, |
| 3206 {"text/plain", 0, DRAG_TEXT}}; | |
| 9556 | 3207 GtkTargetEntry ste[] = {{"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW}, |
| 3208 {"application/x-im-contact", 0, DRAG_BUDDY}, | |
| 3209 {"text/x-vcard", 0, DRAG_VCARD }}; | |
| 5228 | 3210 if (gtkblist && gtkblist->window) { |
|
11709
cae2fb7e8594
[gaim-migrate @ 14000]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11692
diff
changeset
|
3211 if (gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")) |
| 10282 | 3212 gtk_widget_show(gtkblist->window); |
| 5228 | 3213 return; |
| 3214 } | |
| 3215 | |
| 3216 gtkblist = GAIM_GTK_BLIST(list); | |
| 3217 | |
| 3218 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
| 3219 gtk_window_set_role(GTK_WINDOW(gtkblist->window), "buddy_list"); | |
| 9746 | 3220 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); |
| 5228 | 3221 |
| 3222 gtkblist->vbox = gtk_vbox_new(FALSE, 0); | |
|
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3223 gtk_widget_show(gtkblist->vbox); |
| 5228 | 3224 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); |
| 3225 | |
|
11709
cae2fb7e8594
[gaim-migrate @ 14000]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11692
diff
changeset
|
3226 g_signal_connect_after(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); |
| 5228 | 3227 g_signal_connect(G_OBJECT(gtkblist->window), "configure_event", G_CALLBACK(gtk_blist_configure_cb), NULL); |
| 3228 gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK); | |
| 3229 | |
| 3230 /******************************* Menu bar *************************************/ | |
| 3231 accel_group = gtk_accel_group_new(); | |
| 3232 gtk_window_add_accel_group(GTK_WINDOW (gtkblist->window), accel_group); | |
| 3233 g_object_unref(accel_group); | |
| 5427 | 3234 gtkblist->ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", accel_group); |
| 9811 | 3235 gtk_item_factory_set_translate_func(gtkblist->ift, |
| 3236 item_factory_translate_func, | |
| 3237 NULL, NULL); | |
| 5427 | 3238 gtk_item_factory_create_items(gtkblist->ift, sizeof(blist_menu) / sizeof(*blist_menu), |
| 9811 | 3239 blist_menu, NULL); |
| 7620 | 3240 gaim_gtk_load_accels(); |
| 3241 g_signal_connect(G_OBJECT(accel_group), "accel-changed", | |
| 3242 G_CALLBACK(gaim_gtk_save_accels_cb), NULL); | |
|
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3243 menu = gtk_item_factory_get_widget(gtkblist->ift, "<GaimMain>"); |
|
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3244 gtk_widget_show(menu); |
|
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3245 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), menu, FALSE, FALSE, 0); |
| 5228 | 3246 |
| 5427 | 3247 gtkblist->bpmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Buddy Pounce")); |
| 8844 | 3248 protomenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Account Actions")); |
| 10352 | 3249 |
| 11983 | 3250 /****************************** GtkVPaned ************************************/ |
| 3251 vpane = gtk_vpaned_new(); | |
| 3252 gtk_widget_show(vpane); | |
| 3253 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), vpane, TRUE, TRUE, 0); | |
| 3254 | |
| 5228 | 3255 /****************************** GtkTreeView **********************************/ |
| 3256 sw = gtk_scrolled_window_new(NULL,NULL); | |
|
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3257 gtk_widget_show(sw); |
| 5228 | 3258 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); |
| 3259 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
| 3260 | |
| 7620 | 3261 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, |
| 11494 | 3262 GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, |
| 11257 | 3263 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); |
| 5228 | 3264 |
| 3265 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); | |
|
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3266 gtk_widget_show(gtkblist->treeview); |
| 9176 | 3267 gtk_widget_set_name(gtkblist->treeview, "gaim_gtkblist_treeview"); |
| 5228 | 3268 |
| 3269 /* Set up selection stuff */ | |
| 3270 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
| 3271 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(gaim_gtk_blist_selection_changed), NULL); | |
| 3272 | |
| 3273 /* Set up dnd */ | |
| 7650 | 3274 gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), |
| 9811 | 3275 GDK_BUTTON1_MASK, ste, 3, |
| 3276 GDK_ACTION_COPY); | |
| 7650 | 3277 gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), |
| 9811 | 3278 dte, 5, |
| 3279 GDK_ACTION_COPY | GDK_ACTION_MOVE); | |
| 7636 | 3280 |
| 10544 | 3281 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(gaim_gtk_blist_drag_data_rcv_cb), NULL); |
| 5228 | 3282 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(gaim_gtk_blist_drag_data_get_cb), NULL); |
|
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
3283 #ifdef _WIN32 |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
3284 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-begin", G_CALLBACK(gaim_gtk_blist_drag_begin), NULL); |
|
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
3285 #endif |
| 10433 | 3286 |
| 10354 | 3287 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-motion", G_CALLBACK(gaim_gtk_blist_drag_motion_cb), NULL); |
| 5228 | 3288 |
| 3289 /* Tooltips */ | |
| 3290 g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(gaim_gtk_blist_motion_cb), NULL); | |
| 3291 g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(gaim_gtk_blist_leave_cb), NULL); | |
| 3292 | |
| 3293 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
| 3294 | |
| 11016 | 3295 gtkblist->text_column = column = gtk_tree_view_column_new (); |
| 5228 | 3296 |
| 3297 rend = gtk_cell_renderer_pixbuf_new(); | |
| 9811 | 3298 gtk_tree_view_column_pack_start(column, rend, FALSE); |
| 3299 gtk_tree_view_column_set_attributes(column, rend, | |
| 3300 "pixbuf", STATUS_ICON_COLUMN, | |
| 3301 "visible", STATUS_ICON_VISIBLE_COLUMN, | |
| 3302 NULL); | |
| 5228 | 3303 g_object_set(rend, "xalign", 0.0, "ypad", 0, NULL); |
| 3304 | |
| 11016 | 3305 gtkblist->text_rend = rend = gtk_cell_renderer_text_new(); |
| 5228 | 3306 gtk_tree_view_column_pack_start (column, rend, TRUE); |
| 9811 | 3307 gtk_tree_view_column_set_attributes(column, rend, |
| 3308 "markup", NAME_COLUMN, | |
| 3309 NULL); | |
| 11016 | 3310 g_signal_connect(G_OBJECT(rend), "edited", G_CALLBACK(gtk_blist_renderer_edited_cb), NULL); |
| 5228 | 3311 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); |
| 10285 | 3312 #if GTK_CHECK_VERSION(2,6,0) |
| 3313 gtk_tree_view_column_set_expand (column, TRUE); | |
| 10501 | 3314 g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
| 10285 | 3315 #endif |
| 5228 | 3316 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); |
| 3317 | |
| 3318 rend = gtk_cell_renderer_text_new(); | |
| 10351 | 3319 gtkblist->idle_column = gtk_tree_view_column_new_with_attributes("Idle", rend, "markup", IDLE_COLUMN, NULL); |
| 3320 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->idle_column); | |
| 5228 | 3321 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); |
| 3322 | |
| 3323 rend = gtk_cell_renderer_pixbuf_new(); | |
| 3324 gtkblist->buddy_icon_column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); | |
| 3325 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); | |
| 3326 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column); | |
| 3327 | |
| 3328 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); | |
| 3329 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-expanded", G_CALLBACK(gtk_blist_row_expanded_cb), NULL); | |
| 3330 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-collapsed", G_CALLBACK(gtk_blist_row_collapsed_cb), NULL); | |
| 3331 g_signal_connect(G_OBJECT(gtkblist->treeview), "button-press-event", G_CALLBACK(gtk_blist_button_press_cb), NULL); | |
| 7620 | 3332 g_signal_connect(G_OBJECT(gtkblist->treeview), "key-press-event", G_CALLBACK(gtk_blist_key_press_cb), NULL); |
| 8143 | 3333 g_signal_connect(G_OBJECT(gtkblist->treeview), "popup-menu", G_CALLBACK(gaim_gtk_blist_popup_menu_cb), NULL); |
| 5228 | 3334 |
| 5419 | 3335 /* Enable CTRL+F searching */ |
| 3336 gtk_tree_view_set_search_column(GTK_TREE_VIEW(gtkblist->treeview), NAME_COLUMN); | |
| 10433 | 3337 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview), _search_func, NULL, NULL); |
| 5419 | 3338 |
| 11983 | 3339 gtk_paned_pack1(GTK_PANED(vpane), sw, TRUE, FALSE); |
| 5228 | 3340 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); |
| 3341 gaim_gtk_blist_update_columns(); | |
| 3342 | |
| 11732 | 3343 /* TODO: functionize this */ |
| 3344 { | |
| 3345 GList *accounts, *l; | |
| 11983 | 3346 GtkWidget *sw2 = gtk_scrolled_window_new(NULL, NULL); |
| 3347 | |
| 11732 | 3348 /* Set up some per account status boxes */ |
| 3349 gtkblist->statusboxbox = gtk_vbox_new(FALSE, 0); | |
| 3350 gtkblist->statusboxes = NULL; | |
| 11983 | 3351 |
| 11732 | 3352 for (l = accounts = gaim_accounts_get_all_active(); l; l = l->next) { |
| 3353 GtkWidget *statusbox = gtk_gaim_status_box_new_with_account(l->data); | |
| 3354 gtkblist->statusboxes = g_list_append(gtkblist->statusboxes, statusbox); | |
| 3355 gtk_box_pack_start(GTK_BOX(gtkblist->statusboxbox), statusbox, FALSE, TRUE, 0); | |
| 3356 gtk_widget_show(statusbox); | |
| 3357 } | |
| 3358 g_list_free(accounts); | |
| 11983 | 3359 |
| 11732 | 3360 gtk_widget_show(gtkblist->statusboxbox); |
| 11983 | 3361 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw2), gtkblist->statusboxbox); |
| 3362 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); | |
| 3363 gtk_widget_show(sw2); | |
| 3364 gtk_paned_pack2(GTK_PANED(vpane), sw2, FALSE, TRUE); | |
| 11732 | 3365 |
| 3366 gtkblist->statusbox = gtk_gaim_status_box_new(); | |
| 3367 | |
| 3368 gtk_widget_show(gtkblist->statusbox); | |
| 3369 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->statusbox, FALSE, TRUE, 0); | |
| 3370 | |
| 3371 } | |
|
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3372 |
| 5228 | 3373 /* set the Show Offline Buddies option. must be done |
| 3374 * after the treeview or faceprint gets mad. -Robot101 | |
| 3375 */ | |
| 5427 | 3376 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show Offline Buddies"))), |
| 7620 | 3377 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")); |
| 5427 | 3378 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show Empty Groups"))), |
| 7620 | 3379 gaim_prefs_get_bool("/gaim/gtk/blist/show_empty_groups")); |
| 10074 | 3380 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))), |
| 3381 gaim_prefs_get_bool("/gaim/gtk/sound/mute")); | |
| 11796 | 3382 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show Buddy Details"))), |
| 11920 | 3383 gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")); |
| 10074 | 3384 if(!strcmp(gaim_prefs_get_string("/gaim/gtk/sound/method"), "none")) |
| 11494 | 3385 gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), FALSE); |
| 5228 | 3386 |
| 10353 | 3387 /* Update some dynamic things */ |
| 3388 update_menu_bar(gtkblist); | |
| 3389 gaim_gtk_blist_update_plugin_actions(); | |
| 11796 | 3390 gaim_gtk_blist_update_sort_methods(); |
| 10353 | 3391 |
| 5228 | 3392 /* OK... let's show this bad boy. */ |
|
11709
cae2fb7e8594
[gaim-migrate @ 14000]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11692
diff
changeset
|
3393 if (gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")) { |
| 10282 | 3394 gaim_gtk_blist_refresh(list); |
| 3395 gaim_gtk_blist_restore_position(); | |
| 3396 gtk_widget_show(gtkblist->window); | |
| 3397 } | |
| 5228 | 3398 |
| 3399 /* start the refresh timer */ | |
| 10351 | 3400 gtkblist->refresh_timer = g_timeout_add(30000, (GSourceFunc)gaim_gtk_blist_refresh_timer, list); |
| 10353 | 3401 |
| 10087 | 3402 handle = gaim_gtk_blist_get_handle(); |
| 3403 | |
| 7620 | 3404 /* things that affect how buddies are displayed */ |
| 10087 | 3405 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_buddy_icons", |
| 3406 _prefs_change_redo_list, NULL); | |
| 3407 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_empty_groups", | |
| 3408 _prefs_change_redo_list, NULL); | |
| 3409 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_offline_buddies", | |
| 3410 _prefs_change_redo_list, NULL); | |
| 7620 | 3411 |
| 3412 /* sorting */ | |
| 10087 | 3413 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/sort_type", |
| 3414 _prefs_change_sort_method, NULL); | |
| 7620 | 3415 |
| 3416 /* things that affect what columns are displayed */ | |
| 10087 | 3417 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_buddy_icons", |
| 3418 gaim_gtk_blist_update_columns, NULL); | |
|
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3419 |
| 10074 | 3420 /* menus */ |
| 10087 | 3421 gaim_prefs_connect_callback(handle, "/gaim/gtk/sound/mute", |
| 3422 gaim_gtk_blist_mute_pref_cb, NULL); | |
| 3423 gaim_prefs_connect_callback(handle, "/gaim/gtk/sound/method", | |
| 3424 gaim_gtk_blist_sound_method_pref_cb, NULL); | |
| 10074 | 3425 |
|
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3426 /* Setup some gaim signal handlers. */ |
| 8937 | 3427 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", |
| 3428 gtkblist, GAIM_CALLBACK(sign_on_off_cb), list); | |
| 3429 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | |
| 3430 gtkblist, GAIM_CALLBACK(sign_on_off_cb), list); | |
| 8815 | 3431 |
| 8986 | 3432 gaim_signal_connect(gaim_plugins_get_handle(), "plugin-load", |
| 3433 gtkblist, GAIM_CALLBACK(plugin_changed_cb), NULL); | |
| 3434 gaim_signal_connect(gaim_plugins_get_handle(), "plugin-unload", | |
| 3435 gtkblist, GAIM_CALLBACK(plugin_changed_cb), NULL); | |
| 3436 | |
| 8815 | 3437 /* emit our created signal */ |
| 10087 | 3438 gaim_signal_emit(handle, "gtkblist-created", list); |
| 5228 | 3439 } |
| 3440 | |
| 7620 | 3441 /* XXX: does this need fixing? */ |
| 3442 static void redo_buddy_list(GaimBuddyList *list, gboolean remove) | |
| 5228 | 3443 { |
| 7620 | 3444 GaimBlistNode *gnode, *cnode, *bnode; |
| 3445 | |
| 3446 for(gnode = list->root; gnode; gnode = gnode->next) { | |
| 3447 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
| 5234 | 3448 continue; |
| 7620 | 3449 for(cnode = gnode->child; cnode; cnode = cnode->next) { |
| 3450 if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { | |
| 3451 if(remove) | |
| 3452 gaim_gtk_blist_hide_node(list, cnode); | |
| 3453 | |
| 3454 for(bnode = cnode->child; bnode; bnode = bnode->next) { | |
| 3455 if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
| 3456 continue; | |
| 3457 if(remove) | |
| 3458 gaim_gtk_blist_hide_node(list, bnode); | |
| 3459 gaim_gtk_blist_update(list, bnode); | |
| 3460 } | |
| 3461 | |
| 3462 gaim_gtk_blist_update(list, cnode); | |
| 3463 } else if(GAIM_BLIST_NODE_IS_CHAT(cnode)) { | |
| 3464 if(remove) | |
| 3465 gaim_gtk_blist_hide_node(list, cnode); | |
| 3466 | |
| 3467 gaim_gtk_blist_update(list, cnode); | |
| 3468 } | |
| 5228 | 3469 } |
| 7620 | 3470 gaim_gtk_blist_update(list, gnode); |
| 5228 | 3471 } |
| 3472 } | |
| 3473 | |
| 7620 | 3474 void gaim_gtk_blist_refresh(GaimBuddyList *list) |
| 5422 | 3475 { |
| 3476 redo_buddy_list(list, FALSE); | |
| 3477 } | |
| 3478 | |
| 5297 | 3479 void |
| 3480 gaim_gtk_blist_update_refresh_timeout() | |
| 3481 { | |
| 7620 | 3482 GaimBuddyList *blist; |
| 3483 GaimGtkBuddyList *gtkblist; | |
| 5297 | 3484 |
| 3485 blist = gaim_get_blist(); | |
| 3486 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); | |
| 3487 | |
| 10351 | 3488 gtkblist->refresh_timer = g_timeout_add(30000,(GSourceFunc)gaim_gtk_blist_refresh_timer, blist); |
| 5297 | 3489 } |
| 3490 | |
| 5256 | 3491 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) { |
| 3492 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
| 3493 GtkTreePath *path; | |
| 5228 | 3494 |
| 5263 | 3495 if (!gtknode) { |
| 3496 return FALSE; | |
| 3497 } | |
| 3498 | |
| 3499 if (!gtkblist) { | |
| 10006 | 3500 gaim_debug_error("gtkblist", "get_iter_from_node was called, but we don't seem to have a blist\n"); |
| 5263 | 3501 return FALSE; |
| 3502 } | |
| 3503 | |
| 3504 if (!gtknode->row) | |
| 5228 | 3505 return FALSE; |
| 11494 | 3506 |
| 5228 | 3507 |
| 5256 | 3508 if ((path = gtk_tree_row_reference_get_path(gtknode->row)) == NULL) |
| 5228 | 3509 return FALSE; |
| 11016 | 3510 |
| 5256 | 3511 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), iter, path)) { |
| 3512 gtk_tree_path_free(path); | |
| 3513 return FALSE; | |
| 3514 } | |
| 3515 gtk_tree_path_free(path); | |
| 3516 return TRUE; | |
| 5228 | 3517 } |
| 3518 | |
| 7620 | 3519 static void gaim_gtk_blist_remove(GaimBuddyList *list, GaimBlistNode *node) |
| 5228 | 3520 { |
| 11910 | 3521 struct _gaim_gtk_blist_node *gtknode = node->ui_data; |
| 3522 | |
| 10222 | 3523 gaim_request_close_with_handle(node); |
| 3524 | |
| 5260 | 3525 gaim_gtk_blist_hide_node(list, node); |
| 5228 | 3526 |
| 7620 | 3527 if(node->parent) |
| 3528 gaim_gtk_blist_update(list, node->parent); | |
| 3529 | |
| 10504 | 3530 /* There's something I don't understand here - Ethan */ |
| 3531 /* Ethan said that back in 2003, but this g_free has been left commented | |
| 3532 * out ever since. I can't find any reason at all why this is bad and | |
| 3533 * valgrind found several reasons why it's good. If this causes problems | |
| 3534 * comment it out again. Stu */ | |
| 10510 | 3535 /* Of course it still causes problems - this breaks dragging buddies into |
| 10515 | 3536 * contacts, the dragged buddy mysteriously 'disappears'. Stu. */ |
| 3537 /* I think it's fixed now. Stu. */ | |
| 11910 | 3538 |
| 11915 | 3539 if(gtknode) { |
| 3540 if(gtknode->recent_signonoff_timer > 0) | |
| 3541 gaim_timeout_remove(gtknode->recent_signonoff_timer); | |
| 3542 | |
| 3543 g_free(node->ui_data); | |
| 3544 node->ui_data = NULL; | |
| 3545 } | |
| 5228 | 3546 } |
| 3547 | |
| 3548 static gboolean do_selection_changed(GaimBlistNode *new_selection) | |
| 3549 { | |
| 5254 | 3550 GaimBlistNode *old_selection = NULL; |
| 5228 | 3551 |
| 5254 | 3552 /* test for gtkblist because crazy timeout means we can be called after the blist is gone */ |
| 3553 if (gtkblist && new_selection != gtkblist->selected_node) { | |
| 3554 old_selection = gtkblist->selected_node; | |
| 5228 | 3555 gtkblist->selected_node = new_selection; |
| 3556 if(new_selection) | |
| 3557 gaim_gtk_blist_update(NULL, new_selection); | |
| 3558 if(old_selection) | |
| 3559 gaim_gtk_blist_update(NULL, old_selection); | |
| 3560 } | |
| 3561 | |
| 3562 return FALSE; | |
| 3563 } | |
| 3564 | |
| 3565 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data) | |
| 3566 { | |
| 3567 GaimBlistNode *new_selection = NULL; | |
| 3568 GtkTreeIter iter; | |
| 3569 | |
| 3570 if(gtk_tree_selection_get_selected(selection, NULL, &iter)){ | |
| 3571 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
| 3572 NODE_COLUMN, &new_selection, -1); | |
| 3573 } | |
| 5254 | 3574 |
| 5228 | 3575 /* we set this up as a timeout, otherwise the blist flickers */ |
| 3576 g_timeout_add(0, (GSourceFunc)do_selection_changed, new_selection); | |
| 3577 } | |
| 3578 | |
| 8252 | 3579 static gboolean insert_node(GaimBuddyList *list, GaimBlistNode *node, GtkTreeIter *iter) |
| 7620 | 3580 { |
| 3581 GtkTreeIter parent_iter, cur, *curptr = NULL; | |
| 3582 struct _gaim_gtk_blist_node *gtknode = node->ui_data; | |
| 5256 | 3583 GtkTreePath *newpath; |
| 7620 | 3584 |
| 10515 | 3585 if(!iter) |
| 8252 | 3586 return FALSE; |
| 7620 | 3587 |
| 3588 if(node->parent && !get_iter_from_node(node->parent, &parent_iter)) | |
| 8252 | 3589 return FALSE; |
| 7620 | 3590 |
| 3591 if(get_iter_from_node(node, &cur)) | |
| 3592 curptr = &cur; | |
| 3593 | |
| 3594 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
| 3595 *iter = current_sort_method->func(node, list, parent_iter, curptr); | |
| 3596 } else { | |
| 3597 *iter = sort_method_none(node, list, parent_iter, curptr); | |
| 5228 | 3598 } |
| 3599 | |
| 10515 | 3600 if(gtknode != NULL) { |
| 3601 gtk_tree_row_reference_free(gtknode->row); | |
| 3602 } else { | |
| 3603 gaim_gtk_blist_new_node(node); | |
| 3604 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
| 3605 } | |
| 3606 | |
| 7620 | 3607 newpath = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), |
| 3608 iter); | |
| 3609 gtknode->row = | |
| 3610 gtk_tree_row_reference_new(GTK_TREE_MODEL(gtkblist->treemodel), | |
| 3611 newpath); | |
| 11494 | 3612 |
| 5256 | 3613 gtk_tree_path_free(newpath); |
| 3614 | |
| 5228 | 3615 gtk_tree_store_set(gtkblist->treemodel, iter, |
| 3616 NODE_COLUMN, node, | |
| 3617 -1); | |
| 7620 | 3618 |
| 3619 if(node->parent) { | |
| 3620 GtkTreePath *expand = NULL; | |
| 3621 struct _gaim_gtk_blist_node *gtkparentnode = node->parent->ui_data; | |
| 3622 | |
| 3623 if(GAIM_BLIST_NODE_IS_GROUP(node->parent)) { | |
| 7693 | 3624 if(!gaim_blist_node_get_bool(node->parent, "collapsed")) |
| 7620 | 3625 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &parent_iter); |
| 3626 } else if(GAIM_BLIST_NODE_IS_CONTACT(node->parent) && | |
| 3627 gtkparentnode->contact_expanded) { | |
| 3628 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &parent_iter); | |
| 3629 } | |
| 3630 if(expand) { | |
| 7693 | 3631 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), expand, FALSE); |
| 7620 | 3632 gtk_tree_path_free(expand); |
| 3633 } | |
| 3634 } | |
| 3635 | |
| 8252 | 3636 return TRUE; |
| 5228 | 3637 } |
| 3638 | |
| 7620 | 3639 static void gaim_gtk_blist_update_group(GaimBuddyList *list, GaimBlistNode *node) |
| 3640 { | |
| 3641 GaimGroup *group; | |
| 8203 | 3642 int count; |
| 7620 | 3643 |
| 3644 g_return_if_fail(GAIM_BLIST_NODE_IS_GROUP(node)); | |
| 3645 | |
| 3646 group = (GaimGroup*)node; | |
| 3647 | |
| 8203 | 3648 if(gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) |
| 3649 count = gaim_blist_get_group_size(group, FALSE); | |
| 3650 else | |
| 3651 count = gaim_blist_get_group_online_count(group); | |
| 3652 if(gaim_prefs_get_bool("/gaim/gtk/blist/show_empty_groups") || count > 0) { | |
| 7620 | 3653 char *mark, *esc; |
| 3654 GtkTreeIter iter; | |
| 3655 | |
| 8252 | 3656 if(!insert_node(list, node, &iter)) |
| 3657 return; | |
| 7620 | 3658 |
| 3659 esc = g_markup_escape_text(group->name, -1); | |
| 8945 | 3660 mark = g_strdup_printf("<span weight='bold'>%s</span> (%d/%d)", |
| 3661 esc, gaim_blist_get_group_online_count(group), | |
| 3662 gaim_blist_get_group_size(group, FALSE)); | |
| 7620 | 3663 g_free(esc); |
| 3664 | |
| 3665 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
| 3666 STATUS_ICON_COLUMN, NULL, | |
| 3667 STATUS_ICON_VISIBLE_COLUMN, FALSE, | |
| 3668 NAME_COLUMN, mark, | |
| 3669 NODE_COLUMN, node, | |
| 3670 -1); | |
| 3671 g_free(mark); | |
| 3672 } else { | |
| 3673 gaim_gtk_blist_hide_node(list, node); | |
| 3674 } | |
| 3675 } | |
| 3676 | |
| 3677 static void buddy_node(GaimBuddy *buddy, GtkTreeIter *iter, GaimBlistNode *node) | |
| 5228 | 3678 { |
| 9944 | 3679 GaimPresence *presence; |
| 7620 | 3680 GdkPixbuf *status, *avatar; |
| 3681 char *mark; | |
| 11257 | 3682 char *idle = NULL; |
| 7620 | 3683 gboolean selected = (gtkblist->selected_node == node); |
| 3684 | |
| 9944 | 3685 presence = gaim_buddy_get_presence(buddy); |
| 3686 | |
| 7620 | 3687 status = gaim_gtk_blist_get_status_icon((GaimBlistNode*)buddy, |
| 3688 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") | |
| 3689 ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
| 3690 | |
| 10482 | 3691 avatar = gaim_gtk_blist_get_buddy_icon((GaimBlistNode *)buddy, TRUE, TRUE); |
| 7620 | 3692 mark = gaim_gtk_blist_get_name_markup(buddy, selected); |
| 3693 | |
| 9944 | 3694 if (gaim_presence_is_idle(presence)) |
| 3695 { | |
| 3696 time_t idle_secs = gaim_presence_get_idle_time(presence); | |
| 3697 | |
| 3698 if (idle_secs > 0) | |
| 3699 { | |
| 3700 time_t t; | |
| 3701 int ihrs, imin; | |
| 3702 time(&t); | |
| 3703 ihrs = (t - idle_secs) / 3600; | |
| 3704 imin = ((t - idle_secs) / 60) % 60; | |
| 3705 | |
| 3706 if (ihrs > 0) | |
| 3707 idle = g_strdup_printf("(%d:%02d)", ihrs, imin); | |
| 3708 else | |
| 3709 idle = g_strdup_printf("(%d)", imin); | |
| 3710 } | |
| 7620 | 3711 } |
| 3712 | |
| 10118 | 3713 if (gaim_presence_is_idle(presence)) |
| 9944 | 3714 { |
| 3715 if (idle && !selected) { | |
| 10118 | 3716 char *i2 = g_strdup_printf("<span color='%s'>%s</span>", |
| 3717 dim_grey(), idle); | |
| 7620 | 3718 g_free(idle); |
| 3719 idle = i2; | |
| 5228 | 3720 } |
| 7620 | 3721 } |
| 3722 | |
| 3723 gtk_tree_store_set(gtkblist->treemodel, iter, | |
| 3724 STATUS_ICON_COLUMN, status, | |
| 3725 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
| 3726 NAME_COLUMN, mark, | |
| 3727 IDLE_COLUMN, idle, | |
| 3728 BUDDY_ICON_COLUMN, avatar, | |
| 3729 -1); | |
| 3730 | |
| 3731 g_free(mark); | |
| 3732 if(idle) | |
| 3733 g_free(idle); | |
| 3734 if(status) | |
| 3735 g_object_unref(status); | |
| 3736 if(avatar) | |
| 3737 g_object_unref(avatar); | |
| 3738 } | |
| 3739 | |
| 11890 | 3740 |
| 7620 | 3741 static void gaim_gtk_blist_update_contact(GaimBuddyList *list, GaimBlistNode *node) |
| 3742 { | |
| 3743 GaimContact *contact; | |
| 3744 GaimBuddy *buddy; | |
| 3745 struct _gaim_gtk_blist_node *gtknode; | |
| 3746 | |
| 3747 g_return_if_fail(GAIM_BLIST_NODE_IS_CONTACT(node)); | |
| 3748 | |
| 3749 /* First things first, update the group */ | |
| 3750 gaim_gtk_blist_update_group(list, node->parent); | |
| 3751 | |
| 3752 contact = (GaimContact*)node; | |
| 3753 buddy = gaim_contact_get_priority_buddy(contact); | |
| 3754 | |
| 11890 | 3755 if (buddy_is_displayable(buddy)) |
| 10006 | 3756 { |
| 7620 | 3757 GtkTreeIter iter; |
| 3758 | |
| 8252 | 3759 if(!insert_node(list, node, &iter)) |
| 3760 return; | |
| 7620 | 3761 |
| 10515 | 3762 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; |
| 3763 | |
| 7620 | 3764 if(gtknode->contact_expanded) { |
| 3765 GdkPixbuf *status; | |
| 5228 | 3766 char *mark; |
| 3767 | |
| 7620 | 3768 status = gaim_gtk_blist_get_status_icon(node, |
| 3769 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") ? | |
| 3770 GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
| 3771 | |
| 3772 mark = g_markup_escape_text(gaim_contact_get_alias(contact), -1); | |
| 3773 | |
| 5228 | 3774 gtk_tree_store_set(gtkblist->treemodel, &iter, |
| 7620 | 3775 STATUS_ICON_COLUMN, status, |
| 3776 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
| 5228 | 3777 NAME_COLUMN, mark, |
| 7620 | 3778 IDLE_COLUMN, NULL, |
| 3779 BUDDY_ICON_COLUMN, NULL, | |
| 5228 | 3780 -1); |
| 3781 g_free(mark); | |
| 7620 | 3782 if(status) |
| 3783 g_object_unref(status); | |
| 3784 } else { | |
| 3785 buddy_node(buddy, &iter, node); | |
| 5228 | 3786 } |
| 7620 | 3787 } else { |
| 3788 gaim_gtk_blist_hide_node(list, node); | |
| 5228 | 3789 } |
| 7620 | 3790 } |
| 3791 | |
| 3792 static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node) | |
| 3793 { | |
| 3794 GaimContact *contact; | |
| 3795 GaimBuddy *buddy; | |
| 3796 struct _gaim_gtk_blist_node *gtkparentnode; | |
| 3797 | |
| 3798 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
| 3799 | |
| 3800 buddy = (GaimBuddy*)node; | |
| 3801 contact = (GaimContact*)node->parent; | |
| 3802 | |
| 11624 | 3803 if (contact == NULL) |
| 3804 return; | |
| 3805 | |
| 7620 | 3806 /* First things first, update the contact */ |
| 3807 gaim_gtk_blist_update_contact(list, node->parent); | |
| 3808 | |
| 10918 | 3809 gtkparentnode = (struct _gaim_gtk_blist_node *)node->parent->ui_data; |
| 3810 | |
| 10006 | 3811 if (gtkparentnode->contact_expanded && |
| 3812 (gaim_presence_is_online(buddy->presence) || | |
| 11910 | 3813 (0 /* XXX: if we just signed off, need to show logout.png */) || |
| 7620 | 3814 (gaim_account_is_connected(buddy->account) && |
| 10006 | 3815 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || |
| 3816 gaim_blist_node_get_bool(node->parent, "show_offline"))) | |
| 3817 { | |
| 7620 | 3818 GtkTreeIter iter; |
| 3819 | |
| 10006 | 3820 if (!insert_node(list, node, &iter)) |
| 8252 | 3821 return; |
| 3822 | |
| 7620 | 3823 buddy_node(buddy, &iter, node); |
| 3824 | |
| 3825 } else { | |
| 3826 gaim_gtk_blist_hide_node(list, node); | |
| 3827 } | |
| 3828 | |
| 3829 } | |
| 3830 | |
| 3831 static void gaim_gtk_blist_update_chat(GaimBuddyList *list, GaimBlistNode *node) | |
| 3832 { | |
| 3833 GaimChat *chat; | |
| 3834 | |
| 3835 g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); | |
| 3836 | |
| 3837 /* First things first, update the group */ | |
| 3838 gaim_gtk_blist_update_group(list, node->parent); | |
| 3839 | |
| 3840 chat = (GaimChat*)node; | |
| 3841 | |
| 3842 if(gaim_account_is_connected(chat->account)) { | |
| 3843 GtkTreeIter iter; | |
| 5234 | 3844 GdkPixbuf *status; |
| 7620 | 3845 char *mark; |
| 3846 | |
| 8252 | 3847 if(!insert_node(list, node, &iter)) |
| 3848 return; | |
| 5234 | 3849 |
| 3850 status = gaim_gtk_blist_get_status_icon(node, | |
| 7620 | 3851 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") ? |
| 3852 GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
| 3853 | |
| 3854 mark = g_markup_escape_text(gaim_chat_get_name(chat), -1); | |
| 5234 | 3855 |
| 3856 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
| 7620 | 3857 STATUS_ICON_COLUMN, status, |
| 3858 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
| 3859 NAME_COLUMN, mark, | |
| 3860 -1); | |
| 5228 | 3861 |
| 3862 g_free(mark); | |
| 7620 | 3863 if(status) |
| 5228 | 3864 g_object_unref(status); |
| 7620 | 3865 } else { |
| 5260 | 3866 gaim_gtk_blist_hide_node(list, node); |
| 5228 | 3867 } |
| 7620 | 3868 } |
| 3869 | |
| 3870 static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node) | |
| 3871 { | |
| 3872 if(!gtkblist) | |
| 3873 return; | |
| 3874 | |
| 3875 switch(node->type) { | |
| 3876 case GAIM_BLIST_GROUP_NODE: | |
| 3877 gaim_gtk_blist_update_group(list, node); | |
| 3878 break; | |
| 3879 case GAIM_BLIST_CONTACT_NODE: | |
| 3880 gaim_gtk_blist_update_contact(list, node); | |
| 3881 break; | |
| 3882 case GAIM_BLIST_BUDDY_NODE: | |
| 3883 gaim_gtk_blist_update_buddy(list, node); | |
| 3884 break; | |
| 3885 case GAIM_BLIST_CHAT_NODE: | |
| 3886 gaim_gtk_blist_update_chat(list, node); | |
| 3887 break; | |
| 3888 case GAIM_BLIST_OTHER_NODE: | |
| 3889 return; | |
| 3890 } | |
| 5234 | 3891 |
| 5228 | 3892 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); |
| 3893 } | |
| 3894 | |
| 7620 | 3895 |
| 3896 static void gaim_gtk_blist_destroy(GaimBuddyList *list) | |
| 5228 | 3897 { |
| 3898 if (!gtkblist) | |
| 3899 return; | |
| 3900 | |
| 8937 | 3901 gaim_signal_disconnect(gaim_connections_get_handle(), "signed-on", |
| 3902 gtkblist, GAIM_CALLBACK(sign_on_off_cb)); | |
| 3903 gaim_signal_disconnect(gaim_connections_get_handle(), "signed-off", | |
| 3904 gtkblist, GAIM_CALLBACK(sign_on_off_cb)); | |
|
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3905 |
| 5228 | 3906 gtk_widget_destroy(gtkblist->window); |
| 7620 | 3907 |
| 8254 | 3908 gaim_gtk_blist_tooltip_destroy(); |
| 7620 | 3909 |
| 5228 | 3910 if (gtkblist->refresh_timer) |
| 3911 g_source_remove(gtkblist->refresh_timer); | |
| 3912 if (gtkblist->timeout) | |
| 3913 g_source_remove(gtkblist->timeout); | |
| 10354 | 3914 if (gtkblist->drag_timeout) |
| 3915 g_source_remove(gtkblist->drag_timeout); | |
| 5228 | 3916 |
| 3917 gtkblist->refresh_timer = 0; | |
| 3918 gtkblist->timeout = 0; | |
| 10354 | 3919 gtkblist->drag_timeout = 0; |
| 5228 | 3920 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; |
| 3921 gtkblist->treemodel = NULL; | |
| 3922 gtkblist->idle_column = NULL; | |
| 11257 | 3923 gtkblist->buddy_icon_column = NULL; |
| 5427 | 3924 g_object_unref(G_OBJECT(gtkblist->ift)); |
| 5228 | 3925 protomenu = NULL; |
| 3926 gtkblist = NULL; | |
| 7620 | 3927 |
| 10087 | 3928 gaim_prefs_disconnect_by_handle(gaim_gtk_blist_get_handle()); |
| 5228 | 3929 } |
| 3930 | |
| 7620 | 3931 static void gaim_gtk_blist_set_visible(GaimBuddyList *list, gboolean show) |
| 5228 | 3932 { |
| 3933 if (!(gtkblist && gtkblist->window)) | |
| 3934 return; | |
| 10325 | 3935 |
| 10282 | 3936 gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", show); |
| 10325 | 3937 |
| 5228 | 3938 if (show) { |
| 3939 gaim_gtk_blist_restore_position(); | |
| 3940 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
| 3941 } else { | |
|
11709
cae2fb7e8594
[gaim-migrate @ 14000]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11692
diff
changeset
|
3942 gtk_window_iconify(GTK_WINDOW(gtkblist->window)); |
| 5228 | 3943 } |
| 3944 } | |
| 3945 | |
| 7620 | 3946 static GList * |
| 3947 groups_tree(void) | |
| 3948 { | |
| 3949 GList *tmp = NULL; | |
| 3950 char *tmp2; | |
| 3951 GaimGroup *g; | |
| 3952 GaimBlistNode *gnode; | |
| 3953 | |
| 3954 if (gaim_get_blist()->root == NULL) | |
| 3955 { | |
| 3956 tmp2 = g_strdup(_("Buddies")); | |
| 3957 tmp = g_list_append(tmp, tmp2); | |
| 3958 } | |
| 3959 else | |
| 3960 { | |
| 3961 for (gnode = gaim_get_blist()->root; | |
| 3962 gnode != NULL; | |
| 3963 gnode = gnode->next) | |
| 3964 { | |
| 3965 if (GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
| 3966 { | |
| 3967 g = (GaimGroup *)gnode; | |
| 3968 tmp2 = g->name; | |
| 3969 tmp = g_list_append(tmp, tmp2); | |
| 3970 } | |
| 3971 } | |
| 3972 } | |
| 3973 | |
| 3974 return tmp; | |
| 3975 } | |
| 3976 | |
| 3977 static void | |
| 3978 add_buddy_select_account_cb(GObject *w, GaimAccount *account, | |
| 3979 GaimGtkAddBuddyData *data) | |
| 3980 { | |
| 3981 /* Save our account */ | |
| 3982 data->account = account; | |
| 3983 } | |
| 3984 | |
| 3985 static void | |
| 3986 destroy_add_buddy_dialog_cb(GtkWidget *win, GaimGtkAddBuddyData *data) | |
| 3987 { | |
| 3988 g_free(data); | |
| 3989 } | |
| 3990 | |
| 3991 static void | |
| 3992 add_buddy_cb(GtkWidget *w, int resp, GaimGtkAddBuddyData *data) | |
| 3993 { | |
| 3994 const char *grp, *who, *whoalias; | |
| 3995 GaimConversation *c; | |
| 3996 GaimBuddy *b; | |
| 3997 GaimGroup *g; | |
| 3998 | |
| 3999 if (resp == GTK_RESPONSE_OK) | |
| 4000 { | |
| 4001 who = gtk_entry_get_text(GTK_ENTRY(data->entry)); | |
| 4002 grp = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(data->combo)->entry)); | |
| 4003 whoalias = gtk_entry_get_text(GTK_ENTRY(data->entry_for_alias)); | |
| 9658 | 4004 if (*whoalias == '\0') |
| 4005 whoalias = NULL; | |
| 7620 | 4006 |
| 4007 if ((g = gaim_find_group(grp)) == NULL) | |
| 4008 { | |
| 4009 g = gaim_group_new(grp); | |
| 4010 gaim_blist_add_group(g, NULL); | |
| 4011 } | |
| 4012 | |
| 4013 b = gaim_buddy_new(data->account, who, whoalias); | |
| 4014 gaim_blist_add_buddy(b, NULL, g, NULL); | |
| 11643 | 4015 gaim_account_add_buddy(data->account, b); |
| 7620 | 4016 |
| 7887 | 4017 /* |
| 9285 | 4018 * XXX |
| 11643 | 4019 * It really seems like it would be better if the call to |
| 4020 * gaim_account_add_buddy() and gaim_conversation_update() were done in | |
| 4021 * blist.c, possibly in the gaim_blist_add_buddy() function. Maybe | |
| 4022 * gaim_account_add_buddy() should be renamed to | |
| 4023 * gaim_blist_add_new_buddy() or something, and have it call | |
| 7887 | 4024 * gaim_blist_add_buddy() after it creates it. --Mark |
| 9285 | 4025 * |
| 4026 * No that's not good. blist.c should only deal with adding nodes to the | |
| 11643 | 4027 * local list. We need a new, non-gtk file that calls both |
| 4028 * gaim_account_add_buddy and gaim_blist_add_buddy(). | |
| 4029 * Or something. --Mark | |
| 7887 | 4030 */ |
| 4031 | |
| 11338 | 4032 c = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, who, data->account); |
| 7620 | 4033 if (c != NULL) { |
| 4034 gaim_buddy_icon_update(gaim_conv_im_get_icon(GAIM_CONV_IM(c))); | |
| 4035 gaim_conversation_update(c, GAIM_CONV_UPDATE_ADD); | |
| 4036 } | |
| 4037 } | |
| 4038 | |
| 4039 gtk_widget_destroy(data->window); | |
| 4040 } | |
| 4041 | |
| 4042 static void | |
| 4043 gaim_gtk_blist_request_add_buddy(GaimAccount *account, const char *username, | |
| 4044 const char *group, const char *alias) | |
| 4045 { | |
| 4046 GtkWidget *table; | |
| 4047 GtkWidget *label; | |
| 4048 GtkWidget *hbox; | |
| 4049 GtkWidget *vbox; | |
| 4050 GtkWidget *img; | |
| 4051 GaimGtkBuddyList *gtkblist; | |
| 4052 GaimGtkAddBuddyData *data = g_new0(GaimGtkAddBuddyData, 1); | |
| 4053 | |
| 4054 data->account = | |
| 4055 (account != NULL | |
| 4056 ? account | |
| 4057 : gaim_connection_get_account(gaim_connections_get_all()->data)); | |
| 4058 | |
| 4059 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
| 4060 GTK_ICON_SIZE_DIALOG); | |
| 4061 | |
| 4062 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); | |
| 4063 | |
| 4064 data->window = gtk_dialog_new_with_buttons(_("Add Buddy"), | |
| 8975 | 4065 NULL, GTK_DIALOG_NO_SEPARATOR, |
| 7620 | 4066 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
| 4067 GTK_STOCK_ADD, GTK_RESPONSE_OK, | |
| 4068 NULL); | |
| 4069 | |
| 4070 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); | |
| 11243 | 4071 gtk_container_set_border_width(GTK_CONTAINER(data->window), GAIM_HIG_BOX_SPACE); |
| 7620 | 4072 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); |
| 11243 | 4073 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BORDER); |
| 4074 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BOX_SPACE); | |
| 7620 | 4075 gtk_window_set_role(GTK_WINDOW(data->window), "add_buddy"); |
| 8975 | 4076 gtk_window_set_type_hint(GTK_WINDOW(data->window), |
| 9811 | 4077 GDK_WINDOW_TYPE_HINT_DIALOG); |
| 7620 | 4078 |
| 11243 | 4079 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
| 7620 | 4080 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); |
| 4081 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
| 4082 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
| 4083 | |
| 4084 vbox = gtk_vbox_new(FALSE, 0); | |
| 4085 gtk_container_add(GTK_CONTAINER(hbox), vbox); | |
| 4086 | |
| 4087 label = gtk_label_new( | |
| 4088 _("Please enter the screen name of the person you would like " | |
| 4089 "to add to your buddy list. You may optionally enter an alias, " | |
| 4090 "or nickname, for the buddy. The alias will be displayed in " | |
| 4091 "place of the screen name whenever possible.\n")); | |
| 4092 | |
| 4093 gtk_widget_set_size_request(GTK_WIDGET(label), 400, -1); | |
| 4094 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
| 4095 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
| 4096 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
| 4097 | |
| 11243 | 4098 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); |
| 7620 | 4099 gtk_container_add(GTK_CONTAINER(vbox), hbox); |
| 4100 | |
| 4101 g_signal_connect(G_OBJECT(data->window), "destroy", | |
| 4102 G_CALLBACK(destroy_add_buddy_dialog_cb), data); | |
| 4103 | |
| 4104 table = gtk_table_new(4, 2, FALSE); | |
| 4105 gtk_table_set_row_spacings(GTK_TABLE(table), 5); | |
| 4106 gtk_table_set_col_spacings(GTK_TABLE(table), 5); | |
| 4107 gtk_container_set_border_width(GTK_CONTAINER(table), 0); | |
| 4108 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); | |
| 4109 | |
| 4110 label = gtk_label_new(_("Screen Name:")); | |
| 4111 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 4112 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); | |
| 4113 | |
| 4114 data->entry = gtk_entry_new(); | |
| 4115 gtk_table_attach_defaults(GTK_TABLE(table), data->entry, 1, 2, 0, 1); | |
| 4116 gtk_widget_grab_focus(data->entry); | |
| 4117 | |
| 4118 if (username != NULL) | |
| 4119 gtk_entry_set_text(GTK_ENTRY(data->entry), username); | |
| 4120 | |
| 4121 gtk_entry_set_activates_default (GTK_ENTRY(data->entry), TRUE); | |
| 8137 | 4122 gaim_set_accessible_label (data->entry, label); |
| 7620 | 4123 |
| 4124 label = gtk_label_new(_("Alias:")); | |
| 4125 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 4126 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | |
| 4127 | |
| 4128 data->entry_for_alias = gtk_entry_new(); | |
| 4129 gtk_table_attach_defaults(GTK_TABLE(table), | |
| 4130 data->entry_for_alias, 1, 2, 1, 2); | |
| 4131 | |
| 4132 if (alias != NULL) | |
| 4133 gtk_entry_set_text(GTK_ENTRY(data->entry_for_alias), alias); | |
| 4134 | |
|
10734
8b2c81d9b271
[gaim-migrate @ 12336]
Luke Schierer <lschiere@pidgin.im>
parents:
10694
diff
changeset
|
4135 if (username != NULL) |
|
8b2c81d9b271
[gaim-migrate @ 12336]
Luke Schierer <lschiere@pidgin.im>
parents:
10694
diff
changeset
|
4136 gtk_widget_grab_focus(GTK_WIDGET(data->entry_for_alias)); |
|
8b2c81d9b271
[gaim-migrate @ 12336]
Luke Schierer <lschiere@pidgin.im>
parents:
10694
diff
changeset
|
4137 |
| 7620 | 4138 gtk_entry_set_activates_default (GTK_ENTRY(data->entry_for_alias), TRUE); |
| 8137 | 4139 gaim_set_accessible_label (data->entry_for_alias, label); |
| 7620 | 4140 |
| 4141 label = gtk_label_new(_("Group:")); | |
| 4142 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 4143 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); | |
| 4144 | |
| 4145 data->combo = gtk_combo_new(); | |
| 4146 gtk_combo_set_popdown_strings(GTK_COMBO(data->combo), groups_tree()); | |
| 4147 gtk_table_attach_defaults(GTK_TABLE(table), data->combo, 1, 2, 2, 3); | |
| 8137 | 4148 gaim_set_accessible_label (data->combo, label); |
| 7620 | 4149 |
| 4150 /* Set up stuff for the account box */ | |
| 4151 label = gtk_label_new(_("Account:")); | |
| 4152 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 4153 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); | |
| 4154 | |
| 4155 data->account_box = gaim_gtk_account_option_menu_new(account, FALSE, | |
| 4156 G_CALLBACK(add_buddy_select_account_cb), NULL, data); | |
| 4157 | |
| 4158 gtk_table_attach_defaults(GTK_TABLE(table), data->account_box, 1, 2, 3, 4); | |
| 8137 | 4159 gaim_set_accessible_label (data->account_box, label); |
| 7620 | 4160 /* End of account box */ |
| 4161 | |
| 4162 g_signal_connect(G_OBJECT(data->window), "response", | |
| 4163 G_CALLBACK(add_buddy_cb), data); | |
| 4164 | |
| 4165 gtk_widget_show_all(data->window); | |
| 4166 | |
| 4167 if (group != NULL) | |
| 4168 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(data->combo)->entry), group); | |
| 4169 } | |
| 4170 | |
| 4171 static void | |
| 4172 add_chat_cb(GtkWidget *w, GaimGtkAddChatData *data) | |
| 4173 { | |
| 4174 GHashTable *components; | |
| 4175 GList *tmp; | |
| 4176 GaimChat *chat; | |
| 4177 GaimGroup *group; | |
| 4178 const char *group_name; | |
| 9918 | 4179 char *chat_name = NULL; |
| 4180 GaimConversation *conv = NULL; | |
| 10475 | 4181 const char *value; |
| 7620 | 4182 |
| 4183 components = g_hash_table_new_full(g_str_hash, g_str_equal, | |
| 4184 g_free, g_free); | |
| 4185 | |
| 4186 for (tmp = data->entries; tmp; tmp = tmp->next) | |
| 4187 { | |
| 4188 if (g_object_get_data(tmp->data, "is_spin")) | |
| 4189 { | |
| 4190 g_hash_table_replace(components, | |
| 4191 g_strdup(g_object_get_data(tmp->data, "identifier")), | |
| 4192 g_strdup_printf("%d", | |
| 4193 gtk_spin_button_get_value_as_int(tmp->data))); | |
| 4194 } | |
| 4195 else | |
| 4196 { | |
| 10475 | 4197 value = gtk_entry_get_text(tmp->data); |
| 4198 if (*value != '\0') | |
| 4199 g_hash_table_replace(components, | |
| 4200 g_strdup(g_object_get_data(tmp->data, "identifier")), | |
| 4201 g_strdup(value)); | |
| 7620 | 4202 } |
| 4203 } | |
| 4204 | |
| 4205 chat = gaim_chat_new(data->account, | |
| 4206 gtk_entry_get_text(GTK_ENTRY(data->alias_entry)), | |
| 4207 components); | |
| 4208 | |
| 4209 group_name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(data->group_combo)->entry)); | |
| 4210 | |
| 4211 if ((group = gaim_find_group(group_name)) == NULL) | |
| 4212 { | |
| 4213 group = gaim_group_new(group_name); | |
| 4214 gaim_blist_add_group(group, NULL); | |
| 4215 } | |
| 4216 | |
| 4217 if (chat != NULL) | |
| 4218 { | |
| 4219 gaim_blist_add_chat(chat, group, NULL); | |
| 9918 | 4220 |
| 4221 if (GAIM_PLUGIN_PROTOCOL_INFO(data->account->gc->prpl)->get_chat_name != NULL) | |
| 4222 chat_name = GAIM_PLUGIN_PROTOCOL_INFO( | |
| 4223 data->account->gc->prpl)->get_chat_name(chat->components); | |
| 10246 | 4224 |
| 9918 | 4225 if (chat_name != NULL) { |
| 11338 | 4226 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 4227 chat_name, |
| 4228 data->account); | |
| 9918 | 4229 g_free(chat_name); |
| 4230 } | |
| 4231 | |
| 4232 if (conv != NULL) | |
| 4233 gaim_conversation_update(conv, GAIM_CONV_UPDATE_ADD); | |
| 7620 | 4234 } |
| 4235 | |
| 4236 gtk_widget_destroy(data->window); | |
| 9812 | 4237 g_free(data->default_chat_name); |
| 7620 | 4238 g_list_free(data->entries); |
| 4239 g_free(data); | |
| 4240 } | |
| 4241 | |
| 4242 static void | |
| 4243 add_chat_resp_cb(GtkWidget *w, int resp, GaimGtkAddChatData *data) | |
| 4244 { | |
| 4245 if (resp == GTK_RESPONSE_OK) | |
| 4246 { | |
| 4247 add_chat_cb(NULL, data); | |
| 4248 } | |
| 4249 else | |
| 4250 { | |
| 4251 gtk_widget_destroy(data->window); | |
| 9812 | 4252 g_free(data->default_chat_name); |
| 7620 | 4253 g_list_free(data->entries); |
| 4254 g_free(data); | |
| 4255 } | |
| 4256 } | |
| 4257 | |
| 10475 | 4258 /* |
| 4259 * Check the values of all the text entry boxes. If any required input | |
| 4260 * strings are empty then don't allow the user to click on "OK." | |
| 4261 */ | |
| 4262 static void | |
| 4263 addchat_set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data) | |
| 4264 { | |
| 4265 GaimGtkAddChatData *data; | |
| 4266 GList *tmp; | |
| 4267 const char *text; | |
| 4268 gboolean required; | |
| 4269 gboolean sensitive = TRUE; | |
| 4270 | |
| 4271 data = user_data; | |
| 4272 | |
| 4273 for (tmp = data->entries; tmp != NULL; tmp = tmp->next) | |
| 4274 { | |
| 4275 if (!g_object_get_data(tmp->data, "is_spin")) | |
| 4276 { | |
| 4277 required = GPOINTER_TO_INT(g_object_get_data(tmp->data, "required")); | |
| 4278 text = gtk_entry_get_text(tmp->data); | |
| 4279 if (required && (*text == '\0')) | |
| 4280 sensitive = FALSE; | |
| 4281 } | |
| 4282 } | |
| 4283 | |
| 4284 gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_OK, sensitive); | |
| 4285 } | |
| 4286 | |
| 7620 | 4287 static void |
| 4288 rebuild_addchat_entries(GaimGtkAddChatData *data) | |
| 4289 { | |
| 4290 GaimConnection *gc; | |
| 9959 | 4291 GList *list = NULL, *tmp = NULL; |
| 9754 | 4292 GHashTable *defaults = NULL; |
| 7620 | 4293 struct proto_chat_entry *pce; |
| 4294 gboolean focus = TRUE; | |
| 4295 | |
| 10127 | 4296 g_return_if_fail(data->account != NULL); |
| 4297 | |
| 7620 | 4298 gc = gaim_account_get_connection(data->account); |
| 4299 | |
| 4300 while (GTK_BOX(data->entries_box)->children) | |
| 4301 { | |
| 4302 gtk_container_remove(GTK_CONTAINER(data->entries_box), | |
| 10475 | 4303 ((GtkBoxChild *)GTK_BOX(data->entries_box)->children->data)->widget); |
| 7620 | 4304 } |
| 4305 | |
| 4306 if (data->entries != NULL) | |
| 4307 g_list_free(data->entries); | |
| 4308 | |
| 4309 data->entries = NULL; | |
| 4310 | |
| 9959 | 4311 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) |
| 4312 list = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); | |
| 7620 | 4313 |
| 9754 | 4314 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) |
| 10475 | 4315 defaults = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, data->default_chat_name); |
| 9754 | 4316 |
| 7620 | 4317 for (tmp = list; tmp; tmp = tmp->next) |
| 4318 { | |
| 4319 GtkWidget *label; | |
| 4320 GtkWidget *rowbox; | |
| 10475 | 4321 GtkWidget *input; |
| 7620 | 4322 |
| 4323 pce = tmp->data; | |
| 4324 | |
| 4325 rowbox = gtk_hbox_new(FALSE, 5); | |
| 4326 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0); | |
| 4327 | |
| 7889 | 4328 label = gtk_label_new_with_mnemonic(pce->label); |
| 7620 | 4329 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
| 4330 gtk_size_group_add_widget(data->sg, label); | |
| 4331 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
| 4332 | |
| 4333 if (pce->is_int) | |
| 4334 { | |
| 4335 GtkObject *adjust; | |
| 4336 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, | |
| 4337 1, 10, 10); | |
| 10475 | 4338 input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); |
| 4339 gtk_widget_set_size_request(input, 50, -1); | |
| 4340 gtk_box_pack_end(GTK_BOX(rowbox), input, FALSE, FALSE, 0); | |
| 7620 | 4341 } |
| 4342 else | |
| 4343 { | |
| 9754 | 4344 char *value; |
| 10475 | 4345 input = gtk_entry_new(); |
| 4346 gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE); | |
| 9754 | 4347 value = g_hash_table_lookup(defaults, pce->identifier); |
| 4348 if (value != NULL) | |
| 10475 | 4349 gtk_entry_set_text(GTK_ENTRY(input), value); |
| 7620 | 4350 if (pce->secret) |
| 11986 | 4351 { |
| 10475 | 4352 gtk_entry_set_visibility(GTK_ENTRY(input), FALSE); |
| 11986 | 4353 gtk_entry_set_invisible_char(GTK_ENTRY(input), GAIM_INVISIBLE_CHAR); |
| 4354 } | |
| 10475 | 4355 gtk_box_pack_end(GTK_BOX(rowbox), input, TRUE, TRUE, 0); |
| 4356 g_signal_connect(G_OBJECT(input), "changed", | |
| 4357 G_CALLBACK(addchat_set_sensitive_if_input_cb), data); | |
| 7620 | 4358 } |
| 4359 | |
| 10475 | 4360 /* Do the following for any type of input widget */ |
| 4361 if (focus) | |
| 4362 { | |
| 4363 gtk_widget_grab_focus(input); | |
| 4364 focus = FALSE; | |
| 4365 } | |
| 4366 gtk_label_set_mnemonic_widget(GTK_LABEL(label), input); | |
| 4367 gaim_set_accessible_label(input, label); | |
| 4368 g_object_set_data(G_OBJECT(input), "identifier", pce->identifier); | |
| 4369 g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int)); | |
| 4370 g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required)); | |
| 4371 data->entries = g_list_append(data->entries, input); | |
| 4372 | |
| 7620 | 4373 g_free(pce); |
| 4374 } | |
| 4375 | |
| 4376 g_list_free(list); | |
| 9754 | 4377 g_hash_table_destroy(defaults); |
| 7620 | 4378 |
| 10475 | 4379 /* Set whether the "OK" button should be clickable initially */ |
| 4380 addchat_set_sensitive_if_input_cb(NULL, data); | |
| 4381 | |
| 7620 | 4382 gtk_widget_show_all(data->entries_box); |
| 4383 } | |
| 4384 | |
| 4385 static void | |
| 10475 | 4386 addchat_select_account_cb(GObject *w, GaimAccount *account, |
| 7620 | 4387 GaimGtkAddChatData *data) |
| 4388 { | |
| 9460 | 4389 if (strcmp(gaim_account_get_protocol_id(data->account), |
| 4390 gaim_account_get_protocol_id(account)) == 0) | |
| 7620 | 4391 { |
| 4392 data->account = account; | |
| 4393 } | |
| 4394 else | |
| 4395 { | |
| 4396 data->account = account; | |
| 4397 rebuild_addchat_entries(data); | |
| 4398 } | |
| 4399 } | |
| 4400 | |
| 4401 void | |
| 7859 | 4402 gaim_gtk_blist_request_add_chat(GaimAccount *account, GaimGroup *group, |
| 9754 | 4403 const char *alias, const char *name) |
| 7620 | 4404 { |
| 4405 GaimGtkAddChatData *data; | |
| 8975 | 4406 GaimGtkBuddyList *gtkblist; |
| 4407 GList *l; | |
| 4408 GaimConnection *gc; | |
| 7620 | 4409 GtkWidget *label; |
| 4410 GtkWidget *rowbox; | |
| 4411 GtkWidget *hbox; | |
| 4412 GtkWidget *vbox; | |
| 4413 GtkWidget *img; | |
| 4414 | |
| 9812 | 4415 if (account != NULL) { |
| 4416 gc = gaim_account_get_connection(account); | |
| 4417 | |
| 4418 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat == NULL) { | |
| 4419 gaim_notify_error(gc, NULL, _("This protocol does not support chat rooms."), NULL); | |
| 4420 return; | |
| 4421 } | |
| 4422 } else { | |
| 4423 /* Find an account with chat capabilities */ | |
| 4424 for (l = gaim_connections_get_all(); l != NULL; l = l->next) { | |
| 4425 gc = (GaimConnection *)l->data; | |
| 4426 | |
| 4427 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat != NULL) { | |
| 4428 account = gaim_connection_get_account(gc); | |
| 4429 break; | |
| 4430 } | |
| 4431 } | |
| 4432 | |
| 4433 if (account == NULL) { | |
| 4434 gaim_notify_error(NULL, NULL, | |
| 4435 _("You are not currently signed on with any " | |
| 4436 "protocols that have the ability to chat."), NULL); | |
| 4437 return; | |
| 4438 } | |
| 4439 } | |
| 4440 | |
| 7620 | 4441 data = g_new0(GaimGtkAddChatData, 1); |
| 9812 | 4442 data->account = account; |
| 4443 data->default_chat_name = g_strdup(name); | |
| 7620 | 4444 |
| 4445 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
| 4446 GTK_ICON_SIZE_DIALOG); | |
| 4447 | |
| 8975 | 4448 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); |
| 4449 | |
| 7620 | 4450 data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
| 4451 | |
| 8975 | 4452 data->window = gtk_dialog_new_with_buttons(_("Add Chat"), |
| 4453 NULL, GTK_DIALOG_NO_SEPARATOR, | |
| 4454 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
| 4455 GTK_STOCK_ADD, GTK_RESPONSE_OK, | |
| 4456 NULL); | |
| 4457 | |
| 4458 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); | |
| 11243 | 4459 gtk_container_set_border_width(GTK_CONTAINER(data->window), GAIM_HIG_BOX_SPACE); |
| 8975 | 4460 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); |
| 11243 | 4461 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BORDER); |
| 4462 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BOX_SPACE); | |
| 7620 | 4463 gtk_window_set_role(GTK_WINDOW(data->window), "add_chat"); |
| 8975 | 4464 gtk_window_set_type_hint(GTK_WINDOW(data->window), |
| 9811 | 4465 GDK_WINDOW_TYPE_HINT_DIALOG); |
| 7620 | 4466 |
| 11243 | 4467 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
| 7620 | 4468 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); |
| 4469 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
| 4470 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
| 4471 | |
| 4472 vbox = gtk_vbox_new(FALSE, 5); | |
| 4473 gtk_container_add(GTK_CONTAINER(hbox), vbox); | |
| 4474 | |
| 4475 label = gtk_label_new( | |
| 4476 _("Please enter an alias, and the appropriate information " | |
| 4477 "about the chat you would like to add to your buddy list.\n")); | |
| 4478 gtk_widget_set_size_request(label, 400, -1); | |
| 4479 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
| 4480 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
| 4481 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
| 4482 | |
| 4483 rowbox = gtk_hbox_new(FALSE, 5); | |
| 4484 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
| 4485 | |
| 4486 label = gtk_label_new(_("Account:")); | |
| 4487 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 4488 gtk_size_group_add_widget(data->sg, label); | |
| 4489 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
| 4490 | |
| 4491 data->account_menu = gaim_gtk_account_option_menu_new(account, FALSE, | |
| 10475 | 4492 G_CALLBACK(addchat_select_account_cb), |
| 9987 | 4493 chat_account_filter_func, data); |
| 7620 | 4494 gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0); |
| 8137 | 4495 gaim_set_accessible_label (data->account_menu, label); |
| 7620 | 4496 |
| 4497 data->entries_box = gtk_vbox_new(FALSE, 5); | |
| 9811 | 4498 gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0); |
| 7620 | 4499 gtk_box_pack_start(GTK_BOX(vbox), data->entries_box, TRUE, TRUE, 0); |
| 4500 | |
| 4501 rebuild_addchat_entries(data); | |
| 4502 | |
| 4503 rowbox = gtk_hbox_new(FALSE, 5); | |
| 4504 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
| 4505 | |
| 4506 label = gtk_label_new(_("Alias:")); | |
| 4507 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 4508 gtk_size_group_add_widget(data->sg, label); | |
| 4509 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
| 4510 | |
| 4511 data->alias_entry = gtk_entry_new(); | |
| 7859 | 4512 if (alias != NULL) |
| 4513 gtk_entry_set_text(GTK_ENTRY(data->alias_entry), alias); | |
| 7620 | 4514 gtk_box_pack_end(GTK_BOX(rowbox), data->alias_entry, TRUE, TRUE, 0); |
| 10311 | 4515 gtk_entry_set_activates_default(GTK_ENTRY(data->alias_entry), TRUE); |
| 8137 | 4516 gaim_set_accessible_label (data->alias_entry, label); |
| 7620 | 4517 |
| 4518 rowbox = gtk_hbox_new(FALSE, 5); | |
| 4519 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
| 4520 | |
| 9811 | 4521 label = gtk_label_new(_("Group:")); |
| 7620 | 4522 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
| 4523 gtk_size_group_add_widget(data->sg, label); | |
| 4524 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
| 4525 | |
| 9811 | 4526 data->group_combo = gtk_combo_new(); |
| 4527 gtk_combo_set_popdown_strings(GTK_COMBO(data->group_combo), groups_tree()); | |
| 7620 | 4528 gtk_box_pack_end(GTK_BOX(rowbox), data->group_combo, TRUE, TRUE, 0); |
| 4529 | |
| 4530 if (group) | |
| 4531 { | |
| 4532 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(data->group_combo)->entry), | |
| 4533 group->name); | |
| 4534 } | |
| 8137 | 4535 gaim_set_accessible_label (data->group_combo, label); |
| 7620 | 4536 |
| 4537 g_signal_connect(G_OBJECT(data->window), "response", | |
| 4538 G_CALLBACK(add_chat_resp_cb), data); | |
| 4539 | |
| 4540 gtk_widget_show_all(data->window); | |
| 4541 } | |
| 4542 | |
| 4543 static void | |
| 4544 add_group_cb(GaimConnection *gc, const char *group_name) | |
| 4545 { | |
| 9285 | 4546 GaimGroup *group; |
| 4547 | |
| 4548 group = gaim_group_new(group_name); | |
| 4549 gaim_blist_add_group(group, NULL); | |
| 7620 | 4550 } |
| 4551 | |
| 4552 void | |
| 4553 gaim_gtk_blist_request_add_group(void) | |
| 4554 { | |
| 7853 | 4555 gaim_request_input(NULL, _("Add Group"), NULL, |
| 7620 | 4556 _("Please enter the name of the group to be added."), |
| 8697 | 4557 NULL, FALSE, FALSE, NULL, |
| 7620 | 4558 _("Add"), G_CALLBACK(add_group_cb), |
| 4559 _("Cancel"), NULL, NULL); | |
| 4560 } | |
| 4561 | |
| 4562 static GaimBlistUiOps blist_ui_ops = | |
| 5228 | 4563 { |
| 4564 gaim_gtk_blist_new_list, | |
| 5256 | 4565 gaim_gtk_blist_new_node, |
| 5228 | 4566 gaim_gtk_blist_show, |
| 4567 gaim_gtk_blist_update, | |
| 4568 gaim_gtk_blist_remove, | |
| 4569 gaim_gtk_blist_destroy, | |
| 7620 | 4570 gaim_gtk_blist_set_visible, |
| 4571 gaim_gtk_blist_request_add_buddy, | |
| 4572 gaim_gtk_blist_request_add_chat, | |
| 10012 | 4573 gaim_gtk_blist_request_add_group |
| 5228 | 4574 }; |
| 4575 | |
| 4576 | |
| 7620 | 4577 GaimBlistUiOps * |
| 4578 gaim_gtk_blist_get_ui_ops(void) | |
| 5228 | 4579 { |
| 4580 return &blist_ui_ops; | |
| 4581 } | |
| 4582 | |
| 10643 | 4583 GaimGtkBuddyList *gaim_gtk_blist_get_default_gtk_blist() |
| 4584 { | |
| 4585 return gtkblist; | |
| 4586 } | |
| 4587 | |
| 7620 | 4588 static void account_signon_cb(GaimConnection *gc, gpointer z) |
| 4589 { | |
| 4590 GaimAccount *account = gaim_connection_get_account(gc); | |
| 4591 GaimBlistNode *gnode, *cnode; | |
| 4592 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) | |
| 4593 { | |
| 4594 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
| 4595 continue; | |
| 4596 for(cnode = gnode->child; cnode; cnode = cnode->next) | |
| 4597 { | |
| 4598 GaimChat *chat; | |
| 4599 | |
| 4600 if(!GAIM_BLIST_NODE_IS_CHAT(cnode)) | |
| 4601 continue; | |
| 4602 | |
| 4603 chat = (GaimChat *)cnode; | |
| 4604 | |
| 4605 if(chat->account != account) | |
| 4606 continue; | |
| 4607 | |
| 8197 | 4608 if(gaim_blist_node_get_bool((GaimBlistNode*)chat, "gtk-autojoin") || |
| 8198 | 4609 (gaim_blist_node_get_string((GaimBlistNode*)chat, |
| 4610 "gtk-autojoin") != NULL)) | |
| 7620 | 4611 serv_join_chat(gc, chat->components); |
| 4612 } | |
| 4613 } | |
| 4614 } | |
| 4615 | |
| 8815 | 4616 void * |
| 4617 gaim_gtk_blist_get_handle() { | |
| 4618 static int handle; | |
| 4619 | |
| 4620 return &handle; | |
| 4621 } | |
| 4622 | |
| 11910 | 4623 static gboolean buddy_signonoff_timeout_cb(GaimBuddy *buddy) |
| 4624 { | |
| 4625 struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode*)buddy)->ui_data; | |
| 4626 GaimConversation *conv; | |
| 4627 | |
| 4628 gtknode->recent_signonoff = FALSE; | |
| 4629 gtknode->recent_signonoff_timer = 0; | |
| 4630 | |
| 4631 gaim_gtk_blist_update(NULL, (GaimBlistNode*)buddy); | |
| 4632 | |
| 4633 if((conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account))) { | |
| 4634 if(GAIM_BUDDY_IS_ONLINE(buddy)) { | |
| 4635 gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_ONLINE); | |
| 4636 } else { | |
| 4637 gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_OFFLINE); | |
| 4638 } | |
| 4639 } | |
| 4640 | |
| 4641 return FALSE; | |
| 4642 } | |
| 4643 | |
| 4644 static void buddy_signonoff_cb(GaimBuddy *buddy) | |
| 4645 { | |
| 11915 | 4646 struct _gaim_gtk_blist_node *gtknode; |
| 4647 | |
| 4648 if(!((GaimBlistNode*)buddy)->ui_data) { | |
| 4649 gaim_gtk_blist_new_node((GaimBlistNode*)buddy); | |
| 4650 } | |
| 4651 | |
| 4652 gtknode = ((GaimBlistNode*)buddy)->ui_data; | |
| 11910 | 4653 |
| 4654 gtknode->recent_signonoff = TRUE; | |
| 4655 | |
| 4656 if(gtknode->recent_signonoff_timer > 0) | |
| 4657 gaim_timeout_remove(gtknode->recent_signonoff_timer); | |
| 4658 gtknode->recent_signonoff_timer = gaim_timeout_add(10000, | |
| 4659 (GSourceFunc)buddy_signonoff_timeout_cb, buddy); | |
| 4660 } | |
| 4661 | |
| 7620 | 4662 void gaim_gtk_blist_init(void) |
| 4663 { | |
| 8815 | 4664 void *gtk_blist_handle = gaim_gtk_blist_get_handle(); |
| 7620 | 4665 |
| 4666 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | |
| 8815 | 4667 gtk_blist_handle, GAIM_CALLBACK(account_signon_cb), |
| 7620 | 4668 NULL); |
| 7731 | 4669 |
| 4670 /* Initialize prefs */ | |
| 8819 | 4671 gaim_prefs_add_none("/gaim/gtk/blist"); |
| 4672 gaim_prefs_add_bool("/gaim/gtk/blist/show_buddy_icons", TRUE); | |
| 4673 gaim_prefs_add_bool("/gaim/gtk/blist/show_empty_groups", FALSE); | |
| 4674 gaim_prefs_add_bool("/gaim/gtk/blist/show_offline_buddies", FALSE); | |
| 10282 | 4675 gaim_prefs_add_bool("/gaim/gtk/blist/list_visible", TRUE); |
| 9711 | 4676 gaim_prefs_add_string("/gaim/gtk/blist/sort_type", "alphabetical"); |
| 8819 | 4677 gaim_prefs_add_int("/gaim/gtk/blist/x", 0); |
| 4678 gaim_prefs_add_int("/gaim/gtk/blist/y", 0); | |
| 9778 | 4679 gaim_prefs_add_int("/gaim/gtk/blist/width", 309); /* Golden ratio, baby */ |
| 4680 gaim_prefs_add_int("/gaim/gtk/blist/height", 500); /* Golden ratio, baby */ | |
| 8819 | 4681 gaim_prefs_add_int("/gaim/gtk/blist/tooltip_delay", 500); |
| 7731 | 4682 |
| 8815 | 4683 /* Register our signals */ |
| 4684 gaim_signal_register(gtk_blist_handle, "gtkblist-created", | |
| 9811 | 4685 gaim_marshal_VOID__POINTER, NULL, 1, |
| 4686 gaim_value_new(GAIM_TYPE_SUBTYPE, | |
| 4687 GAIM_SUBTYPE_BLIST)); | |
| 8819 | 4688 |
| 4689 gaim_signal_register(gtk_blist_handle, "drawing-tooltip", | |
| 9811 | 4690 gaim_marshal_VOID__POINTER_POINTER, NULL, 2, |
| 4691 gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_BLIST_NODE), | |
| 10477 | 4692 gaim_value_new_outgoing(GAIM_TYPE_BOXED, "GString *")); |
| 11910 | 4693 |
| 4694 | |
| 4695 gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", gtk_blist_handle, GAIM_CALLBACK(buddy_signonoff_cb), NULL); | |
| 4696 gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-off", gtk_blist_handle, GAIM_CALLBACK(buddy_signonoff_cb), NULL); | |
| 7620 | 4697 } |
| 4698 | |
| 8815 | 4699 void |
| 4700 gaim_gtk_blist_uninit(void) { | |
| 4701 gaim_signals_unregister_by_instance(gaim_gtk_blist_get_handle()); | |
| 4702 } | |
| 5228 | 4703 |
| 4704 /********************************************************************* | |
| 4705 * Public utility functions * | |
| 4706 *********************************************************************/ | |
| 4707 | |
| 4708 GdkPixbuf * | |
| 10884 | 4709 gaim_gtk_create_prpl_icon(GaimAccount *account) |
| 5228 | 4710 { |
| 4711 GaimPlugin *prpl; | |
| 4712 GaimPluginProtocolInfo *prpl_info = NULL; | |
| 4713 GdkPixbuf *status = NULL; | |
| 4714 char *filename = NULL; | |
| 4715 const char *protoname = NULL; | |
| 4716 char buf[256]; | |
| 4717 | |
| 10046 | 4718 g_return_val_if_fail(account != NULL, NULL); |
| 4719 | |
| 7956 | 4720 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
| 5228 | 4721 |
| 4722 if (prpl != NULL) { | |
| 4723 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
| 4724 | |
| 4725 if (prpl_info->list_icon != NULL) | |
| 4726 protoname = prpl_info->list_icon(account, NULL); | |
| 4727 } | |
| 4728 | |
| 4729 if (protoname == NULL) | |
| 4730 return NULL; | |
| 4731 | |
| 4732 /* | |
| 4733 * Status icons will be themeable too, and then it will look up | |
| 4734 * protoname from the theme | |
| 4735 */ | |
| 4736 g_snprintf(buf, sizeof(buf), "%s.png", protoname); | |
| 4737 | |
| 4738 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", | |
| 4739 "default", buf, NULL); | |
| 4740 status = gdk_pixbuf_new_from_file(filename, NULL); | |
| 4741 g_free(filename); | |
| 4742 | |
| 4743 return status; | |
| 4744 } | |
| 4745 | |
| 5422 | 4746 |
| 4747 /********************************************************************* | |
| 9811 | 4748 * Buddy List sorting functions * |
| 5422 | 4749 *********************************************************************/ |
| 4750 | |
| 11796 | 4751 GList *gaim_gtk_blist_get_sort_methods() |
| 4752 { | |
| 4753 return gaim_gtk_blist_sort_methods; | |
| 4754 } | |
| 4755 | |
| 7620 | 4756 void gaim_gtk_blist_sort_method_reg(const char *id, const char *name, gaim_gtk_blist_sort_function func) |
| 5422 | 4757 { |
| 4758 struct gaim_gtk_blist_sort_method *method = g_new0(struct gaim_gtk_blist_sort_method, 1); | |
| 7620 | 4759 method->id = g_strdup(id); |
| 5422 | 4760 method->name = g_strdup(name); |
| 9775 | 4761 method->func = func; |
| 11796 | 4762 gaim_gtk_blist_sort_methods = g_list_append(gaim_gtk_blist_sort_methods, method); |
| 4763 gaim_gtk_blist_update_sort_methods(); | |
| 5422 | 4764 } |
| 4765 | |
| 7620 | 4766 void gaim_gtk_blist_sort_method_unreg(const char *id){ |
| 11796 | 4767 GList *l = gaim_gtk_blist_sort_methods; |
| 7620 | 4768 |
| 4769 while(l) { | |
| 4770 struct gaim_gtk_blist_sort_method *method = l->data; | |
| 4771 if(!strcmp(method->id, id)) { | |
| 11796 | 4772 gaim_gtk_blist_sort_methods = g_list_delete_link(gaim_gtk_blist_sort_methods, l); |
| 7620 | 4773 g_free(method->id); |
| 4774 g_free(method->name); | |
| 4775 g_free(method); | |
| 4776 break; | |
| 4777 } | |
| 4778 } | |
| 11796 | 4779 gaim_gtk_blist_update_sort_methods(); |
| 5422 | 4780 } |
| 4781 | |
| 7620 | 4782 void gaim_gtk_blist_sort_method_set(const char *id){ |
| 11796 | 4783 GList *l = gaim_gtk_blist_sort_methods; |
| 7620 | 4784 |
| 4785 if(!id) | |
| 4786 id = "none"; | |
| 4787 | |
| 4788 while (l && strcmp(((struct gaim_gtk_blist_sort_method*)l->data)->id, id)) | |
| 5422 | 4789 l = l->next; |
| 7620 | 4790 |
| 5422 | 4791 if (l) { |
| 4792 current_sort_method = l->data; | |
| 4793 } else if (!current_sort_method) { | |
| 7620 | 4794 gaim_gtk_blist_sort_method_set("none"); |
| 5422 | 4795 return; |
| 4796 } | |
| 4797 redo_buddy_list(gaim_get_blist(), TRUE); | |
| 4798 | |
| 4799 } | |
| 4800 | |
| 4801 /****************************************** | |
| 4802 ** Sort Methods | |
| 4803 ******************************************/ | |
| 4804 | |
| 7620 | 4805 static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter parent_iter, GtkTreeIter *cur) |
| 5422 | 4806 { |
| 7620 | 4807 GtkTreeIter iter; |
| 4808 GaimBlistNode *sibling = node->prev; | |
| 4809 GtkTreeIter sibling_iter; | |
| 4810 | |
| 4811 if(cur) | |
| 5422 | 4812 return *cur; |
| 7620 | 4813 |
| 4814 while (sibling && !get_iter_from_node(sibling, &sibling_iter)) { | |
| 4815 sibling = sibling->prev; | |
| 5422 | 4816 } |
| 7620 | 4817 |
| 4818 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, | |
| 4819 node->parent ? &parent_iter : NULL, | |
| 4820 sibling ? &sibling_iter : NULL); | |
| 4821 | |
| 5422 | 4822 return iter; |
| 4823 } | |
| 4824 | |
| 7620 | 4825 #if GTK_CHECK_VERSION(2,2,1) |
| 4826 | |
| 4827 static GtkTreeIter sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) | |
| 5422 | 4828 { |
| 4829 GtkTreeIter more_z, iter; | |
| 4830 GaimBlistNode *n; | |
| 4831 GValue val = {0,}; | |
| 7620 | 4832 |
| 4833 const char *my_name; | |
| 4834 | |
| 4835 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
| 4836 my_name = gaim_contact_get_alias((GaimContact*)node); | |
| 4837 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
| 4838 my_name = gaim_chat_get_name((GaimChat*)node); | |
| 4839 } else { | |
| 4840 return sort_method_none(node, blist, groupiter, cur); | |
| 4841 } | |
| 4842 | |
| 5422 | 4843 |
| 4844 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { | |
| 4845 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
| 7620 | 4846 return iter; |
| 4847 } | |
| 4848 | |
| 4849 do { | |
| 4850 const char *this_name; | |
| 4851 int cmp; | |
| 4852 | |
| 4853 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); | |
| 4854 n = g_value_get_pointer(&val); | |
| 4855 | |
| 4856 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
| 4857 this_name = gaim_contact_get_alias((GaimContact*)n); | |
| 4858 } else if(GAIM_BLIST_NODE_IS_CHAT(n)) { | |
| 4859 this_name = gaim_chat_get_name((GaimChat*)n); | |
| 4860 } else { | |
| 4861 this_name = NULL; | |
| 4862 } | |
| 4863 | |
| 4864 cmp = gaim_utf8_strcasecmp(my_name, this_name); | |
| 4865 | |
| 4866 if(this_name && (cmp < 0 || (cmp == 0 && node < n))) { | |
| 4867 if(cur) { | |
| 4868 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); | |
| 4869 return *cur; | |
| 4870 } else { | |
| 4871 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, | |
| 4872 &groupiter, &more_z); | |
| 4873 return iter; | |
| 4874 } | |
| 4875 } | |
| 4876 g_value_unset(&val); | |
| 4877 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z)); | |
| 4878 | |
| 4879 if(cur) { | |
| 4880 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
| 4881 return *cur; | |
| 4882 } else { | |
| 4883 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
| 4884 return iter; | |
| 4885 } | |
| 4886 } | |
| 4887 | |
| 4888 static GtkTreeIter sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) | |
| 4889 { | |
| 4890 GtkTreeIter more_z, iter; | |
| 4891 GaimBlistNode *n; | |
| 4892 GValue val = {0,}; | |
| 4893 | |
| 4894 GaimBuddy *my_buddy, *this_buddy; | |
| 4895 | |
| 4896 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
| 4897 my_buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
| 4898 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
| 4899 if(cur) | |
| 4900 return *cur; | |
| 4901 | |
| 4902 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
| 4903 return iter; | |
| 4904 } else { | |
| 4905 return sort_method_none(node, blist, groupiter, cur); | |
| 4906 } | |
| 4907 | |
| 4908 | |
| 4909 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { | |
| 4910 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
| 5422 | 4911 return iter; |
| 4912 } | |
| 4913 | |
| 4914 do { | |
| 9944 | 4915 gint name_cmp; |
| 4916 gint presence_cmp; | |
| 7620 | 4917 |
| 5422 | 4918 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); |
| 4919 n = g_value_get_pointer(&val); | |
| 7620 | 4920 |
| 4921 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
| 4922 this_buddy = gaim_contact_get_priority_buddy((GaimContact*)n); | |
| 4923 } else { | |
| 4924 this_buddy = NULL; | |
| 4925 } | |
| 4926 | |
| 9944 | 4927 name_cmp = gaim_utf8_strcasecmp( |
| 4928 (my_buddy | |
| 4929 ? gaim_contact_get_alias(gaim_buddy_get_contact(my_buddy)) | |
| 4930 : NULL), | |
| 4931 (this_buddy | |
| 4932 ? gaim_contact_get_alias(gaim_buddy_get_contact(this_buddy)) | |
| 4933 : NULL)); | |
| 4934 | |
| 4935 presence_cmp = gaim_presence_compare( | |
| 4936 gaim_buddy_get_presence(my_buddy), | |
| 4937 gaim_buddy_get_presence(this_buddy)); | |
| 4938 | |
| 4939 if (this_buddy == NULL || | |
| 10860 | 4940 (presence_cmp < 0 || |
| 9944 | 4941 (presence_cmp == 0 && |
| 4942 (name_cmp < 0 || (name_cmp == 0 && node < n))))) | |
| 4943 { | |
| 4944 if (cur != NULL) | |
| 4945 { | |
| 7620 | 4946 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); |
| 4947 return *cur; | |
| 9944 | 4948 } |
| 4949 else | |
| 4950 { | |
| 7620 | 4951 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, |
| 9944 | 4952 &groupiter, &more_z); |
| 7620 | 4953 return iter; |
| 4954 } | |
| 5422 | 4955 } |
| 9944 | 4956 |
| 5422 | 4957 g_value_unset(&val); |
| 9944 | 4958 } |
| 4959 while (gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), | |
| 4960 &more_z)); | |
| 7620 | 4961 |
| 4962 if(cur) { | |
| 4963 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
| 4964 return *cur; | |
| 4965 } else { | |
| 4966 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
| 4967 return iter; | |
| 4968 } | |
| 5422 | 4969 } |
| 4970 | |
| 7620 | 4971 static GtkTreeIter sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) |
| 5422 | 4972 { |
| 4973 GtkTreeIter more_z, iter; | |
| 7620 | 4974 GaimBlistNode *n = NULL, *n2; |
| 5422 | 4975 GValue val = {0,}; |
| 7620 | 4976 |
| 4977 int log_size = 0, this_log_size = 0; | |
| 4978 const char *buddy_name, *this_buddy_name; | |
| 4979 | |
| 4980 if(cur && (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter) == 1)) | |
| 4981 return *cur; | |
| 4982 | |
| 4983 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
| 4984 for (n = node->child; n; n = n->next) | |
| 8898 | 4985 log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy*)(n))->name, ((GaimBuddy*)(n))->account); |
| 7620 | 4986 buddy_name = gaim_contact_get_alias((GaimContact*)node); |
| 4987 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
| 4988 /* we don't have a reliable way of getting the log filename | |
| 4989 * from the chat info in the blist, yet */ | |
| 4990 if(cur) | |
| 4991 return *cur; | |
| 4992 | |
| 4993 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
| 4994 return iter; | |
| 4995 } else { | |
| 4996 return sort_method_none(node, blist, groupiter, cur); | |
| 4997 } | |
| 4998 | |
| 4999 | |
| 5422 | 5000 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { |
| 5001 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
| 5002 return iter; | |
| 5003 } | |
| 5004 | |
| 5005 do { | |
| 7620 | 5006 int cmp; |
| 5007 | |
| 5422 | 5008 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); |
| 5009 n = g_value_get_pointer(&val); | |
| 7620 | 5010 this_log_size = 0; |
| 5011 | |
| 5012 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
| 5013 for (n2 = n->child; n2; n2 = n2->next) | |
| 8898 | 5014 this_log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy*)(n2))->name, ((GaimBuddy*)(n2))->account); |
| 7620 | 5015 this_buddy_name = gaim_contact_get_alias((GaimContact*)n); |
| 5016 } else { | |
| 5017 this_buddy_name = NULL; | |
| 5422 | 5018 } |
| 7620 | 5019 |
| 5020 cmp = gaim_utf8_strcasecmp(buddy_name, this_buddy_name); | |
| 5021 | |
| 5022 if (!GAIM_BLIST_NODE_IS_CONTACT(n) || log_size > this_log_size || | |
| 5023 ((log_size == this_log_size) && | |
| 5024 (cmp < 0 || (cmp == 0 && node < n)))) { | |
| 5025 if(cur) { | |
| 5026 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); | |
| 5027 return *cur; | |
| 5028 } else { | |
| 5029 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, | |
| 5030 &groupiter, &more_z); | |
| 5031 return iter; | |
| 5032 } | |
| 5422 | 5033 } |
| 5034 g_value_unset(&val); | |
| 5035 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z)); | |
| 7620 | 5036 |
| 5037 if(cur) { | |
| 5038 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
| 5039 return *cur; | |
| 5040 } else { | |
| 5041 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
| 5042 return iter; | |
| 5043 } | |
| 5044 } | |
| 5045 | |
| 5046 #endif | |
| 5047 | |
| 5048 static void | |
| 9015 | 5049 plugin_act(GtkObject *obk, GaimPluginAction *pam) |
| 7620 | 5050 { |
| 10352 | 5051 if (pam->callback) |
| 5052 pam->callback(pam); | |
| 5422 | 5053 } |
| 7620 | 5054 |
| 11742 | 5055 static GList *plugin_menu_items = NULL; |
| 5056 static int plugin_menu_index = 8; | |
| 5057 | |
| 8986 | 5058 static void |
| 9015 | 5059 build_plugin_actions(GtkWidget *menu, GaimPlugin *plugin, gpointer context) |
| 8986 | 5060 { |
| 9015 | 5061 GtkWidget *menuitem = NULL; |
| 5062 GaimPluginAction *action = NULL; | |
| 5063 GList *l, *ll; | |
| 5064 | |
| 5065 for (l = ll = GAIM_PLUGIN_ACTIONS(plugin, context); l; l = l->next) { | |
| 5066 if (l->data) { | |
| 5067 action = (GaimPluginAction *) l->data; | |
| 5068 action->plugin = plugin; | |
| 5069 action->context = context; | |
| 5070 | |
| 5071 menuitem = gtk_menu_item_new_with_label(action->label); | |
| 11745 | 5072 if (context) { |
| 5073 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
| 5074 } else { | |
| 5075 plugin_menu_items = g_list_append(plugin_menu_items, menuitem); | |
| 5076 plugin_menu_index++; | |
| 5077 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menuitem, plugin_menu_index); | |
| 5078 } | |
| 9015 | 5079 g_signal_connect(G_OBJECT(menuitem), "activate", |
| 5080 G_CALLBACK(plugin_act), action); | |
| 5081 g_object_set_data(G_OBJECT(menuitem), "plugin_action", action); | |
| 5082 gtk_widget_show(menuitem); | |
| 5083 } | |
| 5084 else | |
| 5085 gaim_separator(menu); | |
| 5086 } | |
| 5087 | |
| 5088 g_list_free(ll); | |
| 8986 | 5089 } |
| 5090 | |
| 5091 | |
| 7620 | 5092 void |
| 5093 gaim_gtk_blist_update_protocol_actions(void) | |
| 5094 { | |
| 9015 | 5095 GtkWidget *menuitem, *submenu; |
| 7620 | 5096 GList *l; |
| 5097 GaimConnection *gc = NULL; | |
| 9015 | 5098 GaimPlugin *plugin = NULL; |
| 7620 | 5099 int count = 0; |
| 9015 | 5100 |
| 9019 | 5101 if (protomenu == NULL) |
| 7620 | 5102 return; |
| 5103 | |
| 9019 | 5104 /* Clear the old Account Actions menu */ |
| 9015 | 5105 for (l = gtk_container_get_children(GTK_CONTAINER(protomenu)); l; l = l->next) { |
| 5106 GaimPluginAction *action; | |
| 9987 | 5107 |
| 7620 | 5108 menuitem = l->data; |
| 9015 | 5109 action = (GaimPluginAction *) g_object_get_data(G_OBJECT(menuitem), |
| 5110 "plugin_action"); | |
| 5111 g_free(action); | |
| 7620 | 5112 |
| 5113 gtk_container_remove(GTK_CONTAINER(protomenu), GTK_WIDGET(menuitem)); | |
| 5114 } | |
| 5115 | |
| 9019 | 5116 /* Count the number of accounts with actions */ |
| 9015 | 5117 for (l = gaim_connections_get_all(); l; l = l->next) { |
| 5118 gc = l->data; | |
| 5119 plugin = gc->prpl; | |
| 5120 | |
| 9019 | 5121 if (GAIM_CONNECTION_IS_CONNECTED(gc) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
| 5122 count++; | |
| 5123 | |
| 9015 | 5124 /* no need to count past 2, so don't */ |
| 9019 | 5125 if (count > 1) |
| 9015 | 5126 break; |
| 7620 | 5127 } |
| 5128 | |
| 9015 | 5129 if (count == 0) { |
| 5130 menuitem = gtk_menu_item_new_with_label(_("No actions available")); | |
| 7620 | 5131 gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem); |
| 9015 | 5132 gtk_widget_set_sensitive(menuitem, FALSE); |
| 7620 | 5133 gtk_widget_show(menuitem); |
| 5134 } | |
| 9019 | 5135 |
| 5136 else if (count == 1) { | |
| 5137 /* Find the one account that has actions */ | |
| 5138 for (l = gaim_connections_get_all(); l; l = l->next) { | |
| 5139 gc = l->data; | |
| 5140 plugin = gc->prpl; | |
| 5141 | |
| 5142 if (GAIM_CONNECTION_IS_CONNECTED(gc) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) | |
| 5143 break; | |
| 5144 } | |
| 5145 | |
| 9015 | 5146 build_plugin_actions(protomenu, plugin, gc); |
| 7620 | 5147 } |
| 9019 | 5148 |
| 7620 | 5149 else { |
| 9015 | 5150 for (l = gaim_connections_get_all(); l; l = l->next) { |
| 7620 | 5151 GaimAccount *account; |
| 5152 GdkPixbuf *pixbuf, *scale; | |
| 5153 GtkWidget *image; | |
| 9015 | 5154 char *buf; |
| 5155 | |
| 5156 gc = l->data; | |
| 5157 plugin = gc->prpl; | |
| 5158 | |
| 9019 | 5159 if (!GAIM_CONNECTION_IS_CONNECTED(gc) || !GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
| 7620 | 5160 continue; |
| 5161 | |
| 5162 account = gaim_connection_get_account(gc); | |
| 9015 | 5163 buf = g_strconcat(gaim_account_get_username(account), " (", |
| 5164 plugin->info->name, ")", NULL); | |
| 7620 | 5165 menuitem = gtk_image_menu_item_new_with_label(buf); |
| 9015 | 5166 g_free(buf); |
| 5167 | |
| 10884 | 5168 pixbuf = gaim_gtk_create_prpl_icon(account); |
| 9019 | 5169 if (pixbuf) { |
| 7620 | 5170 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, |
| 5171 GDK_INTERP_BILINEAR); | |
| 5172 image = gtk_image_new_from_pixbuf(scale); | |
| 5173 g_object_unref(G_OBJECT(pixbuf)); | |
| 5174 g_object_unref(G_OBJECT(scale)); | |
| 5175 gtk_widget_show(image); | |
| 9015 | 5176 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); |
| 7620 | 5177 } |
| 5178 | |
| 5179 gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem); | |
| 5180 gtk_widget_show(menuitem); | |
| 5181 | |
| 5182 submenu = gtk_menu_new(); | |
| 5183 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
| 5184 gtk_widget_show(submenu); | |
| 5185 | |
| 9015 | 5186 build_plugin_actions(submenu, plugin, gc); |
| 7620 | 5187 } |
| 5188 } | |
| 5189 } | |
| 8986 | 5190 |
| 5191 void | |
| 5192 gaim_gtk_blist_update_plugin_actions(void) | |
| 5193 { | |
| 11742 | 5194 GtkWidget *menuitem; |
| 9015 | 5195 GaimPlugin *plugin = NULL; |
| 8986 | 5196 GList *l; |
| 5197 int count = 0; | |
| 5198 | |
| 11742 | 5199 GtkWidget *pluginmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools")); |
| 5200 | |
| 9019 | 5201 if (pluginmenu == NULL) |
| 8986 | 5202 return; |
| 5203 | |
| 9019 | 5204 /* Clear the old Account Actions menu */ |
| 11742 | 5205 for (l = plugin_menu_items; l; l = l->next) { |
| 9015 | 5206 GaimPluginAction *action; |
| 11742 | 5207 plugin_menu_index--; |
| 8986 | 5208 menuitem = l->data; |
| 9015 | 5209 action = g_object_get_data(G_OBJECT(menuitem), "plugin_action"); |
| 5210 g_free(action); | |
| 8986 | 5211 |
| 5212 gtk_container_remove(GTK_CONTAINER(pluginmenu), GTK_WIDGET(menuitem)); | |
| 5213 } | |
| 11742 | 5214 g_list_free(plugin_menu_items); |
| 5215 plugin_menu_items = NULL; | |
| 8986 | 5216 |
| 9019 | 5217 /* Count the number of plugins with actions */ |
| 9015 | 5218 for (l = gaim_plugins_get_loaded(); l; l = l->next) { |
| 5219 plugin = (GaimPlugin *) l->data; | |
| 5220 | |
| 9019 | 5221 if (!GAIM_IS_PROTOCOL_PLUGIN(plugin) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
| 5222 count++; | |
| 5223 | |
| 5224 /* no need to count past 2, so don't */ | |
| 5225 if (count > 1) | |
| 9015 | 5226 break; |
| 8986 | 5227 } |
| 5228 | |
| 11742 | 5229 for (l = gaim_plugins_get_loaded(); l; l = l->next) { |
| 11923 | 5230 |
| 11742 | 5231 plugin = (GaimPlugin *) l->data; |
| 11923 | 5232 |
| 11742 | 5233 if (GAIM_IS_PROTOCOL_PLUGIN(plugin)) |
| 5234 continue; | |
| 5235 | |
| 5236 if (!GAIM_PLUGIN_HAS_ACTIONS(plugin)) | |
| 5237 continue; | |
| 9019 | 5238 |
| 9015 | 5239 build_plugin_actions(pluginmenu, plugin, NULL); |
| 8986 | 5240 } |
| 5241 } | |
| 11796 | 5242 |
| 5243 void sortmethod_act(GtkCheckMenuItem *checkmenuitem, char *id) | |
| 5244 { | |
| 5245 if (gtk_check_menu_item_get_active(checkmenuitem)) | |
| 11923 | 5246 { |
| 11796 | 5247 gaim_gtk_blist_sort_method_set(id); |
| 11923 | 5248 gaim_prefs_set_string("/gaim/gtk/blist/sort_type", id); |
| 5249 } | |
| 11796 | 5250 } |
| 5251 | |
| 5252 void | |
| 5253 gaim_gtk_blist_update_sort_methods(void) | |
| 5254 { | |
| 5255 GtkWidget *menuitem = NULL, *activeitem = NULL; | |
| 5256 GaimGtkBlistSortMethod *method = NULL; | |
| 5257 GList *l; | |
| 5258 GSList *sl = NULL; | |
| 5259 GtkWidget *sortmenu; | |
| 11797 | 5260 const char *m = gaim_prefs_get_string("/gaim/gtk/blist/sort_type"); |
| 11796 | 5261 |
| 5262 if (gtkblist == NULL) | |
| 5263 return; | |
| 5264 | |
|
11798
01c3eec6ea3c
[gaim-migrate @ 14089]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11797
diff
changeset
|
5265 sortmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Sort Buddies")); |
| 11796 | 5266 |
| 5267 if (sortmenu == NULL) | |
| 5268 return; | |
| 5269 | |
| 5270 /* Clear the old menu */ | |
| 5271 for (l = gtk_container_get_children(GTK_CONTAINER(sortmenu)); l; l = l->next) { | |
| 5272 menuitem = l->data; | |
| 5273 gtk_widget_destroy(GTK_WIDGET(menuitem)); | |
| 5274 } | |
| 11923 | 5275 |
| 11796 | 5276 for (l = gaim_gtk_blist_sort_methods; l; l = l->next) { |
| 5277 method = (GaimGtkBlistSortMethod *) l->data; | |
| 5278 menuitem = gtk_radio_menu_item_new_with_label(sl, _(method->name)); | |
| 5279 if (!strcmp(m, method->id)) | |
| 5280 activeitem = menuitem; | |
| 5281 sl = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem)); | |
| 5282 gtk_menu_shell_append(GTK_MENU_SHELL(sortmenu), menuitem); | |
| 5283 g_signal_connect(G_OBJECT(menuitem), "toggled", | |
| 5284 G_CALLBACK(sortmethod_act), method->id); | |
| 11923 | 5285 gtk_widget_show(menuitem); |
| 11796 | 5286 } |
| 5287 if (activeitem) | |
| 5288 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(activeitem), TRUE); | |
| 5289 | |
| 5290 } |
