#include <tny-camel-folder.h>
#include <tny-simple-list.h>
#include <tny-camel-account.h>
+#include <modest-defs.h>
#include <modest-tny-account.h>
#include <modest-tny-folder.h>
#include <modest-tny-local-folders-account.h>
FOLDER_SELECTION_CHANGED_SIGNAL,
FOLDER_DISPLAY_NAME_CHANGED_SIGNAL,
FOLDER_ACTIVATED_SIGNAL,
+ VISIBLE_ACCOUNT_CHANGED_SIGNAL,
LAST_SIGNAL
};
gboolean reselect; /* we use this to force a reselection of the INBOX */
gboolean show_non_move;
+ TnyList *list_to_move;
gboolean reexpand; /* next time we expose, we'll expand all root folders */
GtkCellRenderer *messages_renderer;
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
+ /*
+ * Emitted whenever the visible account changes
+ */
+ signals[VISIBLE_ACCOUNT_CHANGED_SIGNAL] =
+ g_signal_new ("visible-account-changed",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (ModestFolderViewClass,
+ visible_account_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
treeview_class->select_cursor_parent = NULL;
#ifdef MODEST_TOOLKIT_HILDON2
priv->filter = MODEST_FOLDER_VIEW_FILTER_NONE;
priv->reselect = FALSE;
priv->show_non_move = TRUE;
+ priv->list_to_move = NULL;
/* Build treeview */
add_columns (GTK_WIDGET (obj));
priv->cur_folder_store = NULL;
}
+ if (priv->list_to_move) {
+ g_object_unref (priv->list_to_move);
+ priv->list_to_move = NULL;
+ }
+
/* Clear hidding array created by cut operation */
_clear_hidding_filter (MODEST_FOLDER_VIEW (obj));
gtk_tree_path_free (path);
}
+static gboolean
+is_parent_of (TnyFolder *a, TnyFolder *b)
+{
+ const gchar *a_id;
+ gboolean retval = FALSE;
+
+ a_id = tny_folder_get_id (a);
+ if (a_id) {
+ gchar *string_to_match;
+ const gchar *b_id;
+
+ string_to_match = g_strconcat (a_id, "/", NULL);
+ b_id = tny_folder_get_id (b);
+ retval = g_str_has_prefix (b_id, string_to_match);
+ g_free (string_to_match);
+ }
+
+ return retval;
+}
+
+typedef struct _ForeachFolderInfo {
+ gchar *needle;
+ gboolean found;
+} ForeachFolderInfo;
+
+static gboolean
+foreach_folder_with_id (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ ForeachFolderInfo *info;
+ GObject *instance;
+
+ info = (ForeachFolderInfo *) data;
+ gtk_tree_model_get (model, iter,
+ INSTANCE_COLUMN, &instance,
+ -1);
+
+ if (TNY_IS_FOLDER (instance)) {
+ const gchar *id;
+ gchar *collate;
+ id = tny_folder_get_id (TNY_FOLDER (instance));
+ if (id) {
+ collate = g_utf8_collate_key (id, -1);
+ info->found = !strcmp (info->needle, collate);
+ g_free (collate);
+ }
+ }
+
+ return info->found;
+
+}
+
+
+static gboolean
+has_folder_with_id (ModestFolderView *self, const gchar *id)
+{
+ GtkTreeModel *model;
+ ForeachFolderInfo info = {NULL, FALSE};
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+ info.needle = g_utf8_collate_key (id, -1);
+
+ gtk_tree_model_foreach (model, foreach_folder_with_id, &info);
+ g_free (info.needle);
+
+ return info.found;
+}
+
+static gboolean
+has_child_with_name_of (ModestFolderView *self, TnyFolder *a, TnyFolder *b)
+{
+ const gchar *a_id;
+ gboolean retval = FALSE;
+
+ a_id = tny_folder_get_id (a);
+ if (a_id) {
+ const gchar *b_id;
+ b_id = tny_folder_get_id (b);
+
+ if (b_id) {
+ const gchar *last_bar;
+ gchar *string_to_match;
+ last_bar = g_strrstr (b_id, "/");
+ if (last_bar)
+ last_bar++;
+ else
+ last_bar = b_id;
+ string_to_match = g_strconcat (a_id, "/", last_bar, NULL);
+ retval = has_folder_with_id (self, string_to_match);
+ g_free (string_to_match);
+ }
+ }
+
+ return retval;
+}
+
+static gboolean
+check_move_to_this_folder_valid (ModestFolderView *self, TnyFolder *folder)
+{
+ ModestFolderViewPrivate *priv;
+ TnyIterator *iterator;
+ gboolean retval = TRUE;
+
+ g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (self), FALSE);
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+ for (iterator = tny_list_create_iterator (priv->list_to_move);
+ retval && !tny_iterator_is_done (iterator);
+ tny_iterator_next (iterator)) {
+ GObject *instance;
+ instance = tny_iterator_get_current (iterator);
+ if (instance == (GObject *) folder) {
+ retval = FALSE;
+ } else if (TNY_IS_FOLDER (instance)) {
+ retval = !is_parent_of (TNY_FOLDER (instance), folder);
+ if (retval) {
+ retval = !has_child_with_name_of (self, folder, TNY_FOLDER (instance));
+ }
+ }
+ g_object_unref (instance);
+ }
+ g_object_unref (iterator);
+
+ return retval;
+}
+
+
/*
* We use this function to implement the
* MODEST_FOLDER_VIEW_STYLE_SHOW_ONE style. We only show the default
/* If this is a move to dialog, hide Sent, Outbox and Drafts
folder as no message can be move there according to UI specs */
- if (!priv->show_non_move) {
- if (TNY_IS_FOLDER (instance) &&
+ if (retval && !priv->show_non_move) {
+ if (priv->list_to_move &&
+ tny_list_get_length (priv->list_to_move) > 0 &&
+ TNY_IS_FOLDER (instance)) {
+ retval = check_move_to_this_folder_valid (MODEST_FOLDER_VIEW (data), TNY_FOLDER (instance));
+ }
+ if (retval && TNY_IS_FOLDER (instance) &&
modest_tny_folder_is_local_folder (TNY_FOLDER (instance))) {
switch (type) {
case TNY_FOLDER_TYPE_OUTBOX:
return FALSE;
}
+ if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_HIDE_FOLDERS)) {
+ if (TNY_IS_FOLDER (instance))
+ return FALSE;
+ }
+
+ if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_HIDE_LOCAL_FOLDERS)) {
+ if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (instance))) {
+ return FALSE;
+ }
+ }
+
if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_CAN_HAVE_FOLDERS)) {
if (TNY_IS_FOLDER (instance)) {
/* Check folder rules */
/* Save settings to gconf */
modest_widget_memory_save (modest_runtime_get_conf (), G_OBJECT(self),
MODEST_CONF_FOLDER_VIEW_KEY);
+
+ /* Notify observers */
+ g_signal_emit (G_OBJECT(self),
+ signals[VISIBLE_ACCOUNT_CHANGED_SIGNAL], 0,
+ account_id);
}
const gchar *
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
}
}
+
+gboolean
+modest_folder_view_any_folder_fulfils_rules (ModestFolderView *self,
+ ModestTnyFolderRules rules)
+{
+ GtkTreeModel *filter_model;
+ GtkTreeIter iter;
+ gboolean fulfil = FALSE;
+
+ if (!get_inner_models (self, &filter_model, NULL, NULL))
+ return FALSE;
+
+ if (!gtk_tree_model_get_iter_first (filter_model, &iter))
+ return FALSE;
+
+ do {
+ TnyFolderStore *folder;
+
+ gtk_tree_model_get (filter_model, &iter, INSTANCE_COLUMN, &folder, -1);
+ if (folder) {
+ if (TNY_IS_FOLDER (folder)) {
+ ModestTnyFolderRules folder_rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
+ /* Folder rules are negative: non_writable, non_deletable... */
+ if (!(folder_rules & rules))
+ fulfil = TRUE;
+ }
+ g_object_unref (folder);
+ }
+
+ } while (gtk_tree_model_iter_next (filter_model, &iter) && !fulfil);
+
+ return fulfil;
+}
+
+void
+modest_folder_view_set_list_to_move (ModestFolderView *self,
+ TnyList *list)
+{
+ ModestFolderViewPrivate *priv;
+
+ g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+ if (priv->list_to_move)
+ g_object_unref (priv->list_to_move);
+
+ if (list)
+ g_object_ref (list);
+
+ priv->list_to_move = list;
+}