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:
@@ -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);
|
||||
|
||||
@@ -129,7 +129,7 @@ private:
|
||||
ChangesIterator* fChangesIterator;
|
||||
BMessageRunner* fChangesPulse;
|
||||
|
||||
|
||||
int32 fCurrentHistoryIndex;
|
||||
BFilePanel* fFilePanel;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user