1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00

Translating TDriveViewInt's ReadSubDirs, DoScanDir and AddChildNode to C++ before modifying them

Source commit: f8c0cdbb0c4e8665eac9a9b9526d6714ed6457cf
This commit is contained in:
Martin Prikryl
2026-10-05 13:30:38 +00:00
parent a6916d4101
commit a9fa4a583a
3 changed files with 74 additions and 76 deletions

View File

@@ -69,3 +69,66 @@ void __fastcall TDriveView::CreateWnd()
AddStartupSequence(L"V" + StartupSequenceTag);
#endif
}
//---------------------------------------------------------------------------
void __fastcall TDriveView::ReadSubDirs(TTreeNode * Node)
{
auto NodeData = static_cast<TNodeData *>(Node->Data);
UnicodeString Path = NodePath(Node);
TSearchRec SRec;
if (!FindFirstSubDir(IncludeTrailingBackslash(Path) + L"*.*", SRec))
{
Node->HasChildren = false;
}
else
{
int CheckInterval = 100;
int Limit = DriveViewLoadingTooLongLimit * 1000;
if (!Showing)
{
Limit /= 10;
CheckInterval /= 10;
}
if (!ReadSubDirsBatch(Node, SRec, CheckInterval, Limit))
{
NodeData->DelayedSrec = SRec;
NodeData->DelayedExclude = new TStringList();
NodeData->DelayedExclude->CaseSensitive = false;
NodeData->DelayedExclude->Sorted = true;
FDelayedNodes->AddObject(Path, Node);
DebugAssert(FDelayedNodes->Count < 20); // if more, something went likely wrong
UpdateDelayedNodeTimer();
}
SortChildren(Node, false);
}
NodeData->Scanned = true;
Application->ProcessMessages();
}
//---------------------------------------------------------------------------
bool __fastcall TDriveView::DoScanDir(TTreeNode * FromNode)
{
return !static_cast<TNodeData *>(FromNode->Data)->IsRecycleBin;
}
//---------------------------------------------------------------------------
void __fastcall TDriveView::AddChildNode(TTreeNode * ParentNode, UnicodeString ParentPath, const TSearchRec & SRec)
{
auto NodeData = new TNodeData();
NodeData->Attr = SRec.Attr;
NodeData->DirName = SRec.Name;
NodeData->IsRecycleBin =
FLAGSET(SRec.Attr, faSysFile) &&
(ParentNode->Parent == nullptr) &&
(SameText(SRec.Name, L"RECYCLED") ||
SameText(SRec.Name, L"RECYCLER") ||
SameText(SRec.Name, L"$RECYCLE.BIN"));
NodeData->Scanned = false;
TTreeNode * NewNode = Items->AddChildObject(ParentNode, EmptyStr, NodeData);
NewNode->Text = GetDisplayName(NewNode);
NewNode->HasChildren = true;
if (GetDriveTypetoNode(ParentNode) != DRIVE_REMOTE)
{
FSubDirReaderThread->Add(NewNode, IncludeTrailingBackslash(ParentPath) + SRec.Name);
}
}

View File

@@ -18,6 +18,9 @@ protected:
virtual bool __fastcall GetNextDriveStatus(int & Iterator, UnicodeString * Drive, TDriveStatus *& Status);
virtual void __fastcall CreateWnd();
virtual void __fastcall ReadSubDirs(TTreeNode * Node);
virtual bool __fastcall DoScanDir(TTreeNode * FromNode);
virtual void __fastcall AddChildNode(TTreeNode * ParentNode, UnicodeString ParentPath, const TSearchRec & SRec);
private:
TDriveStatus * GetDriveStatus(int Index);

View File

