From efb071e3f74cefeaf1b085a4db6bbdb2d014ab31 Mon Sep 17 00:00:00 2001 From: Bryan Tan Date: Wed, 29 May 2019 23:09:50 -0700 Subject: [PATCH] Properly implement text editor paragraph-on-cursor selection --- src/gui/TextEditor.cpp | 52 +++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/gui/TextEditor.cpp b/src/gui/TextEditor.cpp index c1187f6a..2ff3a989 100644 --- a/src/gui/TextEditor.cpp +++ b/src/gui/TextEditor.cpp @@ -454,20 +454,21 @@ void TextEditor::selectAtCursor(TextEditor::SelectType ty) XOJ_CHECK_TYPE(TextEditor); GtkTextMark* mark = gtk_text_buffer_get_insert(this->buffer); - GtkTextIter currentPos; - gtk_text_buffer_get_iter_at_mark(this->buffer, ¤tPos, mark); - - // Only process double click - if (!gtk_text_iter_inside_word(¤tPos)) - { - return; - } - - GtkTextIter startPos = currentPos; - GtkTextIter endPos = currentPos; + GtkTextIter startPos; + GtkTextIter endPos; + gtk_text_buffer_get_selection_bounds(this->buffer, &startPos, &endPos); + const auto searchFlag = GTK_TEXT_SEARCH_TEXT_ONLY; // To be used to find double newlines switch(ty) { case TextEditor::SelectType::word: + // Do nothing if cursor is over whitespace + GtkTextIter currentPos; + gtk_text_buffer_get_iter_at_mark(this->buffer, ¤tPos, mark); + if (!gtk_text_iter_inside_word(¤tPos)) + { + return; + } + if (!gtk_text_iter_starts_word(¤tPos)) { gtk_text_iter_backward_word_start(&startPos); @@ -478,13 +479,38 @@ void TextEditor::selectAtCursor(TextEditor::SelectType ty) } break; case TextEditor::SelectType::paragraph: - if (!gtk_text_iter_starts_line(¤tPos)) + // Note that a GTK "paragraph" is a line, so there's no nice one-liner. + // We define a paragraph as text separated by double newlines. + while (!gtk_text_iter_is_start(&startPos)) { + // There's no GTK function to go to line start, so do it manually. + while (!gtk_text_iter_starts_line(&startPos)) + { + if (!gtk_text_iter_backward_word_start(&startPos)) + { + break; + } + } + // Check for paragraph start + GtkTextIter searchPos = startPos; + gtk_text_iter_backward_chars(&searchPos, 2); + if (gtk_text_iter_backward_search(&startPos, "\n\n", searchFlag, nullptr, nullptr, &searchPos)) + { + break; + } gtk_text_iter_backward_line(&startPos); } - if (!gtk_text_iter_ends_line(¤tPos)) + while (!gtk_text_iter_ends_line(&endPos)) { gtk_text_iter_forward_to_line_end(&endPos); + // Check for paragraph end + GtkTextIter searchPos = endPos; + gtk_text_iter_forward_chars(&searchPos, 2); + if (gtk_text_iter_forward_search(&endPos, "\n\n", searchFlag, nullptr, nullptr, &searchPos)) + { + break; + } + gtk_text_iter_forward_line(&endPos); } break; case TextEditor::SelectType::all: