UPD: Changes to find files:

- Use different structure for Find Files and Search Template than for DSX. Change DSX structure to use stack memory.
- Now all find files settings are saved to templates.
- Changed how attributes work, now it is more like chmod. Allows for some more refined search (AND's and OR's).
- Fixed resources leaks when find thread was created but not executed.
- Reformatted text in some units.
This commit is contained in:
cobines 2010-03-16 14:09:16 +00:00
commit 930a6a0416
9 changed files with 1391 additions and 1321 deletions

View file

@ -2,60 +2,62 @@ unit DsxPlugin;
interface
uses Sysutils;
uses
SysUtils;
type
TSearchAttrRecord=record
rFileMask : Pchar;
rAttributes: Cardinal;
rAttribStr : Pchar;
rCaseSens:Boolean;
{Date search}
rIsDateFrom,
rIsDateTo : Boolean;
rDateTimeFrom,
rDateTimeTo : TDateTime;
{Time search}
rIsTimeFrom,
rIsTimeTo : Boolean;
(* File size search *)
rIsFileSizeFrom,
rIsFileSizeTo : Boolean;
rFileSizeFrom,
rFileSizeTo : Int64;
(* Find text *)
rIsNoThisText,
rFindInFiles:Boolean;
rFindData:Pchar;
(* Replace text *)
rReplaceInFiles : Boolean;
rReplaceData : Pchar;
end;
TDsxSearchRecord = record
FileMask: array[0..1024] of AnsiChar;
Attributes: Cardinal;
AttribStr: array[0..32] of AnsiChar;
CaseSensitive: Boolean;
{ Date/time search }
IsDateFrom,
IsDateTo,
IsTimeFrom,
IsTimeTo: Boolean;
DateTimeFrom,
DateTimeTo: TDateTime;
{ File size search }
IsFileSizeFrom,
IsFileSizeTo: Boolean;
FileSizeFrom,
FileSizeTo: Int64;
{ Find/replace text }
IsFindText: Boolean;
FindText: array[0..1024] of AnsiChar;
IsReplaceText: Boolean;
ReplaceText: array[0..1024] of AnsiChar;
NotContainingText: Boolean;
end;
tDSXDefaultParamStruct=record
tDSXDefaultParamStruct = record
size,
PluginInterfaceVersionLow,
PluginInterfaceVersionHi:longint;
DefaultIniName:array[0..MAX_PATH-1] of char;
PluginInterfaceVersionHi: Longint;
DefaultIniName: array[0..MAX_PATH - 1] of Char;
end;
pDSXDefaultParamStruct=^tDSXDefaultParamStruct;
pDSXDefaultParamStruct = ^tDSXDefaultParamStruct;
{Prototypes}
{Callbacks procs}
TSAddFileProc=procedure (PlugNr:integer; FoundFile:pchar); stdcall; //if FoundFile='' then searching is finished
{Prototypes}
{Callbacks procs}
TSAddFileProc = procedure(PlugNr: Integer; FoundFile: PChar); Stdcall;
//if FoundFile='' then searching is finished
TSUpdateStatusProc=procedure (PlugNr:integer; CurrentFile:pchar; FilesScaned:integer); stdcall;
TSUpdateStatusProc = procedure(PlugNr: Integer; CurrentFile: PChar;
FilesScaned: Integer); Stdcall;
{Mandatory (must be implemented)}
{
function Init(dps:pDSXDefaultParamStruct; pAddFileProc:TSAddFileProc; pUpdateStatus:TSUpdateStatusProc):integer; stdcall;
procedure StartSearch(FPluginNr:integer; StartPath:pchar; SearchAttrRec:TSearchAttrRecord); stdcall;
procedure StopSearch(FPluginNr:integer); stdcall;
procedure Finalize(FPluginNr:integer); stdcall;
}
{Mandatory (must be implemented)}
{
function Init(dps:pDSXDefaultParamStruct; pAddFileProc:TSAddFileProc; pUpdateStatus:TSUpdateStatusProc):integer; stdcall;
procedure StartSearch(FPluginNr:integer; StartPath:pchar; SearchAttrRec:TSearchAttrRecord); stdcall;
procedure StopSearch(FPluginNr:integer); stdcall;
procedure Finalize(FPluginNr:integer); stdcall;
}
implementation
end.

View file

@ -1,9 +1,8 @@
object frmFindDlg: TfrmFindDlg
Left = 162
Left = 182
Height = 422
Top = 17
Top = 146
Width = 768
ActiveControl = cmbFindFileMask
Caption = 'Find files'
ClientHeight = 422
ClientWidth = 768
@ -37,21 +36,21 @@ object frmFindDlg: TfrmFindDlg
Width = 667
ActivePage = tsStandard
Anchors = [akTop, akLeft, akRight, akBottom]
TabIndex = 0
TabIndex = 1
TabOrder = 0
object tsStandard: TTabSheet
Caption = 'Standard'
ChildSizing.LeftRightSpacing = 6
ChildSizing.TopBottomSpacing = 6
ClientHeight = 395
ClientWidth = 665
ClientHeight = 392
ClientWidth = 659
object lblFindPathStart: TLabel
AnchorSideTop.Control = cmbFindFileMask
AnchorSideTop.Side = asrBottom
Left = 8
Height = 18
Top = 59
Width = 71
Top = 57
Width = 49
BorderSpacing.Top = 6
Caption = '&Directory'
FocusControl = edtFindPathStart
@ -61,7 +60,7 @@ object frmFindDlg: TfrmFindDlg
Left = 8
Height = 18
Top = 4
Width = 74
Width = 55
Caption = '&File mask'
FocusControl = cmbFindFileMask
ParentColor = False
@ -72,8 +71,8 @@ object frmFindDlg: TfrmFindDlg
AnchorSideTop.Side = asrCenter
Left = 8
Height = 18
Top = 115
Width = 155
Top = 111
Width = 123
BorderSpacing.Left = 8
Caption = 'Search su&bdirectories:'
FocusControl = cbSearchDepth
@ -85,40 +84,42 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Control = tsStandard
AnchorSideRight.Side = asrBottom
Left = 8
Height = 27
Height = 25
Top = 26
Width = 651
Width = 645
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 4
ItemHeight = 0
ItemHeight = 17
TabOrder = 0
Text = '*'
end
object gbFindData: TGroupBox
AnchorSideTop.Control = cbFindInFile
AnchorSideTop.Control = cbFindText
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = tsStandard
AnchorSideRight.Side = asrBottom
Left = 8
Height = 148
Top = 168
Width = 651
Height = 132
Top = 162
Width = 645
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BorderSpacing.Top = 4
Caption = 'Find Data'
ClientHeight = 129
ClientWidth = 647
ChildSizing.TopBottomSpacing = 2
ClientHeight = 114
ClientWidth = 641
Enabled = False
TabOrder = 5
object lblEncoding: TLabel
AnchorSideLeft.Control = cbNoThisText
AnchorSideLeft.Control = cbNotContainingText
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = cbEncoding
AnchorSideTop.Control = cmbEncoding
AnchorSideTop.Side = asrCenter
Left = 388
Left = 339
Height = 18
Top = 96
Width = 64
Top = 90
Width = 54
BorderSpacing.Left = 12
BorderSpacing.Top = 6
Caption = 'Encoding:'
@ -126,28 +127,28 @@ object frmFindDlg: TfrmFindDlg
end
object cbCaseSens: TCheckBox
AnchorSideLeft.Control = gbFindData
AnchorSideTop.Control = cbEncoding
AnchorSideTop.Control = cmbEncoding
AnchorSideTop.Side = asrCenter
Left = 6
Height = 21
Top = 95
Width = 118
Top = 89
Width = 104
BorderSpacing.Left = 6
Caption = 'Case sens&itive'
TabOrder = 1
TabOrder = 3
end
object cbNoThisText: TCheckBox
object cbNotContainingText: TCheckBox
AnchorSideLeft.Control = cbCaseSens
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = cbEncoding
AnchorSideTop.Control = cmbEncoding
AnchorSideTop.Side = asrCenter
Left = 136
Left = 122
Height = 21
Top = 95
Width = 240
Top = 89
Width = 205
BorderSpacing.Left = 12
Caption = 'Find files N&OT containing the text'
TabOrder = 2
TabOrder = 4
end
object cbReplaceText: TCheckBox
AnchorSideLeft.Control = gbFindData
@ -155,29 +156,29 @@ object frmFindDlg: TfrmFindDlg
AnchorSideTop.Side = asrBottom
Left = 6
Height = 21
Top = 37
Width = 104
Top = 35
Width = 93
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Caption = 'Re&place text'
OnChange = cbReplaceTextChange
TabOrder = 0
TabOrder = 1
end
object cbEncoding: TComboBox
object cmbEncoding: TComboBox
AnchorSideLeft.Control = lblEncoding
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = cmbReplaceText
AnchorSideTop.Side = asrBottom
Left = 458
Height = 29
Top = 91
Left = 399
Height = 25
Top = 87
Width = 100
BorderSpacing.Left = 6
BorderSpacing.Top = 4
ItemHeight = 0
OnSelect = cbEncodingSelect
ItemHeight = 17
OnSelect = cmbEncodingSelect
Style = csDropDownList
TabOrder = 3
TabOrder = 5
end
object cmbFindText: TComboBox
AnchorSideLeft.Control = gbFindData
@ -185,15 +186,15 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Control = gbFindData
AnchorSideRight.Side = asrBottom
Left = 6
Height = 27
Height = 25
Top = 4
Width = 635
Width = 629
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Top = 4
BorderSpacing.Right = 6
ItemHeight = 0
TabOrder = 4
ItemHeight = 17
TabOrder = 0
end
object cmbReplaceText: TComboBox
AnchorSideLeft.Control = gbFindData
@ -202,27 +203,27 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Control = gbFindData
AnchorSideRight.Side = asrBottom
Left = 6
Height = 27
Top = 60
Width = 635
Height = 25
Top = 58
Width = 629
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Top = 2
BorderSpacing.Right = 6
ItemHeight = 0
TabOrder = 5
ItemHeight = 17
TabOrder = 2
end
end
object cbFindInFile: TCheckBox
object cbFindText: TCheckBox
AnchorSideTop.Control = cbSearchDepth
AnchorSideTop.Side = asrBottom
Left = 12
Height = 21
Top = 143
Width = 120
Top = 137
Width = 105
BorderSpacing.Top = 4
Caption = 'Find &text in file'
OnChange = cbFindInFileChange
OnChange = cbFindTextChange
TabOrder = 4
end
object edtFindPathStart: TDirectoryEdit
@ -231,8 +232,8 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
Left = 8
Height = 25
Top = 81
Width = 626
Top = 79
Width = 620
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
@ -243,34 +244,34 @@ object frmFindDlg: TfrmFindDlg
end
object cbUsePlugin: TCheckBox
AnchorSideLeft.Control = tsStandard
AnchorSideTop.Control = cbbSPlugins
AnchorSideTop.Control = cmbPlugin
AnchorSideTop.Side = asrCenter
Left = 8
Height = 21
Top = 325
Width = 143
Top = 302
Width = 124
BorderSpacing.Left = 8
Caption = '&Use search plugin:'
OnChange = cbUsePluginChange
TabOrder = 6
end
object cbbSPlugins: TComboBox
object cmbPlugin: TComboBox
AnchorSideLeft.Control = cbUsePlugin
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = gbFindData
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = tsStandard
AnchorSideRight.Side = asrBottom
Left = 157
Height = 27
Top = 322
Width = 502
Left = 138
Height = 25
Top = 300
Width = 515
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Right = 6
Enabled = False
ItemHeight = 0
ItemHeight = 17
MaxLength = 65535
TabOrder = 7
end
@ -279,13 +280,13 @@ object frmFindDlg: TfrmFindDlg
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = edtFindPathStart
AnchorSideTop.Side = asrBottom
Left = 167
Height = 29
Top = 110
Left = 135
Height = 25
Top = 108
Width = 184
BorderSpacing.Left = 4
BorderSpacing.Top = 4
ItemHeight = 0
ItemHeight = 17
Style = csDropDownList
TabOrder = 2
end
@ -294,10 +295,10 @@ object frmFindDlg: TfrmFindDlg
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = cbSearchDepth
AnchorSideTop.Side = asrCenter
Left = 363
Left = 331
Height = 21
Top = 114
Width = 154
Top = 110
Width = 135
BorderSpacing.Left = 12
Caption = '&Regular expressions'
TabOrder = 3
@ -310,8 +311,8 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
Left = 6
Height = 4
Top = 364
Width = 653
Top = 341
Width = 647
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Top = 18
@ -322,8 +323,8 @@ object frmFindDlg: TfrmFindDlg
end
object tsAdvanced: TTabSheet
Caption = 'Advanced'
ClientHeight = 395
ClientWidth = 665
ClientHeight = 392
ClientWidth = 659
ImageIndex = 1
object cbDateFrom: TCheckBox
AnchorSideLeft.Control = tsAdvanced
@ -331,7 +332,7 @@ object frmFindDlg: TfrmFindDlg
Left = 6
Height = 21
Top = 18
Width = 95
Width = 85
BorderSpacing.Left = 6
BorderSpacing.Top = 18
Caption = 'Date From:'
@ -345,40 +346,42 @@ object frmFindDlg: TfrmFindDlg
Left = 6
Height = 21
Top = 142
Width = 120
Width = 106
BorderSpacing.Left = 6
BorderSpacing.Top = 12
Caption = 'Not older than:'
OnChange = cbNotOlderThanChange
TabOrder = 6
TabOrder = 8
end
object seNotOlderThan: TSpinEdit
AnchorSideLeft.Control = tsAdvanced
AnchorSideTop.Control = cbNotOlderThan
AnchorSideTop.Side = asrBottom
AnchorSideBottom.Control = cbDelayUnit
AnchorSideBottom.Control = cmbNotOlderThanUnit
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 29
Height = 25
Top = 169
Width = 106
Anchors = [akTop, akLeft, akBottom]
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Enabled = False
TabOrder = 7
MaxValue = 999999999
TabOrder = 9
end
object cbDelayUnit: TComboBox
object cmbNotOlderThanUnit: TComboBox
AnchorSideTop.Control = cbNotOlderThan
AnchorSideTop.Side = asrBottom
Left = 164
Height = 29
Height = 25
Top = 169
Width = 110
BorderSpacing.Top = 6
Enabled = False
ItemHeight = 0
ItemHeight = 17
Items.Strings = (
'Second(s)'
'Minute(s)'
'Hour(s)'
'Day(s)'
@ -387,95 +390,96 @@ object frmFindDlg: TfrmFindDlg
'Year(s)'
)
Style = csDropDownList
TabOrder = 8
TabOrder = 10
end
object cbFileSizeFrom: TCheckBox
AnchorSideLeft.Control = tsAdvanced
AnchorSideTop.Control = gbAttributes
AnchorSideTop.Control = seNotOlderThan
AnchorSideTop.Side = asrBottom
Left = 6
Height = 21
Top = 220
Width = 118
Top = 206
Width = 105
BorderSpacing.Left = 6
BorderSpacing.Top = 12
Caption = 'File Size From:'
OnChange = cbFileSizeFromChange
TabOrder = 9
TabOrder = 11
end
object cbDateTo: TCheckBox
AnchorSideTop.Control = tsAdvanced
Left = 164
Height = 21
Top = 18
Width = 76
Width = 69
BorderSpacing.Top = 18
Caption = 'Date To:'
OnChange = cbDateToChange
TabOrder = 1
TabOrder = 2
end
object cbFileSizeTo: TCheckBox
AnchorSideTop.Control = gbAttributes
AnchorSideTop.Control = seNotOlderThan
AnchorSideTop.Side = asrBottom
Left = 164
Height = 21
Top = 220
Width = 99
Top = 206
Width = 89
BorderSpacing.Top = 12
Caption = 'File Size To:'
OnChange = cbFileSizeToChange
TabOrder = 11
TabOrder = 13
end
object seFileSizeFrom: TSpinEdit
AnchorSideLeft.Control = tsAdvanced
AnchorSideTop.Control = cbFileSizeFrom
AnchorSideTop.Side = asrBottom
AnchorSideBottom.Control = cbUnitOfMeasure
AnchorSideBottom.Control = cmbFileSizeUnit
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 30
Top = 247
Height = 26
Top = 233
Width = 106
Anchors = [akTop, akLeft, akBottom]
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Enabled = False
MaxValue = 1023
TabOrder = 10
MaxValue = 999999999
TabOrder = 12
end
object seFileSizeTo: TSpinEdit
AnchorSideTop.Control = cbFileSizeTo
AnchorSideTop.Side = asrBottom
AnchorSideBottom.Control = cbUnitOfMeasure
AnchorSideBottom.Control = cmbFileSizeUnit
AnchorSideBottom.Side = asrBottom
Left = 164
Height = 30
Top = 247
Height = 26
Top = 233
Width = 110
Anchors = [akTop, akLeft, akBottom]
BorderSpacing.Top = 6
Enabled = False
MaxValue = 1023
TabOrder = 12
MaxValue = 999999999
TabOrder = 14
end
object cbUnitOfMeasure: TComboBox
object cmbFileSizeUnit: TComboBox
AnchorSideTop.Control = seFileSizeTo
AnchorSideTop.Side = asrCenter
Left = 284
Height = 29
Top = 248
Height = 25
Top = 234
Width = 72
Enabled = False
ItemHeight = 0
ItemHeight = 17
ItemIndex = 1
Items.Strings = (
'Byte'
'Kbyte'
'Mbyte'
'Gbyte'
'Tbyte'
)
Style = csDropDownList
TabOrder = 13
TabOrder = 15
Text = 'Kbyte'
end
object cbTimeFrom: TCheckBox
@ -484,23 +488,23 @@ object frmFindDlg: TfrmFindDlg
Left = 6
Height = 21
Top = 78
Width = 95
Width = 83
BorderSpacing.Left = 6
BorderSpacing.Top = 12
Caption = 'Time from:'
OnChange = cbTimeFromChange
TabOrder = 2
TabOrder = 4
end
object cbTimeTo: TCheckBox
AnchorSideTop.Side = asrBottom
Left = 164
Height = 21
Top = 78
Width = 77
Width = 68
BorderSpacing.Top = 12
Caption = 'Time to:'
OnChange = cbTimeToChange
TabOrder = 4
TabOrder = 6
end
object edtTimeFrom: TEdit
AnchorSideLeft.Control = tsAdvanced
@ -513,7 +517,7 @@ object frmFindDlg: TfrmFindDlg
BorderSpacing.Left = 6
BorderSpacing.Top = 6
MaxLength = 8
TabOrder = 3
TabOrder = 5
end
object edtTimeTo: TEdit
AnchorSideTop.Control = cbTimeTo
@ -524,91 +528,51 @@ object frmFindDlg: TfrmFindDlg
Width = 110
BorderSpacing.Top = 6
MaxLength = 8
TabOrder = 5
TabOrder = 7
end
object gbAttributes: TGroupBox
AnchorSideTop.Control = cbAttrib
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 284
Height = 163
Top = 45
Width = 144
Height = 58
Top = 18
Width = 252
AutoSize = True
BorderSpacing.Top = 6
BorderSpacing.Right = 6
Caption = '&Attributes'
ChildSizing.LeftRightSpacing = 6
ChildSizing.TopBottomSpacing = 6
ClientHeight = 159
ClientWidth = 140
Enabled = False
TabOrder = 15
object lblInfo: TLabel
AnchorSideLeft.Control = gbAttributes
Left = 6
Height = 39
Top = 114
Width = 119
Caption = 'Windows: ''rahs'''#13#10'Unix: ''rwxrwxrwx'''
ParentColor = False
end
object cbDirectory: TCheckBox
AnchorSideLeft.Control = gbAttributes
Left = 6
Height = 21
Top = 6
Width = 83
AllowGrayed = True
Caption = 'Directory'
OnChange = cbDirectoryChange
State = cbGrayed
TabOrder = 0
end
object cbSymLink: TCheckBox
AnchorSideLeft.Control = gbAttributes
Left = 6
Height = 21
Top = 34
Width = 79
AllowGrayed = True
Caption = 'SymLink'
OnChange = cbSymLinkChange
State = cbGrayed
TabOrder = 1
end
object cbMore: TCheckBox
AnchorSideLeft.Control = gbAttributes
Left = 6
Height = 21
Top = 62
Width = 56
Caption = 'More'
OnChange = cbMoreChange
TabOrder = 2
end
ClientHeight = 40
ClientWidth = 248
TabOrder = 16
object edtAttrib: TEdit
AnchorSideLeft.Control = gbAttributes
Left = 6
Height = 25
Hint = 'Use ''-'' to off attribute and ''?'' to any'
Top = 88
Width = 128
Enabled = False
Top = 6
Width = 176
ParentShowHint = False
ShowHint = True
TabOrder = 3
TabOrder = 0
end
object btnAttrsHelp: TButton
AnchorSideLeft.Control = edtAttrib
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = edtAttrib
AnchorSideTop.Side = asrCenter
Left = 187
Height = 31
Top = 3
Width = 55
AutoSize = True
BorderSpacing.Left = 5
BorderSpacing.InnerBorder = 2
Caption = '&Help'
OnClick = btnAttrsHelpClick
TabOrder = 1
end
end
object cbAttrib: TCheckBox
AnchorSideTop.Control = tsAdvanced
Left = 284
Height = 21
Top = 18
Width = 87
BorderSpacing.Top = 18
Caption = 'Attributes'
OnChange = cbAttribChange
TabOrder = 14
end
object deDateFrom: TEditButton
AnchorSideLeft.Control = tsAdvanced
@ -662,7 +626,7 @@ object frmFindDlg: TfrmFindDlg
MaxLength = 0
NumGlyphs = 1
OnButtonClick = deDateButtonClick
TabOrder = 16
TabOrder = 1
end
object deDateTo: TEditButton
AnchorSideTop.Control = cbDateTo
@ -714,7 +678,7 @@ object frmFindDlg: TfrmFindDlg
MaxLength = 0
NumGlyphs = 1
OnButtonClick = deDateButtonClick
TabOrder = 17
TabOrder = 3
end
object Bevel2: TBevel
AnchorSideLeft.Control = tsAdvanced
@ -724,8 +688,8 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
Left = 6
Height = 4
Top = 295
Width = 361
Top = 277
Width = 647
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Top = 18
@ -736,17 +700,16 @@ object frmFindDlg: TfrmFindDlg
end
object tsLoadSave: TTabSheet
Caption = 'Load/Save'
ClientHeight = 395
ClientWidth = 665
ClientHeight = 392
ClientWidth = 659
OnShow = tsLoadSaveShow
object lblTemplateHeader: TLabel
AnchorSideLeft.Control = tsLoadSave
AnchorSideTop.Control = tsLoadSave
Left = 12
Height = 14
Height = 18
Top = 6
Width = 417
AutoSize = False
Width = 104
BorderSpacing.Left = 12
BorderSpacing.Top = 6
Caption = '&Previous searches:'
@ -761,9 +724,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = lblSearchContents
Left = 12
Height = 286
Top = 26
Width = 641
Height = 276
Top = 30
Width = 635
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 12
BorderSpacing.Top = 6
@ -772,7 +735,6 @@ object frmFindDlg: TfrmFindDlg
ItemHeight = 0
OnSelectionChange = lbSearchTemplatesSelectionChange
TabOrder = 0
TopIndex = -1
end
object lblSearchContents: TPanel
AnchorSideLeft.Control = lbSearchTemplates
@ -780,9 +742,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = btnSearchLoad
Left = 12
Height = 17
Top = 324
Width = 641
Height = 20
Top = 318
Width = 635
Alignment = taLeftJustify
Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Bottom = 12
@ -793,9 +755,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Control = btnSearchSave
AnchorSideBottom.Control = tsLoadSave
AnchorSideBottom.Side = asrBottom
Left = 140
Left = 137
Height = 30
Top = 353
Top = 350
Width = 120
Anchors = [akRight, akBottom]
BorderSpacing.Right = 12
@ -809,9 +771,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideLeft.Side = asrCenter
AnchorSideBottom.Control = tsLoadSave
AnchorSideBottom.Side = asrBottom
Left = 272
Left = 269
Height = 30
Top = 353
Top = 350
Width = 120
Anchors = [akLeft, akBottom]
BorderSpacing.Bottom = 12
@ -825,9 +787,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = tsLoadSave
AnchorSideBottom.Side = asrBottom
Left = 404
Left = 401
Height = 30
Top = 353
Top = 350
Width = 120
Anchors = [akLeft, akBottom]
BorderSpacing.Left = 12
@ -839,29 +801,29 @@ object frmFindDlg: TfrmFindDlg
end
object tsResults: TTabSheet
Caption = 'Results'
ClientHeight = 395
ClientWidth = 665
ClientHeight = 392
ClientWidth = 659
object pnlResults: TPanel
AnchorSideTop.Control = pnlFindFile
AnchorSideTop.Side = asrBottom
Left = 0
Height = 395
Height = 392
Top = 0
Width = 665
Width = 659
Align = alClient
BevelOuter = bvNone
ClientHeight = 395
ClientWidth = 665
ClientHeight = 392
ClientWidth = 659
FullRepaint = False
TabOrder = 0
object pnlStatus: TPanel
Left = 0
Height = 58
Top = 0
Width = 665
Width = 659
Align = alTop
ClientHeight = 58
ClientWidth = 665
ClientWidth = 659
FullRepaint = False
TabOrder = 0
object lblStatus: TLabel
@ -871,7 +833,7 @@ object frmFindDlg: TfrmFindDlg
Left = 10
Height = 18
Top = 30
Width = 42
Width = 36
BorderSpacing.Left = 10
BorderSpacing.Top = 6
Caption = 'Status'
@ -884,7 +846,7 @@ object frmFindDlg: TfrmFindDlg
Left = 10
Height = 18
Top = 6
Width = 49
Width = 42
BorderSpacing.Left = 10
BorderSpacing.Top = 6
Caption = 'Current'
@ -896,10 +858,10 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = lblStatus
AnchorSideBottom.Side = asrCenter
Left = 612
Left = 611
Height = 18
Top = 30
Width = 41
Width = 36
Anchors = [akRight, akBottom]
BorderSpacing.Right = 12
Caption = 'Found'
@ -910,9 +872,9 @@ object frmFindDlg: TfrmFindDlg
object lsFoundedFiles: TListBox
AnchorSideBottom.Side = asrBottom
Left = 0
Height = 279
Height = 276
Top = 58
Width = 665
Width = 659
Align = alClient
ItemHeight = 0
MultiSelect = True
@ -924,11 +886,11 @@ object frmFindDlg: TfrmFindDlg
object pnlResultsButtons: TPanel
Left = 0
Height = 58
Top = 337
Width = 665
Top = 334
Width = 659
Align = alBottom
ClientHeight = 58
ClientWidth = 665
ClientWidth = 659
TabOrder = 2
object btnView: TButton
AnchorSideLeft.Control = pnlResultsButtons
@ -962,7 +924,7 @@ object frmFindDlg: TfrmFindDlg
object btnGoToPath: TButton
AnchorSideTop.Control = pnlResultsButtons
AnchorSideRight.Control = btnWorkWithFound
Left = 367
Left = 361
Height = 32
Top = 12
Width = 140
@ -978,7 +940,7 @@ object frmFindDlg: TfrmFindDlg
AnchorSideTop.Control = pnlResultsButtons
AnchorSideRight.Control = pnlResultsButtons
AnchorSideRight.Side = asrBottom
Left = 513
Left = 507
Height = 32
Top = 12
Width = 140
@ -1006,7 +968,7 @@ object frmFindDlg: TfrmFindDlg
BorderSpacing.InnerBorder = 4
Caption = '&Close'
OnClick = btnCloseClick
TabOrder = 3
TabOrder = 2
end
object btnStop: TButton
AnchorSideTop.Control = btnClose
@ -1022,7 +984,7 @@ object frmFindDlg: TfrmFindDlg
Caption = 'Cancel'
Enabled = False
OnClick = btnStopClick
TabOrder = 1
TabOrder = 3
end
object btnStart: TButton
Left = 681
@ -1033,12 +995,12 @@ object frmFindDlg: TfrmFindDlg
BorderSpacing.InnerBorder = 4
Caption = '&Start'
OnClick = btnStartClick
TabOrder = 2
TabOrder = 1
end
end
object PopupMenuFind: TPopupMenu
left = 152
top = 408
left = 80
top = 392
object miShowInViewer: TMenuItem
Caption = 'Show In Viewer'
OnClick = miShowInViewerClick

