doublecmd/src/fFindDlg.pas
Alexander Koblov 401416afba FIX: Create archives using plug-ins with hidden flag
UPD: Use poOwnerFormCenter for pack/extract dialogs
2016-11-07 18:32:18 +00:00

2176 lines
61 KiB
ObjectPascal

{
Double Commander
-------------------------------------------------------------------------
Find dialog, with searching in thread
Copyright (C) 2003-2004 Radek Cervinka (radek.cervinka@centrum.cz)
Copyright (C) 2006-2015 Alexander Koblov (alexx2000@mail.ru)
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; either version 2 of the License, or
(at your option) any later version.
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
}
unit fFindDlg;
{$mode objfpc}{$H+}
{$include calling.inc}
interface
uses
Graphics, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ComCtrls,
ExtCtrls, Menus, EditBtn, Spin, Buttons, DateTimePicker, KASComboBox,
fAttributesEdit, uDsxModule, DsxPlugin, uFindThread, uFindFiles,
uSearchTemplate, fSearchPlugin, uFileView, types, DCStrUtils, ShellCtrls,
ActnList, uOSForms, uShellContextMenu, uExceptions, uFileSystemFileSource,
uFormCommands, uHotkeyManager;
const
HotkeysCategory = 'Find files';
type
{ TfrmFindDlg }
TfrmFindDlg = class(TForm,IFormCommands)
actIntelliFocus: TAction;
actCancel: TAction;
actClose: TAction;
actEdit: TAction;
actGoToFile: TAction;
actFeedToListbox: TAction;
actCancelClose: TAction;
actPageResults: TAction;
actPageLoadSave: TAction;
actPagePlugins: TAction;
actPageAdvanced: TAction;
actPageStandard: TAction;
actView: TAction;
actLastSearch: TAction;
actNewSearch: TAction;
actStart: TAction;
actList: TActionList;
Bevel2: TBevel;
btnAddAttribute: TButton;
btnAttrsHelp: TButton;
btnClose: TButton;
btnGoToPath: TButton;
btnNewSearch: TButton;
btnLastSearch: TButton;
btnSaveTemplate: TButton;
btnSearchDelete: TButton;
btnSearchLoad: TButton;
btnSearchSave: TButton;
btnSearchSaveWithStartingPath: TButton;
btnStart: TButton;
btnUseTemplate: TButton;
btnStop: TButton;
btnView: TButton;
btnEdit: TButton;
btnWorkWithFound: TButton;
cbFindText: TCheckBox;
cbNotContainingText: TCheckBox;
cbDateFrom: TCheckBox;
cbNotOlderThan: TCheckBox;
cbFileSizeFrom: TCheckBox;
cbDateTo: TCheckBox;
cbFileSizeTo: TCheckBox;
cbReplaceText: TCheckBox;
cbTimeFrom: TCheckBox;
cbTimeTo: TCheckBox;
cbPartialNameSearch: TCheckBox;
cbFollowSymLinks: TCheckBox;
cbUsePlugin: TCheckBox;
cbSelectedFiles: TCheckBox;
cbTextRegExp: TCheckBox;
cbFindInArchive: TCheckBox;
cbOpenedTabs: TCheckBox;
cmbExcludeDirectories: TComboBoxWithDelItems;
cmbNotOlderThanUnit: TComboBox;
cmbFileSizeUnit: TComboBox;
cmbEncoding: TComboBox;
cmbSearchDepth: TComboBox;
cbRegExp: TCheckBox;
cmbPlugin: TComboBox;
cmbReplaceText: TComboBoxWithDelItems;
cmbFindText: TComboBoxWithDelItems;
cmbExcludeFiles: TComboBoxWithDelItems;
edtAttrib: TEdit;
edtFindPathStart: TDirectoryEdit;
frmContentPlugins: TfrmSearchPlugin;
gbDirectories: TGroupBox;
gbFiles: TGroupBox;
lblAttributes: TLabel;
lblExcludeDirectories: TLabel;
lblCurrent: TLabel;
lblExcludeFiles: TLabel;
lblFound: TLabel;
lblStatus: TLabel;
lblTemplateHeader: TLabel;
lbSearchTemplates: TListBox;
lblSearchContents: TPanel;
lblSearchDepth: TLabel;
lblEncoding: TLabel;
lsFoundedFiles: TListBox;
CheksPanel: TPanel;
miOpenInNewTab: TMenuItem;
miShowInEditor: TMenuItem;
miShowAllFound: TMenuItem;
miRemoveFromLlist: TMenuItem;
pnlDirectoriesDepth: TPanel;
pnlLoadSaveBottomButtons: TPanel;
pnlLoadSaveBottom: TPanel;
pnlButtons: TPanel;
pnlResultsBottomButtons: TPanel;
pnlResults: TPanel;
pnlStatus: TPanel;
pnlResultsBottom: TPanel;
seNotOlderThan: TSpinEdit;
seFileSizeFrom: TSpinEdit;
seFileSizeTo: TSpinEdit;
pnlFindFile: TPanel;
pgcSearch: TPageControl;
tsPlugins: TTabSheet;
tsResults: TTabSheet;
tsLoadSave: TTabSheet;
tsStandard: TTabSheet;
lblFindPathStart: TLabel;
lblFindFileMask: TLabel;
cmbFindFileMask: TComboBoxWithDelItems;
gbFindData: TGroupBox;
cbCaseSens: TCheckBox;
tsAdvanced: TTabSheet;
PopupMenuFind: TPopupMenu;
miShowInViewer: TMenuItem;
ZVDateFrom: TDateTimePicker;
ZVDateTo: TDateTimePicker;
ZVTimeFrom: TDateTimePicker;
ZVTimeTo: TDateTimePicker;
procedure actExecute(Sender: TObject);
procedure btnAddAttributeClick(Sender: TObject);
procedure btnAttrsHelpClick(Sender: TObject);
procedure btnEditClick(Sender: TObject);
procedure btnLastSearchClick(Sender: TObject);
procedure btnNewSearchKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure btnSearchDeleteClick(Sender: TObject);
procedure btnSearchLoadClick(Sender: TObject);
procedure btnSearchSaveWithStartingPathClick(Sender: TObject);
procedure btnSearchSaveClick(Sender: TObject);
procedure cbCaseSensChange(Sender: TObject);
procedure cbDateFromChange(Sender: TObject);
procedure cbDateToChange(Sender: TObject);
procedure cbFindInArchiveChange(Sender: TObject);
procedure cbOpenedTabsChange(Sender: TObject);
procedure cbPartialNameSearchChange(Sender: TObject);
procedure cbRegExpChange(Sender: TObject);
procedure cbTextRegExpChange(Sender: TObject);
procedure cbSelectedFilesChange(Sender: TObject);
procedure cmbEncodingSelect(Sender: TObject);
procedure cbFindTextChange(Sender: TObject);
procedure cbUsePluginChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnGoToPathClick(Sender: TObject);
procedure btnNewSearchClick(Sender: TObject);
procedure btnSelDirClick(Sender: TObject);
procedure btnStartClick(Sender: TObject);
procedure btnViewClick(Sender: TObject);
procedure btnWorkWithFoundClick(Sender: TObject);
procedure cbFileSizeFromChange(Sender: TObject);
procedure cbFileSizeToChange(Sender: TObject);
procedure cbNotOlderThanChange(Sender: TObject);
procedure cbReplaceTextChange(Sender: TObject);
procedure cbTimeFromChange(Sender: TObject);
procedure cbTimeToChange(Sender: TObject);
procedure btnStopClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure btnCloseClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure frmFindDlgClose(Sender: TObject; var {%H-}CloseAction: TCloseAction);
procedure frmFindDlgShow(Sender: TObject);
procedure gbDirectoriesResize(Sender: TObject);
procedure lbSearchTemplatesDblClick(Sender: TObject);
procedure lbSearchTemplatesSelectionChange(Sender: TObject; {%H-}User: boolean);
procedure lsFoundedFilesDblClick(Sender: TObject);
procedure lsFoundedFilesKeyDown(Sender: TObject;
var Key: Word; Shift: TShiftState);
procedure lsFoundedFilesMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure lsFoundedFilesMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure lsFoundedFilesMouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
procedure lsFoundedFilesMouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
procedure miOpenInNewTabClick(Sender: TObject);
procedure miRemoveFromLlistClick(Sender: TObject);
procedure miShowAllFoundClick(Sender: TObject);
procedure miShowInEditorClick(Sender: TObject);
procedure miShowInViewerClick(Sender: TObject);
procedure pgcSearchChange(Sender: TObject);
procedure seFileSizeFromChange(Sender: TObject);
procedure seFileSizeToChange(Sender: TObject);
procedure seNotOlderThanChange(Sender: TObject);
procedure tsLoadSaveShow(Sender: TObject);
procedure tsStandardEnter(Sender: TObject);
procedure ZVDateFromChange(Sender: TObject);
procedure ZVDateToChange(Sender: TObject);
procedure ZVTimeFromChange(Sender: TObject);
procedure ZVTimeToChange(Sender: TObject);
private
FSelectedFiles: TStringList;
FFindThread:TFindThread;
FTimeSearch:string;
DsxPlugins: TDSXModuleList;
FSearchingActive: Boolean;
FFrmAttributesEdit: TfrmAttributesEdit;
FLastTemplateName: String;
FLastSearchTemplate: TSearchTemplate;
FUpdateTimer: TTimer;
FUpdating: Boolean;
FRButtonPanelSender:TObject; // last focused button on Right Panel (pnlButtons)
FCommands: TFormCommands;
property Commands: TFormCommands read FCommands implements IFormCommands;
procedure DisableControlsForTemplate;
procedure StopSearch;
procedure AfterSearchStopped; //update button states after stop search(ThreadTerminate call this method)
procedure AfterSearchFocus; //set correct focus after search stopped
procedure FillFindOptions(out FindOptions: TSearchTemplateRec; SetStartPath: Boolean);
procedure FindOptionsToDSXSearchRec(const AFindOptions: TSearchTemplateRec;
out SRec: TDsxSearchRecord);
procedure FoundedStringCopyChanged(Sender: TObject);
procedure LoadTemplate(const Template: TSearchTemplateRec);
procedure LoadSelectedTemplate;
procedure SaveTemplate(SaveStartingPath: Boolean);
procedure SelectTemplate(const ATemplateName: String);
procedure UpdateTemplatesList;
procedure OnUpdateTimer(Sender: TObject);
procedure OnAddAttribute(Sender: TObject);
function InvalidRegExpr(AChecked: Boolean; const ARegExpr: String): Boolean;
public
class function Instance: TfrmFindDlg;
public
LastClickResultsPath:string;
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure ClearFilter;
procedure ClearResults;
procedure ThreadTerminate(Sender:TObject);
procedure FocusOnResults(Sender:TObject); // if press VK_LEFT or VK_RIGHT when on any button on left panel - focus on results and remember button in FRButtonPanelSender
published
procedure cm_IntelliFocus(const Params: array of string);
procedure cm_Start(const Params: array of string);
procedure cm_CancelClose(const Params: array of string);
procedure cm_Cancel(const Params: array of string);
procedure cm_Close(const Params: array of string);
procedure cm_NewSearch(const Params: array of string);
procedure cm_LastSearch(const Params: array of string);
procedure cm_View(const Params: array of string);
procedure cm_Edit(const Params: array of string);
procedure cm_GoToFile(const Params: array of string);
procedure cm_FeedToListbox(const Params: array of string);
procedure cm_PageStandard(const Params: array of string);
procedure cm_PageAdvanced(const Params: array of string);
procedure cm_PagePlugins(const Params: array of string);
procedure cm_PageLoadSave(const Params: array of string);
procedure cm_PageResults(const Params: array of string);
end;
var
FoundedStringCopy: TStringlist = nil;
{en
Shows the find files dialog.
Cannot store FileView reference as it might get destroyed while Find Dialog is running.
We can store FileSource though, if needed in future (as it is reference counted).
@param(FileView
For which file view the find dialog is executed,
to get file source, current path and a list of selected files.)
}
procedure ShowFindDlg(FileView: TFileView; const TemplateName: String);
function ShowDefineTemplateDlg(var TemplateName: String): Boolean;
function ShowUseTemplateDlg(var Template: TSearchTemplate): Boolean;
implementation
{$R *.lfm}
uses
LCLProc, LCLType, LConvEncoding, StrUtils, HelpIntfs, fViewer, fMain,
uLng, uGlobs, uShowForm, uDCUtils, uFileSource, uFileSourceUtil,
uSearchResultFileSource, uFile,
uFileViewNotebook, uKeyboard, uOSUtils, uArchiveFileSourceUtil,
DCOSUtils, SynRegExpr;
const
TimeUnitToComboIndex: array[TTimeUnit] of Integer = (0, 1, 2, 3, 4, 5, 6);
ComboIndexToTimeUnit: array[0..6] of TTimeUnit = (tuSecond, tuMinute, tuHour, tuDay, tuWeek, tuMonth, tuYear);
FileSizeUnitToComboIndex: array[TFileSizeUnit] of Integer = (0, 1, 2, 3, 4);
ComboIndexToFileSizeUnit: array[0..4] of TFileSizeUnit = (suBytes, suKilo, suMega, suGiga, suTera);
type
{ TStringListTemp }
TStringListTemp = class(TStringList)
public
function AddObject(const S: String; AObject: TObject): Integer; override;
end;
var
GfrmFindDlgInstance: TfrmFindDlg = nil;
procedure SAddFileProc({%H-}PlugNr: Integer; FoundFile: PChar); dcpcall;
var
s: string;
begin
s := string(FoundFile);
if s='' then
begin
TfrmFindDlg.Instance.AfterSearchStopped;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
TfrmFindDlg.Instance.btnStart.Default := True;
{$ENDIF}
end
else
begin
FoundedStringCopy.Add(s);
Application.ProcessMessages;
end;
end;
procedure SUpdateStatusProc({%H-}PlugNr: Integer; CurrentFile: PChar; FilesScanned: Integer); dcpcall;
var
sCurrentFile: String;
begin
sCurrentFile := String(CurrentFile);
TfrmFindDlg.Instance.lblStatus.Caption:=Format(rsFindScanned,[FilesScanned])+TfrmFindDlg.Instance.FTimeSearch;
if sCurrentFile = '' then
TfrmFindDlg.Instance.lblCurrent.Caption := ''
else
TfrmFindDlg.Instance.lblCurrent.Caption:=rsFindScanning + ': ' + sCurrentFile;
Application.ProcessMessages;
end;
procedure ShowFindDlg(FileView: TFileView; const TemplateName: String);
var
ASelectedFiles: TFiles = nil;
I: Integer;
begin
if not Assigned(FileView) then
raise Exception.Create('ShowFindDlg: FileView=nil');
with TfrmFindDlg.Instance do
begin
// Prepare window for search files
ClearFilter;
Caption := rsFindSearchFiles;
edtFindPathStart.Text := FileView.CurrentPath;
// Get paths of selected files, if any.
FSelectedFiles.Clear;
ASelectedFiles := FileView.CloneSelectedFiles;
if Assigned(ASelectedFiles) then
try
if ASelectedFiles.Count > 0 then
begin
for I := 0 to ASelectedFiles.Count - 1 do
FSelectedFiles.Add(ASelectedFiles[I].FullPath);
end;
finally
FreeAndNil(ASelectedFiles);
end;
if Length(TemplateName) > 0 then
begin
FUpdating:= True;
UpdateTemplatesList;
SelectTemplate(TemplateName);
LoadSelectedTemplate;
FUpdating:= False;
end;
ShowOnTop;
end;
end;
function ShowDefineTemplateDlg(var TemplateName: String): Boolean;
var
AIndex: Integer;
AForm: TfrmFindDlg;
begin
AForm := TfrmFindDlg.Create(nil);
try
with AForm do
begin
// Prepare window for define search template
Caption := rsFindDefineTemplate;
AForm.DisableControlsForTemplate;
btnSaveTemplate.Visible := True;
btnSaveTemplate.Default := True;
BorderIcons := [biSystemMenu, biMaximize];
if Length(TemplateName) > 0 then
begin
UpdateTemplatesList;
AIndex:= lbSearchTemplates.Items.IndexOf(TemplateName);
if AIndex >= 0 then
begin
lbSearchTemplates.ItemIndex:= AIndex;
AForm.LoadSelectedTemplate;
end;
end;
Result:= (ShowModal = mrOK);
if Result and (lbSearchTemplates.Count > 0) then
begin
TemplateName:= lbSearchTemplates.Items[lbSearchTemplates.Count - 1];
end;
end;
finally
AForm.Free;
end;
end;
function ShowUseTemplateDlg(var Template: TSearchTemplate): Boolean;
var
AForm: TfrmFindDlg;
SearchRec: TSearchTemplateRec;
begin
AForm := TfrmFindDlg.Create(nil);
try
with AForm do
begin
// Prepare window for define search template
Caption := rsFindDefineTemplate;
DisableControlsForTemplate;
btnUseTemplate.Visible := True;
btnUseTemplate.Default := True;
BorderIcons := [biSystemMenu, biMaximize];
if Assigned(Template) then
AForm.LoadTemplate(Template.SearchRecord);
Result:= (ShowModal = mrOK);
if Result then
begin
if not Assigned(Template) then
Template:= TSearchTemplate.Create;
try
Template.TemplateName := AForm.FLastTemplateName;
AForm.FillFindOptions(SearchRec, False);
Template.SearchRecord := SearchRec;
except
FreeAndNil(Template);
raise;
end;
end;
end;
finally
AForm.Free;
end;
end;
{ TStringListTemp }
function TStringListTemp.AddObject(const S: String; AObject: TObject): Integer;
begin
Result:= Count;
InsertItem(Result, S, AObject);
end;
{ TfrmFindDlg }
procedure TfrmFindDlg.FormCreate(Sender: TObject);
var
I: Integer;
HMFindFiles: THMForm;
begin
Height:= pnlFindFile.Height + 22;
DsxPlugins := TDSXModuleList.Create;
DsxPlugins.Assign(gDSXPlugins);
FoundedStringCopy := TStringListTemp.Create;
FoundedStringCopy.OnChange:=@FoundedStringCopyChanged;
// load language
edtFindPathStart.DialogTitle:= rsFindWhereBeg;
cmbNotOlderThanUnit.Items.Add(rsTimeUnitSecond);
cmbNotOlderThanUnit.Items.Add(rsTimeUnitMinute);
cmbNotOlderThanUnit.Items.Add(rsTimeUnitHour);
cmbNotOlderThanUnit.Items.Add(rsTimeUnitDay);
cmbNotOlderThanUnit.Items.Add(rsTimeUnitWeek);
cmbNotOlderThanUnit.Items.Add(rsTimeUnitMonth);
cmbNotOlderThanUnit.Items.Add(rsTimeUnitYear);
cmbFileSizeUnit.Items.Add(rsSizeUnitBytes);
cmbFileSizeUnit.Items.Add(rsSizeUnitKBytes);
cmbFileSizeUnit.Items.Add(rsSizeUnitMBytes);
cmbFileSizeUnit.Items.Add(rsSizeUnitGBytes);
cmbFileSizeUnit.Items.Add(rsSizeUnitTBytes);
// fill search depth combobox
cmbSearchDepth.Items.Add(rsFindDepthAll);
cmbSearchDepth.Items.Add(rsFindDepthCurDir);
for I:= 1 to 100 do
cmbSearchDepth.Items.Add(Format(rsFindDepth, [IntToStr(I)]));
cmbSearchDepth.ItemIndex:= 0;
// fill encoding combobox
cmbEncoding.Clear;
GetSupportedEncodings(cmbEncoding.Items);
I:= cmbEncoding.Items.IndexOf('UTF-8BOM');
if I >= 0 then cmbEncoding.Items.Delete(I);
cmbEncoding.ItemIndex:= cmbEncoding.Items.IndexOf(EncodingAnsi);
// gray disabled fields
cbUsePluginChange(Sender);
cbFindTextChange(Sender);
cbReplaceTextChange(Sender);
cbNotOlderThanChange(Sender);
cbFileSizeFromChange(Sender);
cbFileSizeToChange(Sender);
ZVDateFrom.DateTime:=Now();
ZVDateTo.DateTime:=Now();
ZVTimeFrom.DateTime:=Now();
ZVTimeTo.DateTime:=Now();
cbDateFrom.Checked:=False;
cbDateTo.Checked:=False;
cbTimeFrom.Checked:=False;
cbTimeTo.Checked:=False;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default := True;
{$ENDIF}
cmbNotOlderThanUnit.ItemIndex := 3; // Days
cmbFileSizeUnit.ItemIndex := 1; // Kilobytes
edtFindPathStart.ShowHidden := gShowSystemFiles;
cbPartialNameSearch.Checked:= gPartialNameSearch;
InitPropStorage(Self);
HMFindFiles := HotMan.Register(Self, HotkeysCategory);
HMFindFiles.RegisterActionList(actList);
end;
procedure TfrmFindDlg.cbUsePluginChange(Sender: TObject);
begin
EnableControl(cmbPlugin, cbUsePlugin.Checked);
if not FUpdating and cmbPlugin.Enabled and cmbPlugin.CanFocus and (Sender = cbUsePlugin) then
begin
cmbPlugin.SetFocus;
cmbPlugin.SelectAll;
end;
end;
procedure TfrmFindDlg.cmbEncodingSelect(Sender: TObject);
var
AEncoding: String;
begin
AEncoding:= NormalizeEncoding(cmbEncoding.Text);
cbTextRegExp.Enabled := (AEncoding = EncodingAnsi);
if not cbTextRegExp.Enabled then cbTextRegExp.Checked:= False;
end;
constructor TfrmFindDlg.Create(TheOwner: TComponent);
begin
FSelectedFiles := TStringList.Create;
inherited Create(TheOwner);
FUpdateTimer := TTimer.Create(Self);
FUpdateTimer.Interval := 100;
FUpdateTimer.Enabled := False;
FUpdateTimer.OnTimer := @OnUpdateTimer;
FCommands := TFormCommands.Create(Self, actList);
end;
destructor TfrmFindDlg.Destroy;
begin
inherited Destroy;
FSelectedFiles.Free;
FLastSearchTemplate.Free;
end;
procedure TfrmFindDlg.DisableControlsForTemplate;
begin
lblFindPathStart.Visible := False;
edtFindPathStart.Visible := False;
cbFollowSymLinks.Visible := False;
cbSelectedFiles.Visible := False;
btnStart.Visible := False;
btnStop.Visible := False;
btnNewSearch.Visible := False;
btnLastSearch.Visible := False;
btnSearchSaveWithStartingPath.Visible := False;
gbFindData.Visible := False;
tsResults.TabVisible := False;
end;
procedure TfrmFindDlg.cbFindTextChange(Sender: TObject);
begin
EnableControl(cmbFindText, cbFindText.Checked);
EnableControl(cmbEncoding, cbFindText.Checked);
EnableControl(cbCaseSens, cbFindText.Checked);
EnableControl(cbReplaceText, cbFindText.Checked and not cbFindInArchive.Checked);
EnableControl(cbNotContainingText, cbFindText.Checked);
EnableControl(cbTextRegExp, cbFindText.Checked);
lblEncoding.Enabled:=cbFindText.Checked;
cbReplaceText.Checked:= False;
if not FUpdating and cmbFindText.Enabled and cmbFindText.CanFocus and (Sender = cbFindText) then
begin
cmbFindText.SetFocus;
cmbFindText.SelectAll;
end;
end;
procedure TfrmFindDlg.ClearFilter;
begin
FUpdating := True;
FLastTemplateName := '';
edtFindPathStart.Text:= '';
edtFindPathStart.ShowHidden := gShowSystemFiles;
cmbExcludeDirectories.Text := '';
cmbSearchDepth.ItemIndex := 0;
cmbFindFileMask.Text:= '*';
cmbExcludeFiles.Text := '';
cbPartialNameSearch.Checked:= gPartialNameSearch;
cbRegExp.Checked := False;
// attributes
edtAttrib.Text:= '';
// file date/time
ZVDateFrom.DateTime:=Now();
ZVDateTo.DateTime:=Now();
ZVTimeFrom.DateTime:=Now();
ZVTimeTo.DateTime:=Now();
cbDateFrom.Checked:=False;
cbDateTo.Checked:=False;
cbTimeFrom.Checked:=False;
cbTimeTo.Checked:=False;
// not older then
cbNotOlderThan.Checked:= False;
seNotOlderThan.Value:= 1;
cmbNotOlderThanUnit.ItemIndex := 3; // Days
// file size
cbFileSizeFrom.Checked:= False;
cbFileSizeTo.Checked:= False;
seFileSizeFrom.Value:= 0;
seFileSizeTo.Value:= 10;
cmbFileSizeUnit.ItemIndex := 1; // Kilobytes
// find/replace text
// do not clear search/replace text just clear checkbox
cbFindText.Checked:= False;
cbReplaceText.Checked:= False;
cbCaseSens.Checked:= False;
cbNotContainingText.Checked:= False;
cmbEncoding.ItemIndex := cmbEncoding.Items.IndexOf(EncodingAnsi);
// plugins
cmbPlugin.Text:= '';
FUpdating := False;
end;
procedure TfrmFindDlg.ClearResults;
begin
lsFoundedFiles.Clear;
lsFoundedFiles.Tag:= 0;
lsFoundedFiles.ScrollWidth:= 0;
FoundedStringCopy.Clear;
end;
procedure TfrmFindDlg.btnSearchLoadClick(Sender: TObject);
begin
LoadSelectedTemplate;
end;
procedure TfrmFindDlg.btnSearchSaveWithStartingPathClick(Sender: TObject);
begin
SaveTemplate(True);
end;
procedure TfrmFindDlg.btnSearchDeleteClick(Sender: TObject);
var
OldIndex: Integer;
begin
OldIndex := lbSearchTemplates.ItemIndex;
if OldIndex < 0 then Exit;
gSearchTemplateList.DeleteTemplate(OldIndex);
lbSearchTemplates.Items.Delete(OldIndex);
if OldIndex < lbSearchTemplates.Count then
lbSearchTemplates.ItemIndex := OldIndex
else if lbSearchTemplates.Count > 0 then
lbSearchTemplates.ItemIndex := lbSearchTemplates.Count - 1;
end;
procedure TfrmFindDlg.btnAttrsHelpClick(Sender: TObject);
begin
ShowHelpOrErrorForKeyword('', edtAttrib.HelpKeyword);
end;
procedure TfrmFindDlg.btnEditClick(Sender: TObject);
begin
if lsFoundedFiles.ItemIndex <> -1 then
ShowEditorByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
end;
procedure TfrmFindDlg.actExecute(Sender: TObject);
var
cmd: string;
begin
cmd := (Sender as TAction).Name;
cmd := 'cm_' + Copy(cmd, 4, Length(cmd) - 3);
Commands.ExecuteCommand(cmd, []);
end;
procedure TfrmFindDlg.btnAddAttributeClick(Sender: TObject);
begin
if not Assigned(FFrmAttributesEdit) then
begin
FFrmAttributesEdit := TfrmAttributesEdit.Create(Self);
FFrmAttributesEdit.OnOk := @OnAddAttribute;
end;
FFrmAttributesEdit.Reset;
if not (fsModal in FormState) then
FFrmAttributesEdit.Show
else begin
FFrmAttributesEdit.ShowModal;
end;
end;
procedure TfrmFindDlg.btnSearchSaveClick(Sender: TObject);
begin
SaveTemplate(False);
end;
procedure TfrmFindDlg.cbCaseSensChange(Sender: TObject);
begin
if cbCaseSens.Checked then cbTextRegExp.Checked:= False;
end;
procedure TfrmFindDlg.cbDateFromChange(Sender: TObject);
begin
UpdateColor(ZVDateFrom, cbDateFrom.Checked);
end;
procedure TfrmFindDlg.cbDateToChange(Sender: TObject);
begin
UpdateColor(ZVDateTo, cbDateTo.Checked);
end;
procedure TfrmFindDlg.cbFindInArchiveChange(Sender: TObject);
begin
EnableControl(cbReplaceText, cbFindText.Checked and not cbFindInArchive.Checked);
if cbReplaceText.Checked then cbReplaceText.Checked := cbReplaceText.Enabled;
btnView.Enabled:= not cbFindInArchive.Checked;
btnEdit.Enabled:= not cbFindInArchive.Checked;
btnWorkWithFound.Enabled:= not cbFindInArchive.Checked;
cbReplaceTextChange(cbReplaceText);
end;
procedure TfrmFindDlg.cbOpenedTabsChange(Sender: TObject);
begin
cbSelectedFiles.Enabled:=not cbOpenedTabs.Checked;
cbFollowSymLinks.Enabled:=not cbOpenedTabs.Checked;
edtFindPathStart.Enabled:=not cbOpenedTabs.Checked;
end;
procedure TfrmFindDlg.cbPartialNameSearchChange(Sender: TObject);
begin
if cbPartialNameSearch.Checked then cbRegExp.Checked:=False;
end;
procedure TfrmFindDlg.cbRegExpChange(Sender: TObject);
begin
if cbRegExp.Checked then cbPartialNameSearch.Checked:=False;
end;
procedure TfrmFindDlg.cbTextRegExpChange(Sender: TObject);
begin
if cbTextRegExp.Checked then
begin
if cbCaseSens.Enabled then
begin
cbCaseSens.Tag:= Integer(cbCaseSens.Checked);
cbCaseSens.Checked:= False;
cbCaseSens.Enabled:= False;
end;
end
else if not cbCaseSens.Enabled then
begin
cbCaseSens.Checked:= Boolean(cbCaseSens.Tag);
cbCaseSens.Enabled:= True;
end;
end;
procedure TfrmFindDlg.cbSelectedFilesChange(Sender: TObject);
begin
edtFindPathStart.Enabled := not cbSelectedFiles.Checked;
end;
procedure TfrmFindDlg.btnSelDirClick(Sender: TObject);
var
s:String;
begin
s:=edtFindPathStart.Text;
if not mbDirectoryExists(s) then s:='';
SelectDirectory(rsFindWhereBeg,'',s, False);
edtFindPathStart.Text:=s;
end;
procedure TfrmFindDlg.btnNewSearchClick(Sender: TObject);
begin
StopSearch;
pgcSearch.PageIndex:= 0;
ClearResults;
miShowAllFound.Enabled:=False;
lblStatus.Caption:= EmptyStr;
lblCurrent.Caption:= EmptyStr;
lblFound.Caption:= EmptyStr;
if pgcSearch.ActivePage = tsStandard then
cmbFindFileMask.SetFocus;
// AfterSearchStopped;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default := True;
{$ENDIF}
end;
procedure TfrmFindDlg.btnGoToPathClick(Sender: TObject);
var
AFile: TFile = nil;
TargetFile: String;
ArchiveFile: String;
FileSource: IFileSource;
begin
if lsFoundedFiles.ItemIndex <> -1 then
try
StopSearch;
if (lsFoundedFiles.Items.Objects[lsFoundedFiles.ItemIndex] <> nil) then
begin
TargetFile:= lsFoundedFiles.Items[lsFoundedFiles.ItemIndex];
ArchiveFile:= ExtractWord(1, TargetFile, [ReversePathDelim]);
TargetFile:= PathDelim + ExtractWord(2, TargetFile, [ReversePathDelim]);
AFile:= TFileSystemFileSource.CreateFileFromFile(ArchiveFile);
try
FileSource:= GetArchiveFileSource(TFileSystemFileSource.GetFileSource, AFile, EmptyStr, False, False);
finally
AFile.Free;
end;
if Assigned(FileSource) then
begin
frmMain.ActiveFrame.AddFileSource(FileSource, ExtractFilePath(TargetFile));
frmMain.ActiveFrame.SetActiveFile(ExtractFileName(TargetFile));
end;
end
else begin
SetFileSystemPath(frmMain.ActiveFrame, ExtractFilePath(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]));
frmMain.ActiveFrame.SetActiveFile(ExtractFileName(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]));
end;
Close;
except
on E: Exception do MessageDlg(E.Message, mtError, [mbOK], 0);
end;
end;
procedure TfrmFindDlg.btnLastSearchClick(Sender: TObject);
begin
if Assigned(FLastSearchTemplate) then
begin
LoadTemplate(FLastSearchTemplate.SearchRecord);
pgcSearch.ActivePage := tsStandard;
cmbFindFileMask.SetFocus;
end;
end;
procedure TfrmFindDlg.btnNewSearchKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if ((Key=VK_LEFT)or(Key=VK_RIGHT))and(lsFoundedFiles.Count>0) then FocusOnResults(Sender);
end;
procedure TfrmFindDlg.FillFindOptions(out FindOptions: TSearchTemplateRec; SetStartPath: Boolean);
begin
with FindOptions do
begin
if SetStartPath then
StartPath := edtFindPathStart.Text
else
StartPath := '';
ExcludeDirectories := cmbExcludeDirectories.Text;
FilesMasks := cmbFindFileMask.Text;
ExcludeFiles := cmbExcludeFiles.Text;
SearchDepth := cmbSearchDepth.ItemIndex - 1;
RegExp := cbRegExp.Checked;
IsPartialNameSearch := cbPartialNameSearch.Checked;
FollowSymLinks := cbFollowSymLinks.Checked;
FindInArchives := cbFindInArchive.Checked;
{ File attributes }
AttributesPattern := edtAttrib.Text;
{ Date/time }
DateTimeFrom := 0;
DateTimeTo := 0;
IsDateFrom := False;
IsDateTo := False;
IsTimeFrom := False;
IsTimeTo := False;
if cbDateFrom.Checked then
begin
IsDateFrom := True;
DateTimeFrom := ZVDateFrom.Date;
end;
if cbDateTo.Checked then
begin
IsDateTo := True;
DateTimeTo := ZVDateTo.Date;
end;
if cbTimeFrom.Checked then
begin
IsTimeFrom := True;
DateTimeFrom := DateTimeFrom + ZVTimeFrom.Time;
end;
if cbTimeTo.Checked then
begin
IsTimeTo := True;
DateTimeTo := DateTimeTo + ZVTimeTo.Time;
end;
{ Not Older Than }
IsNotOlderThan := cbNotOlderThan.Checked;
NotOlderThan := seNotOlderThan.Value;
NotOlderThanUnit := ComboIndexToTimeUnit[cmbNotOlderThanUnit.ItemIndex];
{ File size }
IsFileSizeFrom := cbFileSizeFrom.Checked;
IsFileSizeTo := cbFileSizeTo.Checked;
FileSizeFrom := seFileSizeFrom.Value;
FileSizeTo := seFileSizeTo.Value;
FileSizeUnit := ComboIndexToFileSizeUnit[cmbFileSizeUnit.ItemIndex];
{ Find/replace text }
IsFindText := cbFindText.Checked;
FindText := cmbFindText.Text;
IsReplaceText := cbReplaceText.Checked;
ReplaceText := cmbReplaceText.Text;
CaseSensitive := cbCaseSens.Checked;
NotContainingText := cbNotContainingText.Checked;
TextRegExp := cbTextRegExp.Checked;
TextEncoding := cmbEncoding.Text;
{ Plugins }
SearchPlugin := cmbPlugin.Text;
frmContentPlugins.Save(FindOptions)
end;
end;
procedure TfrmFindDlg.FindOptionsToDSXSearchRec(
const AFindOptions: TSearchTemplateRec;
out SRec: TDsxSearchRecord);
begin
with AFindOptions do
begin
FillByte(SRec{%H-}, SizeOf(SRec), 0);
SRec.StartPath:= Copy(StartPath, 1, SizeOf(SRec.StartPath));
if IsPartialNameSearch then
SRec.FileMask:= '*' + Copy(FilesMasks, 1, SizeOf(SRec.FileMask) - 2) + '*'
else
SRec.FileMask:= Copy(FilesMasks, 1, SizeOf(SRec.FileMask));
SRec.Attributes:= faAnyFile; // AttrStrToFileAttr?
SRec.AttribStr:= Copy(AttributesPattern, 1, SizeOf(SRec.AttribStr));
SRec.CaseSensitive:=CaseSensitive;
{Date search}
SRec.IsDateFrom:=IsDateFrom;
SRec.IsDateTo:=IsDateTo;
SRec.DateTimeFrom:=DateTimeFrom;
SRec.DateTimeTo:=DateTimeTo;
{Time search}
SRec.IsTimeFrom:=IsTimeFrom;
SRec.IsTimeTo:=IsTimeTo;
(* File size search *)
SRec.IsFileSizeFrom:=IsFileSizeFrom;
SRec.IsFileSizeTo:=IsFileSizeTo;
SRec.FileSizeFrom:=FileSizeFrom;
SRec.FileSizeTo:=FileSizeTo;
(* Find text *)
SRec.NotContainingText:=NotContainingText;
SRec.IsFindText:=IsFindText;
SRec.FindText:= Copy(FindText, 1, SizeOf(SRec.FindText));
(* Replace text *)
SRec.IsReplaceText:=IsReplaceText;
SRec.ReplaceText:= Copy(ReplaceText, 1, SizeOf(SRec.ReplaceText));
end;
end;
procedure TfrmFindDlg.StopSearch;
begin
if FSearchingActive then
begin
if (cbUsePlugin.Checked) and (cmbPlugin.ItemIndex<>-1) then
begin
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallStopSearch;
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallFinalize;
AfterSearchStopped;
AfterSearchFocus;
// btnNewSearch.SetFocus;
end;
if Assigned(FFindThread) then
begin
FFindThread.Terminate;
FFindThread := nil;
end;
end;
end;
class function TfrmFindDlg.Instance: TfrmFindDlg;
begin
if not Assigned(GfrmFindDlgInstance) then
GfrmFindDlgInstance := TfrmFindDlg.Create(nil);
Result := GfrmFindDlgInstance;
end;
procedure TfrmFindDlg.lbSearchTemplatesDblClick(Sender: TObject);
begin
LoadSelectedTemplate;
end;
procedure TfrmFindDlg.AfterSearchStopped;
begin
btnStop.Enabled:= False;
btnStart.Enabled:= True;
btnClose.Enabled:= True;
btnNewSearch.Enabled:= True;
FSearchingActive := False;
// btnNewSearch.SetFocus;
end;
procedure TfrmFindDlg.AfterSearchFocus;
var
LastButton: TButton;
begin
if Assigned(Self) and Visible then
begin
if FRButtonPanelSender <> nil then // if user press a keys while search - keep focus on it
begin
LastButton:= (FRButtonPanelSender as TButton);
if LastButton.Enabled then LastButton.SetFocus else btnNewSearch.SetFocus;
end
else begin // if user don't press anything - focus on results
if (pgcSearch.ActivePage=tsResults)and(lsFoundedFiles.Count > 0) then
begin
lsFoundedFiles.SetFocus;
if (lsFoundedFiles.ItemIndex <> -1) then
lsFoundedFiles.Selected[lsFoundedFiles.ItemIndex]:= True;
end else
begin
if btnNewSearch.Enabled then btnNewSearch.SetFocus else btnStart.SetFocus;
end;
end;
end;
end;
procedure TfrmFindDlg.btnStartClick(Sender: TObject);
var
sTemp, sPath : String;
sr: TDsxSearchRecord;
SearchTemplate, TmpTemplate: TSearchTemplateRec;
PassedSelectedFiles: TStringList = nil;
begin
sTemp:= edtFindPathStart.Text;
repeat
sPath:= Copy2SymbDel(sTemp, ';');
if not mbDirectoryExists(sPath) then
begin
ShowMessage(Format(rsFindDirNoEx,[sPath]));
Exit;
end;
until sTemp = EmptyStr;
// add to find mask history
InsertFirstItem(cmbFindFileMask.Text, cmbFindFileMask);
// add to exclude directories history
InsertFirstItem(cmbExcludeDirectories.Text, cmbExcludeDirectories);
// add to exclude files history
InsertFirstItem(cmbExcludeFiles.Text, cmbExcludeFiles);
// add to search text history
if cbFindText.Checked then
begin
InsertFirstItem(cmbFindText.Text, cmbFindText);
// update search history, so it can be used in
// Viewer/Editor opened from find files dialog
gFirstTextSearch:= False;
glsSearchHistory.Assign(cmbFindText.Items);
end;
// add to replace text history
if cbReplaceText.Checked then
begin
InsertFirstItem(cmbReplaceText.Text, cmbReplaceText);
// update replace history, so it can be used in
// Editor opened from find files dialog (issue 0000539)
glsReplaceHistory.Assign(cmbReplaceText.Items);
end;
if cbSelectedFiles.Checked and (FSelectedFiles.Count = 0) then
begin
ShowMessage(rsMsgNoFilesSelected);
cbSelectedFiles.Checked:= False;
Exit;
end;
// Show search results page
pgcSearch.ActivePageIndex:= pgcSearch.PageCount - 1;
if lsFoundedFiles.CanFocus then
lsFoundedFiles.SetFocus;
ClearResults;
miShowAllFound.Enabled:=False;
FSearchingActive := True;
btnStop.Enabled:=True;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStop.Default:=True;
{$ENDIF}
btnStart.Enabled:= False;
btnClose.Enabled:= False;
btnNewSearch.Enabled:= False;
FillFindOptions(SearchTemplate, True);
if not Assigned(FLastSearchTemplate) then
FLastSearchTemplate := TSearchTemplate.Create;
TmpTemplate := SearchTemplate;
TmpTemplate.StartPath := ''; // Don't remember starting path.
FLastSearchTemplate.SearchRecord := TmpTemplate;
try
if (cbUsePlugin.Checked) and (cmbPlugin.ItemIndex<>-1) then
begin
if DSXPlugins.LoadModule(cmbPlugin.ItemIndex) then
begin
FindOptionsToDSXSearchRec(SearchTemplate, sr);
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallInit(@SAddFileProc,@SUpdateStatusProc);
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallStartSearch(sr);
end
else
StopSearch;
end
else
begin
if cbSelectedFiles.Checked then PassedSelectedFiles := FSelectedFiles;
if cbOpenedTabs.Checked then
begin
frmMain.GetListOpenedPaths(FSelectedFiles);
PassedSelectedFiles := FSelectedFiles;
end;
FFindThread := TFindThread.Create(SearchTemplate, PassedSelectedFiles);
with FFindThread do
begin
Items := FoundedStringCopy;
OnTerminate := @ThreadTerminate; // will update the buttons after search is finished
end;
FTimeSearch:='';
FFindThread.Start;
FUpdateTimer.Enabled := True;
FUpdateTimer.OnTimer(FUpdateTimer);
FRButtonPanelSender:=nil;
end;
except
StopSearch;
raise;
end;
end;
procedure TfrmFindDlg.FoundedStringCopyChanged(Sender: TObject);
var
sText: String;
iTemp: Integer;
begin
if FoundedStringCopy.Count > 0 then
begin
iTemp:= FoundedStringCopy.Count - 1;
Sender:= FoundedStringCopy.Objects[iTemp];
sText:= FoundedStringCopy[iTemp];
iTemp:= Length(sText);
if iTemp > lsFoundedFiles.Tag then
begin
lsFoundedFiles.Tag:= iTemp;
iTemp:= lsFoundedFiles.Canvas.TextWidth(sText);
if iTemp > lsFoundedFiles.ScrollWidth then
lsFoundedFiles.ScrollWidth:= iTemp + 32;
end;
lsFoundedFiles.Items.AddObject(sText, Sender);
end;
end;
procedure TfrmFindDlg.btnViewClick(Sender: TObject);
begin
if lsFoundedFiles.ItemIndex <> -1 then
ShowViewerByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
end;
procedure TfrmFindDlg.btnWorkWithFoundClick(Sender: TObject);
var
I: Integer;
sFileName: String;
SearchResultFS: ISearchResultFileSource;
FileList: TFileTree;
aFile: TFile;
Notebook: TFileViewNotebook;
NewPage: TFileViewPage;
begin
StopSearch;
FileList := TFileTree.Create;
for i := 0 to lsFoundedFiles.Items.Count - 1 do
begin
sFileName:= lsFoundedFiles.Items[I];
try
aFile := TFileSystemFileSource.CreateFileFromFile(sFileName);
FileList.AddSubNode(aFile);
except
on EFileNotFound do;
end;
end;
// Create search result file source.
// Currently only searching FileSystem is supported.
SearchResultFS := TSearchResultFileSource.Create;
SearchResultFS.AddList(FileList, TFileSystemFileSource.GetFileSource);
// Add new tab for search results.
Notebook := frmMain.ActiveNotebook;
NewPage := Notebook.NewPage(Notebook.ActiveView);
NewPage.FileView.AddFileSource(SearchResultFS, SearchResultFS.GetRootDir);
NewPage.FileView.FlatView := True;
NewPage.MakeActive;
Close;
end;
procedure TfrmFindDlg.cbFileSizeFromChange(Sender: TObject);
begin
UpdateColor(seFileSizeFrom, cbFileSizeFrom.Checked);
EnableControl(cmbFileSizeUnit,cbFileSizeFrom.Checked or cbFileSizeTo.Checked);
end;
procedure TfrmFindDlg.cbFileSizeToChange(Sender: TObject);
begin
UpdateColor(seFileSizeTo, cbFileSizeTo.Checked);
EnableControl(cmbFileSizeUnit,cbFileSizeFrom.Checked or cbFileSizeTo.Checked);
end;
procedure TfrmFindDlg.cbNotOlderThanChange(Sender: TObject);
begin
UpdateColor(seNotOlderThan, cbNotOlderThan.Checked);
EnableControl(cmbNotOlderThanUnit,cbNotOlderThan.Checked);
end;
procedure TfrmFindDlg.cbReplaceTextChange(Sender: TObject);
begin
EnableControl(cmbReplaceText, cbReplaceText.Checked and cbFindText.Checked);
cbNotContainingText.Checked := False;
cbNotContainingText.Enabled := (not cbReplaceText.Checked and cbFindText.Checked);
if not FUpdating and cmbReplaceText.Enabled and cmbReplaceText.CanFocus then
begin
cmbReplaceText.SetFocus;
cmbReplaceText.SelectAll;
end;
end;
procedure TfrmFindDlg.cbTimeFromChange(Sender: TObject);
begin
UpdateColor(ZVTimeFrom, cbTimeFrom.Checked);
end;
procedure TfrmFindDlg.cbTimeToChange(Sender: TObject);
begin
UpdateColor(ZVTimeTo, cbTimeTo.Checked);
end;
procedure TfrmFindDlg.ThreadTerminate(Sender:TObject);
begin
FFindThread := TFindThread(Sender);
if FFindThread.TimeOfScan<>0 then FTimeSearch:=' , '+rsFindTimeOfScan+formatdatetime('hh:nn:ss.zzz', FFindThread.TimeOfScan);
FUpdateTimer.OnTimer(FUpdateTimer);
FUpdateTimer.Enabled := False;
FFindThread := nil;
AfterSearchStopped;
AfterSearchFocus;
{
if Assigned(Self) and Visible then
begin
if FRButtonPanelSender<>nil then // if user press a keys while search - keep focus on it
begin
LastButton:=(FRButtonPanelSender as TButton);
if LastButton.Enabled then LastButton.SetFocus else btnNewSearch.SetFocus;
end else
begin// if user don't press anything - focus on results
lsFoundedFiles.SetFocus;
if lsFoundedFiles.Count>0 then lsFoundedFiles.Selected[lsFoundedFiles.ItemIndex]:=True;
end;
end;
}
// if Assigned(Self) and Visible then btnNewSearch.SetFocus;
// if Self.Instance;
end;
procedure TfrmFindDlg.FocusOnResults(Sender: TObject);
begin
FRButtonPanelSender:=Sender;
if pgcSearch.ActivePage=tsResults then
begin
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default:= False;
{$ENDIF}
if lsFoundedFiles.SelCount=0 then lsFoundedFiles.ItemIndex:=0;
lsFoundedFiles.SetFocus;
lsFoundedFiles.Selected[lsFoundedFiles.ItemIndex]:=True;
end;
end;
procedure TfrmFindDlg.cm_IntelliFocus(const Params: array of string);
begin
if FFindThread<>nil then
begin
FFindThread.OnTerminate:=nil;
FFindThread.Terminate;
FUpdateTimer.OnTimer(FUpdateTimer);
FUpdateTimer.Enabled := False;
FFindThread := nil;
end;
AfterSearchStopped;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default := True;
{$ENDIF}
if cmbFindText.Focused then // if F7 on already focused textSearch field- disable text search and set focun on file mask
begin
cbFindText.Checked:=False;
cmbFindFileMask.SetFocus;
cmbFindFileMask.SelectAll;
exit;
end else
begin
pgcSearch.PageIndex:= 0;
cbFindText.Checked:=True;
cmbFindText.SetFocus;
cmbFindText.SelectAll;
end;
end;
procedure TfrmFindDlg.cm_Start(const Params: array of string);
begin
btnStop.Click;
Self.Repaint;
Application.ProcessMessages;
btnStart.Click;
end;
procedure TfrmFindDlg.cm_CancelClose(const Params: array of string);
begin
if FSearchingActive then
StopSearch
else
Close;
end;
procedure TfrmFindDlg.cm_Cancel(const Params: array of string);
begin
btnStop.Click;
end;
procedure TfrmFindDlg.cm_Close(const Params: array of string);
begin
btnClose.Click;
end;
procedure TfrmFindDlg.cm_NewSearch(const Params: array of string);
begin
btnNewSearch.Click;
end;
procedure TfrmFindDlg.cm_LastSearch(const Params: array of string);
begin
btnLastSearch.Click;
end;
procedure TfrmFindDlg.cm_View(const Params: array of string);
begin
btnView.Click;
end;
procedure TfrmFindDlg.cm_Edit(const Params: array of string);
begin
btnEdit.Click;
end;
procedure TfrmFindDlg.cm_GoToFile(const Params: array of string);
begin
btnGoToPath.Click;
end;
procedure TfrmFindDlg.cm_FeedToListbox(const Params: array of string);
begin
btnWorkWithFound.Click;
end;
procedure TfrmFindDlg.cm_PageStandard(const Params: array of string);
begin
pgcSearch.PageIndex:=0;
end;
procedure TfrmFindDlg.cm_PageAdvanced(const Params: array of string);
begin
pgcSearch.PageIndex:=1;
end;
procedure TfrmFindDlg.cm_PagePlugins(const Params: array of string);
begin
pgcSearch.PageIndex:=2;
end;
procedure TfrmFindDlg.cm_PageLoadSave(const Params: array of string);
begin
pgcSearch.PageIndex:=3;
end;
procedure TfrmFindDlg.cm_PageResults(const Params: array of string);
begin
pgcSearch.PageIndex:=4;
end;
procedure TfrmFindDlg.btnStopClick(Sender: TObject);
begin
StopSearch;
AfterSearchStopped;
AfterSearchFocus;
// btnNewSearch.SetFocus;
end;
procedure TfrmFindDlg.FormCloseQuery(Sender: TObject;var CanClose: Boolean);
// was on F7
begin
if FFindThread<>nil then // we can't call StopSearch because it method will set focus on unavailable field
begin
FFindThread.OnTerminate:=nil;
FFindThread.Terminate;
FUpdateTimer.OnTimer(FUpdateTimer);
FUpdateTimer.Enabled := False;
FFindThread := nil;
end;
AfterSearchStopped;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default := True;
{$ENDIF}
CanClose:= not Assigned(FFindThread);
end;
procedure TfrmFindDlg.btnCloseClick(Sender: TObject);
begin
Close;
end;
procedure TfrmFindDlg.FormDestroy(Sender: TObject);
begin
FreeThenNil(FoundedStringCopy);
FreeThenNil(DsxPlugins);
end;
procedure TfrmFindDlg.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
{
case Key of
{$IF DEFINED(LCLGTK) or DEFINED(LCLGTK2)}
// On LCLGTK2 default button on Enter does not work.
VK_RETURN, VK_SELECT:
begin
Key := 0;
if btnStart.Enabled then
btnStart.Click
else
btnStop.Click;
end;
{$ENDIF}
VK_ESCAPE:
begin
Key := 0;
if FSearchingActive then
StopSearch
else
Close;
end;
VK_1..VK_5:
begin
if Shift * KeyModifiersShortcut = [ssAlt] then
begin
pgcSearch.PageIndex := Key - VK_1;
Key := 0;
end;
end;
VK_TAB:
begin
if Shift * KeyModifiersShortcut = [ssCtrl] then
begin
pgcSearch.SelectNextPage(True);
Key := 0;
end
else if Shift * KeyModifiersShortcut = [ssCtrl, ssShift] then
begin
pgcSearch.SelectNextPage(False);
Key := 0;
end;
end;
VK_F7 :
begin
if FFindThread<>nil then
begin
FFindThread.OnTerminate:=nil;
FFindThread.Terminate;
FUpdateTimer.OnTimer(FUpdateTimer);
FUpdateTimer.Enabled := False;
FFindThread := nil;
end;
AfterSearchStopped;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default := True;
{$ENDIF}
if cmbFindText.Focused then // if F7 on already focused textSearch field- disable text search and set focun on file mask
begin
cbFindText.Checked:=False;
cmbFindFileMask.SetFocus;
cmbFindFileMask.SelectAll;
exit;
end else
begin
pgcSearch.PageIndex:= 0;
cbFindText.Checked:=True;
cmbFindText.SetFocus;
cmbFindText.SelectAll;
end;
end;
end;
}
end;
procedure TfrmFindDlg.frmFindDlgClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
glsMaskHistory.Assign(cmbFindFileMask.Items);
glsSearchExcludeFiles.Assign(cmbExcludeFiles.Items);
glsSearchExcludeDirectories.Assign(cmbExcludeDirectories.Items);
if Assigned(FFrmAttributesEdit) then
begin
FFrmAttributesEdit.Close;
FreeAndNil(FFrmAttributesEdit);
end;
end;
procedure TfrmFindDlg.frmFindDlgShow(Sender: TObject);
var
I: Integer;
begin
pgcSearch.PageIndex:= 0;
if cmbFindFileMask.Visible then
cmbFindFileMask.SelectAll;
cmbFindFileMask.Items.Assign(glsMaskHistory);
cmbFindText.Items.Assign(glsSearchHistory);
// if we already search text then use last searched text
if not gFirstTextSearch then
begin
if glsSearchHistory.Count > 0 then
cmbFindText.Text:= glsSearchHistory[0];
end;
cmbReplaceText.Items.Assign(glsReplaceHistory);
cmbExcludeFiles.Items.Assign(glsSearchExcludeFiles);
cmbExcludeDirectories.Items.Assign(glsSearchExcludeDirectories);
cbFindText.Checked := False;
lsFoundedFiles.Canvas.Font := lsFoundedFiles.Font;
cmbPlugin.Clear;
for I:= 0 to DSXPlugins.Count-1 do
begin
cmbPlugin.AddItem(DSXPlugins.GetDSXModule(i).Name+' (' + DSXPlugins.GetDSXModule(I).Descr+' )',nil);
end;
if (cmbPlugin.Items.Count>0) then cmbPlugin.ItemIndex:=0;
if pgcSearch.ActivePage = tsStandard then
if cmbFindFileMask.CanFocus then
cmbFindFileMask.SetFocus;
cbSelectedFiles.Checked := FSelectedFiles.Count > 0;
cbSelectedFiles.Enabled := cbSelectedFiles.Checked;
end;
procedure TfrmFindDlg.gbDirectoriesResize(Sender: TObject);
begin
pnlDirectoriesDepth.Width := gbDirectories.Width div 3;
end;
procedure TfrmFindDlg.lbSearchTemplatesSelectionChange(Sender: TObject; User: boolean);
begin
if lbSearchTemplates.ItemIndex < 0 then
lblSearchContents.Caption := ''
else
begin
with gSearchTemplateList.Templates[lbSearchTemplates.ItemIndex].SearchRecord do
begin
if StartPath <> '' then
lblSearchContents.Caption := '"' + FilesMasks + '" -> "' + StartPath + '"'
else
lblSearchContents.Caption := '"' + FilesMasks + '"';
end;
end;
end;
procedure TfrmFindDlg.LoadSelectedTemplate;
var
SearchTemplate: TSearchTemplate;
begin
if lbSearchTemplates.ItemIndex < 0 then Exit;
SearchTemplate:= gSearchTemplateList.Templates[lbSearchTemplates.ItemIndex];
if Assigned(SearchTemplate) then
begin
FLastTemplateName := SearchTemplate.TemplateName;
LoadTemplate(SearchTemplate.SearchRecord);
end;
end;
procedure TfrmFindDlg.LoadTemplate(const Template: TSearchTemplateRec);
begin
with Template do
begin
if StartPath <> '' then
edtFindPathStart.Text:= StartPath;
cmbExcludeDirectories.Text:= ExcludeDirectories;
cmbFindFileMask.Text:= FilesMasks;
cmbExcludeFiles.Text:= ExcludeFiles;
if (SearchDepth + 1 >= 0) and (SearchDepth + 1 < cmbSearchDepth.Items.Count) then
cmbSearchDepth.ItemIndex:= SearchDepth + 1
else
cmbSearchDepth.ItemIndex:= 0;
cbRegExp.Checked := RegExp;
cbPartialNameSearch.Checked := IsPartialNameSearch;
cbFollowSymLinks.Checked := FollowSymLinks;
cbFindInArchive.Checked := FindInArchives;
// attributes
edtAttrib.Text:= AttributesPattern;
// file date/time
cbDateFrom.Checked:= IsDateFrom;
if IsDateFrom then
ZVDateFrom.Date:= DateTimeFrom;
cbDateTo.Checked:= IsDateTo;
if IsDateTo then
ZVDateTo.Date:= DateTimeTo;
cbTimeFrom.Checked:= IsTimeFrom;
if IsTimeFrom then
ZVTimeFrom.Time:= DateTimeFrom;
cbTimeTo.Checked:= IsTimeTo;
if IsTimeTo then
ZVTimeTo.Time:= DateTimeTo;
// not older then
cbNotOlderThan.Checked:= IsNotOlderThan;
seNotOlderThan.Value:= NotOlderThan;
cmbNotOlderThanUnit.ItemIndex := TimeUnitToComboIndex[NotOlderThanUnit];
// file size
cbFileSizeFrom.Checked:= IsFileSizeFrom;
cbFileSizeTo.Checked:= IsFileSizeTo;
seFileSizeFrom.Value:= FileSizeFrom;
seFileSizeTo.Value:= FileSizeTo;
cmbFileSizeUnit.ItemIndex := FileSizeUnitToComboIndex[FileSizeUnit];
// find/replace text
cbFindText.Checked:= IsFindText;
cmbFindText.Text:= FindText;
cbReplaceText.Checked:= IsReplaceText;
cmbReplaceText.Text:= ReplaceText;
cbCaseSens.Checked:= CaseSensitive;
cbNotContainingText.Checked:= NotContainingText;
cbTextRegExp.Checked:= TextRegExp;
cmbEncoding.Text:= TextEncoding;
// plugins
cmbPlugin.Text:= SearchPlugin;
frmContentPlugins.Load(Template);
end;
end;
procedure TfrmFindDlg.lsFoundedFilesDblClick(Sender: TObject);
begin
// if not FSearchingActive then btnGoToPathClick(Sender);
btnGoToPathClick(Sender);
end;
procedure TfrmFindDlg.lsFoundedFilesKeyDown(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
if (Shift = []) and (lsFoundedFiles.ItemIndex <> -1) then
begin
case Key of
VK_F3:
begin
ShowViewerByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
Key := 0;
end;
VK_F4:
begin
ShowEditorByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
Key := 0;
end;
VK_DELETE:
begin
miRemoveFromLlistClick(Sender);
Key := 0;
end;
VK_RETURN:
begin
if not FSearchingActive then
begin
btnGoToPathClick(Sender);
Key := 0;
end;
end;
VK_RIGHT,VK_LEFT:
begin
if not FSearchingActive then
begin
if FRButtonPanelSender<>nil then (FRButtonPanelSender as TButton).SetFocus
else btnNewSearch.SetFocus;
// btnNewSearch.SetFocus;
Key := 0;
end else
begin
Key := 0;
btnStop.SetFocus;
end;
end;
end;
end;
end;
procedure TfrmFindDlg.lsFoundedFilesMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i:integer;
begin
i:=lsFoundedFiles.ItemAtPos(Point(X,Y),False);
if (i>=0) then
begin
LastClickResultsPath:=GetDeepestExistingPath(lsFoundedFiles.Items[i]);
if (Button=mbRight)and(lsFoundedFiles.Selected[i]<>True) then
begin
lsFoundedFiles.ClearSelection;
lsFoundedFiles.Selected[i]:=True;
end;
end;
end;
procedure TfrmFindDlg.lsFoundedFilesMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i:integer;
sPath:string;
AFile: TFile;
AFiles: TFiles;
Panel:TFileView;
FileList :TFileTree;
pt: TPoint;
begin
if Button=mbRight then
begin
if Shift=[ssCtrl] then // Show System context menu
begin
{$IF DEFINED(MSWINDOWS)}
try
AFiles:= TFiles.Create(LastClickResultsPath);
AFiles.Path:=LastClickResultsPath;
i:=0;
while i<lsFoundedFiles.Count do
begin
if lsFoundedFiles.Selected[i] then
begin
sPath:=lsFoundedFiles.Items[i];
AFile:= TFileSystemFileSource.CreateFile(sPath);
AFiles.Add(aFile);
end;
inc(i);
end;
try
pt.X := X;
pt.Y := Y;
pt := ClientToScreen(pt);
ShowContextMenu(lsFoundedFiles, AFiles, pt.X, pt.Y, False, nil);
finally
FreeAndNil(AFiles);
end;
except
on E: EContextMenuException do
ShowException(E)
else;
end;
{$ENDIF}
end else
begin
PopupMenuFind.PopUp; // Show DC menu
end;
end;
end;
procedure TfrmFindDlg.lsFoundedFilesMouseWheelDown(Sender: TObject;
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
if (Shift=[ssCtrl])and(gFonts[dcfEditor].Size<MAX_FONT_SIZE_EDITOR) then
begin
//gFonts[dcfEditor].Size:=gFonts[dcfEditor].Size+1;
//FontOptionsToFont(gFonts[dcfEditor], Editor.Font);
lsFoundedFiles.Font.Size:=lsFoundedFiles.Font.Size-1;
Handled:=True;
end;
end;
procedure TfrmFindDlg.lsFoundedFilesMouseWheelUp(Sender: TObject;
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
if (Shift=[ssCtrl])and(gFonts[dcfEditor].Size<MAX_FONT_SIZE_EDITOR) then
begin
//gFonts[dcfFileSearchResults].Size:=gFonts[dcfFileSearchResults].Size+1;
//FontOptionsToFont(gFonts[dcfEditor], Editor.Font);
lsFoundedFiles.Font.Size:=lsFoundedFiles.Font.Size+1;
Handled:=True;
end;
end;
procedure TfrmFindDlg.miOpenInNewTabClick(Sender: TObject);
var
i,ind:integer;
sPath:string;
Notebook: TFileViewNotebook;
NewPage: TFileViewPage;
begin
ind:=lsFoundedFiles.ItemIndex;
Notebook := frmMain.ActiveNotebook;
i:=0;
while i<lsFoundedFiles.Count do
begin
if lsFoundedFiles.Selected[i] then
begin
sPath :=lsFoundedFiles.Items[i];
sPath := GetDeepestExistingPath(sPath);
NewPage := Notebook.NewPage(Notebook.ActiveView);
NewPage.FileView.CurrentPath:=sPath;
NewPage.FileView.SetActiveFile(ExtractFileName(lsFoundedFiles.Items[i]));
end;
inc(i);
end;
end;
procedure TfrmFindDlg.miRemoveFromLlistClick(Sender: TObject);
var
i:Integer;
begin
if lsFoundedFiles.ItemIndex=-1 then Exit;
if lsFoundedFiles.SelCount = 0 then Exit;
for i:=lsFoundedFiles.Items.Count-1 downto 0 do
if lsFoundedFiles.Selected[i] then
lsFoundedFiles.Items.Delete(i);
miShowAllFound.Enabled:=True;
end;
procedure TfrmFindDlg.miShowAllFoundClick(Sender: TObject);
begin
lsFoundedFiles.Clear;
lsFoundedFiles.Items.AddStrings(FoundedStringCopy);
miShowAllFound.Enabled:=False;
end;
procedure TfrmFindDlg.miShowInEditorClick(Sender: TObject);
begin
if lsFoundedFiles.ItemIndex>=0 then
ShowEditorByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
end;
procedure TfrmFindDlg.miShowInViewerClick(Sender: TObject);
var
sl:TStringList;
i:Integer;
begin
if lsFoundedFiles.ItemIndex=-1 then Exit;
sl:=TStringList.Create;
try
for i:=0 to lsFoundedFiles.Items.Count-1 do
if lsFoundedFiles.Selected[i] then
sl.Add(lsFoundedFiles.Items[i]);
ShowViewer(sl);
finally
sl.Free;
end;
end;
procedure TfrmFindDlg.seFileSizeFromChange(Sender: TObject);
begin
if not FUpdating then
cbFileSizeFrom.Checked:= (seFileSizeFrom.Value > 0);
end;
procedure TfrmFindDlg.seFileSizeToChange(Sender: TObject);
begin
if not FUpdating then
cbFileSizeTo.Checked:= (seFileSizeTo.Value > 0);
end;
procedure TfrmFindDlg.SelectTemplate(const ATemplateName: String);
var
i: Integer;
begin
for i := 0 to lbSearchTemplates.Count - 1 do
if lbSearchTemplates.Items[i] = ATemplateName then
begin
lbSearchTemplates.ItemIndex := i;
Break;
end;
end;
procedure TfrmFindDlg.seNotOlderThanChange(Sender: TObject);
begin
if not FUpdating then
cbNotOlderThan.Checked:= (seNotOlderThan.Value > 0);
end;
procedure TfrmFindDlg.tsLoadSaveShow(Sender: TObject);
begin
UpdateTemplatesList;
if (lbSearchTemplates.Count > 0) and (lbSearchTemplates.ItemIndex = -1) then
lbSearchTemplates.ItemIndex := 0;
end;
procedure TfrmFindDlg.tsStandardEnter(Sender: TObject);
begin
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default:= True;
{$ENDIF}
end;
procedure TfrmFindDlg.UpdateTemplatesList;
var
OldIndex: Integer;
begin
OldIndex := lbSearchTemplates.ItemIndex;
gSearchTemplateList.LoadToStringList(lbSearchTemplates.Items);
if OldIndex <> -1 then
lbSearchTemplates.ItemIndex := OldIndex;
end;
procedure TfrmFindDlg.OnUpdateTimer(Sender: TObject);
begin
if Assigned(FFindThread) then
begin
lblStatus.Caption := Format(rsFindScanned, [FFindThread.FilesScanned])+FTimeSearch;
lblFound.Caption := Format(rsFindFound, [FFindThread.FilesFound]);
lblCurrent.Caption := rsFindScanning + ': ' + FFindThread.CurrentDir;
end;
end;
procedure TfrmFindDlg.ZVDateFromChange(Sender: TObject);
begin
if not FUpdating then
cbDateFrom.Checked:= True;
end;
procedure TfrmFindDlg.ZVDateToChange(Sender: TObject);
begin
if not FUpdating then
cbDateTo.Checked:= True;
end;
procedure TfrmFindDlg.ZVTimeFromChange(Sender: TObject);
begin
if not FUpdating then
cbTimeFrom.Checked:= True;
end;
procedure TfrmFindDlg.ZVTimeToChange(Sender: TObject);
begin
if not FUpdating then
cbTimeTo.Checked:= True;
end;
procedure TfrmFindDlg.OnAddAttribute(Sender: TObject);
var
sAttr: String;
begin
sAttr := edtAttrib.Text;
if edtAttrib.SelStart > 0 then
// Insert at caret position.
Insert((Sender as TfrmAttributesEdit).AttrsAsText, sAttr, edtAttrib.SelStart + 1)
else
sAttr := sAttr + (Sender as TfrmAttributesEdit).AttrsAsText;
edtAttrib.Text := sAttr;
end;
function TfrmFindDlg.InvalidRegExpr(AChecked: Boolean; const ARegExpr: String): Boolean;
var
sMsg: String;
begin
Result:= False;
if AChecked then
try
ExecRegExpr(ARegExpr, '');
except
on E: Exception do
begin
Result:= True;
sMsg:= StringReplace(cbRegExp.Caption, '&', '', [rfReplaceAll]);
MessageDlg(sMsg + ': ' + E.Message, mtError, [mbOK], 0);
end;
end;
end;
procedure TfrmFindDlg.pgcSearchChange(Sender: TObject);
begin
if (pgcSearch.ActivePage = tsStandard) and not cmbFindFileMask.Focused then
begin
if cmbFindFileMask.CanFocus then
cmbFindFileMask.SetFocus;
end;
end;
procedure TfrmFindDlg.SaveTemplate(SaveStartingPath: Boolean);
var
sName: String;
SearchTemplate: TSearchTemplate;
SearchRec: TSearchTemplateRec;
begin
if InvalidRegExpr(cbRegExp.Checked, cmbFindFileMask.Text) or
InvalidRegExpr(cbTextRegExp.Checked, cmbFindText.Text) then
Exit;
sName := FLastTemplateName;
if not InputQuery(rsFindSaveTemplateCaption, rsFindSaveTemplateTitle, sName) then
begin
ModalResult:= mrCancel;
Exit;
end;
FLastTemplateName := sName;
SearchTemplate := gSearchTemplateList.TemplateByName[sName];
if Assigned(SearchTemplate) then
begin
// TODO: Ask for overwriting existing template.
FillFindOptions(SearchRec, SaveStartingPath);
SearchTemplate.SearchRecord := SearchRec;
Exit;
end;
SearchTemplate:= TSearchTemplate.Create;
try
SearchTemplate.TemplateName:= sName;
FillFindOptions(SearchRec, SaveStartingPath);
SearchTemplate.SearchRecord := SearchRec;
gSearchTemplateList.Add(SearchTemplate);
except
FreeAndNil(SearchTemplate);
raise;
end;
UpdateTemplatesList;
SelectTemplate(FLastTemplateName);
end;
initialization
TFormCommands.RegisterCommandsForm(TfrmFindDlg, HotkeysCategory, @rsHotkeyCategoryFindFiles);
finalization
FreeAndNil(GfrmFindDlgInstance);
end.