home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d7xx / d787 / scale.lha / Scale / Source.lha / FileWindow.c < prev    next >
C/C++ Source or Header  |  1992-12-12  |  40KB  |  1,309 lines

  1. /* Name: FileWindow.c   by Anders Bjerin
  2.    Modified version by Dick Taylor May 1992.  Removed--comment cards,
  3.    blank lines.  Structure formats compressed.  Also removed two 
  4.    erroneous hex characters "A0".  
  5.  
  6.    This is a customized version of FileWindow.c to use with SCALE.  A few
  7.    minor technical details have been changed:
  8.         --Remove entry point parameters: title, extension, x, y, screen.
  9.         --Change PANIC to --
  10.             PANIC1 = could not open window for FileWindow
  11.             PANIC2 = not enough memory available
  12.         --Delete struct "my_font" (= topaz) and all references to it.
  13.         --Delete option for using a custom screen.
  14.         --Removed the DELETE option
  15.         --Added gadget for ram:
  16.         --On entry, use either gadget Save or gadget Load, but not both
  17.  
  18. */
  19.  
  20. #include <exec/types.h>
  21. #include <exec/nodes.h>
  22. #include <exec/lists.h>
  23. #include <exec/libraries.h>
  24. #include <exec/ports.h>
  25. #include <exec/interrupts.h>
  26. #include <exec/io.h>
  27. #include <exec/memory.h>
  28. #include <libraries/dos.h>
  29. #include <libraries/dosextens.h>
  30. #include <intuition/intuition.h>
  31. #include <string.h>
  32.  
  33. /*#include "FileWindow.h" -- 14 lines inserted */
  34. /* What file_window() will return: */
  35. #define LOAD    500
  36. #define SAVE    600
  37. #define CANCEL  800
  38. #define QUIT    900
  39. #define PANIC1  1001        /* Cannot open window for FileWindow */
  40. #define PANIC2  1002        /* Not enough memory */
  41.  
  42. /* The minimum size of the strings: */
  43. #define DRAWER_LENGTH 100 /*  100 characters including NULL. */
  44. #define FILE_LENGTH    30 /*   30           -"-              */
  45. #define TOTAL_LENGTH  130 /*  130           -"-              */
  46.  
  47. /* THE END -- of FileWindow.h */
  48.  
  49. /* Declare the functions we are going to use: */
  50. USHORT FileWindow();
  51. STRPTR right_pos();
  52. APTR save_file_info();
  53. BOOL file_comp();
  54. BOOL directory();
  55. BOOL last_check();
  56. BOOL new_drawer();
  57. BOOL pick_file();
  58. BOOL request_ask();
  59. void put_in();
  60. void deallocate_file_info();
  61. void change_device();
  62. void parent();
  63. void request_ok();
  64. void display_list();
  65. void connect_dir_file();
  66. void adjust_string_gadgets();
  67.  
  68. extern struct IntuitionBase *IntuitionBase;
  69. extern struct MenuItem *item, mitem2;
  70.  
  71. struct Window *file_window;
  72. struct IntuiMessage *my_gadget_message;
  73.  
  74. /* Structure for memory allocate of each file/directory */
  75. struct file_info { BYTE name[28]; BOOL directory; struct file_info *next;};
  76.  
  77. struct FileInfoBlock *file_info;
  78. struct FileLock *lock, *Lock();
  79.  
  80. BOOL file_lock;  /* Have we locked a file?       */
  81. BOOL more_files; /* More files in the directory? */
  82. BOOL first_file; /* First file?                  */
  83.  
  84. struct file_info *first_pointer; /* Pointing to the first structure. */
  85.  
  86. /* ********************************************************************* */
  87. /* * IntuiText structures for the requesters                           * */
  88.  
  89. struct IntuiText text_request={0,2,JAM1,15,5,NULL,NULL,NULL};
  90.  
  91. struct IntuiText ok_request={0,2,JAM1,6,3,NULL,"OK",NULL};
  92.  
  93. struct IntuiText option1_request={0,2,JAM1,6,3,NULL,NULL,NULL};
  94.  
  95. struct IntuiText option2_request={0,2,JAM1,6,3,NULL,NULL,NULL};
  96.  
  97. /* Values for a 4-letter box: */
  98. SHORT points4[]={0,0,  44,0,  44,14,   0,14,   0,0};
  99.  
  100. /* Values for a 6-letter box: */
  101. SHORT points6[]={0,0,  60,0,  60,14,   0,14,   0,0};
  102.  
  103. /* A border for a 4-letter box: */
  104. struct Border border_text4={0,0,1,2,JAM1,5,points4,NULL};
  105.  
  106. /* A border for a 6-letter box: */
  107. struct Border border_text6={0,0,1,2,JAM1,5,points6,NULL};
  108.  
  109. /* ********************************************************************* */
  110. /* * Information for the proportional gadget                           * */
  111.  
  112. struct Image image_prop;
  113. struct PropInfo prop_info={AUTOKNOB | FREEVERT,0,0,0,0xFFFF,0,0,0,0,0,0};
  114.  
  115. struct Gadget gadget_proportional={NULL,290,50,21,72,GADGHCOMP,
  116.   GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY,PROPGADGET,(APTR) &image_prop,
  117.   NULL,NULL,NULL,(APTR) &prop_info,NULL,NULL};
  118.  
  119. UBYTE name_backup[DRAWER_LENGTH];    /* Undo buffer for string gadgets*/
  120.  
  121. /* ********************************************************************* */
  122. /* * Information for the string gadget "Drawer:"                       * */
  123.  
  124. UBYTE drawer_name[DRAWER_LENGTH];
  125.  
  126. /* Values for a 28-letter string box: */
  127. SHORT points28s[]={-7,-4,  200,-4,  200,11,   -7,11,   -7,-4};
  128.  
  129. /* A border for a 28-letter string box: */
  130. struct Border border_text28s={0,0,1,2,JAM1,5,points28s,NULL};
  131.  
  132. struct IntuiText text_drawer={1,2,JAM1,-69,0,NULL,"Drawer:",NULL};
  133.  
  134. struct StringInfo string_drawer={drawer_name,name_backup,0,70,0,
  135.   0,0,0,NULL,NULL,NULL,};
  136.  
  137. struct Gadget gadget_drawer={&gadget_proportional,83,35,198,8,
  138.   GADGHCOMP,RELVERIFY,STRGADGET,(APTR) &border_text28s,
  139.   NULL,&text_drawer,NULL,(APTR) &string_drawer,NULL,NULL};
  140.  
  141. /* ********************************************************************* */
  142. /* * Information for the string gadget "File:"                         * */
  143.  
  144. UBYTE file_name[FILE_LENGTH];
  145.  
  146. /* Values for a 30-letter string box: */
  147. SHORT points30s[]={-7,-4,  244,-4,  244,11,   -7,11,   -7,-4};
  148.  
  149. /* A border for a 30-letter string box: */
  150. struct Border border_text30s={0,0,1,2,JAM1,5,points30s,NULL};
  151.  
  152. struct IntuiText text_file={1,2,JAM1,-53,0,NULL,"File:",NULL};
  153.  
  154. struct StringInfo string_file={file_name,name_backup,0,40,0,
  155.   0,0,0,NULL,NULL,NULL,};
  156.  
  157. struct Gadget gadget_file={&gadget_drawer,66,129,240,8,GADGHCOMP,NULL,
  158.   STRGADGET,(APTR) &border_text30s,NULL,&text_file,NULL,
  159.   (APTR) &string_file,NULL,NULL};
  160.  
  161. /* ********************************************************************* */
  162. /* * Information for the string gadget "Extension"                     * */
  163.  
  164. UBYTE extension_name[7]; /* 7 characters including NULL. */
  165.  
  166. /* Values for a 6-letter string box: */
  167. SHORT points6s[]={-7,-4,  57,-4,  57,10,  -7,10,  -7,-4};
  168.  
  169. /* A border for a 6-letter string box: */
  170. struct Border border_text6s={0,0,1,2,JAM1,5,points6s,NULL};
  171.  
  172. struct IntuiText text_extension={1,2,JAM1,-36,0,NULL,"Ext",NULL};
  173.  
  174. struct StringInfo string_extension={extension_name,name_backup,0,7,0,
  175.   0,0,0,NULL,NULL,NULL,};
  176.  
  177. struct Gadget gadget_extension={&gadget_file,253,17,59,8,GADGHCOMP,
  178.   RELVERIFY,STRGADGET,(APTR) &border_text6s,NULL,&text_extension,
  179.   NULL,(APTR) &string_extension,NULL,NULL};
  180.  
  181. /* ********************************************************************* */
  182. /* * Information for the boolean gadget parent "<"                     * */
  183.  
  184. /* Values for a 1-letter box: */
  185. SHORT points1[]={0,0,  20,0,  20,15,   0,15,   0,0};
  186.  
  187. /* A border for a 1-letter box: */
  188. struct Border border_text1={0,0,1,2,JAM1,5,points1,NULL};
  189.  
  190. struct IntuiText text_parent={1,2,JAM1,7,4,NULL,"<",NULL};
  191.  
  192. struct Gadget gadget_parent={&gadget_extension,290,31,21,16,GADGHCOMP,
  193.   RELVERIFY,BOOLGADGET,(APTR) &border_text1,NULL,&text_parent,
  194.   NULL,NULL,NULL,NULL};
  195.  
  196. /* ********************************************************************* */
  197. /* * Information for the boolean gadget "ram:"                         * */
  198.  
  199. struct IntuiText text_ram={1,2,JAM1,7,4,NULL,"ram:",NULL};
  200.  
  201. struct Gadget gadget_ram={&gadget_parent,161,13,45,15,GADGHCOMP,
  202.   RELVERIFY,BOOLGADGET,(APTR) &border_text4,NULL,&text_ram,
  203.   NULL,NULL,NULL,NULL};
  204.  
  205. /* ********************************************************************* */
  206. /* * Information for the boolean gadget "dh0:"                         * */
  207.  
  208. struct IntuiText text_dh0={1,2,JAM1,7,4,NULL,"dh0:",NULL};
  209.  
  210. struct Gadget gadget_dh0={&gadget_ram,110,13,45,15,GADGHCOMP,
  211.   RELVERIFY,BOOLGADGET,(APTR) &border_text4,NULL,&text_dh0,
  212.   NULL,NULL,NULL,NULL};
  213.  
  214. /* ********************************************************************* */
  215. /* * Information for the boolean gadget "df1:"                         * */
  216.  
  217. struct IntuiText text_df1={1,2,JAM1,7,4,NULL,"df1:",NULL};
  218.  
  219. struct Gadget gadget_df1={&gadget_dh0,59,13,45,15,GADGHCOMP,
  220.   RELVERIFY,BOOLGADGET,(APTR) &border_text4,NULL,&text_df1,
  221.   NULL,NULL,NULL,NULL};
  222.  
  223. /* ********************************************************************* */
  224. /* * Information for the boolean gadget "df0:"                         * */
  225.  
  226. struct IntuiText text_df0={1,2,JAM1,7,4,NULL,"df0:",NULL};
  227.  
  228. struct Gadget gadget_df0={&gadget_df1,8,13,45,15,GADGHCOMP,
  229.   RELVERIFY,BOOLGADGET,(APTR) &border_text4,NULL,&text_df0,
  230.   NULL,NULL,NULL,NULL};
  231.  
  232. /* ********************************************************************* */
  233. /* * Information for the boolean gadget "CANCEL"                       * */
  234.  
  235. struct IntuiText text_cancel={1,2,JAM1,7,4,NULL,"CANCEL",NULL};
  236.  
  237. struct Gadget gadget_cancel={&gadget_df0,177,144,61,15,GADGHCOMP,
  238.   RELVERIFY,BOOLGADGET,(APTR) &border_text6,NULL,&text_cancel,
  239.   NULL,NULL,NULL,NULL};
  240.  
  241. /* ********************************************************************* */
  242. /* * Information for the boolean gadget "SAVE"                         * */
  243.  
  244. struct IntuiText text_save={1,2,JAM1,7,4,NULL,"SAVE",NULL};
  245.  
  246. struct Gadget gadget_save={&gadget_cancel,59,144,45,15,GADGHCOMP,
  247.   RELVERIFY,BOOLGADGET,(APTR) &border_text4,NULL,&text_save,
  248.   NULL,NULL,NULL,NULL};
  249.  
  250. /* ********************************************************************* */
  251. /* * Information for the boolean gadget "LOAD"                         * */
  252.  
  253. struct IntuiText text_load={1,2,JAM1,7,4,NULL,"LOAD",NULL};
  254.  
  255. struct Gadget gadget_load={&gadget_cancel,8,144,45,15,GADGHCOMP,
  256.   RELVERIFY,BOOLGADGET,(APTR) &border_text4,NULL,&text_load,
  257.   NULL,NULL,NULL,NULL};
  258.  
  259. UBYTE display_text[8][34];
  260.  
  261. struct IntuiText text_list[8]=
  262. {
  263.   {1,0,JAM2,0,0,NULL,display_text[0],&text_list[1]},
  264.   {1,0,JAM2,0,8,NULL,display_text[1],&text_list[2]},
  265.   {1,0,JAM2,0,16,NULL,display_text[2],&text_list[3]},
  266.   {1,0,JAM2,0,24,NULL,display_text[3],&text_list[4]},
  267.   {1,0,JAM2,0,32,NULL,display_text[4],&text_list[5]},
  268.   {1,0,JAM2,0,40,NULL,display_text[5],&text_list[6]},
  269.   {1,0,JAM2,0,48,NULL,display_text[6],&text_list[7]},
  270.   {1,0,JAM2,0,56,NULL,display_text[7],NULL}
  271. };
  272.  
  273. struct Gadget gadget_display[8]=
  274. {
  275.   {&gadget_display[1],8,50,276,12,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,
  276.     NULL,NULL,NULL,NULL,NULL,NULL,NULL},
  277.   {&gadget_display[2],8,62,276,8,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,
  278.     NULL,NULL,NULL,NULL,NULL,NULL,NULL},
  279.   {&gadget_display[3],8,70,276,8,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,
  280.     NULL,NULL,NULL,NULL,NULL,NULL,NULL},
  281.   {&gadget_display[4],8,78,276,8,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,
  282.     NULL,NULL,NULL,NULL,NULL,NULL,NULL},
  283.   {&gadget_display[5],8,86,276,8,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,
  284.     NULL,NULL,NULL,NULL,NULL,NULL,NULL},
  285.   {&gadget_display[6],8,94,276,8,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,
  286.     NULL,NULL,NULL,NULL,NULL,NULL,NULL},
  287.   {&gadget_display[7],8,102,276,8,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,
  288.     NULL,NULL,NULL,NULL,NULL,NULL,NULL},
  289.   {&gadget_load,8,110,276,12,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,
  290.     NULL,NULL,NULL,NULL,NULL,NULL,NULL}
  291. };
  292.  
  293. /* ********************************************************************* */
  294. /* * BIG BOX                                                           * */
  295.  
  296. /* Values for a big box: */
  297. SHORT points_big_box[]={8,50, 283,50, 283,121,   8,121,   8,50};
  298.  
  299. /* A border for a 1-letter box: */
  300. struct Border border_big_box={0,0,1,2,JAM1,5,points_big_box,NULL};
  301.  
  302. /* ********************************************************************* */
  303. /* * Information for the window                                          */
  304.  
  305. struct NewWindow new_file_window={0,0,320,163,0,1,
  306.   CLOSEWINDOW|  GADGETDOWN|  MOUSEMOVE|  GADGETUP,
  307.   ACTIVATE|  WINDOWDEPTH|  WINDOWDRAG|  WINDOWCLOSE|  SMART_REFRESH,
  308.   &gadget_display[0],NULL,NULL,NULL,NULL,0,0,0,0,WBENCHSCREEN};
  309.  
  310.  
  311. /* ********************************************************************* */
  312. /*     Entry Point -- FileWindow()  */
  313. /* ********************************************************************* */
  314.  
  315. USHORT FileWindow( total_file_name )
  316. STRPTR total_file_name;
  317. {
  318. STRPTR extension = "";
  319. SHORT  x=0,y=0;
  320.   int temp1; /* Variable used for loops etc. */
  321.   int file_count; /* How many files/directories there are. */
  322.  
  323.   ULONG class;  /* Saved IntuiMessage: IDCMP flags. */
  324.   USHORT code;  /*        -"-        : Special code. */
  325.   APTR address; /*        -"-        : The address of the object. */
  326.  
  327.   int position; /* The number of the first file in the display. */
  328.  
  329.   BOOL working;     /* Wants the user to quit? */
  330.   BOOL fix_display; /* Should we update the file-display? */
  331.  
  332.   STRPTR string_pointer; /* Pointer to a string. */
  333.   struct file_info *pointer; /* Pointer to a file_info structure. */
  334.  
  335.   USHORT operation; /* What operation FileWindow will return. */
  336.  
  337.     /* Scale invokes FileWindow for either Load or Save. */
  338.     /* Show either the Load gadget or the Save gadget. */
  339.     if (item == &mitem2)
  340.         gadget_display[7].NextGadget = &gadget_load;
  341.     else
  342.         gadget_display[7].NextGadget = &gadget_save;
  343.  
  344.   file_lock=FALSE; /* We have not locked any file/directory. */
  345.   more_files=FALSE; /* Do not list any files yet. */
  346.  
  347.   /* Make sure the proportional gadget is at the top, showing 100%: */
  348.   prop_info.VertBody=0xFFFF;
  349.   prop_info.HorizBody=0;
  350.   prop_info.VertPot=0;
  351.   prop_info.HorizPot=0;
  352.  
  353.   /* Copy the extension into the string gadget: */
  354.   strcpy(extension_name, extension);
  355.  
  356.   /* If there is an extension, the text "Ext:" will be highlighted: */
  357.   if(*extension_name != '\0')
  358.     text_extension.FrontPen=3; /* Orange. (Normal WB colour) */
  359.   else
  360.     text_extension.FrontPen=1; /* White. (Normal WB colour) */
  361.  
  362.   /* Change some values in the new_file_window structure: */
  363.   new_file_window.LeftEdge=x;
  364.   new_file_window.TopEdge=y;
  365.   new_file_window.Title= "SCALE FileWindow";
  366.  
  367.   /* Open the window: */
  368.   if( (file_window = (struct Window *) OpenWindow(&new_file_window)) == NULL )
  369.   {
  370.     /* We could NOT open the window! */
  371.     return(PANIC1);
  372.   }
  373.  
  374.   /* Draw the big box around the display: */
  375.   DrawBorder(file_window->RPort, &border_big_box, 0, 0);
  376.  
  377.   /* Allocate memory for the FileInfoBlock: */
  378.   if((file_info=(struct FileInfoBlock *)
  379.     AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  380.   {
  381.     /* Could not allocate memory for the FileInfoBlock! */
  382.     /* Inform the user about the problem, and leave. */
  383.     request_ok("NOT enough memory!");
  384.     return(PANIC2);
  385.   }
  386.  
  387.   /* Is the there anything in the total_file_name string? */
  388.   if(*total_file_name != '\0')
  389.   {
  390.     /* Yes! */
  391.     /* Try to "lock" the file/directory: */
  392.     if((lock=Lock(total_file_name, ACCESS_READ))==NULL)
  393.     {
  394.       /* PROBLEMS! */
  395.       /* File/directory/device did NOT exist! */
  396.     }
  397.     else
  398.     {
  399.       /* Could lock the file/directory! */
  400.       file_lock=TRUE;
  401.   
  402.       /* Get some information of the file/directory: */
  403.       if((Examine(lock, file_info))==NULL)
  404.       {
  405.         /* Could NOT examine the object! */
  406.         request_ok("ERROR reading file/directory!");
  407.       }
  408.       else
  409.       {
  410.         /* Is it a directory or a file? */
  411.         if(directory(file_info))
  412.         {
  413.           /* It is a directory! */
  414.           *file_name='\0'; /* Clear file_name string. */
  415.           /* Copy total_file_name into drawer_name string: */
  416.           strcpy(drawer_name, total_file_name);
  417.  
  418.           /* Since it is a directory, we will look for more files: */
  419.           more_files=TRUE;
  420.         }
  421.         else
  422.         {
  423.           /* It is a file! */
  424.           
  425.           /* Separate the file name from the path: */
  426.           if(string_pointer=right_pos(total_file_name, '/'))
  427.           {
  428.             /* Copy the file name into file_name string: */
  429.             strcpy(file_name, string_pointer+1);
  430.             *string_pointer='\0';
  431.           }
  432.           else
  433.           {
  434.             if(string_pointer=right_pos(total_file_name, ':'))
  435.             {
  436.               /* Copy the file name into file_name string: */
  437.               strcpy(file_name, string_pointer+1);
  438.               *(string_pointer+1)='\0';
  439.             }
  440.             else
  441.             {
  442.               strcpy(file_name, total_file_name);        
  443.               *drawer_name='\0';
  444.               *total_file_name='\0';
  445.             }
  446.           }
  447.           strcpy(drawer_name, total_file_name);
  448.  
  449.           /* Since it is a file, we will NOT look for more files: */
  450.           /* However, more_files is already FALSE. */
  451.  
  452.         } /* Is it a directory? */
  453.       } /* Could we examine the object? */
  454.     } /* Could we "lock" the file/directory? */
  455.   } /* Anything in the total_file_name string? */
  456.  
  457.  
  458.   /* Since we have messed around with the string gadgets it is best */
  459.   /* to adjust them so the user can see them clearly:               */
  460.   adjust_string_gadgets();
  461.  
  462.   new_drawer(); /* Start to show us the files. */
  463.  
  464.   position=0;        /* The display will show the first file. */
  465.   fix_display=FALSE; /* We do not need to fix the display. */
  466.   first_file=TRUE;   /* No files saved. */
  467.   file_count=0;      /* No files saved. */
  468.  
  469.   working=TRUE;
  470.   do
  471.   {
  472.     /* If we have shown all files in the directory, we put our task */
  473.     /* to sleep. That will speed up other programs, and we will not */
  474.     /* use unnecessary processing time:                             */
  475.     if(more_files==FALSE)
  476.       Wait(1 << file_window->UserPort->mp_SigBit);
  477.  
  478.  
  479.     /* Has something has happened with the gadgets in the file_window? */
  480.     while(my_gadget_message = (struct IntuiMessage *)
  481.       GetMsg(file_window->UserPort))
  482.     {
  483.       /* As long as something is happening with the gadgets we will     */
  484.       /* stay in the while loop. This is very handy since we can        */
  485.       /* recieve hundereds of messages if the mouse is moving, and      */
  486.       /* we only want to update the display when the mouse has stopped: */
  487.       
  488.       /* Collect some interesting values: */
  489.       class = my_gadget_message->Class;
  490.       code = my_gadget_message->Code;
  491.       address = my_gadget_message->IAddress;
  492.  
  493.       /* We have now saved some important values, and can now reply: */
  494.       /* (Do NEVER try to get some values after you have replied!)   */
  495.       ReplyMsg((struct Message *)my_gadget_message);
  496.  
  497.       /* What has actually happened? */
  498.       switch(class)
  499.       {
  500.         case MOUSEMOVE:
  501.           /* The proportional gadget is selected, and the mouse is  */ 
  502.           /* moving; we must update the file_display when the mouse */
  503.           /* has stopped: */
  504.           fix_display=TRUE;
  505.           break;
  506.  
  507.         case CLOSEWINDOW:
  508.           /* The user wants to quit. */
  509.           connect_dir_file(total_file_name);
  510.           working=FALSE;
  511.           operation=QUIT;
  512.           break;
  513.  
  514.         case GADGETDOWN:
  515.            /* A gadget has been pressed down. */
  516.            /* Which gadget has been clicked on? */
  517.            
  518.            /* DISPLAY */
  519.            /* Is the user clicking inside the file display? */
  520.            for(temp1=0; temp1 < 8; temp1++)
  521.            {
  522.              if(address == (APTR)&gadget_display[temp1])
  523.              {
  524.                /* The user wants to select a file/directory: */
  525.                pick_file(temp1+position);
  526.              }
  527.            }
  528.            break;
  529.  
  530.         case GADGETUP:
  531.            /* A gadget has been released. */
  532.            /* Which gadget has been clicked on? */
  533.            if(address == (APTR)&gadget_load)  /* LOAD */
  534.            {
  535.              if(last_check(total_file_name))
  536.              {
  537.                working=FALSE;
  538.                operation=LOAD;
  539.              }
  540.              break;
  541.            }
  542.            if(address == (APTR)&gadget_save)  /* SAVE */
  543.            {
  544.              if(last_check(total_file_name))
  545.              {
  546.                working=FALSE;
  547.                operation=SAVE;
  548.              }
  549.              break;
  550.            }
  551.            if(address == (APTR)&gadget_cancel)  /* CANCEL */
  552.            {
  553.              connect_dir_file(total_file_name);
  554.              working=FALSE;
  555.              operation=CANCEL;
  556.              break;
  557.            }
  558.            if(address == (APTR)&gadget_df0)  /* df0: */
  559.            {
  560.              change_device("df0:");
  561.              break;
  562.            }
  563.            if(address == (APTR)&gadget_df1)  /* df1: */
  564.            {
  565.              change_device("df1:");
  566.              break;
  567.            }
  568.            if(address == (APTR)&gadget_dh0)  /* dh0: */
  569.            {
  570.              change_device("dh0:");
  571.              break;
  572.            }
  573.            if(address == (APTR)&gadget_ram)  /* ram: */
  574.            {
  575.              change_device("ram:");
  576.              break;
  577.            }
  578.            if(address == (APTR)&gadget_drawer)  /* DRAWER */
  579.            {
  580.              /* The user has entered something new in the drawer: */
  581.              new_drawer();
  582.              break;
  583.            }
  584.            if(address == (APTR)&gadget_extension)  /* EXTENSION */
  585.            {
  586.              /* If there is an extension, the text "Ext:" will be */
  587.              /* highlighted: */
  588.              if(*extension_name != '\0')
  589.                text_extension.FrontPen=3; /* Orange. (Normal WB colour) */
  590.              else
  591.                text_extension.FrontPen=1; /* White. (Normal WB colour) */
  592.  
  593.              /* Show the user the colour change: */
  594.              RefreshGadgets(&gadget_extension, file_window, NULL);
  595.  
  596.              /* Start again to diplay the files, using a new extension. */
  597.              new_drawer();
  598.              break;
  599.            }
  600.            if(address == (APTR)&gadget_parent)  /* PARENT "<" */
  601.            {
  602.              parent();
  603.              break;
  604.            }
  605.            if(address == (APTR)&gadget_proportional)  /* PROPORTIONAL */
  606.            {
  607.              /* The user has released the proprtional gadget, update */
  608.              /* the display: */
  609.              fix_display=TRUE;
  610.              break;
  611.            }
  612.       }
  613.     }
  614.  
  615.     /* Do we need to update the file display? */
  616.     if(fix_display)
  617.     {
  618.       fix_display=FALSE;
  619.  
  620.       /* Which file should we start to show in the display? */
  621.       if(file_count > 8)
  622.         position=(int) prop_info.VertPot/(float) 0xFFFF*(file_count-8);
  623.       else
  624.         position=0;
  625.  
  626.       /* List the files: (Starting with position) */
  627.       display_list(position);
  628.     }
  629.  
  630.     if(more_files)
  631.     {
  632.       /* Are there more files/dirtectories left to be collected? */    
  633.       if(ExNext(lock, file_info))
  634.       {
  635.         /* List the file/directory if it is: */
  636.         /* 1. A file which has the right extension. */
  637.         /* 2. A directory. */
  638.         if(stricmp(extension_name, (file_info->fib_FileName+
  639.            strlen(file_info->fib_FileName)-strlen(extension_name)))==0 ||
  640.            directory(file_info) )
  641.         {
  642.           /* Is this the first file/directory? */
  643.           if(first_file)
  644.           {
  645.             /* first_pointer will point at the first file in our list: */
  646.             first_pointer=(struct file_info *) save_file_info(file_info);
  647.             
  648.             if(first_pointer != NULL)
  649.             {
  650.               /* There are no more elements (for the moment) in our list: */ 
  651.               first_pointer->next=NULL; 
  652.               first_file=FALSE;
  653.             }
  654.             file_count=1;
  655.             position=1;
  656.           }
  657.           else
  658.           {
  659.             /* save_file_info will return a pointer to the allocated */
  660.             /* structure: */
  661.             pointer=(struct file_info *) save_file_info(file_info);
  662.             
  663.             /* If we have been able to allocate space for the file we */
  664.             /* put it into our list: */
  665.             if(pointer !=NULL)
  666.             {
  667.               /* Put the new structure into the list: */
  668.               put_in(first_pointer, pointer);       
  669.               file_count++;
  670.             }
  671.           }
  672.         
  673.           /* If tehre are more than eight files/directories we modify */
  674.           /* the proportional gadget: */
  675.           if(file_count > 8)
  676.           {
  677.             ModifyProp
  678.             (&gadget_proportional,file_window,NULL,prop_info.Flags,
  679.               0,prop_info.VertPot,0,(ULONG) 0xFFFF*8/file_count
  680.             );            
  681.             position=(int) prop_info.VertPot/(float) 0xFFFF*(file_count-8);
  682.           }
  683.           else
  684.            position=0;
  685.  
  686.           /* List all the files: */
  687.           display_list(position);
  688.         }
  689.       }
  690.       else
  691.       {
  692.         /* ExNext() failed: */
  693.         
  694.         more_files=FALSE; /* Do not try to list any more files. */
  695.  
  696.         /* Check what went wrong: */
  697.         /* If the error message is NOT "ERROR_NO_MORE_ENTRIES" something */
  698.         /* went terrible wrong while reading: */
  699.         if(IoErr() != ERROR_NO_MORE_ENTRIES)
  700.         {
  701.           request_ok("ERROR reading file/directory!");
  702.         }
  703.       }
  704.     }
  705.   } while(working);
  706.  
  707.   /* Clean up and leave: */
  708.  
  709.   /* This will clear the IDCMP port: */
  710.   while( (my_gadget_message = (struct IntuiMessage *)
  711.            GetMsg(file_window->UserPort)) )
  712.   {
  713.     ReplyMsg((struct Message *)my_gadget_message);
  714.   }
  715.  
  716.   /* Deallocate the memory we have dynamically allocated: */ 
  717.   deallocate_file_info();
  718.  
  719.   /* If we have "locked" a file/directory, "unlock" it: */
  720.   if(file_lock)
  721.   {
  722.     UnLock(lock);
  723.     file_lock=FALSE;
  724.   }
  725.   
  726.   /* Deallocate FileInfoBlock: */
  727.   if(file_info) FreeMem(file_info, sizeof(struct FileInfoBlock));
  728.  
  729.   /* If we have successfully opened the file_window, we close it: */
  730.   if(file_window)
  731.     CloseWindow(file_window);
  732.   
  733.   /* Leave with a message: */
  734.   return(operation);
  735. }
  736.  
  737. /* Deallocate the memory we have dynamically allocated: */ 
  738. void deallocate_file_info()
  739. {
  740.   struct file_info *pointer, *temp_pointer;
  741.  
  742.   /* Does the first pointer point to an allocated structure? */   
  743.   if(first_pointer)
  744.   {
  745.     /* Save the address of the next structure: */
  746.     pointer=first_pointer->next;
  747.     
  748.     /* Deallocate the first structure: */
  749.     FreeMem( first_pointer, sizeof(struct file_info));
  750.  
  751.     /* As long as pointer points to an allocated structure: */
  752.     while(pointer)
  753.     {
  754.       /* Save the address of the next structure: */    
  755.       temp_pointer=pointer->next;
  756.       
  757.       FreeMem( pointer, sizeof(struct file_info));
  758.       pointer=temp_pointer;
  759.     }
  760.   }
  761.   
  762.   /* Clear first_pointer: */
  763.   first_pointer=NULL;
  764.  
  765.   /* Next time we try to list the files, we start with the first_file: */
  766.   first_file=TRUE;
  767. }
  768.  
  769. /* Allocate memory for the new file/directory, and fills the structure */
  770. /* with information. (name of the object, and if it is a directory.)   */
  771. /* Returns a memory pointer to the allocated structure, or NULL.       */
  772. APTR save_file_info(info)
  773. struct FileInfoBlock *info;
  774. {
  775.   struct file_info *pointer;
  776.  
  777.   if((pointer=(struct file_info *)
  778.     AllocMem(sizeof(struct file_info), MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  779.   {
  780.     /* We could NOT allocate memory for the structure! */
  781.     request_ok("NOT enough memory!"); /* Inform the user. */
  782.     more_files=FALSE; /* Do not list any more files/directories. */
  783.     return(NULL);
  784.   }
  785.   else
  786.   {
  787.     /* If the file/directory name is not too long, we copy it into the */
  788.     /* new stucture: */
  789.     if(strlen(info->fib_FileName) < 28)
  790.       strcpy(pointer->name, info->fib_FileName);
  791.     else
  792.     {
  793.       /* The file/directory name is too long! */
  794.       /* Inform the user: */
  795.       
  796.       if( directory(info))
  797.         request_ok("Directory name too long!"); /* It is a directory. */
  798.       else    
  799.         request_ok("File name too long!"); /* It is a file. */
  800.  
  801.       /* Deallocate the structure: */
  802.       FreeMem( pointer, sizeof(struct file_info));
  803.       return(NULL);
  804.     }
  805.  
  806.     /* Is it a file or a directory? */
  807.     if( directory(info))
  808.       pointer->directory=TRUE; /* It is a directory. */
  809.     else    
  810.       pointer->directory=FALSE; /* It is a file. */
  811.   }
  812.   
  813.   /* Return the address of the allocated structure: */
  814.   return( (APTR) pointer);
  815. }
  816.  
  817.  
  818.  
  819. /* Will check a FileInfoBlock if it is a file or a directory. */
  820. /* Return TRUE if it is a directory, FALSE if it is a file.   */
  821. BOOL directory(info)
  822. struct FileInfoBlock *info;
  823. {
  824.   if(info->fib_DirEntryType < 0)
  825.     return(FALSE);
  826.   else
  827.     return(TRUE);
  828. }
  829.  
  830. /* Put the new structure into the dynamically allocated list at the */
  831. /* right place (sorted alphabetically, directories first):          */
  832. void put_in(a_pointer, pointer)
  833. struct file_info *a_pointer, *pointer;
  834. {
  835.   struct file_info *old_pointer=NULL;
  836.  
  837.   /* Move slowly down the list and try to fit in the structure: */
  838.   while( a_pointer && file_comp(a_pointer->name, pointer->name) )
  839.   {
  840.     old_pointer=a_pointer;
  841.     a_pointer=a_pointer->next;
  842.   }
  843.  
  844.   if(a_pointer)
  845.   {
  846.     if(old_pointer)
  847.     {
  848.       /* Put the structure into the list: */
  849.       pointer->next=old_pointer->next;
  850.       old_pointer->next=pointer;
  851.     }
  852.     else
  853.     {
  854.       /* First in the list! */
  855.       pointer->next=first_pointer;
  856.       first_pointer=pointer;
  857.     }
  858.   }
  859.   else
  860.   {
  861.     /* Last int the list: */
  862.     old_pointer->next=pointer;
  863.     pointer->next=NULL;
  864.   }
  865. }
  866.  
  867. /* This function will return TRUE if the first pointer (a_pointer) */
  868. /* points to a file structure which should come before the second  */
  869. /* pointers file structure.                                        */
  870. /* ORDER: */
  871. /* 1. DIRECTORIES sorted alphabetically. */
  872. /* 2. FILES       sorted alphabetically. */
  873.  
  874. BOOL file_comp(a_pointer, pointer)
  875. struct file_info *a_pointer, *pointer;
  876. {
  877.   if(a_pointer->directory == FALSE && pointer->directory)
  878.     return(FALSE);
  879.     
  880.   if(a_pointer->directory == pointer->directory)
  881.   {
  882.     if(stricmp(a_pointer->name, pointer->name) <= 0 )
  883.       return(TRUE);
  884.     else
  885.       return(FALSE);
  886.   } 
  887.   return(TRUE);
  888. }
  889.  
  890. /* Give this function a string and a character, and it will return a */
  891. /* pointer to the right most occurance character in you string which */
  892. /* match your character.                                             */
  893. STRPTR right_pos(string, sign)
  894. STRPTR string;
  895. char sign;
  896. {
  897.   STRPTR start_pos;
  898.   
  899.   start_pos=string;
  900.   
  901.   /* Go to the end: */
  902.   while(*string != '\0')
  903.     string++;
  904.  
  905.   /* Start to go backwards and check teh string: */
  906.   while(*string != sign && string > start_pos)
  907.     string--;
  908.     
  909.   if(*string==sign)
  910.     return(string); /* We have found a matching character. */
  911.  
  912.   return(NULL); /* We could not find a matching character. */
  913. }
  914.  
  915. /* This function will change to a new device, for example df0:. */
  916. /* Does not return anything.                                    */
  917. void change_device(device)
  918. STRPTR device;
  919. {
  920.   strcpy(drawer_name, device); /* Change the drawer string. */
  921.  
  922.   adjust_string_gadgets(); /* Adjust the string gadgets. */
  923.  
  924.   new_drawer(); /* Start to show us the new files/directories */
  925. }
  926.  
  927. /* When the user or the program has changet the drawer string, this      */
  928. /* function is called, and will do what is necessary to start to collect */
  929. /* the new files/directories from the disk.                              */
  930. /* Returns TRUE if everything is OK, and FALSE if something went wrong.  */
  931. BOOL new_drawer()
  932. {
  933.   STRPTR string_pointer;
  934.  
  935.   /* Unlock: */
  936.   if(file_lock)
  937.   {
  938.     UnLock(lock);
  939.     file_lock=FALSE;
  940.   }
  941.  
  942.   /* Deallocate the memory we have dynamically allocated: */ 
  943.   deallocate_file_info();
  944.  
  945.   /* Change the proportianal gadget: */
  946.   ModifyProp
  947.   (&gadget_proportional,file_window,NULL,prop_info.Flags,
  948.     0,0,0,(ULONG) 0xFFFF
  949.   );
  950.  
  951.   /* Clear the display: */
  952.   display_list(0);
  953.  
  954.   more_files=FALSE;
  955.  
  956.   /* Try to "lock" the file/directory: */
  957.   if((lock=Lock(drawer_name, ACCESS_READ))==NULL)
  958.   {
  959.     /* We could NOT lock the file/directory/device! */
  960.     /* Inform the user: */
  961.     string_pointer=drawer_name+strlen(drawer_name)-1;
  962.     if(*string_pointer==':')
  963.       request_ok("Device NOT found!");
  964.     else
  965.       request_ok("Device/Directory NOT found!");
  966.  
  967.     return(FALSE); /* ERROR */
  968.   }
  969.   else
  970.   {
  971.     /* We "locked" the file/directory! */
  972.     file_lock=TRUE;
  973.   }
  974.  
  975.   /* Now try to get some information from the file/directory: */
  976.   if((Examine(lock, file_info))==NULL)
  977.   {
  978.     /* We could NOT examine the file/directory! */
  979.  
  980.     request_ok("ERROR reading file/directory!"); /* Inform the user. */
  981.  
  982.     return(FALSE); /* ERROR */
  983.   }
  984.  
  985.   /* Is it a directory or a file? */
  986.   if(directory(file_info))
  987.   {
  988.     /* It is a directory! */
  989.  
  990.     /* Since it is a directory, we will look for more files: */
  991.     more_files=TRUE;
  992.   }
  993.   else
  994.   {
  995.     /* It is a file! */
  996.     request_ok("NOT a valid directory name!"); /* Inform the user. */
  997.     return(FALSE);
  998.   }  
  999.   return(TRUE);
  1000. }
  1001.  
  1002. /* The function parent() will try to go backwards one step in the */
  1003. /* directory path.                                                */
  1004. /* Does not return anything.                                      */
  1005. void parent()
  1006. {
  1007.   STRPTR string_pointer;
  1008.  
  1009.   /* Separate the last directory from the path: */
  1010.   if(string_pointer=right_pos(drawer_name, '/'))
  1011.   {
  1012.     /* Take away the last directory: */
  1013.     *string_pointer='\0';
  1014.   }
  1015.   else
  1016.   {
  1017.     if(string_pointer=right_pos(drawer_name, ':'))
  1018.     {
  1019.       /* Take away the last directory: */
  1020.       /* Only the device ("df0:" for example) left: */
  1021.       *(string_pointer+1)='\0';
  1022.     }
  1023.     else
  1024.     {
  1025.       /* Strange drawer_name, clear it: */
  1026.       *drawer_name='\0';
  1027.     }
  1028.   }
  1029.  
  1030.   /* Since we have messed around with the string gadgets, adjust them: */
  1031.   adjust_string_gadgets();
  1032.   
  1033.   /* Start to show the user the files etc in the new directory: */
  1034.   new_drawer();
  1035. }
  1036.  
  1037. /* You give this function a pointer to an error string, and it will open */
  1038. /* a simple requester displaying the message. The requester will go away */
  1039. /* first when the user has selected the button "OK".                     */
  1040. /* Does not return anything.                                             */
  1041. void request_ok(message)
  1042. STRPTR message;
  1043. {
  1044.   text_request.IText=message;
  1045.   
  1046.   AutoRequest
  1047.   (file_window,&text_request,NULL,&ok_request,NULL,NULL,320,72);
  1048. }
  1049.  
  1050. /* This function will also open a simple requester, but will instead      */
  1051. /* ask the user to make a choice between option1 or option2               */
  1052. /* If the user selects option1 the function returns TRUE, else it returns */
  1053. /* FALSE.                                                                 */
  1054. BOOL request_ask(message, option1, option2)
  1055. STRPTR message, option1, option2;
  1056. {
  1057.   text_request.IText=message;
  1058.   option1_request.IText=option1;
  1059.   option2_request.IText=option2;
  1060.   
  1061.   
  1062.   return( (BOOL) AutoRequest
  1063.   (file_window,&text_request,&option1_request,&option2_request,
  1064.     NULL,NULL,320,72
  1065.   ));
  1066. }
  1067.  
  1068. /* This function will display the files etc which are inside the */
  1069. /* directory, starting with the file number start_pos.           */
  1070. /* Does not return anything.                                     */
  1071. void display_list(start_pos)
  1072. int start_pos;
  1073. {
  1074.   struct file_info *pointer;
  1075.   int pos, temp1;
  1076.                   /* 123456789012345678901234567890123 */
  1077.   char empty_name[]="                                 ";
  1078.   STRPTR string_pointer;
  1079.   BOOL clear;
  1080.   
  1081.   pos=0;
  1082.   
  1083.   /* Does it exist any files at all? */
  1084.   if(first_pointer)
  1085.   {
  1086.     pointer=first_pointer;
  1087.  
  1088.     /* Go through the list until you have found the file/directory */
  1089.     /* which should be shown first:                                */
  1090.     while(pointer && pos < start_pos)
  1091.     {
  1092.       pos++;
  1093.       pointer=pointer->next;
  1094.     }
  1095.     
  1096.     /* Try to show the eight files: */
  1097.     pos=0;
  1098.     while(pointer && pos < 8)
  1099.     {
  1100.       strcpy(display_text[pos], pointer->name);
  1101.       
  1102.       clear=FALSE;
  1103.       temp1=0;
  1104.       string_pointer=display_text[pos];
  1105.  
  1106.       if(pointer->directory)
  1107.       {
  1108.         /* It is a directory: */
  1109.         text_list[pos].FrontPen=3; /* Highlight it. */
  1110.  
  1111.         /* Clear everything after the name, and add the string "(Dir)". */
  1112.         while(temp1 < 28)
  1113.         {
  1114.           if(*string_pointer=='\0')
  1115.             clear=TRUE;
  1116.           if(clear)
  1117.             *string_pointer=' ';
  1118.           string_pointer++;
  1119.           temp1++;
  1120.         }
  1121.         *string_pointer='\0';
  1122.         strcat(display_text[pos], "(Dir)");
  1123.       }
  1124.       else
  1125.       {
  1126.         /* It is a file: */
  1127.         text_list[pos].FrontPen=1; /* Normal colour. */
  1128.  
  1129.         /* Clear everything after the name: */
  1130.         while(temp1 < 33)
  1131.         {
  1132.           if(*string_pointer=='\0')
  1133.             clear=TRUE;
  1134.           if(clear)
  1135.             *string_pointer=' ';
  1136.           string_pointer++;
  1137.           temp1++;
  1138.         }
  1139.         *string_pointer='\0';
  1140.       }      
  1141.       pos++;
  1142.       pointer=pointer->next; /* Next. */
  1143.     }
  1144.   }
  1145.  
  1146.   /* If there are less than eight files, show clear the rest of the */
  1147.   /* display: */
  1148.   while(pos < 8)
  1149.   {
  1150.     strcpy(display_text[pos], empty_name);
  1151.     pos++;
  1152.   }
  1153.   
  1154.   /* Show the user the new display: */
  1155.   PrintIText(file_window->RPort, text_list, 13+3, 53+1);
  1156. }
  1157.  
  1158. /* The user has selected a file or a directory. If it is a file put it */
  1159. /* into the file string, otherwise put it into the drawer string.      */
  1160. /* Returns TRUE if everything went OK, FALSE if there was a problem.   */
  1161. BOOL pick_file(file_pos)
  1162. int file_pos;
  1163. {
  1164.   struct file_info *pointer=NULL;
  1165.   STRPTR string_pointer;
  1166.   int pos=0;
  1167.   
  1168.   /* Go through the allocated list untill we find the file/directory: */
  1169.   if(first_pointer)
  1170.   {
  1171.     pointer=first_pointer;
  1172.     
  1173.     while(pointer && pos < file_pos)
  1174.     {
  1175.       pos++;
  1176.       pointer=pointer->next;
  1177.     }
  1178.   }
  1179.  
  1180.   /* Have we found the file/directory? */
  1181.   if(pointer)
  1182.   {
  1183.     if(pointer->directory)
  1184.     {
  1185.       /* It is a directory! */
  1186.       
  1187.       /* Is the drawer_name string long enough? */
  1188.       /* (+2: 1 for the NULL ('\0') character, 1 for the '\' character) */
  1189.       if((strlen(pointer->name)+strlen(drawer_name)+2) <= DRAWER_LENGTH)
  1190.       {
  1191.         /* YES!, there is enough room for it. */
  1192.         string_pointer=drawer_name+strlen(drawer_name)-1;
  1193.         if(*string_pointer==':'  || *string_pointer=='\0' )
  1194.           strcat(drawer_name, pointer->name);
  1195.         else
  1196.         {
  1197.           /* We need to add a '/' before we can add the directory. */
  1198.           strcat(drawer_name, "/");
  1199.           strcat(drawer_name, pointer->name);
  1200.         }
  1201.         
  1202.         /* Adjust the string gadgets: */
  1203.         adjust_string_gadgets();
  1204.       }
  1205.       else
  1206.       {
  1207.         /* The drawer_name is NOT big enough! */
  1208.         request_ok("Too long drawer string"); /* Inform the user. */
  1209.         return(FALSE); /* ERROR */
  1210.       }
  1211.       new_drawer();
  1212.       return(TRUE); /* OK */
  1213.     }
  1214.     else
  1215.     {
  1216.       /* It is a File! */
  1217.       /* Is the file_name string long enough? */
  1218.       /* (+1 for the NULL ('\0') character.) */
  1219.       if((strlen(pointer->name)+1) <= FILE_LENGTH)
  1220.       {
  1221.         strcpy(file_name, pointer->name);
  1222.         adjust_string_gadgets();
  1223.       }
  1224.       else
  1225.       {
  1226.         /* The file_name is NOT big enough! */
  1227.         request_ok("File name too long!"); /* Inform the user. */
  1228.         return(FALSE); /* ERROR */
  1229.       }
  1230.       return(TRUE); /* OK */
  1231.     }
  1232.   }
  1233. }
  1234.  
  1235. /* Adjust the string gadgets, so the user can */
  1236. /* at least see the last 28/22 characters.    */
  1237. /* Does not return anything.                  */
  1238. void adjust_string_gadgets()
  1239. {
  1240.   int length;
  1241.  
  1242.   length=strlen(file_name);        
  1243.  
  1244.   if(length > 28)
  1245.     string_file.DispPos=length-28;
  1246.   else
  1247.     string_file.DispPos=0;
  1248.  
  1249.   string_file.BufferPos=string_file.DispPos;
  1250.   
  1251.   length=strlen(drawer_name);        
  1252.  
  1253.   if(length > 22)
  1254.     string_drawer.DispPos=length-22;
  1255.   else
  1256.     string_drawer.DispPos=0;
  1257.  
  1258.   string_drawer.BufferPos=string_drawer.DispPos;
  1259.  
  1260.   /* Display the changes. */
  1261.   RefreshGadgets(&gadget_file, file_window, NULL);
  1262. }
  1263.  
  1264. /* Returns TRUE if there exist a file name, otherwise FALSE. */
  1265. BOOL last_check(name)
  1266. STRPTR name;
  1267. {
  1268.   if(*file_name == '\0')
  1269.   {
  1270.     /* No file name! */
  1271.     request_ok("NO filename selected!"); /* Inform the user. */
  1272.     return(FALSE);
  1273.   }
  1274.   else
  1275.   {
  1276.     /* Change the total_file_name. Drawer + File. */
  1277.     connect_dir_file(name);
  1278.   }
  1279.   return(TRUE);
  1280. }
  1281.  
  1282. /* This function will connect the drawer string with the file string. */
  1283. /* Does not return anything.                                          */
  1284. void connect_dir_file(name)
  1285. STRPTR name;
  1286. {
  1287.   STRPTR string_pointer;
  1288.        
  1289.   strcpy(name, drawer_name); /* Copy the drawer string into name. */
  1290.  
  1291.   /* Does it exist a file name? */
  1292.   if(*file_name != '\0')
  1293.   {
  1294.     /* Yes! */
  1295.     string_pointer=drawer_name+strlen(drawer_name)-1;
  1296.     if(*string_pointer==':'  || *string_pointer=='\0' )
  1297.     {
  1298.       strcat(name, file_name); /* Add the file name. */
  1299.     }
  1300.     else
  1301.     {
  1302.       strcat(name, "/"); /* Add a '\'. */
  1303.       strcat(name, file_name); /* Add the file name. */
  1304.     }
  1305.   }
  1306. }
  1307.  
  1308. /* End of FileWindow */
  1309.