Copy.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include <WinInterface.h>
  6. #include <CoreMain.h>
  7. #include <TextsWin.h>
  8. #include <VCLCommon.h>
  9. #include <CustomWinConfiguration.h>
  10. #include <Tools.h>
  11. #include "Copy.h"
  12. //---------------------------------------------------------------------------
  13. #pragma package(smart_init)
  14. #pragma link "Rights"
  15. #pragma link "CopyParams"
  16. #pragma link "HistoryComboBox"
  17. #ifndef NO_RESOURCES
  18. #pragma resource "*.dfm"
  19. #endif
  20. //---------------------------------------------------------------------------
  21. bool __fastcall DoCopyDialog(bool ToRemote,
  22. bool Move, TStrings * FileList, UnicodeString & TargetDirectory,
  23. TGUICopyParamType * Params, int Options, int CopyParamAttrs, int * OutputOptions)
  24. {
  25. bool Result;
  26. TCopyDialog *CopyDialog = new TCopyDialog(Application, ToRemote, Move, FileList, Options, CopyParamAttrs);
  27. try
  28. {
  29. if (FLAGSET(CopyParamAttrs, cpaNoTransferMode))
  30. {
  31. // If local and remote EOL types are the same, there is no need
  32. // for ASCII (or Automatic) mode
  33. Params->TransferMode = tmBinary;
  34. }
  35. if (OutputOptions != NULL)
  36. {
  37. CopyDialog->OutputOptions = *OutputOptions;
  38. }
  39. CopyDialog->Directory = TargetDirectory;
  40. CopyDialog->Params = *Params;
  41. Result = CopyDialog->Execute();
  42. if (Result)
  43. {
  44. TargetDirectory = CopyDialog->Directory;
  45. *Params = CopyDialog->Params;
  46. if (OutputOptions != NULL)
  47. {
  48. *OutputOptions = CopyDialog->OutputOptions;
  49. }
  50. }
  51. }
  52. __finally
  53. {
  54. delete CopyDialog;
  55. }
  56. return Result;
  57. }
  58. //---------------------------------------------------------------------------
  59. __fastcall TCopyDialog::TCopyDialog(
  60. TComponent* Owner, bool ToRemote, bool Move, TStrings * FileList, int Options, int CopyParamAttrs)
  61. : TForm(Owner)
  62. {
  63. FToRemote = ToRemote;
  64. FMove = Move;
  65. FOptions = Options;
  66. FCopyParamAttrs = CopyParamAttrs;
  67. FFileList = FileList;
  68. FOutputOptions = 0;
  69. AdjustControls();
  70. FPresetsMenu = new TPopupMenu(this);
  71. HotTrackLabel(CopyParamLabel);
  72. CopyParamListButton(TransferSettingsButton);
  73. HotTrackLabel(ShortCutHintLabel);
  74. UseSystemSettings(this);
  75. }
  76. //---------------------------------------------------------------------------
  77. __fastcall TCopyDialog::~TCopyDialog()
  78. {
  79. delete FPresetsMenu;
  80. }
  81. //---------------------------------------------------------------------------
  82. void __fastcall TCopyDialog::AdjustTransferControls()
  83. {
  84. if (FFileList && FFileList->Count)
  85. {
  86. if (!FToRemote && !FMove && FLAGSET(FOutputOptions, cooRemoteTransfer))
  87. {
  88. UnicodeString Label;
  89. if (FFileList->Count == 1)
  90. {
  91. UnicodeString FileName;
  92. if (!FToRemote) FileName = UnixExtractFileName(FFileList->Strings[0]);
  93. else FileName = ExtractFileName(FFileList->Strings[0]);
  94. Label = FMTLOAD(REMOTE_COPY_FILE, (FileName));
  95. }
  96. else
  97. {
  98. Label = FMTLOAD(REMOTE_COPY_FILES, (FFileList->Count));
  99. }
  100. DirectoryLabel->Caption = Label;
  101. }
  102. else
  103. {
  104. UnicodeString TransferStr =
  105. LoadStr(RemotePaths() ? COPY_COPY_TOREMOTE : COPY_COPY_TOLOCAL);
  106. // currently the copy dialog is shown when downloading to temp folder
  107. // only for drag&drop downloads, for we dare to display d&d specific prompt
  108. UnicodeString DirectionStr =
  109. LoadStr(((FOptions & coTemp) != 0) ? COPY_TODROP :
  110. (RemotePaths() ? COPY_TOREMOTE : COPY_TOLOCAL));
  111. if (FFileList->Count == 1)
  112. {
  113. UnicodeString FileName;
  114. if (!FToRemote) FileName = UnixExtractFileName(FFileList->Strings[0]);
  115. else FileName = ExtractFileName(FFileList->Strings[0]);
  116. DirectoryLabel->Caption = FMTLOAD((FMove ? MOVE_FILE : COPY_FILE),
  117. (TransferStr, FileName, DirectionStr));
  118. }
  119. else
  120. {
  121. DirectoryLabel->Caption = FMTLOAD((FMove ? MOVE_FILES : COPY_FILES),
  122. (TransferStr, FFileList->Count, DirectionStr));
  123. }
  124. }
  125. }
  126. TImage * Image;
  127. UnicodeString ACaption;
  128. if (!FMove)
  129. {
  130. if (!FToRemote && FLAGSET(FOutputOptions, cooRemoteTransfer))
  131. {
  132. ACaption = LoadStr(REMOTE_COPY_TITLE);
  133. Image = CopyImage;
  134. }
  135. else
  136. {
  137. if (RemotePaths())
  138. {
  139. ACaption = LoadStr(COPY_COPY_TOREMOTE_CAPTION);
  140. Image = CopyUploadImage;
  141. }
  142. else
  143. {
  144. ACaption = LoadStr(COPY_COPY_TOLOCAL_CAPTION);
  145. Image = CopyDownloadImage;
  146. }
  147. }
  148. }
  149. else
  150. {
  151. if (!FToRemote && FLAGSET(FOutputOptions, cooRemoteTransfer))
  152. {
  153. ACaption = LoadStr(COPY_MOVE_CAPTION);
  154. Image = MoveImage;
  155. }
  156. else
  157. {
  158. if (RemotePaths())
  159. {
  160. ACaption = LoadStr(COPY_MOVE_TOREMOTE_CAPTION);
  161. Image = MoveUploadImage;
  162. }
  163. else
  164. {
  165. ACaption = LoadStr(COPY_MOVE_TOLOCAL_CAPTION);
  166. Image = MoveDownloadImage;
  167. }
  168. }
  169. }
  170. Caption = FormatFormCaption(this, ACaption);
  171. CopyImage->Visible = (Image == CopyImage) || (Image == NULL);
  172. MoveImage->Visible = (Image == MoveImage);
  173. CopyUploadImage->Visible = (Image == CopyUploadImage);
  174. CopyDownloadImage->Visible = (Image == CopyDownloadImage);
  175. MoveUploadImage->Visible = (Image == MoveUploadImage);
  176. MoveDownloadImage->Visible = (Image == MoveDownloadImage);
  177. bool RemoteTransfer = FLAGSET(FOutputOptions, cooRemoteTransfer);
  178. assert(FLAGSET(FOptions, coAllowRemoteTransfer) || !RemoteTransfer);
  179. EnableControl(TransferSettingsButton, !RemoteTransfer);
  180. EnableControl(CopyParamGroup, !RemoteTransfer);
  181. }
  182. //---------------------------------------------------------------------------
  183. void __fastcall TCopyDialog::AdjustControls()
  184. {
  185. RemoteDirectoryEdit->Visible = false;
  186. LocalDirectoryEdit->Visible = false;
  187. DirectoryEdit->Visible = FLAGCLEAR(FOptions, coTemp);
  188. EnableControl(DirectoryEdit, FLAGCLEAR(FOptions, coDisableDirectory));
  189. EnableControl(DirectoryLabel, DirectoryEdit->Enabled);
  190. EnableControl(LocalDirectoryBrowseButton, DirectoryEdit->Enabled);
  191. DirectoryLabel->FocusControl = DirectoryEdit;
  192. UnicodeString QueueLabel = LoadStr(COPY_BACKGROUND);
  193. if (FLAGCLEAR(FOptions, coNoQueue))
  194. {
  195. QueueLabel = FMTLOAD(COPY_QUEUE, (QueueLabel));
  196. }
  197. QueueCheck2->Caption = QueueLabel;
  198. AdjustTransferControls();
  199. LocalDirectoryBrowseButton->Visible = !FToRemote &&
  200. FLAGCLEAR(FOptions, coTemp);
  201. if (FLAGCLEAR(FOptions, coDoNotShowAgain))
  202. {
  203. NeverShowAgainCheck->Visible = false;
  204. ClientHeight = ClientHeight -
  205. (ShortCutHintPanel->Top - NeverShowAgainCheck->Top);
  206. }
  207. if (FLAGCLEAR(FOptions, coShortCutHint) || CustomWinConfiguration->CopyShortCutHintShown)
  208. {
  209. ShortCutHintPanel->Visible = false;
  210. ClientHeight = ClientHeight - ShortCutHintPanel->Height;
  211. }
  212. UpdateControls();
  213. }
  214. //---------------------------------------------------------------------------
  215. void __fastcall TCopyDialog::SetOutputOptions(int value)
  216. {
  217. if (OutputOptions != value)
  218. {
  219. FSaveSettings = FLAGSET(value, cooSaveSettings);
  220. NeverShowAgainCheck->Checked = FLAGSET(value, cooDoNotShowAgain);
  221. FOutputOptions = (value & ~(cooDoNotShowAgain | cooSaveSettings));
  222. }
  223. }
  224. //---------------------------------------------------------------------------
  225. int __fastcall TCopyDialog::GetOutputOptions()
  226. {
  227. return FOutputOptions |
  228. FLAGMASK(FSaveSettings, cooSaveSettings) |
  229. FLAGMASK(NeverShowAgainCheck->Checked, cooDoNotShowAgain);
  230. }
  231. //---------------------------------------------------------------------------
  232. THistoryComboBox * __fastcall TCopyDialog::GetDirectoryEdit()
  233. {
  234. return FToRemote ? RemoteDirectoryEdit : LocalDirectoryEdit;
  235. }
  236. //---------------------------------------------------------------------------
  237. bool __fastcall TCopyDialog::RemotePaths()
  238. {
  239. return (FToRemote || FLAGSET(FOutputOptions, cooRemoteTransfer));
  240. }
  241. //---------------------------------------------------------------------------
  242. UnicodeString __fastcall TCopyDialog::GetFileMask()
  243. {
  244. return ExtractFileName(DirectoryEdit->Text, RemotePaths());
  245. }
  246. //---------------------------------------------------------------------------
  247. void __fastcall TCopyDialog::SetParams(const TGUICopyParamType & value)
  248. {
  249. FParams = value;
  250. FCopyParams = value;
  251. DirectoryEdit->Text = Directory + FParams.FileMask;
  252. QueueCheck2->Checked = FParams.Queue;
  253. QueueIndividuallyCheck->Checked = FParams.QueueIndividually;
  254. UpdateControls();
  255. }
  256. //---------------------------------------------------------------------------
  257. TGUICopyParamType __fastcall TCopyDialog::GetParams()
  258. {
  259. // overwrites TCopyParamType fields only
  260. FParams = FCopyParams;
  261. FParams.FileMask = GetFileMask();
  262. FParams.Queue = QueueCheck2->Checked;
  263. FParams.QueueIndividually = QueueIndividuallyCheck->Checked;
  264. return FParams;
  265. }
  266. //---------------------------------------------------------------------------
  267. void __fastcall TCopyDialog::SetDirectory(UnicodeString value)
  268. {
  269. if (!value.IsEmpty())
  270. {
  271. value = RemotePaths() ?
  272. UnicodeString(UnixIncludeTrailingBackslash(value)) : IncludeTrailingBackslash(value);
  273. }
  274. DirectoryEdit->Text = value + GetFileMask();
  275. }
  276. //---------------------------------------------------------------------------
  277. UnicodeString __fastcall TCopyDialog::GetDirectory()
  278. {
  279. assert(DirectoryEdit);
  280. UnicodeString Result = DirectoryEdit->Text;
  281. if (RemotePaths())
  282. {
  283. Result = UnixExtractFilePath(Result);
  284. if (!Result.IsEmpty())
  285. {
  286. Result = UnixIncludeTrailingBackslash(Result);
  287. }
  288. }
  289. else
  290. {
  291. Result = ExtractFilePath(Result);
  292. if (!Result.IsEmpty())
  293. {
  294. Result = IncludeTrailingBackslash(Result);
  295. }
  296. }
  297. return Result;
  298. }
  299. //---------------------------------------------------------------------------
  300. void __fastcall TCopyDialog::UpdateControls()
  301. {
  302. if (!FToRemote && FLAGSET(FOptions, coAllowRemoteTransfer))
  303. {
  304. UnicodeString Directory = DirectoryEdit->Text;
  305. bool RemoteTransfer = (Directory.Pos(L"\\") == 0) && (Directory.Pos(L"/") > 0);
  306. if (RemoteTransfer != FLAGSET(FOutputOptions, cooRemoteTransfer))
  307. {
  308. FOutputOptions =
  309. (FOutputOptions & ~cooRemoteTransfer) |
  310. FLAGMASK(RemoteTransfer, cooRemoteTransfer);
  311. AdjustTransferControls();
  312. }
  313. }
  314. UnicodeString InfoStr = FCopyParams.GetInfoStr(L"; ", FCopyParamAttrs);
  315. CopyParamLabel->Caption = InfoStr;
  316. CopyParamLabel->Hint = InfoStr;
  317. CopyParamLabel->ShowHint =
  318. (CopyParamLabel->Canvas->TextWidth(InfoStr) > (CopyParamLabel->Width * 3 / 2));
  319. bool RemoteTransfer = FLAGSET(FOutputOptions, cooRemoteTransfer);
  320. EnableControl(QueueCheck2,
  321. ((FOptions & (coDisableQueue | coTemp)) == 0) && !RemoteTransfer);
  322. QueueIndividuallyCheck->Visible =
  323. FLAGCLEAR(FOptions, coNoQueueIndividually) &&
  324. QueueCheck2->Enabled && QueueCheck2->Checked &&
  325. (FFileList != NULL) && (FFileList->Count > 1);
  326. TransferSettingsButton->Style =
  327. FLAGCLEAR(FOptions, coDoNotUsePresets) ?
  328. TCustomButton::bsSplitButton : TCustomButton::bsPushButton;
  329. }
  330. //---------------------------------------------------------------------------
  331. void __fastcall TCopyDialog::FormShow(TObject * /*Sender*/)
  332. {
  333. assert(FFileList && (FFileList->Count > 0));
  334. if (DirectoryEdit->Enabled && DirectoryEdit->Visible)
  335. {
  336. ActiveControl = DirectoryEdit;
  337. }
  338. else
  339. {
  340. ActiveControl = OkButton;
  341. }
  342. UpdateControls();
  343. InstallPathWordBreakProc(RemoteDirectoryEdit);
  344. InstallPathWordBreakProc(LocalDirectoryEdit);
  345. // Does not work when set from a contructor
  346. ShortCutHintPanel->Color = Application->HintColor;
  347. }
  348. //---------------------------------------------------------------------------
  349. bool __fastcall TCopyDialog::Execute()
  350. {
  351. // at start assume that copy param is current preset
  352. FPreset = GUIConfiguration->CopyParamCurrent;
  353. DirectoryEdit->Items = CustomWinConfiguration->History[
  354. FToRemote ? L"RemoteTarget" : L"LocalTarget"];
  355. bool Result = (ShowModal() == DefaultResult(this));
  356. if (Result)
  357. {
  358. Configuration->BeginUpdate();
  359. try
  360. {
  361. if (FLAGSET(OutputOptions, cooSaveSettings) &&
  362. FLAGCLEAR(FOptions, coDisableSaveSettings))
  363. {
  364. GUIConfiguration->DefaultCopyParam = Params;
  365. }
  366. DirectoryEdit->SaveToHistory();
  367. CustomWinConfiguration->History[FToRemote ?
  368. L"RemoteTarget" : L"LocalTarget"] = DirectoryEdit->Items;
  369. if (FLAGSET(FOptions, coShortCutHint))
  370. {
  371. CustomWinConfiguration->CopyShortCutHintShown = true;
  372. }
  373. }
  374. __finally
  375. {
  376. Configuration->EndUpdate();
  377. }
  378. }
  379. return Result;
  380. }
  381. //---------------------------------------------------------------------------
  382. void __fastcall TCopyDialog::FormCloseQuery(TObject * /*Sender*/,
  383. bool &CanClose)
  384. {
  385. if (ModalResult == DefaultResult(this))
  386. {
  387. if (!RemotePaths() && ((FOptions & coTemp) == 0))
  388. {
  389. UnicodeString Dir = Directory;
  390. UnicodeString Drive = ExtractFileDrive(Dir);
  391. if (!DirectoryExists(ApiPath(Dir)))
  392. {
  393. if (MessageDialog(MainInstructions(FMTLOAD(CREATE_LOCAL_DIRECTORY, (Dir))),
  394. qtConfirmation, qaOK | qaCancel, HELP_NONE) != qaCancel)
  395. {
  396. if (!ForceDirectories(ApiPath(Dir)))
  397. {
  398. SimpleErrorDialog(FMTLOAD(CREATE_LOCAL_DIR_ERROR, (Dir)));
  399. CanClose = false;
  400. }
  401. }
  402. else
  403. {
  404. CanClose = False;
  405. }
  406. }
  407. if (!CanClose)
  408. {
  409. DirectoryEdit->SelectAll();
  410. DirectoryEdit->SetFocus();
  411. }
  412. };
  413. if (CanClose)
  414. {
  415. ExitActiveControl(this);
  416. }
  417. }
  418. }
  419. //---------------------------------------------------------------------------
  420. void __fastcall TCopyDialog::LocalDirectoryBrowseButtonClick(
  421. TObject * /*Sender*/)
  422. {
  423. assert(!FToRemote);
  424. UnicodeString ADirectory;
  425. // if we are duplicating, we have remote path there
  426. if (!RemotePaths())
  427. {
  428. ADirectory = Directory;
  429. }
  430. if (SelectDirectory(ADirectory, LoadStr(SELECT_LOCAL_DIRECTORY), true))
  431. {
  432. Directory = ADirectory;
  433. UpdateControls();
  434. }
  435. }
  436. //---------------------------------------------------------------------------
  437. void __fastcall TCopyDialog::ControlChange(TObject * /*Sender*/)
  438. {
  439. UpdateControls();
  440. ResetSystemSettings(this);
  441. }
  442. //---------------------------------------------------------------------------
  443. void __fastcall TCopyDialog::TransferSettingsButtonClick(TObject * /*Sender*/)
  444. {
  445. if (FLAGCLEAR(FOptions, coDoNotUsePresets) && !SupportsSplitButton())
  446. {
  447. CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), 0);
  448. }
  449. else
  450. {
  451. CopyParamGroupClick(NULL);
  452. }
  453. }
  454. //---------------------------------------------------------------------------
  455. void __fastcall TCopyDialog::CopyParamClick(TObject * Sender)
  456. {
  457. TCopyParamType Param = Params;
  458. bool PrevSaveSettings = FSaveSettings;
  459. if (CopyParamListPopupClick(Sender, Param, FPreset, FCopyParamAttrs, &FSaveSettings))
  460. {
  461. Params = Param;
  462. }
  463. else
  464. {
  465. UpdateControls();
  466. }
  467. if (PrevSaveSettings && !FSaveSettings)
  468. {
  469. NeverShowAgainCheck->Checked = false;
  470. }
  471. }
  472. //---------------------------------------------------------------------------
  473. void __fastcall TCopyDialog::HelpButtonClick(TObject * /*Sender*/)
  474. {
  475. FormHelp(this);
  476. }
  477. //---------------------------------------------------------------------------
  478. void __fastcall TCopyDialog::CopyParamGroupClick(TObject * /*Sender*/)
  479. {
  480. if (CopyParamGroup->Enabled)
  481. {
  482. if (DoCopyParamCustomDialog(FCopyParams, FCopyParamAttrs))
  483. {
  484. UpdateControls();
  485. }
  486. }
  487. }
  488. //---------------------------------------------------------------------------
  489. void __fastcall TCopyDialog::CopyParamGroupContextPopup(TObject * /*Sender*/,
  490. TPoint & MousePos, bool & Handled)
  491. {
  492. if (FLAGCLEAR(FOptions, coDoNotUsePresets))
  493. {
  494. CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos), cplCustomizeDefault);
  495. Handled = true;
  496. }
  497. }
  498. //---------------------------------------------------------------------------
  499. void __fastcall TCopyDialog::CopyParamListPopup(TRect R, int AdditionalOptions)
  500. {
  501. bool RemoteTransfer = FLAGSET(FOutputOptions, cooRemoteTransfer);
  502. ::CopyParamListPopup(R, FPresetsMenu,
  503. FCopyParams, FPreset, CopyParamClick,
  504. cplCustomize | AdditionalOptions |
  505. FLAGMASK(
  506. FLAGCLEAR(FOptions, coDisableSaveSettings) && !RemoteTransfer,
  507. cplSaveSettings),
  508. FCopyParamAttrs,
  509. FSaveSettings);
  510. }
  511. //---------------------------------------------------------------------------
  512. void __fastcall TCopyDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/)
  513. {
  514. CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault);
  515. }
  516. //---------------------------------------------------------------------------
  517. void __fastcall TCopyDialog::NeverShowAgainCheckClick(TObject * /*Sender*/)
  518. {
  519. FSaveSettings = NeverShowAgainCheck->Checked;
  520. UpdateControls();
  521. }
  522. //---------------------------------------------------------------------------
  523. void __fastcall TCopyDialog::ShortCutHintLabelClick(TObject * /*Sender*/)
  524. {
  525. DoPreferencesDialog(pmCommander);
  526. }
  527. //---------------------------------------------------------------------------