aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table/e-tree-model.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-model.c
parent0629bbb778bf9634c380067b65a7f62f2f05a676 (diff)
downloadgsoc2013-evolution-1510304c2de206313c637d9269b4fb451cb50adb.tar
gsoc2013-evolution-1510304c2de206313c637d9269b4fb451cb50adb.tar.gz
gsoc2013-evolution-1510304c2de206313c637d9269b4fb451cb50adb.tar.bz2
gsoc2013-evolution-1510304c2de206313c637d9269b4fb451cb50adb.tar.lz
gsoc2013-evolution-1510304c2de206313c637d9269b4fb451cb50adb.tar.xz
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-model.c')
-rw-r--r--widgets/table/e-tree-model.c1755
1 files changed, 343 insertions, 1412 deletions
diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c
index 0658cef7db..389e37223a 100644
--- a/widgets/table/e-tree-model.c
+++ b/widgets/table/e-tree-model.c
@@ -4,10 +4,11 @@
*
* Author:
* Chris Toshok (toshok@ximian.com)
+ * Chris Lahey <clahey@ximian.com>
*
* Adapted from the gtree code and ETableModel.
*
- * (C) 2000 Ximian, Inc.
+ * (C) 2000, 2001 Ximian, Inc.
*/
#include <config.h>
@@ -27,566 +28,37 @@
#define ETM_CLASS(e) ((ETreeModelClass *)((GtkObject *)e)->klass)
-#define PARENT_TYPE E_TABLE_MODEL_TYPE
+#define PARENT_TYPE (gtk_object_get_type())
-#define TREEPATH_CHUNK_AREA_SIZE (30 * sizeof (ETreePath))
-
-static ETableModel *e_tree_model_parent_class;
-
-struct ETreeModelPriv {
- GMemChunk *node_chunk;
- ETreePath *root;
- gboolean root_visible;
- GArray *row_array; /* used in the mapping between ETable and our tree */
- GHashTable *expanded_state; /* used for loading/saving expanded state */
- GString *sort_group; /* for caching the last sort group info */
- gboolean expanded_default; /* whether nodes are created expanded or collapsed by default */
- gint frozen;
-};
-
-struct ETreePath {
- gboolean expanded;
- gboolean expanded_set;
- guint visible_descendents;
- char *save_id;
- ETreePathCompareFunc compare;
- gpointer node_data;
-
- /* parent/child/sibling pointers */
- ETreePath *parent;
- ETreePath *next_sibling;
- ETreePath *prev_sibling;
- ETreePath *first_child;
- ETreePath *last_child;
- guint32 num_children;
-};
+static GtkObjectClass *parent_class;
enum {
+ PRE_CHANGE,
NODE_CHANGED,
+ NODE_DATA_CHANGED,
+ NODE_COL_CHANGED,
NODE_INSERTED,
NODE_REMOVED,
- NODE_COLLAPSED,
- NODE_EXPANDED,
LAST_SIGNAL
};
static guint e_tree_model_signals [LAST_SIGNAL] = {0, };
-static void add_visible_descendents_to_array (ETreeModel *etm, ETreePath *node, int *row, int *count);
-
-
-/* ETreePath functions */
-
-static int
-e_tree_path_depth (ETreePath *path)
-{
- int depth = 0;
- while (path) {
- depth ++;
- path = path->parent;
- }
- return depth;
-}
-
-static void
-e_tree_path_insert (ETreePath *parent, int position, ETreePath *child)
-{
- g_return_if_fail (position <= parent->num_children || position == -1);
-
- child->parent = parent;
-
- if (parent->first_child == NULL)
- parent->first_child = child;
-
- if (position == -1 || position == parent->num_children) {
- child->prev_sibling = parent->last_child;
- if (parent->last_child)
- parent->last_child->next_sibling = child;
- parent->last_child = child;
- }
- else {
- ETreePath *c;
- for (c = parent->first_child; c; c = c->next_sibling) {
- if (position == 0) {
- child->next_sibling = c;
- child->prev_sibling = c->prev_sibling;
-
- if (child->next_sibling)
- child->next_sibling->prev_sibling = child;
- if (child->prev_sibling)
- child->prev_sibling->next_sibling = child;
-
- if (parent->first_child == c)
- parent->first_child = child;
- break;
- }
- position --;
- }
- }
-
- parent->num_children++;
-}
-
-static void
-e_tree_path_unlink (ETreePath *path)
-{
- ETreePath *parent = path->parent;
-
- /* unlink first/last child if applicable */
- if (parent) {
- if (path == parent->first_child)
- parent->first_child = path->next_sibling;
- if (path == parent->last_child)
- parent->last_child = path->prev_sibling;
-
- parent->num_children --;
- }
-
- /* unlink prev/next sibling links */
- if (path->next_sibling)
- path->next_sibling->prev_sibling = path->prev_sibling;
- if (path->prev_sibling)
- path->prev_sibling->next_sibling = path->next_sibling;
-
- path->parent = NULL;
- path->next_sibling = NULL;
- path->prev_sibling = NULL;
-}
-
-/**
- * e_tree_model_node_traverse:
- * @model:
- * @path:
- * @func:
- * @data:
- *
- *
- **/
-void
-e_tree_model_node_traverse (ETreeModel *model, ETreePath *path, ETreePathFunc func, gpointer data)
-{
- ETreePath *child;
-
- g_return_if_fail (path);
-
- child = path->first_child;
-
- while (child) {
- ETreePath *next_child = child->next_sibling;
- e_tree_model_node_traverse (model, child, func, data);
- if (func (model, child, data) == TRUE)
- return;
-
- child = next_child;
- }
-}
-
-
-
-/**
- * e_tree_model_freeze:
- * @etm: the ETreeModel to freeze.
- *
- * This function prepares an ETreeModel for a period of much change.
- * All signals regarding changes to the tree are deferred until we
- * thaw the tree.
- *
- **/
-void
-e_tree_model_freeze(ETreeModel *etm)
-{
- ETreeModelPriv *priv = etm->priv;
-
- priv->frozen ++;
-}
-
-/**
- * e_tree_model_thaw:
- * @etm: the ETreeModel to thaw.
- *
- * This function thaws an ETreeModel. All the defered signals can add
- * up to a lot, we don't know - so we just emit a model_changed
- * signal.
- *
- **/
-void
-e_tree_model_thaw(ETreeModel *etm)
-{
- ETreeModelPriv *priv = etm->priv;
-
- if (priv->frozen > 0)
- priv->frozen --;
- if (priv->frozen == 0) {
- e_table_model_changed(E_TABLE_MODEL(etm));
- }
-}
-
-
-/* virtual methods */
-
-static void
-etree_destroy (GtkObject *object)
-{
- ETreeModel *etree = E_TREE_MODEL (object);
- ETreeModelPriv *priv = etree->priv;
-
- /* XXX lots of stuff to free here */
-
- if (priv->root)
- e_tree_model_node_remove (etree, priv->root);
-
- g_array_free (priv->row_array, TRUE);
- g_hash_table_destroy (priv->expanded_state);
-
- g_string_free(priv->sort_group, TRUE);
-
- g_free (priv);
-
- GTK_OBJECT_CLASS (e_tree_model_parent_class)->destroy (object);
-}
-
-static ETreePath*
-etree_get_root (ETreeModel *etm)
-{
- ETreeModelPriv *priv = etm->priv;
- return priv->root;
-}
-
-static ETreePath*
-etree_get_parent (ETreeModel *etm, ETreePath *path)
-{
- g_return_val_if_fail (path, NULL);
-
- return path->parent;
-}
-
-static ETreePath*
-etree_get_next (ETreeModel *etm, ETreePath *node)
-{
- g_return_val_if_fail (node, NULL);
-
- return node->next_sibling;
-}
-
-static ETreePath*
-etree_get_prev (ETreeModel *etm, ETreePath *node)
-{
- g_return_val_if_fail (node, NULL);
-
- return node->prev_sibling;
-}
-
-static ETreePath*
-etree_get_first_child (ETreeModel *etm, ETreePath *node)
-{
- g_return_val_if_fail (node, NULL);
-
- return node->first_child;
-}
-
-static ETreePath*
-etree_get_last_child (ETreeModel *etm, ETreePath *node)
-{
- g_return_val_if_fail (node, NULL);
-
- return node->last_child;
-}
-
-static guint
-etree_get_children (ETreeModel *etm, ETreePath* node, ETreePath ***paths)
-{
- guint n_children;
-
- g_return_val_if_fail (node, 0);
-
- n_children = node->num_children;
-
- if (paths) {
- ETreePath *p;
- int i = 0;
- (*paths) = g_malloc (sizeof (ETreePath*) * n_children);
- for (p = node->first_child; p; p = p->next_sibling) {
- (*paths)[i++] = p;
- }
- }
-
- return n_children;
-}
-
-static gboolean
-etree_is_expanded (ETreeModel *etm, ETreePath* node)
-{
- g_return_val_if_fail (node, FALSE);
-
- return node->expanded;
-}
-
-static gboolean
-etree_is_visible (ETreeModel *etm, ETreePath* node)
-{
- g_return_val_if_fail (node, FALSE);
-
- for (node = node->parent; node; node = node->parent) {
- if (!node->expanded)
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-etree_set_expanded (ETreeModel *etm, ETreePath* node, gboolean expanded)
-{
- ETreeModelPriv *priv = etm->priv;
- ETreePath *child;
- int row;
-
- g_return_if_fail (node);
-
- node->expanded_set = TRUE;
-
- if (node->expanded == expanded)
- return;
-
- if (expanded) {
- gboolean allow_expand = TRUE;
- e_tree_model_node_expanded (etm, node, &allow_expand);
- if (!allow_expand)
- return;
- }
-
- node->expanded = expanded;
- if (node->save_id) {
- g_hash_table_insert (priv->expanded_state, node->save_id, (gpointer)expanded);
- }
-
- /* if the node wasn't visible at present */
- if ((row = e_tree_model_row_of_node (etm, node)) == -1) {
- if (!expanded) {
- e_tree_model_node_collapsed (etm, node);
- }
- return;
- }
-
- row++;
-
- if (expanded) {
- ETreePath *parent;
-
- if (e_tree_model_node_is_visible (etm, node)) {
- node->visible_descendents = 0;
- for (child = node->first_child; child;
- child = child->next_sibling) {
- add_visible_descendents_to_array (etm, child, &row, &node->visible_descendents);
- }
- }
- /* now iterate back up the tree, adding to our
- ancestors' visible descendents */
-
- for (parent = node->parent; parent; parent = parent->parent) {
- parent->visible_descendents += node->visible_descendents;
- }
- }
- else {
- int i;
- ETreePath *parent;
-
- if (e_tree_model_node_is_visible (etm, node)) {
- for (i = 0; i < node->visible_descendents; i ++) {
- priv->row_array = g_array_remove_index (priv->row_array, row);
- e_table_model_row_deleted (E_TABLE_MODEL (etm), row);
- }
- }
- /* now iterate back up the tree, subtracting from our
- ancestors' visible descendents */
-
- for (parent = node->parent; parent; parent = parent->parent) {
- parent->visible_descendents -= node->visible_descendents;
- }
-
- node->visible_descendents = 0;
-
- e_tree_model_node_collapsed (etm, node);
- }
-}
-
-/**
- * e_tree_model_set_expanded_default:
- * @etree: The ETreeModel we're setting the default expanded behavior on.
- * @expanded: Whether or not newly inserted parent nodes should be expanded by default.
- *
- *
- **/
-void
-e_tree_model_show_node (ETreeModel *etm, ETreePath* node)
-{
- ETreePath *parent;
-
- parent = e_tree_model_node_get_parent(etm, node);
- if (parent) {
- e_tree_model_show_node(etm, parent);
- e_tree_model_node_set_expanded(etm, parent, TRUE);
- }
-}
-
-void
-e_tree_model_set_expanded_default (ETreeModel *etree,
- gboolean expanded)
-{
- ETreeModelPriv *priv = etree->priv;
-
- priv->expanded_default = expanded;
-}
-
-/* fairly naive implementation */
-static void
-etree_set_expanded_recurse (ETreeModel *etm, ETreePath* node, gboolean expanded)
-{
- ETreePath *child;
-
- e_tree_model_node_set_expanded (etm, node, expanded);
-
- for (child = node->first_child; child; child = child->next_sibling)
- e_tree_model_node_set_expanded_recurse (etm, child, expanded);
-}
-
-static ETreePath *
-etree_node_at_row (ETreeModel *etree, int row)
-{
- ETreeModelPriv *priv = etree->priv;
-
- g_return_val_if_fail (row < priv->row_array->len, NULL);
-
- return g_array_index (priv->row_array, ETreePath*, row);
-}
-
-
-/* ETable analogs */
-static void*
-etree_value_at (ETreeModel *etm, ETreePath* node, int col)
-{
- /* shouldn't be called */
- g_assert (0);
- return NULL;
-}
-
-static GdkPixbuf*
-etree_icon_at (ETreeModel *etm, ETreePath* node)
-{
- /* shouldn't be called */
- g_assert (0);
- return NULL;
-}
-
-static void
-etree_set_value_at (ETreeModel *etm, ETreePath* node, int col, const void *val)
-{
- /* shouldn't be called */
- g_assert (0);
-}
-
-static gboolean
-etree_is_editable (ETreeModel *etm, ETreePath* node, int col)
-{
- /* shouldn't be called */
- g_assert(0);
- return FALSE;
-}
-
-
-/* ETable virtual functions we map */
-static int
-etable_row_count (ETableModel *etm)
-{
- ETreeModel *tree = E_TREE_MODEL (etm);
- ETreeModelPriv *priv = tree->priv;
- return priv->row_array->len;
-}
-
-static void *
-etable_value_at (ETableModel *etm, int col, int row)
-{
- ETreeModel *etree = E_TREE_MODEL(etm);
- ETreeModelClass *et_class = ETM_CLASS(etm);
- ETreePath* node = e_tree_model_node_at_row (etree, row);
-
- if (node == NULL)
- g_warning ("node is NULL for row %d in etable_value_at\n", row);
-
- if (col == -1)
- return node;
- else if (col == -2)
- return etm;
- else
- return et_class->value_at (etree, node, col);
-}
-
-static void
-etable_set_value_at (ETableModel *etm, int col, int row, const void *val)
-{
- ETreeModel *etree = E_TREE_MODEL(etm);
- ETreeModelClass *et_class = ETM_CLASS(etm);
- ETreePath* node = e_tree_model_node_at_row (etree, row);
-
- g_return_if_fail (node);
-
- et_class->set_value_at (etree, node, col, val);
-}
-
-static gboolean
-etable_is_cell_editable (ETableModel *etm, int col, int row)
-{
- ETreeModel *etree = E_TREE_MODEL(etm);
- ETreeModelClass *et_class = ETM_CLASS(etm);
- ETreePath* node = e_tree_model_node_at_row (etree, row);
-
- g_return_val_if_fail (node, FALSE);
-
- return et_class->is_editable (etree, node, col);
-}
-
-static void
-build_sort_group(GString *out, ETreePath *node)
-{
- if (node->parent) {
- build_sort_group(out, node->parent);
- }
- g_string_sprintfa(out, "/%p", node);
-}
-
-static const char *
-etable_row_sort_group(ETableModel *etm, int row)
-{
- ETreeModel *etree = E_TREE_MODEL(etm);
- ETreeModelPriv *priv = etree->priv;
- ETreePath* node = e_tree_model_node_at_row (etree, row);
-
- g_return_val_if_fail (node, "");
-
- g_string_truncate(priv->sort_group, 0);
- if (node)
- build_sort_group(priv->sort_group, node);
-
- return priv->sort_group->str;
-}
-
-static gboolean
-etable_has_sort_group(ETableModel *etm)
-{
- /* could optimise for the flat &/or unexpanded tree case */
- return TRUE;
-}
-
static void
e_tree_model_class_init (GtkObjectClass *klass)
{
- ETableModelClass *table_class = (ETableModelClass *) klass;
ETreeModelClass *tree_class = (ETreeModelClass *) klass;
- e_tree_model_parent_class = gtk_type_class (PARENT_TYPE);
-
- klass->destroy = etree_destroy;
+ parent_class = gtk_type_class (PARENT_TYPE);
+
+ e_tree_model_signals [PRE_CHANGE] =
+ gtk_signal_new ("pre_change",
+ GTK_RUN_LAST,
+ klass->type,
+ GTK_SIGNAL_OFFSET (ETreeModelClass, pre_change),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
e_tree_model_signals [NODE_CHANGED] =
gtk_signal_new ("node_changed",
@@ -596,6 +68,22 @@ e_tree_model_class_init (GtkObjectClass *klass)
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+ e_tree_model_signals [NODE_DATA_CHANGED] =
+ gtk_signal_new ("node_data_changed",
+ GTK_RUN_LAST,
+ klass->type,
+ GTK_SIGNAL_OFFSET (ETreeModelClass, node_data_changed),
+ gtk_marshal_NONE__POINTER,
+ GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+
+ e_tree_model_signals [NODE_COL_CHANGED] =
+ gtk_signal_new ("node_col_changed",
+ GTK_RUN_LAST,
+ klass->type,
+ GTK_SIGNAL_OFFSET (ETreeModelClass, node_col_changed),
+ gtk_marshal_NONE__POINTER_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_INT);
+
e_tree_model_signals [NODE_INSERTED] =
gtk_signal_new ("node_inserted",
GTK_RUN_LAST,
@@ -612,66 +100,50 @@ e_tree_model_class_init (GtkObjectClass *klass)
gtk_marshal_NONE__POINTER_POINTER,
GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
- e_tree_model_signals [NODE_COLLAPSED] =
- gtk_signal_new ("node_collapsed",
- GTK_RUN_LAST,
- klass->type,
- GTK_SIGNAL_OFFSET (ETreeModelClass, node_collapsed),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+ gtk_object_class_add_signals (klass, e_tree_model_signals, LAST_SIGNAL);
- e_tree_model_signals [NODE_EXPANDED] =
- gtk_signal_new ("node_expanded",
- GTK_RUN_LAST,
- klass->type,
- GTK_SIGNAL_OFFSET (ETreeModelClass, node_expanded),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
+ tree_class->get_root = NULL;
- gtk_object_class_add_signals (klass, e_tree_model_signals, LAST_SIGNAL);
+ tree_class->get_parent = NULL;
+ tree_class->get_first_child = NULL;
+ tree_class->get_last_child = NULL;
+ tree_class->get_next = NULL;
+ tree_class->get_prev = NULL;
+
+ tree_class->is_root = NULL;
+ tree_class->is_expandable = NULL;
+ tree_class->get_children = NULL;
+ tree_class->depth = NULL;
+
+ tree_class->icon_at = NULL;
+
+ tree_class->get_expanded_default = NULL;
+ tree_class->column_count = NULL;
- table_class->row_count = etable_row_count;
- table_class->value_at = etable_value_at;
- table_class->set_value_at = etable_set_value_at;
- table_class->is_cell_editable = etable_is_cell_editable;
-#if 0
- /* XX need to pass these through */
- table_class->duplicate_value = etable_duplicate_value;
- table_class->free_value = etable_free_value;
- table_class->initialize_value = etable_initialize_value;
- table_class->value_is_empty = etable_value_is_empty;
- table_class->value_to_string = etable_value_to_string;
- table_class->thaw = etable_thaw;
-#endif
-
- table_class->row_sort_group = etable_row_sort_group;
- table_class->has_sort_group = etable_has_sort_group;
-
- tree_class->get_root = etree_get_root;
- tree_class->get_prev = etree_get_prev;
- tree_class->get_next = etree_get_next;
- tree_class->get_first_child = etree_get_first_child;
- tree_class->get_last_child = etree_get_last_child;
- tree_class->get_parent = etree_get_parent;
-
- tree_class->value_at = etree_value_at;
- tree_class->icon_at = etree_icon_at;
- tree_class->set_value_at = etree_set_value_at;
- tree_class->is_editable = etree_is_editable;
-
- tree_class->get_children = etree_get_children;
- tree_class->is_expanded = etree_is_expanded;
- tree_class->is_visible = etree_is_visible;
- tree_class->set_expanded = etree_set_expanded;
- tree_class->set_expanded_recurse = etree_set_expanded_recurse;
- tree_class->node_at_row = etree_node_at_row;
+ tree_class->has_save_id = NULL;
+ tree_class->get_save_id = NULL;
+
+ tree_class->value_at = NULL;
+ tree_class->set_value_at = NULL;
+ tree_class->is_editable = NULL;
+
+ tree_class->duplicate_value = NULL;
+ tree_class->free_value = NULL;
+ tree_class->initialize_value = NULL;
+ tree_class->value_is_empty = NULL;
+ tree_class->value_to_string = NULL;
+
+ tree_class->pre_change = NULL;
+ tree_class->node_changed = NULL;
+ tree_class->node_data_changed = NULL;
+ tree_class->node_col_changed = NULL;
+ tree_class->node_inserted = NULL;
+ tree_class->node_removed = NULL;
}
static void
e_tree_init (GtkObject *object)
{
- ETreeModel *etree = (ETreeModel *)object;
- e_tree_model_construct (etree);
}
E_MAKE_TYPE(e_tree_model, "ETreeModel", ETreeModel, e_tree_model_class_init, e_tree_init, PARENT_TYPE)
@@ -689,136 +161,114 @@ E_MAKE_TYPE(e_tree_model, "ETreeModel", ETreeModel, e_tree_model_class_init, e_t
* Return value:
**/
void
-e_tree_model_node_changed (ETreeModel *tree_model, ETreePath *node)
+e_tree_model_pre_change (ETreeModel *tree_model)
{
- int row;
g_return_if_fail (tree_model != NULL);
g_return_if_fail (E_IS_TREE_MODEL (tree_model));
- row = e_tree_model_row_of_node (tree_model, node);
- if (row != -1)
- e_table_model_row_changed (E_TABLE_MODEL (tree_model), row);
-
gtk_signal_emit (GTK_OBJECT (tree_model),
- e_tree_model_signals [NODE_CHANGED], node);
+ e_tree_model_signals [PRE_CHANGE]);
}
/**
- * e_tree_model_node_inserted:
+ * e_tree_model_node_changed:
* @tree_model:
- * @parent_node:
- * @inserted_node:
+ * @node:
*
*
+ *
+ * Return value:
**/
void
-e_tree_model_node_inserted (ETreeModel *tree_model,
- ETreePath *parent_node,
- ETreePath *inserted_node)
+e_tree_model_node_changed (ETreeModel *tree_model, ETreePath node)
{
- int row;
g_return_if_fail (tree_model != NULL);
g_return_if_fail (E_IS_TREE_MODEL (tree_model));
-
- row = e_tree_model_row_of_node (tree_model, inserted_node);
- if (row != -1)
- e_table_model_row_inserted (E_TABLE_MODEL (tree_model), row);
gtk_signal_emit (GTK_OBJECT (tree_model),
- e_tree_model_signals [NODE_INSERTED],
- parent_node, inserted_node);
+ e_tree_model_signals [NODE_CHANGED], node);
}
/**
- * e_tree_model_node_removed:
+ * e_tree_model_node_data_changed:
* @tree_model:
- * @parent_node:
- * @removed_node:
+ * @node:
+ *
*
*
+ * Return value:
**/
void
-e_tree_model_node_removed (ETreeModel *tree_model, ETreePath *parent_node, ETreePath *removed_node)
+e_tree_model_node_data_changed (ETreeModel *tree_model, ETreePath node)
{
- int row;
-
g_return_if_fail (tree_model != NULL);
g_return_if_fail (E_IS_TREE_MODEL (tree_model));
-
- row = e_tree_model_row_of_node (tree_model, removed_node);
- if (row != -1)
- e_table_model_row_deleted (E_TABLE_MODEL (tree_model), row);
gtk_signal_emit (GTK_OBJECT (tree_model),
- e_tree_model_signals [NODE_REMOVED],
- parent_node, removed_node);
+ e_tree_model_signals [NODE_DATA_CHANGED], node);
}
/**
- * e_tree_model_node_collapsed:
+ * e_tree_model_node_col_changed:
* @tree_model:
* @node:
*
*
+ *
+ * Return value:
**/
void
-e_tree_model_node_collapsed (ETreeModel *tree_model, ETreePath *node)
+e_tree_model_node_col_changed (ETreeModel *tree_model, ETreePath node, int col)
{
g_return_if_fail (tree_model != NULL);
g_return_if_fail (E_IS_TREE_MODEL (tree_model));
gtk_signal_emit (GTK_OBJECT (tree_model),
- e_tree_model_signals [NODE_COLLAPSED],
- node);
+ e_tree_model_signals [NODE_COL_CHANGED], node, col);
}
/**
- * e_tree_model_node_expanded:
+ * e_tree_model_node_inserted:
* @tree_model:
- * @node:
- * @allow_expand:
+ * @parent_node:
+ * @inserted_node:
*
*
**/
void
-e_tree_model_node_expanded (ETreeModel *tree_model, ETreePath *node, gboolean *allow_expand)
+e_tree_model_node_inserted (ETreeModel *tree_model,
+ ETreePath parent_node,
+ ETreePath inserted_node)
{
g_return_if_fail (tree_model != NULL);
g_return_if_fail (E_IS_TREE_MODEL (tree_model));
-
+
gtk_signal_emit (GTK_OBJECT (tree_model),
- e_tree_model_signals [NODE_EXPANDED],
- node, allow_expand);
+ e_tree_model_signals [NODE_INSERTED],
+ parent_node, inserted_node);
}
-
-
/**
- * e_tree_model_construct:
- * @etree:
+ * e_tree_model_node_removed:
+ * @tree_model:
+ * @parent_node:
+ * @removed_node:
*
*
**/
void
-e_tree_model_construct (ETreeModel *etree)
+e_tree_model_node_removed (ETreeModel *tree_model, ETreePath parent_node, ETreePath removed_node)
{
- ETreeModelPriv *priv;
-
- g_return_if_fail (etree != NULL);
- g_return_if_fail (E_IS_TREE_MODEL (etree));
-
- priv = g_new0 (ETreeModelPriv, 1);
- etree->priv = priv;
-
- priv->node_chunk = g_mem_chunk_create (ETreePath, TREEPATH_CHUNK_AREA_SIZE, G_ALLOC_AND_FREE);
- priv->root = NULL;
- priv->root_visible = TRUE;
- priv->row_array = g_array_new (FALSE, FALSE, sizeof(ETreePath*));
- priv->expanded_state = g_hash_table_new (g_str_hash, g_str_equal);
- priv->sort_group = g_string_new("");
- priv->frozen = 0;
+ g_return_if_fail (tree_model != NULL);
+ g_return_if_fail (E_IS_TREE_MODEL (tree_model));
+
+ gtk_signal_emit (GTK_OBJECT (tree_model),
+ e_tree_model_signals [NODE_REMOVED],
+ parent_node, removed_node);
}
+
+
/**
* e_tree_model_new
*
@@ -844,124 +294,35 @@ e_tree_model_new ()
*
* return values: the ETreePath corresponding to the root node.
*/
-ETreePath *
+ETreePath
e_tree_model_get_root (ETreeModel *etree)
{
g_return_val_if_fail (etree != NULL, NULL);
g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
- return ETM_CLASS(etree)->get_root(etree);
-}
-
-/**
- * e_tree_model_node_at_row
- * @etree: the ETreeModel.
- * @row:
- *
- * XXX docs here.
- *
- * return values: the ETreePath corresponding to @row.
- */
-ETreePath *
-e_tree_model_node_at_row (ETreeModel *etree, int row)
-{
- g_return_val_if_fail (etree != NULL, NULL);
- g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
-
- return ETM_CLASS(etree)->node_at_row (etree, row);
-}
-
-/**
- * e_tree_model_icon_of_node
- * @etree: The ETreeModel.
- * @path: The ETreePath to the node we're getting the icon of.
- *
- * XXX docs here.
- *
- * return values: the GdkPixbuf associated with this node.
- */
-GdkPixbuf *
-e_tree_model_icon_of_node (ETreeModel *etree, ETreePath *path)
-{
- g_return_val_if_fail (etree != NULL, NULL);
- g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
-
- return ETM_CLASS(etree)->icon_at (etree, path);
-}
-
-/**
- * e_tree_model_row_of_node
- * @etree: The ETreeModel.
- * @node: The node whose row we're looking up.
- *
- * return values: an int.
- */
-int
-e_tree_model_row_of_node (ETreeModel *etree, ETreePath *node)
-{
- ETreeModelPriv *priv;
- int i;
-
- g_return_val_if_fail (etree != NULL, 0);
- g_return_val_if_fail (E_IS_TREE_MODEL (etree), 0);
-
- priv = etree->priv;
- for (i = 0; i < priv->row_array->len; i ++)
- if (g_array_index (priv->row_array, ETreePath*, i) == node)
- return i;
-
- return -1;
-}
-
-/**
- * e_tree_model_root_node_set_visible
- *
- * return values: none
- */
-void
-e_tree_model_root_node_set_visible (ETreeModel *etm, gboolean visible)
-{
- ETreeModelPriv *priv;
-
- g_return_if_fail (etm != NULL);
- g_return_if_fail (E_IS_TREE_MODEL (etm));
-
- priv = etm->priv;
- if (visible != priv->root_visible) {
- priv->root_visible = visible;
- if (priv->root) {
- if (visible) {
- priv->row_array = g_array_insert_val (priv->row_array, 0, priv->root);
- }
- else {
- ETreePath *root_path = e_tree_model_get_root (etm);
- e_tree_model_node_set_expanded (etm, root_path, TRUE);
- priv->row_array = g_array_remove_index (priv->row_array, 0);
- }
-
- e_table_model_changed (E_TABLE_MODEL (etm));
- }
- }
+ if (ETM_CLASS(etree)->get_root)
+ return ETM_CLASS(etree)->get_root(etree);
+ else
+ return NULL;
}
/**
- * e_tree_model_root_node_is_visible:
- * @etm:
+ * e_tree_model_node_get_parent:
+ * @etree:
+ * @path:
*
*
*
* Return value:
**/
-gboolean
-e_tree_model_root_node_is_visible (ETreeModel *etm)
+ETreePath
+e_tree_model_node_get_parent (ETreeModel *etree, ETreePath node)
{
- ETreeModelPriv *priv;
-
- g_return_val_if_fail (etm != NULL, FALSE);
- g_return_val_if_fail (E_IS_TREE_MODEL (etm), FALSE);
-
- priv = etm->priv;
- return priv->root_visible;
+ g_return_val_if_fail(etree != NULL, NULL);
+ if (ETM_CLASS(etree)->get_parent)
+ return ETM_CLASS(etree)->get_parent(etree, node);
+ else
+ return NULL;
}
/**
@@ -973,13 +334,16 @@ e_tree_model_root_node_is_visible (ETreeModel *etm)
*
* Return value:
**/
-ETreePath *
-e_tree_model_node_get_first_child (ETreeModel *etree, ETreePath *node)
+ETreePath
+e_tree_model_node_get_first_child (ETreeModel *etree, ETreePath node)
{
g_return_val_if_fail (etree != NULL, NULL);
g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
- return ETM_CLASS(etree)->get_first_child(etree, node);
+ if (ETM_CLASS(etree)->get_first_child)
+ return ETM_CLASS(etree)->get_first_child(etree, node);
+ else
+ return NULL;
}
/**
@@ -991,13 +355,16 @@ e_tree_model_node_get_first_child (ETreeModel *etree, ETreePath *node)
*
* Return value:
**/
-ETreePath *
-e_tree_model_node_get_last_child (ETreeModel *etree, ETreePath *node)
+ETreePath
+e_tree_model_node_get_last_child (ETreeModel *etree, ETreePath node)
{
g_return_val_if_fail (etree != NULL, NULL);
g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
- return ETM_CLASS(etree)->get_last_child(etree, node);
+ if (ETM_CLASS(etree)->get_last_child)
+ return ETM_CLASS(etree)->get_last_child(etree, node);
+ else
+ return NULL;
}
@@ -1010,13 +377,16 @@ e_tree_model_node_get_last_child (ETreeModel *etree, ETreePath *node)
*
* Return value:
**/
-ETreePath *
-e_tree_model_node_get_next (ETreeModel *etree, ETreePath *node)
+ETreePath
+e_tree_model_node_get_next (ETreeModel *etree, ETreePath node)
{
g_return_val_if_fail (etree != NULL, NULL);
g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
- return ETM_CLASS(etree)->get_next(etree, node);
+ if (ETM_CLASS(etree)->get_next)
+ return ETM_CLASS(etree)->get_next(etree, node);
+ else
+ return NULL;
}
/**
@@ -1028,47 +398,16 @@ e_tree_model_node_get_next (ETreeModel *etree, ETreePath *node)
*
* Return value:
**/
-ETreePath *
-e_tree_model_node_get_prev (ETreeModel *etree, ETreePath *node)
+ETreePath
+e_tree_model_node_get_prev (ETreeModel *etree, ETreePath node)
{
g_return_val_if_fail (etree != NULL, NULL);
g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
- return ETM_CLASS(etree)->get_prev(etree, node);
-}
-
-/**
- * e_tree_model_node_depth:
- * @etree:
- * @path:
- *
- *
- *
- * Return value:
- **/
-guint
-e_tree_model_node_depth (ETreeModel *etree, ETreePath *path)
-{
- g_return_val_if_fail (etree != NULL, 0);
- g_return_val_if_fail (E_IS_TREE_MODEL (etree), 0);
-
- return e_tree_path_depth (path) - 1;
-}
-
-/**
- * e_tree_model_node_get_parent:
- * @etree:
- * @path:
- *
- *
- *
- * Return value:
- **/
-ETreePath *
-e_tree_model_node_get_parent (ETreeModel *etree, ETreePath *path)
-{
- g_return_val_if_fail(etree != NULL, NULL);
- return ETM_CLASS(etree)->get_parent(etree, path);
+ if (ETM_CLASS(etree)->get_prev)
+ return ETM_CLASS(etree)->get_prev(etree, node);
+ else
+ return NULL;
}
/**
@@ -1081,10 +420,14 @@ e_tree_model_node_get_parent (ETreeModel *etree, ETreePath *path)
* Return value:
**/
gboolean
-e_tree_model_node_is_root (ETreeModel *etree, ETreePath *path)
+e_tree_model_node_is_root (ETreeModel *etree, ETreePath node)
{
g_return_val_if_fail(etree != NULL, FALSE);
- return (e_tree_model_node_depth (etree, path) == 0);
+
+ if (ETM_CLASS(etree)->is_root)
+ return ETM_CLASS(etree)->is_root(etree, node);
+ else
+ return FALSE;
}
/**
@@ -1097,30 +440,28 @@ e_tree_model_node_is_root (ETreeModel *etree, ETreePath *path)
* Return value:
**/
gboolean
-e_tree_model_node_is_expandable (ETreeModel *etree, ETreePath *path)
+e_tree_model_node_is_expandable (ETreeModel *etree, ETreePath node)
{
g_return_val_if_fail(etree != NULL, FALSE);
- return (e_tree_model_node_get_children (etree, path, NULL) > 0);
+
+ if (ETM_CLASS(etree)->is_expandable)
+ return ETM_CLASS(etree)->is_expandable(etree, node);
+ else
+ return FALSE;
}
-/**
- * e_tree_model_node_is_expanded:
- * @etree:
- * @path:
- *
- *
- *
- * Return value:
- **/
-gboolean
-e_tree_model_node_is_expanded (ETreeModel *etree, ETreePath *path)
+guint
+e_tree_model_node_get_children (ETreeModel *etree, ETreePath node, ETreePath **nodes)
{
- g_return_val_if_fail(etree != NULL, FALSE);
- return ETM_CLASS(etree)->is_expanded (etree, path);
+ g_return_val_if_fail(etree != NULL, 0);
+ if (ETM_CLASS(etree)->get_children)
+ return ETM_CLASS(etree)->get_children (etree, node, nodes);
+ else
+ return 0;
}
/**
- * e_tree_model_node_is_visible:
+ * e_tree_model_node_depth:
* @etree:
* @path:
*
@@ -1128,290 +469,182 @@ e_tree_model_node_is_expanded (ETreeModel *etree, ETreePath *path)
*
* Return value:
**/
-gboolean
-e_tree_model_node_is_visible (ETreeModel *etree, ETreePath *path)
+guint
+e_tree_model_node_depth (ETreeModel *etree, ETreePath node)
{
- g_return_val_if_fail(etree != NULL, FALSE);
- return ETM_CLASS(etree)->is_visible (etree, path);
+ g_return_val_if_fail (etree != NULL, 0);
+ g_return_val_if_fail (E_IS_TREE_MODEL (etree), 0);
+
+ if (ETM_CLASS(etree)->depth)
+ return ETM_CLASS(etree)->depth(etree, node);
+ else
+ return 0;
}
/**
- * e_tree_model_node_set_expanded:
- * @etree:
- * @path:
- * @expanded:
- *
- *
- **/
-void
-e_tree_model_node_set_expanded (ETreeModel *etree, ETreePath *path, gboolean expanded)
+ * e_tree_model_icon_at
+ * @etree: The ETreeModel.
+ * @path: The ETreePath to the node we're getting the icon of.
+ *
+ * XXX docs here.
+ *
+ * return values: the GdkPixbuf associated with this node.
+ */
+GdkPixbuf *
+e_tree_model_icon_at (ETreeModel *etree, ETreePath node)
{
- g_return_if_fail(etree != NULL);
- ETM_CLASS(etree)->set_expanded (etree, path, expanded);
+ g_return_val_if_fail (etree != NULL, NULL);
+ g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
+
+ if (ETM_CLASS(etree)->icon_at)
+ return ETM_CLASS(etree)->icon_at (etree, node);
+ else
+ return NULL;
}
/**
- * e_tree_model_node_set_expanded_recurse:
- * @etree:
- * @path:
- * @expanded:
- *
- *
- **/
-void
-e_tree_model_node_set_expanded_recurse (ETreeModel *etree, ETreePath *path, gboolean expanded)
+ * e_tree_model_get_expanded_default
+ * @etree: The ETreeModel.
+ *
+ * XXX docs here.
+ *
+ * return values: Whether nodes should be expanded by default.
+ */
+gboolean
+e_tree_model_get_expanded_default (ETreeModel *etree)
{
- g_return_if_fail(etree != NULL);
- ETM_CLASS(etree)->set_expanded_recurse (etree, path, expanded);
-}
+ g_return_val_if_fail (etree != NULL, FALSE);
+ g_return_val_if_fail (E_IS_TREE_MODEL (etree), FALSE);
-guint
-e_tree_model_node_get_children (ETreeModel *etree, ETreePath *path, ETreePath ***paths)
-{
- g_return_val_if_fail(etree != NULL, 0);
- return ETM_CLASS(etree)->get_children (etree, path, paths);
+ if (ETM_CLASS(etree)->get_expanded_default)
+ return ETM_CLASS(etree)->get_expanded_default (etree);
+ else
+ return FALSE;
}
/**
- * e_tree_model_node_num_visible_descendents:
- * @etm:
- * @node:
- *
- *
- *
- * Return value:
- **/
-guint
-e_tree_model_node_num_visible_descendents (ETreeModel *etm, ETreePath *node)
+ * e_tree_model_column_count
+ * @etree: The ETreeModel.
+ *
+ * XXX docs here.
+ *
+ * return values: The number of columns
+ */
+gint
+e_tree_model_column_count (ETreeModel *etree)
{
- g_return_val_if_fail(node != NULL, 0);
- return node->visible_descendents;
+ g_return_val_if_fail (etree != NULL, 0);
+ g_return_val_if_fail (E_IS_TREE_MODEL (etree), 0);
+
+ if (ETM_CLASS(etree)->column_count)
+ return ETM_CLASS(etree)->column_count (etree);
+ else
+ return 0;
}
/**
- * e_tree_model_node_get_data:
- * @etm:
- * @node:
- *
- *
- *
- * Return value:
- **/
-gpointer
-e_tree_model_node_get_data (ETreeModel *etm, ETreePath *node)
+ * e_tree_model_has_save_id
+ * @etree: The ETreeModel.
+ *
+ * XXX docs here.
+ *
+ * return values: Whether this tree has valid save id data.
+ */
+gboolean
+e_tree_model_has_save_id (ETreeModel *etree)
{
- g_return_val_if_fail (node, NULL);
+ g_return_val_if_fail (etree != NULL, FALSE);
+ g_return_val_if_fail (E_IS_TREE_MODEL (etree), FALSE);
- return node->node_data;
+ if (ETM_CLASS(etree)->has_save_id)
+ return ETM_CLASS(etree)->has_save_id (etree);
+ else
+ return FALSE;
}
/**
- * e_tree_model_node_set_data:
- * @etm:
- * @node:
- * @node_data:
- *
- *
- **/
-void
-e_tree_model_node_set_data (ETreeModel *etm, ETreePath *node, gpointer node_data)
+ * e_tree_model_get_save_id
+ * @etree: The ETreeModel.
+ * @node: The ETreePath.
+ *
+ * XXX docs here.
+ *
+ * return values: The save id for this path.
+ */
+gchar *
+e_tree_model_get_save_id (ETreeModel *etree, ETreePath node)
{
- g_return_if_fail (node);
+ g_return_val_if_fail (etree != NULL, NULL);
+ g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
- node->node_data = node_data;
+ if (ETM_CLASS(etree)->get_save_id)
+ return ETM_CLASS(etree)->get_save_id (etree, node);
+ else
+ return NULL;
}
/**
- * e_tree_model_node_insert:
- * @tree_model:
- * @parent_path:
- * @position:
- * @node_data:
- *
- *
- *
- * Return value:
- **/
-ETreePath*
-e_tree_model_node_insert (ETreeModel *tree_model,
- ETreePath *parent_path,
- int position,
- gpointer node_data)
+ * e_tree_model_icon_of_node
+ * @etree: The ETreeModel.
+ * @path: The ETreePath to the node we're getting the icon of.
+ *
+ * XXX docs here.
+ *
+ * return values: the GdkPixbuf associated with this node.
+ */
+void *
+e_tree_model_value_at (ETreeModel *etree, ETreePath node, int col)
{
- ETreeModelPriv *priv;
- ETreePath *new_path;
-
- g_return_val_if_fail(tree_model != NULL, NULL);
-
- priv = tree_model->priv;
-
- g_return_val_if_fail (parent_path != NULL || priv->root == NULL, NULL);
-
- priv = tree_model->priv;
-
- new_path = g_chunk_new0 (ETreePath, priv->node_chunk);
-
- new_path->expanded = FALSE;
- new_path->node_data = node_data;
-
- if (parent_path != NULL) {
-
- if (parent_path->first_child == NULL
- && !parent_path->expanded_set) {
- e_tree_model_node_set_expanded (tree_model,
- parent_path,
- priv->expanded_default);
- }
-
- e_tree_path_insert (parent_path, position, new_path);
-
- if (e_tree_model_node_is_visible (tree_model, new_path)) {
- int parent_row, child_offset = 0;
- ETreePath *n;
-
- /* we need to iterate back up to the root, incrementing the number of visible
- descendents */
- for (n = parent_path; n; n = n->parent) {
- n->visible_descendents ++;
- }
-
- /* determine if we are inserting at the end of this parent */
- if (position == -1 || position == parent_path->num_children) {
- position = e_tree_model_node_num_visible_descendents (tree_model, parent_path) - 1;
- } else {
- /* if we're not inserting at the end of the array, position is the child node we're
- inserting at, not the absolute row position - need to count expanded nodes before it too */
- int i = position;
-
- n = e_tree_model_node_get_first_child(tree_model, parent_path);
- while (n != NULL && i > 0) {
- child_offset += n->visible_descendents;
- n = n->next_sibling;
- i--;
- }
- }
-
-
- /* if the parent is the root, no need to search for its position since it aint there */
- if (parent_path->parent == NULL) {
- parent_row = -1;
- } else {
- parent_row = e_tree_model_row_of_node (tree_model, parent_path);
- }
-
- e_table_model_pre_change(E_TABLE_MODEL(tree_model));
-
- priv->row_array = g_array_insert_val (priv->row_array,
- parent_row + position + 1 + child_offset, new_path);
-
- /* only do this if we know a changed signal isn't coming later on */
- if (priv->frozen == 0)
- e_table_model_row_inserted (E_TABLE_MODEL(tree_model), parent_row + position + 1 + child_offset);
- }
-
- if (parent_path->compare)
- e_tree_model_node_sort (tree_model, parent_path);
- }
- else {
- priv->root = new_path;
- if (priv->root_visible) {
- priv->row_array = g_array_insert_val (priv->row_array, 0, priv->root);
- e_table_model_row_inserted (E_TABLE_MODEL (tree_model), 0);
- }
- else {
- /* need to mark the new node as expanded or
- we'll never see it's children */
- new_path->expanded = TRUE;
- new_path->expanded_set = TRUE;
- }
- }
-
- return new_path;
+ g_return_val_if_fail (etree != NULL, NULL);
+ g_return_val_if_fail (E_IS_TREE_MODEL (etree), NULL);
+
+ if (ETM_CLASS(etree)->value_at)
+ return ETM_CLASS(etree)->value_at (etree, node, col);
+ else
+ return NULL;
}
/**
- * e_tree_model_node_insert_id:
- * @tree_model:
- * @parent_path:
- * @position:
- * @node_data:
- * @save_id:
- *
- *
- *
- * Return value:
- **/
-ETreePath*
-e_tree_model_node_insert_id (ETreeModel *tree_model,
- ETreePath *parent_path,
- int position,
- gpointer node_data,
- const char *save_id)
+ * e_tree_model_icon_of_node
+ * @etree: The ETreeModel.
+ * @path: The ETreePath to the node we're getting the icon of.
+ *
+ * XXX docs here.
+ *
+ * return values: the GdkPixbuf associated with this node.
+ */
+void
+e_tree_model_set_value_at (ETreeModel *etree, ETreePath node, int col, const void *val)
{
- ETreePath *path;
-
- g_return_val_if_fail(tree_model != NULL, NULL);
-
- path = e_tree_model_node_insert (tree_model, parent_path, position, node_data);
-
- e_tree_model_node_set_save_id (tree_model, path, save_id);
+ g_return_if_fail (etree != NULL);
+ g_return_if_fail (E_IS_TREE_MODEL (etree));
- return path;
+ if (ETM_CLASS(etree)->set_value_at)
+ ETM_CLASS(etree)->set_value_at (etree, node, col, val);
}
/**
- * e_tree_model_node_insert_before:
+ * e_tree_model_node_is_editable:
* @etree:
- * @parent:
- * @sibling:
- * @node_data:
+ * @path:
*
*
*
* Return value:
**/
-ETreePath *
-e_tree_model_node_insert_before (ETreeModel *etree,
- ETreePath *parent,
- ETreePath *sibling,
- gpointer node_data)
+gboolean
+e_tree_model_node_is_editable (ETreeModel *etree, ETreePath node, int col)
{
- ETreePath *child;
- int position = 0;
-
- g_return_val_if_fail(etree != NULL, NULL);
-
- for (child = parent->first_child; child; child = child->next_sibling) {
- if (child == sibling)
- break;
- position ++;
- }
- return e_tree_model_node_insert (etree, parent, position, node_data);
-}
+ g_return_val_if_fail(etree != NULL, FALSE);
-/* just blows away child data, doesn't take into account unlinking/etc */
-static void
-child_free(ETreeModel *etree, ETreePath *node)
-{
- ETreePath *child, *next;
- ETreeModelPriv *priv = etree->priv;
-
- child = node->first_child;
- while (child) {
- next = child->next_sibling;
- child_free(etree, child);
- child = next;
- }
-
- if (node->save_id) {
- g_hash_table_remove(priv->expanded_state, node->save_id);
- g_free(node->save_id);
- }
- g_chunk_free(node, priv->node_chunk);
+ if (ETM_CLASS(etree)->is_editable)
+ return ETM_CLASS(etree)->is_editable(etree, node, col);
+ else
+ return FALSE;
}
/**
- * e_tree_model_node_remove:
+ * e_tree_model_duplicate_value:
* @etree:
* @path:
*
@@ -1419,393 +652,91 @@ child_free(ETreeModel *etree, ETreePath *node)
*
* Return value:
**/
-gpointer
-e_tree_model_node_remove (ETreeModel *etree, ETreePath *path)
+void *
+e_tree_model_duplicate_value (ETreeModel *etree, int col, const void *value)
{
- ETreeModelPriv *priv = etree->priv;
- ETreePath *parent = path->parent;
- gpointer ret = path->node_data;
- int row, visible = 0, base = 0;
- gboolean dochanged;
-
g_return_val_if_fail(etree != NULL, NULL);
- /* work out what range of visible rows to remove */
- if (parent) {
- if (e_tree_model_node_is_visible(etree, path)) {
- base = e_tree_model_row_of_node(etree, path);
- visible = path->visible_descendents + 1;
- }
- } else if (path == priv->root) {
- priv->root = NULL;
- if (priv->root_visible) {
- base = 0;
- visible = path->visible_descendents + 1;
- } else {
- base = 0;
- visible = path->visible_descendents;
- }
- } else {
- g_warning("Trying to remove invalid path %p", path);
+ if (ETM_CLASS(etree)->duplicate_value)
+ return ETM_CLASS(etree)->duplicate_value(etree, col, value);
+ else
return NULL;
- }
-
- /* unlink this node - we only have to unlink the root node being removed,
- since the others are only references from this node */
- e_tree_path_unlink (path);
-
- /*printf("removing %d nodes from position %d\n", visible, base);*/
-
- if (visible > 0) {
- /* fix up the parent visible counts */
- for (; parent; parent = parent->parent) {
- parent->visible_descendents -= visible;
- }
-
- /* if we have a lot of nodes to remove, then we dont row_deleted each one */
- /* could probably be tuned, but this'll do, since its normally only when we
- remove the whole lot do we really care */
- dochanged = (visible > 1000) || (visible > (priv->row_array->len / 4));
-
- e_table_model_pre_change(E_TABLE_MODEL (etree));
-
- /* and physically remove them */
- if (visible == priv->row_array->len) {
- g_array_set_size(priv->row_array, 0);
- } else {
- memmove(&g_array_index(priv->row_array, ETreePath *, base),
- &g_array_index(priv->row_array, ETreePath *, base+visible),
- (priv->row_array->len - (base+visible)) * sizeof(ETreePath *));
- g_array_set_size(priv->row_array, priv->row_array->len - visible);
- }
-
- /* tell the system we've removed (these) nodes */
- if (priv->frozen == 0) {
- if (dochanged) {
- e_table_model_changed(E_TABLE_MODEL(etree));
- } else {
- for (row=visible-1;row>=0;row--) {
- e_table_model_row_deleted(E_TABLE_MODEL(etree), row+base);
- }
- }
- }
- }
-
- child_free(etree, path);
-
- return ret;
-}
-
-static void
-add_visible_descendents_to_array (ETreeModel *etm, ETreePath *node, int *row, int *count)
-{
- ETreeModelPriv *priv = etm->priv;
-
- /* add a row for this node */
- e_table_model_pre_change(E_TABLE_MODEL (etm));
- priv->row_array = g_array_insert_val (priv->row_array, (*row), node);
- if (priv->frozen == 0)
- e_table_model_row_inserted (E_TABLE_MODEL (etm), (*row));
- (*row) ++;
- (*count) ++;
-
- /* then loop over its children, calling this routine for each
- of them */
- if (node->expanded) {
- ETreePath *child;
- for (child = node->first_child; child;
- child = child->next_sibling) {
- add_visible_descendents_to_array (etm, child, row, count);
- }
- }
-}
-
-static void
-save_expanded_state_func (char *key, gboolean expanded, gpointer user_data)
-{
- if (expanded) {
- xmlNode *root = (xmlNode*)user_data;
- xmlNode *node_root = xmlNewNode (NULL, (xmlChar*) "node");
-
- xmlAddChild (root, node_root);
- xmlNewChild (node_root, NULL, (xmlChar *) "id", (xmlChar*) key);
- }
}
/**
- * e_tree_model_save_expanded_state:
- * @etm:
- * @filename:
+ * e_tree_model_free_value:
+ * @etree:
+ * @path:
*
*
*
* Return value:
**/
-gboolean
-e_tree_model_save_expanded_state (ETreeModel *etm, const char *filename)
-{
- xmlDoc *doc;
- xmlNode *root;
- int fd, rv;
- xmlChar *buf;
- int buf_size;
- ETreeModelPriv *priv = etm->priv;
-
- g_return_val_if_fail(etm != NULL, FALSE);
-
- doc = xmlNewDoc ((xmlChar*) "1.0");
- root = xmlNewDocNode (doc, NULL,
- (xmlChar *) "expanded_state",
- NULL);
- xmlDocSetRootElement (doc, root);
-
- g_hash_table_foreach (priv->expanded_state,
- (GHFunc)save_expanded_state_func,
- root);
-
- fd = open (filename, O_CREAT | O_TRUNC | O_WRONLY, 0777);
-
- xmlDocDumpMemory (doc, &buf, &buf_size);
-
- if (buf == NULL) {
- g_error ("Failed to write %s: xmlBufferCreate() == NULL", filename);
- return FALSE;
- }
-
- rv = write (fd, buf, buf_size);
- xmlFree (buf);
- close (fd);
-
- if (0 > rv) {
- g_error ("Failed to write new %s: %d\n", filename, errno);
- unlink (filename);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static char *
-get_string_value (xmlNode *node,
- const char *name)
+void
+e_tree_model_free_value (ETreeModel *etree, int col, void *value)
{
- xmlNode *p;
- xmlChar *xml_string;
- char *retval;
-
- p = e_xml_get_child_by_name (node, (xmlChar *) name);
- if (p == NULL)
- return NULL;
-
- p = e_xml_get_child_by_name (p, (xmlChar *) "text");
- if (p == NULL) /* there's no text between the tags, return the empty string */
- return g_strdup("");
-
- xml_string = xmlNodeListGetString (node->doc, p, 1);
- retval = g_strdup ((char *) xml_string);
- xmlFree (xml_string);
+ g_return_if_fail(etree != NULL);
- return retval;
+ if (ETM_CLASS(etree)->free_value)
+ ETM_CLASS(etree)->free_value(etree, col, value);
}
/**
- * e_tree_model_load_expanded_state:
- * @etm:
- * @filename:
+ * e_tree_model_initialize_value:
+ * @etree:
+ * @path:
*
*
*
* Return value:
**/
-gboolean
-e_tree_model_load_expanded_state (ETreeModel *etm, const char *filename)
+void *
+e_tree_model_initialize_value (ETreeModel *etree, int col)
{
- ETreeModelPriv *priv = etm->priv;
- xmlDoc *doc;
- xmlNode *root;
- xmlNode *child;
-
- g_return_val_if_fail(etm != NULL, FALSE);
-
- doc = xmlParseFile (filename);
- if (!doc)
- return FALSE;
-
- root = xmlDocGetRootElement (doc);
- if (root == NULL || strcmp (root->name, "expanded_state")) {
- xmlFreeDoc (doc);
- return FALSE;
- }
-
- for (child = root->childs; child; child = child->next) {
- char *id;
-
- if (strcmp (child->name, "node")) {
- g_warning ("unknown node '%s' in %s", child->name, filename);
- continue;
- }
-
- id = get_string_value (child, "id");
-
- g_hash_table_insert (priv->expanded_state, id, (gpointer)TRUE);
- }
-
- xmlFreeDoc (doc);
+ g_return_val_if_fail(etree != NULL, NULL);
- return TRUE;
+ if (ETM_CLASS(etree)->initialize_value)
+ return ETM_CLASS(etree)->initialize_value(etree, col);
+ else
+ return NULL;
}
-
/**
- * e_tree_model_node_set_save_id:
- * @etm:
- * @node:
- * @id:
+ * e_tree_model_value_is_empty:
+ * @etree:
+ * @path:
*
*
- **/
-void
-e_tree_model_node_set_save_id (ETreeModel *etm, ETreePath *node, const char *id)
-{
- char *key;
- gboolean expanded_state;
- ETreeModelPriv *priv;
-
- g_return_if_fail(etm != NULL);
- g_return_if_fail (E_TREE_MODEL (etm));
- g_return_if_fail (node);
-
- priv = etm->priv;
-
- if (g_hash_table_lookup_extended (priv->expanded_state,
- id, (gpointer*)&key, (gpointer*)&expanded_state)) {
-
- e_tree_model_node_set_expanded (etm, node,
- expanded_state);
-
- /* important that this comes after the e_tree_model_node_set_expanded */
- node->save_id = key;
- }
- else {
- node->save_id = g_strdup (id);
-
- g_hash_table_insert (priv->expanded_state, node->save_id, (gpointer)node->expanded);
- }
-}
-
-
-
-/**
- * e_tree_model_node_set_compare_function:
- * @tree_model:
- * @node:
- * @compare:
- *
*
+ * Return value:
**/
-void
-e_tree_model_node_set_compare_function (ETreeModel *tree_model,
- ETreePath *node,
- ETreePathCompareFunc compare)
+gboolean
+e_tree_model_value_is_empty (ETreeModel *etree, int col, const void *value)
{
- gboolean need_sort;
-
- g_return_if_fail (tree_model != NULL);
- g_return_if_fail (E_TREE_MODEL (tree_model));
- g_return_if_fail (node);
+ g_return_val_if_fail(etree != NULL, TRUE);
- need_sort = (compare != node->compare);
-
- node->compare = compare;
-
- if (need_sort)
- e_tree_model_node_sort (tree_model, node);
-}
-
-typedef struct {
- ETreeModel *model;
- ETreePath *path;
- ETreePathCompareFunc compare;
- gboolean was_expanded;
-} ETreeSortInfo;
-
-static gint
-e_tree_model_node_compare (ETreeSortInfo *info1, ETreeSortInfo *info2)
-{
- return info1->compare (info1->model, info1->path, info2->path);
+ if (ETM_CLASS(etree)->value_is_empty)
+ return ETM_CLASS(etree)->value_is_empty(etree, col, value);
+ else
+ return TRUE;
}
/**
- * e_tree_model_node_sort:
- * @tree_model:
- * @node:
+ * e_tree_model_value_to_string:
+ * @etree:
+ * @path:
+ *
*
*
+ * Return value:
**/
-void
-e_tree_model_node_sort (ETreeModel *tree_model,
- ETreePath *node)
+char *
+e_tree_model_value_to_string (ETreeModel *etree, int col, const void *value)
{
- int num_nodes = node->num_children;
- ETreeSortInfo *sort_info;
- int i;
- int child_index;
- gboolean node_expanded;
- ETreeModelPriv *priv = tree_model->priv;;
-
- node_expanded = e_tree_model_node_is_expanded (tree_model, node);
-
- g_return_if_fail (tree_model != NULL);
- g_return_if_fail (E_TREE_MODEL (tree_model));
- g_return_if_fail (node);
-
- g_return_if_fail (node->compare);
-
- if (num_nodes == 0)
- return;
+ g_return_val_if_fail(etree != NULL, g_strdup(""));
- e_table_model_pre_change(E_TABLE_MODEL (tree_model));
-
- sort_info = g_new (ETreeSortInfo, num_nodes);
-
- child_index = e_tree_model_row_of_node (tree_model, node) + 1;
-
- /* collect our info and remove the children */
- for (i = 0; i < num_nodes; i ++) {
- sort_info[i].path = node->first_child;
- sort_info[i].was_expanded = e_tree_model_node_is_expanded (tree_model, sort_info[i].path);
- sort_info[i].model = tree_model;
- sort_info[i].compare = node->compare;
-
- e_tree_model_node_set_expanded(tree_model, sort_info[i].path, FALSE);
- if (node_expanded)
- priv->row_array = g_array_remove_index (priv->row_array, child_index);
- e_tree_path_unlink (sort_info[i].path);
- }
-
- /* sort things */
- qsort (sort_info, num_nodes, sizeof(ETreeSortInfo), (GCompareFunc)e_tree_model_node_compare);
-
- /* reinsert the children nodes into the tree in the sorted order */
- for (i = 0; i < num_nodes; i ++) {
- e_tree_path_insert (node, i, sort_info[i].path);
- if (node_expanded)
- priv->row_array = g_array_insert_val (priv->row_array, child_index + i,
- sort_info[i].path);
- }
-
- /* make another pass expanding the children as needed.
-
- XXX this used to be in the loop above, but a recent change
- (either here or in the etable code) causes an assertion and
- a crash */
- for (i = 0; i < num_nodes; i ++) {
- e_tree_model_node_set_expanded (tree_model, sort_info[i].path, sort_info[i].was_expanded);
- }
-
- g_free (sort_info);
-
- if (priv->frozen == 0)
- e_table_model_changed (E_TABLE_MODEL (tree_model));
+ if (ETM_CLASS(etree)->value_to_string)
+ return ETM_CLASS(etree)->value_to_string(etree, col, value);
+ else
+ return g_strdup("");
}
-