diff --git a/debian/changelog b/debian/changelog index 3881768..89ec2f9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +gridtracker (1.23.1217) unstable; urgency=low + - BIGCTY - Update from December 15th + - System - Add QSO processing indicator + - System - QSL location authority selector added in Settings > Logbook + - Logbook Viewer - QSL sources added + - Call Roster - Added Grid to Watcher and Ignores + - Language - Updates to Chinese simplified and traditional translations + - Logging - DX Keeper grid bug workaround + -- Tag Loomis Sun, 17 Dec 2023 00:00:00 -0000 gridtracker (1.23.1207) unstable; urgency=high - BIGCTY - Update from December 5th - System - LoTW, eQSL and OQRS membership columns icon updated diff --git a/gridtracker.spec b/gridtracker.spec index 3975e37..d9c96ba 100644 --- a/gridtracker.spec +++ b/gridtracker.spec @@ -1,6 +1,6 @@ Name: {{{ git_name name=gridtracker }}} Summary: GridTracker: An Amateur Radio Companion -Version: 1.23.1207 +Version: 1.23.1217 Release: 1%{?dist} BuildArch: noarch Source0: {{{ git_dir_pack }}} @@ -40,6 +40,14 @@ DESTDIR=${RPM_BUILD_ROOT} make clean %license %{_docdir}/%{name}/ %changelog +* Sun Dec 17 2023 Tag Loomis - 1.23.1217-1 + - BIGCTY - Update from December 15th + - System - Add QSO processing indicator + - System - QSL location authority selector added in Settings > Logbook + - Logbook Viewer - QSL sources added + - Call Roster - Added Grid to Watcher and Ignores + - Language - Updates to Chinese simplified and traditional translations + - Logging - DX Keeper grid bug workaround * Thu Dec 07 2023 Tag Loomis - 1.23.1207-1 - BIGCTY - Update from December 5th - System - LoTW, eQSL and OQRS membership columns icon updated diff --git a/package.nw/GridTracker.html b/package.nw/GridTracker.html index 40668cc..308fbda 100644 --- a/package.nw/GridTracker.html +++ b/package.nw/GridTracker.html @@ -334,7 +334,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. align="right"> QSO -
0
@@ -350,12 +350,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0
QSL -
0
@@ -1610,7 +1610,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+
+ + + + + + + +
QSL Location Authority
+ +
+
+
diff --git a/package.nw/data/mh-root-prefixed.json b/package.nw/data/mh-root-prefixed.json index c096aa1..ecefc6e 100644 --- a/package.nw/data/mh-root-prefixed.json +++ b/package.nw/data/mh-root-prefixed.json @@ -1517,7 +1517,7 @@ "VE9TEN/5", "VE9XX/6", "VE9ZP/4", - "VER20231205", + "VER20231215", "VF0X", "VF0X/M", "VO/DL2GF", @@ -2628,6 +2628,7 @@ "K6VH", "K7BUF", "K7CAP", + "K7DN", "K7EJM", "K7LOP", "K7MVX", @@ -3085,6 +3086,7 @@ "KK6BVH", "KK6CAU", "KK6IMB", + "KK6IQC", "KK6IUY", "KK6LL", "KK6NRF", @@ -10568,6 +10570,7 @@ "R11QRP/8/P", "R11QRP/9", "R11UND", + "R120I", "R120RAEM", "R120RB", "R120RDP", @@ -10580,7 +10583,10 @@ "R120RU", "R120RW", "R120RZ", + "R120S", + "R120T", "R120TM", + "R120W", "R123JDR", "R125NSK", "R135TU", @@ -10830,6 +10836,7 @@ "R71RRC", "R7378TM", "R73EPC/P", + "R73YOTA", "R750X", "R7AA/0", "R7AB/0", @@ -12242,6 +12249,7 @@ "UA3WB/9", "UA3YH/0", "UA3ZAF/9", + "UA4FMQ/P", "UA4LCQ/9", "UA4LU/0", "UA4LU/9/P", @@ -15245,6 +15253,7 @@ "RW9C": "20", "RX9CC": "20", "R0MQ/9": "31", + "R120I": "31", "R135TU": "31", "R140TU": "31", "R2BDY/9": "31", @@ -15961,6 +15970,7 @@ "RQ0J/QRP": "33", "RU3HD/0": "33", "RW80KEDR": "33", + "UA4FMQ/P": "33", "UA9MUY/0": "33", "UE75OJ": "33", "R2015RY": "25", @@ -16149,6 +16159,7 @@ "UE60QA": "23", "UE6MAC/0": "23", "R11QRP/9": "32", + "R120W": "32", "R150LA": "32", "R150LB": "32", "R18SWE": "32", @@ -16399,6 +16410,7 @@ "UE18U": "18", "UE18Z": "19", "R0MQ/9": "18", + "R120I": "18", "R135TU": "18", "R140TU": "18", "R2BDY/9": "18", @@ -17235,6 +17247,7 @@ "RQ0J/QRP": "19", "RU3HD/0": "19", "RW80KEDR": "19", + "UA4FMQ/P": "19", "UA9MUY/0": "19", "UE75OJ": "19", "R2015RY": "19", @@ -17423,6 +17436,7 @@ "UE60QA": "19", "UE6MAC/0": "19", "R11QRP/9": "18", + "R120W": "18", "R150LA": "18", "R150LB": "18", "R18SWE": "18", @@ -20445,8 +20459,10 @@ "R100RK", "R100UD", "R110A/P", + "R120K", "R120RK", "R120RP", + "R120X", "R155PM", "R160PM", "R16NOR", @@ -21471,7 +21487,6 @@ "UA3YH/ANT", "UA4ASE/FF", "UA4ATL/FF", - "UA4FMQ/P", "UA4H", "UA4HAZ/P", "UA4HBM", @@ -22480,6 +22495,7 @@ "R0000O": "19", "R100FA": "19", "R100K": "19", + "R120K": "19", "R20ARRS": "19", "R25ILIM": "19", "R350AR": "19", @@ -22591,6 +22607,7 @@ "RZ30RR": "19", "UB1Z": "19", "UB1ZBD/N": "19", + "R120X": "30", "R170SG": "30", "R2023EN": "30", "R20SAM": "30", @@ -22700,7 +22717,7 @@ "UE77MR": "30", "UE77WT": "30", "UF4H": "30", - "UG4I": "30", + "UG4I": "29", "UG4I/P": "30", "UI4H": "30", "UI4I": "29", @@ -23480,9 +23497,7 @@ "confirmed_bands": {}, "worked_modes": {}, "confirmed_modes": {}, - "direct": [ - "VERSION" - ], + "direct": [], "prefixITU": {}, "prefixCQ": {}, "directITU": {}, @@ -30349,7 +30364,6 @@ "AC6IF", "AC9PT", "AD6YJ", - "AE3TT", "AE5AB", "AE5LR", "AE7QR", @@ -30547,6 +30561,7 @@ "KC9KEX", "KC9NJG", "KC9SBG", + "KC9WIB", "KD0JNO", "KD0OLJ", "KD0OXU", @@ -31036,7 +31051,6 @@ "WK1K", "WL7CSW", "WL7CSW/H", - "WL7M", "WV0Z", "WV6K", "WW7CC", @@ -35775,7 +35789,8 @@ "worked_modes": {}, "confirmed_modes": {}, "direct": [ - "3D5X" + "3D5X", + "VERSION" ], "prefixITU": {}, "prefixCQ": {}, @@ -38203,6 +38218,7 @@ "OH6OG/SA", "OH6OS/S", "OH6OT/S", + "OH6P/S", "OH6P/SA", "OH6PA/S", "OH6QR/S", @@ -38479,6 +38495,7 @@ "F/ON7RU/LH", "F/PH2CV/LH", "F4FET/LH", + "F4IGB/TRC", "F5HPY/LH", "F5NBX/LH", "F5NMK/LH", @@ -41364,6 +41381,7 @@ "GB8SPD", "GB8STM", "GB8UKR", + "GB8WWA", "GB90RSGB/82", "GB90SOM", "GB9AFD", @@ -42524,6 +42542,7 @@ "GB0SFM", "GB0SHP", "GB0SI", + "GB0SIC", "GB0SIM", "GB0SJR", "GB0SK", @@ -42754,6 +42773,7 @@ "GB4SMM", "GB4SRO", "GB4SWF", + "GB4WWA", "GB50FVS", "GB50GDS", "GB50GT", @@ -45456,6 +45476,7 @@ "AD4MM", "AD5S", "AD5XX", + "AE3TT", "AE4RM", "AE6CA", "AE6I", @@ -46300,7 +46321,6 @@ "KC9HYY/LUS100", "KC9HYY/MMD", "KC9JDB", - "KC9WIB", "KD0EBY", "KD0ETC/LH", "KD0FDP", @@ -47454,6 +47474,7 @@ "KL3TY", "KL3UA", "KL3UX", + "KL3UY", "KL3VA", "KL3VJ", "KL3VN", @@ -48314,6 +48335,7 @@ "KY0C", "KY7W", "KZ5DX", + "KZ9G", "KZ9V", "N0BHR", "N0CO", @@ -48431,6 +48453,7 @@ "N5UC", "N5WE", "N5XKG", + "N5YDC", "N5YIZ", "N5ZWF", "N6AI", @@ -49390,6 +49413,7 @@ "WH6ADS", "WH6AFM", "WH6AFV", + "WH6AIR", "WH6AJS", "WH6AKZ", "WH6AM", @@ -51627,6 +51651,7 @@ "KL7GLK/B": "07", "KL7GT": "07", "KL7HR": "07", + "KL7IEI": "07", "KL7IWT": "07", "KL7IXI": "07", "KL7JGJ": "07", @@ -53005,6 +53030,7 @@ "N4UK": "08", "N4Z": "08", "N5HPW": "08", + "N5YDC": "08", "N6RMQ": "08", "N6TSM": "08", "N7CGC": "08", @@ -53221,6 +53247,7 @@ "WH2G": "08", "WH6A": "08", "WH6ACF": "08", + "WH6AIR": "08", "WH6AJS": "08", "WH6AQ": "08", "WH6AVU": "08", @@ -55214,6 +55241,7 @@ "KL3TQ": "06", "KL3TW": "06", "KL3TY": "06", + "KL3UY": "06", "KL3VJ": "06", "KL3XS": "06", "KL4AO": "06", @@ -55294,7 +55322,6 @@ "KL7IAL": "06", "KL7IBT": "06", "KL7IDY": "06", - "KL7IEI": "06", "KL7IFK": "06", "KL7IG": "06", "KL7IGB": "06", @@ -56072,6 +56099,7 @@ "WP4PLR": "08", "WT3A": "08", "AC9H": "08", + "AE3TT": "08", "AH6DA": "08", "AH6EZ/9": "08", "AH6OM": "08", @@ -56108,7 +56136,6 @@ "KC9HYY/EOI": "08", "KC9HYY/LUS100": "08", "KC9HYY/MMD": "08", - "KC9WIB": "08", "KD9Q/M": "08", "KD9TWW": "08", "KE5DDD": "08", @@ -56165,6 +56192,7 @@ "KP4TD": "08", "KP4WG": "08", "KV4AA": "08", + "KZ9G": "08", "KZ9V": "08", "N3QKX": "08", "N4RIH": "08", @@ -56684,6 +56712,7 @@ "KL7GLK/B": "04", "KL7GT": "04", "KL7HR": "04", + "KL7IEI": "04", "KL7IWT": "04", "KL7IXI": "04", "KL7JGJ": "04", @@ -58062,6 +58091,7 @@ "N4UK": "05", "N4Z": "05", "N5HPW": "05", + "N5YDC": "05", "N6RMQ": "05", "N6TSM": "05", "N7CGC": "05", @@ -58278,6 +58308,7 @@ "WH2G": "05", "WH6A": "05", "WH6ACF": "05", + "WH6AIR": "05", "WH6AJS": "05", "WH6AQ": "05", "WH6AVU": "05", @@ -60271,6 +60302,7 @@ "KL3TQ": "03", "KL3TW": "03", "KL3TY": "03", + "KL3UY": "03", "KL3VJ": "03", "KL3XS": "03", "KL4AO": "03", @@ -60351,7 +60383,6 @@ "KL7IAL": "03", "KL7IBT": "03", "KL7IDY": "03", - "KL7IEI": "03", "KL7IFK": "03", "KL7IG": "03", "KL7IGB": "03", @@ -61129,6 +61160,7 @@ "WP4PLR": "04", "WT3A": "04", "AC9H": "04", + "AE3TT": "04", "AH6DA": "04", "AH6EZ/9": "04", "AH6OM": "04", @@ -61165,7 +61197,6 @@ "KC9HYY/EOI": "04", "KC9HYY/LUS100": "04", "KC9HYY/MMD": "04", - "KC9WIB": "04", "KD9Q/M": "04", "KD9TWW": "04", "KE5DDD": "04", @@ -61222,6 +61253,7 @@ "KP4TD": "04", "KP4WG": "04", "KV4AA": "04", + "KZ9G": "04", "KZ9V": "04", "N3QKX": "04", "N4RIH": "04", @@ -62134,6 +62166,7 @@ "GB50RSC", "GB50SGP", "GB5AC", + "GB5ANT", "GB5BPL", "GB5FI", "GB5GEO", @@ -62162,6 +62195,7 @@ "GB6TS", "GB6TSG", "GB6WT", + "GB6WWA", "GB6WWT", "GB70BTF", "GB70W", diff --git a/package.nw/gt_roster.html b/package.nw/gt_roster.html index fe85a1b..2ca0bb7 100644 --- a/package.nw/gt_roster.html +++ b/package.nw/gt_roster.html @@ -285,8 +285,9 @@ @@ -408,10 +409,12 @@ + +
CQ "" From diff --git a/package.nw/gt_update.odt b/package.nw/gt_update.odt index a086cc1..623efc6 100644 Binary files a/package.nw/gt_update.odt and b/package.nw/gt_update.odt differ diff --git a/package.nw/gt_update.pdf b/package.nw/gt_update.pdf index 8a78926..90e3fe9 100644 Binary files a/package.nw/gt_update.pdf and b/package.nw/gt_update.pdf differ diff --git a/package.nw/i18n/cn-dxcc.json b/package.nw/i18n/cn-dxcc.json index 96166e7..c61735d 100644 --- a/package.nw/i18n/cn-dxcc.json +++ b/package.nw/i18n/cn-dxcc.json @@ -250,7 +250,7 @@ "312": "柬埔寨", "315": "斯里兰卡", "318": "中国", - "321": "国香港", + "321": "香港", "324": "印度", "327": "印度尼西亚", "330": "伊朗", @@ -328,8 +328,8 @@ "502": "北马其顿", "503": "捷克", "504": "斯洛伐克", - "505": "国东沙群岛", - "506": "国黄岩岛", + "505": "东沙群岛", + "506": "黄岩岛", "507": "泰莫图省", "508": "南方群岛", "509": "马克萨斯岛", diff --git a/package.nw/i18n/cn-t.json b/package.nw/i18n/cn-t.json index 04b620f..7d727a6 100644 --- a/package.nw/i18n/cn-t.json +++ b/package.nw/i18n/cn-t.json @@ -4,7 +4,7 @@ "The GridTracker Team", "VR2UPU" ], - "last-updated": "2023-12-03", + "last-updated": "2023-12-07", "locale": "hk", "message-documentation": "Traditional Chinese: VR2UPU" }, @@ -576,7 +576,7 @@ "roster.secondary.exceptions.onlyMyDXCC": "我需要的DXCC", "roster.secondary.exceptions.useseQSL": "eQSL用戶", "roster.secondary.exceptions.usesOQRS": "OQRS用戶", - "roster.secondary.exceptions.allOnlyNew": "僅限新呼號", + "roster.secondary.exceptions.allOnlyNew": "新呼號", "roster.secondary.exceptions.wantRRCQ": "RR73當作CQ", "roster.secondary.exceptions.noUnknownDXCC": "禁止不明DXCC", "roster.secondary.exceptions.noMsg.label": "不包含", @@ -595,8 +595,8 @@ "stats.tabs.logbook": "日誌", "stats.tabs.scores": "分數", "stats.tabs.DXCCs": "DXCCs", - "stats.tabs.CQZones": "CQ 分區", - "stats.tabs.ITUZones": "ITU 分區", + "stats.tabs.CQZones": "CQ分區", + "stats.tabs.ITUZones": "ITU分區", "stats.tabs.WASWAC": "洲大陸/美國州", "stats.tabs.live": "在線", "stats.noDecodes": "還沒有解碼", @@ -624,7 +624,7 @@ "adif.LoggedHRDLogbook": "已記錄到 HRD Logbook", "adif.ExceptionHRDLogbook": "HRD 日誌異常", "adif.ExceptionLoTW": "LoTW 日誌異常", - "adif.ExceptionAlertLog": "Alert 日誌異常", + "adif.ExceptionAlertLog": "警報日誌異常", "adif.ExceptionHideLookup": "隱藏查找異常", "adif.BadPassUser": "錯誤
密碼

