aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2012-06-28 01:09:51 +0800
committerMilan Crha <mcrha@redhat.com>2012-06-28 01:10:45 +0800
commit9cdae1a4cc9b5c0879c61eeee351036540fc473c (patch)
tree345e4b6e1f5081d9a8115e9b799ec26799601a5b
parent0da915da8d8a1d2d584fe905bb4673c25db14fb9 (diff)
downloadgsoc2013-evolution-9cdae1a4cc9b5c0879c61eeee351036540fc473c.tar.gz
gsoc2013-evolution-9cdae1a4cc9b5c0879c61eeee351036540fc473c.tar.zst
gsoc2013-evolution-9cdae1a4cc9b5c0879c61eeee351036540fc473c.zip
Bug #257283 - Can't select multiple folders at once in vFolder sources
-rw-r--r--mail/em-vfolder-editor-rule.c170
-rw-r--r--mail/mail-dialogs.ui2
2 files changed, 112 insertions, 60 deletions
diff --git a/mail/em-vfolder-editor-rule.c b/mail/em-vfolder-editor-rule.c
index a108e2bc43..dad5059228 100644
--- a/mail/em-vfolder-editor-rule.c
+++ b/mail/em-vfolder-editor-rule.c
@@ -210,7 +210,6 @@ enum {
struct _source_data {
ERuleContext *rc;
EMVFolderRule *vr;
- const gchar *current;
GtkListStore *model;
GtkTreeView *list;
GtkWidget *source_selector;
@@ -231,28 +230,21 @@ static struct {
static void
set_sensitive (struct _source_data *data)
{
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (data->list);
+
gtk_widget_set_sensitive (
GTK_WIDGET (data->buttons[BUTTON_ADD]), TRUE);
gtk_widget_set_sensitive (
GTK_WIDGET (data->buttons[BUTTON_REMOVE]),
- data->current != NULL);
+ selection && gtk_tree_selection_count_selected_rows (selection) > 0);
}
static void
-select_source (GtkWidget *list,
- struct _source_data *data)
+selection_changed_cb (GtkTreeSelection *selection,
+ struct _source_data *data)
{
- GtkTreeViewColumn *column;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- gtk_tree_view_get_cursor (data->list, &path, &column);
- if (path && gtk_tree_model_get_iter (GTK_TREE_MODEL (data->model), &iter, path))
- gtk_tree_model_get (GTK_TREE_MODEL (data->model), &iter, 0, &data->current, -1);
- else
- data->current = NULL;
- gtk_tree_path_free (path);
-
set_sensitive (data);
}
@@ -288,36 +280,67 @@ vfr_folder_response (EMFolderSelector *selector,
struct _source_data *data)
{
EMFolderTreeModel *model;
- EMailSession *session;
- const gchar *uri;
+ EMFolderTree *folder_tree;
+ CamelSession *session;
+ GList *selected_uris;
+ folder_tree = em_folder_selector_get_folder_tree (selector);
model = em_folder_selector_get_model (selector);
- session = em_folder_tree_model_get_session (model);
+ session = CAMEL_SESSION (em_folder_tree_model_get_session (model));
- uri = em_folder_selector_get_selected_uri (selector);
+ selected_uris = em_folder_tree_get_selected_uris (folder_tree);
- if (button == GTK_RESPONSE_OK && uri != NULL) {
- GtkTreeSelection *selection;
+ if (button == GTK_RESPONSE_OK && selected_uris != NULL) {
+ GList *uris_iter;
+ GHashTable *known_uris;
GtkTreeIter iter;
- gchar *markup;
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (data->list);
+ gtk_tree_selection_unselect_all (selection);
- g_queue_push_tail (&data->vr->sources, g_strdup (uri));
+ known_uris = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- markup = e_mail_folder_uri_to_markup (
- CAMEL_SESSION (session), uri, NULL);
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (data->model), &iter)) {
+ GtkTreeModel *model = GTK_TREE_MODEL (data->model);
+ do {
+ gchar *known = NULL;
- gtk_list_store_append (data->model, &iter);
- gtk_list_store_set (data->model, &iter, 0, markup, 1, uri, -1);
- selection = gtk_tree_view_get_selection (data->list);
- gtk_tree_selection_select_iter (selection, &iter);
- data->current = uri;
+ gtk_tree_model_get (model, &iter, 1, &known, -1);
- g_free (markup);
+ if (known)
+ g_hash_table_insert (known_uris, known, GINT_TO_POINTER (1));
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+
+ for (uris_iter = selected_uris; uris_iter != NULL; uris_iter = uris_iter->next) {
+ const gchar *uri = uris_iter->data;
+ gchar *markup;
+
+ if (!uri || g_hash_table_lookup (known_uris, uri))
+ continue;
+
+ g_hash_table_insert (known_uris, g_strdup (uri), GINT_TO_POINTER (1));
+
+ g_queue_push_tail (&data->vr->sources, g_strdup (uri));
+
+ markup = e_mail_folder_uri_to_markup (session, uri, NULL);
+
+ gtk_list_store_append (data->model, &iter);
+ gtk_list_store_set (data->model, &iter, 0, markup, 1, uri, -1);
+ g_free (markup);
+
+ /* select all newly added folders */
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+
+ g_hash_table_destroy (known_uris);
set_sensitive (data);
}
gtk_widget_destroy (GTK_WIDGET (selector));
+ g_list_free_full (selected_uris, g_free);
}
static void
@@ -326,6 +349,7 @@ source_add (GtkWidget *widget,
{
EMFolderTree *folder_tree;
EMFolderTreeModel *model;
+ GtkTreeSelection *selection;
GtkWidget *dialog;
gpointer parent;
@@ -344,6 +368,9 @@ source_add (GtkWidget *widget,
em_folder_tree_set_excluded (folder_tree, EMFT_EXCLUDE_NOSELECT);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+
g_signal_connect (
dialog, "response",
G_CALLBACK (vfr_folder_response), data);
@@ -356,13 +383,15 @@ source_remove (GtkWidget *widget,
struct _source_data *data)
{
GtkTreeSelection *selection;
- const gchar *source;
+ const gchar *source, *prev_source;
GtkTreePath *path;
GtkTreeIter iter;
- gint index = 0;
+ GHashTable *to_remove;
+ gint index = 0, first_selected = -1, removed;
gint n;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->list));
+ to_remove = g_hash_table_new (g_direct_hash, g_direct_equal);
source = NULL;
while ((source = em_vfolder_rule_next_source (data->vr, source))) {
@@ -370,6 +399,28 @@ source_remove (GtkWidget *widget,
gtk_tree_path_append_index (path, index);
if (gtk_tree_selection_path_is_selected (selection, path)) {
+ g_hash_table_insert (to_remove, GINT_TO_POINTER (index), GINT_TO_POINTER (1));
+
+ if (first_selected == -1)
+ first_selected = index;
+ }
+
+ index++;
+
+ gtk_tree_path_free (path);
+ }
+
+ /* do not depend on selection when removing */
+ gtk_tree_selection_unselect_all (selection);
+
+ index = 0;
+ source = NULL;
+ removed = 0;
+ prev_source = NULL;
+ while ((source = em_vfolder_rule_next_source (data->vr, source))) {
+ if (g_hash_table_lookup (to_remove, GINT_TO_POINTER (index + removed))) {
+ path = gtk_tree_path_new ();
+ gtk_tree_path_append_index (path, index);
gtk_tree_model_get_iter (
GTK_TREE_MODEL (data->model), &iter, path);
@@ -377,32 +428,29 @@ source_remove (GtkWidget *widget,
gtk_list_store_remove (data->model, &iter);
gtk_tree_path_free (path);
- /* now select the next rule */
- n = gtk_tree_model_iter_n_children (
- GTK_TREE_MODEL (data->model), NULL);
- index = index >= n ? n - 1 : index;
-
- if (index >= 0) {
- path = gtk_tree_path_new ();
- gtk_tree_path_append_index (path, index);
- gtk_tree_model_get_iter (
- GTK_TREE_MODEL (data->model),
- &iter, path);
- gtk_tree_path_free (path);
-
- gtk_tree_selection_select_iter (
- selection, &iter);
- gtk_tree_model_get (
- GTK_TREE_MODEL (data->model), &iter,
- 0, &data->current, -1);
- } else {
- data->current = NULL;
- }
-
- break;
+ /* try again from the previous source */
+ removed++;
+ source = prev_source;
+ } else {
+ index++;
+ prev_source = source;
}
+ }
- index++;
+ g_hash_table_destroy (to_remove);
+
+ /* now select the next rule */
+ n = gtk_tree_model_iter_n_children (
+ GTK_TREE_MODEL (data->model), NULL);
+ index = first_selected >= n ? n - 1 : first_selected;
+
+ if (index >= 0) {
+ path = gtk_tree_path_new ();
+ gtk_tree_path_append_index (path, index);
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (data->model), &iter, path)) {
+ gtk_tree_selection_select_iter (selection, &iter);
+ gtk_tree_view_set_cursor (data->list, path, NULL, FALSE);
+ }
gtk_tree_path_free (path);
}
@@ -420,6 +468,7 @@ get_widget (EFilterRule *fr,
GtkRadioButton *rb;
const gchar *source;
GtkTreeIter iter;
+ GtkTreeSelection *selection;
GtkBuilder *builder;
GObject *object;
gint i;
@@ -465,9 +514,12 @@ get_widget (EFilterRule *fr,
g_free (markup);
}
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->list));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+
g_signal_connect (
- data->list, "cursor-changed",
- G_CALLBACK (select_source), data);
+ selection, "changed",
+ G_CALLBACK (selection_changed_cb), data);
rb = (GtkRadioButton *)e_builder_get_widget (builder, "local_rb");
g_signal_connect (
diff --git a/mail/mail-dialogs.ui b/mail/mail-dialogs.ui
index 71ee06c192..147490690b 100644
--- a/mail/mail-dialogs.ui
+++ b/mail/mail-dialogs.ui
@@ -417,7 +417,7 @@ Please select a follow up action from the "Flag" menu.</property>
<!-- column-name Translated -->
<column type="gchararray"/>
<!-- column-name Raw -->
- <column type="gpointer"/>
+ <column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="license_dialog">