View file

@ -1,47 +1,43 @@
TFRMFINDDLG.CAPTION=Find files
TFRMFINDDLG.TSSTANDARD.CAPTION=Standard
TFRMFINDDLG.LBLFINDPATHSTART.CAPTION=&Directory
TFRMFINDDLG.LBLFINDFILEMASK.CAPTION=&File mask
TFRMFINDDLG.LBLSEARCHDEPTH.CAPTION=Search su&bdirectories:
TFRMFINDDLG.CMBFINDFILEMASK.TEXT=*
TFRMFINDDLG.GBFINDDATA.CAPTION=Find Data
TFRMFINDDLG.LBLENCODING.CAPTION=Encoding:
TFRMFINDDLG.CBCASESENS.CAPTION=Case sens&itive
TFRMFINDDLG.CBNOTHISTEXT.CAPTION=Find files N&OT containing the text
TFRMFINDDLG.CBREPLACETEXT.CAPTION=Re&place text
TFRMFINDDLG.CBFINDINFILE.CAPTION=Find &text in file
TFRMFINDDLG.CBUSEPLUGIN.CAPTION=&Use search plugin:
TFRMFINDDLG.CBREGEXP.CAPTION=&Regular expressions
TFRMFINDDLG.TSADVANCED.CAPTION=Advanced
TFRMFINDDLG.CBDATEFROM.CAPTION=Date From:
TFRMFINDDLG.CBNOTOLDERTHAN.CAPTION=Not older than:
TFRMFINDDLG.CBFILESIZEFROM.CAPTION=File Size From:
TFRMFINDDLG.CBDATETO.CAPTION=Date To:
TFRMFINDDLG.CBFILESIZETO.CAPTION=File Size To:
TFRMFINDDLG.CBUNITOFMEASURE.TEXT=Kbyte
TFRMFINDDLG.CBTIMEFROM.CAPTION=Time from:
TFRMFINDDLG.CBTIMETO.CAPTION=Time to:
TFRMFINDDLG.LBLINFO.CAPTION=Windows: 'rahs'
Unix: 'rwxrwxrwx'
TFRMFINDDLG.CBDIRECTORY.CAPTION=Directory
TFRMFINDDLG.CBSYMLINK.CAPTION=SymLink
TFRMFINDDLG.CBMORE.CAPTION=More
TFRMFINDDLG.EDTATTRIB.HINT=Use '-' to off attribute and '?' to any
TFRMFINDDLG.CBATTRIB.CAPTION=Attributes
TFRMFINDDLG.TSLOADSAVE.CAPTION=Load/Save
TFRMFINDDLG.LBLTEMPLATEHEADER.CAPTION=&Previous searches:
TFRMFINDDLG.BTNSEARCHLOAD.CAPTION=L&oad
TFRMFINDDLG.BTNSEARCHSAVE.CAPTION=S&ave
TFRMFINDDLG.BTNSEARCHDELETE.CAPTION=&Delete
TFRMFINDDLG.TSRESULTS.CAPTION=Results
TFRMFINDDLG.LBLSTATUS.CAPTION=Status
TFRMFINDDLG.LBLCURRENT.CAPTION=Current
TFRMFINDDLG.LBLFOUND.CAPTION=Found
TFRMFINDDLG.BTNVIEW.CAPTION=&View
TFRMFINDDLG.BTNNEWSEARCH.CAPTION=&New search
TFRMFINDDLG.BTNGOTOPATH.CAPTION=&Go to file
TFRMFINDDLG.BTNWORKWITHFOUND.CAPTION=Feed to &listbox
TFRMFINDDLG.BTNCLOSE.CAPTION=&Close
TFRMFINDDLG.BTNSTOP.CAPTION=Cancel
TFRMFINDDLG.BTNSTART.CAPTION=&Start
TFRMFINDDLG.MISHOWINVIEWER.CAPTION=Show In Viewer
TFRMFINDDLG.CAPTION=Find files
TFRMFINDDLG.TSSTANDARD.CAPTION=Standard
TFRMFINDDLG.LBLFINDPATHSTART.CAPTION=&Directory
TFRMFINDDLG.LBLFINDFILEMASK.CAPTION=&File mask
TFRMFINDDLG.LBLSEARCHDEPTH.CAPTION=Search su&bdirectories:
TFRMFINDDLG.CMBFINDFILEMASK.TEXT=*
TFRMFINDDLG.GBFINDDATA.CAPTION=Find Data
TFRMFINDDLG.LBLENCODING.CAPTION=Encoding:
TFRMFINDDLG.CBCASESENS.CAPTION=Case sens&itive
TFRMFINDDLG.CBNOTCONTAININGTEXT.CAPTION=Find files N&OT containing the text
TFRMFINDDLG.CBREPLACETEXT.CAPTION=Re&place text
TFRMFINDDLG.CBFINDTEXT.CAPTION=Find &text in file
TFRMFINDDLG.CBUSEPLUGIN.CAPTION=&Use search plugin:
TFRMFINDDLG.CBREGEXP.CAPTION=&Regular expressions
TFRMFINDDLG.TSADVANCED.CAPTION=Advanced
TFRMFINDDLG.CBDATEFROM.CAPTION=Date From:
TFRMFINDDLG.CBNOTOLDERTHAN.CAPTION=Not older than:
TFRMFINDDLG.CBFILESIZEFROM.CAPTION=File Size From:
TFRMFINDDLG.CBDATETO.CAPTION=Date To:
TFRMFINDDLG.CBFILESIZETO.CAPTION=File Size To:
TFRMFINDDLG.CMBFILESIZEUNIT.TEXT=Kbyte
TFRMFINDDLG.CBTIMEFROM.CAPTION=Time from:
TFRMFINDDLG.CBTIMETO.CAPTION=Time to:
TFRMFINDDLG.GBATTRIBUTES.CAPTION=&Attributes
TFRMFINDDLG.EDTATTRIB.HINT=Use '-' to off attribute and '?' to any
TFRMFINDDLG.BTNATTRSHELP.CAPTION=&Help
TFRMFINDDLG.TSLOADSAVE.CAPTION=Load/Save
TFRMFINDDLG.LBLTEMPLATEHEADER.CAPTION=&Previous searches:
TFRMFINDDLG.BTNSEARCHLOAD.CAPTION=L&oad
TFRMFINDDLG.BTNSEARCHSAVE.CAPTION=S&ave
TFRMFINDDLG.BTNSEARCHDELETE.CAPTION=&Delete
TFRMFINDDLG.TSRESULTS.CAPTION=Results
TFRMFINDDLG.LBLSTATUS.CAPTION=Status
TFRMFINDDLG.LBLCURRENT.CAPTION=Current
TFRMFINDDLG.LBLFOUND.CAPTION=Found
TFRMFINDDLG.BTNVIEW.CAPTION=&View
TFRMFINDDLG.BTNNEWSEARCH.CAPTION=&New search
TFRMFINDDLG.BTNGOTOPATH.CAPTION=&Go to file
TFRMFINDDLG.BTNWORKWITHFOUND.CAPTION=Feed to &listbox
TFRMFINDDLG.BTNCLOSE.CAPTION=&Close
TFRMFINDDLG.BTNSTOP.CAPTION=Cancel
TFRMFINDDLG.BTNSTART.CAPTION=&Start
TFRMFINDDLG.MISHOWINVIEWER.CAPTION=Show In Viewer

View file

@ -30,9 +30,8 @@ interface
uses
LResources,
SysUtils, Classes, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, Buttons, uFindThread, Menus,
EditBtn, Spin, MaskEdit, udsxmodule, DsxPlugin;
SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, Menus, EditBtn, Spin, MaskEdit,
uDsxModule, DsxPlugin, uFindThread, uFindFiles;
type
@ -48,8 +47,9 @@ type
btnStop: TButton;
btnView: TButton;
btnWorkWithFound: TButton;
cbFindInFile: TCheckBox;
cbNoThisText: TCheckBox;
btnAttrsHelp: TButton;
cbFindText: TCheckBox;
cbNotContainingText: TCheckBox;
cbDateFrom: TCheckBox;
cbNotOlderThan: TCheckBox;
cbFileSizeFrom: TCheckBox;
@ -58,15 +58,11 @@ type
cbReplaceText: TCheckBox;
cbTimeFrom: TCheckBox;
cbTimeTo: TCheckBox;
cbDelayUnit: TComboBox;
cbUnitOfMeasure: TComboBox;
cbDirectory: TCheckBox;
cbSymLink: TCheckBox;
cbMore: TCheckBox;
cbAttrib: TCheckBox;
cmbNotOlderThanUnit: TComboBox;
cmbFileSizeUnit: TComboBox;
cbUsePlugin: TCheckBox;
cbbSPlugins: TComboBox;
cbEncoding: TComboBox;
cmbPlugin: TComboBox;
cmbEncoding: TComboBox;
cbSearchDepth: TComboBox;
cbRegExp: TCheckBox;
cmbReplaceText: TComboBox;
@ -89,7 +85,6 @@ type
lblSearchContents: TPanel;
lblSearchDepth: TLabel;
lblEncoding: TLabel;
lblInfo: TLabel;
lsFoundedFiles: TListBox;
pnlResults: TPanel;
pnlStatus: TPanel;
@ -110,11 +105,12 @@ type
tsAdvanced: TTabSheet;
PopupMenuFind: TPopupMenu;
miShowInViewer: TMenuItem;
procedure btnAttrsHelpClick(Sender: TObject);
procedure btnSearchDeleteClick(Sender: TObject);
procedure btnSearchLoadClick(Sender: TObject);
procedure btnSearchSaveClick(Sender: TObject);
procedure cbEncodingSelect(Sender: TObject);
procedure cbFindInFileChange(Sender: TObject);
procedure cmbEncodingSelect(Sender: TObject);
procedure cbFindTextChange(Sender: TObject);
procedure cbUsePluginChange(Sender: TObject);
procedure deDateButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
@ -124,13 +120,11 @@ type
procedure btnStartClick(Sender: TObject);
procedure btnViewClick(Sender: TObject);
procedure btnWorkWithFoundClick(Sender: TObject);
procedure cbAttribChange(Sender: TObject);
procedure cbDateFromChange(Sender: TObject);
procedure cbDateToChange(Sender: TObject);
procedure cbDirectoryChange(Sender: TObject);
procedure cbFileSizeFromChange(Sender: TObject);
procedure cbFileSizeToChange(Sender: TObject);
procedure cbMoreChange(Sender: TObject);
procedure cbNotOlderThanChange(Sender: TObject);
procedure cbReplaceTextChange(Sender: TObject);
procedure cbSymLinkChange(Sender: TObject);
@ -155,18 +149,16 @@ type
FFindThread:TFindThread;
DsxPlugins: TDSXModuleList;
FSearchingActive: Boolean;
procedure PrepareSearch;
procedure StopSearch;
procedure AfterSearchStopped;
procedure FillFindOptions(var FindOptions: TSearchTemplateRec);
procedure FindOptionsToDSXSearchRec(const AFindOptions: TSearchTemplateRec;
var SRec: TDsxSearchRecord);
public
{ Public declarations }
procedure ThreadTerminate(Sender:TObject);
end;
const
cKilo = 1024;
cMega = 1024*1024;
cGiga = 1024*1024*1024;
var
frmFindDlg: TfrmFindDlg =nil;
@ -175,27 +167,32 @@ procedure ShowFindDlg(const sActPath:String);
implementation
uses
LCLProc, LCLType, LConvEncoding, StrUtils, DateUtils, fCalendar, fViewer, uLng, uGlobs, uShowForm, fMain,
uTypes, uOSUtils, uSearchTemplate, uDCUtils;
LCLProc, LCLType, LConvEncoding, StrUtils, fCalendar, fViewer, fMain,
uLng, uGlobs, uShowForm, uOSUtils, uSearchTemplate, uDCUtils;
procedure SAddFileProc(PlugNr:integer; FoundFile:pchar); stdcall;
var s:string;
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);
procedure SAddFileProc(PlugNr: Integer; FoundFile: PChar); stdcall;
var
s: string;
begin
s:=string(FoundFile);
s := string(FoundFile);
if s='' then
begin
frmFindDlg.ThreadTerminate(nil);
frmFindDlg.AfterSearchStopped;
end
else
begin
frmFindDlg.lsFoundedFiles.Items.Add(s);
DebugLn('fFindLlg: '+S);
Application.ProcessMessages;
end;
end;
procedure SUpdateStatusProc(PlugNr:integer; CurrentFile:pchar; FilesScanned:integer); stdcall;
procedure SUpdateStatusProc(PlugNr: Integer; CurrentFile: PChar; FilesScanned: Integer); stdcall;
var
sCurrentFile: String;
begin
@ -248,26 +245,26 @@ begin
cbSearchDepth.Items.Add(Format(rsFindDepth, [IntToStr(I)]));
cbSearchDepth.ItemIndex:= 0;
// fill encoding combobox
cbEncoding.Clear;
GetSupportedEncodings(cbEncoding.Items);
cbEncoding.ItemIndex:= cbEncoding.Items.IndexOf(EncodingAnsi);
cmbEncoding.Clear;
GetSupportedEncodings(cmbEncoding.Items);
cmbEncoding.ItemIndex:= cmbEncoding.Items.IndexOf(EncodingAnsi);
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default := True;
{$ENDIF}
cbDelayUnit.ItemIndex:= 2;
cmbNotOlderThanUnit.ItemIndex:= 3;
edtFindPathStart.ShowHidden := gShowSystemFiles;
end;
procedure TfrmFindDlg.cbUsePluginChange(Sender: TObject);
begin
cbbSPlugins.Enabled:=cbUsePlugin.Checked;
cmbPlugin.Enabled:=cbUsePlugin.Checked;
if cbbSPlugins.Enabled and cbbSPlugins.CanFocus then
if cmbPlugin.Enabled and cmbPlugin.CanFocus then
begin
cbbSPlugins.SetFocus;
cbbSPlugins.SelectAll;
cmbPlugin.SetFocus;
cmbPlugin.SelectAll;
end;
end;
@ -278,9 +275,9 @@ begin
ebDate.Text:= ShowCalendarDialog(ebDate.Text, Mouse.CursorPos);
end;
procedure TfrmFindDlg.cbEncodingSelect(Sender: TObject);
procedure TfrmFindDlg.cmbEncodingSelect(Sender: TObject);
begin
if cbEncoding.ItemIndex <> cbEncoding.Items.IndexOf(EncodingAnsi) then
if cmbEncoding.ItemIndex <> cmbEncoding.Items.IndexOf(EncodingAnsi) then
begin
cbCaseSens.Tag:= Integer(cbCaseSens.Checked);
cbCaseSens.Checked:= True;
@ -293,9 +290,9 @@ begin
end;
end;
procedure TfrmFindDlg.cbFindInFileChange(Sender: TObject);
procedure TfrmFindDlg.cbFindTextChange(Sender: TObject);
begin
gbFindData.Enabled:=cbFindInFile.Checked;
gbFindData.Enabled:=cbFindText.Checked;
if cmbFindText.Enabled and cmbFindText.CanFocus then
begin
@ -312,96 +309,43 @@ begin
SearchTemplate:= gSearchTemplateList.Templates[lbSearchTemplates.ItemIndex];
with SearchTemplate.SearchRecord do
begin
cmbFindFileMask.Text:= rFileMask;
edtFindPathStart.Text:= SearchTemplate.StartPath;
cmbFindFileMask.Text:= FilesMasks;
edtFindPathStart.Text:= StartPath;
if (SearchDepth + 1 >= 0) and (SearchDepth + 1 < cbSearchDepth.Items.Count) then
cbSearchDepth.ItemIndex:= SearchDepth + 1
else
cbSearchDepth.ItemIndex:= 0;
cbRegExp.Checked := RegExp;
// attributes
cbAttrib.Checked:= False;
cbDirectory.State:= cbGrayed;
cbSymLink.State:= cbGrayed;
cbMore.Checked:= False;
edtAttrib.Text:= '';
if rAttributes <> faAnyFile then
begin
cbAttrib.Checked:= True;
cbDirectory.Checked:= FPS_ISDIR(rAttributes);
cbSymLink.Checked:= FPS_ISLNK(rAttributes);
end;
if (rAttribStr <> '') and (rAttribStr <> '?????????') then
begin
cbAttrib.Checked:= True;
cbMore.Checked:= True;
edtAttrib.Text:= rAttribStr;
end;
// file date
cbDateFrom.Checked:= rIsDateFrom;
deDateFrom.Text:= '';
deDateTo.Text:= '';
if rIsDateFrom then
deDateFrom.Text:= DateToStr(rDateTimeFrom);
if rIsDateTo then
deDateTo.Text:= DateToStr(rDateTimeTo);
// file time
cbTimeFrom.Checked:= rIsTimeFrom;
cbTimeTo.Checked:= rIsTimeTo;
edtTimeFrom.Text:= '';
edtTimeTo.Text:= '';
if rIsTimeFrom then
edtTimeFrom.Text:= TimeToStr(rDateTimeFrom);
if rIsTimeTo then
edtTimeTo.Text:= TimeToStr(rDateTimeTo);
edtAttrib.Text:= AttributesPattern;
// file date/time
cbDateFrom.Checked:= IsDateFrom;
cbDateTo.Checked:= IsDateTo;
deDateFrom.Text:= DateToStr(DateTimeFrom);
deDateTo.Text:= DateToStr(DateTimeTo);
cbTimeFrom.Checked:= IsTimeFrom;
cbTimeTo.Checked:= IsTimeTo;
edtTimeFrom.Text:= TimeToStr(DateTimeFrom);
edtTimeTo.Text:= TimeToStr(DateTimeTo);
// not older then
cbNotOlderThan.Checked:= SearchTemplate.IsNotOlderThan;
if SearchTemplate.IsNotOlderThan then
begin
seNotOlderThan.Value:= Trunc(SearchTemplate.NotOlderThan);
cbDelayUnit.ItemIndex:= Round(Frac(SearchTemplate.NotOlderThan)*10);
end;
cbNotOlderThan.Checked:= IsNotOlderThan;
seNotOlderThan.Value:= NotOlderThan;
cmbNotOlderThanUnit.ItemIndex := TimeUnitToComboIndex[NotOlderThanUnit];
// file size
cbFileSizeFrom.Checked:= rIsFileSizeFrom;
cbFileSizeTo.Checked:= rIsFileSizeTo;
if rIsFileSizeFrom or rIsFileSizeTo then
begin
if (rFileSizeFrom >= cGiga) or (rFileSizeTo >= cGiga) then
begin
cbUnitOfMeasure.ItemIndex:= 3;
seFileSizeFrom.Value:= rFileSizeFrom div cGiga;
seFileSizeTo.Value:= rFileSizeTo div cGiga;
end
else if (rFileSizeFrom >= cMega) or (rFileSizeTo >= cMega) then
begin
cbUnitOfMeasure.ItemIndex:= 2;
seFileSizeFrom.Value:= rFileSizeFrom div cMega;
seFileSizeTo.Value:= rFileSizeTo div cMega;
end
else if (rFileSizeFrom >= cKilo) or (rFileSizeTo >= cKilo) then
begin
cbUnitOfMeasure.ItemIndex:= 1;
seFileSizeFrom.Value:= rFileSizeFrom div cKilo;
seFileSizeTo.Value:= rFileSizeTo div cKilo;
end
else
begin
cbUnitOfMeasure.ItemIndex:= 0;
seFileSizeFrom.Value:= rFileSizeFrom;
seFileSizeTo.Value:= rFileSizeTo;
end;
end;
if not rIsFileSizeFrom then
seFileSizeFrom.Text:= '';
if not rIsFileSizeTo then
seFileSizeTo.Text:= '';
// find text
cbNoThisText.Checked:= rIsNoThisText;
cbFindInFile.Checked:= rFindInFiles;
cbCaseSens.Checked:= rCaseSens;
cmbFindText.Text:= '';
if rFindInFiles then
cmbFindText.Text:= rFindData;
// replace text
cbReplaceText.Checked:= rReplaceInFiles;
cmbReplaceText.Text:= '';
if rReplaceInFiles then
cmbReplaceText.Text:= rReplaceData;
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;
cmbEncoding.Text:= TextEncoding;
cmbPlugin.Text:= SearchPlugin;
end;
end;
@ -412,26 +356,29 @@ begin
tsLoadSaveShow(nil);
end;
procedure TfrmFindDlg.btnAttrsHelpClick(Sender: TObject);
begin
end;
procedure TfrmFindDlg.btnSearchSaveClick(Sender: TObject);
var
sName: UTF8String;
SearchTemplate: TSearchTemplate;
begin
if not InputQuery(rsFindSaveTemplateCaption, rsFindSaveTemplateTitle, sName) then Exit;
SearchTemplate := gSearchTemplateList.TemplateByName[sName];
if Assigned(SearchTemplate) then
begin
// TODO: Ask for overwriting existing template.
FillFindOptions(SearchTemplate.SearchRecord);
Exit;
end;
SearchTemplate:= TSearchTemplate.Create;
SearchTemplate.TemplateName:= sName;
SearchTemplate.StartPath:= edtFindPathStart.Text;
SearchTemplate.IsNotOlderThan:= cbNotOlderThan.Checked;
SearchTemplate.NotOlderThan:= seNotOlderThan.Value + cbDelayUnit.ItemIndex/10;
PrepareSearch;
FFindThread.FillSearchRecord(SearchTemplate.SearchRecord);
if SearchTemplate.IsNotOlderThan then
begin
SearchTemplate.SearchRecord.rIsDateFrom:= False;
SearchTemplate.SearchRecord.rIsTimeFrom:= False;
end;
FillFindOptions(SearchTemplate.SearchRecord);
gSearchTemplateList.Add(SearchTemplate);
FreeAndNil(FFindThread);
tsLoadSaveShow(nil);
end;
@ -447,7 +394,7 @@ end;
procedure TfrmFindDlg.btnNewSearchClick(Sender: TObject);
begin
btnStopClick(Sender);
StopSearch;
pgcSearch.PageIndex:= 0;
lsFoundedFiles.Clear;
lblStatus.Caption:= EmptyStr;
@ -467,172 +414,156 @@ begin
end;
end;
procedure TfrmFindDlg.PrepareSearch;
procedure TfrmFindDlg.FillFindOptions(var FindOptions: TSearchTemplateRec);
var
dtTemp, dtNow: TDateTime;
iCount: Integer;
dtTemp: TDateTime;
begin
FFindThread:=TFindThread.Create;
if Assigned(FFindThread) then
try
with FFindThread do
begin
FilterMask:= cmbFindFileMask.Text;
PathStart:= edtFindPathStart.Text;
Items:= lsFoundedFiles.Items;
RegularExpressions:= cbRegExp.Checked;
SearchDepth:= cbSearchDepth.ItemIndex - 1;
IsNoThisText:= cbNoThisText.Checked;
FindInFiles:= cbFindInFile.Checked;
FindData:= ConvertEncoding(cmbFindText.Text, EncodingUTF8, cbEncoding.Text);
CaseSensitive:= cbCaseSens.Checked;
ReplaceInFiles:= cbReplaceText.Checked;
ReplaceData:= cmbReplaceText.Text;
(* Date search *)
if cbDateFrom.Checked then
begin
IsDateFrom := True;
if TryStrToDate(deDateFrom.Text, dtTemp) then
DateTimeFrom := dtTemp;
end;
if cbDateTo.Checked then
begin
IsDateTo := True;
if TryStrToDate(deDateTo.Text, dtTemp) then
DateTimeTo := dtTemp;
end;
(* Time search *)
if cbTimeFrom.Checked then
begin
IsTimeFrom := True;
dtTemp := 0;
if TryStrToTime(edtTimeFrom.Text, dtTemp) then
DateTimeFrom := DateTimeFrom + dtTemp;
end;
with FindOptions do
begin
StartPath := edtFindPathStart.Text;
FilesMasks := cmbFindFileMask.Text;
SearchDepth := cbSearchDepth.ItemIndex - 1;
RegExp := cbRegExp.Checked;
if cbTimeTo.Checked then
begin
IsTimeTo := True;
dtTemp := 0;
if TryStrToTime(edtTimeTo.Text, dtTemp) then
DateTimeTo := DateTimeTo + dtTemp;
end;
(* Not Older Than *)
if cbNotOlderThan.Checked then
begin
dtNow:= Now;
iCount:= -StrToInt(seNotOlderThan.Text);
case cbDelayUnit.ItemIndex of
0: //Minute(s)
begin
IsDateFrom := True;
IsTimeFrom := True;
DateTimeFrom := IncMinute(dtNow, iCount);
end;
1: //Hour(s)
begin
IsDateFrom := True;
IsTimeFrom := True;
DateTimeFrom := IncHour(dtNow, iCount);
end;
2: //Day(s)
begin
IsDateFrom := True;
DateTimeFrom := IncDay(dtNow, iCount);
end;
3: //Week(s)
begin
IsDateFrom := True;
DateTimeFrom := IncWeek(dtNow, iCount);
end;
4: //Month(s)
begin
IsDateFrom := True;
DateTimeFrom := IncMonth(dtNow, iCount);
end;
5: //Year(s)
begin
IsDateFrom := True;
DateTimeFrom := IncYear(dtNow, iCount);
end;
end;
end;
{ File attributes }
AttributesPattern := edtAttrib.Text;
(* File size search *)
if cbFileSizeFrom.Checked then
begin
IsFileSizeFrom := True;
case cbUnitOfMeasure.ItemIndex of
0:
FileSizeFrom := seFileSizeFrom.Value; //Byte
1:
FileSizeFrom := Int64(seFileSizeFrom.Value) * cKilo; //KiloByte
2:
FileSizeFrom := Int64(seFileSizeFrom.Value) * cMega; //MegaByte
3:
FileSizeFrom := Int64(seFileSizeFrom.Value) * cGiga; //GigaByte
end;
end;
if cbFileSizeTo.Checked then
begin
IsFileSizeTo := True;
case cbUnitOfMeasure.ItemIndex of
0:
FileSizeTo := seFileSizeTo.Value; //Byte
1:
FileSizeTo := Int64(seFileSizeTo.Value) * cKilo; //KiloByte
2:
FileSizeTo := Int64(seFileSizeTo.Value) * cMega; //MegaByte
3:
FileSizeTo := Int64(seFileSizeTo.Value) * cGiga; //GigaByte
end;
end;
(* File attributes *)
if cbAttrib.Checked then
begin
Attributes := 0;
{ Date/time }
DateTimeFrom := 0;
DateTimeTo := 0;
IsDateFrom := False;
IsDateTo := False;
IsTimeFrom := False;
IsTimeTo := False;
if cbDateFrom.Checked then
begin
if TryStrToDate(deDateFrom.Text, dtTemp) then
begin
IsDateFrom := True;
DateTimeFrom := dtTemp;
end;
end;
if cbDateTo.Checked then
begin
if TryStrToDate(deDateTo.Text, dtTemp) then
begin
IsDateTo := True;
DateTimeTo := dtTemp;
end;
end;
if cbTimeFrom.Checked then
begin
if TryStrToTime(edtTimeFrom.Text, dtTemp) then
begin
IsTimeFrom := True;
DateTimeFrom := DateTimeFrom + dtTemp;
end;
end;
if cbTimeTo.Checked then
begin
if TryStrToTime(edtTimeTo.Text, dtTemp) then
begin
IsTimeTo := True;
DateTimeTo := DateTimeTo + dtTemp;
end;
end;
if cbDirectory.Checked then
Attributes := Attributes or faDirectory;
{ Not Older Than }
IsNotOlderThan := cbNotOlderThan.Checked;
NotOlderThan := seNotOlderThan.Value;
NotOlderThanUnit := ComboIndexToTimeUnit[cmbNotOlderThanUnit.ItemIndex];
DebugLn('Attributes == ' + IntToStr(Attributes));
{ File size }
IsFileSizeFrom := cbFileSizeFrom.Checked;
IsFileSizeTo := cbFileSizeTo.Checked;
FileSizeFrom := seFileSizeFrom.Value;
FileSizeTo := seFileSizeTo.Value;
FileSizeUnit := ComboIndexToFileSizeUnit[cmbFileSizeUnit.ItemIndex];
if cbSymLink.Checked then
Attributes := Attributes or uOSUtils.faSymLink;
{ Find/replace text }
IsFindText := cbFindText.Checked;
FindText := cmbFindText.Text;
IsReplaceText := cbReplaceText.Checked;
ReplaceText := cmbReplaceText.Text;
CaseSensitive := cbCaseSens.Checked;
NotContainingText := cbNotContainingText.Checked;
TextEncoding := cmbEncoding.Text;
SearchPlugin := cmbPlugin.Text;
end;
end;
if Attributes = 0 then
Attributes := faAnyFile;
procedure TfrmFindDlg.FindOptionsToDSXSearchRec(
const AFindOptions: TSearchTemplateRec;
var SRec: TDsxSearchRecord);
begin
with AFindOptions do
begin
FillByte(SRec, SizeOf(TDsxSearchRecord), 0);
if cbMore.Checked then
AttribStr := edtAttrib.Text;
SRec.FileMask:= Copy(FilesMasks, 1, SizeOf(SRec.FileMask));
SRec.Attributes:= faAnyFile; // AttrStrToFileAttr?
SRec.AttribStr:= Copy(AttributesPattern, 1, SizeOf(SRec.AttribStr));
end;
end;
except
FreeAndNil(FFindThread);
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 (cbUsePlugin.Checked) and (cbbSPlugins.ItemIndex<>-1) then
begin
DSXPlugins.GetDSXModule(cbbSPlugins.ItemIndex).CallStopSearch;
DSXPlugins.GetDSXModule(cbbSPlugins.ItemIndex).CallFinalize;
ThreadTerminate(nil);
end;
if Assigned(FFindThread) then
if FSearchingActive then
begin
FFindThread.Terminate;
if (cbUsePlugin.Checked) and (cmbPlugin.ItemIndex<>-1) then
begin
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallStopSearch;
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallFinalize;
AfterSearchStopped;
end;
if Assigned(FFindThread) then
begin
FFindThread.Terminate;
FFindThread := nil;
end;
end;
end;
procedure TfrmFindDlg.AfterSearchStopped;
begin
btnStop.Enabled:=False;
btnStart.Enabled:=True;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default:=True;
{$ENDIF}
btnClose.Enabled:=True;
FSearchingActive := False;
end;
procedure TfrmFindDlg.btnStartClick(Sender: TObject);
var
sTemp,
sPath : UTF8String;
sr: TSearchAttrRecord;
sr: TDsxSearchRecord;
FindOptions: TSearchTemplateRec;
begin
sTemp:= edtFindPathStart.Text;
repeat
@ -646,7 +577,7 @@ begin
// add to find mask history
InsertFirstItem(cmbFindFileMask.Text, cmbFindFileMask);
// add to search text history
if cbFindInFile.Checked then
if cbFindText.Checked then
InsertFirstItem(cmbFindText.Text, cmbFindText);
// add to replace text history
if cbReplaceText.Checked then
@ -666,37 +597,36 @@ begin
btnStart.Enabled:=False;
btnClose.Enabled:=False;
PrepareSearch;
if Assigned(FFindThread) then
FillFindOptions(FindOptions);
try
FSearchingActive := True;
with FFindThread do
begin
Status:=lblStatus;
Current:=lblCurrent;
Found:=lblFound;
//---------------------
if (cbUsePlugin.Checked) and (cbbSPlugins.ItemIndex<>-1) then
begin
DSXPlugins.LoadModule(cbbSPlugins.ItemIndex);
FillSearchRecord(sr);
FreeAndNil(FFindThread);
DSXPlugins.GetDSXModule(cbbSPlugins.ItemIndex).CallInit(@SAddFileProc,@SUpdateStatusProc);
DSXPlugins.GetDSXModule(cbbSPlugins.ItemIndex).CallStartSearch(PChar(edtFindPathStart.Text),sr);
end
else
if (cbUsePlugin.Checked) and (cmbPlugin.ItemIndex<>-1) then
begin
if DSXPlugins.LoadModule(cmbPlugin.ItemIndex) then
begin
OnTerminate:=@ThreadTerminate; // will update the buttons after search is finished
Resume;
FindOptionsToDSXSearchRec(FindOptions, sr);
FSearchingActive := True;
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallInit(@SAddFileProc,@SUpdateStatusProc);
DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallStartSearch(PChar(edtFindPathStart.Text),sr);
end
else
StopSearch;
end
else
begin
FFindThread := TFindThread.Create(FindOptions);
with FFindThread do
begin
Items := lsFoundedFiles.Items;
Status := lblStatus;
Current := lblCurrent;
Found := lblFound;
OnTerminate := @ThreadTerminate; // will update the buttons after search is finished
end;
end;
FFindThread.Resume;
end;
except
if Assigned(FFindThread) then
FreeAndNil(FFindThread);
FSearchingActive := False;
StopSearch;
raise;
end;
end;
@ -711,7 +641,6 @@ end;
procedure TfrmFindDlg.btnWorkWithFoundClick(Sender: TObject);
var
I, Count: Integer;
FileRecItem: TFileRecItem;
sFileName: String;
begin
// This should create a new file source (virtual).
@ -739,11 +668,6 @@ begin
Close;
end;
procedure TfrmFindDlg.cbAttribChange(Sender: TObject);
begin
gbAttributes.Enabled := cbAttrib.Checked;
end;
procedure TfrmFindDlg.cbDateFromChange(Sender: TObject);
begin
deDateFrom.Enabled := cbDateFrom.Checked;
@ -763,9 +687,9 @@ begin
seFileSizeFrom.Enabled := cbFileSizeFrom.Checked;
if seFileSizeFrom.Enabled or seFileSizeTo.Enabled then
cbUnitOfMeasure.Enabled := True
cmbFileSizeUnit.Enabled := True
else
cbUnitOfMeasure.Enabled := False;
cmbFileSizeUnit.Enabled := False;
end;
procedure TfrmFindDlg.cbFileSizeToChange(Sender: TObject);
@ -773,27 +697,22 @@ begin
seFileSizeTo.Enabled := cbFileSizeTo.Checked;
if seFileSizeFrom.Enabled or seFileSizeTo.Enabled then
cbUnitOfMeasure.Enabled := True
cmbFileSizeUnit.Enabled := True
else
cbUnitOfMeasure.Enabled := False;
end;
procedure TfrmFindDlg.cbMoreChange(Sender: TObject);
begin
edtAttrib.Enabled := cbMore.Checked;
cmbFileSizeUnit.Enabled := False;
end;
procedure TfrmFindDlg.cbNotOlderThanChange(Sender: TObject);
begin
seNotOlderThan.Enabled := cbNotOlderThan.Checked;
cbDelayUnit.Enabled := cbNotOlderThan.Checked;
cmbNotOlderThanUnit.Enabled := cbNotOlderThan.Checked;
end;
procedure TfrmFindDlg.cbReplaceTextChange(Sender: TObject);
begin
cmbReplaceText.Enabled := cbReplaceText.Checked;
cbNoThisText.Checked := False;
cbNoThisText.Enabled := not cbReplaceText.Checked;
cbNotContainingText.Checked := False;
cbNotContainingText.Enabled := not cbReplaceText.Checked;
if cmbReplaceText.Enabled and cmbReplaceText.CanFocus then
begin
@ -827,14 +746,8 @@ end;
procedure TfrmFindDlg.ThreadTerminate(Sender:TObject);
begin
btnStop.Enabled:=False;
btnStart.Enabled:=True;
{$IF NOT (DEFINED(LCLGTK) or DEFINED(LCLGTK2))}
btnStart.Default:=True;
{$ENDIF}
btnClose.Enabled:=True;
FFindThread:=nil;
FSearchingActive := False;
AfterSearchStopped;
end;
procedure TfrmFindDlg.btnStopClick(Sender: TObject);
@ -915,19 +828,19 @@ begin
end;
cmbReplaceText.Items.Assign(glsReplaceHistory);
cbbSPlugins.Clear;
cmbPlugin.Clear;
for I:= 0 to DSXPlugins.Count-1 do
begin
cbbSPlugins.AddItem(DSXPlugins.GetDSXModule(i).Name+' (' + DSXPlugins.GetDSXModule(I).Descr+' )',nil);
cmbPlugin.AddItem(DSXPlugins.GetDSXModule(i).Name+' (' + DSXPlugins.GetDSXModule(I).Descr+' )',nil);
end;
if (cbbSPlugins.Items.Count>0) then cbbSPlugins.ItemIndex:=0;
if (cmbPlugin.Items.Count>0) then cmbPlugin.ItemIndex:=0;
end;
procedure TfrmFindDlg.lbSearchTemplatesSelectionChange(Sender: TObject; User: boolean);
begin
if lbSearchTemplates.ItemIndex < 0 then Exit;
with gSearchTemplateList.Templates[lbSearchTemplates.ItemIndex] do
lblSearchContents.Caption:= '"'+SearchRecord.rFileMask+'" in "'+StartPath+'"';
with gSearchTemplateList.Templates[lbSearchTemplates.ItemIndex].SearchRecord do
lblSearchContents.Caption := '"' + FilesMasks + '" in "' + StartPath + '"';
end;
procedure TfrmFindDlg.lsFoundedFilesDblClick(Sender: TObject);

