unit VA508AccessibilityManagerEditor;

interface

uses
  Winapi.Windows, Winapi.Messages, SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.CheckLst, Vcl.ImgList, Vcl.ComCtrls,
  Vcl.ToolWin,
  Vcl.StdCtrls, Vcl.ExtCtrls, VA508AccessibilityManager, ColnEdit,
  Vcl.Menus, Generics.Collections, 
  VAShared.UTStringsHelper;

type
  /// <summary>Dictates how the list view should be sorted</summary>
  /// <param name="stName">Sort by name</param>
  /// <param name="stType">Sort by type</param>
  tSortType = (stName, stType);
  
  Tva508CollectionEditor = class(TForm)
    pnlLeft: TPanel;
    pnlRight: TPanel;
    splMain: TSplitter;
    chkDefault: TCheckBox;
    cmbAccessLbl: TComboBox;
    cmbAccessProp: TComboBox;
    memAccessTxt: TMemo;
    lbCtrllList: TLabel;
    lblAccLbl: TLabel;
    lblAccProp: TLabel;
    lnlAccTxt: TLabel;
    pnlLstView: TPanel;
    lblAccColumns: TLabel;
    lstCtrls: TListView;
    StatusBar1: TStatusBar;
    lblHeader: TLabel;
    MainMenu1: TMainMenu;
    mnuMain: TMenuItem;
    mnuRefreshAll: TMenuItem;
    mnuView: TMenuItem;
    mnuOrderByName: TMenuItem;
    mnuOrderbyType: TMenuItem;
    chkIgnoreWatch: TCheckBox;
    gpWatchEnable: TGroupBox;
    chkWatchEnable: TCheckBox;
    bgScreenReaderSettings: TGroupBox;
    lvAccessCol: TListView;
    memCustomText: TMemo;
    cbCustomText: TGroupBox;
    pnlHeaders: TPanel;
    rgColHeaders: TRadioGroup;
    procedure lstCtrlsSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure memAccessTxtChange(Sender: TObject);
    procedure cmbAccessLblChange(Sender: TObject);
    procedure cmbAccessPropChange(Sender: TObject);
    procedure chkDefaultClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure mnuRefreshAllClick(Sender: TObject);
    procedure mnuOrderByNameClick(Sender: TObject);
    procedure mnuOrderbyTypeClick(Sender: TObject);
    procedure lstCtrlsCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    procedure chkWatchEnableClick(Sender: TObject);
    procedure chkIgnoreWatchClick(Sender: TObject);
    procedure lvAccessColItemChecked(Sender: TObject; Item: TListItem);
    procedure rgColHeadersClick(Sender: TObject);
    procedure memCustomTextExit(Sender: TObject);
    procedure lvAccessColSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
  private
    { Private declarations }
    fInternal: Boolean;
    fCollection: TVA508AccessibilityCollection;
    fOwnerCtrl: TVA508AccessibilityManager;
    fOldHint: TNotifyEvent;
    fSortType: tSortType;
    fOrigCollection: TVA508AccessibilityCollection;
    procedure MyHint(Sender: TObject);
    procedure ClearAll;
    Function GetAccessItem: TVA508AccessibilityItem;
    procedure SetAccessData(Sender: TObject; AccessItem: TVA508AccessibilityItem);
    procedure ClearControl(aObj: TObject; aEvent: String; AccessItem: TVA508AccessibilityItem);
    /// <summary>Determains if the properties of any access control were modified</summary>
    /// <returns>Boolean</returns>
    function WasControlUpdated: Boolean;
    procedure CheckForDisabled;
    procedure ClearColumnSettings;
  public
    { Public declarations }
    procedure FillOutList(aCollection: TVA508AccessibilityCollection;
      aOwnerCtrl: TVA508AccessibilityManager);
      Property Modified: Boolean read WasControlUpdated;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

uses System.TypInfo, VAUtils, ToolsAPI, VA508AccessibilityDisableCheck,
  VAHelpers;

const
  HeaderTxt = 'Settings for %s';

  //Header info
  HI_JAWS = 'Use Jaws Settings';
  HI_IGNORE = 'Ignore Header';
  HI_HEADER = 'Say Header';
  HI_SAY = 'Say';
  HI_NOTHING = 'Say Nothing';
{$R *.dfm}

