#include "wfmain.h" #include "ui_wfmain.h" #include "rigidentities.h" #include "logcategories.h" // This code is copyright 2017-2022 Elliott H. Liggett // All rights reserved // Log support: //static void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg); QScopedPointer m_logFile; QMutex logMutex; QMutex logTextMutex; QVector> logStringBuffer; #ifdef QT_DEBUG bool debugModeLogging = true; #else bool debugModeLogging = false; #endif wfmain::wfmain(const QString settingsFile, const QString logFile, bool debugMode, QWidget *parent ) : QMainWindow(parent), ui(new Ui::wfmain), logFilename(logFile) { QGuiApplication::setApplicationDisplayName("wfview"); QGuiApplication::setApplicationName(QString("wfview")); setWindowIcon(QIcon( QString(":resources/wfview.png"))); this->debugMode = debugMode; debugModeLogging = debugMode; ui->setupUi(this); setWindowTitle(QString("wfview")); ui->monitorLabel->setText("Mon"); logWindow = new loggingWindow(logFile); initLogging(); logWindow->setInitialDebugState(debugMode); qInfo(logSystem()).noquote() << QString("wfview version: %1 (Git:%2 on %3 at %4 by %5@%6)") .arg(QString(WFVIEW_VERSION),GITSHORT,__DATE__,__TIME__,UNAME,HOST); qInfo(logSystem()).noquote() << QString("Operating System: %0 (%1)").arg(QSysInfo::prettyProductName(),QSysInfo::buildCpuArchitecture()); qInfo(logSystem()).noquote() << "Looking for External Dependencies:"; qInfo(logSystem()).noquote() << QString("QT Runtime Version: %0").arg(qVersion()); if (strncmp(QT_VERSION_STR, qVersion(),sizeof(QT_VERSION_STR))) { qWarning(logSystem()).noquote() << QString("QT Build Version Mismatch: %0").arg(QT_VERSION_STR); } qInfo(logSystem()).noquote() << QString("OPUS Version: %0").arg(opus_get_version_string()); #ifdef HID_API_VERSION_MAJOR qInfo(logSystem()).noquote() << QString("HIDAPI Version: %0.%1.%2") .arg(HID_API_VERSION_MAJOR) .arg(HID_API_VERSION_MINOR) .arg(HID_API_VERSION_PATCH); if (HID_API_VERSION != HID_API_MAKE_VERSION(hid_version()->major, hid_version()->minor, hid_version()->patch)) { qWarning(logSystem()).noquote() << QString("HIDAPI Version mismatch: %0.%1.%2") .arg(hid_version()->major) .arg(hid_version()->minor) .arg(hid_version()->patch); } #endif #ifdef EIGEN_WORLD_VERSION qInfo(logSystem()).noquote() << QString("EIGEN Version: %0.%1.%2").arg(EIGEN_WORLD_VERSION).arg(EIGEN_MAJOR_VERSION).arg(EIGEN_MINOR_VERSION); #endif #ifdef QCUSTOMPLOT_VERSION_STR qInfo(logSystem()).noquote() << QString("QCUSTOMPLOT Version: %0").arg(QCUSTOMPLOT_VERSION_STR); #endif #ifdef RTAUDIO_VERSION qInfo(logSystem()).noquote() << QString("RTAUDIO Version: %0").arg(RTAUDIO_VERSION); if (RTAUDIO_VERSION != RtAudio::getVersion()) { qWarning(logSystem()).noquote() << QString("RTAUDIO Version Mismatch: %0").arg(RtAudio::getVersion().c_str()); } #endif qInfo(logSystem()).noquote() << QString("PORTAUDIO Version: %0").arg(Pa_GetVersionText()); cal = new calibrationWindow(); rpt = new repeaterSetup(); sat = new satelliteSetup(); cw = new cwSender(); abtBox = new aboutbox(); selRad = new selectRadio(); bandbtns = new bandbuttons(); finputbtns = new frequencyinputwidget(); setupui = new settingswidget(); qRegisterMetaType(); // Needs to be registered early. qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType>(); qRegisterMetaType*>(); qRegisterMetaType*>(); qRegisterMetaType*>(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType>(); qRegisterMetaType>(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); //qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); this->setObjectName("wfmain"); queue = cachingQueue::getInstance(this); connect(queue,SIGNAL(sendValue(cacheItem)),this,SLOT(receiveValue(cacheItem))); // We need to populate the list of rigs as early as possible so do it now #ifndef Q_OS_LINUX QString systemRigLocation = QCoreApplication::applicationDirPath(); #else QString systemRigLocation = PREFIX; #endif #ifdef Q_OS_LINUX systemRigLocation += "/share/wfview/rigs"; #else systemRigLocation +="/rigs"; #endif QDir systemRigDir(systemRigLocation); if (!systemRigDir.exists()) { qWarning() << "********* Rig directory does not exist ********"; } else { QStringList rigs = systemRigDir.entryList(QStringList() << "*.rig" << "*.RIG", QDir::Files); for (QString &rig: rigs) { QSettings* rigSettings = new QSettings(systemRigDir.absoluteFilePath(rig), QSettings::Format::IniFormat); #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) rigSettings->setIniCodec("UTF-8"); #endif if (!rigSettings->childGroups().contains("Rig")) { qWarning() << rig << "Does not seem to be a rig description file"; delete rigSettings; continue; } rigSettings->beginGroup("Rig"); qDebug() << QString("Found Rig %0 with CI-V address of %1").arg(rigSettings->value("Model","").toString(), rigSettings->value("CIVAddress",0).toString()); // Any user modified rig files will override system provided ones. this->rigList.insert(rigSettings->value("CIVAddress",0).toInt(),systemRigDir.absoluteFilePath(rig)); rigSettings->endGroup(); delete rigSettings; } } QString userRigLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)+"/rigs"; QDir userRigDir(userRigLocation); if (userRigDir.exists()){ QStringList rigs = userRigDir.entryList(QStringList() << "*.rig" << "*.RIG", QDir::Files); for (QString& rig: rigs) { QSettings* rigSettings = new QSettings(userRigDir.absoluteFilePath(rig), QSettings::Format::IniFormat); if (!rigSettings->childGroups().contains("Rig")) { qWarning() << rig << "Does not seem to be a rig description file"; delete rigSettings; continue; } rigSettings->beginGroup("Rig"); qDebug() << QString("Found User Rig %0 with CI-V address of %1").arg(rigSettings->value("Model","").toString(), rigSettings->value("CIVAddress",0).toString()); // Any user modified rig files will override system provided ones. this->rigList.insert(rigSettings->value("CIVAddress",0).toInt(),userRigDir.absoluteFilePath(rig)); rigSettings->endGroup(); delete rigSettings; } } // Setup the connectiontimer as we will need it soon! ConnectionTimer.setSingleShot(true); connect(&ConnectionTimer,SIGNAL(timeout()), this,SLOT(connectionTimeout())); // Make sure we know about any changes to rigCaps connect(queue, SIGNAL(rigCapsUpdated(rigCapabilities*)), this, SLOT(receiveRigCaps(rigCapabilities*))); setupKeyShortcuts(); setupMainUI(); connectSettingsWidget(); setSerialDevicesUI(); setDefPrefs(); getSettingsFilePath(settingsFile); setDefaultColorPresets(); loadSettings(); // Look for saved preferences //setAudioDevicesUI(); // no need to call this as it will be called by the updated() signal setTuningSteps(); // TODO: Combine into preferences changeFullScreenMode(prefs.useFullScreen); useSystemTheme(prefs.useSystemTheme); finputbtns->setAutomaticSidebandSwitching(prefs.automaticSidebandSwitching); qDebug(logSystem()) << "Running setInititalTiming()"; setInitialTiming(); fts = new FirstTimeSetup(); if(prefs.hasRunSetup) { qDebug(logSystem()) << "Running openRig()"; openRig(); } else { qInfo(logSystem()) << "Detected first-time run. Showing the First Time Setup widget."; connect(fts, &FirstTimeSetup::exitProgram, [=]() { qInfo(logSystem()) << "User elected exit program."; prefs.settingsChanged = false; prefs.confirmExit = false; QTimer::singleShot(10, [&](){ on_exitBtn_clicked(); }); }); connect(fts, &FirstTimeSetup::showSettings, [=](const bool networkEnabled) { qInfo(logSystem()) << "User elected to visit the Settings UI."; prefs.enableLAN = networkEnabled; setupui->updateLanPrefs((int)l_all); showAndRaiseWidget(setupui); prefs.settingsChanged = true; prefs.hasRunSetup = true; }); connect(fts, &FirstTimeSetup::skipSetup, [=]() { qInfo(logSystem()) << "User elected to skip the setup. Marking setup complete."; prefs.settingsChanged = true; prefs.hasRunSetup = true; }); fts->exec(); } cluster = new dxClusterClient(); clusterThread = new QThread(this); clusterThread->setObjectName("dxcluster()"); cluster->moveToThread(clusterThread); connect(this, SIGNAL(setClusterEnableUdp(bool)), cluster, SLOT(enableUdp(bool))); connect(this, SIGNAL(setClusterEnableTcp(bool)), cluster, SLOT(enableTcp(bool))); connect(this, SIGNAL(setClusterUdpPort(int)), cluster, SLOT(setUdpPort(int))); connect(this, SIGNAL(setClusterServerName(QString)), cluster, SLOT(setTcpServerName(QString))); connect(this, SIGNAL(setClusterTcpPort(int)), cluster, SLOT(setTcpPort(int))); connect(this, SIGNAL(setClusterUserName(QString)), cluster, SLOT(setTcpUserName(QString))); connect(this, SIGNAL(setClusterPassword(QString)), cluster, SLOT(setTcpPassword(QString))); connect(this, SIGNAL(setClusterTimeout(int)), cluster, SLOT(setTcpTimeout(int))); connect(this, SIGNAL(setClusterSkimmerSpots(bool)), cluster, SLOT(enableSkimmerSpots(bool))); connect(clusterThread, SIGNAL(finished()), cluster, SLOT(deleteLater())); clusterThread->start(); emit setClusterUdpPort(prefs.clusterUdpPort); emit setClusterEnableUdp(prefs.clusterUdpEnable); for (int f = 0; f < prefs.clusters.size(); f++) { if (prefs.clusters[f].isdefault) { emit setClusterServerName(prefs.clusters[f].server); emit setClusterTcpPort(prefs.clusters[f].port); emit setClusterUserName(prefs.clusters[f].userName); emit setClusterPassword(prefs.clusters[f].password); emit setClusterTimeout(prefs.clusters[f].timeout); emit setClusterSkimmerSpots(prefs.clusterSkimmerSpotsEnable); } } emit setClusterEnableTcp(prefs.clusterTcpEnable); setServerToPrefs(); amTransmitting = false; connect(ui->txPowerSlider, &QSlider::sliderMoved, [&](int value) { QToolTip::showText(QCursor::pos(), QString("%1").arg(value*100/255), nullptr); }); connect(ui->meter2Widget, &meter::configureMeterSignal, [=](const meter_t &meterTypeRequested) { // Change the preferences and update settings widget to reflect new meter selection: prefs.meter2Type = meterTypeRequested; setupui->updateIfPref(if_meter2Type); // Change the meter locally: changeMeterType(meterTypeRequested, 2); // Block duplicate meter selection in the other meter: ui->meter3Widget->blockMeterType(meterTypeRequested); }); connect(ui->meter3Widget, &meter::configureMeterSignal, [=](const meter_t &meterTypeRequested) { // Change the preferences and update settings widget to reflect new meter selection: prefs.meter3Type = meterTypeRequested; setupui->updateIfPref(if_meter3Type); // Change the meter locally: changeMeterType(meterTypeRequested, 3); // Block duplicate meter selection in the other meter: ui->meter2Widget->blockMeterType(meterTypeRequested); }); #if defined(USB_CONTROLLER) #if defined(USB_HOTPLUG) && defined(Q_OS_LINUX) uDev = udev_new(); if (!uDev) { qInfo(logUsbControl()) << "Cannot register udev, hotplug of USB devices is not available"; return; } uDevMonitor = udev_monitor_new_from_netlink(uDev, "udev"); if (!uDevMonitor) { qInfo(logUsbControl()) << "Cannot register udev_monitor, hotplug of USB devices is not available"; return; } int fd = udev_monitor_get_fd(uDevMonitor); uDevNotifier = new QSocketNotifier(fd, QSocketNotifier::Read,this); connect(uDevNotifier, SIGNAL(activated(int)), this, SLOT(uDevEvent())); udev_monitor_enable_receiving(uDevMonitor); #endif #endif } wfmain::~wfmain() { if(rigThread != Q_NULLPTR) { rigThread->quit(); rigThread->wait(); } if (serverThread != Q_NULLPTR) { serverThread->quit(); serverThread->wait(); } if (clusterThread != Q_NULLPTR) { clusterThread->quit(); clusterThread->wait(); } if (tciThread != Q_NULLPTR) { tciThread->quit(); tciThread->wait(); } if (rigCtl != Q_NULLPTR) { delete rigCtl; } if (colorPrefs != Q_NULLPTR) { delete colorPrefs; } delete rpt; delete ui; delete settings; #if defined(USB_CONTROLLER) if (usbControllerThread != Q_NULLPTR) { usbControllerThread->quit(); usbControllerThread->wait(); } #if defined(Q_OS_LINUX) if (uDevMonitor) { udev_monitor_unref(uDevMonitor); udev_unref(uDev); delete uDevNotifier; } #endif #endif } void wfmain::closeEvent(QCloseEvent *event) { if (on_exitBtn_clicked()) event->ignore(); } void wfmain::openRig() { // This function is intended to handle opening a connection to the rig. // the connection can be either serial or network, // and this function is also responsible for initiating the search for a rig model and capabilities. // Any errors, such as unable to open connection or unable to open port, are to be reported to the user. //TODO: if(hasRunPreviously) //TODO: if(useNetwork){... // } else { // if (prefs.fileWasNotFound) { // showRigSettings(); // rig setting dialog box for network/serial, CIV, hostname, port, baud rate, serial device, etc // TODO: How do we know if the setting was loaded? emit connectionStatus(true); // Signal any other parts that need to know if we are connecting/connected. ui->connectBtn->setText("Cancel connection"); // We are attempting to connect connStatus = connConnecting; // PET: This could be in a better place? if (prefs.audioSystem == tciAudio) { prefs.rxSetup.tci = tci; prefs.txSetup.tci = tci; } makeRig(); // 10 second connection timeout. ConnectionTimer.start(10000); if (prefs.enableLAN) { usingLAN = true; // "We need to setup the tx/rx audio: udpPrefs.waterfallFormat = prefs.waterfallFormat; emit sendCommSetup(rigList, prefs.radioCIVAddr, udpPrefs, prefs.rxSetup, prefs.txSetup, prefs.virtualSerialPort, prefs.tcpPort); } else { if( (prefs.serialPortRadio.toLower() == QString("auto"))) { findSerialPort(); } else { serialPortRig = prefs.serialPortRadio; } usingLAN = false; emit sendCommSetup(rigList, prefs.radioCIVAddr, serialPortRig, prefs.serialPortBaud,prefs.virtualSerialPort, prefs.tcpPort,prefs.waterfallFormat); ui->statusBar->showMessage(QString("Connecting to rig using serial port ").append(serialPortRig), 1000); } } // Deprecated (moved to makeRig()) void wfmain::rigConnections() { } void wfmain::makeRig() { if (rigThread == Q_NULLPTR) { rig = new rigCommander(); rigThread = new QThread(this); rigThread->setObjectName("rigCommander()"); // Thread: rig->moveToThread(rigThread); connect(rigThread, SIGNAL(started()), rig, SLOT(process())); connect(rigThread, SIGNAL(finished()), rig, SLOT(deleteLater())); rigThread->start(); // Rig status and Errors: connect(rig, SIGNAL(havePortError(errorType)), this, SLOT(receivePortError(errorType))); connect(rig, SIGNAL(haveStatusUpdate(networkStatus)), this, SLOT(receiveStatusUpdate(networkStatus))); connect(rig, SIGNAL(haveNetworkAudioLevels(networkAudioLevels)), this, SLOT(receiveNetworkAudioLevels(networkAudioLevels))); connect(rig, SIGNAL(requestRadioSelection(QList)), this, SLOT(radioSelection(QList))); connect(rig, SIGNAL(setRadioUsage(quint8, bool, quint8, QString, QString)), selRad, SLOT(setInUse(quint8, bool, quint8, QString, QString))); connect(selRad, SIGNAL(selectedRadio(quint8)), rig, SLOT(setCurrentRadio(quint8))); // Rig comm setup: connect(this, SIGNAL(sendCommSetup(rigTypedef,unsigned char, udpPreferences, audioSetup, audioSetup, QString, quint16)), rig, SLOT(commSetup(rigTypedef,unsigned char, udpPreferences, audioSetup, audioSetup, QString, quint16))); connect(this, SIGNAL(sendCommSetup(rigTypedef,unsigned char, QString, quint32,QString, quint16,quint8)), rig, SLOT(commSetup(rigTypedef,unsigned char, QString, quint32,QString, quint16,quint8))); connect(this, SIGNAL(setRTSforPTT(bool)), rig, SLOT(setRTSforPTT(bool))); connect(rig, SIGNAL(haveBaudRate(quint32)), this, SLOT(receiveBaudRate(quint32))); connect(this, SIGNAL(sendCloseComm()), rig, SLOT(closeComm())); connect(this, SIGNAL(sendChangeLatency(quint16)), rig, SLOT(changeLatency(quint16))); connect(this, SIGNAL(getRigCIV()), rig, SLOT(findRigs())); connect(this, SIGNAL(setRigID(unsigned char)), rig, SLOT(setRigID(unsigned char))); connect(rig, SIGNAL(commReady()), this, SLOT(receiveCommReady())); connect(this, SIGNAL(setCIVAddr(unsigned char)), rig, SLOT(setCIVAddr(unsigned char))); connect(this, SIGNAL(sendPowerOn()), rig, SLOT(powerOn())); connect(this, SIGNAL(sendPowerOff()), rig, SLOT(powerOff())); connect(this, SIGNAL(getDebug()), rig, SLOT(getDebug())); // Repeater, duplex, and split: //connect(rpt, SIGNAL(getDuplexMode()), rig, SLOT(getDuplexMode())); //connect(rpt, SIGNAL(setDuplexMode(duplexMode_t)), rig, SLOT(setDuplexMode(duplexMode_t))); //connect(rig, SIGNAL(haveDuplexMode(duplexMode_t)), rpt, SLOT(receiveDuplexMode(duplexMode_t))); //connect(this, SIGNAL(getRptDuplexOffset()), rig, SLOT(getRptDuplexOffset())); connect(rig, SIGNAL(haveRptOffsetFrequency(freqt)), rpt, SLOT(handleRptOffsetFrequency(freqt))); // Memories //connect(this, SIGNAL(setMemoryMode()), rig, SLOT(setMemoryMode())); //connect(this, SIGNAL(setSatelliteMode(bool)), rig, SLOT(setSatelliteMode(bool))); //connect(this, SIGNAL(getMemory(quint32)), rig, SLOT(getMemory(quint32))); //connect(this, SIGNAL(getSatMemory(quint32)), rig, SLOT(getSatMemory(quint32))); //connect(this, SIGNAL(setMemory(memoryType)), rig, SLOT(setMemory(memoryType))); //connect(this, SIGNAL(clearMemory(quint32)), rig, SLOT(clearMemory(quint32))); //connect(this, SIGNAL(rigCaps->ry(quint32)), rig, SLOT(rigCaps->ry(quint32))); connect(this->rpt, &repeaterSetup::getTone, this->rig, [=]() { qDebug(logSystem()) << "Asking for TONE"; queue->add(priorityImmediate,funcRepeaterTone,false,false);}); connect(this->rpt, &repeaterSetup::getTSQL, this->rig, [=]() { qDebug(logSystem()) << "Asking for TSQL"; queue->add(priorityImmediate,funcRepeaterTSQL,false,false);}); connect(this->rpt, &repeaterSetup::setDTCS, this->rig, [=](const toneInfo& t) { qDebug(logSystem()) << "Setting DCS, code =" << t.tone; queue->add(priorityImmediate,queueItem(funcRepeaterDTCS,QVariant::fromValue(t),false));}); connect(this->rpt, &repeaterSetup::getRptAccessMode, this->rig, [=]() { if (rigCaps->commands.contains(funcToneSquelchType)) { queue->add(priorityImmediate,funcToneSquelchType,false,false); } else { queue->add(priorityImmediate,funcRepeaterTone,false,false); queue->add(priorityImmediate,funcRepeaterTSQL,false,false); } }); connect(this->rig, &rigCommander::haveDuplexMode, this->rpt, [=](const duplexMode_t &dm) { if(dm==dmSplitOn) this->splitModeEnabled = true; else this->splitModeEnabled = false; }); connect(this->rpt, &repeaterSetup::selectVFO, this->rig, [=](const vfo_t &v) { queue->add(priorityImmediate,queueItem(funcSelectVFO,QVariant::fromValue(v),false));}); connect(this->rpt, &repeaterSetup::equalizeVFOsAB, this->rig, [=]() { queue->add(priorityImmediate,funcVFOEqualAB,false,false);}); connect(this->rpt, &repeaterSetup::equalizeVFOsMS, this->rig, [=]() { queue->add(priorityImmediate,funcVFOEqualMS,false,false);}); connect(this->rpt, &repeaterSetup::swapVFOs, this->rig, [=]() { queue->add(priorityImmediate,funcVFOSwapMS,false,false);}); connect(this->rpt, &repeaterSetup::setRptDuplexOffset, this->rig, [=](const freqt &fOffset) { queue->add(priorityImmediate,queueItem(funcSendFreqOffset,QVariant::fromValue(fOffset),false));}); connect(this->rpt, &repeaterSetup::getRptDuplexOffset, this->rig, [=]() { queue->add(priorityImmediate,funcReadFreqOffset,false,false);}); connect(this, SIGNAL(setAfGain(unsigned char)), rig, SLOT(setAfGain(unsigned char))); // Create link for server so it can have easy access to rig. if (serverConfig.rigs.first() != Q_NULLPTR) { serverConfig.rigs.first()->rig = rig; serverConfig.rigs.first()->rigThread = rigThread; } } } void wfmain::removeRig() { ConnectionTimer.stop(); if (rigThread != Q_NULLPTR) { rigThread->quit(); rigThread->wait(); rig = Q_NULLPTR; rigThread = Q_NULLPTR; } } void wfmain::findSerialPort() { // Find the ICOM radio connected, or, if none, fall back to OS default. // qInfo(logSystem()) << "Searching for serial port..."; bool found = false; // First try to find first Icom port: for(const QSerialPortInfo & serialPortInfo: QSerialPortInfo::availablePorts()) { if (serialPortInfo.serialNumber().left(3) == "IC-") { qInfo(logSystem()) << "Serial Port found: " << serialPortInfo.portName() << "Manufacturer:" << serialPortInfo.manufacturer() << "Product ID" << serialPortInfo.description() << "S/N" << serialPortInfo.serialNumber(); #if defined(Q_OS_LINUX) || defined(Q_OS_MAC) serialPortRig = (QString("/dev/") + serialPortInfo.portName()); #else serialPortRig = serialPortInfo.portName(); #endif found = true; break; } } if (!found) { QDirIterator it73("/dev/serial/by-id", QStringList() << "*IC-7300*", QDir::Files, QDirIterator::Subdirectories); QDirIterator it97("/dev/serial", QStringList() << "*IC-9700*A*", QDir::Files, QDirIterator::Subdirectories); QDirIterator it785x("/dev/serial", QStringList() << "*IC-785*A*", QDir::Files, QDirIterator::Subdirectories); QDirIterator it705("/dev/serial", QStringList() << "*IC-705*A", QDir::Files, QDirIterator::Subdirectories); QDirIterator it7610("/dev/serial", QStringList() << "*IC-7610*A", QDir::Files, QDirIterator::Subdirectories); QDirIterator itR8600("/dev/serial", QStringList() << "*IC-R8600*A", QDir::Files, QDirIterator::Subdirectories); if(!it73.filePath().isEmpty()) { // IC-7300 serialPortRig = it73.filePath(); // first } else if(!it97.filePath().isEmpty()) { // IC-9700 serialPortRig = it97.filePath(); } else if(!it785x.filePath().isEmpty()) { // IC-785x serialPortRig = it785x.filePath(); } else if(!it705.filePath().isEmpty()) { // IC-705 serialPortRig = it705.filePath(); } else if(!it7610.filePath().isEmpty()) { // IC-7610 serialPortRig = it7610.filePath(); } else if(!itR8600.filePath().isEmpty()) { // IC-R8600 serialPortRig = itR8600.filePath(); } else { //fall back: qInfo(logSystem()) << "Could not find Icom serial port. Falling back to OS default. Use --port to specify, or modify preferences."; #ifdef Q_OS_MAC serialPortRig = QString("/dev/tty.SLAB_USBtoUART"); #endif #ifdef Q_OS_LINUX serialPortRig = QString("/dev/ttyUSB0"); #endif #ifdef Q_OS_WIN serialPortRig = QString("COM1"); #endif } } } void wfmain::receiveCommReady() { //qInfo(logSystem()) << "Received CommReady!! "; if(!usingLAN) { // usingLAN gets set when we emit the sendCommSetup signal. // If we're not using the LAN, then we're on serial, and // we already know the baud rate and can calculate the timing parameters. calculateTimingParameters(); } if(prefs.radioCIVAddr == 0) { // tell rigCommander to broadcast a request for all rig IDs. // qInfo(logSystem()) << "Beginning search from wfview for rigCIV (auto-detection broadcast)"; ui->statusBar->showMessage(QString("Searching CI-V bus for connected radios."), 1000); //emit getRigCIV(); //queue->add(priorityImmediate,funcTransceiverId,false); queue->addUnique(priorityHighest,funcTransceiverId,true); //issueDelayedCommand(cmdGetRigCIV); //delayedCommand->start(); } else { // don't bother, they told us the CIV they want, stick with it. // We still query the rigID to find the model, but at least we know the CIV. qInfo(logSystem()) << "Skipping automatic CIV, using user-supplied value of " << prefs.radioCIVAddr; showStatusBarText(QString("Using user-supplied radio CI-V address of 0x%1").arg(prefs.radioCIVAddr, 2, 16)); if(prefs.CIVisRadioModel) { qInfo(logSystem()) << "Skipping Rig ID query, using user-supplied model from CI-V address: " << prefs.radioCIVAddr; emit setCIVAddr(prefs.radioCIVAddr); emit setRigID(prefs.radioCIVAddr); } else { emit setCIVAddr(prefs.radioCIVAddr); //emit getRigCIV(); //queue->add(priorityImmediate,funcTransceiverId,false); queue->addUnique(priorityHighest,funcTransceiverId,true); //emit getRigID(); //issueDelayedCommand(cmdGetRigID); //delayedCommand->start(); } } } void wfmain::receivePortError(errorType err) { if (err.alert) { connectionHandler(false); // Force disconnect QMessageBox::critical(this, err.device, err.message, QMessageBox::Ok); } else { qInfo(logSystem()) << "wfmain: received error for device: " << err.device << " with message: " << err.message; ui->statusBar->showMessage(QString("ERROR: using device ").append(err.device).append(": ").append(err.message), 10000); } // TODO: Dialog box, exit, etc } void wfmain::receiveStatusUpdate(networkStatus status) { //this->rigStatus->setText(QString("%0/%1 %2").arg(mainElapsed).arg(subElapsed).arg(status.message)); this->rigStatus->setText(status.message); selRad->audioOutputLevel(status.rxAudioLevel); selRad->audioInputLevel(status.txAudioLevel); //qInfo(logSystem()) << "Got Status Update" << status.rxAudioLevel; } void wfmain::receiveNetworkAudioLevels(networkAudioLevels l) { meter_t m = meterNone; if(l.haveRxLevels) { m = meterRxAudio; receiveMeter(m, l.rxAudioPeak); } if(l.haveTxLevels) { m = meterTxMod; receiveMeter(m, l.txAudioPeak); } } void wfmain::setupMainUI() { // Set scroll wheel response (tick interval) // and set arrow key response (single step) ui->rfGainSlider->setTickInterval(100); ui->rfGainSlider->setSingleStep(10); ui->afGainSlider->setTickInterval(100); ui->afGainSlider->setSingleStep(10); ui->sqlSlider->setTickInterval(100); ui->sqlSlider->setSingleStep(10); ui->txPowerSlider->setTickInterval(100); ui->txPowerSlider->setSingleStep(10); ui->micGainSlider->setTickInterval(100); ui->micGainSlider->setSingleStep(10); ui->monitorSlider->setTickInterval(100); ui->monitorSlider->setSingleStep(10); // Keep this code when the rest is removed from this function: qDebug(logSystem()) << "Running with debugging options enabled."; rigStatus = new QLabel(this); ui->statusBar->addPermanentWidget(rigStatus); ui->statusBar->showMessage("Connecting to rig...", 1000); pttLed = new QLedLabel(this); ui->statusBar->addPermanentWidget(pttLed); pttLed->setState(QLedLabel::State::StateOk); pttLed->setToolTip("Receiving"); connectedLed = new QLedLabel(this); ui->statusBar->addPermanentWidget(connectedLed); rigName = new QLabel(this); rigName->setAlignment(Qt::AlignRight); ui->statusBar->addPermanentWidget(rigName); rigName->setText("NONE"); rigName->setFixedWidth(60); freqt f; f.MHzDouble = 0.0; f.Hz = 0; oldFreqDialVal = ui->freqDial->value(); ui->tuneLockChk->setChecked(false); freqLock = false; connect( ui->txPowerSlider, &QSlider::valueChanged, this, [=](const int &newValue) { statusFromSliderPercent("Tx Power", newValue);} ); connect( ui->rfGainSlider, &QSlider::valueChanged, this, [=](const int &newValue) { statusFromSliderPercent("RF Gain", newValue);} ); connect( ui->afGainSlider, &QSlider::valueChanged, this, [=](const int &newValue) { statusFromSliderPercent("AF Gain", newValue);} ); connect( ui->micGainSlider, &QSlider::valueChanged, this, [=](const int &newValue) { statusFromSliderPercent("TX Audio Gain", newValue);} ); connect( ui->sqlSlider, &QSlider::valueChanged, this, [=](const int &newValue) { statusFromSliderPercent("Squelch", newValue);} ); /* connect(this->cw, &cwSender::sendCW, [=](const QString &cwMessage) { issueCmd(cmdSendCW, cwMessage);}); connect(this->cw, &cwSender::stopCW, [=]() { issueDelayedCommand(cmdStopCW);}); connect(this->cw, &cwSender::setBreakInMode, [=](const unsigned char &bmode) { issueCmd(cmdSetBreakMode, bmode);}); connect(this->cw, &cwSender::setKeySpeed, [=](const unsigned char& wpm) { issueCmd(cmdSetKeySpeed, wpm); }); connect(this->cw, &cwSender::setPitch, [=](const unsigned char& pitch) { issueCmd(cmdSetCwPitch, pitch); }); connect(this->cw, &cwSender::getCWSettings, [=]() { issueDelayedCommand(cmdGetKeySpeed); issueDelayedCommand(cmdGetBreakMode);}); */ } void wfmain::connectSettingsWidget() { connect(setupui, SIGNAL(changedClusterPref(prefClusterItem)), this, SLOT(extChangedClusterPref(prefClusterItem))); connect(setupui, SIGNAL(changedClusterPrefs(quint64)), this, SLOT(extChangedClusterPrefs(quint64))); connect(setupui, SIGNAL(changedCtPref(prefCtItem)), this, SLOT(extChangedCtPref(prefCtItem))); connect(setupui, SIGNAL(changedCtPrefs(quint64)), this, SLOT(extChangedCtPrefs(quint64))); connect(setupui, SIGNAL(changedIfPref(prefIfItem)), this, SLOT(extChangedIfPref(prefIfItem))); connect(setupui, SIGNAL(changedIfPrefs(quint64)), this, SLOT(extChangedIfPrefs(quint64))); connect(setupui, SIGNAL(changedColPref(prefColItem)), this, SLOT(extChangedColPref(prefColItem))); connect(setupui, SIGNAL(changedColPrefs(quint64)), this, SLOT(extChangedColPrefs(quint64))); connect(setupui, SIGNAL(changedLanPref(prefLanItem)), this, SLOT(extChangedLanPref(prefLanItem))); connect(setupui, SIGNAL(changedLanPrefs(quint64)), this, SLOT(extChangedLanPrefs(quint64))); connect(setupui, SIGNAL(changedRaPref(prefRaItem)), this, SLOT(extChangedRaPref(prefRaItem))); connect(setupui, SIGNAL(changedRaPrefs(quint64)), this, SLOT(extChangedRaPrefs(quint64))); connect(setupui, SIGNAL(changedRsPref(prefRsItem)), this, SLOT(extChangedRsPref(prefRsItem))); connect(setupui, SIGNAL(changedRsPrefs(quint64)), this, SLOT(extChangedRsPrefs(quint64))); connect(setupui, SIGNAL(changedUdpPref(prefUDPItem)), this, SLOT(extChangedUdpPref(prefUDPItem))); connect(setupui, SIGNAL(changedUdpPrefs(quint64)), this, SLOT(extChangedUdpPrefs(quint64))); connect(setupui, SIGNAL(changedServerPref(prefServerItem)), this, SLOT(extChangedServerPref(prefServerItem))); connect(setupui, SIGNAL(changedServerPrefs(quint64)), this, SLOT(extChangedServerPrefs(quint64))); //connect(setupui, SIGNAL(changedAudioInputCombo(int)), this, SLOT(changedAudioInput(int))); //connect(setupui, SIGNAL(changedAudioOutputCombo(int)), this, SLOT(changedAudioOutput(int))); //connect(setupui, SIGNAL(changedServerRXAudioInputCombo(int)), this, SLOT(changedServerRXAudioInput(int))); //connect(setupui, SIGNAL(changedServerTXAudioOutputCombo(int)), this, SLOT(changedServerTXAudioOutput(int))); connect(this, SIGNAL(connectionStatus(bool)), setupui, SLOT(connectionStatus(bool))); connect(setupui, SIGNAL(connectButtonPressed()), this, SLOT(handleExtConnectBtn())); connect(setupui, SIGNAL(saveSettingsButtonPressed()), this, SLOT(on_saveSettingsBtn_clicked())); connect(setupui, SIGNAL(revertSettingsButtonPressed()), this, SLOT(handleRevertSettingsBtn())); } // NOT Migrated, EHL TODO, carefully remove this function void wfmain::getSettingsFilePath(QString settingsFile) { if (settingsFile.isNull()) { settings = new QSettings(); } else { QString file = settingsFile; QFile info(settingsFile); QString path=""; if (!QFileInfo(info).isAbsolute()) { path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); if (path.isEmpty()) { path = QDir::homePath(); } path = path + "/"; file = info.fileName(); } settings = new QSettings(path + file, QSettings::Format::IniFormat); } } void wfmain::setInitialTiming() { loopTickCounter = 0; delayedCmdIntervalLAN_ms = 70; // interval for regular delayed commands, including initial rig/UI state queries delayedCmdIntervalSerial_ms = 100; // interval for regular delayed commands, including initial rig/UI state queries delayedCmdStartupInterval_ms = 250; // interval for rigID polling delayedCommand = new QTimer(this); queue->interval(delayedCmdStartupInterval_ms); pttTimer = new QTimer(this); pttTimer->setInterval(180*1000); // 3 minute max transmit time in ms pttTimer->setSingleShot(true); connect(pttTimer, SIGNAL(timeout()), this, SLOT(handlePttLimit())); timeSync = new QTimer(this); connect(timeSync, SIGNAL(timeout()), this, SLOT(setRadioTimeDateSend())); waitingToSetTimeDate = false; lastFreqCmdTime_ms = QDateTime::currentMSecsSinceEpoch() - 5000; // 5 seconds ago } void wfmain::setServerToPrefs() { // Start server if enabled in config //ui->serverSetupGroup->setEnabled(serverConfig.enabled); if (serverThread != Q_NULLPTR) { serverThread->quit(); serverThread->wait(); serverThread = Q_NULLPTR; udp = Q_NULLPTR; ui->statusBar->showMessage(QString("Server disabled"), 1000); } if (serverConfig.enabled) { serverConfig.lan = prefs.enableLAN; udp = new udpServer(&serverConfig); serverThread = new QThread(this); udp->moveToThread(serverThread); connect(this, SIGNAL(initServer()), udp, SLOT(init())); connect(serverThread, SIGNAL(finished()), udp, SLOT(deleteLater())); if (rig != Q_NULLPTR) { connect(rig, SIGNAL(haveAudioData(audioPacket)), udp, SLOT(receiveAudioData(audioPacket))); // Need to add a signal/slot for audio from the client to rig. //connect(udp, SIGNAL(haveAudioData(audioPacket)), rig, SLOT(receiveAudioData(audioPacket))); connect(rig, SIGNAL(haveDataForServer(QByteArray)), udp, SLOT(dataForServer(QByteArray))); connect(udp, SIGNAL(haveDataFromServer(QByteArray)), rig, SLOT(dataFromServer(QByteArray))); } if (serverConfig.lan) { connect(udp, SIGNAL(haveNetworkStatus(networkStatus)), this, SLOT(receiveStatusUpdate(networkStatus))); } else { qInfo(logAudio()) << "Audio Input device " << serverConfig.rigs.first()->rxAudioSetup.name; qInfo(logAudio()) << "Audio Output device " << serverConfig.rigs.first()->txAudioSetup.name; } serverThread->start(); emit initServer(); //connect(this, SIGNAL(sendRigCaps(rigCapabilities)), udp, SLOT(receiveRigCaps(rigCapabilities))); ui->statusBar->showMessage(QString("Server enabled"), 1000); } } void wfmain::configureVFOs() { qInfo(logSystem()) << "Running configureVFOs()"; if (QThread::currentThread() != QCoreApplication::instance()->thread()) { qCritical(logSystem()) << "Thread is NOT the main UI thread, cannot create VFO"; return; } if (receivers.size()) { foreach (spectrumScope* receiver, receivers) { ui->vfoLayout->removeWidget(receiver); delete receiver; } receivers.clear(); } for(uchar i=0;inumReceiver;i++) { spectrumScope* receiver = new spectrumScope(rigCaps->hasSpectrum,i,rigCaps->numVFO,this); receiver->setUnderlayMode(prefs.underlayMode); receiver->wfAntiAliased(prefs.wfAntiAlias); receiver->wfInterpolate(prefs.wfInterpolate); receiver->setScrollSpeedXY(prefs.scopeScrollX, prefs.scopeScrollY); receiver->prepareWf(i==0?prefs.mainWflength:prefs.subWflength); receiver->setRange(i==0?prefs.mainPlotFloor:prefs.subPlotFloor,i==0?prefs.mainPlotCeiling:prefs.subPlotCeiling); receiver->wfTheme(i==0?prefs.mainWfTheme:prefs.subWfTheme); receiver->setClickDragTuning(prefs.clickDragTuningEnable); receiver->setTuningFloorZeros(prefs.niceTS); receiver->resizePlasmaBuffer(prefs.underlayBufferSize); receiver->setUnit((FctlUnit)prefs.frequencyUnits); receiver->colorPreset(this->colorPrefs); receiver->setIdentity(i==0?"Main Band":"Sub Band"); ui->vfoLayout->addWidget(receiver); // Hide any secondary receivers until we need them! if (i>0){ receiver->setVisible(false); } connect(receiver, SIGNAL(frequencyRange(uchar, double, double)), cluster, SLOT(freqRange(uchar, double, double))); connect(cluster, SIGNAL(sendSpots(uchar, QList)), receiver, SLOT(receiveSpots(uchar, QList))); connect(cluster, SIGNAL(sendOutput(QString)), this, SLOT(receiveClusterOutput(QString))); connect(receiver, SIGNAL(updateSettings(uchar,int,quint16,int,int)), this, SLOT(receiveScopeSettings(uchar,int,quint16,int,int))); connect(receiver, SIGNAL(dataChanged(modeInfo)), this, SLOT(dataModeChanged(modeInfo))); connect(receiver,SIGNAL(showStatusBarText(QString)),this,SLOT(showStatusBarText(QString))); receivers.append(receiver); //ui->scopeSpacer->changeSize(0,0,QSizePolicy::Minimum); } } void wfmain::setSerialDevicesUI() { } void wfmain::setupKeyShortcuts() { keyF1 = new QShortcut(this); keyF1->setKey(Qt::Key_F1); connect(keyF1, SIGNAL(activated()), this, SLOT(shortcutF1())); keyF2 = new QShortcut(this); keyF2->setKey(Qt::Key_F2); connect(keyF2, SIGNAL(activated()), this, SLOT(shortcutF2())); keyF3 = new QShortcut(this); keyF3->setKey(Qt::Key_F3); connect(keyF3, SIGNAL(activated()), this, SLOT(shortcutF3())); keyF4 = new QShortcut(this); keyF4->setKey(Qt::Key_F4); connect(keyF4, SIGNAL(activated()), this, SLOT(shortcutF4())); keyF5 = new QShortcut(this); keyF5->setKey(Qt::Key_F5); connect(keyF5, SIGNAL(activated()), this, SLOT(shortcutF5())); keyF6 = new QShortcut(this); keyF6->setKey(Qt::Key_F6); connect(keyF6, SIGNAL(activated()), this, SLOT(shortcutF6())); keyF7 = new QShortcut(this); keyF7->setKey(Qt::Key_F7); connect(keyF7, SIGNAL(activated()), this, SLOT(shortcutF7())); keyF8 = new QShortcut(this); keyF8->setKey(Qt::Key_F8); connect(keyF8, SIGNAL(activated()), this, SLOT(shortcutF8())); keyF9 = new QShortcut(this); keyF9->setKey(Qt::Key_F9); connect(keyF9, SIGNAL(activated()), this, SLOT(shortcutF9())); keyF10 = new QShortcut(this); keyF10->setKey(Qt::Key_F10); connect(keyF10, SIGNAL(activated()), this, SLOT(shortcutF10())); keyF11 = new QShortcut(this); keyF11->setKey(Qt::Key_F11); connect(keyF11, SIGNAL(activated()), this, SLOT(shortcutF11())); keyF12 = new QShortcut(this); keyF12->setKey(Qt::Key_F12); connect(keyF12, SIGNAL(activated()), this, SLOT(shortcutF12())); keyControlT = new QShortcut(this); keyControlT->setKey(Qt::CTRL | Qt::Key_T); connect(keyControlT, SIGNAL(activated()), this, SLOT(shortcutControlT())); keyControlR = new QShortcut(this); keyControlR->setKey(Qt::CTRL | Qt::Key_R); connect(keyControlR, SIGNAL(activated()), this, SLOT(shortcutControlR())); keyControlR = new QShortcut(this); keyControlR->setKey(Qt::CTRL | Qt::Key_P); connect(keyControlR, SIGNAL(activated()), this, SLOT(shortcutControlP())); keyControlI = new QShortcut(this); keyControlI->setKey(Qt::CTRL | Qt::Key_I); connect(keyControlI, SIGNAL(activated()), this, SLOT(shortcutControlI())); keyControlU = new QShortcut(this); keyControlU->setKey(Qt::CTRL | Qt::Key_U); connect(keyControlU, SIGNAL(activated()), this, SLOT(shortcutControlU())); keyStar = new QShortcut(this); keyStar->setKey(Qt::Key_Asterisk); connect(keyStar, SIGNAL(activated()), this, SLOT(shortcutStar())); keySlash = new QShortcut(this); keySlash->setKey(Qt::Key_Slash); connect(keySlash, SIGNAL(activated()), this, SLOT(shortcutSlash())); keyMinus = new QShortcut(this); keyMinus->setKey(Qt::Key_Minus); connect(keyMinus, SIGNAL(activated()), this, SLOT(shortcutMinus())); keyPlus = new QShortcut(this); keyPlus->setKey(Qt::Key_Plus); connect(keyPlus, SIGNAL(activated()), this, SLOT(shortcutPlus())); keyShiftMinus = new QShortcut(this); keyShiftMinus->setKey(Qt::SHIFT | Qt::Key_Minus); connect(keyShiftMinus, SIGNAL(activated()), this, SLOT(shortcutShiftMinus())); keyShiftPlus = new QShortcut(this); keyShiftPlus->setKey(Qt::SHIFT | Qt::Key_Plus); connect(keyShiftPlus, SIGNAL(activated()), this, SLOT(shortcutShiftPlus())); keyControlMinus = new QShortcut(this); keyControlMinus->setKey(Qt::CTRL | Qt::Key_Minus); connect(keyControlMinus, SIGNAL(activated()), this, SLOT(shortcutControlMinus())); keyControlPlus = new QShortcut(this); keyControlPlus->setKey(Qt::CTRL | Qt::Key_Plus); connect(keyControlPlus, SIGNAL(activated()), this, SLOT(shortcutControlPlus())); keyQuit = new QShortcut(this); keyQuit->setKey(Qt::CTRL | Qt::Key_Q); connect(keyQuit, SIGNAL(activated()), this, SLOT(on_exitBtn_clicked())); keyPageUp = new QShortcut(this); keyPageUp->setKey(Qt::Key_PageUp); connect(keyPageUp, SIGNAL(activated()), this, SLOT(shortcutPageUp())); keyPageDown = new QShortcut(this); keyPageDown->setKey(Qt::Key_PageDown); connect(keyPageDown, SIGNAL(activated()), this, SLOT(shortcutPageDown())); keyF = new QShortcut(this); keyF->setKey(Qt::Key_F); connect(keyF, SIGNAL(activated()), this, SLOT(shortcutF())); keyM = new QShortcut(this); keyM->setKey(Qt::Key_M); connect(keyM, SIGNAL(activated()), this, SLOT(shortcutM())); // Alternate for plus: keyK = new QShortcut(this); keyK->setKey(Qt::Key_K); connect(keyK, &QShortcut::activated, this, [=]() { if (freqLock) return; this->shortcutPlus(); }); // Alternate for minus: keyJ = new QShortcut(this); keyJ->setKey(Qt::Key_J); connect(keyJ, &QShortcut::activated, this, [=]() { if (freqLock) return; this->shortcutMinus(); }); keyShiftK = new QShortcut(this); keyShiftK->setKey(Qt::SHIFT | Qt::Key_K); connect(keyShiftK, &QShortcut::activated, this, [=]() { if (freqLock) return; this->shortcutShiftPlus(); }); keyShiftJ = new QShortcut(this); keyShiftJ->setKey(Qt::SHIFT | Qt::Key_J); connect(keyShiftJ, &QShortcut::activated, this, [=]() { if (freqLock) return; this->shortcutShiftMinus(); }); keyControlK = new QShortcut(this); keyControlK->setKey(Qt::CTRL | Qt::Key_K); connect(keyControlK, &QShortcut::activated, this, [=]() { if (freqLock) return; this->shortcutControlPlus(); }); keyControlJ = new QShortcut(this); keyControlJ->setKey(Qt::CTRL | Qt::Key_J); connect(keyControlJ, &QShortcut::activated, this, [=]() { if (freqLock) return; this->shortcutControlMinus(); }); // Move the tuning knob by the tuning step selected: // H = Down keyH = new QShortcut(this); keyH->setKey(Qt::Key_H); connect(keyH, &QShortcut::activated, this, [=]() { if (freqLock) return; if (receivers.size()) { freqt f; f.Hz = roundFrequencyWithStep(receivers.first()->getFrequency().Hz, -1, tsKnobHz); f.MHzDouble = f.Hz / (double)1E6; queue->add(priorityImmediate,queueItem(funcMainFreq,QVariant::fromValue(f))); } }); // L = Up keyL = new QShortcut(this); keyL->setKey(Qt::Key_L); connect(keyL, &QShortcut::activated, this, [=]() { if (freqLock) return; freqt f; if (receivers.size()) { f.Hz = roundFrequencyWithStep(receivers.first()->getFrequency().Hz, 1, tsKnobHz); f.MHzDouble = f.Hz / (double)1E6; queue->add(priorityImmediate,queueItem(funcMainFreq,QVariant::fromValue(f))); } }); keyDebug = new QShortcut(this); #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) keyDebug->setKey(Qt::CTRL | Qt::SHIFT | Qt::Key_D); #else keyDebug->setKey(Qt::CTRL | Qt::Key_D); #endif connect(keyDebug, SIGNAL(activated()), this, SLOT(debugBtn_clicked())); } void wfmain::setupUsbControllerDevice() { #if defined (USB_CONTROLLER) if (usbWindow == Q_NULLPTR) { usbWindow = new controllerSetup(); } usbControllerDev = new usbController(); usbControllerThread = new QThread(this); usbControllerThread->setObjectName("usb()"); usbControllerDev->moveToThread(usbControllerThread); connect(usbControllerThread, SIGNAL(started()), usbControllerDev, SLOT(run())); connect(usbControllerThread, SIGNAL(finished()), usbControllerDev, SLOT(deleteLater())); connect(usbControllerThread, SIGNAL(finished()), usbWindow, SLOT(deleteLater())); // Delete window when controller is deleted connect(usbControllerDev, SIGNAL(sendJog(int)), this, SLOT(changeFrequency(int))); connect(usbControllerDev, SIGNAL(doShuttle(bool,unsigned char)), this, SLOT(doShuttle(bool,unsigned char))); connect(usbControllerDev, SIGNAL(button(const COMMAND*)), this, SLOT(buttonControl(const COMMAND*))); connect(usbControllerDev, SIGNAL(setBand(int)), this, SLOT(setBand(int))); connect(usbControllerDev, SIGNAL(removeDevice(USBDEVICE*)), usbWindow, SLOT(removeDevice(USBDEVICE*))); connect(usbControllerDev, SIGNAL(initUI(usbDevMap*, QVector