home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / modula2 / library / filetool / toolmenu.mod < prev    next >
Text File  |  1987-12-29  |  41KB  |  1,317 lines

  1. IMPLEMENTATION MODULE ToolMenuCommands;
  2.  
  3. (*
  4. Title    : TOOLMENU.MOD
  5. LastEdit : 01/05/87
  6. Author   : Russell G. Osterlund, Jr.
  7. System   : LOGITECH MODULA-2/86, REPERTOIRE, BlackBeard
  8.  
  9. This product has been developed with the use of, and embodies portions of,
  10. LOGITECH software development tools - compiler, linker, and M2MAKE.
  11.  
  12. *)
  13.  
  14. FROM SYSTEM IMPORT
  15.   ADR;
  16. FROM Exec IMPORT
  17.   DosShell, DosCommand;
  18. FROM Keyboard IMPORT
  19.   Read, KeyPressed;
  20. FROM EnvironUtils IMPORT (* REPETOIRE *)
  21.   ReadEnvironment, GetDate, GetTime;
  22. FROM SmartScreen IMPORT (* REPETOIRE *)
  23.   Colors, SetCursorHeight, ClearScreen, TextColor;
  24. FROM FileIO IMPORT (* REPETOIRE *)
  25.   OpenFile, CloseHandle, FileExists, EndReached;
  26. FROM StringIO IMPORT (* REPETOIRE *)
  27.   ErrorMessage, ReadStr;
  28. FROM StrEdit IMPORT (* REPETOIRE *)
  29.   CAPstr;
  30. FROM Strings IMPORT
  31.   Pos, Assign, Concat, Delete, Length, Copy, CompareStr;
  32. FROM StrConv IMPORT (* REPETOIRE *)
  33.   CardinalToStr;
  34. FROM Drectory IMPORT (* REPETOIRE *)
  35.   FileMode, ModeSet,
  36.   GetFileMode, SetFileMode,
  37.   SetFileDateAndTime,
  38.   RenameFile, DeleteFile, CopyFile,
  39.   MkDir, RmDir, ChDir,
  40.   SetDefaultDrive, GetDefaultDrive, GetCurrentDir;
  41. FROM GetKey IMPORT (* REPETOIRE *)
  42.   CRchar, ESCchar, TABchar, BTBnum,
  43.   KeySet,
  44.   MakeKeySet, GetKey;
  45. FROM ToolUtilities IMPORT
  46.   InitDirectoryInfo, ReadInfo,
  47.   SortByName, SortByExtension, SortBySize, SortByDate,
  48.   BuildFullFileName, BuildFullPath, ConcatPathFile,
  49.   RedisplayDirectory, RedisplayScreen;
  50. FROM ToolDisplay IMPORT
  51.   ConfigForeground, ConfigBackground,
  52.   DisplayInfo, DisplayFileLine, DisplaySummaryLine,
  53.   CopyMenu, RenameMenu, ExecuteMenu, AdditionalMenu,
  54.   SortMenu, AttributesMenu, OtherMenu,
  55.   DisplaySubMenu, DisplayAdditionalMenu, INCMenuPos, DECMenuPos,
  56.   YesAnswer, GetMoreInfo, DisplayMessage, NoErrorMsg, DisplayHelpScreen;
  57. FROM ToolTypes IMPORT
  58.   DirectoryRecPtr,
  59.   WindowType, ActiveWindow, BothWindowsActive,
  60.   SubmenuType, DirectoryInfo;
  61.  
  62. VAR
  63.   CopyMenuKeySet,
  64.   RenameMenuKeySet,
  65.   ExecuteMenuKeySet,
  66.   AdditionalMenuKeySet,
  67.   SortMenuKeySet,
  68.   AttributesMenuKeySet,
  69.   OtherMenuKeySet: KeySet;
  70.   Key: CHAR;
  71.   ListUtility,
  72.   EditUtility: ARRAY [0 .. 65] OF CHAR;
  73.   TheMessage,
  74.   TheQuestion: ARRAY [0 .. 79] OF CHAR;
  75.  
  76.  
  77.           (* Begin Internal Routines *)
  78.  
  79.  
  80. PROCEDURE WaitASec ();
  81. VAR
  82.   key: CHAR;
  83. BEGIN
  84.   DisplayMessage ('Press any key to return to FILETOOL.');
  85.   WHILE NOT KeyPressed () DO END;
  86.   Read (key);
  87. END WaitASec;
  88.  
  89. PROCEDURE ProcessCommand (VAR Key: CHAR;
  90.                   MenuKeySet: KeySet;
  91.                   Menu: ARRAY OF SubmenuType;
  92.                   blank: BOOLEAN): BOOLEAN;
  93. VAR
  94.   Done,
  95.   ProcessCmd,
  96.   ExtendedKey: BOOLEAN;
  97.   MenuPos: CARDINAL;
  98. BEGIN
  99.   Done := FALSE;
  100.   ProcessCmd := FALSE;
  101.   MenuPos := 0;
  102.   REPEAT
  103.     DisplaySubMenu (Menu, MenuPos, blank);
  104.     GetKey (MenuKeySet, Key, ExtendedKey);
  105.     IF ExtendedKey THEN
  106.       IF ORD (Key) = BTBnum THEN
  107.     DECMenuPos (HIGH (Menu), MenuPos);
  108.       END
  109.     ELSE
  110.       IF Key = CRchar THEN
  111.     Key := Menu [MenuPos] . KeyEquivalent;
  112.     ProcessCmd := TRUE;
  113.     Done := TRUE;
  114.       ELSE
  115.     CASE Key OF
  116.       ESCchar:
  117.       Done := TRUE;
  118.     | TABchar:
  119.       INCMenuPos (HIGH (Menu), MenuPos);
  120.     ELSE
  121.       Done := TRUE;
  122.       ProcessCmd := TRUE;
  123.     END;
  124.       END;
  125.     END;
  126.   UNTIL Done;
  127.   RETURN ProcessCmd;
  128. END ProcessCommand;
  129.  
  130. PROCEDURE ParsePath (directory: DirectoryRecPtr;
  131.              Path: ARRAY OF CHAR;
  132.          VAR TheDrive: CHAR;
  133.          VAR ThePath: ARRAY OF CHAR;
  134.          VAR TheFile: ARRAY OF CHAR;
  135.          VAR DifferentWindow: BOOLEAN);
  136. VAR
  137.   l: CARDINAL;
  138.   error: ErrorMessage;
  139. BEGIN
  140.   DifferentWindow := FALSE;
  141.   TheFile [0] := 0C;
  142.  
  143.   IF Length (Path) > 0 THEN
  144.     Assign (Path, ThePath);
  145.  
  146.     IF ThePath [1] = ':' THEN
  147.       TheDrive := ThePath [0];
  148.       Delete (ThePath, 0, 2);
  149.     ELSE
  150.       TheDrive := GetDefaultDrive ();
  151.     END;
  152.  
  153.     IF Length (ThePath) = 0 THEN (* only a drive letter entered, e.g. A: *)
  154.       TheFile [0] := 0C;
  155.       error := GetCurrentDir (TheDrive, ThePath);
  156.     ELSE
  157.       IF (Pos ('\', ThePath) # HIGH (ThePath) + 1) OR
  158.      (Pos ('/', ThePath) # HIGH (ThePath) + 1) THEN (* if found *)
  159.     l := Length (ThePath);
  160.     LOOP
  161.       IF (ThePath [l] = '\') OR
  162.          (ThePath [l] = '/') THEN
  163.         EXIT;
  164.       END;
  165.       DEC (l);
  166.     END;
  167.     IF l = 0 THEN
  168.       Copy (ThePath, 1, Length (ThePath) - 1, TheFile);
  169.       ThePath [0] := '\';
  170.       ThePath [1] := 0C;
  171.     ELSE
  172.       Copy (ThePath, l + 1, Length (ThePath) - l, TheFile);
  173.       Copy (ThePath, 0, l, ThePath);
  174.     END;
  175.       ELSE (* if not found, then assume the remainder is a filename *)
  176.     Assign (ThePath, TheFile);
  177.     error := GetCurrentDir (TheDrive, ThePath);
  178.       END;
  179.     END;
  180.  
  181.   ELSE (* Length (Path) = 0, default to current *)
  182.     TheDrive := directory^ . DirectoryDrive;
  183.     Assign (directory^ . DirectoryPath, ThePath);
  184.     TheFile [0] := 0C;
  185.   END;
  186.  
  187.   IF TheDrive # directory^ . DirectoryDrive THEN
  188.     DifferentWindow := TRUE;
  189.   END;
  190.   IF CompareStr (ThePath, directory^ . DirectoryPath) # 0 THEN
  191.     DifferentWindow := TRUE;
  192.   END;
  193. END ParsePath;
  194.  
  195. PROCEDURE OpenNewWindow (NewDrive: CHAR;
  196.              NewPath: ARRAY OF CHAR;
  197.              NewMask: ARRAY OF CHAR);
  198. VAR
  199.   NewWindow: WindowType;
  200.   OldDirectory,
  201.   NewDirectory: DirectoryRecPtr;
  202. BEGIN
  203.   IF ActiveWindow = LeftWindow THEN
  204.     OldDirectory := ADR (DirectoryInfo [ORD (LeftWindow)]);
  205.     NewWindow := RightWindow;
  206.     BothWindowsActive := TRUE;
  207.   ELSE
  208.     OldDirectory := ADR (DirectoryInfo [ORD (RightWindow)]);
  209.     NewWindow := LeftWindow;
  210.   END;
  211.   NewDirectory := ADR (DirectoryInfo [ORD (NewWindow)]);
  212.   SetDefaultDrive (NewDrive);
  213.   IF NoErrorMsg (ChDir (NewPath)) THEN
  214.     IF BothWindowsActive THEN
  215.       DisplayFileLine (OldDirectory, OldDirectory^ . CurrentFile, FALSE);
  216.     END;
  217.     InitDirectoryInfo (NewDirectory);
  218.     Assign (NewPath, NewDirectory^ . DirectoryPath);
  219.     NewDirectory^ . DirectoryDrive := NewDrive;
  220.     Assign (NewMask, NewDirectory^ . DirectoryMask);
  221.     ActiveWindow := NewWindow;
  222.     ReadInfo (NewDirectory);
  223.     DisplayInfo (NewDirectory, 0, TRUE);
  224.   END;
  225. END OpenNewWindow;
  226.  
  227. PROCEDURE CopyOther (Delete: BOOLEAN;
  228.              directory: DirectoryRecPtr);
  229. VAR
  230.   handle: CARDINAL;
  231.   OldWindow,
  232.   NewWindow: BOOLEAN;
  233.   OldDrive,
  234.   NewDrive: CHAR;
  235.   OldPath,
  236.   NewPath,
  237.   OldName,
  238.   NewName,
  239.   TheFile,
  240.   ThePath: ARRAY [0 .. 65] OF CHAR;
  241. BEGIN
  242.   GetMoreInfo (' Enter filename:', TheFile);
  243.   CAPstr (TheFile);
  244.   ParsePath (directory, TheFile, OldDrive, OldPath, OldName, OldWindow);
  245.   BuildFullPath (OldDrive, OldPath, TheFile);
  246.   ConcatPathFile (TheFile, OldName, TheFile);
  247.  
  248.   GetMoreInfo (' Enter target pathname:', ThePath);
  249.   CAPstr (ThePath);
  250.   ParsePath (directory, ThePath, NewDrive, NewPath, NewName, NewWindow);
  251.   BuildFullPath (NewDrive, NewPath, ThePath);
  252.  
  253.   IF Delete THEN
  254.     Concat (' Move ', TheFile, TheQuestion);
  255.   ELSE
  256.     Concat (' Copy ', TheFile, TheQuestion);
  257.   END;
  258.   Concat (TheQuestion, ' to ', TheQuestion);
  259.   Concat (TheQuestion, ThePath, TheQuestion);
  260.   Concat (TheQuestion, '? (Y/N)', TheQuestion);
  261.  
  262.   IF YesAnswer (TheQuestion) THEN
  263.     IF Length (NewName) > 0 THEN
  264.       ConcatPathFile (ThePath, NewName, ThePath);
  265.     ELSE (* default to old name *)
  266.       ConcatPathFile (ThePath, OldName, ThePath);
  267.     END;
  268.     IF NoErrorMsg (OpenFile (handle, TheFile)) THEN
  269.       IF NoErrorMsg (CopyFile (handle, ThePath)) THEN
  270.     IF NoErrorMsg (CloseHandle (handle)) THEN
  271.       IF Delete THEN
  272.         IF NoErrorMsg (DeleteFile (TheFile)) THEN
  273.           Concat (TheFile, ' was moved.', TheMessage);
  274.           DisplayMessage (TheMessage);
  275.         END;
  276.       ELSE
  277.         Concat (TheFile, ' was copied.', TheMessage);
  278.         DisplayMessage (TheMessage);
  279.       END;
  280.     END;
  281.       ELSE
  282.     IF NoErrorMsg (CloseHandle (handle)) THEN
  283.       IF NewWindow THEN
  284.         OpenNewWindow (NewDrive, NewPath, '*.*');
  285.       END;
  286.     END;
  287.       END;
  288.     END;
  289.   END;
  290. END CopyOther;
  291.  
  292. PROCEDURE CopyTagged (Delete: BOOLEAN;
  293.               directory: DirectoryRecPtr);
  294. VAR
  295.   i, handle: CARDINAL;
  296.   NewWindow: BOOLEAN;
  297.   NewDrive: CHAR;
  298.   NumFiles: ARRAY [0 .. 2] OF CHAR;
  299.   NewName,
  300.   OldName,
  301.   NewPath,
  302.   OldPath,
  303.   TheFile,
  304.   ThePath: ARRAY [0 .. 65] OF CHAR;
  305. BEGIN
  306.   CardinalToStr (directory^ . NumberTagged, 3, NumFiles);
  307.   BuildFullPath (directory^ . DirectoryDrive,
  308.          directory^ . DirectoryPath,
  309.          OldPath);
  310.  
  311.   GetMoreInfo (' Enter target pathname:', ThePath);
  312.   CAPstr (ThePath);
  313.   ParsePath (directory, ThePath, NewDrive, NewPath, NewName, NewWindow);
  314.   BuildFullPath (NewDrive, NewPath, ThePath);
  315.  
  316.   IF Delete THEN
  317.     Concat (' Move ', NumFiles, TheQuestion);
  318.   ELSE
  319.     Concat (' Copy ', NumFiles, TheQuestion);
  320.   END;
  321.   Concat (TheQuestion, ' file(s) from ', TheQuestion);
  322.   Concat (TheQuestion, OldPath, TheQuestion);
  323.   Concat (TheQuestion, ' to ', TheQuestion);
  324.   Concat (TheQuestion, ThePath, TheQuestion);
  325.   Concat (TheQuestion, '? (Y/N)', TheQuestion);
  326.  
  327.   IF YesAnswer (TheQuestion) THEN
  328.     FOR i := 0 TO directory^ . NumberOfEntries DO
  329.       IF directory^ . FileInfoArray [i] . tagged THEN
  330.     BuildFullFileName (directory, i, OldName);
  331.     ConcatPathFile (OldPath, OldName, TheFile);
  332.     IF NoErrorMsg (OpenFile (handle, TheFile)) THEN
  333.       ConcatPathFile (ThePath, OldName, NewName);
  334.       IF NoErrorMsg (CopyFile (handle, NewName)) THEN
  335.         IF NoErrorMsg (CloseHandle (handle)) THEN
  336.           IF Delete THEN
  337.         IF NoErrorMsg (DeleteFile (OldName)) THEN
  338.           Concat (TheFile, ' was moved.', TheMessage);
  339.           DisplayMessage (TheMessage);
  340.         END;
  341.           ELSE
  342.         Concat (TheFile, ' was copied.', TheMessage);
  343.         DisplayMessage (TheMessage);
  344.           END;
  345.         END;
  346.       END;
  347.     END;
  348.       END; (* IF tagged *)
  349.     END; (* FOR *)
  350.  
  351.     IF NewWindow THEN
  352.       OpenNewWindow (NewDrive, NewPath, '*.*');
  353.     ELSIF Delete THEN
  354.       RedisplayDirectory (directory, 0);
  355.     ELSE
  356.     END;
  357.   END;
  358. END CopyTagged;
  359.  
  360. PROCEDURE CopyCurrent (Delete: BOOLEAN;
  361.                directory: DirectoryRecPtr);
  362. VAR
  363.   handle: CARDINAL;
  364.   NewWindow: BOOLEAN;
  365.   NewDrive: CHAR;
  366.   TheFile,
  367.   ThePath,
  368.   NewPath,
  369.   OldPath,
  370.   NewName,
  371.   OldName: ARRAY [0 .. 65] OF CHAR;
  372. BEGIN
  373.   BuildFullFileName (directory, directory^ . CurrentFile, OldName);
  374.   BuildFullPath (directory^ . DirectoryDrive,
  375.          directory^ . DirectoryPath,
  376.          OldPath);
  377.   ConcatPathFile (OldPath, OldName, TheFile);
  378.  
  379.   IF NoErrorMsg (OpenFile (handle, TheFile)) THEN
  380.     GetMoreInfo (' Enter target pathname:', ThePath);
  381.     CAPstr (ThePath);
  382.     ParsePath (directory, ThePath, NewDrive, NewPath, NewName, NewWindow);
  383.     BuildFullPath (NewDrive, NewPath, ThePath);
  384.  
  385.     IF Delete THEN
  386.       Concat (' Move ', TheFile, TheQuestion);
  387.     ELSE
  388.       Concat (' Copy ', TheFile, TheQuestion);
  389.     END;
  390.     Concat (TheQuestion, ' to ', TheQuestion);
  391.     Concat (TheQuestion, ThePath, TheQuestion);
  392.     Concat (TheQuestion, '? (Y/N)', TheQuestion);
  393.  
  394.     IF YesAnswer (TheQuestion) THEN
  395.       IF Length (NewName) > 0 THEN
  396.     ConcatPathFile (ThePath, NewName, ThePath);
  397.       ELSE (* default to old name *)
  398.     ConcatPathFile (ThePath, OldName, ThePath);
  399.       END;
  400.       IF NoErrorMsg (CopyFile (handle, ThePath)) THEN
  401.     IF NoErrorMsg (CloseHandle (handle)) THEN
  402.       IF Delete THEN
  403.         IF NoErrorMsg (DeleteFile (TheFile)) THEN
  404.           Concat (TheFile, ' was moved.', TheMessage);
  405.           DisplayMessage (TheMessage);
  406.         END;
  407.       ELSE
  408.         Concat (TheFile, ' was copied.', TheMessage);
  409.         DisplayMessage (TheMessage);
  410.       END;
  411.  
  412.       IF NewWindow THEN
  413.         OpenNewWindow (NewDrive, NewPath, '*.*');
  414.       ELSIF Delete THEN
  415.         RedisplayDirectory (directory, 0);
  416.       ELSE
  417.       END;
  418.     END;
  419.       END;
  420.     END;
  421.   END;
  422. END CopyCurrent;
  423.  
  424.  
  425.           (* Begin External Routines *)
  426.  
  427.  
  428. PROCEDURE HelpCommand (LeftDirectory,
  429.                RightDirectory: DirectoryRecPtr);
  430. VAR
  431.   directory: DirectoryRecPtr;
  432. BEGIN
  433.   IF ActiveWindow = LeftWindow THEN
  434.     directory := LeftDirectory
  435.   ELSE
  436.     directory := RightDirectory;
  437.   END;
  438.   DisplayHelpScreen ();
  439.   WaitASec ();
  440.   ClearScreen ();
  441.   RedisplayScreen (directory, LeftDirectory, RightDirectory);
  442. END HelpCommand;
  443.  
  444. PROCEDURE CopyCommand (directory: DirectoryRecPtr);
  445. BEGIN
  446.   IF ProcessCommand (Key, CopyMenuKeySet, CopyMenu, TRUE) THEN
  447.     WITH directory^ DO
  448.       CASE Key OF
  449.     "c", "C":
  450.       IF SubdirectoryFile IN FileInfoArray [CurrentFile] . FileAttribute THEN
  451.       ELSIF (FileInfoArray [CurrentFile] . FileName [0] = '.') OR                           (* special DOS *)
  452.            ((FileInfoArray [CurrentFile] . FileName [0] = '.') AND
  453.         (FileInfoArray [CurrentFile] . FileName [1] = '.')) THEN
  454.       ELSE
  455.         CopyCurrent (FALSE, directory);
  456.       END;
  457.       | "t", "T":
  458.       IF NumberTagged > 0 THEN
  459.         CopyTagged (FALSE, directory);
  460.       END;
  461.       | "o", "O":
  462.       CopyOther (FALSE, directory);
  463.       ELSE
  464.       END;
  465.     END;
  466.   END;
  467. END CopyCommand;
  468.  
  469. PROCEDURE MoveCommand (directory: DirectoryRecPtr);
  470. BEGIN
  471.   IF ProcessCommand (Key, CopyMenuKeySet, CopyMenu, TRUE) THEN
  472.     WITH directory^ DO
  473.       CASE Key OF
  474.     "c", "C":
  475.       IF SubdirectoryFile IN FileInfoArray [CurrentFile] . FileAttribute THEN
  476.       ELSIF (FileInfoArray [CurrentFile] . FileName [0] = '.') OR                           (* special DOS *)
  477.            ((FileInfoArray [CurrentFile] . FileName [0] = '.') AND
  478.         (FileInfoArray [CurrentFile] . FileName [1] = '.')) THEN
  479.       ELSE
  480.         CopyCurrent (TRUE, directory);
  481.       END;
  482.       | "t", "T":
  483.       IF NumberTagged > 0 THEN
  484.         CopyTagged (TRUE, directory);
  485.       END;
  486.       | "o", "O":
  487.       CopyOther (TRUE, directory);
  488.       ELSE
  489.       END;
  490.     END;
  491.   END;
  492. END MoveCommand;
  493.  
  494. PROCEDURE DeleteCommand (directory: DirectoryRecPtr);
  495. VAR
  496.   i: CARDINAL;
  497.   NewWindow: BOOLEAN;
  498.   NewDrive: CHAR;
  499.   NumFiles: ARRAY [0 .. 2] OF CHAR;
  500.   NewPath,
  501.   NewName,
  502.   TheFile: ARRAY [0 .. 65] OF CHAR;
  503. BEGIN
  504.   IF ProcessCommand (Key, CopyMenuKeySet, CopyMenu, TRUE) THEN
  505.     WITH directory^ DO
  506.       CASE Key OF
  507.     "c", "C":
  508.       IF SubdirectoryFile IN FileInfoArray [CurrentFile] . FileAttribute THEN
  509.       ELSIF (FileInfoArray [CurrentFile] . FileName [0] = '.') OR                           (* special DOS *)
  510.            ((FileInfoArray [CurrentFile] . FileName [0] = '.') AND
  511.         (FileInfoArray [i] . FileName [1] = '.')) THEN
  512.       ELSE
  513.         BuildFullFileName (directory, CurrentFile, NewName);
  514.         BuildFullPath (DirectoryDrive, DirectoryPath, NewPath);
  515.         ConcatPathFile (NewPath, NewName, TheFile);
  516.         Concat (' Delete ', NewName, TheQuestion);
  517.         Concat (TheQuestion, ' from ', TheQuestion);
  518.         Concat (TheQuestion, NewPath, TheQuestion);
  519.         Concat (TheQuestion, '? (Y/N)', TheQuestion);
  520.         IF YesAnswer (TheQuestion) THEN
  521.           IF NoErrorMsg (DeleteFile (TheFile)) THEN
  522.         RedisplayDirectory (directory, 0);
  523.         Concat (TheFile, ' was deleted.', TheMessage);
  524.         DisplayMessage (TheMessage);
  525.           END;
  526.         END;
  527.       END;
  528.       | "t", "T":
  529.       IF NumberTagged > 0 THEN
  530.         CardinalToStr (NumberTagged, 3, NumFiles);
  531.         BuildFullPath (DirectoryDrive, DirectoryPath, NewPath);
  532.         Concat (' Delete ', NumFiles, TheQuestion);
  533.         Concat (TheQuestion, ' file(s) from ', TheQuestion);
  534.         Concat (TheQuestion, NewPath, TheQuestion);
  535.         Concat (TheQuestion, '? (Y/N)', TheQuestion);
  536.         IF YesAnswer (TheQuestion) THEN
  537.           FOR i := 0 TO NumberOfEntries DO
  538.         IF FileInfoArray [i] . tagged THEN
  539.           BuildFullFileName (directory, i, NewName);
  540.           ConcatPathFile (NewPath, NewName, TheFile);
  541.           IF NoErrorMsg (DeleteFile (TheFile)) THEN
  542.             Concat (TheFile, ' was deleted.', TheMessage);
  543.             DisplayMessage (TheMessage);
  544.           END;
  545.         END;
  546.           END;
  547.           RedisplayDirectory (directory, 0);
  548.         END;
  549.       END;
  550.       | "o", "O":
  551.       GetMoreInfo (' Enter filename:', TheFile);
  552.       CAPstr (TheFile);
  553.       ParsePath (directory, TheFile, NewDrive, NewPath, NewName, NewWindow);
  554.       BuildFullPath (NewDrive, NewPath, TheFile);
  555.       ConcatPathFile (TheFile, NewName, TheFile);
  556.       Concat (' Delete ', TheFile, TheQuestion);
  557.       Concat (TheQuestion, '? (Y/N)', TheQuestion);
  558.       IF YesAnswer (TheQuestion) THEN
  559.         IF NoErrorMsg (DeleteFile (TheFile)) THEN
  560.           Concat (TheFile, ' was deleted.', TheMessage);
  561.           DisplayMessage (TheMessage);
  562.         END;
  563.         IF NewWindow THEN
  564.           OpenNewWindow (NewDrive, NewPath, '*.*');
  565.         END;
  566.       END;
  567.       ELSE
  568.       END;
  569.     END;
  570.   END;
  571. END DeleteCommand;
  572.  
  573. PROCEDURE RenameCommand (directory: DirectoryRecPtr);
  574. VAR
  575.   NewName,
  576.   OldName: ARRAY [0 .. 65] OF CHAR;
  577.  
  578. PROCEDURE PerformRename (redisplay: BOOLEAN);
  579. BEGIN
  580.   Concat (' Rename ', OldName, TheQuestion);
  581.   Concat (TheQuestion, ' to ', TheQuestion);
  582.   Concat (TheQuestion, NewName, TheQuestion);
  583.   Concat (TheQuestion, '? (Y/N)', TheQuestion);
  584.   IF YesAnswer (TheQuestion) THEN
  585.     IF NoErrorMsg (RenameFile (OldName, NewName)) THEN
  586.       IF redisplay THEN
  587.     RedisplayDirectory (directory, directory^ . FirstDisplayed);
  588.       END;
  589.       Concat (OldName, ' was renamed.', TheMessage);
  590.       DisplayMessage (TheMessage);
  591.     END;
  592.   END;
  593. END PerformRename;
  594.  
  595. BEGIN
  596.   IF ProcessCommand (Key, RenameMenuKeySet, RenameMenu, TRUE) THEN
  597.     WITH directory^ DO
  598.       CASE Key OF
  599.     "c", "C":
  600.       IF SubdirectoryFile IN FileInfoArray [CurrentFile] . FileAttribute THEN
  601.       ELSIF (FileInfoArray [CurrentFile] . FileName [0] = '.') OR                           (* special DOS *)
  602.            ((FileInfoArray [CurrentFile] . FileName [0] = '.') AND
  603.         (FileInfoArray [CurrentFile] . FileName [1] = '.')) THEN
  604.       ELSE
  605.         GetMoreInfo (' Enter new name:', NewName);
  606.         CAPstr (NewName);
  607.         BuildFullFileName (directory, CurrentFile, OldName);
  608.         PerformRename (TRUE);
  609.       END;
  610.       | "o", "O":
  611.       GetMoreInfo (' Enter old name:', OldName);
  612.       GetMoreInfo (' Enter new name:', NewName);
  613.       CAPstr (OldName);
  614.       CAPstr (NewName);
  615.       PerformRename (FALSE);
  616.       ELSE
  617.       END;
  618.     END;
  619.   END;
  620. END RenameCommand;
  621.  
  622. PROCEDURE AttributesCommand (directory: DirectoryRecPtr);
  623. VAR
  624.   i: CARDINAL;
  625.   NewWindow: BOOLEAN;
  626.   NewDrive: CHAR;
  627.   NumFiles: ARRAY [0 .. 2] OF CHAR;
  628.   NewPath,
  629.   NewName,
  630.   TheFile: ARRAY [0 .. 65] OF CHAR;
  631.   TheMessage,
  632.   TheResponse: ARRAY [0 .. 79] OF CHAR;
  633.  
  634. PROCEDURE ProcessAttribute (TheAttribute: FileMode;
  635.                 Include: BOOLEAN);
  636. VAR
  637.   TheAttributes: ModeSet;
  638. BEGIN
  639.   IF ProcessCommand (Key, CopyMenuKeySet, CopyMenu, TRUE) THEN
  640.     CASE TheAttribute OF
  641.       ReadOnlyFile:
  642.     IF Include THEN
  643.       TheQuestion := ' Protect ';
  644.       TheResponse := ' was protected.';
  645.     ELSE
  646.       TheQuestion := ' Unprotect ';
  647.       TheResponse := ' was unprotected.';
  648.     END;
  649.     | HiddenFile:
  650.     IF Include THEN
  651.       TheQuestion := ' Hide ';
  652.       TheResponse := ' was hidden.';
  653.     ELSE
  654.       TheQuestion := ' Show ';
  655.       TheResponse := ' was unhidden.';
  656.     END;
  657.     ELSE
  658.     END;
  659.     WITH directory^ DO
  660.       CASE Key OF
  661.     "c", "C":
  662.       BuildFullFileName (directory, CurrentFile, NewName);
  663.       BuildFullPath (DirectoryDrive, DirectoryPath, NewPath);
  664.       Concat (TheQuestion, NewName, TheQuestion);
  665.       Concat (TheQuestion, ' in ', TheQuestion);
  666.       Concat (TheQuestion, NewPath, TheQuestion);
  667.       Concat (TheQuestion, '? (Y/N)', TheQuestion);
  668.       IF YesAnswer (TheQuestion) THEN
  669.         ConcatPathFile (NewPath, NewName, TheFile);
  670.         IF Include THEN
  671.           INCL (FileInfoArray [CurrentFile] . FileAttribute, TheAttribute);
  672.         ELSE
  673.           EXCL (FileInfoArray [CurrentFile] . FileAttribute, TheAttribute);
  674.         END;
  675.         IF NoErrorMsg (SetFileMode (TheFile,
  676.                     FileInfoArray [CurrentFile] . FileAttribute)) THEN
  677.           RedisplayDirectory (directory, 0);
  678.           Concat (TheFile, TheResponse, TheResponse);
  679.           DisplayMessage (TheResponse);
  680.         END;
  681.       END;
  682.       | "o", "O":
  683.       GetMoreInfo (' Enter filename:', TheFile);
  684.       CAPstr (TheFile);
  685.       ParsePath (directory, TheFile, NewDrive, NewPath, NewName, NewWindow);
  686.       BuildFullPath (NewDrive, NewPath, TheFile);
  687.       ConcatPathFile (TheFile, NewName, TheFile);
  688.       Concat (TheQuestion, TheFile, TheQuestion);
  689.       Concat (TheQuestion, '? (Y/N)', TheQuestion);
  690.       IF YesAnswer (TheQuestion) THEN
  691.         IF NoErrorMsg (GetFileMode (TheFile, TheAttributes)) THEN
  692.           IF Include THEN
  693.         INCL (TheAttributes, TheAttribute);
  694.           ELSE
  695.         EXCL (TheAttributes, TheAttribute);
  696.           END;
  697.           IF NoErrorMsg (SetFileMode (TheFile, TheAttributes)) THEN
  698.         IF NewWindow THEN
  699.           OpenNewWindow (NewDrive, NewPath, '*.*');
  700.         ELSE
  701.           RedisplayDirectory (directory, 0);
  702.         END;
  703.         Concat (TheFile, TheResponse, TheResponse);
  704.         DisplayMessage (TheResponse);
  705.           END;
  706.         END;
  707.       END;
  708.       | "t", "T":
  709.     IF NumberTagged > 0 THEN
  710.       CardinalToStr (NumberTagged, 3, NumFiles);
  711.       BuildFullPath (DirectoryDrive, DirectoryPath, NewPath);
  712.       Concat (TheQuestion, NumFiles, TheQuestion);
  713.       Concat (TheQuestion, ' file(s) in ', TheQuestion);
  714.       Concat (TheQuestion, NewPath, TheQuestion);
  715.       Concat (TheQuestion, '? (Y/N)', TheQuestion);
  716.       IF YesAnswer (TheQuestion) THEN
  717.         FOR i := 0 TO NumberOfEntries DO
  718.           IF FileInfoArray [i] . tagged THEN
  719.         BuildFullFileName (directory, i, NewName);
  720.         ConcatPathFile (NewPath, NewName, TheFile);
  721.         IF Include THEN
  722.           INCL (FileInfoArray [i] . FileAttribute, TheAttribute);
  723.         ELSE
  724.           EXCL (FileInfoArray [i] . FileAttribute, TheAttribute);
  725.         END;
  726.         IF NoErrorMsg (SetFileMode (TheFile,
  727.                         FileInfoArray [i] . FileAttribute)) THEN
  728.           Concat (TheFile, TheResponse, TheMessage);
  729.           DisplayMessage (TheMessage);
  730.         END;
  731.           END;
  732.         END;
  733.         RedisplayDirectory (directory, 0);
  734.       END;
  735.     END;
  736.       ELSE
  737.       END;
  738.     END;
  739.   END;
  740. END ProcessAttribute;
  741.  
  742. PROCEDURE ProcessDateTime ();
  743. VAR
  744.   handle,
  745.   Month, Day, Year,
  746.   Hours, Minutes, Seconds, Hundreths: CARDINAL;
  747.   Time, DayOfWeek, Date: ARRAY [0 .. 79] OF CHAR;
  748. BEGIN
  749.   GetDate (Month, Day, Year, DayOfWeek, Date);
  750.   GetTime (Hours, Minutes, Seconds, Hundreths, Time);
  751.   Concat (' Set file(s) to SYSTEM date/time of ', Date, TheQuestion);
  752.   Concat (TheQuestion, '/', TheQuestion);
  753.   Concat (TheQuestion, Time, TheQuestion);
  754.   Concat (TheQuestion, '? (Y/N)', TheQuestion);
  755.   IF YesAnswer (TheQuestion) THEN
  756.     IF ProcessCommand (Key, CopyMenuKeySet, CopyMenu, TRUE) THEN
  757.       WITH directory^ DO
  758.     CASE Key OF
  759.       "c", "C":
  760.         BuildFullFileName (directory, CurrentFile, NewName);
  761.         BuildFullPath (DirectoryDrive, DirectoryPath, NewPath);
  762.         ConcatPathFile (NewPath, NewName, TheFile);
  763.         IF NoErrorMsg (OpenFile (handle, TheFile)) THEN
  764.           SetFileDateAndTime (handle, Month, Day, Year, Hours, Minutes, Seconds);
  765.           IF NoErrorMsg (CloseHandle (handle)) THEN
  766.         RedisplayDirectory (directory, 0);
  767.         Concat (' New date/time was set for ', TheFile, TheResponse);
  768.         DisplayMessage (TheResponse);
  769.           END;
  770.         END;
  771.     | "o", "O":
  772.         GetMoreInfo (' Enter filename:', TheFile);
  773.         CAPstr (TheFile);
  774.         ParsePath (directory, TheFile, NewDrive, NewPath, NewName, NewWindow);
  775.         BuildFullPath (NewDrive, NewPath, TheFile);
  776.         ConcatPathFile (TheFile, NewName, TheFile);
  777.         IF NoErrorMsg (OpenFile (handle, TheFile)) THEN
  778.           SetFileDateAndTime (handle, Month, Day, Year, Hours, Minutes, Seconds);
  779.           IF NoErrorMsg (CloseHandle (handle)) THEN
  780.         IF NewWindow THEN
  781.           OpenNewWindow (NewDrive, NewPath, '*.*');
  782.         ELSE
  783.           RedisplayDirectory (directory, 0);
  784.         END;
  785.         Concat (' New date/time was set for ', TheFile, TheResponse);
  786.         DisplayMessage (TheResponse);
  787.           END;
  788.         END;
  789.     | "t", "T":
  790.         IF NumberTagged > 0 THEN
  791.           BuildFullPath (DirectoryDrive, DirectoryPath, NewPath);
  792.           FOR i := 0 TO NumberOfEntries DO
  793.         IF FileInfoArray [i] . tagged THEN
  794.           BuildFullFileName (directory, i, NewName);
  795.           ConcatPathFile (NewPath, NewName, TheFile);
  796.           IF NoErrorMsg (OpenFile (handle, TheFile)) THEN
  797.             SetFileDateAndTime (handle, Month, Day, Year, Hours, Minutes, Seconds);
  798.             IF NoErrorMsg (CloseHandle (handle)) THEN
  799.               Concat (' New date/time was set for ', TheFile, TheResponse);
  800.               DisplayMessage (TheResponse);
  801.             END;
  802.           END;
  803.         END;
  804.           END;
  805.           RedisplayDirectory (directory, 0);
  806.         END;
  807.     ELSE
  808.     END;
  809.       END;
  810.     END;
  811.   END;
  812. END ProcessDateTime;
  813.  
  814. BEGIN
  815.   IF ProcessCommand (Key, AttributesMenuKeySet, AttributesMenu, TRUE) THEN
  816.     CASE Key OF
  817.       "d", "D":
  818.     ProcessDateTime ();
  819.     | "p", "P":
  820.     ProcessAttribute (ReadOnlyFile, TRUE);
  821.     | "h", "H":
  822.     ProcessAttribute (HiddenFile, TRUE);
  823.     | "s", "S":
  824.     ProcessAttribute (HiddenFile, FALSE);
  825.     | "u", "U":
  826.     ProcessAttribute (ReadOnlyFile, FALSE);
  827.     ELSE
  828.     END;
  829.   END;
  830. END AttributesCommand;
  831.  
  832. PROCEDURE EditListCommand (LeftDirectory,
  833.                RightDirectory: DirectoryRecPtr;
  834.                edit: BOOLEAN);
  835.  
  836. VAR
  837.   done,
  838.   NewWindow: BOOLEAN;
  839.   NewDrive: CHAR;
  840.   i: CARDINAL;
  841.   FullFileName: ARRAY [0 .. 11] OF CHAR;
  842.   NewPath,
  843.   NewName,
  844.   OtherName: ARRAY [0 .. 65] OF CHAR;
  845.   directory: DirectoryRecPtr;
  846. BEGIN
  847.   IF ActiveWindow = LeftWindow THEN
  848.     directory := LeftDirectory
  849.   ELSE
  850.     directory := RightDirectory;
  851.   END;
  852.   IF ProcessCommand (Key, CopyMenuKeySet, CopyMenu, TRUE) THEN
  853.     WITH directory^ DO
  854.       CASE Key OF
  855.     "c", "C":
  856.       IF SubdirectoryFile IN FileInfoArray [CurrentFile] . FileAttribute THEN
  857.       ELSIF (FileInfoArray [CurrentFile] . FileName [0] = '.') OR                           (* special DOS *)
  858.            ((FileInfoArray [CurrentFile] . FileName [0] = '.') AND
  859.         (FileInfoArray [CurrentFile] . FileName [1] = '.')) THEN
  860.       ELSE
  861.         BuildFullFileName (directory, CurrentFile, FullFileName);
  862.         SetCursorHeight (2);
  863.         IF edit THEN
  864.           DosCommand (EditUtility, FullFileName, done);
  865.         ELSE
  866.           DosCommand (ListUtility, FullFileName, done);
  867.         END;
  868.         ClearScreen ();
  869.         SetCursorHeight (0);
  870.         RedisplayScreen (directory, LeftDirectory, RightDirectory);
  871.       END;
  872.       | "o", "O":
  873.       GetMoreInfo (' Enter filename:', OtherName);
  874.       ParsePath (directory, OtherName, NewDrive, NewPath, NewName, NewWindow);
  875.       BuildFullPath (NewDrive, NewPath, OtherName);
  876.       ConcatPathFile (OtherName, NewName, OtherName);
  877.       SetCursorHeight (2);
  878.       IF edit THEN
  879.         DosCommand (EditUtility, OtherName, done);
  880.       ELSE
  881.         DosCommand (ListUtility, OtherName, done);
  882.       END;
  883.       ClearScreen ();
  884.       SetCursorHeight (0);
  885.       RedisplayScreen (directory, LeftDirectory, RightDirectory);
  886.       | "t", "T":
  887.       IF NumberTagged > 0 THEN
  888.         FOR i := 0 TO NumberOfEntries DO
  889.           IF FileInfoArray [i] . tagged THEN
  890.         BuildFullFileName (directory, i, FullFileName);
  891.         SetCursorHeight (2);
  892.         IF edit THEN
  893.           DosCommand (EditUtility, FullFileName, done);
  894.         ELSE
  895.           DosCommand (ListUtility, FullFileName, done);
  896.         END;
  897.         ClearScreen ();
  898.         SetCursorHeight (0);
  899.           END;
  900.         END;
  901.         RedisplayScreen (directory, LeftDirectory, RightDirectory);
  902.       END;
  903.       ELSE
  904.       END;
  905.     END;
  906.   END;
  907. END EditListCommand;
  908.  
  909. PROCEDURE ExecuteCommand (LeftDirectory,
  910.               RightDirectory: DirectoryRecPtr);
  911. VAR
  912.   done: BOOLEAN;
  913.   MenuPos: CARDINAL;
  914.   FullFileName: ARRAY [0 .. 11] OF CHAR;
  915.   Parameters,
  916.   OtherName: ARRAY [0 .. 65] OF CHAR;
  917.   directory: DirectoryRecPtr;
  918. BEGIN
  919.   IF ActiveWindow = LeftWindow THEN
  920.     directory := LeftDirectory
  921.   ELSE
  922.     directory := RightDirectory;
  923.   END;
  924.   IF ProcessCommand (Key, ExecuteMenuKeySet, ExecuteMenu, TRUE) THEN
  925.     CASE Key OF
  926.       "c", "C":
  927.     WITH directory^ DO
  928.       IF SubdirectoryFile IN FileInfoArray [CurrentFile] . FileAttribute THEN
  929.       ELSIF (FileInfoArray [CurrentFile] . FileName [0] = '.') OR                           (* special DOS *)
  930.            ((FileInfoArray [CurrentFile] . FileName [0] = '.') AND
  931.         (FileInfoArray [CurrentFile] . FileName [1] = '.')) THEN
  932.       ELSE
  933.         GetMoreInfo (' Enter any parameters:', Parameters);
  934.         SetCursorHeight (2);
  935.         BuildFullFileName (directory, CurrentFile, FullFileName);
  936.         ClearScreen ();
  937.         DosCommand (FullFileName, Parameters, done);
  938.         IF done THEN
  939.           SetCursorHeight (0);
  940.           WaitASec ();
  941.           ClearScreen ();
  942.           RedisplayScreen (directory, LeftDirectory, RightDirectory);
  943.         END;
  944.       END;
  945.     END;
  946.     | "s", "S":
  947.     SetCursorHeight (2);
  948.     ClearScreen ();
  949.     DosShell (done);
  950.     IF done THEN
  951.       ClearScreen ();
  952.       SetCursorHeight (0);
  953.       RedisplayScreen (directory, LeftDirectory, RightDirectory);
  954.     END;
  955.     | "o", "O":
  956.     GetMoreInfo (' Enter other command:', OtherName);
  957.     GetMoreInfo (' Enter any parameters:', Parameters);
  958.     SetCursorHeight (2);
  959.     ClearScreen ();
  960.     DosCommand (OtherName, Parameters, done);
  961.     IF done THEN
  962.       SetCursorHeight (0);
  963.       WaitASec ();
  964.       ClearScreen ();
  965.       RedisplayScreen (directory, LeftDirectory, RightDirectory);
  966.     END;
  967.     | "m", "M":
  968.     DisplayAdditionalMenu ();
  969.     IF ProcessCommand (Key, AdditionalMenuKeySet, AdditionalMenu, FALSE) THEN
  970.       DisplaySubMenu (ExecuteMenu, 2, TRUE);
  971.       CASE Key OF
  972.         "a", "A":
  973.           Assign (AdditionalMenu [0] . Command, OtherName);
  974.           MenuPos := 0;
  975.       | "b", "B":
  976.           Assign (AdditionalMenu [1] . Command, OtherName);
  977.           MenuPos := 1;
  978.       | "c", "C":
  979.           Assign (AdditionalMenu [2] . Command, OtherName);
  980.           MenuPos := 2;
  981.       | "d", "D":
  982.           Assign (AdditionalMenu [3] . Command, OtherName);
  983.           MenuPos := 3;
  984.       | "e", "E":
  985.           Assign (AdditionalMenu [4] . Command, OtherName);
  986.           MenuPos := 4;
  987.       | "f", "F":
  988.           Assign (AdditionalMenu [5] . Command, OtherName);
  989.           MenuPos := 5;
  990.       | "g", "G":
  991.           Assign (AdditionalMenu [6] . Command, OtherName);
  992.           MenuPos := 6;
  993.       | "h", "H":
  994.           Assign (AdditionalMenu [7] . Command, OtherName);
  995.           MenuPos := 7;
  996.       | "i", "I":
  997.           Assign (AdditionalMenu [8] . Command, OtherName);
  998.           MenuPos := 8;
  999.       | "j", "J":
  1000.           Assign (AdditionalMenu [9] . Command, OtherName);
  1001.           MenuPos := 9;
  1002.       ELSE
  1003.       END;
  1004.       DisplaySubMenu (AdditionalMenu, MenuPos, FALSE);
  1005.       GetMoreInfo (' Enter any parameters:', Parameters);
  1006.       SetCursorHeight (2);
  1007.       ClearScreen ();
  1008.       DosCommand (OtherName, Parameters, done);
  1009.       SetCursorHeight (0);
  1010.       IF done THEN
  1011.         WaitASec ();
  1012.       END;
  1013.     END;
  1014.     ClearScreen ();
  1015.     RedisplayScreen (directory, LeftDirectory, RightDirectory);
  1016.     ELSE
  1017.     END;
  1018.   END;
  1019. END ExecuteCommand;
  1020.  
  1021. PROCEDURE SortCommand ();
  1022. BEGIN
  1023.   IF ProcessCommand (Key, SortMenuKeySet, SortMenu, TRUE) THEN
  1024.     CASE Key OF
  1025.       "n", "N":
  1026.     SortByName (0, DirectoryInfo [ORD (ActiveWindow)] . NumberOfEntries);
  1027.     DirectoryInfo [ORD (ActiveWindow)] . CurrentFile := 0;
  1028.     DisplayInfo (ADR (DirectoryInfo [ORD (ActiveWindow)]), 0, TRUE);
  1029.     | "e", "E":
  1030.     SortByExtension (0, DirectoryInfo [ORD (ActiveWindow)] . NumberOfEntries);
  1031.     DirectoryInfo [ORD (ActiveWindow)] . CurrentFile := 0;
  1032.     DisplayInfo (ADR (DirectoryInfo [ORD (ActiveWindow)]), 0, TRUE);
  1033.     | "d", "D":
  1034.     SortByDate (0, DirectoryInfo [ORD (ActiveWindow)] . NumberOfEntries);
  1035.     DirectoryInfo [ORD (ActiveWindow)] . CurrentFile := 0;
  1036.     DisplayInfo (ADR (DirectoryInfo [ORD (ActiveWindow)]), 0, TRUE);
  1037.     | "s", "S":
  1038.     SortBySize (0, DirectoryInfo [ORD (ActiveWindow)] . NumberOfEntries);
  1039.     DirectoryInfo [ORD (ActiveWindow)] . CurrentFile := 0;
  1040.     DisplayInfo (ADR (DirectoryInfo [ORD (ActiveWindow)]), 0, TRUE);
  1041.     ELSE
  1042.     END;
  1043.   END;
  1044. END SortCommand;
  1045.  
  1046. PROCEDURE OtherCommand (LeftDirectory,
  1047.             RightDirectory: DirectoryRecPtr);
  1048. VAR
  1049.   i, n: CARDINAL;
  1050.   NewWindow: BOOLEAN;
  1051.   NewDrive: CHAR;
  1052.   NumFiles: ARRAY [0 .. 2] OF CHAR;
  1053.   NewDirectory: ARRAY [0 .. 10] OF CHAR;
  1054.   FullPath,
  1055.   NewPath,
  1056.   NewName,
  1057.   Path: ARRAY [0 .. 65] OF CHAR;
  1058.   directory: DirectoryRecPtr;
  1059. BEGIN
  1060.   IF ActiveWindow = LeftWindow THEN
  1061.     directory := LeftDirectory
  1062.   ELSE
  1063.     directory := RightDirectory;
  1064.   END;
  1065.   IF ProcessCommand (Key, OtherMenuKeySet, OtherMenu, TRUE) THEN
  1066.     CASE Key OF
  1067.       "c", "C":
  1068.     GetMoreInfo (' Enter new directory name:', NewDirectory);
  1069.     IF NoErrorMsg (MkDir (NewDirectory)) THEN
  1070.       CAPstr (NewDirectory);
  1071.       RedisplayDirectory (directory, 0);
  1072.       Concat ('Subdirectory ', NewDirectory, TheMessage);
  1073.       Concat (TheMessage, ' was created.', TheMessage);
  1074.       DisplayMessage (TheMessage);
  1075.     END;
  1076.     | "d", "D":
  1077.     IF SubdirectoryFile IN directory^ . FileInfoArray [directory^ . CurrentFile] . FileAttribute THEN
  1078.       IF NoErrorMsg (RmDir (directory^ . FileInfoArray [directory^ . CurrentFile] . FileName)) THEN
  1079.         Concat ('Subdirectory ', directory^ . FileInfoArray [directory^ . CurrentFile] . FileName, TheMessage);
  1080.         Concat (TheMessage, ' was deleted.', TheMessage);
  1081.         RedisplayDirectory (directory, 0);
  1082.         DisplayMessage (TheMessage);
  1083.       END;
  1084.     END;
  1085.     | "l", "L":
  1086.     GetMoreInfo (' Enter new path:', Path);
  1087.     IF Path [0] = 0C THEN
  1088.       IF ActiveWindow = LeftWindow THEN (* do nothing *)
  1089.       ELSE
  1090.         IF BothWindowsActive THEN
  1091.           (* blank out "diamond" sign if present *)
  1092.           DisplayFileLine (RightDirectory, RightDirectory^ . CurrentFile, FALSE);
  1093.         END;
  1094.         ActiveWindow := LeftWindow;
  1095.         RedisplayDirectory (LeftDirectory, 0);
  1096.       END;
  1097.     ELSE
  1098.       CAPstr (Path);
  1099.       ParsePath (directory, Path, NewDrive, NewPath, NewName, NewWindow);
  1100.       IF NewName [0] = 0C THEN
  1101.         NewName := '*.*';
  1102.       END;
  1103.       ActiveWindow := RightWindow;
  1104.       OpenNewWindow (NewDrive, NewPath, NewName);
  1105.     END;
  1106.     | "r", "R":
  1107.     GetMoreInfo (' Enter new path:', Path);
  1108.     IF Path [0] = 0C THEN
  1109.       IF ActiveWindow = RightWindow THEN (* do nothing *)
  1110.       ELSIF BothWindowsActive THEN
  1111.         (* blank out "diamond" sign if present *)
  1112.         DisplayFileLine (LeftDirectory, LeftDirectory^ . CurrentFile, FALSE);
  1113.         ActiveWindow := RightWindow;
  1114.         RedisplayDirectory (RightDirectory, 0);
  1115.       END;
  1116.     ELSE
  1117.       CAPstr (Path);
  1118.       ParsePath (directory, Path, NewDrive, NewPath, NewName, NewWindow);
  1119.       IF NewName [0] = 0C THEN
  1120.         NewName := '*.*';
  1121.       END;
  1122.       ActiveWindow := LeftWindow;
  1123.       OpenNewWindow (NewDrive, NewPath, NewName);
  1124.     END;
  1125.     | "s", "S":
  1126.     InitConfiguration ();
  1127.     ClearScreen ();
  1128.     RedisplayScreen (directory, LeftDirectory, RightDirectory);
  1129.     | "t", "T":
  1130.     WITH directory^ DO
  1131.       n := NumberOfEntries - NumberTagged + 1;
  1132.       CardinalToStr (n, 3, NumFiles);
  1133.       BuildFullPath (DirectoryDrive, DirectoryPath, FullPath);
  1134.       Concat (' Tag ', NumFiles, TheQuestion);
  1135.       Concat (TheQuestion, ' file(s) in ', TheQuestion);
  1136.       Concat (TheQuestion, FullPath, TheQuestion);
  1137.       Concat (TheQuestion, '? (Y/N)', TheQuestion);
  1138.       IF YesAnswer (TheQuestion) THEN
  1139.         FOR i := 0 TO NumberOfEntries DO
  1140.           IF FileInfoArray [i] . tagged THEN
  1141.           ELSE
  1142.         IF SubdirectoryFile IN FileInfoArray [i] . FileAttribute THEN
  1143.         ELSIF (FileInfoArray [i] . FileName [0] = '.') OR                           (* special DOS *)
  1144.              ((FileInfoArray [i] . FileName [0] = '.') AND
  1145.               (FileInfoArray [i] . FileName [1] = '.')) THEN
  1146.         ELSE
  1147.           FileInfoArray [i] . tagged := TRUE;
  1148.           INC (NumberTagged);
  1149.           TaggedSize := TaggedSize + FileInfoArray [i] . FileSize;
  1150.         END;
  1151.           END;
  1152.         END;
  1153.         DisplayInfo (directory, FirstDisplayed, TRUE);
  1154.         DisplaySummaryLine (directory);
  1155.       END;
  1156.     END;
  1157.     | "u", "U":
  1158.     WITH directory^ DO
  1159.       IF NumberTagged > 0 THEN
  1160.         CardinalToStr (NumberTagged, 3, NumFiles);
  1161.         BuildFullPath (DirectoryDrive, DirectoryPath, FullPath);
  1162.         Concat (' Untag ', NumFiles, TheQuestion);
  1163.         Concat (TheQuestion, ' file(s) in ', TheQuestion);
  1164.         Concat (TheQuestion, FullPath, TheQuestion);
  1165.         Concat (TheQuestion, '? (Y/N)', TheQuestion);
  1166.         IF YesAnswer (TheQuestion) THEN
  1167.           FOR i := 0 TO NumberOfEntries DO
  1168.         IF FileInfoArray [i] . tagged THEN
  1169.           FileInfoArray [i] . tagged := FALSE;
  1170.           DEC (NumberTagged);
  1171.           TaggedSize := TaggedSize - FileInfoArray [i] . FileSize;
  1172.         END;
  1173.           END;
  1174.           DisplayInfo (directory, FirstDisplayed, TRUE);
  1175.           DisplaySummaryLine (directory);
  1176.         END;
  1177.       END; (* IF *)
  1178.     END; (* WITH *)
  1179.     ELSE
  1180.     END;
  1181.   END;
  1182. END OtherCommand;
  1183.  
  1184. PROCEDURE InitConfiguration ();
  1185. CONST
  1186.   filler = '                     ';
  1187. VAR
  1188.   count,
  1189.   handle: CARDINAL;
  1190.   color: ARRAY [0 .. 19] OF CHAR;
  1191.   ConfigurationFile: ARRAY [0 .. 65] OF CHAR;
  1192.   TheUtility: ARRAY [0 .. 79] OF CHAR;
  1193. BEGIN
  1194.   ReadEnvironment ('FILETOOL=', ConfigurationFile);
  1195.   ListUtility := 'List';
  1196.   EditUtility := 'BB';
  1197.   ConfigForeground := lightgrey;
  1198.   ConfigBackground := black;
  1199.   FOR count := 0 TO HIGH (AdditionalMenu) DO
  1200.     AdditionalMenu [count] . Command := filler;
  1201.   END;
  1202.   count := 0;
  1203.   IF ConfigurationFile [0] = 0C THEN
  1204.   ELSE
  1205.     IF FileExists (ConfigurationFile) THEN
  1206.       IF OpenFile (handle, ConfigurationFile) = NoError THEN
  1207.     REPEAT
  1208.       ReadStr (handle, TheUtility);
  1209.       CAPstr (TheUtility);
  1210.       IF Pos ('LIST=', TheUtility) # HIGH (TheUtility) + 1 THEN
  1211.         Copy (TheUtility,
  1212.           Pos ('LIST=', TheUtility) + 5,
  1213.           Length (TheUtility) - 5 - Pos ('LIST=', TheUtility),
  1214.           ListUtility);
  1215.       ELSIF Pos ('EDIT=', TheUtility) # HIGH (TheUtility) + 1 THEN
  1216.         Copy (TheUtility,
  1217.           Pos ('EDIT=', TheUtility) + 5,
  1218.           Length (TheUtility) - 5 - Pos ('EDIT=', TheUtility),
  1219.           EditUtility);
  1220.       ELSIF Pos ('OPTION=', TheUtility) # HIGH (TheUtility) + 1 THEN
  1221.         IF count <= HIGH (AdditionalMenu) THEN
  1222.           Copy (TheUtility,
  1223.             Pos ('OPTION=', TheUtility) + 7,
  1224.             Length (TheUtility) - 7 - Pos ('OPTION=', TheUtility),
  1225.             AdditionalMenu [count] . Command);
  1226.           Concat (AdditionalMenu [count] . Command, filler, AdditionalMenu [count] . Command);
  1227.           INC (count);
  1228.         END;
  1229.       ELSIF Pos ('FCOLOR=', TheUtility) # HIGH (TheUtility) + 1 THEN
  1230.         Copy (TheUtility,
  1231.           Pos ('FCOLOR=', TheUtility) + 7,
  1232.           Length (TheUtility) - 7 - Pos ('FCOLOR=', TheUtility),
  1233.           color);
  1234.         IF CompareStr (color, 'BLACK') = 0 THEN
  1235.           ConfigForeground := black;
  1236.         ELSIF CompareStr (color, 'BLUE') = 0 THEN
  1237.           ConfigForeground := blue;
  1238.         ELSIF CompareStr (color, 'GREEN') = 0 THEN
  1239.           ConfigForeground := green;
  1240.         ELSIF CompareStr (color, 'CYAN') = 0 THEN
  1241.           ConfigForeground := cyan;
  1242.         ELSIF CompareStr (color, 'RED') = 0 THEN
  1243.           ConfigForeground := red;
  1244.         ELSIF CompareStr (color, 'MAGENTA') = 0 THEN
  1245.           ConfigForeground := magenta;
  1246.         ELSIF CompareStr (color, 'BROWN') = 0 THEN
  1247.           ConfigForeground := brown;
  1248.         ELSIF CompareStr (color, 'LIGHTGREY') = 0 THEN
  1249.           ConfigForeground := lightgrey;
  1250.         ELSIF CompareStr (color, 'DARKGREY') = 0 THEN
  1251.           ConfigForeground := darkgrey;
  1252.         ELSIF CompareStr (color, 'LIGHTBLUE') = 0 THEN
  1253.           ConfigForeground := lightblue;
  1254.         ELSIF CompareStr (color, 'LIGHTGREEN') = 0 THEN
  1255.           ConfigForeground := lightgreen;
  1256.         ELSIF CompareStr (color, 'LIGHTCYAN') = 0 THEN
  1257.           ConfigForeground := lightcyan;
  1258.         ELSIF CompareStr (color, 'LIGHTRED') = 0 THEN
  1259.           ConfigForeground := lightred;
  1260.         ELSIF CompareStr (color, 'LIGHTMAGENTA') = 0 THEN
  1261.           ConfigForeground := lightmagenta;
  1262.         ELSIF CompareStr (color, 'YELLOW') = 0 THEN
  1263.           ConfigForeground := yellow;
  1264.         ELSIF CompareStr (color, 'BRIGHTWHITE') = 0 THEN
  1265.           ConfigForeground := brightwhite;
  1266.         ELSE
  1267.         END;
  1268.       ELSIF Pos ('BCOLOR=', TheUtility) # HIGH (TheUtility) + 1 THEN
  1269.         Copy (TheUtility,
  1270.           Pos ('BCOLOR=', TheUtility) + 7,
  1271.           Length (TheUtility) - 7 - Pos ('BCOLOR=', TheUtility),
  1272.           color);
  1273.         IF CompareStr (color, 'BLACK') = 0 THEN
  1274.           ConfigBackground := black;
  1275.         ELSIF CompareStr (color, 'BLUE') = 0 THEN
  1276.           ConfigBackground := blue;
  1277.         ELSIF CompareStr (color, 'GREEN') = 0 THEN
  1278.           ConfigBackground := green;
  1279.         ELSIF CompareStr (color, 'CYAN') = 0 THEN
  1280.           ConfigBackground := cyan;
  1281.         ELSIF CompareStr (color, 'RED') = 0 THEN
  1282.           ConfigBackground := red;
  1283.         ELSIF CompareStr (color, 'MAGENTA') = 0 THEN
  1284.           ConfigBackground := magenta;
  1285.         ELSIF CompareStr (color, 'BROWN') = 0 THEN
  1286.           ConfigBackground := brown;
  1287.         ELSIF CompareStr (color, 'LIGHTGREY') = 0 THEN
  1288.           ConfigBackground := lightgrey;
  1289.         ELSE
  1290.         END;
  1291.       ELSE
  1292.       END;
  1293.     UNTIL EndReached (handle);
  1294.       END;
  1295.     END;
  1296.   END;
  1297.   TextColor (ConfigForeground, ConfigBackground);
  1298. END InitConfiguration;
  1299.  
  1300. BEGIN
  1301.   MakeKeySet (' 13;27;9;E15;"c";"C";"t";"T";"o";"O" ',
  1302.           CopyMenuKeySet);
  1303.   MakeKeySet (' 13;27;9;E15;"c";"C";"o";"O" ',
  1304.           RenameMenuKeySet);
  1305.   MakeKeySet (' 13;27;9;E15;"c";"C";"m";"M";"s";"S";"o";"O" ',
  1306.           ExecuteMenuKeySet);
  1307.   MakeKeySet (' 13;27;9;E15;"a";"A";"b";"B";"c";"C";"d";"D";"e";"E";"f";"F";"g";"G";"h";"H";"i";"I";"j";"J" ',
  1308.           AdditionalMenuKeySet);
  1309.   MakeKeySet (' 13;27;9;E15;"n";"N";"e";"E";"d";"D";"s";"S" ',
  1310.           SortMenuKeySet);
  1311.   MakeKeySet (' 13;27;9;E15;"d";"D";"h";"H";"p";"P";"s";"S";"u";"U" ',
  1312.           AttributesMenuKeySet);
  1313.   MakeKeySet (' 13;27;9;E15;"c";"C";"d";"D";"l";"L";"r";"R";"s";"S";"t";"T";"u";"U" ',
  1314.           OtherMenuKeySet);
  1315.   InitConfiguration ();
  1316. END ToolMenuCommands.
  1317.