QCodeEdit blockselection almost works, without copypaste and with bad visual
This commit is contained in:
@@ -49,7 +49,7 @@ QCodeEdit::QCodeEdit(QWidget * parent): QWidget(parent) {
|
|||||||
overlay = 0;
|
overlay = 0;
|
||||||
prev_lc = auto_comp_pl = cur_search_ind = pos_press = pos_el_press = -1;
|
prev_lc = auto_comp_pl = cur_search_ind = pos_press = pos_el_press = -1;
|
||||||
timer_parse = 0;
|
timer_parse = 0;
|
||||||
_ignore_focus_out = _destructor = _replacing = cursor_state = false;
|
_ignore_focus_out = _destructor = _replacing = cursor_state = block_sel_state = false;
|
||||||
_first = true;
|
_first = true;
|
||||||
qRegisterMetaType<QTextCursor>();
|
qRegisterMetaType<QTextCursor>();
|
||||||
qRegisterMetaType<QCodeEdit::ACEntry>();
|
qRegisterMetaType<QCodeEdit::ACEntry>();
|
||||||
@@ -454,21 +454,20 @@ bool QCodeEdit::eventFilter(QObject * o, QEvent * e) {
|
|||||||
if (ui->textCode) {
|
if (ui->textCode) {
|
||||||
if (o == ui->textCode->viewport()) {
|
if (o == ui->textCode->viewport()) {
|
||||||
if (e->type() == QEvent::MouseButtonPress) {
|
if (e->type() == QEvent::MouseButtonPress) {
|
||||||
|
cancelBlockSelection();
|
||||||
completer->hide();
|
completer->hide();
|
||||||
hideHelp();
|
hideHelp();
|
||||||
}
|
|
||||||
if (e->type() == QEvent::MouseMove && completer->isHidden()) {
|
|
||||||
QMouseEvent * me = (QMouseEvent*)e;
|
|
||||||
if (me->modifiers().testFlag(Qt::ControlModifier)) {
|
|
||||||
showLink();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (e->type() == QEvent::MouseButtonPress) {
|
|
||||||
QMouseEvent * me = (QMouseEvent*)e;
|
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();
|
gotoLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (e->type() == QEvent::MouseMove && completer->isHidden()) {
|
||||||
|
QMouseEvent * me = (QMouseEvent*)e;
|
||||||
|
switchBlockSelection();
|
||||||
|
if (me->modifiers().testFlag(Qt::ControlModifier))
|
||||||
|
showLink();
|
||||||
|
}
|
||||||
if (e->type() == QEvent::Paint) {
|
if (e->type() == QEvent::Paint) {
|
||||||
resizeOverlay();
|
resizeOverlay();
|
||||||
}
|
}
|
||||||
@@ -477,8 +476,6 @@ bool QCodeEdit::eventFilter(QObject * o, QEvent * e) {
|
|||||||
if (o == ui->textCode) {
|
if (o == ui->textCode) {
|
||||||
//qDebug() << e;
|
//qDebug() << e;
|
||||||
QMetaObject::invokeMethod(this, "syncScrolls", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(this, "syncScrolls", Qt::QueuedConnection);
|
||||||
QKeyEvent * ke;
|
|
||||||
QChar kc(0);
|
|
||||||
switch (e->type()) {
|
switch (e->type()) {
|
||||||
case QEvent::ToolTip:
|
case QEvent::ToolTip:
|
||||||
if (completer->isHidden()) {
|
if (completer->isHidden()) {
|
||||||
@@ -488,112 +485,9 @@ bool QCodeEdit::eventFilter(QObject * o, QEvent * e) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QEvent::KeyPress:
|
case QEvent::KeyPress:
|
||||||
ke = (QKeyEvent * )e;
|
|
||||||
//qDebug() << "key" << ke;
|
//qDebug() << "key" << ke;
|
||||||
switch (ke->key()) {
|
if (codeKeyEvent((QKeyEvent * )e))
|
||||||
case Qt::Key_Space:
|
return true;
|
||||||
if (ke->modifiers().testFlag(Qt::ControlModifier)) {
|
|
||||||
invokeAutoCompletition(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_Escape:
|
|
||||||
hideHelp();
|
|
||||||
if (completer->isVisible())
|
|
||||||
completer->hide();
|
|
||||||
else
|
|
||||||
hideSearch();
|
|
||||||
break;
|
|
||||||
case Qt::Key_Up:
|
|
||||||
if (completer->isVisible()) {
|
|
||||||
completer->previousCompletition();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
completer->hide();
|
|
||||||
hideHelp();
|
|
||||||
if (ke->modifiers().testFlag(Qt::AltModifier)) {
|
|
||||||
copyLineUp();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ke->modifiers().testFlag(Qt::ControlModifier) && ke->modifiers().testFlag(Qt::ShiftModifier)) {
|
|
||||||
moveLineUp();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_Down:
|
|
||||||
if (completer->isVisible()) {
|
|
||||||
completer->nextCompletition();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
completer->hide();
|
|
||||||
hideHelp();
|
|
||||||
if (ke->modifiers().testFlag(Qt::AltModifier)) {
|
|
||||||
copyLineDown();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ke->modifiers().testFlag(Qt::ControlModifier) && ke->modifiers().testFlag(Qt::ShiftModifier)) {
|
|
||||||
moveLineDown();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_Home:
|
|
||||||
case Qt::Key_End:
|
|
||||||
case Qt::Key_PageUp:
|
|
||||||
case Qt::Key_PageDown:
|
|
||||||
if (completer->isVisible()) {
|
|
||||||
qApp->sendEvent(completer, new QKeyEvent(e->type(), ke->key(), ke->modifiers()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_Left:
|
|
||||||
case Qt::Key_Right:
|
|
||||||
case Qt::Key_Backspace:
|
|
||||||
case Qt::Key_Delete:
|
|
||||||
if (completer->isVisible())
|
|
||||||
QMetaObject::invokeMethod(this, "invokeAutoCompletition", Qt::QueuedConnection, Q_ARG(bool, false));
|
|
||||||
break;
|
|
||||||
case Qt::Key_Return:
|
|
||||||
if (completer->isVisible()) {
|
|
||||||
commitCompletition();
|
|
||||||
completer->hide();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ui->textCode->textCursor().selectedText().isEmpty())
|
|
||||||
QMetaObject::invokeMethod(this, "autoIndent", Qt::QueuedConnection);
|
|
||||||
break;
|
|
||||||
case Qt::Key_Tab:
|
|
||||||
if (!ui->textCode->textCursor().selectedText().isEmpty()) {
|
|
||||||
if (ke->modifiers().testFlag(Qt::ShiftModifier))
|
|
||||||
deindent();
|
|
||||||
else
|
|
||||||
indent();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_D:
|
|
||||||
if (ke->modifiers().testFlag(Qt::ControlModifier)) {
|
|
||||||
completer->hide();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_Control:
|
|
||||||
showLink();
|
|
||||||
break;
|
|
||||||
case Qt::Key_F1:
|
|
||||||
if (widget_help->isVisible())
|
|
||||||
gotoHelpHRef(help_entry);
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
if (!ke->text().isEmpty())
|
|
||||||
kc = ke->text()[0];
|
|
||||||
if (kc == '.') {
|
|
||||||
completer->hide();
|
|
||||||
QMetaObject::invokeMethod(this, "invokeAutoCompletition", Qt::QueuedConnection, Q_ARG(bool, false));
|
|
||||||
} else {
|
|
||||||
if ((kc.isLetterOrNumber() || kc.toLatin1() == '_') && completer->isVisible())
|
|
||||||
QMetaObject::invokeMethod(this, "invokeAutoCompletition", Qt::QueuedConnection, Q_ARG(bool, false));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case QEvent::KeyRelease:
|
case QEvent::KeyRelease:
|
||||||
hideLink();
|
hideLink();
|
||||||
@@ -661,6 +555,138 @@ void QCodeEdit::changeEvent(QEvent * e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QCodeEdit::codeKeyEvent(QKeyEvent * ke) {
|
||||||
|
QChar kc;
|
||||||
|
switch (ke->key()) {
|
||||||
|
case Qt::Key_Space:
|
||||||
|
if (ke->modifiers().testFlag(Qt::ControlModifier)) {
|
||||||
|
invokeAutoCompletition(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_Escape:
|
||||||
|
hideHelp();
|
||||||
|
if (completer->isVisible())
|
||||||
|
completer->hide();
|
||||||
|
else
|
||||||
|
hideSearch();
|
||||||
|
break;
|
||||||
|
case Qt::Key_Up:
|
||||||
|
switchBlockSelection(ke);
|
||||||
|
if (completer->isVisible()) {
|
||||||
|
completer->previousCompletition();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
completer->hide();
|
||||||
|
hideHelp();
|
||||||
|
if (ke->modifiers().testFlag(Qt::AltModifier)) {
|
||||||
|
if (ke->modifiers().testFlag(Qt::ShiftModifier))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
copyLineUp();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ke->modifiers().testFlag(Qt::ControlModifier) && ke->modifiers().testFlag(Qt::ShiftModifier)) {
|
||||||
|
moveLineUp();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_Down:
|
||||||
|
switchBlockSelection(ke);
|
||||||
|
if (completer->isVisible()) {
|
||||||
|
completer->nextCompletition();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
completer->hide();
|
||||||
|
hideHelp();
|
||||||
|
if (ke->modifiers().testFlag(Qt::AltModifier)) {
|
||||||
|
if (ke->modifiers().testFlag(Qt::ShiftModifier))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
copyLineDown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ke->modifiers().testFlag(Qt::ControlModifier) && ke->modifiers().testFlag(Qt::ShiftModifier)) {
|
||||||
|
moveLineDown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_Home:
|
||||||
|
case Qt::Key_End:
|
||||||
|
case Qt::Key_PageUp:
|
||||||
|
case Qt::Key_PageDown:
|
||||||
|
switchBlockSelection(ke);
|
||||||
|
if (completer->isVisible()) {
|
||||||
|
qApp->sendEvent(completer, new QKeyEvent(ke->type(), ke->key(), ke->modifiers()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_Left:
|
||||||
|
case Qt::Key_Right:
|
||||||
|
switchBlockSelection(ke);
|
||||||
|
if (hasBlockSelection()) break;
|
||||||
|
case Qt::Key_Backspace:
|
||||||
|
case Qt::Key_Delete:
|
||||||
|
if (completer->isVisible())
|
||||||
|
QMetaObject::invokeMethod(this, "invokeAutoCompletition", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||||
|
if (removeBlockSelection(ke->key() == Qt::Key_Delete))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case Qt::Key_Return:
|
||||||
|
if (hasBlockSelection()) {
|
||||||
|
cancelBlockSelection();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (completer->isVisible()) {
|
||||||
|
commitCompletition();
|
||||||
|
completer->hide();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ui->textCode->textCursor().selectedText().isEmpty())
|
||||||
|
QMetaObject::invokeMethod(this, "autoIndent", Qt::QueuedConnection);
|
||||||
|
break;
|
||||||
|
case Qt::Key_Tab:
|
||||||
|
if (!ui->textCode->textCursor().selectedText().isEmpty()) {
|
||||||
|
if (ke->modifiers().testFlag(Qt::ShiftModifier))
|
||||||
|
deindent();
|
||||||
|
else
|
||||||
|
indent();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_D:
|
||||||
|
if (ke->modifiers().testFlag(Qt::ControlModifier)) {
|
||||||
|
completer->hide();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_Control:
|
||||||
|
showLink();
|
||||||
|
break;
|
||||||
|
case Qt::Key_F1:
|
||||||
|
if (widget_help->isVisible())
|
||||||
|
gotoHelpHRef(help_entry);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (!ke->text().isEmpty()) {
|
||||||
|
if (hasBlockSelection() && (ke->modifiers() == 0 || ke->modifiers() == Qt::ShiftModifier)) {
|
||||||
|
insertBlockSelection(ke->text());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
kc = ke->text()[0];
|
||||||
|
}
|
||||||
|
if (kc == '.') {
|
||||||
|
completer->hide();
|
||||||
|
QMetaObject::invokeMethod(this, "invokeAutoCompletition", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||||
|
} else {
|
||||||
|
if ((kc.isLetterOrNumber() || kc.toLatin1() == '_') && completer->isVisible())
|
||||||
|
QMetaObject::invokeMethod(this, "invokeAutoCompletition", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char antiBracket(char c) {
|
char antiBracket(char c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '(': return ')';
|
case '(': return ')';
|
||||||
@@ -747,34 +773,143 @@ int QCodeEdit::searchIndFromCursor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QRect QCodeEdit::cursorRect(QRect * line) {
|
||||||
|
QRect r = ui->textCode->cursorRect(textCursor()), lr = r;
|
||||||
|
if (hasBlockSelection()) {
|
||||||
|
r |= ui->textCode->cursorRect(block_start_cursor);
|
||||||
|
lr.setY(r.y());
|
||||||
|
lr.setHeight(r.height());
|
||||||
|
}
|
||||||
|
lr.setWidth(cursor_width);
|
||||||
|
if (line) *line = lr;
|
||||||
|
return (r | lr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QRect QCodeEdit::blockSelectionRect() {
|
||||||
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
QPoint ps(block_start_cursor.columnNumber(), block_start_cursor.blockNumber()),
|
||||||
|
pe(tc.columnNumber(), 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void QCodeEdit::repaintCursor() {
|
void QCodeEdit::repaintCursor() {
|
||||||
QRect r = ui->textCode->cursorRect(ui->textCode->textCursor());
|
overlay->update(cursorRect());
|
||||||
r.setWidth(cursor_width);
|
|
||||||
//r.translate(-cursor_width, 0);
|
|
||||||
overlay->update(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QCodeEdit::drawCursor() {
|
void QCodeEdit::drawCursor() {
|
||||||
QPainter p(overlay);
|
QPainter p(overlay);
|
||||||
QTextCursor tc = textCursor();
|
QTextCursor tc = textCursor();
|
||||||
if (cursor_state && ui->textCode->hasFocus()) {
|
//qDebug() << block_start_cursor.position() << tc.position();
|
||||||
QTextLayout * lay = tc.block().layout();
|
QRect line, all = cursorRect(&line);
|
||||||
if (lay) {
|
if (hasBlockSelection() && (tc.columnNumber() != block_start_cursor.columnNumber())) {
|
||||||
//QTextLine l = lay->lineForTextPosition(tc.positionInBlock());
|
p.setCompositionMode(QPainter::CompositionMode_Difference);
|
||||||
//int x = l.cursorToX(tc.position(), QTextLine::Trailing);
|
QColor hc = palette().color(QPalette::Highlight);
|
||||||
p.setPen(Qt::black);
|
p.fillRect(all, QColor(255 - hc.red(), 255 - hc.green(), 255 - hc.blue()));
|
||||||
QRect r = ui->textCode->cursorRect(tc);
|
|
||||||
r.setWidth(cursor_width);
|
|
||||||
r.adjust(0, 1, 0, -1);
|
|
||||||
//r.translate(-cursor_width, 0);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Difference);
|
|
||||||
p.fillRect(r, Qt::white);
|
|
||||||
//p.fillRect(p.viewport(), Qt::red);
|
|
||||||
//qDebug() << x << l.y() << cursor_width << l.height();
|
|
||||||
//p.fillRect(x, l.y(), cursor_width, l.height(), Qt::black);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (cursor_state && ui->textCode->hasFocus()) {
|
||||||
|
line.adjust(0, 1, 0, -1);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_Difference);
|
||||||
|
p.fillRect(line, Qt::white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QCodeEdit::hasBlockSelection() const {
|
||||||
|
return !block_start_cursor.isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QCodeEdit::startBlockSelection() {
|
||||||
|
if (!hasBlockSelection()) {
|
||||||
|
QTextCursor tc = textCursor();
|
||||||
|
block_start_cursor = tc;
|
||||||
|
block_start_cursor.setPosition(tc.selectionStart());
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
void QCodeEdit::cancelBlockSelection() {
|
||||||
|
block_start_cursor = QTextCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QCodeEdit::switchBlockSelection(QKeyEvent * ke) {
|
||||||
|
bool alt = QApplication::keyboardModifiers().testFlag(Qt::AltModifier);
|
||||||
|
if (ke) alt = ke->modifiers().testFlag(Qt::AltModifier);
|
||||||
|
if (alt) {
|
||||||
|
startBlockSelection();
|
||||||
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
QTextCursor::MoveOperation op = QTextCursor::NoMove;
|
||||||
|
if (!ke) return;
|
||||||
|
switch (ke->key()) {
|
||||||
|
case Qt::Key_Left : op = QTextCursor::Left ; break;
|
||||||
|
case Qt::Key_Right: op = QTextCursor::Right; break;
|
||||||
|
case Qt::Key_Up : op = QTextCursor::Up ; break;
|
||||||
|
case Qt::Key_Down : op = QTextCursor::Down ; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (op != QTextCursor::NoMove) {
|
||||||
|
tc.movePosition(op);
|
||||||
|
ui->textCode->setTextCursor(tc);
|
||||||
|
}
|
||||||
|
repaintCursor();
|
||||||
|
} else
|
||||||
|
cancelBlockSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QCodeEdit::removeBlockSelection(bool is_del) {
|
||||||
|
if (!hasBlockSelection()) return false;
|
||||||
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
tc.beginEditBlock();
|
||||||
|
QRect bsr = blockSelectionRect();
|
||||||
|
if (bsr.width() == 0) {
|
||||||
|
if (is_del) bsr.setWidth(1);
|
||||||
|
else if (bsr.x() > 0) bsr.setLeft(bsr.x() - 1);
|
||||||
|
}
|
||||||
|
//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());
|
||||||
|
if (l != ctc.blockNumber()) continue;
|
||||||
|
int pos = ctc.position();
|
||||||
|
ctc.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, bsr.width());
|
||||||
|
if (l != ctc.blockNumber()) {
|
||||||
|
ctc.setPosition(pos);
|
||||||
|
ctc.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||||
|
}
|
||||||
|
ctc.removeSelectedText();
|
||||||
|
}
|
||||||
|
tc.setPosition(tc.block().position() + block_start_cursor.positionInBlock());
|
||||||
|
ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QCodeEdit::insertBlockSelection(QString text) {
|
||||||
|
if (!hasBlockSelection()) return;
|
||||||
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
tc.beginEditBlock();
|
||||||
|
QRect bsr = blockSelectionRect();
|
||||||
|
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());
|
||||||
|
if (l != ctc.blockNumber()) {
|
||||||
|
ctc = QTextCursor(ui->textCode->document()->findBlockByNumber(l));
|
||||||
|
ctc.movePosition(QTextCursor::EndOfLine);
|
||||||
|
ctc.insertText(QString(bsr.left() - ctc.columnNumber(), QChar(' ')));
|
||||||
|
}
|
||||||
|
ctc.insertText(text);
|
||||||
|
}
|
||||||
|
//tc.setPosition(tc.block().position() + block_start_cursor.positionInBlock());
|
||||||
|
//ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -835,6 +970,7 @@ void QCodeEdit::scrollDown() {
|
|||||||
|
|
||||||
void QCodeEdit::deleteLine() {
|
void QCodeEdit::deleteLine() {
|
||||||
QTextCursor tc = ui->textCode->textCursor();
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
tc.beginEditBlock();
|
||||||
tc.movePosition(QTextCursor::EndOfLine);
|
tc.movePosition(QTextCursor::EndOfLine);
|
||||||
tc.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
|
tc.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
|
||||||
bool md = true;
|
bool md = true;
|
||||||
@@ -848,11 +984,13 @@ void QCodeEdit::deleteLine() {
|
|||||||
tc.movePosition(QTextCursor::StartOfLine);
|
tc.movePosition(QTextCursor::StartOfLine);
|
||||||
if (md) tc.movePosition(QTextCursor::Down);
|
if (md) tc.movePosition(QTextCursor::Down);
|
||||||
ui->textCode->setTextCursor(tc);
|
ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QCodeEdit::copyLineUp() {
|
void QCodeEdit::copyLineUp() {
|
||||||
QTextCursor tc = ui->textCode->textCursor();
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
tc.beginEditBlock();
|
||||||
int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se;
|
int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se;
|
||||||
QString st_ = tc.selection().toPlainText();
|
QString st_ = tc.selection().toPlainText();
|
||||||
if (st_.endsWith("\n")) {
|
if (st_.endsWith("\n")) {
|
||||||
@@ -875,11 +1013,13 @@ void QCodeEdit::copyLineUp() {
|
|||||||
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
||||||
tc.endEditBlock();
|
tc.endEditBlock();
|
||||||
ui->textCode->setTextCursor(tc);
|
ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QCodeEdit::copyLineDown() {
|
void QCodeEdit::copyLineDown() {
|
||||||
QTextCursor tc = ui->textCode->textCursor();
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
tc.beginEditBlock();
|
||||||
int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se;
|
int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se;
|
||||||
QString st_ = tc.selection().toPlainText();
|
QString st_ = tc.selection().toPlainText();
|
||||||
if (st_.endsWith("\n")) {
|
if (st_.endsWith("\n")) {
|
||||||
@@ -905,6 +1045,7 @@ void QCodeEdit::copyLineDown() {
|
|||||||
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
||||||
tc.endEditBlock();
|
tc.endEditBlock();
|
||||||
ui->textCode->setTextCursor(tc);
|
ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -921,6 +1062,7 @@ void QCodeEdit::moveLineUp() {
|
|||||||
tc.setPosition(ss);
|
tc.setPosition(ss);
|
||||||
if (!tc.movePosition(QTextCursor::Up))
|
if (!tc.movePosition(QTextCursor::Up))
|
||||||
return;
|
return;
|
||||||
|
tc.beginEditBlock();
|
||||||
tc.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
|
tc.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
|
||||||
QString l = tc.selectedText();
|
QString l = tc.selectedText();
|
||||||
ss -= l.size(); se -= l.size();
|
ss -= l.size(); se -= l.size();
|
||||||
@@ -943,6 +1085,7 @@ void QCodeEdit::moveLineUp() {
|
|||||||
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
||||||
tc.endEditBlock();
|
tc.endEditBlock();
|
||||||
ui->textCode->setTextCursor(tc);
|
ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -959,6 +1102,7 @@ void QCodeEdit::moveLineDown() {
|
|||||||
tc.setPosition(se);
|
tc.setPosition(se);
|
||||||
if (!tc.movePosition(QTextCursor::Right))
|
if (!tc.movePosition(QTextCursor::Right))
|
||||||
return;
|
return;
|
||||||
|
tc.beginEditBlock();
|
||||||
bool de = false;
|
bool de = false;
|
||||||
if (!tc.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor)) {
|
if (!tc.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor)) {
|
||||||
tc.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
tc.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||||
@@ -981,11 +1125,13 @@ void QCodeEdit::moveLineDown() {
|
|||||||
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
||||||
tc.endEditBlock();
|
tc.endEditBlock();
|
||||||
ui->textCode->setTextCursor(tc);
|
ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QCodeEdit::indent() {
|
void QCodeEdit::indent() {
|
||||||
QTextCursor tc = ui->textCode->textCursor();
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
tc.beginEditBlock();
|
||||||
int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se;
|
int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se;
|
||||||
QString st_ = tc.selection().toPlainText();
|
QString st_ = tc.selection().toPlainText();
|
||||||
if (st_.endsWith("\n")) {
|
if (st_.endsWith("\n")) {
|
||||||
@@ -1005,11 +1151,13 @@ void QCodeEdit::indent() {
|
|||||||
tc.setPosition(ss_ + 1);
|
tc.setPosition(ss_ + 1);
|
||||||
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
||||||
ui->textCode->setTextCursor(tc);
|
ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QCodeEdit::deindent() {
|
void QCodeEdit::deindent() {
|
||||||
QTextCursor tc = ui->textCode->textCursor();
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
tc.beginEditBlock();
|
||||||
int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se;
|
int ss = tc.selectionStart(), ss_ = ss, se = tc.selectionEnd(), se_ = se;
|
||||||
QString st_ = tc.selection().toPlainText();
|
QString st_ = tc.selection().toPlainText();
|
||||||
if (st_.endsWith("\n")) {
|
if (st_.endsWith("\n")) {
|
||||||
@@ -1049,6 +1197,7 @@ void QCodeEdit::deindent() {
|
|||||||
tc.setPosition(ss_);
|
tc.setPosition(ss_);
|
||||||
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
tc.setPosition(se_, QTextCursor::KeepAnchor);
|
||||||
ui->textCode->setTextCursor(tc);
|
ui->textCode->setTextCursor(tc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1056,6 +1205,7 @@ void QCodeEdit::autoIndent() {
|
|||||||
QTextCursor tc = ui->textCode->textCursor(), stc = tc;
|
QTextCursor tc = ui->textCode->textCursor(), stc = tc;
|
||||||
tc.movePosition(QTextCursor::StartOfLine);
|
tc.movePosition(QTextCursor::StartOfLine);
|
||||||
if (!tc.movePosition(QTextCursor::Up)) return;
|
if (!tc.movePosition(QTextCursor::Up)) return;
|
||||||
|
tc.beginEditBlock();
|
||||||
tc.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
|
tc.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
|
||||||
QString line = tc.selectedText(), tabs;
|
QString line = tc.selectedText(), tabs;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -1071,6 +1221,7 @@ void QCodeEdit::autoIndent() {
|
|||||||
if (tabs.isEmpty()) return;
|
if (tabs.isEmpty()) return;
|
||||||
stc.insertText(tabs);
|
stc.insertText(tabs);
|
||||||
ui->textCode->setTextCursor(stc);
|
ui->textCode->setTextCursor(stc);
|
||||||
|
tc.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1508,6 +1659,17 @@ void QCodeEdit::textEdit_textChanged() {
|
|||||||
|
|
||||||
|
|
||||||
void QCodeEdit::textEdit_selectionChanged() {
|
void QCodeEdit::textEdit_selectionChanged() {
|
||||||
|
if (hasBlockSelection()) {
|
||||||
|
QTextCursor tc = ui->textCode->textCursor();
|
||||||
|
//qDebug() << block_start_cursor.selectionStart() << tc.selectionEnd();
|
||||||
|
bool bs = ui->textCode->blockSignals(true);
|
||||||
|
tc.clearSelection();
|
||||||
|
ui->textCode->setTextCursor(tc);
|
||||||
|
ui->textCode->blockSignals(bs);
|
||||||
|
applyExtraSelection();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
block_start_cursor = QTextCursor();
|
||||||
es_selected.clear();
|
es_selected.clear();
|
||||||
QString sf = ui->textCode->textCursor().selectedText();
|
QString sf = ui->textCode->textCursor().selectedText();
|
||||||
if (sf.trimmed().isEmpty() || sf.contains("\n")) {
|
if (sf.trimmed().isEmpty() || sf.contains("\n")) {
|
||||||
|
|||||||
@@ -147,23 +147,33 @@ private:
|
|||||||
QMap<int, ACClass> ac_classes;
|
QMap<int, ACClass> ac_classes;
|
||||||
QStringList cursor_scope;
|
QStringList cursor_scope;
|
||||||
ACEntry link_entry, help_entry;
|
ACEntry link_entry, help_entry;
|
||||||
|
QTextCursor block_start_cursor;
|
||||||
int prev_lc, auto_comp_pl, timer_parse, timer_blink, cur_search_ind, pos_press, pos_el_press;
|
int prev_lc, auto_comp_pl, timer_parse, timer_blink, cur_search_ind, pos_press, pos_el_press;
|
||||||
int cursor_width;
|
int cursor_width;
|
||||||
bool spaces_, _ignore_focus_out, _first, _destructor, _replacing;
|
bool spaces_, _ignore_focus_out, _first, _destructor, _replacing;
|
||||||
bool word_complete, help_visible, cursor_state;
|
bool word_complete, help_visible, cursor_state, block_sel_state;
|
||||||
|
|
||||||
bool eventFilter(QObject * o, QEvent * e) override;
|
bool eventFilter(QObject * o, QEvent * e) override;
|
||||||
void showEvent(QShowEvent * ) override;
|
void showEvent(QShowEvent * ) override;
|
||||||
void timerEvent(QTimerEvent * ) override;
|
void timerEvent(QTimerEvent * ) override;
|
||||||
void leaveEvent(QEvent * ) override;
|
void leaveEvent(QEvent * ) override;
|
||||||
void changeEvent(QEvent * e) override;
|
void changeEvent(QEvent * e) override;
|
||||||
|
bool codeKeyEvent(QKeyEvent * ke);
|
||||||
void highlightBrackets();
|
void highlightBrackets();
|
||||||
void applyExtraSelection();
|
void applyExtraSelection();
|
||||||
void clearSearch();
|
void clearSearch();
|
||||||
void moveToSearch();
|
void moveToSearch();
|
||||||
int searchIndFromCursor();
|
int searchIndFromCursor();
|
||||||
|
QRect cursorRect(QRect * line = 0);
|
||||||
|
QRect blockSelectionRect();
|
||||||
void repaintCursor();
|
void repaintCursor();
|
||||||
void drawCursor();
|
void drawCursor();
|
||||||
|
bool hasBlockSelection() const;
|
||||||
|
void startBlockSelection();
|
||||||
|
void cancelBlockSelection();
|
||||||
|
void switchBlockSelection(QKeyEvent * ke = 0);
|
||||||
|
bool removeBlockSelection(bool is_del);
|
||||||
|
void insertBlockSelection(QString text);
|
||||||
ACEntry findEntryOnCursor(QTextCursor tc, int arg = -1, ACClass * acc = 0, QPair<QStringList, QString> * scope = 0);
|
ACEntry findEntryOnCursor(QTextCursor tc, int arg = -1, ACClass * acc = 0, QPair<QStringList, QString> * scope = 0);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|||||||
Reference in New Issue
Block a user