aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table/e-tree.c
diff options
context:
space:
mode:
authorChristopher James Lahey <clahey@ximian.com>2001-03-20 12:43:42 +0800
committerChris Lahey <clahey@src.gnome.org>2001-03-20 12:43:42 +0800
commit1510304c2de206313c637d9269b4fb451cb50adb (patch)
tree391fc87bab4413e5eec82de476d6ca08db2ce27d /widgets/table/e-tree.c
parent0629bbb778bf9634c380067b65a7f62f2f05a676 (diff)
downloadgsoc2013-evolution-1510304c2de206313c637d9269b4fb451cb50adb.tar.gz
gsoc2013-evolution-1510304c2de206313c637d9269b4fb451cb50adb.tar.zst
gsoc2013-evolution-1510304c2de206313c637d9269b4fb451cb50adb.zip
Deal with proxy_node_changed being called on a different root node than
2001-03-19 Christopher James Lahey <clahey@ximian.com> * e-tree-sorted.c (ets_proxy_node_changed): Deal with proxy_node_changed being called on a different root node than the one we have in our tree. * e-tree-table-adapter.c: Did some general clean up here. * Merged branch: 2001-03-19 Christopher James Lahey <clahey@ximian.com> * e-tree-sorted.c (find_child_path): Added this function to allow us to find paths that have been removed from the source. (ets_proxy_node_removed): Fixed the memmove here a bit. Call find_child_path. * e-tree-table-adapter.c (find_node): Check that the passed in path isn't NULL. 2001-03-19 Christopher James Lahey <clahey@ximian.com> * e-table-item.c (eti_reflow): Get width from header object instead of calculating it ourselves. * e-table-selection-model.c: Turn off selection saving since it's so slow. * e-table.c (e_table_set_state_object): Set the width of the newly created header object. * e-tree.c (e_tree_set_state_object): Set the width of the newly created header object. (tree_canvas_size_allocate): Don't bother setting the dimensions of the white background twice. 2001-03-18 Christopher James Lahey <clahey@ximian.com> * e-table-selection-model.c, e-table-selection-model.h: Made ETableSelectionModel save the cursor properly across changed signals if has_save_id is true. 2001-03-18 Christopher James Lahey <clahey@ximian.com> * e-table-selection-model.c, e-table-selection-model.h: Made ETableSelectionModel save selection properly across changed signals if has_save_id is true. * e-tree-memory.c: A couple of typos. 2001-03-18 Christopher James Lahey <clahey@ximian.com> * e-tree-memory.c, e-tree-sorted.c: Send pre_changes properly. 2001-03-18 Christopher James Lahey <clahey@ximian.com> * e-tree-table-adapter.c: Send pre_changes when performing set_expanded or root_node_set_visible. 2001-03-18 Christopher James Lahey <clahey@ximian.com> * e-tree-sorted.c (ets_is_expandable): When the API requests whether the object is expandable and it isn't, make sure to send a signal when it becomes expandable. * e-tree-table-adapter.c: Made it so that in a number of cases where it doesn't need to create an empty hash table node if the current tree node has no children, it doesn't. 2001-03-18 Christopher James Lahey <clahey@ximian.com> * e-tree-memory-callbacks.c, e-tree-memory-callbacks.h (etmc_has_save_id, etmc_get_save_id): Added has_save_id and get_save_id to the list of methods supported by e_tree_memory_callbacks. * e-tree-table-adapter.c, e-tree-table-adapter.h: Added saving of expanded nodes. 2001-03-18 Christopher James Lahey <clahey@ximian.com> * e-table-model.c, e-table-model.h (e_table_model_get_save_id): Changed row_save_id to get_save_id to be consistent with ETree. * e-tree-model.c, e-tree-model.h: Added "pre_change" signal. Added has_save_id and get_save_id methods. * e-tree-sorted.c: Proxy pre_change signal. Implemented has_save_id and get_save_id. If the base model doesn't provide has_save_id then we g_strdup_printf the pointer of the base model ETreePath as the save_id. * e-tree-table-adapter.c: Proxy pre_change signal. If base model has_save_id, then use the results of get_save_id as the key for the hash table of node attributes. Otherwise use the pointer as before. 2001-03-17 Christopher James Lahey <clahey@ximian.com> * e-tree-sorted.c (ets_sort_idle): Fixed it so that all nodes get sorted properly instead of just the top node. 2001-03-17 Christopher James Lahey <clahey@ximian.com> * e-table-sorting-utils.c (e_table_sorting_utils_tree_sort): Made tree sorting faster by using a cache. * e-tree-sorted.c: Added commented out debugging g_prints. 2001-03-17 Christopher James Lahey <clahey@ximian.com> * e-tree-sorted.c: Switched to using GMemChunks. 2001-03-17 Christopher James Lahey <clahey@ximian.com> * e-tree-sorted.c (resort_node): Made it so that children of a node that's being sorted don't send changed signals. 2001-03-17 Christopher James Lahey <clahey@ximian.com> * e-table-sorting-utils.c, e-table-sorting-utils.h: Switched to using e_sort and e_search instead of qsort and a linear search. Added the tree functions e_table_sorting_utils_tree_sort, e_table_sorting_utils_tree_check_position, and e_table_sorting_utils_tree_insert. * e-tree-sorted.c: Made this actually do sorting. * e-tree-table-adapter.c (etta_proxy_node_changed): The old_size needs to be the number of visible children + 1 to include the top node. * e-tree.c (e_tree_set_state_object): Set the sort_info on the ETreeSorted when you get a new sort_info. 2001-03-16 Christopher James Lahey <clahey@ximian.com> * Makefile.am: Added e-tree-sorted.c and e-tree-sorted.h. * e-table-item.c (eti_realize_cell_views): Only realize the cells if they're not realized already and if the canvas is realized. * e-table-sorted.c (ets_proxy_model_cell_changed): Matched the change to the signature of e_table_sorting_utils_affects_sort. * e-table-sorting-utils.c, e-table-sorting-utils.h (e_table_sorting_utils_affects_sort): Changed the signature of this function to not take the ETableModel source since it doesn't use it and we need to use this function for ETreeSorted which doesn't have an ETableModel. * e-tree-memory.c (etmm_get_expanded_default): Actually implement the get_expanded_default for this tree. * e-tree-model.h: Cleaned up the indentation here. * e-tree-sorted.c, e-tree-sorted.h: New class meant to be used for sorting trees. It doesn't actually sort yet. It simply acts as an ETreeProxy which is the hardest part of making ETreeSorted. * e-tree.c, e-tree.h: Made this use an ETreeSorted. 2001-03-14 Christopher James Lahey <clahey@ximian.com> * e-table-item.c, e-table-item.h, e-table-selection-model.c, e-table-selection-model.h, e-table-sorted.c, e-table-sorted.h, e-table-subset.c, e-table-subset.h, e-table.c, e-table.h: Switch to handling e_table_model_rows_inserted instead of e_table_model_row_inserted and e_table_model_rows_deleted instead of e_table_model_row_deleted. * e-table-model.c, e-table-model.h: Replaced the signals "model_row_inserted" and "model_row_deleted" with "model_rows_inserted" and "model_rows_deleted" so that when multiple rows are inserted or deleted at the same time they can be handled properly. * e-tree-table-adapter.c: Call "model_rows_inserted" and "model_rows_deleted" instead of "model_changed" when inserting or deleting multiple rows. 2001-03-14 Christopher James Lahey <clahey@ximian.com> * e-table-item.c (e_table_item_row_diff): Made this not count the pixel between rows if it isn't there. 2001-03-14 Christopher James Lahey <clahey@ximian.com> * e-table-item.c (eti_header_structure_changed): Properly attach & realize cell views here. 2001-03-13 Christopher James Lahey <clahey@ximian.com> * e-tree-table-adapter.c (etta_proxy_node_removed): Check that parent_node and parent aren't NULL before making function calls on them. 2001-03-13 Christopher James Lahey <clahey@ximian.com> * e-table-item.c (confirm_height_cache): Fixed a height cache miscalculation. * e-tree-table-adapter.c (find_first_child_node): Made the semantics of this mean that find_first_child_node(adapter, -1) means return the first node in the tree. 2001-03-13 Christopher James Lahey <clahey@ximian.com> * e-table-extras.c: Added a "string-integer" comparison function to the default %ETableExtras so you can do comparisons based on integer value even if you using strings for the data (this lets you do editable numbers, for instance.) * e-table-item.c: Rearranged it a bit so that if you have draw_grid off it doesn't add space for the horizontal lines, nor leave them the background color. * e-table-model.c, e-table-model.h: Added the row_save_id and has_save_id methods to %ETableModel. * e-tree.c, e-tree.h: Replaced e_tree_compute_location with e_tree_get_cell_at. 2001-03-08 Christopher James Lahey <clahey@ximian.com> * Makefile.am: Added e-table/e-table-utils.c, e-table/e-tree-memory-callbacks.c, e-table/e-tree-memory.c, e-table/e-tree-scrolled.c, e-table/e-tree-table-adapter.c, and e-table/e-tree.c. Removed e-table/e-tree-simple.c. Added e-table/e-table-utils.h, e-table/e-tree-memory-callbacks.h, e-table/e-tree-memory.h, e-table/e-tree-scrolled.h, e-table/e-tree-table-adapter.h, and e-table/e-tree.h. Removed e-table/e-tree-simple.h. * e-cell-tree.c: Updated this for the new tree. * e-table-item.c: Added some redraw requests where appropriate. * e-table-item.h: Fixed an incorrect class method declaration. * e-table-model.c, e-table-model.h: Removed e_table_model_has_sort_group and e_table_model_row_sort_group. * e-table-scrolled.h: Removed unused headers. * e-table-simple.c, e-table-simple.h: Rearranged this a bit. * e-table-sorter.c, e-table-sorting-utils.c, e-table-sorting-utils.h: Removed sort group stuff. Added the function e_table_sorting_utils_check_position. * e-table-utils.c, e-table-utils.h: Utility functions for ETable and ETree. * e-table.c: Moved some of the functionality from here to e-table-utils.c so that it can be reused by ETree. * e-tree-memory-callbacks.c, e-tree-memory-callbacks.h: Class to implement an ETreeMemory as callbacks instead of overriding the class. * e-tree-memory.c, e-tree-memory.h: ETreeModel that stores a tree of physical nodes. * e-tree-model.c, e-tree-model.h: Removed most of the functionality from here to the classes ETreeMemory and ETreeTableAdapter. This is now just a simple virtualized tree class. * e-tree-scrolled.c, e-tree-scrolled.h: New class. An ETree in an EScrollFrame. * e-tree-simple.c: Small change. This is no longer used. * e-tree-table-adapter.c, e-tree-table-adapter.h: ETableModel that represents an ETreeModel as a table. * e-tree.c, e-tree.h: New super class kind of like ETable but for trees. End of branch svn path=/trunk/; revision=8837
Diffstat (limited to 'widgets/table/e-tree.c')
-rw-r--r--widgets/table/e-tree.c2004
1 files changed, 2004 insertions, 0 deletions
diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c
new file mode 100644
index 0000000000..a434d54ea8
--- /dev/null
+++ b/widgets/table/e-tree.c
@@ -0,0 +1,2004 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-tree.c: A graphical view of a tree.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright 1999, 2000, 2001, Ximian, Inc
+ */
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdio.h>
+#include "gal/util/e-i18n.h"
+#include <libgnomeui/gnome-canvas.h>
+#include <gtk/gtksignal.h>
+
+#include "gal/util/e-util.h"
+#include "gal/widgets/e-canvas.h"
+#include "e-tree.h"
+#include "e-table-header-item.h"
+#include "e-table-header-utils.h"
+#include "e-table-subset.h"
+#include "e-table-item.h"
+#include "e-table-group.h"
+#include "e-table-group-leaf.h"
+#include "e-table-specification.h"
+#include "e-table-state.h"
+#include "e-table-column-specification.h"
+
+#include "e-table-utils.h"
+
+#define COLUMN_HEADER_HEIGHT 16
+
+#define PARENT_TYPE gtk_table_get_type ()
+
+static GtkObjectClass *parent_class;
+
+enum {
+ CURSOR_CHANGE,
+ CURSOR_ACTIVATED,
+ SELECTION_CHANGE,
+ DOUBLE_CLICK,
+ RIGHT_CLICK,
+ CLICK,
+ KEY_PRESS,
+
+ TREE_DRAG_BEGIN,
+ TREE_DRAG_END,
+ TREE_DRAG_DATA_GET,
+ TREE_DRAG_DATA_DELETE,
+
+ TREE_DRAG_LEAVE,
+ TREE_DRAG_MOTION,
+ TREE_DRAG_DROP,
+ TREE_DRAG_DATA_RECEIVED,
+
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_LENGTH_THRESHOLD,
+};
+
+static gint et_signals [LAST_SIGNAL] = { 0, };
+
+static void et_grab_focus (GtkWidget *widget);
+
+static void et_drag_begin (GtkWidget *widget,
+ GdkDragContext *context,
+ ETree *et);
+static void et_drag_end (GtkWidget *widget,
+ GdkDragContext *context,
+ ETree *et);
+static void et_drag_data_get(GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ ETree *et);
+static void et_drag_data_delete(GtkWidget *widget,
+ GdkDragContext *context,
+ ETree *et);
+
+static void et_drag_leave(GtkWidget *widget,
+ GdkDragContext *context,
+ guint time,
+ ETree *et);
+static gboolean et_drag_motion(GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ ETree *et);
+static gboolean et_drag_drop(GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ ETree *et);
+static void et_drag_data_received(GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ ETree *et);
+static gint e_tree_drag_source_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ ETree *tree);
+
+static gint et_focus (GtkContainer *container, GtkDirectionType direction);
+
+static void
+et_destroy (GtkObject *object)
+{
+ ETree *et = E_TREE (object);
+
+ if (et->reflow_idle_id)
+ g_source_remove(et->reflow_idle_id);
+ et->reflow_idle_id = 0;
+
+ gtk_object_unref (GTK_OBJECT (et->model));
+ gtk_object_unref (GTK_OBJECT (et->sorted));
+ gtk_object_unref (GTK_OBJECT (et->full_header));
+ gtk_object_unref (GTK_OBJECT (et->header));
+ gtk_object_unref (GTK_OBJECT (et->sort_info));
+ gtk_object_unref (GTK_OBJECT (et->selection));
+ if (et->spec)
+ gtk_object_unref (GTK_OBJECT (et->spec));
+
+ if (et->header_canvas != NULL)
+ gtk_widget_destroy (GTK_WIDGET (et->header_canvas));
+
+ gtk_widget_destroy (GTK_WIDGET (et->table_canvas));
+
+ (*parent_class->destroy)(object);
+}
+
+static void
+e_tree_init (GtkObject *object)
+{
+ ETree *e_tree = E_TREE (object);
+ GtkTable *gtk_table = GTK_TABLE (object);
+
+ GTK_WIDGET_SET_FLAGS (e_tree, GTK_CAN_FOCUS);
+
+ gtk_table->homogeneous = FALSE;
+
+ e_tree->sort_info = NULL;
+ e_tree->reflow_idle_id = 0;
+
+ e_tree->draw_grid = 1;
+ e_tree->draw_focus = 1;
+ e_tree->cursor_mode = E_CURSOR_SIMPLE;
+ e_tree->length_threshold = 200;
+
+ e_tree->horizontal_scrolling = FALSE;
+
+ e_tree->drop_row = -1;
+ e_tree->drop_path = NULL;
+ e_tree->drop_col = -1;
+
+ e_tree->drag_row = -1;
+ e_tree->drag_path = NULL;
+ e_tree->drag_col = -1;
+
+ e_tree->site = NULL;
+ e_tree->drag_source_button_press_event_id = 0;
+ e_tree->drag_source_motion_notify_event_id = 0;
+
+ e_tree->selection = e_table_selection_model_new();
+ e_tree->spec = NULL;
+}
+
+/* Grab_focus handler for the ETree */
+static void
+et_grab_focus (GtkWidget *widget)
+{
+ ETree *e_tree;
+
+ e_tree = E_TREE (widget);
+
+ gtk_widget_grab_focus (GTK_WIDGET (e_tree->table_canvas));
+}
+
+/* Focus handler for the ETree */
+static gint
+et_focus (GtkContainer *container, GtkDirectionType direction)
+{
+ ETree *e_tree;
+
+ e_tree = E_TREE (container);
+
+ if (container->focus_child) {
+ gtk_container_set_focus_child (container, NULL);
+ return FALSE;
+ }
+
+ return gtk_container_focus (GTK_CONTAINER (e_tree->table_canvas), direction);
+}
+
+static void
+header_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETree *e_tree)
+{
+ gnome_canvas_set_scroll_region (
+ GNOME_CANVAS (e_tree->header_canvas),
+ 0, 0, alloc->width - 1, /* COLUMN_HEADER_HEIGHT - 1 */
+ E_TABLE_HEADER_ITEM (e_tree->header_item)->height - 1);
+
+ /* When the header item is created ->height == 0,
+ as the font is only created when everything is realized.
+ So we set the usize here as well, so that the size of the
+ header is correct */
+ if (GTK_WIDGET (e_tree->header_canvas)->allocation.height !=
+ E_TABLE_HEADER_ITEM (e_tree->header_item)->height)
+ gtk_widget_set_usize (GTK_WIDGET (e_tree->header_canvas), -1,
+ E_TABLE_HEADER_ITEM (e_tree->header_item)->height);
+}
+
+static void
+e_tree_setup_header (ETree *e_tree)
+{
+ char *pointer;
+ e_tree->header_canvas = GNOME_CANVAS (e_canvas_new ());
+ GTK_WIDGET_UNSET_FLAGS (e_tree->header_canvas, GTK_CAN_FOCUS);
+
+ gtk_widget_show (GTK_WIDGET (e_tree->header_canvas));
+
+ pointer = g_strdup_printf("%p", e_tree);
+
+ e_tree->header_item = gnome_canvas_item_new (
+ gnome_canvas_root (e_tree->header_canvas),
+ e_table_header_item_get_type (),
+ "ETableHeader", e_tree->header,
+ "full_header", e_tree->full_header,
+ "sort_info", e_tree->sort_info,
+ "dnd_code", pointer,
+ /* "table", e_tree, FIXME*/
+ NULL);
+
+ g_free(pointer);
+
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree->header_canvas), "size_allocate",
+ GTK_SIGNAL_FUNC (header_canvas_size_allocate), e_tree);
+
+ gtk_widget_set_usize (GTK_WIDGET (e_tree->header_canvas), -1,
+ E_TABLE_HEADER_ITEM (e_tree->header_item)->height);
+}
+
+static gboolean
+tree_canvas_reflow_idle (ETree *e_tree)
+{
+ gdouble height, width;
+ gdouble item_height;
+ GtkAllocation *alloc = &(GTK_WIDGET (e_tree->table_canvas)->allocation);
+
+ gtk_object_get (GTK_OBJECT (e_tree->item),
+ "height", &height,
+ "width", &width,
+ NULL);
+ item_height = height;
+ height = MAX ((int)height, alloc->height);
+ width = MAX((int)width, alloc->width);
+ /* I have no idea why this needs to be -1, but it works. */
+ gnome_canvas_set_scroll_region (
+ GNOME_CANVAS (e_tree->table_canvas),
+ 0, 0, width - 1, height - 1);
+ gtk_object_set (GTK_OBJECT (e_tree->white_item),
+ "y1", item_height + 1,
+ "x2", width,
+ "y2", height,
+ NULL);
+ e_tree->reflow_idle_id = 0;
+ return FALSE;
+}
+
+static void
+tree_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc,
+ ETree *e_tree)
+{
+ gdouble width;
+ gdouble height;
+ gdouble item_height;
+
+ width = alloc->width;
+ gtk_object_get (GTK_OBJECT (e_tree->item),
+ "height", &height,
+ NULL);
+ item_height = height;
+ height = MAX ((int)height, alloc->height);
+
+ gtk_object_set (GTK_OBJECT (e_tree->item),
+ "width", width,
+ NULL);
+ gtk_object_set (GTK_OBJECT (e_tree->header),
+ "width", width,
+ NULL);
+ if (e_tree->reflow_idle_id)
+ g_source_remove(e_tree->reflow_idle_id);
+ tree_canvas_reflow_idle(e_tree);
+}
+
+static void
+tree_canvas_reflow (GnomeCanvas *canvas, ETree *e_tree)
+{
+ if (!e_tree->reflow_idle_id)
+ e_tree->reflow_idle_id = g_idle_add_full (400, (GSourceFunc) tree_canvas_reflow_idle, e_tree, NULL);
+}
+
+static void
+item_cursor_change (ETableItem *eti, int row, ETree *et)
+{
+ ETreePath path = e_tree_table_adapter_node_at_row(et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [CURSOR_CHANGE],
+ row, path);
+}
+
+static void
+item_cursor_activated (ETableItem *eti, int row, ETree *et)
+{
+ ETreePath path = e_tree_table_adapter_node_at_row(et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [CURSOR_ACTIVATED],
+ row, path);
+}
+
+static void
+item_double_click (ETableItem *eti, int row, int col, GdkEvent *event, ETree *et)
+{
+ ETreePath path = e_tree_table_adapter_node_at_row(et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [DOUBLE_CLICK],
+ row, path, col, event);
+}
+
+static gint
+item_right_click (ETableItem *eti, int row, int col, GdkEvent *event, ETree *et)
+{
+ int return_val = 0;
+ ETreePath path = e_tree_table_adapter_node_at_row(et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [RIGHT_CLICK],
+ row, path, col, event, &return_val);
+ return return_val;
+}
+
+static gint
+item_click (ETableItem *eti, int row, int col, GdkEvent *event, ETree *et)
+{
+ int return_val = 0;
+ ETreePath path = e_tree_table_adapter_node_at_row(et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [CLICK],
+ row, path, col, event, &return_val);
+ return return_val;
+}
+
+static gint
+item_key_press (ETableItem *eti, int row, int col, GdkEvent *event, ETree *et)
+{
+ int return_val = 0;
+ ETreePath path = e_tree_table_adapter_node_at_row(et->etta, row);
+ GdkEventKey *key = (GdkEventKey *) event;
+ GdkEventButton click;
+
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+
+ switch (key->keyval) {
+ case GDK_Page_Down:
+ gtk_adjustment_set_value(
+ gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas)),
+ CLAMP(gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas))->value +
+ (gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas))->page_size - 20),
+ 0,
+ gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas))->upper -
+ gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas))->page_size));
+ click.type = GDK_BUTTON_PRESS;
+ click.window = GTK_LAYOUT (et->table_canvas)->bin_window;
+ click.send_event = key->send_event;
+ click.time = key->time;
+ click.x = 30;
+ click.y = gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas))->page_size - 1;
+ click.state = key->state;
+ click.button = 1;
+ gtk_widget_event(GTK_WIDGET(et->table_canvas),
+ (GdkEvent *) &click);
+ return_val = 1;
+ break;
+ case GDK_Page_Up:
+ gtk_adjustment_set_value(
+ gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas)),
+ gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas))->value -
+ (gtk_layout_get_vadjustment (GTK_LAYOUT (et->table_canvas))->page_size - 20));
+ click.type = GDK_BUTTON_PRESS;
+ click.window = GTK_LAYOUT (et->table_canvas)->bin_window;
+ click.send_event = key->send_event;
+ click.time = key->time;
+ click.x = 30;
+ click.y = 1;
+ click.state = key->state;
+ click.button = 1;
+ gtk_widget_event(GTK_WIDGET(et->table_canvas),
+ (GdkEvent *) &click);
+ return_val = 1;
+ break;
+ default:
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [KEY_PRESS],
+ row, path, col, event, &return_val);
+ break;
+ }
+ return return_val;
+}
+
+static void
+et_selection_model_selection_change (ETableSelectionModel *etsm, ETable *et)
+{
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [SELECTION_CHANGE]);
+}
+
+static void
+et_build_item (ETree *et)
+{
+ et->item = gnome_canvas_item_new(GNOME_CANVAS_GROUP (gnome_canvas_root(et->table_canvas)),
+ e_table_item_get_type(),
+ "ETableHeader", et->header,
+ "ETableModel", et->etta,
+ "table_selection_model", et->selection,
+ "drawgrid", et->draw_grid,
+ "drawfocus", et->draw_focus,
+ "cursor_mode", et->cursor_mode,
+ "length_threshold", et->length_threshold,
+ NULL);
+
+ gtk_signal_connect (GTK_OBJECT (et->item), "cursor_change",
+ GTK_SIGNAL_FUNC (item_cursor_change), et);
+ gtk_signal_connect (GTK_OBJECT (et->item), "cursor_activated",
+ GTK_SIGNAL_FUNC (item_cursor_activated), et);
+ gtk_signal_connect (GTK_OBJECT (et->item), "double_click",
+ GTK_SIGNAL_FUNC (item_double_click), et);
+ gtk_signal_connect (GTK_OBJECT (et->item), "right_click",
+ GTK_SIGNAL_FUNC (item_right_click), et);
+ gtk_signal_connect (GTK_OBJECT (et->item), "click",
+ GTK_SIGNAL_FUNC (item_click), et);
+ gtk_signal_connect (GTK_OBJECT (et->item), "key_press",
+ GTK_SIGNAL_FUNC (item_key_press), et);
+}
+
+static void
+et_canvas_realize (GtkWidget *canvas, ETree *e_tree)
+{
+ gnome_canvas_item_set(
+ e_tree->white_item,
+ "fill_color_gdk", &GTK_WIDGET(e_tree->table_canvas)->style->base[GTK_STATE_NORMAL],
+ NULL);
+}
+
+static void
+et_canvas_button_press (GtkWidget *canvas, GdkEvent *event, ETree *e_tree)
+{
+ if (GTK_WIDGET_HAS_FOCUS(canvas)) {
+ GnomeCanvasItem *item = GNOME_CANVAS(canvas)->focused_item;
+
+ if (E_IS_TABLE_ITEM(item)) {
+ e_table_item_leave_edit(E_TABLE_ITEM(item));
+ }
+ }
+}
+
+static void
+e_tree_setup_table (ETree *e_tree)
+{
+ e_tree->table_canvas = GNOME_CANVAS (e_canvas_new ());
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree->table_canvas), "size_allocate",
+ GTK_SIGNAL_FUNC (tree_canvas_size_allocate), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree->table_canvas), "focus_in_event",
+ GTK_SIGNAL_FUNC (gtk_widget_queue_draw), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree->table_canvas), "focus_out_event",
+ GTK_SIGNAL_FUNC (gtk_widget_queue_draw), e_tree);
+
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree), "drag_begin",
+ GTK_SIGNAL_FUNC (et_drag_begin), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree), "drag_end",
+ GTK_SIGNAL_FUNC (et_drag_end), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree), "drag_data_get",
+ GTK_SIGNAL_FUNC (et_drag_data_get), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree), "drag_data_delete",
+ GTK_SIGNAL_FUNC (et_drag_data_delete), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree), "drag_motion",
+ GTK_SIGNAL_FUNC (et_drag_motion), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree), "drag_leave",
+ GTK_SIGNAL_FUNC (et_drag_leave), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree), "drag_drop",
+ GTK_SIGNAL_FUNC (et_drag_drop), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT (e_tree), "drag_data_received",
+ GTK_SIGNAL_FUNC (et_drag_data_received), e_tree);
+
+ gtk_signal_connect (GTK_OBJECT(e_tree->table_canvas), "reflow",
+ GTK_SIGNAL_FUNC (tree_canvas_reflow), e_tree);
+
+ gtk_widget_show (GTK_WIDGET (e_tree->table_canvas));
+
+ e_tree->white_item = gnome_canvas_item_new(
+ gnome_canvas_root(e_tree->table_canvas),
+ gnome_canvas_rect_get_type(),
+ "x1", (double) 0,
+ "y1", (double) 0,
+ "x2", (double) 100,
+ "y2", (double) 100,
+ "fill_color_gdk", &GTK_WIDGET(e_tree->table_canvas)->style->base[GTK_STATE_NORMAL],
+ NULL);
+
+ gtk_signal_connect (
+ GTK_OBJECT(e_tree->table_canvas), "realize",
+ GTK_SIGNAL_FUNC(et_canvas_realize), e_tree);
+ gtk_signal_connect (
+ GTK_OBJECT(e_tree->table_canvas), "button_press_event",
+ GTK_SIGNAL_FUNC(et_canvas_button_press), e_tree);
+
+ et_build_item(e_tree);
+}
+
+void
+e_tree_set_state_object(ETree *e_tree, ETableState *state)
+{
+ if (e_tree->header)
+ gtk_object_unref(GTK_OBJECT(e_tree->header));
+ e_tree->header = e_table_state_to_header (GTK_WIDGET(e_tree), e_tree->full_header, state);
+ if (e_tree->header)
+ gtk_object_ref(GTK_OBJECT(e_tree->header));
+
+ gtk_object_set (GTK_OBJECT (e_tree->header),
+ "width", (double) (GTK_WIDGET(e_tree->table_canvas)->allocation.width),
+ NULL);
+
+ if (e_tree->sort_info)
+ gtk_object_unref(GTK_OBJECT(e_tree->sort_info));
+
+ if (state->sort_info)
+ e_tree->sort_info = e_table_sort_info_duplicate(state->sort_info);
+ else
+ e_tree->sort_info = NULL;
+
+ if (e_tree->header_item)
+ gtk_object_set(GTK_OBJECT(e_tree->header_item),
+ "ETableHeader", e_tree->header,
+ "sort_info", e_tree->sort_info,
+ NULL);
+
+ if (e_tree->item)
+ gtk_object_set(GTK_OBJECT(e_tree->item),
+ "ETableHeader", e_tree->header,
+ NULL);
+
+ if (e_tree->sorted)
+ gtk_object_set(GTK_OBJECT(e_tree->sorted),
+ "sort_info", e_tree->sort_info,
+ NULL);
+}
+
+/**
+ * e_tree_set_state:
+ * @e_tree: %ETree object that will be modified
+ * @state_str: a string with the XML representation of the ETableState.
+ *
+ * This routine sets the state (as described by %ETableState) of the
+ * %ETree object.
+ */
+void
+e_tree_set_state (ETree *e_tree,
+ const gchar *state_str)
+{
+ ETableState *state;
+
+ g_return_if_fail(e_tree != NULL);
+ g_return_if_fail(E_IS_TREE(e_tree));
+ g_return_if_fail(state_str != NULL);
+
+ state = e_table_state_new();
+ e_table_state_load_from_string(state, state_str);
+
+ if (state->col_count > 0)
+ e_tree_set_state_object(e_tree, state);
+
+ gtk_object_unref(GTK_OBJECT(state));
+}
+
+/**
+ * e_tree_load_state:
+ * @e_tree: %ETree object that will be modified
+ * @filename: name of the file containing the state to be loaded into the %ETree
+ *
+ * An %ETableState will be loaded form the file pointed by @filename into the
+ * @e_tree object.
+ */
+void
+e_tree_load_state (ETree *e_tree,
+ const gchar *filename)
+{
+ ETableState *state;
+
+ g_return_if_fail(e_tree != NULL);
+ g_return_if_fail(E_IS_TREE(e_tree));
+ g_return_if_fail(filename != NULL);
+
+ state = e_table_state_new();
+ e_table_state_load_from_file(state, filename);
+
+ if (state->col_count > 0)
+ e_tree_set_state_object(e_tree, state);
+
+ gtk_object_unref(GTK_OBJECT(state));
+}
+
+/**
+ * e_tree_get_state_object:
+ * @e_tree: %ETree object that will be modified
+ *
+ * Returns: the %ETreeState object that encapsulates the current
+ * state of the @e_tree object
+ */
+ETableState *
+e_tree_get_state_object (ETree *e_tree)
+{
+ ETableState *state;
+ int full_col_count;
+ int i, j;
+
+ state = e_table_state_new();
+ state->sort_info = e_tree->sort_info;
+ gtk_object_ref(GTK_OBJECT(state->sort_info));
+
+ state->col_count = e_table_header_count (e_tree->header);
+ full_col_count = e_table_header_count (e_tree->full_header);
+ state->columns = g_new(int, state->col_count);
+ state->expansions = g_new(double, state->col_count);
+ for (i = 0; i < state->col_count; i++) {
+ ETableCol *col = e_table_header_get_column(e_tree->header, i);
+ state->columns[i] = -1;
+ for (j = 0; j < full_col_count; j++) {
+ if (col->col_idx == e_table_header_index(e_tree->full_header, j)) {
+ state->columns[i] = j;
+ break;
+ }
+ }
+ state->expansions[i] = col->expansion;
+ }
+
+ return state;
+}
+
+gchar *e_tree_get_state (ETree *e_tree)
+{
+ ETableState *state;
+ gchar *string;
+
+ state = e_tree_get_state_object(e_tree);
+ string = e_table_state_save_to_string(state);
+ gtk_object_unref(GTK_OBJECT(state));
+ return string;
+}
+
+/**
+ * e_tree_save_state:
+ * @e_tree: %ETree object that will be modified
+ * @filename: name of the file containing the state to be loaded into the %ETree
+ *
+ * This routine saves the state of the @e_tree object into the file pointed
+ * by @filename
+ */
+void
+e_tree_save_state (ETree *e_tree,
+ const gchar *filename)
+{
+ ETableState *state;
+
+ state = e_tree_get_state_object(e_tree);
+ e_table_state_save_to_file(state, filename);
+ gtk_object_unref(GTK_OBJECT(state));
+}
+
+static ETree *
+et_real_construct (ETree *e_tree, ETreeModel *etm, ETableExtras *ete,
+ ETableSpecification *specification, ETableState *state)
+{
+ int row = 0;
+
+ if (ete)
+ gtk_object_ref(GTK_OBJECT(ete));
+ else
+ ete = e_table_extras_new();
+
+ e_tree->draw_grid = specification->draw_grid;
+ e_tree->draw_focus = specification->draw_focus;
+ e_tree->cursor_mode = specification->cursor_mode;
+ e_tree->full_header = e_table_spec_to_full_header(specification, ete);
+
+ e_tree->header = e_table_state_to_header (GTK_WIDGET(e_tree), e_tree->full_header, state);
+ e_tree->horizontal_scrolling = specification->horizontal_scrolling;
+
+ e_tree->sort_info = state->sort_info;
+
+ gtk_object_set(GTK_OBJECT(e_tree->header),
+ "sort_info", e_tree->sort_info,
+ NULL);
+
+ e_tree->model = etm;
+ gtk_object_ref (GTK_OBJECT (etm));
+
+ e_tree->sorted = e_tree_sorted_new(etm, e_tree->full_header, e_tree->sort_info);
+
+ e_tree->etta = E_TREE_TABLE_ADAPTER(e_tree_table_adapter_new(E_TREE_MODEL(e_tree->sorted)));
+
+ gtk_object_set(GTK_OBJECT(e_tree->selection),
+ "model", E_TABLE_MODEL(e_tree->etta),
+ "selection_mode", specification->selection_mode,
+ "cursor_mode", specification->cursor_mode,
+ NULL);
+
+ gtk_widget_push_visual (gdk_rgb_get_visual ());
+ gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+
+ e_tree->sorter = e_sorter_new();
+
+ gtk_object_set (GTK_OBJECT (e_tree->selection),
+ "model", e_tree->etta,
+ "sorter", e_tree->sorter,
+ NULL);
+
+ gtk_signal_connect(GTK_OBJECT(e_tree->selection), "selection_changed",
+ GTK_SIGNAL_FUNC(et_selection_model_selection_change), e_tree);
+
+ if (!specification->no_headers) {
+ e_tree_setup_header (e_tree);
+ }
+ e_tree_setup_table (e_tree);
+
+ gtk_layout_get_vadjustment (GTK_LAYOUT (e_tree->table_canvas))->step_increment = 20;
+ gtk_adjustment_changed(gtk_layout_get_vadjustment (GTK_LAYOUT (e_tree->table_canvas)));
+
+ if (!specification->no_headers) {
+ /*
+ * The header
+ */
+ gtk_table_attach (GTK_TABLE (e_tree), GTK_WIDGET (e_tree->header_canvas),
+ 0, 1, 0 + row, 1 + row,
+ GTK_FILL | GTK_EXPAND,
+ GTK_FILL, 0, 0);
+ row ++;
+ }
+ gtk_table_attach (GTK_TABLE (e_tree), GTK_WIDGET (e_tree->table_canvas),
+ 0, 1, 0 + row, 1 + row,
+ GTK_FILL | GTK_EXPAND,
+ GTK_FILL | GTK_EXPAND,
+ 0, 0);
+
+ gtk_widget_pop_colormap ();
+ gtk_widget_pop_visual ();
+
+ gtk_object_unref(GTK_OBJECT(ete));
+
+ return e_tree;
+}
+
+ETree *
+e_tree_construct (ETree *e_tree, ETreeModel *etm, ETableExtras *ete,
+ const char *spec_str, const char *state_str)
+{
+ ETableSpecification *specification;
+ ETableState *state;
+
+ g_return_val_if_fail(e_tree != NULL, NULL);
+ g_return_val_if_fail(E_IS_TREE(e_tree), NULL);
+ g_return_val_if_fail(etm != NULL, NULL);
+ g_return_val_if_fail(E_IS_TREE_MODEL(etm), NULL);
+ g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL);
+ g_return_val_if_fail(spec_str != NULL, NULL);
+
+ specification = e_table_specification_new();
+ e_table_specification_load_from_string(specification, spec_str);
+ if (state_str) {
+ state = e_table_state_new();
+ e_table_state_load_from_string(state, state_str);
+ if (state->col_count <= 0) {
+ gtk_object_unref(GTK_OBJECT(state));
+ state = specification->state;
+ gtk_object_ref(GTK_OBJECT(state));
+ }
+ } else {
+ state = specification->state;
+ gtk_object_ref(GTK_OBJECT(state));
+ }
+
+ e_tree = et_real_construct (e_tree, etm, ete, specification, state);
+
+ e_tree->spec = specification;
+ gtk_object_unref(GTK_OBJECT(state));
+
+ return e_tree;
+}
+
+ETree *
+e_tree_construct_from_spec_file (ETree *e_tree, ETreeModel *etm, ETableExtras *ete,
+ const char *spec_fn, const char *state_fn)
+{
+ ETableSpecification *specification;
+ ETableState *state;
+
+ g_return_val_if_fail(e_tree != NULL, NULL);
+ g_return_val_if_fail(E_IS_TREE(e_tree), NULL);
+ g_return_val_if_fail(etm != NULL, NULL);
+ g_return_val_if_fail(E_IS_TREE_MODEL(etm), NULL);
+ g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL);
+ g_return_val_if_fail(spec_fn != NULL, NULL);
+
+ specification = e_table_specification_new();
+ if (!e_table_specification_load_from_file(specification, spec_fn)) {
+ gtk_object_unref(GTK_OBJECT(specification));
+ return NULL;
+ }
+
+ if (state_fn) {
+ state = e_table_state_new();
+ if (!e_table_state_load_from_file(state, state_fn)) {
+ gtk_object_unref(GTK_OBJECT(state));
+ state = specification->state;
+ gtk_object_ref(GTK_OBJECT(state));
+ }
+ if (state->col_count <= 0) {
+ gtk_object_unref(GTK_OBJECT(state));
+ state = specification->state;
+ gtk_object_ref(GTK_OBJECT(state));
+ }
+ } else {
+ state = specification->state;
+ gtk_object_ref(GTK_OBJECT(state));
+ }
+
+ e_tree = et_real_construct (e_tree, etm, ete, specification, state);
+
+ e_tree->spec = specification;
+ gtk_object_unref(GTK_OBJECT(state));
+
+ return e_tree;
+}
+
+GtkWidget *
+e_tree_new (ETreeModel *etm, ETableExtras *ete, const char *spec, const char *state)
+{
+ ETree *e_tree;
+
+ g_return_val_if_fail(etm != NULL, NULL);
+ g_return_val_if_fail(E_IS_TREE_MODEL(etm), NULL);
+ g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL);
+ g_return_val_if_fail(spec != NULL, NULL);
+
+ e_tree = gtk_type_new (e_tree_get_type ());
+
+ e_tree = e_tree_construct (e_tree, etm, ete, spec, state);
+
+ return GTK_WIDGET (e_tree);
+}
+
+GtkWidget *
+e_tree_new_from_spec_file (ETreeModel *etm, ETableExtras *ete, const char *spec_fn, const char *state_fn)
+{
+ ETree *e_tree;
+
+ g_return_val_if_fail(etm != NULL, NULL);
+ g_return_val_if_fail(E_IS_TREE_MODEL(etm), NULL);
+ g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL);
+ g_return_val_if_fail(spec_fn != NULL, NULL);
+
+ e_tree = gtk_type_new (e_tree_get_type ());
+
+ e_tree = e_tree_construct_from_spec_file (e_tree, etm, ete, spec_fn, state_fn);
+
+ return GTK_WIDGET (e_tree);
+}
+
+void
+e_tree_set_cursor (ETree *e_tree, ETreePath path)
+{
+ int row;
+ g_return_if_fail(e_tree != NULL);
+ g_return_if_fail(E_IS_TREE(e_tree));
+ g_return_if_fail(path != NULL);
+
+ path = e_tree_sorted_model_to_view_path(e_tree->sorted, path);
+
+ row = e_tree_table_adapter_row_of_node(E_TREE_TABLE_ADAPTER(e_tree->etta), path);
+
+ if (row == -1)
+ return;
+
+ gtk_object_set(GTK_OBJECT(e_tree->selection),
+ "cursor_row", row,
+ NULL);
+}
+
+ETreePath
+e_tree_get_cursor (ETree *e_tree)
+{
+ int row;
+ ETreePath path;
+ g_return_val_if_fail(e_tree != NULL, NULL);
+ g_return_val_if_fail(E_IS_TREE(e_tree), NULL);
+
+ gtk_object_get(GTK_OBJECT(e_tree->selection),
+ "cursor_row", &row,
+ NULL);
+ path = e_tree_table_adapter_node_at_row(E_TREE_TABLE_ADAPTER(e_tree->etta), row);
+ path = e_tree_sorted_view_to_model_path(e_tree->sorted, path);
+ return path;
+}
+
+void
+e_tree_selected_row_foreach (ETree *e_tree,
+ EForeachFunc callback,
+ gpointer closure)
+{
+ g_return_if_fail(e_tree != NULL);
+ g_return_if_fail(E_IS_TREE(e_tree));
+
+ e_selection_model_foreach(E_SELECTION_MODEL (e_tree->selection),
+ callback,
+ closure);
+}
+
+gint
+e_tree_selected_count (ETree *e_tree)
+{
+ g_return_val_if_fail(e_tree != NULL, -1);
+ g_return_val_if_fail(E_IS_TREE(e_tree), -1);
+
+ return e_selection_model_selected_count(E_SELECTION_MODEL (e_tree->selection));
+}
+
+void
+e_tree_select_all (ETree *tree)
+{
+ g_return_if_fail (tree != NULL);
+ g_return_if_fail (E_IS_TREE (tree));
+
+ e_selection_model_select_all (E_SELECTION_MODEL (tree->selection));
+}
+
+void
+e_tree_invert_selection (ETree *tree)
+{
+ g_return_if_fail (tree != NULL);
+ g_return_if_fail (E_IS_TREE (tree));
+
+ e_selection_model_invert_selection (E_SELECTION_MODEL (tree->selection));
+}
+
+
+EPrintable *
+e_tree_get_printable (ETree *e_tree)
+{
+ g_return_val_if_fail(e_tree != NULL, NULL);
+ g_return_val_if_fail(E_IS_TREE(e_tree), NULL);
+
+ return e_table_item_get_printable(E_TABLE_ITEM(e_tree->item));
+}
+
+static void
+et_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ switch (arg_id){
+ default:
+ break;
+ }
+}
+
+typedef struct {
+ char *arg;
+ gboolean setting;
+} bool_closure;
+
+static void
+et_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETree *etree = E_TREE (o);
+
+ switch (arg_id){
+ case ARG_LENGTH_THRESHOLD:
+ etree->length_threshold = GTK_VALUE_INT (*arg);
+ if (etree->item) {
+ gnome_canvas_item_set (GNOME_CANVAS_ITEM(etree->item),
+ "length_threshold", GTK_VALUE_INT (*arg),
+ NULL);
+ }
+ break;
+
+ }
+}
+
+static void
+set_scroll_adjustments (ETree *tree,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment)
+{
+ if (vadjustment != NULL) {
+ vadjustment->step_increment = 20;
+ gtk_adjustment_changed(vadjustment);
+ }
+
+ gtk_layout_set_hadjustment (GTK_LAYOUT(tree->table_canvas),
+ hadjustment);
+ gtk_layout_set_vadjustment (GTK_LAYOUT(tree->table_canvas),
+ vadjustment);
+
+ if (tree->header_canvas != NULL)
+ gtk_layout_set_hadjustment (GTK_LAYOUT(tree->header_canvas),
+ hadjustment);
+}
+
+gint
+e_tree_get_next_row (ETree *e_tree,
+ gint model_row)
+{
+ g_return_val_if_fail(e_tree != NULL, -1);
+ g_return_val_if_fail(E_IS_TREE(e_tree), -1);
+
+ if (e_tree->sorter) {
+ int i;
+ i = e_sorter_model_to_sorted(E_SORTER (e_tree->sorter), model_row);
+ i++;
+ if (i < e_table_model_row_count(E_TABLE_MODEL(e_tree->etta))) {
+ return e_sorter_sorted_to_model(E_SORTER (e_tree->sorter), i);
+ } else
+ return -1;
+ } else
+ if (model_row < e_table_model_row_count(E_TABLE_MODEL(e_tree->etta)) - 1)
+ return model_row + 1;
+ else
+ return -1;
+}
+
+gint
+e_tree_get_prev_row (ETree *e_tree,
+ gint model_row)
+{
+ g_return_val_if_fail(e_tree != NULL, -1);
+ g_return_val_if_fail(E_IS_TREE(e_tree), -1);
+
+ if (e_tree->sorter) {
+ int i;
+ i = e_sorter_model_to_sorted(E_SORTER (e_tree->sorter), model_row);
+ i--;
+ if (i >= 0)
+ return e_sorter_sorted_to_model(E_SORTER (e_tree->sorter), i);
+ else
+ return -1;
+ } else
+ return model_row - 1;
+}
+
+gint
+e_tree_model_to_view_row (ETree *e_tree,
+ gint model_row)
+{
+ g_return_val_if_fail(e_tree != NULL, -1);
+ g_return_val_if_fail(E_IS_TREE(e_tree), -1);
+
+ if (e_tree->sorter)
+ return e_sorter_model_to_sorted(E_SORTER (e_tree->sorter), model_row);
+ else
+ return model_row;
+}
+
+gint
+e_tree_view_to_model_row (ETree *e_tree,
+ gint view_row)
+{
+ g_return_val_if_fail(e_tree != NULL, -1);
+ g_return_val_if_fail(E_IS_TREE(e_tree), -1);
+
+ if (e_tree->sorter)
+ return e_sorter_sorted_to_model (E_SORTER (e_tree->sorter), view_row);
+ else
+ return view_row;
+}
+
+
+gboolean
+e_tree_node_is_expanded (ETree *et, ETreePath path)
+{
+ path = e_tree_sorted_model_to_view_path(et->sorted, path);
+
+ return e_tree_table_adapter_node_is_expanded (et->etta, path);
+}
+
+void
+e_tree_node_set_expanded (ETree *et, ETreePath path, gboolean expanded)
+{
+ g_return_if_fail (et != NULL);
+ g_return_if_fail (E_IS_TREE(et));
+
+ path = e_tree_sorted_model_to_view_path(et->sorted, path);
+
+ e_tree_table_adapter_node_set_expanded (et->etta, path, expanded);
+}
+
+void
+e_tree_node_set_expanded_recurse (ETree *et, ETreePath path, gboolean expanded)
+{
+ g_return_if_fail (et != NULL);
+ g_return_if_fail (E_IS_TREE(et));
+
+ path = e_tree_sorted_model_to_view_path(et->sorted, path);
+
+ e_tree_table_adapter_node_set_expanded_recurse (et->etta, path, expanded);
+}
+
+void
+e_tree_root_node_set_visible (ETree *et, gboolean visible)
+{
+ g_return_if_fail (et != NULL);
+ g_return_if_fail (E_IS_TREE(et));
+
+ e_tree_table_adapter_root_node_set_visible (et->etta, visible);
+}
+
+ETreePath
+e_tree_node_at_row (ETree *et, int row)
+{
+ ETreePath path;
+
+ path = e_tree_table_adapter_node_at_row (et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+
+ return path;
+}
+
+int
+e_tree_row_of_node (ETree *et, ETreePath path)
+{
+ path = e_tree_sorted_model_to_view_path(et->sorted, path);
+ return e_tree_table_adapter_row_of_node (et->etta, path);
+}
+
+gboolean
+e_tree_root_node_is_visible(ETree *et)
+{
+ return e_tree_table_adapter_root_node_is_visible (et->etta);
+}
+
+void
+e_tree_show_node (ETree *et, ETreePath path)
+{
+ g_return_if_fail (et != NULL);
+ g_return_if_fail (E_IS_TREE(et));
+
+ path = e_tree_sorted_model_to_view_path(et->sorted, path);
+
+ e_tree_table_adapter_show_node (et->etta, path);
+}
+
+void
+e_tree_save_expanded_state (ETree *et, char *filename)
+{
+ g_return_if_fail (et != NULL);
+ g_return_if_fail (E_IS_TREE(et));
+
+ e_tree_table_adapter_save_expanded_state (et->etta, filename);
+}
+
+void
+e_tree_load_expanded_state (ETree *et, char *filename)
+{
+ e_tree_table_adapter_load_expanded_state (et->etta, filename);
+}
+
+gint
+e_tree_row_count (ETree *et)
+{
+ return e_table_model_row_count (E_TABLE_MODEL(et->etta));
+}
+
+struct _ETreeDragSourceSite
+{
+ GdkModifierType start_button_mask;
+ GtkTargetList *target_list; /* Targets for drag data */
+ GdkDragAction actions; /* Possible actions */
+ GdkColormap *colormap; /* Colormap for drag icon */
+ GdkPixmap *pixmap; /* Icon for drag data */
+ GdkBitmap *mask;
+
+ /* Stored button press information to detect drag beginning */
+ gint state;
+ gint x, y;
+ gint row, col;
+};
+
+typedef enum
+{
+ GTK_DRAG_STATUS_DRAG,
+ GTK_DRAG_STATUS_WAIT,
+ GTK_DRAG_STATUS_DROP
+} GtkDragStatus;
+
+typedef struct _GtkDragDestInfo GtkDragDestInfo;
+typedef struct _GtkDragSourceInfo GtkDragSourceInfo;
+
+struct _GtkDragDestInfo
+{
+ GtkWidget *widget; /* Widget in which drag is in */
+ GdkDragContext *context; /* Drag context */
+ GtkDragSourceInfo *proxy_source; /* Set if this is a proxy drag */
+ GtkSelectionData *proxy_data; /* Set while retrieving proxied data */
+ gboolean dropped : 1; /* Set after we receive a drop */
+ guint32 proxy_drop_time; /* Timestamp for proxied drop */
+ gboolean proxy_drop_wait : 1; /* Set if we are waiting for a
+ * status reply before sending
+ * a proxied drop on.
+ */
+ gint drop_x, drop_y; /* Position of drop */
+};
+
+struct _GtkDragSourceInfo
+{
+ GtkWidget *widget;
+ GtkTargetList *target_list; /* Targets for drag data */
+ GdkDragAction possible_actions; /* Actions allowed by source */
+ GdkDragContext *context; /* drag context */
+ GtkWidget *icon_window; /* Window for drag */
+ GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */
+ GdkCursor *cursor; /* Cursor for drag */
+ gint hot_x, hot_y; /* Hot spot for drag */
+ gint button; /* mouse button starting drag */
+
+ GtkDragStatus status; /* drag status */
+ GdkEvent *last_event; /* motion event waiting for response */
+
+ gint start_x, start_y; /* Initial position */
+ gint cur_x, cur_y; /* Current Position */
+
+ GList *selections; /* selections we've claimed */
+
+ GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */
+
+ guint drop_timeout; /* Timeout for aborting drop */
+ guint destroy_icon : 1; /* If true, destroy icon_window
+ */
+};
+
+/* Drag & drop stuff. */
+/* Target */
+void
+e_tree_drag_get_data (ETree *tree,
+ int row,
+ int col,
+ GdkDragContext *context,
+ GdkAtom target,
+ guint32 time)
+{
+ ETreePath path;
+ g_return_if_fail(tree != NULL);
+ g_return_if_fail(E_IS_TREE(tree));
+
+ path = e_tree_table_adapter_node_at_row(tree->etta, row);
+ path = e_tree_sorted_view_to_model_path(tree->sorted, path);
+
+ gtk_drag_get_data(GTK_WIDGET(tree),
+ context,
+ target,
+ time);
+
+}
+
+/**
+ * e_tree_drag_highlight:
+ * @tree:
+ * @row:
+ * @col:
+ *
+ * Set col to -1 to highlight the entire row.
+ */
+void
+e_tree_drag_highlight (ETree *tree,
+ int row,
+ int col)
+{
+ g_return_if_fail(tree != NULL);
+ g_return_if_fail(E_IS_TREE(tree));
+}
+
+void
+e_tree_drag_unhighlight (ETree *tree)
+{
+ g_return_if_fail(tree != NULL);
+ g_return_if_fail(E_IS_TREE(tree));
+}
+
+void e_tree_drag_dest_set (ETree *tree,
+ GtkDestDefaults flags,
+ const GtkTargetEntry *targets,
+ gint n_targets,
+ GdkDragAction actions)
+{
+ g_return_if_fail(tree != NULL);
+ g_return_if_fail(E_IS_TREE(tree));
+
+ gtk_drag_dest_set(GTK_WIDGET(tree),
+ flags,
+ targets,
+ n_targets,
+ actions);
+}
+
+void e_tree_drag_dest_set_proxy (ETree *tree,
+ GdkWindow *proxy_window,
+ GdkDragProtocol protocol,
+ gboolean use_coordinates)
+{
+ g_return_if_fail(tree != NULL);
+ g_return_if_fail(E_IS_TREE(tree));
+
+ gtk_drag_dest_set_proxy(GTK_WIDGET(tree),
+ proxy_window,
+ protocol,
+ use_coordinates);
+}
+
+/*
+ * There probably should be functions for setting the targets
+ * as a GtkTargetList
+ */
+
+void
+e_tree_drag_dest_unset (GtkWidget *widget)
+{
+ g_return_if_fail(widget != NULL);
+ g_return_if_fail(E_IS_TREE(widget));
+
+ gtk_drag_dest_unset(widget);
+}
+
+/* Source side */
+
+void
+e_tree_drag_source_set (ETree *tree,
+ GdkModifierType start_button_mask,
+ const GtkTargetEntry *targets,
+ gint n_targets,
+ GdkDragAction actions)
+{
+ ETreeDragSourceSite *site;
+ GtkWidget *canvas;
+
+ g_return_if_fail(tree != NULL);
+ g_return_if_fail(E_IS_TREE(tree));
+
+ canvas = GTK_WIDGET(tree->table_canvas);
+ site = tree->site;
+
+ gtk_widget_add_events (canvas,
+ gtk_widget_get_events (canvas) |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_BUTTON_MOTION_MASK | GDK_STRUCTURE_MASK);
+
+ if (site) {
+ if (site->target_list)
+ gtk_target_list_unref (site->target_list);
+ } else {
+ site = g_new0 (ETreeDragSourceSite, 1);
+
+ tree->drag_source_button_press_event_id =
+ gtk_signal_connect (GTK_OBJECT (canvas), "button_press_event",
+ GTK_SIGNAL_FUNC (e_tree_drag_source_event_cb),
+ tree);
+ tree->drag_source_motion_notify_event_id =
+ gtk_signal_connect (GTK_OBJECT (canvas), "motion_notify_event",
+ GTK_SIGNAL_FUNC (e_tree_drag_source_event_cb),
+ tree);
+
+ tree->site = site;
+ }
+
+ site->start_button_mask = start_button_mask;
+
+ if (targets)
+ site->target_list = gtk_target_list_new (targets, n_targets);
+ else
+ site->target_list = NULL;
+
+ site->actions = actions;
+}
+
+void
+e_tree_drag_source_unset (ETree *tree)
+{
+ ETreeDragSourceSite *site;
+
+ g_return_if_fail (tree != NULL);
+ g_return_if_fail (E_IS_TREE(tree));
+
+ site = tree->site;
+
+ if (site) {
+ gtk_signal_disconnect (
+ GTK_OBJECT (tree->table_canvas),
+ tree->drag_source_button_press_event_id);
+ gtk_signal_disconnect (
+ GTK_OBJECT (tree->table_canvas),
+ tree->drag_source_motion_notify_event_id);
+ g_free (site);
+ tree->site = NULL;
+ }
+}
+
+/* There probably should be functions for setting the targets
+ * as a GtkTargetList
+ */
+
+GdkDragContext *
+e_tree_drag_begin (ETree *tree,
+ int row,
+ int col,
+ GtkTargetList *targets,
+ GdkDragAction actions,
+ gint button,
+ GdkEvent *event)
+{
+ ETreePath path;
+ g_return_val_if_fail (tree != NULL, NULL);
+ g_return_val_if_fail (E_IS_TREE(tree), NULL);
+
+ path = e_tree_table_adapter_node_at_row(tree->etta, row);
+ path = e_tree_sorted_view_to_model_path(tree->sorted, path);
+
+ tree->drag_row = row;
+ tree->drag_path = path;
+ tree->drag_col = col;
+
+ return gtk_drag_begin(GTK_WIDGET(tree),
+ targets,
+ actions,
+ button,
+ event);
+}
+
+/**
+ * e_tree_get_cell_at:
+ * @tree: An ETree widget
+ * @x: X coordinate for the pixel
+ * @y: Y coordinate for the pixel
+ * @row_return: Pointer to return the row value
+ * @col_return: Pointer to return the column value
+ *
+ * Return the row and column for the cell in which the pixel at (@x, @y) is
+ * contained.
+ **/
+void
+e_tree_get_cell_at (ETree *tree,
+ int x, int y,
+ int *row_return, int *col_return)
+{
+ g_return_if_fail (tree != NULL);
+ g_return_if_fail (E_IS_TREE (tree));
+ g_return_if_fail (row_return != NULL);
+ g_return_if_fail (col_return != NULL);
+
+ /* FIXME it would be nice if it could handle a NULL row_return or
+ * col_return gracefully. */
+
+ x += GTK_LAYOUT(tree->table_canvas)->hadjustment->value;
+ y += GTK_LAYOUT(tree->table_canvas)->vadjustment->value;
+ e_table_item_compute_location(E_TABLE_ITEM(tree->item), &x, &y, row_return, col_return);
+}
+
+static void
+et_drag_begin (GtkWidget *widget,
+ GdkDragContext *context,
+ ETree *et)
+{
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_BEGIN],
+ et->drag_row,
+ et->drag_path,
+ et->drag_col,
+ context);
+}
+
+static void
+et_drag_end (GtkWidget *widget,
+ GdkDragContext *context,
+ ETree *et)
+{
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_END],
+ et->drag_row,
+ et->drag_path,
+ et->drag_col,
+ context);
+}
+
+static void
+et_drag_data_get(GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ ETree *et)
+{
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_DATA_GET],
+ et->drag_row,
+ et->drag_path,
+ et->drag_col,
+ context,
+ selection_data,
+ info,
+ time);
+}
+
+static void
+et_drag_data_delete(GtkWidget *widget,
+ GdkDragContext *context,
+ ETree *et)
+{
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_DATA_DELETE],
+ et->drag_row,
+ et->drag_path,
+ et->drag_col,
+ context);
+}
+
+static void
+et_drag_leave(GtkWidget *widget,
+ GdkDragContext *context,
+ guint time,
+ ETree *et)
+{
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_LEAVE],
+ et->drop_row,
+ et->drop_path,
+ et->drop_col,
+ context,
+ time);
+ et->drop_row = -1;
+ et->drop_col = -1;
+}
+
+static gboolean
+et_drag_motion(GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ ETree *et)
+{
+ gboolean ret_val;
+ int row, col;
+ ETreePath path;
+ e_tree_get_cell_at (et,
+ x,
+ y,
+ &row,
+ &col);
+ if (et->drop_row >= 0 && et->drop_col >= 0 &&
+ row != et->drop_row && col != et->drop_row) {
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_LEAVE],
+ et->drop_row,
+ et->drop_path,
+ et->drop_col,
+ context,
+ time);
+ }
+
+ path = e_tree_table_adapter_node_at_row(et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+
+ et->drop_row = row;
+ et->drop_path = path;
+ et->drop_col = col;
+ if (row >= 0 && col >= 0)
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_MOTION],
+ et->drop_row,
+ et->drop_path,
+ et->drop_col,
+ context,
+ x,
+ y,
+ time,
+ &ret_val);
+ return ret_val;
+}
+
+static gboolean
+et_drag_drop(GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ ETree *et)
+{
+ gboolean ret_val;
+ int row, col;
+ ETreePath path;
+ e_tree_get_cell_at(et,
+ x,
+ y,
+ &row,
+ &col);
+ path = e_tree_table_adapter_node_at_row(et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+
+ if (et->drop_row >= 0 && et->drop_col >= 0 &&
+ row != et->drop_row && col != et->drop_row) {
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_LEAVE],
+ et->drop_row,
+ et->drop_path,
+ et->drop_col,
+ context,
+ time);
+ if (row >= 0 && col >= 0)
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_MOTION],
+ row,
+ path,
+ col,
+ context,
+ x,
+ y,
+ time,
+ &ret_val);
+ }
+ et->drop_row = row;
+ et->drop_path = path;
+ et->drop_col = col;
+ if (row >= 0 && col >= 0)
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_DROP],
+ et->drop_row,
+ et->drop_path,
+ et->drop_col,
+ context,
+ x,
+ y,
+ time,
+ &ret_val);
+ et->drop_row = -1;
+ et->drop_path = NULL;
+ et->drop_col = -1;
+ return ret_val;
+}
+
+static void
+et_drag_data_received(GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ ETree *et)
+{
+ int row, col;
+ ETreePath path;
+ e_tree_get_cell_at(et,
+ x,
+ y,
+ &row,
+ &col);
+ path = e_tree_table_adapter_node_at_row(et->etta, row);
+ path = e_tree_sorted_view_to_model_path(et->sorted, path);
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [TREE_DRAG_DATA_RECEIVED],
+ row,
+ path,
+ col,
+ context,
+ x,
+ y,
+ selection_data,
+ info,
+ time);
+}
+
+static gint
+e_tree_drag_source_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ ETree *tree)
+{
+ ETreeDragSourceSite *site;
+ site = tree->site;
+
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ if ((GDK_BUTTON1_MASK << (event->button.button - 1)) & site->start_button_mask) {
+ int row, col;
+ e_tree_get_cell_at(tree, event->button.x, event->button.y, &row, &col);
+ if (row >= 0 && col >= 0) {
+ site->state |= (GDK_BUTTON1_MASK << (event->button.button - 1));
+ site->x = event->button.x;
+ site->y = event->button.y;
+ site->row = row;
+ site->col = col;
+ }
+ }
+ break;
+
+ case GDK_BUTTON_RELEASE:
+ if ((GDK_BUTTON1_MASK << (event->button.button - 1)) & site->start_button_mask) {
+ site->state &= ~(GDK_BUTTON1_MASK << (event->button.button - 1));
+ }
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ if (site->state & event->motion.state & site->start_button_mask) {
+ /* FIXME: This is really broken and can leave us
+ * with a stuck grab
+ */
+ int i;
+ for (i=1; i<6; i++) {
+ if (site->state & event->motion.state &
+ GDK_BUTTON1_MASK << (i - 1))
+ break;
+ }
+
+ if (MAX (abs (site->x - event->motion.x),
+ abs (site->y - event->motion.y)) > 3) {
+ GtkDragSourceInfo *info;
+ GdkDragContext *context;
+
+ site->state = 0;
+ context = e_tree_drag_begin (tree, site->row, site->col,
+ site->target_list,
+ site->actions,
+ i, event);
+
+
+ info = g_dataset_get_data (context, "gtk-info");
+
+ if (!info->icon_window) {
+ if (site->pixmap)
+ gtk_drag_set_icon_pixmap (context,
+ site->colormap,
+ site->pixmap,
+ site->mask, -2, -2);
+ else
+ gtk_drag_set_icon_default (context);
+ }
+
+ return TRUE;
+ }
+ }
+ break;
+
+ default: /* hit for 2/3BUTTON_PRESS */
+ break;
+ }
+ return FALSE;
+}
+
+static void
+e_tree_class_init (ETreeClass *class)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ object_class = (GtkObjectClass *) class;
+ widget_class = (GtkWidgetClass *) class;
+ container_class = (GtkContainerClass *) class;
+
+ parent_class = gtk_type_class (PARENT_TYPE);
+
+ object_class->destroy = et_destroy;
+ object_class->set_arg = et_set_arg;
+ object_class->get_arg = et_get_arg;
+
+ widget_class->grab_focus = et_grab_focus;
+
+ container_class->focus = et_focus;
+
+ class->cursor_change = NULL;
+ class->cursor_activated = NULL;
+ class->selection_change = NULL;
+ class->double_click = NULL;
+ class->right_click = NULL;
+ class->click = NULL;
+ class->key_press = NULL;
+
+ class->tree_drag_begin = NULL;
+ class->tree_drag_end = NULL;
+ class->tree_drag_data_get = NULL;
+ class->tree_drag_data_delete = NULL;
+
+ class->tree_drag_leave = NULL;
+ class->tree_drag_motion = NULL;
+ class->tree_drag_drop = NULL;
+ class->tree_drag_data_received = NULL;
+
+ et_signals [CURSOR_CHANGE] =
+ gtk_signal_new ("cursor_change",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, cursor_change),
+ gtk_marshal_NONE__POINTER_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_INT);
+
+ et_signals [CURSOR_ACTIVATED] =
+ gtk_signal_new ("cursor_activated",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, cursor_activated),
+ gtk_marshal_NONE__POINTER_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_INT);
+
+ et_signals [SELECTION_CHANGE] =
+ gtk_signal_new ("selection_change",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, selection_change),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
+ et_signals [DOUBLE_CLICK] =
+ gtk_signal_new ("double_click",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, double_click),
+ e_marshal_NONE__INT_POINTER_INT_POINTER,
+ GTK_TYPE_NONE, 4, GTK_TYPE_INT, GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_POINTER);
+
+ et_signals [RIGHT_CLICK] =
+ gtk_signal_new ("right_click",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, right_click),
+ e_marshal_INT__INT_POINTER_INT_POINTER,
+ GTK_TYPE_INT, 4, GTK_TYPE_INT, GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_POINTER);
+
+ et_signals [CLICK] =
+ gtk_signal_new ("click",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, click),
+ e_marshal_INT__INT_POINTER_INT_POINTER,
+ GTK_TYPE_INT, 4, GTK_TYPE_INT, GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_POINTER);
+
+ et_signals [KEY_PRESS] =
+ gtk_signal_new ("key_press",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, key_press),
+ e_marshal_INT__INT_POINTER_INT_POINTER,
+ GTK_TYPE_INT, 4, GTK_TYPE_INT, GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_POINTER);
+
+ et_signals[TREE_DRAG_BEGIN] =
+ gtk_signal_new ("tree_drag_begin",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, tree_drag_begin),
+ e_marshal_NONE__INT_POINTER_INT_POINTER,
+ GTK_TYPE_NONE, 4,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
+ GTK_TYPE_GDK_DRAG_CONTEXT);
+ et_signals[TREE_DRAG_END] =
+ gtk_signal_new ("tree_drag_end",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, tree_drag_end),
+ e_marshal_NONE__INT_POINTER_INT_POINTER,
+ GTK_TYPE_NONE, 4,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
+ GTK_TYPE_GDK_DRAG_CONTEXT);
+ et_signals[TREE_DRAG_DATA_GET] =
+ gtk_signal_new ("tree_drag_data_get",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, tree_drag_data_get),
+ e_marshal_NONE__INT_POINTER_INT_POINTER_POINTER_UINT_UINT,
+ GTK_TYPE_NONE, 7,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
+ GTK_TYPE_GDK_DRAG_CONTEXT,
+ GTK_TYPE_SELECTION_DATA,
+ GTK_TYPE_UINT,
+ GTK_TYPE_UINT);
+ et_signals[TREE_DRAG_DATA_DELETE] =
+ gtk_signal_new ("tree_drag_data_delete",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, tree_drag_data_delete),
+ e_marshal_NONE__INT_POINTER_INT_POINTER,
+ GTK_TYPE_NONE, 4,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
+ GTK_TYPE_GDK_DRAG_CONTEXT);
+
+ et_signals[TREE_DRAG_LEAVE] =
+ gtk_signal_new ("tree_drag_leave",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, tree_drag_leave),
+ e_marshal_NONE__INT_POINTER_INT_POINTER_UINT,
+ GTK_TYPE_NONE, 5,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
+ GTK_TYPE_GDK_DRAG_CONTEXT,
+ GTK_TYPE_UINT);
+ et_signals[TREE_DRAG_MOTION] =
+ gtk_signal_new ("tree_drag_motion",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, tree_drag_motion),
+ e_marshal_BOOL__INT_POINTER_INT_POINTER_INT_INT_UINT,
+ GTK_TYPE_BOOL, 7,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
+ GTK_TYPE_GDK_DRAG_CONTEXT,
+ GTK_TYPE_INT,
+ GTK_TYPE_INT,
+ GTK_TYPE_UINT);
+ et_signals[TREE_DRAG_DROP] =
+ gtk_signal_new ("tree_drag_drop",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, tree_drag_drop),
+ e_marshal_BOOL__INT_POINTER_INT_POINTER_INT_INT_UINT,
+ GTK_TYPE_BOOL, 7,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
+ GTK_TYPE_GDK_DRAG_CONTEXT,
+ GTK_TYPE_INT,
+ GTK_TYPE_INT,
+ GTK_TYPE_UINT);
+ et_signals[TREE_DRAG_DATA_RECEIVED] =
+ gtk_signal_new ("tree_drag_data_received",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, tree_drag_data_received),
+ e_marshal_NONE__INT_POINTER_INT_POINTER_INT_INT_POINTER_UINT_UINT,
+ GTK_TYPE_NONE, 9,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
+ GTK_TYPE_GDK_DRAG_CONTEXT,
+ GTK_TYPE_INT,
+ GTK_TYPE_INT,
+ GTK_TYPE_SELECTION_DATA,
+ GTK_TYPE_UINT,
+ GTK_TYPE_UINT);
+
+ gtk_object_class_add_signals (object_class, et_signals, LAST_SIGNAL);
+
+ class->set_scroll_adjustments = set_scroll_adjustments;
+
+ widget_class->set_scroll_adjustments_signal =
+ gtk_signal_new ("set_scroll_adjustments",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETreeClass, set_scroll_adjustments),
+ gtk_marshal_NONE__POINTER_POINTER,
+ GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
+
+ gtk_object_add_arg_type ("ETree::length_threshold", GTK_TYPE_INT,
+ GTK_ARG_WRITABLE, ARG_LENGTH_THRESHOLD);
+}
+
+E_MAKE_TYPE(e_tree, "ETree", ETree, e_tree_class_init, e_tree_init, PARENT_TYPE);