[Patch] Multiple trees support in MlViewTreeView

Nicolas Centa <[email protected]> Mon, 20 Oct 2003 23:28:08 +0200
Newsgroups gmane.editors.mlview.devel
Message-ID <[email protected]>
Hello !

This patch adds support for multiple trees in MlViewTreeView. 

«API» changes in MlViewTreeView :
- The trees (currently MlViewTreeEditor2 only) are in a GtkNotebook
(MlViewTreeViewPrivate::trees)
- The current tree is pointed by MlViewTreeViewPrivate::tree_editor
- Look at mlview_tree_view_construct() : you can add a tree simply by adding it
to the notebook (connections etc. are made automatically for all trees which are
in it)

A bug was also corrected in MlViewNodeEditor (comment node editor) (see
mlview_node_editor_clear_xml_text_node_view(), mlview-node-editor.c line 968).

I will soon add a tree with icons, etc. like I wanted to do :-) 

Don't forget to give me your opinions, especially if you are an user :-)

Nicolas Centa
"HappyPeng"
multitree.diff (application/octet-stream, 15.6 KB)
diff -ur orig/mlview/src/mlview-node-editor.c mlview/src/mlview-node-editor.c
--- orig/mlview/src/mlview-node-editor.c	2003-10-19 02:45:57.000000000 +0200
+++ mlview/src/mlview-node-editor.c	2003-10-20 23:19:55.000000000 +0200
@@ -1250,6 +1250,7 @@
 
         status = mlview_xml_document_node_get_content (a_node, UTF8,
                                                        &utf8_content);
+
         g_return_if_fail (status == MLVIEW_OK);
         
         text_buffer = gtk_text_view_get_buffer (editor_view->widget) ;
