UnixDriveView.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include "UnixDriveView.h"
  6. #ifndef DESIGN_ONLY
  7. #include <Terminal.h>
  8. #include <RemoteFiles.h>
  9. #endif
  10. #pragma package(smart_init)
  11. //---------------------------------------------------------------------------
  12. static inline void ValidCtrCheck(TUnixDriveView *)
  13. {
  14. new TUnixDriveView(NULL);
  15. }
  16. //---------------------------------------------------------------------------
  17. namespace Unixdriveview
  18. {
  19. void __fastcall PACKAGE Register()
  20. {
  21. TComponentClass classes[1] = {__classid(TUnixDriveView)};
  22. RegisterComponents("Scp", classes, 0);
  23. }
  24. }
  25. //---------------------------------------------------------------------------
  26. __fastcall TUnixDriveView::TUnixDriveView(TComponent * Owner) :
  27. TCustomUnixDriveView(Owner)
  28. {
  29. }
  30. //---------------------------------------------------------------------------
  31. struct TNodeData
  32. {
  33. TRemoteFileList * FileList;
  34. TRemoteFile * File;
  35. AnsiString Directory;
  36. };
  37. //---------------------------------------------------------------------------
  38. __fastcall TCustomUnixDriveView::TCustomUnixDriveView(TComponent* Owner) :
  39. TCustomDriveView(Owner)
  40. {
  41. FTerminal = NULL;
  42. FRootName = Customunixdirview_SUnixDefaultRootName;
  43. FIgnoreChange = false;
  44. FPrevSelected = NULL;
  45. DDAllowMove = false;
  46. FShowInaccesibleDirectories = true;
  47. FDummyDragFile = NULL;
  48. }
  49. //---------------------------------------------------------------------------
  50. __fastcall TCustomUnixDriveView::~TCustomUnixDriveView()
  51. {
  52. Terminal = NULL;
  53. if (FDummyDragFile != NULL)
  54. {
  55. #ifndef DESIGN_ONLY
  56. SAFE_DESTROY(FDummyDragFile);
  57. #endif
  58. }
  59. }
  60. //---------------------------------------------------------------------------
  61. void __fastcall TCustomUnixDriveView::CreateWnd()
  62. {
  63. TCustomDriveView::CreateWnd();
  64. FDragDropFilesEx->TargetEffects = TDropEffectSet() << deCopy << deMove;
  65. }
  66. //---------------------------------------------------------------------------
  67. void __fastcall TCustomUnixDriveView::SetTerminal(TTerminal * value)
  68. {
  69. if (FTerminal != value)
  70. {
  71. FTerminal = value;
  72. Items->Clear();
  73. #ifndef DESIGN_ONLY
  74. if (FTerminal != NULL)
  75. {
  76. TStrings * FixedPaths = FTerminal->FixedPaths;
  77. if (FixedPaths != NULL)
  78. {
  79. for (int i = 0; i < FixedPaths->Count; i++)
  80. {
  81. LoadPath(FixedPaths->Strings[i]);
  82. }
  83. }
  84. }
  85. #endif
  86. }
  87. }
  88. //---------------------------------------------------------------------------
  89. void __fastcall TCustomUnixDriveView::SetDirView(TUnixDirView * Value)
  90. {
  91. if (FDirView != Value)
  92. {
  93. if (FDirView != NULL)
  94. {
  95. FDirView->DriveView = NULL;
  96. }
  97. FDirView = Value;
  98. if (FDirView != NULL)
  99. {
  100. FDirView->DriveView = this;
  101. }
  102. }
  103. }
  104. //---------------------------------------------------------------------------
  105. TCustomDirView * __fastcall TCustomUnixDriveView::GetCustomDirView()
  106. {
  107. return FDirView;
  108. }
  109. //---------------------------------------------------------------------------
  110. void __fastcall TCustomUnixDriveView::SetCustomDirView(TCustomDirView * Value)
  111. {
  112. SetDirView(dynamic_cast<TUnixDirView *>(Value));
  113. }
  114. //---------------------------------------------------------------------------
  115. bool __fastcall TCustomUnixDriveView::IsRootNameStored()
  116. {
  117. return (FRootName != Customunixdirview_SUnixDefaultRootName);
  118. }
  119. //---------------------------------------------------------------------------
  120. bool __fastcall TCustomUnixDriveView::NodeIsHidden(const TTreeNode * Node)
  121. {
  122. #ifndef DESIGN_ONLY
  123. TNodeData * Data = NodeData(Node);
  124. TRemoteFile * File = Data->File;
  125. return
  126. ((File != NULL) && File->IsHidden) ||
  127. ((File == NULL) && IsUnixHiddenFile(UnixExtractFileName(Data->Directory)));
  128. #else
  129. return false;
  130. #endif
  131. }
  132. //---------------------------------------------------------------------------
  133. bool __fastcall TCustomUnixDriveView::NodeCanDelete(TTreeNode * Node)
  134. {
  135. return (Selected == NULL) ||
  136. ((Selected != Node) && !Selected->HasAsParent(Node));
  137. }
  138. //---------------------------------------------------------------------------
  139. void __fastcall TCustomUnixDriveView::UpdatePath(TTreeNode * Node, bool Force,
  140. bool CanLoad)
  141. {
  142. #ifndef DESIGN_ONLY
  143. TNodeData * Data = NodeData(Node);
  144. AnsiString Path = Data->Directory;
  145. if (FTerminal->DirectoryFileList(Path, Data->FileList, CanLoad) ||
  146. ((Data->FileList != NULL) && Force))
  147. {
  148. TStringList * ChildrenDirs = new TStringList();
  149. try
  150. {
  151. ChildrenDirs->Sorted = true;
  152. ChildrenDirs->Duplicates = dupAccept;
  153. ChildrenDirs->CaseSensitive = true;
  154. bool HadChildren = (Node->Count > 0);
  155. if (HadChildren)
  156. {
  157. for (int i = 0; i < Node->Count; i++)
  158. {
  159. TTreeNode * ChildNode = Node->Item[i];
  160. TNodeData * ChildData = NodeData(ChildNode);
  161. ChildData->File = NULL;
  162. ChildrenDirs->AddObject(UnixExtractFileName(ChildData->Directory),
  163. ChildNode);
  164. }
  165. }
  166. for (int i = 0; i < Data->FileList->Count; i++)
  167. {
  168. TRemoteFile * File = Data->FileList->Files[i];
  169. if (File->IsDirectory && !File->IsParentDirectory && !File->IsThisDirectory &&
  170. (ShowHiddenDirs || !File->IsHidden) &&
  171. (ShowInaccesibleDirectories || !File->IsInaccesibleDirectory))
  172. {
  173. int ChildIndex = ChildrenDirs->IndexOf(File->FileName);
  174. if (ChildIndex >= 0)
  175. {
  176. TTreeNode * ChildNode =
  177. dynamic_cast<TTreeNode *>(ChildrenDirs->Objects[ChildIndex]);
  178. TNodeData * ChildData = NodeData(ChildNode);
  179. ChildData->File = File;
  180. UpdatePath(ChildNode, Force);
  181. }
  182. else
  183. {
  184. AnsiString ChildPath = UnixIncludeTrailingBackslash(Path) + File->FileName;
  185. assert(!IsUnixRootPath(ChildPath));
  186. LoadPathEasy(Node, ChildPath, File);
  187. }
  188. }
  189. }
  190. if (HadChildren)
  191. {
  192. for (int i = 0; i < ChildrenDirs->Count; i++)
  193. {
  194. TTreeNode * ChildNode = dynamic_cast<TTreeNode *>(ChildrenDirs->Objects[i]);
  195. TNodeData * ChildData = NodeData(ChildNode);
  196. if ((ChildData->File == NULL) && NodeCanDelete(ChildNode))
  197. {
  198. ChildNode->Delete();
  199. }
  200. }
  201. }
  202. Node->AlphaSort(false);
  203. }
  204. __finally
  205. {
  206. delete ChildrenDirs;
  207. }
  208. }
  209. else if (Force)
  210. {
  211. for (int i = Node->Count - 1; i >= 0; i--)
  212. {
  213. TTreeNode * ChildNode = Node->Item[i];
  214. TRemoteFile * File = NodeFile(ChildNode);
  215. if (!NodeCanDelete(ChildNode) ||
  216. ((ShowHiddenDirs || !NodeIsHidden(ChildNode)) &&
  217. (ShowInaccesibleDirectories || (File == NULL) || !File->IsInaccesibleDirectory)))
  218. {
  219. UpdatePath(ChildNode, true);
  220. }
  221. else
  222. {
  223. ChildNode->Delete();
  224. }
  225. }
  226. }
  227. #endif
  228. }
  229. //---------------------------------------------------------------------------
  230. TTreeNode * __fastcall TCustomUnixDriveView::LoadPathEasy(TTreeNode * Parent,
  231. AnsiString Path, TRemoteFile * File)
  232. {
  233. #ifndef DESIGN_ONLY
  234. assert(Path == UnixExcludeTrailingBackslash(Path));
  235. AnsiString DirName;
  236. if (IsUnixRootPath(Path))
  237. {
  238. DirName = RootName;
  239. }
  240. else
  241. {
  242. DirName = UnixExtractFileName(Path);
  243. }
  244. TTreeNode * Node = Items->AddChild(Parent, DirName);
  245. TNodeData * Data = new TNodeData();
  246. Node->Data = Data;
  247. Data->Directory = Path;
  248. Data->File = File;
  249. Data->FileList = NULL;
  250. UpdatePath(Node, true);
  251. return Node;
  252. #else
  253. return NULL;
  254. #endif
  255. }
  256. //---------------------------------------------------------------------------
  257. TTreeNode * __fastcall TCustomUnixDriveView::LoadPath(AnsiString Path)
  258. {
  259. #ifndef DESIGN_ONLY
  260. if (Path.IsEmpty())
  261. {
  262. Path = ROOTDIRECTORY;
  263. }
  264. TTreeNode * Node = FindNodeToPath(Path);
  265. if (Node == NULL)
  266. {
  267. Path = UnixExcludeTrailingBackslash(Path);
  268. TTreeNode * Parent = NULL;
  269. TRemoteFile * File = NULL;
  270. if (!IsUnixRootPath(Path))
  271. {
  272. Parent = LoadPath(UnixExtractFileDir(Path));
  273. }
  274. Node = FindNodeToPath(Path);
  275. if (Node == NULL)
  276. {
  277. // node still does not exist, this should happen only when
  278. // if the parent directory is not in cache
  279. if (Parent != NULL)
  280. {
  281. TRemoteFileList * ParentFileList = NodeFileList(Parent);
  282. if (ParentFileList != NULL)
  283. {
  284. File = ParentFileList->FindFile(UnixExtractFileName(Path));
  285. }
  286. }
  287. Node = LoadPathEasy(Parent, Path, File);
  288. if (Parent != NULL)
  289. {
  290. Parent->AlphaSort(false);
  291. }
  292. }
  293. else
  294. {
  295. UpdatePath(Node, false);
  296. }
  297. }
  298. else
  299. {
  300. UpdatePath(Node, false);
  301. }
  302. return Node;
  303. #else
  304. return NULL;
  305. #endif
  306. }
  307. //---------------------------------------------------------------------------
  308. void __fastcall TCustomUnixDriveView::LoadDirectory()
  309. {
  310. #ifndef DESIGN_ONLY
  311. assert(!FIgnoreChange);
  312. FIgnoreChange = true;
  313. try
  314. {
  315. Selected = LoadPath(FTerminal->Files->Directory);
  316. assert(Selected != NULL);
  317. FPrevSelected = Selected;
  318. }
  319. __finally
  320. {
  321. FIgnoreChange = false;
  322. FDirectoryLoaded = true;
  323. }
  324. #endif
  325. }
  326. //---------------------------------------------------------------------------
  327. TNodeData * __fastcall TCustomUnixDriveView::NodeData(const TTreeNode * Node)
  328. {
  329. assert(Node->Data != NULL);
  330. return static_cast<TNodeData*>(Node->Data);
  331. }
  332. //---------------------------------------------------------------------------
  333. TRemoteFileList * __fastcall TCustomUnixDriveView::NodeFileList(const TTreeNode * Node)
  334. {
  335. assert(Node->Data != NULL);
  336. return static_cast<TNodeData*>(Node->Data)->FileList;
  337. }
  338. //---------------------------------------------------------------------------
  339. TRemoteFile * __fastcall TCustomUnixDriveView::NodeFile(const TTreeNode * Node)
  340. {
  341. assert(Node->Data != NULL);
  342. return static_cast<TNodeData*>(Node->Data)->File;
  343. }
  344. //---------------------------------------------------------------------------
  345. TRemoteFile * __fastcall TCustomUnixDriveView::NodeFileForce(TTreeNode * Node)
  346. {
  347. TRemoteFile * File = NodeFile(Node);
  348. if (File == NULL)
  349. {
  350. #ifndef DESIGN_ONLY
  351. SAFE_DESTROY(FDummyDragFile);
  352. FDummyDragFile = new TRemoteDirectoryFile();
  353. FDummyDragFile->FileName = Node->Text;
  354. FDummyDragFile->FullFileName = NodePathName(Node);
  355. File = FDummyDragFile;
  356. #endif
  357. }
  358. return File;
  359. }
  360. //---------------------------------------------------------------------------
  361. void __fastcall TCustomUnixDriveView::Delete(TTreeNode * Node)
  362. {
  363. if (Node == FPrevSelected)
  364. {
  365. FPrevSelected = NULL;
  366. }
  367. TNodeData * Data = NULL;
  368. if (Node != NULL)
  369. {
  370. Data = NodeData(Node);
  371. }
  372. TCustomDriveView::Delete(Node);
  373. // delete file list at last, when we are sure that no child nodes exist
  374. if (Data != NULL)
  375. {
  376. #ifndef DESIGN_ONLY
  377. delete Data->FileList;
  378. #endif
  379. delete Data;
  380. }
  381. }
  382. //---------------------------------------------------------------------------
  383. void __fastcall TCustomUnixDriveView::Change(TTreeNode * Node)
  384. {
  385. #ifndef DESIGN_ONLY
  386. // During D&D Selected is set to NULL and then back to previous selection,
  387. // prevent actually changing directory in such case
  388. if (FIgnoreChange || (Node == NULL) || (Node == FPrevSelected))
  389. {
  390. TCustomDriveView::Change(Node);
  391. }
  392. else
  393. {
  394. if (FDirView != NULL)
  395. {
  396. // remember current directory, so it gets selected if we move to parent
  397. // directory
  398. FDirView->ContinueSession(true);
  399. }
  400. // if previous node is child to newly selected one, do not expand it.
  401. // it is either already expanded and it is even being collapsed.
  402. bool Expand = (FPrevSelected == NULL) || !FPrevSelected->HasAsParent(Node);
  403. FDirectoryLoaded = false;
  404. try
  405. {
  406. Terminal->ChangeDirectory(NodePathName(Node));
  407. TCustomDriveView::Change(Node);
  408. }
  409. __finally
  410. {
  411. if (FDirectoryLoaded)
  412. {
  413. FPrevSelected = Selected;
  414. if (Expand)
  415. {
  416. Selected->Expand(false);
  417. }
  418. }
  419. else
  420. {
  421. assert(!FIgnoreChange);
  422. FIgnoreChange = true;
  423. try
  424. {
  425. Selected = FPrevSelected;
  426. }
  427. __finally
  428. {
  429. FIgnoreChange = false;
  430. }
  431. }
  432. }
  433. }
  434. #else
  435. TCustomDriveView::Change(Node);
  436. #endif
  437. }
  438. //---------------------------------------------------------------------------
  439. void __fastcall TCustomUnixDriveView::PerformDragDropFileOperation(
  440. TTreeNode * Node, int Effect)
  441. {
  442. if (OnDDFileOperation)
  443. {
  444. assert(DragDropFilesEx->FileList->Count > 0);
  445. assert(Node != NULL);
  446. AnsiString SourceDirectory;
  447. AnsiString TargetDirectory;
  448. SourceDirectory = ExtractFilePath(DragDropFilesEx->FileList->Items[0]->Name);
  449. TargetDirectory = NodeData(Node)->Directory;
  450. bool DoFileOperation = true;
  451. OnDDFileOperation(this, Effect, SourceDirectory, TargetDirectory,
  452. DoFileOperation);
  453. }
  454. }
  455. //---------------------------------------------------------------------------
  456. void __fastcall TCustomUnixDriveView::DDChooseEffect(int KeyState, int & Effect)
  457. {
  458. // if any drop effect is allowed at all (e.g. no drop to self and drop to parent)
  459. if (Effect != DROPEFFECT_None)
  460. {
  461. if (DropTarget != NULL)
  462. {
  463. if ((KeyState & (MK_CONTROL | MK_SHIFT)) == 0)
  464. {
  465. Effect = DROPEFFECT_Copy;
  466. }
  467. }
  468. else
  469. {
  470. Effect = DROPEFFECT_None;
  471. }
  472. }
  473. TCustomDriveView::DDChooseEffect(KeyState, Effect);
  474. }
  475. //---------------------------------------------------------------------------
  476. void __fastcall TCustomUnixDriveView::UpdateDropTarget()
  477. {
  478. // should never be NULL
  479. if (DropTarget != NULL)
  480. {
  481. UpdatePath(DropTarget, false, true);
  482. }
  483. }
  484. //---------------------------------------------------------------------------
  485. void __fastcall TCustomUnixDriveView::UpdateDropSource()
  486. {
  487. // DragNode may be NULL if its parent directory was reloaded as result
  488. // of D&D operation and thus all child nodes are recreated
  489. if ((DragNode != NULL) && (DragNode->Parent != NULL))
  490. {
  491. UpdatePath(DragNode->Parent, false, true);
  492. }
  493. }
  494. //---------------------------------------------------------------------------
  495. TStrings * __fastcall TCustomUnixDriveView::DragFileList()
  496. {
  497. assert(DragNode != NULL);
  498. TStrings * FileList = new TStringList();
  499. try
  500. {
  501. #ifndef DESIGN_ONLY
  502. FileList->AddObject(ExcludeTrailingBackslash(NodePathName(DragNode)),
  503. NodeFileForce(DragNode));
  504. #endif
  505. }
  506. catch(...)
  507. {
  508. delete FileList;
  509. throw;
  510. }
  511. return FileList;
  512. }
  513. //---------------------------------------------------------------------------
  514. bool __fastcall TCustomUnixDriveView::DragCompleteFileList()
  515. {
  516. return true;
  517. }
  518. //---------------------------------------------------------------------------
  519. TDropEffectSet __fastcall TCustomUnixDriveView::DDSourceEffects()
  520. {
  521. TDropEffectSet Result;
  522. Result << deCopy;
  523. if (DDAllowMove)
  524. {
  525. Result << deMove;
  526. }
  527. return Result;
  528. }
  529. //---------------------------------------------------------------------------
  530. AnsiString __fastcall TCustomUnixDriveView::NodePathName(TTreeNode * Node)
  531. {
  532. // same as NodePath
  533. return NodeData(Node)->Directory;
  534. }
  535. //---------------------------------------------------------------------------
  536. void __fastcall TCustomUnixDriveView::ClearDragFileList(TFileList * FileList)
  537. {
  538. #ifndef DESIGN_ONLY
  539. if (FDummyDragFile != NULL)
  540. {
  541. SAFE_DESTROY(FDummyDragFile);
  542. }
  543. #endif
  544. TCustomDriveView::ClearDragFileList(FileList);
  545. }
  546. //---------------------------------------------------------------------------
  547. void __fastcall TCustomUnixDriveView::AddToDragFileList(TFileList * FileList,
  548. TTreeNode * Node)
  549. {
  550. AnsiString FileName = NodePathName(Node);
  551. TRemoteFile * File = NodeFileForce(Node);
  552. if (OnDDDragFileName != NULL)
  553. {
  554. OnDDDragFileName(this, File, FileName);
  555. }
  556. FileList->AddItem(NULL, FileName);
  557. }
  558. //---------------------------------------------------------------------------
  559. AnsiString __fastcall TCustomUnixDriveView::NodePath(TTreeNode * Node)
  560. {
  561. // same as NodePathName
  562. return NodeData(Node)->Directory;
  563. }
  564. //---------------------------------------------------------------------------
  565. bool __fastcall TCustomUnixDriveView::NodeIsRecycleBin(TTreeNode * /*Node*/)
  566. {
  567. return false;
  568. }
  569. //---------------------------------------------------------------------------
  570. bool __fastcall TCustomUnixDriveView::NodePathExists(TTreeNode * /*Node*/)
  571. {
  572. return true;
  573. }
  574. //---------------------------------------------------------------------------
  575. TColor __fastcall TCustomUnixDriveView::NodeColor(TTreeNode * Node)
  576. {
  577. assert(Node != NULL);
  578. TColor Result = static_cast<TColor>(clDefaultItemColor);
  579. #ifndef DESIGN_ONLY
  580. if (FDimmHiddenDirs && !Node->Selected)
  581. {
  582. if (NodeIsHidden(Node))
  583. {
  584. Result = clGrayText;
  585. }
  586. }
  587. #endif
  588. return Result;
  589. }
  590. //---------------------------------------------------------------------------
  591. Word __fastcall TCustomUnixDriveView::NodeOverlayIndexes(TTreeNode * Node)
  592. {
  593. #ifndef DESIGN_ONLY
  594. Word Result = oiNoOverlay;
  595. // Cannot query root node for file
  596. if (Node->Parent != NULL)
  597. {
  598. TRemoteFile * File = NodeFile(Node);
  599. if ((File != NULL) && (File->IsSymLink))
  600. {
  601. // broken link cannot probably happen anyway
  602. // as broken links are treated as files
  603. Result |= File->BrokenLink ? oiBrokenLink : oiLink;
  604. }
  605. }
  606. return Result;
  607. #else
  608. return 0;
  609. #endif
  610. }
  611. //---------------------------------------------------------------------------
  612. void __fastcall TCustomUnixDriveView::GetImageIndex(TTreeNode * Node)
  613. {
  614. TCustomDriveView::GetImageIndex(Node);
  615. Node->ImageIndex = StdDirIcon;
  616. Node->SelectedIndex = StdDirSelIcon;
  617. }
  618. //---------------------------------------------------------------------------
  619. TTreeNode * __fastcall TCustomUnixDriveView::FindNodeToPath(AnsiString Path)
  620. {
  621. TTreeNode * Result = NULL;
  622. #ifndef DESIGN_ONLY
  623. if (IsUnixRootPath(Path))
  624. {
  625. if (Items->Count > 0)
  626. {
  627. Result = Items->Item[0];
  628. }
  629. }
  630. else
  631. {
  632. Result = NULL;
  633. Path = UnixExcludeTrailingBackslash(Path);
  634. TTreeNode * Parent = NULL;
  635. if (!IsUnixRootPath(Path))
  636. {
  637. Parent = FindNodeToPath(UnixExtractFileDir(Path));
  638. }
  639. if ((Parent != NULL) && (Parent->Count > 0))
  640. {
  641. AnsiString DirName = UnixExtractFileName(Path);
  642. int StartIndex = 0;
  643. int EndIndex = Parent->Count - 1;
  644. while (true)
  645. {
  646. int Index = (StartIndex + EndIndex) / 2;
  647. AnsiString NodeDir = Parent->Item[Index]->Text;
  648. // lstrcmp is used by AlphaSort()
  649. int C = lstrcmp(DirName.c_str(), NodeDir.c_str());
  650. if (C == 0)
  651. {
  652. Result = Parent->Item[Index];
  653. break;
  654. }
  655. else if (C < 0)
  656. {
  657. if (Index == StartIndex)
  658. {
  659. break;
  660. }
  661. EndIndex = Index - 1;
  662. }
  663. else
  664. {
  665. if (Index == EndIndex)
  666. {
  667. break;
  668. }
  669. StartIndex = Index + 1;
  670. }
  671. }
  672. }
  673. }
  674. #endif
  675. return Result;
  676. }
  677. //---------------------------------------------------------------------------
  678. TTreeNode * __fastcall TCustomUnixDriveView::FindPathNode(AnsiString Path)
  679. {
  680. TTreeNode * Result = NULL;
  681. #ifndef DESIGN_ONLY
  682. if (Items->Count > 0)
  683. {
  684. do
  685. {
  686. Result = FindNodeToPath(Path);
  687. if (Result == NULL)
  688. {
  689. assert(!IsUnixRootPath(Path));
  690. Path = UnixExtractFileDir(UnixExcludeTrailingBackslash(Path));
  691. }
  692. }
  693. while (Result == NULL);
  694. }
  695. #endif
  696. return Result;
  697. }
  698. //---------------------------------------------------------------------------
  699. void __fastcall TCustomUnixDriveView::ValidateDirectoryEx(TTreeNode * /*Node*/,
  700. TRecursiveScan /*Recurse*/, bool /*NewDirs*/)
  701. {
  702. // nothing
  703. }
  704. //---------------------------------------------------------------------------
  705. void __fastcall TCustomUnixDriveView::RebuildTree()
  706. {
  707. if (Items->Count > 0)
  708. {
  709. UpdatePath(Items->Item[0], true);
  710. }
  711. }
  712. //---------------------------------------------------------------------------
  713. void __fastcall TCustomUnixDriveView::SetShowInaccesibleDirectories(bool value)
  714. {
  715. if (FShowInaccesibleDirectories != value)
  716. {
  717. FShowInaccesibleDirectories = value;
  718. RebuildTree();
  719. }
  720. }
  721. //---------------------------------------------------------------------------
  722. void __fastcall TCustomUnixDriveView::CMShowingChanged(TMessage & Message)
  723. {
  724. TCustomDriveView::Dispatch(&Message);
  725. if (Showing && (Terminal != NULL))
  726. {
  727. LoadDirectory();
  728. }
  729. }
  730. //---------------------------------------------------------------------------
  731. void __fastcall TCustomUnixDriveView::DisplayContextMenu(TTreeNode * /*Node*/,
  732. const TPoint & /*ScreenPos*/)
  733. {
  734. // TODO
  735. }
  736. //---------------------------------------------------------------------------
  737. void __fastcall TCustomUnixDriveView::DisplayPropertiesMenu(TTreeNode * /*Node*/)
  738. {
  739. // TODO
  740. }