changeset 10175:53410b84336f

[gaim-migrate @ 11290] I wrote a helper function that creates the imhtml and toolbar and puts them in a widget and what not. And I changed some places to use this. And I removed some whitespace from log.c. And I changed the conversation colors back to normal. And I'm not committing everything in my tree, so let me know if this doesn't compile. And that's all. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 14 Nov 2004 01:52:25 +0000
parents 8dd4535dd359
children 0109f3a518d2
files src/gtkconv.c src/gtkconv.h src/gtkdebug.c src/gtkdialogs.c src/gtklog.c src/gtkutils.c src/gtkutils.h
diffstat 7 files changed, 168 insertions(+), 194 deletions(-) [+]
line wrap: on
line diff
--- a/src/gtkconv.c	Sat Nov 13 16:17:41 2004 +0000
+++ b/src/gtkconv.c	Sun Nov 14 01:52:25 2004 +0000
@@ -66,8 +66,8 @@
 
 #define AUTO_RESPONSE "&lt;AUTO-REPLY&gt; : "
 
-#define SEND_COLOR "#0d005d"
-#define RECV_COLOR "#fd4100"
+#define SEND_COLOR "#16569E"
+#define RECV_COLOR "#A82F2F"
 
 #define LUMINANCE(c) (float)((0.3*(c.red))+(0.59*(c.green))+(0.11*(c.blue)))
 
@@ -170,7 +170,7 @@
 
 	if (gaim_conversation_get_type(conv) == GAIM_CONV_IM)
 	{
-		if (w == gtkconv->sw && (gaim_conv_window_get_conversation_count(win) == 1))
+		if (w == gtkconv->imhtml && (gaim_conv_window_get_conversation_count(win) == 1))
 		{
 			gaim_prefs_set_int("/gaim/gtk/conversations/im/default_width", allocation->width);
 			if (saveheight)
@@ -181,7 +181,7 @@
 	}
 	else if (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT)
 	{
-		if (w == gtkconv->sw && (gaim_conv_window_get_conversation_count(win) == 1))
+		if (w == gtkconv->imhtml && (gaim_conv_window_get_conversation_count(win) == 1))
 		{
 			gaim_prefs_set_int("/gaim/gtk/conversations/chat/default_width", allocation->width);
 			if (saveheight)
@@ -3972,7 +3972,7 @@
 	GaimGtkChatPane *gtkchat;
 	GaimConnection *gc;
 	GtkWidget *vpaned, *hpaned;
-	GtkWidget *vbox, *hbox, *frame, *vbox2, *sep;
+	GtkWidget *vbox, *hbox, *frame;
 	GtkWidget *lbox, *bbox;
 	GtkWidget *label;
 	GtkWidget *list;
@@ -4027,31 +4027,20 @@
 	gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0);
 	gtk_widget_show(hpaned);
 
-	/* Setup the scrolled window to put gtkimhtml in. */
-	gtkconv->sw = gtk_scrolled_window_new(NULL, NULL);
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkconv->sw),
-								   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkconv->sw),
-										GTK_SHADOW_IN);
-	gtk_paned_pack1(GTK_PANED(hpaned), gtkconv->sw, TRUE, TRUE);
-
-	gtk_widget_set_size_request(gtkconv->sw,
+	/* Setup gtkihmtml. */
+	frame = gaim_gtk_create_imhtml(FALSE, &gtkconv->imhtml, NULL);
+	gtk_widget_set_name(gtkconv->imhtml, "gaim_gtkconv_imhtml");
+	gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
+			gaim_prefs_get_bool("/gaim/gtk/conversations/show_timestamps"));
+	gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE);
+	gtk_widget_show(frame);
+
+	gtk_widget_set_size_request(gtkconv->imhtml,
 			gaim_prefs_get_int("/gaim/gtk/conversations/chat/default_width"),
 			gaim_prefs_get_int("/gaim/gtk/conversations/chat/default_height"));
-
-	g_signal_connect(G_OBJECT(gtkconv->sw), "size-allocate",
+	g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
 					 G_CALLBACK(size_allocate_cb), conv);
 
-	gtk_widget_show(gtkconv->sw);
-
-	/* Setup gtkihmtml. */
-	gtkconv->imhtml = gtk_imhtml_new(NULL, NULL);
-	gtk_widget_set_name(gtkconv->imhtml, "gaim_gtkconv_imhtml");
-	gtk_container_add(GTK_CONTAINER(gtkconv->sw), gtkconv->imhtml);
-
-	gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
-			gaim_prefs_get_bool("/gaim/gtk/conversations/show_timestamps"));
-
 	g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
 						   G_CALLBACK(entry_stop_rclick_cb), NULL);
 	g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
