summaryrefslogtreecommitdiff
path: root/USearch.pas
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2008-06-07 20:34:49 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2008-06-07 20:34:49 +0200
commitecde167da74c86bc047aaf84c5e548cf65a5da98 (patch)
treea015dfda84f28a65811e3aa0d369f8f211ec8c60 /USearch.pas
downloadtuxcmd-release-0.6.36-dev.tar.xz
Diffstat (limited to 'USearch.pas')
-rw-r--r--USearch.pas1030
1 files changed, 1030 insertions, 0 deletions
diff --git a/USearch.pas b/USearch.pas
new file mode 100644
index 0000000..4cd49f1
--- /dev/null
+++ b/USearch.pas
@@ -0,0 +1,1030 @@
+(*
+ Tux Commander - USearch - Search dialog
+ Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ Check for updates on tuxcmd.sourceforge.net
+
+ 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 USearch;
+
+interface
+
+uses
+ glib2, gdk2, gtk2, SyncObjs, SysUtils, Types, Classes, Variants, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKView,
+ GTKMenus,
+ UEngines, UGnome;
+
+type
+ TFSearch = class(TGTKDialog)
+ BottomBox: TGTKVBox;
+ HBox, HBox2: TGTKHBox;
+ ButtonBox: TGTKHButtonBox;
+ FileList: TGTKListView;
+ FileListScrolledWindow: TGTKScrolledWindow;
+
+ Notebook: TGTKNotebook;
+ Table1, Table2: TGTKTable;
+ ResultsLabel, StatusLabel: TGTKLabel;
+ Label1, Label2, Label3, Label4, Label5, Label6: TGTKLabel;
+ FileMaskEntry: TGTKCombo;
+ SearchInEntry, FindTextEntry: TGTKEntry;
+ ViewButton, NewSearchButton, GoToFileButton, FeedToListboxButton: TGTKButton;
+ SearchArchivesCheckButton, CaseSensitiveCheckButton, StayCurrentFSCheckButton, CaseSensitiveMatchCheckButton: TGTKCheckButton;
+ FindButton, StopButton, CloseButton: TGTKButton;
+ BiggerThanCheckButton, SmallerThanCheckButton: TGTKCheckButton;
+ BiggerThanEntry, SmallerThanEntry: TGTKSpinEdit;
+ BiggerThanOptionMenu, SmallerThanOptionMenu, ModifiedLastOptionMenu, ModifiedNotLastOptionMenu: TGTKOptionMenu;
+ ModifiedBetweenRadioButton, NotModifiedAfterRadioButton, ModifiedLastRadioButton, ModifiedNotLastRadionButton: TGTKCheckButton;
+ ModifiedLastSpinEdit, ModifiedNotLastSpinEdit: TGTKSpinEdit;
+ ModifiedBetweenEntry1, ModifiedBetweenEntry2, NotModifiedAfterEntry: TGTKEntry;
+ ModifiedBetweenEntry1G, ModifiedBetweenEntry2G, NotModifiedAfterEntryG: TGnomeDateEdit;
+ procedure FormCreate(Sender: TObject); override;
+ procedure FormDestroy(Sender: TObject);
+ procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
+ procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+ procedure FormResponse(Sender: TObject; const ResponseID: integer);
+ procedure FileListSelectionChanged(Sender: TObject);
+ procedure FindButtonClick(Sender: TObject);
+ procedure StopButtonClick(Sender: TObject);
+ procedure CloseButtonClick(Sender: TObject);
+ procedure BiggerThanCheckButtonToggled(Sender: TObject);
+ procedure NewSearchButtonClick(Sender: TObject);
+ procedure ViewButtonClick(Sender: TObject);
+ procedure GoToFileButtonClick(Sender: TObject);
+ procedure FileListDblClick(Sender: TObject; Button: TGDKMouseButton; Shift: TShiftState; X, Y: Integer; var Accept: boolean);
+ procedure FileMaskEntryKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
+ private
+ Processing, Stop, FUseGnomeWidgets: boolean;
+ SavedData: string;
+ procedure ConstructViews;
+ procedure DoSearch;
+ public
+ Engine: TPanelEngine;
+ AListView: TGTKListView;
+ List: TList;
+ GoToFile, GoToFileArchive: string;
+ end;
+
+ TSearchThread = class(TThread)
+ private
+ FEngine: TPanelEngine;
+ Wilds: array of string;
+ GUIMutex: TCriticalSection;
+ procedure Rekurze(StartDir: string);
+ function FindText(FileName: string): boolean;
+ protected
+ FStartPath, FFileMask, FStringFind: string;
+ FDontLeaveFS, FCaseSensitiveMask, FCaseSensitiveStrings, FSearchArchives: boolean;
+ FBiggerThan, FSmallerThan: integer; // -1 = skip
+ FModifiedBetween1, FModifiedBetween2, FNotModifiedAfter: TDateTime;
+ FModifiedLast, FModifiedNotLast: integer;
+ FList: TList;
+ procedure Execute; override;
+ public
+ Finished, CancelIt: boolean;
+ CurrentDir: string;
+ constructor Create(Engine: TPanelEngine);
+ destructor Destroy; override;
+ end;
+
+var
+ FSearch: TFSearch;
+
+implementation
+
+uses Math, UMain, ULocale, UCoreUtils, Libc, UCore, DateUtils, UViewer, UConfig, UVFSCore;
+
+type TFileListItem = class
+ CRC: LongWord;
+ MD5: string;
+ Name, FullPath: string;
+ Status: byte;
+ IsMD5: boolean;
+ Size: Int64;
+ end;
+
+var SizeUnits: array[0..2] of string;
+ DayUnits: array[0..3] of string;
+
+
+procedure TFSearch.FormCreate(Sender: TObject);
+var MenuItem: TGTKMenuItem;
+ i: integer;
+begin
+ // Set the constants
+ SizeUnits[0] := LANGSearch_Bytes;
+ SizeUnits[1] := LANGSearch_kB;
+ SizeUnits[2] := LANGSearch_MB;
+ DayUnits[0] := LANGSearch_days;
+ DayUnits[1] := LANGSearch_weeks;
+ DayUnits[2] := LANGSearch_months;
+ DayUnits[3] := LANGSearch_years;
+
+ // Initialization
+// WindowTypeHint := whNormal;
+ List := TList.Create;
+ List.Clear;
+ Processing := False;
+ Stop := False;
+ GoToFile := '';
+ GoToFileArchive := '';
+ SetDefaultSize(650, 600);
+ Caption := LANGSearch_Caption;
+ Buttons := [];
+ ShowSeparator := False;
+ FUseGnomeWidgets := Assigned(@gnome_date_edit_new) and Assigned(@gnome_date_edit_set_time) and Assigned(@gnome_date_edit_get_time);
+
+ Notebook := TGTKNotebook.Create(Self);
+ Notebook.BorderWidth := 10;
+ Table1 := TGTKTable.Create(Self);
+ Table1.BorderWidth := 10;
+ Table2 := TGTKTable.Create(Self);
+ Table2.BorderWidth := 10;
+ Notebook.AppendPage(Table1, LANGSearch_General);
+ Notebook.AppendPage(Table2, LANGSearch_Advanced);
+
+ ConstructViews;
+
+ ResultsLabel := TGTKLabel.Create(Self);
+ ResultsLabel.XAlign := 0;
+ ResultsLabel.XPadding := 0;
+ ResultsLabel.Caption := Format('<span weight="ultrabold">%s</span>', [LANGSearch_SearchResults]);
+ ResultsLabel.FocusControl := FileList;
+ ResultsLabel.UseMarkup := True;
+ ResultsLabel.UseUnderline := True;
+
+ ClientArea.AddControlEx(Notebook, False, False, 0);
+
+
+ Label1 := TGTKLabel.Create(Self);
+ Label1.XAlign := 0;
+ Label1.XPadding := 0;
+ Label1.Caption := Format('<span weight="ultrabold">%s</span>', [LANGSearch_SearchFor]);
+ FileMaskEntry := TGTKCombo.Create(Self);
+ FileMaskEntry.Tooltip := LANGSearch_FileMaskEntryTooltip;
+ FileMaskEntry.Entry.OnKeyDown := FileMaskEntryKeyDown;
+ if SearchHistory.Count > 0 then
+ for i := 0 to SearchHistory.Count - 1 do
+ FileMaskEntry.Items.Append(SearchHistory[i]);
+ FileMaskEntry.Entry.Text := '';
+ Label1.FocusControl := FileMaskEntry.Entry;
+ Label1.UseMarkup := True;
+ Label1.UseUnderline := True;
+ Label2 := TGTKLabel.Create(Self);
+ Label2.XAlign := 0;
+ Label2.XPadding := 0;
+ Label2.Caption := LANGSearch_SearchIn;
+ SearchInEntry := TGTKEntry.Create(Self);
+ Label2.FocusControl := SearchInEntry;
+ Label2.UseMarkup := True;
+ Label2.UseUnderline := True;
+ SearchArchivesCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_SearchArchivesCheckButton);
+ SearchArchivesCheckButton.Enabled := PluginList.Count > 0;
+ Label3 := TGTKLabel.Create(Self);
+ Label3.XAlign := 0;
+ Label3.XPadding := 0;
+ Label3.Caption := LANGSearch_FindText;
+ FindTextEntry := TGTKEntry.Create(Self);
+ FindTextEntry.Tooltip := LANGSearch_FindTextEntryTooltip;
+ Label3.FocusControl := FindTextEntry;
+ Label3.UseMarkup := True;
+ Label3.UseUnderline := True;
+ CaseSensitiveCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_CaseSensitiveCheckButton);
+ StayCurrentFSCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_StayCurrentFSCheckButton);
+ CaseSensitiveMatchCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_CaseSensitiveMatchCheckButton);
+
+ Table1.AddControlEx(0, 0, 1, 1, Label1, [taoShrink, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(1, 0, 1, 1, FileMaskEntry, [taoExpand, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(2, 0, 1, 1, CaseSensitiveMatchCheckButton, [taoShrink, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(0, 1, 1, 1, Label2, [taoShrink, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(1, 1, 1, 1, SearchInEntry, [taoExpand, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(2, 1, 1, 1, StayCurrentFSCheckButton, [taoShrink], [taoShrink], 5, 2);
+ Table1.AddControlEx(1, 2, 2, 1, SearchArchivesCheckButton, [taoShrink, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(0, 3, 3, 1, TGTKHSeparator.Create(Self), [taoExpand, taoFill], [taoShrink], 5, 4);
+ Table1.AddControlEx(0, 4, 1, 1, Label3, [taoShrink, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(1, 4, 2, 1, FindTextEntry, [taoExpand, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(1, 5, 2, 1, CaseSensitiveCheckButton, [taoShrink, taoFill], [taoShrink], 5, 2);
+ Table1.AddControlEx(0, 6, 3, 1, TGTKVBox.Create(Self), [taoShrink, taoFill], [taoExpand, taoFill], 5, 2);
+
+
+
+ Label4 := TGTKLabel.Create(Self);
+ Label4.XAlign := 0;
+ Label4.XPadding := 0;
+ Label4.Caption := Format('<span weight="ultrabold">%s</span>', [LANGSearch_Size]);
+ Label4.UseMarkup := True;
+ Label5 := TGTKLabel.Create(Self);
+ Label5.XAlign := 0;
+ Label5.XPadding := 0;
+ Label5.Caption := Format('<span weight="ultrabold">%s</span>', [LANGSearch_Date]);
+ Label5.UseMarkup := True;
+ BiggerThanCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_BiggerThan);
+ SmallerThanCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_SmallerThan);
+ BiggerThanEntry := TGTKSpinEdit.Create(Self);
+ BiggerThanEntry.Min := 0;
+ BiggerThanEntry.Max := 999999999;
+ BiggerThanEntry.Digits := 0;
+ BiggerThanEntry.IncrementStep := 1;
+ BiggerThanEntry.IncrementPage := 10;
+ SmallerThanEntry := TGTKSpinEdit.Create(Self);
+ SmallerThanEntry.Min := 0;
+ SmallerThanEntry.Max := 999999999;
+ SmallerThanEntry.Digits := 0;
+ SmallerThanEntry.IncrementStep := 1;
+ SmallerThanEntry.IncrementPage := 10;
+ BiggerThanOptionMenu := TGTKOptionMenu.Create(Self);
+ for i := Low(SizeUnits) to High(SizeUnits) do begin
+ MenuItem := TGTKMenuItem.Create(Self);
+ MenuItem.Caption := SizeUnits[i];
+ BiggerThanOptionMenu.Items.Add(MenuItem);
+ end;
+ SmallerThanOptionMenu := TGTKOptionMenu.Create(Self);
+ for i := Low(SizeUnits) to High(SizeUnits) do begin
+ MenuItem := TGTKMenuItem.Create(Self);
+ MenuItem.Caption := SizeUnits[i];
+ SmallerThanOptionMenu.Items.Add(MenuItem);
+ end;
+ ModifiedBetweenRadioButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_ModifiedBetweenRadioButton);
+ NotModifiedAfterRadioButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_NotModifiedAfterRadioButton);
+ ModifiedLastRadioButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_ModifiedLastRadioButton);
+ ModifiedNotLastRadionButton := TGTKCheckButton.CreateWithLabel(Self, LANGSearch_ModifiedNotLastRadionButton);
+ ModifiedLastSpinEdit := TGTKSpinEdit.Create(Self);
+ ModifiedLastSpinEdit.Min := 0;
+ ModifiedLastSpinEdit.Max := 10000;
+ ModifiedLastSpinEdit.Digits := 0;
+ ModifiedLastSpinEdit.IncrementStep := 1;
+ ModifiedLastSpinEdit.IncrementPage := 10;
+ ModifiedNotLastSpinEdit := TGTKSpinEdit.Create(Self);
+ ModifiedNotLastSpinEdit.Min := 0;
+ ModifiedNotLastSpinEdit.Max := 10000;
+ ModifiedNotLastSpinEdit.Digits := 0;
+ ModifiedNotLastSpinEdit.IncrementStep := 1;
+ ModifiedNotLastSpinEdit.IncrementPage := 10;
+ ModifiedLastOptionMenu := TGTKOptionMenu.Create(Self);
+ for i := Low(DayUnits) to High(DayUnits) do begin
+ MenuItem := TGTKMenuItem.Create(Self);
+ MenuItem.Caption := DayUnits[i];
+ ModifiedLastOptionMenu.Items.Add(MenuItem);
+ end;
+ ModifiedNotLastOptionMenu := TGTKOptionMenu.Create(Self);
+ for i := Low(DayUnits) to High(DayUnits) do begin
+ MenuItem := TGTKMenuItem.Create(Self);
+ MenuItem.Caption := DayUnits[i];
+ ModifiedNotLastOptionMenu.Items.Add(MenuItem);
+ end;
+ Label6 := TGTKLabel.Create(Self);
+ Label6.XAlign := 0;
+ Label6.XPadding := 0;
+ Label6.Caption := LANGSearch_And;
+ Label6.UseMarkup := True;
+
+ if not FUseGnomeWidgets then begin
+ ModifiedBetweenEntry1 := TGTKEntry.Create(Self);
+ ModifiedBetweenEntry1.Tooltip := FormatDateTime(LANGSearch_ModifiedBetweenEntry1, Date);
+ ModifiedBetweenEntry2 := TGTKEntry.Create(Self);
+ ModifiedBetweenEntry2.Tooltip := FormatDateTime(LANGSearch_ModifiedBetweenEntry1, Date);
+ NotModifiedAfterEntry := TGTKEntry.Create(Self);
+ NotModifiedAfterEntry.Tooltip := FormatDateTime(LANGSearch_ModifiedBetweenEntry1, Date);
+ Table2.AddControlEx(2, 5, 2, 1, ModifiedBetweenEntry1, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ Table2.AddControlEx(5, 5, 2, 1, ModifiedBetweenEntry2, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ Table2.AddControlEx(2, 6, 2, 1, NotModifiedAfterEntry, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ end else begin
+ ModifiedBetweenEntry1G := TGnomeDateEdit.Create(Self);
+ ModifiedBetweenEntry2G := TGnomeDateEdit.Create(Self);
+ NotModifiedAfterEntryG := TGnomeDateEdit.Create(Self);
+ Table2.AddControlEx(2, 5, 2, 1, ModifiedBetweenEntry1G, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ Table2.AddControlEx(5, 5, 2, 1, ModifiedBetweenEntry2G, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ Table2.AddControlEx(2, 6, 2, 1, NotModifiedAfterEntryG, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ end;
+
+ Table2.AddControlEx(0, 0, 3, 1, Label4, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 0);
+ Table2.AddControlEx(0, 1, 1, 1, TGTKVBox.Create(Self), [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 8, 0);
+ Table2.AddControlEx(1, 1, 1, 1, BiggerThanCheckButton, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 2, 0);
+ Table2.AddControlEx(2, 1, 1, 1, BiggerThanEntry, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 0);
+ Table2.AddControlEx(3, 1, 1, 1, BiggerThanOptionMenu, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 0, 0);
+ Table2.AddControlEx(5, 1, 1, 1, SmallerThanCheckButton, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 0);
+ Table2.AddControlEx(6, 1, 1, 1, SmallerThanEntry, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 0);
+ Table2.AddControlEx(7, 1, 1, 1, SmallerThanOptionMenu, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 0, 0);
+ Table2.AddControlEx(1, 3, 3, 1, TGTKVBox.Create(Self), [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 0, 6);
+ Table2.AddControlEx(0, 4, 3, 1, Label5, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 1);
+ Table2.AddControlEx(1, 5, 1, 1, ModifiedBetweenRadioButton, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 2, 2);
+ Table2.AddControlEx(4, 5, 1, 1, Label6, [taoShrink], [taoShrink, taoExpand, taoFill], 5, 2);
+ Table2.AddControlEx(1, 6, 1, 1, NotModifiedAfterRadioButton, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 2, 2);
+ Table2.AddControlEx(1, 7, 1, 1, ModifiedLastRadioButton, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 2, 2);
+ Table2.AddControlEx(2, 7, 1, 1, ModifiedLastSpinEdit, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ Table2.AddControlEx(3, 7, 1, 1, ModifiedLastOptionMenu, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 2, 2);
+ Table2.AddControlEx(4, 7, 2, 1, ModifiedNotLastRadionButton, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ Table2.AddControlEx(6, 7, 1, 1, ModifiedNotLastSpinEdit, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
+ Table2.AddControlEx(7, 7, 1, 1, ModifiedNotLastOptionMenu, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 0, 2);
+
+
+ BottomBox := TGTKVBox.Create(Self);
+ BottomBox.Homogeneous := False;
+ BottomBox.BorderWidth := 10;
+ FileListScrolledWindow := TGTKScrolledWindow.Create(Self);
+ FileListScrolledWindow.HorizScrollBarPolicy := sbAutomatic;
+ FileListScrolledWindow.VertScrollBarPolicy := sbAutomatic;
+ FileListScrolledWindow.ShadowType := stShadowIn;
+ FileListScrolledWindow.AddControl(FileList);
+ FileListScrolledWindow.SetSizeRequest(100, -1);
+ FileList.SetSizeRequest(100, -1);
+ HBox := TGTKHBox.Create(Self);
+ HBox2 := TGTKHBox.Create(Self);
+ HBox2.Homogeneous := False;
+ HBox.Homogeneous := True;
+ ViewButton := TGTKButton.Create(Self);
+ ViewButton.Caption := LANGSearch_ViewButtonCaption;
+ ViewButton.Visible := True;
+ NewSearchButton := TGTKButton.Create(Self);
+ NewSearchButton.Caption := LANGSearch_NewSearchButtonCaption;
+ GoToFileButton := TGTKButton.Create(Self);
+ GoToFileButton.Caption := LANGSearch_GoToFileButtonCaption;
+ FeedToListboxButton := TGTKButton.Create(Self);
+ FeedToListboxButton.Caption := LANGSearch_FeedToListboxButtonCaption;
+ FeedToListboxButton.Enabled := False;
+ FeedToListboxButton.Visible := True;
+ StatusLabel := TGTKLabel.Create(Self);
+ StatusLabel.XAlign := 0;
+ StatusLabel.XPadding := 0;
+ StatusLabel.Caption := Format('<span weight="ultrabold">%s</span> %s', [LANGSearch_StatusSC, LANGSearch_Ready]);
+ StatusLabel.UseMarkup := True;
+ StatusLabel.SetSizeRequest(100, -1);
+ HBox.AddControlEx(ViewButton, True, True, 3);
+ HBox.AddControlEx(NewSearchButton, True, True, 3);
+ HBox.AddControlEx(GoToFileButton, True, True, 3);
+ HBox.AddControlEx(FeedToListboxButton, True, True, 3);
+ HBox2.AddControlEx(TGTKVBox.Create(Self), True, True, 20);
+ HBox2.AddControlEx(HBox, False, False, 0);
+
+ BottomBox.AddControlEx(ResultsLabel, False, False, 5);
+ BottomBox.AddControlEx(FileListScrolledWindow, True, True, 0);
+ BottomBox.AddControlEx(StatusLabel, False, False, 5);
+ BottomBox.AddControlEx(HBox2, False, False, 2);
+ ClientArea.AddControlEx(BottomBox, True, True, 5);
+
+ FindButton := TGTKButton.CreateFromStock(Self, GTK_STOCK_FIND);
+ FindButton.Default := True;
+ StopButton := TGTKButton.CreateFromStock(Self, GTK_STOCK_STOP);
+ StopButton.Visible := False;
+ StopButton.Default := True;
+ CloseButton := TGTKButton.CreateFromStock(Self, GTK_STOCK_CLOSE);
+ CloseButton.Default := True;
+ Default := FindButton;
+ ButtonBox := TGTKHButtonBox.Create(Self);
+ ButtonBox.Layout := blEnd;
+ ButtonBox.Spacing := 10;
+ ButtonBox.BorderWidth := 10;
+ ButtonBox.AddControlEnd(FindButton);
+ ButtonBox.AddControlEnd(StopButton);
+ ButtonBox.AddControlEnd(CloseButton);
+
+ ActionArea.AddControlEx(ButtonBox, False, False, 0);
+
+ OnKeyDown := FormKeyDown;
+ OnCloseQuery := FormCloseQuery;
+ OnResponse := FormResponse;
+ OnDestroy := FormDestroy;
+ FileList.OnSelectionChanged := FileListSelectionChanged;
+ FindButton.OnClick := FindButtonClick;
+ StopButton.OnClick := StopButtonClick;
+ CloseButton.OnClick := CloseButtonClick;
+ BiggerThanCheckButton.OnToggled := BiggerThanCheckButtonToggled;
+ SmallerThanCheckButton.OnToggled := BiggerThanCheckButtonToggled;
+ ModifiedBetweenRadioButton.OnToggled := BiggerThanCheckButtonToggled;
+ NotModifiedAfterRadioButton.OnToggled := BiggerThanCheckButtonToggled;
+ ModifiedLastRadioButton.OnToggled := BiggerThanCheckButtonToggled;
+ ModifiedNotLastRadionButton.OnToggled := BiggerThanCheckButtonToggled;
+ NewSearchButton.OnClick := NewSearchButtonClick;
+ ViewButton.OnClick := ViewButtonClick;
+ GoToFileButton.OnClick := GoToFileButtonClick;
+ FileList.OnDblClick := FileListDblClick;
+
+ Notebook.PageIndex := 0;
+ FileMaskEntry.Entry.SetFocus;
+ BiggerThanCheckButtonToggled(Sender);
+ FileListSelectionChanged(Sender);
+end;
+
+procedure TFSearch.ConstructViews;
+var Column: TGTKTreeViewColumn;
+ i: integer;
+begin
+ FileList := TGTKListView.CreateTyped(Self, True, [lcPointer, lcText]);
+ FileList.SelectionMode := smSingle;
+ FileList.RulesHint := True;
+ FileList.ShowHeaders := False;
+ Column := FileList.Columns.Add;
+ Column.Caption := LANGFilenameColumnCaption;
+ Column.AddAttribute('text', 1);
+ Column.SortID := 0;
+ for i := 0 to FileList.Columns.Count - 1 do begin
+ FileList.Columns[i].SizingMode := smAutoSize;
+ FileList.Columns[i].Resizable := True;
+ FileList.Columns[i].SetProperty('ypad', 0);
+ FileList.Columns[i].SetProperty('yalign', 0.5);
+ end;
+end;
+
+procedure TFSearch.FormDestroy(Sender: TObject);
+ var i: integer;
+begin
+ Application.ProcessMessages;
+ try
+ if List.Count > 0 then
+ for i := 0 to List.Count - 1 do
+ FreeDataItem(PDataItem(List[i]));
+ List.Free;
+ except end;
+end;
+
+procedure TFSearch.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+begin
+ Stop := True;
+end;
+
+procedure TFSearch.FormResponse(Sender: TObject; const ResponseID: integer);
+begin
+ Stop := True;
+end;
+
+procedure TFSearch.FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
+begin
+ case Key of
+ GDK_F3: if FileList.Focused and Assigned(FileList.Selected) then begin
+ Accept := False;
+ ViewButtonClick(Sender);
+ end;
+ GDK_RETURN, GDK_KP_ENTER: if FileList.Focused and Assigned(FileList.Selected) then begin
+ Accept := False;
+ GoToFileButtonClick(Sender);
+ end else
+ if FindButton.Visible then begin
+ FindButtonClick(Sender);
+ Accept := False;
+ end;
+ GDK_ESCAPE: begin
+ Accept := False;
+ if Processing then Stop := True
+ else ModalResult := mbCancel;
+ end;
+ end;
+end;
+
+procedure TFSearch.FindButtonClick(Sender: TObject);
+var s: string;
+ i: integer;
+begin
+ s := Trim(FileMaskEntry.Entry.Text);
+ if Length(s) > 0 then begin
+ SaveItemToHistory(s, SearchHistory);
+ if FileMaskEntry.Items.Count > 0 then
+ for i := FileMaskEntry.Items.Count - 1 downto 0 do
+ FileMaskEntry.Items.Delete(i);
+ if SearchHistory.Count > 0 then
+ for i := 0 to SearchHistory.Count - 1 do
+ FileMaskEntry.Items.Append(SearchHistory[i]);
+ end;
+
+ DoSearch;
+end;
+
+procedure TFSearch.StopButtonClick(Sender: TObject);
+begin
+ Stop := True;
+end;
+
+procedure TFSearch.CloseButtonClick(Sender: TObject);
+begin
+ if Processing then Stop := True;
+ ModalResult := mbClose;
+end;
+
+procedure TFSearch.BiggerThanCheckButtonToggled(Sender: TObject);
+begin
+ BiggerThanEntry.Enabled := BiggerThanCheckButton.Checked;
+ BiggerThanOptionMenu.Enabled := BiggerThanCheckButton.Checked;
+ SmallerThanEntry.Enabled := SmallerThanCheckButton.Checked;
+ SmallerThanOptionMenu.Enabled := SmallerThanCheckButton.Checked;
+ Label6.Enabled := ModifiedBetweenRadioButton.Checked;
+ ModifiedLastSpinEdit.Enabled := ModifiedLastRadioButton.Checked;
+ ModifiedLastOptionMenu.Enabled := ModifiedLastRadioButton.Checked;
+ ModifiedNotLastSpinEdit.Enabled := ModifiedNotLastRadionButton.Checked;
+ ModifiedNotLastOptionMenu.Enabled := ModifiedNotLastRadionButton.Checked;
+ if not FUseGnomeWidgets then begin
+ ModifiedBetweenEntry1.Enabled := ModifiedBetweenRadioButton.Checked;
+ ModifiedBetweenEntry2.Enabled := ModifiedBetweenRadioButton.Checked;
+ NotModifiedAfterEntry.Enabled := NotModifiedAfterRadioButton.Checked;
+ end else begin
+ ModifiedBetweenEntry1G.Enabled := ModifiedBetweenRadioButton.Checked;
+ ModifiedBetweenEntry2G.Enabled := ModifiedBetweenRadioButton.Checked;
+ NotModifiedAfterEntryG.Enabled := NotModifiedAfterRadioButton.Checked;
+ end;
+end;
+
+procedure TFSearch.FileListSelectionChanged(Sender: TObject);
+begin
+ GoToFileButton.Enabled := Assigned(FileList.Selected) and Assigned(FileList.Selected.AsPointer(0));
+ ViewButton.Enabled := Assigned(FileList.Selected) and Assigned(FileList.Selected.AsPointer(0));
+end;
+
+procedure TFSearch.NewSearchButtonClick(Sender: TObject);
+var i: integer;
+begin
+ try
+ FileMaskEntry.Entry.Text := '';
+ FileMaskEntry.Entry.SetFocus;
+ FileList.Items.Clear;
+ if List.Count > 0 then
+ for i := List.Count - 1 downto 0 do
+ FreeDataItem(PDataItem(List[i]));
+ List.Clear;
+ StatusLabel.Caption := Format('<span weight="ultrabold">%s</span> %s', [LANGSearch_StatusSC, LANGSearch_Ready]);
+ StatusLabel.UseMarkup := True;
+ except
+ end;
+end;
+
+procedure TFSearch.ViewButtonClick(Sender: TObject);
+var AViewer: TViewerThread;
+ AEngine: TPanelEngine;
+ Plugin: TVFSPlugin;
+ b: boolean;
+ archive, s: string;
+ i, j: integer;
+begin
+ if not (Assigned(FileList.Selected) and Assigned(FileList.Selected.AsPointer(0))) then Exit;
+ if Assigned(PDataItem(FileList.Selected.AsPointer(0))^.LnkPointTo) then begin
+ archive := string(PDataItem(FileList.Selected.AsPointer(0))^.LnkPointTo);
+ b := False;
+ s := ANSIUpperCase(Trim(Copy(archive, LastDelimiter('.', archive) + 1, Length(archive) - LastDelimiter('.', archive))));
+ if (Length(s) > 1) and (s[1] = '.') then Delete(s, 1, 1);
+ if PluginList.Count > 0 then
+ for i := 0 to PluginList.Count - 1 do begin
+ Plugin := TVFSPlugin(PluginList[i]);
+ if Length(Plugin.Extensions) > 0 then
+ for j := 0 to Length(Plugin.Extensions) - 1 do
+ if AnsiCompareText(Plugin.Extensions[j], s) = 0 then begin
+ b := True;
+ Break;
+ end;
+ if b then Break;
+ end;
+ if b then begin
+ DebugMsg(['Found plugin ''', Plugin.VFSName, ''', trying to open the archive ''', archive, '''']);
+ AEngine := TVFSEngine.Create(Plugin);
+ (AEngine as TVFSEngine).ArchiveMode := True;
+ b := b and ((AEngine as TVFSEngine).VFSOpenEx(archive) = 0);
+ end;
+ end else begin
+ AEngine := TLocalTreeEngine.Create;
+ b := True;
+ end;
+ if b then FMain.EditViewFileInternal(Self, string(PDataItem(FileList.Selected.AsPointer(0))^.AName), AEngine, True, False)
+ else Application.MessageBox(Format(LANGCannotLoadFile, [ANSIToUTF8(string(PDataItem(FileList.Selected.AsPointer(0))^.AName))]), [mbOK], mbError, mbNone, mbOK);
+ if AEngine is TVFSEngine then (AEngine as TVFSEngine).VFSClose;
+ AEngine.Free;
+end;
+
+procedure TFSearch.GoToFileButtonClick(Sender: TObject);
+begin
+ if not (Assigned(FileList.Selected) and Assigned(FileList.Selected.AsPointer(0))) then Exit;
+ GoToFile := string(PDataItem(FileList.Selected.AsPointer(0))^.AName);
+ if Assigned(PDataItem(FileList.Selected.AsPointer(0))^.LnkPointTo) then
+ GoToFileArchive := string(PDataItem(FileList.Selected.AsPointer(0))^.LnkPointTo);
+ ModalResult := mbApply;
+end;
+
+procedure TFSearch.FileListDblClick(Sender: TObject; Button: TGDKMouseButton; Shift: TShiftState; X, Y: Integer; var Accept: boolean);
+begin
+ if Assigned(FileList.Selected) and Assigned(FileList.Selected.AsPointer(0)) then GoToFileButtonClick(Sender);
+end;
+
+procedure TFSearch.FileMaskEntryKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
+var Orig, s: string;
+ i: integer;
+begin
+ case Key of
+ GDK_UP, GDK_DOWN: if Shift = [] then begin
+ Accept := False;
+ if SearchHistory.Count > 0 then begin
+ Orig := Trim(FileMaskEntry.Entry.Text);
+ i := SearchHistory.IndexOf(Orig);
+
+ if Key = GDK_DOWN then begin
+ if i < 0 then begin
+ SavedData := Orig;
+ i := 0;
+ end else
+ if SearchHistory.Count > i + 1 then Inc(i);
+ s := SearchHistory[i];
+ end else begin
+ if i < 0 then Exit else
+ if i = 0 then begin
+ s := SavedData;
+ SavedData := '';
+ end else
+ if SearchHistory.Count > i then s := SearchHistory[i - 1];
+ end;
+
+ FileMaskEntry.Entry.Text := s;
+ FileMaskEntry.Entry.SetFocus;
+ FileMaskEntry.Entry.SelectAll;
+ end;
+ end;
+ end;
+end;
+
+
+
+(********************************************************************************************************************************)
+procedure TFSearch.DoSearch;
+var FSearchThread: TSearchThread;
+ i, LastItems: integer;
+ ListItem: TGTKListItem;
+ x: Pointer;
+ OldDir: string;
+begin
+ try
+ Processing := True;
+ Stop := False;
+ FindButton.Visible := False;
+ StopButton.Visible := True;
+ StopButton.SetFocus;
+ Default := StopButton;
+ StatusLabel.Caption := Format('<span weight="ultrabold">%s</span> %s', [LANGSearch_StatusSC, LANGSearch_PreparingToSearch]);
+ StatusLabel.UseMarkup := True;
+
+ // Disable the UI
+ Table1.Enabled := False;
+ Table2.Enabled := False;
+
+ // Clear the items
+ FileList.Items.Clear;
+ if List.Count > 0 then
+ for i := List.Count - 1 downto 0 do
+ FreeDataItem(PDataItem(List[i]));
+ List.Clear;
+
+ // Save current directory
+ OldDir := Engine.GetPath;
+
+ // Set the parameters
+ FSearchThread := TSearchThread.Create(Engine);
+ with FSearchThread do begin
+ FStartPath := UTF8ToANSI(SearchInEntry.Text);
+ FFileMask := UTF8ToANSI(FileMaskEntry.Entry.Text);
+ FStringFind := UTF8ToANSI(FindTextEntry.Text);
+ FDontLeaveFS := not StayCurrentFSCheckButton.Checked;
+ FCaseSensitiveMask := CaseSensitiveMatchCheckButton.Checked;
+ FCaseSensitiveStrings := CaseSensitiveCheckButton.Checked;
+ FSearchArchives := SearchArchivesCheckButton.Checked;
+ if not BiggerThanCheckButton.Checked then FBiggerThan := -1 else begin
+ i := StrToIntDef(BiggerThanEntry.Text, -1);
+ i := i * Trunc(Power(1024, BiggerThanOptionMenu.ItemIndex));
+ FBiggerThan := i;
+ end;
+ if not SmallerThanCheckButton.Checked then FSmallerThan := -1 else begin
+ i := StrToIntDef(SmallerThanEntry.Text, -1);
+ i := i * Trunc(Power(1024, SmallerThanOptionMenu.ItemIndex));
+ FSmallerThan := i;
+ end;
+ FModifiedBetween1 := -1;
+ FModifiedBetween2 := -1;
+ FNotModifiedAfter := -1;
+ if not FUseGnomeWidgets then begin
+ if ModifiedBetweenRadioButton.Checked then begin
+ FModifiedBetween1 := StrToDateDef(ModifiedBetweenEntry1.Text, -1);
+ FModifiedBetween2 := StrToDateDef(ModifiedBetweenEntry2.Text, -1);
+ end;
+ if NotModifiedAfterRadioButton.Checked then
+ FNotModifiedAfter := StrToDateDef(NotModifiedAfterEntry.Text, -1);
+ end else begin
+ if ModifiedBetweenRadioButton.Checked then begin
+ FModifiedBetween1 := ModifiedBetweenEntry1G.Time;
+ FModifiedBetween2 := ModifiedBetweenEntry2G.Time;
+ end;
+ if NotModifiedAfterRadioButton.Checked then
+ FNotModifiedAfter := NotModifiedAfterEntryG.Time;
+ end;
+ if not ModifiedLastRadioButton.Checked then FModifiedLast := -1 else begin
+ i := StrToIntDef(ModifiedLastSpinEdit.Text, -1);
+ case ModifiedLastOptionMenu.ItemIndex of
+ 1: i := i * 7; // weeks
+ 2: i := i * 30; // months
+ 3: i := i * 365; // years
+ end;
+ FModifiedLast := i;
+ end;
+ if not ModifiedNotLastRadionButton.Checked then FModifiedNotLast := -1 else begin
+ i := StrToIntDef(ModifiedNotLastSpinEdit.Text, -1);
+ case ModifiedNotLastOptionMenu.ItemIndex of
+ 1: i := i * 7; // weeks
+ 2: i := i * 30; // months
+ 3: i := i * 365; // years
+ end;
+ FModifiedNotLast := i;
+ end;
+ end;
+
+ // UI loop
+ FSearchThread.Resume;
+ LastItems := 0;
+ repeat
+ Sleep(ConstInternalProgressTimer);
+
+ FSearchThread.GUIMutex.Acquire;
+ StatusLabel.Caption := Format('<span weight="ultrabold">%s</span> %s', [LANGSearch_SearchInProgress, FSearchThread.CurrentDir]);
+ FSearchThread.GUIMutex.Release;
+
+ StatusLabel.UseMarkup := True;
+ Application.ProcessMessages;
+
+ FSearchThread.GUIMutex.Acquire;
+ if Stop then FSearchThread.CancelIt := True;
+ if LastItems < FSearchThread.FList.Count then begin
+ for i := LastItems to FSearchThread.FList.Count - 1 do begin
+ ListItem := FileList.Items.Add;
+ ListItem.SetValue(0, FSearchThread.FList[i]);
+ if PDataItem(FSearchThread.FList[i])^.LnkPointTo <> nil
+ then ListItem.SetValue(1, Format('%s%s%s', [string(PDataItem(FSearchThread.FList[i])^.LnkPointTo), ConstPathDelim, string(PDataItem(FSearchThread.FList[i])^.AName)]))
+ else ListItem.SetValue(1, string(PDataItem(FSearchThread.FList[i])^.AName));
+ if i mod 30 = 0 then Application.ProcessMessages; // Refresh UI only after some amount of items added
+ end;
+ LastItems := FSearchThread.FList.Count;
+ end;
+ FSearchThread.GUIMutex.Release;
+
+ until FSearchThread.Finished;
+
+ if not Stop then StatusLabel.Caption := Format('<span weight="ultrabold">%s</span> (' + LANGSearch_FilesFound + ')',
+ [LANGSearch_SearchFinished, FSearchThread.FList.Count])
+ else StatusLabel.Caption := Format('<span weight="ultrabold">%s</span>', [LANGSearch_UserCancelled]);
+ StatusLabel.UseMarkup := True;
+
+ // Save the list
+ x := List;
+ List := FSearchThread.FList;
+ FSearchThread.FList := x;
+ FSearchThread.Free;
+ finally
+ StopButton.Visible := False;
+ FindButton.Visible := True;
+ Default := FindButton;
+ Processing := False;
+ Stop := False;
+ if FileList.Items.Count > 0 then FileList.SetFocus;
+ if Engine.ChangeDir(OldDir, False) <> 0 then DebugMsg(['DoSearch: cannot change back to saved directory']);
+
+ // Enable the UI
+ Table1.Enabled := True;
+ Table2.Enabled := True;
+ end;
+end;
+
+
+(********************************************************************************************************************************)
+constructor TSearchThread.Create(Engine: TPanelEngine);
+begin
+ inherited Create(True);
+ FreeOnTerminate := False;
+ GUIMutex := TCriticalSection.Create;
+ CancelIt := False;
+ Finished := False;
+ CurrentDir := '';
+ FSearchArchives := False;
+
+ FEngine := Engine;
+ FList := TList.Create;
+end;
+
+destructor TSearchThread.Destroy;
+begin
+ FList.Free;
+ GUIMutex.Free;
+ inherited Destroy;
+end;
+
+procedure TSearchThread.Execute;
+var i: integer;
+ s: string;
+begin
+ try
+ // Prepare the wildcards
+ SetLength(Wilds, 0);
+ if Length(FFileMask) > 0 then begin
+ while LastDelimiter(ConfSelItemsDelim, FFileMask) > 0 do begin
+ i := LastDelimiter(ConfSelItemsDelim, FFileMask);
+ if i < Length(FFileMask) then begin
+ s := Copy(FFileMask, i + 1, Length(FFileMask) - i);
+ Delete(FFileMask, i, Length(FFileMask) - i + 1);
+ SetLength(Wilds, Length(Wilds) + 1);
+ Wilds[Length(Wilds) - 1] := s;
+ end;
+ end;
+ if Length(FFileMask) > 0 then begin
+ SetLength(Wilds, Length(Wilds) + 1);
+ Wilds[Length(Wilds) - 1] := FFileMask;
+ end;
+ // Check for strings with no jokers ---> allow searching by partial names
+ if Length(Wilds) > 0 then
+ for i := 0 to Length(Wilds) - 1 do
+ if (Pos('*', Wilds[i]) < 1) and (Pos('?', Wilds[i]) < 1) then
+ Wilds[i] := Format('*%s*', [Wilds[i]]);
+ end;
+
+ Rekurze(ExcludeTrailingPathDelimiter(FStartPath));
+ SetLength(Wilds, 0);
+ finally
+ Finished := True;
+ end;
+end;
+
+procedure TSearchThread.Rekurze(StartDir: string);
+var LocalList: TList;
+ i, j, k: integer;
+ Matches, b: boolean;
+ FileName, s: string;
+ Data: PDataItem;
+ Plugin: TVFSPlugin;
+ xEngine: TVFSEngine;
+ VFSOpenResult: integer;
+begin
+ try
+ if CancelIt then Exit;
+ Plugin := nil;
+ if Length(StartDir) < 1 then StartDir := '/';
+ DebugMsg(['++ Entering directory ', StartDir]);
+
+ GUIMutex.Acquire;
+ CurrentDir := StartDir;
+ GUIMutex.Release;
+
+ if FEngine.ChangeDir(StartDir, False) <> 0 then Exit;
+ LocalList := TList.Create;
+ if FEngine.GetListing(LocalList, True, StartDir) = 0 then begin
+
+ // Processing...
+ StartDir := IncludeTrailingPathDelimiter(StartDir);
+ if LocalList.Count > 0 then
+ for i := 0 to LocalList.Count - 1 do begin
+ if CancelIt then Break;
+ Data := LocalList[i];
+// DebugMsg([' --- found ', Data^.AName]);
+
+ FileName := Data^.AName;
+
+ Matches := True;
+ // Test if the file is on the same FS
+ if Matches and FDontLeaveFS then
+ Matches := Matches and FEngine.IsOnSameFS(FStartPath, StartDir + FileName);
+ // File mask test
+ if Matches and (Length(Wilds) > 0) then begin
+ b := False;
+ for j := 0 to Length(Wilds) - 1 do
+ b := b or IsWild(FileName, Wilds[j], not FCaseSensitiveMask);
+ Matches := Matches and b;
+ end;
+ if not Data^.IsDir then begin // Stop matching if file is directory
+ // Size limiting
+ if Matches and (FSmallerThan > 0) then Matches := Matches and (Data^.Size <= FSmallerThan);
+ if Matches and (FBiggerThan > 0) then Matches := Matches and (Data^.Size >= FBiggerThan);
+ // Date limiting
+ if Matches and (FModifiedLast > 0) then
+ Matches := Matches and (Data^.ModifyTime <= Now) and (Data^.ModifyTime >= Now - FModifiedLast);
+ if Matches and (FModifiedNotLast > 0) then
+ Matches := Matches and ((Data^.ModifyTime > Now) or (Data^.ModifyTime <= Now - FModifiedNotLast));
+ if Matches and (FNotModifiedAfter > 0) then
+ Matches := Matches and (Data^.ModifyTime <= FNotModifiedAfter);
+ if Matches and (FModifiedBetween1 > 0) and (FModifiedBetween2 > 0) then
+ Matches := Matches and (Data^.ModifyTime >= FModifiedBetween1) and (Data^.ModifyTime <= FModifiedBetween2);
+ // Find text in file
+ if Matches and (Length(FStringFind) > 0) and (not (FEngine is TVFSEngine)) then begin
+ GUIMutex.Acquire;
+ CurrentDir := IncludeTrailingPathDelimiter(StartDir) + FileName;
+ Matches := Matches and FindText(CurrentDir);
+ CurrentDir := ExcludeTrailingPathDelimiter(StartDir);
+ GUIMutex.Release;
+ end;
+ end else
+ if (Length(FStringFind) > 0) then Matches := False; // When searching text in files, do not include directories
+
+ // Add the record to the list
+ if Matches then begin
+ GUIMutex.Acquire;
+ FList.Add(LocalList[i]);
+ Libc.free(Data^.AName);
+ PDataItem(LocalList[i])^.AName := strdup(PChar(StartDir + FileName));
+ if Assigned(PDataItem(LocalList[i])^.LnkPointTo) then begin
+ Libc.free(PDataItem(LocalList[i])^.LnkPointTo);
+ PDataItem(LocalList[i])^.LnkPointTo := nil;
+ end;
+ if FEngine is TVFSEngine then PDataItem(LocalList[i])^.LnkPointTo := strdup(PChar((FEngine as TVFSEngine).SavePath));
+ GUIMutex.Release;
+ end;
+
+ if Data^.IsDir and ((not FDontLeaveFS) or (FDontLeaveFS and FEngine.IsOnSameFS(FStartPath, StartDir + FileName)))
+ then Rekurze(IncludeTrailingPathDelimiter(StartDir) + FileName);
+
+ // Handle archives
+ if (not Data^.IsDir) and FSearchArchives and (not (FEngine is TVFSEngine)) then begin
+ b := False;
+ s := ANSIUpperCase(Trim(Copy(FileName, LastDelimiter('.', FileName) + 1, Length(FileName) - LastDelimiter('.', FileName))));
+ if (Length(s) > 1) and (s[1] = '.') then Delete(s, 1, 1);
+ if PluginList.Count > 0 then
+ for k := 0 to PluginList.Count - 1 do begin
+ Plugin := TVFSPlugin(PluginList[k]);
+ if Length(Plugin.Extensions) > 0 then
+ for j := 0 to Length(Plugin.Extensions) - 1 do
+ if AnsiCompareText(Plugin.Extensions[j], s) = 0 then begin
+ b := True;
+ Break;
+ end;
+ if b then Break;
+ end;
+ if b then begin
+ DebugMsg(['Found plugin ''', Plugin.VFSName, ''', trying to open the archive ''', FileName, '''']);
+ xEngine := TVFSEngine.Create(Plugin);
+ xEngine.ParentEngine := FEngine;
+ xEngine.ArchiveMode := True;
+ xEngine.SavePath := StartDir + FileName;
+ FEngine := xEngine;
+ VFSOpenResult := (FEngine as TVFSEngine).VFSOpenEx(IncludeTrailingPathDelimiter(StartDir) + FileName);
+ if (VFSOpenResult = 0) and (not CancelIt) then Rekurze('/');
+ FEngine := FEngine.ParentEngine;
+ if not (xEngine as TVFSEngine).VFSClose then DebugMsg(['Error closing the engine...']);
+ xEngine.Free;
+ end;
+ end;
+
+ if not Matches then Libc.free(LocalList[i]);
+ end;
+ end;
+ LocalList.Free;
+ finally
+// DebugMsg(['-- Leaving directory ', StartDir]);
+ end;
+end;
+
+function TSearchThread.FindText(FileName: string): boolean;
+const BlockSize = 65536;
+var fd: TEngineFileDes;
+ i, Error, Read, Pos: integer;
+ Buffer: PByteArray;
+ x: boolean;
+begin
+ Result := False;
+ try
+ Error := 0;
+ Buffer := Libc.malloc(BlockSize);
+ if Buffer = nil then Exit;
+ Libc.memset(Buffer, 0, BlockSize);
+ fd := FEngine.OpenFile(FileName, omRead, Error);
+ if (fd = nil) or (Error <> 0) then Exit;
+
+ Pos := 1;
+ repeat
+ Read := FEngine.ReadFile(fd, Buffer, BlockSize, Error);
+ if Read > 0 then
+ for i := 0 to Read - 1 do begin
+ if FCaseSensitiveStrings then x := Buffer^[i] = byte(FStringFind[Pos])
+ else x := ANSIUpperCase(char(Buffer^[i])) = ANSIUpperCase(FStringFind[Pos]);
+ if x then begin
+ Inc(Pos);
+ if Pos > Length(FStringFind) then begin
+ Result := True;
+ FEngine.CloseFile(fd);
+ Libc.free(Buffer);
+ Exit;
+ end;
+ end else Pos := 1;
+ end;
+
+ DebugMsg(['Read : ', Read, ' bytes.']);
+ if CancelIt then Break;
+ until Read < BlockSize;
+ FEngine.CloseFile(fd);
+ Libc.free(Buffer);
+ except
+ end;
+end;
+
+
+
+
+
+
+
+end.
+