unit oi;

interface

uses
  SysUtils, Graphics, Controls, Forms,
  ComCtrls, Grids, ValEdit, Classes, ObjectInspector, Messages, Dialogs,
  ToolWin, main, Menus, ExtCtrls, types, Engine, pluginpalette;

type
  ToeInspector = class(TForm)
    TrackBar1: TTrackBar;
    PageControl1: TPageControl;
    tabProps: TTabSheet;
    tabContent: TTabSheet;
    OpenDialog1: TOpenDialog;
    ColorDialog1: TColorDialog;
    contentLV: TListView;
    listProps: TValueListEditor;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    FontDialog1: TFontDialog;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    adddropdownmenu: TPopupMenu;
    N1: TMenuItem;
    ContentPopup: TPopupMenu;
    ReplaceWith1: TMenuItem;
    N2: TMenuItem;
    Delete1: TMenuItem;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    ToolButton7: TToolButton;
    N3: TMenuItem;
    AddToTemplate1: TMenuItem;
    Events: TTabSheet;
    EventLV: TListView;
    EventsPopup: TPopupMenu;
    AddEvent1: TMenuItem;
    N4: TMenuItem;
    Delete2: TMenuItem;
    procedure TrackBar1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormHide(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure listPropsValidate(Sender: TObject; ACol, ARow: Integer;
      const KeyName, KeyValue: String);
    procedure listPropsKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure listPropsEditButtonClick(Sender: TObject);
    procedure contentLVDblClick(Sender: TObject);
    procedure listPropsDblClick(Sender: TObject);
    procedure ToolButton1Click(Sender: TObject);
    procedure FontDialog1Show(Sender: TObject);
    procedure ToolButton4Click(Sender: TObject);
    procedure ToolButton3Click(Sender: TObject);
    procedure ColorDialog1Show(Sender: TObject);
    procedure adddropdownmenuPopup(Sender: TObject);
    procedure listPropsMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure listPropsMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormActivate(Sender: TObject);
    procedure listPropsDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure listPropsDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure ContentPopupPopup(Sender: TObject);
    procedure contentLVKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure PageControl1Change(Sender: TObject);
    procedure Delete1Click(Sender: TObject);
    procedure ToolButton6Click(Sender: TObject);
    procedure ToolButton7Click(Sender: TObject);
    procedure FormDeactivate(Sender: TObject);
    procedure listPropsDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure ColorDialog1Close(Sender: TObject);
    procedure AddToTemplate1Click(Sender: TObject);
    procedure AddEvent1Click(Sender: TObject);
    procedure Delete2Click(Sender: TObject);
    procedure EventLVDblClick(Sender: TObject);
  private
    dlgName: string;
    IsExtended: Boolean;
    SenIndex: Integer;
    GenIndex: Integer;
    VisIndex: Integer;
    procedure WMNCLButtondblclk(var Msg: TWMNCLButtondblclk); message WM_NCLBUTTONDBLCLK;
  public
    oldHeight: integer;
    OIItemList: TOIItemList;
    OIContentList: TOIContentList;
    procedure SetRoll(Extended: Boolean);
    Procedure ClearOI;
    procedure WM(Var msg: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
    Procedure BuildFromOIIL;
    Procedure BuildFromOIContent;
    Procedure SetOIFields(Number: Integer);
    Procedure BuildAddMenuFromForm;
    Procedure BuildAddMenuFromVisual;
    Procedure BuildAddMenuFromSensor;
    Procedure AddParamForm(ParameterName: String);
    Procedure AddParamVisual(ParamterName: string);
    Procedure AddParamSensor(ParamterName: String);
    Procedure AddMenuOnClick(Sender: TObject);
    Procedure OnContentMenuClick(Sender: TObject);
    Procedure MoveContentSelection(DirectionUp: boolean);
    Procedure OICopyToClipboard;
    Procedure BuildGenMenuFromNode(InsertAt: Integer; Node: TEdSensorNode);
    Procedure ClearGenMenu(Var InsertAt: Integer);
    Procedure OnGenMenu(Sender: TObject);
    Procedure BuildEventList(SelectedNode: TEdRawNode);
  end;

var
  oeInspector: ToeInspector;

implementation

uses
  Windows, CM2FormUnit,
  CM2VisPlugTypes, filter, SnapTo, CM2EditorSupportInterface, CodeSnippet,
  popupHint, AddWin, ProcsAndTypes, LPL_SysUtils, comobj, addtemplate,
  objbrowsewin, AddEventWin;

{$R *.dfm}

procedure ToeInspector.SetOIFields(Number: Integer);
Var
 I: Integer;
begin
 // Ensure we have to correct amount of rows
 If listprops.RowCount > Number then begin
  for I := listprops.RowCount - 1 downto Number do begin // ORiginal Value was 1 to ...
   listprops.DeleteRow(I);
  end;
 end;
 if listprops.RowCount < Number then begin
  For I := (listprops.RowCount - 1) to Number - 2 do begin
   If (listprops.InsertRow('', '', true) < 1) then MessageDlg('Failure to add Row', mtWarning, [mbOK], 0);
  end;
 end;
 For I := 0 to number - 1 do begin
  listprops.ItemProps[I].ReadOnly := False;
  listprops.ItemProps[I].EditStyle := esSimple;
  listprops.Cells[0, I] := '';
  listprops.Cells[1, I] := '';
 End;
end;

procedure ToeInspector.ClearOI;
begin
  if listProps.Strings.Count > 1 then begin
   repeat
     listProps.Strings.Delete(listProps.Strings.Count - 1);
   until listProps.Strings.Count = 1;
  End;
  listProps.Keys[1] := '-';
  listProps.Values[listProps.Keys[1]] := '-';
end;


procedure ToeInspector.TrackBar1Change(Sender: TObject);
begin
  AlphaBlendValue := TrackBar1.Position;
end;

procedure ToeInspector.SetRoll(Extended: Boolean);
begin
 If not extended then begin
  If not IsExtended then exit;
  oldHeight := ClientHeight;
  ClientHeight := TrackBar1.Height;
  toolbar1.Visible := false;
  IsExtended := false;
 end
  else
 begin
  If IsExtended then exit;
  ClientHeight := oldHeight;
  Toolbar1.Visible := true;
  IsExtended := true;
 end;
end;

procedure ToeInspector.FormCreate(Sender: TObject);
begin
  IsExtended := true;
  left := 50;
  top := 50;
  oldHeight := ClientHeight;
  OIItemList := TOIItemList.Create;
  OIContentList := TOIContentList.Create;
  PageControl1.ActivePageIndex := 0;
end;

procedure ToeInspector.FormPaint(Sender: TObject);
begin
  self.Update;
end;

procedure ToeInspector.WM(var msg: TWMWindowPosChanging);
begin
 SnapTo.WMWindowPosChanging(MSG, self);
end;

procedure ToeInspector.FormHide(Sender: TObject);
begin
 oeMain.actionOI.Checked := False;
end;

procedure ToeInspector.FormShow(Sender: TObject);
begin
 oeMain.actionOI.Checked := True;
end;

procedure ToeInspector.BuildFromOIIL;
Var
 Sel, I, II: Integer;
 S, S1, S2: String;
 AlphaList: Tstringlist;
begin
 If OIItemList.Count = 0 then begin
  SetOIFields(1);
  listprops.Cells[0, 0] := '-';
  listprops.Cells[1, 0] := '-';
  listprops.Enabled := false;
  toolbar1.Enabled := False;
  exit;
 end
  else
 begin
  listprops.Enabled := true;
  toolbar1.Enabled := true;
 end;
 SetOIFields(OIItemList.Count);
 // These will used when drawing
 GenIndex := -1; VisIndex := -1; SenIndex := -1;
 Case oeMain.CurrentSelectNode.NodeType of
  ntSensor: begin
             S1 := (oeMain.CurrentSelectNode as TEdSensorNode).PlugInName;
             S2 := (oeMain.CurrentSelectNode as TEdSensorNode).SensorName;
             For I := 0 to oeMain.GESL.Count - 1 do begin
              If uppercase(oeMain.GESL[I].Name) = uppercase(S1) then begin
               GenIndex := I;
               For II := 0 to oeMain.GESL[I].Count - 1 do begin
                If uppercase(oeMain.GESL[I][II].SensorName) = uppercase(S2) then begin
                 SenIndex := II;
                 break;
                end;
               end;
              end;
             end;
            end;
  ntVisual: Begin
             S1 := (oeMain.CurrentSelectNode as TEdVisualNode).VisualName;
             For I := 0 to oeMain.VESL.Count - 1 do begin
              If uppercase(oeMain.VESL[I].Name) = uppercase(S1) then begin
               VisIndex := I;
               break;
              end;
             end;
            end;
 end;
 listprops.strings.BeginUpdate;
 AlphaList := TStringList.Create;
 For I := 0 to OIItemList.Count - 1 do begin
  AlphaList.Add(OIItemList[I].Name);
 end;
 AlphaList.Sort;
 If (OIItemList.Name = '') and (oeMain.CurrentSelectNode is TEdFormNode) then begin
  Caption := 'Object Inspector - Form (Unnamed)';
 end
  else
 begin
  Caption := 'Object Inspector - ' + OIItemList.Name;
 end;
 For I := 0 to AlphaList.Count - 1 do begin
  Sel := -1;
  For II := 0 to OIItemList.Count - 1 do begin
   If uppercase(OIItemList[II].Name) = uppercase(AlphaList[I]) then begin
    Sel := II;
    break;
   end;
  end;
  If Sel > -1 then begin
   listProps.Keys[I] := OIItemList[Sel].Name;
   listProps.Values[listProps.Keys[I]] := OIItemList[Sel].Value;
   Case OIItemList[Sel].EditorSupport.ValueType of
    vtUnknown: listProps.ItemProps[OIItemList[Sel].Name].EditStyle := esSimple;
    vtFixed: Begin
              listProps.ItemProps[OIItemList[Sel].Name].EditStyle := esPickList;
              listProps.ItemProps[OIItemList[Sel].Name].PickList.Clear;
              S := OIItemList[Sel].EditorSupport.ValueRange;
              For II := 1 to CountFilt(S, '|') do begin
               listProps.ItemProps[OIItemList[Sel].Name].PickList.Add(GetFilt(S, II, '|'));
              end;
             End;
    vtColor: Begin
              listProps.ItemProps[OIItemList[Sel].Name].EditStyle := esEllipsis;
              listProps.ItemProps[OIItemList[Sel].Name].PickList.Clear;
             end;
    vtFile: Begin
              listProps.ItemProps[OIItemList[Sel].Name].EditStyle := esEllipsis;
              listProps.ItemProps[OIItemList[Sel].Name].PickList.Clear;
             End;
    vtFontEx: Begin
               listProps.ItemProps[OIItemList[Sel].Name].EditStyle := esEllipsis;
               listProps.ItemProps[OIItemList[Sel].Name].PickList.Clear;
               listProps.ItemProps[OIItemList[Sel].Name].ReadOnly := true;
              End;
    vtEditor: Begin
               listProps.ItemProps[OIItemList[Sel].Name].EditStyle := esEllipsis;
               listProps.ItemProps[OIItemList[Sel].Name].PickList.Clear;
               listProps.ItemProps[OIItemList[Sel].Name].ReadOnly := false;
              End;


   end;
   If OIItemList[Sel].Value = '[sensor]' then begin
    listprops.ItemProps[OIItemList[Sel].Name].EditStyle := esEllipsis;
    listprops.ItemProps[OIItemList[Sel].Name].ReadOnly := true;
    listprops.ItemProps[OIItemList[Sel].Name].PickList.Clear;
   end;
  end;
 end;
 listprops.Strings.EndUpdate;
 If Visible then begin
  listprops.Row := 0;
  listprops.col := 1;
 end;
 FreeAndNil(AlphaList);
end;

procedure ToeInspector.listPropsValidate(Sender: TObject; ACol,
  ARow: Integer; const KeyName, KeyValue: String);
Var
 Sel, I: Integer;
 Current, Min, Max: Integer;
begin
 Sel := -1;
 For I := 0 to OIItemList.Count - 1 do begin
  If OIItemList[I].Name = KeyName Then begin
   Sel := I;
   Break;
  end;
 end;
 // This is required to avoid a warning
 I := OIItemList.Count;
 If (Sel >= I) or (Sel = -1) then begin
  // This causes an AV when deleting rows ...
  exit;
 end;
 If OIItemList[Sel].EditorSupport.ValueType = vtRange then begin
  Min := StrToInt(GetFilt(OIItemList[Sel].EditorSupport.ValueRange, 1, '|'));
  Max := StrToInt(GetFilt(OIItemList[Sel].EditorSupport.ValueRange, 2, '|'));
  Try
   Current := StrToInt(KeyValue);
   If Current < Min then begin
    Current := Min;
    listProps.Cells[ACol, ARow] := IntToStr(Current);
   end;
   If Current > Max then begin
    Current := Max;
    listProps.Cells[ACol, ARow] := IntToStr(Current);
   end;
  except
   on EConvertError do begin
    listProps.Cells[ACol, ARow] := IntToStr(Min);
   end;
  end;
 end;
 If Sel = -1 then begin
  MessageDlg('Unable to locate corrosponding value in Tree.', mtError, [mbOK], 0);
  exit;
 end;
 oeMain.Tree.Modified := true;
 For I := 0 to Length(OIItemList[Sel].Node) - 1 do begin
  Case OIItemList[Sel].Node[I].NodeType of
   ntParameter: Begin
                 (OIItemList[Sel].Node[I] as TEdParameterNode).Value := KeyValue;
                 (OIItemList[Sel].Node[I].Parent as TEdParameterBlockNode).OnParameterUpdate(self);
                end;
   ntForm: Begin
            If Uppercase(KeyName) = 'NAME' then begin
             (OIItemList[Sel].Node[I] as TEdFormNode).FormName := KeyValue;
            end;
           end;
   ntSensor: Begin
              If uppercase(KeyName) = 'DEDICATED' then begin
               If Uppercase(KeyValue) = 'YES' then (OIItemList[Sel].Node[I] as TEdSensorNode).IsDedicated := true
                else (OIItemList[Sel].Node[I] as TEdSensorNode).IsDedicated := false;
               (OIItemList[Sel].Node[I] as TEdSensorNode).OnParameterUpdate(self);
              end;
              If uppercase(KeyName) = 'ID' then begin
               (OIItemList[Sel].Node[I] as TEdSensorNode).IDName := KeyValue;
               (OIItemList[Sel].Node[I] as TEdSensorNode).OnParameterUpdate(self);
              end;
              If uppercase(KeyName) = 'UPDATE' then begin
               (OIItemList[Sel].Node[I] as TEdSensorNode).UpdateStr := KeyValue;
               (OIItemList[Sel].Node[I] as TEdSensorNode).OnParameterUpdate(self);
              end;
            End;
   ntText: Begin
            If Uppercase(KeyName) = 'TEXT' then begin
             (OIItemList[Sel].Node[I] as TEdTextNode).TextValue := KeyValue;
             (OIItemList[Sel].Node[I] as TEdTextNode).OnEvent(self);
            end;
           end;
  end;
 end;
 SnipWin.UpdateSnippet;
end;

procedure ToeInspector.listPropsKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 if key = vk_return then begin
  listPropsValidate(self, listProps.Col, listProps.Row, listProps.Cells[0, listProps.Row], listProps.Cells[1, listProps.Row]);
 end;
end;

procedure ToeInspector.listPropsEditButtonClick(Sender: TObject);
Var
 PlugIndex, SensorIndex, I, II: Integer;
 S, S1, S2, KeyName, KeyValue: String;
 FName, FSize, FStyle: String;
 Strikeout, italic, bold, underline: boolean;
 FS: TFontStyles;
 ESV20: ICM2EditorSupportVis20;
 ES20: ICM2EditorSupport20;
 ESV20Value: PChar;
 ES20Value: PChar;
 FullList: String;
begin
 KeyName := listProps.Cells[0,ListProps.Row];
 KeyValue := listProps.Cells[1,ListProps.Row];
 For I := 0 to OIItemList.Count - 1 do begin
  If OIItemList[I].Name = KeyName then begin
   If OIItemList[I].Value = '[sensor]' then begin
    oeMain.SelectNode(OIItemList[I].Node[0], false);
    exit;
   end;
   If OIItemList[I].EditorSupport.ValueType = vtColor then begin
    Colordialog1.Color := RGBToColor(KeyValue);
    dlgName := OIItemList[I].Name;
    If not ColorDialog1.Execute then exit;
    KeyValue := ColorToRGB(ColorDialog1.Color);
   end;
   If OIItemList[I].EditorSupport.ValueType = vtFile then begin
    Opendialog1.Title := 'Assign File To "' + KeyName + '" Property';
    S := OIItemList[I].EditorSupport.ValueRange;
    S1 := ''; S2 := '';
    For II := 1 to CountFilt(S, '|') do begin
     S1 := S1 + ';*.' + GetFilt(S, II, '|');
     S2 := S2 + ';*.' + GetFilt(S, II, '|');
    end;
    S1 := Copy(S1, 2, length(S1));
    S2 := Copy(S2, 2, Length(S2));
    Opendialog1.Filter := 'All supported Type (' + S1 + ')|' + S2;
    Opendialog1.FileName := KeyValue;
    If not opendialog1.Execute then exit;
    KeyValue := Opendialog1.Filename;
   end;
   If OIItemList[I].EditorSupport.ValueType = vtEditor Then begin
    Case oeMain.CurrentSelectNode.NodeType of
     ntVisual: Begin
                PlugIndex := -1;
                For II := 0 to oeMain.vpl.Count - 1 do begin
                 If GUIDToString(oeMain.VPL[II].GUID) = GUIDToString((oeMain.CurrentSelectNode as TEdVisualNode).VisualGUID) then begin
                  PlugIndex := II;
                  break;
                 end;
                end;
                If PlugIndex = -1 then exit;
                Try
                 ESV20 := CreateComObject (oeMain.VPL[PlugIndex].GUID) as ICM2EditorSupportVis20;
                except
                 exit;
                end;
                ESV20Value := Pchar(KeyValue);
                FullList := '';
                For II := 0 to listprops.RowCount - 1 do begin
                 FullList := FullList + '|' + Listprops.Cells[0, II] + '=' + listprops.Cells[1, II];
                end;
                FullList := copy(FullList, 2, length(FullList));
                If ESV20.OnEditor(Pchar(KeyName), Pchar(FullList), ESV20Value) <> S_OK Then exit;
                KeyValue := ESV20Value;
               end;
     ntSensor: Begin
                PlugIndex := -1;
                SensorIndex := (oeMain.CurrentSelectNode as TEdSensorNode).SensorIndex;
                For II := 0 to oeMain.gpl.Count - 1 do begin
                 If GUIDToString(oeMain.GPL[II].GUID) = GUIDTOString((oeMain.CurrentSelectNode as TEdSensorNode).PlugInGUID) then begin
                  PlugIndex := II;
                  break;
                 end;
                end;
                If PlugIndex = -1 then exit;
                If SensorIndex = -1 then exit;
                Try
                 ES20 := CreateCOMObject (oeMain.GPL[PlugIndex].GUID) as ICM2EditorSupport20;
                except
                 exit;
                end;
                ES20Value := Pchar(KeyValue);
                FullList := '';
                For II := 0 to listprops.RowCount - 1 do begin
                 FullList := FullList + '|' + Listprops.Cells[0, II] + '=' + listprops.Cells[1, II];
                end;
                FullList := copy(FullList, 2, length(FullList));
                If ES20.OnEditor(SensorIndex, PChar(KeyName), PChar(FullList), ES20Value) <> S_OK then exit;
                KeyValue := ES20Value;
               end;
    end;
   end;
   If OIItemList[I].EditorSupport.ValueType = vtFontEx then begin
    FName := GetFilt(KeyValue, 1, ',');
    FSize := GetFilt(KeyValue, 2, ',');
    FStyle := GetFilt(KeyValue, 3, ',');
    If Length(FStyle) <> 4 then FStyle := '0000';
    fontdialog1.Font.Name := FName;
    try
     fontdialog1.Font.Size := StrToInt(FSize);
    except
     FontDialog1.Font.Size := 8;
    end;
    If FStyle[1] = '1' then Bold := true
     else Bold := false;
    If FStyle[2] = '1' then Italic := true
     else Italic := false;
    If FStyle[3] = '1' then Underline := true
     else Underline := false;
    If FStyle[4] = '1' then Strikeout := true
     else Strikeout := false;
    Fs := [];
    If Bold then FS := FS + [fsBold];
    If Italic then FS := FS + [fsItalic];
    If Underline Then FS := FS + [fsUnderline];
    If StrikeOut then FS := FS + [fsStrikeOut];
    fontdialog1.Font.Style := FS;
    dlgName := OIItemList[I].Name;
    If fontDialog1.Execute then begin
     KeyValue := Fontdialog1.Font.Name + ',' + IntToStr(Fontdialog1.Font.Size) + ',';
     If fsbold in Fontdialog1.Font.Style then KeyValue := KeyValue + '1'
      else KeyValue := KeyValue + '0';
     If fsItalic in Fontdialog1.Font.Style then KeyValue := KeyValue + '1'
      else KeyValue := KeyValue + '0';
     If fsUnderline in Fontdialog1.Font.Style then KeyValue := KeyValue + '1'
      else KeyValue := KeyValue + '0';
     If fsStrikeout in Fontdialog1.Font.Style then KeyValue := KeyValue + '1'
      else KeyValue := KeyValue + '0';
    end;
   end;
  end;
 end;
 listProps.Cells[1, ListProps.Row] := KeyValue;
 listPropsValidate(self, ListProps.Col, ListProps.Row, KeyName, KeyValue);
end;


procedure ToeInspector.BuildFromOIContent;
Var
 I: Integer;
 LI: TListItem;
begin
 contentLV.Items.BeginUpdate;
 contentLv.Items.Clear;
 For I := 0 to OIContentList.Count - 1 do begin
  Case OIContentList[I].Node.NodeType of
   ntVisual: Begin
              LI := contentLV.Items.Add;
              LI.ImageIndex := 3;
              LI.Caption := (OIContentList[I].Node as TEdVisualNode).VisualName;
              LI.SubItems.Add(IntToStr(I));
             End;
   ntSensor: Begin
              LI := contentLV.Items.Add;
              If (OIContentList[I].Node as TEdSensorNode).LinkedTo = nil then begin
               LI.ImageIndex := 4;
               LI.Caption := (OIContentList[I].Node as TEdSensorNode).PlugInName + '.' + (OIContentList[I].Node as TEdSensorNode).SensorName;
              end
               else
              begin
               LI.ImageIndex := 6;
               LI.Caption := 'Linked Sensor: "@' + (OIContentList[I].Node as TEdSensorNode).LinkedTo.IDName + '"';
              end;
              LI.SubItems.Add(IntToStr(I));
             End;
   ntText: Begin
              LI := contentLV.Items.Add;
              LI.ImageIndex := 5;
              LI.Caption := (OIContentList[I].Node as TEdTextNode).TextValue;
              LI.SubItems.Add(IntToStr(I));
           End;
  end;
 end;
 contentLV.Items.EndUpdate;
 If oeMain.Select.Count = 1 then begin
  If oeMain.Select.CurrentSelectedNode = nil then begin
   contentlv.Enabled := false;
  end
   else
  begin
   contentlv.Enabled := true;
  end;
 end;
end;

procedure ToeInspector.contentLVDblClick(Sender: TObject);
Var
 Sel: Integer;
begin
 If contentLV.Selected = nil then exit;
 Sel := StrToInt(contentLV.Selected.SubItems[0]);
 If contentLV.Selected.ImageIndex = 6 then begin
  oeMain.SelectNode((OIContentList[Sel].Node as TEdSensorNode).LinkedTo);
 end
  else
 begin
  oeMain.SelectNode(OIContentList[Sel].Node);
 end;
 pagecontrol1.ActivePageIndex := 0;
 listprops.SetFocus;
end;

procedure ToeInspector.listPropsDblClick(Sender: TObject);
Var
 Sel, I: Integer;
 KeyName, KeyValue: String;
 OIItem: TOIItem;
begin
 KeyName := listprops.Cells[0, listprops.row];
 KeyValue := listProps.Cells[1, listprops.row];
 If uppercase(Keyname) = 'LEFT' then begin
  Sel := -1;
  For I := 0 to OIItemList.Count - 1 do begin
   If OIItemList[I].Name = KeyName Then begin
    If OIItemList[I].Node[0].Parent.Parent.NodeType <> ntForm then exit;
    Sel := I;
    Break;
   end;
  end;
  if (OIItemList[Sel].Node[0] is TEdParameterNode) then begin
   (OIItemList[Sel].Node[0] as TEdParameterNode).Name := 'right';
   OIItem := OIItemList[Sel];
   OIItem.Name := 'right';
   OIItemList[Sel] := OIItem;
   KeyName := 'right';
   listprops.Cells[0, Listprops.Row] := KeyName;
  end;
  listPropsValidate(self, listprops.Col, listprops.Row, KeyName, KeyValue);
  Exit;
 end;
 If uppercase(Keyname) = 'TOP' then begin
  Sel := -1;
  For I := 0 to OIItemList.Count - 1 do begin
   If OIItemList[I].Name = KeyName Then begin
    If OIItemList[I].Node[0].Parent.Parent.NodeType <> ntForm then exit;
    Sel := I;
    Break;
   end;
  end;
  if (OIItemList[Sel].Node[0] is TEdParameterNode) then begin
   (OIItemList[Sel].Node[0] as TEdParameterNode).Name := 'bottom';
   OIItem := OIItemList[Sel];
   OIItem.Name := 'bottom';
   OIItemList[Sel] := OIItem;
   KeyName := 'bottom';
   listprops.Cells[0, Listprops.Row] := KeyName;
  end;
  listPropsValidate(self, listprops.Col, listprops.Row, KeyName, KeyValue);
  Exit;
 end;
 If uppercase(KeyName) = 'RIGHT' then begin
  Sel := -1;
  For I := 0 to OIItemList.Count - 1 do begin
   If OIItemList[I].Name = KeyName Then begin
    If OIItemList[I].Node[0].Parent.Parent.Nodetype <> ntForm then exit;
    Sel := I;
    Break;
   end;
  end;
  if (OIItemList[Sel].Node[0] is TEdParameterNode) then begin
   (OIItemList[Sel].Node[0] as TEdParameterNode).Name := 'left';
   OIItem := OIItemList[Sel];
   OIItem.Name := 'left';
   OIItemList[Sel] := OIItem;
   KeyName := 'left';
   listprops.Cells[0, Listprops.Row] := KeyName;
  end;
  listPropsValidate(self, listprops.Col, listprops.Row, KeyName, KeyValue);
  Exit;
 end;
 If uppercase(KeyName) = 'BOTTOM' then begin
  Sel := -1;
  For I := 0 to OIItemList.Count - 1 do begin
   If uppercase(OIItemList[I].Name) = uppercase(KeyName) Then begin
    If OIItemList[I].Node[0].Parent.Parent.nodetype <> ntForm then exit;
    Sel := I;
    Break;
   end;
  end;
  If sel = -1 then exit;
  if (OIItemList[Sel].Node[0] is TEdParameterNode) then begin
   (OIItemList[Sel].Node[0] as TEdParameterNode).Name := 'top';
   OIItem := OIItemList[Sel];
   OIItem.Name := 'top';
   OIItemList[Sel] := OIItem;
   KeyName := 'top';
   listprops.Cells[0, Listprops.Row] := KeyName;
  end;
  listPropsValidate(self, listprops.Col, listprops.Row, KeyName, KeyValue);
  Exit;
 end;
 if listprops.ItemProps[Keyname].EditStyle = esEllipsis then begin
  listPropsEditButtonClick(self);
  exit;
 end;
 if listprops.ItemProps[Keyname].EditStyle <> esPickList then exit;
 Sel := -1;
 For I := 0 to listprops.ItemProps[Keyname].PickList.Count - 1 do begin
  If uppercase(listProps.ItemProps[KeyName].PickList[I]) = uppercase(KeyValue) then begin
   Sel := I;
  end;
 end;
 If Sel = -1 then exit;
 Inc(Sel);
 If Sel >= listProps.ItemProps[KeyName].PickList.Count then Sel := 0;
 KeyValue := listProps.ItemProps[KeyName].PickList[Sel];
 listProps.Cells[1, listprops.row] := KeyValue;
 listPropsValidate(self, listprops.col, listprops.Row, KeyName, KeyValue);
end;


procedure ToeInspector.ToolButton1Click(Sender: TObject);
Var
 NodeToSelect: TEdRawNode;
begin
 NodetoSelect := oeMain.CurrentSelectNode.Parent;
 If oeMain.CurrentSelectNode.Parent.NodeType = ntdisplay then begin
  MessageDlg('Already showing top visual level (Form).', mtInformation, [mbOK], 0);
  exit;
 end;
 While (NodeToSelect.NodeType = ntContent) or (NodeToSelect.NodeType = ntParameter) or (NodeToSelect.NodeType = ntParameterBlock) do begin
  NodeToSelect := NodeToSelect.Parent;
  If NodeToSelect = nil then break;
 end;
 If NodeToSelect <> nil then begin
  oeMain.SelectNode(NodeToSelect);
 end
  else
 begin
  MessageDlg('No node to select', mtInformation, [mbOK], 0);
 end;
end;

procedure ToeInspector.FontDialog1Show(Sender: TObject);
begin
 ShowWindow(GetDlgItem(fontDialog1.Handle, 1091), SW_HIDE); //label Color:
 ShowWindow(GetDlgItem(fontDialog1.Handle, 1139), SW_HIDE); //ColorBox
 ShowWindow(GetDlgItem(fontdialog1.Handle, 1094), SW_HIDE); //label Script
 ShowWindow(GetDlgItem(fontdialog1.Handle, 1140), SW_HIDE); //Script
 SetWindowText(fontdialog1.Handle, PAnsiChar(dlgName));
end;

procedure ToeInspector.ToolButton4Click(Sender: TObject);
Var
 Sel, I: Integer;
 KeyName, KeyValue: String;
begin
 KeyName := listProps.Cells[0, Listprops.row];
 KeyValue := ListProps.Cells[1, ListProps.row];
 If (uppercase(KeyName) = 'LEFT') or (Uppercase(KeyName) = 'TOP') or (Uppercase(KeyName) = 'RIGHT') or
     (Uppercase(Keyname) = 'BOTTOM') or (Uppercase(KeyName) = 'HEIGHT') or (Uppercase(KeyName) = 'WIDTH') then begin
  MessageDlg('You cannot delete positioning and dimension parameters.', mtInformation, [mbOK], 0);
  exit;
 end;
 If (uppercase(KeyName) = 'TRANSPARENTCOLOR') then begin
  For I := 0 to OIItemList.Count - 1 do begin
   If uppercase(OIItemList[I].Name) = 'TRANSPARENT' then begin
    MessageDlg('Transparent is depended on this parameter, so you cannot delete it while transparent is present as parameter.'+#13+#10+'Delete Transparent first.', mtInformation, [mbOK], 0);
    exit;
   end;
  end;
 end;
 Sel := -1;
 For I := 0 to OIItemList.Count -1 do begin
  If uppercase(OIItemList[I].Name) = uppercase(Keyname) then begin
   Sel := I;
   break;
  end;
 end;
 If OIItemList[Sel].EditorSupport.Required then begin
  MessageDlg('The parameter "' + OIItemList[Sel].Name + '" is required for this object, so you cannot delete it.', mtInformation, [mbOK], 0);
  exit;
 end;
 if MessageDlg('Are you sure you wish to delete the parameter "' + OIItemList[Sel].Name + '" ?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then exit;
 OIItemList[Sel].Node[0].DeleteSelf;
 oeMain.SelectNode(oeMain.CurrentSelectNode, true);
end;

procedure ToeInspector.ToolButton3Click(Sender: TObject);
Var
 S: String;
begin
 S := '';
 If not inputQuery('Add Parameter', 'Parameter Name', S) then exit;
 If S = '' then begin
  MessageDlg('You must give the parameter a name.', mtInformation, [mbOK], 0);
  exit;
 end;
 case oeMain.CurrentSelectNode.NodeType of
  ntForm: begin
           (oeMain.CurrentSelectNode as TEdFormNode).GetParameterBlockNode.Add(ntParameter).Name := S;
           oeMain.SelectNode(oeMain.CurrentSelectNode, true);
          end;
  ntSensor: begin
             (oeMain.CurrentSelectNode as TEdSensorNode).GetParameterBlockNode.Add(ntParameter).Name := S;
             oeMain.SelectNode(oeMain.CurrentSelectNode, true);
            end;
  ntText: Begin
           MessageDlg('You cannot add parameters to a text tag.', mtInformation, [mbOK], 0);
          end;
  ntVisual: begin
             (oeMain.CurrentSelectNode as TEdVisualNode).GetParameterBlockNode.Add(ntParameter).Name := S;
             oeMain.SelectNode(oeMain.CurrentSelectNode, true);
            end;
  else
   begin
    MessageDlg('Location: ToeInspector.ToolButton3Click'+#13+#10+'Error: When trying to find the parameterblock node, the current select node type (' + NodeTypeToString(oeMain.CurrentSelectNode.NodeType) + ') was not recognized by the handler.', mtError, [mbOK], 0);
   end;
 end;
end;

procedure ToeInspector.ColorDialog1Show(Sender: TObject);
begin
 SetWindowText(colordialog1.Handle, PAnsiChar(dlgName));
 If Fileexists(PathToOk(ExtractfilePath(ParamStr(0))) + '\CustomColors.dat') then begin
  Colordialog1.CustomColors.LoadFromFile(PathToOk(ExtractfilePath(ParamStr(0))) + '\CustomColors.dat');
 end;
end;

procedure ToeInspector.adddropdownmenuPopup(Sender: TObject);
begin
 adddropdownmenu.Items.Clear;
 Case oeMain.CurrentSelectNode.NodeType of
  ntForm: begin
           BuildAddMenuFromForm;
          end;
  ntVisual: begin
             BuildAddMenuFromVisual;
            end;
  ntSensor: Begin
             BuildAddMenuFromSensor;
            end; 
 end;
end;

procedure ToeInspector.BuildAddMenuFromForm;
Var
 MI: TMenuITem;
 List: TStringList;
 I, II: Integer;
 Found: Boolean;
begin
 List := TStringList.Create;
 for I := 0 to oeMain.FESL.Count - 1 do begin
  Found := false;
  For II := 0 to listProps.RowCount - 1 do begin
   if uppercase(oeMain.FESL[I].Name) = uppercase(listProps.Cells[0, II]) then begin
    Found := true;
   end;
  end;
  If not found then List.Add(oeMain.FESL[I].Name);
 end;
 For I := 0 to List.count - 1 do begin
  MI := TMenuItem.Create(adddropdownmenu);
  MI.Caption := List[I];
  MI.OnClick := AddMenuOnClick;
  adddropdownmenu.items.Add(MI);
 end;
 FreeAndNil(List);
end;

procedure ToeInspector.BuildAddMenuFromSensor;
Var
 MI: TMenuITem;
 List: TStringList;
 PlugIndex, SensorIndex, I, II: Integer;
 Found: Boolean;
 PlugName, SensorName: String;
begin
 List := TStringList.Create;
 PlugName := (oeMain.CurrentSelectNode as TEdSensorNode).PlugInName;
 SensorName := (oeMain.CurrentSelectNode as TEdSensorNode).SensorName;
 If not oeMain.GESL.GetIndexByName(PlugName + '.' + SensorName, PlugIndex, SensorIndex) then begin
  MessageDlg('Location: BuildAddMenuFromSensor'+#13+#10+'Error: Unable to locate plugin in the plugin list', mtError, [mbOK], 0);
  exit;
 end;
 For I := 0 to oeMain.GESL[PlugIndex].SensorParamEditorSupportList[SensorIndex].Count - 1 do begin
  Found := false;
  For II := 0 to listProps.RowCount - 1 do begin
    If uppercase(oeMain.GESL[PlugIndex].SensorParamEditorSupportList[SensorIndex].SensorParamEditorSupport[I].Name) = uppercase(listProps.Cells[0, II]) then begin
     Found := true;
    end;
  end;
  If not found then List.Add(oeMain.GESL[PlugIndex].SensorParamEditorSupportList[SensorIndex].SensorParamEditorSupport[I].Name);
 end;
 For I := 0 to List.count - 1 do begin
  MI := TMenuItem.Create(adddropdownmenu);
  MI.Caption := List[I];
  MI.OnClick := AddMenuOnClick;
  adddropdownmenu.items.Add(MI);
 end;
 FreeAndNil(List);
end;

procedure ToeInspector.BuildAddMenuFromVisual;
Var
 MI: TMenuITem;
 List: TStringList;
 VisIndex, I, II: Integer;
 Found: Boolean;
 VisName: String;
begin
 List := TStringList.Create;
 VisName := (oeMain.CurrentSelectNode as TEdVisualNode).VisualName;
 VisIndex := oeMain.VESL.GetIndexByName(VisName);
 For I := 0 to oeMain.VESL[VisIndex].Count - 1 do begin
  Found := false;
  For II := 0 to listProps.RowCount - 1 do begin
    If uppercase(oeMain.VESL[VisIndex].VisPlugEditorInfo[I].Name) = uppercase(listProps.Cells[0, II]) then begin
     Found := true;
    end;
  end;
  If not found then List.Add(oeMain.VESL[VisIndex].VisPlugEditorInfo[I].Name);
 end;
 For I := 0 to List.count - 1 do begin
  MI := TMenuItem.Create(adddropdownmenu);
  MI.Caption := List[I];
  MI.OnClick := AddMenuOnClick;
  adddropdownmenu.items.Add(MI);
 end;
 FreeAndNil(List);
end;

procedure ToeInspector.AddMenuOnClick(Sender: TObject);
Var
 ParamName: String;
begin
 ParamName := (Sender as TMenuItem).Caption;
 ParamName := GetFilt(ParamName, 1, '&') + GetFilt(ParamName, 2, '&');
 Case oeMain.CurrentSelectNode.NodeType of
  ntForm: Begin
           AddParamForm(ParamName);
          end;
  ntVisual: Begin
             AddParamVisual(ParamName);
            end;
  ntSensor: Begin
             AddParamSensor(ParamName);
            end;
 end;
 ObjBrowser.LoadFromNode();
end;

procedure ToeInspector.AddParamForm(ParameterName: String);
Var
 I: Integer;
begin
 For I := 0 to oeMain.FESL.Count - 1 do begin
  If uppercase(oeMain.FESL[I].Name) = uppercase(ParameterName) then begin
   (oeMain.CurrentSelectNode as TEdFormNode).GetParameterBlockNode.AddParameterNode(oeMain.FESL[I].Name, oeMain.FESL[I].Value);
   oeMain.SelectNode(oeMain.CurrentSelectNode, true);
   break;
  end;
 end;
end;

procedure ToeInspector.AddParamSensor(ParamterName: String);
Var
 PlugIndex, SensorIndex: Integer;
 I: Integer;
begin
 If not oeMain.GESL.GetIndexByName((oeMain.CurrentSelectNode as TedSensorNode).PlugInName + '.' + (oeMain.CurrentSelectNode as TedSensorNode).SensorName, PlugIndex, SensorIndex) then begin
  MessageDlg('Location: ToeInspector.AddParameterSensor'+#13+#10+'Error: Could not find plugin in GESL', mtError, [mbOK], 0);
  exit;
 end;
 For I := 0 to oeMain.GESL[PlugIndex][SensorIndex].Count - 1 do begin
  if uppercase(oeMain.GESL[PlugIndex][SensorIndex][I].Name) = uppercase(ParamterNAme) then begin
   (oeMain.CurrentSelectNode as TEdSensorNode).GetParameterBlockNode.AddParameterNode(oeMain.GESL[PlugIndex][SensorIndex][I].Name, oeMain.GESL[PlugIndex][SensorIndex][I].Value);
   oeMain.SelectNode(oeMain.CurrentSelectNode, true);
   break;
  end;
 end;
end;

procedure ToeInspector.AddParamVisual(ParamterName: string);
Var
 VisIndex, I: Integer;
begin
 VisIndex := oeMain.VESL.GetIndexByName((oeMain.CurrentSelectNode as TEdVisualNode).VisualName);
 For I := 0 to oeMain.VESL[VisIndex].Count - 1 do begin
  If uppercase(oeMain.VESL[VisIndex][I].Name) = uppercase(ParamterName) then begin
   (oeMain.CurrentSelectNode as TEdVisualNode).GetParameterBlockNode.AddParameterNode(oeMain.VESL[VisIndex][I].Name, oeMain.VESL[VisIndex][I].Value);
   oeMain.SelectNode(oeMain.CurrentSelectNode, true);
   break;
  end;
 end;
end;

procedure ToeInspector.listPropsMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
Var
 I, ARow, ACol: Integer;
 Des, KeyName: String;
 PT: TPoint;
begin
 if button = mbright then begin
  listprops.MouseToCell(x,y,ACol,ARow);
  If arow = -1 then exit;
  KeyName := ListProps.Cells[0, ARow];
  Des := '';
  For I := 0 to OIItemList.Count - 1 do begin
   If uppercase(OIItemList[I].Name) = uppercase(Keyname) then begin
    Des := OIItemList[I].EditorSupport.Description + '  [Default Value: ' + OIItemList[I].EditorSupport.Value + ']';
   end;
  end;
  If Des = '  [Default Value: ]' then exit;
  PT := HintWin.ProvideLocation(listprops);
  PT.X := PT.X + X - (listprops.Width div 2);
  PT.Y := PT.Y + Y - (listprops.Height div 2);
  HintWin.ShowHint(PT, adAuto, KeyName, Des, 0, oeMain.TutorialList.CaptionFont, oeMain.TutorialList.MainFont);
 end;
end;

procedure ToeInspector.listPropsMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 if button = mbRight then begin
  If HintWin.Visible then HintWin.Hide; 
 end;
end;

procedure ToeInspector.FormActivate(Sender: TObject);
begin
 oeMain.SetHotKeyStates(self);
 If (Options.ToolWindows.AutoRollUp and (not Options.ToolWindows.ARUExcept.OI)) then begin
  SetRoll(true);
 end;
end;

procedure ToeInspector.listPropsDragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
Var
 R, C: Integer;
 KeyName: String;
begin
  Accept := False;
  if (Source is TListview) then begin
   listprops.MouseToCell(X, y, C, R);
   If R < 0 then exit;
   KeyName := ListProps.Cells[0, R];
   If not (OIItemList.Find(Keyname).EditorSupport.CanContainSensor) then exit;
   if uppercase((Source as TListView).Name) = 'LISTGEN' then Accept := true;
  end;
end;

procedure ToeInspector.listPropsDragDrop(Sender, Source: TObject; X,
  Y: Integer);
Var
 Sel, R, C, I: Integer;
 KeyName: String;
 GUID: TGUID;
begin
 listprops.MouseToCell(X, Y, C, R);
 KeyName := listprops.Cells[0, R];
 Sel := -1;
 For I := 0 to OIItemList.Count - 1 do begin
  If OIItemList.OIItem[I].Name = Keyname then begin
   Sel := I;
   break;
  end;
 end;
 If Sel = -1 then begin
  MessageDlg('Location: ToeInspector.listpropsDragDrop'+#13+#10+'Error: Could not find the name from the parameter that the object was dragged to.', mtError, [mbOK], 0);
  exit;
 end;
 For I := 0 to Length(OIItemList[Sel].Node) - 1 do begin
  Case OIItemList[Sel].Node[I].NodeType of
   ntParameter: Begin
                 If OIItemList[Sel].Node[I].ContainsASensorChildNode then begin
                  OIItemList[Sel].Node[I].Node[0].DeleteSelf;
                 end;
                 (OIItemList[Sel].Node[I] as TEdParameterNode).Value := '';
                 (OIItemList[Sel].Node[I] as TEdParameterNode).OIType := oitUnknown;
                 (OIItemList[Sel].Node[I] as TEdParameterNode).OITString := '';
                 GUID := StringToGUID((Source as TListView).Selected.SubItems[0]);
                 AddSensorDlg.Execute(GUID, OIItemList[Sel].Node[I]);
                end;
   ntSensor: begin
              OIItemList[Sel].Node[I] := OIItemList[Sel].Node[I].Parent;
              OIItemList[Sel].Node[I].Node[0].DeleteSelf;
              (OIItemList[Sel].Node[I] as TEdParameterNode).Value := '';
              (OIItemList[Sel].Node[I] as TEdParameterNode).OIType := oitUnknown;
              (OIItemList[Sel].Node[I] as TEdParameterNode).OITString := '';
              GUID := StringToGUID((Source as TListView).Selected.SubItems[0]);
              AddSensorDlg.Execute(GUID, OIItemList[Sel].Node[I]);
             end;
  end;
 end;
end;

procedure ToeInspector.ContentPopupPopup(Sender: TObject);
Var
 InsertAt: Integer;
begin
 InsertAt := -1;
 ClearGenMenu(InsertAt);
 If InsertAt = -1 then begin
  MessageDlg('Unable to find Delete1, cannot insert custom items.', mtWarning, [mbOK], 0);
  exit;
 end;

 If contentLv.Selected = nil then begin
  AddToTemplate1.Enabled := false;
  If oeMain.Select.Count > 0 then begin
   If oeMain.Select.CurrentSelectedNode.NodeType = ntVisual then begin
    ReplaceWith1.Caption := 'Add';
    ReplaceWith1.Items[0].Visible := true;
    ReplaceWith1.Visible := true;
   end
    else
   begin
    ReplaceWith1.Visible := false;
   end;
  end;
  Delete1.Enabled := false;
  Exit;
 end
  else
 begin
  If oeMain.Select.CurrentSelectedNode.NodeType = ntVisual then begin
   ReplaceWith1.Caption := 'Replace With';
   ReplaceWith1.Items[0].Visible := false;
   ReplaceWith1.Visible := true;
  end
   else
  begin
   ReplaceWith1.Visible := false;
  end;
  Delete1.Enabled := true;
 end;

 Case oeMain.Select.CurrentSelectedNode.NodeType of
  ntForm: Begin
           AddToTemplate1.Enabled := true;
          end;
  ntVisual: Begin
             AddToTemplate1.Enabled := true;
            end;
  else begin
   AddToTemplate1.Enabled := false;
  end;
 end;

 If oeMain.Select.CurrentSelectedNode.NodeType = ntVisual then begin
  If (oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode[contentLV.Selected.Index].NodeType <> ntSensor then exit;
  BuildGenMenuFromNode(InsertAt, (oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode[contentLV.Selected.Index] as TEdSensorNode);
 end;

end;

procedure ToeInspector.contentLVKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
Var
 Sel: Integer;
begin
 If ssCtrl in Shift then begin
  If key = vk_Down then begin
   Key := 0;
   MoveContentSelection(false);
  end;
  If key = vk_up then begin
   Key := 0;
   MoveContentSelection(true);
  end;
 end
  else
 begin
  // Manual  selection handling
  Sel := contentlv.ItemIndex;
  If key = vk_up then begin
   Dec(Sel);
   If Sel = -1 then Sel := 0;
  end;
  if key = vk_down then begin
   Inc(Sel);
   If Sel >= contentLv.items.count Then Sel := ContentLV.Items.Count - 1;
  end;
  contentLV.ItemIndex := Sel;
  contentlv.ItemFocused := contentLV.Items[sel];
 end;
 key := 0;
end;

procedure ToeInspector.OnContentMenuClick(Sender: TObject);
Var
 I: Integer;
 GUID: TGUID;
 Found: Boolean;
 S, PlugName, PlugSens: String;
 ChildCML: String;
 VNode: TEdVisualNode;
 CNode: TEdContentNode;
begin
 S := (Sender as TMenuItem).Caption;
 S := GetFilt(S, 1, '&') + GetFilt(S, 2, '&');
 If uppercase(S) = uppercase(rawtext) then begin
  CNode := (oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode;
  oeMain.Select.CurrentSelectedNode := CNode.Add(ntText);
  PageControl1.ActivePageIndex := 0;
  listprops.Col := 1;
  listProps.SetFocus;
  exit;
 end;
 PlugSens := (Sender as TMenuItem).Caption;
 PlugSens := GetFilt(PlugSens, 1, '&') + GetFilt(PlugSens, 2, '&');
 PlugName := ((Sender as TMenuItem).Parent as TMenuItem).Caption;
 PlugName := GetFilt(PlugName, 1, '&') + GetFilt(PlugName, 2, '&');
 Found := False;
 For I := 0 to oeMain.GPL.Count - 1 do begin
  If oeMain.GPL[I].Name = PlugName then begin
   Found := True;
   GUID := oeMain.GPL[I].GUID;
   break;
  end;
 end;
 If not found then exit;
 If contentLV.Selected = nil then begin
  // add Mode
  AddSensorDlg.Execute(GUID, (oeMain.Select.CurrentSelectedNode as TEdVisualNode), PlugName, PlugSens);
  exit;
 end;
 // Replace mode
 ChildCML := '';
 VNode := (OIContentList[contentLV.Selected.Index].Node.Parent.Parent as TEdVisualNode);
 OIContentList[contentLV.Selected.Index].Node.DeleteSelf;
 AddSensorDlg.Execute(GUID, VNode, PlugName, PlugSens);
end;

procedure ToeInspector.PageControl1Change(Sender: TObject);
begin
 If pagecontrol1.ActivePageIndex = 0 then begin
  ToolButton3.Enabled := true;
  Toolbutton4.Enabled := true;
  ToolButton6.Enabled := false;
  Toolbutton7.Enabled := false;
 end
  else
 begin
  ToolButton3.Enabled := false;
  Toolbutton4.Enabled := false;
  ToolButton6.Enabled := true;
  Toolbutton7.Enabled := true;
 end;
end;

procedure ToeInspector.Delete1Click(Sender: TObject);
Var
 Sel: Integer;
 CNode: TEdContentNode;
begin
 If MessageDlg('Are you sure you want to delete this object ?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then exit;
 Sel := contentLV.Selected.Index;
 CNode := nil;
 case oeMain.Select.CurrentSelectedNode.nodetype of
  ntForm: begin
           CNode := (oeMain.Select.CurrentSelectedNode as TEdFormNode).GetContentNode;
          end;
  ntVisual: begin
             CNode := (oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode;
            end;
 end;
 If CNode = nil then exit;
 CNode.Delete(Sel);
 OIContentList.BuildFromTag(CNode.Parent);
 BuildFromOIContent;
 ObjBrowser.LoadFromNode();
end;

procedure ToeInspector.WMNCLButtondblclk(var Msg: TWMNCLButtondblclk);
begin
 If ((msg.HitTest = HTCAPTION) and (not(Options.ToolWindows.AutoRollUp and (not Options.ToolWindows.ARUExcept.OI)))) then begin
  SetRoll(not IsExtended);
 end;
end;

procedure ToeInspector.MoveContentSelection(DirectionUp: boolean);
Var
 CNode: TEdcontentNode;
 From, Moveto: Integer;
begin
  CNode := nil;
  If DirectionUp then begin
   From := contentLv.Selected.Index;
   If From = 0 then exit;
   MoveTo := From - 1;
   Case oeMain.Select.CurrentSelectedNode.NodeType of
    ntForm: begin
             CNode := (oeMain.Select.CurrentSelectedNode as TEdFormNode).GetContentNode;
            end;
    ntVisual: begin
               CNode := (oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode;
              end;
   end;
  end
   else
  begin
   From := contentLv.Selected.Index;
   If (From >= (contentlv.items.Count)) or (From < 0) then exit;
   MoveTo := From + 1;
   If MoveTo >= (contentlv.items.Count) then exit;
   Case oeMain.Select.CurrentSelectedNode.NodeType of
    ntForm: begin
             CNode := (oeMain.Select.CurrentSelectedNode as TEdFormNode).GetContentNode;
            end;
    ntVisual: begin
               CNode := (oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode;
              end;
   end;
  end;
  If CNode = nil then exit;
  CNode.MoveChild(From, MoveTo);
  OIContentList.BuildFromTag(oeMain.Select.CurrentSelectedNode);
  BuildFromOIContent;
  contentlv.ItemIndex := MoveTo;
end;

procedure ToeInspector.ToolButton6Click(Sender: TObject);
begin
 If ContentLV.Selected = nil then exit;
 MoveContentSelection(true);
end;

procedure ToeInspector.ToolButton7Click(Sender: TObject);
begin
 If ContentLV.Selected = nil then exit;
 MoveContentSelection(false);
end;

procedure ToeInspector.OICopyToClipboard;
begin

end;

procedure ToeInspector.FormDeactivate(Sender: TObject);
begin
 If (Options.ToolWindows.AutoRollUp and (not Options.ToolWindows.ARUExcept.OI)) then begin
  SetRoll(false);
 end;
end;

procedure ToeInspector.listPropsDrawCell(Sender: TObject; ACol,
  ARow: Integer; Rect: TRect; State: TGridDrawState);
Var
 DV, KeyName, KeyValue: String;
 I: Integer;
 Found, Req: Boolean;
begin
 Req := True;
 KeyValue := listprops.Cells[1, Arow];
 KeyName := listprops.Cells[0, Arow];
 For I := 0 to OIItemList.Count -1 do begin
  If uppercase(OIItemList[I].Name) = uppercase(Keyname) then begin
   Req := OIItemList[I].EditorSupport.Required;
   DV := OIItemList[I].EditorSupport.Value;
   break;
  end;
 end;
 If not Req then begin
  If (uppercase(KeyName) = 'LEFT') or (Uppercase(Keyname) = 'TOP') or
   (Uppercase(KeyName) = 'HEIGHT') or (Uppercase(KeyName) = 'WIDTH') or (Uppercase(Keyname) = 'ID') then begin
   Req := True;
  end;
 end;
 If Req then begin
  listprops.Canvas.Brush.Color := Options.OI.RequiredBackgroundColor;
  listprops.Canvas.Pen.Color := Options.OI.RequiredBackgroundColor;
  Listprops.Canvas.Font.Color := Options.OI.RequiredFontColor;
 End
  else
 begin
  Found := false;
  DV := '';
  Case oeMain.CurrentSelectNode.NodeType of
   ntForm: begin
            For I := 0 to oeMain.FESL.Count - 1 do begin
             If uppercase(oeMain.FESL[I].Name) = uppercase(keyname) then begin
              Found := true;
              DV := oeMain.FESL[I].Value;
              break;
             end;
            end;
           end;
   ntVisual: begin
              If VisIndex > -1 then begin
               For I := 0 to oeMain.VESL[VisIndex].Count - 1 do begin
                If uppercase(oeMain.VESL[VisIndex][I].Name) = uppercase(Keyname) then begin
                 Found := true;
                 DV := oeMain.VESL[VisIndex][I].Value;
                 break;
                end;
               end;
              end;
             end;
   ntSensor: begin
              If (GenIndex > -1) and (SenIndex > -1) then begin
               For I := 0 to oeMain.GESL[GenIndex][SenIndex].Count - 1 do begin
                If uppercase(oeMain.GESL[GenIndex][SenIndex][I].Name) = uppercase(Keyname) then begin
                 Found := true;
                 DV := oeMain.GESL[GenIndex][SenIndex][I].Value;
                 break;
                end;
               end;
              end;
             end;
  end;
  If Found then begin
   listprops.Canvas.Brush.Color := Options.OI.BackgroundColor;
   listprops.Canvas.Pen.Color := Options.OI.BackgroundColor;
   Listprops.Canvas.Font.Color := Options.OI.FontColor;
  end
   else
  begin
   listprops.Canvas.Brush.Color := Options.OI.NonBackgroundColor;
   listprops.Canvas.Pen.Color := Options.OI.NonBackgroundColor;
   Listprops.Canvas.Font.Color := Options.OI.NonFontColor;
  end;
 end;
 If (DV = KeyValue) and (ACol = 1) then begin
  listprops.Canvas.Font.Style := [fsBold];
 end
  else
 begin
  listprops.Canvas.Font.Style := [];
 end;
 listprops.Canvas.Rectangle(Rect);
 listprops.Canvas.TextOut(Rect.Left + 1, Rect.Top + 1, Listprops.Cells[acol, arow]);
end;

procedure ToeInspector.ColorDialog1Close(Sender: TObject);
begin
 Colordialog1.CustomColors.SaveToFile(PathToOk(ExtractfilePath(ParamStr(0))) + '\CustomColors.dat');
end;

procedure ToeInspector.BuildGenMenuFromNode(InsertAt: Integer; Node: TEdSensorNode);
Var
 Res, PlugIndex, I: Integer;
 MI: TMenuItem;
 ES20: ICM2EditorSupport20;
 MC: Byte;
 MN, MH: PChar;
begin
 PlugIndex := -1;
 For I := 0 to oeMain.gpl.Count - 1 do begin
  If GUIDTOstring(Node.PlugInGUID) = GUIDToString(oeMain.GPl[I].GUID) then begin
   PlugIndex := I;
  end;
 end;
 If plugindex = -1 then exit;
 Try
  ES20 := CreateComObject (oeMain.GPL[PlugIndex].GUID) as ICM2EditorSupport20;
 except
  exit;
 end;
 Res := ES20.GetMenuCount(Node.SensorIndex, MC);
 If Res = S_OK then begin
  For I := 0 to MC - 1 do begin
   Res := ES20.GetMenuItem(Node.SensorIndex, I, MN, MH);
   If Res = S_OK then begin
    MI := TMenuItem.Create(ContentPopup);
    MI.Tag := 1000 + I;
    MI.Caption := MN;
    MI.Hint := MH;
    MI.OnClick := OnGenMenu;
    ContentPopup.Items.Insert(InsertAt, MI);
    Inc(InsertAt);
   end;
  end;
  MI := TMenuItem.Create(ContentPopup);
  MI.Tag := 99999;
  MI.Caption := '-';
  ContentPopup.Items.Insert(InsertAt, MI);
 end;
end;

procedure ToeInspector.ClearGenMenu(Var InsertAt: Integer);
Var
 I: Integer;
begin
 I := 0;
 InsertAt := 0;
 Repeat
  If ContentPopup.Items[I].Name = 'Delete1' then begin
   InsertAt := I;
  end;
  If ContentPopup.Items[I].Tag > 999 then begin
   ContentPopup.Items.Delete(I);
  end
   else
  begin
   Inc(I);
  end;
 Until I >= ContentPopup.Items.Count;
End;

procedure ToeInspector.OnGenMenu(Sender: TObject);
Var
 Res, PlugIndex, I: Integer;
 ES20: ICM2EditorSupport20;
 ResultStr: Pchar;
begin
 PlugIndex := -1;
 For I := 0 to oemain.gpl.Count - 1 do begin
  If GUIDTOstring(((oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode[contentLV.Selected.Index] As TEdSensorNode).PlugInGUID) = GUIDToString(oeMain.GPl[I].GUID) then begin
   PlugIndex := I;
  end;
 end;
 If plugindex = -1 then exit;
 Try
  ES20 := CreateComObject (oeMain.GPL[PlugIndex].GUID) as ICM2EditorSupport20;
 except
  exit;
 end;
 Res := ES20.OnMenu(((oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode[contentLV.Selected.Index] as TEdSensorNode).SensorIndex, (Sender as TMenuItem).Tag - 1000, ResultStr);
 If Res = S_OK then begin
  If ResultStr <> '' then begin
   // *** TODO ***
   // Insert ADD Code here
  end;
 end;
end;

procedure ToeInspector.AddToTemplate1Click(Sender: TObject);
begin
 Case oeMain.Select.CurrentSelectedNode.NodeType of
  ntForm: Begin
           AddTempDlg.Execute((oeMain.Select.CurrentSelectedNode as TEdFormNode).GetContentNode[contentLV.Selected.Index]);
          end;
  ntVisual: Begin
             AddTempDlg.Execute((oeMain.Select.CurrentSelectedNode as TEdVisualNode).GetContentNode[contentLV.Selected.Index]);
            end;
 end;
end;

procedure ToeInspector.BuildEventList(SelectedNode: TEdRawNode);
Var
 I: Integer;
 Node: TEdEventsNode;
 EventString: String;
 LI: TListItem;
 S: String;
begin
 If SelectedNode = nil then begin
  Events.TabVisible := false;
  exit;
 end;
 If not ((SelectedNode.NodeType = ntVisual) or (SelectedNode.NodeType = ntForm)) then begin
  Events.TabVisible := False;
  exit;
 end;
 Events.TabVisible := true;
 EventLV.Items.Clear;
 Node := nil;
 Case SelectedNode.Nodetype of
  ntForm: begin
           Node := (SelectedNode as TEdFormNode).GetEventsNode(false);
          end;
  ntVisual: Begin
             Node := (SelectedNode as TEdVisualNode).GetEventsNode(false);
            end;
 end;
 If Node = nil then exit;

 EventLV.Items.BeginUpdate;
 EventString := Node.GetEvents;
 For I := 1 to CountFilt(EventString, '|') do begin
  LI := EventLV.Items.Add;
  S := GetFilt(EventString, I, '|');
  LI.Caption := GetFilt(S, 1, '>');
  LI.SubItems.Add(GetFilt(S, 2, '>'));
  LI.SubItems.Add(GetFilt(S, 3, '>'));
 end;
 EventLv.Items.EndUpdate;
end;

procedure ToeInspector.AddEvent1Click(Sender: TObject);
Var
 T, M, C: String;
 LI: TListItem;
begin
 T := ''; M := ''; C := '';
 If not addeventdlg.Execute(T, M, C) then exit;
 Case oeMain.CurrentSelectNode.NodeType of
  ntForm: begin
           (oeMain.CurrentSelectNode as TEdFormNode).GetEventsNode(True).GetEventHandlerNode(T, True).GetActionNode(M, True).GetExecuteNode(C, True);
          end;
  ntVisual: Begin
             (oeMain.CurrentSelectNode As TEdVisualNode).GetEventsNode(True).GetEventHandlerNode(T, True).GetActionNode(M, True).GetExecuteNode(C, True);
            end;
 end;
 LI := EventLV.Items.Add;
 LI.Caption := T;
 LI.SubItems.Add(M);
 LI.SubItems.Add(C);
end;

procedure ToeInspector.Delete2Click(Sender: TObject);
Var
 T, M, C: String;
 Node: TEdEventsNode;
begin
 If eventLV.Selected = nil then exit;
 If MessageDlg('Are you sure you wish to remove this event ?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then exit;
 T := eventLV.Selected.Caption;
 M := eventLV.Selected.SubItems[0];
 C := EventLV.Selected.SubITems[1];
 Node := nil;
 case oeMain.CurrentSelectNode.Nodetype of
  ntForm: begin
           Node := (oeMain.CurrentSelectNode as TEdFormNode).GetEventsNode(false);
          end;
  ntVisual: begin
             Node := (oeMain.CurrentSelectNode as TEdVisualNode).GetEventsNode(false);
            end;
 end;
 If node = nil then exit;
 Node.DeleteEvent(T, M, C);
 eventLV.Selected.Delete;
end;

procedure ToeInspector.EventLVDblClick(Sender: TObject);
var
 T, M, C: String;
 OT, OM, OC: String;
 Node: TEdEventsNode;
 LI: TListItem;
begin
 If eventlv.Selected = nil then exit;
 T := EventLV.Selected.Caption;
 M := EventLV.Selected.SubItems[0];
 C := EventLV.Selected.SubItems[1];
 OT := T; OM := M; OC := C;
 If not addeventdlg.Execute(T, M, C) then exit;
 eventlv.Selected.Delete;
 Node := nil;
 Case oeMain.CurrentSelectNode.Nodetype of
  ntForm: Begin
           Node := (oeMain.CurrentSelectNode as TEdFormNode).GetEventsNode(true);
          end;
  ntVisual: Begin
             Node := (oeMain.CurrentSelectNode as TEdVisualNode).GetEventsNode(true);
            end;
 end;
 If node = nil then exit;
 Node.DeleteEvent(OT, OM, OC);
 Case oeMain.CurrentSelectNode.NodeType of
  ntForm: begin
           (oeMain.CurrentSelectNode as TEdFormNode).GetEventsNode(True).GetEventHandlerNode(T, True).GetActionNode(M, True).GetExecuteNode(C, True);
          end;
  ntVisual: Begin
             (oeMain.CurrentSelectNode As TEdVisualNode).GetEventsNode(True).GetEventHandlerNode(T, True).GetActionNode(M, True).GetExecuteNode(C, True);
            end;
 end;
 LI := eventlv.Items.add;
 LI.Caption := T;
 LI.Subitems.Add(M);
 LI.SubItems.Add(C);
end;

end.
