From e204861de57b18b889ff7147e64ed64434a81947 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Sat, 5 Nov 2011 04:19:47 +0000 Subject: Allow typing to select items in various panels (sort, user, signal). Factored code from the SignalsPanel to apply to all selections from main screen. Closes feature request #3425304. --- Makefile.am | 4 +-- Panel.c | 1 + Panel.h | 1 + SignalItem.c | 101 --------------------------------------------------------- SignalItem.h | 39 ---------------------- SignalsPanel.c | 79 +++++++++++++++++++++++++------------------- SignalsPanel.h | 10 +++--- htop.c | 38 +++++++++++++++++++--- 8 files changed, 89 insertions(+), 184 deletions(-) delete mode 100644 SignalItem.c delete mode 100644 SignalItem.h diff --git a/Makefile.am b/Makefile.am index a650b3aa..419054e5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,7 @@ ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c DebugMemory.c \ DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c \ LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c \ BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \ -SignalItem.c SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \ +SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \ UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \ HostnameMeter.c OpenFilesScreen.c Affinity.c @@ -32,7 +32,7 @@ CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \ CPUMeter.h CRT.h DebugMemory.h DisplayOptionsPanel.h FunctionBar.h \ Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h \ BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \ -ScreenManager.h Settings.h SignalItem.h SignalsPanel.h String.h \ +ScreenManager.h Settings.h SignalsPanel.h String.h \ SwapMeter.h TasksMeter.h TraceScreen.h UptimeMeter.h UsersTable.h Vector.h \ Process.h AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Affinity.h diff --git a/Panel.c b/Panel.c index 5da79092..43432602 100644 --- a/Panel.c +++ b/Panel.c @@ -47,6 +47,7 @@ struct Panel_ { bool needsRedraw; RichString header; Panel_EventHandler eventHandler; + char* eventHandlerBuffer; }; }*/ diff --git a/Panel.h b/Panel.h index 53fc6fd3..fb588789 100644 --- a/Panel.h +++ b/Panel.h @@ -49,6 +49,7 @@ struct Panel_ { bool needsRedraw; RichString header; Panel_EventHandler eventHandler; + char* eventHandlerBuffer; }; diff --git a/SignalItem.c b/SignalItem.c deleted file mode 100644 index add947e7..00000000 --- a/SignalItem.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -htop - SignalItem.c -(C) 2004-2011 Hisham H. Muhammad -Released under the GNU GPL, see the COPYING file -in the source distribution for its full text. -*/ - -#include "SignalItem.h" -#include "String.h" -#include "Object.h" -#include "RichString.h" -#include - -#include "debug.h" - -#define SIGNAL_COUNT 34 - -/*{ - -typedef struct Signal_ { - Object super; - const char* name; - int number; -} Signal; - -}*/ - -#ifdef DEBUG -char* SIGNAL_CLASS = "Signal"; -#else -#define SIGNAL_CLASS NULL -#endif - -static void Signal_delete(Object* cast) { - Signal* this = (Signal*)cast; - assert (this != NULL); - // names are string constants, so we're not deleting them. - free(this); -} - -static void Signal_display(Object* cast, RichString* out) { - Signal* this = (Signal*)cast; - assert (this != NULL); - - char buffer[31]; - snprintf(buffer, 30, "%2d %s", this->number, this->name); - RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer); -} - -static Signal* Signal_new(const char* name, int number) { - Signal* this = malloc(sizeof(Signal)); - Object_setClass(this, SIGNAL_CLASS); - ((Object*)this)->display = Signal_display; - ((Object*)this)->delete = Signal_delete; - this->name = name; - this->number = number; - return this; -} - -int Signal_getSignalCount() { - return SIGNAL_COUNT; -} - -Signal** Signal_getSignalTable() { - Signal** signals = malloc(sizeof(Signal*) * SIGNAL_COUNT); - signals[0] = Signal_new("Cancel", 0); - signals[1] = Signal_new("SIGHUP", 1); - signals[2] = Signal_new("SIGINT", 2); - signals[3] = Signal_new("SIGQUIT", 3); - signals[4] = Signal_new("SIGILL", 4); - signals[5] = Signal_new("SIGTRAP", 5); - signals[6] = Signal_new("SIGABRT", 6); - signals[7] = Signal_new("SIGIOT", 6); - signals[8] = Signal_new("SIGBUS", 7); - signals[9] = Signal_new("SIGFPE", 8); - signals[10] = Signal_new("SIGKILL", 9); - signals[11] = Signal_new("SIGUSR1", 10); - signals[12] = Signal_new("SIGSEGV", 11); - signals[13] = Signal_new("SIGUSR2", 12); - signals[14] = Signal_new("SIGPIPE", 13); - signals[15] = Signal_new("SIGALRM", 14); - signals[16] = Signal_new("SIGTERM", 15); - signals[17] = Signal_new("SIGSTKFLT", 16); - signals[18] = Signal_new("SIGCHLD", 17); - signals[19] = Signal_new("SIGCONT", 18); - signals[20] = Signal_new("SIGSTOP", 19); - signals[21] = Signal_new("SIGTSTP", 20); - signals[22] = Signal_new("SIGTTIN", 21); - signals[23] = Signal_new("SIGTTOU", 22); - signals[24] = Signal_new("SIGURG", 23); - signals[25] = Signal_new("SIGXCPU", 24); - signals[26] = Signal_new("SIGXFSZ", 25); - signals[27] = Signal_new("SIGVTALRM", 26); - signals[28] = Signal_new("SIGPROF", 27); - signals[29] = Signal_new("SIGWINCH", 28); - signals[30] = Signal_new("SIGIO", 29); - signals[31] = Signal_new("SIGPOLL", 29); - signals[32] = Signal_new("SIGPWR", 30); - signals[33] = Signal_new("SIGSYS", 31); - return signals; -} diff --git a/SignalItem.h b/SignalItem.h deleted file mode 100644 index 03dc25f5..00000000 --- a/SignalItem.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Do not edit this file. It was automatically generated. */ - -#ifndef HEADER_SignalItem -#define HEADER_SignalItem -/* -htop - SignalItem.h -(C) 2004-2011 Hisham H. Muhammad -Released under the GNU GPL, see the COPYING file -in the source distribution for its full text. -*/ - -#include "String.h" -#include "Object.h" -#include "RichString.h" -#include - -#include "debug.h" - -#define SIGNAL_COUNT 34 - - -typedef struct Signal_ { - Object super; - const char* name; - int number; -} Signal; - - -#ifdef DEBUG -extern char* SIGNAL_CLASS; -#else -#define SIGNAL_CLASS NULL -#endif - -int Signal_getSignalCount(); - -Signal** Signal_getSignalTable(); - -#endif diff --git a/SignalsPanel.c b/SignalsPanel.c index 83dfda86..7bd4b3b2 100644 --- a/SignalsPanel.c +++ b/SignalsPanel.c @@ -1,7 +1,7 @@ #include "SignalsPanel.h" #include "Panel.h" -#include "SignalItem.h" +#include "ListItem.h" #include "RichString.h" #include "debug.h" @@ -13,37 +13,14 @@ typedef struct SignalsPanel_ { Panel super; - - int state; - Signal** signals; + ListItem** signals; } SignalsPanel; }*/ -static HandlerResult SignalsPanel_eventHandler(Panel* super, int ch) { - SignalsPanel* this = (SignalsPanel*) super; - - int size = Panel_size(super); - - if (ch <= 255 && isdigit(ch)) { - int sgn = ch-48 + this->state; - for (int i = 0; i < size; i++) - if (((Signal*) Panel_get(super, i))->number == sgn) { - Panel_setSelected(super, i); - break; - } - this->state = sgn * 10; - if (this->state > 100) - this->state = 0; - return HANDLED; - } else { - this->state = 0; - } - if (ch == 13) { - return BREAK_LOOP; - } - return IGNORED; -} +#ifndef SIGNAL_COUNT +#define SIGNAL_COUNT 34 +#endif static void SignalsPanel_delete(Object* object) { Panel* super = (Panel*) object; @@ -53,16 +30,53 @@ static void SignalsPanel_delete(Object* object) { free(this); } +static ListItem** Signal_getSignalTable() { + ListItem** signals = malloc(sizeof(ListItem*) * SIGNAL_COUNT); + signals[0] = ListItem_new(" 0 Cancel", 0); + signals[1] = ListItem_new(" 1 SIGHUP", 1); + signals[2] = ListItem_new(" 2 SIGINT", 2); + signals[3] = ListItem_new(" 3 SIGQUIT", 3); + signals[4] = ListItem_new(" 4 SIGILL", 4); + signals[5] = ListItem_new(" 5 SIGTRAP", 5); + signals[6] = ListItem_new(" 6 SIGABRT", 6); + signals[7] = ListItem_new(" 6 SIGIOT", 6); + signals[8] = ListItem_new(" 7 SIGBUS", 7); + signals[9] = ListItem_new(" 8 SIGFPE", 8); + signals[10] = ListItem_new(" 9 SIGKILL", 9); + signals[11] = ListItem_new("10 SIGUSR1", 10); + signals[12] = ListItem_new("11 SIGSEGV", 11); + signals[13] = ListItem_new("12 SIGUSR2", 12); + signals[14] = ListItem_new("13 SIGPIPE", 13); + signals[15] = ListItem_new("14 SIGALRM", 14); + signals[16] = ListItem_new("15 SIGTERM", 15); + signals[17] = ListItem_new("16 SIGSTKFLT", 16); + signals[18] = ListItem_new("17 SIGCHLD", 17); + signals[19] = ListItem_new("18 SIGCONT", 18); + signals[20] = ListItem_new("19 SIGSTOP", 19); + signals[21] = ListItem_new("20 SIGTSTP", 20); + signals[22] = ListItem_new("21 SIGTTIN", 21); + signals[23] = ListItem_new("22 SIGTTOU", 22); + signals[24] = ListItem_new("23 SIGURG", 23); + signals[25] = ListItem_new("24 SIGXCPU", 24); + signals[26] = ListItem_new("25 SIGXFSZ", 25); + signals[27] = ListItem_new("26 SIGVTALRM", 26); + signals[28] = ListItem_new("27 SIGPROF", 27); + signals[29] = ListItem_new("28 SIGWINCH", 28); + signals[30] = ListItem_new("29 SIGIO", 29); + signals[31] = ListItem_new("29 SIGPOLL", 29); + signals[32] = ListItem_new("30 SIGPWR", 30); + signals[33] = ListItem_new("31 SIGSYS", 31); + return signals; +} + SignalsPanel* SignalsPanel_new(int x, int y, int w, int h) { SignalsPanel* this = (SignalsPanel*) malloc(sizeof(SignalsPanel)); Panel* super = (Panel*) this; - Panel_init(super, x, y, w, h, SIGNAL_CLASS, true); + Panel_init(super, x, y, w, h, LISTITEM_CLASS, true); ((Object*)this)->delete = SignalsPanel_delete; this->signals = Signal_getSignalTable(); - super->eventHandler = SignalsPanel_eventHandler; - int sigCount = Signal_getSignalCount(); - for(int i = 0; i < sigCount; i++) + for(int i = 0; i < SIGNAL_COUNT; i++) Panel_set(super, i, (Object*) this->signals[i]); SignalsPanel_reset(this); return this; @@ -73,5 +87,4 @@ void SignalsPanel_reset(SignalsPanel* this) { Panel_setHeader(super, "Send signal:"); Panel_setSelected(super, 16); // 16th item is SIGTERM - this->state = 0; } diff --git a/SignalsPanel.h b/SignalsPanel.h index 34ef472f..0032cc7c 100644 --- a/SignalsPanel.h +++ b/SignalsPanel.h @@ -4,7 +4,7 @@ #define HEADER_SignalsPanel #include "Panel.h" -#include "SignalItem.h" +#include "ListItem.h" #include "RichString.h" #include "debug.h" @@ -15,12 +15,14 @@ typedef struct SignalsPanel_ { Panel super; - - int state; - Signal** signals; + ListItem** signals; } SignalsPanel; +#ifndef SIGNAL_COUNT +#define SIGNAL_COUNT 34 +#endif + SignalsPanel* SignalsPanel_new(int x, int y, int w, int h); void SignalsPanel_reset(SignalsPanel* this); diff --git a/htop.c b/htop.c index b71198a6..d5921cb5 100644 --- a/htop.c +++ b/htop.c @@ -195,15 +195,41 @@ static bool changePriority(Panel* panel, int delta) { } static HandlerResult pickWithEnter(Panel* panel, int ch) { - (void) panel; - if (ch == 13) + int size = Panel_size(panel); + + if (isalnum(ch)) { + int len = strlen(panel->eventHandlerBuffer); + if (len < 99) { + panel->eventHandlerBuffer[len] = ch; + panel->eventHandlerBuffer[len+1] = '\0'; + } + for (int try = 0; try < 2; try++) { + len = strlen(panel->eventHandlerBuffer); + for (int i = 0; i < size; i++) { + char* cur = ((ListItem*) Panel_get(panel, i))->value; + while (*cur == ' ') cur++; + if (strncasecmp(cur, panel->eventHandlerBuffer, len) == 0) { + Panel_setSelected(panel, i); + return HANDLED; + } + } + panel->eventHandlerBuffer[0] = ch; + panel->eventHandlerBuffer[1] = '\0'; + } + return HANDLED; + } else if (ch != ERR) { + panel->eventHandlerBuffer[0] = '\0'; + } + if (ch == 13) { return BREAK_LOOP; + } return IGNORED; } static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, const char** keyLabels, FunctionBar* prevBar, Header* header) { const char* fuKeys[] = {"Enter", "Esc", NULL}; int fuEvents[] = {13, 27}; + list->eventHandlerBuffer = calloc(100, 1); if (!list->eventHandler) Panel_setEventHandler(list, pickWithEnter); ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, header, false); @@ -213,6 +239,8 @@ static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, const cha int ch; ScreenManager_run(scr, &panelFocus, &ch); ScreenManager_delete(scr); + free(list->eventHandlerBuffer); + list->eventHandlerBuffer = NULL; Panel_move(panel, 0, y); Panel_resize(panel, COLS, LINES-y-1); FunctionBar_draw(prevBar, NULL); @@ -758,7 +786,7 @@ int main(int argc, char** argv) { const char* fuFunctions[] = {"Send ", "Cancel ", NULL}; Signal* sgn = (Signal*) pickFromVector(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar, header); if (sgn) { - if (sgn->number != 0) { + if (sgn->super.key != 0) { Panel_setHeader(panel, "Sending..."); Panel_draw(panel, true); refresh(); @@ -766,13 +794,13 @@ int main(int argc, char** argv) { for (int i = 0; i < Panel_size(panel); i++) { Process* p = (Process*) Panel_get(panel, i); if (p->tag) { - Process_sendSignal(p, sgn->number); + Process_sendSignal(p, sgn->super.key); anyTagged = true; } } if (!anyTagged) { Process* p = (Process*) Panel_getSelected(panel); - Process_sendSignal(p, sgn->number); + Process_sendSignal(p, sgn->super.key); } napms(500); } -- cgit v1.2.3