FullSynchronize.cpp 19 KB

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