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:
@@ -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
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user