@@ -4059,9 +4048,6 @@
 	g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
 						   G_CALLBACK(refocus_entry_cb), gtkconv);
 
-	gaim_setup_imhtml(gtkconv->imhtml);
-	gtk_widget_show(gtkconv->imhtml);
-
 	/* Build the right pane. */
 	lbox = gtk_vbox_new(FALSE, 6);
 	gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE);
@@ -4160,9 +4146,7 @@
 
 	gtkconv->info = button;
 
-	/* Build the toolbar. */
-	frame = gtk_frame_new(NULL);
-
+	/* Setup the bottom half of the conversation window */
 	vbox = gtk_vbox_new(FALSE, 6);
 	gtk_paned_pack2(GTK_PANED(vpaned), vbox, FALSE, TRUE);
 	gtk_widget_show(vbox);
@@ -4175,47 +4159,18 @@
 	gtk_box_pack_end(GTK_BOX(gtkconv->lower_hbox), vbox, TRUE, TRUE, 0);
 	gtk_widget_show(vbox);
 
-	frame = gtk_frame_new(NULL);
+	/* Setup the toolbar, entry widget and all signals */
+	frame = gaim_gtk_create_imhtml(TRUE, &gtkconv->entry, &gtkconv->toolbar);
 	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
-	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
-	vbox2 = gtk_vbox_new(FALSE, 0);
-	gtk_container_add(GTK_CONTAINER(frame), vbox2);
-	gtk_widget_show_all(frame);
-
-	gtkconv->toolbar = gtk_imhtmltoolbar_new();
-	gtk_box_pack_start(GTK_BOX(vbox2), gtkconv->toolbar, FALSE, FALSE, 0);
-
-	sep = gtk_hseparator_new();
-	gtk_box_pack_start(GTK_BOX(vbox2), sep, FALSE, FALSE, 0);
-	gtk_widget_show(sep);
-
-	/* Setup the entry widget.
-	 * We never show the horizontal scrollbar because it was causing weird
-	 * lockups when typing text just as you type the character that would 
-	 * cause both scrollbars to appear.  Definitely seems like a gtk bug.
-	 */
-	sw = gtk_scrolled_window_new(NULL, NULL);
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
-				       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
-					    GTK_SHADOW_NONE);
-	gtk_box_pack_start(GTK_BOX(vbox2), sw, TRUE, TRUE, 0);
-	gtk_widget_show(sw);
-
-	gtkconv->entry = gtk_imhtml_new(NULL, NULL);
+	gtk_widget_show(frame);
+
 	gtk_widget_set_name(gtkconv->entry, "gaim_gtkconv_entry");
-
 	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
 								 gaim_account_get_protocol_name(conv->account));
+	gtk_widget_set_size_request(gtkconv->entry, -1,
+			gaim_prefs_get_int("/gaim/gtk/conversations/chat/entry_height"));
 	gtkconv->entry_buffer =
 		gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry));
-	gaim_setup_imhtml(gtkconv->entry);
-	gtk_imhtml_set_editable(GTK_IMHTML(gtkconv->entry), TRUE);
-	default_formatize(conv);
-	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(gtkconv->entry),
-								GTK_WRAP_WORD_CHAR);
-	gtk_widget_set_size_request(gtkconv->entry, -1,
-			gaim_prefs_get_int("/gaim/gtk/conversations/chat/entry_height"));
 	g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", conv);
 
 	g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event",
@@ -4227,13 +4182,7 @@
 	g_signal_connect(G_OBJECT(gtkconv->entry), "size-allocate",
 					 G_CALLBACK(size_allocate_cb), conv);
 
-	if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck"))
-		gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(gtkconv->entry));
-	gtk_imhtmltoolbar_attach(GTK_IMHTMLTOOLBAR(gtkconv->toolbar),
-							 gtkconv->entry);
-
-	gtk_container_add(GTK_CONTAINER(sw), GTK_WIDGET(gtkconv->entry));
-	gtk_widget_show(gtkconv->entry);
+	default_formatize(conv);
 
 	/* Setup the bottom button box. */
 	gtkconv->bbox = gtk_hbox_new(FALSE, 6);
