Synchronize.cpp 23 KB

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