comparison src/gtkimhtml.c @ 8931:73223e21b943

[gaim-migrate @ 9701] This gives us a "Paste as Text" right click menu option for imhtml, thanks to khc and Simguy. I did some work on it too, and fixed all the bugs I could find. I also decided to change all the gtk_clipboard_get()s to gtk_widget_get_clipboard()s, all two of them. committer: Tailor Script <tailor@pidgin.im>
author Tim Ringenbach <marv@pidgin.im>
date Sat, 15 May 2004 05:56:55 +0000
parents 87e171358001
children 849507541e86
comparison
equal deleted inserted replaced
8930:4e59af6cc8de 8931:73223e21b943
75 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml); 75 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml);
76 static gboolean gtk_imhtml_is_amp_escape (const gchar *string, gchar **replace, gint *length); 76 static gboolean gtk_imhtml_is_amp_escape (const gchar *string, gchar **replace, gint *length);
77 void gtk_imhtml_close_tags(GtkIMHtml *imhtml, GtkTextIter *iter); 77 void gtk_imhtml_close_tags(GtkIMHtml *imhtml, GtkTextIter *iter);
78 static void gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml); 78 static void gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml);
79 static void mark_set_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextMark *mark, GtkIMHtml *imhtml); 79 static void mark_set_cb(GtkTextBuffer *buffer, GtkTextIter *arg1, GtkTextMark *mark, GtkIMHtml *imhtml);
80 static void hijack_menu_cb(GtkIMHtml *imhtml, GtkMenu *menu, gpointer data);
81 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data);
82 static void paste_plaintext_received_cb (GtkClipboard *clipboard, const gchar *text, gpointer data);
80 83
81 /* POINT_SIZE converts from AIM font sizes to point sizes. It probably should be redone in such a 84 /* POINT_SIZE converts from AIM font sizes to point sizes. It probably should be redone in such a
82 * way that it base the sizes off the default font size rather than using arbitrary font sizes. */ 85 * way that it base the sizes off the default font size rather than using arbitrary font sizes. */
83 #define MAX_FONT_SIZE 7 86 #define MAX_FONT_SIZE 7
84 #define POINT_SIZE(x) (options & GTK_IMHTML_USE_POINTSIZE ? x : _point_sizes [MIN ((x), MAX_FONT_SIZE) - 1]) 87 #define POINT_SIZE(x) (options & GTK_IMHTML_USE_POINTSIZE ? x : _point_sizes [MIN ((x), MAX_FONT_SIZE) - 1])
539 return TRUE; 542 return TRUE;
540 } 543 }
541 return FALSE; 544 return FALSE;
542 } 545 }
543 546
547 static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml)
548 {
549 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD);
550
551 gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml);
552
553 }
554
555 static void hijack_menu_cb(GtkIMHtml *imhtml, GtkMenu *menu, gpointer data)
556 {
557 GtkWidget *menuitem;
558
559 menuitem = gtk_menu_item_new_with_mnemonic(_("Pa_ste As Text"));
560 gtk_widget_show(menuitem);
561 gtk_widget_set_sensitive(menuitem,
562 (imhtml->editable &&
563 gtk_clipboard_wait_is_text_available(
564 gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD))));
565 /* put it after "Paste" */
566 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menuitem, 3);
567
568 g_signal_connect(G_OBJECT(menuitem), "activate",
569 G_CALLBACK(paste_unformatted_cb), imhtml);
570 }
571
544 static void gtk_imhtml_clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, GtkIMHtml *imhtml) { 572 static void gtk_imhtml_clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, GtkIMHtml *imhtml) {
545 char *text; 573 char *text;
546 gboolean primary; 574 gboolean primary;
547 GtkTextIter start, end; 575 GtkTextIter start, end;
548 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); 576 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer);
684 if (imhtml->editable) 712 if (imhtml->editable)
685 gtk_text_buffer_delete_selection(imhtml->text_buffer, FALSE, FALSE); 713 gtk_text_buffer_delete_selection(imhtml->text_buffer, FALSE, FALSE);
686 g_signal_stop_emission_by_name(imhtml, "cut-clipboard"); 714 g_signal_stop_emission_by_name(imhtml, "cut-clipboard");
687 } 715 }
688 716
717 static void imhtml_paste_insert(GtkIMHtml *imhtml, const char *text, gboolean plaintext)
718 {
719 GtkTextIter iter;
720 GtkIMHtmlOptions flags = plaintext ? 0 : GTK_IMHTML_NO_NEWLINE;
721
722 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, gtk_text_buffer_get_insert(imhtml->text_buffer));
723 if (!imhtml->wbfo && !plaintext)
724 gtk_imhtml_close_tags(imhtml, &iter);
725
726 gtk_imhtml_insert_html_at_iter(imhtml, text, flags, &iter);
727 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "insert", &iter);
728 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(imhtml), gtk_text_buffer_get_insert(imhtml->text_buffer),
729 0, FALSE, 0.0, 0.0);
730 }
731
732 static void paste_plaintext_received_cb (GtkClipboard *clipboard, const gchar *text, gpointer data)
733 {
734 char *tmp;
735
736 if (text == NULL)
737 return;
738
739 tmp = gaim_escape_html(text);
740 imhtml_paste_insert(data, tmp, TRUE);
741 g_free(tmp);
742 }
743
689 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) 744 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data)
690 { 745 {
691 char *text; 746 char *text;
692 GtkIMHtml *imhtml = data; 747 GtkIMHtml *imhtml = data;
693 GtkTextIter iter;
694 GtkIMHtmlOptions flags = GTK_IMHTML_NO_NEWLINE;
695 gboolean plaintext = FALSE;
696 748
697 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml))) 749 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)))
698 return; 750 return;
699 751
700 #ifdef _WIN32
701 /* If we're on windows, let's see if we can get data from the HTML Format
702 clipboard before we try to paste from the GTK buffer */
703 HGLOBAL hdata;
704 DWORD err;
705 char *buffer;
706 if (IsClipboardFormatAvailable(win_html_fmt)) {
707 OpenClipboard(NULL);
708 hdata = GetClipboardData(win_html_fmt);
709 if (hdata == NULL) {
710 err = GetLastError();
711 gaim_debug_info("html clipboard", "error number %u! See http://msdn.microsoft.com/library/en-us/debug/base/system_error_codes.asp\n", err);
712 CloseClipboard();
713 return;
714 }
715 buffer = GlobalLock(hdata);
716 if (buffer == NULL) {
717 err = GetLastError();
718 gaim_debug_info("html clipboard", "error number %u! See http://msdn.microsoft.com/library/en-us/debug/base/system_error_codes.asp\n", err);
719 CloseClipboard();
720 return;
721 }
722 text = clipboard_win32_to_html(buffer);
723 GlobalUnlock(hdata);
724 CloseClipboard();
725 } else
726 #endif
727 if (selection_data->length < 0) { 752 if (selection_data->length < 0) {
728 char *tmp; 753 gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml);
729 text = gtk_clipboard_wait_for_text(clipboard); 754 return;
730 flags = 0;
731 plaintext = TRUE;
732
733 if (text == NULL)
734 return;
735
736 tmp = gaim_escape_html(text);
737 g_free(text);
738 text = tmp;
739 } else { 755 } else {
740 #if 0 756 #if 0
741 /* Here's some debug code, for figuring out what sent to us over the clipboard. */ 757 /* Here's some debug code, for figuring out what sent to us over the clipboard. */
742 { 758 {
743 int i; 759 int i;
779 gaim_debug_warning("gtkimhtml", "empty string or invalid UTF-8 in paste_received_cb\n"); 795 gaim_debug_warning("gtkimhtml", "empty string or invalid UTF-8 in paste_received_cb\n");
780 g_free(text); 796 g_free(text);
781 return; 797 return;
782 } 798 }
783 799
784 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, gtk_text_buffer_get_insert(imhtml->text_buffer)); 800 imhtml_paste_insert(imhtml, text, FALSE);
785 if (!imhtml->wbfo && !plaintext)
786 gtk_imhtml_close_tags(imhtml, &iter);
787 gtk_imhtml_insert_html_at_iter(imhtml, text, flags, &iter);
788 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "insert", &iter);
789 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(imhtml), gtk_text_buffer_get_insert(imhtml->text_buffer),
790 0, FALSE, 0.0, 0.0);
791 g_free(text); 801 g_free(text);
792 } 802 }
793 803
794 static void paste_clipboard_cb(GtkIMHtml *imhtml, gpointer blah) 804 static void paste_clipboard_cb(GtkIMHtml *imhtml, gpointer blah)
795 { 805 {
796 806 #ifdef _WIN32
807 /* If we're on windows, let's see if we can get data from the HTML Format
808 clipboard before we try to paste from the GTK buffer */
809 HGLOBAL hdata;
810 DWORD err;
811 char *buffer;
812 char *text;
813
814 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)))
815 return;
816
817 if (IsClipboardFormatAvailable(win_html_fmt)) {
818 OpenClipboard(NULL);
819 hdata = GetClipboardData(win_html_fmt);
820 if (hdata == NULL) {
821 err = GetLastError();
822 gaim_debug_info("html clipboard", "error number %u! See http://msdn.microsoft.com/library/en-us/debug/base/system_error_codes.asp\n", err);
823 CloseClipboard();
824 return;
825 }
826 buffer = GlobalLock(hdata);
827 if (buffer == NULL) {
828 err = GetLastError();
829 gaim_debug_info("html clipboard", "error number %u! See http://msdn.microsoft.com/library/en-us/debug/base/system_error_codes.asp\n", err);
830 CloseClipboard();
831 return;
832 }
833 text = clipboard_win32_to_html(buffer);
834 GlobalUnlock(hdata);
835 CloseClipboard();
836
837 imhtml_paste_insert(imhtml, text, FALSE);
838 g_free(text);
839 } else {
840 #endif
797 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); 841 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD);
798 gtk_clipboard_request_contents(clipboard, gdk_atom_intern("text/html", FALSE), 842 gtk_clipboard_request_contents(clipboard, gdk_atom_intern("text/html", FALSE),
799 paste_received_cb, imhtml); 843 paste_received_cb, imhtml);
844 #ifdef _WIN32
845 }
846 #endif
800 g_signal_stop_emission_by_name(imhtml, "paste-clipboard"); 847 g_signal_stop_emission_by_name(imhtml, "paste-clipboard");
801 } 848 }
802 849
803 static void imhtml_realized_remove_primary(GtkIMHtml *imhtml, gpointer unused) 850 static void imhtml_realized_remove_primary(GtkIMHtml *imhtml, gpointer unused)
804 { 851 {
1024 1071
1025 imhtml->scalables = NULL; 1072 imhtml->scalables = NULL;
1026 1073
1027 gtk_imhtml_set_editable(imhtml, FALSE); 1074 gtk_imhtml_set_editable(imhtml, FALSE);
1028 1075
1076 g_signal_connect(G_OBJECT(imhtml), "populate-popup",
1077 G_CALLBACK(hijack_menu_cb), NULL);
1078
1029 #ifdef _WIN32 1079 #ifdef _WIN32
1030 /* Register HTML Format as desired clipboard format */ 1080 /* Register HTML Format as desired clipboard format */
1031 win_html_fmt = RegisterClipboardFormat("HTML Format"); 1081 win_html_fmt = RegisterClipboardFormat("HTML Format");
1032 #endif 1082 #endif
1033 } 1083 }
1081 } 1131 }
1082 1132
1083 static void url_copy(GtkWidget *w, gchar *url) { 1133 static void url_copy(GtkWidget *w, gchar *url) {
1084 GtkClipboard *clipboard; 1134 GtkClipboard *clipboard;
1085 1135
1086 clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); 1136 clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY);
1087 gtk_clipboard_set_text(clipboard, url, -1); 1137 gtk_clipboard_set_text(clipboard, url, -1);
1088 1138
1089 clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); 1139 clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_CLIPBOARD);
1090 gtk_clipboard_set_text(clipboard, url, -1); 1140 gtk_clipboard_set_text(clipboard, url, -1);
1091 } 1141 }
1092 1142
1093 /* The callback for an event on a link tag. */ 1143 /* The callback for an event on a link tag. */
1094 gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused) { 1144 gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused) {