[latexila/structure-update: 2/2] Structure: update structure on the fly (test)
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [latexila/structure-update: 2/2] Structure: update structure on the fly (test)
- Date: Sun, 12 Jun 2011 17:14:53 +0000 (UTC)
commit 6d17dbf5413f221d3acf4deeee00316077855e5c
Author: Sébastien Wilmet <sebastien wilmet gmail com>
Date: Wed May 4 20:34:47 2011 +0200
Structure: update structure on the fly (test)
It becomes a little too hackish.
A custom TreeStore would be a cleaner approach, to get rid of updating
all the time the TreeStore from the GNodes.
src/document_structure.vala | 145 +++++++++++++++++++++++++++++++++++++++---
1 files changed, 134 insertions(+), 11 deletions(-)
---
diff --git a/src/document_structure.vala b/src/document_structure.vala
index b2854e3..7d8322c 100644
--- a/src/document_structure.vala
+++ b/src/document_structure.vala
@@ -34,6 +34,7 @@ public class DocumentStructure : GLib.Object
private bool _insert_at_end = true;
private Node<DataNode?> _tree;
+ private TreeStore _tree_store = null;
private static Regex? _comment_regex = null;
@@ -59,6 +60,8 @@ public class DocumentStructure : GLib.Object
stderr.printf ("Structure: %s\n", e.message);
}
}
+
+ update_structure_on_the_fly ();
}
public void parse ()
@@ -315,7 +318,7 @@ public class DocumentStructure : GLib.Object
return;
}
- int pos = get_position_from_mark (item.mark);
+ int pos = get_mark_position (item.mark);
unowned Node<DataNode?> cur_parent = _tree;
while (true)
{
@@ -323,7 +326,7 @@ public class DocumentStructure : GLib.Object
int child_index = 0;
while (true)
{
- int cur_pos = get_position_from_mark (cur_child.data.mark);
+ int cur_pos = get_mark_position (cur_child.data.mark);
if (cur_pos > pos)
{
@@ -451,7 +454,7 @@ public class DocumentStructure : GLib.Object
parent.insert (cur_pos, (owned) new_node);
}
- private static int get_position_from_mark (TextMark mark)
+ private static int get_mark_position (TextMark mark)
{
TextIter iter;
TextBuffer doc = mark.get_buffer ();
@@ -484,30 +487,30 @@ public class DocumentStructure : GLib.Object
public void populate_tree_store (TreeStore store)
{
- populate_tree_store_at_node (store, _tree);
+ _tree_store = store;
+ populate_tree_store_at_node (_tree);
}
// The data are first inserted in Gnodes. When the parsing is done, this method is
// called to populate the tree store with the data contained in the GNodes.
- private void populate_tree_store_at_node (TreeStore store, Node<DataNode?> node,
+ private void populate_tree_store_at_node (Node<DataNode?> node,
TreeIter? parent = null, bool root_node = true)
{
TreeIter? iter = null;
if (! root_node)
- iter = add_item_to_tree_store (store, parent, node.data);
+ iter = add_item_to_tree_store (parent, node.data);
node.children_foreach (TraverseFlags.ALL, (child_node) =>
{
- populate_tree_store_at_node (store, child_node, iter, false);
+ populate_tree_store_at_node (child_node, iter, false);
});
}
- private TreeIter add_item_to_tree_store (TreeStore store, TreeIter? parent,
- DataNode data)
+ private TreeIter add_item_to_tree_store (TreeIter? parent, DataNode data)
{
TreeIter iter;
- store.append (out iter, parent);
- store.set (iter,
+ _tree_store.append (out iter, parent);
+ _tree_store.set (iter,
StructItem.PIXBUF, Structure.get_icon_from_type (data.type),
StructItem.TYPE, data.type,
StructItem.TEXT, data.text,
@@ -518,6 +521,126 @@ public class DocumentStructure : GLib.Object
return iter;
}
+ // remove all items that are located at 'pos'
+ private void remove_items_at_node (Node<DataNode?> node, int pos, string[] indices)
+ {
+ unowned Node<DataNode?>? child = node.first_child ();
+ if (child == null)
+ return;
+
+ int cur_pos = get_mark_position (child.data.mark);
+ int i = 0;
+
+ while (child != null)
+ {
+ if (cur_pos > pos)
+ return;
+
+ unowned Node<DataNode?>? next_child = child.next_sibling ();
+ int next_pos = 0;
+ if (next_child != null)
+ {
+ next_pos = get_mark_position (next_child.data.mark);
+ if (next_pos < pos)
+ {
+ child = next_child;
+ cur_pos = next_pos;
+ i++;
+ continue;
+ }
+ }
+
+ string[] cur_indices = indices;
+ cur_indices += i.to_string ();
+
+ remove_items_at_node (child, pos, cur_indices);
+
+ if (cur_pos == pos)
+ remove_item_from_tree_store (child, cur_indices);
+
+ child = next_child;
+ cur_pos = next_pos;
+ i++;
+ }
+ }
+
+ private void remove_item_from_tree_store (Node<DataNode?> node, string[] indices)
+ {
+ if (node.is_leaf ())
+ {
+ string path_string = string.joinv (":", indices);
+ TreeIter iter;
+ stdout.printf ("path string: %s\n", path_string);
+ bool success = _tree_store.get_iter_from_string (out iter, path_string);
+ return_if_fail (success);
+
+ string text;
+ TreeModel model = (TreeModel) _tree_store;
+ model.get (iter, StructItem.TEXT, out text, -1);
+ stdout.printf ("remove item '%s'\n", text);
+
+ _tree_store.remove (iter);
+ return;
+ }
+ }
+
+ private void update_structure_on_the_fly ()
+ {
+ // some text is deleted
+ _doc.delete_range.connect_after (on_delete_range_after);
+ }
+
+ private void on_delete_range_after (TextIter iter)
+ {
+ // The text is already deleted. If there were some marks in the range, these marks
+ // will now be located at 'iter'.
+
+ /* Is there some marks? */
+ SList<weak TextMark> marks = iter.get_marks ();
+
+ // We keep a sample mark (one is enough, since they are all at the same place)
+ TextMark? sample_mark = null;
+
+ bool found = false;
+ foreach (weak TextMark mark in marks)
+ {
+ string? name = mark.get_name ();
+ if (name == null)
+ continue;
+
+ if (name.has_prefix (MARK_NAME_PREFIX))
+ {
+ found = true;
+ sample_mark = mark;
+ break;
+ }
+ }
+
+ if (! found)
+ return;
+
+ // We can run the rest in an IdleSource, so the UI is not frozen.
+ // I think we can't put the above code in the Idle, since the TextIter could be
+ // invalid.
+ Idle.add (() =>
+ {
+ // If the active document has changed (why not?)
+
+ // Delete all marks located at the same place as sample_mark.
+ int pos = get_mark_position (sample_mark);
+ string[] indices = {};
+ remove_items_at_node (_tree, pos, indices);
+
+ // But maybe one mark was actually good.
+ // Example:
+ // before: blabla \nicecommand{blabla}
+ // after: \nicecommand{blabla}
+ // In this example, we find a mark which is still good, so we recreate it.
+
+ return false;
+ });
+ }
+
private StructType? get_type_from_simple_command_name (string name)
{
switch (name)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]