procedure Tva508CollectionEditor.MyHint(Sender: TObject);
begin
  StatusBar1.SimpleText := Application.Hint;
end;

procedure Tva508CollectionEditor.RgColHeadersClick(Sender: TObject);
var
  AccessItem: TVA508AccessibilityItem;
  TmpObj: TColumnList;
  I: Integer;
  LItem: TListItem;
  S: string;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
  begin
    TmpObj := AccessItem.AccessColumns;
    case RgColHeaders.ItemIndex of
      0:
        TmpObj.ReadColumnHeader := ColUseJaws;
      1:
        TmpObj.ReadColumnHeader := ColIgnore;
      2:
        TmpObj.ReadColumnHeader := ColCustomOrHeader;
      3:
        TmpObj.ReadColumnHeader := ColCustomAndHeader;
      4:
        TmpObj.ReadColumnHeader := ColCustom;
    end;
    if (Sender = MemCustomText) or (Sender = lvAccessCol) then
    begin
      LItem := LvAccessCol.Items[LvAccessCol.ItemIndex];
      If TmpObj.ReadColumnValue[LvAccessCol.ItemIndex] then
      begin
        S := TmpObj.ColumnHeaderCustomText[LvAccessCol.ItemIndex];
        case RgColHeaders.ItemIndex of
          0:
            LItem.SubItems[2] := HI_JAWS;
          1:
            LItem.SubItems[2] := HI_IGNORE;
          2:
            begin
              if Trim(S) <> '' then
                LItem.SubItems[2] := HI_SAY + ' ' + S
              else
                LItem.SubItems[2] := HI_HEADER;
            end;
          3:
            begin
              if Trim(S) <> '' then
                LItem.SubItems[2] := HI_HEADER + ' AND ' + S
              else
                LItem.SubItems[2] := HI_HEADER;
            end;
          4:
            begin
              if Trim(S) <> '' then
                LItem.SubItems[2] := HI_SAY + ' ' + S
              else
                LItem.SubItems[2] := HI_NOTHING;
            end;
        end;
      end else
        LItem.SubItems[2] := HI_NOTHING;
    end
    else
    begin
      for I := 0 to LvAccessCol.Items.Count - 1 do
      begin
        LItem := LvAccessCol.Items[I];
        If TmpObj.ReadColumnValue[I] then
        begin
          S := TmpObj.ColumnHeaderCustomText[I];
          case RgColHeaders.ItemIndex of
            0:
              LItem.SubItems[2] := HI_JAWS;
            1:
              LItem.SubItems[2] := HI_IGNORE;
            2:
              begin
                if Trim(S) <> '' then
                  LItem.SubItems[2] := HI_SAY + ' ' + S
                else
                  LItem.SubItems[2] := HI_HEADER;
              end;
            3:
              begin
                if Trim(S) <> '' then
                  LItem.SubItems[2] := HI_HEADER + ' AND ' + S
                else
                  LItem.SubItems[2] := HI_HEADER;
              end;
            4:
              begin
                if Trim(S) <> '' then
                  LItem.SubItems[2] := HI_SAY + ' ' + S
                else
                  LItem.SubItems[2] := HI_NOTHING;
              end;
          end;
        end else
         LItem.SubItems[2] := HI_NOTHING;
      end;
    end;
  end;
end;

procedure Tva508CollectionEditor.mnuOrderByNameClick(Sender: TObject);
begin
  if not assigned(Sender) then
    exit;
  lstCtrls.SortType := stText;
  fSortType := stName;
  lstCtrls.AlphaSort;
end;

procedure Tva508CollectionEditor.mnuOrderbyTypeClick(Sender: TObject);
begin
  if not assigned(Sender) then
    exit;
  lstCtrls.SortType := stText;
  fSortType := stType;
  lstCtrls.AlphaSort;
end;

procedure Tva508CollectionEditor.mnuRefreshAllClick(Sender: TObject);
begin
 fOwnerCtrl.RefreshComponents;
 FillOutList(fCollection, fOwnerCtrl);
