mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
2919 lines
86 KiB
ObjectPascal
2919 lines
86 KiB
ObjectPascal
{
|
|
Double Commander
|
|
-------------------------------------------------------------------------
|
|
Find dialog, with searching in thread
|
|
|
|
Copyright (C) 2006-2021 Alexander Koblov (alexx2000@mail.ru)
|
|
Copyright (C) 2003-2004 Radek Cervinka (radek.cervinka@centrum.cz)
|
|
|
|
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, see <http://www.gnu.org/licenses/>.
|
|
|
|
Notes:
|
|
1. on MacOS, two Buttons may be display the focused state at the same time.
|
|
it's caused by Lazarus, it will be fixed atfer Lazarus merges related Patches.
|
|
see also: https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39981
|
|
}
|
|
|
|
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, uRegExprU,
|
|
uSearchTemplate, fSearchPlugin, uFileView, types, DCStrUtils,
|
|
ActnList, uOSForms, uShellContextMenu, uExceptions, uFileSystemFileSource,
|
|
uFormCommands, uHotkeyManager, LCLVersion, uWcxModule, uFileSource;
|
|
|
|
{$IF DEFINED(LCLGTK2) or DEFINED(LCLQT) or DEFINED(LCLQT5) or DEFINED(LCLQT6)}
|
|
{$DEFINE FIX_DEFAULT}
|
|
{$ENDIF}
|
|
|
|
const
|
|
HotkeysCategory = 'Find files';
|
|
|
|
type
|
|
{ TfrmFindDlg }
|
|
TfrmFindDlg = class(TModalForm, IFormCommands)
|
|
actIntelliFocus: TAction;
|
|
actCancel: TAction;
|
|
actClose: TAction;
|
|
actEdit: TAction;
|
|
actGoToFile: TAction;
|
|
actFeedToListbox: TAction;
|
|
actCancelClose: TAction;
|
|
actPagePrev: TAction;
|
|
actPageNext: TAction;
|
|
actPageResults: TAction;
|
|
actPageLoadSave: TAction;
|
|
actPagePlugins: TAction;
|
|
actPageAdvanced: TAction;
|
|
actPageStandard: TAction;
|
|
actView: TAction;
|
|
actLastSearch: TAction;
|
|
actNewSearch: TAction;
|
|
actStart: TAction;
|
|
actList: TActionList;
|
|
Bevel2: TBevel;
|
|
Bevel3: 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;
|
|
cbOfficeXML: TCheckBox;
|
|
chkDuplicateContent: TCheckBox;
|
|
chkDuplicateSize: TCheckBox;
|
|
chkDuplicateHash: TCheckBox;
|
|
chkDuplicateName: TCheckBox;
|
|
chkDuplicates: TCheckBox;
|
|
chkHex: TCheckBox;
|
|
cmbExcludeDirectories: TComboBoxWithDelItems;
|
|
cmbNotOlderThanUnit: TComboBox;
|
|
cmbFileSizeUnit: TComboBox;
|
|
cmbEncoding: TComboBox;
|
|
cmbSearchDepth: TComboBox;
|
|
cbRegExp: TCheckBox;
|
|
cmbPlugin: TComboBox;
|
|
cmbReplaceText: TComboBoxWithDelItems;
|
|
cmbFindText: TComboBoxWithDelItems;
|
|
cmbExcludeFiles: TComboBoxWithDelItems;
|
|
edtAttrib: TEdit;
|
|
cmbFindPathStart: TComboBoxWithDelItems;
|
|
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;
|
|
pnlDuplicates: TPanel;
|
|
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;
|
|
btnChooseFolder: TSpeedButton;
|
|
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;
|
|
actFreeFromMem: TAction;
|
|
actFreeFromMemAllOthers: TAction;
|
|
actConfigFileSearchHotKeys: TAction;
|
|
actNewSearchClearFilters: TAction;
|
|
mmMainMenu: TMainMenu;
|
|
miNewSearchClearFilters: TMenuItem;
|
|
miConfigFileSearchHotKeys: TMenuItem;
|
|
miOptions: TMenuItem;
|
|
miAction: TMenuItem;
|
|
miNewSearch: TMenuItem;
|
|
miLastSearch: TMenuItem;
|
|
miStart: TMenuItem;
|
|
miCancel: TMenuItem;
|
|
miFreeFromMem: TMenuItem;
|
|
miFreeFromMemAllOthers: TMenuItem;
|
|
miSeparator1: TMenuItem;
|
|
miCancelClose: TMenuItem;
|
|
miClose: TMenuItem;
|
|
miViewTab: TMenuItem;
|
|
miPageStandard: TMenuItem;
|
|
miPageAdvanced: TMenuItem;
|
|
miPagePlugins: TMenuItem;
|
|
miPageLoadSave: TMenuItem;
|
|
miPageResults: TMenuItem;
|
|
miSeparator2: TMenuItem;
|
|
miResult: TMenuItem;
|
|
miView: TMenuItem;
|
|
miEdit: TMenuItem;
|
|
miFeedToListbox: TMenuItem;
|
|
miGoToFile: TMenuItem;
|
|
procedure actExecute(Sender: TObject);
|
|
procedure btnAddAttributeClick(Sender: TObject);
|
|
procedure btnAttrsHelpClick(Sender: TObject);
|
|
procedure btnNewSearchKeyDown(Sender: TObject; var Key: word;
|
|
{%H-}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 cbOfficeXMLChange(Sender: TObject);
|
|
procedure cbOpenedTabsChange(Sender: TObject);
|
|
procedure cbPartialNameSearchChange(Sender: TObject);
|
|
procedure cbRegExpChange(Sender: TObject);
|
|
procedure cbTextRegExpChange(Sender: TObject);
|
|
procedure cbSelectedFilesChange(Sender: TObject);
|
|
procedure chkDuplicateContentChange(Sender: TObject);
|
|
procedure chkDuplicateHashChange(Sender: TObject);
|
|
procedure chkDuplicatesChange(Sender: TObject);
|
|
procedure chkDuplicateSizeChange(Sender: TObject);
|
|
procedure chkHexChange(Sender: TObject);
|
|
procedure cmbEncodingSelect(Sender: TObject);
|
|
procedure cbFindTextChange(Sender: TObject);
|
|
procedure cbUsePluginChange(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure btnSelDirClick(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 FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
|
procedure FormDestroy(Sender: TObject);
|
|
{$IF DEFINED(FIX_DEFAULT)}
|
|
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
{$ENDIF}
|
|
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;
|
|
{%H-}Shift: TShiftState; X, Y: integer);
|
|
procedure lsFoundedFilesMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: integer);
|
|
procedure lsFoundedFilesMouseWheelDown(Sender: TObject; Shift: TShiftState;
|
|
{%H-}MousePos: TPoint; var Handled: boolean);
|
|
procedure lsFoundedFilesMouseWheelUp(Sender: TObject; Shift: TShiftState;
|
|
{%H-}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);
|
|
procedure PopupMenuFindPopup(Sender: TObject);
|
|
function GetTextSearchOptions: UIntPtr;
|
|
procedure CancelCloseAndFreeMem;
|
|
procedure LoadHistory;
|
|
procedure SaveHistory;
|
|
procedure LoadPlugins;
|
|
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;
|
|
FSearchWithDSXPluginInProgress: boolean;
|
|
FSearchWithWDXPluginInProgress: boolean;
|
|
FFreeOnClose: boolean;
|
|
FAtLeastOneSearchWasDone: boolean;
|
|
FFileSource: IFileSource;
|
|
FWcxModule: TWcxModule;
|
|
|
|
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 FindInArchive(AFileView: TFileView);
|
|
procedure FillFindOptions(out FindOptions: TSearchTemplateRec; SetStartPath: boolean);
|
|
procedure FindOptionsToDSXSearchRec(const AFindOptions: TSearchTemplateRec;
|
|
out SRec: TDsxSearchRecord);
|
|
procedure FoundedStringCopyAdded(Sender: TObject);
|
|
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: Boolean;
|
|
procedure SetWindowCaption(AWindowCaptionStyle: byte);
|
|
function ObjectType(Index: Integer): TCheckBoxState;
|
|
function GetFileMask: String;
|
|
public
|
|
FoundedStringCopy: TStringList;
|
|
class function Instance: TfrmFindDlg;
|
|
public
|
|
LastClickResultsPath: string;
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure ClearFilter(bClearSearchLocation: boolean = True);
|
|
procedure ClearResults;
|
|
procedure ThreadTerminate(Sender: TObject);
|
|
procedure EnableControls(AEnabled: Boolean);
|
|
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 {%H-}Params: array of string);
|
|
procedure cm_Start(const {%H-}Params: array of string);
|
|
procedure cm_CancelClose(const {%H-}Params: array of string);
|
|
procedure cm_Cancel(const {%H-}Params: array of string);
|
|
procedure cm_Close(const {%H-}Params: array of string);
|
|
procedure cm_NewSearch(const {%H-}Params: array of string);
|
|
procedure cm_LastSearch(const {%H-}Params: array of string);
|
|
procedure cm_View(const {%H-}Params: array of string);
|
|
procedure cm_Edit(const {%H-}Params: array of string);
|
|
procedure cm_GoToFile(const {%H-}Params: array of string);
|
|
procedure cm_FeedToListbox(const {%H-}Params: array of string);
|
|
procedure cm_PageNext(const Params: array of string);
|
|
procedure cm_PagePrev(const Params: array of string);
|
|
procedure cm_PageStandard(const {%H-}Params: array of string);
|
|
procedure cm_PageAdvanced(const {%H-}Params: array of string);
|
|
procedure cm_PagePlugins(const {%H-}Params: array of string);
|
|
procedure cm_PageLoadSave(const {%H-}Params: array of string);
|
|
procedure cm_PageResults(const {%H-}Params: array of string);
|
|
procedure cm_NewSearchClearFilters(const {%H-}Params: array of string);
|
|
procedure cm_FreeFromMem(const {%H-}Params: array of string);
|
|
procedure cm_FreeFromMemAllOthers(const {%H-}Params: array of string);
|
|
procedure cm_ConfigFileSearchHotKeys(const {%H-}Params: array of string);
|
|
end;
|
|
|
|
{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.)
|
|
}
|
|
|
|
{ TListOffrmFindDlgInstance }
|
|
TListOffrmFindDlgInstance = class(TList)
|
|
private
|
|
function GetfrmFindDlgInstance(Index: integer): TfrmFindDlg;
|
|
public
|
|
constructor Create;
|
|
procedure Clear; override;
|
|
function Add(AfrmFindDlg: TfrmFindDlg): integer;
|
|
property frmFindDlgInstance[Index: integer]: TfrmFindDlg read GetfrmFindDlgInstance;
|
|
end;
|
|
|
|
var
|
|
// [ ListOffrmFindDlgInstance ]
|
|
// This list will hold in memory pointers to our find dialog forms.
|
|
ListOffrmFindDlgInstance: TListOffrmFindDlgInstance;
|
|
frmFindDlgUsingPluginDSX: TfrmFindDlg = nil;
|
|
frmFindDlgUsingPluginWDX: TfrmFindDlg = nil;
|
|
|
|
procedure ShowFindDlg(FileView: TFileView; const TemplateName: string; bCreateNewFindDlg: boolean = False);
|
|
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, uFileSourceUtil, uOfficeXML,
|
|
uSearchResultFileSource, uFile, uFileProperty, uColumnsFileView,
|
|
uFileViewNotebook, uKeyboard, uOSUtils, uArchiveFileSourceUtil,
|
|
DCOSUtils, uRegExprA, uRegExprW, uDebug, uShowMsg, uConvEncoding,
|
|
uColumns, uFileFunctions, uFileSorting, uWcxArchiveFileSource,
|
|
DCConvertEncoding, WcxPlugin
|
|
{$IFDEF DARKWIN}
|
|
, uDarkStyle
|
|
{$ENDIF}
|
|
;
|
|
|
|
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);
|
|
|
|
wcs_NewSearch = $01;
|
|
wcs_StartSearch = $0A;
|
|
wcs_EndSearch = $1B;
|
|
|
|
type
|
|
{ TStringListTemp }
|
|
TStringListTemp = class(TStringList)
|
|
public
|
|
function AddObject(const S: string; AObject: TObject): integer; override;
|
|
end;
|
|
|
|
var
|
|
gSearchWithDSXPluginInProgress: boolean = False;
|
|
gSearchWithWDXPluginInProgress: boolean = False;
|
|
|
|
{ TListOffrmFindDlgInstance.Create }
|
|
constructor TListOffrmFindDlgInstance.Create;
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
{ TListOffrmFindDlgInstance.Clear }
|
|
procedure TListOffrmFindDlgInstance.Clear;
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := pred(Count) downto 0 do
|
|
if frmFindDlgInstance[i] <> nil then
|
|
frmFindDlgInstance[i].Free;
|
|
inherited Clear;
|
|
end;
|
|
|
|
{ TListOffrmFindDlgInstance.Add }
|
|
function TListOffrmFindDlgInstance.Add(AfrmFindDlg: TfrmFindDlg): integer;
|
|
begin
|
|
Result := inherited Add(AfrmFindDlg);
|
|
end;
|
|
|
|
{ TListOffrmFindDlgInstance.GetfrmFindDlgInstance }
|
|
function TListOffrmFindDlgInstance.GetfrmFindDlgInstance(Index: integer): TfrmFindDlg;
|
|
begin
|
|
Result := TfrmFindDlg(Items[Index]);
|
|
end;
|
|
|
|
procedure SAddFileProc({%H-}PlugNr: integer; FoundFile: PChar); dcpcall;
|
|
var
|
|
s: string;
|
|
begin
|
|
s := string(FoundFile);
|
|
if s = '' then
|
|
begin
|
|
TfrmFindDlg.Instance.AfterSearchStopped;
|
|
TfrmFindDlg.Instance.btnStart.Default := True;
|
|
end
|
|
else
|
|
begin
|
|
TfrmFindDlg.Instance.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;
|
|
|
|
{ ShowFindDlg }
|
|
procedure ShowFindDlg(FileView: TFileView; const TemplateName: string; bCreateNewFindDlg: boolean = False);
|
|
var
|
|
ASelectedFiles: TFiles = nil;
|
|
I: integer;
|
|
AfrmFindDlgInstance: TfrmFindDlg;
|
|
bFirstFindDlg: boolean;
|
|
begin
|
|
if not Assigned(FileView) then
|
|
raise Exception.Create('ShowFindDlg: FileView=nil');
|
|
|
|
bFirstFindDlg := (ListOffrmFindDlgInstance.Count = 0);
|
|
|
|
// 1. We create a new form: if it's the first search we do OR if we've been instructed to do so (cm_AddNewSearch)
|
|
if bFirstFindDlg or bCreateNewFindDlg then
|
|
begin
|
|
AfrmFindDlgInstance := TfrmFindDlg.Create(nil);
|
|
ListOffrmFindDlgInstance.add(AfrmFindDlgInstance);
|
|
end
|
|
else
|
|
begin
|
|
AfrmFindDlgInstance := ListOffrmFindDlgInstance.frmFindDlgInstance[pred(ListOffrmFindDlgInstance.Count)];
|
|
end;
|
|
|
|
// 2. If we don't have a search in progress, then clear and set a few things.
|
|
if not AfrmFindDlgInstance.FSearchingActive then
|
|
begin
|
|
with AfrmFindDlgInstance do
|
|
begin
|
|
// Prepare window for search files
|
|
LoadHistory;
|
|
LoadPlugins;
|
|
ClearFilter;
|
|
// SetWindowCaption(wcs_NewSearch);
|
|
cmbFindPathStart.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;
|
|
|
|
FindInArchive(FileView);
|
|
|
|
if Length(TemplateName) > 0 then
|
|
begin
|
|
FUpdating := True;
|
|
UpdateTemplatesList;
|
|
SelectTemplate(TemplateName);
|
|
LoadSelectedTemplate;
|
|
FUpdating := False;
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
AfrmFindDlgInstance.ShowOnTop;
|
|
end;
|
|
|
|
{ ShowDefineTemplateDlg }
|
|
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
|
|
LoadHistory;
|
|
LoadPlugins;
|
|
Caption := rsFindDefineTemplate;
|
|
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 := FLastTemplateName;
|
|
end;
|
|
end;
|
|
finally
|
|
AForm.Free;
|
|
end;
|
|
end;
|
|
|
|
{ ShowUseTemplateDlg }
|
|
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
|
|
LoadHistory;
|
|
LoadPlugins;
|
|
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 }
|
|
|
|
{ TStringListTemp.AddObject }
|
|
function TStringListTemp.AddObject(const S: string; AObject: TObject): integer;
|
|
begin
|
|
Result := Count;
|
|
InsertItem(Result, S, AObject);
|
|
end;
|
|
|
|
{ TfrmFindDlg }
|
|
|
|
{ TfrmFindDlg.FormCreate }
|
|
procedure TfrmFindDlg.FormCreate(Sender: TObject);
|
|
var
|
|
I: integer;
|
|
HMFindFiles: THMForm;
|
|
begin
|
|
if not gShowMenuBarInFindFiles then FreeAndNil(mmMainMenu);
|
|
DsxPlugins := TDSXModuleList.Create;
|
|
FoundedStringCopy := TStringListTemp.Create;
|
|
FoundedStringCopy.OwnsObjects := True;
|
|
FFreeOnClose := False;
|
|
FAtLeastOneSearchWasDone := False;
|
|
FSearchWithDSXPluginInProgress := False;
|
|
FSearchWithWDXPluginInProgress := False;
|
|
|
|
// load language
|
|
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);
|
|
|
|
cbOfficeXML.Hint := StripHotkey(cbOfficeXML.Caption) + ' ' + OFFICE_FILTER;
|
|
|
|
// 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.Items.Insert(0, 'Default');
|
|
cmbEncoding.ItemIndex := 0;
|
|
|
|
// 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;
|
|
|
|
btnStart.Default := True;
|
|
|
|
cmbNotOlderThanUnit.ItemIndex := 3; // Days
|
|
cmbFileSizeUnit.ItemIndex := 1; // Kilobytes
|
|
cbPartialNameSearch.Checked := gPartialNameSearch;
|
|
FontOptionsToFont(gFonts[dcfSearchResults], lsFoundedFiles.Font);
|
|
|
|
InitPropStorage(Self);
|
|
|
|
HMFindFiles := HotMan.Register(Self, HotkeysCategory);
|
|
HMFindFiles.RegisterActionList(actList);
|
|
|
|
CloneMainAction(frmMain.actAddNewSearch, actList, miViewTab, -1);
|
|
CloneMainAction(frmMain.actViewSearches, actList, miViewTab, -1);
|
|
CloneMainAction(frmMain.actDeleteSearches, actList, miAction, -1);
|
|
CloneMainAction(frmMain.actConfigSearches, actList, miOptions, 0);
|
|
|
|
{$IF DEFINED(FIX_DEFAULT)}
|
|
if (ListOffrmFindDlgInstance.Count = 0) then
|
|
Application.AddOnKeyDownBeforeHandler(@FormKeyDown);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbUsePluginChange }
|
|
procedure TfrmFindDlg.cbUsePluginChange(Sender: TObject);
|
|
begin
|
|
EnableControl(cmbPlugin, cbUsePlugin.Checked);
|
|
|
|
if not FUpdating and cmbPlugin.Enabled and cmbPlugin.CanSetFocus and (Sender = cbUsePlugin) then
|
|
begin
|
|
cmbPlugin.SetFocus;
|
|
cmbPlugin.SelectAll;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cmbEncodingSelect }
|
|
procedure TfrmFindDlg.cmbEncodingSelect(Sender: TObject);
|
|
var
|
|
SupportedEncoding: Boolean;
|
|
Encoding: String;
|
|
begin
|
|
Encoding := cmbEncoding.Text;
|
|
SupportedEncoding:= SingleByteEncoding(Encoding);
|
|
if (not SupportedEncoding) and TRegExprU.AvailableNew then
|
|
begin
|
|
Encoding := NormalizeEncoding(Encoding);
|
|
if Encoding = EncodingDefault then Encoding := GetDefaultTextEncoding;
|
|
SupportedEncoding := Encoding = EncodingUTF8;
|
|
end;
|
|
|
|
cbTextRegExp.Enabled := cbFindText.Checked and SupportedEncoding and (not chkHex.Checked);
|
|
if not cbTextRegExp.Enabled then cbTextRegExp.Checked := False;
|
|
|
|
cbCaseSens.Enabled:= cbFindText.Checked and (not cbReplaceText.Checked) and (not chkHex.Checked) and (not cbTextRegExp.Checked);
|
|
if cbFindText.Checked and (not cbCaseSens.Enabled) then cbCaseSens.Checked := not cbTextRegExp.Checked;
|
|
end;
|
|
|
|
{ TfrmFindDlg.Create }
|
|
constructor TfrmFindDlg.Create(TheOwner: TComponent);
|
|
var
|
|
C: TPortableNetworkGraphic;
|
|
begin
|
|
FSelectedFiles := TStringList.Create;
|
|
inherited Create(TheOwner);
|
|
FUpdateTimer := TTimer.Create(Self);
|
|
FUpdateTimer.Interval := 100;
|
|
FUpdateTimer.Enabled := False;
|
|
FUpdateTimer.OnTimer := @OnUpdateTimer;
|
|
|
|
try
|
|
C := TPortableNetworkGraphic.Create;
|
|
C.LoadFromResourceName(hInstance, ResBtnSelDir);
|
|
btnChooseFolder.Glyph.Assign(C);
|
|
finally
|
|
C.Free;
|
|
end;
|
|
|
|
FCommands := TFormCommands.Create(Self, actList);
|
|
end;
|
|
|
|
{ TfrmFindDlg.Destroy }
|
|
destructor TfrmFindDlg.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
FSelectedFiles.Free;
|
|
FLastSearchTemplate.Free;
|
|
end;
|
|
|
|
{ TfrmFindDlg.DisableControlsForTemplate }
|
|
procedure TfrmFindDlg.DisableControlsForTemplate;
|
|
begin
|
|
lblFindPathStart.Visible := False;
|
|
cmbFindPathStart.Visible := False;
|
|
cbFollowSymLinks.Visible := False;
|
|
cbSelectedFiles.Visible := False;
|
|
cbOpenedTabs.Visible := False;
|
|
btnStart.Visible := False;
|
|
btnStop.Visible := False;
|
|
btnNewSearch.Visible := False;
|
|
btnLastSearch.Visible := False;
|
|
btnSearchSaveWithStartingPath.Visible := False;
|
|
gbFindData.Visible := False;
|
|
tsResults.TabVisible := False;
|
|
actPageResults.Enabled := False;
|
|
chkDuplicates.Visible:= False;
|
|
pnlDuplicates.Visible:= False;
|
|
if mmMainMenu <> nil then FreeAndNil(mmMainMenu);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbFindTextChange }
|
|
procedure TfrmFindDlg.cbFindTextChange(Sender: TObject);
|
|
begin
|
|
EnableControl(chkHex, cbFindText.Checked);
|
|
EnableControl(cmbFindText, cbFindText.Checked);
|
|
EnableControl(cmbEncoding, cbFindText.Checked);
|
|
EnableControl(cbCaseSens, cbFindText.Checked);
|
|
EnableControl(cbReplaceText, cbFindText.Checked and not (cbFindInArchive.Checked or chkHex.Checked or cbOfficeXML.Checked));
|
|
EnableControl(cbNotContainingText, cbFindText.Checked);
|
|
EnableControl(cbTextRegExp, cbFindText.Checked);
|
|
EnableControl(cbOfficeXML, cbFindText.Checked);
|
|
lblEncoding.Enabled := cbFindText.Checked;
|
|
cbReplaceText.Checked := False;
|
|
cmbEncodingSelect(nil);
|
|
|
|
if not FUpdating and cmbFindText.Enabled and cmbFindText.CanSetFocus and (Sender = cbFindText) then
|
|
begin
|
|
cmbFindText.SetFocus;
|
|
cmbFindText.SelectAll;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.ClearFilter }
|
|
procedure TfrmFindDlg.ClearFilter(bClearSearchLocation: boolean = True);
|
|
var
|
|
FreezeTime: TDateTime;
|
|
begin
|
|
FUpdating := True;
|
|
|
|
FLastTemplateName := '';
|
|
if bClearSearchLocation then
|
|
begin
|
|
cmbFindPathStart.Text := '';
|
|
cmbExcludeDirectories.Text := '';
|
|
end;
|
|
|
|
if gInitiallyClearFileMask then
|
|
cmbFindFileMask.Text := ''
|
|
else if glsMaskHistory.Count > 0 then begin
|
|
cmbFindFileMask.Text:= glsMaskHistory[0];
|
|
end;
|
|
|
|
// 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;
|
|
|
|
cmbSearchDepth.ItemIndex := 0;
|
|
cmbExcludeFiles.Text := '';
|
|
cbPartialNameSearch.Checked := gPartialNameSearch;
|
|
cbRegExp.Checked := False;
|
|
|
|
// attributes
|
|
edtAttrib.Text := '';
|
|
|
|
// file date/time
|
|
FreezeTime := Now;
|
|
ZVDateFrom.DateTime := FreezeTime;
|
|
ZVDateTo.DateTime := FreezeTime;
|
|
ZVTimeFrom.DateTime := FreezeTime;
|
|
ZVTimeTo.DateTime := FreezeTime;
|
|
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
|
|
chkHex.Checked := False;
|
|
cbFindText.Checked := False;
|
|
cbReplaceText.Checked := False;
|
|
cbCaseSens.Checked := False;
|
|
cbOfficeXML.Checked := False;
|
|
cbNotContainingText.Checked := False;
|
|
cmbEncoding.ItemIndex := 0;
|
|
cmbEncodingSelect(nil);
|
|
|
|
// duplicates
|
|
chkDuplicates.Checked:= False;
|
|
|
|
// plugins
|
|
cbUsePlugin.Checked:= False;
|
|
frmContentPlugins.chkUsePlugins.Checked:= False;
|
|
|
|
FUpdating := False;
|
|
end;
|
|
|
|
{ TfrmFindDlg.ClearResults }
|
|
procedure TfrmFindDlg.ClearResults;
|
|
begin
|
|
lsFoundedFiles.Clear;
|
|
lsFoundedFiles.Tag := 0;
|
|
lsFoundedFiles.ScrollWidth := 0;
|
|
FoundedStringCopy.Clear;
|
|
EnableControls(False);
|
|
end;
|
|
|
|
{ TfrmFindDlg.btnSearchLoadClick }
|
|
procedure TfrmFindDlg.btnSearchLoadClick(Sender: TObject);
|
|
begin
|
|
LoadSelectedTemplate;
|
|
end;
|
|
|
|
{ TfrmFindDlg.btnSearchSaveWithStartingPathClick }
|
|
procedure TfrmFindDlg.btnSearchSaveWithStartingPathClick(Sender: TObject);
|
|
begin
|
|
SaveTemplate(True);
|
|
end;
|
|
|
|
{ TfrmFindDlg.btnSearchDeleteClick }
|
|
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;
|
|
|
|
{ TfrmFindDlg.btnAttrsHelpClick }
|
|
procedure TfrmFindDlg.btnAttrsHelpClick(Sender: TObject);
|
|
begin
|
|
ShowHelpOrErrorForKeyword('', edtAttrib.HelpKeyword);
|
|
end;
|
|
|
|
{ TfrmFindDlg.actExecute }
|
|
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;
|
|
|
|
{ TfrmFindDlg.btnAddAttributeClick }
|
|
procedure TfrmFindDlg.btnAddAttributeClick(Sender: TObject);
|
|
begin
|
|
if not Assigned(FFrmAttributesEdit) then
|
|
begin
|
|
FFrmAttributesEdit := TfrmAttributesEdit.Create(Self);
|
|
FFrmAttributesEdit.OnOk := @OnAddAttribute;
|
|
end;
|
|
FFrmAttributesEdit.Reset;
|
|
{$IFDEF DARKWIN}
|
|
if g_darkModeEnabled then
|
|
FFrmAttributesEdit.ShowModal
|
|
else
|
|
{$ENDIF}
|
|
if not (fsModal in FormState) then
|
|
FFrmAttributesEdit.Show
|
|
else
|
|
begin
|
|
FFrmAttributesEdit.ShowModal;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.btnSearchSaveClick }
|
|
procedure TfrmFindDlg.btnSearchSaveClick(Sender: TObject);
|
|
begin
|
|
SaveTemplate(False);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbCaseSensChange }
|
|
procedure TfrmFindDlg.cbCaseSensChange(Sender: TObject);
|
|
begin
|
|
if cbCaseSens.Checked then cbTextRegExp.Checked := False;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbDateFromChange }
|
|
procedure TfrmFindDlg.cbDateFromChange(Sender: TObject);
|
|
begin
|
|
UpdateColor(ZVDateFrom, cbDateFrom.Checked);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbDateToChange }
|
|
procedure TfrmFindDlg.cbDateToChange(Sender: TObject);
|
|
begin
|
|
UpdateColor(ZVDateTo, cbDateTo.Checked);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbFindInArchiveChange }
|
|
procedure TfrmFindDlg.cbFindInArchiveChange(Sender: TObject);
|
|
begin
|
|
EnableControl(cbReplaceText, cbFindText.Checked and not cbFindInArchive.Checked);
|
|
if cbReplaceText.Checked then cbReplaceText.Checked := cbReplaceText.Enabled;
|
|
actView.Enabled := pnlResultsBottom.Enabled and (not cbFindInArchive.Checked);
|
|
actEdit.Enabled := pnlResultsBottom.Enabled and (not cbFindInArchive.Checked);
|
|
actFeedToListbox.Enabled := pnlResultsBottom.Enabled and (not cbFindInArchive.Checked);
|
|
cbReplaceTextChange(cbReplaceText);
|
|
end;
|
|
|
|
procedure TfrmFindDlg.cbOfficeXMLChange(Sender: TObject);
|
|
begin
|
|
if cbOfficeXML.Checked then
|
|
begin
|
|
chkHex.Checked:= False;
|
|
cbReplaceText.Checked:= False;
|
|
end;
|
|
cbReplaceText.Enabled:= not (chkHex.Checked or cbOfficeXML.Checked);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbOpenedTabsChange }
|
|
procedure TfrmFindDlg.cbOpenedTabsChange(Sender: TObject);
|
|
begin
|
|
cbSelectedFiles.Enabled := not cbOpenedTabs.Checked AND (FSelectedFiles.Count > 0);
|
|
cbFollowSymLinks.Enabled := not cbOpenedTabs.Checked;
|
|
cmbFindPathStart.Enabled := not cbOpenedTabs.Checked;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbPartialNameSearchChange }
|
|
procedure TfrmFindDlg.cbPartialNameSearchChange(Sender: TObject);
|
|
begin
|
|
if cbPartialNameSearch.Checked then cbRegExp.Checked := False;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbRegExpChange }
|
|
procedure TfrmFindDlg.cbRegExpChange(Sender: TObject);
|
|
begin
|
|
if cbRegExp.Checked then cbPartialNameSearch.Checked := False;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbTextRegExpChange }
|
|
procedure TfrmFindDlg.cbTextRegExpChange(Sender: TObject);
|
|
begin
|
|
if cbTextRegExp.Checked then
|
|
begin
|
|
if cbCaseSens.Enabled then
|
|
begin
|
|
cbCaseSens.Tag := Integer(cbCaseSens.Checked);
|
|
end;
|
|
end
|
|
else if not cbCaseSens.Enabled then
|
|
begin
|
|
cbCaseSens.Checked := Boolean(cbCaseSens.Tag);
|
|
end;
|
|
cmbEncodingSelect(cmbEncoding);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbSelectedFilesChange }
|
|
procedure TfrmFindDlg.cbSelectedFilesChange(Sender: TObject);
|
|
begin
|
|
cmbFindPathStart.Enabled := not cbSelectedFiles.Checked;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.chkDuplicateContentChange(Sender: TObject);
|
|
begin
|
|
if chkDuplicateContent.Checked then
|
|
begin
|
|
chkDuplicateSize.Checked:= True;
|
|
chkDuplicateHash.Checked:= False;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.chkDuplicateHashChange(Sender: TObject);
|
|
begin
|
|
if chkDuplicateHash.Checked then
|
|
begin
|
|
chkDuplicateSize.Checked:= True;
|
|
chkDuplicateContent.Checked:= False;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.chkDuplicatesChange(Sender: TObject);
|
|
begin
|
|
pnlDuplicates.Enabled:= chkDuplicates.Checked;
|
|
if chkDuplicates.Checked then
|
|
begin
|
|
if not (chkDuplicateName.Checked or chkDuplicateSize.Checked) then
|
|
chkDuplicateName.Checked:= True;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.chkDuplicateSizeChange(Sender: TObject);
|
|
begin
|
|
if not chkDuplicateSize.Checked then
|
|
begin
|
|
chkDuplicateHash.Checked:= False;
|
|
chkDuplicateContent.Checked:= False;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.chkHexChange(Sender: TObject);
|
|
begin
|
|
if chkHex.Checked then
|
|
begin
|
|
cmbEncoding.ItemIndex:= 0;
|
|
if cbCaseSens.Enabled then
|
|
begin
|
|
cbCaseSens.Tag := Integer(cbCaseSens.Checked);
|
|
end;
|
|
cbOfficeXML.Checked:= False;
|
|
cbReplaceText.Checked:= False;
|
|
end
|
|
else if not cbCaseSens.Enabled then
|
|
begin
|
|
cbCaseSens.Checked := Boolean(cbCaseSens.Tag);
|
|
end;
|
|
cmbEncoding.Enabled:= not chkHex.Checked;
|
|
cbReplaceText.Enabled:= not (chkHex.Checked or cbOfficeXML.Checked);
|
|
cmbEncodingSelect(cmbEncoding);
|
|
end;
|
|
|
|
{ TfrmFindDlg.btnSelDirClick }
|
|
procedure TfrmFindDlg.btnSelDirClick(Sender: TObject);
|
|
var
|
|
S, AFolder: String;
|
|
begin
|
|
S := cmbFindPathStart.Text;
|
|
AFolder:= ExtractFilePath(ExcludeTrailingBackslash(S));
|
|
if not mbDirectoryExists(AFolder) then AFolder := EmptyStr;
|
|
if SelectDirectory(rsFindWhereBeg, AFolder, S, gShowSystemFiles) then
|
|
cmbFindPathStart.Text := S;
|
|
end;
|
|
|
|
{ TfrmFindDlg.btnNewSearchKeyDown }
|
|
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;
|
|
|
|
{ TfrmFindDlg.FillFindOptions }
|
|
procedure TfrmFindDlg.FillFindOptions(out FindOptions: TSearchTemplateRec; SetStartPath: boolean);
|
|
begin
|
|
with FindOptions do
|
|
begin
|
|
if SetStartPath then
|
|
StartPath := cmbFindPathStart.Text
|
|
else
|
|
StartPath := '';
|
|
ExcludeDirectories := cmbExcludeDirectories.Text;
|
|
FilesMasks := GetFileMask;
|
|
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;
|
|
HexValue := chkHex.Checked;
|
|
CaseSensitive := cbCaseSens.Checked;
|
|
NotContainingText := cbNotContainingText.Checked;
|
|
TextRegExp := cbTextRegExp.Checked;
|
|
TextEncoding := cmbEncoding.Text;
|
|
OfficeXML := cbOfficeXML.Checked;
|
|
{ Duplicates }
|
|
Duplicates:= chkDuplicates.Checked;
|
|
DuplicateName:= chkDuplicateName.Checked;
|
|
DuplicateSize:= chkDuplicateSize.Checked;
|
|
DuplicateHash:= chkDuplicateHash.Checked;
|
|
DuplicateContent:= chkDuplicateContent.Checked;
|
|
{ Plugins }
|
|
if not cbUsePlugin.Checked then
|
|
SearchPlugin := EmptyStr
|
|
else begin
|
|
SearchPlugin := cmbPlugin.Text;
|
|
end;
|
|
frmContentPlugins.Save(FindOptions);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.FindOptionsToDSXSearchRec }
|
|
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;
|
|
|
|
{ TfrmFindDlg.StopSearch }
|
|
procedure TfrmFindDlg.StopSearch;
|
|
begin
|
|
if FSearchingActive then
|
|
begin
|
|
if (cbUsePlugin.Checked) and (cmbPlugin.ItemIndex <> -1) then
|
|
begin
|
|
if FSearchWithDSXPluginInProgress then
|
|
begin
|
|
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallStopSearch;
|
|
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallFinalize;
|
|
end;
|
|
AfterSearchStopped;
|
|
AfterSearchFocus;
|
|
end;
|
|
|
|
if Assigned(FFindThread) then
|
|
begin
|
|
FFindThread.Terminate;
|
|
FFindThread := nil;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.Instance }
|
|
class function TfrmFindDlg.Instance: TfrmFindDlg;
|
|
begin
|
|
Result:=frmFindDlgUsingPluginDSX;
|
|
end;
|
|
|
|
{ TfrmFindDlg.lbSearchTemplatesDblClick }
|
|
procedure TfrmFindDlg.lbSearchTemplatesDblClick(Sender: TObject);
|
|
begin
|
|
LoadSelectedTemplate;
|
|
end;
|
|
|
|
{ TfrmFindDlg.AfterSearchStopped }
|
|
procedure TfrmFindDlg.AfterSearchStopped;
|
|
begin
|
|
actCancel.Enabled := False;
|
|
actStart.Enabled := True;;
|
|
actClose.Enabled := True;
|
|
actNewSearch.Enabled := True;
|
|
actNewSearchClearFilters.Enabled := True;
|
|
actLastSearch.Enabled := True;
|
|
FSearchingActive := False;
|
|
if FSearchWithDSXPluginInProgress then
|
|
begin
|
|
FSearchWithDSXPluginInProgress := False;
|
|
gSearchWithDSXPluginInProgress := False;
|
|
end;
|
|
if FSearchWithWDXPluginInProgress then
|
|
begin
|
|
FSearchWithWDXPluginInProgress := False;
|
|
gSearchWithWDXPluginInProgress := False;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.AfterSearchFocus }
|
|
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
|
|
btnGoToPath.SetFocus;
|
|
lsFoundedFiles.SetFocus;
|
|
if lsFoundedFiles.ItemIndex<0 then lsFoundedFiles.ItemIndex:=0;
|
|
lsFoundedFiles.Selected[lsFoundedFiles.ItemIndex] := True;
|
|
end
|
|
else
|
|
begin
|
|
if actNewSearch.Enabled then
|
|
btnNewSearch.SetFocus
|
|
else
|
|
btnStart.SetFocus;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.FindInArchive(AFileView: TFileView);
|
|
var
|
|
AEnabled: Boolean;
|
|
AFileSource: IWcxArchiveFileSource;
|
|
begin
|
|
FFileSource:= aFileView.FileSource;
|
|
AEnabled:= FFileSource.IsClass(TWcxArchiveFileSource);
|
|
|
|
cbOpenedTabs.Visible:= not AEnabled;
|
|
cbSelectedFiles.Visible:= not AEnabled;
|
|
cbFindInArchive.Enabled:= not AEnabled;
|
|
cbReplaceText.Enabled:= (not AEnabled) and (cbFindText.Checked);
|
|
cmbFindPathStart.Enabled:= not AEnabled;
|
|
btnChooseFolder.Enabled:= not AEnabled;
|
|
chkDuplicates.Enabled:= not AEnabled;
|
|
cmbSearchDepth.Enabled:= not AEnabled;
|
|
tsPlugins.TabVisible:= not AEnabled;
|
|
actPagePlugins.Enabled:= not AEnabled;
|
|
cbFollowSymLinks.Enabled:= not AEnabled;
|
|
|
|
if not AEnabled then
|
|
FWcxModule:= nil
|
|
else begin
|
|
AFileSource:= (FFileSource as IWcxArchiveFileSource);
|
|
FWcxModule:= AFileSource.WcxModule;
|
|
end;
|
|
|
|
cbFindText.Enabled:= (AEnabled = False) or (AFileSource.PluginCapabilities and PK_CAPS_SEARCHTEXT <> 0);
|
|
|
|
if AEnabled then
|
|
begin
|
|
cmbSearchDepth.ItemIndex:= 0;
|
|
cbFindInArchive.Checked:= True;
|
|
cbReplaceText.Checked:= False;
|
|
chkDuplicates.Checked:= False;
|
|
cbOpenedTabs.Checked:= False;
|
|
cbSelectedFiles.Checked:= False;
|
|
cbFollowSymLinks.Checked:= False;
|
|
cmbFindPathStart.Text:= aFileView.CurrentAddress;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.FoundedStringCopyAdded(Sender: TObject);
|
|
begin
|
|
if FoundedStringCopy.Count > 0 then
|
|
begin
|
|
EnableControls(True);
|
|
FoundedStringCopyChanged(Sender);
|
|
FoundedStringCopy.OnChange:= @FoundedStringCopyChanged;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.FoundedStringCopyChanged }
|
|
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);
|
|
{$IF DEFINED(LCLQT) or DEFINED(LCLQT5) or DEFINED(LCLQT6)}
|
|
Application.ProcessMessages;
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbFileSizeFromChange }
|
|
procedure TfrmFindDlg.cbFileSizeFromChange(Sender: TObject);
|
|
begin
|
|
UpdateColor(seFileSizeFrom, cbFileSizeFrom.Checked);
|
|
EnableControl(cmbFileSizeUnit, cbFileSizeFrom.Checked or cbFileSizeTo.Checked);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbFileSizeToChange }
|
|
procedure TfrmFindDlg.cbFileSizeToChange(Sender: TObject);
|
|
begin
|
|
UpdateColor(seFileSizeTo, cbFileSizeTo.Checked);
|
|
EnableControl(cmbFileSizeUnit, cbFileSizeFrom.Checked or cbFileSizeTo.Checked);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbNotOlderThanChange }
|
|
procedure TfrmFindDlg.cbNotOlderThanChange(Sender: TObject);
|
|
begin
|
|
UpdateColor(seNotOlderThan, cbNotOlderThan.Checked);
|
|
EnableControl(cmbNotOlderThanUnit, cbNotOlderThan.Checked);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbReplaceTextChange }
|
|
procedure TfrmFindDlg.cbReplaceTextChange(Sender: TObject);
|
|
begin
|
|
EnableControl(cmbReplaceText, cbReplaceText.Checked and cbFindText.Checked);
|
|
cbNotContainingText.Checked := False;
|
|
cbNotContainingText.Enabled := (not cbReplaceText.Checked and cbFindText.Checked);
|
|
|
|
cmbEncodingSelect(cmbEncoding);
|
|
|
|
if not FUpdating and cmbReplaceText.Enabled and cmbReplaceText.CanSetFocus then
|
|
begin
|
|
cmbReplaceText.SetFocus;
|
|
cmbReplaceText.SelectAll;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbTimeFromChange }
|
|
procedure TfrmFindDlg.cbTimeFromChange(Sender: TObject);
|
|
begin
|
|
UpdateColor(ZVTimeFrom, cbTimeFrom.Checked);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cbTimeToChange }
|
|
procedure TfrmFindDlg.cbTimeToChange(Sender: TObject);
|
|
begin
|
|
UpdateColor(ZVTimeTo, cbTimeTo.Checked);
|
|
end;
|
|
|
|
{ TfrmFindDlg.ThreadTerminate }
|
|
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;
|
|
SetWindowCaption(wcs_EndSearch);
|
|
AfterSearchStopped;
|
|
AfterSearchFocus;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.EnableControls(AEnabled: Boolean);
|
|
begin
|
|
actView.Enabled:= AEnabled;
|
|
actEdit.Enabled:= AEnabled;
|
|
actGoToFile.Enabled:= AEnabled;
|
|
actFeedToListbox.Enabled:= AEnabled;
|
|
pnlResultsBottom.Enabled:= AEnabled;
|
|
end;
|
|
|
|
{ TfrmFindDlg.FocusOnResults }
|
|
procedure TfrmFindDlg.FocusOnResults(Sender: TObject);
|
|
begin
|
|
FRButtonPanelSender := Sender;
|
|
|
|
if pgcSearch.ActivePage = tsResults then
|
|
begin
|
|
btnStart.Default := False;
|
|
if lsFoundedFiles.SelCount = 0 then lsFoundedFiles.ItemIndex := 0;
|
|
lsFoundedFiles.SetFocus;
|
|
lsFoundedFiles.Selected[lsFoundedFiles.ItemIndex] := True;
|
|
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_IntelliFocus }
|
|
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;
|
|
|
|
btnStart.Default := True;
|
|
|
|
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;
|
|
|
|
{ TfrmFindDlg.cm_Start }
|
|
procedure TfrmFindDlg.cm_Start(const Params: array of string);
|
|
var
|
|
sPath: String;
|
|
sr: TDsxSearchRecord;
|
|
SearchTemplate, TmpTemplate: TSearchTemplateRec;
|
|
PassedSelectedFiles: TStringList = nil;
|
|
begin
|
|
cm_Cancel([]);
|
|
Self.Repaint;
|
|
Application.ProcessMessages;
|
|
|
|
if cbFindInArchive.Enabled then
|
|
begin
|
|
if (cmbFindPathStart.Text = '') then begin
|
|
cmbFindPathStart.Text:= mbGetCurrentDir;
|
|
end;
|
|
for sPath in SplitPath(cmbFindPathStart.Text) do
|
|
begin
|
|
if not mbDirectoryExists(sPath) then
|
|
begin
|
|
ShowMessage(Format(rsFindDirNoEx, [sPath]));
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (cbFindText.Checked and chkHex.Checked) then
|
|
try
|
|
HexToBin(cmbFindText.Text);
|
|
except
|
|
on E: EConvertError do
|
|
begin
|
|
MessageDlg(E.Message, mtError, [mbOK], 0, mbOK);
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
SaveHistory;
|
|
FAtLeastOneSearchWasDone := True;
|
|
|
|
if cbSelectedFiles.Checked and (FSelectedFiles.Count = 0) then
|
|
begin
|
|
ShowMessage(rsMsgNoFilesSelected);
|
|
cbSelectedFiles.Checked := False;
|
|
Exit;
|
|
end;
|
|
|
|
if not (chkDuplicateName.Checked or chkDuplicateSize.Checked) then
|
|
chkDuplicates.Checked:= False;
|
|
|
|
// Show search results page
|
|
pgcSearch.ActivePage := tsResults;
|
|
|
|
if lsFoundedFiles.CanSetFocus then
|
|
lsFoundedFiles.SetFocus;
|
|
|
|
ClearResults;
|
|
miShowAllFound.Enabled := False;
|
|
|
|
FSearchingActive := True;
|
|
actCancel.Enabled := True;
|
|
|
|
btnStop.Default := True;
|
|
|
|
actStart.Enabled := False;
|
|
actClose.Enabled := False;
|
|
actNewSearch.Enabled := False;
|
|
actNewSearchClearFilters.Enabled := False;
|
|
actLastSearch.Enabled := False;
|
|
|
|
if (not frmContentPlugins.chkUsePlugins.Checked) OR (not gSearchWithWDXPluginInProgress) then
|
|
begin
|
|
FillFindOptions(SearchTemplate, True);
|
|
if frmContentPlugins.chkUsePlugins.Checked then
|
|
begin
|
|
gSearchWithWDXPluginInProgress := True;
|
|
FSearchWithWDXPluginInProgress := True;
|
|
frmFindDlgUsingPluginWDX := Self;
|
|
end;
|
|
|
|
if not Assigned(FLastSearchTemplate) then
|
|
FLastSearchTemplate := TSearchTemplate.Create;
|
|
TmpTemplate := SearchTemplate;
|
|
TmpTemplate.StartPath := ''; // Don't remember starting path.
|
|
FLastSearchTemplate.SearchRecord := TmpTemplate;
|
|
|
|
FoundedStringCopy.OnChange:= @FoundedStringCopyAdded;
|
|
|
|
try
|
|
if (cbUsePlugin.Checked) and (cmbPlugin.ItemIndex <> -1) then
|
|
begin
|
|
if not gSearchWithDSXPluginInProgress then
|
|
begin
|
|
gSearchWithDSXPluginInProgress := True;
|
|
FSearchWithDSXPluginInProgress := True;
|
|
frmFindDlgUsingPluginDSX := Self;
|
|
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
|
|
MsgError(rsSearchWithDSXPluginInProgress);
|
|
StopSearch;
|
|
end;
|
|
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
|
|
Archive := FWcxModule;
|
|
Items := FoundedStringCopy;
|
|
OnTerminate := @ThreadTerminate; // will update the buttons after search is finished
|
|
end;
|
|
|
|
SetWindowCaption(wcs_StartSearch);
|
|
|
|
FTimeSearch := '';
|
|
FFindThread.Start;
|
|
FUpdateTimer.Enabled := True;
|
|
FUpdateTimer.OnTimer(FUpdateTimer);
|
|
|
|
FRButtonPanelSender := nil;
|
|
end;
|
|
except
|
|
StopSearch;
|
|
raise;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
MsgError(rsSearchWithWDXPluginInProgress);
|
|
StopSearch;
|
|
AfterSearchStopped;
|
|
AfterSearchFocus;
|
|
end;
|
|
end; //cm_Start
|
|
|
|
{ TfrmFindDlg.cm_CancelClose }
|
|
procedure TfrmFindDlg.cm_CancelClose(const Params: array of string);
|
|
begin
|
|
if FSearchingActive then
|
|
StopSearch
|
|
else
|
|
Close;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_Cancel }
|
|
procedure TfrmFindDlg.cm_Cancel(const Params: array of string);
|
|
begin
|
|
StopSearch;
|
|
AfterSearchStopped;
|
|
AfterSearchFocus;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_NewSearch }
|
|
procedure TfrmFindDlg.cm_NewSearch(const Params: array of string);
|
|
var
|
|
Param: string;
|
|
sActionWithFilters: string = '';
|
|
begin
|
|
StopSearch;
|
|
|
|
if length(Params) = 0 then
|
|
begin
|
|
case gNewSearchClearFiltersAction of
|
|
fonsClear: sActionWithFilters := 'clear';
|
|
fonsPrompt: if msgYesNo(rsClearFiltersOrNot) then sActionWithFilters := 'clear';
|
|
end;
|
|
end;
|
|
for Param in Params do
|
|
GetParamValue(Param, 'filters', sActionWithFilters);
|
|
if sActionWithFilters = 'clear' then ClearFilter(False);
|
|
|
|
pgcSearch.PageIndex := 0;
|
|
ClearResults;
|
|
miShowAllFound.Enabled := False;
|
|
lblStatus.Caption := EmptyStr;
|
|
lblCurrent.Caption := EmptyStr;
|
|
lblFound.Caption := EmptyStr;
|
|
SetWindowCaption(wcs_NewSearch);
|
|
if pgcSearch.ActivePage = tsStandard then cmbFindFileMask.SetFocus;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_LastSearch }
|
|
procedure TfrmFindDlg.cm_LastSearch(const Params: array of string);
|
|
begin
|
|
if Assigned(FLastSearchTemplate) then
|
|
begin
|
|
LoadTemplate(FLastSearchTemplate.SearchRecord);
|
|
pgcSearch.ActivePage := tsStandard;
|
|
cmbFindFileMask.SetFocus;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_View }
|
|
procedure TfrmFindDlg.cm_View(const Params: array of string);
|
|
begin
|
|
if pgcSearch.ActivePage = tsResults then
|
|
if lsFoundedFiles.ItemIndex <> -1 then
|
|
begin
|
|
if (ObjectType(lsFoundedFiles.ItemIndex) = cbChecked) then
|
|
msgError(rsMsgErrNotSupported)
|
|
else
|
|
ShowViewerByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_Edit }
|
|
procedure TfrmFindDlg.cm_Edit(const Params: array of string);
|
|
begin
|
|
if pgcSearch.ActivePage = tsResults then
|
|
if lsFoundedFiles.ItemIndex <> -1 then
|
|
begin
|
|
if (ObjectType(lsFoundedFiles.ItemIndex) = cbChecked) then
|
|
msgError(rsMsgErrNotSupported)
|
|
else
|
|
ShowEditorByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_GoToFile }
|
|
procedure TfrmFindDlg.cm_GoToFile(const Params: array of string);
|
|
var
|
|
AFile: TFile = nil;
|
|
TargetFile: string;
|
|
ArchiveFile: string;
|
|
FileSource: IFileSource;
|
|
begin
|
|
if lsFoundedFiles.ItemIndex <> -1 then
|
|
try
|
|
StopSearch;
|
|
TargetFile := lsFoundedFiles.Items[lsFoundedFiles.ItemIndex];
|
|
if (ObjectType(lsFoundedFiles.ItemIndex) = cbChecked) then
|
|
begin
|
|
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
|
|
if not mbFileSystemEntryExists(TargetFile) then begin
|
|
msgError(rsMsgObjectNotExists + LineEnding + TargetFile);
|
|
Exit;
|
|
end;
|
|
SetFileSystemPath(frmMain.ActiveFrame, ExtractFilePath(TargetFile));
|
|
frmMain.ActiveFrame.SetActiveFile(ExtractFileName(TargetFile));
|
|
end;
|
|
frmMain.RestoreWindow;
|
|
Close;
|
|
except
|
|
on E: Exception do MessageDlg(E.Message, mtError, [mbOK], 0);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_FeedToListbox }
|
|
procedure TfrmFindDlg.cm_FeedToListbox(const Params: array of string);
|
|
const
|
|
PluginDuplicate = 'Plugin().Duplicate{}';
|
|
var
|
|
I: integer;
|
|
sFileName: string;
|
|
SearchResultFS: ISearchResultFileSource;
|
|
FileList: TFileTree;
|
|
aFile: TFile;
|
|
Notebook: TFileViewNotebook;
|
|
NewPage: TFileViewPage;
|
|
DCFunc: String;
|
|
AProperty: TFileVariantProperty;
|
|
ANewSet: TPanelColumnsClass;
|
|
NewSorting: TFileSortings;
|
|
AHeader: TWCXHeader;
|
|
begin
|
|
StopSearch;
|
|
|
|
FileList := TFileTree.Create;
|
|
for i := 0 to lsFoundedFiles.Items.Count - 1 do
|
|
begin
|
|
if Assigned(FWcxModule) then
|
|
begin
|
|
AHeader:= TWCXHeader(lsFoundedFiles.Items.Objects[I]);
|
|
aFile := TWcxArchiveFileSource.CreateFile(ExtractFilePath(AHeader.FileName), AHeader);
|
|
FileList.AddSubNode(aFile);
|
|
end
|
|
else try
|
|
sFileName := lsFoundedFiles.Items[I];
|
|
aFile := TFileSystemFileSource.CreateFileFromFile(sFileName);
|
|
if FLastSearchTemplate.SearchRecord.Duplicates then
|
|
begin
|
|
AProperty:= TFileVariantProperty.Create(PluginDuplicate);
|
|
AProperty.Value:= TDuplicate(lsFoundedFiles.Items.Objects[I]).Index;
|
|
aFile.Properties[fpVariant]:= AProperty;
|
|
end;
|
|
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, FFileSource);
|
|
|
|
// Add new tab for search results.
|
|
Notebook := frmMain.ActiveNotebook;
|
|
NewPage := Notebook.NewPage(Notebook.ActiveView);
|
|
|
|
if FLastSearchTemplate.SearchRecord.Duplicates then
|
|
begin
|
|
if not (NewPage.FileView is TColumnsFileView) then
|
|
begin
|
|
NewPage.FileView:= TColumnsFileView.Create(NewPage, NewPage.FileView, EmptyStr);
|
|
NewPage.FileView.SetFocus;
|
|
end;
|
|
|
|
ANewSet:= TPanelColumnsClass.Create;
|
|
DCFunc := '[' + sFuncTypeDC + '().%s{}]';
|
|
I:= Notebook.ActiveView.ClientWidth;
|
|
ANewSet.Add(rsFuncName, Format(DCFunc, [TFileFunctionStrings[fsfName]]), I * 40 div 100, taLeftJustify);
|
|
ANewSet.Add(rsFuncGroup, '[' + PluginDuplicate + ']', I * 20 div 100, taCenter);
|
|
ANewSet.Add(rsFuncPath, Format(DCFunc, [TFileFunctionStrings[fsfPath]]), I * 40 div 100, taLeftJustify);
|
|
|
|
TColumnsFileView(NewPage.FileView).isSlave:= True;
|
|
TColumnsFileView(NewPage.FileView).ActiveColmSlave:= ANewSet;
|
|
|
|
TColumnsFileView(NewPage.FileView).UpdateColumnsView;
|
|
|
|
SetLength(NewSorting, 1);
|
|
SetLength(NewSorting[0].SortFunctions, 2);
|
|
NewSorting[0].SortFunctions[0] := fsfVariant;
|
|
NewSorting[0].SortFunctions[1] := fsfName;
|
|
NewSorting[0].SortDirection := sdAscending;
|
|
|
|
NewPage.FileView.Sorting:= NewSorting;
|
|
end;
|
|
|
|
NewPage.FileView.AddFileSource(SearchResultFS, SearchResultFS.GetRootDir);
|
|
NewPage.FileView.FlatView := True;
|
|
NewPage.MakeActive;
|
|
|
|
Close;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.cm_PageNext(const Params: array of string);
|
|
begin
|
|
with pgcSearch do
|
|
begin
|
|
if PageIndex = PageCount - 1 then
|
|
ActivePage := Pages[0]
|
|
else
|
|
ActivePage := Pages[PageIndex + 1];
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.cm_PagePrev(const Params: array of string);
|
|
begin
|
|
with pgcSearch do
|
|
begin
|
|
if PageIndex = 0 then
|
|
ActivePage := Pages[PageCount - 1]
|
|
else
|
|
ActivePage := Pages[PageIndex - 1];
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_PageStandard }
|
|
procedure TfrmFindDlg.cm_PageStandard(const Params: array of string);
|
|
begin
|
|
pgcSearch.ActivePage := tsStandard;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_PageAdvanced }
|
|
procedure TfrmFindDlg.cm_PageAdvanced(const Params: array of string);
|
|
begin
|
|
pgcSearch.ActivePage := tsAdvanced;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_PagePlugins }
|
|
procedure TfrmFindDlg.cm_PagePlugins(const Params: array of string);
|
|
begin
|
|
pgcSearch.ActivePage := tsPlugins;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_PageLoadSave }
|
|
procedure TfrmFindDlg.cm_PageLoadSave(const Params: array of string);
|
|
begin
|
|
pgcSearch.ActivePage := tsLoadSave;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_PageResults }
|
|
procedure TfrmFindDlg.cm_PageResults(const Params: array of string);
|
|
begin
|
|
pgcSearch.ActivePage := tsResults;
|
|
end;
|
|
|
|
{ TfrmFindDlg.FormCloseQuery }
|
|
procedure TfrmFindDlg.FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
|
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;
|
|
|
|
btnStart.Default := True;
|
|
|
|
CanClose := not Assigned(FFindThread);
|
|
end;
|
|
|
|
{ TfrmFindDlg.FormDestroy }
|
|
procedure TfrmFindDlg.FormDestroy(Sender: TObject);
|
|
begin
|
|
{$IF DEFINED(FIX_DEFAULT)}
|
|
if ListOffrmFindDlgInstance.Count = 0 then
|
|
Application.RemoveOnKeyDownBeforeHandler(@FormKeyDown);
|
|
{$ENDIF}
|
|
FreeAndNil(FoundedStringCopy);
|
|
FreeAndNil(DsxPlugins);
|
|
end;
|
|
|
|
{$IF DEFINED(FIX_DEFAULT)}
|
|
procedure TfrmFindDlg.FormKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
var
|
|
AParentForm: TCustomForm;
|
|
begin
|
|
if Key = VK_RETURN then
|
|
begin
|
|
if Sender is TControl then
|
|
begin
|
|
AParentForm := GetParentForm(TControl(Sender));
|
|
if (AParentForm is TfrmFindDlg) then
|
|
begin
|
|
if (Sender = TfrmFindDlg(AParentForm).lsFoundedFiles) then
|
|
TCustomListBox(Sender).OnKeyDown(Sender, Key, Shift)
|
|
else if (Sender is TCustomButton) then
|
|
begin
|
|
TCustomButton(Sender).Click;
|
|
Key:= 0;
|
|
end
|
|
{$if (lcl_fullversion < 1090000) and defined(lclgtk2)}
|
|
else begin
|
|
Key := 0;
|
|
if btnStart.Enabled then
|
|
btnStart.Click
|
|
else
|
|
btnStop.Click;
|
|
end;
|
|
{$endif}
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{ TfrmFindDlg.FormClose }
|
|
procedure TfrmFindDlg.frmFindDlgClose(Sender: TObject; var CloseAction: TCloseAction);
|
|
const
|
|
CLOSETAG: longint = $233528DE;
|
|
var
|
|
iSearchingForm: integer;
|
|
begin
|
|
if Assigned(FFrmAttributesEdit) then
|
|
begin
|
|
FFrmAttributesEdit.Close;
|
|
FreeAndNil(FFrmAttributesEdit);
|
|
end;
|
|
|
|
// Remove the whole thing from memory if no search was made at all.
|
|
// We remove it also if we've been asked to remove it.
|
|
// We ned to remove it from our list of instances "ListOffrmFindDlgInstance".
|
|
// We'll use the trick to give current form a magic tag number and then pass the list to delete the matching one.
|
|
if (not FAtLeastOneSearchWasDone) or FFreeOnClose then
|
|
begin
|
|
tag := CLOSETAG;
|
|
for iSearchingForm := pred(ListOffrmFindDlgInstance.Count) downto 0 do
|
|
if ListOffrmFindDlgInstance.frmFindDlgInstance[iSearchingForm].Tag = CLOSETAG then
|
|
ListOffrmFindDlgInstance.Delete(iSearchingForm);
|
|
|
|
CloseAction := caFree; // This will destroy the from on next step in the flow.
|
|
end;
|
|
{$IFDEF DARKWIN}
|
|
if g_darkModeEnabled and (CloseAction <> caFree) then DestroyHandle;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{ TfrmFindDlg.SetWindowCaption }
|
|
procedure TfrmFindDlg.SetWindowCaption(AWindowCaptionStyle: byte);
|
|
var
|
|
sBuildingCaptionName: string;
|
|
begin
|
|
sBuildingCaptionName := rsFindSearchFiles;
|
|
|
|
case (AWindowCaptionStyle and $07) of
|
|
2: sBuildingCaptionName := sBuildingCaptionName + ' - ' + rsFindScanning;
|
|
3: sBuildingCaptionName := sBuildingCaptionName + ' - ' + rsOperFinished;
|
|
end;
|
|
|
|
if (AWindowCaptionStyle and $10) <> 0 then
|
|
sBuildingCaptionName := sBuildingCaptionName + ' - ' + lblFound.Caption;
|
|
|
|
if (AWindowCaptionStyle and $08) <> 0 then
|
|
begin
|
|
sBuildingCaptionName := sBuildingCaptionName + ' - Files: ' + GetFileMask;
|
|
if cbFindText.Checked then
|
|
sBuildingCaptionName := sBuildingCaptionName + ' - Text: ' + cmbFindText.Text;
|
|
end;
|
|
|
|
Caption := sBuildingCaptionName;
|
|
end;
|
|
|
|
function TfrmFindDlg.ObjectType(Index: Integer): TCheckBoxState;
|
|
var
|
|
ATemp: TObject;
|
|
begin
|
|
ATemp:= lsFoundedFiles.Items.Objects[Index];
|
|
if (ATemp = nil) then
|
|
Result:= cbUnchecked
|
|
else if (ATemp is TWcxHeader) then
|
|
Result:= cbChecked
|
|
else
|
|
Result:= cbGrayed;
|
|
end;
|
|
|
|
function TfrmFindDlg.GetFileMask: String;
|
|
begin
|
|
if Length(cmbFindFileMask.Text) = 0 then
|
|
Result := AllFilesMask
|
|
else begin
|
|
Result := cmbFindFileMask.Text;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.LoadHistory }
|
|
procedure TfrmFindDlg.LoadHistory;
|
|
begin
|
|
cmbFindFileMask.Items.Assign(glsMaskHistory);
|
|
cmbFindPathStart.Items.Assign(glsSearchDirectories);
|
|
cmbExcludeDirectories.Items.Assign(glsSearchExcludeDirectories);
|
|
cmbExcludeFiles.Items.Assign(glsSearchExcludeFiles);
|
|
cmbFindText.Items.Assign(glsSearchHistory);
|
|
cmbReplaceText.Items.Assign(glsReplaceHistory);
|
|
end;
|
|
|
|
{ TfrmFindDlg.SaveHistory }
|
|
procedure TfrmFindDlg.SaveHistory;
|
|
begin
|
|
// 1. Add to find mask history
|
|
InsertFirstItem(cmbFindFileMask.Text, cmbFindFileMask);
|
|
glsMaskHistory.Assign(cmbFindFileMask.Items);
|
|
|
|
// 1. Add to find directory history
|
|
InsertFirstItem(cmbFindPathStart.Text, cmbFindPathStart);
|
|
glsSearchDirectories.Assign(cmbFindPathStart.Items);
|
|
|
|
// 2. Add to exclude directories history
|
|
InsertFirstItem(cmbExcludeDirectories.Text, cmbExcludeDirectories);
|
|
glsSearchExcludeFiles.Assign(cmbExcludeFiles.Items);
|
|
|
|
// 3. Add to exclude files history
|
|
InsertFirstItem(cmbExcludeFiles.Text, cmbExcludeFiles);
|
|
glsSearchExcludeDirectories.Assign(cmbExcludeDirectories.Items);
|
|
|
|
// 4. Add to search text history
|
|
if cbFindText.Checked then
|
|
begin
|
|
InsertFirstItem(cmbFindText.Text, cmbFindText, GetTextSearchOptions);
|
|
// Update search history, so it can be used in
|
|
// Viewer/Editor opened from find files dialog
|
|
gFirstTextSearch := False;
|
|
glsSearchHistory.Assign(cmbFindText.Items);
|
|
end;
|
|
|
|
// 5. 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;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.LoadPlugins;
|
|
var
|
|
I: Integer;
|
|
AModule: TDsxModule;
|
|
begin
|
|
cmbPlugin.Clear;
|
|
DSXPlugins.Assign(gDSXPlugins);
|
|
for I := 0 to DSXPlugins.Count - 1 do
|
|
begin
|
|
AModule:= DSXPlugins.GetDSXModule(I);
|
|
if Length(AModule.Descr) = 0 then
|
|
cmbPlugin.Items.Add(AModule.Name)
|
|
else
|
|
cmbPlugin.Items.Add(AModule.Name + ' (' + AModule.Descr + ')');
|
|
end;
|
|
cbUsePlugin.Enabled := (cmbPlugin.Items.Count > 0);
|
|
if (cbUsePlugin.Enabled) then cmbPlugin.ItemIndex := 0;
|
|
end;
|
|
|
|
{ TfrmFindDlg.FormShow }
|
|
procedure TfrmFindDlg.frmFindDlgShow(Sender: TObject);
|
|
begin
|
|
{$IFDEF LCLCOCOA}
|
|
pgcSearch.DoAdjustClientRectChange();
|
|
{$ENDIF}
|
|
|
|
pgcSearch.PageIndex := 0;
|
|
|
|
if cmbFindFileMask.Visible then
|
|
cmbFindFileMask.SelectAll;
|
|
|
|
lsFoundedFiles.Canvas.Font := lsFoundedFiles.Font;
|
|
|
|
if pgcSearch.ActivePage = tsStandard then
|
|
if cmbFindFileMask.CanSetFocus then
|
|
cmbFindFileMask.SetFocus;
|
|
|
|
cbSelectedFiles.Checked := FSelectedFiles.Count > 0;
|
|
cbSelectedFiles.Enabled := cbSelectedFiles.Checked;
|
|
end;
|
|
|
|
{ TfrmFindDlg.gbDirectoriesResize }
|
|
procedure TfrmFindDlg.gbDirectoriesResize(Sender: TObject);
|
|
begin
|
|
pnlDirectoriesDepth.Width := gbDirectories.Width div 3;
|
|
end;
|
|
|
|
{ TfrmFindDlg.lbSearchTemplatesSelectionChange }
|
|
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 begin
|
|
lblSearchContents.Caption := '"' + FilesMasks + '"';
|
|
end;
|
|
pnlLoadSaveBottom.Enabled:= cbFindInArchive.Enabled or
|
|
((Duplicates = False) and (ContentPlugin = False) and
|
|
(SearchPlugin = EmptyStr) and (IsReplaceText = False));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.LoadSelectedTemplate }
|
|
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;
|
|
|
|
{ TfrmFindDlg.LoadTemplate }
|
|
procedure TfrmFindDlg.LoadTemplate(const Template: TSearchTemplateRec);
|
|
begin
|
|
with Template do
|
|
begin
|
|
if cbFindInArchive.Enabled then
|
|
begin
|
|
if StartPath <> '' then
|
|
cmbFindPathStart.Text := StartPath;
|
|
cbFollowSymLinks.Checked := FollowSymLinks;
|
|
cbFindInArchive.Checked := FindInArchives;
|
|
if (SearchDepth + 1 >= 0) and (SearchDepth + 1 < cmbSearchDepth.Items.Count) then
|
|
cmbSearchDepth.ItemIndex := SearchDepth + 1
|
|
else
|
|
cmbSearchDepth.ItemIndex := 0;
|
|
end;
|
|
cmbExcludeDirectories.Text := ExcludeDirectories;
|
|
cmbFindFileMask.Text := FilesMasks;
|
|
cmbExcludeFiles.Text := ExcludeFiles;
|
|
|
|
cbRegExp.Checked := RegExp;
|
|
cbPartialNameSearch.Checked := IsPartialNameSearch;
|
|
|
|
// 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;
|
|
if cbFindInArchive.Enabled then
|
|
begin
|
|
cbReplaceText.Checked := IsReplaceText;
|
|
cmbReplaceText.Text := ReplaceText;
|
|
end;
|
|
chkHex.Checked := HexValue;
|
|
cbCaseSens.Checked := CaseSensitive;
|
|
cbNotContainingText.Checked := NotContainingText;
|
|
cbTextRegExp.Checked := TextRegExp;
|
|
cmbEncoding.Text := TextEncoding;
|
|
cbOfficeXML.Checked := OfficeXML;
|
|
|
|
if cbFindInArchive.Enabled then
|
|
begin
|
|
// duplicates
|
|
chkDuplicates.Checked := Duplicates;
|
|
chkDuplicateName.Checked := DuplicateName;
|
|
chkDuplicateSize.Checked := DuplicateSize;
|
|
chkDuplicateHash.Checked := DuplicateHash;
|
|
chkDuplicateContent.Checked := DuplicateContent;
|
|
// plugins
|
|
if cbUsePlugin.Enabled then
|
|
begin
|
|
cmbPlugin.Tag := cmbPlugin.Items.IndexOf(SearchPlugin);
|
|
cbUsePlugin.Checked:= (cmbPlugin.Tag >= 0);
|
|
if cbUsePlugin.Checked then
|
|
cmbPlugin.ItemIndex := cmbPlugin.Tag;
|
|
end;
|
|
frmContentPlugins.Load(Template);
|
|
end;
|
|
|
|
//Let's switch to the most pertinent tab after having load the template.
|
|
//If we would just load and no switching, user has not a real feedback visually he loaded something.
|
|
//1. If we're using at least plug in, switch to it.
|
|
//2. If not but we're using at least something from the "Advanced" tab, switch to it.
|
|
//3. If nothing above, at least switch to "Standard" tab.
|
|
pgcSearch.Options:= pgcSearch.Options + [nboDoChangeOnSetIndex];
|
|
if (cbUsePlugin.Checked OR frmContentPlugins.chkUsePlugins.Checked) then
|
|
pgcSearch.ActivePage := tsPlugins
|
|
else
|
|
if (cbNotOlderThan.Checked OR cbFileSizeFrom.Checked OR cbFileSizeTo.Checked OR cbDateFrom.Checked OR cbDateTo.Checked OR cbTimeFrom.Checked OR cbTimeTo.Checked OR (edtAttrib.Text<>'')) then
|
|
pgcSearch.ActivePage := tsAdvanced
|
|
else begin
|
|
pgcSearch.ActivePage := tsStandard;
|
|
end;
|
|
pgcSearch.Options:= pgcSearch.Options - [nboDoChangeOnSetIndex];
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.lsFoundedFilesDblClick }
|
|
procedure TfrmFindDlg.lsFoundedFilesDblClick(Sender: TObject);
|
|
begin
|
|
cm_GoToFile([]);
|
|
end;
|
|
|
|
{ TfrmFindDlg.lsFoundedFilesKeyDown }
|
|
procedure TfrmFindDlg.lsFoundedFilesKeyDown(Sender: TObject;
|
|
var Key: word; Shift: TShiftState);
|
|
begin
|
|
if (Shift = []) and (lsFoundedFiles.ItemIndex <> -1) then
|
|
begin
|
|
case Key of
|
|
VK_DELETE:
|
|
begin
|
|
miRemoveFromLlistClick(Sender);
|
|
Key := 0;
|
|
end;
|
|
|
|
VK_RETURN:
|
|
begin
|
|
if not FSearchingActive then
|
|
begin
|
|
cm_GotoFile([]);
|
|
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;
|
|
Key := 0;
|
|
end
|
|
else
|
|
begin
|
|
Key := 0;
|
|
btnStop.SetFocus;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.lsFoundedFilesMouseDown }
|
|
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;
|
|
|
|
{ TfrmFindDlg.lsFoundedFilesMouseUp }
|
|
procedure TfrmFindDlg.lsFoundedFilesMouseUp(Sender: TObject;
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|
var
|
|
i: integer;
|
|
sPath: string;
|
|
AFile: TFile;
|
|
AFiles: TFiles;
|
|
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;
|
|
|
|
{ TfrmFindDlg.lsFoundedFilesMouseWheelDown }
|
|
procedure TfrmFindDlg.lsFoundedFilesMouseWheelDown(Sender: TObject;
|
|
Shift: TShiftState; MousePos: TPoint; var Handled: boolean);
|
|
begin
|
|
if (Shift = [ssCtrl]) and (gFonts[dcfSearchResults].Size > gFonts[dcfSearchResults].MinValue) then
|
|
begin
|
|
dec(gFonts[dcfSearchResults].Size);
|
|
lsFoundedFiles.Font.Size := gFonts[dcfSearchResults].Size;
|
|
Handled := True;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.lsFoundedFilesMouseWheelUp }
|
|
procedure TfrmFindDlg.lsFoundedFilesMouseWheelUp(Sender: TObject;
|
|
Shift: TShiftState; MousePos: TPoint; var Handled: boolean);
|
|
begin
|
|
if (Shift = [ssCtrl]) and (gFonts[dcfSearchResults].Size < gFonts[dcfSearchResults].MaxValue) then
|
|
begin
|
|
inc(gFonts[dcfSearchResults].Size);
|
|
lsFoundedFiles.Font.Size := gFonts[dcfSearchResults].Size;
|
|
Handled := True;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.miOpenInNewTabClick }
|
|
procedure TfrmFindDlg.miOpenInNewTabClick(Sender: TObject);
|
|
var
|
|
i: integer;
|
|
sPath: string;
|
|
|
|
Notebook: TFileViewNotebook;
|
|
NewPage: TFileViewPage;
|
|
|
|
begin
|
|
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;
|
|
|
|
{ TfrmFindDlg.miRemoveFromLlistClick }
|
|
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;
|
|
|
|
{ TfrmFindDlg.miShowAllFoundClick }
|
|
procedure TfrmFindDlg.miShowAllFoundClick(Sender: TObject);
|
|
begin
|
|
lsFoundedFiles.Clear;
|
|
lsFoundedFiles.Items.AddStrings(FoundedStringCopy);
|
|
|
|
miShowAllFound.Enabled := False;
|
|
end;
|
|
|
|
{ TfrmFindDlg.miShowInEditorClick }
|
|
procedure TfrmFindDlg.miShowInEditorClick(Sender: TObject);
|
|
begin
|
|
if lsFoundedFiles.ItemIndex >= 0 then
|
|
ShowEditorByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
|
|
end;
|
|
|
|
{ TfrmFindDlg.miShowInViewerClick }
|
|
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;
|
|
|
|
{ TfrmFindDlg.seFileSizeFromChange }
|
|
procedure TfrmFindDlg.seFileSizeFromChange(Sender: TObject);
|
|
begin
|
|
if not FUpdating then
|
|
cbFileSizeFrom.Checked := (seFileSizeFrom.Value > 0);
|
|
end;
|
|
|
|
{ TfrmFindDlg.seFileSizeToChange }
|
|
procedure TfrmFindDlg.seFileSizeToChange(Sender: TObject);
|
|
begin
|
|
if not FUpdating then
|
|
cbFileSizeTo.Checked := (seFileSizeTo.Value > 0);
|
|
end;
|
|
|
|
{ TfrmFindDlg.SelectTemplate }
|
|
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;
|
|
|
|
{ TfrmFindDlg.seNotOlderThanChange }
|
|
procedure TfrmFindDlg.seNotOlderThanChange(Sender: TObject);
|
|
begin
|
|
if not FUpdating then
|
|
cbNotOlderThan.Checked := (seNotOlderThan.Value > 0);
|
|
end;
|
|
|
|
{ TfrmFindDlg.tsLoadSaveShow }
|
|
procedure TfrmFindDlg.tsLoadSaveShow(Sender: TObject);
|
|
begin
|
|
UpdateTemplatesList;
|
|
if (lbSearchTemplates.Count > 0) and (lbSearchTemplates.ItemIndex = -1) then
|
|
lbSearchTemplates.ItemIndex := 0;
|
|
end;
|
|
|
|
{ TfrmFindDlg.tsStandardEnter }
|
|
procedure TfrmFindDlg.tsStandardEnter(Sender: TObject);
|
|
begin
|
|
btnStart.Default := True;
|
|
end;
|
|
|
|
{ TfrmFindDlg.UpdateTemplatesList }
|
|
procedure TfrmFindDlg.UpdateTemplatesList;
|
|
var
|
|
OldIndex: integer;
|
|
begin
|
|
OldIndex := lbSearchTemplates.ItemIndex;
|
|
gSearchTemplateList.LoadToStringList(lbSearchTemplates.Items);
|
|
if OldIndex <> -1 then
|
|
lbSearchTemplates.ItemIndex := OldIndex;
|
|
end;
|
|
|
|
{ TfrmFindDlg.OnUpdateTimer }
|
|
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;
|
|
|
|
{ TfrmFindDlg.ZVDateFromChange }
|
|
procedure TfrmFindDlg.ZVDateFromChange(Sender: TObject);
|
|
begin
|
|
if not FUpdating then
|
|
cbDateFrom.Checked := True;
|
|
end;
|
|
|
|
{ TfrmFindDlg.ZVDateToChange }
|
|
procedure TfrmFindDlg.ZVDateToChange(Sender: TObject);
|
|
begin
|
|
if not FUpdating then
|
|
cbDateTo.Checked := True;
|
|
end;
|
|
|
|
{ TfrmFindDlg.ZVTimeFromChange }
|
|
procedure TfrmFindDlg.ZVTimeFromChange(Sender: TObject);
|
|
begin
|
|
if not FUpdating then
|
|
cbTimeFrom.Checked := True;
|
|
end;
|
|
|
|
{ TfrmFindDlg.ZVTimeToChange }
|
|
procedure TfrmFindDlg.ZVTimeToChange(Sender: TObject);
|
|
begin
|
|
if not FUpdating then
|
|
cbTimeTo.Checked := True;
|
|
end;
|
|
|
|
procedure TfrmFindDlg.PopupMenuFindPopup(Sender: TObject);
|
|
begin
|
|
if (lsFoundedFiles.ItemIndex <> -1) then
|
|
begin
|
|
miShowInViewer.Enabled:= (ObjectType(lsFoundedFiles.ItemIndex) <> cbChecked);
|
|
miShowInEditor.Enabled:= (ObjectType(lsFoundedFiles.ItemIndex) <> cbChecked);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.OnAddAttribute }
|
|
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;
|
|
|
|
{ TfrmFindDlg.InvalidRegExpr }
|
|
function TfrmFindDlg.InvalidRegExpr: Boolean;
|
|
var
|
|
sMsg, sEncoding: String;
|
|
begin
|
|
Result:= False;
|
|
try
|
|
if cbRegExp.Checked then
|
|
begin
|
|
uRegExprW.ExecRegExpr(CeUtf8ToUtf16(cmbFindFileMask.Text), '');
|
|
end;
|
|
if cbTextRegExp.Checked then
|
|
begin
|
|
sMsg:= cmbFindText.Text;
|
|
sEncoding:= NormalizeEncoding(cmbEncoding.Text);
|
|
if sEncoding = EncodingDefault then sEncoding:= GetDefaultTextEncoding;
|
|
// Use correct RegExp engine
|
|
if TRegExprU.Available and (sEncoding = EncodingUTF8) then
|
|
uRegExprU.ExecRegExpr(sMsg, '')
|
|
else if SingleByteEncoding(sEncoding) then
|
|
uRegExprA.ExecRegExpr(sMsg, '')
|
|
else if (sEncoding = EncodingUTF16LE) then
|
|
uRegExprW.ExecRegExpr(CeUtf8ToUtf16(sMsg), '');
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
Result:= True;
|
|
sMsg:= StringReplace(cbRegExp.Caption, '&', '', [rfReplaceAll]);
|
|
MessageDlg(sMsg + ': ' + E.Message, mtError, [mbOK], 0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.pgcSearchChange }
|
|
procedure TfrmFindDlg.pgcSearchChange(Sender: TObject);
|
|
begin
|
|
if pgcSearch.ActivePage = tsStandard then
|
|
begin
|
|
if (not cmbFindFileMask.Focused) and (cmbFindFileMask.CanSetFocus) then
|
|
cmbFindFileMask.SetFocus;
|
|
end
|
|
else
|
|
if pgcSearch.ActivePage = tsResults then
|
|
begin
|
|
if (not lsFoundedFiles.Focused) and (lsFoundedFiles.CanSetFocus) then
|
|
lsFoundedFiles.SetFocus;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.SaveTemplate }
|
|
procedure TfrmFindDlg.SaveTemplate(SaveStartingPath: boolean);
|
|
var
|
|
sName: string;
|
|
SearchTemplate: TSearchTemplate;
|
|
SearchRec: TSearchTemplateRec;
|
|
begin
|
|
if InvalidRegExpr 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;
|
|
|
|
function TfrmFindDlg.GetTextSearchOptions: UIntPtr;
|
|
var
|
|
Options: TTextSearchOptions absolute Result;
|
|
begin
|
|
Result:= 0;
|
|
if cbCaseSens.Checked then
|
|
Include(Options, tsoMatchCase);
|
|
if cbTextRegExp.Checked then
|
|
Include(Options, tsoRegExpr);
|
|
if chkHex.Checked then
|
|
Include(Options, tsoHex);
|
|
end;
|
|
|
|
procedure TfrmFindDlg.CancelCloseAndFreeMem;
|
|
begin
|
|
cm_FreeFromMem([]);
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_Close }
|
|
procedure TfrmFindDlg.cm_Close(const Params: array of string);
|
|
begin
|
|
Hide;
|
|
Close;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_NewSearchClearFilters }
|
|
procedure TfrmFindDlg.cm_NewSearchClearFilters(const Params: array of string);
|
|
begin
|
|
cm_NewSearch(['filters=clear']);
|
|
end;
|
|
|
|
|
|
{ TfrmFindDlg.cm_FreeFromMem }
|
|
// We will set the flag "FFreeOnClose" to "true" (it was to "false" since "FormCreate".
|
|
// This flag will be checked in "FormClose" to set "CloseAction" to "caFree" so form will be destroy.
|
|
// But we need to remove the pointer to that form from our "ListOffrmFindDlgInstance".
|
|
// To determine which one to remove, we set the tag to a magic number, then scan our list and delete the one pointing the form with that magic number.
|
|
// We just delete the pointer. The actual form will be destroyed properly because of the "CloseAction" set to "caFree".
|
|
procedure TfrmFindDlg.cm_FreeFromMem(const {%H-}Params: array of string);
|
|
var
|
|
iSearchingForm: integer;
|
|
const
|
|
CLOSETAG: longint = $233528DE;
|
|
begin
|
|
if FSearchingActive then StopSearch;
|
|
|
|
// Remove our pointer from our list of forms
|
|
tag := CLOSETAG;
|
|
for iSearchingForm := pred(ListOffrmFindDlgInstance.Count) downto 1 do
|
|
begin
|
|
if ListOffrmFindDlgInstance.frmFindDlgInstance[iSearchingForm].Tag = CLOSETAG then
|
|
ListOffrmFindDlgInstance.Delete(iSearchingForm);
|
|
end;
|
|
|
|
FFreeOnClose := True; // Prepare the "free mem"
|
|
|
|
// Do the "close"
|
|
Close;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_FreeFromMemAllOthers }
|
|
// We set the tag of our actual current form to a magic number and then scan
|
|
// all forms in our list to close all the ones that does not have that magic
|
|
// tag number.
|
|
procedure TfrmFindDlg.cm_FreeFromMemAllOthers(const {%H-}Params: array of string);
|
|
const
|
|
KEEPOPENTAG: longint = $270299;
|
|
var
|
|
iIndex: integer;
|
|
begin
|
|
if ListOffrmFindDlgInstance.Count > 1 then
|
|
begin
|
|
tag := KEEPOPENTAG;
|
|
try
|
|
for iIndex := pred(ListOffrmFindDlgInstance.Count) downto 0 do
|
|
if ListOffrmFindDlgInstance.frmFindDlgInstance[iIndex].Tag <> KEEPOPENTAG then
|
|
ListOffrmFindDlgInstance.frmFindDlgInstance[iIndex].CancelCloseAndFreeMem;
|
|
finally
|
|
tag := 0; // Don't forget to set back tag to 0!!!
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
msgOK(rsNoOtherFindFilesWindowToClose);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmFindDlg.cm_ConfigFileSearchHotKeys }
|
|
procedure TfrmFindDlg.cm_ConfigFileSearchHotKeys(const {%H-}Params: array of string);
|
|
begin
|
|
frmMain.Commands.cm_ConfigHotKeys([Format('category=%s', [rsHotkeyCategoryFindFiles])]);
|
|
end;
|
|
|
|
initialization
|
|
TFormCommands.RegisterCommandsForm(TfrmFindDlg, HotkeysCategory, @rsHotkeyCategoryFindFiles);
|
|
ListOffrmFindDlgInstance := TListOffrmFindDlgInstance.Create;
|
|
|
|
finalization
|
|
ListOffrmFindDlgInstance.Destroy; // "Destroy" does call the "Clear" who will free the forms.
|
|
end.
|