Added n3fjp mapping of custom fields
This commit is contained in:
parent
22432c7fea
commit
72bf58ad4c
@ -58,24 +58,21 @@ TCPClient::TCPClient(QObject *parent) : QObject(parent)
|
||||
|
||||
bool TCPClient::ensureConnected(QString host, port_type port, int msecs){
|
||||
if(!m_->isConnected(host, port)){
|
||||
//qDebug() << "connecting to" << host << port;
|
||||
m_->connectToHost(host, port);
|
||||
}
|
||||
|
||||
return m_->waitForConnected(msecs);
|
||||
}
|
||||
|
||||
bool TCPClient::sendNetworkMessage(QString host, port_type port, QByteArray const &message, bool crlf){
|
||||
if(!ensureConnected(host, port)){
|
||||
bool TCPClient::sendNetworkMessage(QString host, port_type port, QByteArray const &message, bool crlf, int msecs){
|
||||
if(!ensureConnected(host, port, msecs)){
|
||||
return false;
|
||||
}
|
||||
|
||||
//qDebug() << "connecting to" << host << port;
|
||||
qint64 n = m_->send(message, crlf);
|
||||
if(n <= 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
//qDebug() << "sent" << n << "bytes" << message;
|
||||
return m_->flush();
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ signals:
|
||||
|
||||
public slots:
|
||||
Q_SLOT bool ensureConnected(QString host, port_type port, int msecs = 5000);
|
||||
Q_SLOT bool sendNetworkMessage(QString host, port_type port, QByteArray const &message, bool crlf=true);
|
||||
Q_SLOT bool sendNetworkMessage(QString host, port_type port, QByteArray const &message, bool crlf=true, int msecs=5000);
|
||||
|
||||
private:
|
||||
class impl;
|
||||
|
@ -117,7 +117,8 @@ HEADERS += qt_helpers.hpp \
|
||||
Inbox.h \
|
||||
messagewindow.h \
|
||||
SpotClient.h \
|
||||
TCPClient.h
|
||||
TCPClient.h \
|
||||
logbook/n3fjp.h
|
||||
|
||||
|
||||
INCLUDEPATH += qmake_only
|
||||
|
@ -333,7 +333,7 @@ QByteArray ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QStri
|
||||
, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn
|
||||
, QDateTime const& dateTimeOff, QString const& band, QString const& comments
|
||||
, QString const& name, QString const& strDialFreq, QString const& m_myCall
|
||||
, QString const& m_myGrid, QString const& operator_call, QMap<QString, QString> const &additionalFields)
|
||||
, QString const& m_myGrid, QString const& operator_call, QMap<QString, QVariant> const &additionalFields)
|
||||
{
|
||||
QString t;
|
||||
t = "<call:" + QString::number(hisCall.length()) + ">" + hisCall;
|
||||
@ -365,7 +365,7 @@ QByteArray ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QStri
|
||||
">" + operator_call;
|
||||
|
||||
foreach(auto key, additionalFields.keys()){
|
||||
auto value = additionalFields[key];
|
||||
auto value = additionalFields[key].toString();
|
||||
t += QString(" <%1:%2>%3").arg(key).arg(value.length()).arg(value);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QMultiHash>
|
||||
#include <QVariant>
|
||||
#else
|
||||
#include <QtGui>
|
||||
#endif
|
||||
@ -42,7 +43,7 @@ class ADIF
|
||||
, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff
|
||||
, QString const& band, QString const& comments, QString const& name
|
||||
, QString const& strDialFreq, QString const& m_myCall, QString const& m_myGrid
|
||||
, QString const& operator_call, const QMap<QString, QString> &additionalFields);
|
||||
, QString const& operator_call, const QMap<QString, QVariant> &additionalFields);
|
||||
|
||||
|
||||
struct QSO
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "countrydat.h"
|
||||
#include "countriesworked.h"
|
||||
#include "adif.h"
|
||||
#include "n3fjp.h"
|
||||
|
||||
class QDir;
|
||||
|
||||
|
82
logbook/n3fjp.h
Normal file
82
logbook/n3fjp.h
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef N3FJP_H
|
||||
#define N3FJP_H
|
||||
|
||||
|
||||
// Mapping between ADIF field to N3FJP field
|
||||
static const QMap<QString, QString> N3FJP_ADIF_MAP = {
|
||||
{"AGE", "fldAge"},
|
||||
//{"", "fldARCI"},
|
||||
{"BAND", "fldBand"},
|
||||
{"CALL", "fldCall"},
|
||||
//{"", "fldCategory"},
|
||||
{"CHECK", "fldCheck"},
|
||||
{"CLASS", "fldClass"},
|
||||
{"COMMENT", "fldComments"},
|
||||
{"COMMENT_INTL", "fldComments"},
|
||||
//{"", "fldComputerName"},
|
||||
{"CONTEST_ID", "fldContestID"},
|
||||
{"CONT", "fldContinent"},
|
||||
{"DXCC", "fldCountryDXCC"},
|
||||
//{"", "fldCountryWorked"},
|
||||
{"COUNTRY", "fldCountyR"},
|
||||
{"COUNTRY_INTL", "fldCountyR"},
|
||||
{"MY_COUNTRY", "fldCountyS"},
|
||||
{"MY_COUNTRY_INTL", "fldCountyS"},
|
||||
{"CQZ", "fldCQZone"},
|
||||
{"QSO_DATE", "fldDateStr"},
|
||||
{"FISTS", "fldFists"},
|
||||
{"FISTS_CC", "fldFists"},
|
||||
{"FREQ", "fldFrequency"},
|
||||
//{"", "fldFuture1"},
|
||||
//{"", "fldFuture2"},
|
||||
{"GRIDSQUARE", "fldGridR"},
|
||||
{"MY_GRIDSQUARE", "fldGridS"},
|
||||
//{"", "fldIARUZone"},
|
||||
//{"", "fldInitials"},
|
||||
{"IOTA", "fldIOTA"},
|
||||
{"ITUZ", "fldITUZone"},
|
||||
//{"", "fldLightHouse"},
|
||||
{"MODE", "fldMode"},
|
||||
{"CONTEST_ID", "fldModeContest"},
|
||||
{"NAME", "fldNameR"},
|
||||
{"NAME_INTL", "fldNameR"},
|
||||
{"MY_NAME", "fldNameS"},
|
||||
{"MY_NAME_INTL", "fldNameS"},
|
||||
{"OPERATOR", "fldOperator"},
|
||||
{"*1", "fldOther1"},
|
||||
{"*2", "fldOther2"},
|
||||
{"*3", "fldOther3"},
|
||||
{"*4", "fldOther4"},
|
||||
{"*5", "fldOther5"},
|
||||
{"*6", "fldOther6"},
|
||||
{"*7", "fldOther7"},
|
||||
{"*8", "fldOther8"},
|
||||
//{"", "fldPoints"},
|
||||
{"RX_PWR", "fldPower"},
|
||||
{"TX_PWR", "fldPower"},
|
||||
{"PRECEDENCE", "fldPrecedence"},
|
||||
{"PFX", "fldPrefix"},
|
||||
{"PROP_MODE", "fldPropMode"},
|
||||
{"QSL_RCVD_VIA", "fldQSLConfByR"},
|
||||
{"QSL_SENT_VIA", "fldQSLConfByS"},
|
||||
{"QSL_RCVD", "fldQSLR"},
|
||||
{"QSL_SENT", "fldQSLS"},
|
||||
{"QTH", "fldQTHGroup"},
|
||||
{"QTH_INTL", "fldQTHGroup"},
|
||||
{"RST_RCVD", "fldRstR"},
|
||||
{"RST_SENT", "fldRstS"},
|
||||
{"SAT_NAME", "fldSatName"},
|
||||
{"ARRL_SECT", "fldSection"},
|
||||
{"SRX", "fldSerialNoR"},
|
||||
{"STX", "fldSerialNoS"},
|
||||
{"SRX_STRING", "fldSPC"},
|
||||
{"SRX", "fldSPCNum"},
|
||||
{"STATE", "fldState"},
|
||||
{"STATION_CALLSIGN", "fldStation"},
|
||||
{"TEN_TEN", "fldTenTen"},
|
||||
{"TIME_OFF", "fldTimeOffStr"},
|
||||
{"TIME_ON", "fldTimeOnStr"},
|
||||
//{"", "fldTransmitterID"},
|
||||
};
|
||||
|
||||
#endif // N3FJP_H
|
71
logqso.cpp
71
logqso.cpp
@ -92,6 +92,18 @@ void LogQSO::createAdditionalField(QString key, QString value){
|
||||
m_additionalFieldsControls.append(l);
|
||||
}
|
||||
|
||||
QMap<QString, QVariant> LogQSO::collectAdditionalFields(){
|
||||
QMap<QString, QVariant> additionalFields;
|
||||
foreach(auto field, m_additionalFieldsControls){
|
||||
auto key = field->property("fieldKey").toString();
|
||||
if(key.isEmpty()){
|
||||
continue;
|
||||
}
|
||||
additionalFields[key] = QVariant(field->text());
|
||||
}
|
||||
return additionalFields;
|
||||
}
|
||||
|
||||
void LogQSO::resetAdditionalFields(){
|
||||
if(m_additionalFieldsControls.isEmpty()){
|
||||
return;
|
||||
@ -207,15 +219,6 @@ void LogQSO::accept()
|
||||
QString hisCall,hisGrid,mode,submode,rptSent,rptRcvd,dateOn,dateOff,timeOn,timeOff,band,operator_call;
|
||||
QString comments,name;
|
||||
|
||||
QMap<QString, QString> additionalFields;
|
||||
foreach(auto field, m_additionalFieldsControls){
|
||||
auto key = field->property("fieldKey").toString();
|
||||
if(key.isEmpty()){
|
||||
continue;
|
||||
}
|
||||
additionalFields[key] = field->text();
|
||||
}
|
||||
|
||||
hisCall=ui->call->text().toUpper();
|
||||
hisGrid=ui->grid->text().toUpper();
|
||||
mode = ui->mode->text().toUpper();
|
||||
@ -239,6 +242,8 @@ void LogQSO::accept()
|
||||
auto adifilePath = QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath (filename);
|
||||
adifile.init(adifilePath);
|
||||
|
||||
auto additionalFields = collectAdditionalFields();
|
||||
|
||||
QByteArray ADIF {adifile.QSOToADIF (hisCall, hisGrid, mode, submode, rptSent, rptRcvd, m_dateTimeOn, m_dateTimeOff, band
|
||||
, comments, name, strDialFreq, m_myCall, m_myGrid, operator_call, additionalFields)};
|
||||
|
||||
@ -248,38 +253,42 @@ void LogQSO::accept()
|
||||
tr ("Cannot open \"%1\"").arg (adifilePath));
|
||||
}
|
||||
|
||||
// Log to N1MM Logger
|
||||
if (m_config->broadcast_to_n1mm() && m_config->valid_n1mm_info()) {
|
||||
const QHostAddress n1mmhost = QHostAddress(m_config->n1mm_server_name());
|
||||
QUdpSocket _sock;
|
||||
auto rzult = _sock.writeDatagram (ADIF + " <eor>", n1mmhost, quint16(m_config->n1mm_server_port()));
|
||||
if (rzult == -1) {
|
||||
MessageBox::warning_message (this, tr ("Error sending log to N1MM"),
|
||||
tr ("Write returned \"%1\"").arg (rzult));
|
||||
}
|
||||
}
|
||||
|
||||
//Log this QSO to file "js8call.log"
|
||||
//Log this QSO to file "js8call.log"
|
||||
static QFile f {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("js8call.log")};
|
||||
if(!f.open(QIODevice::Text | QIODevice::Append)) {
|
||||
MessageBox::warning_message (this, tr ("Log file error"),
|
||||
tr ("Cannot open \"%1\" for append").arg (f.fileName ()),
|
||||
tr ("Error: %1").arg (f.errorString ()));
|
||||
} else {
|
||||
QString logEntry=m_dateTimeOn.date().toString("yyyy-MM-dd,") +
|
||||
m_dateTimeOn.time().toString("hh:mm:ss,") +
|
||||
m_dateTimeOff.date().toString("yyyy-MM-dd,") +
|
||||
m_dateTimeOff.time().toString("hh:mm:ss,") + hisCall + "," +
|
||||
hisGrid + "," + strDialFreq + "," + (mode == "MFSK" ? "JS8" : mode) +
|
||||
"," + rptSent + "," + rptRcvd +
|
||||
"," + comments + "," + name;
|
||||
QStringList logEntryItems = {
|
||||
m_dateTimeOn.date().toString("yyyy-MM-dd"),
|
||||
m_dateTimeOn.time().toString("hh:mm:ss"),
|
||||
m_dateTimeOff.date().toString("yyyy-MM-dd"),
|
||||
m_dateTimeOff.time().toString("hh:mm:ss"),
|
||||
hisCall,
|
||||
hisGrid,
|
||||
strDialFreq,
|
||||
(mode == "MFSK" ? "JS8" : mode),
|
||||
rptSent,
|
||||
rptRcvd,
|
||||
comments,
|
||||
name
|
||||
};
|
||||
|
||||
if(!additionalFields.isEmpty()){
|
||||
foreach(auto value, additionalFields.values()){
|
||||
logEntryItems.append(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
QTextStream out(&f);
|
||||
out << logEntry << endl;
|
||||
out << logEntryItems.join(",") << endl;
|
||||
f.close();
|
||||
}
|
||||
|
||||
//Clean up and finish logging
|
||||
Q_EMIT acceptQSO (m_dateTimeOff, hisCall, hisGrid, m_dialFreq, mode, submode, rptSent, rptRcvd, comments, name,m_dateTimeOn, operator_call, m_myCall, m_myGrid, ADIF);
|
||||
//Clean up and finish logging
|
||||
Q_EMIT acceptQSO (m_dateTimeOff, hisCall, hisGrid, m_dialFreq, mode, submode, rptSent, rptRcvd, comments, name,m_dateTimeOn, operator_call, m_myCall, m_myGrid, ADIF, additionalFields);
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
|
3
logqso.h
3
logqso.h
@ -45,7 +45,7 @@ signals:
|
||||
, QString const& rpt_sent, QString const& rpt_received
|
||||
, QString const& comments
|
||||
, QString const& name, QDateTime const& QSO_date_on, QString const& operator_call
|
||||
, QString const& my_call, QString const& my_grid, QByteArray const& ADIF);
|
||||
, QString const& my_call, QString const& my_grid, QByteArray const& ADIF, QMap<QString, QVariant> const &additionalFields);
|
||||
|
||||
protected:
|
||||
void hideEvent (QHideEvent *);
|
||||
@ -53,6 +53,7 @@ protected:
|
||||
private slots:
|
||||
void createAdditionalField(QString key={}, QString value={});
|
||||
void resetAdditionalFields();
|
||||
QMap<QString, QVariant> collectAdditionalFields();
|
||||
void on_add_new_field_button_pressed();
|
||||
void on_start_now_button_pressed();
|
||||
void on_end_now_button_pressed();
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <QActionGroup>
|
||||
#include <QSplashScreen>
|
||||
#include <QSound>
|
||||
#include <QUdpSocket>
|
||||
#include <QVariant>
|
||||
|
||||
#include "APRSISClient.h"
|
||||
#include "revision_utils.hpp"
|
||||
@ -6624,6 +6626,7 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
|
||||
}
|
||||
|
||||
QString comments = ui->textEditRX->textCursor().selectedText();
|
||||
|
||||
m_logDlg->initLogQSO (call.trimmed(), grid.trimmed(), m_modeTx == "FT8" ? "JS8" : m_modeTx, m_rptSent, m_rptRcvd,
|
||||
m_dateTimeQSOOn, dateTimeQSOOff, m_freqNominal + ui->TxFreqSpinBox->value(),
|
||||
m_config.my_callsign(), m_config.my_grid(),
|
||||
@ -6636,11 +6639,12 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
|
||||
, QString const& rpt_sent, QString const& rpt_received
|
||||
, QString const& comments
|
||||
, QString const& name, QDateTime const& QSO_date_on, QString const& operator_call
|
||||
, QString const& my_call, QString const& my_grid, QByteArray const& ADIF)
|
||||
, QString const& my_call, QString const& my_grid, QByteArray const& ADIF, QMap<QString, QVariant> const &additionalFields)
|
||||
{
|
||||
QString date = QSO_date_on.toString("yyyyMMdd");
|
||||
m_logBook.addAsWorked (m_hisCall, m_config.bands ()->find (m_freqNominal), mode, submode, date, name, comments);
|
||||
|
||||
// Log to JS8Call API
|
||||
if(m_config.udpEnabled()){
|
||||
sendNetworkMessage("LOG.QSO", QString(ADIF), {
|
||||
{"UTC.ON", QVariant(QSO_date_on.toMSecsSinceEpoch())},
|
||||
@ -6656,10 +6660,23 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
|
||||
{"COMMENTS", QVariant(comments)},
|
||||
{"STATION.OP", QVariant(operator_call)},
|
||||
{"STATION.CALL", QVariant(my_call)},
|
||||
{"STATION.GRID", QVariant(my_grid)}
|
||||
{"STATION.GRID", QVariant(my_grid)},
|
||||
{"EXTRA", additionalFields}
|
||||
});
|
||||
}
|
||||
|
||||
// Log to N1MM Logger
|
||||
if (m_config.broadcast_to_n1mm() && m_config.valid_n1mm_info()) {
|
||||
const QHostAddress n1mmhost = QHostAddress(m_config.n1mm_server_name());
|
||||
QUdpSocket _sock;
|
||||
auto rzult = _sock.writeDatagram (ADIF + " <eor>", n1mmhost, quint16(m_config.n1mm_server_port()));
|
||||
if (rzult == -1) {
|
||||
MessageBox::warning_message (this, tr ("Error sending log to N1MM"),
|
||||
tr ("Write returned \"%1\"").arg (rzult));
|
||||
}
|
||||
}
|
||||
|
||||
// Log to N3FJP Logger
|
||||
if(m_config.broadcast_to_n3fjp() && m_config.valid_n3fjp_info()){
|
||||
QString data = QString(
|
||||
"<CMD>"
|
||||
@ -6678,6 +6695,7 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
|
||||
"<fldComments>%9</fldComments>"
|
||||
"<fldRstS>%10</fldRstS>"
|
||||
"<fldRstR>%11</fldRstR>"
|
||||
"%12"
|
||||
"</CMD>");
|
||||
|
||||
data = data.arg(QSO_date_on.toString("yyyy/MM/dd"));
|
||||
@ -6692,15 +6710,36 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
|
||||
data = data.arg(rpt_sent);
|
||||
data = data.arg(rpt_received);
|
||||
|
||||
int other = 0;
|
||||
QStringList additional;
|
||||
if(!additionalFields.isEmpty()){
|
||||
foreach(auto key, additionalFields.keys()){
|
||||
QString n3key;
|
||||
if(N3FJP_ADIF_MAP.contains(key)){
|
||||
n3key = N3FJP_ADIF_MAP.value(key);
|
||||
} else {
|
||||
other++;
|
||||
n3key = N3FJP_ADIF_MAP.value(QString("*%1").arg(other));
|
||||
}
|
||||
|
||||
if(n3key.isEmpty()){
|
||||
break;
|
||||
}
|
||||
auto value = additionalFields[key].toString();
|
||||
additional.append(QString("<%1>%2</%1>").arg(n3key).arg(value));
|
||||
}
|
||||
}
|
||||
data = data.arg(additional.join(""));
|
||||
|
||||
auto host = m_config.n3fjp_server_name();
|
||||
auto port = m_config.n3fjp_server_port();
|
||||
|
||||
m_n3fjpClient->sendNetworkMessage(host, port, data.toLocal8Bit());
|
||||
|
||||
QTimer::singleShot(300, this, [this, host, port](){
|
||||
m_n3fjpClient->sendNetworkMessage(host, port, "<CMD><CHECKLOG></CMD>");
|
||||
m_n3fjpClient->sendNetworkMessage(host, port, "\r\n");
|
||||
});
|
||||
if(m_n3fjpClient->sendNetworkMessage(host, port, data.toLocal8Bit(), 100)){
|
||||
QTimer::singleShot(300, this, [this, host, port](){
|
||||
m_n3fjpClient->sendNetworkMessage(host, port, "<CMD><CHECKLOG></CMD>", 100);
|
||||
m_n3fjpClient->sendNetworkMessage(host, port, "\r\n", 100);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// reload the logbook data
|
||||
|
@ -352,7 +352,7 @@ private slots:
|
||||
, QString const& rpt_sent, QString const& rpt_received
|
||||
, QString const& comments
|
||||
, QString const& name, QDateTime const& QSO_date_on, QString const& operator_call
|
||||
, QString const& my_call, QString const& my_grid, QByteArray const& ADIF);
|
||||
, QString const& my_call, QString const& my_grid, QByteArray const& ADIF, const QMap<QString, QVariant> &additionalFields);
|
||||
void on_bandComboBox_currentIndexChanged (int index);
|
||||
void on_bandComboBox_activated (int index);
|
||||
void on_readFreq_clicked();
|
||||
|
Loading…
Reference in New Issue
Block a user