[latexila] Structure: optimize insertion of figures and tables



commit fef46a237dc7eb9d01200e5884ed17a0f0f3b0d6
Author: SÃbastien Wilmet <swilmet src gnome org>
Date:   Fri Jul 22 21:04:07 2011 +0200

    Structure: optimize insertion of figures and tables
    
    As soon as we find the \begin{env}, we insert the item in the model.
    When we find the first caption, we store it in a variable, and when we
    find the corresponding \end{env}, we modify the data of the item.
    
    This is when the data is modified that the items between the \begin and
    the \end are moved as children of the environment.
    
    This is a lot faster than waiting the \end{env} and insert it in middle.

 TODO                        |    4 ---
 src/document_structure.vala |   60 +++++++++++++++++++++++-------------------
 src/structure_model.vala    |   38 ++++++++++++++++++++-------
 3 files changed, 61 insertions(+), 41 deletions(-)
---
diff --git a/TODO b/TODO
index 47653ff..266240d 100644
--- a/TODO
+++ b/TODO
@@ -9,10 +9,6 @@ LaTeXila 2.2
 - Build Tools:
 	- Some problems with the latex and latexmk post processors
 
-- Structure:
-	- Insert in middle is very slow comparated to insert at the end
-	  => Insert environments as soon as we find the \begin, and then update the item (or delete it)
-
 
 LaTeXila â 2.4
 ==============
diff --git a/src/document_structure.vala b/src/document_structure.vala
index 40d1835..16d7d4a 100644
--- a/src/document_structure.vala
+++ b/src/document_structure.vala
@@ -50,6 +50,14 @@ public class DocumentStructure : GLib.Object
         CAPTION
     }
 
+    // For a figure or table environment, because all the data can not be inserted at once
+    private struct EnvData
+    {
+        TreePath path;
+        StructType type;
+        string? first_caption;
+    }
+
     private unowned Document _doc;
     private int _nb_marks = 0;
     private static const string MARK_NAME_PREFIX = "struct_item_";
@@ -63,8 +71,7 @@ public class DocumentStructure : GLib.Object
 
     private bool _in_verbatim_env = false;
 
-    // we can not take all data for figures and tables at once
-    private StructData? _env_data = null;
+    private EnvData? _last_env_data = null;
 
     private static const int CAPTION_MAX_LENGTH = 60;
 
@@ -108,7 +115,7 @@ public class DocumentStructure : GLib.Object
         // reset
         parsing_done = false;
         _model = new StructureModel ();
-        _env_data = null;
+        _last_env_data = null;
         _start_parsing_line = 0;
 
         _end_document_mark = null;
@@ -410,21 +417,22 @@ public class DocumentStructure : GLib.Object
             create_new_environment (type, iter);
 
         // a caption (we take only the first)
-        else if (type == LowLevelType.CAPTION && _env_data != null
-            && _env_data.text == null)
+        else if (type == LowLevelType.CAPTION && _last_env_data != null
+            && _last_env_data.first_caption == null)
         {
-            string? short_caption = null;
             if (contents.length > CAPTION_MAX_LENGTH)
-                short_caption = contents.substring (0, CAPTION_MAX_LENGTH);
-
-            _env_data.text = short_caption ?? contents;
+                _last_env_data.first_caption = contents.substring (0, CAPTION_MAX_LENGTH);
+            else
+                _last_env_data.first_caption = contents;
         }
 
         // end of a figure or table env
         else if (verify_end_environment_type (type))
         {
-            _env_data.end_mark = create_text_mark_from_iter (iter);
-            add_item_data (_env_data, true);
+            TextMark end_mark = create_text_mark_from_iter (iter);
+            _model.modify_data (_last_env_data.path, _last_env_data.first_caption,
+                end_mark);
+            _last_env_data = null;
         }
 
         // end of the document
@@ -437,32 +445,33 @@ public class DocumentStructure : GLib.Object
         return_if_fail (type == LowLevelType.BEGIN_FIGURE
             || type == LowLevelType.BEGIN_TABLE);
 
-        _env_data = StructData ();
-        _env_data.text = null;
-        _env_data.start_mark = create_text_mark_from_iter (start_iter);
-        _env_data.end_mark = null;
+        _last_env_data = EnvData ();
+        _last_env_data.first_caption = null;
 
         if (type == LowLevelType.BEGIN_TABLE)
-            _env_data.type = StructType.TABLE;
+            _last_env_data.type = StructType.TABLE;
         else
