aboutsummaryrefslogtreecommitdiffstats
path: root/shell/e-storage-set-view.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/e-storage-set-view.c')
-rw-r--r--shell/e-storage-set-view.c708
1 files changed, 312 insertions, 396 deletions
diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c
index ea7eb938ee..aa8bd141f5 100644
--- a/shell/e-storage-set-view.c
+++ b/shell/e-storage-set-view.c
@@ -19,6 +19,7 @@
* Boston, MA 02111-1307, USA.
*
* Author: Ettore Perazzoli
+ * Etree-ification: Chris Toshok
*/
#ifdef HAVE_CONFIG_H
@@ -32,40 +33,40 @@
#include "e-storage-set-view.h"
-
-#define PARENT_TYPE GTK_TYPE_CTREE
-static GtkCTreeClass *parent_class = NULL;
+#include "e-table/e-tree-simple.h"
+#include "e-table/e-cell-tree.h"
+#include "e-table/e-cell-text.h"
-struct _EStorageSetViewPrivate {
- EStorageSet *storage_set;
+#include "art/tree-expanded.xpm"
+#include "art/tree-unexpanded.xpm"
- /* These tables must always be kept in sync, and one cannot exist
- without the other, as they share the dynamically allocated path. */
- GHashTable *ctree_node_to_path;
- GHashTable *path_to_ctree_node;
+#define ETABLE_SPEC "<ETableSpecification no-header=\"1\"> \
+ <columns-shown> \
+ <column> 0 </column> \
+ </columns-shown> \
+ <grouping></grouping> \
+</ETableSpecification>"
- /* Path of the row selected by the latest "tree_select_row" signal. */
- const char *selected_row_path;
+
+#define PARENT_TYPE E_TABLE_TYPE
+static ETableClass *parent_class = NULL;
- /* Path of the row currently being dragged. */
- const char *dragged_row_path;
+struct _EStorageSetViewPrivate {
+ EStorageSet *storage_set;
- /* Path of the row that was selected before the latest click. */
- const char *selected_row_path_before_click;
+ ETreeModel *etree_model;
+ ETreePath *root_node;
+ GdkPixbuf *tree_expanded_pixbuf;
+ GdkPixbuf *tree_unexpanded_pixbuf;
- /* Whether we are currently performing a drag from this view. */
- int in_drag : 1;
+ GHashTable *path_to_etree_node;
- /* X/Y position for the last button click. */
- int button_x, button_y;
+ GHashTable *type_name_to_pixbuf;
- /* Button used for the drag. This is initialized in the `button_press_event'
- handler. */
- int drag_button;
+ /* Path of the row selected by the latest "cursor_change" signal. */
+ const char *selected_row_path;
};
-#define DRAG_RESISTANCE 3
-
enum {
FOLDER_SELECTED,
@@ -98,9 +99,9 @@ static GtkTargetList *target_list;
/* Helper functions. */
static gboolean
-add_node_to_hashes (EStorageSetView *storage_set_view,
- const char *path,
- GtkCTreeNode *node)
+add_node_to_hash (EStorageSetView *storage_set_view,
+ const char *path,
+ ETreePath *node)
{
EStorageSetViewPrivate *priv;
char *hash_path;
@@ -109,7 +110,7 @@ add_node_to_hashes (EStorageSetView *storage_set_view,
priv = storage_set_view->priv;
- if (g_hash_table_lookup (priv->path_to_ctree_node, path) != NULL) {
+ if (g_hash_table_lookup (priv->path_to_etree_node, path) != NULL) {
g_warning ("EStorageSetView: Node already existing while adding -- %s", path);
return FALSE;
}
@@ -118,23 +119,21 @@ add_node_to_hashes (EStorageSetView *storage_set_view,
hash_path = g_strdup (path);
- g_hash_table_insert (priv->path_to_ctree_node, hash_path, node);
- g_hash_table_insert (priv->ctree_node_to_path, node, hash_path);
+ g_hash_table_insert (priv->path_to_etree_node, hash_path, node);
return TRUE;
}
-static GtkCTreeNode *
-remove_node_from_hashes (EStorageSetView *storage_set_view,
- const char *path)
+static ETreePath *
+remove_node_from_hash (EStorageSetView *storage_set_view,
+ const char *path)
{
EStorageSetViewPrivate *priv;
- GtkCTreeNode *node;
- char *hash_path;
+ ETreePath *node;
priv = storage_set_view->priv;
- node = g_hash_table_lookup (priv->path_to_ctree_node, path);
+ node = g_hash_table_lookup (priv->path_to_etree_node, path);
if (node == NULL) {
g_warning ("EStorageSetView: Node not found while removing -- %s", path);
return NULL;
@@ -142,72 +141,56 @@ remove_node_from_hashes (EStorageSetView *storage_set_view,
g_print ("EStorageSetView: Removing -- %s\n", path);
- hash_path = g_hash_table_lookup (priv->ctree_node_to_path, node);
- g_free (hash_path);
-
- g_hash_table_remove (priv->ctree_node_to_path, node);
- g_hash_table_remove (priv->path_to_ctree_node, path);
+ g_hash_table_remove (priv->path_to_etree_node, path);
return node;
}
-static void
-get_pixmap_and_mask_for_folder (EStorageSetView *storage_set_view,
- EFolder *folder,
- GdkPixmap **pixmap_return,
- GdkBitmap **mask_return)
+static GdkPixbuf*
+get_pixbuf_for_folder (EStorageSetView *storage_set_view,
+ EFolder *folder)
{
- EFolderTypeRegistry *folder_type_registry;
- EStorageSet *storage_set;
- const char *type_name;
- GdkPixbuf *icon_pixbuf;
GdkPixbuf *scaled_pixbuf;
- GdkVisual *visual;
- GdkGC *gc;
-
- storage_set = storage_set_view->priv->storage_set;
- folder_type_registry = e_storage_set_get_folder_type_registry (storage_set);
+ const char *type_name;
+ EStorageSetViewPrivate *priv;
+ priv = storage_set_view->priv;
+
type_name = e_folder_get_type_string (folder);
- icon_pixbuf = e_folder_type_registry_get_icon_for_type (folder_type_registry,
- type_name, TRUE);
- if (icon_pixbuf == NULL) {
- *pixmap_return = NULL;
- *mask_return = NULL;
- return;
- }
+ scaled_pixbuf = g_hash_table_lookup (priv->type_name_to_pixbuf, type_name);
+
+ if (scaled_pixbuf == NULL) {
+ EFolderTypeRegistry *folder_type_registry;
+ EStorageSet *storage_set;
+ GdkPixbuf *icon_pixbuf;
- scaled_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (icon_pixbuf),
- gdk_pixbuf_get_has_alpha (icon_pixbuf),
- gdk_pixbuf_get_bits_per_sample (icon_pixbuf),
- E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE);
+ storage_set = priv->storage_set;
+ folder_type_registry = e_storage_set_get_folder_type_registry (storage_set);
- gdk_pixbuf_scale (icon_pixbuf, scaled_pixbuf,
- 0, 0, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
- 0.0, 0.0,
- (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_width (icon_pixbuf),
- (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_height (icon_pixbuf),
- GDK_INTERP_HYPER);
+ icon_pixbuf = e_folder_type_registry_get_icon_for_type (folder_type_registry,
+ type_name, TRUE);
- visual = gdk_rgb_get_visual ();
- *pixmap_return = gdk_pixmap_new (NULL,
- E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
- visual->depth);
+ if (icon_pixbuf == NULL) {
+ return NULL;
+ }
+
+ scaled_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (icon_pixbuf),
+ gdk_pixbuf_get_has_alpha (icon_pixbuf),
+ gdk_pixbuf_get_bits_per_sample (icon_pixbuf),
+ E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE);
- gc = gdk_gc_new (*pixmap_return);
- gdk_pixbuf_render_to_drawable (scaled_pixbuf, *pixmap_return, gc, 0, 0, 0, 0,
- E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
- GDK_RGB_DITHER_NORMAL, 0, 0);
- gdk_gc_unref (gc);
+ gdk_pixbuf_scale (icon_pixbuf, scaled_pixbuf,
+ 0, 0, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
+ 0.0, 0.0,
+ (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_width (icon_pixbuf),
+ (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_height (icon_pixbuf),
+ GDK_INTERP_HYPER);
- *mask_return = gdk_pixmap_new (NULL, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE, 1);
- gdk_pixbuf_render_threshold_alpha (scaled_pixbuf, *mask_return,
- 0, 0, 0, 0,
- E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE,
- 0x7f);
+ g_hash_table_insert (priv->type_name_to_pixbuf, g_strdup(type_name), scaled_pixbuf);
+ }
- gdk_pixbuf_unref (scaled_pixbuf);
+ return scaled_pixbuf;
}
@@ -228,10 +211,6 @@ folder_context_menu_activate_cb (BonoboUIHandler *uih,
gtk_signal_emit (GTK_OBJECT (storage_set_view), signals[FOLDER_SELECTED],
priv->selected_row_path);
-
- /* Make sure we don't restore the previously selected row after the
- menu is popped down. */
- priv->selected_row_path_before_click = NULL;
}
static void
@@ -290,183 +269,70 @@ popup_folder_menu (EStorageSetView *storage_set_view,
/* GtkObject methods. */
static void
-hash_foreach_free_path (gpointer key,
- gpointer value,
- gpointer data)
+path_free_func (gpointer key, gpointer value, gpointer user_data)
{
- g_free (value);
+ g_free (key);
}
static void
-destroy (GtkObject *object)
+pixbuf_free_func (gpointer key, gpointer value, gpointer user_data)
{
- EStorageSetView *storage_set_view;
- EStorageSetViewPrivate *priv;
-
- storage_set_view = E_STORAGE_SET_VIEW (object);
- priv = storage_set_view->priv;
-
- gtk_object_unref (GTK_OBJECT (priv->storage_set));
-
- g_hash_table_foreach (priv->ctree_node_to_path, hash_foreach_free_path, NULL);
- g_hash_table_destroy (priv->ctree_node_to_path);
- g_hash_table_destroy (priv->path_to_ctree_node);
-
- g_free (priv);
-
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ g_free (key);
+ gdk_pixbuf_unref ((GdkPixbuf*)value);
}
-
-/* GtkWidget methods. */
-
-static int
-button_press_event (GtkWidget *widget,
- GdkEventButton *event)
+static void
+destroy (GtkObject *object)
{
EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
- storage_set_view = E_STORAGE_SET_VIEW (widget);
+ storage_set_view = E_STORAGE_SET_VIEW (object);
priv = storage_set_view->priv;
- priv->selected_row_path_before_click = priv->selected_row_path;
-
- (* GTK_WIDGET_CLASS (parent_class)->button_press_event) (widget, event);
-
- if (priv->in_drag)
- return FALSE;
-
- priv->drag_button = event->button;
- priv->button_x = event->x;
- priv->button_y = event->y;
-
- /* KLUDGE ALERT. So look at this. We need to grab the pointer now, to check for
- motion events and maybe start a drag operation. And GtkCTree seems to do it
- already in the `button_press_event'. *But* for some reason something is very
- broken somewhere and the grab misbehaves when done by GtkCTree's
- `button_press_event'. So we have to ungrab the pointer and re-grab it our way.
- Weee! */
-
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
- gdk_flush ();
- gtk_grab_remove (widget);
+ /* need to destroy our tree */
+ e_tree_model_node_remove (priv->etree_model, priv->root_node);
+ gtk_object_unref (GTK_OBJECT (priv->etree_model));
- gdk_pointer_grab (GTK_CLIST (widget)->clist_window, FALSE,
- GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
- NULL, NULL, event->time);
- gtk_grab_add (widget);
+ /* now free up all the paths stored in the hash table and
+ destroy the hash table itself */
+ g_hash_table_foreach (priv->path_to_etree_node, path_free_func, NULL);
+ g_hash_table_destroy (priv->path_to_etree_node);
- return TRUE;
-}
-
-static int
-motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event)
-{
- EStorageSetView *storage_set_view;
- EStorageSetViewPrivate *priv;
+ /* now free up all the type_names and pixbufs stored in the
+ hash table and destroy the hash table itself */
+ g_hash_table_foreach (priv->type_name_to_pixbuf, pixbuf_free_func, NULL);
+ g_hash_table_destroy (priv->type_name_to_pixbuf);
- if (event->window != GTK_CLIST (widget)->clist_window)
- return (* GTK_WIDGET_CLASS (parent_class)->motion_notify_event) (widget, event);
-
- storage_set_view = E_STORAGE_SET_VIEW (widget);
- priv = storage_set_view->priv;
-
- if (priv->in_drag || priv->drag_button == 0)
- return FALSE;
-
- if (ABS (event->x - priv->button_x) < DRAG_RESISTANCE
- && ABS (event->y - priv->button_y) < DRAG_RESISTANCE)
- return FALSE;
+ gtk_object_unref (GTK_OBJECT (priv->storage_set));
- priv->in_drag = TRUE;
- priv->dragged_row_path = priv->selected_row_path;
+ /* free up our expanded/unexpanded pixmaps */
+ gdk_pixbuf_unref (priv->tree_expanded_pixbuf);
+ gdk_pixbuf_unref (priv->tree_unexpanded_pixbuf);
- gtk_drag_begin (widget, target_list, GDK_ACTION_MOVE,
- priv->drag_button, (GdkEvent *) event);
+ g_free (priv);
- return TRUE;
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
-static void
-handle_left_button_selection (EStorageSetView *storage_set_view,
- GtkWidget *widget,
- GdkEventButton *event)
-{
- EStorageSetViewPrivate *priv;
-
- priv = storage_set_view->priv;
-
- gtk_signal_emit (GTK_OBJECT (widget), signals[FOLDER_SELECTED],
- priv->selected_row_path);
- priv->selected_row_path = NULL;
-}
+
+/* ETable methods */
static void
-handle_right_button_selection (EStorageSetView *storage_set_view,
- GtkWidget *widget,
- GdkEventButton *event)
+etable_drag_begin (EStorageSetView *storage_set_view,
+ int row, int col,
+ GdkDragContext *context)
{
EStorageSetViewPrivate *priv;
+ ETreePath *node;
priv = storage_set_view->priv;
- popup_folder_menu (storage_set_view, event);
+ node = e_tree_model_node_at_row (priv->etree_model, row);
- if (priv->selected_row_path_before_click != NULL)
- e_storage_set_view_set_current_folder (storage_set_view,
- priv->selected_row_path_before_click);
-}
-
-static int
-button_release_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- EStorageSetView *storage_set_view;
- EStorageSetViewPrivate *priv;
-
- if (event->window != GTK_CLIST (widget)->clist_window)
- return (* GTK_WIDGET_CLASS (parent_class)->button_release_event) (widget, event);
-
- storage_set_view = E_STORAGE_SET_VIEW (widget);
- priv = storage_set_view->priv;
-
- if (! priv->in_drag) {
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
- gtk_grab_remove (widget);
- gdk_flush ();
-
- if (priv->selected_row_path != NULL) {
- if (priv->drag_button == 1)
- handle_left_button_selection (storage_set_view, widget, event);
- else
- handle_right_button_selection (storage_set_view, widget, event);
- }
- }
+ priv->selected_row_path = e_tree_model_node_get_data (priv->etree_model, node);
- priv->selected_row_path_before_click = NULL;
-
- return TRUE;
-}
-
-static void
-drag_end (GtkWidget *widget,
- GdkDragContext *context)
-{
- EStorageSetView *storage_set_view;
- EStorageSetViewPrivate *priv;
-
- storage_set_view = E_STORAGE_SET_VIEW (widget);
- priv = storage_set_view->priv;
-
- if (priv->dragged_row_path != NULL)
- e_storage_set_view_set_current_folder (storage_set_view,
- priv->selected_row_path_before_click);
-
- priv->in_drag = FALSE;
- priv->drag_button = 0;
- priv->dragged_row_path = NULL;
+ g_print ("dragging %s\n", priv->selected_row_path);
}
static void
@@ -532,16 +398,14 @@ set_e_shortcut_selection (EStorageSetView *storage_set_view,
}
static void
-drag_data_get (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint32 time)
+etable_drag_data_get (EStorageSetView *storage_set_view,
+ int drag_row,
+ int drag_col,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint32 time)
{
- EStorageSetView *storage_set_view;
-
- storage_set_view = E_STORAGE_SET_VIEW (widget);
-
switch (info) {
case DND_TARGET_TYPE_URI_LIST:
set_uri_list_selection (storage_set_view, selection_data);
@@ -555,8 +419,72 @@ drag_data_get (GtkWidget *widget,
}
+/* ETreeModel Methods */
+
+static GdkPixbuf*
+etree_icon_at (ETreeModel *etree, ETreePath *tree_path, void *model_data)
+{
+ EStorageSetView *storage_set_view;
+ char *path;
+ EStorageSet *storage_set;
+
+ /* folders are from depth 2 on. depth 1 are storages and 0 is
+ our (invisible) root node. */
+ if (e_tree_model_node_depth (etree, tree_path) < 2)
+ return NULL;
+
+ storage_set_view = E_STORAGE_SET_VIEW (model_data);
+ storage_set = storage_set_view->priv->storage_set;
+
+ path = (char*)e_tree_model_node_get_data (etree, tree_path);
+
+ return get_pixbuf_for_folder (storage_set_view,
+ e_storage_set_get_folder (storage_set, path));
+}
+
+static void*
+etree_value_at (ETreeModel *etree, ETreePath *tree_path, int col, void *model_data)
+{
+ char *path;
+ char *last_separator;
+
+ path = (char*)e_tree_model_node_get_data (etree, tree_path);
+
+ last_separator = strrchr (path, G_DIR_SEPARATOR);
+
+ g_return_val_if_fail (last_separator != NULL, NULL);
+
+ return last_separator + 1;
+}
+
+static void
+etree_set_value_at (ETreeModel *etree, ETreePath *path, int col, const void *val, void *model_data)
+{
+ /* nada */
+}
+
+static gboolean
+etree_is_editable (ETreeModel *etree, ETreePath *path, int col, void *model_data)
+{
+ return FALSE;
+}
+
+
/* StorageSet signal handling. */
+ETreeModel *sort_model;
+
+static gint
+treepath_compare (ETreePath **node1,
+ ETreePath **node2)
+{
+ char *path1, *path2;
+ path1 = e_tree_model_node_get_data (sort_model, *node1);
+ path2 = e_tree_model_node_get_data (sort_model, *node2);
+
+ return strcasecmp (path1, path2);
+}
+
static void
new_storage_cb (EStorageSet *storage_set,
EStorage *storage,
@@ -564,8 +492,7 @@ new_storage_cb (EStorageSet *storage_set,
{
EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
- GtkCTreeNode *node;
- char *text[2];
+ ETreePath *node;
char *path;
storage_set_view = E_STORAGE_SET_VIEW (data);
@@ -573,15 +500,15 @@ new_storage_cb (EStorageSet *storage_set,
path = g_strconcat (G_DIR_SEPARATOR_S, e_storage_get_name (storage), NULL);
- text[0] = (char *) e_storage_get_name (storage); /* Yuck. */
- text[1] = NULL;
+ node = e_tree_model_node_insert (priv->etree_model,
+ priv->root_node,
+ -1, path);
- node = gtk_ctree_insert_node (GTK_CTREE (storage_set_view), NULL, NULL,
- text, 3, NULL, NULL, NULL, NULL, FALSE, TRUE);
+ e_tree_model_node_set_expanded (priv->etree_model, node, TRUE);
- if (! add_node_to_hashes (storage_set_view, path, node)) {
+ if (! add_node_to_hash (storage_set_view, path, node)) {
g_free (path);
- gtk_ctree_remove_node (GTK_CTREE (storage_set_view), node);
+ e_tree_model_node_remove (priv->etree_model, node);
return;
}
@@ -589,7 +516,8 @@ new_storage_cb (EStorageSet *storage_set,
/* FIXME: We want a more specialized sort, e.g. the local folders should always be
on top. */
- gtk_ctree_sort_node (GTK_CTREE (storage_set_view), NULL);
+ sort_model = priv->etree_model;
+ e_tree_model_node_sort (priv->etree_model, priv->root_node, (GCompareFunc)treepath_compare);
}
static void
@@ -599,17 +527,19 @@ removed_storage_cb (EStorageSet *storage_set,
{
EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
- GtkCTreeNode *node;
+ ETreeModel *etree;
+ ETreePath *node;
char *path;
storage_set_view = E_STORAGE_SET_VIEW (data);
priv = storage_set_view->priv;
+ etree = priv->etree_model;
path = g_strconcat (G_DIR_SEPARATOR_S, e_storage_get_name (storage), NULL);
- node = remove_node_from_hashes (storage_set_view, path);
+ node = remove_node_from_hash (storage_set_view, path);
g_free (path);
- gtk_ctree_remove_node (GTK_CTREE (storage_set_view), node);
+ e_tree_model_node_remove (etree, node);
}
static void
@@ -619,11 +549,9 @@ new_folder_cb (EStorageSet *storage_set,
{
EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
- GtkCTreeNode *parent_node;
- GtkCTreeNode *node;
- GdkPixmap *pixmap;
- GdkBitmap *mask;
- char *text[2];
+ ETreeModel *etree;
+ ETreePath *parent_node;
+ ETreePath *new_node;
const char *last_separator;
char *parent_path;
@@ -631,11 +559,12 @@ new_folder_cb (EStorageSet *storage_set,
storage_set_view = E_STORAGE_SET_VIEW (data);
priv = storage_set_view->priv;
+ etree = priv->etree_model;
last_separator = strrchr (path, G_DIR_SEPARATOR);
parent_path = g_strndup (path, last_separator - path);
- parent_node = g_hash_table_lookup (priv->path_to_ctree_node, parent_path);
+ parent_node = g_hash_table_lookup (priv->path_to_etree_node, parent_path);
if (parent_node == NULL) {
g_print ("EStorageSetView: EStorageSet reported new subfolder for non-existing folder -- %s\n",
parent_path);
@@ -645,27 +574,15 @@ new_folder_cb (EStorageSet *storage_set,
g_free (parent_path);
- if (parent_node == NULL)
- return;
-
- text[0] = (char *) last_separator + 1; /* Yuck. */
- text[1] = NULL;
+ new_node = e_tree_model_node_insert (etree, parent_node, -1, (gpointer)g_strdup(path));
- get_pixmap_and_mask_for_folder (storage_set_view,
- e_storage_set_get_folder (storage_set, path),
- &pixmap, &mask);
- node = gtk_ctree_insert_node (GTK_CTREE (storage_set_view),
- parent_node, NULL,
- text, 3,
- pixmap, mask, pixmap, mask,
- FALSE, TRUE);
-
- if (! add_node_to_hashes (storage_set_view, path, node)) {
- gtk_ctree_remove_node (GTK_CTREE (storage_set_view), node);
+ if (! add_node_to_hash (storage_set_view, path, new_node)) {
+ e_tree_model_node_remove (etree, new_node);
return;
}
- gtk_ctree_sort_node (GTK_CTREE (storage_set_view), parent_node);
+ sort_model = priv->etree_model;
+ e_tree_model_node_sort (priv->etree_model, parent_node, (GCompareFunc)treepath_compare);
}
static void
@@ -674,36 +591,16 @@ removed_folder_cb (EStorageSet *storage_set,
void *data)
{
EStorageSetView *storage_set_view;
- GtkCTreeNode *node;
-
- storage_set_view = E_STORAGE_SET_VIEW (data);
-
- node = remove_node_from_hashes (storage_set_view, path);
- gtk_ctree_remove_node (GTK_CTREE (storage_set_view), node);
-}
-
-
-/* GtkCTree methods. */
-
-static void
-tree_select_row (GtkCTree *ctree,
- GtkCTreeNode *row,
- gint column)
-{
- EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
- const char *path;
+ ETreeModel *etree;
+ ETreePath *node;
- (* GTK_CTREE_CLASS (parent_class)->tree_select_row) (ctree, row, column);
-
- storage_set_view = E_STORAGE_SET_VIEW (ctree);
+ storage_set_view = E_STORAGE_SET_VIEW (data);
priv = storage_set_view->priv;
+ etree = priv->etree_model;
- path = g_hash_table_lookup (storage_set_view->priv->ctree_node_to_path, row);
- if (path == NULL)
- return;
-
- priv->selected_row_path = path;
+ node = remove_node_from_hash (storage_set_view, path);
+ e_tree_model_node_remove (etree, node);
}
@@ -711,24 +608,12 @@ static void
class_init (EStorageSetViewClass *klass)
{
GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- GtkCTreeClass *ctree_class;
- parent_class = gtk_type_class (gtk_ctree_get_type ());
+ parent_class = gtk_type_class (e_table_get_type ());
object_class = GTK_OBJECT_CLASS (klass);
object_class->destroy = destroy;
- widget_class = GTK_WIDGET_CLASS (klass);
- widget_class->button_press_event = button_press_event;
- widget_class->motion_notify_event = motion_notify_event;
- widget_class->button_release_event = button_release_event;
- widget_class->drag_end = drag_end;
- widget_class->drag_data_get = drag_data_get;
-
- ctree_class = GTK_CTREE_CLASS (klass);
- ctree_class->tree_select_row = tree_select_row;
-
signals[FOLDER_SELECTED]
= gtk_signal_new ("folder_selected",
GTK_RUN_FIRST,
@@ -750,28 +635,15 @@ static void
init (EStorageSetView *storage_set_view)
{
EStorageSetViewPrivate *priv;
- GtkCList *clist;
-
- /* Avoid GtkCTree's broken focusing behavior. FIXME: Other ways? */
- GTK_WIDGET_UNSET_FLAGS (storage_set_view, GTK_CAN_FOCUS);
priv = g_new (EStorageSetViewPrivate, 1);
priv->storage_set = NULL;
- priv->ctree_node_to_path = g_hash_table_new (g_direct_hash, g_direct_equal);
- priv->path_to_ctree_node = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->path_to_etree_node = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->type_name_to_pixbuf = g_hash_table_new (g_str_hash, g_str_equal);
priv->selected_row_path = NULL;
- priv->dragged_row_path = NULL;
- priv->selected_row_path_before_click = NULL;
- priv->in_drag = FALSE;
- priv->button_x = 0;
- priv->button_y = 0;
storage_set_view->priv = priv;
-
- /* Set up the right mouse button so that it also selects. */
- clist = GTK_CLIST (storage_set_view);
- clist->button_actions[2] |= GTK_BUTTON_SELECTS;
}
@@ -794,20 +666,19 @@ folder_compare_cb (gconstpointer a, gconstpointer b)
static void
insert_folders (EStorageSetView *storage_set_view,
- GtkCTreeNode *parent,
+ ETreePath *parent,
EStorage *storage,
- const char *path,
- int level)
+ const char *path)
{
EStorageSetViewPrivate *priv;
- GtkCTree *ctree;
- GtkCTreeNode *node;
+ ETreeModel *etree;
+ ETreePath *node;
GList *folder_list;
GList *p;
const char *storage_name;
- ctree = GTK_CTREE (storage_set_view);
priv = storage_set_view->priv;
+ etree = priv->etree_model;
storage_name = e_storage_get_name (storage);
@@ -820,30 +691,21 @@ insert_folders (EStorageSetView *storage_set_view,
for (p = folder_list; p != NULL; p = p->next) {
EFolder *folder;
const char *folder_name;
- char *text[2];
char *subpath;
char *full_path;
- GdkPixmap *pixmap;
- GdkBitmap *mask;
folder = E_FOLDER (p->data);
folder_name = e_folder_get_name (folder);
- text[0] = (char *) folder_name; /* Yuck. */
- text[1] = NULL;
-
- get_pixmap_and_mask_for_folder (storage_set_view, folder, &pixmap, &mask);
- node = gtk_ctree_insert_node (ctree, parent, NULL,
- text, 3,
- pixmap, mask, pixmap, mask,
- FALSE, TRUE);
-
subpath = g_concat_dir_and_file (path, folder_name);
- insert_folders (storage_set_view, node, storage, subpath, level + 1);
full_path = g_strconcat("/", storage_name, subpath, NULL);
- g_hash_table_insert (priv->ctree_node_to_path, node, full_path);
- g_hash_table_insert (priv->path_to_ctree_node, full_path, node);
+
+ node = e_tree_model_node_insert (etree, parent, -1, (gpointer)full_path);
+
+ insert_folders (storage_set_view, node, storage, subpath);
+
+ add_node_to_hash (storage_set_view, full_path, node);
g_free (subpath);
}
@@ -851,38 +713,92 @@ insert_folders (EStorageSetView *storage_set_view,
e_free_object_list (folder_list);
}
+static void
+right_click (EStorageSetView *storage_set_view, int row, int col,
+ GdkEventButton *event, gboolean *ret)
+{
+ EStorageSetViewPrivate *priv;
+
+ priv = storage_set_view->priv;
+
+ popup_folder_menu (storage_set_view, event);
+}
+
+static void
+on_cursor_change (EStorageSetView *storage_set_view, int row, gpointer user_data)
+{
+ ETreePath *node;
+ EStorageSetViewPrivate *priv;
+
+ priv = storage_set_view->priv;
+
+ node = e_tree_model_node_at_row (priv->etree_model, row);
+
+ /* don't emit the folder selected signal for storages */
+ if (e_tree_model_node_depth (priv->etree_model, node) < 2)
+ return;
+
+ priv->selected_row_path = e_tree_model_node_get_data (priv->etree_model, node);
+
+ gtk_signal_emit (GTK_OBJECT (storage_set_view), signals[FOLDER_SELECTED],
+ priv->selected_row_path);
+}
+
void
e_storage_set_view_construct (EStorageSetView *storage_set_view,
EStorageSet *storage_set)
{
EStorageSetViewPrivate *priv;
- GtkCTreeNode *parent;
- GtkCTree *ctree;
+ ETreePath *parent;
EStorage *storage;
GList *storage_list;
GList *p;
const char *name;
char *text[2];
char *path;
+ ETableCol *ecol;
+ ETableHeader *e_table_header;
+ ECell *cell_left_just;
+ ECell *cell_tree;
g_return_if_fail (storage_set_view != NULL);
g_return_if_fail (E_IS_STORAGE_SET_VIEW (storage_set_view));
g_return_if_fail (storage_set != NULL);
g_return_if_fail (E_IS_STORAGE_SET (storage_set));
- ctree = GTK_CTREE (storage_set_view);
priv = storage_set_view->priv;
- /* Set up GtkCTree/GtkCList parameters. */
+ priv->tree_expanded_pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)tree_expanded_xpm);
+ priv->tree_unexpanded_pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)tree_unexpanded_xpm);
- gtk_ctree_construct (ctree, 1, 0, NULL);
- gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
- gtk_ctree_set_expander_style (ctree, GTK_CTREE_EXPANDER_SQUARE);
+ priv->etree_model = e_tree_simple_new (etree_icon_at,
+ etree_value_at,
+ etree_set_value_at,
+ etree_is_editable,
+ storage_set_view);
+ e_tree_model_root_node_set_visible (priv->etree_model, FALSE);
+
+ priv->root_node = e_tree_model_node_insert (priv->etree_model, NULL, -1, "/Root Node");
+
+ e_table_header = e_table_header_new ();
+ cell_left_just = e_cell_text_new (E_TABLE_MODEL (priv->etree_model), NULL, GTK_JUSTIFY_LEFT);
+ cell_tree = e_cell_tree_new (E_TABLE_MODEL (priv->etree_model),
+ priv->tree_expanded_pixbuf,
+ priv->tree_unexpanded_pixbuf, TRUE, cell_left_just);
+
+ ecol = e_table_col_new (0, "Folder", 80, 20, cell_tree, g_str_compare, TRUE);
+ e_table_header_add_column (e_table_header, ecol, 0);
+
+ e_table_construct (E_TABLE (storage_set_view), e_table_header, E_TABLE_MODEL(priv->etree_model),
+ ETABLE_SPEC);
+
+ gtk_object_set (GTK_OBJECT (storage_set_view),
+ "cursor_mode", E_TABLE_CURSOR_LINE,
+ NULL);
+
+ e_table_drag_source_set (E_TABLE (storage_set_view), GDK_BUTTON1_MASK,
+ drag_types, num_drag_types, GDK_ACTION_MOVE);
- gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_BROWSE);
- gtk_clist_set_row_height (GTK_CLIST (ctree), E_SHELL_MINI_ICON_SIZE);
- gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
-
gtk_object_ref (GTK_OBJECT (storage_set));
priv->storage_set = storage_set;
@@ -898,7 +814,16 @@ e_storage_set_view_construct (EStorageSetView *storage_set_view,
gtk_signal_connect_while_alive (GTK_OBJECT (storage_set), "removed_folder",
GTK_SIGNAL_FUNC (removed_folder_cb), storage_set_view,
GTK_OBJECT (storage_set_view));
-
+
+ gtk_signal_connect (GTK_OBJECT (storage_set_view), "right_click",
+ GTK_SIGNAL_FUNC (right_click), GTK_OBJECT(storage_set_view));
+ gtk_signal_connect (GTK_OBJECT (storage_set_view), "cursor_change",
+ GTK_SIGNAL_FUNC (on_cursor_change), GTK_OBJECT(storage_set_view));
+ gtk_signal_connect (GTK_OBJECT (storage_set_view), "table_drag_begin",
+ GTK_SIGNAL_FUNC (etable_drag_begin), GTK_OBJECT(storage_set_view));
+ gtk_signal_connect (GTK_OBJECT (storage_set_view), "drag_data_get",
+ GTK_SIGNAL_FUNC (etable_drag_data_get), GTK_OBJECT(storage_set_view));
+
storage_list = e_storage_set_get_storage_list (storage_set);
text[1] = NULL;
@@ -907,18 +832,15 @@ e_storage_set_view_construct (EStorageSetView *storage_set_view,
storage = E_STORAGE (p->data);
name = e_storage_get_name (storage);
- text[0] = (char *) name; /* Yuck. */
+ path = g_strconcat ("/", name, NULL);
- parent = gtk_ctree_insert_node (ctree, NULL, NULL,
- text, 3,
- NULL, NULL, NULL, NULL,
- FALSE, TRUE);
+ parent = e_tree_model_node_insert (priv->etree_model, priv->root_node,
+ -1, path);
+ e_tree_model_node_set_expanded (priv->etree_model, parent, TRUE);
- path = g_strconcat ("/", name, NULL);
- g_hash_table_insert (priv->ctree_node_to_path, parent, path);
- g_hash_table_insert (priv->path_to_ctree_node, path, parent);
+ g_hash_table_insert (priv->path_to_etree_node, path, parent);
- insert_folders (storage_set_view, parent, storage, "/", 1);
+ insert_folders (storage_set_view, parent, storage, "/");
}
e_free_object_list (storage_list);
@@ -944,7 +866,7 @@ e_storage_set_view_set_current_folder (EStorageSetView *storage_set_view,
const char *path)
{
EStorageSetViewPrivate *priv;
- GtkCTreeNode *node;
+ ETreePath *node;
g_return_if_fail (storage_set_view != NULL);
g_return_if_fail (E_IS_STORAGE_SET_VIEW (storage_set_view));
@@ -953,17 +875,18 @@ e_storage_set_view_set_current_folder (EStorageSetView *storage_set_view,
priv = storage_set_view->priv;
if (path == NULL) {
- gtk_clist_unselect_all (GTK_CLIST (storage_set_view));
+ e_table_set_cursor_row (E_TABLE (storage_set_view), -1);
return;
}
- node = g_hash_table_lookup (priv->path_to_ctree_node, path);
+ node = g_hash_table_lookup (priv->path_to_etree_node, path);
if (node == NULL) {
- gtk_clist_unselect_all (GTK_CLIST (storage_set_view));
+ e_table_set_cursor_row (E_TABLE (storage_set_view), -1);
return;
}
- gtk_ctree_select (GTK_CTREE (storage_set_view), node);
+ e_table_set_cursor_row (E_TABLE (storage_set_view),
+ e_tree_model_row_of_node (priv->etree_model, node));
gtk_signal_emit (GTK_OBJECT (storage_set_view), signals[FOLDER_SELECTED], path);
}
@@ -972,29 +895,22 @@ const char *
e_storage_set_view_get_current_folder (EStorageSetView *storage_set_view)
{
EStorageSetViewPrivate *priv;
- GtkCList *clist;
- GtkCTree *ctree;
- GtkCTreeRow *ctree_row;
- GtkCTreeNode *ctree_node;
+ ETreePath *etree_node;
const char *path;
+ int row;
g_return_val_if_fail (storage_set_view != NULL, NULL);
g_return_val_if_fail (E_IS_STORAGE_SET_VIEW (storage_set_view), NULL);
priv = storage_set_view->priv;
- clist = GTK_CLIST (storage_set_view);
- ctree = GTK_CTREE (storage_set_view);
-
- if (clist->selection == NULL)
- return NULL;
+ row = e_table_get_cursor_row (E_TABLE (storage_set_view));
+ etree_node = e_tree_model_node_at_row (priv->etree_model, row);
- ctree_row = GTK_CTREE_ROW (clist->selection->data);
- ctree_node = gtk_ctree_find_node_ptr (ctree, ctree_row);
- if (ctree_node == NULL)
+ if (etree_node == NULL)
return NULL; /* Mmh? */
- path = g_hash_table_lookup (priv->ctree_node_to_path, ctree_node);
+ path = (char*)e_tree_model_node_get_data(priv->etree_model, etree_node);
return path;
}