{*****************************************************************************
 *
 *  FMSearch.pas - Search Mails and Addresses  (12-September-1998)
 *
 *  Copyright (c) 1998-99 Michael Haller
 *
 *  Author:     Michael Haller
 *  E-mail:     michael@discountdrive.com
 *  Homepage:   http://www.discountdrive.com/sunrise
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation;
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 *
 *----------------------------------------------------------------------------
 *
 *  Revision history:
 *
 *     DATE     REV                 DESCRIPTION
 *  ----------- --- ----------------------------------------------------------
 *
 *****************************************************************************}

unit FMSearch;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
//  Roland,
  GradForm,
  StdCtrls, ComCtrls, PXStuff, StatusBarEx, ExtListView,
  ExtCtrls, ComboBoxEx, Menus, EnhListView{, RichEdit2};

type
  TmenSearchForm = class(TdfsGradientForm)
    pnlResult: TPanel;
    lvwResult: TdfsExtListView;
    StatusBarEx1: TStatusBarEx;
    Panel1: TPanel;
    Panel2: TPanel;
    btnFind: TButton;
    btnStop: TButton;
    btnClose: TButton;
    Animate1: TAnimate;
    Panel3: TPanel;
    TabSheet1: TTabSheet;
    Label1: TLabel;
    Label2: TLabel;
    cboSearchIn: TPMComboBoxEx;
    cboFindText: TComboBox;
    TabSheet3: TTabSheet;
    nbOptions: TNotebook;
    menchkFirst: TCheckBox;
    menchkLast: TCheckBox;
    menchkEmail: TCheckBox;
    menchkDescription: TCheckBox;
    menchkPhone: TCheckBox;
    menchkAddress: TCheckBox;
    chkMatchCase: TCheckBox;
    chkSubfolder: TCheckBox;
    PopupMenu1: TPopupMenu;
    Jumpto1: TMenuItem;
    chkSubject: TCheckBox;
    chkBody: TCheckBox;
    chkSender: TCheckBox;
    chkReceiver: TCheckBox;
    chkKeywords: TCheckBox;
    Label8: TLabel;
    Bevel4: TBevel;
    menchkDate: TCheckBox;
    menButtonSelectAll: TButton;
    menButtonSelectNone: TButton;
    ButtonMarkAll: TButton;
    ButtonMarkNone: TButton;
    btnBrowse: TButton;
    PageControl1: TPageControl;
    procedure FormCreate(Sender: TObject);
    procedure btnFindClick(Sender: TObject);
    procedure cboFindTextChange(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure btnCloseClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure btnBrowseClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Panel3Resize(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Jumpto1Click(Sender: TObject);
    procedure PopupMenu1Popup(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure menButtonSelectAllClick(Sender: TObject);
    procedure menButtonSelectNoneClick(Sender: TObject);
    procedure ButtonMarkAllClick(Sender: TObject);
    procedure ButtonMarkNoneClick(Sender: TObject);
  private
    { Private declarations }
    fSearchMode: Byte;
    procedure DoSearch;
    procedure StopSearch;
    procedure DoSearchAddress;
    procedure DoSearchMessage;
    procedure EnableControls(AEnable: boolean);
  public
    { Public declarations }
    procedure DoRemoteMove(oldfile, newfile : string);
    property SearchMode: Byte read fSearchMode write fSearchMode;
  end;

const
  smMessage = 0;
  smAddress = 1;

var
  menSearchForm: TmenSearchForm;

implementation

{$R *.DFM}

uses
  Main, FMAddress, FMMoveMessage, IniFiles, ParserSup;

var
  bStopSearch: boolean;
  sFindText: string;
  bSearching: boolean;

procedure TmenSearchForm.FormCreate(Sender: TObject);
var
  IniFile: TIniFile;
begin
  PageControl1.activepage:=TabSheet1;
  Height := 215;
  Constraints.MaxHeight := 215;
  Top := 150;
  Left := 170;

  if (byGlobalSearchMode = smMessage) then FormStyle := fsNormal
  else FormStyle := fsStayOnTop;

  IniFile := TIniFile.Create(sSettingsFile);
  try
    with IniFile do begin
      chkMatchCase.Checked := ReadBool('Search', 'MatchCase', false);

      chkSubfolder.Checked := ReadBool('Search', 'Subfolder', true);
      chkSubject.Checked := ReadBool('Search', 'Subject', true);
      chkBody.Checked := ReadBool('Search', 'Body', true);
      chkSender.Checked := ReadBool('Search', 'Sender', true);
      chkReceiver.Checked := ReadBool('Search', 'Receiver', true);
      chkKeywords.Checked := ReadBool('Search', 'Keywords', true);

      menchkFirst.Checked := ReadBool('Search', 'First', true);
      menchkLast.Checked := ReadBool('Search', 'Last', true);
      menchkEmail.Checked := ReadBool('Search', 'Email', true);
      menchkDescription.Checked := ReadBool('Search', 'Description', true);
      menchkDate.Checked := ReadBool('Search', 'Date', true);
      menchkPhone.Checked := ReadBool('Search', 'Phone', true);
      menchkAddress.Checked := ReadBool('Search', 'Address', true);

      // Form Position
      case IniFile.ReadInteger('Position', 'SearchState', 1) of
        0, 1: begin
            WindowState := wsNormal;
            Width := IniFile.ReadInteger('Position', 'SearchWidth', Width);
            Height := IniFile.ReadInteger('Position', 'SearchHeight', Height);
            Top := IniFile.ReadInteger('Position', 'SearchTop', Top);
            Left := IniFile.ReadInteger('Position', 'SearchLeft', Left);
          end;
        2: WindowState := wsMaximized;
      end;
    end;
  finally
    IniFile.Free;

  end;
end;

procedure TmenSearchForm.btnFindClick(Sender: TObject);
begin
  if Height = 215 then begin
    Constraints.MaxHeight := 0;
    Height := 426;
  end;
  bStopSearch := false;
  DoSearch;
end;

procedure TmenSearchForm.cboFindTextChange(Sender: TObject);
begin
  btnFind.Enabled := Length(cboFindText.Text) > 0;
end;

procedure TmenSearchForm.EnableControls(AEnable: boolean);
begin
  btnFind.Enabled := AEnable;
  btnClose.Enabled := AEnable;

  cboFindText.Enabled := AEnable;
  Label1.Enabled := AEnable;
  cboSearchIn.Enabled := AEnable;
  Label2.Enabled := AEnable;
  btnBrowse.Enabled := AEnable;
  chkSubfolder.Enabled := AEnable;
  chkMatchCase.Enabled := AEnable;

  chkSubject.Enabled := AEnable;
  chkBody.Enabled := AEnable;
  chkSender.Enabled := AEnable;
  chkReceiver.Enabled := AEnable;
  chkKeywords.Enabled := AEnable;

  menchkFirst.Enabled := AEnable;
  menchkLast.Enabled := AEnable;
  menchkEmail.Enabled := AEnable;
  menchkDescription.Enabled := AEnable;
  menchkDate.Enabled := AEnable;
  menchkPhone.Enabled := AEnable;
  menchkAddress.Enabled := AEnable;
end;

procedure TmenSearchForm.DoSearch;
var
  i: integer;
begin
  Animate1.Active := true;
  btnStop.Enabled := true;
  lvwResult.Items.Clear;
  StatusBarEx1.Panels[0].Text := Format(GetMessageString(111), ['0']);
  sFindText := cboFindText.Text;
  i := cboFindText.Items.IndexOf(sFindText);
  if cboFindText.Text <> '' then begin
    if i > -1 then
      cboFindText.Items.Delete(i);
    cboFindText.Items.Insert(0, sFindText);
  end;
  EnableControls(false);
  cboFindText.Text := sFindText;
  Application.ProcessMessages;
  bSearching := true;
  if fSearchMode = smAddress then
    DoSearchAddress
  else
    DoSearchMessage;
end;

procedure TmenSearchForm.DoSearchAddress;
var
  Found: Integer;
  SearchRec: TSearchRec;
  c: Byte;
  f: string;

  procedure AddAddress(const AName, ABook: string);
  var
    li: TListItem;
    aaFile: string;
  begin
    Application.ProcessMessages;
    if bStopSearch then Exit;
    aaFile := ExtractFileName(ABook);
    Delete(aaFile, Length(aaFile) - 3, 4);
    li := lvwResult.Items.Add;
    li.Caption := AName;
    li.SubItems.Add(aaFile);
    // AH08
    StatusBarEx1.Panels[0].Text := Format(GetMessageString(111), [IntToStr(lvwResult.Items.Count)]);
  end;

  procedure SearchBook(const Filename: string; Compare: Byte);
  var
    sl,AddressInfo: TStringList;
    S1, S2, S3, S4, S5, S6, S7: string;
    i, I1: integer;
  label
    final;
  begin
    sl := TStringList.Create;
    AddressInfo:= TStringList.Create;
    try
      sl.LoadFromFile(Filename);
      StatusBarEx1.Panels[1].Text := CompactPath(Filename,
        Width - StatusBarEx1.Panels[0].Width - 20, Canvas.Handle);
      Application.ProcessMessages;
      if bStopSearch then Exit;
      for i := 1 to sl.Count - 1 do begin
        FromAddressFormat(sl[i], AddressInfo);
        Application.ProcessMessages;
        if bStopSearch then Exit;
        if menchkFirst.Checked then begin
          if InStr(0, AddressInfo[0], sFindText, Compare) > 0 then begin
            AddAddress(AddressInfo[0]+ ' <' + AddressInfo[1] + '>', Filename);
            goto final;
          end;
        end;
{        if menchkLast.Checked then begin
          if InStr(0, S2, sFindText, Compare) > 0 then begin
            AddAddress(S1 + ' ' + S2 + ' <' + S3 + '>', Filename);
            goto final;
          end;
        end;
        if menchkDescription.Checked then begin
          if InStr(0, S7, sFindText, Compare) > 0 then begin
            AddAddress(S1 + ' ' + S2 + ' <' + S3 + '>', Filename);
            goto final;
          end;
        end;
        if menchkDate.Checked then begin
          if InStr(0, S6, sFindText, Compare) > 0 then begin
            AddAddress(S1 + ' ' + S2 + ' <' + S3 + '>', Filename);
            goto final;
          end;
        end; }
        if menchkEmail.Checked then begin
          if InStr(0, AddressInfo[1], sFindText, Compare) > 0 then begin
            AddAddress(AddressInfo[0] +  ' <' + AddressInfo[1] + '>', Filename);
            goto final;
          end;
        end;
        if menchkPhone.Checked then begin
          if InStr(0, AddressInfo[2], sFindText, Compare) > 0 then begin
            AddAddress(AddressInfo[0]  + ' <' + AddressInfo[1] + '>', Filename);
            goto final;
          end;
        end;
        if menchkAddress.Checked then begin
          if InStr(0, AddressInfo[23], sFindText, Compare) > 0 then
            AddAddress(AddressInfo[0] + ' <' + AddressInfo[1] + '>', Filename);
        end;
        final:
      end;
    finally
      sl.Free;
      AddressInfo.Free;
    end;
  end;
begin
  // sreach an address
  if chkMatchCase.Checked then
    c := 0
  else
    c := 1;
  if cboSearchIn.ItemIndex = 0 then begin
    // all books
    f := MakeValidDirName(sAddressBookFolder);
    Found := FindFirst(f + '*.ssf', faAnyFile, SearchRec);
    while Found = 0 do begin
      SearchBook(f + SearchRec.Name, c);
      Found := FindNext(SearchRec);
      Application.ProcessMessages;
      if bStopSearch then Break;
    end;
    FindClose(SearchRec);
  end else begin
    // one book
    f := cboSearchIn.Values[cboSearchIn.ItemIndex];
    SearchBook(f, c)
  end;
  StopSearch;
end;

procedure TmenSearchForm.DoSearchMessage;
  procedure ParseMail(const AFilename: string; var ASubject, ABody, ASender,
    AReceiver, AKeyWords: string);
  var
    sl: TStringList;
    S1, S2: string;
    i, j: integer;
  begin
    ABody := '';
    sl := TStringList.Create;
    try
      sl.LoadFromFile(AFilename);
      for I := 0 to sl.Count - 1 do begin
        Application.ProcessMessages;
        if bStopSearch then Exit;
        GetFieldArguments(sl[I], S1, S2);
        if CompareText(S1, 'from') = 0 then
          ASender := SkipChar(S2, '"')
        else if CompareText(S1, 'subject') = 0 then
          ASubject := S2
        else if CompareText(S1, 'to') = 0 then
          AReceiver := SkipChar(S2, '"')
        else if CompareText(S1, 'keywords') = 0 then
          AKeywords := S2
        else if CompareText(S1, 'content-transfer-encoding') = 0 then
          Break
        else if chkBody.Checked then
          ABody := Abody + sl[i];
      end;
      if chkBody.Checked then begin
        // only when body should be searched, save some time
        for j := i to sl.Count - 1 do begin
          Application.ProcessMessages;
          if bStopSearch then Exit;
          ABody := ABody + sl[j];
        end;
      end;
    finally
      sl.Free;
    end;
  end;

  function CompareField(AIn: string; c: Byte): boolean;
  begin
    Result := (InStr(0, AIn, sFindText, c) > 0);
  end;

  procedure AddMessage(ASubject, AFolder, AFile: string);
  var
    li: TListItem;
  begin
    Application.ProcessMessages;
    if bStopSearch then Exit;
    li := lvwResult.Items.Add;
    li.Caption := ASubject;
    li.SubItems.Add(AFolder);
    li.SubItems.Add(AFile); // Hidden
    StatusBarEx1.Panels[0].Text := IntToStr(lvwResult.Items.Count) + ' Objects';
  end;

  procedure SearchFolder(AFolder: string);
  var
    f: string;
    Subject, Body, Sender, Receiver, KeyWords: string;
    Found: integer;
    SearchRec: TSearchRec;
    c: Byte;
  label
    final;
  begin
    if chkMatchCase.Checked then
      c := 0
    else
      c := 1;
    f := MakeValidDirName(AFolder);
    Found := FindFirst(f + '*.msg', faAnyFile, SearchRec); //AH11 was *.msg
    while Found = 0 do begin
      StatusBarEx1.Panels[1].Text := CompactPath(f + SearchRec.Name,
        Width - StatusBarEx1.Panels[0].Width - 20, Canvas.Handle);
      Application.ProcessMessages;
      if bStopSearch then Break;
      ParseMail(f + SearchRec.Name, Subject, Body, Sender, Receiver, KeyWords);
      if chkSubject.Checked then
        if CompareField(Subject, c) then begin
          AddMessage(Subject, f, f + SearchRec.Name);
          goto final;
        end;
      if chkBody.Checked then
        if CompareField(Body, c) then begin
          AddMessage(Subject, f, f + SearchRec.Name);
          goto final;
        end;
      if chkSender.Checked then
        if CompareField(Sender, c) then begin
          AddMessage(Subject, f, f + SearchRec.Name);
          goto final;
        end;
      if chkReceiver.Checked then
        if CompareField(Receiver, c) then begin
          AddMessage(Subject, f, f + SearchRec.Name);
          goto final;
        end;
      if chkKeyWords.Checked then
        if CompareField(Keywords, c) then
          AddMessage(Subject, f, f + SearchRec.Name);
      final:
      Found := FindNext(SearchRec);
      Application.ProcessMessages;
      if bStopSearch then Break;
    end;
    FindClose(SearchRec);
  end;

  procedure RecurseDirs(Dir: string);
  var
    SearchRec: TSearchRec;
    Found: Integer;
  begin
    Found := FindFirst(Dir + '*.*', $37, SearchRec);
    while Found = 0 do begin
      Application.ProcessMessages;
      if bStopSearch then Break;
      if (SearchRec.Attr and $10 = $10) and (SearchRec.Name <> '.') and
        (SearchRec.Name <> '..') then begin
        SearchFolder(Dir + SearchRec.Name);
        Application.ProcessMessages;
        if bStopSearch then Break;
        RecurseDirs(Dir + SearchRec.Name + '\');
      end;
      Found := FindNext(SearchRec);
    end;
    FindClose(SearchRec);
  end;

begin
  // search a message
  SearchFolder(cboSearchIn.Values[cboSearchIn.ItemIndex]);
  if chkSubfolder.Checked then
    RecurseDirs(cboSearchIn.Values[cboSearchIn.ItemIndex]);
  StopSearch;
end;

procedure TmenSearchForm.StopSearch;
begin
  bStopSearch := true;
  bSearching := false;
  Animate1.Active := false;
  btnStop.Enabled := false;
  sFindText := '';
  StatusBarEx1.Panels[1].Text := '';
  EnableControls(true);
  Application.ProcessMessages;
end;

procedure TmenSearchForm.btnStopClick(Sender: TObject);
begin
  StopSearch;
end;

procedure TmenSearchForm.btnCloseClick(Sender: TObject);
begin
  bSearchName := false;
  bSearchDate := false;
  Close;
end;

procedure TmenSearchForm.FormShow(Sender: TObject);
var
  s : TTreeNode;
  SearchRec: TSearchRec;
  sName:string;
  Found,i:integer;
begin
  SetWindowLong(Handle, GWL_ExStyle, WS_Ex_AppWindow);
  btnBrowse.Visible := (fSearchMode = smMessage);
  chkSubfolder.Visible := (fSearchMode = smMessage);
  if (fSearchMode = smMessage) then begin
    nbOptions.PageIndex := 0;
    cboSearchIn.Images := MainForm.ImageList1;
    lvwResult.Columns[0].Caption := GetMessageString(112);
    lvwResult.Columns[1].Caption := GetMessageString(113);
    if FileExists(GetAppPath + 'mfhis.txt') then
      cboFindText.Items.LoadFromFile(GetAppPath + 'mfhis.txt');

    s := MainForm.TreeView1.Items.GetFirstNode;
    while s <> nil do
    begin
      cboSearchIn.Items.Add(s.Text);
      case s.StateIndex of
      tnThrashBag:  cboSearchIn.Values.Add(sTrashFolder);
      tnAccounts:   cboSearchIn.Values.Add(sAccountRootFolder);
      tnRepository: cboSearchIn.Values.Add(sRepositoryFolder);
      tnStationary:  cboSearchIn.Values.Add(sStationaryFolder);
      end;
      cboSearchIn.ImgIndexes.Add(IntToStr(s.ImageIndex));
      s := s.getNextSibling;
    end;
    cboSearchIn.ItemIndex := 0;
    cboSearchIn.Invalidate;
  end else begin

    nbOptions.PageIndex := 1;
    Found := FindFirst(sAddressBookFolder + '*.ssf', faAnyFile, SearchRec);
    while Found = 0 do
    begin
      sName := SearchRec.Name;
      Delete(sName, Length(sName) - 3, 4);
      cboSearchIn.Items.Add(sName);
      cboSearchIn.Values.Insert(i, sAddressBookFolder + SearchRec.Name);
      i:=i+1;
      Found := FindNext(SearchRec);
    end;
    FindClose(SearchRec);



    cboSearchIn.Images := AddressForm.ImageList1;

    cboSearchIn.ImgIndexes := AddressForm.ComboBox1.ImgIndexes;
    cboSearchIn.Items.Insert(0, '<ËùÓÐÄ¿Â¼>');
    cboSearchIn.ImgIndexes.Insert(0, '-1');
    cboSearchIn.Values.Insert(0, '');
    cboSearchIn.ItemIndex := 0;

    lvwResult.Columns[0].Caption := GetMessageString(139);
    lvwResult.Columns[1].Caption := GetMessageString(140);
    if FileExists(GetAppPath + 'afhis.txt') then
      cboFindText.Items.LoadFromFile(GetAppPath + 'afhis.txt');
  end;
  SetForeGroundWindow(menSearchForm.Handle);
end;

procedure TmenSearchForm.btnBrowseClick(Sender: TObject);
var
  dlg: TfrmMoveMessage;
  i: integer;
begin
  dlg := TfrmMoveMessage.Create(Self);
  if Assigned(LangHolder) then
  begin
    if LangHolder.Language <> '' then
      LangHolder.Translate([dlg]);
  end;

  try
    with dlg.TreeView1 do begin
      Items := MainForm.TreeView1.Items;
      FullExpand;
      // AHRK95-- AlphaSort;
      // AHRK90
      if MainForm.TreeView1.Selected <> nil then
      begin
        Items[MainForm.TreeView1.Selected.AbsoluteIndex].Selected := True;
      end;
    end;

    //dlg.CurrentDir := MakeValidDirName(PFolderData(MainForm.TreeView1.Selected.Data)^.Path);
    // AH08
    dlg.Caption := GetMessageString(116);
    if dlg.ShowModal = mrOK then begin
      i := cboSearchIn.Items.IndexOf(dlg.GetSearchPathName);
      if i > -1 then begin
        cboSearchIn.Items.Delete(i);
        cboSearchIn.Values.Delete(i);
        cboSearchIn.ImgIndexes.Delete(i);
      end;
      cboSearchIn.Items.Insert(0, dlg.GetSearchPathName);
      cboSearchIn.ItemIndex := 0;
      cboSearchIn.Values.Insert(0, dlg.GetSelectedPath);
      cboSearchIn.ImgIndexes.Insert(0, IntToStr(dlg.TreeView1.Selected.ImageIndex));
      cboSearchIn.Invalidate;
    end;
  finally
    dlg.Free;
  end;
end;

procedure TmenSearchForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
  IniFile: TIniFile;
begin
  IniFile := TIniFile.Create(sSettingsFile);
  try
    with IniFile do begin
      WriteBool('Search', 'MatchCase', chkMatchCase.Checked);

      WriteBool('Search', 'Subfolder', chkSubfolder.Checked);
      WriteBool('Search', 'Subject', chkSubject.Checked);
      WriteBool('Search', 'Body', chkBody.Checked);
      WriteBool('Search', 'Sender', chkSender.Checked);
      WriteBool('Search', 'Receiver', chkReceiver.Checked);
      ReadBool('Search', 'Keywords', chkKeywords.Checked);

      WriteBool('Search', 'First', menchkFirst.Checked);
      WriteBool('Search', 'Last', menchkLast.Checked);
      WriteBool('Search', 'Email', menchkEmail.Checked);
      WriteBool('Search', 'Description', menchkDescription.Checked);
      WriteBool('Search', 'Date', menchkDate.Checked);
      WriteBool('Search', 'Phone', menchkPhone.Checked);
      WriteBool('Search', 'Address', menchkAddress.Checked);

      if WindowState = wsNormal then begin
        WriteInteger('Position', 'SearchState', 1);
        WriteInteger('Position', 'SearchWidth', Width);
        WriteInteger('Position', 'SearchHeight', Height);
        WriteInteger('Position', 'SearchTop', Top);
        WriteInteger('Position', 'SearchLeft', Left);
      end;
      if WindowState = wsMaximized then
        WriteInteger('Position', 'SearchState', 2);
    end;
  finally
    IniFile.Free;
  end;
  if cboFindText.Items.Count > 0 then begin
    if (fSearchMode = smMessage) then
      cboFindText.Items.SaveToFile(GetAppPath + 'mfhis.txt')
    else
      cboFindText.Items.SaveToFile(GetAppPath + 'afhis.txt');
  end;
  Action := caFree;
end;

procedure TmenSearchForm.Panel3Resize(Sender: TObject);
begin
  try
    PageControl1.Width := Panel3.Width - 15;
    cboFindText.Width := Panel3.Width - 111;
    cboSearchIn.Width := Panel3.Width - 111;
    btnBrowse.Left := Panel3.Width - 120;
    Bevel4.Width := Panel3.Width - 35;
  except end;
end;

procedure TmenSearchForm.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  if bSearching then begin
    Application.MessageBox(PChar(GetMessageString(114)),
      PChar(GetMessageString(116)), MB_ICONSTOP + MB_OK);
    CanClose := false;
  end;
end;

procedure TmenSearchForm.Jumpto1Click(Sender: TObject);
var
  i, j, findpos : integer;
  s: boolean;
//  lType : TSearchTypes98;
  tstring : string;
begin

  if lvwResult.Selected = nil then Exit;
  s := false;
  if (fSearchMode = smMessage) then begin
    with MainForm.TreeView1 do begin
      for i := 1 to Items.Count - 1 do begin
        if CompareText(lvwResult.Selected.SubItems[0], sRepositoryFolder) = 0 then begin
          RepositoryNode.Selected := true;
          s := true;
        end else if CompareText(lvwResult.Selected.SubItems[0], sTrashFolder) = 0 then begin
          TrashNode.Selected := true;
          s := true;
        end
          else if CompareText(lvwResult.Selected.SubItems[0], sStationaryFolder) = 0 then begin // AH03
            StationaryNode.Selected := true;
            s := true;
          end  else if Items[i].StateIndex = tnFolder then begin
                 if CompareText(PFolderData(Items[i].Data)^.Path,
                     lvwResult.Selected.SubItems[0]) = 0 then begin
                     Items[i].Selected := true;
                     s := true;
                     Break;
                     end;
                end;
        Application.ProcessMessages;
      end;
    end;
    if s then begin
      with MainForm.ListView1 do begin
        Items.BeginUpdate;
        for i := 0 to Items.Count - 1 do begin
          if CompareText(Items[i].Subitems[ciFileName],
            lvwResult.Selected.Subitems[1]) = 0 then
            Break;
        end;
        for j := 0 to Items.Count - 1 do
          Items[j].Selected := false;
        Items[i].Selected := true;
        Items[i].MakeVisible(false);
        Items.EndUpdate;
        Invalidate;
      end;
      MainForm.UpdateListView;
      // AH02
  //    findpos := MainForm.RichEdit1.FindText(cboFindText.text, 1, Length(MainForm.RichEdit1.Text), ltype);
      findpos := InStr(0, MainForm.RichEdit1.Text, cboFindText.Text, Ord( not chkMatchCase.Checked));
      if findpos > 0 then
      begin
        tstring := Copy(MainForm.RichEdit1.Text, 1, findpos + Length(cboFindText.Text));
        tstring := StringReplace(tstring, #13#10, ' ', [rfReplaceAll]);
        findpos := Instr(0, tstring, cboFindText.Text, Ord(not chkMatchCase.Checked));
        if findpos > 0 then
        begin
          MainForm.RichEdit1.SelStart := findpos -1;
          MainForm.RichEdit1.SelLength := Length(cboFindText.Text);
        end;
      end;
      // AH02
    end
  end else begin
    if not AddressForm.visible then AddressForm.show;
    AddressForm.ComboBox1.ItemIndex :=
      AddressForm.ComboBox1.Items.IndexOf(lvwResult.Selected.SubItems[0]);
    AddressForm.ComboBox1Change(Self);
    Application.ProcessMessages;
//    Fehler(Handle,'hier');
    with AddressForm.AdrBookListView do begin
      Items.BeginUpdate;
      for i := 0 to Items.Count - 1 do begin
        if CompareText(lvwResult.Selected.Caption, Items[i].SubItems[0] + ' ' +
          Items[i].SubItems[1] + ' <' + Items[i].SubItems[3] + '>') = 0 then
          Break;
      end;
      for j := 0 to Items.Count - 1 do
        Items[j].Selected := false;
        //Fehler(Handle,inttostr(i));
      if i < Items.Count - 1 then
      begin
        Items[i].Selected := true;
         //Fehler(Handle,'hier');
        Items[i].MakeVisible(false);
      end;
      Items.EndUpdate;
      Invalidate;
    end;
  end;
end;

procedure TmenSearchForm.PopupMenu1Popup(Sender: TObject);
begin
  Jumpto1.Enabled := (lvwResult.Selected <> nil);
end;

procedure TmenSearchForm.FormDestroy(Sender: TObject);
begin
  menSearchForm := nil;
end;

procedure TmenSearchForm.menButtonSelectAllClick(Sender: TObject);
begin
  menchkFirst.checked := true;
  menchkLast.checked := true;
  menchkDescription.checked := true;
  menchkDate.checked := true;
  menchkEMail.checked := true;
  menchkPhone.checked := true;
  menchkAddress.checked := true;
end;

procedure TmenSearchForm.menButtonSelectNoneClick(Sender: TObject);
begin
  menchkFirst.checked := false;
  menchkLast.checked := false;
  menchkDescription.checked := false;
  menchkDate.checked := false;
  menchkEMail.checked := false;
  menchkPhone.checked := false;
  menchkAddress.checked := false;
end;

procedure TmenSearchForm.ButtonMarkAllClick(Sender: TObject);
begin
  chkSubject.checked := true;
  chkBody.checked := true;
  chkSender.checked := true;
  chkReceiver.checked := true;
  chkKeywords.checked := true;
end;

procedure TmenSearchForm.ButtonMarkNoneClick(Sender: TObject);
begin
  chkSubject.checked := false;
  chkBody.checked := false;
  chkSender.checked := false;
  chkReceiver.checked := false;
  chkKeywords.checked := false;
end;


procedure TmenSearchForm.DoRemoteMove(oldfile, newfile : string);
var x : integer;
begin
  if lvwResult.Items.Count > 0 then
  begin
    x := 0;
    while x < lvwResult.Items.Count do
    begin
      if pos(lvwResult.Items[x].SubItems[1], oldfile) = 1 then
      begin
        if newfile = '' then
          lvwResult.Items[x].Delete
        else
          lvwResult.Items[x].SubItems[1] := newfile;
      end;
      inc(x);
    end;
  end;
end;

initialization
   PMRegistry.AddCustomClass(TmenSearchForm, 'TSearchForm');


end.