-            _env_data.type = StructType.FIGURE;
+            _last_env_data.type = StructType.FIGURE;
+
+        TreeIter tree_iter = add_item (_last_env_data.type, null, start_iter);
+        _last_env_data.path = _model.get_path (tree_iter);
     }
 
     private bool verify_end_environment_type (LowLevelType type)
     {
-        if (_env_data == null)
+        if (_last_env_data == null)
             return false;
 
         if (type == LowLevelType.END_TABLE)
-            return _env_data.type == StructType.TABLE;
+            return _last_env_data.type == StructType.TABLE;
 
         if (type == LowLevelType.END_FIGURE)
-            return _env_data.type == StructType.FIGURE;
+            return _last_env_data.type == StructType.FIGURE;
 
         return false;
     }
 
-    private void add_item (StructType type, string? text, TextIter start_iter)
+    private TreeIter? add_item (StructType type, string? text, TextIter start_iter)
     {
         StructData data = {};
         data.type = type;
@@ -470,18 +479,15 @@ public class DocumentStructure : GLib.Object
         data.start_mark = create_text_mark_from_iter (start_iter);
         data.end_mark = null;
 
-        add_item_data (data);
+        return add_item_data (data);
     }
 
-    private void add_item_data (StructData data, bool insert_in_middle = false)
+    private TreeIter? add_item_data (StructData data)
     {
         if (data.text == null)
             data.text = "";
 
-        if (insert_in_middle)
-            _model.add_item_in_middle (data);
-        else
-            _model.add_item_at_end (data);
+        return _model.add_item_at_end (data);
     }
 
     private TextMark create_text_mark_from_iter (TextIter iter)
diff --git a/src/structure_model.vala b/src/structure_model.vala
index 220cc7c..bcb469f 100644
--- a/src/structure_model.vala
+++ b/src/structure_model.vala
@@ -349,7 +349,7 @@ public class StructureModel : TreeModel, GLib.Object
         return _nb_nodes;
     }
 
-    public void add_item_at_end (StructData item)
+    public TreeIter? add_item_at_end (StructData item)
     {
         /* search the parent, based on the type */
         unowned Node<StructData?> parent = _tree;
@@ -368,12 +368,13 @@ public class StructureModel : TreeModel, GLib.Object
             parent = last_child;
         }
 
-        append_item (parent, item);
+        return append_item (parent, item);
     }
 
     // In the middle means that we have to find where to insert the data in the tree.
     // If items have to be shifted (for example: insert a chapter in the middle of
     // sections), it will be done by insert_item_at_position().
+    /*
     public void add_item_in_middle (StructData item)
     {
         // if the tree is empty
@@ -432,6 +433,7 @@ public class StructureModel : TreeModel, GLib.Object
             }
         }
     }
+    */
 
     // With the iter returned, we can simply go one line backward and we have the end of
     // the section. If null is returned, the end of the section is the end of the doc.
@@ -468,6 +470,23 @@ public class StructureModel : TreeModel, GLib.Object
         regenerate_simple_lists ();
     }
 
+    public void modify_data (TreePath path, string text, TextMark end_mark)
+    {
+        TreeIter iter;
+        bool iter_is_valid = get_iter (out iter, path);
+        return_if_fail (iter_is_valid);
+
+        unowned Node<StructData?> node = get_node_from_iter (iter);
+
+        // modify data
+        new_stamp ();
+        node.data.text = text;
+        node.data.end_mark = end_mark;
+        row_changed (path, iter);
+
+        make_children_between_marks (node);
+    }
+
     public void shift_right (TreeIter iter)
     {
         return_if_fail (iter_is_valid (iter));
@@ -665,6 +684,7 @@ public class StructureModel : TreeModel, GLib.Object
         }
     }
 
+    /*
     private void insert_item_at_position (StructData item, Node<StructData?> parent,
         int pos)
     {
@@ -705,16 +725,17 @@ public class StructureModel : TreeModel, GLib.Object
 
         insert_item (parent, pos, item);
     }
+    */
 
-    private void append_item (Node<StructData?> parent, StructData item)
+    private TreeIter? append_item (Node<StructData?> parent, StructData item)
     {
-        insert_item (parent, -1, item);
+        return insert_item (parent, -1, item);
     }
 
     // insert the item, and emits the appropriate signals
-    private void insert_item (Node<StructData?> parent, int pos, StructData item)
+    private TreeIter? insert_item (Node<StructData?> parent, int pos, StructData item)
     {
-        return_if_fail (item.text != null);
+        return_val_if_fail (item.text != null, null);
 
         unowned Node<StructData?> new_node = parent.insert_data (pos, item);
         insert_node (new_node);
@@ -723,10 +744,7 @@ public class StructureModel : TreeModel, GLib.Object
         bool append = pos == -1;
         insert_node_in_list (new_node, append);
 
-        // If an end_mark exists, move the items between start_mark and end_mark so this
-        // node is the parent.
-        if (! append)
-            make_children_between_marks (new_node);
+        return create_iter_at_node (new_node);
     }
 
     private void make_children_between_marks (Node<StructData?> node)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]