@@ -4257,42 +4206,37 @@
 {
 	GaimGtkConversation *gtkconv;
 	GaimGtkImPane *gtkim;
+	GtkWidget *frame;
 	GtkWidget *paned;
-	GtkWidget *vbox, *sep;
-	GtkWidget *vbox2, *vbox3, *frame;
-	GtkWidget *sw;
+	GtkWidget *vbox;
+	GtkWidget *vbox2;
 	GList *focus_chain = NULL;
 
 	gtkconv = GAIM_GTK_CONVERSATION(conv);
 	gtkim   = gtkconv->u.im;
 
-	/* Setup the outer pane. */
+	/* Setup the outer pane */
 	paned = gtk_vpaned_new();
 	gtk_widget_show(paned);
 
-	/* Setup the top part of the pane. */
+	/* Setup the top part of the pane */
 	vbox = gtk_vbox_new(FALSE, 6);
 	gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE);
 	gtk_widget_show(vbox);
 
-	/* Setup the gtkimhtml widget. */
-	gtkconv->sw = gtk_scrolled_window_new(NULL, NULL);
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkconv->sw),
-								   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkconv->sw),
-										GTK_SHADOW_IN);
-	gtk_box_pack_start(GTK_BOX(vbox), gtkconv->sw, TRUE, TRUE, 0);
-
-	gtk_widget_set_size_request(gtkconv->sw,
+	/* Setup the gtkimhtml widget */
+	frame = gaim_gtk_create_imhtml(FALSE, &gtkconv->imhtml, NULL);
+	gtk_widget_set_name(gtkconv->imhtml, "gaim_gtkconv_imhtml");
+	gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
+			gaim_prefs_get_bool("/gaim/gtk/conversations/show_timestamps"));
+	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+	gtk_widget_show(frame);
+
+	gtk_widget_set_size_request(gtkconv->imhtml,
 			gaim_prefs_get_int("/gaim/gtk/conversations/im/default_width"),
 			gaim_prefs_get_int("/gaim/gtk/conversations/im/default_height"));
-	g_signal_connect(G_OBJECT(gtkconv->sw), "size-allocate",
+	g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
 					 G_CALLBACK(size_allocate_cb), conv);
-	gtk_widget_show(gtkconv->sw);
-
-	gtkconv->imhtml = gtk_imhtml_new(NULL, NULL);
-	gtk_widget_set_name(gtkconv->imhtml, "gaim_gtkconv_imhtml");
-	gtk_container_add(GTK_CONTAINER(gtkconv->sw), gtkconv->imhtml);
 
 	g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
 						   G_CALLBACK(entry_stop_rclick_cb), NULL);
@@ -4301,19 +4245,11 @@
 	g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
 						   G_CALLBACK(refocus_entry_cb), gtkconv);
 
-	gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
-			gaim_prefs_get_bool("/gaim/gtk/conversations/show_timestamps"));
-	gaim_setup_imhtml(gtkconv->imhtml);
-	gtk_widget_show(gtkconv->imhtml);
+	/* Setup the bottom half of the conversation window */
 	vbox2 = gtk_vbox_new(FALSE, 6);
 	gtk_paned_pack2(GTK_PANED(paned), vbox2, FALSE, TRUE);
 	gtk_widget_show(vbox2);
 
-	/* Setup the entry widget.
-	 * We never show the horizontal scrollbar because it was causing weird
-	 * lockups when typing text just as you type the character that would
-	 * cause both scrollbars to appear.  Definitely seems like a gtk bug.
-	 */
 	gtkconv->lower_hbox = gtk_hbox_new(FALSE, 6);
 	gtk_box_pack_start(GTK_BOX(vbox2), gtkconv->lower_hbox, TRUE, TRUE, 0);
 	gtk_widget_show(gtkconv->lower_hbox);
@@ -4322,42 +4258,18 @@
 	gtk_box_pack_end(GTK_BOX(gtkconv->lower_hbox), vbox2, TRUE, TRUE, 0);
 	gtk_widget_show(vbox2);
 
-	frame = gtk_frame_new(NULL);
-	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+	/* Setup the toolbar, entry widget and all signals */
+	frame = gaim_gtk_create_imhtml(TRUE, &gtkconv->entry, &gtkconv->toolbar);
 	gtk_box_pack_start(GTK_BOX(vbox2), frame, TRUE, TRUE, 0);
-	vbox3 = gtk_vbox_new(FALSE, 0);
-	gtk_container_add(GTK_CONTAINER(frame), vbox3);
-	gtk_widget_show_all(frame);
-
-	/* Build the toolbar. */
-	gtkconv->toolbar = gtk_imhtmltoolbar_new();
-	gtk_box_pack_start(GTK_BOX(vbox3), gtkconv->toolbar, FALSE, FALSE, 0);
-
-	sep = gtk_hseparator_new();
-	gtk_box_pack_start(GTK_BOX(vbox3), sep, FALSE, FALSE, 0);
-	gtk_widget_show(sep);
-
-	sw = gtk_scrolled_window_new(NULL, NULL);
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
-								   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
-										GTK_SHADOW_NONE);
-	gtk_box_pack_start(GTK_BOX(vbox3), sw, TRUE, TRUE, 0);
-	gtk_widget_show(sw);
-
-	gtkconv->entry = gtk_imhtml_new(NULL, NULL);
+	gtk_widget_show(frame);
+
 	gtk_widget_set_name(gtkconv->entry, "gaim_gtkconv_entry");
-
 	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
 								 gaim_account_get_protocol_name(conv->account));
+	gtk_widget_set_size_request(gtkconv->entry, -1,
+			gaim_prefs_get_int("/gaim/gtk/conversations/im/entry_height"));
 	gtkconv->entry_buffer =
 		gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry));
-	gaim_setup_imhtml(gtkconv->entry);
-	gtk_imhtml_set_editable(GTK_IMHTML(gtkconv->entry), TRUE);
-	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(gtkconv->entry),
-								GTK_WRAP_WORD_CHAR);
-	gtk_widget_set_size_request(gtkconv->entry, -1,
-			gaim_prefs_get_int("/gaim/gtk/conversations/im/entry_height"));
 	g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", conv);
 
 	g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event",
@@ -4373,13 +4285,6 @@
 	g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range",
 					 G_CALLBACK(delete_text_cb), conv);
 
-	if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck"))
-		gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(gtkconv->entry));
-
-	gtk_container_add(GTK_CONTAINER(sw), GTK_WIDGET(gtkconv->entry));
-	gtk_widget_show(gtkconv->entry);
-	gtk_imhtmltoolbar_attach(GTK_IMHTMLTOOLBAR(gtkconv->toolbar),
-							 gtkconv->entry);
 	/* had to move this after the imtoolbar is attached so that the
 	 * signals get fired to toggle the buttons on the toolbar as well.
 	 */
@@ -5732,7 +5637,7 @@
 	g_return_if_fail(gaim_conversation_get_type(conv) == GAIM_CONV_IM);
 
 	gtkconv = GAIM_GTK_CONVERSATION(conv);
-	
+
 	if (!gtkconv->u.im->show_icon)
 		return;
 
--- a/src/gtkconv.h	Sat Nov 13 16:17:41 2004 +0000
+++ b/src/gtkconv.h	Sun Nov 14 01:52:25 2004 +0000
@@ -177,7 +177,6 @@
 	GtkSizeGroup *sg;
 
 	GtkWidget *bbox;
-	GtkWidget *sw;
 	GtkWidget *lower_hbox;
 
 	GtkWidget *toolbar;
--- a/src/gtkdebug.c	Sat Nov 13 16:17:41 2004 +0000
+++ b/src/gtkdebug.c	Sun Nov 14 01:52:25 2004 +0000
@@ -228,7 +228,7 @@
 	DebugWindow *win;
 	GtkWidget *vbox;
 	GtkWidget *toolbar;
-	GtkWidget *sw;
+	GtkWidget *frame;
 	GtkWidget *button;
 	GtkWidget *image;
 	int width, height;
@@ -299,20 +299,10 @@
 									timestamps_pref_cb, button);
 	}
 
-	/* Now our scrolled window... */
-	sw = gtk_scrolled_window_new(NULL, NULL);
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
-								   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
-										GTK_SHADOW_IN);
-
-	/* ... which has a gtkimhtml in it. */
-	win->text = gtk_imhtml_new(NULL, NULL);
-
-	gtk_container_add(GTK_CONTAINER(sw), win->text);
-
-	/* Pack it in... Not like that, sicko. */
-	gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
+	/* Add the gtkimhtml */
+	frame = gaim_gtk_create_imhtml(FALSE, &win->text, NULL);
+	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+	gtk_widget_show(frame);
 
 	gtk_widget_show_all(win->window);
 
--- a/src/gtkdialogs.c	Sat Nov 13 16:17:41 2004 +0000
+++ b/src/gtkdialogs.c	Sun Nov 14 01:52:25 2004 +0000
@@ -164,7 +164,7 @@
 	GtkWidget *vbox;
 	GtkWidget *logo;
 	GtkWidget *label;
-	GtkWidget *sw;
+	GtkWidget *frame;
 	GtkWidget *text;
 	GtkWidget *bbox;
 	GtkWidget *button;
@@ -203,15 +203,8 @@
 	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 	g_free(labeltext);
 
-	sw = gtk_scrolled_window_new(NULL, NULL);
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
-				GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
-	gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
-
-	text = gtk_imhtml_new(NULL, NULL);
-	gtk_container_add(GTK_CONTAINER(sw), text);
-	gaim_setup_imhtml(text);
+	frame = gaim_gtk_create_imhtml(FALSE, &text, NULL);
+	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
 
 	str = g_string_sized_new(4096);
 
@@ -316,7 +309,6 @@
 	gtk_imhtml_append_text(GTK_IMHTML(text), str->str, GTK_IMHTML_NO_SCROLL);
 	g_string_free(str, TRUE);
 
-	gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(sw)), 0);
 	gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &iter);
 	gtk_text_buffer_place_cursor(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &iter);
 
--- a/src/gtklog.c	Sat Nov 13 16:17:41 2004 +0000
+++ b/src/gtklog.c	Sun Nov 14 01:52:25 2004 +0000
@@ -70,10 +70,10 @@
 	const char *search_term = gtk_entry_get_text(GTK_ENTRY(lv->entry));
 	GList *logs;
 	GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
-	
+
 	if (lv->search)
 		g_free(lv->search);
-	
+
        	gtk_tree_store_clear(lv->treestore);
 	if (strlen(search_term) == 0) {/* reset the tree */
 		populate_log_tree(lv);
@@ -81,14 +81,14 @@
 		gtk_imhtml_search_clear(GTK_IMHTML(lv->imhtml));
 		return;
 	}
-	
+
 	lv->search = g_strdup(search_term);
-	
+
 	gdk_window_set_cursor(lv->window->window, cursor);
 	while (gtk_events_pending())
 		gtk_main_iteration();
 	gdk_cursor_unref(cursor);
-	
+
 	for (logs = lv->logs; logs != NULL; logs = logs->next) {
 		char *read = gaim_log_read((GaimLog*)logs->data, NULL);
 		if (gaim_strcasestr(read, search_term)) {
@@ -103,11 +103,11 @@
 			gtk_tree_store_append (lv->treestore, &iter, NULL);
 			gtk_tree_store_set(lv->treestore, &iter,
 					   0, title,
-					   1, log, -1);	
+					   1, log, -1);
 		}
 	}
-	
-	
+
+
 	cursor = gdk_cursor_new(GDK_LEFT_PTR);
 	gdk_window_set_cursor(lv->window->window, cursor);
 	gdk_cursor_unref(cursor);
@@ -189,13 +189,13 @@
 	title = title_utf8;
 	gtk_window_set_title(GTK_WINDOW(viewer->window), title);
 	gtk_imhtml_clear(GTK_IMHTML(viewer->imhtml));
-       	gtk_imhtml_append_text(GTK_IMHTML(viewer->imhtml), read, 
-			       GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_SCROLL | 
+       	gtk_imhtml_append_text(GTK_IMHTML(viewer->imhtml), read,
+			       GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_SCROLL |
 			       ((flags & GAIM_LOG_READ_NO_NEWLINE) ? GTK_IMHTML_NO_NEWLINE : 0));
 
 	if (viewer->search)
 		gtk_imhtml_search_find(GTK_IMHTML(viewer->imhtml), viewer->search);
-	
+
 	g_free(read);
 	g_free(title);
 }
