aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'widgets')
-rw-r--r--widgets/table/e-tree-memory.c12
-rw-r--r--widgets/table/e-tree-model.c8
-rw-r--r--widgets/table/e-tree-model.h5
-rw-r--r--widgets/table/e-tree-sorted.c113
-rw-r--r--widgets/table/e-tree-table-adapter.c2
5 files changed, 95 insertions, 45 deletions
diff --git a/widgets/table/e-tree-memory.c b/widgets/table/e-tree-memory.c
index b14beafb15..886c7beb0f 100644
--- a/widgets/table/e-tree-memory.c
+++ b/widgets/table/e-tree-memory.c
@@ -524,12 +524,20 @@ e_tree_memory_node_remove (ETreeMemory *etree, ETreePath node)
{
ETreeMemoryPath *path = node;
ETreeMemoryPath *parent = path->parent;
+ ETreeMemoryPath *sibling;
gpointer ret = path->node_data;
+ int old_position = 0;
g_return_val_if_fail(etree != NULL, NULL);
- if (!etree->priv->frozen)
+ if (!etree->priv->frozen) {
e_tree_model_pre_change(E_TREE_MODEL(etree));
+ for (old_position = 0, sibling = path;
+ sibling;
+ old_position++, sibling = sibling->prev_sibling)
+ /* Empty intentionally*/;
+ old_position --;
+ }
/* unlink this node - we only have to unlink the root node being removed,
since the others are only references from this node */
@@ -537,7 +545,7 @@ e_tree_memory_node_remove (ETreeMemory *etree, ETreePath node)
/*printf("removing %d nodes from position %d\n", visible, base);*/
if (!etree->priv->frozen)
- e_tree_model_node_removed(E_TREE_MODEL(etree), parent, path);
+ e_tree_model_node_removed(E_TREE_MODEL(etree), parent, path, old_position);
child_free(etree, path);
diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c
index 389e37223a..60b01310ab 100644
--- a/widgets/table/e-tree-model.c
+++ b/widgets/table/e-tree-model.c
@@ -97,8 +97,8 @@ e_tree_model_class_init (GtkObjectClass *klass)
GTK_RUN_LAST,
klass->type,
GTK_SIGNAL_OFFSET (ETreeModelClass, node_removed),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
+ e_marshal_NONE__POINTER_POINTER_INT,
+ GTK_TYPE_NONE, 3, GTK_TYPE_POINTER, GTK_TYPE_POINTER, GTK_TYPE_INT);
gtk_object_class_add_signals (klass, e_tree_model_signals, LAST_SIGNAL);
@@ -257,14 +257,14 @@ e_tree_model_node_inserted (ETreeModel *tree_model,
*
**/
void
-e_tree_model_node_removed (ETreeModel *tree_model, ETreePath parent_node, ETreePath removed_node)
+e_tree_model_node_removed (ETreeModel *tree_model, ETreePath parent_node, ETreePath removed_node, int old_position)
{
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);
+ parent_node, removed_node, old_position);
}
diff --git a/widgets/table/e-tree-model.h b/widgets/table/e-tree-model.h
index 965d66e915..720bd897de 100644
--- a/widgets/table/e-tree-model.h
+++ b/widgets/table/e-tree-model.h
@@ -74,7 +74,7 @@ struct ETreeModelClass {
void (*node_data_changed) (ETreeModel *etm, ETreePath node);
void (*node_col_changed) (ETreeModel *etm, ETreePath node, int col);
void (*node_inserted) (ETreeModel *etm, ETreePath parent, ETreePath inserted_node);
- void (*node_removed) (ETreeModel *etm, ETreePath parent, ETreePath removed_node);
+ void (*node_removed) (ETreeModel *etm, ETreePath parent, ETreePath removed_node, int old_position);
};
GtkType e_tree_model_get_type (void);
ETreeModel *e_tree_model_new (void);
@@ -159,7 +159,8 @@ void e_tree_model_node_inserted (ETreeModel *tree_model,
ETreePath inserted_node);
void e_tree_model_node_removed (ETreeModel *tree_model,
ETreePath parent_node,
- ETreePath removed_node);
+ ETreePath removed_node,
+ int old_position);
#ifdef __cplusplus
}
diff --git a/widgets/table/e-tree-sorted.c b/widgets/table/e-tree-sorted.c
index b5fc211347..1ebfbe7846 100644
--- a/widgets/table/e-tree-sorted.c
+++ b/widgets/table/e-tree-sorted.c
@@ -53,6 +53,7 @@ struct ETreeSortedPath {
gint num_children;
ETreeSortedPath **children;
int position;
+ int orig_position;
guint needs_resort : 1;
guint child_needs_resort : 1;
@@ -87,11 +88,12 @@ enum {
};
static void ets_sort_info_changed (ETableSortInfo *sort_info, ETreeSorted *ets);
-static void resort_node (ETreeSorted *ets, ETreeSortedPath *path, gboolean resort_all_children, gboolean send_signals);
+static void resort_node (ETreeSorted *ets, ETreeSortedPath *path, gboolean resort_all_children, gboolean needs_regen, gboolean send_signals);
static void mark_path_needs_resort (ETreeSorted *ets, ETreeSortedPath *path, gboolean needs_rebuild, gboolean resort_all_children);
static void schedule_resort (ETreeSorted *ets, ETreeSortedPath *path, gboolean needs_regen, gboolean resort_all_children);
static void free_path (ETreeSortedPath *path);
-static void generate_children(ETreeSorted *ets, ETreeSortedPath *path, gboolean needs_resort);
+static void generate_children(ETreeSorted *ets, ETreeSortedPath *path);
+static void regenerate_children(ETreeSorted *ets, ETreeSortedPath *path);
@@ -103,7 +105,7 @@ ets_sort_idle(gpointer user_data)
ETreeSorted *ets = user_data;
ets->priv->sort_idle_id = 0;
if (ets->priv->root) {
- resort_node (ets, ets->priv->root, FALSE, TRUE);
+ resort_node (ets, ets->priv->root, FALSE, FALSE, TRUE);
}
return FALSE;
}
@@ -226,7 +228,7 @@ find_or_create_path(ETreeSorted *ets, ETreePath corresponding)
int j;
if (path->num_children == -1) {
- generate_children(ets, path, TRUE);
+ generate_children(ets, path);
}
for (j = 0; j < path->num_children; j++) {
@@ -286,6 +288,7 @@ new_path (ETreeSortedPath *parent, ETreePath corresponding)
path->num_children = -1;
path->children = NULL;
path->position = -1;
+ path->orig_position = -1;
path->child_needs_resort = 0;
path->resort_all_children = 0;
path->needs_resort = 0;
@@ -345,7 +348,20 @@ reposition_path (ETreeSorted *ets, ETreeSortedPath *path)
}
static void
-generate_children(ETreeSorted *ets, ETreeSortedPath *path, gboolean needs_resort)
+regenerate_children(ETreeSorted *ets, ETreeSortedPath *path)
+{
+ ETreeSortedPath **children;
+ int i;
+
+ children = g_new(ETreeSortedPath *, path->num_children);
+ for (i = 0; i < path->num_children; i++)
+ children[path->children[i]->orig_position] = path->children[i];
+ g_free(path->children);
+ path->children = children;
+}
+
+static void
+generate_children(ETreeSorted *ets, ETreeSortedPath *path)
{
ETreePath child;
int i;
@@ -367,26 +383,28 @@ generate_children(ETreeSorted *ets, ETreeSortedPath *path, gboolean needs_resort
child = e_tree_model_node_get_next(ets->priv->source, child), i++) {
path->children[i] = new_path(path, child);
path->children[i]->position = i;
+ path->children[i]->orig_position = i;
}
- if (needs_resort)
+ if (path->num_children > 0)
schedule_resort (ets, path, FALSE, TRUE);
}
static void
-resort_node (ETreeSorted *ets, ETreeSortedPath *path, gboolean resort_all_children, gboolean send_signals)
+resort_node (ETreeSorted *ets, ETreeSortedPath *path, gboolean resort_all_children, gboolean needs_regen, gboolean send_signals)
{
gboolean needs_resort;
if (path) {
needs_resort = path->needs_resort || resort_all_children;
- if (needs_resort && send_signals)
- e_tree_model_pre_change(E_TREE_MODEL(ets));
- if (needs_resort) {
- int i;
- d(g_print("Start sort of node %p\n", path));
- if (path->needs_regen_to_sort)
- generate_children(ets, path, FALSE);
- d(g_print("Regened sort of node %p\n", path));
- if (path->num_children > 0) {
+ needs_regen = path->needs_regen_to_sort || needs_regen;
+ if (path->num_children > 0) {
+ if (needs_resort && send_signals)
+ e_tree_model_pre_change(E_TREE_MODEL(ets));
+ if (needs_resort) {
+ int i;
+ d(g_print("Start sort of node %p\n", path));
+ if (needs_regen)
+ regenerate_children(ets, path);
+ d(g_print("Regened sort of node %p\n", path));
e_table_sorting_utils_tree_sort (E_TREE_MODEL(ets),
ets->priv->sort_info,
ets->priv->full_header,
@@ -396,23 +414,23 @@ resort_node (ETreeSorted *ets, ETreeSortedPath *path, gboolean resort_all_childr
for (i = 0; i < path->num_children; i++) {
path->children[i]->position = i;
}
+ d(g_print("End sort of node %p\n", path));
}
- d(g_print("End sort of node %p\n", path));
- }
- if (path->resort_all_children)
- resort_all_children = TRUE;
- if ((resort_all_children || path->child_needs_resort) && path->num_children >= 0) {
- int i;
- for (i = 0; i < path->num_children; i++) {
- resort_node(ets, path->children[i], resort_all_children, send_signals && !needs_resort);
+ if (path->resort_all_children)
+ resort_all_children = TRUE;
+ if ((resort_all_children || path->child_needs_resort) && path->num_children >= 0) {
+ int i;
+ for (i = 0; i < path->num_children; i++) {
+ resort_node(ets, path->children[i], resort_all_children, needs_regen, send_signals && !needs_resort);
+ }
+ path->child_needs_resort = 0;
}
- path->child_needs_resort = 0;
}
path->needs_resort = 0;
path->child_needs_resort = 0;
path->needs_regen_to_sort = 0;
path->resort_all_children = 0;
- if (needs_resort && send_signals)
+ if (needs_resort && send_signals && path->num_children > 0)
e_tree_model_node_changed(E_TREE_MODEL(ets), path);
}
}
@@ -433,6 +451,8 @@ mark_path_needs_resort (ETreeSorted *ets, ETreeSortedPath *path, gboolean needs_
{
if (path == NULL)
return;
+ if (path->num_children == 0)
+ return;
path->needs_resort = 1;
path->needs_regen_to_sort = needs_regen;
path->resort_all_children = resort_all_children;
@@ -590,7 +610,7 @@ ets_get_root (ETreeModel *etm)
}
}
if (priv->root && priv->root->num_children == -1) {
- generate_children(E_TREE_SORTED(etm), priv->root, TRUE);
+ generate_children(E_TREE_SORTED(etm), priv->root);
}
return priv->root;
@@ -610,7 +630,7 @@ ets_get_first_child (ETreeModel *etm, ETreePath node)
ETreeSorted *ets = E_TREE_SORTED(etm);
if (path->num_children == -1)
- generate_children(ets, path, TRUE);
+ generate_children(ets, path);
if (path->num_children > 0)
return path->children[0];
@@ -625,7 +645,7 @@ ets_get_last_child (ETreeModel *etm, ETreePath node)
ETreeSorted *ets = E_TREE_SORTED(etm);
if (path->num_children == -1)
- generate_children(ets, path, TRUE);
+ generate_children(ets, path);
if (path->num_children > 0)
return path->children[path->num_children - 1];
@@ -678,7 +698,7 @@ ets_is_expandable (ETreeModel *etm, ETreePath node)
gboolean expandable = e_tree_model_node_is_expandable (ets->priv->source, path->corresponding);
if (path->num_children == -1) {
- generate_children(ets, node, TRUE);
+ generate_children(ets, node);
}
return expandable;
@@ -691,7 +711,7 @@ ets_get_children (ETreeModel *etm, ETreePath node, ETreePath **nodes)
guint n_children;
if (path->num_children == -1) {
- generate_children(E_TREE_SORTED(etm), node, TRUE);
+ generate_children(E_TREE_SORTED(etm), node);
}
n_children = path->num_children;
@@ -893,8 +913,22 @@ ets_proxy_node_inserted (ETreeModel *etm, ETreePath parent, ETreePath child, ETr
int i;
int j;
ETreeSortedPath *path;
- i = parent_path->num_children;
+ int position = parent_path->num_children;
+ ETreePath counter;
+
+ for (counter = e_tree_model_node_get_next(etm, child);
+ counter;
+ counter = e_tree_model_node_get_next(etm, counter))
+ position --;
+
+ if (position != parent_path->num_children) {
+ for (i = 0; i < parent_path->num_children; i++) {
+ if (parent_path->children[i]->position >= position)
+ parent_path->children[i]->position++;
+ }
+ }
+ i = parent_path->num_children;
path = new_path(parent_path, child);
if (ets->priv->sort_idle_id == 0) {
ets->priv->insert_count++;
@@ -934,7 +968,7 @@ ets_proxy_node_inserted (ETreeModel *etm, ETreePath parent, ETreePath child, ETr
}
static void
-ets_proxy_node_removed (ETreeModel *etm, ETreePath parent, ETreePath child, ETreeSorted *ets)
+ets_proxy_node_removed (ETreeModel *etm, ETreePath parent, ETreePath child, int old_position, ETreeSorted *ets)
{
ETreeSortedPath *parent_path = find_path(ets, parent);
ETreeSortedPath *path;
@@ -945,17 +979,24 @@ ets_proxy_node_removed (ETreeModel *etm, ETreePath parent, ETreePath child, ETre
path = find_path(ets, child);
if (path && parent_path && parent_path->num_children != -1) {
- int i = path->position;
+ int i;
+ for (i = 0; i < parent_path->num_children; i++) {
+ if (parent_path->children[i]->orig_position > old_position)
+ parent_path->children[i]->orig_position --;
+ }
+
+ i = path->position;
+
parent_path->num_children --;
memmove(parent_path->children + i, parent_path->children + i + 1, sizeof(ETreeSortedPath *) * (parent_path->num_children - i));
for (; i < parent_path->num_children; i++) {
parent_path->children[i]->position = i;
}
- e_tree_model_node_removed(E_TREE_MODEL(ets), parent_path, path);
+ e_tree_model_node_removed(E_TREE_MODEL(ets), parent_path, path, path->position);
free_path(path);
} else if (path && path == ets->priv->root) {
ets->priv->root = NULL;
- e_tree_model_node_removed(E_TREE_MODEL(ets), NULL, path);
+ e_tree_model_node_removed(E_TREE_MODEL(ets), NULL, path, -1);
free_path(path);
}
}
diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c
index 481deb8eb5..e56c3eeb1c 100644
--- a/widgets/table/e-tree-table-adapter.c
+++ b/widgets/table/e-tree-table-adapter.c
@@ -664,7 +664,7 @@ etta_proxy_node_inserted (ETreeModel *etm, ETreePath parent, ETreePath child, ET
}
static void
-etta_proxy_node_removed (ETableModel *etm, ETreePath parent, ETreePath child, ETreeTableAdapter *etta)
+etta_proxy_node_removed (ETableModel *etm, ETreePath parent, ETreePath child, int old_position, ETreeTableAdapter *etta)
{
int parent_row = find_row_num(etta, parent);
int row = find_child_row_num(etta, parent_row, child);