View file

@ -5,7 +5,7 @@ unit uFileAttributes;
interface
uses
Classes, SysUtils;
Classes, SysUtils, uTypes;
const // Windows attributes
FILE_ATTRIBUTE_ARCHIVE = 32;
@ -61,7 +61,102 @@ const // Unix attributes
S_ISGID = $0400;
S_ISVTX = $0200;
function SingleStrToFileAttr(sAttr: String): TFileAttrs;
function WinSingleStrToFileAttr(sAttr: String): TFileAttrs;
function UnixSingleStrToFileAttr(sAttr: String): TFileAttrs;
implementation
uses
uDCUtils;
type
TAttrStrToFileAttr = record
Str: String;
Attr: TFileAttrs;
end;
const
WinAttrStrToFileAttr: array[0..9] of TAttrStrToFileAttr = (
(Str: 'r'; Attr: FILE_ATTRIBUTE_READONLY),
(Str: 'h'; Attr: FILE_ATTRIBUTE_HIDDEN),
(Str: 's'; Attr: FILE_ATTRIBUTE_SYSTEM),
(Str: 'd'; Attr: FILE_ATTRIBUTE_DIRECTORY),
(Str: 'a'; Attr: FILE_ATTRIBUTE_ARCHIVE),
(Str: 't'; Attr: FILE_ATTRIBUTE_TEMPORARY),
(Str: 'p'; Attr: FILE_ATTRIBUTE_SPARSE_FILE),
(Str: 'l'; Attr: FILE_ATTRIBUTE_REPARSE_POINT),
(Str: 'c'; Attr: FILE_ATTRIBUTE_COMPRESSED),
(Str: 'e'; Attr: FILE_ATTRIBUTE_ENCRYPTED));
UnixAttrStrToFileAttr: array[0..18] of TAttrStrToFileAttr = (
// Permissions
(Str: 'ur'; Attr: S_IRUSR),
(Str: 'uw'; Attr: S_IWUSR),
(Str: 'ux'; Attr: S_IXUSR),
(Str: 'gr'; Attr: S_IRGRP),
(Str: 'gw'; Attr: S_IWGRP),
(Str: 'gx'; Attr: S_IXGRP),
(Str: 'or'; Attr: S_IROTH),
(Str: 'ow'; Attr: S_IWOTH),
(Str: 'ox'; Attr: S_IXOTH),
(Str: 'us'; Attr: S_ISUID),
(Str: 'gs'; Attr: S_ISGID),
(Str: 'vs'; Attr: S_ISVTX),
// File types
(Str: 'f'; Attr: S_IFIFO),
(Str: 'c'; Attr: S_IFCHR),
(Str: 'd'; Attr: S_IFDIR),
(Str: 'b'; Attr: S_IFBLK),
(Str: 'r'; Attr: S_IFREG),
(Str: 'l'; Attr: S_IFLNK),
(Str: 's'; Attr: S_IFSOCK));
function SingleStrToFileAttr(sAttr: String): TFileAttrs;
begin
{$IF DEFINED(MSWINDOWS)}
Result := WinSingleStrToFileAttr(sAttr);
{$ELSEIF DEFINED(UNIX)}
Result := UnixSingleStrToFileAttr(sAttr);
{$ENDIF}
end;
function WinSingleStrToFileAttr(sAttr: String): TFileAttrs;
var
i: Integer;
begin
for i := Low(WinAttrStrToFileAttr) to High(WinAttrStrToFileAttr) do
begin
if sAttr = WinAttrStrToFileAttr[i].Str then
Exit(WinAttrStrToFileAttr[i].Attr);
end;
Result := 0;
end;
function UnixSingleStrToFileAttr(sAttr: String): TFileAttrs;
var
i: Integer;
begin
if Length(sAttr) > 0 then
begin
if sAttr[1] in ['0'..'7'] then
begin
// Octal representation.
{$PUSH}{$R-,Q-}
Result := OctToDec(sAttr);
{$POP}
end
else
begin
for i := Low(UnixAttrStrToFileAttr) to High(UnixAttrStrToFileAttr) do
begin
if sAttr = UnixAttrStrToFileAttr[i].Str then
Exit(UnixAttrStrToFileAttr[i].Attr);
end;
end;
end;
Result := 0;
end;
end.

View file

