Synchronize.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include "WinInterface.h"
  6. #include "Synchronize.h"
  7. #include "VCLCommon.h"
  8. #include "CopyParams.h"
  9. #include "Terminal.h"
  10. #include "GUITools.h"
  11. #include <CoreMain.h>
  12. #include <Configuration.h>
  13. #include <TextsWin.h>
  14. #include <HelpWin.h>
  15. #include <WinConfiguration.h>
  16. #include <TerminalManager.h>
  17. #include <StrUtils.hpp>
  18. #include <Tools.h>
  19. //---------------------------------------------------------------------------
  20. #pragma package(smart_init)
  21. #pragma link "HistoryComboBox"
  22. #pragma link "GrayedCheckBox"
  23. #pragma resource "*.dfm"
  24. //---------------------------------------------------------------------------
  25. const int WM_USER_STOP = WM_WINSCP_USER + 2;
  26. //---------------------------------------------------------------------------
  27. bool __fastcall DoSynchronizeDialog(TSynchronizeParamType & Params,
  28. const TCopyParamType * CopyParams, TSynchronizeStartStopEvent OnStartStop,
  29. bool & SaveSettings, int Options, int CopyParamAttrs,
  30. TGetSynchronizeOptionsEvent OnGetOptions,
  31. TSynchronizeSessionLog OnSynchronizeSessionLog,
  32. TFeedSynchronizeError & OnFeedSynchronizeError,
  33. TNotifyEvent & OnSynchronizeAbort,
  34. TSynchronizeInNewWindow OnSynchronizeInNewWindow,
  35. int AutoSubmit)
  36. {
  37. bool Result;
  38. TSynchronizeDialog * Dialog = SafeFormCreate<TSynchronizeDialog>(Application);
  39. Dialog->Init(
  40. OnStartStop, OnGetOptions, OnSynchronizeSessionLog, OnFeedSynchronizeError, OnSynchronizeAbort,
  41. OnSynchronizeInNewWindow, AutoSubmit);
  42. try
  43. {
  44. Dialog->Options = Options;
  45. Dialog->CopyParamAttrs = CopyParamAttrs;
  46. Dialog->Params = Params;
  47. Dialog->CopyParams = *CopyParams;
  48. Dialog->SaveSettings = SaveSettings;
  49. Result = Dialog->Execute();
  50. if (Result)
  51. {
  52. SaveSettings = Dialog->SaveSettings;
  53. Params = Dialog->Params;
  54. }
  55. }
  56. __finally
  57. {
  58. delete Dialog;
  59. OnSynchronizeAbort = NULL;
  60. }
  61. return Result;
  62. }
  63. //---------------------------------------------------------------------------
  64. const TSynchronizeDialog::MaxLogItems = 1000;
  65. //---------------------------------------------------------------------------
  66. struct TLogItemData
  67. {
  68. TSynchronizeLogEntry Entry;
  69. UnicodeString Message;
  70. std::unique_ptr<TStrings> MoreMessages;
  71. TQueryType Type;
  72. UnicodeString HelpKeyword;
  73. };
  74. //---------------------------------------------------------------------------
  75. __fastcall TSynchronizeDialog::TSynchronizeDialog(TComponent * Owner)
  76. : TForm(Owner)
  77. {
  78. UseSystemSettings(this);
  79. FOptions = 0;
  80. FSynchronizing = false;
  81. FMinimizedByMe = false;
  82. FPresetsMenu = new TPopupMenu(this);
  83. FSynchronizeOptions = NULL;
  84. HotTrackLabel(CopyParamLabel);
  85. LoadDialogImage(Image, L"Keep remote directory up to date");
  86. SetGlobalMinimizeHandler(this, GlobalMinimize);
  87. }
  88. //---------------------------------------------------------------------------
  89. void __fastcall TSynchronizeDialog::Init(TSynchronizeStartStopEvent OnStartStop,
  90. TGetSynchronizeOptionsEvent OnGetOptions,
  91. TSynchronizeSessionLog OnSynchronizeSessionLog,
  92. TFeedSynchronizeError & OnFeedSynchronizeError,
  93. TNotifyEvent & OnSynchronizeAbort,
  94. TSynchronizeInNewWindow OnSynchronizeInNewWindow,
  95. int AutoSubmit)
  96. {
  97. FOnStartStop = OnStartStop;
  98. FOnGetOptions = OnGetOptions;
  99. FOnSynchronizeSessionLog = OnSynchronizeSessionLog;
  100. FOnFeedSynchronizeError = &OnFeedSynchronizeError;
  101. OnSynchronizeAbort = &SynchronizeAbort;
  102. DebugAssert(OnSynchronizeInNewWindow != NULL);
  103. FOnSynchronizeInNewWindow = OnSynchronizeInNewWindow;
  104. if (AutoSubmit == 0)
  105. {
  106. FStartImmediately = true;
  107. }
  108. else
  109. {
  110. FStartImmediately = false;
  111. if (AutoSubmit > 0)
  112. {
  113. InitiateDialogTimeout(this, AutoSubmit * MSecsPerSec, StartButton);
  114. }
  115. }
  116. }
  117. //---------------------------------------------------------------------------
  118. __fastcall TSynchronizeDialog::~TSynchronizeDialog()
  119. {
  120. // if application is closing OnCloseQuery might not get called
  121. // (this particularly happens if last terminal is disconnected while dialog is
  122. // open)
  123. if (FSynchronizing)
  124. {
  125. OnlyStop();
  126. }
  127. ClearGlobalMinimizeHandler(GlobalMinimize);
  128. delete FSynchronizeOptions;
  129. delete FPresetsMenu;
  130. }
  131. //---------------------------------------------------------------------------
  132. void __fastcall TSynchronizeDialog::FeedSynchronizeError(
  133. const UnicodeString & Message, TStrings * MoreMessages, TQueryType Type,
  134. const UnicodeString & HelpKeyword)
  135. {
  136. DoLogInternal(slContinuedError, Message, MoreMessages, Type, HelpKeyword);
  137. }
  138. //---------------------------------------------------------------------------
  139. void __fastcall TSynchronizeDialog::SynchronizeAbort(TObject *)
  140. {
  141. Abort(true);
  142. }
  143. //---------------------------------------------------------------------------
  144. void __fastcall TSynchronizeDialog::UpdateControls()
  145. {
  146. EnableControl(StartButton, !LocalDirectoryEdit->Text.IsEmpty() &&
  147. !RemoteDirectoryEdit->Text.IsEmpty());
  148. TButton * OldButton = FSynchronizing ? StartButton : StopButton;
  149. TButton * NewButton = FSynchronizing ? StopButton : StartButton;
  150. if (!NewButton->Visible || OldButton->Visible)
  151. {
  152. NewButton->Visible = true;
  153. if (OldButton->Focused())
  154. {
  155. NewButton->SetFocus();
  156. }
  157. OldButton->Default = false;
  158. NewButton->Default = true;
  159. OldButton->Visible = false;
  160. // some of the above steps hides accelerators when start button is pressed with mouse
  161. ResetSystemSettings(this);
  162. }
  163. TTerminalManager * Manager = TTerminalManager::Instance();
  164. UnicodeString Title = LoadStr(FSynchronizing ? SYNCHRONIZE_SYCHRONIZING : SYNCHRONIZE_TITLE);
  165. Caption = Manager->FormatFormCaptionWithSession(this, Title);
  166. EnableControl(TransferSettingsButton, !FSynchronizing);
  167. CancelButton->Visible = !FSynchronizing || FLAGSET(FOptions, soNoMinimize);
  168. EnableControl(CancelButton, !FSynchronizing);
  169. EnableControl(DirectoriesGroup, !FSynchronizing);
  170. EnableControl(OptionsGroup, !FSynchronizing);
  171. EnableControl(CopyParamGroup, !FSynchronizing);
  172. MinimizeButton->Visible = FSynchronizing && FLAGCLEAR(FOptions, soNoMinimize);
  173. EnableControl(SynchronizeSelectedOnlyCheck,
  174. OptionsGroup->Enabled && FLAGSET(FOptions, soAllowSelectedOnly));
  175. UnicodeString InfoStr = CopyParams.GetInfoStr(L"; ", ActualCopyParamAttrs());
  176. SetLabelHintPopup(CopyParamLabel, InfoStr);
  177. TransferSettingsButton->Style =
  178. FLAGCLEAR(Options, soDoNotUsePresets) ?
  179. TCustomButton::bsSplitButton : TCustomButton::bsPushButton;
  180. if (LogPanel->Visible != FSynchronizing)
  181. {
  182. if (FSynchronizing)
  183. {
  184. LogPanel->Visible = true;
  185. ClientHeight = ClientHeight + LogPanel->Height;
  186. }
  187. else
  188. {
  189. ClientHeight = ClientHeight - LogPanel->Height;
  190. LogPanel->Visible = false;
  191. }
  192. }
  193. // When minimizing to tray globally, no point showing special "minimize to tray" command
  194. MinimizeButton->Style =
  195. !WinConfiguration->MinimizeToTray ? TCustomButton::bsSplitButton : TCustomButton::bsPushButton;
  196. StartButton->Style = AllowStartInNewWindow() ? TCustomButton::bsSplitButton : TCustomButton::bsPushButton;
  197. StartInNewWindowItem->Enabled = CanStartInNewWindow();
  198. }
  199. //---------------------------------------------------------------------------
  200. bool __fastcall TSynchronizeDialog::AllowStartInNewWindow()
  201. {
  202. return !IsMainFormLike(this);
  203. }
  204. //---------------------------------------------------------------------------
  205. bool __fastcall TSynchronizeDialog::CanStartInNewWindow()
  206. {
  207. return
  208. AllowStartInNewWindow() &&
  209. (!SynchronizeSelectedOnlyCheck->Enabled || !SynchronizeSelectedOnlyCheck->Checked);
  210. }
  211. //---------------------------------------------------------------------------
  212. void __fastcall TSynchronizeDialog::ControlChange(TObject * /*Sender*/)
  213. {
  214. UpdateControls();
  215. }
  216. //---------------------------------------------------------------------------
  217. bool __fastcall TSynchronizeDialog::Execute()
  218. {
  219. // at start assume that copy param is current preset
  220. FPreset = GUIConfiguration->CopyParamCurrent;
  221. LocalDirectoryEdit->Items = CustomWinConfiguration->History[L"LocalDirectory"];
  222. RemoteDirectoryEdit->Items = CustomWinConfiguration->History[L"RemoteDirectory"];
  223. ShowModal();
  224. return true;
  225. }
  226. //---------------------------------------------------------------------------
  227. void __fastcall TSynchronizeDialog::SetParams(const TSynchronizeParamType& value)
  228. {
  229. FParams = value;
  230. RemoteDirectoryEdit->Text = value.RemoteDirectory;
  231. LocalDirectoryEdit->Text = value.LocalDirectory;
  232. SynchronizeDeleteCheck->Checked = FLAGSET(value.Params, TTerminal::spDelete);
  233. SynchronizeExistingOnlyCheck->Checked = FLAGSET(value.Params, TTerminal::spExistingOnly);
  234. SynchronizeSelectedOnlyCheck->Checked = FLAGSET(value.Params, TTerminal::spSelectedOnly);
  235. SynchronizeRecursiveCheck->Checked = FLAGSET(value.Options, soRecurse);
  236. SynchronizeSynchronizeCheck->State =
  237. FLAGSET(value.Options, soSynchronizeAsk) ? cbGrayed :
  238. (FLAGSET(value.Options, soSynchronize) ? cbChecked : cbUnchecked);
  239. ContinueOnErrorCheck->Checked = FLAGSET(value.Options, soContinueOnError);
  240. }
  241. //---------------------------------------------------------------------------
  242. TSynchronizeParamType __fastcall TSynchronizeDialog::GetParams()
  243. {
  244. TSynchronizeParamType Result = FParams;
  245. Result.RemoteDirectory = RemoteDirectoryEdit->Text;
  246. Result.LocalDirectory = LocalDirectoryEdit->Text;
  247. Result.Params =
  248. (Result.Params & ~(TTerminal::spDelete | TTerminal::spExistingOnly | TTerminal::spSelectedOnly | TTerminal::spTimestamp)) |
  249. FLAGMASK(SynchronizeDeleteCheck->Checked, TTerminal::spDelete) |
  250. FLAGMASK(SynchronizeExistingOnlyCheck->Checked, TTerminal::spExistingOnly) |
  251. FLAGMASK(SynchronizeSelectedOnlyCheck->Checked, TTerminal::spSelectedOnly);
  252. Result.Options =
  253. (Result.Options & ~(soRecurse | soSynchronize | soSynchronizeAsk | soContinueOnError)) |
  254. FLAGMASK(SynchronizeRecursiveCheck->Checked, soRecurse) |
  255. FLAGMASK(SynchronizeSynchronizeCheck->State == cbChecked, soSynchronize) |
  256. FLAGMASK(SynchronizeSynchronizeCheck->State == cbGrayed, soSynchronizeAsk) |
  257. FLAGMASK(ContinueOnErrorCheck->Checked, soContinueOnError);
  258. return Result;
  259. }
  260. //---------------------------------------------------------------------------
  261. void __fastcall TSynchronizeDialog::LocalDirectoryBrowseButtonClick(
  262. TObject * /*Sender*/)
  263. {
  264. UnicodeString Directory = LocalDirectoryEdit->Text;
  265. if (SelectDirectory(Directory, LoadStr(SELECT_LOCAL_DIRECTORY), false))
  266. {
  267. LocalDirectoryEdit->Text = Directory;
  268. }
  269. }
  270. //---------------------------------------------------------------------------
  271. void __fastcall TSynchronizeDialog::SetOptions(int value)
  272. {
  273. if (Options != value)
  274. {
  275. FOptions = value;
  276. UpdateControls();
  277. }
  278. }
  279. //---------------------------------------------------------------------------
  280. void __fastcall TSynchronizeDialog::CopyParamListPopup(TRect R, int AdditionalOptions)
  281. {
  282. // We pass in FCopyParams, although it may not be the exact copy param
  283. // that will be used (because of PreserveTime). The reason is to
  284. // display checkbox next to user-selected preset
  285. ::CopyParamListPopup(
  286. R, FPresetsMenu, FCopyParams, FPreset, CopyParamClick,
  287. AdditionalOptions, ActualCopyParamAttrs());
  288. }
  289. //---------------------------------------------------------------------------
  290. void __fastcall TSynchronizeDialog::TransferSettingsButtonClick(
  291. TObject * /*Sender*/)
  292. {
  293. CopyParamGroupClick(NULL);
  294. }
  295. //---------------------------------------------------------------------------
  296. void __fastcall TSynchronizeDialog::DoStartStop(bool Start, bool Synchronize)
  297. {
  298. if (FOnStartStop)
  299. {
  300. TSynchronizeParamType SParams = GetParams();
  301. SParams.Options =
  302. (SParams.Options & ~(soSynchronize | soSynchronizeAsk)) |
  303. FLAGMASK(Synchronize, soSynchronize);
  304. if (Start)
  305. {
  306. DebugAssert(*FOnFeedSynchronizeError == NULL);
  307. *FOnFeedSynchronizeError =
  308. (FLAGSET(SParams.Options, soContinueOnError) ? &FeedSynchronizeError : TFeedSynchronizeError(NULL));
  309. delete FSynchronizeOptions;
  310. FSynchronizeOptions = new TSynchronizeOptions;
  311. FOnGetOptions(SParams.Params, *FSynchronizeOptions);
  312. }
  313. else
  314. {
  315. *FOnFeedSynchronizeError = NULL;
  316. }
  317. FOnStartStop(this, Start, SParams, CopyParams, FSynchronizeOptions, DoAbort,
  318. NULL, DoLog);
  319. }
  320. }
  321. //---------------------------------------------------------------------------
  322. void __fastcall TSynchronizeDialog::Dispatch(void * AMessage)
  323. {
  324. DebugAssert(AMessage != NULL);
  325. TMessage & Message = *reinterpret_cast<TMessage *>(AMessage);
  326. if ((Message.Msg == WM_USER_STOP) && FAbort)
  327. {
  328. if (FSynchronizing)
  329. {
  330. Stop();
  331. }
  332. if (FClose)
  333. {
  334. FClose = false;
  335. ModalResult = mrCancel;
  336. }
  337. }
  338. else if (Message.Msg == WM_MANAGES_CAPTION)
  339. {
  340. // caption managed in UpdateControls()
  341. Message.Result = 1;
  342. }
  343. else
  344. {
  345. TForm::Dispatch(AMessage);
  346. }
  347. }
  348. //---------------------------------------------------------------------------
  349. void TSynchronizeDialog::Abort(bool Close)
  350. {
  351. FAbort = true;
  352. FClose = Close;
  353. PostMessage(Handle, WM_USER_STOP, 0, 0);
  354. }
  355. //---------------------------------------------------------------------------
  356. void __fastcall TSynchronizeDialog::DoAbort(TObject * /*Sender*/, bool Close)
  357. {
  358. Abort(Close);
  359. }
  360. //---------------------------------------------------------------------------
  361. void __fastcall TSynchronizeDialog::DoLogInternal(
  362. TSynchronizeLogEntry Entry, const UnicodeString & Message,
  363. TStrings * MoreMessages, TQueryType Type, const UnicodeString & HelpKeyword)
  364. {
  365. LogView->Items->BeginUpdate();
  366. try
  367. {
  368. TListItem * Item = LogView->Items->Add();
  369. TLogItemData * LogItemData = new TLogItemData();
  370. Item->Data = LogItemData;
  371. LogItemData->Entry = Entry;
  372. LogItemData->Message = Message;
  373. if (MoreMessages != NULL)
  374. {
  375. LogItemData->MoreMessages.reset(new TStringList());
  376. LogItemData->MoreMessages->Assign(MoreMessages);
  377. }
  378. LogItemData->Type = Type;
  379. LogItemData->HelpKeyword = HelpKeyword;
  380. Item->Caption = Now().TimeString();
  381. UnicodeString UnformattedMessage = UnformatMessage(Message);
  382. UnformattedMessage = ReplaceStr(UnformattedMessage, L"\r", L"");
  383. UnformattedMessage = ReplaceStr(UnformattedMessage, L"\n", L" ");
  384. Item->SubItems->Add(UnformattedMessage);
  385. Item->MakeVisible(false);
  386. while (LogView->Items->Count > MaxLogItems)
  387. {
  388. LogView->Items->Delete(0);
  389. }
  390. }
  391. __finally
  392. {
  393. LogView->Items->EndUpdate();
  394. if (Entry == slScan)
  395. {
  396. // redraw log before the scanning block update
  397. LogView->Repaint();
  398. }
  399. }
  400. FOnSynchronizeSessionLog(Message);
  401. }
  402. //---------------------------------------------------------------------------
  403. void __fastcall TSynchronizeDialog::DoLog(TSynchronizeController * /*Controller*/,
  404. TSynchronizeLogEntry Entry, const UnicodeString Message)
  405. {
  406. DoLogInternal(Entry, Message,
  407. // these are unused (as Entry is not slContinuedError here)
  408. NULL, qtInformation, UnicodeString());
  409. }
  410. //---------------------------------------------------------------------------
  411. void __fastcall TSynchronizeDialog::StartButtonClick(TObject * /*Sender*/)
  412. {
  413. if (OpenInNewWindow())
  414. {
  415. if (CanStartInNewWindow())
  416. {
  417. StartInNewWindow();
  418. }
  419. else
  420. {
  421. Beep();
  422. }
  423. }
  424. else
  425. {
  426. Start();
  427. }
  428. }
  429. //---------------------------------------------------------------------------
  430. void __fastcall TSynchronizeDialog::Start()
  431. {
  432. bool Synchronize;
  433. bool Continue = true;
  434. if (SynchronizeSynchronizeCheck->State == cbGrayed)
  435. {
  436. TMessageParams Params(mpNeverAskAgainCheck);
  437. switch (MoreMessageDialog(LoadStr(SYNCHRONISE_BEFORE_KEEPUPTODATE2),
  438. NULL, qtConfirmation, qaYes | qaNo | qaCancel, HELP_KEEPUPTODATE_SYNCHRONIZE,
  439. &Params))
  440. {
  441. case qaNeverAskAgain:
  442. SynchronizeSynchronizeCheck->State = cbChecked;
  443. // fall thru
  444. case qaYes:
  445. Synchronize = true;
  446. break;
  447. case qaNo:
  448. Synchronize = false;
  449. break;
  450. default:
  451. case qaCancel:
  452. Continue = false;
  453. break;
  454. };
  455. }
  456. else
  457. {
  458. Synchronize = SynchronizeSynchronizeCheck->Checked;
  459. }
  460. if (Continue)
  461. {
  462. DebugAssert(!FSynchronizing);
  463. SaveHistory();
  464. FSynchronizing = true;
  465. try
  466. {
  467. UpdateControls();
  468. Repaint();
  469. FAbort = false;
  470. DoStartStop(true, Synchronize);
  471. }
  472. catch(...)
  473. {
  474. FSynchronizing = false;
  475. UpdateControls();
  476. throw;
  477. }
  478. }
  479. }
  480. //---------------------------------------------------------------------------
  481. void __fastcall TSynchronizeDialog::SaveHistory()
  482. {
  483. LocalDirectoryEdit->SaveToHistory();
  484. CustomWinConfiguration->History[L"LocalDirectory"] = LocalDirectoryEdit->Items;
  485. RemoteDirectoryEdit->SaveToHistory();
  486. CustomWinConfiguration->History[L"RemoteDirectory"] = RemoteDirectoryEdit->Items;
  487. }
  488. //---------------------------------------------------------------------------
  489. void __fastcall TSynchronizeDialog::StopButtonClick(TObject * /*Sender*/)
  490. {
  491. Stop();
  492. }
  493. //---------------------------------------------------------------------------
  494. void __fastcall TSynchronizeDialog::OnlyStop()
  495. {
  496. FSynchronizing = false;
  497. DoStartStop(false, false);
  498. }
  499. //---------------------------------------------------------------------------
  500. void __fastcall TSynchronizeDialog::Stop()
  501. {
  502. OnlyStop();
  503. UpdateControls();
  504. Repaint();
  505. if (IsApplicationMinimized() && FMinimizedByMe)
  506. {
  507. FMinimizedByMe = false;
  508. ApplicationRestore();
  509. Application->BringToFront();
  510. }
  511. }
  512. //---------------------------------------------------------------------------
  513. void __fastcall TSynchronizeDialog::Minimize(TObject * Sender)
  514. {
  515. CallGlobalMinimizeHandler(Sender);
  516. }
  517. //---------------------------------------------------------------------------
  518. void __fastcall TSynchronizeDialog::MinimizeButtonClick(TObject * Sender)
  519. {
  520. Minimize(Sender);
  521. }
  522. //---------------------------------------------------------------------------
  523. void __fastcall TSynchronizeDialog::GlobalMinimize(TObject * /*Sender*/)
  524. {
  525. ApplicationMinimize();
  526. FMinimizedByMe = true;
  527. }
  528. //---------------------------------------------------------------------------
  529. void __fastcall TSynchronizeDialog::SetSaveSettings(bool value)
  530. {
  531. SaveSettingsCheck->Checked = value;
  532. }
  533. //---------------------------------------------------------------------------
  534. bool __fastcall TSynchronizeDialog::GetSaveSettings()
  535. {
  536. return SaveSettingsCheck->Checked;
  537. }
  538. //---------------------------------------------------------------------------
  539. void __fastcall TSynchronizeDialog::FormShow(TObject * /*Sender*/)
  540. {
  541. InstallPathWordBreakProc(LocalDirectoryEdit);
  542. InstallPathWordBreakProc(RemoteDirectoryEdit);
  543. // OnShow gets called more than once sometimes
  544. if (!FSynchronizing)
  545. {
  546. ClearLog();
  547. UpdateControls();
  548. if (FStartImmediately)
  549. {
  550. // if starting get cancelled (from SYNCHRONISE_BEFORE_KEEPUPTODATE2 prompt),
  551. // and OnShow gets called again (FSynchronizing is false),
  552. // we do not want to try to start again
  553. FStartImmediately = false;
  554. StartButtonClick(NULL);
  555. }
  556. }
  557. }
  558. //---------------------------------------------------------------------------
  559. void __fastcall TSynchronizeDialog::FormCloseQuery(TObject * /*Sender*/,
  560. bool & /*CanClose*/)
  561. {
  562. if (FSynchronizing)
  563. {
  564. Stop();
  565. }
  566. }
  567. //---------------------------------------------------------------------------
  568. TCopyParamType __fastcall TSynchronizeDialog::GetCopyParams()
  569. {
  570. TCopyParamType Result = FCopyParams;
  571. Result.PreserveTime = true;
  572. Result.NewerOnly = false;
  573. return Result;
  574. }
  575. //---------------------------------------------------------------------------
  576. void __fastcall TSynchronizeDialog::SetCopyParams(const TCopyParamType & value)
  577. {
  578. FCopyParams = value;
  579. UpdateControls();
  580. }
  581. //---------------------------------------------------------------------------
  582. int __fastcall TSynchronizeDialog::ActualCopyParamAttrs()
  583. {
  584. return FCopyParamAttrs | cpaNoPreserveTime | cpaNoNewerOnly;
  585. }
  586. //---------------------------------------------------------------------------
  587. void __fastcall TSynchronizeDialog::CopyParamClick(TObject * Sender)
  588. {
  589. DebugAssert(FLAGCLEAR(FOptions, soDoNotUsePresets));
  590. // PreserveTime is forced for some settings, but avoid hard-setting it until
  591. // user really confirms it on custom dialog
  592. TCopyParamType ACopyParams = CopyParams;
  593. if (CopyParamListPopupClick(Sender, ACopyParams, FPreset,
  594. ActualCopyParamAttrs()) > 0)
  595. {
  596. FCopyParams = ACopyParams;
  597. UpdateControls();
  598. }
  599. }
  600. //---------------------------------------------------------------------------
  601. void __fastcall TSynchronizeDialog::CopyParamGroupContextPopup(
  602. TObject * /*Sender*/, TPoint & MousePos, bool & Handled)
  603. {
  604. if (FLAGCLEAR(FOptions, soDoNotUsePresets))
  605. {
  606. CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos),
  607. cplCustomizeDefault);
  608. Handled = true;
  609. }
  610. }
  611. //---------------------------------------------------------------------------
  612. void __fastcall TSynchronizeDialog::CopyParamGroupClick(TObject * /*Sender*/)
  613. {
  614. // PreserveTime is forced for some settings, but avoid hard-setting it until
  615. // user really confirms it on cutom dialog
  616. TCopyParamType ACopyParams = CopyParams;
  617. if (DoCopyParamCustomDialog(ACopyParams, ActualCopyParamAttrs()))
  618. {
  619. FCopyParams = ACopyParams;
  620. UpdateControls();
  621. }
  622. }
  623. //---------------------------------------------------------------------------
  624. void __fastcall TSynchronizeDialog::HelpButtonClick(TObject * /*Sender*/)
  625. {
  626. FormHelp(this);
  627. }
  628. //---------------------------------------------------------------------------
  629. void __fastcall TSynchronizeDialog::ClearLog()
  630. {
  631. // TListItems::Clear() does nothing without allocated handle
  632. LogView->HandleNeeded();
  633. LogView->Items->Clear();
  634. }
  635. //---------------------------------------------------------------------------
  636. void __fastcall TSynchronizeDialog::CopyLog()
  637. {
  638. TInstantOperationVisualizer Visualizer;
  639. UnicodeString Content;
  640. for (int i = 0; i < LogView->Items->Count; i++)
  641. {
  642. TListItem * Item = LogView->Items->Item[i];
  643. Content += Item->Caption + L"\t" + Item->SubItems->Strings[0] + L"\r\n";
  644. }
  645. CopyToClipboard(Content);
  646. }
  647. //---------------------------------------------------------------------------
  648. void __fastcall TSynchronizeDialog::LogViewKeyDown(TObject * /*Sender*/,
  649. WORD & Key, TShiftState Shift)
  650. {
  651. if (Key == VK_DELETE)
  652. {
  653. ClearLog();
  654. Key = 0;
  655. }
  656. else if ((Key == L'C') && Shift.Contains(ssCtrl) && (LogView->Items->Count > 0))
  657. {
  658. CopyLog();
  659. Key = 0;
  660. }
  661. }
  662. //---------------------------------------------------------------------------
  663. void __fastcall TSynchronizeDialog::FormKeyDown(TObject * /*Sender*/, WORD & Key,
  664. TShiftState /*Shift*/)
  665. {
  666. if ((Key == VK_ESCAPE) && FSynchronizing)
  667. {
  668. Stop();
  669. Key = 0;
  670. }
  671. }
  672. //---------------------------------------------------------------------------
  673. void __fastcall TSynchronizeDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/)
  674. {
  675. CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault);
  676. }
  677. //---------------------------------------------------------------------------
  678. void __fastcall TSynchronizeDialog::LogViewCustomDrawItem(TCustomListView * Sender,
  679. TListItem * Item, TCustomDrawState /*State*/, bool & /*DefaultDraw*/)
  680. {
  681. TLogItemData * LogItemData = GetLogItemData(Item);
  682. if (LogItemData->Entry == slContinuedError)
  683. {
  684. Sender->Canvas->Font->Color = clRed;
  685. }
  686. }
  687. //---------------------------------------------------------------------------
  688. TLogItemData * __fastcall TSynchronizeDialog::GetLogItemData(TListItem * Item)
  689. {
  690. return reinterpret_cast<TLogItemData *>(Item->Data);
  691. }
  692. //---------------------------------------------------------------------------
  693. void __fastcall TSynchronizeDialog::LogViewDeletion(TObject * /*Sender*/, TListItem * Item)
  694. {
  695. delete GetLogItemData(Item);
  696. Item->Data = NULL;
  697. }
  698. //---------------------------------------------------------------------------
  699. void __fastcall TSynchronizeDialog::LogViewDblClick(TObject * /*Sender*/)
  700. {
  701. if (LogView->ItemFocused != NULL)
  702. {
  703. TLogItemData * LogItemData = GetLogItemData(LogView->ItemFocused);
  704. if (LogItemData->Entry == slContinuedError)
  705. {
  706. MoreMessageDialog(
  707. LogItemData->Message, LogItemData->MoreMessages.get(), LogItemData->Type,
  708. qaOK, LogItemData->HelpKeyword);
  709. }
  710. }
  711. }
  712. //---------------------------------------------------------------------------
  713. void __fastcall TSynchronizeDialog::Minimize1Click(TObject * Sender)
  714. {
  715. Minimize(Sender);
  716. }
  717. //---------------------------------------------------------------------------
  718. void __fastcall TSynchronizeDialog::MinimizetoTray1Click(TObject * Sender)
  719. {
  720. bool MinimizeToTrayPrev = WinConfiguration->MinimizeToTray;
  721. DebugAssert(!MinimizeToTrayPrev);
  722. WinConfiguration->MinimizeToTray = true;
  723. try
  724. {
  725. Minimize(Sender);
  726. }
  727. __finally
  728. {
  729. WinConfiguration->MinimizeToTray = MinimizeToTrayPrev;
  730. }
  731. }
  732. //---------------------------------------------------------------------------
  733. void __fastcall TSynchronizeDialog::MinimizeButtonDropDownClick(TObject * /*Sender*/)
  734. {
  735. MenuPopup(MinimizeMenu, MinimizeButton);
  736. }
  737. //---------------------------------------------------------------------------
  738. void __fastcall TSynchronizeDialog::StartInNewWindowItemClick(TObject * /*Sender*/)
  739. {
  740. StartInNewWindow();
  741. }
  742. //---------------------------------------------------------------------------
  743. void __fastcall TSynchronizeDialog::StartInNewWindow()
  744. {
  745. SaveHistory();
  746. TSynchronizeParamType AParams = Params;
  747. TCopyParamType ACopyParams = CopyParams;
  748. FOnSynchronizeInNewWindow(AParams, &ACopyParams);
  749. Close();
  750. }
  751. //---------------------------------------------------------------------------
  752. void __fastcall TSynchronizeDialog::StartButtonDropDownClick(TObject * /*Sender*/)
  753. {
  754. MenuPopup(StartMenu, StartButton);
  755. }
  756. //---------------------------------------------------------------------------