Further improvements to SimpleFle

* show contest-exchange beneath RSTr/-s, as usual
* implement non-numeric contest-exchange
* warn, if xor contest-select / contest-data present
* introduce increment-mode, to be set by user
* add documentation
This commit is contained in:
DJ3CE
2025-01-11 02:30:23 +01:00
committed by DJ3CE
parent cc2fce9214
commit 9ad9e7c0f0
3 changed files with 140 additions and 20 deletions

View File

@@ -32,6 +32,7 @@
var lang_qso_simplefle_warning_missing_band_mode = "<?= __("Warning! You can't log the QSO List, because some QSO don't have band and/or mode defined!"); ?>";
var lang_qso_simplefle_warning_missing_time = "<?= __("Warning! You can't log the QSO List, because some QSO don't have a time defined!"); ?>";
var lang_qso_simplefle_warning_example_data = "<?= __("Attention! The Data Field containes example data. First Clear Logging Session!"); ?>";
var lang_qso_simplefle_warning_missing_contestid = "<?= __("Attention! Either you have set a contest, but included no exchange, or you have logged contest-data but did not select a contest."); ?>";
var lang_qso_simplefle_confirm_save_to_log = "<?= __("Are you sure that you want to add these QSO to the Log and clear the session?"); ?>";
var lang_qso_simplefle_success_save_to_log_header = "<?= __("QSO Logged!"); ?>";
var lang_qso_simplefle_success_save_to_log = "<?= __("The QSO were successfully logged in the logbook! Dupes were skipped."); ?>";
@@ -187,4 +188,4 @@
</div>
</div>
</div>
</div>
</div>

View File

@@ -25,5 +25,41 @@
day ++
df3et
</pre>
<p><?= __("Additional informations can be submitted in the following way:") ?></p>
<p><?= __("Notes:") ?></p>
<pre>
2112 dj3ce < comment >
</pre>
<p><?= __("Operator Name:") ?></p>
<pre>
2112 dj3ce @Cedric
</pre>
<p><?= __("QSL-message (Caution! Not visible in wavelog currently!):") ?></p>
<pre>
2112 dj3ce [tnx qso]
</pre>
<p><?= __("Contest exchange; serials or other exchange - or even both:") ?></p>
<pre>
2112 dj3ce ,1.12
2113 dj3ce ,LA.DL
2114 dj3ce ,12,LA.14.DL
2114 dj3ce .14 ,12 .DL ,LA
</pre>
<p><?= __("Received exchange has to be prefixed with a dot '.', sent exchange with a comma ','. The last to lines are equivalent - i.e. spaces don't matter as the order doesn't as well. Exchange you have sent will automatically be included in the next QSO, if it contains received exchange, or if you use a single comma ','. To automatically increment the sent serial, use ',++' and give an initial sent exchange. To deactivate, use ',+0':") ?></p>
<pre>
,++
2112 dj3ce ,1.12
2113 dk0mm .105
</pre>
<p><?= __("Here, the first qso uses the set serial 1, and the second will use 2 as the serial. If you want to wipe your sent exchange, use ',-':") ?></p>
<pre>
2115 dj3ce ,15,D23.1.F39
2116 dk0mm ,-,16.1015
</pre>
<p><?= __("First, all previous exchange is wiped, then only a serial is set. Otherwise the previous exchange 'D23' would have been set also.") ?></p>
<p><?= __("You may use the comment syntax, to fill adif-fields supported by the Wavelog-Import:") ?></p>
<pre>
2119 dj3ce <tx_pwr:50> <rx_pwr:750> <darc_dok:F39> <sfi:210> <rig:QCX> <...>
</pre>
<p><?= sprintf(__("A full summary of all commands and the necessary syntax can be found in %sthis article%s of our Wiki."), '<a href="https://github.com/wavelog/wavelog/wiki/SimpleFLE" target="_blank">', '</a>'); ?></p>

View File

