2556 lines
74 KiB
Plaintext
2556 lines
74 KiB
Plaintext
unit uTemplateFields;
|
|
|
|
interface
|
|
|
|
uses
|
|
Forms, SysUtils, Classes, Dialogs, StdCtrls, ExtCtrls, Controls, Contnrs,
|
|
Graphics, ORClasses, ComCtrls, ORDtTm, uDlgComponents, TypInfo, ORFn, StrUtils;
|
|
|
|
type
|
|
TTemplateFieldType = (dftUnknown, dftEditBox, dftComboBox, dftButton, dftCheckBoxes,
|
|
dftRadioButtons, dftDate, dftNumber, dftHyperlink, dftWP, dftText,
|
|
// keep dftScreenReader as last entry - users can not create this type of field
|
|
dftScreenReader);
|
|
|
|
TTmplFldDateType = (dtUnknown, dtDate, dtDateTime, dtDateReqTime,
|
|
dtCombo, dtYear, dtYearMonth);
|
|
|
|
const
|
|
FldItemTypes = [dftComboBox, dftButton, dftCheckBoxes, dftRadioButtons, dftWP, dftText];
|
|
SepLinesTypes = [dftCheckBoxes, dftRadioButtons];
|
|
EditLenTypes = [dftEditBox, dftComboBox, dftWP];
|
|
EditDfltTypes = [dftEditBox, dftHyperlink];
|
|
EditDfltType2 = [dftEditBox, dftHyperlink, dftDate];
|
|
ItemDfltTypes = [dftComboBox, dftButton, dftCheckBoxes, dftRadioButtons];
|
|
NoRequired = [dftHyperlink, dftText];
|
|
ExcludeText = [dftHyperlink, dftText];
|
|
DateComboTypes = [dtCombo, dtYear, dtYearMonth];
|
|
|
|
type
|
|
TTemplateDialogEntry = class(TObject)
|
|
private
|
|
FID: string;
|
|
FFont: TFont;
|
|
FPanel: TDlgFieldPanel;
|
|
FControls: TStringList;
|
|
FIndents: TStringList;
|
|
FFirstBuild: boolean;
|
|
FOnChange: TNotifyEvent;
|
|
FText: string;
|
|
FInternalID: string;
|
|
FObj: TObject;
|
|
FFieldValues: string;
|
|
FUpdating: boolean;
|
|
FAutoDestroyOnPanelFree: boolean;
|
|
FPanelDying: boolean;
|
|
FOnDestroy: TNotifyEvent;
|
|
procedure KillLabels;
|
|
function GetFieldValues: string;
|
|
procedure SetFieldValues(const Value: string);
|
|
procedure SetAutoDestroyOnPanelFree(const Value: boolean);
|
|
function StripCode(var txt: string; code: char): boolean;
|
|
protected
|
|
procedure UpDownChange(Sender: TObject);
|
|
procedure DoChange(Sender: TObject);
|
|
function GetControlText(CtrlID: integer; NoCommas: boolean;
|
|
var FoundEntry: boolean; AutoWrap: boolean;
|
|
emField: string = ''): string;
|
|
procedure SetControlText(CtrlID: integer; AText: string);
|
|
public
|
|
constructor Create(AParent: TWinControl; AID, Text: string);
|
|
destructor Destroy; override;
|
|
function GetPanel(MaxLen: integer; AParent: TWinControl;
|
|
OwningCheckBox: TCPRSDialogParentCheckBox): TDlgFieldPanel;
|
|
function GetText: string;
|
|
property Text: string read FText write FText;
|
|
property InternalID: string read FInternalID write FInternalID;
|
|
property ID: string read FID;
|
|
property Obj: TObject read FObj write FObj;
|
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
property OnDestroy: TNotifyEvent read FOnDestroy write FOnDestroy;
|
|
property FieldValues: string read GetFieldValues write SetFieldValues;
|
|
property AutoDestroyOnPanelFree: boolean read FAutoDestroyOnPanelFree
|
|
write SetAutoDestroyOnPanelFree;
|
|
end;
|
|
|
|
TTemplateField = class(TObject)
|
|
private
|
|
FMaxLen: integer;
|
|
FFldName: string;
|
|
FNameChanged: boolean;
|
|
FLMText: string;
|
|
FEditDefault: string;
|
|
FNotes: string;
|
|
FItems: string;
|
|
FInactive: boolean;
|
|
FItemDefault: string;
|
|
FFldType: TTemplateFieldType;
|
|
FRequired: boolean;
|
|
FSepLines: boolean;
|
|
FTextLen: integer;
|
|
FIndent: integer;
|
|
FPad: integer;
|
|
FMinVal: integer;
|
|
FMaxVal: integer;
|
|
FIncrement: integer;
|
|
FURL: string;
|
|
FDateType: TTmplFldDateType;
|
|
FModified: boolean;
|
|
FID: string;
|
|
FLocked: boolean;
|
|
procedure SetEditDefault(const Value: string);
|
|
procedure SetFldName(const Value: string);
|
|
procedure SetFldType(const Value: TTemplateFieldType);
|
|
procedure SetInactive(const Value: boolean);
|
|
procedure SetRequired(const Value: boolean);
|
|
procedure SetSepLines(const Value: boolean);
|
|
procedure SetItemDefault(const Value: string);
|
|
procedure SetItems(const Value: string);
|
|
procedure SetLMText(const Value: string);
|
|
procedure SetMaxLen(const Value: integer);
|
|
procedure SetNotes(const Value: string);
|
|
procedure SetID(const Value: string);
|
|
procedure SetIncrement(const Value: integer);
|
|
procedure SetIndent(const Value: integer);
|
|
procedure SetMaxVal(const Value: integer);
|
|
procedure SetMinVal(const Value: integer);
|
|
procedure SetPad(const Value: integer);
|
|
procedure SetTextLen(const Value: integer);
|
|
procedure SetURL(const Value: string);
|
|
function GetTemplateFieldDefault: string;
|
|
procedure CreateDialogControls(Entry: TTemplateDialogEntry;
|
|
var Index: Integer; CtrlID: integer);
|
|
function SaveError: string;
|
|
function Width: integer;
|
|
function GetRequired: boolean;
|
|
procedure SetDateType(const Value: TTmplFldDateType);
|
|
public
|
|
constructor Create(AData: TStrings);
|
|
destructor Destroy; override;
|
|
procedure Assign(AFld: TTemplateField);
|
|
function NewField: boolean;
|
|
function CanModify: boolean;
|
|
property ID: string read FID write SetID;
|
|
property FldName: string read FFldName write SetFldName;
|
|
property NameChanged: boolean read FNameChanged;
|
|
property FldType: TTemplateFieldType read FFldType write SetFldType;
|
|
property MaxLen: integer read FMaxLen write SetMaxLen;
|
|
property EditDefault: string read FEditDefault write SetEditDefault;
|
|
property Items: string read FItems write SetItems;
|
|
property ItemDefault: string read FItemDefault write SetItemDefault;
|
|
property LMText: string read FLMText write SetLMText;
|
|
property Inactive: boolean read FInactive write SetInactive;
|
|
property Required: boolean read GetRequired write SetRequired;
|
|
property SepLines: boolean read FSepLines write SetSepLines;
|
|
property TextLen: integer read FTextLen write SetTextLen;
|
|
property Indent: integer read FIndent write SetIndent;
|
|
property Pad: integer read FPad write SetPad;
|
|
property MinVal: integer read FMinVal write SetMinVal;
|
|
property MaxVal: integer read FMaxVal write SetMaxVal;
|
|
property Increment: integer read FIncrement write SetIncrement;
|
|
property URL: string read FURL write SetURL;
|
|
property DateType: TTmplFldDateType read FDateType write SetDateType;
|
|
property Notes: string read FNotes write SetNotes;
|
|
property TemplateFieldDefault: string read GetTemplateFieldDefault;
|
|
end;
|
|
|
|
TIntStruc = class(TObject)
|
|
public
|
|
x: integer;
|
|
end;
|
|
|
|
function GetDialogEntry(AParent: TWinControl; AID, AText: string): TTemplateDialogEntry;
|
|
procedure FreeEntries(SL: TStrings);
|
|
procedure AssignFieldIDs(var Txt: string); overload;
|
|
procedure AssignFieldIDs(SL: TStrings); overload;
|
|
function ResolveTemplateFields(Text: string; AutoWrap: boolean; Hidden: boolean = FALSE; IncludeEmbedded: boolean = FALSE): string;
|
|
function AreTemplateFieldsRequired(const Text: string; FldValues: TORStringList = nil): boolean;
|
|
function HasTemplateField(txt: string): boolean;
|
|
|
|
function GetTemplateField(ATemplateField: string; ByIEN: boolean): TTemplateField;
|
|
function TemplateFieldNameProblem(Fld: TTemplateField): boolean;
|
|
function SaveTemplateFieldErrors: string;
|
|
procedure ClearModifiedTemplateFields;
|
|
function AnyTemplateFieldsModified: boolean;
|
|
procedure ListTemplateFields(const AText: string; AList: TStrings; ListErrors: boolean = FALSE);
|
|
function BoilerplateTemplateFieldsOK(const AText: string; Msg: string = ''): boolean;
|
|
procedure EnsureText(edt: TEdit; ud: TUpDown);
|
|
procedure ConvertCodes2Text(sl: TStrings; Short: boolean);
|
|
function StripEmbedded(iItems: string): string;
|
|
procedure StripScreenReaderCodes(var Text: string); overload;
|
|
procedure StripScreenReaderCodes(SL: TStrings); overload;
|
|
function HasScreenReaderBreakCodes(SL: TStrings): boolean;
|
|
|
|
const
|
|
TemplateFieldSignature = '{FLD';
|
|
TemplateFieldBeginSignature = TemplateFieldSignature + ':';
|
|
TemplateFieldEndSignature = '}';
|
|
ScreenReaderCodeSignature = '{SR-';
|
|
ScreenReaderCodeType = ' Screen Reader Code';
|
|
ScreenReaderCodeCount = 2;
|
|
ScreenReaderShownCount = 1;
|
|
ScreenReaderStopCode = ScreenReaderCodeSignature + 'STOP' + TemplateFieldEndSignature;
|
|
ScreenReaderStopCodeLen = Length(ScreenReaderStopCode);
|
|
ScreenReaderStopCodeID = '-43';
|
|
ScreenReaderStopName = 'SCREEN READER STOP CODE **';
|
|
ScreenReaderStopCodeLine = ScreenReaderStopCodeID + U + ScreenReaderStopName + U + ScreenReaderCodeType;
|
|
ScreenReaderContinueCode = ScreenReaderCodeSignature + 'CONT' + TemplateFieldEndSignature;
|
|
ScreenReaderContinueCodeLen = Length(ScreenReaderContinueCode);
|
|
ScreenReaderContinueCodeOld = ScreenReaderCodeSignature + 'CONTINUE' + TemplateFieldEndSignature;
|
|
ScreenReaderContinueCodeOldLen = Length(ScreenReaderContinueCodeOld);
|
|
ScreenReaderContinueCodeID = '-44';
|
|
ScreenReaderContinueCodeName = 'SCREEN READER CONTINUE CODE ***';
|
|
ScreenReaderContinueCodeLine = ScreenReaderContinueCodeID + U + ScreenReaderContinueCodeName + U + ScreenReaderCodeType;
|
|
MissingFieldsTxt = 'One or more required fields must still be entered.';
|
|
|
|
ScreenReaderCodes: array[0..ScreenReaderCodeCount] of string =
|
|
(ScreenReaderStopCode, ScreenReaderContinueCode, ScreenReaderContinueCodeOld);
|
|
ScreenReaderCodeLens: array[0..ScreenReaderCodeCount] of integer =
|
|
(ScreenReaderStopCodeLen, ScreenReaderContinueCodeLen, ScreenReaderContinueCodeOldLen);
|
|
ScreenReaderCodeIDs: array[0..ScreenReaderShownCount] of string =
|
|
(ScreenReaderStopCodeID, ScreenReaderContinueCodeID);
|
|
ScreenReaderCodeLines: array[0..ScreenReaderShownCount] of string =
|
|
(ScreenReaderStopCodeLine, ScreenReaderContinueCodeLine);
|
|
|
|
TemplateFieldTypeCodes: array[TTemplateFieldType] of string[1] =
|
|
{ dftUnknown } ('',
|
|
{ dftEditBox } 'E',
|
|
{ dftComboBox } 'C',
|
|
{ dftButton } 'B',
|
|
{ dftCheckBoxes } 'X',
|
|
{ dftRadioButtons } 'R',
|
|
{ dftDate } 'D',
|
|
{ dftNumber } 'N',
|
|
{ dftHyperlink } 'H',
|
|
{ dftWP } 'W',
|
|
{ dftText } 'T',
|
|
{ dftScreenReader } 'S');
|
|
|
|
TemplateFieldTypeDesc: array[TTemplateFieldType, boolean] of string =
|
|
{ dftUnknown } (('',''),
|
|
{ dftEditBox } ('Edit Box', 'Edit'),
|
|
{ dftComboBox } ('Combo Box', 'Combo'),
|
|
{ dftButton } ('Button', 'Button'),
|
|
{ dftCheckBoxes } ('Check Boxes', 'Check'),
|
|
{ dftRadioButtons } ('Radio Buttons', 'Radio'),
|
|
{ dftDate } ('Date', 'Date'),
|
|
{ dftNumber } ('Number', 'Num'),
|
|
{ dftHyperlink } ('Hyperlink', 'Link'),
|
|
{ dftWP } ('Word Processing', 'WP'),
|
|
{ dftText } ('Display Text', 'Text'),
|
|
{ dftScreenReader } ('Screen Reader Stop', 'SRStop'));
|
|
|
|
TemplateDateTypeDesc: array[TTmplFldDateType, boolean] of string =
|
|
{ dtUnknown } (('',''),
|
|
{ dtDate } ('Date', 'Date'),
|
|
{ dtDateTime } ('Date & Time', 'Time'),
|
|
{ dtDateReqTime } ('Date & Req Time','R.Time'),
|
|
{ dtCombo } ('Date Combo', 'C.Date'),
|
|
{ dtYear } ('Year', 'Year'),
|
|
{ dtYearMonth } ('Year & Month', 'Month'));
|
|
|
|
FldNames: array[TTemplateFieldType] of string =
|
|
{ dftUnknown } ('',
|
|
{ dftEditBox } 'EDIT',
|
|
{ dftComboBox } 'LIST',
|
|
{ dftButton } 'BTTN',
|
|
{ dftCheckBoxes } 'CBOX',
|
|
{ dftRadioButtons } 'RBTN',
|
|
{ dftDate } 'DATE',
|
|
{ dftNumber } 'NUMB',
|
|
{ dftHyperlink } 'LINK',
|
|
{ dftWP } 'WRDP',
|
|
{ dftTExt } 'TEXT',
|
|
{ dftScreenReader } 'SRST');
|
|
|
|
TemplateFieldDateCodes: array[TTmplFldDateType] of string[1] =
|
|
{ dtUnknown } ('',
|
|
{ dtDate } 'D',
|
|
{ dtDateTime } 'T',
|
|
{ dtDateReqTime } 'R',
|
|
{ dtCombo } 'C',
|
|
{ dtYear } 'Y',
|
|
{ dtYearMonth } 'M');
|
|
|
|
MaxTFWPLines = 20;
|
|
MaxTFEdtLen = 70;
|
|
|
|
implementation
|
|
|
|
uses
|
|
rTemplates, ORCtrls, mTemplateFieldButton, dShared, uConst, uCore, rCore, Windows,
|
|
VAUtils, VA508AccessibilityManager, VA508AccessibilityRouter;
|
|
|
|
const
|
|
NewTemplateField = 'NEW TEMPLATE FIELD';
|
|
TemplateFieldSignatureLen = length(TemplateFieldBeginSignature);
|
|
TemplateFieldSignatureEndLen = length(TemplateFieldEndSignature);
|
|
|
|
var
|
|
uTmplFlds: TList = nil;
|
|
uEntries: TStringList = nil;
|
|
|
|
uNewTemplateFieldIDCnt: longint = 0;
|
|
uRadioGroupIndex: integer = 0;
|
|
|
|
uInternalFieldIDCount: integer = 0;
|
|
|
|
const
|
|
FieldIDDelim = '`';
|
|
FieldIDLen = 6;
|
|
NewLine = 'NL';
|
|
|
|
function GetNewFieldID: string;
|
|
begin
|
|
inc(uInternalFieldIDCount);
|
|
Result := IntToStr(uInternalFieldIDCount);
|
|
Result := FieldIDDelim +
|
|
copy(StringOfChar('0', FieldIDLen-2) + Result, length(Result), FieldIDLen-1);
|
|
end;
|
|
|
|
function GetDialogEntry(AParent: TWinControl; AID, AText: string): TTemplateDialogEntry;
|
|
var
|
|
idx: integer;
|
|
|
|
begin
|
|
Result := nil;
|
|
if AID = '' then exit;
|
|
if(not assigned(uEntries)) then
|
|
uEntries := TStringList.Create;
|
|
idx := uEntries.IndexOf(AID);
|
|
if(idx < 0) then
|
|
begin
|
|
Result := TTemplateDialogEntry.Create(AParent, AID, AText);
|
|
uEntries.AddObject(AID, Result);
|
|
end
|
|
else
|
|
Result := TTemplateDialogEntry(uEntries.Objects[idx]);
|
|
end;
|
|
|
|
procedure FreeEntries(SL: TStrings);
|
|
var
|
|
i, idx, cnt: integer;
|
|
|
|
begin
|
|
if(assigned(uEntries)) then
|
|
begin
|
|
for i := SL.Count-1 downto 0 do
|
|
begin
|
|
idx := uEntries.IndexOf(SL[i]);
|
|
if(idx >= 0) then
|
|
begin
|
|
cnt := uEntries.Count;
|
|
if(assigned(uEntries.Objects[idx])) then
|
|
begin
|
|
TTemplateDialogEntry(uEntries.Objects[idx]).AutoDestroyOnPanelFree := FALSE;
|
|
uEntries.Objects[idx].Free;
|
|
end;
|
|
if cnt = uEntries.Count then
|
|
uEntries.Delete(idx);
|
|
end;
|
|
end;
|
|
if(uEntries.Count = 0) then
|
|
uInternalFieldIDCount := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure AssignFieldIDs(var Txt: string);
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
i := 0;
|
|
while (i < length(Txt)) do
|
|
begin
|
|
inc(i);
|
|
if(copy(Txt,i,TemplateFieldSignatureLen) = TemplateFieldBeginSignature) then
|
|
begin
|
|
inc(i,TemplateFieldSignatureLen);
|
|
if(i < length(Txt)) and (copy(Txt,i,1) <> FieldIDDelim) then
|
|
begin
|
|
insert(GetNewFieldID, Txt, i);
|
|
inc(i, FieldIDLen);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure AssignFieldIDs(SL: TStrings);
|
|
var
|
|
i: integer;
|
|
txt: string;
|
|
|
|
begin
|
|
for i := 0 to SL.Count-1 do
|
|
begin
|
|
txt := SL[i];
|
|
AssignFieldIDs(txt);
|
|
SL[i] := txt;
|
|
end;
|
|
end;
|
|
|
|
procedure WordWrapText(var Txt: string);
|
|
var
|
|
TmpSL: TStringList;
|
|
i: integer;
|
|
|
|
function WrappedText(const Str: string): string;
|
|
var
|
|
i, i2, j, k: integer;
|
|
Temp: string;
|
|
|
|
begin
|
|
Temp := Str;
|
|
Result := '';
|
|
i2 := 0;
|
|
|
|
repeat
|
|
i := pos(TemplateFieldBeginSignature, Temp);
|
|
|
|
if i>0 then
|
|
j := pos(TemplateFieldEndSignature, copy(Temp, i, MaxInt))
|
|
else
|
|
j := 0;
|
|
|
|
if (j > 0) then
|
|
begin
|
|
i2 := pos(TemplateFieldBeginSignature, copy(Temp, i+TemplateFieldSignatureLen, MaxInt));
|
|
if (i2 = 0) then
|
|
i2 := MaxInt
|
|
else
|
|
i2 := i + TemplateFieldSignatureLen + i2 - 1;
|
|
end;
|
|
|
|
if (i>0) and (j=0) then
|
|
i := 0;
|
|
|
|
if (i>0) and (j>0) then
|
|
if (j > i2) then
|
|
begin
|
|
Result := Result + copy(Temp, 1, i2-1);
|
|
delete(Temp, 1, i2-1);
|
|
end
|
|
else
|
|
begin
|
|
for k := (i+TemplateFieldSignatureLen) to (i+j-2) do
|
|
if Temp[k]=' ' then
|
|
Temp[k]:= #1;
|
|
i := i + j - 1;
|
|
Result := Result + copy(Temp,1,i);
|
|
delete(Temp,1,i);
|
|
end;
|
|
|
|
until (i = 0);
|
|
|
|
Result := Result + Temp;
|
|
Result := WrapText(Result, #13#10, [' '], MAX_ENTRY_WIDTH);
|
|
repeat
|
|
i := pos(#1, Result);
|
|
if i > 0 then
|
|
Result[i] := ' ';
|
|
until i = 0;
|
|
end;
|
|
|
|
begin
|
|
if length(Txt) > MAX_ENTRY_WIDTH then
|
|
begin
|
|
TmpSL := TStringList.Create;
|
|
try
|
|
TmpSL.Text := Txt;
|
|
Txt := '';
|
|
for i := 0 to TmpSL.Count-1 do
|
|
begin
|
|
if Txt <> '' then
|
|
Txt := Txt + CRLF;
|
|
Txt := Txt + WrappedText(TmpSL[i]);
|
|
end;
|
|
finally
|
|
TmpSL.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function ResolveTemplateFields(Text: string;
|
|
AutoWrap: boolean;
|
|
Hidden: boolean = FALSE;
|
|
IncludeEmbedded: boolean = FALSE): string;
|
|
var
|
|
flen, CtrlID, i, j: integer;
|
|
Entry: TTemplateDialogEntry;
|
|
iField, Temp, NewTxt, Fld: string;
|
|
FoundEntry: boolean;
|
|
TmplFld: TTemplateField;
|
|
|
|
procedure AddNewTxt;
|
|
begin
|
|
if(NewTxt <> '') then
|
|
begin
|
|
insert(StringOfChar('x',length(NewTxt)), Temp, i);
|
|
insert(NewTxt, Result, i);
|
|
inc(i, length(NewTxt));
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if(not assigned(uEntries)) then
|
|
uEntries := TStringList.Create;
|
|
Result := Text;
|
|
Temp := Text; // Use Temp to allow template fields to contain other template field references
|
|
repeat
|
|
i := pos(TemplateFieldBeginSignature, Temp);
|
|
if(i > 0) then
|
|
begin
|
|
CtrlID := 0;
|
|
if(copy(Temp, i + TemplateFieldSignatureLen, 1) = FieldIDDelim) then
|
|
begin
|
|
CtrlID := StrToIntDef(copy(Temp, i + TemplateFieldSignatureLen + 1, FieldIDLen-1), 0);
|
|
delete(Temp,i + TemplateFieldSignatureLen, FieldIDLen);
|
|
delete(Result,i + TemplateFieldSignatureLen, FieldIDLen);
|
|
end;
|
|
j := pos(TemplateFieldEndSignature, copy(Temp, i + TemplateFieldSignatureLen, MaxInt));
|
|
Fld := '';
|
|
if(j > 0) then
|
|
begin
|
|
inc(j, i + TemplateFieldSignatureLen - 1);
|
|
flen := j - i - TemplateFieldSignatureLen;
|
|
Fld := copy(Temp,i + TemplateFieldSignatureLen, flen);
|
|
delete(Temp,i,flen + TemplateFieldSignatureLen + 1);
|
|
delete(Result,i,flen + TemplateFieldSignatureLen + 1);
|
|
end
|
|
else
|
|
begin
|
|
delete(Temp,i,TemplateFieldSignatureLen);
|
|
delete(Result,i,TemplateFieldSignatureLen);
|
|
end;
|
|
if(CtrlID > 0) then
|
|
begin
|
|
FoundEntry := FALSE;
|
|
for j := 0 to uEntries.Count-1 do
|
|
begin
|
|
Entry := TTemplateDialogEntry(uEntries.Objects[j]);
|
|
if(assigned(Entry)) then
|
|
begin
|
|
if IncludeEmbedded then
|
|
iField := Fld
|
|
else
|
|
iField := '';
|
|
NewTxt := Entry.GetControlText(CtrlID, FALSE, FoundEntry, AutoWrap, iField);
|
|
TmplFld := GetTemplateField(Fld, FALSE);
|
|
if (assigned(TmplFld)) and (TmplFld.DateType in DateComboTypes) then {if this is a TORDateBox}
|
|
NewTxt := Piece(NewTxt,':',1); {we only want the first piece of NewTxt}
|
|
AddNewTxt;
|
|
end;
|
|
if FoundEntry then break;
|
|
end;
|
|
if Hidden and (not FoundEntry) and (Fld <> '') then
|
|
begin
|
|
NewTxt := TemplateFieldBeginSignature + Fld + TemplateFieldEndSignature;
|
|
AddNewTxt;
|
|
end;
|
|
end;
|
|
end;
|
|
until(i = 0);
|
|
if not AutoWrap then
|
|
WordWrapText(Result);
|
|
end;
|
|
|
|
function AreTemplateFieldsRequired(const Text: string; FldValues: TORStringList = nil): boolean;
|
|
var
|
|
flen, CtrlID, i, j: integer;
|
|
Entry: TTemplateDialogEntry;
|
|
Fld: TTemplateField;
|
|
Temp, NewTxt, FldName: string;
|
|
FoundEntry: boolean;
|
|
|
|
begin
|
|
if(not assigned(uEntries)) then
|
|
uEntries := TStringList.Create;
|
|
Temp := Text;
|
|
Result := FALSE;
|
|
repeat
|
|
i := pos(TemplateFieldBeginSignature, Temp);
|
|
if(i > 0) then
|
|
begin
|
|
CtrlID := 0;
|
|
if(copy(Temp, i + TemplateFieldSignatureLen, 1) = FieldIDDelim) then
|
|
begin
|
|
CtrlID := StrToIntDef(copy(Temp, i + TemplateFieldSignatureLen + 1, FieldIDLen-1), 0);
|
|
delete(Temp,i + TemplateFieldSignatureLen, FieldIDLen);
|
|
end;
|
|
j := pos(TemplateFieldEndSignature, copy(Temp, i + TemplateFieldSignatureLen, MaxInt));
|
|
if(j > 0) then
|
|
begin
|
|
inc(j, i + TemplateFieldSignatureLen - 1);
|
|
flen := j - i - TemplateFieldSignatureLen;
|
|
FldName := copy(Temp, i + TemplateFieldSignatureLen, flen);
|
|
Fld := GetTemplateField(FldName, FALSE);
|
|
delete(Temp,i,flen + TemplateFieldSignatureLen + 1);
|
|
end
|
|
else
|
|
begin
|
|
delete(Temp,i,TemplateFieldSignatureLen);
|
|
Fld := nil;
|
|
end;
|
|
if(CtrlID > 0) and (assigned(Fld)) and (Fld.Required) then
|
|
begin
|
|
FoundEntry := FALSE;
|
|
for j := 0 to uEntries.Count-1 do
|
|
begin
|
|
Entry := TTemplateDialogEntry(uEntries.Objects[j]);
|
|
if(assigned(Entry)) then
|
|
begin
|
|
NewTxt := Entry.GetControlText(CtrlID, TRUE, FoundEntry, FALSE);
|
|
if FoundEntry and (NewTxt = '') then
|
|
Result := TRUE;
|
|
end;
|
|
if FoundEntry then break;
|
|
end;
|
|
if (not FoundEntry) and assigned(FldValues) then
|
|
begin
|
|
j := FldValues.IndexOfPiece(IntToStr(CtrlID));
|
|
if(j < 0) or (Piece(FldValues[j],U,2) = '') then
|
|
Result := TRUE;
|
|
end;
|
|
end;
|
|
end;
|
|
until((i = 0) or Result);
|
|
end;
|
|
|
|
function HasTemplateField(txt: string): boolean;
|
|
begin
|
|
Result := (pos(TemplateFieldBeginSignature, txt) > 0);
|
|
end;
|
|
|
|
function GetTemplateField(ATemplateField: string; ByIEN: boolean): TTemplateField;
|
|
var
|
|
i, idx: integer;
|
|
AData: TStrings;
|
|
|
|
begin
|
|
Result := nil;
|
|
if(not assigned(uTmplFlds)) then
|
|
uTmplFlds := TList.Create;
|
|
idx := -1;
|
|
for i := 0 to uTmplFlds.Count-1 do
|
|
begin
|
|
if(ByIEN) then
|
|
begin
|
|
if(TTemplateField(uTmplFlds[i]).FID = ATemplateField) then
|
|
begin
|
|
idx := i;
|
|
break;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if(TTemplateField(uTmplFlds[i]).FFldName = ATemplateField) then
|
|
begin
|
|
idx := i;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
if(idx < 0) then
|
|
begin
|
|
if(ByIEN) then
|
|
AData := LoadTemplateFieldByIEN(ATemplateField)
|
|
else
|
|
AData := LoadTemplateField(ATemplateField);
|
|
if(AData.Count > 1) then
|
|
Result := TTemplateField.Create(AData);
|
|
end
|
|
else
|
|
Result := TTemplateField(uTmplFlds[idx]);
|
|
end;
|
|
|
|
function TemplateFieldNameProblem(Fld: TTemplateField): boolean;
|
|
const
|
|
DUPFLD = 'Field Name is not unique';
|
|
|
|
var
|
|
i: integer;
|
|
msg: string;
|
|
|
|
begin
|
|
msg := '';
|
|
if(Fld.FldName = NewTemplateField) then
|
|
msg := 'Field Name can not be ' + NewTemplateField
|
|
else
|
|
if(length(Fld.FldName) < 3) then
|
|
msg := 'Field Name must be at least three characters in length'
|
|
else
|
|
if(not (Fld.FldName[1] in ['A'..'Z','0'..'9'])) then
|
|
msg := 'First Field Name character must be "A" - "Z", or "0" - "9"'
|
|
else
|
|
if(assigned(uTmplFlds)) then
|
|
begin
|
|
for i := 0 to uTmplFlds.Count-1 do
|
|
begin
|
|
if(Fld <> uTmplFlds[i]) and
|
|
(CompareText(TTemplateField(uTmplFlds[i]).FFldName, Fld.FFldName) = 0) then
|
|
begin
|
|
msg := DUPFLD;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
if(msg = '') and (not IsTemplateFieldNameUnique(Fld.FFldName, Fld.ID)) then
|
|
msg := DUPFLD;
|
|
Result := (msg <> '');
|
|
if(Result) then
|
|
ShowMsg(msg);
|
|
end;
|
|
|
|
function SaveTemplateFieldErrors: string;
|
|
var
|
|
i: integer;
|
|
Errors: TStringList;
|
|
Fld: TTemplateField;
|
|
msg: string;
|
|
|
|
begin
|
|
Result := '';
|
|
if(assigned(uTmplFlds)) then
|
|
begin
|
|
Errors := nil;
|
|
try
|
|
for i := 0 to uTmplFlds.Count-1 do
|
|
begin
|
|
Fld := TTemplateField(uTmplFlds[i]);
|
|
if(Fld.FModified) then
|
|
begin
|
|
msg := Fld.SaveError;
|
|
if(msg <> '') then
|
|
begin
|
|
if(not assigned(Errors)) then
|
|
begin
|
|
Errors := TStringList.Create;
|
|
Errors.Add('The following template field save errors have occurred:');
|
|
Errors.Add('');
|
|
end;
|
|
Errors.Add(' ' + Fld.FldName + ': ' + msg);
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
if(assigned(Errors)) then
|
|
begin
|
|
Result := Errors.Text;
|
|
Errors.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ClearModifiedTemplateFields;
|
|
var
|
|
i: integer;
|
|
Fld: TTemplateField;
|
|
|
|
begin
|
|
if(assigned(uTmplFlds)) then
|
|
begin
|
|
for i := uTmplFlds.Count-1 downto 0 do
|
|
begin
|
|
Fld := TTemplateField(uTmplFlds[i]);
|
|
if(assigned(Fld)) and (Fld.FModified) then
|
|
begin
|
|
if Fld.FLocked then
|
|
UnlockTemplateField(Fld.FID);
|
|
Fld.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function AnyTemplateFieldsModified: boolean;
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
Result := FALSE;
|
|
if(assigned(uTmplFlds)) then
|
|
begin
|
|
for i := 0 to uTmplFlds.Count-1 do
|
|
begin
|
|
if(TTemplateField(uTmplFlds[i]).FModified) then
|
|
begin
|
|
Result := TRUE;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ListTemplateFields(const AText: string; AList: TStrings; ListErrors: boolean = FALSE);
|
|
var
|
|
i, j, k, flen, BadCount: integer;
|
|
flddesc, tmp, fld: string;
|
|
TmpList: TStringList;
|
|
InactiveList: TStringList;
|
|
FldObj: TTemplateField;
|
|
|
|
begin
|
|
if(AText = '') then exit;
|
|
BadCount := 0;
|
|
InactiveList := TStringList.Create;
|
|
try
|
|
TmpList := TStringList.Create;
|
|
try
|
|
TmpList.Text := AText;
|
|
for k := 0 to TmpList.Count-1 do
|
|
begin
|
|
tmp := TmpList[k];
|
|
repeat
|
|
i := pos(TemplateFieldBeginSignature, tmp);
|
|
if(i > 0) then
|
|
begin
|
|
fld := '';
|
|
j := pos(TemplateFieldEndSignature, copy(tmp, i + TemplateFieldSignatureLen, MaxInt));
|
|
if(j > 0) then
|
|
begin
|
|
inc(j, i + TemplateFieldSignatureLen - 1);
|
|
flen := j - i - TemplateFieldSignatureLen;
|
|
fld := copy(tmp,i + TemplateFieldSignatureLen, flen);
|
|
delete(tmp, i, flen + TemplateFieldSignatureLen + 1);
|
|
end
|
|
else
|
|
begin
|
|
delete(tmp,i,TemplateFieldSignatureLen);
|
|
inc(BadCount);
|
|
end;
|
|
if(fld <> '') then
|
|
begin
|
|
if ListErrors then
|
|
begin
|
|
FldObj := GetTemplateField(fld, FALSE);
|
|
if assigned(FldObj) then
|
|
begin
|
|
if FldObj.Inactive then
|
|
InactiveList.Add(' "' + fld + '"');
|
|
flddesc := '';
|
|
end
|
|
else
|
|
flddesc := ' "' + fld + '"';
|
|
end
|
|
else
|
|
flddesc := fld;
|
|
if(flddesc <> '') and (AList.IndexOf(flddesc) < 0) then
|
|
AList.Add(flddesc)
|
|
end;
|
|
end;
|
|
until (i = 0);
|
|
end;
|
|
finally
|
|
TmpList.Free;
|
|
end;
|
|
if ListErrors then
|
|
begin
|
|
if(AList.Count > 0) then
|
|
AList.Insert(0, 'The following template fields were not found:');
|
|
if (BadCount > 0) then
|
|
begin
|
|
if(BadCount = 1) then
|
|
tmp := 'A template field marker "' + TemplateFieldBeginSignature +
|
|
'" was found without a'
|
|
else
|
|
tmp := IntToStr(BadCount) + ' template field markers "' + TemplateFieldBeginSignature +
|
|
'" were found without';
|
|
if(AList.Count > 0) then
|
|
AList.Add('');
|
|
AList.Add(tmp + ' matching "' + TemplateFieldEndSignature + '"');
|
|
end;
|
|
if(InactiveList.Count > 0) then
|
|
begin
|
|
if(AList.Count > 0) then
|
|
AList.Add('');
|
|
AList.Add('The following inactive template fields were found:');
|
|
FastAddStrings(InactiveList, AList);
|
|
end;
|
|
if(AList.Count > 0) then
|
|
begin
|
|
AList.Insert(0, 'Text contains template field errors:');
|
|
AList.Insert(1, '');
|
|
end;
|
|
end;
|
|
finally
|
|
InactiveList.Free;
|
|
end;
|
|
end;
|
|
|
|
function BoilerplateTemplateFieldsOK(const AText: string; Msg: string = ''): boolean;
|
|
var
|
|
Errors: TStringList;
|
|
btns: TMsgDlgButtons;
|
|
|
|
begin
|
|
Result := TRUE;
|
|
Errors := TStringList.Create;
|
|
try
|
|
ListTemplateFields(AText, Errors, TRUE);
|
|
if(Errors.Count > 0) then
|
|
begin
|
|
if(Msg = 'OK') then
|
|
btns := [mbOK]
|
|
else
|
|
begin
|
|
btns := [mbAbort, mbIgnore];
|
|
Errors.Add('');
|
|
if(Msg = '') then
|
|
Msg := 'text insertion';
|
|
Errors.Add('Do you want to Abort ' + Msg + ', or Ignore the error and continue?');
|
|
end;
|
|
Result := (MessageDlg(Errors.Text, mtError, btns, 0) = mrIgnore);
|
|
end;
|
|
finally
|
|
Errors.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure EnsureText(edt: TEdit; ud: TUpDown);
|
|
var
|
|
v: integer;
|
|
s: string;
|
|
|
|
begin
|
|
if assigned(ud.Associate) then
|
|
begin
|
|
v := StrToIntDef(edt.Text, ud.Position);
|
|
if (v < ud.Min) or (v > ud.Max) then
|
|
v := ud.Position;
|
|
s := IntToStr(v);
|
|
if edt.Text <> s then
|
|
edt.Text := s;
|
|
end;
|
|
edt.SelStart := edt.GetTextLen;
|
|
end;
|
|
|
|
function TemplateFieldCode2Field(const Code: string): TTemplateFieldType;
|
|
var
|
|
typ: TTemplateFieldType;
|
|
|
|
begin
|
|
Result := dftUnknown;
|
|
for typ := low(TTemplateFieldType) to high(TTemplateFieldType) do
|
|
if Code = TemplateFieldTypeCodes[typ] then
|
|
begin
|
|
Result := typ;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TemplateDateCode2DateType(const Code: string): TTmplFldDateType;
|
|
var
|
|
typ: TTmplFldDateType;
|
|
|
|
begin
|
|
Result := dtUnknown;
|
|
for typ := low(TTmplFldDateType) to high(TTmplFldDateType) do
|
|
if Code = TemplateFieldDateCodes[typ] then
|
|
begin
|
|
Result := typ;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
procedure ConvertCodes2Text(sl: TStrings; Short: boolean);
|
|
var
|
|
i: integer;
|
|
tmp, output: string;
|
|
ftype: TTemplateFieldType;
|
|
dtype: TTmplFldDateType;
|
|
|
|
begin
|
|
for i := 0 to sl.Count-1 do
|
|
begin
|
|
tmp := sl[i];
|
|
if piece(tmp,U,4) = BOOLCHAR[TRUE] then
|
|
output := '* '
|
|
else
|
|
output := ' ';
|
|
ftype := TemplateFieldCode2Field(Piece(tmp, U, 3));
|
|
if ftype = dftDate then
|
|
begin
|
|
dtype := TemplateDateCode2DateType(Piece(tmp, U, 5));
|
|
output := output + TemplateDateTypeDesc[dtype, short];
|
|
end
|
|
else
|
|
output := output + TemplateFieldTypeDesc[ftype, short];
|
|
SetPiece(tmp, U, 3, output);
|
|
sl[i] := tmp;
|
|
end;
|
|
end;
|
|
|
|
{ TTemplateField }
|
|
|
|
constructor TTemplateField.Create(AData: TStrings);
|
|
var
|
|
tmp, p1: string;
|
|
AFID, i,idx,cnt: integer;
|
|
|
|
begin
|
|
AFID := 0;
|
|
if(assigned(AData)) then
|
|
begin
|
|
if AData.Count > 0 then
|
|
AFID := StrToIntDef(AData[0],0);
|
|
if(AFID > 0) and (AData.Count > 1) then
|
|
begin
|
|
FID := IntToStr(AFID);
|
|
FFldName := Piece(AData[1],U,1);
|
|
FFldType := TemplateFieldCode2Field(Piece(AData[1],U,2));
|
|
FInactive := (Piece(AData[1],U,3) = '1');
|
|
FMaxLen := StrToIntDef(Piece(AData[1],U,4),0);
|
|
FEditDefault := Piece(AData[1],U,5);
|
|
FLMText := Piece(AData[1],U,6);
|
|
idx := StrToIntDef(Piece(AData[1],U,7),0);
|
|
cnt := 0;
|
|
for i := 2 to AData.Count-1 do
|
|
begin
|
|
tmp := AData[i];
|
|
p1 := Piece(tmp,U,1);
|
|
tmp := Piece(tmp,U,2);
|
|
if(p1 = 'D') then
|
|
FNotes := FNotes + tmp + CRLF
|
|
else
|
|
if(p1 = 'U') then
|
|
FURL := tmp
|
|
else
|
|
if(p1 = 'I') then
|
|
begin
|
|
inc(cnt);
|
|
FItems := FItems + tmp + CRLF;
|
|
if(cnt=idx) then
|
|
FItemDefault := tmp;
|
|
end;
|
|
end;
|
|
FRequired := (Piece(AData[1],U,8) = '1');
|
|
FSepLines := (Piece(AData[1],U,9) = '1');
|
|
FTextLen := StrToIntDef(Piece(AData[1],U,10),0);
|
|
FIndent := StrToIntDef(Piece(AData[1],U,11),0);
|
|
FPad := StrToIntDef(Piece(AData[1],U,12),0);
|
|
FMinVal := StrToIntDef(Piece(AData[1],U,13),0);
|
|
FMaxVal := StrToIntDef(Piece(AData[1],U,14),0);
|
|
FIncrement := StrToIntDef(Piece(AData[1],U,15),0);
|
|
FDateType := TemplateDateCode2DateType(Piece(AData[1],U,16));
|
|
FModified := FALSE;
|
|
FNameChanged := FALSE;
|
|
end;
|
|
end;
|
|
if(AFID = 0) then
|
|
begin
|
|
inc(uNewTemplateFieldIDCnt);
|
|
FID := IntToStr(-uNewTemplateFieldIDCnt);
|
|
FFldName := NewTemplateField;
|
|
FModified := TRUE;
|
|
end;
|
|
if(not assigned(uTmplFlds)) then
|
|
uTmplFlds := TList.Create;
|
|
uTmplFlds.Add(Self);
|
|
end;
|
|
|
|
function TTemplateField.GetTemplateFieldDefault: string;
|
|
begin
|
|
case FFldType of
|
|
dftEditBox, dftNumber: Result := FEditDefault;
|
|
|
|
dftComboBox,
|
|
dftButton,
|
|
dftCheckBoxes, {Clear out embedded fields}
|
|
dftRadioButtons: Result := StripEmbedded(FItemDefault);
|
|
|
|
dftDate: if FEditDefault <> '' then Result := FEditDefault;
|
|
|
|
dftHyperlink, dftText: if FEditDefault <> '' then
|
|
Result := StripEmbedded(FEditDefault)
|
|
else
|
|
Result := URL;
|
|
|
|
dftWP: Result := Items;
|
|
end;
|
|
end;
|
|
|
|
procedure TTemplateField.CreateDialogControls(Entry: TTemplateDialogEntry;
|
|
var Index: Integer; CtrlID: integer);
|
|
|
|
var
|
|
i, Aht, w, tmp, AWdth: integer;
|
|
STmp: string;
|
|
TmpSL: TStringList;
|
|
edt: TEdit;
|
|
cbo: TORComboBox;
|
|
cb: TORCheckBox;
|
|
btn: TfraTemplateFieldButton;
|
|
dbox: TORDateBox;
|
|
dcbo: TORDateCombo;
|
|
lbl: TCPRSTemplateFieldLabel;
|
|
re: TRichEdit;
|
|
pnl: TCPRSDialogNumber;
|
|
DefDate: TFMDateTime;
|
|
ctrl: TControl;
|
|
|
|
function wdth: integer;
|
|
begin
|
|
if(Awdth < 0) then
|
|
Awdth := FontWidthPixel(Entry.FFont.Handle);
|
|
Result := Awdth;
|
|
end;
|
|
|
|
function ht: integer;
|
|
begin
|
|
if(Aht < 0) then
|
|
Aht := FontHeightPixel(Entry.FFont.Handle);
|
|
Result := Aht;
|
|
end;
|
|
|
|
procedure UpdateIndents(AControl: TControl);
|
|
var
|
|
idx: integer;
|
|
|
|
begin
|
|
if (FIndent > 0) or (FPad > 0) then
|
|
begin
|
|
idx := Entry.FIndents.IndexOfObject(AControl);
|
|
if idx < 0 then
|
|
Entry.FIndents.AddObject(IntToStr(FIndent * wdth) + U + IntToStr(FPad), AControl);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if(not FInactive) and (FFldType <> dftUnknown) then
|
|
begin
|
|
AWdth := -1;
|
|
Aht := -1;
|
|
ctrl := nil;
|
|
|
|
case FFldType of
|
|
dftEditBox:
|
|
begin
|
|
edt := TCPRSDialogFieldEdit.Create(nil);
|
|
(edt as ICPRSDialogComponent).RequiredField := Required;
|
|
edt.Parent := Entry.FPanel;
|
|
edt.BorderStyle := bsNone;
|
|
edt.Height := ht;
|
|
edt.Width := (wdth * Width + 4);
|
|
if FTextLen > 0 then
|
|
edt.MaxLength := FTextLen
|
|
else
|
|
edt.MaxLength := FMaxLen;
|
|
edt.Text := FEditDefault;
|
|
edt.Tag := CtrlID;
|
|
edt.OnChange := Entry.DoChange;
|
|
UpdateColorsFor508Compliance(edt, TRUE);
|
|
ctrl := edt;
|
|
end;
|
|
|
|
dftComboBox:
|
|
begin
|
|
cbo := TCPRSDialogComboBox.Create(nil);
|
|
(cbo as ICPRSDialogComponent).RequiredField := Required;
|
|
cbo.Parent := Entry.FPanel;
|
|
cbo.TemplateField := TRUE;
|
|
w := Width;
|
|
cbo.MaxLength := w;
|
|
if FTextLen > 0 then
|
|
cbo.MaxLength := FTextLen
|
|
else
|
|
cbo.ListItemsOnly := TRUE;
|
|
{Clear out embedded fields}
|
|
cbo.Items.Text := StripEmbedded(Items);
|
|
cbo.SelectByID(StripEmbedded(FItemDefault));
|
|
cbo.Tag := CtrlID;
|
|
cbo.OnClick := Entry.DoChange;
|
|
|
|
if cbo.Items.Count > 12 then
|
|
begin
|
|
cbo.Width := (wdth * w) + ScrollBarWidth + 8;
|
|
cbo.DropDownCount := 12;
|
|
end
|
|
else
|
|
begin
|
|
cbo.Width := (wdth * w) + 18;
|
|
cbo.DropDownCount := cbo.Items.Count;
|
|
end;
|
|
UpdateColorsFor508Compliance(cbo, TRUE);
|
|
ctrl := cbo;
|
|
end;
|
|
|
|
dftButton:
|
|
begin
|
|
btn := TfraTemplateFieldButton.Create(nil);
|
|
(btn as ICPRSDialogComponent).RequiredField := Required;
|
|
btn.Parent := Entry.FPanel;
|
|
{Clear out embedded fields}
|
|
btn.Items.Text := StripEmbedded(Items);
|
|
btn.ButtonText := StripEmbedded(FItemDefault);
|
|
btn.Height := ht;
|
|
btn.Width := (wdth * Width) + 6;
|
|
btn.Tag := CtrlID;
|
|
btn.OnChange := Entry.DoChange;
|
|
UpdateColorsFor508Compliance(btn);
|
|
ctrl := btn;
|
|
end;
|
|
|
|
dftCheckBoxes, dftRadioButtons:
|
|
begin
|
|
if FFldType = dftRadioButtons then
|
|
inc(uRadioGroupIndex);
|
|
TmpSL := TStringList.Create;
|
|
try
|
|
{Clear out embedded fields}
|
|
TmpSL.Text := StripEmbedded(Items);
|
|
for i := 0 to TmpSL.Count-1 do
|
|
begin
|
|
cb := TCPRSDialogCheckBox.Create(nil);
|
|
if i = 0 then
|
|
(cb as ICPRSDialogComponent).RequiredField := Required;
|
|
cb.Parent := Entry.FPanel;
|
|
cb.Caption := TmpSL[i];
|
|
cb.AutoSize := TRUE;
|
|
cb.AutoAdjustSize;
|
|
// cb.AutoSize := FALSE;
|
|
// cb.Height := ht;
|
|
if FFldType = dftRadioButtons then
|
|
begin
|
|
cb.GroupIndex := uRadioGroupIndex;
|
|
cb.RadioStyle := TRUE;
|
|
end;
|
|
if(TmpSL[i] = StripEmbedded(FItemDefault)) then
|
|
cb.Checked := TRUE;
|
|
cb.Tag := CtrlID;
|
|
if FSepLines and (FFldType in SepLinesTypes) then
|
|
cb.StringData := NewLine;
|
|
cb.OnClick := Entry.DoChange;
|
|
UpdateColorsFor508Compliance(cb);
|
|
inc(Index);
|
|
Entry.FControls.InsertObject(Index, '', cb);
|
|
if (i=0) or FSepLines then
|
|
UpdateIndents(cb);
|
|
end;
|
|
finally
|
|
TmpSL.Free;
|
|
end;
|
|
end;
|
|
|
|
dftDate:
|
|
begin
|
|
if FEditDefault <> '' then
|
|
DefDate := StrToFMDateTime(FEditDefault)
|
|
else
|
|
DefDate := 0;
|
|
if FDateType in DateComboTypes then
|
|
begin
|
|
dcbo := TCPRSDialogDateCombo.Create(nil);
|
|
(dcbo as ICPRSDialogComponent).RequiredField := Required;
|
|
dcbo.Parent := Entry.FPanel;
|
|
dcbo.Tag := CtrlID;
|
|
dcbo.IncludeBtn := (FDateType = dtCombo);
|
|
dcbo.IncludeDay := (FDateType = dtCombo);
|
|
dcbo.IncludeMonth := (FDateType <> dtYear);
|
|
dcbo.FMDate := DefDate;
|
|
dcbo.TemplateField := TRUE;
|
|
dcbo.OnChange := Entry.DoChange;
|
|
UpdateColorsFor508Compliance(dcbo, TRUE);
|
|
ctrl := dcbo;
|
|
end
|
|
else
|
|
begin
|
|
dbox := TCPRSDialogDateBox.Create(nil);
|
|
(dbox as ICPRSDialogComponent).RequiredField := Required;
|
|
dbox.Parent := Entry.FPanel;
|
|
dbox.Tag := CtrlID;
|
|
dbox.DateOnly := (FDateType = dtDate);
|
|
dbox.RequireTime := (FDateType = dtDateReqTime);
|
|
dbox.TemplateField := TRUE;
|
|
dbox.FMDateTime := DefDate;
|
|
if (FDateType = dtDate) then
|
|
tmp := 11
|
|
else
|
|
tmp := 17;
|
|
dbox.Width := (wdth * tmp) + 18;
|
|
dbox.OnChange := Entry.DoChange;
|
|
UpdateColorsFor508Compliance(dbox, TRUE);
|
|
ctrl := dbox;
|
|
end;
|
|
end;
|
|
|
|
dftNumber:
|
|
begin
|
|
pnl := TCPRSDialogNumber.CreatePanel(nil);
|
|
(pnl as ICPRSDialogComponent).RequiredField := Required;
|
|
pnl.Parent := Entry.FPanel;
|
|
pnl.BevelOuter := bvNone;
|
|
pnl.Tag := CtrlID;
|
|
pnl.Edit.Height := ht;
|
|
pnl.Edit.Width := (wdth * 5 + 4);
|
|
pnl.UpDown.Min := MinVal;
|
|
pnl.UpDown.Max := MaxVal;
|
|
pnl.UpDown.Min := MinVal; // Both ud.Min settings are needeed!
|
|
i := Increment;
|
|
if i < 1 then i := 1;
|
|
pnl.UpDown.Increment := i;
|
|
pnl.UpDown.Position := StrToIntDef(EditDefault, 0);
|
|
pnl.Edit.OnChange := Entry.UpDownChange;
|
|
pnl.Height := pnl.Edit.Height;
|
|
pnl.Width := pnl.Edit.Width + pnl.UpDown.Width;
|
|
UpdateColorsFor508Compliance(pnl, TRUE);
|
|
ctrl := pnl;
|
|
end;
|
|
|
|
dftHyperlink, dftText:
|
|
begin
|
|
if (FFldType = dftHyperlink) and User.WebAccess then
|
|
lbl := TCPRSDialogHyperlinkLabel.Create(nil)
|
|
else
|
|
lbl := TCPRSTemplateFieldLabel.Create(nil);
|
|
lbl.Parent := Entry.FPanel;
|
|
lbl.ShowAccelChar := FALSE;
|
|
lbl.Exclude := FSepLines;
|
|
if (FFldType = dftHyperlink) then
|
|
begin
|
|
if FEditDefault <> '' then
|
|
lbl.Caption := StripEmbedded(FEditDefault)
|
|
else
|
|
lbl.Caption := URL;
|
|
end
|
|
else
|
|
begin
|
|
STmp := StripEmbedded(Items);
|
|
if copy(STmp,length(STmp)-1,2) = CRLF then
|
|
delete(STmp,length(STmp)-1,2);
|
|
lbl.Caption := STmp;
|
|
end;
|
|
if lbl is TCPRSDialogHyperlinkLabel then
|
|
TCPRSDialogHyperlinkLabel(lbl).Init(FURL);
|
|
lbl.Tag := CtrlID;
|
|
UpdateColorsFor508Compliance(lbl);
|
|
ctrl := lbl;
|
|
end;
|
|
|
|
dftWP:
|
|
begin
|
|
re := TCPRSDialogRichEdit.Create(nil);
|
|
(re as ICPRSDialogComponent).RequiredField := Required;
|
|
re.Parent := Entry.FPanel;
|
|
re.Tag := CtrlID;
|
|
tmp := FMaxLen;
|
|
if tmp < 5 then
|
|
tmp := 5;
|
|
re.Width := wdth * tmp;
|
|
tmp := FTextLen;
|
|
if tmp < 2 then
|
|
tmp := 2
|
|
else
|
|
if tmp > MaxTFWPLines then
|
|
tmp := MaxTFWPLines;
|
|
re.Height := ht * tmp;
|
|
re.BorderStyle := bsNone;
|
|
re.ScrollBars := ssVertical;
|
|
re.Lines.Text := Items;
|
|
re.OnChange := Entry.DoChange;
|
|
UpdateColorsFor508Compliance(re, TRUE);
|
|
ctrl := re;
|
|
end;
|
|
end;
|
|
if assigned(ctrl) then
|
|
begin
|
|
inc(Index);
|
|
Entry.FControls.InsertObject(Index, '', ctrl);
|
|
UpdateIndents(ctrl);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TTemplateField.CanModify: boolean;
|
|
begin
|
|
if((not FModified) and (not FLocked) and (StrToIntDef(FID,0) > 0)) then
|
|
begin
|
|
FLocked := LockTemplateField(FID);
|
|
Result := FLocked;
|
|
if(not FLocked) then
|
|
ShowMsg('Template Field ' + FFldName + ' is currently being edited by another user.');
|
|
end
|
|
else
|
|
Result := TRUE;
|
|
if(Result) then FModified := TRUE;
|
|
end;
|
|
|
|
procedure TTemplateField.SetEditDefault(const Value: string);
|
|
begin
|
|
if(FEditDefault <> Value) and CanModify then
|
|
FEditDefault := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetFldName(const Value: string);
|
|
begin
|
|
if(FFldName <> Value) and CanModify then
|
|
begin
|
|
FFldName := Value;
|
|
FNameChanged := TRUE;
|
|
end;
|
|
end;
|
|
|
|
procedure TTemplateField.SetFldType(const Value: TTemplateFieldType);
|
|
begin
|
|
if(FFldType <> Value) and CanModify then
|
|
begin
|
|
FFldType := Value;
|
|
if(Value = dftEditBox) then
|
|
begin
|
|
if (FMaxLen < 1) then
|
|
FMaxLen := 1;
|
|
if FTextLen < FMaxLen then
|
|
FTextLen := FMaxLen;
|
|
end
|
|
else
|
|
if(Value = dftHyperlink) and (FURL = '') then
|
|
FURL := 'http://'
|
|
else
|
|
if(Value = dftComboBox) and (FMaxLen < 1) then
|
|
begin
|
|
FMaxLen := Width;
|
|
if FMaxLen < 1 then
|
|
FMaxLen := 1;
|
|
end
|
|
else
|
|
if(Value = dftWP) then
|
|
begin
|
|
if (FMaxLen = 0) then
|
|
FMaxLen := MAX_ENTRY_WIDTH
|
|
else
|
|
if (FMaxLen < 5) then
|
|
FMaxLen := 5;
|
|
if FTextLen < 2 then
|
|
FTextLen := 2;
|
|
end
|
|
else
|
|
if(Value = dftDate) and (FDateType = dtUnknown) then
|
|
FDateType := dtDate;
|
|
end;
|
|
end;
|
|
|
|
procedure TTemplateField.SetID(const Value: string);
|
|
begin
|
|
// if(FID <> Value) and CanModify then
|
|
FID := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetInactive(const Value: boolean);
|
|
begin
|
|
if(FInactive <> Value) and CanModify then
|
|
FInactive := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetItemDefault(const Value: string);
|
|
begin
|
|
if(FItemDefault <> Value) and CanModify then
|
|
FItemDefault := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetItems(const Value: string);
|
|
begin
|
|
if(FItems <> Value) and CanModify then
|
|
FItems := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetLMText(const Value: string);
|
|
begin
|
|
if(FLMText <> Value) and CanModify then
|
|
FLMText := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetMaxLen(const Value: integer);
|
|
begin
|
|
if(FMaxLen <> Value) and CanModify then
|
|
FMaxLen := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetNotes(const Value: string);
|
|
begin
|
|
if(FNotes <> Value) and CanModify then
|
|
FNotes := Value;
|
|
end;
|
|
|
|
function TTemplateField.SaveError: string;
|
|
var
|
|
TmpSL, FldSL: TStringList;
|
|
AID,Res: string;
|
|
idx, i: integer;
|
|
IEN64: Int64;
|
|
NewRec: boolean;
|
|
|
|
begin
|
|
if(FFldName = NewTemplateField) then
|
|
begin
|
|
Result := 'Template Field can not be named "' + NewTemplateField + '"';
|
|
exit;
|
|
end;
|
|
Result := '';
|
|
NewRec := (StrToIntDef(FID,0) < 0);
|
|
if(FModified or NewRec) then
|
|
begin
|
|
TmpSL := TStringList.Create;
|
|
try
|
|
FldSL := TStringList.Create;
|
|
try
|
|
if(StrToIntDef(FID,0) > 0) then
|
|
AID := FID
|
|
else
|
|
AID := '0';
|
|
FldSL.Add('.01='+FFldName);
|
|
FldSL.Add('.02='+TemplateFieldTypeCodes[FFldType]);
|
|
FldSL.Add('.03='+BOOLCHAR[FInactive]);
|
|
FldSL.Add('.04='+IntToStr(FMaxLen));
|
|
FldSL.Add('.05='+FEditDefault);
|
|
FldSL.Add('.06='+FLMText);
|
|
idx := -1;
|
|
if(FItems <> '') and (FItemDefault <> '') then
|
|
begin
|
|
TmpSL.Text := FItems;
|
|
for i := 0 to TmpSL.Count-1 do
|
|
if(FItemDefault = TmpSL[i]) then
|
|
begin
|
|
idx := i;
|
|
break;
|
|
end;
|
|
end;
|
|
FldSL.Add('.07='+IntToStr(Idx+1));
|
|
FldSL.Add('.08='+BOOLCHAR[fRequired]);
|
|
FldSL.Add('.09='+BOOLCHAR[fSepLines]);
|
|
FldSL.Add('.1=' +IntToStr(FTextLen));
|
|
FldSL.Add('.11='+IntToStr(FIndent));
|
|
FldSL.Add('.12='+IntToStr(FPad));
|
|
FldSL.Add('.13='+IntToStr(FMinVal));
|
|
FldSL.Add('.14='+IntToStr(FMaxVal));
|
|
FldSL.Add('.15='+IntToStr(FIncrement));
|
|
if FDateType = dtUnknown then
|
|
FldSL.Add('.16=@')
|
|
else
|
|
FldSL.Add('.16='+TemplateFieldDateCodes[FDateType]);
|
|
|
|
if FURL='' then
|
|
FldSL.Add('3=@')
|
|
else
|
|
FldSL.Add('3='+FURL);
|
|
|
|
if(FNotes <> '') or (not NewRec) then
|
|
begin
|
|
if(FNotes = '') then
|
|
FldSL.Add('2,1=@')
|
|
else
|
|
begin
|
|
TmpSL.Text := FNotes;
|
|
for i := 0 to TmpSL.Count-1 do
|
|
FldSL.Add('2,'+IntToStr(i+1)+',0='+TmpSL[i]);
|
|
end;
|
|
end;
|
|
if((FItems <> '') or (not NewRec)) then
|
|
begin
|
|
if(FItems = '') then
|
|
FldSL.Add('10,1=@')
|
|
else
|
|
begin
|
|
TmpSL.Text := FItems;
|
|
for i := 0 to TmpSL.Count-1 do
|
|
FldSL.Add('10,'+IntToStr(i+1)+',0='+TmpSL[i]);
|
|
end;
|
|
end;
|
|
|
|
Res := UpdateTemplateField(AID, FldSL);
|
|
IEN64 := StrToInt64Def(Piece(Res,U,1),0);
|
|
if(IEN64 > 0) then
|
|
begin
|
|
if(NewRec) then
|
|
FID := IntToStr(IEN64)
|
|
else
|
|
UnlockTemplateField(FID);
|
|
FModified := FALSE;
|
|
FNameChanged := FALSE;
|
|
FLocked := FALSE;
|
|
end
|
|
else
|
|
Result := Piece(Res, U, 2);
|
|
finally
|
|
FldSL.Free;
|
|
end;
|
|
finally
|
|
TmpSL.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TTemplateField.Assign(AFld: TTemplateField);
|
|
begin
|
|
FMaxLen := AFld.FMaxLen;
|
|
FFldName := AFld.FFldName;
|
|
FLMText := AFld.FLMText;
|
|
FEditDefault := AFld.FEditDefault;
|
|
FNotes := AFld.FNotes;
|
|
FItems := AFld.FItems;
|
|
FInactive := AFld.FInactive;
|
|
FItemDefault := AFld.FItemDefault;
|
|
FFldType := AFld.FFldType;
|
|
FRequired := AFld.FRequired;
|
|
FSepLines := AFld.FSepLines;
|
|
FTextLen := AFld.FTextLen;
|
|
FIndent := AFld.FIndent;
|
|
FPad := AFld.FPad;
|
|
FMinVal := AFld.FMinVal;
|
|
FMaxVal := AFld.FMaxVal;
|
|
FIncrement := AFld.FIncrement;
|
|
FDateType := AFld.FDateType;
|
|
FURL := AFld.FURL;
|
|
end;
|
|
|
|
function TTemplateField.Width: integer;
|
|
var
|
|
i, ilen: integer;
|
|
TmpSL: TStringList;
|
|
|
|
begin
|
|
if(FFldType = dftEditBox) then
|
|
Result := FMaxLen
|
|
else
|
|
begin
|
|
if FMaxLen > 0 then
|
|
Result := FMaxLen
|
|
else
|
|
begin
|
|
Result := -1;
|
|
TmpSL := TStringList.Create;
|
|
try
|
|
TmpSL.Text := StripEmbedded(FItems);
|
|
for i := 0 to TmpSL.Count-1 do
|
|
begin
|
|
ilen := length(TmpSL[i]);
|
|
if(Result < ilen) then
|
|
Result := ilen;
|
|
end;
|
|
finally
|
|
TmpSL.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
if Result > MaxTFEdtLen then
|
|
Result := MaxTFEdtLen;
|
|
end;
|
|
|
|
destructor TTemplateField.Destroy;
|
|
begin
|
|
uTmplFlds.Remove(Self);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TTemplateField.SetRequired(const Value: boolean);
|
|
begin
|
|
if(FRequired <> Value) and CanModify then
|
|
FRequired := Value;
|
|
end;
|
|
|
|
function TTemplateField.NewField: boolean;
|
|
begin
|
|
Result := (StrToIntDef(FID,0) <= 0);
|
|
end;
|
|
|
|
procedure TTemplateField.SetSepLines(const Value: boolean);
|
|
begin
|
|
if(FSepLines <> Value) and CanModify then
|
|
FSepLines := Value
|
|
end;
|
|
|
|
procedure TTemplateField.SetIncrement(const Value: integer);
|
|
begin
|
|
if(FIncrement <> Value) and CanModify then
|
|
FIncrement := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetIndent(const Value: integer);
|
|
begin
|
|
if(FIndent <> Value) and CanModify then
|
|
FIndent := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetMaxVal(const Value: integer);
|
|
begin
|
|
if(FMaxVal <> Value) and CanModify then
|
|
FMaxVal := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetMinVal(const Value: integer);
|
|
begin
|
|
if(FMinVal <> Value) and CanModify then
|
|
FMinVal := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetPad(const Value: integer);
|
|
begin
|
|
if(FPad <> Value) and CanModify then
|
|
FPad := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetTextLen(const Value: integer);
|
|
begin
|
|
if(FTextLen <> Value) and CanModify then
|
|
FTextLen := Value;
|
|
end;
|
|
|
|
procedure TTemplateField.SetURL(const Value: string);
|
|
begin
|
|
if(FURL <> Value) and CanModify then
|
|
FURL := Value;
|
|
end;
|
|
|
|
function TTemplateField.GetRequired: boolean;
|
|
begin
|
|
if FFldType in NoRequired then
|
|
Result := FALSE
|
|
else
|
|
Result := FRequired;
|
|
end;
|
|
|
|
procedure TTemplateField.SetDateType(const Value: TTmplFldDateType);
|
|
begin
|
|
if(FDateType <> Value) and CanModify then
|
|
FDateType := Value;
|
|
end;
|
|
|
|
{ TTemplateDialogEntry }
|
|
const
|
|
EOL_MARKER = #182;
|
|
SR_BREAK = #186;
|
|
|
|
procedure PanelDestroy(AData: Pointer; Sender: TObject);
|
|
var
|
|
idx: integer;
|
|
dlg: TTemplateDialogEntry;
|
|
|
|
begin
|
|
dlg := TTemplateDialogEntry(AData);
|
|
idx := uEntries.IndexOf(dlg.FID);
|
|
if(idx >= 0) then
|
|
uEntries.Delete(idx);
|
|
dlg.FPanelDying := TRUE;
|
|
dlg.Free;
|
|
end;
|
|
|
|
constructor TTemplateDialogEntry.Create(AParent: TWinControl; AID, Text: string);
|
|
var
|
|
CtrlID, idx, i, j, flen: integer;
|
|
txt, FldName: string;
|
|
Fld: TTemplateField;
|
|
|
|
begin
|
|
FID := AID;
|
|
FText := Text;
|
|
FControls := TStringList.Create;
|
|
FIndents := TStringList.Create;
|
|
FFont := TFont.Create;
|
|
FFont.Assign(TORExposedControl(AParent).Font);
|
|
FControls.Text := Text;
|
|
if(FControls.Count > 1) then
|
|
begin
|
|
for i := 1 to FControls.Count-1 do
|
|
FControls[i] := EOL_MARKER + FControls[i];
|
|
if not ScreenReaderSystemActive then
|
|
StripScreenReaderCodes(FControls);
|
|
end;
|
|
FFirstBuild := TRUE;
|
|
FPanel := TDlgFieldPanel.Create(AParent.Owner);
|
|
FPanel.Parent := AParent;
|
|
FPanel.BevelOuter := bvNone;
|
|
FPanel.Caption := '';
|
|
FPanel.Font.Assign(FFont);
|
|
UpdateColorsFor508Compliance(FPanel, TRUE);
|
|
idx := 0;
|
|
while (idx < FControls.Count) do
|
|
begin
|
|
txt := FControls[idx];
|
|
i := pos(TemplateFieldBeginSignature, txt);
|
|
if(i > 0) then
|
|
begin
|
|
if(copy(txt, i + TemplateFieldSignatureLen, 1) = FieldIDDelim) then
|
|
begin
|
|
CtrlID := StrToIntDef(copy(txt, i + TemplateFieldSignatureLen + 1, FieldIDLen-1), 0);
|
|
delete(txt,i + TemplateFieldSignatureLen, FieldIDLen);
|
|
end
|
|
else
|
|
CtrlID := 0;
|
|
j := pos(TemplateFieldEndSignature, copy(txt, i + TemplateFieldSignatureLen, MaxInt));
|
|
if(j > 0) then
|
|
begin
|
|
inc(j, i + TemplateFieldSignatureLen - 1);
|
|
flen := j - i - TemplateFieldSignatureLen;
|
|
FldName := copy(txt, i + TemplateFieldSignatureLen, flen);
|
|
Fld := GetTemplateField(FldName, FALSE);
|
|
delete(txt,i,flen + TemplateFieldSignatureLen + 1);
|
|
if(assigned(Fld)) then
|
|
begin
|
|
FControls[idx] := copy(txt,1,i-1);
|
|
if(Fld.Required) then
|
|
begin
|
|
if ScreenReaderSystemActive then
|
|
begin
|
|
if Fld.FFldType in [dftCheckBoxes, dftRadioButtons] then
|
|
FControls[idx] := FControls[idx] + ScreenReaderStopCode;
|
|
end;
|
|
FControls[idx] := FControls[idx] + '*';
|
|
end;
|
|
Fld.CreateDialogControls(Self, idx, CtrlID);
|
|
FControls.Insert(idx+1,copy(txt,i,MaxInt));
|
|
end
|
|
else
|
|
begin
|
|
FControls[idx] := txt;
|
|
dec(idx);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
delete(txt,i,TemplateFieldSignatureLen);
|
|
FControls[idx] := txt;
|
|
dec(idx);
|
|
end;
|
|
end;
|
|
inc(idx);
|
|
end;
|
|
if ScreenReaderSystemActive then
|
|
begin
|
|
idx := 0;
|
|
while (idx < FControls.Count) do
|
|
begin
|
|
txt := FControls[idx];
|
|
i := pos(ScreenReaderStopCode, txt);
|
|
if i > 0 then
|
|
begin
|
|
FControls[idx] := copy(txt, 1, i-1);
|
|
txt := copy(txt, i + ScreenReaderStopCodeLen, MaxInt);
|
|
FControls.Insert(idx+1, SR_BREAK + txt);
|
|
end;
|
|
inc(idx);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
destructor TTemplateDialogEntry.Destroy;
|
|
begin
|
|
if assigned(FOnDestroy) then
|
|
FOnDestroy(Self);
|
|
KillLabels;
|
|
KillObj(@FControls, TRUE);
|
|
if FPanelDying then
|
|
FPanel := nil
|
|
else
|
|
FreeAndNil(FPanel);
|
|
FreeAndNil(FFont);
|
|
FreeAndNil(FIndents);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TTemplateDialogEntry.DoChange(Sender: TObject);
|
|
begin
|
|
if (not FUpdating) and assigned(FOnChange) then
|
|
FOnChange(Self);
|
|
end;
|
|
|
|
function TTemplateDialogEntry.GetControlText(CtrlID: integer; NoCommas: boolean;
|
|
var FoundEntry: boolean; AutoWrap: boolean;
|
|
emField: string = ''): string;
|
|
var
|
|
x, i, j, ind, idx: integer;
|
|
Ctrl: TControl;
|
|
Done: boolean;
|
|
iString: string;
|
|
iField: TTemplateField;
|
|
iTemp: TStringList;
|
|
|
|
function GetOriginalItem(istr: string): string;
|
|
begin
|
|
Result := '';
|
|
if emField <> '' then
|
|
begin
|
|
iField := GetTemplateField(emField,FALSE);
|
|
iTemp := nil;
|
|
if ifield <> nil then
|
|
try
|
|
iTemp := TStringList.Create;
|
|
iTemp.Text := StripEmbedded(iField.Items);
|
|
x := iTemp.IndexOf(istr);
|
|
if x >= 0 then
|
|
begin
|
|
iTemp.Text := iField.Items;
|
|
Result := iTemp.Strings[x];
|
|
end;
|
|
finally
|
|
iTemp.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
begin
|
|
Result := '';
|
|
Done := FALSE;
|
|
ind := -1;
|
|
for i := 0 to FControls.Count-1 do
|
|
begin
|
|
Ctrl := TControl(FControls.Objects[i]);
|
|
if(assigned(Ctrl)) and (Ctrl.Tag = CtrlID) then
|
|
begin
|
|
FoundEntry := TRUE;
|
|
Done := TRUE;
|
|
if ind < 0 then
|
|
begin
|
|
idx := FIndents.IndexOfObject(Ctrl);
|
|
if idx >= 0 then
|
|
ind := StrToIntDef(Piece(FIndents[idx], U, 2), 0)
|
|
else
|
|
ind := 0;
|
|
end;
|
|
if(Ctrl is TCPRSTemplateFieldLabel) then
|
|
begin
|
|
if not TCPRSTemplateFieldLabel(Ctrl).Exclude then begin
|
|
if emField <> '' then begin
|
|
iField := GetTemplateField(emField,FALSE);
|
|
case iField.FldType of
|
|
dftHyperlink: if iField.EditDefault <> '' then
|
|
Result := iField.EditDefault
|
|
else
|
|
Result := iField.URL;
|
|
dftText: begin
|
|
iString := iField.Items;
|
|
if copy(iString,length(iString)-1,2) = CRLF then
|
|
delete(iString,length(iString)-1,2);
|
|
Result := iString;
|
|
end;
|
|
else {case}
|
|
Result := TCPRSTemplateFieldLabel(Ctrl).Caption
|
|
end; {case iField.FldType}
|
|
end {if emField}
|
|
else
|
|
Result := TCPRSTemplateFieldLabel(Ctrl).Caption;
|
|
end;
|
|
end
|
|
else
|
|
if(Ctrl is TEdit) then
|
|
Result := TEdit(Ctrl).Text
|
|
else
|
|
if(Ctrl is TORComboBox) then begin
|
|
Result := TORComboBox(Ctrl).Text;
|
|
iString := GetOriginalItem(Result);
|
|
if iString <> '' then
|
|
Result := iString;
|
|
end
|
|
else
|
|
if(Ctrl is TORDateCombo) then
|
|
Result := TORDateCombo(Ctrl).Text + ':' + FloatToStr(TORDateCombo(Ctrl).FMDate)
|
|
else
|
|
if(Ctrl is TORDateBox) then
|
|
Result := TORDateBox(Ctrl).Text
|
|
else
|
|
if(Ctrl is TRichEdit) then
|
|
begin
|
|
if((ind = 0) and (not AutoWrap)) then
|
|
Result := TRichEdit(Ctrl).Lines.Text
|
|
else
|
|
begin
|
|
for j := 0 to TRichEdit(Ctrl).Lines.Count-1 do
|
|
begin
|
|
if AutoWrap then
|
|
begin
|
|
if(Result <> '') then
|
|
Result := Result + ' ';
|
|
Result := Result + TRichEdit(Ctrl).Lines[j];
|
|
end
|
|
else
|
|
begin
|
|
if(Result <> '') then
|
|
Result := Result + CRLF;
|
|
Result := Result + StringOfChar(' ', ind) + TRichEdit(Ctrl).Lines[j];
|
|
end;
|
|
end;
|
|
ind := 0;
|
|
end;
|
|
end
|
|
else
|
|
if(Ctrl is TORCheckBox) then
|
|
begin
|
|
Done := FALSE;
|
|
if(TORCheckBox(Ctrl).Checked) then
|
|
begin
|
|
if(Result <> '') then
|
|
begin
|
|
if NoCommas then
|
|
Result := Result + '|'
|
|
else
|
|
Result := Result + ', ';
|
|
end;
|
|
iString := GetOriginalItem(TORCheckBox(Ctrl).Caption);
|
|
if iString <> '' then
|
|
Result := Result + iString
|
|
else
|
|
Result := Result + TORCheckBox(Ctrl).Caption;
|
|
end;
|
|
end
|
|
else
|
|
if(Ctrl is TfraTemplateFieldButton) then
|
|
begin
|
|
Result := TfraTemplateFieldButton(Ctrl).ButtonText;
|
|
iString := GetOriginalItem(Result);
|
|
if iString <> '' then
|
|
Result := iString;
|
|
end
|
|
else
|
|
if(Ctrl is TPanel) then
|
|
begin
|
|
for j := 0 to Ctrl.ComponentCount-1 do
|
|
if Ctrl.Components[j] is TUpDown then
|
|
begin
|
|
Result := IntToStr(TUpDown(Ctrl.Components[j]).Position);
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
if Done then break;
|
|
end;
|
|
if (ind > 0) and (not NoCommas) then
|
|
Result := StringOfChar(' ', ind) + Result;
|
|
end;
|
|
|
|
function TTemplateDialogEntry.GetFieldValues: string;
|
|
var
|
|
i: integer;
|
|
Ctrl: TControl;
|
|
CtrlID: integer;
|
|
TmpIDs: TList;
|
|
TmpSL: TStringList;
|
|
Dummy: boolean;
|
|
|
|
begin
|
|
Result := '';
|
|
TmpIDs := TList.Create;
|
|
try
|
|
TmpSL := TStringList.Create;
|
|
try
|
|
for i := 0 to FControls.Count-1 do
|
|
begin
|
|
Ctrl := TControl(FControls.Objects[i]);
|
|
if(assigned(Ctrl)) then
|
|
begin
|
|
CtrlID := Ctrl.Tag;
|
|
if(TmpIDs.IndexOf(Pointer(CtrlID)) < 0) then
|
|
begin
|
|
TmpSL.Add(IntToStr(CtrlID) + U + GetControlText(CtrlID, TRUE, Dummy, FALSE));
|
|
TmpIDs.Add(Pointer(CtrlID));
|
|
end;
|
|
end;
|
|
end;
|
|
Result := TmpSL.CommaText;
|
|
finally
|
|
TmpSL.Free;
|
|
end;
|
|
finally
|
|
TmpIDs.Free;
|
|
end;
|
|
end;
|
|
|
|
function TTemplateDialogEntry.GetPanel(MaxLen: integer; AParent: TWinControl;
|
|
OwningCheckBox: TCPRSDialogParentCheckBox): TDlgFieldPanel;
|
|
var
|
|
i, x, y, cnt, idx, ind, yinc, ybase, MaxX: integer;
|
|
MaxTextLen: integer; {Max num of chars per line in pixels}
|
|
MaxChars: integer; {Max num of chars per line}
|
|
txt: string;
|
|
ctrl: TControl;
|
|
LastLineBlank: boolean;
|
|
sLbl: TCPRSDialogStaticLabel;
|
|
nLbl: TVA508ChainedLabel;
|
|
sLblHeight: integer;
|
|
TabOrdr: integer;
|
|
|
|
const
|
|
FOCUS_RECT_MARGIN = 2; {The margin around the panel so the label won't
|
|
overlay the focus rect on its parent panel.}
|
|
|
|
procedure Add2TabOrder(ctrl: TWinControl);
|
|
begin
|
|
ctrl.TabOrder := TabOrdr;
|
|
inc(TabOrdr);
|
|
end;
|
|
|
|
function StripSRCode(var txt: string; code: string; len: integer): integer;
|
|
begin
|
|
Result := pos(code, txt);
|
|
if Result > 0 then
|
|
begin
|
|
delete(txt,Result,len);
|
|
dec(Result);
|
|
end
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure DoLabel(Atxt: string);
|
|
var
|
|
ctrl: TControl;
|
|
tempLbl: TVA508ChainedLabel;
|
|
|
|
begin
|
|
if ScreenReaderSystemActive then
|
|
begin
|
|
if assigned(sLbl) then
|
|
begin
|
|
tempLbl := TVA508ChainedLabel.Create(nil);
|
|
if assigned(nLbl) then
|
|
nLbl.NextLabel := tempLbl
|
|
else
|
|
sLbl.NextLabel := tempLbl;
|
|
nLbl := tempLbl;
|
|
ctrl := nLbl;
|
|
end
|
|
else
|
|
begin
|
|
sLbl := TCPRSDialogStaticLabel.Create(nil);
|
|
ctrl := sLbl;
|
|
end;
|
|
end
|
|
else
|
|
ctrl := TLabel.Create(nil);
|
|
SetOrdProp(ctrl, ShowAccelCharProperty, ord(FALSE));
|
|
SetStrProp(ctrl, CaptionProperty, Atxt);
|
|
ctrl.Parent := FPanel;
|
|
ctrl.Left := x;
|
|
ctrl.Top := y;
|
|
if ctrl = sLbl then
|
|
begin
|
|
Add2TabOrder(sLbl);
|
|
sLbl.Height := sLblHeight;
|
|
ScreenReaderSystem_CurrentLabel(sLbl);
|
|
end;
|
|
if ScreenReaderSystemActive then
|
|
ScreenReaderSystem_AddText(Atxt);
|
|
UpdateColorsFor508Compliance(ctrl);
|
|
inc(x, ctrl.Width);
|
|
end;
|
|
|
|
procedure Init;
|
|
var
|
|
lbl : TLabel;
|
|
begin
|
|
if(FFirstBuild) then
|
|
FFirstBuild := FALSE
|
|
else
|
|
KillLabels;
|
|
y := FOCUS_RECT_MARGIN; {placement of labels on panel so they don't cover the}
|
|
x := FOCUS_RECT_MARGIN; {focus rectangle}
|
|
MaxX := 0;
|
|
//ybase := FontHeightPixel(FFont.Handle) + 1 + (FOCUS_RECT_MARGIN * 2); AGP commentout line for
|
|
//reminder spacing
|
|
ybase := FontHeightPixel(FFont.Handle) + 2;
|
|
yinc := ybase;
|
|
LastLineBlank := FALSE;
|
|
sLbl := nil;
|
|
nLbl := nil;
|
|
TabOrdr := 0;
|
|
if ScreenReaderSystemActive then
|
|
begin
|
|
ScreenReaderSystem_CurrentCheckBox(OwningCheckBox);
|
|
lbl := TLabel.Create(nil);
|
|
try
|
|
lbl.Parent := FPanel;
|
|
sLblHeight := lbl.Height + 2;
|
|
finally
|
|
lbl.Free;
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
procedure Text508Work;
|
|
var
|
|
ContinueCode: boolean;
|
|
begin
|
|
if StripCode(txt, SR_BREAK) then
|
|
begin
|
|
ScreenReaderSystem_Stop;
|
|
nLbl := nil;
|
|
sLbl := nil;
|
|
end;
|
|
|
|
ContinueCode := FALSE;
|
|
while StripSRCode(txt, ScreenReaderContinueCode, ScreenReaderContinueCodeLen) >= 0 do
|
|
ContinueCode := TRUE;
|
|
while StripSRCode(txt, ScreenReaderContinueCodeOld, ScreenReaderContinueCodeOldLen) >= 0 do
|
|
ContinueCode := TRUE;
|
|
if ContinueCode then
|
|
ScreenReaderSystem_Continue;
|
|
end;
|
|
|
|
procedure Ctrl508Work(ctrl: TControl);
|
|
var
|
|
lbl: TCPRSTemplateFieldLabel;
|
|
begin
|
|
if (Ctrl is TCPRSTemplateFieldLabel) and (not (Ctrl is TCPRSDialogHyperlinkLabel)) then
|
|
begin
|
|
lbl := Ctrl as TCPRSTemplateFieldLabel;
|
|
if trim(lbl.Caption) <> '' then
|
|
begin
|
|
ScreenReaderSystem_CurrentLabel(lbl);
|
|
ScreenReaderSystem_AddText(lbl.Caption);
|
|
end
|
|
else
|
|
begin
|
|
lbl.TabStop := FALSE;
|
|
ScreenReaderSystem_Stop;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if ctrl is TWinControl then
|
|
Add2TabOrder(TWinControl(ctrl));
|
|
if Supports(ctrl, ICPRSDialogComponent) then
|
|
ScreenReaderSystem_CurrentComponent(ctrl as ICPRSDialogComponent);
|
|
end;
|
|
sLbl := nil;
|
|
nLbl := nil;
|
|
end;
|
|
|
|
procedure NextLine;
|
|
begin
|
|
if(MaxX < x) then
|
|
MaxX := x;
|
|
x := FOCUS_RECT_MARGIN; {leave two pixels on the left for the Focus Rect}
|
|
inc(y, yinc);
|
|
yinc := ybase;
|
|
end;
|
|
|
|
begin
|
|
MaxTextLen := MaxLen - (FOCUS_RECT_MARGIN * 2);{save room for the focus rectangle on the panel}
|
|
if(FFirstBuild or (FPanel.Width <> MaxLen)) then
|
|
begin
|
|
Init;
|
|
for i := 0 to FControls.Count-1 do
|
|
begin
|
|
txt := FControls[i];
|
|
if ScreenReaderSystemActive then
|
|
Text508Work;
|
|
if StripCode(txt,EOL_MARKER) then
|
|
begin
|
|
if((x <> 0) or LastLineBlank) then
|
|
NextLine;
|
|
LastLineBlank := (txt = '');
|
|
end;
|
|
if(txt <> '') then
|
|
begin
|
|
while(txt <> '') do
|
|
begin
|
|
cnt := NumCharsFitInWidth(FFont.Handle, txt, MaxTextLen-x);
|
|
MaxChars := cnt;
|
|
if(cnt >= length(txt)) then
|
|
begin
|
|
DoLabel(txt);
|
|
txt := '';
|
|
end
|
|
else
|
|
if(cnt < 1) then
|
|
NextLine
|
|
else
|
|
begin
|
|
repeat
|
|
if(txt[cnt+1] = ' ') then
|
|
begin
|
|
DoLabel(copy(txt,1,cnt));
|
|
NextLine;
|
|
txt := copy(txt, cnt + 1, MaxInt);
|
|
break;
|
|
end
|
|
else
|
|
dec(cnt);
|
|
until(cnt = 0);
|
|
if(cnt = 0) then
|
|
begin
|
|
if(x = FOCUS_RECT_MARGIN) then {If x is at the far left margin...}
|
|
begin
|
|
DoLabel(Copy(txt,1,MaxChars));
|
|
NextLine;
|
|
txt := copy(txt, MaxChars + 1, MaxInt);
|
|
end
|
|
else
|
|
NextLine;
|
|
end;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
ctrl := TControl(FControls.Objects[i]);
|
|
if(assigned(ctrl)) then
|
|
begin
|
|
if ScreenReaderSystemActive then
|
|
Ctrl508Work(ctrl);
|
|
idx := FIndents.IndexOfObject(Ctrl);
|
|
if idx >= 0 then
|
|
ind := StrToIntDef(Piece(FIndents[idx], U, 1), 0)
|
|
else
|
|
ind := 0;
|
|
if(x > 0) then
|
|
begin
|
|
if (x < MaxLen) and (Ctrl is TORCheckBox) and (TORCheckBox(Ctrl).StringData = NewLine) then
|
|
x := MaxLen;
|
|
if((ctrl.Width + x + ind) > MaxLen) then
|
|
NextLine;
|
|
end;
|
|
inc(x,ind);
|
|
Ctrl.Left := x;
|
|
Ctrl.Top := y;
|
|
inc(x, Ctrl.Width + 4);
|
|
if yinc <= Ctrl.Height then
|
|
yinc := Ctrl.Height + 2;
|
|
if (x < MaxLen) and ((Ctrl is TRichEdit) or
|
|
((Ctrl is TLabel) and (pos(CRLF, TLabel(Ctrl).Caption) > 0))) then
|
|
x := MaxLen;
|
|
end;
|
|
end;
|
|
end;
|
|
NextLine;
|
|
FPanel.Height := (y-1) + (FOCUS_RECT_MARGIN * 2); //AGP added Focus_rect_margin for Reminder spacing
|
|
FPanel.Width := MaxX + FOCUS_RECT_MARGIN;
|
|
end;
|
|
if(FFieldValues <> '') then
|
|
SetFieldValues(FFieldValues);
|
|
if ScreenReaderSystemActive then
|
|
ScreenReaderSystem_Stop;
|
|
Result := FPanel;
|
|
end;
|
|
|
|
function TTemplateDialogEntry.GetText: string;
|
|
begin
|
|
Result := ResolveTemplateFields(FText, FALSE);
|
|
end;
|
|
|
|
procedure TTemplateDialogEntry.KillLabels;
|
|
var
|
|
i, idx: integer;
|
|
obj: TObject;
|
|
max: integer;
|
|
|
|
begin
|
|
if(assigned(FPanel)) then
|
|
begin
|
|
max := FPanel.ControlCount-1;
|
|
for i := max downto 0 do
|
|
begin
|
|
// deleting TVA508StaticText can delete several TVA508ChainedLabel components
|
|
if i < FPanel.ControlCount then
|
|
begin
|
|
obj := FPanel.Controls[i];
|
|
if (not (obj is TVA508ChainedLabel)) and
|
|
((obj is TLabel) or (obj is TVA508StaticText)) then
|
|
begin
|
|
idx := FControls.IndexOfObject(obj);
|
|
if idx < 0 then
|
|
obj.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TTemplateDialogEntry.SetAutoDestroyOnPanelFree(
|
|
const Value: boolean);
|
|
var
|
|
M: TMethod;
|
|
|
|
begin
|
|
FAutoDestroyOnPanelFree := Value;
|
|
if(Value) then
|
|
begin
|
|
M.Data := Self;
|
|
M.Code := @PanelDestroy;
|
|
FPanel.OnDestroy := TNotifyEvent(M);
|
|
end
|
|
else
|
|
FPanel.OnDestroy := nil;
|
|
end;
|
|
|
|
procedure TTemplateDialogEntry.SetControlText(CtrlID: integer; AText: string);
|
|
var
|
|
cnt, i, j: integer;
|
|
Ctrl: TControl;
|
|
Done: boolean;
|
|
|
|
begin
|
|
FUpdating := TRUE;
|
|
try
|
|
Done := FALSE;
|
|
cnt := 0;
|
|
for i := 0 to FControls.Count-1 do
|
|
begin
|
|
Ctrl := TControl(FControls.Objects[i]);
|
|
if(assigned(Ctrl)) and (Ctrl.Tag = CtrlID) then
|
|
begin
|
|
Done := TRUE;
|
|
if(Ctrl is TLabel) then
|
|
TLabel(Ctrl).Caption := AText
|
|
else
|
|
if(Ctrl is TEdit) then
|
|
TEdit(Ctrl).Text := AText
|
|
else
|
|
if(Ctrl is TORComboBox) then
|
|
TORComboBox(Ctrl).SelectByID(AText)
|
|
else
|
|
if(Ctrl is TRichEdit) then
|
|
TRichEdit(Ctrl).Lines.Text := AText
|
|
else
|
|
if(Ctrl is TORDateCombo) then
|
|
TORDateCombo(Ctrl).FMDate := MakeFMDateTime(piece(AText,':',2))
|
|
else
|
|
if(Ctrl is TORDateBox) then
|
|
TORDateBox(Ctrl).Text := AText
|
|
else
|
|
if(Ctrl is TORCheckBox) then
|
|
begin
|
|
Done := FALSE;
|
|
TORCheckBox(Ctrl).Checked := FALSE; //<-PSI-06-170-ADDED THIS LINE - v27.23 - RV
|
|
if(cnt = 0) then
|
|
cnt := DelimCount(AText, '|') + 1;
|
|
for j := 1 to cnt do
|
|
begin
|
|
if(TORCheckBox(Ctrl).Caption = piece(AText,'|',j)) then
|
|
TORCheckBox(Ctrl).Checked := TRUE;
|
|
end;
|
|
end
|
|
else
|
|
if(Ctrl is TfraTemplateFieldButton) then
|
|
TfraTemplateFieldButton(Ctrl).ButtonText := AText
|
|
else
|
|
if(Ctrl is TPanel) then
|
|
begin
|
|
for j := 0 to Ctrl.ComponentCount-1 do
|
|
if Ctrl.Components[j] is TUpDown then
|
|
begin
|
|
TUpDown(Ctrl.Components[j]).Position := StrToIntDef(AText,0);
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
if Done then break;
|
|
end;
|
|
finally
|
|
FUpdating := FALSE;
|
|
end;
|
|
end;
|
|
|
|
procedure TTemplateDialogEntry.SetFieldValues(const Value: string);
|
|
var
|
|
i: integer;
|
|
TmpSL: TStringList;
|
|
|
|
begin
|
|
FFieldValues := Value;
|
|
TmpSL := TStringList.Create;
|
|
try
|
|
TmpSL.CommaText := Value;
|
|
for i := 0 to TmpSL.Count-1 do
|
|
SetControlText(StrToIntDef(Piece(TmpSL[i], U, 1), 0), Piece(TmpSL[i], U, 2));
|
|
finally
|
|
TmpSL.Free;
|
|
end;
|
|
end;
|
|
|
|
function TTemplateDialogEntry.StripCode(var txt: string; code: char): boolean;
|
|
var
|
|
p: integer;
|
|
begin
|
|
p := pos(code, txt);
|
|
Result := (p > 0);
|
|
if Result then
|
|
begin
|
|
while p > 0 do
|
|
begin
|
|
delete(txt, p, 1);
|
|
p := pos(code, txt);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TTemplateDialogEntry.UpDownChange(Sender: TObject);
|
|
begin
|
|
EnsureText(TEdit(Sender), TUpDown(TEdit(Sender).Tag));
|
|
DoChange(Sender);
|
|
end;
|
|
|
|
function StripEmbedded(iItems: string): string;
|
|
{7/26/01 S Monson
|
|
Returns the field will all embedded fields removed}
|
|
var
|
|
p1, p2, icur: integer;
|
|
Begin
|
|
p1 := pos(TemplateFieldBeginSignature,iItems);
|
|
icur := 0;
|
|
while p1 > 0 do
|
|
begin
|
|
p2 := pos(TemplateFieldEndSignature,copy(iItems,icur+p1+TemplateFieldSignatureLen,maxint));
|
|
if p2 > 0 then
|
|
begin
|
|
delete(iItems,p1+icur,TemplateFieldSignatureLen+p2+TemplateFieldSignatureEndLen-1);
|
|
icur := icur + p1 - 1;
|
|
p1 := pos(TemplateFieldBeginSignature,copy(iItems,icur+1,maxint));
|
|
end
|
|
else
|
|
p1 := 0;
|
|
end;
|
|
Result := iItems;
|
|
end;
|
|
|
|
procedure StripScreenReaderCodes(var Text: string);
|
|
var
|
|
p, j: integer;
|
|
begin
|
|
for j := low(ScreenReaderCodes) to high(ScreenReaderCodes) do
|
|
begin
|
|
p := 1;
|
|
while (p > 0) do
|
|
begin
|
|
p := posex(ScreenReaderCodes[j], Text, p);
|
|
if p > 0 then
|
|
delete(Text, p, ScreenReaderCodeLens[j]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure StripScreenReaderCodes(SL: TStrings);
|
|
var
|
|
temp: string;
|
|
i: integer;
|
|
|
|
begin
|
|
for i := 0 to SL.Count - 1 do
|
|
begin
|
|
temp := SL[i];
|
|
StripScreenReaderCodes(temp);
|
|
SL[i] := temp;
|
|
end;
|
|
end;
|
|
|
|
function HasScreenReaderBreakCodes(SL: TStrings): boolean;
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
Result := TRUE;
|
|
for i := 0 to SL.Count - 1 do
|
|
begin
|
|
if pos(ScreenReaderCodeSignature, SL[i]) > 0 then
|
|
exit;
|
|
end;
|
|
Result := FALSE;
|
|
end;
|
|
|
|
initialization
|
|
|
|
finalization
|
|
KillObj(@uTmplFlds, TRUE);
|
|
KillObj(@uEntries, TRUE);
|
|
|
|
end.
|