ADD: Search plugins Api + DSXLocate - search plugin which uses locate for search

This commit is contained in:
b4rr4cuda 2008-04-28 17:22:10 +00:00
commit fa3f616337
11 changed files with 1111 additions and 85 deletions

View file

@ -1,43 +1,45 @@
object frmFindDlg: TfrmFindDlg
Left = 272
Height = 599
Top = 105
Width = 645
HorzScrollBar.Page = 644
VertScrollBar.Page = 598
Left = 306
Height = 704
Top = 112
Width = 970
HorzScrollBar.Page = 969
VertScrollBar.Page = 703
VertScrollBar.Range = 316
ActiveControl = pgcSearch
Caption = 'Find files'
ClientHeight = 599
ClientWidth = 645
ClientHeight = 704
ClientWidth = 970
KeyPreview = True
OnClose = frmFindDlgClose
OnCloseQuery = FormCloseQuery
OnCreate = FormCreate
OnDestroy = FormDestroy
OnKeyPress = FormKeyPress
OnShow = frmFindDlgShow
Position = poScreenCenter
ShowInTaskBar = stAlways
LCLVersion = '0.9.25'
object Splitter1: TSplitter
Cursor = crVSplit
Height = 1
Top = 320
Width = 645
Top = 345
Width = 970
Align = alTop
ResizeAnchor = akTop
end
object Panel2: TPanel
Height = 320
Width = 645
Height = 345
Width = 970
Align = alTop
BevelOuter = bvNone
ClientHeight = 320
ClientWidth = 645
ClientHeight = 345
ClientWidth = 970
FullRepaint = False
TabOrder = 0
object pgcSearch: TPageControl
Height = 324
Width = 544
Height = 339
Width = 869
ActivePage = tsStandard
Anchors = [akTop, akLeft, akRight]
TabIndex = 0
@ -46,24 +48,24 @@ object frmFindDlg: TfrmFindDlg
Caption = 'Standard'
ChildSizing.LeftRightSpacing = 6
ChildSizing.TopBottomSpacing = 6
ClientHeight = 292
ClientWidth = 540
ClientHeight = 309
ClientWidth = 865
object lblFindPathStart: TLabel
AnchorSideTop.Control = cmbFindFileMask
AnchorSideTop.Side = asrBottom
Left = 8
Height = 19
Height = 13
Top = 61
Width = 44
Width = 57
BorderSpacing.Top = 6
Caption = 'FileDir'
ParentColor = False
end
object lblFindFileMask: TLabel
Left = 8
Height = 19
Height = 13
Top = 4
Width = 61
Width = 65
Caption = 'FileMask'
ParentColor = False
end
@ -73,7 +75,7 @@ object frmFindDlg: TfrmFindDlg
Left = 8
Height = 30
Top = 25
Width = 526
Width = 851
Anchors = [akTop, akLeft, akRight]
AutoCompleteText = [cbactEndOfLineComplete, cbactSearchAscending]
MaxLength = 0
@ -87,14 +89,14 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Control = tsStandard
AnchorSideRight.Side = asrBottom
Left = 8
Height = 145
Top = 141
Width = 526
Height = 131
Top = 133
Width = 851
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
Caption = 'Find Data'
ClientHeight = 125
ClientWidth = 522
ClientHeight = 114
ClientWidth = 847
Enabled = False
ParentCtl3D = False
TabOrder = 1
@ -103,9 +105,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideTop.Control = edtReplaceText
AnchorSideTop.Side = asrBottom
Left = 6
Height = 22
Top = 96
Width = 121
Height = 20
Top = 94
Width = 136
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Caption = 'Case sensitive'
@ -118,7 +120,7 @@ object frmFindDlg: TfrmFindDlg
Left = 6
Height = 24
Top = 9
Width = 510
Width = 835
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Right = 6
@ -127,10 +129,10 @@ object frmFindDlg: TfrmFindDlg
object cbNoThisText: TCheckBox
AnchorSideLeft.Control = cbCaseSens
AnchorSideLeft.Side = asrBottom
Left = 139
Height = 22
Left = 154
Height = 20
Top = 97
Width = 244
Width = 296
BorderSpacing.Left = 12
Caption = 'Find files NOT containing the text'
TabOrder = 2
@ -140,9 +142,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideTop.Control = edtFindText
AnchorSideTop.Side = asrBottom
Left = 6
Height = 22
Height = 20
Top = 39
Width = 106
Width = 120
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Caption = 'Replace text'
@ -157,8 +159,8 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
Left = 6
Height = 23
Top = 67
Width = 510
Top = 65
Width = 835
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Top = 6
@ -171,9 +173,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideTop.Control = edtFindPathStart
AnchorSideTop.Side = asrBottom
Left = 12
Height = 22
Top = 113
Width = 91
Height = 20
Top = 107
Width = 120
BorderSpacing.Top = 6
Caption = 'Find in file'
OnClick = cbFindInFileClick
@ -186,8 +188,8 @@ object frmFindDlg: TfrmFindDlg
AnchorSideRight.Side = asrBottom
Left = 8
Height = 21
Top = 86
Width = 504
Top = 80
Width = 829
ButtonWidth = 23
NumGlyphs = 1
Anchors = [akTop, akLeft, akRight]
@ -196,11 +198,30 @@ object frmFindDlg: TfrmFindDlg
ParentColor = False
TabOrder = 3
end
object cbUsePlugin: TCheckBox
Left = 10
Height = 20
Top = 281
Width = 96
Caption = 'UsePlugin'
OnChange = cbUsePluginChange
TabOrder = 4
end
object cbbSPlugins: TComboBox
Left = 170
Height = 25
Top = 276
Width = 691
AutoCompleteText = [cbactEndOfLineComplete, cbactSearchAscending]
Enabled = False
MaxLength = 65535
TabOrder = 5
end
end
object tsAdvanced: TTabSheet
Caption = 'Advanced'
ClientHeight = 292
ClientWidth = 540
ClientHeight = 324
ClientWidth = 544
ImageIndex = 1
object deDateFrom: TDateEdit
AnchorSideLeft.Control = tsAdvanced
@ -504,12 +525,12 @@ object frmFindDlg: TfrmFindDlg
Left = 284
Height = 165
Top = 46
Width = 250
Width = 254
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
BorderSpacing.Right = 6
ClientHeight = 145
ClientWidth = 246
ClientHeight = 161
ClientWidth = 250
Enabled = False
TabOrder = 16
object lblInfo: TLabel
@ -576,7 +597,7 @@ object frmFindDlg: TfrmFindDlg
object btnClose: TButton
AnchorSideTop.Control = btnStart
AnchorSideTop.Side = asrBottom
Left = 558
Left = 883
Height = 32
Top = 77
Width = 75
@ -590,7 +611,7 @@ object frmFindDlg: TfrmFindDlg
object btnStop: TButton
AnchorSideTop.Control = btnClose
AnchorSideTop.Side = asrBottom
Left = 558
Left = 883
Height = 32
Top = 115
Width = 75
@ -604,7 +625,7 @@ object frmFindDlg: TfrmFindDlg
TabOrder = 1
end
object btnStart: TButton
Left = 558
Left = 883
Height = 32
Top = 39
Width = 75
@ -617,23 +638,23 @@ object frmFindDlg: TfrmFindDlg
end
end
object Panel1: TPanel
Height = 278
Top = 321
Width = 645
Height = 358
Top = 346
Width = 970
Align = alClient
BevelOuter = bvNone
ClientHeight = 278
ClientWidth = 645
ClientHeight = 358
ClientWidth = 970
FullRepaint = False
TabOrder = 1
object Panel3: TPanel
Height = 58
Width = 645
Width = 970
Align = alTop
BevelInner = bvRaised
BevelOuter = bvLowered
ClientHeight = 58
ClientWidth = 645
ClientWidth = 970
FullRepaint = False
TabOrder = 0
object lblStatus: TLabel
@ -641,9 +662,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideTop.Control = lblCurrent
AnchorSideTop.Side = asrBottom
Left = 10
Height = 19
Top = 31
Width = 43
Height = 13
Top = 25
Width = 49
BorderSpacing.Left = 10
BorderSpacing.Top = 6
Caption = 'Status'
@ -656,9 +677,9 @@ object frmFindDlg: TfrmFindDlg
AnchorSideLeft.Control = Panel3
AnchorSideTop.Control = Panel3
Left = 10
Height = 19
Height = 13
Top = 6
Width = 50
Width = 57
BorderSpacing.Left = 10
BorderSpacing.Top = 6
Caption = 'Current'
@ -669,9 +690,9 @@ object frmFindDlg: TfrmFindDlg
end
end
object lsFoundedFiles: TListBox
Height = 162
Height = 242
Top = 58
Width = 645
Width = 970
Align = alClient
MultiSelect = True
OnDblClick = lsFoundedFilesDblClick
@ -681,11 +702,11 @@ object frmFindDlg: TfrmFindDlg
end
object Panel4: TPanel
Height = 58
Top = 220
Width = 645
Top = 300
Width = 970
Align = alBottom
ClientHeight = 58
ClientWidth = 645
ClientWidth = 970
TabOrder = 2
object btnView: TButton
AnchorSideLeft.Control = Panel4
@ -719,7 +740,7 @@ object frmFindDlg: TfrmFindDlg
object btnGoToPath: TButton
AnchorSideTop.Control = Panel4
AnchorSideRight.Control = btnWorkWithFound
Left = 367
Left = 692
Height = 32
Top = 12
Width = 130
@ -735,7 +756,7 @@ object frmFindDlg: TfrmFindDlg
AnchorSideTop.Control = Panel4
AnchorSideRight.Control = Panel4
AnchorSideRight.Side = asrBottom
Left = 503
Left = 828
Height = 32
Top = 12
Width = 130

