mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Differ - show compare progress at start
This commit is contained in:
parent
36791a9b7e
commit
fc5ad2b0c3
4 changed files with 239 additions and 108 deletions
|
|
@ -749,4 +749,9 @@ object frmDiffer: TfrmDiffer
|
|||
left = 352
|
||||
top = 136
|
||||
end
|
||||
object tmProgress: TTimer
|
||||
OnTimer = tmProgressTimer
|
||||
Left = 568
|
||||
Top = 170
|
||||
end
|
||||
end
|
||||
|
|
|
|||
346
src/fdiffer.pas
346
src/fdiffer.pas
|
|
@ -29,7 +29,7 @@ uses
|
|||
Classes, SysUtils, FileUtil, Forms, Controls, Dialogs, Menus, ComCtrls,
|
||||
ActnList, ExtCtrls, EditBtn, Buttons, SynEdit, uSynDiffControls,
|
||||
uPariterControls, uDiffOND, uFormCommands, uHotkeyManager, uOSForms,
|
||||
uBinaryDiffViewer, uShowForm, KASStatusBar, Graphics;
|
||||
uBinaryDiffViewer, uShowForm, KASStatusBar, Graphics, StdCtrls;
|
||||
|
||||
type
|
||||
|
||||
|
|
@ -148,6 +148,7 @@ type
|
|||
pmEncodingRight: TPopupMenu;
|
||||
Splitter: TSplitter;
|
||||
StatusBar: TStatusBar;
|
||||
tmProgress: TTimer;
|
||||
ToolBar: TToolBar;
|
||||
btnSave: TToolButton;
|
||||
btnSaveAs: TToolButton;
|
||||
|
|
@ -201,6 +202,8 @@ type
|
|||
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure FormResize(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure btnCancelClick(Sender: TObject);
|
||||
procedure tmProgressTimer(Sender: TObject);
|
||||
private
|
||||
BinaryDiffList: TFPList;
|
||||
BinaryDiffIndex: Integer;
|
||||
|
|
@ -220,10 +223,17 @@ type
|
|||
EncodingList: TStringList;
|
||||
ScrollLock: LongInt;
|
||||
FShowIdentical: Boolean;
|
||||
FModal: Boolean;
|
||||
FCancel: Boolean;
|
||||
frmProgress: TForm;
|
||||
FWaitData: TWaitData;
|
||||
FElevate: TDuplicates;
|
||||
FCommands: TFormCommands;
|
||||
private
|
||||
procedure ShowDialog;
|
||||
procedure ShowIdentical;
|
||||
procedure ShowProgressDialog;
|
||||
procedure CloseProgressDialog;
|
||||
procedure Clear(bLeft, bRight: Boolean);
|
||||
procedure BuildHashList(bLeft, bRight: Boolean);
|
||||
procedure ChooseEncoding(SynDiffEdit: TSynDiffEdit);
|
||||
|
|
@ -266,7 +276,7 @@ implementation
|
|||
{$R *.lfm}
|
||||
|
||||
uses
|
||||
LCLType, LazFileUtils, LConvEncoding, SynEditTypes, uHash, uLng, uGlobs,
|
||||
Math, LCLType, LazFileUtils, LConvEncoding, SynEditTypes, uHash, uLng, uGlobs,
|
||||
uShowMsg, DCClassesUtf8, dmCommonData, uDCUtils, uConvEncoding, uAdministrator;
|
||||
|
||||
const
|
||||
|
|
@ -279,27 +289,27 @@ begin
|
|||
Differ := TfrmDiffer.Create(Application);
|
||||
with Differ do
|
||||
begin
|
||||
FModal := Modal;
|
||||
FWaitData := WaitData;
|
||||
FShowIdentical := True;
|
||||
edtFileNameLeft.Text:= FileNameLeft;
|
||||
edtFileNameRight.Text:= FileNameRight;
|
||||
FShowIdentical:= actAutoCompare.Checked;
|
||||
SetColors(gDifferAddedColor, gDifferDeletedColor, gDifferModifiedColor);
|
||||
if not (FileIsText(FileNameLeft) and FileIsText(FileNameRight)) then
|
||||
actBinaryCompare.Execute
|
||||
else begin
|
||||
OpenFileLeft(FileNameLeft);
|
||||
OpenFileRight(FileNameRight);
|
||||
if actAutoCompare.Checked then actStartCompare.Execute;
|
||||
end;
|
||||
FShowIdentical:= FShowIdentical and actStartCompare.Enabled;
|
||||
if actBinaryCompare.Checked or (FShowIdentical = False) then
|
||||
begin
|
||||
if Modal then
|
||||
ShowModal
|
||||
else if (WaitData = nil) then
|
||||
ShowOnTop
|
||||
else
|
||||
WaitData.ShowOnTop(Differ);
|
||||
try
|
||||
if not (FileIsText(FileNameLeft) and FileIsText(FileNameRight)) then
|
||||
actBinaryCompare.Execute
|
||||
else begin
|
||||
OpenFileLeft(FileNameLeft);
|
||||
OpenFileRight(FileNameRight);
|
||||
actStartCompare.Execute;
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
tmProgress.Enabled:= False;
|
||||
msgError(E.Message);
|
||||
Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -312,101 +322,113 @@ var
|
|||
LineNumberLeft,
|
||||
LineNumberRight: PtrInt;
|
||||
begin
|
||||
if actBinaryCompare.Checked then
|
||||
begin
|
||||
if (BinaryViewerLeft.IsFileOpen and BinaryViewerRight.IsFileOpen) then
|
||||
FCancel:= False;
|
||||
try
|
||||
if actBinaryCompare.Checked then
|
||||
begin
|
||||
if (BinaryViewerLeft.IsFileOpen and BinaryViewerRight.IsFileOpen) then
|
||||
begin
|
||||
actStartCompare.Enabled := False;
|
||||
actCancelCompare.Enabled := True;
|
||||
actBinaryCompare.Enabled := False;
|
||||
BinaryCompare:= TBinaryCompare.Create(BinaryViewerLeft.GetDataAdr,
|
||||
BinaryViewerRight.GetDataAdr,
|
||||
BinaryViewerLeft.FileSize,
|
||||
BinaryViewerRight.FileSize,
|
||||
BinaryDiffList);
|
||||
|
||||
BinaryCompare.OnFinish:= @BinaryCompareFinish;
|
||||
BinaryCompare.Start;
|
||||
end;
|
||||
end
|
||||
else try
|
||||
Inc(ScrollLock);
|
||||
Screen.Cursor := crHourGlass;
|
||||
|
||||
if SynDiffEditLeft.Modified then SynDiffEditLeft.Lines.RemoveFake;
|
||||
if SynDiffEditRight.Modified then SynDiffEditRight.Lines.RemoveFake;
|
||||
BuildHashList(SynDiffEditLeft.Modified, SynDiffEditRight.Modified);
|
||||
|
||||
if (Length(HashListLeft) = 0) or (Length(HashListRight) = 0) then
|
||||
begin
|
||||
FCancel := True;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
actStartCompare.Enabled := False;
|
||||
actCancelCompare.Enabled := True;
|
||||
actBinaryCompare.Enabled := False;
|
||||
BinaryCompare:= TBinaryCompare.Create(BinaryViewerLeft.GetDataAdr,
|
||||
BinaryViewerRight.GetDataAdr,
|
||||
BinaryViewerLeft.FileSize,
|
||||
BinaryViewerRight.FileSize,
|
||||
BinaryDiffList);
|
||||
|
||||
BinaryCompare.OnFinish:= @BinaryCompareFinish;
|
||||
BinaryCompare.Start;
|
||||
end;
|
||||
end
|
||||
else try
|
||||
Inc(ScrollLock);
|
||||
Screen.Cursor := crHourGlass;
|
||||
Diff.Execute(
|
||||
PInteger(@HashListLeft[0]),
|
||||
PInteger(@HashListRight[0]),
|
||||
Length(HashListLeft),
|
||||
Length(HashListRight)
|
||||
);
|
||||
|
||||
if SynDiffEditLeft.Modified then SynDiffEditLeft.Lines.RemoveFake;
|
||||
if SynDiffEditRight.Modified then SynDiffEditRight.Lines.RemoveFake;
|
||||
BuildHashList(SynDiffEditLeft.Modified, SynDiffEditRight.Modified);
|
||||
tmProgress.Enabled:= False;
|
||||
if Diff.Cancelled then Exit;
|
||||
|
||||
if (Length(HashListLeft) = 0) or (Length(HashListRight) = 0) then Exit;
|
||||
actStartCompare.Enabled := False;
|
||||
actCancelCompare.Enabled := True;
|
||||
SynDiffEditLeft.StartCompare;
|
||||
SynDiffEditRight.StartCompare;
|
||||
|
||||
Diff.Execute(
|
||||
PInteger(@HashListLeft[0]),
|
||||
PInteger(@HashListRight[0]),
|
||||
Length(HashListLeft),
|
||||
Length(HashListRight)
|
||||
);
|
||||
|
||||
if Diff.Cancelled then Exit;
|
||||
|
||||
SynDiffEditLeft.StartCompare;
|
||||
SynDiffEditRight.StartCompare;
|
||||
|
||||
for I := 0 to Diff.Count - 1 do
|
||||
with Diff.Compares[I] do
|
||||
begin
|
||||
LineNumberLeft:= oldIndex1 + 1;
|
||||
LineNumberRight:= oldIndex2 + 1;
|
||||
case Kind of
|
||||
ckAdd:
|
||||
begin
|
||||
SynDiffEditLeft.Lines.InsertFake(I, Kind);
|
||||
SynDiffEditRight.Lines.SetKindAndNumber(I, Kind, LineNumberRight);
|
||||
end;
|
||||
ckDelete:
|
||||
begin
|
||||
SynDiffEditLeft.Lines.SetKindAndNumber(I, Kind, LineNumberLeft);
|
||||
SynDiffEditRight.Lines.InsertFake(I, Kind);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
SynDiffEditLeft.Lines.SetKindAndNumber(I, Kind, LineNumberLeft);
|
||||
SynDiffEditRight.Lines.SetKindAndNumber(I, Kind, LineNumberRight);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
with Diff.DiffStats do
|
||||
begin
|
||||
StatusBar.Panels[0].Text := rsDiffMatches + IntToStr(matches);
|
||||
StatusBar.Panels[1].Text := rsDiffModifies + IntToStr(modifies);
|
||||
StatusBar.Panels[2].Text := rsDiffAdds + IntToStr(adds);
|
||||
StatusBar.Panels[3].Text := rsDiffDeletes + IntToStr(deletes);
|
||||
if FShowIdentical then
|
||||
for I := 0 to Diff.Count - 1 do
|
||||
with Diff.Compares[I] do
|
||||
begin
|
||||
FShowIdentical:= (modifies = 0) and (adds = 0) and (deletes = 0);
|
||||
if FShowIdentical then
|
||||
ShowIdentical
|
||||
else begin
|
||||
FShowIdentical:= False;
|
||||
Application.QueueAsyncCall(@ShowFirstDifference, 0);
|
||||
LineNumberLeft:= oldIndex1 + 1;
|
||||
LineNumberRight:= oldIndex2 + 1;
|
||||
case Kind of
|
||||
ckAdd:
|
||||
begin
|
||||
SynDiffEditLeft.Lines.InsertFake(I, Kind);
|
||||
SynDiffEditRight.Lines.SetKindAndNumber(I, Kind, LineNumberRight);
|
||||
end;
|
||||
ckDelete:
|
||||
begin
|
||||
SynDiffEditLeft.Lines.SetKindAndNumber(I, Kind, LineNumberLeft);
|
||||
SynDiffEditRight.Lines.InsertFake(I, Kind);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
SynDiffEditLeft.Lines.SetKindAndNumber(I, Kind, LineNumberLeft);
|
||||
SynDiffEditRight.Lines.SetKindAndNumber(I, Kind, LineNumberRight);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
with Diff.DiffStats do
|
||||
begin
|
||||
StatusBar.Panels[0].Text := rsDiffMatches + IntToStr(matches);
|
||||
StatusBar.Panels[1].Text := rsDiffModifies + IntToStr(modifies);
|
||||
StatusBar.Panels[2].Text := rsDiffAdds + IntToStr(adds);
|
||||
StatusBar.Panels[3].Text := rsDiffDeletes + IntToStr(deletes);
|
||||
if FShowIdentical then
|
||||
begin
|
||||
CloseProgressDialog;
|
||||
FShowIdentical:= (modifies = 0) and (adds = 0) and (deletes = 0);
|
||||
if FShowIdentical then
|
||||
ShowIdentical
|
||||
else begin
|
||||
FShowIdentical:= False;
|
||||
Application.QueueAsyncCall(@ShowFirstDifference, 0);
|
||||
ShowDialog;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
SynDiffEditLeft.FinishCompare;
|
||||
SynDiffEditRight.FinishCompare;
|
||||
Screen.Cursor := crDefault;
|
||||
actStartCompare.Enabled := True;
|
||||
actCancelCompare.Enabled := False;
|
||||
Dec(ScrollLock);
|
||||
end;
|
||||
if actLineDifferences.Checked then
|
||||
begin
|
||||
SynDiffEditLeft.Highlighter:= SynDiffHighlighterLeft;
|
||||
SynDiffEditRight.Highlighter:= SynDiffHighlighterRight;
|
||||
end;
|
||||
finally
|
||||
SynDiffEditLeft.FinishCompare;
|
||||
SynDiffEditRight.FinishCompare;
|
||||
Screen.Cursor := crDefault;
|
||||
actStartCompare.Enabled := True;
|
||||
actCancelCompare.Enabled := False;
|
||||
Dec(ScrollLock);
|
||||
if FShowIdentical and FCancel then Free;
|
||||
end;
|
||||
if actLineDifferences.Checked then
|
||||
begin
|
||||
SynDiffEditLeft.Highlighter:= SynDiffHighlighterLeft;
|
||||
SynDiffEditRight.Highlighter:= SynDiffHighlighterRight;
|
||||
end;
|
||||
//mnuEdit.Enabled := true;
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.actOpenLeftExecute(Sender: TObject);
|
||||
|
|
@ -529,6 +551,13 @@ begin
|
|||
finally
|
||||
PushPop(FElevate);
|
||||
end;
|
||||
if FShowIdentical then
|
||||
begin
|
||||
if not BinaryViewerLeft.IsFileOpen then
|
||||
raise EFOpenError.Create(BinaryViewerLeft.LastError + LineEnding + edtFileNameLeft.Text);
|
||||
if not BinaryViewerRight.IsFileOpen then
|
||||
raise EFOpenError.Create(BinaryViewerRight.LastError + LineEnding + edtFileNameRight.Text);
|
||||
end;
|
||||
StatusBar.Panels[0].Text := EmptyStr;
|
||||
StatusBar.Panels[1].Text := EmptyStr;
|
||||
StatusBar.Panels[2].Text := EmptyStr;
|
||||
|
|
@ -542,7 +571,7 @@ begin
|
|||
OpenFileRight(edtFileNameRight.Text);
|
||||
end;
|
||||
|
||||
if Visible and actAutoCompare.Checked then actStartCompare.Execute;
|
||||
actStartCompare.Execute;
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.actCancelCompareExecute(Sender: TObject);
|
||||
|
|
@ -759,10 +788,32 @@ begin
|
|||
actStartCompare.Execute;
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.btnCancelClick(Sender: TObject);
|
||||
begin
|
||||
FCancel:= True;
|
||||
if actBinaryCompare.Checked and Assigned(BinaryCompare) then
|
||||
BinaryCompare.Terminate
|
||||
else begin
|
||||
Diff.Cancel;
|
||||
end;
|
||||
CloseProgressDialog;
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.tmProgressTimer(Sender: TObject);
|
||||
begin
|
||||
tmProgress.Enabled:= False;
|
||||
ShowProgressDialog;
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.BinaryCompareFinish;
|
||||
begin
|
||||
BinaryCompare:= nil;
|
||||
if FCancel then begin
|
||||
if FShowIdentical then Free;
|
||||
Exit;
|
||||
end;
|
||||
BinaryDiffIndex:= -1;
|
||||
tmProgress.Enabled:= False;
|
||||
StatusBar.Panels[0].Text := EmptyStr;
|
||||
StatusBar.Panels[1].Text := rsDiffModifies + IntToStr(BinaryDiffList.Count);
|
||||
StatusBar.Panels[2].Text := EmptyStr;
|
||||
|
|
@ -772,16 +823,28 @@ begin
|
|||
actBinaryCompare.Enabled := True;
|
||||
if FShowIdentical then
|
||||
begin
|
||||
CloseProgressDialog;
|
||||
FShowIdentical:= (BinaryDiffList.Count = 0);
|
||||
if FShowIdentical then
|
||||
ShowIdentical
|
||||
else begin
|
||||
FShowIdentical:= False;
|
||||
Application.QueueAsyncCall(@ShowFirstDifference, 0);
|
||||
ShowDialog;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.ShowDialog;
|
||||
begin
|
||||
if FModal then
|
||||
ShowModal
|
||||
else if (FWaitData = nil) then
|
||||
ShowOnTop
|
||||
else
|
||||
FWaitData.ShowOnTop(Self);
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.ShowIdentical;
|
||||
var
|
||||
Message: String;
|
||||
|
|
@ -792,6 +855,71 @@ begin
|
|||
Close
|
||||
else begin
|
||||
FShowIdentical:= False;
|
||||
ShowDialog;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.ShowProgressDialog;
|
||||
var
|
||||
lblPrompt : TLabel;
|
||||
btnCancel : TBitBtn;
|
||||
pbProgress: TProgressBar;
|
||||
begin
|
||||
frmProgress := TModalDialog.CreateNew(nil, 0);
|
||||
with frmProgress do
|
||||
begin
|
||||
BorderStyle := bsDialog;
|
||||
Position := poOwnerFormCenter;
|
||||
AutoSize := True;
|
||||
Height := 120;
|
||||
ChildSizing.TopBottomSpacing := 8;
|
||||
ChildSizing.LeftRightSpacing := 8;
|
||||
Caption := Self.Caption;
|
||||
lblPrompt := TLabel.Create(frmProgress);
|
||||
with lblPrompt do
|
||||
begin
|
||||
Parent := frmProgress;
|
||||
Caption := rsDiffComparing;
|
||||
Top := 6;
|
||||
Left := 6;
|
||||
end;
|
||||
pbProgress:= TProgressBar.Create(frmProgress);
|
||||
with pbProgress do
|
||||
begin
|
||||
Parent := frmProgress;
|
||||
Style:= pbstMarquee;
|
||||
Left := 6;
|
||||
AnchorToNeighbour(akTop, 6, lblPrompt);
|
||||
Constraints.MinWidth := Math.Max(280, Screen.Width div 4);
|
||||
end;
|
||||
btnCancel := TBitBtn.Create(frmProgress);
|
||||
with btnCancel do
|
||||
begin
|
||||
AutoSize := True;
|
||||
Parent := frmProgress;
|
||||
Kind := bkCancel;
|
||||
Cancel := True;
|
||||
OnClick:= @btnCancelClick;
|
||||
Anchors := [akTop, akRight];
|
||||
AnchorToNeighbour(akTop, 18, pbProgress);
|
||||
AnchorSide[akRight].Control := pbProgress;
|
||||
AnchorSide[akRight].Side := asrCenter;
|
||||
end;
|
||||
if FModal then
|
||||
ShowModal
|
||||
else if (FWaitData = nil) then
|
||||
ShowOnTop
|
||||
else
|
||||
FWaitData.ShowOnTop(frmProgress);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmDiffer.CloseProgressDialog;
|
||||
begin
|
||||
if Assigned(frmProgress) then
|
||||
begin
|
||||
frmProgress.Close;
|
||||
FreeAndNil(frmProgress);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -1238,7 +1366,9 @@ begin
|
|||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
msgError(E.Message + LineEnding + FileName);
|
||||
E.Message:= E.Message + LineEnding + FileName;
|
||||
if FShowIdentical then raise;
|
||||
msgError(E.Message);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -1295,14 +1425,11 @@ begin
|
|||
BinaryDiffList.Clear;
|
||||
BinaryViewerLeft.FileName:= FileName
|
||||
end
|
||||
else try
|
||||
else begin
|
||||
Clear(True, False);
|
||||
LoadFromFile(SynDiffEditLeft, FileName);
|
||||
BuildHashList(True, False);
|
||||
SynDiffEditLeft.Repaint;
|
||||
except
|
||||
on EFOpenError do
|
||||
msgWarning(rsMsgErrEOpen + ' ' + FileName);
|
||||
end;
|
||||
finally
|
||||
PushPop(FElevate);
|
||||
|
|
@ -1319,14 +1446,11 @@ begin
|
|||
BinaryDiffList.Clear;
|
||||
BinaryViewerRight.FileName:= FileName
|
||||
end
|
||||
else try
|
||||
else begin
|
||||
Clear(False, True);
|
||||
LoadFromFile(SynDiffEditRight, FileName);
|
||||
BuildHashList(False, True);
|
||||
SynDiffEditRight.Repaint;
|
||||
except
|
||||
on EFOpenError do
|
||||
msgWarning(rsMsgErrEOpen + ' ' + FileName);
|
||||
end;
|
||||
finally
|
||||
PushPop(FElevate);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ type
|
|||
constructor Create(AOwner: TComponent); override;
|
||||
property KeepScrolling: Boolean read FKeepScrolling write FKeepScrolling;
|
||||
property SecondViewer: TBinaryDiffViewer read FSecondViewer write FSecondViewer;
|
||||
property LastError: String read FLastError;
|
||||
end;
|
||||
|
||||
{ TBinaryCompare }
|
||||
|
|
|
|||
|
|
@ -573,6 +573,7 @@ resourcestring
|
|||
rsDiffModifies = ' Modifies: ';
|
||||
rsDiffAdds = ' Adds: ';
|
||||
rsDiffDeletes = ' Deletes: ';
|
||||
rsDiffComparing = 'Comparing...';
|
||||
rsDiffFilesIdentical = 'The two files are identical!';
|
||||
// Find files dialog
|
||||
rsFindSearchFiles = 'Find files';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue