aboutsummaryrefslogtreecommitdiffstats
path: root/mail/message-list.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/message-list.c')
-rw-r--r--mail/message-list.c257
1 files changed, 216 insertions, 41 deletions
diff --git a/mail/message-list.c b/mail/message-list.c
index 2d5b34a270..d28e9a9d0e 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -50,10 +50,12 @@
#include "e-util/e-profile-event.h"
#include "e-util/e-util-private.h"
#include "e-util/e-util.h"
-#include "e-util/e-util-labels.h"
#include "misc/e-gui-utils.h"
+#include "shell/e-shell.h"
+#include "shell/e-shell-settings.h"
+
#include "table/e-cell-checkbox.h"
#include "table/e-cell-hbox.h"
#include "table/e-cell-date.h"
@@ -67,6 +69,7 @@
#include "table/e-cell-vbox.h"
#include "table/e-cell-hbox.h"
+#include "e-mail-label-list-store.h"
#include "em-popup.h"
#include "em-utils.h"
#include "mail-config.h"
@@ -97,6 +100,10 @@
#define d(x)
#define t(x)
+#define MESSAGE_LIST_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), MESSAGE_LIST_TYPE, MessageListPrivate))
+
struct _MLSelection {
GPtrArray *uids;
CamelFolder *folder;
@@ -106,6 +113,8 @@ struct _MLSelection {
struct _MessageListPrivate {
GtkWidget *invisible; /* 4 selection */
+ EShellBackend *shell_backend;
+
struct _MLSelection clipboard;
gboolean destroyed;
@@ -113,6 +122,11 @@ struct _MessageListPrivate {
gboolean any_row_changed; /* save state before regen list when this is set to true */
};
+enum {
+ PROP_0,
+ PROP_SHELL_BACKEND
+};
+
static struct {
const gchar *target;
GdkAtom atom;
@@ -809,7 +823,7 @@ message_list_invert_selection (MessageList *message_list)
void
message_list_copy(MessageList *ml, gboolean cut)
{
- struct _MessageListPrivate *p = ml->priv;
+ MessageListPrivate *p = ml->priv;
GPtrArray *uids;
clear_selection(ml, &p->clipboard);
@@ -1222,53 +1236,124 @@ sanitize_recipients (const gchar *string)
}
static gint
-get_all_labels (CamelMessageInfo *msg_info, gchar **label_str, gboolean get_tags)
-{
+get_all_labels (MessageList *message_list,
+ CamelMessageInfo *msg_info,
+ gchar **label_str,
+ gboolean get_tags)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EMailLabelListStore *store;
+ GtkTreeIter iter;
GString *str;
+ const gchar *property_name;
const gchar *old_label;
+ gchar *new_label;
gint count = 0;
const CamelFlag *flag;
- GSList *labels;
- labels = mail_config_get_labels ();
+ shell_backend = message_list_get_shell_backend (message_list);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ property_name = "mail-label-list-store";
+ store = e_shell_settings_get_object (shell_settings, property_name);
+
str = g_string_new ("");
for (flag = camel_message_info_user_flags (msg_info); flag; flag = flag->next) {
- const gchar *name = e_util_labels_get_name (labels, flag->name);
+ gchar *item;
- if (name) {
- if (str->len)
- g_string_append (str, ", ");
+ if (!e_mail_label_list_store_lookup (store, flag->name, &iter))
+ continue;
- if (get_tags)
- name = flag->name;
+ if (get_tags)
+ item = e_mail_label_list_store_get_tag (store, &iter);
+ else
+ item = e_mail_label_list_store_get_name (store, &iter);
- g_string_append (str, name);
- count++;
- }
+ if (str->len)
+ g_string_append (str, ", ");
+
+ g_string_append (str, item);
+ count++;
+
+ g_free (item);
}
- old_label = e_util_labels_get_new_tag (camel_message_info_user_tag (msg_info, "label"));
+ old_label = camel_message_info_user_tag (msg_info, "label");
+ if (old_label == NULL)
+ goto exit;
- if (old_label != NULL) {
- const gchar *name = NULL;
+ /* Convert old-style labels ("<name>") to "$Label<name>". */
+ new_label = g_alloca (strlen (old_label) + 10);
+ g_stpcpy (g_stpcpy (new_label, "$Label"), old_label);
+
+ if (e_mail_label_list_store_lookup (store, new_label, &iter)) {
+ gchar *name = NULL;
if (str->len)
g_string_append (str, ", ");
if (!get_tags)
- name = e_util_labels_get_name (labels, old_label);
+ name = e_mail_label_list_store_get_name (store, &iter);
g_string_append (str, (get_tags || !name) ? old_label : name);
- ++count;
+ count++;
+
+ g_free (name);
}
+exit:
*label_str = g_string_free (str, FALSE);
+ g_object_unref (store);
+
return count;
}
static const gchar *
+get_label_color (MessageList *message_list,
+ const gchar *tag)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EMailLabelListStore *store;
+ GtkTreeIter iter;
+ GdkColor color;
+ const gchar *property_name;
+ const gchar *interned = NULL;
+ gchar *color_spec;
+
+ /* FIXME get_all_labels() should return an array of tree iterators,
+ * not strings. Now we just have to lookup the tag again. */
+
+ shell_backend = message_list_get_shell_backend (message_list);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ property_name = "mail-label-list-store";
+ store = e_shell_settings_get_object (shell_settings, property_name);
+
+ if (!e_mail_label_list_store_lookup (store, tag, &iter))
+ goto exit;
+
+ e_mail_label_list_store_get_color (store, &iter, &color);
+
+ /* XXX Hack to avoid returning an allocated string. */
+ color_spec = gdk_color_to_string (&color);
+ interned = g_intern_string (color_spec);
+ g_free (color_spec);
+
+exit:
+ g_object_unref (store);
+
+ return interned;
+}
+
+static const gchar *
get_trimmed_subject (CamelMessageInfo *info)
{
const gchar *subject;
@@ -1469,9 +1554,8 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, gint col, gpointer model_data
completed = camel_message_info_user_tag(msg_info, "completed-on");
followup = camel_message_info_user_tag(msg_info, "follow-up");
if (colour == NULL) {
- if ((n = get_all_labels (msg_info, &labels_string, TRUE)) == 1) {
-
- colour = e_util_labels_get_color_str (mail_config_get_labels (), labels_string);
+ if ((n = get_all_labels (message_list, msg_info, &labels_string, TRUE)) == 1) {
+ colour = get_label_color (message_list, labels_string);
} else if (camel_message_info_flags(msg_info) & CAMEL_MESSAGE_FLAGGED) {
/* FIXME: extract from the important.xpm somehow. */
colour = "#A7453E";
@@ -1550,7 +1634,7 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, gint col, gpointer model_data
cleansed_str = g_string_new ("");
- if (get_all_labels (msg_info, &str, FALSE)) {
+ if (get_all_labels (message_list, msg_info, &str, FALSE)) {
gint i;
for (i = 0; str[i] != '\0'; ++i) {
if (str[i] != '_') {
@@ -1946,7 +2030,7 @@ ml_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint ti
static gboolean
ml_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, MessageList *ml)
{
- struct _MessageListPrivate *p = ml->priv;
+ MessageListPrivate *p = ml->priv;
clear_selection(ml, &p->clipboard);
@@ -2241,13 +2325,25 @@ on_model_row_changed (ETableModel *model, gint row, MessageList *ml)
/*
* GObject::init
*/
+
+static void
+message_list_set_shell_backend (MessageList *message_list,
+ EShellBackend *shell_backend)
+{
+ g_return_if_fail (message_list->priv->shell_backend == NULL);
+
+ message_list->priv->shell_backend = g_object_ref (shell_backend);
+}
+
static void
message_list_init (MessageList *message_list)
{
- struct _MessageListPrivate *p;
+ MessageListPrivate *p;
GtkAdjustment *adjustment;
GdkAtom matom;
+ message_list->priv = MESSAGE_LIST_GET_PRIVATE (message_list);
+
adjustment = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, G_MAXDOUBLE, 0.0, 0.0, 0.0);
gtk_scrolled_window_set_vadjustment ((GtkScrolledWindow *) message_list, adjustment);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (message_list), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
@@ -2276,7 +2372,7 @@ message_list_init (MessageList *message_list)
message_list->regen_lock = g_mutex_new ();
/* TODO: Should this only get the selection if we're realised? */
- p = message_list->priv = g_malloc0(sizeof(*message_list->priv));
+ p = message_list->priv;
p->invisible = gtk_invisible_new();
p->destroyed = FALSE;
g_object_ref_sink(p->invisible);
@@ -2297,7 +2393,7 @@ static void
message_list_destroy(GtkObject *object)
{
MessageList *message_list = MESSAGE_LIST (object);
- struct _MessageListPrivate *p = message_list->priv;
+ MessageListPrivate *p = message_list->priv;
p->destroyed = TRUE;
@@ -2349,14 +2445,65 @@ message_list_destroy(GtkObject *object)
message_list->seen_id = 0;
}
+ /* Chain up to parent's destroy() method. */
GTK_OBJECT_CLASS (message_list_parent_class)->destroy(object);
}
static void
-message_list_finalise (GObject *object)
+message_list_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ message_list_set_shell_backend (
+ MESSAGE_LIST (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+message_list_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ g_value_set_object (
+ value, message_list_get_shell_backend (
+ MESSAGE_LIST (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+message_list_dispose (GObject *object)
+{
+ MessageListPrivate *priv;
+
+ priv = MESSAGE_LIST_GET_PRIVATE (object);
+
+ if (priv->shell_backend != NULL) {
+ g_object_unref (priv->shell_backend);
+ priv->shell_backend = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (message_list_parent_class)->dispose (object);
+}
+
+static void
+message_list_finalize (GObject *object)
{
MessageList *message_list = MESSAGE_LIST (object);
- struct _MessageListPrivate *p = message_list->priv;
+ MessageListPrivate *priv = message_list->priv;
g_hash_table_destroy (message_list->normalised_hash);
@@ -2386,10 +2533,9 @@ message_list_finalise (GObject *object)
g_free(message_list->folder_uri);
message_list->folder_uri = NULL;
- clear_selection(message_list, &p->clipboard);
-
- g_free(p);
+ clear_selection(message_list, &priv->clipboard);
+ /* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (message_list_parent_class)->finalize (object);
}
@@ -2397,17 +2543,36 @@ message_list_finalise (GObject *object)
* GObjectClass::init
*/
static void
-message_list_class_init (MessageListClass *message_list_class)
+message_list_class_init (MessageListClass *class)
{
- GObjectClass *object_class = (GObjectClass *) message_list_class;
- GtkObjectClass *gtkobject_class = (GtkObjectClass *) message_list_class;
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
gint i;
for (i=0;i<sizeof(ml_drag_info)/sizeof(ml_drag_info[0]);i++)
ml_drag_info[i].atom = gdk_atom_intern(ml_drag_info[i].target, FALSE);
- object_class->finalize = message_list_finalise;
- gtkobject_class->destroy = message_list_destroy;
+ g_type_class_add_private (class, sizeof (MessageListPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = message_list_set_property;
+ object_class->get_property = message_list_get_property;
+ object_class->dispose = message_list_dispose;
+ object_class->finalize = message_list_finalize;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = message_list_destroy;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_BACKEND,
+ g_param_spec_object (
+ "shell-backend",
+ _("Shell Backend"),
+ _("The mail shell backend"),
+ E_TYPE_SHELL_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
message_list_signals[MESSAGE_SELECTED] =
g_signal_new ("message_selected",
@@ -2560,19 +2725,30 @@ message_list_construct (MessageList *message_list)
* Returns a new message-list widget.
**/
GtkWidget *
-message_list_new (void)
+message_list_new (EShellBackend *shell_backend)
{
MessageList *message_list;
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+
message_list = MESSAGE_LIST (g_object_new(message_list_get_type (),
"hadjustment", NULL,
"vadjustment", NULL,
+ "shell-backend", shell_backend,
NULL));
message_list_construct (message_list);
return GTK_WIDGET (message_list);
}
+EShellBackend *
+message_list_get_shell_backend (MessageList *message_list)
+{
+ g_return_val_if_fail (IS_MESSAGE_LIST (message_list), NULL);
+
+ return message_list->priv->shell_backend;
+}
+
static void
clear_info(gchar *key, ETreePath *node, MessageList *ml)
{
@@ -4068,9 +4244,8 @@ regen_list_exec (struct _regen_list_msg *m)
if ((!is_deleted || (is_deleted && !m->hidedel)) && (!is_junk || (is_junk && !m->hidejunk)))
g_ptr_array_add (uids, (gpointer) camel_pstring_strdup (looking_for));
-
- camel_folder_free_message_info (m->folder, looking_info);
}
+
}
}
}