Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

mlview-xml-document.c

Go to the documentation of this file.
00001 /*
00002  *This file is part of MlView
00003  *
00004  *MlView is free software; you can redistribute it and/or modify it under the terms of 
00005  *the GNU General Public License as published by the Free Software Foundation; either version 2, 
00006  *or (at your option) any later version.
00007  *
00008  *MlView is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
00009  *without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00010  *See the GNU General Public License for more details.
00011  *
00012  *You should have received a copy of the GNU General Public License along with MlView; 
00013  *see the file COPYING. If not, write to the Free Software Foundation, 
00014  *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00015  *
00016  *
00017  *Copyright 2001-2002 Dodji Seketeli.
00018  */
00019 
00020 #include <libxml/tree.h>
00021 #include <libxml/valid.h>
00022 
00023 #include "mlview-xml-document.h"
00024 #include "mlview-parsing-utils.h"
00025 #include "mlview-settings-management.h"
00026 #include "mlview-file-selection.h"
00027 #include "mlview-file-descriptor.h"
00028 #include "mlview-global-settings.h"
00029 #include "utils.h"
00030 
00031 /*FIXME: remove all the references to ->tree_view.
00032  *Make sure to transform then in wrappers of the daniel veillard's libxml.
00033  *That way, all the real actions made on the underlying xml data structure will
00034  *be made through this object. This object will then emit signals to
00035  *notify it's state to all the views that are in relation with it. Of course, this
00036  *object should not know anything about the views that holds it ...
00037  *
00038  *Damn, i think we gonna turn this gnome-mlview into a nice piece of software. :)
00039  */
00040 struct _MlViewXMLDocumentPrivate
00041 {
00042         MlViewFileDescriptor *file_desc ;
00043         /*MlViewXMLDocTreeView * tree_view ;*/
00044 
00045         /*the underlying xml doc data structure*/
00046         xmlDocPtr xml_doc ;
00047 
00048         /*the current xml application context*/
00049         MlViewAppContext * app_context ;
00050 };
00051 
00052 enum {
00053         DOCUMENT_CHANGED = 0 ,
00054         NODE_CUT,
00055         CHILD_NODE_ADDED,
00056         PREV_SIBLING_NODE_INSERTED,
00057         NEXT_SIBLING_NODE_INSERTED,
00058         CONTENT_CHANGED,
00059         NAME_CHANGED,
00060         NODE_CHANGED,
00061         FILE_PATH_CHANGED,
00062         NUMBER_OF_SIGNALS
00063 } ;
00064 
00065 #define PRIVATE(mlview_xml_doc) (mlview_xml_doc->private)
00066 #define MLVIEW_XML_DOCUMENT_DEFAULT_VALIDATION_ON FALSE ;
00067 
00068 
00069 static void 
00070 mlview_xml_document_do_interactive_validation_if_needed (MlViewXMLDocument * a_doc) ;
00071 
00072 static gint 
00073 mlview_xml_document_validate_xml_doc_against_a_dtd (MlViewXMLDocument * a_doc, 
00074                                                     MlViewExternalSubsetDefinition * 
00075                                                     a_subset_def) ;
00076 
00077 static void mlview_xml_document_destroy (GtkObject *a_xml_doc) ;
00078 
00079 #define MLVIEW_XML_DOCUMENT_NODE_CLIPBOARD_SIZE 128
00080 static GtkObjectClass *gv_parent_class = NULL ;
00081 static guint gv_mlview_xml_document_signals [NUMBER_OF_SIGNALS] = {0} ;
00082 static xmlNode * gv_clipboard[MLVIEW_XML_DOCUMENT_NODE_CLIPBOARD_SIZE] = {0} ;
00083 static guint gv_clipboard_index = 0 ;
00084 
00085 /*======================================================
00086  *private helper functions
00087  *=====================================================*/
00088 
00092 static void
00093 mlview_xml_document_do_interactive_validation_if_needed (MlViewXMLDocument * a_doc)
00094 {
00095         gchar * validation_is_on = NULL ;
00096 
00097         g_return_if_fail(a_doc != NULL) ;
00098         g_return_if_fail(PRIVATE(a_doc) != NULL) ;
00099         g_return_if_fail(PRIVATE(a_doc)->xml_doc != NULL) ;
00100 
00101         if (PRIVATE (a_doc)->app_context)
00102                 validation_is_on = 
00103                         mlview_app_context_get_settings_value (PRIVATE (a_doc)->app_context,
00104                                                                MLVIEW_STG_K_IS_VALIDATION_ON) ;
00105         
00106         if (validation_is_on
00107             && (strcmp (validation_is_on, MLVIEW_STG_V_YES) == 0)) {
00108                 
00109                 mlview_xml_document_validate (a_doc) ;
00110         }                  
00111 }
00112 
00113 
00114 
00115 /*
00116  *mlview_xml_document_validate_xml_doc_against_a_dtd:
00117  *@a_doc:The document to validate
00118  *@a_subset_def: a description of the DTD.
00119  *
00120  *Loads the DTD pointed by a_subset_def and validate it.
00121  *Note that if the doc contains a dtd already, that dtd is overloaded by the new one
00122  *without being freed.
00123  *
00124  *FIXME: this function does not support catalog/remote dtd so far. It only support dtds that
00125  *are on the local disk.
00126  *
00127  *Returns 0 if validation went well, >0 if validation failed, <0 if could not even start validation.
00128  *The possible return values are:
00129  *-3 one of the parameter is not correct.
00130  * 0 the document is valid against the Dtd
00131  * 1 the document is not valid against the dtd.
00132  * 2 parsing of the dtd failed.
00133  */
00134 static gint
00135 mlview_xml_document_validate_xml_doc_against_a_dtd (MlViewXMLDocument * a_doc,
00136                                                     MlViewExternalSubsetDefinition * a_subset_def)
00137 {
00138         gint validity_status=1 ;
00139 
00140         g_return_val_if_fail(a_doc != NULL, -3) ;
00141         g_return_val_if_fail(PRIVATE(a_doc) != NULL, -3) ;
00142         g_return_val_if_fail(PRIVATE(a_doc)->xml_doc != NULL, -3) ;
00143         g_return_val_if_fail(a_subset_def != NULL, -3) ;
00144 
00145         if ( !mlview_xml_document_associate_dtd(a_doc, a_subset_def) ) 
00146                 validity_status = mlview_xml_document_validate(a_doc) ;
00147         else
00148                 validity_status = 2; /*association (probably dtd parsing) failed*/
00149 
00150         return validity_status ;
00151 }
00152 
00153 /***********************************************
00154  *private gtk framework methods                                         
00155  ***********************************************/
00156 static void
00157 mlview_xml_document_init_class (MlViewXMLDocumentClass * a_klass)
00158 {
00159         GtkObjectClass * object_class = NULL ;
00160 
00161         g_return_if_fail (a_klass != NULL) ;
00162         g_return_if_fail (MLVIEW_IS_XML_DOCUMENT_CLASS (a_klass)) ;
00163 
00164         object_class = GTK_OBJECT_CLASS (a_klass) ;
00165         gv_parent_class = gtk_type_class (GTK_TYPE_OBJECT) ;
00166         object_class->destroy = mlview_xml_document_destroy ;
00167 
00168         /*signal creation code*/
00169         gv_mlview_xml_document_signals[DOCUMENT_CHANGED] = 
00170                 gtk_signal_new ("document-changed",
00171                                 GTK_RUN_FIRST,
00172                                 object_class->type,
00173                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass,
00174                                                    document_changed),
00175                                 gtk_marshal_NONE__NONE,
00176                                 GTK_TYPE_NONE, 0) ;
00177 
00178         gv_mlview_xml_document_signals[NODE_CUT] = 
00179                 gtk_signal_new ("node-cut",
00180                                 GTK_RUN_FIRST,
00181                                 object_class->type,
00182                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass, node_cut),
00183                                 gtk_marshal_NONE__POINTER_POINTER,
00184                                 GTK_TYPE_NONE, 2, 
00185                                 GTK_TYPE_POINTER, GTK_TYPE_POINTER) ;
00186 
00187         gv_mlview_xml_document_signals [CHILD_NODE_ADDED] = 
00188                 gtk_signal_new ("child-node-added",
00189                                 GTK_RUN_FIRST,
00190                                 object_class->type,
00191                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass, child_node_added),
00192                                 gtk_marshal_NONE__POINTER_POINTER,
00193                                 GTK_TYPE_NONE, 2, 
00194                                 GTK_TYPE_POINTER, GTK_TYPE_POINTER) ;
00195 
00196         gv_mlview_xml_document_signals [PREV_SIBLING_NODE_INSERTED] = 
00197                 gtk_signal_new ("prev-sibling-node-inserted",
00198                                 GTK_RUN_FIRST,
00199                                 object_class->type,
00200                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass, prev_sibling_node_inserted),
00201                                 gtk_marshal_NONE__POINTER_POINTER,
00202                                 GTK_TYPE_NONE, 2, 
00203                                 GTK_TYPE_POINTER, GTK_TYPE_POINTER) ;
00204 
00205         gv_mlview_xml_document_signals [NEXT_SIBLING_NODE_INSERTED] = 
00206                 gtk_signal_new ("next-sibling-node-inserted",
00207                                 GTK_RUN_FIRST,
00208                                 object_class->type,
00209                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass, next_sibling_node_inserted),
00210                                 gtk_marshal_NONE__POINTER_POINTER,
00211                                 GTK_TYPE_NONE, 2, 
00212                                 GTK_TYPE_POINTER, GTK_TYPE_POINTER) ;
00213 
00214         gv_mlview_xml_document_signals [CONTENT_CHANGED] = 
00215                 gtk_signal_new ("content-changed",
00216                                 GTK_RUN_FIRST,
00217                                 object_class->type,
00218                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass, content_changed),
00219                                 gtk_marshal_NONE__POINTER,
00220                                 GTK_TYPE_NONE, 1, 
00221                                 GTK_TYPE_POINTER) ;
00222 
00223         gv_mlview_xml_document_signals [NAME_CHANGED] = 
00224                 gtk_signal_new ("name-changed",
00225                                 GTK_RUN_FIRST,
00226                                 object_class->type,
00227                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass, 
00228                                                    name_changed),
00229                                 gtk_marshal_NONE__POINTER,
00230                                 GTK_TYPE_NONE, 1, 
00231                                 GTK_TYPE_POINTER) ;
00232 
00233         gv_mlview_xml_document_signals [NODE_CHANGED] = 
00234                 gtk_signal_new ("node-changed",
00235                                 GTK_RUN_FIRST,
00236                                 object_class->type,
00237                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass, 
00238                                                    node_changed),
00239                                 gtk_marshal_NONE__POINTER,
00240                                 GTK_TYPE_NONE, 1, 
00241                                 GTK_TYPE_POINTER) ;
00242 
00243         gv_mlview_xml_document_signals [FILE_PATH_CHANGED] =
00244                 gtk_signal_new ("file-path-changed",
00245                                 GTK_RUN_FIRST,
00246                                 object_class->type,
00247                                 GTK_SIGNAL_OFFSET (MlViewXMLDocumentClass, 
00248                                                    file_path_changed),
00249                                 gtk_marshal_NONE__NONE,
00250                                 GTK_TYPE_NONE, 0) ;
00251 
00252         gtk_object_class_add_signals (object_class, 
00253                                       gv_mlview_xml_document_signals, 
00254                                       NUMBER_OF_SIGNALS) ;
00255 
00256         a_klass->document_changed = NULL ;
00257         a_klass->node_cut = NULL ;
00258         a_klass->child_node_added = NULL ;
00259         a_klass->node_changed = NULL ;
00260         a_klass->content_changed = NULL ;
00261         a_klass->name_changed = NULL ;
00262 }
00263 
00264 
00265 static void
00266 mlview_xml_document_init (MlViewXMLDocument * a_xml_doc)
00267 
00268 {
00269         g_return_if_fail (a_xml_doc != NULL) ;
00270         g_return_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_doc)) ;
00271 
00272         PRIVATE (a_xml_doc) = g_malloc0(sizeof(MlViewXMLDocumentPrivate)) ;
00273 }
00274 
00275 /*=============================================
00276  *public methods
00277  *=============================================*/
00278 
00279 guint 
00280 mlview_xml_document_get_type (void)
00281 {
00282         static guint mlview_xml_document_type = 0 ;
00283         
00284         if (!mlview_xml_document_type) {
00285                 static const GtkTypeInfo t_info = {
00286                         "MlViewXMLDocument",
00287                         sizeof (MlViewXMLDocument),
00288                         sizeof (MlViewXMLDocumentClass) ,
00289                         (GtkClassInitFunc) mlview_xml_document_init_class,
00290                         (GtkObjectInitFunc) mlview_xml_document_init,
00291                         NULL, NULL, NULL
00292                 } ;
00293                 mlview_xml_document_type = gtk_type_unique (GTK_TYPE_OBJECT, &t_info) ;
00294         }
00295         return mlview_xml_document_type ;
00296 }
00297 
00298 
00306 MlViewXMLDocument *
00307 mlview_xml_document_new (xmlDocPtr a_xml_doc, MlViewAppContext *a_context)
00308 {
00309         MlViewXMLDocument *result = NULL ;
00310         xmlDocPtr xml_doc=NULL ;
00311         xmlNodePtr xml_node ;
00312 
00313         result = gtk_type_new (MLVIEW_TYPE_XML_DOCUMENT) ;
00314 
00315         xml_doc = a_xml_doc ;
00316 
00317         if (xml_doc == NULL) {
00318                 xml_doc = xmlNewDoc ("1.0") ;
00319                 xml_node = xmlNewNode (NULL, "") ;
00320                 xmlDocSetRootElement (xml_doc, xml_node) ;
00321         }
00322 
00323         PRIVATE (result)->xml_doc = xml_doc ;
00324         PRIVATE (result)->app_context = a_context ;
00325         return result ;
00326 }
00327 
00328 
00336 void
00337 mlview_xml_document_set_app_context (MlViewXMLDocument * a_doc, 
00338                                      MlViewAppContext * a_context)
00339 {
00340         g_return_if_fail (a_doc != NULL) ;
00341         g_return_if_fail (PRIVATE (a_doc) != NULL) ;
00342         g_return_if_fail (a_context != NULL) ;
00343         g_return_if_fail (MLVIEW_IS_APP_CONTEXT (a_context)) ;
00344 
00345 
00346         PRIVATE (a_doc)->app_context = a_context ;
00347 }
00348 
00349 
00356 MlViewAppContext *
00357 mlview_xml_document_get_app_context (MlViewXMLDocument * a_doc) 
00358 {
00359         g_return_val_if_fail (a_doc, NULL) ;
00360         g_return_val_if_fail (PRIVATE (a_doc) != NULL, NULL) ;
00361         
00362         return PRIVATE (a_doc)->app_context ;
00363 }
00364 
00365 
00366 /************************************
00367  *clipboard methods.
00368  ***********************************/
00369 
00378 void
00379 mlview_xml_document_copy_node_to_clipboard (xmlNode *a_xml_node, 
00380                                            xmlDoc *a_doc)
00381 {
00382         g_return_if_fail (a_xml_node != NULL) ;
00383 
00384         g_return_if_fail (sizeof (gv_clipboard) / sizeof (xmlNodePtr) > 0) ;
00385 
00386         if (gv_clipboard_index >= sizeof (gv_clipboard) / sizeof (xmlNodePtr))
00387                 gv_clipboard_index = 0 ;
00388         gv_clipboard[gv_clipboard_index] = xmlDocCopyNode (a_xml_node, a_doc , TRUE) ;
00389         gv_clipboard_index ++ ;
00390 }
00391 
00392 
00400 xmlNode *
00401 mlview_xml_document_get_node_from_clipboard (xmlDoc * a_xml_doc)
00402 {
00403         xmlNodePtr xml_node=NULL ;
00404 
00405         g_return_val_if_fail(sizeof(gv_clipboard)/sizeof(xmlNodePtr) > 0, NULL) ;
00406         if(gv_clipboard_index >= sizeof(gv_clipboard)/sizeof(xmlNodePtr))
00407                 gv_clipboard_index = sizeof(gv_clipboard)/sizeof(xmlNodePtr) - 1 ;
00408 
00409         xml_node = gv_clipboard[gv_clipboard_index - 1] ;
00410         if(xml_node != NULL)
00411                 xml_node = xmlDocCopyNode (xml_node, a_xml_doc, 1) ;/*make a recursive copy of the node*/
00412         return xml_node ;
00413 }
00414 
00415 
00416 /*************************************
00417  *Other miscellaneous methods
00418  *************************************/
00419 
00428 MlViewXMLDocument *
00429 mlview_xml_document_open (gchar * a_file_name, MlViewAppContext * a_context)
00430 {
00431         MlViewXMLDocument *result = NULL;
00432 
00433         xmlDoc * xml_doc ;
00434 
00435         xml_doc = mlview_parsing_utils_load_xml_file (a_file_name, a_context) ;
00436         g_return_val_if_fail (xml_doc != NULL , NULL) ;
00437 
00438         result = mlview_xml_document_new(xml_doc, a_context) ;
00439 
00440         mlview_xml_document_do_interactive_validation_if_needed(result) ;       
00441         mlview_xml_document_set_file_path(result, a_file_name) ;
00442 
00443         return result;
00444 }
00445 
00457 gint
00458 mlview_xml_document_associate_dtd_interactive (MlViewXMLDocument * a_doc)
00459 {
00460         MlViewExternalSubsetDefinition * external_subset_def ;
00461 
00462         g_return_val_if_fail (a_doc != NULL, -1) ;
00463         g_return_val_if_fail (PRIVATE (a_doc) != NULL, -1) ;
00464         g_return_val_if_fail (PRIVATE (a_doc)->app_context != NULL, -1) ;
00465 
00466         external_subset_def = 
00467                 mlview_parsing_utils_let_user_choose_a_dtd (PRIVATE (a_doc)->app_context, 
00468                                                             _("Choose a Dtd to associate to the document")) ;
00469         if ( external_subset_def ) {
00470                 return mlview_xml_document_associate_dtd(a_doc,
00471                                                          external_subset_def) ;         
00472         } else {
00473                 return 1 ;
00474         }
00475 }
00476 
00477 
00486 gint
00487 mlview_xml_document_associate_dtd ( MlViewXMLDocument * a_doc, 
00488                                     MlViewExternalSubsetDefinition * a_ext_subs_def)
00489 {
00490         xmlDtd * dtd=NULL ;
00491         gboolean user_cancels=FALSE ;
00492 
00493         g_return_val_if_fail(a_doc != NULL, -1) ;
00494         g_return_val_if_fail(PRIVATE(a_doc) != NULL, -1) ;
00495 
00496         /*if an external subset already exists, ask the user if she wants to overide it*/
00497         if ( PRIVATE(a_doc)->xml_doc && PRIVATE(a_doc)->xml_doc->extSubset ) {
00498                 GnomeDialog * dialog ;
00499                 GtkWidget * label ;
00500                 gint button ;
00501 
00502                 dialog = GNOME_DIALOG(gnome_dialog_new(_("Document has already has a Dtd"),
00503                                                        _("YES"),_("CANCEL"), NULL)) ;
00504                 label = gtk_label_new(_("This Document already has an associated Dtd.\nDo you want really want to associate another Dtd to this document ?")) ;
00505                 gtk_box_pack_start(GTK_BOX(dialog->vbox),
00506                                    label, TRUE,FALSE,0) ;
00507                 gtk_widget_show_all(dialog->vbox) ;
00508                 gnome_dialog_close_hides(dialog, FALSE) ;
00509                 gnome_dialog_set_close (dialog, TRUE) ;
00510                 button = gnome_dialog_run(dialog) ;
00511 
00512                 switch ( button ) {
00513                 case 0:/*YES button*/
00514                         break ;
00515                 default :/*CANCEL Button, dialog box closed etc..*/
00516                         user_cancels = TRUE ;
00517                         break ;
00518                 }
00519         }/*end if*/
00520         
00521         if ( user_cancels == TRUE )
00522                 return 1 ;/*user cancelled operations*/
00523 
00524         /*if the user did not cancel the operations, let's do the association*/
00525         
00526         /*let's parse the external subset. 
00527          *If parsing is OK, we associate that dtd to
00528          *the document.
00529          */
00530         if ( a_ext_subs_def->system_id  
00531              &&  strcmp(a_ext_subs_def->system_id, "")  
00532              &&  (dtd = mlview_parsing_utils_load_a_dtd (a_ext_subs_def, PRIVATE(a_doc)->app_context)) ) {
00533                 
00534                 if (PRIVATE(a_doc)->xml_doc->extSubset) 
00535                         xmlFreeDtd(PRIVATE(a_doc)->xml_doc->extSubset) ;
00536                 PRIVATE(a_doc)->xml_doc->extSubset = dtd ;
00537                 return 0 ; /*dtd parsing OK, association OK*/
00538         }
00539 
00540         return 2 ;/*dtd parsing failed*/
00541 }
00542 
00543 
00551 gint
00552 mlview_xml_document_validate (MlViewXMLDocument * a_doc)
00553 {
00554         gint validity_status=-2 ;/*defaul value means "there is no dtd to parse"*/
00555 
00556         g_return_val_if_fail (a_doc != NULL, -1) ;
00557         g_return_val_if_fail (PRIVATE (a_doc) != NULL, -1) ;
00558         g_return_val_if_fail (PRIVATE (a_doc)->xml_doc, -1) ;
00559 
00560         if ( PRIVATE(a_doc)->xml_doc->extSubset )
00561                 validity_status = 
00562                         mlview_parsing_utils_validate_dtd (PRIVATE(a_doc)->xml_doc,
00563                                                            PRIVATE(a_doc)->xml_doc->extSubset,
00564                                                            PRIVATE(a_doc)->app_context) ;
00565         else {
00566                 mlview_app_context_warning (PRIVATE (a_doc)->app_context, _("No DTD was provided. Could not validate the document"))  ;
00567                 return validity_status ;
00568         }
00569 
00570         /*If the document is valid, tell the user.*/
00571         if (! validity_status )
00572                 mlview_app_context_message (PRIVATE (a_doc)->app_context, _("The Document is valid :-)")) ;
00573         else
00574                 mlview_app_context_warning (PRIVATE (a_doc)->app_context, _("The Document is not valid !"))  ;
00575 
00576         return validity_status ;
00577 }
00578 
00579 
00587 gint
00588 mlview_xml_document_save (MlViewXMLDocument * a_doc)
00589 {
00590         MlViewFileDescriptor * file_desc ;
00591         gchar * file_path ;
00592         xmlDocPtr xml_doc ;
00593 
00594         g_return_val_if_fail(a_doc != NULL, -1) ;
00595         g_return_val_if_fail(PRIVATE(a_doc) != NULL, -1) ;
00596 
00597         xml_doc = PRIVATE(a_doc)->xml_doc ;
00598         g_return_val_if_fail(xml_doc != NULL, -1) ;
00599 
00600         file_desc = mlview_xml_document_get_file_descriptor(a_doc) ;
00601         g_return_val_if_fail(file_desc != NULL, -1) ;
00602 
00603         file_path = mlview_file_descriptor_get_file_path(file_desc) ;
00604         g_return_val_if_fail(file_path != NULL, -1) ;
00605 
00606         return mlview_parsing_utils_save_xml_doc (xml_doc, file_path, PRIVATE(a_doc)->app_context) ;
00607 }
00608 
00609 
00618 gint
00619 mlview_xml_document_save_as (MlViewXMLDocument *a_doc, gchar * a_file_path)
00620 {
00621         gint result ;
00622         gchar * old_path ;
00623         g_return_val_if_fail (a_file_path != NULL, -1) ;
00624 
00625         /*store the old file path in case the save fails.*/
00626         old_path = g_strdup (mlview_xml_document_get_file_path (a_doc)) ;
00627 
00628         mlview_xml_document_set_file_path (a_doc, a_file_path) ;        
00629 
00630         if ( (result = mlview_xml_document_save (a_doc)) <= 0 )
00631                 mlview_xml_document_set_file_path (a_doc, old_path) ;
00632         g_free (old_path) ;
00633 
00634         return result ;
00635 }
00636 
00637 
00645 MlViewXMLDocument*
00646 mlview_xml_document_clone (MlViewXMLDocument *a_original)
00647 {        
00648         MlViewXMLDocument * result ;
00649         MlViewFileDescriptor * file_desc ;
00650         gchar * file_path ;
00651 
00652         if ( a_original == NULL )
00653                 return NULL ;
00654         file_desc = mlview_xml_document_get_file_descriptor (a_original) ;
00655         file_path = mlview_file_descriptor_get_file_path (file_desc);
00656         result = mlview_xml_document_open (file_path, PRIVATE (a_original)->app_context) ;
00657         return result ;
00658 }
00659 
00667 void
00668 mlview_xml_document_set_file_path (MlViewXMLDocument *a_xml_doc,
00669                                    gchar *a_file_path)
00670 {
00671         g_return_if_fail (a_xml_doc != NULL) ;
00672         g_return_if_fail (PRIVATE (a_xml_doc) != NULL) ;
00673 
00674         if( PRIVATE (a_xml_doc)->file_desc == NULL ) {
00675                 PRIVATE (a_xml_doc)->file_desc =
00676                         mlview_file_descriptor_new (a_file_path) ;
00677         } else {
00678                 mlview_file_descriptor_set_file_path (PRIVATE (a_xml_doc)->file_desc,
00679                                                       a_file_path) ;
00680         }
00681 
00682         gtk_signal_emit (GTK_OBJECT (a_xml_doc),
00683                          gv_mlview_xml_document_signals [FILE_PATH_CHANGED]) ;
00684 }
00685 
00686 
00693 gchar *
00694 mlview_xml_document_get_file_path (MlViewXMLDocument *a_xml_doc)
00695 {
00696         g_return_val_if_fail (a_xml_doc != NULL, NULL) ;
00697         g_return_val_if_fail (PRIVATE(a_xml_doc) != NULL, NULL) ;
00698 
00699         return mlview_file_descriptor_get_file_path (PRIVATE (a_xml_doc)->file_desc) ;
00700 }
00701 
00702 
00712 xmlNode *
00713 mlview_xml_document_add_child_node (MlViewXMLDocument *a_xml_doc,
00714                                     xmlNode *a_parent_xml_node,
00715                                     xmlNode *a_xml_node, gboolean a_subtree_required)
00716 {
00717         xmlNode * result = NULL  ;
00718         gchar *  validation_is_on = NULL ;
00719 
00720         g_return_val_if_fail (a_xml_doc != NULL, NULL) ;
00721         g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_doc), NULL) ;
00722         g_return_val_if_fail (PRIVATE (a_xml_doc) != NULL, NULL) ;
00723         g_return_val_if_fail (a_parent_xml_node != NULL, NULL) ;
00724         g_return_val_if_fail ((a_parent_xml_node->type == XML_ELEMENT_NODE) 
00725                               || (a_parent_xml_node->type == XML_DOCUMENT_NODE), 
00726                               NULL) ;
00727         g_return_val_if_fail (a_xml_node != NULL, NULL) ;
00728 
00729         result = xmlAddChild (a_parent_xml_node, a_xml_node) ;
00730         g_return_val_if_fail (result != NULL, NULL) ;
00731 
00732         if (a_subtree_required == TRUE
00733             && PRIVATE (a_xml_doc)->app_context
00734             && mlview_app_context_settings_exist (PRIVATE (a_xml_doc)->app_context)) {
00735                 validation_is_on = 
00736                         mlview_app_context_get_settings_value (PRIVATE (a_xml_doc)->app_context,
00737                                                                MLVIEW_STG_K_IS_VALIDATION_ON) ;
00738                 if (validation_is_on && !strcmp (validation_is_on, MLVIEW_STG_V_YES)) {
00739 
00740                         enum MLVIEW_PARSING_UTILS_STATUS  status ;
00741                         status =
00742                                 mlview_parsing_utils_build_required_attributes_list (PRIVATE (a_xml_doc)->app_context, 
00743                                                                                      result) ;
00744                         status =
00745                                 mlview_parsing_utils_build_required_children_tree (PRIVATE (a_xml_doc)->app_context,
00746                                                                                    &result) ;
00747                 }
00748 
00749         }
00750 
00751         /*emit the proper signals*/
00752         gtk_signal_emit (GTK_OBJECT (a_xml_doc),
00753                          gv_mlview_xml_document_signals [CHILD_NODE_ADDED],
00754                          a_parent_xml_node, a_xml_node) ;
00755 
00756         gtk_signal_emit (GTK_OBJECT (a_xml_doc),
00757                          gv_mlview_xml_document_signals [DOCUMENT_CHANGED]) ;
00758         return result ;
00759 }
00760 
00761 
00771 xmlNode *
00772 mlview_xml_document_cut_node (MlViewXMLDocument * a_xml_doc, xmlNode * a_xml_node)
00773 {
00774         xmlNode * parent_node = NULL , *result = NULL;
00775 
00776         g_return_val_if_fail (a_xml_doc != NULL, NULL) ;
00777         g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_doc), NULL) ;
00778         g_return_val_if_fail (PRIVATE (a_xml_doc) != NULL, NULL) ;
00779         g_return_val_if_fail (PRIVATE (a_xml_doc)->xml_doc != NULL, NULL) ;
00780         g_return_val_if_fail (a_xml_node != NULL, NULL) ;
00781 
00782         g_return_val_if_fail (a_xml_node->doc == PRIVATE (a_xml_doc)->xml_doc, NULL) ;
00783 
00784         parent_node = a_xml_node->parent ;
00785 
00786         g_return_val_if_fail (parent_node != NULL, NULL) ;
00787 
00788         mlview_xml_document_copy_node_to_clipboard (a_xml_node, PRIVATE (a_xml_doc)->xml_doc) ;
00789         xmlUnlinkNode (a_xml_node) ;
00790         result = a_xml_node ;
00791 
00792         gtk_signal_emit (GTK_OBJECT (a_xml_doc),
00793                          gv_mlview_xml_document_signals [NODE_CUT],
00794                          parent_node, a_xml_node) ;
00795 
00796         gtk_signal_emit (GTK_OBJECT (a_xml_doc),
00797                          gv_mlview_xml_document_signals [DOCUMENT_CHANGED]) ;
00798         
00799         return result ;
00800 }
00801 
00802 
00813 xmlNode *
00814 mlview_xml_document_set_node_content (MlViewXMLDocument * a_xml_document,
00815                                       xmlNode *a_node, gchar * a_content)
00816 {
00817         g_return_val_if_fail (a_xml_document != NULL, NULL) ;
00818         g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_document), NULL) ;
00819         g_return_val_if_fail (a_node != NULL, NULL) ;
00820         
00821         xmlNodeSetContent (a_node, a_content) ;
00822 
00823         gtk_signal_emit (GTK_OBJECT (a_xml_document), 
00824                          gv_mlview_xml_document_signals [CONTENT_CHANGED], a_node) ;
00825 
00826         gtk_signal_emit (GTK_OBJECT (a_xml_document), 
00827                          gv_mlview_xml_document_signals [NODE_CHANGED], a_node) ;
00828 
00829         gtk_signal_emit (GTK_OBJECT (a_xml_document), 
00830                          gv_mlview_xml_document_signals [DOCUMENT_CHANGED]) ;
00831 
00832         return a_node ;
00833 }
00834 
00845 xmlNode *
00846 mlview_xml_document_set_node_name (MlViewXMLDocument * a_xml_document,
00847                                    xmlNode *a_node, gchar * a_name)
00848 {
00849         g_return_val_if_fail (a_xml_document != NULL, NULL) ;
00850         g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_document), NULL) ;
00851         g_return_val_if_fail (a_node != NULL, NULL) ;
00852 
00853         xmlNodeSetName (a_node, a_name) ;
00854 
00855         gtk_signal_emit (GTK_OBJECT (a_xml_document), 
00856                          gv_mlview_xml_document_signals [NAME_CHANGED], a_node) ;
00857  
00858         gtk_signal_emit (GTK_OBJECT (a_xml_document), 
00859                          gv_mlview_xml_document_signals [NODE_CHANGED], a_node) ;
00860 
00861         gtk_signal_emit (GTK_OBJECT (a_xml_document), 
00862                          gv_mlview_xml_document_signals [DOCUMENT_CHANGED]) ;
00863         return a_node ;
00864 }
00865 
00866 
00877 xmlNode *
00878 mlview_xml_document_insert_prev_sibling_node (MlViewXMLDocument *a_xml_document,
00879                                               xmlNode *a_sibling_node, xmlNode *a_xml_node,
00880                                               gboolean a_subtree_required)
00881 {
00882         xmlNode * result = NULL ;
00883         gchar *  validation_is_on = NULL ;
00884 
00885         g_return_val_if_fail (a_xml_document != NULL, NULL) ;
00886         g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_document), NULL) ;
00887         g_return_val_if_fail (PRIVATE (a_xml_document) != NULL, NULL) ;
00888         g_return_val_if_fail (a_sibling_node != NULL, NULL) ;
00889         g_return_val_if_fail (a_xml_node != NULL, NULL) ;
00890 
00891         result = xmlAddPrevSibling (a_sibling_node, a_xml_node) ;
00892 
00893         if (a_subtree_required == TRUE
00894             && PRIVATE (a_xml_document)->app_context
00895             && mlview_app_context_settings_exist (PRIVATE (a_xml_document)->app_context)) {
00896                 validation_is_on =
00897                         mlview_app_context_get_settings_value (PRIVATE (a_xml_document)->app_context,
00898                                                                MLVIEW_STG_K_IS_VALIDATION_ON) ;
00899 
00900                 if (validation_is_on && !strcmp (validation_is_on, MLVIEW_STG_V_YES)) {
00901 
00902                         enum MLVIEW_PARSING_UTILS_STATUS  status ;
00903                         status = 
00904                                 mlview_parsing_utils_build_required_attributes_list (PRIVATE (a_xml_document)->app_context, 
00905                                                                                      result) ;
00906                         status = 
00907                                 mlview_parsing_utils_build_required_children_tree (PRIVATE (a_xml_document)->app_context, 
00908                                                                                    &result) ;
00909                 }
00910                         
00911         }
00912 
00913         gtk_signal_emit (GTK_OBJECT (a_xml_document),
00914                          gv_mlview_xml_document_signals [PREV_SIBLING_NODE_INSERTED],
00915                          a_sibling_node,
00916                          a_xml_node) ;
00917 
00918         gtk_signal_emit (GTK_OBJECT (a_xml_document),
00919                          gv_mlview_xml_document_signals [DOCUMENT_CHANGED]) ;
00920 
00921         return result ;
00922 }
00923 
00924 
00935 xmlNode *
00936 mlview_xml_document_insert_next_sibling_node (MlViewXMLDocument *a_xml_document,
00937                                               xmlNode *a_sibling_node, xmlNode *a_xml_node,
00938                                               gboolean a_subtree_required)
00939 {
00940         xmlNode * result = NULL ;
00941         gchar *  validation_is_on = NULL ;
00942 
00943         g_return_val_if_fail (a_xml_document != NULL, NULL) ;
00944         g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_document), NULL) ;
00945         g_return_val_if_fail (PRIVATE (a_xml_document) != NULL, NULL) ;
00946         g_return_val_if_fail (a_sibling_node != NULL, NULL) ;
00947         g_return_val_if_fail (a_xml_node != NULL, NULL) ;
00948         
00949         result = xmlAddNextSibling (a_sibling_node, a_xml_node) ;
00950         
00951         if (a_subtree_required == TRUE
00952             && PRIVATE (a_xml_document)->app_context
00953             && mlview_app_context_settings_exist (PRIVATE (a_xml_document)->app_context)) {
00954                 validation_is_on =
00955                         mlview_app_context_get_settings_value (PRIVATE (a_xml_document)->app_context,
00956                                                                MLVIEW_STG_K_IS_VALIDATION_ON) ;
00957 
00958                 if (validation_is_on && !strcmp (validation_is_on, MLVIEW_STG_V_YES)) {
00959 
00960                         enum MLVIEW_PARSING_UTILS_STATUS  status ;
00961 
00962                         status =
00963                                 mlview_parsing_utils_build_required_attributes_list (PRIVATE (a_xml_document)->app_context, 
00964                                                                                       result) ;
00965                         status = 
00966                                 mlview_parsing_utils_build_required_children_tree (PRIVATE (a_xml_document)->app_context, 
00967                                                                                    &result) ;
00968                 }
00969                         
00970         }
00971 
00972         gtk_signal_emit (GTK_OBJECT (a_xml_document),
00973                          gv_mlview_xml_document_signals [NEXT_SIBLING_NODE_INSERTED],
00974                          a_sibling_node,
00975                          a_xml_node) ;
00976 
00977         gtk_signal_emit (GTK_OBJECT (a_xml_document),
00978                          gv_mlview_xml_document_signals [DOCUMENT_CHANGED]) ;
00979 
00980         return result ;
00981 }
00982 
00983 
00984 void
00985 mlview_xml_document_paste_node_as_child (MlViewXMLDocument *a_xml_document,
00986                                          xmlNode *a_parent_node)
00987 {
00988         xmlNode * xml_node = NULL ;
00989 
00990         g_return_if_fail (a_xml_document != NULL) ;
00991         g_return_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_document)) ;
00992         g_return_if_fail (PRIVATE (a_xml_document)) ;
00993         g_return_if_fail (a_parent_node != NULL) ;
00994 
00995         xml_node = mlview_xml_document_get_node_from_clipboard (PRIVATE (a_xml_document)->xml_doc) ;
00996         g_return_if_fail (xml_node != NULL) ;
00997 
00998         mlview_xml_document_add_child_node (a_xml_document, a_parent_node, 
00999                                             xml_node, FALSE) ;
01000 }
01001 
01002 
01003 void
01004 mlview_xml_document_paste_node_as_sibling (MlViewXMLDocument * a_xml_document, xmlNode *a_parent_node,
01005                                            xmlNode * a_sibling_node, gboolean a_previous)
01006 {
01007         xmlNode *xml_node = NULL ;
01008 
01009         g_return_if_fail (a_xml_document != NULL) ;
01010         g_return_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_document)) ;
01011         g_return_if_fail (PRIVATE (a_xml_document) != NULL) ;
01012         g_return_if_fail (a_parent_node != NULL) ;
01013         g_return_if_fail (a_sibling_node != NULL) ;
01014 
01015         xml_node = mlview_xml_document_get_node_from_clipboard (PRIVATE (a_xml_document)->xml_doc) ;
01016         g_return_if_fail (xml_node != NULL) ;
01017 
01018         if (a_previous == FALSE) {
01019                 mlview_xml_document_insert_next_sibling_node (a_xml_document,
01020                                                               a_sibling_node, xml_node, FALSE) ;
01021         } else {
01022                 mlview_xml_document_insert_prev_sibling_node (a_xml_document,
01023                                                               a_sibling_node, xml_node, FALSE) ;
01024         }
01025 }
01026 
01027 
01035 gboolean
01036 mlview_xml_document_needs_saving (MlViewXMLDocument *a_doc)
01037 {
01038         MlViewFileDescriptor *file_desc ;
01039         gboolean is_modified ;
01040 
01041         g_return_val_if_fail (a_doc != NULL, FALSE) ;
01042         g_return_val_if_fail (PRIVATE(a_doc) != NULL, FALSE) ;
01043         
01044         file_desc = mlview_xml_document_get_file_descriptor (a_doc) ;
01045         if ( file_desc == NULL )
01046                 return TRUE ;
01047         
01048         if ( mlview_file_descriptor_is_modified (file_desc, &is_modified) )
01049                 return FALSE ;
01050         return is_modified ;
01051 }
01052 
01056 void 
01057 mlview_xml_document_destroy (GtkObject *a_xml_doc)
01058 {
01059         MlViewXMLDocument * xml_doc = NULL ;
01060 
01061         g_return_if_fail (a_xml_doc != NULL) ;
01062         g_return_if_fail (MLVIEW_IS_XML_DOCUMENT (a_xml_doc)) ;
01063         
01064         xml_doc = MLVIEW_XML_DOCUMENT (a_xml_doc) ;
01065 
01066         if ( PRIVATE (xml_doc) == NULL )
01067                 return ;
01068         if ( PRIVATE(xml_doc)->file_desc != NULL ) {
01069                 mlview_file_descriptor_destroy (PRIVATE (xml_doc)->file_desc) ;
01070                 PRIVATE (xml_doc)->file_desc = NULL ;
01071         }
01072         
01073         if ( PRIVATE (xml_doc)->xml_doc != NULL ){
01074                 xmlFreeDoc (PRIVATE (xml_doc)->xml_doc) ;
01075                 PRIVATE (xml_doc)->xml_doc = NULL ;
01076         }
01077 
01078         g_free (PRIVATE (xml_doc)) ;
01079         PRIVATE (xml_doc) = NULL ;
01080 
01081         if (GTK_OBJECT_CLASS (gv_parent_class)->destroy) {
01082                 GTK_OBJECT_CLASS (gv_parent_class)->destroy (a_xml_doc) ;
01083         }
01084 }
01085 
01092 MlViewFileDescriptor *
01093 mlview_xml_document_get_file_descriptor (MlViewXMLDocument *a_xml_doc)
01094 {
01095         g_return_val_if_fail (a_xml_doc != NULL, NULL) ;
01096         g_return_val_if_fail (PRIVATE (a_xml_doc) != NULL, NULL) ;
01097         
01098         return PRIVATE (a_xml_doc)->file_desc ;
01099 }
01100 
01108 void 
01109 mlview_xml_document_set_file_descriptor (MlViewXMLDocument *a_xml_doc, MlViewFileDescriptor *a_file_desc)
01110 {
01111         g_return_if_fail (a_xml_doc != NULL) ;
01112         g_return_if_fail (PRIVATE(a_xml_doc) != NULL) ;
01113         
01114         PRIVATE (a_xml_doc)->file_desc = a_file_desc ;
01115 }
01116 
01123 xmlDocPtr
01124 mlview_xml_document_get_xml_document (MlViewXMLDocument *a_xml_doc)
01125 {
01126         g_return_val_if_fail (a_xml_doc != NULL, NULL) ;
01127         g_return_val_if_fail (PRIVATE(a_xml_doc) != NULL, NULL) ;
01128         
01129         return PRIVATE (a_xml_doc)->xml_doc ;
01130 }
01131 
01132 
01140 void
01141 mlview_xml_document_set_xml_document (MlViewXMLDocument *a_doc, xmlDocPtr a_mem_doc)
01142 {
01143         g_return_if_fail (a_doc != NULL) ;
01144         g_return_if_fail (PRIVATE(a_doc) != NULL) ;
01145 
01146         PRIVATE (a_doc)->xml_doc = a_mem_doc ;  
01147 }

Generated on Sat Jul 6 09:57:38 2002 for Gnome-MlView by doxygen1.2.16