Ejemplo n.º 1
0
int
default_handle_key(ui_t *ui, int key)
{
    int action = -1;

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_RESIZE_SCREEN:
                ui_resize_panel(ui);
                break;
            case ACTION_TOGGLE_SYNTAX:
                setting_toggle(SETTING_SYNTAX);
                break;
            case ACTION_TOGGLE_HINT:
                setting_toggle(SETTING_ALTKEY_HINT);
                break;
            case ACTION_CYCLE_COLOR:
                setting_toggle(SETTING_COLORMODE);
                break;
            case ACTION_SHOW_HOSTNAMES:
                setting_toggle(SETTING_DISPLAY_HOST);
                break;
            case ACTION_SHOW_ALIAS:
                setting_toggle(SETTING_DISPLAY_ALIAS);
                break;
            case ACTION_SHOW_SETTINGS:
                ui_create_panel(PANEL_SETTINGS);
                break;
            case ACTION_TOGGLE_PAUSE:
                // Pause/Resume capture
                capture_set_paused(!capture_is_paused());
                break;
            case ACTION_SHOW_HELP:
                ui_help(ui);
                break;
            case ACTION_PREV_SCREEN:
                ui_destroy(ui);
                break;
            default:
                // Parse next action
                continue;
        }
        // Default handler has handled the key
        break;
    }

    // Return this is a valid handled key
    return (action == ERR) ? key : 0;
}
Ejemplo n.º 2
0
int
call_raw_handle_key(PANEL *panel, int key)
{
    call_raw_info_t *info;
    ui_t *next_panel;
    int rnpag_steps = setting_get_intvalue(SETTING_CR_SCROLLSTEP);
    int action = -1;

    // Sanity check, this should not happen
    if (!(info  = call_raw_info(panel)))
        return -1;

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_DOWN:
                info->scroll++;
                break;
            case ACTION_UP:
                info->scroll--;
                break;
            case ACTION_HNPAGE:
                rnpag_steps = rnpag_steps / 2;
                /* no break */
            case ACTION_NPAGE:
                // Next page => N key down strokes
                info->scroll += rnpag_steps;
                break;
            case ACTION_HPPAGE:
                rnpag_steps = rnpag_steps / 2;
                /* no break */
            case ACTION_PPAGE:
                // Prev page => N key up strokes
                info->scroll -= rnpag_steps;
                break;
            case ACTION_SHOW_HOSTNAMES:
                // Tooggle Host/Address display
                setting_toggle(SETTING_DISPLAY_HOST);
                // Force refresh panel
                if (info->group) {
                    call_raw_set_group(info->group);
                } else {
                    call_raw_set_msg(info->msg);
                }
                break;
            case ACTION_SAVE:
                if (info->group) {
                    // KEY_S, Display save panel
                    next_panel = ui_create_panel(PANEL_SAVE);
                    save_set_group(ui_get_panel(next_panel), info->group);
                }
                break;
            case ACTION_TOGGLE_SYNTAX:
            case ACTION_CYCLE_COLOR:
                // Handle colors using default handler
                default_handle_key(ui_find_by_panel(panel), key);
                // Create a new pad (forces messages draw)
                delwin(info->pad);
                info->pad = newpad(500, COLS);
                info->last = NULL;
                // Force refresh panel
                if (info->group) {
                    call_raw_set_group(info->group);
                } else {
                    call_raw_set_msg(info->msg);
                }
                break;
            default:
                // Parse next action
                continue;
        }

        // This panel has handled the key successfully
        break;
    }

    if (info->scroll < 0 || info->padline < LINES) {
        info->scroll = 0;   // Disable scrolling if there's nothing to scroll
    } else {
        if (info->scroll + LINES / 2 > info->padline)
            info->scroll = info->padline - LINES / 2;
    }

    // Return if this panel has handled or not the key
    return (action == ERR) ? key : 0;
}
Ejemplo n.º 3
0
int
column_select_handle_key_form(ui_t *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));
    strtrim(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;
}
Ejemplo n.º 4
0
int
column_select_handle_key_menu(ui_t *ui, int key)
{
    MENU *menu;
    ITEM *current;
    int current_idx;
    int action = -1;

    // Get panel information
    column_select_info_t *info = column_select_info(ui);

    menu = info->menu;
    current = current_item(menu);
    current_idx = item_index(current);

    // 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;
        }

        // 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;
}
Ejemplo n.º 5
0
int
save_raw_handle_key(PANEL *panel, int key)
{
    int field_idx;
    char field_value[48];
    int action = -1;

    // Get panel information
    save_raw_info_t *info = (save_raw_info_t*) panel_userptr(panel);

    // Get current field id
    field_idx = field_index(current_field(info->form));

    // Get current field value.
    // We trim spaces with sscanf because and empty field is stored as
    // space characters
    memset(field_value, 0, sizeof(field_value));
    sscanf(field_buffer(current_field(info->form), 0), "%[^ ]", 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_PRINTABLE:
                if (field_idx == FLD_SAVE_RAW_SAVE)
                    form_driver(info->form, key);
                break;
            case ACTION_NEXT_FIELD:
                form_driver(info->form, REQ_NEXT_FIELD);
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_PREV_FIELD:
                form_driver(info->form, REQ_PREV_FIELD);
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_RIGHT:
                form_driver(info->form, REQ_RIGHT_CHAR);
                break;
            case ACTION_LEFT:
                form_driver(info->form, REQ_LEFT_CHAR);
                break;
            case ACTION_BEGIN:
                form_driver(info->form, REQ_BEG_LINE);
                break;
            case ACTION_END:
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_DELETE:
                form_driver(info->form, REQ_DEL_CHAR);
                break;
            case ACTION_BACKSPACE:
                if (strlen(field_value) > 0)
                    form_driver(info->form, REQ_DEL_PREV);
                break;
            case ACTION_CLEAR:
                form_driver(info->form, REQ_CLR_FIELD);
                break;
            case ACTION_CONFIRM:
                if (field_idx != FLD_SAVE_RAW_CANCEL) {
                    if (!strcasecmp(field_value, "")) {
                        save_raw_error_message(panel, "Invalid filename");
                        return 0;
                    }
                    return save_raw_to_file(panel);
                }
                return 27;
            default:
                // Parse next action
                continue;
        }

        // We've handled this key, stop checking actions
        break;
    }

    // Validate all input data
    form_driver(info->form, REQ_VALIDATION);

    // Change background and cursor of "button fields"
    set_field_back(info->fields[FLD_SAVE_RAW_SAVE], A_NORMAL);
    set_field_back(info->fields[FLD_SAVE_RAW_CANCEL], A_NORMAL);
    curs_set(1);

    // Change current field background
    field_idx = field_index(current_field(info->form));
    if (field_idx == FLD_SAVE_RAW_SAVE || field_idx == FLD_SAVE_RAW_CANCEL) {
        set_field_back(info->fields[field_idx], A_REVERSE);
        curs_set(0);
    }

    // Return if this panel has handled or not the key
    return (action == ERR) ? key : 0;
}
Ejemplo n.º 6
0
int
call_list_handle_form_key(PANEL *panel, int key)
{
    int field_idx;
    char dfilter[256];
    int action = -1;

    // Get panel information
    call_list_info_t *info = call_list_info(panel);

    // Get current field id
    field_idx = field_index(current_field(info->form));

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_PRINTABLE:
                // If this is a normal character on input field, print it
                form_driver(info->form, key);
                break;
            case ACTION_PREV_SCREEN:
            case ACTION_NEXT_FIELD:
            case ACTION_CONFIRM:
            case ACTION_SELECT:
            case ACTION_UP:
            case ACTION_DOWN:
                // Activate list
                call_list_form_activate(panel, 0);
                break;
            case ACTION_RIGHT:
                form_driver(info->form, REQ_RIGHT_CHAR);
                break;
            case ACTION_LEFT:
                form_driver(info->form, REQ_LEFT_CHAR);
                break;
            case ACTION_BEGIN:
                form_driver(info->form, REQ_BEG_LINE);
                break;
            case ACTION_END:
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_CLEAR:
                form_driver(info->form, REQ_BEG_LINE);
                form_driver(info->form, REQ_CLR_EOL);
                break;
            case ACTION_DELETE:
                form_driver(info->form, REQ_DEL_CHAR);
                break;
            case ACTION_BACKSPACE:
                form_driver(info->form, REQ_DEL_PREV);
                break;
            default:
                // Parse next action
                continue;
        }

        // We've handled this key, stop checking actions
        break;
    }

    // Filter has changed, re-apply filter to displayed calls
    if (action == ACTION_PRINTABLE || action == ACTION_BACKSPACE ||
            action == ACTION_DELETE || action == ACTION_CLEAR) {
        // Updated displayed results
         call_list_clear(panel);
         // Reset filters on each key stroke
         filter_reset_calls();
    }

    // Validate all input data
    form_driver(info->form, REQ_VALIDATION);

    // Store dfilter input
    // We trim spaces with sscanf because and empty field is stored as space characters
    memset(dfilter, 0, sizeof(dfilter));
    strcpy(dfilter, field_buffer(info->fields[FLD_LIST_FILTER], 0));
    strtrim(dfilter);

    // Set display filter
    filter_set(FILTER_CALL_LIST, strlen(dfilter) ? dfilter : NULL);

    // Return if this panel has handled or not the key
    return (action == ERR) ? key : 0;
}
Ejemplo n.º 7
0
int
call_list_handle_key(PANEL *panel, int key)
{
    int i, height, width, rnpag_steps = setting_get_intvalue(SETTING_CL_SCROLLSTEP);
    call_list_info_t *info;
    ui_t *next_panel;
    sip_call_group_t *group;
    int action = -1;
    sip_call_t *call;

    // Sanity check, this should not happen
    if (!(info  = call_list_info(panel)))
        return -1;

    // Handle form key
    if (info->form_active)
        return call_list_handle_form_key(panel, key);

    // Get window of call list panel
    WINDOW *win = info->list_win;
    getmaxyx(win, height, width);

    // Reset iterator position to current call
    vector_iterator_set_current(&info->calls, info->cur_call);

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_DOWN:
                // Check if there is a call below us
                if (!vector_iterator_next(&info->calls))
                    break;
                info->cur_call = vector_iterator_current(&info->calls);
                info->cur_line++;
                // If we are out of the bottom of the displayed list
                // refresh it starting in the next call
                if (info->cur_line > height) {
                    vector_iterator_set_current(&info->calls, info->first_call);
                    vector_iterator_next(&info->calls);
                    info->first_call = vector_iterator_current(&info->calls);
                    info->first_line++;
                    info->cur_line = height;
                }
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_UP:
                // Check if there is a call above us
                if (!vector_iterator_prev(&info->calls))
                    break;
                info->cur_call = vector_iterator_current(&info->calls);
                info->cur_line--;
                // If we are out of the top of the displayed list
                // refresh it starting in the previous (in fact current) call
                if (info->cur_line <= 0) {
                    info->first_call = info->cur_call;
                    info->first_line--;
                    info->cur_line = 1;
                }
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_HNPAGE:
                rnpag_steps = rnpag_steps / 2;
                /* no break */
            case ACTION_NPAGE:
                // Next page => N key down strokes
                for (i = 0; i < rnpag_steps; i++)
                    call_list_handle_key(panel, KEY_DOWN);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_HPPAGE:
                rnpag_steps = rnpag_steps / 2;
                /* no break */
            case ACTION_PPAGE:
                // Prev page => N key up strokes
                for (i = 0; i < rnpag_steps; i++)
                    call_list_handle_key(panel, KEY_UP);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_BEGIN:
                // Initialize structures
                info->first_call = info->cur_call = -1;
                info->first_line = info->cur_line = 0;
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_END:
                // Check if there is a call below us
                while (vector_iterator_next(&info->calls)) {
                    info->cur_call = vector_iterator_current(&info->calls);
                    info->cur_line++;
                    // If we are out of the bottom of the displayed list
                    // refresh it starting in the next call
                    if (info->cur_line > height) {
                        vector_iterator_set_current(&info->calls, info->first_call);
                        vector_iterator_next(&info->calls);
                        info->first_call = vector_iterator_current(&info->calls);
                        info->first_line++;
                        info->cur_line = height;
                        vector_iterator_set_current(&info->calls, info->cur_call);
                    }
                }
                break;
            case ACTION_DISP_FILTER:
                // Activate Form
                call_list_form_activate(panel, 1);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_SHOW_FLOW:
            case ACTION_SHOW_FLOW_EX:
            case ACTION_SHOW_RAW:
                // Check we have calls in the list
                if (info->cur_call == -1)
                    break;
                // Create a new group of calls
                group = call_group_clone(info->group);
                // If not selected call, show current call flow
                if (call_group_count(info->group) == 0)
                    call_group_add(group, sip_find_by_index(info->cur_call));

                // Add xcall to the group
                if (action == ACTION_SHOW_FLOW_EX)
                    call_group_add(group, call_get_xcall(sip_find_by_index(info->cur_call)));

                if (action == ACTION_SHOW_RAW) {
                    // Create a Call Flow panel
                    ui_create_panel(PANEL_CALL_RAW);
                    call_raw_set_group(group);
                } else {
                    // Display current call flow (normal or extended)
                    ui_create_panel(PANEL_CALL_FLOW);
                    call_flow_set_group(group);
                }
                break;
            case ACTION_SHOW_FILTERS:
                ui_create_panel(PANEL_FILTER);
                break;
            case ACTION_SHOW_COLUMNS:
                ui_create_panel(PANEL_COLUMN_SELECT);
                break;
            case ACTION_SHOW_STATS:
                ui_create_panel(PANEL_STATS);
                break;
            case ACTION_SAVE:
                next_panel = ui_create_panel(PANEL_SAVE);
                save_set_group(ui_get_panel(next_panel), info->group);
                break;
            case ACTION_CLEAR:
                // Clear group calls
                vector_clear(info->group->calls);
                break;
            case ACTION_CLEAR_CALLS:
                // Remove all stored calls
                sip_calls_clear();
                // Clear List
                call_list_clear(panel);
                break;
            case ACTION_AUTOSCROLL:
                info->autoscroll = (info->autoscroll) ? 0 : 1;
                break;
            case ACTION_SHOW_SETTINGS:
                ui_create_panel(PANEL_SETTINGS);
                break;
            case ACTION_SELECT:
                call = vector_item(vector_iterator_vector(&info->calls), info->cur_call);
                if (call_group_exists(info->group, call)) {
                    call_group_del(info->group, call);
                } else {
                    call_group_add(info->group, call);
                }
                break;
            case ACTION_PREV_SCREEN:
                // Handle quit from this screen unless requested
                if (setting_enabled(SETTING_EXITPROMPT)) {
                    if (dialog_confirm("Confirm exit", "Are you sure you want to quit?", "Yes,No") == 0) {
                        return KEY_ESC;
                    } else {
                        return 0;
                    }
                } else {
                    return KEY_ESC;
                }
                break;
            default:
                // Parse next action
                continue;
        }

        // This panel has handled the key successfully
        break;
    }

    // Return if this panel has handled or not the key
    return (action == ERR) ? key : 0;
}
Ejemplo n.º 8
0
int
filter_handle_key(PANEL *panel, int key)
{
    int field_idx;
    char field_value[30];
    int action = -1;

    // Get panel information
    filter_info_t *info = filter_info(panel);

    // Get current field id
    field_idx = field_index(current_field(info->form));

    // Get current field value.
    // We trim spaces with sscanf because and empty field is stored as
    // space characters
    memset(field_value, 0, sizeof(field_value));
    strcpy(field_value, field_buffer(current_field(info->form), 0));
    strtrim(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_PRINTABLE:
                // If this is a normal character on input field, print it
                if (field_idx == FLD_FILTER_SIPFROM || field_idx == FLD_FILTER_SIPTO
                    || field_idx == FLD_FILTER_SRC || field_idx == FLD_FILTER_DST
                    || field_idx == FLD_FILTER_PAYLOAD) {
                    form_driver(info->form, key);
                    break;
                }
                continue;
            case ACTION_NEXT_FIELD:
                form_driver(info->form, REQ_NEXT_FIELD);
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_PREV_FIELD:
                form_driver(info->form, REQ_PREV_FIELD);
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_RIGHT:
                form_driver(info->form, REQ_RIGHT_CHAR);
                break;
            case ACTION_LEFT:
                form_driver(info->form, REQ_LEFT_CHAR);
                break;
            case ACTION_BEGIN:
                form_driver(info->form, REQ_BEG_LINE);
                break;
            case ACTION_END:
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_CLEAR:
                form_driver(info->form, REQ_CLR_FIELD);
                break;
            case KEY_DC:
                form_driver(info->form, REQ_DEL_CHAR);
                break;
            case ACTION_DELETE:
                form_driver(info->form, REQ_DEL_CHAR);
                break;
            case ACTION_BACKSPACE:
                if (strlen(field_value) > 0)
                    form_driver(info->form, REQ_DEL_PREV);
                break;
            case ACTION_SELECT:
                switch (field_idx) {
                    case FLD_FILTER_REGISTER:
                    case FLD_FILTER_INVITE:
                    case FLD_FILTER_SUBSCRIBE:
                    case FLD_FILTER_NOTIFY:
                    case FLD_FILTER_OPTIONS:
                    case FLD_FILTER_PUBLISH:
                    case FLD_FILTER_MESSAGE:
                        if (field_value[0] == '*') {
                            form_driver(info->form, REQ_DEL_CHAR);
                        } else {
                            form_driver(info->form, '*');
                        }
                        break;
                    case FLD_FILTER_CANCEL:
                        return KEY_ESC;
                    case FLD_FILTER_FILTER:
                        filter_save_options(panel);
                        return KEY_ESC;
                }
                break;
            case ACTION_CONFIRM:
                if (field_idx != FLD_FILTER_CANCEL)
                    filter_save_options(panel);
                return KEY_ESC;
            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_FILTER_FILTER], A_NORMAL);
    set_field_back(info->fields[FLD_FILTER_CANCEL], A_NORMAL);
    curs_set(1);

    // Change current field background
    field_idx = field_index(current_field(info->form));
    if (field_idx == FLD_FILTER_FILTER || field_idx == FLD_FILTER_CANCEL) {
        set_field_back(info->fields[field_idx], A_REVERSE);
        curs_set(0);
    }

    // Return if this panel has handled or not the key
    return (action == ERR) ? key : 0;
}
Ejemplo n.º 9
0
int
save_handle_key(ui_t *ui, int key)
{
    int field_idx;
    int action = -1;

    // Get panel information
    save_info_t *info = save_info(ui);

    // Get current field id
    field_idx = field_index(current_field(info->form));

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_PRINTABLE:
                if (field_idx == FLD_SAVE_PATH || field_idx == FLD_SAVE_FILE) {
                    form_driver(info->form, key);
                    break;
                }
                continue;
            case ACTION_NEXT_FIELD:
                form_driver(info->form, REQ_NEXT_FIELD);
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_PREV_FIELD:
                form_driver(info->form, REQ_PREV_FIELD);
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_RIGHT:
                form_driver(info->form, REQ_RIGHT_CHAR);
                break;
            case ACTION_LEFT:
                form_driver(info->form, REQ_LEFT_CHAR);
                break;
            case ACTION_BEGIN:
                form_driver(info->form, REQ_BEG_LINE);
                break;
            case ACTION_END:
                form_driver(info->form, REQ_END_LINE);
                break;
            case ACTION_DELETE:
                form_driver(info->form, REQ_DEL_CHAR);
                break;
            case ACTION_BACKSPACE:
                form_driver(info->form, REQ_DEL_PREV);
                break;
            case ACTION_CLEAR:
                form_driver(info->form, REQ_CLR_FIELD);
                break;
            case ACTION_SELECT:
                switch (field_idx) {
                    case FLD_SAVE_ALL:
                        info->savemode = SAVE_ALL;
                        break;
                    case FLD_SAVE_SELECTED:
                        info->savemode = SAVE_SELECTED;
                        break;
                    case FLD_SAVE_DISPLAYED:
                        info->savemode = SAVE_DISPLAYED;
                        break;
                    case FLD_SAVE_MESSAGE:
                        info->savemode = SAVE_MESSAGE;
                        break;
                    case FLD_SAVE_PCAP:
                        info->saveformat = SAVE_PCAP;
                        break;
                    case FLD_SAVE_PCAP_RTP:
                        info->saveformat = SAVE_PCAP_RTP;
                        break;
                    case FLD_SAVE_TXT:
                        info->saveformat = SAVE_TXT;
                        break;
                    case FLD_SAVE_FILE:
                        form_driver(info->form, key);
                        break;
                    default:
                        break;
                }
                break;
            case ACTION_CONFIRM:
                if (field_idx != FLD_SAVE_CANCEL) {
                    save_to_file(ui);
                }
                ui_destroy(ui);
                return KEY_HANDLED;
            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_SAVE_SAVE], A_NORMAL);
    set_field_back(info->fields[FLD_SAVE_CANCEL], A_NORMAL);
    curs_set(1);

    // Change current field background
    field_idx = field_index(current_field(info->form));
    if (field_idx == FLD_SAVE_SAVE || field_idx == FLD_SAVE_CANCEL) {
        set_field_back(info->fields[field_idx], A_REVERSE);
        curs_set(0);
    }

    // Return if this panel has handled or not the key
    return (action == ERR) ? KEY_NOT_HANDLED : KEY_HANDLED;
}