end;

Function Tva508CollectionEditor.GetAccessItem: TVA508AccessibilityItem;
begin
  Result := nil;
  if lstCtrls.ItemIndex > -1 then
    Result := TVA508AccessibilityItem(lstCtrls.Items[lstCtrls.ItemIndex].Data);
end;

procedure Tva508CollectionEditor.chkIgnoreWatchClick(Sender: TObject);
var
  AccessItem: TVA508AccessibilityItem;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
    SetAccessData(chkIgnoreWatch, AccessItem);
  If chkWatchEnable.Checked and chkIgnoreWatch.Checked then
    chkWatchEnable.Checked := false;
end;

procedure Tva508CollectionEditor.chkWatchEnableClick(Sender: TObject);
var
  AccessItem: TVA508AccessibilityItem;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
    SetAccessData(chkWatchEnable, AccessItem);
  If chkIgnoreWatch.Checked and chkWatchEnable.Checked then
    chkIgnoreWatch.Checked := false;
end;

procedure Tva508CollectionEditor.ClearAll;
begin
  lblHeader.Caption := '';

  ClearControl(chkDefault, 'OnClick', nil);
  ClearControl(chkWatchEnable, 'OnClick', nil);
  ClearControl(cmbAccessLbl, 'OnChange', nil);
  ClearControl(cmbAccessProp, 'OnChange', nil);
  ClearControl(memAccessTxt, 'OnChange', nil);

  pnlLstView.Visible := false;
  ClearColumnSettings;
end;

procedure Tva508CollectionEditor.lstCtrlsCompare(Sender: TObject; Item1,
  Item2: TListItem; Data: Integer; var Compare: Integer);
begin
  case fSortType of
    stName: Compare := CompareText(Item1.Caption, Item2.Caption);
    stType: Compare := CompareText(Piece(Item1.Caption, '(', 2), Piece(Item2.Caption, '(', 2));
  end;
end;

type
  TItemCheckedEvent = procedure(Sender: TObject; Item: TListItem) of object;

procedure Tva508CollectionEditor.LstCtrlsSelectItem(Sender: TObject;
  Item: TListItem; Selected: Boolean);

procedure AutoSizeView(View: TListView);
var
 i, x, tmpWidth, setColWidth: integer;
begin
 View.Columns.BeginUpdate;
 try
    //Ignore column 1
    For i := 1 to View.Columns.Count - 1 do
    begin
      setColWidth := -2;
      For x := 1 to View.Items.Count -1 do
      begin
        tmpWidth := self.Canvas.Textwidth(view.Items[x].SubItems[i-1]);

        If self.Canvas.Textwidth(view.Columns[i].Caption) < tmpWidth then
        begin
          setColWidth := -1;
          break;
        end;
      end;

      view.Columns[i].Width := setColWidth;
    end;
 finally
  View.Columns.EndUpdate;
 end;


end;

var
  EdtItem: TVA508AccessibilityItem;
  I: Integer;
  TmpObj: TColumnList;
  LItem: TListItem;
  ItemCheckedEvt: TItemCheckedEvent;
