add new ctree sorting code
authorMartin Schaaf <mascha@ma-scha.de>
Tue, 9 Jul 2002 09:57:45 +0000 (09:57 +0000)
committerMartin Schaaf <mascha@ma-scha.de>
Tue, 9 Jul 2002 09:57:45 +0000 (09:57 +0000)
ChangeLog.claws
configure.in
src/addressbook.c
src/foldersel.c
src/folderview.c
src/gtksctree.c
src/gtksctree.h
src/summaryview.c

index cfd0bb35bf611c10ee981d422533e9575cc0186e..0150bf4923d9c1346334d9861a4cc8926327e024 100644 (file)
@@ -1,3 +1,21 @@
+2002-07-09 [martin]    0.7.8claws56
+       * src/gtksctree.c
+               Added gtk_ctree_last_visible(), tree_update_level(),
+               gtk_ctree_link(), gtk_ctree_unlink(), real_sort_list(),
+               tree_sort(), gtk_ctree_sort_recursive() and gtk_ctree_sort_node()
+               from gtk+ to gtksctree.c for the new sorting code
+               Renamed gtk_ctree_sort_recusive() to gtk_sctree_sort_recursive
+               Renamed gtk_ctree_sort_node() to gtk_sctree_sort_node
+       * src/gtksctree.h
+               Added declaration for gtk_sctree_sort_recursive() and
+               gtk_sctree_sort_node
+       * src/addressbook.c
+       * src/foldersel.c
+       * src/folderview.c
+       * src/summaryview.c
+               changed calls from gtk_ctree_sort_recursive() and gtk_ctree_sort_node()
+               to gtk_sctree_sort_recursive() and gtk_sctree_sort_node()
+
 2002-07-08     [paul]  0.7.8claws55
 
        * more sync with 0.7.8cvs21
 2002-07-08     [paul]  0.7.8claws55
 
        * more sync with 0.7.8cvs21
index 679d9a9d4a0a6497eafc4c3d16ee0458dafac907..f05666c8571487bbf4cb0cdaa868edfcc8eab7e2 100644 (file)
@@ -8,7 +8,7 @@ MINOR_VERSION=7
 MICRO_VERSION=8
 INTERFACE_AGE=0
 BINARY_AGE=0
 MICRO_VERSION=8
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=claws55
+EXTRA_VERSION=claws56
 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
 
 dnl set $target
 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
 
 dnl set $target
index 9f33ec0724ac50d9399a466459f1b87d8b6fa70b..bb1073088be597c87e3ff804809dab755f64a4b6 100644 (file)
@@ -2022,7 +2022,7 @@ static void addressbook_treenode_edit_cb(gpointer data, guint action,
        if( name && parentNode ) {
                /* Update node in tree view */
                addressbook_change_node_name( node, name );
        if( name && parentNode ) {
                /* Update node in tree view */
                addressbook_change_node_name( node, name );
-               gtk_ctree_sort_node(ctree, parentNode);
+               gtk_sctree_sort_node(ctree, parentNode);
                gtk_ctree_expand( ctree, node );
                gtk_ctree_select( ctree, node );
        }
                gtk_ctree_expand( ctree, node );
                gtk_ctree_select( ctree, node );
        }
@@ -2242,7 +2242,7 @@ static void addressbook_move_nodes_up( GtkCTree *ctree, GtkCTreeNode *node ) {
                while( (child = currRow->children) ) {
                        gtk_ctree_move( ctree, child, parent, node );
                }
                while( (child = currRow->children) ) {
                        gtk_ctree_move( ctree, child, parent, node );
                }
-               gtk_ctree_sort_node( ctree, parent );
+               gtk_sctree_sort_node( ctree, parent );
        }
 }
 
        }
 }
 
