UnixDirView.cpp 28 KB

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