Merge branch 'feat-a7-UR' into develop

This commit is contained in:
Steven Franke
2022-04-25 07:23:06 -05:00
27 changed files with 1995 additions and 598 deletions
+123 -43
View File
@@ -90,6 +90,8 @@
#include "ui_mainwindow.h"
#include "moc_mainwindow.cpp"
#define FCL fortran_charlen_t
extern "C" {
//----------------------------------------------------- C and Fortran routines
void symspec_(struct dec_data *, int* k, double* trperiod, int* nsps, int* ingain,
@@ -133,8 +135,7 @@ extern "C" {
void genmsk_128_90_(char* msg, int* ichk, char* msgsent, int itone[], int* itype,
fortran_charlen_t, fortran_charlen_t);
void gen65_(char* msg, int* ichk, char* msgsent, int itone[],
int* itext, fortran_charlen_t, fortran_charlen_t);
void gen65(char* msg, int* ichk, char msgsent[], int itone[], int* itext);
void genq65_(char* msg, int* ichk, char* msgsent, int itone[],
int* i3, int* n3, fortran_charlen_t, fortran_charlen_t);
@@ -147,8 +148,6 @@ extern "C" {
void morse_(char* msg, int* icw, int* ncw, fortran_charlen_t);
int ptt_(int nport, int ntx, int* iptt, int* nopen);
void wspr_downsample_(short int d2[], int* k);
int savec2_(char const * fname, int* TR_seconds, double* dial_freq, fortran_charlen_t);
@@ -170,8 +169,6 @@ extern "C" {
void freqcal_(short d2[], int* k, int* nkhz,int* noffset, int* ntol,
char line[], fortran_charlen_t);
void fix_contest_msg_(char* MyGrid, char* msg, fortran_charlen_t, fortran_charlen_t);
void calibrate_(char const * data_dir, int* iz, double* a, double* b, double* rms,
double* sigmaa, double* sigmab, int* irc, fortran_charlen_t);
@@ -179,13 +176,9 @@ extern "C" {
void plotsave_(float swide[], int* m_w , int* m_h1, int* irow);
void chkcall_(char* w, char* basc_call, bool cok, int len1, int len2);
void get_ft4msg_(int* idecode, char* line, int len);
void chk_samples_(int* m_ihsym,int* k, int* m_hsymStop);
void save_dxbase_(char* dxbase, int len);
void save_dxbase_(char* dxbase, FCL len);
}
int volatile itone[MAX_NUM_SYMBOLS]; //Audio tones for all Tx symbols
@@ -604,6 +597,12 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->actionSave_decoded->setActionGroup(saveGroup);
ui->actionSave_all->setActionGroup(saveGroup);
QActionGroup* alltxtGroup = new QActionGroup(this);
ui->actionDon_t_split_ALL_TXT->setActionGroup(alltxtGroup);
ui->actionSplit_ALL_TXT_yearly->setActionGroup(alltxtGroup);
ui->actionSplit_ALL_TXT_monthly->setActionGroup(alltxtGroup);
ui->actionDisable_writing_of_ALL_TXT->setActionGroup(alltxtGroup);
QActionGroup* DepthGroup = new QActionGroup(this);
ui->actionQuickDecode->setActionGroup(DepthGroup);
ui->actionMediumDecode->setActionGroup(DepthGroup);
@@ -954,7 +953,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->txFirstCheckBox->setChecked(m_txFirst);
morse_(const_cast<char *> (m_config.my_callsign ().toLatin1().constData()),
const_cast<int *> (icw), &m_ncw, m_config.my_callsign ().length());
const_cast<int *> (icw), &m_ncw, (FCL)m_config.my_callsign().length());
on_actionWide_Waterfall_triggered();
ui->cbShMsgs->setChecked(m_bShMsgs);
ui->cbSWL->setChecked(m_bSWL);
@@ -1188,6 +1187,10 @@ void MainWindow::writeSettings()
}
m_settings->setValue ("PhaseEqualizationCoefficients", QVariant {coeffs});
}
m_settings->setValue ("actionDontSplitALLTXT", ui->actionDon_t_split_ALL_TXT->isChecked() );
m_settings->setValue ("splitAllTxtYearly", ui->actionSplit_ALL_TXT_yearly->isChecked() );
m_settings->setValue ("splitAllTxtMonthly", ui->actionSplit_ALL_TXT_monthly->isChecked() );
m_settings->setValue ("disableWritingOfAllTxt", ui->actionDisable_writing_of_ALL_TXT->isChecked() );
m_settings->endGroup();
}
@@ -1230,6 +1233,10 @@ void MainWindow::readSettings()
ui->actionAstronomical_data->setChecked (displayAstro);
m_settings->beginGroup("Common");
ui->actionDon_t_split_ALL_TXT->setChecked(m_settings->value("actionDontSplitALLTXT", true).toBool());
ui->actionSplit_ALL_TXT_yearly->setChecked(m_settings->value("splitAllTxtYearly", false).toBool());
ui->actionSplit_ALL_TXT_monthly->setChecked(m_settings->value("splitAllTxtMonthly", false).toBool());
ui->actionDisable_writing_of_ALL_TXT->setChecked(m_settings->value("disableWritingOfAllTxt", false).toBool());
m_mode=m_settings->value("Mode","JT9").toString();
ui->actionNone->setChecked(m_settings->value("SaveNone",true).toBool());
ui->actionSave_decoded->setChecked(m_settings->value("SaveDecoded",false).toBool());
@@ -1306,7 +1313,7 @@ void MainWindow::readSettings()
// use these initialisation settings to tune the audio o/p buffer
// size and audio thread priority
m_settings->beginGroup ("Tune");
m_audioThreadPriority = static_cast<QThread::Priority> (m_settings->value ("Audio/ThreadPriority", QThread::HighPriority).toInt () % 8);
m_audioThreadPriority = static_cast<QThread::Priority> (m_settings->value ("Audio/ThreadPriority", QThread::TimeCriticalPriority).toInt () % 8);
m_settings->endGroup ();
checkMSK144ContestType();
@@ -1440,7 +1447,7 @@ void MainWindow::dataSink(qint64 frames)
m_bUseRef=m_wideGraph->useRef();
if(!m_diskData) {
refspectrum_(&dec_data.d2[k-m_nsps/2],&m_bClearRefSpec,&m_bRefSpec,
&m_bUseRef, fname.constData (), fname.size ());
&m_bUseRef, fname.constData (), (FCL)fname.size ());
}
m_bClearRefSpec=false;
@@ -1480,7 +1487,7 @@ void MainWindow::dataSink(qint64 frames)
int RxFreq=ui->RxFreqSpinBox->value ();
int nkhz=(m_freqNominal+RxFreq)/1000;
int ftol = ui->sbFtol->value ();
freqcal_(&dec_data.d2[0],&k,&nkhz,&RxFreq,&ftol,&line[0],80);
freqcal_(&dec_data.d2[0], &k, &nkhz, &RxFreq, &ftol, &line[0], (FCL)80);
QString t=QString::fromLatin1(line);
DecodedText decodedtext {t};
ui->decodedTextBrowser->displayDecodedText (decodedtext, m_config.my_callsign (), m_mode, m_config.DXCC (),
@@ -1599,7 +1606,7 @@ void MainWindow::dataSink(qint64 frames)
int nsec=120;
int nbfo=1500;
double f0m1500=m_freqNominal/1000000.0 + nbfo - 1500;
int err = savec2_(c2name.constData (),&nsec,&f0m1500, c2name.size ());
int err = savec2_(c2name.constData (),&nsec,&f0m1500, (FCL)c2name.size());
if (err!=0) MessageBox::warning_message (this, tr ("Error saving c2 file"), c2name);
}
}
@@ -1720,9 +1727,10 @@ void MainWindow::fastSink(qint64 frames)
float rmsNoGain = 0;
int ftol = ui->sbFtol->value ();
hspec_(dec_data.d2,&k,&nutc0,&nTRpDepth,&RxFreq,&ftol,&bmsk144,
&m_bTrain,m_phaseEqCoefficients.constData(),&m_inGain,&dec_data.params.mycall[0],
&dec_data.params.hiscall[0],&bshmsg,&bswl,
data_dir.constData (),fast_green,fast_s,&fast_jh,&pxmax,&rmsNoGain,&line[0],12,12,data_dir.size (),80);
&m_bTrain,m_phaseEqCoefficients.constData(),&m_inGain,&dec_data.params.mycall[0],
&dec_data.params.hiscall[0],&bshmsg,&bswl,
data_dir.constData (),fast_green,fast_s,&fast_jh,&pxmax,&rmsNoGain,&line[0],(FCL)12,
(FCL)12,(FCL)data_dir.size (),(FCL)80);
float px = fast_green[fast_jh];
QString t;
t = t.asprintf(" Rx noise: %5.1f ",px);
@@ -1824,7 +1832,7 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
m_baseCall = Radio::base_callsign (m_config.my_callsign ());
ui->tx1->setEnabled (elide_tx1_not_allowed () || ui->tx1->isEnabled ());
morse_(const_cast<char *> (m_config.my_callsign ().toLatin1().constData()),
const_cast<int *> (icw), &m_ncw, m_config.my_callsign ().length());
const_cast<int *> (icw), &m_ncw, (FCL)m_config.my_callsign().length());
}
if (m_config.my_callsign () != callsign || m_config.my_grid () != my_grid) {
statusUpdate ();
@@ -2537,7 +2545,7 @@ void MainWindow::on_actionSolve_FreqCal_triggered()
auto data_dir {QDir::toNativeSeparators(m_config.writeable_data_dir().absolutePath()).toLocal8Bit ()};
int iz,irc;
double a,b,rms,sigmaa,sigmab;
calibrate_(data_dir.constData (),&iz,&a,&b,&rms,&sigmaa,&sigmab,&irc,data_dir.size ());
calibrate_(data_dir.constData(), &iz, &a, &b, &rms, &sigmaa, &sigmab, &irc, (FCL)data_dir.size());
QString t2;
if(irc==-1) t2="Cannot open " + data_dir + "/fmt.all";
if(irc==-2) t2="Cannot open " + data_dir + "/fcal2.out";
@@ -2582,7 +2590,7 @@ void MainWindow::on_actionCopyright_Notice_triggered()
"\"The algorithms, source code, look-and-feel of WSJT-X and related "
"programs, and protocol specifications for the modes FSK441, FST4, FT8, "
"JT4, JT6M, JT9, JT65, JTMS, QRA64, Q65, MSK144 are Copyright (C) "
"2001-2021 by one or more of the following authors: Joseph Taylor, "
"2001-2022 by one or more of the following authors: Joseph Taylor, "
"K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo, "
"IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR; "
"Philip Karn, KA9Q; and other members of the WSJT Development Group.\"");
@@ -3211,9 +3219,9 @@ void MainWindow::decode() //decode()
narg[13]=-1;
narg[14]=m_config.aggressive();
memcpy(d2b,dec_data.d2,2*360000);
watcher3.setFuture (QtConcurrent::run (std::bind (fast_decode_,&d2b[0],
&narg[0],&m_TRperiod,&m_msg[0][0],
dec_data.params.mycall,dec_data.params.hiscall,8000,12,12)));
watcher3.setFuture (QtConcurrent::run (std::bind (fast_decode_, &d2b[0],
&narg[0],&m_TRperiod, &m_msg[0][0], dec_data.params.mycall,
dec_data.params.hiscall, (FCL)8000, (FCL)12, (FCL)12)));
} else {
mem_jt9->lock ();
memcpy(to, from, qMin(mem_jt9->size(), size));
@@ -3457,6 +3465,15 @@ void MainWindow::readFromStdout() //readFromStdout
ui->cbCQonly->isVisible() && ui->cbCQonly->isChecked(),
haveFSpread, fSpread);
if (m_config.highlight_DXcall () && (m_hisCall!="") && ((decodedtext.string().contains(QRegularExpression {"(\\w+) " + m_hisCall}))
|| (decodedtext.string().contains(QRegularExpression {"(\\w+) <" + m_hisCall +">"}))
|| (decodedtext.string().contains(QRegularExpression {"<(\\w+)> " + m_hisCall})))) {
ui->decodedTextBrowser->highlight_callsign(m_hisCall, QColor(255,0,0), QColor(255,255,255), true); // highlight dxCallEntry
}
if (m_config.highlight_DXgrid () && (m_hisGrid!="") && (decodedtext.string().contains(m_hisGrid))) {
ui->decodedTextBrowser->highlight_callsign(m_hisGrid, QColor(0,0,255), QColor(255,255,255), true); // highlight dxGridEntry
}
if(m_bBestSPArmed && m_mode=="FT4" && CALLING == m_QSOProgress) {
QString messagePriority=ui->decodedTextBrowser->CQPriority();
if(messagePriority!="") {
@@ -3709,7 +3726,8 @@ void MainWindow::auto_sequence (DecodedText const& message, unsigned start_toler
void MainWindow::pskPost (DecodedText const& decodedtext)
{
if (m_diskData || !m_config.spot_to_psk_reporter() || decodedtext.isLowConfidence ()) return;
if (m_diskData || !m_config.spot_to_psk_reporter() || decodedtext.isLowConfidence ()
|| (decodedtext.string().contains(m_baseCall) && decodedtext.string().contains(m_config.my_grid().left(4)))) return; // prevent self-spotting when running multiple instances
QString msgmode=m_mode;
QString deCall;
@@ -4019,18 +4037,18 @@ void MainWindow::guiUpdate()
if(m_QSOProgress==REPORT || m_QSOProgress==ROGER_REPORT) m_bSentReport=true;
if(m_bSentReport and (m_QSOProgress<REPORT or m_QSOProgress>ROGER_REPORT)) m_bSentReport=false;
if(m_mode=="JT4") gen4_(message, &ichk , msgsent, const_cast<int *> (itone),
&m_currentMessageType, 22, 22);
&m_currentMessageType, (FCL)22, (FCL)22);
if(m_mode=="JT9") gen9_(message, &ichk, msgsent, const_cast<int *> (itone),
&m_currentMessageType, 22, 22);
if(m_mode=="JT65") gen65_(message, &ichk, msgsent, const_cast<int *> (itone),
&m_currentMessageType, 22, 22);
&m_currentMessageType, (FCL)22, (FCL)22);
if(m_mode=="JT65") gen65(message, &ichk, msgsent, const_cast<int *> (itone),
&m_currentMessageType);
if(m_mode=="WSPR") genwspr_(message, msgsent, const_cast<int *> (itone),
22, 22);
(FCL)22, (FCL)22);
if(m_mode=="MSK144" or m_mode=="FT8" or m_mode=="FT4"
or m_mode=="FST4" or m_mode=="FST4W" || "Q65" == m_mode) {
if(m_mode=="MSK144") {
genmsk_128_90_(message, &ichk, msgsent, const_cast<int *> (itone),
&m_currentMessageType, 37, 37);
&m_currentMessageType, (FCL)37, (FCL)37);
if(m_restart) {
int nsym=144;
if(itone[40]==-40) nsym=40;
@@ -4046,7 +4064,7 @@ void MainWindow::guiUpdate()
int n3=0;
char ft8msgbits[77];
genft8_(message, &i3, &n3, msgsent, const_cast<char *> (ft8msgbits),
const_cast<int *> (itone), 37, 37);
const_cast<int *> (itone), (FCL)37, (FCL)37);
int nsym=79;
int nsps=4*1920;
float fsample=48000.0;
@@ -4073,7 +4091,7 @@ void MainWindow::guiUpdate()
int ichk=0;
char ft4msgbits[77];
genft4_(message, &ichk, msgsent, const_cast<char *> (ft4msgbits),
const_cast<int *>(itone), 37, 37);
const_cast<int *>(itone), (FCL)37, (FCL)37);
int nsym=103;
int nsps=4*576;
float fsample=48000.0;
@@ -4095,7 +4113,7 @@ void MainWindow::guiUpdate()
ba2msg(ba,message);
}
genfst4_(message,&ichk,msgsent,const_cast<char *> (fst4msgbits),
const_cast<int *>(itone), &iwspr, 37, 37);
const_cast<int *>(itone), &iwspr, (FCL)37, (FCL)37);
int hmod=1;
if(m_config.x2ToneSpacing()) hmod=2;
if(m_config.x4ToneSpacing()) hmod=4;
@@ -4122,7 +4140,7 @@ void MainWindow::guiUpdate()
if(m_mode=="Q65") {
int i3=-1;
int n3=-1;
genq65_(message,&ichk,msgsent,const_cast<int *>(itone),&i3,&n3,37,37);
genq65_(message, &ichk,msgsent, const_cast<int *>(itone), &i3, &n3, (FCL)37, (FCL)37);
int nsps=1800;
if(m_TRperiod==30) nsps=3600;
if(m_TRperiod==60) nsps=7200;
@@ -5374,7 +5392,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
auto is_type_one = !is77BitMode () && is_compound && shortList (my_callsign);
auto const& my_grid = m_config.my_grid ().left (4);
auto const& hisBase = Radio::base_callsign (hisCall);
save_dxbase_(const_cast <char *> ((hisBase + " ").left (6).toLatin1().constData()),6);
save_dxbase_(const_cast <char *> ((hisBase + " ").left(6).toLatin1().constData()), (FCL)6);
auto eme_short_codes = m_config.enable_VHF_features () && ui->cbShMsgs->isChecked ()
&& m_mode == "JT65";
@@ -5761,7 +5779,7 @@ void MainWindow::msgtype(QString t, QLineEdit* tx) //msgtype()
QByteArray s=t.toUpper().toLocal8Bit();
ba2msg(s,message);
int ichk=1,itype=0;
gen65_(message,&ichk,msgsent,const_cast<int*>(itone0),&itype,22,22);
gen65(message, &ichk,msgsent, const_cast<int*>(itone0), &itype);
msgsent[22]=0;
bool text=false;
bool shortMsg=false;
@@ -5859,7 +5877,7 @@ void MainWindow::on_dxCallEntry_textChanged (QString const& call)
void MainWindow::on_dxCallEntry_editingFinished()
{
auto const& dxBase = Radio::base_callsign (m_hisCall);
save_dxbase_(const_cast <char *> ((dxBase + " ").left (6).toLatin1().constData()),6);
save_dxbase_(const_cast <char *> ((dxBase + " ").left (6).toLatin1().constData()), (FCL)6);
}
@@ -5880,7 +5898,7 @@ void MainWindow::on_dxGridEntry_textChanged (QString const& grid)
int nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter;
azdist_(const_cast <char *> ((m_config.my_grid () + " ").left (6).toLatin1().constData()),
const_cast <char *> ((m_hisGrid + " ").left (6).toLatin1().constData()),&utch,
&nAz,&nEl,&nDmiles,&nDkm,&nHotAz,&nHotABetter,6,6);
&nAz,&nEl,&nDmiles,&nDkm,&nHotAz,&nHotABetter,(FCL)6,(FCL)6);
QString t;
int nd=nDkm;
if(m_config.miles()) nd=nDmiles;
@@ -6012,6 +6030,8 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
m_xSent.clear ();
m_xRcvd.clear ();
if (m_config.clear_DXcall ()) ui->dxCallEntry->clear ();
if (m_config.clear_DXgrid ()) ui->dxGridEntry->clear ();
}
qint64 MainWindow::nWidgets(QString t)
@@ -6221,7 +6241,6 @@ void MainWindow::on_actionFT8_triggered()
m_bFast9=false;
m_bFastMode=false;
WSPR_config(false);
switch_mode (Modes::FT8);
m_nsps=6912;
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
@@ -6272,6 +6291,8 @@ void MainWindow::on_actionFT8_triggered()
on_fox_log_action_triggered();
}
if(SpecOp::HOUND == m_config.special_op_id()) {
ui->houndButton->setChecked(true);
ui->houndButton->setStyleSheet("background-color: #ff0000;");
ui->txFirstCheckBox->setChecked(false);
ui->txFirstCheckBox->setEnabled(false);
ui->cbAutoSeq->setEnabled(false);
@@ -6289,6 +6310,8 @@ void MainWindow::on_actionFT8_triggered()
ui->txb4->setEnabled(false);
ui->txb5->setEnabled(false);
ui->txb6->setEnabled(false);
} else {
switch_mode (Modes::FT8);
}
if (SpecOp::NONE < m_config.special_op_id () && SpecOp::FOX > m_config.special_op_id ()) {
@@ -7034,6 +7057,7 @@ void MainWindow::on_rptSpinBox_valueChanged(int n)
void MainWindow::on_tuneButton_clicked (bool checked)
{
tuneATU_Timer.start (120000); // tune watchdog (120s)
static bool lastChecked = false;
if (lastChecked == checked) return;
lastChecked = checked;
@@ -7814,7 +7838,7 @@ void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 de
showNormal ();
raise ();
}
if (text.contains (QRegularExpression {R"(^(CQ |CQDX |QRZ ))"})) {
if ((text.contains (QRegularExpression {R"(^(CQ |CQDX |QRZ ))"})) || (ui->cbHoldTxFreq->isChecked ())) {
// a message we are willing to accept and auto reply to
m_bDoubleClicked = true;
}
@@ -8010,7 +8034,7 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout
int nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter;
azdist_(const_cast <char *> ((m_config.my_grid () + " ").left (6).toLatin1 ().constData ()),
const_cast <char *> ((grid + " ").left (6).toLatin1 ().constData ()),&utch,
&nAz,&nEl,&nDmiles,&nDkm,&nHotAz,&nHotABetter,6,6);
&nAz,&nEl,&nDmiles,&nDkm,&nHotAz,&nHotABetter,(FCL)6,(FCL)6);
QString t1;
if(m_config.miles()) {
t1 = t1.asprintf("%7d",nDmiles);
@@ -9221,6 +9245,7 @@ void MainWindow::foxTest()
void MainWindow::write_all(QString txRx, QString message)
{
if (!(ui->actionDisable_writing_of_ALL_TXT->isChecked())) {
QString line;
QString t;
QString msg;
@@ -9261,6 +9286,8 @@ void MainWindow::write_all(QString txRx, QString message)
}
QString file_name="ALL.TXT";
if (ui->actionSplit_ALL_TXT_yearly->isChecked()) file_name=(time.toString("yyyy") + "-" + "ALL.TXT");
if (ui->actionSplit_ALL_TXT_monthly->isChecked()) file_name=(time.toString("yyyy-MM") + "-" + "ALL.TXT");
if (m_mode=="WSPR") file_name="ALL_WSPR.TXT";
QFile f{m_config.writeable_data_dir().absoluteFilePath(file_name)};
if (f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) {
@@ -9279,6 +9306,7 @@ void MainWindow::write_all(QString txRx, QString message)
QTimer::singleShot (0, [=] { // don't block guiUpdate
MessageBox::warning_message(this, tr ("Log File Error"), message2); });
}
}
}
void MainWindow::chkFT4()
@@ -9443,3 +9471,55 @@ QString MainWindow::WSPR_message()
}
return msg2;
}
void MainWindow::on_houndButton_clicked (bool checked)
{
if (checked) {
ui->houndButton->setStyleSheet("background-color: #ff0000;");
m_config.setSpecial_Hound();
} else {
ui->houndButton->setStyleSheet("");
m_config.setSpecial_None();
}
on_actionFT8_triggered();
}
void MainWindow::on_ft8Button_clicked()
{
ui->houndButton->setChecked(false);
ui->houndButton->setStyleSheet("");
m_config.setSpecial_None();
on_actionFT8_triggered();
}
void MainWindow::on_ft4Button_clicked()
{
ui->houndButton->setChecked(false);
ui->houndButton->setStyleSheet("");
m_config.setSpecial_None();
on_actionFT4_triggered();
}
void MainWindow::on_msk144Button_clicked()
{
ui->houndButton->setChecked(false);
ui->houndButton->setStyleSheet("");
m_config.setSpecial_None();
on_actionMSK144_triggered();
}
void MainWindow::on_q65Button_clicked()
{
ui->houndButton->setChecked(false);
ui->houndButton->setStyleSheet("");
m_config.setSpecial_None();
on_actionQ65_triggered();
}
void MainWindow::on_jt65Button_clicked()
{
ui->houndButton->setChecked(false);
ui->houndButton->setStyleSheet("");
m_config.setSpecial_None();
on_actionJT65_triggered();
}