unit uVA508CPRSCompatibility;

interface

uses
  SysUtils, Windows, Classes, Controls, Forms, StdCtrls;

procedure QuickCopyWith508Msg(AFrom, ATo: TObject; docType: string = '');
procedure QuickAddWith508Msg(AFrom, ATo: TObject; docType: string = '');
procedure FastAssignWith508Msg(source, destination: TStrings; docType: string = '');

procedure SpeakTextInserted(docType: string = '');
function GetTabText: string;
procedure SpeakPatient;
procedure SpeakTabAndPatient;

implementation

uses VA508AccessibilityRouter, VA508AccessibilityManager, ORFn, uDlgComponents,
  VA508DelphiCompatibility, ORCtrls, fReminderDialog, fTemplateDialog, fFrame,
  uCore, ORCtrlsVA508Compatibility, mTemplateFieldButton, VA508AccessibilityConst;

type
  TCPRSParentDialogCheckBox508Manager = class(TORCheckBox508Manager)
  public
    constructor Create; override;
    function GetCaption(Component: TWinControl): string; override;
  end;

  TCPRSBaseDialogComponent508Manager = class(TVA508ManagedComponentClass)
  public
    function GetCaption(Component: TWinControl): string; override;
  end;

{  TCPRSDialogStaticLabel508Manager = class(TVA508StaticTextManager)
  public
    constructor Create; override;
    function GetCaption(Component: TWinControl): string; override;
  end;
  }

  TCPRSDialogEdit508Manager = class(TCPRSBaseDialogComponent508Manager)
  public
    constructor Create; override;
  end;

  TCPRSDialogFieldComboBox508Manager = class(TCPRSBaseDialogComponent508Manager)
  public
    constructor Create; override;
  end;

  TCPRSDialogDateBox508Manager = class(TCPRSBaseDialogComponent508Manager)
  public
    constructor Create; override;
  end;

  TCPRSDialogCheckBox508Manager = class(TORCheckBox508Manager)
  public
    constructor Create; override;
    function GetCaption(Component: TWinControl): string; override;
  end;

  TCPRSDialogRichEdit508Manager = class(TCPRSBaseDialogComponent508Manager)
  public
    constructor Create; override;
  end;

  TCPRSDialogLabel508Manager = class(TCPRSBaseDialogComponent508Manager)
  public
    constructor Create; override;
    function GetValue(Component: TWinControl): string; override;
  end;

  TCPRSDialogHyperlink508Manager = class(TCPRSBaseDialogComponent508Manager)
  public
    constructor Create; override;
    function GetValue(Component: TWinControl): string; override;
    function GetInstructions(Component: TWinControl): string; override;
  end;

  TCPRSDialogNumberComplexManager = class(TVA508ComplexComponentManager)
  public
    constructor Create;
    procedure Refresh(Component: TWinControl;
                      AccessibilityManager: TVA508AccessibilityManager); override;
  end;

  TCPRSDialogYearEdit508Manager = class(TVA508ManagedComponentClass)
  public
    constructor Create; override;
    function Redirect(Component: TWinControl; var ManagedType: TManagedType): TWinControl; override;
  end;

  TCPRSNumberField508Manager = class(TVA508ManagedComponentClass)
  public
    constructor Create; override;
    function GetCaption(Component: TWinControl): string; override;
  end;

  TCPRSDialogDateCombo508Manager = class(TCPRSBaseDialogComponent508Manager)
  public
    constructor Create; override;
  end;

  TfraTemplateFieldButtonComplexManager = class(TVA508ComplexComponentManager)
  public
    constructor Create;
    procedure Refresh(Component: TWinControl;
                      AccessibilityManager: TVA508AccessibilityManager); override;
  end;

  TfraTemplateFieldButton508Manager = class(TVA508ManagedComponentClass)
  public
    constructor Create; override;
    function GetValue(Component: TWinControl): string; override;
    function GetCaption(Component: TWinControl): string; override;
    function GetComponentName(Component: TWinControl): string; override;
    function GetInstructions(Component: TWinControl): string; override;
  end;

  TMentalHealthMemo508Manager = class(TVA508ManagedComponentClass)
  public
    constructor Create; override;
    function GetComponentName(Component: TWinControl): string; override;
    function GetInstructions(Component: TWinControl): string; override;
  end;

procedure SpeakTextInserted(docType: string = '');
begin
  if docType = '' then
    GetScreenReader.Speak('text inserted')
  else
    GetScreenReader.Speak('text inserted in to ' + docType);
end;

procedure QuickCopyWith508Msg(AFrom, ATo: TObject; docType: string = '');
begin
  QuickCopy(AFrom, ATo);
  if (AFrom is TStrings) and (TStrings(AFrom).Count > 0) then
    SpeakTextInserted(docType);