@@ -2312,7 +2312,7 @@ static void addressbook_edit_address_cb( gpointer data, guint action, GtkWidget
        /* Update tree node with node name */
        if( node == NULL ) return;
        addressbook_change_node_name( node, name );
        /* Update tree node with node name */
        if( node == NULL ) return;
        addressbook_change_node_name( node, name );
-       gtk_ctree_sort_node( ctree, parentNode );
+       gtk_sctree_sort_node( ctree, parentNode );
        gtk_ctree_select( ctree, addrbook.opened );
 }
 
        gtk_ctree_select( ctree, addrbook.opened );
 }
 
@@ -2471,7 +2471,7 @@ static void addressbook_folder_load_person( GtkCTree *clist, ItemFolder *itemFol
                                        FALSE, person->isOpened );
                        gtk_ctree_node_set_row_data(clist, nodePerson, person );
                }
                                        FALSE, person->isOpened );
                        gtk_ctree_node_set_row_data(clist, nodePerson, person );
                }
-               gtk_ctree_sort_node(GTK_CTREE(clist), NULL);
+               gtk_sctree_sort_node(GTK_CTREE(clist), NULL);
        }
        /* Free up the list */
        mgu_clear_list( items );
        }
        /* Free up the list */
        mgu_clear_list( items );
@@ -2499,7 +2499,7 @@ static void addressbook_folder_load_group( GtkCTree *clist, ItemFolder *itemFold
                                      atci->iconXpmOpen, atci->maskXpmOpen,
                                      FALSE, FALSE);
                gtk_ctree_node_set_row_data(clist, nodeGroup, group );
                                      atci->iconXpmOpen, atci->maskXpmOpen,
                                      FALSE, FALSE);
                gtk_ctree_node_set_row_data(clist, nodeGroup, group );
-               gtk_ctree_sort_node(clist, NULL);
+               gtk_sctree_sort_node(clist, NULL);
        }
        /* Free up the list */
        mgu_clear_list( items );
        }
        /* Free up the list */
        mgu_clear_list( items );
@@ -2926,7 +2926,7 @@ static GtkCTreeNode *addressbook_add_object(GtkCTreeNode *node,
                }
        }
 
                }
        }
 
-       gtk_ctree_sort_node(ctree, node);
+       gtk_sctree_sort_node(ctree, node);
 
        return added;
 }
 
        return added;
 }
@@ -2962,7 +2962,7 @@ static GtkCTreeNode *addressbook_node_add_group( GtkCTreeNode *node, AddressData
                        atci->treeLeaf, atci->treeExpand );
        gtk_ctree_node_set_row_data_full( ctree, newNode, adapter,
                addressbook_free_treenode );
                        atci->treeLeaf, atci->treeExpand );
        gtk_ctree_node_set_row_data_full( ctree, newNode, adapter,
                addressbook_free_treenode );
-       gtk_ctree_sort_node( ctree, node );
+       gtk_sctree_sort_node( ctree, node );
        return newNode;
 }
 
        return newNode;
 }
 
@@ -3023,7 +3023,7 @@ static GtkCTreeNode *addressbook_node_add_folder(
                addressbook_node_add_group( newNode, ds, item );
                listItems = g_list_next( listItems );
        }
                addressbook_node_add_group( newNode, ds, item );
                listItems = g_list_next( listItems );
        }
-       gtk_ctree_sort_node( ctree, node );
+       gtk_sctree_sort_node( ctree, node );
        return newNode;
 }
 
        return newNode;
 }
 
index be3b84c204bcaf6c6f104337501bf9564d2461de..c9d197f95f6d51d1bc2500dde670eff14c2637b6 100644 (file)
@@ -319,7 +319,7 @@ static void foldersel_set_tree(Folder *cur_folder, FolderSelectionType type)
                                              folder->node,
                                              foldersel_gnode_func,
                                              NULL);
                                              folder->node,
                                              foldersel_gnode_func,
                                              NULL);
