ScpCommander.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "ScpCommander.h"
  5. #include <Common.h>
  6. #include <Net.h>
  7. #include <ScpMain.h>
  8. #include <Interface.h>
  9. #include <TextsWin.h>
  10. #include "NonVisual.h"
  11. #include "Tools.h"
  12. #include "WinConfiguration.h"
  13. #include "TerminalManager.h"
  14. //---------------------------------------------------------------------------
  15. #pragma package(smart_init)
  16. #pragma link "AssociatedStatusBar"
  17. #pragma link "CustomDirView"
  18. #pragma link "CustomScpExplorer"
  19. #pragma link "CustomUnixDirView"
  20. #pragma link "IEListView"
  21. #pragma link "NortonLikeListView"
  22. #pragma link "UnixDirView"
  23. #pragma link "DirView"
  24. #pragma link "CustomPathComboBox"
  25. #pragma link "IEComboBox"
  26. #pragma link "IEPathComboBox"
  27. #pragma link "PathLabel"
  28. #pragma link "UnixPathComboBox"
  29. #pragma link "ToolbarPanel"
  30. #pragma resource "*.dfm"
  31. //---------------------------------------------------------------------------
  32. __fastcall TScpCommanderForm::TScpCommanderForm(TComponent* Owner)
  33. : TCustomScpExplorerForm(Owner)
  34. {
  35. FLastDirView = LocalDirView;
  36. FLastLocalPanelWidth = LocalPanelWidth;
  37. FSynchronization = ssStopped;
  38. FSynchronizeDialog = NULL;
  39. FSynchronisingBrowse = false;
  40. FFirstTerminal = true;
  41. LocalBackButton->DropdownMenu = LocalDirView->BackMenu;
  42. LocalForwardButton->DropdownMenu = LocalDirView->ForwardMenu;
  43. RemoteBackButton->DropdownMenu = RemoteDirView->BackMenu;
  44. RemoteForwardButton->DropdownMenu = RemoteDirView->ForwardMenu;
  45. SavedSessionsButton->OnClick = DropDownButtonMenu;
  46. TopCoolBar->PopupMenu = NonVisualDataModule->CommanderBarPopup;
  47. ToolbarPanel->PopupMenu = TopCoolBar->PopupMenu;
  48. StatusBar->PopupMenu = TopCoolBar->PopupMenu;
  49. LocalCoolBar->PopupMenu = NonVisualDataModule->LocalPanelPopup;
  50. LocalPathLabel->PopupMenu = LocalCoolBar->PopupMenu;
  51. LocalStatusBar->PopupMenu = LocalCoolBar->PopupMenu;
  52. RemoteCoolBar->PopupMenu = NonVisualDataModule->RemotePanelPopup;
  53. RemotePathLabel->PopupMenu = RemoteCoolBar->PopupMenu;
  54. RemoteStatusBar->PopupMenu = RemoteCoolBar->PopupMenu;
  55. // set common norton shorcuts to our actions
  56. NonVisualDataModule->CommanderShortcuts();
  57. Splitter->ShowHint = True;
  58. ((TLabel*)Splitter)->OnDblClick = SplitterDblClick;
  59. RemotePathComboBox->TabStop = False;
  60. LocalDirView->Font = Screen->IconFont;
  61. }
  62. //---------------------------------------------------------------------------
  63. void __fastcall TScpCommanderForm::RestoreFormParams()
  64. {
  65. assert(WinConfiguration);
  66. TCustomScpExplorerForm::RestoreFormParams();
  67. WinConfiguration->RestoreForm(WinConfiguration->ScpCommander.WindowParams, this);
  68. }
  69. //---------------------------------------------------------------------------
  70. void __fastcall TScpCommanderForm::RestoreParams()
  71. {
  72. assert(Configuration);
  73. // called later once again after menu font is updated (see FormShow)
  74. SetCoolBandsMinWidth(TopCoolBar);
  75. SetCoolBandsMinWidth(LocalCoolBar);
  76. SetCoolBandsMinWidth(RemoteCoolBar);
  77. // IDE often looses this link
  78. LocalDirView->HeaderImages = NonVisualDataModule->ArrowImages;
  79. TCustomScpExplorerForm::RestoreParams();
  80. LocalPanelWidth = WinConfiguration->ScpCommander.LocalPanelWidth;
  81. LoadCoolbarLayoutStr(TopCoolBar, WinConfiguration->ScpCommander.CoolBarLayout);
  82. StatusBar->Visible = WinConfiguration->ScpCommander.StatusBar;
  83. ToolbarPanel->Visible = WinConfiguration->ScpCommander.ToolBar;
  84. FDirViewToSelect = (WinConfiguration->ScpCommander.CurrentPanel == osLocal ?
  85. (TCustomDirView *)LocalDirView : (TCustomDirView *)RemoteDirView);
  86. #define RESTORE_PANEL_PARAMS(PANEL) \
  87. PANEL ## DirView->ColProperties->ParamsStr = WinConfiguration->ScpCommander.PANEL ## Panel.DirViewParams; \
  88. PANEL ## StatusBar->Visible = WinConfiguration->ScpCommander.PANEL ## Panel.StatusBar; \
  89. LoadCoolbarLayoutStr(PANEL ## CoolBar, WinConfiguration->ScpCommander.PANEL ## Panel.CoolBarLayout)
  90. RESTORE_PANEL_PARAMS(Local);
  91. RESTORE_PANEL_PARAMS(Remote);
  92. #undef RESTORE_PANEL_PARAMS
  93. }
  94. //---------------------------------------------------------------------------
  95. void __fastcall TScpCommanderForm::StoreParams()
  96. {
  97. assert(WinConfiguration);
  98. WinConfiguration->BeginUpdate();
  99. try
  100. {
  101. WinConfiguration->ScpCommander.CoolBarLayout = GetCoolbarLayoutStr(TopCoolBar);
  102. WinConfiguration->ScpCommander.LocalPanelWidth = LocalPanelWidth;
  103. WinConfiguration->ScpCommander.StatusBar = StatusBar->Visible;
  104. WinConfiguration->ScpCommander.ToolBar = ToolbarPanel->Visible;
  105. WinConfiguration->ScpCommander.CurrentPanel =
  106. ((FLastDirView == LocalDirView) ? osLocal : osRemote);
  107. #define STORE_PANEL_PARAMS(PANEL) \
  108. WinConfiguration->ScpCommander.PANEL ## Panel.DirViewParams = PANEL ## DirView->ColProperties->ParamsStr; \
  109. WinConfiguration->ScpCommander.PANEL ## Panel.StatusBar = PANEL ## StatusBar->Visible; \
  110. WinConfiguration->ScpCommander.PANEL ## Panel.CoolBarLayout = GetCoolbarLayoutStr(PANEL ## CoolBar)
  111. STORE_PANEL_PARAMS(Local);
  112. STORE_PANEL_PARAMS(Remote);
  113. #undef RESTORE_PANEL_PARAMS
  114. WinConfiguration->ScpCommander.WindowParams = WinConfiguration->StoreForm(this);;
  115. TCustomScpExplorerForm::StoreParams();
  116. }
  117. __finally
  118. {
  119. WinConfiguration->EndUpdate();
  120. }
  121. }
  122. //---------------------------------------------------------------------------
  123. void __fastcall TScpCommanderForm::UpdateSessionData(TSessionData * Data)
  124. {
  125. assert(Terminal && Terminal->SessionData);
  126. if (!Data)
  127. {
  128. Data = Terminal->SessionData;
  129. }
  130. TCustomScpExplorerForm::UpdateSessionData(Data);
  131. if (Data->UpdateDirectories || (Data != Terminal->SessionData))
  132. {
  133. assert(LocalDirView);
  134. Data->LocalDirectory = LocalDirView->PathName;
  135. Terminal->UserObject = NULL;
  136. }
  137. else
  138. {
  139. if (!Terminal->UserObject)
  140. {
  141. Terminal->UserObject = new TTerminalUserObject();
  142. }
  143. dynamic_cast<TTerminalUserObject *>(Terminal->UserObject)->LocalDirectory =
  144. LocalDirView->PathName;
  145. }
  146. }
  147. //---------------------------------------------------------------------------
  148. bool __fastcall TScpCommanderForm::CopyParamDialog(TTransferDirection Direction,
  149. TTransferType Type, bool DragDrop, TStrings * FileList, AnsiString & TargetDirectory,
  150. TCopyParamType & CopyParam, bool Confirm)
  151. {
  152. if (DragDrop && Direction == tdToLocal && FDDTargetDirView == LocalDirView)
  153. {
  154. if (LocalDirView->DropTarget)
  155. {
  156. // when drop target is not directory, it is probably file type, which have
  157. // associated drop handler (sich as ZIP file in WinXP). in this case we
  158. // must leave drop handling to destination application.
  159. DragDrop = !LocalDirView->ItemIsDirectory(LocalDirView->DropTarget);
  160. if (!DragDrop)
  161. {
  162. TargetDirectory = LocalDirView->ItemFullFileName(LocalDirView->DropTarget);
  163. }
  164. }
  165. else
  166. {
  167. DragDrop = false;
  168. TargetDirectory = IncludeTrailingBackslash(LocalDirView->Path);
  169. }
  170. }
  171. else if (!DragDrop)
  172. {
  173. if (Direction == tdToLocal)
  174. {
  175. TargetDirectory = IncludeTrailingBackslash(LocalDirView->Path);
  176. }
  177. else
  178. {
  179. TargetDirectory = UnixIncludeTrailingBackslash(RemoteDirView->Path);
  180. }
  181. }
  182. return TCustomScpExplorerForm::CopyParamDialog(Direction, Type, DragDrop,
  183. FileList, TargetDirectory, CopyParam, Confirm);
  184. }
  185. //---------------------------------------------------------------------------
  186. void __fastcall TScpCommanderForm::FormShow(TObject */*Sender*/)
  187. {
  188. assert(FDirViewToSelect);
  189. FDirViewToSelect->SetFocus();
  190. // called for second time after menu font was updated (see also RestoreParams)
  191. SetCoolBandsMinWidth(TopCoolBar);
  192. SetCoolBandsMinWidth(LocalCoolBar);
  193. SetCoolBandsMinWidth(RemoteCoolBar);
  194. UpdateControls();
  195. }
  196. //---------------------------------------------------------------------------
  197. Boolean __fastcall TScpCommanderForm::AllowedAction(TAction * Action, TActionAllowed Allowed)
  198. {
  199. #define FLAG ((TActionFlag)(Action->Tag))
  200. return
  201. // always require Commander flag
  202. (FLAG & afCommander) &&
  203. // if action is execution or update, we don't require any other flag
  204. // if we check for shortcut, we require proper dirview to be selected
  205. ((Allowed != aaShortCut) ||
  206. ((FLAG & afLocal) && (FLastDirView == LocalDirView)) ||
  207. ((FLAG & afRemote) && (FLastDirView == RemoteDirView))
  208. );
  209. #undef FLAG
  210. }
  211. //---------------------------------------------------------------------------
  212. TCustomDirView * __fastcall TScpCommanderForm::DirView(TOperationSide Side)
  213. {
  214. switch (Side) {
  215. case osCurrent: return FLastDirView;
  216. case osLocal: return LocalDirView;
  217. case osRemote: return RemoteDirView;
  218. default: assert(false); return NULL;
  219. }
  220. }
  221. //---------------------------------------------------------------------------
  222. void __fastcall TScpCommanderForm::ExecuteFileOperation(::TFileOperation Operation, TOperationSide Side, Boolean OnFocused)
  223. {
  224. TCustomScpExplorerForm::ExecuteFileOperation(Operation, Side, OnFocused);
  225. }
  226. //---------------------------------------------------------------------------
  227. void __fastcall TScpCommanderForm::TerminalChanged()
  228. {
  229. TCustomScpExplorerForm::TerminalChanged();
  230. if (Terminal)
  231. {
  232. if (FFirstTerminal || !WinConfiguration->ScpCommander.PreserveLocalDirectory)
  233. {
  234. AnsiString LocalDirectory;
  235. if (Terminal->UserObject)
  236. {
  237. LocalDirectory = dynamic_cast<TTerminalUserObject *>(Terminal->UserObject)->LocalDirectory;
  238. }
  239. else
  240. {
  241. LocalDirectory = Terminal->SessionData->LocalDirectory;
  242. }
  243. bool DocumentsDir = LocalDirectory.IsEmpty();
  244. if (!DocumentsDir)
  245. {
  246. try
  247. {
  248. LocalDirView->Path = LocalDirectory;
  249. }
  250. catch(Exception & E)
  251. {
  252. DocumentsDir = true;
  253. ShowExtendedException(&E, this);
  254. }
  255. }
  256. if (DocumentsDir)
  257. {
  258. LocalDirView->HomeDirectory = "";
  259. LocalDirView->ExecuteHomeDirectory();
  260. }
  261. if (Configuration->DefaultDirIsHome &&
  262. !Terminal->SessionData->UpdateDirectories)
  263. {
  264. LocalDirView->HomeDirectory = LocalDirectory;
  265. }
  266. }
  267. FFirstTerminal = false;
  268. }
  269. }
  270. //---------------------------------------------------------------------------
  271. void __fastcall TScpCommanderForm::ConfigurationChanged()
  272. {
  273. TCustomScpExplorerForm::ConfigurationChanged();
  274. if (Configuration->DefaultDirIsHome && Terminal)
  275. {
  276. LocalDirView->HomeDirectory = Terminal->SessionData->LocalDirectory;
  277. }
  278. else
  279. {
  280. LocalDirView->HomeDirectory = "";
  281. }
  282. LocalDirView->DimmHiddenFiles = WinConfiguration->DimmHiddenFiles;
  283. LocalDirView->ShowHiddenFiles = WinConfiguration->ShowHiddenFiles;
  284. LocalDirView->NortonLike = !WinConfiguration->ScpCommander.ExplorerStyleSelection;
  285. RemoteDirView->NortonLike = !WinConfiguration->ScpCommander.ExplorerStyleSelection;
  286. }
  287. //---------------------------------------------------------------------------
  288. void __fastcall TScpCommanderForm::SetLocalPanelWidth(float value)
  289. {
  290. float Total = LocalPanel->Width + RemotePanel->Width;
  291. FLocalPanelWidth = value;
  292. if (value * Total != LocalPanel->Width)
  293. {
  294. LocalPanel->Width = value * Total;
  295. UpdateControls();
  296. }
  297. }
  298. //---------------------------------------------------------------------------
  299. float __fastcall TScpCommanderForm::GetLocalPanelWidth()
  300. {
  301. return FLocalPanelWidth;
  302. }
  303. //---------------------------------------------------------------------------
  304. void __fastcall TScpCommanderForm::SplitterMoved(TObject * /*Sender*/)
  305. {
  306. float Local = LocalPanel->Width;
  307. float Total = LocalPanel->Width + RemotePanel->Width;
  308. FLocalPanelWidth = Local / Total;
  309. FLastLocalPanelWidth = LocalPanelWidth;
  310. UpdateControls();
  311. }
  312. //---------------------------------------------------------------------------
  313. void __fastcall TScpCommanderForm::SplitterCanResize(TObject * /*Sender*/,
  314. int &NewSize, bool & /*Accept*/)
  315. {
  316. // When splitter is drag so far to right, that width contraint of remote panel would
  317. // be violated, it doesn't stop, but extend form width.
  318. // Following prevents this behaviour.
  319. if (ClientWidth - NewSize - Splitter->Width < RemotePanel->Constraints->MinWidth)
  320. NewSize = (ClientWidth - RemotePanel->Constraints->MinWidth - Splitter->Width);
  321. }
  322. //---------------------------------------------------------------------------
  323. void __fastcall TScpCommanderForm::SplitterDblClick(TObject * /*Sender*/)
  324. {
  325. LocalPanelWidth = 0.5;
  326. }
  327. //---------------------------------------------------------------------------
  328. void __fastcall TScpCommanderForm::UpdateControls()
  329. {
  330. Splitter->Hint = FormatFloat("0%|X", LocalPanelWidth*100);
  331. }
  332. //---------------------------------------------------------------------------
  333. void __fastcall TScpCommanderForm::ChangePath(TOperationSide Side)
  334. {
  335. assert((Side == osLocal) || (Side == osRemote));
  336. TCustomPathComboBox * PathComboBox;
  337. if (Side == osLocal) PathComboBox = LocalPathComboBox;
  338. else PathComboBox = RemotePathComboBox;
  339. assert(PathComboBox);
  340. PathComboBox->SetFocus();
  341. PathComboBox->DroppedDown = True;
  342. }
  343. //---------------------------------------------------------------------------
  344. void __fastcall TScpCommanderForm::PathComboBoxCloseUp(TObject * /*Sender*/,
  345. bool /*Canceled*/)
  346. {
  347. assert(FLastDirView);
  348. FLastDirView->SetFocus();
  349. }
  350. //---------------------------------------------------------------------------
  351. void __fastcall TScpCommanderForm::SessionComboCloseUp(TObject *Sender)
  352. {
  353. PathComboBoxCloseUp(Sender, false);
  354. }
  355. //---------------------------------------------------------------------------
  356. void __fastcall TScpCommanderForm::FormResize(TObject * /*Sender*/)
  357. {
  358. LocalPanelWidth = FLastLocalPanelWidth;
  359. UpdateControls();
  360. }
  361. //---------------------------------------------------------------------------
  362. TControl * __fastcall TScpCommanderForm::GetComponent(Byte Component)
  363. {
  364. switch (Component) {
  365. case fcToolBar: return ToolbarPanel;
  366. case fcStatusBar: return StatusBar;
  367. case fcLocalCoolBar: return LocalCoolBar;
  368. case fcLocalStatusBar: return LocalStatusBar;
  369. case fcRemoteCoolBar: return RemoteCoolBar;
  370. case fcRemoteStatusBar: return RemoteStatusBar;
  371. case fcSessionCombo: return SessionCombo;
  372. case fcMenuToolBar: return MenuToolBar;
  373. default: return TCustomScpExplorerForm::GetComponent(Component);
  374. }
  375. }
  376. //---------------------------------------------------------------------------
  377. void __fastcall TScpCommanderForm::SetComponentVisible(Word Component, Boolean value)
  378. {
  379. TCustomScpExplorerForm::SetComponentVisible(Component, value);
  380. if (StatusBar->Top < ToolbarPanel->Top)
  381. StatusBar->Top = ToolbarPanel->Top + ToolbarPanel->Height;
  382. }
  383. //---------------------------------------------------------------------------
  384. void __fastcall TScpCommanderForm::KeyDown(Word & Key, Classes::TShiftState Shift)
  385. {
  386. // duplicate shortcut for deleting
  387. if ((ShortCut(VK_DELETE, TShiftState()) == ShortCut(Key, Shift)) &&
  388. !DirView(osCurrent)->IsEditing())
  389. {
  390. NonVisualDataModule->CurrentDeleteAction->Execute();
  391. Key = 0;
  392. }
  393. else
  394. TCustomScpExplorerForm::KeyDown(Key, Shift);
  395. } /* TScpCommanderForm::KeyDown */
  396. //---------------------------------------------------------------------------
  397. Boolean __fastcall TScpCommanderForm::GetHasDirView(TOperationSide Side)
  398. {
  399. return TCustomScpExplorerForm::GetHasDirView(Side) || (Side == osLocal);
  400. }
  401. //---------------------------------------------------------------------------
  402. void __fastcall TScpCommanderForm::CompareDirectories()
  403. {
  404. LocalDirView->CompareFiles(RemoteDirView);
  405. RemoteDirView->CompareFiles(LocalDirView);
  406. if (LocalDirView->SelCount + RemoteDirView->SelCount == 0)
  407. {
  408. MessageDialog(LoadStr(COMPARE_NO_DIFFERENCES), qtInformation, qaOK, 0);
  409. }
  410. }
  411. //---------------------------------------------------------------------------
  412. void __fastcall TScpCommanderForm::SynchronizeDirectories()
  413. {
  414. TSynchronizeParamType Params;
  415. Params.CopyParams.Assign(Configuration->CopyParam);
  416. Params.AllowTransferMode = Terminal->IsCapable[fcTextMode];
  417. if (!Params.AllowTransferMode) Params.CopyParams.TransferMode = tmBinary;
  418. Params.LocalDirectory = LocalDirView->PathName;
  419. Params.RemoteDirectory = RemoteDirView->PathName;
  420. DoSynchronizeDialog(Params, SynchronizeStartStop);
  421. }
  422. //---------------------------------------------------------------------------
  423. void __fastcall TScpCommanderForm::SynchronizeStartStop(System::TObject* Sender,
  424. bool Start, TSynchronizeParamType Params)
  425. {
  426. FSynchronization = (Start ? ssWaiting : ssStopped);
  427. if (Start)
  428. {
  429. FSynchronizeDialog = (TSynchronizeDialog *)Sender;
  430. FSynchronizeParams = Params;
  431. SynchronizeNow();
  432. }
  433. else
  434. {
  435. FSynchronizeDialog = NULL;
  436. }
  437. }
  438. //---------------------------------------------------------------------------
  439. void __fastcall TScpCommanderForm::LocalDirViewChangeDetected(
  440. TObject * /*Sender*/)
  441. {
  442. switch (FSynchronization) {
  443. case ssWaiting: SynchronizeNow(); break;
  444. case ssSynchronizing: FSynchronization = ssSynchronize; break;
  445. }
  446. }
  447. //---------------------------------------------------------------------------
  448. void __fastcall TScpCommanderForm::SynchronizeNow()
  449. {
  450. try
  451. {
  452. TStrings * ChangedFiles;
  453. FSynchronization = ssSynchronize;
  454. try
  455. {
  456. // repeat until there is any change pending (see ::LocalDirViewChangeDetected)
  457. while (FSynchronization == ssSynchronize)
  458. {
  459. FSynchronization = ssSynchronizing;
  460. ChangedFiles = LocalDirView->CreateChangedFileList(RemoteDirView, true);
  461. Terminal->ExceptionOnFail = true;
  462. try
  463. {
  464. if (ChangedFiles->Count > 0)
  465. {
  466. Terminal->CopyToRemote(ChangedFiles, FSynchronizeParams.RemoteDirectory,
  467. &FSynchronizeParams.CopyParams, 0);
  468. }
  469. }
  470. __finally
  471. {
  472. delete ChangedFiles;
  473. Terminal->ExceptionOnFail = false;
  474. }
  475. }
  476. }
  477. __finally
  478. {
  479. FSynchronization = ssWaiting;
  480. }
  481. }
  482. catch (EFatal & E)
  483. {
  484. throw;
  485. }
  486. catch(Exception & E)
  487. {
  488. assert(FSynchronizeDialog);
  489. FSynchronizeDialog->Stop();
  490. ShowExtendedException(&E);
  491. }
  492. }
  493. //---------------------------------------------------------------------------
  494. void __fastcall TScpCommanderForm::DoOperationFinished(TOperationSide Side,
  495. bool DragDrop, const AnsiString FileName, bool Success,
  496. bool & DisconnectWhenFinished)
  497. {
  498. if (FSynchronization == ssStopped)
  499. {
  500. TCustomScpExplorerForm::DoOperationFinished(Side, DragDrop, FileName,
  501. Success, DisconnectWhenFinished);
  502. }
  503. }
  504. //---------------------------------------------------------------------------
  505. void __fastcall TScpCommanderForm::ExploreLocalDirectory()
  506. {
  507. if ((int)ShellExecute(Application->Handle, "explore",
  508. (char*)LocalDirView->Path.data(), NULL, NULL, SW_SHOWNORMAL) <= 32)
  509. {
  510. throw Exception(FORMAT(EXPLORE_LOCAL_DIR_ERROR, (LocalDirView->Path)));
  511. }
  512. }
  513. //---------------------------------------------------------------------------
  514. void __fastcall TScpCommanderForm::LocalDirViewExecFile(TObject *Sender,
  515. TListItem *Item, bool &AllowExec)
  516. {
  517. assert(Item);
  518. if ((UpperCase(PFileRec(Item->Data)->FileExt) == "LNK") &&
  519. DirectoryExists(ResolveFileShortCut(LocalDirView->ItemFullFileName(Item), true)))
  520. {
  521. AllowExec = true;
  522. }
  523. else
  524. {
  525. DoDirViewExecFile(Sender, Item, AllowExec);
  526. }
  527. }
  528. //---------------------------------------------------------------------------
  529. void __fastcall TScpCommanderForm::LocalDirViewDDDragEnter(TObject *Sender,
  530. IDataObject *DataObj, int grfKeyState, TPoint &Point, int &dwEffect,
  531. bool &Accept)
  532. {
  533. // LocalDirViewDDDragEnter is duplication of
  534. // TCustomScpExplorerForm::DirViewDDDragEnter, but it differs in
  535. // literal type of 'DataObj' parameter.Actual type is however same
  536. DirViewDDDragEnter(Sender, DataObj, grfKeyState, Point, dwEffect, Accept);
  537. }
  538. //---------------------------------------------------------------------------
  539. void __fastcall TScpCommanderForm::FileOperationProgress(
  540. TFileOperationProgressType & ProgressData, TCancelStatus & Cancel)
  541. {
  542. // Heuristic: When operation finishes and DD targed is local dir view,
  543. // we suppose that drag&drop download finished, so local dir view should be
  544. // reloaded
  545. if (!ProgressData.InProgress && FProgressForm &&
  546. FDDTargetDirView == LocalDirView)
  547. {
  548. LocalDirView->ReloadDirectory();
  549. }
  550. TCustomScpExplorerForm::FileOperationProgress(ProgressData, Cancel);
  551. }
  552. //---------------------------------------------------------------------------
  553. void __fastcall TScpCommanderForm::DirViewLoaded(TObject *Sender)
  554. {
  555. try
  556. {
  557. TCustomDirView * ADirView = dynamic_cast<TCustomDirView *>(Sender);
  558. assert(ADirView);
  559. AnsiString PrevPath = FPrevPath[ADirView == LocalDirView];
  560. FPrevPath[ADirView == LocalDirView] = ADirView->Path;
  561. if (!FSynchronisingBrowse && NonVisualDataModule->SynchorizeBrowsingAction->Checked &&
  562. !PrevPath.IsEmpty() && PrevPath != ADirView->Path)
  563. {
  564. FSynchronisingBrowse = true;
  565. if (ADirView == LocalDirView)
  566. {
  567. Terminal->ExceptionOnFail = true;
  568. try
  569. {
  570. if (PrevPath == ExcludeTrailingBackslash(ExtractFilePath(LocalDirView->Path)))
  571. {
  572. RemoteDirView->Path = RemoteDirView->Path + ExtractFileName(LocalDirView->Path);
  573. }
  574. else if (ExcludeTrailingBackslash(ExtractFilePath(PrevPath)) ==
  575. ExcludeTrailingBackslash(LocalDirView->PathName))
  576. {
  577. if (RemoteDirView->IsRoot)
  578. {
  579. Abort();
  580. }
  581. RemoteDirView->Path = UnixExtractFilePath(RemoteDirView->PathName);
  582. }
  583. else
  584. {
  585. Abort();
  586. }
  587. }
  588. __finally
  589. {
  590. Terminal->ExceptionOnFail = false;
  591. }
  592. }
  593. else
  594. {
  595. if (PrevPath == UnixExtractFilePath(RemoteDirView->PathName))
  596. {
  597. LocalDirView->Path = IncludeTrailingBackslash(LocalDirView->Path) +
  598. UnixExtractFileName(RemoteDirView->PathName);
  599. }
  600. else if (UnixExtractFilePath(UnixExcludeTrailingBackslash(PrevPath)) == RemoteDirView->Path)
  601. {
  602. if (LocalDirView->IsRoot)
  603. {
  604. Abort();
  605. }
  606. LocalDirView->Path = ExtractFilePath(LocalDirView->Path);
  607. }
  608. else
  609. {
  610. Abort();
  611. }
  612. }
  613. FSynchronisingBrowse = false;
  614. }
  615. }
  616. catch(Exception & E)
  617. {
  618. FSynchronisingBrowse = false;
  619. NonVisualDataModule->SynchorizeBrowsingAction->Checked = false;
  620. if (!Application->Terminated)
  621. {
  622. ShowExtendedException(&E);
  623. MessageDialog(LoadStr(SYNC_DIR_BROWSE_ERROR), qtInformation, qaOK, 0);
  624. }
  625. else
  626. {
  627. throw;
  628. }
  629. }
  630. }
  631. //---------------------------------------------------------------------------
  632. void __fastcall TScpCommanderForm::AddEditLink()
  633. {
  634. if (FLastDirView == LocalDirView)
  635. {
  636. bool Edit = false;
  637. AnsiString FileName;
  638. AnsiString PointTo;
  639. bool SymbolicLink = true;
  640. if (LocalDirView->ItemFocused)
  641. {
  642. assert(LocalDirView->ItemFocused->Data);
  643. PFileRec FileRec = (PFileRec)LocalDirView->ItemFocused->Data;
  644. Edit = UpperCase(FileRec->FileExt) == "LNK";
  645. if (Edit)
  646. {
  647. AnsiString FullName = LocalDirView->ItemFullFileName(LocalDirView->ItemFocused);
  648. FileName = FullName;//FileRec->FileName;
  649. PointTo = ResolveFileShortCut(FullName, false);
  650. if (PointTo.IsEmpty())
  651. {
  652. throw Exception(FMTLOAD(RESOLVE_SHORTCUT_ERROR, (FullName)));
  653. }
  654. }
  655. else
  656. {
  657. PointTo = FileRec->FileName;
  658. }
  659. }
  660. if (DoSymlinkDialog(FileName, PointTo, osLocal, SymbolicLink, Edit, false))
  661. {
  662. assert(SymbolicLink);
  663. assert(!FileName.IsEmpty());
  664. assert(!PointTo.IsEmpty());
  665. if (ExtractFileDrive(FileName) == "" && FileName[1] != '\\')
  666. {
  667. FileName = IncludeTrailingBackslash(LocalDirView->PathName) + FileName;
  668. }
  669. if (ExtractFileDrive(PointTo) == "" && PointTo[1] != '\\')
  670. {
  671. PointTo = IncludeTrailingBackslash(LocalDirView->PathName) + PointTo;
  672. }
  673. if (ExtractFileExt(FileName) == "")
  674. {
  675. FileName = FileName + ".lnk";
  676. }
  677. if (Edit && !DeleteFile(FileName))
  678. {
  679. throw Exception(FMTLOAD(DELETE_LOCAL_FILE_ERROR, (FileName)));
  680. }
  681. if (!CreateFileShortCut(PointTo, FileName, ""))
  682. {
  683. throw Exception(CREATE_SHORTCUT_ERROR);
  684. }
  685. }
  686. }
  687. else
  688. {
  689. TCustomScpExplorerForm::AddEditLink();
  690. }
  691. }
  692. //---------------------------------------------------------------------------
  693. void __fastcall TScpCommanderForm::DoOpenDirectoryDialog(TOpenDirectoryMode Mode,
  694. TOperationSide Side)
  695. {
  696. if (WinConfiguration->UseLocationProfiles)
  697. {
  698. TStrings * RemoteDirectories = CreateVisitedDirectories(osRemote);
  699. try
  700. {
  701. AnsiString Local = LocalDirView->PathName;
  702. AnsiString Remote = RemoteDirView->PathName;
  703. if (LocationProfilesDialog(Mode, Side, Local, Remote, RemoteDirectories, Terminal))
  704. {
  705. if (!Local.IsEmpty())
  706. {
  707. LocalDirView->Path = Local;
  708. }
  709. if (!Remote.IsEmpty())
  710. {
  711. RemoteDirView->Path = Remote;
  712. }
  713. }
  714. }
  715. __finally
  716. {
  717. delete RemoteDirectories;
  718. }
  719. }
  720. else
  721. {
  722. TCustomScpExplorerForm::DoOpenDirectoryDialog(Mode, Side);
  723. }
  724. }