2012-11-10 00:31:37 +00:00
|
|
|
/*
|
|
|
|
htop - IncSet.c
|
|
|
|
(C) 2005-2012 Hisham H. Muhammad
|
|
|
|
Released under the GNU GPL, see the COPYING file
|
|
|
|
in the source distribution for its full text.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "IncSet.h"
|
2015-08-19 16:43:20 +00:00
|
|
|
#include "StringUtils.h"
|
2012-11-10 00:31:37 +00:00
|
|
|
#include "ListItem.h"
|
|
|
|
#include "CRT.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
|
|
static void IncMode_reset(IncMode* mode) {
|
|
|
|
mode->index = 0;
|
|
|
|
mode->buffer[0] = 0;
|
|
|
|
}
|
|
|
|
|
2018-11-03 19:59:55 +00:00
|
|
|
void IncSet_reset(IncSet* this, IncType type) {
|
|
|
|
IncMode_reset(&this->modes[type]);
|
|
|
|
}
|
|
|
|
|
2017-07-23 02:41:19 +00:00
|
|
|
static const char* const searchFunctions[] = {"Next ", "Cancel ", " Search: ", NULL};
|
|
|
|
static const char* const searchKeys[] = {"F3", "Esc", " "};
|
2012-11-10 00:31:37 +00:00
|
|
|
static int searchEvents[] = {KEY_F(3), 27, ERR};
|
|
|
|
|
|
|
|
static inline void IncMode_initSearch(IncMode* search) {
|
|
|
|
memset(search, 0, sizeof(IncMode));
|
|
|
|
search->bar = FunctionBar_new(searchFunctions, searchKeys, searchEvents);
|
|
|
|
search->isFilter = false;
|
|
|
|
}
|
|
|
|
|
2017-07-23 02:41:19 +00:00
|
|
|
static const char* const filterFunctions[] = {"Done ", "Clear ", " Filter: ", NULL};
|
|
|
|
static const char* const filterKeys[] = {"Enter", "Esc", " "};
|
2012-11-10 00:31:37 +00:00
|
|
|
static int filterEvents[] = {13, 27, ERR};
|
|
|
|
|
|
|
|
static inline void IncMode_initFilter(IncMode* filter) {
|
|
|
|
memset(filter, 0, sizeof(IncMode));
|
|
|
|
filter->bar = FunctionBar_new(filterFunctions, filterKeys, filterEvents);
|
|
|
|
filter->isFilter = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void IncMode_done(IncMode* mode) {
|
2015-03-23 18:26:56 +00:00
|
|
|
FunctionBar_delete(mode->bar);
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
IncSet* IncSet_new(FunctionBar* bar) {
|
2016-02-02 14:53:02 +00:00
|
|
|
IncSet* this = xCalloc(1, sizeof(IncSet));
|
2012-11-10 00:31:37 +00:00
|
|
|
IncMode_initSearch(&(this->modes[INC_SEARCH]));
|
|
|
|
IncMode_initFilter(&(this->modes[INC_FILTER]));
|
|
|
|
this->active = NULL;
|
|
|
|
this->filtering = false;
|
|
|
|
this->defaultBar = bar;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IncSet_delete(IncSet* this) {
|
|
|
|
IncMode_done(&(this->modes[0]));
|
|
|
|
IncMode_done(&(this->modes[1]));
|
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void updateWeakPanel(IncSet* this, Panel* panel, Vector* lines) {
|
|
|
|
Object* selected = Panel_getSelected(panel);
|
|
|
|
Panel_prune(panel);
|
|
|
|
if (this->filtering) {
|
|
|
|
int n = 0;
|
|
|
|
const char* incFilter = this->modes[INC_FILTER].buffer;
|
|
|
|
for (int i = 0; i < Vector_size(lines); i++) {
|
|
|
|
ListItem* line = (ListItem*)Vector_get(lines, i);
|
|
|
|
if (String_contains_i(line->value, incFilter)) {
|
|
|
|
Panel_add(panel, (Object*)line);
|
|
|
|
if (selected == (Object*)line) Panel_setSelected(panel, n);
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int i = 0; i < Vector_size(lines); i++) {
|
|
|
|
Object* line = Vector_get(lines, i);
|
|
|
|
Panel_add(panel, line);
|
|
|
|
if (selected == line) Panel_setSelected(panel, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-05 13:30:06 +00:00
|
|
|
static bool search(IncMode* mode, Panel* panel, IncMode_GetPanelValue getPanelValue) {
|
2012-11-10 00:31:37 +00:00
|
|
|
int size = Panel_size(panel);
|
|
|
|
bool found = false;
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
|
|
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
|
|
|
|
Panel_setSelected(panel, i);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found)
|
|
|
|
FunctionBar_draw(mode->bar, mode->buffer);
|
|
|
|
else
|
|
|
|
FunctionBar_drawAttr(mode->bar, mode->buffer, CRT_colors[FAILED_SEARCH]);
|
2016-05-05 13:30:06 +00:00
|
|
|
return found;
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
|
|
|
|
2018-11-03 19:59:55 +00:00
|
|
|
static bool IncMode_find(IncMode* mode, Panel* panel, IncMode_GetPanelValue getPanelValue, int step) {
|
|
|
|
int size = Panel_size(panel);
|
|
|
|
int here = Panel_getSelectedIndex(panel);
|
|
|
|
int i = here;
|
|
|
|
for(;;) {
|
|
|
|
i+=step;
|
|
|
|
if (i == size) i = 0;
|
|
|
|
if (i == -1) i = size - 1;
|
|
|
|
if (i == here) return false;
|
|
|
|
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
|
|
|
|
Panel_setSelected(panel, i);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IncSet_next(IncSet* this, IncType type, Panel* panel, IncMode_GetPanelValue getPanelValue) {
|
|
|
|
return IncMode_find(&this->modes[type], panel, getPanelValue, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IncSet_prev(IncSet* this, IncType type, Panel* panel, IncMode_GetPanelValue getPanelValue) {
|
|
|
|
return IncMode_find(&this->modes[type], panel, getPanelValue, -1);
|
|
|
|
}
|
|
|
|
|
2012-11-10 00:31:37 +00:00
|
|
|
bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue getPanelValue, Vector* lines) {
|
|
|
|
if (ch == ERR)
|
|
|
|
return true;
|
|
|
|
IncMode* mode = this->active;
|
|
|
|
int size = Panel_size(panel);
|
2015-03-23 20:04:53 +00:00
|
|
|
bool filterChanged = false;
|
2012-11-10 00:31:37 +00:00
|
|
|
bool doSearch = true;
|
|
|
|
if (ch == KEY_F(3)) {
|
|
|
|
if (size == 0) return true;
|
2018-11-03 19:59:55 +00:00
|
|
|
IncMode_find(mode, panel, getPanelValue, 1);
|
2012-11-10 00:31:37 +00:00
|
|
|
doSearch = false;
|
2020-09-11 17:27:56 +00:00
|
|
|
} else if (0 < ch && ch < 255 && isprint((unsigned char)ch)) {
|
2016-05-05 13:30:06 +00:00
|
|
|
if (mode->index < INCMODE_MAX) {
|
|
|
|
mode->buffer[mode->index] = ch;
|
|
|
|
mode->index++;
|
|
|
|
mode->buffer[mode->index] = 0;
|
|
|
|
if (mode->isFilter) {
|
|
|
|
filterChanged = true;
|
|
|
|
if (mode->index == 1) this->filtering = true;
|
|
|
|
}
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
2016-05-05 13:30:06 +00:00
|
|
|
} else if ((ch == KEY_BACKSPACE || ch == 127)) {
|
|
|
|
if (mode->index > 0) {
|
|
|
|
mode->index--;
|
|
|
|
mode->buffer[mode->index] = 0;
|
|
|
|
if (mode->isFilter) {
|
|
|
|
filterChanged = true;
|
|
|
|
if (mode->index == 0) {
|
|
|
|
this->filtering = false;
|
|
|
|
IncMode_reset(mode);
|
|
|
|
}
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
2016-05-05 13:30:06 +00:00
|
|
|
} else {
|
|
|
|
doSearch = false;
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
2015-12-10 06:42:56 +00:00
|
|
|
} else if (ch == KEY_RESIZE) {
|
|
|
|
Panel_resize(panel, COLS, LINES-panel->y-1);
|
2012-11-10 00:31:37 +00:00
|
|
|
} else {
|
|
|
|
if (mode->isFilter) {
|
2015-03-23 20:04:53 +00:00
|
|
|
filterChanged = true;
|
2012-11-10 00:31:37 +00:00
|
|
|
if (ch == 27) {
|
|
|
|
this->filtering = false;
|
|
|
|
IncMode_reset(mode);
|
|
|
|
}
|
|
|
|
} else {
|
2018-11-03 19:59:55 +00:00
|
|
|
if (ch == 27) {
|
|
|
|
IncMode_reset(mode);
|
|
|
|
}
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
|
|
|
this->active = NULL;
|
2015-03-23 20:04:53 +00:00
|
|
|
Panel_setDefaultBar(panel);
|
2012-11-10 00:31:37 +00:00
|
|
|
FunctionBar_draw(this->defaultBar, NULL);
|
|
|
|
doSearch = false;
|
|
|
|
}
|
|
|
|
if (doSearch) {
|
2016-05-05 13:30:06 +00:00
|
|
|
this->found = search(mode, panel, getPanelValue);
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
2015-03-23 20:04:53 +00:00
|
|
|
if (filterChanged && lines) {
|
2012-11-10 00:31:37 +00:00
|
|
|
updateWeakPanel(this, panel, lines);
|
|
|
|
}
|
2015-03-23 20:04:53 +00:00
|
|
|
return filterChanged;
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* IncSet_getListItemValue(Panel* panel, int i) {
|
|
|
|
ListItem* l = (ListItem*) Panel_get(panel, i);
|
|
|
|
if (l)
|
|
|
|
return l->value;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2015-03-23 20:04:53 +00:00
|
|
|
void IncSet_activate(IncSet* this, IncType type, Panel* panel) {
|
2012-11-10 00:31:37 +00:00
|
|
|
this->active = &(this->modes[type]);
|
|
|
|
FunctionBar_draw(this->active->bar, this->active->buffer);
|
2015-03-23 20:04:53 +00:00
|
|
|
panel->currentBar = this->active->bar;
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void IncSet_drawBar(IncSet* this) {
|
2015-03-23 20:04:53 +00:00
|
|
|
if (this->active) {
|
|
|
|
FunctionBar_draw(this->active->bar, this->active->buffer);
|
|
|
|
} else {
|
|
|
|
FunctionBar_draw(this->defaultBar, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int IncSet_synthesizeEvent(IncSet* this, int x) {
|
|
|
|
if (this->active) {
|
|
|
|
return FunctionBar_synthesizeEvent(this->active->bar, x);
|
|
|
|
} else {
|
|
|
|
return FunctionBar_synthesizeEvent(this->defaultBar, x);
|
|
|
|
}
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|