cs: refactorize column select screen

This commit is contained in:
Kaian 2018-11-18 13:55:28 +01:00
parent 911d0a2c38
commit c5d8526c26
15 changed files with 630 additions and 653 deletions

View File

@ -37,7 +37,7 @@ set(SOURCES
src/ncurses/ui_call_flow.c
src/ncurses/call_list.c
src/ncurses/ui_call_raw.c
src/ncurses/ui_column_select.c
src/ncurses/column_select.c
src/ncurses/ui_filter.c
src/ncurses/ui_msg_diff.c
src/ncurses/ui_save.c

View File

@ -120,7 +120,7 @@ filter_check_call(gconstpointer item, G_GNUC_UNUSED gconstpointer user_data)
break;
case FILTER_CALL_LIST:
// FIXME Maybe call should know hot to calculate this line
call_list_line_text(ui_find_by_type(WINDOW_CALL_LIST), call, data);
call_list_line_text(ncurses_find_by_type(WINDOW_CALL_LIST), call, data);
break;
default:
// Unknown filter id

View File

@ -210,6 +210,14 @@ g_ptr_array_remove_array(GPtrArray *array, GPtrArray *items)
g_ptr_array_foreach(items, (GFunc) g_ptr_array_remove_cb, array);
}
void
g_ptr_array_remove_all(GPtrArray *array)
{
if (g_ptr_array_len(array) != 0) {
g_ptr_array_remove_range(array, 0, g_ptr_array_len(array));
}
}
#if !GLIB_CHECK_VERSION(2, 54, 0)
gboolean
g_ptr_array_find(GPtrArray *haystack, gconstpointer needle, guint *index_)

View File

@ -84,6 +84,9 @@ g_ptr_array_add_array(GPtrArray *array, GPtrArray *items);
void
g_ptr_array_remove_array(GPtrArray *array, GPtrArray *items);
void
g_ptr_array_remove_all(GPtrArray *array);
#if !GLIB_CHECK_VERSION(2,54,0)
gboolean
g_ptr_array_find(GPtrArray *haystack, gconstpointer needle, guint *index);

View File

