Guifications - The notification plugin to end all notification plugins! Copyright (C) 2003 Gary Kramlich 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "grimdirtreeview.h" /* folder icons taken from galeon */ static const char * folder_xpm[] = { static const char * folder_open_xpm[] = { static void grim_dir_tree_view_class_init(GrimDirTreeViewClass *klass); static void grim_dir_tree_view_init(GrimDirTreeView *dir_tree_view); static void add_dir(GtkTreeStore *store, GtkTreeIter *parent, gchar *parent_path, gchar *child_path); static void expand_cb(GrimDirTreeView *dir_tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer data); static void collapse_cb(GrimDirTreeView *dir_tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer data); static void add_root_node(GrimDirTreeView *dir_tree_view); static gboolean has_subdir(gchar *path); grim_dir_tree_view_get_type (void) { static GType dir_tree_view_type = 0; if (!dir_tree_view_type) { static const GTypeInfo dir_tree_view_type_info = { sizeof (GrimDirTreeViewClass), NULL, /* base_finalize */ (GClassInitFunc) grim_dir_tree_view_class_init, NULL, /* class_finalize */ sizeof (GrimDirTreeView), (GInstanceInitFunc) grim_dir_tree_view_init, dir_tree_view_type = g_type_register_static(GTK_TYPE_TREE_VIEW, &dir_tree_view_type_info, return dir_tree_view_type; grim_dir_tree_view_class_init(GrimDirTreeViewClass *klass) { grim_dir_tree_view_init(GrimDirTreeView *dir_tree_view) { GtkTreeViewColumn *directory; GtkCellRenderer *renderer; /* initialize variables */ dir_tree_view->store = gtk_tree_store_new(DIR_COL_COUNT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); add_root_node(dir_tree_view); /* set globals for tree view */ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(dir_tree_view), FALSE); /* create and add the directory column to the tree view */ directory = gtk_tree_view_column_new(); //gtk_tree_view_column_set_alignment(directory, 0); gtk_tree_view_append_column(GTK_TREE_VIEW(&dir_tree_view->tree_view), directory); /* create and pack the cell renderer(s) */ renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(directory, renderer, FALSE); gtk_tree_view_column_add_attribute(directory, renderer, "pixbuf", DIR_COL_ICON); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(directory, renderer, FALSE); gtk_tree_view_column_add_attribute(directory, renderer, "text", DIR_COL_TEXT); g_signal_connect(G_OBJECT(dir_tree_view), "row_expanded", G_CALLBACK(expand_cb), NULL); g_signal_connect(G_OBJECT(dir_tree_view), "row_collapsed", G_CALLBACK(collapse_cb), NULL); /* attach the store to the tree view */ gtk_tree_view_set_model(GTK_TREE_VIEW(&dir_tree_view->tree_view), GTK_TREE_MODEL(dir_tree_view->store)); has_subdir(gchar *path) { if (g_path_is_absolute(path)) { if ((directory = g_dir_open(path, 0, FALSE)) != NULL) { while ((name = g_strdup(g_dir_read_name(directory))) != NULL) { /* add check for show hidden when I add the property */ new_path = g_strconcat(path, name, NULL); new_path = g_strdup(name); if (g_file_test(new_path, G_FILE_TEST_IS_DIR)) { add_dir(GtkTreeStore *store, GtkTreeIter *parent, gchar *parent_path, gchar *child_path) { GtkTreeIter current, child; /* tweak when show hidden property is added */ if (child_path[0] == '.') pixbuf = gdk_pixbuf_new_from_xpm_data(folder_xpm); new_path = g_strconcat(parent_path, child_path, G_DIR_SEPARATOR_S, NULL); if (g_ascii_strcasecmp(child_path, G_DIR_SEPARATOR_S) == 0) new_path = g_strdup(child_path); new_path = g_strconcat(child_path, G_DIR_SEPARATOR_S, NULL); if (g_file_test(new_path, G_FILE_TEST_IS_DIR)) { gtk_tree_store_append(store, ¤t, parent); gtk_tree_store_set(store, ¤t, DIR_COL_ICON, pixbuf, DIR_COL_TEXT, child_path, DIR_COL_PATH, new_path, -1); if (has_subdir(new_path)) { gtk_tree_store_append(store, &child, ¤t); gtk_tree_store_set(store, &child, DIR_COL_TEXT, "", DIR_COL_PATH, NULL, -1); expand_cb(GrimDirTreeView *dir_tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer data) { GtkTreeSortable *sortable; gchar *dir_path, *child_path = NULL; gtk_tree_model_get(GTK_TREE_MODEL(dir_tree_view->store), iter, DIR_COL_PATH, &dir_path, -1); pixbuf = gdk_pixbuf_new_from_xpm_data(folder_open_xpm); gtk_tree_store_set(dir_tree_view->store, iter, DIR_COL_ICON, pixbuf, -1); if (gtk_tree_model_iter_children(GTK_TREE_MODEL(dir_tree_view->store), &child, iter)) { gtk_tree_model_get(GTK_TREE_MODEL(dir_tree_view->store), &child, DIR_COL_PATH, &child_path); if (child_path == NULL) { if ((directory = g_dir_open(dir_path, 0, NULL)) != NULL) { cursor = gdk_cursor_new(GDK_WATCH); if (!GTK_WIDGET_REALIZED(dir_tree_view)) gtk_widget_realize(GTK_WIDGET(dir_tree_view)); gdk_window_set_cursor(GTK_WIDGET(dir_tree_view)->window, cursor); while ((name = g_strdup(g_dir_read_name(directory))) != NULL) { add_dir(dir_tree_view->store, iter, dir_path, name); gdk_window_set_cursor(GTK_WIDGET(dir_tree_view)->window, NULL); gdk_cursor_unref(cursor); gtk_tree_store_remove(dir_tree_view->store, &child); sortable = GTK_TREE_SORTABLE(dir_tree_view->store); gtk_tree_sortable_set_sort_column_id(sortable, DIR_COL_TEXT, GTK_SORT_ASCENDING); collapse_cb(GrimDirTreeView *dir_tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer data) { GtkTreeIter holder, child; pixbuf = gdk_pixbuf_new_from_xpm_data(folder_xpm); gtk_tree_store_set(dir_tree_view->store, iter, DIR_COL_ICON, pixbuf, -1); count = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(dir_tree_view->store), iter); gtk_tree_store_append(dir_tree_view->store, &holder, iter); gtk_tree_store_set(dir_tree_view->store, &holder, DIR_COL_PATH, NULL, -1); for (i = 0; i < count; i++) { gtk_tree_model_iter_children(GTK_TREE_MODEL(dir_tree_view->store), &child, iter); gtk_tree_store_remove(dir_tree_view->store, &child); grim_dir_tree_view_new() { return GTK_WIDGET (g_object_new(grim_dir_tree_view_get_type(), NULL)); grim_dir_tree_view_get_path(GrimDirTreeView *dir_tree_view) { GtkTreeSelection *selection; gchar *path = NULL, *ret_path; selection = gtk_tree_view_get_selection(&dir_tree_view->tree_view); if (gtk_tree_selection_get_selected(selection, NULL, &selected)) { gtk_tree_model_get(GTK_TREE_MODEL(dir_tree_view->store), &selected, DIR_COL_PATH, &path, -1); if (path[0] == path[1] && path[0] == G_DIR_SEPARATOR) ret_path = g_strdup(path); grim_dir_tree_view_set_path(GrimDirTreeView *dir_tree_view, const gchar *path) { GtkTreeSelection *selection; GtkTreeIter parent, child; gchar *search_path = NULL, *new_path = NULL, *child_path = NULL; directories = g_strsplit(path, G_DIR_SEPARATOR_S, 0); while (directories[dir] != NULL) { search_path = g_strdup(G_DIR_SEPARATOR_S); gtk_tree_model_get_iter_first(GTK_TREE_MODEL(dir_tree_view->store), &parent); tree_path = gtk_tree_model_get_path(GTK_TREE_MODEL(dir_tree_view->store), &parent); gtk_tree_view_expand_row(GTK_TREE_VIEW(dir_tree_view), tree_path, TRUE); gtk_tree_path_free(tree_path); new_path = g_strdup_printf("%s%s%s", search_path, directories[dir], G_DIR_SEPARATOR_S); if(gtk_tree_model_iter_children(GTK_TREE_MODEL(dir_tree_view->store), &child, &parent)) { search_path = g_strdup(new_path); gtk_tree_model_get(GTK_TREE_MODEL(dir_tree_view->store), &child, DIR_COL_PATH, &child_path, -1); if (g_ascii_strcasecmp(search_path, child_path) == 0) { if (g_ascii_strncasecmp(path, child_path, strlen(path)) != 0) { tree_path = gtk_tree_model_get_path(GTK_TREE_MODEL(dir_tree_view->store), &child); gtk_tree_view_expand_row(GTK_TREE_VIEW(dir_tree_view), tree_path, TRUE); gtk_tree_path_free(tree_path); if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(dir_tree_view->store), &child)) { gtk_widget_grab_focus(GTK_WIDGET(dir_tree_view)); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dir_tree_view)); gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_iter(selection, &child); grim_dir_tree_view_set_show_hidden(GrimDirTreeView *dir_tree_view, gboolean value) { dir_tree_view->show_hidden = value; path = grim_dir_tree_view_get_path(dir_tree_view); gtk_tree_store_clear(dir_tree_view->store); add_root_node(dir_tree_view); grim_dir_tree_view_get_show_hidden(GrimDirTreeView *dir_tree_view) { return dir_tree_view->show_hidden; add_root_node(GrimDirTreeView *dir_tree_view) { drives = GetLogicalDrives(); for (i = 0; i < 32; i++) { if ((drives & (int)exp2(i)) == exp2(i)) { drive = g_strdup_printf("%c:\\", 65 + i); add_dir(dir_tree_view->store, NULL, NULL, drive); add_dir(dir_tree_view->store, NULL, NULL, G_DIR_SEPARATOR_S);