diff options
Diffstat (limited to 'UCoreWorkers.pas')
| -rw-r--r-- | UCoreWorkers.pas | 198 |
1 files changed, 97 insertions, 101 deletions
diff --git a/UCoreWorkers.pas b/UCoreWorkers.pas index a1e65ba..97077aa 100644 --- a/UCoreWorkers.pas +++ b/UCoreWorkers.pas @@ -20,7 +20,7 @@ unit UCoreWorkers; interface -uses glib2, gtk2, SyncObjs, Classes, GTKForms, GTKView, ULibc, UEngines, UCoreUtils, UVFSCore, uVFSprototypes, UCore; +uses glib2, gtk2, SyncObjs, Classes, GTKForms, GTKView, ULibc, UEngines, UCoreUtils, UVFSCore, uVFSprototypes, UCore, UDirDelete; type TWorkerThreadJobType = (WORKER_JOB_DUMMY, WORKER_JOB_DELETE, WORKER_JOB_COPY, WORKER_JOB_MOVE, WORKER_JOB_EXTRACT_TO_TEMP, @@ -99,17 +99,15 @@ type TVFSCallbackThread = class(TThread) procedure UpdateCaption1(const CaptionText: string); procedure UpdateCaption2(const CaptionText: string); - FDirDeleteButtonsType: integer; - FDirDeleteLabel1Text, FDirDeleteLabel2Text, FDirDeleteLabel3Text, FDirDeleteCaption: string; - FDirDeleteLabel2Visible, FDirDeleteLabel3Visible: boolean; - function ShowDirDeleteDialog(ButtonsType: integer; const Label1Text: string; const Label2Text: string = ''; - const Label3Text: string = ''; const DirDeleteCaption: string = ''): integer; + FDirDeleteButtonsType: TFDirDeleteButtonSet; + FDirDeleteTitle, FDirDeleteFileName: string; + FDirDeleteError: PGError; + function ShowDirDeleteDialog(ButtonsType: TFDirDeleteButtonSet; const Title, FileName: string; Error: PGError): integer; - FOverwriteButtonsType: integer; - FOverwriteFromLabel, FOverwriteFromInfoLabel, FOverwriteToLabel, FOverwriteToInfoLabel, - FOverwriteRenameStr, FOverwriteSourceFile, FOverwriteDestFile: string; - function ShowOverwriteDialog(ButtonsType: integer; const FromLabel, FromInfoLabel, ToLabel, ToInfoLabel, RenameStr, - SourceFile, DestFile: string): integer; + FOverwriteShowAppend: boolean; + FOverwriteSourceItem, FOverwriteDestItem: PDataItem; + FOverwriteSourceFile, FOverwriteDestFile, FOverwriteRenameStr: string; + function ShowOverwriteDialog(ShowAppend: boolean; SourceItem, DestItem: PDataItem; const SourceFile, DestFile: string; var RenameStr: string): integer; FNewDirCaption, FNewDirLabel, FNewDirEdit: string; function ShowNewDirDialog(Caption, LabelCaption, Edit: string): integer; @@ -212,7 +210,7 @@ procedure ProcessThreadEvents(SenderThread: TVFSCallbackThread); implementation -uses SysUtils, DateUtils, StrUtils, UConfig, UDirDelete, UOverwrite, ULocale, +uses SysUtils, DateUtils, StrUtils, UConfig, UOverwrite, ULocale, UFileAssoc, UCoreClasses, URemoteWait, UMain, UGnome, UNewDir, UProgress, crc; @@ -511,38 +509,32 @@ begin FGUIMutex.Release; end; -function TWorkerThread.ShowDirDeleteDialog(ButtonsType: integer; const Label1Text: string; const Label2Text: string = ''; const Label3Text: string = ''; const DirDeleteCaption: string = ''): integer; +function TWorkerThread.ShowDirDeleteDialog(ButtonsType: TFDirDeleteButtonSet; const Title, FileName: string; Error: PGError): integer; begin - FDialogResultDirDelete := integer(mbCancel); - FDirDeleteLabel1Text := Label1Text; - FDirDeleteLabel2Text := Label2Text; - FDirDeleteLabel3Text := Label3Text; - FDirDeleteLabel2Visible := Label2Text <> ''; - FDirDeleteLabel3Visible := Label3Text <> ''; + FDialogResultDirDelete := DIR_DELETE_CANCEL; + FDirDeleteTitle := Title; + FDirDeleteFileName := FileName; + FDirDeleteError := Error; FDirDeleteButtonsType := ButtonsType; - if DirDeleteCaption = '' then FDirDeleteCaption := LANGRemoveDirectory - else FDirDeleteCaption := DirDeleteCaption; FDialogShowDirDelete := True; FCallbackLockEvent.ResetEvent; FCallbackLockEvent.WaitFor(INFINITE); Result := FDialogResultDirDelete; end; -function TWorkerThread.ShowOverwriteDialog(ButtonsType: integer; const FromLabel, FromInfoLabel, ToLabel, ToInfoLabel, RenameStr, SourceFile, DestFile: string): integer; +function TWorkerThread.ShowOverwriteDialog(ShowAppend: boolean; SourceItem, DestItem: PDataItem; const SourceFile, DestFile: string; var RenameStr: string): integer; begin - FDialogResultOverwrite := integer(mbCancel); - FOverwriteButtonsType := ButtonsType; - FOverwriteFromLabel := FromLabel; - FOverwriteFromInfoLabel := FromInfoLabel; - FOverwriteToLabel := ToLabel; - FOverwriteToInfoLabel := ToInfoLabel; - FOverwriteRenameStr := RenameStr; + FDialogResultOverwrite := OVERWRITE_CANCEL; + FOverwriteShowAppend := ShowAppend; + FOverwriteSourceItem := SourceItem; + FOverwriteDestItem := DestItem; FOverwriteSourceFile := SourceFile; FOverwriteDestFile := DestFile; FDialogShowOverwrite := True; FCallbackLockEvent.ResetEvent; FCallbackLockEvent.WaitFor(INFINITE); Result := FDialogResultOverwrite; + RenameStr := FOverwriteRenameStr; end; function TWorkerThread.ShowNewDirDialog(Caption, LabelCaption, Edit: string): integer; @@ -604,6 +596,7 @@ var AFDirDelete: TFDirDelete; ParentDialogForm: TCustomGTKForm; b, ShowRemoteWait: boolean; StartTime: TDateTime; + InfoLabelFormat: string; begin DebugMsg([' ** ProcessThreadEvents --begin']); ShowRemoteWait := False; @@ -712,18 +705,16 @@ begin AFDirDelete := nil; try AFDirDelete := TFDirDelete.Create(ParentDialogForm); - AFDirDelete.Caption := FDirDeleteCaption; AFDirDelete.AddButtons(FDirDeleteButtonsType); - AFDirDelete.Label1.Caption := FDirDeleteLabel1Text; - AFDirDelete.Label2.Caption := FDirDeleteLabel2Text; - AFDirDelete.Label3.Caption := FDirDeleteLabel3Text; - AFDirDelete.Label2.Visible := FDirDeleteLabel2Visible; - AFDirDelete.Label3.Visible := FDirDeleteLabel3Visible; + AFDirDelete.Label1.Caption := FDirDeleteTitle; + AFDirDelete.Label2.Caption := FDirDeleteFileName; + if FDirDeleteError <> nil then + AFDirDelete.Label3.Caption := FDirDeleteError^.message; FDialogResultDirDelete := Integer(AFDirDelete.Run); - if (FDirDeleteButtonsType = 3) and (FDialogResultDirDelete = 2) and (JobType = WORKER_JOB_MOVE) + if (FDirDeleteButtonsType = DIR_DELETE_SET_COPY_ERROR) and (FDialogResultDirDelete = DIR_DELETE_IGNORE) and (JobType = WORKER_JOB_MOVE) then case Application.MessageBox(LANGIgnoreError, [mbYes, mbNo{, mbCancel}], mbWarning, mbYes, mbNo) of - mbNo: FDialogResultDirDelete := 1; - mbCancel: FDialogResultDirDelete := 0; + mbNo: FDialogResultDirDelete := DIR_DELETE_IGNORE; + mbCancel: FDialogResultDirDelete := DIR_DELETE_SKIP; end; finally AFDirDelete.Free; @@ -736,12 +727,16 @@ begin AFOverwrite := nil; try AFOverwrite := TFOverwrite.Create(ParentDialogForm); - AFOverwrite.AddButtons(FOverwriteButtonsType); - AFOverwrite.FromLabel.Caption := FOverwriteFromLabel; - AFOverwrite.FromInfoLabel.Caption := FOverwriteFromInfoLabel; - AFOverwrite.ToLabel.Caption := FOverwriteToLabel; - AFOverwrite.ToInfoLabel.Caption := FOverwriteToInfoLabel; - AFOverwrite.RenameStr := FOverwriteRenameStr; + AFOverwrite.AddButtons(FOverwriteShowAppend); + case ConfSizeFormat of + 5: InfoLabelFormat := '%s, %s'; + else InfoLabelFormat := LANGOvewriteSBytesS; + end; + AFOverwrite.FromLabel.Caption := Format(LANGOverwriteS, [StrToUTF8(FOverwriteSourceItem^.FDisplayName)]); + AFOverwrite.FromInfoLabel.Caption := Format(InfoLabelFormat, [FormatSize(FOverwriteSourceItem^.Size, 0), FormatDate(FOverwriteSourceItem^.mtime, True, True)]); + AFOverwrite.ToLabel.Caption := Format(LANGWithFileS, [StrToUTF8(FOverwriteDestItem^.FDisplayName)]); + AFOverwrite.ToInfoLabel.Caption := Format(InfoLabelFormat, [FormatSize(FOverwriteDestItem^.Size, 0), FormatDate(FOverwriteDestItem^.mtime, True, True)]); + AFOverwrite.RenameStr := ExtractFileName(FOverwriteDestFile); AFOverwrite.SourceFile := FOverwriteSourceFile; AFOverwrite.DestFile := FOverwriteDestFile; FDialogResultOverwrite := Integer(AFOverwrite.Run); @@ -788,8 +783,8 @@ begin with SenderThread as TWorkerThread do if FShowCancelMessage then begin if FCancelMessage = LANGUserCancelled - then Application.MessageBox(FCancelMessage, [mbOK], mbWarning, mbNone, mbOK) - else Application.MessageBox(FCancelMessage, [mbOK], mbError, mbNone, mbOK); + then Application.MessageBox(PGtkWindow(ParentDialogForm.FWidget), FCancelMessage, [mbOK], mbWarning, mbNone, mbOK) + else Application.MessageBox(PGtkWindow(ParentDialogForm.FWidget), FCancelMessage, [mbOK], mbError, mbNone, mbOK); end; // Close all dialogs @@ -830,20 +825,19 @@ var SkipAll: boolean; if not Res then if SkipAll then Result := True else begin - Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.DataItem^.FDisplayName), - Format(LANGCouldNotBeDeletedS, [Error^.message])); + Response := ShowDirDeleteDialog(DIR_DELETE_SET_DELETE_ERROR, 'Error deleting file/directory:', String(AFileRec^.DataItem^.FDisplayName), Error); + if Error <> nil then + g_error_free(Error); case Response of - 1 : Result := True; - 3 : begin + DIR_DELETE_SKIP : Result := True; + DIR_DELETE_SKIP_ALL : begin SkipAll := True; Result := True; end; - 2 : Result := HandleDelete(AFileRec); + DIR_DELETE_RETRY : Result := HandleDelete(AFileRec); else Result := False; end; end; - if Error <> nil then - g_error_free(Error); end; var i: longint; @@ -886,12 +880,11 @@ begin if (not DeleteAll) and (PDataItemSL(AList[i])^.Level = 1) and PDataItemSL(AList[i])^.Stage1 and PDataItemSL(AList[i])^.DataItem^.IsDir and (not PDataItemSL(AList[i])^.DataItem^.IsLnk) and (i < AList.Count - 2) and (PDataItemSL(AList[i + 1])^.Level = 2) then begin - Response := ShowDirDeleteDialog(4, Format(LANGTheDirectorySIsNotEmpty, [string(PDataItemSL(AList[i])^.DataItem^.FDisplayName)]), - LANGDoYouWantToDeleteItWithAllItsFilesAndSubdirectories); + Response := ShowDirDeleteDialog(DIR_DELETE_SET_DELETE_NON_EMPTY, 'The directory is not empty, do you want to delete it with all its files and subdirectories?', string(PDataItemSL(AList[i])^.DataItem^.FDisplayName), nil); case Response of - 1 : ; // Do nothing in this case - I will not bother with changing the structure; it works :-) - 2 : DeleteAll := True; - 3 : SkipToNext := True; + DIR_DELETE_DELETE : ; // Do nothing in this case - I will not bother with changing the structure; it works :-) + DIR_DELETE_ALL : DeleteAll := True; + DIR_DELETE_SKIP : SkipToNext := True; else Break; end; end; @@ -965,18 +958,18 @@ end; if ErrorType <> 1 then s3 := StrToUTF8(FileName) else s3 := ''; - // * TODO: fix error string - case ShowDirDeleteDialog(3, s, s3, 'ahoj' { GetErrorString(ErrorNum)} , s2) of - 0, 252 : begin // Cancel button, Escape + // * TODO: fix error string, port to GError + case ShowDirDeleteDialog(DIR_DELETE_SET_COPY_ERROR, s, s3, nil) of + DIR_DELETE_CANCEL : begin Result := False; FCancelled := True; end; - 2 : Result := True; // Ignore - 3 : begin // Skip All + DIR_DELETE_IGNORE : Result := True; + DIR_DELETE_SKIP_ALL : begin FCopySkipAllErrors := True; { Skip All Err } Result := False; //** True? end; - else {1, 124, 255 :} Result := False; // Skip + else Result := False; // Skip end; end; end; @@ -1207,6 +1200,7 @@ var DefResponse: integer; // Global variables for this function Item: PDataItem; s, s1, s3, cap: string; FromInfoLabel, ToInfoLabel, InfoLabelFormat: string; + RenameStr: string; begin Result := True; try @@ -1258,7 +1252,8 @@ var DefResponse: integer; // Global variables for this function (not ((JobType = WORKER_JOB_MOVE) and (not TwoSameFiles(NewFilePath, AFileRec^.DataItem^.FName, False)) and TwoSameFiles(NewFilePath, AFileRec^.DataItem^.FName, True))) then begin Response := DefResponse; - // * TODO: check error + // * TODO: check error --> display dialog + // * TODO: should be SrcEngine? Item := DestEngine.GetFileInfo(NewFilePath, False, True, nil); if Item = nil then begin DebugMsg(['Something went terribly wrong during copy - Item := DestEngine.GetFileInfoSL(NewFilePath) == NULL!']); @@ -1270,47 +1265,42 @@ var DefResponse: integer; // Global variables for this function 5: InfoLabelFormat := '%s, %s'; else InfoLabelFormat := LANGOvewriteSBytesS; end; - FromInfoLabel := Format(InfoLabelFormat, [FormatSize(Item^.Size, 0), FormatDate(Item^.mtime, True, True)]); - ToInfoLabel := Format(InfoLabelFormat, [FormatSize(AFileRec^.DataItem^.Size, 0), FormatDate(AFileRec^.DataItem^.mtime, True, True)]); - Response := ShowOverwriteDialog(1 + Ord((JobType in [WORKER_JOB_COPY, WORKER_JOB_EXTRACT_TO_TEMP])), Format(LANGOverwriteS, [StrToUTF8(NewFilePath)]), FromInfoLabel, - Format(LANGWithFileS, [AFileRec^.DataItem^.FDisplayName]), ToInfoLabel, - ExtractFileName(StrToUTF8(NewFilePath)), ExtractFileName(AFileRec^.DataItem^.FDisplayName), ExtractFileName(StrToUTF8(NewFilePath))); - s := FOverwriteRenameStr; + RenameStr := ExtractFileName(NewFilePath); + Response := ShowOverwriteDialog(JobType in [WORKER_JOB_COPY], Item, AFileRec^.DataItem, NewFilePath, AFileRec^.DataItem^.FName, RenameStr); case Response of - // 1: Overwrite - // 3: Skip - 2 {Overwrite All}, 5 {Overwrite All Older}, 6 {Skip All}: DefResponse := Response; - 4 {Cancel}, 124 {Close Window}, 255: begin + // OVERWRITE_OVERWRITE + // OVERWRITE_SKIP + OVERWRITE_OVERWRITE_ALL, OVERWRITE_OVERWRITE_ALL_OLDER, OVERWRITE_SKIP_ALL: DefResponse := Response; + OVERWRITE_CANCEL, 124 {Close Window}, 255: begin Result := False; Exit; end; - 7: {Rename} begin - NewFilePath := Copy(NewFilePath, 1, LastDelimiter(PathDelim, NewFilePath)) + s; + OVERWRITE_RENAME: begin + NewFilePath := Copy(NewFilePath, 1, LastDelimiter(PathDelim, NewFilePath)) + RenameStr; Result := HandleCopy(AFileRec, NewFilePath); Exit; end; - 8 {Append}: begin + OVERWRITE_APPEND: begin Res := DoOperation(AFileRec, NewFilePath, ErrorKind, True); end; end; end; // Remove destination file if exists and should be overwritten - if (Response in [1, 2]) or ((Response = 5) and (Item^.mtime < AFileRec^.DataItem^.mtime)) then begin + if (Response in [OVERWRITE_OVERWRITE, OVERWRITE_OVERWRITE_ALL]) or ((Response = OVERWRITE_OVERWRITE_ALL_OLDER) and (Item^.mtime < AFileRec^.DataItem^.mtime)) then begin // * TODO: check error r := ord(DestEngine.Remove(NewFilePath, nil)); while r <> 0 do begin - // * TODO: check error - Res := ShowDirDeleteDialog(1, LANGTheFile, StrToUTF8(String(NewFilePath)), - Format(LANGCouldNotBeDeletedS, ['ahoj' {GetErrorString(r)}]), LANGCopyError); + // * TODO: check error, port to GError + Res := ShowDirDeleteDialog(DIR_DELETE_SET_DELETE_ERROR, 'The file could not be deleted', StrToUTF8(String(NewFilePath)), nil); case Res of - 1: begin + DIR_DELETE_SKIP: begin Result := True; Exit; end; // * TODO: check error - 2: r := Ord(DestEngine.Remove(NewFilePath, nil)); - 0, 124, 255: begin + DIR_DELETE_RETRY: r := Ord(DestEngine.Remove(NewFilePath, nil)); + DIR_DELETE_CANCEL, 124, 255: begin Result := False; Exit; end; @@ -1351,11 +1341,11 @@ var DefResponse: integer; // Global variables for this function s3 := GetErrorString(ErrorKind); end; end; } - Response := ShowDirDeleteDialog(1, s1, StrToUTF8(String(NewFilePath)), s3, cap); + Response := ShowDirDeleteDialog(DIR_DELETE_SET_DELETE_ERROR, s1, StrToUTF8(String(NewFilePath)), nil); case Response of - 1 : Result := True; // Skip - 2 : Result := HandleCopy(AFileRec, NewFilePath); // Retry - 3 : begin // Skip All + DIR_DELETE_SKIP : Result := True; // Skip + DIR_DELETE_RETRY : Result := HandleCopy(AFileRec, NewFilePath); // Retry + DIR_DELETE_SKIP_ALL : begin // Skip All SkipAll := True; Result := True; end; @@ -1968,6 +1958,7 @@ var SkipAll: boolean; function HandleChmod(AFileRec: PDataItemSL): boolean; var Response: integer; Res: boolean; + Error: PGError; begin Result := True; // DebugMsg(['Chmod Debug: IsDir: ', AFileRec^.IsDir, ', Stage1: ', AFileRec^.Stage1, ', IsLnk: ', AFileRec^.IsLnk, '; Result = ', AFileRec^.IsDir and AFileRec^.Stage1 and (not AFileRec^.IsLnk)]); @@ -1975,21 +1966,23 @@ var SkipAll: boolean; if (not AFileRec^.DataItem^.IsDir) and (ChmodRecurseType >= 0) and (ChmodRecurseType = 1) then Exit; // Directories only if AFileRec^.DataItem^.IsDir and (ChmodRecurseType >= 0) and (ChmodRecurseType = 2) then Exit; // Files only // * TODO: check error - Res := AEngine.Chmod(String(AFileRec^.DataItem^.FName), ChmodMode, nil); + Error := nil; + Res := AEngine.Chmod(String(AFileRec^.DataItem^.FName), ChmodMode, @Error); // DebugMsg(['Result : ', Res]); if not Res then if SkipAll then Result := True else begin // * TODO: check error - Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.DataItem^.FDisplayName), Format(LANGCouldNotBeChmoddedS, - ['ahoj' {GetErrorString(Res)}]), LANGDialogChangePermissions); + Response := ShowDirDeleteDialog(DIR_DELETE_SET_DELETE_ERROR, 'Error changing permissions', String(AFileRec^.DataItem^.FDisplayName), Error); + if Error <> nil then + g_error_free(Error); case Response of - 1 : Result := True; - 3 : begin + DIR_DELETE_SKIP : Result := True; + DIR_DELETE_SKIP_ALL : begin SkipAll := True; Result := True; end; - 2 : Result := HandleChmod(AFileRec); + DIR_DELETE_RETRY : Result := HandleChmod(AFileRec); else Result := False; end; end; @@ -2042,27 +2035,30 @@ var SkipAll: boolean; function HandleChown(AFileRec: PDataItemSL): boolean; var Response: integer; Res: boolean; + Error: PGError; begin Result := True; // DebugMsg(['Chown Debug: IsDir: ', AFileRec^.IsDir, ', Stage1: ', AFileRec^.Stage1, ', IsLnk: ', AFileRec^.IsLnk, '; Result = ', AFileRec^.IsDir and AFileRec^.Stage1 and (not AFileRec^.IsLnk)]); if (AFileRec^.DataItem^.IsDir and ChownRecursive and AFileRec^.Stage1 and (not AFileRec^.DataItem^.IsLnk)) or ((not AFileRec^.DataItem^.IsDir) and ChownRecursive) then Exit; // * TODO: check error - Res := AEngine.Chown(String(AFileRec^.DataItem^.FName), ChownUID, ChownGID, nil); + Error := nil; + Res := AEngine.Chown(String(AFileRec^.DataItem^.FName), ChownUID, ChownGID, @Error); // DebugMsg(['Result : ', Res]); if not Res then if SkipAll then Result := True else begin // * TODO: check error - Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.DataItem^.FDisplayName), Format(LANGCouldNotBeChownedS, - ['ahoj' {GetErrorString(Res)}]), LANGDialogChangeOwner); + Response := ShowDirDeleteDialog(DIR_DELETE_SET_DELETE_ERROR, 'Error changing owner', String(AFileRec^.DataItem^.FDisplayName), Error); + if Error <> nil then + g_error_free(Error); case Response of - 1 : Result := True; - 3 : begin + DIR_DELETE_SKIP : Result := True; + DIR_DELETE_SKIP_ALL : begin SkipAll := True; Result := True; end; - 2 : Result := HandleChown(AFileRec); + DIR_DELETE_RETRY : Result := HandleChown(AFileRec); else Result := False; end; end; |
