FullSynchronize.cpp 17 KB

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