aboutsummaryrefslogtreecommitdiffstats
path: root/shell/e-storage-set-store.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/e-storage-set-store.c')
-rw-r--r--shell/e-storage-set-store.c1361
1 files changed, 0 insertions, 1361 deletions
diff --git a/shell/e-storage-set-store.c b/shell/e-storage-set-store.c
deleted file mode 100644
index e2816d87d2..0000000000
--- a/shell/e-storage-set-store.c
+++ /dev/null
@@ -1,1361 +0,0 @@
-/* e-storage-set-store.c
- * Copyright (C) 2002 Ximian, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <string.h>
-
-#include <gtk/gtktreemodel.h>
-#include <gtk/gtktreednd.h>
-
-#include "e-icon-factory.h"
-#include "e-storage-set-store.h"
-#include "e-shell-constants.h"
-
-struct _EStorageSetStorePrivate {
- EStorageSet *storage_set;
- GHashTable *checkboxes;
- GHashTable *path_to_node;
- GHashTable *type_name_to_pixbuf;
- GNode *root;
- gint stamp;
- EStorageSetStoreHasCheckBoxFunc has_checkbox_func;
- gpointer has_checkbox_func_data;
-};
-
-#define G_NODE(node) ((GNode *)(node))
-#define VALID_ITER(iter, store) ((iter) != NULL && (iter)->user_data != NULL && (store)->priv->stamp == (iter)->stamp)
-#define VALID_COL(col) ((col) >= 0 && (col) < E_STORAGE_SET_STORE_COLUMN_COUNT)
-
-static GObjectClass *parent_class = NULL;
-
-static gboolean
-has_checkbox (EStorageSetStore *store, const gchar *folder_path)
-{
- EStorageSetStorePrivate *priv = store->priv;
-
- g_return_val_if_fail (folder_path != NULL, FALSE);
-
- if (strchr (folder_path + 1, '/') == NULL) {
- /* If it's a toplevel, never allow checking it. */
- return FALSE;
- }
-
-#if 0
- if (priv->has_checkbox_func)
- return (* priv->has_checkbox_func) (priv->storage_set,
- folder_path,
- priv->has_checkbox_func_data);
-#endif
-
- return TRUE;
-}
-
-
-/* GtkTreeModel interface implementation */
-
-static guint
-esss_get_flags(GtkTreeModel *tree_model)
-{
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), 0);
-
- return GTK_TREE_MODEL_ITERS_PERSIST;
-}
-
-static gint
-esss_get_n_columns(GtkTreeModel *tree_model)
-{
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), 0);
-
- return E_STORAGE_SET_STORE_COLUMN_COUNT;
-}
-
-static GType
-esss_get_column_type(GtkTreeModel *tree_model, gint index)
-{
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
- GType retval;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), G_TYPE_INVALID);
- g_return_val_if_fail(VALID_COL(index), G_TYPE_INVALID);
-
- switch (index) {
- case E_STORAGE_SET_STORE_COLUMN_NAME:
- retval = G_TYPE_STRING;
- break;
- case E_STORAGE_SET_STORE_COLUMN_HIGHLIGHT:
- retval = G_TYPE_INT;
- break;
- case E_STORAGE_SET_STORE_COLUMN_CHECKED:
- case E_STORAGE_SET_STORE_COLUMN_CHECKABLE:
- retval = G_TYPE_BOOLEAN;
- break;
- case E_STORAGE_SET_STORE_COLUMN_ICON:
- retval = GDK_TYPE_PIXBUF;
- break;
- default:
- g_assert_not_reached ();
- }
-
- return retval;
-}
-
-static gboolean
-esss_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
-{
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
- GtkTreeIter parent;
- gint *indices;
- gint depth, i;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), FALSE);
- g_return_val_if_fail(iter != NULL, FALSE);
-
- indices = gtk_tree_path_get_indices(path);
- depth = gtk_tree_path_get_depth(path);
-
- g_return_val_if_fail(depth > 0, FALSE);
-
- parent.stamp = store->priv->stamp;
- parent.user_data = store->priv->root;
-
- for (i = 0; i < depth; i++) {
- if (!gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[i]))
- return FALSE;
- parent = *iter;
- }
-
- return TRUE;
-}
-
-static GtkTreePath *
-tree_path_from_node (EStorageSetStore *store, GNode *node)
-{
- GtkTreePath *retval;
- GNode *tmp_node, *curr_node;
- gint i = 0;
-
- if (node == store->priv->root)
- return NULL;
-
- retval = gtk_tree_path_new();
-
- for (curr_node = node; curr_node != store->priv->root; curr_node = curr_node->parent) {
-
- if (curr_node->parent == NULL) {
- gtk_tree_path_free(retval);
- return NULL;
- }
-
- for (i = 0, tmp_node = curr_node->parent->children;
- tmp_node && tmp_node != curr_node;
- i++, tmp_node = tmp_node->next);
-
- if (tmp_node == NULL) {
- gtk_tree_path_free(retval);
- return NULL;
- }
-
- gtk_tree_path_prepend_index(retval, i);
- }
-
- return retval;
-}
-
-static GtkTreePath *
-esss_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter)
-{
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), NULL);
- g_return_val_if_fail(VALID_ITER(iter, store), NULL);
-
- if (iter->user_data == store->priv->root)
- return NULL;
-
- return tree_path_from_node (store, G_NODE (iter->user_data));
-}
-
-static GdkPixbuf *
-get_pixbuf_for_folder (EStorageSetStore *store, EFolder *folder)
-{
- const char *type_name;
- EStorageSetStorePrivate *priv;
- EFolderTypeRegistry *folder_type_registry;
- EStorageSet *storage_set;
- GdkPixbuf *icon_pixbuf;
- GdkPixbuf *scaled_pixbuf;
- const char *custom_icon_name;
- int icon_pixbuf_width, icon_pixbuf_height;
-
- priv = store->priv;
-
- custom_icon_name = e_folder_get_custom_icon_name (folder);
- if (custom_icon_name != NULL)
- return e_icon_factory_get_icon (custom_icon_name, TRUE);
-
- type_name = e_folder_get_type_string (folder);
-
- scaled_pixbuf = g_hash_table_lookup (priv->type_name_to_pixbuf, type_name);
- if (scaled_pixbuf != NULL)
- return scaled_pixbuf;
-
- storage_set = priv->storage_set;
- folder_type_registry = e_storage_set_get_folder_type_registry (storage_set);
-
- icon_pixbuf = e_folder_type_registry_get_icon_for_type (folder_type_registry,
- type_name, TRUE);
-
- if (icon_pixbuf == NULL)
- return NULL;
-
- icon_pixbuf_width = gdk_pixbuf_get_width (icon_pixbuf);
- icon_pixbuf_height = gdk_pixbuf_get_height (icon_pixbuf);
-
- if (icon_pixbuf_width == E_SHELL_MINI_ICON_SIZE && icon_pixbuf_height == E_SHELL_MINI_ICON_SIZE) {
- scaled_pixbuf = g_object_ref (icon_pixbuf);
- } else {
- 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);
-
- 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);
- }
-
- g_hash_table_insert (priv->type_name_to_pixbuf, g_strdup (type_name), scaled_pixbuf);
-
- return scaled_pixbuf;
-}
-
-static void
-esss_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
-{
- gchar *folder_path;
- const gchar *folder_name;
- int unread_count;
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
- EFolder *folder;
- GNode *node;
- gboolean is_storage;
-
- g_return_if_fail(E_IS_STORAGE_SET_STORE(tree_model));
- g_return_if_fail(VALID_ITER(iter, store));
- g_return_if_fail(VALID_COL(column));
-
- node = G_NODE (iter->user_data);
- g_value_init(value, esss_get_column_type(tree_model, column));
-
- is_storage = (node->parent == store->priv->root);
-
- if (is_storage)
- folder_path = g_strconcat ("/", node->data, NULL);
- else
- folder_path = g_strdup (node->data);
-
- folder = e_storage_set_get_folder(store->priv->storage_set, folder_path);
- g_free (folder_path);
-
- switch (column) {
- case E_STORAGE_SET_STORE_COLUMN_NAME:
- if (!folder) {
- g_value_set_string(value, "?");
- return;
- }
- folder_name = e_folder_get_name(folder);
- unread_count = e_folder_get_unread_count(folder);
- if (unread_count > 0) {
- gchar *with_unread = g_strdup_printf("%s (%d)", folder_name, unread_count);
- g_object_set_data_full(G_OBJECT(folder), "name_with_unread",
- with_unread, g_free);
- g_value_set_string(value, with_unread);
- } else
- g_value_set_string(value, folder_name);
- break;
-
- case E_STORAGE_SET_STORE_COLUMN_HIGHLIGHT:
- if (!folder) {
- g_value_set_boolean(value, FALSE);
- return;
- }
- g_value_set_int(value, is_storage || e_folder_get_highlighted(folder) ? PANGO_WEIGHT_BOLD : 0);
- break;
-
- case E_STORAGE_SET_STORE_COLUMN_CHECKED:
- if (is_storage || !store->priv->checkboxes) {
- g_value_set_boolean(value, FALSE);
- return;
- }
- g_value_set_boolean(value,
- g_hash_table_lookup(store->priv->checkboxes, folder_path) ? TRUE : FALSE);
- break;
-
- case E_STORAGE_SET_STORE_COLUMN_CHECKABLE:
- g_value_set_boolean(value, !is_storage && has_checkbox(store, (gchar *)node->data));
- break;
-
- case E_STORAGE_SET_STORE_COLUMN_ICON:
- if (!is_storage)
- g_value_set_object (value, get_pixbuf_for_folder (store, folder));
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-}
-
-static gboolean
-esss_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter)
-{
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), FALSE);
- g_return_val_if_fail(VALID_ITER(iter, E_STORAGE_SET_STORE(tree_model)), FALSE);
-
- if (G_NODE(iter->user_data)->next) {
- iter->user_data = G_NODE(iter->user_data)->next;
- return TRUE;
- } else
- return FALSE;
-}
-
-static gboolean
-esss_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
-{
- GNode *children;
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), FALSE);
- g_return_val_if_fail(iter != NULL, FALSE);
- g_return_val_if_fail(parent == NULL || parent->user_data != NULL, FALSE);
- g_return_val_if_fail(parent == NULL || parent->stamp == store->priv->stamp, FALSE);
-
- if (parent)
- children = G_NODE(parent->user_data)->children;
- else
- children =
- G_NODE(store->priv->root)->children;
-
- if (children) {
- iter->stamp = store->priv->stamp;
- iter->user_data = children;
- return TRUE;
- } else
- return FALSE;
-}
-
-static gboolean
-esss_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter)
-{
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), FALSE);
- g_return_val_if_fail(VALID_ITER(iter, store), FALSE);
-
- return G_NODE(iter->user_data)->children != NULL;
-}
-
-static gint
-esss_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter)
-{
- GNode *node;
- gint i = 0;
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), 0);
- g_return_val_if_fail(iter == NULL || iter->user_data != NULL, FALSE);
-
- if (iter == NULL)
- node = G_NODE(store->priv->root)->children;
- else
- node = G_NODE(iter->user_data)->children;
-
- while (node) {
- i++;
- node = node->next;
- }
-
- return i;
-}
-
-static gboolean
-esss_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
-{
- GNode *parent_node;
- GNode *child;
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), FALSE);
- g_return_val_if_fail(iter != NULL, FALSE);
- g_return_val_if_fail(parent == NULL || parent->user_data != NULL, FALSE);
-
- if (parent == NULL)
- parent_node = store->priv->root;
- else
- parent_node = parent->user_data;
-
- child = g_node_nth_child(parent_node, n);
-
- if (child) {
- iter->user_data = child;
- iter->stamp = store->priv->stamp;
- return TRUE;
- } else
- return FALSE;
-}
-
-static gboolean
-esss_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
-{
- GNode *parent;
- EStorageSetStore *store = (EStorageSetStore *) tree_model;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(tree_model), FALSE);
- g_return_val_if_fail(iter != NULL, FALSE);
- g_return_val_if_fail(VALID_ITER(child, store), FALSE);
-
- parent = G_NODE(child->user_data)->parent;
-
- g_assert(parent != NULL);
-
- if (parent != store->priv->root) {
- iter->user_data = parent;
- iter->stamp = store->priv->stamp;
- return TRUE;
- } else
- return FALSE;
-}
-
-static void
-esss_tree_model_init(GtkTreeModelIface *iface)
-{
- iface->get_flags = esss_get_flags;
- iface->get_n_columns = esss_get_n_columns;
- iface->get_column_type = esss_get_column_type;
- iface->get_iter = esss_get_iter;
- iface->get_path = esss_get_path;
- iface->get_value = esss_get_value;
- iface->iter_next = esss_iter_next;
- iface->iter_children = esss_iter_children;
- iface->iter_has_child = esss_iter_has_child;
- iface->iter_n_children = esss_iter_n_children;
- iface->iter_nth_child = esss_iter_nth_child;
- iface->iter_parent = esss_iter_parent;
-}
-
-/* GtkTreeDragSource interface implementation */
-
-static gboolean
-esss_drag_data_delete(GtkTreeDragSource *source, GtkTreePath *path)
-{
- GtkTreeIter iter;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(source), FALSE);
-
- if (gtk_tree_model_get_iter(GTK_TREE_MODEL(source), &iter, path)) {
-#if 0
- e_storage_set_store_remove(E_STORAGE_SET_STORE(source), &iter);
-#endif
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-static gboolean
-esss_drag_data_get(GtkTreeDragSource *source, GtkTreePath *path, GtkSelectionData *selection_data)
-{
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(source), FALSE);
-
- /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
- * target, because the default handler does it for us, but
- * we do anyway for the convenience of someone maybe overriding the
- * default handler.
- */
-
- if (gtk_tree_set_row_drag_data(selection_data, GTK_TREE_MODEL(source), path)) {
- return TRUE;
- } else {
- /* FIXME handle text targets at least. */
- }
-
- return FALSE;
-}
-
-static void
-esss_drag_source_init(GtkTreeDragSourceIface * iface)
-{
- iface->drag_data_delete = esss_drag_data_delete;
- iface->drag_data_get = esss_drag_data_get;
-}
-
-/* GtkTreeDragDest interface implementation */
-
-static void
-copy_node_data(EStorageSetStore *store, GtkTreeIter *src_iter, GtkTreeIter *dest_iter)
-{
-}
-
-static void
-recursive_node_copy(EStorageSetStore * store,
- GtkTreeIter * src_iter, GtkTreeIter * dest_iter)
-{
-}
-
-static gboolean
-esss_drag_data_received(GtkTreeDragDest * drag_dest,
- GtkTreePath * dest,
- GtkSelectionData * selection_data)
-{
-#if 0
- GtkTreeModel *tree_model;
- EStorageSetStore *store;
- GtkTreeModel *src_model = NULL;
- GtkTreePath *src_path = NULL;
- gboolean retval = FALSE;
-
- g_return_val_if_fail(E_IS_STORAGE_SET_STORE(drag_dest), FALSE);
-
- tree_model = GTK_TREE_MODEL(drag_dest);
- store = E_STORAGE_SET_STORE(drag_dest);
-
- validate_tree(store);
-
- if (gtk_tree_get_row_drag_data(selection_data,
- &src_model,
- &src_path) &&
- src_model == tree_model) {
- /* Copy the given row to a new position */
- GtkTreeIter src_iter;
- GtkTreeIter dest_iter;
- GtkTreePath *prev;
-
- if (!gtk_tree_model_get_iter(src_model,
- &src_iter, src_path)) {
- goto out;
- }
-
- /* Get the path to insert _after_ (dest is the path to insert _before_) */
- prev = gtk_tree_path_copy(dest);
-
- if (!gtk_tree_path_prev(prev)) {
- GtkTreeIter dest_parent;
- GtkTreePath *parent;
- GtkTreeIter *dest_parent_p;
-
- /* dest was the first spot at the current depth; which means
- * we are supposed to prepend.
- */
-
- /* Get the parent, NULL if parent is the root */
- dest_parent_p = NULL;
- parent = gtk_tree_path_copy(dest);
- if (gtk_tree_path_up(parent) &&
- gtk_tree_path_get_depth(parent) > 0) {
- gtk_tree_model_get_iter(tree_model,
- &dest_parent,
- parent);
- dest_parent_p = &dest_parent;
- }
- gtk_tree_path_free(parent);
- parent = NULL;
-
- e_storage_set_store_prepend(E_STORAGE_SET_STORE(tree_model),
- &dest_iter, dest_parent_p);
-
- retval = TRUE;
- } else {
- if (gtk_tree_model_get_iter
- (GTK_TREE_MODEL(tree_model), &dest_iter,
- prev)) {
- GtkTreeIter tmp_iter = dest_iter;
-
- if (GPOINTER_TO_INT
- (g_object_get_data
- (G_OBJECT(tree_model),
- "gtk-tree-model-drop-append"))) {
- GtkTreeIter parent;
-
- if (gtk_tree_model_iter_parent
- (GTK_TREE_MODEL(tree_model),
- &parent, &tmp_iter))
- e_storage_set_store_append
- (E_STORAGE_SET_STORE
- (tree_model),
- &dest_iter, &parent);
- else
- e_storage_set_store_append
- (E_STORAGE_SET_STORE
- (tree_model),
- &dest_iter, NULL);
- } else
- e_storage_set_store_insert_after
- (E_STORAGE_SET_STORE(tree_model),
- &dest_iter, NULL, &tmp_iter);
- retval = TRUE;
-
- }
- }
-
- g_object_set_data(G_OBJECT(tree_model),
- "gtk-tree-model-drop-append", NULL);
-
- gtk_tree_path_free(prev);
-
- /* If we succeeded in creating dest_iter, walk src_iter tree branch,
- * duplicating it below dest_iter.
- */
-
- if (retval) {
- recursive_node_copy(store,
- &src_iter, &dest_iter);
- }
- } else {
- /* FIXME maybe add some data targets eventually, or handle text
- * targets in the simple case.
- */
-
- }
-
- out:
-
- if (src_path)
- gtk_tree_path_free(src_path);
-
- return retval;
-#else
- return FALSE;
-#endif
-}
-
-static gboolean
-esss_row_drop_possible(GtkTreeDragDest * drag_dest,
- GtkTreePath * dest_path,
- GtkSelectionData * selection_data)
-{
-#if 0
- GtkTreeModel *src_model = NULL;
- GtkTreePath *src_path = NULL;
- GtkTreePath *tmp = NULL;
- gboolean retval = FALSE;
-
- if (!gtk_tree_get_row_drag_data(selection_data,
- &src_model, &src_path))
- goto out;
-
- /* can only drag to ourselves */
- if (src_model != GTK_TREE_MODEL(drag_dest))
- goto out;
-
- /* Can't drop into ourself. */
- if (gtk_tree_path_is_ancestor(src_path, dest_path))
- goto out;
-
- /* Can't drop if dest_path's parent doesn't exist */
- {
- GtkTreeIter iter;
-
- if (gtk_tree_path_get_depth(dest_path) > 1) {
- tmp = gtk_tree_path_copy(dest_path);
- gtk_tree_path_up(tmp);
-
- if (!gtk_tree_model_get_iter
- (GTK_TREE_MODEL(drag_dest), &iter, tmp))
- goto out;
- }
- }
-
- /* Can otherwise drop anywhere. */
- retval = TRUE;
-
- out:
-
- if (src_path)
- gtk_tree_path_free(src_path);
- if (tmp)
- gtk_tree_path_free(tmp);
-
- return retval;
-#else
- return FALSE;
-#endif
-}
-
-static void
-esss_drag_dest_init(GtkTreeDragDestIface * iface)
-{
- iface->drag_data_received = esss_drag_data_received;
- iface->row_drop_possible = esss_row_drop_possible;
-}
-
-typedef struct {
- gint offset;
- GNode *node;
-} SortTuple;
-
-static gint
-folder_sort_callback (gconstpointer a, gconstpointer b, gpointer user_data)
-{
- EStorageSetStore *store = (EStorageSetStore *) user_data;
- EStorageSetStorePrivate *priv = store->priv;
- EFolder *folder_1, *folder_2;
- char *folder_path_1, *folder_path_2;
- int priority_1, priority_2;
-
-
- folder_path_1 = (gchar *)((SortTuple *)a)->node->data;
- folder_path_2 = (gchar *)((SortTuple *)b)->node->data;
-
- folder_1 = e_storage_set_get_folder (priv->storage_set, folder_path_1);
- folder_2 = e_storage_set_get_folder (priv->storage_set, folder_path_2);
-
- priority_1 = e_folder_get_sorting_priority (folder_1);
- priority_2 = e_folder_get_sorting_priority (folder_2);
-
- if (priority_1 == priority_2)
- return g_utf8_collate (e_folder_get_name (folder_1), e_folder_get_name (folder_2));
- else if (priority_1 < priority_2)
- return -1;
- else /* priority_1 > priority_2 */
- return +1;
-}
-
-static gint
-storage_sort_callback (gconstpointer a, gconstpointer b, gpointer user_data)
-{
- char *folder_path_1;
- char *folder_path_2;
- gboolean path_1_local;
- gboolean path_2_local;
-
- folder_path_1 = (gchar *)((SortTuple *)a)->node->data;
- folder_path_2 = (gchar *)((SortTuple *)b)->node->data;
-
- /* FIXME bad hack to put the "my evolution" and "local" storages on
- * top. */
-
- if (strcmp (folder_path_1, E_SUMMARY_STORAGE_NAME) == 0)
- return -1;
- if (strcmp (folder_path_2, E_SUMMARY_STORAGE_NAME) == 0)
- return +1;
-
- path_1_local = ! strcmp (folder_path_1, E_LOCAL_STORAGE_NAME);
- path_2_local = ! strcmp (folder_path_2, E_LOCAL_STORAGE_NAME);
-
- if (path_1_local && path_2_local)
- return 0;
- if (path_1_local)
- return -1;
- if (path_2_local)
- return 1;
-
- return g_utf8_collate (folder_path_1, folder_path_2);
-}
-
-static void
-esss_sort (EStorageSetStore *store, GNode *parent, GCompareDataFunc callback)
-{
- GtkTreeIter iter;
- GArray *sort_array;
- GNode *node;
- GNode *tmp_node;
- gint list_length;
- gint i;
- gint *new_order;
- GtkTreePath *path;
-
- node = parent->children;
- if (node == NULL || node->next == NULL)
- return;
-
- list_length = 0;
- for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
- list_length++;
-
- sort_array = g_array_sized_new(FALSE, FALSE, sizeof(SortTuple), list_length);
-
- i = 0;
- for (tmp_node = node; tmp_node; tmp_node = tmp_node->next) {
- SortTuple tuple;
-
- tuple.offset = i;
- tuple.node = tmp_node;
- g_array_append_val(sort_array, tuple);
- i++;
- }
-
- /* Sort the array */
- g_array_sort_with_data(sort_array, callback, store);
-
- for (i = 0; i < list_length - 1; i++) {
- g_array_index(sort_array, SortTuple, i).node->next =
- g_array_index(sort_array, SortTuple, i + 1).node;
- g_array_index(sort_array, SortTuple, i + 1).node->prev =
- g_array_index(sort_array, SortTuple, i).node;
- }
- g_array_index(sort_array, SortTuple, list_length - 1).node->next = NULL;
- g_array_index(sort_array, SortTuple, 0).node->prev = NULL;
- parent->children = g_array_index(sort_array, SortTuple, 0).node;
-
- /* Let the world know about our new order */
- new_order = g_new(gint, list_length);
- for (i = 0; i < list_length; i++)
- new_order[i] = g_array_index(sort_array, SortTuple, i).offset;
-
- iter.stamp = store->priv->stamp;
- iter.user_data = parent;
- path = esss_get_path(GTK_TREE_MODEL(store), &iter);
- gtk_tree_model_rows_reordered(GTK_TREE_MODEL(store), path, &iter, new_order);
- if (path)
- gtk_tree_path_free(path);
- g_free(new_order);
- g_array_free(sort_array, TRUE);
-}
-
-static void
-esss_init(EStorageSetStore *store)
-{
- store->priv = g_new0(EStorageSetStorePrivate, 1);
-
- store->priv->storage_set = NULL;
- store->priv->checkboxes = NULL;
- store->priv->root = g_node_new(NULL);
- do {
- store->priv->stamp = g_random_int();
- } while (store->priv->stamp == 0);
-
- store->priv->path_to_node = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- store->priv->type_name_to_pixbuf = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-static void
-esss_dispose(GObject *object)
-{
- EStorageSetStore *store = E_STORAGE_SET_STORE(object);
-
- if (store->priv->storage_set)
- g_object_unref(store->priv->storage_set);
- store->priv->storage_set = NULL;
-
- (*parent_class->dispose) (object);
-}
-
-static void
-node_free (GNode *node, gpointer data)
-{
- g_free (node->data);
-}
-
-static void
-pixbuf_free_func (gpointer key, gpointer value, gpointer user_data)
-{
- g_free (key);
- g_object_unref (value);
-}
-
-static void
-esss_finalize(GObject *object)
-{
- EStorageSetStore *store = E_STORAGE_SET_STORE(object);
-
- g_node_children_foreach(store->priv->root, G_TRAVERSE_ALL, node_free, NULL);
-
- g_hash_table_foreach (store->priv->type_name_to_pixbuf, pixbuf_free_func, NULL);
- g_hash_table_destroy (store->priv->type_name_to_pixbuf);
- g_hash_table_destroy (store->priv->path_to_node);
- if (store->priv->checkboxes)
- g_hash_table_destroy (store->priv->checkboxes);
-
- g_free (store->priv);
-
- (*parent_class->finalize) (object);
-}
-
-static void
-esss_class_init(EStorageSetStoreClass *class)
-{
- GObjectClass *object_class;
-
- parent_class = g_type_class_peek_parent(class);
- object_class = (GObjectClass *) class;
-
- object_class->dispose = esss_dispose;
- object_class->finalize = esss_finalize;
-}
-
-GType
-e_storage_set_store_get_type(void)
-{
- static GType store_type = 0;
-
- if (!store_type) {
- static const GTypeInfo store_info = {
- sizeof(EStorageSetStoreClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) esss_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(EStorageSetStore),
- 0, /* n_preallocs */
- (GInstanceInitFunc) esss_init
- };
-
- static const GInterfaceInfo tree_model_info = {
- (GInterfaceInitFunc)
- esss_tree_model_init,
- NULL,
- NULL
- };
-
- static const GInterfaceInfo drag_source_info = {
- (GInterfaceInitFunc)
- esss_drag_source_init,
- NULL,
- NULL
- };
-
- static const GInterfaceInfo drag_dest_info = {
- (GInterfaceInitFunc) esss_drag_dest_init,
- NULL,
- NULL
- };
-
- store_type = g_type_register_static(G_TYPE_OBJECT, "EStorageSetStore", &store_info, 0);
-
- g_type_add_interface_static(store_type, GTK_TYPE_TREE_MODEL, &tree_model_info);
- g_type_add_interface_static(store_type, GTK_TYPE_TREE_DRAG_SOURCE, &drag_source_info);
- g_type_add_interface_static(store_type, GTK_TYPE_TREE_DRAG_DEST, &drag_dest_info);
- }
-
- return store_type;
-}
-
-/* Handling of the "changed" signal in EFolders displayed in the EStorageSetStore. */
-
-typedef struct {
- EStorageSetStore *store;
- GNode * node;
-} FolderChangedCallbackData;
-
-static void
-folder_changed_cb (EFolder *folder, void *data)
-{
- FolderChangedCallbackData *callback_data;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- callback_data = (FolderChangedCallbackData *) data;
- iter.user_data = callback_data->node;
- iter.stamp = callback_data->store->priv->stamp;
- path = esss_get_path (GTK_TREE_MODEL (callback_data->store), &iter);
-
- gtk_tree_model_row_changed (GTK_TREE_MODEL (callback_data->store), path, &iter);
- if (path)
- gtk_tree_path_free (path);
-}
-
-static void
-folder_name_changed_cb (EFolder *folder, void *data)
-{
- FolderChangedCallbackData *callback_data;
-
- callback_data = (FolderChangedCallbackData *) data;
-
- esss_sort (callback_data->store, callback_data->node->parent, folder_sort_callback);
-}
-
-static void
-setup_folder_changed_callbacks (EStorageSetStore *store, EFolder *folder, GNode *node)
-{
- FolderChangedCallbackData *callback_data = g_new0 (FolderChangedCallbackData, 1);
- callback_data->store = store;
- callback_data->node = node;
-
- g_signal_connect (G_OBJECT (folder), "changed",
- G_CALLBACK (folder_changed_cb), callback_data);
-
- g_signal_connect_data (G_OBJECT (folder), "name_changed",
- G_CALLBACK (folder_name_changed_cb),
- callback_data, (GClosureNotify)g_free, 0);
-}
-
-static void
-insert_folders (EStorageSetStore *store, GNode *parent, EStorage *storage, const gchar *path)
-{
- EStorageSetStorePrivate *priv;
- GList *folder_path_list, *p;
- const gchar *storage_name = e_storage_get_name (storage);
-
- priv = store->priv;
-
- folder_path_list = e_storage_get_subfolder_paths (storage, path);
- if (folder_path_list == NULL)
- return;
-
- for (p = folder_path_list; p != NULL; p = p->next) {
- EFolder *folder;
- const char *subpath = (const char *) p->data;
- char *folder_path = g_strconcat ("/", storage_name, subpath, NULL);
- gchar *key = g_strdup (folder_path+1);
- GNode *node = g_node_new (folder_path);
-
- g_node_append (parent, node);
- g_hash_table_replace (priv->path_to_node, key, node);
-
- folder = e_storage_get_folder (storage, subpath);
- setup_folder_changed_callbacks (store, folder, node);
-
- insert_folders (store, node, storage, subpath);
- }
-
- esss_sort (store, parent, folder_sort_callback);
-
- e_free_string_list (folder_path_list);
-}
-
-/* StorageSet signal handling. */
-
-static void
-new_storage_cb (EStorageSet *storage_set, EStorage *storage, void *data)
-{
- EStorageSetStore *store = E_STORAGE_SET_STORE (data);
- EStorageSetStorePrivate *priv = store->priv;
- gchar *storage_name = g_strdup (e_storage_get_name (storage));
- GNode *node = g_node_new (g_strdup (e_storage_get_name (storage)));
- GtkTreePath *path;
- GtkTreeIter iter;
-
- g_hash_table_replace (priv->path_to_node, storage_name, node);
- g_node_append (priv->root, node);
- esss_sort (store, priv->root, storage_sort_callback);
-
- iter.user_data = node;
- iter.stamp = store->priv->stamp;
- path = esss_get_path (GTK_TREE_MODEL (store), &iter);
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (store), path, &iter);
- if (path)
- gtk_tree_path_free (path);
-}
-
-static void
-removed_storage_cb (EStorageSet *storage_set, EStorage *storage, void *data)
-{
- EStorageSetStore *store = E_STORAGE_SET_STORE (data);
- EStorageSetStorePrivate *priv = store->priv;
- const gchar *name = e_storage_get_name (storage);
- GNode *node = g_hash_table_lookup (priv->path_to_node, name);
- GtkTreePath *path;
-
- if (node == NULL) {
- g_warning ("EStorageSetStore: unknown storage removed -- %s", name);
- return;
- }
-
- g_hash_table_remove (priv->path_to_node, name);
- /* FIXME: subfolder hashtable entries might be leaked */
-
- path = tree_path_from_node (store, node);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (store), path);
- if (path)
- gtk_tree_path_free (path);
- g_node_destroy (node);
-}
-
-static void
-new_folder_cb (EStorageSet *storage_set, const char *path, void *data)
-{
- EStorageSetStore *store = E_STORAGE_SET_STORE (data);
- EStorageSetStorePrivate *priv = store->priv;
- GNode *parent_node, *new_node;
- const char *last_separator;
- char *parent_path;
- char *copy_of_path;
- GtkTreeIter iter;
- GtkTreePath *treepath;
-
- last_separator = strrchr (path, E_PATH_SEPARATOR);
-
- parent_path = g_strndup (path + 1, last_separator - path - 1);
- parent_node = g_hash_table_lookup (priv->path_to_node, parent_path);
- g_free (parent_path);
- if (parent_node == NULL) {
- g_warning ("EStorageSetStore: EStorageSet reported new subfolder for non-existing folder -- %s", parent_path);
- return;
- }
-
- copy_of_path = g_strdup (path);
- new_node = g_node_new (copy_of_path);
- g_node_append (parent_node, new_node);
- iter.user_data = new_node;
- iter.stamp = priv->stamp;
- treepath = esss_get_path (GTK_TREE_MODEL (store), &iter);
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (store), treepath, &iter);
- if (treepath)
- gtk_tree_path_free (treepath);
-
- g_hash_table_replace (priv->path_to_node, g_strdup (path + 1), new_node);
-
- setup_folder_changed_callbacks (store, e_storage_set_get_folder (storage_set, path), new_node);
- esss_sort (store, parent_node, folder_sort_callback);
-}
-
-static void
-updated_folder_cb (EStorageSet *storage_set, const char *path, void *data)
-{
- EStorageSetStore *store = E_STORAGE_SET_STORE (data);
- EStorageSetStorePrivate *priv = store->priv;
- GNode *node;
- GtkTreeIter iter;
- GtkTreePath *treepath;
-
- node = g_hash_table_lookup (priv->path_to_node, path+1);
- if (node == NULL) {
- g_warning ("EStorageSetStore: unknown folder updated -- %s", path);
- return;
- }
-
- iter.user_data = node;
- iter.stamp = priv->stamp;
- treepath = esss_get_path (GTK_TREE_MODEL (store), &iter);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (store), treepath, &iter);
- if (treepath)
- gtk_tree_path_free (treepath);
-}
-
-static void
-removed_folder_cb (EStorageSet *storage_set, const char *path, void *data)
-{
- EStorageSetStore *store = E_STORAGE_SET_STORE (data);
- EStorageSetStorePrivate *priv = store->priv;
- GNode *node;
- GtkTreePath *treepath;
-
- node = g_hash_table_lookup (priv->path_to_node, path+1);
- if (node == NULL) {
- g_warning ("EStorageSetStore: unknown folder removed -- %s", path);
- return;
- }
-
- g_hash_table_remove (priv->path_to_node, path+1);
- /* FIXME: subfolder hashtable entries might be leaked */
-
- treepath = tree_path_from_node (store, node);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (store), treepath);
- if (treepath)
- gtk_tree_path_free (treepath);
- g_node_destroy (node);
-}
-
-static void
-close_folder_cb (EStorageSet *storage_set,
- const char *path,
- void *data)
-{
- g_warning ("FIXME: EStorageSetStore: needs to handle close_folder properly");
-#if 0
- EStorageSetStore *store;
- EStorageSetStorePrivate *priv;
- ETreeModel *etree;
- ETreePath node;
-
- store = E_STORAGE_SET_STORE (data);
- priv = store->priv;
- etree = priv->etree_model;
-
- node = lookup_node_in_hash (store, path);
- e_tree_model_node_request_collapse (priv->etree_model, node);
-#endif
-}
-
-static void
-connect_storage_set (EStorageSetStore *store, EStorageSet *storage_set, gboolean show_folders)
-{
- EStorageSetStorePrivate *priv;
- GList *storage_list;
- GList *p;
-
- priv = store->priv;
- priv->storage_set = storage_set;
- g_object_ref (storage_set);
-
- storage_list = e_storage_set_get_storage_list (storage_set);
-
- for (p = storage_list; p != NULL; p = p->next) {
- EStorage *storage = E_STORAGE (p->data);
- const char *name = e_storage_get_name (storage);
- GNode *node = g_node_new (g_strdup (name));
- g_node_append (priv->root, node);
- g_hash_table_replace (priv->path_to_node, g_strdup (name), node);
-
- if (show_folders)
- insert_folders (store, node, storage, "/");
- }
-
- esss_sort (store, priv->root, storage_sort_callback);
-
- e_free_object_list (storage_list);
-
- g_signal_connect_object (storage_set, "new_storage", G_CALLBACK (new_storage_cb), store, 0);
- g_signal_connect_object (storage_set, "removed_storage", G_CALLBACK (removed_storage_cb), store, 0);
- if (!show_folders)
- return;
-
- g_signal_connect_object (storage_set, "new_folder", G_CALLBACK (new_folder_cb), store, 0);
- g_signal_connect_object (storage_set, "updated_folder", G_CALLBACK (updated_folder_cb), store, 0);
- g_signal_connect_object (storage_set, "removed_folder", G_CALLBACK (removed_folder_cb), store, 0);
- g_signal_connect_object (storage_set, "close_folder", G_CALLBACK (close_folder_cb), store, 0);
-}
-
-/**
- * e_storage_set_store_new:
- * @storage_set: the #EStorageSet that the store exposes
- * @show_folders: flag indicating if subfolders should be shown
- *
- * Creates a new tree store from the provided #EStorageSet.
- *
- * Return value: a new #EStorageSetStore
- **/
-EStorageSetStore *
-e_storage_set_store_new(EStorageSet *storage_set, gboolean show_folders)
-{
- EStorageSetStore *store;
- g_return_val_if_fail (E_IS_STORAGE_SET(storage_set), NULL);
-
- store = E_STORAGE_SET_STORE (g_object_new (E_STORAGE_SET_STORE_TYPE, NULL));
- connect_storage_set (store, storage_set, show_folders);
-
- return store;
-}
-
-static gboolean
-esss_real_set_value(EStorageSetStore *store, GtkTreeIter *iter, gint column, GValue *value)
-{
- gchar *path;
-
- if (column != E_STORAGE_SET_STORE_COLUMN_CHECKED)
- return FALSE;
-
- path = G_NODE (iter->user_data)->data;
-
- if (g_value_get_boolean (value)) {
- g_hash_table_insert (store->priv->checkboxes, path, path);
- } else {
- g_hash_table_remove (store->priv->checkboxes, path);
- }
-
- return TRUE;
-}
-
-/**
- * e_storage_set_store_set_value:
- * @store: a #EStorageSetStore
- * @iter: A valid #GtkTreeIter for the row being modified
- * @column: column number to modify
- * @value: new value for the cell
- *
- * Sets the data in the cell specified by @iter and @column.
- * The type of @value must be convertible to the type of the
- * column.
- *
- **/
-void
-e_storage_set_store_set_value(EStorageSetStore *store, GtkTreeIter *iter,
- gint column, GValue *value)
-{
- g_return_if_fail(E_IS_STORAGE_SET_STORE(store));
- g_return_if_fail(VALID_ITER(iter, store));
- g_return_if_fail(VALID_COL(column));
- g_return_if_fail(G_IS_VALUE(value));
-
- if (esss_real_set_value (store, iter, column, value)) {
- GtkTreePath *path;
-
- path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), iter);
- gtk_tree_model_row_changed(GTK_TREE_MODEL(store), path, iter);
- if (path)
- gtk_tree_path_free(path);
- }
-}
-
-/**
- * e_storage_set_store_get_tree_path:
- * @store: a #EStorageSetStore
- * @folder_path: a string representing the #EStorageSet folder path
- *
- * Gets a #GtkTreePath corresponding to the folder path specified.
- *
- * Return value: the tree path of the folder
- **/
-GtkTreePath *
-e_storage_set_store_get_tree_path (EStorageSetStore *store, const gchar *folder_path)
-{
- GNode *node;
-
- g_return_if_fail(E_IS_STORAGE_SET_STORE(store));
-
- node = g_hash_table_lookup (store->priv->path_to_node, folder_path+1);
-
- return tree_path_from_node (store, node);
-}
-
-/**
- * e_storage_set_store_get_folder_path:
- * @store: a #EStorageSetStore
- * @folder_path: a string representing the #EStorageSet folder path
- *
- * Gets a #GtkTreePath corresponding to the folder path specified.
- *
- * Return value: the tree path of the folder
- **/
-const gchar *
-e_storage_set_store_get_folder_path (EStorageSetStore *store, GtkTreePath *tree_path)
-{
- GtkTreeIter iter;
- GNode *node;
-
- g_return_if_fail(E_IS_STORAGE_SET_STORE(store));
-
- if (!esss_get_iter (GTK_TREE_MODEL (store), &iter, tree_path))
- return NULL;
-
- node = G_NODE (iter.user_data);
-
- return (const gchar *)node->data;
-}
-
-/**
- * e_storage_set_store_set_has_checkbox_func:
- * @store: a #EStorageSetStore
- * @func: a callback to determine if a row is checked
- * @data: callback data
- *
- * Sets a callback function for checkbox visibility determination
- **/
-void
-e_storage_set_store_set_has_checkbox_func (EStorageSetStore *store, EStorageSetStoreHasCheckBoxFunc func, gpointer data)
-{
- g_return_if_fail(E_IS_STORAGE_SET_STORE(store));
-
- store->priv->has_checkbox_func = func;
- store->priv->has_checkbox_func_data = data;
-}
-