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

  1. /*
  2.  * mainwindow.c  V2.0
  3.  *
  4.  * main window handling
  5.  *
  6.  * (c) 1990-1992 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. /* Edit windows function tables */
  12. OpenWindowFunction *OpenEditWindowFunctions[TMOBJTYPES]={
  13.                                                          OpenExecEditWindow,
  14.                                                          OpenImageEditWindow,
  15.                                                          OpenSoundEditWindow,
  16.                                                          OpenMenuEditWindow,
  17.                                                          OpenIconEditWindow,
  18.                                                          OpenDockEditWindow
  19.                                                         };
  20.  
  21. CopyNodeFunction *CopyNodeFunctions[TMOBJTYPES]={
  22.                                                  CopyExecNode,
  23.                                                  CopyImageNode,
  24.                                                  CopySoundNode,
  25.                                                  CopyMenuNode,
  26.                                                  CopyIconNode,
  27.                                                  CopyDockNode
  28.                                                 };
  29.  
  30. /* Window data */
  31. static struct Gadget *gl;             /* Gadget list */
  32. static struct Menu *mn;               /* Menu list */
  33. static struct Window *w;              /* Window */
  34. static UWORD ww,wh;                   /* Window size */
  35.                                       /* Current list in ListView gadget */
  36. static struct List *CurrentList=&ObjectLists[TMOBJTYPE_EXEC];
  37. static struct Node *CurrentNode=NULL; /* Current selected node */
  38. static struct Node *OldNode;          /* Current edited node */
  39. static ULONG CurrentListNumber=0;     /* Number of the current list */
  40. static LONG CurrentTop=0;             /* Top node ordinal number */
  41. static LONG CurrentOrd=-1;            /* Current node ordinal number */
  42. static ULONG CurrentSeconds=0;
  43. static ULONG CurrentMicros=0;
  44. static OpenWindowFunction *OpenEditWindow=OpenExecEditWindow;
  45. static CopyNodeFunction *CopyNode=CopyExecNode;
  46. static FreeNodeFunction *FreeNode=FreeExecNode;
  47. static struct EasyStruct es={sizeof(struct EasyStruct),0,NULL,NULL,NULL};
  48. static char *deftooltypes[]={"USE",NULL};
  49. #define WINDOW_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|\
  50.                       LISTVIEWIDCMP|CYCLEIDCMP|IDCMP_MENUPICK)
  51.  
  52. /* Gadget data */
  53. #define GAD_TYPE    0
  54. #define GAD_LIST    1
  55. #define GAD_TOP     2
  56. #define GAD_UP      3
  57. #define GAD_DOWN    4
  58. #define GAD_BOTTOM  5
  59. #define GAD_SORT    6
  60. #define GAD_NEW     7
  61. #define GAD_EDIT    8
  62. #define GAD_COPY    9
  63. #define GAD_REMOVE 10
  64. #define GAD_SAVE   11
  65. #define GAD_USE    12
  66. #define GAD_TEST   13
  67. #define GAD_CANCEL 14
  68. #define GADGETS    15
  69. static struct GadgetData gdata[GADGETS];
  70.  
  71. /* Gadget tags */
  72. static char *cyclelabels[TMOBJTYPES+1];
  73. static struct TagItem cycletags[]={GTCY_Labels, cyclelabels,
  74.                                    GTCY_Active, TMOBJTYPE_EXEC,
  75.                                    TAG_DONE};
  76.  
  77. static struct TagItem lvtags[]={GTLV_Labels,       &ObjectLists[TMOBJTYPE_EXEC],
  78.                                 GTLV_ShowSelected, NULL,
  79.                                 TAG_DONE};
  80.  
  81. /* Menu data */
  82. #define MENU_PROJECT  0
  83. #define MENU_OPEN     1
  84. #define MENU_SAVEAS   2
  85. #define MENU_ABOUT    4
  86. #define MENU_QUIT     6
  87. #define MENU_EDIT     7
  88. #define MENU_LSAVED   8
  89. #define MENU_RESTORE  9
  90. #define MENU_SETTING 10
  91. #define MENU_CRICONS 11
  92. static struct NewMenu mdata[]={
  93.                                {NM_TITLE,NULL,NULL,0,~0,NULL},
  94.                                 {NM_ITEM,NULL,NULL,0,~0,MENU_OPEN},
  95.                                 {NM_ITEM,NULL,NULL,0,~0,MENU_SAVEAS},
  96.                                 {NM_ITEM,NM_BARLABEL,NULL,0,~0,NULL},
  97.                                 {NM_ITEM,NULL,NULL,0,~0,MENU_ABOUT},
  98.                                 {NM_ITEM,NM_BARLABEL,NULL,0,~0,NULL},
  99.                                 {NM_ITEM,NULL,NULL,0,~0,MENU_QUIT},
  100.                                {NM_TITLE,NULL,NULL,0,~0,NULL},
  101.                                 {NM_ITEM,NULL,NULL,0,~0,MENU_LSAVED},
  102.                                 {NM_ITEM,NULL,NULL,0,~0,MENU_RESTORE},
  103.                                {NM_TITLE,NULL,NULL,0,~0,NULL},
  104.                                 {NM_ITEM,NULL,NULL,0,~1,MENU_CRICONS},
  105.                                {NM_END}
  106.                               };
  107.  
  108. /* Init main window */
  109. void InitMainWindow(UWORD left, UWORD fheight)
  110. {
  111.  ULONG i,tmp,maxw1,maxw2,maxw3;
  112.  struct GadgetData *gd;
  113.  
  114.  /* Init strings */
  115.  gdata[GAD_TYPE].name  =AppStrings[MSG_MAINWIN_TYPE_GAD];
  116.  gdata[GAD_LIST].name  =AppStrings[MSG_MAINWIN_LIST_GAD];
  117.  gdata[GAD_TOP].name   =AppStrings[MSG_WINDOW_TOP_GAD];
  118.  gdata[GAD_UP].name    =AppStrings[MSG_WINDOW_UP_GAD];
  119.  gdata[GAD_DOWN].name  =AppStrings[MSG_WINDOW_DOWN_GAD];
  120.  gdata[GAD_BOTTOM].name=AppStrings[MSG_WINDOW_BOTTOM_GAD];
  121.  gdata[GAD_SORT].name  =AppStrings[MSG_MAINWIN_SORT_GAD];
  122.  gdata[GAD_NEW].name   =AppStrings[MSG_MAINWIN_NEW_GAD];
  123.  gdata[GAD_EDIT].name  =AppStrings[MSG_MAINWIN_EDIT_GAD];
  124.  gdata[GAD_COPY].name  =AppStrings[MSG_MAINWIN_COPY_GAD];
  125.  gdata[GAD_REMOVE].name=AppStrings[MSG_WINDOW_REMOVE_GAD];
  126.  gdata[GAD_SAVE].name  =AppStrings[MSG_MAINWIN_SAVE_GAD];
  127.  gdata[GAD_USE].name   =AppStrings[MSG_MAINWIN_USE_GAD];
  128.  gdata[GAD_TEST].name  =AppStrings[MSG_MAINWIN_TEST_GAD];
  129.  gdata[GAD_CANCEL].name=AppStrings[MSG_WINDOW_CANCEL_GAD];
  130.  cyclelabels[TMOBJTYPE_EXEC] =AppStrings[MSG_MAINWIN_TYPE_EXEC_CYCLE_LABEL];
  131.  cyclelabels[TMOBJTYPE_IMAGE]=AppStrings[MSG_MAINWIN_TYPE_IMAGE_CYCLE_LABEL];
  132.  cyclelabels[TMOBJTYPE_SOUND]=AppStrings[MSG_MAINWIN_TYPE_SOUND_CYCLE_LABEL];
  133.  cyclelabels[TMOBJTYPE_MENU] =AppStrings[MSG_MAINWIN_TYPE_MENU_CYCLE_LABEL];
  134.  cyclelabels[TMOBJTYPE_ICON] =AppStrings[MSG_MAINWIN_TYPE_ICON_CYCLE_LABEL];
  135.  cyclelabels[TMOBJTYPE_DOCK] =AppStrings[MSG_MAINWIN_TYPE_DOCK_CYCLE_LABEL];
  136.  cyclelabels[TMOBJTYPES]     =NULL;
  137.  
  138.  mdata[MENU_PROJECT].nm_Label  =AppStrings[MSG_MAINWIN_PROJECT_MENU_LABEL];
  139.  mdata[MENU_OPEN].nm_Label     =AppStrings[MSG_MAINWIN_OPEN_MENU_LABEL];
  140.  mdata[MENU_OPEN].nm_CommKey   =AppStrings[MSG_MAINWIN_OPEN_MENU_SHORTCUT];
  141.  mdata[MENU_SAVEAS].nm_Label   =AppStrings[MSG_MAINWIN_SAVEAS_MENU_LABEL];
  142.  mdata[MENU_SAVEAS].nm_CommKey =AppStrings[MSG_MAINWIN_SAVEAS_MENU_SHORTCUT];
  143.  mdata[MENU_ABOUT].nm_Label    =AppStrings[MSG_MAINWIN_ABOUT_MENU_LABEL];
  144.  mdata[MENU_QUIT].nm_Label     =AppStrings[MSG_MAINWIN_QUIT_MENU_LABEL];
  145.  mdata[MENU_QUIT].nm_CommKey   =AppStrings[MSG_MAINWIN_QUIT_MENU_SHORTCUT];
  146.  mdata[MENU_EDIT].nm_Label     =AppStrings[MSG_MAINWIN_EDIT_MENU_LABEL];
  147.  mdata[MENU_LSAVED].nm_Label   =AppStrings[MSG_MAINWIN_LASTSAVED_MENU_LABEL];
  148.  mdata[MENU_LSAVED].nm_CommKey =AppStrings[MSG_MAINWIN_LASTSAVED_MENU_SHORTCUT];
  149.  mdata[MENU_RESTORE].nm_Label  =AppStrings[MSG_MAINWIN_RESTORE_MENU_LABEL];
  150.  mdata[MENU_RESTORE].nm_CommKey=AppStrings[MSG_MAINWIN_RESTORE_MENU_SHORTCUT];
  151.  mdata[MENU_SETTING].nm_Label  =AppStrings[MSG_MAINWIN_SETTINGS_MENU_LABEL];
  152.  mdata[MENU_CRICONS].nm_Label  =AppStrings[MSG_MAINWIN_CREATEICONS_MENU_LABEL];
  153.  mdata[MENU_CRICONS].nm_CommKey=
  154.                              AppStrings[MSG_MAINWIN_CREATEICONS_MENU_SHORTCUT];
  155.  mdata[MENU_CRICONS].nm_Flags=CHECKIT|MENUTOGGLE| (CreateIcons ? CHECKED : 0);
  156.  
  157.  /* Calculate maximum width for cycle gadget */
  158.  {
  159.   char **s;
  160.   maxw1=0;
  161.   for (s=cyclelabels; *s; s++)
  162.    if ((tmp=TextLength(&TmpRastPort,*s,strlen(*s))) > maxw1)
  163.     maxw1=tmp;
  164.   maxw1+=4*INTERWIDTH;
  165.  }
  166.  
  167.  /* Calculate size for type gadget text */
  168.  gd=gdata;
  169.  gd->left=TextLength(&TmpRastPort,gd->name,strlen(gd->name))+INTERWIDTH;
  170.  ww=gd->left+maxw1+2*INTERWIDTH;
  171.  
  172.  /* Calculate width for listview gadget */
  173.  gd++;
  174.  gd->width=2*TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  175.  if ((tmp=40*ScreenFont->tf_XSize) > gd->width) gd->width=tmp;
  176.  
  177.  /* Calculate maximum width for move gadgets */
  178.  maxw2=0;
  179.  for (gd++, i=GAD_TOP; i<=GAD_SORT; i++, gd++)
  180.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > maxw2)
  181.    maxw2=tmp;
  182.  maxw2+=2*INTERWIDTH;
  183.  if ((tmp=gdata[GAD_LIST].width+maxw2+2*INTERWIDTH) > ww) ww=tmp;
  184.  
  185.  /* Calculate maximum width for manipulation gadgets */
  186.  maxw3=0;
  187.  for (; i<=GAD_CANCEL; i++, gd++)
  188.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > maxw3)
  189.    maxw3=tmp;
  190.  maxw3+=2*INTERWIDTH;
  191.  if ((tmp=4*maxw3+4*INTERWIDTH) > ww) ww=tmp;
  192.  
  193.  /* Calculate window sizes */
  194.  wh=11*fheight+7*INTERHEIGHT;
  195.  
  196.  /* Type gadget */
  197.  gd=&gdata[GAD_TYPE];
  198.  maxw1=ww-gd->left-INTERWIDTH;
  199.  gd->type=CYCLE_KIND;
  200.  gd->flags=PLACETEXT_LEFT;
  201.  gd->tags=cycletags;
  202.  gd->left+=left;
  203.  gd->top=WindowTop+INTERHEIGHT;
  204.  gd->width=maxw1;
  205.  gd->height=fheight;
  206.  
  207.  /* Object list gadget */
  208.  gd++;
  209.  gd->type=LISTVIEW_KIND;
  210.  gd->flags=PLACETEXT_ABOVE;
  211.  gd->tags=lvtags;
  212.  gd->left=left;
  213.  gd->top=WindowTop+2*fheight+3*INTERHEIGHT;
  214.  gd->width=ww-2*INTERWIDTH-maxw2;
  215.  gd->height=7*fheight;
  216.  
  217.  /* Move gadgets */
  218.  maxw1=ww-maxw2-INTERWIDTH+left;
  219.  tmp=gd->top;
  220.  gd++;
  221.  for (i=GAD_TOP; i<=GAD_SORT; i++, gd++, tmp+=fheight+INTERHEIGHT) {
  222.   gd->type=BUTTON_KIND;
  223.   gd->flags=PLACETEXT_IN;
  224.   gd->tags=DisabledTags;
  225.   gd->left=maxw1;
  226.   gd->top=tmp;
  227.   gd->width=maxw2;
  228.   gd->height=fheight;
  229.  }
  230.  gdata[GAD_SORT].tags=NULL;
  231.  
  232.  /* Manipulation gadgets */
  233.  maxw1=left;
  234.  maxw2=(ww-INTERWIDTH-maxw3)/3;
  235.  tmp=WindowTop+9*fheight+4*INTERHEIGHT;
  236.  for (i=GAD_NEW; i<=GAD_REMOVE; i++, gd++, maxw1+=maxw2) {
  237.   gd->type=BUTTON_KIND;
  238.   gd->flags=PLACETEXT_IN;
  239.   gd->tags=DisabledTags;
  240.   gd->left=maxw1;
  241.   gd->top=tmp;
  242.   gd->width=maxw3;
  243.   gd->height=fheight;
  244.  }
  245.  gdata[GAD_NEW].tags=NULL;
  246.  gdata[GAD_REMOVE].left=ww-maxw3-INTERWIDTH+left;
  247.  
  248.  /* Configuration gadgets */
  249.  maxw1=left;
  250.  tmp+=fheight+2*INTERHEIGHT;
  251.  for (; i<=GAD_CANCEL; i++, gd++, maxw1+=maxw2) {
  252.   gd->type=BUTTON_KIND;
  253.   gd->flags=PLACETEXT_IN;
  254.   gd->left=maxw1;
  255.   gd->top=tmp;
  256.   gd->width=maxw3;
  257.   gd->height=fheight;
  258.  }
  259.  gdata[GAD_CANCEL].left=ww-maxw3-INTERWIDTH+left;
  260. }
  261.  
  262. /* Open main window */
  263. ULONG OpenMainWindow(void)
  264. {
  265.  /* Create gadgets */
  266.  if (gl=CreateGadgetList(gdata,GADGETS)) {
  267.   /* Create menus */
  268.   if (mn=CreateMenus(mdata,GTMN_FullMenu,TRUE,
  269.                            TAG_DONE)) {
  270.    /* Layout menus */
  271.    if (LayoutMenus(mn,ScreenVI,TAG_DONE))
  272.     /* Open window */
  273.     if (w=OpenWindowTags(NULL,WA_Left,10,
  274.                               WA_Top,PublicScreen->BarHeight+2,
  275.                               WA_InnerWidth,ww,
  276.                               WA_InnerHeight,wh,
  277.                               WA_AutoAdjust,TRUE,
  278.                               WA_Title,AppStrings[MSG_MAINWIN_TITLE],
  279.                               WA_PubScreen,PublicScreen,
  280.                               WA_Flags,WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  281.                                        WFLG_DEPTHGADGET|WFLG_ACTIVATE,
  282.                               WA_IDCMP,WINDOW_IDCMP,
  283.                               TAG_DONE)) {
  284.      /* Set menu strip */
  285.      if (SetMenuStrip(w,mn)) {
  286.       /* Release public screen */
  287.       UnlockPubScreen(NULL,PublicScreen);
  288.  
  289.       /* Add gadgets to window */
  290.       AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  291.       RefreshGList(gl,w,NULL,(UWORD) -1);
  292.       GT_RefreshWindow(w,NULL);
  293.  
  294.       /* Set local variables */
  295.       IDCMPPort=w->UserPort;
  296.       w->UserData=HandleMainWindowIDCMP;
  297.       CurrentWindow=w;
  298.  
  299.       /* All OK. (Return IDCMP signal mask) */
  300.       return(1L << IDCMPPort->mp_SigBit);
  301.      }
  302.      CloseWindow(w);
  303.    }
  304.    FreeMenus(mn);
  305.   }
  306.   FreeGadgets(gl);
  307.  }
  308.  /* Call failed */
  309.  return(0);
  310. }
  311.  
  312. /* Close main window */
  313. void CloseMainWindow(void)
  314. {
  315.  /* Free resources */
  316.  RemoveGList(w,gl,(UWORD) -1);
  317.  ClearMenuStrip(w);
  318.  CloseWindow(w);
  319.  FreeMenus(mn);
  320.  FreeGadgets(gl);
  321. }
  322.  
  323. /* Detach list */
  324. static void DetachObjectList(void)
  325. {
  326.  GT_SetGadgetAttrs(gdata[GAD_LIST].gadget,w,NULL,GTLV_Labels,-1,
  327.                                                  TAG_DONE);
  328. }
  329.  
  330. /* Attach list */
  331. static void AttachObjectList(void)
  332. {
  333.  GT_SetGadgetAttrs(gdata[GAD_LIST].gadget,w,NULL,GTLV_Labels,   CurrentList,
  334.                                                  GTLV_Top,      CurrentTop,
  335.                                                  GTLV_Selected, CurrentOrd,
  336.                                                  TAG_DONE);
  337. }
  338.  
  339. /* Disable object gadgets */
  340. static void DisableObjectGadgets(BOOL disable)
  341. {
  342.  DisableGadget(gdata[GAD_TOP].gadget,w,disable);
  343.  DisableGadget(gdata[GAD_UP].gadget,w,disable);
  344.  DisableGadget(gdata[GAD_DOWN].gadget,w,disable);
  345.  DisableGadget(gdata[GAD_BOTTOM].gadget,w,disable);
  346.  DisableGadget(gdata[GAD_EDIT].gadget,w,disable);
  347.  DisableGadget(gdata[GAD_COPY].gadget,w,disable);
  348.  DisableGadget(gdata[GAD_REMOVE].gadget,w,disable);
  349. }
  350.  
  351. /* Display write error requester */
  352. static void ConfigWriteError(char *s)
  353. {
  354.  es.es_TextFormat=AppStrings[MSG_MAINWIN_WRITE_ERROR];
  355.  es.es_GadgetFormat=AppStrings[MSG_WINDOW_CANCEL_GAD];
  356.  
  357.  EasyRequest(w,&es,NULL,s);
  358. }
  359.  
  360. /* Handle main window IDCMP events */
  361. void *HandleMainWindowIDCMP(struct IntuiMessage *msg)
  362. {
  363.  void *closewindow=NULL;
  364.  
  365.  /* Which IDCMP class? */
  366.  switch (msg->Class) {
  367.   case IDCMP_CLOSEWINDOW:   if (!UpdateWindow) closewindow=(void *) 1;
  368.                             break;
  369.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  370.                             GT_EndRefresh(w,TRUE);
  371.                             break;
  372.   case IDCMP_GADGETUP:
  373.    switch (((struct Gadget *) msg->IAddress)->GadgetID) {
  374.     case GAD_TYPE:   {
  375.                       ULONG code=msg->Code;
  376.  
  377.                       /* Set new Exec list in ListView gadget, detach list */
  378.                       DetachObjectList();
  379.  
  380.                       /* Set new pointers */
  381.                       CurrentList=&ObjectLists[code];
  382.                       CurrentListNumber=code;
  383.                       CurrentNode=NULL;
  384.                       CurrentTop=0;
  385.                       CurrentOrd=-1;
  386.  
  387.                       /* Set new function pointers */
  388.                       OpenEditWindow=OpenEditWindowFunctions[code];
  389.                       CopyNode=CopyNodeFunctions[code];
  390.                       FreeNode=FreeNodeFunctions[code];
  391.  
  392.                       /* Disable object gadgets, attach list */
  393.                       DisableObjectGadgets(TRUE);
  394.                       AttachObjectList();
  395.                      }
  396.                      break;
  397.     case GAD_LIST:   {
  398.                       ULONG i;
  399.  
  400.                       /* Find node */
  401.                       CurrentOrd=msg->Code;
  402.                       CurrentTop=(CurrentOrd>3) ? CurrentOrd-3 : 0;
  403.                       CurrentNode=GetHead(CurrentList);
  404.                       for (i=0; i<CurrentOrd; i++)
  405.                        CurrentNode=GetSucc(CurrentNode);
  406.  
  407.                       /* Double click? */
  408.                       if (DoubleClick(CurrentSeconds,CurrentMicros,
  409.                                       msg->Seconds,msg->Micros) &&
  410.                           !UpdateWindow && CurrentNode) {
  411.                        /* Save pointer to node */
  412.                        OldNode=CurrentNode;
  413.  
  414.                        /* Open edit window */
  415.                        if ((*OpenEditWindow)(CurrentNode,w)) {
  416.                         /* Disable window */
  417.                         DisableWindow(w);
  418.  
  419.                         /* Set update function */
  420.                         UpdateWindow=UpdateMainWindow;
  421.                        } else
  422.                         DisplayBeep(NULL);
  423.                       }
  424.  
  425.                       /* Activate object gadgets */
  426.                       DisableObjectGadgets(FALSE);
  427.  
  428.                       /* Save current time */
  429.                       CurrentSeconds=msg->Seconds;
  430.                       CurrentMicros=msg->Micros;
  431.                      }
  432.                      break;
  433.     case GAD_TOP:    if (CurrentNode) {
  434.                       /* Detach object list */
  435.                       DetachObjectList();
  436.  
  437.                       /* Move node to top of list */
  438.                       Remove(CurrentNode);
  439.                       AddHead(CurrentList,CurrentNode);
  440.                       CurrentTop=0;
  441.                       CurrentOrd=0;
  442.  
  443.                       /* Attach object list */
  444.                       AttachObjectList();
  445.                      }
  446.                      break;
  447.     case GAD_UP:     {
  448.                       struct Node *pred;
  449.  
  450.                       /* Node valid and has a predecessor? */
  451.                       if (CurrentNode && (pred=GetPred(CurrentNode))) {
  452.                        /* Detach object list */
  453.                        DetachObjectList();
  454.  
  455.                        /* Move node one position up */
  456.                        pred=GetPred(pred);
  457.                        Remove(CurrentNode);
  458.                        Insert(CurrentList,CurrentNode,pred);
  459.                        --CurrentOrd;
  460.                        CurrentTop=(CurrentOrd>3) ? CurrentOrd-3 : 0;
  461.  
  462.                        /* Attach object list */
  463.                        AttachObjectList();
  464.                       }
  465.                      }
  466.                      break;
  467.     case GAD_DOWN:   {
  468.                       struct Node *succ;
  469.  
  470.                       /* Node valid and has a successor? */
  471.                       if (CurrentNode && (succ=GetSucc(CurrentNode))) {
  472.                        /* Detach object list */
  473.                        DetachObjectList();
  474.  
  475.                        /* Move node one position down */
  476.                        Remove(CurrentNode);
  477.                        Insert(CurrentList,CurrentNode,succ);
  478.                        ++CurrentOrd;
  479.                        CurrentTop=(CurrentOrd>3) ? CurrentOrd-3 : 0;
  480.  
  481.                        /* Attach object list */
  482.                        AttachObjectList();
  483.                       }
  484.                      }
  485.                      break;
  486.     case GAD_BOTTOM: if (CurrentNode) {
  487.                       ULONG i;
  488.                       struct Node *tmpnode;
  489.  
  490.                       /* Detach object list */
  491.                       DetachObjectList();
  492.  
  493.                       /* Move tool to bottom of list */
  494.                       Remove(CurrentNode);
  495.                       AddTail(CurrentList,CurrentNode);
  496.  
  497.                       /* Search ordinal number */
  498.                       tmpnode=GetHead(CurrentList);
  499.                       for (i=0; tmpnode; i++) tmpnode=GetSucc(tmpnode);
  500.                       CurrentOrd=--i;
  501.                       CurrentTop=(i>3) ? i-3 : 0;
  502.  
  503.                       /* Attach object list */
  504.                       AttachObjectList();
  505.                      }
  506.                      break;
  507.     case GAD_SORT:   {
  508.                       BOOL notfinished=TRUE;
  509.  
  510.                       /* Detach object list */
  511.                       DetachObjectList();
  512.  
  513.                       /* Sort list (quick & dirty bubble sort) */
  514.                       while (notfinished) {
  515.                        struct Node *first;
  516.  
  517.                        /* Reset not finished flag */
  518.                        notfinished=FALSE;
  519.  
  520.                        /* Get first node */
  521.                        if (first=GetHead(CurrentList)) {
  522.                         struct Node *second;
  523.  
  524.                         /* One bubble sort round */
  525.                         while (second=GetSucc(first))
  526.                          /* Compare */
  527.                          if (stricmp(first->ln_Name,second->ln_Name)>0) {
  528.                           /* Swap */
  529.                           Remove(first);
  530.                           Insert(CurrentList,first,second);
  531.                           notfinished=TRUE;
  532.                          } else
  533.                           /* Next */
  534.                           first=second;
  535.                        }
  536.                       }
  537.  
  538.                       /* Reset pointers */
  539.                       CurrentNode=NULL;
  540.                       CurrentOrd=-1;
  541.                       CurrentTop=0;
  542.  
  543.                       /* Deactivate object gadgets */
  544.                       DisableObjectGadgets(TRUE);
  545.  
  546.                       /* Attach object list */
  547.                       AttachObjectList();
  548.                      }
  549.                      break;
  550.     case GAD_NEW:    if (!UpdateWindow) {
  551.                       /* No old node */
  552.                       OldNode=NULL;
  553.  
  554.                       /* Open edit window */
  555.                       if ((*OpenEditWindow)(NULL,w)) {
  556.                        /* Disable window */
  557.                        DisableWindow(w);
  558.  
  559.                        /* Set update function */
  560.                        UpdateWindow=UpdateMainWindow;
  561.                       } else
  562.                        DisplayBeep(NULL);
  563.                      }
  564.                      break;
  565.     case GAD_EDIT:   if (!UpdateWindow) {
  566.                       /* Save pointer to node */
  567.                       OldNode=CurrentNode;
  568.  
  569.                       /* Open edit window */
  570.                       if ((*OpenEditWindow)(CurrentNode,w)) {
  571.                        /* Disable window */
  572.                        DisableWindow(w);
  573.  
  574.                        /* Set update function */
  575.                        UpdateWindow=UpdateMainWindow;
  576.                       } else
  577.                        DisplayBeep(NULL);
  578.                      }
  579.                      break;
  580.     case GAD_COPY:   if (CurrentNode) {
  581.                       struct Node *newnode;
  582.  
  583.                       /* Detach object list */
  584.                       DetachObjectList();
  585.  
  586.                       /* Copy node */
  587.                       if (newnode=(*CopyNode)(CurrentNode)) {
  588.                        /* Insert new node */
  589.                        Insert(CurrentList,newnode,CurrentNode);
  590.  
  591.                        /* Reset pointers */
  592.                        CurrentNode=newnode;
  593.                        CurrentOrd++;
  594.                        CurrentTop=(CurrentOrd>3) ? CurrentOrd-3 : 0;
  595.                       }
  596.  
  597.                       /* Attach object list */
  598.                       AttachObjectList();
  599.                      }
  600.                      break;
  601.     case GAD_REMOVE: /* Remove current node */
  602.                      if (CurrentNode) {
  603.                       /* Detach object list */
  604.                       DetachObjectList();
  605.  
  606.                       /* Deactivate object gadgets */
  607.                       DisableObjectGadgets(TRUE);
  608.  
  609.                       /* Remove node from list */
  610.                       Remove(CurrentNode);
  611.  
  612.                       /* Free node */
  613.                       (*FreeNode)(CurrentNode);
  614.  
  615.                       /* Reset pointers */
  616.                       CurrentNode=NULL;
  617.                       CurrentTop=(CurrentOrd>3) ? CurrentOrd-3 : 0;
  618.                       CurrentOrd=-1;
  619.  
  620.                       /* Attach object list */
  621.                       AttachObjectList();
  622.                      }
  623.                      break;
  624.     case GAD_SAVE:   {
  625.                       /* Set wait pointer */
  626.                       DisableWindow(w);
  627.  
  628.                       /* Save config file */
  629.                       if (WriteConfigFile(SavePrefsFileName))
  630.                        if (CopyFile(SavePrefsFileName,PrefsFileName))
  631.                         closewindow=(void *) 1;
  632.                        else
  633.                         ConfigWriteError(PrefsFileName);
  634.                       else
  635.                        ConfigWriteError(SavePrefsFileName);
  636.  
  637.                       /* Remove wait pointer */
  638.                       EnableWindow(w,WINDOW_IDCMP);
  639.                      }
  640.                      break;
  641.     case GAD_USE:    {
  642.                       /* Set wait pointer */
  643.                       DisableWindow(w);
  644.  
  645.                       /* Save config file */
  646.                       if (WriteConfigFile(PrefsFileName))
  647.                        closewindow=(void *) 1;
  648.                       else
  649.                        ConfigWriteError(PrefsFileName);
  650.  
  651.                       /* Remove wait pointer */
  652.                       EnableWindow(w,WINDOW_IDCMP);
  653.                      }
  654.                      break;
  655.     case GAD_TEST:   {
  656.                       /* Set wait pointer */
  657.                       DisableWindow(w);
  658.  
  659.                       /* Save config file */
  660.                       if (!WriteConfigFile(PrefsFileName))
  661.                        ConfigWriteError(PrefsFileName);
  662.  
  663.                       /* Remove wait pointer */
  664.                       EnableWindow(w,WINDOW_IDCMP);
  665.                      }
  666.                      break;
  667.     case GAD_CANCEL: if (!UpdateWindow) closewindow=(void *) 1;
  668.                      break;
  669.    }
  670.    break;
  671.   case IDCMP_MENUPICK: {
  672.     USHORT menunum=msg->Code;
  673.  
  674.     /* Scan all menu events */
  675.     while (menunum!=MENUNULL) {
  676.      struct MenuItem *menuitem=ItemAddress(mn,menunum);
  677.  
  678.      /* Which menu selected? */
  679.      switch(GTMENUITEM_USERDATA(menuitem)) {
  680.       case MENU_OPEN:    {
  681.                           char *file;
  682.  
  683.                           FileReqParms.frp_Window=w;
  684.                           FileReqParms.frp_Title=
  685.                              AppStrings[MSG_FILEREQ_TITLE_FILE];
  686.                           FileReqParms.frp_OKText=AppStrings[MSG_WINDOW_OK_GAD];
  687.                           FileReqParms.frp_Flags1=FRF_DOPATTERNS;
  688.                           FileReqParms.frp_Flags2=FRF_REJECTICONS;
  689.                           FileReqParms.frp_OldFile=PrefsFileName;
  690.  
  691.                           /* Get file name */
  692.                           if (file=OpenFileRequester()) {
  693.                            /* Detach object list */
  694.                            DetachObjectList();
  695.  
  696.                            /* Deactivate object gadgets */
  697.                            DisableObjectGadgets(TRUE);
  698.  
  699.                            /* Free all preferences objects */
  700.                            FreeAllObjects();
  701.  
  702.                            /* Set wait pointer */
  703.                            DisableWindow(w);
  704.  
  705.                            /* Read new config file */
  706.                            if (!ReadConfigFile(file)) DisplayBeep(NULL);
  707.  
  708.                            /* Remove wait pointer */
  709.                            EnableWindow(w,WINDOW_IDCMP);
  710.  
  711.                            /* Set new pointers */
  712.                            CurrentList=&ObjectLists[CurrentListNumber];
  713.                            CurrentNode=NULL;
  714.                            CurrentTop=0;
  715.                            CurrentOrd=-1;
  716.  
  717.                            /* Free file name */
  718.                            free(file);
  719.  
  720.                            /* Attach object list */
  721.                            AttachObjectList();
  722.                           }
  723.                          }
  724.                          break;
  725.       case MENU_SAVEAS:  {
  726.                           char *file;
  727.  
  728.                           FileReqParms.frp_Window=w;
  729.                           FileReqParms.frp_Title=
  730.                              AppStrings[MSG_FILEREQ_TITLE_FILE];
  731.                           FileReqParms.frp_OKText=
  732.                              AppStrings[MSG_MAINWIN_SAVE_GAD];
  733.                           FileReqParms.frp_Flags1=FRF_DOSAVEMODE;
  734.                           FileReqParms.frp_Flags2=FRF_REJECTICONS;
  735.                           FileReqParms.frp_OldFile=SavePrefsFileName;
  736.  
  737.                           /* Get file name */
  738.                           if (file=OpenFileRequester()) {
  739.                            /* Set wait pointer */
  740.                            DisableWindow(w);
  741.  
  742.                            /* Read new config file */
  743.                            if (WriteConfigFile(file)) {
  744.                             /* Create icon for file? */
  745.                             if (CreateIcons) {
  746.                              struct DiskObject *dobj;
  747.  
  748.                              /* Get project icon */
  749.                              if (dobj=
  750.                                   GetDiskObjectNew(file)) {
  751.                               char *deftool=dobj->do_DefaultTool;
  752.                               char **tooltypes=dobj->do_ToolTypes;
  753.                               UBYTE type=dobj->do_Type;
  754.  
  755.                               /* Set new values */
  756.                               dobj->do_DefaultTool=ProgramName;
  757.                               dobj->do_ToolTypes=deftooltypes;
  758.                               dobj->do_Type=WBPROJECT;
  759.  
  760.                               /* Write icon */
  761.                               PutDiskObject(file,dobj);
  762.  
  763.                               /* Set old values */
  764.                               dobj->do_DefaultTool=deftool;
  765.                               dobj->do_ToolTypes=tooltypes;
  766.                               dobj->do_Type=type;
  767.  
  768.                               /* Free icon */
  769.                               FreeDiskObject(dobj);
  770.                              }
  771.                             }
  772.                            } else
  773.                             /* error occurred */
  774.                             ConfigWriteError(file);
  775.  
  776.                            /* Remove wait pointer */
  777.                            EnableWindow(w,WINDOW_IDCMP);
  778.  
  779.                            /* Free file name */
  780.                            free(file);
  781.                           }
  782.                          }
  783.                          break;
  784.       case MENU_ABOUT:   es.es_TextFormat="ToolManager " TMVERSION "."
  785.                                           TMREVISION " (" TMCONFDATE ")\n"
  786.                                           "Freely distributable\n"
  787.                                           "⌐ 1990-1992  Stefan Becker";
  788.                          es.es_GadgetFormat=AppStrings[MSG_WINDOW_CANCEL_GAD];
  789.  
  790.                          /* Disable window */
  791.                          DisableWindow(w);
  792.  
  793.                          /* Display requester */
  794.                          EasyRequest(w,&es,NULL,NULL);
  795.  
  796.                          /* Enable window */
  797.                          EnableWindow(w,WINDOW_IDCMP);
  798.                          break;
  799.       case MENU_QUIT:    if (!UpdateWindow) closewindow=(void *) 1;
  800.                          break;
  801.       case MENU_LSAVED:  {
  802.                           /* Detach object list */
  803.                           DetachObjectList();
  804.  
  805.                           /* Deactivate object gadgets */
  806.                           DisableObjectGadgets(TRUE);
  807.  
  808.                           /* Free all preferences objects */
  809.                           FreeAllObjects();
  810.  
  811.                           /* Set wait pointer */
  812.                           DisableWindow(w);
  813.  
  814.                           /* Read new config file */
  815.                           if (!ReadConfigFile(SavePrefsFileName))
  816.                            DisplayBeep(NULL);
  817.  
  818.                           /* Remove wait pointer */
  819.                           EnableWindow(w,WINDOW_IDCMP);
  820.  
  821.                           /* Set new pointers */
  822.                           CurrentList=&ObjectLists[CurrentListNumber];
  823.                           CurrentNode=NULL;
  824.                           CurrentTop=0;
  825.                           CurrentOrd=-1;
  826.  
  827.                           /* Attach object list */
  828.                           AttachObjectList();
  829.                          }
  830.                          break;
  831.       case MENU_RESTORE: {
  832.                           /* Detach object list */
  833.                           DetachObjectList();
  834.  
  835.                           /* Deactivate object gadgets */
  836.                           DisableObjectGadgets(TRUE);
  837.  
  838.                           /* Free all preferences objects */
  839.                           FreeAllObjects();
  840.  
  841.                           /* Set wait pointer */
  842.                           DisableWindow(w);
  843.  
  844.                           /* Read new config file */
  845.                           if (!ReadConfigFile(PrefsFileName)) DisplayBeep(NULL);
  846.  
  847.                           /* Remove wait pointer */
  848.                           EnableWindow(w,WINDOW_IDCMP);
  849.  
  850.                           /* Set new pointers */
  851.                           CurrentList=&ObjectLists[CurrentListNumber];
  852.                           CurrentNode=NULL;
  853.                           CurrentTop=0;
  854.                           CurrentOrd=-1;
  855.  
  856.                           /* Attach object list */
  857.                           AttachObjectList();
  858.                          }
  859.                          break;
  860.       case MENU_CRICONS: CreateIcons=(menuitem->Flags & CHECKED) != 0;
  861.                          break;
  862.      }
  863.  
  864.      /* Get next menu event number */
  865.      menunum=menuitem->NextSelect;
  866.     }
  867.    }
  868.    break;
  869.  }
  870.  
  871.  /* Close Window? */
  872.  if (closewindow) GT_ReplyIMsg(msg);
  873.  
  874.  return(closewindow);
  875. }
  876.  
  877. /* Update main window (after an edit window has closed) */
  878. void UpdateMainWindow(void *data)
  879. {
  880.  /* Detach object list */
  881.  DetachObjectList();
  882.  
  883.  DEBUG_PRINTF("OldNode: 0x%08lx ",OldNode);
  884.  DEBUG_PRINTF("NewNode: 0x%08lx\n",data);
  885.  
  886.  /* Node changed? */
  887.  if (data!=(void *) -1) {
  888.   struct Node *NewNode=data;
  889.  
  890.   /* Make sure that ln_Name is valid */
  891.   if (!NewNode->ln_Name) NewNode->ln_Name=strdup("");
  892.  
  893.   /* Yes. New or Edit? */
  894.   if (OldNode) {
  895.    /* Edit. Insert new node */
  896.    Insert(CurrentList,NewNode,OldNode);
  897.  
  898.    /* Remove old node */
  899.    Remove(OldNode);
  900.  
  901.    /* Free old node */
  902.    (*FreeNode)(OldNode);
  903.  
  904.    /* Set pointer */
  905.    CurrentNode=NewNode;
  906.   } else {
  907.    /* New. Insert after selected node? */
  908.    if (CurrentNode) {
  909.     /* Yes */
  910.     Insert(CurrentList,NewNode,CurrentNode);
  911.     CurrentOrd++;
  912.     CurrentTop=(CurrentOrd>3) ? CurrentOrd-3 : 0;
  913.    } else {
  914.     /* No */
  915.     struct Node *tmpnode;
  916.     ULONG i;
  917.  
  918.     /* Add node to the end of list */
  919.     AddTail(CurrentList,NewNode);
  920.  
  921.     /* Search ordinal number */
  922.     tmpnode=GetHead(CurrentList);
  923.     for (i=0; tmpnode; i++) tmpnode=GetSucc(tmpnode);
  924.     CurrentOrd=--i;
  925.     CurrentTop=(i>3) ? i-3 : 0;
  926.    }
  927.    CurrentNode=NewNode;
  928.   }
  929.  }
  930.  
  931.  /* Activate Gadgets */
  932.  DisableObjectGadgets(CurrentNode==NULL);
  933.  
  934.  /* Attach object list */
  935.  AttachObjectList();
  936.  
  937.  /* Enable window */
  938.  EnableWindow(w,WINDOW_IDCMP);
  939.  
  940.  /* Restore update function pointer */
  941.  UpdateWindow=NULL;
  942.  CurrentWindow=w;
  943. }
  944.