begin
  if (not Assigned(Item.Data)) or (not Selected) then
    Exit;

  ClearAll;
  EdtItem := Item.Data;

  FOwnerCtrl.GetProperties(EdtItem.Component, CmbAccessProp.Items);

  // Fill out the fields
  ChkDefault.Checked := EdtItem.UseDefault;

  ChkWatchEnable.Checked := EdtItem.WatchEnable;
  ChkIgnoreWatch.Checked := EdtItem.IgnoreEnabled;

  LblHeader.Caption := Format(HeaderTxt, [EdtItem.DisplayName]);

  if Assigned(EdtItem.AccessLabel) then
    CmbAccessLbl.ItemIndex := CmbAccessLbl.Items.IndexOfPiece
      (EdtItem.AccessLabel.Name, '=', 1);

  CmbAccessProp.ItemIndex := CmbAccessProp.Items.IndexOf
    (EdtItem.AccessProperty);

  MemAccessTxt.Text := EdtItem.AccessText;

  if EdtItem.Component is TListView then
  begin
    PnlLstView.Visible := True;
    // Build the list

    TmpObj := EdtItem.AccessColumns;
    if Assigned(TmpObj) then
    begin
      LvAccessCol.Items.BeginUpdate;
      ItemCheckedEvt := LvAccessCol.OnItemChecked;
      LvAccessCol.OnItemChecked := nil;
      try
        for I := 0 to TListView(EdtItem.Component).Columns.Count - 1 do
        begin

          LItem := LvAccessCol.Items.Add;

          LItem.Checked := TmpObj.ReadColumnValue[I];
          LItem.Caption := '';
          LItem.SubItems.Add(TListView(EdtItem.Component).Column[I].Caption);
          if LItem.Checked then
            LItem.SubItems.Add('Read Column')
          else
            LItem.SubItems.Add('Ignore Column');

          LItem.SubItems.Add('');

        end;

         case TmpObj.ReadColumnHeader of
            ColUseJaws:
              RgColHeaders.ItemIndex := 0;
            ColIgnore:
              RgColHeaders.ItemIndex := 1;
            ColCustomOrHeader:
              RgColHeaders.ItemIndex := 2;
            ColCustomAndHeader:
              RgColHeaders.ItemIndex := 3;
            ColCustom:
              RgColHeaders.ItemIndex := 4;
          end;

      finally
        LvAccessCol.OnItemChecked := ItemCheckedEvt;
        LvAccessCol.Items.EndUpdate;
        AutoSizeView(LvAccessCol);
      end;
    end;

  end;

end;

procedure Tva508CollectionEditor.LvAccessColItemChecked(Sender: TObject;
  Item: TListItem);
var
  AccessItem: TVA508AccessibilityItem;
  TmpObj: TColumnList;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
  begin
    TmpObj := AccessItem.AccessColumns;
    TmpObj.ReadColumnValue[Item.Index] := Item.Checked;

    if Item.Checked then
      Item.SubItems[1] := 'Read Column'
    else
      Item.SubItems[1] := 'Ignore Column';

    RgColHeadersClick(self);
  end;
end;

procedure Tva508CollectionEditor.LvAccessColSelectItem(Sender: TObject;
  Item: TListItem; Selected: Boolean);
var
  AccessItem: TVA508AccessibilityItem;
  TmpObj: TColumnList;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
  begin
    TmpObj := AccessItem.AccessColumns;
    MemCustomText.Text:= TmpObj.ColumnHeaderCustomText[LvAccessCol.ItemIndex];
  end;
end;

procedure Tva508CollectionEditor.ClearColumnSettings;
begin
  lvAccessCol.Clear;
  rgColHeaders.ItemIndex := -1;
  memCustomText.Clear;
end;

procedure Tva508CollectionEditor.ClearControl(aObj: TObject; aEvent: String; AccessItem: TVA508AccessibilityItem);
 const
   NILEvnt: TMethod = (Code: NIL; Data: NIL);
 var
  fMethodHwnd: TMethod;
 begin
  fMethodHwnd := GetMethodProp(aObj, aEvent);
  SetMethodProp(aObj, aEvent, NILEvnt);
  try
   if aObj = chkDefault then
   begin
    chkDefault.Checked := false;
    if Assigned(AccessItem) then
      AccessItem.UseDefault := false;
   end;
   if aObj = cmbAccessLbl then
   begin
    cmbAccessLbl.ItemIndex := -1;
    if Assigned(AccessItem) then
      AccessItem.AccessLabel := nil;
   end;
   if aObj = cmbAccessProp then
   begin
    cmbAccessProp.ItemIndex := -1;
    if Assigned(AccessItem) then
      AccessItem.AccessProperty := '';
   end;
   if aObj = memAccessTxt then
   begin
    memAccessTxt.text := '';
    if Assigned(AccessItem) then
      AccessItem.AccessText := '';
   end;
   if aObj = chkWatchEnable then
   begin
    chkWatchEnable.Checked := false;
    if Assigned(AccessItem) then
      AccessItem.WatchEnable := false;
   end;
   if aObj = chkIgnoreWatch then
   begin
    chkIgnoreWatch.Checked := false;
    if Assigned(AccessItem) then
      AccessItem.IgnoreEnabled := false;
   end;

  finally
   SetMethodProp(aObj, aEvent, fMethodHwnd);
  end;
 end;


