FullSynchronize.cpp 18 KB

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