Synchronize.cpp 26 KB

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