Merge branch 'master' into rot_dir_btns_save

This commit is contained in:
Petr Hlozek 2022-05-14 16:28:12 +02:00 committed by GitHub
commit edf4bd2a9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 566 additions and 370 deletions

View File

@ -320,8 +320,47 @@ Some <strong>TRX like ICOM don't have support for this in HamLib. To get mode se
all values to 0 (zero).</strong>
</p><p><strong>User definable digital modes</strong> can be set up in a separate box. Use comma
as a separator, ie. MYMODE1,MYMODE2 etc.<br>
If user adds digital modes (submode names) exactly as written in this table <a href="https://adif.org/312/ADIF_312.htm#Mode_Enumeration">ADIF.org: Mode_Enumeration</a> ADIF export will place correct mode and submode tags to exported file.
Submode list is copied at 2021-08-25 and may need updating of source code some day in future.
user should add digital modes (submode names) exactly as written in this table <a href="https://adif.org/312/ADIF_312.htm#Mode_Enumeration">ADIF.org: Mode_Enumeration</a>
If mode is missing from <strong>NewQSO/mode</strong> selection list and not added to <strong>User defined digital modes</strong> it may prevent ADIF import causing "wrong mode" error.
</p><p>
<strong>Note:</strong><br>
Cqrlog uses internally modefied mode name. We call it here <strong>CqrMode</strong>. CqrMode is created from ADIF mode and submode with conversion table. CqrMode is mainly ADIF submode if it exist, with some exceptions.
<br>Cqrlog will create four files in ~/.config/cqrlog folder for this use if they do not exist. One is a brief <strong>README_modefiles</strong> explaining three other files purposes.
<br><br>If files exist they are not overwritten keeping possible user changes there. How ever user must do backups by himself if files are edited from original format.
These files apply to all logs created. They are not log based.
<ul>
<li><strong>submode_mode.txt</strong>
<br> This file holds submode=mode pairs used to convert incoming mode+submode pair to CqrMode that mainly is the submode.
<br><br> All pairs must be in uppercase format. User can add or delete mode pairs with text editor if definition at
<br> <a href="https://adif.org/312/ADIF_312.htm#Mode_Enumeration">ADIF.org: Mode_Enumeration</a> changes.
<br>"Self invented" mode names should not be used! Just one mode pair is accepted in one line.
<br> The first line is never read (lower case). It just shows the order of submode and mode.
<br><br>This file is used also when qso record is ADIF exported. Then CqrMode is converted back to mode+sumbode tags.
<br>
</li>
<li><strong>import_mode.txt</strong>
<br>This file holds a list of deprecated ADIF submodes that are accepted only for input. They are used in CqrModes but they will never be ADIF exported out from Cqrlog.
<br><br> All lines must be in uppercase format. User can add or delete lines with text editor if definition at
<br> <a href="https://adif.org/312/ADIF_312.htm#Mode_Enumeration">ADIF.org: Mode_Enumeration</a> changes.
<br>"Self invented" mode names should not be used! Just one mode is accepted in one line.
<br> The first line is never read (lower case). It just shows the meaning of then list.
<br><br>This file is used also when qso record is ADIF exported. It prevents submode in list to export and only mode is exported.
<br>
</li>
<li><strong>exception_mode.txt</strong>
<br>This file holds submode=mode pairs used to convert incoming mode+submode pair to CqrMode when CqrMode can not use ADIF submode directly.
<br>For example by ADIF definition mode SSB has submodes USB and LSB. How ever Cqrlog does not use those as CqrMode, but uses only SSB.
Then CqrMode is converted as SSB. How ever after exception the mode can not have it's submode back when exporting ADIF from Cqrlog.
<br><br>This file can also have conversion from rigctld given mode to ADIF mode. For example with IC7300 rigctld shows mode PACKETUSB if rig is set to usb and data mode:
<br> then this file can convert PACKETUSB to PKT that is ADIF standard format.
<br><br> All pairs must be in uppercase format. User can add or delete mode pairs with text editor when needed.
<br>How ever in case of outgoing modes (outgoing mode is at right side of mode pair) <a href="https://adif.org/312/ADIF_312.htm#Mode_Enumeration">ADIF.org: Mode_Enumeration</a> should be used.
<br>"Self invented" mode names should not be used! Just one mode pair is accepted in one line.
<br> The first line is never read (lower case). It just shows the order of submode and mode.
</li>
</ul>
</p>
<p align=center><img src=img/line.png></p>
<a name=ah9><h2><strong>QTH Profiles</strong></h2></a>

View File

@ -514,6 +514,10 @@ begin
time_on := Q2.FieldByName('time_on').AsString;
time_on := copy(time_on,1,2) + copy(time_on,4,2);
//2022-05-05 OH1KH I do not know (I can not test) are mode+submode pairs needed with log uploads
// or is the CqrMode ok here ???????
//If mode+submode needed then use dmUtils.ModeFromCqr to get mode and submode at this point
// (look sample from fLoTWExport.pas line 453-460)
adif := GetAdifValue('QSO_DATE',qsodate)+GetAdifValue('TIME_ON',time_on)+
GetAdifValue('CALL',Q2.FieldByName('callsign').AsString)+
GetAdifValue('BAND',Q2.FieldByName('band').AsString)+

View File

@ -1,26 +1,26 @@
object dmUtils: TdmUtils
OnCreate = DataModuleCreate
OnDestroy = DataModuleDestroy
OldCreateOrder = False
Height = 300
HorizontalOffset = 365
VerticalOffset = 366
Width = 400
PPI = 96
object HelpDatabase: THTMLHelpDatabase
BaseURL = 'file:///usr/share/cqrlog/help'
AutoRegister = True
KeywordPrefix = 'help/'
left = 176
top = 40
Left = 176
Top = 40
end
object HelpViewer: THTMLBrowserHelpViewer
BrowserParams = '%s'
AutoRegister = True
left = 272
top = 40
Left = 272
Top = 40
end
object Datasource1: TDataSource
left = 56
top = 48
Left = 56
Top = 48
end
end

View File

