{************************************************} { } { Turbo Vision File Manager Demo } { Copyright (c) 1992 by Borland International } { } {************************************************} unit FileView; { File pane object } {$X+} {$V-} interface uses Drivers, Objects, Views, App, Dos, Dialogs, Memory, Globals, Equ, Tools, DragDrop; type PFileView = ^TFileView; TFileView = object(TDDList) Foc: Integer; Dir: PathStr; List: PFileList; DoneScanning: Boolean; Search: SearchRec; constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar); procedure HandleEvent(var Event: TEvent); virtual; destructor Done; virtual; function SearchForFiles(First: Boolean): Boolean; procedure ScanSingleFile(FileName: PathStr); function GetPalette : PPalette; virtual; procedure Draw; virtual; function GetText(Item: Integer; MaxLen: Integer): String; virtual; procedure SetState(AState: Word; Enable: Boolean); virtual; procedure PickUpItem(Item: Integer; Where: TPoint); virtual; end; implementation uses MsgBox; { TFileView } constructor TFileView.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar); begin inherited Init(Bounds, 1, AHScrollBar, AVScrollBar); List := New(PFileList, Init(30,10)); Dir := ''; DoneScanning := True; EventMask := EventMask or evIdle; Foc := 0; end; function TFileView.GetPalette: PPalette; const MyPal : String[length(CListViewer)] = #6#6#7#6#1; begin GetPalette := @MyPal; end; procedure TFileView.Draw; var B: TDrawBuffer; C: Word; begin inherited Draw; if List^.Count = 0 then begin C := GetColor(1); MoveChar(B, ' ', C, Size.X); MoveStr(B, RezStrings^.Get(sNoFiles), C); WriteLine(0, 0, Size.X, 1, B); end; end; function TFileView.GetText(Item: Integer; MaxLen: Integer): String; var F: PFileRec; S: String; Params: array[0..3] of Pointer; DOpt: Word; begin if Item < List^.Count then begin F := List^.At(Item); Params[0] := @F^.Name; Params[1] := @F^.Ext; Params[2] := Pointer(F^.Size); with ConfigRec do begin if DisplayFields and $1 <> 0 then FormatStr(S, ' %-8s%-4s %7d', Params) else FormatStr(S, ' %-8s%-4s', Params); if F^.Tagged then S[1] := TagChar; DOpt := (DisplayFields and $6) shr 1; { change 0xx0 -> 0,1,2,3 } { 0=none, 1=Date, 2=Time, 3=Date and Time } if DOpt > 0 then S := S + ' ' + FormatDateTime(F^.Time, DOpt); if (DisplayFields and $8) <> 0 then S := S + ' ' + FormatAttr(F^.Attr); end; if Length(S) > MaxLen then S[0] := Char(MaxLen); if ConfigRec.DisplayCase = 0 then LowerCase(S); GetText := S; end else GetText := ''; end; function TFileView.SearchForFiles(First: Boolean): Boolean; var F: PFileRec; begin SearchForFiles := False; if First then FindFirst(Dir + '\' + ConfigRec.FileMask, AnyFile, Search) else FindNext(Search); if DosError = 0 then begin if Search.Attr and UnwantedFiles = 0 then begin F := New(PFileRec, Init(Search)); List^.Insert(F); end; end else SearchForFiles := True; { done searching } end; procedure TFileView.ScanSingleFile(FileName: PathStr); var F: PFileRec; begin FindFirst(FileName, AnyFile, Search); if DosError = 0 then begin if (Search.Attr and UnwantedFiles = 0) then begin F := New(PFileRec, Init(Search)); List^.Insert(F); SetRange(List^.Count); DrawView; end; end; end; procedure TFileView.HandleEvent(var Event: TEvent); var F: PFileRec; P: PFileNameRec; ScanInfo: TScanInfo; Where: TPoint; Mover: PFileMover; I: Integer; WildCard: string[12]; R: TRect; procedure ReverseTags(F: PFileRec); far; begin F^.Toggle; Message(Owner, evBroadcast, cmTagChanged, F); end; procedure ClearTags(F: PFileRec); far; begin if F^.Tagged then begin F^.Toggle; Message(Owner, evBroadcast, cmTagChanged, F); end; end; procedure TagPerCard(F: PFileRec); far; begin if WildCardMatch(F^.Name + F^.Ext, WildCard) then begin F^.Tagged := True; Message(Owner, evBroadcast, cmTagChanged, F); end; end; function MatchFile(F: PFileRec): Boolean; far; begin P := Event.InfoPtr; MatchFile := (P^.Dir = Dir + '\') and (P^.Name = F^.Name) and (P^.Ext = F^.Ext); end; procedure CountBytes(F: PFileRec); far; begin Inc(ScanInfo.ScanBytes, F^.Size); end; begin inherited HandleEvent(Event); if Event.What = evBroadcast then begin case Event.Command of { Scan a new directory, or rescan current directory } cmNewDir, cmRescan : begin if Event.Command = cmNewDir then Dir := PString(Event.InfoPtr)^; Owner^.Last^.DrawView; {Force the frame to redraw } DoneScanning := False; List^.FreeAll; DoneScanning := SearchForFiles(True); { search for the first file } if (not DoneScanning) and LowMemory then begin DoneScanning := True; Application^.OutOfMemory; end; if DoneScanning then begin SetRange(List^.Count); DrawView; ScanInfo.ScanCount := List^.Count; ScanInfo.ScanBytes := 0; List^.ForEach(@CountBytes); Message(Owner, evBroadcast, cmScanComplete, @ScanInfo); end; if Event.Command = cmNewDir then ClearEvent(Event); end; { Mark the current file as tagged } cmListItemSelected : begin if List^.Count > 0 then begin F := List^.At(Focused); F^.Toggle; Message(Owner, evBroadcast, cmTagChanged, F); DrawView; ClearEvent(Event); end; end; { Reorder and redraw the list since the sort order may have changed } cmRefreshDisplay : begin PFileList(List)^.Reorder; DrawView; end; cmItemDropped : begin Mover := Event.InfoPtr; Desktop^.MakeGlobal(Mover^.Origin, Where); if MouseInView(Where) then begin ClearEvent(Event); DragDropCopy(Mover, Dir); end; end; end; { case } end; if Event.What = evIdle then begin if not DoneScanning then begin DoneScanning := SearchForFiles(False); if DoneScanning then begin SetRange(List^.Count); DrawView; ScanInfo.ScanCount := List^.Count; ScanInfo.ScanBytes := 0; List^.ForEach(@CountBytes); Message(Owner, evBroadcast, cmScanComplete, @ScanInfo); end; end; end; if Event.What = evCommand then begin case Event.Command of cmReverseTags : List^.ForEach(@ReverseTags); cmClearTags: List^.ForEach(@ClearTags); cmTagPerCard: begin R.Assign(0,0,35,8); R.Move((Desktop^.Size.X - R.B.X) div 2, (Desktop^.Size.Y - R.B.Y) div 2); WildCard := '*.*'; if InputBoxRect(R, 'Tag per wildcard', 'Wildcard', WildCard, 12) = cmOK then begin UpperCase(WildCard); List^.ForEach(@TagPerCard); end; end; else Exit; end; DrawView; ClearEvent(Event); end; end; procedure TFileView.PickUpItem(Item: Integer; Where: TPoint); var R: TRect; Mover: PMover; E: TEvent; Min, Max: TPoint; F: PFileRec; NewList: PCollection; S: SearchRec; function CloneFileRec(Orig: PFileRec): PFileRec; begin S.Name := Orig^.Name + Orig^.Ext; S.Attr := Orig^.Attr; S.Size := Orig^.Size; S.Time := Orig^.Time; CloneFileRec := New(PFileRec, Init(S)); end; procedure AddIfTagged(FileRec: PFileRec); far; begin if FileRec^.Tagged then NewList^.Insert(CloneFileRec(FileRec)); end; begin NewList := New(PCollection, Init(10, 5)); F := List^.At(Item); { are we dragging the tagged files? } if F^.Tagged then List^.ForEach(@AddIfTagged) else NewList^.Insert(CloneFileRec(F)); Dec(Where.Y); Mover := New(PFileMover, Init(Where, Dir, NewList)); Inc(Where.Y); Desktop^.Insert(Mover); Desktop^.GetExtent(R); E.What := evMouseDown; E.Where := Where; Min := Mover^.Size; Max := Min; Mover^.DragView(E, dmDragMove, R, Min, Max); Message(Desktop, evBroadcast, cmItemDropped, Mover); Dispose(Mover, Done); Dispose(NewList, Done); end; procedure TFileView.SetState(AState: Word; Enable: Boolean); procedure ShowScrollBar(SBar: PScrollBar); begin if (SBar <> nil) then if GetState(sfActive + sfSelected) then SBar^.Show else SBar^.Hide; end; begin inherited SetState(AState, Enable); if AState and (sfActive + sfSelected) <> 0 then begin ShowScrollBar(HScrollBar); ShowScrollBar(VScrollBar); end; end; destructor TFileView.Done; begin if List <> nil then Dispose(List, Done); inherited Done; end; end. { unit }