diff options
Diffstat (limited to 'baobab/src/baobab-treeview.c')
-rw-r--r-- | baobab/src/baobab-treeview.c | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/baobab/src/baobab-treeview.c b/baobab/src/baobab-treeview.c new file mode 100644 index 00000000..2a3aad3f --- /dev/null +++ b/baobab/src/baobab-treeview.c @@ -0,0 +1,336 @@ +/* + * baobab-treeview.c + * This file is part of baobab + * + * Copyright (C) 2005-2006 Fabio Marzocca <[email protected]> + * + * 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 <gtk/gtk.h> +#include <glib.h> +#include <glib/gprintf.h> +#include <glib/gi18n.h> +#include <string.h> + +#include "baobab.h" +#include "baobab-treeview.h" +#include "baobab-cell-renderer-progress.h" +#include "baobab-utils.h" +#include "callbacks.h" + +static GtkTreeStore * +create_model (void) +{ + GtkTreeStore *mdl = gtk_tree_store_new (NUM_TREE_COLUMNS, + G_TYPE_STRING, /* COL_DIR_NAME */ + G_TYPE_STRING, /* COL_H_PARSENAME */ + G_TYPE_DOUBLE, /* COL_H_PERC */ + G_TYPE_STRING, /* COL_DIR_SIZE */ + G_TYPE_UINT64, /* COL_H_SIZE */ + G_TYPE_UINT64, /* COL_H_ALLOCSIZE */ + G_TYPE_STRING, /* COL_ELEMENTS */ + G_TYPE_INT, /* COL_H_ELEMENTS */ + G_TYPE_STRING, /* COL_HARDLINK */ + G_TYPE_UINT64 /* COL_H_HARDLINK */ + ); + + return mdl; +} + +static void +on_tv_row_expanded (GtkTreeView *treeview, + GtkTreeIter *arg1, + GtkTreePath *arg2, + gpointer data) +{ + gtk_tree_view_columns_autosize (treeview); +} + +static void +on_tv_cur_changed (GtkTreeView *treeview, gpointer data) +{ + GtkTreeIter iter; + gchar *parsename = NULL; + + gtk_tree_selection_get_selected (gtk_tree_view_get_selection (treeview), NULL, &iter); + + if (gtk_tree_store_iter_is_valid (baobab.model, &iter)) { + gtk_tree_model_get (GTK_TREE_MODEL (baobab.model), &iter, + COL_H_PARSENAME, &parsename, -1); + } +} + +static void +contents_changed (void) +{ + if (messageyesno (_("Rescan your home folder?"), + _("The content of your home folder has changed. Select rescan to update the disk usage details."), + GTK_MESSAGE_QUESTION, _("_Rescan"), baobab.window) == GTK_RESPONSE_OK) { + baobab_rescan_current_dir (); + } + else { + /* Just update the total */ + baobab_update_filesystem (); + } +} + +static gboolean +on_tv_button_press (GtkWidget *widget, + GdkEventButton *event, + gpointer data) +{ + GtkTreePath *path; + GtkTreeIter iter; + GFile *file; + + gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), + event->x, event->y, + &path, NULL, NULL, NULL); + if (!path) + return TRUE; + + /* get the selected path */ + g_free (baobab.selected_path); + gtk_tree_model_get_iter (GTK_TREE_MODEL (baobab.model), &iter, + path); + gtk_tree_model_get (GTK_TREE_MODEL (baobab.model), &iter, + COL_H_PARSENAME, &baobab.selected_path, -1); + + file = g_file_parse_name (baobab.selected_path); + + if (baobab.CONTENTS_CHANGED_DELAYED) { + GFile *home_file; + + home_file = g_file_new_for_path (g_get_home_dir ()); + if (g_file_has_prefix (file, home_file)) { + baobab.CONTENTS_CHANGED_DELAYED = FALSE; + if (baobab.STOP_SCANNING) { + contents_changed (); + } + } + g_object_unref (home_file); + } + + /* right-click */ + if (event->button == 3) { + + if (g_file_query_exists (file, NULL)) { + popupmenu_list (path, event, can_trash_file (file)); + } + } + + gtk_tree_path_free (path); + g_object_unref (file); + + return FALSE; +} + +static gboolean +baobab_treeview_equal_func (GtkTreeModel *model, + gint column, + const gchar *key, + GtkTreeIter *iter, + gpointer data) +{ + gboolean results = TRUE; + gchar *name; + + gtk_tree_model_get (model, iter, 1, &name, -1); + + if (name != NULL) { + gchar * casefold_key; + gchar * casefold_name; + + casefold_key = g_utf8_casefold (key, -1); + casefold_name = g_utf8_casefold (name, -1); + + if ((casefold_key != NULL) && + (casefold_name != NULL) && + (strstr (casefold_name, casefold_key) != NULL)) { + results = FALSE; + } + g_free (casefold_key); + g_free (casefold_name); + g_free (name); + } + return results; +} + +static void +perc_cell_data_func (GtkTreeViewColumn *col, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data) +{ + gdouble perc; + gchar textperc[10]; + + gtk_tree_model_get (model, iter, COL_H_PERC, &perc, -1); + + if (perc < 0) + strcpy (textperc, "-.- %"); + else if (perc == 100.0) + strcpy (textperc, "100 %"); + else + g_sprintf (textperc, " %.1f %%", perc); + + g_object_set (renderer, "text", textperc, NULL); +} + +GtkWidget * +create_directory_treeview (void) +{ + GtkCellRenderer *cell; + GtkTreeViewColumn *col; + GtkWidget *scrolled; + + GtkWidget *tvw = GTK_WIDGET (gtk_builder_get_object (baobab.main_ui, "treeview1")); + + g_signal_connect (tvw, "row-expanded", + G_CALLBACK (on_tv_row_expanded), NULL); + g_signal_connect (tvw, "cursor-changed", + G_CALLBACK (on_tv_cur_changed), NULL); + g_signal_connect (tvw, "button-press-event", + G_CALLBACK (on_tv_button_press), NULL); + + /* dir name column */ + g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (tvw)), "changed", + G_CALLBACK (on_tv_selection_changed), NULL); + cell = gtk_cell_renderer_text_new (); + col = gtk_tree_view_column_new_with_attributes (NULL, cell, "markup", + COL_DIR_NAME, "text", + COL_DIR_NAME, NULL); + gtk_tree_view_column_set_sort_column_id (col, COL_DIR_NAME); + gtk_tree_view_column_set_reorderable (col, TRUE); + gtk_tree_view_column_set_title (col, _("Folder")); + gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_column_set_resizable (col, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (tvw), col); + + /* percentage bar & text column */ + col = gtk_tree_view_column_new (); + + cell = baobab_cell_renderer_progress_new (); + gtk_tree_view_column_pack_start (col, cell, FALSE); + gtk_tree_view_column_set_attributes (col, cell, "perc", + COL_H_PERC, NULL); + + cell = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (col, cell, TRUE); + gtk_tree_view_column_set_cell_data_func (col, cell, + perc_cell_data_func, + NULL, NULL); + + g_object_set (G_OBJECT (cell), "xalign", (gfloat) 1.0, NULL); + gtk_tree_view_column_set_sort_column_id (col, COL_H_PERC); + gtk_tree_view_column_set_reorderable (col, TRUE); + gtk_tree_view_column_set_title (col, _("Usage")); + gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_column_set_resizable (col, FALSE); + gtk_tree_view_append_column (GTK_TREE_VIEW (tvw), col); + + /* directory size column */ + cell = gtk_cell_renderer_text_new (); + col = gtk_tree_view_column_new_with_attributes (NULL, cell, "markup", + COL_DIR_SIZE, "text", + COL_DIR_SIZE, NULL); + g_object_set (G_OBJECT (cell), "xalign", (gfloat) 1.0, NULL); + gtk_tree_view_column_set_sort_column_id (col, + baobab.show_allocated ? COL_H_ALLOCSIZE : COL_H_SIZE); + gtk_tree_view_column_set_reorderable (col, TRUE); + gtk_tree_view_column_set_title (col, _("Size")); + gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_column_set_resizable (col, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (tvw), col); + + /* store this column, we need it when toggling 'allocated' */ + g_object_set_data (G_OBJECT (tvw), "baobab_size_col", col); + + /* objects column */ + cell = gtk_cell_renderer_text_new (); + col = gtk_tree_view_column_new_with_attributes (NULL, cell, "markup", + COL_ELEMENTS, "text", + COL_ELEMENTS, NULL); + g_object_set (G_OBJECT (cell), "xalign", (gfloat) 1.0, NULL); + gtk_tree_view_column_set_sort_column_id (col, COL_H_ELEMENTS); + gtk_tree_view_column_set_reorderable (col, TRUE); + gtk_tree_view_column_set_title (col, _("Contents")); + gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_column_set_resizable (col, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (tvw), col); + + /* hardlink column */ + cell = gtk_cell_renderer_text_new (); + col = gtk_tree_view_column_new_with_attributes (NULL, cell, "markup", + COL_HARDLINK, "text", + COL_HARDLINK, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tvw), col); + + gtk_tree_view_collapse_all (GTK_TREE_VIEW (tvw)); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tvw), FALSE); + scrolled = GTK_WIDGET (gtk_builder_get_object (baobab.main_ui, "scrolledwindow1")); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (tvw), + baobab_treeview_equal_func, + NULL, NULL); + + baobab.model = create_model (); + + /* By default, sort by size */ + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (baobab.model), + baobab.show_allocated ? COL_H_ALLOCSIZE : COL_H_SIZE, + GTK_SORT_DESCENDING); + + gtk_tree_view_set_model (GTK_TREE_VIEW (tvw), + GTK_TREE_MODEL (baobab.model)); + g_object_unref (baobab.model); + + return tvw; +} + +void +baobab_treeview_show_allocated_size (GtkWidget *tv, + gboolean show_allocated) +{ + gint sort_id; + gint new_sort_id; + GtkSortType order; + GtkTreeViewColumn *size_col; + + g_return_if_fail (GTK_IS_TREE_VIEW (tv)); + + gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (baobab.model), + &sort_id, &order); + + /* set the sort id for the size column */ + size_col = g_object_get_data (G_OBJECT (tv), "baobab_size_col"); + new_sort_id = show_allocated ? COL_H_ALLOCSIZE : COL_H_SIZE; + gtk_tree_view_column_set_sort_column_id (size_col, new_sort_id); + + /* if we are currently sorted on size or allocated size, + * then trigger a resort (with the same order) */ + if (sort_id == COL_H_SIZE || sort_id == COL_H_ALLOCSIZE) { + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (baobab.model), + new_sort_id, order); + } +} |