@ -88,6 +88,12 @@ const
'NAME_INTL', 'NOTES_INTL', 'QSLMSG_INTL', 'QTH_INTL',
'RIG_INTL', 'SIG_INTL', 'SIG_INFO_INTL');
c_MODEFILE_DIR = ''; // 'ctyfiles/';
C_SUBMODE_FILE = 'submode_mode.txt';
C_IMPORTMODE_FILE = 'import_mode.txt';
C_EXCEPMODE_FILE = 'exception_mode.txt';
C_READMEMODE_FILE = 'README_modefiles';
type
{ TdmUtils }
@ -97,16 +103,21 @@ type
HelpViewer: THTMLBrowserHelpViewer;
HelpDatabase: THTMLHelpDatabase;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
private
fTimeOffset: currency;
fGrayLineOffset: currency;
fQRZSession: string;
fHamQTHSession: string;
fSysUTC: boolean;
SubmodeMode: TStringList;
ImportMode : TStringlist;
ExceptMode : TStringlist;
procedure LoadRigList(RigCtlBinaryPath : String;RigList : TStringList);
procedure LoadRigListCombo(CurrentRigId : String; RigList : TStringList; RigComboBox : TComboBox);
procedure ModeConvListsCreate(SetUp:boolean);
procedure MakeMissingModeFile(num:integer);
function nr(ch: char): integer;
function GetTagValue(Data, tg: string): string;
@ -116,6 +127,7 @@ type
var nick, qth, address, zip, grid, state, county, qsl, iota, waz, itu, ErrMsg: string): boolean;
function GetHamQTHInfo(call: string;
var nick, qth, address, zip, grid, state, county, qsl, iota, waz, itu, dok, ErrMsg: string): boolean;
public
s136: string;
s630: string;
@ -152,6 +164,7 @@ type
//list of bands, band labels
BandFreq : array [0..cMaxBandsCount - 1]of BandVsFreq;
property TimeOffset: currency read fTimeOffset write fTimeOffset;
property GrayLineOffset: currency read fGraylineOffset write fGrayLineOffset;
property SysUTC: boolean read fSysUTC write fSysUTC;
@ -204,11 +217,12 @@ type
procedure LoadRigsToComboBox(CurrentRigId : String; RigCtlBinaryPath : String; RigComboBox : TComboBox);
procedure GetShorterCoordinates(latitude,longitude : Currency; var lat, long : String);
procedure LoadListOfFiles(Path, Mask : String; ListOfFiles : TStringList);
procedure BandFromDbase;
procedure BandFromDbase;
procedure UpdateHelpBrowser;
procedure ModeFromCqr(CqrMode:String;var OutMode,OutSubmode:String;dbg:Boolean);
function BandFromArray(tmp:Currency):string;
function MyDefaultBrowser:String;
function MyDefaultBrowser:String;
function StrToDateFormat(sDate : String) : TDateTime;
function DateToSQLIteDate(date : TDateTime) : String;
function GetBandFromFreq(MHz : string): String;
@ -297,6 +311,8 @@ type
function LoadVisibleColumnsConfiguration : TColumnVisibleArray;
function StdFormatLocator(loc:string):String;
function IsHeDx(call:String; CqDir:String = ''):boolean;
function ModeToCqr(InMode,InSubmode:String;dbg:boolean=False):String;
end;
@ -598,7 +614,14 @@ begin
USstates[49] := 'WV, West Virginia';
USstates[50] := 'WY, Wyoming';
ModeConvListsCreate(True);
end;
procedure TdmUtils.DataModuleDestroy(Sender: TObject);
begin
ModeConvListsCreate(False);
end;
procedure TdmUtils.InsertContests(cmbContestName: TComboBox);
var
ListOfContests : TStringList;
@ -4774,5 +4797,246 @@ begin
Writeln('My continent is:', mycont, ' His continent is:', cont,' is DX/CQ for me:',Result);
end;
end;
procedure TdmUtils.ModeFromCqr(CqrMode:String;var OutMode,OutSubmode:String;dbg:Boolean);
//encodes Cqrlog's mode to mode and submode pair
//returns empty string to submode if not exist
var
e: integer;
Begin
if dbg then
Writeln('ModeFromCqr: ',CqrMode);
Cqrmode:=uppercase(CqrMode); //this is for sure
//cqrmode -> ex_mode
e:= ExceptMode.IndexOfName(CqrMode);
if e > -1 then
Begin
OutMode := uppercase(ExceptMode.Values[CqrMode]);
OutSubmode:='';
if dbg then
begin
Writeln('ex_mode=cqrlogmode line: ',e+1);
Writeln('Cqrlog will export adif as mode: ',OutMode,' submode: ',OutSubmode);
end;
exit;
end;
// cqrmode -> mode+submode
e:= SubmodeMode.IndexOfName(CqrMode);
if e > -1 then
Begin
OutMode := uppercase(SubmodeMode.Values[CqrMode]);
OutSubmode := CqrMode;
if dbg then
Writeln('submode=mode line: ',e+1);
//is submode import only
e:=ImportMode.IndexOf(CqrMode);
if e > -1 then
begin
if dbg then
Writeln('submode for_import_only line: ',e+1);
OutSubmode :='';
end;
end
else
//no submodes
Begin
OutMode := CqrMode;
OutSubmode:='';
end;
if dbg then
Writeln('Cqrlog will export adif as mode: ',OutMode,' submode: ',OutSubmode);
end;
function TdmUtils.ModeToCqr(InMode,InSubmode:String;dbg:boolean=False):String;
//decodes mode and submode pair to mode used by Cqrlog internally
var
e: integer;
Begin
if dbg then
Writeln('ModeToCqr mode: ',InMode,' submode: ',InSubmode);
InMode:=uppercase(InMode); //this is for sure
InSubmode:=uppercase(InSubmode);
Result:=InMode; //defaults to InMode
if InSubmode='' then
Begin
if dbg then
writeln('Cqrlog internal mode will be: ',Result);
exit;
end;
e:= SubmodeMode.IndexOfName(InSubmode);
if (e > -1 ) then //it exist
Begin
if dbg then
Writeln('submode=mode line: ',e+1);
Result:=InSubmode;
end;
e:= ExceptMode.IndexOfName(Result);
if e > -1 then //it exist
begin
if dbg then
Writeln('ex_mode=cqrlogmode line: ',e+1);
Result:= ExceptMode.ValueFromIndex[e];
end;
Result:=uppercase(Result); //this is for sure
if dbg then
writeln('Cqrlog internal mode will be: ',Result);
end;
procedure TdmUtils.ModeConvListsCreate(SetUp:boolean);
Begin
if not SetUp then
Begin
if assigned(SubmodeMode) then FreeAndNil(SubmodeMode);
if assigned(ImportMode) then FreeAndNil(ImportMode);
if assigned(ExceptMode) then FreeAndNil(ExceptMode);
exit;
end;
SubmodeMode:= TStringList.Create;
ImportMode := TStringlist.Create;
ExceptMode := TStringlist.Create;
//if we do not find one of these files we create it
if FileSearch(C_SUBMODE_FILE,dmData.HomeDir+C_MODEFILE_DIR,[])='' then
MakeMissingModeFile(1);
if FileSearch(C_IMPORTMODE_FILE,dmData.HomeDir+C_MODEFILE_DIR,[])='' then
MakeMissingModeFile(2);
if FileSearch(C_EXCEPMODE_FILE,dmData.HomeDir+C_MODEFILE_DIR,[])='' then
MakeMissingModeFile(3);
if FileSearch(C_READMEMODE_FILE,dmData.HomeDir+C_MODEFILE_DIR,[])='' then
MakeMissingModeFile(4);
try
SubmodeMode.LoadFromFile(dmData.HomeDir+C_MODEFILE_DIR+C_SUBMODE_FILE);
ImportMode .LoadFromFile(dmData.HomeDir+C_MODEFILE_DIR+C_IMPORTMODE_FILE);
ExceptMode.LoadFromFile(dmData.HomeDir+C_MODEFILE_DIR+C_EXCEPMODE_FILE);
except
on E : Exception do writeln('Could not load mode conversion files!');
end;
if dmData.DebugLevel>=1 then
Begin
Writeln('Loaded mode conversion files:');
Writeln(' ',SubmodeMode.Strings[0]);
Writeln(' ',ImportMode.Strings[0]);
Writeln(' ',ExceptMode.Strings[0]);
end;
end;
procedure TdmUtils.MakeMissingModeFile(num:integer);
//the idea not to use const for conversion is that when they are put in files
//later additions and deletions can be done by user without compile
Const
S_file: array [1..168] of string = (
'submode=mode','8PSK125=PSK','8PSK125F=PSK','8PSK125FL=PSK','8PSK250=PSK','8PSK250F=PSK','8PSK250FL=PSK','8PSK500=PSK','8PSK500F=PSK','8PSK1000=PSK',
'8PSK1000F=PSK','8PSK1200F=PSK','AMTORFEC=TOR','ASCI=RTTY','CHIP64=CHIP','CHIP128=CHIP','DOM-M=DOMINO','DOM4=DOMINO','DOM5=DOMINO','DOM8=DOMINO',
'DOM11=DOMINO','DOM16=DOMINO','DOM22=DOMINO','DOM44=DOMINO','DOM88=DOMINO','DOMINOEX=DOMINO','DOMINOF=DOMINO','FMHELL=HELL','FSK31=PSK','FSKHELL=HELL',
'FSQCALL=MFSK','FST4=MFSK','FST4W=MFSK','FT4=MFSK','GTOR=TOR','HELL80=HELL','HELLX5=HELL','HELLX9=HELL','HFSK=HELL','ISCAT-A=ISCAT',
'ISCAT-B=ISCAT','JS8=MFSK','JT4A=JT4','JT4B=JT4','JT4C=JT4','JT4D=JT4','JT4E=JT4','JT4F=JT4','JT4G=JT4','JT9-1=JT9',
'JT9-2=JT9','JT9-5=JT9','JT9-10=JT9','JT9-30=JT9','JT9A=JT9','JT9B=JT9','JT9C=JT9','JT9D=JT9','JT9E=JT9','JT9E=FAST',
'JT9F=JT9','JT9F=FAST','JT9G=JT9','JT9G=FAST','JT9H=JT9','JT9H=FAST','JT65A=JT65','JT65B=JT65','JT65B2=JT65','JT65C=JT65',
'JT65C2=JT65','JTMS=MFSK','LSB=SSB','MFSK4=MFSK','MFSK8=MFSK','MFSK11=MFSK','MFSK16=MFSK','MFSK22=MFSK','MFSK31=MFSK','MFSK32=MFSK',
'MFSK64=MFSK','MFSK64L=MFSK','MFSK128=MFSK','MFSK128L=MFSK','NAVTEX=TOR','OLIVIA 4/125=OLIVIA','OLIVIA 4/250=OLIVIA','OLIVIA 8/250=OLIVIA','OLIVIA 8/500=OLIVIA','OLIVIA 16/500=OLIVIA',
'OLIVIA 16/1000=OLIVIA','OLIVIA 32/1000=OLIVIA','OPERA-BEACON=OPERA','OPERA-QSO=OPERA','PAC2=PAC','PAC3=PAC','PAC4=PAC','PAX2=PAX','PCW=CW','PSK10=PSK',
'PSK31=PSK','PSK63=PSK','PSK63F=PSK','PSK63RC10=PSK','PSK63RC20=PSK','PSK63RC32=PSK','PSK63RC4=PSK','PSK63RC5=PSK','PSK125=PSK','PSK125RC10=PSK','PSK125RC12=PSK',
'PSK125RC16=PSK','PSK125RC4=PSK','PSK125RC5=PSK','PSK250=PSK','PSK250RC2=PSK','PSK250RC3=PSK','PSK250RC5=PSK','PSK250RC6=PSK','PSK250RC7=PSK','PSK500=PSK',
'PSK500RC2=PSK','PSK500RC3=PSK','PSK500RC4=PSK','PSK800RC2=PSK','PSK1000=PSK','PSK1000RC2=PSK','PSKAM10=PSK','PSKAM31=PSK','PSKAM50=PSK','PSKFEC31=PSK',
'PSKHELL=HELL','QPSK31=PSK','Q65=MFSK','QPSK63=PSK','QPSK125=PSK','QPSK250=PSK','QPSK500=PSK','QRA64A=QRA64','QRA64B=QRA64','QRA64C=QRA64',
'QRA64D=QRA64','QRA64E=QRA64','ROS-EME=ROS','ROS-HF=ROS','ROS-MF=ROS','SIM31=PSK','SITORB=TOR','SLOWHELL=HELL','THOR-M=THOR','THOR4=THOR',
'THOR5=THOR','THOR8=THOR','THOR11=THOR','THOR16=THOR','THOR22=THOR','THOR25X4=THOR','THOR50X1=THOR','THOR50X2=THOR','THOR100=THOR','THRBX=THRB',
'THRBX1=THRB','THRBX2=THRB','THRBX4=THRB','THROB1=THRB','THROB2=THRB','THROB4=THRB','USB=SSB'
);
I_file: array [1 .. 41] of string = (
'for_import_only','AMTORFEC','ASCI','CHIP64','CHIP128','DOMINOF','FMHELL','FSK31','GTOR','HELL80',
'HFSK','JT4A','JT4B','JT4C','JT4D','JT4E','JT4F','JT4G','JT65A','JT65B',
'JT65C','MFSK8','MFSK16','PAC2','PAC3','PAX2','PCW','PSK10','PSK31','PSK63',
'PSK63F','PSK125','PSKAM10','PSKAM31','PSKAM50','PSKFEC31','PSKHELL','QPSK31','QPSK63','QPSK125',
'THRBX'
);
{Exceptions file:
Cqrlog uses SSB for both USB and LSB
Cqrlog uses RTTY, some programs may export ASCI even when it is import only!
'PACKET':
these modes come from ICOM rig (IC7300) when DATA is selected with USB,LSB,FM or AM
and checkbox "auto" for mode is selected in NewQSO we put them all to PKT category here
as it is in ADIF standard
}
E_file: array [1 .. 9] of string = (
'ex_mode=cqrlogmode',
'USB=SSB',
'LSB=SSB',
'ASCI=RTTY',
'PACKET=PKT',
'PKTUSB=PKT',
'PKTLSB=PKT',
'PKTFM=PKT',
'PKTAM=PKT'
);
R_file: array [1 .. 22] of string = (
'Files to modify ADIF mode+submode to fit with Cqrlog.',
'Cqrlog internally uses submodes as mode. (only one database column -> mode)',
'',
'These files are manually created and can be changed if needed:',
'Contents are read to TStringLists at program start.',
'',
'submode_mode.txt',
' Submode=Mode',
' Used en/decoding mode-submode pairs for Cqrlog.',
'',
'import_mode.txt',
' Submode list for import only',
' Used to define deprecated submodes that are used ony for adif input.',
' These submodes do not export.',
'',
'exception_mode.txt',
' mode=cqrlogmode',
' Exceptions between "true" (sub)modes and internal cqrlog mode',
' Converts also in export "non adif" modes from rigctld like PACKET -> PKT',
'',
'Two first files created by https://adif.org/312/ADIF_312_annotated.htm#Mode_Enumeration',
'informations 2022-04-29,'
);
var f:TextFile;
//--------------------------------------------------------
procedure CreaFile(Fname:string;items:array of string);
var
i: integer;
itemsmax:integer;
begin
itemsmax:=length(items);
AssignFile(f,Fname);
try
rewrite(f);
try
for i:= 0 to itemsmax-1 do
Writeln(f, items[i]);
finally
CloseFile(f);
end;
except
on E: EInOutError do
ShowMessage('File handling error occurred. Details: ' + E.ClassName + '/' + E.Message);
end;
end;
//--------------------------------------------------------
Begin
if num=1 then CreaFile(dmData.HomeDir+C_MODEFILE_DIR+C_SUBMODE_FILE,S_file);
if num=2 then CreaFile(dmData.HomeDir+C_MODEFILE_DIR+C_IMPORTMODE_FILE,I_file);
if num=3 then CreaFile(dmData.HomeDir+C_MODEFILE_DIR+C_EXCEPMODE_FILE,E_file);
if num=4 then CreaFile(dmData.HomeDir+C_MODEFILE_DIR+C_READMEMODE_FILE,R_file);
end;
end.

