propagate from branch 'im.pidgin.pidgin.next.minor' (head b8585094b11781ed1e381d6dc2f94dabe94d1db3) cpw.resiak.disconnectreason

Sat, 27 Oct 2007 17:46:04 +0000

author
Will Thompson <resiak@pidgin.im>
date
Sat, 27 Oct 2007 17:46:04 +0000
branch
cpw.resiak.disconnectreason
changeset 21291
f80d343da336
parent 21290
24f3a8fa27c1 (current diff)
parent 21256
b8585094b117 (diff)
child 21293
760804f7b7da

propagate from branch 'im.pidgin.pidgin.next.minor' (head b8585094b11781ed1e381d6dc2f94dabe94d1db3)
to branch 'im.pidgin.cpw.resiak.disconnectreason' (head 24f3a8fa27c1970234b90074d16c185ce3e85327)

ChangeLog.API file | annotate | diff | comparison | revisions
--- a/ChangeLog	Sat Oct 27 17:45:05 2007 +0000
+++ b/ChangeLog	Sat Oct 27 17:46:04 2007 +0000
@@ -22,6 +22,9 @@
 	  could lead to crashes.
 	* It's possible to bind key-strokes to specific menuitems in the windows.
 	  Read the 'Menus' section in the man-page for details.
+	* 'transpose-chars' operation for the entry boxes. The default key-binding
+	  is ctrl+t.
+	* 'yank' operation for the entry boxes. The default binding is ctrl+y.
 
 version 2.2.2:
 	http://developer.pidgin.im/query?status=closed&milestone=2.2.2
--- a/ChangeLog.API	Sat Oct 27 17:45:05 2007 +0000
+++ b/ChangeLog.API	Sat Oct 27 17:46:04 2007 +0000
@@ -4,7 +4,7 @@
 	libpurple:
 		Added:
 		* purple_request_field_blist_nodes_new and its accessory functions.
-		* a PurpleConversation field in PurpleConvMessage
+		* a PurpleConversation field and an alias field in PurpleConvMessage
 		* account-authorization signals (see account-signals.dox for
 		  details) (Stefan Ott)
 		* libpurple/purple.h, which includes #define's and #include's
@@ -133,6 +133,7 @@
 		  given id from a menu.
 		* Added gnt_menuitem_activate, which triggers the 'activate' signal on
 		  the menuitem and calls the callback function, if available.
+		* Added GntEntryKillRing in GntEntry.
 
 version 2.2.2 (??/??/????):
 	libpurple:
--- a/finch/libgnt/gntentry.c	Sat Oct 27 17:45:05 2007 +0000
+++ b/finch/libgnt/gntentry.c	Sat Oct 27 17:46:04 2007 +0000
@@ -36,6 +36,24 @@
 	SIG_COMPLETION,
 	SIGS,
 };
+
+typedef enum
+{
+	ENTRY_JAIL = -1,    /* Suspend the kill ring. */
+	ENTRY_DEL_BWD_WORD = 1,
+	ENTRY_DEL_BWD_CHAR,
+	ENTRY_DEL_FWD_WORD,
+	ENTRY_DEL_FWD_CHAR,
+	ENTRY_DEL_EOL,
+	ENTRY_DEL_BOL,
+} GntEntryAction;
+
+struct _GntEntryKillRing
+{
+	GString *buffer;
+	GntEntryAction last;
+};
+
 static guint signals[SIGS] = { 0 };
 
 static GntWidgetClass *parent_class = NULL;
@@ -43,6 +61,58 @@
 static gboolean gnt_entry_key_pressed(GntWidget *widget, const char *text);
 static void gnt_entry_set_text_internal(GntEntry *entry, const char *text);
 
