UnixDirView.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include "UnixDirView.h"
  6. #include "UnixDriveView.h"
  7. #include <FileCtrl.hpp>
  8. #ifndef DESIGN_ONLY
  9. #include <CoreMain.h>
  10. #include <Terminal.h>
  11. #include <WinConfiguration.h>
  12. #endif
  13. #pragma package(smart_init)
  14. #ifndef DESIGN_ONLY
  15. #define ITEMFILE ((TRemoteFile *)(Item->Data))
  16. #define ASSERT_VALID_ITEM assert(Item && Item->Data && Terminal); assert(Terminal->Files->IndexOf(ITEMFILE) >= 0)
  17. #endif
  18. //---------------------------------------------------------------------------
  19. static inline void ValidCtrCheck(TUnixDirView *)
  20. {
  21. new TUnixDirView(NULL);
  22. }
  23. //---------------------------------------------------------------------------
  24. namespace Unixdirview
  25. {
  26. void __fastcall PACKAGE Register()
  27. {
  28. TComponentClass classes[1] = {__classid(TUnixDirView)};
  29. RegisterComponents("Scp", classes, 0);
  30. }
  31. }
  32. //---------------------------------------------------------------------------
  33. #ifndef DESIGN_ONLY
  34. #define RFILE(N) ((TRemoteFile *)(Item ## N->Data))
  35. int __stdcall CompareDirectories(TListItem *Item1, TListItem *Item2, TUnixDirView *DirView)
  36. {
  37. // Because CompareDirectories is called from each other compare functions
  38. // it's sufficient to check pointers only here (see below)
  39. assert(DirView && Item1 && RFILE(1) && Item2 && RFILE(2));
  40. if (RFILE(1)->IsParentDirectory && !RFILE(2)->IsParentDirectory) return -1;
  41. else
  42. if (!RFILE(1)->IsParentDirectory && RFILE(2)->IsParentDirectory) return 1;
  43. else
  44. if (DirView->DirsOnTop &&
  45. RFILE(1)->IsDirectory && !RFILE(2)->IsDirectory) return -1;
  46. else
  47. if (DirView->DirsOnTop &&
  48. !RFILE(1)->IsDirectory && RFILE(2)->IsDirectory) return 1;
  49. else
  50. return 0;
  51. }
  52. //---------------------------------------------------------------------------
  53. #define DEFINE_COMPARE_FUNC_EX(PROPERTY, NAME, COMPAREFUNC, FALLBACK) \
  54. int __stdcall Compare ## NAME(TListItem *Item1, TListItem *Item2, TUnixDirView *DirView) \
  55. { \
  56. int Result = CompareDirectories(Item1, Item2, DirView); \
  57. if (!Result) \
  58. { \
  59. Result = COMPAREFUNC(RFILE(1)->PROPERTY, RFILE(2)->PROPERTY); \
  60. if (Result == 0) \
  61. { \
  62. Result = FALLBACK(RFILE(1)->FileName, RFILE(2)->FileName); \
  63. } \
  64. if (!DirView->UnixColProperties->SortAscending) Result = -Result; \
  65. } \
  66. return Result; \
  67. }
  68. #define DEFINE_COMPARE_FUNC(PROPERTY, COMPAREFUNC) \
  69. DEFINE_COMPARE_FUNC_EX(PROPERTY, PROPERTY, COMPAREFUNC, AnsiCompareText)
  70. #define COMPARE_NUMBER(Num1, Num2) ( Num1 < Num2 ? -1 : ( Num1 > Num2 ? 1 : 0) )
  71. #define COMPARE_DUMMY(X1, X2) 0
  72. #define COMPARE_TOKEN(Token1, Token2) Token1.Compare(Token2)
  73. //---------------------------------------------------------------------------
  74. DEFINE_COMPARE_FUNC_EX(FileName, ItemFileName, AnsiCompareText, COMPARE_DUMMY);
  75. DEFINE_COMPARE_FUNC(Size, COMPARE_NUMBER);
  76. DEFINE_COMPARE_FUNC(Modification, COMPARE_NUMBER);
  77. DEFINE_COMPARE_FUNC(RightsStr, AnsiCompareText);
  78. DEFINE_COMPARE_FUNC(Owner, COMPARE_TOKEN);
  79. DEFINE_COMPARE_FUNC(Group, COMPARE_TOKEN);
  80. DEFINE_COMPARE_FUNC(Extension, AnsiCompareText);
  81. DEFINE_COMPARE_FUNC(LinkTo, AnsiCompareText);
  82. DEFINE_COMPARE_FUNC(TypeName, AnsiCompareText);
  83. //---------------------------------------------------------------------------
  84. #undef DEFINE_COMPARE_FUNC
  85. #undef COMPARE_NUMBER
  86. #undef RFILE
  87. #endif
  88. //---------------------------------------------------------------------------
  89. #define HOMEDIRECTORY ""
  90. //---------------------------------------------------------------------------
  91. __fastcall TUnixDirView::TUnixDirView(TComponent* Owner)
  92. : TCustomUnixDirView(Owner)
  93. {
  94. #ifndef DESIGN_ONLY
  95. FTerminal = NULL;
  96. #endif
  97. FCaseSensitive = true;
  98. DDAllowMove = false;
  99. FShowInaccesibleDirectories = true;
  100. FFullLoad = false;
  101. FDriveView = NULL;
  102. FInvalidNameChars = "/";
  103. }
  104. //---------------------------------------------------------------------------
  105. __fastcall TUnixDirView::~TUnixDirView()
  106. {
  107. #ifndef DESIGN_ONLY
  108. Terminal = NULL;
  109. #endif
  110. }
  111. //---------------------------------------------------------------------------
  112. void __fastcall TUnixDirView::DisplayContextMenu(const TPoint &Where)
  113. {
  114. bool Handled = false;
  115. if (OnContextPopup) OnContextPopup(this, ScreenToClient(Where), Handled);
  116. if (!Handled)
  117. {
  118. if (PopupMenu && !PopupMenu->AutoPopup)
  119. PopupMenu->Popup(Where.x, Where.y);
  120. }
  121. }
  122. //---------------------------------------------------------------------------
  123. void __fastcall TUnixDirView::DisplayPropertiesMenu()
  124. {
  125. if (OnDisplayProperties) OnDisplayProperties(this);
  126. }
  127. //---------------------------------------------------------------------------
  128. void __fastcall TUnixDirView::ExecuteFile(TListItem * Item)
  129. {
  130. #ifndef DESIGN_ONLY
  131. ASSERT_VALID_ITEM;
  132. if (ITEMFILE->IsDirectory ||
  133. !Terminal->ResolvingSymlinks)
  134. {
  135. PathChanging(true);
  136. ChangeDirectory(ITEMFILE->FileName);
  137. }
  138. else
  139. {
  140. if (ItemFocused != Item) ItemFocused = Item;
  141. DisplayPropertiesMenu();
  142. }
  143. #endif
  144. }
  145. //---------------------------------------------------------------------------
  146. void __fastcall TUnixDirView::ExecuteParentDirectory()
  147. {
  148. PathChanging(true);
  149. #ifndef DESIGN_ONLY
  150. ChangeDirectory(PARENTDIRECTORY);
  151. #endif
  152. }
  153. //---------------------------------------------------------------------------
  154. void __fastcall TUnixDirView::ExecuteHomeDirectory()
  155. {
  156. #ifndef DESIGN_ONLY
  157. // don't select any directory
  158. PathChanging(false);
  159. AnsiString APath = Terminal->SessionData->RemoteDirectory;
  160. if (WinConfiguration->DefaultDirIsHome && !APath.IsEmpty() &&
  161. !Terminal->SessionData->UpdateDirectories)
  162. {
  163. if (APath[1] != '/')
  164. {
  165. Terminal->BeginTransaction();
  166. try
  167. {
  168. ChangeDirectory(HOMEDIRECTORY);
  169. ChangeDirectory(APath);
  170. }
  171. __finally
  172. {
  173. Terminal->EndTransaction();
  174. }
  175. }
  176. else
  177. {
  178. ChangeDirectory(APath);
  179. }
  180. }
  181. else
  182. {
  183. ChangeDirectory(HOMEDIRECTORY);
  184. }
  185. #endif
  186. }
  187. //---------------------------------------------------------------------------
  188. void __fastcall TUnixDirView::ReloadDirectory()
  189. {
  190. #ifndef DESIGN_ONLY
  191. FLastPath = "";
  192. DoAnimation(true);
  193. Terminal->ReloadDirectory();
  194. #endif
  195. }
  196. //---------------------------------------------------------------------------
  197. void __fastcall TUnixDirView::ExecuteRootDirectory()
  198. {
  199. #ifndef DESIGN_ONLY
  200. // We set LastPath to top directory, so it will be selected
  201. // after entering root directory
  202. // DISABLED: see PathChanged(): back moves to top directory, not to current
  203. PathChanging(false);
  204. ChangeDirectory(ROOTDIRECTORY);
  205. #endif
  206. }
  207. //---------------------------------------------------------------------------
  208. bool __fastcall TUnixDirView::ItemIsDirectory(TListItem * Item)
  209. {
  210. #ifndef DESIGN_ONLY
  211. ASSERT_VALID_ITEM;
  212. return ITEMFILE->IsDirectory;
  213. #else
  214. return false;
  215. #endif
  216. }
  217. //---------------------------------------------------------------------------
  218. bool __fastcall TUnixDirView::ItemIsFile(TListItem * Item)
  219. {
  220. #ifndef DESIGN_ONLY
  221. ASSERT_VALID_ITEM;
  222. return !(ITEMFILE->IsParentDirectory);
  223. #else
  224. return false;
  225. #endif
  226. }
  227. //---------------------------------------------------------------------------
  228. bool __fastcall TUnixDirView::ItemIsParentDirectory(TListItem * Item)
  229. {
  230. #ifndef DESIGN_ONLY
  231. ASSERT_VALID_ITEM;
  232. return ITEMFILE->IsParentDirectory;
  233. #else
  234. return false;
  235. #endif
  236. }
  237. //---------------------------------------------------------------------------
  238. AnsiString __fastcall TUnixDirView::ItemFileName(TListItem * Item)
  239. {
  240. #ifndef DESIGN_ONLY
  241. ASSERT_VALID_ITEM;
  242. return ITEMFILE->FileName;
  243. #else
  244. return AnsiString();
  245. #endif
  246. }
  247. //---------------------------------------------------------------------------
  248. __int64 __fastcall TUnixDirView::ItemFileSize(TListItem * Item)
  249. {
  250. #ifndef DESIGN_ONLY
  251. ASSERT_VALID_ITEM;
  252. return ITEMFILE->IsDirectory ? 0 : ITEMFILE->Size;
  253. #else
  254. return 0;
  255. #endif
  256. }
  257. //---------------------------------------------------------------------------
  258. AnsiString __fastcall TUnixDirView::ItemFullFileName(TListItem * Item)
  259. {
  260. #ifndef DESIGN_ONLY
  261. ASSERT_VALID_ITEM;
  262. return ITEMFILE->FullFileName;
  263. #else
  264. return AnsiString();
  265. #endif
  266. }
  267. //---------------------------------------------------------------------------
  268. int __fastcall TUnixDirView::ItemImageIndex(TListItem * Item, bool /*Cache*/)
  269. {
  270. #ifndef DESIGN_ONLY
  271. ASSERT_VALID_ITEM;
  272. // TCustomDirView::ItemImageIndex is used for icon caching
  273. // so we don't need it here. But it's implemented anyway.
  274. return ITEMFILE->IconIndex;
  275. #else
  276. return 0;
  277. #endif
  278. }
  279. //---------------------------------------------------------------------------
  280. bool __fastcall TUnixDirView::ItemMatchesFilter(TListItem * Item,
  281. const TFileFilter &Filter)
  282. {
  283. #ifndef DESIGN_ONLY
  284. ASSERT_VALID_ITEM;
  285. TRemoteFile *File = ITEMFILE;
  286. int Attr = File->Attr;
  287. return
  288. ((Attr & Filter.IncludeAttr) == Filter.IncludeAttr) &&
  289. ((Attr & Filter.ExcludeAttr) == 0) &&
  290. ((!File->IsDirectory) || Filter.Directories) &&
  291. ((Filter.FileSizeFrom == 0) || (File->Size >= Filter.FileSizeFrom)) &&
  292. ((Filter.FileSizeTo == 0) || (File->Size <= Filter.FileSizeTo)) &&
  293. ((!(int)Filter.ModificationFrom) || (File->Modification >= Filter.ModificationFrom)) &&
  294. ((!(int)Filter.ModificationTo) || (File->Modification <= Filter.ModificationTo)) &&
  295. ((Filter.Masks.IsEmpty()) ||
  296. FileNameMatchesMasks(File->FileName, File->IsDirectory, File->Size, Filter.Masks));
  297. #else
  298. return false;
  299. #endif
  300. }
  301. //---------------------------------------------------------------------------
  302. Word __fastcall TUnixDirView::ItemOverlayIndexes(TListItem * Item)
  303. {
  304. #ifndef DESIGN_ONLY
  305. ASSERT_VALID_ITEM;
  306. Word Result = TCustomDirView::ItemOverlayIndexes(Item);
  307. if (ITEMFILE->IsParentDirectory)
  308. {
  309. Result |= oiDirUp;
  310. }
  311. if (ITEMFILE->IsSymLink)
  312. {
  313. Result |= ITEMFILE->BrokenLink ? oiBrokenLink : oiLink;
  314. }
  315. return Result;
  316. #else
  317. return 0;
  318. #endif
  319. }
  320. //---------------------------------------------------------------------------
  321. void __fastcall TUnixDirView::LoadFiles()
  322. {
  323. #ifndef DESIGN_ONLY
  324. assert(Terminal);
  325. if (DirOK)
  326. {
  327. // it's enough if we reach this point, we don't require that loading files into
  328. // list succeeded. FDirLoadedAfterChangeDir == false tells only that
  329. // loding file list from server failed, not loading into listview
  330. FDirLoadedAfterChangeDir = true;
  331. FFilesSize = 0;
  332. FHasParentDir = false;
  333. int VisibleFiles = 0;
  334. FHiddenCount = 0;
  335. FFilteredCount = 0;
  336. for (int Index = 0; Index < Terminal->Files->Count; Index++)
  337. {
  338. TRemoteFile *File = Terminal->Files->Files[Index];
  339. assert(File);
  340. TListItem *Item;
  341. if ((!ShowHiddenFiles && File->IsHidden) ||
  342. (!ShowInaccesibleDirectories && File->IsInaccesibleDirectory))
  343. {
  344. FHiddenCount++;
  345. }
  346. else if (!Mask.IsEmpty() &&
  347. !File->IsDirectory &&
  348. !FileNameMatchesMasks(File->FileName, false, File->Size, Mask))
  349. {
  350. FFilteredCount++;
  351. }
  352. else
  353. {
  354. VisibleFiles++;
  355. if (!File->IsDirectory) FFilesSize += File->Size;
  356. if (File->IsParentDirectory) FHasParentDir = true;
  357. Item = Items->Add();
  358. Item->Data = File;
  359. Item->Caption = File->FileName;
  360. if (FFullLoad)
  361. {
  362. // this is out of date
  363. // (missing columns and does not update then file properties are loaded)
  364. Item->ImageIndex = File->IconIndex;
  365. Item->SubItems->Add((!File->IsDirectory ? FormatFloat("#,##0", File->Size) : AnsiString()));
  366. Item->SubItems->Add(File->UserModificationStr);
  367. Item->SubItems->Add(File->RightsStr);
  368. Item->SubItems->Add(File->Owner.DisplayText);
  369. Item->SubItems->Add(File->Group.DisplayText);
  370. Item->SubItems->Add(File->Extension);
  371. }
  372. }
  373. }
  374. if (OwnerData)
  375. {
  376. Items->Count = VisibleFiles;
  377. }
  378. }
  379. #endif
  380. }
  381. //---------------------------------------------------------------------------
  382. void __fastcall TUnixDirView::GetDisplayInfo(TListItem * Item, tagLVITEMA &DispInfo)
  383. {
  384. if (!FFullLoad)
  385. {
  386. #ifndef DESIGN_ONLY
  387. TRemoteFile * File = ITEMFILE;
  388. if (DispInfo.mask & LVIF_TEXT)
  389. {
  390. AnsiString Value;
  391. switch (DispInfo.iSubItem) {
  392. case uvName: Value = File->FileName; break;
  393. case uvSize:
  394. // expanded from ?: to avoid memory leaks
  395. if (!File->IsDirectory)
  396. {
  397. Value = FormatFloat("#,##0", File->Size);
  398. }
  399. break;
  400. case uvChanged: Value = File->UserModificationStr; break;
  401. case uvRights: Value = File->RightsStr; break;
  402. case uvOwner: Value = File->Owner.DisplayText; break;
  403. case uvGroup: Value = File->Group.DisplayText; break;
  404. case uvExt: Value = File->Extension; break;
  405. case uvLinkTarget: Value = File->LinkTo; break;
  406. case uvType: Value = File->TypeName; break;
  407. default: assert(false);
  408. }
  409. StrPLCopy(DispInfo.pszText, Value, DispInfo.cchTextMax);
  410. }
  411. if (DispInfo.iSubItem == 0 && DispInfo.mask & LVIF_IMAGE)
  412. {
  413. DispInfo.iImage = File->IconIndex;
  414. DispInfo.mask |= LVIF_DI_SETITEM;
  415. }
  416. #endif
  417. }
  418. }
  419. //---------------------------------------------------------------------------
  420. bool __fastcall TUnixDirView::PasteFromClipBoard(AnsiString TargetPath)
  421. {
  422. DragDropFilesEx->FileList->Clear();
  423. bool Result = false;
  424. if (CanPasteFromClipBoard() &&
  425. DragDropFilesEx->GetFromClipboard())
  426. {
  427. if (TargetPath.IsEmpty())
  428. {
  429. TargetPath = PathName;
  430. }
  431. PerformItemDragDropOperation(NULL, DROPEFFECT_COPY);
  432. if (OnDDExecuted != NULL)
  433. {
  434. OnDDExecuted(this, DROPEFFECT_COPY);
  435. }
  436. Result = true;
  437. }
  438. return Result;
  439. }
  440. //---------------------------------------------------------------------------
  441. void __fastcall TUnixDirView::PerformItemDragDropOperation(TListItem * Item,
  442. int Effect)
  443. {
  444. #ifndef DESIGN_ONLY
  445. if (OnDDFileOperation)
  446. {
  447. assert(DragDropFilesEx->FileList->Count > 0);
  448. AnsiString SourceDirectory;
  449. AnsiString TargetDirectory;
  450. SourceDirectory = ExtractFilePath(DragDropFilesEx->FileList->Items[0]->Name);
  451. if (Item)
  452. {
  453. assert(ITEMFILE->IsDirectory && (Terminal->Files->IndexOf(ITEMFILE) >= 0));
  454. TargetDirectory = ITEMFILE->FullFileName;
  455. }
  456. else
  457. {
  458. TargetDirectory = Path;
  459. }
  460. bool DoFileOperation = true;
  461. OnDDFileOperation(this, Effect, SourceDirectory, TargetDirectory,
  462. DoFileOperation);
  463. }
  464. #endif
  465. }
  466. //---------------------------------------------------------------------------
  467. void __fastcall TUnixDirView::SetItemImageIndex(TListItem * /* Item */, int /* Index */)
  468. {
  469. // TCustomDirView::SetItemImageIndex is used for icon caching
  470. // so we don't need it here.
  471. }
  472. //---------------------------------------------------------------------------
  473. void __fastcall TUnixDirView::DDMenuDone(TObject* /* Sender */, HMENU /* AMenu */)
  474. {
  475. // TODO: Why I need to duplicate this method? (see TCustomDirView::DDMenuDone)
  476. }
  477. //---------------------------------------------------------------------------
  478. void __fastcall TUnixDirView::SetDriveView(TCustomUnixDriveView * Value)
  479. {
  480. if (Value != FDriveView)
  481. {
  482. if (FDriveView != NULL)
  483. {
  484. FDriveView->Terminal = NULL;
  485. }
  486. FDriveView = Value;
  487. if (FDriveView != NULL)
  488. {
  489. FDriveView->Terminal = Terminal;
  490. }
  491. }
  492. }
  493. //---------------------------------------------------------------------------
  494. #ifndef DESIGN_ONLY
  495. void __fastcall TUnixDirView::SetTerminal(TTerminal *value)
  496. {
  497. if (FTerminal != value)
  498. {
  499. if (FTerminal)
  500. {
  501. assert(FTerminal->OnReadDirectory == DoReadDirectory);
  502. FTerminal->OnReadDirectory = NULL;
  503. assert(FTerminal->OnStartReadDirectory == DoStartReadDirectory);
  504. FTerminal->OnStartReadDirectory = NULL;
  505. assert(FTerminal->OnChangeDirectory == DoChangeDirectory);
  506. FTerminal->OnChangeDirectory = NULL;
  507. if (!value || !value->Files->Loaded)
  508. {
  509. ClearItems();
  510. }
  511. }
  512. FTerminal = value;
  513. PathChanging(false);
  514. if (FDriveView != NULL)
  515. {
  516. FDriveView->Terminal = FTerminal;
  517. }
  518. if (FTerminal)
  519. {
  520. FTerminal->OnReadDirectory = DoReadDirectory;
  521. FTerminal->OnStartReadDirectory = DoStartReadDirectory;
  522. FTerminal->OnChangeDirectory = DoChangeDirectory;
  523. FTerminal->Files->IncludeParentDirectory = AddParentDir;
  524. if (FTerminal->Files->Loaded)
  525. {
  526. DoChangeDirectory(FTerminal);
  527. DoStartReadDirectory(FTerminal); // just for style and the assertions
  528. DoReadDirectory(FTerminal, false);
  529. }
  530. }
  531. }
  532. }
  533. #endif
  534. //---------------------------------------------------------------------------
  535. void __fastcall TUnixDirView::DoStartReadDirectory(TObject * /*Sender*/)
  536. {
  537. assert(!FLoading);
  538. FLoading = true;
  539. }
  540. //---------------------------------------------------------------------------
  541. void __fastcall TUnixDirView::DoReadDirectory(TObject * /*Sender*/, bool ReloadOnly)
  542. {
  543. assert(FLoading);
  544. FLoading = false;
  545. #ifndef DESIGN_ONLY
  546. if (Terminal->Active)
  547. {
  548. if (ReloadOnly)
  549. {
  550. Reload(false);
  551. }
  552. else
  553. {
  554. Load();
  555. PathChanged();
  556. }
  557. if ((FDriveView != NULL) && FDriveView->Visible)
  558. {
  559. FDriveView->LoadDirectory();
  560. }
  561. }
  562. else
  563. {
  564. // Make sure file list is cleared, to remove all references to invalid
  565. // file objects. LoadFiles check for disconnected terminal, so no reloading
  566. // actually occures.
  567. Load();
  568. }
  569. #endif
  570. }
  571. //---------------------------------------------------------------------------
  572. void __fastcall TUnixDirView::DoChangeDirectory(TObject * /*Sender*/)
  573. {
  574. #ifndef DESIGN_ONLY
  575. // Reload(false);
  576. #endif
  577. }
  578. //---------------------------------------------------------------------------
  579. bool __fastcall TUnixDirView::GetDirOK()
  580. {
  581. #ifndef DESIGN_ONLY
  582. return (Active && Terminal->Files->Loaded);
  583. #else
  584. return false;
  585. #endif
  586. }
  587. //---------------------------------------------------------------------------
  588. AnsiString __fastcall TUnixDirView::GetPathName()
  589. {
  590. #ifndef DESIGN_ONLY
  591. if (DirOK) return Terminal->CurrentDirectory;
  592. else
  593. #endif
  594. return "";
  595. }
  596. //---------------------------------------------------------------------------
  597. AnsiString __fastcall TUnixDirView::GetPath()
  598. {
  599. #ifndef DESIGN_ONLY
  600. if (DirOK) return UnixIncludeTrailingBackslash(Terminal->CurrentDirectory);
  601. else
  602. #endif
  603. return "";
  604. }
  605. //---------------------------------------------------------------------------
  606. void __fastcall TUnixDirView::SetPath(AnsiString Value)
  607. {
  608. #ifndef DESIGN_ONLY
  609. Value = UnixExcludeTrailingBackslash(Value);
  610. if (Active && (Terminal->CurrentDirectory != Value))
  611. {
  612. PathChanging(true);
  613. Terminal->CurrentDirectory = Value;
  614. }
  615. #endif
  616. }
  617. //---------------------------------------------------------------------------
  618. void __fastcall TUnixDirView::SortItems()
  619. {
  620. #ifndef DESIGN_ONLY
  621. assert(Terminal);
  622. if (HandleAllocated())
  623. {
  624. PFNLVCOMPARE SortProc;
  625. switch (SortColumn) {
  626. case uvName: SortProc = (PFNLVCOMPARE)CompareItemFileName; break;
  627. case uvSize: SortProc = (PFNLVCOMPARE)CompareSize; break;
  628. case uvChanged: SortProc = (PFNLVCOMPARE)CompareModification; break;
  629. case uvRights: SortProc = (PFNLVCOMPARE)CompareRightsStr; break;
  630. case uvOwner: SortProc = (PFNLVCOMPARE)CompareOwner; break;
  631. case uvGroup: SortProc = (PFNLVCOMPARE)CompareGroup; break;
  632. case uvExt: SortProc = (PFNLVCOMPARE)CompareExtension; break;
  633. case uvLinkTarget: SortProc = (PFNLVCOMPARE)CompareLinkTo; break;
  634. case uvType: SortProc = (PFNLVCOMPARE)CompareTypeName; break;
  635. default: assert(false);
  636. }
  637. CustomSortItems(SortProc);
  638. }
  639. #endif
  640. }
  641. //---------------------------------------------------------------------------
  642. bool __fastcall TUnixDirView::GetActive()
  643. {
  644. #ifndef DESIGN_ONLY
  645. return ((Terminal != NULL) && Terminal->Active);
  646. #else
  647. return false;
  648. #endif
  649. }
  650. //---------------------------------------------------------------------------
  651. void __fastcall TUnixDirView::DDDragDetect(int grfKeyState,
  652. const TPoint &DetectStart, const TPoint &Point, TDragDetectStatus DragStatus)
  653. {
  654. if ((DragStatus == ddsDrag) && (!Loading) && (MarkedCount > 0))
  655. {
  656. TCustomUnixDirView::DDDragDetect(grfKeyState, DetectStart, Point, DragStatus);
  657. }
  658. }
  659. //---------------------------------------------------------------------------
  660. void __fastcall TUnixDirView::SetAddParentDir(bool Value)
  661. {
  662. if (Value != AddParentDir)
  663. {
  664. #ifndef DESIGN_ONLY
  665. if (Terminal) Terminal->Files->IncludeParentDirectory = Value;
  666. #endif
  667. TCustomUnixDirView::SetAddParentDir(Value);
  668. }
  669. }
  670. //---------------------------------------------------------------------------
  671. bool __fastcall TUnixDirView::TargetHasDropHandler(TListItem * /* Item */, int /* Effect */)
  672. {
  673. return false;
  674. }
  675. //---------------------------------------------------------------------------
  676. void __fastcall TUnixDirView::DDChooseEffect(int grfKeyState, int &dwEffect)
  677. {
  678. if ((grfKeyState & (MK_CONTROL | MK_SHIFT)) == 0)
  679. {
  680. dwEffect = DROPEFFECT_Copy;
  681. }
  682. TCustomDirView::DDChooseEffect(grfKeyState, dwEffect);
  683. }
  684. //---------------------------------------------------------------------------
  685. void __fastcall TUnixDirView::SetDDAllowMove(bool value)
  686. {
  687. if (DDAllowMove != value)
  688. {
  689. assert(DragDropFilesEx);
  690. FDDAllowMove = value;
  691. DragDropFilesEx->SourceEffects = DragSourceEffects;
  692. }
  693. }
  694. //---------------------------------------------------------------------------
  695. TDropEffectSet __fastcall TUnixDirView::GetDragSourceEffects()
  696. {
  697. TDropEffectSet Result;
  698. Result << deCopy;
  699. if (DDAllowMove) Result << deMove;
  700. return Result;
  701. }
  702. //---------------------------------------------------------------------------
  703. void __fastcall TUnixDirView::ChangeDirectory(AnsiString Path)
  704. {
  705. AnsiString LastFile = "";
  706. if (ItemFocused) LastFile = ItemFileName(ItemFocused);
  707. ClearItems();
  708. DoAnimation(true);
  709. #ifndef DESIGN_ONLY
  710. try
  711. {
  712. FDirLoadedAfterChangeDir = false;
  713. if (Path == HOMEDIRECTORY)
  714. {
  715. Terminal->HomeDirectory();
  716. }
  717. else
  718. // this works even with LockInHome
  719. if (Path == ROOTDIRECTORY)
  720. {
  721. Terminal->CurrentDirectory = ROOTDIRECTORY;
  722. }
  723. else
  724. {
  725. Terminal->ChangeDirectory(Path);
  726. }
  727. }
  728. __finally
  729. {
  730. // changing directory failed, so we load again old directory
  731. if (!FDirLoadedAfterChangeDir)
  732. {
  733. FSelectFile = LastFile;
  734. Reload(false);
  735. };
  736. }
  737. #endif
  738. }
  739. //---------------------------------------------------------------------------
  740. bool __fastcall TUnixDirView::CanEdit(TListItem* Item)
  741. {
  742. #ifndef DESIGN_ONLY
  743. assert(Terminal);
  744. return TCustomUnixDirView::CanEdit(Item) && Terminal->IsCapable[fcRename];
  745. #else
  746. return false;
  747. #endif
  748. }
  749. //---------------------------------------------------------------------------
  750. void __fastcall TUnixDirView::InternalEdit(const tagLVITEMA & HItem)
  751. {
  752. #ifndef DESIGN_ONLY
  753. TListItem *Item = GetItemFromHItem(HItem);
  754. ASSERT_VALID_ITEM;
  755. FSelectFile = HItem.pszText;
  756. LoadEnabled = true;
  757. Terminal->RenameFile(ITEMFILE, HItem.pszText, true);
  758. #endif
  759. }
  760. //---------------------------------------------------------------------------
  761. int __fastcall TUnixDirView::SecondaryColumnHeader(int Index, bool & AliasOnly)
  762. {
  763. AliasOnly = false;
  764. return ((Index == uvName) ? uvExt : -1);
  765. }
  766. //---------------------------------------------------------------------------
  767. int __fastcall TUnixDirView::HiddenCount()
  768. {
  769. return FHiddenCount;
  770. }
  771. //---------------------------------------------------------------------------
  772. int __fastcall TUnixDirView::FilteredCount()
  773. {
  774. return FFilteredCount;
  775. }
  776. //---------------------------------------------------------------------------
  777. void __fastcall TUnixDirView::CreateDirectory(AnsiString DirName)
  778. {
  779. CreateDirectoryEx(DirName, NULL);
  780. }
  781. //---------------------------------------------------------------------------
  782. void __fastcall TUnixDirView::CreateDirectoryEx(AnsiString DirName, const TRemoteProperties * Properties)
  783. {
  784. #ifndef DESIGN_ONLY
  785. assert(Terminal);
  786. // if file would be created in current directory, select it after reload
  787. if (UnixExtractFileName(DirName) == DirName)
  788. {
  789. FSelectFile = DirName;
  790. }
  791. Terminal->CreateDirectory(DirName, Properties);
  792. #endif
  793. }
  794. //---------------------------------------------------------------------------
  795. AnsiString __fastcall TUnixDirView::MinimizePath(AnsiString Path, int Length)
  796. {
  797. return StringReplace(MinimizeName(
  798. StringReplace(Path, '/', '\\', TReplaceFlags() << rfReplaceAll),
  799. Canvas, Length), '\\', '/', TReplaceFlags() << rfReplaceAll);
  800. }
  801. //---------------------------------------------------------------------------
  802. bool __fastcall TUnixDirView::GetIsRoot()
  803. {
  804. #ifndef DESIGN_ONLY
  805. return (PathName == ROOTDIRECTORY);
  806. #else
  807. return false;
  808. #endif
  809. }
  810. //---------------------------------------------------------------------------
  811. TColor __fastcall TUnixDirView::ItemColor(TListItem * Item)
  812. {
  813. assert(Item);
  814. #ifndef DESIGN_ONLY
  815. if (DimmHiddenFiles && !Item->Selected && ITEMFILE->IsHidden)
  816. {
  817. return clGrayText;
  818. }
  819. else
  820. #endif
  821. {
  822. return (TColor)clDefaultItemColor;
  823. }
  824. }
  825. //---------------------------------------------------------------------------
  826. TDateTime __fastcall TUnixDirView::ItemFileTime(TListItem * Item,
  827. TDateTimePrecision & Precision)
  828. {
  829. assert(Item);
  830. #ifndef DESIGN_ONLY
  831. switch (ITEMFILE->ModificationFmt)
  832. {
  833. case mfNone:
  834. Precision = tpNone;
  835. break;
  836. case mfMDHM:
  837. Precision = tpMinute;
  838. break;
  839. case mfMDY:
  840. Precision = tpDay;
  841. break;
  842. case mfFull:
  843. default:
  844. Precision = tpSecond;
  845. break;
  846. }
  847. return ITEMFILE->Modification;
  848. #else
  849. Precision = tpSecond;
  850. return Now();
  851. #endif
  852. }
  853. //---------------------------------------------------------------------------
  854. void __fastcall TUnixDirView::SetShowInaccesibleDirectories(bool value)
  855. {
  856. if (FShowInaccesibleDirectories != value)
  857. {
  858. FShowInaccesibleDirectories = value;
  859. if (DirOK) Reload(false);
  860. }
  861. }
  862. //---------------------------------------------------------------------------
  863. void __fastcall TUnixDirView::AddToDragFileList(TFileList * FileList,
  864. TListItem * Item)
  865. {
  866. AnsiString FileName = ItemFullFileName(Item);
  867. #ifndef DESIGN_ONLY
  868. if (OnDDDragFileName != NULL)
  869. {
  870. OnDDDragFileName(this, ITEMFILE, FileName);
  871. }
  872. #endif
  873. FileList->AddItem(NULL, FileName);
  874. }