Mercurial > pidgin
comparison src/gtkimhtml.c @ 8692:0680ca680e92
[gaim-migrate @ 9445]
(23:31:08) SimGuy: LSchiere2: here
(23:31:20) SimGuy: but this patch also adds Win32 HTML clipboard support
(23:31:21) SimGuy: http://kevin.simguy.net/patches/imhtml-windows-rich-text-with-crashfix.diff
(23:32:01) SimGuy: LSchiere2: this feature is desirable in any case :)
(23:32:11) LSchiere2: crashing is desirable?
(23:32:22) SimGuy: no, win32 html clipboard :)
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sun, 18 Apr 2004 03:32:55 +0000 |
parents | 140b0d020c43 |
children | f83de0baf171 |
comparison
equal
deleted
inserted
replaced
8691:0eb5161ef333 | 8692:0680ca680e92 |
---|---|
38 #include <math.h> | 38 #include <math.h> |
39 #ifdef HAVE_LANGINFO_CODESET | 39 #ifdef HAVE_LANGINFO_CODESET |
40 #include <langinfo.h> | 40 #include <langinfo.h> |
41 #include <locale.h> | 41 #include <locale.h> |
42 #endif | 42 #endif |
43 #ifdef _WIN32 | |
44 #include <windows.h> | |
45 #endif | |
43 | 46 |
44 #ifdef ENABLE_NLS | 47 #ifdef ENABLE_NLS |
45 # include <libintl.h> | 48 # include <libintl.h> |
46 # define _(x) gettext(x) | 49 # define _(x) gettext(x) |
47 # ifdef gettext_noop | 50 # ifdef gettext_noop |
108 GtkTargetEntry link_drag_drop_targets[] = { | 111 GtkTargetEntry link_drag_drop_targets[] = { |
109 {"x-url/ftp", 0, DRAG_URL}, | 112 {"x-url/ftp", 0, DRAG_URL}, |
110 {"x-url/http", 0, DRAG_URL}, | 113 {"x-url/http", 0, DRAG_URL}, |
111 {"text/uri-list", 0, DRAG_URL}, | 114 {"text/uri-list", 0, DRAG_URL}, |
112 {"_NETSCAPE_URL", 0, DRAG_URL}}; | 115 {"_NETSCAPE_URL", 0, DRAG_URL}}; |
116 | |
117 #ifdef _WIN32 | |
118 /* Win32 clipboard format value, and functions to convert back and | |
119 * forth between HTML and the clipboard format. | |
120 */ | |
121 static UINT win_html_fmt; | |
122 | |
123 static gchar * | |
124 clipboard_win32_to_html(char *clipboard) { | |
125 const char *begin, *end; | |
126 gchar *html; | |
127 | |
128 begin = strstr(clipboard, "<!--StartFragment"); | |
129 while(*begin++ != '>'); | |
130 end = strstr(clipboard, "<!--EndFragment"); | |
131 html = g_strstrip(g_strndup(begin, (end ? (end - begin) : strlen(begin)))); | |
132 } | |
133 | |
134 static gchar * | |
135 clipboard_html_to_win32(char *html) { | |
136 int length; | |
137 gchar *ret; | |
138 GString *clipboard; | |
139 | |
140 if (html == NULL) | |
141 return NULL; | |
142 | |
143 length = strlen(html); | |
144 clipboard = g_string_new ("Version:0.9\r\n"); | |
145 g_string_append(clipboard, "StartHTML:0000000105\r\n"); | |
146 gaim_debug_info("html clipboard", "Length %d\n", clipboard->len); | |
147 g_string_append(clipboard, g_strdup_printf("EndHTML:%010d\r\n", 143 + length)); | |
148 gaim_debug_info("html clipboard", "Length %d\n", clipboard->len); | |
149 g_string_append(clipboard, "StartFragment:0000000105\r\n"); | |
150 gaim_debug_info("html clipboard", "Length %d\n", clipboard->len); | |
151 g_string_append(clipboard, g_strdup_printf("EndFragment:%010d\r\n", 143 + length)); | |
152 gaim_debug_info("html clipboard", "Length %d\n", clipboard->len); | |
153 g_string_append(clipboard, "<!--StartFragment-->"); | |
154 gaim_debug_info("html clipboard", "Length %d\n", clipboard->len); | |
155 g_string_append(clipboard, html); | |
156 gaim_debug_info("html clipboard", "Length %d\n", clipboard->len); | |
157 g_string_append(clipboard, "<!--EndFragment-->"); | |
158 gaim_debug_info("html clipboard", "Length %d\n", clipboard->len); | |
159 ret = clipboard->str; | |
160 g_string_free(clipboard, FALSE); | |
161 return ret; | |
162 } | |
163 | |
164 #endif | |
113 | 165 |
114 static GtkSmileyTree* | 166 static GtkSmileyTree* |
115 gtk_smiley_tree_new () | 167 gtk_smiley_tree_new () |
116 { | 168 { |
117 return g_new0 (GtkSmileyTree, 1); | 169 return g_new0 (GtkSmileyTree, 1); |
562 } | 614 } |
563 | 615 |
564 imhtml->clipboard_html_string = gtk_imhtml_get_markup_range(imhtml, &start, &end); | 616 imhtml->clipboard_html_string = gtk_imhtml_get_markup_range(imhtml, &start, &end); |
565 imhtml->clipboard_text_string = gtk_imhtml_get_text(imhtml, &start, &end); | 617 imhtml->clipboard_text_string = gtk_imhtml_get_text(imhtml, &start, &end); |
566 | 618 |
619 #ifdef _WIN32 | |
620 /* We're going to still copy plain text, but let's toss the "HTML Format" | |
621 we need into the windows clipboard now as well. */ | |
622 HGLOBAL hdata; | |
623 gchar *clipboard = clipboard_html_to_win32(imhtml->clipboard_html_string); | |
624 gchar *buffer; | |
625 gint length = strlen(clipboard); | |
626 if(clipboard != NULL) { | |
627 OpenClipboard(NULL); | |
628 hdata = GlobalAlloc(GMEM_MOVEABLE, length); | |
629 buffer = GlobalLock(hdata); | |
630 memcpy(buffer, clipboard, length); | |
631 GlobalUnlock(hdata); | |
632 SetClipboardData(win_html_fmt, hdata); | |
633 CloseClipboard(); | |
634 } | |
635 | |
636 gaim_debug_info("html clipboard", "clipboard set\n%s\n", (clipboard ? clipboard : "nothing")); | |
637 #endif | |
638 | |
567 g_signal_stop_emission_by_name(imhtml, "copy-clipboard"); | 639 g_signal_stop_emission_by_name(imhtml, "copy-clipboard"); |
568 } | 640 } |
569 | 641 |
570 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) | 642 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) |
571 { | 643 { |
575 GtkTextIter iter; | 647 GtkTextIter iter; |
576 | 648 |
577 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml))) | 649 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml))) |
578 return; | 650 return; |
579 | 651 |
652 #ifdef _WIN32 | |
653 /* If we're on windows, let's see if we can get data from the HTML Format | |
654 clipboard before we try to paste from the GTK buffer */ | |
655 HGLOBAL hdata; | |
656 DWORD err; | |
657 char *buffer; | |
658 if (IsClipboardFormatAvailable(win_html_fmt)) { | |
659 OpenClipboard(NULL); | |
660 hdata = GetClipboardData(win_html_fmt); | |
661 if (hdata == NULL) { | |
662 err = GetLastError(); | |
663 gaim_debug_info("html clipboard", "error number %u! See http://msdn.microsoft.com/library/en-us/debug/base/system_error_codes.asp\n", err); | |
664 CloseClipboard(); | |
665 return; | |
666 } | |
667 buffer = GlobalLock(hdata); | |
668 if (buffer == NULL) { | |
669 err = GetLastError(); | |
670 gaim_debug_info("html clipboard", "error number %u! See http://msdn.microsoft.com/library/en-us/debug/base/system_error_codes.asp\n", err); | |
671 CloseClipboard(); | |
672 return; | |
673 } | |
674 text = clipboard_win32_to_html(buffer); | |
675 gaim_debug_info("html clipboard", "buffer\n%s\n", (buffer ? buffer : "nothing")); | |
676 GlobalUnlock(hdata); | |
677 CloseClipboard(); | |
678 | |
679 gaim_debug_info("html clipboard", "text\n%s\n", (text ? text : "nothing")); | |
680 | |
681 } else | |
682 #endif | |
580 if (selection_data->length < 0) { | 683 if (selection_data->length < 0) { |
581 text = gtk_clipboard_wait_for_text(clipboard); | 684 text = gtk_clipboard_wait_for_text(clipboard); |
582 | 685 |
583 if (text == NULL) | 686 if (text == NULL) |
584 return; | 687 return; |
598 if (!imhtml->wbfo) | 701 if (!imhtml->wbfo) |
599 gtk_imhtml_close_tags(imhtml); | 702 gtk_imhtml_close_tags(imhtml); |
600 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, gtk_text_buffer_get_insert(imhtml->text_buffer)); | 703 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, gtk_text_buffer_get_insert(imhtml->text_buffer)); |
601 gtk_imhtml_insert_html_at_iter(imhtml, text, GTK_IMHTML_NO_NEWLINE, &iter); | 704 gtk_imhtml_insert_html_at_iter(imhtml, text, GTK_IMHTML_NO_NEWLINE, &iter); |
602 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "insert", &iter); | 705 gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "insert", &iter); |
603 | |
604 g_free(text); | 706 g_free(text); |
605 | 707 } |
606 } | |
607 | |
608 | 708 |
609 static void paste_clipboard_cb(GtkIMHtml *imhtml, gpointer blah) | 709 static void paste_clipboard_cb(GtkIMHtml *imhtml, gpointer blah) |
610 { | 710 { |
611 | 711 |
612 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); | 712 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); |
833 | 933 |
834 | 934 |
835 imhtml->scalables = NULL; | 935 imhtml->scalables = NULL; |
836 | 936 |
837 gtk_imhtml_set_editable(imhtml, FALSE); | 937 gtk_imhtml_set_editable(imhtml, FALSE); |
938 | |
939 #ifdef _WIN32 | |
940 /* Register HTML Format as desired clipboard format */ | |
941 win_html_fmt = RegisterClipboardFormat("HTML Format"); | |
942 #endif | |
838 } | 943 } |
839 | 944 |
840 GtkWidget *gtk_imhtml_new(void *a, void *b) | 945 GtkWidget *gtk_imhtml_new(void *a, void *b) |
841 { | 946 { |
842 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); | 947 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); |
2057 GtkIMHtmlFontDetail *font = fonts->data; | 2162 GtkIMHtmlFontDetail *font = fonts->data; |
2058 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); | 2163 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); |
2059 ws[0] = '\0'; wpos = 0; | 2164 ws[0] = '\0'; wpos = 0; |
2060 /* NEW_BIT (NEW_TEXT_BIT); */ | 2165 /* NEW_BIT (NEW_TEXT_BIT); */ |
2061 fonts = g_slist_remove (fonts, font); | 2166 fonts = g_slist_remove (fonts, font); |
2062 oldfont = fonts->data; | 2167 if (fonts) |
2063 | 2168 oldfont = fonts->data; |
2064 if (font->size != oldfont->size) | 2169 |
2065 gtk_imhtml_font_set_size(imhtml, oldfont->size); | 2170 if (!oldfont) { |
2066 if (font->underline != oldfont->underline) | 2171 gtk_imhtml_font_set_size(imhtml, 3); |
2067 gtk_imhtml_toggle_underline(imhtml); | 2172 if (font->underline) |
2068 if (oldfont->face == NULL || strcmp(font->face, oldfont->face) != 0) | 2173 gtk_imhtml_toggle_underline(imhtml); |
2174 gtk_imhtml_toggle_fontface(imhtml, NULL); | |
2175 gtk_imhtml_toggle_forecolor(imhtml, NULL); | |
2176 gtk_imhtml_toggle_backcolor(imhtml, NULL); | |
2177 } | |
2178 else | |
2069 { | 2179 { |
2070 g_free (font->face); | 2180 |
2071 gtk_imhtml_toggle_fontface(imhtml, oldfont->face); | 2181 if (font->size != oldfont->size) |
2182 gtk_imhtml_font_set_size(imhtml, oldfont->size); | |
2183 | |
2184 if (font->underline != oldfont->underline) | |
2185 gtk_imhtml_toggle_underline(imhtml); | |
2186 | |
2187 if (!oldfont->face || strcmp(font->face, oldfont->face) != 0) | |
2188 gtk_imhtml_toggle_fontface(imhtml, oldfont->face); | |
2189 | |
2190 if (!oldfont->fore || strcmp(font->fore, oldfont->fore) != 0) | |
2191 gtk_imhtml_toggle_forecolor(imhtml, oldfont->fore); | |
2192 | |
2193 if (!oldfont->back || strcmp(font->back, oldfont->back) != 0) | |
2194 gtk_imhtml_toggle_backcolor(imhtml, oldfont->back); | |
2072 } | 2195 } |
2073 if (oldfont->fore == NULL || strcmp(font->fore, oldfont->fore) != 0) | 2196 |
2074 { | 2197 g_free (font->face); |
2075 g_free (font->fore); | 2198 g_free (font->fore); |
2076 gtk_imhtml_toggle_forecolor(imhtml, oldfont->fore); | 2199 g_free (font->back); |
2077 } | 2200 g_free (font->sml); |
2078 if (oldfont->back == NULL || strcmp(font->back, oldfont->back) != 0) | 2201 |
2079 { | |
2080 g_free (font->back); | |
2081 gtk_imhtml_toggle_backcolor(imhtml, oldfont->back); | |
2082 } | |
2083 if (font->sml) | |
2084 g_free (font->sml); | |
2085 g_free (font); | 2202 g_free (font); |
2086 } | 2203 } |
2087 break; | 2204 break; |
2088 case 60: /* SPAN */ | 2205 case 60: /* SPAN */ |
2089 break; | 2206 break; |