FullSynchronize.cpp 17 KB

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