@ -47,6 +47,7 @@
#include "ncurses/ui_filter.h"
#include "ncurses/ui_save.h"
#include "storage.h"
#include "column_select.h"
/**
* @brief Get custom information of given panel
@ -57,7 +58,7 @@
* @param window UI structure pointer
* @return a pointer to info structure of given panel
*/
CallListInfo *
static CallListInfo *
call_list_info(Window *window)
{
return (CallListInfo*) panel_userptr(window->panel);
@ -214,8 +215,8 @@ call_list_resize(Window *window)
static void
call_list_draw_header(Window *window)
{
const char *infile, *coldesc;
int colpos, collen;
const char *infile;
int colpos;
const char *countlb;
const char *device, *filterbpf;
@ -297,26 +298,25 @@ call_list_draw_header(Window *window)
colpos = 6;
}
for (guint i = 0; i < info->columncnt; i++) {
// Get current column width
collen = info->columns[i].width;
for (guint i = 0; i < g_ptr_array_len(info->columns); i++) {
CallListColumn *column = g_ptr_array_index(info->columns, i);
// Get current column title
coldesc = sip_attr_get_title(info->columns[i].id);
const gchar *coldesc = sip_attr_get_title(column->id);
// Check if the column will fit in the remaining space of the screen
if (colpos + strlen(coldesc) >= (guint) window->width)
break;
// Print sort column indicator
if (info->columns[i].id == sort.by) {
if (column->id == sort.by) {
wattron(window->win, A_BOLD | COLOR_PAIR(CP_YELLOW_ON_CYAN));
gchar sortind = (gchar) ((sort.asc) ? '^' : 'v');
mvwprintw(window->win, 4, colpos, "%c%.*s", sortind, collen, coldesc);
mvwprintw(window->win, 4, colpos, "%c%.*s", sortind, column->width, coldesc);
wattron(window->win, A_BOLD | COLOR_PAIR(CP_DEF_ON_CYAN));
} else {
mvwprintw(window->win, 4, colpos, "%.*s", collen, coldesc);
mvwprintw(window->win, 4, colpos, "%.*s", column->width, coldesc);
}
colpos += collen + 1;
colpos += column->width + 1;
}
// Print Autoscroll indicator
@ -339,7 +339,6 @@ call_list_draw_header(Window *window)
} else {
mvwprintw(window->win, 1, 45, "%s: %d", countlb, stats.total);
}
}
/**
@ -381,12 +380,9 @@ call_list_draw_footer(Window *window)
static void
call_list_draw_list(Window *window)
{
WINDOW *list_win;
int listh, listw, cline = 0;
SipCall *call = NULL;
int collen;
char coltext[SIP_ATTR_MAXLEN];
int colid;
int colpos;
int color;
@ -395,7 +391,7 @@ call_list_draw_list(Window *window)
g_return_if_fail(info != NULL);
// Get window of call list panel
list_win = info->list_win;
WINDOW *list_win = info->list_win;
getmaxyx(list_win, listh, listw);
// Get the list of calls that are goint to be displayed
@ -443,36 +439,33 @@ call_list_draw_list(Window *window)
// Print requested columns
colpos = 6;
for (guint j = 0; j < info->columncnt; j++) {
// Get current column id
colid = info->columns[j].id;
// Get current column width
collen = info->columns[j].width;
for (guint j = 0; j < g_ptr_array_len(info->columns); j++) {
CallListColumn *column = g_ptr_array_index(info->columns, j);
// Check if next column fits on window width
if (colpos + collen >= listw)
if (colpos + column->width >= (guint) listw)
break;
// Initialize column text
memset(coltext, 0, sizeof(coltext));
// Get call attribute for current column
if (!call_get_attribute(call, colid, coltext)) {
colpos += collen + 1;
if (!call_get_attribute(call, column->id, coltext)) {
colpos += column->width + 1;
continue;
}
// Enable attribute color (if not current one)
color = 0;
if (info->cur_idx != i) {
if ((color = sip_attr_get_color(colid, coltext)) > 0) {
if ((color = sip_attr_get_color(column->id, coltext)) > 0) {
wattron(list_win, color);
}
}
// Add the column text to the existing columns
mvwprintw(list_win, cline, colpos, "%.*s", collen, coltext);
colpos += collen + 1;
mvwprintw(list_win, cline, colpos, "%.*s", column->width, coltext);
colpos += column->width + 1;
// Disable attribute color
if (color > 0)
@ -583,13 +576,11 @@ call_list_line_text(Window *window, SipCall *call, char *text)
g_return_val_if_fail(info != NULL, text);
// Print requested columns
for (guint i = 0; i < info->columncnt; i++) {
// Get current column id
enum sip_attr_id colid = info->columns[i].id;
for (guint i = 0; i < g_ptr_array_len(info->columns); i++) {
CallListColumn *column = g_ptr_array_index(info->columns, i);
// Get current column width
gint collen = info->columns[i].width;
gint collen = column->width;
// Check if next column fits on window width
if ((gint)(strlen(text) + collen) >= window->width)
@ -604,7 +595,7 @@ call_list_line_text(Window *window, SipCall *call, char *text)
memset(call_attr, 0, sizeof(call_attr));
// Get call attribute for current column
if (call_get_attribute(call, colid, call_attr)) {
if (call_get_attribute(call, column->id, call_attr)) {
sprintf(coltext, "%.*s", collen, call_attr);
}
// Add the column text to the existing columns
@ -635,11 +626,12 @@ call_list_select_sort_attribute(Window *window)
mvderwin(info->list_win, 5, 12);
// Create menu entries
for (guint i = 0; i < info->columncnt; i++) {
info->items[i] = new_item(sip_attr_get_name(info->columns[i].id), 0);
for (guint i = 0; i < g_ptr_array_len(info->columns); i++) {
CallListColumn *column = g_ptr_array_index(info->columns, i);
info->items[i] = new_item(sip_attr_get_name(column->id), 0);
}
info->items[info->columncnt] = NULL;
info->items[g_ptr_array_len(info->columns)] = NULL;
// Create the columns menu and post it
info->menu = new_menu(info->items);
@ -845,7 +837,7 @@ static int
call_list_handle_key(Window *window, int key)
{
guint rnpag_steps = (guint) setting_get_intvalue(SETTING_CL_SCROLLSTEP);
Window *next_ui;
Window *next_window;
SipCallGroup *group;
int action = -1;
SipCall *call;
@ -931,7 +923,8 @@ call_list_handle_key(Window *window, int key)
ncurses_create_window(PANEL_FILTER);
break;
case ACTION_SHOW_COLUMNS:
ncurses_create_window(PANEL_COLUMN_SELECT);
next_window = ncurses_create_window(WINDOW_COLUMN_SELECT);
column_select_set_columns(next_window, info->columns);
break;
case ACTION_SHOW_STATS:
ncurses_create_window(PANEL_STATS);
@ -941,8 +934,8 @@ call_list_handle_key(Window *window, int key)
dialog_run("Saving is not possible when multiple input sources are specified.");
break;
}
next_ui = ncurses_create_window(PANEL_SAVE);
save_set_group(next_ui, info->group);
next_window = ncurses_create_window(PANEL_SAVE);
save_set_group(next_window, info->group);
break;
case ACTION_CLEAR:
// Clear group calls
@ -1108,18 +1101,19 @@ call_list_help(G_GNUC_UNUSED Window *window)
* @param width Column Width
* @return 0 if column has been successufly added to the list, -1 otherwise
*/
void
static void
call_list_add_column(Window *window, enum sip_attr_id id, const char* attr,
const char *title, int width)
{
CallListInfo *info = call_list_info(window);
g_return_if_fail(info != NULL);
info->columns[info->columncnt].id = id;
info->columns[info->columncnt].attr = attr;
info->columns[info->columncnt].title = title;
info->columns[info->columncnt].width = (guint) width;
info->columncnt++;
CallListColumn *column = g_malloc0(sizeof(CallListColumn));
column->id = id;
column->attr = attr;
column->title = title;
column->width = (guint) width;
g_ptr_array_add(info->columns, column);
}
void
@ -1159,6 +1153,7 @@ call_list_free(Window *window)
// Deallocate window private data
call_group_free(info->group);
g_ptr_array_free(info->columns, TRUE);
g_ptr_array_free(info->dcalls, FALSE);
delwin(info->list_win);
g_free(info);
@ -1188,6 +1183,7 @@ call_list_new()
set_panel_userptr(window->panel, (void*) info);
// Add configured columns
info->columns = g_ptr_array_new_with_free_func(g_free);
for (guint i = 0; i < SIP_ATTR_COUNT; i++) {
// Get column attribute name from options
gchar *option = g_strdup_printf("cl.column%d", i);

View File

@ -84,9 +84,7 @@ struct _CallListInfo {
//! Selected calls with space
SipCallGroup *group;
//! Displayed column list, make it configurable in the future
CallListColumn columns[SIP_ATTR_COUNT];
//! Displayed column count.
guint columncnt;
GPtrArray *columns;
//! List subwindow
WINDOW *list_win;
//! Form that contains the display filter
@ -121,18 +119,6 @@ struct _CallListInfo {
Window *
call_list_new();
/**
* @brief Get custom information of given panel
*
* Return ncurses users pointer of the given panel into panel's
* information structure pointer.
*
* @param window UI structure pointer
* @return a pointer to info structure of given panel
*/
CallListInfo *
call_list_info(Window *window);
/**
* @brief Get List line from the given call
*
@ -147,22 +133,6 @@ call_list_info(Window *window);
const char*
call_list_line_text(Window *window, SipCall *call, char *text);
/**
* @brief Add a column the Call List
*
* This function will add a new column to the Call List panel
* @todo Columns are not configurable yet.
*
* @param window UI structure pointer
* @param id SIP call attribute id
* @param attr SIP call attribute name
* @param title SIP call attribute description
* @param width Column Width
*/
void
call_list_add_column(Window *window, enum sip_attr_id id, const char* attr,
const char *title, int width);
/**
* @brief Remove all calls from the list and calls storage
*

View File

@ -29,331 +29,139 @@
*/
#include "config.h"
#include <glib.h>
#include <glib/gstdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <glib/gstdio.h>
#include "glib-utils.h"
#include "ncurses/ui_manager.h"
#include "ncurses/call_list.h"
#include "ncurses/ui_column_select.h"
#include "ncurses/column_select.h"
/**
* Ui Structure definition for Message Diff panel
* @brief Get custom information of given panel
*
* Return ncurses users pointer of the given panel into panel's
* information structure pointer.
*
* @param ui UI structure pointer
* @return a pointer to info structure of given panel
*/
Window ui_column_select = {
.type = PANEL_COLUMN_SELECT,
.panel = NULL,
.create = column_select_create,
.handle_key = column_select_handle_key,
.destroy = column_select_destroy
};
void
column_select_create(Window *ui)
{
int attr_id;
MENU *menu;
column_select_info_t *info;
// Cerate a new indow for the panel and form
window_init(ui, 20, 60);
// Initialize Filter panel specific data
info = g_malloc0(sizeof(column_select_info_t));
// Store it into panel userptr
set_panel_userptr(ui->panel, (void*) info);
// Initialize the fields
info->fields[FLD_COLUMNS_ACCEPT] = new_field(1, 10, ui->height - 2, 13, 0, 0);
info->fields[FLD_COLUMNS_SAVE] = new_field(1, 10, ui->height - 2, 25, 0, 0);
info->fields[FLD_COLUMNS_CANCEL] = new_field(1, 10, ui->height - 2, 37, 0, 0);
info->fields[FLD_COLUMNS_COUNT] = NULL;
// Field Labels
set_field_buffer(info->fields[FLD_COLUMNS_ACCEPT], 0, "[ Accept ]");
set_field_buffer(info->fields[FLD_COLUMNS_SAVE], 0, "[ Save ]");
set_field_buffer(info->fields[FLD_COLUMNS_CANCEL], 0, "[ Cancel ]");
// Create the form and post it
info->form = new_form(info->fields);
set_form_sub(info->form, ui->win);
post_form(info->form);
// Create a subwin for the menu area
info->menu_win = derwin(ui->win, 10, ui->width - 2, 7, 0);
// Initialize one field for each attribute
for (attr_id = 0; attr_id < SIP_ATTR_COUNT; attr_id++) {
// Create a new field for this column
info->items[attr_id] = new_item("[ ]", sip_attr_get_description(attr_id));
set_item_userptr(info->items[attr_id], (void*) sip_attr_get_name(attr_id));
}
info->items[SIP_ATTR_COUNT] = NULL;
// Create the columns menu and post it
info->menu = menu = new_menu(info->items);
// Set current enabled fields
// FIXME Stealing Call list columns :/
CallListInfo *list_info = call_list_info(ui_find_by_type(WINDOW_CALL_LIST));
// Enable current enabled fields and move them to the top
for (guint column = 0; column < list_info->columncnt; column++) {
const char *attr = list_info->columns[column].attr;
for (attr_id = 0; attr_id < item_count(menu); attr_id++) {
if (!strcmp(item_userptr(info->items[attr_id]), attr)) {
column_select_toggle_item(ui, info->items[attr_id]);
column_select_move_item(ui, info->items[attr_id], column);
break;
}
}
}
// Set main window and sub window
set_menu_win(menu, ui->win);
set_menu_sub(menu, derwin(ui->win, 10, ui->width - 5, 7, 2));
set_menu_format(menu, 10, 1);
set_menu_mark(menu, "");
set_menu_fore(menu, COLOR_PAIR(CP_DEF_ON_BLUE));
menu_opts_off(menu, O_ONEVALUE);
post_menu(menu);
// Draw a scrollbar to the right
info->scroll = ui_set_scrollbar(info->menu_win, SB_VERTICAL, SB_RIGHT);
info->scroll.max = item_count(menu) - 1;
ui_scrollbar_draw(info->scroll);
// Set the window title and boxes
mvwprintw(ui->win, 1, ui->width / 2 - 14, "Call List columns selection");
wattron(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF));
title_foot_box(ui->panel);
mvwhline(ui->win, 6, 1, ACS_HLINE, ui->width - 1);
mvwaddch(ui->win, 6, 0, ACS_LTEE);
mvwaddch(ui->win, 6, ui->width - 1, ACS_RTEE);
wattroff(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF));
// Some brief explanation abotu what window shows
wattron(ui->win, COLOR_PAIR(CP_CYAN_ON_DEF));
mvwprintw(ui->win, 3, 2, "This windows show the list of columns displayed on Call");
mvwprintw(ui->win, 4, 2, "List. You can enable/disable using Space Bar and reorder");
mvwprintw(ui->win, 5, 2, "them using + and - keys.");
wattroff(ui->win, COLOR_PAIR(CP_CYAN_ON_DEF));
info->form_active = 0;
}
void
column_select_destroy(Window *ui)
{
int i;
column_select_info_t *info = column_select_info(ui);
// Remove menu and items
unpost_menu(info->menu);
free_menu(info->menu);
for (i = 0; i < SIP_ATTR_COUNT; i++)
free_item(info->items[i]);
// Remove form and fields
unpost_form(info->form);
free_form(info->form);
for (i = 0; i < FLD_COLUMNS_COUNT; i++)
free_field(info->fields[i]);
g_free(info);
// Remove panel window and custom info
window_deinit(ui);
}
column_select_info_t *
static ColumnSelectInfo *
column_select_info(Window *ui)
{
return (column_select_info_t*) panel_userptr(ui->panel);
return (ColumnSelectInfo*) panel_userptr(ui->panel);
}
int
column_select_handle_key(Window *ui, int key)
/**
* @brief Move a item to a new position
*
* This function can be used to reorder the column list
*
* @param ui UI structure pointer
* @param item Menu item to be moved
* @param post New position in the menu
*/
static void
column_select_move_item(Window *ui, ITEM *item, int pos)
{
// Get panel information
column_select_info_t *info = column_select_info(ui);
ColumnSelectInfo *info = column_select_info(ui);
if (info->form_active) {
return column_select_handle_key_form(ui, key);
// Check we have a valid position
if (pos == item_count(info->menu) || pos < 0)
return;
// Swap position with destination
int item_pos = item_index(item);
info->items[item_pos] = info->items[pos];
info->items[pos] = item;
set_menu_items(info->menu, info->items);
}
/**
* @brief Select/Deselect a menu item
*
* This function can be used to toggle selection status of
* the menu item
*
* @param ui UI structure pointer
* @param item Menu item to be (de)selected
*/
static void
column_select_toggle_item(Window *ui, ITEM *item)
{
// Get panel information
ColumnSelectInfo *info = column_select_info(ui);
int pos = item_index(item);
// Change item name
if (!strncmp(item_name(item), "[ ]", 3)) {
info->items[pos] = new_item("[*]", item_description(item));
} else {
return column_select_handle_key_menu(ui, key);
info->items[pos] = new_item("[ ]", item_description(item));
}
return 0;
// Restore menu item
set_item_userptr(info->items[pos], item_userptr(item));
set_menu_items(info->menu, info->items);
// Destroy old item
free_item(item);
}
int
column_select_handle_key_menu(Window *ui, int key)
/**
* @brief Update menu after a change
*
* After moving an item or updating its selectioactivn status
* menu must be redrawn.
*
* @param ui UI structure pointer
*/
static void
column_select_update_menu(Window *ui)
{
MENU *menu;
ITEM *current;
int current_idx;
int action = -1;
// Get panel information
column_select_info_t *info = column_select_info(ui);
ColumnSelectInfo *info = column_select_info(ui);
ITEM *current = current_item(info->menu);
int top_idx = top_row(info->menu);
menu = info->menu;
current = current_item(menu);
current_idx = item_index(current);
// Remove the menu from the subwindow
unpost_menu(info->menu);
// Set menu items
set_menu_items(info->menu, info->items);
// Put the menu agin into its subwindow
post_menu(info->menu);
// Check actions for this key
while ((action = key_find_action(key, action)) != ERR) {
// Check if we handle this action
switch (action) {
case ACTION_DOWN:
menu_driver(menu, REQ_DOWN_ITEM);
break;
case ACTION_UP:
menu_driver(menu, REQ_UP_ITEM);
break;
case ACTION_NPAGE:
menu_driver(menu, REQ_SCR_DPAGE);
break;
case ACTION_PPAGE:
menu_driver(menu, REQ_SCR_UPAGE);
break;
case ACTION_SELECT:
column_select_toggle_item(ui, current);
column_select_update_menu(ui);
break;
case ACTION_COLUMN_MOVE_DOWN:
column_select_move_item(ui, current, current_idx + 1);
column_select_update_menu(ui);
break;
case ACTION_COLUMN_MOVE_UP:
column_select_move_item(ui, current, current_idx - 1);
column_select_update_menu(ui);
break;
case ACTION_NEXT_FIELD:
info->form_active = 1;
set_menu_fore(menu, COLOR_PAIR(CP_DEFAULT));
set_field_back(info->fields[FLD_COLUMNS_ACCEPT], A_REVERSE);
form_driver(info->form, REQ_VALIDATION);
break;
case ACTION_CONFIRM:
column_select_update_columns(ui);
ui_destroy(ui);
return KEY_HANDLED;
default:
// Parse next action
continue;
}
// Move until the current position is set
set_top_row(info->menu, top_idx);
set_current_item(info->menu, current);
// This panel has handled the key successfully
break;
}
// Draw a scrollbar to the right
info->scroll.pos = top_row(menu);
ui_scrollbar_draw(info->scroll);
wnoutrefresh(info->menu_win);
// Return if this panel has handled or not the key
return (action == ERR) ? KEY_NOT_HANDLED : KEY_HANDLED;
// Force menu redraw
menu_driver(info->menu, REQ_DOWN_ITEM);
menu_driver(info->menu, REQ_UP_ITEM);
}
int
column_select_handle_key_form(Window *ui, int key)
{
int field_idx, new_field_idx;
char field_value[48];
int action = -1;
// Get panel information
column_select_info_t *info = column_select_info(ui);
// Get current field id
field_idx = field_index(current_field(info->form));
// Get current field value.
memset(field_value, 0, sizeof(field_value));
strcpy(field_value, field_buffer(current_field(info->form), 0));
g_strstrip(field_value);
// Check actions for this key
while ((action = key_find_action(key, action)) != ERR) {
// Check if we handle this action
switch (action) {
case ACTION_RIGHT:
case ACTION_NEXT_FIELD:
form_driver(info->form, REQ_NEXT_FIELD);
break;
case ACTION_LEFT:
case ACTION_PREV_FIELD:
form_driver(info->form, REQ_PREV_FIELD);
break;
case ACTION_SELECT:
case ACTION_CONFIRM:
switch(field_idx) {
case FLD_COLUMNS_ACCEPT:
column_select_update_columns(ui);
ui_destroy(ui);
return KEY_HANDLED;
case FLD_COLUMNS_CANCEL:
ui_destroy(ui);
return KEY_HANDLED;
case FLD_COLUMNS_SAVE:
column_select_update_columns(ui);
column_select_save_columns(ui);
ui_destroy(ui);
return KEY_HANDLED;
}
break;
default:
// Parse next action
continue;
}
// This panel has handled the key successfully
break;
}
// Validate all input data
form_driver(info->form, REQ_VALIDATION);
// Change background and cursor of "button fields"
set_field_back(info->fields[FLD_COLUMNS_ACCEPT], A_NORMAL);
set_field_back(info->fields[FLD_COLUMNS_SAVE], A_NORMAL);
set_field_back(info->fields[FLD_COLUMNS_CANCEL], A_NORMAL);
// Get current selected field
new_field_idx = field_index(current_field(info->form));
// Swap between menu and form
if (field_idx == FLD_COLUMNS_CANCEL && new_field_idx == FLD_COLUMNS_ACCEPT) {
set_menu_fore(info->menu, COLOR_PAIR(CP_DEF_ON_BLUE));
info->form_active = 0;
} else {
// Change current field background
set_field_back(info->fields[new_field_idx], A_REVERSE);
}
// Return if this panel has handled or not the key
return (action == ERR) ? KEY_NOT_HANDLED : KEY_HANDLED;
}
void
/**
* @brief Update Call List columns
*
* This function will update the columns of Call List
*
* @param ui UI structure pointer
*/
static void
column_select_update_columns(Window *ui)
{
int column, attr_id;
// Get panel information
column_select_info_t *info = column_select_info(ui);
// Set enabled fields
Window *ui_list = ui_find_by_type(WINDOW_CALL_LIST);
CallListInfo *list_info = call_list_info(ui_list);
ColumnSelectInfo *info = column_select_info(ui);
g_return_if_fail(info != NULL);
// Reset column count
list_info->columncnt = 0;
g_ptr_array_remove_all(info->selected);
// Add all selected columns
for (column = 0; column < item_count(info->menu); column++) {
@ -363,13 +171,26 @@ column_select_update_columns(Window *ui)
// Get column attribute
attr_id = sip_attr_from_name(item_userptr(info->items[column]));
// Add a new column to the list
call_list_add_column(ui_list, attr_id, sip_attr_get_name(attr_id),
sip_attr_get_title(attr_id), sip_attr_get_width(attr_id));
CallListColumn *column = g_malloc0(sizeof(CallListColumn));
column->id = attr_id;
column->attr = sip_attr_get_name(attr_id);
column->title = sip_attr_get_title(attr_id);
column->width = (guint) sip_attr_get_width(attr_id);
g_ptr_array_add(info->selected, column);
}
}
void
/**
* @brief Save selected columns to user config file
*
* Remove previously configurated columns from user's
* $SNGREPRC or $HOME/.sngreprc and add new ones
*
* @param ui UI structure pointer
*/
static void
column_select_save_columns(Window *ui)
{
g_autoptr(GString) userconf = g_string_new(NULL);
@ -429,7 +250,7 @@ column_select_save_columns(Window *ui)
}
// Get panel information
column_select_info_t *info = column_select_info(ui);
ColumnSelectInfo *info = column_select_info(ui);
// Add all selected columns
for (gint i = 0; i < item_count(info->menu); i++) {
@ -447,67 +268,338 @@ column_select_save_columns(Window *ui)
dialog_run("Column layout successfully saved to %s", userconf->str);
}
void
column_select_move_item(Window *ui, ITEM *item, int pos)
/**
* @brief Manage pressed keys for column selection panel
*
* This function will handle keys when menu is active.
* You can switch between menu and rest of the components
* using TAB
*
* @param ui UI structure pointer
* @param key key code
* @return enum @key_handler_ret
*/
static int
column_select_handle_key_menu(Window *ui, int key)
{
ITEM *current;
int current_idx;
int action = -1;
// Get panel information
column_select_info_t *info = column_select_info(ui);
ColumnSelectInfo *info = column_select_info(ui);
g_return_val_if_fail(info != NULL, KEY_DESTROY);
// Check we have a valid position
if (pos == item_count(info->menu) || pos < 0)
return;
current = current_item(info->menu);
current_idx = item_index(current);
// Swap position with destination
int item_pos = item_index(item);
info->items[item_pos] = info->items[pos];
info->items[pos] = item;
set_menu_items(info->menu, info->items);
}
// Check actions for this key
while ((action = key_find_action(key, action)) != ERR) {
// Check if we handle this action
switch (action) {
case ACTION_DOWN:
menu_driver(info->menu, REQ_DOWN_ITEM);
break;
case ACTION_UP:
menu_driver(info->menu, REQ_UP_ITEM);
break;
case ACTION_NPAGE:
menu_driver(info->menu, REQ_SCR_DPAGE);
break;
case ACTION_PPAGE:
menu_driver(info->menu, REQ_SCR_UPAGE);
break;
case ACTION_SELECT:
column_select_toggle_item(ui, current);
column_select_update_menu(ui);
break;
case ACTION_COLUMN_MOVE_DOWN:
column_select_move_item(ui, current, current_idx + 1);
column_select_update_menu(ui);
break;
case ACTION_COLUMN_MOVE_UP:
column_select_move_item(ui, current, current_idx - 1);
column_select_update_menu(ui);
break;
case ACTION_NEXT_FIELD:
info->form_active = 1;
set_menu_fore(info->menu, COLOR_PAIR(CP_DEFAULT));
set_field_back(info->fields[FLD_COLUMNS_ACCEPT], A_REVERSE);
form_driver(info->form, REQ_VALIDATION);
break;
case ACTION_CONFIRM:
column_select_update_columns(ui);
return KEY_DESTROY;
default:
// Parse next action
continue;
}
void
column_select_toggle_item(Window *ui, ITEM *item)
{
// Get panel information
column_select_info_t *info = column_select_info(ui);
int pos = item_index(item);
// Change item name
if (!strncmp(item_name(item), "[ ]", 3)) {
info->items[pos] = new_item("[*]", item_description(item));
} else {
info->items[pos] = new_item("[ ]", item_description(item));
// This panel has handled the key successfully
break;
}
// Restore menu item
set_item_userptr(info->items[pos], item_userptr(item));
set_menu_items(info->menu, info->items);
// Draw a scrollbar to the right
info->scroll.pos = (guint) top_row(info->menu);
ui_scrollbar_draw(info->scroll);
wnoutrefresh(info->menu_win);
// Destroy old item
free_item(item);
// Return if this panel has handled or not the key
return (action == ERR) ? KEY_NOT_HANDLED : KEY_HANDLED;
}
/**
* @brief Manage pressed keys for column selection panel
*
* This function will handle keys when form is active.
* You can switch between menu and rest of the components
* using TAB
*
* @param ui UI structure pointer
* @param key key code
* @return enum @key_handler_ret
*/
static int
column_select_handle_key_form(Window *ui, int key)
{
int field_idx, new_field_idx;
char field_value[48];
int action = -1;
// Get panel information
ColumnSelectInfo *info = column_select_info(ui);
g_return_val_if_fail(info != NULL, KEY_DESTROY);
// Get current field id
field_idx = field_index(current_field(info->form));
// Get current field value.
memset(field_value, 0, sizeof(field_value));
strcpy(field_value, field_buffer(current_field(info->form), 0));
g_strstrip(field_value);
// Check actions for this key
while ((action = key_find_action(key, action)) != ERR) {
// Check if we handle this action
switch (action) {
case ACTION_RIGHT:
case ACTION_NEXT_FIELD:
form_driver(info->form, REQ_NEXT_FIELD);
break;
case ACTION_LEFT:
case ACTION_PREV_FIELD:
form_driver(info->form, REQ_PREV_FIELD);
break;
case ACTION_SELECT:
case ACTION_CONFIRM:
switch(field_idx) {
case FLD_COLUMNS_ACCEPT:
column_select_update_columns(ui);
return KEY_DESTROY;
case FLD_COLUMNS_CANCEL:
return KEY_DESTROY;
case FLD_COLUMNS_SAVE:
column_select_update_columns(ui);
column_select_save_columns(ui);
return KEY_DESTROY;
default:break;
}
break;
default:
// Parse next action
continue;
}
// This panel has handled the key successfully
break;
}
// Validate all input data
form_driver(info->form, REQ_VALIDATION);
// Change background and cursor of "button fields"
set_field_back(info->fields[FLD_COLUMNS_ACCEPT], A_NORMAL);
set_field_back(info->fields[FLD_COLUMNS_SAVE], A_NORMAL);
set_field_back(info->fields[FLD_COLUMNS_CANCEL], A_NORMAL);
// Get current selected field
new_field_idx = field_index(current_field(info->form));
// Swap between menu and form
if (field_idx == FLD_COLUMNS_CANCEL && new_field_idx == FLD_COLUMNS_ACCEPT) {
set_menu_fore(info->menu, COLOR_PAIR(CP_DEF_ON_BLUE));
info->form_active = 0;
} else {
// Change current field background
set_field_back(info->fields[new_field_idx], A_REVERSE);
}
// Return if this panel has handled or not the key
return (action == ERR) ? KEY_NOT_HANDLED : KEY_HANDLED;
}
/**
* @brief Manage pressed keys for column selection panel
*
* This function is called by UI manager every time a
* key is pressed. This allow the filter panel to manage
* its own keys.
*
* @param window UI structure pointer
* @param key key code
* @return enum @key_handler_ret
*/
static int
column_select_handle_key(Window *window, int key)
{
// Get panel information
ColumnSelectInfo *info = column_select_info(window);
g_return_val_if_fail(info != NULL, KEY_DESTROY);
if (info->form_active) {
return column_select_handle_key_form(window, key);
} else {
return column_select_handle_key_menu(window, key);
}
}
void
column_select_update_menu(Window *ui)
column_select_set_columns(Window *window, GPtrArray *columns)
{
// Get panel information
column_select_info_t *info = column_select_info(ui);
ITEM *current = current_item(info->menu);
int top_idx = top_row(info->menu);
ColumnSelectInfo *info = column_select_info(window);
g_return_if_fail(info != NULL);
// Remove the menu from the subwindow
// Set selected column array
info->selected = columns;
// Toggle current enabled fields and move them to the top
for (guint i = 0; i < g_ptr_array_len(info->selected); i++) {
CallListColumn *column = g_ptr_array_index(info->selected, i);
for (guint attr_id = 0; attr_id < (guint) item_count(info->menu); attr_id++) {
if (!strcmp(item_userptr(info->items[attr_id]), column->attr)) {
column_select_toggle_item(window, info->items[attr_id]);
column_select_update_menu(window);
column_select_move_item(window, info->items[attr_id], i);
column_select_update_menu(window);
break;
}
}
}
}
/**
* @brief Destroy column selection panel
*
* This function do the final cleanups for this panel
*
* @param ui UI structure pointer
*/
void
column_select_free(Window *ui)
{
int i;
ColumnSelectInfo *info = column_select_info(ui);
// Remove menu and items
unpost_menu(info->menu);
// Set menu items
set_menu_items(info->menu, info->items);
// Put the menu agin into its subwindow
free_menu(info->menu);
for (i = 0; i < SIP_ATTR_COUNT; i++)
free_item(info->items[i]);
// Remove form and fields
unpost_form(info->form);
free_form(info->form);
for (i = 0; i < FLD_COLUMNS_COUNT; i++)
free_field(info->fields[i]);
g_free(info);
// Remove panel window and custom info
window_deinit(ui);
}
Window *
column_select_new()
{
Window *window = g_malloc0(sizeof(Window));
window->type = WINDOW_COLUMN_SELECT;
window->handle_key = column_select_handle_key;
window->destroy = column_select_free;
// Cerate a new indow for the panel and form
window_init(window, 20, 60);
// Initialize Filter panel specific data
ColumnSelectInfo *info = g_malloc0(sizeof(ColumnSelectInfo));
set_panel_userptr(window->panel, (void*) info);
// Initialize attributes
info->form_active = FALSE;
// Initialize the fields
info->fields[FLD_COLUMNS_ACCEPT] = new_field(1, 10, window->height - 2, 13, 0, 0);
info->fields[FLD_COLUMNS_SAVE] = new_field(1, 10, window->height - 2, 25, 0, 0);
info->fields[FLD_COLUMNS_CANCEL] = new_field(1, 10, window->height - 2, 37, 0, 0);
info->fields[FLD_COLUMNS_COUNT] = NULL;
// Field Labels
set_field_buffer(info->fields[FLD_COLUMNS_ACCEPT], 0, "[ Accept ]");
set_field_buffer(info->fields[FLD_COLUMNS_SAVE], 0, "[ Save ]");
set_field_buffer(info->fields[FLD_COLUMNS_CANCEL], 0, "[ Cancel ]");
// Create the form and post it
info->form = new_form(info->fields);
set_form_sub(info->form, window->win);
post_form(info->form);
// Create a subwin for the menu area
info->menu_win = derwin(window->win, 10, window->width - 2, 7, 0);
// Initialize one field for each attribute
for (guint attr_id = 0; attr_id < SIP_ATTR_COUNT; attr_id++) {
// Create a new field for this column
info->items[attr_id] = new_item("[ ]", sip_attr_get_description(attr_id));
set_item_userptr(info->items[attr_id], (void*) sip_attr_get_name(attr_id));
}
info->items[SIP_ATTR_COUNT] = NULL;
// Create the columns menu and post it
info->menu = new_menu(info->items);
// Set main window and sub window
set_menu_win(info->menu, window->win);
set_menu_sub(info->menu, derwin(window->win, 10, window->width - 5, 7, 2));
set_menu_format(info->menu, 10, 1);
set_menu_mark(info->menu, "");
set_menu_fore(info->menu, COLOR_PAIR(CP_DEF_ON_BLUE));
menu_opts_off(info->menu, O_ONEVALUE);
post_menu(info->menu);
// Move until the current position is set
set_top_row(info->menu, top_idx);
set_current_item(info->menu, current);
// Draw a scrollbar to the right
info->scroll = ui_set_scrollbar(info->menu_win, SB_VERTICAL, SB_RIGHT);
info->scroll.max = (guint) (item_count(info->menu) - 1);
ui_scrollbar_draw(info->scroll);
// Force menu redraw
menu_driver(info->menu, REQ_UP_ITEM);
menu_driver(info->menu, REQ_DOWN_ITEM);
// Set the window title and boxes
mvwprintw(window->win, 1, window->width / 2 - 14, "Call List columns selection");
wattron(window->win, COLOR_PAIR(CP_BLUE_ON_DEF));
title_foot_box(window->panel);
mvwhline(window->win, 6, 1, ACS_HLINE, window->width - 1);
mvwaddch(window->win, 6, 0, ACS_LTEE);
mvwaddch(window->win, 6, window->width - 1, ACS_RTEE);
wattroff(window->win, COLOR_PAIR(CP_BLUE_ON_DEF));
// Some brief explanation abotu what window shows
wattron(window->win, COLOR_PAIR(CP_CYAN_ON_DEF));
mvwprintw(window->win, 3, 2, "This windows show the list of columns displayed on Call");
mvwprintw(window->win, 4, 2, "List. You can enable/disable using Space Bar and reorder");
mvwprintw(window->win, 5, 2, "them using + and - keys.");
wattroff(window->win, COLOR_PAIR(CP_CYAN_ON_DEF));
return window;
}

View File

@ -0,0 +1,98 @@
/**************************************************************************
**
** sngrep - SIP Messages flow viewer
**
** Copyright (C) 2013-2018 Ivan Alonso (Kaian)
** Copyright (C) 2013-2018 Irontec SL. All rights reserved.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/
/**
* @file ui_column_select.h
* @author Ivan Alonso [aka Kaian] <kaian@irontec.com>
*
* @brief Functions to manage columns select panel
*/
#ifndef __UI_COLUMN_SELECT_H
#define __UI_COLUMN_SELECT_H
#include "config.h"
#include <menu.h>
#include <form.h>
#include "ncurses/ui_manager.h"
#include "ncurses/scrollbar.h"
#include "sip_attr.h"
/**
* @brief Enum of available fields
*/
enum ColumnSelectFields {
FLD_COLUMNS_ACCEPT = 0,
FLD_COLUMNS_SAVE,
FLD_COLUMNS_CANCEL,
//! Never remove this field id
FLD_COLUMNS_COUNT
};
//! Sorter declaration of struct columns_select_info
typedef struct _ColumnSelectInfo ColumnSelectInfo;
/**
* @brief Column selector panel private information
*
* This structure contains the durable data of column selection panel.
*/
struct _ColumnSelectInfo {
//! Section of panel where menu is being displayed
WINDOW *menu_win;
//! Columns menu
MENU *menu;
// Columns Items
ITEM *items[SIP_ATTR_COUNT + 1];
//! Current selected columns
GPtrArray *selected;
//! Form that contains the save fields
FORM *form;
//! An array of window form fields
FIELD *fields[FLD_COLUMNS_COUNT + 1];
//! Flag to handle key inputs
gboolean form_active;
//! Scrollbar for the menu window
scrollbar_t scroll;
};
/**
* @brief Creates a new column selection window
*
* This function allocates all required memory for
* displaying the column selection window. It also draws all the
* static information of the panel that will never be
* redrawn.
*
* @return Window UI structure pointer
*/
Window *
column_select_new();
/**
* @brief Set Column array to be updated
* @param columns Array of currect active columns
*/
void
column_select_set_columns(Window *window, GPtrArray *columns);
#endif /* __UI_COLUMN_SELECT_H */

View File

@ -1299,7 +1299,7 @@ call_flow_set_group(SipCallGroup *group)
Window *ui;
call_flow_info_t *info;
if (!(ui = ui_find_by_type(PANEL_CALL_FLOW)))
if (!(ui = ncurses_find_by_type(PANEL_CALL_FLOW)))
return -1;
if (!(info = call_flow_info(ui)))

View File

@ -270,7 +270,7 @@ call_raw_handle_key(Window *ui, int key)
case ACTION_TOGGLE_SYNTAX:
case ACTION_CYCLE_COLOR:
// Handle colors using default handler
ui_default_handle_key(ui, key);
ncurses_default_keyhandler(ui, key);
// Create a new pad (forces messages draw)
delwin(info->pad);
info->pad = newpad(500, COLS);
@ -315,7 +315,7 @@ call_raw_set_group(SipCallGroup *group)
if (!group)
return -1;
if (!(ui = ui_find_by_type(PANEL_CALL_RAW)))
if (!(ui = ncurses_find_by_type(PANEL_CALL_RAW)))
return -1;
if (!(info = call_raw_info(ui)))
@ -341,7 +341,7 @@ call_raw_set_msg(SipMsg *msg)
if (!msg)
return -1;
if (!(ui = ui_find_by_type(PANEL_CALL_RAW)))
if (!(ui = ncurses_find_by_type(PANEL_CALL_RAW)))
return -1;
if (!(info = call_raw_info(ui)))

View File

@ -1,209 +0,0 @@
/**************************************************************************
**
** sngrep - SIP Messages flow viewer
**
** Copyright (C) 2013-2018 Ivan Alonso (Kaian)
** Copyright (C) 2013-2018 Irontec SL. All rights reserved.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/
/**
* @file ui_column_select.h
* @author Ivan Alonso [aka Kaian] <kaian@irontec.com>
*
* @brief Functions to manage columns select panel
*/
#ifndef __UI_COLUMN_SELECT_H
#define __UI_COLUMN_SELECT_H
#include "config.h"
#include <menu.h>
#include <form.h>
#include "ncurses/ui_manager.h"
#include "ncurses/scrollbar.h"
#include "sip_attr.h"
/**
* @brief Enum of available fields
*/
enum column_select_field_list {
FLD_COLUMNS_ACCEPT = 0,
FLD_COLUMNS_SAVE,
FLD_COLUMNS_CANCEL,
//! Never remove this field id
FLD_COLUMNS_COUNT
};
//! Sorter declaration of struct columns_select_info
typedef struct column_select_info column_select_info_t;
/**
* @brief Column selector panel private information
*
* This structure contains the durable data of column selection panel.
*/
struct column_select_info {
// Section of panel where menu is being displayed
WINDOW *menu_win;
// Columns menu
MENU *menu;
// Columns Items
ITEM *items[SIP_ATTR_COUNT + 1];
//! Form that contains the save fields
FORM *form;
//! An array of window form fields
FIELD *fields[FLD_COLUMNS_COUNT + 1];
//! Flag to handle key inputs
int form_active;
//! Scrollbar for the menu window
scrollbar_t scroll;
};
/**
* @brief Creates a new column selection panel
*
* This function allocates all required memory for
* displaying the column selection panel. It also draws all the
* static information of the panel that will never be
* redrawn.
*
* @param ui UI structure pointer
*/
void
column_select_create(Window *ui);
/**
* @brief Destroy column selection panel
*
* This function do the final cleanups for this panel
*
* @param ui UI structure pointer
*/
void
column_select_destroy(Window *ui);
/**
* @brief Get custom information of given panel
*
* Return ncurses users pointer of the given panel into panel's
* information structure pointer.
*
* @param ui UI structure pointer
* @return a pointer to info structure of given panel
*/
column_select_info_t *
column_select_info(Window *ui);
/**
* @brief Manage pressed keys for column selection panel
*
* This function is called by UI manager every time a
* key is pressed. This allow the filter panel to manage
* its own keys.
*
* @param ui UI structure pointer
* @param key key code
* @return enum @key_handler_ret
*/
int
column_select_handle_key(Window *ui, int key);
/**
* @brief Manage pressed keys for column selection panel
*
* This function will handle keys when menu is active.
* You can switch between menu and rest of the components
* using TAB
*
* @param ui UI structure pointer
* @param key key code
* @return enum @key_handler_ret
*/
int
column_select_handle_key_menu(Window *ui, int key);
/**
* @brief Manage pressed keys for column selection panel
*
* This function will handle keys when form is active.
* You can switch between menu and rest of the components
* using TAB
*
* @param ui UI structure pointer
* @param key key code
* @return enum @key_handler_ret
*/
int
column_select_handle_key_form(Window *ui, int key);
/**
* @brief Update Call List columns
*
* This function will update the columns of Call List
*
* @param ui UI structure pointer
*/
void
column_select_update_columns(Window *ui);
/**
* @brief Save selected columns to user config file
*
* Remove previously configurated columns from user's
* $SNGREPRC or $HOME/.sngreprc and add new ones
*
* @param ui UI structure pointer
*/
void
column_select_save_columns(Window *ui);
/**
* @brief Move a item to a new position
*
* This function can be used to reorder the column list
*
* @param ui UI structure pointer
* @param item Menu item to be moved
* @param post New position in the menu
*/
void
column_select_move_item(Window *ui, ITEM *item, int pos);
/**
* @brief Select/Deselect a menu item
*
* This function can be used to toggle selection status of
* the menu item
*
* @param ui UI structure pointer
* @param item Menu item to be (de)selected
*/
void
column_select_toggle_item(Window *ui, ITEM *item);
/**
* @brief Update menu after a change
*
* After moving an item or updating its selectioactivn status
* menu must be redrawn.
*
* @param ui UI structure pointer
*/
void
column_select_update_menu(Window *ui);
#endif /* __UI_COLUMN_SELECT_H */

View File

@ -394,7 +394,7 @@ filter_save_options(Window *ui)
// Force filter evaluation
filter_reset_calls();
// TODO FIXME Refresh call list FIXME
call_list_clear(ui_find_by_type(WINDOW_CALL_LIST));
call_list_clear(ncurses_find_by_type(WINDOW_CALL_LIST));
}

View File

@ -41,7 +41,7 @@
#include "ncurses/ui_call_raw.h"
#include "ncurses/ui_filter.h"
#include "ncurses/ui_msg_diff.h"
#include "ncurses/ui_column_select.h"
#include "ncurses/column_select.h"
#include "ncurses/ui_save.h"
#include "ncurses/ui_settings.h"
@ -58,7 +58,6 @@ static Window *panel_pool[] = {
&ui_filter,
&ui_save,
&ui_msg_diff,
&ui_column_select,
&ui_settings,
&ui_stats
};
@ -160,7 +159,16 @@ Window *
ncurses_create_window(enum WindowTypes type)
{
// Find the panel of given type and create it
return ui_create(ui_find_by_type(type));
return ui_create(ncurses_find_by_type(type));
}
void
ncurses_destroy_window(Window *window)
{
// Remove from the window list
g_ptr_array_remove(windows, window);
// Deallocate window memory
ui_destroy(window);
}
static gboolean
@ -176,7 +184,7 @@ ncurses_window_type_cmp(Window *window, gpointer type)
}
Window *
ui_find_by_panel(PANEL *panel)
ncurses_find_by_panel(PANEL *panel)
{
guint index;
if (g_ptr_array_find_with_equal_func(windows, panel,
@ -195,7 +203,7 @@ ui_find_by_panel(PANEL *panel)
}
Window *
ui_find_by_type(enum WindowTypes type)
ncurses_find_by_type(enum WindowTypes type)
{
int i;
@ -212,6 +220,13 @@ ui_find_by_type(enum WindowTypes type)
return window;
}
if (type == WINDOW_COLUMN_SELECT) {
Window *window = column_select_new();
g_ptr_array_add(windows, window);
return window;
}
// Return ui pointer if found
for (i = 0; i < PANEL_COUNT; i++) {
if (panel_pool[i]->type == type)
@ -231,7 +246,7 @@ ui_wait_for_input()
while ((panel = panel_below(NULL))) {
// Get panel interface structure
ui = ui_find_by_panel(panel);
ui = ncurses_find_by_panel(panel);
// Set character input timeout 200 ms
halfdelay(REFRESHTHSECS);
@ -278,12 +293,15 @@ ui_wait_for_input()
continue;
} else if (hld == KEY_PROPAGATED) {
// Destroy current panel
ui_destroy(ui);
ncurses_destroy_window(ui);
// Try to handle this key with the previus panel
ui = ui_find_by_panel(panel_below(NULL));
ui = ncurses_find_by_panel(panel_below(NULL));
} else if (hld == KEY_DESTROY) {
ncurses_destroy_window(ui);
break;
} else {
// Key not handled by UI nor propagated. Use default handler
hld = ui_default_handle_key(ui, c);
hld = ncurses_default_keyhandler(ui, c);
}
}
capture_unlock(capture_manager());
@ -293,7 +311,7 @@ ui_wait_for_input()
}
int
ui_default_handle_key(Window *ui, int key)
ncurses_default_keyhandler(Window *window, int key)
{
int action = -1;
@ -324,10 +342,10 @@ ui_default_handle_key(Window *ui, int key)
capture_manager()->paused = !capture_manager()->paused;
break;
case ACTION_SHOW_HELP:
ui_help(ui);
ui_help(window);
break;
case ACTION_PREV_SCREEN:
ui_destroy(ui);
ncurses_destroy_window(window);
break;
default:
// Parse next action
@ -349,7 +367,7 @@ ui_resize_panels()
// While there are still panels
while ((panel = panel_below(panel))) {
// Invoke resize for this panel
ui_resize_panel(ui_find_by_panel(panel));
ui_resize_panel(ncurses_find_by_panel(panel));
}
}

View File

@ -57,7 +57,6 @@ extern Window ui_call_raw;
extern Window ui_filter;
extern Window ui_save;
extern Window ui_msg_diff;
extern Window ui_column_select;
extern Window ui_settings;
extern Window ui_stats;
@ -98,13 +97,13 @@ ncurses_create_window(enum WindowTypes type);
* @brief Find a ui from its pannel pointer
*/
Window *
ui_find_by_panel(PANEL *panel);
ncurses_find_by_panel(PANEL *panel);
/**
* @brief Find a ui form its panel id
*/
Window *
ui_find_by_type(enum WindowTypes type);
ncurses_find_by_type(enum WindowTypes type);
/**
* @brief Wait for user input in topmost panel
@ -122,11 +121,11 @@ ui_wait_for_input();
* If ui doesn't handle the given key (ui_handle_key returns the key value)
* then the default handler will be invoked
*
* @param ui Current displayed UI structure
* @param window Current displayed UI structure
* @param key key pressed by user
*/
int
ui_default_handle_key(Window *ui, int key);
ncurses_default_keyhandler(Window *window, int key);
/**
* @brief Call Resize function in all panels in the stack

View File

@ -43,7 +43,9 @@ enum key_handler_ret {
//! Panel has not handled the key, try defualt key handler
KEY_NOT_HANDLED = -1,
//! Panel destroys and requests previous panel to handle key
KEY_PROPAGATED = -2
KEY_PROPAGATED = -2,
//! Panel request destroy
KEY_DESTROY = -3
};
/**
@ -65,7 +67,7 @@ enum WindowTypes {
//! Message comprare
PANEL_MSG_DIFF,
//! Column selector panel
PANEL_COLUMN_SELECT,
WINDOW_COLUMN_SELECT,
//! Settings panel
PANEL_SETTINGS,
//! Stats panel