comparison src/buddy.c @ 4359:5fb47ec9bfe4

[gaim-migrate @ 4625] Wow, okay, where to begin with this one ;) I rewrote the whole conversation backend. It is now core/UI split. Here's how it works.. Every conversation is represented by a gaim_conversation structure. This branches out into gaim_im and gaim_chat structures. Every conversation lives in (well, normally, but it doesn't have to) a gaim_window structure. This is a _CORE_ representation of a window. There can be multiple gaim_window structures around. The gaim_window and gaim_conversation structures have UI-specific operation structures associated with them. At the moment, the only UI is GTK+, and this will be for some time. Don't start thinking you can write a QT UI now. It's just not going to happen. Everything that is done on a conversation is done through the core API. This API does core processing and then calls the UI operations for the rendering and anything else. Now, what does this give the user? - Multiple windows. - Multiple tabs per window. - Draggable tabs. - Send As menu is moved to the menubar. - Menubar for chats. - Some very cool stuff in the future, like replacing, say, IRC chat windows with an X-Chat interface, or whatever. - Later on, customizable window/conversation positioning. For developers: - Fully documented API - Core/UI split - Variable checking and mostly sane handling of incorrect variables. - Logical structure to conversations, both core and UI. - Some very cool stuff in the future, like replacing, say, IRC chat windows with an X-Chat interface, or whatever. - Later on, customizable window/conversation positioning. - Oh yeah, and the beginning of a stock icon system. Now, there are things that aren't there yet. You will see tabs even if you have them turned off. This will be fixed in time. Also, the preferences will change to work with the new structure. I'm starting school in 2 days, so it may not be done immediately, but hopefully in the next week. Enjoy! committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Mon, 20 Jan 2003 09:10:23 +0000
parents 0c68d402f59f
children bca8256a91a6
comparison
equal deleted inserted replaced
4358:2b8abf7f9cc1 4359:5fb47ec9bfe4
148 } 148 }
149 } 149 }
150 150
151 void handle_buddy_rename(struct buddy *b, char *prevname) 151 void handle_buddy_rename(struct buddy *b, char *prevname)
152 { 152 {
153 struct conversation *cnv; 153 struct gaim_conversation *cnv;
154 struct buddy_show *bs; 154 struct buddy_show *bs;
155 struct group_show *gs; 155 struct group_show *gs;
156 struct group *g; 156 struct group *g;
157 GtkCTreeNode *c; 157 GtkCTreeNode *c;
158 char buf[256]; 158 char buf[256];
162 g_snprintf(buf, sizeof(buf), "%s (%s)", b->name, get_buddy_alias(b)); 162 g_snprintf(buf, sizeof(buf), "%s (%s)", b->name, get_buddy_alias(b));
163 else 163 else
164 g_snprintf(buf, sizeof(buf), "%s", b->name); 164 g_snprintf(buf, sizeof(buf), "%s", b->name);
165 gtk_ctree_node_set_text(GTK_CTREE(edittree), c, 0, buf); 165 gtk_ctree_node_set_text(GTK_CTREE(edittree), c, 0, buf);
166 166
167 if ((cnv = find_conversation(b->name)) != NULL) 167 if ((cnv = gaim_find_conversation(b->name)) != NULL)
168 set_convo_title(cnv); 168 gaim_conversation_autoset_title(cnv);
169 169
170 g = find_group_by_buddy(b); 170 g = find_group_by_buddy(b);
171 if (!g) { 171 if (!g) {
172 /* shouldn't happen */ 172 /* shouldn't happen */
173 return; 173 return;
434 return FALSE; 434 return FALSE;
435 } 435 }
436 436
437 void pressed_im_bud(GtkWidget *widget, struct buddy *b) 437 void pressed_im_bud(GtkWidget *widget, struct buddy *b)
438 { 438 {
439 struct conversation *c; 439 struct gaim_conversation *c;
440 440
441 c = find_conversation(b->name); 441 c = gaim_find_conversation(b->name);
442 442
443 if (c != NULL) { 443 if (c != NULL) {
444 gdk_window_show(c->window->window); 444 gaim_window_show(gaim_conversation_get_window(c));
445 } else { 445 } else {
446 c = new_conversation(b->name); 446 c = gaim_conversation_new(GAIM_CONV_IM, b->name);
447 447
448 set_convo_gc(c, b->user->gc); 448 gaim_conversation_set_user(c, b->user);
449 } 449 }
450 } 450 }
451 451
452 void pressed_im(GtkWidget *widget, struct buddy_show *b) 452 void pressed_im(GtkWidget *widget, struct buddy_show *b)
453 { 453 {
454 struct conversation *c; 454 struct gaim_conversation *c;
455 455
456 c = find_conversation(b->name); 456 c = gaim_find_conversation(b->name);
457 457
458 if (c != NULL) { 458 if (c != NULL) {
459 gdk_window_show(c->window->window); 459 gaim_window_show(gaim_conversation_get_window(c));
460 } else { 460 } else {
461 c = new_conversation(b->name); 461 struct gaim_connection *gc;
462 462
463 set_convo_gc(c, b->connlist->data); 463 gc = (struct gaim_connection *)b->connlist->data;
464 c = gaim_conversation_new(GAIM_CONV_IM, b->name);
465
466 gaim_conversation_set_user(c, gc->user);
464 } 467 }
465 } 468 }
466 469
467 void pressed_log(GtkWidget *widget, char *name) 470 void pressed_log(GtkWidget *widget, char *name)
468 { 471 {
496 static int handle_click_buddy(GtkWidget *widget, GdkEventButton *event, struct buddy_show *b) 499 static int handle_click_buddy(GtkWidget *widget, GdkEventButton *event, struct buddy_show *b)
497 { 500 {
498 if (!b->connlist) 501 if (!b->connlist)
499 return FALSE; 502 return FALSE;
500 if (event->type == GDK_2BUTTON_PRESS && event->button == 1) { 503 if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
501 struct conversation *c; 504 struct gaim_conversation *c;
502 505 struct gaim_connection *gc;
503 c = find_conversation(b->name); 506
504 507 c = gaim_find_conversation(b->name);
505 if (c != NULL) 508
506 gdk_window_show(c->window->window); 509 if (c != NULL) {
510 struct gaim_window *win = gaim_conversation_get_window(c);
511 size_t index = gaim_conversation_get_index(c);
512
513 gaim_window_switch_conversation(win, index);
514 gaim_window_show(win);
515 }
507 else 516 else
508 c = new_conversation(b->name); 517 c = gaim_conversation_new(GAIM_CONV_IM, b->name);
509 518
510 set_convo_gc(c, b->connlist->data); 519 gc = (struct gaim_connection *)b->connlist->data;
511 if (im_options & OPT_IM_ONE_WINDOW) 520 gaim_conversation_set_user(c, gc->user);
512 raise_convo_tab(c); 521
513 gtk_widget_grab_focus(c->entry); 522 gaim_window_switch_conversation(gaim_conversation_get_window(c),
523 gaim_conversation_get_index(c));
524
525 /* XXX-GTK gtk_widget_grab_focus(c->entry); */
514 } else if (event->type == GDK_BUTTON_PRESS && event->button == 3) { 526 } else if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
515 static GtkWidget *menu = NULL; 527 static GtkWidget *menu = NULL;
516 static GList *mo_top = NULL; 528 static GList *mo_top = NULL;
517 GtkWidget *button; 529 GtkWidget *button;
518 GtkWidget *menuitem; 530 GtkWidget *menuitem;
781 } 793 }
782 } 794 }
783 795
784 void ui_remove_buddy(struct buddy *rem_b) 796 void ui_remove_buddy(struct buddy *rem_b)
785 { 797 {
786 struct conversation *c; 798 struct gaim_conversation *c;
787 struct group *rem_g = find_group_by_buddy(rem_b); 799 struct group *rem_g = find_group_by_buddy(rem_b);
788 struct group_show *gs; 800 struct group_show *gs;
789 struct buddy_show *bs; 801 struct buddy_show *bs;
790 802
791 gs = find_group_show(rem_g->name); 803 gs = find_group_show(rem_g->name);
816 } 828 }
817 if (gs) 829 if (gs)
818 update_num_group(gs); 830 update_num_group(gs);
819 } 831 }
820 832
821 c = find_conversation(rem_b->name); 833 c = gaim_find_conversation(rem_b->name);
834
822 if (c) 835 if (c)
823 update_buttons_by_protocol(c); 836 gaim_conversation_update(c, GAIM_CONV_UPDATE_REMOVE);
837
838 /* CONVXXX update_buttons_by_protocol(c); */
824 839
825 /* Remove CTree node for buddy */ 840 /* Remove CTree node for buddy */
826 ui_remove_buddy_node(rem_g, rem_b); 841 ui_remove_buddy_node(rem_g, rem_b);
827 842
828 } 843 }
936 } 951 }
937 } 952 }
938 update_idle_times(); 953 update_idle_times();
939 } 954 }
940 955
941 static void edit_tree_move(GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 956 void
942 GtkCTreeNode *sibling, gpointer data) 957 reset_convo_gcs()
958 {
959 GList *l;
960 struct gaim_conversation *c;
961
962 for (l = gaim_get_ims(); l != NULL; l = l->next) {
963 c = (struct gaim_conversation *)l->data;
964
965 if (!g_slist_find(connections, gaim_conversation_get_gc(c))) {
966 struct aim_user *user;
967
968 if (connections == NULL)
969 user = ((struct gaim_connection *)connections->data)->user;
970 else
971 user = NULL;
972
973 gaim_conversation_set_user(c, user);
974 }
975 }
976 }
977
978 static void edit_tree_move(GtkCTree *ctree, GtkCTreeNode *child,
979 GtkCTreeNode *parent, GtkCTreeNode *sibling,
980 gpointer data)
943 { 981 {
944 int *ctype, *ptype = NULL, *stype = NULL; 982 int *ctype, *ptype = NULL, *stype = NULL;
945 983
946 ctype = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), child); 984 ctype = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), child);
947 985
1239 1277
1240 static void im_callback(GtkWidget *widget, GtkTree *tree) 1278 static void im_callback(GtkWidget *widget, GtkTree *tree)
1241 { 1279 {
1242 GList *i; 1280 GList *i;
1243 struct buddy_show *b = NULL; 1281 struct buddy_show *b = NULL;
1244 struct conversation *c; 1282 struct gaim_conversation *c;
1283 struct aim_user *user;
1284
1245 i = GTK_TREE_SELECTION_OLD(tree); 1285 i = GTK_TREE_SELECTION_OLD(tree);
1246 if (i) { 1286 if (i) {
1247 b = gtk_object_get_user_data(GTK_OBJECT(i->data)); 1287 b = gtk_object_get_user_data(GTK_OBJECT(i->data));
1248 } 1288 }
1249 if (!i || !b) { 1289 if (!i || !b) {
1251 return; 1291 return;
1252 } 1292 }
1253 if (!b->name) 1293 if (!b->name)
1254 return; 1294 return;
1255 1295
1256 c = find_conversation(b->name); 1296 c = gaim_find_conversation(b->name);
1257 if (c == NULL) { 1297
1258 c = new_conversation(b->name); 1298 if (c == NULL)
1259 } else { 1299 c = gaim_conversation_new(GAIM_CONV_IM, b->name);
1260 gdk_window_raise(c->window->window); 1300 else
1261 } 1301 gaim_window_raise(gaim_conversation_get_window(c));
1262 1302
1263 set_convo_gc(c, b->connlist->data); 1303 user = ((struct gaim_connection *)b->connlist->data)->user;
1264 } 1304 gaim_conversation_set_user(c, user);
1265 1305 }
1266 1306
1267 static void info_callback(GtkWidget *widget, GtkTree *tree) 1307 static void info_callback(GtkWidget *widget, GtkTree *tree)
1268 { 1308 {
1269 GList *i; 1309 GList *i;
1270 struct buddy_show *b = NULL; 1310 struct buddy_show *b = NULL;
1330 void do_pounce(struct gaim_connection *gc, char *name, int when) 1370 void do_pounce(struct gaim_connection *gc, char *name, int when)
1331 { 1371 {
1332 char *who; 1372 char *who;
1333 1373
1334 struct buddy_pounce *b; 1374 struct buddy_pounce *b;
1335 struct conversation *c; 1375 struct gaim_conversation *c;
1336 struct aim_user *u; 1376 struct aim_user *u;
1337 1377
1338 GList *bp = buddy_pounces; 1378 GList *bp = buddy_pounces;
1339 1379
1340 who = g_strdup(normalize (name)); 1380 who = g_strdup(normalize (name));
1354 if (u->gc != gc) 1394 if (u->gc != gc)
1355 continue; 1395 continue;
1356 1396
1357 if (!g_strcasecmp(who, normalize (b->name))) { /* find someone to pounce */ 1397 if (!g_strcasecmp(who, normalize (b->name))) { /* find someone to pounce */
1358 if (b->options & OPT_POUNCE_POPUP) { 1398 if (b->options & OPT_POUNCE_POPUP) {
1359 c = find_conversation(name); 1399 c = gaim_find_conversation(name);
1400
1360 if (c == NULL) 1401 if (c == NULL)
1361 c = new_conversation(name); 1402 c = gaim_conversation_new(GAIM_CONV_IM, name);
1362 1403
1363 set_convo_gc(c, u->gc); 1404 gaim_conversation_set_user(c, u);
1364 } 1405 }
1365 if (b->options & OPT_POUNCE_NOTIFY) { 1406 if (b->options & OPT_POUNCE_NOTIFY) {
1366 char tmp[1024]; 1407 char tmp[1024];
1367 1408
1368 /* I know the line below is really ugly. I only did it this way 1409 /* I know the line below is really ugly. I only did it this way
1376 1417
1377 do_error_dialog(tmp, NULL, GAIM_INFO); 1418 do_error_dialog(tmp, NULL, GAIM_INFO);
1378 } 1419 }
1379 if (b->options & OPT_POUNCE_SEND_IM) { 1420 if (b->options & OPT_POUNCE_SEND_IM) {
1380 if (strlen(b->message) > 0) { 1421 if (strlen(b->message) > 0) {
1381 c = find_conversation(name); 1422 c = gaim_find_conversation(name);
1382 1423
1383 if (c == NULL) 1424 if (c == NULL)
1384 c = new_conversation(name); 1425 c = gaim_conversation_new(GAIM_CONV_IM, name);
1385 1426
1386 set_convo_gc(c, u->gc); 1427 gaim_conversation_set_user(c, u);
1387 1428
1388 write_to_conv(c, b->message, WFLAG_SEND, NULL, time(NULL), -1); 1429 gaim_conversation_write(c, NULL, b->message, -1,
1430 WFLAG_SEND, time(NULL));
1431
1389 serv_send_im(u->gc, name, b->message, -1, 0); 1432 serv_send_im(u->gc, name, b->message, -1, 0);
1390 } 1433 }
1391 } 1434 }
1392 if (b->options & OPT_POUNCE_COMMAND) { 1435 if (b->options & OPT_POUNCE_COMMAND) {
1393 #ifndef _WIN32 1436 #ifndef _WIN32
2174 b->present = 2; 2217 b->present = 2;
2175 if (bs->log_timer > 0) 2218 if (bs->log_timer > 0)
2176 g_source_remove(bs->log_timer); 2219 g_source_remove(bs->log_timer);
2177 bs->log_timer = g_timeout_add(10000, log_timeout, bs); 2220 bs->log_timer = g_timeout_add(10000, log_timeout, bs);
2178 if ((bs->sound != 2) && (im_options & OPT_IM_LOGON)) { 2221 if ((bs->sound != 2) && (im_options & OPT_IM_LOGON)) {
2179 struct conversation *c = find_conversation(b->name); 2222 struct gaim_conversation *c = gaim_find_conversation(b->name);
2180 if (c) { 2223 if (c) {
2181 char tmp[1024]; 2224 char tmp[1024];
2182 g_snprintf(tmp, sizeof(tmp), _("%s logged in."), 2225 g_snprintf(tmp, sizeof(tmp), _("%s logged in."),
2183 get_buddy_alias(b)); 2226 get_buddy_alias(b));
2184 write_to_conv(c, tmp, WFLAG_SYSTEM, NULL, time(NULL), -1); 2227 gaim_conversation_write(c, NULL, tmp, -1,
2228 WFLAG_SYSTEM, time(NULL));
2185 } else if (clistqueue && find_queue_total_by_name(b->name)) { 2229 } else if (clistqueue && find_queue_total_by_name(b->name)) {
2186 struct queued_message *qm = g_new0(struct queued_message, 1); 2230 struct queued_message *qm = g_new0(struct queued_message, 1);
2187 g_snprintf(qm->name, sizeof(qm->name), "%s", b->name); 2231 g_snprintf(qm->name, sizeof(qm->name), "%s", b->name);
2188 qm->message = g_strdup_printf(_("%s logged in."), 2232 qm->message = g_strdup_printf(_("%s logged in."),
2189 get_buddy_alias(b)); 2233 get_buddy_alias(b));
2235 gtk_pixmap_set(GTK_PIXMAP(bs->pix), pm, bm); 2279 gtk_pixmap_set(GTK_PIXMAP(bs->pix), pm, bm);
2236 gtk_widget_show(bs->pix); 2280 gtk_widget_show(bs->pix);
2237 gdk_pixmap_unref(pm); 2281 gdk_pixmap_unref(pm);
2238 gdk_bitmap_unref(bm); 2282 gdk_bitmap_unref(bm);
2239 if ((bs->sound != 1) && (im_options & OPT_IM_LOGON)) { 2283 if ((bs->sound != 1) && (im_options & OPT_IM_LOGON)) {
2240 struct conversation *c = find_conversation(b->name); 2284 struct gaim_conversation *c = gaim_find_conversation(b->name);
2241 if (c) { 2285 if (c) {
2242 char tmp[1024]; 2286 char tmp[1024];
2243 g_snprintf(tmp, sizeof(tmp), _("%s logged out."), 2287 g_snprintf(tmp, sizeof(tmp), _("%s logged out."),
2244 get_buddy_alias(b)); 2288 get_buddy_alias(b));
2245 write_to_conv(c, tmp, WFLAG_SYSTEM, NULL, time(NULL), -1); 2289 gaim_conversation_write(c, NULL, tmp, -1,
2290 WFLAG_SYSTEM, time(NULL));
2246 } else if (clistqueue && find_queue_total_by_name(b->name)) { 2291 } else if (clistqueue && find_queue_total_by_name(b->name)) {
2247 struct queued_message *qm = g_new0(struct queued_message, 1); 2292 struct queued_message *qm = g_new0(struct queued_message, 1);
2248 g_snprintf(qm->name, sizeof(qm->name), "%s", 2293 g_snprintf(qm->name, sizeof(qm->name), "%s",
2249 get_buddy_alias(b)); 2294 get_buddy_alias(b));
2250 qm->message = g_strdup_printf(_("%s logged out."), 2295 qm->message = g_strdup_printf(_("%s logged out."),