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

Bug 1057: Remember remote directory tree nodes state when switching sessions

https://winscp.net/tracker/1057

Source commit: 38437663ba337eb817c89c58c0a0ff15149fcc0f
This commit is contained in:
Martin Prikryl
2021-04-22 13:07:35 +00:00
parent be24819ed2
commit a128fd8e7b
7 changed files with 102 additions and 21 deletions

View File

@@ -53,6 +53,7 @@ __fastcall TUnixDirView::TUnixDirView(TComponent* Owner)
FFullLoad = false;
FDriveView = NULL;
FInvalidNameChars = L"/";
FLoadingDriveViewState = NULL;
DragDropFilesEx->PreferCopy = true;
}
//---------------------------------------------------------------------------
@@ -558,9 +559,51 @@ void __fastcall TUnixDirView::SetTerminal(TTerminal * value)
DoSetTerminal(value, false);
}
//---------------------------------------------------------------------------
void __fastcall TUnixDirView::ReplaceTerminal(TTerminal * value)
class TUnixDirViewState : public TObject
{
DoSetTerminal(value, true);
public:
std::unique_ptr<TObject> CustomDirViewState;
std::unique_ptr<TObject> DriveViewState;
};
//---------------------------------------------------------------------------
TObject * __fastcall TUnixDirView::SaveState()
{
TUnixDirViewState * State = new TUnixDirViewState();
State->CustomDirViewState.reset(TCustomUnixDirView::SaveState());
if (FDriveView != NULL)
{
State->DriveViewState.reset(FDriveView->SaveState());
}
return State;
}
//---------------------------------------------------------------------------
void TUnixDirView::LoadTerminal(TTerminal * value, bool Replace, TObject * State)
{
TObject * CustomDirViewState = NULL;
TObject * DriveViewState = NULL;
if (State != NULL)
{
TUnixDirViewState * UnixDirViewState = dynamic_cast<TUnixDirViewState *>(State);
if (DebugAlwaysTrue(UnixDirViewState != NULL))
{
CustomDirViewState = UnixDirViewState->CustomDirViewState.get();
DriveViewState = UnixDirViewState->DriveViewState.get();
}
}
TValueRestorer<TObject *> LoadingStateRestorer(FLoadingDriveViewState);
FLoadingDriveViewState = DriveViewState;
DoSetTerminal(value, Replace);
if (value->Active)
{
value->RefreshDirectory();
}
if (CustomDirViewState != NULL)
{
RestoreState(CustomDirViewState);
}
}
#endif
//---------------------------------------------------------------------------

View File

@@ -35,6 +35,7 @@ private:
bool __fastcall GetActive();
TCustomUnixDriveView * FDriveView;
TNotifyEvent FOnRead;
TObject * FLoadingDriveViewState;
void __fastcall SetTerminal(TTerminal *value);
void __fastcall DoSetTerminal(TTerminal *value, bool Replace);
void __fastcall SetShowInaccesibleDirectories(bool value);
@@ -98,7 +99,8 @@ public:
virtual bool __fastcall PasteFromClipBoard(UnicodeString TargetPath = L"");
void __fastcall UpdateFiles();
void __fastcall DisplayContextMenu(const TPoint &Where);
void __fastcall ReplaceTerminal(TTerminal * value);
virtual TObject * __fastcall SaveState();
void LoadTerminal(TTerminal * value, bool Replace, TObject * State);
__property bool Active = { read = GetActive };
__property TTerminal *Terminal = { read = FTerminal, write = SetTerminal };

View File

