| 21 * You should have received a copy of the GNU General Public License |
21 * You should have received a copy of the GNU General Public License |
| 22 * along with this program; if not, write to the Free Software |
22 * along with this program; if not, write to the Free Software |
| 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 24 */ |
24 */ |
| 25 |
25 |
| |
26 #include <gdk/gdkkeysyms.h> |
| |
27 |
| 26 #include "account.h" |
28 #include "account.h" |
| 27 #include "internal.h" |
29 #include "internal.h" |
| 28 #include "savedstatuses.h" |
30 #include "savedstatuses.h" |
| 29 #include "status.h" |
31 #include "status.h" |
| 30 #include "debug.h" |
32 #include "debug.h" |
| 37 #include "gtkutils.h" |
39 #include "gtkutils.h" |
| 38 |
40 |
| 39 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data); |
41 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data); |
| 40 static void remove_typing_cb(GtkGaimStatusBox *box); |
42 static void remove_typing_cb(GtkGaimStatusBox *box); |
| 41 |
43 |
| |
44 static void gtk_gaim_status_box_pulse_typing(GtkGaimStatusBox *status_box); |
| 42 static void gtk_gaim_status_box_refresh(GtkGaimStatusBox *status_box); |
45 static void gtk_gaim_status_box_refresh(GtkGaimStatusBox *status_box); |
| 43 static void gtk_gaim_status_box_regenerate(GtkGaimStatusBox *status_box); |
46 static void gtk_gaim_status_box_regenerate(GtkGaimStatusBox *status_box); |
| 44 static void gtk_gaim_status_box_changed(GtkComboBox *box); |
47 static void gtk_gaim_status_box_changed(GtkComboBox *box); |
| 45 static void gtk_gaim_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition); |
48 static void gtk_gaim_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition); |
| 46 static void gtk_gaim_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); |
49 static void gtk_gaim_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); |
| 136 } |
139 } |
| 137 |
140 |
| 138 if (status_no != -1) { |
141 if (status_no != -1) { |
| 139 gtk_widget_set_sensitive(GTK_WIDGET(status_box), FALSE); |
142 gtk_widget_set_sensitive(GTK_WIDGET(status_box), FALSE); |
| 140 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), status_no); |
143 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), status_no); |
| 141 gtk_gaim_status_box_refresh(status_box); |
144 |
| 142 |
|
| 143 message = gaim_status_get_attr_string(newstatus, "message"); |
145 message = gaim_status_get_attr_string(newstatus, "message"); |
| 144 |
146 |
| 145 if (!message || !*message) |
147 if (!message || !*message) |
| 146 { |
148 { |
| 147 gtk_widget_hide_all(status_box->vbox); |
149 gtk_widget_hide_all(status_box->vbox); |
| 150 else |
152 else |
| 151 { |
153 { |
| 152 gtk_widget_show_all(status_box->vbox); |
154 gtk_widget_show_all(status_box->vbox); |
| 153 status_box->imhtml_visible = TRUE; |
155 status_box->imhtml_visible = TRUE; |
| 154 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); |
156 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); |
| |
157 gtk_imhtml_clear_formatting(GTK_IMHTML(status_box->imhtml)); |
| 155 gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); |
158 gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); |
| |
159 gtk_widget_hide(status_box->toolbar); |
| |
160 gtk_widget_hide(status_box->hsep); |
| 156 } |
161 } |
| 157 gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE); |
162 gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE); |
| |
163 gtk_gaim_status_box_refresh(status_box); |
| 158 } |
164 } |
| 159 } |
165 } |
| 160 |
166 |
| 161 static void |
167 static void |
| 162 account_status_changed_cb(GaimAccount *account, GaimStatus *oldstatus, GaimStatus *newstatus, GtkGaimStatusBox *status_box) |
168 account_status_changed_cb(GaimAccount *account, GaimStatus *oldstatus, GaimStatus *newstatus, GtkGaimStatusBox *status_box) |
| 365 * was changed programmatically. |
371 * was changed programmatically. |
| 366 */ |
372 */ |
| 367 gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), FALSE); |
373 gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), FALSE); |
| 368 |
374 |
| 369 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); |
375 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); |
| |
376 gtk_imhtml_clear_formatting(GTK_IMHTML(status_box->imhtml)); |
| 370 gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); |
377 gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); |
| |
378 gtk_widget_hide(status_box->toolbar); |
| |
379 gtk_widget_hide(status_box->hsep); |
| 371 gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), TRUE); |
380 gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), TRUE); |
| 372 } |
381 } |
| 373 |
382 |
| 374 /* Stop suppressing the "changed" signal. */ |
383 /* Stop suppressing the "changed" signal. */ |
| 375 gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE); |
384 gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE); |
| 438 else if (event->direction == GDK_SCROLL_DOWN) |
447 else if (event->direction == GDK_SCROLL_DOWN) |
| 439 gtk_imhtml_page_down(imhtml); |
448 gtk_imhtml_page_down(imhtml); |
| 440 return TRUE; |
449 return TRUE; |
| 441 } |
450 } |
| 442 |
451 |
| |
452 static int imhtml_remove_focus(GtkWidget *w, GdkEventKey *event, GtkGaimStatusBox *box) |
| |
453 { |
| |
454 if (event->keyval == GDK_Tab || event->keyval == GDK_KP_Tab) |
| |
455 { |
| |
456 /* If last inserted character is a tab, then remove the focus from here */ |
| |
457 GtkWidget *top = gtk_widget_get_toplevel(w); |
| |
458 g_signal_emit_by_name(G_OBJECT(top), "move_focus", |
| |
459 (event->state & GDK_SHIFT_MASK) ? |
| |
460 GTK_DIR_TAB_BACKWARD: GTK_DIR_TAB_FORWARD); |
| |
461 return TRUE; |
| |
462 } |
| |
463 if (!box->typing) |
| |
464 return FALSE; |
| |
465 gtk_gaim_status_box_pulse_typing(box); |
| |
466 g_source_remove(box->typing); |
| |
467 box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, box); |
| |
468 return FALSE; |
| |
469 } |
| |
470 |
| 443 #if GTK_CHECK_VERSION(2,6,0) |
471 #if GTK_CHECK_VERSION(2,6,0) |
| 444 static gboolean |
472 static gboolean |
| 445 dropdown_store_row_separator_func(GtkTreeModel *model, |
473 dropdown_store_row_separator_func(GtkTreeModel *model, |
| 446 GtkTreeIter *iter, gpointer data) |
474 GtkTreeIter *iter, gpointer data) |
| 447 { |
475 { |
| 468 update_to_reflect_current_status(box); |
496 update_to_reflect_current_status(box); |
| 469 } |
497 } |
| 470 |
498 |
| 471 static gboolean button_released_cb(GtkWidget *widget, GdkEventButton *event, GtkGaimStatusBox *box) |
499 static gboolean button_released_cb(GtkWidget *widget, GdkEventButton *event, GtkGaimStatusBox *box) |
| 472 { |
500 { |
| |
501 |
| |
502 if (event->button != 1) |
| |
503 return FALSE; |
| 473 gtk_combo_box_popdown(GTK_COMBO_BOX(box)); |
504 gtk_combo_box_popdown(GTK_COMBO_BOX(box)); |
| 474 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(box->toggle_button), FALSE); |
505 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(box->toggle_button), FALSE); |
| 475 if (!box->imhtml_visible) |
506 if (!box->imhtml_visible) |
| 476 g_signal_emit_by_name(G_OBJECT(box), "changed", NULL, NULL); |
507 g_signal_emit_by_name(G_OBJECT(box), "changed", NULL, NULL); |
| 477 return TRUE; |
508 return TRUE; |
| 478 } |
509 } |
| 479 |
510 |
| 480 static gboolean button_pressed_cb(GtkWidget *widget, GdkEventButton *event, GtkGaimStatusBox *box) |
511 static gboolean button_pressed_cb(GtkWidget *widget, GdkEventButton *event, GtkGaimStatusBox *box) |
| 481 { |
512 { |
| |
513 if (event->button != 1) |
| |
514 return FALSE; |
| 482 gtk_combo_box_popup(GTK_COMBO_BOX(box)); |
515 gtk_combo_box_popup(GTK_COMBO_BOX(box)); |
| 483 // released_cb is getting short-circuited gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(box->toggle_button), TRUE); |
516 // Disabled until button_released_cb works |
| |
517 // gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(box->toggle_button), TRUE); |
| 484 return TRUE; |
518 return TRUE; |
| 485 } |
519 } |
| 486 |
520 |
| 487 static void |
521 static void |
| 488 gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) |
522 gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) |
| 520 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); |
554 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); |
| 521 gtk_tree_path_free(path); |
555 gtk_tree_path_free(path); |
| 522 |
556 |
| 523 gtk_container_add(GTK_CONTAINER(status_box->toggle_button), status_box->hbox); |
557 gtk_container_add(GTK_CONTAINER(status_box->toggle_button), status_box->hbox); |
| 524 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->cell_view, TRUE, TRUE, 0); |
558 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->cell_view, TRUE, TRUE, 0); |
| 525 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->vsep, FALSE, 0, 0); |
559 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->vsep, FALSE, FALSE, 0); |
| 526 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->arrow, FALSE, 0, 0); |
560 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->arrow, FALSE, FALSE, 0); |
| 527 gtk_widget_show_all(status_box->toggle_button); |
561 gtk_widget_show_all(status_box->toggle_button); |
| 528 #if GTK_CHECK_VERSION(2,4,0) |
562 #if GTK_CHECK_VERSION(2,4,0) |
| 529 gtk_button_set_focus_on_click(GTK_BUTTON(status_box->toggle_button), FALSE); |
563 gtk_button_set_focus_on_click(GTK_BUTTON(status_box->toggle_button), FALSE); |
| 530 #endif |
564 #endif |
| 531 gtk_container_add(GTK_CONTAINER(status_box), status_box->toggle_button); |
565 gtk_container_add(GTK_CONTAINER(status_box), status_box->toggle_button); |
| 545 |
579 |
| 546 g_object_set(G_OBJECT(status_box->icon_rend), "xpad", 6, NULL); |
580 g_object_set(G_OBJECT(status_box->icon_rend), "xpad", 6, NULL); |
| 547 |
581 |
| 548 status_box->vbox = gtk_vbox_new(0, FALSE); |
582 status_box->vbox = gtk_vbox_new(0, FALSE); |
| 549 vbox = gtk_vbox_new(0,FALSE); |
583 vbox = gtk_vbox_new(0,FALSE); |
| 550 status_box->imhtml = gtk_imhtml_new(NULL, NULL); |
584 status_box->imhtml = gtk_imhtml_new(NULL, NULL); |
| 551 status_box->toolbar = gtk_imhtmltoolbar_new(); |
585 status_box->toolbar = gtk_imhtmltoolbar_new(); |
| 552 gtk_imhtmltoolbar_attach(GTK_IMHTMLTOOLBAR(status_box->toolbar), status_box->imhtml); |
586 gtk_imhtmltoolbar_attach(GTK_IMHTMLTOOLBAR(status_box->toolbar), status_box->imhtml); |
| 553 status_box->hsep = gtk_hseparator_new(); |
587 status_box->hsep = gtk_hseparator_new(); |
| 554 |
588 |
| 555 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml)); |
589 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml)); |
| 556 g_signal_connect(G_OBJECT(status_box->toggle_button), "button-press-event", G_CALLBACK(button_pressed_cb), status_box); |
590 g_signal_connect(G_OBJECT(status_box->toggle_button), "button-press-event", |
| 557 g_signal_connect(G_OBJECT(status_box->toggle_button), "button-release-event", G_CALLBACK(button_released_cb), status_box); |
591 G_CALLBACK(button_pressed_cb), status_box); |
| |
592 g_signal_connect(G_OBJECT(status_box->toggle_button), "button-release-event", |
| |
593 G_CALLBACK(button_released_cb), status_box); |
| 558 g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(imhtml_changed_cb), status_box); |
594 g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(imhtml_changed_cb), status_box); |
| |
595 g_signal_connect(G_OBJECT(status_box->imhtml), "key_press_event", |
| |
596 G_CALLBACK(imhtml_remove_focus), status_box); |
| 559 g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "message_send", G_CALLBACK(remove_typing_cb), status_box); |
597 g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "message_send", G_CALLBACK(remove_typing_cb), status_box); |
| 560 gtk_imhtml_set_editable(GTK_IMHTML(status_box->imhtml), TRUE); |
598 gtk_imhtml_set_editable(GTK_IMHTML(status_box->imhtml), TRUE); |
| 561 gtk_widget_set_parent(status_box->vbox, GTK_WIDGET(status_box)); |
599 gtk_widget_set_parent(status_box->vbox, GTK_WIDGET(status_box)); |
| 562 gtk_widget_set_parent(status_box->toggle_button, GTK_WIDGET(status_box)); |
600 gtk_widget_set_parent(status_box->toggle_button, GTK_WIDGET(status_box)); |
| 563 status_box->sw = gtk_scrolled_window_new(NULL, NULL); |
601 status_box->sw = gtk_scrolled_window_new(NULL, NULL); |
| 912 activate_currently_selected_status(status_box); |
950 activate_currently_selected_status(status_box); |
| 913 |
951 |
| 914 g_source_remove(status_box->typing); |
952 g_source_remove(status_box->typing); |
| 915 status_box->typing = 0; |
953 status_box->typing = 0; |
| 916 gtk_gaim_status_box_refresh(status_box); |
954 gtk_gaim_status_box_refresh(status_box); |
| 917 gtk_widget_hide(status_box->toolbar); |
|
| 918 gtk_widget_hide(status_box->hsep); |
|
| 919 } |
955 } |
| 920 |
956 |
| 921 static void gtk_gaim_status_box_changed(GtkComboBox *box) |
957 static void gtk_gaim_status_box_changed(GtkComboBox *box) |
| 922 { |
958 { |
| 923 GtkGaimStatusBox *status_box; |
959 GtkGaimStatusBox *status_box; |
| 995 g_list_free(accounts); |
1031 g_list_free(accounts); |
| 996 |
1032 |
| 997 if (status_box->imhtml_visible) |
1033 if (status_box->imhtml_visible) |
| 998 { |
1034 { |
| 999 gtk_widget_show_all(status_box->vbox); |
1035 gtk_widget_show_all(status_box->vbox); |
| 1000 if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box))) |
1036 if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box))) { |
| 1001 status_box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, status_box); |
1037 status_box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, status_box); |
| |
1038 } else { |
| |
1039 gtk_widget_hide(status_box->toolbar); |
| |
1040 gtk_widget_hide(status_box->hsep); |
| |
1041 } |
| 1002 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); |
1042 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); |
| |
1043 gtk_imhtml_clear_formatting(GTK_IMHTML(status_box->imhtml)); |
| 1003 gtk_widget_grab_focus(status_box->imhtml); |
1044 gtk_widget_grab_focus(status_box->imhtml); |
| 1004 } |
1045 } |
| 1005 else |
1046 else |
| 1006 { |
1047 { |
| 1007 gtk_widget_hide_all(status_box->vbox); |
1048 gtk_widget_hide_all(status_box->vbox); |