Compare commits
150 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f226b0c11 | |||
| cc9ecf0f47 | |||
| bdfc1cff8e | |||
| 0405dba3fc | |||
| bedc6dd96c | |||
| b001356eb0 | |||
| 85c0f1fb96 | |||
| 81a22ab8b8 | |||
| b7792fe30c | |||
| 19ad283119 | |||
| 7b44b3010a | |||
| b0fff26b77 | |||
| 0a63433bd7 | |||
| a4cc87d7b4 | |||
| 28e542e414 | |||
| 22e2700a04 | |||
| 95bbfb8232 | |||
| 1aed1fde31 | |||
| 7e9e955d7d | |||
| 45f5854bc0 | |||
| 9e1afaf106 | |||
| 1a8d02fc89 | |||
| 4064c70c26 | |||
| ce153a4511 | |||
| ebbdd679e1 | |||
| 298500f8fc | |||
| 0d63463851 | |||
| 2f3ea90263 | |||
| c8af5e51a7 | |||
| df602c663b | |||
| 9f2e87c076 | |||
| 6ef891af0f | |||
| 0f05bfedc3 | |||
| fb9c280c67 | |||
| e19dc2ea8f | |||
| 4ad817c060 | |||
| 88fb605b40 | |||
| 478a909b90 | |||
| 03b2b11938 | |||
| 3b4ea12e5f | |||
| caf3cbfc3c | |||
| 5bc4838496 | |||
| 11740384f3 | |||
| 5c9aee4b3f | |||
| db5969fdc4 | |||
| 5ca582a6b4 | |||
| 17416144a8 | |||
| b8ff10fde9 | |||
| 6c741e21b5 | |||
| 47eec2dc0b | |||
| 6504a1f220 | |||
| 91a2a801f9 | |||
| 8c74499700 | |||
| 51c9dd2761 | |||
| dc70d53f5c | |||
| 3c2a5f98ec | |||
| 5c1f890095 | |||
| 29f759dafe | |||
| 90858f8964 | |||
| e6464e952d | |||
| 186fed04e3 | |||
| 6716eb771e | |||
| b8b2cf33c3 | |||
| 4025edfc0f | |||
| c5930a0aa3 | |||
| 9079d45587 | |||
| 223a4a2183 | |||
| 1584cf0404 | |||
| 5619824bd8 | |||
| e1e2ae50e8 | |||
| cc96daa26f | |||
| 5ba31d6df7 | |||
| 73346240e5 | |||
| 886e678531 | |||
| 526b72022e | |||
| a1864fa3f0 | |||
| b0c57029e8 | |||
| 2d5b41d4b7 | |||
| 21004a7b28 | |||
| 94f2f510fc | |||
| b6745c9e2e | |||
| 8c81b3b83a | |||
| 9ddfec5e72 | |||
| a5f0937cbb | |||
| 26f21cd70a | |||
| bb7e2544b5 | |||
| 4df65585a3 | |||
| f406553a5f | |||
| ecf14dcb5c | |||
| 5163a4a630 | |||
| 4af1a14961 | |||
| 842896d867 | |||
| 4406e99670 | |||
| 79785dbef5 | |||
| 1d1bc254a4 | |||
| 4ddccd99a1 | |||
| dd6f50a5a3 | |||
| 55c365b834 | |||
| b55f8ba5c5 | |||
| fd77e5440f | |||
| 19cb0b859d | |||
| 3d3be02830 | |||
| 55f04d3cd7 | |||
| 693eec8b4b | |||
| 9244ac08c6 | |||
| 8004c51ed2 | |||
| 52b67a5609 | |||
| 3e7c64e994 | |||
| d9d3e6fba3 | |||
| 09cea086c7 | |||
| a013e79eff | |||
| a3e004375e | |||
| f018a622ce | |||
| 565c031b28 | |||
| d88d8aa440 | |||
| 3a59599253 | |||
| 22e4b0891e | |||
| 8c564b6637 | |||
| 97763ed82d | |||
| a7849c5b72 | |||
| 04394273dd | |||
| 1052dd3f9f | |||
| 78ed799a8b | |||
| c0d08f87b6 | |||
| f92b3db5ea | |||
| cebed44ccd | |||
| d47d88681b | |||
| 1be0ee4f4f | |||
| 43d8986e0a | |||
| fd69dce0ae | |||
| b2fb3f31ac | |||
| db704858e2 | |||
| 1d11f0f8ba | |||
| b6bc50a8e1 | |||
| 5addf8f61f | |||
| 367966f5e6 | |||
| caaaa957b6 | |||
| c440d4c143 | |||
| 740c0b4c04 | |||
| f5ce9f0e30 | |||
| 0a6ec136f9 | |||
| d5e1f2822d | |||
| 3fffb45338 | |||
| 1d255b1ebf | |||
| bb97799bdf | |||
| cc6a719f6d | |||
| ccd380356a | |||
| 9f8583c8e2 | |||
| c9016d7378 | |||
| cd683f9bf7 |
+16
-5
@@ -178,6 +178,7 @@ set (wsjt_qt_CXXSRCS
|
||||
HRDTransceiver.cpp
|
||||
DXLabSuiteCommanderTransceiver.cpp
|
||||
NetworkMessage.cpp
|
||||
Message.cpp
|
||||
MessageClient.cpp
|
||||
LettersSpinBox.cpp
|
||||
HintedSpinBox.cpp
|
||||
@@ -237,10 +238,12 @@ set (wsjtx_CXXSRCS
|
||||
jsc.cpp
|
||||
jsc_list.cpp
|
||||
jsc_map.cpp
|
||||
jsc_checker.cpp
|
||||
SelfDestructMessageBox.cpp
|
||||
messagereplydialog.cpp
|
||||
keyeater.cpp
|
||||
APRSISClient.cpp
|
||||
Inbox.cpp
|
||||
mainwindow.cpp
|
||||
Configuration.cpp
|
||||
main.cpp
|
||||
@@ -549,6 +552,10 @@ set (qra_CSRCS
|
||||
lib/qra/qracodes/normrnd.c
|
||||
)
|
||||
|
||||
set (sqlite3_CSRCS
|
||||
vendor/sqlite3/sqlite3.c
|
||||
)
|
||||
|
||||
set (wsjt_CSRCS
|
||||
${ka9q_CSRCS}
|
||||
lib/ftrsd/ftrsdap.c
|
||||
@@ -620,6 +627,7 @@ set (all_CXXSRCS
|
||||
)
|
||||
|
||||
set (all_C_and_CXXSRCS
|
||||
${sqlite3_CSRCS}
|
||||
${wsjt_CSRCS}
|
||||
${wsprsim_CSRCS}
|
||||
${wsprd_CSRCS}
|
||||
@@ -1111,6 +1119,7 @@ endif (${OPENMP_FOUND} OR APPLE)
|
||||
|
||||
# build the main application
|
||||
add_executable (js8call MACOSX_BUNDLE
|
||||
${sqlite3_CSRCS}
|
||||
${wsjtx_CXXSRCS}
|
||||
${wsjtx_GENUISRCS}
|
||||
wsjtx.rc
|
||||
@@ -1272,12 +1281,14 @@ if (NOT WIN32 AND NOT APPLE)
|
||||
#COMPONENT runtime
|
||||
)
|
||||
|
||||
execute_process(COMMAND ln -s /opt/js8call/bin/js8call ljs8call)
|
||||
IF("${CMAKE_INSTALL_PREFIX}" STREQUAL "/opt/js8call")
|
||||
execute_process(COMMAND ln -s /opt/js8call/bin/js8call ljs8call)
|
||||
|
||||
install(FILES
|
||||
${CMAKE_BINARY_DIR}/ljs8call DESTINATION /usr/bin/ RENAME js8call
|
||||
#COMPONENT runtime
|
||||
)
|
||||
install(FILES
|
||||
${CMAKE_BINARY_DIR}/ljs8call DESTINATION /usr/bin/ RENAME js8call
|
||||
#COMPONENT runtime
|
||||
)
|
||||
endif()
|
||||
endif (NOT WIN32 AND NOT APPLE)
|
||||
|
||||
|
||||
|
||||
+130
-40
@@ -163,6 +163,7 @@
|
||||
#include <QSerialPortInfo>
|
||||
#include <QScopedPointer>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QProcess>
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
#include "qt_helpers.hpp"
|
||||
@@ -463,6 +464,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();
|
||||
@@ -517,6 +521,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
|
||||
|
||||
@@ -638,8 +643,10 @@ private:
|
||||
bool insert_blank_;
|
||||
bool DXCC_;
|
||||
bool ppfx_;
|
||||
bool clear_DX_;
|
||||
bool clear_callsign_;
|
||||
bool miles_;
|
||||
bool avoid_allcall_;
|
||||
bool spellcheck_;
|
||||
bool quick_call_;
|
||||
bool disable_TX_on_73_;
|
||||
int heartbeat_;
|
||||
@@ -655,7 +662,7 @@ private:
|
||||
bool x4ToneSpacing_;
|
||||
bool use_dynamic_info_;
|
||||
QString opCall_;
|
||||
|
||||
QString ptt_command_;
|
||||
QString aprs_server_name_;
|
||||
QString aprs_passcode_;
|
||||
port_type aprs_server_port_;
|
||||
@@ -769,8 +776,10 @@ 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::avoid_allcall () const {return m_->avoid_allcall_;}
|
||||
bool Configuration::spellcheck () const {return m_->spellcheck_;}
|
||||
bool Configuration::quick_call () const {return m_->quick_call_;}
|
||||
bool Configuration::disable_TX_on_73 () const {return m_->disable_TX_on_73_;}
|
||||
int Configuration::heartbeat () const {return m_->heartbeat_;}
|
||||
@@ -786,6 +795,7 @@ bool Configuration::x2ToneSpacing() const {return m_->x2ToneSpacing_;}
|
||||
bool Configuration::x4ToneSpacing() const {return m_->x4ToneSpacing_;}
|
||||
bool Configuration::split_mode () const {return m_->split_mode ();}
|
||||
QString Configuration::opCall() const {return m_->opCall_;}
|
||||
QString Configuration::ptt_command() const { return m_->ptt_command_.trimmed();}
|
||||
QString Configuration::aprs_server_name () const {return m_->aprs_server_name_;}
|
||||
auto Configuration::aprs_server_port () const -> port_type {return m_->aprs_server_port_;}
|
||||
QString Configuration::aprs_passcode() const { return m_->aprs_passcode_; }
|
||||
@@ -810,6 +820,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;}
|
||||
@@ -894,6 +905,18 @@ void Configuration::transceiver_ptt (bool on)
|
||||
#endif
|
||||
|
||||
m_->transceiver_ptt (on);
|
||||
|
||||
auto cmd = ptt_command();
|
||||
if(!cmd.isEmpty()){
|
||||
auto p = new QProcess(this);
|
||||
if(cmd.contains("%1")){
|
||||
cmd = cmd.arg(on ? "\"on\"" : "\"off\"");
|
||||
} else {
|
||||
cmd.append(" ");
|
||||
cmd.append(on ? "\"on\"" : "\"off\"");
|
||||
}
|
||||
p->startDetached(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::sync_transceiver (bool force_signal, bool enforce_mode_and_split)
|
||||
@@ -940,6 +963,20 @@ 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_.trimmed();
|
||||
@@ -1009,6 +1046,12 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void setUppercase(T* t){
|
||||
auto f = t->font();
|
||||
f.setCapitalization(QFont::AllUppercase);
|
||||
t->setFont(f);
|
||||
}
|
||||
|
||||
Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
QSettings * settings, QWidget * parent)
|
||||
: QDialog {parent}
|
||||
@@ -1042,6 +1085,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 ??? ###
|
||||
|
||||
{
|
||||
@@ -1117,6 +1161,16 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
ui_->qth_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
ui_->reply_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
ui_->cq_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
ui_->groups_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
|
||||
setUppercase(ui_->callsign_line_edit);
|
||||
setUppercase(ui_->grid_line_edit);
|
||||
setUppercase(ui_->add_macro_line_edit);
|
||||
setUppercase(ui_->station_message_line_edit);
|
||||
setUppercase(ui_->qth_message_line_edit);
|
||||
setUppercase(ui_->reply_message_line_edit);
|
||||
setUppercase(ui_->cq_message_line_edit);
|
||||
setUppercase(ui_->groups_line_edit);
|
||||
|
||||
ui_->udp_server_port_spin_box->setMinimum (1);
|
||||
ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||
@@ -1331,6 +1385,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_);
|
||||
@@ -1346,8 +1401,10 @@ 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_->avoid_allcall_checkbox->setChecked(avoid_allcall_);
|
||||
ui_->spellcheck_check_box->setChecked(spellcheck_);
|
||||
ui_->quick_call_check_box->setChecked (quick_call_);
|
||||
ui_->disable_TX_on_73_check_box->setChecked (disable_TX_on_73_);
|
||||
ui_->heartbeat_spin_box->setValue (heartbeat_);
|
||||
@@ -1389,6 +1446,7 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->TX_audio_source_button_group->button (rig_params_.audio_source)->setChecked (true);
|
||||
ui_->CAT_poll_interval_spin_box->setValue (rig_params_.poll_interval);
|
||||
ui_->opCallEntry->setText (opCall_);
|
||||
ui_->ptt_command_line_edit->setText(ptt_command_);
|
||||
ui_->aprs_server_line_edit->setText (aprs_server_name_);
|
||||
ui_->aprs_server_port_spin_box->setValue (aprs_server_port_);
|
||||
ui_->aprs_passcode_line_edit->setText(aprs_passcode_);
|
||||
@@ -1430,7 +1488,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);
|
||||
}
|
||||
@@ -1438,7 +1496,9 @@ 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 ();
|
||||
@@ -1533,6 +1593,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 ();
|
||||
|
||||
@@ -1653,8 +1714,10 @@ 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 ();
|
||||
avoid_allcall_ = settings_->value ("AvoidAllcall", false).toBool ();
|
||||
spellcheck_ = settings_->value ("Spellcheck", true).toBool();
|
||||
quick_call_ = settings_->value ("QuickCall", false).toBool ();
|
||||
disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool ();
|
||||
heartbeat_ = settings_->value ("TxBeacon", 30).toInt ();
|
||||
@@ -1674,6 +1737,7 @@ void Configuration::impl::read_settings ()
|
||||
rig_params_.poll_interval = settings_->value ("Polling", 0).toInt ();
|
||||
rig_params_.split_mode = settings_->value ("SplitMode", QVariant::fromValue (TransceiverFactory::split_mode_none)).value<TransceiverFactory::SplitMode> ();
|
||||
opCall_ = settings_->value ("OpCall", "").toString ();
|
||||
ptt_command_ = settings_->value("PTTCommand", "").toString();
|
||||
aprs_server_name_ = settings_->value ("aprsServer", "rotate.aprs2.net").toString ();
|
||||
aprs_server_port_ = settings_->value ("aprsServerPort", 14580).toUInt ();
|
||||
aprs_passcode_ = settings_->value ("aprsPasscode", "").toString();
|
||||
@@ -1736,6 +1800,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_);
|
||||
|
||||
@@ -1787,8 +1852,10 @@ 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 ("AvoidAllcall", avoid_allcall_);
|
||||
settings_->setValue ("Spellcheck", spellcheck_);
|
||||
settings_->setValue ("QuickCall", quick_call_);
|
||||
settings_->setValue ("73TxDisable", disable_TX_on_73_);
|
||||
settings_->setValue ("TxBeacon", heartbeat_);
|
||||
@@ -1810,6 +1877,7 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("x2ToneSpacing", x2ToneSpacing_);
|
||||
settings_->setValue ("x4ToneSpacing", x4ToneSpacing_);
|
||||
settings_->setValue ("OpCall", opCall_);
|
||||
settings_->setValue ("PTTCommand", ptt_command_);
|
||||
settings_->setValue ("aprsServer", aprs_server_name_);
|
||||
settings_->setValue ("aprsServerPort", aprs_server_port_);
|
||||
settings_->setValue ("aprsPasscode", aprs_passcode_);
|
||||
@@ -1880,7 +1948,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);
|
||||
@@ -1889,7 +1958,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);
|
||||
@@ -1940,7 +2010,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 ()
|
||||
@@ -1969,7 +2041,7 @@ QStringList splitGroups(QString groupsString, bool filter){
|
||||
if(filter && !g.startsWith("@")){
|
||||
continue;
|
||||
}
|
||||
groups.append(group.trimmed());
|
||||
groups.append(group.trimmed().toUpper());
|
||||
}
|
||||
|
||||
return groups;
|
||||
@@ -1977,19 +2049,25 @@ QStringList splitGroups(QString groupsString, bool filter){
|
||||
|
||||
bool Configuration::impl::validate ()
|
||||
{
|
||||
auto callsign = ui_->callsign_line_edit->text().trimmed();
|
||||
auto callsign = ui_->callsign_line_edit->text().toUpper().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)){
|
||||
foreach(auto group, splitGroups(ui_->groups_line_edit->text().toUpper().trimmed(), false)){
|
||||
if(!Varicode::isCompoundCallsign(group)){
|
||||
MessageBox::critical_message (this, QString("%1 is not a valid group").arg(group));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto cq = ui_->cq_message_line_edit->text().toUpper().trimmed();
|
||||
if(!cq.isEmpty() && !(cq.startsWith("CQ") || cq.contains(callsign))){
|
||||
MessageBox::critical_message (this, QString("The CQ message format is invalid. It must either start with \"CQ\" or contain your callsign."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui_->sound_input_combo_box->currentIndex () < 0
|
||||
&& !QAudioDeviceInfo::availableDevices (QAudio::AudioInput).empty ())
|
||||
{
|
||||
@@ -2238,12 +2316,10 @@ void Configuration::impl::accept ()
|
||||
Q_ASSERT (audio_output_channel_ <= AudioDevice::Both);
|
||||
|
||||
auto_switch_bands_ = ui_->auto_switch_bands_check_box->isChecked();
|
||||
my_callsign_ = ui_->callsign_line_edit->text ();
|
||||
my_grid_ = ui_->grid_line_edit->text ();
|
||||
my_callsign_ = ui_->callsign_line_edit->text ().toUpper();
|
||||
my_grid_ = ui_->grid_line_edit->text ().toUpper();
|
||||
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();
|
||||
@@ -2268,8 +2344,10 @@ 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 ();
|
||||
avoid_allcall_ = ui_->avoid_allcall_checkbox->isChecked();
|
||||
spellcheck_ = ui_->spellcheck_check_box->isChecked();
|
||||
quick_call_ = ui_->quick_call_check_box->isChecked ();
|
||||
disable_TX_on_73_ = ui_->disable_TX_on_73_check_box->isChecked ();
|
||||
heartbeat_ = ui_->heartbeat_spin_box->value ();
|
||||
@@ -2277,6 +2355,7 @@ void Configuration::impl::accept ()
|
||||
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 ();
|
||||
@@ -2292,7 +2371,7 @@ void Configuration::impl::accept ()
|
||||
pwrBandTxMemory_ = ui_->checkBoxPwrBandTxMemory->isChecked ();
|
||||
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
|
||||
opCall_=ui_->opCallEntry->text();
|
||||
|
||||
ptt_command_ = ui_->ptt_command_line_edit->text();
|
||||
aprs_server_name_ = ui_->aprs_server_line_edit->text();
|
||||
aprs_server_port_ = ui_->aprs_server_port_spin_box->value();
|
||||
aprs_passcode_ = ui_->aprs_passcode_line_edit->text();
|
||||
@@ -2668,43 +2747,23 @@ void Configuration::impl::on_sound_output_combo_box_currentTextChanged (QString
|
||||
|
||||
void Configuration::impl::on_station_message_line_edit_textChanged(QString const &text)
|
||||
{
|
||||
QString upper = text.toUpper();
|
||||
if(text != upper){
|
||||
ui_->station_message_line_edit->setText (upper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
if(text != upper){
|
||||
ui_->qth_message_line_edit->setText (upper);
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cq_message_line_edit_textChanged(QString const &text)
|
||||
{
|
||||
QString upper = text.toUpper();
|
||||
if(text != upper){
|
||||
ui_->cq_message_line_edit->setText (upper);
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_reply_message_line_edit_textChanged(QString const &text)
|
||||
{
|
||||
QString upper = text.toUpper();
|
||||
if(text != upper){
|
||||
ui_->reply_message_line_edit->setText (upper);
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_add_macro_line_edit_editingFinished ()
|
||||
@@ -2763,7 +2822,7 @@ void Configuration::impl::on_add_macro_push_button_clicked (bool /* checked */)
|
||||
{
|
||||
auto index = next_macros_.index (next_macros_.rowCount () - 1);
|
||||
ui_->macros_list_view->setCurrentIndex (index);
|
||||
next_macros_.setData (index, ui_->add_macro_line_edit->text ());
|
||||
next_macros_.setData (index, ui_->add_macro_line_edit->text ().toUpper());
|
||||
ui_->add_macro_line_edit->clear ();
|
||||
}
|
||||
}
|
||||
@@ -2945,6 +3004,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)"
|
||||
|
||||
+9
-3
@@ -26,7 +26,7 @@ class QHostAddress;
|
||||
// Class Configuration
|
||||
//
|
||||
// Encapsulates the control, access and, persistence of user defined
|
||||
// settings for the wsjtx GUI. Setting values are accessed through a
|
||||
// settings for the GUI. Setting values are accessed through a
|
||||
// QDialog window containing concept orientated tab windows.
|
||||
//
|
||||
// Responsibilities
|
||||
@@ -37,7 +37,7 @@ class QHostAddress;
|
||||
// farmed out to a separate thread since many of the rig control
|
||||
// functions are blocking.
|
||||
//
|
||||
// All user settings required by the wsjtx GUI are exposed through
|
||||
// All user settings required by the GUI are exposed through
|
||||
// query methods. Settings only become visible once they have been
|
||||
// accepted by the user which is done by clicking the "OK" button on
|
||||
// the settings dialog.
|
||||
@@ -99,6 +99,8 @@ public:
|
||||
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;
|
||||
@@ -131,8 +133,10 @@ public:
|
||||
bool insert_blank () const;
|
||||
bool DXCC () const;
|
||||
bool ppfx() const;
|
||||
bool clear_DX () const;
|
||||
bool clear_callsign () const;
|
||||
bool miles () const;
|
||||
bool avoid_allcall () const;
|
||||
bool spellcheck() const;
|
||||
bool quick_call () const;
|
||||
bool disable_TX_on_73 () const;
|
||||
int heartbeat () const;
|
||||
@@ -155,6 +159,7 @@ public:
|
||||
bool EMEonly() const;
|
||||
bool post_decodes () const;
|
||||
QString opCall() const;
|
||||
QString ptt_command() const;
|
||||
QString aprs_server_name () const;
|
||||
port_type aprs_server_port () const;
|
||||
QString aprs_passcode () const;
|
||||
@@ -180,6 +185,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;
|
||||
|
||||
+3279
-2852
File diff suppressed because it is too large
Load Diff
+8
-1
@@ -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.
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* This file is part of JS8Call.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
*
|
||||
**/
|
||||
|
||||
#include "Inbox.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
const char* SCHEMA = "CREATE TABLE IF NOT EXISTS inbox_v1 ("
|
||||
" id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
" blob TEXT"
|
||||
");"
|
||||
"CREATE INDEX IF NOT EXISTS idx_inbox_v1__type ON"
|
||||
" inbox_v1(json_extract(blob, '$.type'));"
|
||||
"CREATE INDEX IF NOT EXISTS idx_inbox_v1__params_from ON"
|
||||
" inbox_v1(json_extract(blob, '$.params.FROM'));"
|
||||
"CREATE INDEX IF NOT EXISTS idx_inbox_v1__params_to ON"
|
||||
" inbox_v1(json_extract(blob, '$.params.TO'))";
|
||||
|
||||
Inbox::Inbox(QString path) :
|
||||
path_{ path },
|
||||
db_{ nullptr }
|
||||
{
|
||||
}
|
||||
|
||||
Inbox::~Inbox(){
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Low-Level Interface
|
||||
**/
|
||||
|
||||
bool Inbox::isOpen(){
|
||||
return db_ != nullptr;
|
||||
}
|
||||
|
||||
bool Inbox::open(){
|
||||
int rc = sqlite3_open(path_.toLocal8Bit().data(), &db_);
|
||||
if(rc != SQLITE_OK){
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = sqlite3_exec(db_, SCHEMA, nullptr, nullptr, nullptr);
|
||||
if(rc != SQLITE_OK){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Inbox::close(){
|
||||
if(db_){
|
||||
sqlite3_close(db_);
|
||||
db_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QString Inbox::error(){
|
||||
if(db_){
|
||||
return QString::fromLocal8Bit(sqlite3_errmsg(db_));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int Inbox::count(QString type, QString query, QString match){
|
||||
if(!isOpen()){
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* sql = "SELECT COUNT(*) FROM inbox_v1 "
|
||||
"WHERE json_extract(blob, '$.type') = ? "
|
||||
"AND json_extract(blob, ?) LIKE ?;";
|
||||
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
|
||||
if(rc != SQLITE_OK){
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto t8 = type.toLocal8Bit();
|
||||
auto q8 = query.toLocal8Bit();
|
||||
auto m8 = match.toLocal8Bit();
|
||||
rc = sqlite3_bind_text(stmt, 1, t8.data(), -1, nullptr);
|
||||
rc = sqlite3_bind_text(stmt, 2, q8.data(), -1, nullptr);
|
||||
rc = sqlite3_bind_text(stmt, 3, m8.data(), -1, nullptr);
|
||||
|
||||
int count = 0;
|
||||
rc = sqlite3_step(stmt);
|
||||
if(rc == SQLITE_ROW) {
|
||||
count = sqlite3_column_int(stmt, 0);
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(stmt);
|
||||
if(rc != SQLITE_OK){
|
||||
return -1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
QList<QPair<int, Message> > Inbox::values(QString type, QString query, QString match, int offset, int limit){
|
||||
if(!isOpen()){
|
||||
return {};
|
||||
}
|
||||
|
||||
const char* sql = "SELECT id, blob FROM inbox_v1 "
|
||||
"WHERE json_extract(blob, '$.type') = ? "
|
||||
"AND json_extract(blob, ?) LIKE ? "
|
||||
"ORDER BY id ASC "
|
||||
"LIMIT ? OFFSET ?;";
|
||||
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
|
||||
if(rc != SQLITE_OK){
|
||||
return {};
|
||||
}
|
||||
|
||||
auto t8 = type.toLocal8Bit();
|
||||
auto q8 = query.toLocal8Bit();
|
||||
auto m8 = match.toLocal8Bit();
|
||||
rc = sqlite3_bind_text(stmt, 1, t8.data(), -1, nullptr);
|
||||
rc = sqlite3_bind_text(stmt, 2, q8.data(), -1, nullptr);
|
||||
rc = sqlite3_bind_text(stmt, 3, m8.data(), -1, nullptr);
|
||||
rc = sqlite3_bind_int(stmt, 4, limit);
|
||||
rc = sqlite3_bind_int(stmt, 5, offset);
|
||||
|
||||
qDebug() << "exec" << sqlite3_expanded_sql(stmt);
|
||||
|
||||
QList<QPair<int, Message>> v;
|
||||
|
||||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||||
Message m;
|
||||
|
||||
int i = sqlite3_column_int(stmt, 0);
|
||||
|
||||
auto msg = QByteArray((const char*)sqlite3_column_text(stmt, 1), sqlite3_column_bytes(stmt, 1));
|
||||
|
||||
QJsonParseError e;
|
||||
QJsonDocument d = QJsonDocument::fromJson(msg, &e);
|
||||
if(e.error != QJsonParseError::NoError){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!d.isObject()){
|
||||
continue;
|
||||
}
|
||||
|
||||
m.read(d.object());
|
||||
v.append({ i, m });
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(stmt);
|
||||
if(rc != SQLITE_OK){
|
||||
return {};
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
Message Inbox::value(int key){
|
||||
if(!isOpen()){
|
||||
return {};
|
||||
}
|
||||
|
||||
const char* sql = "SELECT blob FROM inbox_v1 WHERE id = ? LIMIT 1;";
|
||||
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
|
||||
if(rc != SQLITE_OK){
|
||||
return {};
|
||||
}
|
||||
|
||||
rc = sqlite3_bind_int(stmt, 1, key);
|
||||
|
||||
Message m;
|
||||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||||
auto msg = QByteArray((const char*)sqlite3_column_text(stmt, 0), sqlite3_column_bytes(stmt, 0));
|
||||
|
||||
QJsonParseError e;
|
||||
QJsonDocument d = QJsonDocument::fromJson(msg, &e);
|
||||
if(e.error != QJsonParseError::NoError){
|
||||
return {};
|
||||
}
|
||||
|
||||
if(!d.isObject()){
|
||||
return {};
|
||||
}
|
||||
|
||||
m.read(d.object());
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(stmt);
|
||||
if(rc != SQLITE_OK){
|
||||
return {};
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
int Inbox::append(Message value){
|
||||
if(!isOpen()){
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* sql = "INSERT INTO inbox_v1 (blob) VALUES (?);";
|
||||
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
|
||||
if(rc != SQLITE_OK){
|
||||
return -2;
|
||||
}
|
||||
|
||||
auto j8 = value.toJson();
|
||||
rc = sqlite3_bind_text(stmt, 1, j8.data(), -1, nullptr);
|
||||
rc = sqlite3_step(stmt);
|
||||
|
||||
rc = sqlite3_finalize(stmt);
|
||||
if(rc != SQLITE_OK){
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sqlite3_last_insert_rowid(db_);
|
||||
}
|
||||
|
||||
bool Inbox::set(int key, Message value){
|
||||
if(!isOpen()){
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* sql = "UPDATE inbox_v1 SET blob = ? WHERE id = ?;";
|
||||
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
|
||||
if(rc != SQLITE_OK){
|
||||
return false;
|
||||
}
|
||||
|
||||
auto j8 = value.toJson();
|
||||
rc = sqlite3_bind_text(stmt, 1, j8.data(), -1, nullptr);
|
||||
rc = sqlite3_bind_int(stmt, 2, key);
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
|
||||
rc = sqlite3_finalize(stmt);
|
||||
if(rc != SQLITE_OK){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Inbox::del(int key){
|
||||
if(!isOpen()){
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* sql = "DELETE FROM inbox_v1 WHERE id = ?;";
|
||||
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
|
||||
if(rc != SQLITE_OK){
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = sqlite3_bind_int(stmt, 1, key);
|
||||
rc = sqlite3_step(stmt);
|
||||
|
||||
rc = sqlite3_finalize(stmt);
|
||||
if(rc != SQLITE_OK){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* High-Level Interface
|
||||
**/
|
||||
|
||||
int Inbox::countUnreadFrom(QString from){
|
||||
return count("UNREAD", "$.params.FROM", from);
|
||||
}
|
||||
|
||||
QPair<int, Message> Inbox::firstUnreadFrom(QString from){
|
||||
auto v = values("UNREAD", "$.params.FROM", from, 0, 1);
|
||||
if(v.isEmpty()){
|
||||
return {};
|
||||
}
|
||||
return v.first();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef INBOX_H
|
||||
#define INBOX_H
|
||||
|
||||
/**
|
||||
* (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
**/
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QPair>
|
||||
#include <QVariant>
|
||||
|
||||
#include "vendor/sqlite3/sqlite3.h"
|
||||
|
||||
#include "Message.h"
|
||||
|
||||
|
||||
class Inbox
|
||||
{
|
||||
public:
|
||||
explicit Inbox(QString path);
|
||||
~Inbox();
|
||||
|
||||
// Low-Level Interface
|
||||
bool isOpen();
|
||||
bool open();
|
||||
void close();
|
||||
QString error();
|
||||
int count(QString type, QString query, QString match);
|
||||
QList<QPair<int, Message>> values(QString type, QString query, QString match, int offset, int limit);
|
||||
Message value(int key);
|
||||
int append(Message value);
|
||||
bool set(int key, Message value);
|
||||
bool del(int key);
|
||||
|
||||
// High-Level Interface
|
||||
int countUnreadFrom(QString from);
|
||||
QPair<int, Message> firstUnreadFrom(QString from);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QString path_;
|
||||
sqlite3 * db_;
|
||||
};
|
||||
|
||||
#endif // INBOX_H
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* This file is part of JS8Call.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
*
|
||||
**/
|
||||
|
||||
#include "Message.h"
|
||||
|
||||
Message::Message()
|
||||
{
|
||||
}
|
||||
|
||||
Message::Message(QString const &type, QString const &value):
|
||||
type_{ type },
|
||||
value_{ value }
|
||||
{
|
||||
}
|
||||
|
||||
Message::Message(QString const &type, QString const &value, QMap<QString, QVariant> const ¶ms):
|
||||
type_{ type },
|
||||
value_{ value },
|
||||
params_{ params }
|
||||
{
|
||||
}
|
||||
|
||||
void Message::read(const QJsonObject &json){
|
||||
if(json.contains("type") && json["type"].isString()){
|
||||
type_ = json["type"].toString();
|
||||
}
|
||||
|
||||
if(json.contains("value") && json["value"].isString()){
|
||||
value_ = json["value"].toString();
|
||||
}
|
||||
|
||||
if(json.contains("params") && json["params"].isObject()){
|
||||
params_.clear();
|
||||
|
||||
QJsonObject params = json["params"].toObject();
|
||||
foreach(auto key, params.keys()){
|
||||
params_[key] = params[key].toVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Message::write(QJsonObject &json) const{
|
||||
json["type"] = type_;
|
||||
json["value"] = value_;
|
||||
|
||||
QJsonObject params;
|
||||
foreach(auto key, params_.keys()){
|
||||
params.insert(key, QJsonValue::fromVariant(params_[key]));
|
||||
}
|
||||
json["params"] = params;
|
||||
}
|
||||
|
||||
QByteArray Message::toJson() const {
|
||||
QJsonObject o;
|
||||
write(o);
|
||||
|
||||
QJsonDocument d(o);
|
||||
return d.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef MESSAGE_H
|
||||
#define MESSAGE_H
|
||||
|
||||
/**
|
||||
* (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
**/
|
||||
|
||||
#include <QMap>
|
||||
#include <QByteArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
class Message {
|
||||
public:
|
||||
Message();
|
||||
Message(QString const &type, QString const &value="");
|
||||
Message(QString const &type, QString const &value, QMap<QString, QVariant> const ¶ms);
|
||||
|
||||
void read(const QJsonObject &json);
|
||||
void write(QJsonObject &json) const;
|
||||
|
||||
QByteArray toJson() const;
|
||||
|
||||
QString type() const { return type_; }
|
||||
void setType(QString type){ type_ = type; }
|
||||
|
||||
QString value() const { return value_; }
|
||||
void setValue(QString value){ value_ = value; }
|
||||
|
||||
QMap<QString, QVariant> params() const { return params_; }
|
||||
|
||||
private:
|
||||
QString type_;
|
||||
QString value_;
|
||||
QMap<QString, QVariant> params_;
|
||||
};
|
||||
|
||||
|
||||
#endif // MESSAGE_H
|
||||
@@ -19,61 +19,6 @@
|
||||
|
||||
#include "moc_MessageClient.cpp"
|
||||
|
||||
Message::Message()
|
||||
{
|
||||
}
|
||||
|
||||
Message::Message(QString const &type, QString const &value):
|
||||
type_{ type },
|
||||
value_{ value }
|
||||
{
|
||||
}
|
||||
|
||||
Message::Message(QString const &type, QString const &value, QMap<QString, QVariant> const ¶ms):
|
||||
type_{ type },
|
||||
value_{ value },
|
||||
params_{ params }
|
||||
{
|
||||
}
|
||||
|
||||
void Message::read(const QJsonObject &json){
|
||||
if(json.contains("type") && json["type"].isString()){
|
||||
type_ = json["type"].toString();
|
||||
}
|
||||
|
||||
if(json.contains("value") && json["value"].isString()){
|
||||
value_ = json["value"].toString();
|
||||
}
|
||||
|
||||
if(json.contains("params") && json["params"].isObject()){
|
||||
params_.clear();
|
||||
|
||||
QJsonObject params = json["params"].toObject();
|
||||
foreach(auto key, params.keys()){
|
||||
params_[key] = params[key].toVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Message::write(QJsonObject &json) const{
|
||||
json["type"] = type_;
|
||||
json["value"] = value_;
|
||||
|
||||
QJsonObject params;
|
||||
foreach(auto key, params_.keys()){
|
||||
params.insert(key, QJsonValue::fromVariant(params_[key]));
|
||||
}
|
||||
json["params"] = params;
|
||||
}
|
||||
|
||||
QByteArray Message::toJson() const {
|
||||
QJsonObject o;
|
||||
write(o);
|
||||
|
||||
QJsonDocument d(o);
|
||||
return d.toJson();
|
||||
}
|
||||
|
||||
|
||||
class MessageClient::impl
|
||||
: public QUdpSocket
|
||||
|
||||
+1
-25
@@ -6,9 +6,8 @@
|
||||
#include <QDataStream>
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "Message.h"
|
||||
#include "Radio.hpp"
|
||||
#include "pimpl_h.hpp"
|
||||
|
||||
@@ -16,29 +15,6 @@ class QByteArray;
|
||||
class QHostAddress;
|
||||
class QColor;
|
||||
|
||||
|
||||
class Message {
|
||||
public:
|
||||
Message();
|
||||
Message(QString const &type, QString const &value="");
|
||||
Message(QString const &type, QString const &value, QMap<QString, QVariant> const ¶ms);
|
||||
|
||||
void read(const QJsonObject &json);
|
||||
void write(QJsonObject &json) const;
|
||||
|
||||
QByteArray toJson() const;
|
||||
|
||||
QString type() const { return type_; }
|
||||
QString value() const { return value_; }
|
||||
QMap<QString, QVariant> params() const { return params_; }
|
||||
|
||||
private:
|
||||
QString type_;
|
||||
QString value_;
|
||||
QMap<QString, QVariant> params_;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// MessageClient - Manage messages sent and replies received from a
|
||||
// matching server (MessageServer) at the other end of
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -10,10 +10,12 @@ JS8Call is an experiment to test the feasibility of a digital mode with the robu
|
||||
|
||||
* For release announcements and discussion, join the JS8Call mailing list here: https://groups.io/g/js8call
|
||||
|
||||
* Documentation is available here: https://docs.google.com/document/d/159S4wqMUVdMA7qBgaSWmU-iDI4C9wd4CuWnetN68O9U/edit?pli=1#heading=h.kfnyge37yfr
|
||||
|
||||
|
||||
# Notice
|
||||
|
||||
JS8Call is a derivative of the WSJT-X application, restructured and redesigned for message passing using FT8 modulation. It is not supported by nor endorsed by the WSJT-X development group. While the WSJT-X group maintains copyright over the original work and code, JS8Call is a derivative work licensed under and in accordance with the terms of the GPLv3 license. The source code modifications are public and can be found in this repository: https://bitbucket.org/widefido/wsjtx/
|
||||
JS8Call is a derivative of the WSJT-X application, restructured and redesigned for message passing using FT8 modulation. It is not supported by nor endorsed by the WSJT-X development group. While the WSJT-X group maintains copyright over the original work and code, JS8Call is a derivative work licensed under and in accordance with the terms of the GPLv3 license. The source code modifications are public and can be found in this repository: https://bitbucket.org/widefido/js8call/
|
||||
|
||||
|
||||
# History
|
||||
@@ -33,3 +35,7 @@ JS8Call is a derivative of the WSJT-X application, restructured and redesigned f
|
||||
* August 12, 2018 - Version 0.4 released - (“leaked” on QRZ) - 500 testers
|
||||
* September 2, 2018 - Version 0.5 released - 3000 testers
|
||||
* September 14, 2018 - Version 0.6 released - 5000 testers
|
||||
* October 8, 2018 - Version 0.7 released - 6000 testers, name changed to JS8 & JS8Call
|
||||
* October 31, 2018 - Version 0.8 released - ~7000 testers
|
||||
* November 15, 2018 - Version 0.9 released - ~7500 testers
|
||||
* November 30, 2018 - Version 0.10 released - ~7800 testers
|
||||
|
||||
+1
-2
@@ -11,8 +11,7 @@ class QString;
|
||||
//
|
||||
// Abstract Transceiver Interface
|
||||
//
|
||||
// This is the minimal generic interface to a rig as required by
|
||||
// wsjtx.
|
||||
// This is the minimal generic interface to a rig.
|
||||
//
|
||||
// Responsibilities
|
||||
//
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
# Version number components
|
||||
set (WSJTX_VERSION_MAJOR 0)
|
||||
set (WSJTX_VERSION_MINOR 8)
|
||||
set (WSJTX_VERSION_PATCH 1)
|
||||
set (WSJTX_VERSION_MINOR 12)
|
||||
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,7 +31,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
"community.<br /><br />"
|
||||
"JS8Call stands on the shoulder of giants...the takeoff angle "
|
||||
"is better up there.<br /><br />"
|
||||
"A special thanks goes out to the JS8Call development team:<br/><br/><strong>"
|
||||
"A special thanks goes out to:<br/><br/><strong>"
|
||||
"KC9QNE, "
|
||||
"KI6SSI, "
|
||||
"K0OG, "
|
||||
@@ -41,8 +41,8 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
"OH8STN, "
|
||||
"VA3OSO, "
|
||||
"VK1MIC, "
|
||||
"W0FW,</strong><br/><br/>and the many other amateur radio operators who have given "
|
||||
"JS8Call a chance.");
|
||||
"W0FW,</strong><br/><br/>and the many other amateur radio operators who have helped<br/>"
|
||||
"bring JS8Call into the world.");
|
||||
}
|
||||
|
||||
CAboutDlg::~CAboutDlg()
|
||||
|
||||
+9
-9
@@ -61,6 +61,11 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
|
||||
bits_ = bits();
|
||||
|
||||
// don't even try to unpack -24dB frames...they are *very* likely to be false decodes...
|
||||
if(snr() <= -24){
|
||||
return;
|
||||
}
|
||||
|
||||
tryUnpack();
|
||||
}
|
||||
|
||||
@@ -121,7 +126,7 @@ bool DecodedText::tryUnpackHeartbeat(){
|
||||
|
||||
// Heartbeat Alt Type
|
||||
// ---------------
|
||||
// 1 0 BCN
|
||||
// 1 0 HB
|
||||
// 1 1 CQ
|
||||
isHeartbeat_ = true;
|
||||
isAlt_ = isAlt;
|
||||
@@ -135,7 +140,7 @@ bool DecodedText::tryUnpackHeartbeat(){
|
||||
cmp.append(parts.at(1));
|
||||
}
|
||||
compound_ = cmp.join("/");
|
||||
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : "HEARTBEAT").arg(extra_);
|
||||
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : Varicode::hbString(bits3)).arg(extra_);
|
||||
frameType_ = type;
|
||||
return true;
|
||||
}
|
||||
@@ -216,19 +221,14 @@ bool DecodedText::tryUnpackData(){
|
||||
return false;
|
||||
}
|
||||
|
||||
if((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData){
|
||||
return false;
|
||||
}
|
||||
|
||||
quint8 type = Varicode::FrameUnknown;
|
||||
QString data = Varicode::unpackDataMessage(m, &type);
|
||||
QString data = Varicode::unpackDataMessage(m);
|
||||
|
||||
if(data.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
|
||||
message_ = data;
|
||||
frameType_ = type;
|
||||
frameType_ = Varicode::FrameData;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +137,14 @@ QString JSC::decompress(Codeword const& bitvec){
|
||||
k++;
|
||||
}
|
||||
|
||||
if(start + k >= bytes.length()){
|
||||
break;
|
||||
}
|
||||
j = j*s + bytes[start + k] + base[k];
|
||||
|
||||
if(j >= (int)JSC::size){
|
||||
break;
|
||||
}
|
||||
auto word = QString(JSC::map[j].str);
|
||||
|
||||
out.append(word);
|
||||
@@ -147,6 +159,13 @@ QString JSC::decompress(Codeword const& bitvec){
|
||||
return out.join("");
|
||||
}
|
||||
|
||||
bool JSC::exists(QString w, quint32 *pIndex){
|
||||
bool found = false;
|
||||
quint32 index = lookup(w, &found);
|
||||
if(pIndex) *pIndex = index;
|
||||
return found && JSC::map[index].size == w.length();
|
||||
}
|
||||
|
||||
quint32 JSC::lookup(QString w, bool * ok){
|
||||
if(LOOKUP_CACHE.contains(w)){
|
||||
if(ok) *ok = true;
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
static QList<CodewordPair> compress(QString text);
|
||||
static QString decompress(Codeword const& bits);
|
||||
|
||||
static bool exists(QString w, quint32 *pIndex);
|
||||
static quint32 lookup(QString w, bool *ok);
|
||||
static quint32 lookup(char const* b, bool *ok);
|
||||
|
||||
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* This file is part of JS8Call.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
*
|
||||
**/
|
||||
|
||||
#include "jsc_checker.h"
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QTextBlock>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocument>
|
||||
#include <QTextLayout>
|
||||
#include <QDebug>
|
||||
|
||||
#include "jsc.h"
|
||||
#include "varicode.h"
|
||||
|
||||
const int CORRECT = QTextFormat::UserProperty + 10;
|
||||
const QString ALPHABET = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
|
||||
|
||||
JSCChecker::JSCChecker(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool cursorHasProperty(const QTextCursor &cursor, int property){
|
||||
if(property < QTextFormat::UserProperty) {
|
||||
return false;
|
||||
}
|
||||
if(cursor.charFormat().intProperty(property) == 1) {
|
||||
return true;
|
||||
}
|
||||
const QList<QTextLayout::FormatRange>& formats = cursor.block().layout()->additionalFormats();
|
||||
int pos = cursor.positionInBlock();
|
||||
foreach(const QTextLayout::FormatRange& range, formats) {
|
||||
if(pos > range.start && pos <= range.start + range.length && range.format.intProperty(property) == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString nextChar(QTextCursor c){
|
||||
QTextCursor cur(c);
|
||||
cur.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
|
||||
return cur.selectedText();
|
||||
}
|
||||
|
||||
bool isNumeric(QString s){
|
||||
return s.indexOf(QRegExp("^\\d+$")) == 0;
|
||||
}
|
||||
|
||||
bool isWordChar(QString ch){
|
||||
return ch.contains(QRegExp("^\\w$"));
|
||||
}
|
||||
|
||||
void JSCChecker::checkRange(QTextEdit* edit, int start, int end)
|
||||
{
|
||||
if(end == -1){
|
||||
QTextCursor tmpCursor(edit->textCursor());
|
||||
tmpCursor.movePosition(QTextCursor::End);
|
||||
end = tmpCursor.position();
|
||||
}
|
||||
|
||||
// stop contentsChange signals from being emitted due to changed charFormats
|
||||
edit->document()->blockSignals(true);
|
||||
|
||||
qDebug() << "checking range " << start << " - " << end;
|
||||
|
||||
QTextCharFormat errorFmt;
|
||||
errorFmt.setFontUnderline(true);
|
||||
errorFmt.setUnderlineColor(Qt::red);
|
||||
errorFmt.setUnderlineStyle(QTextCharFormat::WaveUnderline);
|
||||
QTextCharFormat defaultFormat = QTextCharFormat();
|
||||
|
||||
auto cursor = edit->textCursor();
|
||||
|
||||
cursor.beginEditBlock();
|
||||
{
|
||||
cursor.setPosition(start);
|
||||
while(cursor.position() < end) {
|
||||
bool correct = false;
|
||||
|
||||
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||
if(cursor.selectedText() == "@"){
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
|
||||
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||
}
|
||||
|
||||
if(cursorHasProperty(cursor, CORRECT)){
|
||||
correct = true;
|
||||
} else {
|
||||
QString word = cursor.selectedText();
|
||||
|
||||
// three or less is always "correct"
|
||||
if(word.length() < 4 || isNumeric(word)){
|
||||
correct = true;
|
||||
} else {
|
||||
bool found = false;
|
||||
quint32 index = JSC::lookup(word, &found);
|
||||
if(found){
|
||||
correct = JSC::map[index].size == word.length();
|
||||
}
|
||||
|
||||
if(!correct){
|
||||
correct = Varicode::isValidCallsign(word, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(correct){
|
||||
QTextCharFormat fmt = cursor.charFormat();
|
||||
fmt.setFontUnderline(defaultFormat.fontUnderline());
|
||||
fmt.setUnderlineColor(defaultFormat.underlineColor());
|
||||
fmt.setUnderlineStyle(defaultFormat.underlineStyle());
|
||||
cursor.setCharFormat(fmt);
|
||||
} else {
|
||||
cursor.mergeCharFormat(errorFmt);
|
||||
}
|
||||
|
||||
// Go to next word start
|
||||
//while(cursor.position() < end && !isWordChar(nextChar(cursor))){
|
||||
// cursor.movePosition(QTextCursor::NextCharacter);
|
||||
//}
|
||||
cursor.movePosition(QTextCursor::NextCharacter);
|
||||
}
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
|
||||
edit->document()->blockSignals(false);
|
||||
}
|
||||
|
||||
QSet<QString> oneEdit(QString word, bool includeAdditions, bool includeDeletions){
|
||||
QSet<QString> all;
|
||||
|
||||
// 1-edit distance words (i.e., prefixed/suffixed/edited characters)
|
||||
for(int i = 0; i < 26; i++){
|
||||
if(includeAdditions){
|
||||
auto prefixed = ALPHABET.mid(i, 1) + word;
|
||||
all.insert(prefixed);
|
||||
|
||||
auto suffixed = word + ALPHABET.mid(i, 1);
|
||||
all.insert(suffixed);
|
||||
}
|
||||
|
||||
for(int j = 0; j < word.length(); j++){
|
||||
auto edited = word.mid(0, j) + ALPHABET.mid(i, 1) + word.mid(j + 1, word.length() - j);
|
||||
all.insert(edited);
|
||||
}
|
||||
}
|
||||
|
||||
// 1-edit distance words (i.e., removed characters)
|
||||
if(includeDeletions){
|
||||
for(int j = 0; j < word.length(); j++){
|
||||
auto deleted = word.mid(0, j) + word.mid(j + 1, word.length() - j);
|
||||
all.insert(deleted);
|
||||
}
|
||||
}
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
QMap<quint32, QString> candidates(QString word, bool includeTwoEdits){
|
||||
// one edit
|
||||
QSet<QString> one = oneEdit(word, true, true);
|
||||
|
||||
// two edits
|
||||
QSet<QString> two;
|
||||
if(includeTwoEdits){
|
||||
foreach(auto w, one){
|
||||
two |= oneEdit(w, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
// existence check
|
||||
QMap<quint32, QString> m;
|
||||
|
||||
quint32 index;
|
||||
foreach(auto w, one | two){
|
||||
if(JSC::exists(w, &index)){
|
||||
m[index] = w;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
QStringList JSCChecker::suggestions(QString word, int n, bool *pFound){
|
||||
QStringList s;
|
||||
|
||||
qDebug() << "computing suggestions for word" << word;
|
||||
|
||||
QMap<quint32, QString> m;
|
||||
|
||||
bool prefixFound = false;
|
||||
|
||||
// lookup actual word prefix that is not a single character
|
||||
quint32 index = JSC::lookup(word, &prefixFound);
|
||||
if(prefixFound){
|
||||
auto t = JSC::map[index];
|
||||
if(t.size > 1){
|
||||
m[index] = QString::fromLatin1(t.str, t.size);
|
||||
}
|
||||
}
|
||||
|
||||
// compute suggestion candidates
|
||||
m.unite(candidates(word, false));
|
||||
|
||||
// return in order of probability (i.e., index rank)
|
||||
int i = 0;
|
||||
foreach(auto key, m.uniqueKeys()){
|
||||
if(i >= n){
|
||||
break;
|
||||
}
|
||||
qDebug() << "suggest" << m[key] << key;
|
||||
s.append(m[key]);
|
||||
i++;
|
||||
}
|
||||
|
||||
if(pFound) *pFound = prefixFound;
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef JSC_CHECKER_H
|
||||
#define JSC_CHECKER_H
|
||||
|
||||
/**
|
||||
* (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
**/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QTextEdit;
|
||||
|
||||
class JSCChecker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit JSCChecker(QObject *parent = nullptr);
|
||||
|
||||
static void checkRange(QTextEdit * edit, int start, int end);
|
||||
static QStringList suggestions(QString word, int n, bool *pFound);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // JSC_CHECKER_H
|
||||
+49
-49
@@ -48,50 +48,50 @@ subroutine foxgen()
|
||||
|
||||
do n=1,nslots
|
||||
i3b=i3bit(n)
|
||||
if(i3b.eq.0) then
|
||||
msg=cmsg(n)(1:22) !Standard FT8 message
|
||||
else
|
||||
i1=index(cmsg(n),' ') !Special Fox message
|
||||
i2=index(cmsg(n),';')
|
||||
i3=index(cmsg(n),'<')
|
||||
i4=index(cmsg(n),'>')
|
||||
msg=cmsg(n)(1:i1)//cmsg(n)(i2+1:i3-2)//' '
|
||||
read(cmsg(n)(i4+2:i4+4),*) irpt
|
||||
endif
|
||||
call genft8(msg,mygrid,bcontest,0,msgsent,msgbits,itone)
|
||||
!if(i3b.eq.0) then
|
||||
msg=cmsg(n)(1:12) !Standard FT8 message
|
||||
!else
|
||||
! i1=index(cmsg(n),' ') !Special Fox message
|
||||
! i2=index(cmsg(n),';')
|
||||
! i3=index(cmsg(n),'<')
|
||||
! i4=index(cmsg(n),'>')
|
||||
! msg=cmsg(n)(1:i1)//cmsg(n)(i2+1:i3-2)//' '
|
||||
! read(cmsg(n)(i4+2:i4+4),*) irpt
|
||||
!endif
|
||||
call genft8(msg,mygrid,bcontest,i3b,msgsent,msgbits,itone)
|
||||
! print*,'Foxgen:',n,cmsg(n),msgsent
|
||||
|
||||
if(i3b.eq.1) then
|
||||
icrc10=crc10(c_loc(mycall),12)
|
||||
nrpt=irpt+30
|
||||
write(cbits,1001) msgbits(1:56),icrc10,nrpt,i3b,0
|
||||
1001 format(56b1.1,b10.10,b6.6,b3.3,b12.12)
|
||||
read(cbits,1002) msgbits
|
||||
1002 format(87i1)
|
||||
|
||||
cb88=cbits//'0'
|
||||
read(cb88,1003) i1Msg8BitBytes(1:11)
|
||||
1003 format(11b8)
|
||||
icrc12=crc12(c_loc(i1Msg8BitBytes),11)
|
||||
! icrc12=xor(icrc12, 41) ! TODO: jsherer - could change the crc here
|
||||
|
||||
write(cbits,1001) msgbits(1:56),icrc10,nrpt,i3b,icrc12
|
||||
read(cbits,1002) msgbits
|
||||
|
||||
call encode174(msgbits,codeword) !Encode the test message
|
||||
|
||||
! Message structure: S7 D29 S7 D29 S7
|
||||
itone(1:7)=icos7
|
||||
itone(36+1:36+7)=icos7
|
||||
itone(NN-6:NN)=icos7
|
||||
k=7
|
||||
do j=1,ND
|
||||
i=3*j -2
|
||||
k=k+1
|
||||
if(j.eq.30) k=k+7
|
||||
itone(k)=codeword(i)*4 + codeword(i+1)*2 + codeword(i+2)
|
||||
enddo
|
||||
endif
|
||||
!! if(i3b.eq.1) then
|
||||
!! icrc10=crc10(c_loc(mycall),12)
|
||||
!! nrpt=irpt+30
|
||||
!! write(cbits,1001) msgbits(1:56),icrc10,nrpt,i3b,0
|
||||
!! 1001 format(56b1.1,b10.10,b6.6,b3.3,b12.12)
|
||||
!! read(cbits,1002) msgbits
|
||||
!! 1002 format(87i1)
|
||||
!!
|
||||
!! cb88=cbits//'0'
|
||||
!! read(cb88,1003) i1Msg8BitBytes(1:11)
|
||||
!! 1003 format(11b8)
|
||||
!! icrc12=crc12(c_loc(i1Msg8BitBytes),11)
|
||||
!! ! icrc12=xor(icrc12, 41) ! TODO: jsherer - could change the crc here
|
||||
!!
|
||||
!! write(cbits,1001) msgbits(1:56),icrc10,nrpt,i3b,icrc12
|
||||
!! read(cbits,1002) msgbits
|
||||
!!
|
||||
!! call encode174(msgbits,codeword) !Encode the test message
|
||||
!!
|
||||
!! ! Message structure: S7 D29 S7 D29 S7
|
||||
!! itone(1:7)=icos7
|
||||
!! itone(36+1:36+7)=icos7
|
||||
!! itone(NN-6:NN)=icos7
|
||||
!! k=7
|
||||
!! do j=1,ND
|
||||
!! i=3*j -2
|
||||
!! k=k+1
|
||||
!! if(j.eq.30) k=k+7
|
||||
!! itone(k)=codeword(i)*4 + codeword(i+1)*2 + codeword(i+2)
|
||||
!! enddo
|
||||
!! endif
|
||||
|
||||
! Make copies of itone() and msgbits() for ft8sim
|
||||
itone2=itone
|
||||
@@ -117,13 +117,13 @@ subroutine foxgen()
|
||||
! call plotspec(1,wave) !Plot the spectrum
|
||||
|
||||
! Apply compression
|
||||
! rms=sqrt(dot_product(wave,wave)/kz)
|
||||
! wave=wave/rms
|
||||
! do i=1,NWAVE
|
||||
! wave(i)=h1(wave(i))
|
||||
! enddo
|
||||
! peak2=maxval(abs(wave))
|
||||
! wave=wave/peak2
|
||||
rms=sqrt(dot_product(wave,wave)/kz)
|
||||
wave=wave/rms
|
||||
do i=1,NWAVE
|
||||
wave(i)=h1(wave(i))
|
||||
enddo
|
||||
peak2=maxval(abs(wave))
|
||||
wave=wave/peak2
|
||||
|
||||
! call plotspec(2,wave) !Plot the spectrum
|
||||
|
||||
|
||||
+10
-21
@@ -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,22 +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("JS8",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("JS8",Qt::CaseInsensitive)==0) ||
|
||||
(q.mode.compare("FT8",Qt::CaseInsensitive)==0))
|
||||
)
|
||||
|| (mode.compare(q.mode,Qt::CaseInsensitive)==0)
|
||||
|| (mode=="")
|
||||
|| (q.mode=="")
|
||||
)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -176,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
|
||||
@@ -186,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");
|
||||
@@ -224,7 +213,7 @@ bool ADIF::addQSOToFile(QByteArray const& ADIF_record)
|
||||
{
|
||||
QTextStream out(&f2);
|
||||
if (f2.size()==0)
|
||||
out << "WSJT-X ADIF Export<eoh>" << endl; // new file
|
||||
out << "JS8Call ADIF Export<eoh>" << endl; // new file
|
||||
|
||||
out << ADIF_record << " <eor>" << endl;
|
||||
f2.close();
|
||||
|
||||
+4
-4
@@ -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;
|
||||
|
||||
+5
-6
@@ -50,8 +50,8 @@ void LogBook::_setAlreadyWorkedFromLog()
|
||||
}
|
||||
}
|
||||
|
||||
bool LogBook::hasWorkedBefore(const QString &call, const QString &band, const QString &mode){
|
||||
return _log.match(call, band, mode);
|
||||
bool LogBook::hasWorkedBefore(const QString &call, const QString &band){
|
||||
return _log.match(call, band);
|
||||
}
|
||||
|
||||
void LogBook::match(/*in*/const QString call,
|
||||
@@ -61,9 +61,8 @@ void LogBook::match(/*in*/const QString call,
|
||||
{
|
||||
if (call.length() > 0)
|
||||
{
|
||||
QString currentMode = ""; // match any mode
|
||||
QString currentBand = ""; // match any band
|
||||
callWorkedBefore = _log.match(call,currentBand,currentMode);
|
||||
callWorkedBefore = _log.match(call,currentBand);
|
||||
countryName = _countries.find(call);
|
||||
|
||||
if (countryName.length() > 0) // country was found
|
||||
@@ -76,9 +75,9 @@ void LogBook::match(/*in*/const QString call,
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
_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
-2
@@ -20,12 +20,12 @@ class LogBook
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
bool hasWorkedBefore(const QString &call, const QString &band, const QString &mode);
|
||||
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;
|
||||
|
||||
+10
-6
@@ -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().toUpper();
|
||||
hisGrid=ui->grid->text().toUpper();
|
||||
mode=ui->mode->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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -152,6 +152,9 @@
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -107,7 +107,6 @@ int main(int argc, char *argv[])
|
||||
// that GUI has correct l18n
|
||||
|
||||
// Override programs executable basename as application name.
|
||||
//a.setApplicationName ("WSJT-X");
|
||||
a.setApplicationName("JS8Call");
|
||||
a.setApplicationVersion (version ());
|
||||
|
||||
|
||||
+1393
-431
File diff suppressed because it is too large
Load Diff
+58
-16
@@ -90,6 +90,7 @@ class Detector;
|
||||
class MultiSettings;
|
||||
class EqualizationToolsDialog;
|
||||
class DecodedText;
|
||||
class JSCChecker;
|
||||
|
||||
using namespace std;
|
||||
typedef std::function<void()> Callback;
|
||||
@@ -130,6 +131,8 @@ public slots:
|
||||
void msgAvgDecode2();
|
||||
void fastPick(int x0, int x1, int y);
|
||||
|
||||
void playSoundNotification(const QString &path);
|
||||
bool hasExistingMessageBufferToMe(int *pOffset);
|
||||
bool hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffset);
|
||||
void logCallActivity(CallDetail d, bool spot=true);
|
||||
QString lookupCallInCompoundCache(QString const &call);
|
||||
@@ -150,8 +153,8 @@ public slots:
|
||||
void restoreMessage();
|
||||
void initializeDummyData();
|
||||
bool ensureCallsignSet(bool alert=true);
|
||||
bool ensureSelcalCallsignSelected(bool alert=true);
|
||||
bool ensureKeyNotStuck(QString const& text);
|
||||
bool ensureNotIdle();
|
||||
void createMessage(QString const& text);
|
||||
void createMessageTransmitQueue(QString const& text);
|
||||
void resetMessageTransmitQueue();
|
||||
@@ -170,8 +173,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_Auto_Reply_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_Band_Heartbeats_and_ACKs_triggered(bool checked);
|
||||
void on_actionShow_Call_Activity_triggered(bool checked);
|
||||
void on_actionShow_Waterfall_triggered(bool checked);
|
||||
void on_actionShow_Waterfall_Controls_triggered(bool checked);
|
||||
@@ -185,6 +194,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();
|
||||
@@ -265,13 +275,22 @@ 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 sendHeartbeatAck(QString to, int snr);
|
||||
void on_hbMacroButton_toggled(bool checked);
|
||||
void on_hbMacroButton_clicked();
|
||||
void sendCQ(bool repeat=false);
|
||||
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);
|
||||
@@ -281,6 +300,7 @@ private slots:
|
||||
void buildQueryMenu(QMenu *, QString callsign);
|
||||
QMap<QString, QString> buildMacroValues();
|
||||
QString replaceMacros(QString const &text, QMap<QString, QString> values, bool prune);
|
||||
void buildSuggestionsMenu(QMenu *menu, QTextEdit *edit, const QPoint &point);
|
||||
void buildSavedMessagesMenu(QMenu *menu);
|
||||
void buildRelayMenu(QMenu *menu);
|
||||
QAction* buildRelayAction(QString call);
|
||||
@@ -302,12 +322,8 @@ private slots:
|
||||
bool prepareNextMessageFrame();
|
||||
bool isFreqOffsetFree(int f, int bw);
|
||||
int findFreeFreqOffset(int fmin, int fmax, int bw);
|
||||
void scheduleHeartbeat(bool first=false);
|
||||
void pauseHeartbeat();
|
||||
void unpauseHeartbeat();
|
||||
void checkHeartbeat();
|
||||
void prepareHeartbeat();
|
||||
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();
|
||||
@@ -318,10 +334,9 @@ private slots:
|
||||
void on_tuneButton_clicked (bool);
|
||||
void on_pbR2T_clicked();
|
||||
void on_pbT2R_clicked();
|
||||
void on_heartbeatButton_clicked();
|
||||
void on_selcalButton_clicked();
|
||||
void on_turboButton_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
|
||||
@@ -342,6 +357,12 @@ 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_tuneButton_toggled(bool checked);
|
||||
void on_spotButton_toggled(bool checked);
|
||||
|
||||
void on_actionMessage_averaging_triggered();
|
||||
void on_actionFox_Log_triggered();
|
||||
void on_actionInclude_averaging_toggled (bool);
|
||||
@@ -356,6 +377,7 @@ private slots:
|
||||
void on_cbCQonly_toggled(bool b);
|
||||
void on_cbFirst_toggled(bool b);
|
||||
void on_cbAutoSeq_toggled(bool b);
|
||||
void emitPTT(bool on);
|
||||
void networkMessage(Message const &message);
|
||||
void sendNetworkMessage(QString const &type, QString const &message);
|
||||
void sendNetworkMessage(QString const &type, QString const &message, const QMap<QString, QVariant> ¶ms);
|
||||
@@ -648,7 +670,7 @@ private:
|
||||
QTimer minuteTimer;
|
||||
QTimer splashTimer;
|
||||
QTimer p1Timer;
|
||||
QTimer heartbeatTimer;
|
||||
QTimer repeatTimer;
|
||||
|
||||
QString m_path;
|
||||
QString m_baseCall;
|
||||
@@ -707,6 +729,7 @@ private:
|
||||
QString text;
|
||||
QString extra;
|
||||
float tdrift;
|
||||
QString relayPath;
|
||||
};
|
||||
|
||||
struct ActivityDetail
|
||||
@@ -731,6 +754,10 @@ private:
|
||||
QList<ActivityDetail> msgs;
|
||||
};
|
||||
|
||||
int m_bandActivityWidth;
|
||||
int m_callActivityWidth;
|
||||
int m_textActivityWidth;
|
||||
int m_waterfallHeight;
|
||||
bool m_bandActivityWasVisible;
|
||||
bool m_rxDirty;
|
||||
bool m_rxDisplayDirty;
|
||||
@@ -790,10 +817,14 @@ private:
|
||||
QQueue<QString> m_txHeartbeatQueue; // ping frames to be sent
|
||||
QMap<QString, QDateTime> m_aprsCallCache;
|
||||
|
||||
QMap<QString, int> m_rxInboxCountCache; // call -> count
|
||||
|
||||
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
|
||||
|
||||
JSCChecker * m_checker;
|
||||
|
||||
QSet<QString> m_callSeenHeartbeat; // call
|
||||
int m_previousFreq;
|
||||
bool m_shouldRestoreFreq;
|
||||
@@ -818,9 +849,11 @@ private:
|
||||
QQueue<QString> m_foxQSOinProgress; //QSOs in progress: Fox has sent a report
|
||||
QQueue<qint64> m_foxRateQueue;
|
||||
|
||||
bool m_nextHeartbeatQueued = false;
|
||||
bool m_nextHeartPaused = false;
|
||||
bool m_hbHidden;
|
||||
int m_hbInterval;
|
||||
int m_cqInterval;
|
||||
QDateTime m_nextHeartbeat;
|
||||
QDateTime m_nextCQ;
|
||||
QDateTime m_dateTimeQSOOn;
|
||||
QDateTime m_dateTimeLastTX;
|
||||
|
||||
@@ -847,7 +880,6 @@ private:
|
||||
double m_toneSpacing;
|
||||
int m_firstDecode;
|
||||
QProgressDialog m_optimizingProgress;
|
||||
QTimer m_heartbeat;
|
||||
MessageClient * m_messageClient;
|
||||
PSK_Reporter *psk_Reporter;
|
||||
APRSISClient * m_aprsClient;
|
||||
@@ -886,8 +918,10 @@ private:
|
||||
void postDecode (bool is_new, QString const& message);
|
||||
void displayTransmit();
|
||||
void updateButtonDisplay();
|
||||
void updateRepeatButtonDisplay();
|
||||
void updateTextDisplay();
|
||||
void updateFrameCountEstimate(int count);
|
||||
void updateTextWordCheckerDisplay();
|
||||
void updateTextStatsDisplay(QString text, int count);
|
||||
void updateTxButtonDisplay();
|
||||
bool isMyCallIncluded(QString const &text);
|
||||
@@ -903,10 +937,14 @@ private:
|
||||
void observeTimeDeltaForAverage(float delta);
|
||||
void resetTimeDeltaAverage();
|
||||
void processRxActivity();
|
||||
void processIdleActivity();
|
||||
void processCompoundActivity();
|
||||
void processBufferedActivity();
|
||||
QString generateStatus();
|
||||
void processCommandActivity();
|
||||
void writeDirectedCommandToFile(CommandDetail d);
|
||||
QString inboxPath();
|
||||
void refreshInboxCounts();
|
||||
void addCommandToInbox(CommandDetail d);
|
||||
void processAlertReplyForCommand(CommandDetail d, QString from, QString cmd);
|
||||
void processSpots();
|
||||
void processTxQueue();
|
||||
@@ -934,6 +972,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);
|
||||
|
||||
+705
-757
File diff suppressed because it is too large
Load Diff
+31
@@ -27,6 +27,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
|
||||
m_plot2dGain {0},
|
||||
m_plot2dZero {0},
|
||||
m_nSubMode {0},
|
||||
m_turbo {false},
|
||||
m_Running {false},
|
||||
m_paintEventBusy {false},
|
||||
m_fftBinWidth {1500.0/2048.0},
|
||||
@@ -587,6 +588,9 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
|
||||
if(m_mode=="FT8"){
|
||||
int fwidth=XfromFreq(m_rxFreq+bw)-XfromFreq(m_rxFreq);
|
||||
#if TEST_FOX_WAVE_GEN
|
||||
int offset=XfromFreq(m_rxFreq+bw+10)-XfromFreq(m_rxFreq+bw);
|
||||
#endif
|
||||
QPainter overPainter(&m_DialOverlayPixmap);
|
||||
overPainter.initFrom(this);
|
||||
overPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
@@ -595,10 +599,22 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
overPainter.setPen(thinRed);
|
||||
overPainter.drawLine(0, 30, 0, m_h);
|
||||
overPainter.drawLine(fwidth+1, 30, fwidth+1, m_h);
|
||||
#if TEST_FOX_WAVE_GEN
|
||||
if(m_turbo){
|
||||
overPainter.drawLine(offset+fwidth+1, 30, offset+fwidth+1, m_h);
|
||||
overPainter.drawLine(offset+2*fwidth+1, 30, offset+2*fwidth+1, m_h);
|
||||
}
|
||||
#endif
|
||||
|
||||
overPainter.setPen(penRed);
|
||||
overPainter.drawLine(0, 26, fwidth, 26);
|
||||
overPainter.drawLine(0, 28, fwidth, 28);
|
||||
#if TEST_FOX_WAVE_GEN
|
||||
if(m_turbo){
|
||||
overPainter.drawLine(offset+fwidth, 26, offset+2*fwidth, 26);
|
||||
overPainter.drawLine(offset+fwidth, 28, offset+2*fwidth, 28);
|
||||
}
|
||||
#endif
|
||||
|
||||
QPainter hoverPainter(&m_HoverOverlayPixmap);
|
||||
hoverPainter.initFrom(this);
|
||||
@@ -607,6 +623,12 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
hoverPainter.setPen(QPen(Qt::white));
|
||||
hoverPainter.drawLine(0, 30, 0, m_h);
|
||||
hoverPainter.drawLine(fwidth+1, 30, fwidth+1, m_h);
|
||||
#if TEST_FOX_WAVE_GEN
|
||||
if(m_turbo){
|
||||
hoverPainter.drawLine(offset+fwidth+1, 30, offset+fwidth+1, m_h);
|
||||
hoverPainter.drawLine(offset+2*fwidth+1, 30, offset+2*fwidth+1, m_h);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DRAW_FREQ_OVERLAY
|
||||
int f = FreqfromX(m_lastMouseX);
|
||||
@@ -865,6 +887,15 @@ void CPlotter::setDialFreq(double d)
|
||||
void CPlotter::setRxBand(QString band)
|
||||
{
|
||||
m_rxBand=band;
|
||||
DrawOverlay();
|
||||
update();
|
||||
}
|
||||
|
||||
void CPlotter::setTurbo(bool turbo)
|
||||
{
|
||||
m_turbo=turbo;
|
||||
DrawOverlay();
|
||||
update();
|
||||
}
|
||||
|
||||
void CPlotter::setFlatten(bool b1, bool b2)
|
||||
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
void setFlatten(bool b1, bool b2);
|
||||
void setTol(int n);
|
||||
void setRxBand(QString band);
|
||||
void setTurbo(bool turbo);
|
||||
void setReference(bool b) {m_bReference = b;}
|
||||
bool Reference() const {return m_bReference;}
|
||||
void drawRed(int ia, int ib, float swide[]);
|
||||
@@ -147,6 +148,7 @@ private:
|
||||
QString m_rxBand;
|
||||
QString m_redFile;
|
||||
|
||||
bool m_turbo;
|
||||
bool m_Running;
|
||||
bool m_paintEventBusy;
|
||||
bool m_dataFromDisk;
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ void PSK_Reporter::dnsLookupResult(QHostInfo info)
|
||||
// qDebug() << "PSK Reporter IP: " << m_pskReporterAddress;
|
||||
|
||||
// deal with miss-configured settings that attempt to set a
|
||||
// Pskreporter Internet address for the WSJT-X UDP protocol
|
||||
// Pskreporter Internet address for the UDP protocol
|
||||
// server address
|
||||
m_messageClient->add_blocked_destination (m_pskReporterAddress);
|
||||
}
|
||||
|
||||
+114
-80
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "varicode.h"
|
||||
#include "jsc.h"
|
||||
#include "decodedtext.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@@ -49,30 +50,30 @@ QMap<QString, int> directed_cmds = {
|
||||
{"?", 0 }, // compat
|
||||
|
||||
{" QTH?", 1 }, // query qth
|
||||
{"@", 1 }, // compat
|
||||
|
||||
{" QTC?", 2 }, // query station message
|
||||
{"&", 2 }, // compat
|
||||
|
||||
{" HEARING?", 3 }, // query station calls heard
|
||||
|
||||
{" GRID?", 4 }, // query grid
|
||||
{"^", 4 }, // compat
|
||||
|
||||
{">", 5 }, // relay message
|
||||
|
||||
{" STATUS?", 6 }, // query idle message
|
||||
{"*", 6 }, // compat
|
||||
|
||||
{">", 5 }, // relay message
|
||||
{"#", 8 }, // all or nothing message
|
||||
{" STATUS", 7 }, // this is my status
|
||||
|
||||
//{"!", 7 }, // alert message
|
||||
//{"$", 3 }, // query station(s) heard
|
||||
//{"=", 9 }, // unused
|
||||
{" HEARING", 8 }, // these are the stations i'm hearing
|
||||
|
||||
{" ACTIVE", 10 }, // i have been active in the past 10 minutes
|
||||
{" IDLE", 11 }, // i have not been active in the past 10 minutes
|
||||
{" TU", 9 }, // thank you
|
||||
|
||||
{" HEARTBEAT", -1 }, // this is my ping (unused except for faux processing of pings as directed commands)
|
||||
{" HEARTBEAT ACK", 12 }, // i acknowledge your ping at this SNR
|
||||
{" HEARTBEAT REQ", 13 }, // can you transmit a ping to callsign?
|
||||
{" HB", -1 }, // this is my heartbeat (unused except for faux processing of HBs as directed commands)
|
||||
|
||||
// {" ", 10 }, // unused
|
||||
// {" ", 11 }, // unused
|
||||
|
||||
{" QUERY", 12 }, // issue a generic query
|
||||
{" QUERY CALL", 13 }, // can you transmit a ping to callsign?
|
||||
|
||||
{" APRS:", 14 }, // send an aprs packet
|
||||
|
||||
@@ -86,42 +87,43 @@ QMap<QString, int> directed_cmds = {
|
||||
{" RR", 21 }, // roger roger
|
||||
{" QSL?", 22 }, // do you copy?
|
||||
{" QSL", 23 }, // i copy
|
||||
{" QRZ?", 24 }, // who is calling me
|
||||
// {" ", 24 }, // unused
|
||||
{" SNR", 25 }, // seen a station at the provided snr
|
||||
{" NO", 26 }, // negative confirm
|
||||
{" YES", 27 }, // confirm
|
||||
{" 73", 28 }, // best regards, end of contact
|
||||
{" ACK", 29 }, // acknowledge
|
||||
{" AGN?", 30 }, // repeat message
|
||||
{" ", 31 }, // send freetext
|
||||
{" ", 31 }, // send freetext (weird artifact)
|
||||
{" ", 31 }, // send freetext
|
||||
};
|
||||
|
||||
QSet<int> allowed_cmds = {-1, 0, 1, 2, 3, 4, 5, 6, /*7,*/ 8, /*9,*/ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
||||
QSet<int> allowed_cmds = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /*10,*/ /*11,*/ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, /*24,*/ 25, 26, 27, 28, 29, 30, 31};
|
||||
|
||||
QSet<int> buffered_cmds = {3, 5, /*6,*/ /*7,*/ 8, 13, 14, 15};
|
||||
QSet<int> buffered_cmds = {3, 5, /*6,*/ /*7,*/ 12, 13, 14, 15};
|
||||
|
||||
QSet<int> snr_cmds = {12, 25};
|
||||
QSet<int> snr_cmds = {25, 29};
|
||||
|
||||
QMap<int, int> checksum_cmds = {
|
||||
{ 5, 16 },
|
||||
{ 8, 16 },
|
||||
{ 12, 16 },
|
||||
{ 13, 16 },
|
||||
{ 14, 16 },
|
||||
{ 15, 0 }
|
||||
};
|
||||
|
||||
QString callsign_pattern = QString("(?<callsign>[@]?[A-Z0-9/]+)");
|
||||
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:HEARTBEAT (ACK|REQ)|AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|QRZ[?]|SNR[?]|QTC[?]|QTH[?]|GRID[?]|STATUS[?]|(?:(?:ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|ACTIVE|IDLE)(?=[ ]|$))|[?*^&@#> ]))?");
|
||||
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|SNR[?]|QTC[?]|QTH[?]|GRID[?]|STATUS[?]|HEARING[?]|(?:(?:STATUS|HEARING|QUERY CALL|QUERY|ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|TU)(?=[ ]|$))|[?> ]))?");
|
||||
QString optional_grid_pattern = QString("(?<grid>\\s?[A-R]{2}[0-9]{2})?");
|
||||
QString optional_extended_grid_pattern = QString("^(?<grid>\\s?(?:[A-R]{2}[0-9]{2}(?:[A-X]{2}(?:[0-9]{2})?)*))?");
|
||||
QString optional_num_pattern = QString("(?<num>(?<=SNR|HEARTBEAT ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");
|
||||
QString optional_num_pattern = QString("(?<num>(?<=SNR|ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");
|
||||
|
||||
QRegularExpression directed_re("^" +
|
||||
callsign_pattern +
|
||||
optional_cmd_pattern +
|
||||
optional_num_pattern);
|
||||
|
||||
QRegularExpression heartbeat_re(R"(^\s*(?<type>CQCQCQ|CQ QRPP?|CQ DX|CQ TEST|CQ( CQ){0,2}|HEARTBEAT)(?:\s(?<grid>[A-R]{2}[0-9]{2}))?\b)");
|
||||
QRegularExpression heartbeat_re(R"(^\s*(?<type>CQCQCQ|CQ QRPP?|CQ DX|CQ TEST|CQ( CQ){0,2}|HB)(?:\s(?<grid>[A-R]{2}[0-9]{2}))?\b)");
|
||||
|
||||
QRegularExpression compound_re("^\\s*[`]" +
|
||||
callsign_pattern +
|
||||
@@ -203,6 +205,12 @@ QMap<quint32, QString> cqs = {
|
||||
{ 7, "CQ CQ CQ"},
|
||||
};
|
||||
|
||||
QMap<quint32, QString> hbs = {
|
||||
{ 0, "HB" }, // HB ACTIVE
|
||||
{ 1, "HB" }, // HB IDLE
|
||||
};
|
||||
|
||||
|
||||
QMap<int, int> dbm2mw = {
|
||||
{0 , 1}, // 1mW
|
||||
{3 , 2}, // 2mW
|
||||
@@ -289,6 +297,13 @@ QString Varicode::cqString(int number){
|
||||
return cqs[number];
|
||||
}
|
||||
|
||||
QString Varicode::hbString(int number){
|
||||
if(!hbs.contains(number)){
|
||||
return QString{};
|
||||
}
|
||||
return hbs[number];
|
||||
}
|
||||
|
||||
bool Varicode::startsWithCQ(QString text){
|
||||
foreach(auto cq, cqs.values()){
|
||||
if(text.startsWith(cq)){
|
||||
@@ -298,6 +313,15 @@ bool Varicode::startsWithCQ(QString text){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Varicode::startsWithHB(QString text){
|
||||
foreach(auto cq, hbs.values()){
|
||||
if(text.startsWith(cq)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString Varicode::formatSNR(int snr){
|
||||
if(snr < -60 || snr > 60){
|
||||
return QString();
|
||||
@@ -991,7 +1015,7 @@ quint8 Varicode::packCmd(quint8 cmd, quint8 num, bool *pPackedNum){
|
||||
// [1][X][6]
|
||||
// X = 0 == SNR
|
||||
// X = 1 == ACK
|
||||
value = ((1 << 1) | (int)(cmdStr == " HEARTBEAT ACK")) << 6;
|
||||
value = ((1 << 1) | (int)(cmdStr == " ACK")) << 6;
|
||||
value = value + (num & ((1<<6)-1));
|
||||
if(pPackedNum) *pPackedNum = true;
|
||||
} else {
|
||||
@@ -1009,7 +1033,7 @@ quint8 Varicode::unpackCmd(quint8 value, quint8 *pNum){
|
||||
|
||||
auto cmd = directed_cmds[" SNR"];
|
||||
if(value & (1<<6)){
|
||||
cmd = directed_cmds[" HEARTBEAT ACK"];
|
||||
cmd = directed_cmds[" ACK"];
|
||||
}
|
||||
return cmd;
|
||||
} else {
|
||||
@@ -1118,7 +1142,7 @@ bool Varicode::isCompoundCallsign(const QString &callsign){
|
||||
// CQCQCQ EM73
|
||||
// CQ DX EM73
|
||||
// CQ QRP EM73
|
||||
// HEARTBEAT EM73
|
||||
// HB EM73
|
||||
QString Varicode::packHeartbeatMessage(QString const &text, const QString &callsign, int *n){
|
||||
QString frame;
|
||||
|
||||
@@ -1132,8 +1156,8 @@ QString Varicode::packHeartbeatMessage(QString const &text, const QString &calls
|
||||
|
||||
// Heartbeat Alt Type
|
||||
// ---------------
|
||||
// 1 0 HEARTBEAT
|
||||
// 1 1 CQCQCQ
|
||||
// 1 0 HB
|
||||
// 1 1 CQ
|
||||
|
||||
auto type = parsedText.captured("type");
|
||||
auto isAlt = type.startsWith("CQ");
|
||||
@@ -1148,13 +1172,14 @@ QString Varicode::packHeartbeatMessage(QString const &text, const QString &calls
|
||||
packed_extra = Varicode::packGrid(extra);
|
||||
}
|
||||
|
||||
quint8 cqNumber = hbs.key(type, 0);
|
||||
|
||||
if(isAlt){
|
||||
packed_extra |= (1<<15);
|
||||
cqNumber = cqs.key(type, 0);
|
||||
}
|
||||
|
||||
quint8 cqNumber = cqs.key(type, 0);
|
||||
|
||||
frame = packCompoundFrame(callsign, FrameHeartbeat, packed_extra, cqNumber);
|
||||
frame = packCompoundFrame(callsign, Varicode::FrameHeartbeat, packed_extra, cqNumber);
|
||||
if(frame.isEmpty()){
|
||||
if(n) *n = 0;
|
||||
return frame;
|
||||
@@ -1165,12 +1190,12 @@ QString Varicode::packHeartbeatMessage(QString const &text, const QString &calls
|
||||
}
|
||||
|
||||
QStringList Varicode::unpackHeartbeatMessage(const QString &text, quint8 *pType, bool * isAlt, quint8 * pBits3){
|
||||
quint8 type = FrameHeartbeat;
|
||||
quint8 type = Varicode::FrameHeartbeat;
|
||||
quint16 num = nmaxgrid;
|
||||
quint8 bits3 = 0;
|
||||
|
||||
QStringList unpacked = unpackCompoundFrame(text, &type, &num, &bits3);
|
||||
if(unpacked.isEmpty() || type != FrameHeartbeat){
|
||||
if(unpacked.isEmpty() || type != Varicode::FrameHeartbeat){
|
||||
return QStringList{};
|
||||
}
|
||||
|
||||
@@ -1183,7 +1208,6 @@ QStringList Varicode::unpackHeartbeatMessage(const QString &text, quint8 *pType,
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
|
||||
// KN4CRD/XXXX EM73
|
||||
// XXXX/KN4CRD EM73
|
||||
// KN4CRD/P
|
||||
@@ -1210,7 +1234,7 @@ QString Varicode::packCompoundMessage(QString const &text, int *n){
|
||||
return frame;
|
||||
}
|
||||
|
||||
quint8 type = FrameCompound;
|
||||
quint8 type = Varicode::FrameCompound;
|
||||
quint16 extra = nmaxgrid;
|
||||
|
||||
qDebug() << "try pack cmd" << cmd << directed_cmds.contains(cmd) << Varicode::isCommandAllowed(cmd);
|
||||
@@ -1220,7 +1244,7 @@ QString Varicode::packCompoundMessage(QString const &text, int *n){
|
||||
qint8 inum = Varicode::packNum(num, nullptr);
|
||||
extra = nusergrid + Varicode::packCmd(directed_cmds[cmd], inum, &packedNum);
|
||||
|
||||
type = FrameCompoundDirected;
|
||||
type = Varicode::FrameCompoundDirected;
|
||||
} else if(!grid.isEmpty()){
|
||||
extra = Varicode::packGrid(grid);
|
||||
}
|
||||
@@ -1232,12 +1256,12 @@ QString Varicode::packCompoundMessage(QString const &text, int *n){
|
||||
}
|
||||
|
||||
QStringList Varicode::unpackCompoundMessage(const QString &text, quint8 *pType, quint8 *pBits3){
|
||||
quint8 type = FrameCompound;
|
||||
quint8 type = Varicode::FrameCompound;
|
||||
quint16 extra = nmaxgrid;
|
||||
quint8 bits3 = 0;
|
||||
|
||||
QStringList unpacked = unpackCompoundFrame(text, &type, &extra, &bits3);
|
||||
if(unpacked.isEmpty() || (type != FrameCompound && type != FrameCompoundDirected)){
|
||||
if(unpacked.isEmpty() || (type != Varicode::FrameCompound && type != Varicode::FrameCompoundDirected)){
|
||||
return QStringList {};
|
||||
}
|
||||
|
||||
@@ -1265,7 +1289,7 @@ QString Varicode::packCompoundFrame(const QString &callsign, quint8 type, quint1
|
||||
QString frame;
|
||||
|
||||
// needs to be a compound type...
|
||||
if(type == FrameDataCompressed || type == FrameDataUncompressed || type == FrameDirected){
|
||||
if(type == Varicode::FrameData || type == Varicode::FrameDirected){
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -1309,7 +1333,7 @@ QStringList Varicode::unpackCompoundFrame(const QString &text, quint8 *pType, qu
|
||||
quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3));
|
||||
|
||||
// needs to be a ping type...
|
||||
if(packed_flag == FrameDataCompressed || packed_flag == FrameDataUncompressed || packed_flag == FrameDirected){
|
||||
if(packed_flag == Varicode::FrameData || packed_flag == Varicode::FrameDirected){
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
@@ -1410,7 +1434,7 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &mycall
|
||||
cmdOut = cmd.trimmed();
|
||||
packed_cmd = directed_cmds[cmdOut];
|
||||
}
|
||||
quint8 packed_flag = FrameDirected;
|
||||
quint8 packed_flag = Varicode::FrameDirected;
|
||||
quint8 packed_extra = inum;
|
||||
|
||||
// [3][28][28][5],[2][6] = 72
|
||||
@@ -1438,7 +1462,7 @@ QStringList Varicode::unpackDirectedMessage(const QString &text, quint8 *pType){
|
||||
auto bits = Varicode::intToBits(Varicode::unpack72bits(text, &extra), 64);
|
||||
|
||||
quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3));
|
||||
if(packed_flag != FrameDirected){
|
||||
if(packed_flag != Varicode::FrameDirected){
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
@@ -1471,8 +1495,12 @@ QString packHuffMessage(const QString &input, int *n){
|
||||
|
||||
QString frame;
|
||||
|
||||
// [1][71] = 72
|
||||
QVector<bool> frameBits = {false};
|
||||
// [1][1][70] = 72
|
||||
// The first bit is a flag that indicates this is a data frame, technically encoded as [100]
|
||||
// but, since none of the other frame types start with a 0, we can drop the two zeros and use
|
||||
// them for encoding the first two bits of the actuall data sent. boom!
|
||||
// The second bit is a flag that indicates this is not compressed frame (huffman coding)
|
||||
QVector<bool> frameBits = {true, false};
|
||||
|
||||
int i = 0;
|
||||
|
||||
@@ -1525,8 +1553,12 @@ QString packCompressedMessage(const QString &input, int *n){
|
||||
|
||||
QString frame;
|
||||
|
||||
// [1][71] = 72
|
||||
QVector<bool> frameBits = {true};
|
||||
// [1][1][70] = 72
|
||||
// The first bit is a flag that indicates this is a data frame, technically encoded as [100]
|
||||
// but, since none of the other frame types start with a 1, we can drop the two zeros and use
|
||||
// them for encoding the first two bits of the actuall data sent. boom!
|
||||
// The second bit is a flag that indicates this is a compressed frame (dense coding)
|
||||
QVector<bool> frameBits = {true, true};
|
||||
|
||||
int i = 0;
|
||||
foreach(auto pair, JSC::compress(input)){
|
||||
@@ -1564,24 +1596,25 @@ QString packCompressedMessage(const QString &input, int *n){
|
||||
}
|
||||
|
||||
QString Varicode::packDataMessage(const QString &input, int *n){
|
||||
QString huffFrame;
|
||||
int huffChars = 0;
|
||||
huffFrame = packHuffMessage(input, &huffChars);
|
||||
QString huffFrame;
|
||||
int huffChars = 0;
|
||||
huffFrame = packHuffMessage(input, &huffChars);
|
||||
|
||||
QString compressedFrame;
|
||||
int compressedChars = 0;
|
||||
compressedFrame = packCompressedMessage(input, &compressedChars);
|
||||
QString compressedFrame;
|
||||
int compressedChars = 0;
|
||||
compressedFrame = packCompressedMessage(input, &compressedChars);
|
||||
|
||||
if(huffChars > compressedChars){
|
||||
if(n) *n = huffChars;
|
||||
return huffFrame;
|
||||
} else {
|
||||
if(n) *n = compressedChars;
|
||||
return compressedFrame;
|
||||
}
|
||||
if(huffChars > compressedChars){
|
||||
if(n) *n = huffChars;
|
||||
return huffFrame;
|
||||
} else {
|
||||
if(n) *n = compressedChars;
|
||||
return compressedFrame;
|
||||
}
|
||||
}
|
||||
|
||||
QString Varicode::unpackDataMessage(const QString &text, quint8 *pType){
|
||||
|
||||
QString Varicode::unpackDataMessage(const QString &text){
|
||||
QString unpacked;
|
||||
|
||||
if(text.length() < 12 || text.contains(" ")){
|
||||
@@ -1592,18 +1625,24 @@ QString Varicode::unpackDataMessage(const QString &text, quint8 *pType){
|
||||
quint64 value = Varicode::unpack72bits(text, &rem);
|
||||
auto bits = Varicode::intToBits(value, 64) + Varicode::intToBits(rem, 8);
|
||||
|
||||
bool isData = bits.at(0);
|
||||
if(!isData){
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
bits = bits.mid(1);
|
||||
|
||||
bool compressed = bits.at(0);
|
||||
|
||||
int n = bits.lastIndexOf(0);
|
||||
bits = bits.mid(1, n-1);
|
||||
|
||||
if(compressed){
|
||||
// partial word (s,c)-dense coding with code tables
|
||||
unpacked = JSC::decompress(bits);
|
||||
if(pType) *pType = Varicode::FrameDataCompressed;
|
||||
} else {
|
||||
// huff decode the bits (without escapes)
|
||||
unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);
|
||||
if(pType) *pType = Varicode::FrameDataUncompressed;
|
||||
}
|
||||
|
||||
return unpacked;
|
||||
@@ -1612,9 +1651,7 @@ QString Varicode::unpackDataMessage(const QString &text, quint8 *pType){
|
||||
// TODO: remove the dependence on providing all this data?
|
||||
QList<QPair<QString, int>> Varicode::buildMessageFrames(
|
||||
QString const& mycall,
|
||||
//QString const& basecall,
|
||||
QString const& mygrid,
|
||||
//bool compound,
|
||||
QString const& selectedCall,
|
||||
QString const& text
|
||||
){
|
||||
@@ -1654,9 +1691,9 @@ QList<QPair<QString, int>> Varicode::buildMessageFrames(
|
||||
// and if this isn't a raw message (starting with "`")... then...
|
||||
if(!selectedCall.isEmpty() && !line.startsWith(selectedCall) && !line.startsWith("`")){
|
||||
bool lineStartsWithBaseCall = (
|
||||
line.startsWith("@ALLCALL") ||
|
||||
line.contains("HEARTBEAT") ||
|
||||
Varicode::startsWithCQ(line)
|
||||
line.startsWith("@ALLCALL") ||
|
||||
Varicode::startsWithCQ(line) ||
|
||||
Varicode::startsWithHB(line)
|
||||
);
|
||||
|
||||
#if AUTO_PREPEND_DIRECTED_ALLOW_TEXT_CALLSIGNS
|
||||
@@ -1823,7 +1860,7 @@ QList<QPair<QString, int>> Varicode::buildMessageFrames(
|
||||
}
|
||||
|
||||
if(useDat){
|
||||
frames.append({ frame, Varicode::JS8CallData });
|
||||
frames.append({ frame, Varicode::JS8Call });
|
||||
line = line.mid(m);
|
||||
}
|
||||
}
|
||||
@@ -1839,16 +1876,12 @@ QList<QPair<QString, int>> Varicode::buildMessageFrames(
|
||||
|
||||
BuildMessageFramesThread::BuildMessageFramesThread(
|
||||
const QString &mycall,
|
||||
//const QString &basecall,
|
||||
const QString &mygrid,
|
||||
//bool compound,
|
||||
const QString &selectedCall,
|
||||
const QString &text, QObject *parent):
|
||||
QThread(parent),
|
||||
m_mycall{mycall},
|
||||
//m_basecall{basecall},
|
||||
m_mygrid{mygrid},
|
||||
//m_compound{compound},
|
||||
m_selectedCall{selectedCall},
|
||||
m_text{text}
|
||||
{
|
||||
@@ -1857,19 +1890,20 @@ BuildMessageFramesThread::BuildMessageFramesThread(
|
||||
void BuildMessageFramesThread::run(){
|
||||
auto results = Varicode::buildMessageFrames(
|
||||
m_mycall,
|
||||
//m_basecall,
|
||||
m_mygrid,
|
||||
//m_compound,
|
||||
m_selectedCall,
|
||||
m_text
|
||||
);
|
||||
|
||||
QList<QString> frames;
|
||||
QList<int> bits;
|
||||
foreach(auto pair, results){
|
||||
frames.append(pair.first);
|
||||
bits.append(pair.second);
|
||||
// TODO: jsherer - we wouldn't normally use decodedtext.h here... but it's useful for computing the actual frames transmitted.
|
||||
QStringList textList;
|
||||
qDebug() << "frames:";
|
||||
foreach(auto frame, results){
|
||||
auto dt = DecodedText(frame.first, frame.second);
|
||||
qDebug() << "->" << frame << dt.message() << Varicode::frameTypeString(dt.frameType());
|
||||
textList.append(dt.message());
|
||||
}
|
||||
|
||||
emit resultReady(frames, bits);
|
||||
auto transmitText = textList.join("");
|
||||
emit resultReady(transmitText, results.length());
|
||||
}
|
||||
|
||||
+18
-17
@@ -21,22 +21,28 @@ 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
|
||||
JS8CallData = 4, // [100] <- raw data frame (no frame type header)
|
||||
JS8CallFlag = 4, // [100] <- flagged frame (no frame type header)
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
000 = heartbeat
|
||||
001 = compound
|
||||
010 = compound directed
|
||||
011 = directed
|
||||
1XX = data, with the X lsb bits dropped
|
||||
*/
|
||||
enum FrameType {
|
||||
FrameUnknown = 255, // [11111111] <- only used as a sentinel
|
||||
FrameHeartbeat = 0, // [000]
|
||||
FrameCompound = 1, // [001]
|
||||
FrameCompoundDirected = 2, // [010]
|
||||
FrameDirected = 3, // [011]
|
||||
FrameReservedA = 4, // [100] <- Reserved for future use, likely an extension of one of these formats.
|
||||
FrameDataUncompressed = 5, // [101]
|
||||
FrameDataCompressed = 6, // [110]
|
||||
FrameReservedB = 7, // [111] <- Reserved for future use, likely binary data / other formats.
|
||||
FrameData = 4, // [10X] // but this only encodes the first 2 msb bits and drops the lsb
|
||||
FrameDataCompressed = 6, // [11X] // but this only encodes the first 2 msb bits and drops the lsb
|
||||
};
|
||||
|
||||
static const quint8 FrameTypeMax = 7;
|
||||
static const quint8 FrameTypeMax = 6;
|
||||
|
||||
static QString frameTypeString(quint8 type) {
|
||||
const char* FrameTypeStrings[] = {
|
||||
@@ -44,10 +50,9 @@ public:
|
||||
"FrameCompound",
|
||||
"FrameCompoundDirected",
|
||||
"FrameDirected",
|
||||
"FrameReservedA",
|
||||
"FrameDataUncompressed",
|
||||
"FrameData",
|
||||
"FrameUnknown", // 5
|
||||
"FrameDataCompressed",
|
||||
"FrameReservedB"
|
||||
};
|
||||
|
||||
if(type > FrameTypeMax){
|
||||
@@ -63,7 +68,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);
|
||||
|
||||
@@ -146,13 +153,11 @@ public:
|
||||
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 QString unpackDataMessage(QString const& text);
|
||||
|
||||
static QList<QPair<QString, int>> buildMessageFrames(
|
||||
QString const& mycall,
|
||||
//QString const& basecall,
|
||||
QString const& mygrid,
|
||||
//bool compound,
|
||||
QString const& selectedCall,
|
||||
QString const& text
|
||||
);
|
||||
@@ -164,21 +169,17 @@ class BuildMessageFramesThread : public QThread
|
||||
Q_OBJECT
|
||||
public:
|
||||
BuildMessageFramesThread(QString const& mycall,
|
||||
//QString const& basecall,
|
||||
QString const& mygrid,
|
||||
//bool compound,
|
||||
QString const& selectedCall,
|
||||
QString const& text,
|
||||
QObject *parent=nullptr);
|
||||
void run() override;
|
||||
signals:
|
||||
void resultReady(QStringList, QList<int>);
|
||||
void resultReady(QString, int);
|
||||
|
||||
private:
|
||||
QString m_mycall;
|
||||
//QString m_basecall;
|
||||
QString m_mygrid;
|
||||
//bool m_compound;
|
||||
QString m_selectedCall;
|
||||
QString m_text;
|
||||
};
|
||||
|
||||
Vendored
+16507
File diff suppressed because it is too large
Load Diff
Vendored
+220537
File diff suppressed because it is too large
Load Diff
Vendored
+11691
File diff suppressed because it is too large
Load Diff
Vendored
+628
@@ -0,0 +1,628 @@
|
||||
/*
|
||||
** 2006 June 7
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the SQLite interface for use by
|
||||
** shared libraries that want to be imported as extensions into
|
||||
** an SQLite instance. Shared libraries that intend to be loaded
|
||||
** as extensions by SQLite should #include this file instead of
|
||||
** sqlite3.h.
|
||||
*/
|
||||
#ifndef SQLITE3EXT_H
|
||||
#define SQLITE3EXT_H
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** The following structure holds pointers to all of the SQLite API
|
||||
** routines.
|
||||
**
|
||||
** WARNING: In order to maintain backwards compatibility, add new
|
||||
** interfaces to the end of this structure only. If you insert new
|
||||
** interfaces in the middle of this structure, then older different
|
||||
** versions of SQLite will not be able to load each other's shared
|
||||
** libraries!
|
||||
*/
|
||||
struct sqlite3_api_routines {
|
||||
void * (*aggregate_context)(sqlite3_context*,int nBytes);
|
||||
int (*aggregate_count)(sqlite3_context*);
|
||||
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
|
||||
int (*bind_double)(sqlite3_stmt*,int,double);
|
||||
int (*bind_int)(sqlite3_stmt*,int,int);
|
||||
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
|
||||
int (*bind_null)(sqlite3_stmt*,int);
|
||||
int (*bind_parameter_count)(sqlite3_stmt*);
|
||||
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
|
||||
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
|
||||
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
|
||||
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
|
||||
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
|
||||
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
|
||||
int (*busy_timeout)(sqlite3*,int ms);
|
||||
int (*changes)(sqlite3*);
|
||||
int (*close)(sqlite3*);
|
||||
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const char*));
|
||||
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const void*));
|
||||
const void * (*column_blob)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_count)(sqlite3_stmt*pStmt);
|
||||
const char * (*column_database_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_database_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_decltype)(sqlite3_stmt*,int i);
|
||||
const void * (*column_decltype16)(sqlite3_stmt*,int);
|
||||
double (*column_double)(sqlite3_stmt*,int iCol);
|
||||
int (*column_int)(sqlite3_stmt*,int iCol);
|
||||
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
|
||||
const char * (*column_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_origin_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_origin_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_table_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_table_name16)(sqlite3_stmt*,int);
|
||||
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
|
||||
const void * (*column_text16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_type)(sqlite3_stmt*,int iCol);
|
||||
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
|
||||
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
|
||||
int (*complete)(const char*sql);
|
||||
int (*complete16)(const void*sql);
|
||||
int (*create_collation)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_collation16)(sqlite3*,const void*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_function16)(sqlite3*,const void*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
|
||||
int (*data_count)(sqlite3_stmt*pStmt);
|
||||
sqlite3 * (*db_handle)(sqlite3_stmt*);
|
||||
int (*declare_vtab)(sqlite3*,const char*);
|
||||
int (*enable_shared_cache)(int);
|
||||
int (*errcode)(sqlite3*db);
|
||||
const char * (*errmsg)(sqlite3*);
|
||||
const void * (*errmsg16)(sqlite3*);
|
||||
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
|
||||
int (*expired)(sqlite3_stmt*);
|
||||
int (*finalize)(sqlite3_stmt*pStmt);
|
||||
void (*free)(void*);
|
||||
void (*free_table)(char**result);
|
||||
int (*get_autocommit)(sqlite3*);
|
||||
void * (*get_auxdata)(sqlite3_context*,int);
|
||||
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
|
||||
int (*global_recover)(void);
|
||||
void (*interruptx)(sqlite3*);
|
||||
sqlite_int64 (*last_insert_rowid)(sqlite3*);
|
||||
const char * (*libversion)(void);
|
||||
int (*libversion_number)(void);
|
||||
void *(*malloc)(int);
|
||||
char * (*mprintf)(const char*,...);
|
||||
int (*open)(const char*,sqlite3**);
|
||||
int (*open16)(const void*,sqlite3**);
|
||||
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
|
||||
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
|
||||
void *(*realloc)(void*,int);
|
||||
int (*reset)(sqlite3_stmt*pStmt);
|
||||
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_double)(sqlite3_context*,double);
|
||||
void (*result_error)(sqlite3_context*,const char*,int);
|
||||
void (*result_error16)(sqlite3_context*,const void*,int);
|
||||
void (*result_int)(sqlite3_context*,int);
|
||||
void (*result_int64)(sqlite3_context*,sqlite_int64);
|
||||
void (*result_null)(sqlite3_context*);
|
||||
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
|
||||
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_value)(sqlite3_context*,sqlite3_value*);
|
||||
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
|
||||
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
||||
const char*,const char*),void*);
|
||||
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
||||
char * (*xsnprintf)(int,char*,const char*,...);
|
||||
int (*step)(sqlite3_stmt*);
|
||||
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
||||
char const**,char const**,int*,int*,int*);
|
||||
void (*thread_cleanup)(void);
|
||||
int (*total_changes)(sqlite3*);
|
||||
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
|
||||
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
|
||||
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
|
||||
sqlite_int64),void*);
|
||||
void * (*user_data)(sqlite3_context*);
|
||||
const void * (*value_blob)(sqlite3_value*);
|
||||
int (*value_bytes)(sqlite3_value*);
|
||||
int (*value_bytes16)(sqlite3_value*);
|
||||
double (*value_double)(sqlite3_value*);
|
||||
int (*value_int)(sqlite3_value*);
|
||||
sqlite_int64 (*value_int64)(sqlite3_value*);
|
||||
int (*value_numeric_type)(sqlite3_value*);
|
||||
const unsigned char * (*value_text)(sqlite3_value*);
|
||||
const void * (*value_text16)(sqlite3_value*);
|
||||
const void * (*value_text16be)(sqlite3_value*);
|
||||
const void * (*value_text16le)(sqlite3_value*);
|
||||
int (*value_type)(sqlite3_value*);
|
||||
char *(*vmprintf)(const char*,va_list);
|
||||
/* Added ??? */
|
||||
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
|
||||
/* Added by 3.3.13 */
|
||||
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
int (*clear_bindings)(sqlite3_stmt*);
|
||||
/* Added by 3.4.1 */
|
||||
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
|
||||
void (*xDestroy)(void *));
|
||||
/* Added by 3.5.0 */
|
||||
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
|
||||
int (*blob_bytes)(sqlite3_blob*);
|
||||
int (*blob_close)(sqlite3_blob*);
|
||||
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
|
||||
int,sqlite3_blob**);
|
||||
int (*blob_read)(sqlite3_blob*,void*,int,int);
|
||||
int (*blob_write)(sqlite3_blob*,const void*,int,int);
|
||||
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*),
|
||||
void(*)(void*));
|
||||
int (*file_control)(sqlite3*,const char*,int,void*);
|
||||
sqlite3_int64 (*memory_highwater)(int);
|
||||
sqlite3_int64 (*memory_used)(void);
|
||||
sqlite3_mutex *(*mutex_alloc)(int);
|
||||
void (*mutex_enter)(sqlite3_mutex*);
|
||||
void (*mutex_free)(sqlite3_mutex*);
|
||||
void (*mutex_leave)(sqlite3_mutex*);
|
||||
int (*mutex_try)(sqlite3_mutex*);
|
||||
int (*open_v2)(const char*,sqlite3**,int,const char*);
|
||||
int (*release_memory)(int);
|
||||
void (*result_error_nomem)(sqlite3_context*);
|
||||
void (*result_error_toobig)(sqlite3_context*);
|
||||
int (*sleep)(int);
|
||||
void (*soft_heap_limit)(int);
|
||||
sqlite3_vfs *(*vfs_find)(const char*);
|
||||
int (*vfs_register)(sqlite3_vfs*,int);
|
||||
int (*vfs_unregister)(sqlite3_vfs*);
|
||||
int (*xthreadsafe)(void);
|
||||
void (*result_zeroblob)(sqlite3_context*,int);
|
||||
void (*result_error_code)(sqlite3_context*,int);
|
||||
int (*test_control)(int, ...);
|
||||
void (*randomness)(int,void*);
|
||||
sqlite3 *(*context_db_handle)(sqlite3_context*);
|
||||
int (*extended_result_codes)(sqlite3*,int);
|
||||
int (*limit)(sqlite3*,int,int);
|
||||
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
|
||||
const char *(*sql)(sqlite3_stmt*);
|
||||
int (*status)(int,int*,int*,int);
|
||||
int (*backup_finish)(sqlite3_backup*);
|
||||
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
|
||||
int (*backup_pagecount)(sqlite3_backup*);
|
||||
int (*backup_remaining)(sqlite3_backup*);
|
||||
int (*backup_step)(sqlite3_backup*,int);
|
||||
const char *(*compileoption_get)(int);
|
||||
int (*compileoption_used)(const char*);
|
||||
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void(*xDestroy)(void*));
|
||||
int (*db_config)(sqlite3*,int,...);
|
||||
sqlite3_mutex *(*db_mutex)(sqlite3*);
|
||||
int (*db_status)(sqlite3*,int,int*,int*,int);
|
||||
int (*extended_errcode)(sqlite3*);
|
||||
void (*log)(int,const char*,...);
|
||||
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
|
||||
const char *(*sourceid)(void);
|
||||
int (*stmt_status)(sqlite3_stmt*,int,int);
|
||||
int (*strnicmp)(const char*,const char*,int);
|
||||
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
|
||||
int (*wal_autocheckpoint)(sqlite3*,int);
|
||||
int (*wal_checkpoint)(sqlite3*,const char*);
|
||||
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
|
||||
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
|
||||
int (*vtab_config)(sqlite3*,int op,...);
|
||||
int (*vtab_on_conflict)(sqlite3*);
|
||||
/* Version 3.7.16 and later */
|
||||
int (*close_v2)(sqlite3*);
|
||||
const char *(*db_filename)(sqlite3*,const char*);
|
||||
int (*db_readonly)(sqlite3*,const char*);
|
||||
int (*db_release_memory)(sqlite3*);
|
||||
const char *(*errstr)(int);
|
||||
int (*stmt_busy)(sqlite3_stmt*);
|
||||
int (*stmt_readonly)(sqlite3_stmt*);
|
||||
int (*stricmp)(const char*,const char*);
|
||||
int (*uri_boolean)(const char*,const char*,int);
|
||||
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
|
||||
const char *(*uri_parameter)(const char*,const char*);
|
||||
char *(*xvsnprintf)(int,char*,const char*,va_list);
|
||||
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
|
||||
/* Version 3.8.7 and later */
|
||||
int (*auto_extension)(void(*)(void));
|
||||
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
|
||||
void(*)(void*),unsigned char);
|
||||
int (*cancel_auto_extension)(void(*)(void));
|
||||
int (*load_extension)(sqlite3*,const char*,const char*,char**);
|
||||
void *(*malloc64)(sqlite3_uint64);
|
||||
sqlite3_uint64 (*msize)(void*);
|
||||
void *(*realloc64)(void*,sqlite3_uint64);
|
||||
void (*reset_auto_extension)(void);
|
||||
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
|
||||
void(*)(void*), unsigned char);
|
||||
int (*strglob)(const char*,const char*);
|
||||
/* Version 3.8.11 and later */
|
||||
sqlite3_value *(*value_dup)(const sqlite3_value*);
|
||||
void (*value_free)(sqlite3_value*);
|
||||
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
|
||||
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
|
||||
/* Version 3.9.0 and later */
|
||||
unsigned int (*value_subtype)(sqlite3_value*);
|
||||
void (*result_subtype)(sqlite3_context*,unsigned int);
|
||||
/* Version 3.10.0 and later */
|
||||
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
int (*strlike)(const char*,const char*,unsigned int);
|
||||
int (*db_cacheflush)(sqlite3*);
|
||||
/* Version 3.12.0 and later */
|
||||
int (*system_errno)(sqlite3*);
|
||||
/* Version 3.14.0 and later */
|
||||
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
|
||||
char *(*expanded_sql)(sqlite3_stmt*);
|
||||
/* Version 3.18.0 and later */
|
||||
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
|
||||
/* Version 3.20.0 and later */
|
||||
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
|
||||
sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
|
||||
sqlite3_stmt**,const void**);
|
||||
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
|
||||
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
|
||||
void *(*value_pointer)(sqlite3_value*,const char*);
|
||||
int (*vtab_nochange)(sqlite3_context*);
|
||||
int (*value_nochange)(sqlite3_value*);
|
||||
const char *(*vtab_collation)(sqlite3_index_info*,int);
|
||||
/* Version 3.24.0 and later */
|
||||
int (*keyword_count)(void);
|
||||
int (*keyword_name)(int,const char**,int*);
|
||||
int (*keyword_check)(const char*,int);
|
||||
sqlite3_str *(*str_new)(sqlite3*);
|
||||
char *(*str_finish)(sqlite3_str*);
|
||||
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
|
||||
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
|
||||
void (*str_append)(sqlite3_str*, const char *zIn, int N);
|
||||
void (*str_appendall)(sqlite3_str*, const char *zIn);
|
||||
void (*str_appendchar)(sqlite3_str*, int N, char C);
|
||||
void (*str_reset)(sqlite3_str*);
|
||||
int (*str_errcode)(sqlite3_str*);
|
||||
int (*str_length)(sqlite3_str*);
|
||||
char *(*str_value)(sqlite3_str*);
|
||||
/* Version 3.25.0 and later */
|
||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*));
|
||||
/* Version 3.26.0 and later */
|
||||
const char *(*normalized_sql)(sqlite3_stmt*);
|
||||
};
|
||||
|
||||
/*
|
||||
** This is the function signature used for all extension entry points. It
|
||||
** is also defined in the file "loadext.c".
|
||||
*/
|
||||
typedef int (*sqlite3_loadext_entry)(
|
||||
sqlite3 *db, /* Handle to the database. */
|
||||
char **pzErrMsg, /* Used to set error string on failure. */
|
||||
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
|
||||
);
|
||||
|
||||
/*
|
||||
** The following macros redefine the API routines so that they are
|
||||
** redirected through the global sqlite3_api structure.
|
||||
**
|
||||
** This header file is also used by the loadext.c source file
|
||||
** (part of the main SQLite library - not an extension) so that
|
||||
** it can get access to the sqlite3_api_routines structure
|
||||
** definition. But the main library does not want to redefine
|
||||
** the API. So the redefinition macros are only valid if the
|
||||
** SQLITE_CORE macros is undefined.
|
||||
*/
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
|
||||
#endif
|
||||
#define sqlite3_bind_blob sqlite3_api->bind_blob
|
||||
#define sqlite3_bind_double sqlite3_api->bind_double
|
||||
#define sqlite3_bind_int sqlite3_api->bind_int
|
||||
#define sqlite3_bind_int64 sqlite3_api->bind_int64
|
||||
#define sqlite3_bind_null sqlite3_api->bind_null
|
||||
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
|
||||
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
|
||||
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
|
||||
#define sqlite3_bind_text sqlite3_api->bind_text
|
||||
#define sqlite3_bind_text16 sqlite3_api->bind_text16
|
||||
#define sqlite3_bind_value sqlite3_api->bind_value
|
||||
#define sqlite3_busy_handler sqlite3_api->busy_handler
|
||||
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
|
||||
#define sqlite3_changes sqlite3_api->changes
|
||||
#define sqlite3_close sqlite3_api->close
|
||||
#define sqlite3_collation_needed sqlite3_api->collation_needed
|
||||
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
|
||||
#define sqlite3_column_blob sqlite3_api->column_blob
|
||||
#define sqlite3_column_bytes sqlite3_api->column_bytes
|
||||
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
|
||||
#define sqlite3_column_count sqlite3_api->column_count
|
||||
#define sqlite3_column_database_name sqlite3_api->column_database_name
|
||||
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
|
||||
#define sqlite3_column_decltype sqlite3_api->column_decltype
|
||||
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
|
||||
#define sqlite3_column_double sqlite3_api->column_double
|
||||
#define sqlite3_column_int sqlite3_api->column_int
|
||||
#define sqlite3_column_int64 sqlite3_api->column_int64
|
||||
#define sqlite3_column_name sqlite3_api->column_name
|
||||
#define sqlite3_column_name16 sqlite3_api->column_name16
|
||||
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
|
||||
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
|
||||
#define sqlite3_column_table_name sqlite3_api->column_table_name
|
||||
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
|
||||
#define sqlite3_column_text sqlite3_api->column_text
|
||||
#define sqlite3_column_text16 sqlite3_api->column_text16
|
||||
#define sqlite3_column_type sqlite3_api->column_type
|
||||
#define sqlite3_column_value sqlite3_api->column_value
|
||||
#define sqlite3_commit_hook sqlite3_api->commit_hook
|
||||
#define sqlite3_complete sqlite3_api->complete
|
||||
#define sqlite3_complete16 sqlite3_api->complete16
|
||||
#define sqlite3_create_collation sqlite3_api->create_collation
|
||||
#define sqlite3_create_collation16 sqlite3_api->create_collation16
|
||||
#define sqlite3_create_function sqlite3_api->create_function
|
||||
#define sqlite3_create_function16 sqlite3_api->create_function16
|
||||
#define sqlite3_create_module sqlite3_api->create_module
|
||||
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
|
||||
#define sqlite3_data_count sqlite3_api->data_count
|
||||
#define sqlite3_db_handle sqlite3_api->db_handle
|
||||
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
|
||||
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
|
||||
#define sqlite3_errcode sqlite3_api->errcode
|
||||
#define sqlite3_errmsg sqlite3_api->errmsg
|
||||
#define sqlite3_errmsg16 sqlite3_api->errmsg16
|
||||
#define sqlite3_exec sqlite3_api->exec
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_expired sqlite3_api->expired
|
||||
#endif
|
||||
#define sqlite3_finalize sqlite3_api->finalize
|
||||
#define sqlite3_free sqlite3_api->free
|
||||
#define sqlite3_free_table sqlite3_api->free_table
|
||||
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
|
||||
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
|
||||
#define sqlite3_get_table sqlite3_api->get_table
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_global_recover sqlite3_api->global_recover
|
||||
#endif
|
||||
#define sqlite3_interrupt sqlite3_api->interruptx
|
||||
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
|
||||
#define sqlite3_libversion sqlite3_api->libversion
|
||||
#define sqlite3_libversion_number sqlite3_api->libversion_number
|
||||
#define sqlite3_malloc sqlite3_api->malloc
|
||||
#define sqlite3_mprintf sqlite3_api->mprintf
|
||||
#define sqlite3_open sqlite3_api->open
|
||||
#define sqlite3_open16 sqlite3_api->open16
|
||||
#define sqlite3_prepare sqlite3_api->prepare
|
||||
#define sqlite3_prepare16 sqlite3_api->prepare16
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_profile sqlite3_api->profile
|
||||
#define sqlite3_progress_handler sqlite3_api->progress_handler
|
||||
#define sqlite3_realloc sqlite3_api->realloc
|
||||
#define sqlite3_reset sqlite3_api->reset
|
||||
#define sqlite3_result_blob sqlite3_api->result_blob
|
||||
#define sqlite3_result_double sqlite3_api->result_double
|
||||
#define sqlite3_result_error sqlite3_api->result_error
|
||||
#define sqlite3_result_error16 sqlite3_api->result_error16
|
||||
#define sqlite3_result_int sqlite3_api->result_int
|
||||
#define sqlite3_result_int64 sqlite3_api->result_int64
|
||||
#define sqlite3_result_null sqlite3_api->result_null
|
||||
#define sqlite3_result_text sqlite3_api->result_text
|
||||
#define sqlite3_result_text16 sqlite3_api->result_text16
|
||||
#define sqlite3_result_text16be sqlite3_api->result_text16be
|
||||
#define sqlite3_result_text16le sqlite3_api->result_text16le
|
||||
#define sqlite3_result_value sqlite3_api->result_value
|
||||
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
|
||||
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
|
||||
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
|
||||
#define sqlite3_snprintf sqlite3_api->xsnprintf
|
||||
#define sqlite3_step sqlite3_api->step
|
||||
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
|
||||
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
|
||||
#define sqlite3_total_changes sqlite3_api->total_changes
|
||||
#define sqlite3_trace sqlite3_api->trace
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
|
||||
#endif
|
||||
#define sqlite3_update_hook sqlite3_api->update_hook
|
||||
#define sqlite3_user_data sqlite3_api->user_data
|
||||
#define sqlite3_value_blob sqlite3_api->value_blob
|
||||
#define sqlite3_value_bytes sqlite3_api->value_bytes
|
||||
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
|
||||
#define sqlite3_value_double sqlite3_api->value_double
|
||||
#define sqlite3_value_int sqlite3_api->value_int
|
||||
#define sqlite3_value_int64 sqlite3_api->value_int64
|
||||
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
|
||||
#define sqlite3_value_text sqlite3_api->value_text
|
||||
#define sqlite3_value_text16 sqlite3_api->value_text16
|
||||
#define sqlite3_value_text16be sqlite3_api->value_text16be
|
||||
#define sqlite3_value_text16le sqlite3_api->value_text16le
|
||||
#define sqlite3_value_type sqlite3_api->value_type
|
||||
#define sqlite3_vmprintf sqlite3_api->vmprintf
|
||||
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_overload_function sqlite3_api->overload_function
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
|
||||
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
|
||||
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
|
||||
#define sqlite3_blob_close sqlite3_api->blob_close
|
||||
#define sqlite3_blob_open sqlite3_api->blob_open
|
||||
#define sqlite3_blob_read sqlite3_api->blob_read
|
||||
#define sqlite3_blob_write sqlite3_api->blob_write
|
||||
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
|
||||
#define sqlite3_file_control sqlite3_api->file_control
|
||||
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
|
||||
#define sqlite3_memory_used sqlite3_api->memory_used
|
||||
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
|
||||
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
|
||||
#define sqlite3_mutex_free sqlite3_api->mutex_free
|
||||
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
|
||||
#define sqlite3_mutex_try sqlite3_api->mutex_try
|
||||
#define sqlite3_open_v2 sqlite3_api->open_v2
|
||||
#define sqlite3_release_memory sqlite3_api->release_memory
|
||||
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
|
||||
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
|
||||
#define sqlite3_sleep sqlite3_api->sleep
|
||||
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
|
||||
#define sqlite3_vfs_find sqlite3_api->vfs_find
|
||||
#define sqlite3_vfs_register sqlite3_api->vfs_register
|
||||
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
|
||||
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
|
||||
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
|
||||
#define sqlite3_result_error_code sqlite3_api->result_error_code
|
||||
#define sqlite3_test_control sqlite3_api->test_control
|
||||
#define sqlite3_randomness sqlite3_api->randomness
|
||||
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
|
||||
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
|
||||
#define sqlite3_limit sqlite3_api->limit
|
||||
#define sqlite3_next_stmt sqlite3_api->next_stmt
|
||||
#define sqlite3_sql sqlite3_api->sql
|
||||
#define sqlite3_status sqlite3_api->status
|
||||
#define sqlite3_backup_finish sqlite3_api->backup_finish
|
||||
#define sqlite3_backup_init sqlite3_api->backup_init
|
||||
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
|
||||
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
|
||||
#define sqlite3_backup_step sqlite3_api->backup_step
|
||||
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
|
||||
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
|
||||
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
|
||||
#define sqlite3_db_config sqlite3_api->db_config
|
||||
#define sqlite3_db_mutex sqlite3_api->db_mutex
|
||||
#define sqlite3_db_status sqlite3_api->db_status
|
||||
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
|
||||
#define sqlite3_log sqlite3_api->log
|
||||
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
|
||||
#define sqlite3_sourceid sqlite3_api->sourceid
|
||||
#define sqlite3_stmt_status sqlite3_api->stmt_status
|
||||
#define sqlite3_strnicmp sqlite3_api->strnicmp
|
||||
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
|
||||
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
|
||||
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
|
||||
#define sqlite3_wal_hook sqlite3_api->wal_hook
|
||||
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
|
||||
#define sqlite3_vtab_config sqlite3_api->vtab_config
|
||||
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
|
||||
/* Version 3.7.16 and later */
|
||||
#define sqlite3_close_v2 sqlite3_api->close_v2
|
||||
#define sqlite3_db_filename sqlite3_api->db_filename
|
||||
#define sqlite3_db_readonly sqlite3_api->db_readonly
|
||||
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
|
||||
#define sqlite3_errstr sqlite3_api->errstr
|
||||
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
|
||||
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
|
||||
#define sqlite3_stricmp sqlite3_api->stricmp
|
||||
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
|
||||
#define sqlite3_uri_int64 sqlite3_api->uri_int64
|
||||
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
|
||||
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
|
||||
/* Version 3.8.7 and later */
|
||||
#define sqlite3_auto_extension sqlite3_api->auto_extension
|
||||
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
|
||||
#define sqlite3_bind_text64 sqlite3_api->bind_text64
|
||||
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
|
||||
#define sqlite3_load_extension sqlite3_api->load_extension
|
||||
#define sqlite3_malloc64 sqlite3_api->malloc64
|
||||
#define sqlite3_msize sqlite3_api->msize
|
||||
#define sqlite3_realloc64 sqlite3_api->realloc64
|
||||
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
|
||||
#define sqlite3_result_blob64 sqlite3_api->result_blob64
|
||||
#define sqlite3_result_text64 sqlite3_api->result_text64
|
||||
#define sqlite3_strglob sqlite3_api->strglob
|
||||
/* Version 3.8.11 and later */
|
||||
#define sqlite3_value_dup sqlite3_api->value_dup
|
||||
#define sqlite3_value_free sqlite3_api->value_free
|
||||
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
|
||||
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
|
||||
/* Version 3.9.0 and later */
|
||||
#define sqlite3_value_subtype sqlite3_api->value_subtype
|
||||
#define sqlite3_result_subtype sqlite3_api->result_subtype
|
||||
/* Version 3.10.0 and later */
|
||||
#define sqlite3_status64 sqlite3_api->status64
|
||||
#define sqlite3_strlike sqlite3_api->strlike
|
||||
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
|
||||
/* Version 3.12.0 and later */
|
||||
#define sqlite3_system_errno sqlite3_api->system_errno
|
||||
/* Version 3.14.0 and later */
|
||||
#define sqlite3_trace_v2 sqlite3_api->trace_v2
|
||||
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
|
||||
/* Version 3.18.0 and later */
|
||||
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
|
||||
/* Version 3.20.0 and later */
|
||||
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
|
||||
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
|
||||
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
|
||||
#define sqlite3_result_pointer sqlite3_api->result_pointer
|
||||
#define sqlite3_value_pointer sqlite3_api->value_pointer
|
||||
/* Version 3.22.0 and later */
|
||||
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
|
||||
#define sqlite3_value_nochange sqlite3_api->value_nochange
|
||||
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
|
||||
/* Version 3.24.0 and later */
|
||||
#define sqlite3_keyword_count sqlite3_api->keyword_count
|
||||
#define sqlite3_keyword_name sqlite3_api->keyword_name
|
||||
#define sqlite3_keyword_check sqlite3_api->keyword_check
|
||||
#define sqlite3_str_new sqlite3_api->str_new
|
||||
#define sqlite3_str_finish sqlite3_api->str_finish
|
||||
#define sqlite3_str_appendf sqlite3_api->str_appendf
|
||||
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
|
||||
#define sqlite3_str_append sqlite3_api->str_append
|
||||
#define sqlite3_str_appendall sqlite3_api->str_appendall
|
||||
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
|
||||
#define sqlite3_str_reset sqlite3_api->str_reset
|
||||
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
||||
#define sqlite3_str_length sqlite3_api->str_length
|
||||
#define sqlite3_str_value sqlite3_api->str_value
|
||||
/* Version 3.25.0 and later */
|
||||
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
||||
/* Version 3.26.0 and later */
|
||||
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
/* This case when the file really is being compiled as a loadable
|
||||
** extension */
|
||||
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
|
||||
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
|
||||
# define SQLITE_EXTENSION_INIT3 \
|
||||
extern const sqlite3_api_routines *sqlite3_api;
|
||||
#else
|
||||
/* This case when the file is being statically linked into the
|
||||
** application */
|
||||
# define SQLITE_EXTENSION_INIT1 /*no-op*/
|
||||
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE3EXT_H */
|
||||
@@ -566,3 +566,7 @@ void WideGraph::setRedFile(QString fRed)
|
||||
{
|
||||
ui->widePlot->setRedFile(fRed);
|
||||
}
|
||||
|
||||
void WideGraph::setTurbo(bool turbo){
|
||||
ui->widePlot->setTurbo(turbo);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
void drawRed(int ia, int ib);
|
||||
void setVHF(bool bVHF);
|
||||
void setRedFile(QString fRed);
|
||||
void setTurbo(bool turbo);
|
||||
|
||||
signals:
|
||||
void freezeDecode2(int n);
|
||||
|
||||
+2
-2
@@ -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">
|
||||
|
||||
@@ -77,7 +77,10 @@ SOURCES += \
|
||||
DriftingDateTime.cpp \
|
||||
jsc.cpp \
|
||||
jsc_list.cpp \
|
||||
jsc_map.cpp
|
||||
jsc_map.cpp \
|
||||
jsc_checker.cpp \
|
||||
Message.cpp \
|
||||
Inbox.cpp
|
||||
|
||||
HEADERS += qt_helpers.hpp \
|
||||
pimpl_h.hpp pimpl_impl.hpp \
|
||||
@@ -105,7 +108,10 @@ HEADERS += qt_helpers.hpp \
|
||||
messagereplydialog.h \
|
||||
keyeater.h \
|
||||
DriftingDateTime.h \
|
||||
jsc.h
|
||||
jsc.h \
|
||||
jsc_checker.h \
|
||||
Message.h \
|
||||
Inbox.h
|
||||
|
||||
|
||||
INCLUDEPATH += qmake_only
|
||||
|
||||
Reference in New Issue
Block a user