View file

@ -8,6 +8,7 @@ TFRMFINDDLG.CBCASESENS.CAPTION=Case sensitive
TFRMFINDDLG.CBNOTHISTEXT.CAPTION=Find files NOT containing the text
TFRMFINDDLG.CBREPLACETEXT.CAPTION=Replace text
TFRMFINDDLG.CBFINDINFILE.CAPTION=Find in file
TFRMFINDDLG.CBUSEPLUGIN.CAPTION=UsePlugin
TFRMFINDDLG.TSADVANCED.CAPTION=Advanced
TFRMFINDDLG.DEDATEFROM.OKCAPTION=OK
TFRMFINDDLG.DEDATEFROM.CANCELCAPTION=Cancel

View file

@ -32,7 +32,7 @@ uses
LResources,
SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, Buttons, uFindThread, Menus,
Calendar, EditBtn, Spin, MaskEdit;
Calendar, EditBtn, Spin, MaskEdit,udsxmodule,udsxplugin;
type
@ -62,6 +62,8 @@ type
cbSymLink: TCheckBox;
cbMore: TCheckBox;
cbAttrib: TCheckBox;
cbUsePlugin: TCheckBox;
cbbSPlugins: TComboBox;
deDateFrom: TDateEdit;
deDateTo: TDateEdit;
edtFindPathStart: TDirectoryEdit;
@ -93,6 +95,7 @@ type
lblCurrent: TLabel;
PopupMenuFind: TPopupMenu;
miShowInViewer: TMenuItem;
procedure cbUsePluginChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnGoToPathClick(Sender: TObject);
procedure btnNewSearchClick(Sender: TObject);
@ -116,6 +119,7 @@ type
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure btnCloseClick(Sender: TObject);
procedure cbFindInFileClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure frmFindDlgClose(Sender: TObject; var CloseAction: TCloseAction);
procedure frmFindDlgShow(Sender: TObject);
procedure lsFoundedFilesDblClick(Sender: TObject);
@ -127,6 +131,7 @@ type
FFindThread:TFindThread;
public
{ Public declarations }
DSL:TDSXModuleList;
procedure ThreadTerminate(Sender:TObject);
end;
@ -139,7 +144,31 @@ implementation
uses
LCLProc, fViewer, uLng, uGlobs, uShowForm, fMain, uTypes, uFileOp, uFindEx, uOSUtils;
procedure SAddFileProc(PlugNr:integer; FoundFile:pchar); stdcall;
var s:string;
begin
s:=string(FoundFile);
if s='' then
begin
frmFindDlg.ThreadTerminate(nil);
end
else
begin
frmFindDlg.lsFoundedFiles.Items.Add(s);
DebugLn('fFindLlg: '+S);
Application.ProcessMessages;
end;
end;
procedure SUpdateStatusProc(PlugNr:integer; CurrentFile:pchar; FilesScaned:integer); stdcall;
begin
frmFindDlg.lblStatus.Caption:=Format(rsFindScaned,[FilesScaned]);
frmFindDlg.lblCurrent.Caption:=string(CurrentFile);
Application.ProcessMessages;
end;
procedure ShowFindDlg(const sActPath:String);
begin
if not assigned (frmFindDlg) then
@ -162,6 +191,13 @@ begin
Panel1.Visible := False;
Splitter1.Visible := False;
Height := Panel2.Height + 22;
DSL:=TDSXModuleList.Create;
DSL.Load(gini);
end;
procedure TfrmFindDlg.cbUsePluginChange(Sender: TObject);
begin
cbbSPlugins.Enabled:=cbUsePlugin.Checked;
end;
@ -177,6 +213,7 @@ end;
procedure TfrmFindDlg.btnNewSearchClick(Sender: TObject);
begin
btnStopClick(Sender);
Panel1.Visible := False;
Splitter1.Visible := False;
Height := Panel2.Height + 22;
@ -193,6 +230,7 @@ end;
procedure TfrmFindDlg.btnStartClick(Sender: TObject);
var
dtTime : TDateTime;
sr:TSearchAttrRecord;
begin
if cmbFindFileMask.Items.IndexOf(cmbFindFileMask.Text) < 0 then
cmbFindFileMask.Items.Add(cmbFindFileMask.Text);
@ -341,19 +379,39 @@ begin
end;
Status:=lblStatus;
Current:=lblCurrent;
DebugLn('thread a');
{$IFDEF NOFAKETHREAD}
FreeOnTerminate:=False;
OnTerminate:=@ThreadTerminate; // napojime udalost na obsluhu tlacitka
DebugLn('thread a1');
Resume;
end;
//---------------------
if (cbUsePlugin.Checked) and (cbbSPlugins.ItemIndex<>-1) then
begin
FillSearchRecord(sr);
DSL:=TDSXModuleList.Create;
DSL.Load(gini);
DSL.LoadModule(cbbSPlugins.ItemIndex);
FillSearchRecord(sr);
DSL.GetDSXModule(cbbSPlugins.ItemIndex).CallInit(@SAddFileProc,@SUpdateStatusProc);
DSL.GetDSXModule(cbbSPlugins.ItemIndex).CallStartSearch(PChar(edtFindPathStart.Text),sr);
end
//end
else
begin
DebugLn('thread a');
{$IFDEF NOFAKETHREAD}
FreeOnTerminate:=False;
OnTerminate:=@ThreadTerminate; // napojime udalost na obsluhu tlacitka
DebugLn('thread a1');
Resume;
{$ELSE}
Resume;
//WaitFor; //remove
end;
//ThreadTerminate(self); //remove if thread is Ok
{$ENDIF}
end;
end;
DebugLn('thread a2');
end;
@ -489,6 +547,13 @@ end;
procedure TfrmFindDlg.btnStopClick(Sender: TObject);
begin
if (cbUsePlugin.Checked) and (cbbSPlugins.ItemIndex<>-1) then
begin
DSL.GetDSXModule(cbbSPlugins.ItemIndex).CallStopSearch;
DSL.GetDSXModule(cbbSPlugins.ItemIndex).CallFinalize;
ThreadTerminate(nil);
end;
if not assigned(FFindThread) then Exit;
FFindThread.Terminate;
// FFindThread.WaitFor;
@ -511,6 +576,11 @@ begin
gbFindData.Enabled:=cbFindInFile.Checked;
end;
procedure TfrmFindDlg.FormDestroy(Sender: TObject);
begin
FreeAndNil(DSL);
end;
procedure TfrmFindDlg.frmFindDlgClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
@ -521,11 +591,17 @@ begin
end;
procedure TfrmFindDlg.frmFindDlgShow(Sender: TObject);
var i:integer;
begin
if cmbFindFileMask.Visible then
cmbFindFileMask.SelectAll;
//cmbFindFileMask.SetFocus;
cmbFindFileMask.Items.Assign(glsMaskHistory);
for i:=0 to DSL.Count-1 do
begin
cbbSPlugins.AddItem(DSL.GetDSXModule(i).Name+' ('+DSL.GetDSXModule(i).Descr+' )',nil);
end;
if (cbbSPlugins.Items.Count>0) then cbbSPlugins.ItemIndex:=0;
end;
procedure TfrmFindDlg.lsFoundedFilesDblClick(Sender: TObject);