+static gboolean
+update_kill_ring(GntEntry *entry, GntEntryAction action, const char *text, int len)
+{
+	if (action < 0) {
+		entry->killring->last = action;
+		return FALSE;
+	}
+
+	if (len == 0)
+		len = strlen(text);
+	else if (len < 0) {
+		text += len;
+		len = -len;
+	}
+
+	if (action != entry->killring->last) {
+		struct {
+			GntEntryAction one;
+			GntEntryAction two;
+		} merges[] = {
+			{ENTRY_DEL_BWD_WORD, ENTRY_DEL_FWD_WORD},
+			{ENTRY_DEL_BWD_CHAR, ENTRY_DEL_FWD_CHAR},
+			{ENTRY_DEL_BOL, ENTRY_DEL_EOL},
+			{ENTRY_JAIL, ENTRY_JAIL},
+		};
+		int i;
+
+		for (i = 0; merges[i].one != ENTRY_JAIL; i++) {
+			if (merges[i].one == entry->killring->last &&
+					merges[i].two == action) {
+				g_string_append_len(entry->killring->buffer, text, len);
+				break;
+			} else if (merges[i].one == action &&
+					merges[i].two == entry->killring->last) {
+				g_string_prepend_len(entry->killring->buffer, text, len);
+				break;
+			}
+		}
+		if (merges[i].one == ENTRY_JAIL) {
+			g_string_assign(entry->killring->buffer, text);
+			g_string_truncate(entry->killring->buffer, len);
+		}
+		entry->killring->last = action;
+	} else {
+		if (action == ENTRY_DEL_BWD_CHAR || action == ENTRY_DEL_BWD_WORD)
+			g_string_prepend_len(entry->killring->buffer, text, len);
+		else
+			g_string_append_len(entry->killring->buffer, text, len);
+	}
+	return TRUE;
+}
+
 static void
 destroy_suggest(GntEntry *entry)
 {
@@ -97,6 +167,7 @@
 	if (changed)
 		g_signal_emit(G_OBJECT(entry), signals[SIG_COMPLETION], 0,
 				entry->start + offstart, entry->start + offend);
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 	return changed;
 }
 
@@ -264,6 +335,7 @@
 	entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor);
 	if (entry->cursor < entry->scroll)
 		entry->scroll = entry->cursor;
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 	entry_redraw(GNT_WIDGET(entry));
 	return TRUE;
 }
@@ -277,6 +349,7 @@
 	entry->cursor = g_utf8_find_next_char(entry->cursor, NULL);
 	while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width)
 		entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 	entry_redraw(GNT_WIDGET(entry));
 	return TRUE;
 }
@@ -289,9 +362,11 @@
 
 	if (entry->cursor <= entry->start)
 		return TRUE;
-	
+
 	len = entry->cursor - g_utf8_find_prev_char(entry->start, entry->cursor);
+	update_kill_ring(entry, ENTRY_DEL_BWD_CHAR, entry->cursor, -len);
 	entry->cursor -= len;
+
 	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor);
 	entry->end -= len;
 
@@ -313,8 +388,9 @@
 
 	if (entry->cursor >= entry->end)
 		return FALSE;
-	
+
 	len = g_utf8_find_next_char(entry->cursor, NULL) - entry->cursor;
+	update_kill_ring(entry, ENTRY_DEL_FWD_CHAR, entry->cursor, len);
 	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor - len + 1);
 	entry->end -= len;
 	entry_redraw(GNT_WIDGET(entry));
@@ -331,6 +407,7 @@
 	GntEntry *entry = GNT_ENTRY(bind);
 	entry->scroll = entry->cursor = entry->start;
 	entry_redraw(GNT_WIDGET(entry));
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 	return TRUE;
 }
 
@@ -343,6 +420,7 @@
 	while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width)
 		entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
 	entry_redraw(GNT_WIDGET(entry));
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 	return TRUE;
 }
 
@@ -357,6 +435,7 @@
 		destroy_suggest(entry);
 		entry_text_changed(entry);
 
+		update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 		return TRUE;
 	}
 	return FALSE;
@@ -381,6 +460,7 @@
 		destroy_suggest(entry);
 		entry_text_changed(entry);
 
+		update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 		return TRUE;
 	}
 	return FALSE;
@@ -400,6 +480,7 @@
 	a = g_strndup(entry->start, entry->cursor - entry->start);
 	all = g_strconcat(a, text, entry->cursor, NULL);
 	gnt_entry_set_text_internal(entry, all);
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 	g_free(a);
 	g_free(text);
 	g_free(all);
@@ -445,6 +526,7 @@
 	GntEntry *entry = GNT_ENTRY(bind);
 	if (entry->cursor <= entry->start)
 		return TRUE;
+	update_kill_ring(entry, ENTRY_DEL_BOL, entry->start, entry->cursor - entry->start);
 	memmove(entry->start, entry->cursor, entry->end - entry->cursor);
 	entry->end -= (entry->cursor - entry->start);
 	entry->cursor = entry->scroll = entry->start;
@@ -460,6 +542,7 @@
 	GntEntry *entry = GNT_ENTRY(bind);
 	if (entry->end <= entry->cursor)
 		return TRUE;
+	update_kill_ring(entry, ENTRY_DEL_EOL, entry->cursor, entry->end - entry->cursor);
 	entry->end = entry->cursor;
 	memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
 	entry_redraw(GNT_WIDGET(bind));
@@ -517,6 +600,7 @@
 	entry->cursor = (char*)iter;
 	if (entry->cursor < entry->scroll)
 		entry->scroll = entry->cursor;
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 	entry_redraw(GNT_WIDGET(bind));
 	return TRUE;
 }
@@ -533,6 +617,7 @@
 		return TRUE;
 	iter = (char*)begin_word(iter, entry->start);
 	count = entry->cursor - iter;
+	update_kill_ring(entry, ENTRY_DEL_BWD_WORD, iter, count);
 	memmove(iter, entry->cursor, entry->end - entry->cursor);
 	entry->end -= count;
 	entry->cursor = iter;
@@ -557,6 +642,7 @@
 	while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= widget->priv.width) {
 		entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
 	}
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 	entry_redraw(widget);
 	return TRUE;
 }
@@ -570,6 +656,7 @@
 	int len = entry->end - iter + 1;
 	if (len <= 0)
 		return TRUE;
+	update_kill_ring(entry, ENTRY_DEL_FWD_WORD, entry->cursor, iter - entry->cursor);
 	memmove(entry->cursor, iter, len);
 	len = iter - entry->cursor;
 	entry->end -= len;
@@ -580,6 +667,42 @@
 }
 
 static gboolean
+transpose_chars(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	char *current, *prev;
+	char hold[8];  /* that's right */
+
+	if (entry->cursor <= entry->start)
+		return FALSE;
+
+	if (!*entry->cursor)
+		entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor);
+
+	current = entry->cursor;
+	prev = g_utf8_find_prev_char(entry->start, entry->cursor);
+	move_forward(bind, null);
+
+	/* Let's do this dance! */
+	memcpy(hold, prev, current - prev);
+	memmove(prev, current, entry->cursor - current);
+	memcpy(prev + (entry->cursor - current), hold, current - prev);
+
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
+	entry_redraw(GNT_WIDGET(entry));
+	entry_text_changed(entry);
+	return TRUE;
+}
+
+static gboolean
+entry_yank(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	gnt_entry_key_pressed(GNT_WIDGET(entry), entry->killring->buffer->str);
+	return TRUE;
+}
+
+static gboolean
 gnt_entry_key_pressed(GntWidget *widget, const char *text)
 {
 	GntEntry *entry = GNT_ENTRY(widget);
@@ -602,6 +725,7 @@
 			destroy_suggest(entry);
 			complete_suggest(entry, text);
 			g_free(text);
+			update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 			entry_text_changed(entry);
 			return TRUE;
 		}
@@ -658,6 +782,7 @@
 				if (entry->ddown)
 					show_suggest_dropdown(entry);
 			}
+			update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
 			entry_redraw(widget);
 			entry_text_changed(entry);
 			return TRUE;
@@ -668,6 +793,13 @@
 }
 
 static void
+jail_killring(GntEntryKillRing *kr)
+{
+	g_string_free(kr->buffer, TRUE);
+	g_free(kr);
+}
+
+static void
 gnt_entry_destroy(GntWidget *widget)
 {
 	GntEntry *entry = GNT_ENTRY(widget);
@@ -690,6 +822,8 @@
 	{
 		gnt_widget_destroy(entry->ddown->parent);
 	}
+
+	jail_killring(entry->killring);
 }
 
 static void
@@ -762,6 +896,10 @@
 				"\033" "f", NULL);
 	gnt_bindable_class_register_action(bindable, "delete-next-word", delete_forward_word,
 				"\033" "d", NULL);
+	gnt_bindable_class_register_action(bindable, "transpose-chars", transpose_chars,
+				GNT_KEY_CTRL_T, NULL);
+	gnt_bindable_class_register_action(bindable, "yank", entry_yank,
+				GNT_KEY_CTRL_Y, NULL);
 	gnt_bindable_class_register_action(bindable, "suggest-show", suggest_show,
 				"\t", NULL);
 	gnt_bindable_class_register_action(bindable, "suggest-next", suggest_next,
@@ -779,6 +917,14 @@
 	GNTDEBUG;
 }
 
+static GntEntryKillRing *
+new_killring()
+{
+	GntEntryKillRing *kr = g_new0(GntEntryKillRing, 1);
+	kr->buffer = g_string_new(NULL);
+	return kr;
+}
+
 static void
 gnt_entry_init(GTypeInstance *instance, gpointer class)
 {
@@ -787,13 +933,14 @@
 
 	entry->flag = GNT_ENTRY_FLAG_ALL;
 	entry->max = 0;
-	
+
 	entry->histlength = 0;
 	entry->history = NULL;
 
 	entry->word = TRUE;
 	entry->always = FALSE;
 	entry->suggests = NULL;
+	entry->killring = new_killring();
 
 	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry),
 			GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS);
@@ -801,7 +948,7 @@
 
 	widget->priv.minw = 3;
 	widget->priv.minh = 1;
-	
+
 	GNTDEBUG;
 }
 
@@ -992,7 +1139,7 @@
 
 	if (!text || !*text)
 		return;
-	
+
 	find = g_list_find_custom(entry->suggests, text, (GCompareFunc)g_utf8_collate);
 	if (find)
 		return;
--- a/finch/libgnt/gntentry.h	Sat Oct 27 17:45:05 2007 +0000
+++ b/finch/libgnt/gntentry.h	Sat Oct 27 17:46:04 2007 +0000
@@ -48,6 +48,7 @@
 typedef struct _GntEntry			GntEntry;
 typedef struct _GntEntryPriv		GntEntryPriv;
 typedef struct _GntEntryClass	GntEntryClass;
+typedef struct _GntEntryKillRing    GntEntryKillRing;
 
 typedef enum
 {
@@ -71,9 +72,9 @@
 	char *scroll;   /* Current scrolling position */
 	char *cursor;   /* Cursor location */
 	                /* 0 <= cursor - scroll < widget-width */
-	
+
 	size_t buffer;  /* Size of the buffer */
-	
+
 	int max;        /* 0 means infinite */
 	gboolean masked;
 
@@ -84,6 +85,7 @@
 	gboolean word;      /* Are the suggestions for only a word, or for the whole thing? */
 	gboolean always;    /* Should the list of suggestions show at all times, or only on tab-press? */
 	GntWidget *ddown;   /* The dropdown with the suggested list */
+	GntEntryKillRing *killring; /**< @since 2.3.0 */
 };
 
 struct _GntEntryClass
--- a/finch/libgnt/gnttree.c	Sat Oct 27 17:45:05 2007 +0000
+++ b/finch/libgnt/gnttree.c	Sat Oct 27 17:46:04 2007 +0000
@@ -455,9 +455,10 @@
 		}
 		if (pos)
 		{
-			tree_mark_columns(tree, pos, 0, ACS_TTEE | gnt_color_pair(GNT_COLOR_NORMAL));
+			tree_mark_columns(tree, pos, 0,
+					(tree->show_separator ? ACS_TTEE : ACS_HLINE) | gnt_color_pair(GNT_COLOR_NORMAL));
 			tree_mark_columns(tree, pos, widget->priv.height - pos,
-					ACS_BTEE | gnt_color_pair(GNT_COLOR_NORMAL));
+					(tree->show_separator ? ACS_BTEE : ACS_HLINE) | gnt_color_pair(GNT_COLOR_NORMAL));
 		}
 		tree_mark_columns(tree, pos, pos + 1,
 			(tree->show_separator ? ACS_PLUS : ACS_HLINE) | gnt_color_pair(GNT_COLOR_NORMAL));