@ -3,9 +3,9 @@
-------------------------------------------------------------------------
(DSX) Search plugin API implementation.
DSX - Double commander Search eXtentions.
Copyright (C) 2008 Dmitry Kolomiets (B4rr4cuda@rambler.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
@ -22,10 +22,10 @@
}
unit udsxmodule;
unit uDsxModule;
{$mode objfpc}{$H+}
interface
uses
@ -34,84 +34,84 @@ uses
type
{Prototypes}
{Mandatory (must be implemented)}
TSInit=function (dps:pDSXDefaultParamStruct; pAddFileProc:TSAddFileProc; pUpdateStatus:TSUpdateStatusProc):integer; stdcall;
TSStartSearch= procedure(PluginNr:integer; StartPath:pchar; SearchAttrRec:TSearchAttrRecord); stdcall;
TSStopSearch=procedure (PluginNr:integer); stdcall;
TSFinalize=procedure (PluginNr:integer); stdcall;
{Prototypes}
{Mandatory (must be implemented)}
TSInit = function(dps: pDSXDefaultParamStruct; pAddFileProc: TSAddFileProc;
pUpdateStatus: TSUpdateStatusProc): integer; stdcall;
TSStartSearch = procedure(PluginNr: integer; StartPath: PChar;
SearchRec: TDsxSearchRecord); stdcall;
TSStopSearch = procedure(PluginNr: integer); stdcall;
TSFinalize = procedure(PluginNr: integer); stdcall;
{ TDsxModule }
{ TDsxModule }
TDsxModule=class
protected
SStartSearch:TSStartSearch;
SStopSearch:TSStopSearch;
SAddFileProc:TSAddFileProc;
SUpdateStatusProc:TSUpdateStatusProc;
SInit:TSInit;
SFinalize:TSFinalize;
private
FPluginNr:integer;
FModuleHandle:TLibHandle; // Handle to .DLL or .so
function GIsLoaded:boolean;
public
Name:string;
FileName:string;
Descr:string;
//---------------------
constructor Create;
destructor Destroy; override;
//---------------------
function LoadModule:Boolean;
procedure UnloadModule;
//---------------------
function CallInit(pAddFileProc:TSAddFileProc; pUpdateStatus:TSUpdateStatusProc):integer;
procedure CallStartSearch(StartPath:pchar; SearchAttrRec:TSearchAttrRecord);
procedure CallStopSearch;
procedure CallFinalize;
//---------------------
property IsLoaded:boolean read GIsLoaded;
property ModuleHandle:TLibHandle read FModuleHandle write FModuleHandle;
end;
{ TDSXModuleList }
TDsxModule = class
protected
SStartSearch: TSStartSearch;
SStopSearch: TSStopSearch;
SAddFileProc: TSAddFileProc;
SUpdateStatusProc: TSUpdateStatusProc;
SInit: TSInit;
SFinalize: TSFinalize;
private
FPluginNr: integer;
FModuleHandle: TLibHandle; // Handle to .DLL or .so
function GIsLoaded: boolean;
public
Name: string;
FileName: string;
Descr: string;
//---------------------
constructor Create;
destructor Destroy; override;
//---------------------
function LoadModule: boolean;
procedure UnloadModule;
//---------------------
function CallInit(pAddFileProc: TSAddFileProc; pUpdateStatus: TSUpdateStatusProc): integer;
procedure CallStartSearch(StartPath: PChar; SearchRec: TDsxSearchRecord);
procedure CallStopSearch;
procedure CallFinalize;
//---------------------
property IsLoaded: boolean read GIsLoaded;
property ModuleHandle: TLibHandle read FModuleHandle write FModuleHandle;
end;
TDSXModuleList = class
private
Flist:TStringList;
function GetCount:integer;
public
//---------------------
constructor Create;
destructor Destroy; override;
//---------------------
procedure Clear;
procedure Load(Ini:TIniFileEx); overload;
procedure Load(AConfig: TXmlConfig; ANode: TXmlNode); overload;
procedure Save(Ini:TIniFileEx); overload;
procedure Save(AConfig: TXmlConfig; ANode: TXmlNode); overload;
procedure DeleteItem(Index: integer);
//---------------------
function Add(Item:TDSXModule):integer;overload;
function Add(FileName:string):integer;overload;
function Add(AName,FileName,Descr:string):integer;overload;
//---------------------
procedure Assign(OtherList: TDSXModuleList);
//---------------------
function IsLoaded(AName:String):Boolean;overload;
function IsLoaded(Index: integer):Boolean;overload;
function LoadModule(AName:String):Boolean; overload;
function LoadModule(Index: integer): Boolean; overload;
//---------------------
function GetDSXModule(Index:integer):TDSXModule;overload;
function GetDSXModule(AName:string):TDSXModule;overload;
//---------------------
property Count:integer read GetCount;
end;
{ TDSXModuleList }
TDSXModuleList = class
private
Flist: TStringList;
function GetCount: integer;
public
//---------------------
constructor Create;
destructor Destroy; override;
//---------------------
procedure Clear;
procedure Load(Ini: TIniFileEx); overload;
procedure Load(AConfig: TXmlConfig; ANode: TXmlNode); overload;
procedure Save(Ini: TIniFileEx); overload;
procedure Save(AConfig: TXmlConfig; ANode: TXmlNode); overload;
procedure DeleteItem(Index: integer);
//---------------------
function Add(Item: TDSXModule): integer; overload;
function Add(FileName: string): integer; overload;
function Add(AName, FileName, Descr: string): integer; overload;
//---------------------
procedure Assign(OtherList: TDSXModuleList);
//---------------------
function IsLoaded(AName: string): boolean; overload;
function IsLoaded(Index: integer): boolean; overload;
function LoadModule(AName: string): boolean; overload;
function LoadModule(Index: integer): boolean; overload;
//---------------------
function GetDSXModule(Index: integer): TDSXModule; overload;
function GetDSXModule(AName: string): TDSXModule; overload;
//---------------------
property Count: integer read GetCount;
end;
implementation
@ -126,83 +126,85 @@ const
function TDsxModule.GIsLoaded: boolean;
begin
Result:=FModuleHandle<>0;
Result := FModuleHandle <> 0;
end;
constructor TDsxModule.Create;
begin
FModuleHandle := 0;
inherited Create;
end;
destructor TDsxModule.Destroy;
begin
if GIsLoaded then UnloadModule;
if GIsLoaded then
UnloadModule;
inherited Destroy;
end;
function TDsxModule.LoadModule: Boolean;
function TDsxModule.LoadModule: boolean;
begin
FModuleHandle := mbLoadLibrary(Self.FileName);
Result := (FModuleHandle <> 0);
if FModuleHandle = 0 then exit;
if FModuleHandle = 0 then
exit;
SStopSearch:=TSStopSearch(GetProcAddress(FModuleHandle,'StopSearch'));
SStartSearch:=TSStartSearch(GetProcAddress(FModuleHandle,'StartSearch'));
SInit:=TSInit(GetProcAddress(FModuleHandle,'Init'));
SFinalize:=TSFinalize(GetProcAddress(FModuleHandle,'Finalize'));
SStopSearch := TSStopSearch(GetProcAddress(FModuleHandle, 'StopSearch'));
SStartSearch := TSStartSearch(GetProcAddress(FModuleHandle, 'StartSearch'));
SInit := TSInit(GetProcAddress(FModuleHandle, 'Init'));
SFinalize := TSFinalize(GetProcAddress(FModuleHandle, 'Finalize'));
end;
procedure TDsxModule.UnloadModule;
begin
if Assigned(SFinalize) then SFinalize(FPluginNr);
if FModuleHandle <> 0 then
FreeLibrary(FModuleHandle);
FModuleHandle := 0;
if Assigned(SFinalize) then
SFinalize(FPluginNr);
SStartSearch:=nil;
SStopSearch:=nil;
SInit:=nil;
SFinalize:=nil;
if FModuleHandle <> 0 then
FreeLibrary(FModuleHandle);
FModuleHandle := 0;
SStartSearch := nil;
SStopSearch := nil;
SInit := nil;
SFinalize := nil;
end;
function TDsxModule.CallInit(pAddFileProc: TSAddFileProc;
pUpdateStatus: TSUpdateStatusProc):integer;
var dps:pDSXDefaultParamStruct;
function TDsxModule.CallInit(pAddFileProc: TSAddFileProc; pUpdateStatus: TSUpdateStatusProc): integer;
var
dps: pDSXDefaultParamStruct;
begin
if Assigned(SInit) then
begin
GetMem(dps,SizeOf(tDSXDefaultParamStruct));
dps^.DefaultIniName:=gpCfgDir + DsxIniFileName;
dps^.PluginInterfaceVersionHi:=0;
dps^.PluginInterfaceVersionLow:=10;
dps^.size:=SizeOf(tDSXDefaultParamStruct);
FPluginNr:=Sinit(dps,pAddFileProc,pUpdateStatus);
Result:=FPluginNr;
FreeMem(dps,SizeOf(tDSXDefaultParamStruct));
end;
begin
GetMem(dps, SizeOf(tDSXDefaultParamStruct));
dps^.DefaultIniName := gpCfgDir + DsxIniFileName;
dps^.PluginInterfaceVersionHi := 0;
dps^.PluginInterfaceVersionLow := 10;
dps^.size := SizeOf(tDSXDefaultParamStruct);
FPluginNr := Sinit(dps, pAddFileProc, pUpdateStatus);
Result := FPluginNr;
FreeMem(dps, SizeOf(tDSXDefaultParamStruct));
end;
end;
procedure TDsxModule.CallStartSearch(StartPath: pchar;
SearchAttrRec: TSearchAttrRecord);
procedure TDsxModule.CallStartSearch(StartPath: PChar; SearchRec: TDsxSearchRecord);
begin
if Assigned(SStartSearch) then
begin
SStartSearch(FPluginNr,StartPath,SearchAttrRec);
end;
begin
SStartSearch(FPluginNr, StartPath, SearchRec);
end;
end;
procedure TDsxModule.CallStopSearch;
begin
if Assigned(SStopSearch) then
SStopSearch(FPluginNr);
SStopSearch(FPluginNr);
end;
procedure TDsxModule.CallFinalize;
begin
if Assigned(SFinalize) then
SFinalize(FPluginNr);
SFinalize(FPluginNr);
end;
{ TDSXModuleList }
@ -210,13 +212,14 @@ end;
function TDSXModuleList.GetCount: integer;
begin
if Assigned(Flist) then
Result:=Flist.Count
else Result:=0;
Result := Flist.Count
else
Result := 0;
end;
constructor TDSXModuleList.Create;
begin
Flist:=TStringList.Create;
Flist := TStringList.Create;
end;
destructor TDSXModuleList.Destroy;
@ -229,30 +232,33 @@ end;
procedure TDSXModuleList.Clear;
begin
while Flist.Count>0 do
begin
TDSXModule(Flist.Objects[0]).Free;
Flist.Delete(0);
end;
while Flist.Count > 0 do
begin
TDSXModule(Flist.Objects[0]).Free;
Flist.Delete(0);
end;
end;
procedure TDSXModuleList.Load(Ini: TIniFileEx);
var xCount,I:integer;
tmp:string;
var
xCount, I: integer;
tmp: string;
begin
Self.Clear;
xCount:=Ini.ReadInteger('Search Plugins','PluginCount',0);
if xCount=0 then Exit;
xCount := Ini.ReadInteger('Search Plugins', 'PluginCount', 0);
if xCount = 0 then
Exit;
For i:=0 to xCount-1 do
begin
tmp:=Ini.ReadString('Search Plugins','Plugin'+IntToStr(I+1)+'Name','');
Flist.AddObject(UpCase(tmp),TDSXModule.Create);
TDSXModule(Flist.Objects[I]).Name:=tmp;
TDSXModule(Flist.Objects[I]).Descr:=Ini.ReadString('Search Plugins','Plugin'+IntToStr(I+1)+'Description','');
TDSXModule(Flist.Objects[I]).FileName:=GetCmdDirFromEnvVar(Ini.ReadString('Search Plugins','Plugin'+IntToStr(I+1)+'Path',''));
end;
for i := 0 to xCount - 1 do
begin
tmp := Ini.ReadString('Search Plugins', 'Plugin' + IntToStr(I + 1) + 'Name', '');
Flist.AddObject(UpCase(tmp), TDSXModule.Create);
TDSXModule(Flist.Objects[I]).Name := tmp;
TDSXModule(Flist.Objects[I]).Descr :=
Ini.ReadString('Search Plugins', 'Plugin' + IntToStr(I + 1) + 'Description', '');
TDSXModule(Flist.Objects[I]).FileName :=
GetCmdDirFromEnvVar(Ini.ReadString('Search Plugins', 'Plugin' + IntToStr(I + 1) + 'Path', ''));
end;
end;
procedure TDSXModuleList.Load(AConfig: TXmlConfig; ANode: TXmlNode);
@ -288,17 +294,21 @@ begin
end;
procedure TDSXModuleList.Save(Ini: TIniFileEx);
var i:integer;
var
i: integer;
begin
Ini.EraseSection('Search Plugins');
Ini.WriteInteger('Search Plugins','PluginCount',Flist.Count);
For i:=0 to Flist.Count-1 do
begin
Ini.WriteString('Search Plugins','Plugin'+IntToStr(I+1)+'Name',TDSXModule(Flist.Objects[I]).Name);
Ini.WriteString('Search Plugins','Plugin'+IntToStr(I+1)+'Description',TDSXModule(Flist.Objects[I]).Descr);
Ini.WriteString('Search Plugins','Plugin'+IntToStr(I+1)+'Path',SetCmdDirAsEnvVar(TDSXModule(Flist.Objects[I]).FileName));
end;
end;
Ini.EraseSection('Search Plugins');
Ini.WriteInteger('Search Plugins', 'PluginCount', Flist.Count);
for i := 0 to Flist.Count - 1 do
begin
Ini.WriteString('Search Plugins', 'Plugin' + IntToStr(I + 1) + 'Name',
TDSXModule(Flist.Objects[I]).Name);
Ini.WriteString('Search Plugins', 'Plugin' + IntToStr(I + 1) +
'Description', TDSXModule(Flist.Objects[I]).Descr);
Ini.WriteString('Search Plugins', 'Plugin' + IntToStr(I + 1) + 'Path',
SetCmdDirAsEnvVar(TDSXModule(Flist.Objects[I]).FileName));
end;
end;
procedure TDSXModuleList.Save(AConfig: TXmlConfig; ANode: TXmlNode);
var
@ -309,45 +319,46 @@ begin
AConfig.ClearNode(ANode);
for i := 0 to Flist.Count - 1 do
begin
SubNode := AConfig.AddNode(ANode, 'DsxPlugin');
AConfig.AddValue(SubNode, 'Name', TDSXModule(Flist.Objects[I]).Name);
AConfig.AddValue(SubNode, 'Path', SetCmdDirAsEnvVar(TDSXModule(Flist.Objects[I]).FileName));
AConfig.AddValue(SubNode, 'Description', TDSXModule(Flist.Objects[I]).Descr);
end;
begin
SubNode := AConfig.AddNode(ANode, 'DsxPlugin');
AConfig.AddValue(SubNode, 'Name', TDSXModule(Flist.Objects[I]).Name);
AConfig.AddValue(SubNode, 'Path', SetCmdDirAsEnvVar(TDSXModule(Flist.Objects[I]).FileName));
AConfig.AddValue(SubNode, 'Description', TDSXModule(Flist.Objects[I]).Descr);
end;
end;
procedure TDSXModuleList.DeleteItem(Index: integer);
begin
if (Index>-1) and (Index<Flist.Count) then
begin
if (Index > -1) and (Index < Flist.Count) then
begin
TDSXModule(Flist.Objects[Index]).Free;
Flist.Delete(Index);
end;
end;
end;
function TDSXModuleList.Add(Item: TDSXModule): integer;
begin
Result:=Flist.AddObject(UpCase(item.Name),Item);
Result := Flist.AddObject(UpCase(item.Name), Item);
end;
function TDSXModuleList.Add(FileName: string): integer;
var s:string;
var
s: string;
begin
s:=ExtractFileName(FileName);
if pos('.',s)>0 then
delete(s,pos('.',s),length(s));
Result:=Flist.AddObject(UpCase(s),TDSXModule.Create);
TDSXModule(Flist.Objects[Result]).Name:=s;
TDSXModule(Flist.Objects[Result]).FileName:=FileName;
s := ExtractFileName(FileName);
if pos('.', s) > 0 then
Delete(s, pos('.', s), length(s));
Result := Flist.AddObject(UpCase(s), TDSXModule.Create);
TDSXModule(Flist.Objects[Result]).Name := s;
TDSXModule(Flist.Objects[Result]).FileName := FileName;
end;
function TDSXModuleList.Add(AName, FileName, Descr: string): integer;
begin
Result:=Flist.AddObject(UpCase(AName),TDSXModule.Create);
TDSXModule(Flist.Objects[Result]).Name:=AName;
TDSXModule(Flist.Objects[Result]).Descr:=Descr;
TDSXModule(Flist.Objects[Result]).FileName:=FileName;
Result := Flist.AddObject(UpCase(AName), TDSXModule.Create);
TDSXModule(Flist.Objects[Result]).Name := AName;
TDSXModule(Flist.Objects[Result]).Descr := Descr;
TDSXModule(Flist.Objects[Result]).FileName := FileName;
end;
procedure TDSXModuleList.Assign(OtherList: TDSXModuleList);
@ -362,49 +373,55 @@ begin
end;
end;
function TDSXModuleList.IsLoaded(AName: String): Boolean;
var x:integer;
function TDSXModuleList.IsLoaded(AName: string): boolean;
var
x: integer;
begin
x:=Flist.IndexOf(AName);
if x=-1 then Result:=false
x := Flist.IndexOf(AName);
if x = -1 then
Result := False
else
begin
Result:=GetDSXModule(x).IsLoaded;
end;
begin
Result := GetDSXModule(x).IsLoaded;
end;
end;
function TDSXModuleList.IsLoaded(Index: integer): Boolean;
function TDSXModuleList.IsLoaded(Index: integer): boolean;
begin
Result:=GetDSXModule(Index).IsLoaded;
Result := GetDSXModule(Index).IsLoaded;
end;
function TDSXModuleList.LoadModule(AName: String): Boolean;
var x:integer;
function TDSXModuleList.LoadModule(AName: string): boolean;
var
x: integer;
begin
x:=Flist.IndexOf(UpCase(AName));
if x=-1 then Result:=false
x := Flist.IndexOf(UpCase(AName));
if x = -1 then
Result := False
else
begin
Result:=GetDSXModule(x).LoadModule;
end;
begin
Result := GetDSXModule(x).LoadModule;
end;
end;
function TDSXModuleList.LoadModule(Index: integer): Boolean;
function TDSXModuleList.LoadModule(Index: integer): boolean;
begin
Result:=GetDSXModule(Index).LoadModule;
Result := GetDSXModule(Index).LoadModule;
end;
function TDSXModuleList.GetDSXModule(Index: integer): TDSXModule;
begin
Result:=TDSXModule(Flist.Objects[Index]);
Result := TDSXModule(Flist.Objects[Index]);
end;
function TDSXModuleList.GetDSXModule(AName: string): TDSXModule;
var tmp:integer;
var
tmp: integer;
begin
tmp:=Flist.IndexOf(upcase(AName));
if tmp>-1 then
Result:=TDSXModule(Flist.Objects[tmp]);
tmp := Flist.IndexOf(upcase(AName));
if tmp > -1 then
Result := TDSXModule(Flist.Objects[tmp]);
end;
end.

