aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2013-06-16 02:25:16 +0800
committerMatthew Barnes <mbarnes@redhat.com>2013-06-16 08:10:06 +0800
commit69de51a15ab85e4dca9fed93a1e03644b0e6a840 (patch)
tree6249ab1f556b98b79a5ea6f7679e703428107dc4 /mail
parentb58e9944529a890c5b9672cf6e5eb4f930112b63 (diff)
downloadgsoc2013-evolution-69de51a15ab85e4dca9fed93a1e03644b0e6a840.tar
gsoc2013-evolution-69de51a15ab85e4dca9fed93a1e03644b0e6a840.tar.gz
gsoc2013-evolution-69de51a15ab85e4dca9fed93a1e03644b0e6a840.tar.bz2
gsoc2013-evolution-69de51a15ab85e4dca9fed93a1e03644b0e6a840.tar.lz
gsoc2013-evolution-69de51a15ab85e4dca9fed93a1e03644b0e6a840.tar.xz
gsoc2013-evolution-69de51a15ab85e4dca9fed93a1e03644b0e6a840.tar.zst
gsoc2013-evolution-69de51a15ab85e4dca9fed93a1e03644b0e6a840.zip
Convert ETreeModel to an interface.
This commit does a number of things which I could not subdivide into smaller commits. * Converts ETreeModel to an interface, implemented by MessageList. * Drops ETreeMemory and ETreeMemoryCallbacks, which were ETreeModel subclasses. Their functionality is subsumed by MessageList. * MessageList drops its public ETreeModel pointer, since MessageList now implements ETreeModel as an interface. * Adds message_list_set_expanded_default(), which takes over for e_tree_memory_set_expanded_default().
Diffstat (limited to 'mail')
-rw-r--r--mail/message-list.c1465
-rw-r--r--mail/message-list.h5
2 files changed, 816 insertions, 654 deletions
diff --git a/mail/message-list.c b/mail/message-list.c
index b0fd942679..ae7e351b91 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -102,6 +102,7 @@ struct _MessageListPrivate {
struct _MLSelection clipboard;
gboolean destroyed;
+ gboolean expanded_default;
gboolean group_by_threads;
gboolean show_deleted;
gboolean thread_latest;
@@ -111,6 +112,12 @@ struct _MessageListPrivate {
GtkTargetList *copy_target_list;
GtkTargetList *paste_target_list;
+ /* XXX Not sure if we really need a separate frozen counter
+ * for the tree model but the old ETreeMemory class had
+ * its own frozen counter so we preserve it here. */
+ GNode *tree_model_root;
+ gint tree_model_frozen;
+
/* This aids in automatic message selection. */
time_t newest_read_date;
const gchar *newest_read_uid;
@@ -165,6 +172,8 @@ enum {
/* Forward Declarations */
static void message_list_selectable_init
(ESelectableInterface *interface);
+static void message_list_tree_model_init
+ (ETreeModelInterface *interface);
G_DEFINE_TYPE_WITH_CODE (
MessageList,
@@ -174,7 +183,10 @@ G_DEFINE_TYPE_WITH_CODE (
E_TYPE_EXTENSIBLE, NULL)
G_IMPLEMENT_INTERFACE (
E_TYPE_SELECTABLE,
- message_list_selectable_init))
+ message_list_selectable_init)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_TREE_MODEL,
+ message_list_tree_model_init))
static struct {
const gchar *target;
@@ -238,18 +250,16 @@ enum {
static void on_cursor_activated_cmd (ETree *tree,
gint row,
- ETreePath path,
+ GNode *node,
gpointer user_data);
static void on_selection_changed_cmd (ETree *tree,
MessageList *message_list);
static gint on_click (ETree *tree,
gint row,
- ETreePath path,
+ GNode *node,
gint col,
GdkEvent *event,
MessageList *message_list);
-static gchar * filter_date (time_t date);
-static gchar * filter_size (gint size);
static void mail_regen_list (MessageList *message_list,
const gchar *search,
@@ -257,7 +267,7 @@ static void mail_regen_list (MessageList *message_list,
static void mail_regen_cancel (MessageList *message_list);
static void clear_info (gchar *key,
- ETreePath *node,
+ GNode *node,
MessageList *message_list);
enum {
@@ -268,6 +278,15 @@ enum {
static guint signals[LAST_SIGNAL] = {0, };
+static const gchar *status_map[] = {
+ N_("Unseen"),
+ N_("Seen"),
+ N_("Answered"),
+ N_("Forwarded"),
+ N_("Multiple Unseen Messages"),
+ N_("Multiple Messages"),
+};
+
static const gchar *status_icons[] = {
"mail-unread",
"mail-read",
@@ -277,6 +296,16 @@ static const gchar *status_icons[] = {
"stock_mail-open-multiple"
};
+static const gchar *score_map[] = {
+ N_("Lowest"),
+ N_("Lower"),
+ N_("Low"),
+ N_("Normal"),
+ N_("High"),
+ N_("Higher"),
+ N_("Highest"),
+};
+
static const gchar *score_icons[] = {
"stock_score-lowest",
"stock_score-lower",
@@ -406,6 +435,96 @@ message_list_ref_regen_data (MessageList *message_list)
return regen_data;
}
+static void
+message_list_tree_model_freeze (MessageList *message_list)
+{
+ if (message_list->priv->tree_model_frozen == 0)
+ e_tree_model_pre_change (E_TREE_MODEL (message_list));
+
+ message_list->priv->tree_model_frozen++;
+}
+
+static void
+message_list_tree_model_thaw (MessageList *message_list)
+{
+ if (message_list->priv->tree_model_frozen > 0)
+ message_list->priv->tree_model_frozen--;
+
+ if (message_list->priv->tree_model_frozen == 0)
+ e_tree_model_node_changed (
+ E_TREE_MODEL (message_list),
+ message_list->priv->tree_model_root);
+}
+
+static GNode *
+message_list_tree_model_insert (MessageList *message_list,
+ GNode *parent,
+ gint position,
+ gpointer data)
+{
+ ETreeModel *tree_model;
+ GNode *node;
+ gboolean tree_model_frozen;
+
+ if (parent == NULL)
+ g_return_val_if_fail (
+ message_list->priv->tree_model_root == NULL, NULL);
+
+ tree_model = E_TREE_MODEL (message_list);
+ tree_model_frozen = (message_list->priv->tree_model_frozen > 0);
+
+ if (!tree_model_frozen)
+ e_tree_model_pre_change (tree_model);
+
+ node = g_node_new (data);
+
+ if (parent != NULL) {
+ g_node_insert (parent, position, node);
+ if (!tree_model_frozen)
+ e_tree_model_node_inserted (tree_model, parent, node);
+ } else {
+ message_list->priv->tree_model_root = node;
+ if (!tree_model_frozen)
+ e_tree_model_node_changed (tree_model, node);
+ }
+
+ return node;
+}
+
+static void
+message_list_tree_model_remove (MessageList *message_list,
+ GNode *node)
+{
+ ETreeModel *tree_model;
+ GNode *parent = node->parent;
+ gboolean tree_model_frozen;
+ gint old_position = 0;
+
+ g_return_if_fail (node != NULL);
+
+ tree_model = E_TREE_MODEL (message_list);
+ tree_model_frozen = (message_list->priv->tree_model_frozen > 0);
+
+ if (!tree_model_frozen) {
+ e_tree_model_pre_change (tree_model);
+ old_position = g_node_child_position (parent, node);
+ }
+
+ g_node_unlink (node);
+
+ if (!tree_model_frozen)
+ e_tree_model_node_removed (
+ tree_model, parent, node, old_position);
+
+ g_node_destroy (node);
+
+ if (node == message_list->priv->tree_model_root)
+ message_list->priv->tree_model_root = NULL;
+
+ if (!tree_model_frozen)
+ e_tree_model_node_deleted (tree_model, node);
+}
+
static gint
address_compare (gconstpointer address1,
gconstpointer address2,
@@ -442,16 +561,12 @@ filter_size (gint size)
/* Gets the uid of the message displayed at a given view row */
static const gchar *
get_message_uid (MessageList *message_list,
- ETreePath node)
+ GNode *node)
{
- CamelMessageInfo *info;
-
g_return_val_if_fail (node != NULL, NULL);
- info = e_tree_memory_node_get_data (E_TREE_MEMORY (message_list->model), node);
- /* correct me if I'm wrong, but this should never be NULL, should it? */
- g_return_val_if_fail (info != NULL, NULL);
+ g_return_val_if_fail (node->data != NULL, NULL);
- return camel_message_info_uid (info);
+ return camel_message_info_uid (node->data);
}
/* Gets the CamelMessageInfo for the message displayed at the given
@@ -459,15 +574,12 @@ get_message_uid (MessageList *message_list,
*/
static CamelMessageInfo *
get_message_info (MessageList *message_list,
- ETreePath node)
+ GNode *node)
{
- CamelMessageInfo *info;
-
g_return_val_if_fail (node != NULL, NULL);
- info = e_tree_memory_node_get_data (E_TREE_MEMORY (message_list->model), node);
- g_return_val_if_fail (info != NULL, NULL);
+ g_return_val_if_fail (node->data != NULL, NULL);
- return info;
+ return node->data;
}
static const gchar *
@@ -558,14 +670,14 @@ clear_selection (MessageList *message_list,
g_clear_object (&selection->folder);
}
-static ETreePath
+static GNode *
ml_search_forward (MessageList *message_list,
gint start,
gint end,
guint32 flags,
guint32 mask)
{
- ETreePath path;
+ GNode *node;
gint row;
CamelMessageInfo *info;
ETreeTableAdapter *etta;
@@ -573,24 +685,24 @@ ml_search_forward (MessageList *message_list,
etta = e_tree_get_table_adapter (E_TREE (message_list));
for (row = start; row <= end; row++) {
- path = e_tree_table_adapter_node_at_row (etta, row);
- if (path
- && (info = get_message_info (message_list, path))
+ node = e_tree_table_adapter_node_at_row (etta, row);
+ if (node != NULL
+ && (info = get_message_info (message_list, node))
&& (camel_message_info_flags (info) & mask) == flags)
- return path;
+ return node;
}
return NULL;
}
-static ETreePath
+static GNode *
ml_search_backward (MessageList *message_list,
gint start,
gint end,
guint32 flags,
guint32 mask)
{
- ETreePath path;
+ GNode *node;
gint row;
CamelMessageInfo *info;
ETreeTableAdapter *etta;
@@ -598,23 +710,23 @@ ml_search_backward (MessageList *message_list,
etta = e_tree_get_table_adapter (E_TREE (message_list));
for (row = start; row >= end; row--) {
- path = e_tree_table_adapter_node_at_row (etta, row);
- if (path
- && (info = get_message_info (message_list, path))
+ node = e_tree_table_adapter_node_at_row (etta, row);
+ if (node != NULL
+ && (info = get_message_info (message_list, node))
&& (camel_message_info_flags (info) & mask) == flags)
- return path;
+ return node;
}
return NULL;
}
-static ETreePath
+static GNode *
ml_search_path (MessageList *message_list,
MessageListSelectDirection direction,
guint32 flags,
guint32 mask)
{
- ETreePath node;
+ GNode *node;
gint row, count;
ETreeTableAdapter *etta;
@@ -649,8 +761,8 @@ ml_search_path (MessageList *message_list,
}
static void
-select_path (MessageList *message_list,
- ETreePath path)
+select_node (MessageList *message_list,
+ GNode *node)
{
ETree *tree;
ETreeTableAdapter *etta;
@@ -663,9 +775,9 @@ select_path (MessageList *message_list,
g_free (message_list->cursor_uid);
message_list->cursor_uid = NULL;
- e_tree_table_adapter_show_node (etta, path);
- e_tree_set_cursor (tree, path);
- e_tree_selection_model_select_single_path (etsm, path);
+ e_tree_table_adapter_show_node (etta, node);
+ e_tree_set_cursor (tree, node);
+ e_tree_selection_model_select_single_path (etsm, node);
}
/**
@@ -693,11 +805,11 @@ message_list_select (MessageList *message_list,
guint32 flags,
guint32 mask)
{
- ETreePath path;
+ GNode *node;
- path = ml_search_path (message_list, direction, flags, mask);
- if (path) {
- select_path (message_list, path);
+ node = ml_search_path (message_list, direction, flags, mask);
+ if (node != NULL) {
+ select_node (message_list, node);
/* This function is usually called in response to a key
* press, so grab focus if the message list is visible. */
@@ -743,7 +855,7 @@ message_list_select_uid (MessageList *message_list,
{
MessageListPrivate *priv;
GHashTable *uid_nodemap;
- ETreePath node = NULL;
+ GNode *node = NULL;
RegenData *regen_data = NULL;
g_return_if_fail (IS_MESSAGE_LIST (message_list));
@@ -788,7 +900,7 @@ message_list_select_uid (MessageList *message_list,
if (node) {
ETree *tree;
- ETreePath old_cur;
+ GNode *old_cur;
tree = E_TREE (message_list);
old_cur = e_tree_get_cursor (tree);
@@ -814,10 +926,12 @@ message_list_select_uid (MessageList *message_list,
void
message_list_select_next_thread (MessageList *message_list)
{
- ETreePath node;
+ GNode *node;
ETreeTableAdapter *etta;
gint i, count, row;
+ g_return_if_fail (IS_MESSAGE_LIST (message_list));
+
etta = e_tree_get_table_adapter (E_TREE (message_list));
if (!message_list->cursor_uid
@@ -832,9 +946,8 @@ message_list_select_next_thread (MessageList *message_list)
/* find the next node which has a root parent (i.e. toplevel node) */
for (i = row + 1; i < count - 1; i++) {
node = e_tree_table_adapter_node_at_row (etta, i);
- if (node
- && e_tree_model_node_is_root (message_list->model, e_tree_model_node_get_parent (message_list->model, node))) {
- select_path (message_list, node);
+ if (node != NULL && G_NODE_IS_ROOT (node->parent)) {
+ select_node (message_list, node);
return;
}
}
@@ -843,11 +956,13 @@ message_list_select_next_thread (MessageList *message_list)
void
message_list_select_prev_thread (MessageList *message_list)
{
- ETreePath node;
+ GNode *node;
ETreeTableAdapter *etta;
gint i, row;
gboolean skip_first;
+ g_return_if_fail (IS_MESSAGE_LIST (message_list));
+
etta = e_tree_get_table_adapter (E_TREE (message_list));
if (!message_list->cursor_uid
@@ -859,21 +974,18 @@ message_list_select_prev_thread (MessageList *message_list)
return;
/* skip first found if in the middle of the thread */
- skip_first = !e_tree_model_node_is_root (
- message_list->model,
- e_tree_model_node_get_parent (message_list->model, node));
+ skip_first = !G_NODE_IS_ROOT (node->parent);
/* find the previous node which has a root parent (i.e. toplevel node) */
for (i = row - 1; i >= 0; i--) {
node = e_tree_table_adapter_node_at_row (etta, i);
- if (node
- && e_tree_model_node_is_root (message_list->model, e_tree_model_node_get_parent (message_list->model, node))) {
+ if (node != NULL && G_NODE_IS_ROOT (node->parent)) {
if (skip_first) {
skip_first = FALSE;
continue;
}
- select_path (message_list, node);
+ select_node (message_list, node);
return;
}
}
@@ -915,20 +1027,20 @@ typedef struct thread_select_info {
} thread_select_info_t;
static gboolean
-select_node (ETreeModel *model,
- ETreePath path,
- gpointer user_data)
+select_thread_node (ETreeModel *model,
+ GNode *node,
+ gpointer user_data)
{
thread_select_info_t *tsi = (thread_select_info_t *) user_data;
- g_ptr_array_add (tsi->paths, path);
+ g_ptr_array_add (tsi->paths, node);
+
return FALSE; /*not done yet */
}
static void
select_thread (MessageList *message_list,
- void (*selector) (ETreePath,
- gpointer))
+ ETreeForeachFunc selector)
{
ETree *tree;
ETreeSelectionModel *etsm;
@@ -952,19 +1064,21 @@ thread_select_foreach (ETreePath path,
gpointer user_data)
{
thread_select_info_t *tsi = (thread_select_info_t *) user_data;
- ETreeModel *model = tsi->message_list->model;
- ETreePath node, last;
+ ETreeModel *tree_model;
+ GNode *last, *node = path;
- node = path;
+ tree_model = E_TREE_MODEL (tsi->message_list);
do {
last = node;
- node = e_tree_model_node_get_parent (model, node);
- } while (!e_tree_model_node_is_root (model, node));
+ node = node->parent;
+ } while (!G_NODE_IS_ROOT (node));
g_ptr_array_add (tsi->paths, last);
- e_tree_model_node_traverse (model, last, select_node, tsi);
+ e_tree_model_node_traverse (
+ tree_model, last,
+ (ETreePathFunc) select_thread_node, tsi);
}
/**
@@ -984,9 +1098,13 @@ subthread_select_foreach (ETreePath path,
gpointer user_data)
{
thread_select_info_t *tsi = (thread_select_info_t *) user_data;
- ETreeModel *model = tsi->message_list->model;
+ ETreeModel *tree_model;
+
+ tree_model = E_TREE_MODEL (tsi->message_list);
- e_tree_model_node_traverse (model, path, select_node, tsi);
+ e_tree_model_node_traverse (
+ tree_model, path,
+ (ETreePathFunc) select_thread_node, tsi);
}
/**
@@ -1076,342 +1194,40 @@ message_list_paste (MessageList *message_list)
GDK_CURRENT_TIME);
}
-/*
- * SimpleTableModel::col_count
- */
-static gint
-ml_column_count (ETreeModel *etm,
- gpointer data)
-{
- return COL_LAST;
-}
-
-/*
- * SimpleTableModel::has_save_id
- */
-static gboolean
-ml_has_save_id (ETreeModel *etm,
- gpointer data)
-{
- return TRUE;
-}
-
-/*
- * SimpleTableModel::get_save_id
- */
-static gchar *
-ml_get_save_id (ETreeModel *etm,
- ETreePath path,
- gpointer data)
-{
- CamelMessageInfo *info;
-
- if (e_tree_model_node_is_root (etm, path))
- return g_strdup ("root");
-
- /* Note: etable can ask for the save_id while we're clearing it,
- * which is the only time data should be null */
- info = e_tree_memory_node_get_data (E_TREE_MEMORY (etm), path);
- if (info == NULL)
- return NULL;
-
- return g_strdup (camel_message_info_uid (info));
-}
-
-/*
- * SimpleTableModel::has_save_id
- */
-static gboolean
-ml_has_get_node_by_id (ETreeModel *etm,
- gpointer data)
-{
- return TRUE;
-}
-
-/*
- * SimpleTableModel::get_save_id
- */
-static ETreePath
-ml_get_node_by_id (ETreeModel *etm,
- const gchar *save_id,
- gpointer data)
-{
- MessageList *message_list;
-
- message_list = data;
-
- if (!strcmp (save_id, "root"))
- return e_tree_model_get_root (etm);
-
- return g_hash_table_lookup (message_list->uid_nodemap, save_id);
-}
-
-static gpointer
-ml_duplicate_value (ETreeModel *etm,
- gint col,
- gconstpointer value,
- gpointer data)
-{
- switch (col) {
- case COL_MESSAGE_STATUS:
- case COL_FLAGGED:
- case COL_SCORE:
- case COL_ATTACHMENT:
- case COL_DELETED:
- case COL_UNREAD:
- case COL_SENT:
- case COL_RECEIVED:
- case COL_SIZE:
- case COL_FOLLOWUP_FLAG_STATUS:
- case COL_FOLLOWUP_DUE_BY:
- return (gpointer) value;
-
- case COL_FROM:
- case COL_SUBJECT:
- case COL_TO:
- case COL_SENDER:
- case COL_RECIPIENTS:
- case COL_MIXED_SENDER:
- case COL_MIXED_RECIPIENTS:
- case COL_FOLLOWUP_FLAG:
- case COL_LOCATION:
- case COL_LABELS:
- return g_strdup (value);
- default:
- g_warning ("This shouldn't be reached\n");
- }
- return NULL;
-}
-
-static void
-ml_free_value (ETreeModel *etm,
- gint col,
- gpointer value,
- gpointer data)
-{
- switch (col) {
- case COL_MESSAGE_STATUS:
- case COL_FLAGGED:
- case COL_SCORE:
- case COL_ATTACHMENT:
- case COL_DELETED:
- case COL_UNREAD:
- case COL_SENT:
- case COL_RECEIVED:
- case COL_SIZE:
- case COL_FOLLOWUP_FLAG_STATUS:
- case COL_FOLLOWUP_DUE_BY:
- case COL_FROM_NORM:
- case COL_SUBJECT_NORM:
- case COL_TO_NORM:
- case COL_SUBJECT_TRIMMED:
- case COL_COLOUR:
- break;
-
- case COL_FROM:
- case COL_SUBJECT:
- case COL_TO:
- case COL_FOLLOWUP_FLAG:
- case COL_LOCATION:
- case COL_SENDER:
- case COL_RECIPIENTS:
- case COL_MIXED_SENDER:
- case COL_MIXED_RECIPIENTS:
- case COL_LABELS:
- g_free (value);
- break;
- default:
- g_warning ("%s: This shouldn't be reached (col:%d)", G_STRFUNC, col);
- }
-}
-
-static gpointer
-ml_initialize_value (ETreeModel *etm,
- gint col,
- gpointer data)
-{
- switch (col) {
- case COL_MESSAGE_STATUS:
- case COL_FLAGGED:
- case COL_SCORE:
- case COL_ATTACHMENT:
- case COL_DELETED:
- case COL_UNREAD:
- case COL_SENT:
- case COL_RECEIVED:
- case COL_SIZE:
- case COL_FOLLOWUP_FLAG_STATUS:
- case COL_FOLLOWUP_DUE_BY:
- return NULL;
-
- case COL_FROM:
- case COL_SUBJECT:
- case COL_TO:
- case COL_FOLLOWUP_FLAG:
- case COL_LOCATION:
- case COL_SENDER:
- case COL_RECIPIENTS:
- case COL_MIXED_SENDER:
- case COL_MIXED_RECIPIENTS:
- case COL_LABELS:
- return g_strdup ("");
- default:
- g_warning ("This shouldn't be reached\n");
- }
-
- return NULL;
-}
-
-static gboolean
-ml_value_is_empty (ETreeModel *etm,
- gint col,
- gconstpointer value,
- gpointer data)
-{
- switch (col) {
- case COL_MESSAGE_STATUS:
- case COL_FLAGGED:
- case COL_SCORE:
- case COL_ATTACHMENT:
- case COL_DELETED:
- case COL_UNREAD:
- case COL_SENT:
- case COL_RECEIVED:
- case COL_SIZE:
- case COL_FOLLOWUP_FLAG_STATUS:
- case COL_FOLLOWUP_DUE_BY:
- return value == NULL;
-
- case COL_FROM:
- case COL_SUBJECT:
- case COL_TO:
- case COL_FOLLOWUP_FLAG:
- case COL_LOCATION:
- case COL_SENDER:
- case COL_RECIPIENTS:
- case COL_MIXED_SENDER:
- case COL_MIXED_RECIPIENTS:
- case COL_LABELS:
- return !(value && *(gchar *) value);
- default:
- g_warning ("This shouldn't be reached\n");
- return FALSE;
- }
-}
-
-static const gchar *status_map[] = {
- N_("Unseen"),
- N_("Seen"),
- N_("Answered"),
- N_("Forwarded"),
- N_("Multiple Unseen Messages"),
- N_("Multiple Messages"),
-};
-
-static const gchar *score_map[] = {
- N_("Lowest"),
- N_("Lower"),
- N_("Low"),
- N_("Normal"),
- N_("High"),
- N_("Higher"),
- N_("Highest"),
-};
-
-static gchar *
-ml_value_to_string (ETreeModel *etm,
- gint col,
- gconstpointer value,
- gpointer data)
-{
- guint i;
-
- switch (col) {
- case COL_MESSAGE_STATUS:
- i = GPOINTER_TO_UINT (value);
- if (i > 5)
- return g_strdup ("");
- return g_strdup (_(status_map[i]));
-
- case COL_SCORE:
- i = GPOINTER_TO_UINT (value) + 3;
- if (i > 6)
- i = 3;
- return g_strdup (_(score_map[i]));
-
- case COL_ATTACHMENT:
- case COL_FLAGGED:
- case COL_DELETED:
- case COL_UNREAD:
- case COL_FOLLOWUP_FLAG_STATUS:
- return g_strdup_printf ("%u", GPOINTER_TO_UINT (value));
-
- case COL_SENT:
- case COL_RECEIVED:
- case COL_FOLLOWUP_DUE_BY:
- return filter_date (GPOINTER_TO_INT (value));
-
- case COL_SIZE:
- return filter_size (GPOINTER_TO_INT (value));
-
- case COL_FROM:
- case COL_SUBJECT:
- case COL_TO:
- case COL_FOLLOWUP_FLAG:
- case COL_LOCATION:
- case COL_SENDER:
- case COL_RECIPIENTS:
- case COL_MIXED_SENDER:
- case COL_MIXED_RECIPIENTS:
- case COL_LABELS:
- return g_strdup (value);
- default:
- g_warning ("This shouldn't be reached\n");
- return NULL;
- }
-}
-
-static GdkPixbuf *
-ml_tree_icon_at (ETreeModel *etm,
- ETreePath path,
- gpointer model_data)
-{
- /* we dont really need an icon ... */
- return NULL;
-}
-
static void
for_node_and_subtree_if_collapsed (MessageList *message_list,
- ETreePath node,
+ GNode *node,
CamelMessageInfo *mi,
ETreePathFunc func,
gpointer data)
{
- ETreeModel *etm = message_list->model;
- ETreePath child;
+ ETreeModel *tree_model;
+ GNode *child;
+
+ tree_model = E_TREE_MODEL (message_list);
func (NULL, (ETreePath) mi, data);
if (!node)
return;
- child = e_tree_model_node_get_first_child (etm, node);
+ child = g_node_first_child (node);
if (child && !e_tree_node_is_expanded (E_TREE (message_list), node))
- e_tree_model_node_traverse (etm, node, func, data);
+ e_tree_model_node_traverse (tree_model, node, func, data);
}
static gboolean
unread_foreach (ETreeModel *etm,
- ETreePath node,
+ ETreePath path,
gpointer data)
{
gboolean *saw_unread = data;
CamelMessageInfo *info;
if (!etm)
- info = (CamelMessageInfo *) node;
+ info = (CamelMessageInfo *) path;
else
- info = e_tree_memory_node_get_data ((ETreeMemory *) etm, node);
+ info = ((GNode *) path)->data;
g_return_val_if_fail (info != NULL, FALSE);
if (!(camel_message_info_flags (info) & CAMEL_MESSAGE_SEEN))
@@ -1427,7 +1243,7 @@ struct LatestData {
static gboolean
latest_foreach (ETreeModel *etm,
- ETreePath node,
+ ETreePath path,
gpointer data)
{
struct LatestData *ld = data;
@@ -1435,9 +1251,9 @@ latest_foreach (ETreeModel *etm,
time_t date;
if (!etm)
- info = (CamelMessageInfo *) node;
+ info = (CamelMessageInfo *) path;
else
- info = e_tree_memory_node_get_data ((ETreeMemory *) etm, node);
+ info = ((GNode *) path)->data;
g_return_val_if_fail (info != NULL, FALSE);
date = ld->sent ? camel_message_info_date_sent (info)
@@ -1514,7 +1330,7 @@ add_label_if_known (struct LabelsData *ld,
static gboolean
add_all_labels_foreach (ETreeModel *etm,
- ETreePath node,
+ ETreePath path,
gpointer data)
{
struct LabelsData *ld = data;
@@ -1524,9 +1340,9 @@ add_all_labels_foreach (ETreeModel *etm,
const CamelFlag *flag;
if (!etm)
- msg_info = (CamelMessageInfo *) node;
+ msg_info = (CamelMessageInfo *) path;
else
- msg_info = e_tree_memory_node_get_data ((ETreeMemory *) etm, node);
+ msg_info = ((GNode *) path)->data;
g_return_val_if_fail (msg_info != NULL, FALSE);
for (flag = camel_message_info_user_flags (msg_info); flag; flag = flag->next)
@@ -1609,7 +1425,7 @@ get_trimmed_subject (CamelMessageInfo *info)
static gpointer
ml_tree_value_at_ex (ETreeModel *etm,
- ETreePath path,
+ GNode *node,
gint col,
CamelMessageInfo *msg_info,
MessageList *message_list)
@@ -1697,7 +1513,7 @@ ml_tree_value_at_ex (ETreeModel *etm,
ld.sent = TRUE;
ld.latest = 0;
- for_node_and_subtree_if_collapsed (message_list, path, msg_info, latest_foreach, &ld);
+ for_node_and_subtree_if_collapsed (message_list, node, msg_info, latest_foreach, &ld);
return GINT_TO_POINTER (ld.latest);
}
@@ -1706,7 +1522,7 @@ ml_tree_value_at_ex (ETreeModel *etm,
ld.sent = FALSE;
ld.latest = 0;
- for_node_and_subtree_if_collapsed (message_list, path, msg_info, latest_foreach, &ld);
+ for_node_and_subtree_if_collapsed (message_list, node, msg_info, latest_foreach, &ld);
return GINT_TO_POINTER (ld.latest);
}
@@ -1722,7 +1538,7 @@ ml_tree_value_at_ex (ETreeModel *etm,
case COL_UNREAD: {
gboolean saw_unread = FALSE;
- for_node_and_subtree_if_collapsed (message_list, path, msg_info, unread_foreach, &saw_unread);
+ for_node_and_subtree_if_collapsed (message_list, node, msg_info, unread_foreach, &saw_unread);
return GINT_TO_POINTER (saw_unread);
}
@@ -1747,7 +1563,7 @@ ml_tree_value_at_ex (ETreeModel *etm,
ld.store = e_mail_ui_session_get_label_store (
E_MAIL_UI_SESSION (session));
ld.labels_tag2iter = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gtk_tree_iter_free);
- for_node_and_subtree_if_collapsed (message_list, path, msg_info, add_all_labels_foreach, &ld);
+ for_node_and_subtree_if_collapsed (message_list, node, msg_info, add_all_labels_foreach, &ld);
if (g_hash_table_size (ld.labels_tag2iter) == 1) {
GHashTableIter iter;
@@ -1833,7 +1649,7 @@ ml_tree_value_at_ex (ETreeModel *etm,
ld.store = e_mail_ui_session_get_label_store (
E_MAIL_UI_SESSION (session));
ld.labels_tag2iter = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gtk_tree_iter_free);
- for_node_and_subtree_if_collapsed (message_list, path, msg_info, add_all_labels_foreach, &ld);
+ for_node_and_subtree_if_collapsed (message_list, node, msg_info, add_all_labels_foreach, &ld);
if (g_hash_table_size (ld.labels_tag2iter) > 0) {
GHashTableIter iter;
@@ -1865,69 +1681,6 @@ ml_tree_value_at_ex (ETreeModel *etm,
}
}
-static gpointer
-ml_tree_value_at (ETreeModel *etm,
- ETreePath path,
- gint col,
- gpointer model_data)
-{
- MessageList *message_list = model_data;
- CamelMessageInfo *msg_info;
-
- if (e_tree_model_node_is_root (etm, path))
- return NULL;
-
- /* retrieve the message information array */
- msg_info = e_tree_memory_node_get_data (E_TREE_MEMORY (etm), path);
- g_return_val_if_fail (msg_info != NULL, NULL);
-
- return ml_tree_value_at_ex (etm, path, col, msg_info, message_list);
-}
-
-static gpointer
-ml_tree_sort_value_at (ETreeModel *etm,
- ETreePath path,
- gint col,
- gpointer model_data)
-{
- MessageList *message_list = model_data;
- struct LatestData ld;
-
- if (!(col == COL_SENT || col == COL_RECEIVED))
- return ml_tree_value_at (etm, path, col, model_data);
-
- if (e_tree_model_node_is_root (etm, path))
- return NULL;
-
- ld.sent = (col == COL_SENT);
- ld.latest = 0;
-
- latest_foreach (etm, path, &ld);
- if (message_list->priv->thread_latest)
- e_tree_model_node_traverse (etm, path, latest_foreach, &ld);
-
- return GINT_TO_POINTER (ld.latest);
-}
-
-static void
-ml_tree_set_value_at (ETreeModel *etm,
- ETreePath path,
- gint col,
- gconstpointer val,
- gpointer model_data)
-{
- g_warning ("This shouldn't be reached\n");
-}
-
-static gboolean
-ml_tree_is_cell_editable (ETreeModel *etm,
- ETreePath path,
- gint col,
- gpointer model_data)
-{
- return FALSE;
-}
-
static gchar *
filter_date (time_t date)
{
@@ -2302,7 +2055,7 @@ ml_selection_received (GtkWidget *widget,
static void
ml_tree_drag_data_get (ETree *tree,
gint row,
- ETreePath path,
+ GNode *node,
gint col,
GdkDragContext *context,
GtkSelectionData *data,
@@ -2434,7 +2187,7 @@ ml_drop_action (struct _drop_msg *m)
static void
ml_tree_drag_data_received (ETree *tree,
gint row,
- ETreePath path,
+ GNode *node,
gint col,
GdkDragContext *context,
gint x,
@@ -2629,82 +2382,6 @@ message_list_set_session (MessageList *message_list,
}
static void
-message_list_init (MessageList *message_list)
-{
- MessageListPrivate *p;
- GtkTargetList *target_list;
- GdkAtom matom;
-
- message_list->priv = MESSAGE_LIST_GET_PRIVATE (message_list);
-
- /* FIXME This should be a GTypeInterface. */
- message_list->model = e_tree_memory_callbacks_new (
- ml_tree_icon_at,
-
- ml_column_count,
-
- ml_has_save_id,
- ml_get_save_id,
-
- ml_has_get_node_by_id,
- ml_get_node_by_id,
-
- ml_tree_sort_value_at,
- ml_tree_value_at,
- ml_tree_set_value_at,
- ml_tree_is_cell_editable,
-
- ml_duplicate_value,
- ml_free_value,
- ml_initialize_value,
- ml_value_is_empty,
- ml_value_to_string,
-
- message_list);
-
- message_list->normalised_hash = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) e_poolv_destroy);
-
- message_list->uid_nodemap = g_hash_table_new (g_str_hash, g_str_equal);
-
- message_list->cursor_uid = NULL;
- message_list->last_sel_single = FALSE;
-
- g_mutex_init (&message_list->priv->regen_lock);
-
- /* TODO: Should this only get the selection if we're realised? */
- p = message_list->priv;
- p->invisible = gtk_invisible_new ();
- p->destroyed = FALSE;
- g_object_ref_sink (p->invisible);
- p->any_row_changed = FALSE;
-
- matom = gdk_atom_intern ("x-uid-list", FALSE);
- gtk_selection_add_target (p->invisible, GDK_SELECTION_CLIPBOARD, matom, 0);
- gtk_selection_add_target (p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 2);
-
- g_signal_connect (
- p->invisible, "selection_get",
- G_CALLBACK (ml_selection_get), message_list);
- g_signal_connect (
- p->invisible, "selection_clear_event",
- G_CALLBACK (ml_selection_clear_event), message_list);
- g_signal_connect (
- p->invisible, "selection_received",
- G_CALLBACK (ml_selection_received), message_list);
-
- /* FIXME This is currently unused. */
- target_list = gtk_target_list_new (NULL, 0);
- message_list->priv->copy_target_list = target_list;
-
- /* FIXME This is currently unused. */
- target_list = gtk_target_list_new (NULL, 0);
- message_list->priv->paste_target_list = target_list;
-}
-
-static void
message_list_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -2861,7 +2538,6 @@ message_list_dispose (GObject *object)
g_clear_object (&priv->invisible);
g_clear_object (&message_list->extras);
- g_clear_object (&message_list->model);
if (message_list->idle_id > 0) {
g_source_remove (message_list->idle_id);
@@ -2895,6 +2571,9 @@ message_list_finalize (GObject *object)
clear_selection (message_list, &message_list->priv->clipboard);
+ if (message_list->priv->tree_model_root != NULL)
+ g_node_destroy (message_list->priv->tree_model_root);
+
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (message_list_parent_class)->finalize (object);
}
@@ -2929,6 +2608,395 @@ message_list_selectable_select_all (ESelectable *selectable)
message_list_select_all (MESSAGE_LIST (selectable));
}
+static ETreePath
+message_list_get_root (ETreeModel *tree_model)
+{
+ MessageList *message_list = MESSAGE_LIST (tree_model);
+
+ return message_list->priv->tree_model_root;
+}
+
+static ETreePath
+message_list_get_parent (ETreeModel *tree_model,
+ ETreePath path)
+{
+ return ((GNode *) path)->parent;
+}
+
+static ETreePath
+message_list_get_first_child (ETreeModel *tree_model,
+ ETreePath path)
+{
+ return g_node_first_child ((GNode *) path);
+}
+
+static ETreePath
+message_list_get_next (ETreeModel *tree_model,
+ ETreePath path)
+{
+ return g_node_next_sibling ((GNode *) path);
+}
+
+static gboolean
+message_list_is_root (ETreeModel *tree_model,
+ ETreePath path)
+{
+ return G_NODE_IS_ROOT ((GNode *) path);
+}
+
+static gboolean
+message_list_is_expandable (ETreeModel *tree_model,
+ ETreePath path)
+{
+ return (g_node_first_child ((GNode *) path) != NULL);
+}
+
+static guint
+message_list_get_n_children (ETreeModel *tree_model,
+ ETreePath path)
+{
+ return g_node_n_children ((GNode *) path);
+}
+
+static guint
+message_list_depth (ETreeModel *tree_model,
+ ETreePath path)
+{
+ return g_node_depth ((GNode *) path);
+}
+
+static GdkPixbuf *
+message_list_icon_at (ETreeModel *tree_model,
+ ETreePath path)
+{
+ return NULL;
+}
+
+static gboolean
+message_list_get_expanded_default (ETreeModel *tree_model)
+{
+ MessageList *message_list = MESSAGE_LIST (tree_model);
+
+ return message_list->priv->expanded_default;
+}
+
+static gint
+message_list_column_count (ETreeModel *tree_model)
+{
+ return COL_LAST;
+}
+
+static gboolean
+message_list_has_save_id (ETreeModel *tree_model)
+{
+ return TRUE;
+}
+
+static gchar *
+message_list_get_save_id (ETreeModel *tree_model,
+ ETreePath path)
+{
+ CamelMessageInfo *info;
+
+ if (G_NODE_IS_ROOT ((GNode *) path))
+ return g_strdup ("root");
+
+ /* Note: ETable can ask for the save_id while we're clearing
+ * it, which is the only time info should be NULL. */
+ info = ((GNode *) path)->data;
+ if (info == NULL)
+ return NULL;
+
+ return g_strdup (camel_message_info_uid (info));
+}
+
+static gboolean
+message_list_has_get_node_by_id (ETreeModel *tree_model)
+{
+ return TRUE;
+}
+
+static ETreePath
+message_list_get_node_by_id (ETreeModel *tree_model,
+ const gchar *save_id)
+{
+ MessageList *message_list;
+
+ message_list = MESSAGE_LIST (tree_model);
+
+ if (!strcmp (save_id, "root"))
+ return e_tree_model_get_root (tree_model);
+
+ return g_hash_table_lookup (message_list->uid_nodemap, save_id);
+}
+
+static gpointer
+message_list_sort_value_at (ETreeModel *tree_model,
+ ETreePath path,
+ gint col)
+{
+ MessageList *message_list;
+ struct LatestData ld;
+
+ message_list = MESSAGE_LIST (tree_model);
+
+ if (!(col == COL_SENT || col == COL_RECEIVED))
+ return e_tree_model_value_at (tree_model, path, col);
+
+ if (G_NODE_IS_ROOT ((GNode *) path))
+ return NULL;
+
+ ld.sent = (col == COL_SENT);
+ ld.latest = 0;
+
+ latest_foreach (tree_model, path, &ld);
+ if (message_list->priv->thread_latest)
+ e_tree_model_node_traverse (
+ tree_model, path, latest_foreach, &ld);
+
+ return GINT_TO_POINTER (ld.latest);
+}
+
+static gpointer
+message_list_value_at (ETreeModel *tree_model,
+ ETreePath path,
+ gint col)
+{
+ MessageList *message_list;
+ CamelMessageInfo *msg_info;
+
+ message_list = MESSAGE_LIST (tree_model);
+
+ if (G_NODE_IS_ROOT ((GNode *) path))
+ return NULL;
+
+ /* retrieve the message information array */
+ msg_info = ((GNode *) path)->data;
+ g_return_val_if_fail (msg_info != NULL, NULL);
+
+ return ml_tree_value_at_ex (tree_model, path, col, msg_info, message_list);
+}
+
+static void
+message_list_set_value_at (ETreeModel *tree_model,
+ ETreePath path,
+ gint col,
+ gconstpointer val)
+{
+ g_warn_if_reached ();
+}
+
+static gboolean
+message_list_is_editable (ETreeModel *tree_model,
+ ETreePath path,
+ gint col)
+{
+ return FALSE;
+}
+
+static gpointer
+message_list_duplicate_value (ETreeModel *tree_model,
+ gint col,
+ gconstpointer value)
+{
+ switch (col) {
+ case COL_MESSAGE_STATUS:
+ case COL_FLAGGED:
+ case COL_SCORE:
+ case COL_ATTACHMENT:
+ case COL_DELETED:
+ case COL_UNREAD:
+ case COL_SENT:
+ case COL_RECEIVED:
+ case COL_SIZE:
+ case COL_FOLLOWUP_FLAG_STATUS:
+ case COL_FOLLOWUP_DUE_BY:
+ return (gpointer) value;
+
+ case COL_FROM:
+ case COL_SUBJECT:
+ case COL_TO:
+ case COL_SENDER:
+ case COL_RECIPIENTS:
+ case COL_MIXED_SENDER:
+ case COL_MIXED_RECIPIENTS:
+ case COL_FOLLOWUP_FLAG:
+ case COL_LOCATION:
+ case COL_LABELS:
+ return g_strdup (value);
+
+ default:
+ g_return_val_if_reached (NULL);
+ }
+}
+
+static void
+message_list_free_value (ETreeModel *tree_model,
+ gint col,
+ gpointer value)
+{
+ switch (col) {
+ case COL_MESSAGE_STATUS:
+ case COL_FLAGGED:
+ case COL_SCORE:
+ case COL_ATTACHMENT:
+ case COL_DELETED:
+ case COL_UNREAD:
+ case COL_SENT:
+ case COL_RECEIVED:
+ case COL_SIZE:
+ case COL_FOLLOWUP_FLAG_STATUS:
+ case COL_FOLLOWUP_DUE_BY:
+ case COL_FROM_NORM:
+ case COL_SUBJECT_NORM:
+ case COL_TO_NORM:
+ case COL_SUBJECT_TRIMMED:
+ case COL_COLOUR:
+ break;
+
+ case COL_FROM:
+ case COL_SUBJECT:
+ case COL_TO:
+ case COL_FOLLOWUP_FLAG:
+ case COL_LOCATION:
+ case COL_SENDER:
+ case COL_RECIPIENTS:
+ case COL_MIXED_SENDER:
+ case COL_MIXED_RECIPIENTS:
+ case COL_LABELS:
+ g_free (value);
+ break;
+
+ default:
+ g_warn_if_reached ();
+ }
+}
+
+static gpointer
+message_list_initialize_value (ETreeModel *tree_model,
+ gint col)
+{
+ switch (col) {
+ case COL_MESSAGE_STATUS:
+ case COL_FLAGGED:
+ case COL_SCORE:
+ case COL_ATTACHMENT:
+ case COL_DELETED:
+ case COL_UNREAD:
+ case COL_SENT:
+ case COL_RECEIVED:
+ case COL_SIZE:
+ case COL_FOLLOWUP_FLAG_STATUS:
+ case COL_FOLLOWUP_DUE_BY:
+ return NULL;
+
+ case COL_FROM:
+ case COL_SUBJECT:
+ case COL_TO:
+ case COL_FOLLOWUP_FLAG:
+ case COL_LOCATION:
+ case COL_SENDER:
+ case COL_RECIPIENTS:
+ case COL_MIXED_SENDER:
+ case COL_MIXED_RECIPIENTS:
+ case COL_LABELS:
+ return g_strdup ("");
+
+ default:
+ g_return_val_if_reached (NULL);
+ }
+}
+
+static gboolean
+message_list_value_is_empty (ETreeModel *tree_model,
+ gint col,
+ gconstpointer value)
+{
+ switch (col) {
+ case COL_MESSAGE_STATUS:
+ case COL_FLAGGED:
+ case COL_SCORE:
+ case COL_ATTACHMENT:
+ case COL_DELETED:
+ case COL_UNREAD:
+ case COL_SENT:
+ case COL_RECEIVED:
+ case COL_SIZE:
+ case COL_FOLLOWUP_FLAG_STATUS:
+ case COL_FOLLOWUP_DUE_BY:
+ return value == NULL;
+
+ case COL_FROM:
+ case COL_SUBJECT:
+ case COL_TO:
+ case COL_FOLLOWUP_FLAG:
+ case COL_LOCATION:
+ case COL_SENDER:
+ case COL_RECIPIENTS:
+ case COL_MIXED_SENDER:
+ case COL_MIXED_RECIPIENTS:
+ case COL_LABELS:
+ return !(value && *(gchar *) value);
+
+ default:
+ g_return_val_if_reached (FALSE);
+ }
+}
+
+static gchar *
+message_list_value_to_string (ETreeModel *tree_model,
+ gint col,
+ gconstpointer value)
+{
+ guint ii;
+
+ switch (col) {
+ case COL_MESSAGE_STATUS:
+ ii = GPOINTER_TO_UINT (value);
+ if (ii > 5)
+ return g_strdup ("");
+ return g_strdup (_(status_map[ii]));
+
+ case COL_SCORE:
+ ii = GPOINTER_TO_UINT (value) + 3;
+ if (ii > 6)
+ ii = 3;
+ return g_strdup (_(score_map[ii]));
+
+ case COL_ATTACHMENT:
+ case COL_FLAGGED:
+ case COL_DELETED:
+ case COL_UNREAD:
+ case COL_FOLLOWUP_FLAG_STATUS:
+ ii = GPOINTER_TO_UINT (value);
+ return g_strdup_printf ("%u", ii);
+
+ case COL_SENT:
+ case COL_RECEIVED:
+ case COL_FOLLOWUP_DUE_BY:
+ return filter_date (GPOINTER_TO_INT (value));
+
+ case COL_SIZE:
+ return filter_size (GPOINTER_TO_INT (value));
+
+ case COL_FROM:
+ case COL_SUBJECT:
+ case COL_TO:
+ case COL_FOLLOWUP_FLAG:
+ case COL_LOCATION:
+ case COL_SENDER:
+ case COL_RECIPIENTS:
+ case COL_MIXED_SENDER:
+ case COL_MIXED_RECIPIENTS:
+ case COL_LABELS:
+ return g_strdup (value);
+
+ default:
+ g_return_val_if_reached (NULL);
+ }
+
+}
+
static void
message_list_class_init (MessageListClass *class)
{
@@ -3062,6 +3130,86 @@ message_list_selectable_init (ESelectableInterface *interface)
}
static void
+message_list_tree_model_init (ETreeModelInterface *interface)
+{
+ interface->get_root = message_list_get_root;
+ interface->get_parent = message_list_get_parent;
+ interface->get_first_child = message_list_get_first_child;
+ interface->get_next = message_list_get_next;
+ interface->is_root = message_list_is_root;
+ interface->is_expandable = message_list_is_expandable;
+ interface->get_n_children = message_list_get_n_children;
+ interface->depth = message_list_depth;
+ interface->icon_at = message_list_icon_at;
+ interface->get_expanded_default = message_list_get_expanded_default;
+ interface->column_count = message_list_column_count;
+ interface->has_save_id = message_list_has_save_id;
+ interface->get_save_id = message_list_get_save_id;
+ interface->has_get_node_by_id = message_list_has_get_node_by_id;
+ interface->get_node_by_id = message_list_get_node_by_id;
+ interface->sort_value_at = message_list_sort_value_at;
+ interface->value_at = message_list_value_at;
+ interface->set_value_at = message_list_set_value_at;
+ interface->is_editable = message_list_is_editable;
+ interface->duplicate_value = message_list_duplicate_value;
+ interface->free_value = message_list_free_value;
+ interface->initialize_value = message_list_initialize_value;
+ interface->value_is_empty = message_list_value_is_empty;
+ interface->value_to_string = message_list_value_to_string;
+}
+
+static void
+message_list_init (MessageList *message_list)
+{
+ MessageListPrivate *p;
+ GtkTargetList *target_list;
+ GdkAtom matom;
+
+ message_list->priv = MESSAGE_LIST_GET_PRIVATE (message_list);
+
+ message_list->normalised_hash = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) e_poolv_destroy);
+
+ message_list->uid_nodemap = g_hash_table_new (g_str_hash, g_str_equal);
+
+ message_list->cursor_uid = NULL;
+ message_list->last_sel_single = FALSE;
+
+ g_mutex_init (&message_list->priv->regen_lock);
+
+ /* TODO: Should this only get the selection if we're realised? */
+ p = message_list->priv;
+ p->invisible = gtk_invisible_new ();
+ p->destroyed = FALSE;
+ g_object_ref_sink (p->invisible);
+ p->any_row_changed = FALSE;
+
+ matom = gdk_atom_intern ("x-uid-list", FALSE);
+ gtk_selection_add_target (p->invisible, GDK_SELECTION_CLIPBOARD, matom, 0);
+ gtk_selection_add_target (p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 2);
+
+ g_signal_connect (
+ p->invisible, "selection_get",
+ G_CALLBACK (ml_selection_get), message_list);
+ g_signal_connect (
+ p->invisible, "selection_clear_event",
+ G_CALLBACK (ml_selection_clear_event), message_list);
+ g_signal_connect (
+ p->invisible, "selection_received",
+ G_CALLBACK (ml_selection_received), message_list);
+
+ /* FIXME This is currently unused. */
+ target_list = gtk_target_list_new (NULL, 0);
+ message_list->priv->copy_target_list = target_list;
+
+ /* FIXME This is currently unused. */
+ target_list = gtk_target_list_new (NULL, 0);
+ message_list->priv->paste_target_list = target_list;
+}
+
+static void
message_list_construct (MessageList *message_list)
{
AtkObject *a11y;
@@ -3075,7 +3223,8 @@ message_list_construct (MessageList *message_list)
etspecfile = g_build_filename (EVOLUTION_ETSPECDIR, "message-list.etspec", NULL);
constructed = e_tree_construct_from_spec_file (
- E_TREE (message_list), message_list->model,
+ E_TREE (message_list),
+ E_TREE_MODEL (message_list),
message_list->extras, etspecfile, NULL);
g_free (etspecfile);
@@ -3165,23 +3314,21 @@ message_list_get_session (MessageList *message_list)
static void
clear_info (gchar *key,
- ETreePath *node,
+ GNode *node,
MessageList *message_list)
{
CamelMessageInfo *info;
- info = e_tree_memory_node_get_data (
- (ETreeMemory *) message_list->model, node);
+ info = node->data;
camel_folder_free_message_info (message_list->priv->folder, info);
- e_tree_memory_node_set_data (
- (ETreeMemory *) message_list->model, node, NULL);
+ node->data = NULL;
}
static void
clear_tree (MessageList *message_list,
gboolean tfree)
{
- ETreeModel *etm = message_list->model;
+ ETreeModel *tree_model;
CamelFolder *folder;
#ifdef TIMEIT
@@ -3192,6 +3339,8 @@ clear_tree (MessageList *message_list,
gettimeofday (&start, NULL);
#endif
+ tree_model = E_TREE_MODEL (message_list);
+
/* we also reset the uid_rowmap since it is no longer useful/valid anyway */
folder = message_list_ref_folder (message_list);
if (folder != NULL)
@@ -3207,23 +3356,24 @@ clear_tree (MessageList *message_list,
message_list->priv->oldest_unread_date = 0;
message_list->priv->oldest_unread_uid = NULL;
- if (message_list->tree_root) {
+ if (message_list->priv->tree_model_root != NULL) {
/* we should be frozen already */
- e_tree_memory_node_remove (
- E_TREE_MEMORY (etm), message_list->tree_root);
+ message_list_tree_model_remove (
+ message_list, message_list->priv->tree_model_root);
}
- message_list->tree_root = e_tree_memory_node_insert (
- E_TREE_MEMORY (etm), NULL, 0, NULL);
+ /* Create a new placeholder root node. */
+ message_list_tree_model_insert (message_list, NULL, 0, NULL);
+ g_warn_if_fail (message_list->priv->tree_model_root != NULL);
+
if (tfree)
- e_tree_model_rebuilt (E_TREE_MODEL (etm));
+ e_tree_model_rebuilt (tree_model);
#ifdef TIMEIT
gettimeofday (&end, NULL);
diff = end.tv_sec * 1000 + end.tv_usec / 1000;
diff -= start.tv_sec * 1000 + start.tv_usec / 1000;
printf ("Clearing tree took %ld.%03ld seconds\n", diff / 1000, diff % 1000);
#endif
-
}
static gboolean
@@ -3360,7 +3510,7 @@ is_node_selectable (MessageList *message_list,
static gchar *
find_next_selectable (MessageList *message_list)
{
- ETreePath node;
+ GNode *node;
gint last;
gint vrow_orig;
gint vrow;
@@ -3407,15 +3557,14 @@ find_next_selectable (MessageList *message_list)
return NULL;
}
-static ETreePath *
+static GNode *
ml_uid_nodemap_insert (MessageList *message_list,
CamelMessageInfo *info,
- ETreePath *parent_node,
+ GNode *parent,
gint row)
{
CamelFolder *folder;
- ETreeMemory *tree;
- ETreePath *node;
+ GNode *node;
const gchar *uid;
time_t date;
guint flags;
@@ -3423,11 +3572,11 @@ ml_uid_nodemap_insert (MessageList *message_list,
folder = message_list_ref_folder (message_list);
g_return_val_if_fail (folder != NULL, NULL);
- if (parent_node == NULL)
- parent_node = message_list->tree_root;
+ if (parent == NULL)
+ parent = message_list->priv->tree_model_root;
- tree = E_TREE_MEMORY (message_list->model);
- node = e_tree_memory_node_insert (tree, parent_node, row, info);
+ node = message_list_tree_model_insert (
+ message_list, parent, row, info);
uid = camel_message_info_uid (info);
flags = camel_message_info_flags (info);
@@ -3490,13 +3639,13 @@ ml_uid_nodemap_remove (MessageList *message_list,
/* builds the tree structure */
static void build_subtree (MessageList *message_list,
- ETreePath parent,
+ GNode *parent,
CamelFolderThreadNode *c,
gint *row);
static void build_subtree_diff (MessageList *message_list,
- ETreePath parent,
- ETreePath path,
+ GNode *parent,
+ GNode *node,
CamelFolderThreadNode *c,
gint *row);
@@ -3506,7 +3655,6 @@ build_tree (MessageList *message_list,
gboolean folder_changed)
{
gint row = 0;
- ETreeModel *etm = message_list->model;
ETableItem *table_item = e_tree_get_item (E_TREE (message_list));
gchar *saveuid = NULL;
GPtrArray *selected;
@@ -3525,22 +3673,23 @@ build_tree (MessageList *message_list,
printf ("Loading tree state took %ld.%03ld seconds\n", diff / 1000, diff % 1000);
#endif
- if (message_list->tree_root == NULL)
- message_list->tree_root = e_tree_memory_node_insert (
- E_TREE_MEMORY (etm), NULL, 0, NULL);
+ if (message_list->priv->tree_model_root == NULL) {
+ message_list_tree_model_insert (message_list, NULL, 0, NULL);
+ g_warn_if_fail (message_list->priv->tree_model_root != NULL);
+ }
if (message_list->cursor_uid != NULL)
saveuid = find_next_selectable (message_list);
selected = message_list_get_selected (message_list);
- e_tree_memory_freeze (E_TREE_MEMORY (etm));
+ message_list_tree_model_freeze (message_list);
clear_tree (message_list, FALSE);
build_subtree (
message_list,
- message_list->tree_root,
+ message_list->priv->tree_model_root,
thread->tree, &row);
/* Show the cursor unless we're responding to a
@@ -3548,10 +3697,10 @@ build_tree (MessageList *message_list,
if (folder_changed && table_item != NULL)
table_item->queue_show_cursor = FALSE;
- e_tree_memory_thaw (E_TREE_MEMORY (etm));
+ message_list_tree_model_thaw (message_list);
/* it's required to thaw & freeze, to propagate changes */
- e_tree_memory_freeze (E_TREE_MEMORY (etm));
+ message_list_tree_model_freeze (message_list);
message_list_set_selected (message_list, selected);
@@ -3562,7 +3711,7 @@ build_tree (MessageList *message_list,
if (folder_changed && table_item != NULL)
table_item->queue_show_cursor = FALSE;
- e_tree_memory_thaw (E_TREE_MEMORY (etm));
+ message_list_tree_model_thaw (message_list);
if (!saveuid && message_list->cursor_uid && g_hash_table_lookup (message_list->uid_nodemap, message_list->cursor_uid)) {
/* this makes sure a visible node is selected, like when
* collapsing all nodes and a children had been selected
@@ -3571,7 +3720,7 @@ build_tree (MessageList *message_list,
}
if (saveuid) {
- ETreePath node;
+ GNode *node;
node = g_hash_table_lookup (
message_list->uid_nodemap, saveuid);
@@ -3583,14 +3732,14 @@ build_tree (MessageList *message_list,
signals[MESSAGE_SELECTED], 0, NULL);
} else {
ETree *tree = E_TREE (message_list);
- ETreePath parent = node;
+ GNode *parent = node;
- while (parent = e_tree_model_node_get_parent (etm, parent), parent) {
+ while ((parent = parent->parent) != NULL) {
if (!e_tree_node_is_expanded (tree, parent))
node = parent;
}
- e_tree_memory_freeze (E_TREE_MEMORY (etm));
+ message_list_tree_model_freeze (message_list);
e_tree_set_cursor (E_TREE (message_list), node);
@@ -3599,7 +3748,7 @@ build_tree (MessageList *message_list,
if (folder_changed && table_item != NULL)
table_item->queue_show_cursor = FALSE;
- e_tree_memory_thaw (E_TREE_MEMORY (etm));
+ message_list_tree_model_thaw (message_list);
}
g_free (saveuid);
} else if (message_list->cursor_uid && !g_hash_table_lookup (message_list->uid_nodemap, message_list->cursor_uid)) {
@@ -3624,11 +3773,11 @@ build_tree (MessageList *message_list,
/* Otherwise, this code would probably go as it does the same thing essentially */
static void
build_subtree (MessageList *message_list,
- ETreePath parent,
+ GNode *parent,
CamelFolderThreadNode *c,
gint *row)
{
- ETreePath node;
+ GNode *node;
while (c) {
/* phantom nodes no longer allowed */
@@ -3653,14 +3802,10 @@ build_subtree (MessageList *message_list,
* the same object */
static gint
node_equal (ETreeModel *etm,
- ETreePath ap,
+ GNode *ap,
CamelFolderThreadNode *bp)
{
- CamelMessageInfo *info;
-
- info = e_tree_memory_node_get_data (E_TREE_MEMORY (etm), ap);
-
- if (bp->message && strcmp (camel_message_info_uid (info), camel_message_info_uid (bp->message)) == 0)
+ if (bp->message && strcmp (camel_message_info_uid (ap->data), camel_message_info_uid (bp->message)) == 0)
return 1;
return 0;
@@ -3669,14 +3814,14 @@ node_equal (ETreeModel *etm,
/* adds a single node, retains save state, and handles adding children if required */
static void
add_node_diff (MessageList *message_list,
- ETreePath parent,
- ETreePath path,
+ GNode *parent,
+ GNode *node,
CamelFolderThreadNode *c,
gint *row,
gint myrow)
{
CamelMessageInfo *info;
- ETreePath node;
+ GNode *new_node;
g_return_if_fail (c->message != NULL);
@@ -3685,40 +3830,40 @@ add_node_diff (MessageList *message_list,
/* we just update the hashtable key */
ml_uid_nodemap_remove (message_list, info);
- node = ml_uid_nodemap_insert (message_list, info, parent, myrow);
+ new_node = ml_uid_nodemap_insert (message_list, info, parent, myrow);
(*row)++;
if (c->child) {
- build_subtree_diff (message_list, node, NULL, c->child, row);
+ build_subtree_diff (
+ message_list, new_node, NULL, c->child, row);
}
}
/* removes node, children recursively and all associated data */
static void
remove_node_diff (MessageList *message_list,
- ETreePath node,
+ GNode *node,
gint depth)
{
- ETreeModel *etm = message_list->model;
ETreePath cp, cn;
CamelMessageInfo *info;
- t (printf ("Removing node: %s\n", (gchar *) e_tree_memory_node_get_data (etm, node)));
+ t (printf ("Removing node: %s\n", (gchar *) node->data));
/* we depth-first remove all node data's ... */
- cp = e_tree_model_node_get_first_child (etm, node);
+ cp = g_node_first_child (node);
while (cp) {
- cn = e_tree_model_node_get_next (etm, cp);
+ cn = g_node_next_sibling (cp);
remove_node_diff (message_list, cp, depth + 1);
cp = cn;
}
/* and the rowid entry - if and only if it is referencing this node */
- info = e_tree_memory_node_get_data (E_TREE_MEMORY (etm), node);
+ info = node->data;
/* and only at the toplevel, remove the node (etree should optimise this remove somewhat) */
if (depth == 0)
- e_tree_memory_node_remove (E_TREE_MEMORY (etm), node);
+ message_list_tree_model_remove (message_list, node);
g_return_if_fail (info);
ml_uid_nodemap_remove (message_list, info);
@@ -3728,17 +3873,19 @@ remove_node_diff (MessageList *message_list,
* that have changed */
static void
build_subtree_diff (MessageList *message_list,
- ETreePath parent,
- ETreePath path,
+ GNode *parent,
+ GNode *node,
CamelFolderThreadNode *c,
gint *row)
{
- ETreeModel *etm = message_list->model;
- ETreePath ap, *ai, *at, *tmp;
+ ETreeModel *tree_model;
+ GNode *ap, *ai, *at, *tmp;
CamelFolderThreadNode *bp, *bi, *bt;
gint i, j, myrow = 0;
- ap = path;
+ tree_model = E_TREE_MODEL (message_list);
+
+ ap = node;
bp = c;
while (ap || bp) {
@@ -3753,31 +3900,31 @@ build_subtree_diff (MessageList *message_list,
} else if (bp == NULL) {
t (printf ("out of new nodes\n"));
/* ran out of new nodes - remaining nodes are removed */
- tmp = e_tree_model_node_get_next (etm, ap);
+ tmp = g_node_next_sibling (ap);
remove_node_diff (message_list, ap, 0);
ap = tmp;
- } else if (node_equal (etm, ap, bp)) {
+ } else if (node_equal (tree_model, ap, bp)) {
*row = (*row)+1;
myrow++;
- tmp = e_tree_model_node_get_first_child (etm, ap);
+ tmp = g_node_first_child (ap);
/* make child lists match (if either has one) */
if (bp->child || tmp) {
build_subtree_diff (
message_list, ap, tmp, bp->child, row);
}
- ap = e_tree_model_node_get_next (etm, ap);
+ ap = g_node_next_sibling (ap);
bp = bp->next;
} else {
t (printf ("searching for matches\n"));
/* we have to scan each side for a match */
bi = bp->next;
- ai = e_tree_model_node_get_next (etm, ap);
+ ai = g_node_next_sibling (ap);
for (i = 1; bi != NULL; i++,bi = bi->next) {
- if (node_equal (etm, ap, bi))
+ if (node_equal (tree_model, ap, bi))
break;
}
- for (j = 1; ai != NULL; j++,ai = e_tree_model_node_get_next (etm, ai)) {
- if (node_equal (etm, ai, bp))
+ for (j = 1; ai != NULL; j++,ai = g_node_next_sibling (ai)) {
+ if (node_equal (tree_model, ai, bp))
break;
}
if (i < j) {
@@ -3806,7 +3953,7 @@ build_subtree_diff (MessageList *message_list,
at = ap;
while (at != NULL && at != ai) {
t (printf ("removing old node 0\n"));
- tmp = e_tree_model_node_get_next (etm, at);
+ tmp = g_node_next_sibling (at);
remove_node_diff (message_list, at, 0);
at = tmp;
}
@@ -3828,7 +3975,6 @@ static void
build_flat (MessageList *message_list,
GPtrArray *summary)
{
- ETreeModel *etm = message_list->model;
gchar *saveuid = NULL;
gint i;
GPtrArray *selected;
@@ -3845,7 +3991,7 @@ build_flat (MessageList *message_list,
selected = message_list_get_selected (message_list);
- e_tree_memory_freeze (E_TREE_MEMORY (etm));
+ message_list_tree_model_freeze (message_list);
clear_tree (message_list, FALSE);
@@ -3855,14 +4001,14 @@ build_flat (MessageList *message_list,
ml_uid_nodemap_insert (message_list, info, NULL, -1);
}
- e_tree_memory_thaw (E_TREE_MEMORY (etm));
+ message_list_tree_model_thaw (message_list);
message_list_set_selected (message_list, selected);
g_ptr_array_unref (selected);
if (saveuid) {
- ETreePath node;
+ GNode *node;
node = g_hash_table_lookup (
message_list->uid_nodemap, saveuid);
@@ -3889,19 +4035,21 @@ build_flat (MessageList *message_list,
static void
message_list_change_first_visible_parent (MessageList *message_list,
- ETreePath node)
+ GNode *node)
{
- ETreePath first_visible = NULL;
+ ETreeModel *tree_model;
+ GNode *first_visible = NULL;
+
+ tree_model = E_TREE_MODEL (message_list);
- while (node && (node = e_tree_model_node_get_parent (message_list->model, node))) {
+ while (node != NULL && (node = node->parent) != NULL) {
if (!e_tree_node_is_expanded (E_TREE (message_list), node))
first_visible = node;
}
if (first_visible != NULL) {
- e_tree_model_pre_change (message_list->model);
- e_tree_model_node_data_changed (
- message_list->model, first_visible);
+ e_tree_model_pre_change (tree_model);
+ e_tree_model_node_data_changed (tree_model, first_visible);
}
}
@@ -3918,7 +4066,7 @@ mail_folder_hide_by_flag (CamelFolder *folder,
newchanges = camel_folder_change_info_new ();
for (i = 0; i < changes->uid_changed->len; i++) {
- ETreePath node;
+ GNode *node;
guint32 flags;
node = g_hash_table_lookup (
@@ -3963,6 +4111,7 @@ message_list_folder_changed (CamelFolder *folder,
MessageList *message_list)
{
CamelFolderChangeInfo *altered_changes = NULL;
+ ETreeModel *tree_model;
gboolean need_list_regen = TRUE;
gboolean hide_junk;
gboolean hide_deleted;
@@ -3971,6 +4120,8 @@ message_list_folder_changed (CamelFolder *folder,
if (message_list->priv->destroyed)
return;
+ tree_model = E_TREE_MODEL (message_list);
+
hide_junk = message_list_get_hide_junk (message_list, folder);
hide_deleted = message_list_get_hide_deleted (message_list, folder);
@@ -3995,14 +4146,14 @@ message_list_folder_changed (CamelFolder *folder,
if (altered_changes->uid_added->len == 0 && altered_changes->uid_removed->len == 0 && altered_changes->uid_changed->len < 100) {
for (i = 0; i < altered_changes->uid_changed->len; i++) {
- ETreePath node;
+ GNode *node;
node = g_hash_table_lookup (
message_list->uid_nodemap,
altered_changes->uid_changed->pdata[i]);
if (node) {
- e_tree_model_pre_change (message_list->model);
- e_tree_model_node_data_changed (message_list->model, node);
+ e_tree_model_pre_change (tree_model);
+ e_tree_model_node_data_changed (tree_model, node);
message_list_change_first_visible_parent (message_list, node);
}
@@ -4049,8 +4200,6 @@ void
message_list_set_folder (MessageList *message_list,
CamelFolder *folder)
{
- ETreeModel *etm = message_list->model;
-
/* XXX Do we need a property lock to guard this? */
g_return_if_fail (IS_MESSAGE_LIST (message_list));
@@ -4082,9 +4231,9 @@ message_list_set_folder (MessageList *message_list,
if (message_list->priv->folder != NULL)
save_tree_state (message_list, message_list->priv->folder);
- e_tree_memory_freeze (E_TREE_MEMORY (etm));
+ message_list_tree_model_freeze (message_list);
clear_tree (message_list, TRUE);
- e_tree_memory_thaw (E_TREE_MEMORY (etm));
+ message_list_tree_model_thaw (message_list);
/* remove the cursor activate idle handler */
if (message_list->idle_id != 0) {
@@ -4183,6 +4332,15 @@ message_list_get_paste_target_list (MessageList *message_list)
return message_list->priv->paste_target_list;
}
+void
+message_list_set_expanded_default (MessageList *message_list,
+ gboolean expanded_default)
+{
+ g_return_if_fail (IS_MESSAGE_LIST (message_list));
+
+ message_list->priv->expanded_default = expanded_default;
+}
+
gboolean
message_list_get_group_by_threads (MessageList *message_list)
{
@@ -4309,16 +4467,16 @@ on_cursor_activated_idle (gpointer data)
static void
on_cursor_activated_cmd (ETree *tree,
gint row,
- ETreePath path,
+ GNode *node,
gpointer user_data)
{
MessageList *message_list = MESSAGE_LIST (user_data);
const gchar *new_uid;
- if (path == NULL)
+ if (node == NULL)
new_uid = NULL;
else
- new_uid = get_message_uid (message_list, path);
+ new_uid = get_message_uid (message_list, node);
/* Do not check the cursor_uid and the new_uid values, because the
* selected item (set in on_selection_changed_cmd) can be different
@@ -4347,7 +4505,7 @@ on_selection_changed_cmd (ETree *tree,
{
GPtrArray *uids;
const gchar *newuid;
- ETreePath cursor;
+ GNode *cursor;
/* not sure if we could just ignore this for the cursor, i think sometimes you
* only get a selection changed when you should also get a cursor activated? */
@@ -4356,7 +4514,7 @@ on_selection_changed_cmd (ETree *tree,
if (uids->len == 1)
newuid = g_ptr_array_index (uids, 0);
else if ((cursor = e_tree_get_cursor (tree)))
- newuid = (gchar *) camel_message_info_uid (e_tree_memory_node_get_data ((ETreeMemory *) tree, cursor));
+ newuid = (gchar *) camel_message_info_uid (cursor->data);
else
newuid = NULL;
@@ -4384,7 +4542,7 @@ on_selection_changed_cmd (ETree *tree,
static gint
on_click (ETree *tree,
gint row,
- ETreePath path,
+ GNode *node,
gint col,
GdkEvent *event,
MessageList *list)
@@ -4403,7 +4561,7 @@ on_click (ETree *tree,
else if (col != COL_FOLLOWUP_FLAG_STATUS)
return FALSE;
- if (!(info = get_message_info (list, path)))
+ if (!(info = get_message_info (list, node)))
return FALSE;
folder = message_list_ref_folder (list);
@@ -4482,16 +4640,16 @@ struct _ml_selected_data {
};
static void
-ml_getselected_cb (ETreePath path,
+ml_getselected_cb (GNode *node,
gpointer user_data)
{
struct _ml_selected_data *data = user_data;
const gchar *uid;
- if (e_tree_model_node_is_root (data->message_list->model, path))
+ if (G_NODE_IS_ROOT (node))
return;
- uid = get_message_uid (data->message_list, path);
+ uid = get_message_uid (data->message_list, node);
g_return_if_fail (uid != NULL);
g_ptr_array_add (data->uids, g_strdup (uid));
}
@@ -4509,7 +4667,8 @@ message_list_get_selected (MessageList *message_list)
g_ptr_array_set_free_func (data.uids, (GDestroyNotify) g_free);
e_tree_selected_path_foreach (
- E_TREE (message_list), ml_getselected_cb, &data);
+ E_TREE (message_list),
+ (ETreeForeachFunc) ml_getselected_cb, &data);
folder = message_list_ref_folder (message_list);
@@ -4527,7 +4686,7 @@ message_list_set_selected (MessageList *message_list,
{
gint i;
ETreeSelectionModel *etsm;
- ETreePath node;
+ GNode *node;
GPtrArray *paths = g_ptr_array_new ();
etsm = (ETreeSelectionModel *)
@@ -4535,7 +4694,7 @@ message_list_set_selected (MessageList *message_list,
for (i = 0; i < uids->len; i++) {
node = g_hash_table_lookup (
message_list->uid_nodemap, uids->pdata[i]);
- if (node)
+ if (node != NULL)
g_ptr_array_add (paths, node);
}
@@ -4564,7 +4723,7 @@ message_list_sort_uids (MessageList *message_list,
{
struct ml_sort_uids_data *data;
GPtrArray *array;
- ETreePath path;
+ GNode *node;
ETreeTableAdapter *adapter;
gint ii;
@@ -4583,9 +4742,9 @@ message_list_sort_uids (MessageList *message_list,
data = g_new0 (struct ml_sort_uids_data, 1);
data->uid = g_ptr_array_index (uids, ii);
- path = g_hash_table_lookup (message_list->uid_nodemap, data->uid);
- if (path)
- data->row = e_tree_table_adapter_row_of_node (adapter, path);
+ node = g_hash_table_lookup (message_list->uid_nodemap, data->uid);
+ if (node != NULL)
+ data->row = e_tree_table_adapter_row_of_node (adapter, node);
else
data->row = ii;
@@ -4609,12 +4768,12 @@ struct ml_count_data {
};
static void
-ml_getcount_cb (ETreePath path,
+ml_getcount_cb (GNode *node,
gpointer user_data)
{
struct ml_count_data *data = user_data;
- if (!e_tree_model_node_is_root (data->message_list->model, path))
+ if (!G_NODE_IS_ROOT (node))
data->count++;
}
@@ -4625,7 +4784,9 @@ message_list_count (MessageList *message_list)
g_return_val_if_fail (IS_MESSAGE_LIST (message_list), 0);
- e_tree_path_foreach (E_TREE (message_list), ml_getcount_cb, &data);
+ e_tree_path_foreach (
+ E_TREE (message_list),
+ (ETreeForeachFunc) ml_getcount_cb, &data);
return data.count;
}
@@ -5008,7 +5169,7 @@ message_list_regen_thread (GSimpleAsyncResult *simple,
RegenData *regen_data;
GPtrArray *uids, *searchuids = NULL;
CamelMessageInfo *info;
- ETreePath cursor;
+ GNode *cursor;
ETree *tree;
GString *expr;
gboolean hide_deleted;
@@ -5279,12 +5440,12 @@ message_list_regen_done_cb (GObject *source_object,
regen_data->last_row = row_count;
if (regen_data->last_row >= 0) {
- ETreePath path;
+ GNode *node;
- path = e_tree_table_adapter_node_at_row (
+ node = e_tree_table_adapter_node_at_row (
adapter, regen_data->last_row);
- if (path != NULL)
- select_path (message_list, path);
+ if (node != NULL)
+ select_node (message_list, node);
}
}
diff --git a/mail/message-list.h b/mail/message-list.h
index 06950fe943..9a792e44fc 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -100,8 +100,6 @@ struct _MessageList {
MessageListPrivate *priv;
/* The table */
- ETreeModel *model;
- ETreePath tree_root;
ETableExtras *extras;
GHashTable *uid_nodemap; /* uid (from info) -> tree node mapping */
@@ -162,6 +160,9 @@ GtkTargetList * message_list_get_copy_target_list
(MessageList *message_list);
GtkTargetList * message_list_get_paste_target_list
(MessageList *message_list);
+void message_list_set_expanded_default
+ (MessageList *message_list,
+ gboolean expanded_default);
gboolean message_list_get_group_by_threads
(MessageList *message_list);
void message_list_set_group_by_threads