procedure Tva508CollectionEditor.SetAccessData(Sender: TObject; AccessItem: TVA508AccessibilityItem);
var
  SelTxt: String;
  SelLabel: TComponent;
begin
    if Sender = chkDefault then
    begin
       AccessItem.UseDefault := chkDefault.Checked;
       ClearControl(cmbAccessLbl, 'OnChange', AccessItem);
       ClearControl(memAccessTxt, 'OnChange', AccessItem);
       ClearControl(cmbAccessProp, 'OnChange', AccessItem);
    end else if Sender = cmbAccessLbl then
    begin
       if cmbAccessLbl.ItemIndex > -1 then
       begin
         SelTxt := Piece(cmbAccessLbl.Items.Strings[cmbAccessLbl.ItemIndex], '=', 1);
         SelLabel := fOwnerCtrl.Owner.FindComponent(SelTxt);
         AccessItem.AccessLabel := TLabel(SelLabel);
         ClearControl(chkDefault, 'OnClick', AccessItem);
         ClearControl(memAccessTxt, 'OnChange', AccessItem);
         ClearControl(cmbAccessProp, 'OnChange', AccessItem);
       end else
         AccessItem.AccessLabel := nil;
    end else if Sender = cmbAccessProp then
    begin
       AccessItem.AccessProperty := cmbAccessProp.Items.Strings[cmbAccessProp.ItemIndex];
       ClearControl(cmbAccessLbl, 'OnChange', AccessItem);
       ClearControl(memAccessTxt, 'OnChange', AccessItem);
       ClearControl(chkDefault, 'OnClick', AccessItem);
    end else if Sender = memAccessTxt then
    begin
       AccessItem.AccessText := memAccessTxt.Text;
       ClearControl(cmbAccessLbl, 'OnChange', AccessItem);
       ClearControl(chkDefault, 'OnClick', AccessItem);
       ClearControl(cmbAccessProp, 'OnChange', AccessItem);
    end;
    if Sender = chkWatchEnable then
      AccessItem.WatchEnable := chkWatchEnable.Checked;
    if Sender = chkIgnoreWatch then
      AccessItem.IgnoreEnabled := chkIgnoreWatch.Checked;
end;

function Tva508CollectionEditor.WasControlUpdated: Boolean;
var
  I, x: integer;
  aObj, aOrigObject: TVA508AccessibilityItem;
begin
  // Loop through the controls
  Result := fOrigCollection.Count <> fCollection.Count;

  If not Result then
  begin
    for I := 0 to fOrigCollection.Count - 1 do
    begin
      aObj := nil;
      aOrigObject := nil;

      If fOrigCollection.Items[I] is TVA508AccessibilityItem then
        aOrigObject := TVA508AccessibilityItem(fOrigCollection.Items[I]);

      if assigned(aOrigObject) then
        aObj := fCollection.FindItem(aOrigObject.Component, false);

      If (not assigned(aObj)) or (not assigned(aOrigObject)) then
        break;

      Result := (aObj.UseDefault <> aOrigObject.UseDefault) or
        (aObj.WatchEnable <> aOrigObject.WatchEnable) or
        (aObj.IgnoreEnabled <> aOrigObject.IgnoreEnabled) or
        (aObj.AccessLabel <> aOrigObject.AccessLabel) or
        (aObj.AccessProperty <> aOrigObject.AccessProperty) or
        (aObj.AccessText <> aOrigObject.AccessText);

      If (not Result) and (Assigned(aObj.AccessColumns) and Assigned(aOrigObject.AccessColumns)) then
      begin
        Result := aOrigObject.AccessColumns.ReadColumnHeader <> aObj.AccessColumns.ReadColumnHeader;
        If (not Result) then
        begin
          For x := 0 to aObj.AccessColumns.Count - 1 do
          begin
            if (aObj.AccessColumns.ReadColumnValue[x] <>
              aOrigObject.AccessColumns.ReadColumnValue[x]) or
              (aObj.AccessColumns.ColumnHeaderCustomText[x] <>
              aOrigObject.AccessColumns.ColumnHeaderCustomText[x]) then
            begin
              Result := true;
              break;
            end;
          end;
        end;
      end;

      If Result then
        break;

    end;
  end;
