From bb58ab34c17d7153cdf1df727e9bb2b7529991b9 Mon Sep 17 00:00:00 2001 From: Serhii Moroz Date: Sun, 13 Aug 2017 20:38:08 +0300 Subject: [PATCH] TextEditor: Add sortSelectedLines action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ifdc82766bac3cfe2e9c287b4ef04902a943c8f72 Reviewed-by: André Hartmann --- src/plugins/texteditor/texteditor.cpp | 43 +++++++++++++++++++ src/plugins/texteditor/texteditor.h | 2 + .../texteditor/texteditoractionhandler.cpp | 6 +++ src/plugins/texteditor/texteditorconstants.h | 1 + 4 files changed, 52 insertions(+) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 44318208613..c39bf0227ee 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -154,6 +154,7 @@ namespace Internal { enum { NExtraSelectionKinds = 12 }; typedef QString (TransformationMethod)(const QString &); +typedef void (ListTransformationMethod)(QStringList &); static QString QString_toUpper(const QString &str) { @@ -419,6 +420,8 @@ public: void transformSelection(TransformationMethod method); void transformBlockSelection(TransformationMethod method); + void transformSelectedLines(ListTransformationMethod method); + void slotUpdateExtraAreaWidth(); void slotUpdateRequest(const QRect &r, int dy); void slotUpdateBlockNotify(const QTextBlock &); @@ -1616,6 +1619,11 @@ void TextEditorWidget::lowercaseSelection() d->transformSelection(&QString_toLower); } +void TextEditorWidget::sortSelectedLines() +{ + d->transformSelectedLines([](QStringList &list) { list.sort(); }); +} + void TextEditorWidget::indent() { int offset = 0; @@ -7893,6 +7901,41 @@ void TextEditorWidgetPrivate::transformBlockSelection(TransformationMethod metho enableBlockSelection(positionBlock, anchorColumn, anchorBlock, positionColumn); } +void TextEditorWidgetPrivate::transformSelectedLines(ListTransformationMethod method) +{ + if (!method || q->hasBlockSelection()) + return; + + QTextCursor cursor = q->textCursor(); + if (!cursor.hasSelection()) + return; + + const bool downwardDirection = cursor.anchor() < cursor.position(); + int startPosition = cursor.selectionStart(); + int endPosition = cursor.selectionEnd(); + + cursor.setPosition(startPosition); + cursor.movePosition(QTextCursor::StartOfBlock); + startPosition = cursor.position(); + + cursor.setPosition(endPosition, QTextCursor::KeepAnchor); + if (cursor.positionInBlock() == 0) + cursor.movePosition(QTextCursor::PreviousBlock, QTextCursor::KeepAnchor); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + endPosition = qMax(cursor.position(), endPosition); + + const QString text = cursor.selectedText(); + QStringList lines = text.split(QChar::ParagraphSeparator); + method(lines); + cursor.insertText(lines.join(QChar::ParagraphSeparator)); + + // (re)select the changed lines + // Note: this assumes the transformation did not change the length + cursor.setPosition(downwardDirection ? startPosition : endPosition); + cursor.setPosition(downwardDirection ? endPosition : startPosition, QTextCursor::KeepAnchor); + q->setTextCursor(cursor); +} + void TextEditorWidget::inSnippetMode(bool *active) { *active = d->m_snippetOverlay->isVisible(); diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index f6fb8644045..b5365ad3279 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -423,6 +423,8 @@ public: void uppercaseSelection(); void lowercaseSelection(); + void sortSelectedLines(); + void cleanWhitespace(); void indent(); diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index 35c7d5e2850..e1e0962f9fd 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -176,6 +176,7 @@ public: QAction *m_insertLineBelowAction = nullptr; QAction *m_upperCaseSelectionAction = nullptr; QAction *m_lowerCaseSelectionAction = nullptr; + QAction *m_sortSelectedLinesAction = nullptr; QAction *m_indentAction = nullptr; QAction *m_unindentAction = nullptr; QAction *m_followSymbolAction = nullptr; @@ -382,6 +383,10 @@ void TextEditorActionHandlerPrivate::createActions() [] (TextEditorWidget *w) { w->lowercaseSelection(); }, true, tr("Lowercase Selection"), QKeySequence(Core::UseMacShortcuts ? tr("Meta+U") : tr("Alt+U")), G_EDIT_TEXT, advancedEditMenu); + m_sortSelectedLinesAction = registerAction(SORT_SELECTED_LINES, + [this] (TextEditorWidget *w) { w->sortSelectedLines(); }, false, tr("&Sort Selected Lines"), + QKeySequence(Core::UseMacShortcuts ? tr("Meta+Shift+S") : tr("Alt+Shift+S")), + G_EDIT_TEXT, advancedEditMenu); m_foldAction = registerAction(FOLD, [] (TextEditorWidget *w) { w->fold(); }, true, tr("Fold"), QKeySequence(tr("Ctrl+<")), @@ -500,6 +505,7 @@ void TextEditorActionHandlerPrivate::createActions() m_modifyingActions << m_unCommentSelectionAction; m_modifyingActions << m_unindentAction; m_modifyingActions << m_upperCaseSelectionAction; + m_modifyingActions << m_sortSelectedLinesAction; // set enabled state of optional actions m_followSymbolAction->setEnabled(m_optionalActions & TextEditorActionHandler::FollowSymbolUnderCursor); diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index af565243620..8cf692d022a 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -143,6 +143,7 @@ const char INSERT_LINE_ABOVE[] = "TextEditor.InsertLineAboveCurrentLine"; const char INSERT_LINE_BELOW[] = "TextEditor.InsertLineBelowCurrentLine"; const char UPPERCASE_SELECTION[] = "TextEditor.UppercaseSelection"; const char LOWERCASE_SELECTION[] = "TextEditor.LowercaseSelection"; +const char SORT_SELECTED_LINES[] = "TextEditor.SortSelectedLines"; const char CUT_LINE[] = "TextEditor.CutLine"; const char COPY_LINE[] = "TextEditor.CopyLine"; const char DUPLICATE_SELECTION[] = "TextEditor.DuplicateSelection";