mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Find duplicate files options
This commit is contained in:
parent
df94df6151
commit
d46ad32dfd
4 changed files with 194 additions and 8 deletions
|
|
@ -18,7 +18,7 @@ object frmFindDlg: TfrmFindDlg
|
|||
Position = poScreenCenter
|
||||
SessionProperties = 'Height;Left;Top;Width;WindowState'
|
||||
ShowInTaskBar = stAlways
|
||||
LCLVersion = '1.8.4.0'
|
||||
LCLVersion = '2.0.7.0'
|
||||
object pnlFindFile: TPanel
|
||||
Left = 3
|
||||
Height = 443
|
||||
|
|
@ -905,6 +905,82 @@ object frmFindDlg: TfrmFindDlg
|
|||
OnClick = btnAttrsHelpClick
|
||||
TabOrder = 18
|
||||
end
|
||||
object chkDuplicates: TCheckBox
|
||||
AnchorSideLeft.Control = edtAttrib
|
||||
AnchorSideTop.Control = Bevel3
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 3
|
||||
Height = 19
|
||||
Top = 263
|
||||
Width = 122
|
||||
BorderSpacing.Top = 12
|
||||
Caption = 'Find du&plicate files:'
|
||||
OnChange = chkDuplicatesChange
|
||||
TabOrder = 19
|
||||
end
|
||||
object pnlDuplicates: TPanel
|
||||
AnchorSideLeft.Control = chkDuplicates
|
||||
AnchorSideTop.Control = chkDuplicates
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 11
|
||||
Height = 19
|
||||
Top = 282
|
||||
Width = 259
|
||||
AutoSize = True
|
||||
BorderSpacing.Left = 8
|
||||
BevelOuter = bvNone
|
||||
ChildSizing.HorizontalSpacing = 8
|
||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||
ChildSizing.ControlsPerLine = 3
|
||||
ClientHeight = 19
|
||||
ClientWidth = 259
|
||||
Enabled = False
|
||||
TabOrder = 20
|
||||
object chkDuplicateName: TCheckBox
|
||||
Left = 0
|
||||
Height = 19
|
||||
Top = 0
|
||||
Width = 81
|
||||
Caption = 'same name'
|
||||
OnChange = chkDuplicateNameChange
|
||||
TabOrder = 0
|
||||
end
|
||||
object chkDuplicateSize: TCheckBox
|
||||
Left = 89
|
||||
Height = 19
|
||||
Top = 0
|
||||
Width = 70
|
||||
Caption = 'same size'
|
||||
OnChange = chkDuplicateSizeChange
|
||||
TabOrder = 1
|
||||
end
|
||||
object chkDuplicateContent: TCheckBox
|
||||
Left = 167
|
||||
Height = 19
|
||||
Top = 0
|
||||
Width = 92
|
||||
Caption = 'same content'
|
||||
OnChange = chkDuplicateContentChange
|
||||
TabOrder = 2
|
||||
end
|
||||
end
|
||||
object Bevel3: TBevel
|
||||
AnchorSideLeft.Control = tsAdvanced
|
||||
AnchorSideTop.Control = edtAttrib
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = tsAdvanced
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 6
|
||||
Height = 4
|
||||
Top = 247
|
||||
Width = 740
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Left = 6
|
||||
BorderSpacing.Top = 12
|
||||
BorderSpacing.Right = 6
|
||||
Shape = bsTopLine
|
||||
Style = bsRaised
|
||||
end
|
||||
end
|
||||
object tsPlugins: TTabSheet
|
||||
Caption = 'Plugins'
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@
|
|||
{"hash":193032515,"name":"tfrmfinddlg.lblattributes.caption","sourcebytes":[65,116,116,114,105,38,98,117,116,101,115],"value":"Attri&butes"},
|
||||
{"hash":173988,"name":"tfrmfinddlg.btnaddattribute.caption","sourcebytes":[38,65,100,100],"value":"&Add"},
|
||||
{"hash":2812976,"name":"tfrmfinddlg.btnattrshelp.caption","sourcebytes":[38,72,101,108,112],"value":"&Help"},
|
||||
{"hash":39455530,"name":"tfrmfinddlg.chkduplicates.caption","sourcebytes":[70,105,110,100,32,100,117,38,112,108,105,99,97,116,101,32,102,105,108,101,115,58],"value":"Find du&plicate files:"},
|
||||
{"hash":58146741,"name":"tfrmfinddlg.chkduplicatename.caption","sourcebytes":[115,97,109,101,32,110,97,109,101],"value":"same name"},
|
||||
{"hash":58194565,"name":"tfrmfinddlg.chkduplicatesize.caption","sourcebytes":[115,97,109,101,32,115,105,122,101],"value":"same size"},
|
||||
{"hash":266181940,"name":"tfrmfinddlg.chkduplicatecontent.caption","sourcebytes":[115,97,109,101,32,99,111,110,116,101,110,116],"value":"same content"},
|
||||
{"hash":121364483,"name":"tfrmfinddlg.tsplugins.caption","sourcebytes":[80,108,117,103,105,110,115],"value":"Plugins"},
|
||||
{"hash":125449178,"name":"tfrmfinddlg.cbuseplugin.caption","sourcebytes":[38,85,115,101,32,115,101,97,114,99,104,32,112,108,117,103,105,110,58],"value":"&Use search plugin:"},
|
||||
{"hash":91471358,"name":"tfrmfinddlg.frmcontentplugins.headercontrol.sections[0].text","sourcebytes":[80,108,117,103,105,110],"value":"Plugin"},
|
||||
|
|
|
|||
110
src/fFindDlg.pas
110
src/fFindDlg.pas
|
|
@ -66,6 +66,7 @@ type
|
|||
actStart: TAction;
|
||||
actList: TActionList;
|
||||
Bevel2: TBevel;
|
||||
Bevel3: TBevel;
|
||||
btnAddAttribute: TButton;
|
||||
btnAttrsHelp: TButton;
|
||||
btnClose: TButton;
|
||||
|
|
@ -100,6 +101,10 @@ type
|
|||
cbTextRegExp: TCheckBox;
|
||||
cbFindInArchive: TCheckBox;
|
||||
cbOpenedTabs: TCheckBox;
|
||||
chkDuplicateContent: TCheckBox;
|
||||
chkDuplicateSize: TCheckBox;
|
||||
chkDuplicateName: TCheckBox;
|
||||
chkDuplicates: TCheckBox;
|
||||
chkHex: TCheckBox;
|
||||
cmbExcludeDirectories: TComboBoxWithDelItems;
|
||||
cmbNotOlderThanUnit: TComboBox;
|
||||
|
|
@ -133,6 +138,7 @@ type
|
|||
miShowInEditor: TMenuItem;
|
||||
miShowAllFound: TMenuItem;
|
||||
miRemoveFromLlist: TMenuItem;
|
||||
pnlDuplicates: TPanel;
|
||||
pnlDirectoriesDepth: TPanel;
|
||||
pnlLoadSaveBottomButtons: TPanel;
|
||||
pnlLoadSaveBottom: TPanel;
|
||||
|
|
@ -211,6 +217,10 @@ type
|
|||
procedure cbRegExpChange(Sender: TObject);
|
||||
procedure cbTextRegExpChange(Sender: TObject);
|
||||
procedure cbSelectedFilesChange(Sender: TObject);
|
||||
procedure chkDuplicateContentChange(Sender: TObject);
|
||||
procedure chkDuplicateNameChange(Sender: TObject);
|
||||
procedure chkDuplicatesChange(Sender: TObject);
|
||||
procedure chkDuplicateSizeChange(Sender: TObject);
|
||||
procedure chkHexChange(Sender: TObject);
|
||||
procedure cmbEncodingSelect(Sender: TObject);
|
||||
procedure cbFindTextChange(Sender: TObject);
|
||||
|
|
@ -301,6 +311,7 @@ type
|
|||
procedure OnAddAttribute(Sender: TObject);
|
||||
function InvalidRegExpr(AChecked: boolean; const ARegExpr: string): boolean;
|
||||
procedure SetWindowCaption(AWindowCaptionStyle: byte);
|
||||
function ObjectType(Index: Integer): TCheckBoxState;
|
||||
function GetFileMask: String;
|
||||
public
|
||||
FoundedStringCopy: TStringList;
|
||||
|
|
@ -376,9 +387,10 @@ implementation
|
|||
uses
|
||||
LCLProc, LCLType, LConvEncoding, StrUtils, HelpIntfs, fViewer, fMain,
|
||||
uLng, uGlobs, uShowForm, uDCUtils, uFileSource, uFileSourceUtil,
|
||||
uSearchResultFileSource, uFile,
|
||||
uSearchResultFileSource, uFile, uFileProperty, uColumnsFileView,
|
||||
uFileViewNotebook, uKeyboard, uOSUtils, uArchiveFileSourceUtil,
|
||||
DCOSUtils, RegExpr, uDebug, uShowMsg, uConvEncoding;
|
||||
DCOSUtils, RegExpr, uDebug, uShowMsg, uConvEncoding, uColumns,
|
||||
uFileFunctions;
|
||||
|
||||
const
|
||||
TimeUnitToComboIndex: array[TTimeUnit] of integer = (0, 1, 2, 3, 4, 5, 6);
|
||||
|
|
@ -1014,6 +1026,34 @@ begin
|
|||
cmbFindPathStart.Enabled := not cbSelectedFiles.Checked;
|
||||
end;
|
||||
|
||||
procedure TfrmFindDlg.chkDuplicateContentChange(Sender: TObject);
|
||||
begin
|
||||
if chkDuplicateContent.Checked then chkDuplicateSize.Checked:= True;
|
||||
chkDuplicateNameChange(chkDuplicateName);
|
||||
end;
|
||||
|
||||
procedure TfrmFindDlg.chkDuplicateNameChange(Sender: TObject);
|
||||
begin
|
||||
if not (chkDuplicateName.Checked or chkDuplicateSize.Checked) then
|
||||
chkDuplicates.Checked:= False;
|
||||
end;
|
||||
|
||||
procedure TfrmFindDlg.chkDuplicatesChange(Sender: TObject);
|
||||
begin
|
||||
pnlDuplicates.Enabled:= chkDuplicates.Checked;
|
||||
if chkDuplicates.Checked then
|
||||
begin
|
||||
if not (chkDuplicateName.Checked or chkDuplicateSize.Checked) then
|
||||
chkDuplicateName.Checked:= True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmFindDlg.chkDuplicateSizeChange(Sender: TObject);
|
||||
begin
|
||||
if not chkDuplicateSize.Checked then chkDuplicateContent.Checked:= False;
|
||||
chkDuplicateNameChange(chkDuplicateName);
|
||||
end;
|
||||
|
||||
procedure TfrmFindDlg.chkHexChange(Sender: TObject);
|
||||
begin
|
||||
if chkHex.Checked then
|
||||
|
|
@ -1124,6 +1164,11 @@ begin
|
|||
NotContainingText := cbNotContainingText.Checked;
|
||||
TextRegExp := cbTextRegExp.Checked;
|
||||
TextEncoding := cmbEncoding.Text;
|
||||
{ Duplicates }
|
||||
Duplicates:= chkDuplicates.Checked;
|
||||
DuplicateName:= chkDuplicateName.Checked;
|
||||
DuplicateSize:= chkDuplicateSize.Checked;
|
||||
DuplicateContent:= chkDuplicateContent.Checked;
|
||||
{ Plugins }
|
||||
SearchPlugin := cmbPlugin.Text;
|
||||
frmContentPlugins.Save(FindOptions);
|
||||
|
|
@ -1608,7 +1653,7 @@ begin
|
|||
if pgcSearch.ActivePage = tsResults then
|
||||
if lsFoundedFiles.ItemIndex <> -1 then
|
||||
begin
|
||||
if (lsFoundedFiles.Items.Objects[lsFoundedFiles.ItemIndex] <> nil) then
|
||||
if (ObjectType(lsFoundedFiles.ItemIndex) = cbChecked) then
|
||||
msgError(rsMsgErrNotSupported)
|
||||
else
|
||||
ShowViewerByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
|
||||
|
|
@ -1621,7 +1666,7 @@ begin
|
|||
if pgcSearch.ActivePage = tsResults then
|
||||
if lsFoundedFiles.ItemIndex <> -1 then
|
||||
begin
|
||||
if (lsFoundedFiles.Items.Objects[lsFoundedFiles.ItemIndex] <> nil) then
|
||||
if (ObjectType(lsFoundedFiles.ItemIndex) = cbChecked) then
|
||||
msgError(rsMsgErrNotSupported)
|
||||
else
|
||||
ShowEditorByGlob(lsFoundedFiles.Items[lsFoundedFiles.ItemIndex]);
|
||||
|
|
@ -1640,7 +1685,7 @@ begin
|
|||
try
|
||||
StopSearch;
|
||||
TargetFile := lsFoundedFiles.Items[lsFoundedFiles.ItemIndex];
|
||||
if (lsFoundedFiles.Items.Objects[lsFoundedFiles.ItemIndex] <> nil) then
|
||||
if (ObjectType(lsFoundedFiles.ItemIndex) = cbChecked) then
|
||||
begin
|
||||
ArchiveFile := ExtractWord(1, TargetFile, [ReversePathDelim]);
|
||||
TargetFile := PathDelim + ExtractWord(2, TargetFile, [ReversePathDelim]);
|
||||
|
|
@ -1674,6 +1719,8 @@ end;
|
|||
|
||||
{ TfrmFindDlg.cm_FeedToListbox }
|
||||
procedure TfrmFindDlg.cm_FeedToListbox(const Params: array of string);
|
||||
const
|
||||
PluginDuplicate = 'Plugin().Duplicate{}';
|
||||
var
|
||||
I: integer;
|
||||
sFileName: string;
|
||||
|
|
@ -1682,6 +1729,9 @@ var
|
|||
aFile: TFile;
|
||||
Notebook: TFileViewNotebook;
|
||||
NewPage: TFileViewPage;
|
||||
DCFunc: String;
|
||||
AProperty: TFileVariantProperty;
|
||||
ANewSet: TPanelColumnsClass;
|
||||
begin
|
||||
StopSearch;
|
||||
|
||||
|
|
@ -1691,6 +1741,12 @@ begin
|
|||
sFileName := lsFoundedFiles.Items[I];
|
||||
try
|
||||
aFile := TFileSystemFileSource.CreateFileFromFile(sFileName);
|
||||
if FLastSearchTemplate.SearchRecord.Duplicates then
|
||||
begin
|
||||
AProperty:= TFileVariantProperty.Create(PluginDuplicate);
|
||||
AProperty.Value:= IntPtr(lsFoundedFiles.Items.Objects[I]);
|
||||
aFile.Properties[fpVariant]:= AProperty;
|
||||
end;
|
||||
FileList.AddSubNode(aFile);
|
||||
except
|
||||
on EFileNotFound do ;
|
||||
|
|
@ -1705,6 +1761,27 @@ begin
|
|||
// Add new tab for search results.
|
||||
Notebook := frmMain.ActiveNotebook;
|
||||
NewPage := Notebook.NewPage(Notebook.ActiveView);
|
||||
|
||||
if FLastSearchTemplate.SearchRecord.Duplicates then
|
||||
begin
|
||||
if not (NewPage.FileView is TColumnsFileView) then
|
||||
begin
|
||||
frmMain.Commands.cm_ColumnsView([]);
|
||||
end;
|
||||
|
||||
ANewSet:= TPanelColumnsClass.Create;
|
||||
DCFunc := '[' + sFuncTypeDC + '().%s{}]';
|
||||
I:= Notebook.ActiveView.ClientWidth;
|
||||
ANewSet.Add(rsFuncName, Format(DCFunc, [TFileFunctionStrings[fsfName]]), I * 40 div 100, taLeftJustify);
|
||||
ANewSet.Add(rsFuncGroup, '[' + PluginDuplicate + ']', I * 20 div 100, taCenter);
|
||||
ANewSet.Add(rsFuncPath, Format(DCFunc, [TFileFunctionStrings[fsfPath]]), I * 40 div 100, taLeftJustify);
|
||||
|
||||
TColumnsFileView(NewPage.FileView).isSlave:= True;
|
||||
TColumnsFileView(NewPage.FileView).ActiveColmSlave:= ANewSet;
|
||||
|
||||
TColumnsFileView(NewPage.FileView).UpdateColumnsView;
|
||||
end;
|
||||
|
||||
NewPage.FileView.AddFileSource(SearchResultFS, SearchResultFS.GetRootDir);
|
||||
NewPage.FileView.FlatView := True;
|
||||
NewPage.MakeActive;
|
||||
|
|
@ -1882,6 +1959,20 @@ begin
|
|||
Caption := sBuildingCaptionName;
|
||||
end;
|
||||
|
||||
function TfrmFindDlg.ObjectType(Index: Integer): TCheckBoxState;
|
||||
var
|
||||
ATemp: TObject;
|
||||
AValue: PtrInt absolute ATemp;
|
||||
begin
|
||||
ATemp:= lsFoundedFiles.Items.Objects[Index];
|
||||
if (ATemp) = nil then
|
||||
Result:= cbUnchecked
|
||||
else if (AValue = High(PtrInt)) then
|
||||
Result:= cbChecked
|
||||
else
|
||||
Result:= cbGrayed;
|
||||
end;
|
||||
|
||||
function TfrmFindDlg.GetFileMask: String;
|
||||
begin
|
||||
if Length(cmbFindFileMask.Text) = 0 then
|
||||
|
|
@ -2061,6 +2152,11 @@ begin
|
|||
cbNotContainingText.Checked := NotContainingText;
|
||||
cbTextRegExp.Checked := TextRegExp;
|
||||
cmbEncoding.Text := TextEncoding;
|
||||
// duplicates
|
||||
chkDuplicates.Checked := Duplicates;
|
||||
chkDuplicateName.Checked := DuplicateName;
|
||||
chkDuplicateSize.Checked := DuplicateSize;
|
||||
chkDuplicateContent.Checked := DuplicateContent;
|
||||
// plugins
|
||||
cmbPlugin.Text := SearchPlugin;
|
||||
frmContentPlugins.Load(Template);
|
||||
|
|
@ -2410,8 +2506,8 @@ procedure TfrmFindDlg.PopupMenuFindPopup(Sender: TObject);
|
|||
begin
|
||||
if (lsFoundedFiles.ItemIndex <> -1) then
|
||||
begin
|
||||
miShowInViewer.Enabled:= (lsFoundedFiles.Items.Objects[lsFoundedFiles.ItemIndex] = nil);
|
||||
miShowInEditor.Enabled:= (lsFoundedFiles.Items.Objects[lsFoundedFiles.ItemIndex] = nil);
|
||||
miShowInViewer.Enabled:= (ObjectType(lsFoundedFiles.ItemIndex) <> cbChecked);
|
||||
miShowInEditor.Enabled:= (ObjectType(lsFoundedFiles.ItemIndex) <> cbChecked);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -778,6 +778,11 @@ procedure TColumnsFileView.SetColumnSet(const AName: String);
|
|||
begin
|
||||
if ColSet.Items.IndexOf(AName) >= 0 then
|
||||
begin
|
||||
if Assigned(ActiveColmSlave) then
|
||||
begin
|
||||
isSlave:= False;
|
||||
FreeAndNil(ActiveColmSlave);
|
||||
end;
|
||||
ActiveColm:= AName;
|
||||
UpdateColumnsView;
|
||||
RedrawFiles;
|
||||
|
|
@ -794,6 +799,11 @@ begin
|
|||
else
|
||||
begin
|
||||
ActiveColm:=ColSet.Items[(Sender as TMenuItem).Tag];
|
||||
if Assigned(ActiveColmSlave) then
|
||||
begin
|
||||
isSlave:= False;
|
||||
FreeAndNil(ActiveColmSlave);
|
||||
end;
|
||||
UpdateColumnsView;
|
||||
RedrawFiles;
|
||||
end;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue