Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

324 refactor contest specific logging code #325

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions Contest.pas
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ TContest = class
const AStationCallsign : string) : TExchTypes; virtual;
procedure SendMsg(const AStn: TStation; const AMsg: TStationMessage); virtual;
procedure SendText(const AStn: TStation; const AMsg: string); virtual;

function ValidateEnteredQsoData(const ACall, AExch1, AExch2: string) : boolean; virtual;
procedure SaveEnteredExchToQso(var Qso: TQso; const AExch1, AExch2: string); virtual;
procedure FindQsoErrors(var Qso: TQso; var ACorrections: TStringList);
function ExtractMultiplier(Qso: PQso) : string; virtual;
function Minute: Single;
Expand Down Expand Up @@ -376,6 +379,94 @@ procedure TContest.FindQsoErrors(var Qso: TQso; var ACorrections: TStringList);
end;


{
ValidateEnteredQsoData is called by SaveQSO (see Log.pas).
SaveQSO is called when the QSO is complete and the user has sent 'TU'.
}
function TContest.ValidateEnteredQsoData(const ACall, AExch1, AExch2: string) : boolean;
// Adding a contest: validate contest-specific exchange fields
//validate Exchange 1 (Edit2) field lengths
function ValidateExchField1(const text: string): Boolean;
begin
Result := false;
case Mainform.RecvExchTypes.Exch1 of
etRST: Result := Length(text) = 3;
etOpName: Result := Length(text) > 1;
etFdClass: Result := Length(text) > 1;
else
assert(false, 'missing case');
end;
end;

//validate Exchange 2 (Edit3) field lengths
function ValidateExchField2(const text: string): Boolean;
begin
Result := false;
case Mainform.RecvExchTypes.Exch2 of
etSerialNr: Result := Length(text) > 0;
etGenericField:Result := Length(text) > 0;
etArrlSection: Result := Length(text) > 1;
etStateProv: Result := Length(text) > 1;
etCqZone: Result := Length(text) > 0;
etItuZone: Result := Length(text) > 0;
//etAge:
etPower: Result := Length(text) > 0;
etJaPref: Result := Length(text) > 2;
etJaCity: Result := Length(text) > 3;
etNaQpExch2: Result := Length(text) > 0;
etNaQpNonNaExch2: Result := Length(text) >= 0;
else
assert(false, 'missing case');
end;
end;

begin
Result := ValidateExchField1(AExch1) and ValidateExchField2(AExch2);
end;


{
SaveEnteredExchToQso will save contest-specific exchange values into a QSO.
This is called to enter the completed QSO into the log.
This virtual function can be overriden by specialized contests as needed
(see ARRL Sweepstakes).
}
procedure TContest.SaveEnteredExchToQso(var Qso: TQso; const AExch1, AExch2: string);
begin
// Adding a contest: save contest-specific exchange values into QsoList
//save Exchange 1 (Edit2)
case Mainform.RecvExchTypes.Exch1 of
etRST: Qso.Rst := StrToInt(AExch1);
etOpName: Qso.Exch1 := AExch1;
etFdClass: Qso.Exch1 := AExch1;
else
assert(false, 'missing case');
end;

//save Exchange2 (Edit3)
case Mainform.RecvExchTypes.Exch2 of
etSerialNr: Qso.Nr := StrToInt(AExch2);
etGenericField:Qso.Exch2 := AExch2;
etArrlSection: Qso.Exch2 := AExch2;
etStateProv: Qso.Exch2 := AExch2;
etCqZone: Qso.NR := StrToInt(AExch2);
etItuZone: Qso.Exch2 := AExch2;
//etAge:
etPower: Qso.Exch2 := AExch2;
etJaPref: Qso.Exch2 := AExch2;
etJaCity: Qso.Exch2 := AExch2;
etNaQpExch2: Qso.Exch2 := AExch2;
etNaQpNonNaExch2:
if AExch2 = '' then
Qso.Exch2 := 'DX'
else
Qso.Exch2 := AExch2;
else
assert(false, 'missing case');
end;
end;


{
Extract multiplier string for a given contest. Default behavior will
return the QSO.Pfx string (which implies this method must be called
Expand Down
87 changes: 15 additions & 72 deletions Log.pas
Original file line number Diff line number Diff line change
Expand Up @@ -650,51 +650,23 @@ function ExtractPrefix(Call: string; DeleteTrailingLetters: boolean): string;

procedure SaveQso;
var
Call: string;
i: integer;
Qso: PQso;

// Adding a contest: validate contest-specific exchange fields
//validate Exchange 1 (Edit2) field lengths
function ValidateExchField1(const text: string): Boolean;
begin
Result := false;
case Mainform.RecvExchTypes.Exch1 of
etRST: Result := Length(text) = 3;
etOpName: Result := Length(text) > 1;
etFdClass: Result := Length(text) > 1;
else
assert(false, 'missing case');
end;
end;

//validate Exchange 2 (Edit3) field lengths
function ValidateExchField2(const text: string): Boolean;
begin
Result := false;
case Mainform.RecvExchTypes.Exch2 of
etSerialNr: Result := Length(text) > 0;
etGenericField:Result := Length(text) > 0;
etArrlSection: Result := Length(text) > 1;
etStateProv: Result := Length(text) > 1;
etCqZone: Result := Length(text) > 0;
etItuZone: Result := Length(text) > 0;
//etAge:
etPower: Result := Length(text) > 0;
etJaPref: Result := Length(text) > 2;
etJaCity: Result := Length(text) > 3;
etNaQpExch2: Result := Length(text) > 0;
etNaQpNonNaExch2: Result := Length(text) >= 0;
else
assert(false, 'missing case');
end;
end;

begin
with MainForm do
begin
if (Length(Edit1.Text) < 3) or
not ValidateExchField1(Edit2.Text) or
not ValidateExchField2(Edit3.Text) then
Call := StringReplace(Edit1.Text, '?', '', [rfReplaceAll]);

// This is too late for this check. The user has already sent 'TU'.
// If the entered information is incomplete, this is an error. This code
// results in an entry not being entered in the log and the DxStation
// is already gone after receiving the user's 'TU'.
//
// ValidateEnteredQsoData below is a virtual function to allow specialized
// contests to apply special processing (e.g. ARRL Sweepstakes).
if (Length(Call) < 3) or
not Tst.ValidateEnteredQsoData(Call, Edit2.Text, Edit3.Text) then
begin
{Beep;}
Exit;
Expand All @@ -706,39 +678,10 @@ procedure SaveQso;

//save data
Qso.T := BlocksToSeconds(Tst.BlockNumber) / 86400;
Qso.Call := StringReplace(Edit1.Text, '?', '', [rfReplaceAll]);

// Adding a contest: save contest-specific exchange values into QsoList
//save Exchange 1 (Edit2)
case Mainform.RecvExchTypes.Exch1 of
etRST: Qso.Rst := StrToInt(Edit2.Text);
etOpName: Qso.Exch1 := Edit2.Text;
etFdClass: Qso.Exch1 := Edit2.Text;
else
assert(false, 'missing case');
end;
Qso.Call := Call;

//save Exchange2 (Edit3)
case Mainform.RecvExchTypes.Exch2 of
etSerialNr: Qso.Nr := StrToInt(Edit3.Text);
etGenericField:Qso.Exch2 := Edit3.Text;
etArrlSection: Qso.Exch2 := Edit3.Text;
etStateProv: Qso.Exch2 := Edit3.Text;
etCqZone: Qso.NR := StrToInt(Edit3.Text);
etItuZone: Qso.Exch2 := Edit3.Text;
//etAge:
etPower: Qso.Exch2 := Edit3.Text;
etJaPref: Qso.Exch2 := Edit3.Text;
etJaCity: Qso.Exch2 := Edit3.Text;
etNaQpExch2: Qso.Exch2 := Edit3.Text;
etNaQpNonNaExch2:
if Edit3.Text = '' then
Qso.Exch2 := 'DX'
else
Qso.Exch2 := Edit3.Text;
else
assert(false, 'missing case');
end;
//save contest-specific exchange values into QSO
Tst.SaveEnteredExchToQso(Qso^, Edit2.Text, Edit3.Text);

Qso.Points := 1; // defaults to 1; override in ExtractMultiplier()
Qso.RawCallsign:= ExtractCallsign(Qso.Call);
Expand Down