@@ -202,6 +202,7 @@ void __fastcall TCustomUnixDriveView::UpdatePath(TTreeNode * Node, bool Force,
ChildrenDirs->Duplicates = Types::dupAccept;
ChildrenDirs->CaseSensitive = true;
bool FirstChild = true;
TTreeNode * ChildNode = Node->getFirstChild();
while (ChildNode != NULL)
{
@@ -210,6 +211,7 @@ void __fastcall TCustomUnixDriveView::UpdatePath(TTreeNode * Node, bool Force,
ChildrenDirs->AddObject(UnixExtractFileName(ChildData->Directory),
ChildNode);
ChildNode = Node->GetNextChild(ChildNode);
FirstChild = false;
}
// sort only after adding all items.
@@ -238,6 +240,11 @@ void __fastcall TCustomUnixDriveView::UpdatePath(TTreeNode * Node, bool Force,
DebugAssert(!IsUnixRootPath(ChildPath));
LoadPathEasy(Node, ChildPath, File);
if (FirstChild)
{
LoadNodeState(Node, Path);
FirstChild = false;
}
}
}
}
@@ -333,9 +340,11 @@ TTreeNode * __fastcall TCustomUnixDriveView::LoadPath(UnicodeString Path)
TTreeNode * Parent = NULL;
TRemoteFile * File = NULL;
UnicodeString ParentPath;
if (!IsUnixRootPath(Path))
{
Parent = LoadPath(UnixExtractFileDir(Path));
ParentPath = UnixExtractFileDir(Path);
Parent = LoadPath(ParentPath);
}
Node = FindNodeToPath(Path);
@@ -355,6 +364,7 @@ TTreeNode * __fastcall TCustomUnixDriveView::LoadPath(UnicodeString Path)
Node = LoadPathEasy(Parent, Path, File);
if (Parent != NULL)
{
LoadNodeState(Parent, ParentPath);
Parent->AlphaSort(false);
}
}
@@ -880,3 +890,31 @@ void __fastcall TCustomUnixDriveView::DisplayPropertiesMenu(TTreeNode * /*Node*/
{
// TODO
}
//---------------------------------------------------------------------------
void TCustomUnixDriveView::LoadNodeState(TTreeNode * Node, const UnicodeString & Path)
{
if ((FDirView != NULL) && (FDirView->FLoadingDriveViewState != NULL))
{
TStrings * LoadingDriveViewState = DebugNotNull(dynamic_cast<TStrings *>(FDirView->FLoadingDriveViewState));
if (LoadingDriveViewState->IndexOf(Path) >= 0)
{
Node->Expand(false);
}
}
}
//---------------------------------------------------------------------------
TObject * TCustomUnixDriveView::SaveState()
{
std::unique_ptr<TStrings> ExpandedNodes(CreateSortedStringList());
TTreeNode * Node = Items->GetFirstNode();
while (Node != NULL)
{
if (Node->Expanded)
{
DebugAssert(Node->HasChildren);
ExpandedNodes->Add(NodePathName(Node));
}
Node = Node->GetNext();
}
return ExpandedNodes.release();
}

View File

@@ -72,11 +72,14 @@ protected:
virtual void __fastcall ValidateDirectoryEx(TTreeNode * Node,
TRecursiveScan Recurse, bool NewDirs);
void LoadNodeState(TTreeNode * Node, const UnicodeString & Path);
virtual void __fastcall RebuildTree();
virtual void __fastcall DisplayContextMenu(TTreeNode * Node, const TPoint & ScreenPos);
virtual void __fastcall DisplayPropertiesMenu(TTreeNode * Node);
TObject * SaveState();
#pragma warn -inl
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(CM_SHOWINGCHANGED, TMessage, CMShowingChanged)

View File

@@ -596,24 +596,12 @@ void __fastcall TCustomScpExplorerForm::SessionChanged(bool Replaced)
if (Terminal != NULL)
{
if (Replaced)
{
RemoteDirView->ReplaceTerminal(Terminal);
}
else
{
RemoteDirView->Terminal = Terminal;
}
if (Terminal->Active)
{
Terminal->RefreshDirectory();
}
TObject * State = NULL;
if (WinConfiguration->PreservePanelState)
{
DirView(osRemote)->RestoreState(Terminal->RemoteExplorerState);
State = Terminal->RemoteExplorerState;
}
RemoteDirView->LoadTerminal(Terminal, Replaced, State);
}
else
{

View File

@@ -337,6 +337,7 @@ type
procedure UpdateDarkMode;
procedure DoUpdateStatusBar(Force: Boolean = False);
procedure DoCustomDrawItem(Item: TListItem; Stage: TCustomDrawStage);
procedure RestoreState(AState: TObject);
property ImageList16: TImageList read FImageList16;
property ImageList32: TImageList read FImageList32;
public
@@ -376,8 +377,7 @@ type
procedure ContinueSession(Continue: Boolean);
function CanPasteFromClipBoard: Boolean; dynamic;
function PasteFromClipBoard(TargetPath: string = ''): Boolean; virtual; abstract;
function SaveState: TObject;
procedure RestoreState(AState: TObject);
function SaveState: TObject; virtual;
procedure DisplayContextMenu(Where: TPoint); virtual; abstract;
procedure DisplayContextMenuInSitu;
procedure UpdateStatusBar;

View File

@@ -261,6 +261,7 @@ type
function DuplicateSelectedFiles: Boolean; dynamic;
procedure DisplayPropertiesMenu; override;
procedure DisplayContextMenu(Where: TPoint); override;
procedure RestoreState(AState: TObject);
procedure ExecuteParentDirectory; override;
procedure ExecuteRootDirectory; override;
@@ -2454,6 +2455,12 @@ begin
end;
end;
// Just to make it public
procedure TDirView.RestoreState(AState: TObject);
begin
inherited;
end;
procedure TDirView.GetDisplayInfo(ListItem: TListItem;
var DispInfo: TLVItem);
var