From aa906610b403fbd677920a3a397cbb406406b4d0 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 7 Oct 2020 21:38:16 +0300 Subject: [PATCH] QCodeEdit now can comment/uncomment on ctrl+/ --- libs/widgets/qcodeedit.cpp | 79 +++++++++++++++++++++++++++++++++++++- libs/widgets/qcodeedit.h | 4 ++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/libs/widgets/qcodeedit.cpp b/libs/widgets/qcodeedit.cpp index 53bbf99..0acae0b 100644 --- a/libs/widgets/qcodeedit.cpp +++ b/libs/widgets/qcodeedit.cpp @@ -45,6 +45,7 @@ QCodeEdit::QCodeEdit(QWidget * parent): QWidget(parent) { timer_parse = 0; _ignore_focus_out = _destructor = _replacing = cursor_state = block_sel_state = false; _first = true; + comment_text = "//"; qRegisterMetaType(); qRegisterMetaType(); ui = new Ui::QCodeEdit(); @@ -279,6 +280,16 @@ bool QCodeEdit::isHelpHintVisible() const { } +QString QCodeEdit::commentText() const { + return comment_text; +} + + +void QCodeEdit::setCommentText(QString t) { + comment_text = t; +} + + void QCodeEdit::setEditorFont(QFont f) { ui->textCode->setFont(f); ui->textLines->setFont(f); @@ -577,6 +588,12 @@ bool QCodeEdit::codeKeyEvent(QKeyEvent * ke) { return true; } break; + case Qt::Key_Slash: + if (ke->modifiers().testFlag(Qt::ControlModifier)) { + toggleComment(); + return true; + } + break; case Qt::Key_Escape: hideHelp(); if (completer->isVisible()) @@ -683,7 +700,7 @@ bool QCodeEdit::codeKeyEvent(QKeyEvent * ke) { default: break; } if (!ke->text().isEmpty()) { - if (hasBlockSelection() && (ke->modifiers() == 0 || ke->modifiers() == Qt::ShiftModifier)) { + if (hasBlockSelection() && (ke->modifiers() == 0 || ke->modifiers() == Qt::ShiftModifier || ke->modifiers() == Qt::KeypadModifier)) { insertBlockSelection(ke->text()); return true; } @@ -700,6 +717,66 @@ bool QCodeEdit::codeKeyEvent(QKeyEvent * ke) { } +void QCodeEdit::toggleComment() { + QTextCursor tc = ui->textCode->textCursor(); + tc.beginEditBlock(); + int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se; + QString st_ = tc.selection().toPlainText(); + if (st_.endsWith("\n")) { + st_.chop(1); + se--; se_--; + } + tc.setPosition(ss); tc.movePosition(QTextCursor::StartOfLine); ss = tc.position(); + tc.setPosition(se); tc.movePosition(QTextCursor::EndOfLine ); se = tc.position(); + tc.setPosition(ss); + bool need_comment = false; + QMap comms; + while (tc.position() <= se_) { + int line = tc.blockNumber(); + tc.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, comment_text.size()); + if (line == tc.blockNumber()) { + if (tc.selectedText() == comment_text) { + comms[line] = true; + } else { + need_comment = true; + comms[line] = false; + } + } else + comms[line] = false; + tc.movePosition(QTextCursor::StartOfLine); + if (!tc.movePosition(QTextCursor::Down)) + break; + } + tc.setPosition(ss); + bool first = true; + while (tc.position() <= se_) { + int line = tc.blockNumber(); + if (need_comment) { + if (!comms[line]) { + tc.insertText("//"); + se_ += comment_text.size(); + if (first) ss_ += comment_text.size(); + } + } else { + if (comms[line]) { + tc.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, comment_text.size()); + tc.removeSelectedText(); + se_ -= comment_text.size(); + if (first) ss_ -= comment_text.size(); + } + } + first = false; + tc.movePosition(QTextCursor::StartOfLine); + if (!tc.movePosition(QTextCursor::Down)) + break; + } + tc.setPosition(ss_); + tc.setPosition(se_, QTextCursor::KeepAnchor); + ui->textCode->setTextCursor(tc); + tc.endEditBlock(); +} + + char antiBracket(char c) { switch (c) { case '(': return ')'; diff --git a/libs/widgets/qcodeedit.h b/libs/widgets/qcodeedit.h index 89908c8..ee7dc63 100644 --- a/libs/widgets/qcodeedit.h +++ b/libs/widgets/qcodeedit.h @@ -89,6 +89,8 @@ public: bool showLineNumbers() const; void setHelpHintVisible(bool on); bool isHelpHintVisible() const; + QString commentText() const; + void setCommentText(QString t); void setEditorFont(QFont f); QFont editorFont() const; @@ -146,6 +148,7 @@ private: QList es_selected, es_custom, es_brackets, es_search_list, es_blockselection; QMap ac_classes; QStringList cursor_scope; + QString comment_text; ACEntry link_entry, help_entry; QTextCursor block_start_cursor, drag_cursor; int prev_lc, auto_comp_pl, timer_parse, timer_blink, cur_search_ind, pos_press, pos_el_press; @@ -159,6 +162,7 @@ private: void leaveEvent(QEvent * ) override; void changeEvent(QEvent * e) override; bool codeKeyEvent(QKeyEvent * ke); + void toggleComment(); void highlightBrackets(); void applyExtraSelection(); void clearSearch();