FullSynchronize.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include "WinInterface.h"
  6. #include "FullSynchronize.h"
  7. #include "CopyParams.h"
  8. #include "VCLCommon.h"
  9. #include <CoreMain.h>
  10. #include <Configuration.h>
  11. #include <TextsWin.h>
  12. #include <HelpWin.h>
  13. #include <GUITools.h>
  14. #include <Terminal.h>
  15. #include <CustomWinConfiguration.h>
  16. #include <Tools.h>
  17. //---------------------------------------------------------------------------
  18. #pragma package(smart_init)
  19. #pragma link "HistoryComboBox"
  20. #pragma resource "*.dfm"
  21. //---------------------------------------------------------------------------
  22. bool __fastcall DoFullSynchronizeDialog(TSynchronizeMode & Mode, int & Params,
  23. UnicodeString & LocalDirectory, UnicodeString & RemoteDirectory,
  24. TCopyParamType * CopyParams, bool & SaveSettings, bool & SaveMode, int Options,
  25. const TUsableCopyParamAttrs & CopyParamAttrs, TFullSynchronizeInNewWindow OnFullSynchronizeInNewWindow,
  26. int AutoSubmit)
  27. {
  28. bool Result;
  29. TFullSynchronizeDialog * Dialog = SafeFormCreate<TFullSynchronizeDialog>();
  30. try
  31. {
  32. Dialog->Init(Options, CopyParamAttrs, OnFullSynchronizeInNewWindow);
  33. Dialog->Mode = Mode;
  34. Dialog->Params = Params;
  35. Dialog->LocalDirectory = LocalDirectory;
  36. Dialog->RemoteDirectory = RemoteDirectory;
  37. Dialog->CopyParams = *CopyParams;
  38. Dialog->SaveSettings = SaveSettings;
  39. Dialog->SaveMode = SaveMode;
  40. if (AutoSubmit > 0)
  41. {
  42. InitiateDialogTimeout(Dialog, AutoSubmit * MSecsPerSec, Dialog->OkButton);
  43. }
  44. Result = Dialog->Execute();
  45. if (Result)
  46. {
  47. Mode = Dialog->Mode;
  48. Params = Dialog->Params;
  49. LocalDirectory = Dialog->LocalDirectory;
  50. RemoteDirectory = Dialog->RemoteDirectory;
  51. *CopyParams = Dialog->CopyParams;
  52. SaveSettings = Dialog->SaveSettings;
  53. SaveMode = Dialog->SaveMode;
  54. }
  55. }
  56. __finally
  57. {
  58. delete Dialog;
  59. }
  60. return Result;
  61. }
  62. //---------------------------------------------------------------------------
  63. __fastcall TFullSynchronizeDialog::TFullSynchronizeDialog(TComponent* Owner)
  64. : TForm(Owner)
  65. {
  66. UseSystemSettings(this);
  67. FParams = 0;
  68. FSaveMode = false;
  69. FOptions = 0;
  70. FOnFullSynchronizeInNewWindow = NULL;
  71. FPresetsMenu = new TPopupMenu(this);
  72. FSynchronizeBySizeCaption = SynchronizeBySizeCheck->Caption;
  73. HotTrackLabel(CopyParamLabel);
  74. CopyParamListButton(TransferSettingsButton);
  75. LoadDialogImage(Image, L"Synchronize directories");
  76. }
  77. //---------------------------------------------------------------------------
  78. __fastcall TFullSynchronizeDialog::~TFullSynchronizeDialog()
  79. {
  80. delete FPresetsMenu;
  81. }
  82. //---------------------------------------------------------------------------
  83. void __fastcall TFullSynchronizeDialog::Init(
  84. int Options, const TUsableCopyParamAttrs & CopyParamAttrs, TFullSynchronizeInNewWindow OnFullSynchronizeInNewWindow)
  85. {
  86. FOptions = Options;
  87. if (FLAGSET(Options, fsoDisableTimestamp) &&
  88. SynchronizeTimestampsButton->Checked)
  89. {
  90. SynchronizeFilesButton->Checked = true;
  91. }
  92. FCopyParamAttrs = CopyParamAttrs;
  93. FOnFullSynchronizeInNewWindow = OnFullSynchronizeInNewWindow;
  94. DebugAssert(FOnFullSynchronizeInNewWindow != NULL);
  95. UpdateControls();
  96. }
  97. //---------------------------------------------------------------------------
  98. void __fastcall TFullSynchronizeDialog::UpdateControls()
  99. {
  100. EnableControl(SynchronizeTimestampsButton, FLAGCLEAR(FOptions, fsoDisableTimestamp));
  101. if (SynchronizeTimestampsButton->Checked)
  102. {
  103. SynchronizeExistingOnlyCheck->Checked = true;
  104. SynchronizeDeleteCheck->Checked = false;
  105. SynchronizeByTimeCheck->Checked = true;
  106. SynchronizeByChecksumCheck->Checked = false;
  107. }
  108. if (SynchronizeBothButton->Checked)
  109. {
  110. SynchronizeByTimeCheck->Checked = true;
  111. SynchronizeBySizeCheck->Checked = false;
  112. SynchronizeByChecksumCheck->Checked = false;
  113. if (MirrorFilesButton->Checked)
  114. {
  115. SynchronizeFilesButton->Checked = true;
  116. }
  117. }
  118. EnableControl(MirrorFilesButton, !SynchronizeBothButton->Checked);
  119. EnableControl(SynchronizeDeleteCheck, !SynchronizeBothButton->Checked &&
  120. !SynchronizeTimestampsButton->Checked);
  121. EnableControl(SynchronizeExistingOnlyCheck, !SynchronizeTimestampsButton->Checked);
  122. EnableControl(SynchronizeByTimeCheck, !SynchronizeBothButton->Checked &&
  123. !SynchronizeTimestampsButton->Checked);
  124. EnableControl(SynchronizeBySizeCheck, !SynchronizeBothButton->Checked);
  125. EnableControl(SynchronizeByChecksumCheck,
  126. FLAGCLEAR(FOptions, fsoDisableByChecksum) && !SynchronizeBothButton->Checked && !SynchronizeTimestampsButton->Checked);
  127. EnableControl(SynchronizeSelectedOnlyCheck, FLAGSET(FOptions, fsoAllowSelectedOnly));
  128. EnableControl(OkButton, !LocalDirectoryEdit->Text.IsEmpty() &&
  129. !RemoteDirectoryEdit->Text.IsEmpty());
  130. UnicodeString InfoStr = FCopyParams.GetInfoStr(L"; ", ActualCopyParamAttrs());
  131. SetLabelHintPopup(CopyParamLabel, InfoStr);
  132. SynchronizeBySizeCheck->Caption = SynchronizeTimestampsButton->Checked ?
  133. LoadStr(SYNCHRONIZE_SAME_SIZE) : UnicodeString(FSynchronizeBySizeCaption);
  134. TransferSettingsButton->Style =
  135. FLAGCLEAR(FOptions, fsoDoNotUsePresets) ?
  136. TCustomButton::bsSplitButton : TCustomButton::bsPushButton;
  137. OkButton->Style = AllowStartInNewWindow() ? TCustomButton::bsSplitButton : TCustomButton::bsPushButton;
  138. StartInNewWindowItem->Enabled = CanStartInNewWindow();
  139. }
  140. //---------------------------------------------------------------------------
  141. int __fastcall TFullSynchronizeDialog::ActualCopyParamAttrs()
  142. {
  143. int Result;
  144. if (SynchronizeTimestampsButton->Checked)
  145. {
  146. Result = cpaIncludeMaskOnly;
  147. }
  148. else
  149. {
  150. switch (Mode)
  151. {
  152. case smRemote:
  153. Result = FCopyParamAttrs.Upload;
  154. break;
  155. case smLocal:
  156. Result = FCopyParamAttrs.Download;
  157. break;
  158. default:
  159. DebugFail();
  160. //fallthru
  161. case smBoth:
  162. Result = FCopyParamAttrs.General;
  163. break;
  164. }
  165. }
  166. return
  167. Result |
  168. FLAGMASK(SynchronizeByTimeCheck->Checked, cpaNoPreserveTime) |
  169. cpaNoNewerOnly;
  170. }
  171. //---------------------------------------------------------------------------
  172. void __fastcall TFullSynchronizeDialog::ControlChange(TObject * /*Sender*/)
  173. {
  174. UpdateControls();
  175. }
  176. //---------------------------------------------------------------------------
  177. bool __fastcall TFullSynchronizeDialog::Execute()
  178. {
  179. // at start assume that copy param is current preset
  180. FPreset = GUIConfiguration->CopyParamCurrent;
  181. LocalDirectoryEdit->Items = CustomWinConfiguration->History[L"LocalDirectory"];
  182. RemoteDirectoryEdit->Items = CustomWinConfiguration->History[L"RemoteDirectory"];
  183. bool Result = (ShowModal() == DefaultResult(this));
  184. if (Result)
  185. {
  186. Submitted();
  187. }
  188. return Result;
  189. }
  190. //---------------------------------------------------------------------------
  191. void __fastcall TFullSynchronizeDialog::Submitted()
  192. {
  193. LocalDirectoryEdit->SaveToHistory();
  194. CustomWinConfiguration->History[L"LocalDirectory"] = LocalDirectoryEdit->Items;
  195. RemoteDirectoryEdit->SaveToHistory();
  196. CustomWinConfiguration->History[L"RemoteDirectory"] = RemoteDirectoryEdit->Items;
  197. }
  198. //---------------------------------------------------------------------------
  199. void __fastcall TFullSynchronizeDialog::SetRemoteDirectory(const UnicodeString value)
  200. {
  201. RemoteDirectoryEdit->Text = value;
  202. }
  203. //---------------------------------------------------------------------------
  204. UnicodeString __fastcall TFullSynchronizeDialog::GetRemoteDirectory()
  205. {
  206. return RemoteDirectoryEdit->Text;
  207. }
  208. //---------------------------------------------------------------------------
  209. void __fastcall TFullSynchronizeDialog::SetLocalDirectory(const UnicodeString value)
  210. {
  211. LocalDirectoryEdit->Text = value;
  212. }
  213. //---------------------------------------------------------------------------
  214. UnicodeString __fastcall TFullSynchronizeDialog::GetLocalDirectory()
  215. {
  216. return LocalDirectoryEdit->Text;
  217. }
  218. //---------------------------------------------------------------------------
  219. void __fastcall TFullSynchronizeDialog::SetMode(TSynchronizeMode value)
  220. {
  221. FOrigMode = value;
  222. switch (value)
  223. {
  224. case smRemote:
  225. SynchronizeRemoteButton->Checked = true;
  226. break;
  227. case smLocal:
  228. SynchronizeLocalButton->Checked = true;
  229. break;
  230. case smBoth:
  231. SynchronizeBothButton->Checked = true;
  232. break;
  233. default:
  234. DebugFail();
  235. }
  236. }
  237. //---------------------------------------------------------------------------
  238. TSynchronizeMode __fastcall TFullSynchronizeDialog::GetMode()
  239. {
  240. if (SynchronizeRemoteButton->Checked)
  241. {
  242. return smRemote;
  243. }
  244. else if (SynchronizeLocalButton->Checked)
  245. {
  246. return smLocal;
  247. }
  248. else
  249. {
  250. DebugAssert(SynchronizeBothButton->Checked);
  251. return smBoth;
  252. }
  253. }
  254. //---------------------------------------------------------------------------
  255. void __fastcall TFullSynchronizeDialog::SetParams(int value)
  256. {
  257. FParams = value &
  258. ~(TTerminal::spDelete | TTerminal::spExistingOnly | TTerminal::spPreviewChanges | TTerminal::spTimestamp |
  259. TTerminal::spNotByTime | TTerminal::spBySize | TTerminal::spSelectedOnly | TTerminal::spMirror |
  260. TTerminal::spCaseSensitive | TTerminal::spByChecksum);
  261. SynchronizeDeleteCheck->Checked = FLAGSET(value, TTerminal::spDelete);
  262. SynchronizeExistingOnlyCheck->Checked = FLAGSET(value, TTerminal::spExistingOnly);
  263. SynchronizePreviewChangesCheck->Checked = FLAGSET(value, TTerminal::spPreviewChanges);
  264. SynchronizeSelectedOnlyCheck->Checked = FLAGSET(value, TTerminal::spSelectedOnly);
  265. if (FLAGSET(value, TTerminal::spTimestamp) && FLAGCLEAR(FOptions, fsoDisableTimestamp))
  266. {
  267. SynchronizeTimestampsButton->Checked = true;
  268. }
  269. else if (FLAGSET(value, TTerminal::spMirror))
  270. {
  271. MirrorFilesButton->Checked = true;
  272. }
  273. else
  274. {
  275. SynchronizeFilesButton->Checked = true;
  276. }
  277. SynchronizeByTimeCheck->Checked = FLAGCLEAR(value, TTerminal::spNotByTime);
  278. SynchronizeBySizeCheck->Checked = FLAGSET(value, TTerminal::spBySize);
  279. SynchronizeByChecksumCheck->Checked = FLAGSET(value, TTerminal::spByChecksum);
  280. SynchronizeCaseSensitiveCheck->Checked = FLAGSET(value, TTerminal::spCaseSensitive);
  281. UpdateControls();
  282. }
  283. //---------------------------------------------------------------------------
  284. int __fastcall TFullSynchronizeDialog::GetParams()
  285. {
  286. return FParams |
  287. FLAGMASK(SynchronizeDeleteCheck->Checked, TTerminal::spDelete) |
  288. FLAGMASK(SynchronizeExistingOnlyCheck->Checked, TTerminal::spExistingOnly) |
  289. FLAGMASK(SynchronizePreviewChangesCheck->Checked, TTerminal::spPreviewChanges) |
  290. FLAGMASK(SynchronizeSelectedOnlyCheck->Checked, TTerminal::spSelectedOnly) |
  291. FLAGMASK(SynchronizeTimestampsButton->Checked && FLAGCLEAR(FOptions, fsoDisableTimestamp),
  292. TTerminal::spTimestamp) |
  293. FLAGMASK(MirrorFilesButton->Checked, TTerminal::spMirror) |
  294. FLAGMASK(!SynchronizeByTimeCheck->Checked, TTerminal::spNotByTime) |
  295. FLAGMASK(SynchronizeBySizeCheck->Checked, TTerminal::spBySize) |
  296. FLAGMASK(SynchronizeByChecksumCheck->Enabled && SynchronizeByChecksumCheck->Checked, TTerminal::spByChecksum) |
  297. FLAGMASK(SynchronizeCaseSensitiveCheck->Checked, TTerminal::spCaseSensitive);
  298. }
  299. //---------------------------------------------------------------------------
  300. void __fastcall TFullSynchronizeDialog::LocalDirectoryBrowseButtonClick(
  301. TObject * /*Sender*/)
  302. {
  303. UnicodeString Directory = LocalDirectoryEdit->Text;
  304. if (SelectDirectory(Directory, LoadStr(SELECT_LOCAL_DIRECTORY), false))
  305. {
  306. LocalDirectoryEdit->Text = Directory;
  307. }
  308. }
  309. //---------------------------------------------------------------------------
  310. void __fastcall TFullSynchronizeDialog::SetSaveSettings(bool value)
  311. {
  312. SaveSettingsCheck->Checked = value;
  313. }
  314. //---------------------------------------------------------------------------
  315. bool __fastcall TFullSynchronizeDialog::GetSaveSettings()
  316. {
  317. return SaveSettingsCheck->Checked;
  318. }
  319. //---------------------------------------------------------------------------
  320. void __fastcall TFullSynchronizeDialog::CopyParamListPopup(TRect R, int AdditionalOptions)
  321. {
  322. // We pass in FCopyParams, although it may not be the exact copy param
  323. // that will be used (because of Preservetime). The reason is to
  324. // display checkbox next to user-selected preset
  325. ::CopyParamListPopup(
  326. R, FPresetsMenu, FCopyParams, FPreset, CopyParamClick,
  327. AdditionalOptions,
  328. ActualCopyParamAttrs());
  329. }
  330. //---------------------------------------------------------------------------
  331. void __fastcall TFullSynchronizeDialog::TransferSettingsButtonClick(
  332. TObject * /*Sender*/)
  333. {
  334. if (FLAGCLEAR(FOptions, fsoDoNotUsePresets) && !SupportsSplitButton())
  335. {
  336. CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), 0);
  337. }
  338. else
  339. {
  340. CopyParamGroupClick(NULL);
  341. }
  342. }
  343. //---------------------------------------------------------------------------
  344. void __fastcall TFullSynchronizeDialog::CopyParamClick(TObject * Sender)
  345. {
  346. DebugAssert(FLAGCLEAR(FOptions, fsoDoNotUsePresets));
  347. // PreserveTime is forced for some settings, but avoid hard-setting it until
  348. // user really confirms it on custom dialog
  349. TCopyParamType ACopyParams = CopyParams;
  350. if (CopyParamListPopupClick(Sender, ACopyParams, FPreset,
  351. ActualCopyParamAttrs()) > 0)
  352. {
  353. FCopyParams = ACopyParams;
  354. UpdateControls();
  355. }
  356. }
  357. //---------------------------------------------------------------------------
  358. void __fastcall TFullSynchronizeDialog::FormShow(TObject * /*Sender*/)
  359. {
  360. InstallPathWordBreakProc(LocalDirectoryEdit);
  361. InstallPathWordBreakProc(RemoteDirectoryEdit);
  362. UpdateControls();
  363. }
  364. //---------------------------------------------------------------------------
  365. void __fastcall TFullSynchronizeDialog::FormCloseQuery(TObject * /*Sender*/,
  366. bool & CanClose)
  367. {
  368. if ((ModalResult == DefaultResult(this)) &&
  369. SaveSettings && (FOrigMode != Mode) && !FSaveMode)
  370. {
  371. switch (MessageDialog(LoadStr(SAVE_SYNCHRONIZE_MODE2),
  372. qtConfirmation, qaYes | qaNo | qaCancel, HELP_SYNCHRONIZE_SAVE_MODE))
  373. {
  374. case qaYes:
  375. FSaveMode = true;
  376. break;
  377. case qaCancel:
  378. CanClose = false;
  379. break;
  380. }
  381. }
  382. }
  383. //---------------------------------------------------------------------------
  384. TCopyParamType __fastcall TFullSynchronizeDialog::GetCopyParams()
  385. {
  386. TCopyParamType Result = FCopyParams;
  387. // when synchronizing by time, we force preserving time,
  388. // otherwise it does not make any sense
  389. if (FLAGCLEAR(Params, TTerminal::spNotByTime))
  390. {
  391. Result.PreserveTime = true;
  392. }
  393. Result.NewerOnly = false;
  394. return Result;
  395. }
  396. //---------------------------------------------------------------------------
  397. void __fastcall TFullSynchronizeDialog::SetCopyParams(const TCopyParamType & value)
  398. {
  399. FCopyParams = value;
  400. UpdateControls();
  401. }
  402. //---------------------------------------------------------------------------
  403. void __fastcall TFullSynchronizeDialog::CopyParamGroupContextPopup(
  404. TObject * /*Sender*/, TPoint & MousePos, bool & Handled)
  405. {
  406. if (FLAGCLEAR(FOptions, fsoDoNotUsePresets))
  407. {
  408. CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos), cplCustomizeDefault);
  409. Handled = true;
  410. }
  411. }
  412. //---------------------------------------------------------------------------
  413. void __fastcall TFullSynchronizeDialog::CopyParamGroupClick(
  414. TObject * /*Sender*/)
  415. {
  416. // PreserveTime is forced for some settings, but avoid hard-setting it until
  417. // user really confirms it on custom dialog
  418. TCopyParamType ACopyParams = CopyParams;
  419. if (DoCopyParamCustomDialog(ACopyParams, ActualCopyParamAttrs()))
  420. {
  421. FCopyParams = ACopyParams;
  422. UpdateControls();
  423. }
  424. }
  425. //---------------------------------------------------------------------------
  426. void __fastcall TFullSynchronizeDialog::HelpButtonClick(TObject * /*Sender*/)
  427. {
  428. FormHelp(this);
  429. }
  430. //---------------------------------------------------------------------------
  431. void __fastcall TFullSynchronizeDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/)
  432. {
  433. CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault);
  434. }
  435. //---------------------------------------------------------------------------
  436. bool __fastcall TFullSynchronizeDialog::AllowStartInNewWindow()
  437. {
  438. return !IsMainFormLike(this);
  439. }
  440. //---------------------------------------------------------------------------
  441. bool __fastcall TFullSynchronizeDialog::CanStartInNewWindow()
  442. {
  443. return
  444. AllowStartInNewWindow() &&
  445. (!SynchronizeSelectedOnlyCheck->Enabled || !SynchronizeSelectedOnlyCheck->Checked);
  446. }
  447. //---------------------------------------------------------------------------
  448. void __fastcall TFullSynchronizeDialog::Start1Click(TObject *)
  449. {
  450. OkButton->Click();
  451. }
  452. //---------------------------------------------------------------------------
  453. void __fastcall TFullSynchronizeDialog::OkButtonDropDownClick(TObject *)
  454. {
  455. MenuPopup(OkMenu, OkButton);
  456. }
  457. //---------------------------------------------------------------------------
  458. void __fastcall TFullSynchronizeDialog::OkButtonClick(TObject *)
  459. {
  460. if (OpenInNewWindow())
  461. {
  462. if (CanStartInNewWindow())
  463. {
  464. StartInNewWindow();
  465. ModalResult = mrCancel;
  466. }
  467. else
  468. {
  469. Beep();
  470. }
  471. Abort();
  472. }
  473. }
  474. //---------------------------------------------------------------------------
  475. void __fastcall TFullSynchronizeDialog::StartInNewWindow()
  476. {
  477. Submitted();
  478. TCopyParamType ACopyParams = CopyParams;
  479. FOnFullSynchronizeInNewWindow(Mode, Params, LocalDirectory, RemoteDirectory, &ACopyParams);
  480. Close();
  481. }
  482. //---------------------------------------------------------------------------
  483. void __fastcall TFullSynchronizeDialog::StartInNewWindowItemClick(TObject *)
  484. {
  485. StartInNewWindow();
  486. }
  487. //---------------------------------------------------------------------------