[latexila] Structure action: shift left



commit c2899c05cbfbad325e59359c380a253dfda7fe55
Author: SÃbastien Wilmet <swilmet src gnome org>
Date:   Wed Jul 6 02:36:18 2011 +0200

    Structure action: shift left
    
    It's a bit more complicated than shift right, since the next siblings
    must also be moved in the structure data.

 TODO                        |    3 --
 src/document_structure.vala |   40 +++++++++++++++-------
 src/structure_model.vala    |   77 +++++++++++++++++++++++++++++++++++++++---
 3 files changed, 99 insertions(+), 21 deletions(-)
---
diff --git a/TODO b/TODO
index f167753..f434dc8 100644
--- a/TODO
+++ b/TODO
@@ -7,9 +7,6 @@ LaTeXila 2.2
 ============
 
 - Structure (list of chapters, sections, etc. to easily navigate in a document):
-	- Right click:
-		- shift left
-
 	- When setting a model, expand all only if the tree is not too big
 
 	- Insert in middle is very slow comparated to insert at the end
diff --git a/src/document_structure.vala b/src/document_structure.vala
index 2d595ec..2fb6392 100644
--- a/src/document_structure.vala
+++ b/src/document_structure.vala
@@ -563,6 +563,8 @@ public class DocumentStructure : GLib.Object
     public void do_action (StructAction action_type, TreeIter tree_iter)
         throws StructError
     {
+        /* Comment */
+
         if (action_type == StructAction.COMMENT)
         {
             if (! comment_item (tree_iter))
@@ -572,18 +574,18 @@ public class DocumentStructure : GLib.Object
             return;
         }
 
-        if (action_type == StructAction.SHIFT_LEFT)
-            return;
+        /* Shift left/right */
 
-        if (action_type == StructAction.SHIFT_RIGHT)
+        bool shift_right = action_type == StructAction.SHIFT_RIGHT;
+        if (shift_right || action_type == StructAction.SHIFT_LEFT)
         {
-            if (_model.item_contains_subparagraph (tree_iter))
+            if (shift_right && _model.item_contains_subparagraph (tree_iter))
                 throw new StructError.GENERAL (
                     _("The structure item already contains a sub-paragraph."));
 
             _doc.begin_user_action ();
             bool doc_modified;
-            bool success = shift_right (tree_iter, out doc_modified);
+            bool success = shift_item (tree_iter, shift_right, out doc_modified);
             _doc.end_user_action ();
 
             if (! success)
@@ -594,7 +596,10 @@ public class DocumentStructure : GLib.Object
                 throw new StructError.DATA_OUTDATED ("");
             }
 
-            _model.shift_right (tree_iter);
+            if (shift_right)
+                _model.shift_right (tree_iter);
+            else
+                _model.shift_left (tree_iter);
             return;
         }
 
@@ -922,7 +927,8 @@ public class DocumentStructure : GLib.Object
             iter = begin_line_iter;
     }
 
-    private bool shift_right (TreeIter tree_iter, out bool doc_modified = null)
+    private bool shift_item (TreeIter tree_iter, bool shift_right,
+        out bool doc_modified = null)
     {
         doc_modified = false;
 
@@ -934,7 +940,10 @@ public class DocumentStructure : GLib.Object
             StructColumn.START_MARK, out mark,
             -1);
 
-        return_val_if_fail (type != StructType.SUBPARAGRAPH, false);
+        if (shift_right)
+            return_val_if_fail (type != StructType.SUBPARAGRAPH, false);
+        else
+            return_val_if_fail (type != StructType.PART, false);
 
         if (! Structure.is_section (type))
             return true;
@@ -968,7 +977,13 @@ public class DocumentStructure : GLib.Object
         /* Get the new markup name */
         bool with_star = markup_name.has_suffix ("*");
 
-        string? new_markup_name = get_section_name_from_type (type + 1);
+        StructType new_type;
+        if (shift_right)
+            new_type = type + 1;
+        else
+            new_type = type - 1;
+
+        string? new_markup_name = get_section_name_from_type (new_type);
         return_val_if_fail (new_markup_name != null, false);
 
         if (with_star)
@@ -992,10 +1007,11 @@ public class DocumentStructure : GLib.Object
         for (int child_num = 0 ; child_num < nb_children ; child_num++)
         {
             TreeIter child_iter;
-            if (! _model.iter_nth_child (out child_iter, tree_iter, child_num))
-                continue;
+            bool child_iter_set = _model.iter_nth_child (out child_iter, tree_iter,
+                child_num);
+            return_val_if_fail (child_iter_set, false);
 
-            if (! shift_right (child_iter))
+            if (! shift_item (child_iter, shift_right))
                 return false;
         }
 
diff --git a/src/structure_model.vala b/src/structure_model.vala
index 7a13eba..0909a19 100644
--- a/src/structure_model.vala
+++ b/src/structure_model.vala
@@ -475,25 +475,82 @@ public class StructureModel : TreeModel, GLib.Object
 
         StructType new_type = type + 1;
 
+        /* Find new position in the tree */
         unowned Node<StructData?>? new_parent = node.prev_sibling ();
         int new_pos;
 
         if (new_parent == null || new_type <= new_parent.data.type)
         {
+            // position unchanged
             new_parent = node.parent;
             new_pos = new_parent.child_position (node);
         }
         else
-            new_pos = -1; // append
+            // append
+            new_pos = -1;
+
+        /* Unlink the node, modify the types and reinsert the node */
 
         Node<StructData?> node_unlinked = delete_node (node);
 
-        shift_node_right (node_unlinked);
+        shift_node (node_unlinked, true);
 
         node = new_parent.insert (new_pos, (owned) node_unlinked);
         reinsert_node (node);
     }
 
+    public void shift_left (TreeIter iter)
+    {
+        return_if_fail (iter_is_valid (iter));
+
+        unowned Node<StructData?> node = get_node_from_iter (iter);
+        StructType type = node.data.type;
+        return_if_fail (StructType.PART < type && type <= StructType.SUBPARAGRAPH);
+
+        StructType new_type = type - 1;
+
+        /* Find new position in the tree */
+        unowned Node<StructData?> new_parent;
+        int new_pos;
+
+        unowned Node<StructData?> parent = node.parent;
+        if (parent == _tree || parent.data.type < new_type)
+        {
+            // position unchanged
+            new_parent = parent;
+            new_pos = parent.child_position (node);
+        }
+        else
+        {
+            new_parent = parent.parent;
+            new_pos = new_parent.child_position (parent) + 1;
+        }
+
+        /* Unlink the node and modify the types */
+        unowned Node<StructData?>? sibling = node.next_sibling ();
+
+        Node<StructData?> node_unlinked = delete_node (node);
+        shift_node (node_unlinked, false);
+
+        /* Next siblings becomes normally children */
+        while (sibling != null)
+        {
+            if (sibling.data.type <= new_type)
+                break;
+
+            unowned Node<StructData?>? next_sibling = sibling.next_sibling ();
+
+            Node<StructData?> new_child = delete_node (sibling);
+            node_unlinked.append ((owned) new_child);
+
+            sibling = next_sibling;
+        }
+
+        /* Reinsert the node */
+        node = new_parent.insert (new_pos, (owned) node_unlinked);
+        reinsert_node (node);
+    }
+
     public bool item_contains_subparagraph (TreeIter iter)
     {
         return_val_if_fail (iter_is_valid (iter), false);
@@ -565,15 +622,23 @@ public class StructureModel : TreeModel, GLib.Object
         return node_unlinked;
     }
 
-    private void shift_node_right (Node<StructData?> node)
+    private void shift_node (Node<StructData?> node, bool shift_right)
     {
-        if (node.data.type < StructType.SUBPARAGRAPH)
-            node.data.type += 1;
+        if (! Structure.is_section (node.data.type))
+            return;
+
+        if (shift_right)
+        {
+            if (node.data.type != StructType.SUBPARAGRAPH)
+                node.data.type += 1;
+        }
+        else if (node.data.type != StructType.PART)
+            node.data.type -= 1;
 
         unowned Node<StructData?>? child = node.first_child ();
         while (child != null)
         {
-            shift_node_right (child);
+            shift_node (child, shift_right);
             child = child.next_sibling ();
         }
     }



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