home *** CD-ROM | disk | FTP | other *** search
/ Point Programming 1 / PPROG1.ISO / c / fli106c / examples / open.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-25  |  13.7 KB  |  611 lines

  1. //
  2. // The Fusion Library Interface for DOS
  3. // Version 1.02
  4. // Copyright (C) 1990, 1991
  5. // Software Dimensions
  6. //
  7. // Dialog Development System
  8. //
  9.  
  10. #include "fliwin.h"
  11. #include "elements.h"
  12. #include "colors.h"
  13. #include "dds.h"
  14.  
  15. #include <dos.h>
  16. #include <time.h>
  17. #include <stddef.h>
  18. #include <string.h>
  19. #include <alloc.h>
  20. #include <stdio.h>
  21. #include <io.h>
  22.  
  23. #include "open.h"
  24.  
  25. #pragma warn -inl
  26.  
  27. const FileSelected=10000;
  28. const FileFromPath=10001;
  29.  
  30. //-------------------------------------------------------------------------
  31. //
  32. // Construct the class that will contain the ChDir event handler
  33. // Destruct class upon exit
  34. //
  35. //-------------------------------------------------------------------------
  36.  
  37. OpenDialog::OpenDialog(char *_Mask) : DialogClass(51,14,"Open a File")
  38. {
  39.  
  40.   Path=new PathStorage();
  41.   File=new FileStorage(_Mask);
  42.  
  43.   strcpy(Value,Path->Path);
  44.   strcat(Value,File->Mask);
  45.  
  46.   FilePathed=new FilePath(6,1,*Path,*File,Value);
  47.   Element(FilePathed);
  48.   Help("Enter the search path and file name (masks permitted)");
  49.   HotKey(1,1,"~Name",kbAltN);
  50.   FusionHelp(10103);
  51.  
  52.   FileLister=new FileList(1,4,*File);
  53.  
  54.   Element(FileLister);
  55.   Help("Select the file to load");
  56.   HotKey(1,3,"~File",kbAltF);
  57.   Available(File->Count);
  58.   FusionHelp(10106);
  59.  
  60.   Element(new ChDirList2(17,4,*Path,*File,*FilePathed));
  61.   Help("Select the directory to traverse to");
  62.   HotKey(17,3,"~Directory",kbAltD);
  63.   Available(Path->Count);
  64.   FusionHelp(10104);
  65.  
  66.   Element(new DirList2(33,4,*Path,*File,*FilePathed));
  67.   Help("Select the drive to jump to");
  68.   HotKey(33,3,"D~rive",kbAltR);
  69.   FusionHelp(10105);
  70.  
  71.   Element(new DiaPushButton(39,5," Open ",ChDirOkayButton,0,1));
  72.   Help("Accept the current drive and directory");
  73.  
  74.   Element(new DiaPushButton(39,7,"~Cancel",ChDirCancelButton,kbAltC));
  75.   Help("Cancel and do not change the drive and directory");
  76.  
  77.   Prompt2 *Prompter=new Prompt2(*Path,*File,*FileLister);
  78.   Element(Prompter);
  79.   FileLister->Prompt=Prompter;
  80.  
  81. }
  82.  
  83. OpenDialog::~OpenDialog()
  84. {
  85.   delete Path;
  86.   delete File;
  87. }
  88.  
  89. //-------------------------------------------------------------------------
  90. //
  91. // Event handler for the ChDir dialog
  92. //
  93. //-------------------------------------------------------------------------
  94.  
  95. int OpenDialog::EventHandler(int Event)
  96. {
  97.   switch(Event)
  98.   {
  99.     case kbCr:
  100.     case ChDirOkayButton:
  101.       return StopEvent;
  102.  
  103.     case ChDirRevertButton:
  104.       setdisk(Path->SaveDisk);
  105.       for (int i=0;i<Path->DriveCount;i++)
  106.         if (*Path->Drives[i]=='A'+Path->SaveDisk)
  107.           Path->CurrentDisk=i;
  108.       strcpy(Path->Path,Path->Revert);
  109.       chdir(Path->Path);
  110.       Path->Refresh();
  111.       return RefreshEvent;
  112.  
  113.     case kbEsc:
  114.     case ChDirCancelButton:
  115.     case CloseEvent:
  116.     case OutsideEvent:
  117.       setdisk(Path->SaveDisk);
  118.       for (i=0;i<Path->DriveCount;i++)
  119.         if (*Path->Drives[i]=='A'+Path->SaveDisk)
  120.           Path->CurrentDisk=i;
  121.       strcpy(Path->Path,Path->Revert);
  122.       chdir(Path->Path);
  123.       return StopEvent;
  124.  
  125.     case FileSelected:
  126.     case FileFromPath:
  127.       return StopEvent;
  128.   }
  129.  
  130.   return CompleteEvent;
  131. }
  132.  
  133. char *OpenDialog::OpenFile()
  134. {
  135.  
  136.   int Returned=UseDialog();
  137.  
  138.   if (Returned==ChDirOkayButton || Returned==FileSelected)
  139.   {
  140.     strcpy(FileCompute,(File->DirEntries+FileLister->Item)->ff_name);
  141.     return FileCompute;
  142.   }
  143.  
  144.   if (Returned==FileFromPath)
  145.   {
  146.     strcpy(FileCompute,FilePathed->Value);
  147.     return FileCompute;
  148.   }
  149.  
  150.   return 0;
  151. }
  152.  
  153. //-------------------------------------------------------------------------
  154. //
  155. // Element that lists the available directories
  156. //
  157. //-------------------------------------------------------------------------
  158.  
  159. int FileList::CurrentItem=0;
  160.  
  161. FileList::FileList(int X,int Y,FileStorage &_File) :
  162.   File(_File),
  163.   DiaStructPickList(X,Y,12,5,CurrentItem,_File.Count,sizeof(ffblk),
  164.   &_File.DirEntries->ff_name)
  165. {
  166.   CurrentItem=0;
  167. }
  168.  
  169. int FileList::EventHandler(int Event)
  170. {
  171.   if (Event==kbCr)
  172.     return FileSelected;
  173.  
  174.   int Hold=Item;
  175.  
  176.   int EventStore=DiaStructPickList::EventHandler(Event);
  177.  
  178.   if (EventStore==StopEvent)
  179.     return FileSelected;
  180.  
  181.   if (Hold!=Item)
  182.     Prompt->Show();
  183.  
  184.   return Event;
  185. }
  186.  
  187. void FileList::Show()
  188. {
  189.   if (!File.Count)
  190.   {
  191.     Item=0;
  192.     ItemAtTopOfList=0;
  193.     ItemCount=0;
  194.   }
  195.   DiaStructPickList::Show();
  196. }
  197.  
  198. //-------------------------------------------------------------------------
  199. //
  200. // Powers up the PathStorage class
  201. //
  202. //-------------------------------------------------------------------------
  203.  
  204. FileStorage::FileStorage(char *_Mask)
  205. {
  206.  
  207.   Count=0;
  208.   strcpy(Mask,_Mask);
  209.  
  210.   DirEntries=new ffblk[MaxEntries];
  211.  
  212.   Refresh();
  213.  
  214. }
  215.  
  216. //-------------------------------------------------------------------------
  217. //
  218. // Refresh the directories when our location switched
  219. //
  220. //-------------------------------------------------------------------------
  221.  
  222. void FileStorage::Refresh()
  223. {
  224.   int Done;
  225.  
  226.   ffblk DummyStorage;
  227.  
  228.   if (Mask)
  229.     Done=findfirst(Mask,&DummyStorage,0);
  230.   else
  231.     Done=findfirst("*.*",&DummyStorage,0);
  232.  
  233.   Count=0;
  234.  
  235.   while (!Done)
  236.   {
  237.     DirEntries[(++Count)-1]=DummyStorage;
  238.     if (Count==MaxEntries-1)
  239.     {
  240.       InfoBox &NotAvailable = *new InfoBox;
  241.       NotAvailable
  242.             + "Internal file storage buffer is exhausted."
  243.             + ""
  244.             + "File listing may be missing some files.";
  245.       NotAvailable.Title("Exhausted");
  246.       NotAvailable.UseInfoBox();
  247.       delete &NotAvailable;
  248.       break;
  249.     }
  250.     Done=findnext(&DummyStorage);
  251.   }
  252. }
  253.  
  254. //-------------------------------------------------------------------------
  255. //
  256. // Destructor that frees up the directory information
  257. //
  258. //-------------------------------------------------------------------------
  259.  
  260. FileStorage::~FileStorage()
  261. {
  262.   if (DirEntries)
  263.     delete DirEntries;
  264. }
  265.  
  266. //-------------------------------------------------------------------------
  267. //
  268. // FilePath element that permits typing of a path
  269. //
  270. //-------------------------------------------------------------------------
  271.  
  272. FilePath::FilePath(int X,int Y,PathStorage &_Path,FileStorage &_File,char *Merge) :
  273.   Path(_Path),
  274.   File(_File),
  275.   DiaChar(X,Y,0,Merge,0,'X',42,1)
  276. {
  277.   Reset=1;
  278.   ComparePathStorage=new char[65];
  279.   strcpy(ComparePathStorage,Path.Path);
  280.   strcat(ComparePathStorage,File.Mask);
  281.   strcpy(GetMask,File.Mask);
  282. }
  283.  
  284. FilePath::~FilePath()
  285. {
  286.   delete ComparePathStorage;
  287. }
  288.  
  289. int FilePath::Departure()
  290. {
  291.   strcpy(Value,Path.Path);
  292.   strcat(Value,File.Mask);
  293.  
  294.   return RefreshEvent;
  295. }
  296.  
  297. int FilePath::EventHandler(int Event)
  298. {
  299.   if (Event==kbCr)
  300.   {
  301.     if (strcmp(Value,ComparePathStorage))
  302.     {
  303.       Reset=1;
  304.  
  305.       char Drive[MAXDRIVE];
  306.       char Dir[MAXDIR];
  307.       char File[MAXFILE];
  308.       char Ext[MAXEXT];
  309.  
  310.       // See if changing directory
  311.  
  312.       int Flags=fnsplit(Value,Drive,Dir,File,Ext);
  313.  
  314.       if (Flags&DRIVE)
  315.       {
  316.         setdisk(Drive[0]-'A');
  317.  
  318.         for (int i=0;i<Path.DriveCount;i++)
  319.         {
  320.           if (*(Path.Drives[i]+0)==Drive[0])
  321.           {
  322.             Path.CurrentDisk=i;
  323.             break;
  324.           }
  325.         }
  326.       }
  327.  
  328.       if (Flags&DIRECTORY || Flags&FILENAME)
  329.       {
  330.         char Value[MAXPATH];
  331.  
  332.         if (Flags&WILDCARDS && Flags&DIRECTORY)
  333.         {
  334.           strcpy(Value,Dir);
  335.           if (Value[strlen(Value)-1]=='\\' && strlen(Value)!=1)
  336.             Value[strlen(Value)-1]=0;
  337.         }
  338.         else if (Flags&DIRECTORY)
  339.           strcpy(Value,FilePath::Value);
  340. //        else if (Flags&FILENAME)
  341.   //        strcpy(Value.FilePath::File);  // <<--- bug fixed 11/18
  342.         else
  343.           strcpy(Value,".");
  344.  
  345.         if (chdir(Value) || (!Value[1] && Value[0]=='.'))
  346.         {
  347.           if (!(Flags&WILDCARDS))
  348.           {
  349.             if (!access(FilePath::Value,0))
  350.               return FileFromPath;
  351.  
  352.             fnsplit(GetMask,Drive,Dir,File,Ext);
  353.  
  354.             char WildFile[80];
  355.             strcpy(WildFile,FilePath::Value);
  356.             strcat(WildFile,Ext);
  357.  
  358.             if (!access(WildFile,0))
  359.             {
  360.               strcpy(FilePath::Value,WildFile);
  361.               return FileFromPath;
  362.             }
  363.           }
  364.           else if (!(Flags&DIRECTORY))
  365.             goto WildCheck;
  366.  
  367.           if (strlen(Value)!=2)
  368.           {
  369.  
  370. DirError:
  371.  
  372.             InfoBox &NotAvailable = *new InfoBox;
  373.             NotAvailable
  374.                   + "Sorry, either you entered in an incorrect"
  375.                   + "directory, the directory could not be"
  376.                   + "found, or that file is not available."
  377.                   + ""
  378.                   + "Please try again.";
  379.             NotAvailable.Title("Not Found");
  380.             NotAvailable.UseInfoBox();
  381.             delete &NotAvailable;
  382.             HighLight();
  383.             return CompleteEvent;
  384.           }
  385.  
  386.           if (strlen(Value)==2 && Value[1]!=':')
  387.             goto DirError;
  388.         }
  389.       }
  390.  
  391. WildCheck:
  392.  
  393.       if (Flags&WILDCARDS)
  394.       {
  395.         char JoinWildCards[15];
  396.  
  397.         JoinWildCards[0]=0;
  398.  
  399.         if (File[0])
  400.           strcat(JoinWildCards,File);
  401.  
  402.         if (Ext[0])
  403.           strcat(JoinWildCards,Ext);
  404.  
  405.         strcpy(FilePath::File.Mask,JoinWildCards);
  406.       }
  407.  
  408.       Path.Refresh();
  409.       FilePath::File.Refresh();
  410.       CurrentLocation=0;
  411.       strcpy(Value,Path.Path);
  412.       strcat(Value,FilePath::File.Mask);
  413.       strcpy(ComparePathStorage,Value);
  414.       return RefreshEvent;
  415.     }
  416.     return CompleteEvent;
  417.   }
  418.   else if (Event==' ')
  419.     return CompleteEvent;
  420.   else
  421.     return DiaChar::EventHandler(Event);
  422. }
  423.  
  424. //-------------------------------------------------------------------------
  425. //
  426. // Element that lists the available directories
  427. //
  428. //-------------------------------------------------------------------------
  429.  
  430. int ChDirList2::CurrentItem=0;
  431.  
  432. ChDirList2::ChDirList2(int X,int Y,PathStorage &_Path,FileStorage &_File,
  433.   FilePath &_PathEntry) :
  434.   Path(_Path),
  435.   File(_File),
  436.   PathEntry(_PathEntry),
  437.   DiaStructPickList(X,Y,12,5,CurrentItem,_Path.Count,sizeof(ffblk),
  438.   &_Path.DirEntries->ff_name)
  439. {
  440.   CurrentItem=0;
  441. }
  442.  
  443. int ChDirList2::EventHandler(int Event)
  444. {
  445.   if (Event==kbCr || Event==' ')
  446.   {
  447.     chdir((Path.DirEntries+CurrentItem)->ff_name);
  448.     Item=0;
  449.     ItemAtTopOfList=0;
  450.     Path.Refresh();
  451.     File.Refresh();
  452.     ItemCount=Path.Count;
  453.     strcpy(PathEntry.Value,Path.Path);
  454.     strcat(PathEntry.Value,File.Mask);
  455.     return RefreshEvent;
  456.   }
  457.   else
  458.   {
  459.     int EventStore=DiaStructPickList::EventHandler(Event);
  460.     if (EventStore==StopEvent)
  461.     {
  462.       chdir((Path.DirEntries+CurrentItem)->ff_name);
  463.       Item=0;
  464.       ItemAtTopOfList=0;
  465.       Path.Refresh();
  466.       File.Refresh();
  467.       ItemCount=Path.Count;
  468.       strcpy(PathEntry.Value,Path.Path);
  469.       strcat(PathEntry.Value,File.Mask);
  470.       return RefreshEvent;
  471.     }
  472.     return EventStore;
  473.   }
  474. }
  475.  
  476. void ChDirList2::Show()
  477. {
  478.   if (!Path.Count)
  479.   {
  480.     Item=0;
  481.     ItemAtTopOfList=0;
  482.     ItemCount=0;
  483.   }
  484.   DiaStructPickList::Show();
  485. }
  486.  
  487. //-------------------------------------------------------------------------
  488. //
  489. // DirList2 dialog that controls the display of the drives
  490. //
  491. //-------------------------------------------------------------------------
  492.  
  493. DirList2::DirList2(int X,int Y,PathStorage &_Path,FileStorage &_File,
  494.   FilePath &_PathEntry) :
  495.   Path(_Path),
  496.   File(_File),
  497.   PathEntry(_PathEntry),
  498.   DiaStructPickList(X,Y,2,5,_Path.CurrentDisk,_Path.DriveCount,2,_Path.Drives)
  499. {
  500. }
  501.  
  502. int DirList2::EventHandler(int Event)
  503. {
  504.   if (Event==kbCr || Event==' ')
  505.   {
  506.     setdisk(*Path.Drives[Path.CurrentDisk]-'A');
  507.     Path.Refresh();
  508.     File.Refresh();
  509.     strcpy(PathEntry.Value,Path.Path);
  510.     strcat(PathEntry.Value,File.Mask);
  511.     return RefreshEvent;
  512.   }
  513.   else
  514.   {
  515.     int EventStore=DiaStructPickList::EventHandler(Event);
  516.     if (EventStore==StopEvent)
  517.     {
  518.       setdisk(*Path.Drives[Path.CurrentDisk]-'A');
  519.       Path.Refresh();
  520.       File.Refresh();
  521.       strcpy(PathEntry.Value,Path.Path);
  522.       strcat(PathEntry.Value,File.Mask);
  523.       return RefreshEvent;
  524.     }
  525.     return EventStore;
  526.   }
  527. }
  528.  
  529. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  530. //
  531. // Prompt2 class
  532. //
  533. // Indicates current directory and file.
  534. //
  535. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  536.  
  537. Prompt2::Prompt2(PathStorage &_Path,FileStorage &_File,FileList &_List) :
  538.   Path(_Path),
  539.   File(_File),
  540.   List(_List)
  541. {
  542. }
  543.  
  544. void Prompt2::Show()
  545. {
  546.   MouseHide();
  547.  
  548.   Blaze->EraseArea(0,Blaze->WhatWinHeight()-2,Blaze->WhatWinWidth(),2,bCyan);
  549.   (*Blaze) (1,Blaze->WhatWinHeight()-1) << bCyan << Path.Path;
  550.  
  551.   if (File.Count)
  552.   {
  553.     char *Months[] =
  554.     {
  555.       "Jan","Feb","Mar","Apr","May","Jun",
  556.       "Jul","Aug","Sep","Oct","Nov","Dec"
  557.     };
  558.  
  559.     union
  560.     {
  561.       int Date;
  562.       struct
  563.       {
  564.         unsigned Day : 5;
  565.         unsigned Month : 4;
  566.         unsigned Year : 7;
  567.       } Bits;
  568.     } Date;
  569.  
  570.     union
  571.     {
  572.       int Time;
  573.       struct
  574.       {
  575.         unsigned Seconds : 5;
  576.         unsigned Minutes : 6;
  577.         unsigned Hours : 5;
  578.       } Bits;
  579.     } Time;
  580.  
  581.     char FileInfo[51];
  582.  
  583.     Date.Date=(File.DirEntries+List.Item)->ff_fdate;
  584.     Time.Time=(File.DirEntries+List.Item)->ff_ftime;
  585.  
  586.     sprintf(FileInfo,"%-12s       %7ld  %3s %2d, %4d  %02d:%02d",
  587.       (File.DirEntries+List.Item)->ff_name,
  588.       (File.DirEntries+List.Item)->ff_fsize,
  589.       Months[Date.Bits.Month-1],Date.Bits.Day,Date.Bits.Year+1980,
  590.       Time.Bits.Hours,Time.Bits.Minutes);
  591.  
  592.     (*Blaze) (1,Blaze->WhatWinHeight()-2) << bCyan << FileInfo;
  593.   }
  594.  
  595.   MouseShow();
  596. }
  597.  
  598. void Prompt2::HighLight()
  599. {
  600. }
  601.  
  602. int Prompt2::Available()
  603. {
  604.   return FailedEvent;
  605. }
  606.  
  607. int Prompt2::EventHandler(int Event)
  608. {
  609.   return Event;
  610. }
  611.