ADD: SetFileProperties Dialog: Creation Time can be modified on MacOS (#944)

This commit is contained in:
rich2014 2023-04-27 17:15:39 +08:00 committed by GitHub
commit 4aaf99db9a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 24 deletions

View file

@ -0,0 +1,33 @@
unit DCDarwin;
{$mode delphi}
{$modeswitch objectivec1}
interface
uses
Classes, SysUtils, BaseUnix, CocoaAll;
// MacOS File Utils
function MacosFileSetCreationTime( const path:String; const birthtime:time_t ): Boolean;
implementation
function StringToNSString(const S: String): NSString;
begin
Result:= NSString(NSString.stringWithUTF8String(PAnsiChar(S)));
end;
function MacosFileSetCreationTime( const path:String; const birthtime:time_t ): Boolean;
var
attrs: NSMutableDictionary;
nsPath: NSString;
begin
attrs:= NSMutableDictionary.dictionaryWithCapacity( 1 );
attrs.setValue_forKey( NSDate.dateWithTimeIntervalSince1970(birthtime), NSFileCreationDate );
nsPath:= StringToNSString( path );
Result:= NSFileManager.defaultManager.setAttributes_ofItemAtPath_error( attrs, nsPath, nil );
end;
end.

View file

@ -543,7 +543,6 @@ end;
var
Option: TCopyAttributesOption;
StatInfo : TDCStat;
utb : BaseUnix.TUTimBuf;
mode : TMode;
begin
if DC_fpLStat(UTF8ToSys(sSrc), StatInfo) < 0 then
@ -583,28 +582,15 @@ begin
begin
if caoCopyTime in Options then
begin
utb.actime := time_t(StatInfo.st_atime); // last access time
{$IF DEFINED(DARWIN)}
utb.modtime := time_t(StatInfo.st_birthtime); // creation time
{$ELSE}
utb.modtime := time_t(StatInfo.st_mtime); // last modification time
{$ENDIF}
if fputime(UTF8ToSys(sDst), @utb) <> 0 then
if DC_FileSetTime(
sDst,
StatInfo.st_mtime,
{$IFDEF DARWIN} StatInfo.st_birthtime {$ELSE} 0 {$ENDIF},
StatInfo.st_atime) = false then
begin
Include(Result, caoCopyTime);
if Assigned(Errors) then Errors^[caoCopyTime]:= GetLastOSError;
end;
{$IF DEFINED(DARWIN)}
// creation time supported in MacOS:
// 1. the first call fputime above: set creation time
// 2. the second call here: set modification time
utb.modtime := time_t(StatInfo.st_mtime); // last modification time
if fputime(UTF8ToSys(sDst), @utb) <> 0 then
begin
Include(Result, caoCopyTime);
if Assigned(Errors) then Errors^[caoCopyTime]:= GetLastOSError;
end;
{$ENDIF}
end;
if caoCopyOwnership in Options then
@ -975,14 +961,14 @@ begin
end;
{$ELSE}
var
t: TUTimBuf;
CurrentModificationTime, CurrentCreationTime, CurrentLastAccessTime: DCBasicTypes.TFileTime;
begin
if mbFileGetTime(FileName,CurrentModificationTime, CurrentCreationTime, CurrentLastAccessTime) then
begin
if LastAccessTime<>0 then t.actime := time_t(LastAccessTime) else t.actime := time_t(CurrentLastAccessTime);
if ModificationTime<>0 then t.modtime := time_t(ModificationTime) else t.modtime := time_t(CurrentModificationTime);
Result := (fputime(UTF8ToSys(FileName), @t) <> -1);
if ModificationTime<>0 then CurrentModificationTime:= ModificationTime;
if CreationTime<>0 then CurrentCreationTime:= CreationTime;
if LastAccessTime<>0 then CurrentLastAccessTime:= LastAccessTime;
Result := DC_FileSetTime(FileName,CurrentModificationTime, CurrentCreationTime, CurrentLastAccessTime);
end
else
begin

View file

@ -156,6 +156,10 @@ type
{$ENDIF}
Function DC_fpLstat( const path:RawByteString; var Info:TDCStat ): cint; inline;
function DC_FileSetTime(const FileName: String;
const mtime : time_t;
const birthtime: time_t;
const atime : time_t ): Boolean;
{en
@ -249,7 +253,11 @@ function fnmatch(const pattern: PAnsiChar; const str: PAnsiChar; flags: cint): c
implementation
uses
Unix, DCConvertEncoding;
Unix, DCConvertEncoding, LazUTF8
{$IFDEF DARWIN}
, DCDarwin
{$ENDIF}
;
{$IF DEFINED(DARWIN)}
@ -273,6 +281,26 @@ end;
{$ENDIF}
function DC_FileSetTime(const FileName: String;
const mtime : time_t;
const birthtime: time_t;
const atime : time_t ): Boolean;
var
utb: BaseUnix.TUTimBuf;
begin
Result:= false;
utb.actime:= atime; // last access time
utb.modtime:= mtime; // last modification time
if fputime(UTF8ToSys(FileName), @utb) <> 0 then exit;
{$IF not DEFINED(DARWIN)}
Result:= true;
{$ELSE}
Result:= MacosFileSetCreationTime( FileName, birthtime );
{$ENDIF}
end;
{$IF DEFINED(BSD)}