@@ -1260,7 +1261,7 @@
         gtk_text_buffer_get_iter_at_offset (text_buffer, 
                                             &iter1, 0) ;
         gtk_text_buffer_get_iter_at_offset (text_buffer, 
-                                            &iter2, 0) ;
+                                            &iter2, -1) ;
         gtk_text_buffer_delete (text_buffer, &iter1, &iter2) ;
 
         if (utf8_content) {
diff -ur orig/mlview/src/mlview-tree-view.c mlview/src/mlview-tree-view.c
--- orig/mlview/src/mlview-tree-view.c	2003-10-19 02:45:57.000000000 +0200
+++ mlview/src/mlview-tree-view.c	2003-10-20 23:20:01.000000000 +0200
@@ -32,7 +32,11 @@
 struct _MlViewTreeViewPrivate {
         guchar *name ;
         GtkWidget *set_name_dialog ;
-        MlViewTreeEditor2 *tree_editor;
+
+        GtkNotebook *trees; /* all trees */
+        xmlNode *current_node; /* current node */
+        MlViewTreeEditor2 *tree_editor; /* current tree */
+
         MlViewNodeEditor *node_editor;
         MlViewAppContext *app_context;
         MlViewXMLDocument *xml_doc ;
@@ -60,6 +64,12 @@
                          GtkTreeRowReference *a_ref,
                          gpointer a_user_data);
 
+static void
+tree_selected_cb (GtkNotebook *notebook,
+                  GtkNotebookPage *page, 
+                  guint page_num,
+                  gpointer data);
+
 static void xml_node_changed_cb (MlViewNodeEditor * a_editor,
                                  gpointer a_data);
 
@@ -273,6 +283,32 @@
  *========================================*/
 
 /**
+  *This callback is called when the user
+  *selects a tree in the trees' notebook.
+  *
+  */
+
+static void
+tree_selected_cb (GtkNotebook *notebook,
+                  GtkNotebookPage *page, 
+                  guint page_num,
+                  gpointer data)
+{
+        MlViewTreeEditor2 *tree;
+        MlViewTreeView *this = data;
+
+        g_return_if_fail (this && MLVIEW_IS_TREE_VIEW (this));
+
+        tree = MLVIEW_TREE_EDITOR2 (gtk_notebook_get_nth_page (notebook, page_num));
+        
+        g_return_if_fail (tree && MLVIEW_IS_TREE_EDITOR2 (tree));
+        
+        PRIVATE (this)->tree_editor = tree;
+        if (PRIVATE (this)->current_node)
+                mlview_tree_editor2_select_node (tree, PRIVATE (this)->current_node);
+}
+
+/**
  *This callback is called when an xml 
  *node is selected by the user. It calls the
  *mlview_node_editor_edit_xml_node() method of the MlViewNodeEditor object. 
@@ -305,6 +341,9 @@
         xml_node =
                 mlview_tree_editor2_get_xml_node2 (a_editor, a_ref) ;
         g_return_if_fail (xml_node) ;
+
+        PRIVATE (view)->current_node = xml_node;
+
         mlview_iview_get_document
                 (MLVIEW_IVIEW (view), &mlview_xml_doc);
         g_return_if_fail (mlview_xml_doc);
@@ -326,6 +365,8 @@
         GtkTreeView *visual_tree=NULL;
         xmlNodePtr xml_node=NULL;
         MlViewTreeView *view=NULL;
+        gint i, nb_pages;
+        MlViewTreeEditor2 *tree;
 
         g_return_if_fail (a_node_editor
                           && MLVIEW_IS_NODE_EDITOR (a_node_editor)
@@ -338,18 +379,17 @@
 
         /*get the visual tree */
         view = MLVIEW_TREE_VIEW (a_data);
+        
         g_return_if_fail (view && PRIVATE (view)
-                          && PRIVATE (view)->tree_editor
-                          && MLVIEW_IS_TREE_EDITOR2
-                          (PRIVATE (view)->tree_editor)) ;
-        visual_tree =
-                mlview_tree_editor2_get_tree_view
-                (PRIVATE (view)->tree_editor);
-
-        g_return_if_fail (visual_tree
-                          && GTK_IS_TREE_VIEW (visual_tree));
-        mlview_tree_editor2_update_visual_node2
-                (PRIVATE (view)->tree_editor, xml_node);
+                          && PRIVATE (view)->trees);
+        nb_pages = gtk_notebook_get_n_pages (PRIVATE (view)->trees);
+        for (i = 0; i < nb_pages; i++) {
+                tree = MLVIEW_TREE_EDITOR2 (gtk_notebook_get_nth_page 
+                                            (PRIVATE (view)->trees, i));
+                g_return_if_fail (tree && MLVIEW_IS_TREE_EDITOR2 (tree));
+                visual_tree = mlview_tree_editor2_get_tree_view (tree);
+                g_return_if_fail (visual_tree && GTK_IS_TREE_VIEW (visual_tree));
+                mlview_tree_editor2_update_visual_node2 (tree, xml_node); }
 }
 
 /**
@@ -994,6 +1034,8 @@
                                  MlViewXMLDocument *a_doc) 
 {
         MlViewTreeView *tree_view = NULL ;
+        MlViewTreeEditor2 *tree;
+        gint i, nb_pages;
 
         g_return_val_if_fail (a_this 
                               && MLVIEW_IS_IVIEW (a_this)
@@ -1004,11 +1046,17 @@
 
         tree_view = MLVIEW_TREE_VIEW (a_this) ;
         g_return_val_if_fail (tree_view 
-                              && PRIVATE (tree_view)->tree_editor,
+                              && PRIVATE (tree_view)->trees,
                               MLVIEW_BAD_PARAM_ERROR) ;
-        mlview_tree_editor2_connect_to_doc (PRIVATE
-                                            (tree_view)->tree_editor,
-                                            a_doc) ;
+
+        nb_pages = gtk_notebook_get_n_pages (PRIVATE (tree_view)->trees);
+        for (i = 0; i < nb_pages; i++) {
+                tree = MLVIEW_TREE_EDITOR2 
+                        (gtk_notebook_get_nth_page (PRIVATE (tree_view)->trees, i));
+                g_return_val_if_fail (tree && MLVIEW_IS_TREE_EDITOR2 (tree),
+                                      MLVIEW_BAD_PARAM_ERROR);
+                mlview_tree_editor2_connect_to_doc (tree, a_doc); }
+      
         mlview_node_editor_connect_to_doc (PRIVATE
                                            (tree_view)->node_editor,
                                            a_doc) ;
@@ -1019,19 +1067,33 @@
 mlview_tree_view_disconnect_from_doc (MlViewIView *a_this,
                                       MlViewXMLDocument *a_doc)
 {
-        MlViewTreeView *thiz = NULL ;
-        
+        MlViewTreeView *tree_view = NULL ;
+        MlViewTreeEditor2 *tree;
+        gint i, nb_pages;
+
         g_return_val_if_fail (a_this 
                               && MLVIEW_IS_IVIEW (a_this)
                               && MLVIEW_IS_TREE_VIEW (a_this)
+                              && a_doc
                               && MLVIEW_IS_XML_DOCUMENT (a_doc),
                               MLVIEW_BAD_PARAM_ERROR) ;
-        thiz = MLVIEW_TREE_VIEW (a_this) ;
-        mlview_node_editor_disconnect_from_doc
-                (PRIVATE (thiz)->node_editor, a_doc) ;
-        mlview_tree_editor2_disconnect_from_doc
-                (PRIVATE (thiz)->tree_editor, a_doc) ;
 
+        tree_view = MLVIEW_TREE_VIEW (a_this) ;
+        g_return_val_if_fail (tree_view 
+                              && PRIVATE (tree_view)->trees,
+                              MLVIEW_BAD_PARAM_ERROR) ;
+
+        nb_pages = gtk_notebook_get_n_pages (PRIVATE (tree_view)->trees);
+        for (i = 0; i < nb_pages; i++) {
+                tree = MLVIEW_TREE_EDITOR2 
+                        (gtk_notebook_get_nth_page (PRIVATE (tree_view)->trees, i));
+                g_return_val_if_fail (tree && MLVIEW_IS_TREE_EDITOR2 (tree),
+                                      MLVIEW_BAD_PARAM_ERROR);
+                mlview_tree_editor2_disconnect_from_doc (tree, a_doc); }
+      
+        mlview_node_editor_disconnect_from_doc (PRIVATE
+                                                (tree_view)->node_editor,
+                                                a_doc) ;
         return MLVIEW_OK ;
 }
 
@@ -1077,6 +1139,16 @@
         return PRIVATE (a_this)->tree_editor;
 }
 
+GtkNotebook *
+mlview_tree_view_get_trees (MlViewTreeView *a_this)
+{
+        g_return_val_if_fail (a_this != NULL, NULL);
+        g_return_val_if_fail (PRIVATE (a_this) != NULL,
+                              NULL);
+        
+        return PRIVATE (a_this)->trees;
+}
+
 /**
  *
  */
@@ -1114,6 +1186,7 @@
                                     a_app_context) ;
         mlview_iview_connect_to_doc (MLVIEW_IVIEW (tree_view),
                                      a_mlview_xml_doc) ;
+
         return GTK_WIDGET (tree_view);
 }
 
@@ -1150,6 +1223,12 @@
         GtkWidget *table = NULL,
                 *scrolled = NULL;
 
+        MlViewTreeEditor2 *raw_xml_tree;
+        /* MlViewTreeEditor2 *test_tree; */
+
+        gint i, nb_pages;
+        MlViewTreeEditor2 *tree;
+    
         enum MLVIEW_VIEW_ADAPTER_STATUS status = NOK;
         const gchar *feasible_children_titles[1] =
                 { _("Possible Children") };
@@ -1185,28 +1264,37 @@
         gtk_widget_show (GTK_WIDGET
                          (PRIVATE (a_this)->main_paned));
 
-        /*The tree editor */
-        PRIVATE (a_this)->tree_editor =
-                MLVIEW_TREE_EDITOR2 (mlview_tree_editor2_new
-                                     (a_app_context));
-        g_signal_connect (G_OBJECT
-                          (PRIVATE (a_this)->tree_editor),
-                          "node-selected",
-                          G_CALLBACK (visual_node_selected_cb),
-                          a_this);
+        /*The trees and the trees' notebook */
 
+        /* Notebook */ 
         PRIVATE (a_this)->upper_paned1 =
                 GTK_PANED (gtk_hpaned_new ());
-
         gtk_paned_add1 (GTK_PANED
                         (PRIVATE (a_this)->main_paned),
                         GTK_WIDGET (PRIVATE (a_this)->
                                     upper_paned1));
-
-        gtk_paned_add1 (GTK_PANED
-                        (PRIVATE (a_this)->upper_paned1),
-                        GTK_WIDGET (PRIVATE (a_this)->
-                                    tree_editor));
+        PRIVATE (a_this)->trees = GTK_NOTEBOOK (gtk_notebook_new ());
+        gtk_notebook_set_tab_pos (PRIVATE (a_this)->trees, GTK_POS_BOTTOM);
+        gtk_paned_add1 (GTK_PANED (PRIVATE (a_this)->upper_paned1),
+                        GTK_WIDGET (PRIVATE (a_this)->trees));
+        g_signal_connect (G_OBJECT
+                          (PRIVATE (a_this)->trees),
+                          "switch-page",
+                          G_CALLBACK (tree_selected_cb),
+                          a_this);
+        
+        /* Trees */
+        raw_xml_tree = MLVIEW_TREE_EDITOR2 (mlview_tree_editor2_new (a_app_context));
+        /* test_tree = MLVIEW_TREE_EDITOR2 (mlview_tree_editor2_new (a_app_context)); */
+
+        PRIVATE (a_this)->tree_editor = raw_xml_tree;
+
+        gtk_notebook_append_page (PRIVATE (a_this)->trees, 
+                                  GTK_WIDGET (raw_xml_tree),
+                                  gtk_label_new (_("Elements")));
+        /* gtk_notebook_append_page (PRIVATE (a_this)->trees,
+           GTK_WIDGET (test_tree),
+           gtk_label_new ("Test")); */
 
         /*the table with the feasible children, siblings and attributes */
         PRIVATE (a_this)->feasible_children =
