Synchronize.cpp 25 KB

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