Mercurial > pidgin.yaz
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) { |