Browse Source

When no session is connected, the "remote" panel shows another local folder (part of Bug 1893)

Source commit: d6545d162a6faf65afce575bd2f720904b39df95
Martin Prikryl 5 years ago
parent
commit
417f89a84a

+ 65 - 55
source/forms/CustomScpExplorer.cpp

@@ -1,3 +1,4 @@
+// TODO_OTHER_LOCAL
 //---------------------------------------------------------------------------
 #define NO_WIN32_LEAN_AND_MEAN
 #include <vcl.h>
@@ -213,6 +214,7 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
   FIncrementalSearching = 0;
   FIncrementalSearchHaveNext = false;
   FQueueFileList.reset(new TQueueFileList());
+  FProgressSide = osCurrent;
 
   FEditorManager = new TEditorManager();
   FEditorManager->OnFileChange = ExecutedFileChanged;
@@ -283,7 +285,6 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
   AddFixedSessionImages();
   SessionsPageControl->Images = FSessionColors;
   UpdateQueueLabel();
-  FRemoteDirViewWasFocused = true;
 
   CreateHiddenWindow();
   StartUpdates();
@@ -1011,6 +1012,16 @@ void __fastcall TCustomScpExplorerForm::UpdateSessionsPageControlHeight()
   SessionsPageControl->Height = SessionsPageControl->GetTabsHeight();
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::UpdateRowSelect(TCustomDirView * DirView)
+{
+  if (DirView->RowSelect != WinConfiguration->FullRowSelect)
+  {
+    DirView->RowSelect = WinConfiguration->FullRowSelect;
+    // selection is not redrawn automatically when RowSelect changes
+    DirView->Invalidate();
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::ConfigurationChanged()
 {
   Color = GetBtnFaceColor();
@@ -1023,12 +1034,7 @@ void __fastcall TCustomScpExplorerForm::ConfigurationChanged()
   RemoteDirView->ShowInaccesibleDirectories = WinConfiguration->ShowInaccesibleDirectories;
   RemoteDirView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
 
-  if (RemoteDirView->RowSelect != WinConfiguration->FullRowSelect)
-  {
-    RemoteDirView->RowSelect = WinConfiguration->FullRowSelect;
-    // selection is not redrawn automatically when RowSelect changes
-    RemoteDirView->Invalidate();
-  }
+  UpdateRowSelect(RemoteDirView);
 
   RemoteDriveView->DDAllowMove = !WinConfiguration->DDDisableMove;
   RemoteDriveView->DimmHiddenDirs = WinConfiguration->DimmHiddenFiles;
@@ -1610,8 +1616,19 @@ void __fastcall TCustomScpExplorerForm::DoOperationFinished(
       }
       else
       {
-        TCustomDirView * DView = DirView(Side);
-        UnicodeString FileNameOnly = ExtractFileName(FileName, !IsSideLocalBrowser(Side));
+        TOperationSide DViewSide;
+        if ((FProgressSide != osCurrent) &&
+            IsLocalBrowserMode() && (Side == osLocal)) // Only to limit the impact
+        {
+          // assume the operation is over the focused panel
+          DViewSide = FProgressSide;
+        }
+        else
+        {
+          DViewSide = Side;
+        }
+        TCustomDirView * DView = DirView(DViewSide);
+        UnicodeString FileNameOnly = ExtractFileName(FileName, !IsSideLocalBrowser(DViewSide));
         TListItem *Item = DView->FindFileItem(FileNameOnly);
         // this can happen when local drive is unplugged in the middle of the operation
         if (Item != NULL)
@@ -1624,14 +1641,17 @@ void __fastcall TCustomScpExplorerForm::DoOperationFinished(
 
     if ((Operation == foCopy) || (Operation == foMove))
     {
-      DebugAssert(!IsLocalBrowserMode()); // TODO
-      if (Side == osLocal)
-      {
-        Configuration->Usage->Inc(L"UploadedFiles");
-      }
-      else
+      // TODO_OTHER_LOCAL
+      if (!IsLocalBrowserMode())
       {
-        Configuration->Usage->Inc(L"DownloadedFiles");
+        if (Side == osLocal)
+        {
+          Configuration->Usage->Inc(L"UploadedFiles");
+        }
+        else
+        {
+          Configuration->Usage->Inc(L"DownloadedFiles");
+        }
       }
     }
   }
@@ -2247,7 +2267,7 @@ void __fastcall TCustomScpExplorerForm::LocalCustomCommandWithLocalFiles(
   const TCustomCommandType & ACommand, const UnicodeString & Command, const TCustomCommandData & Data,
   bool FileListCommand, UnicodeString * POutput)
 {
-  std::unique_ptr<TStrings> SelectedFileList(DirView(osLocal)->CreateFileList(false, true, NULL));
+  std::unique_ptr<TStrings> SelectedFileList(DirView(osCurrent)->CreateFileList(false, true, NULL));
 
   std::unique_ptr<TStrings> LocalFileList(new TStringList());
 
@@ -2344,12 +2364,15 @@ void __fastcall TCustomScpExplorerForm::LocalCustomCommand(TStrings * FileList,
     POutput.reset(new UnicodeString());
   }
 
+  TValueRestorer<TOperationSide> ProgressSideRestorer(FProgressSide);
+  FProgressSide = FCurrentSide;
+
   if (!LocalCustomCommand.IsFileCommand(Command))
   {
     ExecuteProcessChecked(LocalCustomCommand.Complete(Command, true), HelpKeyword, POutput.get());
   }
   // remote files?
-  else if ((FCurrentSide == osRemote) || LocalFileCommand)
+  else if (!IsSideLocalBrowser(FCurrentSide) || LocalFileCommand)
   {
     LocalCustomCommandPure(FileList, ACommand, Command, ALocalFileList, Data, LocalFileCommand, FileListCommand, POutput.get());
   }
@@ -3984,6 +4007,8 @@ void __fastcall TCustomScpExplorerForm::DeleteFiles(TOperationSide Side,
     }
     else
     {
+      TValueRestorer<TOperationSide> ProgressSideRestorer(FProgressSide);
+      FProgressSide = FCurrentSide;
       try
       {
         TTerminalManager::Instance()->LocalTerminal->DeleteLocalFiles(FileList, FLAGMASK(Alternative, dfAlternative));
@@ -4473,6 +4498,8 @@ void __fastcall TCustomScpExplorerForm::KeyDown(Word & Key, Classes::TShiftState
     TShortCut KeyShortCut = ShortCut(Key, Shift);
     for (int Index = 0; Index < NonVisualDataModule->ExplorerActions->ActionCount; Index++)
     {
+      // Note that handling shortcuts on panel (current control) popup menu has precendence over this.
+      // But so far it's not a problem, as it does what we want.
       TAction * Action = (TAction *)NonVisualDataModule->ExplorerActions->Actions[Index];
       if (((Action->ShortCut == KeyShortCut) ||
            (Action->SecondaryShortCuts->IndexOfShortCut(KeyShortCut) >= 0)) &&
@@ -5200,12 +5227,17 @@ bool __fastcall TCustomScpExplorerForm::IsComponentPossible(Byte Component)
   return Result;
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::FixControlsPlacement()
+void __fastcall TCustomScpExplorerForm::MakeFocusedItemVisible(TCustomDirView * DirView)
 {
-  if (DirView(osOther)->ItemFocused != NULL)
+  if (DirView->ItemFocused != NULL)
   {
-    DirView(osOther)->ItemFocused->MakeVisible(false);
+    DirView->ItemFocused->MakeVisible(false);
   }
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::FixControlsPlacement()
+{
+  MakeFocusedItemVisible(RemoteDirView);
   QueueSplitter->Visible = QueuePanel->Visible;
   QueueFileListSplitter->Visible = QueueFileList->Visible;
   RemotePanelSplitter->Visible = RemoteDrivePanel->Visible;
@@ -5236,7 +5268,7 @@ void __fastcall TCustomScpExplorerForm::DirViewColumnRightClick(
   DebugAssert(NonVisualDataModule && Column && Sender);
   NonVisualDataModule->ListColumn = Column;
   TPopupMenu * DirViewColumnMenu;
-  if (dynamic_cast<TUnixDirView *>(Sender) != NULL)
+  if (Sender == DirView(osOther))
   {
     DirViewColumnMenu = NonVisualDataModule->RemoteDirViewColumnPopup;
     NonVisualDataModule->RemoteSortByExtColumnPopupItem->Visible =
@@ -6352,7 +6384,8 @@ void __fastcall TCustomScpExplorerForm::DoOpenDirectoryDialog(
       do
       {
         Repeat = false;
-        if (::DoOpenDirectoryDialog(Mode, Side, Name, VisitedDirectories, Terminal,
+        TOperationSide BookmarkSide = IsSideLocalBrowser(Side) ? osLocal : osRemote;
+        if (::DoOpenDirectoryDialog(Mode, BookmarkSide, Name, VisitedDirectories, Terminal,
               // do not allow switching to location profiles,
               // if we are not connected
               HasDirView[osLocal] && (Terminal != NULL)))
@@ -7062,6 +7095,7 @@ void __fastcall TCustomScpExplorerForm::UpdatePixelsPerInchMainWindowCounter()
 void __fastcall TCustomScpExplorerForm::StartingDisconnected()
 {
   DoTerminalListChanged();
+  UpdateControls();
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::PopupTrayBalloon(TTerminal * Terminal,
@@ -8552,9 +8586,9 @@ void __fastcall TCustomScpExplorerForm::UpdateFileStatusExtendedPanels(
 void __fastcall TCustomScpExplorerForm::RemoteStatusBarClick(
   TObject * /*Sender*/)
 {
-  if (DirView(osRemote)->Enabled)
+  if (DirView(osOther)->Enabled)
   {
-    DirView(osRemote)->SetFocus();
+    DirView(osOther)->SetFocus();
   }
 }
 //---------------------------------------------------------------------------
@@ -8650,33 +8684,8 @@ void __fastcall TCustomScpExplorerForm::UpdateControls()
 
     bool HasTerminal = HasActiveTerminal();
 
-    if (HasTerminal)
-    {
-      // TODO needed yet with second local browser?
-      if (!RemoteDirView->Enabled)
-      {
-        RemoteDirView->Enabled = true;
-        if (FRemoteDirViewWasFocused)
-        {
-          ActiveControl = RemoteDirView;
-        }
-      }
-      RemoteDirView->Color = PanelColor();
-    }
-    else
-    {
-      if (RemoteDirView->Enabled)
-      {
-        // This is first called when the form is being constructed
-        // (not anymore due to Showing test above)
-        // but the false is overriden in the constructor later.
-        // An even later in TScpCommanderForm::DoShow()
-        FRemoteDirViewWasFocused = (ActiveControl == RemoteDirView);
-        RemoteDirView->Enabled = false;
-      }
-      RemoteDirView->Color = DisabledPanelColor();
-    }
-
+    RemoteDirView->Enabled = HasTerminal;
+    RemoteDirView->Color = HasTerminal ? PanelColor() : DisabledPanelColor();
     RemoteDirView->Font->Color = GetWindowTextColor(RemoteDirView->Color);
 
     RemoteDriveView->Enabled = RemoteDirView->Enabled;
@@ -10403,9 +10412,10 @@ void __fastcall TCustomScpExplorerForm::CreateOpenDirMenu(TTBCustomItem * Menu,
 bool __fastcall TCustomScpExplorerForm::TryOpenDirectory(TOperationSide Side, const UnicodeString & Path)
 {
   bool Result = true;
+  bool Remote = !IsSideLocalBrowser(Side);
   try
   {
-    if (Side == osRemote)
+    if (Remote)
     {
       Terminal->ExceptionOnFail = true;
     }
@@ -10416,7 +10426,7 @@ bool __fastcall TCustomScpExplorerForm::TryOpenDirectory(TOperationSide Side, co
     }
     __finally
     {
-      if (Side == osRemote)
+      if (Remote)
       {
         Terminal->ExceptionOnFail = false;
       }
@@ -10424,7 +10434,7 @@ bool __fastcall TCustomScpExplorerForm::TryOpenDirectory(TOperationSide Side, co
   }
   catch (Exception & E)
   {
-    if ((Side != osRemote) || Terminal->Active)
+    if (!Remote || Terminal->Active)
     {
       ShowExtendedExceptionEx(Terminal, &E);
       Result = false;

+ 4 - 2
source/forms/CustomScpExplorer.h

@@ -372,13 +372,13 @@ protected:
   TDragDropFilesEx * FSessionsDragDropFilesEx;
   TDragDropFilesEx * FQueueDragDropFilesEx;
   TPoint FLastContextPopupScreenPoint;
-  bool FRemoteDirViewWasFocused;
   int FDoNotIdleCurrentTerminal;
   UnicodeString FFakeFileDropTarget;
   TFileColorData::TList FFileColors;
   UnicodeString FIncrementalSearch;
   int FIncrementalSearching;
   bool FIncrementalSearchHaveNext;
+  TOperationSide FProgressSide;
 
   virtual bool __fastcall CopyParamDialog(TTransferDirection Direction,
     TTransferType Type, bool Temp, TStrings * FileList,
@@ -399,7 +399,6 @@ protected:
   virtual TCustomDriveView * __fastcall DriveView(TOperationSide Side);
   virtual bool IsLocalBrowserMode();
   virtual TCustomDirView * GetCurrentLocalBrowser();
-  virtual bool IsSideLocalBrowser(TOperationSide Side);
   DYNAMIC void __fastcall KeyDown(Word & Key, Classes::TShiftState Shift);
   virtual void __fastcall RestoreFormParams();
   virtual void __fastcall RestoreParams();
@@ -709,6 +708,8 @@ protected:
   int __fastcall GetMinQueueViewHeight();
   void __fastcall DetachTerminal(TObject * ATerminal);
   bool __fastcall IsActiveTerminal(TTerminal * Terminal);
+  void __fastcall UpdateRowSelect(TCustomDirView * DirView);
+  void __fastcall MakeFocusedItemVisible(TCustomDirView * DirView);
 
 public:
   virtual __fastcall ~TCustomScpExplorerForm();
@@ -842,6 +843,7 @@ public:
   void __fastcall ReplaceTerminal(TManagedTerminal * value);
   virtual void __fastcall BrowseFile();
   void __fastcall CloseApp();
+  virtual bool IsSideLocalBrowser(TOperationSide Side);
 
   __property bool ComponentVisible[Byte Component] = { read = GetComponentVisible, write = SetComponentVisible };
   __property bool EnableFocusedOperation[TOperationSide Side] = { read = GetEnableFocusedOperation, index = 0 };

+ 119 - 117
source/forms/NonVisual.cpp

@@ -49,39 +49,34 @@ TNonVisualDataModule *NonVisualDataModule;
 #define EXECOMP(COMP) EXECOMP2(COMP, )
 #define COLPROPS(SIDE) \
   ((TCustomDirViewColProperties*)ScpExplorer->DirView(os ## SIDE)->ColProperties)
-#define UPDSORT(SIDE, PREFIX, COL) if (Action == SIDE ## SortBy ## COL ## Action2) { \
-  SIDE ## SortBy ## COL ## Action2->Enabled = true; Handled = true; \
-  SIDE ## SortBy ## COL ## Action2->Checked = (COLPROPS(SIDE)->SortColumn == PREFIX ## COL); } else
-#define EXESORT(SIDE, PREFIX, COL) EXE(SIDE ## SortBy ## COL ## Action2, \
-    if (COLPROPS(SIDE)->SortColumn == PREFIX ## COL) \
+#define UPDSORT(SIDE, NAME, LCOL, RCOL, NUM) \
+  UPDEX(SIDE ## SortBy ## NAME ## Action ## NUM, (AuxInt = (ScpExplorer->IsSideLocalBrowser(os ## SIDE) ? LCOL : RCOL)) >= 0, \
+    Action->Checked = (COLPROPS(SIDE)->SortColumn == AuxInt), \
+    Action->Checked = false \
+  )
+#define EXESORT(SIDE, NAME, LCOL, RCOL, NUM) \
+  EXE(SIDE ## SortBy ## NAME ## Action ## NUM, \
+    int Col = (ScpExplorer->IsSideLocalBrowser(os ## SIDE) ? LCOL : RCOL); \
+    if (COLPROPS(SIDE)->SortColumn == Col) \
       COLPROPS(SIDE)->SortAscending = !COLPROPS(SIDE)->SortAscending; \
-    else COLPROPS(SIDE)->SortColumn = PREFIX ## COL )
+    else \
+      COLPROPS(SIDE)->SortColumn = Col; \
+  )
 #define UPDSORTA(SIDE, NUM) if (Action == SIDE ## SortAscendingAction ## NUM) { \
   SIDE ## SortAscendingAction ## NUM->Enabled = true; Handled = true; \
   SIDE ## SortAscendingAction ## NUM->Checked = COLPROPS(SIDE)->SortAscending; } else
 #define EXESORTA(SIDE, NUM) EXE(SIDE ## SortAscendingAction ## NUM, \
   COLPROPS(SIDE)->SortAscending = !COLPROPS(SIDE)->SortAscending; )
-#define UPDSORTC(LPREFIX, LCOL, RPREFIX, RCOL, NUM) if (Action == CurrentSortBy ## RCOL ## Action ## NUM) { \
-  Action->Enabled = ScpExplorer->AllowedAction(Action, aaShortCut); \
-  if (Action->Enabled) { \
-    if (ScpExplorer->DirView(osCurrent) == ScpExplorer->DirView(osRemote)) \
-         Action->Checked = (COLPROPS(Current)->SortColumn == RPREFIX ## RCOL); \
-    else Action->Checked = (COLPROPS(Current)->SortColumn == LPREFIX ## LCOL); \
-  } else Action->Checked =  false; Handled = true; } else
-#define EXESORTC(COL, LCOL, RCOL, NUM) \
-  EXE(CurrentSortBy ## COL ## Action ## NUM, \
-    Integer NewSortCol = \
-      ((ScpExplorer->DirView(osCurrent) == ScpExplorer->DirView(osRemote)) ? RCOL : LCOL); \
-    if (COLPROPS(Current)->SortColumn == NewSortCol) \
-      COLPROPS(Current)->SortAscending = !COLPROPS(Current)->SortAscending; \
-    else COLPROPS(Current)->SortColumn = NewSortCol \
+#define UPDSHCOL(SIDE, NAME, LCOL, RCOL) \
+  UPDFUNC(ShowHide ## SIDE ## NAME ## ColumnAction2, \
+    int Col = (ScpExplorer->IsSideLocalBrowser(os ## SIDE) ? LCOL : RCOL); \
+    Action->Enabled = (Col >= 0); \
+    Action->Checked = Action->Enabled && COLPROPS(SIDE)->Visible[Col]; \
   )
-#define UPDSHCOL(SIDE, PREFIX, COL) \
-  EXE(ShowHide ## SIDE ## COL ## ColumnAction2, \
-    ShowHide ## SIDE ## COL ## ColumnAction2->Checked = COLPROPS(SIDE)->Visible[PREFIX ## COL])
-#define EXESHCOL(SIDE, PREFIX, COL) \
-  EXE(ShowHide ## SIDE ## COL ## ColumnAction2, \
-    COLPROPS(SIDE)->Visible[PREFIX ## COL] = !COLPROPS(SIDE)->Visible[PREFIX ## COL])
+#define EXESHCOL(SIDE, NAME, LCOL, RCOL) \
+  EXE(ShowHide ## SIDE ## NAME ## ColumnAction2, \
+    int Col = (ScpExplorer->IsSideLocalBrowser(os ## SIDE) ? LCOL : RCOL); \
+    COLPROPS(SIDE)->Visible[Col] = !COLPROPS(SIDE)->Visible[Col])
 
 #define BAND_COMPONENTS \
   EMIT_BAND_COMPONENT(ExplorerMenuBand) \
@@ -137,7 +132,8 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
     Handled = true;
     return;
   }
-  void * Param;
+  void * AuxVoidPtr;
+  int AuxInt;
   #define HasTerminal ScpExplorer->HasActiveTerminal()
   // CURRENT DIRVIEW
   #define EnabledSelectedOperation (ScpExplorer->EnableSelectedOperation[osCurrent])
@@ -147,9 +143,9 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   #define EnabledLocalSelectedOperation (ScpExplorer->HasDirView[osLocal] && ScpExplorer->EnableSelectedOperation[osLocal])
   #define EnabledLocalFocusedOperation (ScpExplorer->HasDirView[osLocal] && ScpExplorer->EnableFocusedOperation[osLocal])
   #define EnabledLocalSelectedFileOperation (ScpExplorer->HasDirView[osLocal] && ScpExplorer->EnableSelectedFileOperation[osLocal])
-  #define EnabledRemoteSelectedOperation (ScpExplorer->EnableSelectedOperation[osRemote])
-  #define EnabledRemoteFocusedOperation (ScpExplorer->EnableFocusedOperation[osRemote])
-  #define EnabledRemoteSelectedFileOperation (ScpExplorer->EnableSelectedFileOperation[osRemote])
+  #define EnabledRemoteSelectedOperation (ScpExplorer->EnableSelectedOperation[osRemote] && HasTerminal)
+  #define EnabledRemoteFocusedOperation (ScpExplorer->EnableFocusedOperation[osRemote] && HasTerminal)
+  #define EnabledRemoteSelectedFileOperation (ScpExplorer->EnableSelectedFileOperation[osRemote] && HasTerminal)
   // focused operation
   UPD(CurrentDeleteFocusedAction, EnabledFocusedOperation)
   UPD(CurrentPropertiesFocusedAction, EnabledFocusedOperation)
@@ -163,8 +159,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   UPD(CurrentCopyToClipboardFocusedAction, EnabledFocusedOperation)
   // file operation
   UPD(CurrentRenameAction, EnabledFocusedOperation &&
-    ((ScpExplorer->HasDirView[osLocal] && DirView(osLocal) == DirView(osCurrent)) ||
-      ScpExplorer->Terminal->IsCapable[fcRename]))
+    (ScpExplorer->IsSideLocalBrowser(osCurrent) || ScpExplorer->Terminal->IsCapable[fcRename]))
   UPD(CurrentEditAction, EnabledSelectedFileOperation &&
     !WinConfiguration->DisableOpenEdit)
   UPD(CurrentEditInternalAction, EnabledSelectedFileOperation &&
@@ -182,21 +177,21 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   UPD(CurrentPropertiesAction, EnabledSelectedOperation)
   UPD(CurrentCopyToClipboardAction, EnabledSelectedOperation)
   UPD(RemoteMoveToAction, EnabledSelectedOperation &&
-    (DirView(osRemote) == DirView(osCurrent)) &&
+    !ScpExplorer->IsSideLocalBrowser(osCurrent) &&
     ScpExplorer->Terminal->IsCapable[fcRemoteMove])
   UPD(RemoteCopyToAction, EnabledSelectedOperation &&
-    (DirView(osRemote) == DirView(osCurrent)))
+    !ScpExplorer->IsSideLocalBrowser(osCurrent))
   UPD(FileListToCommandLineAction, EnabledSelectedOperation)
   UPD(FileListToClipboardAction, EnabledSelectedOperation)
   UPD(FullFileListToClipboardAction, EnabledSelectedOperation)
-  UPD(FileGenerateUrlAction2, EnabledSelectedOperation && (DirView(osRemote) == DirView(osCurrent)))
+  UPD(FileGenerateUrlAction2, EnabledSelectedOperation && !ScpExplorer->IsSideLocalBrowser(osCurrent))
   UPD(FileListFromClipboardAction, IsFormatInClipboard(CF_TEXT))
   UPD(CurrentAddEditLinkAction, ScpExplorer->CanAddEditLink(osCurrent))
   UPD(LockAction,
-    EnabledSelectedOperation && (DirView(osRemote) == DirView(osCurrent)) &&
+    EnabledSelectedOperation && !ScpExplorer->IsSideLocalBrowser(osCurrent) &&
     ScpExplorer->Terminal->IsCapable[fcLocking])
   UPD(UnlockAction,
-    EnabledSelectedOperation && (DirView(osRemote) == DirView(osCurrent)) &&
+    EnabledSelectedOperation && !ScpExplorer->IsSideLocalBrowser(osCurrent) &&
     ScpExplorer->Terminal->IsCapable[fcLocking])
   // local selected operation
   UPD(LocalCopyAction, HasTerminal && EnabledLocalSelectedOperation)
@@ -234,14 +229,14 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   UPD(RemoteCopyFocusedNonQueueAction, EnabledRemoteFocusedOperation)
   UPD(RemoteMoveFocusedAction, EnabledRemoteFocusedOperation)
   UPD(RemoteMoveToFocusedAction, EnabledFocusedOperation &&
-    (DirView(osRemote) == DirView(osCurrent)) &&
+    !ScpExplorer->IsSideLocalBrowser(osCurrent) &&
     ScpExplorer->Terminal->IsCapable[fcRemoteMove])
   UPD(RemoteCopyToFocusedAction, EnabledFocusedOperation &&
-    DirView(osRemote) == DirView(osCurrent))
+    !ScpExplorer->IsSideLocalBrowser(osCurrent))
   // directory
   UPD(CurrentCreateDirAction, DirViewEnabled(osCurrent))
   UPD(NewDirAction, DirViewEnabled(osCurrent))
-  UPD(RemoteFindFilesAction2, DirViewEnabled(osRemote))
+  UPD(RemoteFindFilesAction2, HasTerminal)
   // selection
   UPD(SelectOneAction, DirView(osCurrent)->FilesCount)
   UPD(SelectAction, DirView(osCurrent)->FilesCount)
@@ -350,30 +345,32 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
 
   // SORT
   UPDSORTA(Local, 2)
-  UPDSORT(Local, dv, Name)
-  UPDSORT(Local, dv, Ext)
-  UPDSORT(Local, dv, Size)
-  UPDSORT(Local, dv, Type)
-  UPDSORT(Local, dv, Changed)
-  UPDSORT(Local, dv, Attr)
+  #define UPDSORTL(NAME, COL) UPDSORT(Local, NAME, COL, -1, 2)
+  UPDSORTL(Name, dvName)
+  UPDSORTL(Ext, dvExt)
+  UPDSORTL(Size, dvSize)
+  UPDSORTL(Type, dvType)
+  UPDSORTL(Changed, dvChanged)
+  UPDSORTL(Attr, dvAttr)
+  #undef UPDSORTL
   UPDSORTA(Remote, 2)
-  UPDSORT(Remote, uv, Name)
-  UPDSORT(Remote, uv, Ext)
-  UPDSORT(Remote, uv, Size)
-  UPDSORT(Remote, uv, Changed)
-  UPDSORT(Remote, uv, Rights)
-  UPDSORT(Remote, uv, Owner)
-  UPDSORT(Remote, uv, Group)
-  UPDSORT(Remote, uv, Type)
+  UPDSORT(Remote, Name, dvName, uvName, 2)
+  UPDSORT(Remote, Ext, dvExt, uvExt, 2)
+  UPDSORT(Remote, Size, dvSize, uvSize, 2)
+  UPDSORT(Remote, Changed, dvChanged, uvChanged, 2)
+  UPDSORT(Remote, Rights, dvAttr, uvRights, 2)
+  UPDSORT(Remote, Owner, -1, uvOwner, 2)
+  UPDSORT(Remote, Group, -1, uvGroup, 2)
+  UPDSORT(Remote, Type, dvType, uvType, 2)
   UPDSORTA(Current, )
-  UPDSORTC(dv, Name, uv, Name, )
-  UPDSORTC(dv, Ext, uv, Ext, )
-  UPDSORTC(dv, Size, uv, Size, )
-  UPDSORTC(dv, Type, uv, Type, 2)
-  UPDSORTC(dv, Changed, uv, Changed, )
-  UPDSORTC(dv, Attr, uv, Rights, )
-  UPDSORTC(dv, Name, uv, Owner, )
-  UPDSORTC(dv, Name, uv, Group, )
+  UPDSORT(Current, Name, dvName, uvName, )
+  UPDSORT(Current, Ext, dvExt, uvExt, )
+  UPDSORT(Current, Size, dvSize, uvSize, )
+  UPDSORT(Current, Type, dvType, uvType, 2)
+  UPDSORT(Current, Changed, dvChanged, uvChanged, )
+  UPDSORT(Current, Rights, dvAttr, uvRights, )
+  UPDSORT(Current, Owner, -1, uvOwner, )
+  UPDSORT(Current, Group, -1, uvGroup, )
   #define COLVIEWPROPS ((TCustomDirViewColProperties*)(((TCustomDirView*)(((TListColumns*)(ListColumn->Collection))->Owner()))->ColProperties))
   UPDEX(SortColumnAscendingAction, (ListColumn != NULL), SortColumnAscendingAction->Checked =
     (COLVIEWPROPS->SortColumn == ListColumn->Index) && COLVIEWPROPS->SortAscending, )
@@ -382,21 +379,23 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   #undef COLVIEWPROPS
 
   // SHOW/HIDE COLUMN
-  UPDSHCOL(Local, dv, Name)
-  UPDSHCOL(Local, dv, Ext)
-  UPDSHCOL(Local, dv, Size)
-  UPDSHCOL(Local, dv, Type)
-  UPDSHCOL(Local, dv, Changed)
-  UPDSHCOL(Local, dv, Attr)
-  UPDSHCOL(Remote, uv, Name)
-  UPDSHCOL(Remote, uv, Ext)
-  UPDSHCOL(Remote, uv, Size)
-  UPDSHCOL(Remote, uv, Changed)
-  UPDSHCOL(Remote, uv, Rights)
-  UPDSHCOL(Remote, uv, Owner)
-  UPDSHCOL(Remote, uv, Group)
-  UPDSHCOL(Remote, uv, LinkTarget)
-  UPDSHCOL(Remote, uv, Type)
+  #define UPDSHCOLL(NAME) UPDSHCOL(Local, NAME, dv ## NAME, -1)
+  UPDSHCOLL(Name)
+  UPDSHCOLL(Ext)
+  UPDSHCOLL(Size)
+  UPDSHCOLL(Type)
+  UPDSHCOLL(Changed)
+  UPDSHCOLL(Attr)
+  #undef UPDSHCOLL
+  UPDSHCOL(Remote, Name, dvName, uvName)
+  UPDSHCOL(Remote, Ext, dvExt, uvExt)
+  UPDSHCOL(Remote, Size, dvSize, uvSize)
+  UPDSHCOL(Remote, Changed, dvChanged, uvChanged)
+  UPDSHCOL(Remote, Rights, dvAttr, uvRights)
+  UPDSHCOL(Remote, Owner, -1, uvOwner)
+  UPDSHCOL(Remote, Group, -1, uvGroup)
+  UPDSHCOL(Remote, LinkTarget, -1, uvLinkTarget)
+  UPDSHCOL(Remote, Type, dvType, uvType)
   UPD(HideColumnAction, (ListColumn != NULL))
   UPD(BestFitColumnAction, (ListColumn != NULL))
 
@@ -467,8 +466,8 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   UPDQUEUE(DeleteAll)
   UPDQUEUE(DeleteAllDone)
   #undef UPDQUEUE
-  UPDEX(QueueItemSpeedAction, ScpExplorer->AllowQueueOperation(qoItemSpeed, &Param),
-    QueueItemSpeedAction->Text = SetSpeedLimit(reinterpret_cast<unsigned long>(Param)),
+  UPDEX(QueueItemSpeedAction, ScpExplorer->AllowQueueOperation(qoItemSpeed, &AuxVoidPtr),
+    QueueItemSpeedAction->Text = SetSpeedLimit(reinterpret_cast<unsigned long>(AuxVoidPtr)),
     QueueItemSpeedAction->Text = L"")
   UPDACT(QueueToggleShowAction,
     Action->Checked = ScpExplorer->ComponentVisible[fcQueueView])
@@ -675,52 +674,55 @@ void __fastcall TNonVisualDataModule::ExplorerActionsExecute(
 
     #define COLVIEWPROPS ((TCustomDirViewColProperties*)(((TCustomDirView*)(((TListColumns*)(ListColumn->Collection))->Owner()))->ColProperties))
     // SORT
-    EXESORTA(Local, 2)
-    EXESORT(Local, dv, Name)
-    EXESORT(Local, dv, Ext)
-    EXESORT(Local, dv, Size)
-    EXESORT(Local, dv, Type)
-    EXESORT(Local, dv, Changed)
-    EXESORT(Local, dv, Attr)
+    #define EXESORTL(NAME, COL) EXESORT(Local, NAME, COL, COL, 2)
+    EXESORTL(Name, dvName)
+    EXESORTL(Ext, dvExt)
+    EXESORTL(Size, dvSize)
+    EXESORTL(Type, dvType)
+    EXESORTL(Changed, dvChanged)
+    EXESORTL(Attr, dvAttr)
+    #undef EXESORTL
     EXESORTA(Remote, 2)
-    EXESORT(Remote, uv, Name)
-    EXESORT(Remote, uv, Ext)
-    EXESORT(Remote, uv, Size)
-    EXESORT(Remote, uv, Changed)
-    EXESORT(Remote, uv, Rights)
-    EXESORT(Remote, uv, Owner)
-    EXESORT(Remote, uv, Group)
-    EXESORT(Remote, uv, Type)
+    EXESORT(Remote, Name, dvName, uvName, 2)
+    EXESORT(Remote, Ext, dvExt, uvExt, 2)
+    EXESORT(Remote, Size, dvSize, uvSize, 2)
+    EXESORT(Remote, Changed, dvChanged, uvChanged, 2)
+    EXESORT(Remote, Rights, dvAttr, uvRights, 2)
+    EXESORT(Remote, Owner, -1, uvOwner, 2)
+    EXESORT(Remote, Group, -1, uvGroup, 2)
+    EXESORT(Remote, Type, dvType, uvType, 2)
     EXESORTA(Current, )
-    EXESORTC(Name, dvName, uvName, )
-    EXESORTC(Ext, dvExt, uvExt, )
-    EXESORTC(Size, dvSize, uvSize, )
-    EXESORTC(Type, dvType, uvType, 2)
-    EXESORTC(Changed, dvChanged, uvChanged, )
-    EXESORTC(Rights, dvAttr, uvRights, )
-    EXESORTC(Owner, dvName, uvOwner, )
-    EXESORTC(Group, dvName, uvGroup, )
+    EXESORT(Current, Name, dvName, uvName, )
+    EXESORT(Current, Ext, dvExt, uvExt, )
+    EXESORT(Current, Size, dvSize, uvSize, )
+    EXESORT(Current, Type, dvType, uvType, 2)
+    EXESORT(Current, Changed, dvChanged, uvChanged, )
+    EXESORT(Current, Rights, dvAttr, uvRights, )
+    EXESORT(Current, Owner, -1, uvOwner, )
+    EXESORT(Current, Group, -1, uvGroup, )
     EXE(SortColumnAscendingAction, DebugAssert(ListColumn);
       COLVIEWPROPS->SortColumn = ListColumn->Index; COLVIEWPROPS->SortAscending = true; ListColumn = NULL )
     EXE(SortColumnDescendingAction, DebugAssert(ListColumn);
       COLVIEWPROPS->SortColumn = ListColumn->Index; COLVIEWPROPS->SortAscending = false; ListColumn = NULL )
 
     // SHOW/HIDE COLUMN
-    EXESHCOL(Local, dv, Name)
-    EXESHCOL(Local, dv, Ext)
-    EXESHCOL(Local, dv, Size)
-    EXESHCOL(Local, dv, Type)
-    EXESHCOL(Local, dv, Changed)
-    EXESHCOL(Local, dv, Attr)
-    EXESHCOL(Remote, uv, Name)
-    EXESHCOL(Remote, uv, Ext)
-    EXESHCOL(Remote, uv, Size)
-    EXESHCOL(Remote, uv, Changed)
-    EXESHCOL(Remote, uv, Rights)
-    EXESHCOL(Remote, uv, Owner)
-    EXESHCOL(Remote, uv, Group)
-    EXESHCOL(Remote, uv, LinkTarget)
-    EXESHCOL(Remote, uv, Type)
+    #define EXESHCOLL(NAME) EXESHCOL(Local, NAME, dv ## NAME, -1)
+    EXESHCOLL(Name)
+    EXESHCOLL(Ext)
+    EXESHCOLL(Size)
+    EXESHCOLL(Type)
+    EXESHCOLL(Changed)
+    EXESHCOLL(Attr)
+    #undef EXESHCOLL
+    EXESHCOL(Remote, Name, dvName, uvName)
+    EXESHCOL(Remote, Ext, dvExt, uvExt)
+    EXESHCOL(Remote, Size, dvSize, uvSize)
+    EXESHCOL(Remote, Changed, dvChanged, uvChanged)
+    EXESHCOL(Remote, Rights, dvAttr, uvRights)
+    EXESHCOL(Remote, Owner, -1, uvOwner)
+    EXESHCOL(Remote, Group, -1, uvGroup)
+    EXESHCOL(Remote, LinkTarget, -1, uvLinkTarget)
+    EXESHCOL(Remote, Type, dvType, uvType)
     EXE(HideColumnAction, DebugAssert(ListColumn);
       COLVIEWPROPS->Visible[ListColumn->Index] = false; ListColumn = NULL )
     EXE(BestFitColumnAction, DebugAssert(ListColumn); ListColumn = NULL ) // TODO

+ 5 - 3
source/forms/NonVisual.dfm

@@ -969,9 +969,11 @@ object NonVisualDataModule: TNonVisualDataModule
     object RemoteSortByRightsAction2: TAction
       Tag = 14
       Category = 'Sort'
-      Caption = 'By &Permissions'
+      Caption = 'By &Permissions/Attributes'
       HelpKeyword = 'ui_file_panel#sorting_files'
-      Hint = 'Sort by permissions|Sort panel by permissions'
+      Hint = 
+        'Sort by attributes/permissions|Sort current panel by attributes/' +
+        'permissions'
       ImageIndex = 36
       ShortCut = 16502
     end
@@ -1058,7 +1060,7 @@ object NonVisualDataModule: TNonVisualDataModule
     object CurrentSortByRightsAction: TAction
       Tag = 15
       Category = 'Sort'
-      Caption = 'By &Attributes'
+      Caption = 'By &Permissions/Attributes'
       HelpKeyword = 'ui_file_panel#sorting_files'
       Hint = 
         'Sort by attributes/permissions|Sort current panel by attributes/' +

+ 213 - 73
source/forms/ScpCommander.cpp

@@ -1,3 +1,4 @@
+// TODO_OTHER_LOCAL
 //---------------------------------------------------------------------------
 #include <vcl.h>
 #pragma hdrstop
@@ -97,6 +98,7 @@ __fastcall TScpCommanderForm::TScpCommanderForm(TComponent* Owner)
   CopyPopup(LocalPathLabel, LocalTopDock);
   CopyPopup(LocalStatusBar, LocalTopDock);
   CopyPopup(LocalDriveView, LocalTopDock);
+  CopyPopup(OtherLocalDriveView, LocalTopDock);
   CopyPopup(LocalBottomDock, LocalTopDock);
 
   RemoteTopDock->PopupMenu = NonVisualDataModule->RemotePanelPopup;
@@ -126,6 +128,11 @@ __fastcall TScpCommanderForm::TScpCommanderForm(TComponent* Owner)
   UseDesktopFont(RemotePathLabel);
   UseDesktopFont(LocalStatusBar);
   UseDesktopFont(StatusBar);
+  UseDesktopFont(OtherLocalDirView);
+  UseDesktopFont(OtherLocalDriveView);
+
+  OtherLocalDirView->Align = RemoteDirView->Align;
+  OtherLocalDriveView->Align = RemoteDriveView->Align;
 
   NonVisualDataModule->QueueSpeedComboBoxItem(QueueSpeedComboBoxItem);
   // particularly to reorder panels on right-to-left bidi mode
@@ -183,6 +190,7 @@ void __fastcall TScpCommanderForm::RestoreParams()
   SessionsPageControl->Visible = WinConfiguration->ScpCommander.SessionsTabs;
   StatusBar->Visible = WinConfiguration->ScpCommander.StatusBar;
 
+  // TODO_OTHER_LOCAL
   RestorePanelParams(LocalDirView, LocalDriveView, LocalStatusBar, WinConfiguration->ScpCommander.LocalPanel);
   RestorePanelParams(RemoteDirView, RemoteDrivePanel, RemoteStatusBar, WinConfiguration->ScpCommander.RemotePanel);
   FPanelsRestored = true;
@@ -190,6 +198,7 @@ void __fastcall TScpCommanderForm::RestoreParams()
   // just to make sure
   LocalDirView->DirColProperties->ExtVisible = false;
   RemoteDirView->UnixColProperties->ExtVisible = false;
+  OtherLocalDirView->DirColProperties->ExtVisible = false;
 }
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::StorePanelParams(
@@ -229,9 +238,11 @@ void __fastcall TScpCommanderForm::StoreParams()
 
     CommanderConfiguration.CurrentPanel = FCurrentSide;
 
+    // TODO_OTHER_LOCAL
     StorePanelParams(LocalDirView, LocalDriveView, LocalStatusBar, CommanderConfiguration.LocalPanel);
     StorePanelParams(RemoteDirView, RemoteDrivePanel, RemoteStatusBar, CommanderConfiguration.RemotePanel);
 
+    // TODO_OTHER_LOCAL
     CommanderConfiguration.LocalPanel.LastPath = LocalDirView->Path;
 
     CommanderConfiguration.WindowParams = StoreForm(this);
@@ -366,25 +377,19 @@ void __fastcall TScpCommanderForm::DoShow()
   // is finally connected
   UpdateControls();
 
+  // TODO_OTHER_LOCAL (persistent "other" local path)
+  DoLocalDefaultDirectory(OtherLocalDirView, UnicodeString());
+
   // If we do not call SetFocus on any control before DoShow,
   // no control will get focused on Login dialog
   // (HACK seems like a bug in VCL)
-  if (WinConfiguration->ScpCommander.CurrentPanel == osLocal)
+  if ((WinConfiguration->ScpCommander.CurrentPanel == osLocal) || !DirView(osOther)->Enabled)
   {
     LocalDirView->SetFocus();
-    FRemoteDirViewWasFocused = false;
   }
   else
   {
-    if (DirView(osOther)->Enabled)
-    {
-      DirView(osOther)->SetFocus();
-    }
-    else
-    {
-      LocalDirView->SetFocus();
-    }
-    FRemoteDirViewWasFocused = true;
+    DirView(osOther)->SetFocus();
   }
 
   TCustomScpExplorerForm::DoShow();
@@ -413,12 +418,21 @@ TCustomDirView * __fastcall TScpCommanderForm::DirView(TOperationSide Side)
   {
     return LocalDirView;
   }
+  else if (DebugAlwaysTrue(Side == osRemote) && IsLocalBrowserMode())
+  {
+    return OtherLocalDirView;
+  }
   else
   {
     return TCustomScpExplorerForm::DirView(Side);
   }
 }
 //---------------------------------------------------------------------------
+bool TScpCommanderForm::IsLocalBrowserMode()
+{
+  return OtherLocalDirView->Visible;
+}
+//---------------------------------------------------------------------------
 TCustomDriveView * __fastcall TScpCommanderForm::DriveView(TOperationSide Side)
 {
   Side = GetSide(Side);
@@ -426,6 +440,10 @@ TCustomDriveView * __fastcall TScpCommanderForm::DriveView(TOperationSide Side)
   {
     return LocalDriveView;
   }
+  else if (DebugAlwaysTrue(Side == osRemote) && IsLocalBrowserMode())
+  {
+    return OtherLocalDriveView;
+  }
   else
   {
     return TCustomScpExplorerForm::DriveView(Side);
@@ -434,7 +452,7 @@ TCustomDriveView * __fastcall TScpCommanderForm::DriveView(TOperationSide Side)
 //---------------------------------------------------------------------------
 bool TScpCommanderForm::IsSideLocalBrowser(TOperationSide Side)
 {
-  return (GetSide(Side) == osLocal);
+  return (GetSide(Side) == osLocal) || IsLocalBrowserMode();
 }
 //---------------------------------------------------------------------------
 TCustomDirView * TScpCommanderForm::GetCurrentLocalBrowser()
@@ -444,6 +462,10 @@ TCustomDirView * TScpCommanderForm::GetCurrentLocalBrowser()
   {
     return LocalDirView;
   }
+  else if (DebugAlwaysTrue(Side == osRemote) && IsLocalBrowserMode())
+  {
+    return OtherLocalDirView;
+  }
   else
   {
     DebugFail();
@@ -454,8 +476,7 @@ TCustomDirView * TScpCommanderForm::GetCurrentLocalBrowser()
 //---------------------------------------------------------------------------
 bool __fastcall TScpCommanderForm::DirViewEnabled(TOperationSide Side)
 {
-  Side = GetSide(Side);
-  if (Side == osLocal)
+  if (IsSideLocalBrowser(Side))
   {
     return true;
   }
@@ -481,6 +502,11 @@ void __fastcall TScpCommanderForm::ReloadLocalDirectory(const UnicodeString Dire
     LocalDirView->ReloadDirectory();
     LocalDriveView->ValidateDirectory(LocalDriveView->Selected);
   }
+  if (Directory.IsEmpty() || SamePaths(Directory, OtherLocalDirView->Path))
+  {
+    OtherLocalDirView->ReloadDirectory();
+    OtherLocalDriveView->ValidateDirectory(OtherLocalDriveView->Selected);
+  }
   TCustomScpExplorerForm::ReloadLocalDirectory();
 }
 //---------------------------------------------------------------------------
@@ -490,6 +516,8 @@ void __fastcall TScpCommanderForm::BatchStart(void *& Storage)
   *static_cast<bool*>(Storage) = LocalDirView->WatchForChanges;
   LocalDirView->WatchForChanges = false;
   LocalDriveView->WatchDirectory = false;
+  OtherLocalDirView->WatchForChanges = false;
+  OtherLocalDriveView->WatchDirectory = false;
 
   TCustomScpExplorerForm::BatchStart(Storage);
 }
@@ -502,6 +530,8 @@ void __fastcall TScpCommanderForm::BatchEnd(void * Storage)
 
   LocalDirView->WatchForChanges = *static_cast<bool*>(Storage);
   LocalDriveView->WatchDirectory = LocalDirView->WatchForChanges;
+  OtherLocalDirView->WatchForChanges = LocalDirView->WatchForChanges;
+  OtherLocalDriveView->WatchDirectory = LocalDirView->WatchForChanges;
 
   delete Storage;
 }
@@ -515,7 +545,6 @@ void __fastcall TScpCommanderForm::StartingDisconnected()
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::TerminalChanged(bool Replaced)
 {
-  DebugAssert(!IsLocalBrowserMode());
   NonVisualDataModule->SynchronizeBrowsingAction2->Checked = false;
 
   TCustomScpExplorerForm::TerminalChanged(Replaced);
@@ -580,15 +609,14 @@ void __fastcall TScpCommanderForm::TerminalChanged(bool Replaced)
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TScpCommanderForm::LocalDefaultDirectory()
+void __fastcall TScpCommanderForm::DoLocalDefaultDirectory(TDirView * DirView, const UnicodeString & LastPath)
 {
   bool DocumentsDir = true;
-  UnicodeString LastPath = WinConfiguration->ScpCommander.LocalPanel.LastPath;
   if (!LastPath.IsEmpty())
   {
     try
     {
-      LocalDirView->Path = LastPath;
+      DirView->Path = LastPath;
       DocumentsDir = false;
     }
     catch (...)
@@ -600,25 +628,30 @@ void __fastcall TScpCommanderForm::LocalDefaultDirectory()
   {
     try
     {
-      LocalDirView->HomeDirectory = L"";
-      UnicodeString HomeDrive = DriveInfo->GetDriveKey(LocalDirView->HomeDirectory);
+      DirView->HomeDirectory = L"";
+      UnicodeString HomeDrive = DriveInfo->GetDriveKey(DirView->HomeDirectory);
       if (DriveInfo->Get(HomeDrive)->DriveType == DRIVE_REMOTE)
       {
-        LocalDirView->Path = DriveInfo->AnyValidPath();
+        DirView->Path = DriveInfo->AnyValidPath();
       }
       else
       {
-        LocalDirView->ExecuteHomeDirectory();
+        DirView->ExecuteHomeDirectory();
       }
     }
     catch(Exception & E)
     {
       ShowExtendedException(NULL, &E);
-      LocalDirView->Path = ExtractFilePath(Application->ExeName);
+      DirView->Path = ExtractFilePath(Application->ExeName);
     }
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::LocalDefaultDirectory()
+{
+  DoLocalDefaultDirectory(LocalDirView, WinConfiguration->ScpCommander.LocalPanel.LastPath);
+}
+//---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::ConfigurationChanged()
 {
   TCustomScpExplorerForm::ConfigurationChanged();
@@ -631,33 +664,47 @@ void __fastcall TScpCommanderForm::ConfigurationChanged()
   {
     LocalDirView->HomeDirectory = L"";
   }
+
   LocalDirView->DimmHiddenFiles = WinConfiguration->DimmHiddenFiles;
   LocalDriveView->DimmHiddenDirs = WinConfiguration->DimmHiddenFiles;
+  OtherLocalDirView->DimmHiddenFiles = WinConfiguration->DimmHiddenFiles;
+  OtherLocalDriveView->DimmHiddenDirs = WinConfiguration->DimmHiddenFiles;
+
   LocalDirView->ShowHiddenFiles = WinConfiguration->ShowHiddenFiles;
-  LocalDirView->FormatSizeBytes = WinConfiguration->FormatSizeBytes;
   LocalDriveView->ShowHiddenDirs = WinConfiguration->ShowHiddenFiles;
+  OtherLocalDirView->ShowHiddenFiles = WinConfiguration->ShowHiddenFiles;
+  OtherLocalDriveView->ShowHiddenDirs = WinConfiguration->ShowHiddenFiles;
+
+  LocalDirView->FormatSizeBytes = WinConfiguration->FormatSizeBytes;
+  OtherLocalDirView->FormatSizeBytes = WinConfiguration->FormatSizeBytes;
+
   LocalDirView->ConfirmOverwrite = WinConfiguration->ConfirmOverwriting;
   LocalDriveView->ConfirmOverwrite = WinConfiguration->ConfirmOverwriting;
+  OtherLocalDirView->ConfirmOverwrite = WinConfiguration->ConfirmOverwriting;
+  OtherLocalDriveView->ConfirmOverwrite = WinConfiguration->ConfirmOverwriting;
 
   LocalDirView->NortonLike = WinConfiguration->ScpCommander.NortonLikeMode;
+  OtherLocalDirView->NortonLike = WinConfiguration->ScpCommander.NortonLikeMode;
   RemoteDirView->NortonLike = WinConfiguration->ScpCommander.NortonLikeMode;
 
   LocalDirView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
   LocalDriveView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
+  OtherLocalDirView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
+  OtherLocalDriveView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
 
   LocalDirView->TimeoutShellIconRetrieval = WinConfiguration->TimeoutShellIconRetrieval;
   LocalDirView->UseIconUpdateThread = WinConfiguration->UseIconUpdateThread;
+  OtherLocalDirView->TimeoutShellIconRetrieval = WinConfiguration->TimeoutShellIconRetrieval;
+  OtherLocalDirView->UseIconUpdateThread = WinConfiguration->UseIconUpdateThread;
 
-  if (LocalDirView->RowSelect != WinConfiguration->FullRowSelect)
-  {
-    LocalDirView->RowSelect = WinConfiguration->FullRowSelect;
-    // selection is not redrawn automatically when RowSelect changes
-    LocalDirView->Invalidate();
-  }
+  UpdateRowSelect(LocalDirView);
+  UpdateRowSelect(OtherLocalDirView);
 
   // See also LocalDirViewDDTargetHasDropHandler
   LocalDirView->DragDropFilesEx->ShellExtensions->DropHandler = !WinConfiguration->DDFakeFile;
   LocalDriveView->DragDropFilesEx->ShellExtensions->DropHandler = !WinConfiguration->DDFakeFile;
+  OtherLocalDirView->DragDropFilesEx->ShellExtensions->DropHandler = !WinConfiguration->DDFakeFile;
+  OtherLocalDriveView->DragDropFilesEx->ShellExtensions->DropHandler = !WinConfiguration->DDFakeFile;
 
   if (Panel(true)->Left > Panel(false)->Left)
   {
@@ -704,6 +751,7 @@ void __fastcall TScpCommanderForm::ConfigurationChanged()
     // save value only if it was set yet
     if (FPanelsRestored)
     {
+      // TODO_OTHER_LOCAL
       if (TreeOnLeft)
       {
         // want to be on left, so it is on top, saving height
@@ -722,6 +770,7 @@ void __fastcall TScpCommanderForm::ConfigurationChanged()
     // See TSplitter.RequestAlign
     TCursor SplitterCursor = (TreeOnLeft ? crSizeWE : crSizeNS);
     LocalDriveView->Align = NonClientAlign;
+    OtherLocalDriveView->Align = NonClientAlign;
     LocalPanelSplitter->Align = NonClientAlign;
     LocalPanelSplitter->Cursor = SplitterCursor;
     RemoteDrivePanel->Align = NonClientAlign;
@@ -729,6 +778,7 @@ void __fastcall TScpCommanderForm::ConfigurationChanged()
     RemotePanelSplitter->Cursor = SplitterCursor;
     FixControlsPlacement();
 
+    // TODO_OTHER_LOCAL
     if (TreeOnLeft)
     {
       LocalDriveView->Width = LocalPanel.DriveViewWidth;
@@ -862,6 +912,10 @@ void __fastcall TScpCommanderForm::PanelSplitterDblClick(TObject * Sender)
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::UpdateControls()
 {
+  // Before TCustomScpExplorerForm disables them (when disconnecting)
+  bool DirViewWasFocused = DirView(osOther)->Focused();
+  bool DriveViewWasFocused = DriveView(osOther)->Focused();
+
   TCustomScpExplorerForm::UpdateControls();
 
   UnicodeString SplitterLongHint = Splitter->Hint;
@@ -882,10 +936,16 @@ void __fastcall TScpCommanderForm::UpdateControls()
   }
   LocalDirView->DarkMode = WinConfiguration->UseDarkTheme();
   LocalDriveView->DarkMode = LocalDirView->DarkMode;
+  OtherLocalDirView->DarkMode = LocalDirView->DarkMode;
+  OtherLocalDriveView->DarkMode = LocalDirView->DarkMode;
   LocalDirView->Color = PanelColor();
   LocalDriveView->Color = LocalDirView->Color;
+  OtherLocalDirView->Color = LocalDirView->Color;
+  OtherLocalDriveView->Color = LocalDirView->Color;
   LocalDirView->Font->Color = GetWindowTextColor(LocalDirView->Color);
   LocalDriveView->Font->Color = LocalDirView->Font->Color;
+  OtherLocalDirView->Font->Color = LocalDirView->Font->Color;
+  OtherLocalDriveView->Font->Color = LocalDirView->Font->Color;
 
   // TODO
   bool LocalSide = (FCurrentSide == osLocal);
@@ -911,6 +971,44 @@ void __fastcall TScpCommanderForm::UpdateControls()
   // Ad hoc hack to disable the drop down menu, when all its items (and all other buttons on the toolbar) are disabled,
   // otherwise it shines too much on the toolbar.
   RemoteNewSubmenuItem->Enabled = DirViewEnabled(osRemote);
+
+  RemoteDirView->Visible = (Terminal != NULL);
+  RemoteDriveView->Visible = RemoteDirView->Visible;
+  OtherLocalDirView->Visible = !RemoteDirView->Visible;
+  OtherLocalDriveView->Visible = OtherLocalDirView->Visible;
+  if (DirViewWasFocused)
+  {
+    if (DirView(osOther)->Enabled)
+    {
+      DirView(osOther)->SetFocus();
+    }
+    else
+    {
+      LocalDirView->SetFocus();
+    }
+  }
+  if (DriveViewWasFocused)
+  {
+    if (DriveView(osOther)->Enabled)
+    {
+      DriveView(osOther)->SetFocus();
+    }
+    else
+    {
+      LocalDriveView->SetFocus();
+    }
+  }
+
+  if (RemotePathLabel->FocusControl != DirView(osOther))
+  {
+    if (DebugAlwaysTrue(RemotePathLabel->FocusControl != NULL))
+    {
+      dynamic_cast<TCustomDirView *>(RemotePathLabel->FocusControl)->PathLabel = NULL;
+    }
+    DirView(osOther)->PathLabel = RemotePathLabel;
+    RemotePathLabel->UnixPath = !IsSideLocalBrowser(osOther);
+    DirView(osOther)->UpdateStatusBar();
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::ChangePath(TOperationSide Side)
@@ -991,10 +1089,8 @@ void __fastcall TScpCommanderForm::FixControlsPlacement()
   SetVerticalControlsOrder(RemoteControlsOrder, LENOF(RemoteControlsOrder));
   SetHorizontalControlsOrder(RemoteControlsOrder, LENOF(RemoteControlsOrder));
 
-  if (LocalDirView->ItemFocused != NULL)
-  {
-    LocalDirView->ItemFocused->MakeVisible(false);
-  }
+  MakeFocusedItemVisible(LocalDirView);
+  MakeFocusedItemVisible(OtherLocalDirView);
 }
 //---------------------------------------------------------------------------
 bool __fastcall TScpCommanderForm::GetHasDirView(TOperationSide Side)
@@ -1017,6 +1113,7 @@ void __fastcall TScpCommanderForm::CompareDirectories()
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::SynchronizeDirectories()
 {
+  DebugAssert(!IsLocalBrowserMode());
   UnicodeString LocalDirectory = LocalDirView->PathName;
   UnicodeString RemoteDirectory = RemoteDirView->PathName;
   DoSynchronizeDirectories(LocalDirectory, RemoteDirectory, -1);
@@ -1024,6 +1121,7 @@ void __fastcall TScpCommanderForm::SynchronizeDirectories()
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::FullSynchronizeDirectories()
 {
+  DebugAssert(!IsLocalBrowserMode());
   UnicodeString LocalDirectory = LocalDirView->PathName;
   UnicodeString RemoteDirectory = RemoteDirView->PathName;
   bool SaveMode = !(GUIConfiguration->SynchronizeModeAuto < 0);
@@ -1132,6 +1230,7 @@ void __fastcall TScpCommanderForm::CreateRemoteDirectory(const UnicodeString & P
 void __fastcall TScpCommanderForm::SynchronizeBrowsingLocal(
   UnicodeString PrevPath, UnicodeString & NewPath, bool Create)
 {
+  DebugAssert(!IsLocalBrowserMode());
   Terminal->ExceptionOnFail = true;
   TStrings * Paths = new TStringList();
   try
@@ -1179,6 +1278,7 @@ void __fastcall TScpCommanderForm::SynchronizeBrowsingLocal(
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::CreateLocalDirectory(const UnicodeString & Path)
 {
+  DebugAssert(!IsLocalBrowserMode()); // Used for synchronized browsing only
   UnicodeString Dir = ExtractFileDir(Path);
   if (!Dir.IsEmpty() && !DirectoryExists(Dir))
   {
@@ -1365,23 +1465,23 @@ void __fastcall TScpCommanderForm::DoDirViewLoaded(TCustomDirView * ADirView)
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::AddEditLink(TOperationSide Side, bool Add)
 {
-  // TODO
-  if (GetSide(Side) == osLocal)
+  if (IsSideLocalBrowser(Side))
   {
     bool Edit = false;
     UnicodeString FileName;
     UnicodeString PointTo;
     bool SymbolicLink = true;
 
-    if (LocalDirView->ItemFocused)
+    TDirView * ADirView = DebugNotNull(dynamic_cast<TDirView *>(DirView(Side)));
+    if (ADirView->ItemFocused != NULL)
     {
-      DebugAssert(LocalDirView->ItemFocused->Data);
-      PFileRec FileRec = (PFileRec)LocalDirView->ItemFocused->Data;
+      DebugAssert(ADirView->ItemFocused->Data);
+      PFileRec FileRec = (PFileRec)ADirView->ItemFocused->Data;
 
       Edit = !Add && (UpperCase(FileRec->FileExt) == L"LNK");
       if (Edit)
       {
-        UnicodeString FullName = LocalDirView->ItemFullFileName(LocalDirView->ItemFocused);
+        UnicodeString FullName = ADirView->ItemFullFileName(ADirView->ItemFocused);
         FileName = FullName;
         PointTo = ResolveFileShortCut(FullName, false);
         if (PointTo.IsEmpty())
@@ -1405,11 +1505,11 @@ void __fastcall TScpCommanderForm::AddEditLink(TOperationSide Side, bool Add)
 
       if (ExtractFileDrive(FileName) == L"" && FileName[1] != L'\\')
       {
-        FileName = IncludeTrailingBackslash(LocalDirView->PathName) + FileName;
+        FileName = IncludeTrailingBackslash(ADirView->PathName) + FileName;
       }
       if (ExtractFileDrive(PointTo) == L"" && PointTo[1] != L'\\')
       {
-        PointTo = IncludeTrailingBackslash(LocalDirView->PathName) + PointTo;
+        PointTo = IncludeTrailingBackslash(ADirView->PathName) + PointTo;
       }
       if (ExtractFileExt(FileName) == L"")
       {
@@ -1501,6 +1601,8 @@ void __fastcall TScpCommanderForm::DoOpenBookmark(UnicodeString Local, UnicodeSt
 //---------------------------------------------------------------------------
 bool __fastcall TScpCommanderForm::OpenBookmark(TOperationSide Side, TBookmark * Bookmark)
 {
+  // TODO_OTHER_LOCAL
+  DebugAssert(!IsLocalBrowserMode());
   bool Result;
   if (WinConfiguration->UseLocationProfiles)
   {
@@ -1515,7 +1617,7 @@ bool __fastcall TScpCommanderForm::OpenBookmark(TOperationSide Side, TBookmark *
 }
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::LocalDirViewDDTargetHasDropHandler(
-  TObject * /*Sender*/, TListItem * Item, int & /*Effect*/, bool & DropHandler)
+  TObject * Sender, TListItem * Item, int & /*Effect*/, bool & DropHandler)
 {
   // When drop target is not directory, it is probably file type, which have
   // associated drop handler (such as EXE file). In this case we
@@ -1523,7 +1625,7 @@ void __fastcall TScpCommanderForm::LocalDirViewDDTargetHasDropHandler(
   // as drop handlers are disabled, so drop would error
   // (see TShellExtension.DropHandler assignment in ConfigurationChanged),
   if (WinConfiguration->DDFakeFile &&
-      !LocalDirView->ItemIsDirectory(Item))
+      !DebugNotNull(dynamic_cast<TDirView *>(Sender))->ItemIsDirectory(Item))
   {
     DropHandler = false;
   }
@@ -1559,7 +1661,7 @@ void __fastcall TScpCommanderForm::LocalFileControlDDFileOperation(
   TObject * /*Sender*/, int dwEffect, UnicodeString SourcePath,
   UnicodeString TargetPath, bool Paste, bool & DoOperation)
 {
-  if (IsFileControl(DropSourceControl, osRemote))
+  if (IsFileControl(DropSourceControl, osRemote) && !IsLocalBrowserMode())
   {
     UnicodeString TargetDirectory;
     if (InternalDDDownload(TargetDirectory))
@@ -1634,6 +1736,7 @@ void __fastcall TScpCommanderForm::SideEnter(TOperationSide Side)
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::UpdatePanelsPathLabelsStatus()
 {
+  // TODO_OTHER_LOCAL
   LocalPathLabel->UpdateStatus();
   RemotePathLabel->UpdateStatus();
 }
@@ -1805,41 +1908,48 @@ void __fastcall TScpCommanderForm::RemotePathLabelGetStatus(
   TCustomPathLabel * /*Sender*/, bool & Active)
 {
   // WORKAROUND this strange form is here to make borland compiler work :-)
-  Active = Active || DriveView(osRemote)->Focused();
+  Active = Active || DriveView(osOther)->Focused();
 }
 //---------------------------------------------------------------------------
-void __fastcall TScpCommanderForm::LocalPathLabelPathClick(
-  TCustomPathLabel * /*Sender*/, UnicodeString Path)
+void __fastcall TScpCommanderForm::DoPathLabelPathClick(TOperationSide Side, const UnicodeString & Path)
 {
   if (!NonVisualDataModule->Busy)
   {
-    if (SamePaths(Path, LocalDirView->Path))
+    TCustomDirView * ADirView = DirView(Side);
+
+    bool Same;
+    if (IsSideLocalBrowser(Side))
     {
-      OpenDirectory(osLocal);
+      Same = SamePaths(Path, ADirView->Path);
     }
     else
     {
-      LocalDirView->Path = Path;
+      Same = UnixSamePath(Path, ADirView->Path);
     }
-  }
-}
-//---------------------------------------------------------------------------
-void __fastcall TScpCommanderForm::RemotePathLabelPathClick(
-  TCustomPathLabel * /*Sender*/, UnicodeString Path)
-{
-  if (!NonVisualDataModule->Busy)
-  {
-    if (UnixSamePath(Path, DirView(osRemote)->Path))
+
+    if (Same)
     {
-      OpenDirectory(osRemote);
+      OpenDirectory(Side);
     }
     else
     {
-      DirView(osRemote)->Path = Path;
+      ADirView->Path = Path;
     }
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::LocalPathLabelPathClick(
+  TCustomPathLabel * /*Sender*/, UnicodeString Path)
+{
+  DoPathLabelPathClick(osLocal, Path);
+}
+//---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::RemotePathLabelPathClick(
+  TCustomPathLabel * /*Sender*/, UnicodeString Path)
+{
+  DoPathLabelPathClick(osOther, Path);
+}
+//---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::LocalDirViewFileIconForName(
   TObject * /*Sender*/, TListItem * /*Item*/, UnicodeString & FileName)
 {
@@ -1866,6 +1976,11 @@ void __fastcall TScpCommanderForm::RemoteDirViewUpdateStatusBar(
   UpdateFileStatusBar(RemoteStatusBar, FileInfo, osRemote);
 }
 //---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::OtherLocalDirViewUpdateStatusBar(TObject *, const TStatusFileInfo & FileInfo)
+{
+  UpdateFileStatusBar(RemoteStatusBar, FileInfo, osOther);
+}
+//---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::LocalStatusBarClick(TObject * /*Sender*/)
 {
   LocalDirView->SetFocus();
@@ -1973,7 +2088,7 @@ void __fastcall TScpCommanderForm::LocalPathComboUpdateDrives()
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::LocalPathComboUpdate()
 {
-  // TODO
+  // TODO_OTHER_LOCAL
   // this may get called even after destructor finishes
   // (e.g. from SetDockAllowDrag invoked [indirectly] from StoreParams)
   if (FLocalPathComboBoxPaths != NULL)
@@ -1996,11 +2111,11 @@ void __fastcall TScpCommanderForm::LocalPathComboUpdate()
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TScpCommanderForm::LocalDirViewPathChange(TCustomDirView * /*Sender*/)
+void __fastcall TScpCommanderForm::LocalDirViewPathChange(TCustomDirView * Sender)
 {
   LocalPathComboUpdate();
   ResetIncrementalSearch();
-  if (IsUncPath(LocalDirView->Path))
+  if (IsUncPath(Sender->Path))
   {
     Configuration->Usage->Inc(L"BrowsedUncPath");
   }
@@ -2122,6 +2237,7 @@ void __fastcall TScpCommanderForm::CommandLineComboEditWndProc(TMessage & Messag
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::LocalDriveViewRefreshDrives(TObject * /*Sender*/)
 {
+  // TODO_OTHER_LOCAL
   LocalPathComboUpdateDrives();
   LocalPathComboUpdate();
 }
@@ -2208,30 +2324,39 @@ void __fastcall TScpCommanderForm::QueueLabelUpdateStatus()
   UpdatePanelsPathLabelsStatus();
 }
 //---------------------------------------------------------------------------
-void __fastcall TScpCommanderForm::LocalDirViewContextPopup(TObject * /*Sender*/,
-  TPoint & MousePos, bool & Handled)
+void __fastcall TScpCommanderForm::DoLocalDirViewContextPopup(TOperationSide Side, TPoint & MousePos, bool & Handled)
 {
   if (!WinConfiguration->ScpCommander.SystemContextMenu && !FForceSystemContextMenu)
   {
-    DirViewContextPopupDefaultItem(osLocal, NonVisualDataModule->LocalOpenMenuItem, dcaOpen);
-    DirViewContextPopupDefaultItem(osLocal, NonVisualDataModule->LocalEditMenuItem, dcaEdit);
-    DirViewContextPopupDefaultItem(osLocal, NonVisualDataModule->LocalCopyMenuItem, dcaCopy);
+    DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalOpenMenuItem, dcaOpen);
+    DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalEditMenuItem, dcaEdit);
+    DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalCopyMenuItem, dcaCopy);
 
-    DirViewContextPopup(osLocal, fcLocalPopup, MousePos);
+    DirViewContextPopup(Side, fcLocalPopup, MousePos);
     Handled = true;
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::LocalDirViewContextPopup(TObject *, TPoint & MousePos, bool & Handled)
+{
+  DoLocalDirViewContextPopup(osLocal, MousePos, Handled);
+}
+//---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::OtherLocalDirViewContextPopup(TObject *, TPoint & MousePos, bool & Handled)
+{
+  DoLocalDirViewContextPopup(osOther, MousePos, Handled);
+}
+//---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::DisplaySystemContextMenu()
 {
   TAutoFlag Flag(FForceSystemContextMenu);
   if ((FLastContextPopupScreenPoint.x >= 0) && (FLastContextPopupScreenPoint.Y >= 0))
   {
-    LocalDirView->DisplayContextMenu(FLastContextPopupScreenPoint);
+    DirView(osCurrent)->DisplayContextMenu(FLastContextPopupScreenPoint);
   }
   else
   {
-    LocalDirView->DisplayContextMenuInSitu();
+    DirView(osCurrent)->DisplayContextMenuInSitu();
   }
 }
 //---------------------------------------------------------------------------
@@ -2304,10 +2429,12 @@ void __fastcall TScpCommanderForm::FileColorsChanged()
 {
   TCustomScpExplorerForm::FileColorsChanged();
   DoFileColorsChanged(LocalDirView);
+  DoFileColorsChanged(OtherLocalDirView);
 }
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::BrowseFile()
 {
+  DebugAssert(!IsLocalBrowserMode());
   TCustomScpExplorerForm::BrowseFile();
   if (LocalDirView->ItemFocused != NULL)
   {
@@ -2330,5 +2457,18 @@ void __fastcall TScpCommanderForm::ThemeChanged()
 {
   TCustomScpExplorerForm::ThemeChanged();
   LocalDirView->Perform(WM_THEMECHANGED, 0, 0);
+  OtherLocalDirView->Perform(WM_THEMECHANGED, 0, 0);
+}
+//---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::OtherLocalDirViewEnter(TObject *)
+{
+  // Actually identical to LocalDirViewEnter
+  SideEnter(osOther);
+}
+//---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::OtherLocalDriveViewEnter(TObject *)
+{
+  MakeNextInTabOrder(OtherLocalDirView, OtherLocalDriveView);
+  SideEnter(osOther);
 }
 //---------------------------------------------------------------------------

+ 69 - 1
source/forms/ScpCommander.dfm

@@ -1119,6 +1119,52 @@ inherited ScpCommanderForm: TScpCommanderForm
         OnHistoryGo = DirViewHistoryGo
         OnPathChange = RemoteDirViewPathChange
       end
+      inherited ReconnectToolbar: TTBXToolbar
+        TabOrder = 2
+      end
+      object OtherLocalDirView: TDirView
+        Left = 280
+        Top = 0
+        Width = 178
+        Height = 124
+        Align = alRight
+        Constraints.MinHeight = 70
+        DoubleBuffered = True
+        FullDrag = True
+        HideSelection = False
+        ParentDoubleBuffered = False
+        PopupMenu = NonVisualDataModule.RemoteDirViewPopup
+        TabOrder = 1
+        ViewStyle = vsReport
+        OnColumnRightClick = DirViewColumnRightClick
+        OnEditing = DirViewEditing
+        OnEnter = OtherLocalDirViewEnter
+        OnExit = DirViewExit
+        OnKeyDown = DirViewKeyDown
+        OnKeyPress = DirViewKeyPress
+        DirColProperties.ExtVisible = False
+        OnUpdateStatusBar = OtherLocalDirViewUpdateStatusBar
+        AddParentDir = True
+        OnSelectItem = DirViewSelectItem
+        OnLoaded = DirViewLoaded
+        OnDDDragEnter = LocalFileControlDDDragEnter
+        OnDDDragLeave = FileControlDDDragLeave
+        OnDDTargetHasDropHandler = LocalDirViewDDTargetHasDropHandler
+        OnDDFileOperation = LocalFileControlDDFileOperation
+        OnExecFile = LocalDirViewExecFile
+        OnMatchMask = DirViewMatchMask
+        OnGetOverlay = DirViewGetOverlay
+        ConfirmDelete = False
+        UseIconUpdateThread = True
+        WatchForChanges = True
+        OnFileIconForName = LocalDirViewFileIconForName
+        OnContextPopup = OtherLocalDirViewContextPopup
+        OnHistoryChange = DirViewHistoryChange
+        OnHistoryGo = DirViewHistoryGo
+        OnPathChange = LocalDirViewPathChange
+        OnBusy = DirViewBusy
+        OnChangeFocus = DirViewChangeFocus
+      end
     end
     inherited RemoteDrivePanel: TPanel
       Top = 98
@@ -1126,8 +1172,30 @@ inherited ScpCommanderForm: TScpCommanderForm
       Height = 45
       Align = alTop
       Constraints.MinHeight = 30
+      object OtherLocalDriveView: TDriveView [0]
+        Left = 280
+        Top = 0
+        Width = 178
+        Height = 45
+        WatchDirectory = True
+        DirView = OtherLocalDirView
+        OnBusy = DirViewBusy
+        OnDDDragEnter = LocalFileControlDDDragEnter
+        OnDDDragLeave = FileControlDDDragLeave
+        OnDDFileOperation = LocalFileControlDDFileOperation
+        Align = alRight
+        Constraints.MinHeight = 30
+        DoubleBuffered = True
+        HideSelection = False
+        Indent = 19
+        ParentColor = False
+        ParentDoubleBuffered = False
+        TabOrder = 1
+        TabStop = False
+        OnEnter = OtherLocalDriveViewEnter
+      end
       inherited RemoteDriveView: TUnixDriveView
-        Width = 458
+        Width = 280
         Height = 45
         TabStop = False
       end

+ 11 - 1
source/forms/ScpCommander.h

@@ -438,6 +438,8 @@ __published:
   TTBXItem *TBXItem255;
   TTBXSeparatorItem *TBXSeparatorItem65;
   TTBXItem *TBXItem256;
+  TDriveView *OtherLocalDriveView;
+  TDirView *OtherLocalDirView;
   void __fastcall SplitterMoved(TObject *Sender);
   void __fastcall SplitterCanResize(TObject *Sender, int &NewSize,
     bool &Accept);
@@ -495,6 +497,10 @@ __published:
   void __fastcall LocalPathLabelMaskClick(TObject *Sender);
   void __fastcall LocalOpenDirButtonPopup(TTBCustomItem *Sender, bool FromLink);
   void __fastcall RemoteOpenDirButtonPopup(TTBCustomItem *Sender, bool FromLink);
+  void __fastcall OtherLocalDirViewEnter(TObject *Sender);
+  void __fastcall OtherLocalDriveViewEnter(TObject *Sender);
+  void __fastcall OtherLocalDirViewContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled);
+  void __fastcall OtherLocalDirViewUpdateStatusBar(TObject *Sender, const TStatusFileInfo &FileInfo);
 
 private:
   bool FConstructed;
@@ -526,8 +532,10 @@ private:
   void __fastcall UpdateToolbar2ItemCaption(TTBCustomItem * Item);
   void __fastcall SetShortcuts();
   void __fastcall UpdatePanelsPathLabelsStatus();
+  void __fastcall DoLocalDefaultDirectory(TDirView * DirView, const UnicodeString & LastPath);
   void __fastcall LocalDefaultDirectory();
   TOperationSide __fastcall GetOtherSize(TOperationSide Side);
+  void __fastcall DoLocalDirViewContextPopup(TOperationSide Side, TPoint & MousePos, bool & Handled);
 
 protected:
   virtual bool __fastcall CopyParamDialog(TTransferDirection Direction,
@@ -550,7 +558,6 @@ protected:
   virtual void __fastcall TerminalChanged(bool Replaced);
   virtual void __fastcall ConfigurationChanged();
   virtual bool __fastcall GetHasDirView(TOperationSide Side);
-  virtual bool IsSideLocalBrowser(TOperationSide Side);
   virtual TCustomDirView * GetCurrentLocalBrowser();
   virtual void __fastcall UpdateControls();
   virtual void __fastcall FileOperationProgress(
@@ -602,6 +609,8 @@ protected:
   virtual void __fastcall UpdateImages();
   virtual void __fastcall FileColorsChanged();
   virtual void __fastcall ThemeChanged();
+  virtual bool IsLocalBrowserMode();
+  void __fastcall DoPathLabelPathClick(TOperationSide Side, const UnicodeString & Path);
 
 public:
   __fastcall TScpCommanderForm(TComponent* Owner);
@@ -627,6 +636,7 @@ public:
   virtual void __fastcall CopyFilesToClipboard(TOperationSide Side, bool OnFocused);
   virtual void __fastcall PasteFromClipBoard();
   virtual void __fastcall BrowseFile();
+  virtual bool IsSideLocalBrowser(TOperationSide Side);
 
   __property double LeftPanelWidth = { read = GetLeftPanelWidth, write = SetLeftPanelWidth };
 };

+ 2 - 3
source/forms/ScpExplorer.cpp

@@ -169,11 +169,10 @@ void __fastcall TScpExplorerForm::DoShow()
   // See comment in TScpCommanderForm::DoShow()
   UpdateControls();
 
-  if (RemoteDirView->Enabled)
+  if (DirView(osOther)->Enabled)
   {
-    RemoteDirView->SetFocus();
+    DirView(osOther)->SetFocus();
   }
-  FRemoteDirViewWasFocused = true;
 
   TCustomScpExplorerForm::DoShow();
 }