暱稱", "adif.UnknownCall": "不明
呼號", diff --git a/package.nw/i18n/cn.json b/package.nw/i18n/cn.json index ac54a22..a69abb1 100644 --- a/package.nw/i18n/cn.json +++ b/package.nw/i18n/cn.json @@ -4,7 +4,7 @@ "The GridTracker Team", "BD3OOX" ], - "last-updated": "2023-12-02", + "last-updated": "2023-12-07", "locale": "cn", "message-documentation": "Simplified Chinese: BD3OOX" }, @@ -576,11 +576,11 @@ "roster.secondary.exceptions.onlyMyDXCC": "我需要的DXCC", "roster.secondary.exceptions.useseQSL": "在用eQSL", "roster.secondary.exceptions.usesOQRS": "在用OQRS", - "roster.secondary.exceptions.allOnlyNew": "仅限新呼号", + "roster.secondary.exceptions.allOnlyNew": "新呼号", "roster.secondary.exceptions.wantRRCQ": "RR73当作CQ", "roster.secondary.exceptions.noUnknownDXCC": "禁止不明DXCC", "roster.secondary.exceptions.noMsg.label": "不包含", - "roster.secondary.exceptions.noMsg.hover": "不包含解码...", + "roster.secondary.exceptions.noMsg.hover": "不包含的解码...", "roster.secondary.exceptions.onlyMsg.label": "仅限", "roster.secondary.exceptions.onlyMsg.hover": "仅限包含的解码...", "roster.secondary.exceptions.regex.label": "呼号匹配", @@ -624,8 +624,8 @@ "adif.LoggedHRDLogbook": "已保存到 HRD Logbook", "adif.ExceptionHRDLogbook": "HRD 日志异常", "adif.ExceptionLoTW": "LoTW 日志异常", - "adif.ExceptionAlertLog": "Alert 日志异常", - "adif.ExceptionHideLookup": "Hide Lookup 异常", + "adif.ExceptionAlertLog": "警报日志异常", + "adif.ExceptionHideLookup": "隐藏查找异常", "adif.BadPassUser": "错误
密码

