ADD: GIO - Google Drive support (fixes #187)

(cherry picked from commit 25c4e77e39)
This commit is contained in:
Alexander Koblov 2026-02-15 15:01:41 +03:00
commit 6d80b002ff
8 changed files with 89 additions and 23 deletions

View file

@ -22,7 +22,7 @@ type
class function GetMainIcon(out Path: String): Boolean; override;
class function IsSupportedPath(const Path: String): Boolean; override;
class function CreateFile(const APath: String; AFolder: PGFile; AFileInfo: PGFileInfo): TFile; override;
class function CreateFile(const APath: String; AFolder, AFile: PGFile; AFileInfo: PGFileInfo): TFile; override;
end;
implementation
@ -54,12 +54,12 @@ begin
Result:= StrBegins(Path, 'network://');
end;
class function TNetworkFileSource.CreateFile(const APath: String;
AFolder: PGFile; AFileInfo: PGFileInfo): TFile;
class function TNetworkFileSource.CreateFile(const APath: String; AFolder,
AFile: PGFile; AFileInfo: PGFileInfo): TFile;
var
ADisplayName: String;
begin
Result:= inherited CreateFile(APath, AFolder, AFileInfo);
Result:= inherited CreateFile(APath, AFolder, AFile, AFileInfo);
ADisplayName:= g_file_info_get_display_name(AFileInfo);
if Length(ADisplayName) > 0 then Result.Name:= ADisplayName;
end;

View file

@ -60,7 +60,7 @@ begin
for AIndex:= 0 to FFiles.Count - 1 do
begin
AFile:= FFiles[AIndex];
SourceFile:= GioNewFile(AFile.FullPath);
SourceFile:= TGioFileLinkProperty(AFile.LinkProperty).Item;
try
AInfo:= g_file_query_info(SourceFile, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, nil, nil);
if Assigned(AInfo) then
@ -201,7 +201,11 @@ begin
begin
AVariant:= TFileVariantProperty.Create(AVariantProperties[AIndex]);
AGFile:= GioNewFile(AFile.FullPath);
if AFile.LinkProperty is TGioFileLinkProperty then
AGFile:= TGioFileLinkProperty(AFile.LinkProperty).Item
else begin
AGFile:= GioNewFile(AFile.FullPath);
end;
AInfo:= g_file_query_info(AGFile, 'trash::*', G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, nil, nil);
if Assigned(AInfo) then

View file

@ -100,6 +100,7 @@ end;
procedure TGioCalcStatisticsOperation.ProcessSubDirs(const srcPath: String);
var
AFile: TFile;
AChild: PGFile;
AFolder: PGFile;
AInfo: PGFileInfo;
AFileName: Pgchar;
@ -120,7 +121,8 @@ begin
if (aFileName <> '.') and (aFileName <> '..') then
begin
aFile:= TGioFileSource.CreateFile(srcPath, AFolder, AInfo);
AChild:= g_file_enumerator_get_child(AFileEnum, AInfo);
aFile:= TGioFileSource.CreateFile(srcPath, AFolder, AChild, AInfo);
try
ProcessFile(aFile);
finally

View file

@ -143,7 +143,7 @@ begin
//if FileIsReadOnly(aFile.Attributes) then
// mbFileSetReadOnly(FileName, False);
AGFile:= GioNewFile(FileName);
AGFile:= TGioFileLinkProperty(aFile.LinkProperty).Item;
Result:= g_file_delete(AGFile, nil, nil);
g_object_unref(PGObject(AGFile));

View file

@ -42,7 +42,7 @@ type
function GetFreeSpace(Path: String; out FreeSize, TotalSize : Int64) : Boolean; override;
class function CreateFile(const APath: String): TFile; override;
class function CreateFile(const APath: String; AFolder: PGFile; AFileInfo: PGFileInfo): TFile; virtual;
class function CreateFile(const APath: String; AFolder, AFile: PGFile; AFileInfo: PGFileInfo): TFile; virtual;
procedure Reload(const PathsToReload: TPathsArray); override;
function GetParentDir(sPath : String): String; override;
@ -80,7 +80,8 @@ uses
DCFileAttributes, DCDateTimeUtils, uGioListOperation, uGioCopyOperation,
uGioDeleteOperation, uGioExecuteOperation, uGioCreateDirectoryOperation,
uGioMoveOperation, uGioSetFilePropertyOperation, uDebug, fGioAuthDlg,
DCBasicTypes, uShowMsg, uGioCalcStatisticsOperation, uGio, uFileSourceManager;
DCBasicTypes, uShowMsg, uGioCalcStatisticsOperation, uGio, uFileSourceManager,
uGioFileSourceUtil;
type
@ -139,25 +140,25 @@ begin
ModificationTimeProperty := TFileModificationDateTimeProperty.Create;
CreationTimeProperty := TFileCreationDateTimeProperty.Create;
LastAccessTimeProperty := TFileLastAccessDateTimeProperty.Create;
LinkProperty := TFileLinkProperty.Create;
LinkProperty := TGioFileLinkProperty.Create;
OwnerProperty := TFileOwnerProperty.Create;
TypeProperty := TFileTypeProperty.Create;
CommentProperty := TFileCommentProperty.Create;
end;
end;
class function TGioFileSource.CreateFile(const APath: String; AFolder: PGFile;
AFileInfo: PGFileInfo): TFile;
class function TGioFileSource.CreateFile(const APath: String; AFolder,
AFile: PGFile; AFileInfo: PGFileInfo): TFile;
var
Addr: TURI;
AFile: PGFile;
ATarget: Pgchar;
AFileType: TGFileType;
AFileTime: TFileTimeEx;
ASymlinkInfo: PGFileInfo;
begin
Result:= CreateFile(APath);
Result.Name:= g_file_info_get_name(AFileInfo);
Result.Name:= g_file_info_get_display_name(AFileInfo);
TGioFileLinkProperty(Result.LinkProperty).Item:= AFile;
Result.Attributes:= g_file_info_get_attribute_uint32(AFileInfo, FILE_ATTRIBUTE_UNIX_MODE);
AFileTime.sec:= Int64(g_file_info_get_attribute_uint64(AFileInfo, FILE_ATTRIBUTE_TIME_MODIFIED));
AFileTime.nanosec:= Int64(g_file_info_get_attribute_uint32(AFileInfo, FILE_ATTRIBUTE_TIME_MODIFIED_USEC)) * 1000;
@ -187,6 +188,12 @@ begin
Result.LinkProperty.LinkTo := ATarget;
AFile:= g_file_get_child(AFolder, ATarget);
if (AFile = nil) and (DCStrUtils.GetPathType(ATarget) = ptAbsolute) then
begin
Addr:= ParseURI(APath);
Addr.Path:= Result.LinkProperty.LinkTo;
AFile:= GioNewFile(EncodeURI(Addr));
end;
Result.LinkProperty.IsValid:= Assigned(AFile);
if Result.LinkProperty.IsValid then

View file

@ -8,7 +8,7 @@ uses
Classes, SysUtils, DCStrUtils, uFile, uFileSource, uFileSourceOperation,
uFileSourceCopyOperation, uFileSystemUtil, uFileSourceOperationOptions,
uFileSourceTreeBuilder, uGioFileSource, uGLib2, uGio2, uLog, uGlobs,
uFileSourceOperationUI;
uFileSourceOperationUI, uFileProperty;
const
CONST_DEFAULT_QUERY_INFO_ATTRIBUTES = FILE_ATTRIBUTE_STANDARD_TYPE + ',' + FILE_ATTRIBUTE_STANDARD_NAME + ',' +
@ -23,6 +23,18 @@ type
TUpdateStatisticsFunction = procedure(var NewStatistics: TFileSourceCopyOperationStatistics) of object;
TCopyMoveFileFunction = function(source: PGFile; destination: PGFile; flags: TGFileCopyFlags; cancellable: PGCancellable; progress_callback: TGFileProgressCallback; progress_callback_data: gpointer; error: PPGError): gboolean; cdecl;
{ TGioFileLinkProperty }
TGioFileLinkProperty = class(TFileLinkProperty)
private
FItem: PGFile;
public
destructor Destroy; override;
function Clone: TFileLinkProperty; override;
procedure CloneTo(FileProperty: TFileProperty); override;
property Item: PGFile read FItem write FItem;
end;
{ TGioTreeBuilder }
TGioTreeBuilder = class(TFileSourceTreeBuilder)
@ -113,7 +125,7 @@ procedure FillAndCount(Files: TFiles; CountDirs: Boolean; out NewFiles: TFiles;
implementation
uses
Forms, Math, DateUtils, DCBasicTypes, DCDateTimeUtils, uDCUtils, uFileProperty,
Forms, Math, DateUtils, DCBasicTypes, DCDateTimeUtils, uDCUtils,
uShowMsg, uLng, uGObject2, uGio, DCFileAttributes;
procedure ShowError(AError: PGError);
@ -130,6 +142,7 @@ var
procedure FillAndCountRec(const srcPath: String);
var
AChild: PGFile;
AFolder: PGFile;
AInfo: PGFileInfo;
AFileName: Pgchar;
@ -150,7 +163,8 @@ var
if (aFileName <> '.') and (aFileName <> '..') then
begin
aFile:= TGioFileSource.CreateFile(srcPath, AFolder, AInfo);
AChild:= g_file_enumerator_get_child(AFileEnum, AInfo);
aFile:= TGioFileSource.CreateFile(srcPath, AFolder, AChild, AInfo);
NewFiles.Add(aFile);
if aFile.IsLink then
@ -243,6 +257,33 @@ begin
end;
end;
{ TGioFileLinkProperty }
destructor TGioFileLinkProperty.Destroy;
begin
inherited Destroy;
if Assigned(FItem) then g_object_unref(PGObject(FItem));
end;
function TGioFileLinkProperty.Clone: TFileLinkProperty;
begin
Result := TGioFileLinkProperty.Create;
CloneTo(Result);
end;
procedure TGioFileLinkProperty.CloneTo(FileProperty: TFileProperty);
begin
if Assigned(FileProperty) then
begin
inherited CloneTo(FileProperty);
if FileProperty is TGioFileLinkProperty then
begin
TGioFileLinkProperty(FileProperty).FItem := g_file_dup(Self.FItem);
end;
end;
end;
{ TGioTreeBuilder }
procedure TGioTreeBuilder.AddLinkTarget(aFile: TFile; CurrentNode: TFileTreeNode);
@ -264,6 +305,7 @@ procedure TGioTreeBuilder.AddFilesInDirectory(srcPath: String;
CurrentNode: TFileTreeNode);
var
AFile: TFile;
AChild: PGFile;
AFolder: PGFile;
AInfo: PGFileInfo;
AError: PGError = nil;
@ -279,7 +321,8 @@ begin
while Assigned(AInfo) do
begin
CheckOperationState;
AFile:= TGioFileSource.CreateFile(srcPath, AFolder, AInfo);
AChild:= g_file_enumerator_get_child(AFileEnum, AInfo);
AFile:= TGioFileSource.CreateFile(srcPath, AFolder, AChild, AInfo);
g_object_unref(AInfo);
AddItem(aFile, CurrentNode);
AInfo:= g_file_enumerator_next_file(AFileEnum, nil, @AError);
@ -402,7 +445,11 @@ var
begin
NodeData := aNode.Data as TFileTreeNodeData;
SourceFile:= GioNewFile(aNode.TheFile.FullPath);
if aNode.TheFile.LinkProperty is TGioFileLinkProperty then
SourceFile:= TGioFileLinkProperty(aNode.TheFile.LinkProperty).Item
else begin
SourceFile:= GioNewFile(aNode.TheFile.FullPath);
end;
TargetFile:= GioNewFile(AbsoluteTargetFileName);
try
// If some files will not be moved then source directory cannot be deleted.
@ -486,7 +533,11 @@ begin
FOldDoneBytes:= FStatistics.DoneBytes;
FCancel:= g_cancellable_new();
SourceFile:= GioNewFile(aNode.TheFile.FullPath);
if aNode.TheFile.LinkProperty is TGioFileLinkProperty then
SourceFile:= TGioFileLinkProperty(aNode.TheFile.LinkProperty).Item
else begin
SourceFile:= GioNewFile(aNode.TheFile.FullPath);
end;
TargetFile:= GioNewFile(AbsoluteTargetFileName);
try

View file

@ -41,6 +41,7 @@ end;
procedure TGioListOperation.MainExecute;
var
AFile: TFile;
AChild: PGFile;
AFolder: PGFile;
AInfo: PGFileInfo;
AError: PGError = nil;
@ -88,7 +89,8 @@ begin
while Assigned(AInfo) do
begin
CheckOperationState;
AFile:= AFileSource.CreateFile(Path, AFolder, AInfo);
AChild:= g_file_enumerator_get_child(AFileEnum, AInfo);
AFile:= AFileSource.CreateFile(Path, AFolder, AChild, AInfo);
g_object_unref(AInfo);
FFiles.Add(AFile);
AInfo:= g_file_enumerator_next_file(AFileEnum, nil, @AError);

View file

@ -142,7 +142,7 @@ var
begin
Result := sfprSuccess;
AGFile:= GioNewFile(aFile.FullPath);
AGFile:= TGioFileLinkProperty(aFile.LinkProperty).Item;
case aTemplateProperty.GetID of
fpName:
if (aTemplateProperty as TFileNameProperty).Value <> aFile.Name then