00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032
00033 #include "intl.h"
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <gdk/gdkkeysyms.h>
00037 #include <ctype.h>
00038 #include <assert.h>
00039
00040 #include "chat_window.h"
00041 #include "util.h"
00042 #include "gtkspell.h"
00043 #include "add_contact_window.h"
00044 #include "sound.h"
00045 #include "dialog.h"
00046 #include "globals.h"
00047 #include "status.h"
00048 #include "away_window.h"
00049 #include "message_parse.h"
00050 #include "gtk_eb_html.h"
00051 #include "plugin.h"
00052 #include "contact_actions.h"
00053 #include "smileys.h"
00054 #include "prefs.h"
00055
00056 #include "pixmaps/tb_book_red.xpm"
00057 #include "pixmaps/tb_open.xpm"
00058 #include "pixmaps/tb_volume.xpm"
00059 #include "pixmaps/tb_edit.xpm"
00060 #include "pixmaps/tb_search.xpm"
00061 #include "pixmaps/tb_no.xpm"
00062 #include "pixmaps/tb_mail_send.xpm"
00063 #include "pixmaps/cancel.xpm"
00064 #include "pixmaps/smiley_button.xpm"
00065
00066 #define BUF_SIZE 1024
00067 #ifndef NAME_MAX
00068 #define NAME_MAX 4096
00069 #endif
00070
00071
00072 #ifdef HAVE_ICONV_H
00073 #include <iconv.h>
00074 #include <errno.h>
00075
00076
00077
00078
00079
00080
00081 #define RECODE_TO_REMOTE 1
00082 #define RECODE_TO_LOCAL 0
00083
00084
00085 static chat_window * find_tabbed_chat_window_index (int current_page);
00086 char *
00087 recode_if_needed(char * source_text, char * recoded_text, int direction)
00088 {
00089 size_t inleft;
00090 size_t outleft;
00091 char * ptr_src_text = source_text;
00092 char * ptr_recoded_text = recoded_text;
00093 iconv_t conv_desc;
00094 int tries;
00095
00096 if( use_recoding == 1 )
00097 {
00098 if( direction == RECODE_TO_REMOTE )
00099 {
00100 conv_desc = iconv_open( cGetLocalPref("remote_encoding"), cGetLocalPref("local_encoding") );
00101 }
00102 else
00103 {
00104 conv_desc = iconv_open( cGetLocalPref("local_encoding"), cGetLocalPref("remote_encoding") );
00105 }
00106
00107 if( conv_desc != (iconv_t)(-1) )
00108 {
00109 ptr_src_text = source_text;
00110 inleft = strlen(source_text) + 1;
00111
00112
00113 outleft = inleft * 2 + 1;
00114
00115 for(tries = 0; tries < 4; tries++ )
00116 {
00117 if( iconv(conv_desc, &ptr_src_text, &inleft,
00118 &ptr_recoded_text, &outleft) == (size_t)(-1) )
00119 {
00120 if( inleft && errno == EILSEQ )
00121 {
00122
00123
00124
00125
00126
00127
00128 if( tries == 3 )
00129 {
00130 strcpy( ptr_recoded_text, ptr_src_text );
00131 fprintf( stderr, "Yattm: recoding broke 3 times,"
00132 " leaving the rest of the line as it is...\n");
00133 break;
00134 } else
00135 {
00136
00137
00138
00139 *ptr_recoded_text = '.';
00140 ptr_recoded_text++;
00141 ptr_src_text++;
00142 inleft--;
00143 outleft--;
00144 fprintf( stderr, "Yattm: charachter cannot be recoded, "
00145 "trying to skip it...\n");
00146 continue;
00147 }
00148 }
00149 else if (errno == EINVAL )
00150 {
00151 fprintf( stderr, "Yattm: recoding broke - "
00152 "incomplete multibyte sequence at the end of the line.\n");
00153 break;
00154 }
00155 else if (errno == E2BIG )
00156 {
00157 fprintf( stderr, "Yattm: recoding buffer too small?!! Oops! :(\n");
00158 break;
00159 }
00160 else
00161 {
00162 fprintf( stderr, "Yattm: unknown recoding error.\n");
00163 break;
00164 }
00165 }
00166 }
00167 *(ptr_recoded_text + strlen(ptr_src_text)) = '\0';
00168
00169 iconv_close(conv_desc);
00170 return recoded_text;
00171 }
00172 else
00173 {
00174 fprintf( stderr, "Yattm: recoding from %s to %s is not valid, sorry!\n"
00175 "Turning recoding off.\n",
00176 cGetLocalPref("local_encoding"), cGetLocalPref("remote_encoding"));
00177 use_recoding = 0;
00178 return source_text;
00179 }
00180 }
00181
00182 return source_text;
00183 }
00184
00185 #endif
00186
00187
00188
00189 void eb_update_window_title(chat_window * cw, gboolean new_message);
00190 void eb_update_window_title_to_tab(int tab, gboolean new_message);
00191
00192 GList *outgoing_message_filters=NULL;
00193 GList *incoming_message_filters=NULL;
00194
00195 static void set_tab_red(GtkNotebook *notebook, GtkWidget *child)
00196 {
00197 GtkStyle *style;
00198 GdkColor color;
00199
00200 GtkWidget *label = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), child);
00201
00202 gtk_widget_realize(label);
00203
00204 color.red = 65000;
00205 color.green = 0;
00206 color.blue = 0;
00207
00208
00209 style = gtk_style_new();
00210 gdk_font_unref(style->font);
00211 style->font = gdk_font_ref(label->style->font);
00212 style->fg[0] = color;
00213
00214 gtk_widget_set_style(label, style);
00215
00216
00217 }
00218
00219 static void set_tab_normal(GtkNotebook *notebook, GtkWidget *child)
00220 {
00221 GtkStyle *style;
00222 GdkColor color;
00223
00224 GtkWidget *label = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), child);
00225 gtk_widget_realize(label);
00226
00227 color.red = 0;
00228 color.green = 0;
00229 color.blue = 0;
00230
00231 style = gtk_style_new();
00232 gdk_font_unref(style->font);
00233 style->font = gdk_font_ref(label->style->font);
00234 style->fg[0] = GTK_WIDGET(notebook)->style->fg[0];
00235
00236 gtk_widget_set_style(label, style);
00237 gtk_style_unref(style);
00238 }
00239
00240
00241 static void end_conversation(chat_window* cw)
00242 {
00243 GList * node;
00244
00245
00246
00247
00248 if (cw->contact != NULL)
00249 {
00250 cw->contact->chatwindow = NULL;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260 for(node = cw->contact->accounts; node; node = node->next)
00261 {
00262 eb_account *ea = (eb_account*)(node->data);
00263
00264 if(eb_services[ea->service_id].sc->terminate_chat)
00265 {
00266 RUN_SERVICE(ea)->terminate_chat(ea);
00267 }
00268 }
00269
00270 for(node=cw->history; node!=NULL; node=node->next)
00271 {
00272 free(node->data);
00273 node->data=NULL;
00274 }
00275
00276 g_list_free(cw->history);
00277
00278
00279
00280
00281
00282
00283 if(do_logging)
00284 {
00285 time_t my_time = time(NULL);
00286
00287 fprintf(cw->fp, _("%sConversation ended on %s %s\n"),
00288 (do_strip_html ? "" : "<P ALIGN=\"CENTER\"><B>"),
00289 g_strchomp(asctime(localtime(&my_time))),
00290 (do_strip_html ? "" : "</B></P>"));
00291 }
00292
00293
00294
00295
00296
00297 if ((cw->fp != NULL )) fclose(cw->fp);
00298
00299
00300
00301
00302
00303
00304
00305 memset(cw, 0, sizeof(chat_window));
00306 g_free(cw);
00307 }
00308
00309
00310
00311
00312
00313 static void destroy_event(GtkWidget *widget, gpointer userdata)
00314 {
00315 chat_window* cw = (chat_window*)userdata;
00316
00317
00318 end_conversation(cw);
00319 }
00320
00321 static void close_tab_callback(GtkWidget *button, gpointer userdata)
00322 {
00323 chat_window *cw = (chat_window*)userdata;
00324 GtkWidget *window = cw->window;
00325 GtkWidget *notebook = cw->notebook;
00326 gint tab_number;
00327
00328
00329
00330 tab_number = gtk_notebook_page_num(GTK_NOTEBOOK(notebook),
00331 cw->notebook_child);
00332
00333 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), tab_number);
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 if (gtk_notebook_get_number_pages(GTK_NOTEBOOK(notebook)) == 0) {
00350
00351
00352 gtk_widget_destroy(window);
00353 }
00354 }
00355
00356 static void add_unknown_callback(GtkWidget * add_button, gpointer userdata)
00357 {
00358 chat_window * cw = userdata;
00359
00360
00361
00362
00363
00364 cw->perfered = find_suitable_remote_account(cw->perfered, cw->contact);
00365
00366
00367
00368
00369
00370 if(!cw->perfered)
00371 cw->perfered = cw->contact->accounts->data;
00372
00373
00374
00375
00376
00377 if(!cw->perfered)
00378 return;
00379
00380
00381
00382 add_unknown_account_window_new(cw->perfered);
00383 }
00384
00385 #define GET_CHAT_WINDOW(cur_cw) {\
00386 if(do_tabbed_chat) { \
00387 chat_window *bck = cur_cw; \
00388 if (cur_cw->notebook) \
00389 cur_cw = find_tabbed_chat_window_index(gtk_notebook_get_current_page(GTK_NOTEBOOK(cur_cw->notebook))); \
00390 if (cur_cw == NULL) \
00391 cur_cw = bck; \
00392 } \
00393 }
00394
00395 void send_message(GtkWidget *widget, gpointer d)
00396 {
00397 chat_window * data = (chat_window*)d;
00398 gchar buff[BUF_SIZE];
00399 gchar buff2[BUF_SIZE];
00400 gchar * text, *o_text;
00401 gchar * link_message;
00402 gchar * temp_message;
00403 struct tm * cur_time;
00404 time_t t;
00405
00406 GList * filter_walk;
00407
00408 #ifdef HAVE_ICONV_H
00409
00410
00411 char recode_buff[BUF_SIZE*2 + 1];
00412 #endif
00413 GET_CHAT_WINDOW(data);
00414
00415
00416 data->perfered= find_suitable_remote_account(data->perfered, data->contact);
00417
00418
00419 if(!data->perfered)
00420 {
00421
00422
00423 if(data->contact->send_offline && can_offline_message(data->contact))
00424 {
00425 data->perfered = can_offline_message(data->contact);
00426 }
00427 else
00428 {
00429 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), "<hr>", 0,0,0);
00430 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), "<b>Cannot send message - user is offline.</b>", 0, 0, 0);
00431 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), "<hr>", 0,0,0);
00432 return;
00433 }
00434 }
00435
00436 if(data->local_user && data->local_user->service_id != data->perfered->service_id)
00437 {
00438 data->local_user = NULL;
00439 }
00440
00441 if(data->local_user && !data->local_user->connected)
00442 {
00443 data->local_user = NULL;
00444 }
00445
00446
00447
00448 if(!data->local_user)
00449 {
00450 data->local_user =
00451 find_suitable_local_account(data->local_user, data->perfered->service_id);
00452 }
00453
00454 if(!data->local_user) {
00455 return;
00456 }
00457
00458 eb_update_window_title(data, FALSE);
00459
00460 text = gtk_editable_get_chars(GTK_EDITABLE (data->entry), 0, -1);
00461
00462 if(strlen(text) == 0)
00463 return;
00464
00465 if(data->this_msg_in_history)
00466 {
00467 GList * node=NULL;
00468 GList * node2=NULL;
00469
00470 for(node=data->history; node!=NULL ; node=node->next)
00471 {
00472 node2=node;
00473 }
00474 free(node2->data);
00475 node2->data=strdup(text);
00476 data->this_msg_in_history=0;
00477 } else {
00478 data->history=g_list_append(data->history, strdup(text));
00479 data->hist_pos=NULL;
00480 }
00481
00482 temp_message = eb_smilify(strdup(text), RUN_SERVICE(data->local_user)->get_smileys());
00483 link_message = linkify(temp_message);
00484 g_free(temp_message);
00485
00486 eb_update_window_title(data, FALSE);
00487
00488
00489 filter_walk=outgoing_message_filters;
00490
00491 eb_debug(DBG_CORE, "Starting to run outgoing filters\n");
00492
00493 while(filter_walk!=NULL)
00494 {
00495 gchar * (*ifilter)(eb_local_account *, eb_account *, struct contact *, gchar *);
00496
00497 eb_debug(DBG_CORE, "Running an outgoing filter\n");
00498
00499 ifilter=(gchar *(*)(eb_local_account *, eb_account *, struct contact *, gchar *))filter_walk->data;
00500
00501 text=ifilter(data->local_user, data->perfered, data->contact, text);
00502
00503 if(text==NULL) { return; }
00504
00505 filter_walk=g_list_next(filter_walk);
00506 }
00507
00508 eb_debug(DBG_CORE, "Finished outgoing filters\n");
00509
00510
00511
00512 o_text = text;
00513 text = convert_eol(text);
00514 g_free(o_text);
00515
00516 #ifdef HAVE_ICONV_H
00517 if(!eb_services[data->perfered->service_id].can_iconvert)
00518 {
00519 RUN_SERVICE(data->local_user)->send_im(
00520 data->local_user,
00521 data->perfered,
00522 text);
00523 }
00524 else
00525 {
00526 RUN_SERVICE(data->local_user)->send_im(
00527 data->local_user,
00528 data->perfered,
00529 recode_if_needed(text, recode_buff, RECODE_TO_REMOTE) );
00530 }
00531
00532
00533 #else
00534 RUN_SERVICE(data->local_user)->send_im(
00535 data->local_user,
00536 data->perfered,
00537 text);
00538 #endif
00539 serv_touch_idle();
00540
00541 if(data->sound_enabled && data->send_enabled)
00542 play_sound(SEND);
00543
00544 if (do_convo_timestamp)
00545 {
00546 time(&t);
00547 cur_time = localtime(&t);
00548 g_snprintf(buff2, BUF_SIZE, "%d:%.2d:%.2d %s", cur_time->tm_hour,
00549 cur_time->tm_min, cur_time->tm_sec,
00550 data->local_user->alias);
00551 }
00552 else
00553 {
00554 g_snprintf(buff2, BUF_SIZE, "%s", data->local_user->alias);
00555 }
00556
00557 g_snprintf(buff, BUF_SIZE, "<FONT COLOR=\"#0000ff\"><B>%s: </B></FONT>", buff2);
00558
00559 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), buff, 1, 0, 0);
00560 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), link_message, do_ignore_back, do_ignore_fore, do_ignore_font);
00561 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), "<br>", 0, 0, 0);
00562
00563
00564
00565
00566
00567 if (data->away_msg_sent)
00568 {
00569 data->away_msg_sent = FALSE;
00570 }
00571
00572
00573
00574 if(do_logging) eb_log_message(data->fp, buff, link_message);
00575
00576 gtk_editable_delete_text(GTK_EDITABLE (data->entry), 0, -1);
00577 g_free(link_message);
00578 g_free(text);
00579
00580
00581
00582 if (data->notebook != NULL) {
00583
00584
00585
00586 set_tab_normal(GTK_NOTEBOOK(data->notebook), data->notebook_child);
00587 }
00588 }
00589
00590
00591
00592
00593
00594
00595 static void view_log_callback(GtkWidget *widget, gpointer d)
00596 {
00597 chat_window* data = (chat_window*)d;
00598 GET_CHAT_WINDOW(data);
00599 eb_view_log(data->contact);
00600 }
00601
00602 static void insert_smiley (GtkWidget * widget, chat_window * cw)
00603 {
00604 gint pos=0;
00605 GET_CHAT_WINDOW(cw);
00606 if(GTK_EDITABLE(cw->entry) && GTK_EDITABLE(cw->entry)->current_pos)
00607 pos=GTK_EDITABLE(cw->entry)->current_pos;
00608 gtk_editable_insert_text(GTK_EDITABLE (cw->entry),
00609 gtk_widget_get_name(widget),
00610 strlen(gtk_widget_get_name(widget)),
00611 &pos);
00612 gtk_widget_destroy(cw->smiley_window);
00613 cw->smiley_window = NULL;
00614 }
00615
00616 static void show_smileys_callback(GtkWidget *widget, gpointer d)
00617 {
00618 chat_window *data = (chat_window*) d;
00619 GList *smileys = NULL;
00620 protocol_smiley * msmiley = NULL;
00621 GtkWidget * smileys_table = NULL;
00622 GtkWidget * button = NULL;
00623 GtkWidget *iconwid;
00624 GdkPixmap *icon;
00625 GdkBitmap *mask;
00626 GList *done = NULL;
00627 int len = 0, real_len = 0, x=-1, y=0;
00628 int win_w=0, win_h=0, w, h;
00629 gint win_x, win_y;
00630 if(data->smiley_window != NULL) {
00631
00632 gtk_widget_destroy(data->smiley_window);
00633 data->smiley_window = NULL;
00634 return;
00635 }
00636
00637 if (data && data->local_user && RUN_SERVICE(data->local_user))
00638 smileys = RUN_SERVICE(data->local_user)->get_smileys();
00639 else
00640 return;
00641 len = g_list_length(smileys);
00642 smileys_table = gtk_table_new(5,len/5 +((len%5==0)?1:2),TRUE);
00643 for(;smileys;smileys=g_list_next(smileys)) {
00644 GList * l;
00645 gboolean already_done = FALSE;
00646 smiley * dsmile = NULL;
00647 msmiley = (smileys->data);
00648 for(l=done; l; l=g_list_next(l)) {
00649 if(!strcmp((char*)l->data, msmiley->name)) {
00650 already_done = TRUE;
00651 break;
00652 }
00653 }
00654
00655 if(already_done)
00656 continue;
00657
00658 done = g_list_append(done, msmiley->name);
00659
00660 dsmile = get_smiley_by_name(msmiley->name);
00661 if(dsmile != NULL) {
00662 icon = gdk_pixmap_create_from_xpm_d(data->window->window, &mask, NULL, dsmile->pixmap);
00663 iconwid = gtk_pixmap_new(icon, mask);
00664 sscanf (dsmile->pixmap [0], "%d %d", &w, &h);
00665 if(x<5) {
00666 x++;
00667 if(y==0) win_h+=h+2;
00668 }
00669 if(x==5) {
00670 y++;
00671 x=0;
00672 if(x==0) win_w+=w+2;
00673 }
00674 gtk_widget_show(iconwid);
00675 button = gtk_button_new();
00676 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
00677 gtk_container_add(GTK_CONTAINER(button), iconwid);
00678 gtk_widget_show(button);
00679 gtk_widget_set_name(button,msmiley->text);
00680 gtk_signal_connect (GTK_OBJECT (button), "clicked",
00681 GTK_SIGNAL_FUNC (insert_smiley), data);
00682 gtk_table_attach(GTK_TABLE(smileys_table),
00683 button,
00684 y,y+1,
00685 x,x+1,
00686 GTK_FILL, GTK_FILL, 0, 0);
00687 real_len++;
00688 }
00689 }
00690
00691 g_list_free(done);
00692 done = NULL;
00693 gtk_table_resize(GTK_TABLE(smileys_table), 5,real_len/5 +((real_len%5==0)?0:1));
00694
00695 data->smiley_window = gtk_window_new(GTK_WINDOW_DIALOG);
00696 gtk_window_set_modal(GTK_WINDOW(data->smiley_window), FALSE);
00697 gtk_window_set_wmclass(GTK_WINDOW(data->smiley_window), "yattm-chat", "Yattm");
00698 gtk_window_set_title(GTK_WINDOW(data->smiley_window), "Smileys");
00699 gtk_window_set_policy(GTK_WINDOW(data->smiley_window), FALSE, FALSE, FALSE);
00700 gtk_widget_realize(data->smiley_window);
00701
00702 gtk_widget_show(data->smiley_window);
00703
00704 gtk_container_add(GTK_CONTAINER(data->smiley_window), smileys_table);
00705 gtk_widget_show(smileys_table);
00706
00707
00708 gdk_window_get_pointer (NULL, &win_x, &win_y, NULL);
00709 win_x += 5; win_y += 5;
00710 while ((win_x)+win_w > gdk_screen_width() - 30)
00711 win_x -= 20;
00712 while ((win_y)+win_h > gdk_screen_height() - 30)
00713 win_y -= 20;
00714 gdk_window_move_resize(data->smiley_window->window, win_x, win_y, win_w, win_h);
00715
00716 }
00717
00718
00719
00720 static void ignore_dialog_callback (GtkWidget *widget, gpointer userdata)
00721 {
00722 struct contact *c = (struct contact *)userdata;
00723 int response = (int)gtk_object_get_user_data(GTK_OBJECT(widget));
00724
00725 if (response)
00726 {
00727 move_contact(_("Ignore"), c);
00728 update_contact_list ();
00729 write_contact_list();
00730 }
00731
00732 }
00733
00734 static void ignore_callback (GtkWidget *ignore_button, gpointer userdata)
00735 {
00736 chat_window * cw = (chat_window *)userdata;
00737 gchar *buff = (gchar *)g_new0(gchar *, BUF_SIZE);
00738 GET_CHAT_WINDOW(cw);
00739
00740 g_snprintf(buff, BUF_SIZE, _("Do you really want to ignore %s?\n"), cw->contact->nick);
00741
00742 do_dialog(buff, _("Ignore Contact"), ignore_dialog_callback, cw->contact);
00743 g_free(buff);
00744 }
00745
00746
00747 static void send_file (GtkWidget * sendf_button, gpointer userdata)
00748 {
00749 eb_account *ea;
00750 chat_window *data = (chat_window*)userdata;
00751 GET_CHAT_WINDOW(data);
00752
00753 if ( data->contact->online == 0 )
00754 {
00755 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), "<hr>", 0,0,0);
00756 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), "<b>Cannot send message - user is offline.</b>", 0, 0, 0);
00757 gtk_eb_html_add(EXT_GTK_TEXT(data->chat), "<hr>", 0,0,0);
00758 return;
00759 }
00760
00761 ea = find_suitable_remote_account(data->perfered,
00762 data->contact);
00763
00764 eb_do_send_file(ea);
00765 }
00766
00767
00768
00769 static void set_sound_on_toggle(GtkWidget * sound_button, gpointer userdata)
00770 {
00771 chat_window * cw = (chat_window *)userdata;
00772
00773
00774
00775 if (GTK_TOGGLE_BUTTON (sound_button)->active)
00776 cw->sound_enabled = TRUE;
00777 else
00778 cw->sound_enabled = FALSE;
00779 }
00780
00781 static void set_sound_on_click(GtkWidget * button, gpointer userdata)
00782 {
00783 chat_window * cw = (chat_window *)userdata;
00784 GET_CHAT_WINDOW(cw);
00785
00786 if (cw->sound_enabled)
00787 {
00788 cw->sound_enabled = FALSE;
00789 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cw->sound_button), FALSE);
00790 }
00791
00792 else
00793 {
00794 cw->sound_enabled = TRUE;
00795 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cw->sound_button), TRUE);
00796 }
00797 }
00798
00799
00800
00801 static void close_win (GtkWidget * close_button, gpointer userdata)
00802 {
00803 chat_window * cw = (chat_window *)userdata;
00804 if(cw->smiley_window != NULL && cw->smiley_window->window != NULL) {
00805
00806 gtk_widget_destroy(cw->smiley_window);
00807 cw->smiley_window = NULL;
00808 }
00809 gtk_widget_destroy(cw->window);
00810 }
00811
00812 static void allow_offline_on_toggle (GtkWidget *allow_button, gpointer userdata)
00813 {
00814 chat_window * cw = (chat_window *)userdata;
00815
00816
00817
00818 if (GTK_TOGGLE_BUTTON (allow_button)->active)
00819 {
00820 cw->contact->send_offline = TRUE;
00821 }
00822 else
00823 {
00824 cw->contact->send_offline = FALSE;
00825 }
00826 }
00827
00828 static void allow_offline_on_click (GtkWidget * button, gpointer userdata)
00829 {
00830 chat_window * cw = (chat_window *)userdata;
00831 GET_CHAT_WINDOW(cw);
00832
00833 if (cw->contact->send_offline)
00834 {
00835 cw->contact->send_offline = FALSE;
00836 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cw->allow_button), FALSE);
00837 }
00838 else
00839 {
00840 cw->contact->send_offline = TRUE;
00841 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cw->allow_button), TRUE);
00842 }
00843 }
00844
00845 static void change_local_account_on_click (GtkWidget * button, gpointer userdata)
00846 {
00847 GtkLabel *label= GTK_LABEL (GTK_BIN (button)->child);
00848 chat_window_account *cwa = (chat_window_account *)userdata;
00849 chat_window * cw;
00850 gchar *account;
00851 eb_local_account *ela=NULL;
00852
00853
00854 if(!cwa)
00855 return;
00856 cw=cwa->cw;
00857 ela=(eb_local_account *)cwa->data;
00858 cw->local_user=ela;
00859
00860 gtk_label_get(label, &account);
00861 eb_debug(DBG_CORE, "change_local_account_on_click: %s\n", account);
00862 }
00863
00864 GtkWidget *get_local_accounts(chat_window *cw)
00865 {
00866 GtkWidget *submenu, *label, *button;
00867 char *handle=NULL, buff[256];
00868 eb_local_account *first_act=NULL, *subsequent_act=NULL;
00869 chat_window_account *cwa=NULL;
00870
00871
00872 if(!cw->perfered) {
00873 cw->perfered = find_suitable_remote_account(NULL, cw->contact);
00874 if(!cw->perfered)
00875 return(NULL);
00876 }
00877 handle=cw->perfered->handle;
00878 eb_debug(DBG_CORE, "Setting menu item with label: %s\n", handle);
00879
00880 first_act = find_local_account_for_remote(cw->perfered, TRUE);
00881 subsequent_act = find_local_account_for_remote(NULL, TRUE);
00882 if(!first_act || !subsequent_act)
00883 return(NULL);
00884
00885 first_act = find_local_account_for_remote(cw->perfered, TRUE);
00886
00887
00888 label = gtk_menu_item_new_with_label(_("Change Local Account"));
00889 submenu = gtk_menu_new();
00890 gtk_menu_item_set_submenu(GTK_MENU_ITEM(label), submenu);
00891
00892 subsequent_act = first_act;
00893 do {
00894 sprintf(buff, "%s:%s", get_service_name(subsequent_act->service_id), subsequent_act->alias);
00895 button = gtk_menu_item_new_with_label(buff);
00896 gtk_menu_append(GTK_MENU(submenu), button);
00897 cwa = g_new0(chat_window_account, 1);
00898 cwa->cw=cw;
00899 cwa->data=subsequent_act;
00900 gtk_signal_connect(GTK_OBJECT(button), "activate",
00901 GTK_SIGNAL_FUNC(change_local_account_on_click), cwa);
00902 gtk_widget_show(button);
00903 } while( (subsequent_act = find_local_account_for_remote(NULL, TRUE)));
00904 gtk_widget_show(label);
00905 gtk_widget_show(submenu);
00906
00907 return(label);
00908 }
00909
00910 static void handle_focus(GtkWidget *widget, GdkEventFocus * event,
00911 gpointer userdata)
00912 {
00913 chat_window * cw = (chat_window *)userdata;
00914 eb_update_window_title(cw, FALSE);
00915
00916 }
00917
00918
00919
00920 static void handle_click(GtkWidget *widget, GdkEventButton * event,
00921 gpointer userdata)
00922 {
00923 chat_window * cw = (chat_window*)userdata;
00924
00925 if (event->type == GDK_BUTTON_PRESS && event->button == 3)
00926 {
00927 GtkWidget *menu;
00928 GtkWidget *button;
00929 menu_data *md=NULL;
00930 menu_item_data *mid=NULL;
00931 ebmContactData *ecd=NULL;
00932 GList *list=NULL;
00933
00934 gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),
00935 "button_press_event");
00936 menu = gtk_menu_new();
00937
00938
00939
00940 if(!strcmp(cw->contact->group->name, _("Unknown")))
00941 {
00942 button = gtk_menu_item_new_with_label(_("Add Contact"));
00943 gtk_signal_connect(GTK_OBJECT(button), "activate",
00944 GTK_SIGNAL_FUNC(add_unknown_callback), cw);
00945 gtk_menu_append(GTK_MENU(menu), button);
00946 gtk_widget_show(button);
00947 }
00948
00949
00950
00951 if(can_offline_message(cw->contact))
00952 {
00953 button = gtk_menu_item_new_with_label(_("Offline Messaging"));
00954 gtk_signal_connect(GTK_OBJECT(button), "activate",
00955 GTK_SIGNAL_FUNC(allow_offline_on_click), cw);
00956 gtk_menu_append(GTK_MENU(menu), button);
00957 gtk_widget_show(button);
00958 }
00959
00960
00961 button = get_local_accounts(cw);
00962 if(button)
00963 gtk_menu_append(GTK_MENU(menu), button);
00964
00965
00966
00967 if (cw->sound_enabled)
00968 button = gtk_menu_item_new_with_label(_("Disable Sounds"));
00969 else
00970 button = gtk_menu_item_new_with_label(_("Enable Sounds"));
00971
00972 gtk_signal_connect(GTK_OBJECT(button), "activate",
00973 GTK_SIGNAL_FUNC(set_sound_on_click), cw);
00974 gtk_menu_append(GTK_MENU(menu), button);
00975 gtk_widget_show(button);
00976
00977
00978
00979 button = gtk_menu_item_new_with_label(_("View Log"));
00980 gtk_signal_connect(GTK_OBJECT(button), "activate",
00981 GTK_SIGNAL_FUNC(view_log_callback), cw);
00982 gtk_menu_append(GTK_MENU(menu), button);
00983 gtk_widget_show(button);
00984
00985
00986
00987 button = gtk_menu_item_new_with_label(_("Send File"));
00988 gtk_signal_connect(GTK_OBJECT(button), "activate",
00989 GTK_SIGNAL_FUNC(send_file), cw);
00990 gtk_menu_append(GTK_MENU(menu), button);
00991 gtk_widget_show(button);
00992
00993
00994
00995 button = gtk_menu_item_new_with_label(_("Ignore Contact"));
00996 gtk_signal_connect(GTK_OBJECT(button), "activate",
00997 GTK_SIGNAL_FUNC(ignore_callback), cw);
00998 gtk_menu_append(GTK_MENU(menu), button);
00999 gtk_widget_show(button);
01000
01001
01002
01003 button = gtk_menu_item_new_with_label(_("Send Message"));
01004 gtk_signal_connect(GTK_OBJECT(button), "activate",
01005 GTK_SIGNAL_FUNC(send_message), cw);
01006 gtk_menu_append(GTK_MENU(menu), button);
01007 gtk_widget_show(button);
01008
01009
01010 md = GetPref(EB_CHAT_WINDOW_MENU);
01011 if(md) {
01012 for(list = md->menu_items; list; list = g_list_next(list) ) {
01013 ecd=ebmContactData_new();
01014 ecd->contact=cw->contact->nick;
01015 mid=(menu_item_data *)list->data;
01016 mid->data=(ebmCallbackData *)ecd;
01017 eb_debug(DBG_CORE, "adding chat window item: %s\n", mid->label);
01018 button = gtk_menu_item_new_with_label(mid->label);
01019 gtk_menu_append(GTK_MENU(menu), button);
01020 gtk_signal_connect(GTK_OBJECT(button), "activate",
01021 eb_generic_menu_function, mid);
01022 gtk_widget_show(button);
01023 }
01024 }
01025
01026
01027
01028
01029 button = gtk_menu_item_new_with_label(_("Close"));
01030
01031 if (do_tabbed_chat)
01032 {
01033 gtk_signal_connect(GTK_OBJECT(button), "activate",
01034 GTK_SIGNAL_FUNC(close_tab_callback), cw);
01035 } else {
01036 gtk_signal_connect(GTK_OBJECT(button), "activate",
01037 GTK_SIGNAL_FUNC(close_win), cw);
01038 }
01039 gtk_menu_append(GTK_MENU(menu), button);
01040 gtk_widget_show(button);
01041
01042 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
01043 event->button, event->time );
01044 }
01045 }
01046
01047 static void send_typing_status(chat_window *cw)
01048 {
01049
01050 time_t now=time(NULL);
01051
01052 if(!do_send_typing_notify)
01053 return;
01054
01055 if(now>=cw->next_typing_send)
01056 {
01057 if(!cw->perfered) {
01058 if(!cw->contact)
01059 return;
01060 cw->perfered = find_suitable_remote_account(NULL, cw->contact);
01061 if(!cw->perfered)
01062 return;
01063 }
01064 cw->local_user=find_suitable_local_account(cw->local_user, cw->perfered->service_id);
01065 if(cw->local_user==NULL) { return; }
01066
01067 if(RUN_SERVICE(cw->local_user)->send_typing!=NULL)
01068 {
01069 cw->next_typing_send=now + RUN_SERVICE(cw->local_user)->send_typing(cw->local_user, cw->perfered);
01070 }
01071 }
01072 }
01073
01074 static gboolean chat_singleline_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
01075 {
01076 chat_window *cw = (chat_window *)data;
01077 if(!(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_MOD4_MASK)))
01078 {
01079 send_typing_status(cw);
01080 }
01081 return gtk_true();
01082 }
01083
01084 static gboolean chat_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
01085 {
01086 chat_window *cw = (chat_window *)data;
01087 GdkModifierType modifiers = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_MOD4_MASK);
01088
01089 eb_update_window_title(cw, FALSE);
01090
01091 if (event->keyval == GDK_Return)
01092 {
01093
01094 if (event->state & GDK_SHIFT_MASK)
01095 {
01096 event->state = 0;
01097 }
01098 else if (do_enter_send)
01099 {
01100
01101 gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event");
01102
01103 send_message(NULL, cw);
01104 return gtk_true();
01105 }
01106 }
01107 else if (event->keyval == GDK_Up)
01108 {
01109 gint p=0;
01110
01111 if(cw->history==NULL) { return gtk_true(); }
01112
01113 if(cw->hist_pos==NULL)
01114 {
01115 char * s;
01116 GList * node;
01117
01118 s= gtk_editable_get_chars(GTK_EDITABLE (cw->entry), 0, -1);
01119
01120 for(node=cw->history; node!=NULL ; node=node->next)
01121 {
01122 cw->hist_pos=node;
01123 }
01124
01125 if(strlen(s)>0)
01126 {
01127 cw->history=g_list_append(cw->history, strdup(s));
01128
01129 g_free(s);
01130
01131
01132
01133
01134 cw->this_msg_in_history=1;
01135 }
01136
01137 } else {
01138 cw->hist_pos=cw->hist_pos->prev;
01139 if(cw->hist_pos==NULL)
01140 {
01141 GList * node;
01142 printf("Wrapped!\n");
01143 for(node=cw->history; node!=NULL ; node=node->next)
01144 {
01145 cw->hist_pos=node;
01146 }
01147 }
01148 }
01149
01150 gtk_editable_delete_text(GTK_EDITABLE (cw->entry), 0, -1);
01151 gtk_editable_insert_text(GTK_EDITABLE (cw->entry), cw->hist_pos->data, strlen(cw->hist_pos->data), &p);
01152 }
01153 else if (event->keyval == GDK_Down)
01154 {
01155 gint p=0;
01156
01157 if(cw->history==NULL || cw->hist_pos==NULL) { return gtk_true(); }
01158 cw->hist_pos=cw->hist_pos->next;
01159 if(cw->hist_pos==NULL)
01160 {
01161 gtk_editable_delete_text(GTK_EDITABLE (cw->entry), 0, -1);
01162 } else {
01163 gtk_editable_delete_text(GTK_EDITABLE (cw->entry), 0, -1);
01164 gtk_editable_insert_text(GTK_EDITABLE (cw->entry), cw->hist_pos->data, strlen(cw->hist_pos->data), &p);
01165 }
01166 }
01167 else if (cw->notebook != NULL)
01168 {
01169
01170
01171
01172
01173
01174 if ((modifiers == accel_prev_tab.modifiers) && (event->keyval == accel_prev_tab.keyval))
01175 {
01176 gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event");
01177 gtk_notebook_prev_page( GTK_NOTEBOOK(cw->notebook) );
01178 return gtk_true();
01179 }
01180 else if ((modifiers == accel_next_tab.modifiers) && (event->keyval == accel_next_tab.keyval))
01181 {
01182 gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event");
01183 gtk_notebook_next_page( GTK_NOTEBOOK(cw->notebook) );
01184 return gtk_true();
01185 }
01186 }
01187
01188 if(cw->perfered==NULL || modifiers)
01189 { return gtk_false(); }
01190
01191 if(!modifiers)
01192 {
01193 send_typing_status(cw);
01194 }
01195
01196 return gtk_false();
01197 }
01198
01199 static void chat_notebook_switch_callback(GtkNotebook *notebook, GtkNotebookPage *page, gint page_num, gpointer user_data)
01200 {
01201
01202 GList * l1;
01203 GList * l2;
01204 struct contact* c;
01205
01206 for(l1 = groups; l1; l1=l1->next )
01207 {
01208 for(l2 = ((grouplist*)l1->data)->members; l2; l2=l2->next )
01209 {
01210
01211
01212
01213 c = (struct contact*)l2->data;
01214 if (c->chatwindow != NULL) {
01215 if (c->chatwindow->notebook_child == page->child) {
01216
01217
01218 set_tab_normal(GTK_NOTEBOOK(c->chatwindow->notebook), c->chatwindow->notebook_child);
01219 gtk_widget_grab_focus(c->chatwindow->entry);
01220 eb_update_window_title_to_tab (page_num, FALSE);
01221 }
01222 }
01223 }
01224 }
01225 }
01226
01227
01228 static chat_window* find_tabbed_chat_window()
01229 {
01230 GList * l1;
01231 GList * l2;
01232 struct contact* c;
01233
01234 for(l1 = groups; l1; l1=l1->next )
01235 {
01236 for(l2 = ((grouplist*)l1->data)->members; l2; l2=l2->next )
01237 {
01238 c = (struct contact*)l2->data;
01239 if (c->chatwindow != NULL) {
01240 if (c->chatwindow->notebook != NULL) {
01241 return c->chatwindow;
01242 }
01243 }
01244 }
01245 }
01246
01247 return NULL;
01248 }
01249
01250 static chat_window *
01251 find_tabbed_chat_window_index (int current_page)
01252 {
01253 GList *l1;
01254 GList *l2;
01255 struct contact *c;
01256
01257 chat_window *notebook_window = find_tabbed_chat_window ();
01258 if (notebook_window == NULL || notebook_window->notebook == NULL)
01259 {
01260 return NULL;
01261 }
01262
01263
01264 for (l1 = groups; l1; l1 = l1->next)
01265 {
01266 for (l2 = ((grouplist *) l1->data)->members; l2; l2 = l2->next)
01267 {
01268 c = (struct contact *) l2->data;
01269 if (c->chatwindow != NULL)
01270 {
01271 if (gtk_notebook_page_num
01272 (GTK_NOTEBOOK (notebook_window->notebook),
01273 c->chatwindow->notebook_child) == current_page)
01274 {
01275 return c->chatwindow;
01276 }
01277 }
01278 }
01279 }
01280
01281 return NULL;
01282 }
01283 static chat_window *
01284 find_tabbed_current_chat_window ()
01285 {
01286 GList *l1;
01287 GList *l2;
01288 struct contact *c;
01289 int current_page = 0;
01290
01291 chat_window *notebook_window = find_tabbed_chat_window ();
01292 if (notebook_window == NULL || notebook_window->notebook == NULL)
01293 {
01294 return NULL;
01295 }
01296
01297 current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook_window->notebook));
01298
01299
01300 for (l1 = groups; l1; l1 = l1->next)
01301 {
01302 for (l2 = ((grouplist *) l1->data)->members; l2; l2 = l2->next)
01303 {
01304 c = (struct contact *) l2->data;
01305 if (c->chatwindow != NULL)
01306 {
01307 if (gtk_notebook_page_num
01308 (GTK_NOTEBOOK (notebook_window->notebook),
01309 c->chatwindow->notebook_child) == current_page)
01310 {
01311 return c->chatwindow;
01312 }
01313 }
01314 }
01315 }
01316
01317 return NULL;
01318 }
01319
01320 chat_window * eb_chat_window_new(eb_local_account * local, struct contact * remote)
01321 {
01322 GtkWidget *vbox;
01323 GtkWidget *hbox;
01324 GtkWidget *scrollwindow;
01325 GtkWidget *toolbar;
01326 GtkWidget *add_button;
01327 GtkWidget *sendf_button;
01328 GtkWidget *send_button;
01329 GtkWidget *view_log_button;
01330 GtkWidget *close_button;
01331 GtkWidget *ignore_button;
01332 GtkWidget *iconwid;
01333 GdkPixmap *icon;
01334 GdkBitmap *mask;
01335 GtkAccelGroup *accel_group;
01336 GtkWidget *menu;
01337 GtkWidget *button;
01338 GtkWidget *separator;
01339 GtkWidget *resize_bar;
01340 gchar buff[NAME_MAX];
01341 chat_window *cw;
01342 chat_window *tab_cw;
01343 GtkPositionType pos;
01344 GtkWidget *contact_label;
01345
01346 if (do_ignore_unknown)
01347 {
01348 if (!strcmp(_("Unknown"), remote->group->name))
01349 return NULL;
01350 }
01351
01352
01353 cw = g_new0(chat_window,1);
01354 cw->contact = remote;
01355 cw->away_msg_sent = 0;
01356 cw->perfered = NULL;
01357 cw->local_user = NULL;
01358
01359 vbox = gtk_vbox_new(FALSE,0);
01360
01361
01362 if (do_tabbed_chat) {
01363
01364 tab_cw = find_tabbed_chat_window();
01365 if (tab_cw == NULL) {
01366
01367 cw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
01368 gtk_window_set_wmclass(GTK_WINDOW(cw->window), "yattm-chat", "Yattm");
01369 gtk_window_set_policy(GTK_WINDOW(cw->window), TRUE, TRUE, TRUE);
01370 gtk_widget_realize(cw->window);
01371
01372 cw->notebook = gtk_notebook_new();
01373
01374
01375 pos = GTK_POS_BOTTOM;
01376 switch (do_tabbed_chat_orient)
01377 {
01378 case 1:
01379 pos = GTK_POS_TOP;
01380 break;;
01381
01382 case 2:
01383 pos = GTK_POS_LEFT;
01384 break;;
01385
01386 case 3:
01387 pos = GTK_POS_RIGHT;
01388 break;;
01389
01390 case 0:
01391 default:
01392 pos = GTK_POS_BOTTOM;
01393 break;;
01394 }
01395 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(cw->notebook), pos);
01396
01397
01398 gtk_notebook_set_scrollable(GTK_NOTEBOOK(cw->notebook), TRUE);
01399 gtk_container_add(GTK_CONTAINER(cw->window), cw->notebook);
01400
01401
01402 gtk_signal_connect(GTK_OBJECT(cw->notebook), "switch-page",
01403 GTK_SIGNAL_FUNC(chat_notebook_switch_callback),
01404 cw);
01405
01406
01407 gtk_widget_show(cw->notebook);
01408 } else {
01409 cw->window = tab_cw->window;
01410 cw->notebook = tab_cw->notebook;
01411 }
01412
01413
01414 contact_label = gtk_label_new(remote->nick);
01415 gtk_widget_show(contact_label);
01416
01417
01418 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
01419 cw->notebook_child = vbox;
01420 gtk_notebook_append_page(GTK_NOTEBOOK(cw->notebook), cw->notebook_child, contact_label);
01421 gtk_widget_show(cw->notebook_child);
01422 } else {
01423
01424 cw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
01425
01426 gtk_window_set_wmclass(GTK_WINDOW(cw->window), "yattm-chat", "Yattm");
01427 gtk_window_set_policy(GTK_WINDOW(cw->window), TRUE, TRUE, TRUE);
01428 gtk_widget_realize(cw->window);
01429
01430 cw->notebook = NULL;
01431 cw->notebook_child = NULL;
01432 gtk_container_add(GTK_CONTAINER(cw->window), vbox);
01433 gtk_widget_show(vbox);
01434 }
01435
01436
01437 cw->chat = ext_gtk_text_new(NULL,NULL);
01438 gtk_eb_html_init(EXT_GTK_TEXT(cw->chat));
01439 scrollwindow = gtk_scrolled_window_new(NULL, EXT_GTK_TEXT(cw->chat)->vadj);
01440
01441
01442 gtk_window_set_title(GTK_WINDOW(cw->window), remote->nick);
01443
01444 eb_icon(cw->window->window);
01445 gtk_widget_set_usize(scrollwindow, 375, 150);
01446 gtk_container_add(GTK_CONTAINER(scrollwindow), cw->chat);
01447 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow),
01448 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
01449 gtk_widget_show(scrollwindow);
01450
01451
01452
01453
01454
01455 if(do_multi_line)
01456 {
01457 resize_bar = gtk_vpaned_new();
01458 gtk_paned_set_gutter_size(GTK_PANED(resize_bar), 20);
01459 gtk_paned_pack1(GTK_PANED(resize_bar), scrollwindow, TRUE, TRUE);
01460 gtk_widget_show(scrollwindow);
01461
01462 scrollwindow = gtk_scrolled_window_new(NULL, NULL);
01463 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrollwindow),
01464 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
01465
01466 cw->entry = gtk_text_new(NULL, NULL);
01467
01468 gtk_widget_set_usize(scrollwindow, 375, 50);
01469 gtk_container_add(GTK_CONTAINER(scrollwindow), cw->entry);
01470
01471 gtk_text_set_editable(GTK_TEXT(cw->entry), TRUE);
01472 gtk_text_set_word_wrap(GTK_TEXT(cw->entry), TRUE);
01473 gtk_text_set_line_wrap(GTK_TEXT(cw->entry), TRUE);
01474
01475 #ifdef HAVE_ISPELL
01476 if(do_spell_checking)
01477 {
01478 if(!gtkspell_running())
01479 {
01480 gchar *ispell_cmd[] = { "ispell", "-a", NULL };
01481 gtkspell_start(NULL, ispell_cmd);
01482 }
01483 gtkspell_attach(GTK_TEXT(cw->entry));
01484 }
01485 #endif
01486
01487 gtk_signal_connect(GTK_OBJECT(cw->entry), "key_press_event",
01488 GTK_SIGNAL_FUNC(chat_key_press),
01489 cw);
01490
01491 gtk_paned_pack2(GTK_PANED(resize_bar), scrollwindow, FALSE, FALSE);
01492 gtk_widget_show(scrollwindow);
01493 gtk_box_pack_start(GTK_BOX(vbox),resize_bar, TRUE, TRUE, 5);
01494 gtk_widget_show(resize_bar);
01495 }
01496
01497
01498
01499 else
01500 {
01501 cw->entry = gtk_entry_new();
01502 gtk_signal_connect(GTK_OBJECT(cw->entry), "key_press_event",
01503 GTK_SIGNAL_FUNC(chat_singleline_key_press),
01504 cw);
01505
01506 gtk_box_pack_start(GTK_BOX(vbox), scrollwindow, TRUE,TRUE, 5);
01507 gtk_box_pack_start(GTK_BOX(vbox), cw->entry, FALSE,FALSE, 5);
01508 }
01509
01510 gtk_container_set_border_width(GTK_CONTAINER(cw->window), do_tabbed_chat ? 2 : 5);
01511
01512
01513 gtk_signal_connect(GTK_OBJECT(cw->entry), "activate",
01514 GTK_SIGNAL_FUNC(send_message), cw);
01515
01516 gtk_signal_connect(GTK_OBJECT(vbox), "destroy",
01517 GTK_SIGNAL_FUNC(destroy_event), cw);
01518
01519 gtk_signal_connect(GTK_OBJECT(cw->chat), "button_press_event",
01520 GTK_SIGNAL_FUNC(handle_click), cw);
01521
01522 gtk_signal_connect(GTK_OBJECT(cw->window), "focus_in_event",
01523 GTK_SIGNAL_FUNC(handle_focus), cw);
01524
01525 hbox = gtk_hbox_new(FALSE, 0);
01526 gtk_widget_set_usize(hbox, 200, 25);
01527
01528 toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
01529 gtk_toolbar_set_button_relief(GTK_TOOLBAR(toolbar), GTK_RELIEF_NONE);
01530 gtk_container_set_border_width(GTK_CONTAINER(toolbar), 0);
01531 gtk_toolbar_set_space_size(GTK_TOOLBAR(toolbar), 5);
01532
01533
01534
01535 accel_group = gtk_accel_group_new();
01536 gtk_window_add_accel_group(GTK_WINDOW(cw->window), accel_group);
01537 menu = gtk_menu_new();
01538
01539
01540
01541
01542
01543
01544
01545 if(!strcmp(cw->contact->group->name, _("Unknown")))
01546 {
01547 button = gtk_menu_item_new_with_label(_("Add Contact"));
01548 gtk_signal_connect(GTK_OBJECT(button), "activate",
01549 GTK_SIGNAL_FUNC(add_unknown_callback),
01550 cw);
01551 gtk_menu_append(GTK_MENU(menu), button);
01552 }
01553
01554
01555
01556 if(can_offline_message(cw->contact))
01557 {
01558 button = gtk_menu_item_new_with_label(_("Offline Messaging"));
01559 gtk_signal_connect(GTK_OBJECT(button), "activate",
01560 GTK_SIGNAL_FUNC(allow_offline_on_click),
01561 cw);
01562 gtk_widget_add_accelerator(button, "activate", accel_group,
01563 GDK_o, GDK_CONTROL_MASK,
01564 GTK_ACCEL_VISIBLE);
01565 gtk_menu_append(GTK_MENU(menu), button);
01566 }
01567
01568
01569
01570 if (cw->sound_enabled)
01571 {
01572 button = gtk_menu_item_new_with_label(_("Disable Sounds"));
01573 }
01574 else
01575 {
01576 button = gtk_menu_item_new_with_label(_("Enable Sounds"));
01577 }
01578
01579 gtk_signal_connect(GTK_OBJECT(button), "activate",
01580 GTK_SIGNAL_FUNC(set_sound_on_click),
01581 cw);
01582 gtk_widget_add_accelerator(button, "activate", accel_group,
01583 GDK_s, GDK_CONTROL_MASK,
01584 GTK_ACCEL_VISIBLE);
01585 gtk_menu_append(GTK_MENU(menu), button);
01586
01587
01588
01589 button = gtk_menu_item_new_with_label(_("Ignore Contact"));
01590 gtk_signal_connect(GTK_OBJECT(button), "activate",
01591 GTK_SIGNAL_FUNC(ignore_callback), cw);
01592 gtk_widget_add_accelerator(button, "activate", accel_group,
01593 GDK_g, GDK_CONTROL_MASK,
01594 GTK_ACCEL_VISIBLE);
01595 gtk_menu_append(GTK_MENU(menu), button);
01596
01597
01598
01599 button = gtk_menu_item_new_with_label(_("Send File"));
01600 gtk_signal_connect(GTK_OBJECT(button), "activate",
01601 GTK_SIGNAL_FUNC(send_file),
01602 cw);
01603 gtk_widget_add_accelerator(button, "activate", accel_group,
01604 GDK_t, GDK_CONTROL_MASK,
01605 GTK_ACCEL_VISIBLE);
01606 gtk_menu_append(GTK_MENU(menu), button);
01607
01608
01609
01610 button = gtk_menu_item_new_with_label(_("Send Message"));
01611 gtk_signal_connect(GTK_OBJECT(button), "activate",
01612 GTK_SIGNAL_FUNC(send_message),
01613 cw);
01614 gtk_widget_add_accelerator(button, "activate", accel_group,
01615 GDK_r, GDK_CONTROL_MASK,
01616 GTK_ACCEL_VISIBLE);
01617 gtk_menu_append(GTK_MENU(menu), button);
01618
01619
01620
01621
01622
01623 button = gtk_menu_item_new_with_label(_("View log"));
01624 gtk_signal_connect(GTK_OBJECT(button), "activate",
01625 GTK_SIGNAL_FUNC(view_log_callback),
01626 cw);
01627 gtk_widget_add_accelerator(button, "activate", accel_group,
01628 GDK_l, GDK_CONTROL_MASK,
01629 GTK_ACCEL_VISIBLE);
01630 gtk_menu_append(GTK_MENU(menu), button);
01631
01632
01633
01634 button = gtk_menu_item_new_with_label(_("Close"));
01635
01636 gtk_signal_connect(GTK_OBJECT(button), "activate",
01637 GTK_SIGNAL_FUNC(close_win),
01638 cw);
01639
01640 gtk_widget_add_accelerator(button, "activate", accel_group,
01641 GDK_q, GDK_CONTROL_MASK,
01642 GTK_ACCEL_VISIBLE);
01643 gtk_menu_append(GTK_MENU(menu), button);
01644
01645
01646
01647 if (!strcmp(cw->contact->group->name, _("Unknown")))
01648 {
01649
01650 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, tb_book_red_xpm);
01651 iconwid = gtk_pixmap_new(icon , mask);
01652 gtk_widget_show(iconwid);
01653 add_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
01654 _("Add"),
01655 _("Add Contact"),
01656 _("Add"),
01657 iconwid,
01658 GTK_SIGNAL_FUNC(add_unknown_callback),
01659 cw);
01660 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01661 }
01662
01663
01664
01665 if(can_offline_message(remote))
01666 {
01667 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, tb_edit_xpm);
01668 iconwid = gtk_pixmap_new(icon , mask);
01669 gtk_widget_show(iconwid);
01670 cw->allow_button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
01671 GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
01672 NULL,
01673 _("Allow"),
01674 _("Allow Offline Messaging CTRL+O"),
01675 _("Allow"),
01676 iconwid,
01677 GTK_SIGNAL_FUNC(allow_offline_on_toggle),
01678 cw);
01679 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01680 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cw->allow_button), FALSE);
01681 }
01682
01683
01684 if(do_smiley == 1) {
01685 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, smiley_button_xpm);
01686 iconwid = gtk_pixmap_new(icon, mask);
01687 gtk_widget_show(iconwid);
01688 cw->smiley_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
01689 _("Smiley"),
01690 _("Insert Smiley"),
01691 _("Smiley"),
01692 iconwid,
01693 GTK_SIGNAL_FUNC(show_smileys_callback),
01694 cw);
01695
01696
01697 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01698 separator = gtk_vseparator_new();
01699 gtk_widget_set_usize(GTK_WIDGET(separator), 0, 20);
01700 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar), separator, NULL, NULL);
01701 gtk_widget_show(separator);
01702 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01703 }
01704
01705
01706 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, tb_volume_xpm);
01707 iconwid = gtk_pixmap_new(icon, mask);
01708 gtk_widget_show(iconwid);
01709 cw->sound_button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
01710 GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
01711 NULL,
01712 _("Sound"),
01713 _("Enable Sounds CTRL+S"),
01714 _("Sound"),
01715 iconwid,
01716 GTK_SIGNAL_FUNC(set_sound_on_toggle),
01717 cw);
01718 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01719
01720
01721
01722 if (do_play_send)
01723 cw->send_enabled=TRUE;
01724
01725 if (do_play_receive)
01726 cw->receive_enabled = TRUE;
01727
01728 if (do_play_first)
01729 cw->first_enabled = TRUE;
01730
01731 if (do_play_send + do_play_receive + do_play_first > 0)
01732 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cw->sound_button), TRUE);
01733 else
01734 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cw->sound_button), FALSE);
01735
01736
01737
01738 separator = gtk_vseparator_new();
01739 gtk_widget_set_usize(GTK_WIDGET(separator), 0, 20);
01740 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar), separator, NULL, NULL);
01741 gtk_widget_show(separator);
01742 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01743
01744
01745
01746
01747
01748 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, tb_search_xpm);
01749 iconwid = gtk_pixmap_new(icon, mask);
01750 gtk_widget_show(iconwid);
01751 view_log_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
01752 "View",
01753 _("View Log CTRL+L"),
01754 "View",
01755 iconwid,
01756 GTK_SIGNAL_FUNC(view_log_callback),
01757 cw);
01758 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01759
01760
01761
01762 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, tb_open_xpm);
01763 iconwid = gtk_pixmap_new(icon, mask);
01764 gtk_widget_show(iconwid);
01765 sendf_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
01766 "sendf",
01767 _("Send File CTRL+T"),
01768 "sendf",
01769 iconwid,
01770 GTK_SIGNAL_FUNC(send_file),
01771 cw);
01772 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01773
01774
01775
01776 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, tb_no_xpm);
01777 iconwid = gtk_pixmap_new(icon, mask);
01778 gtk_widget_show(iconwid);
01779 ignore_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
01780 "ignore",
01781 _("Ignore CTRL+G"),
01782 "ignore",
01783 iconwid,
01784 GTK_SIGNAL_FUNC(ignore_callback),
01785 cw);
01786 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01787
01788
01789
01790 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, tb_mail_send_xpm);
01791 iconwid = gtk_pixmap_new(icon, mask);
01792 gtk_widget_show(iconwid);
01793 send_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
01794 "send",
01795 _("Send Message CTRL+R"),
01796 "send",
01797 iconwid,
01798 GTK_SIGNAL_FUNC(send_message),
01799 cw);
01800 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01801
01802
01803
01804 separator = gtk_vseparator_new();
01805 gtk_widget_set_usize(GTK_WIDGET(separator), 0, 20);
01806 gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar), separator, NULL, NULL);
01807 gtk_widget_show(separator);
01808 gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
01809
01810
01811
01812 icon = gdk_pixmap_create_from_xpm_d(cw->window->window, &mask, NULL, cancel_xpm);
01813 iconwid = gtk_pixmap_new(icon, mask);
01814 gtk_widget_show(iconwid);
01815
01816 if (do_tabbed_chat)
01817 {
01818 close_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
01819 "close",
01820 _("Close CTRL+Q"),
01821 "close",
01822 iconwid,
01823 GTK_SIGNAL_FUNC(close_tab_callback),
01824 cw);
01825 } else {
01826
01827 close_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
01828 "close",
01829 _("Close CTRL+Q"),
01830 "close",
01831 iconwid,
01832 GTK_SIGNAL_FUNC(close_win),
01833 cw);
01834 }
01835
01836 cw->status_label = gtk_label_new(" ");
01837 gtk_box_pack_start(GTK_BOX(hbox), cw->status_label, FALSE, FALSE, 0);
01838 gtk_widget_show(cw->status_label);
01839
01840 gtk_box_pack_end(GTK_BOX(hbox), toolbar, FALSE, FALSE, 0);
01841 gtk_widget_show(toolbar);
01842
01843 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
01844 gtk_widget_show(hbox);
01845
01846 make_safe_filename(buff, remote->nick);
01847
01848 if ((cw->fp = fopen(buff, "a")) == NULL)
01849 {
01850 perror(buff);
01851 do_logging=0;
01852 }
01853
01854 if(do_logging)
01855 {
01856 time_t my_time = time(NULL);
01857 fprintf(cw->fp, _("%sConversation started on %s %s\n"),
01858 (do_strip_html ? "" : "<HR WIDTH=\"100%%\"><P ALIGN=\"CENTER\"><B>"),
01859 g_strchomp(asctime(localtime(&my_time))), (do_strip_html?"":"</B></P>"));
01860 fflush(cw->fp);
01861 }
01862
01863 gtk_widget_show(cw->chat);
01864 gtk_widget_show(cw->entry);
01865
01866
01867
01868 return cw;
01869 }
01870
01871 void eb_chat_window_display_error(eb_account * remote, gchar * message)
01872 {
01873 struct contact * remote_contact = remote->account_contact;
01874
01875 if(remote_contact->chatwindow)
01876 {
01877 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat),
01878 _("<b>Error: </b>"), 0,0,0);
01879 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat), message, 0,0,0);
01880 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat), "<br>", 0,0,0);
01881 }
01882 }
01883
01884 void eb_chat_window_do_timestamp(struct contact * c, gboolean online)
01885 {
01886 gchar buff[BUF_SIZE];
01887 time_t my_time = time(NULL);
01888 if(!c || !c->chatwindow)
01889 return;
01890
01891 if(!do_timestamp)
01892 {
01893 return;
01894 }
01895
01896 gtk_eb_html_add(EXT_GTK_TEXT(c->chatwindow->chat), "<hr>", 0,0,0);
01897 g_snprintf(buff, BUF_SIZE,_("<b>%s is logged %s @ %s.</b>"),
01898 c->nick, (online?_("in"):_("out")), g_strchomp(asctime(localtime(&my_time))));
01899 gtk_eb_html_add(EXT_GTK_TEXT(c->chatwindow->chat), buff, 0,0,0);
01900 gtk_eb_html_add(EXT_GTK_TEXT(c->chatwindow->chat), "<hr>", 0,0,0);
01901 }
01902
01903
01904 void eb_chat_window_display_remote_message(eb_local_account * account,
01905 eb_account * remote,
01906 struct service * serv,
01907 gchar * o_message)
01908 {
01909 struct contact * remote_contact = remote->account_contact;
01910 gchar buff[BUF_SIZE];
01911 gchar buff2[BUF_SIZE];
01912 struct tm * cur_time;
01913 time_t t;
01914 GList * filter_walk;
01915 gchar * message;
01916 gboolean firstmsg = FALSE;
01917
01918
01919 #ifdef HAVE_ICONV_H
01920
01921
01922 char recode_buff[BUF_SIZE*2 + 1];
01923 #endif
01924
01925
01926
01927
01928 if(!strcasecmp(remote_contact->group->name, _("Ignore") ))
01929 return;
01930
01931
01932 filter_walk=incoming_message_filters;
01933
01934 eb_debug(DBG_CORE, "Starting to run incoming filters\n");
01935
01936 message=strdup(o_message);
01937
01938 while(filter_walk!=NULL)
01939 {
01940 gchar * (*ofilter)(eb_local_account *, eb_account *, struct contact *, gchar *);
01941
01942 eb_debug(DBG_CORE, "Running an incoming filter\n");
01943 ofilter=(gchar *(*)(eb_local_account *, eb_account *, struct contact *, gchar *))filter_walk->data;
01944
01945 message=ofilter(account, remote, remote_contact, message);
01946 if(message==NULL) { return; }
01947
01948 filter_walk=g_list_next(filter_walk);
01949 }
01950
01951 eb_debug(DBG_CORE, "Finished incoming filters\n");
01952
01953
01954
01955
01956 message = eb_smilify(message, serv->sc->get_smileys());
01957
01958 if(!remote_contact->chatwindow || !remote_contact->chatwindow->window)
01959 {
01960 if(remote_contact->chatwindow)
01961 g_free(remote_contact->chatwindow);
01962
01963 remote_contact->chatwindow = eb_chat_window_new(account, remote_contact);
01964
01965 if (!remote_contact->chatwindow)
01966
01967 return;
01968
01969 gtk_widget_show(remote_contact->chatwindow->window);
01970 firstmsg = TRUE;
01971
01972 if (do_restore_last_conv){
01973 gchar buff[NAME_MAX];
01974 make_safe_filename(buff, remote_contact->nick);
01975 eb_restore_last_conv(buff,remote_contact->chatwindow);
01976 }
01977 }
01978
01979
01980
01981 remote_contact->chatwindow->local_user = account;
01982
01983
01984
01985 remote_contact->chatwindow->perfered = remote;
01986
01987 if (remote_contact->chatwindow->notebook != NULL) {
01988
01989
01990
01991 if (gtk_notebook_page_num(GTK_NOTEBOOK(remote_contact->chatwindow->notebook),
01992 remote_contact->chatwindow->notebook_child) != gtk_notebook_get_current_page(
01993 GTK_NOTEBOOK(remote_contact->chatwindow->notebook)))
01994 {
01995 set_tab_red(GTK_NOTEBOOK(remote_contact->chatwindow->notebook), remote_contact->chatwindow->notebook_child);
01996 }
01997
01998 } else {
01999 gdk_window_raise(remote_contact->chatwindow->window->window);
02000 gtk_window_set_focus(GTK_WINDOW(remote_contact->chatwindow->window),
02001 remote_contact->chatwindow->entry);
02002 }
02003
02004 eb_update_window_title(remote_contact->chatwindow, TRUE);
02005
02006 if(remote_contact->chatwindow->sound_enabled)
02007 {
02008 if (firstmsg)
02009 {
02010 if (remote_contact->chatwindow->first_enabled)
02011 {
02012 play_sound(FIRSTMSG);
02013 firstmsg = FALSE;
02014 }
02015 else
02016 {
02017 play_sound(RECEIVE);
02018 firstmsg = FALSE;
02019 }
02020 }
02021 else if (remote_contact->chatwindow->receive_enabled)
02022 play_sound(RECEIVE);
02023 }
02024
02025
02026
02027 if(do_raise_window)
02028 {
02029 gdk_window_raise(remote_contact->chatwindow->window->window);
02030
02031 }
02032
02033 if (do_convo_timestamp)
02034 {
02035 gchar * color;
02036
02037 color=serv->sc->get_color();
02038
02039 time(&t);
02040 cur_time = localtime(&t);
02041 g_snprintf(buff2, BUF_SIZE, "<FONT COLOR=\"#ff0000\">%d:%.2d:%.2d</FONT> <FONT COLOR=\"%s\">%s:</FONT>",
02042 cur_time->tm_hour, cur_time->tm_min,
02043 cur_time->tm_sec, color, remote_contact->nick);
02044 }
02045 else
02046 {
02047 g_snprintf(buff2, BUF_SIZE, "%s", remote_contact->nick);
02048 }
02049
02050 #ifdef HAVE_ICONV_H
02051 message = recode_if_needed(message, recode_buff, RECODE_TO_LOCAL);
02052 #endif
02053
02054 g_snprintf(buff, BUF_SIZE, "<B>%s </B>",buff2);
02055
02056 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat), buff,0,0,0);
02057 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat), message,do_ignore_back,do_ignore_fore,do_ignore_font);
02058 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat), "<BR>",0,0,0);
02059
02060
02061
02062 if(do_logging) eb_log_message(remote_contact->chatwindow->fp, buff, message);
02063
02064
02065
02066
02067
02068 if(is_away && (time(NULL) - remote_contact->chatwindow->away_msg_sent) > 300)
02069 {
02070 send_message(NULL, remote_contact->chatwindow);
02071 RUN_SERVICE(account)->send_im(
02072 account,
02073 remote,
02074 gtk_entry_get_text(GTK_ENTRY(away_message)));
02075 time(&t);
02076 cur_time = localtime(&t);
02077 g_snprintf(buff, BUF_SIZE, "<FONT COLOR=\"#0000ff\"><B>%d:%.2d:%.2d %s: </B></FONT>",
02078 cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec,
02079 account->alias);
02080 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat), buff,0,0,0);
02081 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat),
02082 gtk_entry_get_text(GTK_ENTRY(away_message)),do_ignore_back,do_ignore_fore,do_ignore_font);
02083 gtk_eb_html_add(EXT_GTK_TEXT(remote_contact->chatwindow->chat), "<br>", 0,0,0);
02084
02085
02086
02087 remote_contact->chatwindow->away_msg_sent = time(NULL);
02088
02089
02090
02091 if(do_logging) eb_log_message(remote_contact->chatwindow->fp, buff,
02092 gtk_entry_get_text(GTK_ENTRY(away_message)));
02093 }
02094 free(message);
02095 }
02096
02097 void eb_chat_window_display_contact(struct contact * remote_contact)
02098 {
02099 eb_account *remote_account =
02100 find_suitable_remote_account (NULL, remote_contact);
02101 eb_local_account *account = NULL;
02102
02103 if (remote_account)
02104 account = find_suitable_local_account (NULL, remote_account->service_id);
02105
02106 if (!remote_contact->chatwindow || !remote_contact->chatwindow->window)
02107 {
02108 if (remote_contact->chatwindow)
02109 {
02110 g_free (remote_contact->chatwindow);
02111 }
02112
02113 remote_contact->chatwindow = eb_chat_window_new (account, remote_contact);
02114
02115 if (remote_contact->chatwindow)
02116 {
02117 gtk_widget_show (remote_contact->chatwindow->window);
02118 if (do_restore_last_conv)
02119 {
02120 gchar buff[NAME_MAX];
02121 make_safe_filename (buff, remote_contact->nick);
02122 eb_restore_last_conv (buff, remote_contact->chatwindow);
02123 }
02124 gdk_window_raise(remote_contact->chatwindow->window->window);
02125 gtk_window_set_focus (GTK_WINDOW
02126 (remote_contact->chatwindow->window),
02127 remote_contact->chatwindow->entry);
02128 }
02129
02130 } else {
02131 gdk_window_raise(remote_contact->chatwindow->window->window);
02132 gtk_window_set_focus (GTK_WINDOW
02133 (remote_contact->chatwindow->window),
02134 remote_contact->chatwindow->entry);
02135
02136 }
02137
02138 if (remote_contact->chatwindow->notebook != NULL)
02139 {
02140 int page_num =
02141 gtk_notebook_page_num (GTK_NOTEBOOK
02142 (remote_contact->chatwindow->notebook),
02143 remote_contact->chatwindow->notebook_child);
02144
02145
02146
02147 set_tab_normal (GTK_NOTEBOOK (remote_contact->chatwindow->notebook),
02148 remote_contact->chatwindow->notebook_child);
02149
02150 gtk_notebook_set_page (GTK_NOTEBOOK
02151 (remote_contact->chatwindow->notebook), page_num);
02152 }
02153 }
02154
02155 void eb_chat_window_display_account(eb_account * remote_account)
02156 {
02157 struct contact * remote_contact = remote_account->account_contact;
02158 eb_local_account * account =find_suitable_local_account(NULL, remote_account->service_id);
02159
02160 if(!remote_contact->chatwindow || !remote_contact->chatwindow->window)
02161 {
02162 if(remote_contact->chatwindow)
02163 {
02164 g_free(remote_contact->chatwindow);
02165 }
02166
02167 remote_contact->chatwindow = eb_chat_window_new(account, remote_contact);
02168
02169 if(remote_contact->chatwindow)
02170 {
02171 gtk_widget_show(remote_contact->chatwindow->window);
02172 if (do_restore_last_conv)
02173 {
02174 gchar buff[NAME_MAX];
02175 make_safe_filename(buff, remote_contact->nick);
02176 eb_restore_last_conv(buff,remote_contact->chatwindow);
02177 }
02178 gdk_window_raise(remote_contact->chatwindow->window->window);
02179 gtk_window_set_focus (GTK_WINDOW
02180 (remote_contact->chatwindow->window),
02181 remote_contact->chatwindow->entry);
02182 }
02183 else
02184 return;
02185 }
02186 else if (remote_contact->chatwindow && remote_contact->chatwindow->window)
02187 {
02188 gdk_window_raise(remote_contact->chatwindow->window->window);
02189 gtk_window_set_focus (GTK_WINDOW
02190 (remote_contact->chatwindow->window),
02191 remote_contact->chatwindow->entry);
02192 }
02193
02194 eb_update_window_title(remote_contact->chatwindow, FALSE);
02195
02196 if (remote_contact->chatwindow->notebook != NULL)
02197 {
02198 int page_num = gtk_notebook_page_num(GTK_NOTEBOOK(remote_contact->chatwindow->notebook),
02199 remote_contact->chatwindow->notebook_child);
02200
02201
02202 set_tab_normal(GTK_NOTEBOOK(remote_contact->chatwindow->notebook),
02203 remote_contact->chatwindow->notebook_child);
02204 gtk_notebook_set_page(GTK_NOTEBOOK(remote_contact->chatwindow->notebook),
02205 page_num);
02206
02207 } else {
02208 gdk_window_raise(remote_contact->chatwindow->window->window);
02209 gtk_window_set_focus(GTK_WINDOW(remote_contact->chatwindow->window),
02210 remote_contact->chatwindow->entry);
02211 }
02212
02213 remote_contact->chatwindow->perfered = remote_account;
02214 }
02215
02216 void eb_log_status_changed(eb_account *ea, gchar *status)
02217 {
02218 if(ea == NULL || ea->account_contact == NULL ||
02219 ea->account_contact->chatwindow == NULL ||
02220 ea->account_contact->chatwindow->fp == NULL)
02221 return;
02222
02223 eb_log_message(ea->account_contact->chatwindow->fp, ea->handle,
02224 ((status && status[0])?status:"Available"));
02225 }
02226
02227 void eb_log_message(FILE *log_file, gchar buff[], gchar *message)
02228 {
02229 gchar * my_name = strdup(buff);
02230 gchar * my_message = strdup(message);
02231
02232
02233
02234 if(do_strip_html)
02235 {
02236 strip_html(my_message);
02237 strip_html(my_name);
02238 }
02239
02240
02241
02242 fprintf(log_file, "%s %s %s %s\n",
02243 (do_strip_html ? "" : "<P>"), my_name, my_message, (do_strip_html ? "" : "</P>"));
02244 fflush(log_file);
02245
02246 free(my_message);
02247 free(my_name);
02248 }
02249
02250 void eb_restore_last_conv(gchar *file_name, chat_window* cw)
02251 {
02252 FILE * fp;
02253 gchar buff[1024];
02254 gchar buff2[1024];
02255 gchar *buff3;
02256 gchar color[8];
02257 gchar name[512];
02258 gchar *token;
02259 long location = -1;
02260 long lastlocation = -1;
02261 long beforeget;
02262
02263 if ( (fp = fopen(file_name, "r")) == NULL)
02264 {
02265
02266 return;
02267 }
02268
02269
02270
02271 while(!feof(fp))
02272 {
02273 beforeget = ftell(fp);
02274 fgets(buff, 1024, fp);
02275 if(feof(fp))
02276 {
02277 break;
02278 }
02279 g_strchomp(buff);
02280 if(!strncmp(buff,_("Conversation started"),strlen(_("Conversation started")))
02281 || !strncmp(buff,_("<HR WIDTH=\"100%\"><P ALIGN=\"CENTER\"><B>Conversation started"),strlen(_("<HR WIDTH=\"100%\"><P ALIGN=\"CENTER\"><B>Conversation started"))))
02282 {
02283 lastlocation = location;
02284 location = beforeget;
02285 }
02286 }
02287
02288 if(lastlocation == -1)
02289 {
02290 if(location == -1 || location == 0)
02291 {
02292 fclose(fp);
02293 return;
02294 }
02295 lastlocation = location;
02296 }
02297 fseek(fp,lastlocation, SEEK_SET);
02298
02299
02300 while(!feof(fp))
02301 {
02302 fgets(buff,1024,fp);
02303 if(feof(fp))
02304 {
02305 break;
02306 }
02307 g_strchomp(buff);
02308
02309 if(buff[0] == '<')
02310 {
02311
02312 if(!strncmp(buff,"<HR WIDTH=\"100%\">",
02313 strlen("<HR WIDTH=\"100%\">")))
02314 {
02315 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), buff+strlen("<HR WIDTH=\"100%\">"),0,0,0);
02316 }
02317 else
02318 {
02319 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), buff, 0,0,0);
02320 }
02321
02322
02323 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), "<br>",0,0,0);
02324
02325 if(strlen(buff) > 34 && !strncmp(buff+34,_("ended on"),8))
02326 {
02327 break;
02328 }
02329 }
02330 else if(!strncmp(buff,_("Conversation started"),strlen(_("Conversation started"))))
02331 {
02332 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), "<hr>", 0,0,0);
02333 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), buff, 0,0,0);
02334 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), "<br>",0,0,0);
02335
02336 }
02337 else if(!strncmp(buff,_("Conversation ended"),strlen(_("Conversation ended"))))
02338 {
02339
02340 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), buff,0,0,0);
02341 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), "<br>",0,0,0);
02342 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), "<hr>",0,0,0);
02343 break;
02344 }
02345 else
02346 {
02347 strip_html(buff);
02348 strcpy(buff2, buff);
02349
02350 token = strtok(buff2,":");
02351
02352 if(token && (strcmp(buff,token) != 0))
02353 {
02354
02355 if(((strlen(token)==3)&&isdigit((int)token[1])&&isdigit(token[2]))
02356 || ((strlen(token)==2) && isdigit((int)token[1])))
02357 {
02358
02359
02360 token = strtok(NULL,":");
02361 if(token == NULL)
02362 {
02363 break;
02364 }
02365 token = strtok(NULL,":");
02366
02367 if(token == NULL)
02368 break;
02369 buff3 = token + strlen(token)+1;
02370
02371 token+=3;
02372 }
02373 else
02374 {
02375
02376 buff3 = buff2+strlen(token)+1;
02377 token++;
02378 }
02379 if( !strncmp(token,cw->contact->nick,strlen(cw->contact->nick)))
02380 {
02381
02382
02383 strcpy(color,"#ff0000");
02384 }
02385 else
02386 {
02387
02388 strcpy(color,"#0000ff");
02389 }
02390 strncpy(name,buff,buff3-buff2);
02391 name[buff3-buff2] = '\0';
02392 g_snprintf(buff, BUF_SIZE, "<FONT COLOR=\"%s\"><B>%s </B></FONT>",color, name);
02393 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), buff,0,0,0);
02394 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), buff3,0,0,0);
02395 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), "<br>",0,0,0);
02396 }
02397 else
02398 {
02399
02400 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat),buff2,0,0,0);
02401 gtk_eb_html_add(EXT_GTK_TEXT(cw->chat), "<br>",0,0,0);
02402 }
02403 }
02404 }
02405 fclose(fp);
02406
02407 }
02408
02409 void eb_chat_window_display_status(eb_account * remote,
02410 gchar * message)
02411 {
02412 struct contact * remote_contact = find_contact_by_handle(remote->handle);
02413 char * tmp = NULL;
02414
02415
02416 if (remote_contact == NULL || remote_contact->chatwindow == NULL) {
02417 gchar ** tmp_ct = NULL;
02418 if (strchr (remote->handle,'@') ) {
02419 tmp_ct = g_strsplit (remote->handle,"@",2);
02420 remote_contact = find_contact_by_handle(tmp_ct[0]);
02421 g_strfreev (tmp_ct);
02422 }
02423 }
02424
02425 if (remote_contact == NULL || remote_contact->chatwindow == NULL)
02426 return;
02427
02428 if (message != NULL && strlen(message) > 0)
02429 tmp = g_strdup_printf("%s", message);
02430 else
02431 tmp = g_strdup_printf(" ");
02432
02433 gtk_label_set_text( GTK_LABEL(remote_contact->chatwindow->status_label), tmp );
02434 g_free(tmp);
02435 }
02436
02437 void
02438 eb_update_window_title_to_tab (int tab, gboolean new_message)
02439 {
02440 char buff[BUF_SIZE];
02441 chat_window * cw = NULL;
02442
02443 cw = find_tabbed_chat_window_index(tab);
02444 if (cw && cw->notebook != NULL
02445 && cw->contact != NULL
02446 && cw->local_user != NULL
02447 && cw->perfered != NULL
02448 && GET_SERVICE (cw->local_user).name != NULL)
02449 {
02450 g_snprintf (buff, BUF_SIZE, "%s%s (%s <=> %s via %s)",
02451 new_message == TRUE ? "* " : "",
02452 cw->contact->nick, cw->local_user->alias,
02453 cw->perfered->handle,
02454 GET_SERVICE (cw->local_user).name);
02455
02456 gtk_window_set_title (GTK_WINDOW (cw->contact->chatwindow->window),
02457 buff);
02458
02459
02460 }
02461 else if(cw && cw->contact != NULL)
02462 {
02463 gtk_window_set_title (GTK_WINDOW (cw->contact->chatwindow->window),
02464 cw->contact->nick);
02465 }
02466
02467 }
02468
02469 void
02470 eb_update_window_title (chat_window * cw, gboolean new_message)
02471 {
02472 char buff[BUF_SIZE];
02473
02474 if (!do_tabbed_chat
02475 && cw != NULL
02476 && cw->contact != NULL
02477 && cw->perfered != NULL
02478 && cw->local_user != NULL && GET_SERVICE (cw->local_user).name != NULL)
02479 {
02480 g_snprintf (buff, BUF_SIZE, "%s%s (%s <=> %s via %s)",
02481 new_message == TRUE ? "* " : "",
02482 cw->contact->nick, cw->local_user->alias,
02483 cw->perfered->handle, GET_SERVICE (cw->local_user).name);
02484
02485 gtk_window_set_title (GTK_WINDOW (cw->contact->chatwindow->window),
02486 buff);
02487 }
02488 else if (do_tabbed_chat)
02489 {
02490 if (!new_message)
02491 cw = find_tabbed_current_chat_window ();
02492 if (cw && cw->notebook != NULL
02493 && cw->contact != NULL
02494 && cw->local_user != NULL
02495 && cw->perfered != NULL
02496 && GET_SERVICE (cw->local_user).name != NULL)
02497 {
02498 g_snprintf (buff, BUF_SIZE, "%s%s (%s <=> %s via %s)",
02499 new_message == TRUE ? "* " : "",
02500 cw->contact->nick, cw->local_user->alias,
02501 cw->perfered->handle,
02502 GET_SERVICE (cw->local_user).name);
02503
02504 gtk_window_set_title (GTK_WINDOW (cw->contact->chatwindow->window),
02505 buff);
02506
02507
02508 }
02509 }
02510 }