浏览代码

Bug 1127: Bookmark drop down menu

https://winscp.net/tracker/1127

Source commit: 511cdab3afe0274096f8eea9a512e084d995db3f
Martin Prikryl 7 年之前
父节点
当前提交
5dfbf31821

+ 5 - 0
source/core/Bookmarks.cpp

@@ -577,3 +577,8 @@ UnicodeString __fastcall TBookmark::GetKey()
 {
   return BookmarkKey(Node, Name);
 }
+//---------------------------------------------------------------------------
+UnicodeString __fastcall TBookmark::GetSideDirectory(TOperationSide Side)
+{
+  return (Side == osLocal) ? Local : Remote;
+}

+ 4 - 0
source/core/Bookmarks.h

@@ -2,6 +2,8 @@
 #ifndef BookmarksH
 #define BookmarksH
 //---------------------------------------------------------------------------
+#include <CopyParam.h>
+//---------------------------------------------------------------------------
 class THierarchicalStorage;
 class TBookmarkList;
 class TShortCuts;
@@ -83,6 +85,8 @@ public:
 
   virtual void __fastcall Assign(TPersistent * Source);
 
+  UnicodeString __fastcall GetSideDirectory(TOperationSide Side);
+
   __property UnicodeString Name = { read = FName, write = SetName };
   __property UnicodeString Local = { read = FLocal, write = SetLocal };
   __property UnicodeString Remote = { read = FRemote, write = SetRemote };

+ 128 - 12
source/forms/CustomScpExplorer.cpp

@@ -4066,24 +4066,16 @@ void __fastcall TCustomScpExplorerForm::OpenDirectory(TOperationSide Side)
   DoOpenDirectoryDialog(odBrowse, Side);
 }
 //---------------------------------------------------------------------------
-bool __fastcall TCustomScpExplorerForm::OpenBookmark(UnicodeString Local, UnicodeString Remote)
+bool __fastcall TCustomScpExplorerForm::OpenBookmark(TOperationSide Side, TBookmark * Bookmark)
 {
-  UnicodeString Path;
-  if (FCurrentSide == osRemote)
-  {
-    Path = Remote;
-  }
-  else
-  {
-    Path = Local;
-  }
+  UnicodeString Path = Bookmark->GetSideDirectory(Side);
 
   bool Result = !Path.IsEmpty();
   if (Result)
   {
     // While we might get here when the session is closed (from location profiles),
     // it's not a problem as the Path setter is noop then
-    DirView(FCurrentSide)->Path = Path;
+    DirView(Side)->Path = Path;
   }
   return Result;
 }
