ScpCommander.cpp 26 KB

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