aboutsummaryrefslogtreecommitdiffstats
path: root/mail/em-folder-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/em-folder-tree.c')
-rw-r--r--mail/em-folder-tree.c2039
1 files changed, 863 insertions, 1176 deletions
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index b13a47a0e0..7c9293ca19 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -48,6 +48,7 @@
#include <camel/camel-file-utils.h>
#include <camel/camel-stream-fs.h>
+#include "e-util/e-account-utils.h"
#include "e-util/e-mktemp.h"
#include "e-util/e-request.h"
#include "e-util/e-icon-factory.h"
@@ -60,12 +61,10 @@
#include "mail-ops.h"
#include "mail-tools.h"
#include "mail-config.h"
-#include "mail-component.h"
#include "mail-send-recv.h"
#include "mail-vfolder.h"
#include "em-utils.h"
-#include "em-popup.h"
#include "em-folder-tree.h"
#include "em-folder-utils.h"
#include "em-folder-selector.h"
@@ -73,8 +72,14 @@
#include "em-folder-properties.h"
#include "em-event.h"
+#include "e-mail-local.h"
+
#define d(x)
+#define EM_FOLDER_TREE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FOLDER_TREE, EMFolderTreePrivate))
+
struct _selected_uri {
gchar *key; /* store:path or account/path */
gchar *uri;
@@ -83,9 +88,6 @@ struct _selected_uri {
};
struct _EMFolderTreePrivate {
- GtkTreeView *treeview;
- EMFolderTreeModel *model;
-
GSList *select_uris; /* selected_uri structures of each path pending selection. */
GHashTable *select_uris_table; /*Removed as they're encountered, so use this to find uri's not presnet but selected */
@@ -93,14 +95,11 @@ struct _EMFolderTreePrivate {
gboolean (*excluded_func)(EMFolderTree *emft, GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
gpointer excluded_data;
- guint do_multiselect:1; /* multiple select mode */
guint cursor_set:1; /* set to TRUE means we or something
* else has set the cursor, otherwise
* we need to set it when we set the
* selection */
- guint save_state_id;
-
guint autoscroll_id;
guint autoexpand_id;
GtkTreeRowReference *autoexpand_row;
@@ -115,7 +114,7 @@ struct _EMFolderTreePrivate {
enum {
FOLDER_ACTIVATED, /* aka double-clicked or user hit enter */
FOLDER_SELECTED,
- HIDDEN_KEY_EVENT,
+ POPUP_EVENT,
LAST_SIGNAL
};
@@ -154,101 +153,613 @@ static guint signals[LAST_SIGNAL] = { 0 };
extern CamelSession *session;
extern CamelStore *vfolder_store;
-static void em_folder_tree_class_init (EMFolderTreeClass *klass);
-static void em_folder_tree_init (EMFolderTree *emft);
-static void em_folder_tree_destroy (GtkObject *obj);
-static void em_folder_tree_finalize (GObject *obj);
+struct _emft_selection_data {
+ GtkTreeModel *model;
+ GtkTreeIter *iter;
+ gboolean set;
+};
-static gboolean emft_save_state (EMFolderTree *emft);
-static void emft_queue_save_state (EMFolderTree *emft);
+static gpointer parent_class = NULL;
-static void emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter *iter, gboolean expanded);
+struct _EMFolderTreeGetFolderInfo {
+ MailMsg base;
-static void emft_tree_row_activated (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, EMFolderTree *emft);
-static gboolean emft_tree_test_collapse_row (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *path, EMFolderTree *emft);
-static void emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *path, EMFolderTree *emft);
-static gboolean emft_tree_button_press (GtkTreeView *treeview, GdkEventButton *event, EMFolderTree *emft);
-static void emft_tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft);
-static gboolean emft_tree_user_event (GtkTreeView *treeview, GdkEvent *e, EMFolderTree *emft);
-static gboolean emft_popup_menu (GtkWidget *widget);
+ /* input data */
+ GtkTreeRowReference *root;
+ EMFolderTree *emft;
+ CamelStore *store;
+ guint32 flags;
+ gchar *top;
-struct _emft_selection_data {
+ /* output data */
+ CamelFolderInfo *fi;
+};
+
+static gchar *
+emft_get_folder_info__desc (struct _EMFolderTreeGetFolderInfo *m)
+{
+ gchar *ret, *name;
+
+ name = camel_service_get_name((CamelService *)m->store, TRUE);
+ ret = g_strdup_printf(_("Scanning folders in \"%s\""), name);
+ g_free(name);
+ return ret;
+}
+
+static void
+emft_get_folder_info__exec (struct _EMFolderTreeGetFolderInfo *m)
+{
+ guint32 flags = m->flags | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+
+ m->fi = camel_store_get_folder_info (m->store, m->top, flags, &m->base.ex);
+}
+
+static void
+emft_get_folder_info__done (struct _EMFolderTreeGetFolderInfo *m)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreeIter root, iter, titer;
+ CamelFolderInfo *fi;
+ GtkTreeView *tree_view;
GtkTreeModel *model;
- GtkTreeIter *iter;
- gboolean set;
+ GtkTreePath *path;
+ gboolean is_store;
+
+ /* check that we haven't been destroyed */
+ g_return_if_fail (GTK_IS_TREE_VIEW (m->emft));
+
+ /* check that our parent folder hasn't been deleted/unsubscribed */
+ if (!gtk_tree_row_reference_valid (m->root))
+ return;
+
+ tree_view = GTK_TREE_VIEW (m->emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ si = em_folder_tree_model_lookup_store_info (
+ EM_FOLDER_TREE_MODEL (model), m->store);
+ if (si == NULL) {
+ /* store has been removed in the interim - do nothing */
+ return;
+ }
+
+ path = gtk_tree_row_reference_get_path (m->root);
+ gtk_tree_model_get_iter (model, &root, path);
+
+ /* if we had an error, then we need to re-set the load subdirs state and collapse the node */
+ if (!m->fi && camel_exception_is_set(&m->base.ex)) {
+ gtk_tree_store_set(
+ GTK_TREE_STORE (model), &root,
+ COL_BOOL_LOAD_SUBDIRS, TRUE, -1);
+ gtk_tree_view_collapse_row (tree_view, path);
+ gtk_tree_path_free (path);
+ return;
+ }
+
+ gtk_tree_path_free (path);
+
+ /* make sure we still need to load the tree subfolders... */
+ gtk_tree_model_get (model, &root, COL_BOOL_IS_STORE, &is_store, -1);
+
+ /* get the first child (which will be a dummy node) */
+ gtk_tree_model_iter_children (model, &iter, &root);
+
+ /* Traverse to the last valid iter */
+ titer = iter;
+ while (gtk_tree_model_iter_next (model, &iter))
+ titer = iter; /* Preserve the last valid iter */
+
+ iter = titer;
+
+ /* FIXME: camel's IMAP code is totally on crack here, @top's
+ * folder info should be @fi and fi->child should be what we
+ * want to fill our tree with... *sigh* */
+ if (m->top && m->fi && !strcmp (m->fi->full_name, m->top)) {
+ if (!(fi = m->fi->child))
+ fi = m->fi->next;
+ } else
+ fi = m->fi;
+
+ if (fi == NULL) {
+ /* no children afterall... remove the "Loading..." placeholder node */
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+
+ if (is_store) {
+ path = gtk_tree_model_get_path (model, &root);
+ gtk_tree_view_collapse_row (tree_view, path);
+ gtk_tree_path_free (path);
+ return;
+ }
+ } else {
+ gint fully_loaded = (m->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? TRUE : FALSE;
+
+ do {
+ gboolean known = g_hash_table_lookup (si->full_hash, fi->full_name) != NULL;
+
+ if (!known)
+ em_folder_tree_model_set_folder_info (
+ EM_FOLDER_TREE_MODEL (model),
+ &iter, si, fi, fully_loaded);
+
+ if ((fi = fi->next) != NULL && !known)
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &root);
+ } while (fi != NULL);
+ }
+
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), &root,
+ COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
+}
+
+static void
+emft_get_folder_info__free (struct _EMFolderTreeGetFolderInfo *m)
+{
+ camel_store_free_folder_info (m->store, m->fi);
+
+ gtk_tree_row_reference_free (m->root);
+ g_object_unref(m->emft);
+ camel_object_unref (m->store);
+ g_free (m->top);
+}
+
+static MailMsgInfo get_folder_info_info = {
+ sizeof (struct _EMFolderTreeGetFolderInfo),
+ (MailMsgDescFunc) emft_get_folder_info__desc,
+ (MailMsgExecFunc) emft_get_folder_info__exec,
+ (MailMsgDoneFunc) emft_get_folder_info__done,
+ (MailMsgFreeFunc) emft_get_folder_info__free
};
-static GtkVBoxClass *parent_class = NULL;
+static void
+folder_tree_emit_popup_event (EMFolderTree *emft,
+ GdkEvent *event)
+{
+ g_signal_emit (emft, signals[POPUP_EVENT], 0, event);
+}
-GType
-em_folder_tree_get_type (void)
+static void
+emft_free_select_uri (struct _selected_uri *u)
{
- static GType type = 0;
+ g_free (u->uri);
+ if (u->store)
+ camel_object_unref (u->store);
+ g_free (u->key);
+ g_free (u->path);
+ g_free (u);
+}
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderTreeClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_tree_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderTree),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_tree_init,
- };
+static gboolean
+emft_select_func (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean selected)
+{
+ EMFolderTreePrivate *priv;
+ GtkTreeView *tree_view;
+ gboolean is_store;
+ guint32 flags;
+ GtkTreeIter iter;
+
+ tree_view = gtk_tree_selection_get_tree_view (selection);
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (tree_view);
+
+ if (selected)
+ return TRUE;
+
+ if (priv->excluded == 0 && priv->excluded_func == NULL)
+ return TRUE;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return TRUE;
+
+ if (priv->excluded_func != NULL)
+ return priv->excluded_func(
+ EM_FOLDER_TREE (tree_view), model,
+ &iter, priv->excluded_data);
+
+ gtk_tree_model_get (
+ model, &iter, COL_UINT_FLAGS, &flags,
+ COL_BOOL_IS_STORE, &is_store, -1);
+
+ if (is_store)
+ flags |= CAMEL_FOLDER_NOSELECT;
+
+ return (flags & priv->excluded) == 0;
+}
+
+static void
+emft_clear_selected_list(EMFolderTree *emft)
+{
+ EMFolderTreePrivate *priv = emft->priv;
+
+ g_slist_foreach(priv->select_uris, (GFunc) emft_free_select_uri, NULL);
+ g_slist_free(priv->select_uris);
+ g_hash_table_destroy(priv->select_uris_table);
+ priv->select_uris = NULL;
+ priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
+ priv->cursor_set = FALSE;
+}
+
+static void
+emft_selection_changed_cb (EMFolderTree *emft,
+ GtkTreeSelection *selection)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GList *list;
+ guint32 flags = 0;
+ guint unread = 0;
+ guint old_unread = 0;
+ gchar *full_name = NULL;
+ gchar *uri = NULL;
- type = g_type_register_static (GTK_TYPE_VBOX, "EMFolderTree", &info, 0);
+ list = gtk_tree_selection_get_selected_rows (selection, &model);
+
+ if (list == NULL)
+ goto exit;
+
+ gtk_tree_model_get_iter (model, &iter, list->data);
+
+ gtk_tree_model_get (
+ model, &iter,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags,
+ COL_UINT_UNREAD, &unread, COL_UINT_UNREAD_LAST_SEL,
+ &old_unread, -1);
+
+ /* Sync unread counts to distinguish new incoming mail. */
+ if (unread != old_unread)
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), &iter,
+ COL_UINT_UNREAD_LAST_SEL, unread, -1);
+
+exit:
+ g_signal_emit (
+ emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
+
+ g_free (full_name);
+ g_free (uri);
+
+ g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (list);
+}
+
+static void
+folder_tree_finalize (GObject *object)
+{
+ EMFolderTreePrivate *priv;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (object);
+
+ if (priv->select_uris != NULL) {
+ g_slist_foreach (
+ priv->select_uris,
+ (GFunc) emft_free_select_uri, NULL);
+ g_slist_free (priv->select_uris);
+ g_hash_table_destroy (priv->select_uris_table);
+ priv->select_uris = NULL;
}
- return type;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-em_folder_tree_class_init (EMFolderTreeClass *klass)
+em_folder_tree_destroy (GtkObject *object)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ EMFolderTreePrivate *priv;
+ GtkTreeModel *model;
- parent_class = g_type_class_ref (GTK_TYPE_VBOX);
+ priv = EM_FOLDER_TREE_GET_PRIVATE (object);
- object_class->finalize = em_folder_tree_finalize;
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
+
+ if (priv->loaded_row_id != 0) {
+ g_signal_handler_disconnect (model, priv->loaded_row_id);
+ priv->loaded_row_id = 0;
+ }
+
+ if (priv->autoscroll_id != 0) {
+ g_source_remove (priv->autoscroll_id);
+ priv->autoscroll_id = 0;
+ }
+
+ if (priv->autoexpand_id != 0) {
+ gtk_tree_row_reference_free (priv->autoexpand_row);
+ priv->autoexpand_row = NULL;
+
+ g_source_remove (priv->autoexpand_id);
+ priv->autoexpand_id = 0;
+ }
+
+ /* Chain up to parent's destroy() method. */
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+static gboolean
+emft_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ EMFolderTreePrivate *priv;
+ GtkWidgetClass *widget_class;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreePath *path;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (widget);
+
+ tree_view = GTK_TREE_VIEW (widget);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE)
+ emft_clear_selected_list (EM_FOLDER_TREE (widget));
+
+ priv->cursor_set = TRUE;
+
+ if (event->button != 3)
+ goto chainup;
+
+ if (!gtk_tree_view_get_path_at_pos (
+ tree_view, event->x, event->y,
+ &path, NULL, NULL, NULL))
+ goto chainup;
+
+ /* select/focus the row that was right-clicked */
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
+
+ gtk_tree_path_free (path);
+
+ folder_tree_emit_popup_event (
+ EM_FOLDER_TREE (tree_view), (GdkEvent *) event);
+
+chainup:
+
+ /* Chain up to parent's button_press_event() method. */
+ widget_class = GTK_WIDGET_CLASS (parent_class);
+ return widget_class->button_press_event (widget, event);
+}
+
+static gboolean
+emft_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ EMFolderTreePrivate *priv;
+ GtkWidgetClass *widget_class;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (widget);
+
+ tree_view = GTK_TREE_VIEW (widget);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE)
+ emft_clear_selected_list (EM_FOLDER_TREE (widget));
+
+ priv->cursor_set = TRUE;
+
+ /* Chain up to parent's key_press_event() method. */
+ widget_class = GTK_WIDGET_CLASS (parent_class);
+ return widget_class->key_press_event (widget, event);
+}
+
+static gboolean
+emft_popup_menu (GtkWidget *widget)
+{
+ folder_tree_emit_popup_event (EM_FOLDER_TREE (widget), NULL);
+
+ return TRUE;
+}
+
+static void
+emft_row_activated (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column)
+{
+ EMFolderTreePrivate *priv;
+ GtkTreeModel *model;
+ gchar *full_name, *uri;
+ GtkTreeIter iter;
+ guint32 flags;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (tree_view);
+
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (priv->skip_double_click)
+ return;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return;
+
+ gtk_tree_model_get (
+ model, &iter, COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags, -1);
+
+ emft_clear_selected_list (EM_FOLDER_TREE (tree_view));
+
+ g_signal_emit (
+ tree_view, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
+
+ g_signal_emit (
+ tree_view, signals[FOLDER_ACTIVATED], 0, full_name, uri);
+
+ g_free (full_name);
+ g_free (uri);
+}
+
+static gboolean
+emft_test_collapse_row (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter cursor;
+
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &cursor))
+ goto exit;
+
+ /* Select the collapsed node IFF it is a
+ * parent of the currently selected folder. */
+ if (gtk_tree_store_is_ancestor (GTK_TREE_STORE (model), iter, &cursor))
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
+
+exit:
+ return FALSE;
+}
+
+static void
+emft_row_expanded (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ struct _EMFolderTreeGetFolderInfo *msg;
+ GtkTreeModel *model;
+ CamelStore *store;
+ gchar *full_name;
+ gboolean load;
+
+ model = gtk_tree_view_get_model (tree_view);
+
+ gtk_tree_model_get (
+ model, iter,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_LOAD_SUBDIRS, &load, -1);
+
+ if (!load) {
+ g_free (full_name);
+ return;
+ }
+
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), iter,
+ COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
+
+ msg = mail_msg_new (&get_folder_info_info);
+ msg->root = gtk_tree_row_reference_new (model, path);
+ camel_object_ref (store);
+ msg->store = store;
+ msg->emft = g_object_ref (tree_view);
+ msg->top = full_name;
+ msg->flags =
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE |
+ CAMEL_STORE_FOLDER_INFO_FAST;
+
+ mail_msg_unordered_push (msg);
+}
+
+static void
+folder_tree_class_init (EMFolderTreeClass *class)
+{
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+ GtkWidgetClass *widget_class;
+ GtkTreeViewClass *tree_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFolderTreePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = folder_tree_finalize;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
gtk_object_class->destroy = em_folder_tree_destroy;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->button_press_event = emft_button_press_event;
+ widget_class->key_press_event = emft_key_press_event;
widget_class->popup_menu = emft_popup_menu;
- signals[FOLDER_SELECTED] =
- g_signal_new ("folder-selected",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeClass, folder_selected),
- NULL, NULL,
- e_marshal_VOID__STRING_STRING_UINT,
- G_TYPE_NONE, 3,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_UINT);
-
- signals[FOLDER_ACTIVATED] =
- g_signal_new ("folder-activated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeClass, folder_activated),
- NULL, NULL,
- e_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- signals[HIDDEN_KEY_EVENT] =
- g_signal_new ("hidden-key-event",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFolderTreeClass, hidden_key_event),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1, GDK_TYPE_EVENT);
+ tree_view_class = GTK_TREE_VIEW_CLASS (class);
+ tree_view_class->row_activated = emft_row_activated;
+ tree_view_class->test_collapse_row = emft_test_collapse_row;
+ tree_view_class->row_expanded = emft_row_expanded;
+
+ signals[FOLDER_SELECTED] = g_signal_new (
+ "folder-selected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeClass, folder_selected),
+ NULL, NULL,
+ e_marshal_VOID__STRING_STRING_UINT,
+ G_TYPE_NONE, 3,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_UINT);
+
+ signals[FOLDER_ACTIVATED] = g_signal_new (
+ "folder-activated",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeClass, folder_activated),
+ NULL, NULL,
+ e_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMFolderTreeClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+}
+
+static void
+folder_tree_init (EMFolderTree *emft)
+{
+ GtkTreeSelection *selection;
+ GHashTable *select_uris_table;
+ EMFolderTreeModel *model;
+
+ select_uris_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+ emft->priv = EM_FOLDER_TREE_GET_PRIVATE (emft);
+ emft->priv->select_uris_table = select_uris_table;
+
+ model = em_folder_tree_model_get_default ();
+ gtk_tree_view_set_model (GTK_TREE_VIEW (emft), GTK_TREE_MODEL (model));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (emft));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (emft_selection_changed_cb), emft);
+}
+
+GType
+em_folder_tree_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderTreeClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_tree_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderTree),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_tree_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TREE_VIEW, "EMFolderTree", &type_info, 0);
+ }
+
+ return type;
}
static gboolean
@@ -277,7 +788,7 @@ static void
render_display_name (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
- gboolean is_store, bold, subdirs_unread = FALSE;
+ gboolean is_store, bold;
guint unread;
gchar *display;
gchar *name;
@@ -286,36 +797,28 @@ render_display_name (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
COL_BOOL_IS_STORE, &is_store,
COL_UINT_UNREAD, &unread, -1);
- bold = is_store || unread;
-
- if (gtk_tree_model_iter_has_child (model, iter)) {
- gboolean expanded = TRUE;
-
- g_object_get (renderer, "is-expanded", &expanded, NULL);
-
- if (!bold || !expanded)
- subdirs_unread = subdirs_contain_unread (model, iter);
+ if (!(bold = is_store || unread)) {
+ if (gtk_tree_model_iter_has_child (model, iter))
+ bold = subdirs_contain_unread (model, iter);
}
- bold = bold || subdirs_unread;
-
if (!is_store && unread) {
/* Translators: This is the string used for displaying the
- * folder names in folder trees. The first "%s" will be
- * replaced by the folder's name and "%u" will be replaced
- * with the number of unread messages in the folder. The
- * second %s will be replaced with a "+" letter for collapsed
- * folders with unread messages in some subfolder too,
- * or with an empty string for other cases.
+ * folder names in folder trees. "%s" will be replaced by
+ * the folder's name and "%u" will be replaced with the
+ * number of unread messages in the folder.
*
- * Most languages should translate this as "%s (%u%s)". The
+ * Most languages should translate this as "%s (%u)". The
* languages that use localized digits (like Persian) may
* need to replace "%u" with "%Iu". Right-to-left languages
* (like Arabic and Hebrew) may need to add bidirectional
* formatting codes to take care of the cases the folder
* name appears in either direction.
+ *
+ * Do not translate the "folder-display|" part. Remove it
+ * from your translation.
*/
- display = g_strdup_printf (C_("folder-display", "%s (%u%s)"), name, unread, subdirs_unread ? "+" : "");
+ display = g_strdup_printf (C_("folder-display", "%s (%u)"), name, unread);
g_free (name);
} else
display = name;
@@ -333,10 +836,13 @@ render_icon (GtkTreeViewColumn *column,
GtkTreeModel *model,
GtkTreeIter *iter)
{
+ GtkTreeSelection *selection;
+ GtkWidget *tree_view;
GIcon *icon;
guint unread;
guint old_unread;
gchar *icon_name;
+ gboolean row_selected;
gtk_tree_model_get (
model, iter,
@@ -349,8 +855,12 @@ render_icon (GtkTreeViewColumn *column,
icon = g_themed_icon_new (icon_name);
+ tree_view = gtk_tree_view_column_get_tree_view (column);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+ row_selected = gtk_tree_selection_iter_is_selected (selection, iter);
+
/* Show an emblem if there's new mail. */
- if (unread > old_unread) {
+ if (!row_selected && unread > old_unread) {
GIcon *temp_icon;
GEmblem *emblem;
@@ -368,133 +878,21 @@ render_icon (GtkTreeViewColumn *column,
g_object_set (renderer, "gicon", icon, NULL);
g_object_unref (icon);
- g_free (icon_name);
-}
-
-static gboolean
-emft_select_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer data)
-{
- EMFolderTree *emft = data;
- gboolean is_store;
- guint32 flags;
- GtkTreeIter iter;
-
- /* NB: This will be called with selection==NULL from tree_row_activated */
- if (emft->priv->excluded == 0 && emft->priv->excluded_func == NULL)
- return TRUE;
-
- if (!gtk_tree_model_get_iter(model, &iter, path))
- return TRUE;
-
- if (emft->priv->excluded_func != NULL)
- return emft->priv->excluded_func(emft, model, &iter, emft->priv->excluded_data);
-
- gtk_tree_model_get(model, &iter, COL_UINT_FLAGS, &flags, COL_BOOL_IS_STORE, &is_store, -1);
- if (is_store)
- flags |= CAMEL_FOLDER_NOSELECT;
-
- return (flags & emft->priv->excluded) == 0;
-}
-
-static void
-emft_free_select_uri(gpointer v, gpointer data)
-{
- struct _selected_uri *u = v;
-
- g_free(u->uri);
- if (u->store)
- camel_object_unref(u->store);
- g_free(u->key);
- g_free(u->path);
- g_free(u);
-}
-
-static void
-em_folder_tree_init (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv;
-
- priv = g_new0 (struct _EMFolderTreePrivate, 1);
- priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
- priv->treeview = NULL;
- priv->model = NULL;
- priv->drag_row = NULL;
- priv->skip_double_click = FALSE;
-
- emft->priv = priv;
-}
-
-static void
-em_folder_tree_finalize (GObject *obj)
-{
- EMFolderTree *emft = (EMFolderTree *) obj;
-
- if (emft->priv->select_uris) {
- g_slist_foreach(emft->priv->select_uris, emft_free_select_uri, emft);
- g_slist_free(emft->priv->select_uris);
- g_hash_table_destroy(emft->priv->select_uris_table);
- emft->priv->select_uris = NULL;
- }
-
- g_free (emft->priv);
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-em_folder_tree_destroy (GtkObject *obj)
-{
- EMFolderTree *emft = (EMFolderTree *) obj;
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- if (priv->loading_row_id != 0) {
- g_signal_handler_disconnect (priv->model, priv->loading_row_id);
- priv->loading_row_id = 0;
- }
-
- if (priv->loaded_row_id != 0) {
- g_signal_handler_disconnect (priv->model, priv->loaded_row_id);
- priv->loaded_row_id = 0;
- }
-
- if (priv->save_state_id != 0) {
- g_source_remove (priv->save_state_id);
- emft_save_state (emft);
- }
-
- if (priv->autoscroll_id != 0) {
- g_source_remove (priv->autoscroll_id);
- priv->autoscroll_id = 0;
- }
-
- if (priv->autoexpand_id != 0) {
- gtk_tree_row_reference_free (priv->autoexpand_row);
- priv->autoexpand_row = NULL;
-
- g_source_remove (priv->autoexpand_id);
- priv->autoexpand_id = 0;
- }
-
- priv->treeview = NULL;
- priv->model = NULL;
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
}
static GtkTreeView *
-folder_tree_new (EMFolderTree *emft, EMFolderTreeModel *model)
+folder_tree_new (EMFolderTree *emft)
{
GtkTreeSelection *selection;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkWidget *tree;
- gboolean side_bar_search;
GConfClient *gconf;
gconf = mail_config_get_gconf_client ();
- side_bar_search = gconf_client_get_bool (gconf, "/apps/evolution/mail/display/side_bar_search", NULL);
- tree = gtk_tree_view_new_with_model ((GtkTreeModel *) model);
+ /* FIXME Gross hack */
+ tree = GTK_WIDGET (emft);
GTK_WIDGET_SET_FLAGS(tree, GTK_CAN_FOCUS);
column = gtk_tree_view_column_new ();
@@ -516,84 +914,99 @@ folder_tree_new (EMFolderTree *emft, EMFolderTreeModel *model)
selection = gtk_tree_view_get_selection ((GtkTreeView *) tree);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- gtk_tree_selection_set_select_function(selection, emft_select_func, emft, NULL);
+ gtk_tree_selection_set_select_function (
+ selection, (GtkTreeSelectionFunc)
+ emft_select_func, NULL, NULL);
gtk_tree_view_set_headers_visible ((GtkTreeView *) tree, FALSE);
gtk_tree_view_set_search_column((GtkTreeView *)tree, COL_STRING_DISPLAY_NAME);
- gtk_tree_view_set_enable_search((GtkTreeView *)tree, side_bar_search);
return (GtkTreeView *) tree;
}
static void
-em_folder_tree_construct (EMFolderTree *emft, EMFolderTreeModel *model)
+folder_tree_copy_expanded_cb (GtkTreeView *unused,
+ GtkTreePath *path,
+ GtkTreeView *tree_view)
+{
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
+}
+
+static void
+folder_tree_copy_selection_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GtkTreeView *tree_view)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkTreeSelection *selection;
- GtkWidget *scrolled;
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN);
+ selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_select_path (selection, path);
+
+ /* Center the tree view on the selected path. */
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.0);
+}
- priv->model = model;
- priv->treeview = folder_tree_new (emft, model);
- gtk_widget_show ((GtkWidget *) priv->treeview);
+static void
+folder_tree_copy_state (EMFolderTree *emft)
+{
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
- g_signal_connect (priv->treeview, "row-expanded", G_CALLBACK (emft_tree_row_expanded), emft);
- g_signal_connect (priv->treeview, "test-collapse-row", G_CALLBACK (emft_tree_test_collapse_row), emft);
- g_signal_connect (priv->treeview, "row-activated", G_CALLBACK (emft_tree_row_activated), emft);
- g_signal_connect (priv->treeview, "button-press-event", G_CALLBACK (emft_tree_button_press), emft);
- g_signal_connect (priv->treeview, "key-press-event", G_CALLBACK (emft_tree_user_event), emft);
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
- selection = gtk_tree_view_get_selection ((GtkTreeView *) priv->treeview);
- g_signal_connect (selection, "changed", G_CALLBACK (emft_tree_selection_changed), emft);
+ selection = em_folder_tree_model_get_selection (
+ EM_FOLDER_TREE_MODEL (model));
+ if (selection == NULL)
+ return;
- gtk_container_add ((GtkContainer *) scrolled, (GtkWidget *) priv->treeview);
- gtk_widget_show (scrolled);
+ gtk_tree_view_map_expanded_rows (
+ tree_view, (GtkTreeViewMappingFunc)
+ folder_tree_copy_expanded_cb, emft);
- gtk_box_pack_start ((GtkBox *) emft, scrolled, TRUE, TRUE, 0);
+ gtk_tree_selection_selected_foreach (
+ selection, (GtkTreeSelectionForeachFunc)
+ folder_tree_copy_selection_cb, emft);
}
-GtkWidget *
-em_folder_tree_new (void)
+static void
+em_folder_tree_construct (EMFolderTree *emft)
{
- EMFolderTreeModel *model;
- EMFolderTree *emft;
-
- model = em_folder_tree_model_new (e_get_user_data_dir ());
- emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
- g_object_unref (model);
-
- return (GtkWidget *) emft;
+ folder_tree_new (emft);
+ folder_tree_copy_state (emft);
+ gtk_widget_show (GTK_WIDGET (emft));
}
/* NOTE: Removes and frees the selected uri structure */
static void
emft_select_uri(EMFolderTree *emft, GtkTreePath *path, struct _selected_uri *u)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
- selection = gtk_tree_view_get_selection(priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.8f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.8f, 0.0f);
g_hash_table_remove(priv->select_uris_table, u->key);
priv->select_uris = g_slist_remove(priv->select_uris, u);
- emft_free_select_uri((gpointer)u, NULL);
+ emft_free_select_uri(u);
}
static void
-emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft)
+emft_expand_node (const gchar *key, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
struct _EMFolderTreeModelStoreInfo *si;
GtkTreeRowReference *row;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GtkTreePath *path;
EAccount *account;
CamelStore *store;
@@ -611,7 +1024,10 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
memcpy (uid, key, n);
uid[n] = '\0';
- if ((account = mail_config_get_account_by_uid (uid)) && account->enabled) {
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if ((account = e_get_account_by_uid (uid)) && account->enabled) {
CamelException ex;
camel_exception_init (&ex);
@@ -626,7 +1042,7 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
camel_object_ref (store);
} else if (!strcmp (uid, "local")) {
- if (!(store = mail_component_peek_local_store (NULL)))
+ if (!(store = e_mail_local_get_store ()))
return;
camel_object_ref (store);
@@ -634,7 +1050,9 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
return;
}
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
+ si = em_folder_tree_model_lookup_store_info (
+ EM_FOLDER_TREE_MODEL (model), store);
+ if (si == NULL) {
camel_object_unref (store);
return;
}
@@ -648,7 +1066,7 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
row = si->row;
path = gtk_tree_row_reference_get_path (row);
- gtk_tree_view_expand_to_path (priv->treeview, path);
+ gtk_tree_view_expand_to_path (tree_view, path);
u = g_hash_table_lookup(emft->priv->select_uris_table, key);
if (u)
@@ -660,15 +1078,17 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
static void
emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTreeIter *iter, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreeView *tree_view;
gboolean is_store;
CamelStore *store;
EAccount *account;
gchar *full_name;
gchar *key;
struct _selected_uri *u;
- gboolean is_expanded;
+
+ tree_view = GTK_TREE_VIEW (emft);
gtk_tree_model_get ((GtkTreeModel *) model, iter,
COL_STRING_FULL_NAME, &full_name,
@@ -676,8 +1096,8 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
COL_BOOL_IS_STORE, &is_store,
-1);
- si = g_hash_table_lookup (model->store_hash, store);
- if ((account = mail_config_get_account_by_name (si->display_name))) {
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if ((account = e_get_account_by_name (si->display_name))) {
key = g_strdup_printf ("%s/%s", account->uid, full_name ? full_name : "");
} else if (CAMEL_IS_VEE_STORE (store)) {
/* vfolder store */
@@ -687,21 +1107,14 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
key = g_strdup_printf ("local/%s", full_name ? full_name : "");
}
- is_expanded = em_folder_tree_model_get_expanded (model, key);
u = g_hash_table_lookup(priv->select_uris_table, key);
- if (is_expanded || u) {
- if (is_expanded) {
- gtk_tree_view_expand_to_path (priv->treeview, tree_path);
- gtk_tree_view_expand_row (priv->treeview, tree_path, FALSE);
- } else {
- gchar *c = strrchr (key, '/');
+ if (u) {
+ gchar *c = strrchr (key, '/');
- *c = '\0';
- emft_expand_node (model, key, emft);
- }
+ *c = '\0';
+ emft_expand_node (key, emft);
- if (u)
- emft_select_uri(emft, tree_path, u);
+ emft_select_uri(emft, tree_path, u);
}
g_free (full_name);
@@ -709,21 +1122,25 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
}
GtkWidget *
-em_folder_tree_new_with_model (EMFolderTreeModel *model)
+em_folder_tree_new (void)
{
EMFolderTree *emft;
+ GtkTreeModel *model;
AtkObject *a11y;
emft = g_object_new (EM_TYPE_FOLDER_TREE, NULL);
- em_folder_tree_construct (emft, model);
- g_object_ref (model);
+ em_folder_tree_construct (emft);
- em_folder_tree_model_expand_foreach (model, (EMFTModelExpandFunc)emft_expand_node, emft);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
- emft->priv->loading_row_id = g_signal_connect (model, "loading-row", G_CALLBACK (emft_maybe_expand_row), emft);
- emft->priv->loaded_row_id = g_signal_connect (model, "loaded-row", G_CALLBACK (emft_maybe_expand_row), emft);
+ emft->priv->loading_row_id = g_signal_connect (
+ model, "loading-row",
+ G_CALLBACK (emft_maybe_expand_row), emft);
+ emft->priv->loaded_row_id = g_signal_connect (
+ model, "loaded-row",
+ G_CALLBACK (emft_maybe_expand_row), emft);
- a11y = gtk_widget_get_accessible (GTK_WIDGET (emft->priv->treeview));
+ a11y = gtk_widget_get_accessible (GTK_WIDGET (emft));
atk_object_set_name (a11y, _("Mail Folder Tree"));
return (GtkWidget *) emft;
@@ -732,7 +1149,7 @@ em_folder_tree_new_with_model (EMFolderTreeModel *model)
static void
tree_drag_begin (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreePath *path;
@@ -752,8 +1169,9 @@ tree_drag_begin (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
static void
tree_drag_data_delete(GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gchar *full_name = NULL;
+ GtkTreeModel *model;
GtkTreePath *src_path;
gboolean is_store;
CamelStore *store;
@@ -763,13 +1181,16 @@ tree_drag_data_delete(GtkWidget *widget, GdkDragContext *context, EMFolderTree *
if (!priv->drag_row || (src_path = gtk_tree_row_reference_get_path (priv->drag_row)))
return;
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, src_path))
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
+ if (!gtk_tree_model_get_iter (model, &iter, src_path))
goto fail;
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FULL_NAME, &full_name,
- COL_BOOL_IS_STORE, &is_store, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_BOOL_IS_STORE, &is_store, -1);
if (is_store)
goto fail;
@@ -786,8 +1207,9 @@ fail:
static void
tree_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection, guint info, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gchar *full_name = NULL, *uri = NULL;
+ GtkTreeModel *model;
GtkTreePath *src_path;
CamelFolder *folder;
CamelStore *store;
@@ -797,13 +1219,16 @@ tree_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData
if (!priv->drag_row || !(src_path = gtk_tree_row_reference_get_path(priv->drag_row)))
return;
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, src_path))
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
+ if (!gtk_tree_model_get_iter (model, &iter, src_path))
goto fail;
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, -1);
/* make sure user isn't trying to drag on a placeholder row */
if (full_name == NULL)
@@ -959,61 +1384,22 @@ tree_drag_data_action(struct _DragDataReceivedAsync *m)
}
static void
-emft_drop_popup_copy(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _DragDataReceivedAsync *m = data;
-
- m->action = GDK_ACTION_COPY;
- tree_drag_data_action(m);
-}
-
-static void
-emft_drop_popup_move(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _DragDataReceivedAsync *m = data;
-
- m->action = GDK_ACTION_MOVE;
- tree_drag_data_action(m);
-}
-
-static void
-emft_drop_popup_cancel(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _DragDataReceivedAsync *m = data;
-
- m->aborted = TRUE;
- mail_msg_unref(m);
-}
-
-static EPopupItem emft_drop_popup_menu[] = {
- { E_POPUP_ITEM, (gchar *) "00.emc.00", (gchar *) N_("_Copy to Folder"), emft_drop_popup_copy, NULL, NULL, 1 },
- { E_POPUP_ITEM, (gchar *) "00.emc.01", (gchar *) N_("_Move to Folder"), emft_drop_popup_move, NULL, NULL, 1 },
- { E_POPUP_ITEM, (gchar *) "00.emc.02", (gchar *) N_("_Copy"), emft_drop_popup_copy, NULL, (gchar *) "folder-copy", 2 },
- { E_POPUP_ITEM, (gchar *) "00.emc.03", (gchar *) N_("_Move"), emft_drop_popup_move, NULL, (gchar *) "folder-move", 2 },
- { E_POPUP_BAR, (gchar *) "10.emc" },
- { E_POPUP_ITEM, (gchar *) "99.emc.00", (gchar *) N_("Cancel _Drag"), emft_drop_popup_cancel, NULL, (gchar *) "dialog-cancel", 0 },
-};
-
-static void
-emft_drop_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static void
tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection, guint info, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewDropPosition pos;
+ GtkTreeModel *model;
+ GtkTreeView *tree_view;
GtkTreePath *dest_path;
struct _DragDataReceivedAsync *m;
gboolean is_store;
CamelStore *store;
GtkTreeIter iter;
gchar *full_name;
- gint i;
- if (!gtk_tree_view_get_dest_row_at_pos (priv->treeview, x, y, &dest_path, &pos))
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &dest_path, &pos))
return;
/* this means we are receiving no data */
@@ -1022,15 +1408,16 @@ tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint
return;
}
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, dest_path)) {
+ if (!gtk_tree_model_get_iter (model, &iter, dest_path)) {
gtk_drag_finish(context, FALSE, FALSE, GDK_CURRENT_TIME);
return;
}
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_IS_STORE, &is_store,
- COL_STRING_FULL_NAME, &full_name, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_STRING_FULL_NAME, &full_name, -1);
/* make sure user isn't try to drop on a placeholder row */
if (full_name == NULL && !is_store) {
@@ -1053,30 +1440,7 @@ tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint
memcpy(m->selection->data, selection->data, selection->length);
m->selection->length = selection->length;
- if (context->action == GDK_ACTION_ASK) {
- EMPopup *emp;
- gint mask;
- GSList *menus = NULL;
- GtkMenu *menu;
-
- emp = em_popup_new("org.gnome.mail.storageset.popup.drop");
- if (info != DND_DROP_TYPE_FOLDER)
- mask = ~1;
- else
- mask = ~2;
-
- for (i=0;i<sizeof(emft_drop_popup_menu)/sizeof(emft_drop_popup_menu[0]);i++) {
- EPopupItem *item = &emft_drop_popup_menu[i];
-
- if ((item->visible & mask) == 0)
- menus = g_slist_append(menus, item);
- }
- e_popup_add_items((EPopup *)emp, menus, NULL, emft_drop_popup_free, m);
- menu = e_popup_create_menu_once((EPopup *)emp, NULL, mask);
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
- } else {
- tree_drag_data_action(m);
- }
+ tree_drag_data_action(m);
}
static gboolean
@@ -1088,27 +1452,32 @@ is_special_local_folder (const gchar *name)
static GdkAtom
emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
{
- struct _EMFolderTreePrivate *p = emft->priv;
+ EMFolderTreePrivate *p = emft->priv;
gchar *full_name = NULL, *uri = NULL, *src_uri = NULL;
CamelStore *local, *sstore, *dstore;
GdkAtom atom = GDK_NONE;
gboolean is_store;
+ GtkTreeModel *model;
GtkTreeIter iter;
GList *targets;
guint32 flags = 0;
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
/* This is a bit of a mess, but should handle all the cases properly */
- if (!gtk_tree_model_get_iter((GtkTreeModel *)p->model, &iter, path))
+ if (!gtk_tree_model_get_iter (model, &iter, path))
return GDK_NONE;
- gtk_tree_model_get((GtkTreeModel *)p->model, &iter, COL_BOOL_IS_STORE, &is_store,
- COL_STRING_FULL_NAME, &full_name,
- COL_UINT_FLAGS, &flags,
- COL_POINTER_CAMEL_STORE, &dstore,
- COL_STRING_URI, &uri, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_UINT_FLAGS, &flags,
+ COL_POINTER_CAMEL_STORE, &dstore,
+ COL_STRING_URI, &uri, -1);
- local = mail_component_peek_local_store (NULL);
+ local = e_mail_local_get_store ();
targets = context->targets;
@@ -1150,10 +1519,11 @@ emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
GtkTreePath *src_path = gtk_tree_row_reference_get_path(p->drag_row);
if (src_path) {
- if (gtk_tree_model_get_iter((GtkTreeModel *)p->model, &iter, src_path))
- gtk_tree_model_get((GtkTreeModel *)p->model, &iter,
- COL_POINTER_CAMEL_STORE, &sstore,
- COL_STRING_URI, &src_uri, -1);
+ if (gtk_tree_model_get_iter (model, &iter, src_path))
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &sstore,
+ COL_STRING_URI, &src_uri, -1);
/* can't dnd onto itself or below itself - bad things happen,
no point dragging to where we were either */
@@ -1284,12 +1654,15 @@ emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
static gboolean
tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewColumn *column;
+ GtkTreeView *tree_view;
gint cell_x, cell_y;
GtkTreePath *path;
GdkAtom target;
+ tree_view = GTK_TREE_VIEW (emft);
+
if (priv->autoscroll_id != 0) {
g_source_remove (priv->autoscroll_id);
priv->autoscroll_id = 0;
@@ -1303,7 +1676,7 @@ tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guin
priv->autoexpand_id = 0;
}
- if (!gtk_tree_view_get_path_at_pos (priv->treeview, x, y, &path, &column, &cell_x, &cell_y))
+ if (!gtk_tree_view_get_path_at_pos (tree_view, x, y, &path, &column, &cell_x, &cell_y))
return FALSE;
target = emft_drop_target(emft, context, path);
@@ -1317,7 +1690,7 @@ tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guin
static void
tree_drag_end (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
if (priv->drag_row) {
gtk_tree_row_reference_free (priv->drag_row);
@@ -1330,7 +1703,10 @@ tree_drag_end (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
static void
tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
+
+ tree_view = GTK_TREE_VIEW (emft);
if (priv->autoscroll_id != 0) {
g_source_remove (priv->autoscroll_id);
@@ -1345,7 +1721,7 @@ tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolde
priv->autoexpand_id = 0;
}
- gtk_tree_view_set_drag_dest_row(emft->priv->treeview, NULL, GTK_TREE_VIEW_DROP_BEFORE);
+ gtk_tree_view_set_drag_dest_row(tree_view, NULL, GTK_TREE_VIEW_DROP_BEFORE);
}
#define SCROLL_EDGE_SIZE 15
@@ -1353,19 +1729,20 @@ tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolde
static gboolean
tree_autoscroll (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkAdjustment *vadjustment;
+ GtkTreeView *tree_view;
GdkRectangle rect;
GdkWindow *window;
gint offset, y;
gfloat value;
/* get the y pointer position relative to the treeview */
- window = gtk_tree_view_get_bin_window (priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ window = gtk_tree_view_get_bin_window (tree_view);
gdk_window_get_pointer (window, NULL, &y, NULL);
/* rect is in coorinates relative to the scrolled window relative to the treeview */
- gtk_tree_view_get_visible_rect (priv->treeview, &rect);
+ gtk_tree_view_get_visible_rect (tree_view, &rect);
/* move y into the same coordinate system as rect */
y += rect.y;
@@ -1377,7 +1754,7 @@ tree_autoscroll (EMFolderTree *emft)
return TRUE;
}
- vadjustment = gtk_tree_view_get_vadjustment (priv->treeview);
+ vadjustment = gtk_tree_view_get_vadjustment (tree_view);
value = CLAMP (vadjustment->value + offset, 0.0, vadjustment->upper - vadjustment->page_size);
gtk_adjustment_set_value (vadjustment, value);
@@ -1388,11 +1765,13 @@ tree_autoscroll (EMFolderTree *emft)
static gboolean
tree_autoexpand (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
GtkTreePath *path;
+ tree_view = GTK_TREE_VIEW (emft);
path = gtk_tree_row_reference_get_path (priv->autoexpand_row);
- gtk_tree_view_expand_row (priv->treeview, path, FALSE);
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
gtk_tree_path_free (path);
return TRUE;
@@ -1401,16 +1780,20 @@ tree_autoexpand (EMFolderTree *emft)
static gboolean
tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeModel *model = (GtkTreeModel *) priv->model;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewDropPosition pos;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GdkDragAction action = 0;
GtkTreePath *path;
GtkTreeIter iter;
GdkAtom target;
gint i;
- if (!gtk_tree_view_get_dest_row_at_pos(priv->treeview, x, y, &path, &pos))
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (!gtk_tree_view_get_dest_row_at_pos(tree_view, x, y, &path, &pos))
return FALSE;
if (priv->autoscroll_id == 0)
@@ -1418,7 +1801,7 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
gtk_tree_model_get_iter (model, &iter, path);
- if (gtk_tree_model_iter_has_child (model, &iter) && !gtk_tree_view_row_expanded (priv->treeview, path)) {
+ if (gtk_tree_model_iter_has_child (model, &iter) && !gtk_tree_view_row_expanded (tree_view, path)) {
if (priv->autoexpand_id != 0) {
GtkTreePath *autoexpand_path;
@@ -1454,10 +1837,10 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
action = context->suggested_action;
if (action == GDK_ACTION_COPY && (context->actions & GDK_ACTION_MOVE))
action = GDK_ACTION_MOVE;
- gtk_tree_view_set_drag_dest_row(priv->treeview, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+ gtk_tree_view_set_drag_dest_row(tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
break;
default:
- gtk_tree_view_set_drag_dest_row(priv->treeview, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+ gtk_tree_view_set_drag_dest_row(tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
action = context->suggested_action;
break;
}
@@ -1476,12 +1859,15 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
void
em_folder_tree_enable_drag_and_drop (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv;
+ EMFolderTreePrivate *priv;
+ GtkTreeView *tree_view;
static gint setup = 0;
gint i;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+ tree_view = GTK_TREE_VIEW (emft);
+
priv = emft->priv;
if (!setup) {
for (i=0; i<NUM_DRAG_TYPES; i++)
@@ -1493,35 +1879,35 @@ em_folder_tree_enable_drag_and_drop (EMFolderTree *emft)
setup = 1;
}
- gtk_drag_source_set((GtkWidget *)priv->treeview, GDK_BUTTON1_MASK, drag_types, NUM_DRAG_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
- gtk_drag_dest_set((GtkWidget *)priv->treeview, GTK_DEST_DEFAULT_ALL, drop_types, NUM_DROP_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
+ gtk_drag_source_set((GtkWidget *)tree_view, GDK_BUTTON1_MASK, drag_types, NUM_DRAG_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ gtk_drag_dest_set((GtkWidget *)tree_view, GTK_DEST_DEFAULT_ALL, drop_types, NUM_DROP_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE);
- g_signal_connect (priv->treeview, "drag-begin", G_CALLBACK (tree_drag_begin), emft);
- g_signal_connect (priv->treeview, "drag-data-delete", G_CALLBACK (tree_drag_data_delete), emft);
- g_signal_connect (priv->treeview, "drag-data-get", G_CALLBACK (tree_drag_data_get), emft);
- g_signal_connect (priv->treeview, "drag-data-received", G_CALLBACK (tree_drag_data_received), emft);
- g_signal_connect (priv->treeview, "drag-drop", G_CALLBACK (tree_drag_drop), emft);
- g_signal_connect (priv->treeview, "drag-end", G_CALLBACK (tree_drag_end), emft);
- g_signal_connect (priv->treeview, "drag-leave", G_CALLBACK (tree_drag_leave), emft);
- g_signal_connect (priv->treeview, "drag-motion", G_CALLBACK (tree_drag_motion), emft);
+ g_signal_connect (tree_view, "drag-begin", G_CALLBACK (tree_drag_begin), emft);
+ g_signal_connect (tree_view, "drag-data-delete", G_CALLBACK (tree_drag_data_delete), emft);
+ g_signal_connect (tree_view, "drag-data-get", G_CALLBACK (tree_drag_data_get), emft);
+ g_signal_connect (tree_view, "drag-data-received", G_CALLBACK (tree_drag_data_received), emft);
+ g_signal_connect (tree_view, "drag-drop", G_CALLBACK (tree_drag_drop), emft);
+ g_signal_connect (tree_view, "drag-end", G_CALLBACK (tree_drag_end), emft);
+ g_signal_connect (tree_view, "drag-leave", G_CALLBACK (tree_drag_leave), emft);
+ g_signal_connect (tree_view, "drag-motion", G_CALLBACK (tree_drag_motion), emft);
}
void
-em_folder_tree_set_multiselect (EMFolderTree *tree, gboolean mode)
+em_folder_tree_set_excluded (EMFolderTree *emft, guint32 flags)
{
- GtkTreeSelection *sel = gtk_tree_view_get_selection ((GtkTreeView *) tree->priv->treeview);
-
- tree->priv->do_multiselect = mode;
- gtk_tree_selection_set_mode (sel, mode ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE);
-}
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
-void em_folder_tree_set_excluded(EMFolderTree *emft, guint32 flags)
-{
emft->priv->excluded = flags;
}
-void em_folder_tree_set_excluded_func(EMFolderTree *emft, EMFTExcludeFunc exclude, gpointer data)
+void
+em_folder_tree_set_excluded_func (EMFolderTree *emft,
+ EMFTExcludeFunc exclude,
+ gpointer data)
{
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+ g_return_if_fail (exclude != NULL);
+
emft->priv->excluded_func = exclude;
emft->priv->excluded_data = data;
}
@@ -1529,10 +1915,14 @@ void em_folder_tree_set_excluded_func(EMFolderTree *emft, EMFTExcludeFunc exclud
GList *
em_folder_tree_get_selected_uris (EMFolderTree *emft)
{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (emft->priv->treeview);
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GList *list = NULL, *rows, *l;
GSList *sl;
- GtkTreeModel *model;
+
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
/* at first, add lost uris */
for (sl = emft->priv->select_uris; sl; sl = g_slist_next(sl))
@@ -1569,31 +1959,22 @@ get_selected_uris_path_iterate (GtkTreeModel *model, GtkTreePath *treepath, GtkT
GList *
em_folder_tree_get_selected_paths (EMFolderTree *emft)
{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (emft->priv->treeview);
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
GList *list = NULL;
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
gtk_tree_selection_selected_foreach (selection, get_selected_uris_path_iterate, &list);
return list;
}
-static void
-emft_clear_selected_list(EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- g_slist_foreach(priv->select_uris, emft_free_select_uri, emft);
- g_slist_free(priv->select_uris);
- g_hash_table_destroy(priv->select_uris_table);
- priv->select_uris = NULL;
- priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
- priv->cursor_set = FALSE;
-}
-
void
em_folder_tree_set_selected_list (EMFolderTree *emft, GList *list, gboolean expand_only)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gint id = 0;
/* FIXME: need to remove any currently selected stuff? */
@@ -1646,8 +2027,7 @@ em_folder_tree_set_selected_list (EMFolderTree *emft, GList *list, gboolean expa
end = strrchr(expand_key, '/');
do {
- emft_expand_node(priv->model, expand_key, emft);
- em_folder_tree_model_set_expanded(priv->model, expand_key, TRUE);
+ emft_expand_node(expand_key, emft);
*end = 0;
end = strrchr(expand_key, '/');
} while (end);
@@ -1679,680 +2059,15 @@ dump_fi (CamelFolderInfo *fi, gint depth)
}
#endif
-struct _EMFolderTreeGetFolderInfo {
- MailMsg base;
-
- /* input data */
- GtkTreeRowReference *root;
- EMFolderTree *emft;
- CamelStore *store;
- guint32 flags;
- gchar *top;
-
- /* output data */
- CamelFolderInfo *fi;
-};
-
-static gchar *
-emft_get_folder_info__desc (struct _EMFolderTreeGetFolderInfo *m)
-{
- gchar *ret, *name;
-
- name = camel_service_get_name((CamelService *)m->store, TRUE);
- ret = g_strdup_printf(_("Scanning folders in \"%s\""), name);
- g_free(name);
- return ret;
-}
-
-static void
-emft_get_folder_info__exec (struct _EMFolderTreeGetFolderInfo *m)
-{
- guint32 flags = m->flags | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-
- m->fi = camel_store_get_folder_info (m->store, m->top, flags, &m->base.ex);
-}
-
-static void
-emft_get_folder_info__done (struct _EMFolderTreeGetFolderInfo *m)
-{
- struct _EMFolderTreePrivate *priv = m->emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeIter root, iter, titer;
- CamelFolderInfo *fi;
- GtkTreeStore *model;
- GtkTreePath *path;
- gboolean is_store;
-
- /* check that we haven't been destroyed */
- if (priv->treeview == NULL)
- return;
-
- /* check that our parent folder hasn't been deleted/unsubscribed */
- if (!gtk_tree_row_reference_valid (m->root))
- return;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, m->store))) {
- /* store has been removed in the interim - do nothing */
- return;
- }
-
- model = (GtkTreeStore *) gtk_tree_view_get_model (priv->treeview);
-
- path = gtk_tree_row_reference_get_path (m->root);
- gtk_tree_model_get_iter ((GtkTreeModel *) model, &root, path);
-
- /* if we had an error, then we need to re-set the load subdirs state and collapse the node */
- if (!m->fi && camel_exception_is_set(&m->base.ex)) {
- gtk_tree_store_set(model, &root, COL_BOOL_LOAD_SUBDIRS, TRUE, -1);
- gtk_tree_view_collapse_row (priv->treeview, path);
- gtk_tree_path_free (path);
- return;
- }
-
- gtk_tree_path_free (path);
-
- /* make sure we still need to load the tree subfolders... */
- gtk_tree_model_get ((GtkTreeModel *) model, &root,
- COL_BOOL_IS_STORE, &is_store,
- -1);
-
- /* get the first child (which will be a dummy node) */
- gtk_tree_model_iter_children ((GtkTreeModel *) model, &iter, &root);
-
- /* Traverse to the last valid iter */
- titer = iter;
- while (gtk_tree_model_iter_next((GtkTreeModel *) model, &iter))
- titer = iter; /* Preserve the last valid iter */
-
- iter = titer;
-
- /* FIXME: camel's IMAP code is totally on crack here, @top's
- * folder info should be @fi and fi->child should be what we
- * want to fill our tree with... *sigh* */
- if (m->top && m->fi && !strcmp (m->fi->full_name, m->top)) {
- if (!(fi = m->fi->child))
- fi = m->fi->next;
- } else
- fi = m->fi;
-
- if (fi == NULL) {
- /* no children afterall... remove the "Loading..." placeholder node */
- emft_update_model_expanded_state (priv, &root, FALSE);
-
- gtk_tree_store_remove (model, &iter);
-
- if (is_store) {
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, &root);
- gtk_tree_view_collapse_row (priv->treeview, path);
- emft_queue_save_state (m->emft);
- gtk_tree_path_free (path);
- return;
- }
- } else {
- gint fully_loaded = (m->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? TRUE : FALSE;
-
- do {
- gboolean known = g_hash_table_lookup (si->full_hash, fi->full_name) != NULL;
-
- if (!known)
- em_folder_tree_model_set_folder_info (priv->model, &iter, si, fi, fully_loaded);
-
- if ((fi = fi->next) != NULL && !known)
- gtk_tree_store_append (model, &iter, &root);
- } while (fi != NULL);
- }
-
- gtk_tree_store_set (model, &root, COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
- emft_queue_save_state (m->emft);
-}
-
-static void
-emft_get_folder_info__free (struct _EMFolderTreeGetFolderInfo *m)
-{
- camel_store_free_folder_info (m->store, m->fi);
-
- gtk_tree_row_reference_free (m->root);
- g_object_unref(m->emft);
- camel_object_unref (m->store);
- g_free (m->top);
-}
-
-static MailMsgInfo get_folder_info_info = {
- sizeof (struct _EMFolderTreeGetFolderInfo),
- (MailMsgDescFunc) emft_get_folder_info__desc,
- (MailMsgExecFunc) emft_get_folder_info__exec,
- (MailMsgDoneFunc) emft_get_folder_info__done,
- (MailMsgFreeFunc) emft_get_folder_info__free
-};
-
-static void
-emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter *iter, gboolean expanded)
-{
- struct _EMFolderTreeModelStoreInfo *si;
- gboolean is_store;
- CamelStore *store;
- EAccount *account;
- gchar *full_name;
- gchar *key;
-
- gtk_tree_model_get ((GtkTreeModel *) priv->model, iter,
- COL_STRING_FULL_NAME, &full_name,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_IS_STORE, &is_store,
- -1);
-
- si = g_hash_table_lookup (priv->model->store_hash, store);
- if ((account = mail_config_get_account_by_name (si->display_name))) {
- key = g_strdup_printf ("%s/%s", account->uid, full_name ? full_name : "");
- } else if (CAMEL_IS_VEE_STORE (store)) {
- /* vfolder store */
- key = g_strdup_printf ("vfolder/%s", full_name ? full_name : "");
- } else {
- /* local store */
- key = g_strdup_printf ("local/%s", full_name ? full_name : "");
- }
-
- em_folder_tree_model_set_expanded (priv->model, key, expanded);
- g_free (full_name);
- g_free (key);
-}
-
-static void
-emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeGetFolderInfo *m;
- GtkTreeModel *model;
- CamelStore *store;
- gchar *full_name;
- gboolean load;
-
- model = gtk_tree_view_get_model (treeview);
-
- gtk_tree_model_get (model, root,
- COL_STRING_FULL_NAME, &full_name,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_LOAD_SUBDIRS, &load,
- -1);
-
- emft_update_model_expanded_state (priv, root, TRUE);
-
- if (!load) {
- emft_queue_save_state (emft);
- g_free (full_name);
- return;
- }
-
- gtk_tree_store_set ((GtkTreeStore *)model, root, COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
-
- m = mail_msg_new (&get_folder_info_info);
- m->root = gtk_tree_row_reference_new (model, tree_path);
- camel_object_ref (store);
- m->store = store;
- m->emft = emft;
- g_object_ref(emft);
- m->top = full_name;
- m->flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST;
-
- mail_msg_unordered_push (m);
-}
-
-static gboolean
-emft_tree_test_collapse_row (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter cursor;
-
- selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected (selection, &model, &cursor)) {
- /* select the collapsed node IFF it is a parent of the currently selected folder */
- if (gtk_tree_store_is_ancestor ((GtkTreeStore *) model, root, &cursor))
- gtk_tree_view_set_cursor (treeview, tree_path, NULL, FALSE);
- }
-
- emft_update_model_expanded_state (emft->priv, root, FALSE);
- emft_queue_save_state (emft);
-
- return FALSE;
-}
-
-static void
-emft_tree_row_activated (GtkTreeView *treeview, GtkTreePath *tree_path, GtkTreeViewColumn *column, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeModel *model = (GtkTreeModel *) priv->model;
- gchar *full_name, *uri;
- GtkTreeIter iter;
- guint32 flags;
-
- if (!emft_select_func(NULL, model, tree_path, FALSE, emft))
- return;
-
- if (!gtk_tree_model_get_iter (model, &iter, tree_path))
- return;
-
- gtk_tree_model_get (model, &iter, COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags, -1);
-
- emft_clear_selected_list(emft);
-
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
- g_signal_emit (emft, signals[FOLDER_ACTIVATED], 0, full_name, uri);
-
- g_free(full_name);
- g_free(uri);
-}
-
-#if 0
-static void
-emft_popup_view (GtkWidget *item, EMFolderTree *emft)
-{
-
-}
-
-static void
-emft_popup_open_new (GtkWidget *item, EMFolderTree *emft)
-{
-}
-#endif
-
-static void
-emft_popup_copy(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi = NULL;
-
- /* FIXME: use async apis */
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL)
- em_folder_utils_copy_folder(fi, FALSE);
-}
-
-static void
-emft_popup_move(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi = NULL;
-
- /* FIXME: use async apis */
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL)
- em_folder_utils_copy_folder(fi, TRUE);
-}
-
-static void
-emft_popup_new_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi;
-
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL) {
- em_folder_utils_create_folder (fi, emft, NULL);
- camel_folder_info_free(fi);
- }
-}
-
-static void
-selfunc (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
- struct _emft_selection_data *dat = (struct _emft_selection_data *) data;
-
- dat->model = model;
- if (!dat->set)
- *(dat->iter) = *iter;
- dat->set = TRUE;
-}
-
-static gboolean
-emft_selection_get_selected (GtkTreeSelection *selection, GtkTreeModel **model, GtkTreeIter *iter)
-{
- struct _emft_selection_data dat = { NULL, iter, FALSE };
-
- if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_MULTIPLE) {
- gtk_tree_selection_selected_foreach (selection, selfunc, &dat);
- if (model)
- *model = dat.model;
- return dat.set;
- } else {
- return gtk_tree_selection_get_selected (selection, model, iter);
- }
-}
-
-static void
-emft_popup_delete_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- em_folder_utils_delete_folder(folder);
- }
-}
-
-static void
-emft_popup_rename_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- em_folder_utils_rename_folder(folder);
- }
-}
-
-static void
-emft_popup_refresh_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- EMEvent *e = em_event_peek();
- EMEventTargetFolder *t = em_event_target_new_folder(e, folder->full_name, 0);
- e_event_emit((EEvent *)e, "folder.refresh", (EEventTarget *)t);
- mail_refresh_folder(folder, NULL, NULL);
- }
-}
-
-static void
-emft_popup_flush_outbox (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- mail_send ();
-}
-
-static void
-emft_popup_empty_trash (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- em_utils_empty_trash (data);
-}
-
-static void
-emft_popup_properties (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *uri;
-
- selection = gtk_tree_view_get_selection (priv->treeview);
- if (!emft_selection_get_selected (selection, &model, &iter))
- return;
-
- gtk_tree_model_get (model, &iter, COL_STRING_URI, &uri, -1);
- em_folder_properties_show (NULL, NULL, uri);
- g_free (uri);
-}
-
-static void
-emft_popup_uvfolder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- gchar *meta = camel_object_meta_get(folder, "vfolder:unread");
- if (!meta || strcmp(meta, "false") == 0)
- camel_object_meta_set(folder, "vfolder:unread", "true");
- else
- camel_object_meta_set(folder, "vfolder:unread", "false");
- camel_object_state_write (folder);
- g_free (meta);
- }
-}
-
-static EPopupItem emft_popup_items[] = {
-#if 0
- { E_POPUP_ITEM, "00.emc.00", N_("_View"), emft_popup_view, NULL, NULL, EM_POPUP_FOLDER_SELECT },
- { E_POPUP_ITEM, "00.emc.01", N_("Open in _New Window"), emft_popup_open_new, NULL, NULL, EM_POPUP_FOLDER_SELECT },
-
- { E_POPUP_BAR, "10.emc" },
-#endif
- /* FIXME: need to disable for nochildren folders */
- { E_POPUP_ITEM, (gchar *) "10.emc.00", (gchar *) N_("_New Folder..."), emft_popup_new_folder, NULL, (gchar *) "folder-new", 0, EM_POPUP_FOLDER_INFERIORS },
-
- { E_POPUP_ITEM, (gchar *) "10.emc.05", (gchar *) N_("_Copy..."), emft_popup_copy, NULL, (gchar *) "folder-copy", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT },
- { E_POPUP_ITEM, (gchar *) "10.emc.06", (gchar *) N_("_Move..."), emft_popup_move, NULL, (gchar *) "folder-move", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
-
- /* FIXME: need to disable for undeletable folders */
- { E_POPUP_BAR, (gchar *) "20.emc" },
- { E_POPUP_ITEM, (gchar *) "20.emc.01", (gchar *) N_("_Delete"), emft_popup_delete_folder, NULL, (gchar *) "edit-delete", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
-
- { E_POPUP_BAR, (gchar *) "30.emc" },
- { E_POPUP_ITEM, (gchar *) "30.emc.02", (gchar *) N_("_Rename..."), emft_popup_rename_folder, NULL, NULL, 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
- { E_POPUP_ITEM, (gchar *) "30.emc.03", (gchar *) N_("Re_fresh"), emft_popup_refresh_folder, NULL, (gchar *) "view-refresh", EM_POPUP_FOLDER_NONSTATIC, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT},
- { E_POPUP_ITEM, (gchar *) "30.emc.04", (gchar *) N_("Fl_ush Outbox"), emft_popup_flush_outbox, NULL, (gchar *) "mail-send", EM_POPUP_FOLDER_OUTBOX, 0 },
-
- { E_POPUP_BAR, (gchar *) "99.emc" },
- { E_POPUP_ITEM, (gchar *) "99.emc.00", (gchar *) N_("_Properties"), emft_popup_properties, NULL, (gchar *) "document-properties", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT }
-};
-static EPopupItem trash_popup_item = {E_POPUP_ITEM, (gchar *) "30.emc.05", (gchar *) N_("_Empty Trash"), emft_popup_empty_trash,NULL,NULL, 1, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT};
-
-static void
-emft_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static gboolean
-emft_popup (EMFolderTree *emft, GdkEvent *event)
-{
- GtkTreeView *treeview;
- GtkTreeSelection *selection;
- CamelStore *local, *store;
- EMPopupTargetFolder *target;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GSList *menus = NULL;
- guint32 info_flags = 0;
- guint32 flags = 0;
- guint32 folder_type_flags = 0;
- gboolean isstore;
- gchar *uri, *full_name;
- GtkMenu *menu;
- EMPopup *emp;
- CamelFolder *selfolder = NULL;
- gint i;
-
- treeview = emft->priv->treeview;
-
- /* this centralises working out when the user's done something */
- emft_tree_user_event(treeview, (GdkEvent *)event, emft);
-
- /* FIXME: we really need the folderinfo to build a proper menu */
- selection = gtk_tree_view_get_selection (treeview);
- if (!emft_selection_get_selected (selection, &model, &iter))
- return FALSE;
-
- gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_URI, &uri, COL_STRING_FULL_NAME, &full_name,
- COL_BOOL_IS_STORE, &isstore, COL_UINT_FLAGS, &folder_type_flags, -1);
-
- /* Stores have full_name == NULL, otherwise its just a placeholder */
- /* NB: This is kind of messy */
- if (!isstore && full_name == NULL) {
- g_free (uri);
- return FALSE;
- }
-
- /* TODO: em_popup_target_folder_new? */
- if (isstore) {
- flags |= EM_POPUP_FOLDER_STORE;
- } else {
- flags |= EM_POPUP_FOLDER_FOLDER;
-
- local = mail_component_peek_local_store (NULL);
-
- /* don't allow deletion of special local folders */
- if (!(store == local && is_special_local_folder (full_name)))
- flags |= EM_POPUP_FOLDER_DELETE;
-
- /* hack for vTrash/vJunk */
- if (!strcmp (full_name, CAMEL_VTRASH_NAME) || !strcmp (full_name, CAMEL_VJUNK_NAME))
- info_flags |= CAMEL_FOLDER_VIRTUAL | CAMEL_FOLDER_NOINFERIORS;
-
- selfolder = em_folder_tree_get_selected_folder (emft);
-
- if (folder_type_flags & CAMEL_FOLDER_SYSTEM)
- flags &= ~EM_POPUP_FOLDER_DELETE;
-
- if (em_utils_folder_is_outbox (selfolder, NULL))
- info_flags |= CAMEL_FOLDER_TYPE_OUTBOX;
- }
-
- /** @HookPoint-EMPopup: Folder Tree Context Menu
- * @Id: org.gnome.evolution.mail.foldertree.popup
- * @Class: org.gnome.evolution.mail.popup:1.0
- * @Target: EMPopupTargetFolder
- *
- * This is the context menu shown on the folder tree.
- */
- emp = em_popup_new ("org.gnome.evolution.mail.foldertree.popup");
-
- /* FIXME: pass valid fi->flags here */
- target = em_popup_target_new_folder (emp, uri, info_flags, flags);
-
- for (i = 0; i < sizeof (emft_popup_items) / sizeof (emft_popup_items[0]); i++)
- menus = g_slist_prepend (menus, &emft_popup_items[i]);
-
- if ((folder_type_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH)
- menus = g_slist_prepend (menus, &trash_popup_item);
- if (!isstore && strstr(uri, "vfolder")) {
- /* This is a vfolder, so lets add hacked up menu item. */
- static EPopupItem *item = NULL;
- gchar *meta = camel_object_meta_get (selfolder, "vfolder:unread");
-
- if (!item)
- item = g_malloc0(sizeof(*item));
- if (meta && (strcmp (meta, "true") == 0))
- item->type = E_POPUP_TOGGLE | E_POPUP_ACTIVE;
- else
- item->type = E_POPUP_TOGGLE & ~E_POPUP_ACTIVE;
- item->path = (gchar *) "99.emc.99";
- item->label = _("_Unread Search Folder");
- item->activate = emft_popup_uvfolder;
- item->visible = EM_POPUP_FOLDER_SELECT;
- item->user_data = NULL;
- menus = g_slist_prepend (menus, item);
- g_free (meta);
- }
-
- e_popup_add_items ((EPopup *)emp, menus, NULL, emft_popup_free, emft);
-
- menu = e_popup_create_menu_once ((EPopup *)emp, (EPopupTarget *)target, 0);
-
- if (event == NULL || event->type == GDK_KEY_PRESS) {
- /* FIXME: menu pos function */
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
- } else {
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
- }
-
- g_free (full_name);
- g_free (uri);
-
- return TRUE;
-}
-
-static gboolean
-emft_popup_menu (GtkWidget *widget)
-{
- return emft_popup (EM_FOLDER_TREE (widget), NULL);
-}
-
-static gboolean
-emft_tree_button_press (GtkTreeView *treeview, GdkEventButton *event, EMFolderTree *emft)
-{
- GtkTreeSelection *selection;
- GtkTreePath *tree_path;
-
- /* this centralises working out when the user's done something */
- emft_tree_user_event(treeview, (GdkEvent *)event, emft);
-
- if (event->button != 3 && !(event->button == 1 && event->type == GDK_2BUTTON_PRESS))
- return FALSE;
-
- if (!gtk_tree_view_get_path_at_pos (treeview, (gint) event->x, (gint) event->y, &tree_path, NULL, NULL, NULL))
- return FALSE;
-
- /* select/focus the row that was right-clicked or double-clicked */
- selection = gtk_tree_view_get_selection (treeview);
- gtk_tree_selection_select_path(selection, tree_path);
- gtk_tree_view_set_cursor (treeview, tree_path, NULL, FALSE);
-
- if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
- if (emft->priv->skip_double_click) {
- return FALSE;
- }
- emft_tree_row_activated (treeview, tree_path, NULL, emft);
- gtk_tree_path_free (tree_path);
- return TRUE;
- }
-
- gtk_tree_path_free (tree_path);
-
- return emft_popup (emft, (GdkEvent *)event);
-}
-
-/* This is called for keyboard and mouse events, it seems the only way
- * we know the user has done something to the selection as opposed to
- * code or initialisation processes */
-static gboolean
-emft_tree_user_event (GtkTreeView *treeview, GdkEvent *e, EMFolderTree *emft)
-{
- if (e && e->type == GDK_KEY_PRESS && (e->key.keyval == GDK_space || e->key.keyval == '.' || e->key.keyval == ',' || e->key.keyval == '[' || e->key.keyval == ']')) {
- g_signal_emit (emft, signals [HIDDEN_KEY_EVENT], 0, e);
-
- return TRUE;
- }
- if (!emft->priv->do_multiselect)
- emft_clear_selected_list(emft);
-
- emft->priv->cursor_set = TRUE;
-
- return FALSE;
-}
-
-static void
-emft_tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft)
-{
- gchar *full_name, *uri;
- GtkTreeModel *model;
- GtkTreeIter iter;
- guint32 flags;
- guint unread = 0;
- guint old_unread = 0;
-
- if (!emft_selection_get_selected (selection, &model, &iter)) {
- em_folder_tree_model_set_selected (emft->priv->model, NULL);
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, NULL, NULL, 0);
- emft_queue_save_state (emft);
- return;
- }
-
- gtk_tree_model_get (
- model, &iter,
- COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags,
- COL_UINT_UNREAD, &unread, COL_UINT_UNREAD_LAST_SEL,
- &old_unread, -1);
-
- /* Sync unread counts to distinguish new incoming mail. */
- if (unread != old_unread)
- gtk_tree_store_set (
- GTK_TREE_STORE (model), &iter,
- COL_UINT_UNREAD_LAST_SEL, unread, -1);
-
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
- g_free(uri);
- g_free(full_name);
-}
-
void
-em_folder_tree_set_selected (EMFolderTree *emft, const gchar *uri, gboolean expand_only)
+em_folder_tree_set_selected (EMFolderTree *emft,
+ const gchar *uri,
+ gboolean expand_only)
{
GList *l = NULL;
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+
if (uri && uri[0])
l = g_list_append(l, (gpointer)uri);
@@ -2363,16 +2078,18 @@ em_folder_tree_set_selected (EMFolderTree *emft, const gchar *uri, gboolean expa
void
em_folder_tree_select_next_path (EMFolderTree *emft, gboolean skip_read_folders)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter, parent, child;
GtkTreePath *current_path, *path = NULL;
guint unread = 0;
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection(tree_view);
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
current_path = gtk_tree_model_get_path (model, &iter);
@@ -2407,16 +2124,16 @@ em_folder_tree_select_next_path (EMFolderTree *emft, gboolean skip_read_folders)
}
if (path) {
- if (!gtk_tree_view_row_expanded (emft->priv->treeview, path))
- gtk_tree_view_expand_to_path (emft->priv->treeview, path);
+ if (!gtk_tree_view_row_expanded (tree_view, path))
+ gtk_tree_view_expand_to_path (tree_view, path);
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.5f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
}
return;
}
@@ -2442,16 +2159,18 @@ get_last_child (GtkTreeModel *model, GtkTreeIter *iter)
void
em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter, child;
GtkTreePath *path = NULL, *current_path = NULL;
guint unread = 0;
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
@@ -2485,17 +2204,17 @@ em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
}
if (path) {
- if (!gtk_tree_view_row_expanded (priv->treeview, path)) {
- gtk_tree_view_expand_to_path (priv->treeview, path);
+ if (!gtk_tree_view_row_expanded (tree_view, path)) {
+ gtk_tree_view_expand_to_path (tree_view, path);
}
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.5f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
}
return;
}
@@ -2503,6 +2222,7 @@ em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
gchar *
em_folder_tree_get_selected_uri (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2510,9 +2230,13 @@ em_folder_tree_get_selected_uri (EMFolderTree *emft)
g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, COL_STRING_URI, &uri, -1);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_URI, &uri, -1);
return uri;
}
@@ -2520,6 +2244,7 @@ em_folder_tree_get_selected_uri (EMFolderTree *emft)
gchar *
em_folder_tree_get_selected_path (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2527,9 +2252,13 @@ em_folder_tree_get_selected_path (EMFolderTree *emft)
g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, COL_STRING_FULL_NAME, &name, -1);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_FULL_NAME, &name, -1);
return name;
}
@@ -2537,6 +2266,7 @@ em_folder_tree_get_selected_path (EMFolderTree *emft)
CamelFolder *
em_folder_tree_get_selected_folder (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2549,7 +2279,9 @@ em_folder_tree_get_selected_folder (EMFolderTree *emft)
camel_exception_init (&ex);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
if (gtk_tree_selection_get_selected(selection, &model, &iter))
gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
COL_STRING_FULL_NAME, &full_name, -1);
@@ -2565,6 +2297,7 @@ em_folder_tree_get_selected_folder (EMFolderTree *emft)
CamelFolderInfo *
em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2577,7 +2310,9 @@ em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
camel_exception_init (&ex);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
if (gtk_tree_selection_get_selected(selection, &model, &iter))
gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
COL_STRING_FULL_NAME, &full_name,
@@ -2606,54 +2341,6 @@ em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
return fi;
}
-EMFolderTreeModel *
-em_folder_tree_get_model (EMFolderTree *emft)
-{
- g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
-
- return emft->priv->model;
-}
-
-EMFolderTreeModelStoreInfo *
-em_folder_tree_get_model_storeinfo (EMFolderTree *emft, CamelStore *store)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
- g_return_val_if_reached (NULL);
- }
- return si;
-}
-
-static gboolean
-emft_save_state (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- em_folder_tree_model_save_state (priv->model);
- priv->save_state_id = 0;
-
- return FALSE;
-}
-
-static void
-emft_queue_save_state (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- if (priv->save_state_id != 0)
- return;
-
- priv->save_state_id = g_timeout_add_seconds (1, (GSourceFunc) emft_save_state, emft);
-}
-
-GtkWidget *
-em_folder_tree_get_tree_view (EMFolderTree *emft)
-{
- return (GtkWidget *)emft->priv->treeview;
-}
-
void
em_folder_tree_set_skip_double_click (EMFolderTree *emft, gboolean skip)
{