[latexila/structure-update: 1/2] Structure: shift items if needed when inserting a new item
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [latexila/structure-update: 1/2] Structure: shift items if needed when inserting a new item
- Date: Sun, 12 Jun 2011 17:14:48 +0000 (UTC)
commit cdd669cda49c8a3f0c1ad054c337d4a0510c6bef
Author: Sébastien Wilmet <sebastien wilmet gmail com>
Date: Sun May 1 01:51:56 2011 +0200
Structure: shift items if needed when inserting a new item
The code is well documented.
The glib-2.0.vapi contains some errors, see this bug report:
https://bugzilla.gnome.org/show_bug.cgi?id=649052
TODO | 1 -
src/document_structure.vala | 85 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 83 insertions(+), 3 deletions(-)
---
diff --git a/TODO b/TODO
index e55a3e6..36391fe 100644
--- a/TODO
+++ b/TODO
@@ -8,7 +8,6 @@ LaTeXila 2.2
- Structure (list of chapters, sections, etc.):
- different style (e.g. italic) for commented items
- - improve insert_item_at_position() (shift items if needed)
- update on the fly the structure when the document is modified
- right click: cut, copy, paste below, select, delete, comment, shift left/right
diff --git a/src/document_structure.vala b/src/document_structure.vala
index 50f9c32..b2854e3 100644
--- a/src/document_structure.vala
+++ b/src/document_structure.vala
@@ -365,9 +365,90 @@ public class DocumentStructure : GLib.Object
}
}
- private void insert_item_at_position (DataNode item, Node<DataNode?> parent, int pos)
+ private void insert_item_at_position (DataNode item, Node<DataNode?> direct_parent,
+ int pos)
{
- parent.insert_data (pos, item);
+ // If the item to insert is a simple element (not a section), simply insert it
+ // at the given position.
+ if (item.type > StructType.SUBPARAGRAPH)
+ {
+ direct_parent.insert_data (pos, item);
+ return;
+ }
+
+ bool shifted = false;
+
+ // Create the node, but for the moment it is not attached to the tree.
+ // If needed, some nodes from the tree will be removed and inserted as children
+ // of the new node.
+ Node<DataNode?> new_node = new Node<DataNode?> (item);
+
+ // This kind of algorithm is better understandable with an example and some
+ // documentation. So here we go.
+
+ // Example:
+ //_tree (last parent) _tree
+ // 1 (third parent) 1
+ // 2 2
+ // 2 (second parent) 2
+ // 3 (first parent) 3
+ // 4 4
+ // insert a 1 here => 1
+ // 4 4
+ // 4 4
+ // 3 3
+ // 3 3
+ // 2 2
+
+ // 1 is e.g. a part, 2 a chapter, and so on.
+ // All the items above the item to insert must NOT move.
+
+ // We take the first parent (the one given as the function argument).
+
+ // For this parent, we inspect the children (only those that are below).
+ // If a child have a type higher than the type of the item to insert, then
+ // the child is removed from the _tree and added to the new node. In the example,
+ // the first parent is the '3', and the two children '4' are moved.
+
+ // When we have inspected all the below children, we check if the parent have
+ // a lower type. If it's the case, then we know the real parent and the real
+ // position. If it's not the case, then we have to take the grand-parent, and
+ // redo the same stuff with its children.
+ // In the example, the first parent ('3') have not a lower type than '1', so we
+ // take the grand-parent ('2').
+
+ unowned Node<DataNode?>? parent = direct_parent;
+ int cur_pos = pos;
+ while (true)
+ {
+ // Inspect the other children which are after 'cur_pos'. Indeed, the children
+ // which are before 'cur_pos' must not move.
+ unowned Node<DataNode?>? child = parent.nth_child (pos);
+ while (child != null)
+ {
+ unowned Node<DataNode?>? next_child = child.next_sibling ();
+
+ if (child.data.type <= item.type)
+ break;
+
+ shifted = true;
+ new_node.append (child.unlink ());
+
+ child = next_child;
+ }
+
+ if (parent == _tree)
+ break;
+
+ if (parent.data.type < item.type)
+ break;
+
+ unowned Node<DataNode?> grand_parent = parent.parent;
+ cur_pos = grand_parent.child_position (parent) + 1;
+ parent = grand_parent;
+ }
+
+ parent.insert (cur_pos, (owned) new_node);
}
private static int get_position_from_mark (TextMark mark)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]