TextSearch: Add keyboard navigation to history

Move back and forth in the search history with CursorUp/Down.

Entering a search text will reset the current history index
(fCurrentHistoryIndex = -1), and you'll be back to the first
history item next time you CursorUp.

Change-Id: Id45a47756b4732ae6e22e5373c4db5249c8df198
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9303
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Humdinger
2025-05-29 16:40:14 +00:00
committed by waddlesplash
parent 3b75482ee0
commit 67aa257da8
4 changed files with 108 additions and 1 deletions
+87
View File
@@ -17,6 +17,7 @@
#include <Alert.h>
#include <Clipboard.h>
#include <LayoutBuilder.h>
#include <MessageFilter.h>
#include <MessageRunner.h>
#include <MimeType.h>
#include <Path.h>
@@ -71,6 +72,48 @@ static const bigtime_t kChangesPulseInterval = 150000;
#endif // TRACE_FUNCTIONS
class HistoryInputFilter : public BMessageFilter {
public:
HistoryInputFilter(BHandler* target)
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_KEY_DOWN),
fTarget(target)
{
}
virtual filter_result Filter(BMessage* message, BHandler** _target)
{
const char* bytes;
int32 modifiers;
if (message->FindString("bytes", &bytes) != B_OK)
return B_DISPATCH_MESSAGE;
message->FindInt32("modifiers", &modifiers);
if (modifiers & (B_SHIFT_KEY | B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY))
return B_DISPATCH_MESSAGE;
switch (bytes[0]) {
case B_UP_ARROW:
{
fTarget.SendMessage(new BMessage(MSG_PREV_HISTORY));
return B_SKIP_MESSAGE;
} break;
case B_DOWN_ARROW:
{
fTarget.SendMessage(new BMessage(MSG_NEXT_HISTORY));
return B_SKIP_MESSAGE;
} break;
default:
return B_DISPATCH_MESSAGE;
}
}
private:
BMessenger fTarget;
};
GrepWindow::GrepWindow(BMessage* message)
: BWindow(BRect(0, 0, 525, 430), NULL, B_DOCUMENT_WINDOW,
B_AUTO_UPDATE_SIZE_LIMITS),
@@ -115,6 +158,7 @@ GrepWindow::GrepWindow(BMessage* message)
fChangesIterator(NULL),
fChangesPulse(NULL),
fCurrentHistoryIndex(-1),
fFilePanel(NULL)
{
if (fModel == NULL)
@@ -233,6 +277,7 @@ void GrepWindow::MessageReceived(BMessage* message)
break;
case MSG_SEARCH_TEXT:
fCurrentHistoryIndex = -1; // reset on user input
_OnSearchText();
break;
@@ -244,6 +289,46 @@ void GrepWindow::MessageReceived(BMessage* message)
_OnHistoryItem(message);
break;
case MSG_PREV_HISTORY:
{
if (fCurrentHistoryIndex == HISTORY_LIMIT - 1)
break;
fCurrentHistoryIndex++;
BString text = fModel->GetHistoryItem(fCurrentHistoryIndex);
if (text != NULL) {
fSearchText->SetModificationMessage(NULL);
fSearchText->SetText(text);
fSearchText->SetModificationMessage(new BMessage(MSG_SEARCH_TEXT));
} else
fCurrentHistoryIndex--;
_OnSearchText();
break;
}
case MSG_NEXT_HISTORY:
{
if (fCurrentHistoryIndex <= 0) {
fCurrentHistoryIndex = -1;
fSearchText->SetText("");
_OnSearchText();
break;
}
fCurrentHistoryIndex--;
BString text = fModel->GetHistoryItem(fCurrentHistoryIndex);
if (text != NULL) {
fSearchText->SetModificationMessage(NULL);
fSearchText->SetText(text);
fSearchText->SetModificationMessage(new BMessage(MSG_SEARCH_TEXT));
} else {
fCurrentHistoryIndex--;
fSearchText->SetText("");
}
_OnSearchText();
break;
}
case MSG_START_CANCEL:
_OnStartCancel();
break;
@@ -549,6 +634,7 @@ GrepWindow::_CreateViews()
"SearchText", NULL, NULL, NULL,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_NAVIGABLE);
fSearchText->TextView()->AddFilter(new HistoryInputFilter(this));
fSearchText->TextView()->SetMaxBytes(1000);
fSearchText->SetModificationMessage(new BMessage(MSG_SEARCH_TEXT));
@@ -754,6 +840,7 @@ GrepWindow::_OnStartCancel()
fSearchText->SetModificationMessage(NULL);
fGlobText->SetModificationMessage(NULL);
fCurrentHistoryIndex = -1;
fFileMenu->SetEnabled(false);
fActionMenu->SetEnabled(false);
+1 -1
View File
@@ -129,7 +129,7 @@ private:
ChangesIterator* fChangesIterator;
BMessageRunner* fChangesPulse;
int32 fCurrentHistoryIndex;
BFilePanel* fFilePanel;
};
+17
View File
@@ -225,6 +225,23 @@ Model::FillHistoryMenu(BMenu* menu) const
}
BString
Model::GetHistoryItem(int32 index)
{
BList items;
if (!_LoadHistory(items))
return NULL;
int32 itemCount = items.CountItems() - 1;
if (index > itemCount)
return NULL;
// latest entry is at the end of the BList
BString* itemtext = static_cast<BString*>(items.ItemAt(itemCount - index));
return itemtext->String();
}
// #pragma mark - private
+3
View File
@@ -31,6 +31,8 @@ enum {
MSG_SEARCH_GLOB_FILTER,
MSG_INVOKE_ITEM,
MSG_SELECT_HISTORY,
MSG_PREV_HISTORY,
MSG_NEXT_HISTORY,
MSG_NODE_MONITOR_PULSE,
MSG_START_NODE_MONITORING,
@@ -69,6 +71,7 @@ public:
void AddToHistory(const char* text);
void FillHistoryMenu(BMenu* menu) const;
BString GetHistoryItem(int32 index);
public:
// The directory we were invoked from.