Browse Source

Bug 2037: Allow normal behavior of double-click on a file even when resolving of symlinks is disabled

https://winscp.net/tracker/2037

Source commit: ab316b6f4b87b3a18c6e2fb1f04e11163b802d57
Martin Prikryl 4 years ago
parent
commit
4c9a70ee91

+ 3 - 2
source/components/UnixDirView.cpp

@@ -108,14 +108,15 @@ void __fastcall TUnixDirView::ExecuteFile(TListItem * Item)
 {
 #ifndef DESIGN_ONLY
   ASSERT_VALID_ITEM;
-  if (ITEMFILE->IsDirectory ||
-      (!Terminal->ResolvingSymlinks && !Terminal->IsEncryptingFiles()))
+  TResolvedDoubleClickAction Action = WinConfiguration->ResolveDoubleClickAction(ITEMFILE->IsDirectory, Terminal);
+  if (Action == rdcaChangeDir)
   {
     PathChanging(true);
     ChangeDirectory(ITEMFILE->FileName);
   }
   else
   {
+    DebugAssert(Action == rdcaOpen);
     if (ItemFocused != Item) ItemFocused = Item;
     DisplayPropertiesMenu();
   }

+ 58 - 58
source/forms/CustomScpExplorer.cpp

@@ -2590,19 +2590,23 @@ bool __fastcall TCustomScpExplorerForm::IsFileControl(TObject * Control,
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::DirViewContextPopupDefaultItem(
-  TOperationSide Side, TTBXCustomItem * Item, TDoubleClickAction DoubleClickAction)
+  TOperationSide Side, TTBXCustomItem * Item,
+  TResolvedDoubleClickAction DoubleClickAction1, TResolvedDoubleClickAction DoubleClickAction2)
 {
-  TTBItemOptions O;
-  O = Item->Options;
   TCustomDirView * DView = DirView(Side);
-  if ((DView->ItemFocused != NULL) &&
-      (WinConfiguration->DoubleClickAction == DoubleClickAction) &&
-      // when resolving links is disabled, default action is to enter the directory,
-      // no matter what DoubleClickAction is configured to
-      (IsSideLocalBrowser(Side) || Terminal->ResolvingSymlinks || Terminal->IsEncryptingFiles()) &&
-      // Can only Edit files, but can Open/Copy even directories
-      ((DoubleClickAction != dcaEdit) ||
-       !DView->ItemIsDirectory(DView->ItemFocused)))
+
+  bool IsDefault = false;
+  if (DView->ItemFocused != NULL)
+  {
+    TTerminal * ATerminal = !IsSideLocalBrowser(Side) ? Terminal : NULL;
+
+    TResolvedDoubleClickAction DefaultAction =
+      WinConfiguration->ResolveDoubleClickAction(DView->ItemIsDirectory(DView->ItemFocused), ATerminal);
+    IsDefault = (DefaultAction == DoubleClickAction1) || (DefaultAction == DoubleClickAction2);
+  }
+
+  TTBItemOptions O = Item->Options;
+  if (IsDefault)
   {
     Item->Options = O << tboDefault;
   }
@@ -2633,9 +2637,9 @@ void __fastcall TCustomScpExplorerForm::DirViewContextPopup(
 void __fastcall TCustomScpExplorerForm::RemoteDirViewContextPopup(
       TObject * /*Sender*/, const TPoint &MousePos, bool &Handled)
 {
-  DirViewContextPopupDefaultItem(osRemote, NonVisualDataModule->RemoteOpenMenuItem, dcaOpen);
-  DirViewContextPopupDefaultItem(osRemote, NonVisualDataModule->RemoteEditMenuItem, dcaEdit);
-  DirViewContextPopupDefaultItem(osRemote, NonVisualDataModule->RemoteCopyMenuItem, dcaCopy);
+  DirViewContextPopupDefaultItem(osRemote, NonVisualDataModule->RemoteOpenMenuItem, rdcaChangeDir, rdcaOpen);
+  DirViewContextPopupDefaultItem(osRemote, NonVisualDataModule->RemoteEditMenuItem, rdcaEdit, rdcaNone);
+  DirViewContextPopupDefaultItem(osRemote, NonVisualDataModule->RemoteCopyMenuItem, rdcaCopy, rdcaNone);
 
   DirViewContextPopup(osRemote, fcRemotePopup, MousePos);
   Handled = true;
@@ -5553,60 +5557,56 @@ void __fastcall TCustomScpExplorerForm::DoDirViewExecFile(TObject * Sender,
   TCustomDirView * ADirView = (TCustomDirView *)Sender;
   TOperationSide Side = ((ADirView == DirView(osRemote)) ? osRemote : osLocal);
   bool Remote = !IsSideLocalBrowser(Side);
-  bool ResolvedSymlinks = !Remote || Terminal->ResolvingSymlinks || Terminal->IsEncryptingFiles();
 
-  // Anything special is done on double click only (not on "open" indicated by FForceExecution),
-  // on files only (not directories)
-  // and only when symlinks are resolved (apply to remote panel only)
-  if (!ADirView->ItemIsDirectory(Item) &&
-      (ResolvedSymlinks || FForceExecution))
+  DebugAssert(Item == ADirView->ItemFocused);
+  bool IsDirectory = ADirView->ItemIsDirectory(Item);
+  TResolvedDoubleClickAction Action;
+
+  if (FForceExecution)
+  {
+    Action = IsDirectory ? rdcaChangeDir : rdcaOpen;
+  }
+  else
+  {
+    TTerminal * ATerminal = !IsSideLocalBrowser(Side) ? Terminal : NULL;
+    Action = WinConfiguration->ResolveDoubleClickAction(IsDirectory, ATerminal);
+  }
+
+  if (Action == rdcaCopy)
   {
-    if ((WinConfiguration->DoubleClickAction != dcaOpen) &&
-        !FForceExecution && ResolvedSymlinks)
+    // To counter the lock in DirViewBusy (called from TCustomDirView.DoExecute)
+    UnlockWindow();
+    try
     {
-      if (WinConfiguration->DoubleClickAction == dcaCopy)
-      {
-        // To counter the lock in DirViewBusy (called from TCustomDirView.DoExecute)
-        UnlockWindow();
-        try
-        {
-          if (IsLocalBrowserMode())
-          {
-            LocalLocalCopy(foCopy, Side, true, !WinConfiguration->CopyOnDoubleClickConfirmation, false, 0);
-          }
-          else
-          {
-            ExecuteFileOperation(foCopy, Side, true, !WinConfiguration->CopyOnDoubleClickConfirmation);
-          }
-        }
-        __finally
-        {
-          LockWindow();
-        }
-        AllowExec = false;
-      }
-      else if (WinConfiguration->DoubleClickAction == dcaEdit)
+      if (IsLocalBrowserMode())
       {
-        if (!Remote || !WinConfiguration->DisableOpenEdit)
-        {
-          ExecuteFile(Side, efDefaultEditor);
-          AllowExec = false;
-        }
+        LocalLocalCopy(foCopy, Side, true, !WinConfiguration->CopyOnDoubleClickConfirmation, false, 0);
       }
       else
       {
-        DebugFail();
+        ExecuteFileOperation(foCopy, Side, true, !WinConfiguration->CopyOnDoubleClickConfirmation);
       }
     }
-
-    // if we have not done anything special, fall back to default behavior
-    if (AllowExec)
+    __finally
     {
-      if (Remote && !WinConfiguration->DisableOpenEdit)
-      {
-        ExecuteFile(osRemote, efShell);
-        AllowExec = false;
-      }
+      LockWindow();
+    }
+    AllowExec = false;
+  }
+  else if (Action == rdcaEdit)
+  {
+    if (!Remote || !WinConfiguration->DisableOpenEdit)
+    {
+      ExecuteFile(Side, efDefaultEditor);
+      AllowExec = false;
+    }
+  }
+  else if (Action == rdcaOpen)
+  {
+    if (DebugAlwaysTrue(!IsDirectory) && Remote && !WinConfiguration->DisableOpenEdit)
+    {
+      ExecuteFile(osRemote, efShell);
+      AllowExec = false;
     }
   }
 }

+ 1 - 1
source/forms/CustomScpExplorer.h

@@ -652,7 +652,7 @@ protected:
   virtual void __fastcall QueueLabelUpdateStatus();
   void __fastcall EditorAutoConfig();
   void __fastcall DirViewContextPopupDefaultItem(
-    TOperationSide Side, TTBXCustomItem * Item, TDoubleClickAction DoubleClickAction);
+    TOperationSide Side, TTBXCustomItem * Item, TResolvedDoubleClickAction DoubleClickAction1, TResolvedDoubleClickAction DoubleClickAction2);
   void __fastcall DirViewContextPopup(
     TOperationSide Side, Byte PopupComponent, const TPoint & MousePos);
   bool __fastcall CommandLineFromAnotherInstance(const UnicodeString & CommandLine);

+ 4 - 4
source/forms/ScpCommander.cpp

@@ -2510,15 +2510,15 @@ void __fastcall TScpCommanderForm::DoLocalDirViewContextPopup(TOperationSide Sid
 {
   if (!WinConfiguration->ScpCommander.SystemContextMenu && !FForceSystemContextMenu)
   {
-    DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalOpenMenuItem, dcaOpen);
-    DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalEditMenuItem, dcaEdit);
+    DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalOpenMenuItem, rdcaOpen, rdcaChangeDir);
+    DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalEditMenuItem, rdcaEdit, rdcaNone);
     if (IsLocalBrowserMode())
     {
-      DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalLocalCopyMenuItem, dcaCopy);
+      DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalLocalCopyMenuItem, rdcaCopy, rdcaNone);
     }
     else
     {
-      DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalCopyMenuItem, dcaCopy);
+      DirViewContextPopupDefaultItem(Side, NonVisualDataModule->LocalCopyMenuItem, rdcaCopy, rdcaNone);
     }
 
     DirViewContextPopup(Side, fcLocalPopup, MousePos);