end;

procedure QuickAddWith508Msg(AFrom, ATo: TObject; docType: string = '');
begin
  QuickAdd(AFrom, ATo);
  if (AFrom is TStrings) and (TStrings(AFrom).Count > 0) then
    SpeakTextInserted(docType);
end;

procedure FastAssignWith508Msg(source, destination: TStrings; docType: string = '');
begin
  FastAssign(source, destination);
  if source.Count > 0 then
    SpeakTextInserted(docType);
end;

procedure ControlShiftTOverride; forward;
procedure ControlTabOverride; forward;
procedure ControlShiftTabOverride; forward;

type
  TVA508RegistrationScreenReader = class(TVA508ScreenReader);

procedure Register508CompatibilityChanges;
begin
  with GetScreenReader do
  begin
    RegisterDictionaryChange('<unknown>','unknown');
    RegisterDictionaryChange('VistA','Vist a');
    RegisterDictionaryChange('VA','V A');
    RegisterDictionaryChange('VHA','V H A');
    RegisterDictionaryChange('HealtheVet','Health E Vet');
  end;
  RegisterManagedComponentClass(TCPRSParentDialogCheckBox508Manager.Create);
//  RegisterManagedComponentClass(TCPRSDialogStaticLabel508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogEdit508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogFieldComboBox508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogCheckBox508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogRichEdit508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogLabel508Manager.Create);
  RegisterManagedComponentClass(TCPRSNumberField508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogHyperlink508Manager.Create);
  RegisterManagedComponentClass(TfraTemplateFieldButton508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogDateBox508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogDateCombo508Manager.Create);
  RegisterManagedComponentClass(TCPRSDialogYearEdit508Manager.Create);
  RegisterManagedComponentClass(TMentalHealthMemo508Manager.Create);
  
  RegisterComplexComponentManager(TCPRSDialogNumberComplexManager.Create);

  GetScreenReader.RegisterCustomKeyMapping('Control+Tab', ControlTabOverride,
                'Advances to the next tab in a tab control',
                'advances to the next tab in a tab control, when you are inside a control with tabs');
  GetScreenReader.RegisterCustomKeyMapping('Control+Shift+Tab', ControlShiftTabOverride,
                'Advances to the previous tab in a tab control',
                'advances to the previous tab in a tab control, when you are inside a control with tabs');
  GetScreenReader.RegisterCustomKeyMapping('Control+Shift+T', ControlShiftTOverride,
                'Announces Chart Tab and Patient Name',
                'Announces the current CPRS Chart tab and the current patient');

  with TVA508RegistrationScreenReader(GetScreenReader) do
  begin
    RegisterCustomClassBehavior(TCPRSDialogParentCheckBox.ClassName, CLASS_BEHAVIOR_CHECK_BOX);
    RegisterCustomClassBehavior(TCPRSDialogCheckBox.ClassName, CLASS_BEHAVIOR_CHECK_BOX);
    RegisterCustomClassBehavior(TCPRSDialogRichEdit.ClassName, CLASS_BEHAVIOR_EDIT);
    RegisterCustomClassBehavior(TCPRSDialogFieldEdit.ClassName, CLASS_BEHAVIOR_EDIT);
    RegisterCustomClassBehavior(TCPRSDialogComboBox.ClassName, CLASS_BEHAVIOR_EDIT_COMBO);
    RegisterCustomClassBehavior(TCPRSDialogButton.ClassName, CLASS_BEHAVIOR_BUTTON);
    RegisterCustomClassBehavior(TCPRSDialogDateBox.ClassName, CLASS_BEHAVIOR_EDIT);
    RegisterCustomClassBehavior(TCPRSDialogNumber.ClassName, CLASS_BEHAVIOR_EDIT);
    RegisterCustomClassBehavior(TCPRSNumberField.ClassName, CLASS_BEHAVIOR_EDIT);
  end;

end;

{ TCPRSDialogCheckBox }

constructor TCPRSParentDialogCheckBox508Manager.Create;
begin
  inherited Create(TCPRSDialogParentCheckBox, [mtCaption, mtComponentName, mtInstructions, mtState, mtStateChange]);
end;

function TCPRSParentDialogCheckBox508Manager.GetCaption(Component: TWinControl): string;
begin
  Result := TCPRSDialogParentCheckBox(Component).AccessText;
end;

type
  ExposedControl = class(TWinControl);

// CQ #14984
procedure ControlTabOverride;
begin
  if assigned(Screen.ActiveControl) and (Screen.ActiveControl is TCustomMemo) then
    ExposedControl(Screen.FocusedForm).SelectNext(Screen.ActiveControl, TRUE, TRUE)
  else
  begin
    keybd_event(VK_TAB, 0, 0, VK_CONTROL);
    keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, VK_CONTROL);
  end;
