Beispiel #1
0
static void
new_rule_clicked (GtkWidget *w,
                  gint button,
                  gpointer data)
{
	if (button == GTK_RESPONSE_OK) {
		const gchar *config_dir;
		gchar *user;
		EFilterRule *rule = g_object_get_data((GObject *)w, "rule");
		EAlert *alert = NULL;

		if (!e_filter_rule_validate (rule, &alert)) {
			e_alert_run_dialog (GTK_WINDOW (w), alert);
			g_object_unref (alert);
			return;
		}

		if (e_rule_context_find_rule (
			(ERuleContext *) context, rule->name, rule->source)) {
			e_alert_run_dialog_for_args (
				GTK_WINDOW (w), "mail:vfolder-notunique",
				rule->name, NULL);
			return;
		}

		g_object_ref (rule);
		e_rule_context_add_rule ((ERuleContext *) context, rule);
		config_dir = mail_session_get_config_dir ();
		user = g_build_filename (config_dir, "vfolders.xml", NULL);
		e_rule_context_save ((ERuleContext *) context, user);
		g_free (user);
	}

	gtk_widget_destroy (w);
}
Beispiel #2
0
static void
store_folder_renamed_cb (CamelStore *store,
                         const gchar *old_name,
                         CamelFolderInfo *info)
{
	EFilterRule *rule;
	gchar *user;

	gpointer key, folder;

	/* This should be more-or-less thread-safe */

	d(printf("Folder renamed to '%s' from '%s'\n", info->full_name, old_name));

	/* Folder is already renamed? */
	G_LOCK (vfolder);
	d(printf("Changing folder name in hash table to '%s'\n", info->full_name));
	if (g_hash_table_lookup_extended (vfolder_hash, old_name, &key, &folder)) {
		const gchar *config_dir;

		g_hash_table_remove (vfolder_hash, key);
		g_free (key);
		g_hash_table_insert (vfolder_hash, g_strdup (info->full_name), folder);

		rule = e_rule_context_find_rule ((ERuleContext *) context, old_name, NULL);
		if (!rule) {
			G_UNLOCK (vfolder);
			g_warning ("Rule shouldn't be NULL\n");
			return;
		}

		g_signal_handlers_disconnect_matched (
			rule, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
			0, 0, NULL, rule_changed, folder);
		e_filter_rule_set_name (rule, info->full_name);
		g_signal_connect (rule, "changed", G_CALLBACK(rule_changed), folder);

		config_dir = mail_session_get_config_dir ();
		user = g_build_filename (config_dir, "vfolders.xml", NULL);
		e_rule_context_save ((ERuleContext *) context, user);
		g_free (user);

		G_UNLOCK (vfolder);
	} else {
		G_UNLOCK (vfolder);
		g_warning("couldn't find a vfolder rule in our table? %s", info->full_name);
	}
}
Beispiel #3
0
void
mail_filter_rename_folder (CamelStore *store,
                           const gchar *old_folder_name,
                           const gchar *new_folder_name)
{
	CamelSession *session;
	EMFilterContext *fc;
	const gchar *config_dir;
	gchar *user, *system;
	GList *changed;
	gchar *old_uri;
	gchar *new_uri;

	g_return_if_fail (CAMEL_IS_STORE (store));
	g_return_if_fail (old_folder_name != NULL);
	g_return_if_fail (new_folder_name != NULL);

	session = camel_service_ref_session (CAMEL_SERVICE (store));

	old_uri = e_mail_folder_uri_build (store, old_folder_name);
	new_uri = e_mail_folder_uri_build (store, new_folder_name);

	fc = em_filter_context_new (E_MAIL_SESSION (session));
	config_dir = mail_session_get_config_dir ();
	user = g_build_filename (config_dir, "filters.xml", NULL);
	system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
	e_rule_context_load ((ERuleContext *) fc, system, user);
	g_free (system);

	changed = e_rule_context_rename_uri (
		(ERuleContext *) fc, old_uri, new_uri, g_str_equal);
	if (changed) {
		if (e_rule_context_save ((ERuleContext *) fc, user) == -1)
			g_warning ("Could not write out changed filter rules\n");
		e_rule_context_free_uri_list ((ERuleContext *) fc, changed);
	}

	g_free (user);
	g_object_unref (fc);

	g_free (old_uri);
	g_free (new_uri);

	g_object_unref (session);
}
Beispiel #4
0
static void
store_folder_deleted_cb (CamelStore *store,
                         CamelFolderInfo *info)
{
	EFilterRule *rule;
	gchar *user;

	d(printf("Folder deleted: %s\n", info->name));
	store = store;

	/* Warning not thread safe, but might be enough */

	G_LOCK (vfolder);

	/* delete it from our list */
	rule = e_rule_context_find_rule ((ERuleContext *) context, info->full_name, NULL);
	if (rule) {
		const gchar *config_dir;

		/* We need to stop listening to removed events,
		 * otherwise we'll try and remove it again. */
		g_signal_handlers_disconnect_matched (
			context, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
			0, 0, NULL, context_rule_removed, context);
		e_rule_context_remove_rule ((ERuleContext *) context, rule);
		g_object_unref (rule);
		g_signal_connect (
			context, "rule_removed",
			G_CALLBACK (context_rule_removed), context);

		config_dir = mail_session_get_config_dir ();
		user = g_build_filename (config_dir, "vfolders.xml", NULL);
		e_rule_context_save ((ERuleContext *) context, user);
		g_free (user);
	} else {
		g_warning (
			"Cannot find rule for deleted vfolder '%s'",
			info->display_name);
	}

	G_UNLOCK (vfolder);
}
Beispiel #5
0
static void
vfolder_edit_response_cb (GtkWidget *dialog,
                          gint response_id,
                          gpointer user_data)
{
	if (response_id == GTK_RESPONSE_OK) {
		EFilterRule *rule = g_object_get_data (G_OBJECT (dialog), "vfolder-rule");
		EFilterRule *newrule = g_object_get_data (G_OBJECT (dialog), "vfolder-newrule");
		const gchar *config_dir;
		gchar *user;

		e_filter_rule_copy (rule, newrule);
		config_dir = mail_session_get_config_dir ();
		user = g_build_filename (config_dir, "vfolders.xml", NULL);
		e_rule_context_save ((ERuleContext *) context, user);
		g_free (user);
	}

	gtk_widget_destroy (dialog);
}
Beispiel #6
0
void
vfolder_edit (EShellView *shell_view)
{
	EShellBackend *shell_backend;
	EShellWindow *shell_window;
	EMailBackend *backend;
	GtkWidget *dialog;
	const gchar *config_dir;
	gchar *filename;

	g_return_if_fail (E_IS_SHELL_VIEW (shell_view));

	shell_backend = e_shell_view_get_shell_backend (shell_view);
	shell_window = e_shell_view_get_shell_window (shell_view);

	config_dir = e_shell_backend_get_config_dir (shell_backend);
	filename = g_build_filename (config_dir, "vfolders.xml", NULL);

	backend = E_MAIL_BACKEND (shell_backend);

	vfolder_load_storage (backend);

	dialog = em_vfolder_editor_new (context);
	gtk_window_set_title (
		GTK_WINDOW (dialog), _("Search Folders"));
	gtk_window_set_transient_for (
		GTK_WINDOW (dialog), GTK_WINDOW (shell_window));

	switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
		case GTK_RESPONSE_OK:
			e_rule_context_save ((ERuleContext *) context, filename);
			break;
		default:
			e_rule_context_revert ((ERuleContext *) context, filename);
			break;
	}

	gtk_widget_destroy (dialog);
}
Beispiel #7
0
void
mail_filter_delete_folder (EMailBackend *backend,
                           CamelStore *store,
                           const gchar *folder_name)
{
	EMFilterContext *fc;
	const gchar *config_dir;
	gchar *user, *system;
	GList *deleted;
	gchar *uri;

	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
	g_return_if_fail (CAMEL_IS_STORE (store));
	g_return_if_fail (folder_name != NULL);

	uri = e_mail_folder_uri_build (store, folder_name);

	fc = em_filter_context_new (backend);
	config_dir = mail_session_get_config_dir ();
	user = g_build_filename (config_dir, "filters.xml", NULL);
	system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
	e_rule_context_load ((ERuleContext *) fc, system, user);
	g_free (system);

	deleted = e_rule_context_delete_uri (
		(ERuleContext *) fc, uri, g_str_equal);
	if (deleted) {
		GString *s;
		guint s_count;
		gchar *info;
		GList *l;

		s = g_string_new("");
		s_count = 0;
		for (l = deleted; l; l = l->next) {
			const gchar *name = (const gchar *) l->data;

			if (s_count == 0) {
				g_string_append (s, name);
			} else {
				if (s_count == 1) {
					g_string_prepend (s, "    ");
					g_string_append (s, "\n");
				}
				g_string_append_printf (s, "    %s\n", name);
			}
			s_count++;
		}

		info = g_strdup_printf (ngettext (
			/* Translators: The first %s is name of the affected
			 * filter rule(s), the second %s is URI of the removed
			 * folder. For more than one filter rule is each of
			 * them on a separate line, with four spaces in front
			 * of its name, without quotes. */
			"The filter rule \"%s\" has been modified to account "
			"for the deleted folder\n\"%s\".",
			"The following filter rules\n%s have been modified "
			"to account for the deleted folder\n\"%s\".",
			s_count), s->str, folder_name);
		e_mail_backend_submit_alert (
			backend, "mail:filter-updated", info, NULL);
		g_string_free (s, TRUE);
		g_free (info);

		if (e_rule_context_save ((ERuleContext *) fc, user) == -1)
			g_warning ("Could not write out changed filter rules\n");
		e_rule_context_free_uri_list ((ERuleContext *) fc, deleted);
	}

	g_free (user);
	g_object_unref (fc);
	g_free (uri);
}
Beispiel #8
0
/* called when a uri is renamed in a store */
static void
mail_vfolder_rename_folder (CamelStore *store,
                            const gchar *old_folder_name,
                            const gchar *new_folder_name)
{
	ERuleContext *rule_context;
	EFilterRule *rule;
	const gchar *source;
	CamelVeeFolder *vf;
	CamelSession *session;
	gint changed = 0;
	gchar *old_uri;
	gchar *new_uri;

	d(printf("vfolder rename uri: %s to %s\n", cfrom, cto));

	if (context == NULL)
		return;

	if (folder_is_spethal (store, old_folder_name))
		return;

	if (folder_is_spethal (store, new_folder_name))
		return;

	g_return_if_fail (mail_in_main_thread ());

	session = camel_service_get_session (CAMEL_SERVICE (store));

	old_uri = e_mail_folder_uri_build (store, old_folder_name);
	new_uri = e_mail_folder_uri_build (store, new_folder_name);

	G_LOCK (vfolder);

	rule_context = E_RULE_CONTEXT (context);

	/* see if any rules directly reference this removed uri */
	rule = NULL;
	while ((rule = e_rule_context_next_rule (rule_context, rule, NULL))) {
		EMVFolderRule *vf_rule = EM_VFOLDER_RULE (rule);

		source = NULL;
		while ((source = em_vfolder_rule_next_source (vf_rule, source))) {
			/* Remove all sources that match, ignore changed events though
			 * because the adduri call above does the work async */
			if (e_mail_folder_uri_equal (session, old_uri, source)) {
				vf = g_hash_table_lookup (vfolder_hash, rule->name);
				if (!vf) {
					g_warning ("vf is NULL for %s\n", rule->name);
					continue;
				}

				g_signal_handlers_disconnect_matched (
					rule, G_SIGNAL_MATCH_FUNC |
					G_SIGNAL_MATCH_DATA, 0, 0, NULL,
					rule_changed, vf);

				em_vfolder_rule_remove_source (vf_rule, source);
				em_vfolder_rule_add_source (vf_rule, new_uri);

				g_signal_connect (
					vf_rule, "changed",
					G_CALLBACK (rule_changed), vf);

				changed++;
				source = NULL;
			}
		}
	}

	G_UNLOCK (vfolder);

	if (changed) {
		const gchar *config_dir;
		gchar *user;

		d(printf("Vfolders updated from renamed folder\n"));
		config_dir = mail_session_get_config_dir ();
		user = g_build_filename (config_dir, "vfolders.xml", NULL);
		e_rule_context_save ((ERuleContext *) context, user);
		g_free (user);
	}

	g_free (old_uri);
	g_free (new_uri);
}
Beispiel #9
0
/**
 * mail_vfolder_delete_folder:
 * @backend: an #EMailBackend
 * @store: a #CamelStore
 * @folder_name: a folder name
 *
 * Looks through all vfolder rules to see if @folder_name is listed as a
 * source for any vfolder rules.  If the folder is found in the source for
 * any rule, it is removed and the user is alerted to the fact that the
 * vfolder rules have been updated.  The new vfolder rules are written
 * to disk.
 *
 * XXX: It doesn't appear that the changes to the vfolder rules are sent
 * down to the camel level, however. So the actual vfolders will not change
 * behavior until evolution is restarted (?)
 *
 * NOTE: This function must be called from the main thread.
 */