@@ -218,32 +218,32 @@
 	GList *logs = lv->logs;
 	while (logs) {
 		GaimLog *log = logs->data;
-		
+
 		strftime(month, sizeof(month), "%B %Y", localtime(&log->time));
 		strftime(title, sizeof(title), "%c", localtime(&log->time));
-		
+
 		/* do utf8 conversions */
 		utf8_tmp = gaim_utf8_try_convert(month);
 		strncpy(month, utf8_tmp, sizeof(month));
 		utf8_tmp = gaim_utf8_try_convert(title);
 		strncpy(title, utf8_tmp, sizeof(title));
 		g_free(utf8_tmp);
-		
+
 		if (strncmp(month, prev_top_month, sizeof(month)) != 0) {
 			/* top level */
 			gtk_tree_store_append(lv->treestore, &toplevel, NULL);
 			gtk_tree_store_set(lv->treestore, &toplevel, 0, month, 1, NULL, -1);
-			
+
 			/* sub */
 			gtk_tree_store_append(lv->treestore, &child, &toplevel);
 			gtk_tree_store_set(lv->treestore, &child, 0, title, 1, log, -1);
-			
+
 			strncpy(prev_top_month, month, sizeof(prev_top_month));
 		} else {
 			gtk_tree_store_append(lv->treestore, &child, &toplevel);
 			gtk_tree_store_set(lv->treestore, &child, 0, title, 1, log, -1);
 		}
-		   
+
 		logs = logs->next;
 	}
 }
@@ -276,12 +276,12 @@
 	g_hash_table_insert(log_viewers, ht, lv);
 
 	/* Window ***********/
-	lv->window = gtk_dialog_new_with_buttons(screenname, NULL, 0, 
+	lv->window = gtk_dialog_new_with_buttons(screenname, NULL, 0,
 					     GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
 	gtk_container_set_border_width (GTK_CONTAINER(lv->window), 6);
 	gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE);
 	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(lv->window)->vbox), 0);
-	g_signal_connect(G_OBJECT(lv->window), "response", 
+	g_signal_connect(G_OBJECT(lv->window), "response",
 					 G_CALLBACK(destroy_cb), ht);
 
 	hbox = gtk_hbox_new(FALSE, 6);
@@ -311,7 +311,7 @@
 	pane = gtk_hpaned_new();
 	gtk_container_set_border_width(GTK_CONTAINER(pane), 6);
 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), pane, TRUE, TRUE, 0);
-	
+
 	/* List *************/
 	sw = gtk_scrolled_window_new (NULL, NULL);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
@@ -343,7 +343,7 @@
 	gtk_container_add(GTK_CONTAINER(sw), lv->imhtml);
 	gaim_setup_imhtml(lv->imhtml);
 	gtk_widget_set_size_request(lv->imhtml, 320, 200);
-		
+
 	/* Search box **********/
 	hbox = gtk_hbox_new(FALSE, 6);
 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
@@ -392,12 +392,12 @@
 	syslog_viewer->logs = g_list_sort(syslog_viewer->logs, gaim_log_compare);
 
 	/* Window ***********/
-	syslog_viewer->window = gtk_dialog_new_with_buttons(_("System Log"), NULL, 0, 
+	syslog_viewer->window = gtk_dialog_new_with_buttons(_("System Log"), NULL, 0,
 						 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
 	gtk_container_set_border_width (GTK_CONTAINER(syslog_viewer->window), 6);
 	gtk_dialog_set_has_separator(GTK_DIALOG(syslog_viewer->window), FALSE);
 	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(syslog_viewer->window)->vbox), 0);
-	g_signal_connect(G_OBJECT(syslog_viewer->window), "response", 
+	g_signal_connect(G_OBJECT(syslog_viewer->window), "response",
 					 G_CALLBACK(destroy_cb), NULL);
 
 	hbox = gtk_hbox_new(FALSE, 6);
@@ -418,7 +418,7 @@
 	gtk_container_set_border_width(GTK_CONTAINER(pane), 6);
 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(syslog_viewer->window)->vbox), pane,
 					   TRUE, TRUE, 0);
-	
+
 	/* List *************/
 	sw = gtk_scrolled_window_new (NULL, NULL);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
@@ -470,5 +470,5 @@
 			  syslog_viewer);
 	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
 
-	gtk_widget_show_all(syslog_viewer->window);	
+	gtk_widget_show_all(syslog_viewer->window);
 }
--- a/src/gtkutils.c	Sat Nov 13 16:17:41 2004 +0000
+++ b/src/gtkutils.c	Sun Nov 14 01:52:25 2004 +0000
@@ -53,6 +53,7 @@
 #include "gtkconv.h"
 #include "gtkdialogs.h"
 #include "gtkimhtml.h"
+#include "gtkimhtmltoolbar.h"
 #include "gtkutils.h"
 
 guint accels_save_timer = 0;
