Files
nethack/win/gnome/gnmenu.c

758 lines
22 KiB
C

/* NetHack 3.5 gnmenu.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */
/* NetHack 3.5 gnmenu.c $Date: 2009/05/06 10:57:36 $ $Revision: 1.6 $ */
/* SCCS Id: @(#)gnmenu.c 3.5 2000/07/16 */
/* Copyright (C) 1998 by Erik Andersen <andersee@debian.org> */
/* NetHack may be freely redistributed. See license for details. */
#include <string.h>
#include <gtk/gtk.h>
#include <gnome.h>
#include "gnmenu.h"
#include "gnmain.h"
#include "gnbind.h"
#include "func_tab.h"
typedef enum {
MenuUnknown = 0,
MenuText,
MenuMenu
} MenuWinType;
typedef struct {
ANY_P identifier;
gchar accelerator[BUFSZ];
int itemNumber;
int selected;
} menuItem;
typedef struct {
int curItem;
int numRows;
int charIdx;
guint32 lastTime;
} extMenu;
static GdkColor color_blue = { 0, 0, 0, 0xffff };
static void
ghack_menu_window_key(GtkWidget *menuWin, GdkEventKey *event, gpointer data)
{
int i, numRows;
menuItem* item;
MenuWinType isMenu;
isMenu = (MenuWinType) GPOINTER_TO_INT
(gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu"));
if (isMenu == MenuMenu) {
GtkWidget *clist;
gint selection_mode;
clist = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (menuWin), "clist"));
g_assert (clist != NULL);
numRows = GPOINTER_TO_INT
(gtk_object_get_data(GTK_OBJECT(clist), "numRows"));
selection_mode = GPOINTER_TO_INT
(gtk_object_get_data (GTK_OBJECT(clist), "selection_mode"));
for (i = 0; i <= numRows; ++i) {
item = (menuItem*) gtk_clist_get_row_data(GTK_CLIST(clist), i);
if (item == NULL) continue;
if (!strcmp(item->accelerator, "")) continue;
if ((!strcmp(item->accelerator, event->string)) ||
((selection_mode == GTK_SELECTION_MULTIPLE) &&
(event->keyval == ','))) {
if (item->selected) {
gtk_clist_unselect_row( GTK_CLIST (clist),
item->itemNumber, 0);
item->selected = FALSE;
} else {
gtk_clist_select_row(GTK_CLIST (clist),
item->itemNumber, 0);
if (gtk_clist_row_is_visible(GTK_CLIST(clist),
item->itemNumber) != GTK_VISIBILITY_FULL)
gtk_clist_moveto(GTK_CLIST(clist),
item->itemNumber, 0, 0.5, 0);
item->selected = TRUE;
}
}
}
}
}
static void
ghack_menu_row_selected (GtkCList *clist, int row, int col, GdkEvent *event)
{
/* FIXME: Do something */
}
void
ghack_menu_window_clear(GtkWidget *menuWin, gpointer data)
{
MenuWinType isMenu;
int i, numRows;
menuItem* item;
isMenu = (MenuWinType) GPOINTER_TO_INT
(gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu"));
if (isMenu == MenuMenu) {
GtkWidget *clist;
clist = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (menuWin), "clist"));
g_assert (clist != NULL);
/* destroy existing menu data, if any */
if (clist) {
/* destroy all the row_data we stored in the clist */
numRows = GPOINTER_TO_INT( gtk_object_get_data(
GTK_OBJECT(clist), "numRows") );
for( i=0; i<numRows; i++) {
item = (menuItem*) gtk_clist_get_row_data(
GTK_CLIST (clist), i);
if (item != NULL) {
g_free( item);
gtk_clist_set_row_data (GTK_CLIST (clist), i,
(gpointer) NULL);
}
}
gtk_object_set_data (GTK_OBJECT (clist), "numItems",
GINT_TO_POINTER (-1));
gtk_clist_clear (GTK_CLIST (clist));
}
}
else if (isMenu == MenuText) {
GnomeLess *gless;
gless = GNOME_LESS (gtk_object_get_data (GTK_OBJECT (menuWin), "gless"));
g_assert (gless != NULL);
gtk_editable_delete_text (GTK_EDITABLE (gless->text), 0, 0);
}
}
void
ghack_menu_window_display(GtkWidget *menuWin, gboolean blocking,
gpointer data)
{
//if(blocking) {
gnome_dialog_close_hides (GNOME_DIALOG (menuWin), TRUE);
gnome_dialog_set_close (GNOME_DIALOG (menuWin), TRUE);
gnome_dialog_run_and_close(GNOME_DIALOG (menuWin));
//}
//else {
//gtk_widget_show(menuWin);
//}
}
gint
ghack_menu_hide( GtkWidget *menuWin, GdkEvent *event, gpointer data )
{
gtk_widget_hide (menuWin);
return FALSE; /* FIXME: what is correct result here? */
}
void
ghack_menu_window_start_menu (GtkWidget *menuWin, gpointer data)
{
GtkWidget *frame1, *swin, *clist;
MenuWinType isMenu;
g_assert (menuWin != NULL);
g_assert (data == NULL);
/* destroy existing menu data, if any */
frame1 = gtk_object_get_data (GTK_OBJECT (menuWin), "frame1");
if (frame1)
gtk_widget_destroy (frame1);
isMenu = MenuMenu;
gtk_object_set_data (GTK_OBJECT (menuWin), "isMenu",
GINT_TO_POINTER (isMenu));
gtk_widget_set_usize (GTK_WIDGET (menuWin), 500, 400);
gtk_window_set_policy (GTK_WINDOW (menuWin), TRUE, TRUE, FALSE);
frame1 = gtk_frame_new ("Make your selection");
g_assert (frame1 != NULL);
gtk_object_set_data (GTK_OBJECT(menuWin), "frame1", frame1);
gtk_widget_show (GTK_WIDGET (frame1));
gtk_container_set_border_width (GTK_CONTAINER (frame1), 5);
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG(menuWin)->vbox), frame1,
TRUE, TRUE, 0);
swin = gtk_scrolled_window_new (NULL, NULL);
g_assert (swin != NULL);
gtk_object_set_data (GTK_OBJECT(menuWin), "swin", swin);
gtk_widget_show (GTK_WIDGET (swin));
gtk_container_add (GTK_CONTAINER (frame1), swin);
clist = gtk_clist_new (4);
g_assert (clist != NULL);
gtk_object_set_data (GTK_OBJECT(menuWin), "clist", clist);
gtk_widget_show (GTK_WIDGET (clist));
gtk_container_add (GTK_CONTAINER (swin), clist);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_signal_connect (GTK_OBJECT (clist), "select_row",
GTK_SIGNAL_FUNC (ghack_menu_row_selected), NULL);
gtk_object_set_data (GTK_OBJECT (clist), "numItems",
GINT_TO_POINTER (-1));
}
int
ghack_menu_window_select_menu (GtkWidget *menuWin,
MENU_ITEM_P **_selected, gint how)
{
gint rc;
guint num_sel, i, idx;
GtkWidget *clist;
GList *cur;
MENU_ITEM_P *selected = NULL;
menuItem* item;
g_assert (_selected != NULL);
*_selected = NULL;
if (how == PICK_NONE) {
gnome_dialog_close_hides (GNOME_DIALOG (menuWin), TRUE);
rc = gnome_dialog_run_and_close (GNOME_DIALOG (menuWin));
return( rc == 1 ? -1 : 0);
}
clist = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (menuWin), "clist"));
g_assert (clist != NULL);
gtk_object_set_data (GTK_OBJECT (clist), "selection_mode",
GINT_TO_POINTER ((how == PICK_ANY)?
GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE));
gtk_clist_set_selection_mode (GTK_CLIST (clist),
(how == PICK_ANY)? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE);
gnome_dialog_close_hides (GNOME_DIALOG (menuWin), TRUE);
rc = gnome_dialog_run_and_close (GNOME_DIALOG (menuWin));
if ((rc == 1) || (GTK_CLIST (clist)->selection == NULL)) {
return(-1);
}
num_sel = g_list_length (GTK_CLIST (clist)->selection);
if (num_sel < 1) {
return(-1);
}
/* fill in array with selections from clist */
selected = g_new0( MENU_ITEM_P, num_sel);
g_assert (selected != NULL);
cur = GTK_CLIST (clist)->selection;
i = 0;
while (cur) {
g_assert (i < num_sel);
/* grab row number from clist selection list */
idx = GPOINTER_TO_INT (cur->data);
item = (menuItem*) gtk_clist_get_row_data( GTK_CLIST (clist), idx);
selected[i].item = item->identifier;
selected[i].count = -1;
cur = g_list_next(cur);
i++;
}
*_selected = selected;
return( (int) num_sel);
}
void
ghack_menu_window_add_menu( GtkWidget *menuWin, gpointer menu_item,
gpointer data)
{
GHackMenuItem* item;
GtkWidget *clist;
gchar buf[BUFSZ]="", accelBuf[BUFSZ]="";
gchar *pbuf;
char *text[4] = { buf, NULL, NULL, NULL };
gint nCurrentRow = -1, numItems = -1;
MenuWinType isMenu;
GtkStyle *bigStyle = NULL;
gboolean item_selectable;
GdkImlibImage* image;
static gboolean special;
g_assert (menu_item != NULL);
item = (GHackMenuItem*) menu_item;
item_selectable = ( item->identifier->a_int == 0)? FALSE : TRUE;
isMenu = (MenuWinType) GPOINTER_TO_INT
(gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu"));
clist = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (menuWin), "clist"));
g_assert (clist != NULL);
/* This is a special kludge to make the special hidden help menu item work as designed */
if ( special==TRUE ) {
special=FALSE;
item_selectable=TRUE;
}
if ( ! strcmp( item->str, "The NetHack license.")) {
special=TRUE;
}
if (item->str) {
/* First, make a new blank entry in the clist */
nCurrentRow = gtk_clist_append (GTK_CLIST (clist), text);
if (item->glyph != NO_GLYPH) {
image = ghack_image_from_glyph( item->glyph, FALSE);
if (image==NULL || image->pixmap==NULL) {
g_warning("Bummer -- having to force rendering for glyph %d!", item->glyph);
/* wierd -- pixmap is NULL so retry rendering it */
image = ghack_image_from_glyph( item->glyph, TRUE);
}
if (image==NULL || image->pixmap==NULL) {
g_error("Aiiee! glyph is still NULL for item\n\"%s\"",
item->str);
}
else
gtk_clist_set_pixmap (GTK_CLIST (clist),
nCurrentRow, 1,
gdk_imlib_move_image( image),
gdk_imlib_move_mask( image));
}
if (item->accelerator) {
/* FIXME: handle accelerator, */
g_snprintf(accelBuf, sizeof(accelBuf), "%c ", item->accelerator);
gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 0, accelBuf);
g_snprintf(buf, sizeof(buf), "%s", item->str);
gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 2, buf);
} else {
if (item->group_accel) {
/* FIXME: maybe some day I should try to handle
* group accelerators... */
}
if (( (item->attr == 0) && (item->identifier->a_int != 0)) || (special ==TRUE) ) {
numItems = GPOINTER_TO_INT( gtk_object_get_data(
GTK_OBJECT(clist), "numItems") )+1;
/* Ok, now invent a unique accelerator */
if ( ('a'+numItems) <= 'z' ) {
g_snprintf(accelBuf, sizeof(accelBuf), "%c ", 'a'+numItems);
gtk_clist_set_text(GTK_CLIST(clist), nCurrentRow, 0, accelBuf);
}
else if ( ('A'+numItems-26)<='Z') {
g_snprintf(accelBuf, sizeof(accelBuf), "%c ", 'A'+numItems-26);
gtk_clist_set_text(GTK_CLIST(clist), nCurrentRow, 0, accelBuf);
} else {
accelBuf[0] = buf[0] = 0;
}
g_snprintf(buf, sizeof(buf), "%s", item->str);
gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 2, buf);
gtk_object_set_data (GTK_OBJECT (clist), "numItems",
GINT_TO_POINTER (numItems));
/* This junk is to specially handle the options menu */
pbuf = strstr( buf, " [");
if (pbuf == NULL) {
pbuf = strstr( buf, "\t[");
}
if (pbuf != NULL) {
*pbuf=0;
pbuf++;
gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 3, pbuf);
}
}
/* FIXME: handle more than 26*2 accelerators (but how?
* since I only have so many keys to work with???)
else
{
foo();
}
*/
else {
g_snprintf(buf, sizeof(buf), "%s", item->str);
pbuf = strstr( buf, " [");
if (pbuf == NULL) {
pbuf = strstr( buf, "\t[");
}
if (pbuf != NULL) {
*pbuf=0;
pbuf++;
gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 3, pbuf);
}
gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 2, buf);
}
}
if (item->attr) {
switch(item->attr) {
case ATR_ULINE:
case ATR_BOLD:
case ATR_BLINK:
case ATR_INVERSE:
bigStyle = gtk_style_copy (GTK_WIDGET (clist)->style);
g_assert (bigStyle != NULL);
gdk_font_unref (bigStyle->font);
bigStyle->font = gdk_font_load (
"-misc-fixed-*-*-*-*-20-*-*-*-*-*-*-*");
bigStyle->fg[GTK_STATE_NORMAL] = color_blue;
gtk_clist_set_cell_style (GTK_CLIST (clist),
nCurrentRow, 2, bigStyle);
item_selectable = FALSE;
}
}
g_assert (nCurrentRow >= 0);
gtk_clist_set_selectable (GTK_CLIST (clist), nCurrentRow,
item_selectable);
if ( item_selectable==TRUE && item->presel== TRUE) {
/* pre-select this item */
gtk_clist_select_row( GTK_CLIST (clist), nCurrentRow, 0);
}
gtk_object_set_data (GTK_OBJECT (clist), "numRows",
GINT_TO_POINTER (nCurrentRow));
/* We have to allocate memory here, since the menu_item currently
* lives on the stack, and will otherwise go to the great bit bucket
* in the sky as soon as this function exits, which would leave a
* pointer to crap in the row_data. Use g_memdup to make a private,
* persistant copy of the item identifier.
*
* We need to arrange to blow away this memory somewhere (like
* ghack_menu_destroy and ghack_menu_window_clear for example).
*
* -Erik
*/
{
menuItem newItem;
menuItem *pNewItem;
newItem.identifier = *item->identifier;
newItem.itemNumber=nCurrentRow;
newItem.selected=FALSE;
newItem.accelerator[0]=0;
/* only copy 1 char, since accel keys are by definition 1 char */
if (accelBuf[0]) {
strncpy(newItem.accelerator, accelBuf, 1);
}
newItem.accelerator[1]=0;
pNewItem = g_memdup(&newItem, sizeof( menuItem));
gtk_clist_set_row_data (GTK_CLIST (clist), nCurrentRow,
(gpointer) pNewItem);
}
}
/* Now adjust the column widths to match the contents */
gtk_clist_columns_autosize (GTK_CLIST (clist));
}
void
ghack_menu_window_end_menu (GtkWidget *menuWin, gpointer data)
{
const char* p = (const char*) data;
if ((p) && (*p)) {
GtkWidget *frame1 = gtk_object_get_data (GTK_OBJECT (menuWin), "frame1");
g_assert (frame1 != NULL);
gtk_frame_set_label (GTK_FRAME(frame1), p);
}
}
void ghack_menu_window_put_string(GtkWidget *menuWin, int attr,
const char* text, gpointer data)
{
GnomeLess *gless;
MenuWinType isMenu;
if (text == NULL)
return;
isMenu = (MenuWinType) GPOINTER_TO_INT
(gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu"));
if (isMenu == MenuText) {
gless = GNOME_LESS (gtk_object_get_data (GTK_OBJECT (menuWin), "gless"));
g_assert (gless != NULL);
g_assert (gless->text != NULL);
g_assert (GTK_IS_TEXT (gless->text));
/* Don't bother with attributes yet */
gtk_text_insert (GTK_TEXT (gless->text), NULL, NULL, NULL, text, -1);
gtk_text_insert (GTK_TEXT (gless->text), NULL, NULL, NULL, "\n", -1);
}
else if (isMenu == MenuUnknown) {
isMenu = MenuText;
gtk_object_set_data (GTK_OBJECT (menuWin), "isMenu",
GINT_TO_POINTER (isMenu));
gtk_widget_set_usize (GTK_WIDGET (menuWin), 500, 400);
gtk_window_set_policy (GTK_WINDOW (menuWin), TRUE, TRUE, FALSE);
gless = GNOME_LESS (gnome_less_new ());
g_assert (gless != NULL);
gtk_object_set_data (GTK_OBJECT (menuWin), "gless", gless);
gtk_widget_show (GTK_WIDGET (gless));
gnome_less_show_string (gless, text);
gtk_text_insert (GTK_TEXT (gless->text), NULL, NULL, NULL, "\n", -1);
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (menuWin)->vbox),
GTK_WIDGET (gless), TRUE, TRUE, 0);
}
}
void
ghack_menu_destroy (GtkWidget *menuWin, gpointer data)
{
MenuWinType isMenu;
isMenu = (MenuWinType) GPOINTER_TO_INT
(gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu"));
if (isMenu == MenuText) {
GnomeLess *gless;
gless = GNOME_LESS (gtk_object_get_data (GTK_OBJECT (menuWin), "gless"));
g_assert (gless != NULL);
g_assert (gless->text != NULL);
g_assert (GTK_IS_TEXT (gless->text));
gtk_widget_destroy(GTK_WIDGET(gless));
}
else if (isMenu == MenuMenu) {
GtkWidget *frame1, *swin, *clist;
/* destroy existing menu data, if any */
clist = gtk_object_get_data (GTK_OBJECT (menuWin), "clist");
if (clist) {
/* destroy all the row_data we stored in the clist */
int i, numRows;
menuItem* item;
numRows = GPOINTER_TO_INT( gtk_object_get_data(
GTK_OBJECT(clist), "numRows") );
for( i=0; i<numRows; i++) {
item = (menuItem*) gtk_clist_get_row_data(
GTK_CLIST (clist), i);
if (item != NULL) {
g_free( item);
gtk_clist_set_row_data (GTK_CLIST (clist), i,
(gpointer) NULL);
}
}
gtk_object_set_data (GTK_OBJECT (clist), "numItems",
GINT_TO_POINTER (-1));
gtk_widget_destroy (clist);
}
swin = gtk_object_get_data (GTK_OBJECT (menuWin), "swin");
if (swin) {
gtk_widget_destroy (swin);
}
frame1 = gtk_object_get_data (GTK_OBJECT (menuWin), "frame1");
if (frame1) {
gtk_widget_destroy (frame1);
}
}
gnome_delete_nhwindow_by_reference (menuWin);
}
GtkWidget*
ghack_init_menu_window (void)
{
GtkWidget *menuWin = NULL;
GtkWidget *parent = ghack_get_main_window ();
menuWin = gnome_dialog_new("GnomeHack", GNOME_STOCK_BUTTON_OK,
GNOME_STOCK_BUTTON_CANCEL, NULL);
gnome_dialog_set_default( GNOME_DIALOG(menuWin), 0);
gtk_signal_connect(GTK_OBJECT(menuWin), "destroy",
GTK_SIGNAL_FUNC(ghack_menu_destroy),
NULL);
gtk_signal_connect (GTK_OBJECT (menuWin), "delete_event",
GTK_SIGNAL_FUNC (ghack_menu_hide),
NULL);
gtk_signal_connect(GTK_OBJECT(menuWin), "ghack_clear",
GTK_SIGNAL_FUNC(ghack_menu_window_clear),
NULL);
gtk_signal_connect(GTK_OBJECT(menuWin), "ghack_display",
GTK_SIGNAL_FUNC(ghack_menu_window_display),
NULL);
gtk_signal_connect(GTK_OBJECT(menuWin), "ghack_start_menu",
GTK_SIGNAL_FUNC(ghack_menu_window_start_menu),
NULL);
gtk_signal_connect(GTK_OBJECT(menuWin), "ghack_add_menu",
GTK_SIGNAL_FUNC(ghack_menu_window_add_menu),
NULL);
gtk_signal_connect(GTK_OBJECT(menuWin), "ghack_end_menu",
GTK_SIGNAL_FUNC(ghack_menu_window_end_menu),
NULL);
gtk_signal_connect(GTK_OBJECT(menuWin), "ghack_select_menu",
GTK_SIGNAL_FUNC(ghack_menu_window_select_menu),
NULL);
gtk_signal_connect(GTK_OBJECT(menuWin), "ghack_putstr",
GTK_SIGNAL_FUNC(ghack_menu_window_put_string),
NULL);
gtk_signal_connect(GTK_OBJECT(menuWin), "key_press_event",
GTK_SIGNAL_FUNC(ghack_menu_window_key),
NULL);
/* Center the dialog over parent */
g_assert (parent != NULL);
g_assert (menuWin != NULL);
g_assert (GTK_IS_WINDOW (parent));
g_assert (GNOME_IS_DIALOG (menuWin));
gnome_dialog_set_parent (GNOME_DIALOG (menuWin), GTK_WINDOW (parent));
return menuWin;
}
static void
ghack_ext_key_hit(GtkWidget *menuWin, GdkEventKey *event, gpointer data)
{
GtkWidget* clist;
extMenu* info = (extMenu*) data;
int i;
char c = event->string[0];
clist = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(menuWin), "clist"));
g_assert(clist != NULL);
/* if too long between keystrokes, reset to initial state */
if (event->time - info->lastTime > 500) goto init_state;
/* see if current item continue to match */
if (info->charIdx > 0) {
if (extcmdlist[info->curItem].ef_txt[info->charIdx] == c) {
++info->charIdx;
goto found;
}
}
/* see if the prefix matches a later command in the list */
if (info->curItem >= 0) {
for (i = info->curItem + 1; i < info->numRows; ++i) {
if (!strncmp(extcmdlist[info->curItem].ef_txt,
extcmdlist[i].ef_txt, info->charIdx)) {
if (extcmdlist[i].ef_txt[info->charIdx] == c) {
++info->charIdx;
info->curItem = i;
goto found;
}
}
}
}
init_state:
/* reset to initial state, look for matching 1st character */
for (i = 0; i < info->numRows; ++i) {
if (extcmdlist[i].ef_txt[0] == c) {
info->charIdx = 1;
info->curItem = i;
goto found;
}
}
/* no match: leave prior, if any selection in place */
return;
found:
info->lastTime = event->time;
gtk_clist_select_row(GTK_CLIST(clist), info->curItem, 0);
if (gtk_clist_row_is_visible(GTK_CLIST(clist),
info->curItem) != GTK_VISIBILITY_FULL)
gtk_clist_moveto(GTK_CLIST(clist), info->curItem, 0, 0.5, 0);
}
int
ghack_menu_ext_cmd(void)
{
int n;
GtkWidget* dialog;
GtkWidget* swin;
GtkWidget* frame1;
GtkWidget* clist;
extMenu info;
dialog = gnome_dialog_new("Extended Commands",
GNOME_STOCK_BUTTON_OK,
GNOME_STOCK_BUTTON_CANCEL,
NULL);
gnome_dialog_close_hides(GNOME_DIALOG(dialog), FALSE);
gtk_signal_connect(GTK_OBJECT(dialog), "key_press_event",
GTK_SIGNAL_FUNC(ghack_ext_key_hit), &info);
frame1 = gtk_frame_new("Make your selection");
gtk_object_set_data(GTK_OBJECT(dialog), "frame1", frame1);
gtk_widget_show(frame1);
gtk_container_border_width(GTK_CONTAINER(frame1), 3);
swin = gtk_scrolled_window_new(NULL, NULL);
clist = gtk_clist_new(2);
gtk_object_set_data(GTK_OBJECT(dialog), "clist", clist);
gtk_widget_set_usize(clist, 500, 400);
gtk_container_add(GTK_CONTAINER(swin), clist);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_signal_connect(GTK_OBJECT(clist), "select_row",
GTK_SIGNAL_FUNC(ghack_menu_row_selected), NULL);
gtk_container_add(GTK_CONTAINER(frame1), swin);
gtk_box_pack_start_defaults(GTK_BOX(GNOME_DIALOG(dialog)->vbox), frame1);
/* Add the extended commands into the list here... */
for (n = 0; extcmdlist[n].ef_txt; ++n) {
const char *text[3]={extcmdlist[n].ef_txt,extcmdlist[n].ef_desc,NULL};
gtk_clist_insert(GTK_CLIST(clist), n, (char**) text);
}
/* fill in starting info fields */
info.curItem = -1;
info.numRows = n;
info.charIdx = 0;
info.lastTime = 0;
gtk_clist_columns_autosize(GTK_CLIST(clist));
gtk_widget_show_all(swin);
/* Center the dialog over over parent */
gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
gnome_dialog_set_parent(GNOME_DIALOG(dialog),
GTK_WINDOW(ghack_get_main_window()));
/* Run the dialog -- returning whichever button was pressed */
n = gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
/* Quit on button 2 or error */
return (n != 0) ? -1 : info.curItem;
}