summaryrefslogtreecommitdiff
path: root/UChecksumDruid.pas
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2008-06-07 20:34:49 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2008-06-07 20:34:49 +0200
commitecde167da74c86bc047aaf84c5e548cf65a5da98 (patch)
treea015dfda84f28a65811e3aa0d369f8f211ec8c60 /UChecksumDruid.pas
downloadtuxcmd-release-0.6.36-dev.tar.xz
Diffstat (limited to 'UChecksumDruid.pas')
-rw-r--r--UChecksumDruid.pas629
1 files changed, 629 insertions, 0 deletions
diff --git a/UChecksumDruid.pas b/UChecksumDruid.pas
new file mode 100644
index 0000000..81266f6
--- /dev/null
+++ b/UChecksumDruid.pas
@@ -0,0 +1,629 @@
+(*
+ Tux Commander - UChecksumDruid - Checksum calculation druid
+ Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ Check for updates on tuxcmd.sourceforge.net
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*)
+unit UChecksumDruid;
+
+interface
+
+uses
+ glib2, gdk2, gtk2, SysUtils, Types, Classes, Variants, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts,
+ GTKView, GTKText, GTKUtils,
+ UEngines;
+
+type
+ TFChecksumDruid = class(TGTKDialog)
+ CancelButton, BackButton, ForwardButton: TGTKButton;
+ ButtonBox: TGTKHButtonBox;
+ TitleLabel, Page1Label, Page4Label, FilenameLabel, Page6Label, Page7Label, ProcessingLabel, Page6Spacer, ErrorLabel: TGTKLabel;
+ TitleLabelBox, PageAreaColor, LeftSpacer, Page2Color, Page3Color, Page4Color, Page5Color, Page6Color, LeftSpacer7: TGTKEventBox;
+ Page1, FileNameHBox, SeparateFileCheckHBox, Page7, ProgressHBox, ErrorTextViewHBox: TGTKHBox;
+ Page2, Page3, Page4, Page5, Page6: TGTKEventBox;
+ DruidArea, PageArea, Page2ClientArea, Page3ClientArea, Page5ClientArea, Page6ClientArea: TGTKVBox;
+ FileNameEntry: TGTKEntry;
+ SeparateFileCheckBox: TGTKCheckButton;
+ SFVRadioButton, MD5RadioButton: TGTKRadioButton;
+ Progress: TGTKProgressBar;
+ ErrorLabelScrolledWindow: TGTKScrolledWindow;
+ procedure FormCreate(Sender: TObject); override;
+ procedure FormDestroy(Sender: TObject);
+ procedure FormResponse(Sender: TObject; const ResponseID: integer);
+ procedure CancelButtonClick(Sender: TObject);
+ procedure BackButtonClick(Sender: TObject);
+ procedure ForwardButtonClick(Sender: TObject);
+ procedure FileNameEntryChanged(Sender: TObject);
+ procedure SeparateFileCheckBoxToggled(Sender: TObject);
+ procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
+ private
+ ColorFG, ColorBG, ColorGray: PGdkColor;
+ CurrentPage: integer;
+ Processing, Stop, StopBreak: boolean;
+ Buffer: Pointer;
+ FileDes: TEngineFileDes;
+ BufferPos: integer;
+ procedure CreatePages;
+ procedure SetCurrentPage(const Num: integer; const GoingForward: boolean);
+ procedure Process;
+ function ProcessFile(const FName: string; const IsItSFV: boolean; var HashString: string): boolean;
+ procedure CheckStop;
+ procedure WriteLine(const FName, CheckedFName, HashString: string; const IsItSFV, CreateFile, CloseFile: boolean);
+ procedure WriteSFVComment(const FName: string);
+ public
+ Engine: TPanelEngine;
+ FileNames: TStringList;
+ DirName: string;
+ end;
+
+const NumPages = 7;
+
+var
+ FChecksumDruid: TFChecksumDruid;
+
+implementation
+
+uses ULocale, UCoreUtils, Libc, UCore, DateUtils, UConfig, StrUtils;
+
+
+procedure TFChecksumDruid.FormCreate(Sender: TObject);
+begin
+ CurrentPage := 0;
+ Processing := False;
+ Stop := False;
+ StopBreak := False;
+ Buffer := nil;
+ BufferPos := 0;
+ SetDefaultSize(400, 210);
+ Caption := LANGCreateChecksumsCaption;
+ OnDestroy := FormDestroy;
+ OnResponse := FormResponse;
+ FileNames := TStringList.Create;
+ ShowSeparator := False;
+ Buttons := [];
+ ActionArea.SetSizeRequest(0, 0);
+ DruidArea := TGTKVBox.Create(Self);
+ DruidArea.BorderWidth := 2;
+ ClientArea.AddControlEx(DruidArea, True, True, 0);
+ CancelButton := TGTKButton.CreateFromStock(Self, 'gtk-cancel');
+ CancelButton.OnClick := CancelButtonClick;
+ BackButton := TGTKButton.CreateFromStock(Self, 'gtk-go-back');
+ BackButton.OnClick := BackButtonClick;
+ ForwardButton := TGTKButton.CreateFromStock(Self, 'gtk-go-forward');
+ ForwardButton.OnClick := ForwardButtonClick;
+ ButtonBox := TGTKHButtonBox.Create(Self);
+ ButtonBox.Layout := blEnd;
+ ButtonBox.Spacing := 10;
+ ButtonBox.BorderWidth := 5;
+ ButtonBox.AddControlEx(CancelButton, False, False, 0);
+ ButtonBox.AddControlEx(BackButton, False, False, 0);
+ ButtonBox.AddControlEx(ForwardButton, False, False, 0);
+ ClientArea.AddControlEndEx(ButtonBox, False, False, 0);
+ ColorFG := GetDefaultForegroundColor(3);
+ ColorBG := GetDefaultBackgroundColor(3);
+ ColorGray := GetDefaultBackgroundColor(2);
+ TitleLabel := TGTKLabel.Create(Self);
+ TitleLabelBox := TGTKEventBox.Create(Self);
+ TitleLabelBox.AddControl(TitleLabel);
+ TitleLabelBox.BorderWidth := 0;
+ TitleLabel.SetAlignment(0, 0.5);
+ TitleLabel.SetPadding(5, 5);
+ TitleLabel.SetForegroundColor(ColorFG);
+ TitleLabelBox.SetBackgroundColor(ColorBG);
+ DruidArea.AddControlEx(TitleLabelBox, False, False, 0);
+ PageAreaColor := TGTKEventBox.Create(Self);
+ PageAreaColor.SetBackgroundColor(ColorGray);
+ PageArea := TGTKVBox.Create(Self);
+ PageAreaColor.AddControl(PageArea);
+ DruidArea.AddControlEx(PageAreaColor, True, True, 0);
+
+ CreatePages;
+
+ SetCurrentPage(1, True);
+ OnKeyDown := FormKeyDown;
+end;
+
+procedure TFChecksumDruid.FormDestroy(Sender: TObject);
+begin
+ FileNames.Free;
+end;
+
+procedure TFChecksumDruid.FormResponse(Sender: TObject; const ResponseID: integer);
+begin
+ Stop := True;
+end;
+
+procedure TFChecksumDruid.FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
+begin
+// if Key = GDK_ESCAPE then ModalResult := mbCancel;
+ if (Key = GDK_RETURN) or (Key = GDK_KP_ENTER) then ForwardButtonClick(Sender);
+end;
+
+procedure TFChecksumDruid.CreatePages;
+begin
+ Page1 := TGTKHBox.Create(Self);
+ Page1.Homogeneous := False;
+ LeftSpacer := TGTKEventBox.Create(Self);
+ LeftSpacer.SetBackgroundColor(ColorBG);
+ LeftSpacer.SetSizeRequest(100, -1);
+ Page1Label := TGTKLabel.Create(Self);
+ Page1Label.LineWrap := True;
+ Page1Label.SetAlignment(0.5, 0.5);
+ Page1Label.Caption := LANGCCHKSUMPage1Text;
+ Page1.AddControlEx(LeftSpacer, False, False, 0);
+ Page1.AddControlEx(Page1Label, True, True, 0);
+
+ Page2 := TGTKEventBox.Create(Self);
+ Page2.SetBackgroundColor(0, 0, 0);
+ Page2Color := TGTKEventBox.Create(Self);
+ Page2Color.BorderWidth := 1;
+ Page2Color.SetBackgroundColor(ColorGray);
+ Page2.AddControl(Page2Color);
+ Page2ClientArea := TGTKVBox.Create(Self);
+ Page2Color.AddControl(Page2ClientArea);
+ SFVRadioButton := TGTKRadioButton.Create(Self);
+ SFVRadioButton.Caption := LANGCCHKSUMSFVFile;
+ MD5RadioButton := TGTKRadioButton.Create(Self);
+ MD5RadioButton.Caption := LANGCCHKSUMMD5sumFile;
+ MD5RadioButton.SetRadioGroup(SFVRadioButton);
+ SFVRadioButton.Checked := True;
+ Page2ClientArea.AddControlEx(SFVRadioButton, False, False, 3);
+ Page2ClientArea.AddControlEx(MD5RadioButton, False, False, 3);
+ Page2ClientArea.BorderWidth := 30;
+
+ Page3 := TGTKEventBox.Create(Self);
+ Page3.SetBackgroundColor(0, 0, 0);
+ Page3Color := TGTKEventBox.Create(Self);
+ Page3Color.BorderWidth := 1;
+ Page3Color.SetBackgroundColor(ColorGray);
+ Page3.AddControl(Page3Color);
+ Page3ClientArea := TGTKVBox.Create(Self);
+ Page3Color.AddControl(Page3ClientArea);
+ FilenameLabel := TGTKLabel.Create(Self);
+ FilenameLabel.Caption := LANGCCHKSUMFileName;
+ FilenameLabel.UseUnderline := True;
+ FileNameEntry := TGTKEntry.Create(Self);
+ FileNameEntry.Text := 'checksums.sfv';
+ FileNameEntry.SetSizeRequest(215, -1);
+ FileNameEntry.OnChanged := FileNameEntryChanged;
+ FilenameLabel.FocusControl := FileNameEntry;
+ SeparateFileCheckBox := TGTKCheckButton.CreateWithLabel(Self, LANGCCHKSUMCreateSeparateChecksumFiles);
+ SeparateFileCheckBox.OnToggled := SeparateFileCheckBoxToggled;
+ Page3ClientArea.BorderWidth := 30;
+ FileNameHBox := TGTKHBox.Create(Self);
+ FileNameHBox.Homogeneous := False;
+ FileNameHBox.AddControlEx(FilenameLabel, False, False, 5);
+ FileNameHBox.AddControlEx(FileNameEntry, False, False, 5);
+ Page3ClientArea.AddControlEx(FileNameHBox, False, False, 0);
+ SeparateFileCheckHBox := TGTKHBox.Create(Self);
+ SeparateFileCheckHBox.Homogeneous := False;
+ SeparateFileCheckHBox.AddControlEx(SeparateFileCheckBox, False, False, 20);
+ SeparateFileCheckHBox.AddControlEx(TGTKLabel.Create(Self), True, True, 0);
+ Page3ClientArea.AddControlEx(SeparateFileCheckHBox, False, False, 5);
+
+ Page4 := TGTKEventBox.Create(Self);
+ Page4.SetBackgroundColor(0, 0, 0);
+ Page4Color := TGTKEventBox.Create(Self);
+ Page4Color.BorderWidth := 1;
+ Page4Color.SetBackgroundColor(ColorGray);
+ Page4.AddControl(Page4Color);
+ Page4Label := TGTKLabel.Create(Self);
+ Page4Label.LineWrap := True;
+ Page4Label.SetAlignment(0.5, 0.5);
+ Page4Label.Caption := LANGCCHKSUMPage4Text;
+ Page4Color.AddControl(Page4Label);
+
+ Page5 := TGTKEventBox.Create(Self);
+ Page5.SetBackgroundColor(0, 0, 0);
+ Page5Color := TGTKEventBox.Create(Self);
+ Page5Color.BorderWidth := 1;
+ Page5Color.SetBackgroundColor(ColorGray);
+ Page5.AddControl(Page5Color);
+ Page5ClientArea := TGTKVBox.Create(Self);
+ Page5Color.AddControl(Page5ClientArea);
+ ProcessingLabel := TGTKLabel.Create(Self);
+ ProcessingLabel.Caption := Format(LANGCCHKSUMNowProcessingFileS, ['---']);
+ ProcessingLabel.XPadding := 20;
+ ProcessingLabel.XAlign := 0;
+ ProcessingLabel.YPadding := 10;
+ ProcessingLabel.SetSizeRequest(10, -1);
+ Page5ClientArea.AddControlEx(ProcessingLabel, False, False, 10);
+ ProgressHBox := TGTKHBox.Create(Self);
+ Progress := TGTKProgressBar.Create(Self);
+ ProgressHBox.AddControlEx(Progress, True, True, 20);
+ Page5ClientArea.AddControlEx(ProgressHBox, True, True, 10);
+ Page5ClientArea.AddControlEx(TGTKLabel.Create(Self), True, True, 0);
+
+ Page6 := TGTKEventBox.Create(Self);
+ Page6.SetBackgroundColor(0, 0, 0);
+ Page6Color := TGTKEventBox.Create(Self);
+ Page6Color.BorderWidth := 1;
+ Page6Color.SetBackgroundColor(ColorGray);
+ Page6.AddControl(Page6Color);
+ Page6Label := TGTKLabel.Create(Self);
+ Page6Label.LineWrap := True;
+ Page6Label.SetAlignment(0.5, 0.4);
+ Page6Label.Caption := LANGCCHKSUMPage6Text;
+ Page6Label.UseMarkup := True;
+ Page6Label.XAlign := 0.05;
+ Page6Label.YAlign := 0;
+ Page6Spacer := TGTKLabel.Create(Self);
+ Page6Spacer.SetSizeRequest(-1, 6);
+ Page6ClientArea := TGTKVBox.Create(Self);
+ Page6ClientArea.AddControlEx(Page6Spacer, False, False, 0);
+ Page6ClientArea.AddControlEx(Page6Label, False, False, 0);
+ Page6Color.AddControl(Page6ClientArea);
+ ErrorLabel := TGTKLabel.Create(Self);
+ ErrorLabel.Selectable := True;
+ ErrorLabel.SetAlignment(0, 0);
+ ErrorLabel.SetPadding(2, 2);
+ ErrorLabel.Alignment := taLeftJustify;
+ ErrorLabelScrolledWindow := TGTKScrolledWindow.Create(Self);
+ ErrorLabelScrolledWindow.HorizScrollBarPolicy := sbAutomatic;
+ ErrorLabelScrolledWindow.VertScrollBarPolicy := sbAutomatic;
+ ErrorLabelScrolledWindow.AddWithViewPort(ErrorLabel);
+ ErrorTextViewHBox := TGTKHBox.Create(Self);
+ ErrorTextViewHBox.AddControlEx(ErrorLabelScrolledWindow, True, True, 25);
+ Page6ClientArea.AddControlEx(ErrorTextViewHBox, True, True, 10);
+
+ Page7 := TGTKHBox.Create(Self);
+ Page7.Homogeneous := False;
+ LeftSpacer7 := TGTKEventBox.Create(Self);
+ LeftSpacer7.SetBackgroundColor(ColorBG);
+ LeftSpacer7.SetSizeRequest(100, -1);
+ Page7Label := TGTKLabel.Create(Self);
+ Page7Label.LineWrap := True;
+ Page1Label.SetAlignment(0.5, 0.5);
+ Page7Label.Caption := LANGCCHKSUMPage7Text;
+ Page7.AddControlEx(LeftSpacer7, False, False, 0);
+ Page7.AddControlEx(Page7Label, True, True, 0);
+
+ PageArea.AddControlEx(Page1, True, True, 0);
+ PageArea.AddControlEx(Page2, True, True, 0);
+ PageArea.AddControlEx(Page3, True, True, 0);
+ PageArea.AddControlEx(Page4, True, True, 0);
+ PageArea.AddControlEx(Page5, True, True, 0);
+ PageArea.AddControlEx(Page6, True, True, 0);
+ PageArea.AddControlEx(Page7, True, True, 0);
+end;
+
+
+(********************************************************************************************************************************)
+procedure TFChecksumDruid.SetCurrentPage(const Num: integer; const GoingForward: boolean);
+const Ext: array[boolean] of string = ('.md5', '.sfv');
+var s: string;
+ i: TEngineFileDes;
+ Error: integer;
+begin
+ // A simple test before we can continue
+ if (CurrentPage = 3) and (not SeparateFileCheckBox.Checked) and GoingForward then begin
+ s := UTF8ToANSI(FileNameEntry.Text);
+ i := Engine.OpenFile(s, omWrite, Error);
+ if Error <> 0 then begin
+ Application.MessageBox(Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(s)), ANSIToUTF8(GetErrorString(Error))]),
+ [mbOK], mbError, mbNone, mbOK);
+ Exit;
+ end;
+ Engine.CloseFile(i);
+ end;
+ // Changing page
+ CurrentPage := Num;
+ if CurrentPage < 1 then CurrentPage := 1;
+ if CurrentPage > NumPages then CurrentPage := NumPages;
+ case CurrentPage of
+ 1: TitleLabel.SetMarkup(LANGCCHKSUMPage1Title);
+ 2: TitleLabel.SetMarkup(LANGCCHKSUMPage2Title);
+ 3: TitleLabel.SetMarkup(LANGCCHKSUMPage3Title);
+ 4: TitleLabel.SetMarkup(LANGCCHKSUMPage4Title);
+ 5: TitleLabel.SetMarkup(LANGCCHKSUMPage5Title);
+ 6: TitleLabel.SetMarkup(LANGCCHKSUMPage6Title);
+ 7: TitleLabel.SetMarkup(LANGCCHKSUMPage7Title);
+ end;
+ Page1.Visible := CurrentPage = 1;
+ Page2.Visible := CurrentPage = 2;
+ Page3.Visible := CurrentPage = 3;
+ Page4.Visible := CurrentPage = 4;
+ Page5.Visible := CurrentPage = 5;
+ Page6.Visible := CurrentPage = 6;
+ Page7.Visible := CurrentPage = 7;
+ BackButton.Enabled := CurrentPage > 1;
+ ForwardButton.Enabled := CurrentPage < NumPages;
+ if CurrentPage < NumPages then begin
+ if not ForwardButton.UseStock then ForwardButton.Caption := 'gtk-go-forward';
+ ForwardButton.UseStock := True;
+ end else begin
+ ForwardButton.UseStock := False;
+ ForwardButton.Caption := LANGCCHKSUMFinishCaption;
+ end;
+ // after page changed
+ case CurrentPage of
+ 1: ForwardButton.SetFocus;
+ 2: if SFVRadioButton.Checked then SFVRadioButton.SetFocus
+ else MD5RadioButton.SetFocus;
+ 3: begin
+ SeparateFileCheckBox.Visible := MD5RadioButton.Checked and (FileNames.Count > 1);
+ FileNameEntry.Enabled := (not SeparateFileCheckBox.Checked) or (not SeparateFileCheckBox.Visible);
+ if FileNames.Count = 1
+ then FileNameEntry.Text := ANSIToUTF8(ExtractFileName(FileNames[0]) + Ext[SFVRadioButton.Checked])
+ else FileNameEntry.Text := ANSIToUTF8(DirName + Ext[SFVRadioButton.Checked]);
+ FileNameEntry.SetFocus;
+ FileNameEntryChanged(Self);
+ end;
+ 4: ForwardButton.SetFocus;
+ 5: Process;
+ 6: begin
+ BackButton.SetFocus;
+ ForwardButton.Enabled := False;
+ s := ErrorLabel.Caption;
+ if (Length(s) > 1) and (s[Length(s)] = #10) then Delete(s, Length(s), 1);
+ ErrorLabel.Caption := s;
+ end;
+ 7: begin
+ BackButton.Enabled := False;
+ CancelButton.Enabled := False;
+ ForwardButton.Enabled := True;
+ ForwardButton.SetFocus;
+ end;
+ end;
+end;
+
+procedure TFChecksumDruid.CancelButtonClick(Sender: TObject);
+begin
+ ModalResult := mbCancel;
+end;
+
+procedure TFChecksumDruid.BackButtonClick(Sender: TObject);
+begin
+ SetCurrentPage(CurrentPage - 1 - Ord(CurrentPage = 6), False);
+end;
+
+procedure TFChecksumDruid.ForwardButtonClick(Sender: TObject);
+begin
+ if CurrentPage = 7 then ModalResult := mbOK
+ else SetCurrentPage(CurrentPage + 1, True);
+end;
+
+procedure TFChecksumDruid.FileNameEntryChanged(Sender: TObject);
+begin
+ ForwardButton.Enabled := Length(Trim(FileNameEntry.Text)) > 0;
+end;
+
+procedure TFChecksumDruid.SeparateFileCheckBoxToggled(Sender: TObject);
+begin
+ FileNameEntry.Enabled := not SeparateFileCheckBox.Checked;
+end;
+
+(********************************************************************************************************************************)
+procedure TFChecksumDruid.CheckStop;
+begin
+ if Stop and (not StopBreak) then
+ if Application.MessageBox(LANGCCHKSUMAreYouSureYouWantToAbortTheProcessing, [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes
+ then StopBreak := True
+ else begin Stop := False; StopBreak := False; end;
+end;
+
+procedure TFChecksumDruid.Process;
+const Ext: array[boolean] of string = ('.md5', '.sfv');
+var i: integer;
+ MaxSize, LastValue: Int64;
+ Stat: PDataItemSL;
+ s, s2: string;
+begin
+ if FileNames.Count = 0 then begin
+ SetCurrentPage(7, True);
+ Exit;
+ end;
+ FileNames.Sorted := True;
+ CancelButton.SetFocus;
+ ForwardButton.Enabled := False;
+ BackButton.Enabled := False;
+ Processing := True;
+ Stop := False;
+ StopBreak := False;
+ ErrorLabel.Caption := '';
+ Application.ProcessMessages;
+
+ // Compute maximal size of selected files
+ MaxSize := 0;
+ for i := 0 to FileNames.Count - 1 do begin
+ Stat := Engine.GetFileInfoSL(FileNames[i]);
+ if Assigned(Stat) then Inc(MaxSize, Stat.Size);
+ end;
+ Progress.Max := MaxSize;
+ Progress.Value := 0;
+ Progress.Text := '0 %';
+
+ if SFVRadioButton.Checked then WriteSFVComment(ProcessPattern(Engine, UTF8ToANSI(FileNameEntry.Text), IncludeTrailingPathDelimiter(ExtractFilePath(FileNames[0])), '', False));
+ // Process each file
+ for i := 0 to FileNames.Count - 1 do begin
+ ProcessingLabel.Caption := Format(LANGCCHKSUMNowProcessingFileS, [ANSIToUTF8(ExtractFileName(FileNames[i]))]);
+ LastValue := Progress.Value;
+ Stat := Engine.GetFileInfoSL(FileNames[i]);
+ Application.ProcessMessages;
+ try
+ if ProcessFile(FileNames[i], SFVRadioButton.Checked, s) then begin
+ if not SeparateFileCheckBox.Checked
+ then s2 := ProcessPattern(Engine, UTF8ToANSI(FileNameEntry.Text), IncludeTrailingPathDelimiter(ExtractFilePath(FileNames[0])), '', False)
+ else s2 := IncludeTrailingPathDelimiter(ExtractFilePath(FileNames[i])) + ExtractFileName(FileNames[i]) + Ext[SFVRadioButton.Checked];
+ WriteLine(s2, FileNames[i], s, SFVRadioButton.Checked, ((i = 0) and MD5RadioButton.Checked) or SeparateFileCheckBox.Checked,
+ (i = FileNames.Count - 1) or SeparateFileCheckBox.Checked);
+ end;
+ except end;
+ if Assigned(Stat) then Progress.Value := LastValue + Stat.Size;
+ Progress.Text := Format('%d %%', [Trunc(Progress.Fraction * 100)]);
+ Application.ProcessMessages;
+ CheckStop;
+ if StopBreak then Break;
+ end;
+
+ Application.ProcessMessages;
+ Processing := False;
+ Stop := False;
+ StopBreak := False;
+ Application.ProcessMessages;
+ SetCurrentPage(7 - Ord(ErrorLabel.Caption <> ''), ErrorLabel.Caption = '');
+end;
+
+function TFChecksumDruid.ProcessFile(const FName: string; const IsItSFV: boolean; var HashString: string): boolean;
+const ChksumBlockSize = 65536*4;
+var FD: TEngineFileDes;
+ Error, Count: integer;
+ Buffer: Pointer;
+ CRC: LongWord;
+ MD5Hash: THash_MD5;
+begin
+ HashString := '';
+ Result := False;
+ try
+ Buffer := Libc.malloc(ChksumBlockSize);
+ Libc.memset(Buffer, 0, ChksumBlockSize);
+ except
+ ErrorLabel.Caption := ErrorLabel.Caption + LANGAnErrorOccuredWhileInitializingMemoryBlock + #10;
+ Exit;
+ end;
+ CRC := $FFFFFFFF;
+ MD5Hash := nil;
+ if not IsItSFV then MD5Hash := THash_MD5.Create;
+
+ FD := Engine.OpenFile(FName, omRead, Error);
+ if Error <> 0 then begin
+ ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]);
+ Exit;
+ end;
+ repeat
+ Count := Engine.ReadFile(FD, Buffer, ChksumBlockSize, Error);
+ if Error <> 0 then begin
+ ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileReadingFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]);
+ Engine.CloseFile(FD);
+ Exit;
+ end;
+ if IsItSFV then CRC := CRC32(CRC, Buffer, Count)
+ else MD5Hash.Calc(Buffer^, Count);
+ Progress.Value := Progress.Value + Count;
+ Progress.Text := Format('%d %%', [Trunc(Progress.Fraction * 100)]);
+ Application.ProcessMessages;
+ CheckStop;
+ until (Count < ChksumBlockSize) or Stop;
+ Engine.CloseFile(FD);
+ Libc.free(Buffer);
+
+ if IsItSFV then HashString := IntToHex(not CRC, 8) else
+ begin
+ MD5Hash.Done;
+ HashString := MD5Hash.GetKeyStrH;
+ MD5Hash.Free;
+ end;
+ Result := True;
+end;
+
+const ChksumBlockSize = 32768; // Maximum of PByteArray
+
+procedure TFChecksumDruid.WriteLine(const FName, CheckedFName, HashString: string; const IsItSFV, CreateFile, CloseFile: boolean);
+var i, Error, Count: integer;
+ s: string;
+begin
+ if CreateFile then begin
+ FileDes := Engine.OpenFile(FName, omWrite, Error);
+ if Error <> 0 then begin
+ ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]);
+ Exit;
+ end;
+ try
+ Buffer := Libc.malloc(ChksumBlockSize);
+ Libc.memset(Buffer, 0, ChksumBlockSize);
+ except
+ ErrorLabel.Caption := ErrorLabel.Caption + LANGAnErrorOccuredWhileInitializingMemoryBlock + #10;
+ Exit;
+ end;
+ BufferPos := -1;
+ end;
+ if Buffer = nil then Exit;
+
+ if IsItSFV then s := Format('%s %s'#13#10, [ExtractFileName(CheckedFName), Trim(ANSIUpperCase(HashString))])
+ else s := Format('%s %s'#10, [Trim(AnsiLowerCase(HashString)), ExtractFileName(CheckedFName)]);
+ for i := 1 to Length(s) do begin
+ if BufferPos + 1 >= ChksumBlockSize then begin
+ Count := Engine.WriteFile(FileDes, Buffer, ChksumBlockSize, Error);
+ BufferPos := -1;
+ if (Error <> 0) or (Count <> ChksumBlockSize) then begin
+ ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]);
+ Exit;
+ end;
+ end;
+ Inc(BufferPos);
+ PByteArray(Buffer)^[BufferPos] := Byte(s[i]);
+ end;
+
+ if CloseFile then begin
+ Inc(BufferPos); // Counting with zero-starting element
+ Count := Engine.WriteFile(FileDes, Buffer, BufferPos, Error);
+ if (Error <> 0) or (Count <> BufferPos) then begin
+ ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]);
+ Exit;
+ end;
+ BufferPos := -1;
+ Engine.CloseFile(FileDes);
+ Libc.free(Buffer);
+ end;
+end;
+
+procedure TFChecksumDruid.WriteSFVComment(const FName: string);
+var i, Error, Count: integer;
+ Stat: PDataItemSL;
+ s: string;
+begin
+ FileDes := Engine.OpenFile(FName, omWrite, Error);
+ if Error <> 0 then begin
+ ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]);
+ Exit;
+ end;
+ try
+ Buffer := Libc.malloc(ChksumBlockSize);
+ Libc.memset(Buffer, 0, ChksumBlockSize);
+ except
+ ErrorLabel.Caption := ErrorLabel.Caption + LANGAnErrorOccuredWhileInitializingMemoryBlock + #10;
+ Exit;
+ end;
+ BufferPos := -1;
+ if Buffer = nil then Exit;
+
+ s := Format('; Generated by WIN-SFV32 v1 [added for sfv32 compatibility]'#13#10'; Using Tux Commander v%s [%s] on %s'#13#10 +
+ '; http://tuxcmd.sourceforge.net/'#13#10'; '#13#10'; /----'#13#10, [ConstAboutVersion, ConstAboutBuildDate,
+ FormatDateTime('mm.dd.yyyy "at" hh:nn:ss', Now)]);
+ for i := 0 to FileNames.Count - 1 do begin
+ Stat := Engine.GetFileInfoSL(FileNames[i]);
+ if Assigned(Stat) then s := s + Format('; %s %s %s'#13#10, [PadRightStr(IntToStr(Stat^.Size), 11),
+ FormatDateTime('hh:nn.ss yyyy-mm-dd', Stat^.ModifyTime), ExtractFileName(FileNames[i])]);
+ end;
+ s := s + '; \----'#13#10'; '#13#10;
+
+ for i := 1 to Length(s) do begin
+ if BufferPos + 1 >= ChksumBlockSize then begin
+ Count := Engine.WriteFile(FileDes, Buffer, ChksumBlockSize, Error);
+ BufferPos := -1;
+ if (Error <> 0) or (Count <> ChksumBlockSize) then begin
+ ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]);
+ Exit;
+ end;
+ end;
+ Inc(BufferPos);
+ PByteArray(Buffer)^[BufferPos] := Byte(s[i]);
+ end;
+end;
+
+end.
+
+