"Fossies" - the Fresh Open Source Software archive 
Member "evms-2.5.5/ui/ncurses/menu.c" of archive evms-2.5.5.tar.gz:
/*
*
* (C) Copyright IBM Corp. 2002, 2003
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <glib.h>
#include <ncurses.h>
#include <panel.h>
#include <frontend.h>
#include "common.h"
#include "window.h"
#include "dlist.h"
#include "menu.h"
#include "dialog.h"
#include "clist.h"
#include "task.h"
#include "create.h"
#include "delete.h"
#include "add.h"
#include "modify.h"
#include "remove.h"
#include "replace.h"
#include "object.h"
#include "plugin.h"
#include "container.h"
#include "options.h"
#include "fsutils.h"
#include "views.h"
#include "create.h"
#include "convert.h"
#include "delete.h"
#include "resize.h"
#include "mount.h"
#include "volume.h"
#include "settings.h"
#include "save.h"
#include "callbacks.h"
#include "logging.h"
#include "activation.h"
#include "backup.h"
static WINDOW *menubar;
static WINDOW *statusbar;
static struct menu_item menubar_item[MENUBAR_ITEM_COUNT];
/**
* Since we don't destroy the action menus once created, we keep
* track of their popup_menu structures created here so we can
* show or hide them as necessary.
*/
static struct popup_menu *actions_menu = NULL;
static struct popup_menu *settings_menu = NULL;
static struct popup_menu *create_menu = NULL;
static struct popup_menu *delete_menu = NULL;
static struct popup_menu *activation_menu = NULL;
static struct popup_menu *expand_menu = NULL;
static struct popup_menu *shrink_menu = NULL;
static struct popup_menu *add_menu = NULL;
static struct popup_menu *remove_menu = NULL;
static struct popup_menu *modify_menu = NULL;
static struct popup_menu *view_menu = NULL;
static struct popup_menu *convert_menu = NULL;
static struct popup_menu *other_menu = NULL;
static struct popup_menu *fsys_menu = NULL;
/**
* get_accel_color - return the attribute/color for the accelerator character in a menu
* @win: the window that contains the menu
*
* This routine returns the proper color attribute for a menu depending on if the
* current color pair is for a selected menu item or the normal menu background.
*/
chtype get_accel_color(WINDOW *win)
{
short pair;
attr_t attrs;
chtype color;
wattr_get(win, &attrs, &pair, NULL);
if (pair == MENUSEL_COLOR) {
color = COLOR_PAIR(SELECTED_ACCEL_COLOR);
} else {
color = COLOR_PAIR(ACCEL_COLOR);
}
return color;
}
/**
* print_menu_item - prints a menu item with accelerator support
* @win: the window that is to contain the menu item
* @starty: the row to print the menu item at
* @startx: the column to print the menu item at
* @item: the address of the menu_item struct
*
* This routine uses the information in the given menu_item struct
* in order to display a menu item. The accelerator character
* (if any) is displayed brighter than the rest.
*/
void print_menu_item(WINDOW *win, int starty, int startx, struct menu_item *item)
{
if (MI_IS_VISIBLE(item->flags)) {
mvwaddstr(win, starty, startx, item->label);
if (MI_IS_SENSITIVE(item->flags) && item->accel != '\0') {
char *accel;
accel = strchr(item->label, item->accel);
if (accel != NULL) {
int x;
chtype ch;
ch = item->accel | get_accel_color(win);
x = (accel - item->label) + startx;
mvwaddch(win, starty, x, ch);
}
}
wmove(win, starty, startx);
}
}
/**
* get_accelerator_char - retrieves the accelerator character from menu label
* @label: the label containing the accelerator character
*
* This routine scans the string for the '_' character and then uses the
* following character as the accelerator character. '\0' is returned if the
* label does not contain an accelerator character.
*/
char get_accelerator_char(char *label)
{
char ch = '\0';
char *accel;
accel = strchr(label, '_');
if (accel != NULL) {
ch = accel[1];
}
return ch;
}
/**
* remove_accel_identifier - makes a duplicate string of the label with the '_'
* @label: the label containing the accelerator character and identifier
*
* This routine returns a duplicate of the label string minus the first '_'
* character which is used to identify the accelerator character.
*/
char *remove_accel_identifier(char *label)
{
char *dup, *leader;
dup = g_strdup(label);
leader = strchr(dup, '_');
if (leader != NULL) {
while (*leader != '\0') {
*leader = *(leader + 1);
leader++;
}
}
return dup;
}
/**
* create_menu_item - allocates/creates and initializes a menu item
* @label: the menu item label
* @tip: the optional description to display on status line
* @accel: the accelerator character
* @is_submenu: whether this is a submenu or a real menu item (leaf)
* @activate_cb: function to invoke when item is selected
* @user_data: whatever the caller wants to pass to the activate_cb
*
* This routine dynamically allocates a new menu item and initializes it.
*/
struct menu_item *create_menu_item(char *label, char *tip, int accel, int is_submenu,
menuitem_activate_cb activate_cb, void *user_data)
{
struct menu_item *item;
item = g_new0(struct menu_item, 1);
item->label = g_strdup(label);
item->label_len = strlen(label);
item->tip = g_strdup(tip);
item->accel = accel;
item->flags = is_submenu ? MI_FLAG_SUBMENU : 0;
item->flags |= (MI_FLAG_VISIBLE | MI_FLAG_SENSITIVE);
item->startx = -1;
item->activate_cb = activate_cb;
item->delete_cb = NULL;
item->user_data = user_data;
return item;
}
/**
* delete_menu_item - deletes all resources associated with a menu item
* @item: the pointer to the menu_item structure
* @menu: the popup menu containing the item
*
* This routine invokes an user supplied delete callback and then proceeds
* to free the memory allocated for the menu item fields and the menu item
* structure itself.
*/
void delete_menu_item(struct menu_item *item, struct popup_menu *menu)
{
if (item->delete_cb != NULL) {
item->delete_cb(item);
}
if (item == menu->focus_item->data) {
if (g_list_next(menu->focus_item) != NULL) {
menu->focus_item = g_list_next(menu->focus_item);
} else {
menu->focus_item = g_list_previous(menu->focus_item);
}
}
g_free(item->label);
g_free(item->tip);
g_free(item);
}
/**
* set_menu_item_activate_cb - sets the address of the activate callback for a menu item
* @item: the menu item
* @activate_cb: the function to invoke when a menu item is activated
*
* This routine is used to set the menu item activation callback. This allows a
* activation callback to be changed as needed (such as to replace the default).
*/
inline void set_menu_item_activate_cb(struct menu_item *item, menuitem_activate_cb activate_cb)
{
item->activate_cb = activate_cb;
}
/**
* set_menu_item_delete_cb - sets the address of the delete callback for a menu item
* @item: the menu item
* @delete_cb: the function to invoke when a menu item is deleted
*
* This routine is used to set the menu item deletion callback. Since a deletion
* callback is hardly used, it is not provided as a parameter on append_menu_item().
* This routine allows the exceptions access to set it when needed.
*/
inline void set_menu_item_delete_cb(struct menu_item *item, menuitem_delete_cb delete_cb)
{
item->delete_cb = delete_cb;
}
/**
* set_menu_item_sensitivity - make a menu item sensitive or not
* @item: the menu item
* @sensitive: non-zero if the menu item should be sensitive, zero if not
*
* This routine simply enables or disables the flag that identifies
* a menu item a sensitive to selection or activation.
*/
inline void set_menu_item_sensitivity(struct menu_item *item, int sensitive)
{
if (sensitive)
item->flags |= MI_FLAG_SENSITIVE;
else
item->flags &= ~MI_FLAG_SENSITIVE;
}
/**
* set_menu_item_visibility - make a menu item visible or hidden
* @item: the menu item
* @visible: non-zero if the menu item should be visible, zero if hidden
*
* This routine simply enables or disables the flag that identifies
* a menu item as visible (capable of being drawn) or not. The caller
* must make the appropriate call to redraw the menu and either make
* the menu item show up or disappear.
*/
inline void set_menu_item_visibility(struct menu_item *item, int visible)
{
if (visible)
item->flags |= MI_FLAG_VISIBLE;
else
item->flags &= ~MI_FLAG_VISIBLE;
}
/**
* is_menu_item_sensitive - determine if menu item supplied is sensitive to events
* @item: the menu item to check
*
* This routine returns TRUE if the menu item is currently not sensitive to
* events.
*/
inline gboolean is_menu_item_sensitive(struct menu_item *item)
{
return (item->flags & MI_FLAG_SENSITIVE ? TRUE : FALSE);
}
/**
* is_menu_item_visible - determine if menu item supplied is being drawn when needed
* @item: the menu item to check
*
* This routine return TRUE if the menu is currently invisible to draw requests.
*/
inline gboolean is_menu_item_visible(struct menu_item *item)
{
return (item->flags & MI_FLAG_VISIBLE ? TRUE : FALSE);
}
/**
* append_menu_item - creates and appends a menu item to a menu
* @label: the menu item label
* @tip: the optional description to display on status line
* @accel: the accelerator character
* @is_submenu: whether this is a submenu or a real menu item (leaf)
* @activate_cb: function to invoke when item is selected
* @user_data: whatever the caller wants to pass to the activate_cb
*
* This routine creates a new menu item and appends it to the linked
* list of popup menu items.
*/
struct menu_item *append_menu_item(struct popup_menu *menu, char *label, char *tip, int accel,
int is_submenu, menuitem_activate_cb activate_cb, void *user_data)
{
struct menu_item *item;
item = create_menu_item(label, tip, accel, is_submenu, activate_cb, user_data);
menu->items = g_list_append(menu->items, item);
if (menu->focus_item == NULL) {
menu->focus_item = menu->items;
}
return item;
}
/**
* display_not_implemented_popup_window - warns when function not implemented
* @void
*
* This is a temporary function that indicates a function is not available
* for a menu item.
*/
void display_not_implemented_popup_window(void)
{
show_message_dialog(NULL, _("Operation not yet implemented!"));
}
/**
* translate_key - filters keyboard input for a menu
* @items: the list containing the menu items
* @key: the input key
* @focus_item: the address of the focus item tracker
*
* This routine processes keyboard input for a menu and
* translates any accelerator keys to the ENTER_KEY and
* adjusts the focus_item if appropriate.
*/
int translate_key(GList *items, int key, GList **focus_item)
{
GList *element;
struct menu_item *item;
element = items;
while (element != NULL) {
item = element->data;
if (MI_IS_SENSITIVE(item->flags) &&
(tolower(item->accel) == tolower(key))) {
key = KEY_ENTER;
*focus_item = element;
break;
}
element = g_list_next(element);
}
return key;
}
/**
* show_about_box - display some information on the application
* @item: the item that was activated to invoke this callback
*
* This routine creates a popup window with some application information.
*/
int show_about_box(struct menu_item *item)
{
int key = 0;
WINDOW *win;
PANEL *panel;
gchar *version;
struct horizontal_menu *menu;
panel = create_centered_popup_window(MIN(getmaxy(stdscr) - 2, 14),
getmaxx(stdscr) - 6,
WHITE_BKGD);
win = panel_window(panel);
version = g_strdup_printf(_("Version %s"), VERSION);
print_centered(win, 1, _("EVMSN"));
print_centered(win, 2, _("Enterprise Volume Management System Text Mode Interface"));
print_centered(win, 4, version);
print_centered(win, 7, _("(C) Copyright IBM Corp. 2002, 2003"));
print_centered(win, 9, _("Online documentation can be found at http://evms.sf.net"));
menu = create_horizontal_menu(win, getmaxx(win) - 4, getmaxy(win) - 2, 1, 1);
pack_menu_item_at_end(menu, _("[OK]"), get_accelerator_char(_("[_OK]")),
(menuitem_activate_cb)ok_button_activated,
NULL);
draw_horizontal_menu(menu);
show_popup_window(panel);
while (key != KEY_ESCAPE && key != KEY_ENTER) {
key = panel_getch(panel);
process_horizontal_menu_events(menu, &key);
}
delete_horizontal_menu(menu);
delete_popup_window(panel);
g_free(version);
return 0;
}
/**
* init_menubar_menu_items - initialize the main menubar menu items
* @void
*
* This routine initializes the main menubar menu item array.
*/
inline void init_menubar_menu_items(void)
{
menubar_item[ACTIONS_MENUITEM].label = _("Actions");
menubar_item[ACTIONS_MENUITEM].label_len = strlen(menubar_item[ACTIONS_MENUITEM].label);
menubar_item[ACTIONS_MENUITEM].accel = get_accelerator_char(_("_Actions"));
menubar_item[ACTIONS_MENUITEM].flags = MI_FLAG_SENSITIVE | MI_FLAG_VISIBLE;
menubar_item[ACTIONS_MENUITEM].activate_cb = (menuitem_activate_cb)actions_menuitem_activated;
menubar_item[SETTINGS_MENUITEM].label = _("Settings");
menubar_item[SETTINGS_MENUITEM].label_len = strlen(menubar_item[SETTINGS_MENUITEM].label);
menubar_item[SETTINGS_MENUITEM].accel = get_accelerator_char(_("_Settings"));
menubar_item[SETTINGS_MENUITEM].flags = MI_FLAG_SENSITIVE | MI_FLAG_VISIBLE;
menubar_item[SETTINGS_MENUITEM].activate_cb = (menuitem_activate_cb)settings_menuitem_activated;
menubar_item[HELP_MENUITEM].label = _("Help");
menubar_item[HELP_MENUITEM].label_len = strlen(menubar_item[HELP_MENUITEM].label);
menubar_item[HELP_MENUITEM].accel = get_accelerator_char(_("_Help"));
menubar_item[HELP_MENUITEM].flags = MI_FLAG_SENSITIVE | MI_FLAG_VISIBLE;
menubar_item[HELP_MENUITEM].activate_cb = (menuitem_activate_cb)show_about_box;
}
/**
* process_menubar_events - process menubar keys and activates menu items
* @key: the input character/key
*
* This routine translates a character/key into an event such as activating
* a menu item on the menubar.
*/
int process_menubar_events(int key)
{
int i, rc = 0;
for (i = 0; i < MENUBAR_ITEM_COUNT; i++) {
if (tolower(key) == tolower(menubar_item[i].accel)) {
if (menubar_item[i].activate_cb != NULL) {
rc = menubar_item[i].activate_cb(&(menubar_item[i]));
} else {
display_not_implemented_popup_window();
}
break;
}
}
return rc;
}
/**
* draw_menubar - draws the main menubar
* @void
*
* This routine creates the main window menubar that is used to
* access the general dropdown action menus.
*/
void draw_menubar(void)
{
init_menubar_menu_items();
menubar = subwin(stdscr, 1, getmaxx(stdscr), 0, 0);
wbkgd(menubar, WHITE_BKGD);
print_menu_item(menubar, 0, 1, &(menubar_item[ACTIONS_MENUITEM]));
print_menu_item(menubar, 0, menubar_item[ACTIONS_MENUITEM].label_len + 4,
&(menubar_item[SETTINGS_MENUITEM]));
print_menu_item(menubar, 0, getmaxx(stdscr) - (menubar_item[HELP_MENUITEM].label_len + 1),
&(menubar_item[HELP_MENUITEM]));
wrefresh(menubar);
}
/**
* draw_statusbar - draws the status bar at the bottom of the screen
* @void
*
* This routine draws the status bar line at the bottom of the main window.
*/
void draw_statusbar(void)
{
statusbar = subwin(stdscr, 1, getmaxx(stdscr), getmaxy(stdscr) - 1, 0);
wbkgd(statusbar, WHITE_BKGD);
wrefresh(statusbar);
}
/**
* print_statusbar_text - displays given text in statusbar
* @text: the text string to display
*
* This routine displays the given text string in the statusbar
* window. The previous text in the statusbar window is cleared
* before the next text is written.
*/
void print_statusbar_text(char *text)
{
werase(statusbar);
mvwaddstr(statusbar, 0, 1, text);
wrefresh(statusbar);
}
/**
* get_statusbar_win - returns the statusbar window id
* @void
*
* This routine is a simple getter function for the statusbar window id.
*/
WINDOW *get_statusbar_win(void)
{
return statusbar;
}
/**
* create_popup_menu - allocates the popup menu struct
* @void
*
* This routine creates/allocates a popup_menu struct
* and initializes the data struct.
*/
struct popup_menu *create_popup_menu(void)
{
return g_new0(struct popup_menu, 1);
}
/**
* delete_popup_menu - frees all resources for a popup menu
* @menu: the popup menu
*
* This routine deletes window/panel components of a popup menu
* before deallocating the memory for the popup menu structure.
* It also deletes all the menu items in the popup menu as well.
* It invokes the handler for the delete event registered with
* the menu if one exists before actually deleting the popup menu.
*/
void delete_popup_menu(struct popup_menu *menu)
{
if (menu->delete_cb != NULL) {
menu->delete_cb(menu);
}
delete_all_elements(menu->items, (GFunc)delete_menu_item, menu);
delete_panel_window(menu->panel);
g_free(menu);
}
/**
* hide_popup_menu - hides a popup menu window
* @menu: the popup menu
*
* This routine hides the panel window for the popup menu
* and then invokes the handler registered for the menu
* hide event if any.
*/
void hide_popup_menu(struct popup_menu *menu)
{
hide_panel_window(menu->panel);
if (menu->hide_cb != NULL) {
menu->hide_cb(menu);
}
}
/**
* print_blank_menu_item - print a line with spaces in a popup menu
* @win: the popup menu window
* @line: the line in the popup menu to clear
*
* This routine clears a line in a popup window by drawing spaces
* into it.
*/
void print_blank_menu_item(WINDOW *win, int line)
{
char *fill;
fill = g_strnfill(getmaxx(win) - 2, ' ');
mvwaddstr(win, line, 1, fill);
g_free(fill);
}
/**
* draw_menu_item - displays a single menu item in a popup menu
* @element: the address of the linked list item we are in
* @index: an index to identify us in a loop
* @menu: the address of the popup_menu structure we are in
*
* This routine is meant to be invoked through a for_n_elements()
* call. For each iteration we use the index as the row to update.
*/
void draw_menu_item(GList *element, int index, struct popup_menu *menu)
{
if (element != NULL && element->data != NULL) {
index++;
print_blank_menu_item(menu->win, index);
print_menu_item(menu->win, index, 1, element->data);
}
}
/**
* draw_menu_items - draws the menu items in a popup menu
* @menu: the popup menu to draw
*
* This routine draws/updates the menu items in the menu window.
*/
inline void draw_menu_items(struct popup_menu *menu)
{
for_n_elements(menu->items, getmaxy(menu->win),
(iterate_func)draw_menu_item, menu);
}
/**
* get_max_label_width - returns the length of the longest menu item label
* @element: the first element of the linked list of menu items
*
* This routine scans all the menu item labels in the menu item list in
* order to determine the length of the longest label for all menu items.
*/
int get_max_label_width(GList *element)
{
int len = 0;
struct menu_item *item;
while (element != NULL) {
item = element->data;
if (item->label_len > len) {
len = item->label_len;
}
element = g_list_next(element);
}
return len;
}
/**
* create_menu_panel - creates a panel window with menu items
* @menu: the address of the menu we need the panel for
* @starty: the starting line to place the window
* @startx: the starting column to place the window
*
* This routine creates a panel window sized to the width of the
* longest label in the linked list of menu items. The panel of the
* created menu is then set in the popup_menu struct.
*/
inline void create_menu_panel(struct popup_menu *menu, int starty, int startx)
{
int width, height;
width = get_max_label_width(menu->items) + 2;
height = g_list_length(menu->items) + 2;
menu->panel = create_panel_window(height, width, starty, startx, TRUE, WHITE_BKGD);
menu->win = panel_window(menu->panel);
draw_menu_items(menu);
}
/**
* cascade_menu - place a submenu slightly overlapping parent menu
* @submenu: the menu id of the submenu
* @parent: the menu id of the parent menu
* @starty: the row/line to place the submenu relative to parent starty
*
* This routine determines the width and starting row and column of a
* parent window and then places the submenu relative to the parent
* window and slightly overlapping it.
*/
inline void cascade_menu(struct popup_menu *submenu, struct popup_menu *parent, int starty)
{
move_panel(submenu->panel, getbegy(parent->win) + starty, getmaxx(parent->win) - 1);
submenu->parent = parent;
}
/**
* highlight_current_menuitem - sets visual focus on current menu item
* @menu: the popup menu
* @width: the width of the menuitem area
*
* This routine draws a bar across the current menu item so the user
* can see which menu item has focus.
*/
void highlight_current_menuitem(struct popup_menu *menu, int width)
{
int focus_index;
struct menu_item *item;
wbkgdset(menu->win, WHITE_BKGD);
draw_menu_items(menu);
item = menu->focus_item->data;
wbkgdset(menu->win, MENUSEL_FGND);
focus_index = g_list_position(menu->items, menu->focus_item);
draw_menu_item(menu->focus_item, focus_index, menu);
wbkgdset(menu->win, WHITE_BKGD);
if (item->tip != NULL) {
print_statusbar_text(item->tip);
}
wrefresh(menu->win);
}
/**
* hide_parent_menus - hides the menu and all its parent menus
* @menu: the initial menu to hide
*
* This routine hides the given menu and if its a submenu, hides
* any parent menu as well.
*/
inline void hide_parent_menus(struct popup_menu *menu)
{
struct popup_menu *curr_menu;
curr_menu = menu;
while (curr_menu != NULL) {
hide_panel_window(curr_menu->panel);
curr_menu = curr_menu->parent;
}
}
/**
* process_menu_events - handles keyboard movement and selection
* @menu: the menu to process
*
* This routine handles navigation through a menu of menu items.
* It provides for invoking an activation callback for a menu item
* upon selection of the menu item (through ENTER_KEY or the accelerator
* character). This function returns either id ESCAPE_KEY is detected
* or after a selection's activation callback has returned.
*/
int process_menu_events(struct popup_menu *menu)
{
int rc = 0, width, key, process_key;
struct menu_item *curr_item = NULL;
process_key = TRUE;
width = getmaxx(menu->win) - 2;
menu->focus_item = g_list_first(menu->items);
while (process_key == TRUE) {
highlight_current_menuitem(menu, width);
key = panel_getch(menu->panel);
key = translate_key(menu->items, key, &(menu->focus_item));
switch (key) {
case KEY_DOWN:
if (g_list_next(menu->focus_item) != NULL) {
menu->focus_item = g_list_next(menu->focus_item);
} else {
menu->focus_item = g_list_first(menu->items);
}
break;
case KEY_UP:
if (g_list_previous(menu->focus_item) != NULL) {
menu->focus_item = g_list_previous(menu->focus_item);
} else {
menu->focus_item = g_list_last(menu->items);
}
break;
case KEY_HOME:
menu->focus_item = g_list_first(menu->items);
break;
case KEY_END:
menu->focus_item = g_list_last(menu->items);
break;
case KEY_ENTER:
curr_item = menu->focus_item->data;
if (MI_IS_SENSITIVE(curr_item->flags)) {
if (MI_IS_SUBMENU(curr_item->flags)) {
highlight_current_menuitem(menu, width);
} else {
print_statusbar_text("");
hide_parent_menus(menu);
}
if (curr_item->activate_cb != NULL) {
rc = curr_item->activate_cb(curr_item);
if (rc != ELOOP) {
hide_popup_menu(menu);
process_key = FALSE;
}
} else {
display_not_implemented_popup_window();
process_key = FALSE;
}
}
break;
case KEY_ESCAPE:
print_statusbar_text("");
hide_popup_menu(menu);
process_key = FALSE;
rc = ELOOP;
break;
}
}
return rc;
}
/**
* calculate_menu_item_offsets_from_start - calculate the offsets for items in a horiz menu from start
* @menu: the horizontal menu
*
* This routine calculates the starting offsets for each menu item label in a
* horizontal menu. We expect that the first item in the list was just added and
* the we set it's offset to 0 and ensure that the next item over and on are at
* least menu->spacing from each other. Otherwise, we make the necessary adjustments.
*
* At the moment, if ever an item is deleted, we don't shift offsets to close up the
* holes but I suppose it wouldn't be that the difficult to do. Currently, it is not
* a requirement and should also keep this routine a bit simpler.
*/
inline void calculate_menu_item_offsets_from_start(struct horizontal_menu *menu)
{
GList *element;
element = g_list_first(menu->items);
if (element != NULL) {
struct menu_item *curr_item, *prev_item;
curr_item = prev_item = element->data;
curr_item->startx = 0;
element = g_list_next(element);
while (element != NULL) {
int offset;
prev_item = curr_item;
curr_item = element->data;
offset = prev_item->startx + menu->spacing + prev_item->label_len;
if (offset > curr_item->startx) {
curr_item->startx = offset;
element = g_list_next(element);
} else {
/*
* There is sufficient spacing between current
* and previous menu item so stop processing
*/
element = NULL;
}
}
}
}
/**
* calculate_menu_item_offsets_from_end - calculate the offsets for items in a horiz menu from end
* @menu: the horizontal menu
*
* This routine calculates the starting offsets for each menu item label in a
* horizontal menu. It places the last element in the list of menu items at an offset
* where it is to rightmost of the menu.
*
* At the moment, if ever an item is deleted, we don't shift offsets to close up the
* holes but I suppose it wouldn't be that the difficult to do. Currently, it is not
* a requirement and should also keep this routine a bit simpler.
*/
inline void calculate_menu_item_offsets_from_end(struct horizontal_menu *menu)
{
GList *element;
element = g_list_last(menu->items);
if (element != NULL) {
struct menu_item *curr_item, *prev_item;
curr_item = prev_item = element->data;
curr_item->startx = getmaxx(menu->win) - curr_item->label_len;
element = g_list_previous(element);
while (element != NULL) {
int offset;
prev_item = curr_item;
curr_item = element->data;
offset = prev_item->startx - menu->spacing - curr_item->label_len;
if (curr_item->startx > offset) {
curr_item->startx = offset;
element = g_list_previous(element);
} else {
/*
* There is sufficient spacing between current
* and previous menu item so stop processing
*/
element = NULL;
}
}
}
}
/**
* pack_menu_item_at_end - places a menu item at the end (far right) of horizontal menu
* @menu: the horizontal menu to put the menu item in
* @label: the menu item label
* @accel: the accelerator character
* @activate_cb: the callback to invoke when the menu item is activated
* @user_data: whatever the caller wants accessible in the activate callback
*
* This routine creates a menu item for a horizontal menu and places the menu item
* label at the far right of the menu. It adjusts the startx values for previous
* end packed entries to allow them to shift to left to make room for the new
* item.
*/
struct menu_item *pack_menu_item_at_end(struct horizontal_menu *menu, char *label, int accel,
menuitem_activate_cb activate_cb, void *user_data)
{
struct menu_item *item;
item = create_menu_item(label, NULL, accel, FALSE, activate_cb, user_data);
menu->items = g_list_append(menu->items, item);
if (menu->focus_item == NULL) {
menu->focus_item = menu->items;
}
calculate_menu_item_offsets_from_end(menu);
return item;
}
/**
* pack_menu_item_at_end - places a menu item at the end (far right) of horizontal menu
* @menu: the horizontal menu to put the menu item in
* @label: the menu item label
* @accel: the accelerator character
* @activate_cb: the callback to invoke when the menu item is activated
* @user_data: whatever the caller wants accessible in the activate callback
*
* This routine creates a menu item for a horizontal menu and places the menu item
* label at the far left of the menu. It adjusts the startx values for subsequent
* start packed entries to allow them to shift to right to make room for the new
* item.
*/
struct menu_item *pack_menu_item_at_start(struct horizontal_menu *menu, char *label, int accel,
menuitem_activate_cb activate_cb, void *user_data)
{
struct menu_item *item;
item = create_menu_item(label, NULL, accel, FALSE, activate_cb, user_data);
menu->items = g_list_prepend(menu->items, item);
if (menu->focus_item == NULL) {
menu->focus_item = menu->items;
}
calculate_menu_item_offsets_from_start(menu);
return item;
}
/**
* set_horizontal_menu_focus - identify the menu item to focus in a horizontal menu
* @menu: the horizontal menu
* @item: the item to set focus on
*
* This routine sets the focus menu item in a horizontal menu.
*/
inline void set_horizontal_menu_focus(struct horizontal_menu *menu, struct menu_item *item)
{
GList *element;
element = g_list_find(menu->items, item);
if (element != NULL)
menu->focus_item = element;
}
/**
* create_horizontal_menu - creates a menu with the menu items on the same line
* @parent_win: the parent window
* @width: the width of the menu
* @starty: the row to place the menu at within the parent window
* @startx: the column to place the menu at within the parent window
* @spacing: the number of spaces to keep between adjacent (packed) menu items
*
* This routine creates a menu with the menu items on the same. The menu items
* are navigated with the left or right arrow key, cycled with the TAB key or
* activated with an ENTER or accelerator key. Items are either packed at the
* end or the start of the menu row.
*/
struct horizontal_menu *create_horizontal_menu(WINDOW *parent_win, int width, int starty,
int startx, int spacing)
{
struct horizontal_menu *menu;
menu = g_new0(struct horizontal_menu, 1);
menu->win = derwin(parent_win, 1, width, starty, startx);
menu->spacing = spacing;
return menu;
}
/**
* delete_horizontal_menu - frees all resources for a horizontal menu
* @menu: the horizontal menu
*
* This routine deletes window components of a horizontal menu
* before deallocating the memory for the horizontal menu structure.
* It also deletes all the menu items in the horizontal menu as well.
*/
void delete_horizontal_menu(struct horizontal_menu *menu)
{
delete_all_elements(menu->items, (GFunc)delete_menu_item, menu);
delete_window(menu->win);
g_free(menu);
}
/**
* draw_horizontal_menu_item - draws one menu item in a horizontal menu
* @item: the menu item to draw
* @win: the window for the horizontal menu
*
* This routine draws one menu item in a horizontal menu.
*/
void draw_horizontal_menu_item(struct menu_item *item, WINDOW *win)
{
print_menu_item(win, 0, item->startx, item);
}
/**
* move_focus_to_prev_item - move focus to previous visible/sensitive menu item
* @menu: the menu containing the menu items
*
* This routine changes the focus (if possible) from the current focus item
* to a previous item in the list that is both visible and sensitive.
*/
inline void move_focus_to_prev_item(struct horizontal_menu *menu)
{
GList *element;
if (g_list_previous(menu->focus_item) != NULL) {
element = g_list_previous(menu->focus_item);
} else {
element = g_list_last(menu->items);
}
while (element != menu->focus_item) {
struct menu_item *item;
item = element->data;
if (MI_IS_SENSITIVE(item->flags) && MI_IS_VISIBLE(item->flags)) {
menu->focus_item = element;
} else if (g_list_previous(element) != NULL) {
element = g_list_previous(element);
} else {
element = g_list_last(menu->items);
}
}
}
/**
* move_focus_to_next_item - move focus to next visible/sensitive menu item
* @menu: the menu containing the menu items
*
* This routine changes the focus (if possible) from the current focus item
* to the next item in the list that is both visible and sensitive.
*/
inline void move_focus_to_next_item(struct horizontal_menu *menu)
{
GList *element;
if (g_list_next(menu->focus_item) != NULL) {
element = g_list_next(menu->focus_item);
} else {
element = g_list_first(menu->items);
}
while (element != menu->focus_item) {
struct menu_item *item;
item = element->data;
if (MI_IS_SENSITIVE(item->flags) && MI_IS_VISIBLE(item->flags)) {
menu->focus_item = element;
} else if (g_list_next(element) != NULL) {
element = g_list_next(element);
} else {
element = g_list_first(menu->items);
}
}
}
/**
* verify_focus_item - ensure that we have a focus item that is visible and sensitive
* @menu: the horizontal menu
*
* This routine checks to see if the current focus item is visible and sensitive. If
* not, we adjust the focus to some item before it that is.
*/
inline void verify_focus_item(struct horizontal_menu *menu)
{
struct menu_item *item = menu->focus_item->data;
if (!MI_IS_SENSITIVE(item->flags) || !MI_IS_VISIBLE(item->flags))
move_focus_to_prev_item(menu);
}
/**
* draw_horizontal_menu - draws the menu items in a horizontal menu
* @menu: the horizontal menu to draw
*
* This routine draws the menu items in a horizontal menu. The menu item
* with the current focus is highlighted as well.
*/
void draw_horizontal_menu(struct horizontal_menu *menu)
{
struct menu_item *focus_item;
g_return_if_fail(menu->items != NULL);
g_return_if_fail(menu->focus_item != NULL);
verify_focus_item(menu);
focus_item = menu->focus_item->data;
werase(menu->win);
g_list_foreach(menu->items, (GFunc)draw_horizontal_menu_item, menu->win);
wbkgdset(menu->win, MENUSEL_FGND);
print_menu_item(menu->win, 0, focus_item->startx, focus_item);
wbkgdset(menu->win, WHITE_BKGD);
touchwin(menu->win);
wrefresh(menu->win);
}
/**
* process_horizontal_menu_events - processes input for a horizontal menu
* @menu: the address of the horizontal menu data
* @key: the key to convert to a menu event to process
*
* This routine processes the events for a horizontal menu. It receives
* a key and converts this to a corresponding event. It returns TRUE if
* an event/key was handled.
*/
int process_horizontal_menu_events(struct horizontal_menu *menu, int *key)
{
int event_handled = TRUE;
struct menu_item *curr_item = NULL;
*key = translate_key(menu->items, *key, &(menu->focus_item));
switch (*key) {
case KEY_LEFT:
move_focus_to_prev_item(menu);
break;
case KEY_RIGHT:
case KEY_TAB:
move_focus_to_next_item(menu);
break;
case KEY_ENTER:
curr_item = menu->focus_item->data;
draw_horizontal_menu(menu);
if (curr_item->activate_cb != NULL) {
curr_item->activate_cb(curr_item);
} else {
display_not_implemented_popup_window();
}
break;
default:
event_handled = FALSE;
break;
}
if (event_handled == TRUE) {
draw_horizontal_menu(menu);
}
return event_handled;
}
/**
* append_create_menu_items - appends the "Create" menu items
* @void
*
* This routine appends the menu items for the "Create" menu.
*/
inline void append_create_menu_items(void)
{
append_menu_item(create_menu, _("EVMS Volume..."),
_("Create an EVMS native volume"),
get_accelerator_char(_("_EVMS Volume...")), FALSE,
(menuitem_activate_cb)actions_create_evms_vol_menuitem_activated, NULL);
append_menu_item(create_menu, _("Compatibility Volume..."),
_("Create a volume compatible with other volume management packages"),
get_accelerator_char(_("Compatibility _Volume...")), FALSE,
(menuitem_activate_cb)actions_create_vol_menuitem_activated, NULL);
append_menu_item(create_menu, _("Feature Object..."),
_("Create a native EVMS Feature Object"),
get_accelerator_char(_("_Feature Object...")), FALSE,
(menuitem_activate_cb)create_feature_menuitem_activated, NULL);
append_menu_item(create_menu, _("Region..."), _("Create a Storage Region"),
get_accelerator_char(_("_Region...")), FALSE,
(menuitem_activate_cb)create_region_menuitem_activated, NULL);
append_menu_item(create_menu, _("Container..."), _("Create a Storage Container"),
get_accelerator_char(_("_Container...")), FALSE,
(menuitem_activate_cb)create_container_menuitem_activated, NULL);
append_menu_item(create_menu, _("Segment..."), _("Create a Disk Segment"),
get_accelerator_char(_("_Segment...")), FALSE,
(menuitem_activate_cb)create_segment_menuitem_activated, NULL);
}
/**
* draw_create_menu - draws the "Create" submenu
* @void
*
* This routine displays the "Create" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_create_menu(void)
{
if (create_menu == NULL) {
create_menu = create_popup_menu();
append_create_menu_items();
create_menu_panel(create_menu, 0, 0);
cascade_menu(create_menu, actions_menu, CREATE_MENUITEM);
}
show_panel_window(create_menu->panel, TRUE);
}
/**
* create_menuitem_activated - function invoked when create menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Create" menu item
* in the "Actions" menu is selected. It draws the "Create" pulldown submenu
* and processes menu events.
*/
int create_menuitem_activated(struct menu_item *item)
{
int rc;
draw_create_menu();
rc = process_menu_events(create_menu);
return rc;
}
/**
* append_delete_menu_items - appends the "Delete" menu items
* @void
*
* This routine appends the menu items for the "Delete" menu.
*/
inline void append_delete_menu_items(void)
{
append_menu_item(delete_menu, _("Volume..."), _("Delete a Logical Volume"),
get_accelerator_char(_("_Volume...")), FALSE,
(menuitem_activate_cb)actions_delete_menuitem_activated,
GUINT_TO_POINTER(VOLUME));
append_menu_item(delete_menu, _("Storage Object..."), _("Delete a Storage Object"),
get_accelerator_char(_("_Storage Object...")), FALSE,
(menuitem_activate_cb)actions_delete_menuitem_activated,
GUINT_TO_POINTER(EVMS_OBJECT));
append_menu_item(delete_menu, _("Container..."), _("Delete a Storage Container"),
get_accelerator_char(_("_Container...")), FALSE,
(menuitem_activate_cb)actions_delete_menuitem_activated,
GUINT_TO_POINTER(CONTAINER));
}
/**
* draw_delete_menu - draws the "Delete" submenu
* @void
*
* This routine displays the "Delete" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_delete_menu(void)
{
if (delete_menu == NULL) {
delete_menu = create_popup_menu();
append_delete_menu_items();
create_menu_panel(delete_menu, 0, 0);
cascade_menu(delete_menu, actions_menu, DELETE_MENUITEM);
}
show_panel_window(delete_menu->panel, TRUE);
}
/**
* delete_menuitem_activated - function invoked when "Delete" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Delete" menu item
* in the "Actions" menu is selected. It draws the "Delete" pulldown submenu
* and processes menu events.
*/
int delete_menuitem_activated(struct menu_item *item)
{
int rc;
draw_delete_menu();
rc = process_menu_events(delete_menu);
return rc;
}
/**
* append_activation_menu_items - appends the "Activation" menu items
* @void
*
* This routine appends the menu items for the "Activation" menu.
*/
inline void append_activation_menu_items(void)
{
append_menu_item(activation_menu, _("Activate..."), _("Activate a Logical Volume or Storage Object"),
get_accelerator_char(_("_Activate...")), FALSE,
(menuitem_activate_cb)actions_activate_menuitem_activated,
NULL);
append_menu_item(activation_menu, _("Deactivate..."), _("Deactivate a Logical Volume or Storage Object"),
get_accelerator_char(_("_Deactivate...")), FALSE,
(menuitem_activate_cb)actions_deactivate_menuitem_activated,
NULL);
}
/**
* draw_activation_menu - draws the "Activation" submenu
* @void
*
* This routine displays the "Activation" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_activation_menu(void)
{
if (activation_menu == NULL) {
activation_menu = create_popup_menu();
append_activation_menu_items();
create_menu_panel(activation_menu, 0, 0);
cascade_menu(activation_menu, actions_menu, ACTIVATION_MENUITEM);
}
show_panel_window(activation_menu->panel, TRUE);
}
/**
* activation_menuitem_activated - function invoked when "Activation" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Activation" menu item
* in the "Actions" menu is selected. It draws the "Activation" pulldown submenu
* and processes menu events.
*/
int activation_menuitem_activated(struct menu_item *item)
{
int rc;
draw_activation_menu();
rc = process_menu_events(activation_menu);
return rc;
}
/**
* append_expand_menu_items - appends the "Expand" menu items
* @void
*
* This routine appends the menu items for the "Expand" menu.
*/
inline void append_expand_menu_items(void)
{
append_menu_item(expand_menu, _("Volume..."), _("Increase the storage size of Logical Volume"),
get_accelerator_char(_("_Volume...")), FALSE,
(menuitem_activate_cb)actions_expand_volume_menuitem_activated, NULL);
append_menu_item(expand_menu, _("Storage Object..."), _("Increase the storage size of Storage Object"),
get_accelerator_char(_("_Storage Object...")), FALSE,
(menuitem_activate_cb)actions_expand_object_menuitem_activated, NULL);
append_menu_item(expand_menu, _("Container..."), _("Increase the size of a Storage Container"),
get_accelerator_char(_("_Container...")), FALSE,
(menuitem_activate_cb)actions_expand_container_menuitem_activated, NULL);
}
/**
* draw_expand_menu - draws the "Expand" submenu
* @void
*
* This routine displays the "Expand" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_expand_menu(void)
{
if (expand_menu == NULL) {
expand_menu = create_popup_menu();
append_expand_menu_items();
create_menu_panel(expand_menu, 0, 0);
cascade_menu(expand_menu, actions_menu, EXPAND_MENUITEM);
}
show_panel_window(expand_menu->panel, TRUE);
}
/**
* expand_menuitem_activated - function invoked when "Expand" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Expand" menu item
* in the "Actions" menu is selected. It draws the "Expand" pulldown submenu
* and processes menu events.
*/
int expand_menuitem_activated(struct menu_item *item)
{
int rc;
draw_expand_menu();
rc = process_menu_events(expand_menu);
return rc;
}
/**
* append_shrink_menu_items - appends the "Shrink" menu items
* @void
*
* This routine appends the menu items for the "Shrink" menu.
*/
inline void append_shrink_menu_items(void)
{
append_menu_item(shrink_menu, _("Volume..."),
_("Reduce the storage size of a Logical Volume"),
get_accelerator_char(_("_Volume...")), FALSE,
(menuitem_activate_cb)actions_shrink_volume_menuitem_activated, NULL);
append_menu_item(shrink_menu, _("Storage Object..."),
_("Reduce the size of a Storage Object"),
get_accelerator_char(_("_Storage Object...")), FALSE,
(menuitem_activate_cb)actions_shrink_object_menuitem_activated, NULL);
append_menu_item(shrink_menu, _("Container..."),
_("Reduce the storage consumed by a Storage Container"),
get_accelerator_char(_("_Container...")), FALSE,
(menuitem_activate_cb)actions_shrink_container_menuitem_activated, NULL);
}
/**
* draw_shrink_menu - draws the "Shrink" submenu
* @void
*
* This routine displays the "Shrink" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_shrink_menu(void)
{
if (shrink_menu == NULL) {
shrink_menu = create_popup_menu();
append_shrink_menu_items();
create_menu_panel(shrink_menu, 0, 0);
cascade_menu(shrink_menu, actions_menu, SHRINK_MENUITEM);
}
show_panel_window(shrink_menu->panel, TRUE);
}
/**
* shrink_menuitem_activated - function invoked when "Shrink" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Shrink" menu item
* in the "Actions" menu is selected. It draws the "Shrink" pulldown submenu
* and processes menu events.
*/
int shrink_menuitem_activated(struct menu_item *item)
{
int rc;
draw_shrink_menu();
rc = process_menu_events(shrink_menu);
return rc;
}
/**
* append_add_menu_items - append the "Add" menu items
* @void
*
* This routine appends the menu items for the "Add" menu.
*/
inline void append_add_menu_items(void)
{
append_menu_item(add_menu, _("Feature to Volume..."),
_("Add a EVMS Feature to an EVMS Volume"),
get_accelerator_char(_("_Feature to Volume...")), FALSE,
(menuitem_activate_cb)actions_add_feature_menuitem_activated, NULL);
append_menu_item(add_menu, _("Segment Manager to Storage Object..."),
_("Add a Segment Manager to a Storage Object"),
get_accelerator_char(_("_Segment Manager to Storage Object...")),
FALSE,
(menuitem_activate_cb)add_segment_manager_menuitem_activated, NULL);
}
/**
* draw_add_menu - draws the "Add" submenu
* @void
*
* This routine displays the "Add" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_add_menu(void)
{
if (add_menu == NULL) {
add_menu = create_popup_menu();
append_add_menu_items();
create_menu_panel(add_menu, 0, 0);
cascade_menu(add_menu, actions_menu, ADD_MENUITEM);
}
show_panel_window(add_menu->panel, TRUE);
}
/**
* add_menuitem_activated - function invoked when "Add" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Add" menu item
* in the "Actions" menu is selected. It draws the "Add" pulldown submenu
* and processes menu events.
*/
int add_menuitem_activated(struct menu_item *item)
{
int rc;
draw_add_menu();
rc = process_menu_events(add_menu);
return rc;
}
/**
* append_remove_menu_items - appends the "Remove" menu items
* @void
*
* This routine appends the menu items for the "Remove" menu.
*/
inline void append_remove_menu_items(void)
{
append_menu_item(remove_menu, _("Storage Object from Container..."),
_("Remove a Storage Object from Container"),
get_accelerator_char(_("Storage _Object from Container...")),
FALSE,
(menuitem_activate_cb)actions_remove_consumed_object_menuitem_activated,
NULL);
append_menu_item(remove_menu, _("Segment Manager from Storage Object..."),
_("Remove a Segment Manager from Storage Object"),
get_accelerator_char(_("_Segment Manager from Storage Object...")),
FALSE,
(menuitem_activate_cb)context_remove_segment_manager_menuitem_activated,
NULL);
}
/**
* draw_remove_menu - draws the "Remove" submenu
* @void
*
* This routine displays the "Remove" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_remove_menu(void)
{
if (remove_menu == NULL) {
remove_menu = create_popup_menu();
append_remove_menu_items();
create_menu_panel(remove_menu, 0, 0);
cascade_menu(remove_menu, actions_menu, REMOVE_MENUITEM);
}
show_panel_window(remove_menu->panel, TRUE);
}
/**
* remove_menuitem_activated - function invoked when "Remove" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Remove" menu item
* in the "Actions" menu is selected. It draws the "Remove" pulldown submenu
* and processes menu events.
*/
int remove_menuitem_activated(struct menu_item *item)
{
int rc;
draw_remove_menu();
rc = process_menu_events(remove_menu);
return rc;
}
/**
* append_modify_menu_items - appends the "Modify" menu items
* @void
*
* This routine appends the menu items for the "Modify" menu.
*/
inline void append_modify_menu_items(void)
{
append_menu_item(modify_menu, _("Volume..."), _("Modify Logical Volume properties"),
get_accelerator_char(_("_Volume...")), FALSE,
(menuitem_activate_cb)actions_modify_vol_menuitem_activated,
NULL);
append_menu_item(modify_menu, _("Storage Object..."), _("Modify Storage Object properties"),
get_accelerator_char(_("_Storage Object...")), FALSE,
(menuitem_activate_cb)actions_modify_object_menuitem_activated,
NULL);
append_menu_item(modify_menu, _("Container..."), _("Modify Storage Container properties"),
get_accelerator_char(_("_Container...")), FALSE,
(menuitem_activate_cb)actions_modify_container_menuitem_activated,
NULL);
}
/**
* draw_modify_menu - draws the "Modify" submenu
* @void
*
* This routine displays the "Modify" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_modify_menu(void)
{
if (modify_menu == NULL) {
modify_menu = create_popup_menu();
append_modify_menu_items();
create_menu_panel(modify_menu, 0, 0);
cascade_menu(modify_menu, actions_menu, MODIFY_MENUITEM);
}
show_panel_window(modify_menu->panel, TRUE);
}
/**
* modify_menuitem_activated - function invoked when "Modify" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Modify" menu item
* in the "Actions" menu is selected. It draws the "Modify" pulldown submenu
* and processes menu events.
*/
int modify_menuitem_activated(struct menu_item *item)
{
int rc;
draw_modify_menu();
rc = process_menu_events(modify_menu);
return rc;
}
/**
* append_view_menu_items - appends the "View" menu items
* @void
*
* This routine appends the menu items for the "View" menu.
*/
inline void append_view_menu_items(void)
{
append_menu_item(view_menu, _("Messages..."), _("Display informational messages window"),
get_accelerator_char(_("_Messages...")), FALSE,
(menuitem_activate_cb)on_view_messages_menuitem_activated,
NULL);
}
/**
* draw_view_menu - draws the "View" submenu
* @void
*
* This routine displays the "View" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_view_menu(void)
{
if (view_menu == NULL) {
view_menu = create_popup_menu();
append_view_menu_items();
create_menu_panel(view_menu, 0, 0);
cascade_menu(view_menu, actions_menu, VIEW_MENUITEM);
}
show_panel_window(view_menu->panel, TRUE);
}
/**
* modify_menuitem_activated - function invoked when "View" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "View" menu item
* in the "Actions" menu is selected. It draws the "View" pulldown submenu
* and processes menu events.
*/
int view_menuitem_activated(struct menu_item *item)
{
int rc;
draw_view_menu();
rc = process_menu_events(view_menu);
return rc;
}
/**
* append_convert_menu_items - appends the "Convert" menu items
* @void
*
* This routine appends the menu items for the "Convert" menu.
*/
inline void append_convert_menu_items(void)
{
append_menu_item(convert_menu, _("Compatibility Volume to EVMS Volume..."),
_("Convert a Compatibility Volume to a EVMS Volume"),
get_accelerator_char(_("_Compatibility Volume to EVMS Volume...")),
FALSE,
(menuitem_activate_cb)actions_convert_vol_menuitem_activated,
NULL);
append_menu_item(convert_menu, _("EVMS Volume to Compatibility Volume..."),
_("Convert a EVMS Volume to a Compatibility Volume"),
get_accelerator_char(_("_EVMS Volume to Compatibility Volume...")),
FALSE,
(menuitem_activate_cb)actions_convert_evms_vol_menuitem_activated,
NULL);
}
/**
* draw_convert_menu - draws the "Convert" submenu
* @void
*
* This routine displays the "Convert" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_convert_menu(void)
{
if (convert_menu == NULL) {
convert_menu = create_popup_menu();
append_convert_menu_items();
create_menu_panel(convert_menu, 0, 0);
cascade_menu(convert_menu, actions_menu, CONVERT_MENUITEM);
}
show_panel_window(convert_menu->panel, TRUE);
}
/**
* convert_menuitem_activated - function invoked when "Convert" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Convert" menu item
* in the "Actions" menu is selected. It draws the "Convert" pulldown submenu
* and processes menu events.
*/
int convert_menuitem_activated(struct menu_item *item)
{
int rc;
draw_convert_menu();
rc = process_menu_events(convert_menu);
return rc;
}
/**
* append_other_menu_items - appends the "Other" menu items
* @void
*
* This routine appends the menu items for the "Other" menu.
*/
inline void append_other_menu_items(void)
{
append_menu_item(other_menu, _("Volume Tasks..."),
_("Perform plug-in specific operations for a Logical Volume"),
get_accelerator_char(_("_Volume Tasks...")), FALSE,
(menuitem_activate_cb)actions_show_things_with_plugin_funcs_menuitem_activated,
GUINT_TO_POINTER(VOLUME));
append_menu_item(other_menu, _("Storage Object Tasks..."),
_("Perform plug-in specific operations for a Storage Object"),
get_accelerator_char(_("_Storage Object Tasks...")), FALSE,
(menuitem_activate_cb)actions_show_things_with_plugin_funcs_menuitem_activated,
GUINT_TO_POINTER(EVMS_OBJECT));
append_menu_item(other_menu, _("Container Tasks..."),
_("Perform plug-in specific operations for a Storage Container"),
get_accelerator_char(_("_Container Tasks...")), FALSE,
(menuitem_activate_cb)actions_show_things_with_plugin_funcs_menuitem_activated,
GUINT_TO_POINTER(CONTAINER));
append_menu_item(other_menu, _("Plugin Tasks..."),
_("Perform general plug-in specific operations"),
get_accelerator_char(_("_Plugin Tasks...")), FALSE,
(menuitem_activate_cb)actions_show_things_with_plugin_funcs_menuitem_activated,
GUINT_TO_POINTER(PLUGIN));
}
/**
* draw_convert_menu - draws the "Other" submenu
* @void
*
* This routine displays the "Other" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_other_menu(void)
{
if (other_menu == NULL) {
other_menu = create_popup_menu();
append_other_menu_items();
create_menu_panel(other_menu, 0, 0);
cascade_menu(other_menu, actions_menu, OTHER_MENUITEM);
}
show_panel_window(other_menu->panel, TRUE);
}
/**
* other_menuitem_activated - function invoked when "Other" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Other" menu item
* in the "Actions" menu is selected. It draws the "Other" pulldown submenu
* and processes menu events.
*/
int other_menuitem_activated(struct menu_item *item)
{
int rc;
draw_other_menu();
rc = process_menu_events(other_menu);
return rc;
}
/**
* append_fsys_menu_items - appends the "File System" menu items
* @void
*
* This routine appends the menu items for the "File System" menu.
*/
inline void append_fsys_menu_items(void)
{
append_menu_item(fsys_menu, _("Make..."), _("Create a File System"),
get_accelerator_char(_("_Make...")), FALSE,
(menuitem_activate_cb)actions_mkfs_menuitem_activated, NULL);
append_menu_item(fsys_menu, _("Check/Repair..."), _("Check or Repair a File System"),
get_accelerator_char(_("_Check/Repair...")), FALSE,
(menuitem_activate_cb)actions_fsck_menuitem_activated, NULL);
append_menu_item(fsys_menu, _("Remove..."), _("Remove a File System"),
get_accelerator_char(_("_Remove...")), FALSE,
(menuitem_activate_cb)actions_unmkfs_menuitem_activated, NULL);
append_menu_item(fsys_menu, _("Mount..."), _("Mount a File System"),
get_accelerator_char(_("M_ount...")), FALSE,
(menuitem_activate_cb)actions_mount_filesystem_menuitem_activated, NULL);
append_menu_item(fsys_menu, _("Unmount..."), _("Unmount a File System"),
get_accelerator_char(_("_Unmount...")), FALSE,
(menuitem_activate_cb)actions_unmount_filesystem_menuitem_activated, NULL);
}
/**
* draw_fsys_menu - draws the "File System" submenu
* @void
*
* This routine displays the "File System" pulldown submenu. It gets
* placed next to the main "Actions" pulldown menu.
*/
void draw_fsys_menu(void)
{
if (fsys_menu == NULL) {
fsys_menu = create_popup_menu();
append_fsys_menu_items();
create_menu_panel(fsys_menu, 0, 0);
cascade_menu(fsys_menu, actions_menu, FSYS_MENUITEM);
}
show_panel_window(fsys_menu->panel, TRUE);
}
/**
* fsys_menuitem_activated - function invoked when "File System" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "File System" menu item
* in the "Actions" menu is selected. It draws the "File System" pulldown submenu
* and processes menu events.
*/
int fsys_menuitem_activated(struct menu_item *item)
{
int rc;
draw_fsys_menu();
rc = process_menu_events(fsys_menu);
return rc;
}
/**
* append_actions_menu_items - appends the "Actions" menu items
* @void
*
* This routine appends the menu items for the "Actions" drop down menu.
*/
inline void append_actions_menu_items(void)
{
append_menu_item(actions_menu, _("Create"), NULL, get_accelerator_char(_("_Create")),
TRUE, (menuitem_activate_cb)create_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Delete"), NULL, get_accelerator_char(_("_Delete")),
TRUE, (menuitem_activate_cb)delete_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Activation"), NULL, get_accelerator_char(_("Act_ivation")),
TRUE, (menuitem_activate_cb)activation_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Expand"), NULL, get_accelerator_char(_("_Expand")),
TRUE, (menuitem_activate_cb)expand_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Shrink"), NULL, get_accelerator_char(_("S_hrink")),
TRUE, (menuitem_activate_cb)shrink_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Add"), NULL, get_accelerator_char(_("_Add")),
TRUE, (menuitem_activate_cb)add_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Remove"), NULL, get_accelerator_char(_("_Remove")),
TRUE, (menuitem_activate_cb)remove_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Modify"), NULL, get_accelerator_char(_("_Modify")),
TRUE, (menuitem_activate_cb)modify_menuitem_activated, NULL);
append_menu_item(actions_menu, _("View"), NULL, get_accelerator_char(_("_View")),
TRUE, (menuitem_activate_cb)view_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Convert"), NULL, get_accelerator_char(_("C_onvert")),
TRUE, (menuitem_activate_cb)convert_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Replace..."), NULL, get_accelerator_char(_("Re_place...")),
FALSE, (menuitem_activate_cb)actions_replace_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Other"), NULL, get_accelerator_char(_("O_ther")),
TRUE, (menuitem_activate_cb)other_menuitem_activated, NULL);
append_menu_item(actions_menu, _("File System"), NULL, get_accelerator_char(_("_File System")),
TRUE, (menuitem_activate_cb)fsys_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Save..."), NULL, get_accelerator_char(_("_Save...")),
FALSE, (menuitem_activate_cb)on_save_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Backup..."), NULL, get_accelerator_char(_("_Backup...")),
FALSE, (menuitem_activate_cb)on_backup_menuitem_activated, NULL);
append_menu_item(actions_menu, _("Quit"), NULL, get_accelerator_char(_("_Quit")),
FALSE, (menuitem_activate_cb)on_quit_menuitem_activated, NULL);
}
/**
* draw_actions_menu - draws the actions menu pulldown
* @void
*
* This routine displays the "Actions" menu. If the menu
* already existing, it is simply redisplayed. Otherwise,
* the panel window is created and the menu items are
* initialized and displayed.
*/
void draw_actions_menu(void)
{
if (actions_menu == NULL) {
actions_menu = create_popup_menu();
append_actions_menu_items();
create_menu_panel(actions_menu, 1, 0);
}
show_panel_window(actions_menu->panel, TRUE);
}
/**
* actions_menuitem_activated - function invoked when "Actions" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Actions" menu item
* in the main menubar is selected. It draws the actions pulldown menu and
* processes menu events.
*/
int actions_menuitem_activated(struct menu_item *item)
{
int rc;
draw_actions_menu();
rc = process_menu_events(actions_menu);
return rc;
}
/**
* append_settings_menu_items - appends the "Settings" menu items
* @void
*
* This routine appends the menu items for the "Settings" drop down menu.
*/
inline void append_settings_menu_items(void)
{
struct menu_item *new_item;
append_menu_item(settings_menu, _("Log Level..."), NULL,
get_accelerator_char(_("_Log Level...")),
FALSE, (menuitem_activate_cb)show_log_level_dialog_menuitem_activated,
NULL);
new_item = append_menu_item(settings_menu, _("Node Administered..."), NULL,
get_accelerator_char(_("_Node Administered...")),
FALSE, (menuitem_activate_cb)show_nodes_dialog_menuitem_activated,
NULL);
if (get_number_of_nodes() <= 1) {
set_menu_item_sensitivity(new_item, 0);
}
}
/**
* draw_settings_menu - draws the settings menu pulldown
* @void
*
* This routine displays the "Settings" menu. If the menu
* already existing, it is simply redisplayed. Otherwise,
* the panel window is created and the menu items are
* initialized and displayed.
*/
void draw_settings_menu(void)
{
if (settings_menu == NULL) {
settings_menu = create_popup_menu();
append_settings_menu_items();
create_menu_panel(settings_menu, 1, strlen(_("Actions")) + 3);
}
show_panel_window(settings_menu->panel, TRUE);
}
/**
* settings_menuitem_activated - function invoked when "Settings" menu item activated
* @item: the menu item that caused this function to get invoked
*
* This routine is a callback routine invoked when the "Settings" menu item
* in the main menubar is selected. It draws the Settings pulldown menu and
* processes menu events.
*/
int settings_menuitem_activated(struct menu_item *item)
{
int rc;
draw_settings_menu();
rc = process_menu_events(settings_menu);
return rc;
}
/**
* append_navigation_menu_items - append menu items to allow jumping to parent, etc.
* @menu: the popup menu
* @handle: the object handle
*
* This routine appends menu items that allows the user to jump or go to a
* a storage objects parent, consuming container or producing container.
*/
void append_navigation_menu_items(struct popup_menu *menu, object_handle_t handle)
{
object_handle_t parent;
object_handle_t consuming_container;
object_handle_t producing_container;
get_object_handles(handle, &parent, &producing_container, &consuming_container);
if (parent != 0) {
append_menu_item(menu, _("Go to parent object"), NULL, 0, FALSE,
(menuitem_activate_cb)jump_to_view_by_handle,
GUINT_TO_POINTER(parent));
}
if (producing_container != 0) {
append_menu_item(menu, _("Go to producing container"), NULL, 0, FALSE,
(menuitem_activate_cb)jump_to_view_by_handle,
GUINT_TO_POINTER(producing_container));
}
if (consuming_container != 0) {
append_menu_item(menu, _("Go to consuming container"), NULL, 0, FALSE,
(menuitem_activate_cb)jump_to_view_by_handle,
GUINT_TO_POINTER(consuming_container));
}
}
/**
* append_object_menu_items - append menu items for actions pertaining to storage objects
* @menu: the popup menu
* @handle: the object handle
* @type: the object type
*
* This routine appends menu items of allowed storage object actions for the
* given storage object handle.
*/
void append_object_menu_items(struct popup_menu *menu, object_handle_t handle, object_type_t type)
{
void *handle_data;
handle_data = GUINT_TO_POINTER(handle);
append_menu_item(menu, _("Display Object Tree..."), NULL, 0, FALSE,
(menuitem_activate_cb)display_object_tree_menuitem_activated,
handle_data);
if (evms_can_activate(handle) == 0) {
append_menu_item(menu, _("Activate..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_activate_menuitem_activated,
handle_data);
}
if (evms_can_deactivate(handle) == 0) {
append_menu_item(menu, _("Deactivate..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_deactivate_menuitem_activated,
handle_data);
}
if (can_create_from_freespace_object(handle) == TRUE) {
if (type == REGION) {
append_menu_item(menu, _("Create Region..."), NULL, 0, FALSE,
(menuitem_activate_cb)create_region_menuitem_activated,
handle_data);
} else if (type == SEGMENT) {
append_menu_item(menu, _("Create Segment..."), NULL, 0, FALSE,
(menuitem_activate_cb)create_segment_menuitem_activated,
handle_data);
}
}
if (can_create_feature_object(handle) == TRUE) {
append_menu_item(menu, _("Create Feature Object..."), NULL, 0, FALSE,
(menuitem_activate_cb)create_feature_menuitem_activated,
handle_data);
}
if (evms_can_create_volume(handle) == 0) {
append_menu_item(menu, _("Create EVMS Volume..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_create_evms_vol_menuitem_activated,
handle_data);
}
if (evms_can_create_compatibility_volume(handle) == 0) {
append_menu_item(menu, _("Create Compatibility Volume..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_create_vol_menuitem_activated,
handle_data);
}
if (evms_can_set_info(handle) == 0) {
append_menu_item(menu, _("Modify Properties..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_modify_object_menuitem_activated,
handle_data);
}
if (evms_can_delete(handle) == 0) {
append_menu_item(menu, _("Delete..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_delete_menuitem_activated,
handle_data);
}
if (evms_can_expand(handle) == 0) {
append_menu_item(menu, _("Expand..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_expand_object_menuitem_activated,
handle_data);
}
if (evms_can_shrink(handle) == 0) {
append_menu_item(menu, _("Shrink..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_shrink_object_menuitem_activated,
handle_data);
}
if (can_replace_object(handle) == 0) {
append_menu_item(menu, _("Replace..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_replace_menuitem_activated,
handle_data);
}
if (can_remove_from_container(handle) == 0) {
append_menu_item(menu, _("Remove from Container..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_remove_consumed_object_menuitem_activated,
handle_data);
}
if (evms_can_unassign(handle) == 0) {
gchar *text;
text = g_strdup_printf(_("Remove %s from Object..."),
get_parent_plugin_type_string(handle, TRUE));
append_menu_item(menu, text, NULL, 0, FALSE,
(menuitem_activate_cb)context_remove_segment_manager_menuitem_activated,
handle_data);
g_free(text);
}
}
/**
* append_volume_menu_items - append menu items for actions pertaining to volumes
* @menu: the popup menu
* @handle: the object handle
*
* This routine appends menu items of allowed logical volume actions for the
* given logical volume handle.
*/
void append_volume_menu_items(struct popup_menu *menu, object_handle_t handle)
{
void *handle_data;
handle_object_info_t *volume;
handle_data = GUINT_TO_POINTER(handle);
if (evms_get_info(handle, &volume) == 0) {
append_menu_item(menu, _("Display Object Tree..."), NULL, 0, FALSE,
(menuitem_activate_cb)display_object_tree_menuitem_activated,
GUINT_TO_POINTER(volume->info.volume.object));
evms_free(volume);
}
if (evms_can_activate(handle) == 0) {
append_menu_item(menu, _("Activate..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_activate_menuitem_activated,
handle_data);
}
if (evms_can_deactivate(handle) == 0) {
append_menu_item(menu, _("Deactivate..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_deactivate_menuitem_activated,
handle_data);
}
if (can_volume_accept_new_feature(handle) == TRUE) {
append_menu_item(menu, _("Add Feature..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_add_feature_menuitem_activated,
handle_data);
}
if (evms_can_convert_to_evms_volume(handle) == 0) {
append_menu_item(menu, _("Convert to EVMS Volume..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_convert_vol_menuitem_activated,
handle_data);
}
if (evms_can_convert_to_compatibility_volume(handle) == 0) {
append_menu_item(menu, _("Convert to Compatibility Volume..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_convert_evms_vol_menuitem_activated,
handle_data);
}
if (evms_can_set_volume_name(handle) == 0) {
append_menu_item(menu, _("Change Volume Name..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_modify_vol_menuitem_activated,
handle_data);
}
if (evms_can_delete(handle) == 0) {
append_menu_item(menu, _("Delete..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_delete_menuitem_activated,
handle_data);
}
if (evms_can_expand(handle) == 0) {
append_menu_item(menu, _("Expand..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_expand_volume_menuitem_activated,
handle_data);
}
if (evms_can_shrink(handle) == 0) {
append_menu_item(menu, _("Shrink..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_shrink_volume_menuitem_activated,
handle_data);
}
}
/**
* append_filesys_menu_items - append menu items for filesystem actions on a volume
* @menu: the popup menu
* @handle: the object handle
*
* This routine appends menu items of allowed filesystem actions for the
* given logical volume handle.
*/
void append_filesys_menu_items(struct popup_menu *menu, object_handle_t handle)
{
void *handle_data;
handle_data = GUINT_TO_POINTER(handle);
if (evms_can_mount(handle) == 0) {
append_menu_item(menu, _("Mount..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_mount_filesystem_menuitem_activated,
handle_data);
}
if (evms_can_unmount(handle) == 0) {
append_menu_item(menu, _("Unmount..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_unmount_filesystem_menuitem_activated,
handle_data);
}
if (volume_has_fsim(handle) == TRUE) {
if (evms_can_fsck(handle) == 0) {
append_menu_item(menu, _("Check/Repair File System..."), NULL, 0,
FALSE,
(menuitem_activate_cb)context_fsck_menuitem_activated,
handle_data);
}
if (evms_can_unmkfs(handle) == 0) {
append_menu_item(menu, _("Remove File System..."), NULL, 0,
FALSE,
(menuitem_activate_cb)context_unmkfs_menuitem_activated,
handle_data);
}
}
if (can_volume_be_formatted(handle) == TRUE) {
append_menu_item(menu, _("Make File System..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_mkfs_menuitem_activated,
handle_data);
}
}
/**
* append_container_menu_items - append menu items for actions pertaining to storage containers
* @menu: the popup menu
* @handle: the object handle
*
* This routine appends menu items of allowed storage container actions for the
* given storage container handle.
*/
void append_container_menu_items(struct popup_menu *menu, object_handle_t handle)
{
void *handle_data;
handle_data = GUINT_TO_POINTER(handle);
if (evms_can_set_info(handle) == 0) {
append_menu_item(menu, _("Modify Properties..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_modify_container_menuitem_activated,
handle_data);
}
if (evms_can_delete(handle) == 0) {
append_menu_item(menu, _("Delete..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_delete_menuitem_activated,
handle_data);
}
if (evms_can_expand(handle) == 0) {
append_menu_item(menu, _("Expand..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_expand_container_menuitem_activated,
handle_data);
}
if (evms_can_shrink(handle) == 0) {
append_menu_item(menu, _("Shrink..."), NULL, 0, FALSE,
(menuitem_activate_cb)context_shrink_container_menuitem_activated,
handle_data);
}
}
/**
* append_common_menu_items - append menu items for actions pertaining to all types
* @menu: the popup menu
* @handle: the object handle
*
* This routine appends menu items that apply to all object types without requiring
* a check.
*/
void append_common_menu_items(struct popup_menu *menu, object_handle_t handle)
{
void *handle_data;
handle_data = GUINT_TO_POINTER(handle);
append_menu_item(menu, _("Display details..."), NULL, 0, FALSE,
(menuitem_activate_cb)display_details_menuitem_activated,
handle_data);
}
/**
* append_context_menu_items - appends actions available for the given handle
* @menu: the popup menu
* @handle: the object handle
*
* This routine appends menu items to the context popup menu for actions available
* on the given object handle.
*/
void append_context_menu_items(struct popup_menu *menu, object_handle_t handle)
{
object_type_t type;
g_return_if_fail(evms_get_handle_object_type(handle, &type) == 0);
switch (type) {
case EVMS_OBJECT:
case REGION:
case SEGMENT:
case DISK:
append_navigation_menu_items(menu, handle);
append_common_menu_items(menu, handle);
append_object_menu_items(menu, handle, type);
break;
case VOLUME:
append_common_menu_items(menu, handle);
append_volume_menu_items(menu, handle);
append_filesys_menu_items(menu, handle);
break;
case CONTAINER:
append_common_menu_items(menu, handle);
append_container_menu_items(menu, handle);
break;
case PLUGIN:
append_common_menu_items(menu, handle);
break;
default:
log_warning("%s: Unknown type %d encountered.\n", __FUNCTION__, type);
break;
}
append_plugin_function_menu_items(menu, handle);
}
/**
* popup_context_menu - display and process a context popup menu for a handle
* @handle: the object handle
* @starty: where to position the menu on the screen
* @startx: where to position the menu on the screen
*
* This routine creates a context popup menu for a given object handle. It
* populates the menu with selections only valid for this object. The context
* popup is a modal window.
*/
void popup_context_menu(object_handle_t handle, int starty, int startx)
{
struct popup_menu *menu;
menu = create_popup_menu();
append_context_menu_items(menu, handle);
create_menu_panel(menu, starty, startx);
process_menu_events(menu);
delete_popup_menu(menu);
}