@@ -1220,13 +1308,6 @@
                           (selected_a_possible_child_cb),
                           a_this);
 
-        g_signal_connect (G_OBJECT
-                          (PRIVATE (a_this)->tree_editor),
-                          "node-selected",
-                          G_CALLBACK
-                          (update_feasible_children_list_cb),
-                          a_this);
-
         PRIVATE (a_this)->feasible_prev_siblings =
                 GTK_CLIST (gtk_clist_new_with_titles
                            (1, (gchar**)feasible_prev_siblings_titles));
@@ -1238,13 +1319,6 @@
                           (selected_a_possible_prev_sibling_cb),
                           a_this);
 
-        g_signal_connect (G_OBJECT
-                          (PRIVATE (a_this)->tree_editor),
-                          "node-selected",
-                          G_CALLBACK
-                          (update_feasible_prev_siblings_list_cb),
-                          a_this);
-
         PRIVATE (a_this)->feasible_next_siblings =
                 GTK_CLIST (gtk_clist_new_with_titles
                            (1, (gchar**) feasible_next_siblings_titles));
@@ -1256,13 +1330,6 @@
                           (selected_a_possible_next_sibling_cb),
                           a_this);
 
-        g_signal_connect (G_OBJECT
-                          (PRIVATE (a_this)->tree_editor),
-                          "node-selected",
-                          G_CALLBACK
-                          (update_feasible_next_siblings_list_cb),
-                          a_this);
-
         PRIVATE (a_this)->feasible_attributes =
                 GTK_CLIST
                 (gtk_clist_new_with_titles
@@ -1275,13 +1342,6 @@
                           (selected_a_possible_attribute_cb),
                           a_this);
 
-        g_signal_connect (GTK_OBJECT
-                          (PRIVATE (a_this)->tree_editor),
-                          "node-selected",
-                          G_CALLBACK
-                          (update_feasible_attributes_list_cb),
-                          a_this);
-
         table = gtk_table_new (2, 2, TRUE);
 
         scrolled = gtk_scrolled_window_new (NULL, NULL);
@@ -1354,9 +1414,46 @@
                               main_paned));
 
         PRIVATE (a_this)->app_context = a_app_context;
-        mlview_tree_editor2_edit_xml_doc 
-                (PRIVATE (a_this)->tree_editor,
-                 a_mlview_xml_doc, NULL);
+
+        /* Build trees */
+        nb_pages = gtk_notebook_get_n_pages (PRIVATE (a_this)->trees);
+        for (i = 0; i < nb_pages; i++) {
+                tree = MLVIEW_TREE_EDITOR2 
+                        (gtk_notebook_get_nth_page (PRIVATE (a_this)->trees, i));
+                mlview_tree_editor2_edit_xml_doc
+                        (tree, a_mlview_xml_doc, NULL); 
+                g_signal_connect (G_OBJECT
+                                  (tree),
+                                  "node-selected",
+                                  G_CALLBACK (visual_node_selected_cb),
+                                  a_this);
+                g_signal_connect (G_OBJECT
+                                  (tree),
+                                  "node-selected",
+                                  G_CALLBACK
+                                  (update_feasible_children_list_cb),
+                                  a_this);
+                g_signal_connect (G_OBJECT
+                                  (tree),
+                                  "node-selected",
+                                  G_CALLBACK
+                                  (update_feasible_prev_siblings_list_cb),
+                                  a_this);
+                g_signal_connect (G_OBJECT
+                                  (tree),
+                                  "node-selected",
+                                  G_CALLBACK
+                                  (update_feasible_next_siblings_list_cb),
+                                  a_this);
+                g_signal_connect (GTK_OBJECT
+                                  (tree),
+                                  "node-selected",
+                                  G_CALLBACK
+                                  (update_feasible_attributes_list_cb),
+                                  a_this);
+                
+        }
+
         g_signal_connect (G_OBJECT (a_mlview_xml_doc),
                           "file-path-changed",
                           G_CALLBACK