#include <glib/gi18n.h>
#include <string.h>
-
+#include <gdk/gdkkeysyms.h>
#include <tny-account-store-view.h>
#include <tny-gtk-account-list-model.h>
#include <tny-gtk-folder-store-tree-model.h>
GtkTreeIter *iter2,
gpointer user_data);
+static gboolean filter_row (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data);
+
+static gboolean on_key_pressed (GtkWidget *self,
+ GdkEventKey *event,
+ gpointer user_data);
+
+static void on_configuration_key_changed (ModestConf* conf,
+ const gchar *key,
+ ModestConfEvent event,
+ ModestFolderView *self);
+
/* DnD functions */
static void on_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
static void setup_drag_and_drop (GtkTreeView *self);
-static gboolean on_key_pressed (GtkWidget *self,
- GdkEventKey *event,
- gpointer user_data);
-
-static void on_configuration_key_changed (ModestConf* conf,
- const gchar *key,
- ModestConfEvent event,
- ModestFolderView *self);
-
enum {
FOLDER_SELECTION_CHANGED_SIGNAL,
+ FOLDER_DISPLAY_NAME_CHANGED_SIGNAL,
LAST_SIGNAL
};
typedef struct _ModestFolderViewPrivate ModestFolderViewPrivate;
struct _ModestFolderViewPrivate {
- TnyAccountStore *account_store;
- TnyFolder *cur_folder;
- GtkTreeRowReference *cur_row;
+ TnyAccountStore *account_store;
+ TnyFolderStore *cur_folder_store;
- gulong account_update_signal;
- gulong changed_signal;
- gulong accounts_reloaded_signal;
+ gulong account_update_signal;
+ gulong changed_signal;
+ gulong accounts_reloaded_signal;
- GtkTreeSelection *cur_selection;
- TnyFolderStoreQuery *query;
- guint timer_expander;
+ GtkTreeSelection *cur_selection;
+ TnyFolderStoreQuery *query;
+ guint timer_expander;
- gchar *local_account_name;
+ gchar *local_account_name;
+ ModestFolderViewStyle style;
};
#define MODEST_FOLDER_VIEW_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE((o), \
NULL, NULL,
modest_marshal_VOID__POINTER_BOOLEAN,
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN);
+
+ /*
+ * This signal is emitted whenever the currently selected
+ * folder display name is computed. Note that the name could
+ * be different to the folder name, because we could append
+ * the unread messages count to the folder name to build the
+ * folder display name
+ */
+ signals[FOLDER_DISPLAY_NAME_CHANGED_SIGNAL] =
+ g_signal_new ("folder-display-name-changed",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (ModestFolderViewClass,
+ folder_display_name_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
}
text_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
{
+ ModestFolderViewPrivate *priv;
GObject *rendobj;
gchar *fname = NULL;
- gint unread;
+ gint unread, all;
TnyFolderType type;
GObject *instance = NULL;
gtk_tree_model_get (tree_model, iter,
TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &fname,
+ TNY_GTK_FOLDER_STORE_TREE_MODEL_ALL_COLUMN, &all,
TNY_GTK_FOLDER_STORE_TREE_MODEL_UNREAD_COLUMN, &unread,
TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
g_free (fname);
return;
}
+
+
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE (data);
if (type != TNY_FOLDER_TYPE_ROOT) {
+ gint number;
+
if (modest_tny_folder_is_local_folder (TNY_FOLDER (instance))) {
TnyFolderType type;
type = modest_tny_folder_get_local_folder_type (TNY_FOLDER (instance));
}
}
+ /* Select the number to show */
+ if ((type == TNY_FOLDER_TYPE_DRAFTS) || (type == TNY_FOLDER_TYPE_OUTBOX))
+ number = all;
+ else
+ number = unread;
+
/* Use bold font style if there are unread messages */
if (unread > 0) {
gchar *folder_title = g_strdup_printf ("%s (%d)", fname, unread);
g_object_set (rendobj,"text", folder_title, "weight", 800, NULL);
+ if (G_OBJECT (priv->cur_folder_store) == instance)
+ g_signal_emit (G_OBJECT(data),
+ signals[FOLDER_DISPLAY_NAME_CHANGED_SIGNAL], 0,
+ folder_title);
g_free (folder_title);
- } else
+ } else {
g_object_set (rendobj,"text", fname, "weight", 400, NULL);
+ if (G_OBJECT (priv->cur_folder_store) == instance)
+ g_signal_emit (G_OBJECT(data),
+ signals[FOLDER_DISPLAY_NAME_CHANGED_SIGNAL], 0,
+ fname);
+ }
} else {
- ModestFolderViewPrivate *priv;
const gchar *account_name = NULL;
const gchar *account_id = NULL;
-
- priv = MODEST_FOLDER_VIEW_GET_PRIVATE (data);
/* If it's a server account */
account_id = tny_account_get_id (TNY_ACCOUNT (instance));
}
}
+ /* Notify display name observers */
+ if (G_OBJECT (priv->cur_folder_store) == instance)
+ g_signal_emit (G_OBJECT(data),
+ signals[FOLDER_DISPLAY_NAME_CHANGED_SIGNAL], 0,
+ account_name);
+
/* Use bold font style */
g_object_set (rendobj,"text", account_name, "weight", 800, NULL);
}
priv->timer_expander = 0;
priv->account_store = NULL;
- priv->cur_folder = NULL;
- priv->cur_row = NULL;
+ priv->cur_folder_store = NULL;
priv->query = NULL;
+ priv->style = MODEST_FOLDER_VIEW_STYLE_SHOW_ALL;
/* Initialize the local account name */
conf = modest_runtime_get_conf();
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
priv->changed_signal = g_signal_connect (sel, "changed",
G_CALLBACK (on_selection_changed), self);
+
return GTK_WIDGET(self);
}
gtk_tree_path_free (path);
}
+/*
+ * HACK: we use this function to implement the
+ * MODEST_FOLDER_VIEW_STYLE_SHOW_ONE style. This implementation
+ * assumes that the model has the following order (which is currently
+ * true) Remote folders->Local folders->MMC folders, so the rows of
+ * the first level (that represent the accounts) are received in the
+ * same order. So basically it uses a static variable to register that
+ * a remote account has already being shown to hide the others
+ * (returning NULL). When the function evaluates the local or the MMC
+ * accounts is time to reset the static variable in order to get it
+ * ready for the next time the tree model needs to be shown.
+ */
+static gboolean
+filter_row (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ static gboolean found = FALSE;
+ gboolean retval;
+ gint type;
+ GObject *instance;
+
+ gtk_tree_model_get (model, iter,
+ TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
+ TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
+ -1);
+
+ if (type == TNY_FOLDER_TYPE_ROOT) {
+ const gchar *account_id = tny_account_get_id (TNY_ACCOUNT (instance));
+
+ if (strcmp (account_id, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) &&
+ strcmp (account_id, MODEST_MMC_ACCOUNT_ID)) {
+
+ if (!found) {
+ found = TRUE;
+ retval = TRUE;
+ } else
+ retval = FALSE;
+ } else {
+ found = FALSE;
+ retval = TRUE;
+ }
+ } else
+ retval = TRUE;
+
+ return retval;
+}
+
static gboolean
update_model (ModestFolderView *self, ModestTnyAccountStore *account_store)
{
ModestFolderViewPrivate *priv;
-
TnyList *account_list;
- GtkTreeModel *model, *sortable;
+ GtkTreeModel *model;
g_return_val_if_fail (account_store, FALSE);
priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
- /* Notify that there is no folder selected*/
+ /* Notify that there is no folder selected */
g_signal_emit (G_OBJECT(self),
signals[FOLDER_SELECTION_CHANGED_SIGNAL], 0,
NULL, TRUE);
account_list,
TNY_ACCOUNT_STORE_STORE_ACCOUNTS);
if (account_list) {
+ GtkTreeModel *filter_model = NULL, *sortable = NULL;
+
sortable = gtk_tree_model_sort_new_with_model (model);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sortable),
TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN,
TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN,
cmp_rows, NULL, NULL);
+ /* Create filter model */
+ if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE) {
+ filter_model = gtk_tree_model_filter_new (sortable, NULL);
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model),
+ filter_row,
+ NULL,
+ NULL);
+ }
+
/* Set new model */
- gtk_tree_view_set_model (GTK_TREE_VIEW(self), sortable);
+ gtk_tree_view_set_model (GTK_TREE_VIEW(self),
+ (filter_model) ? filter_model : sortable);
expand_root_items (self); /* expand all account folders */
g_object_unref (account_list);
}
static void
on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
{
- GtkTreeModel *model_sort, *model;
- TnyFolder *folder = NULL;
- GtkTreeIter iter, iter_sort;
- GtkTreePath *path;
+ GtkTreeModel *model;
+ TnyFolderStore *folder = NULL;
+ GtkTreeIter iter;
ModestFolderView *tree_view;
ModestFolderViewPrivate *priv;
gint type;
priv->cur_selection = sel;
/* folder was _un_selected if true */
- if (!gtk_tree_selection_get_selected (sel, &model_sort, &iter_sort)) {
- if (priv->cur_folder)
- g_object_unref (priv->cur_folder);
- if (priv->cur_row)
- gtk_tree_row_reference_free (priv->cur_row);
- priv->cur_folder = NULL;
- priv->cur_row = NULL;
+ if (!gtk_tree_selection_get_selected (sel, &model, &iter)) {
+ if (priv->cur_folder_store)
+ g_object_unref (priv->cur_folder_store);
+ priv->cur_folder_store = NULL;
+
+ /* Notify the display name observers */
+ g_signal_emit (G_OBJECT(user_data),
+ signals[FOLDER_DISPLAY_NAME_CHANGED_SIGNAL], 0,
+ NULL);
return;
}
- model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (model_sort));
- gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model_sort),
- &iter,
- &iter_sort);
-
tree_view = MODEST_FOLDER_VIEW (user_data);
gtk_tree_model_get (model, &iter,
-1);
/* If the folder is the same do not notify */
- if ((type == TNY_FOLDER_TYPE_ROOT) || (priv->cur_folder == folder)) {
+ if (priv->cur_folder_store == folder) {
g_object_unref (folder);
return;
}
/* Current folder was unselected */
- if (priv->cur_folder) {
+ if (priv->cur_folder_store) {
g_signal_emit (G_OBJECT(tree_view), signals[FOLDER_SELECTION_CHANGED_SIGNAL], 0,
- priv->cur_folder, FALSE);
- g_object_unref (priv->cur_folder);
+ priv->cur_folder_store, FALSE);
+ g_object_unref (priv->cur_folder_store);
}
- if (priv->cur_row)
- gtk_tree_row_reference_free (priv->cur_row);
-
/* New current references */
- path = gtk_tree_model_get_path (model_sort, &iter_sort);
- priv->cur_folder = folder;
- priv->cur_row = gtk_tree_row_reference_new (model_sort, path);
-
- /* Frees */
- gtk_tree_path_free (path);
+ priv->cur_folder_store = folder;
/* New folder has been selected */
g_signal_emit (G_OBJECT(tree_view),
0, folder, TRUE);
}
-TnyFolder *
+TnyFolderStore *
modest_folder_view_get_selected (ModestFolderView *self)
{
ModestFolderViewPrivate *priv;
g_return_val_if_fail (self, NULL);
priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
- if (priv->cur_folder)
- g_object_ref (priv->cur_folder);
+ if (priv->cur_folder_store)
+ g_object_ref (priv->cur_folder_store);
- return priv->cur_folder;
+ return priv->cur_folder_store;
}
+/*
+ * This function orders the mail accounts following the next rules
+ * 1st - remote accounts
+ * 2nd - local account
+ * 3rd - MMC account
+ */
static gint
cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
gpointer user_data)
gchar *name1, *name2;
TnyFolderType type;
TnyFolder *folder1, *folder2;
-
+
gtk_tree_model_get (tree_model, iter1,
TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &name1,
TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder2,
-1);
- /* local_folders should be the last one */
+ /* Order must be: Remote accounts -> Local account -> MMC account */
if (type == TNY_FOLDER_TYPE_ROOT) {
- /* the account name is also the name of the root folder
- * in case of local folders */
- if (name1 && strcmp (name1, MODEST_LOCAL_FOLDERS_ACCOUNT_NAME) == 0)
+ const gchar *account_id = tny_account_get_id (TNY_ACCOUNT (folder1));
+ const gchar *account_id2 = tny_account_get_id (TNY_ACCOUNT (folder2));
+
+ if (!strcmp (account_id, MODEST_MMC_ACCOUNT_ID))
cmp = +1;
- else if (name2 && strcmp (name2, MODEST_LOCAL_FOLDERS_ACCOUNT_NAME) == 0)
- cmp = -1;
- else
- cmp = modest_text_utils_utf8_strcmp (name1, name2, TRUE);
+ else {
+ if (!strcmp (account_id, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
+ if (!strcmp (account_id2, MODEST_MMC_ACCOUNT_ID))
+ cmp = -1;
+ else
+ cmp = +1;
+ } else {
+ if (!strcmp (account_id2, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
+ !strcmp (account_id2, MODEST_MMC_ACCOUNT_ID))
+ cmp = -1;
+ else
+ cmp = modest_text_utils_utf8_strcmp (name1, name2, TRUE);
+ }
+ }
} else
cmp = modest_text_utils_utf8_strcmp (name1, name2, TRUE);
-
if (folder1)
g_object_unref(G_OBJECT(folder1));
if (folder2)
g_object_unref(G_OBJECT(folder2));
-
+
g_free (name1);
g_free (name2);
gtk_tree_view_column_queue_resize (tree_column);
#endif
}
+
+void
+modest_folder_view_set_style (ModestFolderView *self,
+ ModestFolderViewStyle style)
+{
+ ModestFolderViewPrivate *priv;
+
+ g_return_if_fail (self);
+
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
+
+ priv->style = style;
+}