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 @@
+
+
+

Winkey + + + + +

+
+ +
+
+ + + + + +

+ + +
+ +
+
+

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