comparison src/gtkimhtml.c @ 12672:4bd7e2ebb4cb

[gaim-migrate @ 15015] gaim_imhtml_fix.patch from SF Patch #1237965 from Sadrul This fixes some format clearing bugs. committer: Tailor Script <tailor@pidgin.im>
author Richard Laager <rlaager@wiktel.com>
date Thu, 29 Dec 2005 15:53:39 +0000
parents 8584cc19ee48
children de93d4988ad4
comparison
equal deleted inserted replaced
12671:c8afbc1bf98b 12672:4bd7e2ebb4cb
112 static void imhtml_toggle_italic(GtkIMHtml *imhtml); 112 static void imhtml_toggle_italic(GtkIMHtml *imhtml);
113 static void imhtml_toggle_strike(GtkIMHtml *imhtml); 113 static void imhtml_toggle_strike(GtkIMHtml *imhtml);
114 static void imhtml_toggle_underline(GtkIMHtml *imhtml); 114 static void imhtml_toggle_underline(GtkIMHtml *imhtml);
115 static void imhtml_font_grow(GtkIMHtml *imhtml); 115 static void imhtml_font_grow(GtkIMHtml *imhtml);
116 static void imhtml_font_shrink(GtkIMHtml *imhtml); 116 static void imhtml_font_shrink(GtkIMHtml *imhtml);
117 static void imhtml_clear_formatting(GtkIMHtml *imhtml);
117 118
118 /* POINT_SIZE converts from AIM font sizes to a point size scale factor. */ 119 /* POINT_SIZE converts from AIM font sizes to a point size scale factor. */
119 #define MAX_FONT_SIZE 7 120 #define MAX_FONT_SIZE 7
120 #define POINT_SIZE(x) (_point_sizes [MIN ((x > 0 ? x : 1), MAX_FONT_SIZE) - 1]) 121 #define POINT_SIZE(x) (_point_sizes [MIN ((x > 0 ? x : 1), MAX_FONT_SIZE) - 1])
121 static gdouble _point_sizes [] = { .69444444, .8333333, 1, 1.2, 1.44, 1.728, 2.0736}; 122 static gdouble _point_sizes [] = { .69444444, .8333333, 1, 1.2, 1.44, 1.728, 2.0736};
1303 0, g_cclosure_marshal_VOID__VOID, 1304 0, g_cclosure_marshal_VOID__VOID,
1304 G_TYPE_NONE, 0); 1305 G_TYPE_NONE, 0);
1305 1306
1306 klass->toggle_format = imhtml_toggle_format; 1307 klass->toggle_format = imhtml_toggle_format;
1307 klass->message_send = imhtml_message_send; 1308 klass->message_send = imhtml_message_send;
1309 klass->clear_format = imhtml_clear_formatting;
1308 1310
1309 gobject_class->finalize = gtk_imhtml_finalize; 1311 gobject_class->finalize = gtk_imhtml_finalize;
1310 widget_class->drag_motion = gtk_text_view_drag_motion; 1312 widget_class->drag_motion = gtk_text_view_drag_motion;
1311 widget_class->expose_event = gtk_imhtml_expose_event; 1313 widget_class->expose_event = gtk_imhtml_expose_event;
1312 gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-color", 1314 gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-color",
3717 static void remove_font_link(GtkIMHtml *imhtml, GtkTextIter *i, GtkTextIter *e, gboolean homo) 3719 static void remove_font_link(GtkIMHtml *imhtml, GtkTextIter *i, GtkTextIter *e, gboolean homo)
3718 { 3720 {
3719 remove_tag_by_prefix(imhtml, i, e, "LINK ", 5, homo); 3721 remove_tag_by_prefix(imhtml, i, e, "LINK ", 5, homo);
3720 } 3722 }
3721 3723
3722 /* Editable stuff */ 3724 static void
3723 static void preinsert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml) 3725 imhtml_clear_formatting(GtkIMHtml *imhtml)
3724 {
3725 imhtml->insert_offset = gtk_text_iter_get_offset(iter);
3726 }
3727
3728 static void insert_ca_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextChildAnchor *arg2, gpointer user_data)
3729 {
3730 GtkTextIter start;
3731
3732 start = *arg1;
3733 gtk_text_iter_backward_char(&start);
3734
3735 gtk_imhtml_apply_tags_on_insert(user_data, &start, arg1);
3736 }
3737
3738 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *end, gchar *text, gint len, GtkIMHtml *imhtml)
3739 {
3740 GtkTextIter start;
3741
3742 if (!len)
3743 return;
3744
3745 start = *end;
3746 gtk_text_iter_set_offset(&start, imhtml->insert_offset);
3747
3748 gtk_imhtml_apply_tags_on_insert(imhtml, &start, end);
3749 }
3750
3751 static void gtk_imhtml_apply_tags_on_insert(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end)
3752 {
3753 if (imhtml->edit.bold)
3754 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "BOLD", start, end);
3755 else
3756 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "BOLD", start, end);
3757
3758 if (imhtml->edit.italic)
3759 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", start, end);
3760 else
3761 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "ITALICS", start, end);
3762
3763 if (imhtml->edit.underline)
3764 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", start, end);
3765 else
3766 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "UNDERLINE", start, end);
3767
3768 if (imhtml->edit.strike)
3769 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "STRIKE", start, end);
3770 else
3771 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "STRIKE", start, end);
3772
3773 if (imhtml->edit.forecolor) {
3774 remove_font_forecolor(imhtml, start, end, TRUE);
3775 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3776 find_font_forecolor_tag(imhtml, imhtml->edit.forecolor),
3777 start, end);
3778 }
3779
3780 if (imhtml->edit.backcolor) {
3781 remove_font_backcolor(imhtml, start, end, TRUE);
3782 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3783 find_font_backcolor_tag(imhtml, imhtml->edit.backcolor),
3784 start, end);
3785 }
3786
3787 if (imhtml->edit.background) {
3788 remove_font_background(imhtml, start, end, TRUE);
3789 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3790 find_font_background_tag(imhtml, imhtml->edit.background),
3791 start, end);
3792 }
3793 if (imhtml->edit.fontface) {
3794 remove_font_face(imhtml, start, end, TRUE);
3795 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3796 find_font_face_tag(imhtml, imhtml->edit.fontface),
3797 start, end);
3798 }
3799
3800 if (imhtml->edit.fontsize) {
3801 remove_font_size(imhtml, start, end, TRUE);
3802 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3803 find_font_size_tag(imhtml, imhtml->edit.fontsize),
3804 start, end);
3805 }
3806
3807 if (imhtml->edit.link) {
3808 remove_font_link(imhtml, start, end, TRUE);
3809 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3810 imhtml->edit.link,
3811 start, end);
3812 }
3813 }
3814
3815 void gtk_imhtml_set_editable(GtkIMHtml *imhtml, gboolean editable)
3816 {
3817 gtk_text_view_set_editable(GTK_TEXT_VIEW(imhtml), editable);
3818 /*
3819 * We need a visible caret for accessibility, so mouseless
3820 * people can highlight stuff.
3821 */
3822 /* gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(imhtml), editable); */
3823 imhtml->editable = editable;
3824 imhtml->format_functions = GTK_IMHTML_ALL;
3825
3826 if (editable)
3827 g_signal_connect_after(G_OBJECT(GTK_IMHTML(imhtml)->text_buffer), "mark-set",
3828 G_CALLBACK(mark_set_cb), imhtml);
3829 }
3830
3831 void gtk_imhtml_set_whole_buffer_formatting_only(GtkIMHtml *imhtml, gboolean wbfo)
3832 {
3833 g_return_if_fail(imhtml != NULL);
3834
3835 imhtml->wbfo = wbfo;
3836 }
3837
3838 void gtk_imhtml_set_format_functions(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons)
3839 {
3840 GObject *object = g_object_ref(G_OBJECT(imhtml));
3841 imhtml->format_functions = buttons;
3842 g_signal_emit(object, signals[BUTTONS_UPDATE], 0, buttons);
3843 g_object_unref(object);
3844 }
3845
3846 GtkIMHtmlButtons gtk_imhtml_get_format_functions(GtkIMHtml *imhtml)
3847 {
3848 return imhtml->format_functions;
3849 }
3850
3851 void gtk_imhtml_get_current_format(GtkIMHtml *imhtml, gboolean *bold,
3852 gboolean *italic, gboolean *underline)
3853 {
3854 if (imhtml->edit.bold)
3855 (*bold) = TRUE;
3856 if (imhtml->edit.italic)
3857 (*italic) = TRUE;
3858 if (imhtml->edit.underline)
3859 (*underline) = TRUE;
3860 }
3861
3862 char *
3863 gtk_imhtml_get_current_fontface(GtkIMHtml *imhtml)
3864 {
3865 if (imhtml->edit.fontface)
3866 return g_strdup(imhtml->edit.fontface);
3867 else
3868 return NULL;
3869 }
3870
3871 char *
3872 gtk_imhtml_get_current_forecolor(GtkIMHtml *imhtml)
3873 {
3874 if (imhtml->edit.forecolor)
3875 return g_strdup(imhtml->edit.forecolor);
3876 else
3877 return NULL;
3878 }
3879
3880 char *
3881 gtk_imhtml_get_current_backcolor(GtkIMHtml *imhtml)
3882 {
3883 if (imhtml->edit.backcolor)
3884 return g_strdup(imhtml->edit.backcolor);
3885 else
3886 return NULL;
3887 }
3888
3889 char *
3890 gtk_imhtml_get_current_background(GtkIMHtml *imhtml)
3891 {
3892 if (imhtml->edit.background)
3893 return g_strdup(imhtml->edit.background);
3894 else
3895 return NULL;
3896 }
3897
3898 gint
3899 gtk_imhtml_get_current_fontsize(GtkIMHtml *imhtml)
3900 {
3901 return imhtml->edit.fontsize;
3902 }
3903
3904 gboolean gtk_imhtml_get_editable(GtkIMHtml *imhtml)
3905 {
3906 return imhtml->editable;
3907 }
3908
3909 void
3910 gtk_imhtml_clear_formatting(GtkIMHtml *imhtml)
3911 { 3726 {
3912 GtkTextIter start, end; 3727 GtkTextIter start, end;
3913 GObject *object;
3914 3728
3915 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end); 3729 gtk_text_buffer_get_bounds(imhtml->text_buffer, &start, &end);
3916 3730
3917 /* Move the selection bounds (to select everything), so the format functions 3731 /* Move the selection bounds (to select everything), so the format functions
3918 * will know we want to manipulate the formatting on the entire buffer. */ 3732 * will know we want to manipulate the formatting on the entire buffer. */
3930 remove_font_size(imhtml, &start, &end, TRUE); 3744 remove_font_size(imhtml, &start, &end, TRUE);
3931 remove_font_face(imhtml, &start, &end, TRUE); 3745 remove_font_face(imhtml, &start, &end, TRUE);
3932 remove_font_forecolor(imhtml, &start, &end, TRUE); 3746 remove_font_forecolor(imhtml, &start, &end, TRUE);
3933 remove_font_backcolor(imhtml, &start, &end, TRUE); 3747 remove_font_backcolor(imhtml, &start, &end, TRUE);
3934 remove_font_background(imhtml, &start, &end, TRUE); 3748 remove_font_background(imhtml, &start, &end, TRUE);
3749 remove_font_link(imhtml, &start, &end, TRUE);
3935 3750
3936 imhtml->edit.bold = 0; 3751 imhtml->edit.bold = 0;
3937 imhtml->edit.italic = 0; 3752 imhtml->edit.italic = 0;
3938 imhtml->edit.underline = 0; 3753 imhtml->edit.underline = 0;
3939 imhtml->edit.strike = 0; 3754 imhtml->edit.strike = 0;
3940 imhtml->edit.fontsize = 0; 3755 imhtml->edit.fontsize = 0;
3941 imhtml->edit.forecolor = NULL; 3756 imhtml->edit.forecolor = NULL;
3942 imhtml->edit.backcolor = NULL; 3757 imhtml->edit.backcolor = NULL;
3943 imhtml->edit.background = NULL; 3758 imhtml->edit.background = NULL;
3944 3759
3945 object = g_object_ref(G_OBJECT(imhtml));
3946 g_signal_emit(object, signals[CLEAR_FORMAT], 0);
3947
3948 /* Remove the selection, placing the cursor at the end. */ 3760 /* Remove the selection, placing the cursor at the end. */
3949 #if GTK_CHECK_VERSION(2,4,0) 3761 #if GTK_CHECK_VERSION(2,4,0)
3950 gtk_text_buffer_select_range(imhtml->text_buffer, &end, &end); 3762 gtk_text_buffer_select_range(imhtml->text_buffer, &end, &end);
3951 #else 3763 #else
3952 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "insert", &end); 3764 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "insert", &end);
3953 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "selection_bound", &end); 3765 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "selection_bound", &end);
3954 #endif 3766 #endif
3767 }
3768
3769 /* Editable stuff */
3770 static void preinsert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml)
3771 {
3772 imhtml->insert_offset = gtk_text_iter_get_offset(iter);
3773 }
3774
3775 static void insert_ca_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextChildAnchor *arg2, gpointer user_data)
3776 {
3777 GtkTextIter start;
3778
3779 start = *arg1;
3780 gtk_text_iter_backward_char(&start);
3781
3782 gtk_imhtml_apply_tags_on_insert(user_data, &start, arg1);
3783 }
3784
3785 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *end, gchar *text, gint len, GtkIMHtml *imhtml)
3786 {
3787 GtkTextIter start;
3788
3789 if (!len)
3790 return;
3791
3792 start = *end;
3793 gtk_text_iter_set_offset(&start, imhtml->insert_offset);
3794
3795 gtk_imhtml_apply_tags_on_insert(imhtml, &start, end);
3796 }
3797
3798 static void gtk_imhtml_apply_tags_on_insert(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end)
3799 {
3800 if (imhtml->edit.bold)
3801 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "BOLD", start, end);
3802 else
3803 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "BOLD", start, end);
3804
3805 if (imhtml->edit.italic)
3806 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", start, end);
3807 else
3808 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "ITALICS", start, end);
3809
3810 if (imhtml->edit.underline)
3811 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", start, end);
3812 else
3813 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "UNDERLINE", start, end);
3814
3815 if (imhtml->edit.strike)
3816 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "STRIKE", start, end);
3817 else
3818 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "STRIKE", start, end);
3819
3820 if (imhtml->edit.forecolor) {
3821 remove_font_forecolor(imhtml, start, end, TRUE);
3822 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3823 find_font_forecolor_tag(imhtml, imhtml->edit.forecolor),
3824 start, end);
3825 }
3826
3827 if (imhtml->edit.backcolor) {
3828 remove_font_backcolor(imhtml, start, end, TRUE);
3829 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3830 find_font_backcolor_tag(imhtml, imhtml->edit.backcolor),
3831 start, end);
3832 }
3833
3834 if (imhtml->edit.background) {
3835 remove_font_background(imhtml, start, end, TRUE);
3836 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3837 find_font_background_tag(imhtml, imhtml->edit.background),
3838 start, end);
3839 }
3840 if (imhtml->edit.fontface) {
3841 remove_font_face(imhtml, start, end, TRUE);
3842 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3843 find_font_face_tag(imhtml, imhtml->edit.fontface),
3844 start, end);
3845 }
3846
3847 if (imhtml->edit.fontsize) {
3848 remove_font_size(imhtml, start, end, TRUE);
3849 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3850 find_font_size_tag(imhtml, imhtml->edit.fontsize),
3851 start, end);
3852 }
3853
3854 if (imhtml->edit.link) {
3855 remove_font_link(imhtml, start, end, TRUE);
3856 gtk_text_buffer_apply_tag(imhtml->text_buffer,
3857 imhtml->edit.link,
3858 start, end);
3859 }
3860 }
3861
3862 void gtk_imhtml_set_editable(GtkIMHtml *imhtml, gboolean editable)
3863 {
3864 gtk_text_view_set_editable(GTK_TEXT_VIEW(imhtml), editable);
3865 /*
3866 * We need a visible caret for accessibility, so mouseless
3867 * people can highlight stuff.
3868 */
3869 /* gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(imhtml), editable); */
3870 imhtml->editable = editable;
3871 imhtml->format_functions = GTK_IMHTML_ALL;
3872
3873 if (editable)
3874 g_signal_connect_after(G_OBJECT(GTK_IMHTML(imhtml)->text_buffer), "mark-set",
3875 G_CALLBACK(mark_set_cb), imhtml);
3876 }
3877
3878 void gtk_imhtml_set_whole_buffer_formatting_only(GtkIMHtml *imhtml, gboolean wbfo)
3879 {
3880 g_return_if_fail(imhtml != NULL);
3881
3882 imhtml->wbfo = wbfo;
3883 }
3884
3885 void gtk_imhtml_set_format_functions(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons)
3886 {
3887 GObject *object = g_object_ref(G_OBJECT(imhtml));
3888 imhtml->format_functions = buttons;
3889 g_signal_emit(object, signals[BUTTONS_UPDATE], 0, buttons);
3890 g_object_unref(object);
3891 }
3892
3893 GtkIMHtmlButtons gtk_imhtml_get_format_functions(GtkIMHtml *imhtml)
3894 {
3895 return imhtml->format_functions;
3896 }
3897
3898 void gtk_imhtml_get_current_format(GtkIMHtml *imhtml, gboolean *bold,
3899 gboolean *italic, gboolean *underline)
3900 {
3901 if (imhtml->edit.bold)
3902 (*bold) = TRUE;
3903 if (imhtml->edit.italic)
3904 (*italic) = TRUE;
3905 if (imhtml->edit.underline)
3906 (*underline) = TRUE;
3907 }
3908
3909 char *
3910 gtk_imhtml_get_current_fontface(GtkIMHtml *imhtml)
3911 {
3912 if (imhtml->edit.fontface)
3913 return g_strdup(imhtml->edit.fontface);
3914 else
3915 return NULL;
3916 }
3917
3918 char *
3919 gtk_imhtml_get_current_forecolor(GtkIMHtml *imhtml)
3920 {
3921 if (imhtml->edit.forecolor)
3922 return g_strdup(imhtml->edit.forecolor);
3923 else
3924 return NULL;
3925 }
3926
3927 char *
3928 gtk_imhtml_get_current_backcolor(GtkIMHtml *imhtml)
3929 {
3930 if (imhtml->edit.backcolor)
3931 return g_strdup(imhtml->edit.backcolor);
3932 else
3933 return NULL;
3934 }
3935
3936 char *
3937 gtk_imhtml_get_current_background(GtkIMHtml *imhtml)
3938 {
3939 if (imhtml->edit.background)
3940 return g_strdup(imhtml->edit.background);
3941 else
3942 return NULL;
3943 }
3944
3945 gint
3946 gtk_imhtml_get_current_fontsize(GtkIMHtml *imhtml)
3947 {
3948 return imhtml->edit.fontsize;
3949 }
3950
3951 gboolean gtk_imhtml_get_editable(GtkIMHtml *imhtml)
3952 {
3953 return imhtml->editable;
3954 }
3955
3956 void
3957 gtk_imhtml_clear_formatting(GtkIMHtml *imhtml)
3958 {
3959 GObject *object;
3960
3961 object = g_object_ref(G_OBJECT(imhtml));
3962 g_signal_emit(object, signals[CLEAR_FORMAT], 0);
3955 3963
3956 gtk_widget_grab_focus(GTK_WIDGET(imhtml)); 3964 gtk_widget_grab_focus(GTK_WIDGET(imhtml));
3957 3965
3958 g_object_unref(object); 3966 g_object_unref(object);
3959 } 3967 }