static void
mail_vfolder_delete_folder (EMailBackend *backend,
                            CamelStore *store,
                            const gchar *folder_name)
{
	ERuleContext *rule_context;
	EFilterRule *rule;
	EMailSession *session;
	const gchar *source;
	CamelVeeFolder *vf;
	GString *changed;
	GQueue *queue;
	guint changed_count;
	gchar *uri;
	GList *link;

	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
	g_return_if_fail (CAMEL_IS_STORE (store));
	g_return_if_fail (folder_name != NULL);

	if (folder_is_spethal (store, folder_name))
		return;

	d(printf ("Deleting uri to check: %s\n", uri));

	g_return_if_fail (mail_in_main_thread ());

	session = e_mail_backend_get_session (backend);
	uri = e_mail_folder_uri_build (store, folder_name);

	changed_count = 0;
	changed = g_string_new ("");

	G_LOCK (vfolder);

	if (context == NULL)
		goto done;

	rule_context = E_RULE_CONTEXT (context);

	/* see if any rules directly reference this removed uri */
	rule = NULL;
	while ((rule = e_rule_context_next_rule (rule_context, rule, NULL))) {
		EMVFolderRule *vf_rule = EM_VFOLDER_RULE (rule);

		if (!rule->name)
			continue;

		source = NULL;
		while ((source = em_vfolder_rule_next_source (vf_rule, source))) {
			/* Remove all sources that match, ignore changed events though
			 * because the adduri call above does the work async */
			if (e_mail_folder_uri_equal (CAMEL_SESSION (session), uri, source)) {
				vf = g_hash_table_lookup (
					vfolder_hash, rule->name);

				if (!vf) {
					g_warning ("vf is NULL for %s\n", rule->name);
					continue;
				}

				g_signal_handlers_disconnect_matched (
					rule, G_SIGNAL_MATCH_FUNC |
					G_SIGNAL_MATCH_DATA, 0, 0, NULL,
					rule_changed, vf);

				em_vfolder_rule_remove_source (vf_rule, source);

				g_signal_connect (
					rule, "changed",
					G_CALLBACK (rule_changed), vf);

				if (changed_count == 0) {
					g_string_append (changed, rule->name);
				} else {
					if (changed_count == 1) {
						g_string_prepend (changed, "    ");
						g_string_append (changed, "\n");
					}
					g_string_append_printf (
						changed, "    %s\n",
						rule->name);
				}

				changed_count++;
				source = NULL;
			}
		}
	}

done:
	queue = &source_folders_remote;
	link = mv_find_folder (queue, session, uri);
	if (link != NULL) {
		g_free (link->data);
		g_queue_delete_link (queue, link);
	}

	queue = &source_folders_local;
	link = mv_find_folder (queue, session, uri);
	if (link != NULL) {
		g_free (link->data);
		g_queue_delete_link (queue, link);
	}

	G_UNLOCK (vfolder);

	if (changed_count > 0) {
		const gchar *config_dir;
		gchar *user, *info;

		info = g_strdup_printf (ngettext (
			/* Translators: The first %s is name of the affected
			 * search folder(s), the second %s is the URI of the
			 * removed folder. For more than one search folder is
			 * each of them on a separate line, with four spaces
			 * in front of its name, without quotes. */
			"The Search Folder \"%s\" has been modified to "
			"account for the deleted folder\n\"%s\".",
			"The following Search Folders\n%s have been modified "
			"to account for the deleted folder\n\"%s\".",
			changed_count), changed->str, uri);
		e_mail_backend_submit_alert (
			backend, "mail:vfolder-updated", info, NULL);
		g_free (info);

		config_dir = mail_session_get_config_dir ();
		user = g_build_filename (config_dir, "vfolders.xml", NULL);
		e_rule_context_save ((ERuleContext *) context, user);
		g_free (user);
	}

	g_string_free (changed, TRUE);

	g_free (uri);
}