[mlview-list]patch xslt



Hi everebody

Here is a patch that makes mlview link with libxslt from gnome and
allows user to apply xslt transformations in mlview.

greetings, have fun

Stephane.

-- 
    Stéphane Bonhomme - Formations, Conseil et Réalisations
 Ingénierie Documentaire - Technologies Web - Logiciels Libres
   s bonhomme wanadoo fr - http://perso.wanadoo.fr/s.bonhomme
              04 76 17 09 40 / 06 88 57 27 08

? src/mlview-xslt-utils.c
? src/mlview-xslt-utils.h
Index: configure.in
===================================================================
RCS file: /cvs/gnome/mlview/configure.in,v
retrieving revision 1.48
diff -r1.48 configure.in
22a23
> LIBXSLT_VERSION=1.0.33
29a31
> AC_SUBST(LIBXSLT_VERSION)
97a100,104
> dnl checking for libxslt
> dnl *******************************
> PKG_CHECK_MODULES(LIBXSLT,[libxslt >= $LIBXSLT_VERSION])
> 
> dnl *******************************
128,129c135,136
< MLVIEW_LIBS="$LIBXML2_LIBS $LIBGLADE2_LIBS $LIBGNOMEUI2_LIBS"
< MLVIEW_CFLAGS="$LIBXML2_CFLAGS $LIBGLADE2_CFLAGS $LIBGNOMEUI2_CFLAGS"
---
> MLVIEW_LIBS="$LIBXML2_LIBS $LIBXSLT_LIBS $LIBGLADE2_LIBS $LIBGNOMEUI2_LIBS"
> MLVIEW_CFLAGS="$LIBXML2_CFLAGS $LIBXSLT_CFLAGS $LIBGLADE2_CFLAGS $LIBGNOMEUI2_CFLAGS"
157c164
< if test "x$USER" = "xdodji" -o "x$MLVIEW_DEVEL" = "xon" ; then
---
> if test "x$USER" = "waloo_" -o "x$MLVIEW_DEVEL" = "xon" ; then
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/mlview/src/Makefile.am,v
retrieving revision 1.29
diff -r1.29 Makefile.am
55c55,57
< 	mlview-icon-tree.h
---
> 	mlview-icon-tree.h \
> 	mlview-xslt-utils.c \
> 	mlview-xslt-utils.h
Index: src/mlview-app.c
===================================================================
RCS file: /cvs/gnome/mlview/src/mlview-app.c,v
retrieving revision 1.55
diff -r1.55 mlview-app.c
512a513,526
> apply_xslt_cb (GtkWidget * a_menu_item,
>                          MlViewAppContext * a_context)
> {
>         MlViewEditor *editor;
> 
>         g_return_if_fail (a_context != NULL);
>         g_return_if_fail (a_menu_item != NULL);
> 
>         editor = mlview_app_context_get_element (a_context,
>                                                  "MlViewEditor");
>         mlview_xslt_transform_document_interactive (editor) ;
> }
> 
> static void
673a688,694
> 
>         GNOMEUIINFO_SEPARATOR,
> 
>         GNOMEUIINFO_ITEM (N_("Apply XSLT..."),
>                           N_
>                           ("transform document using xslt stylesheet"),
>                           apply_xslt_cb, NULL),
Index: src/mlview-editor.c
===================================================================
RCS file: /cvs/gnome/mlview/src/mlview-editor.c,v
retrieving revision 1.63
diff -r1.63 mlview-editor.c
34a35
> #include "mlview-xslt-utils.h"
181a183,184
> static GList *build_doc_list_from_hashtable (GHashTable * a_docs);
> 
780a784,793
> static GList *
> build_doc_list_from_hashtable (GHashTable * a_docs)
> {
>         GList *result = NULL;
> 
>         g_hash_table_foreach (a_docs,
>                               (GHFunc) add_hash_key_to_list,
>                               &result);
>         return result;
> }
1148a1162,1180
>  *Getter of the glist of opened docs
>  *#MlViewXMLDocument *
>  *
>  * param a_this the current instance of #MlViewEditor.
>  * return a GList* of #MlViewXMLDocument, taht the caller 
>  * is responsble to free
>  */
> GList *
> mlview_editor_get_list_open_doc (MlViewEditor * a_this)
> {
>    GList *docs = NULL;
> 
>    docs = build_doc_list_from_hashtable
>                 (PRIVATE (a_this)->mlview_xml_docs);
> 
>    return docs;
> }
> 
> /**
2305a2338,2366
> }
> 
> 
> /**
>  *Applies a XSLT stylesheet to the current document
>  *displaying a dialog for xslt selection and opens
>  *the transformation resulting document in the editor
>  * param a_this the current instance of #MlViewEditor.
>  *
>  */
> gint
> mlview_xslt_transform_document_interactive (MlViewEditor *a_this)
> {
>         MlViewXMLDocument *src_doc = NULL;
>         MlViewXMLDocument *xsl_doc = NULL;
>         MlViewXMLDocument *res_doc = NULL;
> 
>         g_return_val_if_fail (a_this != NULL, -1);
>         g_return_val_if_fail (MLVIEW_IS_EDITOR (a_this), -1);
>         g_return_val_if_fail (PRIVATE (a_this) != NULL, -1);
>         
>         src_doc = mlview_editor_get_cur_doc (a_this);
>         xsl_doc = mlview_xslt_select_xsl_doc (a_this);
>         if (xsl_doc != NULL) {
>                 res_doc = mlview_xslt_transform_document(src_doc, xsl_doc);
>                 mlview_xml_document_unref(xsl_doc);
>                 if (res_doc != NULL) 
>                         mlview_editor_create_new_view_on_document (a_this, res_doc, MLVIEW_XML_DOC_TREE_VIEW);
>         }
Index: src/mlview-editor.h
===================================================================
RCS file: /cvs/gnome/mlview/src/mlview-editor.h,v
retrieving revision 1.30
diff -r1.30 mlview-editor.h
115a116,117
> GList *mlview_editor_get_list_open_doc (MlViewEditor * a_this);
> 
218a221
> gint mlview_xslt_transform_document_interactive (MlViewEditor *a_this);
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8-*- */

/*
 *This file is part of MlView
 *
 *MlView is free software; you can redistribute it and/or 
 *modify it under the terms of 
 *the GNU General Public License as published 
 *by the Free Software Foundation; either version 2
 *or (at your option) any later version.
 *
 *MlView 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 General Public License for more details.
 *
 *You should have received a copy of the 
 *GNU General Public License along with MlView.
 *see the file COPYING. 
 *If not, write to the 
 *Free Software Foundation, 
 *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *See COPYRIGHT file for copyright information.
 */

#include <stdio.h>
#include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
#include "mlview-editor.h"
#include "mlview-utils.h"
#include "mlview-xml-document.h"
#include "mlview-xslt-utils.h"

/**
 * file 
 *The mlview xslt transformer
 * 
 *This is a wrapper of the libxslt from Daniel Veillard.
 *It provides an interface to apply a xslt stylesheet to 
 *xml document opened in mlview. 
 *
 */

#define PRIVATE(object) (object)->priv

/*======================================================
 *private helper functions
 *=====================================================*/

/**
 * Checks whether a mlview document is an xslt stylesheet
 * The test is performed on the namespaces declared on
 * the root node of the document 
 * param mlv_xml_doc : the document to test
 * return TRUE if the document is a xslt stylesheet,
 *FALSE otherwise.
 */ 
gboolean
mlview_xslt_is_xslt_doc(MlViewXMLDocument* mlv_xml_doc)
{
        xmlDocPtr xml_doc;
        xmlNodePtr root_node;

        xmlNs *cur_ns = NULL ;
        gint found=FALSE;
        
        xml_doc = mlview_xml_document_get_xml_document(mlv_xml_doc);
        root_node = xmlDocGetRootElement (xml_doc);
        for (cur_ns = root_node->nsDef ;
             !found && cur_ns; 
             cur_ns = cur_ns->next) {
                found = (gboolean)(!xmlStrcmp(cur_ns->href, 
                                              XSLT_NAMESPACE_URI));
        }
        return found;
}


/**
 *Applies a xslt stylesheet to a xml document
 *at libxml level
 * param src_doc : the libxml2 xmlDocPtr to the source doc
 * param xsl_doc : the libxml2 xmlDocPtr to the xslt stylesheet
 * return the xmlDocPtr to the result of the transformation
 *
 */ 
static xmlDocPtr
mlview_xslt_do_transform (xmlDocPtr src_doc,
                          xmlDocPtr xsl_doc)
{
        xmlDocPtr res_doc;
        xmlDocPtr xsl_copy_doc;        
        xsltStylesheetPtr xsl_stylesheet=NULL; 
	const char *params[16+1];
        params[0] = NULL;

        /* makes a copy of the stylesheet */
        xsl_copy_doc = xmlCopyDoc (xsl_doc, 1);
        xsl_stylesheet = xsltParseStylesheetDoc (xsl_copy_doc);
        res_doc = xsltApplyStylesheet(xsl_stylesheet, src_doc, params);
        xsltFreeStylesheet(xsl_stylesheet);
        return res_doc;
}


/**
 *Applies a xslt stylesheet to a xml document
 *at mlview level
 * param src_doc : the libxml2 xmlDocPtr to the source doc
 * param xsl_doc : the libxml2 xmlDocPtr to the xslt stylesheet
 * return the xmlDocPtr to the result of the transformation
 *
 */ 
static MlViewXMLDocument*
mlview_xslt_do_mlview_transform (MlViewXMLDocument* mlv_src_doc,
                                 MlViewXMLDocument* mlv_xsl_doc)
{
        MlViewXMLDocument* mlv_res_doc = NULL;
        MlViewAppContext *app_context;
        xmlDocPtr src_doc, xsl_doc, res_doc;

        app_context = mlview_xml_document_get_app_context(mlv_src_doc); 
        src_doc = mlview_xml_document_get_xml_document(mlv_src_doc);
        xsl_doc = mlview_xml_document_get_xml_document(mlv_xsl_doc);
        res_doc = mlview_xslt_do_transform (src_doc, xsl_doc);
        if (res_doc != NULL) {
                mlv_res_doc = mlview_xml_document_new (res_doc, app_context);
        } else {
                mlview_utils_display_error_dialog (app_context, 
                                                   "%s",  
                                                   _("XSLT transformation failed"));
        }
                
        return mlv_res_doc;
}


/** 
 *
 *Shows a file chooser dialog to select an external stylesheet
 *Loads the file selected, and performs a xslt namespace check
 * param a_this : mlview editor context
 * return the document selected or NULL if user cancels or 
 *document is not an xslt stylesheet
 * 
 */
static MlViewXMLDocument*
mlview_xslt_stylesheet_choose_and_open (MlViewEditor *a_this)
{
        GtkWidget *file_sel;
        enum MLVIEW_SELECTED_BUTTON result_file_sel;
        gchar *file_name = NULL;
        MlViewXMLDocument *mlv_xsl_doc = NULL;
        MlViewAppContext *app_context = NULL;

        file_sel = mlview_file_selection_new();
        result_file_sel=mlview_file_selection_run(MLVIEW_FILE_SELECTION(file_sel), TRUE);
        switch (result_file_sel) {
        case OK_BUTTON:
                file_name = g_strdup (gtk_file_selection_get_filename
                                      (GTK_FILE_SELECTION
                                       (file_sel)));
                
                if (file_name && strcmp (file_name, "")) {
                        /* mlview_editor_load_xml_file (a_this, file_name); */
                        app_context = mlview_editor_get_app_context(a_this);
                        mlv_xsl_doc = mlview_xml_document_open(file_name, app_context);
                        mlview_xml_document_ref(mlv_xsl_doc);
                        if (!mlview_xslt_is_xslt_doc(mlv_xsl_doc)) {
                                /*display error box and close doc*/
                                mlview_utils_display_error_dialog (app_context, 
                                                                   "%s",  
                                                                   _("document is not an XSLT Stylesheet"));
                                mlview_xml_document_unref(mlv_xsl_doc);
                                mlv_xsl_doc=NULL;
                        }
                }
                if (file_name) {
                        g_free (file_name);
                        file_name = NULL;
                }                     
                break;
        case CANCEL_BUTTON:
        case WINDOW_CLOSED:
        default:
                break;
        }
        return mlv_xsl_doc;
}


/*=================================================
 *public methods
 *=================================================*/
 
/** 
 *
 *Shows the xslt chooser dialog
 * param a_this : mlview editor context
 * return the document selected or NULL if user cancels or 
 *document is not an xslt stylesheet
 * 
 */
MlViewXMLDocument*
mlview_xslt_select_xsl_doc  (MlViewEditor *a_this) 
{
        GtkWidget *dialog1;
        GtkWidget *dialog_vbox1;
        GtkWidget *hbox1;
        GtkWidget *label1;
        GtkWidget *menu;
        GtkWidget *option_menu;
        GtkWidget *menu_item;
        GtkWidget *sel_menu_item;
        GtkWidget *dialog_action_area1;
        GtkWidget *button4;
        GtkWidget *button5;
        GtkWidget *button6;
        
        GList *docs, *mobile_doc_ptr;
        GList *xslt_docs = NULL;
        MlViewXMLDocument *mobile_mlv_doc;
        MlViewXMLDocument *mlv_xsl_doc=NULL;
        gchar *file_path, *base_name;
        gint result;

        g_return_val_if_fail (a_this != NULL, NULL);
        g_return_val_if_fail (MLVIEW_IS_EDITOR (a_this), NULL);
        g_return_val_if_fail (PRIVATE (a_this) != NULL, NULL);

        /* builds a GList of opened XSLT doc */

        docs = mlview_editor_get_list_open_doc (a_this);
        if (docs != NULL) {
                for (mobile_doc_ptr = g_list_first(docs);
                     mobile_doc_ptr;
                     mobile_doc_ptr = g_list_next(mobile_doc_ptr)) {
                        mobile_mlv_doc = MLVIEW_XML_DOCUMENT(mobile_doc_ptr->data);
                        if (mlview_xslt_is_xslt_doc(mobile_mlv_doc)) {
                                xslt_docs = g_list_append (xslt_docs, (gpointer)mobile_mlv_doc);
                        }
                }
        }
        
        /* build dialog window */

        dialog1 = gtk_dialog_new ();
        gtk_window_set_title (GTK_WINDOW (dialog1), _("Select XSLT"));
        
        dialog_vbox1 = GTK_DIALOG (dialog1)->vbox;
        gtk_widget_show (dialog_vbox1);
        
        hbox1 = gtk_hbox_new (FALSE, 0);
        gtk_widget_show (hbox1);
        gtk_box_pack_start (GTK_BOX (dialog_vbox1), hbox1, TRUE, TRUE, 0);
        
        if (xslt_docs != NULL) {
                label1 = gtk_label_new (_("Select xslt stylesheet"));
        } else {
                label1 = gtk_label_new (_("No xslt stylesheet is open"));
        }
        gtk_widget_show (label1);
        gtk_box_pack_start (GTK_BOX (hbox1), label1, FALSE, FALSE, 10);
        
        /* build select xslt menu */
        
        if (xslt_docs != NULL) {
                option_menu = gtk_option_menu_new();
                menu = gtk_menu_new();
                gtk_option_menu_set_menu (GTK_OPTION_MENU(option_menu), menu);
                
                gtk_widget_show (menu);
                gtk_widget_show (option_menu);
                
                gtk_box_pack_start (GTK_BOX (hbox1), option_menu, TRUE, TRUE, 0);
  
                for (mobile_doc_ptr = g_list_first(xslt_docs);
                     mobile_doc_ptr;
                     mobile_doc_ptr = g_list_next(mobile_doc_ptr)) {
                                mobile_mlv_doc = MLVIEW_XML_DOCUMENT(mobile_doc_ptr->data);
                                file_path = mlview_xml_document_get_file_path (mobile_mlv_doc);
                                base_name = (gchar *) g_basename (file_path);
                                menu_item = gtk_menu_item_new_with_label(base_name);
                                gtk_menu_shell_append (GTK_MENU_SHELL(menu),  menu_item);
                                gtk_widget_show(menu_item);
                                g_object_set_data (G_OBJECT(menu_item), "mlview_doc", mobile_mlv_doc);
                }
                gtk_option_menu_set_history(GTK_OPTION_MENU(option_menu), 0);
        }
        
        /** end menu **/
       
        dialog_action_area1 = GTK_DIALOG (dialog1)->action_area;
        gtk_widget_show (dialog_action_area1);
        gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
 
        button4 = gtk_button_new_with_mnemonic (_("Browse..."));
        gtk_widget_show (button4);
        gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button4, MLVIEW_XSLT_RESPONSE_BROWSE);
        GTK_WIDGET_SET_FLAGS (button4, GTK_CAN_DEFAULT);
        
        button5 = gtk_button_new_from_stock ("gtk-cancel");
        gtk_widget_show (button5);
        gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button5, GTK_RESPONSE_CANCEL);
        GTK_WIDGET_SET_FLAGS (button5, GTK_CAN_DEFAULT);
        
        if (xslt_docs != NULL) {
                button6 = gtk_button_new_from_stock ("gtk-ok");
                gtk_widget_show (button6);
                gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button6, GTK_RESPONSE_OK);  
                GTK_WIDGET_SET_FLAGS (button6, GTK_CAN_DEFAULT);
        }

        /* runs the dialog box */
        result = gtk_dialog_run (GTK_DIALOG (dialog1));
        switch (result) {
        case GTK_RESPONSE_OK:
                sel_menu_item = gtk_menu_get_active(GTK_MENU(menu));                
                mlv_xsl_doc = g_object_get_data (G_OBJECT(sel_menu_item), "mlview_doc");
                break;
        case GTK_RESPONSE_CANCEL:
                break;
        case MLVIEW_XSLT_RESPONSE_BROWSE:
                mlv_xsl_doc = mlview_xslt_stylesheet_choose_and_open(a_this);
                break;
        }

        g_list_free(docs);
        g_list_free(xslt_docs);
        gtk_widget_destroy (dialog1);

        return mlv_xsl_doc;
}


