kopia lustrzana https://gitlab.com/eliggett/wfview
494 wiersze
14 KiB
C++
494 wiersze
14 KiB
C++
#include "cwsender.h"
|
|
#include "ui_cwsender.h"
|
|
|
|
#include "logcategories.h"
|
|
|
|
cwSender::cwSender(QWidget *parent) :
|
|
QMainWindow(parent),
|
|
ui(new Ui::cwSender)
|
|
{
|
|
ui->setupUi(this);
|
|
this->setWindowTitle("CW Sender");
|
|
ui->textToSendEdit->setFocus();
|
|
QFont f = QFont("Monospace");
|
|
f.setStyleHint(QFont::TypeWriter);
|
|
ui->textToSendEdit->setFont(f);
|
|
ui->transcriptText->setFont(f);
|
|
ui->textToSendEdit->setFocus();
|
|
ui->statusbar->setToolTipDuration(3000);
|
|
this->setToolTipDuration(3000);
|
|
connect(ui->textToSendEdit->lineEdit(), &QLineEdit::textEdited, this, &cwSender::textChanged);
|
|
}
|
|
|
|
cwSender::~cwSender()
|
|
{
|
|
qDebug(logCW()) << "Running CW Sender destructor.";
|
|
|
|
if (toneThread != Q_NULLPTR) {
|
|
toneThread->quit();
|
|
toneThread->wait();
|
|
toneThread = Q_NULLPTR;
|
|
tone = Q_NULLPTR;
|
|
/* Finally disconnect all connections */
|
|
for (auto conn: connections)
|
|
{
|
|
disconnect(conn);
|
|
}
|
|
connections.clear();
|
|
}
|
|
|
|
delete ui;
|
|
}
|
|
|
|
void cwSender::showEvent(QShowEvent *event)
|
|
{
|
|
(void)event;
|
|
emit getCWSettings();
|
|
QMainWindow::showEvent(event);
|
|
}
|
|
|
|
void cwSender::handleKeySpeed(unsigned char wpm)
|
|
{
|
|
if (wpm != ui->wpmSpin->value() && (wpm >= ui->wpmSpin->minimum()) && (wpm <= ui->wpmSpin->maximum()))
|
|
{
|
|
ui->wpmSpin->blockSignals(true);
|
|
QMetaObject::invokeMethod(ui->wpmSpin, "setValue", Qt::QueuedConnection, Q_ARG(int, wpm));
|
|
ui->wpmSpin->blockSignals(false);
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0))
|
|
QMetaObject::invokeMethod(tone, [=]() {
|
|
tone->setSpeed(wpm);
|
|
}, Qt::QueuedConnection);
|
|
#else
|
|
emit setKeySpeed(ratio);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void cwSender::handleDashRatio(unsigned char ratio)
|
|
{
|
|
double calc = double(ratio/10);
|
|
if (calc != ui->dashSpin->value() && (calc >= ui->dashSpin->minimum()) && (ratio <= ui->dashSpin->maximum()))
|
|
{
|
|
ui->dashSpin->blockSignals(true);
|
|
QMetaObject::invokeMethod(ui->dashSpin, "setValue", Qt::QueuedConnection, Q_ARG(double, calc));
|
|
ui->dashSpin->blockSignals(false);
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0))
|
|
QMetaObject::invokeMethod(tone, [=]() {
|
|
tone->setRatio(ratio);
|
|
}, Qt::QueuedConnection);
|
|
#else
|
|
emit setDashRatio(ratio);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void cwSender::handlePitch(unsigned char pitch) {
|
|
int cwPitch = round((((600.0 / 255.0) * pitch) + 300) / 5.0) * 5.0;
|
|
if (cwPitch != ui->pitchSpin->value() && cwPitch >= ui->pitchSpin->minimum() && cwPitch <= ui->pitchSpin->maximum())
|
|
{
|
|
ui->pitchSpin->blockSignals(true);
|
|
QMetaObject::invokeMethod(ui->pitchSpin, "setValue", Qt::QueuedConnection, Q_ARG(int, cwPitch));
|
|
ui->pitchSpin->blockSignals(false);
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0))
|
|
QMetaObject::invokeMethod(tone, [=]() {
|
|
tone->setFrequency(pitch);
|
|
}, Qt::QueuedConnection);
|
|
#else
|
|
emit setPitch(tone);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void cwSender::handleBreakInMode(unsigned char b)
|
|
{
|
|
if(b < 3)
|
|
{
|
|
ui->breakinCombo->blockSignals(true);
|
|
ui->breakinCombo->setCurrentIndex(b);
|
|
ui->breakinCombo->blockSignals(false);
|
|
}
|
|
}
|
|
|
|
void cwSender::handleCurrentModeUpdate(mode_kind mode)
|
|
{
|
|
this->currentMode = mode;
|
|
if( (currentMode==modeCW) || (currentMode==modeCW_R) )
|
|
{
|
|
} else {
|
|
ui->statusbar->showMessage("Note: Mode needs to be set to CW or CW-R to send CW.", 3000);
|
|
}
|
|
}
|
|
|
|
void cwSender::textChanged(QString text)
|
|
{
|
|
if (ui->sendImmediateChk->isChecked() && text.size() && text.back() == ' ')
|
|
{
|
|
int toSend = text.mid(0, 30).size();
|
|
if (toSend > 0) {
|
|
ui->textToSendEdit->clearEditText();
|
|
ui->transcriptText->moveCursor(QTextCursor::End);
|
|
ui->transcriptText->insertPlainText(text.mid(0, 30).toUpper());
|
|
ui->transcriptText->moveCursor(QTextCursor::End);
|
|
|
|
emit sendCW(text.mid(0, 30));
|
|
}
|
|
if( (currentMode != modeCW) && (currentMode != modeCW_R) )
|
|
{
|
|
ui->statusbar->showMessage("Note: Mode needs to be set to CW or CW-R to send CW.", 3000);
|
|
}
|
|
}
|
|
}
|
|
|
|
void cwSender::on_sendBtn_clicked()
|
|
{
|
|
if( (ui->textToSendEdit->currentText().length() > 0) &&
|
|
(ui->textToSendEdit->currentText().length() <= 30) )
|
|
{
|
|
QString text = ui->textToSendEdit->currentText();
|
|
|
|
ui->transcriptText->moveCursor(QTextCursor::End);
|
|
ui->transcriptText->insertPlainText(ui->textToSendEdit->currentText().toUpper()+"\n");
|
|
ui->transcriptText->moveCursor(QTextCursor::End);
|
|
if (!ui->sendImmediateChk->isChecked())
|
|
{
|
|
ui->textToSendEdit->addItem(ui->textToSendEdit->currentText());
|
|
if (ui->textToSendEdit->count() > 5) {
|
|
ui->textToSendEdit->removeItem(0);
|
|
}
|
|
ui->textToSendEdit->setCurrentIndex(-1);
|
|
} else {
|
|
ui->textToSendEdit->clearEditText();
|
|
ui->textToSendEdit->clear();
|
|
}
|
|
|
|
ui->textToSendEdit->setFocus();
|
|
ui->statusbar->showMessage("Sending CW", 3000);
|
|
|
|
emit sendCW(text);
|
|
}
|
|
|
|
if( (currentMode != modeCW) && (currentMode != modeCW_R) )
|
|
{
|
|
ui->statusbar->showMessage("Note: Mode needs to be set to CW or CW-R to send CW.", 3000);
|
|
}
|
|
}
|
|
|
|
void cwSender::on_stopBtn_clicked()
|
|
{
|
|
emit stopCW();
|
|
ui->textToSendEdit->setFocus();
|
|
ui->statusbar->showMessage("Stopping CW transmission.", 3000);
|
|
}
|
|
|
|
//void cwSender::on_textToSendEdit_returnPressed()
|
|
//{
|
|
// on_sendBtn_clicked();
|
|
//}
|
|
|
|
void cwSender::on_breakinCombo_activated(int brkmode)
|
|
{
|
|
// 0 = off, 1 = semi, 2 = full
|
|
emit setBreakInMode((unsigned char)brkmode);
|
|
ui->textToSendEdit->setFocus();
|
|
}
|
|
|
|
void cwSender::on_wpmSpin_valueChanged(int wpm)
|
|
{
|
|
emit setKeySpeed((unsigned char)wpm);
|
|
}
|
|
|
|
void cwSender::on_dashSpin_valueChanged(double ratio)
|
|
{
|
|
emit setDashRatio((unsigned char)double(ratio * 10));
|
|
}
|
|
|
|
void cwSender::on_pitchSpin_valueChanged(int arg1)
|
|
{
|
|
// quint16 cwPitch = round((((600.0 / 255.0) * pitch) + 300) / 5.0) * 5.0;
|
|
unsigned char pitch = 0;
|
|
pitch = ceil((arg1 - 300) * (255.0 / 600.0));
|
|
emit setPitch(pitch);
|
|
}
|
|
|
|
void cwSender::on_macro1btn_clicked()
|
|
{
|
|
processMacroButton(1, ui->macro1btn);
|
|
}
|
|
|
|
void cwSender::on_macro2btn_clicked()
|
|
{
|
|
processMacroButton(2, ui->macro2btn);
|
|
}
|
|
|
|
void cwSender::on_macro3btn_clicked()
|
|
{
|
|
processMacroButton(3, ui->macro3btn);
|
|
}
|
|
|
|
void cwSender::on_macro4btn_clicked()
|
|
{
|
|
processMacroButton(4, ui->macro4btn);
|
|
}
|
|
|
|
void cwSender::on_macro5btn_clicked()
|
|
{
|
|
processMacroButton(5, ui->macro5btn);
|
|
}
|
|
|
|
void cwSender::on_macro6btn_clicked()
|
|
{
|
|
processMacroButton(6, ui->macro6btn);
|
|
}
|
|
|
|
void cwSender::on_macro7btn_clicked()
|
|
{
|
|
processMacroButton(7, ui->macro7btn);
|
|
}
|
|
|
|
void cwSender::on_macro8btn_clicked()
|
|
{
|
|
processMacroButton(8, ui->macro8btn);
|
|
}
|
|
|
|
void cwSender::on_macro9btn_clicked()
|
|
{
|
|
processMacroButton(9, ui->macro9btn);
|
|
}
|
|
|
|
void cwSender::on_macro10btn_clicked()
|
|
{
|
|
processMacroButton(10, ui->macro10btn);
|
|
}
|
|
|
|
void cwSender::on_sidetoneEnableChk_clicked(bool clicked)
|
|
{
|
|
ui->sidetoneLevelSlider->setEnabled(clicked);
|
|
if (clicked && toneThread == Q_NULLPTR)
|
|
{
|
|
toneThread = new QThread(this);
|
|
toneThread->setObjectName("sidetone()");
|
|
|
|
tone = new cwSidetone(sidetoneLevel, ui->wpmSpin->value(),ui->pitchSpin->value(),ui->dashSpin->value(),this);
|
|
tone->moveToThread(toneThread);
|
|
toneThread->start();
|
|
|
|
connections.append(connect(toneThread, &QThread::finished,
|
|
[=]() { tone->deleteLater(); }));
|
|
connections.append(connect(this, &cwSender::sendCW,
|
|
[=](const QString& text) { tone->send(text); ui->sidetoneEnableChk->setEnabled(false); }));
|
|
connections.append(connect(this, &cwSender::setKeySpeed,
|
|
[=](const unsigned char& wpm) { tone->setSpeed(wpm); }));
|
|
connections.append(connect(this, &cwSender::setDashRatio,
|
|
[=](const unsigned char& ratio) { tone->setRatio(ratio); }));
|
|
connections.append(connect(this, &cwSender::setPitch,
|
|
[=](const unsigned char& pitch) { tone->setFrequency(pitch); }));
|
|
connections.append(connect(this, &cwSender::setLevel,
|
|
[=](const unsigned char& level) { tone->setLevel(level); }));
|
|
connections.append(connect(this, &cwSender::stopCW,
|
|
[=]() { tone->stopSending(); }));
|
|
connections.append(connect(tone, &cwSidetone::finished,
|
|
[=]() { ui->sidetoneEnableChk->setEnabled(true); }));
|
|
|
|
} else if (!clicked && toneThread != Q_NULLPTR) {
|
|
/* disconnect all connections */
|
|
toneThread->quit();
|
|
toneThread->wait();
|
|
toneThread = Q_NULLPTR;
|
|
tone = Q_NULLPTR;
|
|
for (auto conn: connections)
|
|
{
|
|
disconnect(conn);
|
|
}
|
|
connections.clear();
|
|
}
|
|
}
|
|
|
|
void cwSender::on_sidetoneLevelSlider_valueChanged(int val)
|
|
{
|
|
sidetoneLevel = val;
|
|
emit setLevel(val);
|
|
}
|
|
|
|
|
|
void cwSender::processMacroButton(int buttonNumber, QPushButton *btn)
|
|
{
|
|
if(ui->macroEditChk->isChecked())
|
|
{
|
|
editMacroButton(buttonNumber, btn);
|
|
} else {
|
|
runMacroButton(buttonNumber);
|
|
}
|
|
ui->textToSendEdit->setFocus();
|
|
}
|
|
|
|
void cwSender::runMacroButton(int buttonNumber)
|
|
{
|
|
if(macroText[buttonNumber].isEmpty())
|
|
return;
|
|
QString outText;
|
|
if(macroText[buttonNumber].contains("%1"))
|
|
{
|
|
outText = macroText[buttonNumber].arg(sequenceNumber, 3, 10, QChar('0'));
|
|
sequenceNumber++;
|
|
ui->sequenceSpin->blockSignals(true);
|
|
QMetaObject::invokeMethod(ui->sequenceSpin, "setValue", Qt::QueuedConnection, Q_ARG(int, sequenceNumber));
|
|
ui->sequenceSpin->blockSignals(false);
|
|
} else {
|
|
outText = macroText[buttonNumber];
|
|
}
|
|
|
|
if (ui->cutNumbersChk->isChecked())
|
|
{
|
|
outText.replace("0", "T");
|
|
outText.replace("9", "N");
|
|
}
|
|
|
|
ui->transcriptText->moveCursor(QTextCursor::End);
|
|
ui->transcriptText->insertPlainText(outText.toUpper()+"\n");
|
|
ui->transcriptText->moveCursor(QTextCursor::End);
|
|
|
|
for (int i = 0; i < outText.size(); i = i + 30) {
|
|
emit sendCW(outText.mid(i,30));
|
|
}
|
|
|
|
ui->textToSendEdit->setFocus();
|
|
|
|
|
|
if( (currentMode==modeCW) || (currentMode==modeCW_R) )
|
|
{
|
|
ui->statusbar->showMessage(QString("Sending CW macro %1").arg(buttonNumber));
|
|
} else {
|
|
ui->statusbar->showMessage("Note: Mode needs to be set to CW or CW-R to send CW.");
|
|
}
|
|
}
|
|
|
|
void cwSender::editMacroButton(int buttonNumber, QPushButton* btn)
|
|
{
|
|
bool ok;
|
|
QString promptFirst = QString("Please enter the text for macro %1,\n"
|
|
"up to 60 characters.\n").arg(buttonNumber);
|
|
QString promptSecond = QString("You may use \"%1\" to insert a sequence number.");
|
|
QString prompt = promptFirst+promptSecond;
|
|
|
|
QString newMacroText = QInputDialog::getText(this, "Macro Edit",
|
|
prompt,
|
|
QLineEdit::Normal, macroText[buttonNumber], &ok).toUpper();
|
|
if(!ok)
|
|
return;
|
|
|
|
if (newMacroText.length() > 60)
|
|
{
|
|
QMessageBox msgBox;
|
|
msgBox.setText(QString("The text entered was too long \n"
|
|
"(max length is 60 characters).\n"
|
|
"Your input was %1 characters.").arg(newMacroText.length()));
|
|
msgBox.exec();
|
|
this->raise();
|
|
return;
|
|
}
|
|
|
|
macroText[buttonNumber] = newMacroText;
|
|
setMacroButtonText(newMacroText, btn);
|
|
}
|
|
|
|
void cwSender::setMacroButtonText(QString btnText, QPushButton *btn)
|
|
{
|
|
if(btn==Q_NULLPTR)
|
|
return;
|
|
if(btnText.isEmpty())
|
|
return;
|
|
|
|
QString shortBtnName;
|
|
if(btnText.length() <= 8)
|
|
{
|
|
shortBtnName = btnText;
|
|
} else {
|
|
shortBtnName = btnText.left(7);
|
|
shortBtnName.append("…");
|
|
}
|
|
btn->setText(shortBtnName);
|
|
}
|
|
|
|
void cwSender::on_sequenceSpin_valueChanged(int newSeq)
|
|
{
|
|
sequenceNumber = newSeq;
|
|
ui->textToSendEdit->setFocus();
|
|
}
|
|
|
|
bool cwSender::getCutNumbers()
|
|
{
|
|
return ui->cutNumbersChk->isChecked();
|
|
}
|
|
|
|
bool cwSender::getSendImmediate()
|
|
{
|
|
return ui->sendImmediateChk->isChecked();
|
|
}
|
|
|
|
bool cwSender::getSidetoneEnable()
|
|
{
|
|
return ui->sidetoneEnableChk->isChecked();
|
|
}
|
|
|
|
int cwSender::getSidetoneLevel()
|
|
{
|
|
return ui->sidetoneLevelSlider->value();
|
|
}
|
|
|
|
void cwSender::setCutNumbers(bool val)
|
|
{
|
|
ui->cutNumbersChk->setChecked(val);
|
|
}
|
|
|
|
void cwSender::setSendImmediate(bool val)
|
|
{
|
|
ui->sendImmediateChk->setChecked(val);
|
|
}
|
|
|
|
void cwSender::setSidetoneEnable(bool val)
|
|
{
|
|
ui->sidetoneEnableChk->setChecked(val);
|
|
on_sidetoneEnableChk_clicked(val);
|
|
}
|
|
|
|
void cwSender::setSidetoneLevel(int val)
|
|
{
|
|
QMetaObject::invokeMethod(ui->sidetoneLevelSlider, "setValue", Qt::QueuedConnection, Q_ARG(int, val));
|
|
}
|
|
|
|
QStringList cwSender::getMacroText()
|
|
{
|
|
// This is for preference saving:
|
|
QStringList mlist;
|
|
for(int i=1; i < 11; i++)
|
|
{
|
|
mlist << macroText[i];
|
|
}
|
|
return mlist;
|
|
}
|
|
|
|
void cwSender::setMacroText(QStringList macros)
|
|
{
|
|
if(macros.length() != 10)
|
|
{
|
|
qCritical(logCW()) << "Macro list must be exactly 10. Rejecting macro text load.";
|
|
return;
|
|
}
|
|
|
|
for(int i=0; i < 10; i++)
|
|
{
|
|
macroText[i+1] = macros.at(i);
|
|
}
|
|
|
|
setMacroButtonText(macroText[1], ui->macro1btn);
|
|
setMacroButtonText(macroText[2], ui->macro2btn);
|
|
setMacroButtonText(macroText[3], ui->macro3btn);
|
|
setMacroButtonText(macroText[4], ui->macro4btn);
|
|
setMacroButtonText(macroText[5], ui->macro5btn);
|
|
setMacroButtonText(macroText[6], ui->macro6btn);
|
|
setMacroButtonText(macroText[7], ui->macro7btn);
|
|
setMacroButtonText(macroText[8], ui->macro8btn);
|
|
setMacroButtonText(macroText[9], ui->macro9btn);
|
|
setMacroButtonText(macroText[10], ui->macro10btn);
|
|
}
|