evolution-3.6.4/mail/mail-vfolder-ui.c

No issues found

  1 /*
  2  * This program is free software; you can redistribute it and/or
  3  * modify it under the terms of the GNU Lesser General Public
  4  * License as published by the Free Software Foundation; either
  5  * version 2 of the License, or (at your option) version 3.
  6  *
  7  * This program is distributed in the hope that it will be useful,
  8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 10  * Lesser General Public License for more details.
 11  *
 12  * You should have received a copy of the GNU Lesser General Public
 13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 14  *
 15  *
 16  * Authors:
 17  *		Michael Zucchi <notzed@ximian.com>
 18  *
 19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 20  *
 21  */
 22 
 23 #ifdef HAVE_CONFIG_H
 24 #include <config.h>
 25 #endif
 26 
 27 #include <string.h>
 28 
 29 #include <glib/gi18n.h>
 30 
 31 #include "libevolution-utils/e-alert-dialog.h"
 32 #include "e-util/e-util-private.h"
 33 
 34 #include "libemail-utils/mail-mt.h"
 35 #include "libemail-engine/mail-folder-cache.h"
 36 #include "libemail-engine/e-mail-folder-utils.h"
 37 #include "libemail-engine/e-mail-session.h"
 38 #include "libemail-engine/e-mail-utils.h"
 39 #include "libemail-engine/mail-ops.h"
 40 #include "libemail-engine/mail-tools.h"
 41 
 42 #include "e-mail-backend.h"
 43 #include "em-folder-tree-model.h"
 44 #include "em-utils.h"
 45 #include "em-vfolder-editor-context.h"
 46 #include "em-vfolder-editor.h"
 47 #include "em-vfolder-editor-rule.h"
 48 #include "mail-autofilter.h"
 49 #include "mail-vfolder-ui.h"
 50 #include "e-mail-ui-session.h"
 51 
 52 #define d(x)  /* (printf("%s:%s: ",  G_STRLOC, G_STRFUNC), (x))*/
 53 
 54 /* NOTE: Once mail is moved to EDS, this context needs to be created ofr Mail UI. */
 55 extern EMVFolderContext *context;	/* context remains open all time */
 56 
 57 void
 58 vfolder_edit (EMailBackend *backend,
 59               GtkWindow *parent_window)
 60 {
 61 	EShellBackend *shell_backend;
 62 	GtkWidget *dialog;
 63 	const gchar *config_dir;
 64 	gchar *filename;
 65 	EMailSession *session;
 66 
 67 	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
 68 	g_return_if_fail (GTK_IS_WINDOW (parent_window));
 69 
 70 	shell_backend = E_SHELL_BACKEND (backend);
 71 	config_dir = e_shell_backend_get_config_dir (shell_backend);
 72 	filename = g_build_filename (config_dir, "vfolders.xml", NULL);
 73 	session = e_mail_backend_get_session (backend);
 74 
 75 	vfolder_load_storage (session);
 76 
 77 	dialog = em_vfolder_editor_new (context);
 78 	gtk_window_set_title (
 79 		GTK_WINDOW (dialog), _("Search Folders"));
 80 	gtk_window_set_transient_for (
 81 		GTK_WINDOW (dialog), parent_window);
 82 
 83 	switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
 84 		case GTK_RESPONSE_OK:
 85 			e_rule_context_save ((ERuleContext *) context, filename);
 86 			break;
 87 		default:
 88 			e_rule_context_revert ((ERuleContext *) context, filename);
 89 			break;
 90 	}
 91 
 92 	gtk_widget_destroy (dialog);
 93 }
 94 
 95 static void
 96 vfolder_edit_response_cb (GtkWidget *dialog,
 97                           gint response_id,
 98                           gpointer user_data)
 99 {
100 	if (response_id == GTK_RESPONSE_OK) {
101 		GObject *object;
102 		EFilterRule *rule;
103 		EFilterRule *newrule;
104 		const gchar *config_dir;
105 		gchar *user;
106 
107 		object = G_OBJECT (dialog);
108 		rule = g_object_get_data (object, "vfolder-rule");
109 		newrule = g_object_get_data (object, "vfolder-newrule");
110 
111 		e_filter_rule_copy (rule, newrule);
112 		config_dir = mail_session_get_config_dir ();
113 		user = g_build_filename (config_dir, "vfolders.xml", NULL);
114 		e_rule_context_save ((ERuleContext *) context, user);
115 		g_free (user);
116 	}
117 
118 	gtk_widget_destroy (dialog);
119 }
120 
121 void
122 vfolder_edit_rule (EMailSession *session,
123                    const gchar *folder_uri,
124                    EAlertSink *alert_sink)
125 {
126 	GtkWidget *dialog;
127 	GtkWidget *widget;
128 	GtkWidget *container;
129 	EFilterRule *rule = NULL;
130 	EFilterRule *newrule;
131 	gchar *folder_name = NULL;
132 
133 	g_return_if_fail (E_IS_MAIL_SESSION (session));
134 	g_return_if_fail (folder_uri != NULL);
135 	g_return_if_fail (E_IS_ALERT_SINK (alert_sink));
136 
137 	e_mail_folder_uri_parse (
138 		CAMEL_SESSION (session), folder_uri,
139 		NULL, &folder_name, NULL);
140 
141 	if (folder_name != NULL) {
142 		rule = e_rule_context_find_rule (
143 			(ERuleContext *) context, folder_name, NULL);
144 		g_free (folder_name);
145 	}
146 
147 	if (rule == NULL) {
148 		/* TODO: we should probably just create it ... */
149 		e_alert_submit (
150 			alert_sink, "mail:vfolder-notexist",
151 			folder_uri, NULL);
152 		return;
153 	}
154 
155 	g_object_ref (rule);
156 	newrule = e_filter_rule_clone (rule);
157 
158 	dialog = gtk_dialog_new_with_buttons (
159 		_("Edit Search Folder"), NULL,
160 		GTK_DIALOG_DESTROY_WITH_PARENT,
161 		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
162 		GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
163 
164 	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
165 	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
166 
167 	gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 500);
168 	gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
169 
170 	container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
171 	gtk_box_set_spacing (GTK_BOX (container), 6);
172 
173 	widget = e_filter_rule_get_widget (
174 		(EFilterRule *) newrule, (ERuleContext *) context);
175 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
176 	gtk_widget_show (widget);
177 
178 	g_object_set_data_full (
179 		G_OBJECT (dialog), "vfolder-rule",
180 		rule, (GDestroyNotify) g_object_unref);
181 	g_object_set_data_full (
182 		G_OBJECT (dialog), "vfolder-newrule",
183 		newrule, (GDestroyNotify) g_object_unref);
184 
185 	g_signal_connect (
186 		dialog, "response",
187 		G_CALLBACK (vfolder_edit_response_cb), NULL);
188 
189 	gtk_widget_show (dialog);
190 }
191 
192 static void
193 new_rule_clicked (GtkWidget *w,
194                   gint button,
195                   gpointer data)
196 {
197 	if (button == GTK_RESPONSE_OK) {
198 		const gchar *config_dir;
199 		gchar *user;
200 		EFilterRule *rule = g_object_get_data ((GObject *) w, "rule");
201 		EAlert *alert = NULL;
202 
203 		if (!e_filter_rule_validate (rule, &alert)) {
204 			e_alert_run_dialog (GTK_WINDOW (w), alert);
205 			g_object_unref (alert);
206 			return;
207 		}
208 
209 		if (e_rule_context_find_rule (
210 			(ERuleContext *) context, rule->name, rule->source)) {
211 			e_alert_run_dialog_for_args (
212 				GTK_WINDOW (w), "mail:vfolder-notunique",
213 				rule->name, NULL);
214 			return;
215 		}
216 
217 		g_object_ref (rule);
218 		e_rule_context_add_rule ((ERuleContext *) context, rule);
219 		config_dir = mail_session_get_config_dir ();
220 		user = g_build_filename (config_dir, "vfolders.xml", NULL);
221 		e_rule_context_save ((ERuleContext *) context, user);
222 		g_free (user);
223 	}
224 
225 	gtk_widget_destroy (w);
226 }
227 
228 static void
229 new_rule_changed_cb (EFilterRule *rule,
230                      GtkDialog *dialog)
231 {
232 	g_return_if_fail (rule != NULL);
233 	g_return_if_fail (dialog != NULL);
234 
235 	gtk_dialog_set_response_sensitive (
236 		dialog, GTK_RESPONSE_OK, rule->parts != NULL);
237 }
238 
239 /* clones a filter/search rule into a matching vfolder rule
240  * (assuming the same system definitions) */
241 EFilterRule *
242 vfolder_clone_rule (EMailSession *session,
243                     EFilterRule *in)
244 {
245 	EFilterRule *rule;
246 	xmlNodePtr xml;
247 
248 	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
249 
250 	rule = em_vfolder_editor_rule_new (session);
251 
252 	xml = e_filter_rule_xml_encode (in);
253 	e_filter_rule_xml_decode (rule, xml, (ERuleContext *) context);
254 	xmlFreeNodeList (xml);
255 
256 	return rule;
257 }
258 
259 static void
260 release_rule_notify_cb (gpointer rule)
261 {
262 	/* disconnect the "changed" signal */
263 	g_signal_handlers_disconnect_by_data (
264 		rule, g_object_get_data (rule, "editor-dlg"));
265 	g_object_set_data (rule, "editor-dlg", NULL);
266 	g_object_unref (rule);
267 }
268 
269 /* adds a rule with a gui */
270 void
271 vfolder_gui_add_rule (EMVFolderRule *rule)
272 {
273 	GtkWidget *w;
274 	GtkDialog *gd;
275 	GtkWidget *container;
276 
277 	w = e_filter_rule_get_widget ((EFilterRule *) rule, (ERuleContext *) context);
278 
279 	gd = (GtkDialog *) gtk_dialog_new_with_buttons (
280 		_("New Search Folder"),
281 		NULL,
282 		GTK_DIALOG_DESTROY_WITH_PARENT,
283 		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
284 		GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
285 
286 	gtk_dialog_set_default_response (gd, GTK_RESPONSE_OK);
287 	gtk_container_set_border_width (GTK_CONTAINER (gd), 6);
288 
289 	container = gtk_dialog_get_content_area (gd);
290 	gtk_box_set_spacing (GTK_BOX (container), 6);
291 
292 	g_object_set (gd, "resizable", TRUE, NULL);
293 	gtk_window_set_default_size (GTK_WINDOW (gd), 500, 500);
294 	gtk_box_pack_start (GTK_BOX (container), w, TRUE, TRUE, 0);
295 	gtk_widget_show ((GtkWidget *) gd);
296 	g_object_set_data (G_OBJECT (rule), "editor-dlg", gd);
297 	g_object_set_data_full (
298 		G_OBJECT (gd), "rule", rule,
299 		release_rule_notify_cb);
300 	g_signal_connect (
301 		rule, "changed",
302 		G_CALLBACK (new_rule_changed_cb), gd);
303 	new_rule_changed_cb ((EFilterRule *) rule, gd);
304 	g_signal_connect (
305 		gd, "response",
306 		G_CALLBACK (new_rule_clicked), NULL);
307 	gtk_widget_show ((GtkWidget *) gd);
308 }
309 
310 void
311 vfolder_gui_add_from_message (EMailSession *session,
312                               CamelMimeMessage *message,
313                               gint flags,
314                               CamelFolder *folder)
315 {
316 	EMVFolderRule *rule;
317 
318 	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
319 
320 	rule = (EMVFolderRule *) em_vfolder_rule_from_message (
321 		context, message, flags, folder);
322 	vfolder_gui_add_rule (rule);
323 }
324 
325 void
326 vfolder_gui_add_from_address (EMailSession *session,
327                               CamelInternetAddress *addr,
328                               gint flags,
329                               CamelFolder *folder)
330 {
331 	EMVFolderRule *rule;
332 
333 	g_return_if_fail (addr != NULL);
334 
335 	rule = (EMVFolderRule *) em_vfolder_rule_from_address (
336 		context, addr, flags, folder);
337 	vfolder_gui_add_rule (rule);
338 }