@@ -226,6 +226,9 @@ function handleInput() {
var sotaWwff = "";
var srx = "";
var stx = "";
var stx_incr_mode = 0;
var prev_stx = "";
var prev_stx_string = "";
qsoList = [];
$("#qsoTable tbody").empty();
errors = [];
@@ -238,10 +241,11 @@ function handleInput() {
var rst_r = null;
var gridsquare = "";
var srx = "";
var stx = "";
var call_rec = false;
var add_info = {};
// First, search for <...>-Patterns, which may contain comments (... or additional fields)
// First, search for <...>- and [...]-Patterns, which may contain comments (... or additional fields) / qsl-notes
let addInfoMatches = row.matchAll(/<([^>]*)>|\[([^\]]*)\]/g);
addInfoMatches.forEach((item) => {
row = row.replace(item[0], "");
@@ -326,21 +330,60 @@ function handleInput() {
} else {
rst_r = item;
}
} else if (itemNumber > 0 && (parts = item.match(/^([\.,])(\d*)(,|([\.,])(\d+))?$/))) { // Contest ,*** .***
if (parts[1] == ',') {
stx = parts[2];
} else {
srx = parts[2];
}
if (parts.length > 3 && parts[3] !== undefined && parts[3] == ',') { // With ',' only increment stx
stx++;
} else if (parts.length > 4 && parts[4] !== undefined) {
if (parts[4] == ',') {
stx = parts[5];
} else {
srx = parts[5];
} else if (itemNumber > 0 && (parts = item.match(/^(([\.,])((\d*|\+[\+0]|-)|([A-Za-z0-9\/]+)))+$/))) { // Contest ,*** .***
// Caution! May be entered multiple times, and may contain empty tokens
// Iterate over all parts -- take care to behave exactly like entered with spaces
item.matchAll(/([\.,])((\d*|\+[\+0]|-)|([A-Za-z0-9\/]+))(?=$|[\.,])/g).forEach((exch) => {
var pre_stx = stx;
var pre_srx = srx;
switch (exch[1]+((exch[3]===undefined)?'s':'n')) { // [.,][sn]
case ".n": // Received serial
srx = exch[2];
break;
case ",n": // Sent serial
stx = exch[2];
break;
case ".s": // Received exchange
add_info.srx_string = exch[2];
break;
case ",s": // Sent exchange
add_info.stx_string = exch[2];
}
}
// Mode swith
if (stx == "++") {
stx = pre_stx;
stx_incr_mode = 1;
return; // no further processing of this (sub-)token here jumps to next pattern, if available
} else if (stx == "+0") {
stx = pre_stx;
stx_incr_mode = 0;
return; // no further processing of this (sub-)token here jumps to next pattern, if available
}
if (stx == '-') { // Wipe all sent exchange if '-'
stx = '';
prev_stx = '';
delete add_info.stx_string;
prev_stx_string = '';
}
// FLE paradima: Previous if not set - we have some sort of contest exchange, so
// re-apply previously set stx / stx_string if not already populated
if (prev_stx != '' && stx == '') {
stx = (prev_stx*1) + stx_incr_mode;
}
if (prev_stx_string != '' && add_info.stx_string === undefined) {
add_info.stx_string = prev_stx_string;
}
// Sanity check
if (srx == "++" || srx == "+0" || srx == '-') srx = pre_srx;
});
} else if (itemNumber > 0 && (parts = item.match(/(?<=^@)[A-Za-z]+/))) {
add_info.name = parts[0];
}
@@ -403,17 +446,34 @@ function handleInput() {
sotaWwffText = `W: ${sotaWwff}`;
}
const refs = [sotaWwffText,stx,srx].filter( (x) => x.length>0 || x>0 ).join(',');
// Contest exchange info: sent
let stx_info = "";
if (stx != '') {
stx_info += `<span data-bs-toggle="tooltip" class="badge text-bg-light">${stx}</span>`;
}
if (add_info.stx_string !== undefined && add_info.stx_string.length > 0) {
stx_info += `<span data-bs-toggle="tooltip" class="badge text-bg-light">${add_info.stx_string}</span>`;
}
// Contest exchange info: received
let srx_info = "";
if (srx != '') {
srx_info += `<span data-bs-toggle="tooltip" title="" class="badge text-bg-light">${srx}</span>`;
}
if (add_info.srx_string !== undefined && add_info.srx_string.length > 0) {
srx_info += `<span data-bs-toggle="tooltip" title="" class="badge text-bg-light">${add_info.srx_string}</span>`;
}
const tableRow = $(`<tr>
<td>${extraQsoDate}</td>
<td>${qsotime}</td>
<td>${callsign}</td>
<td><span data-bs-toggle="tooltip" data-placement="left" title="${freq}">${band}</span></td>
<td>${mode}</td>
<td>${rst_s}</td>
<td>${rst_r}</td>
<td>${rst_s}${stx_info}</td>
<td>${rst_r}${srx_info}</td>
<td>${gridsquare}</td>
<td>${refs}</td>
<td>${sotaWwffText}</td>
</tr>`);
$("#qsoTable > tbody:last-child").append(tableRow);
@@ -456,6 +516,8 @@ function handleInput() {
}
prevMode = mode;
prev_stx = stx;
prev_stx_string = add_info.stx_string ?? '';
});
// Scroll to the bototm of #qsoTableBody (scroll by the value of its scrollheight property)
@@ -761,6 +823,16 @@ function isExampleDataEntered() {
return isExampleData;
}
function isAllContestDataWithContestId() {
// true = allfine, false = something wrong
let hasContestId = $("#contest").val() != '';
let hasContestData = false;
qsoList.forEach((item) => {
hasContestData = hasContestData || (item[10] != '' || item[12].stx_string !== undefined || item[11] != '' || item[12].stx_string !== undefined);
});
return hasContestData == hasContestId;
}
function getAdifTag(tagName, value) {
return "<" + tagName + ":" + value.length + ">" + value + " ";
}
@@ -932,6 +1004,17 @@ $(".js-save-to-log").click(function () {
});
return false;
}
if (false === isAllContestDataWithContestId()) {
BootstrapDialog.alert({
title: lang_general_word_warning,
message: lang_qso_simplefle_warning_missing_contestid,
type: BootstrapDialog.TYPE_DANGER,
btnCancelLabel: lang_general_word_cancel,
btnOKLabel: lang_general_word_ok,
btnOKClass: "btn-warning",
});
return false;
}
if (true === isExampleDataEntered()) {
BootstrapDialog.alert({
title: lang_general_word_warning,