Revision 8a20c90142cacba36041509da3a0e11499df3ebc
sadrul at pidgin.im
sadrul at pidgin.im
Sun Mar 25 21:08:49 EDT 2007
o -----------------------------------------------------------------
| Revision: 8a20c90142cacba36041509da3a0e11499df3ebc
| Ancestor: 0171cbace572ffa1be93217660f27fdba8b4f442
| Author: sadrul at pidgin.im
| Date: 2007-03-26T01:19:59
| Branch: im.pidgin.pidgin
|
| Modified files:
| finch/libgnt/gntfilesel.c finch/libgnt/gntfilesel.h
|
| ChangeLog:
|
| Allow selecting multiple files from the file-select dialog.
| You need to tag the files by pressing 't' to select the files. It is possible
| to tag files from different locations, ie. when you change the directory, the
| tags are remembered. You can untag a selection by pressing 't' again. To untag
| all selections, press 'c'.
|
| ============================================================
| --- finch/libgnt/gntfilesel.c a763f865174d67b465a1c9a6e11ab00042d1f734
| +++ finch/libgnt/gntfilesel.c c7efb481d2495dfbbf09e74d06bae247dcfd914c
| @@ -28,6 +28,10 @@ gnt_file_sel_destroy(GntWidget *widget)
| {
| GntFileSel *sel = GNT_FILE_SEL(widget);
| g_free(sel->current);
| + if (sel->tags) {
| + g_list_foreach(sel->tags, (GFunc)g_free, NULL);
| + g_list_free(sel->tags);
| + }
| }
|
| static char *
| @@ -73,6 +77,15 @@ static gboolean
| }
|
| 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 +122,19 @@ location_changed(GntFileSel *sel, GError
| 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 +148,6 @@ dir_key_pressed(GntTree *tree, const cha
| 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);
| @@ -225,7 +241,7 @@ gnt_file_sel_map(GntWidget *widget)
|
| 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 +269,64 @@ gnt_file_sel_map(GntWidget *widget)
| 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);
| + }
| +
| + 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 +341,9 @@ gnt_file_sel_class_init(GntFileSelClass
| 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;
| @@ -395,3 +469,26 @@ gboolean gnt_file_sel_get_must_exist(Gnt
| 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;
| +}
| +
| ============================================================
| --- finch/libgnt/gntfilesel.h f33327202ef7fe9347106527f3f4b2f2f368c31d
| +++ finch/libgnt/gntfilesel.h f98947e5d0bd0bbb2c1a36818486446e3e7a58f5
| @@ -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;
|
| @@ -36,9 +36,11 @@ struct _GnFileSel
| /* 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;
|
| @@ -57,8 +59,6 @@ gboolean gnt_file_sel_set_current_locati
|
| 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 +69,10 @@ char *gnt_file_sel_get_selected_file(Gnt
|
| 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);
| +
| G_END_DECLS
|
| #endif /* GNT_FILE_SEL_H */
To get the patch for this revision, please do this:
mtn log --last 1 --diffs --from 8a20c90142cacba36041509da3a0e11499df3ebc
More information about the Commits
mailing list