⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gntentry.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <ctype.h>#include <string.h>#include "gntbox.h"#include "gntentry.h"#include "gntstyle.h"#include "gnttree.h"#include "gntutils.h"enum{	SIG_TEXT_CHANGED,	SIGS,};static guint signals[SIGS] = { 0 };static GntWidgetClass *parent_class = NULL;static gboolean gnt_entry_key_pressed(GntWidget *widget, const char *text);static void gnt_entry_set_text_internal(GntEntry *entry, const char *text);static voiddestroy_suggest(GntEntry *entry){	if (entry->ddown)	{		gnt_widget_destroy(entry->ddown->parent);		entry->ddown = NULL;	}}static char *get_beginning_of_word(GntEntry *entry){	char *s = entry->cursor;	while (s > entry->start)	{		char *t = g_utf8_find_prev_char(entry->start, s);		if (isspace(*t))			break;		s = t;	}	return s;}static gbooleancomplete_suggest(GntEntry *entry, const char *text){	gboolean changed = FALSE;	if (entry->word) {		char *s = get_beginning_of_word(entry);		const char *iter = text;		while (*iter && toupper(*s) == toupper(*iter)) {			if (*s != *iter)				changed = TRUE;			*s++ = *iter++;		}		if (*iter) {			gnt_entry_key_pressed(GNT_WIDGET(entry), iter);			changed = TRUE;		}	} else {		gnt_entry_set_text_internal(entry, text);		changed = TRUE;	}	return changed;}static gbooleanshow_suggest_dropdown(GntEntry *entry){	char *suggest = NULL;	int len;	int offset = 0, x, y;	int count = 0;	GList *iter;	const char *text = NULL;	const char *sgst = NULL;	if (entry->word)	{		char *s = get_beginning_of_word(entry);		suggest = g_strndup(s, entry->cursor - s);		if (entry->scroll < s)			offset = gnt_util_onscreen_width(entry->scroll, s);	}	else		suggest = g_strdup(entry->start);	len = strlen(suggest);  /* Don't need to use the utf8-function here */		if (entry->ddown == NULL)	{		GntWidget *box = gnt_vbox_new(FALSE);		entry->ddown = gnt_tree_new();		gnt_tree_set_compare_func(GNT_TREE(entry->ddown), (GCompareFunc)g_utf8_collate);		gnt_box_add_widget(GNT_BOX(box), entry->ddown);		/* XXX: Connect to the "activate" signal for the dropdown tree */		GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT);		gnt_widget_get_position(GNT_WIDGET(entry), &x, &y);		x += offset;		y++;		if (y + 10 >= getmaxy(stdscr))			y -= 11;		gnt_widget_set_position(box, x, y);	}	else		gnt_tree_remove_all(GNT_TREE(entry->ddown));	for (count = 0, iter = entry->suggests; iter; iter = iter->next)	{		text = iter->data;		if (g_ascii_strncasecmp(suggest, text, len) == 0 && strlen(text) >= len)		{			gnt_tree_add_row_after(GNT_TREE(entry->ddown), (gpointer)text,					gnt_tree_create_row(GNT_TREE(entry->ddown), text),					NULL, NULL);			count++;			sgst = text;		}	}	g_free(suggest);	if (count == 0) {		destroy_suggest(entry);		return FALSE;	} else if (count == 1) {		destroy_suggest(entry);		return complete_suggest(entry, sgst);	} else {		gnt_widget_draw(entry->ddown->parent);	}	return TRUE;}static voidgnt_entry_draw(GntWidget *widget){	GntEntry *entry = GNT_ENTRY(widget);	int stop;	gboolean focus;	if ((focus = gnt_widget_has_focus(widget)))		wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TEXT_NORMAL));	else		wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));	if (entry->masked)	{		mvwhline(widget->window, 0, 0, gnt_ascii_only() ? '*' : ACS_BULLET,				g_utf8_pointer_to_offset(entry->scroll, entry->end));	}	else		mvwprintw(widget->window, 0, 0, "%s", entry->scroll);	stop = gnt_util_onscreen_width(entry->scroll, entry->end);	if (stop < widget->priv.width)		whline(widget->window, ENTRY_CHAR, widget->priv.width - stop);	if (focus)		mvwchgat(widget->window, 0, gnt_util_onscreen_width(entry->scroll, entry->cursor),				1, A_REVERSE, GNT_COLOR_TEXT_NORMAL, NULL);	GNTDEBUG;}static voidgnt_entry_size_request(GntWidget *widget){	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))	{		widget->priv.height = 1;		widget->priv.width = 20;	}}static voidgnt_entry_map(GntWidget *widget){	if (widget->priv.width == 0 || widget->priv.height == 0)		gnt_widget_size_request(widget);	GNTDEBUG;}static voidentry_redraw(GntWidget *widget){	gnt_entry_draw(widget);	gnt_widget_queue_update(widget);}static voidentry_text_changed(GntEntry *entry){	g_signal_emit(entry, signals[SIG_TEXT_CHANGED], 0);}static gbooleanmove_back(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->cursor <= entry->start)		return FALSE;	entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor);	if (entry->cursor < entry->scroll)		entry->scroll = entry->cursor;	entry_redraw(GNT_WIDGET(entry));	return TRUE;}static gbooleanmove_forward(GntBindable *bind, GList *list){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->cursor >= entry->end)		return FALSE;	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);	entry_redraw(GNT_WIDGET(entry));	return TRUE;}static gbooleanbackspace(GntBindable *bind, GList *null){	int len;	GntEntry *entry = GNT_ENTRY(bind);	if (entry->cursor <= entry->start)		return TRUE;		len = entry->cursor - g_utf8_find_prev_char(entry->start, entry->cursor);	entry->cursor -= len;	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor);	entry->end -= len;	if (entry->scroll > entry->start)		entry->scroll = g_utf8_find_prev_char(entry->start, entry->scroll);	entry_redraw(GNT_WIDGET(entry));	if (entry->ddown)		show_suggest_dropdown(entry);	entry_text_changed(entry);	return TRUE;}static gbooleandelkey(GntBindable *bind, GList *null){	int len;	GntEntry *entry = GNT_ENTRY(bind);	if (entry->cursor >= entry->end)		return FALSE;		len = g_utf8_find_next_char(entry->cursor, NULL) - entry->cursor;	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor - len + 1);	entry->end -= len;	entry_redraw(GNT_WIDGET(entry));	if (entry->ddown)		show_suggest_dropdown(entry);	entry_text_changed(entry);	return TRUE;}static gbooleanmove_start(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	entry->scroll = entry->cursor = entry->start;	entry_redraw(GNT_WIDGET(entry));	return TRUE;}static gbooleanmove_end(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	entry->cursor = entry->end;	/* This should be better than this */	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));	return TRUE;}static gbooleanhistory_prev(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->histlength && entry->history->prev)	{		entry->history = entry->history->prev;		gnt_entry_set_text_internal(entry, entry->history->data);		destroy_suggest(entry);		entry_text_changed(entry);		return TRUE;	}	return FALSE;}static gbooleanhistory_next(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->histlength && entry->history->next)	{		if (entry->history->prev == NULL)		{			/* Save the current contents */			char *text = g_strdup(gnt_entry_get_text(entry));			g_free(entry->history->data);			entry->history->data = text;		}		entry->history = entry->history->next;		gnt_entry_set_text_internal(entry, entry->history->data);		destroy_suggest(entry);		entry_text_changed(entry);		return TRUE;	}	return FALSE;}static gbooleanclipboard_paste(GntBindable *bind, GList *n){	GntEntry *entry = GNT_ENTRY(bind);	gchar *i, *text, *a, *all;	text = i = gnt_get_clipboard_string();	while (*i != '\0') {		i = g_utf8_next_char(i);		if (*i == '\r' || *i == '\n')			*i = ' ';	}	a = g_strndup(entry->start, entry->cursor - entry->start);	all = g_strconcat(a, text, entry->cursor, NULL);	gnt_entry_set_text_internal(entry, all);	g_free(a);	g_free(text);	g_free(all);	return TRUE;}static gbooleansuggest_show(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->ddown) {		gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down");		return TRUE;	}	return show_suggest_dropdown(entry);}static gbooleansuggest_next(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->ddown) {		gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down", NULL);		return TRUE;	}	return FALSE;}static gbooleansuggest_prev(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->ddown) {		gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-up", NULL);		return TRUE;	}	return FALSE;}static gbooleandel_to_home(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->cursor <= entry->start)		return TRUE;	memmove(entry->start, entry->cursor, entry->end - entry->cursor);	entry->end -= (entry->cursor - entry->start);	entry->cursor = entry->scroll = entry->start;	memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));	entry_redraw(GNT_WIDGET(bind));	entry_text_changed(entry);	return TRUE;}static gbooleandel_to_end(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	if (entry->end <= entry->cursor)		return TRUE;	entry->end = entry->cursor;	memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));	entry_redraw(GNT_WIDGET(bind));	entry_text_changed(entry);	return TRUE;}#define SAME(a,b)    ((g_unichar_isalpha(a) && g_unichar_isalpha(b)) || \				(g_unichar_isdigit(a) && g_unichar_isdigit(b)) || \				(g_unichar_isspace(a) && g_unichar_isspace(b)) || \				(g_unichar_iswide(a) && g_unichar_iswide(b)))static const char *begin_word(const char *text, const char *begin){	gunichar ch = 0;	while (text > begin && (!*text || g_unichar_isspace(g_utf8_get_char(text))))		text = g_utf8_find_prev_char(begin, text);	ch = g_utf8_get_char(text);	while ((text = g_utf8_find_prev_char(begin, text)) >= begin) {		gunichar cur = g_utf8_get_char(text);		if (!SAME(ch, cur))			break;	}	return (text ? g_utf8_find_next_char(text, NULL) : begin);}static const char *next_begin_word(const char *text, const char *end){	gunichar ch = 0;	ch = g_utf8_get_char(text);	while ((text = g_utf8_find_next_char(text, end)) != NULL && text <= end) {		gunichar cur = g_utf8_get_char(text);		if (!SAME(ch, cur))			break;	}	while (text && text < end && g_unichar_isspace(g_utf8_get_char(text)))		text = g_utf8_find_next_char(text, end);	return (text ? text : end);}#undef SAMEstatic gbooleanmove_back_word(GntBindable *bind, GList *null){	GntEntry *entry = GNT_ENTRY(bind);	const char *iter = g_utf8_find_prev_char(entry->start, entry->cursor);	if (iter < entry->start)		return TRUE;	iter = begin_word(iter, entry->start);	entry->cursor = (char*)iter;	if (entry->cursor < entry->scroll)		entry->scroll = entry->cursor;	entry_redraw(GNT_WIDGET(bind));	return TRUE;}static gbooleandel_prev_word(GntBindable *bind, GList *null){	GntWidget *widget = GNT_WIDGET(bind);	GntEntry *entry = GNT_ENTRY(bind);	char *iter = g_utf8_find_prev_char(entry->start, entry->cursor);	int count;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -