/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see
*
*
* Authors:
* Jeffrey Stedfast
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
#include
#include
#include
#include
#include
#include
#include
#include "e-util/e-error.h"
#include "e-filter-file.h"
#include "e-filter-part.h"
static gpointer parent_class;
static void
filter_file_filename_changed (GtkFileChooser *file_chooser,
EFilterElement *element)
{
EFilterFile *file = E_FILTER_FILE (element);
const gchar *path;
path = gtk_file_chooser_get_filename (file_chooser);
g_free (file->path);
file->path = g_strdup (path);
}
static void
filter_file_finalize (GObject *object)
{
EFilterFile *file = E_FILTER_FILE (object);
xmlFree (file->type);
g_free (file->path);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
filter_file_validate (EFilterElement *element,
EError **error)
{
EFilterFile *file = E_FILTER_FILE (element);
g_warn_if_fail (error == NULL || *error == NULL);
if (!file->path) {
if (error)
*error = e_error_new ("filter:no-file", NULL);
return FALSE;
}
/* FIXME: do more to validate command-lines? */
if (g_strcmp0 (file->type, "file") == 0) {
if (!g_file_test (file->path, G_FILE_TEST_IS_REGULAR)) {
if (error)
*error = e_error_new ( "filter:bad-file",
file->path, NULL);
return FALSE;
}
} else if (g_strcmp0 (file->type, "command") == 0) {
/* Only requirements so far is that the
* command can't be an empty string. */
return (file->path[0] != '\0');
}
return TRUE;
}
static gint
filter_file_eq (EFilterElement *element_a,
EFilterElement *element_b)
{
EFilterFile *file_a = E_FILTER_FILE (element_a);
EFilterFile *file_b = E_FILTER_FILE (element_b);
/* Chain up to parent's eq() method. */
if (!E_FILTER_ELEMENT_CLASS (parent_class)->eq (element_a, element_b))
return FALSE;
if (g_strcmp0 (file_a->path, file_b->path) != 0)
return FALSE;
if (g_strcmp0 (file_a->type, file_b->type) != 0)
return FALSE;
return TRUE;
}
static xmlNodePtr
filter_file_xml_encode (EFilterElement *element)
{
EFilterFile *file = E_FILTER_FILE (element);
xmlNodePtr cur, value;
const gchar *type;
type = file->type ? file->type : "file";
value = xmlNewNode (NULL, (xmlChar *)"value");
xmlSetProp (value, (xmlChar *) "name", (xmlChar *) element->name);
xmlSetProp (value, (xmlChar *) "type", (xmlChar *) type);
cur = xmlNewChild (value, NULL, (xmlChar *)type, NULL);
xmlNodeSetContent (cur, (xmlChar *)file->path);
return value;
}
static gint
filter_file_xml_decode (EFilterElement *element,
xmlNodePtr node)
{
EFilterFile *file = E_FILTER_FILE (element);
gchar *name, *str, *type;
xmlNodePtr child;
name = (gchar *)xmlGetProp (node, (xmlChar *) "name");
type = (gchar *)xmlGetProp (node, (xmlChar *) "type");
xmlFree (element->name);
element->name = name;
xmlFree (file->type);
file->type = type;
g_free (file->path);
file->path = NULL;
child = node->children;
while (child != NULL) {
if (!strcmp ((gchar *)child->name, type)) {
str = (gchar *)xmlNodeGetContent (child);
file->path = g_strdup (str ? str : "");
xmlFree (str);
break;
} else if (child->type == XML_ELEMENT_NODE) {
g_warning (
"Unknown node type '%s' encountered "
"decoding a %s\n", child->name, type);
}
child = child->next;
}
return 0;
}
static GtkWidget *
filter_file_get_widget (EFilterElement *element)
{
EFilterFile *file = E_FILTER_FILE (element);
GtkWidget *widget;
widget = gtk_file_chooser_button_new (
_("Choose a File"), GTK_FILE_CHOOSER_ACTION_OPEN);
gtk_file_chooser_set_filename (
GTK_FILE_CHOOSER (widget), file->path);
g_signal_connect (
widget, "selection-changed",
G_CALLBACK (filter_file_filename_changed), element);
return widget;
}
static void
filter_file_format_sexp (EFilterElement *element,
GString *out)
{
EFilterFile *file = E_FILTER_FILE (element);
e_sexp_encode_string (out, file->path);
}
static void
filter_file_class_init (EFilterFileClass *class)
{
GObjectClass *object_class;
EFilterElementClass *filter_element_class;
parent_class = g_type_class_peek_parent (class);
object_class = G_OBJECT_CLASS (class);
object_class->finalize = filter_file_finalize;
filter_element_class = E_FILTER_ELEMENT_CLASS (class);
filter_element_class->validate = filter_file_validate;
filter_element_class->eq = filter_file_eq;
filter_element_class->xml_encode = filter_file_xml_encode;
filter_element_class->xml_decode = filter_file_xml_decode;
filter_element_class->get_widget = filter_file_get_widget;
filter_element_class->format_sexp = filter_file_format_sexp;
}
GType
e_filter_file_get_type (void)
{
static GType type = 0;
if (G_UNLIKELY (type == 0)) {
static const GTypeInfo type_info = {
sizeof (EFilterFileClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) filter_file_class_init,
(GClassFinalizeFunc) NULL,
NULL, /* class_data */
sizeof (EFilterFile),
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
NULL /* value_table */
};
type = g_type_register_static (
E_TYPE_FILTER_ELEMENT, "EFilterFile", &type_info, 0);
}
return type;
}
/**
* filter_file_new:
*
* Create a new EFilterFile object.
*
* Return value: A new #EFilterFile object.
**/
EFilterFile *
e_filter_file_new (void)
{
return g_object_new (E_TYPE_FILTER_FILE, NULL);
}
EFilterFile *
e_filter_file_new_type_name (const gchar *type)
{
EFilterFile *file;
file = e_filter_file_new ();
file->type = (gchar *) xmlStrdup ((xmlChar *)type);
return file;
}
void
e_filter_file_set_path (EFilterFile *file,
const gchar *path)
{
g_return_if_fail (E_IS_FILTER_FILE (file));
g_free (file->path);
file->path = g_strdup (path);
}