FullSynchronize.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  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. SynchronizeDeleteCheck->Checked = FLAGSET(value, TTerminal::spDelete);
  257. SynchronizeExistingOnlyCheck->Checked = FLAGSET(value, TTerminal::spExistingOnly);
  258. SynchronizePreviewChangesCheck->Checked = FLAGSET(value, TTerminal::spPreviewChanges);
  259. SynchronizeSelectedOnlyCheck->Checked = FLAGSET(value, TTerminal::spSelectedOnly);
  260. if (FLAGSET(value, TTerminal::spTimestamp) && FLAGCLEAR(FOptions, fsoDisableTimestamp))
  261. {
  262. SynchronizeTimestampsButton->Checked = true;
  263. }
  264. else if (FLAGSET(value, TTerminal::spMirror))
  265. {
  266. MirrorFilesButton->Checked = true;
  267. }
  268. else
  269. {
  270. SynchronizeFilesButton->Checked = true;
  271. }
  272. SynchronizeByTimeCheck->Checked = FLAGCLEAR(value, TTerminal::spNotByTime);
  273. SynchronizeBySizeCheck->Checked = FLAGSET(value, TTerminal::spBySize);
  274. UpdateControls();
  275. }
  276. //---------------------------------------------------------------------------
  277. int __fastcall TFullSynchronizeDialog::GetParams()
  278. {
  279. return FParams |
  280. FLAGMASK(SynchronizeDeleteCheck->Checked, TTerminal::spDelete) |
  281. FLAGMASK(SynchronizeExistingOnlyCheck->Checked, TTerminal::spExistingOnly) |
  282. FLAGMASK(SynchronizePreviewChangesCheck->Checked, TTerminal::spPreviewChanges) |
  283. FLAGMASK(SynchronizeSelectedOnlyCheck->Checked, TTerminal::spSelectedOnly) |
  284. FLAGMASK(SynchronizeTimestampsButton->Checked && FLAGCLEAR(FOptions, fsoDisableTimestamp),
  285. TTerminal::spTimestamp) |
  286. FLAGMASK(MirrorFilesButton->Checked, TTerminal::spMirror) |
  287. FLAGMASK(!SynchronizeByTimeCheck->Checked, TTerminal::spNotByTime) |
  288. FLAGMASK(SynchronizeBySizeCheck->Checked, TTerminal::spBySize);
  289. }
  290. //---------------------------------------------------------------------------
  291. void __fastcall TFullSynchronizeDialog::LocalDirectoryBrowseButtonClick(
  292. TObject * /*Sender*/)
  293. {
  294. UnicodeString Directory = LocalDirectoryEdit->Text;
  295. if (SelectDirectory(Directory, LoadStr(SELECT_LOCAL_DIRECTORY), false))
  296. {
  297. LocalDirectoryEdit->Text = Directory;
  298. }
  299. }
  300. //---------------------------------------------------------------------------
  301. void __fastcall TFullSynchronizeDialog::SetSaveSettings(bool value)
  302. {
  303. SaveSettingsCheck->Checked = value;
  304. }
  305. //---------------------------------------------------------------------------
  306. bool __fastcall TFullSynchronizeDialog::GetSaveSettings()
  307. {
  308. return SaveSettingsCheck->Checked;
  309. }
  310. //---------------------------------------------------------------------------
  311. void __fastcall TFullSynchronizeDialog::CopyParamListPopup(TRect R, int AdditionalOptions)
  312. {
  313. // We pass in FCopyParams, although it may not be the exact copy param
  314. // that will be used (because of Preservetime). The reason is to
  315. // display checkbox next to user-selected preset
  316. ::CopyParamListPopup(
  317. R, FPresetsMenu, FCopyParams, FPreset, CopyParamClick,
  318. AdditionalOptions,
  319. ActualCopyParamAttrs());
  320. }
  321. //---------------------------------------------------------------------------
  322. void __fastcall TFullSynchronizeDialog::TransferSettingsButtonClick(
  323. TObject * /*Sender*/)
  324. {
  325. if (FLAGCLEAR(FOptions, fsoDoNotUsePresets) && !SupportsSplitButton())
  326. {
  327. CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), 0);
  328. }
  329. else
  330. {
  331. CopyParamGroupClick(NULL);
  332. }
  333. }
  334. //---------------------------------------------------------------------------
  335. void __fastcall TFullSynchronizeDialog::CopyParamClick(TObject * Sender)
  336. {
  337. DebugAssert(FLAGCLEAR(FOptions, fsoDoNotUsePresets));
  338. // PreserveTime is forced for some settings, but avoid hard-setting it until
  339. // user really confirms it on custom dialog
  340. TCopyParamType ACopyParams = CopyParams;
  341. if (CopyParamListPopupClick(Sender, ACopyParams, FPreset,
  342. ActualCopyParamAttrs()) > 0)
  343. {
  344. FCopyParams = ACopyParams;
  345. UpdateControls();
  346. }
  347. }
  348. //---------------------------------------------------------------------------
  349. void __fastcall TFullSynchronizeDialog::FormShow(TObject * /*Sender*/)
  350. {
  351. InstallPathWordBreakProc(LocalDirectoryEdit);
  352. InstallPathWordBreakProc(RemoteDirectoryEdit);
  353. UpdateControls();
  354. }
  355. //---------------------------------------------------------------------------
  356. void __fastcall TFullSynchronizeDialog::FormCloseQuery(TObject * /*Sender*/,
  357. bool & CanClose)
  358. {
  359. if ((ModalResult == DefaultResult(this)) &&
  360. SaveSettings && (FOrigMode != Mode) && !FSaveMode)
  361. {
  362. switch (MessageDialog(LoadStr(SAVE_SYNCHRONIZE_MODE2),
  363. qtConfirmation, qaYes | qaNo | qaCancel, HELP_SYNCHRONIZE_SAVE_MODE))
  364. {
  365. case qaYes:
  366. FSaveMode = true;
  367. break;
  368. case qaCancel:
  369. CanClose = false;
  370. break;
  371. }
  372. }
  373. }
  374. //---------------------------------------------------------------------------
  375. TCopyParamType __fastcall TFullSynchronizeDialog::GetCopyParams()
  376. {
  377. TCopyParamType Result = FCopyParams;
  378. // when synchronizing by time, we force preserving time,
  379. // otherwise it does not make any sense
  380. if (FLAGCLEAR(Params, TTerminal::spNotByTime))
  381. {
  382. Result.PreserveTime = true;
  383. }
  384. Result.NewerOnly = false;
  385. return Result;
  386. }
  387. //---------------------------------------------------------------------------
  388. void __fastcall TFullSynchronizeDialog::SetCopyParams(const TCopyParamType & value)
  389. {
  390. FCopyParams = value;
  391. UpdateControls();
  392. }
  393. //---------------------------------------------------------------------------
  394. void __fastcall TFullSynchronizeDialog::CopyParamGroupContextPopup(
  395. TObject * /*Sender*/, TPoint & MousePos, bool & Handled)
  396. {
  397. if (FLAGCLEAR(FOptions, fsoDoNotUsePresets))
  398. {
  399. CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos), cplCustomizeDefault);
  400. Handled = true;
  401. }
  402. }
  403. //---------------------------------------------------------------------------
  404. void __fastcall TFullSynchronizeDialog::CopyParamGroupClick(
  405. TObject * /*Sender*/)
  406. {
  407. // PreserveTime is forced for some settings, but avoid hard-setting it until
  408. // user really confirms it on custom dialog
  409. TCopyParamType ACopyParams = CopyParams;
  410. if (DoCopyParamCustomDialog(ACopyParams, ActualCopyParamAttrs()))
  411. {
  412. FCopyParams = ACopyParams;
  413. UpdateControls();
  414. }
  415. }
  416. //---------------------------------------------------------------------------
  417. void __fastcall TFullSynchronizeDialog::HelpButtonClick(TObject * /*Sender*/)
  418. {
  419. FormHelp(this);
  420. }
  421. //---------------------------------------------------------------------------
  422. void __fastcall TFullSynchronizeDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/)
  423. {
  424. CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault);
  425. }
  426. //---------------------------------------------------------------------------
  427. bool __fastcall TFullSynchronizeDialog::AllowStartInNewWindow()
  428. {
  429. return !IsMainFormLike(this);
  430. }
  431. //---------------------------------------------------------------------------
  432. bool __fastcall TFullSynchronizeDialog::CanStartInNewWindow()
  433. {
  434. return
  435. AllowStartInNewWindow() &&
  436. (!SynchronizeSelectedOnlyCheck->Enabled || !SynchronizeSelectedOnlyCheck->Checked);
  437. }
  438. //---------------------------------------------------------------------------
  439. void __fastcall TFullSynchronizeDialog::Start1Click(TObject *)
  440. {
  441. OkButton->Click();
  442. }
  443. //---------------------------------------------------------------------------
  444. void __fastcall TFullSynchronizeDialog::OkButtonDropDownClick(TObject *)
  445. {
  446. MenuPopup(OkMenu, OkButton);
  447. }
  448. //---------------------------------------------------------------------------
  449. void __fastcall TFullSynchronizeDialog::OkButtonClick(TObject *)
  450. {
  451. if (OpenInNewWindow())
  452. {
  453. if (CanStartInNewWindow())
  454. {
  455. StartInNewWindow();
  456. ModalResult = mrCancel;
  457. }
  458. else
  459. {
  460. Beep();
  461. }
  462. Abort();
  463. }
  464. }
  465. //---------------------------------------------------------------------------
  466. void __fastcall TFullSynchronizeDialog::StartInNewWindow()
  467. {
  468. Submitted();
  469. TCopyParamType ACopyParams = CopyParams;
  470. FOnFullSynchronizeInNewWindow(Mode, Params, LocalDirectory, RemoteDirectory, &ACopyParams);
  471. Close();
  472. }
  473. //---------------------------------------------------------------------------
  474. void __fastcall TFullSynchronizeDialog::StartInNewWindowItemClick(TObject *)
  475. {
  476. StartInNewWindow();
  477. }
  478. //---------------------------------------------------------------------------