Browse Source

Bug 2211: Allow browsing a source folder/file instead of downloading when handling a download URL + Do not browse a source folders when download dialog is canceled

https://winscp.net/tracker/2211

This reimplements some functionality from 9015d810, which was implemented in suspiciously complicate way for reasons I do not remember.

Source commit: e82be7ff99f61c1a7bdd4722fc9f47e533d7c2bc
Martin Prikryl 2 years ago
parent
commit
d8afea474b

+ 26 - 2
source/forms/Copy.cpp

@@ -131,6 +131,12 @@ __fastcall TCopyDialog::TCopyDialog(
   CopyParamListButton(TransferSettingsButton);
   HotTrackLabel(ShortCutHintLabel);
 
+  if (FLAGSET(FOptions, coBrowse))
+  {
+    DebugAssert(!FToRemote);
+    OkButton->Style = TCustomButton::bsSplitButton;
+  }
+
   UseSystemSettings(this);
 }
 //---------------------------------------------------------------------------
@@ -295,7 +301,8 @@ int __fastcall TCopyDialog::GetOutputOptions()
 {
   return FOutputOptions |
     FLAGMASK(FSaveSettings, cooSaveSettings) |
-    FLAGMASK(NeverShowAgainCheck->Checked, cooDoNotShowAgain);
+    FLAGMASK(NeverShowAgainCheck->Checked, cooDoNotShowAgain) |
+    FLAGMASK(FBrowse, cooBrowse);
 }
 //---------------------------------------------------------------------------
 THistoryComboBox * __fastcall TCopyDialog::GetDirectoryEdit()
@@ -418,6 +425,7 @@ bool __fastcall TCopyDialog::Execute()
   FPreset = GUIConfiguration->CopyParamCurrent;
   DirectoryEdit->Items = CustomWinConfiguration->History[
     FToRemote ? L"RemoteTarget" : L"LocalTarget"];