View file

@ -268,11 +268,10 @@ begin
for I := 0 to Count do
DeleteFile(FileList.Strings[I]);
end;
if assigned(WlxPlugins) then
if assigned(WlxPlugins) then
begin
WlxPlugins.Free;
FreeAndNil(WlxPlugins);
end;
end;
procedure TfrmViewer.frmViewerKeyDown(Sender: TObject; var Key: Word;
@ -414,6 +413,10 @@ begin
procedure TfrmViewer.FormDestroy(Sender: TObject);
begin
if assigned(WlxPlugins) then
begin
FreeAndNil(WlxPlugins);
end;
FileList.Free;
if assigned(FFindDialog) then
FreeAndNil(FFindDialog);

View file

@ -0,0 +1,129 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<PathDelim Value="/"/>
<Version Value="6"/>
<General>
<MainUnit Value="0"/>
<IconPath Value="./"/>
<TargetFileExt Value=""/>
<Title Value="DSXLocate"/>
<ActiveEditorIndexAtStart Value="0"/>
</General>
<VersionInfo>
<ProjectVersion Value=""/>
<Language Value=""/>
<CharSet Value=""/>
</VersionInfo>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
<Units Count="3">
<Unit0>
<Filename Value="DSXLocate.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="DSXLocate"/>
<CursorPos X="31" Y="78"/>
<TopLine Value="64"/>
<EditorIndex Value="0"/>
<UsageCount Value="25"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
<Filename Value="udsxplugin.pas"/>
<UnitName Value="udsxplugin"/>
<CursorPos X="1" Y="37"/>
<TopLine Value="8"/>
<EditorIndex Value="2"/>
<UsageCount Value="13"/>
<Loaded Value="True"/>
</Unit1>
<Unit2>
<Filename Value="un_process.pas"/>
<UnitName Value="un_process"/>
<CursorPos X="14" Y="27"/>
<TopLine Value="12"/>
<EditorIndex Value="1"/>
<UsageCount Value="13"/>
<Loaded Value="True"/>
</Unit2>
</Units>
<JumpHistory Count="13" HistoryIndex="12">
<Position1>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="48" Column="5" TopLine="19"/>
</Position1>
<Position2>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="54" Column="7" TopLine="27"/>
</Position2>
<Position3>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="64" Column="11" TopLine="36"/>
</Position3>
<Position4>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="32" Column="19" TopLine="16"/>
</Position4>
<Position5>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="38" Column="22" TopLine="23"/>
</Position5>
<Position6>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="119" Column="14" TopLine="94"/>
</Position6>
<Position7>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="38" Column="22" TopLine="23"/>
</Position7>
<Position8>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="119" Column="14" TopLine="94"/>
</Position8>
<Position9>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="126" Column="8" TopLine="98"/>
</Position9>
<Position10>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="64" Column="5" TopLine="35"/>
</Position10>
<Position11>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="52" Column="42" TopLine="45"/>
</Position11>
<Position12>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="40" Column="15" TopLine="13"/>
</Position12>
<Position13>
<Filename Value="DSXLocate.lpr"/>
<Caret Line="77" Column="3" TopLine="62"/>
</Position13>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
<Version Value="5"/>
<CodeGeneration>
<Generate Value="Faster"/>
</CodeGeneration>
<Linking>
<Options>
<ExecutableType Value="Library"/>
</Options>
</Linking>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</CONFIG>

View file

@ -0,0 +1,170 @@
{
DSXLocate
-------------------------------------------------------------------------
This is DSX (Search) plugin for Double Commander.
Plugin use locate and it's database for searching.
Copyright (C) 2008 Dmitry Kolomiets (B4rr4cuda@rambler.ru)
The original class of TExProcess used in plugin was written by Anton Rjeshevsky.
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
}
library DSXLocate;
{$mode objfpc}{$H+}
uses
Classes,sysutils,udsxplugin,un_process;
var List:TStringList;
LocatePath:String;
type
{ TPlugInfo }
TPlugInfo = class
private
FProcess:TExProcess;
FAddProc:TSAddFileProc;
FUpdateProc:TSUpdateStatusProc;
FSearchAttr:TSearchAttrRecord;
FStartPath:String;
FilesScaned:integer;
public
PluginNr:integer;
//---------------------
constructor Create(Nr:integer);
procedure SetProcs(AddProc:TSAddFileProc; UpdateProc:TSUpdateStatusProc);
procedure SetDefs(SearchAttr:TSearchAttrRecord; StartPath:String);
destructor Destroy; override;
//---------------------
procedure Start;
procedure Stop;
procedure OnReadLn(str: string);
end;
constructor TPlugInfo.Create(Nr:integer);
begin
PluginNr:=Nr;
end;
procedure TPlugInfo.SetProcs(AddProc: TSAddFileProc; UpdateProc: TSUpdateStatusProc);
begin
FAddProc:=AddProc;
FUpdateProc:=UpdateProc;
end;
procedure TPlugInfo.SetDefs(SearchAttr: TSearchAttrRecord; StartPath: String);
begin
FSearchAttr:=SearchAttr;
FStartPath:=StartPath;
end;
destructor TPlugInfo.Destroy;
begin
if Assigned(FProcess) then FreeAndNil(FProcess);
inherited Destroy;
end;
procedure TPlugInfo.Start;
begin
FilesScaned:=0;
FProcess:=TExProcess.Create();
FProcess.OnReadLn:=@OnReadLn;
FProcess.SetCmdLine(LocatePath+' '+string(FSearchAttr.rFileMask));
FProcess.Execute;
end;
procedure TPlugInfo.Stop;
begin
FProcess.Stop;
FreeAndNil(FProcess);
end;
procedure TPlugInfo.OnReadLn(str: string);
begin
FilesScaned:=FilesScaned+1;
FAddProc(PluginNr,PChar(str));
FUpdateProc(PluginNr,PChar(str),FilesScaned);
end;
{Main --------------------------------------------------------------------------------}
function Init(dps:pDSXDefaultParamStruct; pAddFileProc:TSAddFileProc; pUpdateStatus:TSUpdateStatusProc):integer; stdcall;
var i:integer;
begin
if not assigned(List) then List:=TStringList.Create;
I:=List.Count;
List.AddObject(IntToStr(I),TPlugInfo.Create(I));
TPlugInfo(List.Objects[I]).SetProcs(pAddFileProc,pUpdateStatus);
end;
procedure StartSearch(FPluginNr:integer; StartPath:pchar; SearchAttrRec:TSearchAttrRecord); stdcall;
begin
TPlugInfo(List.Objects[FPluginNr]).SetDefs(SearchAttrRec,string(StartPath));
TPlugInfo(List.Objects[FPluginNr]).Start;
end;
procedure StopSearch(FPluginNr:integer); stdcall;
begin
TPlugInfo(List.Objects[FPluginNr]).Stop;
end;
procedure Finalize(FPluginNr:integer); stdcall;
begin
if not Assigned(List) then exit;
if (FPluginNr>List.Count) or (FPluginNr<0) or (List.Count=0) then exit;
//Destroy PlugInfo Item №
TPlugInfo(List.Objects[FPluginNr]).Free;
List.Delete(FPluginNr);
if List.Count=0 then
FreeAndNil(List);
end;
exports
Init,
StartSearch,
StopSearch,
Finalize;
type Tx=class
procedure OnReadLnWhich(str: string);
end;
procedure Tx.OnReadLnWhich(str: string);
begin
if str<>'' then
begin
LocatePath:=str;
//WriteLn('PLUGIN: locate found in '+str);
end;
end;
var Pr:TExProcess; x:TX;
begin
pr:=TExProcess.Create('which locate');
x:=Tx.Create;
pr.OnReadLn:=@(x.OnReadLnWhich);
pr.Execute;
x.free;
end.

View file

@ -0,0 +1,61 @@
unit udsxplugin;
interface
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;
tDSXDefaultParamStruct=record
size,
PluginInterfaceVersionLow,
PluginInterfaceVersionHi:longint;
DefaultIniName:array[0..MAX_PATH-1] of char;
end;
pDSXDefaultParamStruct=^tDSXDefaultParamStruct;
{Prototypes}
{Callbacks procs}
{удалить PlugNr -это не нужно}
TSAddFileProc=procedure (PlugNr:integer; FoundFile:pchar); 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;
}
implementation
end.