昵称", "adif.UnknownCall": "未知
呼号", "adif.QTHNickname": "需要
QTH昵称", diff --git a/package.nw/i18n/cnt-dxcc.json b/package.nw/i18n/cnt-dxcc.json index a974a29..ed0c6ad 100644 --- a/package.nw/i18n/cnt-dxcc.json +++ b/package.nw/i18n/cnt-dxcc.json @@ -250,7 +250,7 @@ "312": "柬埔寨", "315": "斯里蘭卡", "318": "中國", - "321": "國香港", + "321": "香港", "324": "印度", "327": "印度尼西亞", "330": "伊朗", @@ -328,8 +328,8 @@ "502": "北馬其頓", "503": "捷克", "504": "斯洛伐克", - "505": "國東沙群島", - "506": "國黃岩島", + "505": "東沙群島", + "506": "黃岩島", "507": "泰莫圖省", "508": "南方群島", "509": "馬克薩斯島", diff --git a/package.nw/i18n/it.json b/package.nw/i18n/it.json index bb2831f..8ab4f7c 100644 --- a/package.nw/i18n/it.json +++ b/package.nw/i18n/it.json @@ -662,7 +662,7 @@ "alerts.callsign.popup": "Ricerca", "alerts.gridsquare.speech": "Grid square", "alerts.gridsquare.popup": "Grid square", - "alerts.QRZ.speech": "Chiamata", + "alerts.QRZ.speech": "Chiamando", "alerts.QRZ.popup": "QRZ", "alerts.AlertPop.Type": "Tipo", "alerts.AlertPop.Value": "Valore", diff --git a/package.nw/lib/adif.js b/package.nw/lib/adif.js index 9fba4e5..adae56a 100644 --- a/package.nw/lib/adif.js +++ b/package.nw/lib/adif.js @@ -81,6 +81,14 @@ function findAdiField(row, field) return value; } +GT.confSrcNames = { + C: "Clublog", + e: "eQSL", + L: "LoTW", + Q: "QRZ.com", + O: "Other" +} + function onAdiLoadComplete(adiBuffer) { var rawAdiBuffer = ""; @@ -90,11 +98,18 @@ function onAdiLoadComplete(adiBuffer) var activeAdifArray = Array(); var activeAdifLogMode = true; var eQSLfile = false; + var clublogFile = false; var lotwTimestampUpdated = false; if (rawAdiBuffer.indexOf("PSKReporter") > -1) activeAdifLogMode = false; + if (activeAdifLogMode == true) + { + qsoCountStyle.className = "roundBorderValue QsoQslActive"; + qslCountStyle.className = "roundBorderValue QsoQslActive"; + } if (rawAdiBuffer.indexOf("Received eQSLs") > -1) eQSLfile = true; + if (rawAdiBuffer.indexOf("clublog.adif") > -1 || rawAdiBuffer.indexOf("ADIF export from Club Log") > -1) clublogFile = true; if (rawAdiBuffer.length > 1) { @@ -114,6 +129,8 @@ function onAdiLoadComplete(adiBuffer) { if (activeAdifLogMode) { + let confSource = null; + let lotwConfirmed = false; // let object = parseADIFRecord(activeAdifArray[x]); var appLoTW_RXQSO = findAdiField(activeAdifArray[x], "APP_LOTW_RXQSO"); if (appLoTW_RXQSO != "") @@ -145,6 +162,7 @@ function onAdiLoadComplete(adiBuffer) GT.adifLogSettings.lastFetch.lotw_qsl = timestring.slice(0, 10) + " " + timestring.slice(11, 19); lotwTimestampUpdated = true; } + lotwConfirmed = true; } var finalDEcall = findAdiField(activeAdifArray[x], "STATION_CALLSIGN").replace("_", "/"); @@ -288,6 +306,26 @@ function onAdiLoadComplete(adiBuffer) if (qrzConfirmed == "C" || lotw_qsl_rcvd == "Y" || lotw_qsl_rcvd == "V" || lotwConfirmed1 == "Y" || eqsl_qsl_rcvd == "Y" || eqsl_qsl_rcvd == "V" || eQSLfile == true) { confirmed = true; + if (qrzConfirmed == "C") + { + confSource = "Q"; + } + else if (eQSLfile == true) + { + confSource = "e"; + } + else if (lotwConfirmed == true) + { + confSource = "L"; + } + else if (clublogFile == true) + { + confSource = "C"; + } + else + { + confSource = "O"; + } } finalGrid = finalGrid.substr(0, 6); @@ -340,7 +378,8 @@ function onAdiLoadComplete(adiBuffer) isPhone, finalIOTA, finalSatName, - finalPOTA + finalPOTA, + confSource ); } } @@ -507,6 +546,12 @@ function clubLogCallback(buffer, flag, cookie) GT.isGettingClub = false; function grabClubLog(test) { + if (fs.existsSync(GT.clublogLogFile) && getFilesizeInBytes(GT.clublogLogFile) > 0) + { + GT.fromDirectCallNoFileDialog = true; + onAdiLoadComplete(fs.readFileSync(GT.clublogLogFile)); + } + if (GT.isGettingClub == false) { if (test) clubTestResult.innerHTML = "Testing"; @@ -559,7 +604,6 @@ function cleanAndPrepADIF(name, adiBuffer, reverse = false, noheader = false) regex = new RegExp("", "i"); var adiArray = rawAdiBuffer.split(regex); var activeAdifArray = Array(); - var activeAdifLogMode = true; var finalBuffer = ""; if (noheader == false) finalBuffer = name + "\r\n"; @@ -808,6 +852,12 @@ function qrzCallback(buffer, flag) GT.isGettingQRZCom = false; function grabQrzComLog(test) { + if (fs.existsSync(GT.QrzLogFile) && getFilesizeInBytes(GT.QrzLogFile) > 0) + { + GT.fromDirectCallNoFileDialog = true; + onAdiLoadComplete(fs.readFileSync(GT.QrzLogFile)); + } + if (GT.isGettingQRZCom == false) { var action = "FETCH"; @@ -1437,21 +1487,11 @@ function startupAdifLoadCheck() { logEventMedia.value = GT.alertSettings.logEventMedia; - loadWsjtLogFile(); - - if (loadGTCheckBox.checked == true) loadGtQSOLogFile(); - - if (loadAdifCheckBox.checked == true && GT.startupLogs.length > 0) - { startupAdifLoadFunction(); } + if (loadAdifCheckBox.checked == true && GT.startupLogs.length > 0) startupAdifLoadFunction(); if (GT.mapSettings.offlineMode == false) { - if (GT.appSettings.gtFlagImgSrc == 1) showGtFlags(); - - if (loadLOTWCheckBox.checked == true) - { - grabLOtWLog(false); - } + if (loadLOTWCheckBox.checked == true) grabLOtWLog(false); if (loadQRZCheckBox.checked == true) grabQrzComLog(false); @@ -1459,6 +1499,10 @@ function startupAdifLoadCheck() if (loadPsk24CheckBox.checked == true) grabPsk24(); } + + if (loadGTCheckBox.checked == true) loadGtQSOLogFile(); + + loadWsjtLogFile(); } function getABuffer(file_url, callback, flag, mode, port, imgToGray, stringOfFlag, timeoutX) @@ -2005,11 +2049,7 @@ function finishSendingReport(record, localMode) addLastTraffic("Spotted to POTA"); } - if ( - GT.N1MMSettings.enable == true && - GT.N1MMSettings.port > 1024 && - GT.N1MMSettings.ip.length > 4 - ) + if (GT.N1MMSettings.enable == true && GT.N1MMSettings.port > 1024 && GT.N1MMSettings.ip.length > 4) { sendUdpMessage( report, @@ -2020,11 +2060,7 @@ function finishSendingReport(record, localMode) addLastTraffic("Logged to N1MM"); } - if ( - GT.log4OMSettings.enable == true && - GT.log4OMSettings.port > 1024 && - GT.log4OMSettings.ip.length > 4 - ) + if (GT.log4OMSettings.enable == true && GT.log4OMSettings.port > 1024 && GT.log4OMSettings.ip.length > 4) { sendUdpMessage( "ADD " + report, @@ -2058,9 +2094,7 @@ function finishSendingReport(record, localMode) catch (e) { console.log(e); - addLastTraffic( - "Exception GridTracker backup" - ); + addLastTraffic("Exception GridTracker backup"); } try @@ -2099,11 +2133,7 @@ function finishSendingReport(record, localMode) addLastTraffic("Exception Cloudlog Log"); } - if ( - GT.acLogSettings.enable == true && - GT.acLogSettings.port > 0 && - GT.acLogSettings.ip.length > 4 - ) + if (GT.acLogSettings.enable == true && GT.acLogSettings.port > 0 && GT.acLogSettings.ip.length > 4) { try { @@ -2116,19 +2146,29 @@ function finishSendingReport(record, localMode) } } - if ( - GT.dxkLogSettings.enable == true && - GT.dxkLogSettings.port > 0 && - GT.dxkLogSettings.ip.length > 4 - ) + if (GT.dxkLogSettings.enable == true && GT.dxkLogSettings.port > 0 && GT.dxkLogSettings.ip.length > 4) { try { - sendDXKeeperLogMessage( - report, - GT.dxkLogSettings.port, - GT.dxkLogSettings.ip - ); + let DXreport = ""; + for (const key in record) + { + if ("MY_GRIDSQUARE" in record) + { + record.MY_GRIDSQUARE = record.MY_GRIDSQUARE.substr(0, 6); + } + if ("GRIDSQUARE" in record) + { + record.GRIDSQUARE = record.GRIDSQUARE.substr(0, 6); + } + if (key != "POTA") + { + DXreport += "<" + key + ":" + Buffer.byteLength(record[key]) + ">" + record[key] + " "; + } + } + DXreport += ""; + + sendDXKeeperLogMessage(DXreport, GT.dxkLogSettings.port, GT.dxkLogSettings.ip); addLastTraffic("Logged to DXKeeper"); } catch (e) @@ -2137,22 +2177,12 @@ function finishSendingReport(record, localMode) } } - if ( - GT.HRDLogbookLogSettings.enable == true && - GT.HRDLogbookLogSettings.port > 0 && - GT.HRDLogbookLogSettings.ip.length > 4 - ) + if (GT.HRDLogbookLogSettings.enable == true && GT.HRDLogbookLogSettings.port > 0 && GT.HRDLogbookLogSettings.ip.length > 4) { try { - sendHRDLogbookEntry( - record, - GT.HRDLogbookLogSettings.port, - GT.HRDLogbookLogSettings.ip - ); - addLastTraffic( - "Logged to HRD Logbook" - ); + sendHRDLogbookEntry(record, GT.HRDLogbookLogSettings.port, GT.HRDLogbookLogSettings.ip); + addLastTraffic("Logged to HRD Logbook"); } catch (e) { @@ -2178,29 +2208,27 @@ function finishSendingReport(record, localMode) addLastTraffic("Exception HamCQ Log"); } - if ( - logeQSLQSOCheckBox.checked == true && - nicknameeQSLCheckBox.checked == true && - eQSLNickname.value.trim().length > 0 - ) + if (logeQSLQSOCheckBox.checked == true && (nicknameeQSLCheckBox.checked == false || (nicknameeQSLCheckBox.checked == true && eQSLNickname.value.trim().length > 0))) { - record.APP_EQSL_QTH_NICKNAME = eQSLNickname.value.trim(); - report = ""; + if (nicknameeQSLCheckBox.checked == true) + { + record.APP_EQSL_QTH_NICKNAME = eQSLNickname.value.trim(); + } + let eQSLreport = ""; for (var key in record) { - report += - "<" + key + ":" + Buffer.byteLength(record[key]) + ">" + record[key] + " "; + eQSLreport += "<" + key + ":" + Buffer.byteLength(record[key]) + ">" + record[key] + " "; } - report += ""; - } + eQSLreport += ""; - try - { - sendeQSLEntry(report); - } - catch (e) - { - addLastTraffic("Exception LoTW Log"); + try + { + sendeQSLEntry(eQSLreport); + } + catch (e) + { + addLastTraffic("Exception eQSL Log"); + } } try @@ -2321,23 +2349,21 @@ function sendeQSLEntry(report) { if (GT.mapSettings.offlineMode == true) return; - if (logeQSLQSOCheckBox.checked == true) - { - var pid = "GridTracker"; - var pver = String(gtVersion); - var header = "" + pid + "\r\n"; - header += "" + pver + "\r\n"; - header += "\r\n"; - var eReport = encodeURIComponent(header + report); - var fUrl = - "https://www.eQSL.cc/qslcard/importADIF.cfm?ADIFData=" + - eReport + - "&EQSL_USER=" + - encodeURIComponent(eQSLUser.value) + - "&EQSL_PSWD=" + - encodeURIComponent(eQSLPassword.value); - getABuffer(fUrl, eqslCallback, false, "https", 443); - } + var pid = "GridTracker"; + var pver = String(gtVersion); + var header = "" + pid + "\r\n"; + header += "" + pver + "\r\n"; + header += "\r\n"; + var eReport = encodeURIComponent(header + report); + var fUrl = + "https://www.eQSL.cc/qslcard/importADIF.cfm?ADIFData=" + + eReport + + "&EQSL_USER=" + + encodeURIComponent(eQSLUser.value) + + "&EQSL_PSWD=" + + encodeURIComponent(eQSLPassword.value); + + getABuffer(fUrl, eqslCallback, false, "https", 443); } function testTrustedQSL(test) diff --git a/package.nw/lib/callsigns.js b/package.nw/lib/callsigns.js index f341abe..f9fa554 100644 --- a/package.nw/lib/callsigns.js +++ b/package.nw/lib/callsigns.js @@ -779,37 +779,24 @@ function lookupUsCallsign(object, writeState = false) } } object.zipcode = String(results.rows[0].zip); - if (object.cnty == null) + if (object.cnty == null && object.zipcode in GT.zipToCounty) { - let request = GT.Idb.transaction(["lookups"], "readwrite").objectStore("lookups").get(object.DEcall); - request.onsuccess = function (event) + var counties = GT.zipToCounty[object.zipcode]; + if (counties.length > 1) { - let save = false; - if (request.result && object.cnty == null) - { - object.cnty = request.result.cnty; - object.qual = true; - save = true; - } - if (object.cnty == null && object.zipcode in GT.zipToCounty) - { - var counties = GT.zipToCounty[object.zipcode]; - if (counties.length > 1) - { - object.qual = false; - } - else - { - object.qual = true; - } - object.cnty = counties[0]; - save = true; - } - if (writeState && save) - { - refreshQSOs(); - } - }; + object.qual = false; + } + else + { + object.qual = true; + } + object.cnty = counties[0]; + save = true; + + if (writeState) + { + refreshQSOs(); + } } } }, diff --git a/package.nw/lib/defaults.js b/package.nw/lib/defaults.js index 3f15ed8..78f632d 100644 --- a/package.nw/lib/defaults.js +++ b/package.nw/lib/defaults.js @@ -100,7 +100,8 @@ var def_appSettings = { workingCallsigns: {}, workingDateEnable: false, workingDate: 0, - qsoItemsPerPage: 100 + qsoItemsPerPage: 100, + qslAuthority: "L" }; var def_mapSettings = { @@ -296,6 +297,7 @@ var def_qso = { band: "", cnty: null, confirmed: false, + confSrcs: {}, cont: null, cqz: "", DEcall: "", diff --git a/package.nw/lib/gt.js b/package.nw/lib/gt.js index 8e799ec..10e0a9b 100644 --- a/package.nw/lib/gt.js +++ b/package.nw/lib/gt.js @@ -543,7 +543,9 @@ GT.NWappData = ""; GT.screenshotDir = ""; GT.scriptDir = ""; GT.qsoLogFile = ""; +GT.clublogLogFile = ""; GT.LoTWLogFile = ""; +GT.QrzLogFile = ""; GT.userMediaDir = ""; GT.gtMediaDir = path.resolve("./media"); GT.localeString = navigator.language; @@ -1018,7 +1020,7 @@ function processQSOs() let fourGrid = details.grid.substr(0, 4); let isDigi = details.digital; let isPhone = details.phone; - + GT.tracker.worked.call[details.DEcall + details.band + details.mode] = true; GT.tracker.worked.call[details.DEcall] = true; GT.tracker.worked.call[details.DEcall + details.mode] = true; @@ -1290,6 +1292,10 @@ function processQSOs() } } } + + qsoCountStyle.className = "roundBorderValue"; + qslCountStyle.className = "roundBorderValue"; + updateRosterWorked(); goProcessRoster(); redrawGrids(); @@ -1336,7 +1342,8 @@ function addQSO( finalPhone = false, finalIOTA = "", finalSatName = "", - finalPOTA = null + finalPOTA = null, + confSource = null ) { let hash = ""; @@ -1352,6 +1359,7 @@ function addQSO( if (hash in GT.QSOhash) { details = GT.QSOhash[hash]; + let canWrite = (details.confirmed == false || GT.appSettings.qslAuthority == "0" || GT.appSettings.qslAuthority == confSource || !(GT.appSettings.qslAuthority in details.confSrcs)); if (finalGrid.length > 0 && finalGrid != details.grid) { // only touch the grid if it's larger than the last grid && the 4wide is the same @@ -1359,7 +1367,7 @@ function addQSO( { details.grid = finalGrid; } - else if (details.grid.length != 0 && confirmed == true) + else if (details.grid.length != 0 && confirmed == true && canWrite) { details.grid = finalGrid; } @@ -1369,16 +1377,15 @@ function addQSO( if (finalRSTrecv.length > 0) details.RSTrecv = finalRSTrecv; if (finalCqZone.length > 0) details.cqz = finalCqZone; if (finalItuZone.length > 0) details.ituz = finalItuZone; - if (details.state != null && finalState != null && details.state != finalState && confirmed == true) + if (details.state != null && finalState != null && details.state != finalState && confirmed == true && canWrite) { details.state = finalState; } else if (details.state == null && finalState != null) details.state = finalState; if (finalDxcc < 1 && details.dxcc > 0) finalDxcc = details.dxcc; if (finalCont == null && details.cont) finalCont = details.cont; - if (details.cnty != null && finalCnty != null && details.cnty != finalCnty && confirmed == true) + if (details.cnty != null && finalCnty != null && details.cnty != finalCnty && confirmed == true && canWrite) { - details.qual = true; details.cnty = finalCnty; } else if (details.cnty == null && details.cnty != null) details.cnty = finalCnty; @@ -1388,6 +1395,10 @@ function addQSO( if (finalSatName.length > 0) details.satName = finalSatName; if (finalPOTA) details.pota = finalPOTA; details.confirmed |= confirmed; + if (confirmed == true) + { + details.confSrcs[confSource] = true; + } } else { @@ -1420,6 +1431,11 @@ function addQSO( details.pota = finalPOTA; details.worked = true; details.confirmed = confirmed; + details.confSrcs = {}; + if (confirmed == true) + { + details.confSrcs[confSource] = true; + } } if (finalDxcc < 1) finalDxcc = callsignToDxcc(finalDXcall); @@ -1445,7 +1461,7 @@ function addQSO( details.qual = true; } - if (isKnownCallsignUSplus(finalDxcc)) + if (confirmed == false && isKnownCallsignUSplus(finalDxcc)) { if (details.state == null && fourGrid.length > 0) { @@ -2571,6 +2587,30 @@ function updateRosterInstances() function changeLogbookPage() { qsoItemsPerPageTd.innerHTML = GT.appSettings.qsoItemsPerPage = parseInt(qsoItemsPerPageValue.value); + saveAppSettings(); +} + +GT.qslAuthorityTimer = null; +// Called from GridTracher.html +function qslAuthorityChanged() +{ + if (GT.qslAuthorityTimer != null) + { + nodeTimers.clearTimeout(GT.qslAuthorityTimer); + GT.qslAuthorityTimer = null; + } + + GT.appSettings.qslAuthority = qslAuthority.value; + saveAppSettings(); + // we set the timer as calling directly will pause the input queue + GT.qslAuthorityTimer = nodeTimers.setTimeout(reloadFromQslAuthorityChanged, 500); +} + +function reloadFromQslAuthorityChanged() +{ + GT.qslAuthorityTimer = null; + clearQSOs(false); // do not clear what's on disk! + startupAdifLoadCheck(); } function updateLogbook() @@ -4901,7 +4941,7 @@ function clearAndLoadQSOs() startupAdifLoadCheck(); } -function clearQSOs() +function clearQSOs(clearFiles = true) { initQSOdata(); GT.QSOhash = {}; @@ -4913,7 +4953,10 @@ function clearQSOs() updateLogbook(); updateRosterWorked(); goProcessRoster(); - clearLogFilesAndCounts(); + if (clearFiles == true) + { + clearLogFilesAndCounts(); + } } function clearLogFilesAndCounts() @@ -7369,7 +7412,7 @@ function showCallsignBox(redraw) "
" + "" + "" + - "" + + "" + ""; // "; if (GT.callsignLookups.lotwUseEnable == true) worker += ""; if (GT.callsignLookups.eqslUseEnable == true) worker += ""; @@ -7727,7 +7770,7 @@ function showWorkedBox(sortIndex, nextPage, redraw) var bands = {}; var modes = {}; var dxccs = {}; - + var confSrcs = {}; var ObjectCount = 0; myObjects = GT.QSOhash; @@ -7792,8 +7835,12 @@ function showWorkedBox(sortIndex, nextPage, redraw) var pp = list[key].dxcc in GT.dxccInfo ? GT.dxccInfo[list[key].dxcc].pp : "?"; dxccs[GT.dxccToAltName[list[key].dxcc] + " (" + pp + ")"] = list[key].dxcc; + if (list[key].confirmed) + { + confSrcs = Object.assign(confSrcs, list[key].confSrcs); + } } - + if (GT.filterBand != "Mixed") { list = list.filter(function (value) @@ -7832,7 +7879,18 @@ function showWorkedBox(sortIndex, nextPage, redraw) { list = list.filter(function (value) { - return value.confirmed == (GT.filterQSL == "true"); + if (GT.filterQSL == "false" || GT.filterQSL == "true") + { + return value.confirmed == (GT.filterQSL == "true"); + } + else + { + if (value.confirmed && GT.filterQSL in value.confSrcs) + { + return true; + } + return false; + } }); } @@ -7969,14 +8027,23 @@ function showWorkedBox(sortIndex, nextPage, redraw) worker += ""; var key = null; + var confTitle = ""; + var confTd = ""; for (var i = startIndex; i < endIndex; i++) { key = list[i]; + if (confirmed) + { + let srcs = {}; + Object.keys(key.confSrcs).forEach(src => { srcs[GT.confSrcNames[src]] = true; }); + confTd = Object.keys(key.confSrcs).join(""); + confTitle = "title='" + Object.keys(srcs).join(", ") + "'"; + } worker += ""; worker += ""; worker += ""; worker += ""; - worker += ""; + worker += ""; worker += ""; worker += ""; worker += ""; @@ -8112,6 +8179,15 @@ function showWorkedBox(sortIndex, nextPage, redraw) option.text = "No"; newSelect.appendChild(option); + Object.keys(confSrcs) + .forEach(function (key) + { + var option = document.createElement("option"); + option.value = key + option.text = GT.confSrcNames[key]; + newSelect.appendChild(option); + }); + statsAppendChild( "qslFilterDiv", newSelect, @@ -12896,6 +12972,7 @@ function setMsgSettingsView() function loadAdifSettings() { + qslAuthority.value = GT.appSettings.qslAuthority; qsoItemsPerPageTd.innerHTML = qsoItemsPerPageValue.value = GT.appSettings.qsoItemsPerPage; workingCallsignEnable.checked = GT.appSettings.workingCallsignEnable; @@ -14369,13 +14446,7 @@ function addLookupObjectToIndexedDB(lookupObject) }; } -function getLookupCachedObject( - call, - gridPass, - resultFunction = null, - noResultFunction = null, - callObject = null -) +function getLookupCachedObject(call, gridPass, resultFunction = null, noResultFunction = null, callObject = null) { var request = GT.Idb .transaction(["lookups"], "readwrite") @@ -14384,10 +14455,7 @@ function getLookupCachedObject( request.onsuccess = function (event) { - if ( - request.result && - parseInt(request.result.cached) + 604800 > timeNowSec() - ) + if (request.result && parseInt(request.result.cached) + 604800 > timeNowSec()) { // 7 days, should an option Tag! I know right?! delete request.result; @@ -15244,6 +15312,8 @@ function mediaCheck() GT.qsoLogFile = path.join(GT.appData, "GridTracker_QSO.adif"); GT.LoTWLogFile = path.join(GT.appData, "LogbookOfTheWorld.adif"); + GT.QrzLogFile = path.join(GT.appData, "qrz.adif"); + GT.clublogLogFile = path.join(GT.appData, "clublog.adif"); logEventMedia.appendChild(newOption("none", "None")); msgAlertMedia.appendChild(newOption("none", "Select File")); @@ -15303,7 +15373,7 @@ function mediaCheck() try { let fileExists = fs.existsSync(GT.NWappData + "internal_qso.json"); - if (fileExists == true && GT.startVersion > 1231202) + if (fileExists == true && GT.startVersion > 1231207) { var data = JSON.parse(fs.readFileSync(GT.NWappData + "internal_qso.json")); GT.tracker = data.tracker; diff --git a/package.nw/lib/roster.js b/package.nw/lib/roster.js index 83e53ed..c51d9f8 100644 --- a/package.nw/lib/roster.js +++ b/package.nw/lib/roster.js @@ -11,6 +11,7 @@ CR.blockedCalls = {}; CR.blockedCQ = {}; CR.ignoredCQ = {}; CR.blockedDxcc = {}; +CR.blockedGrid = {}; CR.blockedCQz = {}; CR.blockedITUz = {}; CR.scriptReport = {}; @@ -39,6 +40,7 @@ CR.targetHash = ""; CR.dxccMenu = null; CR.targetDxcc = -1; CR.CQMenu = null; +CR.GridMenu = null; CR.MsgMenu = null; CR.targetCQ = ""; CR.timerInterval = null; @@ -211,11 +213,17 @@ if (typeof localStorage.blockedITUz == "undefined") localStorage.blockedITUz = "{}"; } +if (typeof localStorage.blockedGrid == "undefined") +{ + localStorage.blockedGrid = "{}"; +} + if (typeof localStorage.blockedCalls != "undefined") { CR.blockedCalls = JSON.parse(localStorage.blockedCalls); CR.blockedCQ = JSON.parse(localStorage.blockedCQ); CR.blockedDxcc = JSON.parse(localStorage.blockedDxcc); + CR.blockedGrid = JSON.parse(localStorage.blockedGrid); CR.blockedCQz = JSON.parse(localStorage.blockedCQz); CR.blockedITUz = JSON.parse(localStorage.blockedITUz); } @@ -223,6 +231,7 @@ else { localStorage.blockedCalls = "{}"; localStorage.blockedDxcc = "{}"; + localStorage.blockedGrid = "{}"; localStorage.blockedCQz = "{}"; localStorage.blockedITUz = "{}"; localStorage.ignoredCQ = "{}"; @@ -263,6 +272,7 @@ function storeBlocks(render = true) localStorage.blockedCalls = JSON.stringify(CR.blockedCalls); localStorage.ignoredCQ = JSON.stringify(CR.ignoredCQ); localStorage.blockedDxcc = JSON.stringify(CR.blockedDxcc); + localStorage.blockedGrid = JSON.stringify(CR.blockedGrid); localStorage.blockedCQz = JSON.stringify(CR.blockedCQz); localStorage.blockedITUz = JSON.stringify(CR.blockedITUz); if (render) @@ -1307,6 +1317,7 @@ function initSelectors() CR.ignoreTypeInputs = {}; CR.ignoreTypeInputs.Callsign = ignoreCallsignValue; + CR.ignoreTypeInputs.Grid = ignoreGridValue; CR.ignoreTypeInputs.CQ = ignoreCqDiv; CR.ignoreTypeInputs.DXCC = ignoreDxccSelect; CR.ignoreTypeInputs.CQz = ignoreCqzSelect; @@ -1319,6 +1330,7 @@ function initSelectors() function hideIgnoreElements() { ignoreCallsignValue.style.display = "none"; + ignoreGridValue.style.display = "none"; ignoreCqDiv.style.display = "none"; ignoreDxccSelect.style.display = "none"; ignoreCqzSelect.style.display = "none"; @@ -1337,9 +1349,25 @@ function ignoreTypeChanged(ignoreTypeValue) CR.ignoreType = ignoreTypeValue; } ValidateTextInput(ignoreCallsignValue); + gridInputValidate(ignoreGridValue); ValidateTextInput(ignoreCqCallsignValue); } +function gridInputValidate(element) +{ + element.value = element.value.toUpperCase().replace(/[^A-Z0-9/]+/g, "").substr(0, 4); + if (!element.value.match(GRID_REGEXP)) + { + element.style.color = "#000"; + element.style.backgroundColor = "yellow"; + } + else + { + element.style.color = ""; + element.style.backgroundColor = ""; + } +} + function addNewIgnore() { if (CR.ignoreType == "Callsign") @@ -1360,6 +1388,10 @@ function addNewIgnore() { ignoreDxcc(ignoreDxccSelect.value); } + else if (CR.ignoreType == "Grid") + { + ignoreGrid(ignoreGridValue.value); + } else if (CR.ignoreType == "CQz") { ignoreCQz(ignoreCqzSelect.value) @@ -1429,6 +1461,13 @@ function ignoreDxcc(dxcc) viewRoster(); } +function ignoreGrid(grid) +{ + CR.blockedGrid[grid] = true; + storeBlocks(); + viewRoster(); +} + function ignoreCQ(cq, dxcc) { if (dxcc > 0) @@ -1465,6 +1504,13 @@ function deleteDxccIgnore(key) viewRoster(); } +function deleteGridIgnore(key) +{ + delete CR.blockedGrid[key]; + storeBlocks(); + viewRoster(); +} + function deleteCQIgnore(key) { delete CR.ignoredCQ[key]; @@ -1500,6 +1546,13 @@ function clearAllDxccIgnores() viewRoster(); } +function clearAllGridIgnores() +{ + CR.blockedGrid = Object(); + storeBlocks(); + viewRoster(); +} + function clearAllCQIgnores() { CR.ignoredCQ = Object(); @@ -1585,7 +1638,7 @@ function renderIgnoresTab() let key = split[0]; let dxcc = -1; if (split.length == 2) dxcc = parseInt(split[1]); - worker += ""; + worker += ""; }); worker += "
Logbook Items Per Page " + $.i18n("gt.callsignBox.ITU") + "" + $.i18n("gt.callsignBox.Flag") + "" + $.i18n("gt.callsignBox.QSO") + "" + $.i18n("gt.callsignBox.Grid") + "" + $.i18n("gt.callsignBox.QSL") + "" + $.i18n("gt.callsignBox.When") + "ITUzCQzISO" + $.i18n("gt.callsignBox.LoTW") + "" + $.i18n("gt.callsignBox.eQSL") + "
" + formatCallsign(key.DEcall) + "" + key.grid + (key.vucc_grids.length ? ", " + key.vucc_grids.join(", ") : "") + "" + key.band + "" + key.mode + "" + (key.confirmed ? "✔" : "") + "" + confTd + "" + key.RSTsent + "" + key.RSTrecv + "" + GT.dxccToAltName[key.dxcc] + " (" + (key.dxcc in GT.dxccInfo ? GT.dxccInfo[key.dxcc].pp : "?") + ")
" + key + " from " + (dxcc == -1 ? "All" : window.opener.GT.dxccToAltName[dxcc]) + "
" + key + " from " + (dxcc == -1 ? "All" : window.opener.GT.dxccToAltName[dxcc]) + "
"; } @@ -1603,6 +1656,19 @@ function renderIgnoresTab() worker += "
"; } + if (Object.keys(CR.blockedGrid).length > 0) + { + clearString = "Clear All"; + worker += "
" + clearString + ""; + Object.keys(CR.blockedGrid) + .sort() + .forEach(function (key, i) + { + worker += ""; + }); + worker += "
Grid
" + key + "
"; + } + if (Object.keys(CR.blockedCQz).length > 0) { clearString = "Clear All"; @@ -2175,6 +2241,42 @@ function addControls() CR.dxccMenu.append(item); + CR.GridMenu = new nw.Menu(); + + item = new nw.MenuItem({ + type: "normal", + label: $.i18n("roster.add.watcher.label"), + click: function () + { + addWatcher(CR.callRoster[CR.targetHash].callObj.grid, "Grid"); + } + }); + + CR.GridMenu.append(item); + + item = new nw.MenuItem({ + type: "normal", + label: "Ignore Grid", + click: function () + { + ignoreGrid(CR.callRoster[CR.targetHash].callObj.grid); + } + }); + + CR.GridMenu.append(item); + + item = new nw.MenuItem({ + type: "normal", + label: $.i18n("roster.menu.EditIgnores"), + enabled: true, + click: function () + { + openIgnores(); + } + }); + + CR.GridMenu.append(item); + callsignNeed.value = CR.rosterSettings.callsign; huntMode.value = CR.rosterSettings.hunting; huntNeed.value = CR.rosterSettings.huntNeed; @@ -2358,6 +2460,14 @@ function handleContextMenu(ev) CR.targetHash = parent.id; CR.MsgMenu.popup(mouseX, mouseY); } + else if (name == "Grid") + { + if (CR.callRoster[parent.id].callObj.grid.length == 4) + { + CR.targetHash = parent.id; + CR.GridMenu.popup(mouseX, mouseY); + } + } else if (name == "CQ") { if (CR.callRoster[parent.id].DXcall != "CQ") @@ -3753,13 +3863,15 @@ function watcherTypeChanged(value) watcherType.value = value; if (value == "Callsign") { - // fix i18n - watcherTextTh.innerHTML = "Callsign"; + watcherTextTh.innerHTML = $.i18n("roster.controls.hunting.callsign"); } if (value == "Calling") { - // fix i18n - watcherTextTh.innerHTML = "Calling"; + watcherTextTh.innerHTML = $.i18n("alerts.QRZ.speech"); + } + if (value == "Grid") + { + watcherTextTh.innerHTML = $.i18n("roster.controls.hunting.grid"); } if (value == "Message") { @@ -3789,6 +3901,11 @@ function watcherOnText() testCallsign = true; watcherText.value = watcherText.value.toUpperCase().replace(/[^A-Z0-9/\s]+/g, ""); } + else if (watcherType.value == "Grid") + { + gridInputValidate(watcherText); + return; + } else { testCallsign = true; diff --git a/package.nw/lib/roster/processRosterFiltering.js b/package.nw/lib/roster/processRosterFiltering.js index 969a0e2..413a79d 100644 --- a/package.nw/lib/roster/processRosterFiltering.js +++ b/package.nw/lib/roster/processRosterFiltering.js @@ -18,6 +18,8 @@ const CALLSIGN_REGEXP = for a optional list of postindicators separated by `\/` from the rest of the call */ +const GRID_REGEXP = /^[A-Z]{2}[0-9]{2}$/ + function processRosterFiltering(callRoster, rosterSettings) { // First loop, exclude calls, mostly based on "Exceptions" settings @@ -83,6 +85,11 @@ function processRosterFiltering(callRoster, rosterSettings) entry.tx = false; continue; } + if (callObj.grid in CR.blockedGrid) + { + entry.tx = false; + continue; + } if (CR.rosterSettings.cqOnly == true) { if (CR.rosterSettings.wantRRCQ == true) diff --git a/package.nw/lib/roster/processRosterHunting.js b/package.nw/lib/roster/processRosterHunting.js index 798ff31..f2b6260 100644 --- a/package.nw/lib/roster/processRosterHunting.js +++ b/package.nw/lib/roster/processRosterHunting.js @@ -57,7 +57,7 @@ function processRosterHunting(callRoster, rosterSettings, awardTracker) // If they are not ignored or we're in a QSO with them, let it through // TODO: This is here because it's after the filtering stage - if ((!(entry.DEcall in CR.blockedCalls) && !(callObj.dxcc in CR.blockedDxcc)) || + if ((!(entry.DEcall in CR.blockedCalls) && !(callObj.dxcc in CR.blockedDxcc) && !(callObj.grid in CR.blockedGrid)) || window.opener.GT.instances[callObj.instance].status.DXcall == entry.DEcall) { entry.tx = true; @@ -91,6 +91,7 @@ function processRosterHunting(callRoster, rosterSettings, awardTracker) callObj.DEcallHTML = null; callObj.DXcallHTML = null; callObj.msgHTML = null; + callObj.gridHTML = null; let colorObject = Object(); @@ -833,6 +834,11 @@ function buildWatcher(watcher) watcher.source = "DXcall"; watcher.html = "DXcallHTML"; } + else if (watcher.type == "Grid") + { + watcher.source = "grid"; + watcher.html = "gridHTML"; + } else { watcher.source = "msg"; diff --git a/package.nw/lib/roster/rosterColumns.js b/package.nw/lib/roster/rosterColumns.js index f84ed1e..1625631 100644 --- a/package.nw/lib/roster/rosterColumns.js +++ b/package.nw/lib/roster/rosterColumns.js @@ -102,7 +102,8 @@ const ROSTER_COLUMNS = { tableData: (callObj) => ({ rawAttrs: callObj.style.grid, onClick: `centerOn("${callObj.grid}")`, - html: (callObj.grid.length > 0 ? callObj.grid : " ") + name: "Grid", + html: (callObj.grid.length > 0 ? callObj.gridHTML || callObj.grid : " ") }) }, diff --git a/package.nw/lib/style.css b/package.nw/lib/style.css index 225b87e..b7da5fb 100644 --- a/package.nw/lib/style.css +++ b/package.nw/lib/style.css @@ -270,6 +270,26 @@ html, body { min-width: 20px; outline: none; } + +.QsoQslActive { + background: linear-gradient(90deg, yellow, blue); + background-size: 200% 200%; + animation: AnimationQsoQsl 1s ease infinite; + text-shadow: black 0 0 6px; +} + +@keyframes AnimationQsoQsl { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + .roundBorderDEInfo { border: 1px solid white; -webkit-border-radius: 6px; diff --git a/package.nw/package.json b/package.nw/package.json index e81f5e2..209f166 100644 --- a/package.nw/package.json +++ b/package.nw/package.json @@ -1,7 +1,7 @@ { "name": "GridTracker", "product_string_do_not_use": "gridtracker", - "version": "1.23.1207", + "version": "1.23.1217", "betaVersion": "", "description": "GridTracker: An Amateur Radio Companion", "author": "GridTracker.org",