doublecmd/src/fselectduplicates.pas
2020-08-29 12:21:45 +00:00

243 lines
6.8 KiB
ObjectPascal

unit fSelectDuplicates;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons, StdCtrls,
ExtCtrls, KASComboBox, uFileView;
type
{ TfrmSelectDuplicates }
TfrmSelectDuplicates = class(TForm)
btnApply: TBitBtn;
btnCancel: TBitBtn;
btnOK: TBitBtn;
btnIncludeMask: TSpeedButton;
btnExcludeMask: TSpeedButton;
cmbFirstMethod: TComboBoxAutoWidth;
cmbIncludeMask: TComboBox;
cmbExcludeMask: TComboBox;
chkLeaveUnselected: TCheckBox;
cmbSecondMethod: TComboBoxAutoWidth;
lblIncludeMask: TLabel;
lblExcludeMask: TLabel;
lblFirstMethod: TLabel;
lblSecondMethod: TLabel;
pnlMethods: TPanel;
pnlButtons: TPanel;
procedure btnApplyClick(Sender: TObject);
procedure btnIncludeMaskClick(Sender: TObject);
procedure cmbFirstMethodChange(Sender: TObject);
private
FFileView: TFileView;
private
procedure ButtonsAutosize;
end;
procedure ShowSelectDuplicates(TheOwner: TCustomForm; AFileView: TFileView);
implementation
{$R *.lfm}
uses
uFile, uFileSorting, uFileFunctions, uDisplayFile, uFileProperty, uTypes,
uGlobs, fMaskInputDlg, uLng, uSearchTemplate, DCStrUtils;
procedure ShowSelectDuplicates(TheOwner: TCustomForm; AFileView: TFileView);
begin
with TfrmSelectDuplicates.Create(TheOwner) do
begin
ButtonsAutosize;
FFileView:= AFileView;
cmbFirstMethod.ItemIndex:= 0;
cmbSecondMethod.ItemIndex:= 2;
cmbIncludeMask.Items.Assign(glsMaskHistory);
cmbExcludeMask.Items.Assign(glsMaskHistory);
// Localize methods
ParseLineToList(rsSelectDuplicateMethod, cmbFirstMethod.Items);
ParseLineToList(rsSelectDuplicateMethod, cmbSecondMethod.Items);
cmbSecondMethod.Items.Delete(cmbSecondMethod.Items.Count - 1);
cmbSecondMethod.Items.Delete(cmbSecondMethod.Items.Count - 1);
if ShowModal = mrOK then
begin
btnApplyClick(btnApply);
end;
Free;
end;
end;
{ TfrmSelectDuplicates }
procedure TfrmSelectDuplicates.cmbFirstMethodChange(Sender: TObject);
begin
cmbSecondMethod.Enabled:= cmbFirstMethod.ItemIndex < 4;
end;
procedure TfrmSelectDuplicates.btnApplyClick(Sender: TObject);
var
ARange: TRange;
Index, J: Integer;
ASelected: Integer;
AFiles: TDisplayFiles;
AGroup, AValue: Variant;
NewSorting: TFileSortings = nil;
begin
FFileView.MarkGroup(cmbIncludeMask.Text, True);
if Length(cmbExcludeMask.Text) > 0 then begin
FFileView.MarkGroup(cmbExcludeMask.Text, False);
end;
if not chkLeaveUnselected.Checked then Exit;
AFiles:= FFileView.DisplayFiles;
// First sort by group
SetLength(NewSorting, 1);
SetLength(NewSorting[0].SortFunctions, 1);
NewSorting[0].SortFunctions[0] := fsfVariant;
NewSorting[0].SortDirection := sdAscending;
case cmbFirstMethod.ItemIndex of
0, 1: // Newest/Oldest
begin
SetLength(NewSorting, 2);
SetLength(NewSorting[1].SortFunctions, 1);
NewSorting[1].SortFunctions[0] := fsfModificationTime;
if (cmbFirstMethod.ItemIndex = 1) then
// First item will be Oldest
NewSorting[1].SortDirection := sdAscending
else begin
// First item will be Newest
NewSorting[1].SortDirection := sdDescending;
end;
end;
2, 3: // Largest/Smallest
begin
SetLength(NewSorting, 2);
SetLength(NewSorting[1].SortFunctions, 1);
NewSorting[1].SortFunctions[0] := fsfSize;
if (cmbFirstMethod.ItemIndex = 3) then
// First item will be Smallest
NewSorting[1].SortDirection := sdAscending
else begin
// First item will be Largest
NewSorting[1].SortDirection := sdDescending;
end;
end;
end;
if cmbSecondMethod.Enabled then
begin
case cmbSecondMethod.ItemIndex of
0, 1:
begin
SetLength(NewSorting, 3);
SetLength(NewSorting[2].SortFunctions, 1);
NewSorting[2].SortFunctions[0] := fsfModificationTime;
if (cmbSecondMethod.ItemIndex = 1) then
NewSorting[2].SortDirection := sdAscending
else begin
NewSorting[2].SortDirection := sdDescending;
end;
end;
2, 3:
begin
SetLength(NewSorting, 3);
SetLength(NewSorting[2].SortFunctions, 1);
NewSorting[2].SortFunctions[0] := fsfSize;
if (cmbSecondMethod.ItemIndex = 3) then
NewSorting[2].SortDirection := sdAscending
else begin
NewSorting[2].SortDirection := sdDescending;
end;
end;
end;
end;
FFileView.Sorting:= NewSorting;
// Skip '..' item
if AFiles[0].FSFile.IsNameValid then
ARange.First:= 0
else begin
ARange.First:= 1;
end;
AGroup:= TFileVariantProperty(AFiles[ARange.First].FSFile.Properties[fpVariant]).Value;
for Index:= ARange.First + 1 to AFiles.Count - 1 do
begin
AValue:= TFileVariantProperty(AFiles[Index].FSFile.Properties[fpVariant]).Value;
if (AValue <> AGroup) then
begin
ASelected:= 0;
ARange.Last:= Index - 1;
for J:= ARange.First to ARange.Last do
begin
if AFiles[J].Selected then Inc(ASelected);
end;
// Selected all files in the group
if ASelected = (Index - ARange.First) then
begin
if cmbFirstMethod.ItemIndex = 5 then
AFiles[ARange.Last].Selected:= False
else begin
AFiles[ARange.First].Selected:= False;
end;
end;
AGroup:= AValue;
ARange.First:= Index;
end;
end;
end;
procedure TfrmSelectDuplicates.btnIncludeMaskClick(Sender: TObject);
var
sMask: String;
bTemplate: Boolean;
AComboBox: TComboBox;
begin
if Sender = btnIncludeMask then
AComboBox:= cmbIncludeMask
else begin
AComboBox:= cmbExcludeMask;
end;
sMask:= AComboBox.Text;
if ShowMaskInputDlg(rsMarkPlus, rsMaskInput, glsMaskHistory, sMask) then
begin
bTemplate:= IsMaskSearchTemplate(sMask);
AComboBox.Enabled:= not bTemplate;
AComboBox.Text:= sMask;
end;
end;
procedure TfrmSelectDuplicates.ButtonsAutosize;
var
Index: Integer;
AControl: TControl;
AMaxWidth, AMaxHeight: Integer;
begin
AMaxWidth:= 0;
AMaxHeight:= 0;
for Index:= 0 to pnlButtons.ControlCount - 1 do
begin
AControl:= pnlButtons.Controls[Index];
if AControl.Width > AMaxWidth then AMaxWidth:= AControl.Width;
if AControl.Height > AMaxHeight then AMaxHeight:= AControl.Height;
end;
for Index:= 0 to pnlButtons.ControlCount - 1 do
begin
AControl:= pnlButtons.Controls[Index];
AControl.Constraints.MinWidth:= AMaxWidth;
AControl.Constraints.MinHeight:= AMaxHeight;
end;
end;
end.