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

This commit is contained in:
Jordan Sherer 2019-11-07 14:20:06 -05:00
parent 0d785888d8
commit 2add8ff1b7
5 changed files with 66 additions and 18 deletions

View File

@ -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(); auto c = textCursor();
c.movePosition(QTextCursor::Start); c.movePosition(QTextCursor::Start);
c.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, m_sent); c.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, m_sent);
c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
c.removeSelectedText(); c.removeSelectedText();
c.insertText(text); 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(); auto c = textCursor();
c.movePosition(QTextCursor::Start); c.movePosition(QTextCursor::Start);
c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
c.removeSelectedText(); c.removeSelectedText();
c.insertText(text); 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);
}
} }
// //

View File

@ -19,6 +19,18 @@ class TransmitTextEdit : public QTextEdit
public: public:
TransmitTextEdit(QWidget *parent); TransmitTextEdit(QWidget *parent);
static QPair<int,int> 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 { int charsSent() const {
return m_sent; return m_sent;
} }
@ -34,8 +46,8 @@ public:
QString toPlainText() const; QString toPlainText() const;
void setPlainText(const QString &text); void setPlainText(const QString &text);
void replaceUnsentText(const QString &text); void replaceUnsentText(const QString &text, bool keepCursor);
void replacePlainText(const QString &text); void replacePlainText(const QString &text, bool keepCursor);
void setFont(QFont f); void setFont(QFont f);
void setFont(QFont f, QColor fg, QColor bg); void setFont(QFont f, QColor fg, QColor bg);

View File

@ -6476,19 +6476,19 @@ bool MainWindow::ensureCreateMessageReady(const QString &text){
} }
QString MainWindow::createMessage(QString const& 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){ QString MainWindow::appendMessage(QString const& text, bool isData){
return createMessageTransmitQueue(replaceMacros(text, buildMacroValues(), false), false); 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){ if(reset){
resetMessageTransmitQueue(); resetMessageTransmitQueue();
} }
auto frames = buildMessageFrames(text); auto frames = buildMessageFrames(text, isData);
QStringList lines; QStringList lines;
foreach(auto frame, frames){ foreach(auto frame, frames){
@ -6535,6 +6535,8 @@ QPair<QString, int> MainWindow::popMessageFrame(){
return m_txFrameQueue.dequeue(); 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(){ void MainWindow::on_textEditRX_mouseDoubleClicked(){
auto c = ui->textEditRX->textCursor(); auto c = ui->textEditRX->textCursor();
auto text = c.selectedText(); auto text = c.selectedText();
@ -6578,7 +6580,7 @@ int MainWindow::currentFreqOffset(){
return ui->RxFreqSpinBox->value(); return ui->RxFreqSpinBox->value();
} }
QList<QPair<QString, int>> MainWindow::buildMessageFrames(const QString &text){ QList<QPair<QString, int>> MainWindow::buildMessageFrames(const QString &text, bool isData){
// prepare selected callsign for directed message // prepare selected callsign for directed message
QString selectedCall = callsignSelected(); QString selectedCall = callsignSelected();
@ -6589,7 +6591,7 @@ QList<QPair<QString, int>> MainWindow::buildMessageFrames(const QString &text){
bool forceIdentify = !m_config.avoid_forced_identify(); bool forceIdentify = !m_config.avoid_forced_identify();
// TODO: might want to be more explicit? // TODO: might want to be more explicit?
bool forceData = m_txFrameCountSent > 0; bool forceData = m_txFrameCountSent > 0 && isData;
Varicode::MessageInfo info; Varicode::MessageInfo info;
auto frames = Varicode::buildMessageFrames( auto frames = Varicode::buildMessageFrames(
@ -6621,6 +6623,13 @@ QList<QPair<QString, int>> MainWindow::buildMessageFrames(const QString &text){
bool MainWindow::prepareNextMessageFrame() 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; m_i3bit = Varicode::JS8Call;
// typeahead // typeahead
@ -6634,11 +6643,19 @@ bool MainWindow::prepareNextMessageFrame()
qDebug() << "text dirty for typeahead\n" << sent << "\n" << unsent; qDebug() << "text dirty for typeahead\n" << sent << "\n" << unsent;
m_txFrameQueue.clear(); m_txFrameQueue.clear();
m_txFrameCount = 0; 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; qDebug () << "unsent replaced to" << "\n" << newText;
} }
ui->extFreeTextMsgEdit->setReadOnly(false); ui->extFreeTextMsgEdit->setReadOnly(false);
ui->extFreeTextMsgEdit->replaceUnsentText(newText); ui->extFreeTextMsgEdit->replaceUnsentText(newText, true);
ui->extFreeTextMsgEdit->setClean(); ui->extFreeTextMsgEdit->setClean();
} }

View File

@ -157,8 +157,8 @@ public slots:
bool ensureNotIdle(); bool ensureNotIdle();
bool ensureCreateMessageReady(const QString &text); bool ensureCreateMessageReady(const QString &text);
QString createMessage(QString const& text); QString createMessage(QString const& text);
QString appendMessage(QString const& text); QString appendMessage(QString const& text, bool isData);
QString createMessageTransmitQueue(QString const& text, bool reset); QString createMessageTransmitQueue(QString const& text, bool reset, bool isData);
void resetMessageTransmitQueue(); void resetMessageTransmitQueue();
QPair<QString, int> popMessageFrame(); QPair<QString, int> popMessageFrame();
void tryNotify(const QString &key); void tryNotify(const QString &key);
@ -343,7 +343,7 @@ private slots:
void on_nextFreeTextMsg_currentTextChanged (QString const&); void on_nextFreeTextMsg_currentTextChanged (QString const&);
void on_extFreeTextMsgEdit_currentTextChanged (QString const&); void on_extFreeTextMsgEdit_currentTextChanged (QString const&);
int currentFreqOffset(); int currentFreqOffset();
QList<QPair<QString, int>> buildMessageFrames(QString const& text); QList<QPair<QString, int>> buildMessageFrames(QString const& text, bool isData);
bool prepareNextMessageFrame(); bool prepareNextMessageFrame();
bool isFreqOffsetFree(int f, int bw); bool isFreqOffsetFree(int f, int bw);
int findFreeFreqOffset(int fmin, int fmax, int bw); int findFreeFreqOffset(int fmin, int fmax, int bw);

View File

@ -1831,6 +1831,7 @@ QList<QPair<QString, int>> Varicode::buildMessageFrames(QString const& mycall,
bool forceData, bool forceData,
int submode, int submode,
MessageInfo *pInfo){ MessageInfo *pInfo){
#define ALLOW_SEND_COMPOUND 1 #define ALLOW_SEND_COMPOUND 1
#define ALLOW_SEND_COMPOUND_DIRECTED 1 #define ALLOW_SEND_COMPOUND_DIRECTED 1
#define AUTO_PREPEND_DIRECTED 1 #define AUTO_PREPEND_DIRECTED 1
@ -1897,8 +1898,8 @@ QList<QPair<QString, int>> Varicode::buildMessageFrames(QString const& mycall,
// and if there are no other callsigns in this message // and if there are no other callsigns in this message
// or if the first callsign in the message isn't at the beginning... // 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 // then we should be auto-prefixing this line with the selected call
auto sep = line.startsWith(" ") ? "" : " ";
line = QString("%1 %2").arg(selectedCall).arg(line); line = QString("%1%2%3").arg(selectedCall).arg(sep).arg(line);
} }
} }
#endif #endif