home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / misc / toolmana.lha / ToolManager / Source / prefs / execwindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-26  |  30.8 KB  |  976 lines

  1. /*
  2.  * execwindow.c  V2.0
  3.  *
  4.  * exec edit window handling
  5.  *
  6.  * (c) 1990-1992 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. /* Exec node */
  12. struct ExecNode {
  13.                  struct Node  en_Node;
  14.                  ULONG        en_Flags;
  15.                  UWORD        en_ExecType;
  16.                  WORD         en_Priority;
  17.                  LONG         en_Delay;
  18.                  ULONG        en_Stack;
  19.                  char        *en_Command;
  20.                  char        *en_CurrentDir;
  21.                  char        *en_HotKey;
  22.                  char        *en_Output;
  23.                  char        *en_Path;
  24.                  char        *en_PubScreen;
  25.                 };
  26.  
  27. /* Window data */
  28. static struct Gadget *gl;             /* Gadget list */
  29. static struct Window *w;              /* Window */
  30. static void *aw;                      /* AppWindow pointer */
  31. static UWORD ww,wh;                   /* Window size */
  32. static struct ExecNode *CurrentNode;
  33. static struct Gadget *CurrentGadget;
  34. static BOOL ReqOpen;
  35. #define WINDOW_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|\
  36.                       CHECKBOXIDCMP|CYCLEIDCMP|INTEGERIDCMP|STRINGIDCMP)
  37.  
  38. /* Gadget data */
  39. #define GAD_NAME_STR      0 /* Gadgets with labels (left side) */
  40. #define GAD_EXECTYPE      1
  41. #define GAD_COMMAND_BUT   2
  42. #define GAD_COMMAND_STR   3
  43. #define GAD_HOTKEY_STR    4
  44. #define GAD_STACK_INT     5
  45. #define GAD_PRIORITY_INT  6
  46. #define GAD_DELAY_INT     7
  47.  
  48. #define GAD_CURDIR_BUT    8 /* Gadgets with labels (right side) */
  49. #define GAD_PATH_BUT      9
  50. #define GAD_OUTPUT_BUT   10
  51. #define GAD_PSCREEN_BUT  11
  52.  
  53. #define GAD_ARGS         12 /* Checkbox gadgets (right side) */
  54. #define GAD_TOFRONT      13
  55.  
  56. #define GAD_CURDIR_STR   14
  57. #define GAD_PATH_STR     15
  58. #define GAD_OUTPUT_STR   16
  59. #define GAD_PSCREEN_STR  17
  60.  
  61. #define GAD_OK           18 /* Button gadgets */
  62. #define GAD_CANCEL       19
  63. #define GADGETS          20
  64. static struct GadgetData gdata[GADGETS];
  65.  
  66. /* Gadget tags */
  67. static struct TagItem nametags[]={GTST_String,   NULL,
  68.                                   GTST_MaxChars, 100,
  69.                                   TAG_DONE};
  70.  
  71. static char *cyclelabels[TMETYPES]={"CLI", "WB", "ARexx", NULL};
  72. static struct TagItem cycletags[]={GTCY_Labels, cyclelabels,
  73.                                    GTCY_Active, 0,
  74.                                    TAG_DONE};
  75.  
  76. static struct TagItem commtags[]={GTST_String,   NULL,
  77.                                   GTST_MaxChars, 100,
  78.                                   TAG_DONE};
  79.  
  80. static struct TagItem curdtags[]={GTST_String,   NULL,
  81.                                   GTST_MaxChars, 100,
  82.                                   TAG_DONE};
  83.  
  84. static struct TagItem hotktags[]={GTST_String,   NULL,
  85.                                   GTST_MaxChars, 100,
  86.                                   TAG_DONE};
  87.  
  88. static struct TagItem outptags[]={GTST_String,   NULL,
  89.                                   GTST_MaxChars, 100,
  90.                                   TAG_DONE};
  91.  
  92. static struct TagItem pathtags[]={GTST_String,   NULL,
  93.                                   GTST_MaxChars, 100,
  94.                                   TAG_DONE};
  95.  
  96. static struct TagItem pbsctags[]={GTST_String,   NULL,
  97.                                   GTST_MaxChars, 100,
  98.                                   TAG_DONE};
  99.  
  100. static struct TagItem stacktags[]={GTIN_Number,   0,
  101.                                    GTIN_MaxChars, 10,
  102.                                    TAG_DONE};
  103.  
  104. static struct TagItem priotags[]={GTIN_Number,   0,
  105.                                   GTIN_MaxChars, 10,
  106.                                   TAG_DONE};
  107.  
  108. static struct TagItem delaytags[]={GTIN_Number,   0,
  109.                                    GTIN_MaxChars, 10,
  110.                                    TAG_DONE};
  111.  
  112. static struct TagItem argstags[]={GTCB_Checked, FALSE,
  113.                                   TAG_DONE};
  114.  
  115. static struct TagItem tofronttags[]={GTCB_Checked, FALSE,
  116.                                      TAG_DONE};
  117.  
  118. /* Init exec edit window */
  119. void InitExecEditWindow(UWORD left, UWORD fheight)
  120. {
  121.  ULONG llabwidth,lgadwidth,rlabwidth,rgadwidth;
  122.  ULONG cbwidth,butwidth,minstringwidth;
  123.  ULONG strheight=fheight+2;
  124.  ULONG i,tmp,yadd;
  125.  struct GadgetData *gd;
  126.  
  127.  /* Init strings */
  128.  gdata[GAD_NAME_STR].name     =AppStrings[MSG_WINDOW_NAME_GAD];
  129.  gdata[GAD_EXECTYPE].name     =AppStrings[MSG_EXECWIN_EXECTYPE_GAD];
  130.  gdata[GAD_COMMAND_BUT].name  =AppStrings[MSG_WINDOW_COMMAND_GAD];
  131.  gdata[GAD_COMMAND_STR].name  ="";
  132.  gdata[GAD_HOTKEY_STR].name   =AppStrings[MSG_WINDOW_HOTKEY_GAD];
  133.  gdata[GAD_STACK_INT].name    =AppStrings[MSG_EXECWIN_STACK_GAD];
  134.  gdata[GAD_PRIORITY_INT].name =AppStrings[MSG_EXECWIN_PRIORITY_GAD];
  135.  gdata[GAD_DELAY_INT].name    =AppStrings[MSG_EXECWIN_DELAY_GAD];
  136.  gdata[GAD_CURDIR_BUT].name   =AppStrings[MSG_EXECWIN_CURRENTDIR_GAD];
  137.  gdata[GAD_PATH_BUT].name     =AppStrings[MSG_EXECWIN_PATH_GAD];
  138.  gdata[GAD_OUTPUT_BUT].name   =AppStrings[MSG_EXECWIN_OUTPUT_GAD];
  139.  gdata[GAD_PSCREEN_BUT].name  =AppStrings[MSG_WINDOW_PUBSCREEN_GAD];
  140.  gdata[GAD_ARGS].name         =AppStrings[MSG_EXECWIN_ARGUMENTS_GAD];
  141.  gdata[GAD_TOFRONT].name      =AppStrings[MSG_EXECWIN_TOFRONT_GAD];
  142.  gdata[GAD_OK].name           =AppStrings[MSG_WINDOW_OK_GAD];
  143.  gdata[GAD_CANCEL].name       =AppStrings[MSG_WINDOW_CANCEL_GAD];
  144.  
  145.  /* Calculate maximum label width (left side) */
  146.  llabwidth=0;
  147.  gd=&gdata[GAD_NAME_STR];
  148.  for (i=GAD_NAME_STR; i<=GAD_DELAY_INT; i++, gd++)
  149.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > llabwidth)
  150.    llabwidth=tmp;
  151.  llabwidth+=INTERWIDTH;
  152.  
  153.  /* Calculate maximum gadget width (left side) */
  154.  minstringwidth=TextLength(&TmpRastPort,AppStrings[MSG_EXECWIN_NEWNAME],
  155.                            strlen(AppStrings[MSG_EXECWIN_NEWNAME]))
  156.                 +2*INTERWIDTH;
  157.  lgadwidth=minstringwidth+REQBUTTONWIDTH;
  158.  
  159.  /* Calculate maximum label width (right side) */
  160.  rlabwidth=0;
  161.  gd=&gdata[GAD_CURDIR_BUT];
  162.  for (i=GAD_CURDIR_BUT; i<=GAD_PSCREEN_BUT; i++, gd++)
  163.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > rlabwidth)
  164.    rlabwidth=tmp;
  165.  rlabwidth+=INTERWIDTH;
  166.  
  167.  /* Calculate maximum gadget width (right side) */
  168.  rgadwidth=minstringwidth+REQBUTTONWIDTH;
  169.  
  170.  /* Calculate maximum checkbox gadget width */
  171.  cbwidth=0;
  172.  gd=&gdata[GAD_ARGS];
  173.  for (i=GAD_ARGS; i<=GAD_TOFRONT; i++, gd++)
  174.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > cbwidth)
  175.    cbwidth=tmp;
  176.  cbwidth+=CHKBOXWIDTH+INTERWIDTH;
  177.  if ((rlabwidth+rgadwidth+INTERWIDTH) < cbwidth)
  178.   rgadwidth=cbwidth-rlabwidth-INTERWIDTH;
  179.  
  180.  /* Calculate minimum window width */
  181.  ww=llabwidth+lgadwidth+rlabwidth+rgadwidth+4*INTERWIDTH;
  182.  
  183.  /* Calculate button gadgets width */
  184.  gd=&gdata[GAD_OK];
  185.  butwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  186.  gd++;
  187.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > butwidth)
  188.   butwidth=tmp;
  189.  butwidth+=2*INTERWIDTH;
  190.  if ((tmp=2*(butwidth+INTERWIDTH)) > ww) ww=tmp;
  191.  
  192.  /* window height */
  193.  wh=8*fheight+9*INTERHEIGHT+14;
  194.  
  195.  /* Init gadgets */
  196.  gd=gdata;
  197.  yadd=strheight+INTERHEIGHT;
  198.  tmp=(ww-llabwidth-lgadwidth-rlabwidth-rgadwidth-4*INTERWIDTH)/2;
  199.  lgadwidth+=tmp; /* String gadget width (left) */
  200.  rgadwidth+=tmp; /* String gadget width (right) */
  201.  llabwidth+=left;
  202.  tmp=WindowTop+INTERHEIGHT;
  203.  
  204.  /* (left side) Name string gadget */
  205.  gd->type=STRING_KIND;
  206.  gd->flags=PLACETEXT_LEFT;
  207.  gd->tags=nametags;
  208.  gd->left=llabwidth;
  209.  gd->top=tmp;
  210.  gd->width=lgadwidth;
  211.  gd->height=strheight;
  212.  tmp+=yadd;
  213.  
  214.  /* cycle gadget */
  215.  gd++;
  216.  gd->type=CYCLE_KIND;
  217.  gd->flags=PLACETEXT_LEFT;
  218.  gd->tags=cycletags;
  219.  gd->left=llabwidth;
  220.  gd->top=tmp;
  221.  gd->width=lgadwidth;
  222.  gd->height=strheight;
  223.  tmp+=yadd;
  224.  
  225.  /* Command button gadget */
  226.  gd++;
  227.  gd->type=GENERIC_KIND;
  228.  gd->flags=0;
  229.  gd->left=llabwidth;
  230.  gd->top=tmp;
  231.  gd->width=REQBUTTONWIDTH;
  232.  gd->height=strheight;
  233.  
  234.  /* Command string gadget */
  235.  gd++;
  236.  gd->name=NULL;
  237.  gd->type=STRING_KIND;
  238.  gd->tags=commtags;
  239.  gd->left=llabwidth+REQBUTTONWIDTH;
  240.  gd->top=tmp;
  241.  gd->width=lgadwidth-REQBUTTONWIDTH;
  242.  gd->height=strheight;
  243.  tmp+=yadd;
  244.  
  245.  /* HotKey string gadget */
  246.  gd++;
  247.  gd->type=STRING_KIND;
  248.  gd->flags=PLACETEXT_LEFT;
  249.  gd->tags=hotktags;
  250.  gd->left=llabwidth;
  251.  gd->top=tmp;
  252.  gd->width=lgadwidth;
  253.  gd->height=strheight;
  254.  tmp+=yadd;
  255.  
  256.  /* Stack integer gadget */
  257.  gd++;
  258.  gd->type=INTEGER_KIND;
  259.  gd->flags=PLACETEXT_LEFT;
  260.  gd->tags=stacktags;
  261.  gd->left=llabwidth;
  262.  gd->top=tmp;
  263.  gd->width=lgadwidth;
  264.  gd->height=strheight;
  265.  tmp+=yadd;
  266.  
  267.  /* Priority integer gadget */
  268.  gd++;
  269.  gd->type=INTEGER_KIND;
  270.  gd->flags=PLACETEXT_LEFT;
  271.  gd->tags=priotags;
  272.  gd->left=llabwidth;
  273.  gd->top=tmp;
  274.  gd->width=lgadwidth;
  275.  gd->height=strheight;
  276.  tmp+=yadd;
  277.  
  278.  /* Delay integer gadget */
  279.  gd++;
  280.  gd->type=INTEGER_KIND;
  281.  gd->flags=PLACETEXT_LEFT;
  282.  gd->tags=delaytags;
  283.  gd->left=llabwidth;
  284.  gd->top=tmp;
  285.  gd->width=lgadwidth;
  286.  gd->height=strheight;
  287.  
  288.  /* (right side) Button gadgets */
  289.  llabwidth=ww-INTERWIDTH-REQBUTTONWIDTH-rgadwidth+left;
  290.  tmp=WindowTop+INTERHEIGHT;
  291.  gd++;
  292.  for (i=GAD_CURDIR_BUT; i<=GAD_PSCREEN_BUT; i++, gd++) {
  293.   gd->type=GENERIC_KIND;
  294.   gd->flags=0;
  295.   gd->left=llabwidth;
  296.   gd->top=tmp;
  297.   gd->width=REQBUTTONWIDTH;
  298.   gd->height=strheight;
  299.   tmp+=yadd;
  300.  }
  301.  
  302.  /* Arguments checkbox gadget */
  303.  lgadwidth=rgadwidth+rlabwidth+INTERWIDTH-cbwidth;
  304.  rlabwidth=llabwidth-rlabwidth+lgadwidth/2;
  305.  gd->type=CHECKBOX_KIND;
  306.  gd->flags=PLACETEXT_RIGHT;
  307.  gd->tags=argstags;
  308.  gd->left=rlabwidth;
  309.  gd->top=++tmp;
  310.  gd->width=CHKBOXWIDTH;
  311.  gd->height=strheight;
  312.  tmp+=yadd;
  313.  
  314.  /* ToFront checkbox gadget */
  315.  gd++;
  316.  gd->type=CHECKBOX_KIND;
  317.  gd->flags=PLACETEXT_RIGHT;
  318.  gd->tags=tofronttags;
  319.  gd->left=rlabwidth;
  320.  gd->top=tmp;
  321.  gd->width=CHKBOXWIDTH;
  322.  gd->height=strheight;
  323.  
  324.  /* Current Directory string gadget */
  325.  tmp=WindowTop+INTERHEIGHT;
  326.  llabwidth+=REQBUTTONWIDTH;
  327.  gd++;
  328.  gd->type=STRING_KIND;
  329.  gd->flags=PLACETEXT_LEFT;
  330.  gd->tags=curdtags;
  331.  gd->left=llabwidth;
  332.  gd->top=tmp;
  333.  gd->width=rgadwidth;
  334.  gd->height=strheight;
  335.  tmp+=yadd;
  336.  
  337.  /* Path string gadget */
  338.  gd++;
  339.  gd->type=STRING_KIND;
  340.  gd->flags=PLACETEXT_LEFT;
  341.  gd->tags=pathtags;
  342.  gd->left=llabwidth;
  343.  gd->top=tmp;
  344.  gd->width=rgadwidth;
  345.  gd->height=strheight;
  346.  tmp+=yadd;
  347.  
  348.  /* Output string gadget */
  349.  gd++;
  350.  gd->type=STRING_KIND;
  351.  gd->flags=PLACETEXT_LEFT;
  352.  gd->tags=outptags;
  353.  gd->left=llabwidth;
  354.  gd->top=tmp;
  355.  gd->width=rgadwidth;
  356.  gd->height=strheight;
  357.  tmp+=yadd;
  358.  
  359.  /* Public Screen string gadget */
  360.  gd++;
  361.  gd->type=STRING_KIND;
  362.  gd->flags=PLACETEXT_LEFT;
  363.  gd->tags=pbsctags;
  364.  gd->left=llabwidth;
  365.  gd->top=tmp;
  366.  gd->width=rgadwidth;
  367.  gd->height=strheight;
  368.  
  369.  /* OK button gadget */
  370.  tmp=WindowTop+7*strheight+8*INTERHEIGHT;
  371.  gd++;
  372.  gd->type=BUTTON_KIND;
  373.  gd->flags=PLACETEXT_IN;
  374.  gd->left=left;
  375.  gd->top=tmp;
  376.  gd->width=butwidth;
  377.  gd->height=fheight;
  378.  
  379.  /* Cancel button gadget */
  380.  gd++;
  381.  gd->type=BUTTON_KIND;
  382.  gd->flags=PLACETEXT_IN;
  383.  gd->left=ww-butwidth-INTERWIDTH+left;
  384.  gd->top=tmp;
  385.  gd->width=butwidth;
  386.  gd->height=fheight;
  387. }
  388.  
  389. /* Free exec node */
  390. void FreeExecNode(struct Node *node)
  391. {
  392.  struct ExecNode *en=node;
  393.  char *s;
  394.  
  395.  if (s=en->en_Node.ln_Name) free(s);
  396.  if (s=en->en_Command) free(s);
  397.  if (s=en->en_CurrentDir) free(s);
  398.  if (s=en->en_Output) free(s);
  399.  if (s=en->en_Path) free(s);
  400.  if (s=en->en_HotKey) free(s);
  401.  if (s=en->en_PubScreen) free(s);
  402.  
  403.  /* Free node */
  404.  FreeMem(en,sizeof(struct ExecNode));
  405. }
  406.  
  407. /* Copy exec node */
  408. struct Node *CopyExecNode(struct Node *node)
  409. {
  410.  struct ExecNode *en,*orignode=node;
  411.  
  412.  /* Alloc memory for exec node */
  413.  if (en=AllocMem(sizeof(struct ExecNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  414.  
  415.   /* Got an old node? */
  416.   if (orignode) {
  417.    /* Yes, copy it */
  418.    if ((!orignode->en_Node.ln_Name || (en->en_Node.ln_Name=
  419.                                         strdup(orignode->en_Node.ln_Name))) &&
  420.        (!orignode->en_Command || (en->en_Command=
  421.                                    strdup(orignode->en_Command))) &&
  422.        (!orignode->en_CurrentDir || (en->en_CurrentDir=
  423.                                       strdup(orignode->en_CurrentDir))) &&
  424.        (!orignode->en_Output || (en->en_Output=strdup(orignode->en_Output))) &&
  425.        (!orignode->en_Path || (en->en_Path=strdup(orignode->en_Path))) &&
  426.        (!orignode->en_HotKey || (en->en_HotKey=strdup(orignode->en_HotKey))) &&
  427.        (!orignode->en_PubScreen || (en->en_PubScreen=
  428.                                      strdup(orignode->en_PubScreen)))) {
  429.     /* Copy flags & numbers */
  430.     en->en_ExecType=orignode->en_ExecType;
  431.     en->en_Flags=orignode->en_Flags;
  432.     en->en_Stack=orignode->en_Stack;
  433.     en->en_Priority=orignode->en_Priority;
  434.     en->en_Delay=orignode->en_Delay;
  435.  
  436.     /* Return pointer to new node */
  437.     return(en);
  438.    }
  439.   } else {
  440.    /* No, set defaults */
  441.    if (en->en_Node.ln_Name=strdup(AppStrings[MSG_EXECWIN_NEWNAME])) {
  442.     en->en_Flags=EXPOF_ARGS;
  443.     en->en_Stack=4096;
  444.  
  445.     /* Return pointer to new node */
  446.     return(en);
  447.    }
  448.   }
  449.  
  450.   FreeExecNode((struct Node *) en);
  451.  }
  452.  /* Call failed */
  453.  return(NULL);
  454. }
  455.  
  456. /* Activate gadget and save pointer to it */
  457. static ActivateAndSetGadget(ULONG num)
  458. {
  459.  CurrentGadget=gdata[num].gadget;
  460.  ActivateGadget(CurrentGadget,w,NULL);
  461. }
  462.  
  463. /* Open exec edit window */
  464. BOOL OpenExecEditWindow(struct Node *node, struct Window *parent)
  465. {
  466.  /* Copy node */
  467.  if (CurrentNode=CopyExecNode(node)) {
  468.   /* Set tags */
  469.   nametags[0].ti_Data=CurrentNode->en_Node.ln_Name;
  470.   cycletags[1].ti_Data=CurrentNode->en_ExecType;
  471.   commtags[0].ti_Data=CurrentNode->en_Command;
  472.   curdtags[0].ti_Data=CurrentNode->en_CurrentDir;
  473.   hotktags[0].ti_Data=CurrentNode->en_HotKey;
  474.   outptags[0].ti_Data=CurrentNode->en_Output;
  475.   pathtags[0].ti_Data=CurrentNode->en_Path;
  476.   pbsctags[0].ti_Data=CurrentNode->en_PubScreen;
  477.   stacktags[0].ti_Data=CurrentNode->en_Stack;
  478.   priotags[0].ti_Data=CurrentNode->en_Priority;
  479.   delaytags[0].ti_Data=CurrentNode->en_Delay;
  480.   argstags[0].ti_Data=(CurrentNode->en_Flags & EXPOF_ARGS)!=0;
  481.   tofronttags[0].ti_Data=(CurrentNode->en_Flags & EXPOF_TOFRONT)!=0;
  482.  
  483.   /* Create gadgets */
  484.   if (gl=CreateGadgetList(gdata,GADGETS)) {
  485.    /* Open window */
  486.    if (w=OpenWindowTags(NULL,WA_Left,parent->LeftEdge,
  487.                              WA_Top,parent->TopEdge+WindowTop,
  488.                              WA_InnerWidth,ww,
  489.                              WA_InnerHeight,wh,
  490.                              WA_AutoAdjust,TRUE,
  491.                              WA_Title,AppStrings[MSG_EXECWIN_TITLE],
  492.                              WA_PubScreen,PublicScreen,
  493.                              WA_Flags,WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  494.                                       WFLG_DEPTHGADGET|WFLG_RMBTRAP|
  495.                                       WFLG_ACTIVATE,
  496.                              TAG_DONE)) {
  497.     /* Add as AppWindow */
  498.     aw=NULL;
  499.     if ((!WorkbenchBase) || (!WBScreen) ||
  500.         (aw=AddAppWindowA(0,0,w,AppMsgPort,NULL))) {
  501.      /* Init requester button gadgets */
  502.      InitReqButtonGadget(gdata[GAD_COMMAND_BUT].gadget);
  503.      InitReqButtonGadget(gdata[GAD_CURDIR_BUT].gadget);
  504.      InitReqButtonGadget(gdata[GAD_PATH_BUT].gadget);
  505.      InitReqButtonGadget(gdata[GAD_OUTPUT_BUT].gadget);
  506.      InitReqButtonGadget(gdata[GAD_PSCREEN_BUT].gadget);
  507.  
  508.      /* Add gadgets to window */
  509.      AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  510.      RefreshGList(gl,w,NULL,(UWORD) -1);
  511.      GT_RefreshWindow(w,NULL);
  512.  
  513.      /* Activate first gadget */
  514.      ActivateAndSetGadget(GAD_NAME_STR);
  515.  
  516.      /* Set local variables */
  517.      w->UserPort=IDCMPPort;
  518.      w->UserData=HandleExecEditWindowIDCMP;
  519.      ModifyIDCMP(w,WINDOW_IDCMP);
  520.      CurrentWindow=w;
  521.      HandleAppMsg=HandleExecEditWindowAppMsg;
  522.      ReqOpen=FALSE;
  523.  
  524.      /* Set up file requester parameters */
  525.      FileReqParms.frp_Window=w;
  526.      FileReqParms.frp_OKText=AppStrings[MSG_WINDOW_OK_GAD];
  527.      FileReqParms.frp_Flags1=FRF_DOPATTERNS;
  528.  
  529.      /* All OK. */
  530.      return(TRUE);
  531.     }
  532.     CloseWindow(w);
  533.    }
  534.    FreeGadgets(gl);
  535.   }
  536.   FreeExecNode((struct Node *) CurrentNode);
  537.  }
  538.  /* Call failed */
  539.  return(FALSE);
  540. }
  541.  
  542. /* Close exec edit window */
  543. static void CloseExecEditWindow(void)
  544. {
  545.  /* Free resources */
  546.  RemoveGList(w,gl,(UWORD) -1);
  547.  HandleAppMsg=NULL;
  548.  if (aw) RemoveAppWindow(aw);
  549.  CloseWindowSafely(w);
  550.  FreeGadgets(gl);
  551. }
  552.  
  553. /* Handle application messages */
  554. void HandleExecEditWindowAppMsg(struct AppMessage *msg)
  555. {
  556.  struct WBArg *wa;
  557.  
  558.  DEBUG_PRINTF("AppMsg 0x%08lx\n",msg);
  559.  
  560.  /* Get first argument */
  561.  if (wa=msg->am_ArgList) {
  562.   BPTR olddir;
  563.   struct DiskObject *dobj;
  564.  
  565.   DEBUG_PRINTF("Argument 0x%08lx\n",wa);
  566.  
  567.   /* Go to new current dir */
  568.   olddir=CurrentDir(wa->wa_Lock);
  569.  
  570.   /* Get icon */
  571.   if (dobj=GetDiskObjectNew(wa->wa_Name)) {
  572.    char *command;
  573.  
  574.    /* Get program name */
  575.    switch (dobj->do_Type) {
  576.     case WBTOOL:    command=wa->wa_Name;
  577.                     break;
  578.     case WBPROJECT: /* Default tool valid? */
  579.                     if (!(command=dobj->do_DefaultTool)) command=wa->wa_Name;
  580.                     break;
  581.     default:        command=NULL;
  582.    }
  583.  
  584.    /* Command string valid? */
  585.    if (command) {
  586.     char *dirbuf;
  587.  
  588.     /* Allocate memory for directory buffer */
  589.     if (dirbuf=malloc(4096)) {
  590.      /* Get current dir name */
  591.      if (NameFromLock(wa->wa_Lock,dirbuf,4096)) {
  592.       /* Set new gadget values */
  593.       CurrentNode->en_ExecType=TMET_WB;
  594.       GT_SetGadgetAttrs(gdata[GAD_EXECTYPE].gadget,w,NULL,
  595.                         GTCY_Active,TMET_WB,TAG_DONE);
  596.       GT_SetGadgetAttrs(gdata[GAD_NAME_STR].gadget,w,NULL,
  597.                         GTST_String,wa->wa_Name,TAG_DONE);
  598.       GT_SetGadgetAttrs(gdata[GAD_COMMAND_STR].gadget,w,NULL,
  599.                         GTST_String,command,TAG_DONE);
  600.       GT_SetGadgetAttrs(gdata[GAD_CURDIR_STR].gadget,w,NULL,
  601.                         GTST_String,dirbuf,TAG_DONE);
  602.  
  603.       /* Tool? */
  604.       if (dobj->do_Type==WBTOOL)
  605.        /* Yes, set stack */
  606.        GT_SetGadgetAttrs(gdata[GAD_STACK_INT].gadget,w,NULL,
  607.                          GTIN_Number,dobj->do_StackSize,TAG_DONE);
  608.      }
  609.      free(dirbuf);
  610.     }
  611.    }
  612.  
  613.    /* Free icon */
  614.    FreeDiskObject(dobj);
  615.   }
  616.   CurrentDir(olddir);
  617.  }
  618. }
  619.  
  620. /* Handle exec edit window IDCMP events */
  621. void *HandleExecEditWindowIDCMP(struct IntuiMessage *msg)
  622. {
  623.  struct Node *NewNode=NULL;
  624.  
  625.  /* Which IDCMP class? */
  626.  switch (msg->Class) {
  627.   case IDCMP_CLOSEWINDOW:   NewNode=(struct Node *) -1;
  628.                             FreeExecNode((struct Node *) CurrentNode);
  629.                             break;
  630.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  631.                             GT_EndRefresh(w,TRUE);
  632.                             break;
  633.   case IDCMP_GADGETUP:
  634.    switch (((struct Gadget *) msg->IAddress)->GadgetID) {
  635.     case GAD_NAME_STR:     ActivateAndSetGadget(GAD_COMMAND_STR);
  636.                            break;
  637.     case GAD_EXECTYPE:     /* Save type */
  638.                            CurrentNode->en_ExecType=msg->Code;
  639.  
  640.                            /* Activate old string gadget */
  641.                            ActivateGadget(CurrentGadget,w,NULL);
  642.                            break;
  643.     case GAD_COMMAND_BUT:  {
  644.                             char *file;
  645.                             struct Gadget *g=gdata[GAD_COMMAND_STR].gadget;
  646.  
  647.                             /* Set file requester parameters */
  648.                             FileReqParms.frp_Title=
  649.                              AppStrings[MSG_FILEREQ_TITLE_FILE];
  650.                             FileReqParms.frp_Flags2=FRF_REJECTICONS;
  651.                             FileReqParms.frp_OldFile=
  652.                              ((struct StringInfo *) g->SpecialInfo)->Buffer;
  653.  
  654.                             /* Open file requester */
  655.                             if (file=OpenFileRequester()) {
  656.                               /* Set new file string */
  657.                              GT_SetGadgetAttrs(g,w,NULL,GTST_String,file,
  658.                                                         TAG_DONE);
  659.                              free(file);
  660.                             }
  661.  
  662.                             /* Activate old string gadget */
  663.                             ActivateGadget(CurrentGadget,w,NULL);
  664.                            }
  665.                            break;
  666.     case GAD_COMMAND_STR:  ActivateAndSetGadget(GAD_HOTKEY_STR);
  667.                            break;
  668.     case GAD_HOTKEY_STR:   ActivateAndSetGadget(GAD_STACK_INT);
  669.                            break;
  670.     case GAD_STACK_INT:    ActivateAndSetGadget(GAD_PRIORITY_INT);
  671.                            break;
  672.     case GAD_PRIORITY_INT: ActivateAndSetGadget(GAD_DELAY_INT);
  673.                            break;
  674.     case GAD_DELAY_INT:    ActivateAndSetGadget(GAD_CURDIR_STR);
  675.                            break;
  676.     case GAD_CURDIR_BUT:   {
  677.                             char *file;
  678.                             struct Gadget *g=gdata[GAD_CURDIR_STR].gadget;
  679.  
  680.                             /* Set file requester parameters */
  681.                             FileReqParms.frp_Title=
  682.                              AppStrings[MSG_FILEREQ_TITLE_DRAWER];
  683.                             FileReqParms.frp_Flags2=FRF_DRAWERSONLY|
  684.                                                     FRF_REJECTICONS;
  685.                             FileReqParms.frp_OldFile=
  686.                              ((struct StringInfo *) g->SpecialInfo)->Buffer;
  687.  
  688.                             /* Open file requester */
  689.                             if (file=OpenFileRequester()) {
  690.                               /* Set new file string */
  691.                              GT_SetGadgetAttrs(g,w,NULL,GTST_String,file,
  692.                                                         TAG_DONE);
  693.                              free(file);
  694.                             }
  695.  
  696.                             /* Activate old string gadget */
  697.                             ActivateGadget(CurrentGadget,w,NULL);
  698.                            }
  699.                            break;
  700.     case GAD_PATH_BUT:     {
  701.                             char *file;
  702.                             struct Gadget *g=gdata[GAD_PATH_STR].gadget;
  703.  
  704.                             /* Set file requester parameters */
  705.                             FileReqParms.frp_Title=
  706.                              AppStrings[MSG_FILEREQ_TITLE_DRAWER];
  707.                             FileReqParms.frp_Flags2=FRF_DRAWERSONLY|
  708.                                                     FRF_REJECTICONS;
  709.                             FileReqParms.frp_OldFile="";
  710.  
  711.                             /* Open file requester */
  712.                             if (file=OpenFileRequester()) {
  713.                              char *oldpath,*path;
  714.                              ULONG len;
  715.  
  716.                              oldpath=((struct StringInfo *) g->SpecialInfo)
  717.                                       ->Buffer;
  718.                              len=strlen(oldpath);
  719.  
  720.                              /* Alloc memory for new path string */
  721.                              if (path=malloc(len+strlen(file)+2)) {
  722.                               /* Build new path string. Got old path? */
  723.                               if (len) {
  724.                                /* Yes. Append new path */
  725.                                strcpy(path,oldpath);
  726.                                path[len]=';';
  727.                                strcpy(path+len+1,file);
  728.                               } else
  729.                                /* No. Copy new path */
  730.                                strcpy(path,file);
  731.  
  732.                               /* Set new path string */
  733.                               GT_SetGadgetAttrs(g,w,NULL,GTST_String,path,
  734.                                                          TAG_DONE);
  735.                               free(path);
  736.  
  737.                              }
  738.                              free(file);
  739.                             }
  740.  
  741.                             /* Activate old string gadget */
  742.                             ActivateGadget(CurrentGadget,w,NULL);
  743.                            }
  744.                            break;
  745.     case GAD_OUTPUT_BUT:   {
  746.                             char *file;
  747.                             struct Gadget *g=gdata[GAD_OUTPUT_STR].gadget;
  748.  
  749.                             /* Set file requester parameters */
  750.                             FileReqParms.frp_Title=
  751.                              AppStrings[MSG_FILEREQ_TITLE_FILE];
  752.                             FileReqParms.frp_Flags2=FRF_REJECTICONS;
  753.                             FileReqParms.frp_OldFile=
  754.                              ((struct StringInfo *) g->SpecialInfo)->Buffer;
  755.  
  756.                             /* Open file requester */
  757.                             if (file=OpenFileRequester()) {
  758.                               /* Set new file string */
  759.                              GT_SetGadgetAttrs(g,w,NULL,GTST_String,file,
  760.                                                         TAG_DONE);
  761.                              free(file);
  762.                             }
  763.  
  764.                             /* Activate old string gadget */
  765.                             ActivateGadget(CurrentGadget,w,NULL);
  766.                            }
  767.                            break;
  768.     case GAD_PSCREEN_BUT:  /* Open list requester */
  769.                            if (!ReqOpen &&
  770.                                OpenListRequester(LISTREQ_PUBSC,w)) {
  771.                             /* Disable window */
  772.                             DisableWindow(w);
  773.  
  774.                             /* Set update function */
  775.                             UpdateWindow=UpdateExecEditWindow;
  776.                             ReqOpen=TRUE;
  777.                            } else
  778.                             ActivateGadget(CurrentGadget,w,NULL);
  779.                            break;
  780.     case GAD_CURDIR_STR:   ActivateAndSetGadget(GAD_PATH_STR);
  781.                            break;
  782.     case GAD_PATH_STR:     ActivateAndSetGadget(GAD_OUTPUT_STR);
  783.                            break;
  784.     case GAD_OUTPUT_STR:   ActivateAndSetGadget(GAD_PSCREEN_STR);
  785.                            break;
  786.     case GAD_PSCREEN_STR:  ActivateAndSetGadget(GAD_NAME_STR);
  787.                            break;
  788.     case GAD_ARGS:         /* Toggle flag */
  789.                            CurrentNode->en_Flags^=EXPOF_ARGS;
  790.  
  791.                            /* Activate old string gadget */
  792.                            ActivateGadget(CurrentGadget,w,NULL);
  793.                            break;
  794.     case GAD_TOFRONT:      /* Toggle flag */
  795.                            CurrentNode->en_Flags^=EXPOF_TOFRONT;
  796.  
  797.                            /* Activate old string gadget */
  798.                            ActivateGadget(CurrentGadget,w,NULL);
  799.                            break;
  800.     case GAD_OK: {
  801.      char *s;
  802.  
  803.      /* Free old strings */
  804.      if (s=CurrentNode->en_Node.ln_Name) free(s);
  805.      if (s=CurrentNode->en_Command) free(s);
  806.      if (s=CurrentNode->en_CurrentDir) free(s);
  807.      if (s=CurrentNode->en_Output) free(s);
  808.      if (s=CurrentNode->en_Path) free(s);
  809.      if (s=CurrentNode->en_HotKey) free(s);
  810.      if (s=CurrentNode->en_PubScreen) free(s);
  811.  
  812.      /* Duplicate new strings */
  813.      if (((CurrentNode->en_Node.ln_Name=
  814.             DuplicateBuffer(gdata[GAD_NAME_STR].gadget)) != (char *) -1) &&
  815.          ((CurrentNode->en_Command=
  816.             DuplicateBuffer(gdata[GAD_COMMAND_STR].gadget)) != (char *) -1) &&
  817.          ((CurrentNode->en_CurrentDir=
  818.             DuplicateBuffer(gdata[GAD_CURDIR_STR].gadget)) != (char *) -1) &&
  819.          ((CurrentNode->en_Output=
  820.             DuplicateBuffer(gdata[GAD_OUTPUT_STR].gadget)) != (char *) -1) &&
  821.          ((CurrentNode->en_Path=
  822.             DuplicateBuffer(gdata[GAD_PATH_STR].gadget)) != (char *) -1) &&
  823.          ((CurrentNode->en_HotKey=
  824.             DuplicateBuffer(gdata[GAD_HOTKEY_STR].gadget)) != (char *) -1) &&
  825.          ((CurrentNode->en_PubScreen=
  826.             DuplicateBuffer(gdata[GAD_PSCREEN_STR].gadget)) != (char *) -1)) {
  827.       /* Copy integer gadget values */
  828.       CurrentNode->en_Stack=
  829.        ((struct StringInfo *) gdata[GAD_STACK_INT].gadget->SpecialInfo)
  830.         ->LongInt;
  831.       CurrentNode->en_Priority=
  832.        ((struct StringInfo *) gdata[GAD_PRIORITY_INT].gadget->SpecialInfo)
  833.         ->LongInt;
  834.       CurrentNode->en_Delay=
  835.        ((struct StringInfo *) gdata[GAD_DELAY_INT].gadget->SpecialInfo)
  836.         ->LongInt;
  837.  
  838.       NewNode=CurrentNode;
  839.      } else {
  840.       /* Couldn't copy strings */
  841.       NewNode=(struct Node *) -1;
  842.       CurrentNode->en_Node.ln_Name=NULL;
  843.       CurrentNode->en_Command=NULL;
  844.       CurrentNode->en_CurrentDir=NULL;
  845.       CurrentNode->en_Output=NULL;
  846.       CurrentNode->en_Path=NULL;
  847.       CurrentNode->en_HotKey=NULL;
  848.       CurrentNode->en_PubScreen=NULL;
  849.       FreeExecNode((struct Node *) CurrentNode);
  850.      }
  851.     }
  852.     break;
  853.     case GAD_CANCEL:       NewNode=(struct Node *) -1;
  854.                            FreeExecNode((struct Node *) CurrentNode);
  855.                            break;
  856.    }
  857.    break;
  858.  }
  859.  
  860.  /* Close window? */
  861.  if (NewNode) {
  862.   /* Yes. But first reply message!!! */
  863.   GT_ReplyIMsg(msg);
  864.   CloseExecEditWindow();
  865.  }
  866.  
  867.  return(NewNode);
  868. }
  869.  
  870. /* Update Exec edit window */
  871. void UpdateExecEditWindow(void *data)
  872. {
  873.  /* Got data? */
  874.  if (data != LREQRET_CANCEL) {
  875.   char *new;
  876.  
  877.   /* Selected something? */
  878.   new=(data == LREQRET_NOSELECT) ? NULL : ((struct Node *) data)->ln_Name;
  879.  
  880.   /* Set new public screen name */
  881.   GT_SetGadgetAttrs(gdata[GAD_PSCREEN_STR].gadget,w,NULL,GTST_String,new,
  882.                                                          TAG_DONE);
  883.  }
  884.  
  885.  /* Activate old string gadget */
  886.  ActivateGadget(CurrentGadget,w,NULL);
  887.  
  888.  /* Enable window */
  889.  EnableWindow(w,WINDOW_IDCMP);
  890.  
  891.  /* Restore update function pointer */
  892.  UpdateWindow=UpdateMainWindow;
  893.  CurrentWindow=w;
  894.  ReqOpen=FALSE;
  895. }
  896.  
  897. /* Read TMEX IFF chunk into Exec node */
  898. struct Node *ReadExecNode(UBYTE *buf)
  899. {
  900.  struct ExecNode *en;
  901.  
  902.  /* Allocate memory for node */
  903.  if (en=AllocMem(sizeof(struct ExecNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  904.   struct ExecPrefsObject *epo=buf;
  905.   ULONG sbits=epo->epo_StringBits;
  906.   UBYTE *ptr=epo+1;
  907.  
  908.   if ((!(sbits & EXPO_NAME) || (en->en_Node.ln_Name=GetConfigStr(&ptr))) &&
  909.       (!(sbits & EXPO_COMMAND) || (en->en_Command=GetConfigStr(&ptr))) &&
  910.       (!(sbits & EXPO_CURDIR) || (en->en_CurrentDir=GetConfigStr(&ptr))) &&
  911.       (!(sbits & EXPO_HOTKEY) || (en->en_HotKey=GetConfigStr(&ptr))) &&
  912.       (!(sbits & EXPO_OUTPUT) || (en->en_Output=GetConfigStr(&ptr))) &&
  913.       (!(sbits & EXPO_PATH) || (en->en_Path=GetConfigStr(&ptr))) &&
  914.       (!(sbits & EXPO_PSCREEN) || (en->en_PubScreen=GetConfigStr(&ptr)))) {
  915.    /* Copy flags & values */
  916.    en->en_Flags=epo->epo_Flags;
  917.    en->en_ExecType=epo->epo_ExecType;
  918.    en->en_Priority=epo->epo_Priority;
  919.    en->en_Delay=epo->epo_Delay;
  920.    en->en_Stack=epo->epo_Stack;
  921.  
  922.    /* All OK. */
  923.    return(en);
  924.   }
  925.  
  926.   /* Call failed */
  927.   FreeExecNode((struct Node *) en);
  928.  }
  929.  return(NULL);
  930. }
  931.  
  932. /* Write Exec node to TMEX IFF chunk */
  933. BOOL WriteExecNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  934. {
  935.  struct ExecNode *en=node;
  936.  struct ExecPrefsObject *epo=buf;
  937.  ULONG sbits=0;
  938.  UBYTE *ptr=epo+1;
  939.  
  940.  /* Copy strings */
  941.  if (PutConfigStr(en->en_Node.ln_Name,&ptr)) sbits|=EXPO_NAME;
  942.  if (PutConfigStr(en->en_Command,&ptr)) sbits|=EXPO_COMMAND;
  943.  if (PutConfigStr(en->en_CurrentDir,&ptr)) sbits|=EXPO_CURDIR;
  944.  if (PutConfigStr(en->en_HotKey,&ptr)) sbits|=EXPO_HOTKEY;
  945.  if (PutConfigStr(en->en_Output,&ptr)) sbits|=EXPO_OUTPUT;
  946.  if (PutConfigStr(en->en_Path,&ptr)) sbits|=EXPO_PATH;
  947.  if (PutConfigStr(en->en_PubScreen,&ptr)) sbits|=EXPO_PSCREEN;
  948.  
  949.  /* set string bits */
  950.  epo->epo_StringBits=sbits;
  951.  
  952.  /* Copy flags & values */
  953.  epo->epo_Flags=en->en_Flags;
  954.  epo->epo_ExecType=en->en_ExecType;
  955.  epo->epo_Priority=en->en_Priority;
  956.  epo->epo_Delay=en->en_Delay;
  957.  epo->epo_Stack=en->en_Stack;
  958.  
  959.  /* calculate length */
  960.  sbits=ptr-buf;
  961.  
  962.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  963.  
  964.  /* Open chunk */
  965.  if (PushChunk(iff,0,ID_TMEX,sbits)) return(FALSE);
  966.  
  967.  /* Write chunk */
  968.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  969.  
  970.  /* Close chunk */
  971.  if (PopChunk(iff)) return(FALSE);
  972.  
  973.  /* All OK. */
  974.  return(TRUE);
  975. }
  976.