end;

procedure ControlShiftTabOverride;
begin
  if assigned(Screen.ActiveControl) and (Screen.ActiveControl is TCustomMemo) then
    ExposedControl(Screen.FocusedForm).SelectNext(Screen.ActiveControl, FALSE, TRUE)
  else
  begin
    keybd_event(VK_TAB, 0, 0, (VK_SHIFT * 256) + VK_CONTROL);
    keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, (VK_SHIFT * 256) + VK_CONTROL);
  end;
end;

procedure ControlShiftTOverride;
begin
  SpeakTabAndPatient;
end;

function GetTabText: string;
var
  idx: integer;
begin
  Result := '';
  if assigned(frmFrame) and assigned(frmFrame.tabPage) then
  begin
    idx := frmFrame.tabPage.TabIndex;
    if (idx >= 0) and (idx < uTabList.Count) then
    begin
      Result := frmFrame.tabPage.Tabs[idx];
      if Result = 'D/C Summ' then
        Result := 'Discharge Summary';
    end;
  end;
end;

procedure SpeakPatient;
begin
  //CQ #17491: Associating 508 change that allows JAWS to dictate the patient status indicator along with the name.
  if assigned(Patient) and (Patient.Name <> '') and (Patient.Status <> '') then
    GetScreenReader.Speak(Patient.Name + Patient.Status);
end;

procedure SpeakTabAndPatient;
var
  text: string;
begin
  text := GetTabText;
  if text <> '' then
    text := text + ' tab';
  if text <> '' then
    text := text + ', ';
  //CQ #17491: Associating 508 change that allows JAWS to dictate the patient status indicator along with the name.
  if assigned(Patient) and (Patient.Name <> '') and (Patient.Status <> '') then
    text := text + Patient.Name + Patient.Status
  else
    text := text + 'no patient selected';
  if text <> '' then
    GetScreenReader.Speak(text);
end;

{ TCPRSDialogComponent508Manager }

function TCPRSBaseDialogComponent508Manager.GetCaption(
  Component: TWinControl): string;
begin
  if Supports(Component, ICPRSDialogComponent) then
  begin
    Result := (Component as ICPRSDialogComponent).AccessText;
  end
  else
    Result := '';
end;

(*
{ TCPRSDialogStaticLabel508Manager }

constructor TCPRSDialogStaticLabel508Manager.Create;
begin
  inherited Create(TCPRSDialogStaticLabel, [mtCaption]);
end;

function TCPRSDialogStaticLabel508Manager.GetCaption(
  Component: TWinControl): string;
var
  txt: string;
begin
  if Supports(Component, ICPRSDialogComponent) then
  begin
    Result := (Component as ICPRSDialogComponent).AccessText;
  end
  else
    Result := '';
  txt := inherited GetCaption(Component);
  if txt <> '' then
  begin
    if Result <> '' then
      Result := Result + ' ';
    Result := Result + txt;
  end;
end;
*)

{ TCPRSTemplateFieldEdit508Manager }

constructor TCPRSDialogEdit508Manager.Create;
begin
  inherited Create(TCPRSDialogFieldEdit, [mtCaption]);
end;

{ TCPRSTemplateFieldComboBox508Manager }

constructor TCPRSDialogFieldComboBox508Manager.Create;
begin
  inherited Create(TCPRSDialogComboBox, [mtCaption]);
end;

{ TCPRSTemplateFieldCheckBox508Manager }

constructor TCPRSDialogCheckBox508Manager.Create;
begin
  inherited Create(TCPRSDialogCheckBox, [mtCaption, mtComponentName, mtInstructions, mtState, mtStateChange]);
end;

function TCPRSDialogCheckBox508Manager.GetCaption(
  Component: TWinControl): string;
begin
  if Supports(Component, ICPRSDialogComponent) then
  begin
    Result := (Component as ICPRSDialogComponent).AccessText;
  end
  else
    Result := '';
  Result := Result + ' ' + TCheckBox(Component).Caption;
end;

{ TCPRSTemplateFieldRichEdit508Manager }

constructor TCPRSDialogRichEdit508Manager.Create;
begin
  inherited Create(TCPRSDialogRichEdit, [mtCaption]);
end;

{ TCPRSTemplateFieldDateCombo508Manager }

constructor TCPRSDialogLabel508Manager.Create;
begin
  inherited Create(TCPRSTemplateFieldLabel, [mtCaption, mtValue]);
end;

function TCPRSDialogLabel508Manager.GetValue(
  Component: TWinControl): string;
