2
0
Эх сурвалжийг харах

ADD: Differ - show compare progress at start

Alexander Koblov 4 жил өмнө
parent
commit
fc5ad2b0c3

+ 5 - 0
src/fdiffer.lfm

@@ -749,4 +749,9 @@ object frmDiffer: TfrmDiffer
     left = 352
     left = 352
     top = 136
     top = 136
   end
   end
+  object tmProgress: TTimer
+    OnTimer = tmProgressTimer
+    Left = 568
+    Top = 170
+  end
 end
 end

+ 232 - 108
src/fdiffer.pas

@@ -29,7 +29,7 @@ uses
   Classes, SysUtils, FileUtil, Forms, Controls, Dialogs, Menus, ComCtrls,
   Classes, SysUtils, FileUtil, Forms, Controls, Dialogs, Menus, ComCtrls,
   ActnList, ExtCtrls, EditBtn, Buttons, SynEdit, uSynDiffControls,
   ActnList, ExtCtrls, EditBtn, Buttons, SynEdit, uSynDiffControls,
   uPariterControls, uDiffOND, uFormCommands, uHotkeyManager, uOSForms,
   uPariterControls, uDiffOND, uFormCommands, uHotkeyManager, uOSForms,
-  uBinaryDiffViewer, uShowForm, KASStatusBar, Graphics;
+  uBinaryDiffViewer, uShowForm, KASStatusBar, Graphics, StdCtrls;
 
 
 type
 type
 
 
@@ -148,6 +148,7 @@ type
     pmEncodingRight: TPopupMenu;
     pmEncodingRight: TPopupMenu;
     Splitter: TSplitter;
     Splitter: TSplitter;
     StatusBar: TStatusBar;
     StatusBar: TStatusBar;
+    tmProgress: TTimer;
     ToolBar: TToolBar;
     ToolBar: TToolBar;
     btnSave: TToolButton;
     btnSave: TToolButton;
     btnSaveAs: TToolButton;
     btnSaveAs: TToolButton;
@@ -201,6 +202,8 @@ type
     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
     procedure FormResize(Sender: TObject);
     procedure FormResize(Sender: TObject);
     procedure FormShow(Sender: TObject);
     procedure FormShow(Sender: TObject);
+    procedure btnCancelClick(Sender: TObject);
+    procedure tmProgressTimer(Sender: TObject);
   private
   private
     BinaryDiffList: TFPList;
     BinaryDiffList: TFPList;
     BinaryDiffIndex: Integer;
     BinaryDiffIndex: Integer;
@@ -220,10 +223,17 @@ type
     EncodingList: TStringList;
     EncodingList: TStringList;
     ScrollLock: LongInt;
     ScrollLock: LongInt;
     FShowIdentical: Boolean;
     FShowIdentical: Boolean;
+    FModal: Boolean;
+    FCancel: Boolean;
+    frmProgress: TForm;
     FWaitData: TWaitData;
     FWaitData: TWaitData;
     FElevate: TDuplicates;
     FElevate: TDuplicates;
     FCommands: TFormCommands;
     FCommands: TFormCommands;
+private
+    procedure ShowDialog;
     procedure ShowIdentical;
     procedure ShowIdentical;
+    procedure ShowProgressDialog;
+    procedure CloseProgressDialog;
     procedure Clear(bLeft, bRight: Boolean);
     procedure Clear(bLeft, bRight: Boolean);
     procedure BuildHashList(bLeft, bRight: Boolean);
     procedure BuildHashList(bLeft, bRight: Boolean);
     procedure ChooseEncoding(SynDiffEdit: TSynDiffEdit);
     procedure ChooseEncoding(SynDiffEdit: TSynDiffEdit);
@@ -266,7 +276,7 @@ implementation
 {$R *.lfm}
 {$R *.lfm}
 
 
 uses
 uses
-  LCLType, LazFileUtils, LConvEncoding, SynEditTypes, uHash, uLng, uGlobs,
+  Math, LCLType, LazFileUtils, LConvEncoding, SynEditTypes, uHash, uLng, uGlobs,
   uShowMsg, DCClassesUtf8, dmCommonData, uDCUtils, uConvEncoding, uAdministrator;
   uShowMsg, DCClassesUtf8, dmCommonData, uDCUtils, uConvEncoding, uAdministrator;
 
 
 const
 const
@@ -279,27 +289,27 @@ begin
   Differ := TfrmDiffer.Create(Application);
   Differ := TfrmDiffer.Create(Application);
   with Differ do
   with Differ do
   begin
   begin
