evolution-3.6.4/filter/e-filter-file.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  *		Jeffrey Stedfast <fejj@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 #include <sys/types.h>
 29 
 30 #include <gtk/gtk.h>
 31 #include <glib/gi18n.h>
 32 #include <glib/gstdio.h>
 33 
 34 #include "libevolution-utils/e-alert.h"
 35 
 36 #include "e-filter-file.h"
 37 #include "e-filter-part.h"
 38 
 39 G_DEFINE_TYPE (
 40 	EFilterFile,
 41 	e_filter_file,
 42 	E_TYPE_FILTER_ELEMENT)
 43 
 44 static void
 45 filter_file_filename_changed (GtkFileChooser *file_chooser,
 46                               EFilterElement *element)
 47 {
 48 	EFilterFile *file = E_FILTER_FILE (element);
 49 	const gchar *path;
 50 
 51 	path = gtk_file_chooser_get_filename (file_chooser);
 52 
 53 	g_free (file->path);
 54 	file->path = g_strdup (path);
 55 }
 56 
 57 static void
 58 filter_file_finalize (GObject *object)
 59 {
 60 	EFilterFile *file = E_FILTER_FILE (object);
 61 
 62 	xmlFree (file->type);
 63 	g_free (file->path);
 64 
 65 	/* Chain up to parent's finalize() method. */
 66 	G_OBJECT_CLASS (e_filter_file_parent_class)->finalize (object);
 67 }
 68 
 69 static gboolean
 70 filter_file_validate (EFilterElement *element,
 71                       EAlert **alert)
 72 {
 73 	EFilterFile *file = E_FILTER_FILE (element);
 74 
 75 	g_warn_if_fail (alert == NULL || *alert == NULL);
 76 
 77 	if (!file->path) {
 78 		if (alert)
 79 			*alert = e_alert_new ("filter:no-file", NULL);
 80 		return FALSE;
 81 	}
 82 
 83 	/* FIXME: do more to validate command-lines? */
 84 
 85 	if (g_strcmp0 (file->type, "file") == 0) {
 86 		if (!g_file_test (file->path, G_FILE_TEST_IS_REGULAR)) {
 87 			if (alert)
 88 				*alert = e_alert_new ("filter:bad-file",
 89 						       file->path, NULL);
 90 			return FALSE;
 91 		}
 92 	} else if (g_strcmp0 (file->type, "command") == 0) {
 93 		/* Only requirements so far is that the
 94 		 * command can't be an empty string. */
 95 		return (file->path[0] != '\0');
 96 	}
 97 
 98 	return TRUE;
 99 }
100 
101 static gint
102 filter_file_eq (EFilterElement *element_a,
103                 EFilterElement *element_b)
104 {
105 	EFilterFile *file_a = E_FILTER_FILE (element_a);
106 	EFilterFile *file_b = E_FILTER_FILE (element_b);
107 
108 	/* Chain up to parent's eq() method. */
109 	if (!E_FILTER_ELEMENT_CLASS (e_filter_file_parent_class)->
110 		eq (element_a, element_b))
111 		return FALSE;
112 
113 	if (g_strcmp0 (file_a->path, file_b->path) != 0)
114 		return FALSE;
115 
116 	if (g_strcmp0 (file_a->type, file_b->type) != 0)
117 		return FALSE;
118 
119 	return TRUE;
120 }
121 
122 static xmlNodePtr
123 filter_file_xml_encode (EFilterElement *element)
124 {
125 	EFilterFile *file = E_FILTER_FILE (element);
126 	xmlNodePtr cur, value;
127 	const gchar *type;
128 
129 	type = file->type ? file->type : "file";
130 
131 	value = xmlNewNode (NULL, (xmlChar *)"value");
132 	xmlSetProp (value, (xmlChar *) "name", (xmlChar *) element->name);
133 	xmlSetProp (value, (xmlChar *) "type", (xmlChar *) type);
134 
135 	cur = xmlNewChild (value, NULL, (xmlChar *) type, NULL);
136 	xmlNodeSetContent (cur, (xmlChar *) file->path);
137 
138 	return value;
139 }
140 
141 static gint
142 filter_file_xml_decode (EFilterElement *element,
143                         xmlNodePtr node)
144 {
145 	EFilterFile *file = E_FILTER_FILE (element);
146 	gchar *name, *str, *type;
147 	xmlNodePtr child;
148 
149 	name = (gchar *) xmlGetProp (node, (xmlChar *) "name");
150 	type = (gchar *) xmlGetProp (node, (xmlChar *) "type");
151 
152 	xmlFree (element->name);
153 	element->name = name;
154 
155 	xmlFree (file->type);
156 	file->type = type;
157 
158 	g_free (file->path);
159 	file->path = NULL;
160 
161 	child = node->children;
162 	while (child != NULL) {
163 		if (!strcmp ((gchar *) child->name, type)) {
164 			str = (gchar *) xmlNodeGetContent (child);
165 			file->path = g_strdup (str ? str : "");
166 			xmlFree (str);
167 
168 			break;
169 		} else if (child->type == XML_ELEMENT_NODE) {
170 			g_warning (
171 				"Unknown node type '%s' encountered "
172 				"decoding a %s\n", child->name, type);
173 		}
174 
175 		child = child->next;
176 	}
177 
178 	return 0;
179 }
180 
181 static GtkWidget *
182 filter_file_get_widget (EFilterElement *element)
183 {
184 	EFilterFile *file = E_FILTER_FILE (element);
185 	GtkWidget *widget;
186 
187 	widget = gtk_file_chooser_button_new (
188 		_("Choose a File"), GTK_FILE_CHOOSER_ACTION_OPEN);
189 	gtk_file_chooser_set_filename (
190 		GTK_FILE_CHOOSER (widget), file->path);
191 	g_signal_connect (
192 		widget, "selection-changed",
193 		G_CALLBACK (filter_file_filename_changed), element);
194 
195 	return widget;
196 }
197 
198 static void
199 filter_file_format_sexp (EFilterElement *element,
200                          GString *out)
201 {
202 	EFilterFile *file = E_FILTER_FILE (element);
203 
204 	camel_sexp_encode_string (out, file->path);
205 }
206 
207 static void
208 e_filter_file_class_init (EFilterFileClass *class)
209 {
210 	GObjectClass *object_class;
211 	EFilterElementClass *filter_element_class;
212 
213 	object_class = G_OBJECT_CLASS (class);
214 	object_class->finalize = filter_file_finalize;
215 
216 	filter_element_class = E_FILTER_ELEMENT_CLASS (class);
217 	filter_element_class->validate = filter_file_validate;
218 	filter_element_class->eq = filter_file_eq;
219 	filter_element_class->xml_encode = filter_file_xml_encode;
220 	filter_element_class->xml_decode = filter_file_xml_decode;
221 	filter_element_class->get_widget = filter_file_get_widget;
222 	filter_element_class->format_sexp = filter_file_format_sexp;
223 }
224 
225 static void
226 e_filter_file_init (EFilterFile *filter)
227 {
228 }
229 
230 /**
231  * filter_file_new:
232  *
233  * Create a new EFilterFile object.
234  *
235  * Return value: A new #EFilterFile object.
236  **/
237 EFilterFile *
238 e_filter_file_new (void)
239 {
240 	return g_object_new (E_TYPE_FILTER_FILE, NULL);
241 }
242 
243 EFilterFile *
244 e_filter_file_new_type_name (const gchar *type)
245 {
246 	EFilterFile *file;
247 
248 	file = e_filter_file_new ();
249 	file->type = (gchar *) xmlStrdup ((xmlChar *) type);
250 
251 	return file;
252 }
253 
254 void
255 e_filter_file_set_path (EFilterFile *file,
256                         const gchar *path)
257 {
258 	g_return_if_fail (E_IS_FILTER_FILE (file));
259 
260 	g_free (file->path);
261 	file->path = g_strdup (path);
262 }