changeset 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 0eb5161ef333
children f83de0baf171
files src/gtkimhtml.c
diffstat 1 files changed, 140 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/gtkimhtml.c	Sun Apr 18 03:27:33 2004 +0000
+++ b/src/gtkimhtml.c	Sun Apr 18 03:32:55 2004 +0000
@@ -40,6 +40,9 @@
 #include <langinfo.h>
 #include <locale.h>
 #endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
 
 #ifdef ENABLE_NLS
 #  include <libintl.h>
@@ -111,6 +114,55 @@
 	{"text/uri-list", 0, DRAG_URL},
 	{"_NETSCAPE_URL", 0, DRAG_URL}};
 
+#ifdef _WIN32
+/* Win32 clipboard format value, and functions to convert back and
+ * forth between HTML and the clipboard format.
+ */
+static UINT win_html_fmt;
+
+static gchar *
+clipboard_win32_to_html(char *clipboard) {
+    const char *begin, *end;
+	gchar *html;
+
+    begin = strstr(clipboard, "<!--StartFragment");
+    while(*begin++ != '>');
+	end = strstr(clipboard, "<!--EndFragment");
+	html = g_strstrip(g_strndup(begin, (end ? (end - begin) : strlen(begin))));
+}
+
+static gchar *
+clipboard_html_to_win32(char *html) {
+    int length;
+	gchar *ret;
+	GString *clipboard;
+
+    if (html == NULL)
+	    return NULL;
+
+	length = strlen(html);
+	clipboard = g_string_new ("Version:0.9\r\n");
+	g_string_append(clipboard, "StartHTML:0000000105\r\n");
+	gaim_debug_info("html clipboard", "Length %d\n", clipboard->len);
+	g_string_append(clipboard, g_strdup_printf("EndHTML:%010d\r\n", 143 + length));
+	gaim_debug_info("html clipboard", "Length %d\n", clipboard->len);
+	g_string_append(clipboard, "StartFragment:0000000105\r\n");
+	gaim_debug_info("html clipboard", "Length %d\n", clipboard->len);
+	g_string_append(clipboard, g_strdup_printf("EndFragment:%010d\r\n", 143 + length));
+	gaim_debug_info("html clipboard", "Length %d\n", clipboard->len);
+	g_string_append(clipboard, "<!--StartFragment-->");
+	gaim_debug_info("html clipboard", "Length %d\n", clipboard->len);
+	g_string_append(clipboard, html);
+	gaim_debug_info("html clipboard", "Length %d\n", clipboard->len);
+	g_string_append(clipboard, "<!--EndFragment-->");
+	gaim_debug_info("html clipboard", "Length %d\n", clipboard->len);
+	ret = clipboard->str;
+	g_string_free(clipboard, FALSE);
+	return ret;
+}
+
+#endif
+
 static GtkSmileyTree*
 gtk_smiley_tree_new ()
 {
@@ -564,6 +616,26 @@
 	imhtml->clipboard_html_string = gtk_imhtml_get_markup_range(imhtml, &start, &end);
 	imhtml->clipboard_text_string = gtk_imhtml_get_text(imhtml, &start, &end);
 
+#ifdef _WIN32
+	/* We're going to still copy plain text, but let's toss the "HTML Format"
+	   we need into the windows clipboard now as well.	*/
+	HGLOBAL hdata;
+	gchar *clipboard = clipboard_html_to_win32(imhtml->clipboard_html_string);
+	gchar *buffer;
+	gint length = strlen(clipboard);
+	if(clipboard != NULL) {
+	    OpenClipboard(NULL);
+		hdata = GlobalAlloc(GMEM_MOVEABLE, length);
+		buffer = GlobalLock(hdata);
+        memcpy(buffer, clipboard, length);
+		GlobalUnlock(hdata);
+        SetClipboardData(win_html_fmt, hdata);
+		CloseClipboard();
+	}
+
+	gaim_debug_info("html clipboard", "clipboard set\n%s\n", (clipboard ? clipboard : "nothing"));
+#endif
+
 	g_signal_stop_emission_by_name(imhtml, "copy-clipboard");
 }
 
@@ -577,6 +649,37 @@
 	if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)))
 		return;
 
