forked from Mirrors/sngrep
cs: refactorize column select screen
This commit is contained in:
parent
911d0a2c38
commit
c5d8526c26
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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)))
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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 */
|
|
@ -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));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue