QCodeEdit blockselection patch, now works with visual instead of position

This commit is contained in:
2020-09-24 19:09:37 +03:00
parent 66f9e76d66
commit 3245d71bc8
2 changed files with 77 additions and 42 deletions

View File

@@ -803,9 +803,28 @@ QRect QCodeEdit::blockSelectionRect() {
QTextCursor tc = ui->textCode->textCursor(); QTextCursor tc = ui->textCode->textCursor();
QPoint ps(block_start_cursor.positionInBlock(), block_start_cursor.blockNumber()), QPoint ps(block_start_cursor.positionInBlock(), block_start_cursor.blockNumber()),
pe(tc.positionInBlock(), tc.blockNumber()); pe(tc.positionInBlock(), tc.blockNumber());
QRect bsr(QPoint(qMin(ps.x(), pe.x()), qMin(ps.y(), pe.y())), //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)); // QSize(qAbs(ps.x() - pe.x()), qAbs(ps.y() - pe.y()) + 1));
return bsr; //return bsr;
return (ui->textCode->cursorRect(tc) | ui->textCode->cursorRect(block_start_cursor))
.translated(ui->textCode->horizontalScrollBar()->value(), 0);
}
QVector<QTextCursor> QCodeEdit::blockSelectionCursors(QRect bsr) {
QVector<QTextCursor> ret;
//qDebug() << bsr;
int sline = ui->textCode->cursorForPosition(bsr.topLeft()).blockNumber();
int eline = ui->textCode->cursorForPosition(bsr.bottomRight()).blockNumber();
for (int l = sline; l <= eline; ++l) {
QTextCursor stc(ui->textCode->document()->findBlockByNumber(l)), etc;
QRect stc_rect = ui->textCode->cursorRect(stc);
stc = ui->textCode->cursorForPosition(stc_rect.center() + QPoint(bsr.left() , 0));
etc = ui->textCode->cursorForPosition(stc_rect.center() + QPoint(bsr.right(), 0));
stc.setPosition(etc.position(), QTextCursor::KeepAnchor);
ret << stc;
}
return ret;
} }
@@ -882,27 +901,38 @@ void QCodeEdit::switchBlockSelection(QKeyEvent * ke) {
bool QCodeEdit::removeBlockSelection(bool is_del) { bool QCodeEdit::removeBlockSelection(bool is_del) {
if (!hasBlockSelection()) return false; if (!hasBlockSelection()) return false;
QRect bsr = blockSelectionRect();
bool del = false, back = false;
if (bsr.width() <= 1) {
if (is_del) del = true;
else back = true;
}
QVector<QTextCursor> clist = blockSelectionCursors(bsr);
QTextCursor tc = ui->textCode->textCursor(); QTextCursor tc = ui->textCode->textCursor();
tc.beginEditBlock(); tc.beginEditBlock();
QRect bsr = blockSelectionRect(); int bspx = ui->textCode->cursorRect(block_start_cursor).center().x();
if (bsr.width() == 0) { int nullw = ui->textCode->fontMetrics().
if (is_del) bsr.setWidth(1); #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
else if (bsr.x() > 0) bsr.setLeft(bsr.x() - 1); horizontalAdvance
#else
width
#endif
(" ");
int min_dist = nullw * 0.5;
int new_pos = -1;
foreach (QTextCursor c, clist) {
if (del || back) {
if (qAbs(bspx - ui->textCode->cursorRect(c).center().x()) > min_dist) continue;
int line = c.blockNumber();
c.movePosition(del ? QTextCursor::Right : QTextCursor::Left, QTextCursor::KeepAnchor);
if (line != c.blockNumber()) continue;
//qDebug() << qAbs(bspx - ui->textCode->cursorRect(c).center().x()) << min_dist;
} }
//qDebug() << bsr; c.removeSelectedText();
for (int l = bsr.top(); l <= bsr.bottom(); ++l) { if (c.blockNumber() == tc.blockNumber())
QTextCursor ctc(ui->textCode->document()->findBlockByNumber(l)); new_pos = c.position();
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);
} }
ctc.removeSelectedText(); tc.setPosition(new_pos);
}
tc.setPosition(tc.block().position() + block_start_cursor.positionInBlock());
ui->textCode->setTextCursor(tc); ui->textCode->setTextCursor(tc);
tc.endEditBlock(); tc.endEditBlock();
return true; return true;
@@ -912,18 +942,31 @@ bool QCodeEdit::removeBlockSelection(bool is_del) {
void QCodeEdit::insertBlockSelection(QString text) { void QCodeEdit::insertBlockSelection(QString text) {
if (!hasBlockSelection()) return; if (!hasBlockSelection()) return;
QTextCursor tc = ui->textCode->textCursor(); QTextCursor tc = ui->textCode->textCursor();
tc.beginEditBlock();
QRect bsr = blockSelectionRect(); QRect bsr = blockSelectionRect();
if (bsr.width() > 0) removeBlockSelection(false); //qDebug() << "___" << bsr;
for (int l = bsr.top(); l <= bsr.bottom(); ++l) { int scrl = ui->textCode->horizontalScrollBar()->value();
QTextCursor ctc(ui->textCode->document()->findBlockByNumber(l)); if (bsr.width() > 1) {
ctc.setPosition(ctc.block().position() + bsr.left(), QTextCursor::MoveAnchor); removeBlockSelection(false);
if (l != ctc.blockNumber()) { bsr = blockSelectionRect();
ctc = QTextCursor(ui->textCode->document()->findBlockByNumber(l)); //qDebug() << "del" << bsr;
ctc.movePosition(QTextCursor::EndOfLine);
ctc.insertText(QString(bsr.left() - ctc.columnNumber(), QChar(' ')));
} }
ctc.insertText(text); tc.beginEditBlock();
//tc.joinPreviousEditBlock();
int nullw = ui->textCode->fontMetrics().
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
horizontalAdvance
#else
width
#endif
(" ");
QVector<QTextCursor> clist = blockSelectionCursors(bsr);
foreach (QTextCursor c, clist) {
c.removeSelectedText();
int spcnt = (bsr.left() - ui->textCode->cursorRect(c).center().x() - scrl) / nullw;
if (spcnt > 0) {
c.insertText(QString(spcnt, QChar(' ')));
}
c.insertText(text);
} }
//tc.setPosition(tc.block().position() + block_start_cursor.positionInBlock()); //tc.setPosition(tc.block().position() + block_start_cursor.positionInBlock());
//ui->textCode->setTextCursor(tc); //ui->textCode->setTextCursor(tc);
@@ -937,18 +980,9 @@ void QCodeEdit::createBlockSelection() {
QTextEdit::ExtraSelection es; QTextEdit::ExtraSelection es;
es.format.setForeground(palette().brush(QPalette::HighlightedText)); es.format.setForeground(palette().brush(QPalette::HighlightedText));
es.format.setBackground(palette().brush(QPalette::Highlight)); es.format.setBackground(palette().brush(QPalette::Highlight));
QRect bsr = blockSelectionRect(); QVector<QTextCursor> clist = blockSelectionCursors(blockSelectionRect());
for (int l = bsr.top(); l <= bsr.bottom(); ++l) { foreach (QTextCursor c, clist) {
QTextCursor ctc(ui->textCode->document()->findBlockByNumber(l)); es.cursor = c;
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; es_blockselection << es;
} }
applyExtraSelection(); applyExtraSelection();

View File

@@ -166,6 +166,7 @@ private:
int searchIndFromCursor(); int searchIndFromCursor();
QRect cursorRect(); QRect cursorRect();
QRect blockSelectionRect(); QRect blockSelectionRect();
QVector<QTextCursor> blockSelectionCursors(QRect bsr);
void repaintCursor(); void repaintCursor();
void drawCursor(); void drawCursor();
bool hasBlockSelection() const; bool hasBlockSelection() const;