begin
  Result := TCPRSTemplateFieldLabel(Component).Caption;
end;

{ TCPRSTemplateFieldWebLabel508Manager }

constructor TCPRSDialogHyperlink508Manager.Create;
begin
  inherited Create(TCPRSDialogHyperlinkLabel, [mtCaption, mtValue, mtInstructions]);
end;

function TCPRSDialogHyperlink508Manager.GetInstructions(
  Component: TWinControl): string;
begin
  Result := 'To activate press space bar';
end;

function TCPRSDialogHyperlink508Manager.GetValue(
  Component: TWinControl): string;
begin
  Result := TCPRSDialogHyperlinkLabel(Component).Caption;
end;

{ TCPRSTemplateFieldNumberComplexManager }

constructor TCPRSDialogNumberComplexManager.Create;
begin
  inherited Create(TCPRSDialogNumber);
end;

procedure TCPRSDialogNumberComplexManager.Refresh(Component: TWinControl;
  AccessibilityManager: TVA508AccessibilityManager);
begin
  with TCPRSDialogNumber(Component) do
  begin
    ClearSubControls(Component);
    if assigned(Edit) then
      AddSubControl(Component, Edit, AccessibilityManager);
  end;
end;

{ TCPRSNumberField508Manager }

constructor TCPRSNumberField508Manager.Create;
begin
  inherited Create(TCPRSNumberField, [mtCaption]);
end;

function TCPRSNumberField508Manager.GetCaption(Component: TWinControl): string;
begin
  if assigned(Component.Owner) and Supports(Component.Owner, ICPRSDialogComponent) then
  begin
    Result := (Component.Owner as ICPRSDialogComponent).AccessText;
  end
  else
    Result := '';
end;

{ TfraTemplateFieldButtonComplexManager }

constructor TfraTemplateFieldButtonComplexManager.Create;
begin
  inherited Create(TfraTemplateFieldButton);
end;

procedure TfraTemplateFieldButtonComplexManager.Refresh(Component: TWinControl;
  AccessibilityManager: TVA508AccessibilityManager);
begin
  with TfraTemplateFieldButton(Component) do
  begin
    ClearSubControls(Component);
    AddSubControl(Component, pnlBtn, AccessibilityManager);
  end;
end;

{ TfraTemplateFieldButton508Manager }

constructor TfraTemplateFieldButton508Manager.Create;
begin
  inherited Create(TfraTemplateFieldButton, [mtComponentName, mtCaption, mtInstructions, mtValue]);
end;

function TfraTemplateFieldButton508Manager.GetCaption(
  Component: TWinControl): string;
begin
  if assigned(Component) and Supports(Component, ICPRSDialogComponent) then
  begin
    Result := (Component as ICPRSDialogComponent).AccessText;
  end
  else
    Result := '';
end;

function TfraTemplateFieldButton508Manager.GetComponentName(
  Component: TWinControl): string;
begin
  Result := 'multi value button';
end;

function TfraTemplateFieldButton508Manager.GetInstructions(
  Component: TWinControl): string;
begin
  Result := 'to cycle through values press space bar';
end;

function TfraTemplateFieldButton508Manager.GetValue(
  Component: TWinControl): string;
begin
  Result := TfraTemplateFieldButton(Component).ButtonText;
  if Trim(Result) = '' then
    Result := 'blank';
end;

{ TCPRSTemplateFieldDateBox508Manager }

constructor TCPRSDialogDateBox508Manager.Create;
begin
  inherited Create(TCPRSDialogDateBox, [mtCaption]);
end;

{ TCPRSDialogYearEdit508Manager }

constructor TCPRSDialogYearEdit508Manager.Create;
begin
  inherited Create(TCPRSDialogYearEdit, [mtComponentRedirect]);
end;

function TCPRSDialogYearEdit508Manager.Redirect(Component: TWinControl;
  var ManagedType: TManagedType): TWinControl;
begin
  ManagedType := mtCaption;
  Result := TWinControl(Component.Owner);
end;

{ TCPRSDialogDateCombo508Manager }

constructor TCPRSDialogDateCombo508Manager.Create;
begin
  inherited Create(TCPRSDialogDateCombo, [mtCaption]);
end;

{ TMentalHealthMemo508Manager }

constructor TMentalHealthMemo508Manager.Create;
begin
  inherited Create(TMentalHealthMemo, [mtComponentName, mtInstructions]);
end;

function TMentalHealthMemo508Manager.GetComponentName(
  Component: TWinControl): string;
begin
  Result := ' ';
end;

function TMentalHealthMemo508Manager.GetInstructions(
  Component: TWinControl): string;
begin
  Result := ' ';
end;

initialization
  Register508CompatibilityChanges;


end.