+    FModal := Modal;
     FWaitData := WaitData;
     FWaitData := WaitData;
+    FShowIdentical := True;
     edtFileNameLeft.Text:= FileNameLeft;
     edtFileNameLeft.Text:= FileNameLeft;
     edtFileNameRight.Text:= FileNameRight;
     edtFileNameRight.Text:= FileNameRight;
-    FShowIdentical:= actAutoCompare.Checked;
     SetColors(gDifferAddedColor, gDifferDeletedColor, gDifferModifiedColor);
     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;
   end;
 end;
 end;
@@ -312,101 +322,113 @@ var
   LineNumberLeft,
   LineNumberLeft,
   LineNumberRight: PtrInt;
   LineNumberRight: PtrInt;
 begin
 begin
-  if actBinaryCompare.Checked then
-  begin
-    if (BinaryViewerLeft.IsFileOpen and BinaryViewerRight.IsFileOpen) then
+  FCancel:= False;
+  try
+    if actBinaryCompare.Checked then
     begin
     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 (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 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 Exit;
-    actStartCompare.Enabled := False;
-    actCancelCompare.Enabled := True;
+      if (Length(HashListLeft) = 0) or (Length(HashListRight) = 0) then
+      begin
+        FCancel := True;
+        Exit;
+      end;
 
 
-    Diff.Execute(
-                 PInteger(@HashListLeft[0]),
-                 PInteger(@HashListRight[0]),
-                 Length(HashListLeft),
-                 Length(HashListRight)
-                );
+      actStartCompare.Enabled := False;
+      actCancelCompare.Enabled := True;
 
 
-    if Diff.Cancelled then Exit;
+      Diff.Execute(
+                   PInteger(@HashListLeft[0]),
+                   PInteger(@HashListRight[0]),
+                   Length(HashListLeft),
+                   Length(HashListRight)
+                  );
 
 
-    SynDiffEditLeft.StartCompare;
-    SynDiffEditRight.StartCompare;
+      tmProgress.Enabled:= False;
+      if Diff.Cancelled then Exit;
 
 
-    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);
+      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;
       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
+      with Diff.DiffStats do
       begin
       begin
-        FShowIdentical:= (modifies = 0) and (adds = 0) and (deletes = 0);
+        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
         if FShowIdentical then
-          ShowIdentical
-        else begin
-          FShowIdentical:= False;
-          Application.QueueAsyncCall(@ShowFirstDifference, 0);
+        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;
       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;
     end;
   finally
   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;
+    if FShowIdentical and FCancel then Free;
   end;
   end;
-  //mnuEdit.Enabled := true;
 end;
 end;
 
 
 procedure TfrmDiffer.actOpenLeftExecute(Sender: TObject);
 procedure TfrmDiffer.actOpenLeftExecute(Sender: TObject);
@@ -529,6 +551,13 @@ begin
       finally
       finally
         PushPop(FElevate);
         PushPop(FElevate);
       end;
       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[0].Text := EmptyStr;
       StatusBar.Panels[1].Text := EmptyStr;
       StatusBar.Panels[1].Text := EmptyStr;
       StatusBar.Panels[2].Text := EmptyStr;
       StatusBar.Panels[2].Text := EmptyStr;
@@ -542,7 +571,7 @@ begin
       OpenFileRight(edtFileNameRight.Text);
       OpenFileRight(edtFileNameRight.Text);
     end;
     end;
 
 
-  if Visible and actAutoCompare.Checked then actStartCompare.Execute;
+  actStartCompare.Execute;
 end;
 end;
 
 
 procedure TfrmDiffer.actCancelCompareExecute(Sender: TObject);
 procedure TfrmDiffer.actCancelCompareExecute(Sender: TObject);
@@ -759,10 +788,32 @@ begin
     actStartCompare.Execute;
     actStartCompare.Execute;
 end;
 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;
 procedure TfrmDiffer.BinaryCompareFinish;
 begin
 begin
   BinaryCompare:= nil;
   BinaryCompare:= nil;
+  if FCancel then begin
+    if FShowIdentical then Free;
+    Exit;
+  end;
   BinaryDiffIndex:= -1;
   BinaryDiffIndex:= -1;
+  tmProgress.Enabled:= False;
   StatusBar.Panels[0].Text := EmptyStr;
   StatusBar.Panels[0].Text := EmptyStr;
   StatusBar.Panels[1].Text := rsDiffModifies + IntToStr(BinaryDiffList.Count);
   StatusBar.Panels[1].Text := rsDiffModifies + IntToStr(BinaryDiffList.Count);
   StatusBar.Panels[2].Text := EmptyStr;
   StatusBar.Panels[2].Text := EmptyStr;
@@ -772,16 +823,28 @@ begin
   actBinaryCompare.Enabled := True;
   actBinaryCompare.Enabled := True;
   if FShowIdentical then
   if FShowIdentical then
   begin
   begin
+    CloseProgressDialog;
     FShowIdentical:= (BinaryDiffList.Count = 0);
     FShowIdentical:= (BinaryDiffList.Count = 0);
     if FShowIdentical then
     if FShowIdentical then
       ShowIdentical
       ShowIdentical
     else begin
     else begin
       FShowIdentical:= False;
       FShowIdentical:= False;
       Application.QueueAsyncCall(@ShowFirstDifference, 0);
       Application.QueueAsyncCall(@ShowFirstDifference, 0);
+      ShowDialog;
     end;
     end;
   end;
   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;
 procedure TfrmDiffer.ShowIdentical;
 var
 var
   Message: String;
   Message: String;
@@ -792,6 +855,71 @@ begin
     Close
     Close
   else begin
   else begin
     FShowIdentical:= False;
     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;
 end;
 end;
 
 
@@ -1238,7 +1366,9 @@ begin
   except
   except
     on E: Exception do
     on E: Exception do
     begin
     begin
-      msgError(E.Message + LineEnding + FileName);
+      E.Message:= E.Message + LineEnding + FileName;
+      if FShowIdentical then raise;
+      msgError(E.Message);
     end;
     end;
   end;
   end;
 end;
 end;
@@ -1295,14 +1425,11 @@ begin
       BinaryDiffList.Clear;
       BinaryDiffList.Clear;
       BinaryViewerLeft.FileName:= FileName
       BinaryViewerLeft.FileName:= FileName
     end
     end
-    else try
+    else begin
       Clear(True, False);
       Clear(True, False);
       LoadFromFile(SynDiffEditLeft, FileName);
       LoadFromFile(SynDiffEditLeft, FileName);
       BuildHashList(True, False);
       BuildHashList(True, False);
       SynDiffEditLeft.Repaint;
       SynDiffEditLeft.Repaint;
-    except
-      on EFOpenError do
-        msgWarning(rsMsgErrEOpen + ' ' + FileName);
     end;
     end;
   finally
   finally
     PushPop(FElevate);
     PushPop(FElevate);
@@ -1319,14 +1446,11 @@ begin
       BinaryDiffList.Clear;
       BinaryDiffList.Clear;
       BinaryViewerRight.FileName:= FileName
       BinaryViewerRight.FileName:= FileName
     end
     end
-    else try
+    else begin
       Clear(False, True);
       Clear(False, True);
       LoadFromFile(SynDiffEditRight, FileName);
       LoadFromFile(SynDiffEditRight, FileName);
       BuildHashList(False, True);
       BuildHashList(False, True);
       SynDiffEditRight.Repaint;
       SynDiffEditRight.Repaint;
-    except
-      on EFOpenError do
-        msgWarning(rsMsgErrEOpen + ' ' + FileName);
     end;
     end;
   finally
   finally
     PushPop(FElevate);
     PushPop(FElevate);

+ 1 - 0
src/ubinarydiffviewer.pas

@@ -45,6 +45,7 @@ type
     constructor Create(AOwner: TComponent); override;
     constructor Create(AOwner: TComponent); override;
     property KeepScrolling: Boolean read FKeepScrolling write FKeepScrolling;
     property KeepScrolling: Boolean read FKeepScrolling write FKeepScrolling;
     property SecondViewer: TBinaryDiffViewer read FSecondViewer write FSecondViewer;
     property SecondViewer: TBinaryDiffViewer read FSecondViewer write FSecondViewer;
+    property LastError: String read FLastError;
   end;
   end;
 
 
   { TBinaryCompare }
   { TBinaryCompare }

+ 1 - 0
src/ulng.pas

@@ -573,6 +573,7 @@ resourcestring
   rsDiffModifies = ' Modifies: ';
   rsDiffModifies = ' Modifies: ';
   rsDiffAdds = ' Adds: ';
   rsDiffAdds = ' Adds: ';
   rsDiffDeletes = ' Deletes: ';
   rsDiffDeletes = ' Deletes: ';
+  rsDiffComparing = 'Comparing...';
   rsDiffFilesIdentical = 'The two files are identical!';
   rsDiffFilesIdentical = 'The two files are identical!';
   // Find files dialog
   // Find files dialog
   rsFindSearchFiles = 'Find files';
   rsFindSearchFiles = 'Find files';