diff --git a/TransmitTextEdit.cpp b/TransmitTextEdit.cpp index 9c9ff0b..780d1e0 100644 --- a/TransmitTextEdit.cpp +++ b/TransmitTextEdit.cpp @@ -92,6 +92,7 @@ TransmitTextEdit::TransmitTextEdit(QWidget *parent): connect(this, &QTextEdit::selectionChanged, this, &TransmitTextEdit::on_selectionChanged); connect(this, &QTextEdit::cursorPositionChanged, this, &TransmitTextEdit::on_selectionChanged); connect(this->document(), &QTextDocument::contentsChange, this, &TransmitTextEdit::on_textContentsChanged); + installEventFilter(this); } void TransmitTextEdit::setCharsSent(int n){ @@ -150,9 +151,7 @@ void TransmitTextEdit::setProtected(bool protect){ m_protected = protect; } -// slot -void TransmitTextEdit::on_selectionChanged(){ - auto c = textCursor(); +bool TransmitTextEdit::cursorShouldBeProtected(QTextCursor c){ int start = c.selectionStart(); int end = c.selectionEnd(); if(end < start){ @@ -165,12 +164,23 @@ void TransmitTextEdit::on_selectionChanged(){ if(m_sent && start <= m_sent){ qDebug() << "selection in protected zone" << start << "<=" << m_sent; - setProtected(true); + return true; } else { - setProtected(false); + return false; } } +// slot +void TransmitTextEdit::on_selectionChanged(){ + auto c = textCursor(); + + auto protect = cursorShouldBeProtected(c); + + setProtected(protect); + + // TODO: when protected and text is selected, remove protected region from selection +} + // slot void TransmitTextEdit::on_textContentsChanged(int pos, int rem, int add){ if(rem == 0 && add == 0){ @@ -179,8 +189,13 @@ void TransmitTextEdit::on_textContentsChanged(int pos, int rem, int add){ auto text = toPlainText(); if(text != m_lastText){ - qDebug() << "text changed" << pos << rem << add << "from" << m_lastText << "to" << text; + //qDebug() << "text changed" << pos << rem << add << "from" << m_lastText << "to" << text; + highlight(); + + qDebug() << "sent:" << sentText(); + qDebug() << "unsent:" << unsentText(); + m_lastText = text; } } @@ -226,3 +241,151 @@ void TransmitTextEdit::highlight(){ highlightCharsSent(); } +bool isMovementKeyEvent(QKeyEvent * k){ + return ( + k == QKeySequence::MoveToNextChar || + k == QKeySequence::MoveToPreviousChar || + k == QKeySequence::SelectNextChar || + k == QKeySequence::SelectPreviousChar || + k == QKeySequence::SelectNextWord || + k == QKeySequence::SelectPreviousWord || + k == QKeySequence::SelectStartOfLine || + k == QKeySequence::SelectEndOfLine || + k == QKeySequence::SelectStartOfBlock || + k == QKeySequence::SelectEndOfBlock || + k == QKeySequence::SelectStartOfDocument || + k == QKeySequence::SelectEndOfDocument || + k == QKeySequence::SelectPreviousLine || + k == QKeySequence::SelectNextLine || + k == QKeySequence::MoveToNextWord || + k == QKeySequence::MoveToPreviousWord || + k == QKeySequence::MoveToEndOfBlock || + k == QKeySequence::MoveToStartOfBlock || + k == QKeySequence::MoveToNextLine || + k == QKeySequence::MoveToPreviousLine || + k == QKeySequence::MoveToPreviousLine || + k == QKeySequence::MoveToStartOfLine || + k == QKeySequence::MoveToEndOfLine || + k == QKeySequence::MoveToStartOfDocument || + k == QKeySequence::MoveToEndOfDocument + ); +} + + +QTextCursor::MoveOperation movementKeyEventToMoveOperation(QKeyEvent *e){ + QTextCursor::MoveOperation op = QTextCursor::NoMove; + + if (e == QKeySequence::MoveToNextChar) { + op = QTextCursor::Right; + } + else if (e == QKeySequence::MoveToPreviousChar) { + op = QTextCursor::Left; + } + else if (e == QKeySequence::SelectNextChar) { + op = QTextCursor::Right; + } + else if (e == QKeySequence::SelectPreviousChar) { + op = QTextCursor::Left; + } + else if (e == QKeySequence::SelectNextWord) { + op = QTextCursor::WordRight; + } + else if (e == QKeySequence::SelectPreviousWord) { + op = QTextCursor::WordLeft; + } + else if (e == QKeySequence::SelectStartOfLine) { + op = QTextCursor::StartOfLine; + } + else if (e == QKeySequence::SelectEndOfLine) { + op = QTextCursor::EndOfLine; + } + else if (e == QKeySequence::SelectStartOfBlock) { + op = QTextCursor::StartOfBlock; + } + else if (e == QKeySequence::SelectEndOfBlock) { + op = QTextCursor::EndOfBlock; + } + else if (e == QKeySequence::SelectStartOfDocument) { + op = QTextCursor::Start; + } + else if (e == QKeySequence::SelectEndOfDocument) { + op = QTextCursor::End; + } + else if (e == QKeySequence::SelectPreviousLine) { + op = QTextCursor::Up; + } + else if (e == QKeySequence::SelectNextLine) { + op = QTextCursor::Down; + } + else if (e == QKeySequence::MoveToNextWord) { + op = QTextCursor::WordRight; + } + else if (e == QKeySequence::MoveToPreviousWord) { + op = QTextCursor::WordLeft; + } + else if (e == QKeySequence::MoveToEndOfBlock) { + op = QTextCursor::EndOfBlock; + } + else if (e == QKeySequence::MoveToStartOfBlock) { + op = QTextCursor::StartOfBlock; + } + else if (e == QKeySequence::MoveToNextLine) { + op = QTextCursor::Down; + } + else if (e == QKeySequence::MoveToPreviousLine) { + op = QTextCursor::Up; + } + else if (e == QKeySequence::MoveToPreviousLine) { + op = QTextCursor::Up; + } + else if (e == QKeySequence::MoveToStartOfLine) { + op = QTextCursor::StartOfLine; + } + else if (e == QKeySequence::MoveToEndOfLine) { + op = QTextCursor::EndOfLine; + } + else if (e == QKeySequence::MoveToStartOfDocument) { + op = QTextCursor::Start; + } + else if (e == QKeySequence::MoveToEndOfDocument) { + op = QTextCursor::End; + } + + return op; +} + + +bool TransmitTextEdit::eventFilter(QObject */*o*/, QEvent *e){ + if(e->type() != QEvent::KeyPress){ + return false; + } + + QKeyEvent *k = static_cast(e); + + auto c = textCursor(); + + auto c2 = QTextCursor(c); + c2.movePosition(movementKeyEventToMoveOperation(k)); + + bool shouldBeProtected = cursorShouldBeProtected(c2); + + // 0. only filter when in a protected range + // 0a. but only if we're not moving/deleting _into_ the protected range :/ + if(!isProtected() && !shouldBeProtected){ + return false; + } + + // 1. do not filter movement sequences + if(isMovementKeyEvent(k)){ + return false; + } + + // 2. if on the edge, do not filter if not a backspace + int start = qMin(c.selectionStart(), c.selectionEnd()); + if(start == m_sent && k->key() != Qt::Key_Backspace){ + return false; + } + + return true; +} + diff --git a/TransmitTextEdit.h b/TransmitTextEdit.h index 0a9958b..3c7cf2c 100644 --- a/TransmitTextEdit.h +++ b/TransmitTextEdit.h @@ -24,6 +24,14 @@ public: } void setCharsSent(int n); + QString sentText() const { + return m_textSent; + } + + QString unsentText() const { + return toPlainText().mid(charsSent()); + } + QString toPlainText() const; void setPlainText(const QString &text); void setFont(QFont f); @@ -34,10 +42,13 @@ public: return m_protected; } void setProtected(bool protect); + bool cursorShouldBeProtected(QTextCursor c); void highlightBase(); void highlightCharsSent(); void highlight(); + bool eventFilter(QObject */*o*/, QEvent *e); + public slots: void on_selectionChanged(); void on_textContentsChanged(int pos, int rem, int add); diff --git a/keyeater.cpp b/keyeater.cpp index 8f45f61..5231a7c 100644 --- a/keyeater.cpp +++ b/keyeater.cpp @@ -12,7 +12,8 @@ bool KeyPressEater::eventFilter(QObject *obj, QEvent *event){ } // standard event processing - return QObject::eventFilter(obj, event); + //return QObject::eventFilter(obj, event); + return false; } bool EscapeKeyPressEater::eventFilter(QObject *obj, QEvent *event){ @@ -24,7 +25,8 @@ bool EscapeKeyPressEater::eventFilter(QObject *obj, QEvent *event){ } // standard event processing - return QObject::eventFilter(obj, event); + //return QObject::eventFilter(obj, event); + return false; } bool EnterKeyPressEater::eventFilter(QObject *obj, QEvent *event){ @@ -40,7 +42,8 @@ bool EnterKeyPressEater::eventFilter(QObject *obj, QEvent *event){ } // standard event processing - return QObject::eventFilter(obj, event); + //return QObject::eventFilter(obj, event); + return false; } bool MousePressEater::eventFilter(QObject *obj, QEvent *event){ @@ -54,7 +57,8 @@ bool MousePressEater::eventFilter(QObject *obj, QEvent *event){ } // standard event processing - return QObject::eventFilter(obj, event); + //return QObject::eventFilter(obj, event); + return false; } bool MouseDoubleClickEater::eventFilter(QObject *obj, QEvent *event){ @@ -68,5 +72,6 @@ bool MouseDoubleClickEater::eventFilter(QObject *obj, QEvent *event){ } // standard event processing - return QObject::eventFilter(obj, event); + //return QObject::eventFilter(obj, event); + return false; } diff --git a/mainwindow.cpp b/mainwindow.cpp index d640f8e..c2dd9f5 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1095,7 +1095,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, toggleTx(true); }); - ui->extFreeTextMsgEdit->installEventFilter(enterFilter); + //ui->extFreeTextMsgEdit->installEventFilter(enterFilter); auto doubleClickFilter = new MouseDoubleClickEater(); connect(doubleClickFilter, &MouseDoubleClickEater::mouseDoubleClicked, this, [this](QObject *, QMouseEvent *, bool *){