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 "Panel.h"
|
|
|
|
#include "ListItem.h"
|
|
|
|
#include "CRT.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
/*{
|
|
|
|
|
|
|
|
#include "FunctionBar.h"
|
|
|
|
#include "Panel.h"
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
#define INCMODE_MAX 40
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
INC_SEARCH = 0,
|
|
|
|
INC_FILTER = 1
|
|
|
|
} IncType;
|
|
|
|
|
|
|
|
#define IncSet_filter(inc_) (inc_->filtering ? inc_->modes[INC_FILTER].buffer : NULL)
|
|
|
|
|
|
|
|
typedef struct IncMode_ {
|
2014-04-24 22:48:34 +00:00
|
|
|
char buffer[INCMODE_MAX+1];
|
2012-11-10 00:31:37 +00:00
|
|
|
int index;
|
|
|
|
FunctionBar* bar;
|
|
|
|
bool isFilter;
|
|
|
|
} IncMode;
|
|
|
|
|
|
|
|
typedef struct IncSet_ {
|
|
|
|
IncMode modes[2];
|
|
|
|
IncMode* active;
|
2018-01-28 01:28:37 +00:00
|
|
|
Panel* panel;
|
2012-11-10 00:31:37 +00:00
|
|
|
FunctionBar* defaultBar;
|
|
|
|
bool filtering;
|
2016-05-05 13:30:06 +00:00
|
|
|
bool found;
|
2012-11-10 00:31:37 +00:00
|
|
|
} IncSet;
|
|
|
|
|
|
|
|
typedef const char* (*IncMode_GetPanelValue)(Panel*, int);
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
static void IncMode_reset(IncMode* mode) {
|
|
|
|
mode->index = 0;
|
|
|
|
mode->buffer[0] = 0;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-28 01:28:37 +00:00
|
|
|
static bool search(IncSet* this, 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++) {
|
2018-01-28 01:28:37 +00:00
|
|
|
if (String_contains_i(getPanelValue(panel, i), this->active->buffer)) {
|
2012-11-10 00:31:37 +00:00
|
|
|
Panel_setSelected(panel, i);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-01-28 01:28:37 +00:00
|
|
|
IncSet_drawBar(this, found ? CRT_colors[FUNCTION_BAR] : CRT_colors[FAILED_SEARCH]);
|
2016-05-05 13:30:06 +00:00
|
|
|
return found;
|
2012-11-10 00:31:37 +00:00
|
|
|
}
|
|
|
|
|
2018-01-28 01:28:37 +00:00
|
|
|
void IncSet_activate(IncSet* this, IncType type, Panel* panel) {
|
|
|
|
this->active = &(this->modes[type]);
|
|
|
|
panel->currentBar = this->active->bar;
|
|
|
|
panel->cursorOn = true;
|
|
|
|
this->panel = panel;
|
|
|
|
IncSet_drawBar(this, CRT_colors[FUNCTION_BAR]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void IncSet_deactivate(IncSet* this, Panel* panel) {
|
|
|
|
this->active = NULL;
|
|
|
|
Panel_setDefaultBar(panel);
|
|
|
|
panel->cursorOn = false;
|
|
|
|
FunctionBar_draw(this->defaultBar, NULL);
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
int here = Panel_getSelectedIndex(panel);
|
|
|
|
int i = here;
|
|
|
|
for(;;) {
|
|
|
|
i++;
|
|
|
|
if (i == size) i = 0;
|
|
|
|
if (i == here) break;
|
|
|
|
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
|
|
|
|
Panel_setSelected(panel, i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
doSearch = false;
|
2016-05-05 13:30:06 +00:00
|
|
|
} else if (ch < 255 && isprint((char)ch)) {
|
|
|
|
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 {
|
|
|
|
IncMode_reset(mode);
|
|
|
|
}
|
2018-01-28 01:28:37 +00:00
|
|
|
IncSet_deactivate(this, panel);
|
2012-11-10 00:31:37 +00:00
|
|
|
doSearch = false;
|
|
|
|
}
|
|
|
|
if (doSearch) {
|
2018-01-28 01:28:37 +00:00
|
|
|
this->found = search(this, 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 "";
|
|
|
|
}
|
|
|
|
|
2018-01-28 01:28:37 +00:00
|
|
|
void IncSet_drawBar(IncSet* this, int attr) {
|
2015-03-23 20:04:53 +00:00
|
|
|
if (this->active) {
|
2018-01-28 01:28:37 +00:00
|
|
|
int cursorX = FunctionBar_drawAttr(this->active->bar, this->active->buffer, attr);
|
|
|
|
this->panel->cursorY = LINES - 1;
|
|
|
|
this->panel->cursorX = cursorX;
|
2015-03-23 20:04:53 +00:00
|
|
|
} 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
|
|
|
}
|