View File

@ -46,6 +46,7 @@ type TnewQSOEntry=record //represents a new qso entry in the log
LOTW_QSL_RCVD:string[l_LOTW_QSL_RCVD];
LOTW_QSL_SENT:string[l_LOTW_QSL_SENT];
MODE:string[l_MODE];
SUBMODE:string[l_SUBMODE]; //we need this while processing cqrmode
MY_GRIDSQUARE:string[l_MY_GRIDSQUARE];
NAME:string[l_NAME];
NOTES:string[l_NOTES];
@ -140,7 +141,6 @@ type
procedure mnueditClick(Sender: TObject);
procedure mnuImportClick(Sender: TObject);
private
LockSubMode : boolean; //if we replace mode with submode we set lock in case that submode and mode are in opposite order in qso record.
LocalDbg : Boolean;
AbortImport : boolean;
ERR_FILE : String;
@ -296,58 +296,44 @@ function TfrmAdifImport.fillTypeVariableWithTagData(h:longint;var data:string;va
h_LOTW_QSL_RCVD :d.LOTW_QSL_RCVD:=TrimDataLen(adifTag,data,l_LOTW_QSL_RCVD);
h_LOTW_QSL_SENT :d.LOTW_QSL_SENT:=TrimDataLen(adifTag,data,l_LOTW_QSL_SENT);
// DL7OAP: because MODE-field in cqrlog database does not match completely
// with MODE field of ADIF specification, we have to transfer the
// ADIF MODES/SUBMODES (JS8, FT4, FST4,PKT) to MODE-field in cqrlog database
h_MODE :d.MODE := UpperCase(TrimDataLen(adifTag,data,l_MODE));
h_SUBMODE :d.SUBMODE := UpperCase(TrimDataLen(adifTag,data,l_SUBMODE));
//OH1KH: we can put all submodes to mode when importing
h_MODE : begin
if not LockSubMode then //do not override mode if already set by submode
if data = 'PKT' then d.MODE:='PACKET'
else d.MODE:=UpperCase(TrimDataLen(adifTag,data,l_MODE));
end;
h_SUBMODE : begin
// Cqrlog does not use USB and LSB (submodes)
// but it is fixed in function saveNewEntryFromADIFinDatabase
d.MODE:=UpperCase(TrimDataLen(adifTag,data,l_MODE));
LockSubMode:=true;
end;
h_MY_GRIDSQUARE :d.MY_GRIDSQUARE:=dmUtils.StdFormatLocator(data);
h_NAME :d.NAME:=TrimDataLen(adifTag,data,l_NAME);
h_NOTES :d.NOTES:=TrimDataLen(adifTag,data,l_NOTES);
h_PFX :d.PFX:=UpperCase(TrimDataLen(adifTag,data,l_PFX));
h_QSLMSG :d.QSLMSG:=TrimDataLen(adifTag,data,l_QSLMSG);
h_QSLRDATE :d.QSLRDATE:=TrimDataLen(adifTag,data,l_QSLRDATE);
h_QSLSDATE :d.QSLSDATE:=TrimDataLen(adifTag,data,l_QSLSDATE);
h_QSL_RCVD :d.QSL_RCVD:=TrimDataLen(adifTag,data,l_QSL_RCVD);
h_QSL_SENT :d.QSL_SENT:=TrimDataLen(adifTag,data,l_QSL_SENT);
h_QSL_VIA :d.QSL_VIA:=TrimDataLen(adifTag,data,l_QSL_VIA);
h_QSO_DATE :d.QSO_DATE:=TrimDataLen(adifTag,data,l_QSO_DATE);
h_QTH :d.QTH:=TrimDataLen(adifTag,data,l_QTH);
h_RST_RCVD :d.RST_RCVD:=TrimDataLen(adifTag,data,l_RST_RCVD);
h_RST_SENT :d.RST_SENT:=TrimDataLen(adifTag,data,l_RST_SENT);
h_SRX :d.SRX:=TrimDataLen(adifTag,data,l_SRX);
h_SRX_STRING :d.SRX_STRING:=TrimDataLen(adifTag,data,l_SRX_STRING);
h_STX :d.STX:=TrimDataLen(adifTag,data,l_STX);
h_STX_STRING :d.STX_STRING:=TrimDataLen(adifTag,data,l_STX_STRING);
h_CONTEST_ID :d.CONTEST_ID:=TrimDataLen(adifTag,data,l_CONTEST_ID);
h_DARC_DOK :d.DARC_DOK:=TrimDataLen(adifTag,data,l_DARC_DOK);
h_TIME_OFF :d.TIME_OFF:=copy(data,1,4);//can be HHMMSS but cqrlog uses HHMM both
h_TIME_ON :d.TIME_ON:=copy(data,1,4); //are valid adif forms so no Trim/Err here
h_TX_PWR :d.TX_PWR:=TrimDataLen(adifTag,data,l_TX_PWR);
h_APP_CQRLOG_DXCC :d.APP_CQRLOG_DXCC:=TrimDataLen(adifTag,data,l_APP_CQRLOG_DXCC);
h_APP_CQRLOG_QSLS :d.APP_CQRLOG_QSLS:=TrimDataLen(adifTag,data,l_APP_CQRLOG_QSLS);
h_APP_CQRLOG_PROFILE :d.APP_CQRLOG_PROFILE:=TrimDataLen(adifTag,data,l_APP_CQRLOG_PROFILE);
h_APP_CQRLOG_QSLR :d.APP_CQRLOG_QSLR:=TrimDataLen(adifTag,data,l_APP_CQRLOG_QSLR);
h_APP_CQRLOG_COUNTY :d.APP_CQRLOG_COUNTY:=TrimDataLen(adifTag,data,l_APP_CQRLOG_COUNTY);
h_CQZ :d.CQZ:=TrimDataLen(adifTag,data,l_CQZ);
h_STATE :d.STATE:=UpperCase(TrimDataLen(adifTag,data,l_STATE));
h_AWARD :d.AWARD:=TrimDataLen(adifTag,data,l_AWARD);
h_PROP_MODE :d.PROP_MODE:=TrimDataLen(adifTag,data,l_PROP_MODE);
h_SAT_NAME :d.SAT_NAME:=TrimDataLen(adifTag,data,l_SAT_NAME);
h_FREQ_RX :d.FREQ_RX:=TrimDataLen(adifTag,data,l_FREQ_RX);
h_OP :d.OP:=TrimDataLen(adifTag,data,l_OP);
h_MY_GRIDSQUARE :d.MY_GRIDSQUARE:=dmUtils.StdFormatLocator(data);
h_NAME :d.NAME:=TrimDataLen(adifTag,data,l_NAME);
h_NOTES :d.NOTES:=TrimDataLen(adifTag,data,l_NOTES);
h_PFX :d.PFX:=UpperCase(TrimDataLen(adifTag,data,l_PFX));
h_QSLMSG :d.QSLMSG:=TrimDataLen(adifTag,data,l_QSLMSG);
h_QSLRDATE :d.QSLRDATE:=TrimDataLen(adifTag,data,l_QSLRDATE);
h_QSLSDATE :d.QSLSDATE:=TrimDataLen(adifTag,data,l_QSLSDATE);
h_QSL_RCVD :d.QSL_RCVD:=TrimDataLen(adifTag,data,l_QSL_RCVD);
h_QSL_SENT :d.QSL_SENT:=TrimDataLen(adifTag,data,l_QSL_SENT);
h_QSL_VIA :d.QSL_VIA:=TrimDataLen(adifTag,data,l_QSL_VIA);
h_QSO_DATE :d.QSO_DATE:=TrimDataLen(adifTag,data,l_QSO_DATE);
h_QTH :d.QTH:=TrimDataLen(adifTag,data,l_QTH);
h_RST_RCVD :d.RST_RCVD:=TrimDataLen(adifTag,data,l_RST_RCVD);
h_RST_SENT :d.RST_SENT:=TrimDataLen(adifTag,data,l_RST_SENT);
h_SRX :d.SRX:=TrimDataLen(adifTag,data,l_SRX);
h_SRX_STRING :d.SRX_STRING:=TrimDataLen(adifTag,data,l_SRX_STRING);
h_STX :d.STX:=TrimDataLen(adifTag,data,l_STX);
h_STX_STRING :d.STX_STRING:=TrimDataLen(adifTag,data,l_STX_STRING);
h_CONTEST_ID :d.CONTEST_ID:=TrimDataLen(adifTag,data,l_CONTEST_ID);
h_DARC_DOK :d.DARC_DOK:=TrimDataLen(adifTag,data,l_DARC_DOK);
h_TIME_OFF :d.TIME_OFF:=copy(data,1,4);//can be HHMMSS but cqrlog uses HHMM both
h_TIME_ON :d.TIME_ON:=copy(data,1,4); //are valid adif forms so no Trim/Err here
h_TX_PWR :d.TX_PWR:=TrimDataLen(adifTag,data,l_TX_PWR);
h_APP_CQRLOG_DXCC :d.APP_CQRLOG_DXCC:=TrimDataLen(adifTag,data,l_APP_CQRLOG_DXCC);
h_APP_CQRLOG_QSLS :d.APP_CQRLOG_QSLS:=TrimDataLen(adifTag,data,l_APP_CQRLOG_QSLS);
h_APP_CQRLOG_PROFILE :d.APP_CQRLOG_PROFILE:=TrimDataLen(adifTag,data,l_APP_CQRLOG_PROFILE);
h_APP_CQRLOG_QSLR :d.APP_CQRLOG_QSLR:=TrimDataLen(adifTag,data,l_APP_CQRLOG_QSLR);
h_APP_CQRLOG_COUNTY :d.APP_CQRLOG_COUNTY:=TrimDataLen(adifTag,data,l_APP_CQRLOG_COUNTY);
h_CQZ :d.CQZ:=TrimDataLen(adifTag,data,l_CQZ);
h_STATE :d.STATE:=UpperCase(TrimDataLen(adifTag,data,l_STATE));
h_AWARD :d.AWARD:=TrimDataLen(adifTag,data,l_AWARD);
h_PROP_MODE :d.PROP_MODE:=TrimDataLen(adifTag,data,l_PROP_MODE);
h_SAT_NAME :d.SAT_NAME:=TrimDataLen(adifTag,data,l_SAT_NAME);
h_FREQ_RX :d.FREQ_RX:=TrimDataLen(adifTag,data,l_FREQ_RX);
h_OP :d.OP:=TrimDataLen(adifTag,data,l_OP);
else begin
{ writeln('Unnamed...>',pom,'<');fillTypeVariableWithTagData:=false;exit;}
@ -396,9 +382,11 @@ begin
if (not dmUtils.IsLocOK(d.MY_GRIDSQUARE)) or chkOverrideLocator.Checked then
d.MY_GRIDSQUARE := FMyLoc;
d.CALL := UpperCase(d.CALL);
if (d.MODE = 'USB') or (d.MODE ='LSB') then
d.MODE := 'SSB';
if (d.FREQ = '') or (d.FREQ = '0') then
//convert mode and submode to cqrmode here
d.MODE:=dmUtils.ModeToCqr(d.MODE,d.SUBMODE,LocalDbg);
if (d.FREQ = '') or (d.FREQ = '0') then
d.FREQ := dmUtils.FreqFromBand(d.BAND,d.MODE);
d.QSO_DATE := dmUtils.ADIFDateToDate(d.QSO_DATE);
@ -837,7 +825,6 @@ begin
WriteWrongADIF(tmp,'Imported with shrink(s):'+#10+CutErrText);
CutErrText:='';
tmp:='';
LockSubMode :=false;
end;
fillTypeVariableWithTagData(h,data,D,adifTag);
end;
@ -1047,6 +1034,7 @@ begin
else begin
AssignFile(f,dmData.UsrHomeDir + ERR_FILE);
Rewrite(f);
Writeln(f);
Writeln(f,'ADIF export from CQRLOG for Linux version ' + dmData.VersionString);
Writeln(f,'Copyright (C) ',YearOf(now),' by Petr, OK2CQR and Martin, OK1RR');
Writeln(f,'Internet: http://www.cqrlog.com');

View File

@ -208,6 +208,8 @@ begin
end;
function TfrmCabrilloExport.CabrilloMode(mode: string): String;
//2022-05-05 OH1KH It seems that Cabrilllo mode can be CqrMode (mainly CW,SSB,AM,FM,RTTY)(I.E. no mode+submode pairs needed)
//otherwise use dmUtils.ModeFromCqr to get mode and submode at this function
begin
Result := '';
case mode of

View File

@ -167,14 +167,34 @@ begin
rewrite(f);
Writeln(f, '#!/bin/bash');
Writeln(f);
Writeln(f, 'echo -e "\nCreating backup of all CQRLOG logs in database to /tmp/allcqrlogs.sql\n"');
Writeln(f, 'stamp=$(date +_%Y%m%d-%H%M)');
Writeln(f, 'echo -e "\nStarted$stamp"');
Writeln(f, 'echo -e "Creating common backup of all CQRLOG logs in database to /tmp/allcqrlogs$stamp.sql"');
Writeln(f, '$(mysql -u' + user + ' -p' + pass + ' -B -N -h' + ip + ' -P' + port +
' -e " show databases like ' + #$27 + 'cqr%' + #$27 + '" |\');
' -e " show databases like ' + #$27 + 'cqr%' + #$27 + '" |\');
Writeln(f, 'xargs echo -n mysqldump -q -h' + ip + ' -P' + port + ' -u' +
user + ' -p' + pass + ' --databases) > /tmp/allcqrlogs.sql');
Writeln(f, 'echo -e "Done!\nCopy backup file to your safe place.\nIt will be erased from /tmp at next Linux start\n\nTo restore all CQRLOG logs use command:\n"');
user + ' -p' + pass + ' --databases) > /tmp/allcqrlogs$stamp.sql');
Writeln(f, 'echo -e "Creating separate backups of each CQRLOG logXXX in database to /tmp/cqrlogXXX$stamp.sql(s)\n"');
Writeln(f, 'mysql -u' + user + ' -p' + pass + ' -B -N -h' + ip + ' -P' + port +
' -e " show databases like ' + #$27 + 'cqr%' + #$27 + '" |\');
Writeln(f, 'xargs -d\ | while read line; do if [[ $line != "" ]];then\');
Writeln(f, ' echo "mysqldump -q -h' + ip + ' -P' + port + ' -u' +
user + ' -p' + pass + ' $line > /tmp/$line$stamp.sql";fi;done > /tmp/sepsql.sh');
Writeln(f, 'chmod a+x /tmp/sepsql.sh');
Writeln(f, '/tmp/sepsql.sh');
Writeln(f, 'rm /tmp/sepsql.sh');
Writeln(f, 'echo -e "\nDone!\nCopy backup files to your safe place.\n'+
'They will be erased from /tmp at next Linux start\n\n"');
Writeln(f, 'echo "To restore all CQRLOG logs use command:"');
Writeln(f, 'echo -e "mysql -h' + ip + ' -P' + port + ' -u' + user + ' -p' + pass +
' < /tmp/allcqrlogs$stamp.sql\n\n"');
Writeln(f, 'echo "To restore single a log use command:"');
Writeln(f, 'echo "mysql -h' + ip + ' -P' + port + ' -u' + user + ' -p' + pass +
' < /tmp/allcqrlogs.sql"');
' cqrlog001 < /tmp/cqrlog001$stamp.sql"');
Writeln(f, 'echo -e "\nBe sure that both log numbers used in line are equal"');
closeFile(f);
dmUtils.ExecuteCommand('chmod a+rwx ' + UsrHome + 'backup_all_cqr.sh');
end;

View File

@ -102,6 +102,8 @@ begin
end;
function TfrmEDIExport.EdiMode(mode: string): String;
//2022-05-05 OH1KH It seems that EDI mode can be CqrMode (I.E. no mode+submode pairs needed)
//otherwise use dmUtils.ModeFromCqr to get mode and submode at this point
begin
Result := '0';
case mode of

View File

@ -188,7 +188,10 @@ var
srx, stx_string, srx_string, contestname, Darc_Dok : String);
var
station_callsign : String;
station_callsign : String;
OutMode,
OutSubmode :String;
begin
station_callsign := cqrini.ReadString('Station', 'Call', '');
leng := 0;
@ -219,120 +222,11 @@ var
if ExCall then
SaveTag(dmUtils.StringToADIF('<CALL',dmUtils.RemoveSpaces(call)),leng);
if ExMode then
begin
case Mode of
'PACKET' : begin tmp := '<MODE:3>PKT'; SaveTag(tmp,leng); end;
//these modes come from ICOM rig (IC7300) when DATA is selected with USB,LSB,FM or AM
//and checkbox "auto" for mode is selected in NewQSO
//There is not clear what mode is then actually used (depends on additional program in use)
//but we put them all to PKT category here
'PKTUSB' : begin tmp := '<MODE:3>PKT'; SaveTag(tmp,leng); end;
'PKTLSB' : begin tmp := '<MODE:3>PKT'; SaveTag(tmp,leng); end;
'PKTFM' : begin tmp := '<MODE:3>PKT'; SaveTag(tmp,leng); end;
'PKTAM' : begin tmp := '<MODE:3>PKT'; SaveTag(tmp,leng); end;
//definitions by https://adif.org/312/ADIF_312.htm#Mode_Enumeration
'CHIP64','CHIP128' : begin tmp := '<MODE:4>CHIP<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'PCW' : begin tmp := '<MODE:2>CW<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'DOM-M','DOM4','DOM5',
'DOM8','DOM11','DOM16',
'DOM22','DOM44','DOM88',
'DOMINOEX','DOMINOF' : begin tmp := '<MODE:6>DOMINO<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'FELDHELL', //this is non standard that fldigi uses
'FMHELL','FSKHELL',
'HELL80','HELLX5',
'HELLX9','HFSK',
'PSKHELL','SLOWHELL' : begin tmp := '<MODE:4>HELL<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'ISCAT-A','ISCAT-B' : begin tmp := '<MODE:5>ISCAT<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'JT4A','JT4B','JT4C',
'JT4D','JT4E','JT4F',
'JT4G' : begin tmp := '<MODE:3>JT4<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'JT9-1','JT9-2','JT9-5',
'JT9-10','JT9-30',
'JT9A','JT9B','JT9C',
'JT9D','JT9E','JT9E FAST',
'JT9F','JT9F FAST','JT9G',
'JT9G FAST','JT9H',
'JT9H FAST' : begin tmp := '<MODE:3>JT9<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'FSQCALL','FST4','FST4W',
'FT4','JS8','JTMS','MFSK4',
'MFSK8','MFSK11','MFSK16',
'MFSK22','MFSK31','MFSK32',
'MFSK64','MFSK64L',
'MFSK128' : begin tmp := '<MODE:4>MFSK<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
//OLIVIA is exception #1
'OPERA-BEACON',
'OPERA-QSO' : begin tmp := '<MODE:5>OPERA<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'PAC2','PAC3','PAC4' : begin tmp := '<MODE:3>PAC<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'PAX2' : begin tmp := '<MODE:3>PAX<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'8PSK125','8PSK125F',
'8PSK125FL','8PSK250',
'8PSK250F','8PSK250FL',
'8PSK500','8PSK500F',
'8PSK1000','8PSK1000F',
'8PSK1200F','FSK31','PSK10',
'PSK31','PSK63','PSK63F',
'PSK63RC4','PSK63RC5',
'PSK63RC10','PSK63RC20',
'PSK63RC32','PSK125',
'PSK125C12','PSK125R',
'PSK125RC10','PSK125RC12',
'PSK125RC16','PSK125RC4',
'PSK125RC5','PSK250',
'PSK250C6','PSK250R',
'PSK250RC2','PSK250RC3',
'PSK250RC5','PSK250RC6',
'PSK250RC7','PSK500',
'PSK500C2','PSK500C4',
'PSK500R','PSK500RC2',
'PSK500RC3','PSK500RC4',
'PSK800C2','PSK800RC2',
'PSK1000','PSK1000C2',
'PSK1000R','PSK1000RC2',
'PSKAM10','PSKAM31',
'PSKAM50','PSKFEC31',
'QPSK31','QPSK63',
'QPSK125','QPSK250',
'QPSK500','SIM31' : begin tmp := '<MODE:3>PSK<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'QRA64A','QRA64B','QRA64C',
'QRA64D','QRA64E' : begin tmp := '<MODE:5>QRA64<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'ROS-EME','ROS-HF',
'ROS-MF' : begin tmp := '<MODE:3>ROS<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'ASCI','ASCII' : begin tmp := '<MODE:4>RTTY<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'LSB','USB' : begin tmp := '<MODE:3>SSB<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'THOR-M','THOR4','THOR5',
'THOR8','THOR11','THOR16',
'THOR22','THOR25X4',
'THOR50X1','THOR50X2',
'THOR100' : begin tmp := '<MODE:4>THOR<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'THRBX','THRBX1','THRBX2',
'THRBX4','THROB1','THROB2',
'THROB4' : begin tmp := '<MODE:4>THRB<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
'AMTORFEC','GTOR','NAVTEX',
'SITORB' : begin tmp := '<MODE:3>TOR<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);end;
else begin
//exceptions follow
if pos('OLIVIA',mode)=1 then
//fldigi marks them with "-" that is against standard " "
//also there are more BW definitions than standard: will pass them all
begin
mode := StringReplace(mode,'-',' ',[rfReplaceAll]);
tmp := '<MODE:6>OLIVIA<SUBMODE:'+IntToStr(length(Mode))+'>'+Mode;SaveTag(tmp,leng);
end
else
//exceptions end
Begin
tmp := '<MODE';
SaveTag(dmUtils.StringToADIF(tmp,Mode),leng);
end;
end;
end;
Begin
dmUtils.ModeFromCqr(mode,OutMode,OutSubmode,dmData.DebugLevel>=1);
SaveTag(dmUtils.StringToADIF('<MODE',OutMode),leng);
if OutSubmode<>'' then
SaveTag(dmUtils.StringToADIF('<SUBMODE',OutSubmode),leng);
end;
if ExFreq then
begin
@ -547,6 +441,7 @@ begin //TfrmExportProgress
AssignFile(f, FileName);
Rewrite(f);
Writeln(f);
Writeln(f, 'ADIF export from CQRLOG for Linux version '+dmData.VersionString);
Writeln(f, 'Copyright (C) ',YearOf(now),' by Petr, OK2CQR and Martin, OK1RR');
Writeln(f);

View File

@ -52,9 +52,9 @@ type
procedure RegenerateDXCCStat;
procedure DownloadDXCCData;
procedure DownloadDOKData;
procedure CommonImport(var PosEOR:word;var f:TextFile;var call,band,mode,submode,qsodate,time_on,qslr,
procedure CommonImport(var PosEOR:word;var f:TextFile;var call,band,modeorig,mode,submodeorig,submode,qsodate,time_on,qslr,
qslrdate,cqz,ituz,iota,grid,state,county,qsorecord:String);
procedure WriteErrorRecord(f:char;call,band,mode,qsodate,time_on,qslr,qslrdate,
procedure WriteErrorRecord(f:char;call,band,modeorig,submodeorig,qsodate,time_on,qslr,qslrdate,
cqz,ituz,iota,grid,state,county,qsorecord:string;var s:Tstringlist);
procedure ImportLoTWAdif;
procedure ImportQSLMgrs;
@ -554,7 +554,7 @@ begin
Application.ProcessMessages;
end;
end;
procedure TfrmImportProgress.CommonImport(var PosEOR:word;var f:TextFile;var call,band,mode,submode,qsodate,time_on,qslr,
procedure TfrmImportProgress.CommonImport(var PosEOR:word;var f:TextFile;var call,band,modeorig,mode,submodeorig,submode,qsodate,time_on,qslr,
qslrdate,cqz,ituz,iota,grid,state,county,qsorecord:String);
var
a,
@ -615,10 +615,8 @@ Begin
'GRIDSQUARE' : if dmUtils.IsLocOK(data) then
grid := dmUtils.StdFormatLocator(data);
//if not mode set by submode then set mode
'MODE' : if mode='' then
mode := uppercase(data);
//submode overrides MODE, if exist
'SUBMODE' : mode := uppercase(data);
'MODE' : mode := uppercase(data);
'SUBMODE' : submode := uppercase(data);
'BAND' : band := uppercase(data);
'QSO_DATE' : qsodate := data;
'TIME_ON' : time_on := data;
@ -632,11 +630,13 @@ Begin
end; //case
end; //repeat
until pos('<EOR>',uppercase(Buf))=1;
//execption is SSB. Cqrlog does not use USB and LSB (submodes)
if (mode='USB') or (mode='LSB') then
mode:='SSB';
//store original modes
modeorig:=uppercase(mode);
submodeorig:=uppercase(submode);
//after this line mode will be changed to Cqrmode. submodeorig & modeorig has orignal ones stored for possible error reports
mode :=dmUtils.ModeToCqr(mode,submode,LocalDbg);
end;
procedure TfrmImportProgress.WriteErrorRecord(f:char;call,band,mode,qsodate,time_on,qslr,qslrdate,
procedure TfrmImportProgress.WriteErrorRecord(f:char;call,band,modeorig,submodeorig,qsodate,time_on,qslr,qslrdate,
cqz,ituz,iota,grid,state,county,qsorecord:string;var s:Tstringlist);
var
l,
@ -649,7 +649,8 @@ Begin
+'QSO NOT FOUND in log'+LineEnding
+'Call: '+call+LineEnding
+'Band: '+band+LineEnding
+'Mode: '+mode+LineEnding
+'Mode: '+modeorig+LineEnding
+'Submode: '+submodeorig+lineEnding
+'QSO_date: '+qsodate+LineEnding
+'Time_on: '+time_on+LineEnding;
if f='L' then
@ -685,21 +686,22 @@ var
f : TextFile;
PosEOH : Word;
PosEOR : Word;
qsorecord: String;
call : String;
band : String;
mode : String;
//submode not needed with lotw
submode : String;
qsodate : String;
time_on : String;
qslr : String;
qslrdate : String;
cqz : String;
ituz : String;
iota : String;
grid : String;
state : String;
qsorecord,
call,
band,
mode,
modeorig,
submode,
submodeorig,
qsodate,
time_on,
qslr,
qslrdate,
cqz,
ituz,
iota,
grid,
state,
county : String;
qso_in_log : Boolean = False;
@ -753,7 +755,9 @@ begin
call := '';
band := '';
mode := '';
modeorig := '';
submode := '';
submodeorig := '';
qsodate := '';
time_on := '';
qslr := '';
@ -768,9 +772,9 @@ begin
while not ((PosEOR > 0) or eof(f)) do //read all records
begin
qso_in_log := False;
CommonImport(PosEOR,f,call,band,mode,submode,qsodate,time_on,qslr,
CommonImport(PosEOR,f,call,band,modeorig,mode,submodeorig,submode,qsodate,time_on,qslr,
qslrdate,cqz,ituz,iota,grid,state,county,qsorecord);
//for now on the mode is converted Cqrmode
if PosEOR > 0 then
begin
if LocalDbg then
@ -779,7 +783,9 @@ begin
Writeln('Record Number: ',IntToStr(qsln));
Writeln('Call: ',call);
Writeln('Band: ',band);
Writeln('Mode: ',mode);
Writeln('Mode: ',modeorig);
Writeln('Submode: ',submodeorig);
Writeln('Cqrmode: ',mode);
Writeln('QSO_date: ',qsodate);
Writeln('Time_on: ',time_on);
Writeln('QSLR: ',qslr);
@ -796,15 +802,19 @@ begin
qsodate := dmUtils.ADIFDateToDate(qsodate);
qslrdate := dmUtils.ADIFDateToDate(qslrdate);
mode := UpperCase(mode);
if mode='JT65' then
mode := 'JT65A';
dmData.Q.Close;
//we compare Cqrmode in log to mode and submode received and Cqrmode created.
//If any of these is ok, qso is ok by mode.
//this makes backward compatible to old cqrlog loggings.
//Actually qso is ok even without mode check if other items fit!
dmData.Q.SQL.Text := 'select time_on,lotw_qslr,waz,itu,iota,loc,state,county,id_cqrlog_main from cqrlog_main ' +
'where (qsodate ='+QuotedStr(qsodate)+') '+
'and (band = ' + QuotedStr(band) + ')'+
// 'and (mode = ' + QuotedStr(mode) + ') and (band = ' + QuotedStr(band) + ')'+
'and ('+
'(mode = ' + QuotedStr(mode) +') or '+
'(mode = ' + QuotedStr(modeorig)+') or '+
'(mode = ' + QuotedStr(submodeorig)+') '+
')' +
'and (callsign = ' + QuotedStr(call) + ')';
if LocalDbg then Writeln(dmData.Q.SQL.Text);
//if dmData.trQ.Active then dmData.trQ.Rollback;
@ -872,7 +882,7 @@ begin
end;
if not qso_in_log then
begin
WriteErrorRecord('L',call,band,mode,qsodate,time_on,qslr,qslrdate,cqz,ituz,iota,grid,state,county,qsorecord,l);
WriteErrorRecord('L',call,band,modeorig,submodeorig,qsodate,time_on,qslr,qslrdate,cqz,ituz,iota,grid,state,county,qsorecord,l);
inc(ErrorCount)
end
end
@ -1019,45 +1029,47 @@ end;
procedure TfrmImportProgress.ImporteQSLAdif;
var
num : Word = 1;
size : Word;
sSize : String;
a : String;
orig : String;
f : TextFile;
PosEOH : Word;
num : Word = 1;
size,
PosEOH,
PosEOR : Word;
qsorecord: String;
call : String;
band : String;
mode : String;
submode : String;
qsodate : String;
time_on : String;
qslr : String;
qslrdate : String;
cqz : String;
ituz : String;
iota : String;
grid : String;
state : String;
county : String;
Buf : String;
sSize,
a,
orig,
qsorecord,
call,
band,
mode,
modeorig,
submode,
submodeorig,
qsodate,
time_on,
qslr,
qslrdate,
cqz,
ituz,
iota,
grid,
state,
county,
Buf : String;
PosCall : Word;
PosBand : Word;
PosMode : Word;
PosSubmode : Word;
PosQsoDate : Word;
PosTime_on : Word;
PosCall,
PosBand,
PosMode,
PosSubmode,
PosQsoDate,
PosTime_on,
PosQslr : Word;
qso_in_log : Boolean = False;
ErrorCount : Word = 0;
l : TStringList;
t_eQSL : TDateTime;
t_eQSL_min : TDateTime;
t_eQSL_max : TDateTime;
t_eQSL,
t_eQSL_min,
t_eQSL_max,
t_log : TDateTime;
begin
@ -1099,7 +1111,10 @@ begin
begin
call := '';
band := '';
modeorig := '';
mode := '';
submodeorig
:= '';
submode := '';
qsodate := '';
time_on := '';
@ -1119,9 +1134,9 @@ begin
while not ((PosEOR > 0) or eof(f)) do
begin
qso_in_log := False;
CommonImport(PosEOR,f,call,band,mode,submode,qsodate,time_on,qslr,
CommonImport(PosEOR,f,call,band,modeorig,mode,submodeorig,submode,qsodate,time_on,qslr,
qslrdate,cqz,ituz,iota,grid,state,county,qsorecord);
//for now on the mode is converted Cqrmode
if PosEOR > 0 then
begin
if LocalDbg then
@ -1129,8 +1144,9 @@ begin
Writeln('------------------------------------------------');
Writeln('Call: ',call);
Writeln('Band: ',band);
Writeln('Mode: ',mode);
Writeln('Submode: ',submode);
Writeln('Mode: ',modeorig);
Writeln('Submode: ',submodeorig);
Writeln('CqrMode: ',mode);
Writeln('QSO_date: ',qsodate);
Writeln('Time_on: ',time_on);
Writeln('QSLR: ',qslr);
@ -1140,22 +1156,20 @@ begin
dmData.Q.Close;
if (mode='JT65') then //since implementing submodes below, this can most probably be removed
begin
dmData.Q.SQL.Text := 'select id_cqrlog_main,eqsl_qsl_rcvd,time_on from cqrlog_main ' +
//we compare Cqrmode in log to mode and submode received and Cqrmode created.
//If any of these is ok, qso is ok by mode.
//this makes backward compatible to old cqrlog loggings.
//Actually qso is ok even without mode check if other items fit!
dmData.Q.SQL.Text := 'select id_cqrlog_main,eqsl_qsl_rcvd,time_on from cqrlog_main ' +
'where (qsodate ='+QuotedStr(qsodate)+') '+
'and ((mode = ' + QuotedStr('JT65') + ') or (mode='+QuotedStr('JT65A')+') '+
'or (mode='+QuotedStr('JT65B')+') or (mode='+QuotedStr('JT65C')+')) '+
'and ('+
'(mode = ' + QuotedStr(mode) +') or '+
'(mode = ' + QuotedStr(modeorig)+') or '+
'(mode = ' + QuotedStr(submodeorig)+') '+
')' +
'and (band = ' + QuotedStr(band) + ') '+
'and (callsign = ' + QuotedStr(call) + ')'
end
else begin
dmData.Q.SQL.Text := 'select id_cqrlog_main,eqsl_qsl_rcvd,time_on from cqrlog_main ' +
'where (qsodate ='+QuotedStr(qsodate)+') '+
'and ((mode = ' + QuotedStr(mode) + ') or (mode = ' + QuotedStr(submode) + ')) '+
'and (band = ' + QuotedStr(band) + ') '+
'and (callsign = ' + QuotedStr(call) + ')'
end;
'and (callsign = ' + QuotedStr(call) + ')';
if LocalDbg then Writeln(dmData.Q.SQL.Text);
//if dmData.trQ.Active then dmData.trQ.Rollback;
//dmData.trQ.StartTransaction;
@ -1206,7 +1220,7 @@ begin
end;
if not qso_in_log then
begin
WriteErrorRecord('E',call,band,mode,qsodate,time_on,qslr,qslrdate,cqz,ituz,iota,grid,state,county,qsorecord,l);
WriteErrorRecord('E',call,band,modeorig,submodeorig,qsodate,time_on,qslr,qslrdate,cqz,ituz,iota,grid,state,county,qsorecord,l);
inc(ErrorCount)
end
end

View File

@ -365,10 +365,12 @@ end;
function TfrmLoTWExport.ExportToAdif : Word;
var
f : TextFile;
tmp : String = '';
nr : Integer = 1;
date : String;
f : TextFile;
tmp : String = '';
nr : Integer = 1;
date,
ModeOut,
SubmodeOut: String;
begin
if FileExists(FileName) then
DeleteFile(FileName);
@ -385,6 +387,7 @@ begin
end;
date := FormatDateTime('yyyy-mm-dd',now);
Writeln(f);
Writeln(f, '<ADIF_VER:5>3.1.0');
Writeln(f, '<CREATED_TIMESTAMP:15>',FormatDateTime('YYYYMMDD hhmmss',dmUtils.GetDateTime(0)));
Writeln(f, 'ADIF export from CQRLOG for Linux version '+dmData.VersionString);
@ -447,35 +450,15 @@ begin
tmp := dmUtils.StringToADIF('<CALL',dmUtils.RemoveSpaces(dmData.Q1.FieldByName('callsign').AsString));
Writeln(f,tmp);
case dmData.Q1.FieldByName('mode').AsString of
'JS8' : begin
tmp := '<MODE:4>MFSK';
Writeln(f,tmp);
tmp := '<SUBMODE:3>JS8';
Writeln(f,tmp);
end;
'FT4' : begin
tmp := '<MODE:4>MFSK';
Writeln(f,tmp);
tmp := '<SUBMODE:3>FT4';
Writeln(f,tmp);
end;
'FST4' : begin
tmp := '<MODE:4>MFSK';
Writeln(f,tmp);
tmp := '<SUBMODE:4>FST4';
Writeln(f,tmp);
end;
'PACKET' : begin
tmp := '<MODE:3>PKT';
Writeln(f,tmp);
end;
else
begin
tmp := dmUtils.StringToADIF('<MODE',dmData.Q1.FieldByName('mode').AsString);
Writeln(f,tmp);
end;
end;
dmUtils.ModeFromCqr(dmData.Q1.FieldByName('mode').AsString,ModeOut,SubmodeOut,dmData.DebugLevel >= 1);
tmp := dmUtils.StringToADIF('<MODE',ModeOut);
Writeln(f,tmp);
if SubmodeOut<>'' then
Begin
tmp := dmUtils.StringToADIF('<SUBMODE',SubmodeOut);
Writeln(f,tmp);
end;
tmp :=dmUtils.StringToADIF( '<BAND' , dmData.Q1.FieldByName('band').AsString);
Writeln(f,tmp);

View File

@ -723,7 +723,8 @@ var
if dmData.trQ.Active then
dmData.trQ.RollBack;
dmData.Q.SQL.Text := 'DELETE FROM cqrlog_main WHERE id_cqrlog_main = ' + IntToStr(idx);
WriteLn(dmData.Q.SQL.Text);
if dmData.DebugLevel >= 1 then
WriteLn(dmData.Q.SQL.Text);
dmData.trQ.StartTransaction;
dmData.Q.ExecSQL;
dmData.trQ.Commit

View File

@ -1928,6 +1928,7 @@ var
Mo :TStringList;
mhz,
mode,
submode,
Mask,
data : String;
begin
@ -2026,12 +2027,12 @@ begin
//first set mode by mode, then if submode exist replace mode with it.
//Here no problem with SSB/USB/LSB combination
cmbMode.Text := logged.ValueFromIndex[logged.IndexOfName('mode')];
mode := logged.ValueFromIndex[logged.IndexOfName('mode')];
if logged.IndexOfName('submode')> -1 then
Begin
mode := logged.ValueFromIndex[logged.IndexOfName('submode')];
if mode<>'' then cmbMode.Text := mode;
end;
submode := logged.ValueFromIndex[logged.IndexOfName('submode')]
else
submode:='';
cmbMode.Text:=dmUtils.ModeToCqr(mode,submode,dmData.DebugLevel>=1);
//set frquency
mhz := logged.ValueFromIndex[logged.IndexOfName('mhz')];
@ -2045,10 +2046,7 @@ begin
edtMyRST.Text := logged.ValueFromIndex[logged.IndexOfName('rx')];
//then override with possible defaults for frequency, mode and RST from Cqrlog settings
//Buggy Lazarus GUI creates under this one extra "end;" because of "try/finally/end" above.
//Remove it!
case cqrini.ReadInteger('fldigi','freq',0) of
case cqrini.ReadInteger('fldigi','freq',0) of
0 : if frmTRXControl.GetModeFreqNewQSO(mode,mhz) then cmbFreq.Text := mhz;
2 : cmbFreq.Text := cqrini.ReadString('fldigi','deffreq','3.600')
end;
@ -2075,15 +2073,14 @@ end;
procedure TfrmNewQSO.tmrADIFTimer(Sender: TObject);
var
Buf, buf2,
prik,data :string;
chkDuplicates,
submodeExist :boolean;
prik,data :string;
chkDuplicates :boolean;
i :longint;
a,b,l :integer;
fixed :Boolean;
mode,submode :string;
begin
fixed:=false;
tmrADIF.Enabled:=false;
chkDuplicates:=false;
@ -2151,10 +2148,11 @@ begin
if pos('<CALL:',uppercase (Buf)) > 0 then
Begin
if dmData.DebugLevel>=1 then writeln('Handle qso record: ',Buf);
mode:='';
submode:='';
//this is fake as call info(qslmgr) needs date. We use current date if call tag comes before qso_date tag
//qso_date will then replace this
edtDate.Text := FormatDateTime('YYYY-MM-DD',now());
submodeExist:=false;
repeat
begin
if frmAdifImport.getNextAdifTag(Buf,prik,data) then
@ -2176,14 +2174,8 @@ begin
if pos(data,edtGrid.Text)=0 then //if qso loc does not fit to QRZ loc , or qrz loc is empty
edtGrid.Text := data; //replace qrz loc, otherwise keep it
end;
'MODE' : if not submodeExist
then cmbMode.Text := uppercase(data);
//now this overrides MODE, if exists
'SUBMODE' : Begin
//we need lock in case submode found before mode tag
submodeExist:=true;
cmbMode.Text := uppercase(data);
end;
'MODE' : mode := uppercase(data);
'SUBMODE' : submode := uppercase(data);
'FREQ' : cmbFreq.Text := data;
'FREQ_RX' : edtRXFreq.Text := data;
'RST_SENT' : edtHisRST.Text := data;
@ -2221,9 +2213,10 @@ begin
end; //case
end; //repeat
until pos('<EOR>',uppercase(Buf))=1;
//execption is SSB. Cqrlog does not use USB and LSB (submodes)
if (cmbMode.Text ='USB') or (cmbMode.Text='LSB') then
cmbMode.Text:='SSB';
//set the final Cqrlmode
cmbMode.Text:=dmUtils.ModeToCqr(mode,submode,dmData.DebugLevel>=1 );
SaveRemote;
//these do not reset in qso save, so they must be cleared here in case there was
@ -7551,8 +7544,8 @@ begin
cbOffline.Enabled := True;
btnSave.Enabled := True;
edtCall.SetFocus;
//clear TMPQSO mode on close. Otherwise it shows up on next remote mode (procedure ClearAll makes it)
cqrini.WriteString('TMPQSO','Mode','');
end;
procedure TfrmNewQSO.SaveRemote;
Begin

View File

@ -199,7 +199,10 @@ begin
dmUtils.DateInSOTAFormat(dmData.Q.FieldByName('qsodate').AsDateTime)+',',
StringReplace(dmData.Q.FieldByName('time_on').AsString,':','',[rfReplaceAll, rfIgnoreCase])+',',
FormatFloat('0.00;;',dmData.Q.FieldByName('freq').AsFloat),'MHz,',
//2022-05-05 OH1KH It seems that SOTA mode can be CqrMode (mainly CW,SSB,FM,AM)(I.E. no mode+submode pairs needed)
//otherwise use dmUtils.ModeFromCqr to get mode and submode at this point
dmData.Q.FieldByName('mode').AsString,',',
dmData.Q.FieldByName('callsign').AsString,',', //his callsign
HisSota+',', //his summit
note //comments

View File

@ -237,6 +237,7 @@ var
Drop :integer;
tmp :extended;
begin
frmNewQSO.tmrFldigi.Enabled := false;
SockOK := true;
@ -281,10 +282,12 @@ begin
mode:='';submode:='';
if SockOK then SockOK := PollFldigi('modem.get_mode',mode);
if SockOK then SockOK := PollFldigi('modem.get_submode',submode);
if mode='' then //old version of fldigi, make different query
if mode='' then //old version of fldigi get_mode not supported, make different query
Begin
if SockOK then SockOK := PollFldigi('modem.get_name',mode);
//cqrlog saves submode as mode
if submode<>'' then mode := submode;
end
else
mode:=dmUtils.ModeToCqr(mode,submode,dmData.DebugLevel>=1 );
end;
2 : begin
mode := cqrini.ReadString('fldigi','defmode','RTTY');

View File

@ -69,9 +69,12 @@ end;
function TfrmeQSLUpload.ExportData(const FileName : String) : Boolean;
var
nr : integer = 0;
tmp : String = '';
f : TextFile;
nr : integer = 0;
tmp : String = '';
ModeOut,
SubmodeOut : String;
f : TextFile;
begin
QSOCount := 0;
Result := True;
@ -104,6 +107,7 @@ begin
AssignFile(f,FileName);
try try
Rewrite(f);
Writeln(f);
Writeln(f, 'ADIF export from CQRLOG for Linux version '+dmData.VersionString);
Writeln(f, 'Copyright (C) ',YearOf(now),' by Petr, OK2CQR and Martin, OK1RR');
Writeln(f);
@ -132,34 +136,14 @@ begin
tmp := dmUtils.StringToADIF('<CALL' ,dmUtils.RemoveSpaces(dmData.Q.FieldByName('callsign').AsString));
Writeln(f,tmp);
case dmData.Q.FieldByName('mode').AsString of
'JS8' : begin
tmp := '<MODE:4>MFSK';
Writeln(f,tmp);
tmp := '<SUBMODE:3>JS8';
Writeln(f,tmp);
end;
'FT4' : begin
tmp := '<MODE:4>MFSK';
Writeln(f,tmp);
tmp := '<SUBMODE:3>FT4';
Writeln(f,tmp);
end;
'FST4' : begin
tmp := '<MODE:4>MFSK';
Writeln(f,tmp);
tmp := '<SUBMODE:4>FST4';
Writeln(f,tmp);
end;
'PACKET': begin
tmp := '<MODE:3>PKT';
Writeln(f,tmp);
end;
else begin
tmp := dmUtils.StringToADIF('<MODE',dmData.Q.FieldByName('mode').AsString);
Writeln(f,tmp);
end;
end;
dmUtils.ModeFromCqr(dmData.Q.FieldByName('mode').AsString,ModeOut,SubmodeOut,dmData.DebugLevel >= 1);
tmp := dmUtils.StringToADIF('<MODE',ModeOut);
Writeln(f,tmp);
if SubmodeOut<>'' then
Begin
tmp := dmUtils.StringToADIF('<SUBMODE',SubmodeOut);
Writeln(f,tmp);
end;
tmp := dmUtils.StringToADIF('<BAND' ,dmData.Q.FieldByName('band').AsString);
Writeln(f,tmp);

View File

@ -76,6 +76,7 @@ const l_LOTW_QSLSDATE = 10; // lotw_qslsdate date
const l_LOTW_QSL_RCVD = 2; // lotw_qslr varchar(3)
const l_LOTW_QSL_SENT = 2; // lotw_qsls varchar(3)
const l_MODE = 12; // mode varchar(12)
const l_SUBMODE = 12; // submode this is never stored, no database column. Just for cqrmode conversion
const l_MY_GRIDSQUARE = 6; // my_loc varchar(10)
const l_NAME = 40;//50; // name varchar(40)
const l_NOTES = 250; // notes.longremarks varchar(256)

View File

@ -18,7 +18,7 @@ const
cRELEAS = 2;
cBUILD = 1;
cBUILD_DATE = '2022-05-12';
cBUILD_DATE = '2022-05-05';
implementation