When clean-before-build is off, rebuilding only takes a few 10's of
seconds. Just impatient, I guess.
I used a hidden 'dynamic grid' variable that is set from the UDP message,
but is only used if the checkbox is selected.
For the MessageAggregator test bed for it, the grid field is implemented
similarly to the free text entry -- when editing is deemed 'finished', the
message to change the grid is sent.
Attached is a diff.
On Sat, Feb 3, 2018 at 3:31 PM, Bill Somerville <g4...@classdesign.com>
wrote:
> Hi Brian,
>
> some comments in line below.
>
> On 03/02/2018 21:30, Brian Moran wrote:
>
>> I'll have to take my 1.8.0 diff and get it fixed up for the dev branch.
>>
> I can't help much with that, in theory you can simply switch your svn
> workspace to the development branch and it will merge your changes but YMMV.
>
>>
>> There's one slight UI suggested change, and that is in the configuration
>> UI, an 'autogrid' (didn't think about this name much, it popped in while
>> working on it) checkbox next to the grid entry field in the dialog that
>> will allow updates via UDP.
>>
> I'm not certain that is really necessary but add it if you feel so
> inclined.
>
>>
>> The operation is as follows:
>> The grid is configured in the configuration dialog as normal. At startup
>> of wsjtx, *or when autogrid checkbox is turned off* the grid in the
>> configuration dialog is used.
>> If the 'autogrid' checkbox is checked, then the grid *can* be changed by
>> a valid grid being received by wsjt-x. This change will *not* be saved at
>> program end.
>>
> Ok, that is consistent with an excursion across grids and the default of
> returning "home" on a restart makes sense. I'm not sure how you intend to
> implement that, I suppose all references to Configuration::my_grid() will
> need replacing or are you using a temporary grid cache in he Configuration
> class instance. Either way, how will that interact with normal usage of the
> settings dialog?
>
>>
>> Regarding the python server stuff, yes, I listen for the heartbeat packet
>> before trying to listen for status packets and examining the currently
>> configured grid. I only have unicast support in my current implementation.
>> In a multicast scenario where there were more than one wsjt-x instance, it
>> might be hard to divine the geographic topology of the instances, so that
>> exercise would be left to the reader.
>>
> Multicast and multiple instances of WSJT-X are unrelated issues. Multicast
> UDP only comes into play when there are multiple servers, e.g. your
> application and JTAlert (with the caveat that JTAlert is a bad example as
> it doesn't do multicast UDP).
>
>>
>> I'll go look at the message aggregator -- I originally got it tested with
>> UDP_daemon, but the edit-compile-feedback loop is a bit long on my i5
>> machine, so wrote a little python library so my turnaround would be quicker.
>>
> I am happy to help with message_aggregator, it is somewhat more complex as
> it has a UI and exercise all UDP capabilities.
>
> You should not be having and edit-compile-test loop time issues on
> something as powerful as a Core i5 CPU. I suspect you are using the JTSDK
> and have not turn off the, developer unfriendly, option to do a make clean
> every build.
>
>>
>> I've thought about the 'inconvenient grid changing' occuring during a QSO
>> (and inadvertently tested that a few times myself):
>> - Someone could change the grid in the configuration dialog at any time
>> already
>> - The grid is only used in tx1 and tx6
>>
> Entering the settings dialog and changing something should be disabling
> "Enable Tx" so going into settings during a QSO should be effectively
> quitting the QSO. I am not 100% sure that is always correctly implemented
> but it is the intention. I would recommend a grid change being in line with
> that intent.
>
>>
>> I think the impact of changing a grid during a QSO is minimal, and the
>> grid that is handed out is the one that was reflective of the beginning of
>> the QSO.
>>
> Thinking about it I think that is simple and effective.
>
>>
>> On grid change detected, one could configure the grid server program to
>> ALSO set the Free Text message (TX5) to be something like "73 <CALL>
>> <GRID>" ) to inform subsequent callers of a grid change if they have a
>> five-character-or-fewer-in-length callsign to stay under the 13
>> character limit of the free text message. The downside is the autoseq
>> detection mechanism would not recognize the 73 message in that case.
>>
> Any message with the word "73" should be processed identically to a
> standard format "dx-call de-call 73" message. I would suggest simply
> calling CQ or QRZ with a new grid is sufficient, I can't imagine a station
> moving across a grid boundary is too concerned about an extra 30 seconds
> (in FT8 mode) to announce anew location using existing standard messages.
>
>>
>> The next CQ would send the new grid. Enhancement: Perhaps TX1 gets a
>> color change until CQ is sent again, which hopefully would draw the
>> attention of the operator.
>>
> I'm not sure what a colour change helps with or which end of the QSO shows
> it?
>
>>
>> For the IGC purposes, I would make sense to be the case that the own-grid
>> squares of each station are used if provided (since they don't need to be
>> in a QSO as part of the IGC rules), but I've not tested that.
>>
>>
>> One thing that must be solid is that the roving station must record their
> own grid correctly with each QSO, this is where the behaviour of grid
> change part way through a QSO will cause issues. Keeping it simple, the
> operator must at least push the "Log QSO" button after competing a QSO and
> before moving on.
>
>
> 73
> Bill
> G4WJS.
>
>
> ------------------------------------------------------------
> ------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> wsjt-devel mailing list
> wsjt-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/wsjt-devel
>
Index: Configuration.cpp
===================================================================
--- Configuration.cpp (revision 8453)
+++ Configuration.cpp (working copy)
@@ -524,6 +524,7 @@
CalibrationParams calibration_;
bool frequency_calibration_disabled_; // not persistent
unsigned transceiver_command_number_;
+ QString dynamic_grid_;
// configuration fields that we publish
QString my_callsign_;
@@ -569,6 +570,7 @@
bool bHound_;
bool x2ToneSpacing_;
bool x4ToneSpacing_;
+ bool use_dynamic_grid_;
QString opCall_;
QString udp_server_name_;
port_type udp_server_port_;
@@ -627,7 +629,6 @@
bool Configuration::restart_audio_output () const {return
m_->restart_sound_output_device_;}
auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return
m_->type_2_msg_gen_;}
QString Configuration::my_callsign () const {return m_->my_callsign_;}
-QString Configuration::my_grid () const {return m_->my_grid_;}
QColor Configuration::color_CQ () const {return m_->color_CQ_;}
QColor Configuration::color_MyCall () const {return m_->color_MyCall_;}
QColor Configuration::color_TxMsg () const {return m_->color_TxMsg_;}
@@ -797,6 +798,22 @@
return(!(server_name.trimmed().isEmpty() || port_number == 0));
}
+QString Configuration::my_grid() const
+{
+ auto the_grid = m_->my_grid_;
+ if (!(m_->dynamic_grid_.trimmed().isEmpty()) && m_->use_dynamic_grid_) {
+ the_grid = m_->dynamic_grid_;
+ }
+ return the_grid;
+}
+
+void Configuration::set_location (QString const& grid_descriptor)
+{
+ // change the dynamic grid
+ qDebug () << "Configuration::set_location - location:" << grid_descriptor;
+ m_->dynamic_grid_ = grid_descriptor;
+}
+
namespace
{
#if defined (Q_OS_MAC)
@@ -1102,6 +1119,7 @@
ui_->grid_line_edit->setPalette (pal);
ui_->callsign_line_edit->setText (my_callsign_);
ui_->grid_line_edit->setText (my_grid_);
+ ui_->use_dynamic_grid->setChecked(use_dynamic_grid_);
ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name()));
ui_->labMyCall->setStyleSheet(QString("background:
%1").arg(color_MyCall_.name()));
ui_->labTx->setStyleSheet(QString("background:
%1").arg(color_TxMsg_.name()));
@@ -1316,6 +1334,7 @@
spot_to_psk_reporter_ = settings_->value ("PSKReporter", false).toBool ();
id_after_73_ = settings_->value ("After73", false).toBool ();
tx_QSY_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
+ use_dynamic_grid_ = settings_->value("AutoGrid", false).toBool ();
macros_.setStringList (settings_->value ("Macros", QStringList {"TNX 73
GL"}).toStringList ());
@@ -1496,6 +1515,7 @@
settings_->setValue ("pwrBandTxMemory", pwrBandTxMemory_);
settings_->setValue ("pwrBandTuneMemory", pwrBandTuneMemory_);
settings_->setValue ("Region", QVariant::fromValue (region_));
+ settings_->setValue ("AutoGrid", use_dynamic_grid_);
}
void Configuration::impl::set_rig_invariants ()
@@ -1931,7 +1951,14 @@
stations_.station_list(next_stations_.station_list ());
stations_.sort (StationList::band_column);
}
-
+
+ if (ui_->use_dynamic_grid->isChecked() && !use_dynamic_grid_ )
+ {
+ // clear it so we get an update
+ dynamic_grid_ = QString();
+ }
+ use_dynamic_grid_ = ui_->use_dynamic_grid->isChecked();
+
write_settings (); // make visible to all
}
Index: Configuration.hpp
===================================================================
--- Configuration.hpp (revision 8453)
+++ Configuration.hpp (working copy)
@@ -192,6 +192,9 @@
// Set the calibration parameters and enable calibration corrections.
void set_calibration (CalibrationParams);
+ // Set the dynamic grid which is only used if configuration setting is
enabled.
+ void set_location (QString const&);
+
// This method queries if a CAT and PTT connection is operational.
bool is_transceiver_online () const;
@@ -273,6 +276,9 @@
// the fault condition has been rectified or is transient.
Q_SIGNAL void transceiver_failure (QString const& reason) const;
+ // Grid was changed from an external program
+ Q_SIGNAL void grid_changed(QString const& grid) const;
+
private:
class impl;
pimpl<impl> m_;
Index: Configuration.ui
===================================================================
--- Configuration.ui (revision 8453)
+++ Configuration.ui (working copy)
@@ -81,10 +81,21 @@
</layout>
</item>
<item>
+ <layout class="QFormLayout" name="formLayout_21">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="use_dynamic_grid">
+ <property name="toolTip">
+ <string>Check to allow grid changes from external
programs</string>
+ </property>
+ <property name="text">
+ <string>AutoGrid</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
<layout class="QFormLayout" name="formLayout_2">
- <item row="0" column="1">
- <widget class="QComboBox" name="region_combo_box"/>
- </item>
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
@@ -95,6 +106,9 @@
</property>
</widget>
</item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="region_combo_box"/>
+ </item>
</layout>
</item>
</layout>
@@ -2599,6 +2613,7 @@
<tabstop>configuration_tabs</tabstop>
<tabstop>callsign_line_edit</tabstop>
<tabstop>grid_line_edit</tabstop>
+ <tabstop>use_dynamic_grid</tabstop>
<tabstop>region_combo_box</tabstop>
<tabstop>type_2_msg_gen_combo_box</tabstop>
<tabstop>insert_blank_check_box</tabstop>
Index: MessageClient.cpp
===================================================================
--- MessageClient.cpp (revision 8453)
+++ MessageClient.cpp (working copy)
@@ -207,6 +207,17 @@
}
break;
+ case NetworkMessage::LocationChange:
+ {
+ QByteArray location;
+ in >> location;
+ if (check_status (in) != Fail)
+ {
+ Q_EMIT self_->location_change (QString::fromUtf8
(location));
+ }
+ }
+ break;
+
default:
// Ignore
//
Index: MessageClient.hpp
===================================================================
--- MessageClient.hpp (revision 8453)
+++ MessageClient.hpp (working copy)
@@ -94,6 +94,10 @@
// lookup fails
Q_SIGNAL void error (QString const&) const;
+ // this signal is emitted if the obtains a new location from a server.
+ // (It doesn't have to be new, could be a periodic location update)
+ Q_SIGNAL void location_change (QString const&);
+
private:
class impl;
pimpl<impl> m_;
Index: MessageServer.cpp
===================================================================
--- MessageServer.cpp (revision 8453)
+++ MessageServer.cpp (working copy)
@@ -453,3 +453,15 @@
m_->send_message (out, message, iter.value ().sender_address_,
(*iter).sender_port_);
}
}
+
+void MessageServer::location_change (QString const& id, QString const&
location)
+{
+ auto iter = m_->clients_.find (id);
+ if (iter != std::end (m_->clients_))
+ {
+ QByteArray message;
+ NetworkMessage::Builder out {&message, NetworkMessage::LocationChange, id,
(*iter).negotiated_schema_number_};
+ out << location.toUtf8 ();
+ m_->send_message (out, message, iter.value ().sender_address_,
(*iter).sender_port_);
+ }
+}
\ No newline at end of file
Index: MessageServer.hpp
===================================================================
--- MessageServer.hpp (revision 8453)
+++ MessageServer.hpp (working copy)
@@ -59,6 +59,9 @@
// message and optionally send it ASAP
Q_SLOT void free_text (QString const& id, QString const& text, bool send);
+ // ask the client with identification 'id' to set the grid based on the
location
+ Q_SLOT void location_change (QString const& id, QString const& location);
+
// the following signals are emitted when a client broadcasts the
// matching message
Q_SIGNAL void client_opened (QString const& id, QString const& version,
QString const& revision);
Index: NetworkMessage.hpp
===================================================================
--- NetworkMessage.hpp (revision 8453)
+++ NetworkMessage.hpp (working copy)
@@ -353,6 +353,7 @@
HaltTx,
FreeText,
WSPRDecode,
+ LocationChange,
maximum_message_type_ // ONLY add new message types
// immediately before here
};
Index: UDPExamples/ClientWidget.cpp
===================================================================
--- UDPExamples/ClientWidget.cpp (revision 8453)
+++ UDPExamples/ClientWidget.cpp (working copy)
@@ -131,6 +131,7 @@
, tx_df_label_ {new QLabel}
, report_label_ {new QLabel}
, columns_resized_ {false}
+ , grid_line_edit_ {new QLineEdit}
{
// set up widgets
decodes_proxy_model_.setSourceModel (decodes_model);
@@ -141,6 +142,7 @@
auto form_layout = new QFormLayout;
form_layout->addRow (tr ("Free text:"), message_line_edit_);
+ form_layout->addRow (tr ("New grid:"), grid_line_edit_);
message_line_edit_->setValidator (new QRegExpValidator {message_alphabet,
this});
connect (message_line_edit_, &QLineEdit::textEdited, [this] (QString const&
text) {
Q_EMIT do_free_text (id_, text, false);
@@ -149,6 +151,14 @@
Q_EMIT do_free_text (id_, message_line_edit_->text (), true);
});
+ //connect (grid_line_edit_, &QLineEdit::textEdited, [this] (QString const&
text) {
+ // Q_EMIT location_change (id_, text, false);
+ //});
+
+ connect (grid_line_edit_, &QLineEdit::editingFinished, [this] () {
+ Q_EMIT location_change (id_, grid_line_edit_->text ());
+ });
+
auto decodes_page = new QWidget;
auto decodes_layout = new QVBoxLayout {decodes_page};
decodes_layout->setContentsMargins (QMargins {2, 2, 2, 2});
Index: UDPExamples/ClientWidget.hpp
===================================================================
--- UDPExamples/ClientWidget.hpp (revision 8453)
+++ UDPExamples/ClientWidget.hpp (working copy)
@@ -43,6 +43,7 @@
Q_SIGNAL void do_reply (QModelIndex const&, quint8 modifier);
Q_SIGNAL void do_halt_tx (QString const& id, bool auto_only);
Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool);
+ Q_SIGNAL void location_change(QString const &id, QString const &text);
private:
QString id_;
@@ -69,6 +70,7 @@
QTableView * decodes_table_view_;
QTableView * beacons_table_view_;
QLineEdit * message_line_edit_;
+ QLineEdit * grid_line_edit_;
QStackedLayout * decodes_stack_;
QAbstractButton * auto_off_button_;
QAbstractButton * halt_tx_button_;
Index: UDPExamples/MessageAggregatorMainWindow.cpp
===================================================================
--- UDPExamples/MessageAggregatorMainWindow.cpp (revision 8453)
+++ UDPExamples/MessageAggregatorMainWindow.cpp (working copy)
@@ -149,6 +149,7 @@
connect (dock, &ClientWidget::do_reply, decodes_model_,
&DecodesModel::do_reply);
connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx);
connect (dock, &ClientWidget::do_free_text, server_,
&MessageServer::free_text);
+ connect (dock, &ClientWidget::location_change, server_,
&MessageServer::location_change);
connect (view_action, &QAction::toggled, dock, &ClientWidget::setVisible);
dock_widgets_[id] = dock;
server_->replay (id);
Index: mainwindow.cpp
===================================================================
--- mainwindow.cpp (revision 8453)
+++ mainwindow.cpp (working copy)
@@ -452,6 +452,7 @@
// Network message handlers
connect (m_messageClient, &MessageClient::reply, this,
&MainWindow::replyToCQ);
connect (m_messageClient, &MessageClient::replay, this,
&MainWindow::replayDecodes);
+ connect (m_messageClient, &MessageClient::location_change, this,
&MainWindow::locationChange);
connect (m_messageClient, &MessageClient::halt_tx, [this] (bool auto_only) {
if (m_config.accept_udp_requests ()) {
if (auto_only) {
@@ -6522,6 +6523,36 @@
}
}
+void MainWindow::locationChange(QString const& location) {
+ MaidenheadLocatorValidator::State st =
MaidenheadLocatorValidator::State::Invalid;
+ int len;
+ QString the_grid = QString();
+
+ MaidenheadLocatorValidator *v = new MaidenheadLocatorValidator();
+
+ auto trimmed_location = location.trimmed();
+ // string 6 chars or fewer, interpret as a grid, or use with a 'GRID:' prefix
+ if (trimmed_location.size() <= 6) {
+ the_grid = trimmed_location;
+ } else {
+ if (trimmed_location.toUpper().left(5) == "GRID:") {
+ the_grid = trimmed_location.mid(5).trimmed();
+ } else
+ {
+ // TODO - support any other formats, e.g. latlong? Or have that
conversion done external to wsjtx
+ return;
+ }
+ }
+ st = v->validate((QString &)the_grid, len);
+ if (st == MaidenheadLocatorValidator::State::Acceptable) {
+ qDebug() << "locationChange: Grid supplied is " << the_grid;
+ m_config.set_location(the_grid);
+ genStdMsgs(m_rpt, false);
+ } else {
+ qDebug() << "locationChange: Invalid grid " << the_grid;
+ }
+}
+
void MainWindow::replayDecodes ()
{
// we accept this request even if the setting to accept UDP requests
Index: mainwindow.h
===================================================================
--- mainwindow.h (revision 8453)
+++ mainwindow.h (working copy)
@@ -645,6 +645,7 @@
void transmitDisplay (bool);
void processMessage(DecodedText const&, Qt::KeyboardModifiers = 0);
void replyToCQ (QTime, qint32 snr, float delta_time, quint32
delta_frequency, QString const& mode, QString const& message_text, bool
low_confidence, quint8 modifiers);
+ void locationChange(QString const& location);
void replayDecodes ();
void postDecode (bool is_new, QString const& message);
void postWSPRDecode (bool is_new, QStringList message_parts);
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
wsjt-devel mailing list
wsjt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wsjt-devel