304
src/ufindfiles.pas Normal file
View file

@ -0,0 +1,304 @@
{
Double Commander
-------------------------------------------------------------------------
Structures and functions for searching files.
Copyright (C) 2003-2004 Radek Cervinka (radek.cervinka@centrum.cz)
Copyright (C) 2006-2010 Koblov Alexander (Alexx2000@mail.ru)
Copyright (C) 2010 Przemys³aw Nagay (cobines@gmail.com)
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 uFindFiles;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, uTypes;
type
TTimeUnit = (tuSecond, tuMinute, tuHour, tuDay, tuWeek, tuMonth, tuYear);
TFileSizeUnit = (suBytes, suKilo, suMega, suGiga, suTera);
TSearchTemplateRec = record
StartPath: String;
FilesMasks: String;
SearchDepth: Integer; // -1 = unlimited
RegExp: Boolean;
AttributesPattern: String;
{ Date/time }
IsDateFrom,
IsDateTo,
IsTimeFrom,
IsTimeTo : Boolean;
DateTimeFrom,
DateTimeTo : TDateTime;
IsNotOlderThan: Boolean;
NotOlderThan: Integer;
NotOlderThanUnit: TTimeUnit;
{ File size }
IsFileSizeFrom,
IsFileSizeTo : Boolean;
FileSizeFrom,
FileSizeTo : Int64;
FileSizeUnit: TFileSizeUnit;
{ Find/replace text }
IsFindText: Boolean;
FindText: String;
IsReplaceText : Boolean;
ReplaceText: String;
CaseSensitive,
NotContainingText: Boolean;
TextEncoding: String;
SearchPlugin: String;
end;
TFindFileAttrsCheck = record
HaveAttrs: TFileAttrs; //en> what attributes files must have
DontHaveAttrs: TFileAttrs; //en> what attributes files must not have
Negated: Boolean;
end;
TFindFileChecks = record
FilesMasks: String;
RegExp: Boolean;
DateTimeFrom,
DateTimeTo : TDateTime;
FileSizeFrom,
FileSizeTo : Int64;
Attributes: array of TFindFileAttrsCheck; //en> Each entry is OR'ed.
end;
procedure SearchTemplateToFindFileChecks(const SearchTemplate: TSearchTemplateRec;
var FileChecks: TFindFileChecks);
function CheckFileTime(const FileChecks: TFindFileChecks; FT : TFileTime) : Boolean; inline;
function CheckFileDateTime(const FileChecks: TFindFileChecks; DT : TDateTime) : Boolean;
function CheckFileSize(const FileChecks: TFindFileChecks; FileSize : Int64) : Boolean;
function CheckFileAttributes(const FileChecks: TFindFileChecks; Attrs : TFileAttrs) : Boolean;
implementation
uses
DateUtils, uDateTimeUtils, strutils, uFileAttributes;
const
cKilo = 1024;
cMega = 1024 * cKilo;
cGiga = 1024 * cMega;
cTera = 1024 * cGiga;
procedure DateTimeOptionsToChecks(const SearchTemplate: TSearchTemplateRec;
var FileChecks: TFindFileChecks);
begin
with FileChecks do
begin
if SearchTemplate.IsNotOlderThan then
begin
DateTimeFrom := SysUtils.Now;
DateTimeTo := DateTimeFrom;
case SearchTemplate.NotOlderThanUnit of
tuSecond:
DateTimeFrom := IncSecond(DateTimeFrom, -SearchTemplate.NotOlderThan);
tuMinute:
DateTimeFrom := IncMinute(DateTimeFrom, -SearchTemplate.NotOlderThan);
tuHour:
DateTimeFrom := IncHour(DateTimeFrom, -SearchTemplate.NotOlderThan);
tuDay:
DateTimeFrom := IncDay(DateTimeFrom, -SearchTemplate.NotOlderThan);
tuWeek:
DateTimeFrom := IncWeek(DateTimeFrom, -SearchTemplate.NotOlderThan);
tuMonth:
DateTimeFrom := IncMonth(DateTimeFrom, -SearchTemplate.NotOlderThan);
tuYear:
DateTimeFrom := IncYear(DateTimeFrom, -SearchTemplate.NotOlderThan);
end;
end
else
begin
if SearchTemplate.IsDateFrom then
begin
if SearchTemplate.IsTimeFrom then
DateTimeFrom := SearchTemplate.DateTimeFrom
else
DateTimeFrom := Trunc(SearchTemplate.DateTimeFrom);
end
else if SearchTemplate.IsTimeFrom then
DateTimeFrom := Frac(SearchTemplate.DateTimeFrom)
else
DateTimeFrom := 0;
if SearchTemplate.IsDateTo then
begin
if SearchTemplate.IsTimeTo then
DateTimeTo := SearchTemplate.DateTimeTo
else
DateTimeTo := Trunc(SearchTemplate.DateTimeTo) + Frac(MaxDateTime);
end
else if SearchTemplate.IsTimeTo then
DateTimeFrom := Frac(SearchTemplate.DateTimeTo)
else
DateTimeFrom := 0;
end;
end;
end;
procedure FileSizeOptionsToChecks(const SearchTemplate: TSearchTemplateRec;
var FileChecks: TFindFileChecks);
function GetFileSizeWithUnit(Size: Int64): Int64;
begin
case SearchTemplate.FileSizeUnit of
suBytes:
Result := Size;
suKilo:
Result := Size * cKilo;
suMega:
Result := Size * cMega;
suGiga:
Result := Size * cGiga;
suTera:
Result := Size * cTera;
end;
end;
begin
if SearchTemplate.IsFileSizeFrom then
FileChecks.FileSizeFrom := GetFileSizeWithUnit(SearchTemplate.FileSizeFrom)
else
FileChecks.FileSizeFrom := 0;
if SearchTemplate.IsFileSizeTo then
FileChecks.FileSizeTo := GetFileSizeWithUnit(SearchTemplate.FileSizeTo)
else
FileChecks.FileSizeTo := High(FileChecks.FileSizeTo);
end;
function AttrPatternToCheck(const AttrPattern: String): TFindFileAttrsCheck;
var
StartIndex, CurIndex: Integer;
begin
Result.HaveAttrs := 0;
Result.DontHaveAttrs := 0;
Result.Negated := False;
StartIndex := 1;
CurIndex := StartIndex;
while CurIndex <= Length(AttrPattern) do
begin
case AttrPattern[CurIndex] of
'+', ' ':
begin
Result.HaveAttrs := Result.HaveAttrs or
SingleStrToFileAttr(Copy(AttrPattern, StartIndex, CurIndex - StartIndex));
StartIndex := CurIndex + 1;
end;
'-':
begin
Result.DontHaveAttrs := Result.DontHaveAttrs or
SingleStrToFileAttr(Copy(AttrPattern, StartIndex, CurIndex - StartIndex));
StartIndex := CurIndex + 1;
end;
'!':
begin
if CurIndex = 1 then
Result.Negated := True;
StartIndex := CurIndex + 1;
end;
end;
Inc(CurIndex);
end;
end;
procedure AttrsPatternOptionsToChecks(const SearchTemplate: TSearchTemplateRec;
var FileChecks: TFindFileChecks);
var
AttrsPattern, CurPattern: String;
begin
FileChecks.Attributes := nil;
AttrsPattern := SearchTemplate.AttributesPattern;
while AttrsPattern <> '' do
begin
// For each pattern separated by '|' create a new TFindFileAttrsCheck.
CurPattern := Copy2SymbDel(AttrsPattern, '|');
if CurPattern <> '' then
with FileChecks do
begin
SetLength(Attributes, Length(Attributes) + 1);
Attributes[Length(Attributes) - 1] := AttrPatternToCheck(CurPattern);
end;
end;
end;
procedure SearchTemplateToFindFileChecks(const SearchTemplate: TSearchTemplateRec;
var FileChecks: TFindFileChecks);
begin
FileChecks.FilesMasks := SearchTemplate.FilesMasks;
FileChecks.RegExp := SearchTemplate.RegExp;
DateTimeOptionsToChecks(SearchTemplate, FileChecks);
FileSizeOptionsToChecks(SearchTemplate, FileChecks);
AttrsPatternOptionsToChecks(SearchTemplate, FileChecks);
end;
function CheckFileTime(const FileChecks: TFindFileChecks; FT : TFileTime) : Boolean;
begin
Result := CheckFileDateTime(FileChecks, FileTimeToDateTime(FT));
end;
function CheckFileDateTime(const FileChecks: TFindFileChecks; DT : TDateTime) : Boolean;
begin
with FileChecks do
Result := (DateTimeFrom <= DT) and (DT <= DateTimeTo);
end;
function CheckFileSize(const FileChecks: TFindFileChecks; FileSize: Int64): Boolean;
begin
with FileChecks do
Result := (FileSizeFrom <= FileSize) and (FileSize <= FileSizeTo);
end;
function CheckFileAttributes(const FileChecks: TFindFileChecks; Attrs : TFileAttrs) : Boolean;
var
i: Integer;
begin
if Length(FileChecks.Attributes) = 0 then
Result := True
else
begin
for i := Low(FileChecks.Attributes) to High(FileChecks.Attributes) do
begin
with FileChecks.Attributes[i] do
begin
Result := ((Attrs and HaveAttrs) = HaveAttrs) and
((Attrs and DontHaveAttrs) = 0);
if Negated then
Result := not Result;
if Result then
Exit;
end;
end;
Result := False;
end;
end;
end.

View file

@ -23,21 +23,20 @@
}
unit uFindThread;
{$mode objfpc}{$H+}
interface
uses
Classes, StdCtrls, SysUtils, DsxPlugin, uTypes;
Classes, StdCtrls, SysUtils, uTypes, uFindFiles;
type
{ TFindThread }
{ TFindThread }
TFindThread = class(TThread)
TFindThread = class(TThread)
private
{ Private declarations }
FPathStart:String;
FItems: TStrings;
FStatus: TLabel;
FFound: TLabel;
@ -46,112 +45,62 @@ TFindThread = class(TThread)
FFilesScanned:Integer;
FFilesFound:Integer;
FFoundFile:String;
FFileMask : String;
FAttributes: TFileAttrs;
FAttribStr : String;
FCaseSens: Boolean;
FRegExp: Boolean;
FCurrentDepth,
FSearchDepth: Integer;
{Date search}
FIsDateFrom,
FIsDateTo : Boolean;
FDateTimeFrom,
FDateTimeTo : TDateTime;
{Time search}
FIsTimeFrom,
FIsTimeTo : Boolean;
(* File size search *)
FIsFileSizeFrom,
FIsFileSizeTo : Boolean;
FFileSizeFrom,
FFileSizeTo : Int64;
(* Find text *)
FIsNoThisText,
FFindInFiles:Boolean;
FFindData:String;
(* Replace text *)
FReplaceInFiles : Boolean;
FReplaceData : String;
FCurrentDepth: Integer;
FSearchTemplate: TSearchTemplateRec;
FFileChecks: TFindFileChecks;
procedure SetFileMask(const AValue: String);
procedure SetSearchDepth(const AValue: Integer);
function CheckFileDate(DT : TFileTime) : Boolean;
function CheckFileSize(FileSize : Int64) : Boolean;
function CheckFile(const Folder : String; const sr : TSearchRecEx) : Boolean;
function FindInFile(const sFileName:UTF8String;
sData: String; bCase:Boolean): Boolean;
protected
procedure Execute; override;
public
constructor Create;
constructor Create(const AFindOptions: TSearchTemplateRec);
destructor Destroy; override;
procedure AddFile;
procedure WalkAdr(const sNewDir:String);
procedure UpDateProgress;
procedure FillSearchRecord(var Srec:TSearchAttrRecord);
function IsAborting: Boolean;
property FilterMask:String read FFileMask write SetFileMask;
property PathStart:String read FPathStart write FPathStart;
property Items:TStrings write FItems;
property RegularExpressions: Boolean read FRegExp write FRegExp;
property SearchDepth: Integer read FSearchDepth write SetSearchDepth;
(* Find text *)
property FindInFiles:Boolean write FFindInFiles;
property IsNoThisText:Boolean write FIsNoThisText default False;
property Status:TLabel read FStatus write FStatus;
property Found:TLabel read FFound write FFound;
property Current:TLabel read FCurrent write FCurrent; // label current file
property CaseSensitive:boolean read FCaseSens write FCaseSens;
property FindData:String read FFindData write FFindData;
(* Replace text *)
property ReplaceInFiles:Boolean write FReplaceInFiles;
property ReplaceData:String read FReplaceData write FReplaceData;
(* Date search *)
property IsDateFrom:Boolean read FIsDateFrom write FIsDateFrom;
property IsDateTo:Boolean read FIsDateTo write FIsDateTo;
property DateTimeFrom:TDateTime read FDateTimeFrom write FDateTimeFrom;
property DateTimeTo:TDateTime read FDateTimeTo write FDateTimeTo;
(* Time search *)
property IsTimeFrom:Boolean read FIsTimeFrom write FIsTimeFrom;
property IsTimeTo:Boolean read FIsTimeTo write FIsTimeTo;
(* File size search *)
property IsFileSizeFrom : Boolean read FIsFileSizeFrom write FIsFileSizeFrom;
property IsFileSizeTo : Boolean read FIsFileSizeTo write FIsFileSizeTo;
property FileSizeFrom : Int64 read FFileSizeFrom write FFileSizeFrom;
property FileSizeTo : Int64 read FFileSizeTo write FFileSizeTo;
property Attributes: TFileAttrs read FAttributes write FAttributes;
property AttribStr : String read FAttribStr write FAttribStr;
end;
implementation
uses
LCLProc, Dialogs, DateUtils, Masks, SynRegExpr, StrUtils, uLng, uClassesEx, uFindMmap, uFindEx,
uGlobs, uShowMsg, uOSUtils, uLog, uDateTimeUtils;
LCLProc, Masks, SynRegExpr, StrUtils, LConvEncoding,
uLng, uClassesEx, uFindMmap, uFindEx, uGlobs, uShowMsg, uOSUtils, uLog;
{ TFindThread }
constructor TFindThread.Create;
constructor TFindThread.Create(const AFindOptions: TSearchTemplateRec);
begin
inherited Create(True);
FCaseSens:=True;
FFilesScanned:=0;
FFilesFound := 0;
FilterMask:='*';
FPathStart:= mbGetCurrentDir;
FItems:=nil;
FIsDateFrom := False;
FIsDateTo := False;
FIsFileSizeFrom := False;
FIsFileSizeTo := False;
FAttributes := faAnyFile;
FAttribStr := '?????????';
FSearchDepth:= MaxInt;
FItems := nil;
FSearchTemplate := AFindOptions;
with FSearchTemplate do
begin
if SearchDepth < 0 then
SearchDepth := MaxInt;
// use case insensitive mask because
// MatchesMaskList work incorrect with non ASCII characters
// since it uses UpCase function
FilesMasks := UTF8UpperCase(FilesMasks);
FindText := ConvertEncoding(FindText, EncodingUTF8, TextEncoding);
ReplaceText := ConvertEncoding(ReplaceText, EncodingUTF8, TextEncoding);
end;
SearchTemplateToFindFileChecks(FSearchTemplate, FFileChecks);
end;
destructor TFindThread.Destroy;
@ -172,7 +121,7 @@ begin
FCurrentDepth:= -1;
sCurrDir:= mbGetCurrentDir;
try
sTemp:= FPathStart;
sTemp:= FSearchTemplate.StartPath;
while sTemp <> EmptyStr do
begin
sPath:= Copy2SymbDel(sTemp, ';');
@ -190,22 +139,6 @@ begin
end;
end;
procedure TFindThread.SetSearchDepth(const AValue: Integer);
begin
if AValue < 0 then
FSearchDepth:= MaxInt
else
FSearchDepth:= AValue;
end;
procedure TFindThread.SetFileMask(const AValue: String);
begin
// use case insensitive mask because
// MatchesMaskList work incorrect with non ACSII characters
// since it use UpCase function
FFileMask:= UTF8UpperCase(AValue);
end;
procedure TFindThread.AddFile;
begin
FItems.Add(FFoundFile);
@ -341,128 +274,54 @@ begin
end;
end;
function TFindThread.CheckFileDate(DT : TFileTime) : Boolean;
var
DateTime: TDateTime;
begin
Result := True;
DateTime := FileTimeToDateTime(DT);
(* Check date from *)
if FIsDateFrom then
Result := (Int(DateTime) >= Int(FDateTimeFrom));
(* Check time to *)
if (FIsDateTo and Result) then
Result := (Int(DateTime) <= Int(FDateTimeTo));
(* Check time from *)
if (FIsTimeFrom and Result) then
Result := (CompareTime(DateTime, FDateTimeFrom) >= 0);
//DebugLn('Time From = ', FloatToStr(FDateTimeFrom), ' File time = ', FloatToStr(DateTime), ' Result = ', BoolToStr(Result));
(* Check time to *)
if (FIsTimeTo and Result) then
Result := (CompareTime(DateTime, FDateTimeTo) <= 0);
//DebugLn('Time To = ', FloatToStr(FDateTimeTo), ' File time = ', FloatToStr(DateTime), ' Result = ', BoolToStr(Result));
end;
function TFindThread.CheckFileSize(FileSize: Int64): Boolean;
begin
Result := True;
if FIsFileSizeFrom then
Result := (FileSize >= FFileSizeFrom);
//DebugLn('After From', FileSize, '-', FFileSizeFrom, BoolToStr(Result));
if (FIsFileSizeTo and Result) then
Result := (FileSize <= FFileSizeTo);
//DebugLn('After To', FileSize, '-', FFileSizeTo, BoolToStr(Result));
end;
function TFindThread.CheckFile(const Folder : String; const sr : TSearchRecEx) : Boolean;
begin
Result := True;
// check regular expression
if FRegExp and not ExecRegExpr(FFileMask, sr.Name) then
Exit(False);
//DebugLn('File = ', sr.Name);
if (not FRegExp) and (not MatchesMaskList(UTF8UpperCase(sr.Name), FFileMask)) then
Exit(False);
if (FIsDateFrom or FIsDateTo or FIsTimeFrom or FIsTimeTo) then
Result := CheckFileDate(sr.Time);
if (FIsFileSizeFrom or FIsFileSizeTo) and Result then
Result := CheckFileSize(sr.Size);
// if Length(FAttribStr) <> 0 then
begin
Result := CheckAttrMask(FAttributes, FAttribStr, sr.Attr);
end;
if (FFindInFiles and Result) then
begin
if FPS_ISDIR(sr.Attr) then
begin
Result := False;
Exit;
end;
try
Result := FindInFile(Folder + PathDelim + sr.Name, FFindData, FCaseSens);
if (FReplaceInFiles and Result) then
FileReplaceString(Folder + PathDelim + sr.Name, FFindData, FReplaceData, FCaseSens);
if FIsNoThisText then
Result := not Result;
except
on e : EFOpenError do
begin
if (log_errors in gLogOptions) then
logWrite(Self, rsMsgLogError + rsMsgErrEOpen + ' ' +
Folder + PathDelim + sr.Name, lmtError);
Result := False;
end;
end;
end;
end;
procedure TFindThread.FillSearchRecord(var Srec:TSearchAttrRecord);
begin
with Srec do
with FSearchTemplate do
begin
rFileMask:= StrNew(PChar(FFileMask));
rAttributes:=FAttributes;
rAttribStr:= StrNew(PChar(FAttribStr));
rCaseSens:=FCaseSens;
{Date search}
rIsDateFrom:=FIsDateFrom;
rIsDateTo:=FIsDateTo;
rDateTimeFrom:=FDateTimeFrom;
rDateTimeTo:=FDateTimeTo;
{Time search}
rIsTimeFrom:=FIsTimeFrom;
rIsTimeTo:=FIsTimeTo;
(* File size search *)
rIsFileSizeFrom:=FIsFileSizeFrom;
rIsFileSizeTo:=FIsFileSizeTo;
rFileSizeFrom:=FFileSizeFrom;
rFileSizeTo:=FFileSizeTo;
(* Find text *)
rIsNoThisText:=FIsNoThisText;
rFindInFiles:=FFindInFiles;
rFindData:= StrNew(PChar(FFindData));
(* Replace text *)
rReplaceInFiles:=FReplaceInFiles;
rReplaceData:= StrNew(PChar(FReplaceData));
end;
// check regular expression
if RegExp and not ExecRegExpr(FilesMasks, sr.Name) then
Exit(False);
//DebugLn('File = ', sr.Name);
if (not RegExp) and (not MatchesMaskList(UTF8UpperCase(sr.Name), FilesMasks)) then
Exit(False);
if (IsDateFrom or IsDateTo or IsTimeFrom or IsTimeTo) then
Result := CheckFileTime(FFileChecks, sr.Time);
if (IsFileSizeFrom or IsFileSizeTo) and Result then
Result := CheckFileSize(FFileChecks, sr.Size);
if Result then
Result := CheckFileAttributes(FFileChecks, sr.Attr);
if (Result and IsFindText) then
begin
if FPS_ISDIR(sr.Attr) then
Exit(False);
try
Result := FindInFile(Folder + PathDelim + sr.Name, FindText, CaseSensitive);
if (Result and IsReplaceText) then
FileReplaceString(Folder + PathDelim + sr.Name, FindText, ReplaceText, CaseSensitive);
if NotContainingText then
Result := not Result;
except
on e : EFOpenError do
begin
if (log_errors in gLogOptions) then
logWrite(Self, rsMsgLogError + rsMsgErrEOpen + ' ' +
Folder + PathDelim + sr.Name, lmtError);
Result := False;
end;
end;
end;
end;
end;
procedure TFindThread.WalkAdr(const sNewDir:String);
@ -470,22 +329,17 @@ var
sr: TSearchRecEx;
Path : String;
begin
DebugLn(sNewDir);
if not mbSetCurrentDir(sNewDir) then Exit;
Inc(FCurrentDepth);
// if regular expression then search all files
if FRegExp or (Pos(';', FFileMask) <> 0) then
if FSearchTemplate.RegExp or (Pos(';', FSearchTemplate.FilesMasks) <> 0) then
Path := sNewDir + PathDelim + '*'
else
Path := sNewDir + PathDelim + FFileMask;
//DebugLn('Path = ', Path);
Path := sNewDir + PathDelim + FSearchTemplate.FilesMasks;
DebugLn('FAttributes == ' + IntToStr(FAttributes));
if FindFirstEx(Path, FAttributes, sr) = 0 then
if FindFirstEx(Path, faAnyFile, sr) = 0 then
repeat
if (sr.Name='.') or (sr.Name='..') then Continue;
@ -506,7 +360,7 @@ begin
Synchronize(@UpDateProgress);
{ Search in sub folders }
if (not Terminated) and (FCurrentDepth < FSearchDepth) then
if (not Terminated) and (FCurrentDepth < FSearchTemplate.SearchDepth) then
begin
Path := sNewDir + PathDelim + '*';
DebugLn('Search in sub folders = ', Path);

