From 2add8ff1b73e44d02f168cb6ffafdf9444208022 Mon Sep 17 00:00:00 2001 From: Jordan Sherer Date: Thu, 7 Nov 2019 14:20:06 -0500 Subject: [PATCH] Fixed typeahead cursor shift on text replace. Ensured typeahead resends callsign if in a directed transmission and the typeahead continues after sending a last bit --- TransmitTextEdit.cpp | 22 ++++++++++++++++++++-- TransmitTextEdit.h | 16 ++++++++++++++-- mainwindow.cpp | 35 ++++++++++++++++++++++++++--------- mainwindow.h | 6 +++--- varicode.cpp | 5 +++-- 5 files changed, 66 insertions(+), 18 deletions(-) diff --git a/TransmitTextEdit.cpp b/TransmitTextEdit.cpp index 95608ea..a2cf028 100644 --- a/TransmitTextEdit.cpp +++ b/TransmitTextEdit.cpp @@ -124,22 +124,40 @@ void TransmitTextEdit::setPlainText(const QString &text){ } // -void TransmitTextEdit::replaceUnsentText(const QString &text){ +void TransmitTextEdit::replaceUnsentText(const QString &text, bool keepCursor){ + auto rel = relativeTextCursorPosition(textCursor()); auto c = textCursor(); c.movePosition(QTextCursor::Start); c.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, m_sent); c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); c.removeSelectedText(); c.insertText(text); + + // keep cursor + if(keepCursor){ + c.movePosition(QTextCursor::End); + c.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, rel.first); + c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, rel.second - rel.first); + setTextCursor(c); + } } // -void TransmitTextEdit::replacePlainText(const QString &text){ +void TransmitTextEdit::replacePlainText(const QString &text, bool keepCursor){ + auto rel = relativeTextCursorPosition(textCursor()); auto c = textCursor(); c.movePosition(QTextCursor::Start); c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); c.removeSelectedText(); c.insertText(text); + + // keep cursor + if(keepCursor){ + c.movePosition(QTextCursor::End); + c.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, rel.first); + c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, rel.second - rel.first); + setTextCursor(c); + } } // diff --git a/TransmitTextEdit.h b/TransmitTextEdit.h index 2deee6d..b0ac775 100644 --- a/TransmitTextEdit.h +++ b/TransmitTextEdit.h @@ -19,6 +19,18 @@ class TransmitTextEdit : public QTextEdit public: TransmitTextEdit(QWidget *parent); + static QPair relativeTextCursorPosition(QTextCursor cursor){ + auto c = QTextCursor(cursor); + c.movePosition(QTextCursor::End); + int last = c.position(); + + auto cc = QTextCursor(cursor); + int relstart = last - qMin(cc.selectionStart(), cc.selectionEnd()); + int relend = last - qMax(cc.selectionStart(), cc.selectionEnd()); + + return {relstart, relend}; + } + int charsSent() const { return m_sent; } @@ -34,8 +46,8 @@ public: QString toPlainText() const; void setPlainText(const QString &text); - void replaceUnsentText(const QString &text); - void replacePlainText(const QString &text); + void replaceUnsentText(const QString &text, bool keepCursor); + void replacePlainText(const QString &text, bool keepCursor); void setFont(QFont f); void setFont(QFont f, QColor fg, QColor bg); diff --git a/mainwindow.cpp b/mainwindow.cpp index c03e7b8..1bfdb66 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -6476,19 +6476,19 @@ bool MainWindow::ensureCreateMessageReady(const QString &text){ } QString MainWindow::createMessage(QString const& text){ - return createMessageTransmitQueue(replaceMacros(text, buildMacroValues(), false), true); + return createMessageTransmitQueue(replaceMacros(text, buildMacroValues(), false), true, false); } -QString MainWindow::appendMessage(QString const& text){ - return createMessageTransmitQueue(replaceMacros(text, buildMacroValues(), false), false); +QString MainWindow::appendMessage(QString const& text, bool isData){ + return createMessageTransmitQueue(replaceMacros(text, buildMacroValues(), false), false, isData); } -QString MainWindow::createMessageTransmitQueue(QString const& text, bool reset){ +QString MainWindow::createMessageTransmitQueue(QString const& text, bool reset, bool isData){ if(reset){ resetMessageTransmitQueue(); } - auto frames = buildMessageFrames(text); + auto frames = buildMessageFrames(text, isData); QStringList lines; foreach(auto frame, frames){ @@ -6535,6 +6535,8 @@ QPair MainWindow::popMessageFrame(){ return m_txFrameQueue.dequeue(); } +// when we double click the rx window, we send the selected text to the log dialog +// when the text could be an snr value prefixed with a - or +, we extend the selection to include it void MainWindow::on_textEditRX_mouseDoubleClicked(){ auto c = ui->textEditRX->textCursor(); auto text = c.selectedText(); @@ -6578,7 +6580,7 @@ int MainWindow::currentFreqOffset(){ return ui->RxFreqSpinBox->value(); } -QList> MainWindow::buildMessageFrames(const QString &text){ +QList> MainWindow::buildMessageFrames(const QString &text, bool isData){ // prepare selected callsign for directed message QString selectedCall = callsignSelected(); @@ -6589,7 +6591,7 @@ QList> MainWindow::buildMessageFrames(const QString &text){ bool forceIdentify = !m_config.avoid_forced_identify(); // TODO: might want to be more explicit? - bool forceData = m_txFrameCountSent > 0; + bool forceData = m_txFrameCountSent > 0 && isData; Varicode::MessageInfo info; auto frames = Varicode::buildMessageFrames( @@ -6621,6 +6623,13 @@ QList> MainWindow::buildMessageFrames(const QString &text){ bool MainWindow::prepareNextMessageFrame() { + // check to see if the last i3bit was a last bit + bool i3bitLast = (m_i3bit & Varicode::JS8CallLast) == Varicode::JS8CallLast; + + // TODO: should this be user configurable? + bool shouldForceDataForTypeahead = !i3bitLast; + + // reset i3 m_i3bit = Varicode::JS8Call; // typeahead @@ -6634,11 +6643,19 @@ bool MainWindow::prepareNextMessageFrame() qDebug() << "text dirty for typeahead\n" << sent << "\n" << unsent; m_txFrameQueue.clear(); m_txFrameCount = 0; - newText = appendMessage(unsent); + + newText = appendMessage(unsent, shouldForceDataForTypeahead); + + // if this was the last frame, append a newline + if(i3bitLast){ + m_totalTxMessage.append("\n"); + newText.prepend("\n"); + } + qDebug () << "unsent replaced to" << "\n" << newText; } ui->extFreeTextMsgEdit->setReadOnly(false); - ui->extFreeTextMsgEdit->replaceUnsentText(newText); + ui->extFreeTextMsgEdit->replaceUnsentText(newText, true); ui->extFreeTextMsgEdit->setClean(); } diff --git a/mainwindow.h b/mainwindow.h index d30ee4e..634e80a 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -157,8 +157,8 @@ public slots: bool ensureNotIdle(); bool ensureCreateMessageReady(const QString &text); QString createMessage(QString const& text); - QString appendMessage(QString const& text); - QString createMessageTransmitQueue(QString const& text, bool reset); + QString appendMessage(QString const& text, bool isData); + QString createMessageTransmitQueue(QString const& text, bool reset, bool isData); void resetMessageTransmitQueue(); QPair popMessageFrame(); void tryNotify(const QString &key); @@ -343,7 +343,7 @@ private slots: void on_nextFreeTextMsg_currentTextChanged (QString const&); void on_extFreeTextMsgEdit_currentTextChanged (QString const&); int currentFreqOffset(); - QList> buildMessageFrames(QString const& text); + QList> buildMessageFrames(QString const& text, bool isData); bool prepareNextMessageFrame(); bool isFreqOffsetFree(int f, int bw); int findFreeFreqOffset(int fmin, int fmax, int bw); diff --git a/varicode.cpp b/varicode.cpp index cd2c2a5..d8c7a1d 100644 --- a/varicode.cpp +++ b/varicode.cpp @@ -1831,6 +1831,7 @@ QList> Varicode::buildMessageFrames(QString const& mycall, bool forceData, int submode, MessageInfo *pInfo){ + #define ALLOW_SEND_COMPOUND 1 #define ALLOW_SEND_COMPOUND_DIRECTED 1 #define AUTO_PREPEND_DIRECTED 1 @@ -1897,8 +1898,8 @@ QList> Varicode::buildMessageFrames(QString const& mycall, // and if there are no other callsigns in this message // or if the first callsign in the message isn't at the beginning... // then we should be auto-prefixing this line with the selected call - - line = QString("%1 %2").arg(selectedCall).arg(line); + auto sep = line.startsWith(" ") ? "" : " "; + line = QString("%1%2%3").arg(selectedCall).arg(sep).arg(line); } } #endif