Commit e204861d authored by Hisham Muhammad's avatar Hisham Muhammad
Browse files

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.
parent 4c4cceee
......@@ -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
......
......@@ -47,6 +47,7 @@ struct Panel_ {
bool needsRedraw;
RichString header;
Panel_EventHandler eventHandler;
char* eventHandlerBuffer;
};
}*/
......
......@@ -49,6 +49,7 @@ struct Panel_ {
bool needsRedraw;
RichString header;
Panel_EventHandler eventHandler;
char* eventHandlerBuffer;
};
......
/*
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 <string.h>
#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;
}
/* 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 <string.h>
#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
#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;
}
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment