| 1 | Unit DirOutLn;
|
|---|
| 2 |
|
|---|
| 3 | Interface
|
|---|
| 4 |
|
|---|
| 5 | Uses
|
|---|
| 6 | SysUtils, Classes, Graphics, StdCtrls, Forms, Dialogs,
|
|---|
| 7 | Outline;
|
|---|
| 8 |
|
|---|
| 9 | type
|
|---|
| 10 | TDirectoryOutline=Class(TOutline)
|
|---|
| 11 | Private
|
|---|
| 12 | FDirectory:String;
|
|---|
| 13 | FDrive:Char;
|
|---|
| 14 | FOnChange:TNotifyEvent;
|
|---|
| 15 | FlOpen,FlClose:TBitmap;
|
|---|
| 16 | Private
|
|---|
| 17 | Procedure SetDrive(NewDrive:Char);
|
|---|
| 18 | Procedure SetDirectory(Const NewDir:String);
|
|---|
| 19 | Procedure FillLevel(Node:TOutlineNode);
|
|---|
| 20 | Protected
|
|---|
| 21 | Procedure BuildTree;Virtual;
|
|---|
| 22 | Procedure WalkTree(Const Dir:String);
|
|---|
| 23 | Procedure SetupShow;Override;
|
|---|
| 24 | Procedure Expand(Index: Longint);Override;
|
|---|
| 25 | Procedure BuildOneLevel(ParentLevel:Longint);Virtual;
|
|---|
| 26 | Procedure Change;Virtual;
|
|---|
| 27 | Public
|
|---|
| 28 | Procedure SetupComponent;Override;
|
|---|
| 29 | Destructor Destroy;Override;
|
|---|
| 30 | Procedure Click;Override;
|
|---|
| 31 | Public
|
|---|
| 32 | Property Drive:Char read FDrive write SetDrive;
|
|---|
| 33 | Property Directory:String read FDirectory write SetDirectory;
|
|---|
| 34 | Property Lines;
|
|---|
| 35 | Property OnChange:TNotifyEvent read FOnChange write FOnChange;
|
|---|
| 36 | End;
|
|---|
| 37 |
|
|---|
| 38 | Implementation
|
|---|
| 39 |
|
|---|
| 40 | {$R DirOutLn}
|
|---|
| 41 |
|
|---|
| 42 | Procedure TDirectoryOutline.Change;
|
|---|
| 43 | Begin
|
|---|
| 44 | If FOnChange<>Nil Then FOnChange(Self);
|
|---|
| 45 | End;
|
|---|
| 46 |
|
|---|
| 47 | Procedure TDirectoryOutline.FillLevel(Node:TOutlineNode);
|
|---|
| 48 | Var
|
|---|
| 49 | TempIndex:Longint;
|
|---|
| 50 | Root:ShortString;
|
|---|
| 51 | SearchRec: TSearchRec;
|
|---|
| 52 | Status:Integer;
|
|---|
| 53 | s,s1:String;
|
|---|
| 54 | Begin
|
|---|
| 55 | If Node.Data<>Nil Then exit; //already filled
|
|---|
| 56 | Root:=Node.FullPath;
|
|---|
| 57 | If Root[Length(Root)] In ['\','/'] Then dec(Root[0]);
|
|---|
| 58 |
|
|---|
| 59 | Status:=FindFirst(Root+'\*.*',faDirectory,SearchRec);
|
|---|
| 60 | While Status=0 Do
|
|---|
| 61 | Begin
|
|---|
| 62 | If SearchRec.Attr And faDirectory = faDirectory Then
|
|---|
| 63 | Begin
|
|---|
| 64 | If ((SearchRec.Name<>'.')And(SearchRec.Name<>'..')) Then //no .. and .
|
|---|
| 65 | Begin
|
|---|
| 66 | If Node.HasItems Then //must sort
|
|---|
| 67 | Begin
|
|---|
| 68 | TempIndex:=Node.GetFirstChild;
|
|---|
| 69 | s:=SearchRec.Name;
|
|---|
| 70 | UpcaseStr(s);
|
|---|
| 71 | If TempIndex<>-1 Then
|
|---|
| 72 | Begin
|
|---|
| 73 | s1:=Items[TempIndex].Text;
|
|---|
| 74 | UpcaseStr(s1);
|
|---|
| 75 | End;
|
|---|
| 76 | While (TempIndex<>-1)And(s1<s) Do
|
|---|
| 77 | Begin
|
|---|
| 78 | TempIndex:=Node.GetNextChild(TempIndex);
|
|---|
| 79 | If TempIndex<>-1 Then
|
|---|
| 80 | Begin
|
|---|
| 81 | s1:=Items[TempIndex].Text;
|
|---|
| 82 | UpcaseStr(s1);
|
|---|
| 83 | End;
|
|---|
| 84 | End;
|
|---|
| 85 | If TempIndex<>-1 Then Insert(TempIndex, SearchRec.Name)
|
|---|
| 86 | Else Add(Node.GetLastChild, SearchRec.Name);
|
|---|
| 87 | End
|
|---|
| 88 | Else AddChild(Node.Index,SearchRec.Name);
|
|---|
| 89 | End;
|
|---|
| 90 | End;
|
|---|
| 91 | Status:=FindNext(SearchRec);
|
|---|
| 92 | End;
|
|---|
| 93 |
|
|---|
| 94 | Node.Data:=Pointer(1); //mark item as processed
|
|---|
| 95 | end;
|
|---|
| 96 |
|
|---|
| 97 |
|
|---|
| 98 | Procedure TDirectoryOutline.BuildOneLevel(ParentLevel:Longint);
|
|---|
| 99 | Var Index:LongInt;
|
|---|
| 100 | RootNode:TOutlineNode;
|
|---|
| 101 | FList:TList;
|
|---|
| 102 | t:longint;
|
|---|
| 103 | Begin
|
|---|
| 104 | FillLevel(Items[ParentLevel]);
|
|---|
| 105 |
|
|---|
| 106 | RootNode := Items[ParentLevel];
|
|---|
| 107 | FList.Create;
|
|---|
| 108 | Index:=RootNode.GetFirstChild;
|
|---|
| 109 | While Index<>-1 Do
|
|---|
| 110 | Begin
|
|---|
| 111 | FList.Add(Items[Index]);
|
|---|
| 112 | Index:=RootNode.GetNextChild(Index);
|
|---|
| 113 | End;
|
|---|
| 114 |
|
|---|
| 115 | For t:=0 To FList.Count-1 Do FillLevel(TOutlineNode(FList[t]));
|
|---|
| 116 | FList.Destroy;
|
|---|
| 117 | End;
|
|---|
| 118 |
|
|---|
| 119 | Procedure TDirectoryOutline.SetupComponent;
|
|---|
| 120 | Begin
|
|---|
| 121 | Inherited SetupComponent;
|
|---|
| 122 | BorderStyle:=bsNone;
|
|---|
| 123 | FlOpen.Create;
|
|---|
| 124 | FlOpen.LoadFromResourceName('FolderOpen');
|
|---|
| 125 | FlClose.Create;
|
|---|
| 126 | FlClose.LoadFromResourceName('FolderClose');
|
|---|
| 127 | PictureOpen:=FlOpen;
|
|---|
| 128 | PictureClosed:=FlClose;
|
|---|
| 129 | PictureLeaf:=PictureClosed;
|
|---|
| 130 | PlusMinusSize.CX:=14;
|
|---|
| 131 | PlusMinusSize.CY:=14;
|
|---|
| 132 | ShowPlusMinus:=False;
|
|---|
| 133 | Name:='DirectoryOutline';
|
|---|
| 134 | End;
|
|---|
| 135 |
|
|---|
| 136 | Destructor TDirectoryOutline.Destroy;
|
|---|
| 137 | Begin
|
|---|
| 138 | Inherited Destroy;
|
|---|
| 139 |
|
|---|
| 140 | FlOpen.Destroy;
|
|---|
| 141 | FlClose.Destroy;
|
|---|
| 142 | End;
|
|---|
| 143 |
|
|---|
| 144 | Procedure TDirectoryOutline.Click;
|
|---|
| 145 | Begin
|
|---|
| 146 | inherited Click;
|
|---|
| 147 | Try
|
|---|
| 148 | If SelectedItem=-1 Then Beep(1200,400);
|
|---|
| 149 | Directory :=Items[SelectedItem].FullPath;
|
|---|
| 150 | Except
|
|---|
| 151 | End;
|
|---|
| 152 | End;
|
|---|
| 153 |
|
|---|
| 154 | Procedure TDirectoryOutline.SetDrive(NewDrive:Char);
|
|---|
| 155 | Begin
|
|---|
| 156 | FDrive:=Upcase(NewDrive);
|
|---|
| 157 | ChDir(FDrive+':');
|
|---|
| 158 | GetDir(0,FDirectory);
|
|---|
| 159 | If Not (csLoading In ComponentState) Then BuildTree;
|
|---|
| 160 | End;
|
|---|
| 161 |
|
|---|
| 162 | Procedure TDirectoryOutline.SetDirectory(Const NewDir:String);
|
|---|
| 163 | Var
|
|---|
| 164 | TempPath: ShortString;
|
|---|
| 165 | Node:TOutlineNode;
|
|---|
| 166 | t:LongInt;
|
|---|
| 167 |
|
|---|
| 168 | Function FindNode(Node:TOutlineNode):TOutlineNode;
|
|---|
| 169 | Var s:String;
|
|---|
| 170 | t:LongInt;
|
|---|
| 171 | Node1:TOutlineNode;
|
|---|
| 172 | Begin
|
|---|
| 173 | s:=Node.FullPath;
|
|---|
| 174 | UpcaseStr(s);
|
|---|
| 175 | If s=TempPath Then
|
|---|
| 176 | Begin
|
|---|
| 177 | result:=Node;
|
|---|
| 178 | exit;
|
|---|
| 179 | End;
|
|---|
| 180 |
|
|---|
| 181 | For t:=0 To Node.ItemCount-1 Do
|
|---|
| 182 | Begin
|
|---|
| 183 | Node1:=Node.Items[t];
|
|---|
| 184 | Node1:=FindNode(Node1);
|
|---|
| 185 | If Node1<>Nil Then
|
|---|
| 186 | Begin
|
|---|
| 187 | Result:=Node1;
|
|---|
| 188 | exit;
|
|---|
| 189 | End;
|
|---|
| 190 | End;
|
|---|
| 191 | Result:=Nil;
|
|---|
| 192 | End;
|
|---|
| 193 |
|
|---|
| 194 | Begin
|
|---|
| 195 | If ((NewDir='')Or(NewDir=FDirectory)) Then exit;
|
|---|
| 196 |
|
|---|
| 197 | TempPath := ExpandFileName(NewDir);
|
|---|
| 198 | If TempPath[Length(TempPath)] In ['\','/'] Then
|
|---|
| 199 | If Length(TempPath)>3 Then Dec(TempPath[0]);
|
|---|
| 200 |
|
|---|
| 201 | ChDir(TempPath);
|
|---|
| 202 | FDirectory:=TempPath;
|
|---|
| 203 | If FDirectory[1]<>Drive Then Drive:=FDirectory[1]
|
|---|
| 204 | Else
|
|---|
| 205 | Begin
|
|---|
| 206 | WalkTree(TempPath);
|
|---|
| 207 | Change;
|
|---|
| 208 | End;
|
|---|
| 209 |
|
|---|
| 210 | TempPath:=FDirectory;
|
|---|
| 211 | UpcaseStr(TempPath);
|
|---|
| 212 | For t:=0 To ItemCount-1 Do
|
|---|
| 213 | Begin
|
|---|
| 214 | Node:=Items[t];
|
|---|
| 215 | Node:=FindNode(Node);
|
|---|
| 216 | If Node<>Nil Then Break;
|
|---|
| 217 | End;
|
|---|
| 218 | If Node<>Nil Then
|
|---|
| 219 | If SelectedNode<>Node Then SelectedNode:=Node;
|
|---|
| 220 | End;
|
|---|
| 221 |
|
|---|
| 222 | Procedure TDirectoryOutline.SetupShow;
|
|---|
| 223 | Var CurDir:String;
|
|---|
| 224 | Begin
|
|---|
| 225 | Inherited SetupShow;
|
|---|
| 226 |
|
|---|
| 227 | If FDrive=#0 Then //test if unassigned
|
|---|
| 228 | Begin
|
|---|
| 229 | {$I-}
|
|---|
| 230 | GetDir(0, CurDir);
|
|---|
| 231 | {$I+}
|
|---|
| 232 | If IoResult<>0 Then exit;
|
|---|
| 233 | FDrive := Upcase(CurDir[1]);
|
|---|
| 234 | FDirectory := CurDir;
|
|---|
| 235 | End;
|
|---|
| 236 |
|
|---|
| 237 | BuildTree;
|
|---|
| 238 | End;
|
|---|
| 239 |
|
|---|
| 240 | Procedure TDirectoryOutline.BuildTree;
|
|---|
| 241 | Var
|
|---|
| 242 | RootIndex: Longint;
|
|---|
| 243 | Begin
|
|---|
| 244 | Clear;
|
|---|
| 245 | If FDrive=#0 Then exit;
|
|---|
| 246 | RootIndex:=AddChild(0,Drive+':');
|
|---|
| 247 | WalkTree(FDirectory);
|
|---|
| 248 | Change;
|
|---|
| 249 | End;
|
|---|
| 250 |
|
|---|
| 251 | Procedure TDirectoryOutline.WalkTree(Const Dir:String);
|
|---|
| 252 | Var
|
|---|
| 253 | b:LongInt;
|
|---|
| 254 | CurPath,NextDir,s:ShortString;
|
|---|
| 255 | TempItem,TempIndex: Longint;
|
|---|
| 256 | begin
|
|---|
| 257 | TempItem := 1; { start at root }
|
|---|
| 258 |
|
|---|
| 259 | CurPath := Dir;
|
|---|
| 260 | b:=Pos(':',CurPath);
|
|---|
| 261 | If b>0 then CurPath:=Copy(CurPath,b+1,255);
|
|---|
| 262 | If CurPath<>'' Then
|
|---|
| 263 | If CurPath[1]='\' Then System.Delete(CurPath,1,1);
|
|---|
| 264 |
|
|---|
| 265 | NextDir := CurPath;
|
|---|
| 266 | Repeat
|
|---|
| 267 | b:=Pos('\',CurPath);
|
|---|
| 268 | If b=0 Then b:=Pos('/',CurPath);
|
|---|
| 269 | If b > 0 then
|
|---|
| 270 | Begin
|
|---|
| 271 | NextDir:=Copy(CurPath,1,b-1);
|
|---|
| 272 | CurPath:=Copy(CurPath,b+1,255);
|
|---|
| 273 | End
|
|---|
| 274 | Else
|
|---|
| 275 | Begin
|
|---|
| 276 | NextDir:=CurPath;
|
|---|
| 277 | CurPath:='';
|
|---|
| 278 | End;
|
|---|
| 279 |
|
|---|
| 280 | Items[TempItem].Expanded:=True;
|
|---|
| 281 | TempIndex:=Items[TempItem].GetFirstChild;
|
|---|
| 282 | UpcaseStr(NextDir);
|
|---|
| 283 | If CurPath='' Then TempIndex:=-1
|
|---|
| 284 | Else While TempIndex<>-1 Do
|
|---|
| 285 | Begin
|
|---|
| 286 | s:=Items[TempIndex].Text;
|
|---|
| 287 | UpcaseStr(s);
|
|---|
| 288 | If s=NextDir Then Break;
|
|---|
| 289 | TempIndex:=Items[TempItem].GetNextChild(TempIndex);
|
|---|
| 290 | End;
|
|---|
| 291 | If TempIndex<>-1 Then TempItem:=TempIndex
|
|---|
| 292 | Else CurPath:=''; //break
|
|---|
| 293 | Until CurPath='';
|
|---|
| 294 | End;
|
|---|
| 295 |
|
|---|
| 296 | Procedure TDirectoryOutline.Expand(Index:Longint);
|
|---|
| 297 | Begin
|
|---|
| 298 | BuildOneLevel(Index);
|
|---|
| 299 | Inherited Expand(Index);
|
|---|
| 300 | End;
|
|---|
| 301 |
|
|---|
| 302 | initialization
|
|---|
| 303 | RegisterClasses([TDirectoryOutline]);
|
|---|
| 304 | end.
|
|---|