@@ -4322,7 +4314,7 @@ void __fastcall TCustomScpExplorerForm::KeyDown(Word & Key, Classes::TShiftState
       {
         TBookmark * Bookmark = WinConfiguration->SharedBookmarks->FindByShortCut(CustomShortCut);
         if ((Bookmark != NULL) &&
-            OpenBookmark(Bookmark->Local, Bookmark->Remote))
+            OpenBookmark(FCurrentSide, Bookmark))
         {
           KeyProcessed(Key, Shift);
         }
@@ -9571,3 +9563,127 @@ void __fastcall TCustomScpExplorerForm::CopyPopup(TControl * DestControl, TContr
   static_cast<TPublicControl *>(DestControl)->OnContextPopup = static_cast<TPublicControl *>(SourceControl)->OnContextPopup;
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::DoBookmarkClick(TOperationSide Side, TObject * Sender)
+{
+  TBookmark * Bookmark = DebugNotNull(reinterpret_cast<TBookmark *>(dynamic_cast<TTBCustomItem *>(Sender)->Tag));
+  OpenBookmark(Side, Bookmark);
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::LocalBookmarkClick(TObject * Sender)
+{
+  DoBookmarkClick(osLocal, Sender);
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::RemoteBookmarkClick(TObject * Sender)
+{
+  DoBookmarkClick(osRemote, Sender);
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::CreateOpenDirMenuList(
+  TTBCustomItem * Menu, TOperationSide Side, TBookmarkList * BookmarkList)
+{
+  TNotifyEvent OnBookmarkClick = (Side == osLocal) ? &LocalBookmarkClick : &RemoteBookmarkClick;
+
+  if (!WinConfiguration->UseLocationProfiles)
+  {
+    std::unique_ptr<TStringList> Directories(new TStringList());
+    Directories->CaseSensitive = (Side == osRemote);
+    for (int Index = 0; Index < BookmarkList->Count; Index++)
+    {
+      TBookmark * Bookmark = BookmarkList->Bookmarks[Index];
+      UnicodeString Directory = Bookmark->GetSideDirectory(Side);
+      if (!Directory.IsEmpty() && (Directories->IndexOf(Directory) < 0))
+      {
+        std::unique_ptr<TTBCustomItem> Item(new TTBXItem(Owner));
+        Item->Caption = EscapeHotkey(Directory);
+        Item->ShortCut = Bookmark->ShortCut;
+        Item->OnClick = OnBookmarkClick;
+        Item->Tag = reinterpret_cast<int>(Bookmark);
+        Directories->Add(Directory);
+        Menu->Add(Item.release());
+      }
+    }
+  }
+  else
+  {
+    std::unique_ptr<TStrings> Folders(CreateSortedStringList());
+    for (int Index = 0; Index < BookmarkList->Count; Index++)
+    {
+      TBookmark * Bookmark = BookmarkList->Bookmarks[Index];
+      if (!Bookmark->Node.IsEmpty())
+      {
+        Folders->Add(Bookmark->Node);
+      }
+    }
+
+    for (int Index = 0; Index < Folders->Count; Index++)
+    {
+      std::unique_ptr<TTBCustomItem> Item(new TTBXSubmenuItem(Owner));
+      Item->Caption = Folders->Strings[Index];
+      Item->ImageIndex = NonVisualDataModule->RemoteChangePathAction->ImageIndex;
+      Folders->Objects[Index] = Item.get();
+      Menu->Add(Item.release());
+    }
+
+    for (int Index = 0; Index < BookmarkList->Count; Index++)
+    {
+      TBookmark * Bookmark = BookmarkList->Bookmarks[Index];
+      TTBCustomItem * Parent;
+      if (!Bookmark->Node.IsEmpty())
+      {
+        DebugAssert(Folders->IndexOf(Bookmark->Node) >= 0);
+        Parent = dynamic_cast<TTBCustomItem *>(Folders->Objects[Folders->IndexOf(Bookmark->Node)]);
+      }
+      else
+      {
+        Parent = Menu;
+      }
+      std::unique_ptr<TTBCustomItem> Item(new TTBXItem(Owner));
+      Item->Caption = Bookmark->Name;
+      Item->ShortCut = Bookmark->ShortCut;
+      Item->OnClick = OnBookmarkClick;
+      Item->Tag = reinterpret_cast<int>(Bookmark);
+
+      if (((Bookmark->Name == Bookmark->Local) || (Bookmark->Name == Bookmark->Remote)) &&
+          (Bookmark->Local.IsEmpty() || Bookmark->Remote.IsEmpty()))
+      {
+        // No hint for location profiles that are actually mere "bookmarks"
+      }
+      else
+      {
+        UnicodeString Hint = FORMAT(LoadStrPart(LOCATION_PROFILE_HINT, 1), (Bookmark->Name));
+        UnicodeString LongHint;
+        if (!Bookmark->Local.IsEmpty())
+        {
+          AddToList(LongHint, FORMAT(LoadStrPart(LOCATION_PROFILE_HINT, 2), (Bookmark->Local)), L"\n");
+        }
+        if (!Bookmark->Remote.IsEmpty())
+        {
+          AddToList(LongHint, FORMAT(LoadStrPart(LOCATION_PROFILE_HINT, 3), (Bookmark->Remote)), L"\n");
+        }
+        AddToList(Hint, LongHint, L"|");
+        Item->Hint = Hint;
+      }
+
+      Parent->Add(Item.release());
+    }
+  }
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::CreateOpenDirMenu(TTBCustomItem * Menu, TOperationSide Side)
+{
+  Menu->Clear();
+
+  CreateOpenDirMenuList(Menu, Side, WinConfiguration->Bookmarks[Terminal->SessionData->SessionKey]);
+
+  AddMenuSeparator(Menu);
+
+  CreateOpenDirMenuList(Menu, Side, WinConfiguration->SharedBookmarks);
+
+  AddMenuSeparator(Menu);
+
+  std::unique_ptr<TTBCustomItem> Item(new TTBXItem(Owner));
+  Item->Action = (Side == osLocal) ? NonVisualDataModule->LocalAddBookmarkAction : NonVisualDataModule->RemoteAddBookmarkAction;
+  Menu->Add(Item.release());
+}
+//---------------------------------------------------------------------------

+ 7 - 1
source/forms/CustomScpExplorer.h

@@ -48,6 +48,7 @@ class TTransferPresetNoteData;
 struct TEditedFileData;
 class ITaskbarList3;
 struct TSynchronizeParams;
+class TBookmark;
 //---------------------------------------------------------------------------
 enum TActionAllowed { aaShortCut, aaUpdate, aaExecute };
 enum TActionFlag { afLocal = 1, afRemote = 2, afExplorer = 4 , afCommander = 8 };
@@ -301,6 +302,9 @@ private:
   void __fastcall WMClose(TMessage & Message);
   void __fastcall CMDpiChanged(TMessage & Message);
   void __fastcall WMDpiChanged(TMessage & Message);
+  void __fastcall DoBookmarkClick(TOperationSide Side, TObject * Sender);
+  void __fastcall LocalBookmarkClick(TObject * Sender);
+  void __fastcall RemoteBookmarkClick(TObject * Sender);
 
 protected:
   TOperationSide FCurrentSide;
@@ -539,7 +543,7 @@ protected:
   virtual void __fastcall ToolbarItemResize(TTBXCustomDropDownItem * Item, int Width);
   virtual void __fastcall CreateWnd();
   virtual void __fastcall DestroyWnd();
-  virtual bool __fastcall OpenBookmark(UnicodeString Local, UnicodeString Remote);
+  virtual bool __fastcall OpenBookmark(TOperationSide Side, TBookmark * Bookmark);
   void __fastcall DoFindFiles(TTerminal * Terminal, UnicodeString Directory, const TFileMasks & FileMask,
     TFileFoundEvent OnFileFound, TFindingFileEvent OnFindingFile);
   virtual void __fastcall DoFocusRemotePath(TTerminal * Terminal, const UnicodeString & Path);
@@ -603,6 +607,8 @@ protected:
   void __fastcall CreateRemoteDirectory(const UnicodeString & Path, TRemoteProperties & Properties);
   void __fastcall DoFullSynchronize(void * Token, TProcessedItem OnProcessedItem);
   void __fastcall FullSynchronize(TSynchronizeParams & Params, TProcessedItem OnProcessedItem);
+  void __fastcall CreateOpenDirMenuList(TTBCustomItem * Menu, TOperationSide Side, TBookmarkList * BookmarkList);
+  void __fastcall CreateOpenDirMenu(TTBCustomItem * Menu, TOperationSide Side);
 
 public:
   virtual __fastcall ~TCustomScpExplorerForm();

+ 1 - 1
source/forms/OpenDirectory.cpp

@@ -189,7 +189,7 @@ TStrings * __fastcall TOpenDirectoryDialog::GetDirectories()
 //---------------------------------------------------------------------------
 UnicodeString __fastcall TOpenDirectoryDialog::BookmarkDirectory(TBookmark * Bookmark)
 {
-  return OperationSide == osLocal ? Bookmark->Local : Bookmark->Remote;
+  return Bookmark->GetSideDirectory(OperationSide);
 }
 //---------------------------------------------------------------------------
 UnicodeString __fastcall TOpenDirectoryDialog::BookmarkText(TBookmark * Bookmark)

+ 14 - 3
source/forms/ScpCommander.cpp

@@ -20,6 +20,7 @@
 #include "Tools.h"
 #include "WinConfiguration.h"
 #include "TerminalManager.h"
+#include "Bookmarks.h"
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 #pragma link "CustomDirView"
@@ -1406,17 +1407,17 @@ void __fastcall TScpCommanderForm::DoOpenBookmark(UnicodeString Local, UnicodeSt
   }
 }
 //---------------------------------------------------------------------------
-bool __fastcall TScpCommanderForm::OpenBookmark(UnicodeString Local, UnicodeString Remote)
+bool __fastcall TScpCommanderForm::OpenBookmark(TOperationSide Side, TBookmark * Bookmark)
 {
   bool Result;
   if (WinConfiguration->UseLocationProfiles)
   {
-    DoOpenBookmark(Local, Remote);
+    DoOpenBookmark(Bookmark->Local, Bookmark->Remote);
     Result = true;
   }
   else
   {
-    Result = TCustomScpExplorerForm::OpenBookmark(Local, Remote);
+    Result = TCustomScpExplorerForm::OpenBookmark(Side, Bookmark);
   }
   return Result;
 }
@@ -2217,3 +2218,13 @@ void __fastcall TScpCommanderForm::LocalPathLabelMaskClick(TObject * /*Sender*/)
   Filter(osLocal);
 }
 //---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::LocalOpenDirButtonPopup(TTBCustomItem * /*Sender*/, bool /*FromLink*/)
+{
+  CreateOpenDirMenu(LocalOpenDirButton, osLocal);
+}
+//---------------------------------------------------------------------------
+void __fastcall TScpCommanderForm::RemoteOpenDirButtonPopup(TTBCustomItem * /*Sender*/, bool /*FromLink*/)
+{
+  CreateOpenDirMenu(RemoteOpenDirButton, osRemote);
+}
+//---------------------------------------------------------------------------

+ 6 - 2
source/forms/ScpCommander.dfm

@@ -1195,8 +1195,10 @@ inherited ScpCommanderForm: TScpCommanderForm
           OnMeasureWidth = RemotePathComboBoxMeasureWidth
           OnCancel = RemotePathComboBoxCancel
         end
-        object TBXItem169: TTBXItem
+        object RemoteOpenDirButton: TTBXSubmenuItem
           Action = NonVisualDataModule.RemoteOpenDirAction
+          DropdownCombo = True
+          OnPopup = RemoteOpenDirButtonPopup
         end
         object TBXItem229: TTBXItem
           Action = NonVisualDataModule.RemoteFilterAction
@@ -1525,8 +1527,10 @@ inherited ScpCommanderForm: TScpCommanderForm
           OnItemClick = LocalPathComboBoxItemClick
           OnCancel = LocalPathComboBoxCancel
         end
-        object TBXItem163: TTBXItem
+        object LocalOpenDirButton: TTBXSubmenuItem
           Action = NonVisualDataModule.LocalOpenDirAction
+          DropdownCombo = True
+          OnPopup = LocalOpenDirButtonPopup
         end
         object TBXItem228: TTBXItem
           Action = NonVisualDataModule.LocalFilterAction

+ 5 - 3
source/forms/ScpCommander.h

@@ -338,8 +338,8 @@ __published:
   TTBXToolbar *CommandLineToolbar;
   TTBXComboBoxItem *CommandLineCombo;
   TTBXLabelItem *CommandLinePromptLabel;
-  TTBXItem *TBXItem163;
-  TTBXItem *TBXItem169;
+  TTBXSubmenuItem *LocalOpenDirButton;
+  TTBXSubmenuItem *RemoteOpenDirButton;
   TTBXComboBoxItem *QueueSpeedComboBoxItem;
   TTBXItem *TBXItem220;
   TTBXItem *TBXItem221;
@@ -483,6 +483,8 @@ __published:
   void __fastcall RemoteStatusBarPanelClick(TTBXCustomStatusBar *Sender, TTBXStatusPanel *Panel);
   void __fastcall RemotePathLabelMaskClick(TObject *Sender);
   void __fastcall LocalPathLabelMaskClick(TObject *Sender);
+  void __fastcall LocalOpenDirButtonPopup(TTBCustomItem *Sender, bool FromLink);
+  void __fastcall RemoteOpenDirButtonPopup(TTBCustomItem *Sender, bool FromLink);
 
 private:
   bool FConstructed;
@@ -570,7 +572,7 @@ protected:
   void __fastcall LocalPathComboUpdate();
   virtual void __fastcall ToolbarItemResize(TTBXCustomDropDownItem * Item, int Width);
   void __fastcall DoOpenBookmark(UnicodeString Local, UnicodeString Remote);
-  virtual bool __fastcall OpenBookmark(UnicodeString Local, UnicodeString Remote);
+  virtual bool __fastcall OpenBookmark(TOperationSide Side, TBookmark * Bookmark);
   virtual void __fastcall DoFocusRemotePath(TTerminal * Terminal, const UnicodeString & Path);
   UnicodeString __fastcall ChangeFilePath(UnicodeString Path, TOperationSide Side);
   virtual bool __fastcall EligibleForImageDisplayMode(TTBCustomItem * Item);

+ 1 - 0
source/resource/TextsWin.h

@@ -287,6 +287,7 @@
 #define OPEN_TARGET_FOLDER      1577
 #define OPEN_DOWNLOADED_FILE    1578
 #define ENCRYPT_KEY_GENERATED   1579
+#define LOCATION_PROFILE_HINT   1580
 
 #define WIN_FORMS_STRINGS       1600
 #define COPY_FILE               1605

+ 1 - 0
source/resource/TextsWin1.rc

@@ -290,6 +290,7 @@ BEGIN
         OPEN_TARGET_FOLDER, "Open &Target Folder"
         OPEN_DOWNLOADED_FILE, "Open &Downloaded File"
         ENCRYPT_KEY_GENERATED, "**Encryption key was generated.**\n\nYou should safely backup the generated encryption key. If you lose it, you won't be able to read your files."
+        LOCATION_PROFILE_HINT, "Open location profile \"%s\".|Local directory:\n  %s|Remote directory:\n  %s"
 
         WIN_FORMS_STRINGS, "WIN_FORMS_STRINGS"
         COPY_FILE, "%s file '%s' to %s:"