mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-10-31 23:57:10 -04:00
c5c6feb41c
To facilitate interaction with other applications WSJT-X now sends status updates to a predefined UDP server or multicast group address. The status updates include the information currently posted to the decodes.txt and wsjtx_status.txt files. An optional back communications channel is also implemented allowing the UDP server application to control some basic actions in WSJT-X. A reference implementaion of a typical UDP server written in C++ using Qt is provided to demonstrate these facilities. This application is not intended as a user tool but only as an example of how a third party application may interact with WSJT-X. The UDP messages Use QDataStream based serialization. Messages are documented in NetworkMessage.hpp along with some helper classes that simplify the building and decoding of messages. Two message handling classes are introduced, MessageClient and MessageServer. WSJT-X uses the MessageClient class to manage outgoing and incoming UDP messages that allow communication with other applications. The MessageServer class implements the kind of code that a potential cooperating application might use. Although these classes use Qt serialization facilities, the message formats are easily read and written by applications that do not use the Qt framework. MessageAggregator is a demonstration application that uses MessageServer and presents a GUI that displays messages from one or more WSJT-X instances and allows sending back a CQ or QRZ reply invocation by double clicking a decode. This application is not intended as a user facing tool but rather as a demonstration of the WSJT-X UDP messaging facility. It also demonstrates being a multicast UDP server by allowing multiple instances to run concurrently. This is enabled by using an appropriate multicast group address as the server address. Cooperating applications need not implement multicast techniques but it is recomended otherwise only a single appliaction can act as a broadcast message (from WSJT-X) recipient. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5225 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
150 lines
4.7 KiB
C++
150 lines
4.7 KiB
C++
#include "logqso.h"
|
|
|
|
#include <QString>
|
|
#include <QSettings>
|
|
#include <QStandardPaths>
|
|
#include <QDir>
|
|
#include <QDebug>
|
|
|
|
#include "logbook/adif.h"
|
|
|
|
#include "ui_logqso.h"
|
|
|
|
#include "moc_logqso.cpp"
|
|
|
|
LogQSO::LogQSO(QString const& programTitle, QSettings * settings, QWidget *parent)
|
|
: QDialog(parent)
|
|
, ui(new Ui::LogQSO)
|
|
, m_settings (settings)
|
|
{
|
|
ui->setupUi(this);
|
|
setWindowTitle(programTitle + " - Log QSO");
|
|
loadSettings ();
|
|
}
|
|
|
|
LogQSO::~LogQSO ()
|
|
{
|
|
}
|
|
|
|
void LogQSO::loadSettings ()
|
|
{
|
|
m_settings->beginGroup ("LogQSO");
|
|
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
|
|
ui->cbTxPower->setChecked (m_settings->value ("SaveTxPower", false).toBool ());
|
|
ui->cbComments->setChecked (m_settings->value ("SaveComments", false).toBool ());
|
|
m_txPower = m_settings->value ("TxPower", "").toString ();
|
|
m_comments = m_settings->value ("LogComments", "").toString();
|
|
m_settings->endGroup ();
|
|
}
|
|
|
|
void LogQSO::storeSettings () const
|
|
{
|
|
m_settings->beginGroup ("LogQSO");
|
|
m_settings->setValue ("geometry", saveGeometry ());
|
|
m_settings->setValue ("SaveTxPower", ui->cbTxPower->isChecked ());
|
|
m_settings->setValue ("SaveComments", ui->cbComments->isChecked ());
|
|
m_settings->setValue ("TxPower", m_txPower);
|
|
m_settings->setValue ("LogComments", m_comments);
|
|
m_settings->endGroup ();
|
|
}
|
|
|
|
void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode,
|
|
QString rptSent, QString rptRcvd, QDateTime dateTime,
|
|
Radio::Frequency dialFreq, QString myCall, QString myGrid,
|
|
bool noSuffix, bool toRTTY, bool dBtoComments)
|
|
{
|
|
ui->call->setText(hisCall);
|
|
ui->grid->setText(hisGrid);
|
|
ui->name->setText("");
|
|
ui->txPower->setText("");
|
|
ui->comments->setText("");
|
|
if (ui->cbTxPower->isChecked ()) ui->txPower->setText(m_txPower);
|
|
if (ui->cbComments->isChecked ()) ui->comments->setText(m_comments);
|
|
if(dBtoComments) {
|
|
QString t=mode;
|
|
if(rptSent!="") t+=" Sent: " + rptSent;
|
|
if(rptRcvd!="") t+=" Rcvd: " + rptRcvd;
|
|
ui->comments->setText(t);
|
|
}
|
|
if(noSuffix and mode.mid(0,3)=="JT9") mode="JT9";
|
|
if(toRTTY and mode.mid(0,3)=="JT9") mode="RTTY";
|
|
ui->mode->setText(mode);
|
|
ui->sent->setText(rptSent);
|
|
ui->rcvd->setText(rptRcvd);
|
|
m_dateTime=dateTime;
|
|
QString date=dateTime.toString("yyyy-MM-dd");
|
|
ui->date->setText(date);
|
|
QString time=dateTime.toString("hhmm");
|
|
ui->time->setText(time);
|
|
m_dialFreq=dialFreq;
|
|
m_myCall=myCall;
|
|
m_myGrid=myGrid;
|
|
QString band= ADIF::bandFromFrequency(dialFreq / 1.e6);
|
|
ui->band->setText(band);
|
|
|
|
show ();
|
|
}
|
|
|
|
void LogQSO::accept()
|
|
{
|
|
QString hisCall,hisGrid,mode,rptSent,rptRcvd,date,time,band;
|
|
QString comments,name;
|
|
|
|
hisCall=ui->call->text();
|
|
hisGrid=ui->grid->text();
|
|
mode=ui->mode->text();
|
|
rptSent=ui->sent->text();
|
|
rptRcvd=ui->rcvd->text();
|
|
date=ui->date->text();
|
|
date=date.mid(0,4) + date.mid(5,2) + date.mid(8,2);
|
|
time=ui->time->text();
|
|
band=ui->band->text();
|
|
name=ui->name->text();
|
|
m_txPower=ui->txPower->text();
|
|
comments=ui->comments->text();
|
|
m_comments=comments;
|
|
QString strDialFreq(QString::number(m_dialFreq / 1.e6,'f',6));
|
|
|
|
//Log this QSO to ADIF file "wsjtx_log.adi"
|
|
QString filename = "wsjtx_log.adi"; // TODO allow user to set
|
|
ADIF adifile;
|
|
auto adifilePath = QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("wsjtx_log.adi");
|
|
adifile.init(adifilePath);
|
|
if (!adifile.addQSOToFile(hisCall,hisGrid,mode,rptSent,rptRcvd,date,time,band,comments,name,strDialFreq,m_myCall,m_myGrid,m_txPower))
|
|
{
|
|
QMessageBox m;
|
|
m.setText("Cannot open file \"" + adifilePath + "\".");
|
|
m.exec();
|
|
}
|
|
|
|
//Log this QSO to file "wsjtx.log"
|
|
static QFile f {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("wsjtx.log")};
|
|
if(!f.open(QIODevice::Text | QIODevice::Append)) {
|
|
QMessageBox m;
|
|
m.setText("Cannot open file \"" + f.fileName () + "\" for append:" + f.errorString ());
|
|
m.exec();
|
|
} else {
|
|
QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") +
|
|
m_dateTime.time().toString("hh:mm,") + hisCall + "," +
|
|
hisGrid + "," + strDialFreq + "," + mode +
|
|
"," + rptSent + "," + rptRcvd + "," + m_txPower +
|
|
"," + comments; + "," + name;
|
|
QTextStream out(&f);
|
|
out << logEntry << endl;
|
|
f.close();
|
|
}
|
|
|
|
//Clean up and finish logging
|
|
Q_EMIT acceptQSO (m_dateTime, hisCall, hisGrid, m_dialFreq, mode, rptSent, rptRcvd, m_txPower, comments, name);
|
|
QDialog::accept();
|
|
}
|
|
|
|
// closeEvent is only called from the system menu close widget for a
|
|
// modeless dialog so we use the hideEvent override to store the
|
|
// window settings
|
|
void LogQSO::hideEvent (QHideEvent * e)
|
|
{
|
|
storeSettings ();
|
|
QDialog::hideEvent (e);
|
|
}
|