Skip to content

Commit

Permalink
341 improve exchange error reporting (#342)
Browse files Browse the repository at this point in the history
Improve exchange error reporting #341
- Add TContest.CheckEnteredCallLength virtual function
- Add TContest.ValidateEnteredExchange virtual function
- return ExchError via ValidateEnteredExchange
- report Exchange error after hitting Enter
- callsigns must contain 3 or more characters.

See example output in Issue #341.
  • Loading branch information
w7sst authored Aug 25, 2024
2 parents 7f48975 + 377d4d3 commit 659722d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 18 deletions.
40 changes: 35 additions & 5 deletions Contest.pas
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ TContest = class
procedure SendMsg(const AStn: TStation; const AMsg: TStationMessage); virtual;
procedure SendText(const AStn: TStation; const AMsg: string); virtual;

function ValidateEnteredExchange(const ACall, AExch1, AExch2: string) : boolean; virtual;
function CheckEnteredCallLength(const ACall: string;
out AExchError: String) : boolean; virtual;
function ValidateEnteredExchange(const ACall, AExch1, AExch2: string;
out AExchError: 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;
Expand Down Expand Up @@ -446,12 +449,31 @@ procedure TContest.FindQsoErrors(var Qso: TQso; var ACorrections: TStringList);
end;


{
Performs simple length check on a callsign.
Returns true for callsigns with 3 or more characters; false otherwise.
Upon error, AExchError will contain a simple error message.
}
function TContest.CheckEnteredCallLength(const ACall: string;
out AExchError: String) : boolean;
begin
Result := ACall.Length >= 3;
if not Result then
AExchError := 'Invalid callsign';
end;


{
ValidateEnteredExchange is called prior to sending the final 'TU' and calling
SaveQSO (see Log.pas). This virtual function can be overriden for complex
exchange information (e.g. ARRL Sweepstakes).
SaveQSO (see Log.pas). The basic validation is a length test where each
exchange is checked against a minimum length requirement.
This is contest with original 1.68 behaviors.
This virtual function can be overriden for complex exchange information
(e.g. ARRL Sweepstakes).
}
function TContest.ValidateEnteredExchange(const ACall, AExch1, AExch2: string) : boolean;
function TContest.ValidateEnteredExchange(const ACall, AExch1, AExch2: string;
out AExchError: String) : boolean;
// Adding a contest: validate contest-specific exchange fields
//validate Exchange 1 (Edit2) field lengths
function ValidateExchField1(const text: string): Boolean;
Expand Down Expand Up @@ -489,7 +511,15 @@ function TContest.ValidateEnteredExchange(const ACall, AExch1, AExch2: string) :
end;

begin
Result := ValidateExchField1(AExch1) and ValidateExchField2(AExch2);
if not ValidateExchField1(AExch1) then
AExchError := format('Missing/Invalid %s',
[Exchange1Settings[Mainform.RecvExchTypes.Exch1].C])
else if not ValidateExchField2(AExch2) then
AExchError := format('Missing/Invalid %s',
[Exchange2Settings[Mainform.RecvExchTypes.Exch2].C])
else
AExchError := '';
Result := AExchError.IsEmpty;
end;


Expand Down
29 changes: 20 additions & 9 deletions Log.pas
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ procedure UpdateSbar(const ACallsign: string);
end;

// during debug, use status bar to show CW stream
Mainform.sbar.Font.Color := clDefault;
if not s.IsEmpty and (BDebugCwDecoder or BDebugGhosting) then
Mainform.sbar.Caption:= LeftStr(Mainform.sbar.Caption, 40) + ' -- ' + s
else
Expand Down Expand Up @@ -721,27 +722,37 @@ function ExtractPrefix(Call: string; DeleteTrailingLetters: boolean): string;
end;


{
Save QSO data into the Log.
Called by either:
- 'Enter' key (after sending 'TU' to caller).
- 'Shift-Enter', 'Cntl-Enter' or 'Alt-Enter' (without sending 'TU' to caller).
}
procedure SaveQso;
var
Call: string;
ExchError: string;
i: integer;
Qso: PQso;
begin
with MainForm do
begin
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'.
//
// ValidateEnteredExchange below is a virtual function to allow specialized
// contests to apply special processing (e.g. ARRL Sweepstakes).
if (Length(Call) < 3) or
not Tst.ValidateEnteredExchange(Call, Edit2.Text, Edit3.Text) then
// Virtual functions used below allow special processing as needed
// for some contests (e.g. ARRL Sweepstakes).
if not Tst.CheckEnteredCallLength(Call, ExchError) or
not Tst.ValidateEnteredExchange(Call, Edit2.Text, Edit3.Text, ExchError) then
begin
{Beep;}
if not ExchError.IsEmpty then
begin
sbar.Caption := ExchError;
sbar.Align:= alBottom;
sbar.Visible:= true;
sbar.Font.Color := clRed;
end;
Exit;
end;

Expand Down
21 changes: 17 additions & 4 deletions Main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ procedure TMainForm.ProcessSpace;
procedure TMainForm.ProcessEnter;
var
C, N, R, Q: boolean;
ExchError: string;
begin
if ActiveControl = ExchangeEdit then
begin
Expand All @@ -872,6 +873,9 @@ procedure TMainForm.ProcessEnter;
end;
MustAdvance := false;

sbar.Font.Color := clDefault;

// 'Control-Enter', 'Shift-Enter' and 'Alt-Enter' are shortcuts to SaveQSO
if (GetKeyState(VK_CONTROL) or GetKeyState(VK_SHIFT) or GetKeyState(VK_MENU)) < 0 then
begin
Log.SaveQso;
Expand Down Expand Up @@ -914,6 +918,19 @@ procedure TMainForm.ProcessEnter;

if R and Q and (C or N) then
begin
// validate Exchange before sending TU and logging the QSO
if not Tst.ValidateEnteredExchange(Edit1.Text, Edit2.Text, Edit3.Text, ExchError) then
begin
if not ExchError.IsEmpty then
begin
sbar.Caption := ExchError;
sbar.Align:= alBottom;
sbar.Visible:= true;
sbar.Font.Color := clRed;
end;
Exit;
end;

SendMsg(msgTU);
Log.SaveQso;
end
Expand Down Expand Up @@ -1080,16 +1097,12 @@ function TMainForm.SetMyExchange(const AExchange: string) : Boolean;
sl: TStringList;
ExchError: string;
SentExchTypes : TExchTypes;
Field1Def: PFieldDefinition;
Field2Def: PFieldDefinition;
begin
sl:= TStringList.Create;
try
assert(Tst.Me.SentExchTypes = Tst.GetSentExchTypes(skMyStation, Ini.Call),
'set by TMainForm.SetMyCall');
SentExchTypes := Tst.Me.SentExchTypes;
Field1Def := @Exchange1Settings[SentExchTypes.Exch1];
Field2Def := @Exchange2Settings[SentExchTypes.Exch2];

// parse into two strings [Exch1, Exch2]
// validate sent exchange strings
Expand Down

0 comments on commit 659722d

Please sign in to comment.