diff --git a/application/config/migration.php b/application/config/migration.php
index 5d404393..688dfffe 100644
--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -21,7 +21,8 @@ $config['migration_enabled'] = TRUE;
| be upgraded / downgraded to.
|
*/
-$config['migration_version'] = 131;
+
+$config['migration_version'] = 132;
/*
|--------------------------------------------------------------------------
diff --git a/application/controllers/Qso.php b/application/controllers/Qso.php
index a6b2a267..a5053c5c 100755
--- a/application/controllers/Qso.php
+++ b/application/controllers/Qso.php
@@ -151,6 +151,72 @@ class QSO extends CI_Controller {
}
}
+ function winkeysettings() {
+
+ // Load model Winkey
+ $this->load->model('winkey');
+
+ // call settings from model winkey
+ $data['result'] = $this->winkey->settings($this->session->userdata('user_id'), $this->session->userdata('station_profile_id'));
+
+ if ($data['result'] == false) {
+ $this->load->view('qso/components/winkeysettings', $data);
+ } else {
+ $this->load->view('qso/components/winkeysettings_results', $data);
+ }
+ }
+
+ function cwmacrosave(){
+ // Get the data from the form
+ $function1_name = xss_clean($this->input->post('function1_name'));
+ $function1_macro = xss_clean($this->input->post('function1_macro'));
+
+ $function2_name = xss_clean($this->input->post('function2_name'));
+ $function2_macro = xss_clean($this->input->post('function2_macro'));
+
+ $function3_name = xss_clean($this->input->post('function3_name'));
+ $function3_macro = xss_clean($this->input->post('function3_macro'));
+
+ $function4_name = xss_clean($this->input->post('function4_name'));
+ $function4_macro = xss_clean($this->input->post('function4_macro'));
+
+ $function5_name = xss_clean($this->input->post('function5_name'));
+ $function5_macro = xss_clean($this->input->post('function5_macro'));
+
+ $data = [
+ 'user_id' => $this->session->userdata('user_id'),
+ 'station_location_id' => $this->session->userdata('station_profile_id'),
+ 'function1_name' => $function1_name,
+ 'function1_macro' => $function1_macro,
+ 'function2_name' => $function2_name,
+ 'function2_macro' => $function2_macro,
+ 'function3_name' => $function3_name,
+ 'function3_macro' => $function3_macro,
+ 'function4_name' => $function4_name,
+ 'function4_macro' => $function4_macro,
+ 'function5_name' => $function5_name,
+ 'function5_macro' => $function5_macro,
+ ];
+
+ // Load model Winkey
+ $this->load->model('winkey');
+
+ // save the data
+ $this->winkey->save($data);
+
+ echo "Macros Saved, Press Close and lets get sending!";
+ }
+
+ function cwmacros_json() {
+ // Load model Winkey
+ $this->load->model('winkey');
+
+ header('Content-Type: application/json; charset=utf-8');
+
+ // Call settings_json from model winkey
+ echo $this->winkey->settings_json($this->session->userdata('user_id'), $this->session->userdata('station_profile_id'));
+ }
+
function edit_ajax() {
$this->load->model('logbook_model');
diff --git a/application/migrations/132_create_cwmacros_table.php b/application/migrations/132_create_cwmacros_table.php
new file mode 100644
index 00000000..42940d36
--- /dev/null
+++ b/application/migrations/132_create_cwmacros_table.php
@@ -0,0 +1,116 @@
+db->table_exists('cwmacros')) {
+ $this->dbforge->add_field(array(
+ 'id' => array(
+ 'type' => 'BIGINT',
+ 'constraint' => 20,
+ 'unsigned' => TRUE,
+ 'auto_increment' => TRUE,
+ 'unique' => TRUE
+ ),
+
+ 'user_id' => array(
+ 'type' => 'BIGINT',
+ 'constraint' => 20,
+ 'unsigned' => TRUE,
+ 'auto_increment' => FALSE
+ ),
+
+ 'station_location_id' => array(
+ 'type' => 'BIGINT',
+ 'constraint' => 20,
+ 'unsigned' => TRUE,
+ 'auto_increment' => FALSE
+ ),
+
+ 'function1_name' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function1_macro' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function2_name' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function2_macro' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function3_name' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function3_macro' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function4_name' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function4_macro' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function5_name' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'function5_macro' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '255',
+ 'null' => TRUE
+ ),
+
+ 'modified' => array(
+ 'type' => 'timestamp',
+ 'null' => TRUE,
+ )
+ ));
+
+ $this->dbforge->add_key('id', TRUE);
+ $this->dbforge->add_key('user_id', TRUE);
+ $this->dbforge->add_key('station_location_id', TRUE);
+
+ $this->dbforge->create_table('cwmacros');
+ }
+ }
+
+ public function down()
+ {
+ $this->dbforge->drop_table('cwmacros');
+ }
+}
\ No newline at end of file
diff --git a/application/models/Winkey.php b/application/models/Winkey.php
new file mode 100644
index 00000000..43938fd4
--- /dev/null
+++ b/application/models/Winkey.php
@@ -0,0 +1,49 @@
+db->where('user_id', $user_id);
+ $this->db->where('station_location_id', $station_location_id);
+ $query = $this->db->get('cwmacros');
+
+ if ($query->num_rows() > 0) {
+ return $query->row();
+ } else {
+ return false;
+ }
+ }
+
+ public function settings_json($user_id, $station_location_id)
+ {
+ $this->db->where('user_id', $user_id);
+ $this->db->where('station_location_id', $station_location_id);
+ $query = $this->db->get('cwmacros');
+
+ if ($query->num_rows() > 0) {
+ // return $query->row() as json
+ return json_encode($query->row());
+ } else {
+ // return json with status not found
+ return json_encode(array('status' => 'not found'));
+ }
+ }
+
+ public function save($data)
+ {
+ $this->db->where('user_id', $data['user_id']);
+ $this->db->where('station_location_id', $data['station_location_id']);
+ $query = $this->db->get('cwmacros');
+
+ if ($query->num_rows() > 0) {
+ $this->db->where('user_id', $data['user_id']);
+ $this->db->where('station_location_id', $data['station_location_id']);
+ $this->db->update('cwmacros', $data);
+ } else {
+ $this->db->insert('cwmacros', $data);
+ }
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/application/views/interface_assets/footer.php b/application/views/interface_assets/footer.php
index 9c9e2afe..0c2fcb1d 100644
--- a/application/views/interface_assets/footer.php
+++ b/application/views/interface_assets/footer.php
@@ -7,6 +7,8 @@
var base_url = ""; // Base URL
var site_url = ""; // Site URL
var icon_dot_url = "assets/images/dot.png";
+ // get the user_callsign from session
+ var my_call = "session->userdata('user_callsign'); ?>".toUpperCase();
@@ -936,7 +938,9 @@ $(document).on('keypress',function(e) {
uri->segment(1) == "qso") { ?>
+
+
optionslib->get_option('dxcache_url') != ''){ ?>
@@ -953,6 +957,7 @@ $(document).on('keypress',function(e) {
});
});
+
+
diff --git a/application/views/qso/components/winkeysettings_results.php b/application/views/qso/components/winkeysettings_results.php
new file mode 100644
index 00000000..cd6031c9
--- /dev/null
+++ b/application/views/qso/components/winkeysettings_results.php
@@ -0,0 +1,96 @@
+
+
diff --git a/application/views/qso/index.php b/application/views/qso/index.php
index 02a4b811..abda171c 100755
--- a/application/views/qso/index.php
+++ b/application/views/qso/index.php
@@ -518,6 +518,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/js/sections/qso.js b/assets/js/sections/qso.js
index 48d90ffe..4efbb6a9 100644
--- a/assets/js/sections/qso.js
+++ b/assets/js/sections/qso.js
@@ -854,3 +854,17 @@ function resetDefaultQSOFields() {
$('#callsign-image-content').text("");
$('.dxccsummary').remove();
}
+
+function closeModal() {
+ var container = document.getElementById("modals-here")
+ var backdrop = document.getElementById("modal-backdrop")
+ var modal = document.getElementById("modal")
+
+ modal.classList.remove("show")
+ backdrop.classList.remove("show")
+
+ setTimeout(function() {
+ container.removeChild(backdrop)
+ container.removeChild(modal)
+ }, 200)
+}
\ No newline at end of file
diff --git a/assets/js/winkey.js b/assets/js/winkey.js
new file mode 100644
index 00000000..daa04398
--- /dev/null
+++ b/assets/js/winkey.js
@@ -0,0 +1,294 @@
+// Lets see if CW is selected
+
+const ModeSelected = document.getElementById('mode');
+
+if (location.protocol == 'http:') {
+ // Do something if the page is being served over SSL
+ $('#winkey').hide(); // Hide the CW buttons
+}
+
+if (ModeSelected.value == 'CW') {
+ // Show the CW buttons
+ $('#winkey').show();
+} else {
+ // Hide the CW buttons
+ $('#winkey').hide();
+}
+
+ModeSelected.addEventListener('change', (event) => {
+
+ if (event.target.value == 'CW') {
+ // Show the CW buttons
+ $('#winkey').show();
+
+ } else {
+ // Hide the CW buttons
+ $('#winkey').hide();
+ }
+});
+
+
+
+let function1Name, function1Macro, function2Name, function2Macro, function3Name, function3Macro, function4Name, function4Macro, function5Name, function5Macro;
+
+getMacros();
+
+document.addEventListener('keydown', function(event) {
+
+ if (event.key === 'F1') {
+ event.preventDefault();
+ morsekey_func1();
+ }
+
+ if (event.key === 'F2') {
+ event.preventDefault();
+ morsekey_func2();
+ }
+
+ if (event.key === 'F3') {
+ event.preventDefault();
+ morsekey_func3();
+ }
+
+ if (event.key === 'F4') {
+ event.preventDefault();
+ morsekey_func4();
+ }
+
+ if (event.key === 'F5') {
+ event.preventDefault();
+ morsekey_func5();
+ }
+ });
+
+let sendText = document.getElementById("sendText");
+let sendButton = document.getElementById("sendButton");
+let receiveText = document.getElementById("receiveText");
+let connectButton = document.getElementById("connectButton");
+let statusBar = document.getElementById("statusBar");
+
+//Couple the elements to the Events
+connectButton.addEventListener("click", clickConnect)
+sendButton.addEventListener("click", clickSend)
+helpButton.addEventListener("click", clickHelp)
+statusButton.addEventListener("click", clickStatus)
+
+//When the connectButton is pressed
+async function clickConnect() {
+ if (port) {
+ //if already connected, disconnect
+ disconnect();
+
+ } else {
+ //otherwise connect
+ await connect();
+ }
+}
+
+//Define outputstream, inputstream and port so they can be used throughout the sketch
+var outputStream, inputStream, port;
+navigator.serial.addEventListener('connect', e => {
+ statusBar.innerText = `Connected to ${e.port}`;
+ connectButton.innerText = "Disconnect"
+});
+
+navigator.serial.addEventListener('disconnect', e => {
+ statusBar.innerText = `Disconnected`;
+ connectButton.innerText = "Connect"
+});
+
+//Connect to the serial
+async function connect() {
+
+ //Optional filter to only see relevant boards
+ const filter = {
+ usbVendorId: 0x2341 // Arduino SA
+ };
+
+ //Try to connect to the Serial port
+ try {
+ port = await navigator.serial.requestPort(/*{ filters: [filter] }*/);
+ // Continue connecting to |port|.
+
+ // - Wait for the port to open.
+ await port.open({ baudRate: 1200 });
+
+ statusBar.innerText = "Connected";
+ connectButton.innerText = "Disconnect"
+
+ let decoder = new TextDecoderStream();
+ inputDone = port.readable.pipeTo(decoder.writable);
+ inputStream = decoder.readable;
+
+ const encoder = new TextEncoderStream();
+ outputDone = encoder.readable.pipeTo(port.writable);
+ outputStream = encoder.writable;
+
+ reader = inputStream.getReader();
+ readLoop();
+ } catch (e) {
+ //If the pipeTo error appears; clarify the problem by giving suggestions.
+ if (e == "TypeError: Cannot read property 'pipeTo' of undefined") {
+ e += "\n Use Google Chrome and enable-experimental-web-platform-features"
+ }
+ connectButton.innerText = "Connect"
+ statusBar.innerText = e;
+ }
+}
+
+//Write to the Serial port
+async function writeToStream(line) {
+ var enc = new TextEncoder(); // always utf-8
+
+ const writer = outputStream.getWriter();
+ writer.write(line);
+ writer.releaseLock();
+}
+
+//Disconnect from the Serial port
+async function disconnect() {
+
+ if (reader) {
+ await reader.cancel();
+ await inputDone.catch(() => { });
+ reader = null;
+ inputDone = null;
+ }
+ if (outputStream) {
+ await outputStream.getWriter().close();
+ await outputDone;
+ outputStream = null;
+ outputDone = null;
+ }
+ statusBar.innerText = "Disconnected";
+ connectButton.innerText = "Connect"
+ //Close the port.
+ await port.close();
+ port = null;
+}
+
+//When the send button is pressed
+function clickSend() {
+ writeToStream(sendText.value);
+ writeToStream("\r");
+
+ //and clear the input field, so it's clear it has been sent
+ sendText.value = "";
+
+}
+
+function morsekey_func1() {
+ console.log("F1: " + UpdateMacros(function1Macro));
+ writeToStream(UpdateMacros(function1Macro));
+ //and clear the input field, so it's clear it has been sent
+ sendText.value = "";
+}
+
+function morsekey_func2() {
+ console.log("F2: " + UpdateMacros(function2Macro));
+ writeToStream(UpdateMacros(function2Macro));
+ //and clear the input field, so it's clear it has been sent
+ sendText.value = "";
+}
+
+function morsekey_func3() {
+ console.log("F3: " + UpdateMacros(function3Macro));
+ writeToStream(UpdateMacros(function3Macro));
+ //and clear the input field, so it's clear it has been sent
+ sendText.value = "";
+}
+
+function morsekey_func4() {
+ console.log("F4: " + UpdateMacros(function4Macro));
+ writeToStream(UpdateMacros(function4Macro));
+ //and clear the input field, so it's clear it has been sent
+ sendText.value = "";
+}
+
+function morsekey_func5() {
+ console.log("F5: " + UpdateMacros(function5Macro));
+ writeToStream(UpdateMacros(function5Macro));
+ //and clear the input field, so it's clear it has been sent
+ sendText.value = "";
+}
+
+
+
+//Read the incoming data
+async function readLoop() {
+ while (true) {
+ const { value, done } = await reader.read();
+ if (done === true){
+ break;
+ }
+
+ console.log(value);
+ //When recieved something add it to the big textarea
+ receiveText.value += value;
+ //Scroll to the bottom of the text field
+ receiveText.scrollTop = receiveText.scrollHeight;
+ }
+}
+
+function closeModal() {
+ var container = document.getElementById("modals-here")
+ var backdrop = document.getElementById("modal-backdrop")
+ var modal = document.getElementById("modal")
+
+ modal.classList.remove("show")
+ backdrop.classList.remove("show")
+
+ getMacros();
+
+ setTimeout(function() {
+ container.removeChild(backdrop)
+ container.removeChild(modal)
+ }, 200)
+}
+
+function UpdateMacros(macrotext) {
+
+ // Get the values from the form set to uppercase
+ let CALL = document.getElementById("callsign").value.toUpperCase();
+ let RSTS = document.getElementById("rst_sent").value;
+
+ let newString;
+ newString = macrotext.replace(/\[MYCALL\]/g, my_call);
+ newString = newString.replace(/\[CALL\]/g, CALL);
+ newString = newString.replace(/\[RSTS\]/g, RSTS);
+ console.log(newString);
+ return newString;
+}
+
+// Call url and store the returned json data as variables
+function getMacros() {
+ fetch(base_url + 'index.php/qso/cwmacros_json')
+ .then(response => response.json())
+ .then(data => {
+ function1Name = data.function1_name;
+ function1Macro = data.function1_macro;
+ function2Name = data.function2_name;
+ function2Macro = data.function2_macro;
+ function3Name = data.function3_name;
+ function3Macro = data.function3_macro;
+ function4Name = data.function4_name;
+ function4Macro = data.function4_macro;
+ function5Name = data.function5_name;
+ function5Macro = data.function5_macro;
+
+ const morsekey_func1_Button = document.getElementById('morsekey_func1');
+ morsekey_func1_Button.textContent = 'F1 (' + function1Name + ')';
+
+ const morsekey_func2_Button = document.getElementById('morsekey_func2');
+ morsekey_func2_Button.textContent = 'F2 (' + function2Name + ')';
+
+ const morsekey_func3_Button = document.getElementById('morsekey_func3');
+ morsekey_func3_Button.textContent = 'F3 (' + function3Name + ')';
+
+ const morsekey_func4_Button = document.getElementById('morsekey_func4');
+ morsekey_func4_Button.textContent = 'F4 (' + function4Name + ')';
+
+ const morsekey_func5_Button = document.getElementById('morsekey_func5');
+ morsekey_func5_Button.textContent = 'F5 (' + function5Name + ')';
+ });
+}
\ No newline at end of file