aboutsummaryrefslogblamecommitdiffstats
path: root/e-util/e-filter-file.c
blob: 8e46b52a97ef0cd184d3d4126d14670ff2d26f45 (plain) (tree)





















                                                                             
                    
                   
      







                        
                    


                          



                              






















                                                            
                                                                       



                                              
                                     


                                                    
                                                         
 
                          

                                                                      






                                                                        
                                  
                                                                        
                                                                         


















                                                            

                                                                  























                                                                          

                                                                











                                                    

                                                               











                                

                                                                  






































                                                                      
                                                   


           
                                                  



                                                  











                                                                    

                                        
 




















                                                       
                                                            












                                                   
/*
 * 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 <http://www.gnu.org/licenses/>
 *
 *
 * Authors:
 *      Jeffrey Stedfast <fejj@ximian.com>
 *
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <sys/types.h>

#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>

#include "e-alert.h"
#include "e-filter-file.h"
#include "e-filter-part.h"

G_DEFINE_TYPE (
    EFilterFile,
    e_filter_file,
    E_TYPE_FILTER_ELEMENT)

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 (e_filter_file_parent_class)->finalize (object);
}

static gboolean
filter_file_validate (EFilterElement *element,
                      EAlert **alert)
{
    EFilterFile *file = E_FILTER_FILE (element);

    g_warn_if_fail (alert == NULL || *alert == NULL);

    if (!file->path) {
        if (alert)
            *alert = e_alert_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 (alert)
                *alert = e_alert_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 (e_filter_file_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);

    camel_sexp_encode_string (out, file->path);
}

static void
e_filter_file_class_init (EFilterFileClass *class)
{
    GObjectClass *object_class;
    EFilterElementClass *filter_element_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;
}

static void
e_filter_file_init (EFilterFile *filter)
{
}

/**
 * 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);
}