end;

procedure Tva508CollectionEditor.CheckForDisabled;
begin
  PerformDisabledCheck(self, fCollection);
end;

procedure Tva508CollectionEditor.chkDefaultClick(Sender: TObject);
var
  AccessItem: TVA508AccessibilityItem;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
    SetAccessData(chkDefault, AccessItem);

end;

procedure Tva508CollectionEditor.memAccessTxtChange(Sender: TObject);
var
  AccessItem: TVA508AccessibilityItem;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
    SetAccessData(memAccessTxt, AccessItem);

end;

procedure Tva508CollectionEditor.MemCustomTextExit(Sender: TObject);
var
  AccessItem: TVA508AccessibilityItem;
  TmpObj: TColumnList;
begin
  If LvAccessCol.ItemIndex = -1 then
  begin
    memCustomText.Clear;
    exit;
  end;

  AccessItem := GetAccessItem;
  TmpObj := AccessItem.AccessColumns;
  if (Trim(MemCustomText.Text) <> '') or (Assigned(TmpObj) and
    (Trim(TmpObj.ColumnHeaderCustomText[LvAccessCol.ItemIndex]) <> '')) then
  begin
    AccessItem := GetAccessItem;
    if Assigned(AccessItem) then
    begin
      TmpObj := AccessItem.AccessColumns;
      TmpObj.ColumnHeaderCustomText[LvAccessCol.ItemIndex] :=
        MemCustomText.Text;
      RgColHeadersClick(Self);
    end;
  end;
end;

procedure Tva508CollectionEditor.cmbAccessLblChange(Sender: TObject);
var
  AccessItem: TVA508AccessibilityItem;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
    SetAccessData(cmbAccessLbl, AccessItem);
end;

procedure Tva508CollectionEditor.cmbAccessPropChange(Sender: TObject);
var
  AccessItem: TVA508AccessibilityItem;
begin
  AccessItem := GetAccessItem;
  if Assigned(AccessItem) then
    SetAccessData(cmbAccessProp, AccessItem);
end;

procedure Tva508CollectionEditor.FillOutList(aCollection
  : TVA508AccessibilityCollection; aOwnerCtrl: TVA508AccessibilityManager);
var
  aItem: TListItem;
  I: integer;
  tmpStrLst: TStringList;
begin
  lstCtrls.Clear;
  fCollection := aCollection;

  fOwnerCtrl := aOwnerCtrl;

  tmpStrLst := TStringList.Create;
  try
    If Assigned(fOrigCollection) then
      FreeAndNil(fOrigCollection);

    If fCollection.Count > 0 then
      fOrigCollection := TVA508AccessibilityCollection.Create(fCollection.Manager);

    fOrigCollection.Assign(fCollection);

    for I := 0 to fCollection.Count - 1 do
    begin
      aItem := lstCtrls.Items.Add;
      aItem.Caption := fCollection.Items[I].DisplayName;
      aItem.Data := fCollection.Items[I];
      tmpStrLst.add(fCollection.Items[I].ControlName);
    end;

  // Prefill the available label list
    tmpStrLst.clear;
    fOwnerCtrl.GetLabelStrings(tmpStrLst);
    cmbAccessLbl.Items.Assign(tmpStrLst);
  finally
    tmpStrLst.Free;
  end;
 fInternal := false;
end;

procedure Tva508CollectionEditor.FormCreate(Sender: TObject);
begin
 fOldHint := Application.OnHint;
 Application.OnHint := MyHint;
end;

procedure Tva508CollectionEditor.FormDestroy(Sender: TObject);
begin
  If Modified then
    CheckForDisabled;

  Application.OnHint := fOldHint;
end;

constructor Tva508CollectionEditor.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

end;

destructor Tva508CollectionEditor.Destroy;
begin
  FreeAndNil(fOrigCollection);
  inherited Destroy;
end;

end.