View file

@ -0,0 +1,102 @@
{$mode delphi}
{$longstrings on}
unit un_process;
interface
uses process, math,sysutils;
type
TOnReadLn=procedure (str: string) of object;
{ TExProcess }
TExProcess = class
protected
p: TProcess;
s: string;
FStop:boolean;
function _GetExitStatus(): integer;
public
OnReadLn:TOnReadLn;
constructor Create(commandline: string='');
procedure Execute;
procedure Stop;
procedure SetCmdLine(commandline:string);
destructor Destroy;
property ExitStatus: integer read _GetExitStatus;
end;
implementation
const buf_len = 3000;
{ TExProcess }
function TExProcess._GetExitStatus(): integer;
begin
Result:=p.ExitStatus;
end;
constructor TExProcess.Create(commandline: string='');
begin
s:='';
p:=TProcess.Create(nil);
p.CommandLine:=commandline;
p.Options:=[poUsePipes,poNoConsole];
end;
procedure TExProcess.Execute;
var
buf: string;
i, j, c, n: integer;
begin
try
p.Execute;
repeat
if FStop then exit;
SetLength(buf, buf_len);
SetLength(buf, p.output.Read(buf[1], length(buf))); //waits for the process output
// cut the incoming stream to lines:
s:=s + buf; //add to the accumulator
repeat //detect the line breaks and cut.
i:=Pos(#13, s);
j:=Pos(#10, s);
if i=0 then i:=j;
if j=0 then j:=i;
if j = 0 then Break; //there are no complete lines yet.
if Assigned(OnReadLn) then
OnReadLn(Copy(s, 1, min(i, j) - 1)); //return the line without the CR/LF characters
s:=Copy(s, max(i, j) + 1, length(s) - max(i, j)); //remove the line from accumulator
until false;
until buf = '';
if s <> '' then
if Assigned(OnReadLn) then
OnReadLn(s);
buf:='';
if Assigned(OnReadLn) then
OnReadLn(buf); //Empty line to notify DC about search process finish
finally
end;
end;
procedure TExProcess.Stop;
begin
FStop:=true;
end;
procedure TExProcess.SetCmdLine(commandline:string);
begin
p.CommandLine:=commandline;
end;
destructor TExProcess.Destroy;
begin
FreeAndNil(p);
end;
end.

367
udsxmodule.pas Normal file
View file

@ -0,0 +1,367 @@
{
Double Commander
-------------------------------------------------------------------------
(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
(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 udsxmodule;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, dynlibs,LCLProc,uGlobs,udsxplugin,IniFiles, uDCUtils;
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;
{ 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 }
TDSXModuleList = class
private
Flist:TStringList;
function GetCount:integer;
public
//---------------------
constructor Create;
destructor Destroy; override;
//---------------------
procedure Clear;
procedure Load(FileName:string);overload;
procedure Load(Ini:TiniFile); overload;
procedure Save(FileName:string);overload;
procedure Save(Ini:TIniFile); 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;
//---------------------
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
{ TDsxModule }
function TDsxModule.GIsLoaded: boolean;
begin
Result:=FModuleHandle<>0;
end;
constructor TDsxModule.Create;
begin
end;
destructor TDsxModule.Destroy;
begin
if GIsLoaded then UnloadModule;
inherited Destroy;
end;
function TDsxModule.LoadModule: Boolean;
begin
FModuleHandle := LoadLibrary(Self.FileName);
Result := (FModuleHandle <> 0);
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'));
end;
procedure TDsxModule.UnloadModule;
begin
if Assigned(SFinalize) then SFinalize(FPluginNr);
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;
begin
if Assigned(SInit) then
begin
GetMem(dps,SizeOf(tDSXDefaultParamStruct));
dps^.DefaultIniName:=gini.FileName;
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);
begin
if Assigned(SStartSearch) then
begin
SStartSearch(FPluginNr,StartPath,SearchAttrRec);
end;
end;
procedure TDsxModule.CallStopSearch;
begin
if Assigned(SStopSearch) then
SStopSearch(FPluginNr);
end;
procedure TDsxModule.CallFinalize;
begin
if Assigned(SFinalize) then
SFinalize(FPluginNr);
end;
{ TDSXModuleList }
function TDSXModuleList.GetCount: integer;
begin
if Assigned(Flist) then
Result:=Flist.Count
else Result:=0;
end;
constructor TDSXModuleList.Create;
begin
Flist:=TStringList.Create;
end;
destructor TDSXModuleList.Destroy;
begin
while Flist.Count>0 do
begin
if assigned(TDSXModule(Flist.Objects[0])) then
TDSXModule(Flist.Objects[0]).Free;
Flist.Delete(0);
end;
FreeAndNil(Flist);
inherited Destroy;
end;
procedure TDSXModuleList.Clear;
begin
while Flist.Count>0 do
begin
TDSXModule(Flist.Objects[0]).Free;
Flist.Delete(0);
end;
end;
procedure TDSXModuleList.Load(FileName: string);
var Ini:TIniFile;
begin
try
Ini:=TIniFile.Create(FileName);
Load(Ini);
finally
Ini.Free;
end;
end;
procedure TDSXModuleList.Load(Ini: TiniFile);
var xCount,I:integer;
tmp:string;
begin
Self.Clear;
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;
end;
procedure TDSXModuleList.Save(FileName: string);
var Ini:TIniFile;
begin
try
Ini:=TIniFile.Create(FileName);
Save(Ini);
finally
Ini.Free;
end;
end;
procedure TDSXModuleList.Save(Ini: TIniFile);
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;
procedure TDSXModuleList.DeleteItem(Index: integer);
begin
if (Index>-1) and (Index<Flist.Count) then
begin
TDSXModule(Flist.Objects[Index]).Free;
Flist.Delete(Index);
end;
end;
function TDSXModuleList.Add(Item: TDSXModule): integer;
begin
Result:=Flist.AddObject(UpCase(item.Name),Item);
end;
function TDSXModuleList.Add(FileName: string): integer;
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;
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;
end;
function TDSXModuleList.IsLoaded(AName: String): Boolean;
var x:integer;
begin
x:=Flist.IndexOf(AName);
if x=-1 then Result:=false
else
begin
Result:=GetDSXModule(x).IsLoaded;
end;
end;
function TDSXModuleList.IsLoaded(Index: integer): Boolean;
begin
Result:=GetDSXModule(Index).IsLoaded;
end;
function TDSXModuleList.LoadModule(AName: String): Boolean;
var x:integer;
begin
x:=Flist.IndexOf(UpCase(AName));
if x=-1 then Result:=false
else
begin
Result:=GetDSXModule(x).LoadModule;
end;
end;
function TDSXModuleList.LoadModule(Index: integer): Boolean;
begin
Result:=GetDSXModule(Index).LoadModule;
end;
function TDSXModuleList.GetDSXModule(Index: integer): TDSXModule;
begin
Result:=TDSXModule(Flist.Objects[Index]);
end;
function TDSXModuleList.GetDSXModule(AName: string): TDSXModule;
var tmp:integer;
begin
tmp:=Flist.IndexOf(upcase(AName));
if tmp>-1 then
Result:=TDSXModule(Flist.Objects[tmp]);
end;
end.

61
udsxplugin.pas Normal file
View file

@ -0,0 +1,61 @@
unit udsxplugin;
interface
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;
tDSXDefaultParamStruct=record
size,
PluginInterfaceVersionLow,
PluginInterfaceVersionHi:longint;
DefaultIniName:array[0..MAX_PATH-1] of char;
end;
pDSXDefaultParamStruct=^tDSXDefaultParamStruct;
{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;
{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

@ -28,7 +28,7 @@ unit uFindThread;
interface
uses
Classes, StdCtrls, uDCUtils, SysUtils;
Classes, StdCtrls, uDCUtils, SysUtils,udsxplugin;
type
@ -81,6 +81,7 @@ TFindThread = class(TThread)
procedure AddFile;
procedure WalkAdr(const sNewDir:String);
procedure UpDateProgress;
procedure FillSearchRecord(var Srec:TSearchAttrRecord);
property FilterMask:String read FFileMask write FFileMask;
property PathStart:String read FPathStart write FPathStart;
property Items:TStrings write FItems;
@ -341,6 +342,40 @@ if not MatchesMaskList(sr.Name, FFileMask) then
end;
end;
procedure TFindThread.FillSearchRecord(var Srec:TSearchAttrRecord);
begin
with Srec do
begin
rFileMask:=pchar(FFileMask);
rAttributes:=FAttributes;
rAttribStr:=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:= pchar(FFindData);
(* Replace text *)
rReplaceInFiles:=FReplaceInFiles;
rReplaceData:=pchar(FReplaceData);
end;
end;
procedure TFindThread.WalkAdr(const sNewDir:String);
var
sr: TSearchRec;