{ *************************************************************************** }
{                                                                             }
{ EControl Syntax Editor SDK                                                  }
{                                                                             }
{ Copyright (c) 2004 - 2008 EControl Ltd., Zaharov Michael                    }
{     www.econtrol.ru                                                         }
{     support@econtrol.ru                                                     }
{                                                                             }
{ *************************************************************************** }
{$I ecSyntEdit.INC}

unit ecMultReplDlg;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ActnList, ToolWin, ImgList, ExtCtrls, StdCtrls,
  ecSyntMemo, ecMultRepl, ecSyntAnal;

type
  TMultiReplaceDlg = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    Splitter1: TSplitter;
    ActionList1: TActionList;
    ImageList1: TImageList;
    ToolBar1: TToolBar;
    TV: TTreeView;
    AddGroup: TAction;
    AddChild: TAction;
    DeleteNode: TAction;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    Comp: TecMultiReplace;
    PageControl1: TPageControl;
    TabGroup: TTabSheet;
    TabItem: TTabSheet;
    Label1: TLabel;
    Edit2: TEdit;
    Label2: TLabel;
    Edit3: TEdit;
    Label3: TLabel;
    HotKey1: THotKey;
    Label4: TLabel;
    Edit4: TEdit;
    SyntAnalyzer1: TSyntAnalyzer;
    Bevel1: TBevel;
    Label5: TLabel;
    CheckBox1: TCheckBox;
    SyntaxMemo1: TSyntaxMemo;
    Label6: TLabel;
    SyntaxMemo2: TSyntaxMemo;
    SyntaxMemo3: TSyntaxMemo;
    Label7: TLabel;
    Label8: TLabel;
    SyntaxMemo4: TSyntaxMemo;
    GroupBox1: TGroupBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    Splitter2: TSplitter;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    SyntAnalyzer2: TSyntAnalyzer;
    actLoad: TAction;
    actSave: TAction;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    ToolButton7: TToolButton;
    CheckBox6: TCheckBox;
    Label9: TLabel;
    Edit1: TEdit;
    procedure TVChange(Sender: TObject; Node: TTreeNode);
    procedure GroupChange(Sender: TObject);
    procedure SyntaxMemo1TextChanged(Sender: TObject; Pos, Count,
      LineChange: Integer);
    procedure CheckBox2Click(Sender: TObject);
    procedure SyntaxMemo4TextChanged(Sender: TObject; Pos, Count,
      LineChange: Integer);
    procedure SyntaxMemo3TextChanged(Sender: TObject; Pos, Count,
      LineChange: Integer);
    procedure AddGroupExecute(Sender: TObject);
    procedure HasSelectedCheck(Sender: TObject);
    procedure DeleteNodeExecute(Sender: TObject);
    procedure AddChildExecute(Sender: TObject);
    procedure actLoadExecute(Sender: TObject);
    procedure actSaveExecute(Sender: TObject);
    procedure Label2StartDrag(Sender: TObject;
      var DragObject: TDragObject);
    procedure TVDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure TVDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure Edit1Change(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    FSelfChange: Boolean;
    procedure SetGroup(Group: TecReplaceGroup);
    procedure SetItem(Item: TecReplaceItem);
    procedure SetItemEnbl(Item: TecReplaceItem);
    function AddItemToTree(Item: TecReplaceItem; Parent: TTreeNode): TTreeNode;
  public
    procedure FillTree;
  end;

implementation

{$R *.dfm}

procedure TMultiReplaceDlg.FormShow(Sender: TObject);
begin
  Label5.Transparent := False;
  Label6.Transparent := False;
  Label7.Transparent := False;
  Label8.Transparent := False;
end;

function TMultiReplaceDlg.AddItemToTree(Item: TecReplaceItem; Parent: TTreeNode): TTreeNode;
var i: integer;
begin
  Result := TV.Items.AddChild(Parent, Item.FindText);
  Result.ImageIndex := 1;
  Result.SelectedIndex := 1;
  Result.Data := Item;
  for i := 0 to Item.SubItems.Count - 1 do
    AddItemToTree(Item.SubItems[i], Result);
end;

procedure TMultiReplaceDlg.FillTree;
var i, j: integer;
    tn: TTreeNode;
begin
  TV.Items.BeginUpdate;
  try
    TV.Items.Clear;
    for i := 0 to Comp.Items.Count - 1 do
     begin
      tn := TV.Items.AddChild(nil, Comp.Items[i].DisplayName);
      tn.ImageIndex := 0;
      tn.SelectedIndex := 0;
      tn.Data := Comp.Items[i];
      for j := 0 to Comp.Items[i].Items.Count - 1 do
        AddItemToTree(Comp.Items[i].Items[j], tn);
     end;
  finally
    TV.Items.EndUpdate;
  end;
end;

procedure TMultiReplaceDlg.TVChange(Sender: TObject; Node: TTreeNode);
begin
  PageControl1.Visible := (TV.Selected <> nil);
  if TV.Selected <> nil then
    if TV.Selected.Level = 0 then
      begin
        PageControl1.ActivePageIndex := 0;
        SetGroup(TecReplaceGroup(TV.Selected.Data));
      end else
      begin
        PageControl1.ActivePageIndex := 1;
        SetItem(TecReplaceItem(TV.Selected.Data));
      end;
end;

procedure TMultiReplaceDlg.SetGroup(Group: TecReplaceGroup);
begin
  FSelfChange := True;
  with Group do
  try
    Edit2.Text := DisplayName;
    Edit3.Text := Category;
    Edit4.Text := IntToStr(GroupIndex);
    CheckBox1.Checked := OnlySelection;
    HotKey1.HotKey := ShortCut;
    SyntaxMemo1.Lines.Text := CheckStart;
    SyntaxMemo2.Lines.Text := Notes.Text;
  finally
    FSelfChange := False;
  end;
end;

function ToInt(const S: string): integer;
begin
  if S = '' then Result := 0 else
   try
     Result := StrToInt(S);
   except
     Result := 0;
   end;
end;

procedure TMultiReplaceDlg.GroupChange(Sender: TObject);
begin
  if FSelfChange or (TV.Selected = nil) then Exit;
  with TecReplaceGroup(TV.Selected.Data) do
  begin
    GroupIndex := ToInt(Edit4.Text);
    DisplayName := Edit2.Text;
    Category := Edit3.Text;
    OnlySelection := CheckBox1.Checked;
    ShortCut := HotKey1.HotKey;
    CheckStart := SyntaxMemo1.Lines.Text;
    Notes.Text := SyntaxMemo2.Lines.Text;
    TV.Selected.Text := DisplayName;
  end;
end;

procedure TMultiReplaceDlg.SyntaxMemo1TextChanged(Sender: TObject; Pos,
  Count, LineChange: Integer);
begin
  GroupChange(Sender);
end;

procedure TMultiReplaceDlg.SetItem(Item: TecReplaceItem);
begin
  FSelfChange := True;
  with Item do
  try
    SyntaxMemo4.Lines.Text := FindText;
    SyntaxMemo3.Lines.Text := ReplaceText;
    CheckBox2.Checked := rfRegularExpr in Flags;
    CheckBox3.Checked := rfReplaceTemplate in Flags;
    CheckBox4.Checked := rfCaseSensitive in Flags;
    CheckBox5.Checked := rfKeepPosition in Flags;
    CheckBox6.Checked := rfWordBreakBound in Flags;
    Edit1.Text := IntToStr(PassNumber);
    SetItemEnbl(Item);
  finally
    FSelfChange := False;
  end;
end;

procedure TMultiReplaceDlg.SetItemEnbl(Item: TecReplaceItem);
begin
  CheckBox3.Enabled := rfRegularExpr in Item.Flags;
  if rfRegularExpr in Item.Flags then
    SyntaxMemo4.SyntaxAnalyzer := SyntAnalyzer1
  else
    SyntaxMemo4.SyntaxAnalyzer := nil;

  if (rfRegularExpr in Item.Flags) and (rfReplaceTemplate in Item.Flags) then
    SyntaxMemo3.SyntaxAnalyzer := SyntAnalyzer2
  else
    SyntaxMemo3.SyntaxAnalyzer := nil;
end;

procedure TMultiReplaceDlg.CheckBox2Click(Sender: TObject);
var F: TecReplaceFlags;
begin
  if FSelfChange or (TV.Selected = nil) then Exit;
  F := [];
  if CheckBox2.Checked then Include(F, rfRegularExpr);
  if CheckBox3.Checked then Include(F, rfReplaceTemplate);
  if CheckBox4.Checked then Include(F, rfCaseSensitive);
  if CheckBox5.Checked then Include(F, rfKeepPosition);
  if CheckBox6.Checked then Include(F, rfWordBreakBound);
  TecReplaceItem(TV.Selected.Data).Flags := F;
  SetItemEnbl(TecReplaceItem(TV.Selected.Data));
end;

procedure TMultiReplaceDlg.SyntaxMemo4TextChanged(Sender: TObject; Pos,
  Count, LineChange: Integer);
begin
  if FSelfChange or (TV.Selected = nil) then Exit;
  TecReplaceItem(TV.Selected.Data).FindText := SyntaxMemo4.Lines.Text;
  TV.Selected.Text := TecReplaceItem(TV.Selected.Data).FindText;
end;

procedure TMultiReplaceDlg.SyntaxMemo3TextChanged(Sender: TObject; Pos,
  Count, LineChange: Integer);
begin
  if FSelfChange or (TV.Selected = nil) then Exit;
  TecReplaceItem(TV.Selected.Data).ReplaceText := SyntaxMemo3.Lines.Text;
end;

procedure TMultiReplaceDlg.Edit1Change(Sender: TObject);
begin
  if FSelfChange or (TV.Selected = nil) then Exit;
  TecReplaceItem(TV.Selected.Data).PassNumber := ToInt(Edit1.Text);
end;

procedure TMultiReplaceDlg.AddGroupExecute(Sender: TObject);
var g: TecReplaceGroup;
begin
  g := Comp.Items.Add;
  g.DisplayName := 'New group';
  with TV.Items.AddChild(nil, g.DisplayName) do
    begin
      ImageIndex := 0;
      SelectedIndex := 0;
      Data := g;
      Selected := True;
    end;
end;

procedure TMultiReplaceDlg.HasSelectedCheck(Sender: TObject);
begin
  TAction(Sender).Enabled := (TV.Selected <> nil);
end;

procedure TMultiReplaceDlg.DeleteNodeExecute(Sender: TObject);
begin
  TObject(TV.Selected.Data).Free;
  TV.Selected.Delete;
end;

procedure TMultiReplaceDlg.AddChildExecute(Sender: TObject);
begin
  if TV.Selected.Level = 0 then
    AddItemToTree(TecReplaceGroup(TV.Selected.Data).Items.Add, TV.Selected).Selected := True
  else
    AddItemToTree(TecReplaceItem(TV.Selected.Data).SubItems.Add, TV.Selected).Selected := True;
end;

procedure TMultiReplaceDlg.actLoadExecute(Sender: TObject);
begin
  if OpenDialog1.Execute then
   begin
    Comp.LoadFromFile(OpenDialog1.FileName);
    FillTree;
   end;
end;

procedure TMultiReplaceDlg.actSaveExecute(Sender: TObject);
begin
  if SaveDialog1.Execute then
    Comp.SaveToFile(SaveDialog1.FileName);
end;

procedure TMultiReplaceDlg.Label2StartDrag(Sender: TObject;
  var DragObject: TDragObject);
begin
  if (TV.Selected = nil) or (TV.Selected.Level = 0) then
    CancelDrag;
end;

procedure TMultiReplaceDlg.TVDragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
var tn: TTreeNode;
begin
  tn := TV.GetNodeAt(X, Y);
  Accept := (Source = TV) and (tn <> nil) and (tn <> TV.Selected);
end;

procedure TMultiReplaceDlg.TVDragDrop(Sender, Source: TObject; X,
  Y: Integer);
var tn: TTreeNode;
    Item: TecReplaceItem;
begin
  tn := TV.GetNodeAt(X, Y);
  if tn.Level = 0 then
    Item := TecReplaceGroup(tn.Data).Items.Add
  else
    Item := TecReplaceItem(tn.Data).SubItems.Add;
  Item.Assign(TecReplaceItem(TV.Selected.Data));
  AddItemToTree(Item, TV.Selected).Selected := True;
end;

end.