/**
 *Applies a XSLT stylesheet to an mlview document
 *
 * param src_doc the source mlview xml document
 * param xsl_doc the xslt mlview xml document
 * result the document resuting of the transformation
 * or NULL if it fails
 *
 */
MlViewXMLDocument *
mlview_xslt_transform_document (MlViewXMLDocument *src_doc, 
                                MlViewXMLDocument *xsl_doc)
{
        g_return_val_if_fail (src_doc != NULL, NULL);
        g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (src_doc),
                              NULL);
        g_return_val_if_fail (xsl_doc != NULL, NULL);
        g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (xsl_doc),
                              NULL);

        MlViewXMLDocument *res_doc = NULL;
        res_doc = mlview_xslt_do_mlview_transform(src_doc, xsl_doc);
        return res_doc;
}
#ifndef __mlview_xslt_utils_XSLT_UTILS_H__
#define __mlview_xslt_utils_XSLT_UTILS_H__

#include	<glib-object.h>

G_BEGIN_DECLS

/* xslt namespace uri */
#define XSLT_NAMESPACE_URI "http://www.w3.org/1999/XSL/Transform";

/* select xslt form response */
#define MLVIEW_XSLT_RESPONSE_BROWSE 3

MlViewXMLDocument *mlview_xslt_select_xsl_doc  (MlViewEditor *a_this);
MlViewXMLDocument *mlview_xslt_transform_document (MlViewXMLDocument *src_doc, MlViewXMLDocument *xsl_doc);

G_END_DECLS

#endif /* __mlview_xslt_utils_XSLT_UTILS_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]