{************************************************} { } { Turbo Vision File Manager Demo } { Copyright (c) 1992 by Borland International } { } {************************************************} {$X+} unit DirView; { directory pane } interface uses Drivers, Objects, Views, Outline, Dos; type PDirectory = ^TDirectory; TDirectory = object(TObject) Dir: PString; SubDirectories: Boolean; Children: PDirectory; Next: PDirectory; constructor Init(const ADir: String); destructor Done; virtual; procedure Adjust(Expand: Boolean); function Expanded: Boolean; function GetSubdirectory(I: Integer): PDirectory; function GetName: String; function GetNumSubdirectories: Integer; end; type PDirectoryViewer = ^TDirectoryViewer; TDirectoryViewer = object(TOutlineViewer) SearchPos, OldFoc: Integer; Root: PDirectory; constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar; ARoot: PDirectory); destructor Done; virtual; procedure HandleEvent(var Event: TEvent); virtual; procedure Adjust(Node: Pointer; Expand: Boolean); virtual; function GetRoot: Pointer; virtual; function GetNumChildren(Node: Pointer): Integer; virtual; function GetChild(Node: Pointer; I: Integer): Pointer; virtual; function GetText(Node: Pointer): String; virtual; function IsExpanded(Node: Pointer): Boolean; virtual; function HasChildren(Node: Pointer): Boolean; virtual; function GetPalette: PPalette; virtual; end; implementation uses App, Equ, Globals, Tools; const CDirectoryViewer = CScroller + #3#8; { TDirectory } constructor TDirectory.Init(const ADir: String); var SR: SearchRec; begin inherited Init; Dir := NewStr(ADir); Next := nil; Children := nil; { See if any subdirectories exist in given directory } FindFirst(Dir^ + '\*.*', Directory, SR); while DosError = 0 do begin if (SR.Attr and Directory <> 0) and (SR.Name[1] <> '.') then begin SubDirectories := True; Exit; end; FindNext(SR); end; SubDirectories := False; end; destructor TDirectory.Done; begin if Children <> nil then Dispose(Children, Done); if Next <> nil then Dispose(Next, Done); DisposeStr(Dir); inherited Done; end; procedure TDirectory.Adjust(Expand: Boolean); var SR: SearchRec; PCur: ^PDirectory; begin if Expand then begin PCur := @Children; FindFirst(Dir^ + '\*.*', Directory, SR); while DosError = 0 do begin if (SR.Attr and Directory <> 0) and (SR.Name[1] <> '.') then begin PCur^ := New(PDirectory, Init(Dir^ + '\' + SR.Name)); PCur := @PCur^^.Next; end; FindNext(SR); end; PCur^ := nil; end else begin if Children <> nil then Dispose(Children, Done); Children := nil; end; end; function TDirectory.GetNumSubdirectories: Integer; var I: Integer; Cur: PDirectory; begin I := 0; Cur := Children; while Cur <> nil do begin Cur := Cur^.Next; Inc(I); end; GetNumSubdirectories := I; end; function TDirectory.GetSubdirectory(I: Integer): PDirectory; var Cur: PDirectory; begin Cur := Children; while (Cur <> nil) and (I <> 0) do begin Cur := Cur^.Next; Dec(I); end; GetSubdirectory := Cur; end; function TDirectory.GetName: String; var ADir: DirStr; AName: NameStr; AExt: ExtStr; begin FSplit(Dir^, ADir, AName, AExt); if (AName = '') and (AExt = '') then GetName := ADir else GetName := AName + AExt; end; function TDirectory.Expanded: Boolean; begin Expanded := Children <> nil; end; { TDirectoryViewer } constructor TDirectoryViewer.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar; ARoot: PDirectory); begin inherited Init(Bounds, AHScrollBar, AVScrollBar); Root := ARoot; Update; SearchPos := 0; OldFoc := 0; SetCursor(0, 0); ShowCursor; end; destructor TDirectoryViewer.Done; begin Dispose(Root, Done); inherited Done; end; procedure TDirectoryViewer.HandleEvent(var Event: TEvent); var SearchStr: String; Lev, Pos: Integer; Lns: LongInt; Flgs: Word; Dir: PDirectory; Mover: PFileMover; Where: TPoint; function UpStr(S: String): String; var I: Integer; begin for I := 1 to Length(S) do S[I] := UpCase(S[I]); UpStr := S; end; function IsAMatch(Cur: Pointer; Level, Position: Integer; Lines: LongInt; Flags: Word): Boolean; far; var S: String; begin IsAMatch := False; if UpStr(Copy(GetText(Cur),1, Length(SearchStr))) = SearchStr then begin IsAMatch := True; Pos := Position; Lev := Level; Lns := Lines; Flgs := Flags; end; end; function GetGraphParams(Cur: Pointer; Level, Position: Integer; Lines: LongInt; Flags: Word): Boolean; far; begin GetGraphParams := False; if Position = Foc then begin Lev := Level; Lns := Lines; Flgs := Flags; GetGraphParams := True; end; end; begin inherited HandleEvent(Event); if Event.What = evBroadcast then begin case Event.Command of cmGetCurrentDir: begin Dir := GetNode(Foc); PString(Event.InfoPtr)^ := Dir^.Dir^; ClearEvent(Event); end; cmItemDropped: begin Mover := Event.InfoPtr; if MouseInView(Mover^.Origin) then begin ClearEvent(Event); MakeLocal(Mover^.Origin, Where); Dir := GetNode(Where.Y + 1 + Delta.Y); DragDropCopy(Mover, Dir^.Dir^); end; end; else Exit; end; end; if (Event.What <> evBroadcast) and (Foc <> OldFoc) then SearchPos := 0; Pos := -1; case Event.What of evKeyDown: begin if (Event.KeyCode = kbBack) or ((Event.ScanCode <> 0) and (Event.CharCode in ['A'..'Z','a'..'z', '0'..'9'])) then begin if SearchPos > 0 then begin SearchStr := UpStr(GetText(GetNode(Foc))); SearchStr[0] := Char(SearchPos); end else SearchStr := ''; if Event.KeyCode = kbBack then begin if Length(SearchStr) > 0 then Dec(SearchStr[0]) else Exit; end else if Length(SearchStr) < 255 then begin Inc(SearchStr[0]); SearchStr[Length(SearchStr)] := UpCase(Event.CharCode); end; if FirstThat(@IsAMatch) <> nil then begin Focused(Pos); SearchPos := Length(SearchStr); Update; DrawView; end else Pos := -1; ClearEvent(Event); end; if Event.CharCode = '\' then begin Dir := PDirectory(GetNode(Foc)); if (not Dir^.Expanded) and HasChildren(Dir) then begin Dir^.Adjust(True); Update; DrawView; ClearEvent(Event); end; end; end; end; if (Foc <> OldFoc) or (Pos <> -1) then begin if Pos = -1 then FirstThat(@GetGraphParams); SetCursor(Length(GetGraph(Lev, Lns, Flgs)) + SearchPos, Foc - Delta.Y); Dir := GetNode(Foc); Message(Desktop, evBroadcast, cmNewDir, Dir^.Dir); OldFoc := Foc; end; end; procedure TDirectoryViewer.Adjust(Node: Pointer; Expand: Boolean); begin PDirectory(Node)^.Adjust(Expand); end; function TDirectoryViewer.GetRoot: Pointer; begin GetRoot := Root; end; function TDirectoryViewer.GetNumChildren(Node: Pointer): Integer; begin GetNumChildren := PDirectory(Node)^.GetNumSubDirectories; end; function TDirectoryViewer.GetChild(Node: Pointer; I: Integer): Pointer; begin GetChild := PDirectory(Node)^.GetSubdirectory(I); end; function TDirectoryViewer.GetText(Node: Pointer): String; begin GetText := PDirectory(Node)^.GetName; end; function TDirectoryViewer.IsExpanded(Node: Pointer): Boolean; begin IsExpanded := PDirectory(Node)^.Expanded; end; function TDirectoryViewer.HasChildren(Node: Pointer): Boolean; begin HasChildren := PDirectory(Node)^.SubDirectories; end; function TDirectoryViewer.GetPalette: PPalette; const NewPal: string[Length(CDirectoryViewer)] = CDirectoryViewer; begin GetPalette := @NewPal; end; end.