Compare commits

..

184 Commits

Author SHA1 Message Date
Jordan Sherer 4406e99670 Added MFSK/JS8 for logging modes 2018-11-30 17:02:14 -05:00
Jordan Sherer 79785dbef5 Fixed bug in HB auto-reply when HB was not active 2018-11-30 10:05:47 -05:00
Jordan Sherer 1d1bc254a4 Don't turn off the repeat buttons on stop button clicked, just reset them 2018-11-30 09:09:54 -05:00
Jordan Sherer 4ddccd99a1 Added a compatiblity display for old heartbeat acks 2018-11-29 22:53:56 -05:00
Jordan Sherer dd6f50a5a3 Bump version and EOL 2018-11-29 22:51:19 -05:00
Jordan Sherer 55c365b834 Added heartbeat and CQ to control menu 2018-11-29 22:43:15 -05:00
Jordan Sherer b55f8ba5c5 Added option for displaying/hiding heartbeats and acks 2018-11-29 22:34:39 -05:00
Jordan Sherer fd77e5440f Keep configuration option for heartbeat channelization 2018-11-29 22:19:17 -05:00
Jordan Sherer 19cb0b859d SELCALL checked should disable repeat transmissions 2018-11-29 21:53:03 -05:00
Jordan Sherer 3d3be02830 Countdown for HB and CQ. Escape key stops CQ and resets HB timer 2018-11-28 22:53:18 -05:00
Jordan Sherer 55f04d3cd7 Fixed padding of configuration behavior panel 2018-11-28 16:42:09 -05:00
Jordan Sherer 693eec8b4b Rename do not repeat 2018-11-27 23:25:40 -05:00
Jordan Sherer 9244ac08c6 Hide heartbeat and acks if we have HB turned off 2018-11-27 23:21:16 -05:00
Jordan Sherer 8004c51ed2 Hide configuration for heartbeat. 2018-11-27 23:16:02 -05:00
Jordan Sherer 52b67a5609 HB and CQ repeat logic 2018-11-27 23:04:11 -05:00
Jordan Sherer 3e7c64e994 Proper active/inactive flags for HB 2018-11-26 22:40:34 -05:00
Jordan Sherer d9d3e6fba3 Added active/inactive flag and restructuring heartbeat 2018-11-25 22:12:54 -05:00
Jordan Sherer 09cea086c7 Added fullscreen toggle 2018-11-22 10:37:38 -05:00
Jordan Sherer a013e79eff Reordering varicode commands to make it easier to spot which numbers are available 2018-11-20 10:09:07 -05:00
Jordan Sherer a3e004375e Added deselect callsign after logging as an option instead of forced 2018-11-20 09:50:53 -05:00
Jordan Sherer f018a622ce Removed printing of ALLCALL messages that were not freetext in the RX window 2018-11-19 23:02:59 -05:00
Jordan Sherer 565c031b28 Added add/remove group from callsign list and it propagate to the settings 2018-11-19 22:36:28 -05:00
Jordan Sherer d88d8aa440 Removed clear menu item icons 2018-11-19 22:36:10 -05:00
Jordan Sherer 3a59599253 Fix SELCALL and HB menu items toggle vs click 2018-11-16 15:36:02 -05:00
Jordan Sherer 22e4b0891e Bump eol 2018-11-15 22:09:03 -05:00
Jordan Sherer 8c564b6637 Added control menu 2018-11-15 22:06:52 -05:00
Jordan Sherer 97763ed82d Bump to 0.9 2018-11-15 21:57:20 -05:00
Jordan Sherer a7849c5b72 Added push button bold style for colorblindness 2018-11-15 21:57:04 -05:00
Jordan Sherer 04394273dd Added notification for CQ messages 2018-11-15 15:03:05 -05:00
Jordan Sherer 1052dd3f9f Added macro expansion in typed message text 2018-11-14 22:48:31 -05:00
Jordan Sherer 78ed799a8b Updated configuration panel to be more flexible (scroll areas) 2018-11-14 22:03:45 -05:00
Jordan Sherer c0d08f87b6 Added keyboard shortcuts to the basic Show actions. Added show action to disable tooltips 2018-11-13 12:35:39 -05:00
Jordan Sherer f92b3db5ea Added ability to add an arbitrary station to the heard list manually 2018-11-12 16:51:51 -05:00
Jordan Sherer cebed44ccd User Interface Tweaks:
* Changed Window Menu to View Menu
* Added Show Clock to View Menu
* Changed minimum sizing for better fit on smaller screens
* Reordered Clock and Date for Clock Priority
2018-11-12 16:34:31 -05:00
Jordan Sherer d47d88681b Updated dependencies list 2018-11-11 15:06:45 -05:00
Jordan Sherer 1be0ee4f4f Added a reference to dependency installation 2018-11-11 14:58:23 -05:00
Jordan Sherer 43d8986e0a Tweaking window sizes 2018-11-08 17:11:25 -05:00
Jordan Sherer fd69dce0ae Fixed word wrapping of non-breaking space words by only replacing double spaces 2018-11-06 23:06:05 -05:00
Jordan Sherer b2fb3f31ac Added azimuth to the distance column 2018-11-06 17:28:21 -05:00
Jordan Sherer db704858e2 Merge branch 'ft8call-develop' of bitbucket.org:widefido/js8call into ft8call-develop 2018-11-05 21:36:13 -05:00
Jordan Sherer 1d11f0f8ba Fixed word wrapping with no break spaces 2018-11-05 21:13:16 -05:00
Jordan Sherer b6bc50a8e1 Fixed QAction for older Qt versions 2018-11-05 17:00:59 -05:00
Jordan Sherer 5addf8f61f Fixed bug with space collapsing in displayTextForFreq 2018-11-05 16:51:24 -05:00
Jordan Sherer 367966f5e6 Bump to v0.8.3 2018-11-05 16:47:09 -05:00
Jordan Sherer caaaa957b6 Fixed OSX issue with menuBar menus that have sub-menues that aren't populated at construction, but when the menu is aboutToShow 2018-11-05 16:00:12 -05:00
Jordan Sherer c440d4c143 Added TDELTA macro variable 2018-11-05 11:35:37 -05:00
Jordan Sherer 740c0b4c04 Fixed call activity with empty rows 2018-11-04 14:57:44 -05:00
Jordan Sherer f5ce9f0e30 Added TU short command 2018-11-03 22:38:27 -04:00
Jordan Sherer 0a6ec136f9 Fixed macro expansion for auto-reply messages QTC and QTH 2018-11-03 22:20:49 -04:00
Jordan Sherer d5e1f2822d Fixed more issues with compressed data decoding and invalid frames 2018-11-03 22:14:42 -04:00
Jordan Sherer 3fffb45338 Bump to v0.8.2 2018-11-03 02:13:19 -04:00
Jordan Sherer 1d255b1ebf Fixed time delta labeling 2018-11-03 02:06:20 -04:00
Jordan Sherer bb97799bdf Added checkmark to column header for worked before status 2018-11-03 02:01:01 -04:00
Jordan Sherer cc6a719f6d Added default column show settings 2018-11-03 01:59:21 -04:00
Jordan Sherer ccd380356a Fixed log cache issue by reloading log after qso or erase 2018-11-03 01:47:54 -04:00
Jordan Sherer 9f8583c8e2 Fixed reply queuing when text is typed in the reply textbox 2018-11-03 01:31:24 -04:00
Jordan Sherer c9016d7378 Fixed issue with false decodes causing app crash 2018-11-03 01:14:31 -04:00
Jordan Sherer cd683f9bf7 Added back foxcom waveform to the modulator 2018-11-01 22:14:57 -04:00
Jordan Sherer 6d7b187269 Fixed table column swap for snr and offset 2018-11-01 00:50:39 -04:00
Jordan Sherer 13308a38f8 Fixed sync for non APPLE 2018-11-01 00:44:14 -04:00
Jordan Sherer 804605e9e6 Fixed text count for APPLE 2018-11-01 00:41:15 -04:00
Jordan Sherer 4e981da9c8 Fixed send button initial frame count. Fixed apple specific text counting 2018-11-01 00:37:29 -04:00
Jordan Sherer 6436e163bd Fixed QSO log not uppercase callsign 2018-11-01 00:20:20 -04:00
Jordan Sherer 379a0fa78f Fixed bug with auto-replies using selected callsign as the directed callsign 2018-11-01 00:06:09 -04:00
Jordan Sherer 1c4a2ab7d8 Fix bug with fort.19 2018-11-01 00:05:41 -04:00
Jordan Sherer 54f6bdb0af Bump to v0.8.1 2018-10-31 22:13:26 -04:00
Jordan Sherer 5a0e2a8b14 Fixed time delta average reset on activity clear 2018-10-31 22:10:04 -04:00
Jordan Sherer 1a9c611195 Fixed issue with tdrift average when reset 2018-10-31 22:09:03 -04:00
Jordan Sherer c70661461e Fixed selcall button should prevent heartbeat acks 2018-10-31 21:52:58 -04:00
Jordan Sherer 1f866e14f1 Hotfix. Fixed heartbear idle min value should be zero 2018-10-31 21:42:08 -04:00
Jordan Sherer c0e8a791e6 Hotfix. Broken heartbeat ack when a directed callsign is selected 2018-10-31 18:17:34 -04:00
Jordan Sherer 74523985bb Time drift button labeling 2018-10-31 11:58:11 -04:00
Jordan Sherer 8d28ea345a 0.8 is not backwards compatible 2018-10-31 11:56:12 -04:00
Jordan Sherer 33446297fa Update heartbeat to allow on demand only. Add AUTO requirement for ACKs 2018-10-31 10:51:17 -04:00
Jordan Sherer 6f648d5a60 Added compatibility parsing for commands 2018-10-30 21:00:04 -04:00
Jordan Sherer f1f618bbcd Added worked before status 2018-10-30 20:50:31 -04:00
Jordan Sherer ac7da998a2 15 seconds is not now 2018-10-30 17:04:30 -04:00
Jordan Sherer b3cd705fb6 OCD 2018-10-30 17:00:14 -04:00
Jordan Sherer 604e366d4a Rig name in title 2018-10-29 22:41:54 -04:00
Jordan Sherer 8d73805dce Average time drift labels 2018-10-29 22:34:26 -04:00
Jordan Sherer 5c491dc10d Update threshold and tones. Cleanup bits 2018-10-29 17:56:31 -04:00
Jordan Sherer d611259a25 Fixed typo in varicode 2018-10-29 13:39:15 -04:00
Jordan Sherer 00f2d46167 Reduce late start threshold to 2 seconds 2018-10-29 09:24:52 -04:00
Jordan Sherer e4cba50144 Better labeling 2018-10-29 09:24:38 -04:00
Jordan Sherer 440311a75b Restructured data frame packing so we can send more over the wire in fewer frames 2018-10-29 03:26:10 -04:00
Jordan Sherer 38fc98702b Average time delta computation 2018-10-29 02:02:58 -04:00
Jordan Sherer 6201de8c12 Tweak decoder for better decodes under poor conditions 2018-10-29 01:09:17 -04:00
Jordan Sherer 4321bd5e75 Time drift columns and show column labels 2018-10-28 17:54:10 -04:00
Jordan Sherer 9f7fd2e7e2 Replaced character queries with textual queries to make it easier to read 2018-10-28 12:37:47 -04:00
Jordan Sherer 65a2411c46 Better interface for idle timer values 2018-10-28 12:06:37 -04:00
Jordan Sherer d076eedeb8 Fixed idle timer for idle watchdog 2018-10-28 11:24:00 -04:00
Jordan Sherer 7da30200f5 Heartbeat commands instead 2018-10-28 10:06:03 -04:00
Jordan Sherer cac5f798a3 Rename beacon to heartbean with pings and ping acks 2018-10-28 09:52:07 -04:00
Jordan Sherer 41fb7481ed Bump eol 2018-10-28 09:50:16 -04:00
Jordan Sherer 09effda8e4 Added default macro for CQ message 2018-10-27 15:25:23 -04:00
Jordan Sherer eecf7f65c7 Macro for CQ, Reply, QTH, QTC messages 2018-10-27 15:19:49 -04:00
Jordan Sherer 0618b1cc09 Do not allow text overrides for selected calls during parsing 2018-10-27 15:14:54 -04:00
Jordan Sherer 00685b9117 Warning message for stupid messages 2018-10-27 15:01:27 -04:00
Jordan Sherer a5a6c95a44 Added SK short message 2018-10-27 14:54:48 -04:00
Jordan Sherer 8612f2cd32 Hashed messages have a 16-bit checksum instead of a 32-bit checksum 2018-10-27 14:52:11 -04:00
Jordan Sherer 5fa60659f3 Idle minutes should always be incremented 2018-10-27 14:51:11 -04:00
Jordan Sherer 08629019d4 Added macro like functionality for saved messages 2018-10-27 14:41:57 -04:00
Jordan Sherer 7293d1e796 Remove table configuration from context menu 2018-10-27 14:41:40 -04:00
Jordan Sherer aff001ce96 Bump to v0.8.0 2018-10-27 12:42:16 -04:00
Jordan Sherer 31d80a9b1d Updated configuration tooltip and validation 2018-10-27 12:41:30 -04:00
Jordan Sherer 9010fa07c0 Replace ALLCALL with @ALLCALL 2018-10-27 10:13:34 -04:00
Jordan Sherer 121bb0fdb5 Replace GROUPCALL with actual group calls 2018-10-27 10:09:40 -04:00
Jordan Sherer 47a7c06854 Added configuration for groups 2018-10-27 09:54:13 -04:00
Jordan Sherer c4089c0af9 Don't allow compound calls greater than 9 chars 2018-10-27 09:53:57 -04:00
Jordan Sherer 5c28d154ff Added autoprepend back in 2018-10-26 22:16:48 -04:00
Jordan Sherer 6dfd037736 Compound callsigns and group callsigns parse correctly 2018-10-26 22:10:08 -04:00
Jordan Sherer 3767b347d9 Working compound extended callsigns with group identifiers 2018-10-26 22:10:07 -04:00
Jordan Sherer ff12fd2240 Added validation message for callsigns 2018-10-26 22:10:07 -04:00
Jordan Sherer 6a0fea1d0a Experiment trying to extend compound callsigns 2018-10-26 22:10:07 -04:00
Jordan Sherer f11e02c966 Do not delete band activity or call activity rows that are selected 2018-10-26 22:09:38 -04:00
Jordan Sherer 0763ecfe37 Expose transmit delay in configuration 2018-10-23 12:35:09 -04:00
Jordan Sherer 4c3ed5c719 Removed temp txt file 2018-10-23 12:34:29 -04:00
Jordan Sherer 0064176736 Reduce late start to 25% 2018-10-23 02:26:19 -04:00
Jordan Sherer 67386a09c7 Simple buffered directed commands should log immediately 2018-10-23 02:18:03 -04:00
Jordan Sherer 3c81108cc6 Moved relay responses into the main window 2018-10-23 02:06:24 -04:00
Jordan Sherer 71ed0c1f10 Added menu for decode depth. Removed some WSPR. 2018-10-21 15:37:12 -04:00
Jordan Sherer 20a44171e4 Ripped out decoded.txt and houndcallers.txt junk 2018-10-20 09:04:03 -04:00
Jordan Sherer 644633721f Disable stations heard command: 2018-10-19 09:53:51 -04:00
Jordan Sherer 8529ef0982 Fixed allcall and groupcall counts to respect aging 2018-10-18 10:51:53 -04:00
Jordan Sherer 8bba574963 Fixed issue where whitespace broke ACKd messages 2018-10-17 14:36:15 -04:00
Jordan Sherer 80d798d7e3 Fixed APRS passcode warning 2018-10-17 14:31:23 -04:00
Jordan Sherer 23a554220b Fixed APRS passcode warning 2018-10-17 14:30:32 -04:00
Jordan Sherer 7e903349ae Added QTC, QTH, and Saved messages to the 'immediately transmit' setting 2018-10-17 14:23:17 -04:00
Jordan Sherer 55810e63a6 Transmit entry should be JS8 not FT8 2018-10-17 14:17:53 -04:00
Jordan Sherer 9162d851d4 Made some adjustments to the tx cycling...should help those having trouble with their audio interface not working fast enough. 2018-10-17 11:19:27 -04:00
Jordan Sherer 2022908509 Bump to 0.7.5 2018-10-17 09:11:05 -04:00
Jordan Sherer 2e2551519d Added ACTIVE/IDLE query. Fixed CQ start transmission. 2018-10-17 09:08:37 -04:00
Jordan Sherer 18052773f1 Added clarification labels to the configuration 2018-10-17 08:58:54 -04:00
Jordan Sherer 51010e7310 Allow out of period starts toggles 2018-10-16 20:15:04 -04:00
Jordan Sherer a3eaf1cf74 Fixed BEACON ACK printing overwrite 2018-10-16 17:47:38 -04:00
Jordan Sherer c731fa51ce Fixed menu shortkeys 2018-10-16 17:23:12 -04:00
Jordan Sherer a5f59019d3 Remove unused count message frames function 2018-10-16 17:09:19 -04:00
Jordan Sherer 4a87edc4c7 Fixed compound callsigns and directed messages (SNR reports) 2018-10-16 16:11:28 -04:00
Jordan Sherer 2da25c3171 Move around the force update to be more reliable 2018-10-16 09:49:53 -04:00
Jordan Sherer 87a6e10bd6 Added async frame counting 2018-10-15 22:06:31 -04:00
Jordan Sherer cf9c74b99e Fixed issue with multiple beacon acks not displaying in rx window 2018-10-15 12:43:49 -04:00
Jordan Sherer dae50d3a99 Added constants for NEAR thresholds 2018-10-15 12:10:13 -04:00
Jordan Sherer 83268fbdaf Added groupcall and allcall callsign counts 2018-10-15 12:01:28 -04:00
Jordan Sherer 3b2242e258 Fixed display of APRS frames where a space after the colon causes concern 2018-10-15 11:53:54 -04:00
Jordan Sherer c42c3b7ad1 Added lookup cache to the lookup function 2018-10-15 03:03:26 -04:00
Jordan Sherer 9496d5ed81 Deslect callsign on click cq button 2018-10-15 02:41:35 -04:00
Jordan Sherer 83174bc6fa Fixed stations heard ordering (by time) 2018-10-15 02:37:21 -04:00
Jordan Sherer d74850b8e1 Fixed reversed qtc qth macro buttons 2018-10-15 02:30:46 -04:00
Jordan Sherer 2f1dca3c49 Updated comments 2018-10-15 02:29:40 -04:00
Jordan Sherer 4a38778808 Removed single shot timer from gui loop 2018-10-15 02:10:48 -04:00
Jordan Sherer 960b9b14d1 Rip out fox/hound junk 2018-10-15 01:04:57 -04:00
Jordan Sherer 9e93745587 Instrumentation and pull ui update async 2018-10-15 00:59:38 -04:00
Jordan Sherer 8aa28108ea Fixed font dialog for OSX 2018-10-11 10:49:48 -04:00
Jordan Sherer 4168e1937c Fixed beacon scheduling with a beacon now context menu item 2018-10-11 01:11:48 -04:00
Jordan Sherer f4b640df75 Fixed incremental directed decode for compound calls 2018-10-11 01:01:38 -04:00
Jordan Sherer cf1cece11c Added log button back in. Moved halt button up to balance. Added pressed state 2018-10-11 00:21:34 -04:00
Jordan Sherer 59893f6dfa Fixed label for relay dialog message notifications 2018-10-11 00:16:07 -04:00
Jordan Sherer ead5c225b5 Fixed separator for restore previous message action 2018-10-11 00:15:52 -04:00
Jordan Sherer 4744952a1a Fixed issue with button and text display in the gui event loop 2018-10-10 17:43:11 -04:00
Jordan Sherer a30bff5589 Bump to 0.7.3 2018-10-10 16:01:54 -04:00
Jordan Sherer e7e2f8357f Fixed idle timer alert 2018-10-10 15:36:53 -04:00
Jordan Sherer 4ffa82f695 Fixed default idle timer 2018-10-10 15:29:48 -04:00
Jordan Sherer 3e38067561 Fixed incremental directed message receipt for ALLCALL and GROUPCALL 2018-10-10 13:35:52 -04:00
Jordan Sherer 52177a0513 Fixed parsing of commands to not split up command words 2018-10-10 10:10:30 -04:00
Jordan Sherer f79ca47a93 Fixed incremental print for directed messages.
Fixed compound calls in the heard list
2018-10-10 09:04:56 -04:00
Jordan Sherer f0e30dc7b0 Fixed compound calls / beacon / cq differentiation 2018-10-09 20:09:53 -04:00
Jordan Sherer d20fe46447 Fixed tx first dependence on checkbox and potential delay caused by event processing 2018-10-09 17:44:36 -04:00
Jordan Sherer aa2c41f124 Initial tx cycle cleanup 2018-10-09 17:33:30 -04:00
Jordan Sherer ad563c0aed LDPC codeword update 2018-10-09 15:36:50 -04:00
Jordan Sherer 60b58fb50f Fixed display of beacons and beacon acks when not beaconining 2018-10-09 15:26:13 -04:00
Jordan Sherer ca79a450ca Fixed beacon queue reset on beacon toggle 2018-10-09 15:03:30 -04:00
Jordan Sherer 3c8c80a5d7 Fixed side-effect of double space fix, where F characters were not being encoded correctly 2018-10-09 14:12:00 -04:00
Jordan Sherer fc43c7fbb4 Fixed issue with directed commands splitting up words that appear in the command. E.g., 'NO' 'T' 2018-10-09 09:31:33 -04:00
Jordan Sherer 353d75ac49 Fixed double space compression issue by word replacement for a space character 2018-10-08 15:36:09 -04:00
Jordan Sherer 2d392dd676 Fixed trimming of trailing whitespace for configuration messages and grids 2018-10-08 15:04:10 -04:00
Jordan Sherer 18fac2e4ba Fixed BEACON ACK replies to CQs 2018-10-08 15:00:54 -04:00
Jordan Sherer 5275c0916f Fixed window frame on windows 2018-10-07 11:30:02 -04:00
Jordan Sherer 676aa3c78e Don't close the app when expired...just be really annoying 2018-10-07 11:01:01 -04:00
Jordan Sherer 4e8a65b5ee Move EOL to Oct 31 2018-10-07 10:52:03 -04:00
Jordan Sherer 329ca0b23f Bump to 0.7.2 2018-10-07 10:51:30 -04:00
Jordan Sherer 29cb01697a Bump to 25Hz buffer 2018-10-07 10:51:08 -04:00
Jordan Sherer e27e7baec9 Added groupcall to compound parsing. 2018-10-07 08:44:47 -04:00
Jordan Sherer 9cd17a4441 Only one beacon ack per frame 2018-10-06 23:37:32 -04:00
Jordan Sherer 9d371c474a Fixed truncated grid issue 2018-10-06 23:28:00 -04:00
36 changed files with 6498 additions and 5729 deletions
+158 -36
View File
@@ -454,6 +454,7 @@ private:
Q_SLOT void on_delete_macro_push_button_clicked (bool = false);
Q_SLOT void on_PTT_method_button_group_buttonClicked (int);
Q_SLOT void on_station_message_line_edit_textChanged(QString const&);
Q_SLOT void on_groups_line_edit_textChanged(QString const&);
Q_SLOT void on_qth_message_line_edit_textChanged(QString const&);
Q_SLOT void on_cq_message_line_edit_textChanged(QString const&);
Q_SLOT void on_reply_message_line_edit_textChanged(QString const&);
@@ -462,6 +463,9 @@ private:
void delete_selected_macros (QModelIndexList);
Q_SLOT void on_save_path_select_push_button_clicked (bool);
Q_SLOT void on_azel_path_select_push_button_clicked (bool);
Q_SLOT void on_sound_cq_path_select_push_button_clicked();
Q_SLOT void on_sound_cq_path_test_push_button_clicked();
Q_SLOT void on_sound_cq_path_reset_push_button_clicked();
Q_SLOT void on_sound_dm_path_select_push_button_clicked();
Q_SLOT void on_sound_dm_path_test_push_button_clicked();
Q_SLOT void on_sound_dm_path_reset_push_button_clicked();
@@ -516,6 +520,7 @@ private:
QDir default_azel_directory_;
QDir azel_directory_;
QString sound_cq_path_; // cq message sound file
QString sound_dm_path_; // directed message sound file
QString sound_am_path_; // alert message sound file
@@ -584,6 +589,7 @@ private:
QString my_callsign_;
QString my_grid_;
QString my_station_;
QStringList my_groups_;
QString my_qth_;
QString cq_;
QString reply_;
@@ -626,7 +632,7 @@ private:
bool spot_to_reporting_networks_;
bool transmit_directed_;
bool autoreply_off_at_startup_;
bool beacon_anywhere_;
bool heartbeat_anywhere_;
bool relay_disabled_;
bool monitor_off_at_startup_;
bool monitor_last_used_;
@@ -636,11 +642,11 @@ private:
bool insert_blank_;
bool DXCC_;
bool ppfx_;
bool clear_DX_;
bool clear_callsign_;
bool miles_;
bool quick_call_;
bool disable_TX_on_73_;
int beacon_;
int heartbeat_;
int watchdog_;
bool TX_messages_;
bool enable_VHF_features_;
@@ -757,7 +763,7 @@ void Configuration::set_spot_to_reporting_networks (bool spot)
bool Configuration::transmit_directed() const { return m_->transmit_directed_; }
bool Configuration::autoreply_off_at_startup () const {return m_->autoreply_off_at_startup_;}
bool Configuration::beacon_anywhere() const { return m_->beacon_anywhere_;}
bool Configuration::heartbeat_anywhere() const { return m_->heartbeat_anywhere_;}
bool Configuration::relay_off() const { return m_->relay_disabled_; }
bool Configuration::monitor_off_at_startup () const {return m_->monitor_off_at_startup_;}
bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->monitor_last_used_;}
@@ -767,11 +773,11 @@ bool Configuration::prompt_to_log () const {return m_->prompt_to_log_;}
bool Configuration::insert_blank () const {return m_->insert_blank_;}
bool Configuration::DXCC () const {return m_->DXCC_;}
bool Configuration::ppfx() const {return m_->ppfx_;}
bool Configuration::clear_DX () const {return m_->clear_DX_;}
bool Configuration::clear_callsign () const {return m_->clear_callsign_;}
bool Configuration::miles () const {return m_->miles_;}
bool Configuration::quick_call () const {return m_->quick_call_;}
bool Configuration::disable_TX_on_73 () const {return m_->disable_TX_on_73_;}
int Configuration::beacon () const {return m_->beacon_;}
int Configuration::heartbeat () const {return m_->heartbeat_;}
int Configuration::watchdog () const {return m_->watchdog_;}
bool Configuration::TX_messages () const {return m_->TX_messages_;}
bool Configuration::enable_VHF_features () const {return m_->enable_VHF_features_;}
@@ -808,6 +814,7 @@ QStringListModel * Configuration::macros () {return &m_->macros_;}
QStringListModel const * Configuration::macros () const {return &m_->macros_;}
QDir Configuration::save_directory () const {return m_->save_directory_;}
QDir Configuration::azel_directory () const {return m_->azel_directory_;}
QString Configuration::sound_cq_path() const {return m_->sound_cq_path_;}
QString Configuration::sound_dm_path() const {return m_->sound_dm_path_;}
QString Configuration::sound_am_path() const {return m_->sound_am_path_;}
QString Configuration::rig_name () const {return m_->rig_params_.rig_name;}
@@ -922,7 +929,7 @@ QString Configuration::my_grid() const
if (m_->use_dynamic_info_ && m_->dynamic_grid_.size () >= 4) {
grid = m_->dynamic_grid_;
}
return grid;
return grid.trimmed();
}
QString Configuration::my_station() const
@@ -931,22 +938,40 @@ QString Configuration::my_station() const
if(m_->use_dynamic_info_ && !m_->dynamic_qtc_.isEmpty()){
station = m_->dynamic_qtc_;
}
return station;
return station.trimmed();
}
QSet<QString> Configuration::my_groups() const {
return QSet<QString>::fromList(m_->my_groups_);
}
void Configuration::addGroup(QString const &group){
QSet<QString> groups = my_groups();
groups.insert(group.trimmed());
m_->my_groups_ = groups.toList();
m_->write_settings();
}
void Configuration::removeGroup(QString const &group){
QSet<QString> groups = my_groups();
groups.remove(group.trimmed());
m_->my_groups_ = groups.toList();
m_->write_settings();
}
QString Configuration::my_qth() const
{
return m_->my_qth_;
return m_->my_qth_.trimmed();
}
QString Configuration::cq_message() const
{
return m_->cq_;
return m_->cq_.trimmed();
}
QString Configuration::reply_message() const
{
return m_->reply_;
return m_->reply_.trimmed();
}
int Configuration::callsign_aging() const
@@ -1036,6 +1061,7 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
, default_audio_output_device_selected_ {false}
{
ui_->setupUi (this);
// ui_->groupBox_6->setVisible(false); //### Temporary ??? ###
{
@@ -1300,6 +1326,7 @@ void Configuration::impl::initialize_models ()
ui_->callsign_aging_spin_box->setValue(callsign_aging_);
ui_->activity_aging_spin_box->setValue(activity_aging_);
ui_->station_message_line_edit->setText (my_station_.toUpper());
ui_->groups_line_edit->setText(my_groups_.join(", "));
ui_->qth_message_line_edit->setText (my_qth_.toUpper());
ui_->cq_message_line_edit->setText(cq_.toUpper());
ui_->reply_message_line_edit->setText (reply_.toUpper());
@@ -1324,6 +1351,7 @@ void Configuration::impl::initialize_models ()
ui_->PTT_method_button_group->button (rig_params_.ptt_type)->setChecked (true);
ui_->save_path_display_label->setText (save_directory_.absolutePath ());
ui_->azel_path_display_label->setText (azel_directory_.absolutePath ());
ui_->sound_cq_path_display_label->setText(sound_cq_path_);
ui_->sound_dm_path_display_label->setText(sound_dm_path_);
ui_->sound_am_path_display_label->setText(sound_am_path_);
ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
@@ -1331,7 +1359,7 @@ void Configuration::impl::initialize_models ()
ui_->psk_reporter_check_box->setChecked (spot_to_reporting_networks_);
ui_->transmit_directed_check_box->setChecked(transmit_directed_);
ui_->autoreply_off_check_box->setChecked (autoreply_off_at_startup_);
ui_->beacon_anywhere_check_box->setChecked(beacon_anywhere_);
ui_->heartbeat_anywhere_check_box->setChecked(heartbeat_anywhere_);
ui_->relay_disabled_check_box->setChecked(relay_disabled_);
ui_->monitor_off_check_box->setChecked (monitor_off_at_startup_);
ui_->monitor_last_used_check_box->setChecked (monitor_last_used_);
@@ -1339,11 +1367,11 @@ void Configuration::impl::initialize_models ()
ui_->stations_table_view->setEnabled(ui_->auto_switch_bands_check_box->isChecked());
ui_->report_in_comments_check_box->setChecked (report_in_comments_);
ui_->prompt_to_log_check_box->setChecked (prompt_to_log_);
ui_->clear_DX_check_box->setChecked (clear_DX_);
ui_->clear_callsign_check_box->setChecked (clear_callsign_);
ui_->miles_check_box->setChecked (miles_);
ui_->quick_call_check_box->setChecked (quick_call_);
ui_->disable_TX_on_73_check_box->setChecked (disable_TX_on_73_);
ui_->beacon_spin_box->setValue (beacon_);
ui_->heartbeat_spin_box->setValue (heartbeat_);
ui_->tx_watchdog_spin_box->setValue (watchdog_);
ui_->enable_VHF_features_check_box->setChecked(enable_VHF_features_);
ui_->decode_at_52s_check_box->setChecked(decode_at_52s_);
@@ -1423,7 +1451,7 @@ void Configuration::impl::done (int r)
{
// do this here since window is still on screen at this point
SettingsGroup g {settings_, "Configuration"};
settings_->setValue ("window/geometry", saveGeometry ());
settings_->setValue ("WindowGeometry", saveGeometry ());
QDialog::done (r);
}
@@ -1431,16 +1459,19 @@ void Configuration::impl::done (int r)
void Configuration::impl::read_settings ()
{
SettingsGroup g {settings_, "Configuration"};
restoreGeometry (settings_->value ("window/geometry").toByteArray ());
setMinimumSize(800, 400);
restoreGeometry (settings_->value ("WindowGeometry").toByteArray ());
setMinimumSize(800, 400);
auto_switch_bands_ = settings_->value("AutoSwitchBands", false).toBool();
my_callsign_ = settings_->value ("MyCall", QString {}).toString ();
my_grid_ = settings_->value ("MyGrid", QString {}).toString ();
my_station_ = settings_->value("MyStation", QString {}).toString();
my_groups_ = settings_->value("MyGroups", QStringList{}).toStringList();
callsign_aging_ = settings_->value ("CallsignAging", 0).toInt ();
activity_aging_ = settings_->value ("ActivityAging", 2).toInt ();
my_qth_ = settings_->value("MyQTH", QString {}).toString();
cq_ = settings_->value("CQMessage", QString {"CQCQCQ"}).toString();
cq_ = settings_->value("CQMessage", QString {"CQCQCQ <MYGRID4>"}).toString();
reply_ = settings_->value("Reply", QString {"HW CPY?"}).toString();
next_color_cq_ = color_cq_ = settings_->value("colorCQ","#66ff66").toString();
next_color_mycall_ = color_mycall_ = settings_->value("colorMyCall","#ff6666").toString();
@@ -1525,6 +1556,7 @@ void Configuration::impl::read_settings ()
RxBandwidth_ = settings_->value ("RxBandwidth", 2500).toInt ();
save_directory_ = settings_->value ("SaveDir", default_save_directory_.absolutePath ()).toString ();
azel_directory_ = settings_->value ("AzElDir", default_azel_directory_.absolutePath ()).toString ();
sound_cq_path_ = settings_->value ("SoundCQPath", "").toString ();
sound_dm_path_ = settings_->value ("SoundDMPath", "").toString ();
sound_am_path_ = settings_->value ("SoundAMPath", "").toString ();
@@ -1588,7 +1620,7 @@ void Configuration::impl::read_settings ()
transmit_directed_ = settings_->value ("TransmitDirected", true).toBool();
autoreply_off_at_startup_ = settings_->value ("AutoreplyOFF", false).toBool ();
beacon_anywhere_ = settings_->value("BeaconAnywhere", false).toBool();
heartbeat_anywhere_ = settings_->value("BeaconAnywhere", false).toBool();
relay_disabled_ = settings_->value ("RelayOFF", false).toBool ();
monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
@@ -1645,12 +1677,12 @@ void Configuration::impl::read_settings ()
insert_blank_ = settings_->value ("InsertBlank", false).toBool ();
DXCC_ = settings_->value ("DXCCEntity", false).toBool ();
ppfx_ = settings_->value ("PrincipalPrefix", false).toBool ();
clear_DX_ = settings_->value ("ClearCallGrid", false).toBool ();
clear_callsign_ = settings_->value ("ClearCallGrid", false).toBool ();
miles_ = settings_->value ("Miles", false).toBool ();
quick_call_ = settings_->value ("QuickCall", false).toBool ();
disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool ();
beacon_ = settings_->value ("TxBeacon", 30).toInt ();
watchdog_ = settings_->value ("TxWatchdog", 0).toInt ();
heartbeat_ = settings_->value ("TxBeacon", 30).toInt ();
watchdog_ = settings_->value ("TxIdleWatchdog", 60).toInt ();
if(watchdog_){
watchdog_ = qMax(5, watchdog_);
}
@@ -1692,6 +1724,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("MyCall", my_callsign_);
settings_->setValue ("MyGrid", my_grid_);
settings_->setValue ("MyStation", my_station_);
settings_->setValue ("MyGroups", my_groups_);
settings_->setValue ("MyQTH", my_qth_);
settings_->setValue ("CQMessage", cq_);
settings_->setValue ("Reply", reply_);
@@ -1727,6 +1760,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("PTTport", rig_params_.ptt_port);
settings_->setValue ("SaveDir", save_directory_.absolutePath ());
settings_->setValue ("AzElDir", azel_directory_.absolutePath ());
settings_->setValue ("SoundCQPath", sound_cq_path_);
settings_->setValue ("SoundDMPath", sound_dm_path_);
settings_->setValue ("SoundAMPath", sound_am_path_);
@@ -1753,7 +1787,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
settings_->setValue ("TransmitDirected", transmit_directed_);
settings_->setValue ("AutoreplyOFF", autoreply_off_at_startup_);
settings_->setValue ("BeaconAnywhere", beacon_anywhere_);
settings_->setValue ("BeaconAnywhere", heartbeat_anywhere_);
settings_->setValue ("RelayOFF", relay_disabled_);
settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
settings_->setValue ("MonitorLastUsed", monitor_last_used_);
@@ -1778,12 +1812,12 @@ void Configuration::impl::write_settings ()
settings_->setValue ("InsertBlank", insert_blank_);
settings_->setValue ("DXCCEntity", DXCC_);
settings_->setValue ("PrincipalPrefix", ppfx_);
settings_->setValue ("ClearCallGrid", clear_DX_);
settings_->setValue ("ClearCallGrid", clear_callsign_);
settings_->setValue ("Miles", miles_);
settings_->setValue ("QuickCall", quick_call_);
settings_->setValue ("73TxDisable", disable_TX_on_73_);
settings_->setValue ("TxBeacon", beacon_);
settings_->setValue ("TxWatchdog", watchdog_);
settings_->setValue ("TxBeacon", heartbeat_);
settings_->setValue ("TxIdleWatchdog", watchdog_);
settings_->setValue ("Tx2QSO", TX_messages_);
settings_->setValue ("CATForceDTR", rig_params_.force_dtr);
settings_->setValue ("DTR", rig_params_.dtr_high);
@@ -1871,7 +1905,8 @@ void Configuration::impl::set_rig_invariants ()
// makes no sense with rig as "None"
ui_->monitor_last_used_check_box->setEnabled (false);
ui_->CAT_control_group_box->setEnabled (false);
ui_->catTab->setEnabled(false);
//ui_->CAT_control_group_box->setEnabled (false);
ui_->test_CAT_push_button->setEnabled (false);
ui_->test_PTT_push_button->setEnabled (TransceiverFactory::PTT_method_DTR == ptt_method
|| TransceiverFactory::PTT_method_RTS == ptt_method);
@@ -1880,7 +1915,8 @@ void Configuration::impl::set_rig_invariants ()
else
{
ui_->monitor_last_used_check_box->setEnabled (true);
ui_->CAT_control_group_box->setEnabled (true);
ui_->catTab->setEnabled(true);
//ui_->CAT_control_group_box->setEnabled (true);
ui_->test_CAT_push_button->setEnabled (true);
ui_->test_PTT_push_button->setEnabled (false);
ui_->TX_audio_source_group_box->setEnabled (transceiver_factory_.has_CAT_PTT_mic_data (rig) && TransceiverFactory::PTT_method_CAT == ptt_method);
@@ -1931,7 +1967,9 @@ void Configuration::impl::set_rig_invariants ()
break;
}
}
ui_->CAT_serial_port_parameters_group_box->setEnabled (is_serial_CAT);
ui_->force_DTR_combo_box->setEnabled (is_serial_CAT
&& (cat_port != ptt_port
|| !ui_->PTT_DTR_radio_button->isEnabled ()
@@ -1948,8 +1986,39 @@ void Configuration::impl::set_rig_invariants ()
|| TransceiverFactory::basic_transceiver_name_ != rig);
}
QStringList splitGroups(QString groupsString, bool filter){
QStringList groups;
if(groupsString.isEmpty()){
return groups;
}
foreach(QString group, groupsString.split(",")){
auto g = group.trimmed();
if(filter && !g.startsWith("@")){
continue;
}
groups.append(group.trimmed());
}
return groups;
}
bool Configuration::impl::validate ()
{
auto callsign = ui_->callsign_line_edit->text().trimmed();
if(!Varicode::isValidCallsign(callsign, nullptr) || callsign.startsWith("@")){
MessageBox::critical_message (this, tr ("The callsign format you provided is not supported"));
return false;
}
foreach(auto group, splitGroups(ui_->groups_line_edit->text(), false)){
if(!Varicode::isCompoundCallsign(group)){
MessageBox::critical_message (this, QString("%1 is not a valid group").arg(group));
return false;
}
}
if (ui_->sound_input_combo_box->currentIndex () < 0
&& !QAudioDeviceInfo::availableDevices (QAudio::AudioInput).empty ())
{
@@ -2201,6 +2270,9 @@ void Configuration::impl::accept ()
my_callsign_ = ui_->callsign_line_edit->text ();
my_grid_ = ui_->grid_line_edit->text ();
my_station_ = ui_->station_message_line_edit->text().toUpper();
my_groups_ = splitGroups(ui_->groups_line_edit->text().toUpper().trimmed(), true);
cq_ = ui_->cq_message_line_edit->text().toUpper();
reply_ = ui_->reply_message_line_edit->text().toUpper();
my_qth_ = ui_->qth_message_line_edit->text().toUpper();
@@ -2217,7 +2289,7 @@ void Configuration::impl::accept ()
tx_qsy_allowed_ = ui_->tx_qsy_check_box->isChecked ();
transmit_directed_ = ui_->transmit_directed_check_box->isChecked();
autoreply_off_at_startup_ = ui_->autoreply_off_check_box->isChecked ();
beacon_anywhere_ = ui_->beacon_anywhere_check_box->isChecked();
heartbeat_anywhere_ = ui_->heartbeat_anywhere_check_box->isChecked();
relay_disabled_ = ui_->relay_disabled_check_box->isChecked();
monitor_off_at_startup_ = ui_->monitor_off_check_box->isChecked ();
monitor_last_used_ = ui_->monitor_last_used_check_box->isChecked ();
@@ -2225,15 +2297,16 @@ void Configuration::impl::accept ()
log_as_DATA_ = ui_->log_as_RTTY_check_box->isChecked ();
report_in_comments_ = ui_->report_in_comments_check_box->isChecked ();
prompt_to_log_ = ui_->prompt_to_log_check_box->isChecked ();
clear_DX_ = ui_->clear_DX_check_box->isChecked ();
clear_callsign_ = ui_->clear_callsign_check_box->isChecked ();
miles_ = ui_->miles_check_box->isChecked ();
quick_call_ = ui_->quick_call_check_box->isChecked ();
disable_TX_on_73_ = ui_->disable_TX_on_73_check_box->isChecked ();
beacon_ = ui_->beacon_spin_box->value ();
heartbeat_ = ui_->heartbeat_spin_box->value ();
watchdog_ = ui_->tx_watchdog_spin_box->value ();
data_mode_ = static_cast<DataMode> (ui_->TX_mode_button_group->checkedId ());
save_directory_ = ui_->save_path_display_label->text ();
azel_directory_ = ui_->azel_path_display_label->text ();
sound_cq_path_ = ui_->sound_cq_path_display_label->text();
sound_dm_path_ = ui_->sound_dm_path_display_label->text();
sound_am_path_ = ui_->sound_am_path_display_label->text();
enable_VHF_features_ = ui_->enable_VHF_features_check_box->isChecked ();
@@ -2338,14 +2411,23 @@ void Configuration::impl::reject ()
void Configuration::impl::on_font_push_button_clicked ()
{
next_font_ = QFontDialog::getFont (0, next_font_, this);
next_font_ = QFontDialog::getFont (0, next_font_, this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, QFontDialog::DontUseNativeDialog
#endif
);
ui_->font_push_button->setText(QString("Application Font (%1 %2)").arg(next_font_.family()).arg(next_font_.pointSize()));
}
void Configuration::impl::on_tableFontButton_clicked ()
{
next_table_font_ = QFontDialog::getFont (0, next_table_font_, this);
next_table_font_ = QFontDialog::getFont (0, next_table_font_, this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, QFontDialog::DontUseNativeDialog
#endif
);
ui_->tableFontButton->setText(QString("Table Font (%1 %2)").arg(next_table_font_.family()).arg(next_table_font_.pointSize()));
}
@@ -2453,7 +2535,7 @@ void Configuration::impl::on_rxFontButton_clicked ()
next_rx_text_font_ = QFontDialog::getFont (0, next_rx_text_font_ , this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, 0
, QFontDialog::DontUseNativeDialog
#endif
);
ui_->rxFontButton->setText(QString("Font (%1 %2)").arg(next_rx_text_font_.family()).arg(next_rx_text_font_.pointSize()));
@@ -2495,7 +2577,7 @@ void Configuration::impl::on_txFontButton_clicked ()
next_tx_text_font_ = QFontDialog::getFont (0, next_tx_text_font_ , this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, 0
, QFontDialog::DontUseNativeDialog
#endif
);
@@ -2507,7 +2589,7 @@ void Configuration::impl::on_composeFontButton_clicked ()
next_compose_text_font_ = QFontDialog::getFont (0, next_compose_text_font_ , this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, 0
, QFontDialog::DontUseNativeDialog
#endif
);
ui_->composeFontButton->setText(QString("Font (%1 %2)").arg(next_compose_text_font_.family()).arg(next_compose_text_font_.pointSize()));
@@ -2622,6 +2704,15 @@ void Configuration::impl::on_station_message_line_edit_textChanged(QString const
}
}
void Configuration::impl::on_groups_line_edit_textChanged(QString const &text)
{
QString upper = text.toUpper();
if(text != upper){
ui_->groups_line_edit->setText (upper);
}
}
void Configuration::impl::on_qth_message_line_edit_textChanged(QString const &text)
{
QString upper = text.toUpper();
@@ -2884,6 +2975,37 @@ void Configuration::impl::on_azel_path_select_push_button_clicked (bool /* check
}
}
void Configuration::impl::on_sound_cq_path_select_push_button_clicked(){
QStringList filters;
filters << "Audio files (*.wav)"
<< "Any files (*)";
QFileDialog fd {this, tr ("Sound File"), ui_->sound_cq_path_display_label->text ()};
fd.setNameFilters(filters);
if (fd.exec ()) {
if (fd.selectedFiles ().size ()) {
if(rig_params_.ptt_type == TransceiverFactory::PTT_method_VOX){
QMessageBox::warning(this, "Notifications Sounds Warning", "You have enabled notification sounds while using VOX. To avoid transmitting these notification sounds, please make sure your rig is using a different sound card than your system.");
}
ui_->sound_cq_path_display_label->setText(fd.selectedFiles().at(0));
}
}
}
void Configuration::impl::on_sound_cq_path_test_push_button_clicked(){
auto path = ui_->sound_cq_path_display_label->text();
if(path.isEmpty()){
return;
}
QSound::play(path);
}
void Configuration::impl::on_sound_cq_path_reset_push_button_clicked(){
ui_->sound_cq_path_display_label->clear();
}
void Configuration::impl::on_sound_dm_path_select_push_button_clicked(){
QStringList filters;
filters << "Audio files (*.wav)"
+7 -3
View File
@@ -98,6 +98,9 @@ public:
QString my_callsign () const;
QString my_grid () const;
QString my_station () const;
QSet<QString> my_groups() const;
void addGroup(QString const &group);
void removeGroup(QString const &group);
int activity_aging() const;
int callsign_aging() const;
QString my_qth () const;
@@ -120,7 +123,7 @@ public:
void set_spot_to_reporting_networks (bool);
bool transmit_directed() const;
bool autoreply_off_at_startup () const;
bool beacon_anywhere() const;
bool heartbeat_anywhere() const;
bool relay_off() const;
bool monitor_off_at_startup () const;
bool monitor_last_used () const;
@@ -130,11 +133,11 @@ public:
bool insert_blank () const;
bool DXCC () const;
bool ppfx() const;
bool clear_DX () const;
bool clear_callsign () const;
bool miles () const;
bool quick_call () const;
bool disable_TX_on_73 () const;
int beacon () const;
int heartbeat () const;
int watchdog () const;
bool TX_messages () const;
bool split_mode () const;
@@ -179,6 +182,7 @@ public:
QStringListModel const * macros () const;
QDir save_directory () const;
QDir azel_directory () const;
QString sound_cq_path() const;
QString sound_dm_path() const;
QString sound_am_path() const;
QString rig_name () const;
+3239 -2787
View File
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -50,6 +50,13 @@ require this so normally you can choose not to install libusb-1.0-dev
but if you have a SoftRock USB or similar SDR that uses a custom USB
interface then it is required.
On Debian based systems, install requirements like:
sudo apt install git cmake clang gfortran \
libfftw3-dev git libgfortran3 libusb-1.0-dev autoconf libtool \
texinfo qt5-default qtmultimedia5-dev libqt5multimedia5-plugins libqt5serialport5-dev \
libudev-dev pkg-config
The Hamlib library is required. Currently WSJT-X needs to be built
using a forked version of the Hamlib git master. This fork contains
patches not yet accepted by the Hamlib development team which are
@@ -413,4 +420,4 @@ $ cmake --build . --target install
73
Bill
G4WJS.
G4WJS.
+1
View File
@@ -291,6 +291,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
if (m_ic > i1) m_amp = 0.0;
sample=qRound(m_amp*qSin(m_phi));
if(m_toneSpacing < 0) sample=qRound(m_amp*foxcom_.wave[m_ic]);
samples = load(postProcessSample(sample), samples);
++framesGenerated;
++m_ic;
+2 -2
View File
@@ -1,6 +1,6 @@
# Version number components
set (WSJTX_VERSION_MAJOR 0)
set (WSJTX_VERSION_MINOR 7)
set (WSJTX_VERSION_PATCH 1)
set (WSJTX_VERSION_MINOR 10)
set (WSJTX_VERSION_PATCH 0)
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
+31 -16
View File
@@ -22,8 +22,9 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
, message_ {string_.mid (column_qsoText + padding_).trimmed ()}
, is_standard_ {false}
, frameType_(Varicode::FrameUnknown)
, isBeacon_(false)
, isHeartbeat_(false)
, isAlt_(false)
, bits_{0}
{
if(message_.length() >= 1) {
message_ = message_.left (21).remove (QRegularExpression {"[<>]"});
@@ -51,21 +52,29 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
grid_c_string += QByteArray {6 - grid_c_string.size (), ' '};
is_standard_ = stdmsg_ (message_c_string.constData (), contest_mode_, grid_c_string.constData (), 22, 6);
// We're only going to unpack standard messages for CQs && beacons...
// We're only going to unpack standard messages for CQs && pings...
// TODO: jsherer - this is a hack for now...
if(is_standard_){
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
}
}
bits_ = bits();
// don't even try to unpack -24dB frames...they are *very* likely to be false decodes...
if(snr() <= -24){
return;
}
tryUnpack();
}
DecodedText::DecodedText (QString const& js8callmessage):
DecodedText::DecodedText (QString const& js8callmessage, int bits):
frameType_(Varicode::FrameUnknown),
message_(js8callmessage),
isBeacon_(false),
isAlt_(false)
isHeartbeat_(false),
isAlt_(false),
bits_(bits)
{
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
@@ -80,7 +89,11 @@ bool DecodedText::tryUnpack(){
bool unpacked = false;
if(!unpacked){
unpacked = tryUnpackBeacon();
unpacked = tryUnpackData();
}
if(!unpacked){
unpacked = tryUnpackHeartbeat();
}
if(!unpacked){
@@ -91,14 +104,10 @@ bool DecodedText::tryUnpack(){
unpacked = tryUnpackDirected();
}
if(!unpacked){
unpacked = tryUnpackData();
}
return unpacked;
}
bool DecodedText::tryUnpackBeacon(){
bool DecodedText::tryUnpackHeartbeat(){
QString m = message().trimmed();
// directed calls will always be 12+ chars and contain no spaces.
@@ -109,17 +118,17 @@ bool DecodedText::tryUnpackBeacon(){
bool isAlt = false;
quint8 type = Varicode::FrameUnknown;
quint8 bits3 = 0;
QStringList parts = Varicode::unpackBeaconMessage(m, &type, &isAlt, &bits3);
QStringList parts = Varicode::unpackHeartbeatMessage(m, &type, &isAlt, &bits3);
if(parts.isEmpty() || parts.length() < 2){
return false;
}
// Beacon Alt Type
// Heartbeat Alt Type
// ---------------
// 1 0 BCN
// 1 0 HB
// 1 1 CQ
isBeacon_ = true;
isHeartbeat_ = true;
isAlt_ = isAlt;
extra_ = parts.length() < 3 ? "" : parts.at(2);
@@ -131,7 +140,7 @@ bool DecodedText::tryUnpackBeacon(){
cmp.append(parts.at(1));
}
compound_ = cmp.join("/");
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : "BEACON").arg(extra_);
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : Varicode::hbString(bits3)).arg(extra_);
frameType_ = type;
return true;
}
@@ -197,6 +206,8 @@ bool DecodedText::tryUnpackDirected(){
message_ = QString(parts.join(""));
}
message_ = message_.replace("APRS: ", "APRS:");
directed_ = parts;
frameType_ = type;
return true;
@@ -210,6 +221,10 @@ bool DecodedText::tryUnpackData(){
return false;
}
if((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData){
return false;
}
quint8 type = Varicode::FrameUnknown;
QString data = Varicode::unpackDataMessage(m, &type);
+5 -4
View File
@@ -31,10 +31,10 @@ class DecodedText
{
public:
explicit DecodedText (QString const& message, bool, QString const& my_grid);
explicit DecodedText (QString const& js8callmessage);
explicit DecodedText (QString const& js8callmessage, int bits);
bool tryUnpack();
bool tryUnpackBeacon();
bool tryUnpackHeartbeat();
bool tryUnpackCompound();
bool tryUnpackDirected();
bool tryUnpackData();
@@ -45,7 +45,7 @@ public:
QString compoundCall() const { return compound_; }
bool isCompound() const { return !compound_.isEmpty(); }
bool isBeacon() const { return isBeacon_; }
bool isHeartbeat() const { return isHeartbeat_; }
bool isAlt() const { return isAlt_; }
QStringList directedMessage() const { return directed_; }
@@ -99,7 +99,7 @@ private:
column_qsoText = 22 };
quint8 frameType_;
bool isBeacon_;
bool isHeartbeat_;
bool isAlt_;
QString compound_;
QString extra_;
@@ -109,6 +109,7 @@ private:
bool contest_mode_;
QString message_;
bool is_standard_;
int bits_;
};
#endif // DECODEDTEXT_H
+52 -16
View File
@@ -23,6 +23,10 @@
#include <cmath>
#include <QDebug>
#include <QCache>
QMap<QString, quint32> LOOKUP_CACHE;
Codeword JSC::codeword(quint32 index, bool separate, quint32 bytesize, quint32 s, quint32 c){
QList<Codeword> out;
@@ -52,9 +56,19 @@ QList<CodewordPair> JSC::compress(QString text){
const quint32 s = 7;
const quint32 c = pow(2, 4) - s;
foreach(QString w, text.split(" ", QString::SkipEmptyParts)){
QString space(" ");
foreach(QString w, text.split(" ", QString::KeepEmptyParts)){
bool ok = false;
bool isSpaceCharacter = false;
// if this is an empty part, it should be a space.
if(w.isEmpty()){
w = space;
isSpaceCharacter = true;
}
while(!w.isEmpty()){
// this does both prefix and full match lookup
auto index = lookup(w, &ok);
@@ -63,10 +77,11 @@ QList<CodewordPair> JSC::compress(QString text){
}
auto t = JSC::map[index];
w = QString(w.mid(t.size));
w = QString(w).mid(t.size);
bool isLast = w.isEmpty();
out.append({ codeword(index, isLast, b, s, c), (quint32)t.size + (isLast ? 1 : 0) /* for the space that follows */});
bool shouldAppendSpace = isLast && !isSpaceCharacter;
out.append({ codeword(index, shouldAppendSpace, b, s, c), (quint32)t.size + (shouldAppendSpace ? 1 : 0) /* for the space that follows */});
}
}
@@ -92,17 +107,23 @@ QString JSC::decompress(Codeword const& bitvec){
QList<quint64> bytes;
QList<int> separators;
auto iter = bitvec.begin();
while(iter != bitvec.end()){
quint64 byte = Varicode::bitsToInt(iter, 4);
iter += 4;
int i = 0;
int count = bitvec.count();
while(i < count){
auto b = bitvec.mid(i, 4);
if(b.length() != 4){
break;
}
quint64 byte = Varicode::bitsToInt(b);
bytes.append(byte);
i += 4;
if(byte < s){
if(*iter){
if(count - i > 0 && bitvec.at(i)){
separators.append(bytes.length()-1);
}
iter += 1;
i += 1;
}
}
@@ -116,9 +137,17 @@ QString JSC::decompress(Codeword const& bitvec){
k++;
}
if(start + k >= bytes.length()){
break;
}
j = j*s + bytes[start + k] + base[k];
out.append(QString(JSC::map[j].str));
if(j >= (int)JSC::size){
break;
}
auto word = QString(JSC::map[j].str);
out.append(word);
if(!separators.isEmpty() && separators.first() == start + k){
out.append(" ");
separators.removeFirst();
@@ -131,7 +160,19 @@ QString JSC::decompress(Codeword const& bitvec){
}
quint32 JSC::lookup(QString w, bool * ok){
return lookup(w.toLatin1().data(), ok);
if(LOOKUP_CACHE.contains(w)){
if(ok) *ok = true;
return LOOKUP_CACHE[w];
}
bool found = false;
quint32 result = lookup(w.toLatin1().data(), &found);
if(found){
LOOKUP_CACHE[w] = result;
}
if(ok) *ok = found;
return result;
}
quint32 JSC::lookup(char const* b, bool *ok){
@@ -167,11 +208,6 @@ quint32 JSC::lookup(char const* b, bool *ok){
// now that we have the first index in the list, let's just iterate through the list, comparing words along the way
for(quint32 i = index; i < index + count; i++){
// if we're no longer a prefix match, end.
if(b[0] != JSC::list[i].str[0]){
break;
}
quint32 len = JSC::list[i].size;
if(strncmp(b, JSC::list[i].str, len) == 0){
if(ok) *ok = true;
+2 -2
View File
@@ -39,8 +39,8 @@ public:
static const Tuple map[262144];
static const Tuple list[262144];
static const quint32 prefixSize = 68;
static const Tuple prefix[68];
static const quint32 prefixSize = 69;
static const Tuple prefix[69];
};
#endif // JSC_H
+9 -8
View File
@@ -29,7 +29,7 @@ const Tuple JSC::list[262144] = {
{"_", 1, 48},
{"^", 1, 64},
{"]", 1, 59},
{"\\", 1, 67},
{" ", 1, 67},
{"[", 1, 58},
{"ZZZZ", 4, 91474},
{"ZZZ", 3, 70901},
@@ -180080,8 +180080,8 @@ const Tuple JSC::list[262144] = {
{"FTAD", 4, 112460},
{"FTAC", 4, 68872},
{"FTAB", 4, 72752},
{"FT8CALL", 7, 69},
{"FT8", 3, 68},
{"\\", 1, 69},
{"FT8", 3, 68},
{"FSYW", 4, 155790},
{"FSYT", 4, 186523},
{"FSYS", 4, 69541},
@@ -256665,7 +256665,7 @@ const Tuple JSC::list[262144] = {
{"ALLCOCK", 7, 255496},
{"ALLCLASSIFIEDS", 14, 205858},
{"ALLCHIN", 7, 102391},
{"ALLCALL", 7, 81},
{"@ALLCALL", 7, 81},
{"ALLBUSINESS", 11, 110217},
{"ALLBRITTON", 10, 248655},
{"ALLBRIGHT", 9, 249916},
@@ -262164,10 +262164,10 @@ const Tuple JSC::list[262144] = {
{"$", 1, 51},
{"#", 1, 53},
{"\"", 1, 26},
{"!", 1, 28},
{"!", 1, 28},
};
const Tuple JSC::prefix[68] = {
const Tuple JSC::prefix[69] = {
{"!", 1, 262143},
{"\"", 1, 262142},
{"#", 1, 262141},
@@ -262204,7 +262204,8 @@ const Tuple JSC::prefix[68] = {
{"B", 13306, 233869},
{"C", 17608, 216261},
{"D", 13749, 202512},
{"E", 12403, 190109},
{"E", 12403, 190109},
{"\\", 1, 180059},
{"F", 11252, 178857},
{"G", 10672, 168185},
{"H", 9060, 159125},
@@ -262227,7 +262228,7 @@ const Tuple JSC::prefix[68] = {
{"Y", 4348, 2264},
{"Z", 2254, 10},
{"[", 1, 9},
{"\\", 1, 8},
{" ", 1, 8},
{"]", 1, 7},
{"^", 1, 6},
{"_", 1, 5},
+4 -4
View File
@@ -88,9 +88,9 @@ const Tuple JSC::map[262144] = {
{"^", 1, 64},
{"`", 1, 65},
{"~", 1, 66},
{"\\", 1, 67},
{"FT8", 3, 68},
{"FT8CALL", 7, 69},
{" ", 1, 67},
{"FT8", 3, 68},
{"\\", 1, 69},
{"JS8", 3, 70},
{"JS8CALL", 7, 71},
{"JSQSO", 5, 72},
@@ -102,7 +102,7 @@ const Tuple JSC::map[262144] = {
{"589", 3, 78},
{"579", 3, 79},
{"569", 3, 80},
{"ALLCALL", 7, 81},
{"@ALLCALL", 7, 81},
{"BEACON", 6, 82},
{"CQCQCQ", 6, 83},
{"CPY?", 4, 84},
+9 -61
View File
@@ -60,25 +60,15 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
if(mod(params%nranera,2).eq.1) ntrials=3*10**(params%nranera/2)
if(params%nranera.eq.0) ntrials=0
nfail=0
10 if (params%nagain) then
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown', &
position='append',iostat=ios)
else
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown',iostat=ios)
endif
10 nfail=0
if(params%nmode.eq.8) then
inquire(file=trim(temp_dir)//'/houndcallers.txt',exist=ex)
if(.not.ex) then
c2fox=' '
g2fox=' '
nsnrfox=-99
nfreqfox=-99
n30z=0
nwrap=0
nfox=0
endif
open(19,file=trim(temp_dir)//'/houndcallers.txt',status='unknown')
c2fox=' '
g2fox=' '
nsnrfox=-99
nfreqfox=-99
n30z=0
nwrap=0
nfox=0
endif
if(ios.ne.0) then
@@ -103,35 +93,6 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
n30min=minval(n30fox(1:nfox))
n30max=maxval(n30fox(1:nfox))
endif
j=0
rewind 19
if(nfox.eq.0) then
endfile 19
rewind 19
else
do i=1,nfox
n=n30fox(i)
if(n30max-n30fox(i).le.4) then
j=j+1
c2fox(j)=c2fox(i)
g2fox(j)=g2fox(i)
nsnrfox(j)=nsnrfox(i)
nfreqfox(j)=nfreqfox(i)
n30fox(j)=n
m=n30max-n
if(len(trim(g2fox(j))).eq.4) then
call azdist(mygrid,g2fox(j),0.d0,nAz,nEl,nDmiles,nDkm, &
nHotAz,nHotABetter)
else
nDkm=9999
endif
write(19,1004) c2fox(j),g2fox(j),nsnrfox(j),nfreqfox(j),nDkm,m
1004 format(a12,1x,a4,i5,i6,i7,i3)
endif
enddo
nfox=j
flush(19)
endif
go to 800
endif
@@ -255,8 +216,6 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
write(*,1010) nsynced,ndecoded
1010 format('<DecodeFinished>',2i4)
call flush(6)
close(13)
close(19)
if(params%nmode.eq.4 .or. params%nmode.eq.65) close(14)
return
@@ -369,9 +328,6 @@ contains
write(*,1009) params%nutc,snr,dt,freq,csync,decoded,nft
1009 format(i4.4,i4,f5.1,i5,1x,a2,1x,a22,i2)
endif
write(13,1011) params%nutc,nint(sync),snr,dt,float(freq),drift, &
decoded,nft
1011 format(i4.4,i4,i5,f6.2,f8.0,i4,3x,a22,' QRA64',i3)
go to 100
endif
@@ -415,9 +371,6 @@ contains
write(*,1010) params%nutc,snr,dt,freq,csync,decoded,cflags
1010 format(i4.4,i4,f5.1,i5,1x,a2,1x,a22,1x,a3)
endif
write(13,1012) params%nutc,nint(sync),snr,dt,float(freq),drift, &
decoded,ft,nsum,nsmo
1012 format(i4.4,i4,i5,f6.2,f8.0,i4,3x,a22,' JT65',3i3)
100 call flush(6)
@@ -443,8 +396,6 @@ contains
!$omp critical(decode_results)
write(*,1000) params%nutc,snr,dt,nint(freq),decoded
1000 format(i4.4,i4,f5.1,i5,1x,'@ ',1x,a22)
write(13,1002) params%nutc,nint(sync),snr,dt,freq,drift,decoded
1002 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22,' JT9')
call flush(6)
!$omp end critical(decode_results)
select type(this)
@@ -503,8 +454,6 @@ contains
1000 format(i6.6,i4,f5.1,i5,' ~ ',1x,a22,1x,a2)
if(i0.gt.0) write(*,1001) params%nutc,snr,dt,nint(freq),decoded0
1001 format(i6.6,i4,f5.1,i5,' ~ ',1x,a37)
write(13,1002) params%nutc,nint(sync),snr,dt,freq,0,decoded0
1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FT8')
i1=index(decoded0,' ')
i2=i1 + index(decoded0(i1+1:),' ')
@@ -538,8 +487,7 @@ contains
endif
call flush(6)
call flush(13)
select type(this)
type is (counting_ft8_decoder)
this%decoded = this%decoded + 1
-126
View File
@@ -1,126 +0,0 @@
Quick Start for DXpedition Mode
-------------------------------
These notes are intended for operators already familiar with WSJT-X
and FT8 mode. QSOs between the Dxpedition ("Fox") and other stations
("Hounds") are completed with as little as one transmission per Hound,
as in the following examples:
----------------------------------------------------------------------------
Fox (300-600 Hz) Hounds
----------------------------------------------------------------------------
1. CQ KH1DX AJ10
2. KH1DX K1ABC FN42, KH1DX W9XYZ EN37, ...
3. K1ABC KH1DX -13
4. KH1DX K1ABC R-11
5. K1ABC RR73; W9XYZ <KH1DX> -17
6. KH1DX W9XYZ R-16
7. W9XYZ RR73; G4AAA <KH1DX> -09
8. ...
----------------------------------------------------------------------------
Everybody sets dial frequency to an agreed number and uses CAT control
with Split Operation (either *Rig* or *Fake It*). Fox transmits up to
5 signals simultaneously, at audio frequencies 300, 360, ... 540
Hz. Hounds make initial calls (e.g., line 2 above) anywhere in the
range 1000 - 4000 Hz. They send "R+rpt" 350 Hz above the frequency
where Fox called them.
INSTRUCTIONS FOR FOX
--------------------
1. Start WSJT-X in FT8 mode. Select *Fox* on the *Settings ->
Advanced tab*. On the main window, check *Tx even/1st*, *Auto Seq*,
and *Hold Tx Freq*; uncheck *Call 1st*. Set *Tx 300 Hz* and select
Tab 3.
2. In Fox mode the left window (called "Band Activity" in normal FT8
mode) is labeled "Stations calling DXpedition <MyCall>". It will be
filled with a sorted list of calling Hounds. You can sort by Call,
Grid, S/N, Distance, or Random order by using the comboBox at top
right of Tab 3. You can limit the displayed Hound callsigns to those
no stronger than *Max dB*. Fox might use this feature to discourage
Hounds from engaging in a QRO arms race.
3. *N Slots* sets the number of simultaneous Fox signals to be used.
Fox carries out as many as *N Slots* QSOs simultaneously.
4. *Repeats* sets the maximum number of repeat transmissions of the
same message. A QSO is aborted when this number would be exceeded.
5. The *CQ* comboBox on Tab 3 offers a selection of directed CQ
messages. *Reset* clears the QSO queue.
6. The Fox operator's main task is to select Hounds to be called and
worked. The text box on Tab 3 holds the "QSO queue": a list of Hound
calls to be worked. Hit Enter to select the top callsign from the
sorted list of callers (left window), or double-click on any
particular call. Either actiion moves that Hound into the "QSO
queue".
7. The right window displays decodes of signals below 1000 Hz.
Normally these should include only Hound messages containing "R+rpt"
and Fox's own transmissions.
8. To get things started, toggle *Enable Tx* to red. If a Hound call
is available in the QSO queue, that station will be called. If the
QSO queue is empty, Fox calls CQ.
9. If you're using Nslots = 2 or higher, your signal no longer has
a constant envelope. To avoid producing intermod sidebands you need
to ensure linearity in your Tx system. One way to get things about right
is to use the WSJT-X *Tune* button to generate a pure tone. Reduce the
Tx audio level until your power output decreases by 10% or so. Use this
level for your Fox transmissions.
NOTE: If you are generating Nslots signals, the average power in each one
will be 1/Nslots^2 of its normal value for single-signal transmissions.
Nslots Relative dB
-------------------
1 0
2 -6
3 -9.5
4 -12
5 -14
The following features are not yet implemented for Fox:
1. Enforce all required settings
2. Tx message timeout
3. Manual abort of selected QSO
4. All Tx and Rx messages to all.txt
5. Additional sort criteria for Hound calls
6. Selectable timeout for keeping Hounds in the sorted list
7. Display number of active callers
8. Display QSO rate
INSTRUCTIONS FOR HOUND
----------------------
1. Start WSJT-X in FT8 mode. Select *Hound* On the *Settings ->
Advanced* tab. On the main window check *Auto Seq* and uncheck *Tx
even/1st*, *Call 1st*, and *Hold Tx Freq*. Set *Tx nnnn Hz* to some
frequency between 1000 and 4000 Hz, and select *Tab 1*. Enter Fox's
callsign and locator in DX Call and DX Grid, select Tx1, and start
*Monitor*.
2. When you have copied Fox, hit *Enable Tx* to call him. You may
keep calling until he answers. You may wish to move your TxFreq
around, hoping to find a clear calling frequency.
3. When you are called by Fox with a signal report, your next
transmission will automatically be sent as Tx3 ("R+rpt"). When Fox
receives that message he responds with "RR73", and your QSO is
complete!
The following features are not yet implemented for Hound:
1. Force all required settings
2. React properly to directed CQs from Fox
3. Disable Tx2, 4, 5, 6
4. For Tx1, enforce TxFreq >= 1000 Hz
+1 -1
View File
@@ -16,7 +16,7 @@ subroutine chkcrc12a(decoded,nbadcrc)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32)
i1Dec8BitBytes(11)=0
icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits
! icrc12=xor(icrc12, 41) ! TODO: jsherer - could change the crc here
icrc12=xor(icrc12, 42) ! TODO: jsherer - could change the crc here
nbadcrc=1
if(ncrc12.eq.icrc12) nbadcrc=0
+2 -2
View File
@@ -22,9 +22,9 @@ subroutine extractmessage174(decoded,msgreceived,ncrcflag)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32)
i1Dec8BitBytes(11)=0
icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits
! icrc12=xor(icrc12, 41) ! TODO: jsherer - could change the crc here
icrc12=xor(icrc12, 42) ! TODO: jsherer - could change the crc here
if(ncrc12.eq.icrc12 .or. sum(decoded(57:87)).eq.0) then !### Kludge ###
if(ncrc12.eq.icrc12) then ! .or. sum(decoded(57:87)).eq.0) then !### Kludge ###
! CRC12 checks out --- unpack 72-bit message
do ibyte=1,12
itmp=0
+16 -6
View File
@@ -5,15 +5,23 @@ subroutine ft8_downsample(dd,newdat,f0,c1)
parameter (NMAX=15*12000,NSPS=1920)
parameter (NFFT1=192000,NFFT2=3200) !192000/60 = 3200
logical newdat
logical newdat,first
complex c1(0:NFFT2-1)
complex cx(0:NFFT1/2)
real dd(NMAX),x(NFFT1)
real dd(NMAX),x(NFFT1),taper(0:100)
equivalence (x,cx)
save cx
data first/.true./
save cx,first,taper
if(first) then
pi=4.0*atan(1.0)
do i=0,100
taper(i)=0.5*(1.0+cos(i*pi/100))
enddo
first=.false.
endif
if(newdat) then
! Data in dd have changed, recompute the long FFT
! Data in dd have changed, recompute the long FFT
x(1:NMAX)=dd
x(NMAX+1:NFFT1)=0. !Zero-pad the x array
call four2a(cx,NFFT1,1,-1,0) !r2c FFT to freq domain
@@ -23,9 +31,9 @@ subroutine ft8_downsample(dd,newdat,f0,c1)
df=12000.0/NFFT1
baud=12000.0/NSPS
i0=nint(f0/df)
ft=f0+8.0*baud
ft=f0+8.5*baud
it=min(nint(ft/df),NFFT1/2)
fb=f0-1.0*baud
fb=f0-1.5*baud
ib=max(1,nint(fb/df))
k=0
c1=0.
@@ -33,6 +41,8 @@ subroutine ft8_downsample(dd,newdat,f0,c1)
c1(k)=cx(i)
k=k+1
enddo
c1(0:100)=c1(0:100)*taper(100:0:-1)
c1(k-1-100:k-1)=c1(k-1-100:k-1)*taper
c1=cshift(c1,i0-ib)
call four2a(c1,NFFT2,1,1,1) !c2c FFT back to time domain
fac=1.0/sqrt(float(NFFT1)*NFFT2)
+4 -3
View File
@@ -28,7 +28,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
integer nappasses(0:5) !Number of decoding passes to use for each QSO state
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
integer*1, target:: i1hiscall(12)
complex cd0(3200)
complex cd0(0:3199)
complex ctwk(32)
complex csymb(32)
logical first,newdat,lsubtract,lapon,lapcqonly,nagain
@@ -126,7 +126,8 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
do k=1,NN
i1=ibest+(k-1)*32
csymb=cmplx(0.0,0.0)
if( i1.ge.1 .and. i1+31 .le. NP2 ) csymb=cd0(i1:i1+31)
!if( i1.ge.1 .and. i1+31 .le. NP2 ) csymb=cd0(i1:i1+31)
if( i1.ge.0 .and. i1+31 .le. NP2-1 ) csymb=cd0(i1:i1+31)
call four2a(csymb,32,1,-1,1)
s2(0:7,k)=abs(csymb(1:8))/1e3
enddo
@@ -181,7 +182,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
bmetap(i2)=r2
bmetap(i1)=r1
! Max log metric
psl=log(ps)
psl=log(ps+1e-32)
r1=max(psl(1),psl(3),psl(5),psl(7))-max(psl(0),psl(2),psl(4),psl(6))
r2=max(psl(2),psl(3),psl(6),psl(7))-max(psl(0),psl(1),psl(4),psl(5))
r4=max(psl(4),psl(5),psl(6),psl(7))-max(psl(0),psl(1),psl(2),psl(3))
+1 -1
View File
@@ -38,7 +38,7 @@ subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
i1Msg8BitBytes(10)=iand(i1Msg8BitBytes(10),128+64+32)
i1Msg8BitBytes(11)=0
icrc12=crc12(c_loc(i1Msg8BitBytes),11)
! icrc12=xor(icrc12, 41) ! TODO: jsherer - could change the crc here
icrc12=xor(icrc12, 42) ! TODO: jsherer - could change the crc here
! For reference, here's how to check the CRC
! i1Msg8BitBytes(10)=icrc12/256
+2 -2
View File
@@ -65,7 +65,7 @@ write(*,*) "niter= ",max_iterations," s= ",s
allocate ( codeword(N), decoded(K), message(K) )
allocate ( rxdata(N), llr(N) )
msg="K1JT K9AN EN50"
msg="0123456789012"
! msg="G4WJS K9AN EN50"
call packmsg(msg,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent,.false.,grid) !Unpack to get msgsent
@@ -91,7 +91,7 @@ allocate ( rxdata(N), llr(N) )
i1Msg8BitBytes(10:11)=0
checksum = crc12 (c_loc (i1Msg8BitBytes), 11)
! checksum = xor(checksum, 41) ! TODO: jsherer - could change the crc here
checksum = xor(checksum, 42) ! TODO: jsherer - could change the crc here
! For reference, the next 3 lines show how to check the CRC
i1Msg8BitBytes(10)=checksum/256
i1Msg8BitBytes(11)=iand (checksum,255)
+12 -19
View File
@@ -37,11 +37,6 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
savg=savg + s(1:NH1,j) !Average spectrum
enddo
call baseline(savg,nfa,nfb,sbase)
! savg=savg/NHSYM
! do i=1,NH1
! write(51,3051) i*df,savg(i),db(savg(i))
!3051 format(f10.3,e12.3,f12.3)
! enddo
ia=max(1,nint(nfa/df))
ib=nint(nfb/df)
@@ -49,6 +44,9 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
nfos=NFFT1/NSPS ! # frequency bin oversampling factor
jstrt=0.5/tstep
candidate0=0.
k=0
do i=ia,ib
do j=-JZ,+JZ
ta=0.
@@ -95,20 +93,18 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
iz=ib-ia+1
call indexx(red(ia:ib),iz,indx)
ibase=indx(nint(0.40*iz)) - 1 + ia
if(ibase.lt.1) ibase=1
if(ibase.gt.nh1) ibase=nh1
base=red(ibase)
red=red/base
candidate0=0.
k=0
do i=1,200
ji=iz+1-1
if(ji.eq.0) exit
n=ia + indx(ji) - 1
if(red(n).lt.syncmin) exit
if(k.lt.200) k=k+1
candidate0(1,k)=n*df
candidate0(2,k)=(jpeak(n)-1)*tstep
candidate0(3,k)=red(n)
do i=1,min(200,iz)
n=ia + indx(iz+1-i) - 1
if(red(n).lt.syncmin.or.isnan(red(n)).or.k.eq.200) exit
k=k+1
candidate0(1,k)=n*df
candidate0(2,k)=(jpeak(n)-1)*tstep
candidate0(3,k)=red(n)
enddo
ncand=k
@@ -123,9 +119,6 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
if(candidate0(3,i).lt.candidate0(3,j)) candidate0(3,i)=0.
endif
enddo
! write(*,3001) i,candidate0(1,i-1),candidate0(1,i),candidate0(3,i-1), &
! candidate0(3,i)
!3001 format(i2,4f8.1)
endif
enddo
+9 -18
View File
@@ -100,6 +100,7 @@ void ADIF::load()
add (extractField (record, "CALL")
, extractField (record, "BAND")
, extractField (record, "MODE")
, extractField (record, "SUBMODE")
, extractField (record, "QSO_DATE"));
}
inputFile.close ();
@@ -107,12 +108,13 @@ void ADIF::load()
}
void ADIF::add(QString const& call, QString const& band, QString const& mode, QString const& date)
void ADIF::add(QString const& call, QString const& band, QString const& mode, QString const& submode, QString const& date)
{
QSO q;
q.call = call;
q.band = band;
q.mode = mode;
q.submode = submode;
q.date = date;
if (q.call.size ())
{
@@ -121,8 +123,8 @@ void ADIF::add(QString const& call, QString const& band, QString const& mode, QS
}
}
// return true if in the log same band and mode (where JT65 == JT9)
bool ADIF::match(QString const& call, QString const& band, QString const& mode) const
// return true if in the log same band
bool ADIF::match(QString const& call, QString const& band) const
{
QList<QSO> qsos = _data.values(call);
if (qsos.size()>0)
@@ -134,20 +136,6 @@ bool ADIF::match(QString const& call, QString const& band, QString const& mode)
|| (band=="")
|| (q.band==""))
{
if (
(
((mode.compare("JT65",Qt::CaseInsensitive)==0) ||
(mode.compare("JT9",Qt::CaseInsensitive)==0) ||
(mode.compare("FT8",Qt::CaseInsensitive)==0))
&&
((q.mode.compare("JT65",Qt::CaseInsensitive)==0) ||
(q.mode.compare("JT9",Qt::CaseInsensitive)==0) ||
(q.mode.compare("FT8",Qt::CaseInsensitive)==0))
)
|| (mode.compare(q.mode,Qt::CaseInsensitive)==0)
|| (mode=="")
|| (q.mode=="")
)
return true;
}
}
@@ -174,7 +162,7 @@ int ADIF::getCount() const
return _data.size();
}
QByteArray ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode
QByteArray ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& submode
, 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
@@ -184,6 +172,9 @@ QByteArray ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QStri
t = "<call:" + QString::number(hisCall.length()) + ">" + hisCall;
t += " <gridsquare:" + QString::number(hisGrid.length()) + ">" + hisGrid;
t += " <mode:" + QString::number(mode.length()) + ">" + mode;
if(!submode.isEmpty()){
t += " <submode:" + QString::number(submode.length()) + ">" + submode;
}
t += " <rst_sent:" + QString::number(rptSent.length()) + ">" + rptSent;
t += " <rst_rcvd:" + QString::number(rptRcvd.length()) + ">" + rptRcvd;
t += " <qso_date:8>" + dateTimeOn.date().toString("yyyyMMdd");
+4 -4
View File
@@ -23,15 +23,15 @@ class ADIF
public:
void init(QString const& filename);
void load();
void add(QString const& call, QString const& band, QString const& mode, QString const& date);
bool match(QString const& call, QString const& band, QString const& mode) const;
void add(QString const& call, QString const& band, QString const& mode, const QString &submode, QString const& date);
bool match(QString const& call, QString const& band) const;
QList<QString> getCallList() const;
int getCount() const;
// open ADIF file and append the QSO details. Return true on success
bool addQSOToFile(QByteArray const& ADIF_record);
QByteArray QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& rptSent
QByteArray QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& submode, 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
@@ -41,7 +41,7 @@ class ADIF
private:
struct QSO
{
QString call,band,mode,date;
QString call,band,mode,submode,date;
};
QMultiHash<QString, QSO> _data;
+7 -21
View File
@@ -33,19 +33,6 @@ void LogBook::init()
_log.load();
_setAlreadyWorkedFromLog();
/*
int QSOcount = _log.getCount();
int count = _worked.getWorkedCount();
qDebug() << QSOcount << "QSOs and" << count << "countries worked in file" << logFilename;
*/
// QString call = "ok1ct";
// QString countryName;
// bool callWorkedBefore,countryWorkedBefore;
// match(/*in*/call, /*out*/ countryName,callWorkedBefore,countryWorkedBefore);
// qDebug() << countryName;
}
@@ -59,11 +46,14 @@ void LogBook::_setAlreadyWorkedFromLog()
if (countryName.length() > 0)
{
_worked.setAsWorked(countryName);
//qDebug() << countryName << " worked " << c;
}
}
}
bool LogBook::hasWorkedBefore(const QString &call, const QString &band){
return _log.match(call, band);
}
void LogBook::match(/*in*/const QString call,
/*out*/ QString &countryName,
bool &callWorkedBefore,
@@ -71,11 +61,9 @@ void LogBook::match(/*in*/const QString call,
{
if (call.length() > 0)
{
QString currentMode = "JT9"; // JT65 == JT9 in ADIF::match()
QString currentBand = ""; // match any band
callWorkedBefore = _log.match(call,currentBand,currentMode);
callWorkedBefore = _log.match(call,currentBand);
countryName = _countries.find(call);
// qDebug() << "B" << countryName;
if (countryName.length() > 0) // country was found
countryWorkedBefore = _worked.getHasWorked(countryName);
@@ -85,13 +73,11 @@ void LogBook::match(/*in*/const QString call,
countryWorkedBefore = false;
}
}
//qDebug() << "Logbook:" << call << ":" << countryName << "Cty B4:" << countryWorkedBefore << "call B4:" << callWorkedBefore;
}
void LogBook::addAsWorked(const QString call, const QString band, const QString mode, const QString date)
void LogBook::addAsWorked(const QString call, const QString band, const QString mode, const QString submode, const QString date)
{
//qDebug() << "adding " << call << " as worked";
_log.add(call,band,mode,date);
_log.add(call,band,mode,submode,date);
QString countryName = _countries.find(call);
if (countryName.length() > 0)
_worked.setAsWorked(countryName);
+2 -1
View File
@@ -20,11 +20,12 @@ class LogBook
{
public:
void init();
bool hasWorkedBefore(const QString &call, const QString &band);
void match(/*in*/ const QString call,
/*out*/ QString &countryName,
bool &callWorkedBefore,
bool &countryWorkedBefore) const;
void addAsWorked(const QString call, const QString band, const QString mode, const QString date);
void addAsWorked(const QString call, const QString band, const QString mode, const QString submode, const QString date);
private:
CountryDat _countries;
+12 -8
View File
@@ -95,12 +95,16 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
void LogQSO::accept()
{
QString hisCall,hisGrid,mode,rptSent,rptRcvd,dateOn,dateOff,timeOn,timeOff,band,operator_call;
QString hisCall,hisGrid,mode,submode,rptSent,rptRcvd,dateOn,dateOff,timeOn,timeOff,band,operator_call;
QString comments,name;
hisCall=ui->call->text();
hisGrid=ui->grid->text();
mode=ui->mode->text();
hisCall=ui->call->text().toUpper();
hisGrid=ui->grid->text().toUpper();
mode = ui->mode->text().toUpper();
if(mode == "JS8"){
mode="MFSK";
submode="JS8";
}
rptSent=ui->sent->text();
rptRcvd=ui->rcvd->text();
m_dateTimeOn = ui->start_date_time->dateTime ();
@@ -115,10 +119,10 @@ void LogQSO::accept()
//Log this QSO to ADIF file "js8call_log.adi"
QString filename = "js8call_log.adi"; // TODO allow user to set
ADIF adifile;
auto adifilePath = QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("js8call_log.adi");
auto adifilePath = QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath (filename);
adifile.init(adifilePath);
QByteArray ADIF {adifile.QSOToADIF (hisCall, hisGrid, mode, rptSent, rptRcvd, m_dateTimeOn, m_dateTimeOff, band
QByteArray ADIF {adifile.QSOToADIF (hisCall, hisGrid, mode, submode, rptSent, rptRcvd, m_dateTimeOn, m_dateTimeOff, band
, comments, name, strDialFreq, m_myCall, m_myGrid, m_txPower, operator_call)};
if (!adifile.addQSOToFile (ADIF))
{
@@ -148,7 +152,7 @@ void LogQSO::accept()
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 +
hisGrid + "," + strDialFreq + "," + (mode == "MFSK" ? "JS8" : mode) +
"," + rptSent + "," + rptRcvd + "," + m_txPower +
"," + comments + "," + name;
QTextStream out(&f);
@@ -157,7 +161,7 @@ void LogQSO::accept()
}
//Clean up and finish logging
Q_EMIT acceptQSO (m_dateTimeOff, hisCall, hisGrid, m_dialFreq, mode, rptSent, rptRcvd, m_txPower, comments, name,m_dateTimeOn, operator_call, m_myCall, m_myGrid, ADIF);
Q_EMIT acceptQSO (m_dateTimeOff, hisCall, hisGrid, m_dialFreq, mode, submode, rptSent, rptRcvd, m_txPower, comments, name,m_dateTimeOn, operator_call, m_myCall, m_myGrid, ADIF);
QDialog::accept();
}
+1 -1
View File
@@ -40,7 +40,7 @@ public slots:
signals:
void acceptQSO (QDateTime const& QSO_date_off, QString const& call, QString const& grid
, Radio::Frequency dial_freq, QString const& mode
, Radio::Frequency dial_freq, QString const& mode, QString const& submode
, QString const& rpt_sent, QString const& rpt_received
, QString const& tx_power, QString const& comments
, QString const& name, QDateTime const& QSO_date_on, QString const& operator_call
+3
View File
@@ -152,6 +152,9 @@
<height>16777215</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
+1603 -1650
View File
File diff suppressed because it is too large Load Diff
+69 -39
View File
@@ -120,8 +120,6 @@ public slots:
void diskDat();
void freezeDecode(int n);
void guiUpdate();
void doubleClickOnCall (Qt::KeyboardModifiers);
void doubleClickOnCall2(Qt::KeyboardModifiers);
void readFromStdout();
void p1ReadFromStdout();
void setXIT(int n, Frequency base = 0u);
@@ -132,13 +130,14 @@ public slots:
void msgAvgDecode2();
void fastPick(int x0, int x1, int y);
void playSoundNotification(const QString &path);
bool hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffset);
void logCallActivity(CallDetail d, bool spot=true);
QString lookupCallInCompoundCache(QString const &call);
void cacheActivity(QString key);
void restoreActivity(QString key);
void clearActivity();
void createAllcallTableRow(QTableWidget *table, bool selected);
void createAllcallTableRows(QTableWidget *table, const QString &selectedCall);
void displayTextForFreq(QString text, int freq, QDateTime date, bool isTx, bool isNewLine, bool isLast);
void writeNoticeTextToUI(QDateTime date, QString text);
int writeMessageTextToUI(QDateTime date, QString text, int freq, bool bold, int block=-1);
@@ -146,17 +145,18 @@ public slots:
void prependMessageText(QString text);
void addMessageText(QString text, bool clear=false, bool selectFirstPlaceholder=false);
void enqueueMessage(int priority, QString message, int freq, Callback c);
void enqueueBeacon(QString message);
void enqueueHeartbeat(QString message);
void resetMessage();
void resetMessageUI();
void restoreMessage();
void initializeDummyData();
bool ensureCallsignSet(bool alert=true);
bool ensureSelcalCallsignSelected(bool alert=true);
bool ensureKeyNotStuck(QString const& text);
void createMessage(QString const& text);
void createMessageTransmitQueue(QString const& text);
void resetMessageTransmitQueue();
QString popMessageFrame();
QPair<QString, int> popMessageFrame();
protected:
void keyPressEvent (QKeyEvent *) override;
void closeEvent(QCloseEvent *) override;
@@ -171,7 +171,14 @@ private slots:
void on_tx4_editingFinished();
void on_tx5_currentTextChanged (QString const&);
void on_tx6_editingFinished();
void on_menuControl_aboutToShow();
void on_actionEnable_Spotting_toggled(bool checked);
void on_actionEnable_Active_toggled(bool checked);
void on_actionEnable_Auto_Reply_toggled(bool checked);
void on_actionEnable_Selcall_toggled(bool checked);
void on_menuWindow_aboutToShow();
void on_actionShow_Fullscreen_triggered(bool checked);
void on_actionShow_Frequency_Clock_triggered(bool checked);
void on_actionShow_Band_Activity_triggered(bool checked);
void on_actionShow_Call_Activity_triggered(bool checked);
void on_actionShow_Waterfall_triggered(bool checked);
@@ -186,6 +193,7 @@ private slots:
void on_actionAbout_triggered();
void on_autoButton_clicked (bool);
void on_labDialFreq_clicked();
void resetPushButtonToggleText(QPushButton *btn);
void on_monitorTxButton_clicked();
void on_stopTxButton_clicked();
void on_stopButton_clicked();
@@ -211,9 +219,6 @@ private slots:
void decode();
void decodeBusy(bool b);
void on_EraseButton_clicked();
void band_activity_cleared ();
void rx_frequency_activity_cleared ();
void on_txFirstCheckBox_stateChanged(int arg1);
void set_dateTimeQSO(int m_ntx);
void set_ntx(int n);
void on_txrb1_toggled(bool status);
@@ -249,6 +254,7 @@ private slots:
void on_actionSave_decoded_triggered();
void on_actionQuickDecode_toggled (bool);
void on_actionMediumDecode_toggled (bool);
void on_actionDeepDecode_toggled (bool);
void on_actionDeepestDecode_toggled (bool);
void bumpFqso(int n);
void on_actionErase_ALL_TXT_triggered();
@@ -257,7 +263,6 @@ private slots:
void startTx();
void startTx2();
void startP1();
void continueTx();
void stopTx();
void stopTx2();
void on_pbCallCQ_clicked();
@@ -269,12 +274,21 @@ private slots:
void on_rbGenMsg_clicked(bool checked);
void on_rbFreeText_clicked(bool checked);
void on_clearAction_triggered(QObject * sender);
void buildHeartbeatMenu(QMenu *menu);
void buildCQMenu(QMenu *menu);
void buildRepeatMenu(QMenu *menu, QPushButton * button, int * interval);
void sendHeartbeat();
void on_hbMacroButton_toggled(bool checked);
void on_hbMacroButton_clicked();
void sendCQ();
void on_cqMacroButton_toggled(bool checked);
void on_cqMacroButton_clicked();
void on_replyMacroButton_clicked();
void on_snrMacroButton_clicked();
void on_qthMacroButton_clicked();
void on_qtcMacroButton_clicked();
void setShowColumn(QString tableKey, QString columnKey, bool value);
bool showColumn(QString tableKey, QString columnKey);
bool showColumn(QString tableKey, QString columnKey, bool default_=true);
void buildShowColumnsMenu(QMenu *menu, QString tableKey);
void setSortBy(QString key, QString value);
QString getSortBy(QString key, QString defaultValue);
@@ -282,6 +296,8 @@ private slots:
void buildBandActivitySortByMenu(QMenu * menu);
void buildCallActivitySortByMenu(QMenu * menu);
void buildQueryMenu(QMenu *, QString callsign);
QMap<QString, QString> buildMacroValues();
QString replaceMacros(QString const &text, QMap<QString, QString> values, bool prune);
void buildSavedMessagesMenu(QMenu *menu);
void buildRelayMenu(QMenu *menu);
QAction* buildRelayAction(QString call);
@@ -299,16 +315,12 @@ private slots:
void on_nextFreeTextMsg_currentTextChanged (QString const&);
void on_extFreeTextMsgEdit_currentTextChanged (QString const&);
int currentFreqOffset();
int countMessageFrames(QString const& text);
QStringList buildMessageFrames(QString const& text);
QList<QPair<QString, int>> buildMessageFrames(QString const& text);
bool prepareNextMessageFrame();
bool isFreqOffsetFree(int f, int bw);
int findFreeFreqOffset(int fmin, int fmax, int bw);
void scheduleBeacon(bool first=false);
void pauseBeacon();
void checkBeacon();
void prepareBeacon();
QString calculateDistance(QString const& grid, int *pDistance=nullptr);
void checkRepeat();
QString calculateDistance(QString const& grid, int *pDistance=nullptr, int *pAzimuth=nullptr);
void on_driftSpinBox_valueChanged(int n);
void on_driftSyncButton_clicked();
void on_driftSyncEndButton_clicked();
@@ -319,10 +331,8 @@ private slots:
void on_tuneButton_clicked (bool);
void on_pbR2T_clicked();
void on_pbT2R_clicked();
void on_beaconButton_clicked();
void on_selcalButton_clicked();
void acceptQSO (QDateTime const&, QString const& call, QString const& grid
, Frequency dial_freq, QString const& mode
, Frequency dial_freq, QString const& mode, QString const& submode
, QString const& rpt_sent, QString const& rpt_received
, QString const& tx_power, QString const& comments
, QString const& name, QDateTime const& QSO_date_on, QString const& operator_call
@@ -343,6 +353,14 @@ private slots:
void stop_tuning ();
void stopTuneATU();
void auto_tx_mode(bool);
void on_autoReplyButton_toggled(bool checked);
void on_monitorButton_toggled(bool checked);
void on_monitorTxButton_toggled(bool checked);
void on_selcalButton_toggled(bool checked);
void on_tuneButton_toggled(bool checked);
void on_spotButton_toggled(bool checked);
void on_activeButton_toggled(bool checked);
void on_actionMessage_averaging_triggered();
void on_actionFox_Log_triggered();
void on_actionInclude_averaging_toggled (bool);
@@ -385,8 +403,8 @@ private slots:
void on_cbCQTx_toggled(bool b);
void splash_done ();
void on_measure_check_box_stateChanged (int);
void expiry_warning_message ();
void not_GA_warning_message ();
void checkExpiryWarningMessage ();
void checkStartupWarnings ();
void clearCallsignSelected();
void refreshTextDisplay();
@@ -416,8 +434,7 @@ private:
private:
void astroUpdate ();
void writeAllTxt(QString message);
void auto_sequence (DecodedText const& message, unsigned start_tolerance, unsigned stop_tolerance);
void writeAllTxt(QString message, int bits);
void hideMenus(bool b);
NetworkAccessManager m_network_manager;
@@ -539,7 +556,6 @@ private:
bool m_diskData;
bool m_loopall;
bool m_decoderBusy;
bool m_txFirst;
bool m_auto;
bool m_restart;
bool m_startAnother;
@@ -556,6 +572,7 @@ private:
bool m_sentFirst73;
int m_currentMessageType;
QString m_currentMessage;
int m_currentMessageBits;
int m_lastMessageType;
QString m_lastMessageSent;
bool m_bShMsgs;
@@ -650,7 +667,7 @@ private:
QTimer minuteTimer;
QTimer splashTimer;
QTimer p1Timer;
QTimer beaconTimer;
QTimer repeatTimer;
QString m_path;
QString m_baseCall;
@@ -691,6 +708,7 @@ private:
QDateTime utcTimestamp;
int snr;
int bits;
float tdrift;
};
struct CommandDetail
@@ -707,6 +725,7 @@ private:
QString grid;
QString text;
QString extra;
float tdrift;
};
struct ActivityDetail
@@ -721,6 +740,8 @@ private:
QString text;
QDateTime utcTimestamp;
int snr;
bool shouldDisplay;
float tdrift;
};
struct MessageBuffer {
@@ -740,7 +761,8 @@ private:
QString m_txTextDirtyLastSelectedCall;
QString m_lastTxMessage;
QDateTime m_lastTxTime;
int m_timeDeltaMsMMA;
int m_timeDeltaMsMMA_N;
enum Priority {
PriorityLow = 10,
@@ -771,7 +793,7 @@ private:
QMap<QString, QVariant> m_showColumnsCache; // table column:key -> show boolean
QMap<QString, QVariant> m_sortCache; // table key -> sort by
QPriorityQueue<PrioritizedMessage> m_txMessageQueue; // messages to be sent
QQueue<QString> m_txFrameQueue; // frames to be sent
QQueue<QPair<QString, int>> m_txFrameQueue; // frames to be sent
QQueue<ActivityDetail> m_rxActivityQueue; // all rx activity queue
QQueue<CommandDetail> m_rxCommandQueue; // command queue for processing commands
QQueue<CallDetail> m_rxCallQueue; // call detail queue for spots to pskreporter
@@ -784,14 +806,14 @@ private:
QMap<int, QList<ActivityDetail>> m_bandActivity; // freq -> [(text, last timestamp), ...]
QMap<int, MessageBuffer> m_messageBuffer; // freq -> (cmd, [frames, ...])
QMap<QString, CallDetail> m_callActivity; // call -> (last freq, last timestamp)
QQueue<QString> m_txBeaconQueue; // beacon frames to be sent
QQueue<QString> m_txHeartbeatQueue; // ping frames to be sent
QMap<QString, QDateTime> m_aprsCallCache;
QMap<QString, QMap<QString, CallDetail>> m_callActivityCache; // band -> call activity
QMap<QString, QMap<int, QList<ActivityDetail>>> m_bandActivityCache; // band -> band activity
QMap<QString, QString> m_rxTextCache; // band -> rx text
QSet<QString> m_callSeenBeacon; // call
QSet<QString> m_callSeenHeartbeat; // call
int m_previousFreq;
bool m_shouldRestoreFreq;
bool m_bandHopped;
@@ -815,9 +837,11 @@ private:
QQueue<QString> m_foxQSOinProgress; //QSOs in progress: Fox has sent a report
QQueue<qint64> m_foxRateQueue;
bool m_nextBeaconQueued = false;
bool m_nextBeaconPaused = false;
QDateTime m_nextBeacon;
bool m_hbHidden;
int m_hbInterval;
int m_cqInterval;
QDateTime m_nextHeartbeat;
QDateTime m_nextCQ;
QDateTime m_dateTimeQSOOn;
QDateTime m_dateTimeLastTX;
@@ -834,6 +858,7 @@ private:
bool m_tx_when_ready;
bool m_transmitting;
bool m_tune;
bool m_deadAirTone;
bool m_tx_watchdog; // true when watchdog triggered
bool m_block_pwr_tooltip;
bool m_PwrBandSetOK;
@@ -843,7 +868,6 @@ private:
double m_toneSpacing;
int m_firstDecode;
QProgressDialog m_optimizingProgress;
QTimer m_heartbeat;
MessageClient * m_messageClient;
PSK_Reporter *psk_Reporter;
APRSISClient * m_aprsClient;
@@ -860,8 +884,6 @@ private:
void writeSettings();
void createStatusBar();
void updateStatusBar();
void genStdMsgs(QString rpt, bool unconditional = false);
void genCQMsg();
void clearDX ();
void lookup();
void ba2msg(QByteArray ba, char* message);
@@ -874,19 +896,18 @@ private:
void rigFailure (QString const& reason);
void pskSetLocal ();
void aprsSetLocal ();
void pskPost(DecodedText const& decodedtext);
void pskLogReport(QString mode, int offset, int snr, QString callsign, QString grid);
void aprsLogReport(int offset, int snr, QString callsign, QString grid);
Radio::Frequency dialFrequency();
void displayDialFrequency ();
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 displayTransmit();
void updateButtonDisplay();
void updateRepeatButtonDisplay();
void updateTextDisplay();
void updateFrameCountEstimate(int count);
void updateTextStatsDisplay(QString text, int count);
void updateTxButtonDisplay();
@@ -900,6 +921,8 @@ private:
void markOffsetDirected(int offset, bool isAllCall);
void clearOffsetDirected(int offset);
void processActivity(bool force=false);
void observeTimeDeltaForAverage(float delta);
void resetTimeDeltaAverage();
void processRxActivity();
void processCompoundActivity();
void processBufferedActivity();
@@ -932,6 +955,10 @@ private:
, QString const& his_call
, QString const& his_grid) const;
void read_wav_file (QString const& fname);
QDateTime nextTransmitCycle();
void resetAutomaticIntervalTransmissions(bool stopCQ, bool stopHB);
void resetCQTimer(bool stop);
void resetHeartbeatTimer(bool stop);
void decodeDone ();
void subProcessFailed (QProcess *, int exit_code, QProcess::ExitStatus);
void subProcessError (QProcess *, QProcess::ProcessError);
@@ -942,6 +969,9 @@ private:
void add_child_to_event_filter (QObject *);
void remove_child_from_event_filter (QObject *);
void setup_status_bar (bool vhf);
void resetIdleTimer();
void incrementIdleTimer();
void tx_watchdog (bool triggered);
qint64 nWidgets(QString t);
void displayWidgets(qint64 n);
+787 -660
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -578,7 +578,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
x1=XfromFreq(500);
x2=XfromFreq(1000);
if(x1<=m_w and x2>0) {
painter0.setPen(penBlue); //Mark beacon range
painter0.setPen(penBlue); //Mark ping range
painter0.drawLine(x1+1,26,x2-2,26);
painter0.drawLine(x1+1,28,x2-2,28);
}
+4 -2
View File
@@ -33,6 +33,8 @@ QString version (bool include_patch)
QString program_title (QString const& revision)
{
QString id {"JS8Call de KN4CRD (v%1)"};
return id.arg(QCoreApplication::applicationVersion ());
QString id {"%1 DE KN4CRD (v%2)"};
id = id.arg(QCoreApplication::applicationName());
id = id.arg(QCoreApplication::applicationVersion ());
return id;
}
+406 -207
View File
File diff suppressed because it is too large Load Diff
+23 -15
View File
@@ -12,6 +12,7 @@
#include <QVector>
#include <QThread>
class Varicode
{
public:
@@ -20,12 +21,12 @@ public:
JS8Call = 0, // [000] <- any other frame of the message
JS8CallFirst = 1, // [001] <- the first frame of a message
JS8CallLast = 2, // [010] <- the last frame of a message
JS8CallReserved = 4, // [100] <- a reserved flag for future use...
JS8CallData = 4, // [100] <- raw data frame (no frame type header)
};
enum FrameType {
FrameUnknown = 255, // [11111111] <- only used as a sentinel
FrameBeacon = 0, // [000]
FrameHeartbeat = 0, // [000]
FrameCompound = 1, // [001]
FrameCompoundDirected = 2, // [010]
FrameDirected = 3, // [011]
@@ -39,7 +40,7 @@ public:
static QString frameTypeString(quint8 type) {
const char* FrameTypeStrings[] = {
"FrameBeacon",
"FrameHeartbeat",
"FrameCompound",
"FrameCompoundDirected",
"FrameDirected",
@@ -62,7 +63,9 @@ public:
static QMap<QString, QString> defaultHuffTable();
static QString cqString(int number);
static QString hbString(int number);
static bool startsWithCQ(QString text);
static bool startsWithHB(QString text);
static QString formatSNR(int snr);
static QString formatPWR(int dbm);
@@ -109,6 +112,9 @@ public:
static quint32 packAlphaNumeric22(QString const& value, bool isFlag);
static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);
static quint64 packAlphaNumeric50(QString const& value);
static QString unpackAlphaNumeric50(quint64 packed);
static quint32 packCallsign(QString const& value);
static QString unpackCallsign(quint32 value);
@@ -126,27 +132,29 @@ public:
static bool isCommandAllowed(const QString &cmd);
static bool isCommandBuffered(const QString &cmd);
static int isCommandChecksumed(const QString &cmd);
static bool isValidCallsign(const QString &callsign, bool *pIsCompound);
static bool isCompoundCallsign(const QString &callsign);
static QString packBeaconMessage(QString const &text, QString const&callsign, int *n);
static QStringList unpackBeaconMessage(const QString &text, quint8 *pType, bool *isAlt, quint8 *pBits3);
static QString packHeartbeatMessage(QString const &text, QString const&callsign, int *n);
static QStringList unpackHeartbeatMessage(const QString &text, quint8 *pType, bool *isAlt, quint8 *pBits3);
static QString packCompoundMessage(QString const &text, int *n);
static QStringList unpackCompoundMessage(const QString &text, quint8 *pType, quint8 *pBits3);
static QString packCompoundFrame(const QString &baseCallsign, const QString &fix, bool isPrefix, quint8 type, quint16 num, quint8 bits3);
static QString packCompoundFrame(const QString &callsign, quint8 type, quint16 num, quint8 bits3);
static QStringList unpackCompoundFrame(const QString &text, quint8 *pType, quint16 *pNum, quint8 *pBits3);
static QString packDirectedMessage(QString const& text, QString const& callsign, QString *pTo, QString * pCmd, QString *pNum, int *n);
static QString packDirectedMessage(QString const& text, QString const& mycall, QString *pTo, bool *pToCompound, QString * pCmd, QString *pNum, int *n);
static QStringList unpackDirectedMessage(QString const& text, quint8 *pType);
static QString packDataMessage(QString const& text, int *n);
static QString unpackDataMessage(QString const& text, quint8 *pType);
static QStringList buildMessageFrames(
static QList<QPair<QString, int>> buildMessageFrames(
QString const& mycall,
QString const& basecall,
//QString const& basecall,
QString const& mygrid,
bool compound,
//bool compound,
QString const& selectedCall,
QString const& text
);
@@ -158,21 +166,21 @@ class BuildMessageFramesThread : public QThread
Q_OBJECT
public:
BuildMessageFramesThread(QString const& mycall,
QString const& basecall,
//QString const& basecall,
QString const& mygrid,
bool compound,
//bool compound,
QString const& selectedCall,
QString const& text,
QObject *parent=nullptr);
void run() override;
signals:
void resultReady(const QStringList s);
void resultReady(QStringList, QList<int>);
private:
QString m_mycall;
QString m_basecall;
//QString m_basecall;
QString m_mygrid;
bool m_compound;
//bool m_compound;
QString m_selectedCall;
QString m_text;
};
+2 -2
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1083</width>
<height>337</height>
<height>154</height>
</rect>
</property>
<property name="windowTitle">
@@ -43,7 +43,7 @@
<property name="minimumSize">
<size>
<width>400</width>
<height>100</height>
<height>10</height>
</size>
</property>
<property name="frameShape">