-               gtk_ctree_sort_recursive(GTK_CTREE(ctree), node);
+               gtk_sctree_sort_recursive(GTK_CTREE(ctree), node);
                SET_SPECIAL_FOLDER(folder->inbox);
                SET_SPECIAL_FOLDER(folder->outbox);
                SET_SPECIAL_FOLDER(folder->draft);
                SET_SPECIAL_FOLDER(folder->inbox);
                SET_SPECIAL_FOLDER(folder->outbox);
                SET_SPECIAL_FOLDER(folder->draft);
index 234ceddbb31e091b452f53a8da33e376022d61a9..8e10ab7288a55fd8b9f511e24df8a50eaae70b79 100644 (file)
@@ -1292,7 +1292,7 @@ static void folderview_sort_folders(FolderView *folderview, GtkCTreeNode *root,
        GtkCTree *ctree = GTK_CTREE(folderview->ctree);
        GtkCTreeNode *prev = NULL;
 
        GtkCTree *ctree = GTK_CTREE(folderview->ctree);
        GtkCTreeNode *prev = NULL;
 
-       gtk_ctree_sort_recursive(ctree, root);
+       gtk_sctree_sort_recursive(ctree, root);
 
        if (GTK_CTREE_ROW(root)->parent) return;
 
 
        if (GTK_CTREE_ROW(root)->parent) return;
 
index 5ac6f50bb94e5d8e6b6e812fa36c682b56f7572d..2fe6a81210da038c007c99d87f612675e42c7d89 100644 (file)
@@ -37,11 +37,35 @@ static void gtk_sctree_drag_data_received (GtkWidget *widget, GdkDragContext *co
 static void gtk_sctree_clear (GtkCList *clist);
 static void gtk_sctree_collapse (GtkCTree *ctree, GtkCTreeNode *node);
        
 static void gtk_sctree_clear (GtkCList *clist);
 static void gtk_sctree_collapse (GtkCTree *ctree, GtkCTreeNode *node);
        
+static void tree_sort (GtkCTree *ctree, GtkCTreeNode  *node, gpointer data);
+void gtk_sctree_sort_node (GtkCTree *ctree, GtkCTreeNode *node);
+static void real_sort_list (GtkCList *clist);
+void gtk_sctree_sort_recursive (GtkCTree *ctree, GtkCTreeNode *node);
+
+static void gtk_ctree_link (GtkCTree *ctree,
+                       GtkCTreeNode  *node,
+                       GtkCTreeNode  *parent,
+                       GtkCTreeNode  *sibling,
+                       gboolean       update_focus_row);
+
+static void gtk_ctree_unlink (GtkCTree      *ctree, 
+                       GtkCTreeNode  *node,
+                       gboolean       update_focus_row);
+
+static void tree_update_level (GtkCTree      *ctree, 
+                       GtkCTreeNode  *node, 
+                       gpointer       data);
+
+static GtkCTreeNode * gtk_ctree_last_visible (GtkCTree     *ctree,
+                                             GtkCTreeNode *node);
+
 static GtkCTreeClass *parent_class;
 
 static guint sctree_signals[LAST_SIGNAL];
 
 
 static GtkCTreeClass *parent_class;
 
 static guint sctree_signals[LAST_SIGNAL];
 
 
+#define GTK_CLIST_CLASS_FW(_widget_) GTK_CLIST_CLASS (((GtkObject*) (_widget_))->klass)
+
 /**
  * gtk_sctree_get_type:
  * @void: 
 /**
  * gtk_sctree_get_type:
  * @void: 
@@ -195,8 +219,8 @@ select_row (GtkSCTree *sctree, gint row, gint col, guint state)
        g_return_if_fail (GTK_IS_SCTREE (sctree));
     
        range = ((state & GDK_SHIFT_MASK) != 0) &&
        g_return_if_fail (GTK_IS_SCTREE (sctree));
     
        range = ((state & GDK_SHIFT_MASK) != 0) &&
-               (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_SINGLE) &&
-               (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_BROWSE);
+               (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_SINGLE) &&
+               (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_BROWSE);
        additive = ((state & GDK_CONTROL_MASK) != 0) &&
                   (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_SINGLE) &&
                   (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_BROWSE);
        additive = ((state & GDK_CONTROL_MASK) != 0) &&
                   (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_SINGLE) &&
                   (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_BROWSE);
@@ -539,3 +563,480 @@ void  gtk_sctree_unselect_all (GtkSCTree *sctree)
        sctree->anchor_row = NULL;
 }
 
        sctree->anchor_row = NULL;
 }
 
+/***********************************************************
+ *             Tree sorting functions                      *
+ ***********************************************************/
+
+static void sink(GtkCList *clist, GPtrArray *numbers, gint root, gint bottom)
+{
+       gint j, k ;
+       GtkCTreeNode *temp;
+
+       j = 2 * root;
+       k = j + 1;
+
+       /* find the maximum element of numbers[root],
+          numbers[2*root] and numbers[2*root+1] */
+       if (j <= bottom) {
+               if (clist->compare( clist, GTK_CTREE_ROW (g_ptr_array_index(numbers, root)),
+                                   GTK_CTREE_ROW(g_ptr_array_index( numbers, j))) >= 0)
+                       j = root;
+               if (k <= bottom)
+                       if (clist->compare( clist, GTK_CTREE_ROW (g_ptr_array_index(numbers, k)),
+                                           GTK_CTREE_ROW (g_ptr_array_index( numbers, j))) > 0)
+                               j = k;
+               /* if numbers[root] wasn't the maximum element then
+                  sink again */
+               if (root != j) {
+                       temp = g_ptr_array_index( numbers,root);
+                       g_ptr_array_index( numbers, root) = g_ptr_array_index( numbers, j);
+                       g_ptr_array_index( numbers, j) = temp;
+                       sink( clist, numbers, j, bottom);
+               }
+       }
+}
+
+static void heap_sort(GtkCList *clist, GPtrArray *numbers, gint array_size)
+{
+       gint i;
+       GtkCTreeNode *temp;
+       
+       /* build the Heap */
+       for (i = (array_size / 2); i >= 1; i--)
+               sink( clist, numbers, i, array_size);
+       /* output the Heap */
+       for (i = array_size; i >= 2; i--) {
+               temp = g_ptr_array_index( numbers, 1);
+               g_ptr_array_index( numbers, 1) = g_ptr_array_index( numbers, i);
+               g_ptr_array_index( numbers, i) = temp;
+               sink( clist, numbers, 1, i-1);
+       }
+}
+
+static void
+tree_sort (GtkCTree    *ctree,
+          GtkCTreeNode *node,
+          gpointer      data)
+{
+       GtkCTreeNode *list_start, *work, *next;
+       GPtrArray *row_array, *viewable_array;
+       GtkCList *clist;
+       gint i;
+
+
+       clist = GTK_CLIST (ctree);
+
+       if (node)
+               work = GTK_CTREE_ROW (node)->children;
+       else
+               work = GTK_CTREE_NODE (clist->row_list);
+
+       row_array = g_ptr_array_new();
+       viewable_array = g_ptr_array_new();
+
+       if (work) {
+               g_ptr_array_add( row_array, NULL);
+               while (work) {
+                       /* add all rows to row_array */
+                       g_ptr_array_add( row_array, work);
+                       if (GTK_CTREE_ROW (work)->parent && gtk_ctree_is_viewable( ctree, work))
+                               g_ptr_array_add( viewable_array, GTK_CTREE_ROW (work)->parent);
+                       next = GTK_CTREE_ROW (work)->sibling;
+                       gtk_ctree_unlink( ctree, work, FALSE);
+                       work = next;
+               }
+
+               heap_sort( clist, row_array, (row_array->len)-1);
+
+               if (node)
+                       list_start = GTK_CTREE_ROW (node)->children;
+               else
+                       list_start = GTK_CTREE_NODE (clist->row_list);
+
+               if (clist->sort_type == GTK_SORT_ASCENDING) {
+                       for (i=(row_array->len)-1; i>=1; i--) {
+                               work = g_ptr_array_index( row_array, i);
+                               gtk_ctree_link( ctree, work, node, list_start, FALSE);
+                               list_start = work;
+                               /* insert work at the beginning of the list */
+                       }
+               } else {
+                       for (i=1; i<row_array->len; i++) {
+                               work = g_ptr_array_index( row_array, i);
+                               gtk_ctree_link( ctree, work, node, list_start, FALSE);
+                               list_start = work;
+                               /* insert work at the beginning of the list */
+                       }
+               }
+
+               for (i=0; i<viewable_array->len; i++) {
+                       gtk_ctree_expand( ctree, g_ptr_array_index( viewable_array, i));
+               }
+               
+       }
+
+       g_ptr_array_free( row_array, FALSE);
+       g_ptr_array_free( viewable_array, FALSE);
+}
+
+void
+gtk_sctree_sort_recursive (GtkCTree     *ctree, 
+                         GtkCTreeNode *node)
+{
+       GtkCList *clist;
+       GtkCTreeNode *focus_node = NULL;
+
+       g_return_if_fail (ctree != NULL);
+       g_return_if_fail (GTK_IS_CTREE (ctree));
+
+       clist = GTK_CLIST (ctree);
+
+       gtk_clist_freeze (clist);
+
+       if (clist->selection_mode == GTK_SELECTION_EXTENDED) {
+               GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+      
+               g_list_free (clist->undo_selection);
+               g_list_free (clist->undo_unselection);
+               clist->undo_selection = NULL;
+               clist->undo_unselection = NULL;
+       }
+
+       if (!node || (node && gtk_ctree_is_viewable (ctree, node)))
+               focus_node = GTK_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row));
+      
+       gtk_ctree_post_recursive (ctree, node, GTK_CTREE_FUNC (tree_sort), NULL);
+
+       if (!node)
+               tree_sort (ctree, NULL, NULL);
+
+       if (focus_node) {
+               clist->focus_row = g_list_position (clist->row_list,(GList *)focus_node);
+               clist->undo_anchor = clist->focus_row;
+       }
+
+       gtk_clist_thaw (clist);
+}
+
+static void
+real_sort_list (GtkCList *clist)
+{
+       gtk_sctree_sort_recursive (GTK_CTREE (clist), NULL);
+}
+
+void
+gtk_sctree_sort_node (GtkCTree     *ctree, 
+                    GtkCTreeNode *node)
+{
+       GtkCList *clist;
+       GtkCTreeNode *focus_node = NULL;
+
+       g_return_if_fail (ctree != NULL);
+       g_return_if_fail (GTK_IS_CTREE (ctree));
+
+       clist = GTK_CLIST (ctree);
+
+       gtk_clist_freeze (clist);
+
+       if (clist->selection_mode == GTK_SELECTION_EXTENDED) {
+               GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+               g_list_free (clist->undo_selection);
+               g_list_free (clist->undo_unselection);
+               clist->undo_selection = NULL;
+               clist->undo_unselection = NULL;
+       }
+
+       if (!node || (node && gtk_ctree_is_viewable (ctree, node)))
+               focus_node = GTK_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row));
+
+       tree_sort (ctree, node, NULL);
+
+       if (focus_node) {
+               clist->focus_row = g_list_position (clist->row_list,(GList *)focus_node);
+               clist->undo_anchor = clist->focus_row;
+       }
+
+       gtk_clist_thaw (clist);
+}
+
+/************************************************************************/
+
+static void
+gtk_ctree_unlink (GtkCTree     *ctree, 
+                 GtkCTreeNode *node,
+                  gboolean      update_focus_row)
+{
+       GtkCList *clist;
+       gint rows;
+       gint level;
+       gint visible;
+       GtkCTreeNode *work;
+       GtkCTreeNode *parent;
+       GList *list;
+
+       g_return_if_fail (ctree != NULL);
+       g_return_if_fail (GTK_IS_CTREE (ctree));
+       g_return_if_fail (node != NULL);
+
+       clist = GTK_CLIST (ctree);
+  
+       if (update_focus_row && clist->selection_mode == GTK_SELECTION_EXTENDED) {
+               GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+               g_list_free (clist->undo_selection);
+               g_list_free (clist->undo_unselection);
+               clist->undo_selection = NULL;
+               clist->undo_unselection = NULL;
+       }
+
+       visible = gtk_ctree_is_viewable (ctree, node);
+
+       /* clist->row_list_end unlinked ? */
+       if (visible && (GTK_CTREE_NODE_NEXT (node) == NULL ||
+          (GTK_CTREE_ROW (node)->children && gtk_ctree_is_ancestor (ctree, node,
+           GTK_CTREE_NODE (clist->row_list_end)))))
+               clist->row_list_end = (GList *) (GTK_CTREE_NODE_PREV (node));
+
+       /* update list */
+       rows = 0;
+       level = GTK_CTREE_ROW (node)->level;
+       work = GTK_CTREE_NODE_NEXT (node);
+       while (work && GTK_CTREE_ROW (work)->level > level) {
+               work = GTK_CTREE_NODE_NEXT (work);
+               rows++;
+       }
+
+       if (visible) {
+               clist->rows -= (rows + 1);
+
+               if (update_focus_row) {
+                       gint pos;
+
+                       pos = g_list_position (clist->row_list, (GList *)node);
+                       if (pos + rows < clist->focus_row)
+                               clist->focus_row -= (rows + 1);
+                       else if (pos <= clist->focus_row) {
+                               if (!GTK_CTREE_ROW (node)->sibling)
+                                       clist->focus_row = MAX (pos - 1, 0);
+                               else
+                                       clist->focus_row = pos;
+             
+                               clist->focus_row = MIN (clist->focus_row, clist->rows - 1);
+                       }
+                       clist->undo_anchor = clist->focus_row;
+               }
+       }
+
+       if (work) {
+               list = (GList *)GTK_CTREE_NODE_PREV (work);
+               list->next = NULL;
+               list = (GList *)work;
+               list->prev = (GList *)GTK_CTREE_NODE_PREV (node);
+       }
+
+       if (GTK_CTREE_NODE_PREV (node) &&
+           GTK_CTREE_NODE_NEXT (GTK_CTREE_NODE_PREV (node)) == node) {
+               list = (GList *)GTK_CTREE_NODE_PREV (node);
+               list->next = (GList *)work;
+       }
+
+       /* update tree */
+       parent = GTK_CTREE_ROW (node)->parent;
+       if (parent) {
+               if (GTK_CTREE_ROW (parent)->children == node) {
+                       GTK_CTREE_ROW (parent)->children = GTK_CTREE_ROW (node)->sibling;
+                       if (!GTK_CTREE_ROW (parent)->children)
+                               gtk_ctree_collapse (ctree, parent);
+               }
+               else {
+                       GtkCTreeNode *sibling;
+
+                       sibling = GTK_CTREE_ROW (parent)->children;
+                       while (GTK_CTREE_ROW (sibling)->sibling != node)
+                               sibling = GTK_CTREE_ROW (sibling)->sibling;
+                       GTK_CTREE_ROW (sibling)->sibling = GTK_CTREE_ROW (node)->sibling;
+               }
+       }
+       else {
+               if (clist->row_list == (GList *)node)
+                       clist->row_list = (GList *) (GTK_CTREE_ROW (node)->sibling);
+               else {
+                       GtkCTreeNode *sibling;
+
+                       sibling = GTK_CTREE_NODE (clist->row_list);
+                       while (GTK_CTREE_ROW (sibling)->sibling != node)
+                               sibling = GTK_CTREE_ROW (sibling)->sibling;
+                       GTK_CTREE_ROW (sibling)->sibling = GTK_CTREE_ROW (node)->sibling;
+               }
+       }
+}
+
+static void
+gtk_ctree_link (GtkCTree     *ctree,
+               GtkCTreeNode *node,
+               GtkCTreeNode *parent,
+               GtkCTreeNode *sibling,
+               gboolean      update_focus_row)
+{
+       GtkCList *clist;
+       GList *list_end;
+       GList *list;
+       GList *work;
+       gboolean visible = FALSE;
+       gint rows = 0;
+  
+       if (sibling)
+               g_return_if_fail (GTK_CTREE_ROW (sibling)->parent == parent);
+       g_return_if_fail (node != NULL);
+       g_return_if_fail (node != sibling);
+       g_return_if_fail (node != parent);
+
+       clist = GTK_CLIST (ctree);
+
+       if (update_focus_row && clist->selection_mode == GTK_SELECTION_EXTENDED) {
+               GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+               g_list_free (clist->undo_selection);
+               g_list_free (clist->undo_unselection);
+               clist->undo_selection = NULL;
+               clist->undo_unselection = NULL;
+       }
+
+       for (rows = 1, list_end = (GList *)node; list_end->next;
+            list_end = list_end->next)
+               rows++;
+
+       GTK_CTREE_ROW (node)->parent = parent;
+       GTK_CTREE_ROW (node)->sibling = sibling;
+
+       if (!parent || (parent && (gtk_ctree_is_viewable (ctree, parent) &&
+           GTK_CTREE_ROW (parent)->expanded))) {
+               visible = TRUE;
+               clist->rows += rows;
+       }
+
+       if (parent)
+               work = (GList *)(GTK_CTREE_ROW (parent)->children);
+       else
+               work = clist->row_list;
+
+       if (sibling) {
+               if (work != (GList *)sibling) {
+                       while (GTK_CTREE_ROW (work)->sibling != sibling)
+                               work = (GList *)(GTK_CTREE_ROW (work)->sibling);
+                       GTK_CTREE_ROW (work)->sibling = node;
+               }
+
+               if (sibling == GTK_CTREE_NODE (clist->row_list))
+               clist->row_list = (GList *) node;
+               if (GTK_CTREE_NODE_PREV (sibling) &&
+                   GTK_CTREE_NODE_NEXT (GTK_CTREE_NODE_PREV (sibling)) == sibling) {
+                       list = (GList *)GTK_CTREE_NODE_PREV (sibling);
+                       list->next = (GList *)node;
+               }
+
+               list = (GList *)node;
+               list->prev = (GList *)GTK_CTREE_NODE_PREV (sibling);
+               list_end->next = (GList *)sibling;
+               list = (GList *)sibling;
+               list->prev = list_end;
+               if (parent && GTK_CTREE_ROW (parent)->children == sibling)
+                       GTK_CTREE_ROW (parent)->children = node;
+       }
+       else {
+               if (work) {
+                       /* find sibling */
+                       while (GTK_CTREE_ROW (work)->sibling)
+                       work = (GList *)(GTK_CTREE_ROW (work)->sibling);
+                       GTK_CTREE_ROW (work)->sibling = node;
+
+                       /* find last visible child of sibling */
+                       work = (GList *) gtk_ctree_last_visible (ctree,
+                              GTK_CTREE_NODE (work));
+
+                       list_end->next = work->next;
+                       if (work->next)
+                               list = work->next->prev = list_end;
+                       work->next = (GList *)node;
+                       list = (GList *)node;
+                       list->prev = work;
+               }
+               else {
+                       if (parent) {
+                               GTK_CTREE_ROW (parent)->children = node;
+                               list = (GList *)node;
+                               list->prev = (GList *)parent;
+                               if (GTK_CTREE_ROW (parent)->expanded) {
+                                       list_end->next = (GList *)GTK_CTREE_NODE_NEXT (parent);
+                                       if (GTK_CTREE_NODE_NEXT(parent)) {
+                                               list = (GList *)GTK_CTREE_NODE_NEXT (parent);
+                                               list->prev = list_end;
+                                       }
+                                       list = (GList *)parent;
+                                       list->next = (GList *)node;
+                               }
+                               else
+                                       list_end->next = NULL;
+                       }
+                       else {
+                               clist->row_list = (GList *)node;
+                               list = (GList *)node;
+                               list->prev = NULL;
+                               list_end->next = NULL;
+                       }
+               }
+       }
+
+       gtk_ctree_pre_recursive (ctree, node, tree_update_level, NULL); 
+
+       if (clist->row_list_end == NULL ||
+           clist->row_list_end->next == (GList *)node)
+               clist->row_list_end = list_end;
+
+       if (visible && update_focus_row) {
+               gint pos;
+         
+               pos = g_list_position (clist->row_list, (GList *)node);
+  
+               if (pos <= clist->focus_row) {
+                       clist->focus_row += rows;
+                       clist->undo_anchor = clist->focus_row;
+               }
+       }
+}
+
+static void
+tree_update_level (GtkCTree     *ctree, 
+                  GtkCTreeNode *node, 
+                  gpointer      data)
+{
+       if (!node)
+               return;
+
+       if (GTK_CTREE_ROW (node)->parent)
+               GTK_CTREE_ROW (node)->level = 
+               GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->level + 1;
+       else
+               GTK_CTREE_ROW (node)->level = 1;
+}
+
+static GtkCTreeNode *
+gtk_ctree_last_visible (GtkCTree     *ctree,
+                       GtkCTreeNode *node)
+{
+       GtkCTreeNode *work;
+  
+       if (!node)
+               return NULL;
+
+       work = GTK_CTREE_ROW (node)->children;
+
+       if (!work || !GTK_CTREE_ROW (node)->expanded)
+               return node;
+
+       while (GTK_CTREE_ROW (work)->sibling)
+               work = GTK_CTREE_ROW (work)->sibling;
+
+       return gtk_ctree_last_visible (ctree, work);
+}
index 94f600a44ee60f0f4a1a385aa1f1710c547c7ed4..e463f3acf789c076129e8c76f74bb4f0d062a4ac 100644 (file)
@@ -61,4 +61,15 @@ void  gtk_sctree_select (GtkSCTree *sctree,
 
 void  gtk_sctree_unselect_all (GtkSCTree *sctree);
 
 
 void  gtk_sctree_unselect_all (GtkSCTree *sctree);
 
+/***********************************************************
+ *             Tree sorting functions                      *
+ ***********************************************************/
+
+void gtk_sctree_sort_node (GtkCTree *ctree, GtkCTreeNode *node);
+
+void gtk_sctree_sort_recursive (GtkCTree *ctree, GtkCTreeNode *node);
+
+
+
+
 #endif /* __GTK_SCTREE_H__ */
 #endif /* __GTK_SCTREE_H__ */
index 37b255f31884ecdb8f7685280e361b18521413f9..50bd12e4b648351f871b604dc3399d259f1a985c 100644 (file)
@@ -1944,7 +1944,7 @@ void summary_sort(SummaryView *summaryview,
        summary_set_column_titles(summaryview);
        summary_set_menu_sensitive(summaryview);
 
        summary_set_column_titles(summaryview);
        summary_set_menu_sensitive(summaryview);
 
-       gtk_ctree_sort_recursive(ctree, NULL);
+       gtk_sctree_sort_recursive(ctree, NULL);
 
        gtk_ctree_node_moveto(ctree, summaryview->selected, -1, 0.5, 0);
 
 
        gtk_ctree_node_moveto(ctree, summaryview->selected, -1, 0.5, 0);