1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*
htop - AvailableColumnsPanel.c
(C) 2004-2011 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 "AvailableColumnsPanel.h"
#include <assert.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include "ColumnsPanel.h"
#include "DynamicColumn.h"
#include "FunctionBar.h"
#include "Hashtable.h"
#include "ListItem.h"
#include "Object.h"
#include "Platform.h"
#include "Process.h"
#include "ProvideCurses.h"
#include "RowField.h"
#include "XUtils.h"
static const char* const AvailableColumnsFunctions[] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done ", NULL};
static void AvailableColumnsPanel_delete(Object* object) {
AvailableColumnsPanel* this = (AvailableColumnsPanel*) object;
Panel_done(&this->super);
free(this);
}
static void AvailableColumnsPanel_insert(AvailableColumnsPanel* this, int at, int key) {
const char* name;
if (key >= ROW_DYNAMIC_FIELDS)
name = DynamicColumn_name(key);
else
name = Process_fields[key].name;
Panel_insert(this->columns, at, (Object*) ListItem_new(name, key));
}
static HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch) {
AvailableColumnsPanel* this = (AvailableColumnsPanel*) super;
HandlerResult result = IGNORED;
switch (ch) {
case 13:
case KEY_ENTER:
case KEY_F(5): {
const ListItem* selected = (ListItem*) Panel_getSelected(super);
if (!selected)
break;
int at = Panel_getSelectedIndex(this->columns);
AvailableColumnsPanel_insert(this, at, selected->key);
Panel_setSelected(this->columns, at + 1);
ColumnsPanel_update(this->columns);
result = HANDLED;
break;
}
default:
if (0 < ch && ch < 255 && isgraph((unsigned char)ch))
result = Panel_selectByTyping(super, ch);
break;
}
return result;
}
const PanelClass AvailableColumnsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = AvailableColumnsPanel_delete
},
.eventHandler = AvailableColumnsPanel_eventHandler
};
static void AvailableColumnsPanel_addDynamicColumn(ht_key_t key, void* value, void* data) {
const DynamicColumn* column = (const DynamicColumn*) value;
if (column->table) /* DynamicScreen, handled differently */
return;
AvailableColumnsPanel* this = (AvailableColumnsPanel*) data;
const char* title = column->heading ? column->heading : column->name;
const char* text = column->description ? column->description : column->caption;
char description[256];
if (text)
xSnprintf(description, sizeof(description), "%s - %s", title, text);
else
xSnprintf(description, sizeof(description), "%s", title);
Panel_add(&this->super, (Object*) ListItem_new(description, key));
}
// Handle DynamicColumns entries in the AvailableColumnsPanel
static void AvailableColumnsPanel_addDynamicColumns(AvailableColumnsPanel* this, Hashtable* dynamicColumns) {
assert(dynamicColumns);
Hashtable_foreach(dynamicColumns, AvailableColumnsPanel_addDynamicColumn, this);
}
// Handle remaining Platform Meter entries in the AvailableColumnsPanel
static void AvailableColumnsPanel_addPlatformColumns(AvailableColumnsPanel* this) {
for (int i = 1; i < LAST_PROCESSFIELD; i++) {
if (Process_fields[i].description) {
char description[256];
xSnprintf(description, sizeof(description), "%s - %s", Process_fields[i].name, Process_fields[i].description);
Panel_add(&this->super, (Object*) ListItem_new(description, i));
}
}
}
// Handle DynamicColumns entries associated with DynamicScreens
static void AvailableColumnsPanel_addDynamicScreens(AvailableColumnsPanel* this, const char* screen) {
Platform_addDynamicScreenAvailableColumns(&this->super, screen);
}
void AvailableColumnsPanel_fill(AvailableColumnsPanel* this, const char* dynamicScreen, Hashtable* dynamicColumns) {
Panel_prune(&this->super);
if (dynamicScreen) {
AvailableColumnsPanel_addDynamicScreens(this, dynamicScreen);
} else {
AvailableColumnsPanel_addPlatformColumns(this);
AvailableColumnsPanel_addDynamicColumns(this, dynamicColumns);
}
}
AvailableColumnsPanel* AvailableColumnsPanel_new(Panel* columns, Hashtable* dynamicColumns) {
AvailableColumnsPanel* this = AllocThis(AvailableColumnsPanel);
Panel* super = &this->super;
FunctionBar* fuBar = FunctionBar_new(AvailableColumnsFunctions, NULL, NULL);
Panel_init(super, 1, 1, 1, 1, Class(ListItem), true, fuBar);
Panel_setHeader(super, "Available Columns");
this->columns = columns;
AvailableColumnsPanel_fill(this, NULL, dynamicColumns);
return this;
}
|