1: /************************************************************
*      Program: RMENU Menu Interpreter
*       Module: rmenu3.c
*         Execute a Menu Item
*      Written by: Leor Zolman, 7/91
************************************************************/

#include "cmenu.h"
#include "rcmenu.h"

#if __STDC__
#pragma hdrstop
#endif

/************************************************************
 * do_item():
 * Perform the action associated with a particular item.
 * Default path is supplied as "path":
 ************************************************************/

int do_item(M2p, curr, path)
MENU2 *M2p;
int curr;
char *path;
{
   ITEM *Ip = M2p -> Items[curr];
   char newpath[MAX_PATH];
   int i, j;

   strcpy(newpath, make_path(path, Ip -> path));

   switch (Ip -> acttyp)
   {
      case ACT_CMND:
         do_cmnd(Ip, newpath);
         break;

      case ACT_LMENU:
         if (sub_menu(Ip->lmenunum, newpath) == EXITALL)
            return EXITALL;
         break;
            
      case ACT_EMENU:
         if (do_emenu(Ip, newpath) == EXITALL)
            return EXITALL;
         break;
   }
   return OK;
}


/************************************************************
 * show_item():
 * Display the action associated with a particular item.
 * Default path is supplied as "path":
 ************************************************************/

Void show_item(M2p, curr, path)
MENU2 *M2p;
int curr;
char *path;
{
   ITEM *Ip = M2p -> Items[curr];
   char newpath[MAX_PATH];
   int i, j;

   strcpy(newpath, make_path(path, Ip -> path));

   switch (Ip -> acttyp)
   {
      case ACT_CMND:
         show_cmnd(Ip, newpath);
         break;

      case ACT_LMENU:
         put_msg(0, "This is a local menu. Press any key: ");
         break;
                  
      case ACT_EMENU:
         put_msg(0,
          " Path: %s; Emenu spec: %s. Press any key to continue: ",
                           newpath, Ip -> action);
         break;
   }
/*  return OK; */
}


/************************************************************
 * do_cmnd():
 * Run a directly executable item.
 ************************************************************/

Void do_cmnd(Ip, path)
ITEM *Ip;
char *path;
{
   char *cmd_line;
   int retval;

   cmd_line = make_cmd(path, Ip -> action);

   if (Ip -> pre_clear == YES ||
      (Ip -> pre_clear == DEFAULT && DEF_PRECLEAR == YES))
         clear();

   move(0, 0);
   refresh();

   if (debug)
      put_msg(0, "About to exec: %s", cmd_line);

   pre_shell();                      /* set up for shell call    */
   retval = system0(cmd_line);       /* make the shell call      */

   switch (Ip -> prompt)             /* decide whether to prompt */
   {                                 /* or not after the command */
      case NO:                       /* explicit no is clear     */
         break;

      case DEFAULT:                  /* if unspecified, then...  */

#if (DEF_PROMPT == NO)               /* if default is NO,        */
            break;                   /* then don't prompt        */
#endif

#if (DEF_PROMPT == ON_ERROR)         /* if prompting on errors,  */
         if (!retval)                /* but there wasn't any     */
            break;                   /* error, then don't prompt */
#endif
                                     /* else fall through to YES */
      case YES:
         puts("\nPress RETURN to continue . . .");
         (Void) getchar();
   }
                                     /* Upon return from shell,  */
   post_shell();                     /* restore everything       */
}


/************************************************************
 * show_cmnd():
 * Show a directly executable action string.
 ************************************************************/

Void show_cmnd(Ip, path)
ITEM *Ip;
char *path;
{
   char *cmd_line;
   int retval;

   cmd_line = make_cmd(path, Ip -> action);

   put_msg(0, " Action: %s. Press a key to continue: ", cmd_line);
}


/**************************************************************
 * do_emenu():
 * Run an external menu specification.
 **************************************************************/

int do_emenu(Ip, path)
ITEM *Ip;
char *path;
{
   char filename[MAX_PATH];
   int retval;
   
   if (nestlev == MAX_NEST - 1)
      return fatal("Menus nested too deeply (increase MAX_NEST)");

   strcpy(filename, make_path(path, Ip -> action));

   nestlev++;
   retval = do_menu("", filename);
   nestlev--;

   return retval;
}


/************************************************************
 * pre_shell()
 * Set tty mode for a shell call
 * DOS only: save drive and path for later restoration
 ************************************************************/


Void pre_shell()
{
   push_path();
   tty_shell();
}


/************************************************************
 * post_shell()
 * Set tty mode for curses
 * DOS only: restore drive and path from before shell call
 ************************************************************/
 
Void post_shell()
{
   pop_path();
   tty_curses();
}
