summaryrefslogtreecommitdiffstats
path: root/IncSet.c
diff options
context:
space:
mode:
Diffstat (limited to 'IncSet.c')
-rw-r--r--IncSet.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/IncSet.c b/IncSet.c
new file mode 100644
index 0000000..71edf1c
--- /dev/null
+++ b/IncSet.c
@@ -0,0 +1,247 @@
+/*
+htop - IncSet.c
+(C) 2005-2012 Hisham H. Muhammad
+Released under the GNU GPLv2+, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include "config.h" // IWYU pragma: keep
+
+#include "IncSet.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "CRT.h"
+#include "ListItem.h"
+#include "Object.h"
+#include "ProvideCurses.h"
+#include "XUtils.h"
+
+
+static void IncMode_reset(IncMode* mode) {
+ mode->index = 0;
+ mode->buffer[0] = 0;
+}
+
+void IncSet_reset(IncSet* this, IncType type) {
+ IncMode_reset(&this->modes[type]);
+}
+
+void IncSet_setFilter(IncSet* this, const char* filter) {
+ IncMode* mode = &this->modes[INC_FILTER];
+ size_t len = String_safeStrncpy(mode->buffer, filter, sizeof(mode->buffer));
+ mode->index = len;
+ this->filtering = true;
+}
+
+static const char* const searchFunctions[] = {"Next ", "Prev ", "Cancel ", " Search: ", NULL};
+static const char* const searchKeys[] = {"F3", "S-F3", "Esc", " "};
+static const int searchEvents[] = {KEY_F(3), KEY_F(15), 27, ERR};
+
+static inline void IncMode_initSearch(IncMode* search) {
+ memset(search, 0, sizeof(IncMode));
+ search->bar = FunctionBar_new(searchFunctions, searchKeys, searchEvents);
+ search->isFilter = false;
+}
+
+static const char* const filterFunctions[] = {"Done ", "Clear ", " Filter: ", NULL};
+static const char* const filterKeys[] = {"Enter", "Esc", " "};
+static const 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) {
+ FunctionBar_delete(mode->bar);
+}
+
+IncSet* IncSet_new(FunctionBar* bar) {
+ IncSet* this = xMalloc(sizeof(IncSet));
+ IncMode_initSearch(&(this->modes[INC_SEARCH]));
+ IncMode_initFilter(&(this->modes[INC_FILTER]));
+ this->active = NULL;
+ this->defaultBar = bar;
+ this->filtering = false;
+ this->found = false;
+ return this;
+}
+
+void IncSet_delete(IncSet* this) {
+ IncMode_done(&(this->modes[0]));
+ IncMode_done(&(this->modes[1]));
+ free(this);
+}
+
+static void updateWeakPanel(const IncSet* this, Panel* panel, Vector* lines) {
+ const 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, true)) {
+ 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);
+ }
+ }
+ }
+}
+
+static bool search(const IncSet* this, Panel* panel, IncMode_GetPanelValue getPanelValue) {
+ int size = Panel_size(panel);
+ for (int i = 0; i < size; i++) {
+ if (String_contains_i(getPanelValue(panel, i), this->active->buffer, true)) {
+ Panel_setSelected(panel, i);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+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);
+}
+
+static bool IncMode_find(const 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, true)) {
+ Panel_setSelected(panel, i);
+ return true;
+ }
+ }
+}
+
+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);
+ bool filterChanged = false;
+ bool doSearch = true;
+ if (ch == KEY_F(3) || ch == KEY_F(15)) {
+ if (size == 0)
+ return true;
+
+ IncMode_find(mode, panel, getPanelValue, ch == KEY_F(3) ? 1 : -1);
+ doSearch = false;
+ } else if (0 < ch && ch < 255 && isprint((unsigned char)ch)) {
+ if (mode->index < INCMODE_MAX) {
+ mode->buffer[mode->index] = (char) ch;
+ mode->index++;
+ mode->buffer[mode->index] = 0;
+ if (mode->isFilter) {
+ filterChanged = true;
+ if (mode->index == 1) {
+ this->filtering = true;
+ }
+ }
+ }
+ } 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);
+ }
+ }
+ } else {
+ doSearch = false;
+ }
+ } else if (ch == KEY_RESIZE) {
+ doSearch = (mode->index > 0);
+ } else {
+ if (mode->isFilter) {
+ filterChanged = true;
+ if (ch == 27) {
+ this->filtering = false;
+ IncMode_reset(mode);
+ }
+ } else {
+ if (ch == 27) {
+ IncMode_reset(mode);
+ }
+ }
+ IncSet_deactivate(this, panel);
+ doSearch = false;
+ }
+ if (doSearch) {
+ this->found = search(this, panel, getPanelValue);
+ }
+ if (filterChanged && lines) {
+ updateWeakPanel(this, panel, lines);
+ }
+ return filterChanged;
+}
+
+const char* IncSet_getListItemValue(Panel* panel, int i) {
+ const ListItem* l = (const ListItem*) Panel_get(panel, i);
+ return l ? l->value : "";
+}
+
+void IncSet_drawBar(const IncSet* this, int attr) {
+ if (this->active) {
+ if (!this->active->isFilter && !this->found)
+ attr = CRT_colors[FAILED_SEARCH];
+ int cursorX = FunctionBar_drawExtra(this->active->bar, this->active->buffer, attr, true);
+ this->panel->cursorY = LINES - 1;
+ this->panel->cursorX = cursorX;
+ } else {
+ FunctionBar_draw(this->defaultBar);
+ }
+}
+
+int IncSet_synthesizeEvent(IncSet* this, int x) {
+ if (this->active) {
+ return FunctionBar_synthesizeEvent(this->active->bar, x);
+ } else {
+ return FunctionBar_synthesizeEvent(this->defaultBar, x);
+ }
+}