FullSynchronize.cpp 17 KB

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