+#ifdef _WIN32
+	/* If we're on windows, let's see if we can get data from the HTML Format
+	   clipboard before we try to paste from the GTK buffer */
+	HGLOBAL hdata;
+	DWORD err;
+	char *buffer;
+	if (IsClipboardFormatAvailable(win_html_fmt)) {
+	    OpenClipboard(NULL);
+		hdata = GetClipboardData(win_html_fmt);
+		if (hdata == NULL) {
+		    err = GetLastError();
+			gaim_debug_info("html clipboard", "error number %u!  See http://msdn.microsoft.com/library/en-us/debug/base/system_error_codes.asp\n", err);
+			CloseClipboard();
+			return;
+		}
+		buffer = GlobalLock(hdata);
+		if (buffer == NULL) {
+		    err = GetLastError();
+			gaim_debug_info("html clipboard", "error number %u!  See http://msdn.microsoft.com/library/en-us/debug/base/system_error_codes.asp\n", err);
+			CloseClipboard();
+			return;
+		}
+		text = clipboard_win32_to_html(buffer);
+		gaim_debug_info("html clipboard", "buffer\n%s\n", (buffer ? buffer : "nothing"));
+		GlobalUnlock(hdata);
+		CloseClipboard();
+
+		gaim_debug_info("html clipboard", "text\n%s\n", (text ? text : "nothing"));
+
+	} else
+#endif
 	if (selection_data->length < 0) {
 		text = gtk_clipboard_wait_for_text(clipboard);
 
@@ -600,12 +703,9 @@
 	gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, gtk_text_buffer_get_insert(imhtml->text_buffer));
 	gtk_imhtml_insert_html_at_iter(imhtml, text, GTK_IMHTML_NO_NEWLINE, &iter);
 	gtk_text_buffer_move_mark_by_name(imhtml->text_buffer, "insert", &iter);
-
 	g_free(text);
-
 }
 
-
 static void paste_clipboard_cb(GtkIMHtml *imhtml, gpointer blah)
 {
 
@@ -835,6 +935,11 @@
 	imhtml->scalables = NULL;
 
 	gtk_imhtml_set_editable(imhtml, FALSE);
+
+#ifdef _WIN32
+	/* Register HTML Format as desired clipboard format */
+	win_html_fmt = RegisterClipboardFormat("HTML Format");
+#endif
 }
 
 GtkWidget *gtk_imhtml_new(void *a, void *b)
@@ -2059,29 +2164,41 @@
 						ws[0] = '\0'; wpos = 0;
 						/* NEW_BIT (NEW_TEXT_BIT); */
 						fonts = g_slist_remove (fonts, font);
-						oldfont = fonts->data;
-
-						if (font->size != oldfont->size)
-						    gtk_imhtml_font_set_size(imhtml, oldfont->size);
-						if (font->underline != oldfont->underline)
-						    gtk_imhtml_toggle_underline(imhtml);
-						if (oldfont->face == NULL || strcmp(font->face, oldfont->face) != 0)
-						{
-							g_free (font->face);
-						    gtk_imhtml_toggle_fontface(imhtml, oldfont->face);
+						if (fonts)
+						    oldfont = fonts->data;
+
+						if (!oldfont) {
+							gtk_imhtml_font_set_size(imhtml, 3);
+							if (font->underline)
+							    gtk_imhtml_toggle_underline(imhtml);
+							gtk_imhtml_toggle_fontface(imhtml, NULL);
+							gtk_imhtml_toggle_forecolor(imhtml, NULL);
+							gtk_imhtml_toggle_backcolor(imhtml, NULL);
 						}
-						if (oldfont->fore == NULL || strcmp(font->fore, oldfont->fore) != 0)
+						else
 						{
-							g_free (font->fore);
-						    gtk_imhtml_toggle_forecolor(imhtml, oldfont->fore);
+
+						    if (font->size != oldfont->size)
+							    gtk_imhtml_font_set_size(imhtml, oldfont->size);
+
+							if (font->underline != oldfont->underline)
+							    gtk_imhtml_toggle_underline(imhtml);
+
+							if (!oldfont->face || strcmp(font->face, oldfont->face) != 0)
+							    gtk_imhtml_toggle_fontface(imhtml, oldfont->face);
+
+							if (!oldfont->fore || strcmp(font->fore, oldfont->fore) != 0)
+							    gtk_imhtml_toggle_forecolor(imhtml, oldfont->fore);
+
+							if (!oldfont->back || strcmp(font->back, oldfont->back) != 0)
+						      gtk_imhtml_toggle_backcolor(imhtml, oldfont->back);
 						}
-						if (oldfont->back == NULL || strcmp(font->back, oldfont->back) != 0)
-						{
-							g_free (font->back);
-						    gtk_imhtml_toggle_backcolor(imhtml, oldfont->back);
-						}
-						if (font->sml)
-							g_free (font->sml);
+
+						g_free (font->face);
+						g_free (font->fore);
+						g_free (font->back);
+						g_free (font->sml);
+
 						g_free (font);
 					}
 					break;