+ 52 - 0
source/windows/WinConfiguration.cpp

@@ -547,6 +547,7 @@ void __fastcall TWinConfiguration::Default()
   FConfirmClosingSession = true;
   FDoubleClickAction = dcaEdit;
   FCopyOnDoubleClickConfirmation = false;
+  FAlwaysRespectDoubleClickAction = false;
   FDimmHiddenFiles = true;
   FRenameWholeName = false;
   FAutoStartSession = L"";
@@ -947,6 +948,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool & SessionList)
   BLOCK(L"Interface", CANCREATE, \
     KEYEX(Integer,DoubleClickAction, L"CopyOnDoubleClick"); \
     KEY(Bool,     CopyOnDoubleClickConfirmation); \
+    KEY(Bool,     AlwaysRespectDoubleClickAction); \
     KEY(Bool,     DDDisableMove); \
     KEYEX(Integer, DDTransferConfirmation, L"DDTransferConfirmation2"); \
     KEY(String,   DDTemporaryDirectory); \
@@ -2058,6 +2060,11 @@ void __fastcall TWinConfiguration::SetCopyOnDoubleClickConfirmation(bool value)
   SET_CONFIG_PROPERTY(CopyOnDoubleClickConfirmation);
 }
 //---------------------------------------------------------------------------
+void __fastcall TWinConfiguration::SetAlwaysRespectDoubleClickAction(bool value)
+{
+  SET_CONFIG_PROPERTY(AlwaysRespectDoubleClickAction);
+}
+//---------------------------------------------------------------------------
 void __fastcall TWinConfiguration::SetDimmHiddenFiles(bool value)
 {
   SET_CONFIG_PROPERTY(DimmHiddenFiles);
@@ -2899,6 +2906,51 @@ void __fastcall TWinConfiguration::StoreFont(
   Configuration.FontStyle = FontStylesToInt(Font->Style);
 }
 //---------------------------------------------------------------------------
+TResolvedDoubleClickAction TWinConfiguration::ResolveDoubleClickAction(bool IsDirectory, TTerminal * Terminal)
+{
+  TResolvedDoubleClickAction Result;
+  // Anything special is done on files only (not directories)
+  if (IsDirectory)
+  {
+    Result = rdcaChangeDir;
+  }
+  else
+  {
+    Result = rdcaNone;
+    if (Terminal != NULL)
+    {
+      if (!Terminal->ResolvingSymlinks && !Terminal->IsEncryptingFiles() && !AlwaysRespectDoubleClickAction)
+      {
+        Result = rdcaChangeDir;
+      }
+    }
+
+    if (Result == rdcaNone)
+    {
+      switch (DoubleClickAction)
+      {
+        case dcaOpen:
+          Result = rdcaOpen;
+          break;
+
+        case dcaCopy:
+          Result = rdcaCopy;
+          break;
+
+        case dcaEdit:
+          Result = rdcaEdit;
+          break;
+
+        default:
+          DebugFail();
+          Abort();
+          break;
+      }
+    }
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 __fastcall TCustomCommandType::TCustomCommandType() :
   FParams(0), FShortCut(0), FShortCutOriginal(0)

+ 5 - 0
source/windows/WinConfiguration.h

@@ -350,6 +350,7 @@ enum TPathInCaption { picShort, picFull, picNone };
 enum TSessionTabNameFormat { stnfNone, stnfShortPath, stnfShortPathTrunc };
 // constants must be compatible with legacy CopyOnDoubleClick
 enum TDoubleClickAction { dcaOpen = 0, dcaCopy = 1, dcaEdit = 2 };
+enum TResolvedDoubleClickAction { rdcaNone, rdcaChangeDir, rdcaOpen, rdcaCopy, rdcaEdit };
 //---------------------------------------------------------------------------
 typedef void __fastcall (__closure *TMasterPasswordPromptEvent)();
 //---------------------------------------------------------------------------
@@ -359,6 +360,7 @@ private:
   UnicodeString FAutoStartSession;
   TDoubleClickAction FDoubleClickAction;
   bool FCopyOnDoubleClickConfirmation;
+  bool FAlwaysRespectDoubleClickAction;
   bool FDDDisableMove;
   TAutoSwitch FDDTransferConfirmation;
   bool FDeleteToRecycleBin;
@@ -480,6 +482,7 @@ private:
 
   void __fastcall SetDoubleClickAction(TDoubleClickAction value);
   void __fastcall SetCopyOnDoubleClickConfirmation(bool value);
+  void __fastcall SetAlwaysRespectDoubleClickAction(bool value);
   void __fastcall SetDDDisableMove(bool value);
   void __fastcall SetDDTransferConfirmation(TAutoSwitch value);
   void __fastcall SetDeleteToRecycleBin(bool value);
@@ -665,6 +668,7 @@ public:
   bool __fastcall IsDDExtRunning();
   bool __fastcall IsDDExtBroken();
   bool __fastcall UseDarkTheme();
+  TResolvedDoubleClickAction ResolveDoubleClickAction(bool IsDirectory, TTerminal * Terminal);
 
   static void __fastcall RestoreFont(const TFontConfiguration & Configuration, TFont * Font);
   static void __fastcall StoreFont(TFont * Font, TFontConfiguration & Configuration);
@@ -687,6 +691,7 @@ public:
   __property UnicodeString AutoStartSession = { read = FAutoStartSession, write = SetAutoStartSession };
   __property TDoubleClickAction DoubleClickAction = { read = FDoubleClickAction, write = SetDoubleClickAction };
   __property bool CopyOnDoubleClickConfirmation = { read = FCopyOnDoubleClickConfirmation, write = SetCopyOnDoubleClickConfirmation };
+  __property bool AlwaysRespectDoubleClickAction = { read = FAlwaysRespectDoubleClickAction, write = SetAlwaysRespectDoubleClickAction };
   __property bool DDDisableMove = { read = FDDDisableMove, write = SetDDDisableMove };
   __property TAutoSwitch DDTransferConfirmation = { read = FDDTransferConfirmation, write = SetDDTransferConfirmation };
   __property bool DeleteToRecycleBin = { read = FDeleteToRecycleBin, write = SetDeleteToRecycleBin };