[latexila] Structure action: select
- From: SÃbastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [latexila] Structure action: select
- Date: Fri, 1 Jul 2011 13:27:36 +0000 (UTC)
commit d9a98db1a09e0a0056df013747047f6a7c85e8fb
Author: SÃbastien Wilmet <swilmet src gnome org>
Date: Thu Jun 30 01:49:10 2011 +0200
Structure action: select
TODO | 16 +++-
src/document_structure.vala | 216 ++++++++++++++++++++++++++++++++++++++++---
src/structure.vala | 1 +
3 files changed, 218 insertions(+), 15 deletions(-)
---
diff --git a/TODO b/TODO
index 5d82ad1..c9fcfd1 100644
--- a/TODO
+++ b/TODO
@@ -8,16 +8,28 @@ LaTeXila 2.2
- Structure (list of chapters, sections, etc. to easily navigate in a document):
- Right click:
- - cut, copy, delete, select
- - comment
+ - cut, copy, delete
+ - comment: remove the item(s) from the model when the item is commented
- shift left
- shift right:
- display a warning if a subparagraph already exists
+ - display a warning if the action fails (most probably when the structure data
+ is not up-to-date)
Shift left/right is new comparated to Kile. For example we have a big section (with
subsections, etc.) and we want to shift it to the left so it becomes a chapter (the
subsections becomes sections, etc.).
+ - 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
+ => Insert environments as soon as we find the \begin, and then update the item (or delete it)
+
+ - Create the TextMarks at the right places with get_iter_at_line_index(),
+ and simplify the code for actions
+
+ - Take into account \end{document}
+
- Write some documentation:
- explain the build tools, how to create a new one, etc.
- the difference between Latexmk and Rubber
diff --git a/src/document_structure.vala b/src/document_structure.vala
index 89a17f1..12a3e0b 100644
--- a/src/document_structure.vala
+++ b/src/document_structure.vala
@@ -159,13 +159,7 @@ public class DocumentStructure : GLib.Object
}
// get the text of the current line
- TextIter next_line_iter;
- if (cur_line == nb_lines - 1)
- _doc.get_end_iter (out next_line_iter);
- else
- _doc.get_iter_at_line (out next_line_iter, cur_line + 1);
-
- string line = _doc.get_text (cur_line_iter, next_line_iter, false);
+ string line = get_document_line_contents (cur_line);
// in one line there could be several items
@@ -188,7 +182,7 @@ public class DocumentStructure : GLib.Object
start_index = end_match_index;
}
- cur_line_iter = next_line_iter;
+ cur_line_iter.forward_line ();
cur_line++;
}
@@ -558,12 +552,20 @@ public class DocumentStructure : GLib.Object
{
if (action_type == StructAction.COMMENT)
{
- do_comment (tree_iter);
+ comment_item (tree_iter);
return;
}
+
+ if (action_type != StructAction.SELECT)
+ return;
+
+ TextIter? start_iter;
+ TextIter? end_iter;
+ if (get_exact_item_bounds (tree_iter, out start_iter, out end_iter))
+ _doc.select_range (start_iter, end_iter);
}
- private void do_comment (TreeIter tree_iter)
+ private void comment_item (TreeIter tree_iter)
{
StructType type;
TextMark start_mark = null;
@@ -586,7 +588,7 @@ public class DocumentStructure : GLib.Object
/* comment a simple item */
if (! Structure.is_section (type))
{
- comment (start_iter, end_iter);
+ comment_between (start_iter, end_iter);
return;
}
@@ -620,11 +622,11 @@ public class DocumentStructure : GLib.Object
end_iter = null;
}
- comment (start_iter, end_iter);
+ comment_between (start_iter, end_iter);
}
// comment the lines between start_iter and end_iter included
- private void comment (TextIter start_iter, TextIter? end_iter)
+ private void comment_between (TextIter start_iter, TextIter? end_iter)
{
int start_line = start_iter.get_line ();
int end_line = start_line;
@@ -641,4 +643,192 @@ public class DocumentStructure : GLib.Object
}
_doc.end_user_action ();
}
+
+ // Returns true only if the bounds are correctly set.
+ private bool get_exact_item_bounds (TreeIter tree_iter, out TextIter? start_iter,
+ out TextIter? end_iter)
+ {
+ /* get item data */
+ StructType item_type;
+ TextMark start_mark = null;
+ TextMark end_mark = null;
+ string item_contents = null;
+
+ _model.get (tree_iter,
+ StructColumn.TYPE, out item_type,
+ StructColumn.START_MARK, out start_mark,
+ StructColumn.END_MARK, out end_mark,
+ StructColumn.TEXT, out item_contents,
+ -1);
+
+ /* search 'start_iter' */
+ TextIter line_iter;
+ _doc.get_iter_at_mark (out line_iter, start_mark);
+ int line_num = line_iter.get_line ();
+
+ int? start_match_index;
+ int? end_match_index;
+
+ bool found = get_low_level_item_bounds (item_type, item_contents, line_num, true,
+ out start_match_index, out end_match_index);
+
+ if (! found)
+ return false;
+
+ // set 'start_iter'
+ _doc.get_iter_at_line_index (out start_iter, line_num, start_match_index);
+
+ /* search 'end_iter' */
+
+ // a section
+ if (Structure.is_section (item_type))
+ {
+ TreeIter? next_section_iter = null;
+ try
+ {
+ next_section_iter = _model.get_next_sibling_or_parent (tree_iter);
+ }
+ catch (StructError e)
+ {
+ stderr.printf ("Structure: get next sibling or parent: %s\n", e.message);
+ return false;
+ }
+
+ // the end of the section is the end of the document
+ if (next_section_iter == null)
+ {
+ _doc.get_end_iter (out end_iter);
+ return true;
+ }
+
+ _model.get (next_section_iter,
+ StructColumn.TYPE, out item_type,
+ StructColumn.START_MARK, out start_mark,
+ StructColumn.TEXT, out item_contents,
+ -1);
+
+ _doc.get_iter_at_mark (out line_iter, start_mark);
+ line_num = line_iter.get_line ();
+
+ found = get_low_level_item_bounds (item_type, item_contents, line_num, true,
+ out start_match_index, null);
+
+ if (! found)
+ return false;
+
+ _doc.get_iter_at_line_index (out end_iter, line_num, start_match_index);
+ return true;
+ }
+
+ // an other common type
+ else if (item_type < StructType.NB_COMMON_TYPES)
+ {
+ _doc.get_iter_at_line_index (out end_iter, line_num, end_match_index);
+ return true;
+ }
+
+ // an environment
+ if (end_mark == null)
+ return false;
+
+ _doc.get_iter_at_mark (out line_iter, end_mark);
+ line_num = line_iter.get_line ();
+
+ found = get_low_level_item_bounds (item_type, item_contents, line_num, false,
+ null, out end_match_index);
+
+ if (! found)
+ return false;
+
+ _doc.get_iter_at_line_index (out end_iter, line_num, end_match_index);
+
+ return true;
+ }
+
+ private bool get_low_level_item_bounds (StructType item_type, string item_contents,
+ int line_num, bool is_start, out int? start_match_index, out int? end_match_index)
+ {
+ string line = get_document_line_contents (line_num);
+
+ /* parse the line */
+ int start_index = 0;
+ int line_length = line.length;
+
+ while (true)
+ {
+ if (line_length <= start_index)
+ break;
+
+ LowLevelType? low_level_type;
+ string? contents;
+
+ bool found = search_low_level_item (line, start_index, out low_level_type,
+ out contents, out start_match_index, out end_match_index);
+
+ if (! found)
+ break;
+
+ if (contents == null)
+ contents = "";
+
+ // compare the item found with the structure item
+ if (same_items (item_type, item_contents, low_level_type, contents, is_start))
+ return true;
+
+ start_index = end_match_index;
+ }
+
+ return false;
+ }
+
+ // Compare a structure item with another low-level item
+ // If 'start' is true, and if the structure item is an environment, a \begin{} is
+ // expected. Otherwise, a \end{} is expected.
+ private bool same_items (StructType item_type, string item_contents,
+ LowLevelType item_found_type, string item_found_contents, bool start)
+ {
+ if (item_found_type < LowLevelType.NB_COMMON_TYPES)
+ {
+ bool same_type = item_type == (StructType) item_found_type;
+ bool same_contents = item_contents == item_found_contents;
+ return same_type && same_contents;
+ }
+
+ if (item_type == StructType.FIGURE)
+ {
+ if (start)
+ return item_found_type == LowLevelType.BEGIN_FIGURE;
+ else
+ return item_found_type == LowLevelType.END_FIGURE;
+ }
+
+ if (item_type == StructType.TABLE)
+ {
+ if (start)
+ return item_found_type == LowLevelType.BEGIN_TABLE;
+ else
+ return item_found_type == LowLevelType.END_TABLE;
+ }
+
+ return false;
+ }
+
+ private string? get_document_line_contents (int line_num)
+ {
+ int nb_lines = _doc.get_line_count ();
+ return_val_if_fail (0 <= line_num && line_num < nb_lines, null);
+
+ TextIter begin;
+ _doc.get_iter_at_line (out begin, line_num);
+
+ // If the line is empty, and if we do a forward_to_line_end(), we go to the end of
+ // the _next_ line, so we must handle this special case.
+ if (begin.ends_line ())
+ return "";
+
+ TextIter end = begin;
+ end.forward_to_line_end ();
+
+ return _doc.get_text (begin, end, false);
+ }
}
diff --git a/src/structure.vala b/src/structure.vala
index ead6d42..968aebc 100644
--- a/src/structure.vala
+++ b/src/structure.vala
@@ -35,6 +35,7 @@ public enum StructType
IMAGE,
TODO,
FIXME,
+ NB_COMMON_TYPES,
// Second part: "high-level" only
TABLE,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]