From f98aa4e6f4ecf10fa373482ac6562440055f250b Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 30 Dec 2016 15:45:31 +0000 Subject: [PATCH] Options (via Ctrl+M) to minimize size of Main Window and Wide Graph; add separate Start/End times to logging information. Thanks to W9MDB! git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7430 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- MessageClient.cpp | 8 +- MessageClient.hpp | 4 +- MessageServer.cpp | 11 +- MessageServer.hpp | 4 +- NetworkMessage.hpp | 3 +- .../en/controls-functions-main-window.adoc | 9 +- .../en/controls-functions-wide-graph.adoc | 10 + doc/user_guide/en/images/log-qso.png | Bin 14418 -> 9920 bytes doc/user_guide/en/images/view-menu.png | Bin 3458 -> 3767 bytes logbook/adif.cpp | 8 +- logbook/adif.h | 2 +- logqso.cpp | 38 +- logqso.h | 9 +- logqso.ui | 1610 +++++++++-------- mainwindow.cpp | 133 +- mainwindow.h | 14 +- mainwindow.ui | 13 + shortcuts.txt | 1 + widegraph.cpp | 61 + widegraph.h | 3 +- 20 files changed, 1135 insertions(+), 806 deletions(-) diff --git a/MessageClient.cpp b/MessageClient.cpp index 1c6712e31..ea657d329 100644 --- a/MessageClient.cpp +++ b/MessageClient.cpp @@ -400,17 +400,17 @@ void MessageClient::clear_decodes () } } -void MessageClient::qso_logged (QDateTime time, QString const& dx_call, QString const& dx_grid +void MessageClient::qso_logged (QDateTime timeOff, QString const& dx_call, QString const& dx_grid , Frequency dial_frequency, QString const& mode, QString const& report_sent , QString const& report_received, QString const& tx_power - , QString const& comments, QString const& name) + , QString const& comments, QString const& name, QDateTime timeOn) { if (m_->server_port_ && !m_->server_string_.isEmpty ()) { QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_}; - out << time << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 () - << report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 () << name.toUtf8 (); + out << timeOff << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 () + << report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 () << name.toUtf8 () << timeOn; m_->send_message (out, message); } } diff --git a/MessageClient.hpp b/MessageClient.hpp index d8b3788dd..9807c4d2f 100644 --- a/MessageClient.hpp +++ b/MessageClient.hpp @@ -57,10 +57,10 @@ public: Q_SLOT void WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency , qint32 drift, QString const& callsign, QString const& grid, qint32 power); Q_SLOT void clear_decodes (); - Q_SLOT void qso_logged (QDateTime time, QString const& dx_call, QString const& dx_grid + Q_SLOT void qso_logged (QDateTime timeOff, QString const& dx_call, QString const& dx_grid , Frequency dial_frequency, QString const& mode, QString const& report_sent , QString const& report_received, QString const& tx_power, QString const& comments - , QString const& name); + , QString const& name, QDateTime timeOn); // this slot may be used to send arbitrary UDP datagrams to and // destination allowing the underlying socket to be used for general diff --git a/MessageServer.cpp b/MessageServer.cpp index c33588649..a9812e3f3 100644 --- a/MessageServer.cpp +++ b/MessageServer.cpp @@ -273,7 +273,7 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s case NetworkMessage::QSOLogged: { - QDateTime time; + QDateTime timeOff; QByteArray dx_call; QByteArray dx_grid; Frequency dial_frequency; @@ -283,14 +283,15 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s QByteArray tx_power; QByteArray comments; QByteArray name; - in >> time >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received - >> tx_power >> comments >> name; + QDateTime timeOn; + in >> timeOff >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received + >> tx_power >> comments >> name >> timeOn; if (check_status (in) != Fail) { - Q_EMIT self_->qso_logged (id, time, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid) + Q_EMIT self_->qso_logged (id, timeOff, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid) , dial_frequency, QString::fromUtf8 (mode), QString::fromUtf8 (report_sent) , QString::fromUtf8 (report_received), QString::fromUtf8 (tx_power) - , QString::fromUtf8 (comments), QString::fromUtf8 (name)); + , QString::fromUtf8 (comments), QString::fromUtf8 (name), timeOn); } } break; diff --git a/MessageServer.hpp b/MessageServer.hpp index ad6cca1d0..7338cbe4e 100644 --- a/MessageServer.hpp +++ b/MessageServer.hpp @@ -72,10 +72,10 @@ public: , quint32 delta_frequency, QString const& mode, QString const& message); Q_SIGNAL void WSPR_decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time, Frequency , qint32 drift, QString const& callsign, QString const& grid, qint32 power); - Q_SIGNAL void qso_logged (QString const& id, QDateTime time, QString const& dx_call, QString const& dx_grid + Q_SIGNAL void qso_logged (QString const& id, QDateTime timeOff, QString const& dx_call, QString const& dx_grid , Frequency dial_frequency, QString const& mode, QString const& report_sent , QString const& report_received, QString const& tx_power, QString const& comments - , QString const& name); + , QString const& name, QDateTime timeOn); Q_SIGNAL void clear_decodes (QString const& id); // this signal is emitted when a network error occurs diff --git a/NetworkMessage.hpp b/NetworkMessage.hpp index 41fba03f9..00664b126 100644 --- a/NetworkMessage.hpp +++ b/NetworkMessage.hpp @@ -203,7 +203,7 @@ * * QSO Logged Out 5 quint32 * Id (unique key) utf8 - * Date & Time QDateTime + * Date & Time Off QDateTime * DX call utf8 * DX grid utf8 * Dial frequency (Hz) quint64 @@ -213,6 +213,7 @@ * Tx power utf8 * Comments utf8 * Name utf8 + * Date & Time On QDateTime * * The QSO logged message is sent to the server(s) when the * WSJT-X user accepts the "Log QSO" dialog by clicking the "OK" diff --git a/doc/user_guide/en/controls-functions-main-window.adoc b/doc/user_guide/en/controls-functions-main-window.adoc index 37f5b39f7..2af20722e 100644 --- a/doc/user_guide/en/controls-functions-main-window.adoc +++ b/doc/user_guide/en/controls-functions-main-window.adoc @@ -2,15 +2,18 @@ The following buttons appear just under the decoded text windows on the main screen: -//.Main UI Controls +//.Main UI image::main-ui-controls.png[align="left",width=650,alt="Main UI Controls"] * *Log QSO* raises a dialog window pre-filled with known information about a QSO you have nearly completed. You can edit or add to this information before clicking *OK* to log the QSO. If you check *Prompt me to log QSO* on the *Setup* menu, the program will raise the -confirmation screen automatically when you send a message containing -73. +confirmation screen automatically when you send a message +containing "`73`". *Start Date* and *Start Time* are set when you click +to send the *Tx 2* or *Tx 3* message, and backed up by one or two +minutes, respectively. End date and time are set when the *Log +QSO* screen is invoked. //.Log QSO Window image::log-qso.png[align="center",alt="Log QSO"] diff --git a/doc/user_guide/en/controls-functions-wide-graph.adoc b/doc/user_guide/en/controls-functions-wide-graph.adoc index e269f1e17..1e53b2730 100644 --- a/doc/user_guide/en/controls-functions-wide-graph.adoc +++ b/doc/user_guide/en/controls-functions-wide-graph.adoc @@ -87,3 +87,13 @@ spectra, thereby smoothing the curves over multiple bins. - Click the *Colors* button to cycle through 6 possible choices of color and line width for the plots. + +[[CONTROLS_MISCELLANEOUS]] +=== Miscellaneous + +Most windows can be resized as desired. If you are short of screen +space you can make the Main Window and Wide Graph smaller by hiding +some controls and labels. To enable this feature type *Ctrl+M* with +focus on the appropriate window. (For the Main Window you can select +*Hide menus and labels* on the *View* menu.) Type *Ctrl+M* again +to make the controls visible once more. diff --git a/doc/user_guide/en/images/log-qso.png b/doc/user_guide/en/images/log-qso.png index 5f46f6331a7e4e28bc5081a831994093035fbdb6..722927fe138bc84122f89c2df70a9214d032a775 100644 GIT binary patch literal 9920 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 literal 14418 zcmc(_WmH^2w=LR8fZzlI!4o>TJ2Wn#afjgUE{!`R5D4z>?(VL^T?4`0-Qjie-E)4u zJMNG7&U<6@?%lh3SFKumSIsqR)(V!F1*0JoAOipZGzoE0MF0TCA9|=DAwWwuy7ow* zCm2UXurQ!}jA$Qv0dFcKBLo0cMW8(Czky!AwG&r&1OU*xp+_%_h{G|oBImAzsF1R& z&T$$_Dv?Uu>$o&Uk_4=gFs%P)%nM&xn}Jbj$jU5kUmrZ|ox

  • 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

    ;g0GbcUw60X!_djh215!*xk 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 diff --git a/doc/user_guide/en/images/view-menu.png b/doc/user_guide/en/images/view-menu.png index b2bd323cb4dd0c8032712cf0daabd4d6cb5b9b30..602565b0fd675e8085eff5c94f097f9862f0d2a0 100644 GIT binary patch literal 3767 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 literal 3458 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" + mode; t+=" " + rptSent; t+=" " + rptRcvd; - t+=" " + date; - t+=" " + time; + t+=" " + dateOn; + t+=" " + timeOn; + t+=" " + dateOff; + t+=" " + timeOff; t+=" " + band; t+=" " + strDialFreq; t+=" " + diff --git a/logbook/adif.h b/logbook/adif.h index 7445d4aaf..a54db8eb0 100644 --- a/logbook/adif.h +++ b/logbook/adif.h @@ -28,7 +28,7 @@ class ADIF int getCount(); // open ADIF file and append the QSO details. Return true on success - bool addQSOToFile(const QString hisCall, const QString hisGrid, const QString mode, const QString rptSent, const QString rptRcvd, const QString date, const QString time, const QString band, + bool addQSOToFile(const QString hisCall, const QString hisGrid, const QString mode, const QString rptSent, const QString rptRcvd, const QString dateOn, const QString timeOn, const QString dateOff, const QString timeOff, const QString band, const QString comments, const QString name, const QString strDialFreq, const QString m_myCall, const QString m_myGrid, const QString m_txPower); static QString bandFromFrequency(double dialFreq); diff --git a/logqso.cpp b/logqso.cpp index aefd4370e..39ef44495 100644 --- a/logqso.cpp +++ b/logqso.cpp @@ -49,7 +49,7 @@ void LogQSO::storeSettings () const } void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode, - QString rptSent, QString rptRcvd, QDateTime dateTime, + QString rptSent, QString rptRcvd, QDateTime dateTimeOn, QDateTime dateTimeOff, Radio::Frequency dialFreq, QString myCall, QString myGrid, bool noSuffix, bool toRTTY, bool dBtoComments) { @@ -72,11 +72,16 @@ void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode, 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_dateTimeOn=dateTimeOn; + m_dateTimeOff=dateTimeOff; + QString dateOn=dateTimeOn.toString("yyyy-MM-dd"); + ui->dateOn->setText(dateOn); + QString timeOn=dateTimeOn.toString("hhmm"); + ui->timeOn->setText(timeOn); + QString dateOff=dateTimeOff.toString("yyyy-MM-dd"); + ui->dateOff->setText(dateOff); + QString timeOff=dateTimeOff.toString("hhmm"); + ui->timeOff->setText(timeOff); m_dialFreq=dialFreq; m_myCall=myCall; m_myGrid=myGrid; @@ -88,7 +93,7 @@ void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode, void LogQSO::accept() { - QString hisCall,hisGrid,mode,rptSent,rptRcvd,date,time,band; + QString hisCall,hisGrid,mode,rptSent,rptRcvd,dateOn,dateOff,timeOn,timeOff,band; QString comments,name; hisCall=ui->call->text(); @@ -96,9 +101,12 @@ void LogQSO::accept() 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(); + dateOn=ui->dateOn->text(); + dateOn=dateOn.mid(0,4) + dateOn.mid(5,2) + dateOn.mid(8,2); + timeOn=ui->timeOn->text(); + dateOff=ui->dateOff->text(); + dateOff=dateOff.mid(0,4) + dateOff.mid(5,2) + dateOff.mid(8,2); + timeOff=ui->timeOff->text(); band=ui->band->text(); name=ui->name->text(); m_txPower=ui->txPower->text(); @@ -111,7 +119,7 @@ void LogQSO::accept() 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)) + if (!adifile.addQSOToFile(hisCall,hisGrid,mode,rptSent,rptRcvd,dateOn,timeOn,dateOff,timeOff,band,comments,name,strDialFreq,m_myCall,m_myGrid,m_txPower)) { MessageBox::warning_message (this, tr ("Log file error"), tr ("Cannot open \"%1\"").arg (adifilePath)); @@ -124,8 +132,10 @@ void LogQSO::accept() tr ("Cannot open \"%1\" for append").arg (f.fileName ()), tr ("Error: %1").arg (f.errorString ())); } else { - QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") + - m_dateTime.time().toString("hh:mm,") + hisCall + "," + + QString logEntry=m_dateTimeOn.date().toString("yyyy-MM-dd,") + + m_dateTimeOn.time().toString("hh:mm,") + + m_dateTimeOff.date().toString("yyyy-MM-dd,") + + m_dateTimeOff.time().toString("hh:mm,") + hisCall + "," + hisGrid + "," + strDialFreq + "," + mode + "," + rptSent + "," + rptRcvd + "," + m_txPower + "," + comments + "," + name; @@ -135,7 +145,7 @@ void LogQSO::accept() } //Clean up and finish logging - Q_EMIT acceptQSO (m_dateTime, hisCall, hisGrid, m_dialFreq, mode, rptSent, rptRcvd, m_txPower, comments, name); + Q_EMIT acceptQSO (m_dateTimeOff, hisCall, hisGrid, m_dialFreq, mode, rptSent, rptRcvd, m_txPower, comments, name,m_dateTimeOn); QDialog::accept(); } diff --git a/logqso.h b/logqso.h index fb1609a24..55b0dd9cd 100644 --- a/logqso.h +++ b/logqso.h @@ -26,7 +26,7 @@ public: explicit LogQSO(QString const& programTitle, QSettings *, QWidget *parent = 0); ~LogQSO(); void initLogQSO(QString hisCall, QString hisGrid, QString mode, - QString rptSent, QString rptRcvd, QDateTime dateTime, + QString rptSent, QString rptRcvd, QDateTime dateTimeOn,QDateTime dateTimeOff, Radio::Frequency dialFreq, QString myCall, QString myGrid, bool noSuffix, bool toRTTY, bool dBtoComments); @@ -34,11 +34,11 @@ public slots: void accept(); signals: - void acceptQSO (QDateTime const&, QString const& call, QString const& grid + void acceptQSO (QDateTime const& QSO_date_off, QString const& call, QString const& grid , Radio::Frequency dial_freq, QString const& mode , QString const& rpt_sent, QString const& rpt_received , QString const& tx_power, QString const& comments - , QString const& name); + , QString const& name, QDateTime const& QSO_date_on); protected: void hideEvent (QHideEvent *); @@ -54,7 +54,8 @@ private: Radio::Frequency m_dialFreq; QString m_myCall; QString m_myGrid; - QDateTime m_dateTime; + QDateTime m_dateTimeOn; + QDateTime m_dateTimeOff; }; #endif // LogQSO_H diff --git a/logqso.ui b/logqso.ui index 36cb10066..2ea916eee 100644 --- a/logqso.ui +++ b/logqso.ui @@ -1,756 +1,854 @@ - - - LogQSO - - - - 0 - 0 - 372 - 305 - - - - - 16777215 - 16777215 - - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 10 - - - - - - - - - 10 - - - - Click OK to confirm the following QSO: - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 10 - - - - - - - - - - - 0 - 0 - - - - - 70 - 0 - - - - - 70 - 16777215 - - - - - 10 - - - - Call - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 10 - - - - Date - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - 10 - - - - Time - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - 10 - - - - Mode - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - 10 - - - - Band - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - - 70 - 0 - - - - - 70 - 16777215 - - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 10 - - - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - 10 - - - - Rpt Sent - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - 10 - - - - Rpt Rcvd - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - 10 - - - - Grid - - - Qt::AlignCenter - - - - - - - true - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 10 - - - - Name - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - - - - - true - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 10 - - - - - - - - - - - 65 - 0 - - - - Tx power - - - - - - - - - - Retain - - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 10 - - - - - - - - - - true - - - - 65 - 0 - - - - - 10 - - - - Comments - - - - - - - true - - - - - - - Retain - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - call - date - time - mode - band - sent - rcvd - grid - name - txPower - cbTxPower - comments - cbComments - buttonBox - - - - - buttonBox - accepted() - LogQSO - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - LogQSO - reject() - - - 316 - 260 - - - 286 - 274 - - - - - + + + LogQSO + + + + 0 + 0 + 520 + 318 + + + + + 16777215 + 16777215 + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 13 + + + + + + + + + 10 + + + + Click OK to confirm the following QSO: + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 13 + + + + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + + 70 + 16777215 + + + + + 10 + + + + Call + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + 10 + + + + Start Date + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 60 + 16777215 + + + + + 10 + + + + Start Time + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + 10 + + + + End Date + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 60 + 16777215 + + + + + 10 + + + + End Time + + + Qt::AlignCenter + + + + + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + + 70 + 16777215 + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + + + + + 50 + 0 + + + + + 60 + 16777215 + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + + + + + 50 + 0 + + + + + 60 + 16777215 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 13 + + + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + 10 + + + + Mode + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + 10 + + + + Band + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + 10 + + + + Rpt Sent + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + 10 + + + + Rpt Rcvd + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + 10 + + + + Grid + + + Qt::AlignCenter + + + + + + + true + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + 10 + + + + Name + + + Qt::AlignCenter + + + + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + + + + true + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 13 + + + + + + + + + + + 65 + 0 + + + + Tx power + + + + + + + + + + Retain + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 13 + + + + + + + + + + true + + + + 65 + 0 + + + + + 10 + + + + Comments + + + + + + + true + + + + + + + Retain + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + call + dateOn + timeOn + sent + rcvd + grid + name + txPower + cbTxPower + comments + cbComments + buttonBox + + + + + buttonBox + accepted() + LogQSO + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + LogQSO + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/mainwindow.cpp b/mainwindow.cpp index 3e93296da..ca6c83ea5 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -504,6 +504,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, txMsgButtonGroup->addButton(ui->txrb4,4); txMsgButtonGroup->addButton(ui->txrb5,5); txMsgButtonGroup->addButton(ui->txrb6,6); + set_dateTimeQSO(-1); connect(txMsgButtonGroup,SIGNAL(buttonClicked(int)),SLOT(set_ntx(int))); connect(ui->decodedTextBrowser2,SIGNAL(selectCallsign(bool,bool)),this, SLOT(doubleClickOnCall(bool,bool))); @@ -679,6 +680,9 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_audioThread.start (m_audioThreadPriority); + m_dateTimeDefault=QDateTime(QDate(1900,1,1),QTime(0,0)); + m_dateTimeQSOOn=m_dateTimeDefault; + #ifdef WIN32 if (!m_multiple) { @@ -849,6 +853,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, connect (&splashTimer, &QTimer::timeout, this, &MainWindow::splash_done); splashTimer.setSingleShot (true); splashTimer.start (20 * 1000); + m_bHideControls = !m_bHideControls; // we're not toggling here so we start in opposite state + on_actionHide_Controls_triggered(); // this must be the last statement of constructor if (!m_valid) throw std::runtime_error {"Fatal initialization exception"}; @@ -904,6 +910,7 @@ void MainWindow::writeSettings() { m_settings->beginGroup("MainWindow"); m_settings->setValue ("geometry", saveGeometry ()); + m_settings->setValue ("geometryNoControls", m_geometryNoControls); m_settings->setValue ("state", saveState ()); m_settings->setValue("MRUdir", m_path); m_settings->setValue("TxFirst",m_txFirst); @@ -912,6 +919,7 @@ void MainWindow::writeSettings() m_settings->setValue ("AstroDisplayed", m_astroWidget && m_astroWidget->isVisible()); m_settings->setValue ("MsgAvgDisplayed", m_msgAvgWidget && m_msgAvgWidget->isVisible()); m_settings->setValue ("FreeText", ui->freeTextMsg->currentText ()); + m_settings->setValue ("HideControls", m_bHideControls); m_settings->endGroup(); m_settings->beginGroup("Common"); @@ -958,6 +966,7 @@ void MainWindow::readSettings() { m_settings->beginGroup("MainWindow"); restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ()); + m_geometryNoControls = m_settings->value ("geometryNoControls",saveGeometry()).toByteArray(); restoreState (m_settings->value ("state", saveState ()).toByteArray ()); ui->dxCallEntry->setText (m_settings->value ("DXcall", QString {}).toString ()); ui->dxGridEntry->setText (m_settings->value ("DXgrid", QString {}).toString ()); @@ -967,6 +976,7 @@ void MainWindow::readSettings() auto displayMsgAvg = m_settings->value ("MsgAvgDisplayed", false).toBool (); if (m_settings->contains ("FreeText")) ui->freeTextMsg->setCurrentText ( m_settings->value ("FreeText").toString ()); + m_bHideControls = m_settings->value("HideControls", false).toBool (); m_settings->endGroup(); // do this outside of settings group because it uses groups internally @@ -1550,6 +1560,12 @@ void MainWindow::keyPressEvent (QKeyEvent * e) } } break; + case Qt::Key_M: + if(e->modifiers() & Qt::ControlModifier) { + on_actionHide_Controls_triggered(); + return; + } + break; case Qt::Key_F4: clearDX (); ui->dxCallEntry->setFocus(); @@ -1919,6 +1935,59 @@ void MainWindow::on_actionFast_Graph_triggered() m_fastGraph->show(); } +// This allows the window to shrink by removing certain things +// and reducing space used by controls +void MainWindow::on_actionHide_Controls_triggered() +{ + m_bHideControls = !m_bHideControls; + int spacing = m_bHideControls ? 1 : 6; + + if (m_bHideControls) { + statusBar ()->removeWidget (&auto_tx_label); + minimumSize().setHeight(450); + minimumSize().setWidth(700); + restoreGeometry(m_geometryNoControls); + updateGeometry(); + //resize(450,700); // how to auto-shrink it? + } + else { + m_geometryNoControls = saveGeometry(); + statusBar ()->addWidget(&auto_tx_label); + minimumSize().setHeight(520); + minimumSize().setWidth(770); + } + ui->menuBar->setVisible(!m_bHideControls); + ui->label_6->setVisible(!m_bHideControls); + ui->line->setVisible(!m_bHideControls); + ui->line_2->setVisible(!m_bHideControls); + ui->label_7->setVisible(!m_bHideControls); + ui->decodedTextLabel->setVisible(!m_bHideControls); + ui->decodedTextLabel2->setVisible(!m_bHideControls); + ui->gridLayout_5->layout()->setSpacing(spacing); + ui->horizontalLayout->layout()->setSpacing(spacing); + ui->horizontalLayout_2->layout()->setSpacing(spacing); + ui->horizontalLayout_3->layout()->setSpacing(spacing); + ui->horizontalLayout_4->layout()->setSpacing(spacing); + ui->horizontalLayout_5->layout()->setSpacing(spacing); + ui->horizontalLayout_6->layout()->setSpacing(spacing); + ui->horizontalLayout_7->layout()->setSpacing(spacing); + ui->horizontalLayout_8->layout()->setSpacing(spacing); + ui->horizontalLayout_9->layout()->setSpacing(spacing); + ui->horizontalLayout_10->layout()->setSpacing(spacing); + ui->horizontalLayout_11->layout()->setSpacing(spacing); + ui->horizontalLayout_12->layout()->setSpacing(spacing); + ui->horizontalLayout_13->layout()->setSpacing(spacing); + ui->horizontalLayout_14->layout()->setSpacing(spacing); + ui->verticalLayout->layout()->setSpacing(spacing); + ui->verticalLayout_2->layout()->setSpacing(spacing); + ui->verticalLayout_3->layout()->setSpacing(spacing); + ui->verticalLayout_4->layout()->setSpacing(spacing); + ui->verticalLayout_5->layout()->setSpacing(spacing); + ui->verticalLayout_7->layout()->setSpacing(spacing); + ui->verticalLayout_8->layout()->setSpacing(spacing); + ui->tab->layout()->setSpacing(spacing); +} + void MainWindow::on_actionAstronomical_data_toggled (bool checked) { if (checked) @@ -2595,6 +2664,7 @@ void MainWindow::on_EraseButton_clicked() //Erase } } m_msErase=ms; + set_dateTimeQSO(-1); } void MainWindow::decodeBusy(bool b) //decodeBusy() @@ -3153,11 +3223,51 @@ void MainWindow::on_txFirstCheckBox_stateChanged(int nstate) //TxFirst m_txFirst = (nstate==2); } +void MainWindow::set_dateTimeQSO(int m_ntx) +{ + // m_ntx = -1 resets to default time + // Our QSO start time can be fairly well determined from Tx 2 and Tx 3 -- the grid reports + // If we CQ'd and sending sigrpt then 2 minutes ago n=2 + // If we're on msg 3 then 3 minutes ago n=3 -- might have sat on msg1 for a while + // If we've already set our time on just return. + // This should mean that Tx2 or Tx3 has been repeated so don't update the start time + // We reset it in several places + if (m_ntx == -1) { // we use a default date to detect change + m_dateTimeQSOOn=m_dateTimeDefault; + } + else if (m_dateTimeQSOOn != m_dateTimeDefault) { + return; + } + else { // we also take of m_TRperiod/2 to allow for late clicks + m_dateTimeQSOOn=QDateTime::currentDateTimeUtc().addSecs((-(m_ntx-1)*m_TRperiod)-m_TRperiod/2); + } +} + void MainWindow::set_ntx(int n) //set_ntx() { m_ntx=n; } +void MainWindow::on_txrb1_toggled(bool status) +{ + // if Tx 1 is clicked we won't use it so reset to default + // We may hang on this message for quite a while trying + // to get a response perhaps when another QSO is going on + if (status) set_dateTimeQSO(-1); +} + +void MainWindow::on_txrb2_toggled(bool status) +{ + // Tx 2 means we already have CQ'd so good reference + if (status) set_dateTimeQSO(m_ntx); +} + +void MainWindow::on_txrb3_toggled(bool status) +{ + // Tx 3 means we should havel already have done Tx 1 so good reference + if (status) set_dateTimeQSO(m_ntx); +} + void MainWindow::on_txb1_clicked() //txb1 { m_ntx=1; @@ -3198,10 +3308,12 @@ void MainWindow::on_txb6_clicked() //txb6 m_ntx=6; ui->txrb6->setChecked(true); if (m_transmitting) m_restart=true; + if (ui->txrb6->text().contains("CQ")) set_dateTimeQSO(-1); } void MainWindow::doubleClickOnCall2(bool shift, bool ctrl) { + set_dateTimeQSO(-1); // reset our QSO start time m_decodedText2=true; doubleClickOnCall(shift,ctrl); m_decodedText2=false; @@ -3211,6 +3323,7 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl) { QTextCursor cursor; QString t; //Full contents + set_dateTimeQSO(-1); // reset our QSO start time if(m_mode=="ISCAT") { MessageBox::information_message (this, "Double-click not presently implemented for ISCAT mode"); @@ -3935,24 +4048,27 @@ void MainWindow::on_genStdMsgsPushButton_clicked() //genStdMsgs button void MainWindow::on_logQSOButton_clicked() //Log QSO button { if (!m_hisCall.size ()) return; - m_dateTimeQSO=QDateTime::currentDateTimeUtc(); - + // m_dateTimeQSOOn should really already be set but we'll ensure it gets set to something just in case + if (m_dateTimeQSOOn==m_dateTimeDefault) + m_dateTimeQSOOn=QDateTime::currentDateTimeUtc(); + m_dateTimeQSOOff = QDateTime::currentDateTimeUtc(); m_logDlg->initLogQSO (m_hisCall, m_hisGrid, m_modeTx, m_rptSent, m_rptRcvd, - m_dateTimeQSO, m_freqNominal + ui->TxFreqSpinBox->value(), + m_dateTimeQSOOn, m_dateTimeQSOOff, m_freqNominal + ui->TxFreqSpinBox->value(), m_config.my_callsign(), m_config.my_grid(), m_noSuffix, m_config.log_as_RTTY(), m_config.report_in_comments()); + m_dateTimeQSOOn = m_dateTimeDefault; } -void MainWindow::acceptQSO2(QDateTime const& QSO_date, QString const& call, QString const& grid +void MainWindow::acceptQSO2(QDateTime const& QSO_date_off, QString const& call, QString const& grid , Frequency dial_freq, QString const& mode , QString const& rpt_sent, QString const& rpt_received , QString const& tx_power, QString const& comments - , QString const& name) + , QString const& name, QDateTime const& QSO_date_on) { - QString date = m_dateTimeQSO.toString("yyyyMMdd"); + QString date = m_dateTimeQSOOn.toString("yyyyMMdd"); m_logBook.addAsWorked (m_hisCall, m_config.bands ()->find (m_freqNominal), m_modeTx, date); - m_messageClient->qso_logged (QSO_date, call, grid, dial_freq, mode, rpt_sent, rpt_received, tx_power, comments, name); + m_messageClient->qso_logged (QSO_date_off, call, grid, dial_freq, mode, rpt_sent, rpt_received, tx_power, comments, name, QSO_date_on); if (m_config.clear_DX ()) { @@ -4645,6 +4761,7 @@ void MainWindow::on_pbCallCQ_clicked() m_ntx=7; ui->rbGenMsg->setChecked(true); if(m_transmitting) m_restart=true; + set_dateTimeQSO(-1); } void MainWindow::on_pbAnswerCaller_clicked() @@ -4658,6 +4775,7 @@ void MainWindow::on_pbAnswerCaller_clicked() m_ntx=7; ui->rbGenMsg->setChecked(true); if(m_transmitting) m_restart=true; + set_dateTimeQSO(2); } void MainWindow::on_pbSendRRR_clicked() @@ -4689,6 +4807,7 @@ void MainWindow::on_pbSendReport_clicked() m_ntx=7; ui->rbGenMsg->setChecked(true); if(m_transmitting) m_restart=true; + set_dateTimeQSO(3); } void MainWindow::on_pbSend73_clicked() diff --git a/mainwindow.h b/mainwindow.h index 6eba4c228..b807eb7a3 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -148,7 +148,11 @@ private slots: void on_EraseButton_clicked(); void on_txb1_clicked(); void on_txFirstCheckBox_stateChanged(int arg1); + void set_dateTimeQSO(int m_ntx); void set_ntx(int n); + void on_txrb1_toggled(bool status); + void on_txrb2_toggled(bool status); + void on_txrb3_toggled(bool status); void on_txb2_clicked(); void on_txb3_clicked(); void on_txb4_clicked(); @@ -196,7 +200,7 @@ private slots: , Frequency dial_freq, QString const& mode , QString const& rpt_sent, QString const& rpt_received , QString const& tx_power, QString const& comments - , QString const& name); + , QString const& name, QDateTime const&); void on_bandComboBox_currentIndexChanged (int index); void on_bandComboBox_activated (int index); void on_readFreq_clicked(); @@ -239,6 +243,7 @@ private slots: void on_actionEcho_triggered(); void on_actionISCAT_triggered(); void on_actionFast_Graph_triggered(); + void on_actionHide_Controls_triggered(); void fast_decode_done(); void on_actionSave_reference_spectrum_triggered(); void on_actionClear_reference_spectrum_triggered(); @@ -422,6 +427,7 @@ private: bool m_bNoMoreFiles; bool m_bQRAsyncWarned; bool m_bDoubleClicked; + bool m_bHideControls; float m_pctZap; int m_ihsym; @@ -495,7 +501,9 @@ private: QSet m_pfx; QSet m_sfx; - QDateTime m_dateTimeQSO; + QDateTime m_dateTimeQSOOn; + QDateTime m_dateTimeQSOOff; + QDateTime m_dateTimeDefault; QSharedMemory *mem_jt9; LogBook m_logBook; @@ -523,7 +531,7 @@ private: DisplayManual m_manual; QHash m_pwrBandTxMemory; // Remembers power level by band QHash m_pwrBandTuneMemory; // Remembers power level by band for tuning - + QByteArray m_geometryNoControls; //---------------------------------------------------- private functions void readSettings(); void setDecodedTextFont (QFont const&); diff --git a/mainwindow.ui b/mainwindow.ui index 4f6521fe0..e3a0f3a64 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -2357,6 +2357,8 @@ QPushButton[state="ok"] { + + @@ -2899,6 +2901,17 @@ QPushButton[state="ok"] { Clear reference spectrum + + + Hide menus and labels + + + Reduces window size by removing controls and some spacing + + + Ctrl+M + + diff --git a/shortcuts.txt b/shortcuts.txt index 504094c78..7ddd71740 100644 --- a/shortcuts.txt +++ b/shortcuts.txt @@ -22,6 +22,7 @@ Alt+H Halt Tx Ctrl+L Lookup callsign in database, generate standard messages Alt+M Monitor + Ctrl+M Minimize window size by hiding some controls Alt+N Enable Tx Ctrl+O Open a .wav file Alt+Q Log QSO diff --git a/widegraph.cpp b/widegraph.cpp index 0c5d50c79..513cb856f 100644 --- a/widegraph.cpp +++ b/widegraph.cpp @@ -6,6 +6,7 @@ #include "Configuration.hpp" #include "MessageBox.hpp" #include "moc_widegraph.cpp" +#include "SettingsGroup.hpp" namespace { @@ -82,6 +83,9 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) : int m_fMin = m_settings->value ("Fmin", 2500).toInt (); ui->fSplitSpinBox->setValue (m_fMin); setRxRange (m_fMin); + m_bHideControls = m_settings->value("HideControls", false).toBool (); + m_bHideControls = !m_bHideControls; // we're not toggling here so we start in opposite state + on_hideControls(); m_settings->endGroup(); saveSettings (); // update config with defaults @@ -112,6 +116,57 @@ void WideGraph::closeEvent (QCloseEvent * e) QDialog::closeEvent (e); } +void WideGraph::on_hideControls() +{ + m_bHideControls = !m_bHideControls; + ui->verticalLayout->setEnabled(!m_bHideControls); + ui->gridLayout->setEnabled(!m_bHideControls); + ui->horizontalLayout->setEnabled(!m_bHideControls); + ui->horizontalLayout_2->setEnabled(!m_bHideControls); + ui->horizontalLayout_3->setEnabled(!m_bHideControls); + if (!m_bHideControls) { + ui->adjust_palette_push_button->show(); + ui->labPalette->show(); + ui->smoSpinBox->show(); + ui->cbFlatten->show(); + ui->cbRef->show(); + ui->bppSpinBox->show(); + ui->fSplitSpinBox->show(); + ui->fStartSpinBox->show(); + ui->gain2dSlider->show(); + ui->gainSlider->show(); + ui->line->show(); + ui->line_2->show(); + ui->paletteComboBox->show(); + ui->sbPercent2dPlot->show(); + ui->spec2dComboBox->show(); + ui->waterfallAvgSpinBox->show(); + ui->zero2dSlider->show(); + ui->zeroSlider->show(); + } + else { + ui->adjust_palette_push_button->hide(); + ui->labPalette->hide(); + ui->smoSpinBox->hide(); + ui->cbFlatten->hide(); + ui->cbRef->hide(); + ui->bppSpinBox->hide(); + ui->fSplitSpinBox->hide(); + ui->fStartSpinBox->hide(); + ui->gain2dSlider->hide(); + ui->gainSlider->hide(); + ui->line->hide(); + ui->line_2->hide(); + ui->paletteComboBox->hide(); + ui->sbPercent2dPlot->hide(); + ui->spec2dComboBox->hide(); + ui->waterfallAvgSpinBox->hide(); + ui->zero2dSlider->hide(); + ui->zeroSlider->hide(); + ui->widePlot->adjustSize(); + } +} + void WideGraph::saveSettings() //saveSettings { m_settings->beginGroup ("WideGraph"); @@ -136,6 +191,7 @@ void WideGraph::saveSettings() //saveS m_settings->setValue ("Fmin", m_fMin); m_settings->setValue("Flatten",m_bFlatten); m_settings->setValue("UseRef",m_bRef); + m_settings->setValue("HideControls",m_bHideControls); m_settings->endGroup (); } @@ -217,6 +273,11 @@ void WideGraph::keyPressEvent(QKeyEvent *e) //F1 if(e->modifiers() & Qt::ControlModifier) n+=100; emit f11f12(n); break; + case Qt::Key_M: + if(e->modifiers() & Qt::ControlModifier) { + on_hideControls(); + } + break; default: QDialog::keyPressEvent (e); } diff --git a/widegraph.h b/widegraph.h index 36ce6014b..3e15d14b9 100644 --- a/widegraph.h +++ b/widegraph.h @@ -80,6 +80,7 @@ private slots: void on_zero2dSlider_valueChanged(int value); void on_smoSpinBox_valueChanged(int n); void on_sbPercent2dPlot_valueChanged(int n); + void on_hideControls(); private: void readPalette(); @@ -104,7 +105,7 @@ private: bool m_bFlatten; bool m_bRef; bool m_bHaveTransmitted; //Set true at end of a WSPR transmission - + bool m_bHideControls; QString m_mode; QString m_modeTx; QString m_waterfallPalette;