/gnome-commander-1.2.8.15/src/gnome-cmd-file-list.cc
C++ | 2286 lines | 1644 code | 559 blank | 83 comment | 323 complexity | 27cae00865c551ce32bdea3728aef19c MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- GNOME Commander - A GNOME based file manager
- Copyright (C) 2001-2006 Marcus Bjurman
- Copyright (C) 2007-2011 Piotr Eljasiak
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- #include <config.h>
- #include <regex.h>
- #include "gnome-cmd-includes.h"
- #include "gnome-cmd-file-selector.h"
- #include "gnome-cmd-file-list.h"
- #include "gnome-cmd-file.h"
- #include "gnome-cmd-main-win.h"
- #include "utils.h"
- #include "gnome-cmd-data.h"
- #include "gnome-cmd-patternsel-dialog.h"
- #include "imageloader.h"
- #include "cap.h"
- #include "gnome-cmd-style.h"
- #include "gnome-cmd-file-popmenu.h"
- #include "gnome-cmd-rename-dialog.h"
- #include "gnome-cmd-chown-dialog.h"
- #include "gnome-cmd-chmod-dialog.h"
- #include "gnome-cmd-delete-dialog.h"
- #include "gnome-cmd-quicksearch-popup.h"
- #include "gnome-cmd-file-collection.h"
- #include "gnome-cmd-user-actions.h"
- #include "ls_colors.h"
- using namespace std;
- /* Controls if file-uris should be escaped for local files when drag-N-dropping
- * Setting this seems be more portable when dropping on old file-managers as gmc etc.
- */
- #define UNESCAPE_LOCAL_FILES
- /* The time (in ms) it takes from that the right mouse button is clicked on a file until
- * the popup menu appears when the right btn is used to select files.
- */
- #define POPUP_TIMEOUT 750
- enum
- {
- FILE_CLICKED, // A file in the list was clicked
- FILE_RELEASED, // A file in the list has been clicked and mouse button has been released
- LIST_CLICKED, // The file list widget was clicked
- EMPTY_SPACE_CLICKED, // The file list was clicked but not on a file
- FILES_CHANGED, // The visible content of the file list has changed (files have been: selected, created, deleted or modified)
- DIR_CHANGED, // The current directory has been changed
- LAST_SIGNAL
- };
- GtkTargetEntry drag_types [] = {
- { TARGET_URI_LIST_TYPE, 0, TARGET_URI_LIST },
- { TARGET_TEXT_PLAIN_TYPE, 0, TARGET_TEXT_PLAIN },
- { TARGET_URL_TYPE, 0, TARGET_URL }
- };
- static GnomeCmdCListClass *parent_class = NULL;
- static guint file_list_signals[LAST_SIGNAL] = { 0 };
- struct GnomeCmdFileListColumn
- {
- guint id;
- const gchar *title;
- guint default_width;
- GtkJustification justification;
- GtkSortType default_sort_direction;
- GCompareDataFunc sort_func;
- };
- static gint sort_by_name (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl);
- static gint sort_by_ext (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl);
- static gint sort_by_dir (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl);
- static gint sort_by_size (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl);
- static gint sort_by_date (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl);
- static gint sort_by_perm (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl);
- static gint sort_by_owner (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl);
- static gint sort_by_group (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl);
- GnomeCmdFileListColumn file_list_column[GnomeCmdFileList::NUM_COLUMNS] =
- {{GnomeCmdFileList::COLUMN_ICON,"",16,GTK_JUSTIFY_CENTER,GTK_SORT_ASCENDING, NULL},
- {GnomeCmdFileList::COLUMN_NAME, N_("name"), 140, GTK_JUSTIFY_LEFT, GTK_SORT_ASCENDING, (GCompareDataFunc) sort_by_name},
- {GnomeCmdFileList::COLUMN_EXT, N_("ext"), 40, GTK_JUSTIFY_LEFT, GTK_SORT_ASCENDING, (GCompareDataFunc) sort_by_ext},
- {GnomeCmdFileList::COLUMN_DIR, N_("dir"), 240, GTK_JUSTIFY_LEFT, GTK_SORT_ASCENDING, (GCompareDataFunc) sort_by_dir},
- {GnomeCmdFileList::COLUMN_SIZE, N_("size"), 70, GTK_JUSTIFY_RIGHT, GTK_SORT_DESCENDING, (GCompareDataFunc) sort_by_size},
- {GnomeCmdFileList::COLUMN_DATE, N_("date"), 150, GTK_JUSTIFY_LEFT, GTK_SORT_DESCENDING, (GCompareDataFunc) sort_by_date},
- {GnomeCmdFileList::COLUMN_PERM, N_("perm"), 70, GTK_JUSTIFY_LEFT, GTK_SORT_ASCENDING, (GCompareDataFunc) sort_by_perm},
- {GnomeCmdFileList::COLUMN_OWNER, N_("uid"), 50, GTK_JUSTIFY_LEFT, GTK_SORT_ASCENDING, (GCompareDataFunc) sort_by_owner},
- {GnomeCmdFileList::COLUMN_GROUP, N_("gid"), 50, GTK_JUSTIFY_LEFT, GTK_SORT_ASCENDING, (GCompareDataFunc) sort_by_group}};
- class GnomeCmdFileList::Private
- {
- public:
- GtkWidget *column_pixmaps[GnomeCmdFileList::NUM_COLUMNS];
- GtkWidget *column_labels[GnomeCmdFileList::NUM_COLUMNS];
- GtkWidget *popup_menu;
- gint cur_file;
- GnomeCmdFileCollection visible_files;
- GList *selected_files; // contains GnomeCmdFile pointers
- GCompareDataFunc sort_func;
- gint current_col;
- gboolean sort_raising[GnomeCmdFileList::NUM_COLUMNS];
- gboolean shift_down;
- gint shift_down_row;
- GnomeCmdFile *right_mb_down_file;
- gboolean right_mb_sel_state;
- guint right_mb_timeout_id;
- GtkWidget *selpat_dialog;
- GtkWidget *quicksearch_popup;
- gchar *focus_later;
- Private(GnomeCmdFileList *fl);
- ~Private();
- };
- GnomeCmdFileList::Private::Private(GnomeCmdFileList *fl)
- {
- selected_files = NULL;
- memset(column_pixmaps, NULL, sizeof(column_pixmaps));
- memset(column_labels, NULL, sizeof(column_labels));
- popup_menu = NULL;
- quicksearch_popup = NULL;
- selpat_dialog = NULL;
- focus_later = NULL;
- shift_down = FALSE;
- shift_down_row = 0;
- right_mb_sel_state = FALSE;
- right_mb_down_file = NULL;
- right_mb_timeout_id = 0;
- memset(sort_raising, FALSE, sizeof(sort_raising));
- gint col = COLUMN_NAME; // defaults,
- gboolean b = GTK_SORT_ASCENDING; // used when not set by gnome_cmd_data_get_sort_params()
- gnome_cmd_data_get_sort_params (fl, col, b);
- current_col = col;
- sort_raising[col] = b;
- sort_func = file_list_column[col].sort_func;
- for (gint i=0; i<NUM_COLUMNS; i++)
- gtk_clist_set_column_resizeable (*fl, i, TRUE);
- }
- GnomeCmdFileList::Private::~Private()
- {
- gnome_cmd_file_list_free (selected_files);
- }
- inline gchar *strip_extension (const gchar *fname)
- {
- gchar *s = g_strdup (fname);
- gchar *p = g_strrstr (s, ".");
- if (p && p != s)
- *p = '\0';
- return s;
- }
- struct FileFormatData
- {
- gchar *text[GnomeCmdFileList::NUM_COLUMNS];
- gchar *dpath;
- gchar *fname;
- gchar *fext;
- static gchar empty_string[];
- FileFormatData(GnomeCmdFile *f, gboolean tree_size);
- ~FileFormatData();
- };
- gchar FileFormatData::empty_string[] = "";
- inline FileFormatData::FileFormatData(GnomeCmdFile *f, gboolean tree_size)
- {
- // If the user wants a character instead of icon for filetype set it now
- if (gnome_cmd_data.layout == GNOME_CMD_LAYOUT_TEXT)
- text[GnomeCmdFileList::COLUMN_ICON] = (gchar *) gnome_cmd_file_get_type_string (f);
- else
- text[GnomeCmdFileList::COLUMN_ICON] = NULL;
- // Prepare the strings to show
- gchar *t1 = gnome_cmd_file_get_path (f);
- gchar *t2 = g_path_get_dirname (t1);
- dpath = get_utf8 (t2);
- g_free (t1);
- g_free (t2);
- if (gnome_cmd_data.ext_disp_mode == GNOME_CMD_EXT_DISP_STRIPPED
- && f->info->type == GNOME_VFS_FILE_TYPE_REGULAR)
- {
- gchar *t = strip_extension (gnome_cmd_file_get_name (f));
- fname = get_utf8 (t);
- g_free (t);
- }
- else
- fname = get_utf8 (gnome_cmd_file_get_name (f));
- if (gnome_cmd_data.ext_disp_mode != GNOME_CMD_EXT_DISP_WITH_FNAME)
- fext = get_utf8 (gnome_cmd_file_get_extension (f));
- else
- fext = NULL;
- //Set other file information
- text[GnomeCmdFileList::COLUMN_NAME] = fname;
- text[GnomeCmdFileList::COLUMN_EXT] = fext;
- text[GnomeCmdFileList::COLUMN_DIR] = dpath;
- text[GnomeCmdFileList::COLUMN_SIZE] = tree_size ? (gchar *) gnome_cmd_file_get_tree_size_as_str (f) :
- (gchar *) gnome_cmd_file_get_size (f);
- if (f->info->type != GNOME_VFS_FILE_TYPE_DIRECTORY || !f->is_dotdot)
- {
- text[GnomeCmdFileList::COLUMN_DATE] = (gchar *) gnome_cmd_file_get_mdate (f, FALSE);
- text[GnomeCmdFileList::COLUMN_PERM] = (gchar *) gnome_cmd_file_get_perm (f);
- text[GnomeCmdFileList::COLUMN_OWNER] = (gchar *) gnome_cmd_file_get_owner (f);
- text[GnomeCmdFileList::COLUMN_GROUP] = (gchar *) gnome_cmd_file_get_group (f);
- }
- else
- {
- text[GnomeCmdFileList::COLUMN_DATE] = empty_string;
- text[GnomeCmdFileList::COLUMN_PERM] = empty_string;
- text[GnomeCmdFileList::COLUMN_OWNER] = empty_string;
- text[GnomeCmdFileList::COLUMN_GROUP] = empty_string;
- }
- }
- inline FileFormatData::~FileFormatData()
- {
- g_free (dpath);
- g_free (fname);
- g_free (fext);
- }
- static void on_selpat_hide (GtkWidget *dialog, GnomeCmdFileList *fl)
- {
- fl->priv->selpat_dialog = NULL;
- }
- inline void show_selpat_dialog (GnomeCmdFileList *fl, gboolean mode)
- {
- if (fl->priv->selpat_dialog) return;
- GtkWidget *dialog = gnome_cmd_patternsel_dialog_new (fl, mode);
- gtk_widget_ref (dialog);
- gtk_signal_connect (GTK_OBJECT (dialog), "hide", GTK_SIGNAL_FUNC (on_selpat_hide), fl);
- gtk_widget_show (dialog);
- fl->priv->selpat_dialog = dialog;
- }
- // Given a GnomeFileList, returns the upper-left corner of the selected file
- static void get_focus_row_coordinates (GnomeCmdFileList *fl, gint &x, gint &y, gint &width, gint &height)
- {
- #define CELL_SPACING 1
- #define COLUMN_INSET 3
- gint x0, y0;
- gdk_window_get_origin (GTK_CLIST (fl)->clist_window, &x0, &y0);
- gint row = GTK_CLIST (fl)->focus_row;
- gint rowh = GTK_CLIST (fl)->row_height + CELL_SPACING;
- gint colx = GTK_CLIST (fl)->column[GnomeCmdFileList::COLUMN_NAME].area.x - COLUMN_INSET - CELL_SPACING;
- x = x0 + colx;
- y = y0 + row*rowh + GTK_CLIST (fl)->voffset;
- width = GTK_CLIST (fl)->column[GnomeCmdFileList::COLUMN_NAME].area.width + 2*COLUMN_INSET;
- if (gnome_cmd_data.ext_disp_mode != GNOME_CMD_EXT_DISP_BOTH)
- width += GTK_CLIST (fl)->column[GnomeCmdFileList::COLUMN_EXT].area.width + 2*COLUMN_INSET + CELL_SPACING;
- height = rowh + 2*CELL_SPACING;
- }
- inline void focus_file_at_row (GnomeCmdFileList *fl, gint row)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- GTK_CLIST (fl)->focus_row = row;
- gtk_clist_select_row (*fl, row, 0);
- fl->priv->cur_file = GTK_CLIST (fl)->focus_row;
- }
- static void on_quicksearch_popup_hide (GtkWidget *quicksearch_popup, GnomeCmdFileList *fl)
- {
- fl->priv->quicksearch_popup = NULL;
- }
- static void select_file (GnomeCmdFileList *fl, GnomeCmdFile *f)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- g_return_if_fail (f != NULL);
- g_return_if_fail (f->info != NULL);
- if (f->is_dotdot)
- return;
- gint row = fl->get_row_from_file(f);
- if (row == -1)
- return;
- if (!gnome_cmd_data.use_ls_colors)
- gtk_clist_set_row_style (*fl, row, row%2 ? alt_sel_list_style : sel_list_style);
- else
- {
- GnomeCmdColorTheme *colors = gnome_cmd_data_get_current_color_theme ();
- if (!colors->respect_theme)
- {
- gtk_clist_set_foreground (*fl, row, colors->sel_fg);
- gtk_clist_set_background (*fl, row, colors->sel_bg);
- }
- }
- if (g_list_index (fl->priv->selected_files, f) != -1)
- return;
- gnome_cmd_file_ref (f);
- fl->priv->selected_files = g_list_append (fl->priv->selected_files, f);
- gtk_signal_emit (*fl, file_list_signals[FILES_CHANGED]);
- }
- static void unselect_file (GnomeCmdFileList *fl, GnomeCmdFile *f)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- g_return_if_fail (f != NULL);
- gint row = fl->get_row_from_file(f);
- if (row == -1)
- return;
- if (g_list_index (fl->priv->selected_files, f) == -1)
- return;
- gnome_cmd_file_unref (f);
- fl->priv->selected_files = g_list_remove (fl->priv->selected_files, f);
- if (!gnome_cmd_data.use_ls_colors)
- gtk_clist_set_row_style (*fl, row, row%2 ? alt_list_style : list_style);
- else
- if (LsColor *col = ls_colors_get (f))
- {
- GnomeCmdColorTheme *colors = gnome_cmd_data_get_current_color_theme ();
- GdkColor *fg = col->fg ? col->fg : colors->norm_fg;
- GdkColor *bg = col->bg ? col->bg : colors->norm_bg;
- if (bg) gtk_clist_set_background (*fl, row, bg);
- if (fg) gtk_clist_set_foreground (*fl, row, fg);
- }
- gtk_signal_emit (*fl, file_list_signals[FILES_CHANGED]);
- }
- inline void toggle_file (GnomeCmdFileList *fl, GnomeCmdFile *f)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- g_return_if_fail (f != NULL);
- gint row = fl->get_row_from_file(f);
- if (row == -1)
- return;
- if (row < fl->priv->visible_files.size())
- if (g_list_index (fl->priv->selected_files, f) == -1)
- select_file (fl, f);
- else
- unselect_file (fl, f);
- }
- inline void select_file_at_row (GnomeCmdFileList *fl, gint row)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- fl->priv->cur_file = row;
- GnomeCmdFile *f = fl->get_file_at_row(row);
- if (f)
- select_file (fl, f);
- }
- inline void select_file_range (GnomeCmdFileList *fl, gint start_row, gint end_row)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- if (start_row > end_row)
- {
- gint i = start_row;
- start_row = end_row;
- end_row = i;
- }
- for (gint i=start_row; i<=end_row; i++)
- select_file_at_row (fl, i);
- }
- inline void toggle_file_at_row (GnomeCmdFileList *fl, gint row)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- fl->priv->cur_file = row;
- GnomeCmdFile *f = fl->get_file_at_row(row);
- if (f)
- toggle_file (fl, f);
- }
- inline void toggle_file_range (GnomeCmdFileList *fl, gint start_row, gint end_row)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- if (start_row > end_row)
- {
- gint i = start_row;
- start_row = end_row;
- end_row = i;
- }
- for (gint i=start_row; i<=end_row; i++)
- toggle_file_at_row (fl, i);
- }
- static void toggle_files_with_same_extension (GnomeCmdFileList *fl, gboolean select)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- GnomeCmdFile *f = fl->get_selected_file();
- if (!f) return;
- const gchar *ext1 = gnome_cmd_file_get_extension (f);
- if (!ext1) return;
- for (GList *tmp=fl->get_visible_files(); tmp; tmp=tmp->next)
- {
- GnomeCmdFile *f = (GnomeCmdFile *) tmp->data;
- if (f && f->info)
- {
- const gchar *ext2 = gnome_cmd_file_get_extension (f);
- if (ext2 && strcmp (ext1, ext2) == 0)
- {
- if (select)
- select_file (fl, f);
- else
- unselect_file (fl, f);
- }
- }
- }
- }
- inline void toggle_with_pattern (GnomeCmdFileList *fl, const gchar *pattern, gboolean case_sens, gboolean mode)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- Filter filter(pattern, case_sens, gnome_cmd_data.filter_type);
- for (GList *tmp=fl->get_visible_files(); tmp; tmp=tmp->next)
- {
- GnomeCmdFile *f = (GnomeCmdFile *) tmp->data;
- if (f && f->info)
- if (filter.match(f->info->name))
- {
- if (mode)
- select_file (fl, f);
- else
- unselect_file (fl, f);
- }
- }
- }
- void GnomeCmdFileList::create_column_titles()
- {
- gtk_clist_column_title_passive (*this, COLUMN_ICON);
- for (gint i=COLUMN_NAME; i<NUM_COLUMNS; i++)
- {
- GtkWidget *hbox, *pixmap;
- GdkPixmap *pm = IMAGE_get_pixmap (PIXMAP_FLIST_ARROW_BLANK);
- GdkBitmap *bm = IMAGE_get_mask (PIXMAP_FLIST_ARROW_BLANK);
- hbox = gtk_hbox_new (FALSE, 1);
- gtk_widget_ref (hbox);
- gtk_object_set_data_full (*this, "column-hbox", hbox, (GtkDestroyNotify) gtk_widget_unref);
- gtk_widget_show (hbox);
- priv->column_labels[i] = gtk_label_new (_(file_list_column[i].title));
- gtk_widget_ref (priv->column_labels[i]);
- gtk_object_set_data_full (*this, "column-label", priv->column_labels[i], (GtkDestroyNotify) gtk_widget_unref);
- gtk_widget_show (priv->column_labels[i]);
- gtk_box_pack_start (GTK_BOX (hbox), priv->column_labels[i], TRUE, TRUE, 0);
- pixmap = gtk_pixmap_new (pm, bm);
- gtk_widget_ref (pixmap);
- gtk_object_set_data_full (*this, "column-pixmap", pixmap, (GtkDestroyNotify) gtk_widget_unref);
- gtk_widget_show (pixmap);
- gtk_box_pack_start (GTK_BOX (hbox), pixmap, FALSE, FALSE, 0);
- priv->column_pixmaps[i] = pixmap;
- gtk_clist_set_column_widget (*this, i, hbox);
- }
- for (gint i=COLUMN_ICON; i<NUM_COLUMNS; i++)
- {
- gtk_clist_set_column_width (*this, i, gnome_cmd_data.fs_col_width[i]);
- gtk_clist_set_column_justification (*this, i, file_list_column[i].justification);
- }
- gtk_clist_column_titles_show (*this);
- }
- static void update_column_sort_arrows (GnomeCmdFileList *fl)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- for (gint i=GnomeCmdFileList::COLUMN_NAME; i<GnomeCmdFileList::NUM_COLUMNS; i++)
- {
- if (i != fl->priv->current_col)
- gtk_pixmap_set (GTK_PIXMAP (fl->priv->column_pixmaps[i]),
- IMAGE_get_pixmap (PIXMAP_FLIST_ARROW_BLANK),
- IMAGE_get_mask (PIXMAP_FLIST_ARROW_BLANK));
- else
- if (fl->priv->sort_raising[i])
- gtk_pixmap_set (GTK_PIXMAP (fl->priv->column_pixmaps[i]),
- IMAGE_get_pixmap (PIXMAP_FLIST_ARROW_UP),
- IMAGE_get_mask (PIXMAP_FLIST_ARROW_UP));
- else
- gtk_pixmap_set (GTK_PIXMAP (fl->priv->column_pixmaps[i]),
- IMAGE_get_pixmap (PIXMAP_FLIST_ARROW_DOWN),
- IMAGE_get_mask (PIXMAP_FLIST_ARROW_DOWN));
- }
- }
- /******************************************************
- * DnD functions
- **/
- static char *build_selected_file_list (GnomeCmdFileList *fl, int *file_list_len)
- {
- GList *sel_files = fl->get_selected_files();
- int listlen = g_list_length (sel_files);
- if (listlen > 1)
- {
- int total_len = 0;
- GList *uri_str_list = NULL;
- // create a list with the uri's of the selected files and calculate the total_length needed
- for (GList *tmp=sel_files; tmp; tmp=tmp->next)
- {
- GnomeCmdFile *f = (GnomeCmdFile *) tmp->data;
- const gchar *fn = NULL;
- gchar *uri_str;
- if (gnome_vfs_uri_is_local (gnome_cmd_file_get_uri (f)))
- {
- #ifdef UNESCAPE_LOCAL_FILES
- fn = gnome_vfs_unescape_string (gnome_cmd_file_get_uri_str (f), 0);
- #endif
- }
- if (!fn)
- fn = gnome_cmd_file_get_uri_str (f);
- uri_str = g_strdup_printf ("%s\r\n", fn);
- uri_str_list = g_list_append (uri_str_list, uri_str);
- total_len += strlen (uri_str);
- }
- // allocate memory
- total_len++;
- char *data, *copy;
- data = copy = (gchar *) g_malloc (total_len+1);
- // put the uri_str_list in the allocated memory
- for (GList *tmp=uri_str_list; tmp; tmp=tmp->next)
- {
- gchar *uri_str = (gchar *) tmp->data;
- strcpy (copy, uri_str);
- copy += strlen (uri_str);
- }
- g_list_foreach (uri_str_list, (GFunc) g_free, NULL);
- g_list_free (uri_str_list);
- data [total_len] = '\0';
- *file_list_len = total_len;
- return data;
- }
- else
- if (listlen == 1)
- {
- GnomeCmdFile *f = (GnomeCmdFile *) sel_files->data;
- char *uri_str = g_strdup (gnome_cmd_file_get_uri_str (f));
- *file_list_len = strlen (uri_str) + 1;
- return uri_str;
- }
- *file_list_len = 0;
- g_list_free (sel_files);
- return NULL;
- }
- static void drag_data_get (GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint32 time, GnomeCmdFileList *fl)
- {
- int len;
- GList *files;
- gchar *data = (gchar *) build_selected_file_list (fl, &len);
- if (!data) return;
- switch (info)
- {
- case TARGET_URI_LIST:
- case TARGET_TEXT_PLAIN:
- gtk_selection_data_set (selection_data, selection_data->target, 8, (const guchar *) data, len);
- break;
- case TARGET_URL:
- files = gnome_vfs_uri_list_parse (data);
- if (files)
- gtk_selection_data_set (selection_data, selection_data->target, 8, (const guchar *) files->data, strlen ((const char *) files->data));
- g_list_foreach (files, (GFunc) g_free, NULL);
- break;
- default:
- g_assert_not_reached ();
- }
- g_free (data);
- }
- inline void init_dnd (GnomeCmdFileList *fl)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- gtk_drag_source_set (*fl, GDK_BUTTON1_MASK, drag_types, G_N_ELEMENTS (drag_types),
- (GdkDragAction) (GDK_ACTION_LINK | GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_ASK | GDK_ACTION_DEFAULT));
- gtk_signal_connect (*fl, "drag-data-get", GTK_SIGNAL_FUNC (drag_data_get), fl);
- }
- static void popup_position_function (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
- {
- GnomeCmdFileList *fl = GNOME_CMD_FILE_LIST (user_data);
- gint unused_x, unused_w, unused_h;
- get_focus_row_coordinates (fl, unused_x, *y, unused_w, unused_h);
- }
- static void show_file_popup (GnomeCmdFileList *fl, GdkEventButton *event)
- {
- // create the popup menu
- GtkWidget *menu = gnome_cmd_file_popmenu_new (fl);
- if (!menu) return;
- gtk_widget_ref (menu);
- gtk_object_set_data_full (*fl, "file_popup_menu", menu, (GtkDestroyNotify) gtk_widget_unref);
- gnome_popup_menu_do_popup (menu, (GtkMenuPositionFunc) popup_position_function, fl, event, fl, NULL);
- }
- inline void show_file_popup_with_warp (GnomeCmdFileList *fl)
- {
- gint x, y, w, h;
- get_focus_row_coordinates (fl, x, y, w, h);
- //FIXME: Warp the pointer to x, y here
- show_file_popup (fl, NULL);
- }
- static gboolean on_right_mb_timeout (GnomeCmdFileList *fl)
- {
- GnomeCmdFile *focus_file = fl->get_focused_file();
- if (fl->priv->right_mb_down_file == focus_file)
- {
- select_file (fl, focus_file);
- show_file_popup (fl, NULL);
- return FALSE;
- }
- fl->priv->right_mb_down_file = focus_file;
- return TRUE;
- }
- /******************************************************
- * File sorting functions
- **/
- inline gint my_strcmp (const gchar *s1, const gchar *s2, gboolean raising)
- {
- int ret = strcmp (s1, s2);
- if (ret > 0)
- return raising ? -1 : 1;
- if (ret < 0)
- return raising ? 1 : -1;
- return ret;
- }
- inline gint my_intcmp (gint i1, gint i2, gboolean raising)
- {
- if (i1 > i2)
- return raising ? -1 : 1;
- if (i2 > i1)
- return raising ? 1 : -1;
- return 0;
- }
- inline gint my_filesizecmp (GnomeVFSFileSize i1, GnomeVFSFileSize i2, gboolean raising)
- {
- if (i1 > i2)
- return raising ? -1 : 1;
- if (i2 > i1)
- return raising ? 1 : -1;
- return 0;
- }
- static gint sort_by_name (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl)
- {
- if (f1->is_dotdot)
- return -1;
- if (f2->is_dotdot)
- return 1;
- if (f1->info->type > f2->info->type)
- return -1;
- if (f1->info->type < f2->info->type)
- return 1;
- gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
- return my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), raising);
- }
- static gint sort_by_ext (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl)
- {
- if (f1->is_dotdot)
- return -1;
- if (f2->is_dotdot)
- return 1;
- if (f1->info->type > f2->info->type)
- return -1;
- if (f1->info->type < f2->info->type)
- return 1;
- gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
- if (!gnome_cmd_file_get_extension (f1) && !gnome_cmd_file_get_extension (f2))
- return my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), fl->priv->sort_raising[1]);
- if (!gnome_cmd_file_get_extension (f1))
- return raising?1:-1;
- if (!gnome_cmd_file_get_extension (f2))
- return raising?-1:1;
- gint ret = my_strcmp (gnome_cmd_file_get_extension (f1), gnome_cmd_file_get_extension (f2), raising);
- return ret ? ret : my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), fl->priv->sort_raising[1]);
- }
- static gint sort_by_dir (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl)
- {
- if (f1->is_dotdot)
- return -1;
- if (f2->is_dotdot)
- return 1;
- if (f1->info->type > f2->info->type)
- return -1;
- if (f1->info->type < f2->info->type)
- return 1;
- // gchar *t1 = gnome_cmd_file_get_path (f1);
- // gchar *t2 = gnome_cmd_file_get_path (f2);
- // gchar *d1 = g_path_get_dirname (t1);
- // gchar *d2 = g_path_get_dirname (t2);
- gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
- // gint ret = my_strcmp (d1, d2, raising);
- // g_free (t1);
- // g_free (t2);
- // g_free (d1);
- // g_free (d2);
- // return ret;
- return my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), raising);
- }
- static gint sort_by_size (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl)
- {
- if (f1->is_dotdot)
- return -1;
- if (f2->is_dotdot)
- return 1;
- gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
- gboolean file_raising = fl->priv->sort_raising[1];
- gint ret = my_intcmp (f1->info->type, f2->info->type, TRUE);
- if (!ret)
- {
- ret = my_filesizecmp (f1->info->size, f2->info->size, raising);
- if (!ret)
- ret = my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), file_raising);
- }
- return ret;
- }
- static gint sort_by_perm (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl)
- {
- if (f1->is_dotdot)
- return -1;
- if (f2->is_dotdot)
- return 1;
- gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
- gboolean file_raising = fl->priv->sort_raising[1];
- gint ret = my_intcmp (f1->info->type, f2->info->type, TRUE);
- if (!ret)
- {
- ret = my_intcmp (f1->info->permissions, f2->info->permissions, raising);
- if (!ret)
- ret = my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), file_raising);
- }
- return ret;
- }
- static gint sort_by_date (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl)
- {
- if (f1->is_dotdot)
- return -1;
- if (f2->is_dotdot)
- return 1;
- gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
- gboolean file_raising = fl->priv->sort_raising[1];
- gint ret = my_intcmp (f1->info->type, f2->info->type, TRUE);
- if (!ret)
- {
- ret = my_intcmp (f1->info->mtime, f2->info->mtime, raising);
- if (!ret)
- ret = my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), file_raising);
- }
- return ret;
- }
- static gint sort_by_owner (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl)
- {
- if (f1->is_dotdot)
- return -1;
- if (f2->is_dotdot)
- return 1;
- gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
- gboolean file_raising = fl->priv->sort_raising[1];
- gint ret = my_intcmp (f1->info->type, f2->info->type, TRUE);
- if (!ret)
- {
- ret = my_intcmp (f1->info->uid, f2->info->uid, raising);
- if (!ret)
- ret = my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), file_raising);
- }
- return ret;
- }
- static gint sort_by_group (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *fl)
- {
- if (f1->is_dotdot)
- return -1;
- if (f2->is_dotdot)
- return 1;
- gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
- gboolean file_raising = fl->priv->sort_raising[1];
- gint ret = my_intcmp (f1->info->type, f2->info->type, TRUE);
- if (!ret)
- {
- ret = my_intcmp (f1->info->gid, f2->info->gid, raising);
- if (!ret)
- ret = my_strcmp (gnome_cmd_file_get_collation_fname (f1), gnome_cmd_file_get_collation_fname (f2), file_raising);
- }
- return ret;
- }
- /*******************************
- * Callbacks
- *******************************/
- static void on_column_clicked (GtkCList *list, gint col, GnomeCmdFileList *fl)
- {
- g_return_if_fail (GTK_IS_CLIST (list));
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- fl->priv->sort_raising[col] = fl->priv->current_col == col ? !fl->priv->sort_raising[col] :
- file_list_column[col].default_sort_direction;
- fl->priv->sort_func = file_list_column[col].sort_func;
- fl->priv->current_col = col;
- update_column_sort_arrows (fl);
- fl->sort();
- gnome_cmd_data_set_sort_params (fl, col, fl->priv->sort_raising[col]);
- }
- static void on_scroll_vertical (GtkCList *clist, GtkScrollType scroll_type, gfloat position, GnomeCmdFileList *fl)
- {
- g_return_if_fail (GTK_IS_CLIST (clist));
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- gint num_files = fl->size();
- if (fl->priv->shift_down)
- {
- int start_row = fl->priv->cur_file;
- int end_row = clist->focus_row;
- fl->priv->shift_down = FALSE;
- if (start_row < 0 || end_row < 0)
- return;
- switch (scroll_type)
- {
- case GTK_SCROLL_STEP_BACKWARD:
- case GTK_SCROLL_STEP_FORWARD:
- toggle_file_at_row (fl, start_row);
- break;
- case GTK_SCROLL_PAGE_BACKWARD:
- toggle_file_range (fl, start_row, end_row);
- if (clist->focus_row > 0)
- focus_file_at_row (fl, --clist->focus_row);
- break;
- case GTK_SCROLL_PAGE_FORWARD:
- toggle_file_range (fl, start_row, end_row);
- if (clist->focus_row < num_files - 1)
- focus_file_at_row (fl, ++clist->focus_row);
- break;
- default:
- toggle_file_range (fl, start_row, end_row);
- break;
- }
- }
- fl->priv->cur_file = clist->focus_row;
- }
- static gboolean on_button_press (GtkCList *clist, GdkEventButton *event, GnomeCmdFileList *fl)
- {
- g_return_val_if_fail (clist != NULL, FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
- g_return_val_if_fail (GNOME_CMD_IS_FILE_LIST (fl), FALSE);
- if (GTK_CLIST (fl)->clist_window != event->window)
- return FALSE;
- gtk_signal_emit (*fl, file_list_signals[LIST_CLICKED], event);
- gint row = gnome_cmd_clist_get_row (*fl, event->x, event->y);
- if (row < 0)
- {
- gtk_signal_emit (*fl, file_list_signals[EMPTY_SPACE_CLICKED], event);
- return FALSE;
- }
- GnomeCmdFile *f = fl->get_file_at_row(row);
- gtk_signal_emit (*fl, file_list_signals[FILE_CLICKED], f, event);
- gtk_signal_emit_stop_by_name (GTK_OBJECT (clist), "button-press-event");
- return TRUE;
- }
- inline gboolean mime_exec_file (GnomeCmdFile *f)
- {
- g_return_val_if_fail (GNOME_CMD_IS_FILE (f), FALSE);
- if (f->info->type == GNOME_VFS_FILE_TYPE_REGULAR)
- {
- mime_exec_single (f);
- return TRUE;
- }
- return FALSE;
- }
- static void on_file_clicked (GnomeCmdFileList *fl, GnomeCmdFile *f, GdkEventButton *event, gpointer data)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- g_return_if_fail (f != NULL);
- g_return_if_fail (event != NULL);
- fl->modifier_click = event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK);
- if (event->type == GDK_2BUTTON_PRESS && event->button == 1 && gnome_cmd_data.left_mouse_button_mode == GnomeCmdData::LEFT_BUTTON_OPENS_WITH_DOUBLE_CLICK)
- {
- mime_exec_file (f);
- }
- else
- if (event->type == GDK_BUTTON_PRESS && (event->button == 1 || event->button == 3))
- {
- gint prev_row = fl->priv->cur_file;
- gint row = fl->get_row_from_file(f);
- fl->select_row(row);
- gtk_widget_grab_focus (*fl);
- if (event->button == 1)
- {
- if (event->state & GDK_SHIFT_MASK)
- {
- select_file_range (fl, fl->priv->shift_down_row, row);
- }
- else
- if (event->state & GDK_CONTROL_MASK)
- {
- if (fl->priv->selected_files || gnome_cmd_data.left_mouse_button_mode == GnomeCmdData::LEFT_BUTTON_OPENS_WITH_SINGLE_CLICK)
- toggle_file_at_row (fl, row);
- else
- {
- if (prev_row!=row)
- select_file (fl, fl->get_file_at_row(prev_row));
- select_file_at_row (fl, row);
- }
- }
- }
- else
- if (event->button == 3)
- if (!f->is_dotdot)
- {
- if (gnome_cmd_data.right_mouse_button_mode == GnomeCmdData::RIGHT_BUTTON_SELECTS)
- {
- if (g_list_index (fl->priv->selected_files, f) == -1)
- {
- select_file (fl, f);
- fl->priv->right_mb_sel_state = 1;
- }
- else
- {
- unselect_file (fl, f);
- fl->priv->right_mb_sel_state = 0;
- }
- fl->priv->right_mb_down_file = f;
- fl->priv->right_mb_timeout_id =
- g_timeout_add (POPUP_TIMEOUT, (GSourceFunc) on_right_mb_timeout, fl);
- }
- else
- show_file_popup (fl, event);
- }
- }
- }
- static void on_file_released (GnomeCmdFileList *fl, GnomeCmdFile *f, GdkEventButton *event, gpointer data)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- g_return_if_fail (f != NULL);
- g_return_if_fail (event != NULL);
- if (event->type == GDK_BUTTON_RELEASE && event->button == 1 && !fl->modifier_click && gnome_cmd_data.left_mouse_button_mode == GnomeCmdData::LEFT_BUTTON_OPENS_WITH_SINGLE_CLICK)
- mime_exec_file (f);
- }
- static void on_motion_notify (GtkCList *clist, GdkEventMotion *event, GnomeCmdFileList *fl)
- {
- g_return_if_fail (event != NULL);
- if (event->state & GDK_BUTTON3_MASK)
- {
- gint row;
- gint y;
- y = event->y;
- y -= (clist->column_title_area.height - GTK_CONTAINER (clist)->border_width);
- row = gnome_cmd_clist_get_row (*fl, event->x, y);
- if (row != -1)
- {
- GnomeCmdFile *f = fl->get_file_at_row(row+1);
- if (f)
- {
- fl->select_row(row+1);
- if (fl->priv->right_mb_sel_state)
- select_file (fl, f);
- else
- unselect_file (fl, f);
- }
- }
- }
- }
- static gint on_button_release (GtkWidget *widget, GdkEventButton *event, GnomeCmdFileList *fl)
- {
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
- g_return_val_if_fail (GNOME_CMD_IS_FILE_LIST (fl), FALSE);
- if (GTK_CLIST (fl)->clist_window != event->window)
- return FALSE;
- gint row = gnome_cmd_clist_get_row (*fl, event->x, event->y);
- if (row < 0)
- return FALSE;
- GnomeCmdFile *f = fl->get_file_at_row(row);
- gtk_signal_emit (*fl, file_list_signals[FILE_RELEASED], f, event);
- if (event->type == GDK_BUTTON_RELEASE)
- {
- if (event->button == 1 && state_is_blank (event->state))
- {
- if (f && g_list_index (fl->priv->selected_files, f)==-1 && gnome_cmd_data.left_mouse_button_unselects)
- fl->unselect_all();
- return TRUE;
- }
- else
- if (event->button == 3)
- g_source_remove (fl->priv->right_mb_timeout_id);
- }
- return FALSE;
- }
- static void on_realize (GnomeCmdFileList *fl, gpointer user_data)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
- update_column_sort_arrows (fl);
- fl->realized = TRUE;
- }
- /*******************************
- * Gtk class implementation
- *******************************/
- static void destroy (GtkObject *object)
- {
- GnomeCmdFileList *fl = GNOME_CMD_FILE_LIST (object);
- delete fl->priv;
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
- }
- static void map (GtkWidget *widget)
- {
- if (GTK_WIDGET_CLASS (parent_class)->map != NULL)
- GTK_WIDGET_CLASS (parent_class)->map (widget);
- }
- static void class_init (GnomeCmdFileListClass *klass)
- {
- GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- parent_class = (GnomeCmdCListClass *) gtk_type_class (gnome_cmd_clist_get_type ());
- file_list_signals[FILE_CLICKED] =
- gtk_signal_new ("file-clicked",
- GTK_RUN_LAST,
- G_OBJECT_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GnomeCmdFileListClass, file_clicked),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE,
- 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
- file_list_signals[FILE_RELEASED] =
- gtk_signal_new ("file-released",
- GTK_RUN_LAST,
- G_OBJECT_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GnomeCmdFileListClass, file_released),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE,
- 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
- file_list_signals[LIST_CLICKED] =
- gtk_signal_new ("list-clicked",
- GTK_RUN_LAST,
- G_OBJECT_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GnomeCmdFileListClass, list_clicked),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE,
- 1,
- GTK_TYPE_POINTER);
- file_list_signals[EMPTY_SPACE_CLICKED] =
- gtk_signal_new ("empty-space-clicked",
- GTK_RUN_LAST,
- G_OBJECT_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GnomeCmdFileListClass, empty_space_clicked),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE,
- 1, GTK_TYPE_POINTER);
- file_list_signals[FILES_CHANGED] =
- gtk_signal_new ("files-changed",
- GTK_RUN_LAST,
- G_OBJECT_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GnomeCmdFileListClass, files_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE,
- 0);
- file_list_signals[DIR_CHANGED] =
- gtk_signal_new ("dir-changed",
- GTK_RUN_LAST,
- G_OBJECT_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GnomeCmdFileListClass, dir_changed),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE,
- 1, GTK_TYPE_POINTER);
- object_class->destroy = destroy;
- widget_class->map = ::map;
- klass->file_clicked = NULL;
- klass->file_released = NULL;
- klass->list_clicked = NULL;
- klass->files_changed = NULL;
- klass->dir_changed = NULL;
- }
- static void init (GnomeCmdFileList *fl)
- {
- fl->priv = new GnomeCmdFileList::Private(fl);
- init_dnd (fl);
- gtk_signal_connect_after (*fl, "scroll-vertical", GTK_SIGNAL_FUNC (on_scroll_vertical), fl);
- gtk_signal_connect (*fl, "click-column", GTK_SIGNAL_FUNC (on_column_clicked), fl);
- gtk_signal_connect (*fl, "button-press-event", GTK_SIGNAL_FUNC (on_button_press), fl);
- gtk_signal_connect (*fl, "button-release-event", GTK_SIGNAL_FUNC (on_button_release), fl);
- gtk_signal_connect (*fl, "motion-notify-event", GTK_SIGNAL_FUNC (on_motion_notify), fl);
- gtk_signal_connect_after (*fl, "realize", GTK_SIGNAL_FUNC (on_realize), fl);
- gtk_signal_connect (*fl, "file-clicked", GTK_SIGNAL_FUNC (on_file_clicked), fl);
- gtk_signal_connect (*fl, "file-released", GTK_SIGNAL_FUNC (on_file_released), fl);
- }
- /***********************************
- * Public functions
- ***********************************/
- GtkType gnome_cmd_file_list_get_type ()
- {
- static GtkType type = 0;
- if (type == 0)
- {
- GtkTypeInfo info =
- {
- "GnomeCmdFileList",
- sizeof (GnomeCmdFileList),
- sizeof (GnomeCmdFileListClass),
- (GtkClassInitFunc) class_init,
- (GtkObjectInitFunc) init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL
- };
- type = gtk_type_unique (gnome_cmd_clist_get_type (), &info);
- }
- return type;
- }
- guint GnomeCmdFileList::get_column_default_width (GnomeCmdFileList::ColumnID col)
- {
- return file_list_column[col].default_width;
- }
- GnomeCmdFileList::ColumnID GnomeCmdFileList::get_sort_column()
- {
- return (ColumnID) priv->current_col;
- }
- inline void add_file_to_clist (GnomeCmdFileList *fl, GnomeCmdFile *f, gint in_row)
- {
- GtkCList *clist = GTK_CLIST (fl);
- FileFormatData data(f,FALSE);
- gint row = in_row == -1 ? gtk_clist_append (clist, data.text) : gtk_clist_insert (clist, in_row, data.text);
- // Setup row data and color
- if (!gnome_cmd_data.use_ls_colors)
- gtk_clist_set_row_style (clist, row, row%2 ? alt_list_style : list_style);
- else
- {
- LsColor *col = ls_colors_get (f);
- if (col)
- {
- if (col->bg)
- gtk_clist_set_background (clist, row, col->bg);
- if (col->fg)
- gtk_clist_set_foreground (clist, row, col->fg);
- }
- }
- gtk_clist_set_row_data (clist, row, f);
- // If the use wants icons to show file types set it now
- if (gnome_cmd_data.layout != GNOME_CMD_LAYOUT_TEXT)
- {
- gtk_clist_set_pixmap (clist, row, 0,
- gnome_cmd_file_get_type_pixmap (f),
- gnome_cmd_file_get_type_mask (f));
- }
- // If we have been waiting for this file to show up, focus it
- if (fl->priv->focus_later &&
- strcmp (gnome_cmd_file_get_name (f), fl->priv->focus_later) == 0)
- focus_file_at_row (fl, row);
- }
- /******************************************************************************
- *
- * Function: GnomeCmdFileList::append_file
- *
- * Purpose: Add a file to the list
- *
- * Params: @f: The file to add
- *
- * Returns:
- *
- * Statuses:
- *
- ******************************************************************************/
- void GnomeCmdFileList::append_file (GnomeCmdFile *f)
- {
- priv->visible_files.add(f);
- add_file_to_clist (this, f, -1);
- }
- gboolean GnomeCmdFileList::insert_file(GnomeCmdFile *f)
- {
- if (!file_is_wanted(f))
- return FALSE;
- gint num_files = size();
- for (gint i=0; i<num_files; i++)
- {
- GnomeCmdFile *f2 = get_file_at_row(i);
- if (priv->sort_func (f2, f, this) == 1)
- {
- priv->visible_files.add(f);
- add_file_to_clist (this, f, i);
- if (i<=priv->cur_file)
- priv->cur_file++;
- return TRUE;
- }
- }
- // Insert the file at the end of the list
- append_file(f);
- return TRUE;
- }
- void GnomeCmdFileList::show_files(GnomeCmdDir *dir)
- {
- remove_all_files();
- GList *list;
- GList *files = NULL;
- // select the files to show
- for (gnome_cmd_dir_get_files (dir, &list); list; list = list->next)
- {
- GnomeCmdFile *f = GNOME_CMD_FILE (list->data);
- if (file_is_wanted (f))
- files = g_list_append (files, f);
- }
- // Create a parent dir file (..) if appropriate
- gchar *path = gnome_cmd_file_get_path (GNOME_CMD_FILE (dir));
- if (path && strcmp (path, G_DIR_SEPARATOR_S) != 0)
- files = g_list_append (files, gnome_cmd_dir_new_parent_dir_file (dir));
- g_free (path);
- if (!files)
- return;
- files = g_list_sort_with_data (files, (GCompareDataFunc) priv->sort_func, this);
- gtk_clist_freeze (*this);
- for (GList *i = files; i; i = i->next)
- append_file(GNOME_CMD_FILE (i->data));
- gtk_clist_thaw (*this);
- if (files)
- g_list_free (files);
- }
- void GnomeCmdFileList::update_file(GnomeCmdFile *f)
- {
- if (!gnome_cmd_file_needs_update (f))
- return;
- gint row = get_row_from_file(f);
- if (row == -1)
- return;
- FileFormatData data(f, FALSE);
- for (gint i=1; i<GnomeCmdFileList::NUM_COLUMNS; i++)
- gtk_clist_set_text (*this, row, i, data.text[i]);
- if (gnome_cmd_data.layout != GNOME_CMD_LAYOUT_TEXT)
- {
- GdkPixmap *pixmap;
- GdkBitmap *mask;
- if (gnome_cmd_file_get_type_pixmap_and_mask (f, &pixmap, &mask))
- gtk_clist_set_pixmap (*this, row, 0, pixmap, mask);
- }
- }
- void GnomeCmdFileList::show_dir_tree_size(GnomeCmdFile *f)
- {
- g_return_if_fail (GNOME_CMD_IS_FILE (f));
- gint row = get_row_from_file(f);
- if (row == -1)
- return;
- FileFormatData data(f,TRUE);
- for (gint i=1; i<NUM_COLUMNS; i++)
- gtk_clist_set_text (*this, row, i, data.text[i]);
- }
- gboolean GnomeCmdFileList::remove_file(GnomeCmdFile *f)
- {
- g_return_val_if_fail (f != NULL, FALSE);
- gint row = get_row_from_file(f);
- if (row<0) // f not found in the shown file list...
- return FALSE;
- gtk_clist_remove (GTK_CLIST (this), row);
- priv->selected_files = g_list_remove (priv->selected_files, f);
- priv->visible_files.remove(f);
- if (gtk_widget_is_focus(*this))
- focus_file_at_row (this, MIN (row, GTK_CLIST (this)->focus_row));
- return TRUE;
- }
- gboolean GnomeCmdFileList::remove_file(const gchar *uri_str)
- {
- g_return_val_if_fail (uri_str != NULL, FALSE);
- return remove_file (priv->visible_files.find(uri_str));
- }
- void GnomeCmdFileList::clear()
- {
- gtk_clist_clear (GTK_CLIST (this));
- priv->visible_files.clear();
- gnome_cmd_file_list_free (priv->selected_files);
- priv->selected_files = NULL;
- }
- GList *GnomeCmdFileList::get_selected_files()
- {
- if (priv->selected_files)
- return g_list_copy (priv->selected_files);
- GnomeCmdFile *file = get_selected_file();
- return file ? g_list_append (NULL, file) : NULL;
- }
- GList *GnomeCmdFileList::get_marked_files()
- {
- return priv->selected_files;
- }
- GList *GnomeCmdFileList::get_visible_files()
- {
- return priv->visible_files.get_list();
- }
- GnomeCmdFile *GnomeCmdFileList::get_first_selected_file()
- {
- return priv->selected_files ? (GnomeCmdFile *) priv->selected_files->data : get_selected_file();
- }
- GnomeCmdFile *GnomeCmdFileList::get_focused_file()
- {
- return priv->cur_file < 0 ? NULL : get_file_at_row(priv->cur_file);
- }
- void GnomeCmdFileList::select_all()
- {
- gnome_cmd_file_list_free (priv->selected_files);
- priv->selected_files = NULL;
- for (GList *tmp = get_visible_files(); tmp; tmp = tmp->next)
- select_file (this, (GnomeCmdFile *) tmp->data);
- }
- void GnomeCmdFileList::unselect_all()
- {
- GList *selfiles = g_list_copy (priv->selected_files);
- for (GList *tmp = selfiles; tmp; tmp = tmp->next)
- unselect_file (this, (GnomeCmdFile *) tmp->data);
- g_list_free (selfiles);
- gnome_cmd_file_list_free (priv->selected_files);
- priv->selected_files = NULL;
- }
- void GnomeCmdFileList::toggle()
- {
- GnomeCmdFile *f = get_file_at_row(priv->cur_file);
- if (f)
- toggle_file (this, f);
- }
- void GnomeCmdFileList::toggle_and_step()
- {
- GnomeCmdFile *f = get_file_at_row(priv->cur_file);
- if (f)
- toggle_file (this, f);
- if (priv->cur_file < size()-1)
- focus_file_at_row (this, priv->cur_file+1);
- }
- void GnomeCmdFileList::focus_file(const gchar *focus_file, gboolean scroll_to_file)
- {
- for (GList *tmp = get_visible_files(); tmp; tmp = tmp->next)
- {
- GnomeCmdFile *f = (GnomeCmdFile *) tmp->data;
- g_return_if_fail (f != NULL);
- g_return_if_fail (f->info != NULL);
- gint row = get_row_from_file (f);
- if (row == -1)
- return;
- if (strcmp (f->info->name, focus_file) == 0)
- {
- priv->cur_file = row;
- focus_file_at_row (this, row);
- if (scroll_to_file)
- gtk_clist_moveto (*this, row, 0, 0, 0);
- return;
- }
- }
- /* The file was not found, remember the filename in …
Large files files are truncated, but you can click here to view the full file