Synchronize.cpp 26 KB

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