From: <sa...@us...> - 2006-12-18 19:41:46
|
Revision: 18020 http://svn.sourceforge.net/gaim/?rev=18020&view=rev Author: sadrul Date: 2006-12-18 11:41:38 -0800 (Mon, 18 Dec 2006) Log Message: ----------- text-changed signal for GntEntry. Not used anywhere yet, but will be in the future. Modified Paths: -------------- trunk/console/libgnt/gntentry.c trunk/console/libgnt/gntentry.h Modified: trunk/console/libgnt/gntentry.c =================================================================== --- trunk/console/libgnt/gntentry.c 2006-12-17 21:12:18 UTC (rev 18019) +++ trunk/console/libgnt/gntentry.c 2006-12-18 19:41:38 UTC (rev 18020) @@ -9,11 +9,15 @@ enum { - SIGS = 1, + SIG_TEXT_CHANGED, + SIGS, }; +static guint signals[SIGS] = { 0 }; static GntWidgetClass *parent_class = NULL; +static void gnt_entry_set_text_internal(GntEntry *entry, const char *text); + static void destroy_suggest(GntEntry *entry) { @@ -157,6 +161,12 @@ gnt_widget_queue_update(widget); } +static void +entry_text_changed(GntEntry *entry) +{ + g_signal_emit(entry, signals[SIG_TEXT_CHANGED], 0); +} + static gboolean move_back(GntBindable *bind, GList *null) { @@ -203,6 +213,7 @@ entry_redraw(GNT_WIDGET(entry)); if (entry->ddown) show_suggest_dropdown(entry); + entry_text_changed(entry); return TRUE; } @@ -222,6 +233,7 @@ if (entry->ddown) show_suggest_dropdown(entry); + entry_text_changed(entry); return TRUE; } @@ -253,8 +265,9 @@ if (entry->histlength && entry->history->prev) { entry->history = entry->history->prev; - gnt_entry_set_text(entry, entry->history->data); + gnt_entry_set_text_internal(entry, entry->history->data); destroy_suggest(entry); + entry_text_changed(entry); return TRUE; } @@ -276,8 +289,9 @@ } entry->history = entry->history->next; - gnt_entry_set_text(entry, entry->history->data); + gnt_entry_set_text_internal(entry, entry->history->data); destroy_suggest(entry); + entry_text_changed(entry); return TRUE; } @@ -316,11 +330,14 @@ del_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; } @@ -328,9 +345,12 @@ del_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; } @@ -410,6 +430,7 @@ } memset(entry->end, '\0', entry->buffer - (entry->end - entry->start)); entry_redraw(widget); + entry_text_changed(entry); return TRUE; } @@ -434,11 +455,14 @@ GntWidget *widget = GNT_WIDGET(bind); char *iter = (char *)next_begin_word(entry->cursor, entry->end); int len = entry->end - iter + 1; + if (len <= 0) + return TRUE; memmove(entry->cursor, iter, len); len = iter - entry->cursor; entry->end -= len; memset(entry->end, '\0', len); entry_redraw(widget); + entry_text_changed(entry); return TRUE; } @@ -484,9 +508,10 @@ } else { - gnt_entry_set_text(entry, text); + gnt_entry_set_text_internal(entry, text); } g_free(text); + entry_text_changed(entry); return TRUE; } @@ -519,7 +544,7 @@ { /* This will cause the buffer to grow */ char *tmp = g_strdup_printf("%s%*s", entry->start, len, ""); - gnt_entry_set_text(entry, tmp); + gnt_entry_set_text_internal(entry, tmp); g_free(tmp); } @@ -543,6 +568,7 @@ show_suggest_dropdown(entry); } entry_redraw(widget); + entry_text_changed(entry); return TRUE; } } @@ -597,6 +623,15 @@ parent_class->key_pressed = gnt_entry_key_pressed; parent_class->lost_focus = gnt_entry_lost_focus; + signals[SIG_TEXT_CHANGED] = + g_signal_new("text_changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntEntryClass, text_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gnt_bindable_class_register_action(bindable, "cursor-home", move_start, GNT_KEY_CTRL_A, NULL); gnt_bindable_register_binding(bindable, "cursor-home", GNT_KEY_HOME, NULL); @@ -703,12 +738,13 @@ GntWidget *widget = g_object_new(GNT_TYPE_ENTRY, NULL); GntEntry *entry = GNT_ENTRY(widget); - gnt_entry_set_text(entry, text); + gnt_entry_set_text_internal(entry, text); return widget; } -void gnt_entry_set_text(GntEntry *entry, const char *text) +static void +gnt_entry_set_text_internal(GntEntry *entry, const char *text) { int len; int scroll, cursor; @@ -741,6 +777,18 @@ entry_redraw(GNT_WIDGET(entry)); } +void gnt_entry_set_text(GntEntry *entry, const char *text) +{ + gboolean changed = TRUE; + if (text == NULL && entry->start == NULL) + changed = FALSE; + if (text && entry->start && g_utf8_collate(text, entry->start) == 0) + changed = FALSE; + gnt_entry_set_text_internal(entry, text); + if (changed) + entry_text_changed(entry); +} + void gnt_entry_set_max(GntEntry *entry, int max) { entry->max = max; @@ -759,10 +807,11 @@ void gnt_entry_clear(GntEntry *entry) { - gnt_entry_set_text(entry, NULL); + gnt_entry_set_text_internal(entry, NULL); entry->scroll = entry->cursor = entry->end = entry->start; entry_redraw(GNT_WIDGET(entry)); destroy_suggest(entry); + entry_text_changed(entry); } void gnt_entry_set_masked(GntEntry *entry, gboolean set) Modified: trunk/console/libgnt/gntentry.h =================================================================== --- trunk/console/libgnt/gntentry.h 2006-12-17 21:12:18 UTC (rev 18019) +++ trunk/console/libgnt/gntentry.h 2006-12-18 19:41:38 UTC (rev 18020) @@ -64,6 +64,7 @@ { GntWidgetClass parent; + void (*text_changed)(GntEntry *entry); void (*gnt_reserved1)(void); void (*gnt_reserved2)(void); void (*gnt_reserved3)(void); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2007-03-21 08:33:18
|
Revision: 18213 http://svn.sourceforge.net/gaim/?rev=18213&view=rev Author: sadrul Date: 2007-03-21 01:33:15 -0700 (Wed, 21 Mar 2007) Log Message: ----------- A file selector Modified Paths: -------------- trunk/console/libgnt/Makefile.am Added Paths: ----------- trunk/console/libgnt/gntfilesel.c trunk/console/libgnt/gntfilesel.h Modified: trunk/console/libgnt/Makefile.am =================================================================== --- trunk/console/libgnt/Makefile.am 2007-03-20 16:42:41 UTC (rev 18212) +++ trunk/console/libgnt/Makefile.am 2007-03-21 08:33:15 UTC (rev 18213) @@ -16,6 +16,7 @@ gntcolors.c \ gntcombobox.c \ gntentry.c \ + gntfilesel.c \ gntkeys.c \ gntlabel.c \ gntline.c \ @@ -39,6 +40,7 @@ gntcolors.h \ gntcombobox.h \ gntentry.h \ + gntfilesel.h \ gntkeys.h \ gntlabel.h \ gntline.h \ @@ -73,6 +75,7 @@ libgnt_la_LIBADD = \ $(GLIB_LIBS) \ $(GNT_LIBS) + AM_CPPFLAGS = \ $(GLIB_CFLAGS) \ Added: trunk/console/libgnt/gntfilesel.c =================================================================== --- trunk/console/libgnt/gntfilesel.c (rev 0) +++ trunk/console/libgnt/gntfilesel.c 2007-03-21 08:33:15 UTC (rev 18213) @@ -0,0 +1,397 @@ +#include "gntbutton.h" +#include "gntentry.h" +#include "gntfilesel.h" +#include "gntlabel.h" +#include "gntmarshal.h" +#include "gntstyle.h" +#include "gnttree.h" + +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <glob.h> + +enum +{ + SIG_FILE_SELECTED, + SIGS +}; + +static GntWindowClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; +static void (*orig_map)(GntWidget *widget); + +static void +gnt_file_sel_destroy(GntWidget *widget) +{ + GntFileSel *sel = GNT_FILE_SEL(widget); + g_free(sel->current); +} + +static char * +process_path(const char *path) +{ + char **splits = NULL; + int i, j; + char *str, *ret; + + splits = g_strsplit(path, G_DIR_SEPARATOR_S, -1); + for (i = 0, j = 0; splits[i]; i++) { + if (strcmp(splits[i], ".") == 0) { + } else if (strcmp(splits[i], "..") == 0) { + if (j) + j--; + } else { + if (i != j) { + g_free(splits[j]); + splits[j] = splits[i]; + splits[i] = NULL; + } + j++; + } + } + g_free(splits[j]); + splits[j] = NULL; + str = g_build_pathv(G_DIR_SEPARATOR_S, splits); + ret = g_strdup_printf(G_DIR_SEPARATOR_S "%s", str); + g_free(str); + g_strfreev(splits); + return ret; +} + +static void +update_location(GntFileSel *sel) +{ + char *old; + const char *tmp; + tmp = (const char*)gnt_tree_get_selection_data(sel->dirsonly ? GNT_TREE(sel->dirs) : GNT_TREE(sel->files)); + old = g_strdup_printf("%s%s%s", sel->current, sel->current[1] ? G_DIR_SEPARATOR_S : "", tmp ? tmp : ""); + gnt_entry_set_text(GNT_ENTRY(sel->location), old); + g_free(old); +} + +static gboolean +location_changed(GntFileSel *sel, GError **err) +{ + GDir *dir; + const char *str; + + if (!sel->dirs) + return TRUE; + + gnt_tree_remove_all(GNT_TREE(sel->dirs)); + if (sel->files) + gnt_tree_remove_all(GNT_TREE(sel->files)); + gnt_entry_set_text(GNT_ENTRY(sel->location), NULL); + if (sel->current == NULL) { + if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(sel), GNT_WIDGET_MAPPED)) + gnt_widget_draw(GNT_WIDGET(sel)); + return TRUE; + } + + dir = g_dir_open(sel->current, 0, err); + if (dir == NULL || *err) { + g_printerr("GntFileSel: error opening location %s (%s)\n", + sel->current, *err ? (*err)->message : "reason unknown"); + return FALSE; + } + + if (*sel->current != '\0' && strcmp(sel->current, G_DIR_SEPARATOR_S)) + gnt_tree_add_row_after(GNT_TREE(sel->dirs), g_strdup(".."), + gnt_tree_create_row(GNT_TREE(sel->dirs), ".."), NULL, NULL); + + while ((str = g_dir_read_name(dir)) != NULL) { + char *fp = g_build_filename(sel->current, str, NULL); + struct stat st; + + if (stat(fp, &st)) { + g_printerr("Error stating location %s\n", fp); + } else { + if (S_ISDIR(st.st_mode)) + gnt_tree_add_row_after(GNT_TREE(sel->dirs), g_strdup(str), + gnt_tree_create_row(GNT_TREE(sel->dirs), str), NULL, NULL); + else if (!sel->dirsonly) { + char size[128]; + snprintf(size, sizeof(size), "%ld", (long)st.st_size); + + gnt_tree_add_row_after(GNT_TREE(sel->files), g_strdup(str), + gnt_tree_create_row(GNT_TREE(sel->files), str, size, ""), NULL, NULL); + } + } + g_free(fp); + } + if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(sel), GNT_WIDGET_MAPPED)) + gnt_widget_draw(GNT_WIDGET(sel)); + return TRUE; +} + +static gboolean +dir_key_pressed(GntTree *tree, const char *key, GntFileSel *sel) +{ + if (strcmp(key, "\r") == 0) { + /* XXX: if we are moving up the tree, make sure the current node is selected after the redraw */ + char *str = g_strdup(gnt_tree_get_selection_data(tree)); + char *path = g_build_filename(sel->current, str, NULL); + char *dir = g_path_get_basename(sel->current); + if (!gnt_file_sel_set_current_location(sel, path)) { + gnt_tree_set_selected(tree, str); + } else if (strcmp(str, "..") == 0) { + gnt_tree_set_selected(tree, dir); + } + g_free(dir); + g_free(str); + g_free(path); + return TRUE; + } + return FALSE; +} + +static gboolean +location_key_pressed(GntTree *tree, const char *key, GntFileSel *sel) +{ + if (strcmp(key, "\r") == 0) { + int count; + glob_t gl; + char *path; + char *str; + struct stat st; + int glob_ret; + + str = (char*)gnt_entry_get_text(GNT_ENTRY(sel->location)); + if (*str == G_DIR_SEPARATOR) + path = g_strdup(str); + else + path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", sel->current, str); + str = process_path(path); + g_free(path); + path = str; + + if (!stat(path, &st)) { + if (S_ISDIR(st.st_mode)) { + gnt_file_sel_set_current_location(sel, path); + goto success; + } + } + + glob_ret = glob(path, GLOB_MARK, NULL, &gl); + if (!glob_ret) { /* XXX: do something with the return value */ + char *loc = g_path_get_dirname(gl.gl_pathv[0]); + + stat(gl.gl_pathv[0], &st); + gnt_file_sel_set_current_location(sel, loc); /* XXX: check the return value */ + g_free(loc); + if (!S_ISDIR(st.st_mode) && !sel->dirsonly) { + gnt_tree_remove_all(GNT_TREE(sel->files)); + for (count = 0; count < gl.gl_pathc; count++) { + char *tmp = process_path(gl.gl_pathv[count]); + loc = g_path_get_dirname(tmp); + if (g_utf8_collate(sel->current, loc) == 0) { + char *base = g_path_get_basename(tmp); + char size[128]; + snprintf(size, sizeof(size), "%ld", (long)st.st_size); + gnt_tree_add_row_after(GNT_TREE(sel->files), base, + gnt_tree_create_row(GNT_TREE(sel->files), base, size, ""), NULL, NULL); + } + g_free(loc); + g_free(tmp); + } + gnt_widget_draw(sel->files); + } + } else if (sel->files) { + gnt_tree_remove_all(GNT_TREE(sel->files)); + gnt_widget_draw(sel->files); + } + globfree(&gl); +success: + g_free(path); + return TRUE; + } + return FALSE; +} + +static void +file_sel_changed(GntWidget *widget, gpointer old, gpointer current, GntFileSel *sel) +{ + update_location(sel); +} + +static void +gnt_file_sel_map(GntWidget *widget) +{ + GntFileSel *sel = GNT_FILE_SEL(widget); + GntWidget *hbox, *vbox; + + vbox = gnt_vbox_new(FALSE); + gnt_box_set_pad(GNT_BOX(vbox), 0); + gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_LEFT); + + /* The dir. and files list */ + hbox = gnt_hbox_new(FALSE); + gnt_box_set_pad(GNT_BOX(hbox), 0); + + gnt_box_add_widget(GNT_BOX(hbox), sel->dirs); + + if (!sel->dirsonly) { + gnt_box_add_widget(GNT_BOX(hbox), sel->files); + } else { + g_signal_connect(G_OBJECT(sel->dirs), "selection_changed", G_CALLBACK(file_sel_changed), sel); + } + + gnt_box_add_widget(GNT_BOX(vbox), hbox); + gnt_box_add_widget(GNT_BOX(vbox), sel->location); + + /* The buttons */ + hbox = gnt_hbox_new(FALSE); + gnt_box_add_widget(GNT_BOX(hbox), sel->cancel); + gnt_box_add_widget(GNT_BOX(hbox), sel->select); + gnt_box_add_widget(GNT_BOX(vbox), hbox); + + gnt_box_add_widget(GNT_BOX(sel), vbox); + orig_map(widget); + update_location(sel); +} + +static void +gnt_file_sel_class_init(GntFileSelClass *klass) +{ + GntWidgetClass *kl = GNT_WIDGET_CLASS(klass); + parent_class = GNT_WINDOW_CLASS(klass); + kl->destroy = gnt_file_sel_destroy; + orig_map = kl->map; + kl->map = gnt_file_sel_map; + + signals[SIG_FILE_SELECTED] = + g_signal_new("file_selected", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntFileSelClass, file_selected), + NULL, NULL, + gnt_closure_marshal_VOID__STRING_STRING, + G_TYPE_NONE, 0); + gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); + + GNTDEBUG; +} + +static void +gnt_file_sel_init(GTypeInstance *instance, gpointer class) +{ + GNTDEBUG; +} + +/****************************************************************************** + * GntFileSel API + *****************************************************************************/ +GType +gnt_file_sel_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntFileSelClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_file_sel_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntFileSel), + 0, /* n_preallocs */ + gnt_file_sel_init, /* instance_init */ + NULL + }; + + type = g_type_register_static(GNT_TYPE_WINDOW, + "GntFileSel", + &info, 0); + } + + return type; +} + +GntWidget *gnt_file_sel_new() +{ + GntWidget *widget = g_object_new(GNT_TYPE_FILE_SEL, NULL); + GntFileSel *sel = GNT_FILE_SEL(widget); + + sel->dirs = gnt_tree_new(); + gnt_tree_set_compare_func(GNT_TREE(sel->dirs), (GCompareFunc)g_utf8_collate); + gnt_tree_set_hash_fns(GNT_TREE(sel->dirs), g_str_hash, g_str_equal, g_free); + gnt_tree_set_column_titles(GNT_TREE(sel->dirs), "Directories"); + gnt_tree_set_show_title(GNT_TREE(sel->dirs), TRUE); + gnt_tree_set_col_width(GNT_TREE(sel->dirs), 0, 20); + g_signal_connect(G_OBJECT(sel->dirs), "key_pressed", G_CALLBACK(dir_key_pressed), sel); + + sel->files = gnt_tree_new_with_columns(2); /* Name, Size */ + gnt_tree_set_compare_func(GNT_TREE(sel->files), (GCompareFunc)g_utf8_collate); + gnt_tree_set_column_titles(GNT_TREE(sel->files), "Filename", "Size"); + gnt_tree_set_show_title(GNT_TREE(sel->files), TRUE); + gnt_tree_set_col_width(GNT_TREE(sel->files), 0, 25); + gnt_tree_set_col_width(GNT_TREE(sel->files), 1, 10); + g_signal_connect(G_OBJECT(sel->files), "selection_changed", G_CALLBACK(file_sel_changed), sel); + + /* The location entry */ + sel->location = gnt_entry_new(NULL); + g_signal_connect(G_OBJECT(sel->location), "key_pressed", G_CALLBACK(location_key_pressed), sel); + + sel->cancel = gnt_button_new("Cancel"); + sel->select = gnt_button_new("Select"); + + return widget; +} + +gboolean gnt_file_sel_set_current_location(GntFileSel *sel, const char *path) +{ + char *old; + GError *error = NULL; + gboolean ret = TRUE; + + old = sel->current; + sel->current = process_path(path); + if (!location_changed(sel, &error)) { + g_error_free(error); + error = NULL; + g_free(sel->current); + sel->current = old; + location_changed(sel, &error); + ret = FALSE; + } else + g_free(old); + + update_location(sel); + return ret; +} + +void gnt_file_sel_set_dirs_only(GntFileSel *sel, gboolean dirs) +{ + sel->dirsonly = dirs; +} + +gboolean gnt_file_sel_get_dirs_only(GntFileSel *sel) +{ + return sel->dirsonly; +} + +char *gnt_file_sel_get_selected_file(GntFileSel *sel) +{ + char *ret; + const char *tmp; + tmp = (const char*)gnt_tree_get_selection_data(sel->dirsonly ? GNT_TREE(sel->dirs) : GNT_TREE(sel->files)); + ret = g_strdup_printf("%s%s%s", sel->current, sel->current[1] ? G_DIR_SEPARATOR_S : "", tmp ? tmp : ""); + return ret; +} + +void gnt_file_sel_set_must_exist(GntFileSel *sel, gboolean must) +{ + /*XXX: What do I do with this? */ + sel->must_exist = must; +} + +gboolean gnt_file_sel_get_must_exist(GntFileSel *sel) +{ + return sel->must_exist; +} + Property changes on: trunk/console/libgnt/gntfilesel.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: trunk/console/libgnt/gntfilesel.h =================================================================== --- trunk/console/libgnt/gntfilesel.h (rev 0) +++ trunk/console/libgnt/gntfilesel.h 2007-03-21 08:33:15 UTC (rev 18213) @@ -0,0 +1,74 @@ +#ifndef GNT_FILE_SEL_H +#define GNT_FILE_SEL_H + +#include "gntwindow.h" +#include "gnt.h" +#include "gntcolors.h" +#include "gntkeys.h" + +#define GNT_TYPE_FILE_SEL (gnt_file_sel_get_gtype()) +#define GNT_FILE_SEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_FILE_SEL, GntFileSel)) +#define GNT_FILE_SEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_FILE_SEL, GntFileSelClass)) +#define GNT_IS_FILE_SEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_FILE_SEL)) +#define GNT_IS_FILE_SEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_FILE_SEL)) +#define GNT_FILE_SEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_FILE_SEL, GntFileSelClass)) + +#define GNT_FILE_SEL_FLAGS(obj) (GNT_FILE_SEL(obj)->priv.flags) +#define GNT_FILE_SEL_SET_FLAGS(obj, flags) (GNT_FILE_SEL_FLAGS(obj) |= flags) +#define GNT_FILE_SEL_UNSET_FLAGS(obj, flags) (GNT_FILE_SEL_FLAGS(obj) &= ~(flags)) + +typedef struct _GnFileSel GntFileSel; +typedef struct _GnFileSelPriv GntFileSelPriv; +typedef struct _GnFileSelClass GntFileSelClass; + +struct _GnFileSel +{ + GntWindow parent; + + GntWidget *dirs; /* list of files */ + GntWidget *files; /* list of directories */ + GntWidget *location; /* location entry */ + + GntWidget *select; /* select button */ + GntWidget *cancel; /* cancel button */ + + char *current; /* Full path of the current location */ + /* XXX: someone should make these useful */ + gboolean must_exist; /* Make sure the selected file (the name entered in 'location') exists */ + gboolean dirsonly; /* Show only directories */ +}; + +struct _GnFileSelClass +{ + GntWindowClass parent; + + void (*file_selected)(GntFileSel *sel, const char *path, const char *filename); + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_file_sel_get_gtype(void); + +GntWidget *gnt_file_sel_new(); + +gboolean gnt_file_sel_set_current_location(GntFileSel *sel, const char *path); + +const char *gnt_file_sel_get_current_location(GntFileSel *sel); + +void gnt_file_sel_set_dirs_only(GntFileSel *sel, gboolean dirs); + +gboolean gnt_file_sel_get_dirs_only(GntFileSel *sel); + +void gnt_file_sel_set_must_exist(GntFileSel *sel, gboolean must); + +gboolean gnt_file_sel_get_must_exist(GntFileSel *sel); + +char *gnt_file_sel_get_selected_file(GntFileSel *sel); /* The returned value should be free'd */ + +G_END_DECLS + +#endif /* GNT_FILE_SEL_H */ Property changes on: trunk/console/libgnt/gntfilesel.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2007-03-30 05:49:43
|
Revision: 18220 http://svn.sourceforge.net/gaim/?rev=18220&view=rev Author: sadrul Date: 2007-03-29 22:49:39 -0700 (Thu, 29 Mar 2007) Log Message: ----------- A lot of stuff. Some memory leaks, some bug fixes, some new features. Pretty much everything you could want in a commit. Modified Paths: -------------- trunk/console/libgnt/Makefile.am trunk/console/libgnt/gnt-skel.h trunk/console/libgnt/gnt.h trunk/console/libgnt/gnt.pc.in trunk/console/libgnt/gntbindable.c trunk/console/libgnt/gntbindable.h trunk/console/libgnt/gntbox.c trunk/console/libgnt/gntbox.h trunk/console/libgnt/gntbutton.c trunk/console/libgnt/gntbutton.h trunk/console/libgnt/gntcheckbox.c trunk/console/libgnt/gntcheckbox.h trunk/console/libgnt/gntcolors.c trunk/console/libgnt/gntcolors.h trunk/console/libgnt/gntcombobox.c trunk/console/libgnt/gntcombobox.h trunk/console/libgnt/gntentry.c trunk/console/libgnt/gntentry.h trunk/console/libgnt/gntfilesel.c trunk/console/libgnt/gntfilesel.h trunk/console/libgnt/gntkeys.c trunk/console/libgnt/gntkeys.h trunk/console/libgnt/gntlabel.c trunk/console/libgnt/gntlabel.h trunk/console/libgnt/gntline.c trunk/console/libgnt/gntline.h trunk/console/libgnt/gntmain.c trunk/console/libgnt/gntmenu.c trunk/console/libgnt/gntmenu.h trunk/console/libgnt/gntmenuitem.c trunk/console/libgnt/gntmenuitem.h trunk/console/libgnt/gntmenuitemcheck.c trunk/console/libgnt/gntmenuitemcheck.h trunk/console/libgnt/gntstyle.c trunk/console/libgnt/gntstyle.h trunk/console/libgnt/gnttextview.c trunk/console/libgnt/gnttextview.h trunk/console/libgnt/gnttree.c trunk/console/libgnt/gnttree.h trunk/console/libgnt/gntwidget.c trunk/console/libgnt/gntwidget.h trunk/console/libgnt/gntwindow.c trunk/console/libgnt/gntwindow.h trunk/console/libgnt/gntwm.c trunk/console/libgnt/gntwm.h trunk/console/libgnt/test/key.c trunk/console/libgnt/test/menu.c trunk/console/libgnt/test/tv.c Added Paths: ----------- trunk/console/libgnt/gntclipboard.c trunk/console/libgnt/gntclipboard.h Modified: trunk/console/libgnt/Makefile.am =================================================================== --- trunk/console/libgnt/Makefile.am 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/Makefile.am 2007-03-30 05:49:39 UTC (rev 18220) @@ -13,6 +13,7 @@ gntbox.c \ gntbutton.c \ gntcheckbox.c \ + gntclipboard.c \ gntcolors.c \ gntcombobox.c \ gntentry.c \ @@ -37,6 +38,7 @@ gntbox.h \ gntbutton.h \ gntcheckbox.h \ + gntclipboard.h \ gntcolors.h \ gntcombobox.h \ gntentry.h \ @@ -61,7 +63,8 @@ gntmarshal.c gntmarshal.c: genmarshal gntmarshal.h - cat genmarshal | glib-genmarshal --prefix=gnt_closure_marshal --body > $@ + echo "#include \"gntmarshal.h\"" > $@ + cat genmarshal | glib-genmarshal --prefix=gnt_closure_marshal --body >> $@ gntmarshal.h: genmarshal cat genmarshal | glib-genmarshal --prefix=gnt_closure_marshal --header > $@ @@ -75,8 +78,8 @@ libgnt_la_LIBADD = \ $(GLIB_LIBS) \ $(GNT_LIBS) - AM_CPPFLAGS = \ $(GLIB_CFLAGS) \ - $(GNT_CFLAGS) + $(GNT_CFLAGS) \ + $(DEBUG_CFLAGS) Modified: trunk/console/libgnt/gnt-skel.h =================================================================== --- trunk/console/libgnt/gnt-skel.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gnt-skel.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -17,16 +17,16 @@ #define GNT_SKEL_SET_FLAGS(obj, flags) (GNT_SKEL_FLAGS(obj) |= flags) #define GNT_SKEL_UNSET_FLAGS(obj, flags) (GNT_SKEL_FLAGS(obj) &= ~(flags)) -typedef struct _GnSkel GntSkel; -typedef struct _GnSkelPriv GntSkelPriv; -typedef struct _GnSkelClass GntSkelClass; +typedef struct _GntSkel GntSkel; +typedef struct _GntSkelPriv GntSkelPriv; +typedef struct _GntSkelClass GntSkelClass; -struct _GnSkel +struct _GntSkel { GntWidget parent; }; -struct _GnSkelClass +struct _GntSkelClass { GntWidgetClass parent; Modified: trunk/console/libgnt/gnt.h =================================================================== --- trunk/console/libgnt/gnt.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gnt.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -1,13 +1,14 @@ #include <glib.h> #include "gntwidget.h" +#include "gntclipboard.h" #include "gntcolors.h" #include "gntkeys.h" -void gnt_init(); +void gnt_init(void); -void gnt_main(); +void gnt_main(void); -gboolean gnt_ascii_only(); +gboolean gnt_ascii_only(void); void gnt_screen_occupy(GntWidget *widget); @@ -15,8 +16,6 @@ void gnt_screen_update(GntWidget *widget); -void gnt_screen_take_focus(GntWidget *widget); - void gnt_screen_resize_widget(GntWidget *widget, int width, int height); void gnt_screen_move_widget(GntWidget *widget, int x, int y); @@ -31,5 +30,10 @@ gboolean gnt_screen_menu_show(gpointer menu); -void gnt_quit(); +void gnt_quit(void); +GntClipboard *gnt_get_clipboard(void); + +gchar *gnt_get_clipboard_string(void); + +void gnt_set_clipboard_string(gchar *string); Modified: trunk/console/libgnt/gnt.pc.in =================================================================== --- trunk/console/libgnt/gnt.pc.in 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gnt.pc.in 2007-03-30 05:49:39 UTC (rev 18220) @@ -2,11 +2,12 @@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ +datarootdir=@datarootdir@ datadir=@datadir@ sysconfdir=@sysconfdir@ Name: LibGNT -Description: Gaim Ncurses Toolkit is a collection of curses-widgets. +Description: Glib Ncurses Toolkit is a collection of curses-widgets. Version: @VERSION@ Requires: glib-2.0 Cflags: -I${includedir}/gnt Modified: trunk/console/libgnt/gntbindable.c =================================================================== --- trunk/console/libgnt/gntbindable.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntbindable.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -77,6 +77,7 @@ sizeof(GntBindable), 0, /* n_preallocs */ NULL, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(G_TYPE_OBJECT, @@ -155,6 +156,7 @@ if (name == NULL || *name == '\0') { g_hash_table_remove(klass->bindings, (char*)trigger); + gnt_keys_del_combination(trigger); return; } @@ -171,6 +173,7 @@ param->action = action; param->list = list; g_hash_table_replace(klass->bindings, g_strdup(trigger), param); + gnt_keys_add_combination(trigger); } void gnt_bindable_register_binding(GntBindableClass *klass, const char *name, Modified: trunk/console/libgnt/gntbindable.h =================================================================== --- trunk/console/libgnt/gntbindable.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntbindable.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -13,17 +13,17 @@ #define GNT_IS_BINDABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BINDABLE)) #define GNT_BINDABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BINDABLE, GntBindableClass)) -#define GNTDEBUG fprintf(stderr, "%s\n", __FUNCTION__) +#define GNTDEBUG g_printerr("%s\n", __FUNCTION__) -typedef struct _GnBindable GntBindable; -typedef struct _GnBindableClass GntBindableClass; +typedef struct _GntBindable GntBindable; +typedef struct _GntBindableClass GntBindableClass; -struct _GnBindable +struct _GntBindable { GObject inherit; }; -struct _GnBindableClass +struct _GntBindableClass { GObjectClass parent; @@ -52,10 +52,10 @@ typedef gboolean (*GntBindableActionCallback) (GntBindable *bindable, GList *params); typedef gboolean (*GntBindableActionCallbackNoParam)(GntBindable *bindable); -typedef struct _GnBindableAction GntBindableAction; -typedef struct _GnBindableActionParam GntBindableActionParam; +typedef struct _GntBindableAction GntBindableAction; +typedef struct _GntBindableActionParam GntBindableActionParam; -struct _GnBindableAction +struct _GntBindableAction { char *name; /* The name of the action */ union { @@ -64,7 +64,7 @@ } u; }; -struct _GnBindableActionParam +struct _GntBindableActionParam { GntBindableAction *action; GList *list; Modified: trunk/console/libgnt/gntbox.c =================================================================== --- trunk/console/libgnt/gntbox.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntbox.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -62,7 +62,7 @@ else wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE_D)); mvwaddch(widget->window, 0, pos-1, ACS_RTEE | COLOR_PAIR(GNT_COLOR_NORMAL)); - mvwprintw(widget->window, 0, pos, title); + mvwaddstr(widget->window, 0, pos, title); mvwaddch(widget->window, 0, right, ACS_LTEE | COLOR_PAIR(GNT_COLOR_NORMAL)); g_free(title); } @@ -352,11 +352,6 @@ GntBox *box = GNT_BOX(widget); int wchange, hchange; - if (widget->priv.width != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X)) - return FALSE; - if (widget->priv.height != height && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y)) - return FALSE; - if (!box->list) return TRUE; @@ -387,13 +382,21 @@ gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th); if (box->vertical) { - if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) - return FALSE; + if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) { + /* If we are decreasing the size and the widget is going + * to be too large to fit into the box, then do not allow + * resizing. */ + if (wchange > 0 && tw >= widget->priv.width) + return FALSE; + } } else { - if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) + if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) { + if (hchange > 0 && th >= widget->priv.height) + return FALSE; return FALSE; + } } } #if 0 @@ -535,6 +538,7 @@ sizeof(GntBox), 0, /* n_preallocs */ gnt_box_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_WIDGET, @@ -561,17 +565,6 @@ { b->list = g_list_append(b->list, widget); widget->parent = GNT_WIDGET(b); - - if (b->vertical) - { - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X)) - GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_X); - } - else - { - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y)) - GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_Y); - } } void gnt_box_set_title(GntBox *b, const char *title) Modified: trunk/console/libgnt/gntbox.h =================================================================== --- trunk/console/libgnt/gntbox.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntbox.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -11,8 +11,8 @@ #define GNT_IS_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BOX)) #define GNT_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BOX, GntBoxClass)) -typedef struct _GnBox GntBox; -typedef struct _GnBoxClass GntBoxClass; +typedef struct _GntBox GntBox; +typedef struct _GntBoxClass GntBoxClass; typedef enum { @@ -27,7 +27,7 @@ GNT_ALIGN_BOTTOM } GntAlignment; -struct _GnBox +struct _GntBox { GntWidget parent; @@ -49,7 +49,7 @@ void (*gnt_reserved4)(void); }; -struct _GnBoxClass +struct _GntBoxClass { GntWidgetClass parent; Modified: trunk/console/libgnt/gntbutton.c =================================================================== --- trunk/console/libgnt/gntbutton.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntbutton.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -22,7 +22,7 @@ type = GNT_COLOR_NORMAL; wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); - mvwprintw(widget->window, 1, 2, button->priv->text); + mvwaddstr(widget->window, 1, 2, button->priv->text); GNTDEBUG; } @@ -87,8 +87,6 @@ GntButton *button = GNT_BUTTON(instance); button->priv = g_new0(GntButtonPriv, 1); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X); - widget->priv.minw = 4; widget->priv.minh = 3; GNTDEBUG; @@ -112,6 +110,7 @@ sizeof(GntButton), 0, /* n_preallocs */ gnt_button_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_WIDGET, Modified: trunk/console/libgnt/gntbutton.h =================================================================== --- trunk/console/libgnt/gntbutton.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntbutton.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -13,16 +13,16 @@ #define GNT_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BUTTON)) #define GNT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BUTTON, GntButtonClass)) -typedef struct _GnButton GntButton; -typedef struct _GnButtonPriv GntButtonPriv; -typedef struct _GnButtonClass GntButtonClass; +typedef struct _GntButton GntButton; +typedef struct _GntButtonPriv GntButtonPriv; +typedef struct _GntButtonClass GntButtonClass; -struct _GnButtonPriv +struct _GntButtonPriv { char *text; }; -struct _GnButton +struct _GntButton { GntWidget parent; @@ -34,7 +34,7 @@ void (*gnt_reserved4)(void); }; -struct _GnButtonClass +struct _GntButtonClass { GntWidgetClass parent; Modified: trunk/console/libgnt/gntcheckbox.c =================================================================== --- trunk/console/libgnt/gntcheckbox.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntcheckbox.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -24,11 +24,11 @@ wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); text = g_strdup_printf("[%c]", cb->checked ? 'X' : ' '); - mvwprintw(widget->window, 0, 0, text); + mvwaddstr(widget->window, 0, 0, text); g_free(text); wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); - mvwprintw(widget->window, 0, 4, GNT_BUTTON(cb)->priv->text); + mvwaddstr(widget->window, 0, 4, GNT_BUTTON(cb)->priv->text); GNTDEBUG; } @@ -117,6 +117,7 @@ sizeof(GntCheckBox), 0, /* n_preallocs */ gnt_check_box_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_BUTTON, Modified: trunk/console/libgnt/gntcheckbox.h =================================================================== --- trunk/console/libgnt/gntcheckbox.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntcheckbox.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -17,17 +17,17 @@ #define GNT_CHECK_BOX_SET_FLAGS(obj, flags) (GNT_CHECK_BOX_FLAGS(obj) |= flags) #define GNT_CHECK_BOX_UNSET_FLAGS(obj, flags) (GNT_CHECK_BOX_FLAGS(obj) &= ~(flags)) -typedef struct _GnCheckBox GntCheckBox; -typedef struct _GnCheckBoxPriv GntCheckBoxPriv; -typedef struct _GnCheckBoxClass GntCheckBoxClass; +typedef struct _GntCheckBox GntCheckBox; +typedef struct _GntCheckBoxPriv GntCheckBoxPriv; +typedef struct _GntCheckBoxClass GntCheckBoxClass; -struct _GnCheckBox +struct _GntCheckBox { GntButton parent; gboolean checked; }; -struct _GnCheckBoxClass +struct _GntCheckBoxClass { GntButtonClass parent; Added: trunk/console/libgnt/gntclipboard.c =================================================================== --- trunk/console/libgnt/gntclipboard.c (rev 0) +++ trunk/console/libgnt/gntclipboard.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -0,0 +1,74 @@ +#include "gntclipboard.h" + +gchar *string; + +enum { + SIG_CLIPBOARD = 0, + SIGS +}; + +static guint signals[SIGS] = { 0 }; + +static void +gnt_clipboard_class_init(GntClipboardClass *klass) +{ + signals[SIG_CLIPBOARD] = + g_signal_new("clipboard_changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + +} + +/****************************************************************************** + * GntClipboard API + *****************************************************************************/ + +void +gnt_clipboard_set_string(GntClipboard *clipboard, gchar *string) +{ + g_free(clipboard->string); + clipboard->string = g_strdup(string); + g_signal_emit(clipboard, signals[SIG_CLIPBOARD], 0, clipboard->string); +} + +gchar * +gnt_clipboard_get_string(GntClipboard *clipboard) +{ + return g_strdup(clipboard->string); +} + +static void gnt_clipboard_init(GTypeInstance *instance, gpointer class) { + GntClipboard *clipboard = GNT_CLIPBOARD(instance); + clipboard->string = g_strdup(""); +} + +GType +gnt_clipboard_get_gtype(void) +{ + static GType type = 0; + + if (type == 0) { + static const GTypeInfo info = { + sizeof(GntClipboardClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_clipboard_class_init, + NULL, + NULL, /* class_data */ + sizeof(GntClipboard), + 0, /* n_preallocs */ + gnt_clipboard_init, /* instance_init */ + NULL /* value_table */ + }; + + type = g_type_register_static(G_TYPE_OBJECT, + "GntClipboard", + &info, 0); + } + + return type; +} Property changes on: trunk/console/libgnt/gntclipboard.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: trunk/console/libgnt/gntclipboard.h =================================================================== --- trunk/console/libgnt/gntclipboard.h (rev 0) +++ trunk/console/libgnt/gntclipboard.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -0,0 +1,46 @@ +#ifndef GNT_CLIPBOARD_H +#define GNT_CLIPBOARD_H + +#include <stdio.h> +#include <glib.h> +#include <glib-object.h> + +#define GNT_TYPE_CLIPBOARD (gnt_clipboard_get_gtype()) +#define GNT_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_CLIPBOARD, GntClipboard)) +#define GNT_CLIPBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_CLIPBOARD, GntClipboardClass)) +#define GNT_IS_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_CLIPBOARD)) +#define GNT_IS_CLIPBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_CLIPBOARD)) +#define GNT_CLIPBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_CLIPBOARD, GntClipboardClass)) + +#define GNTDEBUG g_printerr("%s\n", __FUNCTION__) + +typedef struct _GntClipboard GntClipboard; +typedef struct _GntClipboardClass GntClipboardClass; + +struct _GntClipboard +{ + GObject inherit; + gchar *string; +}; + +struct _GntClipboardClass +{ + GObjectClass parent; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_clipboard_get_gtype(void); + +gchar *gnt_clipboard_get_string(GntClipboard *clip); + +void gnt_clipboard_set_string(GntClipboard *clip, gchar *string); + +G_END_DECLS + +#endif Property changes on: trunk/console/libgnt/gntclipboard.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Modified: trunk/console/libgnt/gntcolors.c =================================================================== --- trunk/console/libgnt/gntcolors.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntcolors.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -161,7 +161,7 @@ while (nkeys--) { gsize len; - char *key = keys[nkeys]; + gchar *key = keys[nkeys]; char **list = g_key_file_get_string_list(kfile, "colors", key, &len, NULL); if (len == 3) { @@ -170,8 +170,9 @@ int b = atoi(list[2]); int color = -1; - g_ascii_strdown(key, -1); + key = g_ascii_strdown(key, -1); color = get_color(key); + g_free(key); if (color == -1) continue; @@ -204,17 +205,21 @@ while (nkeys--) { gsize len; - char *key = keys[nkeys]; + gchar *key = keys[nkeys]; char **list = g_key_file_get_string_list(kfile, "colorpairs", key, &len, NULL); if (len == 2) { GntColorType type = 0; - int fg = get_color(g_ascii_strdown(list[0], -1)); - int bg = get_color(g_ascii_strdown(list[1], -1)); + gchar *fgc = g_ascii_strdown(list[0], -1); + gchar *bgc = g_ascii_strdown(list[1], -1); + int fg = get_color(fgc); + int bg = get_color(bgc); + g_free(fgc); + g_free(bgc); if (fg == -1 || bg == -1) continue; - g_ascii_strdown(key, -1); + key = g_ascii_strdown(key, -1); if (strcmp(key, "normal") == 0) type = GNT_COLOR_NORMAL; @@ -234,8 +239,11 @@ type = GNT_COLOR_DISABLED; else if (strcmp(key, "urgent") == 0) type = GNT_COLOR_URGENT; - else + else { + g_free(key); continue; + } + g_free(key); init_pair(type, fg, bg); } Modified: trunk/console/libgnt/gntcolors.h =================================================================== --- trunk/console/libgnt/gntcolors.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntcolors.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -33,9 +33,9 @@ }; /* populate some default colors */ -void gnt_init_colors(); +void gnt_init_colors(void); -void gnt_uninit_colors(); +void gnt_uninit_colors(void); #if GLIB_CHECK_VERSION(2,6,0) void gnt_colors_parse(GKeyFile *kfile); Modified: trunk/console/libgnt/gntcombobox.c =================================================================== --- trunk/console/libgnt/gntcombobox.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntcombobox.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -33,6 +33,18 @@ } static void +hide_popup(GntComboBox *box, gboolean set) +{ + gnt_widget_set_size(box->dropdown, + box->dropdown->priv.width - 1, box->dropdown->priv.height); + if (set) + set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown))); + else + gnt_tree_set_selected(GNT_TREE(box->dropdown), box->selected); + gnt_widget_hide(box->dropdown->parent); +} + +static void gnt_combo_box_draw(GntWidget *widget) { GntComboBox *box = GNT_COMBO_BOX(widget); @@ -56,7 +68,7 @@ s = (char*)gnt_util_onscreen_width_to_pointer(text, widget->priv.width - 4, &len); *s = '\0'; - mvwprintw(widget->window, 1, 1, text); + mvwaddstr(widget->window, 1, 1, text); whline(widget->window, ' ' | COLOR_PAIR(type), widget->priv.width - 4 - len); mvwaddch(widget->window, 1, widget->priv.width - 3, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL)); mvwaddch(widget->window, 1, widget->priv.width - 2, ACS_DARROW | COLOR_PAIR(GNT_COLOR_NORMAL)); @@ -121,12 +133,11 @@ { case '\r': case '\t': - set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown))); + hide_popup(box, TRUE); + return TRUE; case 27: - gnt_tree_set_selected(GNT_TREE(box->dropdown), box->selected); - gnt_widget_hide(box->dropdown->parent); + hide_popup(box, FALSE); return TRUE; - break; } } if (gnt_widget_key_pressed(box->dropdown, text)) @@ -159,7 +170,7 @@ { GntComboBox *combo = GNT_COMBO_BOX(widget); if (GNT_WIDGET_IS_FLAG_SET(combo->dropdown->parent, GNT_WIDGET_MAPPED)) - gnt_widget_hide(GNT_COMBO_BOX(widget)->dropdown->parent); + hide_popup(combo, FALSE); widget_lost_focus(widget); } @@ -177,8 +188,7 @@ gnt_widget_key_pressed(box->dropdown, GNT_KEY_DOWN); } else if (event == GNT_LEFT_MOUSE_DOWN) { if (dshowing) { - set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown))); - gnt_widget_hide(box->dropdown->parent); + hide_popup(box, TRUE); } else { popup_dropdown(GNT_COMBO_BOX(widget)); } @@ -188,6 +198,13 @@ } static void +gnt_combo_box_size_changed(GntWidget *widget, int oldw, int oldh) +{ + GntComboBox *box = GNT_COMBO_BOX(widget); + gnt_widget_set_size(box->dropdown, widget->priv.width - 1, box->dropdown->priv.height); +} + +static void gnt_combo_box_class_init(GntComboBoxClass *klass) { parent_class = GNT_WIDGET_CLASS(klass); @@ -198,6 +215,7 @@ parent_class->size_request = gnt_combo_box_size_request; parent_class->key_pressed = gnt_combo_box_key_pressed; parent_class->clicked = gnt_combo_box_clicked; + parent_class->size_changed = gnt_combo_box_size_changed; widget_lost_focus = parent_class->lost_focus; parent_class->lost_focus = gnt_combo_box_lost_focus; @@ -255,6 +273,7 @@ sizeof(GntComboBox), 0, /* n_preallocs */ gnt_combo_box_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_WIDGET, Modified: trunk/console/libgnt/gntcombobox.h =================================================================== --- trunk/console/libgnt/gntcombobox.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntcombobox.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -17,11 +17,11 @@ #define GNT_COMBO_BOX_SET_FLAGS(obj, flags) (GNT_COMBO_BOX_FLAGS(obj) |= flags) #define GNT_COMBO_BOX_UNSET_FLAGS(obj, flags) (GNT_COMBO_BOX_FLAGS(obj) &= ~(flags)) -typedef struct _GnComboBox GntComboBox; -typedef struct _GnComboBoxPriv GntComboBoxPriv; -typedef struct _GnComboBoxClass GntComboBoxClass; +typedef struct _GntComboBox GntComboBox; +typedef struct _GntComboBoxPriv GntComboBoxPriv; +typedef struct _GntComboBoxClass GntComboBoxClass; -struct _GnComboBox +struct _GntComboBox { GntWidget parent; @@ -30,7 +30,7 @@ void *selected; /* Currently selected key */ }; -struct _GnComboBoxClass +struct _GntComboBoxClass { GntWidgetClass parent; @@ -44,7 +44,7 @@ GType gnt_combo_box_get_gtype(void); -GntWidget *gnt_combo_box_new(); +GntWidget *gnt_combo_box_new(void); void gnt_combo_box_add_data(GntComboBox *box, gpointer key, const char *text); Modified: trunk/console/libgnt/gntentry.c =================================================================== --- trunk/console/libgnt/gntentry.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntentry.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -16,6 +16,7 @@ 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 void @@ -299,9 +300,37 @@ } static gboolean +clipboard_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 gboolean suggest_show(GntBindable *bind, GList *null) { - return show_suggest_dropdown(GNT_ENTRY(bind)); + GntEntry *entry = GNT_ENTRY(bind); + if (entry->ddown) { + if (g_list_length(GNT_TREE(entry->ddown)->list) == 1) + gnt_entry_key_pressed(GNT_WIDGET(entry), "\r"); + else + gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down"); + return TRUE; + } + return show_suggest_dropdown(entry); } static gboolean @@ -543,7 +572,7 @@ if (entry->end + len - entry->start >= entry->buffer) { /* This will cause the buffer to grow */ - char *tmp = g_strdup_printf("%s%*s", entry->start, len, ""); + char *tmp = g_strdup(entry->start); gnt_entry_set_text_internal(entry, tmp); g_free(tmp); } @@ -673,6 +702,8 @@ GNT_KEY_CTRL_DOWN, NULL); gnt_bindable_class_register_action(bindable, "history-next", history_next, GNT_KEY_CTRL_UP, NULL); + gnt_bindable_class_register_action(bindable, "clipboard-paste", clipboard_paste, + GNT_KEY_CTRL_V, NULL); gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); GNTDEBUG; @@ -724,6 +755,7 @@ sizeof(GntEntry), 0, /* n_preallocs */ gnt_entry_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_WIDGET, Modified: trunk/console/libgnt/gntentry.h =================================================================== --- trunk/console/libgnt/gntentry.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntentry.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -19,9 +19,9 @@ #define ENTRY_CHAR '_' /* The character to use to fill in the blank places */ -typedef struct _GnEntry GntEntry; -typedef struct _GnEntryPriv GntEntryPriv; -typedef struct _GnEntryClass GntEntryClass; +typedef struct _GntEntry GntEntry; +typedef struct _GntEntryPriv GntEntryPriv; +typedef struct _GntEntryClass GntEntryClass; typedef enum { @@ -34,7 +34,7 @@ #define GNT_ENTRY_FLAG_ALL (GNT_ENTRY_FLAG_ALPHA | GNT_ENTRY_FLAG_INT) -struct _GnEntry +struct _GntEntry { GntWidget parent; @@ -60,7 +60,7 @@ GntWidget *ddown; /* The dropdown with the suggested list */ }; -struct _GnEntryClass +struct _GntEntryClass { GntWidgetClass parent; Modified: trunk/console/libgnt/gntfilesel.c =================================================================== --- trunk/console/libgnt/gntfilesel.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntfilesel.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -28,6 +28,11 @@ { GntFileSel *sel = GNT_FILE_SEL(widget); g_free(sel->current); + g_free(sel->suggest); + if (sel->tags) { + g_list_foreach(sel->tags, (GFunc)g_free, NULL); + g_list_free(sel->tags); + } } static char * @@ -66,13 +71,23 @@ { char *old; const char *tmp; - tmp = (const char*)gnt_tree_get_selection_data(sel->dirsonly ? GNT_TREE(sel->dirs) : GNT_TREE(sel->files)); + tmp = sel->suggest ? sel->suggest : + (const char*)gnt_tree_get_selection_data(sel->dirsonly ? GNT_TREE(sel->dirs) : GNT_TREE(sel->files)); old = g_strdup_printf("%s%s%s", sel->current, sel->current[1] ? G_DIR_SEPARATOR_S : "", tmp ? tmp : ""); gnt_entry_set_text(GNT_ENTRY(sel->location), old); g_free(old); } static gboolean +is_tagged(GntFileSel *sel, const char *f) +{ + char *ret = g_strdup_printf("%s%s%s", sel->current, sel->current[1] ? G_DIR_SEPARATOR_S : "", f); + gboolean find = g_list_find_custom(sel->tags, ret, (GCompareFunc)g_utf8_collate) != NULL; + g_free(ret); + return find; +} + +static gboolean location_changed(GntFileSel *sel, GError **err) { GDir *dir; @@ -109,15 +124,19 @@ if (stat(fp, &st)) { g_printerr("Error stating location %s\n", fp); } else { - if (S_ISDIR(st.st_mode)) + if (S_ISDIR(st.st_mode)) { gnt_tree_add_row_after(GNT_TREE(sel->dirs), g_strdup(str), gnt_tree_create_row(GNT_TREE(sel->dirs), str), NULL, NULL); - else if (!sel->dirsonly) { + if (sel->multiselect && sel->dirsonly && is_tagged(sel, str)) + gnt_tree_set_row_flags(GNT_TREE(sel->dirs), (gpointer)str, GNT_TEXT_FLAG_BOLD); + } else if (!sel->dirsonly) { char size[128]; snprintf(size, sizeof(size), "%ld", (long)st.st_size); gnt_tree_add_row_after(GNT_TREE(sel->files), g_strdup(str), gnt_tree_create_row(GNT_TREE(sel->files), str, size, ""), NULL, NULL); + if (sel->multiselect && is_tagged(sel, str)) + gnt_tree_set_row_flags(GNT_TREE(sel->files), (gpointer)str, GNT_TEXT_FLAG_BOLD); } } g_free(fp); @@ -131,7 +150,6 @@ dir_key_pressed(GntTree *tree, const char *key, GntFileSel *sel) { if (strcmp(key, "\r") == 0) { - /* XXX: if we are moving up the tree, make sure the current node is selected after the redraw */ char *str = g_strdup(gnt_tree_get_selection_data(tree)); char *path = g_build_filename(sel->current, str, NULL); char *dir = g_path_get_basename(sel->current); @@ -214,6 +232,8 @@ static void file_sel_changed(GntWidget *widget, gpointer old, gpointer current, GntFileSel *sel) { + g_free(sel->suggest); + sel->suggest = NULL; update_location(sel); } @@ -225,7 +245,7 @@ vbox = gnt_vbox_new(FALSE); gnt_box_set_pad(GNT_BOX(vbox), 0); - gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_LEFT); + gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_MID); /* The dir. and files list */ hbox = gnt_hbox_new(FALSE); @@ -253,9 +273,66 @@ update_location(sel); } +static gboolean +toggle_tag_selection(GntBindable *bind, GList *null) +{ + GntFileSel *sel = GNT_FILE_SEL(bind); + char *str; + GList *find; + char *file; + GntWidget *tree; + + if (!sel->multiselect) + return FALSE; + tree = sel->dirsonly ? sel->dirs : sel->files; + if (!gnt_widget_has_focus(tree)) + return FALSE; + + file = gnt_tree_get_selection_data(sel->dirsonly ? GNT_TREE(sel->dirs) : GNT_TREE(sel->files)); + + str = gnt_file_sel_get_selected_file(sel); + if ((find = g_list_find_custom(sel->tags, str, (GCompareFunc)g_utf8_collate)) != NULL) { + g_free(find->data); + sel->tags = g_list_delete_link(sel->tags, find); + gnt_tree_set_row_flags(GNT_TREE(tree), file, GNT_TEXT_FLAG_NORMAL); + g_free(str); + } else { + sel->tags = g_list_prepend(sel->tags, str); + gnt_tree_set_row_flags(GNT_TREE(tree), file, GNT_TEXT_FLAG_BOLD); + } + + gnt_bindable_perform_action_named(GNT_BINDABLE(tree), "move-down", NULL); + + return TRUE; +} + +static gboolean +clear_tags(GntBindable *bind, GList *null) +{ + GntFileSel *sel = GNT_FILE_SEL(bind); + GntWidget *tree; + GList *iter; + + if (!sel->multiselect) + return FALSE; + tree = sel->dirsonly ? sel->dirs : sel->files; + if (!gnt_widget_has_focus(tree)) + return FALSE; + + g_list_foreach(sel->tags, (GFunc)g_free, NULL); + g_list_free(sel->tags); + sel->tags = NULL; + + for (iter = GNT_TREE(tree)->list; iter; iter = iter->next) + gnt_tree_set_row_flags(GNT_TREE(tree), iter->data, GNT_TEXT_FLAG_NORMAL); + + return TRUE; +} + static void gnt_file_sel_class_init(GntFileSelClass *klass) { + GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); GntWidgetClass *kl = GNT_WIDGET_CLASS(klass); parent_class = GNT_WINDOW_CLASS(klass); kl->destroy = gnt_file_sel_destroy; @@ -270,6 +347,9 @@ NULL, NULL, gnt_closure_marshal_VOID__STRING_STRING, G_TYPE_NONE, 0); + + gnt_bindable_class_register_action(bindable, "toggle-tag", toggle_tag_selection, "t", NULL); + gnt_bindable_class_register_action(bindable, "clear-tags", clear_tags, "c", NULL); gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); GNTDEBUG; @@ -312,7 +392,7 @@ return type; } -GntWidget *gnt_file_sel_new() +GntWidget *gnt_file_sel_new(void) { GntWidget *widget = g_object_new(GNT_TYPE_FILE_SEL, NULL); GntFileSel *sel = GNT_FILE_SEL(widget); @@ -375,12 +455,19 @@ return sel->dirsonly; } +void gnt_file_sel_set_suggested_filename(GntFileSel *sel, const char *suggest) +{ + sel->suggest = g_strdup(suggest); +} + char *gnt_file_sel_get_selected_file(GntFileSel *sel) { char *ret; - const char *tmp; - tmp = (const char*)gnt_tree_get_selection_data(sel->dirsonly ? GNT_TREE(sel->dirs) : GNT_TREE(sel->files)); - ret = g_strdup_printf("%s%s%s", sel->current, sel->current[1] ? G_DIR_SEPARATOR_S : "", tmp ? tmp : ""); + if (sel->dirsonly) { + ret = g_path_get_dirname(gnt_entry_get_text(GNT_ENTRY(sel->location))); + } else { + ret = g_strdup(gnt_entry_get_text(GNT_ENTRY(sel->location))); + } return ret; } @@ -395,3 +482,26 @@ return sel->must_exist; } +void gnt_file_sel_set_multi_select(GntFileSel *sel, gboolean set) +{ + sel->multiselect = set; +} + +GList *gnt_file_sel_get_selected_multi_files(GntFileSel *sel) +{ + GList *list = NULL, *iter; + char *str = gnt_file_sel_get_selected_file(sel); + + for (iter = sel->tags; iter; iter = iter->next) { + list = g_list_prepend(list, g_strdup(iter->data)); + if (g_utf8_collate(str, iter->data)) { + g_free(str); + str = NULL; + } + } + if (str) + list = g_list_prepend(list, str); + list = g_list_reverse(list); + return list; +} + Modified: trunk/console/libgnt/gntfilesel.h =================================================================== --- trunk/console/libgnt/gntfilesel.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntfilesel.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -17,11 +17,11 @@ #define GNT_FILE_SEL_SET_FLAGS(obj, flags) (GNT_FILE_SEL_FLAGS(obj) |= flags) #define GNT_FILE_SEL_UNSET_FLAGS(obj, flags) (GNT_FILE_SEL_FLAGS(obj) &= ~(flags)) -typedef struct _GnFileSel GntFileSel; -typedef struct _GnFileSelPriv GntFileSelPriv; -typedef struct _GnFileSelClass GntFileSelClass; +typedef struct _GntFileSel GntFileSel; +typedef struct _GntFileSelPriv GntFileSelPriv; +typedef struct _GntFileSelClass GntFileSelClass; -struct _GnFileSel +struct _GntFileSel { GntWindow parent; @@ -33,12 +33,15 @@ GntWidget *cancel; /* cancel button */ char *current; /* Full path of the current location */ + char *suggest; /* Suggested filename */ /* XXX: someone should make these useful */ gboolean must_exist; /* Make sure the selected file (the name entered in 'location') exists */ gboolean dirsonly; /* Show only directories */ + gboolean multiselect; + GList *tags; /* List of tagged files when multiselect is set */ }; -struct _GnFileSelClass +struct _GntFileSelClass { GntWindowClass parent; @@ -53,12 +56,10 @@ GType gnt_file_sel_get_gtype(void); -GntWidget *gnt_file_sel_new(); +GntWidget *gnt_file_sel_new(void); gboolean gnt_file_sel_set_current_location(GntFileSel *sel, const char *path); -const char *gnt_file_sel_get_current_location(GntFileSel *sel); - void gnt_file_sel_set_dirs_only(GntFileSel *sel, gboolean dirs); gboolean gnt_file_sel_get_dirs_only(GntFileSel *sel); @@ -69,6 +70,13 @@ char *gnt_file_sel_get_selected_file(GntFileSel *sel); /* The returned value should be free'd */ +GList *gnt_file_sel_get_selected_multi_files(GntFileSel *sel); + +void gnt_file_sel_set_multi_select(GntFileSel *sel, gboolean set); + +void gnt_file_sel_set_suggested_filename(GntFileSel *sel, const char *suggest); + G_END_DECLS #endif /* GNT_FILE_SEL_H */ + Modified: trunk/console/libgnt/gntkeys.c =================================================================== --- trunk/console/libgnt/gntkeys.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntkeys.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -1,5 +1,6 @@ #include "gntkeys.h" +#include <glib.h> #include <stdlib.h> #include <string.h> @@ -8,11 +9,16 @@ char *gnt_key_cleft; char *gnt_key_cright; - static const char *term; +static GHashTable *specials; void gnt_init_keys() { + const char *controls[] = {"", "c-", "ctrl-", "ctr-", "ctl-", NULL}; + const char *alts[] = {"", "alt-", "a-", "m-", "meta-", NULL}; + int c, a, ch; + char key[32]; + if (term == NULL) { term = getenv("TERM"); if (!term) @@ -30,11 +36,86 @@ gnt_key_cright = "\033" "Oc"; gnt_key_cleft = "\033" "Od"; } + + specials = g_hash_table_new(g_str_hash, g_str_equal); + +#define INSERT_KEY(k, code) do { \ + g_hash_table_insert(specials, g_strdup(k), g_strdup(code)); \ + gnt_keys_add_combination(code); \ + } while (0) + + INSERT_KEY("home", GNT_KEY_HOME); + INSERT_KEY("end", GNT_KEY_END); + INSERT_KEY("pageup", GNT_KEY_PGUP); + INSERT_KEY("pagedown", GNT_KEY_PGDOWN); + INSERT_KEY("insert", GNT_KEY_INS); + INSERT_KEY("delete", GNT_KEY_DEL); + + INSERT_KEY("left", GNT_KEY_LEFT); + INSERT_KEY("right", GNT_KEY_RIGHT); + INSERT_KEY("up", GNT_KEY_UP); + INSERT_KEY("down", GNT_KEY_DOWN); + + INSERT_KEY("tab", "\t"); + INSERT_KEY("menu", GNT_KEY_POPUP); + + INSERT_KEY("f1", GNT_KEY_F1); + INSERT_KEY("f2", GNT_KEY_F2); + INSERT_KEY("f3", GNT_KEY_F3); + INSERT_KEY("f4", GNT_KEY_F4); + INSERT_KEY("f5", GNT_KEY_F5); + INSERT_KEY("f6", GNT_KEY_F6); + INSERT_KEY("f7", GNT_KEY_F7); + INSERT_KEY("f8", GNT_KEY_F8); + INSERT_KEY("f9", GNT_KEY_F9); + INSERT_KEY("f10", GNT_KEY_F10); + INSERT_KEY("f11", GNT_KEY_F11); + INSERT_KEY("f12", GNT_KEY_F12); + +#define REM_LENGTH (sizeof(key) - (cur - key)) +#define INSERT_COMB(k, code) do { \ + snprintf(key, sizeof(key), "%s%s%s", controls[c], alts[a], k); \ + INSERT_KEY(key, code); \ + } while (0); + + /* Lower-case alphabets */ + for (a = 0, c = 0; controls[c]; c++, a = 0) { + if (c) { + INSERT_COMB("up", gnt_key_cup); + INSERT_COMB("down", gnt_key_cdown); + INSERT_COMB("left", gnt_key_cleft); + INSERT_COMB("right", gnt_key_cright); + } + + for (a = 0; alts[a]; a++) { + for (ch = 0; ch < 26; ch++) { + char str[2] = {'a' + ch, 0}, code[4] = "\0\0\0\0"; + int ind = 0; + if (a) + code[ind++] = '\033'; + code[ind] = (c ? 1 : 'a') + ch; + INSERT_COMB(str, code); + } + } + } + c = 0; + for (a = 0; alts[a]; a++) { + /* Upper-case alphabets */ + for (ch = 0; ch < 26; ch++) { + char str[2] = {'A' + ch, 0}, code[] = {'\033', 'A' + ch, 0}; + INSERT_COMB(str, code); + } + /* Digits */ + for (ch = 0; ch < 10; ch++) { + char str[2] = {'0' + ch, 0}, code[] = {'\033', '0' + ch, 0}; + INSERT_COMB(str, code); + } + } } void gnt_keys_refine(char *text) { - if (*text == 27 && *(text + 1) == '[' && *(text + 3) == '\0' && + if (*text == 27 && *(text + 1) == '[' && (*(text + 2) >= 'A' && *(text + 2) <= 'D')) { /* Apparently this is necessary for urxvt and screen and xterm */ if (strcmp(term, "screen") == 0 || strcmp(term, "rxvt-unicode") == 0 || @@ -48,3 +129,115 @@ } } +const char *gnt_key_translate(const char *name) +{ + return g_hash_table_lookup(specials, name); +} + +/** + * The key-bindings will be saved in a tree. When a keystroke happens, GNT will + * find the sequence that matches a binding and return the length. + * A sequence should not be a prefix of another sequence. If it is, then only + * the shortest one will be processed. If we want to change that, we will need + * to allow getting the k-th prefix that matches the input, and pay attention + * to the return value of gnt_wm_process_input in gntmain.c. + */ +#define SIZE 256 + +#define IS_END 1 << 0 +struct _node +{ + struct _node *next[SIZE]; + int ref; + int flags; +}; + +static struct _node root = {.ref = 1, .flags = 0}; + +static void add_path(struct _node *node, const char *path) +{ + struct _node *n = NULL; + if (!path || !*path) { + node->flags |= IS_END; + return; + } + while (*path && node->next[*path]) { + node = node->next[*path]; + node->ref++; + path++; + } + if (!*path) + return; + n = g_new0(struct _node, 1); + n->ref = 1; + node->next[*path++] = n; + add_path(n, path); +} + +void gnt_keys_add_combination(const char *path) +{ + add_path(&root, path); +} + +static void del_path(struct _node *node, const char *path) +{ + struct _node *next = NULL; + + if (!*path) + return; + next = node->next[*path]; + if (!next) + return; + del_path(next, path + 1); + next->ref--; + if (next->ref == 0) { + node->next[*path] = NULL; + g_free(next); + } +} + +void gnt_keys_del_combination(const char *path) +{ + del_path(&root, path); +} + +int gnt_keys_find_combination(const char *path) +{ + int depth = 0; + struct _node *n = &root; + + root.flags &= ~IS_END; + while (*path && n->next[*path] && !(n->flags & IS_END)) { + if (g_utf8_find_next_char(path, NULL) - path > 1) + return 0; + n = n->next[*path++]; + depth++; + } + + if (!(n->flags & IS_END)) + depth = 0; + return depth; +} + +static void +print_path(struct _node *node, int depth) +{ + int i; + for (i = 0; i < SIZE; i++) { + if (node->next[i]) { + g_printerr("%*c (%d:%d)\n", depth * 4, i, node->next[i]->ref, + node->next[i]->flags); + print_path(node->next[i], depth + 1); + } + } +} + +/* this is purely for debugging purposes. */ +void gnt_keys_print_combinations(void); +void gnt_keys_print_combinations() +{ + g_printerr("--------\n"); + print_path(&root, 1); + g_printerr("--------\n"); +} + Modified: trunk/console/libgnt/gntkeys.h =================================================================== --- trunk/console/libgnt/gntkeys.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntkeys.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -79,10 +79,15 @@ /** * This will do stuff with the terminal settings and stuff. */ -void gnt_init_keys(); +void gnt_init_keys(void); void gnt_keys_refine(char *text); +const char *gnt_key_translate(const char *name); +void gnt_keys_add_combination(const char *path); +void gnt_keys_del_combination(const char *path); +int gnt_keys_find_combination(const char *path); + /* A lot of commonly used variable names are defined in <term.h>. * #undef them to make life easier for everyone. */ Modified: trunk/console/libgnt/gntlabel.c =================================================================== --- trunk/console/libgnt/gntlabel.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntlabel.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -24,7 +24,7 @@ chtype flag = gnt_text_format_flag_to_chtype(label->flags); wbkgdset(widget->window, '\0' | flag); - mvwprintw(widget->window, 0, 0, label->text); + mvwaddstr(widget->window, 0, 0, label->text); GNTDEBUG; } @@ -80,6 +80,7 @@ sizeof(GntLabel), 0, /* n_preallocs */ gnt_label_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_WIDGET, Modified: trunk/console/libgnt/gntlabel.h =================================================================== --- trunk/console/libgnt/gntlabel.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntlabel.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -12,10 +12,10 @@ #define GNT_IS_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_LABEL)) #define GNT_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_LABEL, GntLabelClass)) -typedef struct _GnLabel GntLabel; -typedef struct _GnLabelClass GntLabelClass; +typedef struct _GntLabel GntLabel; +typedef struct _GntLabelClass GntLabelClass; -struct _GnLabel +struct _GntLabel { GntWidget parent; @@ -28,7 +28,7 @@ void (*gnt_reserved4)(void); }; -struct _GnLabelClass +struct _GntLabelClass { GntWidgetClass parent; Modified: trunk/console/libgnt/gntline.c =================================================================== --- trunk/console/libgnt/gntline.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntline.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -83,6 +83,7 @@ sizeof(GntLine), 0, /* n_preallocs */ gnt_line_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_WIDGET, Modified: trunk/console/libgnt/gntline.h =================================================================== --- trunk/console/libgnt/gntline.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntline.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -17,18 +17,18 @@ #define GNT_LINE_SET_FLAGS(obj, flags) (GNT_LINE_FLAGS(obj) |= flags) #define GNT_LINE_UNSET_FLAGS(obj, flags) (GNT_LINE_FLAGS(obj) &= ~(flags)) -typedef struct _GnLine GntLine; -typedef struct _GnLinePriv GntLinePriv; -typedef struct _GnLineClass GntLineClass; +typedef struct _GntLine GntLine; +typedef struct _GntLinePriv GntLinePriv; +typedef struct _GntLineClass GntLineClass; -struct _GnLine +struct _GntLine { GntWidget parent; gboolean vertical; }; -struct _GnLineClass +struct _GntLineClass { GntWidgetClass parent; Modified: trunk/console/libgnt/gntmain.c =================================================================== --- trunk/console/libgnt/gntmain.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntmain.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -7,9 +7,13 @@ #include <gmodule.h> +#include <sys/types.h> +#include <sys/wait.h> + #include "gnt.h" #include "gntbox.h" #include "gntcolors.h" +#include "gntclipboard.h" #include "gntkeys.h" #include "gntmenu.h" #include "gntstyle.h" @@ -28,9 +32,6 @@ #include <ctype.h> #include <errno.h> -#include <sys/types.h> -#include <sys/wait.h> - /** * Notes: Interesting functions to look at: * scr_dump, scr_init, scr_restore: for workspaces @@ -43,12 +44,27 @@ static gboolean ascii_only; static gboolean mouse_enabled; -static void setup_io(); +static void setup_io(void); static gboolean refresh_screen(); GntWM *wm; +static GntClipboard *clipboard; +#define HOLDING_ESCAPE (escape_stuff.timer != 0) + +static struct { + int timer; +} escape_stuff; + +static gboolean +escape_timeout(gpointer data) +{ + gnt_wm_process_input(wm, "\033"); + escape_stuff.timer = 0; + return FALSE; +} + /** * Mouse support: * - bring a window on top if you click on its taskbar @@ -178,7 +194,8 @@ io_invoke(GIOChannel *source, GIOCondition cond, gpointer null) { char keys[256]; - int rd = read(STDIN_FILENO, keys, sizeof(keys) - 1); + int rd = read(STDIN_FILENO, keys + HOLDING_ESCAPE, sizeof(keys) - 1 - HOLDING_ESCAPE); + char *k; if (rd < 0) { int ch = getch(); /* This should return ERR, but let's see what it really returns */ @@ -194,14 +211,39 @@ raise(SIGABRT); } + rd += HOLDING_ESCAPE; keys[rd] = 0; - gnt_keys_refine(keys); - if (mouse_enabled && detect_mouse_action(keys)) return TRUE; - - gnt_wm_process_input(wm, keys); + if (HOLDING_ESCAPE) + keys[0] = '\033'; + k = keys; + while (rd) { + char back; + int p; + + if (k[0] == '\033' && rd == 1) { + if (escape_stuff.timer) { + gnt_wm_process_input(wm, "\033\033"); + g_source_remove(escape_stuff.timer); + escape_stuff.timer = 0; + break; + } + escape_stuff.timer = g_timeout_add(250, escape_timeout, NULL); + break; + } + + gnt_keys_refine(k); + p = MAX(1, gnt_keys_find_combination(k)); + back = k[p]; + k[p] = '\0'; + gnt_wm_process_input(wm, k); /* XXX: */ + k[p] = back; + rd -= p; + k += p; + } + return TRUE; } @@ -210,10 +252,11 @@ { int result; channel = g_io_channel_unix_new(STDIN_FILENO); + g_io_channel_set_close_on_unref(channel, TRUE); +#if 0 g_io_channel_set_encoding(channel, NULL, NULL); g_io_channel_set_buffered(channel, FALSE); -#if 0 g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL ); #endif @@ -303,10 +346,10 @@ if (channel) return; + locale = setlocale(LC_ALL, ""); + setup_io(); - locale = setlocale(LC_ALL, ""); - if (locale && (strstr(locale, "UTF") || strstr(locale, "utf"))) ascii_only = FALSE; else @@ -317,6 +360,7 @@ noecho(); curs_set(0); + gnt_init_keys(); gnt_init_styles(); filename = g_build_filename(g_get_home_dir(), ".gntrc", NULL); @@ -324,7 +368,6 @@ g_free(filename); gnt_init_colors(); - gnt_init_keys(); wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); refresh(); @@ -347,6 +390,8 @@ g_type_init(); init_wm(); + + clipboard = g_object_new(GNT_TYPE_CLIPBOARD, NULL); } void gnt_main() @@ -475,3 +520,16 @@ return TRUE; } +void gnt_set_clipboard_string(gchar *string) +{ + gnt_clipboard_set_string(clipboard, string); +} + +GntClipboard *gnt_get_clipboard() +{ + return clipboard; +} +gchar *gnt_get_clipboard_string() +{ + return gnt_clipboard_get_string(clipboard); +} Modified: trunk/console/libgnt/gntmenu.c =================================================================== --- trunk/console/libgnt/gntmenu.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntmenu.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -28,7 +28,7 @@ werase(widget->window); for (i = 0, iter = menu->list; iter; iter = iter->next, i++) { - GntMenuItem *item = GNT_MENUITEM(iter->data); + GntMenuItem *item = GNT_MENU_ITEM(iter->data); type = ' ' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT); if (i == menu->selected) type |= A_REVERSE; @@ -61,10 +61,10 @@ static void menu_tree_add(GntMenu *menu, GntMenuItem *item, GntMenuItem *parent) { - if (GNT_IS_MENUITEM_CHECK(item)) { + if (GNT_IS_MENU_ITEM_CHECK(item)) { gnt_tree_add_choice(GNT_TREE(menu), item, gnt_tree_create_row(GNT_TREE(menu), item->text, " "), parent, NULL); - gnt_tree_set_choice(GNT_TREE(menu), item, gnt_menuitem_check_get_checked(GNT_MENUITEM_CHECK(item))); + gnt_tree_set_choice(GNT_TREE(menu), item, gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item))); } else gnt_tree_add_row_last(GNT_TREE(menu), item, gnt_tree_create_row(GNT_TREE(menu), item->text, item->submenu ? ">" : " "), parent); @@ -73,7 +73,7 @@ GntMenu *sub = GNT_MENU(item->submenu); GList *iter; for (iter = sub->list; iter; iter = iter->next) { - GntMenuItem *it = GNT_MENUITEM(iter->data); + GntMenuItem *it = GNT_MENU_ITEM(iter->data); menu_tree_add(menu, it, item); } } @@ -91,7 +91,7 @@ GList *iter; gnt_tree_remove_all(GNT_TREE(widget)); for (iter = menu->list; iter; iter = iter->next) { - GntMenuItem *item = GNT_MENUITEM(iter->data); + GntMenuItem *item = GNT_MENU_ITEM(iter->data); menu_tree_add(menu, item, NULL); } org_map(widget); @@ -134,7 +134,8 @@ int current = menu->selected; if (menu->submenu) { - return (gnt_widget_key_pressed(GNT_WIDGET(menu->submenu), text)); + do menu = menu->submenu; while (menu->submenu); + return (gnt_widget_key_pressed(GNT_WIDGET(menu), text)); } if (text[0] == 27 && text[1] == 0) { @@ -184,10 +185,10 @@ static void gnt_menu_toggled(GntTree *tree, gpointer key) { - GntMenuItem *item = GNT_MENUITEM(key); + GntMenuItem *item = GNT_MENU_ITEM(key); GntMenu *menu = GNT_MENU(tree); - gboolean check = gnt_menuitem_check_get_checked(GNT_MENUITEM_CHECK(item)); - gnt_menuitem_check_set_checked(GNT_MENUITEM_CHECK(item), !check); + gboolean check = gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item)); + gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(item), !check); if (item->callback) item->callback(item, item->callbackdata); while (menu) { @@ -209,7 +210,7 @@ } if (item) { - if (GNT_IS_MENUITEM_CHECK(item)) + if (GNT_IS_MENU_ITEM_CHECK(item)) gnt_menu_toggled(GNT_TREE(widget), item); else menuitem_activate(menu, item); @@ -277,6 +278,7 @@ sizeof(GntMenu), 0, /* n_preallocs */ gnt_menu_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_TREE, Modified: trunk/console/libgnt/gntmenu.h =================================================================== --- trunk/console/libgnt/gntmenu.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntmenu.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -16,9 +16,9 @@ #define GNT_MENU_SET_FLAGS(obj, flags) (GNT_MENU_FLAGS(obj) |= flags) #define GNT_MENU_UNSET_FLAGS(obj, flags) (GNT_MENU_FLAGS(obj) &= ~(flags)) -typedef struct _GnMenu GntMenu; -typedef struct _GnMenuPriv GntMenuPriv; -typedef struct _GnMenuClass GntMenuClass; +typedef struct _GntMenu GntMenu; +typedef struct _GntMenuPriv GntMenuPriv; +typedef struct _GntMenuClass GntMenuClass; #include "gntmenuitem.h" @@ -33,7 +33,7 @@ GNT_MENU_POPUP, /* A popup menu */ } GntMenuType; -struct _GnMenu +struct _GntMenu { GntTree parent; GntMenuType type; @@ -47,7 +47,7 @@ GntMenu *parentmenu; }; -struct _GnMenuClass +struct _GntMenuClass { GntTreeClass parent; Modified: trunk/console/libgnt/gntmenuitem.c =================================================================== --- trunk/console/libgnt/gntmenuitem.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntmenuitem.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -6,7 +6,7 @@ static void gnt_menuitem_destroy(GObject *obj) { - GntMenuItem *item = GNT_MENUITEM(obj); + GntMenuItem *item = GNT_MENU_ITEM(obj); g_free(item->text); item->text = NULL; if (item->submenu) @@ -48,6 +48,7 @@ sizeof(GntMenuItem), 0, /* n_preallocs */ gnt_menuitem_init, /* instance_init */ + NULL /* value_table */ }; type = g_type_register_static(G_TYPE_OBJECT, @@ -60,8 +61,8 @@ GntMenuItem *gnt_menuitem_new(const char *text) { - GObject *item = g_object_new(GNT_TYPE_MENUITEM, NULL); - GntMenuItem *menuitem = GNT_MENUITEM(item); + GObject *item = g_object_new(GNT_TYPE_MENU_ITEM, NULL); + GntMenuItem *menuitem = GNT_MENU_ITEM(item); menuitem->text = g_strdup(text); Modified: trunk/console/libgnt/gntmenuitem.h =================================================================== --- trunk/console/libgnt/gntmenuitem.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntmenuitem.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -4,24 +4,24 @@ #include <glib.h> #include <glib-object.h> -#define GNT_TYPE_MENUITEM (gnt_menuitem_get_gtype()) -#define GNT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENUITEM, GntMenuItem)) -#define GNT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENUITEM, GntMenuItemClass)) -#define GNT_IS_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_MENUITEM)) -#define GNT_IS_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_MENUITEM)) -#define GNT_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_MENUITEM, GntMenuItemClass)) +#define GNT_TYPE_MENU_ITEM (gnt_menuitem_get_gtype()) +#define GNT_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENU_ITEM, GntMenuItem)) +#define GNT_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENU_ITEM, GntMenuItemClass)) +#define GNT_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_MENU_ITEM)) +#define GNT_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_MENU_ITEM)) +#define GNT_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_MENU_ITEM, GntMenuItemClass)) -#define GNT_MENUITEM_FLAGS(obj) (GNT_MENUITEM(obj)->priv.flags) -#define GNT_MENUITEM_SET_FLAGS(obj, flags) (GNT_MENUITEM_FLAGS(obj) |= flags) -#define GNT_MENUITEM_UNSET_FLAGS(obj, flags) (GNT_MENUITEM_FLAGS(obj) &= ~(flags)) +#define GNT_MENU_ITEM_FLAGS(obj) (GNT_MENU_ITEM(obj)->priv.flags) +#define GNT_MENU_ITEM_SET_FLAGS(obj, flags) (GNT_MENU_ITEM_FLAGS(obj) |= flags) +#define GNT_MENU_ITEM_UNSET_FLAGS(obj, flags) (GNT_MENU_ITEM_FLAGS(obj) &= ~(flags)) -typedef struct _GnMenuItem GntMenuItem; -typedef struct _GnMenuItemPriv GntMenuItemPriv; -typedef struct _GnMenuItemClass GntMenuItemClass; +typedef struct _GntMenuItem GntMenuItem; +typedef struct _GntMenuItemPriv GntMenuItemPriv; +typedef struct _GntMenuItemClass GntMenuItemClass; #include "gntmenu.h" -struct _GnMenuItemPriv +struct _GntMenuItemPriv { /* These will be used to determine the position of the submenu */ int x; @@ -30,7 +30,7 @@ typedef void (*GntMenuItemCallback)(GntMenuItem *item, gpointer data); -struct _GnMenuItem +struct _GntMenuItem { GObject parent; GntMenuItemPriv priv; @@ -46,7 +46,7 @@ GntMenu *submenu; }; -struct _GnMenuItemClass +struct _GntMenuItemClass { GObjectClass parent; Modified: trunk/console/libgnt/gntmenuitemcheck.c =================================================================== --- trunk/console/libgnt/gntmenuitemcheck.c 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntmenuitemcheck.c 2007-03-30 05:49:39 UTC (rev 18220) @@ -5,7 +5,7 @@ static void gnt_menuitem_check_class_init(GntMenuItemCheckClass *klass) { - parent_class = GNT_MENUITEM_CLASS(klass); + parent_class = GNT_MENU_ITEM_CLASS(klass); GNTDEBUG; } @@ -36,9 +36,10 @@ sizeof(GntMenuItemCheck), 0, /* n_preallocs */ gnt_menuitem_check_init, /* instance_init */ + NULL /* value_table */ }; - type = g_type_register_static(GNT_TYPE_MENUITEM, + type = g_type_register_static(GNT_TYPE_MENU_ITEM, "GntMenuItemCheck", &info, 0); } @@ -48,8 +49,8 @@ GntMenuItem *gnt_menuitem_check_new(const char *text) { - GntMenuItem *item = g_object_new(GNT_TYPE_MENUITEM_CHECK, NULL); - GntMenuItem *menuitem = GNT_MENUITEM(item); + GntMenuItem *item = g_object_new(GNT_TYPE_MENU_ITEM_CHECK, NULL); + GntMenuItem *menuitem = GNT_MENU_ITEM(item); menuitem->text = g_strdup(text); return item; Modified: trunk/console/libgnt/gntmenuitemcheck.h =================================================================== --- trunk/console/libgnt/gntmenuitemcheck.h 2007-03-28 12:42:19 UTC (rev 18219) +++ trunk/console/libgnt/gntmenuitemcheck.h 2007-03-30 05:49:39 UTC (rev 18220) @@ -1,33 +1,33 @@ -#ifndef GNT_MENUITEM_CHECK_H -#define GNT_MENUITEM_CHECK_H +#ifndef GNT_MENU_ITEM_CHECK_H +#define GNT_MENU_ITEM_CHECK_H #include "gnt.h" #include "gntcolors.h" #include "gntkeys.h" #include "gntmenuitem.h" -#define GNT_TYPE_MENUITEM_CHECK (gnt_menuitem_check_get_gtype()) -#define GNT_MENUITEM_CHECK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENUITEM_CHECK, GntMenuItemCheck)) -#define GNT_MENUITEM_CHECK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENUITEM_CHECK, GntMenuItemCheckClass)) -#... [truncated message content] |
From: <sa...@us...> - 2007-04-04 03:50:24
|
Revision: 18229 http://svn.sourceforge.net/gaim/?rev=18229&view=rev Author: sadrul Date: 2007-04-03 20:50:24 -0700 (Tue, 03 Apr 2007) Log Message: ----------- Add a way to get a list of bindings for a widget. This can be used by, eg, a window-manager to show helpful messages to the user. Modified Paths: -------------- trunk/console/libgnt/gntkeys.c trunk/console/libgnt/gntkeys.h trunk/console/libgnt/gntutils.c trunk/console/libgnt/gntutils.h Modified: trunk/console/libgnt/gntkeys.c =================================================================== --- trunk/console/libgnt/gntkeys.c 2007-04-01 23:59:40 UTC (rev 18228) +++ trunk/console/libgnt/gntkeys.c 2007-04-04 03:50:24 UTC (rev 18229) @@ -134,6 +134,28 @@ return g_hash_table_lookup(specials, name); } +typedef struct { + const char *name; + const char *key; +} gntkey; + +static void +get_key_name(gpointer key, gpointer value, gpointer data) +{ + gntkey *k = data; + if (k->name) + return; + if (g_utf8_collate(value, k->key) == 0) + k->name = key; +} + +const char *gnt_key_lookup(const char *key) +{ + gntkey k = {NULL, key}; + g_hash_table_foreach(specials, get_key_name, &k); + return k.name; +} + /** * The key-bindings will be saved in a tree. When a keystroke happens, GNT will * find the sequence that matches a binding and return the length. Modified: trunk/console/libgnt/gntkeys.h =================================================================== --- trunk/console/libgnt/gntkeys.h 2007-04-01 23:59:40 UTC (rev 18228) +++ trunk/console/libgnt/gntkeys.h 2007-04-04 03:50:24 UTC (rev 18229) @@ -82,6 +82,7 @@ void gnt_init_keys(void); void gnt_keys_refine(char *text); const char *gnt_key_translate(const char *name); +const char *gnt_key_lookup(const char *key); void gnt_keys_add_combination(const char *path); void gnt_keys_del_combination(const char *path); Modified: trunk/console/libgnt/gntutils.c =================================================================== --- trunk/console/libgnt/gntutils.c 2007-04-01 23:59:40 UTC (rev 18228) +++ trunk/console/libgnt/gntutils.c 2007-04-04 03:50:24 UTC (rev 18229) @@ -1,4 +1,5 @@ #include "gntutils.h" +#include "gnttree.h" #include <stdlib.h> #include <string.h> @@ -145,3 +146,47 @@ return continue_emission; } +typedef struct { + GHashTable *hash; + GntTree *tree; +} BindingView; + +static void +add_binding(gpointer key, gpointer value, gpointer data) +{ + BindingView *bv = data; + GntBindableActionParam *act = value; + const char *name = g_hash_table_lookup(bv->hash, act->action); + if (name && *name) { + const char *k = gnt_key_lookup(key); + if (!k) + k = key; + gnt_tree_add_row_after(bv->tree, (gpointer)k, + gnt_tree_create_row(bv->tree, k, name), NULL, NULL); + } +} + +static void +add_action(gpointer key, gpointer value, gpointer data) +{ + BindingView *bv = data; + g_hash_table_insert(bv->hash, value, key); +} + +GntWidget *gnt_widget_bindings_view(GntWidget *widget) +{ + GntBindable *bind = GNT_BINDABLE(widget); + GntWidget *tree = gnt_tree_new_with_columns(2); + GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bind)); + GHashTable *hash = g_hash_table_new(g_direct_hash, g_direct_equal); + BindingView bv = {hash, GNT_TREE(tree)}; + + gnt_tree_set_compare_func(bv.tree, (GCompareFunc)g_utf8_collate); + g_hash_table_foreach(klass->actions, add_action, &bv); + g_hash_table_foreach(klass->bindings, add_binding, &bv); + gnt_tree_adjust_columns(bv.tree); + g_hash_table_destroy(hash); + + return tree; +} + Modified: trunk/console/libgnt/gntutils.h =================================================================== --- trunk/console/libgnt/gntutils.h 2007-04-01 23:59:40 UTC (rev 18228) +++ trunk/console/libgnt/gntutils.h 2007-04-04 03:50:24 UTC (rev 18229) @@ -34,3 +34,8 @@ const GValue *handler_return, gpointer dummy); +/** + * Returns a GntTree populated with "key" -> "binding" for the widget. + */ +GntWidget *gnt_widget_bindings_view(GntWidget *widget); + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2007-04-04 08:37:19
|
Revision: 18233 http://svn.sourceforge.net/gaim/?rev=18233&view=rev Author: sadrul Date: 2007-04-04 01:37:15 -0700 (Wed, 04 Apr 2007) Log Message: ----------- Allow using different methods for reading directory entries. Modified Paths: -------------- trunk/console/libgnt/gntfilesel.c trunk/console/libgnt/gntfilesel.h Modified: trunk/console/libgnt/gntfilesel.c =================================================================== --- trunk/console/libgnt/gntfilesel.c 2007-04-04 04:07:16 UTC (rev 18232) +++ trunk/console/libgnt/gntfilesel.c 2007-04-04 08:37:15 UTC (rev 18233) @@ -11,7 +11,9 @@ #include <sys/stat.h> #include <unistd.h> +#if 0 #include <glob.h> +#endif enum { @@ -87,12 +89,76 @@ return find; } +GntFile* gnt_file_new_dir(const char *name) +{ + GntFile *file = g_new0(GntFile, 1); + file->basename = g_strdup(name); + file->type = GNT_FILE_DIR; + return file; +} + +GntFile* gnt_file_new(const char *name, unsigned long size) +{ + GntFile *file = g_new0(GntFile, 1); + file->basename = g_strdup(name); + file->type = GNT_FILE_REGULAR; + file->size = size; + return file; +} + static gboolean -location_changed(GntFileSel *sel, GError **err) +local_read_fn(const char *path, GList **files, GError **error) { GDir *dir; + GntFile *file; const char *str; + + dir = g_dir_open(path, 0, error); + if (dir == NULL || (error && *error)) { + return FALSE; + } + *files = NULL; + if (*path != '\0' && strcmp(path, G_DIR_SEPARATOR_S)) { + file = gnt_file_new_dir(".."); + *files = g_list_prepend(*files, file); + } + + while ((str = g_dir_read_name(dir)) != NULL) { + char *fp = g_build_filename(path, str, NULL); + struct stat st; + + if (stat(fp, &st)) { + g_printerr("Error stating location %s\n", fp); + } else { + if (S_ISDIR(st.st_mode)) { + file = gnt_file_new_dir(str); + } else { + file = gnt_file_new(str, (long)st.st_size); + } + *files = g_list_prepend(*files, file); + } + g_free(fp); + } + + *files = g_list_reverse(*files); + return TRUE; +} + +static void +gnt_file_free(GntFile *file) +{ + g_free(file->fullpath); + g_free(file->basename); + g_free(file); +} + +static gboolean +location_changed(GntFileSel *sel, GError **err) +{ + GList *files, *iter; + gboolean success; + if (!sel->dirs) return TRUE; @@ -105,42 +171,43 @@ gnt_widget_draw(GNT_WIDGET(sel)); return TRUE; } + + /* XXX:\ + * XXX: This is blocking. + * XXX:/ + */ + files = NULL; + if (sel->read_fn) + success = sel->read_fn(sel->current, &files, err); + else + success = local_read_fn(sel->current, &files, err); - dir = g_dir_open(sel->current, 0, err); - if (dir == NULL || *err) { + if (!success || *err) { g_printerr("GntFileSel: error opening location %s (%s)\n", sel->current, *err ? (*err)->message : "reason unknown"); return FALSE; } - if (*sel->current != '\0' && strcmp(sel->current, G_DIR_SEPARATOR_S)) - gnt_tree_add_row_after(GNT_TREE(sel->dirs), g_strdup(".."), - gnt_tree_create_row(GNT_TREE(sel->dirs), ".."), NULL, NULL); + for (iter = files; iter; iter = iter->next) { + GntFile *file = iter->data; + char *str = file->basename; + if (file->type == GNT_FILE_DIR) { + gnt_tree_add_row_after(GNT_TREE(sel->dirs), g_strdup(str), + gnt_tree_create_row(GNT_TREE(sel->dirs), str), NULL, NULL); + if (sel->multiselect && sel->dirsonly && is_tagged(sel, str)) + gnt_tree_set_row_flags(GNT_TREE(sel->dirs), (gpointer)str, GNT_TEXT_FLAG_BOLD); + } else if (!sel->dirsonly) { + char size[128]; + snprintf(size, sizeof(size), "%ld", file->size); - while ((str = g_dir_read_name(dir)) != NULL) { - char *fp = g_build_filename(sel->current, str, NULL); - struct stat st; - - if (stat(fp, &st)) { - g_printerr("Error stating location %s\n", fp); - } else { - if (S_ISDIR(st.st_mode)) { - gnt_tree_add_row_after(GNT_TREE(sel->dirs), g_strdup(str), - gnt_tree_create_row(GNT_TREE(sel->dirs), str), NULL, NULL); - if (sel->multiselect && sel->dirsonly && is_tagged(sel, str)) - gnt_tree_set_row_flags(GNT_TREE(sel->dirs), (gpointer)str, GNT_TEXT_FLAG_BOLD); - } else if (!sel->dirsonly) { - char size[128]; - snprintf(size, sizeof(size), "%ld", (long)st.st_size); - - gnt_tree_add_row_after(GNT_TREE(sel->files), g_strdup(str), - gnt_tree_create_row(GNT_TREE(sel->files), str, size, ""), NULL, NULL); - if (sel->multiselect && is_tagged(sel, str)) - gnt_tree_set_row_flags(GNT_TREE(sel->files), (gpointer)str, GNT_TEXT_FLAG_BOLD); - } + gnt_tree_add_row_after(GNT_TREE(sel->files), g_strdup(str), + gnt_tree_create_row(GNT_TREE(sel->files), str, size, ""), NULL, NULL); + if (sel->multiselect && is_tagged(sel, str)) + gnt_tree_set_row_flags(GNT_TREE(sel->files), (gpointer)str, GNT_TEXT_FLAG_BOLD); } - g_free(fp); } + g_list_foreach(files, (GFunc)gnt_file_free, NULL); + g_list_free(files); if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(sel), GNT_WIDGET_MAPPED)) gnt_widget_draw(GNT_WIDGET(sel)); return TRUE; @@ -151,8 +218,13 @@ { if (strcmp(key, "\r") == 0) { char *str = g_strdup(gnt_tree_get_selection_data(tree)); - char *path = g_build_filename(sel->current, str, NULL); - char *dir = g_path_get_basename(sel->current); + char *path, *dir; + + if (!str) + return TRUE; + + path = g_build_filename(sel->current, str, NULL); + dir = g_path_get_basename(sel->current); if (!gnt_file_sel_set_current_location(sel, path)) { gnt_tree_set_selected(tree, str); } else if (strcmp(str, "..") == 0) { @@ -169,64 +241,67 @@ static gboolean location_key_pressed(GntTree *tree, const char *key, GntFileSel *sel) { - if (strcmp(key, "\r") == 0) { - int count; - glob_t gl; - char *path; - char *str; - struct stat st; - int glob_ret; + char *path; + char *str; +#if 0 + int count; + glob_t gl; + struct stat st; + int glob_ret; +#endif + if (strcmp(key, "\r")) + return FALSE; - str = (char*)gnt_entry_get_text(GNT_ENTRY(sel->location)); - if (*str == G_DIR_SEPARATOR) - path = g_strdup(str); - else - path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", sel->current, str); - str = process_path(path); + str = (char*)gnt_entry_get_text(GNT_ENTRY(sel->location)); + if (*str == G_DIR_SEPARATOR) + path = g_strdup(str); + else + path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", sel->current, str); + str = process_path(path); + g_free(path); + path = g_path_get_dirname(str); + g_free(str); + + if (!gnt_file_sel_set_current_location(sel, path)) { g_free(path); - path = str; + return FALSE; + } +#if 0 + /* XXX: there needs to be a way to allow other methods for globbing, + * like the read_fn stuff. */ + glob_ret = glob(path, GLOB_MARK, NULL, &gl); + if (!glob_ret) { /* XXX: do something with the return value */ + char *loc = g_path_get_dirname(gl.gl_pathv[0]); - if (!stat(path, &st)) { - if (S_ISDIR(st.st_mode)) { - gnt_file_sel_set_current_location(sel, path); - goto success; - } - } - - glob_ret = glob(path, GLOB_MARK, NULL, &gl); - if (!glob_ret) { /* XXX: do something with the return value */ - char *loc = g_path_get_dirname(gl.gl_pathv[0]); - - stat(gl.gl_pathv[0], &st); - gnt_file_sel_set_current_location(sel, loc); /* XXX: check the return value */ - g_free(loc); - if (!S_ISDIR(st.st_mode) && !sel->dirsonly) { - gnt_tree_remove_all(GNT_TREE(sel->files)); - for (count = 0; count < gl.gl_pathc; count++) { - char *tmp = process_path(gl.gl_pathv[count]); - loc = g_path_get_dirname(tmp); - if (g_utf8_collate(sel->current, loc) == 0) { - char *base = g_path_get_basename(tmp); - char size[128]; - snprintf(size, sizeof(size), "%ld", (long)st.st_size); - gnt_tree_add_row_after(GNT_TREE(sel->files), base, - gnt_tree_create_row(GNT_TREE(sel->files), base, size, ""), NULL, NULL); - } - g_free(loc); - g_free(tmp); + stat(gl.gl_pathv[0], &st); + gnt_file_sel_set_current_location(sel, loc); /* XXX: check the return value */ + g_free(loc); + if (!S_ISDIR(st.st_mode) && !sel->dirsonly) { + gnt_tree_remove_all(GNT_TREE(sel->files)); + for (count = 0; count < gl.gl_pathc; count++) { + char *tmp = process_path(gl.gl_pathv[count]); + loc = g_path_get_dirname(tmp); + if (g_utf8_collate(sel->current, loc) == 0) { + char *base = g_path_get_basename(tmp); + char size[128]; + snprintf(size, sizeof(size), "%ld", (long)st.st_size); + gnt_tree_add_row_after(GNT_TREE(sel->files), base, + gnt_tree_create_row(GNT_TREE(sel->files), base, size, ""), NULL, NULL); } - gnt_widget_draw(sel->files); + g_free(loc); + g_free(tmp); } - } else if (sel->files) { - gnt_tree_remove_all(GNT_TREE(sel->files)); gnt_widget_draw(sel->files); } - globfree(&gl); + } else if (sel->files) { + gnt_tree_remove_all(GNT_TREE(sel->files)); + gnt_widget_draw(sel->files); + } + globfree(&gl); success: - g_free(path); - return TRUE; - } - return FALSE; +#endif + g_free(path); + return TRUE; } static void @@ -329,6 +404,24 @@ return TRUE; } +static gboolean +up_directory(GntBindable *bind, GList *null) +{ + char *path, *dir; + GntFileSel *sel = GNT_FILE_SEL(bind); + if (!gnt_widget_has_focus(sel->dirs) && + !gnt_widget_has_focus(sel->files)) + return FALSE; + + path = g_build_filename(sel->current, "..", NULL); + dir = g_path_get_basename(sel->current); + if (gnt_file_sel_set_current_location(sel, path)) + gnt_tree_set_selected(GNT_TREE(sel->dirs), dir); + g_free(dir); + g_free(path); + return TRUE; +} + static void gnt_file_sel_class_init(GntFileSelClass *klass) { @@ -350,6 +443,7 @@ gnt_bindable_class_register_action(bindable, "toggle-tag", toggle_tag_selection, "t", NULL); gnt_bindable_class_register_action(bindable, "clear-tags", clear_tags, "c", NULL); + gnt_bindable_class_register_action(bindable, "up-directory", up_directory, GNT_KEY_BACKSPACE, NULL); gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); GNTDEBUG; @@ -505,3 +599,9 @@ return list; } +void gnt_file_sel_set_read_fn(GntFileSel *sel, gboolean (*read_fn)(const char *path, GList **files, GError **error)) +{ + sel->read_fn = read_fn; +} + + Modified: trunk/console/libgnt/gntfilesel.h =================================================================== --- trunk/console/libgnt/gntfilesel.h 2007-04-04 04:07:16 UTC (rev 18232) +++ trunk/console/libgnt/gntfilesel.h 2007-04-04 08:37:15 UTC (rev 18233) @@ -20,6 +20,7 @@ typedef struct _GntFileSel GntFileSel; typedef struct _GntFileSelPriv GntFileSelPriv; typedef struct _GntFileSelClass GntFileSelClass; +typedef struct _GntFile GntFile; struct _GntFileSel { @@ -39,6 +40,8 @@ gboolean dirsonly; /* Show only directories */ gboolean multiselect; GList *tags; /* List of tagged files when multiselect is set */ + + gboolean (*read_fn)(const char *path, GList **files, GError **error); }; struct _GntFileSelClass @@ -52,6 +55,20 @@ void (*gnt_reserved4)(void); }; +typedef enum _GntFileType +{ + GNT_FILE_REGULAR, + GNT_FILE_DIR +} GntFileType; + +struct _GntFile +{ + char *fullpath; + char *basename; + GntFileType type; + unsigned long size; +}; + G_BEGIN_DECLS GType gnt_file_sel_get_gtype(void); @@ -76,6 +93,12 @@ void gnt_file_sel_set_suggested_filename(GntFileSel *sel, const char *suggest); +void gnt_file_sel_set_read_fn(GntFileSel *sel, gboolean (*read_fn)(const char *path, GList **files, GError **error)); + +GntFile* gnt_file_new(const char *name, unsigned long size); + +GntFile* gnt_file_new_dir(const char *name); + G_END_DECLS #endif /* GNT_FILE_SEL_H */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |