src/gtkblist.c

changeset 12413
ce06aa90beee
parent 12368
c05189876b11
child 12431
35be5bb89089
equal deleted inserted replaced
12412:8abe3226695e 12413:ce06aa90beee
105 static guint visibility_manager_count = 0; 105 static guint visibility_manager_count = 0;
106 static gboolean gtk_blist_obscured = FALSE; 106 static gboolean gtk_blist_obscured = FALSE;
107 107
108 static GList *gaim_gtk_blist_sort_methods = NULL; 108 static GList *gaim_gtk_blist_sort_methods = NULL;
109 static struct gaim_gtk_blist_sort_method *current_sort_method = NULL; 109 static struct gaim_gtk_blist_sort_method *current_sort_method = NULL;
110 static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); 110 static void sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
111 111
112 /* The functions we use for sorting aren't available in gtk 2.0.x, and 112 /* The functions we use for sorting aren't available in gtk 2.0.x, and
113 * segfault in 2.2.0. 2.2.1 is known to work, so I'll require that */ 113 * segfault in 2.2.0. 2.2.1 is known to work, so I'll require that */
114 #if GTK_CHECK_VERSION(2,2,1) 114 #if GTK_CHECK_VERSION(2,2,1)
115 static GtkTreeIter sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); 115 static void sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
116 static GtkTreeIter sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); 116 static void sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
117 static GtkTreeIter sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); 117 static void sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
118 #endif 118 #endif
119 static GaimGtkBuddyList *gtkblist = NULL; 119 static GaimGtkBuddyList *gtkblist = NULL;
120 120
121 static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node); 121 static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node);
122 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); 122 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data);
125 static char *item_factory_translate_func (const char *path, gpointer func_data); 125 static char *item_factory_translate_func (const char *path, gpointer func_data);
126 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter); 126 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter);
127 static void redo_buddy_list(GaimBuddyList *list, gboolean remove); 127 static void redo_buddy_list(GaimBuddyList *list, gboolean remove);
128 static void gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node); 128 static void gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node);
129 129
130 static void gaim_gtk_blist_tooltip_destroy(); 130 static void gaim_gtk_blist_tooltip_destroy(void);
131 131
132 struct _gaim_gtk_blist_node { 132 struct _gaim_gtk_blist_node {
133 GtkTreeRowReference *row; 133 GtkTreeRowReference *row;
134 gboolean contact_expanded; 134 gboolean contact_expanded;
135 gboolean recent_signonoff; 135 gboolean recent_signonoff;
3829 3829
3830 if(get_iter_from_node(node, &cur)) 3830 if(get_iter_from_node(node, &cur))
3831 curptr = &cur; 3831 curptr = &cur;
3832 3832
3833 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node)) { 3833 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node)) {
3834 *iter = current_sort_method->func(node, list, parent_iter, curptr); 3834 current_sort_method->func(node, list, parent_iter, curptr, iter);
3835 } else { 3835 } else {
3836 *iter = sort_method_none(node, list, parent_iter, curptr); 3836 sort_method_none(node, list, parent_iter, curptr, iter);
3837 } 3837 }
3838 3838
3839 if(gtknode != NULL) { 3839 if(gtknode != NULL) {
3840 gtk_tree_row_reference_free(gtknode->row); 3840 gtk_tree_row_reference_free(gtknode->row);
3841 } else { 3841 } else {
4660 data->account = account; 4660 data->account = account;
4661 rebuild_addchat_entries(data); 4661 rebuild_addchat_entries(data);
4662 } 4662 }
4663 } 4663 }
4664 4664
4665 void 4665 static void
4666 gaim_gtk_blist_request_add_chat(GaimAccount *account, GaimGroup *group, 4666 gaim_gtk_blist_request_add_chat(GaimAccount *account, GaimGroup *group,
4667 const char *alias, const char *name) 4667 const char *alias, const char *name)
4668 { 4668 {
4669 GaimGtkAddChatData *data; 4669 GaimGtkAddChatData *data;
4670 GaimGtkBuddyList *gtkblist; 4670 GaimGtkBuddyList *gtkblist;
4811 4811
4812 group = gaim_group_new(group_name); 4812 group = gaim_group_new(group_name);
4813 gaim_blist_add_group(group, NULL); 4813 gaim_blist_add_group(group, NULL);
4814 } 4814 }
4815 4815
4816 void 4816 static void
4817 gaim_gtk_blist_request_add_group(void) 4817 gaim_gtk_blist_request_add_group(void)
4818 { 4818 {
4819 gaim_request_input(NULL, _("Add Group"), NULL, 4819 gaim_request_input(NULL, _("Add Group"), NULL,
4820 _("Please enter the name of the group to be added."), 4820 _("Please enter the name of the group to be added."),
4821 NULL, FALSE, FALSE, NULL, 4821 NULL, FALSE, FALSE, NULL,
5059 5059
5060 /****************************************** 5060 /******************************************
5061 ** Sort Methods 5061 ** Sort Methods
5062 ******************************************/ 5062 ******************************************/
5063 5063
5064 static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter parent_iter, GtkTreeIter *cur) 5064 static void sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter parent_iter, GtkTreeIter *cur, GtkTreeIter *iter)
5065 { 5065 {
5066 GtkTreeIter iter;
5067 GaimBlistNode *sibling = node->prev; 5066 GaimBlistNode *sibling = node->prev;
5068 GtkTreeIter sibling_iter; 5067 GtkTreeIter sibling_iter;
5069 5068
5070 if(cur) 5069 if (cur != NULL) {
5071 return *cur; 5070 *iter = *cur;
5071 return;
5072 }
5072 5073
5073 while (sibling && !get_iter_from_node(sibling, &sibling_iter)) { 5074 while (sibling && !get_iter_from_node(sibling, &sibling_iter)) {
5074 sibling = sibling->prev; 5075 sibling = sibling->prev;
5075 } 5076 }
5076 5077
5077 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, 5078 gtk_tree_store_insert_after(gtkblist->treemodel, iter,
5078 node->parent ? &parent_iter : NULL, 5079 node->parent ? &parent_iter : NULL,
5079 sibling ? &sibling_iter : NULL); 5080 sibling ? &sibling_iter : NULL);
5080
5081 return iter;
5082 } 5081 }
5083 5082
5084 #if GTK_CHECK_VERSION(2,2,1) 5083 #if GTK_CHECK_VERSION(2,2,1)
5085 5084
5086 static GtkTreeIter sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) 5085 static void sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter)
5087 { 5086 {
5088 GtkTreeIter more_z, iter; 5087 GtkTreeIter more_z;
5089 GaimBlistNode *n; 5088 GaimBlistNode *n;
5090 GValue val = {0,}; 5089 GValue val = {0,};
5091 5090
5092 const char *my_name; 5091 const char *my_name;
5093 5092
5094 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { 5093 if(GAIM_BLIST_NODE_IS_CONTACT(node)) {
5095 my_name = gaim_contact_get_alias((GaimContact*)node); 5094 my_name = gaim_contact_get_alias((GaimContact*)node);
5096 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { 5095 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) {
5097 my_name = gaim_chat_get_name((GaimChat*)node); 5096 my_name = gaim_chat_get_name((GaimChat*)node);
5098 } else { 5097 } else {
5099 return sort_method_none(node, blist, groupiter, cur); 5098 sort_method_none(node, blist, groupiter, cur, iter);
5099 return;
5100 } 5100 }
5101 5101
5102 5102
5103 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { 5103 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) {
5104 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); 5104 gtk_tree_store_insert(gtkblist->treemodel, iter, &groupiter, 0);
5105 return iter; 5105 return;
5106 } 5106 }
5107 5107
5108 do { 5108 do {
5109 const char *this_name; 5109 const char *this_name;
5110 int cmp; 5110 int cmp;
5123 cmp = gaim_utf8_strcasecmp(my_name, this_name); 5123 cmp = gaim_utf8_strcasecmp(my_name, this_name);
5124 5124
5125 if(this_name && (cmp < 0 || (cmp == 0 && node < n))) { 5125 if(this_name && (cmp < 0 || (cmp == 0 && node < n))) {
5126 if(cur) { 5126 if(cur) {
5127 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); 5127 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z);
5128 return *cur; 5128 *iter = *cur;
5129 return;
5129 } else { 5130 } else {
5130 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, 5131 gtk_tree_store_insert_before(gtkblist->treemodel, iter,
5131 &groupiter, &more_z); 5132 &groupiter, &more_z);
5132 return iter; 5133 return;
5133 } 5134 }
5134 } 5135 }
5135 g_value_unset(&val); 5136 g_value_unset(&val);
5136 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z)); 5137 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z));
5137 5138
5138 if(cur) { 5139 if(cur) {
5139 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); 5140 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL);
5140 return *cur; 5141 *iter = *cur;
5142 return;
5141 } else { 5143 } else {
5142 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); 5144 gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
5143 return iter; 5145 return;
5144 } 5146 }
5145 } 5147 }
5146 5148
5147 static GtkTreeIter sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) 5149 static void sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter)
5148 { 5150 {
5149 GtkTreeIter more_z, iter; 5151 GtkTreeIter more_z;
5150 GaimBlistNode *n; 5152 GaimBlistNode *n;
5151 GValue val = {0,}; 5153 GValue val = {0,};
5152 5154
5153 GaimBuddy *my_buddy, *this_buddy; 5155 GaimBuddy *my_buddy, *this_buddy;
5154 5156
5155 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { 5157 if(GAIM_BLIST_NODE_IS_CONTACT(node)) {
5156 my_buddy = gaim_contact_get_priority_buddy((GaimContact*)node); 5158 my_buddy = gaim_contact_get_priority_buddy((GaimContact*)node);
5157 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { 5159 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) {
5158 if(cur) 5160 if (cur != NULL) {
5159 return *cur; 5161 *iter = *cur;
5160 5162 return;
5161 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); 5163 }
5162 return iter; 5164
5165 gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
5166 return;
5163 } else { 5167 } else {
5164 return sort_method_none(node, blist, groupiter, cur); 5168 sort_method_none(node, blist, groupiter, cur, iter);
5169 return;
5165 } 5170 }
5166 5171
5167 5172
5168 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { 5173 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) {
5169 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); 5174 gtk_tree_store_insert(gtkblist->treemodel, iter, &groupiter, 0);
5170 return iter; 5175 return;
5171 } 5176 }
5172 5177
5173 do { 5178 do {
5174 gint name_cmp; 5179 gint name_cmp;
5175 gint presence_cmp; 5180 gint presence_cmp;
5201 (name_cmp < 0 || (name_cmp == 0 && node < n))))) 5206 (name_cmp < 0 || (name_cmp == 0 && node < n)))))
5202 { 5207 {
5203 if (cur != NULL) 5208 if (cur != NULL)
5204 { 5209 {
5205 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); 5210 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z);
5206 return *cur; 5211 *iter = *cur;
5212 return;
5207 } 5213 }
5208 else 5214 else
5209 { 5215 {
5210 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, 5216 gtk_tree_store_insert_before(gtkblist->treemodel, iter,
5211 &groupiter, &more_z); 5217 &groupiter, &more_z);
5212 return iter; 5218 return;
5213 } 5219 }
5214 } 5220 }
5215 5221
5216 g_value_unset(&val); 5222 g_value_unset(&val);
5217 } 5223 }
5218 while (gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), 5224 while (gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel),
5219 &more_z)); 5225 &more_z));
5220 5226
5221 if(cur) { 5227 if (cur) {
5222 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); 5228 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL);
5223 return *cur; 5229 *iter = *cur;
5230 return;
5224 } else { 5231 } else {
5225 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); 5232 gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
5226 return iter; 5233 return;
5227 } 5234 }
5228 } 5235 }
5229 5236
5230 static GtkTreeIter sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) 5237 static void sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter)
5231 { 5238 {
5232 GtkTreeIter more_z, iter; 5239 GtkTreeIter more_z;
5233 GaimBlistNode *n = NULL, *n2; 5240 GaimBlistNode *n = NULL, *n2;
5234 GValue val = {0,}; 5241 GValue val = {0,};
5235 5242
5236 int log_size = 0, this_log_size = 0; 5243 int log_size = 0, this_log_size = 0;
5237 const char *buddy_name, *this_buddy_name; 5244 const char *buddy_name, *this_buddy_name;
5238 5245
5239 if(cur && (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter) == 1)) 5246 if(cur && (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter) == 1)) {
5240 return *cur; 5247 *iter = *cur;
5248 return;
5249 }
5241 5250
5242 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { 5251 if(GAIM_BLIST_NODE_IS_CONTACT(node)) {
5243 for (n = node->child; n; n = n->next) 5252 for (n = node->child; n; n = n->next)
5244 log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy*)(n))->name, ((GaimBuddy*)(n))->account); 5253 log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy*)(n))->name, ((GaimBuddy*)(n))->account);
5245 buddy_name = gaim_contact_get_alias((GaimContact*)node); 5254 buddy_name = gaim_contact_get_alias((GaimContact*)node);
5246 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { 5255 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) {
5247 /* we don't have a reliable way of getting the log filename 5256 /* we don't have a reliable way of getting the log filename
5248 * from the chat info in the blist, yet */ 5257 * from the chat info in the blist, yet */
5249 if(cur) 5258 if (cur != NULL) {
5250 return *cur; 5259 *iter = *cur;
5251 5260 return;
5252 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); 5261 }
5253 return iter; 5262
5263 gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
5264 return;
5254 } else { 5265 } else {
5255 return sort_method_none(node, blist, groupiter, cur); 5266 sort_method_none(node, blist, groupiter, cur, iter);
5267 return;
5256 } 5268 }
5257 5269
5258 5270
5259 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { 5271 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) {
5260 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); 5272 gtk_tree_store_insert(gtkblist->treemodel, iter, &groupiter, 0);
5261 return iter; 5273 return;
5262 } 5274 }
5263 5275
5264 do { 5276 do {
5265 int cmp; 5277 int cmp;
5266 5278
5279 cmp = gaim_utf8_strcasecmp(buddy_name, this_buddy_name); 5291 cmp = gaim_utf8_strcasecmp(buddy_name, this_buddy_name);
5280 5292
5281 if (!GAIM_BLIST_NODE_IS_CONTACT(n) || log_size > this_log_size || 5293 if (!GAIM_BLIST_NODE_IS_CONTACT(n) || log_size > this_log_size ||
5282 ((log_size == this_log_size) && 5294 ((log_size == this_log_size) &&
5283 (cmp < 0 || (cmp == 0 && node < n)))) { 5295 (cmp < 0 || (cmp == 0 && node < n)))) {
5284 if(cur) { 5296 if (cur != NULL) {
5285 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); 5297 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z);
5286 return *cur; 5298 *iter = *cur;
5299 return;
5287 } else { 5300 } else {
5288 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, 5301 gtk_tree_store_insert_before(gtkblist->treemodel, iter,
5289 &groupiter, &more_z); 5302 &groupiter, &more_z);
5290 return iter; 5303 return;
5291 } 5304 }
5292 } 5305 }
5293 g_value_unset(&val); 5306 g_value_unset(&val);
5294 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z)); 5307 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z));
5295 5308
5296 if(cur) { 5309 if (cur != NULL) {
5297 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); 5310 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL);
5298 return *cur; 5311 *iter = *cur;
5312 return;
5299 } else { 5313 } else {
5300 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); 5314 gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
5301 return iter; 5315 return;
5302 } 5316 }
5303 } 5317 }
5304 5318
5305 #endif 5319 #endif
5306 5320
5590 static void 5604 static void
5591 sortmethod_act(GtkCheckMenuItem *checkmenuitem, char *id) 5605 sortmethod_act(GtkCheckMenuItem *checkmenuitem, char *id)
5592 { 5606 {
5593 if (gtk_check_menu_item_get_active(checkmenuitem)) 5607 if (gtk_check_menu_item_get_active(checkmenuitem))
5594 { 5608 {
5609 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
5610
5611 gdk_window_set_cursor(gtkblist->window->window, cursor);
5612 gdk_cursor_unref(cursor);
5613 while (gtk_events_pending())
5614 gtk_main_iteration();
5615
5595 gaim_gtk_blist_sort_method_set(id); 5616 gaim_gtk_blist_sort_method_set(id);
5596 gaim_prefs_set_string("/gaim/gtk/blist/sort_type", id); 5617 gaim_prefs_set_string("/gaim/gtk/blist/sort_type", id);
5618
5619 gdk_window_set_cursor(gtkblist->window->window, NULL);
5597 } 5620 }
5598 } 5621 }
5599 5622
5600 void 5623 void
5601 gaim_gtk_blist_update_sort_methods(void) 5624 gaim_gtk_blist_update_sort_methods(void)

mercurial