View file

@ -27,7 +27,7 @@ unit uSearchTemplate;
interface
uses
Classes, SysUtils, DsxPlugin, uClassesEx, uFile, uXmlConfig;
Classes, SysUtils, uClassesEx, uFile, uXmlConfig, uFindFiles;
type
@ -35,22 +35,14 @@ type
TSearchTemplate = class
private
FTemplateName,
FStartPath: UTF8String;
FIsNotOlderThan: Boolean;
FNotOlderThan: Double;
function CheckFileDate(DateTime: TDateTime): Boolean;
function CheckFileSize(FileSize: Int64): Boolean;
FTemplateName: UTF8String;
public
SearchRecord: TSearchAttrRecord;
SearchRecord: TSearchTemplateRec;
constructor Create;
destructor Destroy; override;
function CheckFile(const AFile: TFile): Boolean;
property TemplateName: UTF8String read FTemplateName write FTemplateName;
property StartPath: UTF8String read FStartPath write FStartPath;
property IsNotOlderThan: Boolean read FIsNotOlderThan write FIsNotOlderThan;
property NotOlderThan: Double read FNotOlderThan write FNotOlderThan;
end;
{ TSearchTemplateList }
@ -80,7 +72,7 @@ function IsMaskSearchTemplate(const sMask: UTF8String): Boolean; inline;
implementation
uses
DateUtils, Masks, uFileProperty;
Masks, uFileProperty;
function IsMaskSearchTemplate(const sMask: UTF8String): Boolean; inline;
begin
@ -89,93 +81,6 @@ end;
{ TSearchTemplate }
function TSearchTemplate.CheckFileDate(DateTime: TDateTime): Boolean;
var
dtNow: TDateTime;
iCount: Integer;
bIsDateFrom,
bIsTimeFrom: Boolean;
begin
Result:= True;
with SearchRecord do
begin
if FIsNotOlderThan then
begin
dtNow:= Now;
iCount:= -Trunc(FNotOlderThan);
case Round(Frac(FNotOlderThan)*10) of
0: //Minute(s)
begin
bIsDateFrom:= True;
bIsTimeFrom:= True;
rDateTimeFrom:= IncMinute(dtNow, iCount);
end;
1: //Hour(s)
begin
bIsDateFrom:= True;
bIsTimeFrom:= True;
rDateTimeFrom:= IncHour(dtNow, iCount);
end;
2: //Day(s)
begin
bIsDateFrom:= True;
rDateTimeFrom:= IncDay(dtNow, iCount);
end;
3: //Week(s)
begin
bIsDateFrom:= True;
rDateTimeFrom:= IncWeek(dtNow, iCount);
end;
4: //Month(s)
begin
bIsDateFrom:= True;
rDateTimeFrom:= IncMonth(dtNow, iCount);
end;
5: //Year(s)
begin
bIsDateFrom:= True;
rDateTimeFrom:= IncYear(dtNow, iCount);
end;
end;
end;
(* Check date from *)
if rIsDateFrom or bIsDateFrom then
Result:= (Int(DateTime) >= Int(rDateTimeFrom));
(* Check time to *)
if (rIsDateTo and Result) then
Result:= (Int(DateTime) <= Int(rDateTimeTo));
(* Check time from *)
if ((rIsTimeFrom or bIsTimeFrom) and Result) then
Result:= (CompareTime(DateTime, rDateTimeFrom) >= 0);
//DebugLn('Time From = ', FloatToStr(rDateTimeFrom), ' File time = ', FloatToStr(DateTime), ' Result = ', BoolToStr(Result));
(* Check time to *)
if (rIsTimeTo and Result) then
Result:= (CompareTime(DateTime, rDateTimeTo) <= 0);
//DebugLn('Time To = ', FloatToStr(rDateTimeTo), ' File time = ', FloatToStr(DateTime), ' Result = ', BoolToStr(Result));
end;
end;
function TSearchTemplate.CheckFileSize(FileSize: Int64): Boolean;
begin
Result:= True;
with SearchRecord do
begin
if rIsFileSizeFrom then
Result:= (FileSize >= rFileSizeFrom);
//DebugLn('After From', FileSize, '-', rFileSizeFrom, BoolToStr(Result));
if (rIsFileSizeTo and Result) then
Result:= (FileSize <= rFileSizeTo);
//DebugLn('After To', FileSize, '-', rFileSizeTo, BoolToStr(Result));
end;
end;
constructor TSearchTemplate.Create;
begin
inherited Create;
@ -184,31 +89,30 @@ end;
destructor TSearchTemplate.Destroy;
begin
with SearchRecord do
begin
StrDispose(rFileMask);
StrDispose(rAttribStr);
StrDispose(rFindData);
StrDispose(rReplaceData);
end;
inherited Destroy;
end;
function TSearchTemplate.CheckFile(const AFile: TFile): Boolean;
var
FileChecks: TFindFileChecks;
begin
Result:= True;
SearchTemplateToFindFileChecks(SearchRecord, FileChecks);
with SearchRecord do
begin
if (fpName in AFile.GetSupportedProperties) then
Result:= MatchesMaskList(AFile.Name, SearchRecord.rFileMask);
Result:= MatchesMaskList(AFile.Name, FilesMasks);
if (fpModificationTime in AFile.GetSupportedProperties) then
if (rIsDateFrom or rIsDateTo or rIsTimeFrom or rIsTimeTo or FIsNotOlderThan) then
Result:= CheckFileDate((AFile.Properties[fpModificationTime] as TFileDateTimeProperty).Value);
if Result and (fpModificationTime in AFile.GetSupportedProperties) then
if (IsDateFrom or IsDateTo or IsTimeFrom or IsTimeTo or IsNotOlderThan) then
Result:= CheckFileDateTime(FileChecks, (AFile.Properties[fpModificationTime] as TFileDateTimeProperty).Value);
if (fpSize in AFile.GetSupportedProperties) then
if (rIsFileSizeFrom or rIsFileSizeTo) and Result then
Result:= CheckFileSize((AFile.Properties[fpSize] as TFileSizeProperty).Value);
if Result and (fpSize in AFile.GetSupportedProperties) then
if (IsFileSizeFrom or IsFileSizeTo) then
Result:= CheckFileSize(FileChecks, (AFile.Properties[fpSize] as TFileSizeProperty).Value);
if Result and (fpAttributes in AFile.GetSupportedProperties) then
Result:= CheckFileAttributes(FileChecks, (AFile.Properties[fpAttributes] as TFileAttributesProperty).Value);
end;
end;
@ -276,6 +180,7 @@ var
I, iCount: Integer;
sTemplate: String;
SearchTemplate: TSearchTemplate;
FloatNotOlderThan: Double;
begin
Clear;
@ -287,50 +192,53 @@ begin
begin
sTemplate:= 'Template' + IntToStr(I+1);
SearchTemplate.TemplateName:= IniFile.ReadString(cSection, sTemplate+'Name', '');
SearchTemplate.StartPath:= IniFile.ReadString(cSection, sTemplate+'StartPath', '');
rFileMask:= StrNew(PChar(IniFile.ReadString(cSection, sTemplate+'FileMask', '*')));
rAttributes:= IniFile.ReadInteger(cSection, sTemplate+'Attributes', faAnyFile);
rAttribStr:= StrNew(PChar(IniFile.ReadString(cSection, sTemplate+'AttribStr', '*')));
StartPath:= IniFile.ReadString(cSection, sTemplate+'StartPath', '');
FilesMasks:= IniFile.ReadString(cSection, sTemplate+'FileMask', '*');
//Attributes:= IniFile.ReadInteger(cSection, sTemplate+'Attributes', faAnyFile);
//AttributesPattern:= IniFile.ReadString(cSection, sTemplate+'AttribStr', '');
// date/time
rCaseSens:= IniFile.ReadBool(cSection, sTemplate+'CaseSens', False);
rIsDateFrom:= IniFile.ReadBool(cSection, sTemplate+'IsDateFrom', False);
rIsDateTo:= IniFile.ReadBool(cSection, sTemplate+'IsDateTo', False);
rIsTimeFrom:= IniFile.ReadBool(cSection, sTemplate+'IsTimeFrom', False);
rIsTimeTo:= IniFile.ReadBool(cSection, sTemplate+'IsTimeTo', False);
if rIsDateFrom or rIsTimeFrom then
rDateTimeFrom:= IniFile.ReadDateTime(cSection, sTemplate+'DateTimeFrom', 0);
if rIsDateTo or rIsTimeTo then
rDateTimeTo:= IniFile.ReadDateTime(cSection, sTemplate+'DateTimeTo', Now);
CaseSensitive:= IniFile.ReadBool(cSection, sTemplate+'CaseSens', False);
IsDateFrom:= IniFile.ReadBool(cSection, sTemplate+'IsDateFrom', False);
IsDateTo:= IniFile.ReadBool(cSection, sTemplate+'IsDateTo', False);
IsTimeFrom:= IniFile.ReadBool(cSection, sTemplate+'IsTimeFrom', False);
IsTimeTo:= IniFile.ReadBool(cSection, sTemplate+'IsTimeTo', False);
if IsDateFrom or IsTimeFrom then
DateTimeFrom:= IniFile.ReadDateTime(cSection, sTemplate+'DateTimeFrom', 0);
if IsDateTo or IsTimeTo then
DateTimeTo:= IniFile.ReadDateTime(cSection, sTemplate+'DateTimeTo', Now);
// not older than
SearchTemplate.IsNotOlderThan:= IniFile.ReadBool(cSection, sTemplate+'IsNotOlderThan', False);
if SearchTemplate.IsNotOlderThan then
SearchTemplate.NotOlderThan:= IniFile.ReadFloat(cSection, sTemplate+'NotOlderThan', 0);
IsNotOlderThan:= IniFile.ReadBool(cSection, sTemplate+'IsNotOlderThan', False);
if IsNotOlderThan then
begin
FloatNotOlderThan:= IniFile.ReadFloat(cSection, sTemplate+'NotOlderThan', 0);
NotOlderThan:= Trunc(FloatNotOlderThan);
NotOlderThanUnit:= TTimeUnit(Round(Frac(FloatNotOlderThan)*10) + 1);
end;
// file size
rIsFileSizeFrom:= IniFile.ReadBool(cSection, sTemplate+'IsFileSizeFrom', False);
rIsFileSizeTo:= IniFile.ReadBool(cSection, sTemplate+'IsFileSizeTo', False);
if rIsFileSizeFrom then
rFileSizeFrom:= IniFile.ReadInteger(cSection, sTemplate+'FileSizeFrom', 0);
if rIsFileSizeTo then
rFileSizeTo:= IniFile.ReadInteger(cSection, sTemplate+'FileSizeTo', MaxInt);
IsFileSizeFrom:= IniFile.ReadBool(cSection, sTemplate+'IsFileSizeFrom', False);
IsFileSizeTo:= IniFile.ReadBool(cSection, sTemplate+'IsFileSizeTo', False);
if IsFileSizeFrom then
FileSizeFrom:= IniFile.ReadInteger(cSection, sTemplate+'FileSizeFrom', 0);
if IsFileSizeTo then
FileSizeTo:= IniFile.ReadInteger(cSection, sTemplate+'FileSizeTo', MaxInt);
// find text
rIsNoThisText:= IniFile.ReadBool(cSection, sTemplate+'IsNoThisText', False);
rFindInFiles:= IniFile.ReadBool(cSection, sTemplate+'FindInFiles', False);
if rFindInFiles then
rFindData:= StrNew(PChar(IniFile.ReadString(cSection, sTemplate+'FindData', '')));
NotContainingText:= IniFile.ReadBool(cSection, sTemplate+'IsNoThisText', False);
IsFindText:= IniFile.ReadBool(cSection, sTemplate+'FindInFiles', False);
if IsFindText then
FindText:= IniFile.ReadString(cSection, sTemplate+'FindData', '');
// replace text
rReplaceInFiles:= IniFile.ReadBool(cSection, sTemplate+'ReplaceInFiles', False);
if rReplaceInFiles then
rReplaceData:= StrNew(PChar(IniFile.ReadString(cSection, sTemplate+'ReplaceData', '')));
IsReplaceText:= IniFile.ReadBool(cSection, sTemplate+'ReplaceInFiles', False);
if IsReplaceText then
ReplaceText:= IniFile.ReadString(cSection, sTemplate+'ReplaceData', '');
end;
Add(SearchTemplate)
Add(SearchTemplate);
end;
end;
procedure TSearchTemplateList.LoadFromXml(AConfig: TXmlConfig; ANode: TXmlNode);
var
I: Integer;
sTemplate: String;
SearchTemplate: TSearchTemplate;
FloatNotOlderThan: Double;
begin
Clear;
@ -346,42 +254,51 @@ begin
with SearchTemplate.SearchRecord do
begin
SearchTemplate.TemplateName:= AConfig.GetValue(ANode, 'Name', '');
SearchTemplate.StartPath:= AConfig.GetValue(ANode, 'StartPath', '');
rFileMask:= StrNew(PChar(AConfig.GetValue(ANode, 'FileMask', '*')));
rAttributes:= AConfig.GetValue(ANode, 'Attributes', faAnyFile);
rAttribStr:= StrNew(PChar(AConfig.GetValue(ANode, 'AttribStr', '*')));
StartPath:= AConfig.GetValue(ANode, 'StartPath', '');
FilesMasks:= AConfig.GetValue(ANode, 'FilesMasks', '*');
SearchDepth:= AConfig.GetValue(ANode, 'SearchDepth', -1);
RegExp:= AConfig.GetValue(ANode, 'RegExp', False);
AttributesPattern:= AConfig.GetValue(ANode, 'AttributesPattern', '');
// date/time
rCaseSens:= AConfig.GetValue(ANode, 'CaseSens', False);
rIsDateFrom:= AConfig.GetValue(ANode, 'IsDateFrom', False);
rIsDateTo:= AConfig.GetValue(ANode, 'IsDateTo', False);
rIsTimeFrom:= AConfig.GetValue(ANode, 'IsTimeFrom', False);
rIsTimeTo:= AConfig.GetValue(ANode, 'IsTimeTo', False);
if rIsDateFrom or rIsTimeFrom then
rDateTimeFrom:= AConfig.GetValue(ANode, 'DateTimeFrom', 0);
if rIsDateTo or rIsTimeTo then
rDateTimeTo:= AConfig.GetValue(ANode, 'DateTimeTo', Now);
IsDateFrom:= AConfig.GetValue(ANode, 'IsDateFrom', False);
IsDateTo:= AConfig.GetValue(ANode, 'IsDateTo', False);
IsTimeFrom:= AConfig.GetValue(ANode, 'IsTimeFrom', False);
IsTimeTo:= AConfig.GetValue(ANode, 'IsTimeTo', False);
if IsDateFrom or IsTimeFrom then
DateTimeFrom:= AConfig.GetValue(ANode, 'DateTimeFrom', TDateTime(0));
if IsDateTo or IsTimeTo then
DateTimeTo:= AConfig.GetValue(ANode, 'DateTimeTo', Now);
// not older than
SearchTemplate.IsNotOlderThan:= AConfig.GetValue(ANode, 'IsNotOlderThan', False);
if SearchTemplate.IsNotOlderThan then
SearchTemplate.NotOlderThan:= AConfig.GetValue(ANode, 'NotOlderThan', 0);
IsNotOlderThan:= AConfig.GetValue(ANode, 'IsNotOlderThan', False);
if IsNotOlderThan then
begin
// Workaround because old value was floating point.
FloatNotOlderThan:= AConfig.GetValue(ANode, 'NotOlderThan', Double(0));
NotOlderThan:= Trunc(FloatNotOlderThan);
NotOlderThanUnit:= TTimeUnit(AConfig.GetValue(ANode, 'NotOlderThanUnit', 0));
end;
// file size
rIsFileSizeFrom:= AConfig.GetValue(ANode, 'IsFileSizeFrom', False);
rIsFileSizeTo:= AConfig.GetValue(ANode, 'IsFileSizeTo', False);
if rIsFileSizeFrom then
rFileSizeFrom:= AConfig.GetValue(ANode, 'FileSizeFrom', 0);
if rIsFileSizeTo then
rFileSizeTo:= AConfig.GetValue(ANode, 'FileSizeTo', MaxInt);
IsFileSizeFrom:= AConfig.GetValue(ANode, 'IsFileSizeFrom', False);
IsFileSizeTo:= AConfig.GetValue(ANode, 'IsFileSizeTo', False);
if IsFileSizeFrom then
FileSizeFrom:= AConfig.GetValue(ANode, 'FileSizeFrom', Int64(0));
if IsFileSizeTo then
FileSizeTo:= AConfig.GetValue(ANode, 'FileSizeTo', High(Int64));
FileSizeUnit:= TFileSizeUnit(AConfig.GetValue(ANode, 'FileSizeUnit', 0));
// find text
rIsNoThisText:= AConfig.GetValue(ANode, 'IsNoThisText', False);
rFindInFiles:= AConfig.GetValue(ANode, 'FindInFiles', False);
if rFindInFiles then
rFindData:= StrNew(PChar(AConfig.GetValue(ANode, 'FindData', '')));
IsFindText:= AConfig.GetValue(ANode, 'IsFindText', False);
if IsFindText then
FindText:= AConfig.GetValue(ANode, 'FindText', '');
// replace text
rReplaceInFiles:= AConfig.GetValue(ANode, 'ReplaceInFiles', False);
if rReplaceInFiles then
rReplaceData:= StrNew(PChar(AConfig.GetValue(ANode, 'ReplaceData', '')));
IsReplaceText:= AConfig.GetValue(ANode, 'IsReplaceText', False);
if IsReplaceText then
ReplaceText:= AConfig.GetValue(ANode, 'ReplaceText', '');
CaseSensitive:= AConfig.GetValue(ANode, 'CaseSensitive', False);
NotContainingText:= AConfig.GetValue(ANode, 'NotContainingText', False);
TextEncoding:= AConfig.GetValue(ANode, 'TextEncoding', '');
SearchPlugin:= AConfig.GetValue(ANode, 'SearchPlugin', '');
end;
Add(SearchTemplate)
Add(SearchTemplate);
end;
ANode := ANode.NextSibling;
end;
@ -392,6 +309,7 @@ procedure TSearchTemplateList.SaveToIni(IniFile: TIniFileEx);
var
I: Integer;
sTemplate: String;
FloatNotOlderThan: Double;
begin
IniFile.EraseSection(cSection);
IniFile.WriteInteger(cSection, 'TemplateCount', Count);
@ -400,47 +318,49 @@ begin
begin
sTemplate:= 'Template' + IntToStr(I+1);
IniFile.WriteString(cSection, sTemplate+'Name', Templates[I].TemplateName);
IniFile.WriteString(cSection, sTemplate+'StartPath', Templates[I].StartPath);
IniFile.WriteString(cSection, sTemplate+'FileMask', StrPas(rFileMask));
IniFile.WriteInteger(cSection, sTemplate+'Attributes', rAttributes);
IniFile.WriteString(cSection, sTemplate+'AttribStr', StrPas(rAttribStr));
IniFile.WriteString(cSection, sTemplate+'StartPath', StartPath);
IniFile.WriteString(cSection, sTemplate+'FileMask', FilesMasks);
//IniFile.WriteInteger(cSection, sTemplate+'Attributes', Attributes);
//IniFile.WriteString(cSection, sTemplate+'AttribStr', AttributesPattern);
// date/time
IniFile.WriteBool(cSection, sTemplate+'CaseSens', rCaseSens);
IniFile.WriteBool(cSection, sTemplate+'IsDateFrom', rIsDateFrom);
IniFile.WriteBool(cSection, sTemplate+'IsDateTo', rIsDateTo);
IniFile.WriteBool(cSection, sTemplate+'IsTimeFrom', rIsTimeFrom);
IniFile.WriteBool(cSection, sTemplate+'IsTimeTo', rIsTimeTo);
if rIsDateFrom or rIsTimeFrom then
IniFile.WriteDateTime(cSection, sTemplate+'DateTimeFrom', rDateTimeFrom);
if rIsDateTo or rIsTimeTo then
IniFile.WriteDateTime(cSection, sTemplate+'DateTimeTo', rDateTimeTo);
IniFile.WriteBool(cSection, sTemplate+'CaseSens', CaseSensitive);
IniFile.WriteBool(cSection, sTemplate+'IsDateFrom', IsDateFrom);
IniFile.WriteBool(cSection, sTemplate+'IsDateTo', IsDateTo);
IniFile.WriteBool(cSection, sTemplate+'IsTimeFrom', IsTimeFrom);
IniFile.WriteBool(cSection, sTemplate+'IsTimeTo', IsTimeTo);
if IsDateFrom or IsTimeFrom then
IniFile.WriteDateTime(cSection, sTemplate+'DateTimeFrom', DateTimeFrom);
if IsDateTo or IsTimeTo then
IniFile.WriteDateTime(cSection, sTemplate+'DateTimeTo', DateTimeTo);
// not older than
IniFile.WriteBool(cSection, sTemplate+'IsNotOlderThan', Templates[I].IsNotOlderThan);
if Templates[I].IsNotOlderThan then
IniFile.WriteFloat(cSection, sTemplate+'NotOlderThan', Templates[I].NotOlderThan);
IniFile.WriteBool(cSection, sTemplate+'IsNotOlderThan', IsNotOlderThan);
if IsNotOlderThan then
begin
FloatNotOlderThan := Double(NotOlderThan) + Double(Integer(NotOlderThanUnit) - 1) / 10;
IniFile.WriteFloat(cSection, sTemplate+'NotOlderThan', FloatNotOlderThan);
end;
// file size
IniFile.WriteBool(cSection, sTemplate+'IsFileSizeFrom', rIsFileSizeFrom);
IniFile.WriteBool(cSection, sTemplate+'IsFileSizeTo', rIsFileSizeTo);
if rIsFileSizeFrom then
IniFile.WriteInteger(cSection, sTemplate+'FileSizeFrom', rFileSizeFrom);
if rIsFileSizeTo then
IniFile.WriteInteger(cSection, sTemplate+'FileSizeTo', rFileSizeTo);
IniFile.WriteBool(cSection, sTemplate+'IsFileSizeFrom', IsFileSizeFrom);
IniFile.WriteBool(cSection, sTemplate+'IsFileSizeTo', IsFileSizeTo);
if IsFileSizeFrom then
IniFile.WriteInteger(cSection, sTemplate+'FileSizeFrom', FileSizeFrom);
if IsFileSizeTo then
IniFile.WriteInteger(cSection, sTemplate+'FileSizeTo', FileSizeTo);
// find text
IniFile.WriteBool(cSection, sTemplate+'IsNoThisText', rIsNoThisText);
IniFile.WriteBool(cSection, sTemplate+'FindInFiles', rFindInFiles);
if rFindInFiles then
IniFile.WriteString(cSection, sTemplate+'FindData', StrPas(rFindData));
IniFile.WriteBool(cSection, sTemplate+'IsNoThisText', NotContainingText);
IniFile.WriteBool(cSection, sTemplate+'FindInFiles', IsFindText);
if IsFindText then
IniFile.WriteString(cSection, sTemplate+'FindData', FindText);
// replace text
IniFile.WriteBool(cSection, sTemplate+'ReplaceInFiles', rReplaceInFiles);
if rReplaceInFiles then
IniFile.WriteString(cSection, sTemplate+'ReplaceData', StrPas(rReplaceData));
IniFile.WriteBool(cSection, sTemplate+'ReplaceInFiles', IsReplaceText);
if IsReplaceText then
IniFile.WriteString(cSection, sTemplate+'ReplaceData', ReplaceText);
end;
end;
procedure TSearchTemplateList.SaveToXml(AConfig: TXmlConfig; ANode: TXmlNode);
var
I: Integer;
sTemplate: String;
SubNode: TXmlNode;
begin
ANode := AConfig.FindNode(ANode, cSection, True);
@ -450,40 +370,47 @@ begin
begin
SubNode := AConfig.AddNode(ANode, 'Template');
AConfig.AddValue(SubNode, 'Name', Templates[I].TemplateName);
AConfig.AddValue(SubNode, 'StartPath', Templates[I].StartPath);
AConfig.AddValue(SubNode, 'FileMask', StrPas(rFileMask));
AConfig.AddValue(SubNode, 'Attributes', rAttributes);
AConfig.AddValue(SubNode, 'AttribStr', StrPas(rAttribStr));
AConfig.AddValue(SubNode, 'StartPath', StartPath);
AConfig.AddValue(SubNode, 'FilesMasks', FilesMasks);
AConfig.AddValue(SubNode, 'SearchDepth', SearchDepth);
AConfig.AddValue(SubNode, 'RegExp', RegExp);
AConfig.AddValue(SubNode, 'AttributesPattern', AttributesPattern);
// date/time
AConfig.AddValue(SubNode, 'CaseSens', rCaseSens);
AConfig.AddValue(SubNode, 'IsDateFrom', rIsDateFrom);
AConfig.AddValue(SubNode, 'IsDateTo', rIsDateTo);
AConfig.AddValue(SubNode, 'IsTimeFrom', rIsTimeFrom);
AConfig.AddValue(SubNode, 'IsTimeTo', rIsTimeTo);
if rIsDateFrom or rIsTimeFrom then
AConfig.AddValue(SubNode, 'DateTimeFrom', rDateTimeFrom);
if rIsDateTo or rIsTimeTo then
AConfig.AddValue(SubNode, 'DateTimeTo', rDateTimeTo);
AConfig.AddValue(SubNode, 'IsDateFrom', IsDateFrom);
AConfig.AddValue(SubNode, 'IsDateTo', IsDateTo);
AConfig.AddValue(SubNode, 'IsTimeFrom', IsTimeFrom);
AConfig.AddValue(SubNode, 'IsTimeTo', IsTimeTo);
if IsDateFrom or IsTimeFrom then
AConfig.AddValue(SubNode, 'DateTimeFrom', DateTimeFrom);
if IsDateTo or IsTimeTo then
AConfig.AddValue(SubNode, 'DateTimeTo', DateTimeTo);
// not older than
AConfig.AddValue(SubNode, 'IsNotOlderThan', Templates[I].IsNotOlderThan);
if Templates[I].IsNotOlderThan then
AConfig.AddValue(SubNode, 'NotOlderThan', Templates[I].NotOlderThan);
AConfig.AddValue(SubNode, 'IsNotOlderThan', IsNotOlderThan);
if IsNotOlderThan then
begin
AConfig.AddValue(SubNode, 'NotOlderThan', NotOlderThan);
AConfig.AddValue(SubNode, 'NotOlderThanUnit', Integer(NotOlderThanUnit));
end;
// file size
AConfig.AddValue(SubNode, 'IsFileSizeFrom', rIsFileSizeFrom);
AConfig.AddValue(SubNode, 'IsFileSizeTo', rIsFileSizeTo);
if rIsFileSizeFrom then
AConfig.AddValue(SubNode, 'FileSizeFrom', rFileSizeFrom);
if rIsFileSizeTo then
AConfig.AddValue(SubNode, 'FileSizeTo', rFileSizeTo);
AConfig.AddValue(SubNode, 'IsFileSizeFrom', IsFileSizeFrom);
AConfig.AddValue(SubNode, 'IsFileSizeTo', IsFileSizeTo);
if IsFileSizeFrom then
AConfig.AddValue(SubNode, 'FileSizeFrom', FileSizeFrom);
if IsFileSizeTo then
AConfig.AddValue(SubNode, 'FileSizeTo', FileSizeTo);
AConfig.AddValue(SubNode, 'FileSizeUnit', Integer(FileSizeUnit));
// find text
AConfig.AddValue(SubNode, 'IsNoThisText', rIsNoThisText);
AConfig.AddValue(SubNode, 'FindInFiles', rFindInFiles);
if rFindInFiles then
AConfig.AddValue(SubNode, 'FindData', StrPas(rFindData));
AConfig.AddValue(SubNode, 'IsFindText', IsFindText);
if IsFindText then
AConfig.AddValue(SubNode, 'FindText', FindText);
// replace text
AConfig.AddValue(SubNode, 'ReplaceInFiles', rReplaceInFiles);
if rReplaceInFiles then
AConfig.AddValue(SubNode, 'ReplaceData', StrPas(rReplaceData));
AConfig.AddValue(SubNode, 'IsReplaceText', IsReplaceText);
if IsReplaceText then
AConfig.AddValue(SubNode, 'ReplaceText', ReplaceText);
AConfig.AddValue(SubNode, 'CaseSensitive', CaseSensitive);
AConfig.AddValue(SubNode, 'NotContainingText', NotContainingText);
AConfig.AddValue(SubNode, 'TextEncoding', TextEncoding);
AConfig.AddValue(SubNode, 'SearchPlugin', SearchPlugin);
end;
end;