diff options
author | Milan Crha <mcrha@redhat.com> | 2012-07-11 22:38:27 +0800 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2012-07-11 22:38:27 +0800 |
commit | 0c881254de455c77032b24d419bdabe7a4b5adfd (patch) | |
tree | d1e3782305097e07752de2061d86a4e43e4631e5 | |
parent | 1852490a930c625a5fb300069694d661e3eeed02 (diff) | |
download | gsoc2013-evolution-0c881254de455c77032b24d419bdabe7a4b5adfd.tar.gz gsoc2013-evolution-0c881254de455c77032b24d419bdabe7a4b5adfd.tar.zst gsoc2013-evolution-0c881254de455c77032b24d419bdabe7a4b5adfd.zip |
Bug #223309 - Add "Include Subfolders" to "Search Folder Sources"
-rw-r--r-- | libemail-engine/mail-vfolder.c | 245 | ||||
-rw-r--r-- | libemail-utils/em-vfolder-rule.c | 93 | ||||
-rw-r--r-- | libemail-utils/em-vfolder-rule.h | 12 | ||||
-rw-r--r-- | mail/em-vfolder-editor-rule.c | 76 | ||||
-rw-r--r-- | mail/mail-vfolder-ui.c | 13 |
5 files changed, 340 insertions, 99 deletions
diff --git a/libemail-engine/mail-vfolder.c b/libemail-engine/mail-vfolder.c index 08e6e22fe5..233e6a0f02 100644 --- a/libemail-engine/mail-vfolder.c +++ b/libemail-engine/mail-vfolder.c @@ -60,6 +60,59 @@ static void rule_changed (EFilterRule *rule, CamelFolder *folder); /* ********************************************************************** */ +static GList * +vfolder_get_include_subfolders_uris (EMailSession *session, + const gchar *base_uri, + GCancellable *cancellable) +{ + GList *uris = NULL; + CamelStore *store = NULL; + gchar *folder_name = NULL; + CamelFolderInfo *fi; + const CamelFolderInfo *cur; + + g_return_val_if_fail (session != NULL, NULL); + g_return_val_if_fail (base_uri != NULL, NULL); + g_return_val_if_fail (*base_uri == '*', NULL); + + if (!e_mail_folder_uri_parse (CAMEL_SESSION (session), base_uri + 1, &store, &folder_name, NULL)) + return NULL; + + fi = camel_store_get_folder_info_sync (store, folder_name, + CAMEL_STORE_FOLDER_INFO_RECURSIVE, cancellable, NULL); + cur = fi; + while (cur) { + if ((cur->flags & CAMEL_FOLDER_NOSELECT) == 0) { + gchar *fi_uri = e_mail_folder_uri_build (store, cur->full_name); + + if (fi_uri) + uris = g_list_prepend (uris, fi_uri); + } + + /* move to the next fi */ + if (cur->child) { + cur = cur->child; + } else if (cur->next) { + cur = cur->next; + } else { + while (cur && !cur->next) { + cur = cur->parent; + } + + if (cur) + cur = cur->next; + } + } + + if (fi) + camel_store_free_folder_info (store, fi); + + g_object_unref (store); + g_free (folder_name); + + return g_list_reverse (uris); +} + struct _setup_msg { MailMsg base; @@ -67,7 +120,6 @@ struct _setup_msg { CamelFolder *folder; gchar *query; GList *sources_uri; - GList *sources_folder; }; static gchar * @@ -88,34 +140,42 @@ vfolder_setup_exec (struct _setup_msg *m, camel_vee_folder_set_expression ((CamelVeeFolder *) m->folder, m->query); - l = m->sources_uri; - while (l && !vfolder_shutdown) { - d(printf(" Adding uri: %s\n", (gchar *)l->data)); + for (l = m->sources_uri; + l && !vfolder_shutdown && !g_cancellable_is_cancelled (cancellable); + l = l->next) { + const gchar *uri = l->data; - /* FIXME Not passing a GCancellable or GError here. */ - folder = e_mail_session_uri_to_folder_sync ( - m->session, l->data, 0, NULL, NULL); - if (folder != NULL) - list = g_list_append (list, folder); - l = l->next; - } + d(printf(" Adding uri: %s\n", uri)); - l = m->sources_folder; - while (l && !vfolder_shutdown) { - g_object_ref (l->data); - list = g_list_append (list, l->data); - l = l->next; + if (!uri || !*uri || !uri[1]) + continue; + + if (*uri == '*') { + /* include folder and its subfolders */ + GList *uris, *iter; + + uris = vfolder_get_include_subfolders_uris (m->session, uri, cancellable); + for (iter = uris; iter; iter = iter->next) { + const gchar *fi_uri = iter->data; + + folder = e_mail_session_uri_to_folder_sync ( + m->session, fi_uri, 0, cancellable, NULL); + if (folder != NULL) + list = g_list_append (list, folder); + } + + g_list_free_full (uris, g_free); + } else { + folder = e_mail_session_uri_to_folder_sync (m->session, l->data, 0, cancellable, NULL); + if (folder != NULL) + list = g_list_append (list, folder); + } } - if (!vfolder_shutdown) + if (!vfolder_shutdown && !g_cancellable_is_cancelled (cancellable)) camel_vee_folder_set_folders ((CamelVeeFolder *) m->folder, list, cancellable); - l = list; - while (l) { - g_object_unref (l->data); - l = l->next; - } - g_list_free (list); + g_list_free_full (list, g_object_unref); } static void @@ -126,27 +186,12 @@ vfolder_setup_done (struct _setup_msg *m) static void vfolder_setup_free (struct _setup_msg *m) { - GList *l; - camel_folder_thaw (m->folder); g_object_unref (m->session); g_object_unref (m->folder); g_free (m->query); - - l = m->sources_uri; - while (l) { - g_free (l->data); - l = l->next; - } - g_list_free (m->sources_uri); - - l = m->sources_folder; - while (l) { - g_object_unref (l->data); - l = l->next; - } - g_list_free (m->sources_folder); + g_list_free_full (m->sources_uri, g_free); } static MailMsgInfo vfolder_setup_info = { @@ -162,8 +207,7 @@ static gint vfolder_setup (EMailSession *session, CamelFolder *folder, const gchar *query, - GList *sources_uri, - GList *sources_folder) + GList *sources_uri) { struct _setup_msg *m; gint id; @@ -173,7 +217,6 @@ vfolder_setup (EMailSession *session, m->folder = g_object_ref (folder); m->query = g_strdup (query); m->sources_uri = sources_uri; - m->sources_folder = sources_folder; camel_folder_freeze (m->folder); @@ -185,6 +228,27 @@ vfolder_setup (EMailSession *session, /* ********************************************************************** */ +static void +vfolder_add_remove_one (GList *vfolders, + gboolean remove, + CamelFolder *folder, + GCancellable *cancellable) +{ + GList *iter; + + for (iter = vfolders; iter && !vfolder_shutdown; iter = iter->next) { + CamelVeeFolder *vfolder = CAMEL_VEE_FOLDER (iter->data); + + if (!vfolder) + continue; + + if (remove) + camel_vee_folder_remove_folder (vfolder, folder, cancellable); + else + camel_vee_folder_add_folder (vfolder, folder, cancellable); + } +} + struct _adduri_msg { MailMsg base; @@ -229,7 +293,6 @@ vfolder_adduri_exec (struct _adduri_msg *m, GCancellable *cancellable, GError **error) { - GList *l; CamelFolder *folder = NULL; MailFolderCache *folder_cache; @@ -241,29 +304,39 @@ vfolder_adduri_exec (struct _adduri_msg *m, /* we dont try lookup the cache if we are removing it, its no longer there */ if (!m->remove && - !mail_folder_cache_get_folder_from_uri (folder_cache, m->uri, NULL)) { + !mail_folder_cache_get_folder_from_uri (folder_cache, m->uri[0] == '*' ? m->uri + 1 : m->uri, NULL)) { g_warning ( "Folder '%s' disappeared while I was " "adding/removing it to/from my vfolder", m->uri); return; } - /* always pick fresh folders - they are - * from CamelStore's folders bag anyway */ - folder = e_mail_session_uri_to_folder_sync ( - m->session, m->uri, 0, cancellable, error); - - if (folder != NULL) { - l = m->folders; - while (l && !vfolder_shutdown) { - if (m->remove) - camel_vee_folder_remove_folder ( - CAMEL_VEE_FOLDER (l->data), folder, cancellable); - else - camel_vee_folder_add_folder ((CamelVeeFolder *) l->data, folder, cancellable); - l = l->next; + if (m->uri[0] == '*') { + GList *uris, *iter; + + uris = vfolder_get_include_subfolders_uris (m->session, m->uri, cancellable); + for (iter = uris; iter; iter = iter->next) { + const gchar *fi_uri = iter->data; + + folder = e_mail_session_uri_to_folder_sync ( + m->session, fi_uri, 0, cancellable, NULL); + if (folder != NULL) { + vfolder_add_remove_one (m->folders, m->remove, folder, cancellable); + g_object_unref (folder); + } + } + + g_list_free_full (uris, g_free); + } else { + /* always pick fresh folders - they are + * from CamelStore's folders bag anyway */ + folder = e_mail_session_uri_to_folder_sync ( + m->session, m->uri, 0, cancellable, error); + + if (folder != NULL) { + vfolder_add_remove_one (m->folders, m->remove, folder, cancellable); + g_object_unref (folder); } - g_object_unref (folder); } } @@ -359,10 +432,11 @@ mail_vfolder_add_folder (CamelStore *store, CamelService *service; CamelSession *session; EFilterRule *rule; + EMVFolderRule *vrule; const gchar *source; CamelVeeFolder *vf; CamelProvider *provider; - GList *folders = NULL; + GList *folders = NULL, *folders_include_subfolders = NULL; gint remote; gchar *uri; @@ -395,18 +469,20 @@ mail_vfolder_add_folder (CamelStore *store, d(printf("invalid rule (%p): rule->name is set to NULL\n", rule)); continue; } + + vrule = (EMVFolderRule *) rule; + /* Don't auto-add any sent/drafts folders etc, * they must be explictly listed as a source. */ if (rule->source && !CAMEL_IS_VEE_STORE (store) - && ((em_vfolder_rule_get_with ((EMVFolderRule *) rule) == EM_VFOLDER_RULE_WITH_LOCAL && !remote) - || (em_vfolder_rule_get_with ((EMVFolderRule *) rule) == EM_VFOLDER_RULE_WITH_REMOTE_ACTIVE && remote) - || (em_vfolder_rule_get_with ((EMVFolderRule *) rule) == EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE))) + && ((em_vfolder_rule_get_with (vrule) == EM_VFOLDER_RULE_WITH_LOCAL && !remote) + || (em_vfolder_rule_get_with (vrule) == EM_VFOLDER_RULE_WITH_REMOTE_ACTIVE && remote) + || (em_vfolder_rule_get_with (vrule) == EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE))) found = TRUE; source = NULL; - while (!found && (source = em_vfolder_rule_next_source ( - (EMVFolderRule *) rule, source))) { + while (!found && (source = em_vfolder_rule_next_source (vrule, source))) { found = e_mail_folder_uri_equal (session, uri, source); } @@ -417,7 +493,11 @@ mail_vfolder_add_folder (CamelStore *store, continue; } g_object_ref (vf); - folders = g_list_prepend (folders, vf); + + if (em_vfolder_rule_source_get_include_subfolders (vrule, uri)) + folders_include_subfolders = g_list_prepend (folders_include_subfolders, vf); + else + folders = g_list_prepend (folders, vf); } } @@ -429,6 +509,16 @@ done: E_MAIL_SESSION (session), uri, folders, remove); + if (folders_include_subfolders) { + gchar *exuri = g_strconcat ("*", uri, NULL); + + vfolder_adduri ( + E_MAIL_SESSION (session), + exuri, folders_include_subfolders, remove); + + g_free (exuri); + } + g_free (uri); } @@ -671,10 +761,9 @@ static void context_rule_added (ERuleContext *ctx, EFilterRule *rule, EMailSessi static void rule_add_sources (EMailSession *session, GQueue *queue, - GList **sources_folderp, - GList **sources_urip) + GList **sources_urip, + EMVFolderRule *rule) { - GList *sources_folder = *sources_folderp; GList *sources_uri = *sources_urip; MailFolderCache *folder_cache; GList *head, *link; @@ -688,11 +777,14 @@ rule_add_sources (EMailSession *session, /* always pick fresh folders - they are * from CamelStore's folders bag anyway */ if (mail_folder_cache_get_folder_from_uri (folder_cache, uri, NULL)) { - sources_uri = g_list_append (sources_uri, g_strdup (uri)); + /* "tag" uris with subfolders with a star prefix */ + if (!rule || !em_vfolder_rule_source_get_include_subfolders (rule, uri)) + sources_uri = g_list_prepend (sources_uri, g_strdup (uri)); + else + sources_uri = g_list_prepend (sources_uri, g_strconcat ("*", uri, NULL)); } } - *sources_folderp = sources_folder; *sources_urip = sources_uri; } @@ -713,7 +805,6 @@ rule_changed (EFilterRule *rule, EMailSession *session; CamelService *service; GList *sources_uri = NULL; - GList *sources_folder = NULL; GString *query; const gchar *full_name; @@ -764,7 +855,7 @@ rule_changed (EFilterRule *rule, /* find any (currently available) folders, and add them to the ones to open */ rule_add_sources ( session, em_vfolder_rule_get_sources ((EMVFolderRule *) rule), - &sources_folder, &sources_uri); + &sources_uri, (EMVFolderRule *) rule); } G_LOCK (vfolder); @@ -778,8 +869,7 @@ rule_changed (EFilterRule *rule, cache = e_mail_session_get_folder_cache (session); mail_folder_cache_get_local_folder_uris (cache, &queue); - rule_add_sources ( - session, &queue, &sources_folder, &sources_uri); + rule_add_sources (session, &queue, &sources_uri, NULL); while (!g_queue_is_empty (&queue)) g_free (g_queue_pop_head (&queue)); @@ -794,8 +884,7 @@ rule_changed (EFilterRule *rule, cache = e_mail_session_get_folder_cache (session); mail_folder_cache_get_remote_folder_uris (cache, &queue); - rule_add_sources ( - session, &queue, &sources_folder, &sources_uri); + rule_add_sources (session, &queue, &sources_uri, NULL); while (!g_queue_is_empty (&queue)) g_free (g_queue_pop_head (&queue)); @@ -806,7 +895,7 @@ rule_changed (EFilterRule *rule, query = g_string_new(""); e_filter_rule_build_code (rule, query); - vfolder_setup (session, folder, query->str, sources_uri, sources_folder); + vfolder_setup (session, folder, query->str, sources_uri); g_string_free (query, TRUE); } diff --git a/libemail-utils/em-vfolder-rule.c b/libemail-utils/em-vfolder-rule.c index 237c99d5ca..ac77e75ce5 100644 --- a/libemail-utils/em-vfolder-rule.c +++ b/libemail-utils/em-vfolder-rule.c @@ -49,6 +49,7 @@ struct _EMVFolderRulePrivate { em_vfolder_rule_with_t with; GQueue sources; /* uri's of the source folders */ gboolean autoupdate; + GHashTable *include_subfolders; }; static gint validate (EFilterRule *, EAlert **alert); @@ -80,6 +81,8 @@ vfolder_rule_finalize (GObject *object) while ((uri = g_queue_pop_head (&rule->priv->sources)) != NULL) g_free (uri); + g_hash_table_destroy (rule->priv->include_subfolders); + /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (em_vfolder_rule_parent_class)->finalize (object); } @@ -110,11 +113,15 @@ em_vfolder_rule_init (EMVFolderRule *rule) rule->priv = EM_VFOLDER_RULE_GET_PRIVATE (rule); rule->priv->with = EM_VFOLDER_RULE_WITH_SPECIFIC; rule->priv->autoupdate = TRUE; + /* it's using pointers from priv::sources, and those + included has include_subfolders set to true */ + rule->priv->include_subfolders = g_hash_table_new (g_direct_hash, g_direct_equal); + rule->rule.source = g_strdup ("incoming"); } EFilterRule * -em_vfolder_rule_new () +em_vfolder_rule_new (void) { return g_object_new ( EM_TYPE_VFOLDER_RULE, NULL); @@ -159,6 +166,7 @@ em_vfolder_rule_remove_source (EMVFolderRule *rule, found =(gchar *) em_vfolder_rule_find_source (rule, uri); if (found != NULL) { g_queue_remove (&rule->priv->sources, found); + g_hash_table_remove (rule->priv->include_subfolders, found); g_free (found); e_filter_rule_emit_changed (E_FILTER_RULE (rule)); } @@ -183,6 +191,64 @@ em_vfolder_rule_next_source (EMVFolderRule *rule, return (link != NULL) ? link->data : NULL; } +GQueue * +em_vfolder_rule_get_sources (EMVFolderRule *rule) +{ + g_return_val_if_fail (rule != NULL, NULL); + + return &rule->priv->sources; +} + +static gboolean +check_queue_has_key (gpointer key, + gpointer value, + gpointer user_data) +{ + EMVFolderRule *rule = user_data; + + g_return_val_if_fail (rule != NULL, FALSE); + + return g_queue_find (&rule->priv->sources, key) == NULL; +} + +void +em_vfolder_rule_sources_changed (EMVFolderRule *rule) +{ + g_return_if_fail (rule != NULL); + + g_hash_table_foreach_remove (rule->priv->include_subfolders, + check_queue_has_key, rule); +} + +gboolean +em_vfolder_rule_source_get_include_subfolders (EMVFolderRule *rule, + const gchar *source) +{ + g_return_val_if_fail (rule != NULL, FALSE); + g_return_val_if_fail (source != NULL, FALSE); + + source = em_vfolder_rule_find_source (rule, source); + + return source && g_hash_table_lookup (rule->priv->include_subfolders, source); +} + +void +em_vfolder_rule_source_set_include_subfolders (EMVFolderRule *rule, + const gchar *source, + gboolean include_subfolders) +{ + g_return_if_fail (rule != NULL); + g_return_if_fail (source != NULL); + + source = em_vfolder_rule_find_source (rule, source); + g_return_if_fail (source != NULL); + + if (include_subfolders) + g_hash_table_insert (rule->priv->include_subfolders, (gpointer) source, GINT_TO_POINTER (1)); + else + g_hash_table_remove (rule->priv->include_subfolders, (gpointer) source); +} + void em_vfolder_rule_set_with (EMVFolderRule *rule, em_vfolder_rule_with_t with) @@ -200,14 +266,6 @@ em_vfolder_rule_get_with (EMVFolderRule *rule) return rule->priv->with; } -GQueue * -em_vfolder_rule_get_sources (EMVFolderRule *rule) -{ - g_return_val_if_fail (rule != NULL, NULL); - - return &rule->priv->sources; -} - void em_vfolder_rule_set_autoupdate (EMVFolderRule *rule, gboolean autoupdate) @@ -306,6 +364,8 @@ xml_encode (EFilterRule *fr) work = xmlNewNode (NULL, (const guchar *) "folder"); xmlSetProp (work, (const guchar *) "uri", (guchar *) uri); + xmlSetProp (work, (const guchar *) "include-subfolders", (guchar *) + (em_vfolder_rule_source_get_include_subfolders (vr, uri) ? "true" : "false")); xmlAddChild (set, work); } @@ -368,7 +428,17 @@ xml_decode (EFilterRule *fr, if (!strcmp((gchar *)work->name, "folder")) { tmp = (gchar *)xmlGetProp(work, (const guchar *)"uri"); if (tmp) { + gchar *include_subfolders; + g_queue_push_tail (&vr->priv->sources, g_strdup (tmp)); + + include_subfolders = (gchar *) xmlGetProp (work, (const guchar *) "include-subfolders"); + if (include_subfolders) { + em_vfolder_rule_source_set_include_subfolders (vr, + tmp, g_str_equal (include_subfolders, "true")); + xmlFree (include_subfolders); + } + xmlFree (tmp); } } @@ -394,10 +464,15 @@ rule_copy (EFilterRule *dest, while ((uri = g_queue_pop_head (&vdest->priv->sources)) != NULL) g_free (uri); + em_vfolder_rule_sources_changed (vdest); + head = g_queue_peek_head_link (&vsrc->priv->sources); for (link = head; link != NULL; link = g_list_next (link)) { const gchar *uri = link->data; g_queue_push_tail (&vdest->priv->sources, g_strdup (uri)); + + em_vfolder_rule_source_set_include_subfolders (vdest, uri, + em_vfolder_rule_source_get_include_subfolders (vsrc, uri)); } vdest->priv->with = vsrc->priv->with; diff --git a/libemail-utils/em-vfolder-rule.h b/libemail-utils/em-vfolder-rule.h index f6dbfa0d03..60f30044b4 100644 --- a/libemail-utils/em-vfolder-rule.h +++ b/libemail-utils/em-vfolder-rule.h @@ -71,7 +71,7 @@ struct _EMVFolderRuleClass { }; GType em_vfolder_rule_get_type (void); -EFilterRule * em_vfolder_rule_new (); +EFilterRule * em_vfolder_rule_new (void); void em_vfolder_rule_add_source (EMVFolderRule *rule, const gchar *uri); void em_vfolder_rule_remove_source (EMVFolderRule *rule, @@ -80,11 +80,19 @@ const gchar * em_vfolder_rule_find_source (EMVFolderRule *rule, const gchar *uri); const gchar * em_vfolder_rule_next_source (EMVFolderRule *rule, const gchar *last); +GQueue * em_vfolder_rule_get_sources (EMVFolderRule *rule); +void em_vfolder_rule_sources_changed (EMVFolderRule *rule); +gboolean em_vfolder_rule_source_get_include_subfolders + (EMVFolderRule *rule, + const gchar *source); +void em_vfolder_rule_source_set_include_subfolders + (EMVFolderRule *rule, + const gchar *source, + gboolean include_subfolders); void em_vfolder_rule_set_with (EMVFolderRule *rule, em_vfolder_rule_with_t with); em_vfolder_rule_with_t em_vfolder_rule_get_with (EMVFolderRule *rule); -GQueue * em_vfolder_rule_get_sources (EMVFolderRule *rule); void em_vfolder_rule_set_autoupdate (EMVFolderRule *rule, gboolean autoupdate); gboolean em_vfolder_rule_get_autoupdate (EMVFolderRule *rule); diff --git a/mail/em-vfolder-editor-rule.c b/mail/em-vfolder-editor-rule.c index b1fdadd1ea..78fbd4624d 100644 --- a/mail/em-vfolder-editor-rule.c +++ b/mail/em-vfolder-editor-rule.c @@ -211,7 +211,7 @@ struct _source_data { ERuleContext *rc; EMVFolderRule *vr; GtkListStore *model; - GtkTreeView *list; + GtkTreeView *tree_view; GtkWidget *source_selector; GtkWidget *buttons[BUTTON_LAST]; }; @@ -221,7 +221,7 @@ set_sensitive (struct _source_data *data) { GtkTreeSelection *selection; - selection = gtk_tree_view_get_selection (data->list); + selection = gtk_tree_view_get_selection (data->tree_view); gtk_widget_set_sensitive ( GTK_WIDGET (data->buttons[BUTTON_ADD]), TRUE); @@ -262,6 +262,39 @@ autoupdate_toggled_cb (GtkToggleButton *toggle, } static void +include_subfolders_toggled_cb (GtkCellRendererToggle *cell_renderer, + const gchar *path_string, + struct _source_data *data) +{ + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + gtk_cell_renderer_toggle_set_active (cell_renderer, + !gtk_cell_renderer_toggle_get_active (cell_renderer)); + + model = gtk_tree_view_get_model (data->tree_view); + path = gtk_tree_path_new_from_string (path_string); + + if (gtk_tree_model_get_iter (model, &iter, path)) { + gchar *source = NULL; + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + 2, gtk_cell_renderer_toggle_get_active (cell_renderer), + -1); + + gtk_tree_model_get (model, &iter, 1, &source, -1); + if (source) { + em_vfolder_rule_source_set_include_subfolders (data->vr, source, + gtk_cell_renderer_toggle_get_active (cell_renderer)); + g_free (source); + } + } + + gtk_tree_path_free (path); +} + +static void vfr_folder_response (EMFolderSelector *selector, gint button, struct _source_data *data) @@ -282,8 +315,9 @@ vfr_folder_response (EMFolderSelector *selector, GHashTable *known_uris; GtkTreeIter iter; GtkTreeSelection *selection; + gboolean changed = FALSE; - selection = gtk_tree_view_get_selection (data->list); + selection = gtk_tree_view_get_selection (data->tree_view); gtk_tree_selection_unselect_all (selection); known_uris = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); @@ -309,6 +343,7 @@ vfr_folder_response (EMFolderSelector *selector, g_hash_table_insert (known_uris, g_strdup (uri), GINT_TO_POINTER (1)); + changed = TRUE; g_queue_push_tail (em_vfolder_rule_get_sources (data->vr), g_strdup (uri)); markup = e_mail_folder_uri_to_markup (session, uri, NULL); @@ -322,6 +357,8 @@ vfr_folder_response (EMFolderSelector *selector, } g_hash_table_destroy (known_uris); + if (changed) + em_vfolder_rule_sources_changed (data->vr); set_sensitive (data); } @@ -377,7 +414,7 @@ source_remove (GtkWidget *widget, gint index = 0, first_selected = -1, removed; gint n; - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->list)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->tree_view)); to_remove = g_hash_table_new (g_direct_hash, g_direct_equal); source = NULL; @@ -436,7 +473,7 @@ source_remove (GtkWidget *widget, 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_view_set_cursor (data->tree_view, path, NULL, FALSE); } gtk_tree_path_free (path); } @@ -454,6 +491,7 @@ get_widget (EFilterRule *fr, GtkWidget *autoupdate; GtkListStore *model; GtkCellRenderer *renderer; + GtkTreeViewColumn *column; struct _source_data *data; const gchar *source; gchar *tmp; @@ -538,13 +576,29 @@ get_widget (EFilterRule *fr, NULL); gtk_container_add (GTK_CONTAINER (hgrid), scrolled_window); - model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); + model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); renderer = gtk_cell_renderer_text_new (); tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view), -1, "column", renderer, "markup", 0, NULL); + renderer = gtk_cell_renderer_toggle_new (); + column = gtk_tree_view_column_new_with_attributes ( + "include subfolders", renderer, "active", 2, NULL); + g_signal_connect (renderer, "toggled", G_CALLBACK (include_subfolders_toggled_cb), data); + + renderer = gtk_cell_renderer_text_new (); + g_object_set (G_OBJECT (renderer), + "editable", FALSE, + "text", _("include subfolders"), + NULL); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), column, -1); + + column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), 0); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), tree_view); vgrid = gtk_grid_new (); @@ -566,7 +620,7 @@ get_widget (EFilterRule *fr, gtk_container_add (GTK_CONTAINER (vgrid), data->buttons[BUTTON_ADD]); gtk_container_add (GTK_CONTAINER (vgrid), data->buttons[BUTTON_REMOVE]); - data->list = GTK_TREE_VIEW (tree_view); + data->tree_view = GTK_TREE_VIEW (tree_view); data->model = model; session = em_vfolder_editor_context_get_session (EM_VFOLDER_EDITOR_CONTEXT (rc)); @@ -579,11 +633,15 @@ get_widget (EFilterRule *fr, CAMEL_SESSION (session), source, NULL); gtk_list_store_append (data->model, &iter); - gtk_list_store_set (data->model, &iter, 0, markup, 1, source, -1); + gtk_list_store_set (data->model, &iter, + 0, markup, + 1, source, + 2, em_vfolder_rule_source_get_include_subfolders (vr, source), + -1); g_free (markup); } - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->list)); + selection = gtk_tree_view_get_selection (data->tree_view); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); g_signal_connect ( diff --git a/mail/mail-vfolder-ui.c b/mail/mail-vfolder-ui.c index 14b55d1d8f..d9b68ad834 100644 --- a/mail/mail-vfolder-ui.c +++ b/mail/mail-vfolder-ui.c @@ -256,6 +256,16 @@ vfolder_clone_rule (EMailSession *session, return rule; } +static void +release_rule_notify_cb (gpointer rule) +{ + /* disconnect the "changed" signal */ + g_signal_handlers_disconnect_by_data (rule, + g_object_get_data (rule, "editor-dlg")); + g_object_set_data (rule, "editor-dlg", NULL); + g_object_unref (rule); +} + /* adds a rule with a gui */ void vfolder_gui_add_rule (EMVFolderRule *rule) @@ -283,9 +293,10 @@ vfolder_gui_add_rule (EMVFolderRule *rule) gtk_window_set_default_size (GTK_WINDOW (gd), 500, 500); gtk_box_pack_start (GTK_BOX (container), w, TRUE, TRUE, 0); gtk_widget_show ((GtkWidget *) gd); + g_object_set_data (G_OBJECT (rule), "editor-dlg", gd); g_object_set_data_full ( G_OBJECT (gd), "rule", rule, - (GDestroyNotify) g_object_unref); + release_rule_notify_cb); g_signal_connect ( rule, "changed", G_CALLBACK (new_rule_changed_cb), gd); |