public Selection(Book book, SelectionScope scope, List <int> indexes) { this.book = book; this.scope = scope; if (indexes != null) { this.indexes = new List <int>(indexes); } }
public Selection(Book book, SelectionScope scope, List<int> indexes) { this.book = book; this.scope = scope; if (indexes != null) { this.indexes = new List<int>(indexes); } }
/// <summary> /// Removes the selection run from a sequence of runs, merging content with the previous /// and next sibling runs. /// </summary> /// <returns> /// The merged run containing next, run, and previous content /// </returns> /// <remarks> /// The selection run may be either empty or contain content. An empty selection /// represents the insertion text cursor with no range; content represents a selection /// range of a word or phrase. /// /// The SelectionScope is set based on the range type: Empty, Run, Special, or Region /// if there are multiple selections in context, e.g. the Root is higher than an OE. /// </remarks> public XElement Deselect() { SelectionScope = SelectionScope.Unknown; var selections = GetSelections(); var count = selections.Count(); if (count == 0) { return(null); } if (count > 1) { // empty cursor run should be the only selected run; // this can only happen if the given root is not an OE SelectionScope = SelectionScope.Region; return(null); } var cursor = selections.First(); if (!(cursor.FirstNode is XCData cdata)) { // shouldn't happen? return(null); } // A zero length insertion cursor (CDATA[]) is easy to recognize. But OneNote doesn't // provide enough information when the cursor is positioned on a partially or fully // selected hyperlink or XML comment so we can't tell the difference between these // three cases without looking at the CDATA value. Note that XML comments are used // to wrap mathML equations. if (cdata.Value.Length == 0) { cursor = JoinCursorContext(cursor); NormalizeRuns(); SelectionScope = SelectionScope.Empty; } else if (Regex.IsMatch(cdata.Value, @"<a href.+?</a>") || Regex.IsMatch(cdata.Value, @"<!--.+?-->")) { SelectionScope = SelectionScope.Special; } else { // the entire current non-empty run is selected NormalizeRuns(); SelectionScope = SelectionScope.Run; } root.DescendantsAndSelf().Attributes("selected").Remove(); return(cursor); }
public SelectionHistoryItem(Book book, SelectionScope scope, List <int> indexes) : base(book, scope, indexes) { }
private void UpdateNumbersAndDistances(SelectionScope scope) { //////////////////////////////////////////////////////////////////////////////////// // update numbers //////////////////////////////////////////////////////////////////////////////////// int chapter_number = 1; int verse_number = 1; int word_number = 1; int letter_number = 1; if (this.chapters != null) { // update verse/word/letter numbers foreach (Chapter chapter in this.chapters) { chapter.Number = chapter_number++; int verse_number_in_chapter = 1; int word_number_in_chapter = 1; int letter_number_in_chapter = 1; foreach (Verse verse in chapter.Verses) { verse.Number = verse_number++; verse.NumberInChapter = verse_number_in_chapter++; int word_number_in_verse = 1; int letter_number_in_verse = 1; foreach (Word word in verse.Words) { word.Number = word_number++; word.NumberInChapter = word_number_in_chapter++; word.NumberInVerse = word_number_in_verse++; int letter_number_in_word = 1; foreach (Letter letter in word.Letters) { letter.Number = letter_number++; letter.NumberInChapter = letter_number_in_chapter++; letter.NumberInVerse = letter_number_in_verse++; letter.NumberInWord = letter_number_in_word++; } } } } } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// // update positions and distances //////////////////////////////////////////////////////////////////////////////////// // foreach chapter: no repeated chapters so no distances to previous same chapter // foreach verse: calculate distance to its previous occurrence Dictionary<string, int> verse_previous_verse_numbers = new Dictionary<string, int>(); Dictionary<string, int> verse_previous_chapter_numbers = new Dictionary<string, int>(); // foreach word: calculate distance to its previous occurrence Dictionary<string, int> word_previous_word_numbers = new Dictionary<string, int>(); Dictionary<string, int> word_previous_verse_numbers = new Dictionary<string, int>(); Dictionary<string, int> word_previous_chapter_numbers = new Dictionary<string, int>(); // foreach letter: calculate distance to its previous occurrence Dictionary<char, int> letter_previous_letter_numbers = new Dictionary<char, int>(); Dictionary<char, int> letter_previous_word_numbers = new Dictionary<char, int>(); Dictionary<char, int> letter_previous_verse_numbers = new Dictionary<char, int>(); Dictionary<char, int> letter_previous_chapter_numbers = new Dictionary<char, int>(); if (this.chapters != null) { foreach (Chapter chapter in this.chapters) { if (scope == SelectionScope.Chapter) { // there are no repeated chapters so there is no chapter_previous_chapter_numbers to clear verse_previous_verse_numbers.Clear(); verse_previous_chapter_numbers.Clear(); word_previous_word_numbers.Clear(); word_previous_verse_numbers.Clear(); word_previous_chapter_numbers.Clear(); letter_previous_letter_numbers.Clear(); letter_previous_word_numbers.Clear(); letter_previous_verse_numbers.Clear(); letter_previous_chapter_numbers.Clear(); } foreach (Verse verse in chapter.Verses) { string verse_text = verse.Text; if (!verse_previous_verse_numbers.ContainsKey(verse_text)) { verse.DistanceToPrevious.dL = -1; // non-applicable verse.DistanceToPrevious.dW = -1; // non-applicable verse.DistanceToPrevious.dV = 0; verse.DistanceToPrevious.dC = 0; verse_previous_verse_numbers.Add(verse_text, verse.Number); verse_previous_chapter_numbers.Add(verse_text, verse.Chapter.Number); } else { verse.DistanceToPrevious.dL = -1; // non-applicable verse.DistanceToPrevious.dW = -1; // non-applicable verse.DistanceToPrevious.dV = verse.Number - verse_previous_verse_numbers[verse_text]; verse.DistanceToPrevious.dC = verse.Chapter.Number - verse_previous_chapter_numbers[verse_text]; // save latest chapter and verse numbers for next iteration verse_previous_verse_numbers[verse_text] = verse.Number; verse_previous_chapter_numbers[verse_text] = verse.Chapter.Number; } foreach (Word word in verse.Words) { string word_text = word.Text; if (!word_previous_verse_numbers.ContainsKey(word_text)) { word.DistanceToPrevious.dL = -1; // non-applicable word.DistanceToPrevious.dW = 0; word.DistanceToPrevious.dV = 0; word.DistanceToPrevious.dC = 0; word_previous_word_numbers.Add(word_text, word.Number); word_previous_verse_numbers.Add(word_text, word.Verse.Number); word_previous_chapter_numbers.Add(word_text, word.Verse.Chapter.Number); } else { word.DistanceToPrevious.dL = -1; // non-applicable word.DistanceToPrevious.dW = word.Number - word_previous_word_numbers[word_text]; word.DistanceToPrevious.dV = word.Verse.Number - word_previous_verse_numbers[word_text]; word.DistanceToPrevious.dC = word.Verse.Chapter.Number - word_previous_chapter_numbers[word_text]; // save latest chapter, verse and word numbers for next iteration word_previous_word_numbers[word_text] = word.Number; word_previous_verse_numbers[word_text] = word.Verse.Number; word_previous_chapter_numbers[word_text] = word.Verse.Chapter.Number; } foreach (Letter letter in word.Letters) { if (!letter_previous_verse_numbers.ContainsKey(letter.Character)) { letter.DistanceToPrevious.dL = 0; letter.DistanceToPrevious.dW = 0; letter.DistanceToPrevious.dV = 0; letter.DistanceToPrevious.dC = 0; letter_previous_letter_numbers.Add(letter.Character, letter.Number); letter_previous_word_numbers.Add(letter.Character, letter.Word.Number); letter_previous_verse_numbers.Add(letter.Character, letter.Word.Verse.Number); letter_previous_chapter_numbers.Add(letter.Character, letter.Word.Verse.Chapter.Number); } else { letter.DistanceToPrevious.dL = letter.Number - letter_previous_letter_numbers[letter.Character]; letter.DistanceToPrevious.dW = letter.Word.Number - letter_previous_word_numbers[letter.Character]; letter.DistanceToPrevious.dV = letter.Word.Verse.Number - letter_previous_verse_numbers[letter.Character]; letter.DistanceToPrevious.dC = letter.Word.Verse.Chapter.Number - letter_previous_chapter_numbers[letter.Character]; // save latest chapter, verse, word and letter numbers for next iteration letter_previous_letter_numbers[letter.Character] = letter.Number; letter_previous_word_numbers[letter.Character] = letter.Word.Number; letter_previous_verse_numbers[letter.Character] = letter.Word.Verse.Number; letter_previous_chapter_numbers[letter.Character] = letter.Word.Verse.Chapter.Number; } } } } } } //////////////////////////////////////////////////////////////////////////////////// }
public Bookmark GotoBookmark(SelectionScope scope, List<int> indexes) { Bookmark bookmark = GetBookmark(scope, indexes); if (bookmark != null) { m_current_bookmark = bookmark; m_current_bookmark_index = GetBookmarkIndex(bookmark); } return bookmark; }
public Bookmark GetBookmark(SelectionScope scope, List<int> indexes) { if (m_bookmarks != null) { foreach (Bookmark bookmark in m_bookmarks) { if (bookmark.Selection.Scope == scope) { if (bookmark.Selection.Indexes.Count == indexes.Count) { int matching_indexes = 0; for (int i = 0; i < bookmark.Selection.Indexes.Count; i++) { if (bookmark.Selection.Indexes[i] == indexes[i]) { matching_indexes++; } } if (indexes.Count == matching_indexes) { return bookmark; } } } } } return null; }