home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / diredit.zip / DirectoryEdit.PAS next >
Pascal/Delphi Source File  |  1999-08-23  |  4KB  |  181 lines

  1. Unit DirectoryEdit;
  2. // An edit box that will act as a directory
  3. // changer, with tab completion and enter
  4. // selecting a dir.
  5. Interface
  6.  
  7. Uses
  8.   Classes, Forms, StdCtrls, SysUtils;
  9.  
  10. Type
  11.   TNotifyDirChange = procedure( NewDir: string ) of object;
  12.  
  13.   TDirectoryEdit=Class(TEdit)
  14.   Protected
  15.     FCompletionIndex: longint;
  16.     FCompletionStartPath: string;
  17.     FOnChangeDir: TNotifyDirChange;
  18.     FCompletionSearch: TSearchRec;
  19.     Procedure SetupComponent; Override;
  20.     Procedure ScanEvent( Var KeyCode: TKeyCode;
  21.                          RepeatCount: Byte ); override;
  22.     Procedure CharEvent( Var Key: Char;
  23.                          RepeatCount: Byte ); override;
  24.   Public
  25.     Destructor Destroy; Override;
  26.   Published
  27.     property OnChangeDirectory: TNotifyDirChange read FOnChangeDir write FOnChangeDir;
  28.   End;
  29.  
  30. // Function returns true if directory Dir exists
  31. Function DirectoryExists( Dir: string ): boolean;
  32.  
  33. Exports
  34.   TDirectoryEdit,'User','diredit.bmp';
  35.  
  36. Implementation
  37.  
  38. Uses
  39.   PMWIN, BseDos;
  40.  
  41. Function DirectoryExists( Dir: string ):boolean;
  42. Var
  43.   SearchRec: TSearchRec;
  44.   rc: longint;
  45.   DriveMap: LongWord;
  46.   ActualDrive: LongWord;
  47.   Drive: Char;
  48.   DriveNum: longword;
  49.   DriveBit: longword;
  50. Begin
  51.   Result:= false;
  52.   if Dir = '' then
  53.   begin
  54.     Result:= true;
  55.     exit;
  56.   end;
  57.   // remove slash off end if present
  58.   if Dir[ length( dir ) ] in ['\','/'] then
  59.     Delete( Dir, length( Dir ), 1 );
  60.  
  61.   if length( Dir ) = 2 then
  62.     if Dir[ 2 ] = ':' then
  63.     begin
  64.       // a drive only has been specified, see if it exists
  65.       Drive:= UpCase( Dir[ 1 ] );
  66.       if ( Drive < 'A' ) or ( Drive > 'Z' ) then
  67.         exit;
  68.       DosQueryCurrentDisk( ActualDrive, DriveMap );
  69.       DriveNum:= Ord( Drive ) - Ord( 'A' ) + 1; // A -> 1, B -> 2...
  70.       DriveBit:= 1 shl (DriveNum-1); // 2^DriveNum
  71.       if ( DriveMap and ( DriveBit ) > 0 ) then
  72.         // Yes drive exists
  73.         Result:= true;
  74.       exit;
  75.     end;
  76.  
  77.   rc:= FindFirst( Dir, faAnyFile, SearchRec );
  78.   if rc = 0 then
  79.     if ( SearchRec.Attr and faDirectory )>0 then
  80.       Result:= true;
  81.   FindClose( SearchRec );
  82. End;
  83.  
  84. Procedure TDirectoryEdit.SetupComponent;
  85. Begin
  86.   Inherited SetupComponent;
  87.   FCompletionIndex:= 0;
  88.   Name:= 'DirectoryEdit';
  89. End;
  90.  
  91. Destructor TDirectoryEdit.Destroy;
  92. Begin
  93.   Inherited Destroy;
  94. End;
  95.  
  96. Procedure TDirectoryEdit.ScanEvent( Var KeyCode: TKeyCode;
  97.                                     RepeatCount: Byte );
  98. Var
  99.   Entry: string;
  100.   rc: longint;
  101.   Dir: string;
  102. Begin
  103.   if KeyCode = kbTab then
  104.   begin
  105.     KeyCode:= kbNull;
  106.     // want to use tab for completion
  107.     if FCompletionIndex = 0 then
  108.     begin
  109.       Entry:= Text;
  110.       Dir:= ExtractFilePath( Entry );
  111.       // starting a completion sequence.
  112.       rc:= FindFirst( Entry+'*',
  113.                       faDirectory,
  114.                       FCompletionSearch );
  115.       FCompletionStartPath:= Dir;
  116.     end
  117.     else
  118.     begin
  119.       // tab repeated; continuing
  120.       rc:= FindNext( FCompletionSearch );
  121.     end;
  122.     while     ( rc = 0 )
  123.           and ( ( FCompletionSearch.Attr and faDirectory ) = 0 )
  124.            or ( FCompletionSearch.Name='.' )
  125.            or ( FCompletionSearch.Name='..' ) do
  126.       rc:= FindNext( FCompletionSearch );
  127.  
  128.     if rc = 0 then
  129.     begin
  130.       // found summat
  131.       Text:= FCompletionStartPath + FCompletionSearch.Name+'\';
  132.     end
  133.     else
  134.     begin
  135.       // nothing more
  136.       Beep( 1000, 50 );
  137.     end;
  138.     inc( FCompletionIndex );
  139.   end
  140.   else
  141.   begin
  142.     // not a tab
  143.     if FCompletionIndex > 0 then
  144.       FindClose( FCompletionSearch );
  145.     FCompletionIndex:= 0;
  146.     if KeyCode =  kb_VK + VK_NEWLINE then
  147.     begin
  148.       KeyCode:= kbNull;
  149.       // enter key pressed - change dir
  150.       if DirectoryExists( Text ) then
  151.       begin
  152.         if FOnChangeDir <> nil then
  153.            FOnChangeDir( Text )
  154.       end
  155.       else
  156.         Beep( 1000, 50 );
  157.     end
  158.     else if KeyCode = kbCtrlTab then
  159.     begin
  160.        // fake a normal focus shift
  161.        KeyCode:= kbTab;
  162.        Parent.ScanEvent( KeyCode, 1 );
  163.        KeyCode:= kbNull;
  164.     end;
  165.   end;
  166. End;
  167.  
  168. Procedure TDirectoryEdit.CharEvent( Var Key: Char;
  169.                                     RepeatCount: Byte );
  170. Begin
  171.   if FCompletionIndex > 0 then
  172.     FindClose( FCompletionSearch );
  173.   FCompletionIndex:= 0;
  174. End;
  175.  
  176. Initialization
  177.   {Register classes}
  178.   RegisterClasses([TDirectoryEdit]);
  179. End.
  180.  
  181.