Procházet zdrojové kódy

Bug 1673: When a path entered in Open Directory dialog or Address toolbar cannot be opened, retry an entry to allow user to correct it

https://winscp.net/tracker/1673

Source commit: 7a413f59d854f3c21b808bb78666552a4c4bb0ec
Martin Prikryl před 7 roky
rodič
revize
fbd2162e16

+ 54 - 7
source/forms/CustomScpExplorer.cpp

@@ -5941,14 +5941,24 @@ void __fastcall TCustomScpExplorerForm::DoOpenDirectoryDialog(
     try
     {
       UnicodeString Name = DirView(Side)->PathName;
-      if (::DoOpenDirectoryDialog(Mode, Side, Name, VisitedDirectories, Terminal,
-            // do not allow switching to location profiles,
-            // if we are not connected
-            HasDirView[osLocal] && (Terminal != NULL)))
-      {
-        TWindowLock Lock(this);
-        DirView(Side)->Path = Name;
+      bool Repeat;
+      do
+      {
+        Repeat = false;
+        if (::DoOpenDirectoryDialog(Mode, Side, Name, VisitedDirectories, Terminal,
+              // do not allow switching to location profiles,
+              // if we are not connected
+              HasDirView[osLocal] && (Terminal != NULL)))
+        {
+          TWindowLock Lock(this);
+          if (!TryOpenDirectory(Side, Name))
+          {
+            Repeat = true;
+            Mode = odBrowse;
+          }
+        }
       }
+      while (Repeat);
     }
     __finally
     {
@@ -9808,3 +9818,40 @@ void __fastcall TCustomScpExplorerForm::CreateOpenDirMenu(TTBCustomItem * Menu,
   Menu->Add(Item.release());
 }
 //---------------------------------------------------------------------------
+bool __fastcall TCustomScpExplorerForm::TryOpenDirectory(TOperationSide Side, const UnicodeString & Path)
+{
+  bool Result = true;
+  try
+  {
+    if (Side == osRemote)
+    {
+      Terminal->ExceptionOnFail = true;
+    }
+
+    try
+    {
+      DirView(Side)->Path = Path;
+    }
+    __finally
+    {
+      if (Side == osRemote)
+      {
+        Terminal->ExceptionOnFail = false;
+      }
+    }
+  }
+  catch (Exception & E)
+  {
+    if ((Side != osRemote) || Terminal->Active)
+    {
+      ShowExtendedExceptionEx(Terminal, &E);
+      Result = false;
+    }
+    else
+    {
+      throw;
+    }
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------

+ 1 - 0
source/forms/CustomScpExplorer.h

@@ -619,6 +619,7 @@ protected:
   void __fastcall SynchronizeProcessedItem(void * Token, const TSynchronizeChecklist::TItem * ChecklistItem);
   void __fastcall CreateOpenDirMenuList(TTBCustomItem * Menu, TOperationSide Side, TBookmarkList * BookmarkList);
   void __fastcall CreateOpenDirMenu(TTBCustomItem * Menu, TOperationSide Side);
+  bool __fastcall TryOpenDirectory(TOperationSide Side, const UnicodeString & Path);
 
 public:
   virtual __fastcall ~TCustomScpExplorerForm();

+ 23 - 2
source/forms/ScpExplorer.cpp

@@ -290,6 +290,20 @@ void __fastcall TScpExplorerForm::UnixPathComboBoxBeginEdit(
   TTBEditItem * /*Sender*/, TTBEditItemViewer * /*Viewer*/, TEdit * EditControl)
 {
   InstallPathWordBreakProc(EditControl);
+  if (!FFailedAddress.IsEmpty())
+  {
+    EditControl->Text = FFailedAddress;
+    EditControl->SelectAll();
+  }
+  FFailedAddress = UnicodeString();
+}
+//---------------------------------------------------------------------------
+void __fastcall TScpExplorerForm::AddressToolbarEndModal(TObject * /*Sender*/)
+{
+  if (!FFailedAddress.IsEmpty())
+  {
+    GoToAddress();
+  }
 }
 //---------------------------------------------------------------------------
 UnicodeString __fastcall TScpExplorerForm::RemotePathComboBoxText()
@@ -320,8 +334,15 @@ void __fastcall TScpExplorerForm::UnixPathComboBoxAcceptText(
 {
   if (RemoteDirView->Path != NewText)
   {
-    RemoteDirView->Path = NewText;
-    NewText = RemotePathComboBoxText();
+    if (!TryOpenDirectory(osRemote, NewText))
+    {
+      FFailedAddress = NewText;
+      Abort();
+    }
+    else
+    {
+      NewText = RemotePathComboBoxText();
+    }
   }
 }
 //---------------------------------------------------------------------------

+ 1 - 0
source/forms/ScpExplorer.dfm

@@ -883,6 +883,7 @@ inherited ScpExplorerForm: TScpExplorerForm
       TabOrder = 1
       OnResize = ToolBarResize
       OnGetBaseSize = ToolbarGetBaseSize
+      OnEndModal = AddressToolbarEndModal
       object TBXLabelItem1: TTBXLabelItem
         Caption = 'Address'
         Margin = 2

+ 2 - 0
source/forms/ScpExplorer.h

@@ -324,9 +324,11 @@ __published:
   void __fastcall QueueSubmenuItemPopup(TTBCustomItem *Sender,
           bool FromLink);
   void __fastcall RemoteStatusBarPanelClick(TTBXCustomStatusBar *Sender, TTBXStatusPanel *Panel);
+  void __fastcall AddressToolbarEndModal(TObject *Sender);
 
 private:
   UnicodeString FStatusBarFileText;
+  UnicodeString FFailedAddress;
 
   void __fastcall RemotePanelSplitterDblClick(TObject * Sender);
 

+ 1 - 1
source/packages/tb2k/TB2Item.pas

@@ -505,7 +505,7 @@ type
     { /MP }
     procedure EndModalWithSystemMenu(AWnd: HWND; AKey: Cardinal);
     procedure EndUpdate;
-    procedure EnterToolbarLoop(Options: TTBEnterToolbarLoopOptions);
+    procedure EnterToolbarLoop(Options: TTBEnterToolbarLoopOptions); virtual;
     procedure ExecuteSelected(AGivePriority: Boolean);
     function Find(Item: TTBCustomItem): TTBItemViewer;
     function FirstSelectable: TTBItemViewer;

+ 11 - 0
source/packages/tb2k/TB2Toolbar.pas

@@ -55,6 +55,7 @@ type
     constructor Create(AOwner: TComponent); override;
     function GetFont: TFont; override;
     procedure InvalidatePositions; override;
+    procedure EnterToolbarLoop(Options: TTBEnterToolbarLoopOptions); override;
   end;
 
   TTBChevronPriorityForNewItems = (tbcpHighest, tbcpLowest);
@@ -83,6 +84,7 @@ type
     FUpdateActions: Boolean;
     { MP }
     FOnGetBaseSize: TToolbarGetBaseSizeEvent;
+    FOnEndModal: TNotifyEvent;
 
     procedure CancelHover;
     function CalcChevronOffset(const ADock: TTBDock;
@@ -191,6 +193,7 @@ type
     property View: TTBToolbarView read FView;
     { MP }
     property OnGetBaseSize: TToolbarGetBaseSizeEvent read FOnGetBaseSize write FOnGetBaseSize;
+    property OnEndModal: TNotifyEvent read FOnEndModal write FOnEndModal;
   published
     property Hint stored False;  { Hint is set dynamically; don't save it }
   end;
@@ -264,6 +267,7 @@ type
     property OnVisibleChanged;
     { MP }
     property OnGetBaseSize;
+    property OnEndModal;
   end;
 
 { TTBChevronItem & TTBChevronItemViewer }
@@ -520,6 +524,12 @@ begin
   Result := FToolbar.FMDISystemMenuItem;
 end;
 
+procedure TTBToolbarView.EnterToolbarLoop(Options: TTBEnterToolbarLoopOptions);
+begin
+  inherited;
+  if Assigned(FToolbar.OnEndModal) then
+    FToolbar.OnEndModal(FToolbar);
+end;
 
 { TTBCustomToolbar }
 
@@ -549,6 +559,7 @@ begin
   SetBounds(Left, Top, 23, 22);{}
   { MP }
   FOnGetBaseSize := nil;
+  FOnEndModal := nil;
 end;
 
 destructor TTBCustomToolbar.Destroy;

+ 1 - 0
source/packages/tbx/TBX.pas

@@ -409,6 +409,7 @@ type
     property OnVisibleChanged;
     { MP }
     property OnGetBaseSize;
+    property OnEndModal;
   end;
 
   { TTBXChevronItem }