@@ -94,6 +95,75 @@
 	gtk_imhtml_set_funcs(GTK_IMHTML(imhtml), &gtkimhtml_cbs);
 }
 
+GtkWidget *
+gaim_gtk_create_imhtml(gboolean editable, GtkWidget **imhtml_ret, GtkWidget **toolbar_ret)
+{
+	GtkWidget *frame;
+	GtkWidget *imhtml;
+	GtkWidget *sep;
+	GtkWidget *sw;
+	GtkWidget *toolbar;
+	GtkWidget *vbox;
+
+	frame = gtk_frame_new(NULL);
+	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+	gtk_widget_show(frame);
+
+	vbox = gtk_vbox_new(FALSE, 0);
+	gtk_container_add(GTK_CONTAINER(frame), vbox);
+	gtk_widget_show(vbox);
+
+	if (editable) {
+		toolbar = gtk_imhtmltoolbar_new();
+		gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
+		gtk_widget_show(toolbar);
+
+		sep = gtk_hseparator_new();
+		gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
+		gtk_widget_show(sep);
+	}
+
+	/*
+	 * We never show the horizontal scrollbar in editable imhtmls becuase
+	 * it was causing weird lockups when typing text just as you type the
+	 * character that would cause both scrollbars to appear.  Definitely
+	 * seems like a gtk bug to me.
+	 */
+	sw = gtk_scrolled_window_new(NULL, NULL);
+	if (editable)
+		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+									   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+	else
+		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+									   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+	gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
+	gtk_widget_show(sw);
+
+	imhtml = gtk_imhtml_new(NULL, NULL);
+	gtk_imhtml_set_editable(GTK_IMHTML(imhtml), editable);
+	gtk_imhtml_set_format_functions(GTK_IMHTML(imhtml), GTK_IMHTML_ALL ^ GTK_IMHTML_IMAGE);
+	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(imhtml), GTK_WRAP_WORD_CHAR);
+	if (editable && gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck"))
+		gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(imhtml));
+	gtk_widget_show(imhtml);
+
+	if (editable) {
+		gtk_imhtmltoolbar_attach(GTK_IMHTMLTOOLBAR(toolbar), imhtml);
+		gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(toolbar), "default");
+	}
+	gaim_setup_imhtml(imhtml);
+
+	gtk_container_add(GTK_CONTAINER(sw), imhtml);
+
+	if (imhtml_ret != NULL)
+		*imhtml_ret = imhtml;
+
+	if (toolbar_ret != NULL)
+		*toolbar_ret = toolbar;
+
+	return frame;
+}
+
 void
 toggle_sensitive(GtkWidget *widget, GtkWidget *to_toggle)
 {
@@ -137,7 +207,7 @@
 
 		sensitivity = GTK_WIDGET_IS_SENSITIVE(element);
 
-		gtk_widget_set_sensitive(element, !sensitivity);	
+		gtk_widget_set_sensitive(element, !sensitivity);
 	}
 }
 
--- a/src/gtkutils.h	Sat Nov 13 16:17:41 2004 +0000
+++ b/src/gtkutils.h	Sun Nov 14 01:52:25 2004 +0000
@@ -67,6 +67,24 @@
 void gaim_setup_imhtml(GtkWidget *imhtml);
 
 /**
+ * Create an GtkIMHtml widget and associated GtkIMHtmlToolbar widget.  This
+ * functions puts both widgets in a nice GtkFrame.  They're separate by an
+ * attractive GtkSeparator.
+ *
+ * @param editable TRUE if this imhtml should be editable.  If this is FALSE,
+ *        then the toolbar will NOT be created.  If this imthml should be
+ *        read-only at first, but may become editable later, then pass in
+ *        TRUE here and then manually call gtk_imhtml_set_editable() later.
+ * @param imhtml_ret A pointer to a pointer to a GtkWidget.  This pointer
+ *        will be set to the imhtml when this function exits.
+ * @param toolbar_ret A pointer to a pointer to a GtkWidget.  If editable is
+ *        TRUE then this will be set to the toolbar when this function exits.
+ *        Otherwise this will be set to NULL.
+ * @return The GtkFrame containing the toolbar and imhtml.
+ */
+GtkWidget *gaim_gtk_create_imhtml(gboolean editable, GtkWidget **imhtml_ret, GtkWidget **toolbar_ret);
+
+/**
  * Toggles the sensitivity of a widget.
  *
  * @param widget    @c NULL. Used for signal handlers.