Browse Source

Incremental search panel pops up on Ctrl+F to make the function easier to find (part of Bug 2281)

https://winscp.net/tracker/2281

Source commit: 1584b79e350aff206a19e95bd1f4debd1c0744ed
Martin Prikryl 1 year ago
parent
commit
8dbc8efb82

+ 29 - 16
source/forms/CustomScpExplorer.cpp

@@ -24,7 +24,6 @@
 #include <DragExt.h>
 #include <WinApi.h>
 
-#include "GUITools.h"
 #include "NonVisual.h"
 #include "Glyphs.h"
 #include "Tools.h"
@@ -38,6 +37,7 @@
 #include <TB2Common.hpp>
 #include <DirectoryMonitor.hpp>
 #include <System.IOUtils.hpp>
+#include <System.StrUtils.hpp>
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 #pragma link "CustomDirView"
@@ -211,7 +211,6 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
   FNeedSession = false;
   FDoNotIdleCurrentTerminal = 0;
   FIncrementalSearching = 0;
-  FIncrementalSearchHaveNext = false;
   FQueueFileList.reset(new TQueueFileList());
   FProgressSide = osCurrent;
   FCalculateSizeOperation = NULL;
@@ -9177,9 +9176,9 @@ UnicodeString __fastcall TCustomScpExplorerForm::FileStatusBarText(
 {
   UnicodeString Result;
 
-  if (!FIncrementalSearch.IsEmpty() && (Side == GetSide(osCurrent)))
+  if (FIncrementalSearchState.Searching && (Side == GetSide(osCurrent)))
   {
-    Result = FormatIncrementalSearchStatus(FIncrementalSearch, FIncrementalSearchHaveNext);
+    Result = FormatIncrementalSearchStatus(FIncrementalSearchState);
   }
   else if (!IsSideLocalBrowser(Side) && ((Terminal == NULL) || Terminal->Disconnected))
   {
@@ -11543,15 +11542,15 @@ void __fastcall TCustomScpExplorerForm::DirViewKeyDown(TObject * Sender, WORD &
     // while searching
     if (Key == VK_BACK)
     {
-      if (!FIncrementalSearch.IsEmpty())
+      if (FIncrementalSearchState.Searching)
       {
-        if (FIncrementalSearch.Length() == 1)
+        if (FIncrementalSearchState.Text.Length() <= 1)
         {
           ResetIncrementalSearch();
         }
         else
         {
-          UnicodeString NewText = FIncrementalSearch.SubString(1, FIncrementalSearch.Length() - 1);
+          UnicodeString NewText = LeftStr(FIncrementalSearchState.Text, FIncrementalSearchState.Text.Length() - 1);
           IncrementalSearch(NewText, false, false);
         }
         Key = 0;
@@ -11569,9 +11568,9 @@ void __fastcall TCustomScpExplorerForm::DirViewKeyPress(TObject * Sender, wchar_
     // When not searching yet, prefer use of the space for toggling file selection
     // (so we cannot incrementally search for a string starting with a space).
     if ((Key > VK_SPACE) ||
-        ((Key == VK_SPACE) && (GetKeyState(VK_CONTROL) >= 0) && !FIncrementalSearch.IsEmpty()))
+        ((Key == VK_SPACE) && (GetKeyState(VK_CONTROL) >= 0) && !FIncrementalSearchState.Searching))
     {
-      IncrementalSearch(FIncrementalSearch + Key, false, false);
+      IncrementalSearch(FIncrementalSearchState.Text + Key, false, false);
       Key = 0;
     }
   }
@@ -11579,9 +11578,9 @@ void __fastcall TCustomScpExplorerForm::DirViewKeyPress(TObject * Sender, wchar_
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::ResetIncrementalSearch()
 {
-  if (!FIncrementalSearch.IsEmpty())
+  if (FIncrementalSearchState.Searching)
   {
-    FIncrementalSearch = L"";
+    FIncrementalSearchState.Reset();
     DirView(osCurrent)->UpdateStatusBar();
   }
 }
@@ -11610,11 +11609,12 @@ void __fastcall TCustomScpExplorerForm::IncrementalSearch(const UnicodeString &
         }
       }
     }
-    FIncrementalSearch = Text;
+    FIncrementalSearchState.Searching = true;
+    FIncrementalSearchState.Text = Text;
     Item->MakeVisible(false);
 
     TListItem * NextItem = SearchFile(Text, true, Reverse);
-    FIncrementalSearchHaveNext = (NextItem != NULL) && (NextItem != Item);
+    FIncrementalSearchState.HaveNext = (NextItem != NULL) && (NextItem != Item);
 
     ADirView->UpdateStatusBar();
   }
@@ -11709,18 +11709,18 @@ void __fastcall TCustomScpExplorerForm::CMDialogKey(TWMKeyDown & Message)
 {
   if (Message.CharCode == VK_TAB)
   {
-    if (!FIncrementalSearch.IsEmpty())
+    if (!FIncrementalSearchState.Text.IsEmpty())
     {
       TShiftState Shift = KeyDataToShiftState(Message.KeyData);
       bool Reverse = Shift.Contains(ssShift);
-      IncrementalSearch(FIncrementalSearch, true, Reverse);
+      IncrementalSearch(FIncrementalSearchState.Text, true, Reverse);
       Message.Result = 1;
       return;
     }
   }
   else if (Message.CharCode == VK_ESCAPE)
   {
-    if (!FIncrementalSearch.IsEmpty())
+    if (FIncrementalSearchState.Searching)
     {
       ResetIncrementalSearch();
       Message.Result = 1;
@@ -12110,3 +12110,16 @@ void TCustomScpExplorerForm::RestoreFocus(void * Focus)
   DebugUsedParam(Focus);
   DebugAssert(Focus == NULL);
 }
+//---------------------------------------------------------------------------
+void TCustomScpExplorerForm::IncrementalSearchStart()
+{
+  TCustomDirView * ADirView = DirView(osCurrent);
+  ADirView->SetFocus();
+  if (!FIncrementalSearchState.Searching)
+  {
+    FIncrementalSearchState.Searching = true;
+    FIncrementalSearchState.HaveNext = false;
+    DebugAssert(FIncrementalSearchState.Text.IsEmpty());
+    ADirView->UpdateStatusBar();
+  }
+}

+ 3 - 2
source/forms/CustomScpExplorer.h

@@ -33,6 +33,7 @@
 #include "ThemePageControl.h"
 #include "PathLabel.hpp"
 #include <Vcl.AppEvnts.hpp>
+#include <GUITools.h>
 //---------------------------------------------------------------------------
 class TProgressForm;
 class TSynchronizeProgressForm;
@@ -403,9 +404,8 @@ protected:
   int FDoNotIdleCurrentTerminal;
   UnicodeString FFakeFileDropTarget;
   TFileColorData::TList FFileColors;
-  UnicodeString FIncrementalSearch;
+  TIncrementalSearchState FIncrementalSearchState;
   int FIncrementalSearching;
-  bool FIncrementalSearchHaveNext;
   TOperationSide FProgressSide;
   bool FImmersiveDarkMode;
 
@@ -919,6 +919,7 @@ public:
   void AutoSizeColumns(TOperationSide Side);
   virtual void ResetLayoutColumns(TOperationSide Side) = 0;
   void QueueResetLayoutColumns();
+  void IncrementalSearchStart();
   virtual void * SaveFocus();
   virtual void RestoreFocus(void * Focus);
 

+ 32 - 17
source/forms/Login.cpp

@@ -67,7 +67,6 @@ __fastcall TLoginDialog::TLoginDialog(TComponent* AOwner)
   FDataList = NULL;
   FUpdatePortWithProtocol = true;
   FIncrementalSearching = 0;
-  FSitesIncrementalSearchHaveNext = false;
   FEditing = false;
   FRenaming = false;
   FNewSiteKeepName = false;
@@ -729,9 +728,9 @@ void __fastcall TLoginDialog::UpdateControls()
     EnableControl(S3ProfileCombo, S3CredentialsEnv);
 
     // sites
-    if (SitesIncrementalSearchLabel->Visible != !FSitesIncrementalSearch.IsEmpty())
+    if (SitesIncrementalSearchLabel->Visible != FIncrementalSearchState.Searching)
     {
-      if (FSitesIncrementalSearch.IsEmpty())
+      if (!FIncrementalSearchState.Searching)
       {
         SitesIncrementalSearchLabel->Visible = false;
         SessionTree->Height = SitesIncrementalSearchLabel->BoundsRect.Bottom - SessionTree->Top;
@@ -743,9 +742,9 @@ void __fastcall TLoginDialog::UpdateControls()
       }
     }
 
-    if (!FSitesIncrementalSearch.IsEmpty())
+    if (FIncrementalSearchState.Searching)
     {
-      SitesIncrementalSearchLabel->Caption = FormatIncrementalSearchStatus(FSitesIncrementalSearch, FSitesIncrementalSearchHaveNext);
+      SitesIncrementalSearchLabel->Caption = FormatIncrementalSearchStatus(FIncrementalSearchState);
     }
 
     EnableControl(ManageButton, !FEditing);
@@ -929,11 +928,11 @@ void __fastcall TLoginDialog::SessionTreeKeyPress(TObject * /*Sender*/, System::
     // filter control sequences
     if (Key >= VK_SPACE)
     {
-      if (FSitesIncrementalSearch.IsEmpty())
+      if (!FIncrementalSearchState.Searching)
       {
         Configuration->Usage->Inc(L"SiteIncrementalSearches");
       }
-      if (!SitesIncrementalSearch(FSitesIncrementalSearch + Key, false, false, false))
+      if (!SitesIncrementalSearch(FIncrementalSearchState.Text + Key, false, false, false))
       {
         MessageBeep(MB_ICONHAND);
       }
@@ -941,16 +940,15 @@ void __fastcall TLoginDialog::SessionTreeKeyPress(TObject * /*Sender*/, System::
     }
     else if (Key == VK_BACK)
     {
-      if (!FSitesIncrementalSearch.IsEmpty())
+      if (FIncrementalSearchState.Searching)
       {
-        if (FSitesIncrementalSearch.Length() == 1)
+        if (FIncrementalSearchState.Text.Length() <= 1)
         {
           ResetSitesIncrementalSearch();
         }
         else
         {
-          UnicodeString NewText =
-            FSitesIncrementalSearch.SubString(1, FSitesIncrementalSearch.Length() - 1);
+          UnicodeString NewText = LeftStr(FIncrementalSearchState.Text, FIncrementalSearchState.Text.Length() - 1);
           SitesIncrementalSearch(NewText, false, false, false);
         }
         Key = 0;
@@ -1326,6 +1324,10 @@ void __fastcall TLoginDialog::ActionListUpdate(TBasicAction * BasicAction,
     // without hostname it's pointless
     Action->Enabled = (Data != NULL) && !Data->HostNameExpanded.IsEmpty();
   }
+  else if (Action == SearchSiteStartAction)
+  {
+    Action->Enabled = !SessionTree->IsEditing() && !FEditing;
+  }
   else if (Action == SearchSiteNameStartOnlyAction)
   {
     Action->Checked = (FSiteSearch == isNameStartOnly);
@@ -1682,11 +1684,11 @@ void __fastcall TLoginDialog::CMDialogKey(TWMKeyDown & Message)
 {
   if (Message.CharCode == VK_TAB)
   {
-    if (!FSitesIncrementalSearch.IsEmpty())
+    if (!FIncrementalSearchState.Text.IsEmpty())
     {
       TShiftState Shift = KeyDataToShiftState(Message.KeyData);
       bool Reverse = Shift.Contains(ssShift);
-      if (!SitesIncrementalSearch(FSitesIncrementalSearch, true, Reverse, true))
+      if (!SitesIncrementalSearch(FIncrementalSearchState.Text, true, Reverse, true))
       {
         MessageBeep(MB_ICONHAND);
       }
@@ -1696,7 +1698,7 @@ void __fastcall TLoginDialog::CMDialogKey(TWMKeyDown & Message)
   }
   else if (Message.CharCode == VK_ESCAPE)
   {
-    if (!FSitesIncrementalSearch.IsEmpty())
+    if (FIncrementalSearchState.Searching)
     {
       ResetSitesIncrementalSearch();
       Message.Result = 1;
@@ -2786,7 +2788,7 @@ void __fastcall TLoginDialog::ImportActionExecute(TObject * /*Sender*/)
 //---------------------------------------------------------------------------
 void __fastcall TLoginDialog::ResetSitesIncrementalSearch()
 {
-  FSitesIncrementalSearch = L"";
+  FIncrementalSearchState.Reset();
   // this is to prevent active tree node being set back to Sites tab
   // (from UpdateNavigationTree) when we are called from SessionTreeExit,
   // while tab is changing
@@ -2825,11 +2827,12 @@ bool __fastcall TLoginDialog::SitesIncrementalSearch(
       TAutoNestingCounter Guard(FIncrementalSearching);
       SessionTree->Selected = Node;
     }
-    FSitesIncrementalSearch = Text;
+    FIncrementalSearchState.Searching = true;
+    FIncrementalSearchState.Text = Text;
 
     // Tab always searches even in collapsed nodes
     TTreeNode * NextNode = SearchSite(Text, true, true, Reverse);
-    FSitesIncrementalSearchHaveNext =
+    FIncrementalSearchState.HaveNext =
       (NextNode != NULL) && (NextNode != Node);
 
     UpdateControls();
@@ -3380,3 +3383,15 @@ void __fastcall TLoginDialog::ShowAgainCheckClick(TObject *)
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TLoginDialog::SearchSiteStartActionExecute(TObject *)
+{
+  SessionTree->SetFocus();
+  if (!FIncrementalSearchState.Searching)
+  {
+    FIncrementalSearchState.Searching = true;
+    FIncrementalSearchState.HaveNext = false;
+    DebugAssert(FIncrementalSearchState.Text.IsEmpty());
+    UpdateControls();
+  }
+}
+//---------------------------------------------------------------------------

+ 37 - 16
source/forms/Login.dfm

@@ -720,6 +720,15 @@ object LoginDialog: TLoginDialog
       Caption = 'Edit &Raw Settings...'
       OnExecute = SessionAdvancedActionExecute
     end
+    object SearchSiteStartAction: TAction
+      Category = 'Other'
+      Caption = '&Find Site'
+      SecondaryShortCuts.Strings = (
+        'Alt+F7'
+        'F3')
+      ShortCut = 16454
+      OnExecute = SearchSiteStartActionExecute
+    end
   end
   object ToolsPopupMenu: TPopupMenu
     Left = 152
@@ -1265,13 +1274,16 @@ object LoginDialog: TLoginDialog
     object ExplorersSendToShortcut2: TMenuItem
       Action = SendToHookAction
     end
-    object Options1: TMenuItem
-      Caption = 'Options'
+    object Search1: TMenuItem
+      Caption = 'Search'
       Enabled = False
       Visible = False
     end
-    object IncrementalSearch1: TMenuItem
-      Caption = 'Incremental Search'
+    object FindSite1: TMenuItem
+      Action = SearchSiteStartAction
+    end
+    object SearchOptions1: TMenuItem
+      Caption = 'Options'
       object SearchSiteNameStartOnly1: TMenuItem
         Action = SearchSiteNameStartOnlyAction
         RadioItem = True
@@ -1325,13 +1337,16 @@ object LoginDialog: TLoginDialog
     object MenuItem8: TMenuItem
       Action = DesktopIconAction
     end
-    object Options3: TMenuItem
-      Caption = 'Options'
+    object Search3: TMenuItem
+      Caption = 'Search'
       Enabled = False
       Visible = False
     end
-    object IncrementalSearch3: TMenuItem
-      Caption = 'Incremental Search'
+    object FindSite3: TMenuItem
+      Action = SearchSiteStartAction
+    end
+    object SearchOptions3: TMenuItem
+      Caption = 'Options'
       object BeginningofSiteNameOnly2: TMenuItem
         Action = SearchSiteNameStartOnlyAction
         RadioItem = True
@@ -1389,13 +1404,16 @@ object LoginDialog: TLoginDialog
     object MenuItem17: TMenuItem
       Action = NewSessionFolderAction
     end
-    object Options2: TMenuItem
-      Caption = 'Options'
+    object Search2: TMenuItem
+      Caption = 'Search'
       Enabled = False
       Visible = False
     end
-    object IncrementalSearch2: TMenuItem
-      Caption = 'Incremental Search'
+    object FindSite2: TMenuItem
+      Action = SearchSiteStartAction
+    end
+    object SearchOptions2: TMenuItem
+      Caption = 'Options'
       object BeginningofSiteNameOnly1: TMenuItem
         Action = SearchSiteNameStartOnlyAction
         RadioItem = True
@@ -1440,13 +1458,16 @@ object LoginDialog: TLoginDialog
     object MenuItem19: TMenuItem
       Action = DesktopIconAction
     end
-    object Options4: TMenuItem
-      Caption = 'Options'
+    object Search4: TMenuItem
+      Caption = 'Search'
       Enabled = False
       Visible = False
     end
-    object IncrementalSearch4: TMenuItem
-      Caption = 'Incremental Search'
+    object FindSite4: TMenuItem
+      Action = SearchSiteStartAction
+    end
+    object SearchOptions4: TMenuItem
+      Caption = 'Options'
       object BeginningofSiteNameOnly3: TMenuItem
         Action = SearchSiteNameStartOnlyAction
         RadioItem = True

+ 18 - 13
source/forms/Login.h

@@ -181,26 +181,31 @@ __published:
   TAction *SearchSiteNameStartOnlyAction;
   TAction *SearchSiteNameAction;
   TAction *SearchSiteAction;
-  TMenuItem *Options1;
-  TMenuItem *IncrementalSearch1;
+  TMenuItem *Search1;
+  TMenuItem *SearchOptions1;
   TMenuItem *SearchSiteNameStartOnly1;
   TMenuItem *SearchSiteName1;
   TMenuItem *SearchSite1;
-  TMenuItem *Options2;
-  TMenuItem *IncrementalSearch2;
-  TMenuItem *AllMajorSiteFields1;
-  TMenuItem *AnyPartofSiteName1;
-  TMenuItem *BeginningofSiteNameOnly1;
-  TMenuItem *Options3;
-  TMenuItem *IncrementalSearch3;
+  TAction *SearchSiteStartAction;
+  TMenuItem *FindSite1;
+  TMenuItem *Search3;
+  TMenuItem *FindSite3;
+  TMenuItem *SearchOptions3;
   TMenuItem *AllMajorSiteFields2;
   TMenuItem *AnyPartofSiteName2;
   TMenuItem *BeginningofSiteNameOnly2;
-  TMenuItem *Options4;
-  TMenuItem *IncrementalSearch4;
+  TMenuItem *Search4;
+  TMenuItem *FindSite4;
+  TMenuItem *SearchOptions4;
   TMenuItem *AllMajorSiteFields3;
   TMenuItem *AnyPartofSiteName3;
   TMenuItem *BeginningofSiteNameOnly3;
+  TMenuItem *Search2;
+  TMenuItem *FindSite2;
+  TMenuItem *SearchOptions2;
+  TMenuItem *AllMajorSiteFields1;
+  TMenuItem *AnyPartofSiteName1;
+  TMenuItem *BeginningofSiteNameOnly1;
   TPngImageList *SessionImageList144;
   TPngImageList *SessionImageList192;
   TPngImageList *ActionImageList144;
@@ -294,6 +299,7 @@ __published:
   void __fastcall EncryptionComboChange(TObject *Sender);
   void __fastcall S3ProfileComboChange(TObject *Sender);
   void __fastcall ShowAgainCheckClick(TObject *Sender);
+  void __fastcall SearchSiteStartActionExecute(TObject *Sender);
 
 private:
   int NoUpdate;
@@ -307,9 +313,8 @@ private:
   int FDefaultPort;
   TList * FDataList;
   bool FUpdatePortWithProtocol;
-  UnicodeString FSitesIncrementalSearch;
+  TIncrementalSearchState FIncrementalSearchState;
   int FIncrementalSearching;
-  bool FSitesIncrementalSearchHaveNext;
   int FBasicGroupBaseHeight;
   int FNoteGroupOffset;
   bool FEditing;

+ 2 - 0
source/forms/NonVisual.cpp

@@ -445,6 +445,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   UPD(EditorListCustomizeAction, true)
   UPD(ChangePasswordAction, ScpExplorer->CanChangePassword())
   UPD(PrivateKeyUploadAction, ScpExplorer->CanPrivateKeyUpload())
+  UPD(IncrementalSearchStartAction, true);
 
   // CUSTOM COMMANDS
   UPD(CustomCommandsFileAction, true)
@@ -792,6 +793,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsExecute(
     EXE(EditorListCustomizeAction, PreferencesDialog(pmEditor))
     EXE(ChangePasswordAction, ScpExplorer->ChangePassword())
     EXE(PrivateKeyUploadAction, ScpExplorer->PrivateKeyUpload())
+    EXE(IncrementalSearchStartAction, ScpExplorer->IncrementalSearchStart())
 
     // CUSTOM COMMANDS
     EXE(CustomCommandsFileAction, CreateCustomCommandsMenu(CustomCommandsFileAction, ccltFile))

+ 6 - 0
source/forms/NonVisual.dfm

@@ -2459,6 +2459,12 @@ object NonVisualDataModule: TNonVisualDataModule
       Hint = 'Open the same directory as in the other panel'
       ShortCut = 16574
     end
+    object IncrementalSearchStartAction: TAction
+      Tag = 11
+      Category = 'Command'
+      Caption = 'IncrementalSearchStartAction'
+      ShortCut = 16454
+    end
   end
   object ExplorerBarPopup: TTBXPopupMenu
     Images = GlyphsModule.ExplorerImages

+ 1 - 0
source/forms/NonVisual.h

@@ -710,6 +710,7 @@ __published:    // IDE-managed Components
   TAction *QueueResetLayoutColumnsAction;
   TTBXSeparatorItem *TBXSeparatorItem23;
   TTBXItem *TBXItem116;
+  TAction *IncrementalSearchStartAction;
   void __fastcall ExplorerActionsUpdate(TBasicAction *Action, bool &Handled);
   void __fastcall ExplorerActionsExecute(TBasicAction *Action, bool &Handled);
   void __fastcall SessionIdleTimerTimer(TObject *Sender);

+ 1 - 0
source/resource/TextsWin.h

@@ -692,6 +692,7 @@
 #define SSH_HOST_CA_HOSTS_INVALID 6205
 #define LOGIN_NOT_SHOWING_AGAIN 6206
 #define IMPORT_INI_TITLE        6207
+#define INC_SEARCH_TYPE         6208
 
 // 2xxx is reserved for TextsFileZilla.h
 

+ 1 - 0
source/resource/TextsWin1.rc

@@ -697,6 +697,7 @@ BEGIN
         SSH_HOST_CA_HOSTS_INVALID, "Error in validity expression."
         LOGIN_NOT_SHOWING_AGAIN, "**Stop showing Login dialog automatically?** Please confirm if you really want to WinSCP stop showing Login dialog automatically on startup and when the last session is closed.\n\nIf you change your mind later, you can revert this in Preferences on Environment > Window page.\n\nTo open the Login dialog manually, go to Tabs > New Tab [> Remote Tab] or use corresponding toolbar button."
         IMPORT_INI_TITLE, "Select file to import sites from"
+        INC_SEARCH_TYPE, "(start typing)"
 
         WIN_VARIABLE_STRINGS, "WIN_VARIABLE"
         WINSCP_COPYRIGHT, "Copyright © 2000–2024 Martin Prikryl"

+ 15 - 3
source/windows/GUITools.cpp

@@ -1285,11 +1285,23 @@ void __fastcall HideComponentsPanel(TForm * Form)
   }
 }
 //---------------------------------------------------------------------------
-UnicodeString FormatIncrementalSearchStatus(const UnicodeString & Text, bool HaveNext)
+TIncrementalSearchState::TIncrementalSearchState()
+{
+  Reset();
+}
+//---------------------------------------------------------------------------
+void TIncrementalSearchState::Reset()
+{
+  Searching = false;
+  Text = EmptyStr;
+  HaveNext = false;
+}
+//---------------------------------------------------------------------------
+UnicodeString FormatIncrementalSearchStatus(const TIncrementalSearchState & SearchState)
 {
   UnicodeString Result =
-    L" " + FMTLOAD(INC_SEARCH, (Text)) +
-    (HaveNext ? L" " + LoadStr(INC_NEXT_SEARCH) : UnicodeString());
+    L" " + FMTLOAD(INC_SEARCH, (DefaultStr(SearchState.Text, LoadStr(INC_SEARCH_TYPE)))) +
+    ((SearchState.HaveNext && DebugAlwaysTrue(!SearchState.Text.IsEmpty())) ? L" " + LoadStr(INC_NEXT_SEARCH) : EmptyStr);
   return Result;
 }
 //---------------------------------------------------------------------------

+ 10 - 1
source/windows/GUITools.h

@@ -44,7 +44,16 @@ void __fastcall LoadDialogImage(TImage * Image, const UnicodeString & ImageName)
 int __fastcall DialogImageSize(TForm * Form);
 int __fastcall NormalizePixelsPerInch(int PixelsPerInch);
 void __fastcall HideComponentsPanel(TForm * Form);
-UnicodeString FormatIncrementalSearchStatus(const UnicodeString & Text, bool HaveNext);
+struct TIncrementalSearchState
+{
+  TIncrementalSearchState();
+  void Reset();
+
+  bool Searching;
+  UnicodeString Text;
+  bool HaveNext;
+};
+UnicodeString FormatIncrementalSearchStatus(const TIncrementalSearchState & SearchState);
 namespace Webbrowserex
 {
   class TWebBrowserEx;