Table of Contents

Folder and file operations

Once connected, TTMSFNCCloudDropBox organises the account's structure: listing folders, creating new ones, and moving, renaming or deleting existing items. Every request is asynchronous — a method returns immediately and the outcome arrives in a matching On... event carrying a TTMSFNCCloudBaseRequestResult. This chapter covers listing, creating, and managing items, and how to chain those steps together.

The async result model

No Dropbox method blocks waiting for the network. Check ARequestResult.Success first, and read ARequestResult.ResultString for the raw response or error detail on failure. Returned items are TTMSFNCCloudDropBoxItem objects (a TTMSFNCCloudItem descendant) exposing FileName, Size, ID, Path, ParentPath and FullPath.

Listing a folder

GetFolderList lists a folder — pass nil (or no argument) for the account root, or a folder item to list its contents. Dropbox returns folders in pages: items arrive incrementally in OnGetFolderList, and OnGetFolderListComplete fires once with the full listing when every page has been retrieved. FileLimit caps how many items a single listing returns.

procedure TForm1.ListRootFolder;
begin
  TMSFNCCloudDropBox1.OnGetFolderListComplete := RootFolderListed;
  TMSFNCCloudDropBox1.GetFolderList; // nil / no argument = account root
end;

procedure TForm1.RootFolderListed(Sender: TObject; const AFolderList: TTMSFNCCloudItems;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
var
  i: Integer;
begin
  if not ARequestResult.Success then
    Exit;

  for i := 0 to AFolderList.Count - 1 do
    Memo1.Lines.Add(AFolderList[i].FileName);
end;

For a recursive tree, GetFolderListHierarchical walks subfolders. To resolve a single item you already know the provider ID for, GetFileByID returns it directly without listing its parent folder; the returned TTMSFNCCloudDropBoxItem.ParentPath gives you the path of the folder that contains it.

function TForm1.ShowParentOfItem(const AItemID: string): string;
var
  it: TTMSFNCCloudItem;
begin
  Result := '';
  it := TMSFNCCloudDropBox1.GetFileByID(AItemID);
  if Assigned(it) and (it is TTMSFNCCloudDropBoxItem) then
    Result := TTMSFNCCloudDropBoxItem(it).ParentPath;
end;

Creating, moving, renaming and deleting

CreateFolder adds a folder (pass nil as the parent for the root) and reports the new item in OnCreateFolder. MoveFile moves an item into a target folder, MoveFileToRoot moves it back to the account root, and RenameFile changes its name — each raises OnMoveFile / OnRenameFile. Delete removes an item, by reference or by full path.

procedure TForm1.CreateReportsFolder;
begin
  TMSFNCCloudDropBox1.OnCreateFolder := DropBoxFolderCreated;
  TMSFNCCloudDropBox1.CreateFolder(nil, 'Reports'); // nil parent = root
end;

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

procedure TForm1.MoveRenameDeleteItem(AItem, ATargetFolder: TTMSFNCCloudItem);
begin
  TMSFNCCloudDropBox1.OnMoveFile := DropBoxFileMoved;
  TMSFNCCloudDropBox1.OnRenameFile := DropBoxFileRenamed;
  TMSFNCCloudDropBox1.OnDeleteItem := DropBoxItemDeleted;

  TMSFNCCloudDropBox1.MoveFile(AItem, ATargetFolder);
  TMSFNCCloudDropBox1.RenameFile(AItem, 'Q4-final.pdf');
  TMSFNCCloudDropBox1.Delete(AItem);
end;

procedure TForm1.DropBoxFileMoved(Sender: TObject; const AFile: TTMSFNCCloudItem;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add('Moved to ' + AFile.FileName);
end;

procedure TForm1.DropBoxFileRenamed(Sender: TObject; const AFile: TTMSFNCCloudItem;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add('Renamed to ' + AFile.FileName);
end;

procedure TForm1.DropBoxItemDeleted(Sender: TObject;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add('Item deleted');
end;

Combining create, move and rename

Because each step is event-driven, you chain operations by starting the next one from the previous completion event. This creates a folder, then moves a file into it and renames it once the folder exists:

// Assumes a private field: FItemToArchive: TTMSFNCCloudItem;
// (needed to carry the item across the CreateFolder -> MoveFile event chain).
procedure TForm1.ArchiveItem(AItem: TTMSFNCCloudItem);
begin
  FItemToArchive := AItem;
  TMSFNCCloudDropBox1.OnCreateFolder := DropBoxArchiveFolderCreated;
  TMSFNCCloudDropBox1.OnMoveFile := DropBoxArchiveFileMoved;
  TMSFNCCloudDropBox1.CreateFolder(nil, 'Archive');
end;

procedure TForm1.DropBoxArchiveFolderCreated(Sender: TObject; const AFolder: TTMSFNCCloudItem;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    TMSFNCCloudDropBox1.MoveFile(FItemToArchive, AFolder);
end;

procedure TForm1.DropBoxArchiveFileMoved(Sender: TObject; const AFile: TTMSFNCCloudItem;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    TMSFNCCloudDropBox1.RenameFile(AFile, 'archived-' + AFile.FileName);
end;

Synchronous mode

Reach for synchronous mode when the calls are part of a batch job, a startup step, or a console/service routine rather than a responsive UI: it collapses an event chain into ordinary sequential code. BeginSync switches the component so every request blocks until Dropbox answers, which means the method's return value is filled in by the time the call returns — GetFolderList hands back the items, CreateFolder hands back the new folder, and no On... handler is needed. EndSync restores the default asynchronous behaviour.

procedure TForm1.ListRootSynchronously;
var
  Items: TTMSFNCCloudItems;
  I: Integer;
begin
  // In sync mode every request blocks until Dropbox answers, so the method's
  // return value is already filled in when the call comes back.
  TMSFNCCloudDropBox1.BeginSync;
  try
    Items := TMSFNCCloudDropBox1.GetFolderList;
    if Assigned(Items) then
      for I := 0 to Items.Count - 1 do
        ListBox1.Items.Add(Items[I].FileName);
  finally
    // Always leave sync mode again so UI-facing calls stay asynchronous.
    TMSFNCCloudDropBox1.EndSync;
  end;
end;

Because sync mode blocks the calling thread, never leave it on for work started from the UI thread of an interactive form — wrap the batch in try ... finally EndSync so a failure cannot leave the component blocking.

Combining synchronous mode with create, list and move

Synchronous mode is at its most useful when several operations depend on each other. The same create-then-move flow that needs three chained event handlers in async mode becomes three consecutive statements:

procedure TForm1.ArchiveOldReports;
var
  Archive: TTMSFNCCloudItem;
  Items: TTMSFNCCloudItems;
  I: Integer;
begin
  // Sync mode turns the usual event chain (create -> list -> move) into three
  // ordinary statements, which is what makes a batch job like this readable.
  TMSFNCCloudDropBox1.BeginSync;
  try
    Archive := TMSFNCCloudDropBox1.CreateFolder(nil, 'Archive');
    if not Assigned(Archive) then
      Exit;

    Items := TMSFNCCloudDropBox1.GetFolderList;
    if not Assigned(Items) then
      Exit;

    for I := Items.Count - 1 downto 0 do
      if (Items[I].ItemType = ciFile) and (Items[I].ModifiedDate < Now - 365) then
        TMSFNCCloudDropBox1.MoveFile(Items[I], Archive);
  finally
    TMSFNCCloudDropBox1.EndSync;
  end;
end;

Common mistakes

  • Reading results outside the event. In the default asynchronous mode a method returns before the network call completes — use the On... event, not the method's return value, for the data. The return value is only meaningful inside BeginSync/EndSync, or for GetFileByID, which always performs its request synchronously.
  • Deleting by a stale reference. Delete the item returned by a current listing or search, not a cached one whose path may have changed after a rename or move.
  • Assuming GetFolderList is complete after OnGetFolderList. That event fires per page; wait for OnGetFolderListComplete before treating the listing as final.
  • TTMSFNCCloudDropBoxGetFolderList, GetFolderListHierarchical, GetFileByID, CreateFolder, MoveFile, MoveFileToRoot, RenameFile, Delete, FileLimit, BeginSync, EndSync
  • TTMSFNCCloudDropBoxItemParentPath, FullPath, Path

See also