QCodeEdit blockselection patch, ready to use
This commit is contained in:
@@ -30,18 +30,12 @@ public:
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent * e) override {
|
||||
//qDebug() << "paint" << geometry();
|
||||
//QPainter p(this);
|
||||
//p.fillRect(rect(), Qt::red);
|
||||
//QWidget::paintEvent(e);
|
||||
if (!isEnabled()) return;
|
||||
ce->drawCursor();
|
||||
}
|
||||
|
||||
bool event(QEvent * e) override {
|
||||
//qDebug() << "event" << e;
|
||||
return QWidget::event(e);
|
||||
}
|
||||
QCodeEdit * ce;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -157,6 +151,7 @@ QCodeEdit::QCodeEdit(QWidget * parent): QWidget(parent) {
|
||||
connect(ui->textCode, SIGNAL(textChanged()), this, SIGNAL(textChanged()));
|
||||
connect(ui->textCode, SIGNAL(cursorPositionChanged()), this, SLOT(textEdit_cursorPositionChanged()));
|
||||
connect(ui->textCode, SIGNAL(selectionChanged()), this, SLOT(textEdit_selectionChanged()));
|
||||
connect(ui->textCode, SIGNAL(redoAvailable(bool)), this, SLOT(textEdit_redoAvailable(bool)));
|
||||
connect(ui->comboSearch->lineEdit(), SIGNAL(returnPressed()), this, SLOT(searchNext()));
|
||||
connect(ui->comboReplace->lineEdit(), SIGNAL(returnPressed()), this, SLOT(on_buttonReplaceSearch_clicked()));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
@@ -190,6 +185,7 @@ QTextDocument * QCodeEdit::document() const {
|
||||
|
||||
|
||||
void QCodeEdit::setDocument(QTextDocument * doc) {
|
||||
cancelBlockSelection();
|
||||
if (document()) {
|
||||
document()->setProperty("_cursor", QVariant::fromValue(textCursor()));
|
||||
document()->setProperty("_vpos", textEdit()->verticalScrollBar()->value());
|
||||
@@ -454,23 +450,36 @@ bool QCodeEdit::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
if (ui->textCode) {
|
||||
if (o == ui->textCode->viewport()) {
|
||||
if (e->type() == QEvent::MouseButtonPress) {
|
||||
switch (e->type()) {
|
||||
case QEvent::MouseButtonPress: {
|
||||
cancelBlockSelection();
|
||||
completer->hide();
|
||||
hideHelp();
|
||||
QMouseEvent * me = (QMouseEvent*)e;
|
||||
if (me->modifiers().testFlag(Qt::ControlModifier) && (me->button() == Qt::LeftButton)) {
|
||||
if (me->modifiers().testFlag(Qt::ControlModifier) && (me->button() == Qt::LeftButton))
|
||||
gotoLink();
|
||||
}
|
||||
}
|
||||
if (e->type() == QEvent::MouseMove && completer->isHidden()) {
|
||||
} break;
|
||||
case QEvent::MouseMove: {
|
||||
if (!completer->isHidden()) break;
|
||||
QMouseEvent * me = (QMouseEvent*)e;
|
||||
switchBlockSelection();
|
||||
if (me->modifiers().testFlag(Qt::ControlModifier))
|
||||
showLink();
|
||||
}
|
||||
if (e->type() == QEvent::Paint) {
|
||||
} break;
|
||||
case QEvent::Paint:
|
||||
resizeOverlay();
|
||||
break;
|
||||
case QEvent::DragMove:
|
||||
if (!isEnabled()) break;
|
||||
drag_cursor = ui->textCode->cursorForPosition(((QDragMoveEvent*)e)->pos());
|
||||
repaintCursor();
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
case QEvent::DragLeave:
|
||||
case QEvent::Drop:
|
||||
cancelDragCursor();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return QWidget::eventFilter(o, e);
|
||||
}
|
||||
@@ -498,6 +507,9 @@ bool QCodeEdit::eventFilter(QObject * o, QEvent * e) {
|
||||
_ignore_focus_out = false;
|
||||
break;
|
||||
}
|
||||
case QEvent::FocusIn:
|
||||
createBlockSelection();
|
||||
break;
|
||||
case QEvent::Hide:
|
||||
case QEvent::HideToParent:
|
||||
hideLink();
|
||||
@@ -636,7 +648,7 @@ bool QCodeEdit::codeKeyEvent(QKeyEvent * ke) {
|
||||
case Qt::Key_Return:
|
||||
if (hasBlockSelection()) {
|
||||
cancelBlockSelection();
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
if (completer->isVisible()) {
|
||||
commitCompletition();
|
||||
@@ -745,7 +757,8 @@ void QCodeEdit::highlightBrackets() {
|
||||
|
||||
void QCodeEdit::applyExtraSelection() {
|
||||
ui->textCode->setExtraSelections(QList<QTextEdit::ExtraSelection>() << es_line << es_selected
|
||||
<< es_custom << es_brackets << es_search_list << es_cursor << es_link);
|
||||
<< es_custom << es_brackets << es_search_list << es_cursor
|
||||
<< es_link << es_blockselection);
|
||||
}
|
||||
|
||||
|
||||
@@ -774,7 +787,7 @@ int QCodeEdit::searchIndFromCursor() {
|
||||
}
|
||||
|
||||
|
||||
QRect QCodeEdit::cursorRect(QRect * line) {
|
||||
QRect QCodeEdit::cursorRect() {
|
||||
QRect r = ui->textCode->cursorRect(textCursor()), lr = r;
|
||||
if (hasBlockSelection()) {
|
||||
r |= ui->textCode->cursorRect(block_start_cursor);
|
||||
@@ -782,15 +795,14 @@ QRect QCodeEdit::cursorRect(QRect * line) {
|
||||
lr.setHeight(r.height());
|
||||
}
|
||||
lr.setWidth(cursor_width);
|
||||
if (line) *line = lr;
|
||||
return (r | lr);
|
||||
return lr;
|
||||
}
|
||||
|
||||
|
||||
QRect QCodeEdit::blockSelectionRect() {
|
||||
QTextCursor tc = ui->textCode->textCursor();
|
||||
QPoint ps(block_start_cursor.columnNumber(), block_start_cursor.blockNumber()),
|
||||
pe(tc.columnNumber(), tc.blockNumber());
|
||||
QPoint ps(block_start_cursor.positionInBlock(), block_start_cursor.blockNumber()),
|
||||
pe(tc.positionInBlock(), tc.blockNumber());
|
||||
QRect bsr(QPoint(qMin(ps.x(), pe.x()), qMin(ps.y(), pe.y())),
|
||||
QSize(qAbs(ps.x() - pe.x()), qAbs(ps.y() - pe.y()) + 1));
|
||||
return bsr;
|
||||
@@ -803,20 +815,22 @@ void QCodeEdit::repaintCursor() {
|
||||
|
||||
|
||||
void QCodeEdit::drawCursor() {
|
||||
if (!isEnabled() || !ui->textCode->hasFocus()) return;
|
||||
QPainter p(overlay);
|
||||
QTextCursor tc = textCursor();
|
||||
//qDebug() << block_start_cursor.position() << tc.position();
|
||||
QRect line, all = cursorRect(&line);
|
||||
if (hasBlockSelection() && (tc.columnNumber() != block_start_cursor.columnNumber())) {
|
||||
p.setCompositionMode(QPainter::CompositionMode_Difference);
|
||||
QColor hc = palette().color(QPalette::Highlight);
|
||||
p.fillRect(all, QColor(255 - hc.red(), 255 - hc.green(), 255 - hc.blue()));
|
||||
}
|
||||
QRect line = cursorRect();
|
||||
if (cursor_state && ui->textCode->hasFocus()) {
|
||||
line.adjust(0, 1, 0, -1);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Difference);
|
||||
p.fillRect(line, Qt::white);
|
||||
}
|
||||
if (!drag_cursor.isNull()) {
|
||||
line = ui->textCode->cursorRect(drag_cursor);
|
||||
line.setWidth(cursor_width);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Difference);
|
||||
p.fillRect(line, Qt::white);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -830,17 +844,20 @@ void QCodeEdit::startBlockSelection() {
|
||||
QTextCursor tc = textCursor();
|
||||
block_start_cursor = tc;
|
||||
block_start_cursor.setPosition(tc.selectionStart());
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QCodeEdit::cancelBlockSelection() {
|
||||
block_start_cursor = QTextCursor();
|
||||
es_blockselection.clear();
|
||||
applyExtraSelection();
|
||||
}
|
||||
|
||||
|
||||
void QCodeEdit::switchBlockSelection(QKeyEvent * ke) {
|
||||
bool alt = QApplication::keyboardModifiers().testFlag(Qt::AltModifier);
|
||||
if (ke) alt = ke->modifiers().testFlag(Qt::AltModifier);
|
||||
if (ke) alt = ke->modifiers().testFlag(Qt::AltModifier) && ke->modifiers().testFlag(Qt::ShiftModifier);
|
||||
if (alt) {
|
||||
startBlockSelection();
|
||||
QTextCursor tc = ui->textCode->textCursor();
|
||||
@@ -875,10 +892,10 @@ bool QCodeEdit::removeBlockSelection(bool is_del) {
|
||||
//qDebug() << bsr;
|
||||
for (int l = bsr.top(); l <= bsr.bottom(); ++l) {
|
||||
QTextCursor ctc(ui->textCode->document()->findBlockByNumber(l));
|
||||
ctc.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, bsr.left());
|
||||
ctc.setPosition(ctc.block().position() + bsr.left(), QTextCursor::MoveAnchor);
|
||||
if (l != ctc.blockNumber()) continue;
|
||||
int pos = ctc.position();
|
||||
ctc.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, bsr.width());
|
||||
ctc.setPosition(ctc.block().position() + bsr.right() + 1, QTextCursor::KeepAnchor);
|
||||
if (l != ctc.blockNumber()) {
|
||||
ctc.setPosition(pos);
|
||||
ctc.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||
@@ -900,7 +917,7 @@ void QCodeEdit::insertBlockSelection(QString text) {
|
||||
if (bsr.width() > 0) removeBlockSelection(false);
|
||||
for (int l = bsr.top(); l <= bsr.bottom(); ++l) {
|
||||
QTextCursor ctc(ui->textCode->document()->findBlockByNumber(l));
|
||||
ctc.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, bsr.left());
|
||||
ctc.setPosition(ctc.block().position() + bsr.left(), QTextCursor::MoveAnchor);
|
||||
if (l != ctc.blockNumber()) {
|
||||
ctc = QTextCursor(ui->textCode->document()->findBlockByNumber(l));
|
||||
ctc.movePosition(QTextCursor::EndOfLine);
|
||||
@@ -914,6 +931,36 @@ void QCodeEdit::insertBlockSelection(QString text) {
|
||||
}
|
||||
|
||||
|
||||
void QCodeEdit::createBlockSelection() {
|
||||
if (!hasBlockSelection()) return;
|
||||
es_blockselection.clear();
|
||||
QTextEdit::ExtraSelection es;
|
||||
es.format.setForeground(palette().brush(QPalette::HighlightedText));
|
||||
es.format.setBackground(palette().brush(QPalette::Highlight));
|
||||
QRect bsr = blockSelectionRect();
|
||||
for (int l = bsr.top(); l <= bsr.bottom(); ++l) {
|
||||
QTextCursor ctc(ui->textCode->document()->findBlockByNumber(l));
|
||||
ctc.setPosition(ctc.block().position() + bsr.left(), QTextCursor::MoveAnchor);
|
||||
if (l != ctc.blockNumber()) continue;
|
||||
int pos = ctc.position();
|
||||
ctc.setPosition(ctc.block().position() + bsr.right() + 1, QTextCursor::KeepAnchor);
|
||||
if (l != ctc.blockNumber()) {
|
||||
ctc.setPosition(pos);
|
||||
ctc.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||
}
|
||||
es.cursor = ctc;
|
||||
es_blockselection << es;
|
||||
}
|
||||
applyExtraSelection();
|
||||
}
|
||||
|
||||
|
||||
void QCodeEdit::cancelDragCursor() {
|
||||
drag_cursor = QTextCursor();
|
||||
overlay->update();
|
||||
}
|
||||
|
||||
|
||||
void QCodeEdit::searchAll() {
|
||||
QString st = ui->comboSearch->currentText();
|
||||
es_search_list.clear();
|
||||
@@ -1206,7 +1253,6 @@ void QCodeEdit::autoIndent() {
|
||||
QTextCursor tc = ui->textCode->textCursor(), stc = tc;
|
||||
tc.movePosition(QTextCursor::StartOfLine);
|
||||
if (!tc.movePosition(QTextCursor::Up)) return;
|
||||
tc.beginEditBlock();
|
||||
tc.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
|
||||
QString line = tc.selectedText(), tabs;
|
||||
int i = 0;
|
||||
@@ -1220,9 +1266,10 @@ void QCodeEdit::autoIndent() {
|
||||
int nt = qMax<int>(0, line.count(QChar('{')) - line.count(QChar('}')));
|
||||
tabs.append(QString("\t").repeated(nt));
|
||||
if (tabs.isEmpty()) return;
|
||||
stc.beginEditBlock();
|
||||
stc.insertText(tabs);
|
||||
ui->textCode->setTextCursor(stc);
|
||||
tc.endEditBlock();
|
||||
stc.endEditBlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -1641,6 +1688,7 @@ void QCodeEdit::commitCompletition() {
|
||||
|
||||
void QCodeEdit::textEdit_cursorPositionChanged() {
|
||||
es_line.cursor = ui->textCode->textCursor();
|
||||
//qDebug() << "cursorPositionChanged" << es_line.cursor.position();
|
||||
es_line.cursor.select(QTextCursor::LineUnderCursor);
|
||||
es_line.cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
|
||||
highlightBrackets();
|
||||
@@ -1648,7 +1696,7 @@ void QCodeEdit::textEdit_cursorPositionChanged() {
|
||||
if (timer_blink) killTimer(timer_blink);
|
||||
timer_blink = startTimer(QApplication::cursorFlashTime() / 2);
|
||||
cursor_state = true;
|
||||
repaintCursor();
|
||||
createBlockSelection();
|
||||
}
|
||||
|
||||
|
||||
@@ -1690,6 +1738,11 @@ void QCodeEdit::textEdit_selectionChanged() {
|
||||
}
|
||||
|
||||
|
||||
void QCodeEdit::textEdit_redoAvailable(bool available) {
|
||||
if (available) cancelBlockSelection();
|
||||
}
|
||||
|
||||
|
||||
void QCodeEdit::setShowSpaces(bool yes) {
|
||||
spaces_ = yes;
|
||||
QTextOption to = ui->textCode->document()->defaultTextOption();
|
||||
|
||||
Reference in New Issue
Block a user