Bläddra i källkod

ADD: Differ - show compare progress at start

Alexander Koblov 4 år sedan
förälder
incheckning
fc5ad2b0c3
4 ändrade filer med 239 tillägg och 108 borttagningar
  1. 5 0
      src/fdiffer.lfm
  2. 232 108
      src/fdiffer.pas
  3. 1 0
      src/ubinarydiffviewer.pas
  4. 1 0
      src/ulng.pas

+ 5 - 0
src/fdiffer.lfm

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

+ 232 - 108
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
-      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;
-    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
-        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
-          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;
+    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);
-  end;
-  if actLineDifferences.Checked then
-  begin
-    SynDiffEditLeft.Highlighter:= SynDiffHighlighterLeft;
-    SynDiffEditRight.Highlighter:= SynDiffHighlighterRight;
+    if FShowIdentical and FCancel then Free;
   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);

+ 1 - 0
src/ubinarydiffviewer.pas

@@ -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 }

+ 1 - 0
src/ulng.pas

@@ -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';