im.pidgin.pidgin.next.minor: a6e1d13e8af0e00ac47c87b5e118bb3c7ed5064f
sadrul at pidgin.im
sadrul at pidgin.im
Fri Oct 26 11:40:45 EDT 2007
-----------------------------------------------------------------
Revision: a6e1d13e8af0e00ac47c87b5e118bb3c7ed5064f
Ancestor: 38a2141cecd959a12818cbd101c479413892741d
Author: sadrul at pidgin.im
Date: 2007-10-26T13:31:26
Branch: im.pidgin.pidgin.next.minor
Modified files:
ChangeLog ChangeLog.API finch/libgnt/gntentry.c
finch/libgnt/gntentry.h
ChangeLog:
Add 'yank' action in the entry boxes.
-------------- next part --------------
============================================================
--- ChangeLog 65b10c2fc34dd5273a016ae78611482343dccf9a
+++ ChangeLog d8097a92790fd650d17d788c401b48c91dc12bdc
@@ -24,6 +24,7 @@ version 2.3.0:
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
============================================================
--- ChangeLog.API 632b61fb302854c6a896c0bceffb6b21cedcb525
+++ ChangeLog.API ff40c2de429ca1a2eaf2a2a49afb89a94c5a07bb
@@ -108,6 +108,7 @@ version 2.3.0 (??/??/????):
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:
============================================================
--- finch/libgnt/gntentry.c 46a955aee57e3162256268b4b3bf5cfd6ca7a6d0
+++ finch/libgnt/gntentry.c 26c1533be747e0aa30cf530f9ecd50154142474b
@@ -36,6 +36,24 @@ enum
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 void gnt_entry_set_text_internal(
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 @@ complete_suggest(GntEntry *entry, const
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 @@ move_back(GntBindable *bind, GList *null
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 @@ move_forward(GntBindable *bind, GList *l
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 @@ backspace(GntBindable *bind, GList *null
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 @@ delkey(GntBindable *bind, GList *null)
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 @@ move_start(GntBindable *bind, GList *nul
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 @@ move_end(GntBindable *bind, GList *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);
entry_redraw(GNT_WIDGET(entry));
+ update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
return TRUE;
}
@@ -357,6 +435,7 @@ history_prev(GntBindable *bind, GList *n
destroy_suggest(entry);
entry_text_changed(entry);
+ update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
return TRUE;
}
return FALSE;
@@ -381,6 +460,7 @@ history_next(GntBindable *bind, GList *n
destroy_suggest(entry);
entry_text_changed(entry);
+ update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
return TRUE;
}
return FALSE;
@@ -400,6 +480,7 @@ clipboard_paste(GntBindable *bind, GList
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 @@ del_to_home(GntBindable *bind, GList *nu
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 @@ del_to_end(GntBindable *bind, GList *nul
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 @@ move_back_word(GntBindable *bind, GList
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 @@ del_prev_word(GntBindable *bind, GList *
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 @@ move_forward_word(GntBindable *bind, GLi
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 @@ delete_forward_word(GntBindable *bind, G
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;
@@ -601,12 +688,21 @@ transpose_chars(GntBindable *bind, GList
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);
@@ -629,6 +725,7 @@ gnt_entry_key_pressed(GntWidget *widget,
destroy_suggest(entry);
complete_suggest(entry, text);
g_free(text);
+ update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
entry_text_changed(entry);
return TRUE;
}
@@ -685,6 +782,7 @@ gnt_entry_key_pressed(GntWidget *widget,
if (entry->ddown)
show_suggest_dropdown(entry);
}
+ update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
entry_redraw(widget);
entry_text_changed(entry);
return TRUE;
@@ -695,6 +793,13 @@ static void
}
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);
@@ -717,6 +822,8 @@ gnt_entry_destroy(GntWidget *widget)
{
gnt_widget_destroy(entry->ddown->parent);
}
+
+ jail_killring(entry->killring);
}
static void
@@ -791,6 +898,8 @@ gnt_entry_class_init(GntEntryClass *klas
"\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,
@@ -808,6 +917,14 @@ gnt_entry_class_init(GntEntryClass *klas
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)
{
@@ -816,13 +933,14 @@ gnt_entry_init(GTypeInstance *instance,
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);
@@ -830,7 +948,7 @@ gnt_entry_init(GTypeInstance *instance,
widget->priv.minw = 3;
widget->priv.minh = 1;
-
+
GNTDEBUG;
}
@@ -1021,7 +1139,7 @@ void gnt_entry_add_suggest(GntEntry *ent
if (!text || !*text)
return;
-
+
find = g_list_find_custom(entry->suggests, text, (GCompareFunc)g_utf8_collate);
if (find)
return;
============================================================
--- finch/libgnt/gntentry.h 15a838de46a2fe83c482899079bbbad5cf86e956
+++ finch/libgnt/gntentry.h 4be38f89219eec94a088a7993c20eafaf2ae46ae
@@ -48,6 +48,7 @@ typedef struct _GntEntryClass GntEntryCl
typedef struct _GntEntry GntEntry;
typedef struct _GntEntryPriv GntEntryPriv;
typedef struct _GntEntryClass GntEntryClass;
+typedef struct _GntEntryKillRing GntEntryKillRing;
typedef enum
{
@@ -71,9 +72,9 @@ struct _GntEntry
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 @@ struct _GntEntry
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
More information about the Commits
mailing list