--- a/libpurple/conversation.c	Sat Oct 27 17:45:05 2007 +0000
+++ b/libpurple/conversation.c	Sat Oct 27 17:46:04 2007 +0000
@@ -205,8 +205,8 @@
 /* Functions that deal with PurpleConvMessage */
 
 static void
-add_message_to_history(PurpleConversation *conv, const char *who, const char *message,
-		PurpleMessageFlags flags, time_t when)
+add_message_to_history(PurpleConversation *conv, const char *who, const char *alias,
+		const char *message, PurpleMessageFlags flags, time_t when)
 {
 	PurpleConvMessage *msg;
 
@@ -218,10 +218,11 @@
 			me = conv->account->username;
 		who = me;
 	}
-	
+
 	msg = g_new0(PurpleConvMessage, 1);
 	PURPLE_DBUS_REGISTER_POINTER(msg, PurpleConvMessage);
 	msg->who = g_strdup(who);
+	msg->alias = g_strdup(alias);
 	msg->flags = flags;
 	msg->what = g_strdup(message);
 	msg->when = when;
@@ -234,6 +235,7 @@
 free_conv_message(PurpleConvMessage *msg)
 {
 	g_free(msg->who);
+	g_free(msg->alias);
 	g_free(msg->what);
 	PURPLE_DBUS_UNREGISTER_POINTER(msg);
 	g_free(msg);
@@ -293,14 +295,10 @@
 	/* Check if this conversation already exists. */
 	if ((conv = purple_find_conversation_with_account(type, name, account)) != NULL)
 	{
-		if (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT ||
-		    purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)))
-		{
-			if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
-				purple_conversation_chat_cleanup_for_rejoin(conv);
-
-			return conv;
-		}
+		if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
+				purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)))
+			purple_conversation_chat_cleanup_for_rejoin(conv);
+		return conv;
 	}
 
 	gc = purple_account_get_connection(account);
@@ -934,7 +932,8 @@
 
 	if (ops && ops->write_conv)
 		ops->write_conv(conv, who, alias, displayed, flags, mtime);
-	add_message_to_history(conv, who, message, flags, mtime);
+
+	add_message_to_history(conv, who, alias, message, flags, mtime);
 
 	purple_signal_emit(purple_conversations_get_handle(),
 		(type == PURPLE_CONV_TYPE_IM ? "wrote-im-msg" : "wrote-chat-msg"),
--- a/libpurple/conversation.h	Sat Oct 27 17:45:05 2007 +0000
+++ b/libpurple/conversation.h	Sat Oct 27 17:46:04 2007 +0000
@@ -294,7 +294,8 @@
 	char *what;
 	PurpleMessageFlags flags;
 	time_t when;
-	PurpleConversation *conv;
+	PurpleConversation *conv;  /**< @since 2.3.0 */
+	char *alias;               /**< @since 2.3.0 */
 };
 
 /**
--- a/pidgin/gtkconv.c	Sat Oct 27 17:45:05 2007 +0000
+++ b/pidgin/gtkconv.c	Sat Oct 27 17:46:04 2007 +0000
@@ -7435,7 +7435,7 @@
 			gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0);
 			g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);
 		}
-		pidgin_conv_write_conv(msg->conv, msg->who, msg->who, msg->what, msg->flags, msg->when);
+		pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when);
 		if (im) {
 			gtkconv->attach.current = g_list_delete_link(gtkconv->attach.current, gtkconv->attach.current);
 		} else {
@@ -7465,7 +7465,7 @@
 		msgs = g_list_sort(msgs, message_compare);
 		for (; msgs; msgs = g_list_delete_link(msgs, msgs)) {
 			PurpleConvMessage *msg = msgs->data;
-			pidgin_conv_write_conv(msg->conv, msg->who, msg->who, msg->what, msg->flags, msg->when);
+			pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when);
 		}
 		gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0);
 		g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);

mercurial