Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

mlview-tree-editor.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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00014  *
00015  *
00016  *Copyright 2001-2002 Dodji Seketeli.
00017  */
00018 
00019 
00029 #include <string.h>
00030 #include <stdlib.h>
00031 
00032 #include "mlview-tree-editor.h"
00033 #include "mlview-node-type-picker.h"
00034 #include "mlview-global-settings.h"
00035 #include "utils.h"
00036 
00037 
00038 
00039 #define SEARCH_IN_NAMES_CHECK_BUTTON "search-in-names-check-box"
00040 #define SEARCH_IN_ATTRIBUTES_NAMES_CHECK_BUTTON "search-in-attributes-names-check-box"
00041 #define SEARCH_IN_ATTRIBUTES_VALUES_CHECK_BUTTON "search-in-attributes-values-check-box"
00042 #define SEARCH_IN_CONTENT_CHECK_BUTTON "search-in-content-check-box"
00043 #define SEARCHED_TEXT_ENTRY "searched-text-entry"
00044 
00045 #define IS_THE_FIND_DIALOG "is-the-find-dialog"
00046 
00047 /*================================================================
00048  *The struct defining the private attributes of MlViewTreeEditor and it associated macros
00049  *=================================================================*/
00050 
00051 #define PRIVATE(mlview_tree_editor) ((mlview_tree_editor)->private)
00052 
00053 
00054 struct _MlViewTreeEditorPrivate {
00055         /*the xml document being edited. FIXME => handle it lifetime !!!*/
00056         xmlDocPtr xml_doc ; 
00057 
00058         MlViewXMLDocument * mlview_xml_doc ;
00059 
00060         /*the viewable tree that matches xml_doc*/
00061         GtkCTree *viewable_doc ;
00062 
00063         /*the menu poped up when the user right clicks on an xml_node*/
00064         GtkWidget *xml_node_popup_menu ;
00065         
00066         GtkCTreeNode * current_selected_node ;
00067         
00068         /*the node type picker used when creating a new node. MlViewTreeEditor does not have to handle it lifetime*/
00069         MlViewNodeTypePicker *node_type_picker ;
00070 
00071         MlViewAppContext *app_context ; 
00072 } ;
00073 
00074 
00075 enum {
00076         TREE_CHANGED=1,
00077         MARK_SET_TO_NODE,
00078         MARK_REMOVED_FROM_NODE,
00079         NODE_CUT,
00080         NODE_PASTED,
00081         NODE_ADDED,
00082         NODE_SELECTED,
00083         NODE_UNSELECTED,
00084         NUMBER_OF_SIGNALS
00085 };
00086 
00087 static gchar * p_tree_editor_titles[]=
00088 {
00089         N_("the xml document"),
00090         N_("the xml document tags")
00091 } ;
00092 
00093 #define MLVIEW_TREE_EDITOR_NODE_CLIPBOARD_SIZE 128
00094 static const gint TREE_EDITOR_NUMBER_OF_COLUMNS = 1 ;
00095 static const gint TREE_EDITOR_TREE_COLUMN= 0 ;
00096 static const gint TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT = 2 ;
00097 static const gint MLVIEW_CONTENT_MAX_LEN=512 ;
00098 static const gint MLVIEW_TREE_EDITOR_DEFAULT_EXPANSION_DEPTH = 2 ;
00099 
00100 static GnomeDialog * p_find_dialog = NULL ;
00101 
00102 
00103 /*===================================================================
00104  *The edition popup menu definition array.
00105  *This menu is poped up on an xml visual node.
00106  *Note that this pop up menu must be dynamicaly build when this widget supports
00107  *Validation.
00108  *
00109  *FIXME: do not use this popup menu when validation is on.
00110  *Maybe build a dynamic menu using GtkMenu widgetware.
00111  *==================================================================*/
00112 
00113 
00114 /*===================================================================
00115  *declaration of the private functions used and defined by this object.
00116  *===================================================================*/
00117 
00118 static void mlview_tree_editor_init_class(MlViewTreeEditorClass *a_klass) ;
00119 static void mlview_tree_editor_init(MlViewTreeEditor *a_editor) ;
00120 
00121 
00122 /*=== helper functions that build the visual tree from the xml document object model ================*/
00123 static GtkCTreeNode * build_ctree_from_xml_tree (MlViewAppContext *a_app_context, xmlNodePtr a_node,
00124                                                 GtkCTreeNode *a_parent_node, GtkCTree ** a_visual_tree_ptr) ;
00125 static void build_ctree_from_xml_doc (MlViewAppContext *a_app_context, xmlDocPtr a_doc, 
00126                                       GtkCTree ** a_visual_tree_ptr, gchar * a_doc_name, 
00127                                       guint a_expansion_level) ;
00128 /*==================================================================================================*/
00129 
00130 /*==helper functions that build the strings that you see on the right side of a visual xml node.==*/
00131 static void attributes_list_to_string(void *a_attr_node, gchar ** a_result) ;
00132 static gchar* node_to_start_tag(const xmlNodePtr a_node) ;
00133 /*==================================================================================================*/
00134 
00135 /*=========helper functions of the search (find) api==============*/
00136 static gint xml_node_name_contains_string(const xmlNode *a_xml_node, const gchar *a_str, gchar ** a_found_str) ;
00137 static gint xml_node_attributes_name_contains_string(const xmlNode * a_xml_node, const gchar *a_str, gchar **a_found_str) ;
00138 static gint xml_node_attributes_value_contains_string(const xmlNode * a_xml_node, const gchar *a_str, gchar **a_found_str) ;
00139 static gint xml_node_content_contains_string(const xmlNode *a_xml_node, const gchar *a_str, gchar **a_found_str) ;
00140 static enum WhereInTheNodeBitmap xml_node_contains_string(const xmlNode * a_xml_node, const gchar *a_str, const enum WhereInTheNodeBitmap a_where_in_node_mask) ;
00141 static GtkCTreeNode * downward_find_visual_node_that_contains(GtkCTree * a_visual_tree, GtkCTreeNode * a_starting_from, 
00142                                                               const gchar * a_str, const enum WhereInTheNodeBitmap a_where_in_node_bitmap,
00143                                                               gboolean a_start_after) ;
00144 static gboolean mlview_tree_editor_find_dialog_search_in_names_is_on(GnomeDialog * a_find_dialog) ;
00145 static gboolean mlview_tree_editor_find_dialog_search_in_attributes_names_is_on(GnomeDialog * a_find_dialog) ;
00146 static gboolean mlview_tree_editor_find_dialog_search_in_attributes_values_is_on(GnomeDialog * a_find_dialog) ;
00147 static gboolean mlview_tree_editor_find_dialog_search_in_content_is_on(GnomeDialog * a_find_dialog) ;
00148 static gchar *  mlview_tree_editor_find_dialog_get_searched_text(GnomeDialog * a_find_dialog) ;
00149 static GtkCTreeNode * mlview_tree_editor_get_data_from_find_dialog_and_perform_search(MlViewTreeEditor *a_tree_editor,GnomeDialog *a_dialog, 
00150                                                                                       GtkCTreeNode * a_start_from, gboolean a_start_after) ;
00151 
00152 
00153 /*===============callbacks and signal handlers used to update the state of the widget when user cliks on a node==========================*/
00154 static void mlview_tree_editor_node_selected_default_signal_handler(MlViewTreeEditor *a_editor,GtkCTreeNode *a_visual_node, gpointer a_user_data) ;
00155 static void mlview_tree_editor_tree_select_row_cb(GtkCTree *a_visual_tree,GList * a_node, gint a_column,gpointer a_tree_editor) ;
00156 /*==================================================================================================================================*/
00157 
00158 static gboolean mlview_tree_editor_event_cb (GtkWidget * a_widget,
00159                                              GdkEvent *a_event,
00160                                              gpointer a_user_data) ;
00161 
00162 static gint mlview_tree_editor_build_node_insertion_submenu (MlViewTreeEditor *a_editor,
00163                                                              enum NODE_INSERTION_SCHEME a_insertion_scheme,
00164                                                              GtkMenu ** a_submenu) ;
00165 
00166 static void menu_add_child_node_activate_cb (GtkMenuItem *a_menu_item,
00167                                              gpointer a_user_data) ;
00168 static void menu_insert_prev_sibling_node_activate_cb (GtkMenuItem *a_menu_item,
00169                                                        gpointer a_user_data) ;
00170 static void menu_insert_next_sibling_node_activate_cb (GtkMenuItem *a_menu_item,
00171                                                        gpointer a_user_data) ;
00172 /*==helper functions called by the callbacks (controllers) when the user selects a type of node during node adding as child/sibling===*/
00173 static void mlview_tree_editor_handle_nt_picker_ok_button_clicked_to_add_child(MlViewTreeEditor *a_tree_editor) ;
00174 static void mlview_tree_editor_handle_nt_picker_ok_button_clicked_to_insert_sibling_node(MlViewTreeEditor *a_tree_editor) ;
00175 /*=======================================================*/
00176 
00177 
00178 /*===helper function to build, cache the find (search) dialog box and to retrieve info from it====*/
00179 static GnomeDialog * mlview_tree_editor_find_dialog_box_retrieve(MlViewAppContext *a_context) ;
00180 static gchar * mlview_tree_editor_find_dialog_get_searched_text(GnomeDialog * a_find_dialog) ;
00181 static gboolean  mlview_tree_editor_find_dialog_search_in_names_is_on(GnomeDialog * a_find_dialog) ;
00182 static gboolean mlview_tree_editor_find_dialog_search_in_attributes_names_is_on(GnomeDialog * a_find_dialog) ;
00183 static gboolean mlview_tree_editor_find_dialog_search_in_attributes_values_is_on(GnomeDialog * a_find_dialog) ;
00184 static gboolean mlview_tree_editor_find_dialog_search_in_content_is_on(GnomeDialog * a_find_dialog) ;
00185 /*===================================*/
00186 
00187 //static void mlview_tree_editor_build_contextual_menu (MlViewTreeEditor * a_tree_editor) ;
00188 
00189 static guint mlview_tree_editor_signals [NUMBER_OF_SIGNALS] = {0} ;
00190 static GtkVBoxClass *parent_class=NULL ;
00191 
00192 
00193 /*==================================================
00194  *private methods required by GTK typing system
00195  *
00196  *==================================================
00197  */
00198 
00203 static void
00204 mlview_tree_editor_init_class (MlViewTreeEditorClass *a_klass)
00205 {
00206         GtkObjectClass *object_class ;
00207         g_return_if_fail(a_klass!=NULL) ;
00208 
00209         parent_class=gtk_type_class(GTK_TYPE_VBOX) ;
00210         object_class=GTK_OBJECT_CLASS(a_klass) ;
00211   
00212         object_class->destroy=mlview_tree_editor_destroy;
00213 
00214         /*FIXME:add signals creation*/
00215         mlview_tree_editor_signals[TREE_CHANGED] = gtk_signal_new("tree-changed",
00216                                                                   GTK_RUN_FIRST,
00217                                                                   object_class->type,
00218                                                                   GTK_SIGNAL_OFFSET (MlViewTreeEditorClass, tree_changed),
00219                                                                   gtk_marshal_NONE__NONE,
00220                                                                   GTK_TYPE_NONE,0);
00221 
00222         mlview_tree_editor_signals[MARK_SET_TO_NODE] = gtk_signal_new("mark-set-to-node",
00223                                                                       GTK_RUN_FIRST,
00224                                                                       object_class->type,
00225                                                                       GTK_SIGNAL_OFFSET (MlViewTreeEditorClass, mark_set_to_node),
00226                                                                       gtk_marshal_NONE__POINTER,
00227                                                                       GTK_TYPE_NONE,1,
00228                                                                       GTK_TYPE_POINTER) ;
00229 
00230         mlview_tree_editor_signals[MARK_REMOVED_FROM_NODE] = gtk_signal_new ("mark-removed-from-node",
00231                                                                             GTK_RUN_FIRST,
00232                                                                             object_class->type,
00233                                                                             GTK_SIGNAL_OFFSET (MlViewTreeEditorClass, mark_removed_from_node),
00234                                                                             gtk_marshal_NONE__POINTER ,
00235                                                                             GTK_TYPE_NONE, 1 ,
00236                                                                             GTK_TYPE_POINTER) ;
00237         mlview_tree_editor_signals[NODE_CUT] = gtk_signal_new ("node-cut",
00238                                                                GTK_RUN_FIRST,
00239                                                                object_class->type,
00240                                                                GTK_SIGNAL_OFFSET (MlViewTreeEditorClass,node_cut),
00241                                                                gtk_marshal_NONE__POINTER,
00242                                                                GTK_TYPE_NONE, 1,
00243                                                                GTK_TYPE_POINTER) ;
00244 
00245         mlview_tree_editor_signals[NODE_PASTED] = gtk_signal_new ("node-pasted",
00246                                                                   GTK_RUN_FIRST,
00247                                                                   object_class->type,
00248                                                                   GTK_SIGNAL_OFFSET (MlViewTreeEditorClass,node_pasted),
00249                                                                   gtk_marshal_NONE__POINTER,
00250                                                                   GTK_TYPE_NONE, 1,
00251                                                                   GTK_TYPE_POINTER) ;
00252 
00253         mlview_tree_editor_signals[NODE_ADDED] = gtk_signal_new ("node-added",
00254                                                                  GTK_RUN_FIRST,
00255                                                                  object_class->type,
00256                                                                  GTK_SIGNAL_OFFSET (MlViewTreeEditorClass,node_added),
00257                                                                  gtk_marshal_NONE__POINTER,
00258                                                                  GTK_TYPE_NONE, 1, GTK_TYPE_POINTER) ;
00259 
00260         mlview_tree_editor_signals[NODE_SELECTED] = gtk_signal_new ("node-selected",
00261                                                                     GTK_RUN_FIRST,
00262                                                                     object_class->type,
00263                                                                     GTK_SIGNAL_OFFSET (MlViewTreeEditorClass,node_selected),
00264                                                                     gtk_marshal_NONE__POINTER,
00265                                                                     GTK_TYPE_NONE,1,GTK_TYPE_POINTER) ;
00266 
00267         mlview_tree_editor_signals[NODE_UNSELECTED] = gtk_signal_new ("node-unselected",
00268                                                                       GTK_RUN_FIRST,
00269                                                                       object_class->type,
00270                                                                       GTK_SIGNAL_OFFSET (MlViewTreeEditorClass,node_unselected),
00271                                                                       gtk_marshal_NONE__POINTER,
00272                                                                       GTK_TYPE_NONE, 1, GTK_TYPE_POINTER) ;
00273         
00274         gtk_object_class_add_signals (object_class, mlview_tree_editor_signals, NUMBER_OF_SIGNALS) ;
00275         a_klass->tree_changed = NULL ;
00276         a_klass->mark_set_to_node = NULL ;
00277         a_klass->mark_removed_from_node = NULL ;
00278         a_klass->node_cut = NULL ;
00279         a_klass->node_added = NULL ;
00280         a_klass->node_pasted = NULL;
00281         a_klass->node_selected = mlview_tree_editor_node_selected_default_signal_handler ;
00282         a_klass->node_unselected = NULL ;
00283 }
00284 
00285 
00290 static void
00291 mlview_tree_editor_init (MlViewTreeEditor *a_editor)
00292 {
00293         g_return_if_fail(a_editor != NULL) ;
00294         g_return_if_fail(PRIVATE(a_editor) == NULL) ;
00295 
00296         PRIVATE(a_editor) = g_malloc0(sizeof(MlViewTreeEditorPrivate)) ;
00297 }
00298 
00299 
00300 /*==============================================
00301  *private helper functions
00302  *==============================================
00303  */
00304 
00310 static void
00311 attributes_list_to_string (void *a_attr_node, gchar ** a_result)
00312 {
00313         xmlAttrPtr xml_attr = (xmlAttrPtr) a_attr_node ;
00314         xmlNodePtr xml_node = (xmlNodePtr) a_attr_node ;
00315 
00316         static int num_of_use = 0 ;
00317 
00318         if (num_of_use++ == 0)
00319                 *a_result = NULL ;
00320 
00321         if (a_attr_node == NULL)
00322                 return ;
00323 
00324         if (xml_attr->type == XML_ATTRIBUTE_NODE) {
00325                 gchar * tmp_str = *a_result, *name ;
00326                 if (xml_attr->ns != NULL  &&  xml_attr->ns->prefix != NULL) {
00327                         name = g_strconcat(xml_attr->ns->prefix, ":", xml_attr->name, NULL) ;
00328                 } else {
00329                         name = g_strdup(xml_attr->name) ;
00330                 }
00331                 if ( tmp_str == NULL )
00332                         *a_result= g_strdup(name) ;
00333                 else
00334                         *a_result = g_strconcat(tmp_str," ",name, NULL) ;
00335                 if ( tmp_str ){
00336                         g_free(tmp_str) ;
00337                         tmp_str = NULL ;
00338                 }
00339                 if (name) {
00340                         g_free (name) ;
00341                         name = NULL ;
00342                 }
00343                 if (xml_attr->children)
00344                         attributes_list_to_string (xml_attr->children, a_result) ;
00345 
00346                 if (xml_attr->next)
00347                         attributes_list_to_string (xml_attr->next, a_result) ;
00348         } else if ( xml_node->type == XML_TEXT_NODE ){
00349 
00350                 gchar * tmp_str = *a_result;
00351                 if (tmp_str) {
00352 
00353                         *a_result = g_strconcat (tmp_str, "=\"", xml_node->content,"\"", NULL) ;
00354                         g_free(tmp_str) ; 
00355                         tmp_str = NULL ;
00356                 }
00357         }
00358 }
00359 
00365 static gchar *
00366 node_to_start_tag (const xmlNodePtr a_node)
00367 {
00368         gchar *result = NULL,*content ;
00369         g_return_val_if_fail (a_node != NULL, NULL) ;
00370 
00371         if (a_node->type == XML_ELEMENT_NODE) {
00372                 gchar * attr_str=NULL, *ns_prefix=NULL, *name=NULL ;
00373                 attributes_list_to_string (a_node->properties, &attr_str) ;
00374 
00375                 if (a_node->ns != NULL && a_node->ns->prefix)
00376                         ns_prefix = g_strconcat (a_node->ns->prefix, ":", NULL) ;
00377                 else
00378                         ns_prefix = NULL ;
00379 
00380                 if (ns_prefix)
00381                         name = g_strconcat (ns_prefix, a_node->name, NULL) ;
00382                 else
00383                         name = g_strdup (a_node->name) ;
00384 
00385                 if (ns_prefix) {
00386                         g_free (ns_prefix) ;
00387                         ns_prefix = NULL ;
00388                 }
00389 
00390                 if (a_node->children != NULL) {
00391                         if(attr_str)
00392                                 result = g_strconcat ("<" ,name, " ", attr_str, ">", NULL) ;
00393                         else
00394                                 result = g_strconcat ("<", name,">", NULL) ;
00395                 } else {/*empty tag*/
00396                         if (attr_str)
00397                                 result = g_strconcat ("<", name, " ", attr_str, "/>", NULL) ;
00398                         else
00399                                 result = g_strconcat ("<", name,"/>", NULL) ;
00400                 }
00401                 if (name) {
00402                         g_free (name) ;
00403                         name = NULL ;
00404                 }
00405         }else if (xmlNodeIsText(a_node)) {
00406                 content = xmlNodeGetContent (a_node) ;
00407                 if (content == NULL) {
00408                         xmlNodeSetContent (a_node, "text") ;
00409                         content = xmlNodeGetContent (a_node) ;
00410                 }
00411                 if (strlen (content) > MLVIEW_CONTENT_MAX_LEN)
00412                         content[MLVIEW_CONTENT_MAX_LEN]='\0' ;
00413 
00414                 if (content != NULL) {
00415                         result = g_strdup (content) ;
00416                         g_free (content) ;
00417                 }
00418                
00419         } else if (a_node->type == XML_COMMENT_NODE) {
00420                 content = xmlNodeGetContent (a_node) ;
00421                 if (content == NULL) {
00422                         xmlNodeSetContent (a_node, "<!--comment-->") ;
00423                         content = xmlNodeGetContent (a_node) ;
00424                 }
00425                 if (strlen (content) > MLVIEW_CONTENT_MAX_LEN)
00426                         content[MLVIEW_CONTENT_MAX_LEN] = '\0' ;
00427 
00428                 result = g_strconcat ("<!--", content, "-->", NULL) ;
00429                 if (content != NULL) {
00430                         g_free (content) ;
00431                         content = NULL ;
00432                 }
00433         } else if (a_node->type == XML_PI_NODE) {
00434                 content = xmlNodeGetContent (a_node) ;
00435                 if (content == NULL) {
00436                         xmlNodeSetContent (a_node, "<?processing instruction node>") ;
00437                 }
00438                 if (strlen (content) > MLVIEW_CONTENT_MAX_LEN)
00439                         content[MLVIEW_CONTENT_MAX_LEN]='\0' ;
00440 
00441                 result = g_strconcat ("<?",a_node->name," ",content, ">" ,NULL) ;
00442                 if (content != NULL) {
00443                         g_free (content) ;
00444                         content = NULL ;
00445                 }
00446 
00447         }
00448         return result ;
00449 }
00450 
00451 
00457 static GtkCTreeNode *
00458 build_ctree_from_xml_tree (MlViewAppContext *a_app_context, xmlNodePtr a_node, 
00459                            GtkCTreeNode *a_parent_node, GtkCTree ** a_visual_tree_ptr)
00460 {
00461         xmlNode * node = NULL ;
00462         GtkCTreeNode * visual_node = NULL ;
00463         GtkCTreeNode * result = NULL ;
00464 
00465         GdkPixmap * open_element_node_xpm = NULL ;
00466         GdkBitmap * open_element_node_bmp = NULL ;
00467         GdkPixmap * close_element_node_xpm = NULL ;
00468         GdkBitmap * close_element_node_bmp = NULL ;
00469         GdkPixmap * text_node_xpm = NULL ;
00470         GdkBitmap * text_node_bmp = NULL ;
00471 
00472         g_return_val_if_fail (a_node != NULL, NULL) ;
00473 
00474         mlview_app_context_get_xpm (a_app_context, (char *)MLVIEW_STG_K_OPEN_ELEMENT_NODE_XPM, 
00475                                     &open_element_node_xpm, &open_element_node_bmp) ;
00476 
00477         mlview_app_context_get_xpm (a_app_context, (char *)MLVIEW_STG_K_CLOSE_ELEMENT_NODE_XPM, 
00478                                     &close_element_node_xpm, &close_element_node_bmp) ;
00479 
00480         mlview_app_context_get_xpm (a_app_context, (char *)MLVIEW_STG_K_TEXT_NODE_XPM,
00481                                     &text_node_xpm, &text_node_bmp) ;
00482 
00483         for (node = a_node; node != NULL; node = node->next) {/*walk thru the siblings and create sibling visual nodes*/
00484                 gchar * tag_str=NULL ;/*the string reprentation of the opening tag of the current element node*/
00485                 tag_str = node_to_start_tag (node) ;/*builds the string representation of the open tag represented by node.*/
00486 
00487                 if ( node->type == XML_ELEMENT_NODE ) {
00488 
00489                         if ( *a_visual_tree_ptr == NULL )
00490                                 *a_visual_tree_ptr = GTK_CTREE (gtk_ctree_new_with_titles (TREE_EDITOR_NUMBER_OF_COLUMNS,
00491                                                                                            TREE_EDITOR_TREE_COLUMN,
00492                                                                                            p_tree_editor_titles)) ;
00493                         if ( node->children == NULL ) {/*node is leaf node*/
00494                                 visual_node = gtk_ctree_insert_node (*a_visual_tree_ptr,a_parent_node, NULL, &tag_str,
00495                                                                      TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT,
00496                                                                      close_element_node_xpm, close_element_node_bmp,
00497                                                                      open_element_node_xpm, open_element_node_bmp,
00498                                                                      FALSE, FALSE) ;
00499                                 g_assert (visual_node != NULL) ;
00500                                 gtk_ctree_node_set_row_data (*a_visual_tree_ptr, visual_node, node) ;
00501 
00502                                 if (!result)
00503                                         result = visual_node ;
00504 
00505                         } else {/*node is not leaf node*/
00506                                 visual_node = gtk_ctree_insert_node(*a_visual_tree_ptr,a_parent_node, NULL, &tag_str,
00507                                                                     TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT,
00508                                                                     close_element_node_xpm,close_element_node_bmp,
00509                                                                     open_element_node_xpm,open_element_node_bmp,
00510                                                                     FALSE,FALSE) ;
00511                                 g_assert (visual_node != NULL) ;
00512                                 gtk_ctree_node_set_row_data (*a_visual_tree_ptr,visual_node,node) ;
00513                                 if (!result)
00514                                         result = visual_node ;
00515                                 build_ctree_from_xml_tree (a_app_context, node->children, 
00516                                                            visual_node, a_visual_tree_ptr) ;
00517                         }
00518                         if ( tag_str != NULL ) {
00519                                 g_free (tag_str) ;
00520                                 tag_str = NULL ;
00521                         }
00522                 } else if ( node->type == XML_TEXT_NODE && ! xmlIsBlankNode(node) ) {
00523                         visual_node = gtk_ctree_insert_node(*a_visual_tree_ptr, a_parent_node,NULL,
00524                                                             (gchar**)&tag_str, TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT,
00525                                                             text_node_xpm,text_node_bmp, text_node_xpm,text_node_bmp,
00526                                                             FALSE, FALSE) ;
00527                         g_assert (visual_node != NULL) ;
00528                         gtk_ctree_node_set_row_data (*a_visual_tree_ptr,visual_node,node) ;
00529 
00530                         if (!result)
00531                                 result = visual_node ;
00532 
00533                 } else if ( node->type == XML_COMMENT_NODE || node->type == XML_PI_NODE ) {
00534                         gchar * tag_str=NULL ;/*the string reprentation of the opening tag of the current element node*/
00535                         tag_str = node_to_start_tag (node) ;/*builds the string representation of the open tag represented by node.*/
00536                         visual_node = gtk_ctree_insert_node (*a_visual_tree_ptr,
00537                                                              a_parent_node, NULL, &tag_str,
00538                                                              TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT,
00539                                                              text_node_xpm,text_node_bmp,
00540                                                              text_node_xpm,text_node_bmp,
00541                                                              FALSE, FALSE) ;
00542                         if ( tag_str != NULL )
00543                                 g_free (tag_str) ;
00544 
00545                         g_assert (visual_node != NULL) ;
00546                         gtk_ctree_node_set_row_data (*a_visual_tree_ptr,visual_node,node) ;
00547 
00548                         if (!result)
00549                                 result = visual_node ;
00550                 } else {
00551                         
00552                 }
00553         }/*end for*/
00554         return result ;
00555 }/*end function*/
00556 
00557 
00563 static void
00564 build_ctree_from_xml_doc (MlViewAppContext *a_app_context, const xmlDocPtr a_doc, 
00565                           GtkCTree ** a_visual_tree_ptr, gchar * a_doc_name, 
00566                           guint a_expansion_level)
00567 {
00568         GtkCTreeNode * visual_node ;
00569         
00570         xmlNodePtr xml_tree ;
00571         gchar * root = N_("XML Document") ;
00572         gchar * tree_editor_titles [] = {"", N_("the xml document tags")} ;
00573 
00574         g_assert(*a_visual_tree_ptr == NULL) ;
00575         g_return_if_fail(a_doc != NULL) ;
00576         
00577         if(a_doc_name != NULL)
00578                 tree_editor_titles[TREE_EDITOR_TREE_COLUMN] = a_doc_name ;
00579         else if(a_doc->name != NULL)
00580                 tree_editor_titles[TREE_EDITOR_TREE_COLUMN] = a_doc->name ;
00581         else
00582                 tree_editor_titles[TREE_EDITOR_TREE_COLUMN] = _("the xml document") ;
00583 
00584         *a_visual_tree_ptr = GTK_CTREE(gtk_ctree_new_with_titles(TREE_EDITOR_NUMBER_OF_COLUMNS,
00585                                                                  TREE_EDITOR_TREE_COLUMN,
00586                                                                  tree_editor_titles)) ;
00587         /*
00588          *FIXME: add support of display all the types of node that could occur before the real so called xml tree.
00589          */
00590         visual_node = gtk_ctree_insert_node(*a_visual_tree_ptr, NULL, NULL,
00591                                           (gchar**)&root, TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT,
00592                                           NULL,NULL,NULL,NULL,
00593                                           FALSE,FALSE) ;
00594 
00595         gtk_ctree_node_set_row_data(*a_visual_tree_ptr, visual_node, a_doc) ;
00596         xml_tree = a_doc->children ;
00597         
00598         if(xml_tree != NULL){
00599                 build_ctree_from_xml_tree(a_app_context, xml_tree, visual_node, a_visual_tree_ptr) ;
00600                 gtk_ctree_expand_to_depth (*a_visual_tree_ptr, visual_node, a_expansion_level) ;
00601         }
00602 }
00603 
00604 
00609 static xmlNodePtr
00610 new_xml_node (xmlElementType a_node_type, xmlDocPtr a_xml_doc)
00611 {
00612         xmlNodePtr result = NULL ;
00613         switch(a_node_type){
00614 
00615         case XML_ELEMENT_NODE :
00616                 result = xmlNewNode(NULL,"") ;
00617                 break ;
00618         case XML_TEXT_NODE :
00619                 result = xmlNewText("") ;
00620                 break ;
00621         case XML_CDATA_SECTION_NODE :
00622                 xmlNewCDataBlock(a_xml_doc,"",128) ;
00623                 break ;
00624         case XML_PI_NODE :
00625                 result = xmlNewPI("","") ;
00626                 break ;
00627         case XML_COMMENT_NODE:
00628                 result = xmlNewComment("") ;
00629                 break ;
00630         case XML_DOCUMENT_NODE:
00631         case XML_DOCUMENT_TYPE_NODE :
00632         case XML_DOCUMENT_FRAG_NODE :
00633         case XML_NOTATION_NODE :
00634         case XML_DTD_NODE :
00635         case XML_ELEMENT_DECL :
00636         case XML_ATTRIBUTE_DECL :
00637         case XML_ENTITY_DECL :
00638         case XML_NAMESPACE_DECL:
00639         case XML_XINCLUDE_START :
00640         case XML_XINCLUDE_END :
00641         default :
00642                 result = xmlNewNode(NULL,"") ;
00643                 break ;         
00644         }
00645         return result ;
00646 }
00647 
00653 static gint
00654 xml_node_name_contains_string (const xmlNode *a_xml_node, const gchar *a_str, gchar **a_found_str)
00655 {
00656         g_return_val_if_fail(a_xml_node != NULL, -1) ;
00657         
00658         *a_found_str = NULL ;
00659         if(a_str == NULL)
00660                 return 0 ;
00661         
00662         if(a_xml_node->type != XML_ELEMENT_NODE
00663            &&  a_xml_node->type != XML_PI_NODE){
00664                 return -1 ;
00665         }
00666 
00667         *a_found_str = strstr(a_xml_node->name, a_str) ;
00668         if(*a_found_str)
00669                 return 1 ;
00670         return 0 ;
00671 }
00672 
00676 static gint 
00677 xml_node_attributes_name_contains_string(const xmlNode * a_xml_node, const gchar *a_str, gchar **a_found_str)
00678 {
00679         xmlAttr * mobile_attr ;
00680 
00681         g_return_val_if_fail(a_xml_node != NULL, -1) ;
00682         
00683         *a_found_str = NULL ;
00684         if(a_str == NULL)
00685                 return 0 ;
00686         
00687         mobile_attr = a_xml_node->properties ;
00688         while(mobile_attr){
00689                 *a_found_str = strstr(mobile_attr->name, a_str) ;
00690                 if(*a_found_str)
00691                         return 1 ;
00692                 mobile_attr = mobile_attr->next ;
00693         }
00694         return 0 ;
00695 }
00696 
00697 
00701 static gint
00702 xml_node_attributes_value_contains_string(const xmlNode * a_xml_node, const gchar *a_str, gchar **a_found_str)
00703 {
00704         xmlAttr * mobile_attr ;
00705 
00706         g_return_val_if_fail(a_xml_node != NULL , -1) ;
00707 
00708         *a_found_str = NULL ;
00709 
00710         if(a_str == NULL)
00711                 return 0 ;
00712 
00713         mobile_attr = a_xml_node->properties ;
00714 
00715         while(mobile_attr){
00716                 gchar * content=NULL ;
00717                 content = xmlNodeGetContent(mobile_attr->children) ;
00718                 if(content != NULL)
00719                         *a_found_str = strstr(content, a_str) ;
00720                 if(*a_found_str != NULL)
00721                         return 1 ;
00722                 mobile_attr = mobile_attr->next ;
00723         }
00724         return 0 ;
00725 }
00726 
00730 static gint
00731 xml_node_content_contains_string (const xmlNode *a_xml_node, const gchar *a_str, gchar **a_found_str)
00732 {
00733         gchar *content ;
00734         g_return_val_if_fail(a_xml_node != NULL, -1) ;
00735 
00736         *a_found_str = NULL ;
00737 
00738         if(a_str == NULL)
00739                 return 0 ;
00740 
00741         if(a_xml_node->type != XML_TEXT_NODE)
00742                 return -1 ;
00743 
00744         content = xmlNodeGetContent((xmlNode *)a_xml_node) ;
00745         if(content != NULL)
00746                 *a_found_str = strstr(content, a_str) ;
00747         if(*a_found_str != NULL)
00748                 return 1 ;
00749         return 0 ;
00750 }
00751 
00755 static enum WhereInTheNodeBitmap
00756 xml_node_contains_string(const xmlNode * a_xml_node, const gchar *a_str, const enum WhereInTheNodeBitmap a_where_in_node_bitmap)
00757 {
00758         enum WhereInTheNodeBitmap result = 0;
00759         gchar *string_found ;
00760         g_return_val_if_fail(a_xml_node, 0) ;
00761         
00762         if(a_str == NULL)
00763                 return 0 ;
00764         if(a_where_in_node_bitmap & NODE_NAME){
00765                 if(xml_node_name_contains_string(a_xml_node, a_str, &string_found) > 0){
00766                         result |= NODE_NAME ;
00767                 }
00768         }
00769         if(a_where_in_node_bitmap & NODE_ATTRIBUTE_NAME){
00770                 if(xml_node_attributes_name_contains_string(a_xml_node, a_str, &string_found) > 0){
00771                         result |= NODE_ATTRIBUTE_VALUE ;
00772                 }
00773         }
00774         if(a_where_in_node_bitmap & NODE_ATTRIBUTE_VALUE){
00775                 if(xml_node_attributes_value_contains_string(a_xml_node, a_str, &string_found) > 0){
00776                         result |= NODE_ATTRIBUTE_VALUE ;
00777                 }
00778         }
00779         if(a_where_in_node_bitmap & NODE_CONTENT){
00780                 if(xml_node_content_contains_string(a_xml_node, a_str, &string_found) > 0){
00781                         result |= NODE_CONTENT ;
00782                 }
00783         }
00784         return result ;
00785 }
00786 
00787 
00798 static GtkCTreeNode *
00799 downward_find_visual_node_that_contains(GtkCTree * a_visual_tree, GtkCTreeNode * a_starting_from,
00800                                         const gchar * a_str, const enum WhereInTheNodeBitmap a_where_in_node_bitmap, 
00801                                         gboolean a_start_after)
00802 {
00803         GtkCTreeNode * visual_node=NULL, *result=NULL ;
00804         xmlNode * xml_node ;
00805 
00806         g_return_val_if_fail(a_visual_tree != NULL, NULL) ;
00807 
00808         if(a_starting_from == NULL)
00809                 return NULL ;
00810 
00811         visual_node = a_starting_from ;
00812         if(a_start_after == TRUE){
00813                 visual_node = GTK_CTREE_NODE_NEXT(visual_node) ;
00814         }
00815 
00816         while(visual_node){
00817                 xml_node = gtk_ctree_node_get_row_data(a_visual_tree, visual_node) ;
00818                 if(xml_node_contains_string(xml_node, a_str, a_where_in_node_bitmap))
00819                         return visual_node ;
00820 
00821                 result = downward_find_visual_node_that_contains(a_visual_tree,GTK_CTREE_ROW(visual_node)->children,
00822                                                                  a_str, a_where_in_node_bitmap,FALSE) ;
00823                 if(result != NULL)
00824                         return result ;
00825                 //visual_node = GTK_CTREE_ROW(visual_node)->sibling ;
00826                 visual_node = GTK_CTREE_NODE_NEXT(visual_node) ;
00827         }
00828         return result ;
00829 }
00830 
00831 
00836 static GnomeDialog *
00837 mlview_tree_editor_find_dialog_box_retrieve (MlViewAppContext *a_app_context)
00838 {
00839         GtkWidget * search_in_names_check, * search_in_attribute_names_check, * searched_text_entry ;
00840         GtkWidget *search_in_attribute_value_check, *search_in_content_check ;
00841         GtkWidget * label, *table ;
00842 
00843         if(p_find_dialog == NULL){
00844                 p_find_dialog = GNOME_DIALOG (gnome_dialog_new (_("Find an xml node in this document"),
00845                                                                 _("Find"),_("Cancel"),
00846                                                                 NULL)) ;
00847 
00848                 gtk_object_set_data (GTK_OBJECT (p_find_dialog), IS_THE_FIND_DIALOG, "yes") ;
00849                 label = gtk_label_new (_("Text to look for:")) ;
00850                 searched_text_entry = gtk_entry_new () ;
00851                 table = gtk_table_new (1,2,TRUE) ;
00852                 gtk_table_attach_defaults (GTK_TABLE (table), label,
00853                                            0,1,0,1) ;
00854                 gtk_table_attach_defaults (GTK_TABLE (table), searched_text_entry,
00855                                            1,2,0,1) ;
00856                 gtk_box_pack_start (GTK_BOX (p_find_dialog->vbox), table,
00857                                    TRUE,FALSE,0) ;
00858 
00859                 search_in_names_check = gtk_check_button_new_with_label(_("Search among nodes name")) ;
00860                 search_in_attribute_names_check = gtk_check_button_new_with_label(_("Search among attributes names")) ;
00861                 search_in_attribute_value_check = gtk_check_button_new_with_label(_("Search among attributes values")) ;
00862                 search_in_content_check = gtk_check_button_new_with_label(_("Search among content nodes text")) ;
00863 
00864                 gtk_object_set_data(GTK_OBJECT(p_find_dialog),SEARCH_IN_NAMES_CHECK_BUTTON,search_in_names_check) ;
00865                 gtk_object_set_data(GTK_OBJECT(p_find_dialog),SEARCH_IN_ATTRIBUTES_NAMES_CHECK_BUTTON, search_in_attribute_names_check) ;
00866                 gtk_object_set_data(GTK_OBJECT(p_find_dialog),SEARCH_IN_ATTRIBUTES_VALUES_CHECK_BUTTON,search_in_attribute_value_check) ;
00867                 gtk_object_set_data(GTK_OBJECT(p_find_dialog),SEARCH_IN_CONTENT_CHECK_BUTTON,search_in_content_check) ;
00868                 gtk_object_set_data(GTK_OBJECT(p_find_dialog),SEARCHED_TEXT_ENTRY,searched_text_entry) ;
00869                 
00870                 gtk_box_pack_start(GTK_BOX(p_find_dialog->vbox),search_in_names_check,
00871                                    TRUE,FALSE,0) ;
00872                 gtk_box_pack_start(GTK_BOX(p_find_dialog->vbox),search_in_attribute_names_check,
00873                                    TRUE,FALSE,0) ;
00874                 gtk_box_pack_start(GTK_BOX(p_find_dialog->vbox),search_in_attribute_value_check,
00875                                    TRUE,FALSE,0) ;
00876                 gtk_box_pack_start(GTK_BOX(p_find_dialog->vbox),search_in_content_check,
00877                                    TRUE,FALSE,0) ;
00878 
00879                 //mlview_app_context_set_window_icon (a_app_context, GTK_WIDGET (p_find_dialog)) ;
00880                 gtk_window_set_wmclass (GTK_WINDOW (p_find_dialog), "find-dialog-box", "MlView") ;
00881                 gtk_widget_show_all (GTK_WIDGET(p_find_dialog->vbox)) ;
00882                 
00883         }
00884 
00885         return p_find_dialog ;
00886 }
00887 
00888 
00892 static gboolean 
00893 mlview_tree_editor_find_dialog_search_in_names_is_on(GnomeDialog * a_find_dialog)
00894 {
00895         gchar * check_str ;
00896         GtkCheckButton * search_in_names_check_button ;
00897 
00898         g_return_val_if_fail(GNOME_IS_DIALOG(a_find_dialog), FALSE) ;
00899         
00900         /*a SANITY check:
00901          *get a sanity check string associated to the search dialog by the function mlview_tree_editor_find_dialog_retrieve()
00902          *and see if it's equals "yes". If yes, the a_find_dialog is a find dialog box build by mlview_tree_editor_find_dialog_retrieve() ;
00903          *if no, return false... just in case ...
00904          */
00905         check_str = gtk_object_get_data(GTK_OBJECT(a_find_dialog),IS_THE_FIND_DIALOG) ;
00906         if(strcmp(check_str, "yes"))
00907                 return FALSE ;
00908         
00909         search_in_names_check_button = GTK_CHECK_BUTTON(gtk_object_get_data(GTK_OBJECT(a_find_dialog), SEARCH_IN_NAMES_CHECK_BUTTON)) ;
00910         return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search_in_names_check_button)) ;  
00911 }
00912 
00916 static gboolean 
00917 mlview_tree_editor_find_dialog_search_in_attributes_names_is_on(GnomeDialog * a_find_dialog)
00918 {
00919         gchar * check_str ;
00920         GtkCheckButton * search_in_attribute_names_check_button ;
00921 
00922         g_return_val_if_fail(GNOME_IS_DIALOG(a_find_dialog), FALSE) ;
00923         
00924         /*a SANITY check:
00925          *get a sanity check string associated to the search dialog by the function mlview_tree_editor_find_dialog_retrieve()
00926          *and see if it's equals "yes". If yes, the a_find_dialog is a find dialog box build by mlview_tree_editor_find_dialog_retrieve() ;
00927          *if no, return false... just in case ...
00928          */
00929         check_str = gtk_object_get_data(GTK_OBJECT(a_find_dialog),IS_THE_FIND_DIALOG) ;
00930         if(strcmp(check_str, "yes"))
00931                 return FALSE ;
00932         
00933         search_in_attribute_names_check_button = GTK_CHECK_BUTTON(gtk_object_get_data(GTK_OBJECT(a_find_dialog), SEARCH_IN_ATTRIBUTES_NAMES_CHECK_BUTTON)) ;
00934         return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search_in_attribute_names_check_button)) ;
00935 }
00936 
00940 static gboolean 
00941 mlview_tree_editor_find_dialog_search_in_attributes_values_is_on(GnomeDialog * a_find_dialog)
00942 {
00943         gchar * check_str ;
00944         GtkCheckButton * search_in_attribute_values_check_button ;
00945 
00946         g_return_val_if_fail(GNOME_IS_DIALOG(a_find_dialog), FALSE) ;
00947         
00948         /*a SANITY check:
00949          *get a sanity check string associated to the search dialog by the function mlview_tree_editor_find_dialog_retrieve()
00950          *and see if it's equals "yes". If yes, the a_find_dialog is a find dialog box build by mlview_tree_editor_find_dialog_retrieve() ;
00951          *if no, return false... just in case ...
00952          */
00953         check_str = gtk_object_get_data(GTK_OBJECT(a_find_dialog),IS_THE_FIND_DIALOG) ;
00954         if(strcmp(check_str, "yes"))
00955                 return FALSE ;
00956         
00957         search_in_attribute_values_check_button = GTK_CHECK_BUTTON(gtk_object_get_data(GTK_OBJECT(a_find_dialog), SEARCH_IN_ATTRIBUTES_VALUES_CHECK_BUTTON)) ;
00958         return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search_in_attribute_values_check_button)) ;
00959 }
00960 
00964 static gboolean 
00965 mlview_tree_editor_find_dialog_search_in_content_is_on (GnomeDialog * a_find_dialog)
00966 {
00967         gchar * check_str ;
00968         GtkCheckButton * search_in_content_check_button ;
00969 
00970         g_return_val_if_fail(GNOME_IS_DIALOG(a_find_dialog), FALSE) ;
00971         
00972         /*a SANITY check:
00973          *get a sanity check string associated to the search dialog by the function mlview_tree_editor_find_dialog_retrieve()
00974          *and see if it's equals "yes". If yes, the a_find_dialog is a find dialog box build by mlview_tree_editor_find_dialog_retrieve() ;
00975          *if no, return false... just in case ...
00976          */
00977         check_str = gtk_object_get_data(GTK_OBJECT(a_find_dialog),IS_THE_FIND_DIALOG) ;
00978         if(strcmp(check_str, "yes"))
00979                 return FALSE ;
00980         
00981         search_in_content_check_button = GTK_CHECK_BUTTON(gtk_object_get_data(GTK_OBJECT(a_find_dialog), SEARCH_IN_CONTENT_CHECK_BUTTON)) ;
00982         return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search_in_content_check_button)) ;
00983 }
00984 
00985 
00992 static gchar * 
00993 mlview_tree_editor_find_dialog_get_searched_text(GnomeDialog * a_find_dialog)
00994 {
00995         gchar * check_str ;
00996         gchar * result ;
00997         GtkEntry * search_string_entry ;
00998 
00999         g_return_val_if_fail(GNOME_IS_DIALOG(a_find_dialog), NULL) ;
01000         
01001         /*a SANITY check:
01002          *get a sanity check string associated to the search dialog by the function mlview_tree_editor_find_dialog_retrieve()
01003          *and see if it's equals "yes". If yes, the a_find_dialog is a find dialog box build by mlview_tree_editor_find_dialog_retrieve() ;
01004          *if no, return false... just in case ...
01005          */
01006         check_str = gtk_object_get_data(GTK_OBJECT(a_find_dialog),IS_THE_FIND_DIALOG) ;
01007         if(strcmp(check_str, "yes"))
01008                 return FALSE ;
01009 
01010         search_string_entry = GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(a_find_dialog), SEARCHED_TEXT_ENTRY)) ;
01011         g_return_val_if_fail(GTK_IS_ENTRY(search_string_entry),NULL);
01012 
01013         result = gtk_entry_get_text(search_string_entry) ;
01014 
01015         if(result != NULL)
01016                 return g_strdup(result) ;
01017         return result ;
01018 }
01019 
01026 static GtkCTreeNode *
01027 mlview_tree_editor_get_data_from_find_dialog_and_perform_search(MlViewTreeEditor *a_tree_editor,
01028                                                                 GnomeDialog *a_dialog, GtkCTreeNode * a_start_from, gboolean a_start_after)
01029 {
01030         gchar * check_str ;
01031         gchar * str_to_search ;
01032         GtkCTreeNode * start_from=NULL, *result=NULL ;
01033         enum WhereInTheNodeBitmap bmp=0 ;
01034 
01035         g_return_val_if_fail(a_dialog != NULL, NULL) ;
01036         g_return_val_if_fail(a_tree_editor != NULL, NULL) ;
01037         g_return_val_if_fail(PRIVATE(a_tree_editor) != NULL, NULL) ;
01038         g_return_val_if_fail(PRIVATE(a_tree_editor)->viewable_doc != NULL, NULL) ;
01039 
01040         /*a SANITY check:
01041          *get a sanity check string associated to the search dialog by the function mlview_tree_editor_find_dialog_retrieve()
01042          *and see if it's equals "yes". If yes, the a_find_dialog is a find dialog box build by mlview_tree_editor_find_dialog_retrieve() ;
01043          *if no, return false... just in case ...
01044          */
01045         check_str = gtk_object_get_data(GTK_OBJECT(a_dialog),IS_THE_FIND_DIALOG) ;
01046         if(strcmp(check_str, "yes"))
01047                 return NULL ;
01048         /*build the bitmap that describes where in the xml node (attribute names?, node names?, node content?) the search functions have to look ...*/
01049         if(mlview_tree_editor_find_dialog_search_in_names_is_on(a_dialog) == TRUE)
01050                 bmp |= NODE_NAME ;
01051         if(mlview_tree_editor_find_dialog_search_in_attributes_names_is_on(a_dialog) == TRUE)
01052                 bmp |= NODE_ATTRIBUTE_NAME ;
01053                         
01054         if(mlview_tree_editor_find_dialog_search_in_attributes_values_is_on(a_dialog) == TRUE)
01055                 bmp |= NODE_ATTRIBUTE_VALUE ;
01056         if(mlview_tree_editor_find_dialog_search_in_content_is_on(a_dialog) == TRUE)
01057                 bmp |= NODE_CONTENT ;
01058         str_to_search = mlview_tree_editor_find_dialog_get_searched_text(a_dialog) ;
01059 
01060         start_from = a_start_from ;
01061         if(start_from == NULL){
01062                 start_from = gtk_ctree_node_nth(PRIVATE(a_tree_editor)->viewable_doc,0) ;
01063                 g_return_val_if_fail(start_from != NULL, NULL) ;
01064         }
01065         if(str_to_search != NULL  &&  strcmp(str_to_search,""))
01066                 result = downward_find_visual_node_that_contains(PRIVATE(a_tree_editor)->viewable_doc,
01067                                                                  start_from,
01068                                                                  str_to_search, bmp, a_start_after) ;
01069         if(result != NULL){
01070                 GtkAdjustment *vadj ;
01071                 gint node_ypos ;
01072                 gtk_ctree_expand_to_depth(PRIVATE(a_tree_editor)->viewable_doc, 
01073                                           gtk_ctree_node_nth(PRIVATE(a_tree_editor)->viewable_doc, 0),
01074                                           GTK_CTREE_ROW(result)->level) ;
01075                 gtk_ctree_select(PRIVATE(a_tree_editor)->viewable_doc, result) ;
01076                 vadj = gtk_clist_get_vadjustment(GTK_CLIST(PRIVATE(a_tree_editor)->viewable_doc)) ;
01077                 if(vadj == NULL)
01078                         return NULL;
01079                 node_ypos = gtk_ctree_node_absolute_top_ypixel(PRIVATE(a_tree_editor)->viewable_doc, result) ;
01080                 gtk_adjustment_set_value(vadj,node_ypos) ;
01081         }
01082         return result ;
01083 }
01084 
01085 
01086 
01087 
01088 
01096 static void
01097 mlview_tree_editor_handle_nt_picker_ok_button_clicked_to_add_child (MlViewTreeEditor *a_tree_editor)
01098 {
01099         guint selected_node_type, node_addion_status ;
01100         MlViewNodeTypePicker *nt_picker ;
01101 
01102         xmlNodePtr xml_node ;
01103         xmlDocPtr xml_doc ;
01104         xmlNs * ns ;
01105         gchar * node_name_or_content, *local_name ;
01106 
01107         g_return_if_fail(a_tree_editor != NULL) ;
01108 
01109         nt_picker = mlview_tree_editor_get_node_type_picker(a_tree_editor) ;
01110         g_return_if_fail(nt_picker != NULL) ;
01111 
01112         node_name_or_content = mlview_node_type_picker_get_node_name_or_content(nt_picker) ;
01113         if (node_name_or_content != NULL && !utils_is_white_string(node_name_or_content)){
01114                 selected_node_type = mlview_node_type_picker_get_selected_node_type(nt_picker) ;
01115                 xml_doc = mlview_tree_editor_get_xml_document(a_tree_editor) ;
01116                 xml_node = new_xml_node(selected_node_type,xml_doc) ;
01117 
01118                 switch(selected_node_type) {
01119                 case XML_ELEMENT_NODE:
01120                 case XML_PI_NODE:
01121                         utils_parse_full_name(xml_node, node_name_or_content, &ns, &local_name) ;
01122                         if(local_name != NULL){
01123                                 xmlNodeSetName(xml_node, g_strdup(local_name)) ;
01124                                 g_free(local_name) ;
01125                                 local_name = NULL ;
01126                         }
01127                         
01128                         break ;
01129                 default:
01130                         xmlNodeSetContent(xml_node, g_strdup(node_name_or_content)) ;
01131                         break ;
01132                 }
01133                 node_addion_status = mlview_tree_editor_add_child_node (a_tree_editor,
01134                                                                         mlview_tree_editor_get_current_selected_node(a_tree_editor),
01135                                                                         xml_node) ;
01136 
01137                 if(!node_addion_status && (selected_node_type == XML_ELEMENT_NODE  ||  selected_node_type == XML_PI_NODE)){
01138                         utils_parse_full_name(xml_node, node_name_or_content, &ns, &local_name) ;
01139                         if(ns){
01140                                 xmlSetNs(xml_node, ns) ;
01141                         }else{
01142                                 xml_node->ns = NULL ;
01143                         }
01144                         if(local_name){
01145                                 g_free(local_name) ;
01146                                 local_name = NULL ;
01147                         }
01148                         //mlview_tree_editor_update_visual_node(a_tree_editor, visual_node) ;
01149                 }
01150         }
01151 }
01152 
01153 
01160 static void
01161 mlview_tree_editor_handle_nt_picker_ok_button_clicked_to_insert_sibling_node (MlViewTreeEditor *a_tree_editor)
01162 {
01163         guint selected_node_type ;
01164         xmlNode *xml_node = NULL, *result_node = NULL ;
01165         xmlDocPtr xml_doc = NULL ;
01166         gpointer previous = NULL ;
01167         MlViewNodeTypePicker *node_type_picker = NULL ;
01168         gchar * node_name_or_content = NULL, *local_name = NULL ;
01169         xmlNs * ns = NULL ;
01170         GtkCTreeNode * visual_node = NULL ;
01171         GtkCTree *visual_tree = NULL ;
01172 
01173         g_return_if_fail(a_tree_editor != NULL) ;
01174 
01175         node_type_picker = mlview_tree_editor_get_node_type_picker(a_tree_editor) ;
01176         g_return_if_fail(node_type_picker != NULL) ;
01177         node_name_or_content = mlview_node_type_picker_get_node_name_or_content(node_type_picker) ;
01178 
01179         if(node_name_or_content != NULL && !utils_is_white_string(node_name_or_content)){
01180                 selected_node_type = mlview_node_type_picker_get_selected_node_type(node_type_picker) ; 
01181                 xml_doc = mlview_tree_editor_get_xml_document(a_tree_editor) ;
01182                 xml_node = new_xml_node(selected_node_type,xml_doc) ;
01183         
01184                 switch(selected_node_type){
01185                 case XML_ELEMENT_NODE:
01186                 case XML_PI_NODE:
01187                         utils_parse_full_name(xml_node, node_name_or_content, &ns, &local_name) ;
01188                         if(local_name != NULL){
01189                                 xmlNodeSetName(xml_node, g_strdup(local_name)) ;
01190                                 g_free(local_name) ;
01191                         }
01192                         break ;
01193                 default:
01194                         xmlNodeSetContent(xml_node, node_name_or_content) ;
01195                         break ;
01196                 }
01197                 /*retrieve a flag set to indicate if the sibling has to be inserted before or after the current xml node*/
01198                 previous = gtk_object_get_data(GTK_OBJECT(a_tree_editor), "prev") ;
01199                 result_node = mlview_tree_editor_insert_sibling_node(a_tree_editor,
01200                                                                      mlview_tree_editor_get_current_selected_node(a_tree_editor),
01201                                                                      xml_node,GPOINTER_TO_INT(previous)) ;
01202 
01203                 if(result_node != NULL && (selected_node_type == XML_ELEMENT_NODE  ||  selected_node_type == XML_PI_NODE)){
01204                         visual_tree = mlview_tree_editor_get_visual_tree (a_tree_editor) ;
01205                         g_return_if_fail (visual_tree != NULL) ;
01206 
01207                         visual_node = gtk_ctree_find_by_row_data (visual_tree, NULL, result_node) ;
01208                         g_return_if_fail (visual_node != NULL) ;
01209 
01210                         utils_parse_full_name (xml_node, node_name_or_content, &ns, &local_name) ;
01211 
01212                         if(ns){
01213                                 xmlSetNs(xml_node, ns) ;
01214                         }else{
01215                                 xml_node->ns = NULL ;
01216                         }
01217                         if(local_name != NULL)
01218                                 g_free(local_name) ;
01219                         mlview_tree_editor_update_visual_node (a_tree_editor, visual_node) ;
01220                 }
01221         }
01222 }
01223 
01224 
01225 static gint
01226 mlview_tree_editor_build_node_insertion_submenu (MlViewTreeEditor *a_editor,
01227                                                  enum NODE_INSERTION_SCHEME a_insertion_scheme,
01228                                                  GtkMenu ** a_submenu)
01229 {
01230         gchar * validation_is_on = NULL ;
01231         GList * attr_names = NULL ;
01232         xmlNode * xml_node = NULL ;
01233         gint nb_names = 0 ;
01234 
01235         g_return_val_if_fail (a_editor != NULL, -5) ;
01236         g_return_val_if_fail (MLVIEW_IS_TREE_EDITOR (a_editor), -5) ;
01237         g_return_val_if_fail (PRIVATE (a_editor) != NULL, -5) ;
01238         g_return_val_if_fail (a_submenu != NULL, -5) ;
01239 
01240         *a_submenu = NULL ;
01241         if (PRIVATE (a_editor)->app_context == NULL)            
01242                 return -4 ;
01243         
01244         if (!PRIVATE (a_editor)->current_selected_node
01245             || !PRIVATE (a_editor)->viewable_doc)
01246                 return -3 ;
01247 
01248         xml_node = gtk_ctree_node_get_row_data (PRIVATE (a_editor)->viewable_doc,
01249                                                 PRIVATE (a_editor)->current_selected_node) ;
01250         if (xml_node == NULL)
01251                 return -3 ;
01252 
01253         validation_is_on = 
01254                 mlview_app_context_get_settings_value (PRIVATE (a_editor)->app_context,
01255                                                        MLVIEW_STG_K_IS_VALIDATION_ON) ;
01256         if (!validation_is_on 
01257             || strcmp (validation_is_on, MLVIEW_STG_V_YES) ) {
01258                 return -2 ;
01259         }
01260 
01261         nb_names = mlview_parsing_utils_build_element_name_completion_list (PRIVATE (a_editor)->app_context,
01262                                                                             a_insertion_scheme, xml_node, &attr_names) ;
01263         if (nb_names != 0) {
01264                 GList *cur = attr_names ;
01265                 GtkMenuItem * menu_item = NULL ;
01266                 *a_submenu = GTK_MENU (gtk_menu_new ()) ;
01267 
01268                 while (cur) {
01269                         menu_item = GTK_MENU_ITEM (gtk_menu_item_new_with_label (cur->data)) ;
01270                         gtk_object_set_data (GTK_OBJECT (menu_item), "element-name", cur->data) ;
01271 
01272                         switch (a_insertion_scheme) {
01273                         case ADD_CHILD:
01274                                 gtk_signal_connect (GTK_OBJECT (menu_item),"activate", 
01275                                                     GTK_SIGNAL_FUNC (menu_add_child_node_activate_cb),
01276                                                     a_editor) ;
01277                                 break ;
01278 
01279                         case INSERT_BEFORE:
01280                                 gtk_signal_connect (GTK_OBJECT (menu_item),"activate", 
01281                                                     GTK_SIGNAL_FUNC (menu_insert_prev_sibling_node_activate_cb),
01282                                                     a_editor) ;
01283                                 break ;
01284                         case INSERT_AFTER:
01285                                 gtk_signal_connect (GTK_OBJECT (menu_item),"activate", 
01286                                                     GTK_SIGNAL_FUNC (menu_insert_next_sibling_node_activate_cb),
01287                                                     a_editor) ;
01288                                 break ;
01289                         default :
01290                                 break ;
01291                         }
01292                         gtk_widget_show (GTK_WIDGET (menu_item)) ;
01293                         gtk_menu_append (*a_submenu, GTK_WIDGET (menu_item)) ;
01294  
01295                         cur = cur->next ;
01296                 }
01297         }
01298         return 0 ;
01299 }
01300 
01301 
01302 
01303 /*===========================================================
01304  *callbacks and signal handlers
01305  *===========================================================
01306  */
01307 
01318 static
01319 void mlview_tree_editor_node_selected_default_signal_handler(MlViewTreeEditor *a_editor, 
01320                                                              GtkCTreeNode *a_visual_node,
01321                                                              gpointer a_user_data)
01322 {
01323         g_assert(a_editor != NULL ) ;
01324         g_assert(PRIVATE(a_editor) != NULL) ;
01325         g_assert(PRIVATE(a_editor)->viewable_doc != NULL) ;
01326 }
01327 
01337 static void 
01338 mlview_tree_editor_tree_select_row_cb (GtkCTree *a_visual_tree,
01339                                       GList * a_node,
01340                                       gint a_column,
01341                                       gpointer a_tree_editor)
01342 {
01343         MlViewTreeEditor * editor ;
01344         
01345         g_assert (a_tree_editor != NULL) ;
01346         g_assert (a_node != NULL) ;
01347         g_assert (a_node->data != NULL) ;
01348         
01349         editor = MLVIEW_TREE_EDITOR (a_tree_editor) ;
01350         g_assert (PRIVATE (editor) != NULL) ;
01351 
01352         PRIVATE (editor)->current_selected_node = GTK_CTREE_NODE (a_node) ;
01353 
01354         gtk_signal_emit (GTK_OBJECT (MLVIEW_TREE_EDITOR (a_tree_editor)),
01355                          mlview_tree_editor_signals[NODE_SELECTED],
01356                          GTK_CTREE_NODE (a_node)/*visual_node*/) ;
01357 }
01358 
01359 static void
01360 menu_add_child_node_activate_cb (GtkMenuItem *a_menu_item,
01361                                  gpointer a_user_data)
01362 {
01363         MlViewTreeEditor * tree_editor = NULL ;
01364         gchar * element_name = NULL ;
01365 
01366         g_return_if_fail (a_menu_item != NULL) ;
01367         g_return_if_fail (GTK_IS_MENU_ITEM (a_menu_item)) ;
01368         g_return_if_fail (a_user_data != NULL) ;
01369         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_user_data)) ;
01370         
01371         tree_editor = MLVIEW_TREE_EDITOR (a_user_data) ;
01372         g_return_if_fail (PRIVATE (tree_editor) != NULL) ;
01373         g_return_if_fail (PRIVATE (tree_editor)->current_selected_node != NULL) ;
01374         g_return_if_fail (PRIVATE (tree_editor)->viewable_doc != NULL) ;
01375 
01376         element_name = gtk_object_get_data (GTK_OBJECT (a_menu_item), "element-name") ;
01377 
01378         if (element_name) {             
01379                 xmlNode *xml_node = xmlNewNode (NULL, element_name) ;
01380                 mlview_tree_editor_add_child_node (tree_editor,
01381                                                    PRIVATE (tree_editor)->current_selected_node,
01382                                                    xml_node) ;
01383         }
01384 }
01385 
01386 static void
01387 menu_insert_prev_sibling_node_activate_cb (GtkMenuItem *a_menu_item,
01388                                            gpointer a_user_data)
01389 {
01390         MlViewTreeEditor * tree_editor = NULL ;
01391         gchar * element_name = NULL ;
01392 
01393         g_return_if_fail (a_menu_item != NULL) ;
01394         g_return_if_fail (GTK_IS_MENU_ITEM (a_menu_item)) ;
01395         g_return_if_fail (a_user_data != NULL) ;
01396         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_user_data)) ;
01397         
01398         tree_editor = MLVIEW_TREE_EDITOR (a_user_data) ;
01399         g_return_if_fail (PRIVATE (tree_editor) != NULL) ;
01400         g_return_if_fail (PRIVATE (tree_editor)->current_selected_node != NULL) ;
01401         g_return_if_fail (PRIVATE (tree_editor)->viewable_doc != NULL) ;
01402 
01403         element_name = gtk_object_get_data (GTK_OBJECT (a_menu_item), "element-name") ;
01404 
01405         if (element_name) {
01406                 xmlNode *xml_node = xmlNewNode (NULL, element_name) ;
01407                 mlview_tree_editor_insert_sibling_node (tree_editor,
01408                                                         PRIVATE (tree_editor)->current_selected_node,
01409                                                         xml_node, TRUE) ;
01410         }
01411 }
01412 
01413 static void
01414 menu_insert_next_sibling_node_activate_cb (GtkMenuItem *a_menu_item,
01415                                            gpointer a_user_data)
01416 {
01417         MlViewTreeEditor * tree_editor = NULL ;
01418         gchar * element_name = NULL ;
01419 
01420         g_return_if_fail (a_menu_item != NULL) ;
01421         g_return_if_fail (GTK_IS_MENU_ITEM (a_menu_item)) ;
01422         g_return_if_fail (a_user_data != NULL) ;
01423         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_user_data)) ;
01424         
01425         tree_editor = MLVIEW_TREE_EDITOR (a_user_data) ;
01426         g_return_if_fail (PRIVATE (tree_editor) != NULL) ;
01427         g_return_if_fail (PRIVATE (tree_editor)->current_selected_node != NULL) ;
01428         g_return_if_fail (PRIVATE (tree_editor)->viewable_doc != NULL) ;
01429 
01430         element_name = gtk_object_get_data (GTK_OBJECT (a_menu_item), "element-name") ;
01431 
01432         if (element_name) {             
01433                 xmlNode *xml_node = xmlNewNode (NULL, element_name) ;
01434                 mlview_tree_editor_insert_sibling_node (tree_editor,
01435                                                         PRIVATE (tree_editor)->current_selected_node,
01436                                                         xml_node, FALSE) ;
01437         }
01438 }
01439 
01440 static gboolean
01441 mlview_tree_editor_event_cb (GtkWidget * a_widget,
01442                                GdkEvent *a_event,
01443                                gpointer a_user_data) {
01444 
01445           MlViewTreeEditor * tree_editor = NULL ;
01446 
01447           g_return_val_if_fail (a_widget != NULL, FALSE) ;
01448           g_return_val_if_fail (GTK_IS_WIDGET (a_widget), FALSE) ;
01449           g_return_val_if_fail (a_user_data != NULL, FALSE) ;
01450           g_return_val_if_fail (MLVIEW_IS_TREE_EDITOR (a_user_data), FALSE) ;
01451           g_return_val_if_fail (a_event != NULL, FALSE) ;
01452 
01453           tree_editor = MLVIEW_TREE_EDITOR (a_user_data) ;
01454           g_return_val_if_fail (tree_editor != NULL, FALSE) ;
01455           g_return_val_if_fail (PRIVATE (tree_editor), FALSE) ;
01456           
01457           switch (a_event->type) {
01458           case GDK_BUTTON_PRESS :
01459                   if (a_event->button.button == 3) { /*user pressed the right mouse button*/
01460                           GtkWidget * root_widget = gtk_widget_get_toplevel (GTK_WIDGET (tree_editor)) ;
01461                           g_return_val_if_fail (root_widget != NULL, FALSE) ;
01462                           gtk_propagate_event (root_widget, a_event) ;
01463                   }
01464                   break ;
01465           default :
01466                   break ;
01467           }
01468           return TRUE ;
01469 }
01470 
01471 
01472 /*===============================================================
01473  *public methods
01474  *===============================================================
01475  */
01476 
01482 guint
01483 mlview_tree_editor_get_type (void)
01484 {
01485         static guint mlview_tree_editor_type=0 ;
01486 
01487         if(!mlview_tree_editor_type){
01488                 static const GtkTypeInfo t_info={
01489                         "MlViewTreeEditor",
01490                         sizeof(MlViewTreeEditor),
01491                         sizeof(MlViewTreeEditorClass),
01492                         (GtkClassInitFunc)mlview_tree_editor_init_class,
01493                         (GtkObjectInitFunc)mlview_tree_editor_init,
01494                         NULL,NULL,NULL
01495                 };
01496                 mlview_tree_editor_type=gtk_type_unique(GTK_TYPE_VBOX,&t_info) ;
01497         }
01498         return mlview_tree_editor_type ;
01499 }
01500 
01501 
01510 GtkWidget *
01511 mlview_tree_editor_new (MlViewAppContext * a_context)
01512 {
01513         MlViewTreeEditor *editor ;
01514         editor = gtk_type_new (MLVIEW_TYPE_TREE_EDITOR) ;
01515         PRIVATE (editor)->app_context = a_context ;
01516 
01517         gtk_signal_connect (GTK_OBJECT (editor),
01518                             "button_press_event",
01519                             GTK_SIGNAL_FUNC (mlview_tree_editor_event_cb),
01520                             editor) ;
01521 
01522         return GTK_WIDGET (editor) ;
01523 }
01524 
01525 void 
01526 mlview_tree_editor_set_application_context (MlViewTreeEditor * a_tree_editor,
01527                                             MlViewAppContext *a_app_context)
01528 {
01529         g_return_if_fail (a_tree_editor != NULL) ;
01530         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
01531         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
01532 
01533         PRIVATE (a_tree_editor)->app_context = a_app_context ;
01534 }
01535 
01536 
01537 MlViewAppContext * 
01538 mlview_tree_editor_get_application_context (MlViewTreeEditor *a_tree_editor)
01539 {
01540         g_return_val_if_fail (a_tree_editor != NULL, NULL) ;
01541         g_return_val_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor), NULL) ;
01542         g_return_val_if_fail (PRIVATE (a_tree_editor) != NULL, NULL) ;
01543 
01544         return PRIVATE (a_tree_editor)->app_context ;
01545 }
01546 
01547 
01558 void
01559 mlview_tree_editor_set_xml_document_path (MlViewTreeEditor * a_tree_editor, gchar * a_file_path)
01560 {
01561         g_return_if_fail (a_tree_editor != NULL) ;
01562         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
01563         g_return_if_fail (a_file_path != NULL) ;
01564 
01565         if ( !PRIVATE (a_tree_editor)->xml_doc )
01566                 return ;
01567 
01568         if ( PRIVATE (a_tree_editor)->xml_doc->name )
01569                 g_free (PRIVATE (a_tree_editor)->xml_doc->name) ;
01570 
01571         PRIVATE (a_tree_editor)->xml_doc->name = g_strdup (a_file_path) ;
01572         gtk_clist_set_column_title (GTK_CLIST (PRIVATE (a_tree_editor)->viewable_doc),
01573                                     TREE_EDITOR_TREE_COLUMN, 
01574                                     PRIVATE (a_tree_editor)->xml_doc->name) ;
01575 }
01576 
01577 
01588 guint
01589 mlview_tree_editor_edit_xml_doc (MlViewTreeEditor *a_editor, MlViewXMLDocument *a_mlview_xml_doc, gchar * a_doc_name)
01590 {       
01591         GtkCTree * viewable_doc = NULL ;
01592         GtkWidget * scr_win = NULL ;
01593         glong expansion_depth = MLVIEW_TREE_EDITOR_DEFAULT_EXPANSION_DEPTH ;
01594         gchar * expansion_depth_str = NULL ;
01595         GHashTable *settings = NULL ;
01596         xmlDoc * xml_doc = NULL ;
01597 
01598         g_return_val_if_fail (a_editor != NULL, -1) ;
01599         g_return_val_if_fail (MLVIEW_IS_TREE_EDITOR (a_editor), -1) ;
01600         g_return_val_if_fail (PRIVATE (a_editor) != NULL ,-1) ;
01601         g_return_val_if_fail (a_mlview_xml_doc != NULL, -1) ;
01602         g_return_val_if_fail (MLVIEW_IS_XML_DOCUMENT (a_mlview_xml_doc), -1) ;
01603 
01604         xml_doc = mlview_xml_document_get_xml_document ((MlViewXMLDocument*)a_mlview_xml_doc) ;
01605         g_return_val_if_fail (xml_doc != NULL, -1) ;
01606 
01607         PRIVATE (a_editor)->mlview_xml_doc = a_mlview_xml_doc ;
01608 
01609         if (PRIVATE (a_editor)->app_context)
01610                 settings = mlview_app_context_get_settings_hash_table (PRIVATE (a_editor)->app_context) ;
01611 
01612         if (settings 
01613             && (expansion_depth_str = g_hash_table_lookup (settings, MLVIEW_STG_K_DEFAULT_TREE_EXPANSION_LEVEL)))
01614                 expansion_depth = strtol (expansion_depth_str, NULL, 10) ;
01615         if ((expansion_depth == LONG_MIN)  ||  (expansion_depth == LONG_MAX))
01616                 expansion_depth = MLVIEW_TREE_EDITOR_DEFAULT_EXPANSION_DEPTH ;
01617 
01618         build_ctree_from_xml_doc (PRIVATE (a_editor)->app_context, xml_doc,
01619                                  &viewable_doc, a_doc_name, expansion_depth) ;
01620 
01621         g_assert(viewable_doc != NULL) ;
01622 
01623         if (PRIVATE(a_editor)->viewable_doc) {
01624                 gtk_widget_destroy (GTK_WIDGET (PRIVATE (a_editor)->viewable_doc)) ;
01625         }
01626         
01627         PRIVATE (a_editor)->viewable_doc = viewable_doc ;
01628         gtk_signal_connect (GTK_OBJECT (viewable_doc),
01629                             "tree-select-row",
01630                             GTK_SIGNAL_FUNC (mlview_tree_editor_tree_select_row_cb),
01631                             a_editor) ;
01632         scr_win = gtk_scrolled_window_new (NULL, NULL) ;
01633         gtk_container_add (GTK_CONTAINER (scr_win), GTK_WIDGET (viewable_doc)) ;
01634         gtk_box_pack_start (GTK_BOX (a_editor), scr_win,
01635                             TRUE,TRUE,0) ;
01636         gtk_widget_show_all (GTK_WIDGET (a_editor)) ;
01637         PRIVATE (a_editor)->xml_doc = xml_doc ;
01638         return 0 ;
01639 }
01640 
01641 
01642 void
01643 mlview_tree_editor_update_visual_xml_node (MlViewTreeEditor *a_tree_editor, 
01644                                            xmlNode * a_node)
01645 {
01646         GtkCTreeNode * visual_node = NULL ;
01647 
01648         g_return_if_fail (a_tree_editor != NULL) ;
01649         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
01650         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
01651         g_return_if_fail (PRIVATE (a_tree_editor)->viewable_doc != NULL) ;
01652         g_return_if_fail (a_node != NULL) ;
01653 
01654         visual_node = gtk_ctree_find_by_row_data (PRIVATE (a_tree_editor)->viewable_doc, NULL,
01655                                                   a_node) ;
01656         g_return_if_fail (visual_node != NULL) ;
01657         mlview_tree_editor_update_visual_node (a_tree_editor, visual_node) ;
01658 
01659 }
01660 
01671 void
01672 mlview_tree_editor_update_visual_node (MlViewTreeEditor *a_tree_editor, 
01673                                        GtkCTreeNode * a_visual_node)
01674 {
01675         xmlNodePtr xml_node=NULL ;
01676         gchar * tag_string=NULL ;
01677         GdkPixmap *pixmap = NULL ;
01678         GdkBitmap *bitmap = NULL ;
01679         guint8 spacing ;
01680         gchar * text = NULL ;
01681 
01682         g_return_if_fail (a_tree_editor != NULL) ;
01683         g_return_if_fail (MLVIEW_TREE_EDITOR (a_tree_editor)) ;
01684         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
01685         g_return_if_fail (PRIVATE (a_tree_editor)->viewable_doc != NULL) ;
01686         g_return_if_fail (a_visual_node != NULL) ;
01687 
01688         xml_node = (xmlNodePtr) gtk_ctree_node_get_row_data (PRIVATE (a_tree_editor)->viewable_doc,
01689                                                              a_visual_node) ;
01690         g_return_if_fail (xml_node != NULL) ;
01691         tag_string = node_to_start_tag (xml_node) ;
01692 
01693         if (tag_string != NULL) {
01694 
01695                 gtk_ctree_node_get_pixtext (PRIVATE (a_tree_editor)->viewable_doc, a_visual_node, 
01696                                             TREE_EDITOR_TREE_COLUMN, &text , &spacing, &pixmap, &bitmap) ;
01697 
01698                 gtk_ctree_node_set_pixtext (PRIVATE (a_tree_editor)->viewable_doc,
01699                                             a_visual_node, TREE_EDITOR_TREE_COLUMN, tag_string, 
01700                                             TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT, pixmap, bitmap) ;
01701                 g_free (tag_string) ;
01702 
01703                 gtk_widget_show (GTK_WIDGET (PRIVATE (a_tree_editor)->viewable_doc)) ;
01704         }
01705 }
01706 
01714 void
01715 mlview_tree_editor_destroy (GtkObject *a_object)
01716 {
01717         MlViewTreeEditor *editor ;
01718         g_return_if_fail(a_object) ;
01719 
01720         editor = MLVIEW_TREE_EDITOR (a_object) ;
01721         g_return_if_fail (PRIVATE (editor) != NULL) ;
01722 
01723         if (p_find_dialog != NULL) {
01724                 gtk_widget_destroy (GTK_WIDGET (p_find_dialog)) ;
01725                 p_find_dialog = NULL ;
01726         }
01727 
01728         if (PRIVATE(editor)->node_type_picker != NULL) {
01729                 gtk_widget_destroy (GTK_WIDGET (PRIVATE (editor)->node_type_picker)) ;
01730                 PRIVATE (editor)->node_type_picker = NULL ;
01731         }
01732         if (PRIVATE (editor)->viewable_doc) {
01733                 gtk_widget_destroy (GTK_WIDGET (PRIVATE(editor)->viewable_doc)) ;
01734                 PRIVATE (editor)->viewable_doc=NULL;
01735         }
01736 
01737         if (PRIVATE (editor) != NULL){
01738                 g_free(PRIVATE(editor) ) ;
01739                 PRIVATE(editor) = NULL ;
01740         }
01741         
01742         if (GTK_OBJECT_CLASS(parent_class)->destroy) {
01743                 (*GTK_OBJECT_CLASS(parent_class)->destroy)(a_object) ;
01744         }
01745 }
01746 
01747 
01762 void
01763 mlview_tree_editor_update_child_node_added (MlViewTreeEditor * a_tree_editor,
01764                                             xmlNode *a_parent_node, xmlNode *a_added_node)
01765 {
01766         GtkCTreeNode *result = NULL, *parent_visual_node = NULL, *visual_added_node = NULL ;
01767         GtkCTree *visual_tree = NULL ;
01768 
01769         g_return_if_fail (a_tree_editor != NULL) ;
01770         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
01771         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
01772 
01773         g_return_if_fail (a_parent_node != NULL) ;
01774         g_return_if_fail (a_added_node != NULL) ;
01775 
01776         g_return_if_fail (a_parent_node->type == XML_ELEMENT_NODE) ; /*only an element node should have children*/
01777         visual_tree =  mlview_tree_editor_get_visual_tree (a_tree_editor);
01778         g_return_if_fail (visual_tree != NULL) ;
01779 
01780         parent_visual_node = gtk_ctree_find_by_row_data (visual_tree, NULL, a_parent_node) ;
01781         g_return_if_fail (parent_visual_node != NULL) ;/*make sure the parent node has been drawn on the editor already.*/
01782 
01783         visual_added_node = gtk_ctree_find_by_row_data (visual_tree, NULL, a_added_node) ; 
01784         g_return_if_fail (visual_added_node == NULL) ;/*Make sure this node hasn't been drawn yet*/
01785 
01786         result = build_ctree_from_xml_tree (PRIVATE (a_tree_editor)->app_context,
01787                                             a_added_node, parent_visual_node, &visual_tree) ;
01788 
01789         mlview_tree_editor_update_visual_node (a_tree_editor, parent_visual_node) ;
01790 
01791         if (! gtk_ctree_is_viewable (visual_tree, result))
01792                 mlview_tree_editor_expand_tree_to_depth (a_tree_editor, 1) ;
01793 
01794         gtk_ctree_select (visual_tree, result) ;
01795 
01796         /*emit the appropriate signals*/
01797         gtk_signal_emit (GTK_OBJECT (a_tree_editor),
01798                          mlview_tree_editor_signals [NODE_ADDED],
01799                          (gpointer) result) ;
01800 
01801         gtk_signal_emit (GTK_OBJECT (a_tree_editor),
01802                          mlview_tree_editor_signals [TREE_CHANGED])  ;
01803 }
01804 
01813 void 
01814 mlview_tree_editor_update_node_cut (MlViewTreeEditor *a_tree_editor, xmlNode *a_parent_node,
01815                                     xmlNode *a_cut_node)
01816 
01817 {
01818 
01819         GtkCTree *visual_tree=NULL ;
01820         GtkCTreeNode * parent_visual_node = NULL, *visual_cut_node = NULL;
01821 
01822         g_return_if_fail (a_tree_editor != NULL) ;
01823         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
01824         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
01825         g_return_if_fail (PRIVATE (a_tree_editor)->viewable_doc != NULL) ;
01826         g_return_if_fail (a_parent_node != NULL) ;
01827         g_return_if_fail (a_cut_node != NULL) ;
01828 
01829         visual_tree = mlview_tree_editor_get_visual_tree (a_tree_editor) ;
01830         g_return_if_fail (visual_tree != NULL) ;
01831 
01832         visual_cut_node = gtk_ctree_find_by_row_data (visual_tree, NULL, a_cut_node) ; 
01833         g_return_if_fail (visual_cut_node != NULL) ;/*Make sure this node has been draw already.*/
01834 
01835         parent_visual_node = gtk_ctree_find_by_row_data (visual_tree, NULL, a_parent_node) ;
01836         g_return_if_fail (parent_visual_node != NULL) ;
01837 
01838         gtk_ctree_remove_node (visual_tree, visual_cut_node) ;
01839 
01840         mlview_tree_editor_update_visual_node (a_tree_editor, parent_visual_node) ;
01841 
01842         gtk_ctree_select (visual_tree,parent_visual_node) ;
01843 
01844         /*emit the appropriate signals*/
01845         gtk_signal_emit (GTK_OBJECT (a_tree_editor),
01846                          mlview_tree_editor_signals [NODE_CUT],
01847                          visual_cut_node) ;
01848 
01849         gtk_signal_emit (GTK_OBJECT(a_tree_editor),
01850                          mlview_tree_editor_signals [TREE_CHANGED]) ;
01851 }
01852 
01853 
01862 void 
01863 mlview_tree_editor_update_node_pasted (MlViewTreeEditor *a_tree_editor, xmlNode *a_parent_node,
01864                                        xmlNode *a_pasted_node)
01865 {
01866         GtkCTree *visual_tree=NULL ;
01867         GtkCTreeNode * parent_visual_node = NULL, *visual_node = NULL, *visual_pasted_node= NULL ;
01868 
01869         
01870         g_return_if_fail (a_tree_editor != NULL) ;
01871         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
01872         g_return_if_fail (PRIVATE (a_tree_editor)) ;
01873         g_return_if_fail (a_parent_node != NULL) ;
01874         g_return_if_fail (a_pasted_node != NULL) ;
01875 
01876         visual_pasted_node = gtk_ctree_find_by_row_data (visual_tree, NULL, a_pasted_node) ; 
01877         g_return_if_fail (visual_pasted_node == NULL) ;/*Make sure this node hasn't been drawn yet*/
01878         
01879         visual_tree = mlview_tree_editor_get_visual_tree (a_tree_editor) ;
01880         g_return_if_fail (visual_tree != NULL) ;
01881 
01882         parent_visual_node = gtk_ctree_find_by_row_data (visual_tree, NULL, a_parent_node) ;
01883         g_return_if_fail (parent_visual_node != NULL) ;
01884 
01885         mlview_tree_editor_update_child_node_added (a_tree_editor, a_parent_node, a_pasted_node) ;
01886 
01887         gtk_signal_emit (GTK_OBJECT (a_tree_editor),
01888                          mlview_tree_editor_signals [NODE_PASTED],
01889                          visual_node) ;
01890 }
01891 
01892 
01893 void
01894 mlview_tree_editor_update_sibling_node_inserted (MlViewTreeEditor * a_tree_editor, 
01895                                                  xmlNode * a_sibling_node,
01896                                                  xmlNode * a_inserted_node,
01897                                                  gboolean a_previous)
01898 {
01899         GtkCTreeNode * visual_sibling_node = NULL, *visual_inserted_node = NULL, *result = NULL, *visual_parent_node = NULL ;
01900         GtkCTree * visual_tree = NULL ;
01901         gchar * tag_str = NULL ;
01902 
01903         GdkPixmap * open_element_node_xpm = NULL ;
01904         GdkBitmap *open_element_node_bmp = NULL ;
01905         GdkPixmap * close_element_node_xpm = NULL ;
01906         GdkBitmap * close_element_node_bmp = NULL ;
01907         GdkPixmap * text_node_xpm = NULL ;
01908         GdkBitmap * text_node_bmp = NULL ;
01909 
01910         g_return_if_fail (a_tree_editor != NULL) ;
01911         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
01912         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
01913         g_return_if_fail (a_sibling_node != NULL) ;
01914         g_return_if_fail (a_inserted_node != NULL) ;
01915 
01916         mlview_app_context_get_xpm (PRIVATE (a_tree_editor)->app_context, (char *)MLVIEW_STG_K_OPEN_ELEMENT_NODE_XPM,
01917                                     &open_element_node_xpm, &open_element_node_bmp) ;
01918 
01919         mlview_app_context_get_xpm (PRIVATE (a_tree_editor)->app_context, (char *)MLVIEW_STG_K_CLOSE_ELEMENT_NODE_XPM,
01920                                     &close_element_node_xpm, &close_element_node_bmp) ;
01921 
01922         mlview_app_context_get_xpm (PRIVATE (a_tree_editor)->app_context, (char *)MLVIEW_STG_K_TEXT_NODE_XPM,
01923                                     &text_node_xpm, &text_node_bmp) ;
01924 
01925         visual_tree = mlview_tree_editor_get_visual_tree (a_tree_editor);
01926         g_return_if_fail (visual_tree != NULL) ;        
01927 
01928         visual_inserted_node = gtk_ctree_find_by_row_data (visual_tree, NULL, a_inserted_node) ;
01929         g_return_if_fail (visual_inserted_node == NULL) ; /*Make sure the node has not been drawn before*/
01930 
01931         tag_str = node_to_start_tag (a_inserted_node) ;
01932         g_return_if_fail (tag_str != NULL) ;
01933 
01934         visual_sibling_node = gtk_ctree_find_by_row_data (visual_tree, NULL, a_sibling_node) ;
01935         g_return_if_fail (visual_sibling_node != NULL) ;
01936 
01937         visual_parent_node = GTK_CTREE_ROW (visual_sibling_node)->parent ;
01938 
01939         if (a_previous == FALSE) {              
01940                 visual_sibling_node = (GTK_CTREE_ROW (visual_sibling_node)->sibling == NULL)?NULL : GTK_CTREE_ROW (visual_sibling_node)->sibling ;
01941         }       
01942 
01943         if (a_inserted_node->type == XML_ELEMENT_NODE)
01944                 result = gtk_ctree_insert_node (visual_tree, visual_parent_node,
01945                                                 visual_sibling_node, &tag_str, TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT,
01946                                                 close_element_node_xpm, close_element_node_bmp,
01947                                                 open_element_node_xpm, open_element_node_bmp, FALSE, FALSE) ;
01948         else
01949                 result = gtk_ctree_insert_node (visual_tree, visual_parent_node,
01950                                                 visual_sibling_node, &tag_str, TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT,
01951                                                 text_node_xpm, text_node_bmp, text_node_xpm, text_node_bmp, FALSE, FALSE) ;
01952 
01953         g_return_if_fail (result != NULL) ;
01954 
01955         if (a_inserted_node->children != NULL) {
01956                 build_ctree_from_xml_tree (PRIVATE (a_tree_editor)->app_context,
01957                                            a_inserted_node->children, result, &visual_tree) ;
01958         }
01959         
01960         gtk_ctree_node_set_row_data (visual_tree, result, a_inserted_node) ;
01961         mlview_tree_editor_update_visual_node (a_tree_editor, visual_parent_node) ;
01962         gtk_ctree_select (visual_tree, result) ;
01963 }
01964 
01965 
01978 gint
01979 mlview_tree_editor_add_child_node (MlViewTreeEditor *a_tree_editor,
01980                                    GtkCTreeNode *a_parent_node,
01981                                    xmlNode *a_xml_node)
01982 {
01983         xmlNode *parent_xml_node = NULL ;
01984         xmlNode * added_node = NULL ;
01985         GtkCTree * visual_tree = NULL ;
01986 
01987         g_return_val_if_fail (a_tree_editor != NULL, -1) ;
01988         g_return_val_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor), -1) ;
01989         g_return_val_if_fail (PRIVATE (a_tree_editor) != NULL, -1) ;
01990         g_return_val_if_fail (PRIVATE (a_tree_editor)->mlview_xml_doc != NULL, -1) ;
01991 
01992         g_return_val_if_fail (a_parent_node != NULL, -1) ;
01993         g_return_val_if_fail (a_xml_node != NULL, -1) ;
01994 
01995         visual_tree =  mlview_tree_editor_get_visual_tree (a_tree_editor);
01996         g_return_val_if_fail (visual_tree != NULL, -1) ;
01997 
01998         parent_xml_node = (xmlNodePtr) gtk_ctree_node_get_row_data (visual_tree, a_parent_node) ;
01999 
02000         added_node = 
02001                 mlview_xml_document_add_child_node (PRIVATE (a_tree_editor)->mlview_xml_doc,
02002                                                     parent_xml_node, a_xml_node, TRUE) ;
02003         if (added_node)
02004                 return 0 ;
02005         return 1 ;
02006 }
02007 
02008 
02022 xmlNode *
02023 mlview_tree_editor_insert_sibling_node (MlViewTreeEditor *a_tree_editor, GtkCTreeNode *a_sibling_node,
02024                                         xmlNodePtr a_xml_node, gboolean a_previous)
02025 {
02026         xmlNode *sibling_xml_node = NULL, *result = NULL ;
02027         GtkCTree * visual_tree = NULL ;
02028 
02029         g_return_val_if_fail (a_tree_editor != NULL, NULL) ;
02030         g_return_val_if_fail (a_sibling_node != NULL, NULL) ;
02031         g_return_val_if_fail (a_xml_node != NULL, NULL) ;
02032 
02033         visual_tree = mlview_tree_editor_get_visual_tree (a_tree_editor);
02034         g_return_val_if_fail (visual_tree != NULL, NULL) ;
02035         
02036         sibling_xml_node = (xmlNodePtr) gtk_ctree_node_get_row_data (visual_tree, a_sibling_node) ;
02037         g_return_val_if_fail (sibling_xml_node != NULL, NULL) ; 
02038 
02039         if (a_previous == TRUE) {/*insert the node as previous sibling*/
02040 
02041                 result = mlview_xml_document_insert_prev_sibling_node (PRIVATE (a_tree_editor)->mlview_xml_doc,
02042                                                                        sibling_xml_node, a_xml_node, TRUE) ;            
02043         } else {/*insert the node as next sibling*/
02044 
02045                 result = mlview_xml_document_insert_next_sibling_node (PRIVATE (a_tree_editor)->mlview_xml_doc,
02046                                                                        sibling_xml_node, a_xml_node, TRUE) ;
02047         }
02048 
02049         return result ;
02050 }
02051 
02052 
02062 void
02063 mlview_tree_editor_cut_node (MlViewTreeEditor *a_tree_editor, GtkCTreeNode *a_visual_node)
02064 {
02065         xmlNodePtr xml_node=NULL ;
02066         GtkCTree *visual_tree=NULL ;
02067 
02068         g_return_if_fail (a_tree_editor != NULL) ;
02069         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
02070         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
02071         g_return_if_fail (PRIVATE (a_tree_editor)->mlview_xml_doc != NULL) ;
02072         g_return_if_fail (a_visual_node != NULL) ;
02073 
02074         visual_tree = mlview_tree_editor_get_visual_tree (a_tree_editor) ;
02075         g_return_if_fail (visual_tree != NULL) ;
02076 
02077         xml_node = (xmlNodePtr) gtk_ctree_node_get_row_data (visual_tree, a_visual_node) ;
02078         g_return_if_fail (xml_node) ;
02079 
02080         mlview_xml_document_cut_node (PRIVATE (a_tree_editor)->mlview_xml_doc, xml_node) ;
02081 }
02082 
02083 
02092 void 
02093 mlview_tree_editor_copy_node (MlViewTreeEditor *a_tree_editor,
02094                               GtkCTreeNode * a_visual_node, 
02095                               gboolean a_recursive)
02096 {
02097         GtkCTree * visual_tree=NULL ;
02098         xmlNodePtr xml_node = NULL;
02099         
02100         g_return_if_fail (a_tree_editor != NULL) ;
02101         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
02102         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
02103         g_return_if_fail (a_visual_node != NULL) ;
02104 
02105         visual_tree = mlview_tree_editor_get_visual_tree (a_tree_editor) ;
02106         g_return_if_fail (visual_tree != NULL) ;
02107 
02108         xml_node = (xmlNodePtr) gtk_ctree_node_get_row_data (visual_tree, a_visual_node) ;
02109         g_return_if_fail (xml_node) ;
02110 
02111         mlview_xml_document_copy_node_to_clipboard (xml_node, PRIVATE (a_tree_editor)->xml_doc) ;
02112 }
02113 
02114 
02121 GtkCTreeNode * 
02122 mlview_tree_editor_get_current_selected_node (MlViewTreeEditor * a_tree_editor)
02123 {
02124         g_return_val_if_fail (a_tree_editor != NULL, NULL) ;
02125         g_return_val_if_fail (PRIVATE(a_tree_editor) != NULL, NULL) ;
02126 
02127         return PRIVATE (a_tree_editor)->current_selected_node ;
02128 }
02129 
02130 
02139 void
02140 mlview_tree_editor_create_new_xml_doc (MlViewTreeEditor *a_tree_editor, MlViewXMLDocument* a_xml_doc)
02141 {
02142         g_return_if_fail(a_tree_editor != NULL) ;
02143         g_return_if_fail(a_xml_doc != NULL) ;   
02144         g_return_if_fail(PRIVATE(a_tree_editor) != NULL) ;
02145         
02146         
02147         mlview_tree_editor_edit_xml_doc (a_tree_editor, a_xml_doc, NULL) ;
02148 }
02149 
02150 
02160 GtkCTreeNode *
02161 mlview_tree_editor_set_root_element (MlViewTreeEditor *a_tree_editor, xmlNodePtr a_xml_root_node)
02162 {
02163         GtkCTreeNode *visual_doc_node=NULL,*result=NULL ;
02164         xmlNode * tmp_node = NULL ;
02165         gchar * tag_string ;
02166 
02167         g_return_val_if_fail(a_tree_editor != NULL,NULL) ;
02168         g_return_val_if_fail(a_xml_root_node != NULL,NULL) ;
02169         g_return_val_if_fail(PRIVATE(a_tree_editor) != NULL,NULL) ;
02170         g_return_val_if_fail(PRIVATE(a_tree_editor)->viewable_doc != NULL,NULL) ;
02171         g_return_val_if_fail(PRIVATE(a_tree_editor)->xml_doc != NULL,NULL) ;
02172         g_return_val_if_fail(visual_doc_node != NULL,NULL) ;
02173 
02174         tmp_node = xmlAddChild ((xmlNode *)PRIVATE(a_tree_editor)->xml_doc,
02175                                 a_xml_root_node) ;
02176         g_return_val_if_fail (tmp_node != NULL, NULL) ;
02177 
02178         xmlDocSetRootElement (PRIVATE(a_tree_editor)->xml_doc, a_xml_root_node) ;
02179         tag_string = node_to_start_tag (a_xml_root_node) ;
02180         result = gtk_ctree_insert_node (PRIVATE(a_tree_editor)->viewable_doc,
02181                                        NULL,
02182                                        NULL,&tag_string,
02183                                        TREE_EDITOR_SPACE_BETWEEN_PIXMAP_AND_TEXT,
02184                                        NULL,NULL,NULL,NULL,
02185                                        FALSE,TRUE) ;
02186         if(tag_string != NULL)
02187                 g_free(tag_string) ;
02188         g_return_val_if_fail(result != NULL,NULL) ;
02189         gtk_ctree_node_set_row_data(PRIVATE(a_tree_editor)->viewable_doc,
02190                                     result,a_xml_root_node) ;
02191         gtk_ctree_select(PRIVATE(a_tree_editor)->viewable_doc, result) ;
02192                 
02193         gtk_signal_emit (GTK_OBJECT(a_tree_editor),
02194                          mlview_tree_editor_signals [NODE_ADDED],
02195                          (gpointer) result) ;
02196 
02197         gtk_signal_emit (GTK_OBJECT (a_tree_editor), mlview_tree_editor_signals [TREE_CHANGED]) ;
02198 
02199         return result ;
02200 }
02201 
02202 
02212 void
02213 mlview_tree_editor_paste_node_as_child (MlViewTreeEditor *a_tree_editor,
02214                                         GtkCTreeNode * a_visual_parent_node)
02215 {
02216         xmlNode *parent_xml_node = NULL ;
02217 
02218         g_return_if_fail (a_tree_editor != NULL) ;
02219         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
02220         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
02221         g_return_if_fail (PRIVATE (a_tree_editor)->viewable_doc) ;
02222 
02223         g_return_if_fail (a_visual_parent_node != NULL) ;
02224         g_return_if_fail (PRIVATE (a_tree_editor)->viewable_doc) ;
02225 
02226         parent_xml_node = gtk_ctree_node_get_row_data (PRIVATE (a_tree_editor)->viewable_doc,
02227                                                        a_visual_parent_node) ;
02228         g_return_if_fail (parent_xml_node != NULL) ;
02229 
02230         mlview_xml_document_paste_node_as_child (PRIVATE (a_tree_editor)->mlview_xml_doc,
02231                                                  parent_xml_node) ;
02232 
02233         gtk_signal_emit (GTK_OBJECT (a_tree_editor),
02234                         mlview_tree_editor_signals[TREE_CHANGED]) ;
02235 }
02236 
02246 void
02247 mlview_tree_editor_paste_node_as_sibling (MlViewTreeEditor *a_tree_editor, 
02248                                           GtkCTreeNode * a_visual_sibling_node, 
02249                                           gboolean a_previous){
02250 
02251         xmlNode *sibling_node = NULL ;
02252 
02253         g_return_if_fail (a_tree_editor != NULL) ;
02254         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
02255         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
02256         g_return_if_fail (PRIVATE (a_tree_editor)->mlview_xml_doc != NULL) ;
02257         g_return_if_fail (PRIVATE (a_tree_editor)->viewable_doc != NULL) ;
02258         g_return_if_fail (a_visual_sibling_node != NULL) ;
02259 
02260         sibling_node = gtk_ctree_node_get_row_data (PRIVATE (a_tree_editor)->viewable_doc, a_visual_sibling_node) ;
02261         g_return_if_fail (sibling_node != NULL) ;
02262         g_return_if_fail (sibling_node->parent != NULL) ;
02263 
02264         mlview_xml_document_paste_node_as_sibling (PRIVATE (a_tree_editor)->mlview_xml_doc, 
02265                                                    sibling_node->parent, sibling_node, a_previous) ;
02266 
02267         /*emit the appropriate signals*/
02268         gtk_signal_emit (GTK_OBJECT (a_tree_editor),
02269                         mlview_tree_editor_signals[TREE_CHANGED]) ;
02270 }
02271 
02272 
02276 GtkCTree *
02277 mlview_tree_editor_get_visual_tree (MlViewTreeEditor * a_tree_editor)
02278 {
02279         g_return_val_if_fail (a_tree_editor != NULL, NULL) ;
02280         g_return_val_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor), NULL) ;
02281         g_return_val_if_fail (PRIVATE (a_tree_editor) != NULL, NULL) ;
02282 
02283         return PRIVATE (a_tree_editor)->viewable_doc ;
02284 }
02285 
02293 void
02294 mlview_tree_editor_add_child_node_interactive (MlViewTreeEditor *a_tree_editor)
02295 {
02296         MlViewNodeTypePicker * nt_picker ;
02297         gint button ;
02298         xmlNode * current_node = NULL  ;
02299 
02300         g_return_if_fail (a_tree_editor != NULL) ;
02301         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
02302         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
02303 
02304         current_node = 
02305                 gtk_ctree_node_get_row_data (PRIVATE (a_tree_editor)->viewable_doc, 
02306                                              PRIVATE (a_tree_editor)->current_selected_node) ;
02307 
02308         /*
02309          *only an element node should have children.
02310          */
02311         if (current_node->type != XML_ELEMENT_NODE) 
02312                 return ;
02313 
02314         nt_picker = mlview_tree_editor_get_node_type_picker (a_tree_editor) ;
02315 
02316         if (nt_picker == NULL) {
02317                 nt_picker = MLVIEW_NODE_TYPE_PICKER (mlview_node_type_picker_new (PRIVATE (a_tree_editor)->app_context)) ;
02318                 gnome_dialog_close_hides (GNOME_DIALOG (nt_picker), TRUE) ;
02319                 gtk_window_set_modal (GTK_WINDOW (nt_picker),TRUE) ;
02320                 mlview_tree_editor_set_node_type_picker (a_tree_editor,
02321                                                          nt_picker) ;
02322         }
02323 
02324         mlview_node_type_picker_set_title(nt_picker, _("add a child node")) ;   
02325         mvliew_node_type_picker_build_element_name_choice_list (nt_picker, ADD_CHILD, current_node) ;
02326 
02327         mlview_node_type_picker_select_node_name_or_content_entry_text (nt_picker) ;
02328         gtk_widget_realize (GTK_WIDGET (nt_picker)) ;
02329         mlview_app_context_set_window_icon (PRIVATE (a_tree_editor)->app_context, GTK_WIDGET (nt_picker)) ;
02330         button = gnome_dialog_run (GNOME_DIALOG (nt_picker)) ;
02331 
02332         switch(button){
02333         case 0:/*OK button*/
02334                 mlview_tree_editor_handle_nt_picker_ok_button_clicked_to_add_child(a_tree_editor) ;
02335                 gnome_dialog_close(GNOME_DIALOG(PRIVATE(a_tree_editor)->node_type_picker)) ;
02336                 break ;
02337         case 1:/*cancel button*/
02338                 gnome_dialog_close(GNOME_DIALOG(PRIVATE(a_tree_editor)->node_type_picker)) ;
02339                 break ;
02340         default :
02341                 gnome_dialog_close(GNOME_DIALOG(PRIVATE(a_tree_editor)->node_type_picker)) ;
02342                 break ;
02343         }
02344 }
02345 
02346 
02354 void 
02355 mlview_tree_editor_insert_prev_sibling_node_interactive (MlViewTreeEditor *a_tree_editor)
02356 {
02357         MlViewNodeTypePicker * nt_picker ;
02358 
02359         gint button ;
02360         xmlNode * current_node = NULL  ;
02361 
02362         g_return_if_fail (a_tree_editor != NULL) ;
02363         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
02364         g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
02365 
02366         nt_picker = mlview_tree_editor_get_node_type_picker (a_tree_editor) ;
02367 
02368         if ( nt_picker == NULL ) {
02369                 nt_picker = MLVIEW_NODE_TYPE_PICKER (mlview_node_type_picker_new(PRIVATE (a_tree_editor)->app_context)) ;
02370                 gnome_dialog_close_hides (GNOME_DIALOG (nt_picker), TRUE) ;
02371                 gtk_window_set_modal (GTK_WINDOW (nt_picker),TRUE) ;
02372                 mlview_tree_editor_set_node_type_picker (a_tree_editor, nt_picker) ;
02373         }
02374         mlview_node_type_picker_set_title (nt_picker, _("insert a previous sibling node")) ;
02375         mlview_node_type_picker_select_node_name_or_content_entry_text (nt_picker) ;
02376 
02377         /*insert a flag to indicate that the picker is used to insert node as previous node
02378          *this is used in function
02379          */
02380         gtk_object_set_data (GTK_OBJECT (a_tree_editor), "prev", GINT_TO_POINTER (TRUE)) ;
02381         current_node = 
02382                 gtk_ctree_node_get_row_data (PRIVATE (a_tree_editor)->viewable_doc, 
02383                                              PRIVATE (a_tree_editor)->current_selected_node) ;
02384 
02385         mvliew_node_type_picker_build_element_name_choice_list (nt_picker, 
02386                                                                 INSERT_BEFORE, 
02387                                                                 current_node) ;
02388 
02389         
02390         gtk_widget_realize (GTK_WIDGET (nt_picker)) ;
02391         mlview_app_context_set_window_icon (PRIVATE (a_tree_editor)->app_context, GTK_WIDGET (nt_picker)) ;
02392         button = gnome_dialog_run (GNOME_DIALOG (nt_picker)) ;
02393 
02394         switch (button) {
02395         case 0:/*OK button*/
02396                 mlview_tree_editor_handle_nt_picker_ok_button_clicked_to_insert_sibling_node (a_tree_editor) ;
02397                 gnome_dialog_close (GNOME_DIALOG (PRIVATE (a_tree_editor)->node_type_picker)) ;
02398                 break ;
02399         case 1:/*cancel button*/
02400                 gnome_dialog_close (GNOME_DIALOG (PRIVATE (a_tree_editor)->node_type_picker)) ;
02401                 break ;
02402         default :
02403                 gnome_dialog_close (GNOME_DIALOG (PRIVATE (a_tree_editor)->node_type_picker)) ;
02404                 break ;
02405         }
02406 }
02407 
02408 
02416 void 
02417 mlview_tree_editor_insert_next_sibling_node_interactive (MlViewTreeEditor *a_tree_editor)
02418 {
02419         MlViewNodeTypePicker * nt_picker ;
02420         gint button ;
02421         xmlNode * current_node = NULL  ;
02422 
02423         g_return_if_fail( a_tree_editor != NULL) ;
02424         
02425         nt_picker = mlview_tree_editor_get_node_type_picker(a_tree_editor) ;
02426 
02427         if(nt_picker == NULL){
02428                 nt_picker = MLVIEW_NODE_TYPE_PICKER(mlview_node_type_picker_new(PRIVATE (a_tree_editor)->app_context)) ;
02429                 gnome_dialog_close_hides(GNOME_DIALOG(nt_picker), TRUE) ;
02430                 gtk_window_set_modal(GTK_WINDOW(nt_picker),TRUE) ;
02431                 mlview_tree_editor_set_node_type_picker(a_tree_editor,nt_picker) ;              
02432         }
02433 
02434         mlview_node_type_picker_set_title(nt_picker, _("insert a next sibling node")) ;
02435         mlview_node_type_picker_select_node_name_or_content_entry_text(nt_picker) ;
02436         current_node = 
02437                 gtk_ctree_node_get_row_data (PRIVATE (a_tree_editor)->viewable_doc, 
02438                                              PRIVATE (a_tree_editor)->current_selected_node) ;
02439         mvliew_node_type_picker_build_element_name_choice_list (nt_picker, INSERT_AFTER, current_node) ;
02440 
02441         gtk_object_set_data (GTK_OBJECT (a_tree_editor), "prev", GINT_TO_POINTER (FALSE)) ;
02442         gtk_widget_realize (GTK_WIDGET (nt_picker)) ;
02443         mlview_app_context_set_window_icon (PRIVATE (a_tree_editor)->app_context, GTK_WIDGET (nt_picker)) ;
02444         button = gnome_dialog_run (GNOME_DIALOG(nt_picker)) ;
02445 
02446         switch(button){
02447         case 0:/*OK button*/
02448                 mlview_tree_editor_handle_nt_picker_ok_button_clicked_to_insert_sibling_node(a_tree_editor) ;
02449                 gnome_dialog_close(GNOME_DIALOG(PRIVATE(a_tree_editor)->node_type_picker)) ;
02450                 break ;
02451         case 1:/*cancel button*/
02452                 gnome_dialog_close(GNOME_DIALOG(PRIVATE(a_tree_editor)->node_type_picker)) ;
02453                 break ;
02454         default :
02455                 break ;
02456         }                       
02457 }
02458 
02459 
02466 xmlDocPtr
02467 mlview_tree_editor_get_xml_document (MlViewTreeEditor *a_tree_editor)
02468 {
02469         g_return_val_if_fail(a_tree_editor != NULL, NULL) ;
02470         g_return_val_if_fail(PRIVATE(a_tree_editor) != NULL,NULL) ;
02471         
02472         return PRIVATE(a_tree_editor)->xml_doc ;
02473 }
02474 
02482 void 
02483 mlview_tree_editor_set_node_type_picker (MlViewTreeEditor* a_tree_editor, 
02484                                          MlViewNodeTypePicker * a_node_type_picker)
02485 {
02486         g_return_if_fail(a_tree_editor != NULL) ;       
02487         g_return_if_fail(PRIVATE(a_tree_editor) != NULL) ;
02488 
02489         PRIVATE(a_tree_editor)->node_type_picker = a_node_type_picker ;
02490 }
02491 
02499 MlViewNodeTypePicker *
02500 mlview_tree_editor_get_node_type_picker (MlViewTreeEditor *a_tree_editor)
02501 {
02502         g_return_val_if_fail(a_tree_editor != NULL, NULL) ;
02503         g_return_val_if_fail(PRIVATE(a_tree_editor) != NULL, NULL) ;
02504         return PRIVATE(a_tree_editor)->node_type_picker ;
02505 }
02506 
02514 GtkCTreeNode *
02515 mlview_tree_editor_find_xml_node_that_contains_str (MlViewTreeEditor * a_tree_editor, const gchar * a_str, 
02516                                                     const enum WhereInTheNodeBitmap a_where_in_node_bitmap,
02517                                                     const gboolean a_start_after)
02518 {
02519         GtkCTreeNode * start_node ;
02520         xmlDoc * xml_doc ;
02521 
02522         g_return_val_if_fail(a_tree_editor != NULL, NULL) ;
02523         g_return_val_if_fail(PRIVATE(a_tree_editor) != NULL, NULL) ;
02524         g_return_val_if_fail(PRIVATE(a_tree_editor)->viewable_doc != NULL, NULL) ;
02525 
02526         if(a_str == NULL)
02527                 return NULL ;
02528         xml_doc = mlview_tree_editor_get_xml_document(a_tree_editor) ;
02529         g_return_val_if_fail(xml_doc != NULL, NULL) ;
02530         start_node = mlview_tree_editor_get_current_selected_node(a_tree_editor) ;
02531 
02532         if(start_node == NULL){/*set start node to the doc root element.*/
02533                 start_node = gtk_ctree_node_nth(PRIVATE(a_tree_editor)->viewable_doc, 0) ;
02534                 g_return_val_if_fail(start_node != NULL, NULL) ;
02535         }
02536         return downward_find_visual_node_that_contains(PRIVATE(a_tree_editor)->viewable_doc, start_node, a_str,
02537                                                        a_where_in_node_bitmap, a_start_after) ;
02538 }
02539 
02540 
02545 GtkCTreeNode * 
02546 mlview_tree_editor_find_xml_node_that_contains_str_interactive (MlViewTreeEditor *a_tree_editor)
02547 {
02548         GnomeDialog * find_dialog ;
02549         GtkCTreeNode * previously_found_node=NULL ;
02550         gint button ;
02551         gboolean go=FALSE, start_after=FALSE ;
02552 
02553         g_return_val_if_fail (a_tree_editor != NULL, NULL) ;
02554         g_return_val_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor), NULL) ;
02555         g_return_val_if_fail (PRIVATE (a_tree_editor) != NULL, NULL) ;
02556 
02557         find_dialog = 
02558                 mlview_tree_editor_find_dialog_box_retrieve (PRIVATE (a_tree_editor)->app_context) ;
02559         g_return_val_if_fail (find_dialog != NULL, NULL) ;
02560         gtk_window_set_modal (GTK_WINDOW (find_dialog), FALSE) ;
02561 
02562         go = TRUE ;
02563         previously_found_node = NULL ;
02564 
02565         while (go) {
02566 
02567                 gnome_dialog_close_hides (find_dialog, TRUE) ;          
02568                 gtk_widget_realize (GTK_WIDGET (find_dialog)) ;
02569                 mlview_app_context_set_window_icon (PRIVATE (a_tree_editor)->app_context, GTK_WIDGET (find_dialog)) ;
02570                 button = gnome_dialog_run (find_dialog) ;
02571 
02572                 switch (button) {
02573                 case 0:
02574                         start_after = (previously_found_node != NULL)?TRUE:FALSE;
02575                         previously_found_node = mlview_tree_editor_get_data_from_find_dialog_and_perform_search (a_tree_editor,
02576                                                                                                                  find_dialog,previously_found_node, start_after) ;
02577                         break ;
02578                 case 1:
02579                         gnome_dialog_close (find_dialog) ;
02580                         go = FALSE ;
02581                         break ;
02582                 default :
02583                         gnome_dialog_close (find_dialog) ;
02584                         go = FALSE ;
02585                         break ;        
02586                 }
02587         }
02588         return NULL ;
02589 }
02590 
02591 
02601 void
02602 mlview_tree_editor_expand_tree_to_depth (MlViewTreeEditor * a_editor,
02603                                          gint a_depth)
02604 {
02605         g_return_if_fail (a_editor != NULL) ;
02606         g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_editor)) ;
02607         g_return_if_fail (PRIVATE (a_editor) != NULL) ;
02608                 
02609         if (PRIVATE (a_editor)->current_selected_node == NULL)
02610                 return ;
02611 
02612         if (a_depth >= 0) {
02613                 gtk_ctree_collapse_recursive (PRIVATE (a_editor)->viewable_doc,
02614                                               PRIVATE (a_editor)->current_selected_node) ;
02615 
02616                 if (a_depth != 0) {
02617                         gtk_ctree_expand_to_depth (PRIVATE (a_editor)->viewable_doc,
02618                                                    PRIVATE (a_editor)->current_selected_node,
02619                                                    GTK_CTREE_ROW (PRIVATE (a_editor)->current_selected_node)->level + a_depth -1) ;
02620                 }
02621 
02622         } else {/*expand to leaves*/
02623                 gtk_ctree_expand_recursive (PRIVATE (a_editor)->viewable_doc,
02624                                             PRIVATE (a_editor)->current_selected_node) ;                
02625         }
02626         gtk_widget_show_all (GTK_WIDGET (a_editor)) ;
02627 }
02628 
02636 void
02637 mlview_tree_editor_update_contextual_menu (MlViewTreeEditor * a_tree_editor,
02638                                            GtkMenu ** a_menu_ptr)
02639 {
02640             GtkWidget * menu_item = NULL ;
02641 
02642             g_return_if_fail (a_tree_editor != NULL) ;
02643             g_return_if_fail (MLVIEW_IS_TREE_EDITOR (a_tree_editor)) ;
02644             g_return_if_fail (PRIVATE (a_tree_editor) != NULL) ;
02645             g_return_if_fail (a_menu_ptr != NULL) ;
02646             g_return_if_fail (*a_menu_ptr != NULL) ;
02647             g_return_if_fail (GTK_IS_MENU (*a_menu_ptr)) ;
02648 
02649             if (PRIVATE (a_tree_editor)->current_selected_node != NULL) {
02650                     GtkMenu * submenu = NULL ;
02651 
02652                     /*separator*/
02653                     menu_item = gtk_menu_item_new () ;
02654                     gtk_menu_append (*a_menu_ptr,
02655                                      menu_item) ;
02656                     gtk_widget_show (menu_item) ;
02657 
02658                     menu_item = gtk_menu_item_new_with_label (_("Add child node")) ;                
02659                     gtk_menu_append (GTK_MENU (*a_menu_ptr),
02660                                      menu_item) ;
02661                     gtk_widget_show (menu_item) ;
02662                     if (!mlview_tree_editor_build_node_insertion_submenu (a_tree_editor, ADD_CHILD, &submenu)
02663                         && submenu) {
02664                             gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), GTK_WIDGET (submenu)) ;
02665                     }
02666                                     
02667                     menu_item = gtk_menu_item_new_with_label (_("Insert next sibling node")) ;
02668                     gtk_menu_append (GTK_MENU (*a_menu_ptr),menu_item) ;
02669                     gtk_widget_show (menu_item) ;
02670                     if (!mlview_tree_editor_build_node_insertion_submenu (a_tree_editor, INSERT_AFTER, &submenu)
02671                         && submenu) {
02672                             gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), GTK_WIDGET (submenu)) ;
02673                     }
02674             
02675                     menu_item = gtk_menu_item_new_with_label (_("Insert previous sibling node")) ;
02676                     gtk_menu_append (GTK_MENU (*a_menu_ptr), menu_item) ;
02677                     gtk_widget_show (menu_item) ;
02678                     if (!mlview_tree_editor_build_node_insertion_submenu (a_tree_editor, INSERT_BEFORE, &submenu)
02679                         && submenu) {
02680                             gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), GTK_WIDGET (submenu)) ;
02681                     }
02682             }
02683 }

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