+  FBrowse = false;
   bool Result = (ShowModal() == DefaultResult(this));
   if (Result)
   {
@@ -449,7 +457,7 @@ bool __fastcall TCopyDialog::Execute()
 void __fastcall TCopyDialog::FormCloseQuery(TObject * /*Sender*/,
       bool &CanClose)
 {
-  if (ModalResult == DefaultResult(this))
+  if ((ModalResult == DefaultResult(this)) && !FBrowse)
   {
     ExitActiveControl(this);
 
@@ -604,3 +612,19 @@ void __fastcall TCopyDialog::LocalDirectoryEditExit(TObject *)
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TCopyDialog::DownloadItemClick(TObject *)
+{
+  OkButton->Click();
+}
+//---------------------------------------------------------------------------
+void __fastcall TCopyDialog::BrowseItemClick(TObject *)
+{
+  FBrowse = true;
+  OkButton->Click();
+}
+//---------------------------------------------------------------------------
+void __fastcall TCopyDialog::OkButtonDropDownClick(TObject *)
+{
+  MenuPopup(OkMenu, OkButton);
+}
+//---------------------------------------------------------------------------

+ 14 - 0
source/forms/Copy.dfm

@@ -69,6 +69,7 @@ object CopyDialog: TCopyDialog
     Default = True
     ModalResult = 1
     TabOrder = 6
+    OnDropDownClick = OkButtonDropDownClick
   end
   object CancelButton: TButton
     Left = 343
@@ -178,4 +179,17 @@ object CopyDialog: TCopyDialog
       OnClick = ShortCutHintLabelClick
     end
   end
+  object OkMenu: TPopupMenu
+    Left = 456
+    Top = 69
+    object DownloadItem: TMenuItem
+      Caption = '&Download'
+      Default = True
+      OnClick = DownloadItemClick
+    end
+    object BrowseItem: TMenuItem
+      Caption = '&Browse'
+      OnClick = BrowseItemClick
+    end
+  end
 end

+ 7 - 0
source/forms/Copy.h

@@ -33,6 +33,9 @@ __published:
   TImage *Image;
   TPanel *ShortCutHintPanel;
   TLabel *ShortCutHintLabel;
+  TPopupMenu *OkMenu;
+  TMenuItem *DownloadItem;
+  TMenuItem *BrowseItem;
   void __fastcall FormShow(TObject *Sender);
   void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);
   void __fastcall LocalDirectoryBrowseButtonClick(TObject *Sender);
@@ -46,6 +49,9 @@ __published:
   void __fastcall NeverShowAgainCheckClick(TObject *Sender);
   void __fastcall ShortCutHintLabelClick(TObject *Sender);
   void __fastcall LocalDirectoryEditExit(TObject *Sender);
+  void __fastcall DownloadItemClick(TObject *Sender);
+  void __fastcall BrowseItemClick(TObject *Sender);
+  void __fastcall OkButtonDropDownClick(TObject *Sender);
 private:
   bool FDefaultToRemote;
   bool FToRemote;
@@ -60,6 +66,7 @@ private:
   int FCopyParamAttrs;
   TSessionData * FSessionData;
   bool FSaveSettings;
+  bool FBrowse;
   UnicodeString __fastcall GetDirectory();
   THistoryComboBox * __fastcall GetDirectoryEdit();
   void __fastcall SetParams(const TGUICopyParamType & value);

+ 12 - 3
source/forms/CustomScpExplorer.cpp

@@ -11646,14 +11646,23 @@ void __fastcall TCustomScpExplorerForm::RemoteDirViewResize(TObject *)
   CenterReconnectToolbar();
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::BrowseFile()
+void TCustomScpExplorerForm::DoBrowseFile(TCustomDirView * DirView, const UnicodeString & FileName)
 {
-  if (RemoteDirView->ItemFocused != NULL)
+  if (!FileName.IsEmpty())
   {
-    RemoteDirView->ItemFocused->Selected = true;
+    DirView->RestoreFocus(FileName);
+    if (DirView->ItemFocused != NULL)
+    {
+      DirView->ItemFocused->Selected = true;
+    }
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::BrowseFile(const UnicodeString & FileName)
+{
+  DoBrowseFile(RemoteDirView, FileName);
+}
+//---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::UpdateQueueFileList()
 {
   if (!FQueueStatusUpdating)

+ 2 - 1
source/forms/CustomScpExplorer.h

@@ -756,6 +756,7 @@ protected:
   void LoadFilesProperties(TStrings * FileList);
   void PasteFiles();
   bool DoDirectoryExists(void * Session, const UnicodeString & Directory);
+  void DoBrowseFile(TCustomDirView * DirView, const UnicodeString & FileName);
 
 public:
   virtual __fastcall ~TCustomScpExplorerForm();
@@ -899,7 +900,7 @@ public:
   void __fastcall PrivateKeyUpload();
   bool __fastcall IsComponentPossible(Byte Component);
   void __fastcall ReplaceTerminal(TManagedTerminal * value);
-  virtual void __fastcall BrowseFile();
+  virtual void __fastcall BrowseFile(const UnicodeString & FileName);
   void __fastcall CloseApp();
   virtual bool SupportsLocalBrowser();
   virtual bool IsSideLocalBrowser(TOperationSide Side);

+ 3 - 6
source/forms/ScpCommander.cpp

@@ -2655,14 +2655,11 @@ void __fastcall TScpCommanderForm::FileColorsChanged()
   DoFileColorsChanged(OtherLocalDirView);
 }
 //---------------------------------------------------------------------------
-void __fastcall TScpCommanderForm::BrowseFile()
+void __fastcall TScpCommanderForm::BrowseFile(const UnicodeString & FileName)
 {
   DebugAssert(!IsLocalBrowserMode());
-  TCustomScpExplorerForm::BrowseFile();
-  if (LocalDirView->ItemFocused != NULL)
-  {
-    LocalDirView->ItemFocused->Selected = true;
-  }
+  TCustomScpExplorerForm::BrowseFile(FileName);
+  DoBrowseFile(LocalDirView, FileName);
   TScpCommanderConfiguration ScpCommander = WinConfiguration->ScpCommander;
   // Select the panel that has the file, with preference on the remote panel
   if ((RemoteDirView->ItemFocused != NULL) && RemoteDirView->ItemFocused->Selected)

+ 1 - 1
source/forms/ScpCommander.h

@@ -678,7 +678,7 @@ public:
   virtual void __fastcall GoToAddress();
   virtual void __fastcall CopyFilesToClipboard(TOperationSide Side, bool OnFocused);
   virtual void __fastcall PasteFromClipBoard();
-  virtual void __fastcall BrowseFile();
+  virtual void __fastcall BrowseFile(const UnicodeString & FileName);
   virtual bool SupportsLocalBrowser();
   virtual bool IsSideLocalBrowser(TOperationSide Side);
   virtual bool IsLocalBrowserMode();

+ 6 - 21
source/packages/filemng/CustomDirView.pas

@@ -340,7 +340,6 @@ type
     procedure UpdateDarkMode;
     procedure DoUpdateStatusBar(Force: Boolean = False);
     procedure DoCustomDrawItem(Item: TListItem; Stage: TCustomDrawStage);
-    procedure RestoreFocus(FocusedItem: string);
     procedure ItemCalculatedSizeUpdated(Item: TListItem; OldSize, NewSize: Int64);
     property ImageList16: TImageList read FImageList16;
     property ImageList32: TImageList read FImageList32;
@@ -387,6 +386,7 @@ type
     function SaveState: TObject; virtual;
     procedure RestoreState(AState: TObject); virtual;
     procedure AnnounceState(AState: TObject); virtual;
+    procedure RestoreFocus(FocusedItem: string);
     procedure DisplayContextMenu(Where: TPoint); virtual; abstract;
     procedure DisplayContextMenuInSitu;
     procedure UpdateStatusBar;
@@ -514,8 +514,6 @@ resourcestring
   SDriveNotReady = 'Drive ''%s:'' is not ready.';
   SDirNotExists = 'Directory ''%s'' doesn''t exist.';
 
-function CreateDirViewStateForFocusedItem(FocusedItem: string): TObject;
-
 {Additional non-component specific functions:}
 
 {Create and resolve a shell link (file shortcut):}
@@ -642,15 +640,6 @@ begin
   inherited;
 end;
 
-function CreateDirViewStateForFocusedItem(FocusedItem: string): TObject;
-var
-  State: TDirViewState;
-begin
-  State := TDirViewState.Create;
-  State.FocusedItem := FocusedItem;
-  Result := State;
-end;
-
 function IsExecutable(FileName: string): Boolean;
 var
   FileExt: string;
@@ -3348,17 +3337,13 @@ begin
     State := AState as TDirViewState;
     Assert(Assigned(State));
 
-    if Assigned(State.HistoryPaths) then
-      FHistoryPaths.Assign(State.HistoryPaths);
+    FHistoryPaths.Assign(State.HistoryPaths);
     FBackCount := State.BackCount;
     DoHistoryChange;
-    if State.SortStr <> '' then
-    begin
-      // TCustomDirViewColProperties should not be here
-      DirColProperties := ColProperties as TCustomDirViewColProperties;
-      Assert(Assigned(DirColProperties));
-      DirColProperties.SortStr := State.SortStr;
-    end;
+    // TCustomDirViewColProperties should not be here
+    DirColProperties := ColProperties as TCustomDirViewColProperties;
+    Assert(Assigned(DirColProperties));
+    DirColProperties.SortStr := State.SortStr;
     Mask := State.Mask;
     RestoreFocus(State.FocusedItem);
   end

+ 2 - 0
source/windows/WinInterface.h

@@ -220,9 +220,11 @@ const coAllowRemoteTransfer = 0x100;
 const coNoQueue             = 0x200;
 const coShortCutHint        = 0x800;
 const coAllFiles            = 0x1000;
+const coBrowse              = 0x2000;
 const cooDoNotShowAgain     = 0x01;
 const cooRemoteTransfer     = 0x02;
 const cooSaveSettings       = 0x04;
+const cooBrowse             = 0x08;
 bool __fastcall DoCopyDialog(
   bool ToRemote, bool Move, TStrings * FileList, UnicodeString & TargetDirectory,
   TGUICopyParamType * Params, int Options, int CopyParamAttrs,

+ 35 - 27
source/windows/WinMain.cpp

@@ -131,7 +131,7 @@ void __fastcall Upload(TTerminal * Terminal, TStrings * FileList, int UseDefault
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall Download(TTerminal * Terminal, const UnicodeString FileName, int UseDefaults)
+void __fastcall Download(TTerminal * Terminal, const UnicodeString FileName, int UseDefaults, bool & Browse, UnicodeString & BrowseFile)
 {
   TRemoteFile * File = NULL;
 
@@ -169,33 +169,45 @@ void __fastcall Download(TTerminal * Terminal, const UnicodeString FileName, int
     std::unique_ptr<TStrings> FileListFriendly(new TStringList());
     FileListFriendly->AddObject(FriendyFileName, File);
 
-    int Options = coDisableQueue;
+    int Options = coDisableQueue | coBrowse;
     int CopyParamAttrs = Terminal->UsableCopyParamAttrs(0).Download;
+    int OutputOptions = 0;
     if ((UseDefaults == 0) ||
         DoCopyDialog(false, false, FileListFriendly.get(), TargetDirectory, &CopyParam,
-          Options, CopyParamAttrs, NULL, NULL, UseDefaults))
+          Options, CopyParamAttrs, NULL, &OutputOptions, UseDefaults))
     {
-      // Setting parameter overrides only now, otherwise the dialog would present the parametes as non-default
-
-      if (CustomDisplayName)
+      if (FLAGCLEAR(OutputOptions, cooBrowse))
       {
-        // Set only now, so that it is not redundantly displayed on the copy dialog.
-        // We should escape the * and ?'s.
-        CopyParam.FileMask = DisplayName;
-      }
+        // Setting parameter overrides only now, otherwise the dialog would present the parametes as non-default
 
-      CopyParam.OnceDoneOperation = odoDisconnect;
+        if (CustomDisplayName)
+        {
+          // Set only now, so that it is not redundantly displayed on the copy dialog.
+          // We should escape the * and ?'s.
+          CopyParam.FileMask = DisplayName;
+        }
 
-      std::unique_ptr<TStrings> FileList(new TStringList());
-      FileList->AddObject(FileName, File);
-      CopyParam.IncludeFileMask.SetRoots(TargetDirectory, FileList.get());
+        CopyParam.OnceDoneOperation = odoDisconnect;
 
-      Terminal->CopyToLocal(FileList.get(), TargetDirectory, &CopyParam, 0, NULL);
-    }
+        std::unique_ptr<TStrings> FileList(new TStringList());
+        FileList->AddObject(FileName, File);
+        CopyParam.IncludeFileMask.SetRoots(TargetDirectory, FileList.get());
 
-    UnicodeString Directory = UnixExtractFilePath(FileName);
-    Terminal->AutoReadDirectory = true;
-    Terminal->ChangeDirectory(Directory);
+        Terminal->CopyToLocal(FileList.get(), TargetDirectory, &CopyParam, 0, NULL);
+      }
+      else
+      {
+        UnicodeString Directory = UnixExtractFilePath(FileName);
+        BrowseFile = UnixExtractFileName(FileName);
+        Browse = true;
+        Terminal->AutoReadDirectory = true;
+        Terminal->ChangeDirectory(Directory);
+      }
+    }
+    else
+    {
+      Abort();
+    }
   }
   __finally
   {
@@ -1279,10 +1291,10 @@ int __fastcall Execute()
 
               bool CanStart;
               bool Browse = false;
+              UnicodeString BrowseFile;
               if (DataList->Count > 0)
               {
                 TManagedTerminal * Session = TerminalManager->NewSessions(DataList.get());
-                UnicodeString BrowseFile;
                 if (Params->FindSwitch(BROWSE_SWITCH, BrowseFile) &&
                     (!BrowseFile.IsEmpty() || !DownloadFile.IsEmpty()))
                 {
@@ -1290,10 +1302,6 @@ int __fastcall Execute()
                   {
                     BrowseFile = DownloadFile;
                   }
-                  DebugAssert(Session->RemoteExplorerState == NULL);
-                  Session->RemoteExplorerState = CreateDirViewStateForFocusedItem(BrowseFile);
-                  DebugAssert(Session->LocalExplorerState == NULL);
-                  Session->LocalExplorerState = CreateDirViewStateForFocusedItem(BrowseFile);
                   DownloadFile = UnicodeString();
                   Browse = true;
                 }
@@ -1362,8 +1370,8 @@ int __fastcall Execute()
                   }
                   else if (!DownloadFile.IsEmpty())
                   {
-                    Download(TerminalManager->ActiveSession, DownloadFile,
-                      UseDefaults);
+                    Download(
+                      TerminalManager->ActiveSession, DownloadFile, UseDefaults, Browse, BrowseFile);
                   }
                   else
                   {
@@ -1377,7 +1385,7 @@ int __fastcall Execute()
 
                   if (Browse)
                   {
-                    ScpExplorer->BrowseFile();
+                    ScpExplorer->BrowseFile(BrowseFile);
                   }
 
                   AddStartupSequence(L"R");