@@ -94,7 +94,7 @@ type
property Attr: Integer read FAttr write FAttr;
property Scanned: Boolean read FScanned write FScanned;
property Data: Pointer read FData write FData;
property IsRecycleBin: Boolean read FIsRecycleBin;
property IsRecycleBin: Boolean read FIsRecycleBin write FIsRecycleBin;
property IconEmpty: Boolean read FIconEmpty write FIconEmpty;
property Schedule: TSubDirReaderSchedule read FSchedule write FSchedule;
end;
@@ -108,7 +108,8 @@ type
destructor Destroy; override;
procedure Terminate; override;
protected
// temporarily, as we need to access it from C++ code in other unit
public
constructor Create(DriveView: TDriveViewInt);
procedure Add(Node: TTreeNode; Path: string);
procedure Delete(Node: TTreeNode);
@@ -139,7 +140,7 @@ type
TTreeNodeArray = array of TTreeNode;
TDriveViewInt = class(TCustomDriveView)
private
protected
FConfirmDelete: Boolean;
FConfirmOverwrite: Boolean;
FWatchDirectory: Boolean;
@@ -179,7 +180,7 @@ type
function GetSubDir(var SRec: TSearchRec): Boolean;
function FindFirstSubDir(Path: string; var SRec: TSearchRec): Boolean;
function FindNextSubDir(var SRec: TSearchRec): Boolean;
procedure ReadSubDirs(Node: TTreeNode);
procedure ReadSubDirs(Node: TTreeNode); virtual; abstract;
procedure CancelDelayedNode(Node: TTreeNode);
procedure DelayedNodeTimer(Sender: TObject);
function ReadSubDirsBatch(Node: TTreeNode; var SRec: TSearchRec; CheckInterval, Limit: Integer): Boolean;
@@ -203,13 +204,13 @@ type
// Notification procedure used by component TTimer:
procedure ChangeTimerOnTimer(Sender: TObject);
protected
// former protected boundary
procedure SetSelected(Node: TTreeNode);
procedure SetWatchDirectory(Value: Boolean);
procedure SetDirView(Value: TDirViewInt);
procedure SetDirectory(Value: string); override;
function DoScanDir(FromNode: TTreeNode): Boolean;
procedure AddChildNode(ParentNode: TTreeNode; ParentPath: string; SRec: TSearchRec);
function DoScanDir(FromNode: TTreeNode): Boolean; virtual; abstract;
procedure AddChildNode(ParentNode: TTreeNode; ParentPath: string; SRec: TSearchRec); virtual; abstract;
procedure CreateWatchThread(Drive: string);
function NodeWatched(Node: TTreeNode): Boolean;
procedure TerminateWatchThread(Drive: string);
@@ -1588,35 +1589,6 @@ begin
end;
end;
procedure TDriveViewInt.AddChildNode(ParentNode: TTreeNode; ParentPath: string; SRec: TSearchRec);
var
NewNode: TTreeNode;
NodeData: TNodeData;
begin
NodeData := TNodeData.Create;
NodeData.Attr := SRec.Attr;
NodeData.DirName := SRec.Name;
NodeData.FIsRecycleBin :=
(SRec.Attr and faSysFile <> 0) and
(not Assigned(ParentNode.Parent)) and
(SameText(SRec.Name, 'RECYCLED') or
SameText(SRec.Name, 'RECYCLER') or
SameText(SRec.Name, '$RECYCLE.BIN'));
NodeData.Scanned := False;
NewNode := Self.Items.AddChildObject(ParentNode, '', NodeData);
NewNode.Text := GetDisplayName(NewNode);
NewNode.HasChildren := True;
if GetDriveTypeToNode(ParentNode) <> DRIVE_REMOTE then
FSubDirReaderThread.Add(NewNode, IncludeTrailingBackslash(ParentPath) + SRec.Name);
end;
function TDriveViewInt.DoScanDir(FromNode: TTreeNode): Boolean;
begin
Result := not TNodeData(FromNode.Data).IsRecycleBin;
end;
function TDriveViewInt.DirAttrMask: Integer;
begin
Result := faDirectory or faSysFile;
@@ -1961,46 +1933,6 @@ begin
FDelayedNodeTimer.Enabled := HandleAllocated and (FDelayedNodes.Count > 0);
end;
procedure TDriveViewInt.ReadSubDirs(Node: TTreeNode);
var
SRec: TSearchRec;
NodeData: TNodeData;
Path: string;
CheckInterval, Limit: Integer;
begin
NodeData := TNodeData(Node.Data);
Path := NodePath(Node);
if not FindFirstSubDir(IncludeTrailingBackslash(Path) + '*.*', SRec) then
begin
Node.HasChildren := False;
end
else
begin
CheckInterval := 100;
Limit := DriveViewLoadingTooLongLimit * 1000;
if not Showing then
begin
Limit := Limit div 10;
CheckInterval := CheckInterval div 10;
end;
if not ReadSubDirsBatch(Node, SRec, CheckInterval, Limit) then
begin
NodeData.DelayedSrec := SRec;
NodeData.DelayedExclude := TStringList.Create;
NodeData.DelayedExclude.CaseSensitive := False;
NodeData.DelayedExclude.Sorted := True;
FDelayedNodes.AddObject(Path, Node);
Assert(FDelayedNodes.Count < 20); // if more, something went likely wrong
UpdateDelayedNodeTimer;
end;
SortChildren(Node, False);
end;
NodeData.Scanned := True;
Application.ProcessMessages;
end;
procedure TDriveViewInt.CancelDelayedNode(Node: TTreeNode);
var
NodeData: TNodeData;