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;