[latexila] Structure action: shift right
- From: SÃbastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [latexila] Structure action: shift right
- Date: Mon, 4 Jul 2011 23:56:36 +0000 (UTC)
commit 48948a3fe9bce9b89e109f2f7ad1097db140835b
Author: SÃbastien Wilmet <swilmet src gnome org>
Date: Tue Jul 5 01:52:08 2011 +0200
Structure action: shift right
For example we have a chapter with sections, and we want to shift it to
the right: the chapter becomes a section, and the sections become
sub-sections.
What still need to be done:
- show a warning if a subparagraph already exists
- show a warning if the action failed (and undo the changes, if any)
src/document_structure.vala | 102 ++++++++++++++++++++++++++++++++-
src/structure_model.vala | 131 +++++++++++++++++++++++++++++++++----------
2 files changed, 202 insertions(+), 31 deletions(-)
---
diff --git a/src/document_structure.vala b/src/document_structure.vala
index b603e41..44aead1 100644
--- a/src/document_structure.vala
+++ b/src/document_structure.vala
@@ -73,6 +73,8 @@ public class DocumentStructure : GLib.Object
private static const bool _measure_parsing_time = false;
private Timer _timer = null;
+ private static string[] _section_names = null;
+
public bool parsing_done { get; private set; default = false; }
public DocumentStructure (Document doc)
@@ -568,9 +570,18 @@ public class DocumentStructure : GLib.Object
return;
}
- if (action_type == StructAction.SHIFT_LEFT
- || action_type == StructAction.SHIFT_RIGHT)
+ if (action_type == StructAction.SHIFT_LEFT)
+ return;
+
+ if (action_type == StructAction.SHIFT_RIGHT)
+ {
+ _doc.begin_user_action ();
+ shift_right (tree_iter);
+ _doc.end_user_action ();
+
+ _model.shift_right (tree_iter);
return;
+ }
TextIter? start_iter;
TextIter? end_iter;
@@ -893,4 +904,91 @@ public class DocumentStructure : GLib.Object
if (text_between.strip () == "")
iter = begin_line_iter;
}
+
+ private bool shift_right (TreeIter tree_iter)
+ {
+ /* Get some data about the item */
+ StructType type;
+ TextMark mark;
+ _model.get (tree_iter,
+ StructColumn.TYPE, out type,
+ StructColumn.START_MARK, out mark,
+ -1);
+
+ return_val_if_fail (type != StructType.SUBPARAGRAPH, false);
+
+ if (! Structure.is_section (type))
+ return true;
+
+ /* Get the markup name, do some checks, etc. */
+ TextIter text_iter;
+ _doc.get_iter_at_mark (out text_iter, mark);
+
+ int line_num = text_iter.get_line ();
+ string? line = get_document_line_contents (line_num);
+ return_val_if_fail (line != null, false);
+
+ int backslash_index = text_iter.get_line_index ();
+ if (line[backslash_index] != '\\')
+ return false;
+
+ int after_backslash_index = backslash_index + 1;
+ string? markup_name = get_markup_name (line, after_backslash_index);
+ if (markup_name == null)
+ return false;
+
+ /* Get the new markup name */
+ bool with_star = markup_name.has_suffix ("*");
+
+ string? new_markup_name = get_section_name_from_type (type + 1);
+ return_val_if_fail (new_markup_name != null, false);
+
+ if (with_star)
+ new_markup_name += "*";
+
+ /* Replace the markup name */
+ TextIter begin_markup_name_iter;
+ _doc.get_iter_at_line_index (out begin_markup_name_iter, line_num,
+ after_backslash_index);
+
+ TextIter end_markup_name_iter;
+ _doc.get_iter_at_line_index (out end_markup_name_iter, line_num,
+ after_backslash_index + markup_name.length);
+
+ _doc.delete (begin_markup_name_iter, end_markup_name_iter);
+ _doc.insert (begin_markup_name_iter, new_markup_name, -1);
+
+ /* Do the same for all the children */
+ int nb_children = _model.iter_n_children (tree_iter);
+ 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;
+
+ if (! shift_right (child_iter))
+ return false;
+ }
+
+ return true;
+ }
+
+ private string? get_section_name_from_type (StructType type)
+ {
+ if (_section_names == null)
+ {
+ _section_names = new string[7];
+ _section_names[StructType.PART] = "part";
+ _section_names[StructType.CHAPTER] = "chapter";
+ _section_names[StructType.SECTION] = "section";
+ _section_names[StructType.SUBSECTION] = "subsection";
+ _section_names[StructType.SUBSUBSECTION] = "subsubsection";
+ _section_names[StructType.PARAGRAPH] = "paragraph";
+ _section_names[StructType.SUBPARAGRAPH] = "subparagraph";
+ }
+
+ return_val_if_fail (Structure.is_section (type), null);
+
+ return _section_names[type];
+ }
}
diff --git a/src/structure_model.vala b/src/structure_model.vala
index 91b21ba..0dc18f4 100644
--- a/src/structure_model.vala
+++ b/src/structure_model.vala
@@ -460,10 +460,107 @@ public class StructureModel : TreeModel, GLib.Object
{
return_if_fail (iter_is_valid (iter));
- TreePath path = get_path (iter);
unowned Node<StructData?> node = get_node_from_iter (iter);
- node.unlink ();
+ delete_node (node);
+ }
+
+ public void shift_right (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 (type < StructType.SUBPARAGRAPH);
+
+ StructType new_type = type + 1;
+
+ unowned Node<StructData?>? new_parent = node.prev_sibling ();
+ int new_pos;
+
+ if (new_parent == null || new_type <= new_parent.data.type)
+ {
+ new_parent = node.parent;
+ new_pos = new_parent.child_position (node);
+ }
+ else
+ new_pos = -1; // append
+
+ Node<StructData?> node_unlinked = delete_node (node);
+
+ shift_node_right (node_unlinked);
+
+ node = new_parent.insert (new_pos, (owned) node_unlinked);
+ reinsert_node (node);
+ }
+
+ private void insert_node (Node<StructData?> node, bool force_first_child = false)
+ {
+ new_stamp ();
+
+ TreeIter item_iter = create_iter_at_node (node);
+ TreePath item_path = get_path (item_iter);
+ row_inserted (item_path, item_iter);
+
+ // Attention, the row-has-child-toggled signal must be emitted _after_,
+ // else there are strange errors.
+ unowned Node<StructData?> parent = node.parent;
+ bool first_child = parent != _tree && parent.n_children () == 1;
+ if (force_first_child || first_child)
+ {
+ TreeIter parent_iter = create_iter_at_node (parent);
+ TreePath parent_path = get_path (parent_iter);
+ row_has_child_toggled (parent_path, parent_iter);
+ }
+ }
+
+ private Node<StructData?>? delete_node (Node<StructData?> node)
+ {
+ new_stamp ();
+
+ TreeIter? iter = create_iter_at_node (node);
+ return_val_if_fail (iter != null, null);
+
+ TreePath path = get_path (iter);
+ unowned Node<StructData?> parent = node.parent;
+ Node<StructData?> node_unlinked = node.unlink ();
row_deleted (path);
+
+ if (parent != _tree && parent.n_children () == 0)
+ {
+ TreeIter parent_iter = create_iter_at_node (parent);
+ TreePath parent_path = get_path (parent_iter);
+ row_has_child_toggled (parent_path, parent_iter);
+ }
+
+ return node_unlinked;
+ }
+
+ private void shift_node_right (Node<StructData?> node)
+ {
+ if (node.data.type < StructType.SUBPARAGRAPH)
+ node.data.type += 1;
+
+ unowned Node<StructData?>? child = node.first_child ();
+ while (child != null)
+ {
+ shift_node_right (child);
+ child = child.next_sibling ();
+ }
+ }
+
+ private void reinsert_node (Node<StructData?> node, bool force_first_child = false)
+ {
+ insert_node (node, force_first_child);
+
+ unowned Node<StructData?>? child = node.first_child ();
+ bool first_child = true;
+
+ while (child != null)
+ {
+ reinsert_node (child, first_child);
+ child = child.next_sibling ();
+ first_child = false;
+ }
}
private void insert_item_at_position (StructData item, Node<StructData?> parent,
@@ -518,22 +615,7 @@ public class StructureModel : TreeModel, GLib.Object
return_if_fail (item.text != null);
unowned Node<StructData?> new_node = parent.insert_data (pos, item);
-
- new_stamp ();
-
- TreeIter item_iter = create_iter_at_node (new_node);
- TreePath item_path = get_path (item_iter);
- row_inserted (item_path, item_iter);
-
- // Attention, the row-has-child-toggled signal must be emitted _after_,
- // else there are strange errors.
- if (parent != _tree && parent.n_children () == 1)
- {
- TreeIter parent_iter = create_iter_at_node (parent);
- TreePath parent_path = get_path (parent_iter);
- row_has_child_toggled (parent_path, parent_iter);
- }
-
+ insert_node (new_node);
// Store the node to a list, if it's not a section
bool append = pos == -1;
@@ -596,20 +678,11 @@ public class StructureModel : TreeModel, GLib.Object
break;
// unlink the node
- new_stamp ();
- TreePath previous_path = get_path (create_iter_at_node (sibling));
- Node<StructData?> sibling_unlinked = sibling.unlink ();
- row_deleted (previous_path);
+ Node<StructData?> sibling_unlinked = delete_node (sibling);
// append it as a child
- new_stamp ();
unowned Node<StructData?> new_child = node.append ((owned) sibling_unlinked);
-
- TreeIter? new_iter = create_iter_at_node (new_child);
- return_if_fail (new_iter != null);
-
- TreePath new_path = get_path (new_iter);
- row_inserted (new_path, new_iter);
+ insert_node (new_child);
sibling = node.next_sibling ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]