Skip to main content
Table of Contents

Managing and sharing

Beyond browsing and transferring, TTMSFNCCloudGoogleDrive manages the account's structure and exposes Drive's search, sharing and account features: create and delete folders, move and rename items, search by name, inspect and revoke sharing, and read account quota. Like every Drive request these are asynchronous and report through events. This chapter covers organising items, finding and sharing them, and reading account info.

Creating, renaming, moving and deleting

CreateFolder adds a folder (pass nil as the parent for the root) and reports the new item in OnCreateFolder. RenameFile, MoveFile (and MoveFileToRoot) and Delete (by item or by Drive ID) act on existing items.

Create, rename, move and delete Drive itemsPascalC++
procedure TForm1.CreateReportsFolder;
begin
  TMSFNCCloudGoogleDrive1.OnCreateFolder := DriveFolderCreated;
  TMSFNCCloudGoogleDrive1.CreateFolder(nil, 'Reports');   // nil parent = root
end;

procedure TForm1.DriveFolderCreated(Sender: TObject; const AFolder: TTMSFNCCloudItem;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add('Created folder id ' + AFolder.ID);
end;

procedure TForm1.RenameMoveDelete(AItem, ATargetFolder: TTMSFNCCloudItem);
begin
  TMSFNCCloudGoogleDrive1.RenameFile(AItem, 'Q4-final.xlsx');
  TMSFNCCloudGoogleDrive1.MoveFile(AItem, ATargetFolder);
  TMSFNCCloudGoogleDrive1.Delete(AItem);
end;
void __fastcall TForm1::CreateReportsFolder()
{
  TMSFNCCloudGoogleDrive1->OnCreateFolder = DriveFolderCreated;
  TMSFNCCloudGoogleDrive1->CreateFolder(nullptr, "Reports");   // nullptr parent = root
}

void __fastcall TForm1::DriveFolderCreated(TObject *Sender,
  Fmx::Tmsfnccloudstorage::TTMSFNCCloudItem *AFolder,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    Memo1->Lines->Add("Created folder id " + AFolder->ID);
}

void __fastcall TForm1::RenameMoveDelete(Fmx::Tmsfnccloudstorage::TTMSFNCCloudItem *AItem,
  Fmx::Tmsfnccloudstorage::TTMSFNCCloudItem *ATargetFolder)
{
  TMSFNCCloudGoogleDrive1->RenameFile(AItem, "Q4-final.xlsx");
  TMSFNCCloudGoogleDrive1->MoveFile(AItem, ATargetFolder);
  TMSFNCCloudGoogleDrive1->Delete(AItem);
}

Searching

SearchFile and SearchFolder find files or folders by name; SearchList searches the whole account and Search runs a folder-scoped, filtered query. Results arrive in OnSearch as a TTMSFNCCloudGoogleDriveItems collection.

Search Google DrivePascalC++
procedure TForm1.FindBudgets;
begin
  TMSFNCCloudGoogleDrive1.OnSearch := DriveSearchDone;
  // SearchFile / SearchFolder narrow the result to files or folders;
  // SearchList(query, exact, folder) searches the whole account.
  TMSFNCCloudGoogleDrive1.SearchFile('budget', False);
end;

procedure TForm1.DriveSearchDone(Sender: TObject;
  const ASearchResults: TTMSFNCCloudGoogleDriveItems;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
var
  i: Integer;
begin
  if not ARequestResult.Success then
    Exit;

  for i := 0 to ASearchResults.Count - 1 do
    Memo1.Lines.Add(ASearchResults.Items[i].FileName);
end;
void __fastcall TForm1::FindBudgets()
{
  TMSFNCCloudGoogleDrive1->OnSearch = DriveSearchDone;
  // SearchFile / SearchFolder narrow the result to files or folders;
  // SearchList(query, exact, folder) searches the whole account.
  TMSFNCCloudGoogleDrive1->SearchFile("budget", false);
}

void __fastcall TForm1::DriveSearchDone(TObject *Sender,
  TTMSFNCCloudGoogleDriveItems *ASearchResults,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (!ARequestResult->Success)
    return;

  for (int i = 0; i < ASearchResults->Count; i++)
    Memo1->Lines->Add(ASearchResults->Items[i]->FileName);
}

Sharing

Drive sharing is permission-based. An item's metadata carries its sharing state (Shared, PublicShare) and links (WebContentLink, AlternateLink); RemovePermission revokes the public/anyone permission from an item.

Inspect and revoke Drive sharingPascalC++
type
  { RemovePermission is protected; reach it through a small accessor subclass. }
  TDriveAccess = class(TTMSFNCCloudGoogleDrive);

procedure TForm1.ShowSharing(AItem: TTMSFNCCloudGoogleDriveItem);
begin
  // Sharing state and links arrive on the item with its metadata.
  if AItem.Shared then
    Memo1.Lines.Add('Shared link: ' + AItem.WebContentLink);
  if AItem.PublicShare then
    Memo1.Lines.Add('Item is public');
end;

procedure TForm1.RevokeSharing(AItem: TTMSFNCCloudGoogleDriveItem);
begin
  // Remove the public/anyone permission from the item.
  TDriveAccess(TMSFNCCloudGoogleDrive1).RemovePermission(AItem);
end;
// RemovePermission is declared in a protected section in the C++Builder header,
// so reach it through a small accessor subclass.
class TDriveAccess : public TTMSFNCCloudGoogleDrive
{
public:
  using TTMSFNCCloudGoogleDrive::RemovePermission;
};

void __fastcall TForm1::ShowSharing(TTMSFNCCloudGoogleDriveItem *AItem)
{
  // Sharing state and links arrive on the item with its metadata.
  if (AItem->Shared)
    Memo1->Lines->Add("Shared link: " + AItem->WebContentLink);
  if (AItem->PublicShare)
    Memo1->Lines->Add("Item is public");
}

void __fastcall TForm1::RevokeSharing(TTMSFNCCloudGoogleDriveItem *AItem)
{
  // Remove the public/anyone permission from the item.
  static_cast<TDriveAccess *>(TMSFNCCloudGoogleDrive1)->RemovePermission(AItem);
}

Account information

GetAccountInfo retrieves the connected user and quota into a TTMSFNCCloudGoogleDriveInfo, reported by OnGetCurrentAccount; GetDriveInfo / OnGetSpaceUsage report storage usage.

Read Google Drive account and quota infoPascalC++
procedure TForm1.ShowAccount;
begin
  TMSFNCCloudGoogleDrive1.OnGetCurrentAccount := DriveAccount;
  TMSFNCCloudGoogleDrive1.GetAccountInfo;
end;

procedure TForm1.DriveAccount(Sender: TObject;
  const AInfo: TTMSFNCCloudGoogleDriveInfo;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add(Format('%s — %.0f of %.0f bytes used',
      [AInfo.UserName, AInfo.QuotaUsed, AInfo.Quota]));
end;
void __fastcall TForm1::ShowAccount()
{
  TMSFNCCloudGoogleDrive1->OnGetCurrentAccount = DriveAccount;
  TMSFNCCloudGoogleDrive1->GetAccountInfo();
}

void __fastcall TForm1::DriveAccount(TObject *Sender,
  TTMSFNCCloudGoogleDriveInfo *AInfo,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    Memo1->Lines->Add(Format("%s - %.0f of %.0f bytes used",
      ARRAYOFCONST((AInfo->UserName, (long double)AInfo->QuotaUsed, (long double)AInfo->Quota))));
}

Combining create and move

Chaining the create and move events builds a small workflow — create a folder, then move a file into it once it exists:

Create a folder, then move a file into itPascalC++
procedure TForm1.OrganiseFile(AFile: TTMSFNCCloudItem);
begin
  FPendingFile := AFile;   // remember the file to move once the folder exists
  TMSFNCCloudGoogleDrive1.OnCreateFolder := FolderReadyMoveFile;
  TMSFNCCloudGoogleDrive1.OnMoveFile := DriveFileMoved;
  TMSFNCCloudGoogleDrive1.CreateFolder(nil, 'Archive');
end;

procedure TForm1.FolderReadyMoveFile(Sender: TObject; const AFolder: TTMSFNCCloudItem;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    TMSFNCCloudGoogleDrive1.MoveFile(FPendingFile, AFolder);
end;

procedure TForm1.DriveFileMoved(Sender: TObject; const AFile: TTMSFNCCloudItem;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add('Moved into Archive');
end;
void __fastcall TForm1::OrganiseFile(Fmx::Tmsfnccloudstorage::TTMSFNCCloudItem *AFile)
{
  FPendingFile = AFile;   // remember the file to move once the folder exists
  TMSFNCCloudGoogleDrive1->OnCreateFolder = FolderReadyMoveFile;
  TMSFNCCloudGoogleDrive1->OnMoveFile = DriveFileMoved;
  TMSFNCCloudGoogleDrive1->CreateFolder(nullptr, "Archive");
}

void __fastcall TForm1::FolderReadyMoveFile(TObject *Sender,
  Fmx::Tmsfnccloudstorage::TTMSFNCCloudItem *AFolder,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    TMSFNCCloudGoogleDrive1->MoveFile(FPendingFile, AFolder);
}

void __fastcall TForm1::DriveFileMoved(TObject *Sender,
  Fmx::Tmsfnccloudstorage::TTMSFNCCloudItem *AFile,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    Memo1->Lines->Add("Moved into Archive");
}

Common mistakes

  • Deleting by stale reference. Delete the item (or ID) from a current listing or search, not a cached one whose state may have changed.
  • Expecting a path-based move. MoveFile takes item and target-folder items; obtain the target folder from a listing, search, or CreateFolder result.

See also