CustomScpExplorer.cpp 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Clipbrd.hpp>
  5. #include <Common.h>
  6. #include "CustomScpExplorer.h"
  7. #include <Interface.h>
  8. #include <Net.h>
  9. #include <ScpMain.h>
  10. #include <FileSystems.h>
  11. #include <TextsWin.h>
  12. #include <DiscMon.hpp>
  13. #include <VCLCommon.h>
  14. #include <Log.h>
  15. #include <Progress.h>
  16. #include <SynchronizeProgress.h>
  17. #include <OperationStatus.h>
  18. #include <Queue.h>
  19. #include <DragExt.h>
  20. #include "GUITools.h"
  21. #include "NonVisual.h"
  22. #include "Tools.h"
  23. #include "WinConfiguration.h"
  24. #include "TerminalManager.h"
  25. //---------------------------------------------------------------------------
  26. #pragma package(smart_init)
  27. #pragma link "CustomDirView"
  28. #pragma link "CustomUnixDirView"
  29. #pragma link "IEListView"
  30. #pragma link "NortonLikeListView"
  31. #pragma link "UnixDirView"
  32. #pragma link "AssociatedStatusBar"
  33. #pragma resource "*.dfm"
  34. //---------------------------------------------------------------------------
  35. #ifdef DEBUGMODE
  36. #define DEBUG(MSG) CurrentSSH->LogEvent(MSG)
  37. #else
  38. #define DEBUG(MSG)
  39. #endif
  40. //---------------------------------------------------------------------------
  41. #define SAVE_SELECTION(DIRVIEW) \
  42. AnsiString FocusFile = ""; \
  43. AnsiString LastFocusedFile = ""; \
  44. if (DIRVIEW->ItemFocused) LastFocusedFile = DIRVIEW->ItemFocused->Caption; \
  45. { TListItem * ClosestUnselected = DIRVIEW->ClosestUnselected(DIRVIEW->ItemFocused); \
  46. if (ClosestUnselected) FocusFile = ClosestUnselected->Caption; }
  47. #define RESTORE_SELECTION(DIRVIEW) \
  48. if (!LastFocusedFile.IsEmpty() && \
  49. (!DIRVIEW->ItemFocused || (DIRVIEW->ItemFocused->Caption != LastFocusedFile))) \
  50. { \
  51. TListItem *ItemToSelect = DIRVIEW->FindFileItem(FocusFile); \
  52. if (ItemToSelect) \
  53. { \
  54. DIRVIEW->ItemFocused = ItemToSelect; \
  55. DIRVIEW->ItemFocused->MakeVisible(False); \
  56. } \
  57. }
  58. //---------------------------------------------------------------------------
  59. class TMutexGuard
  60. {
  61. public:
  62. TMutexGuard(HANDLE AMutex, int Message = MUTEX_RELEASE_TIMEOUT,
  63. int Timeout = 5000)
  64. {
  65. FMutex = NULL;
  66. unsigned long WaitResult = WaitForSingleObject(AMutex, Timeout);
  67. if (WaitResult == WAIT_TIMEOUT)
  68. {
  69. throw Exception(LoadStr(MUTEX_RELEASE_TIMEOUT));
  70. }
  71. else
  72. {
  73. FMutex = AMutex;
  74. }
  75. }
  76. ~TMutexGuard()
  77. {
  78. if (FMutex != NULL)
  79. {
  80. ReleaseMutex(FMutex);
  81. }
  82. }
  83. private:
  84. HANDLE FMutex;
  85. };
  86. //---------------------------------------------------------------------------
  87. __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
  88. FLastDirView(NULL), FFormRestored(False), TForm(Owner)
  89. {
  90. RestoreParams();
  91. RemoteDirView->Invalidate();
  92. assert(NonVisualDataModule && !NonVisualDataModule->ScpExplorer);
  93. NonVisualDataModule->ScpExplorer = this;
  94. Application->OnHint = ApplicationHint;
  95. FAutoOperation = false;
  96. FForceExecution = false;
  97. FShowStatusBarHint = false;
  98. FIgnoreNextSysCommand = false;
  99. FErrorList = NULL;
  100. FSynchronizeProgressForm = NULL;
  101. FProgressForm = NULL;
  102. FRefreshLocalDirectory = false;
  103. FRefreshRemoteDirectory = false;
  104. FDDMoveSlipped = false;
  105. FDDExtMapFile = NULL;
  106. FDDExtMutex = CreateMutex(NULL, false, DRAG_EXT_MUTEX);
  107. assert(FDDExtMutex != NULL);
  108. FQueueStatus = NULL;
  109. FQueueStatusSection = new TCriticalSection();
  110. FQueueStatusInvalidated = false;
  111. FQueueItemInvalidated = false;
  112. FQueueActedItem = NULL;
  113. FQueueController = new TQueueController(QueueView);
  114. FUserActionTimer = new TTimer(this);
  115. FUserActionTimer->Enabled = false;
  116. FUserActionTimer->Interval = 10;
  117. FUserActionTimer->OnTimer = UserActionTimer;
  118. FOle32Library = LoadLibrary("Ole32.dll");
  119. FDragMoveCursor = FOle32Library != NULL ?
  120. LoadCursor(FOle32Library, MAKEINTRESOURCE(2)) : NULL;
  121. UseSystemSettings(this);
  122. TComboBox * SessionCombo = dynamic_cast<TComboBox*>(GetComponent(fcSessionCombo));
  123. if (SessionCombo != NULL)
  124. {
  125. SessionCombo->OnDrawItem = SessionComboDrawItem;
  126. SessionCombo->OnDropDown = SessionComboDropDown;
  127. SessionCombo->OnChange = SessionComboChange;
  128. SessionCombo->Hint = NonVisualDataModule->OpenedSessionsAction->Hint;
  129. }
  130. TToolBar * MenuToolBar = dynamic_cast<TToolBar*>(GetComponent(fcMenuToolBar));
  131. assert(MenuToolBar);
  132. MenuToolBar->Font = Screen->MenuFont;
  133. assert(MenuToolBar->ControlCount);
  134. MenuToolBar->Height = MenuToolBar->Controls[0]->Height;
  135. RemoteDirView->Font = Screen->IconFont;
  136. }
  137. //---------------------------------------------------------------------------
  138. __fastcall TCustomScpExplorerForm::~TCustomScpExplorerForm()
  139. {
  140. CloseHandle(FDDExtMutex);
  141. FDDExtMutex = NULL;
  142. FreeLibrary(FOle32Library);
  143. FOle32Library = NULL;
  144. FDragMoveCursor = NULL;
  145. assert(!FErrorList);
  146. StoreParams();
  147. Terminal = NULL;
  148. Queue = NULL;
  149. assert(NonVisualDataModule && (NonVisualDataModule->ScpExplorer == this));
  150. NonVisualDataModule->ScpExplorer = NULL;
  151. delete FQueueController;
  152. FQueueController = NULL;
  153. delete FQueueStatusSection;
  154. FQueueStatusSection = NULL;
  155. delete FQueueStatus;
  156. FQueueStatus = NULL;
  157. delete FUserActionTimer;
  158. FUserActionTimer = NULL;
  159. }
  160. //---------------------------------------------------------------------------
  161. void __fastcall TCustomScpExplorerForm::SetTerminal(TTerminal * value)
  162. {
  163. if (FTerminal != value)
  164. {
  165. if (FTerminal)
  166. {
  167. UpdateSessionData(Terminal->SessionData);
  168. }
  169. FTerminal = value;
  170. TerminalChanged();
  171. }
  172. }
  173. //---------------------------------------------------------------------------
  174. void __fastcall TCustomScpExplorerForm::TerminalChanged()
  175. {
  176. RemoteDirView->Terminal = Terminal;
  177. Caption = Application->Title;
  178. if (Terminal)
  179. {
  180. if (Terminal->Active)
  181. {
  182. Terminal->RefreshDirectory();
  183. }
  184. UpdateStatusBar();
  185. }
  186. TerminalListChanged(NULL);
  187. }
  188. //---------------------------------------------------------------------------
  189. void __fastcall TCustomScpExplorerForm::SetQueue(TTerminalQueue * value)
  190. {
  191. if (Queue != value)
  192. {
  193. if (FQueue != NULL)
  194. {
  195. FQueue->OnListUpdate = NULL;
  196. FQueue->OnQueueItemUpdate = NULL;
  197. }
  198. FQueue = value;
  199. if (FQueue != NULL)
  200. {
  201. assert(FQueue->OnListUpdate == NULL);
  202. FQueue->OnListUpdate = QueueListUpdate;
  203. assert(FQueue->OnQueueItemUpdate == NULL);
  204. FQueue->OnQueueItemUpdate = QueueItemUpdate;
  205. }
  206. QueueChanged();
  207. }
  208. }
  209. //---------------------------------------------------------------------------
  210. void __fastcall TCustomScpExplorerForm::QueueViewDeletion(TObject * /*Sender*/,
  211. TListItem * Item)
  212. {
  213. if (FQueueActedItem == Item)
  214. {
  215. FQueueActedItem = NULL;
  216. if ((QueueView->PopupMenu != NULL) &&
  217. (QueueView->PopupMenu->PopupComponent == QueueView))
  218. {
  219. SendMessage(PopupList->Window, WM_CANCELMODE, 0, 0);
  220. }
  221. }
  222. if (Item->Data == FPendingQueueActionItem)
  223. {
  224. FPendingQueueActionItem = NULL;
  225. }
  226. }
  227. //---------------------------------------------------------------------------
  228. void __fastcall TCustomScpExplorerForm::UpdateQueueStatus()
  229. {
  230. {
  231. TGuard Guard(FQueueStatusSection);
  232. FQueueStatusInvalidated = false;
  233. if (FQueue != NULL)
  234. {
  235. FQueueStatus = FQueue->CreateStatus(FQueueStatus);
  236. }
  237. }
  238. FQueueController->UpdateQueueStatus(FQueueStatus);
  239. UpdateQueueView();
  240. }
  241. //---------------------------------------------------------------------------
  242. void __fastcall TCustomScpExplorerForm::UpdateQueueView()
  243. {
  244. ComponentVisible[fcQueueView] =
  245. (WinConfiguration->QueueView.Show == qvShow) ||
  246. ((WinConfiguration->QueueView.Show == qvHideWhenEmpty) &&
  247. (FQueueStatus != NULL) && (FQueueStatus->Count > 0));
  248. }
  249. //---------------------------------------------------------------------------
  250. void __fastcall TCustomScpExplorerForm::QueueChanged()
  251. {
  252. if (FQueueStatus != NULL)
  253. {
  254. delete FQueueStatus;
  255. FQueueStatus = NULL;
  256. }
  257. UpdateQueueStatus();
  258. }
  259. //---------------------------------------------------------------------------
  260. void __fastcall TCustomScpExplorerForm::QueueListUpdate(TTerminalQueue * Queue)
  261. {
  262. if (FQueue == Queue)
  263. {
  264. FQueueStatusInvalidated = true;
  265. }
  266. }
  267. //---------------------------------------------------------------------------
  268. void __fastcall TCustomScpExplorerForm::QueueItemUpdate(TTerminalQueue * Queue,
  269. TQueueItem * Item)
  270. {
  271. if (FQueue == Queue)
  272. {
  273. TGuard Guard(FQueueStatusSection);
  274. assert(FQueueStatus != NULL);
  275. TQueueItemProxy * QueueItem = FQueueStatus->FindByQueueItem(Item);
  276. if ((Item->Status == TQueueItem::qsDone) && (Terminal != NULL))
  277. {
  278. FRefreshLocalDirectory = (QueueItem == NULL) || (QueueItem->Info->ModifiesLocal);
  279. FRefreshRemoteDirectory = (QueueItem == NULL) || (QueueItem->Info->ModifiesRemote);
  280. }
  281. if (QueueItem != NULL)
  282. {
  283. QueueItem->Flag = true;
  284. FQueueItemInvalidated = true;
  285. }
  286. }
  287. }
  288. //---------------------------------------------------------------------------
  289. TQueueItemProxy * __fastcall TCustomScpExplorerForm::RefreshQueueItems()
  290. {
  291. TQueueItemProxy * Result = NULL;
  292. if (FQueueStatus != NULL)
  293. {
  294. bool Refresh = FQueueItemInvalidated;
  295. FQueueItemInvalidated = false;
  296. int Limit = Refresh ? FQueueStatus->Count : FQueueStatus->ActiveCount;
  297. bool Updated = false;
  298. bool Update;
  299. TQueueItemProxy * QueueItem;
  300. bool UserAction;
  301. for (int Index = 0; Index < Limit; Index++)
  302. {
  303. Update = false;
  304. QueueItem = FQueueStatus->Items[Index];
  305. UserAction = TQueueItem::IsUserActionStatus(QueueItem->Status);
  306. if (UserAction && (Result == NULL))
  307. {
  308. Result = QueueItem;
  309. }
  310. if (QueueItem->Flag)
  311. {
  312. QueueItem->Flag = false;
  313. QueueItem->Update();
  314. Updated = true;
  315. Update = true;
  316. }
  317. else if (UserAction)
  318. {
  319. Update = true;
  320. }
  321. if (Update)
  322. {
  323. FQueueController->RefreshQueueItem(QueueItem);
  324. }
  325. }
  326. if (Updated)
  327. {
  328. NonVisualDataModule->UpdateNonVisibleActions();
  329. }
  330. }
  331. return Result;
  332. }
  333. //---------------------------------------------------------------------------
  334. void __fastcall TCustomScpExplorerForm::ConfigurationChanged()
  335. {
  336. assert(Configuration && RemoteDirView);
  337. RemoteDirView->DDAllowMove = WinConfiguration->DDAllowMoveInit;
  338. RemoteDirView->DimmHiddenFiles = WinConfiguration->DimmHiddenFiles;
  339. RemoteDirView->ShowHiddenFiles = WinConfiguration->ShowHiddenFiles;
  340. RemoteDirView->ShowInaccesibleDirectories = WinConfiguration->ShowInaccesibleDirectories;
  341. RemoteDirView->DDTemporaryDirectory = WinConfiguration->DDTemporaryDirectory;
  342. UpdateQueueView();
  343. }
  344. //---------------------------------------------------------------------------
  345. void __fastcall TCustomScpExplorerForm::RemoteDirViewGetCopyParam(
  346. TUnixDirView * /*Sender*/, TTransferDirection Direction,
  347. TTransferType Type, AnsiString &TargetDirectory, TStrings * FileList,
  348. TCopyParamType &CopyParam)
  349. {
  350. TGUICopyParamType GUICopyParam = GUIConfiguration->CopyParam;
  351. // overwrites TCopyParamType fields only
  352. GUICopyParam = CopyParam;
  353. if (!CopyParamDialog(Direction, Type, true, FileList,
  354. TargetDirectory, GUICopyParam, WinConfiguration->DDTransferConfirmation))
  355. {
  356. Abort();
  357. }
  358. else
  359. {
  360. CopyParam = GUICopyParam;
  361. }
  362. }
  363. //---------------------------------------------------------------------------
  364. bool __fastcall TCustomScpExplorerForm::CopyParamDialog(
  365. TTransferDirection Direction, TTransferType Type, bool DragDrop,
  366. TStrings * FileList, AnsiString & TargetDirectory, TGUICopyParamType & CopyParam,
  367. bool Confirm)
  368. {
  369. bool Result = true;
  370. assert(Terminal && Terminal->Active);
  371. if (DragDrop && (Direction == tdToLocal) && (Type == ttMove) &&
  372. !WinConfiguration->DDAllowMove)
  373. {
  374. int Answer = MessageDialog(LoadStr(DND_DOWNLOAD_MOVE_WARNING), qtWarning,
  375. qaOK | qaCancel, 0, mpNeverAskAgainCheck);
  376. if (Answer == qaNeverAskAgain)
  377. {
  378. WinConfiguration->DDAllowMove = true;
  379. }
  380. else if (Answer == qaCancel)
  381. {
  382. Result = false;
  383. }
  384. }
  385. bool DragDropTemp = (DragDrop && (Direction == tdToLocal));
  386. if (Result && Confirm)
  387. {
  388. int Options =
  389. (!Terminal->IsCapable[fcTextMode] ? coDisableTransferMode : 0) |
  390. (DragDropTemp ? coDragDropTemp : 0);
  391. Result = DoCopyDialog(Direction == tdToRemote, Type == ttMove,
  392. FileList, TargetDirectory, &CopyParam, Options);
  393. }
  394. if (Result && CopyParam.Queue && !DragDropTemp)
  395. {
  396. assert(Queue != NULL);
  397. int Params =
  398. ((Type == ttMove) ? cpDelete : 0) |
  399. (CopyParam.QueueNoConfirmation ? cpNoConfirmation : 0);
  400. TQueueItem * QueueItem;
  401. if (Direction == tdToRemote)
  402. {
  403. QueueItem = new TUploadQueueItem(Terminal, FileList, TargetDirectory,
  404. &CopyParam, Params);
  405. }
  406. else
  407. {
  408. QueueItem = new TDownloadQueueItem(Terminal, FileList, TargetDirectory,
  409. &CopyParam, Params);
  410. }
  411. Queue->AddItem(QueueItem);
  412. Result = false;
  413. TOperationSide Side = ((Direction == tdToRemote) ? osLocal : osRemote);
  414. if (HasDirView[Side])
  415. {
  416. DirView(Side)->SelectAll(smNone);
  417. }
  418. }
  419. return Result;
  420. }
  421. //---------------------------------------------------------------------------
  422. void __fastcall TCustomScpExplorerForm::RestoreFormParams()
  423. {
  424. }
  425. //---------------------------------------------------------------------------
  426. void __fastcall TCustomScpExplorerForm::RestoreParams()
  427. {
  428. // IDE often looses this link
  429. RemoteDirView->HeaderImages = NonVisualDataModule->ArrowImages;
  430. if (Position == poDesigned)
  431. {
  432. RestoreFormParams();
  433. }
  434. ConfigurationChanged();
  435. QueuePanel->Height = WinConfiguration->QueueView.Height;
  436. LoadListViewStr(QueueView, WinConfiguration->QueueView.Layout);
  437. QueueCoolBar->Visible = WinConfiguration->QueueView.ToolBar;
  438. }
  439. //---------------------------------------------------------------------------
  440. void __fastcall TCustomScpExplorerForm::StoreParams()
  441. {
  442. WinConfiguration->QueueView.Height = QueuePanel->Height;
  443. WinConfiguration->QueueView.Layout = GetListViewStr(QueueView);
  444. WinConfiguration->QueueView.ToolBar = QueueCoolBar->Visible;
  445. }
  446. //---------------------------------------------------------------------------
  447. void __fastcall TCustomScpExplorerForm::CreateParams(TCreateParams & Params)
  448. {
  449. if (!FFormRestored)
  450. {
  451. FFormRestored = true;
  452. RestoreFormParams();
  453. }
  454. TForm::CreateParams(Params);
  455. }
  456. //---------------------------------------------------------------------------
  457. void __fastcall TCustomScpExplorerForm::FileOperationProgress(
  458. TFileOperationProgressType & ProgressData, TCancelStatus & /*Cancel*/)
  459. {
  460. // operation is being executed and we still didn't show up progress form
  461. if (ProgressData.InProgress && !FProgressForm)
  462. {
  463. //assert(Screen && Screen->ActiveCustomForm);
  464. FProgressForm = new TProgressForm(Application);
  465. FProgressForm->DeleteToRecycleBin = WinConfiguration->DeleteToRecycleBin;
  466. // When main window is hidden, we suppose "/upload" mode
  467. if (!Visible)
  468. {
  469. FProgressForm->DisconnectWhenComplete = true;
  470. }
  471. }
  472. // operation is finished (or terminated), so we hide progress form
  473. else if (!ProgressData.InProgress && FProgressForm)
  474. {
  475. SAFE_DESTROY(FProgressForm);
  476. }
  477. if (FProgressForm)
  478. {
  479. FProgressForm->SetProgressData(ProgressData);
  480. if (FProgressForm->Cancel > ProgressData.Cancel)
  481. {
  482. ProgressData.Cancel = FProgressForm->Cancel;
  483. }
  484. }
  485. }
  486. //---------------------------------------------------------------------------
  487. void __fastcall TCustomScpExplorerForm::OperationProgress(
  488. TFileOperationProgressType & ProgressData, TCancelStatus & Cancel)
  489. {
  490. FileOperationProgress(ProgressData, Cancel);
  491. }
  492. //---------------------------------------------------------------------------
  493. void __fastcall TCustomScpExplorerForm::DoOperationFinished(
  494. TFileOperation Operation, TOperationSide Side,
  495. bool DragDrop, const AnsiString FileName, bool Success,
  496. bool & DisconnectWhenComplete)
  497. {
  498. if (!FAutoOperation)
  499. {
  500. // no selection on "/upload", form servers only as event handler
  501. // (it is not displayed)
  502. if (!DragDrop && Visible && (Operation != foCalculateSize))
  503. {
  504. AnsiString FileNameOnly = (Side == osRemote) ?
  505. UnixExtractFileName(FileName) : ExtractFileName(FileName);
  506. TListItem *Item = DirView(Side)->FindFileItem(FileNameOnly);
  507. assert(Item);
  508. if (Success) Item->Selected = false;
  509. Item->MakeVisible(false);
  510. }
  511. }
  512. if (FProgressForm)
  513. {
  514. DisconnectWhenComplete = FProgressForm->DisconnectWhenComplete;
  515. }
  516. }
  517. //---------------------------------------------------------------------------
  518. void __fastcall TCustomScpExplorerForm::OperationFinished(
  519. TFileOperation Operation, TOperationSide Side,
  520. bool DragDrop, const AnsiString FileName, Boolean Success,
  521. bool & DisconnectWhenComplete)
  522. {
  523. DoOperationFinished(Operation, Side, DragDrop, FileName, Success,
  524. DisconnectWhenComplete);
  525. }
  526. //---------------------------------------------------------------------------
  527. TCustomDirView * __fastcall TCustomScpExplorerForm::DirView(TOperationSide Side)
  528. {
  529. assert((Side == osRemote) || ((Side == osCurrent) && FLastDirView));
  530. return (Side == osCurrent) ? FLastDirView : RemoteDirView;
  531. }
  532. //---------------------------------------------------------------------------
  533. bool __fastcall TCustomScpExplorerForm::GetEnableFocusedOperation(TOperationSide Side)
  534. {
  535. return DirView(Side)->AnyFileSelected(true);
  536. }
  537. //---------------------------------------------------------------------------
  538. bool __fastcall TCustomScpExplorerForm::GetEnableSelectedOperation(TOperationSide Side)
  539. {
  540. return DirView(Side)->AnyFileSelected(false);
  541. }
  542. //---------------------------------------------------------------------------
  543. void __fastcall TCustomScpExplorerForm::RemoteDirViewContextPopup(
  544. TObject * /*Sender*/, const TPoint &MousePos, bool &Handled)
  545. {
  546. TListItem * Item = RemoteDirView->ItemFocused;
  547. if ((RemoteDirView->GetItemAt(MousePos.x, MousePos.y) == Item) &&
  548. RemoteDirView->AnyFileSelected(true))
  549. {
  550. TPoint ScreenPoint, ClientPoint;
  551. ClientPoint = ((MousePos.x < 0) && (MousePos.y < 0)) ?
  552. TPoint(0, 0) : MousePos;
  553. ScreenPoint = RemoteDirView->ClientToScreen(ClientPoint);
  554. NonVisualDataModule->CurrentOpenMenuItem->Default = !WinConfiguration->CopyOnDoubleClick;
  555. NonVisualDataModule->CurrentCopyMenuItem->Default = WinConfiguration->CopyOnDoubleClick;
  556. NonVisualDataModule->CurrentOpenMenuItem->Visible = WinConfiguration->ExpertMode;
  557. NonVisualDataModule->CurentEditMenuItem->Visible = WinConfiguration->ExpertMode;
  558. reinterpret_cast<TPopupMenu*>(GetComponent(fcRemotePopup))->Popup(
  559. ScreenPoint.x, ScreenPoint.y);
  560. }
  561. Handled = true;
  562. }
  563. //---------------------------------------------------------------------------
  564. void __fastcall TCustomScpExplorerForm::BatchStart(void *& Storage)
  565. {
  566. assert(FErrorList == NULL);
  567. Storage = new bool;
  568. if (HasDirView[osLocal])
  569. {
  570. *static_cast<bool*>(Storage) = DirView(osLocal)->WatchForChanges;
  571. DirView(osLocal)->WatchForChanges = false;
  572. }
  573. if (WinConfiguration->ContinueOnError)
  574. {
  575. FErrorList = new TStringList();
  576. }
  577. }
  578. //---------------------------------------------------------------------------
  579. void __fastcall TCustomScpExplorerForm::BatchEnd(void * Storage)
  580. {
  581. assert(Storage != NULL);
  582. if (FErrorList)
  583. {
  584. HandleErrorList(FErrorList);
  585. }
  586. if (HasDirView[osLocal])
  587. {
  588. DirView(osLocal)->WatchForChanges = *static_cast<bool*>(Storage);
  589. }
  590. delete Storage;
  591. }
  592. //---------------------------------------------------------------------------
  593. void __fastcall TCustomScpExplorerForm::ExecuteFileOperation(TFileOperation Operation,
  594. TOperationSide Side, TStrings * FileList, bool NoConfirmation, void * Param)
  595. {
  596. void * BatchStorage;
  597. BatchStart(BatchStorage);
  598. try
  599. {
  600. if ((Operation == foCopy) || (Operation == foMove))
  601. {
  602. TTransferDirection Direction = (Side == osLocal ? tdToRemote : tdToLocal);
  603. TTransferType Type = (Operation == foCopy ? ttCopy : ttMove);
  604. AnsiString TargetDirectory;
  605. if (Param != NULL)
  606. {
  607. TargetDirectory = *static_cast<AnsiString*>(Param);
  608. }
  609. TGUICopyParamType CopyParam = GUIConfiguration->CopyParam;
  610. if (CopyParamDialog(Direction, Type, false, FileList, TargetDirectory,
  611. CopyParam, !NoConfirmation))
  612. {
  613. assert(Terminal);
  614. TCustomDirView * DView = DirView(Side);
  615. bool SelectionRestored = false;
  616. DView->SaveSelection();
  617. try
  618. {
  619. if (Side == osLocal)
  620. {
  621. int Params = 0;
  622. if (Operation == foMove) Params |= cpDelete;
  623. Terminal->CopyToRemote(FileList, TargetDirectory, &CopyParam, Params);
  624. if (Operation == foMove)
  625. {
  626. DView->Reload(True);
  627. DView->RestoreSelection();
  628. SelectionRestored = true;
  629. }
  630. }
  631. else
  632. {
  633. try
  634. {
  635. Terminal->CopyToLocal(FileList, TargetDirectory, &CopyParam,
  636. (Operation == foMove ? cpDelete : 0));
  637. }
  638. __finally
  639. {
  640. if (Operation == foMove)
  641. {
  642. DView->RestoreSelection();
  643. SelectionRestored = true;
  644. }
  645. if (HasDirView[osLocal] &&
  646. (IncludeTrailingBackslash(TargetDirectory) ==
  647. IncludeTrailingBackslash(DirView(osLocal)->Path)))
  648. {
  649. DirView(osLocal)->ReloadDirectory();
  650. }
  651. }
  652. }
  653. }
  654. __finally
  655. {
  656. if (!SelectionRestored)
  657. {
  658. DView->DiscardSavedSelection();
  659. }
  660. }
  661. }
  662. }
  663. else if (Operation == foRename)
  664. {
  665. assert(DirView(Side)->ItemFocused);
  666. DirView(Side)->ItemFocused->EditCaption();
  667. }
  668. else if (Operation == foDelete)
  669. {
  670. assert(FileList->Count);
  671. bool Confirmed = !WinConfiguration->ConfirmDeleting;
  672. if (!Confirmed)
  673. {
  674. AnsiString Query;
  675. if (FileList->Count == 1)
  676. {
  677. if (Side == osLocal)
  678. {
  679. Query = ExtractFileName(FileList->Strings[0]);
  680. }
  681. else
  682. {
  683. Query = UnixExtractFileName(FileList->Strings[0]);
  684. }
  685. Query = FMTLOAD(CONFIRM_DELETE_FILE, (Query));
  686. }
  687. else
  688. {
  689. Query = FMTLOAD(CONFIRM_DELETE_FILES, (FileList->Count));
  690. }
  691. int Answer = MessageDialog(Query, qtConfirmation,
  692. qaOK | qaCancel, 0, mpNeverAskAgainCheck);
  693. if (Answer == qaNeverAskAgain)
  694. {
  695. Confirmed = true;
  696. WinConfiguration->ConfirmDeleting = false;
  697. }
  698. else
  699. {
  700. Confirmed = (Answer == qaOK);
  701. }
  702. }
  703. if (Confirmed) DeleteFiles(Side, FileList);
  704. }
  705. else if (Operation == foSetProperties)
  706. {
  707. SetProperties(Side, FileList);
  708. }
  709. else if (Operation == foCustomCommand)
  710. {
  711. assert(Param);
  712. assert(Side == osRemote);
  713. FCustomCommandName = *((AnsiString *)Param);
  714. try
  715. {
  716. AnsiString Command = TCustomFileSystem::CompleteCustomCommand(
  717. WinConfiguration->CustomCommands->Values[FCustomCommandName],
  718. "", CustomCommandGetParamValue);
  719. Terminal->CustomCommandOnFiles(Command,
  720. WinConfiguration->CustomCommands->Params[FCustomCommandName],
  721. FileList);
  722. }
  723. __finally
  724. {
  725. FCustomCommandName = "";
  726. }
  727. }
  728. else if (Operation == foRemoteMove)
  729. {
  730. assert(Side == osRemote);
  731. RemoteMoveFiles(FileList, NoConfirmation);
  732. }
  733. else
  734. {
  735. assert(false);
  736. }
  737. }
  738. __finally
  739. {
  740. BatchEnd(BatchStorage);
  741. }
  742. }
  743. //---------------------------------------------------------------------------
  744. TOperationSide __fastcall TCustomScpExplorerForm::GetSide(TOperationSide Side)
  745. {
  746. if (Side == osCurrent)
  747. {
  748. Side = osRemote;
  749. }
  750. return Side;
  751. }
  752. //---------------------------------------------------------------------------
  753. void __fastcall TCustomScpExplorerForm::ExecuteFileOperation(TFileOperation Operation,
  754. TOperationSide Side, bool OnFocused, bool NoConfirmation, void * Param)
  755. {
  756. Side = GetSide(Side);
  757. TStrings * FileList = DirView(Side)->CreateFileList(OnFocused, (Side == osLocal), NULL);
  758. try
  759. {
  760. ExecuteFileOperation(Operation, Side, FileList, NoConfirmation, Param);
  761. }
  762. __finally
  763. {
  764. delete FileList;
  765. }
  766. }
  767. //---------------------------------------------------------------------------
  768. void __fastcall TCustomScpExplorerForm::CustomCommandGetParamValue(
  769. const AnsiString AName, AnsiString & Value)
  770. {
  771. assert(!FCustomCommandName.IsEmpty());
  772. AnsiString Name = AName;
  773. if (Name.IsEmpty())
  774. {
  775. Name = FMTLOAD(CUSTOM_COMMANDS_PARAM_PROMPT, (StripHotkey(FCustomCommandName)));
  776. }
  777. if (!InputDialog(FMTLOAD(CUSTOM_COMMANDS_PARAM_TITLE,
  778. (StripHotkey(FCustomCommandName))), Name, Value))
  779. {
  780. Abort();
  781. }
  782. }
  783. //---------------------------------------------------------------------------
  784. void __fastcall TCustomScpExplorerForm::HandleErrorList(TStringList *& ErrorList)
  785. {
  786. try
  787. {
  788. if (ErrorList->Count)
  789. {
  790. if (MessageDialog(FMTLOAD(ERROR_LIST_COUNT, (ErrorList->Count)), qtError,
  791. qaOK | qaCancel, 0) == qaOK)
  792. {
  793. int Answer;
  794. int Index = 0;
  795. do
  796. {
  797. assert(Index >= 0 && Index < ErrorList->Count);
  798. Answer = MoreMessageDialog(
  799. FMTLOAD(ERROR_LIST_NUMBER, (Index+1, ErrorList->Count, ErrorList->Strings[Index])),
  800. dynamic_cast<TStrings *>(ErrorList->Objects[Index]), qtError,
  801. (Index ? qaPrev : 0) | (Index < ErrorList->Count - 1 ? qaNext : 0) |
  802. qaOK, 0);
  803. if (Answer == qaNext)
  804. {
  805. Index++;
  806. }
  807. if (Answer == qaPrev)
  808. {
  809. Index--;
  810. }
  811. }
  812. while (Answer != qaOK);
  813. }
  814. }
  815. }
  816. __finally
  817. {
  818. TStrings * List = ErrorList;
  819. ErrorList = NULL;
  820. for (int i = 0; i < List->Count; i++)
  821. {
  822. delete List->Objects[i];
  823. }
  824. delete List;
  825. }
  826. }
  827. //---------------------------------------------------------------------------
  828. void __fastcall TCustomScpExplorerForm::ExecuteFile(TOperationSide Side,
  829. TExecuteFileBy ExecuteFileBy)
  830. {
  831. assert(!WinConfiguration->DisableOpenEdit);
  832. if (Side == osCurrent)
  833. {
  834. Side = FLastDirView == RemoteDirView ? osRemote : osLocal;
  835. }
  836. bool Edit = (ExecuteFileBy == efEditor || ExecuteFileBy == efAlternativeEditor);
  837. bool InternalEdit = Edit &&
  838. ((WinConfiguration->Editor.Editor == edInternal) !=
  839. (ExecuteFileBy == efAlternativeEditor));
  840. FExecutedFileForceText =
  841. (InternalEdit || (Edit && WinConfiguration->Editor.ExternalEditorText));
  842. TStrings * FileList = DirView(Side)->CreateFocusedFileList(Side == osLocal);
  843. try
  844. {
  845. assert(FileList->Count == 1);
  846. if (Side == osRemote)
  847. {
  848. TCopyParamType CopyParam = GUIConfiguration->CopyParam;
  849. if (FExecutedFileForceText)
  850. {
  851. CopyParam.TransferMode = tmAscii;
  852. }
  853. CopyParam.FileNameCase = ncNoChange;
  854. CopyParam.PreserveReadOnly = false;
  855. CopyParam.ResumeSupport = rsOff;
  856. AnsiString TempDir = UniqTempDir(WinConfiguration->DDTemporaryDirectory);
  857. ForceDirectories(TempDir);
  858. FAutoOperation = true;
  859. Terminal->ExceptionOnFail = true;
  860. try
  861. {
  862. Terminal->CopyToLocal(FileList, TempDir, &CopyParam, cpTemporary);
  863. }
  864. __finally
  865. {
  866. FAutoOperation = false;
  867. Terminal->ExceptionOnFail = false;
  868. }
  869. FExecutedFile = TempDir + FileList->Strings[0];
  870. }
  871. else
  872. {
  873. FExecutedFile = FileList->Strings[0];
  874. }
  875. }
  876. __finally
  877. {
  878. delete FileList;
  879. }
  880. Terminal->BeginTransaction();
  881. try
  882. {
  883. try
  884. {
  885. FExecutedFileTimestamp = FileAge(FExecutedFile);
  886. FFileExecutedBy = ExecuteFileBy;
  887. if (InternalEdit)
  888. {
  889. TNotifyEvent OnFileChanged = NULL;
  890. AnsiString Caption = FExecutedFile;
  891. if (Side == osRemote)
  892. {
  893. OnFileChanged = ExecutedFileChanged;
  894. Caption = RemoteDirView->Path + ExtractFileName(FExecutedFile);
  895. }
  896. DoEditorForm(FExecutedFile, this, OnFileChanged, Caption);
  897. }
  898. else
  899. {
  900. TDiscMonitor * DiscMonitor = NULL;
  901. try
  902. {
  903. if (Side == osRemote)
  904. {
  905. DiscMonitor = new TDiscMonitor(this);
  906. DiscMonitor->SubTree = false;
  907. DiscMonitor->Filters = TMonitorFilters() << moLastWrite;
  908. DiscMonitor->Directory = ExtractFilePath(FExecutedFile);
  909. DiscMonitor->OnChange = ExecutedFileChanged;
  910. DiscMonitor->Active = true;
  911. }
  912. TOperationStatusForm * StatusForm = new TOperationStatusForm(Application);
  913. try
  914. {
  915. StatusForm->Status = LoadStr(DOCUMENT_WAIT);
  916. StatusForm->ShowAsModal();
  917. if (Edit)
  918. {
  919. AnsiString ExternalEditor, Program, Params, Dir;
  920. ExternalEditor = WinConfiguration->Editor.ExternalEditor;
  921. TWinConfiguration::ReformatFileNameCommand(ExternalEditor);
  922. SplitCommand(ExternalEditor, Program, Params, Dir);
  923. assert(Params.Pos(ShellCommandFileNamePattern) > 0);
  924. Params = StringReplace(Params, ShellCommandFileNamePattern,
  925. AddPathQuotes(FExecutedFile), TReplaceFlags() << rfReplaceAll);
  926. if (ExecuteShellAndWait(Program, Params) < 0)
  927. {
  928. throw Exception(FMTLOAD(EDITOR_ERROR, (Program)));
  929. }
  930. }
  931. else
  932. {
  933. assert(Side == osRemote);
  934. if (ExecuteShellAndWait(FExecutedFile, "") < 0)
  935. {
  936. throw Exception(FMTLOAD(EXECUTE_FILE_ERROR, (FExecutedFile)));
  937. }
  938. }
  939. }
  940. __finally
  941. {
  942. delete StatusForm;
  943. }
  944. if (Side == osRemote)
  945. {
  946. if (DiscMonitor)
  947. {
  948. DiscMonitor->Active = false;
  949. }
  950. // upload file if it was saved while [editor] was closed
  951. ExecutedFileChanged(NULL);
  952. }
  953. }
  954. __finally
  955. {
  956. delete DiscMonitor;
  957. }
  958. }
  959. }
  960. __finally
  961. {
  962. AnsiString FileName = FExecutedFile;
  963. FExecutedFile = "";
  964. if (Side == osRemote)
  965. {
  966. bool Deleted;
  967. AnsiString DirName = ExtractFilePath(FileName);
  968. if (WinConfiguration->ForceDeleteTempFolder)
  969. {
  970. Deleted = RecursiveDeleteFile(ExcludeTrailingBackslash(DirName), false);
  971. }
  972. else
  973. {
  974. Deleted = DeleteFile(FileName) && RemoveDir(DirName);
  975. }
  976. if (!Deleted)
  977. {
  978. throw Exception(FMTLOAD(DELETE_TEMP_EXECUTE_FILE_ERROR, (DirName)));
  979. }
  980. }
  981. else
  982. {
  983. DirView(osLocal)->ReloadDirectory();
  984. }
  985. }
  986. }
  987. __finally
  988. {
  989. Terminal->EndTransaction();
  990. }
  991. }
  992. //---------------------------------------------------------------------------
  993. void __fastcall TCustomScpExplorerForm::ExecutedFileChanged(TObject * Sender)
  994. {
  995. static Uploading = 0;
  996. try
  997. {
  998. assert(!FExecutedFile.IsEmpty());
  999. if (Uploading == 1)
  1000. {
  1001. Uploading = 2;
  1002. }
  1003. else
  1004. {
  1005. Uploading = 1;
  1006. try
  1007. {
  1008. int FileTimestamp = FileAge(FExecutedFile);
  1009. if (FileTimestamp != FExecutedFileTimestamp)
  1010. {
  1011. FExecutedFileTimestamp = FileTimestamp;
  1012. TStrings * FileList = new TStringList();
  1013. try
  1014. {
  1015. FileList->Add(FExecutedFile);
  1016. TCopyParamType CopyParam = GUIConfiguration->CopyParam;
  1017. if (FExecutedFileForceText)
  1018. {
  1019. CopyParam.TransferMode = tmAscii;
  1020. }
  1021. CopyParam.FileNameCase = ncNoChange;
  1022. CopyParam.PreserveRights = false;
  1023. CopyParam.ResumeSupport = rsOff;
  1024. FAutoOperation = true;
  1025. Terminal->ExceptionOnFail = true;
  1026. try
  1027. {
  1028. Terminal->CopyToRemote(FileList, RemoteDirView->PathName,
  1029. &CopyParam, cpNoConfirmation);
  1030. }
  1031. __finally
  1032. {
  1033. FAutoOperation = false;
  1034. Terminal->ExceptionOnFail = false;
  1035. }
  1036. }
  1037. __finally
  1038. {
  1039. delete FileList;
  1040. }
  1041. }
  1042. }
  1043. __finally
  1044. {
  1045. if (Uploading == 2)
  1046. {
  1047. Uploading = 0;
  1048. ExecutedFileChanged(this);
  1049. }
  1050. else
  1051. {
  1052. Uploading = 0;
  1053. }
  1054. }
  1055. }
  1056. }
  1057. catch (Exception & E)
  1058. {
  1059. if (dynamic_cast<TDiscMonitor *> (Sender))
  1060. {
  1061. Terminal->DoHandleExtendedException(&E);
  1062. }
  1063. else
  1064. {
  1065. throw;
  1066. }
  1067. }
  1068. }
  1069. //---------------------------------------------------------------------------
  1070. void __fastcall TCustomScpExplorerForm::DirViewEnter(TObject *Sender)
  1071. {
  1072. DoDirViewEnter(dynamic_cast<TCustomDirView*>(Sender));
  1073. }
  1074. //---------------------------------------------------------------------------
  1075. void __fastcall TCustomScpExplorerForm::DoDirViewEnter(TCustomDirView * DirView)
  1076. {
  1077. assert(DirView != NULL);
  1078. FLastDirView = DirView;
  1079. }
  1080. //---------------------------------------------------------------------------
  1081. void __fastcall TCustomScpExplorerForm::DeleteFiles(TOperationSide Side,
  1082. TStrings * FileList)
  1083. {
  1084. assert(Terminal);
  1085. TCustomDirView * DView = DirView(Side);
  1086. DView->SaveSelection();
  1087. try
  1088. {
  1089. if (Side == osRemote)
  1090. {
  1091. Terminal->DeleteFiles(FileList);
  1092. }
  1093. else
  1094. {
  1095. try
  1096. {
  1097. Terminal->DeleteLocalFiles(FileList);
  1098. }
  1099. __finally
  1100. {
  1101. DView->Reload(true);
  1102. }
  1103. }
  1104. }
  1105. catch(...)
  1106. {
  1107. DView->DiscardSavedSelection();
  1108. throw;
  1109. }
  1110. DView->RestoreSelection();
  1111. }
  1112. //---------------------------------------------------------------------------
  1113. bool __fastcall TCustomScpExplorerForm::RemoteMoveDialog(TStrings * FileList,
  1114. AnsiString & Target, AnsiString & FileMask, bool NoConfirmation)
  1115. {
  1116. if (RemoteDirView->DropTarget != NULL)
  1117. {
  1118. assert(RemoteDirView->ItemIsDirectory(RemoteDirView->DropTarget));
  1119. Target = RemoteDirView->ItemFullFileName(RemoteDirView->DropTarget);
  1120. }
  1121. else
  1122. {
  1123. Target = RemoteDirView->Path;
  1124. }
  1125. Target = UnixIncludeTrailingBackslash(Target);
  1126. FileMask = "*.*";
  1127. bool Result = true;
  1128. if (!NoConfirmation)
  1129. {
  1130. Result = DoRemoteMoveDialog(FileList, Target, FileMask);
  1131. }
  1132. return Result;
  1133. }
  1134. //---------------------------------------------------------------------------
  1135. void __fastcall TCustomScpExplorerForm::RemoteMoveFiles(
  1136. TStrings * FileList, bool NoConfirmation)
  1137. {
  1138. AnsiString Target, FileMask;
  1139. if (RemoteMoveDialog(FileList, Target, FileMask, NoConfirmation))
  1140. {
  1141. RemoteDirView->SaveSelection();
  1142. try
  1143. {
  1144. Terminal->MoveFiles(FileList, Target, FileMask);
  1145. }
  1146. catch(...)
  1147. {
  1148. RemoteDirView->DiscardSavedSelection();
  1149. throw;
  1150. }
  1151. RemoteDirView->RestoreSelection();
  1152. }
  1153. }
  1154. //---------------------------------------------------------------------------
  1155. void __fastcall TCustomScpExplorerForm::CreateDirectory(TOperationSide Side)
  1156. {
  1157. AnsiString Name = LoadStr(NEW_FOLDER);
  1158. if (InputDialog(LoadStr(CREATE_FOLDER_CAPTION), LoadStr(CREATE_FOLDER_PROMPT), Name))
  1159. {
  1160. DirView(Side)->CreateDirectory(Name);
  1161. }
  1162. }
  1163. //---------------------------------------------------------------------------
  1164. void __fastcall TCustomScpExplorerForm::OpenDirectory(TOperationSide Side)
  1165. {
  1166. DoOpenDirectoryDialog(odBrowse, Side);
  1167. }
  1168. //---------------------------------------------------------------------------
  1169. void __fastcall TCustomScpExplorerForm::RemoteDirViewGetSelectFilter(
  1170. TCustomDirView *Sender, bool Select, TFileFilter &Filter)
  1171. {
  1172. assert(Sender);
  1173. if (!DoSelectMaskDialog(Sender, Select, &Filter, Configuration)) Abort();
  1174. }
  1175. //---------------------------------------------------------------------------
  1176. void __fastcall TCustomScpExplorerForm::SetProperties(TOperationSide Side, TStrings * FileList)
  1177. {
  1178. if (Side == osRemote)
  1179. {
  1180. TRemoteProperties CurrentProperties;
  1181. CurrentProperties = TRemoteProperties::CommonProperties(FileList);
  1182. int Flags = 0;
  1183. if (Terminal->IsCapable[fcModeChanging]) Flags |= cpMode;
  1184. if (Terminal->IsCapable[fcOwnerChanging]) Flags |= cpOwner;
  1185. if (Terminal->IsCapable[fcGroupChanging]) Flags |= cpGroup;
  1186. TRemoteProperties NewProperties = CurrentProperties;
  1187. if (DoPropertiesDialog(FileList, RemoteDirView->PathName,
  1188. Terminal->Groups, Terminal->Users, &NewProperties, Flags, Terminal))
  1189. {
  1190. NewProperties = TRemoteProperties::ChangedProperties(CurrentProperties, NewProperties);
  1191. Terminal->ChangeFilesProperties(FileList, &NewProperties);
  1192. }
  1193. }
  1194. else
  1195. {
  1196. DirView(Side)->DisplayPropertiesMenu();
  1197. }
  1198. }
  1199. //---------------------------------------------------------------------------
  1200. void __fastcall TCustomScpExplorerForm::KeyDown(Word & Key, Classes::TShiftState Shift)
  1201. {
  1202. if (QueueView->Focused() && (QueueView->OnKeyDown != NULL))
  1203. {
  1204. QueueView->OnKeyDown(QueueView, Key, Shift);
  1205. }
  1206. if (!DirView(osCurrent)->IsEditing())
  1207. {
  1208. TShortCut KeyShortCut = ShortCut(Key, Shift);
  1209. for (int Index = 0; Index < NonVisualDataModule->ExplorerActions->ActionCount; Index++)
  1210. {
  1211. TAction * Action = (TAction *)NonVisualDataModule->ExplorerActions->Actions[Index];
  1212. if (((Action->ShortCut == KeyShortCut) ||
  1213. (Action->SecondaryShortCuts->IndexOfShortCut(KeyShortCut) >= 0)) &&
  1214. AllowedAction(Action, aaShortCut))
  1215. {
  1216. Key = 0;
  1217. Action->Execute();
  1218. return;
  1219. }
  1220. }
  1221. for (int i = 0; i < NonVisualDataModule->OpenedSessionsMenu->Count; i++)
  1222. {
  1223. TMenuItem * Item = NonVisualDataModule->OpenedSessionsMenu->Items[i];
  1224. if (Item->ShortCut == KeyShortCut)
  1225. {
  1226. Key = 0;
  1227. Item->Click();
  1228. FIgnoreNextSysCommand = true;
  1229. return;
  1230. }
  1231. }
  1232. if (Key == VK_TAB && Shift.Contains(ssCtrl))
  1233. {
  1234. TTerminalManager::Instance()->CycleTerminals(!Shift.Contains(ssShift));
  1235. }
  1236. }
  1237. TForm::KeyDown(Key, Shift);
  1238. }
  1239. //---------------------------------------------------------------------------
  1240. void __fastcall TCustomScpExplorerForm::UpdateStatusBar()
  1241. {
  1242. TStatusBar * SessionStatusBar = (TStatusBar *)GetComponent(fcStatusBar);
  1243. assert(SessionStatusBar && (SessionStatusBar->Panels->Count >= 3));
  1244. if (FShowStatusBarHint)
  1245. {
  1246. SessionStatusBar->SimplePanel = true;
  1247. SessionStatusBar->SimpleText = FStatusBarHint;
  1248. }
  1249. else if (!Terminal || !Terminal->Active || Terminal->Status < sshReady)
  1250. {
  1251. // note: (Terminal->Status < sshReady) currently never happens here,
  1252. // so STATUS_CONNECTING is never used
  1253. SessionStatusBar->SimplePanel = true;
  1254. SessionStatusBar->SimpleText = LoadStr(
  1255. !Terminal || !Terminal->Active ? STATUS_DISCONNECTED : STATUS_CONNECTING);
  1256. }
  1257. else
  1258. {
  1259. assert(Terminal);
  1260. SessionStatusBar->SimplePanel = false;
  1261. int Index = SessionStatusBar->Tag;
  1262. SessionStatusBar->Panels->Items[Index]->Text = FormatBytes(Terminal->BytesReceived);
  1263. SessionStatusBar->Panels->Items[Index + 1]->Text = FormatBytes(Terminal->BytesSent);
  1264. SessionStatusBar->Panels->Items[Index + 5]->Text = Terminal->ProtocolName;
  1265. SessionStatusBar->Panels->Items[Index + 6]->Text =
  1266. FormatDateTime(Configuration->TimeFormat, Terminal->Duration);
  1267. }
  1268. }
  1269. //---------------------------------------------------------------------------
  1270. void __fastcall TCustomScpExplorerForm::SessionStatusBarDrawPanel(
  1271. TStatusBar *StatusBar, TStatusPanel *Panel, const TRect &Rect)
  1272. {
  1273. if (Terminal && Terminal->Active && Terminal->Status >= sshReady)
  1274. {
  1275. TFontStyles Style;
  1276. StatusBar->Font->Style = Style;
  1277. int ImageIndex;
  1278. AnsiString PanelText;
  1279. switch (Panel->Index - StatusBar->Tag) {
  1280. case 2: ImageIndex = Terminal->SshVersion - 1; break;
  1281. case 3: ImageIndex = 2 + (Terminal->CSCompression || Terminal->SCCompression); break;
  1282. case 4: ImageIndex = 4; PanelText = CipherNames[Terminal->CSCipher]; break;
  1283. default: assert(false); break;
  1284. }
  1285. TCanvas *SCanvas = StatusBar->Canvas;
  1286. if ((Panel->Alignment == taCenter) && PanelText.IsEmpty())
  1287. {
  1288. NonVisualDataModule->SessionImages->Draw(SCanvas,
  1289. Rect.Left + Rect.Width() / 2 - NonVisualDataModule->SessionImages->Width / 2,
  1290. Rect.Top, ImageIndex, true);
  1291. }
  1292. else
  1293. {
  1294. NonVisualDataModule->SessionImages->Draw(SCanvas,
  1295. Rect.Left + 1, Rect.Top, ImageIndex, true);
  1296. if (!PanelText.IsEmpty())
  1297. {
  1298. SCanvas->TextOut(Rect.left + 18, Rect.top + 1, PanelText);
  1299. }
  1300. }
  1301. }
  1302. }
  1303. //---------------------------------------------------------------------------
  1304. void __fastcall TCustomScpExplorerForm::Idle(bool AppIdle)
  1305. {
  1306. // terminal may not be active here, when connection is closed by remote side
  1307. // and coresponding error message is being displayed
  1308. if (Terminal && Terminal->Active)
  1309. {
  1310. Terminal->Idle();
  1311. }
  1312. if (AppIdle)
  1313. {
  1314. if (FRefreshRemoteDirectory)
  1315. {
  1316. if ((Terminal != NULL) && Terminal->Active)
  1317. {
  1318. Terminal->RefreshDirectory();
  1319. }
  1320. FRefreshRemoteDirectory = false;
  1321. }
  1322. if (FRefreshLocalDirectory)
  1323. {
  1324. if (HasDirView[osLocal])
  1325. {
  1326. DirView(osLocal)->ReloadDirectory();
  1327. }
  1328. FRefreshLocalDirectory = false;
  1329. }
  1330. }
  1331. if (FQueueStatusInvalidated)
  1332. {
  1333. UpdateQueueStatus();
  1334. }
  1335. TQueueItemProxy * PendingQueueActionItem = RefreshQueueItems();
  1336. if (AppIdle &&
  1337. GUIConfiguration->QueueAutoPopup &&
  1338. (PendingQueueActionItem != NULL) &&
  1339. (FPendingQueueActionItem == NULL))
  1340. {
  1341. FPendingQueueActionItem = PendingQueueActionItem;
  1342. FUserActionTimer->Enabled = true;
  1343. }
  1344. UpdateStatusBar();
  1345. FIgnoreNextSysCommand = false;
  1346. }
  1347. //---------------------------------------------------------------------------
  1348. void __fastcall TCustomScpExplorerForm::UserActionTimer(TObject * /*Sender*/)
  1349. {
  1350. try
  1351. {
  1352. FUserActionTimer->Enabled = false;
  1353. if (GUIConfiguration->QueueAutoPopup && (FPendingQueueActionItem != NULL))
  1354. {
  1355. if (TQueueItem::IsUserActionStatus(FPendingQueueActionItem->Status))
  1356. {
  1357. FPendingQueueActionItem->ProcessUserAction();
  1358. }
  1359. }
  1360. }
  1361. __finally
  1362. {
  1363. FPendingQueueActionItem = NULL;
  1364. }
  1365. }
  1366. //---------------------------------------------------------------------------
  1367. void __fastcall TCustomScpExplorerForm::SessionStatusBarMouseMove(
  1368. TObject * Sender, TShiftState /*Shift*/, int X, int Y)
  1369. {
  1370. if (Terminal && Terminal->Active)
  1371. {
  1372. const int Hints[3] = { STATUS_RECEIVED_HINT, STATUS_SENT_HINT, STATUS_DURATION_HINT };
  1373. TStatusBar * StatusBar = ((TStatusBar *)Sender);
  1374. assert(StatusBar);
  1375. TPoint Local(X, Y)/* = StatusBar->ScreenToClient(Mouse->CursorPos)*/;
  1376. int IPanel = 0;
  1377. while ((Local.x > StatusBar->Panels->Items[IPanel]->Width) &&
  1378. (IPanel < StatusBar->Panels->Count - 1))
  1379. {
  1380. Local.x -= StatusBar->Panels->Items[IPanel]->Width;
  1381. IPanel ++;
  1382. }
  1383. AnsiString AHint;
  1384. if (StatusBar->Tag && (IPanel == 0))
  1385. {
  1386. AHint = LoadStr(STATUS_FILEINFO_HINT);
  1387. }
  1388. else
  1389. {
  1390. if (StatusBar->Tag) IPanel--;
  1391. switch (IPanel) {
  1392. case 0:
  1393. case 1: AHint = LoadStr(Hints[IPanel]); break;
  1394. case 6: AHint = LoadStr(Hints[2]); break;
  1395. case 2: AHint = FMTLOAD(STATUS_VERSION_HINT, (Terminal->SshVersion)); break;
  1396. case 3:
  1397. if (Terminal->CSCompression == Terminal->SCCompression)
  1398. {
  1399. AHint = FMTLOAD(STATUS_COMPRESSION_HINT, (BooleanToStr(Terminal->CSCompression)));
  1400. }
  1401. else
  1402. {
  1403. AHint = FMTLOAD(STATUS_COMPRESSION2_HINT,
  1404. (BooleanToStr(Terminal->CSCompression), BooleanToStr(Terminal->SCCompression)));
  1405. }
  1406. break;
  1407. case 4:
  1408. if (Terminal->CSCipher == Terminal->SCCipher)
  1409. {
  1410. AHint = FMTLOAD(STATUS_ENCRYPTION_HINT, (CipherNames[Terminal->CSCipher]));
  1411. }
  1412. else
  1413. {
  1414. AHint = FMTLOAD(STATUS_ENCRYPTION2_HINT,
  1415. (CipherNames[Terminal->CSCipher], CipherNames[Terminal->SCCipher]));
  1416. }
  1417. break;
  1418. case 5:
  1419. AHint = FMTLOAD(STATUS_FS_PROTOCOL, (Terminal->ProtocolName));
  1420. break;
  1421. default: AHint = ""; break;
  1422. }
  1423. }
  1424. if (AHint.IsEmpty())
  1425. {
  1426. StatusBar->Hint = AHint;
  1427. }
  1428. else
  1429. {
  1430. AHint = FORMAT("%s|X", (AHint));
  1431. if (AHint != StatusBar->Hint)
  1432. {
  1433. Application->CancelHint();
  1434. StatusBar->Hint = AHint;
  1435. }
  1436. }
  1437. }
  1438. }
  1439. //---------------------------------------------------------------------------
  1440. void __fastcall TCustomScpExplorerForm::ApplicationHint(TObject * /*Sender*/)
  1441. {
  1442. assert(GetComponent(fcStatusBar) && Application);
  1443. AnsiString AHint = GetLongHint(Application->Hint);
  1444. FShowStatusBarHint = Active && !AHint.IsEmpty() && (AHint != "X");
  1445. if (FShowStatusBarHint)
  1446. {
  1447. FStatusBarHint = AHint != "E" ? AHint : AnsiString("");
  1448. }
  1449. else
  1450. {
  1451. FStatusBarHint = "";
  1452. }
  1453. UpdateStatusBar();
  1454. }
  1455. //---------------------------------------------------------------------------
  1456. void __fastcall TCustomScpExplorerForm::NewSession()
  1457. {
  1458. TSessionData * Data = new TSessionData("");
  1459. try
  1460. {
  1461. Data->Assign(StoredSessions->DefaultSettings);
  1462. if (DoLoginDialog(StoredSessions, Data, loAddSession))
  1463. {
  1464. assert(Data->CanLogin);
  1465. TTerminalManager * Manager = TTerminalManager::Instance();
  1466. TTerminal * Terminal = Manager->NewTerminal(Data);
  1467. Manager->ActiveTerminal = Terminal;
  1468. Manager->ConnectActiveTerminal();
  1469. }
  1470. }
  1471. __finally
  1472. {
  1473. delete Data;
  1474. }
  1475. }
  1476. //---------------------------------------------------------------------------
  1477. bool __fastcall TCustomScpExplorerForm::CanCloseQueue()
  1478. {
  1479. assert(FQueue != NULL);
  1480. return (FQueue->IsEmpty ||
  1481. (MessageDialog(LoadStr(PENDING_QUEUE_ITEMS), qtWarning, qaOK | qaCancel) == qaOK));
  1482. }
  1483. //---------------------------------------------------------------------------
  1484. void __fastcall TCustomScpExplorerForm::CloseSession()
  1485. {
  1486. if (CanCloseQueue())
  1487. {
  1488. TTerminalManager::Instance()->FreeActiveTerminal();
  1489. }
  1490. }
  1491. //---------------------------------------------------------------------------
  1492. void __fastcall TCustomScpExplorerForm::OpenStoredSession(TSessionData * Data)
  1493. {
  1494. TTerminalManager * Manager = TTerminalManager::Instance();
  1495. TTerminal * Terminal = Manager->NewTerminal(Data);
  1496. Manager->ActiveTerminal = Terminal;
  1497. Manager->ConnectActiveTerminal();
  1498. }
  1499. //---------------------------------------------------------------------------
  1500. void __fastcall TCustomScpExplorerForm::FormCloseQuery(TObject * /*Sender*/,
  1501. bool &CanClose)
  1502. {
  1503. if (Terminal->Active && WinConfiguration->ConfirmClosingSession)
  1504. {
  1505. int Result;
  1506. if (TTerminalManager::Instance()->Count > 1)
  1507. {
  1508. Result = MessageDialog(LoadStr(CLOSE_SESSIONS), qtConfirmation,
  1509. qaOK | qaCancel, 0, mpNeverAskAgainCheck);
  1510. }
  1511. else
  1512. {
  1513. Result = MessageDialog(FMTLOAD(CLOSE_SESSION,
  1514. (Terminal->SessionData->SessionName)), qtConfirmation,
  1515. qaOK | qaCancel, 0, mpNeverAskAgainCheck);
  1516. }
  1517. if (Result == qaNeverAskAgain)
  1518. {
  1519. WinConfiguration->ConfirmClosingSession = false;
  1520. }
  1521. CanClose = (Result == qaOK || Result == qaNeverAskAgain);
  1522. }
  1523. if (CanClose)
  1524. {
  1525. CanClose = CanCloseQueue();
  1526. }
  1527. }
  1528. //---------------------------------------------------------------------------
  1529. void __fastcall TCustomScpExplorerForm::DropDownButtonMenu(TObject *Sender)
  1530. {
  1531. ((TToolButton*)Sender)->CheckMenuDropdown();
  1532. }
  1533. //---------------------------------------------------------------------------
  1534. void __fastcall TCustomScpExplorerForm::RemoteDirViewDisplayProperties(
  1535. TObject *Sender)
  1536. {
  1537. TStrings *FileList = ((TUnixDirView*)Sender)->CreateFileList(True, False, NULL);
  1538. try
  1539. {
  1540. SetProperties(osRemote, FileList);
  1541. }
  1542. __finally
  1543. {
  1544. delete FileList;
  1545. }
  1546. }
  1547. //---------------------------------------------------------------------------
  1548. void __fastcall TCustomScpExplorerForm::SetComponentVisible(Word Component, Boolean value)
  1549. {
  1550. TControl * Control = GetComponent((Word)(Component & 0x00FF));
  1551. assert(Control);
  1552. bool Changed;
  1553. if ((dynamic_cast<TCoolBar*>(Control) != NULL) && (Component & 0xFF00))
  1554. {
  1555. TCoolBand * Band = GetCoolBand(dynamic_cast<TCoolBar*>(Control),
  1556. (Component & 0xFF00) >> 8);
  1557. assert(Band);
  1558. Changed = (Band->Visible != value);
  1559. if (Changed)
  1560. {
  1561. Band->Visible = value;
  1562. }
  1563. }
  1564. else
  1565. {
  1566. Changed = (Control->Visible != value);
  1567. if (Changed)
  1568. {
  1569. Control->Visible = value;
  1570. }
  1571. }
  1572. if (Changed)
  1573. {
  1574. FixControlsPlacement();
  1575. }
  1576. }
  1577. //---------------------------------------------------------------------------
  1578. bool __fastcall TCustomScpExplorerForm::GetComponentVisible(Word Component)
  1579. {
  1580. TControl * Control = GetComponent((Word)(Component & 0x00FF));
  1581. if (Control == NULL)
  1582. {
  1583. return false;
  1584. }
  1585. else if ((dynamic_cast<TCoolBar*>(Control) != NULL) && (Component & 0xFF00))
  1586. {
  1587. TCoolBand * Band = GetCoolBand(dynamic_cast<TCoolBar*>(Control),
  1588. (Component & 0xFF00) >> 8);
  1589. return Band != NULL ? Band->Visible : false;
  1590. }
  1591. else
  1592. {
  1593. return Control->Visible;
  1594. }
  1595. }
  1596. //---------------------------------------------------------------------------
  1597. void __fastcall TCustomScpExplorerForm::FixControlsPlacement()
  1598. {
  1599. TToolBar * MenuToolBar = dynamic_cast<TToolBar*>(GetComponent(fcMenuToolBar));
  1600. MenuToolBar->Height = MenuToolBar->Controls[0]->Height;
  1601. if (RemoteDirView->ItemFocused != NULL)
  1602. {
  1603. RemoteDirView->ItemFocused->MakeVisible(false);
  1604. }
  1605. QueueSplitter->Visible = QueuePanel->Visible;
  1606. }
  1607. //---------------------------------------------------------------------------
  1608. TCoolBand * __fastcall TCustomScpExplorerForm::GetCoolBand(TCoolBar * Coolbar, int ID)
  1609. {
  1610. return dynamic_cast<TCoolBand *>(Coolbar->Bands->FindItemID(ID));
  1611. }
  1612. //---------------------------------------------------------------------------
  1613. TControl * __fastcall TCustomScpExplorerForm::GetComponent(Byte Component)
  1614. {
  1615. switch (Component) {
  1616. case fcStatusBar: return RemoteStatusBar;
  1617. case fcCoolBar: return TopCoolBar;
  1618. case fcRemotePopup: return reinterpret_cast<TControl *>(NonVisualDataModule->RemoteDirViewPopup);
  1619. case fcQueueView: return QueuePanel;
  1620. case fcQueueToolbar: return QueueCoolBar;
  1621. default: return NULL;
  1622. }
  1623. }
  1624. //---------------------------------------------------------------------------
  1625. void __fastcall TCustomScpExplorerForm::DirViewColumnRightClick(
  1626. TObject *Sender, TListColumn *Column, TPoint &Point)
  1627. {
  1628. assert(NonVisualDataModule && Column && Sender);
  1629. NonVisualDataModule->ListColumn = Column;
  1630. TPoint ScreenPoint = ((TControl*)Sender)->ClientToScreen(Point);
  1631. TPopupMenu * DirViewColumnMenu;
  1632. if (Sender == RemoteDirView)
  1633. {
  1634. DirViewColumnMenu = NonVisualDataModule->RemoteDirViewColumnPopup;
  1635. }
  1636. else
  1637. {
  1638. DirViewColumnMenu = NonVisualDataModule->LocalDirViewColumnPopup;
  1639. }
  1640. DirViewColumnMenu->Popup(ScreenPoint.x, ScreenPoint.y);
  1641. }
  1642. //---------------------------------------------------------------------------
  1643. void __fastcall TCustomScpExplorerForm::DirViewExecFile(
  1644. TObject *Sender, TListItem *Item, bool &AllowExec)
  1645. {
  1646. DoDirViewExecFile(Sender, Item, AllowExec);
  1647. }
  1648. //---------------------------------------------------------------------------
  1649. void __fastcall TCustomScpExplorerForm::DoDirViewExecFile(TObject * Sender,
  1650. TListItem * Item, bool & AllowExec)
  1651. {
  1652. assert(Sender && Item && Configuration);
  1653. TCustomDirView * ADirView = (TCustomDirView *)Sender;
  1654. if (ADirView->ItemIsDirectory(Item))
  1655. {
  1656. AllowExec = true;
  1657. }
  1658. else if (WinConfiguration->CopyOnDoubleClick && !FForceExecution)
  1659. {
  1660. ExecuteFileOperation(foCopy,
  1661. (ADirView == DirView(osRemote) ? osRemote : osLocal),
  1662. true, !WinConfiguration->CopyOnDoubleClickConfirmation);
  1663. AllowExec = false;
  1664. }
  1665. else if (ADirView == DirView(osRemote) && !WinConfiguration->DisableOpenEdit)
  1666. {
  1667. ExecuteFile(osRemote, efDefault);
  1668. AllowExec = false;
  1669. }
  1670. else
  1671. {
  1672. AllowExec = true;
  1673. }
  1674. }
  1675. //---------------------------------------------------------------------------
  1676. bool __fastcall TCustomScpExplorerForm::GetHasDirView(TOperationSide Side)
  1677. {
  1678. return ((Side == osRemote) || (Side == osCurrent));
  1679. }
  1680. //---------------------------------------------------------------------------
  1681. void __fastcall TCustomScpExplorerForm::CompareDirectories()
  1682. {
  1683. assert(false);
  1684. }
  1685. //---------------------------------------------------------------------------
  1686. void __fastcall TCustomScpExplorerForm::SynchronizeDirectories()
  1687. {
  1688. assert(false);
  1689. }
  1690. //---------------------------------------------------------------------------
  1691. void __fastcall TCustomScpExplorerForm::FullSynchronizeDirectories()
  1692. {
  1693. assert(false);
  1694. }
  1695. //---------------------------------------------------------------------------
  1696. bool __fastcall TCustomScpExplorerForm::DoFullSynchronizeDirectories(
  1697. AnsiString & LocalDirectory, AnsiString & RemoteDirectory, TSynchronizeMode & Mode)
  1698. {
  1699. bool Result;
  1700. int Params = GUIConfiguration->SynchronizeParams;
  1701. bool SaveSettings;
  1702. Result = DoFullSynchronizeDialog(Mode, Params, LocalDirectory, RemoteDirectory,
  1703. SaveSettings);
  1704. if (Result)
  1705. {
  1706. if (SaveSettings)
  1707. {
  1708. GUIConfiguration->SynchronizeParams = Params;
  1709. }
  1710. assert(!FAutoOperation);
  1711. void * BatchStorage;
  1712. BatchStart(BatchStorage);
  1713. FAutoOperation = true;
  1714. try
  1715. {
  1716. TCopyParamType CopyParam = GUIConfiguration->CopyParam;
  1717. FSynchronizeProgressForm = new TSynchronizeProgressForm(Application);
  1718. FSynchronizeProgressForm->Start();
  1719. Terminal->Synchronize(LocalDirectory, RemoteDirectory,
  1720. static_cast<TTerminal::TSynchronizeMode>(Mode),
  1721. &CopyParam, Params, TerminalSynchronizeDirectory);
  1722. }
  1723. __finally
  1724. {
  1725. FAutoOperation = false;
  1726. SAFE_DESTROY(FSynchronizeProgressForm);
  1727. BatchEnd(BatchStorage);
  1728. if (HasDirView[osLocal])
  1729. {
  1730. DirView(osLocal)->Reload(true);
  1731. }
  1732. }
  1733. }
  1734. return Result;
  1735. }
  1736. //---------------------------------------------------------------------------
  1737. void __fastcall TCustomScpExplorerForm::TerminalSynchronizeDirectory(
  1738. const AnsiString LocalDirectory, const AnsiString RemoteDirectory, bool & Continue)
  1739. {
  1740. assert(FSynchronizeProgressForm != NULL);
  1741. FSynchronizeProgressForm->SetData(LocalDirectory, RemoteDirectory, Continue);
  1742. }
  1743. //---------------------------------------------------------------------------
  1744. void __fastcall TCustomScpExplorerForm::ExploreLocalDirectory()
  1745. {
  1746. assert(false);
  1747. }
  1748. //---------------------------------------------------------------------------
  1749. void __fastcall TCustomScpExplorerForm::SaveCurrentSession()
  1750. {
  1751. AnsiString SessionName;
  1752. SessionName = Terminal->SessionData->SessionName;
  1753. SessionName = DoSaveSessionDialog(StoredSessions, SessionName);
  1754. if (!SessionName.IsEmpty())
  1755. {
  1756. TSessionData * SessionData = new TSessionData("");
  1757. try
  1758. {
  1759. SessionData->Assign(Terminal->SessionData);
  1760. UpdateSessionData(SessionData);
  1761. StoredSessions->NewSession(SessionName, SessionData);
  1762. StoredSessions->Save();
  1763. }
  1764. __finally
  1765. {
  1766. delete SessionData;
  1767. }
  1768. }
  1769. }
  1770. //---------------------------------------------------------------------------
  1771. void __fastcall TCustomScpExplorerForm::UpdateSessionData(TSessionData * Data)
  1772. {
  1773. assert(Terminal && Terminal->SessionData);
  1774. if (!Data)
  1775. {
  1776. Data = Terminal->SessionData;
  1777. }
  1778. // cannot use RemoteDirView->Path, because it is empty if connection
  1779. // was already closed
  1780. Data->RemoteDirectory = Terminal->CurrentDirectory;
  1781. }
  1782. //---------------------------------------------------------------------------
  1783. void __fastcall TCustomScpExplorerForm::ToolBarResize(TObject *Sender)
  1784. {
  1785. TToolBar * ToolBar = (TToolBar*)Sender;
  1786. TControl * Child = (TControl *)ToolBar->Controls[0];
  1787. Child->Width = ToolBar->Width;
  1788. }
  1789. //---------------------------------------------------------------------------
  1790. void __fastcall TCustomScpExplorerForm::RemoteDirViewWarnLackOfTempSpace(
  1791. TUnixDirView * /*Sender*/, const AnsiString Path, __int64 RequiredSpace,
  1792. bool &Continue)
  1793. {
  1794. if (WinConfiguration->DDWarnLackOfTempSpace)
  1795. {
  1796. AnsiString ADrive = ExtractFileDrive(ExpandFileName(Path));
  1797. if (!ADrive.IsEmpty())
  1798. {
  1799. __int64 FreeSpace = DiskFree((Byte)(ADrive[1]-'A'+1));
  1800. Integer MessageRes = 0;
  1801. if (RequiredSpace >= 0)
  1802. {
  1803. __int64 RequiredWithReserve;
  1804. RequiredWithReserve = (__int64)(RequiredSpace * WinConfiguration->DDWarnLackOfTempSpaceRatio);
  1805. if (FreeSpace < RequiredWithReserve) MessageRes = DD_WARN_LACK_OF_TEMP_SPACE;
  1806. }
  1807. else
  1808. {
  1809. MessageRes = DD_WARN_UNKNOWN_TEMP_SPACE;
  1810. }
  1811. if (MessageRes)
  1812. {
  1813. int Result;
  1814. Result = MessageDialog(FMTLOAD(MessageRes, (Path,
  1815. FormatBytes(FreeSpace), FormatBytes(RequiredSpace))),
  1816. qtWarning, qaYes | qaNo, 0, mpNeverAskAgainCheck);
  1817. if (Result == qaNeverAskAgain)
  1818. {
  1819. WinConfiguration->DDWarnLackOfTempSpace = false;
  1820. }
  1821. Continue = (Result == qaYes || Result == qaNeverAskAgain);
  1822. }
  1823. }
  1824. }
  1825. }
  1826. //---------------------------------------------------------------------------
  1827. void __fastcall TCustomScpExplorerForm::AddBookmark(TOperationSide Side)
  1828. {
  1829. DoOpenDirectoryDialog(odAddBookmark, Side);
  1830. }
  1831. //---------------------------------------------------------------------------
  1832. TStrings * __fastcall TCustomScpExplorerForm::CreateVisitedDirectories(TOperationSide Side)
  1833. {
  1834. TStringList * VisitedDirectories = new TStringList();
  1835. try
  1836. {
  1837. TCustomDirView * DView = DirView(Side);
  1838. VisitedDirectories->Duplicates = dupIgnore;
  1839. // we should better use TCustomDirView::FCaseSensitive, but it is private
  1840. VisitedDirectories->CaseSensitive = (Side == osRemote);
  1841. VisitedDirectories->Sorted = true;
  1842. for (int Index = -DView->BackCount; Index <= DView->ForwardCount; Index++)
  1843. {
  1844. VisitedDirectories->Add(DView->HistoryPath[Index]);
  1845. }
  1846. }
  1847. catch (...)
  1848. {
  1849. delete VisitedDirectories;
  1850. throw;
  1851. }
  1852. return VisitedDirectories;
  1853. }
  1854. //---------------------------------------------------------------------------
  1855. void __fastcall TCustomScpExplorerForm::DoOpenDirectoryDialog(
  1856. TOpenDirectoryMode Mode, TOperationSide Side)
  1857. {
  1858. if (Mode != odAddBookmark ||
  1859. (MessageDialog(FMTLOAD(ADD_BOOKMARK_CONFIRM, (DirView(Side)->PathName)),
  1860. qtConfirmation, qaYes | qaNo, 0) == qaYes))
  1861. {
  1862. TStrings * VisitedDirectories = CreateVisitedDirectories(Side);
  1863. try
  1864. {
  1865. AnsiString Name = DirView(Side)->PathName;
  1866. if (::DoOpenDirectoryDialog(Mode, Side, Name, VisitedDirectories, Terminal))
  1867. {
  1868. DirView(Side)->Path = Name;
  1869. }
  1870. }
  1871. __finally
  1872. {
  1873. delete VisitedDirectories;
  1874. }
  1875. }
  1876. }
  1877. //---------------------------------------------------------------------------
  1878. void __fastcall TCustomScpExplorerForm::OpenInPutty()
  1879. {
  1880. OpenSessionInPutty(Terminal->SessionData);
  1881. }
  1882. //---------------------------------------------------------------------------
  1883. void __fastcall TCustomScpExplorerForm::OpenConsole(AnsiString Command)
  1884. {
  1885. DoConsoleDialog(Terminal, Command);
  1886. }
  1887. //---------------------------------------------------------------------------
  1888. void __fastcall TCustomScpExplorerForm::DirViewDDDragEnter(
  1889. TObject *Sender, _di_IDataObject /*DataObj*/, int /*grfKeyState*/,
  1890. const TPoint & /*Point*/, int & /*dwEffect*/, bool & Accept)
  1891. {
  1892. if ((DropSourceControl == RemoteDirView) &&
  1893. (FDDExtMapFile != NULL))
  1894. {
  1895. Accept = true;
  1896. }
  1897. FDDTargetDirView = (TCustomDirView*)Sender;
  1898. }
  1899. //---------------------------------------------------------------------------
  1900. void __fastcall TCustomScpExplorerForm::DirViewDDDragLeave(
  1901. TObject *Sender)
  1902. {
  1903. USEDPARAM(Sender);
  1904. assert(FDDTargetDirView == Sender);
  1905. FDDTargetDirView = NULL;
  1906. }
  1907. //---------------------------------------------------------------------------
  1908. void __fastcall TCustomScpExplorerForm::AddEditLink()
  1909. {
  1910. assert(FLastDirView == RemoteDirView);
  1911. bool Edit = false;
  1912. TRemoteFile * File = NULL;
  1913. AnsiString FileName;
  1914. AnsiString PointTo;
  1915. bool SymbolicLink = true;
  1916. if (RemoteDirView->ItemFocused)
  1917. {
  1918. assert(RemoteDirView->ItemFocused->Data);
  1919. File = (TRemoteFile *)RemoteDirView->ItemFocused->Data;
  1920. Edit = File->IsSymLink && Terminal->SessionData->ResolveSymlinks;
  1921. if (Edit)
  1922. {
  1923. FileName = File->FileName;
  1924. PointTo = File->LinkTo;
  1925. }
  1926. else
  1927. {
  1928. PointTo = File->FileName;
  1929. }
  1930. }
  1931. if (DoSymlinkDialog(FileName, PointTo, osRemote, SymbolicLink, Edit,
  1932. Terminal->IsCapable[fcHardLink]))
  1933. {
  1934. if (Edit)
  1935. {
  1936. assert(File->FileName == FileName);
  1937. bool Recursive = false;
  1938. Terminal->ExceptionOnFail = true;
  1939. try
  1940. {
  1941. Terminal->DeleteFile("", File, &Recursive);
  1942. }
  1943. __finally
  1944. {
  1945. Terminal->ExceptionOnFail = false;
  1946. }
  1947. }
  1948. Terminal->CreateLink(FileName, PointTo, SymbolicLink);
  1949. }
  1950. }
  1951. //---------------------------------------------------------------------------
  1952. void __fastcall TCustomScpExplorerForm::ExecuteCurrentFile()
  1953. {
  1954. assert(!WinConfiguration->DisableOpenEdit);
  1955. FForceExecution = true;
  1956. try
  1957. {
  1958. DirView(osCurrent)->ExecuteCurrentFile();
  1959. }
  1960. __finally
  1961. {
  1962. FForceExecution = false;
  1963. }
  1964. }
  1965. //---------------------------------------------------------------------------
  1966. void __fastcall TCustomScpExplorerForm::LastTerminalClosed(TObject * /*Sender*/)
  1967. {
  1968. try
  1969. {
  1970. NewSession();
  1971. }
  1972. __finally
  1973. {
  1974. if (!Terminal || !Terminal->Active)
  1975. {
  1976. Application->Terminate();
  1977. }
  1978. }
  1979. }
  1980. //---------------------------------------------------------------------------
  1981. void __fastcall TCustomScpExplorerForm::TerminalListChanged(TObject * /*Sender*/)
  1982. {
  1983. TCustomCombo * SessionCombo = dynamic_cast<TCustomCombo *>(GetComponent(fcSessionCombo));
  1984. if (SessionCombo != NULL)
  1985. {
  1986. SessionCombo->Items = TTerminalManager::Instance()->TerminalList;
  1987. SessionCombo->ItemIndex = TTerminalManager::Instance()->ActiveTerminalIndex;
  1988. }
  1989. NonVisualDataModule->CreateOpenedSessionListMenu();
  1990. }
  1991. //---------------------------------------------------------------------------
  1992. void __fastcall TCustomScpExplorerForm::SessionComboDropDown(TObject * Sender)
  1993. {
  1994. TCustomComboBox * SessionCombo = dynamic_cast<TCustomComboBox *>(Sender);
  1995. assert(SessionCombo);
  1996. TCanvas * Canvas = SessionCombo->Canvas;
  1997. int MaxWidth = 0, Width;
  1998. for (int i = 0; i < SessionCombo->Items->Count; i++)
  1999. {
  2000. Width = Canvas->TextExtent(SessionCombo->Items->Strings[i]).cx;
  2001. TShortCut ShortCut = NonVisualDataModule->OpenSessionShortCut(i);
  2002. if (ShortCut != scNone)
  2003. {
  2004. Width += Canvas->TextExtent(ShortCutToText(ShortCut)).cx;
  2005. }
  2006. if (Width > MaxWidth)
  2007. {
  2008. MaxWidth = Width;
  2009. }
  2010. }
  2011. MaxWidth += 8;
  2012. if (SessionCombo->Items->Count > ((TComboBox *)SessionCombo)->DropDownCount)
  2013. {
  2014. MaxWidth += GetSystemMetrics(SM_CXVSCROLL);
  2015. }
  2016. SessionCombo->Perform(CB_SETDROPPEDWIDTH, MaxWidth + 8 + 1, 0);
  2017. }
  2018. //---------------------------------------------------------------------------
  2019. void __fastcall TCustomScpExplorerForm::SessionComboDrawItem(
  2020. TWinControl * Control, int Index, const TRect & Rect, TOwnerDrawState /*State*/)
  2021. {
  2022. TCustomComboBox * SessionCombo = dynamic_cast<TCustomComboBox *>(Control);
  2023. assert(SessionCombo);
  2024. TCanvas * Canvas = SessionCombo->Canvas;
  2025. Canvas->FillRect(Rect);
  2026. if (Index >= 0)
  2027. {
  2028. int ShortCutWidth = 0;
  2029. AnsiString ShortCutStr;
  2030. if (Rect.Top != 3)
  2031. {
  2032. TShortCut ShortCut = NonVisualDataModule->OpenSessionShortCut(Index);
  2033. if (ShortCut != scNone)
  2034. {
  2035. ShortCutStr = ShortCutToText(ShortCut);
  2036. ShortCutWidth = Canvas->TextExtent(ShortCutStr).cx;
  2037. }
  2038. }
  2039. TRect R = Rect;
  2040. R.Right -= ShortCutWidth + 2;
  2041. Canvas->TextRect(R, R.Left + 2, R.Top, SessionCombo->Items->Strings[Index]);
  2042. R = Rect;
  2043. R.Left = R.Right - ShortCutWidth - 2;
  2044. Canvas->TextRect(R, R.Left, R.Top, ShortCutStr);
  2045. }
  2046. }
  2047. //---------------------------------------------------------------------------
  2048. void __fastcall TCustomScpExplorerForm::SessionComboChange(TObject * Sender)
  2049. {
  2050. TCustomComboBox * SessionCombo = dynamic_cast<TCustomComboBox *>(Sender);
  2051. assert(SessionCombo);
  2052. TTerminal * Terminal;
  2053. Terminal = dynamic_cast<TTerminal *>(SessionCombo->Items->Objects[SessionCombo->ItemIndex]);
  2054. assert(Terminal);
  2055. TTerminalManager::Instance()->ActiveTerminal = Terminal;
  2056. }
  2057. //---------------------------------------------------------------------------
  2058. void __fastcall TCustomScpExplorerForm::CMAppSysCommand(TMessage & Message)
  2059. {
  2060. TWMSysCommand * SysCommand = (TWMSysCommand *)Message.LParam;
  2061. if (SysCommand->CmdType != SC_KEYMENU || !FIgnoreNextSysCommand)
  2062. {
  2063. FIgnoreNextSysCommand = false;
  2064. TForm::Dispatch(&Message);
  2065. }
  2066. else
  2067. {
  2068. Message.Result = 1;
  2069. }
  2070. }
  2071. //---------------------------------------------------------------------------
  2072. void __fastcall TCustomScpExplorerForm::DoShow()
  2073. {
  2074. FixControlsPlacement();
  2075. TForm::DoShow();
  2076. }
  2077. //---------------------------------------------------------------------------
  2078. int __fastcall TCustomScpExplorerForm::MoreMessageDialog(const AnsiString Message,
  2079. TStrings * MoreMessages, TQueryType Type, int Answers,
  2080. int HelpCtx, int Params)
  2081. {
  2082. if (WinConfiguration->ContinueOnError && (Params & mpAllowContinueOnError) &&
  2083. FErrorList)
  2084. {
  2085. TStringList * MoreMessagesCopy = NULL;
  2086. if (MoreMessages)
  2087. {
  2088. MoreMessagesCopy = new TStringList();
  2089. MoreMessagesCopy->Assign(MoreMessages);
  2090. }
  2091. FErrorList->AddObject(Message, MoreMessagesCopy);
  2092. if (Answers & qaSkip) return qaSkip;
  2093. else
  2094. if (Answers & qaIgnore) return qaIgnore;
  2095. else
  2096. if (Answers & qaOK) return qaOK;
  2097. else
  2098. if (Answers & qaYes) return qaYes;
  2099. else
  2100. if (Answers & qaRetry) return qaRetry;
  2101. else
  2102. {
  2103. assert(false);
  2104. return qaYes;
  2105. }
  2106. }
  2107. else
  2108. {
  2109. return ::MoreMessageDialog(Message, MoreMessages, Type, Answers, HelpCtx, Params);
  2110. }
  2111. }
  2112. //---------------------------------------------------------------------------
  2113. void __fastcall TCustomScpExplorerForm::RemoteDirViewDDCreateDragFileList(
  2114. TObject * /*Sender*/, TFileList * FileList, bool & Created)
  2115. {
  2116. if (FDDExtMapFile != NULL)
  2117. {
  2118. CloseHandle(FDDExtMapFile);
  2119. FDDExtMapFile = NULL;
  2120. }
  2121. if (WinConfiguration->DDExtEnabled)
  2122. {
  2123. if (!WinConfiguration->DDExtInstalled)
  2124. {
  2125. throw Exception(LoadStr(DRAGEXT_TARGET_NOT_INSTALLED));
  2126. }
  2127. DDExtInitDrag(FileList, Created);
  2128. }
  2129. }
  2130. //---------------------------------------------------------------------------
  2131. void __fastcall TCustomScpExplorerForm::DDExtInitDrag(TFileList * FileList,
  2132. bool & Created)
  2133. {
  2134. FDragExtFakeDirectory =
  2135. ExcludeTrailingBackslash(UniqTempDir(WinConfiguration->DDTemporaryDirectory));
  2136. ForceDirectories(FDragExtFakeDirectory);
  2137. FileList->AddItem(NULL, FDragExtFakeDirectory);
  2138. Created = true;
  2139. FDDExtMapFile = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE,
  2140. 0, sizeof(TDragExtCommStruct), DRAG_EXT_MAPPING);
  2141. {
  2142. TMutexGuard Guard(FDDExtMutex, DRAGEXT_MUTEX_RELEASE_TIMEOUT);
  2143. TDragExtCommStruct* CommStruct;
  2144. CommStruct = static_cast<TDragExtCommStruct*>(MapViewOfFile(FDDExtMapFile,
  2145. FILE_MAP_ALL_ACCESS, 0, 0, 0));
  2146. assert(CommStruct != NULL);
  2147. CommStruct->Version = TDragExtCommStruct::CurrentVersion;
  2148. CommStruct->Dragging = true;
  2149. strncpy(CommStruct->DropDest, FDragExtFakeDirectory.c_str(),
  2150. sizeof(CommStruct->DropDest));
  2151. CommStruct->DropDest[sizeof(CommStruct->DropDest) - 1] = '\0';
  2152. UnmapViewOfFile(CommStruct);
  2153. }
  2154. FDDMoveSlipped = false;
  2155. }
  2156. //---------------------------------------------------------------------------
  2157. void __fastcall TCustomScpExplorerForm::RemoteDirViewDDEnd(TObject * /*Sender*/)
  2158. {
  2159. if (FDDExtMapFile != NULL)
  2160. {
  2161. try
  2162. {
  2163. if ((RemoteDirView->LastDDResult == drCopy) ||
  2164. (RemoteDirView->LastDDResult == drMove))
  2165. {
  2166. AnsiString TargetDirectory;
  2167. TFileOperation Operation;
  2168. Operation = (RemoteDirView->LastDDResult == drMove) ? foMove : foCopy;
  2169. if (FDDMoveSlipped)
  2170. {
  2171. Operation = foMove;
  2172. }
  2173. DDGetTarget(TargetDirectory);
  2174. ExecuteFileOperation(Operation, osRemote, true,
  2175. !WinConfiguration->DDTransferConfirmation, &TargetDirectory);
  2176. }
  2177. }
  2178. __finally
  2179. {
  2180. CloseHandle(FDDExtMapFile);
  2181. FDDExtMapFile = NULL;
  2182. RemoveDir(FDragExtFakeDirectory);
  2183. FDragExtFakeDirectory = "";
  2184. }
  2185. }
  2186. }
  2187. //---------------------------------------------------------------------------
  2188. void __fastcall TCustomScpExplorerForm::RemoteDirViewDDGiveFeedback(
  2189. TObject * /*Sender*/, int dwEffect, HRESULT & /*Result*/)
  2190. {
  2191. HCURSOR SlippedCopyCursor;
  2192. FDDMoveSlipped =
  2193. (FDragMoveCursor != NULL) &&
  2194. (!RemoteDirView->DDAllowMove) && (dwEffect == DROPEFFECT_Copy) &&
  2195. ((FDDTargetDirView == RemoteDirView) ||
  2196. ((FDDTargetDirView != NULL) && (GetKeyState(VK_SHIFT) < 0)));
  2197. SlippedCopyCursor = FDDMoveSlipped ? FDragMoveCursor : Dragdrop::DefaultCursor;
  2198. RemoteDirView->DragDropFilesEx->CHCopy = SlippedCopyCursor;
  2199. RemoteDirView->DragDropFilesEx->CHScrollCopy = SlippedCopyCursor;
  2200. }
  2201. //---------------------------------------------------------------------------
  2202. void __fastcall TCustomScpExplorerForm::DDGetTarget(AnsiString & Directory)
  2203. {
  2204. bool Result = false;
  2205. Enabled = false;
  2206. try
  2207. {
  2208. int Timer = 0;
  2209. while (!Result && (Timer < WinConfiguration->DDExtTimeout))
  2210. {
  2211. {
  2212. TMutexGuard Guard(FDDExtMutex, DRAGEXT_MUTEX_RELEASE_TIMEOUT);
  2213. TDragExtCommStruct* CommStruct;
  2214. CommStruct = static_cast<TDragExtCommStruct*>(MapViewOfFile(FDDExtMapFile,
  2215. FILE_MAP_ALL_ACCESS, 0, 0, 0));
  2216. assert(CommStruct != NULL);
  2217. Result = !CommStruct->Dragging;
  2218. if (Result)
  2219. {
  2220. Directory = ExtractFilePath(CommStruct->DropDest);
  2221. }
  2222. UnmapViewOfFile(CommStruct);
  2223. }
  2224. if (!Result)
  2225. {
  2226. Sleep(50);
  2227. Timer += 50;
  2228. Application->ProcessMessages();
  2229. }
  2230. }
  2231. }
  2232. __finally
  2233. {
  2234. Enabled = true;
  2235. }
  2236. if (!Result)
  2237. {
  2238. throw Exception(LoadStr(DRAGEXT_TARGET_UNKNOWN));
  2239. }
  2240. }
  2241. //---------------------------------------------------------------------------
  2242. void __fastcall TCustomScpExplorerForm::RemoteDirViewDDTargetDrop(
  2243. TUnixDirView * /*Sender*/, int DropEffect, bool & Continue)
  2244. {
  2245. if (FDDTargetDirView == RemoteDirView)
  2246. {
  2247. // when move from remote side is disabled, we allow coying inside the remote
  2248. // panel, but we interpret is as moving (we also slip in the move cursor)
  2249. if ((DropEffect == DROPEFFECT_MOVE) ||
  2250. ((!RemoteDirView->DDAllowMove) && (DropEffect == DROPEFFECT_COPY)))
  2251. {
  2252. ExecuteFileOperation(foRemoteMove, osRemote, true,
  2253. !WinConfiguration->DDTransferConfirmation);
  2254. }
  2255. // abort drag&drop
  2256. Abort();
  2257. }
  2258. else if (FDDExtMapFile != NULL)
  2259. {
  2260. Continue = false;
  2261. FDDDropTime = Now();
  2262. }
  2263. }
  2264. //---------------------------------------------------------------------------
  2265. class TFakeDataObjectFilesEx : public TDataObjectFilesEx
  2266. {
  2267. public:
  2268. __fastcall TFakeDataObjectFilesEx(TFileList * AFileList, bool RenderPIDL,
  2269. bool RenderFilename) : TDataObjectFilesEx(AFileList, RenderPIDL, RenderFilename)
  2270. {
  2271. }
  2272. virtual bool __fastcall AllowData(const tagFORMATETC & FormatEtc)
  2273. {
  2274. return (FormatEtc.cfFormat == CF_HDROP) ? false :
  2275. TDataObjectFilesEx::AllowData(FormatEtc);
  2276. }
  2277. };
  2278. //---------------------------------------------------------------------------
  2279. void __fastcall TCustomScpExplorerForm::RemoteDirViewDDCreateDataObject(
  2280. TObject * /*Sender*/, TDataObject *& DataObject)
  2281. {
  2282. if (FDDExtMapFile != NULL)
  2283. {
  2284. TFileList * FileList = RemoteDirView->DragDropFilesEx->FileList;
  2285. if (!FileList->RenderPIDLs() || !FileList->RenderNames())
  2286. {
  2287. Abort();
  2288. }
  2289. if (FileList->Count > 0)
  2290. {
  2291. TDataObjectFilesEx * FilesObject = new TFakeDataObjectFilesEx(FileList, true, true);
  2292. if (!FilesObject->IsValid(true, true))
  2293. {
  2294. FilesObject->_Release();
  2295. }
  2296. else
  2297. {
  2298. DataObject = FilesObject;
  2299. }
  2300. }
  2301. }
  2302. }
  2303. //---------------------------------------------------------------------------
  2304. void __fastcall TCustomScpExplorerForm::GoToCommandLine()
  2305. {
  2306. assert(false);
  2307. }
  2308. //---------------------------------------------------------------------------
  2309. void __fastcall TCustomScpExplorerForm::PanelExport(TOperationSide Side,
  2310. TPanelExport Export, TPanelExportDestination Destination, bool OnFocused)
  2311. {
  2312. Side = GetSide(Side);
  2313. TCustomDirView * DirView = this->DirView(Side);
  2314. TStringList * ExportData = new TStringList();
  2315. try
  2316. {
  2317. if (Export == pePath)
  2318. {
  2319. ExportData->Add(DirView->PathName);
  2320. }
  2321. else
  2322. {
  2323. bool FullPath = (Export == peFullFileList);
  2324. DirView->CreateFileList(OnFocused, FullPath, ExportData);
  2325. AnsiString FileName;
  2326. for (int Index = 0; Index < ExportData->Count; Index++)
  2327. {
  2328. if (ExportData->Strings[Index].Pos(" ") > 0)
  2329. {
  2330. ExportData->Strings[Index] = FORMAT("\"%s\"", (ExportData->Strings[Index]));
  2331. }
  2332. }
  2333. }
  2334. PanelExportStore(Side, Export, Destination, ExportData);
  2335. }
  2336. __finally
  2337. {
  2338. delete ExportData;
  2339. }
  2340. }
  2341. //---------------------------------------------------------------------------
  2342. void __fastcall TCustomScpExplorerForm::PanelExportStore(TOperationSide /*Side*/,
  2343. TPanelExport /*Export*/, TPanelExportDestination Destination,
  2344. TStringList * ExportData)
  2345. {
  2346. if (Destination == pedClipboard)
  2347. {
  2348. TClipboard * AClipboard = Clipboard();
  2349. if (ExportData->Count == 1)
  2350. {
  2351. AClipboard->AsText = ExportData->Strings[0];
  2352. }
  2353. else
  2354. {
  2355. AClipboard->AsText = ExportData->Text;
  2356. }
  2357. }
  2358. else
  2359. {
  2360. assert(false);
  2361. }
  2362. }
  2363. //---------------------------------------------------------------------------
  2364. TQueueOperation __fastcall TCustomScpExplorerForm::DefaultQueueOperation()
  2365. {
  2366. return FQueueController->DefaultOperation();
  2367. }
  2368. //---------------------------------------------------------------------------
  2369. bool __fastcall TCustomScpExplorerForm::AllowQueueOperation(
  2370. TQueueOperation Operation)
  2371. {
  2372. switch (Operation)
  2373. {
  2374. case qoPreferences:
  2375. return true;
  2376. case qoGoTo:
  2377. return ComponentVisible[fcQueueView];
  2378. default:
  2379. return FQueueController->AllowOperation(Operation);
  2380. }
  2381. }
  2382. //---------------------------------------------------------------------------
  2383. void __fastcall TCustomScpExplorerForm::ExecuteQueueOperation(
  2384. TQueueOperation Operation)
  2385. {
  2386. if (Operation == qoGoTo)
  2387. {
  2388. assert(QueueView->Visible);
  2389. QueueView->SetFocus();
  2390. }
  2391. else if (Operation == qoPreferences)
  2392. {
  2393. DoPreferencesDialog(pmQueue);
  2394. }
  2395. else
  2396. {
  2397. FQueueController->ExecuteOperation(Operation);
  2398. }
  2399. }
  2400. //---------------------------------------------------------------------------
  2401. void __fastcall TCustomScpExplorerForm::QueueViewContextPopup(
  2402. TObject * /*Sender*/, TPoint & /*MousePos*/, bool & /*Handled*/)
  2403. {
  2404. FQueueActedItem = QueueView->ItemFocused;
  2405. }
  2406. //---------------------------------------------------------------------------
  2407. /*virtual*/ int __fastcall TCustomScpExplorerForm::GetStaticComponentsHeight()
  2408. {
  2409. return TopCoolBar->Height + QueueSplitter->Height;
  2410. }
  2411. //---------------------------------------------------------------------------
  2412. void __fastcall TCustomScpExplorerForm::QueueSplitterCanResize(
  2413. TObject * /*Sender*/, int & NewSize, bool & /*Accept*/)
  2414. {
  2415. int HeightLimit = ClientHeight - GetStaticComponentsHeight() -
  2416. RemotePanel->Constraints->MinHeight;
  2417. if (NewSize > HeightLimit)
  2418. {
  2419. NewSize = HeightLimit;
  2420. }
  2421. }
  2422. //---------------------------------------------------------------------------
  2423. void __fastcall TCustomScpExplorerForm::StatusBarResize(
  2424. TObject * Sender)
  2425. {
  2426. RepaintStatusBar(dynamic_cast<TCustomStatusBar *>(Sender));
  2427. }
  2428. //---------------------------------------------------------------------------
  2429. void __fastcall TCustomScpExplorerForm::QueueViewStartDrag(TObject * /*Sender*/,
  2430. TDragObject *& /*DragObject*/)
  2431. {
  2432. FQueueActedItem = QueueView->ItemFocused;
  2433. }
  2434. //---------------------------------------------------------------------------
  2435. void __fastcall TCustomScpExplorerForm::QueueViewDragOver(TObject * /*Sender*/,
  2436. TObject * Source, int X, int Y, TDragState /*State*/, bool & Accept)
  2437. {
  2438. Accept = true;
  2439. if (Source == QueueView)
  2440. {
  2441. TListItem * DropTarget = QueueView->GetItemAt(X, Y);
  2442. Accept = (DropTarget != NULL) && (FQueueActedItem != NULL);
  2443. if (Accept)
  2444. {
  2445. TQueueItemProxy * QueueItem;
  2446. TQueueItemProxy * DestQueueItem;
  2447. QueueItem = static_cast<TQueueItemProxy *>(FQueueActedItem->Data);
  2448. DestQueueItem = static_cast<TQueueItemProxy *>(DropTarget->Data);
  2449. Accept = (QueueItem != DestQueueItem) &&
  2450. (QueueItem->Status == TQueueItem::qsPending) &&
  2451. (DestQueueItem->Status == TQueueItem::qsPending);
  2452. }
  2453. }
  2454. }
  2455. //---------------------------------------------------------------------------
  2456. void __fastcall TCustomScpExplorerForm::QueueViewDragDrop(TObject * /*Sender*/,
  2457. TObject * /*Source*/, int /*X*/, int /*Y*/)
  2458. {
  2459. if ((FQueueActedItem != NULL) && (QueueView->DropTarget != NULL))
  2460. {
  2461. TQueueItemProxy * QueueItem;
  2462. TQueueItemProxy * DestQueueItem;
  2463. QueueItem = static_cast<TQueueItemProxy *>(FQueueActedItem->Data);
  2464. DestQueueItem = static_cast<TQueueItemProxy *>(QueueView->DropTarget->Data);
  2465. QueueItem->Move(DestQueueItem);
  2466. }
  2467. }
  2468. //---------------------------------------------------------------------------
  2469. void __fastcall TCustomScpExplorerForm::QueueViewEnter(TObject * /*Sender*/)
  2470. {
  2471. if ((QueueView->ItemFocused == NULL) &&
  2472. (QueueView->Items->Count > 0))
  2473. {
  2474. QueueView->ItemFocused = QueueView->Items->Item[0];
  2475. }
  2476. }
  2477. //---------------------------------------------------------------------------
  2478. void __fastcall TCustomScpExplorerForm::QueueViewSelectItem(
  2479. TObject * /*Sender*/, TListItem * /*Item*/, bool Selected)
  2480. {
  2481. if (Selected)
  2482. {
  2483. NonVisualDataModule->UpdateNonVisibleActions();
  2484. }
  2485. }
  2486. //---------------------------------------------------------------------------