static void modest_folder_view_set_account_store (TnyAccountStoreView *self,
TnyAccountStore *account_store);
-static void on_selection_changed (GtkTreeSelection *sel, gpointer data);
+static void on_selection_changed (GtkTreeSelection *sel,
+ gpointer data);
static void on_account_removed (TnyAccountStore *self,
TnyAccount *account,
}
static void
-icon_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
+icon_cell_data (GtkTreeViewColumn *column,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer data)
{
- GObject *rendobj = (GObject *) renderer, *instance = NULL;
+ GObject *rendobj = NULL, *instance = NULL;
TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
gboolean has_children;
ThreePixbufs *pixbufs;
+ rendobj = (GObject *) renderer;
+
gtk_tree_model_get (tree_model, iter,
TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
TnyAccount *tny_account,
gpointer user_data)
{
- /* do nothing */
ModestFolderViewPrivate *priv;
GtkTreeModel *sort_model, *filter_model;
/* Get the inner model */
filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
-
+
/* Remove the account from the model */
tny_list_remove (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
G_OBJECT (tny_account));
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
}
+/**
+ *
+ * Selects the first inbox or the local account in an idle
+ */
+static gboolean
+on_idle_select_first_inbox_or_local (gpointer user_data)
+{
+ ModestFolderView *self = MODEST_FOLDER_VIEW (user_data);
+
+ modest_folder_view_select_first_inbox_or_local (self);
+
+ return FALSE;
+}
static void
ModestFolderViewPrivate *priv;
GtkTreeModel *sort_model, *filter_model;
GtkTreeSelection *sel = NULL;
+ gboolean same_account_selected = FALSE;
/* Ignore transport account removals, we're not showing them
in the folder view */
if (selected_folder_account == account) {
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
gtk_tree_selection_unselect_all (sel);
+ same_account_selected = TRUE;
}
g_object_unref (selected_folder_account);
}
folder_to_select_account = tny_folder_get_account (priv->folder_to_select);
if (folder_to_select_account == account) {
-/* modest_folder_view_disable_next_folder_selection (self); */
+ modest_folder_view_disable_next_folder_selection (self);
g_object_unref (priv->folder_to_select);
priv->folder_to_select = NULL;
}
/* Select the first INBOX if the currently selected folder
belongs to the account that is being deleted */
- if (priv->cur_folder_store) {
- TnyAccount *folder_selected_account;
-
- folder_selected_account = (TNY_IS_FOLDER (priv->cur_folder_store)) ?
- modest_tny_folder_get_account (TNY_FOLDER (priv->cur_folder_store)) :
- TNY_ACCOUNT (g_object_ref (priv->cur_folder_store));
- if (account == folder_selected_account)
- modest_folder_view_select_first_inbox_or_local (self);
- g_object_unref (folder_selected_account);
- }
+ if (same_account_selected)
+ g_idle_add (on_idle_select_first_inbox_or_local, self);
}
void
/* New current references */
priv->cur_folder_store = folder;
- /* New folder has been selected */
- g_signal_emit (G_OBJECT(tree_view),
- signals[FOLDER_SELECTION_CHANGED_SIGNAL],
- 0, priv->cur_folder_store, TRUE);
+ /* New folder has been selected. Do not notify if there is
+ nothing new selected */
+ if (selected) {
+ g_signal_emit (G_OBJECT(tree_view),
+ signals[FOLDER_SELECTION_CHANGED_SIGNAL],
+ 0, priv->cur_folder_store, TRUE);
+ }
}
TnyFolderStore *
guint time;
} DndHelper;
+static void
+dnd_helper_destroyer (DndHelper *helper)
+{
+ /* Free the helper */
+ gtk_tree_path_free (helper->source_row);
+ g_slice_free (DndHelper, helper);
+}
/*
* This function is the callback of the
gtk_drag_finish (helper->context, success, FALSE, helper->time);
/* Free the helper */
- gtk_tree_path_free (helper->source_row);
- g_slice_free (DndHelper, helper);
+ dnd_helper_destroyer (helper);
}
/* get the folder for the row the treepath refers to. */
g_object_unref (headers);
}
+typedef struct {
+ TnyFolderStore *src_folder;
+ TnyFolderStore *dst_folder;
+ DndHelper *helper;
+} DndFolderInfo;
+
+static void
+dnd_folder_info_destroyer (DndFolderInfo *info)
+{
+ if (info->src_folder)
+ g_object_unref (info->src_folder);
+ if (info->dst_folder)
+ g_object_unref (info->dst_folder);
+ g_slice_free (DndFolderInfo, info);
+}
+
+static void
+dnd_on_connection_failed_destroyer (DndFolderInfo *info,
+ GtkWindow *parent_window,
+ TnyAccount *account)
+{
+ time_t dnd_time = info->helper->time;
+ GdkDragContext *context = info->helper->context;
+
+ /* Show error */
+ modest_ui_actions_on_account_connection_error (parent_window, account);
+
+ /* Free the helper & info */
+ dnd_helper_destroyer (info->helper);
+ dnd_folder_info_destroyer (info);
+
+ /* Notify the drag source. Never call delete, the monitor will
+ do the job if needed */
+ gtk_drag_finish (context, FALSE, FALSE, dnd_time);
+ return;
+}
+
+static void
+drag_and_drop_from_folder_view_src_folder_performer (gboolean canceled,
+ GError *err,
+ GtkWindow *parent_window,
+ TnyAccount *account,
+ gpointer user_data)
+{
+ DndFolderInfo *info = NULL;
+ ModestMailOperation *mail_op;
+
+ info = (DndFolderInfo *) user_data;
+
+ if (err || canceled) {
+ dnd_on_connection_failed_destroyer (info, parent_window, account);
+ return;
+ }
+
+ /* Do the mail operation */
+ mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
+ modest_ui_actions_move_folder_error_handler,
+ info->src_folder, NULL);
+
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+ mail_op);
+
+ /* Transfer the folder */
+ modest_mail_operation_xfer_folder (mail_op,
+ TNY_FOLDER (info->src_folder),
+ info->dst_folder,
+ info->helper->delete_source,
+ xfer_cb,
+ info->helper);
+
+ g_object_unref (G_OBJECT (mail_op));
+}
+
+
+static void
+drag_and_drop_from_folder_view_dst_folder_performer (gboolean canceled,
+ GError *err,
+ GtkWindow *parent_window,
+ TnyAccount *account,
+ gpointer user_data)
+{
+ DndFolderInfo *info = NULL;
+
+ info = (DndFolderInfo *) user_data;
+
+ if (err || canceled) {
+ dnd_on_connection_failed_destroyer (info, parent_window, account);
+ return;
+ }
+
+ /* Connect to source folder and perform the copy/move */
+ modest_platform_connect_and_perform_if_network_folderstore (NULL,
+ info->src_folder,
+ drag_and_drop_from_folder_view_src_folder_performer,
+ info);
+}
+
/*
* This function is used by drag_data_received_cb to manage drag and
* drop of a folder, i.e, and drag from the folder view to the same
GtkSelectionData *selection_data,
DndHelper *helper)
{
- ModestMailOperation *mail_op = NULL;
GtkTreeIter dest_iter, iter;
TnyFolderStore *dest_folder = NULL;
TnyFolderStore *folder = NULL;
gboolean forbidden = FALSE;
ModestWindow *win;
+ DndFolderInfo *info = NULL;
win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE); /* don't create */
if (!win) {
TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
&folder, -1);
- /* Offer the connection dialog if necessary, for the destination parent folder and source folder: */
- if (modest_platform_connect_and_wait_if_network_folderstore (NULL, dest_folder) &&
- modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (folder))) {
-
- /* Do the mail operation */
- mail_op = modest_mail_operation_new_with_error_handling ((GObject *) win,
- modest_ui_actions_move_folder_error_handler,
- folder, NULL);
-
- modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
- mail_op);
-
- modest_mail_operation_xfer_folder (mail_op,
- TNY_FOLDER (folder),
- dest_folder,
- helper->delete_source,
- xfer_cb,
- helper);
-
- g_object_unref (G_OBJECT (mail_op));
- }
+ /* Create the info for the performer */
+ info = g_slice_new (DndFolderInfo);
+ info->src_folder = g_object_ref (folder);
+ info->dst_folder = g_object_ref (dest_folder);
+ info->helper = helper;
+
+ /* Connect to the destination folder and perform the copy/move */
+ modest_platform_connect_and_perform_if_network_folderstore (GTK_WINDOW (win),
+ dest_folder,
+ drag_and_drop_from_folder_view_dst_folder_performer,
+ info);
/* Frees */
- g_object_unref (G_OBJECT (dest_folder));
- g_object_unref (G_OBJECT (folder));
+ g_object_unref (dest_folder);
+ g_object_unref (folder);
}
/*
GtkTreeViewDropPosition pos;
gboolean result = FALSE;
- GDK_THREADS_ENTER ();
+ gdk_threads_enter ();
gtk_tree_view_get_drag_dest_row (tree_view,
&dest_path,
result = TRUE;
}
- GDK_THREADS_LEAVE ();
+ gdk_threads_leave ();
return result;
}
goto out;
}
}
- g_object_unref (folder);
/* Expand the selected row after 1/2 second */
if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (widget), dest_row)) {
gdk_drag_status(context, GDK_ACTION_DEFAULT, time);
out:
+ if (folder)
+ g_object_unref (folder);
if (dest_row)
gtk_tree_path_free (dest_row);
g_signal_stop_emission_by_name (widget, "drag-motion");