Custom.cpp 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597
  1. //---------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Dialogs.hpp>
  5. //---------------------------------------------------------------------
  6. #include <Common.h>
  7. #include <CustomWinConfiguration.h>
  8. #include <WinInterface.h>
  9. #include <VCLCommon.h>
  10. #include <TextsWin.h>
  11. #include <HelpWin.h>
  12. #include <CoreMain.h>
  13. #include <PasTools.hpp>
  14. #include <ProgParams.h>
  15. #include <Tools.h>
  16. #include <GUITools.h>
  17. #include <HistoryComboBox.hpp>
  18. #include <Math.hpp>
  19. #include "Custom.h"
  20. //---------------------------------------------------------------------
  21. #pragma link "PasswordEdit"
  22. #pragma resource "*.dfm"
  23. //---------------------------------------------------------------------
  24. __fastcall TCustomDialog::TCustomDialog(UnicodeString AHelpKeyword)
  25. : TForm(GetFormOwner())
  26. {
  27. UseSystemSettings(this);
  28. FControlPadding = ScaleByTextHeight(this, 8);
  29. FPos = ScaleByTextHeight(this, 8);
  30. FPrePos = FPos;
  31. FHorizontalMargin = ScaleByTextHeight(this, 8);
  32. FIndent = FHorizontalMargin;
  33. FGroupBox = NULL;
  34. HelpKeyword = AHelpKeyword;
  35. TBorderIcons BI = BorderIcons;
  36. if (HelpKeyword.IsEmpty())
  37. {
  38. BI >> biHelp;
  39. OKButton->Left = CancelButton->Left;
  40. CancelButton->Left = HelpButton->Left;
  41. HelpButton->Visible = false;
  42. }
  43. else
  44. {
  45. BI << biHelp;
  46. }
  47. BorderIcons = BI;
  48. }
  49. //---------------------------------------------------------------------
  50. bool __fastcall TCustomDialog::Execute()
  51. {
  52. Changed();
  53. return (ShowModal() == DefaultResult(this));
  54. }
  55. //---------------------------------------------------------------------
  56. void __fastcall TCustomDialog::DoChange(bool & /*CanSubmit*/)
  57. {
  58. // noop
  59. }
  60. //---------------------------------------------------------------------
  61. void __fastcall TCustomDialog::Changed()
  62. {
  63. bool CanSubmit = true;
  64. DoChange(CanSubmit);
  65. EnableControl(OKButton, CanSubmit);
  66. }
  67. //---------------------------------------------------------------------
  68. void __fastcall TCustomDialog::Change(TObject * /*Sender*/)
  69. {
  70. Changed();
  71. }
  72. //---------------------------------------------------------------------------
  73. void __fastcall TCustomDialog::DoHelp()
  74. {
  75. FormHelp(this);
  76. }
  77. //---------------------------------------------------------------------------
  78. void __fastcall TCustomDialog::HelpButtonClick(TObject * /*Sender*/)
  79. {
  80. DoHelp();
  81. }
  82. //---------------------------------------------------------------------------
  83. void __fastcall TCustomDialog::DoShow()
  84. {
  85. OKButton->TabOrder = FCount;
  86. CancelButton->TabOrder = static_cast<short>(FCount + 1);
  87. HelpButton->TabOrder = static_cast<short>(FCount + 2);
  88. Changed();
  89. TForm::DoShow();
  90. }
  91. //---------------------------------------------------------------------------
  92. void __fastcall TCustomDialog::DoValidate()
  93. {
  94. // noop
  95. }
  96. //---------------------------------------------------------------------------
  97. bool __fastcall TCustomDialog::CloseQuery()
  98. {
  99. if (ModalResult == DefaultResult(this))
  100. {
  101. DoValidate();
  102. }
  103. return TForm::CloseQuery();
  104. }
  105. //---------------------------------------------------------------------------
  106. void __fastcall TCustomDialog::RemoveCancelButton()
  107. {
  108. CancelButton->Visible = false;
  109. OKButton->Left = CancelButton->Left;
  110. OKButton->Cancel = true;
  111. DebugAssert(OKButton->Width == CancelButton->Width);
  112. DebugAssert(OKButton->Top == CancelButton->Top);
  113. }
  114. //---------------------------------------------------------------------------
  115. void __fastcall TCustomDialog::AddDialogButton(TButton * Button)
  116. {
  117. Button->Parent = this;
  118. Button->Top = OKButton->Top;
  119. Button->Left = FHorizontalMargin;
  120. Button->Height = OKButton->Height;
  121. AddWinControl(Button);
  122. }
  123. //---------------------------------------------------------------------------
  124. void __fastcall TCustomDialog::AddImage(const UnicodeString & ImageName)
  125. {
  126. TImage * Image = new TImage(this);
  127. Image->Name = L"Image";
  128. Image->Parent = GetDefaultParent();
  129. LoadDialogImage(Image, ImageName);
  130. Image->SetBounds(FIndent, FPos + ScaleByTextHeight(this, 3), Image->Picture->Width, Image->Picture->Height);
  131. FIndent += Image->Width + ScaleByTextHeight(this, 12);
  132. }
  133. //---------------------------------------------------------------------------
  134. int __fastcall TCustomDialog::GetMaxControlWidth(TControl * Control)
  135. {
  136. return GetDefaultParent()->ClientWidth - Control->Left - FHorizontalMargin;
  137. }
  138. //---------------------------------------------------------------------------
  139. TWinControl * __fastcall TCustomDialog::GetDefaultParent()
  140. {
  141. return (FGroupBox != NULL) ? FGroupBox : static_cast<TWinControl *>(this);
  142. }
  143. //---------------------------------------------------------------------------
  144. void __fastcall TCustomDialog::AdjustHeight(TControl * Control)
  145. {
  146. FPos = Control->Top + Control->Height + FControlPadding;
  147. int Delta = (FPos - FPrePos);
  148. ClientHeight = ClientHeight + Delta;
  149. if (FGroupBox != NULL)
  150. {
  151. FGroupBox->Height = FGroupBox->Height + Delta;
  152. }
  153. FPrePos = FPos;
  154. }
  155. //---------------------------------------------------------------------------
  156. void __fastcall TCustomDialog::AddWinControl(TWinControl * Control)
  157. {
  158. Control->TabOrder = FCount;
  159. FCount++;
  160. }
  161. //---------------------------------------------------------------------------
  162. TCheckBox * __fastcall TCustomDialog::CreateAndAddCheckBox(const UnicodeString & Caption)
  163. {
  164. TCheckBox * CheckBox = new TCheckBox(this);
  165. CheckBox->Caption = Caption;
  166. AddButtonControl(CheckBox);
  167. return CheckBox;
  168. }
  169. //---------------------------------------------------------------------------
  170. TLabel * __fastcall TCustomDialog::CreateLabel(UnicodeString Label)
  171. {
  172. TLabel * Result = new TUIStateAwareLabel(this);
  173. Result->Caption = Label;
  174. return Result;
  175. }
  176. //---------------------------------------------------------------------------
  177. void __fastcall TCustomDialog::AddEditLikeControl(TWinControl * Edit, TLabel * Label, bool OneLine)
  178. {
  179. Edit->Parent = GetDefaultParent();
  180. // this updates Height property to real value
  181. Edit->HandleNeeded();
  182. if (Label != NULL)
  183. {
  184. Label->Parent = GetDefaultParent();
  185. Label->Left = FIndent;
  186. if (OneLine)
  187. {
  188. DebugAssert(Edit->Height > Label->Height);
  189. Label->Top = FPos + ((Edit->Height - Label->Height) / 2);
  190. }
  191. else
  192. {
  193. Label->Top = FPos;
  194. FPos += Label->Height + ScaleByTextHeight(this, 4);
  195. }
  196. }
  197. Edit->Top = FPos;
  198. if (OneLine)
  199. {
  200. Edit->Left = GetDefaultParent()->ClientWidth - FHorizontalMargin - Edit->Width;
  201. }
  202. else
  203. {
  204. Edit->Left = FIndent;
  205. Edit->Width = GetMaxControlWidth(Edit);
  206. }
  207. AdjustHeight(Edit);
  208. if (Label != NULL)
  209. {
  210. if (Label->FocusControl == NULL)
  211. {
  212. Label->FocusControl = Edit;
  213. }
  214. else
  215. {
  216. DebugAssert(Label->FocusControl == Edit);
  217. }
  218. }
  219. AddWinControl(Edit);
  220. }
  221. //---------------------------------------------------------------------------
  222. void __fastcall TCustomDialog::AddEdit(TCustomEdit * Edit, TLabel * Label, bool OneLine)
  223. {
  224. AddEditLikeControl(Edit, Label, OneLine);
  225. TEdit * PublicEdit = reinterpret_cast<TEdit *>(Edit);
  226. if (PublicEdit->OnChange == NULL)
  227. {
  228. PublicEdit->OnChange = Change;
  229. }
  230. }
  231. //---------------------------------------------------------------------------
  232. void __fastcall TCustomDialog::SetUpComboBox(TCustomCombo * Combo, TStrings * Items, bool OneLine)
  233. {
  234. if (Items != NULL)
  235. {
  236. Combo->Items = Items;
  237. }
  238. if (OneLine)
  239. {
  240. int Width = 0;
  241. for (int Index = 0; Index < Combo->Items->Count; Index++)
  242. {
  243. Width = Max(Width, Combo->Canvas->TextWidth(Combo->Items->Strings[Index]));
  244. }
  245. Width += ScaleByTextHeight(Combo, 4 + 16 + 14);
  246. Width = Max(Width, HelpButton->Width);
  247. Combo->Width = Width;
  248. Combo->Left = GetDefaultParent()->ClientWidth - FHorizontalMargin - Width;
  249. }
  250. TComboBox * PublicCombo = reinterpret_cast<TComboBox *>(Combo);
  251. if (PublicCombo->OnChange == NULL)
  252. {
  253. PublicCombo->OnChange = Change;
  254. }
  255. }
  256. //---------------------------------------------------------------------------
  257. void __fastcall TCustomDialog::AddComboBox(TCustomCombo * Combo, TLabel * Label, TStrings * Items, bool OneLine)
  258. {
  259. AddEditLikeControl(Combo, Label, OneLine);
  260. SetUpComboBox(Combo, Items, OneLine);
  261. }
  262. //---------------------------------------------------------------------------
  263. void __fastcall TCustomDialog::AddShortCutComboBox(TComboBox * Combo, TLabel * Label, const TShortCuts & ShortCuts)
  264. {
  265. AddEditLikeControl(Combo, Label, true);
  266. InitializeShortCutCombo(Combo, ShortCuts);
  267. SetUpComboBox(Combo, NULL, true);
  268. }
  269. //---------------------------------------------------------------------------
  270. void __fastcall TCustomDialog::ScaleButtonControl(TButtonControl * Control)
  271. {
  272. // this updates Height property to real value
  273. Control->HandleNeeded();
  274. // buttons do not scale with text on their own
  275. Control->Height = ScaleByTextHeight(Control, Control->Height);
  276. }
  277. //---------------------------------------------------------------------------
  278. void __fastcall TCustomDialog::AddButtonControl(TButtonControl * Control)
  279. {
  280. Control->Parent = GetDefaultParent();
  281. Control->Left = FIndent + ScaleByTextHeight(this, 6);
  282. Control->Top = FPos;
  283. Control->Width = GetMaxControlWidth(Control);
  284. ScaleButtonControl(Control);
  285. AdjustHeight(Control);
  286. AddWinControl(Control);
  287. TCheckBox * PublicControl = reinterpret_cast<TCheckBox *>(Control);
  288. if (PublicControl->OnClick == NULL)
  289. {
  290. PublicControl->OnClick = Change;
  291. }
  292. }
  293. //---------------------------------------------------------------------------
  294. void __fastcall TCustomDialog::AddText(TLabel * Label)
  295. {
  296. Label->Parent = GetDefaultParent();
  297. DebugAssert(Label->AutoSize);
  298. Label->WordWrap = true;
  299. Label->Left = FIndent;
  300. Label->Width = GetMaxControlWidth(Label);
  301. Label->Top = FPos;
  302. Label->ShowAccelChar = false;
  303. TRect TextRect;
  304. SetRect(&TextRect, 0, 0, Label->Width, 0);
  305. DrawText(Label->Canvas->Handle, Label->Caption.c_str(), Label->Caption.Length() + 1, &TextRect,
  306. DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK | DT_NOPREFIX |
  307. Label->DrawTextBiDiModeFlagsReadingOnly());
  308. if (TextRect.Height() > Label->Height)
  309. {
  310. Label->Height = TextRect.Height();
  311. Label->AutoSize = false;
  312. }
  313. else
  314. {
  315. Label->WordWrap = false;
  316. }
  317. AdjustHeight(Label);
  318. }
  319. //---------------------------------------------------------------------------
  320. void __fastcall TCustomDialog::AddText(TStaticText * Label)
  321. {
  322. Label->Parent = GetDefaultParent();
  323. DebugAssert(Label->AutoSize);
  324. Label->Left = FIndent;
  325. Label->Top = FPos;
  326. Label->ShowAccelChar = false;
  327. AdjustHeight(Label);
  328. AddWinControl(Label);
  329. }
  330. //---------------------------------------------------------------------------
  331. void __fastcall TCustomDialog::AddSeparator()
  332. {
  333. TBevel * Bevel = new TBevel(this);
  334. Bevel->Parent = GetDefaultParent();
  335. Bevel->Left = FIndent;
  336. Bevel->Top = FPos;
  337. Bevel->Height = 2;
  338. Bevel->Width = GetMaxControlWidth(Bevel);
  339. AdjustHeight(Bevel);
  340. }
  341. //---------------------------------------------------------------------------
  342. void __fastcall TCustomDialog::StartGroup(const UnicodeString & Caption)
  343. {
  344. if (FGroupBox != NULL)
  345. {
  346. FIndent = FGroupBox->Left;
  347. FPos = FGroupBox->Top + FGroupBox->Height + FControlPadding;
  348. FPrePos = FPos;
  349. FGroupBox = NULL;
  350. }
  351. TGroupBox * GroupBox = new TGroupBox(this);
  352. GroupBox->Parent = this;
  353. GroupBox->Caption = Caption;
  354. GroupBox->Left = FIndent;
  355. GroupBox->Top = FPos;
  356. GroupBox->Height = ScaleByTextHeight(GroupBox, 20);
  357. GroupBox->Width = GetMaxControlWidth(GroupBox);
  358. AdjustHeight(GroupBox);
  359. AddWinControl(GroupBox);
  360. FPos = ScaleByTextHeight(this, 16);
  361. FPrePos = FPos;
  362. FIndent = FHorizontalMargin;
  363. FGroupBox = GroupBox;
  364. }
  365. //---------------------------------------------------------------------------
  366. //---------------------------------------------------------------------------
  367. class TSaveSessionDialog : public TCustomDialog
  368. {
  369. public:
  370. __fastcall TSaveSessionDialog(TComponent* AOwner);
  371. void __fastcall Init(bool CanSavePassword, bool NotRecommendedSavingPassword,
  372. TStrings * AdditionalFolders);
  373. bool __fastcall Execute(UnicodeString & SessionName, bool & SavePassword,
  374. bool & CreateShortcut, const UnicodeString & OriginalSessionName);
  375. protected:
  376. virtual void __fastcall DoValidate();
  377. virtual void __fastcall DoChange(bool & CanSubmit);
  378. private:
  379. UnicodeString FOriginalSessionName;
  380. TEdit * SessionNameEdit;
  381. TComboBox * FolderCombo;
  382. TCheckBox * SavePasswordCheck;
  383. TCheckBox * CreateShortcutCheck;
  384. UnicodeString FRootFolder;
  385. UnicodeString __fastcall GetSessionName();
  386. };
  387. //---------------------------------------------------------------------------
  388. // Need to have an Owner argument for SafeFormCreate
  389. __fastcall TSaveSessionDialog::TSaveSessionDialog(TComponent* /*AOwner*/) :
  390. TCustomDialog(HELP_SESSION_SAVE)
  391. {
  392. }
  393. //---------------------------------------------------------------------------
  394. void __fastcall TSaveSessionDialog::Init(bool CanSavePassword,
  395. bool NotRecommendedSavingPassword, TStrings * AdditionalFolders)
  396. {
  397. Caption = LoadStr(SAVE_SESSION_CAPTION);
  398. SessionNameEdit = new TEdit(this);
  399. AddEdit(SessionNameEdit, CreateLabel(LoadStr(SAVE_SESSION_PROMPT)));
  400. FRootFolder = LoadStr(SAVE_SESSION_ROOT_FOLDER2);
  401. std::unique_ptr<TStringList> Folders(new TStringList());
  402. if (AdditionalFolders != NULL)
  403. {
  404. Folders->AddStrings(AdditionalFolders);
  405. }
  406. for (int Index = 0; Index < StoredSessions->Count; Index++)
  407. {
  408. TSessionData * Data = StoredSessions->Sessions[Index];
  409. if (!Data->Special && !Data->IsWorkspace)
  410. {
  411. UnicodeString Folder = Data->FolderName;
  412. if (!Folder.IsEmpty() && Folders->IndexOf(Folder) < 0)
  413. {
  414. Folders->Add(Folder);
  415. }
  416. }
  417. }
  418. DebugAssert(!Folders->CaseSensitive);
  419. Folders->Sort();
  420. FolderCombo = new TUIStateAwareComboBox(this);
  421. AddComboBox(FolderCombo, CreateLabel(LoadStr(SAVE_SESSION_FOLDER)));
  422. FolderCombo->DropDownCount = Max(FolderCombo->DropDownCount, 16);
  423. FolderCombo->Items->Add(FRootFolder);
  424. FolderCombo->Items->AddStrings(Folders.get());
  425. SavePasswordCheck = CreateAndAddCheckBox(
  426. LoadStr(NotRecommendedSavingPassword ? SAVE_SESSION_PASSWORD :
  427. (CustomWinConfiguration->UseMasterPassword ? SAVE_SESSION_PASSWORD_MASTER : SAVE_SESSION_PASSWORD_RECOMMENDED)));
  428. CreateShortcutCheck = CreateAndAddCheckBox(LoadStr(SAVE_SITE_WORKSPACE_SHORTCUT));
  429. EnableControl(SavePasswordCheck, CanSavePassword);
  430. }
  431. //---------------------------------------------------------------------------
  432. bool __fastcall TSaveSessionDialog::Execute(
  433. UnicodeString & SessionName, bool & SavePassword, bool & CreateShortcut,
  434. const UnicodeString & OriginalSessionName)
  435. {
  436. FOriginalSessionName = OriginalSessionName;
  437. SessionNameEdit->Text = TSessionData::ExtractLocalName(SessionName);
  438. UnicodeString Folder = TSessionData::ExtractFolderName(SessionName);
  439. if (Folder.IsEmpty())
  440. {
  441. FolderCombo->Text = FRootFolder;
  442. }
  443. else
  444. {
  445. FolderCombo->Text = Folder;
  446. }
  447. SavePasswordCheck->Checked = SavePassword;
  448. CreateShortcutCheck->Checked = CreateShortcut;
  449. bool Result = TCustomDialog::Execute();
  450. if (Result)
  451. {
  452. SessionName = GetSessionName();
  453. SavePassword = SavePasswordCheck->Checked;
  454. CreateShortcut = CreateShortcutCheck->Checked;
  455. }
  456. return Result;
  457. }
  458. //---------------------------------------------------------------------------
  459. UnicodeString __fastcall TSaveSessionDialog::GetSessionName()
  460. {
  461. UnicodeString Folder;
  462. if (FolderCombo->Text != FRootFolder)
  463. {
  464. Folder = FolderCombo->Text;
  465. }
  466. return TSessionData::ComposePath(Folder, SessionNameEdit->Text);
  467. }
  468. //---------------------------------------------------------------------------
  469. void __fastcall TSaveSessionDialog::DoValidate()
  470. {
  471. TSessionData::ValidateName(SessionNameEdit->Text);
  472. SessionNameValidate(GetSessionName(), FOriginalSessionName);
  473. UnicodeString Folder = TSessionData::ExtractFolderName(GetSessionName());
  474. if (!Folder.IsEmpty() && StoredSessions->IsWorkspace(Folder))
  475. {
  476. throw Exception(FMTLOAD(WORKSPACE_NOT_FOLDER, (Folder)));
  477. }
  478. if (SavePasswordCheck->Enabled && SavePasswordCheck->Checked &&
  479. CustomWinConfiguration->UseMasterPassword)
  480. {
  481. CustomWinConfiguration->AskForMasterPasswordIfNotSet();
  482. }
  483. TCustomDialog::DoValidate();
  484. }
  485. //---------------------------------------------------------------------------
  486. void __fastcall TSaveSessionDialog::DoChange(bool & CanSubmit)
  487. {
  488. CanSubmit = !SessionNameEdit->Text.IsEmpty();
  489. TCustomDialog::DoChange(CanSubmit);
  490. }
  491. //---------------------------------------------------------------------------
  492. TSessionData * __fastcall DoSaveSession(TSessionData * SessionData,
  493. TSessionData * OriginalSession, bool ForceDialog,
  494. TStrings * AdditionalFolders)
  495. {
  496. bool SavePassword = false;
  497. bool * PSavePassword;
  498. bool NotRecommendedSavingPassword =
  499. !CustomWinConfiguration->UseMasterPassword &&
  500. !SameText(SessionData->UserName, AnonymousUserName);
  501. if (Configuration->DisablePasswordStoring ||
  502. !SessionData->HasAnySessionPassword())
  503. {
  504. PSavePassword = NULL;
  505. }
  506. else
  507. {
  508. PSavePassword = &SavePassword;
  509. SavePassword =
  510. ((OriginalSession != NULL) && OriginalSession->HasAnySessionPassword()) ||
  511. !NotRecommendedSavingPassword;
  512. }
  513. UnicodeString SessionName = SessionData->SessionName;
  514. bool Result;
  515. bool CreateShortcut = false;
  516. if (!ForceDialog && ((PSavePassword == NULL) || SavePassword))
  517. {
  518. // This is probably here to ask before session is started saving.
  519. // Otherwise we would ask implicitly, when saving passwords, but at that moment,
  520. // part of the site is already saved and when the user cancel the prompt it's too late.
  521. CustomWinConfiguration->AskForMasterPasswordIfNotSetAndNeededToPersistSessionData(SessionData);
  522. Result = true;
  523. }
  524. else
  525. {
  526. // This can be a standalone dialog when used with save URL (from GetLoginData)
  527. TSaveSessionDialog * Dialog = SafeFormCreate<TSaveSessionDialog>();
  528. try
  529. {
  530. Dialog->Init((PSavePassword != NULL), NotRecommendedSavingPassword, AdditionalFolders);
  531. Result = Dialog->Execute(SessionName, SavePassword, CreateShortcut, SessionData->Name);
  532. }
  533. __finally
  534. {
  535. delete Dialog;
  536. }
  537. }
  538. TSessionData * NewSession = NULL;
  539. if (Result)
  540. {
  541. if ((PSavePassword != NULL) && !SavePassword)
  542. {
  543. SessionData->ClearSessionPasswords();
  544. }
  545. NewSession =
  546. StoredSessions->NewSession(SessionName, SessionData);
  547. // modified only, explicit
  548. StoredSessions->Save(false, true);
  549. if (!SessionData->HostKey.IsEmpty())
  550. {
  551. SessionData->CacheHostKeyIfNotCached();
  552. }
  553. if (CreateShortcut)
  554. {
  555. TOperationVisualizer Visualizer;
  556. UnicodeString AdditionalParams =
  557. TProgramParams::FormatSwitch(DESKTOP_SWITCH) + L" " +
  558. TProgramParams::FormatSwitch(UPLOAD_IF_ANY_SWITCH);
  559. CreateDesktopSessionShortCut(SessionName, L"", AdditionalParams, -1, SITE_ICON);
  560. }
  561. }
  562. return NewSession;
  563. }
  564. //---------------------------------------------------------------------------
  565. void __fastcall SessionNameValidate(const UnicodeString & Text,
  566. const UnicodeString & OriginalName)
  567. {
  568. TSessionData::ValidatePath(Text);
  569. DebugAssert(StoredSessions);
  570. TSessionData * Data = (TSessionData *)StoredSessions->FindByName(Text);
  571. if (Data && Data->Special)
  572. {
  573. MessageDialog(FMTLOAD(CANNOT_OVERWRITE_SPECIAL_SESSION, (Text)),
  574. qtError, qaOK, HELP_NONE);
  575. Abort();
  576. }
  577. else if ((Data != NULL) && !Data->IsSameName(OriginalName) &&
  578. MessageDialog(MainInstructions(FMTLOAD(CONFIRM_OVERWRITE_SESSION, (Text))),
  579. qtConfirmation, qaYes | qaNo, HELP_SESSION_SAVE_OVERWRITE) != qaYes)
  580. {
  581. Abort();
  582. }
  583. }
  584. //---------------------------------------------------------------------------
  585. //---------------------------------------------------------------------------
  586. class TSaveWorkspaceDialog : public TCustomDialog
  587. {
  588. public:
  589. __fastcall TSaveWorkspaceDialog(bool CanSavePasswords,
  590. bool NotRecommendedSavingPasswords);
  591. bool __fastcall Execute(
  592. UnicodeString & WorkspaceName, bool & SavePasswords, bool & CreateShortcut,
  593. bool & EnableAutoSave);
  594. protected:
  595. virtual void __fastcall DoValidate();
  596. virtual void __fastcall DoChange(bool & CanSubmit);
  597. private:
  598. TComboBox * WorkspaceNameCombo;
  599. TCheckBox * SavePasswordsCheck;
  600. TCheckBox * CreateShortcutCheck;
  601. TCheckBox * EnableAutoSaveCheck;
  602. };
  603. //---------------------------------------------------------------------------
  604. __fastcall TSaveWorkspaceDialog::TSaveWorkspaceDialog(
  605. bool CanSavePasswords, bool NotRecommendedSavingPasswords) :
  606. TCustomDialog(HELP_WORKSPACE_SAVE)
  607. {
  608. Caption = LoadStr(SAVE_WORKSPACE_CAPTION);
  609. WorkspaceNameCombo = new TUIStateAwareComboBox(this);
  610. WorkspaceNameCombo->AutoComplete = false;
  611. AddComboBox(WorkspaceNameCombo, CreateLabel(LoadStr(SAVE_WORKSPACE_PROMPT)));
  612. WorkspaceNameCombo->DropDownCount = Max(WorkspaceNameCombo->DropDownCount, 16);
  613. std::unique_ptr<TStrings> Workspaces(StoredSessions->GetWorkspaces());
  614. WorkspaceNameCombo->Items->AddStrings(Workspaces.get());
  615. SavePasswordsCheck = CreateAndAddCheckBox(
  616. LoadStr(NotRecommendedSavingPasswords ? SAVE_WORKSPACE_PASSWORDS :
  617. (CustomWinConfiguration->UseMasterPassword ?
  618. SAVE_WORKSPACE_PASSWORDS_MASTER : SAVE_WORKSPACE_PASSWORDS_RECOMMENDED)));
  619. EnableControl(SavePasswordsCheck, CanSavePasswords);
  620. CreateShortcutCheck = CreateAndAddCheckBox(LoadStr(SAVE_SITE_WORKSPACE_SHORTCUT));
  621. EnableAutoSaveCheck = CreateAndAddCheckBox(LoadStr(SAVE_WORKSPACE_AUTO));
  622. }
  623. //---------------------------------------------------------------------------
  624. bool __fastcall TSaveWorkspaceDialog::Execute(
  625. UnicodeString & WorkspaceName, bool & SavePasswords, bool & CreateShortcut,
  626. bool & EnableAutoSave)
  627. {
  628. WorkspaceNameCombo->Text = WorkspaceName;
  629. SavePasswordsCheck->Checked = SavePasswords;
  630. CreateShortcutCheck->Checked = CreateShortcut;
  631. EnableAutoSaveCheck->Checked = EnableAutoSave;
  632. bool Result = TCustomDialog::Execute();
  633. if (Result)
  634. {
  635. WorkspaceName = WorkspaceNameCombo->Text;
  636. SavePasswords = SavePasswordsCheck->Checked;
  637. CreateShortcut = CreateShortcutCheck->Checked;
  638. EnableAutoSave = EnableAutoSaveCheck->Checked;
  639. }
  640. return Result;
  641. }
  642. //---------------------------------------------------------------------------
  643. void __fastcall TSaveWorkspaceDialog::DoValidate()
  644. {
  645. TSessionData::ValidateName(WorkspaceNameCombo->Text);
  646. if (StoredSessions->IsFolder(WorkspaceNameCombo->Text))
  647. {
  648. throw Exception(FMTLOAD(FOLDER_NOT_WORKSPACE, (WorkspaceNameCombo->Text)));
  649. }
  650. if (SavePasswordsCheck->Enabled && SavePasswordsCheck->Checked &&
  651. CustomWinConfiguration->UseMasterPassword)
  652. {
  653. CustomWinConfiguration->AskForMasterPasswordIfNotSet();
  654. }
  655. TCustomDialog::DoValidate();
  656. }
  657. //---------------------------------------------------------------------------
  658. void __fastcall TSaveWorkspaceDialog::DoChange(bool & CanSubmit)
  659. {
  660. CanSubmit = !WorkspaceNameCombo->Text.IsEmpty();
  661. TCustomDialog::DoChange(CanSubmit);
  662. }
  663. //---------------------------------------------------------------------------
  664. bool __fastcall DoSaveWorkspaceDialog(UnicodeString & WorkspaceName,
  665. bool * SavePasswords, bool NotRecommendedSavingPasswords,
  666. bool & CreateShortcut, bool & EnableAutoSave)
  667. {
  668. std::unique_ptr<TSaveWorkspaceDialog> Dialog(
  669. new TSaveWorkspaceDialog((SavePasswords != NULL), NotRecommendedSavingPasswords));
  670. bool Dummy = false;
  671. if (SavePasswords == NULL)
  672. {
  673. SavePasswords = &Dummy;
  674. }
  675. return
  676. Dialog->Execute(
  677. WorkspaceName, *SavePasswords, CreateShortcut, EnableAutoSave);
  678. }
  679. //---------------------------------------------------------------------------
  680. //---------------------------------------------------------------------------
  681. class TShortCutDialog : public TCustomDialog
  682. {
  683. public:
  684. __fastcall TShortCutDialog(const TShortCuts & ShortCuts, UnicodeString HelpKeyword);
  685. bool __fastcall Execute(TShortCut & ShortCut);
  686. private:
  687. TComboBox * ShortCutCombo;
  688. };
  689. //---------------------------------------------------------------------------
  690. __fastcall TShortCutDialog::TShortCutDialog(const TShortCuts & ShortCuts, UnicodeString HelpKeyword) :
  691. TCustomDialog(HelpKeyword)
  692. {
  693. Caption = LoadStr(SHORTCUT_CAPTION);
  694. ShortCutCombo = new TUIStateAwareComboBox(this);
  695. AddShortCutComboBox(ShortCutCombo, CreateLabel(LoadStr(SHORTCUT_LABEL)), ShortCuts);
  696. }
  697. //---------------------------------------------------------------------------
  698. bool __fastcall TShortCutDialog::Execute(TShortCut & ShortCut)
  699. {
  700. SetShortCutCombo(ShortCutCombo, ShortCut);
  701. bool Result = TCustomDialog::Execute();
  702. if (Result)
  703. {
  704. ShortCut = GetShortCutCombo(ShortCutCombo);
  705. }
  706. return Result;
  707. }
  708. //---------------------------------------------------------------------------
  709. bool __fastcall DoShortCutDialog(TShortCut & ShortCut,
  710. const TShortCuts & ShortCuts, UnicodeString HelpKeyword)
  711. {
  712. bool Result;
  713. TShortCutDialog * Dialog = new TShortCutDialog(ShortCuts, HelpKeyword);
  714. try
  715. {
  716. Result = Dialog->Execute(ShortCut);
  717. }
  718. __finally
  719. {
  720. delete Dialog;
  721. }
  722. return Result;
  723. }
  724. //---------------------------------------------------------------------------
  725. //---------------------------------------------------------------------------
  726. class TRemoteMoveDialog : public TCustomDialog
  727. {
  728. public:
  729. __fastcall TRemoteMoveDialog(bool Multi, TDirectoryExistsEvent OnDirectoryExists);
  730. bool __fastcall Execute(UnicodeString & Target, UnicodeString & FileMask);
  731. protected:
  732. DYNAMIC void __fastcall DoShow();
  733. virtual void __fastcall DoValidate();
  734. UnicodeString __fastcall GetFileMask();
  735. private:
  736. THistoryComboBox * Combo;
  737. bool FMulti;
  738. TDirectoryExistsEvent FOnDirectoryExists;
  739. };
  740. //---------------------------------------------------------------------------
  741. __fastcall TRemoteMoveDialog::TRemoteMoveDialog(bool Multi, TDirectoryExistsEvent OnDirectoryExists) :
  742. TCustomDialog(HELP_REMOTE_MOVE)
  743. {
  744. Caption = LoadStr(REMOTE_MOVE_TITLE);
  745. // The same as TRemoteTransferDialog
  746. ClientWidth = ScaleByTextHeight(this, 420);
  747. FMulti = Multi;
  748. FOnDirectoryExists = OnDirectoryExists;
  749. AddImage(L"Move L to R");
  750. Combo = new THistoryComboBox(this);
  751. Combo->AutoComplete = false;
  752. AddComboBox(Combo, CreateLabel(LoadStr(REMOTE_TRANSFER_PROMPT2)));
  753. }
  754. //---------------------------------------------------------------------------
  755. bool __fastcall TRemoteMoveDialog::Execute(UnicodeString & Target, UnicodeString & FileMask)
  756. {
  757. Combo->Items = CustomWinConfiguration->History[L"RemoteTarget"];
  758. Combo->Text = UnixIncludeTrailingBackslash(Target) + FileMask;
  759. bool Result = TCustomDialog::Execute();
  760. if (Result)
  761. {
  762. Target = UnixExtractFilePath(Combo->Text);
  763. FileMask = GetFileMask();
  764. Combo->SaveToHistory();
  765. CustomWinConfiguration->History[L"RemoteTarget"] = Combo->Items;
  766. }
  767. return Result;
  768. }
  769. //---------------------------------------------------------------------------
  770. UnicodeString __fastcall TRemoteMoveDialog::GetFileMask()
  771. {
  772. return UnixExtractFileName(Combo->Text);
  773. }
  774. //---------------------------------------------------------------------------
  775. void __fastcall TRemoteMoveDialog::DoShow()
  776. {
  777. TCustomDialog::DoShow();
  778. InstallPathWordBreakProc(Combo);
  779. }
  780. //---------------------------------------------------------------------------
  781. void __fastcall TRemoteMoveDialog::DoValidate()
  782. {
  783. if (FOnDirectoryExists(NULL, Combo->Text))
  784. {
  785. Combo->Text = UnixCombinePaths(Combo->Text, AnyMask);
  786. }
  787. if (!IsFileNameMask(GetFileMask()) && FMulti)
  788. {
  789. UnicodeString Message =
  790. FormatMultiFilesToOneConfirmation(Combo->Text, true);
  791. if (MessageDialog(Message, qtConfirmation, qaOK | qaCancel, HELP_NONE) == qaCancel)
  792. {
  793. Abort();
  794. }
  795. }
  796. TCustomDialog::DoValidate();
  797. }
  798. //---------------------------------------------------------------------------
  799. bool __fastcall DoRemoteMoveDialog(
  800. bool Multi, UnicodeString & Target, UnicodeString & FileMask, TDirectoryExistsEvent OnDirectoryExists)
  801. {
  802. std::unique_ptr<TRemoteMoveDialog> Dialog(new TRemoteMoveDialog(Multi, OnDirectoryExists));
  803. return Dialog->Execute(Target, FileMask);
  804. }
  805. //---------------------------------------------------------------------------
  806. //---------------------------------------------------------------------------
  807. class TCustomCommandOptionsDialog : public TCustomDialog
  808. {
  809. public:
  810. __fastcall TCustomCommandOptionsDialog(
  811. const TCustomCommandType * Command, TStrings * CustomCommandOptions, unsigned int Flags,
  812. TCustomCommand * CustomCommandForOptions, const UnicodeString & Site, const TShortCuts * ShortCuts);
  813. bool __fastcall Execute(TShortCut * ShortCut);
  814. protected:
  815. virtual void __fastcall DoHelp();
  816. DYNAMIC void __fastcall DoShow();
  817. private:
  818. const TCustomCommandType * FCommand;
  819. TStrings * FCustomCommandOptions;
  820. std::vector<TControl *> FControls;
  821. std::vector<std::vector<UnicodeString> > FValues;
  822. unsigned int FFlags;
  823. UnicodeString FSite;
  824. TComboBox * FShortCutCombo;
  825. UnicodeString __fastcall HistoryKey(const TCustomCommandType::TOption & Option);
  826. THistoryComboBox * __fastcall CreateHistoryComboBox(const TCustomCommandType::TOption & Option, const UnicodeString & Value);
  827. void __fastcall BrowseButtonClick(TObject * Sender);
  828. void __fastcall LinkLabelClick(TObject * Sender);
  829. UnicodeString __fastcall SaveHistoryComboBoxValue(TControl * Control, const TCustomCommandType::TOption & Option);
  830. void __fastcall AddOptionComboBox(
  831. TComboBox * ComboBox, const UnicodeString & Value, const TCustomCommandType::TOption & Option,
  832. std::vector<UnicodeString> & Values);
  833. UnicodeString __fastcall GetComboBoxValue(TControl * Control, const UnicodeString & Default);
  834. int __fastcall GetOptionIndex(TControl * Control);
  835. int __fastcall GetControlIndex(TControl * Control);
  836. };
  837. //---------------------------------------------------------------------------
  838. __fastcall TCustomCommandOptionsDialog::TCustomCommandOptionsDialog(
  839. const TCustomCommandType * Command, TStrings * CustomCommandOptions,
  840. unsigned int Flags, TCustomCommand * CustomCommandForOptions,
  841. const UnicodeString & Site, const TShortCuts * ShortCuts) :
  842. TCustomDialog(HELP_EXTENSION_OPTIONS)
  843. {
  844. FCommand = Command;
  845. FFlags = Flags;
  846. FCustomCommandOptions = CustomCommandOptions;
  847. FSite = Site;
  848. Caption = StripEllipsis(StripHotkey(FCommand->Name));
  849. Width = ScaleByTextHeight(this, 400);
  850. bool HasGroups = false;
  851. int ControlIndex = 0;
  852. for (int OptionIndex = 0; OptionIndex < FCommand->OptionsCount; OptionIndex++)
  853. {
  854. const TCustomCommandType::TOption & Option = FCommand->GetOption(OptionIndex);
  855. if ((Option.Flags & FFlags) != 0)
  856. {
  857. UnicodeString OptionKey = FCommand->GetOptionKey(Option, FSite);
  858. UnicodeString Value;
  859. if ((CustomCommandForOptions != NULL) &&
  860. Option.HasPatterns(CustomCommandForOptions))
  861. {
  862. Value = CustomCommandForOptions->Complete(Option.Default, true);
  863. }
  864. else
  865. {
  866. if (FCustomCommandOptions->IndexOfName(OptionKey) >= 0)
  867. {
  868. Value = FCustomCommandOptions->Values[OptionKey];
  869. }
  870. else
  871. {
  872. Value = Option.Default;
  873. }
  874. }
  875. int Tag = (OptionIndex << 16) + ControlIndex;
  876. TControl * Control = NULL;
  877. std::vector<UnicodeString> Values;
  878. if (Option.Kind == TCustomCommandType::okUnknown)
  879. {
  880. Control = NULL;
  881. }
  882. else if (Option.Kind == TCustomCommandType::okLabel)
  883. {
  884. TLabel * Label = CreateLabel(Option.Caption);
  885. AddText(Label);
  886. Control = Label;
  887. }
  888. else if (Option.Kind == TCustomCommandType::okLink)
  889. {
  890. TStaticText * Label = new TStaticText(this);
  891. Label->Caption = Option.Caption;
  892. if (IsHttpOrHttpsUrl(Label->Caption))
  893. {
  894. Label->Caption = SecureUrl(Label->Caption);
  895. LinkLabel(Label);
  896. Label->TabStop = true;
  897. }
  898. else if (!Option.Default.IsEmpty() && IsHttpOrHttpsUrl(Option.Default))
  899. {
  900. Label->OnClick = LinkLabelClick;
  901. LinkLabel(Label);
  902. Label->TabStop = true;
  903. }
  904. else
  905. {
  906. // keep it plain text, as we have no URL
  907. }
  908. AddText(Label);
  909. Control = Label;
  910. }
  911. else if (Option.Kind == TCustomCommandType::okGroup)
  912. {
  913. StartGroup(Option.Caption);
  914. HasGroups = true;
  915. }
  916. else if (Option.Kind == TCustomCommandType::okSeparator)
  917. {
  918. AddSeparator();
  919. }
  920. else if (Option.Kind == TCustomCommandType::okTextBox)
  921. {
  922. Control = CreateHistoryComboBox(Option, Value);
  923. }
  924. else if (Option.Kind == TCustomCommandType::okFile)
  925. {
  926. THistoryComboBox * ComboBox = CreateHistoryComboBox(Option, Value);
  927. TButton * Button = new TButton(this);
  928. Button->Parent = GetDefaultParent();
  929. Button->Width = HelpButton->Width;
  930. Button->Left = GetDefaultParent()->ClientWidth - Button->Width - HorizontalMargin;
  931. ComboBox->Width = Button->Left - ComboBox->Left - ScaleByTextHeight(this, 6);
  932. Button->Top = ComboBox->Top - ScaleByTextHeight(this, 2);
  933. Button->Tag = Tag;
  934. Button->Caption = LoadStr(EXTENSION_OPTIONS_BROWSE);
  935. Button->OnClick = BrowseButtonClick;
  936. ScaleButtonControl(Button);
  937. AddWinControl(Button);
  938. Control = ComboBox;
  939. }
  940. else if (Option.Kind == TCustomCommandType::okDropDownList)
  941. {
  942. TComboBox * ComboBox = new TUIStateAwareComboBox(this);
  943. ComboBox->Style = csDropDownList;
  944. AddOptionComboBox(ComboBox, Value, Option, Values);
  945. Control = ComboBox;
  946. }
  947. else if (Option.Kind == TCustomCommandType::okComboBox)
  948. {
  949. TComboBox * ComboBox = new TUIStateAwareComboBox(this);
  950. ComboBox->Style = csDropDown;
  951. AddOptionComboBox(ComboBox, Value, Option, Values);
  952. if (ComboBox->ItemIndex < 0)
  953. {
  954. ComboBox->Text = Value;
  955. }
  956. Control = ComboBox;
  957. }
  958. else if (Option.Kind == TCustomCommandType::okCheckBox)
  959. {
  960. TCheckBox * CheckBox = CreateAndAddCheckBox(Option.Caption);
  961. CheckBox->Checked =
  962. (Option.Params.size() >= 1) &&
  963. (Value == Option.Params[0]);
  964. Control = CheckBox;
  965. }
  966. else
  967. {
  968. DebugFail();
  969. }
  970. if (Control != NULL)
  971. {
  972. Control->Tag = Tag;
  973. }
  974. FControls.push_back(Control);
  975. FValues.push_back(Values);
  976. ControlIndex++;
  977. DebugAssert(static_cast<int>(FControls.size()) == ControlIndex);
  978. }
  979. }
  980. if (ShortCuts != NULL)
  981. {
  982. if (HasGroups)
  983. {
  984. StartGroup(LoadStr(EXTENSION_GENERAL_GROUP));
  985. }
  986. else if (ControlIndex > 0)
  987. {
  988. AddSeparator();
  989. }
  990. FShortCutCombo = new TUIStateAwareComboBox(this);
  991. AddShortCutComboBox(FShortCutCombo, CreateLabel(LoadStr(EXTENSION_SHORTCUT)), *ShortCuts);
  992. }
  993. }
  994. //---------------------------------------------------------------------------
  995. void __fastcall TCustomCommandOptionsDialog::AddOptionComboBox(
  996. TComboBox * ComboBox, const UnicodeString & Value, const TCustomCommandType::TOption & Option, std::vector<UnicodeString> & Values)
  997. {
  998. std::unique_ptr<TStringList> Items(new TStringList());
  999. int ItemIndex = -1;
  1000. TCustomCommandType::TOption::TParams::const_iterator ParamI = Option.Params.begin();
  1001. while (ParamI != Option.Params.end())
  1002. {
  1003. UnicodeString Item = (*ParamI);
  1004. int P = Item.Pos(L"=");
  1005. UnicodeString ParamValue;
  1006. if (P > 0)
  1007. {
  1008. ParamValue = Item.SubString(1, P - 1);
  1009. Item.Delete(1, P);
  1010. }
  1011. else
  1012. {
  1013. ParamValue = Item;
  1014. }
  1015. Item = WinConfiguration->ExtensionStringTranslation(FCommand->Id, Item);
  1016. Items->Add(Item);
  1017. if (Value == ParamValue)
  1018. {
  1019. ItemIndex = Items->Count - 1;
  1020. }
  1021. Values.push_back(ParamValue);
  1022. ParamI++;
  1023. }
  1024. AddComboBox(ComboBox, CreateLabel(Option.Caption), Items.get(), true);
  1025. ComboBox->ItemIndex = ItemIndex;
  1026. }
  1027. //---------------------------------------------------------------------------
  1028. int __fastcall TCustomCommandOptionsDialog::GetOptionIndex(TControl * Control)
  1029. {
  1030. return (Control->Tag >> 16);
  1031. }
  1032. //---------------------------------------------------------------------------
  1033. int __fastcall TCustomCommandOptionsDialog::GetControlIndex(TControl * Control)
  1034. {
  1035. return (Control->Tag & 0xFFFF);
  1036. }
  1037. //---------------------------------------------------------------------------
  1038. void __fastcall TCustomCommandOptionsDialog::LinkLabelClick(TObject * Sender)
  1039. {
  1040. TStaticText * Label = DebugNotNull(dynamic_cast<TStaticText *>(Sender));
  1041. const TCustomCommandType::TOption & Option = FCommand->GetOption(GetOptionIndex(Label));
  1042. OpenBrowser(SecureUrl(Option.Default));
  1043. }
  1044. //---------------------------------------------------------------------------
  1045. void __fastcall TCustomCommandOptionsDialog::BrowseButtonClick(TObject * Sender)
  1046. {
  1047. TButton * Button = DebugNotNull(dynamic_cast<TButton *>(Sender));
  1048. int OptionIndex = GetOptionIndex(Button);
  1049. const TCustomCommandType::TOption & Option = FCommand->GetOption(OptionIndex);
  1050. int ControlIndex = GetControlIndex(Button);
  1051. THistoryComboBox * ComboBox = dynamic_cast<THistoryComboBox *>(FControls[ControlIndex]);
  1052. std::unique_ptr<TOpenDialog> OpenDialog(new TOpenDialog(Application));
  1053. UnicodeString Title;
  1054. if (!Option.FileCaption.IsEmpty())
  1055. {
  1056. Title = Option.FileCaption;
  1057. }
  1058. else
  1059. {
  1060. UnicodeString Caption = Option.Caption;
  1061. Caption = StripHotkey(Caption);
  1062. if (!Caption.IsEmpty() && (Caption[Caption.Length()] == L':'))
  1063. {
  1064. Caption.SetLength(Caption.Length() - 1);
  1065. }
  1066. Title = FMTLOAD(EXTENSION_OPTIONS_BROWSE_TITLE, (Caption));
  1067. }
  1068. OpenDialog->Title = Title;
  1069. UnicodeString Value;
  1070. if (ComboBox->Text.IsEmpty())
  1071. {
  1072. Value = Option.FileInitial;
  1073. }
  1074. else
  1075. {
  1076. Value = ComboBox->Text;
  1077. }
  1078. UnicodeString ExpandedValue = ExpandEnvironmentVariables(Value);
  1079. OpenDialog->FileName = ExpandedValue;
  1080. UnicodeString InitialDir = ExtractFilePath(ExpandedValue);
  1081. if (!InitialDir.IsEmpty())
  1082. {
  1083. OpenDialog->InitialDir = InitialDir;
  1084. }
  1085. OpenDialog->Filter = Option.FileFilter;
  1086. OpenDialog->DefaultExt = Option.FileExt;
  1087. if (OpenDialog->Execute())
  1088. {
  1089. if (OpenDialog->FileName != ExpandedValue)
  1090. {
  1091. ComboBox->Text = OpenDialog->FileName;
  1092. }
  1093. // If user just confirms the initial value, persist it
  1094. else if (ComboBox->Text.IsEmpty())
  1095. {
  1096. DebugAssert(Option.FileInitial == Value);
  1097. ComboBox->Text = Value;
  1098. }
  1099. }
  1100. }
  1101. //---------------------------------------------------------------------------
  1102. THistoryComboBox * __fastcall TCustomCommandOptionsDialog::CreateHistoryComboBox(
  1103. const TCustomCommandType::TOption & Option, const UnicodeString & Value)
  1104. {
  1105. THistoryComboBox * ComboBox = new THistoryComboBox(this);
  1106. ComboBox->AutoComplete = false;
  1107. AddComboBox(ComboBox, CreateLabel(Option.Caption));
  1108. ComboBox->Items = CustomWinConfiguration->History[HistoryKey(Option)];
  1109. ComboBox->Text = Value;
  1110. return ComboBox;
  1111. }
  1112. //---------------------------------------------------------------------------
  1113. UnicodeString __fastcall TCustomCommandOptionsDialog::HistoryKey(const TCustomCommandType::TOption & Option)
  1114. {
  1115. UnicodeString Result = FCommand->GetOptionKey(Option, FSite);
  1116. Result = CustomWinConfiguration->GetValidHistoryKey(Result);
  1117. return L"CustomCommandOption_" + Result;
  1118. }
  1119. //---------------------------------------------------------------------------
  1120. bool __fastcall TCustomCommandOptionsDialog::Execute(TShortCut * ShortCut)
  1121. {
  1122. if (ShortCut != NULL)
  1123. {
  1124. SetShortCutCombo(FShortCutCombo, *ShortCut);
  1125. }
  1126. bool Result = TCustomDialog::Execute();
  1127. if (Result)
  1128. {
  1129. int ControlIndex = 0;
  1130. for (int OptionIndex = 0; OptionIndex < FCommand->OptionsCount; OptionIndex++)
  1131. {
  1132. const TCustomCommandType::TOption & Option = FCommand->GetOption(OptionIndex);
  1133. if ((Option.Flags & FFlags) != 0)
  1134. {
  1135. if ((Option.Kind != TCustomCommandType::okUnknown) &&
  1136. Option.IsControl)
  1137. {
  1138. UnicodeString OptionKey = FCommand->GetOptionKey(Option, FSite);
  1139. TControl * Control = FControls[ControlIndex];
  1140. UnicodeString Value;
  1141. if (Option.Kind == TCustomCommandType::okTextBox)
  1142. {
  1143. Value = SaveHistoryComboBoxValue(Control, Option);
  1144. }
  1145. else if (Option.Kind == TCustomCommandType::okFile)
  1146. {
  1147. Value = SaveHistoryComboBoxValue(Control, Option);
  1148. }
  1149. else if (Option.Kind == TCustomCommandType::okDropDownList)
  1150. {
  1151. Value = GetComboBoxValue(Control, Option.Default);
  1152. }
  1153. else if (Option.Kind == TCustomCommandType::okComboBox)
  1154. {
  1155. TComboBox * ComboBox = DebugNotNull(dynamic_cast<TComboBox *>(Control));
  1156. Value = GetComboBoxValue(Control, ComboBox->Text);
  1157. }
  1158. else if (Option.Kind == TCustomCommandType::okCheckBox)
  1159. {
  1160. TCheckBox * CheckBox = DebugNotNull(dynamic_cast<TCheckBox *>(Control));
  1161. int Index = (CheckBox->Checked ? 0 : 1);
  1162. Value = (Index < static_cast<int>(Option.Params.size())) ? Option.Params[Index] : UnicodeString();
  1163. }
  1164. else
  1165. {
  1166. DebugFail();
  1167. }
  1168. // The default value setter deletes the "name" when the value is empty.
  1169. // It would cause us to fall back to the default value, but we want to remember the empty value.
  1170. SetStringValueEvenIfEmpty(FCustomCommandOptions, OptionKey, Value);
  1171. }
  1172. ControlIndex++;
  1173. }
  1174. }
  1175. if (ShortCut != NULL)
  1176. {
  1177. *ShortCut = GetShortCutCombo(FShortCutCombo);
  1178. }
  1179. }
  1180. return Result;
  1181. }
  1182. //---------------------------------------------------------------------------
  1183. UnicodeString __fastcall TCustomCommandOptionsDialog::GetComboBoxValue(
  1184. TControl * Control, const UnicodeString & Default)
  1185. {
  1186. TComboBox * ComboBox = DebugNotNull(dynamic_cast<TComboBox *>(Control));
  1187. UnicodeString Result;
  1188. if (ComboBox->ItemIndex < 0)
  1189. {
  1190. Result = Default;
  1191. }
  1192. else
  1193. {
  1194. Result = FValues[GetControlIndex(Control)][ComboBox->ItemIndex];
  1195. }
  1196. return Result;
  1197. }
  1198. //---------------------------------------------------------------------------
  1199. UnicodeString __fastcall TCustomCommandOptionsDialog::SaveHistoryComboBoxValue(
  1200. TControl * Control, const TCustomCommandType::TOption & Option)
  1201. {
  1202. THistoryComboBox * ComboBox = DebugNotNull(dynamic_cast<THistoryComboBox *>(Control));
  1203. ComboBox->SaveToHistory();
  1204. CustomWinConfiguration->History[HistoryKey(Option)] = ComboBox->Items;
  1205. return ComboBox->Text;
  1206. }
  1207. //---------------------------------------------------------------------------
  1208. void __fastcall TCustomCommandOptionsDialog::DoHelp()
  1209. {
  1210. UnicodeString HelpPage;
  1211. if (!FCommand->OptionsPage.IsEmpty())
  1212. {
  1213. HelpPage = FCommand->OptionsPage;
  1214. }
  1215. else
  1216. {
  1217. HelpPage = FCommand->HomePage;
  1218. }
  1219. if (!HelpPage.IsEmpty())
  1220. {
  1221. OpenBrowser(HelpPage);
  1222. }
  1223. else
  1224. {
  1225. TCustomDialog::DoHelp();
  1226. }
  1227. }
  1228. //---------------------------------------------------------------------------
  1229. void __fastcall TCustomCommandOptionsDialog::DoShow()
  1230. {
  1231. TCustomDialog::DoShow();
  1232. int ControlIndex = 0;
  1233. for (int OptionIndex = 0; OptionIndex < FCommand->OptionsCount; OptionIndex++)
  1234. {
  1235. const TCustomCommandType::TOption & Option = FCommand->GetOption(OptionIndex);
  1236. if ((Option.Flags & FFlags) != 0)
  1237. {
  1238. if (Option.Kind == TCustomCommandType::okFile)
  1239. {
  1240. TControl * Control = FControls[ControlIndex];
  1241. InstallPathWordBreakProc(DebugNotNull(dynamic_cast<TWinControl *>(Control)));
  1242. }
  1243. ControlIndex++;
  1244. }
  1245. }
  1246. }
  1247. //---------------------------------------------------------------------------
  1248. bool __fastcall DoCustomCommandOptionsDialog(
  1249. const TCustomCommandType * Command, TStrings * CustomCommandOptions, TShortCut * ShortCut,
  1250. unsigned int Flags, TCustomCommand * CustomCommandForOptions,
  1251. const UnicodeString & Site, const TShortCuts * ShortCuts)
  1252. {
  1253. std::unique_ptr<TCustomCommandOptionsDialog> Dialog(
  1254. new TCustomCommandOptionsDialog(Command, CustomCommandOptions, Flags, CustomCommandForOptions, Site, ShortCuts));
  1255. return Dialog->Execute(ShortCut);
  1256. }
  1257. //---------------------------------------------------------------------------
  1258. //---------------------------------------------------------------------------
  1259. class TUsageStatisticsDialog : public TCustomDialog
  1260. {
  1261. public:
  1262. __fastcall TUsageStatisticsDialog();
  1263. protected:
  1264. virtual void __fastcall DoChange(bool & CanSubmit);
  1265. private:
  1266. TEdit * FilterEdit;
  1267. TMemo * UsageMemo;
  1268. TButton * ClipboardButton;
  1269. void __fastcall ClipboardButtonClick(TObject * Sender);
  1270. };
  1271. //---------------------------------------------------------------------------
  1272. __fastcall TUsageStatisticsDialog::TUsageStatisticsDialog() :
  1273. TCustomDialog(HELP_USAGE)
  1274. {
  1275. Caption = LoadStr(USAGE_CAPTION);
  1276. Width = ScaleByTextHeight(this, 400);
  1277. // UnformatMessage is called, because previously, ** markup was used and translations may still contain that
  1278. AddText(CreateLabel(UnformatMessage(LoadStr(USAGE_DATA2))));
  1279. FilterEdit = new TEdit(this);
  1280. FilterEdit->Width = ScaleByTextHeight(this, 250);
  1281. AddEdit(FilterEdit, CreateLabel(LoadStr(USAGE_FILTER)), true);
  1282. UsageMemo = new TMemo(this);
  1283. UsageMemo->Height = ScaleByTextHeight(this, 300);
  1284. UsageMemo->ScrollBars = ssVertical;
  1285. AddEdit(UsageMemo, NULL);
  1286. ReadOnlyControl(UsageMemo);
  1287. ClipboardButton = new TButton(this);
  1288. ClipboardButton->Caption = LoadStr(USAGE_COPY);
  1289. ClipboardButton->Width = ScaleByTextHeight(this, 161);
  1290. ClipboardButton->OnClick = ClipboardButtonClick;
  1291. AddDialogButton(ClipboardButton);
  1292. RemoveCancelButton();
  1293. }
  1294. //---------------------------------------------------------------------------
  1295. void __fastcall TUsageStatisticsDialog::ClipboardButtonClick(TObject * /*Sender*/)
  1296. {
  1297. TInstantOperationVisualizer Visualizer;
  1298. CopyToClipboard(UsageMemo->Lines);
  1299. }
  1300. //---------------------------------------------------------------------------
  1301. void __fastcall TUsageStatisticsDialog::DoChange(bool & CanSubmit)
  1302. {
  1303. TCustomDialog::DoChange(CanSubmit);
  1304. UnicodeString Text = Configuration->Usage->Serialize(L"\n", FilterEdit->Text);
  1305. bool NoUsage = Text.IsEmpty();
  1306. ClipboardButton->Enabled = !NoUsage;
  1307. if (NoUsage)
  1308. {
  1309. Text = LoadStr(USAGE_DATA_NONE2);
  1310. }
  1311. UsageMemo->Lines->Text = Text;
  1312. }
  1313. //---------------------------------------------------------------------------
  1314. void __fastcall DoUsageStatisticsDialog()
  1315. {
  1316. std::unique_ptr<TUsageStatisticsDialog> Dialog(new TUsageStatisticsDialog());
  1317. Dialog->Execute();
  1318. }
  1319. //---------------------------------------------------------------------------
  1320. //---------------------------------------------------------------------------
  1321. class TSiteRawDialog : public TCustomDialog
  1322. {
  1323. public:
  1324. __fastcall TSiteRawDialog();
  1325. bool __fastcall Execute(TSessionData * Data);
  1326. protected:
  1327. DYNAMIC void __fastcall DoShow();
  1328. private:
  1329. TMemo * SettingsMemo;
  1330. void __fastcall AddButtonClick(TObject * Sender);
  1331. void __fastcall SettingsMemoKeyDown(TObject * Sender, WORD & Key, TShiftState Shift);
  1332. void DeleteNames(TStrings * Names, TStrings * Options);
  1333. };
  1334. //---------------------------------------------------------------------------
  1335. __fastcall TSiteRawDialog::TSiteRawDialog() :
  1336. TCustomDialog(HELP_SITE_RAW)
  1337. {
  1338. Caption = LoadStr(SITE_RAW_CAPTION);
  1339. Width = ScaleByTextHeight(this, 400);
  1340. SettingsMemo = new TMemo(this);
  1341. SettingsMemo->Height = ScaleByTextHeight(this, 300);
  1342. SettingsMemo->OnKeyDown = SettingsMemoKeyDown;
  1343. AddEdit(SettingsMemo, NULL);
  1344. TButton * AddButton = new TButton(this);
  1345. AddButton->Caption = LoadStr(SITE_RAW_ADD);
  1346. AddButton->Width = OKButton->Width;
  1347. AddButton->OnClick = AddButtonClick;
  1348. AddDialogButton(AddButton);
  1349. }
  1350. //---------------------------------------------------------------------------
  1351. void __fastcall TSiteRawDialog::DoShow()
  1352. {
  1353. TCustomDialog::DoShow();
  1354. InstallPathWordBreakProc(SettingsMemo);
  1355. }
  1356. //---------------------------------------------------------------------------
  1357. bool __fastcall TSiteRawDialog::Execute(TSessionData * Data)
  1358. {
  1359. std::unique_ptr<TSessionData> FactoryDefaults(new TSessionData(L""));
  1360. std::unique_ptr<TSessionData> RawData(new TSessionData(L""));
  1361. RawData->Assign(Data);
  1362. // SFTP-only is not reflected by the protocol prefix, we have to use rawsettings for that
  1363. if (RawData->FSProtocol != fsSFTPonly)
  1364. {
  1365. RawData->FSProtocol = FactoryDefaults->FSProtocol;
  1366. }
  1367. RawData->HostName = FactoryDefaults->HostName;
  1368. RawData->PortNumber = FactoryDefaults->PortNumber;
  1369. RawData->UserName = FactoryDefaults->UserName;
  1370. RawData->Password = FactoryDefaults->Password;
  1371. RawData->Ftps = FactoryDefaults->Ftps;
  1372. std::unique_ptr<TStrings> Options(RawData->SaveToOptions(FactoryDefaults.get(), false, false));
  1373. SettingsMemo->Lines = Options.get();
  1374. bool Result = TCustomDialog::Execute();
  1375. if (Result)
  1376. {
  1377. std::unique_ptr<TSessionData> BackupData(new TSessionData(L""));
  1378. BackupData->Assign(Data);
  1379. Data->DefaultSettings();
  1380. Data->FSProtocol = BackupData->FSProtocol;
  1381. Data->HostName = BackupData->HostName;
  1382. Data->PortNumber = BackupData->PortNumber;
  1383. Data->UserName = BackupData->UserName;
  1384. Data->Password = BackupData->Password;
  1385. Data->Ftps = BackupData->Ftps;
  1386. Data->ApplyRawSettings(SettingsMemo->Lines, false);
  1387. }
  1388. return Result;
  1389. }
  1390. //---------------------------------------------------------------------------
  1391. void __fastcall TSiteRawDialog::SettingsMemoKeyDown(TObject * Sender, WORD & Key, TShiftState Shift)
  1392. {
  1393. MemoKeyDown(Sender, Key, Shift);
  1394. }
  1395. //---------------------------------------------------------------------------
  1396. void __fastcall TSiteRawDialog::AddButtonClick(TObject *)
  1397. {
  1398. std::unique_ptr<TSessionData> FactoryDefaults(new TSessionData(L""));
  1399. std::unique_ptr<TSessionData> BasicData(new TSessionData(L""));
  1400. BasicData->FSProtocol = TFSProtocol(FactoryDefaults->FSProtocol + 1);
  1401. UnicodeString RandomAppendix(L"_");
  1402. BasicData->HostName = FactoryDefaults->HostName + RandomAppendix;
  1403. BasicData->Ftps = TFtps(FactoryDefaults->Ftps + 1);
  1404. BasicData->PortNumber = BasicData->GetDefaultPort() + 1;
  1405. BasicData->UserName = FactoryDefaults->UserName + RandomAppendix;
  1406. BasicData->Password = FactoryDefaults->Password + RandomAppendix;
  1407. std::unique_ptr<TStrings> BasicOptions(BasicData->SaveToOptions(FactoryDefaults.get(), false, false));
  1408. std::unique_ptr<TStrings> AllOptions(TSessionData::GetAllOptionNames(false));
  1409. std::unique_ptr<TStrings> Names(CreateSortedStringList());
  1410. for (int Index = 0; Index < AllOptions->Count; Index++)
  1411. {
  1412. Names->Add(AllOptions->Names[Index]);
  1413. }
  1414. DeleteNames(Names.get(), BasicOptions.get());
  1415. DeleteNames(Names.get(), SettingsMemo->Lines);
  1416. std::unique_ptr<TCustomDialog> AddDialog(new TCustomDialog(HelpKeyword));
  1417. AddDialog->Caption = LoadStr(SITE_RAW_ADD_CAPTION);
  1418. TComboBox * AddComboBox = new TUIStateAwareComboBox(AddDialog.get());
  1419. AddComboBox->Style = csDropDownList;
  1420. AddComboBox->DropDownCount = Max(AddComboBox->DropDownCount, 16);
  1421. AddDialog->AddComboBox(AddComboBox, CreateLabel(LoadStr(SITE_RAW_ADD_LABEL)), Names.get(), true);
  1422. AddComboBox->ItemIndex = 0;
  1423. if (AddDialog->Execute())
  1424. {
  1425. UnicodeString Name = AddComboBox->Items->Strings[AddComboBox->ItemIndex];
  1426. UnicodeString Value = AllOptions->Values[Name];
  1427. UnicodeString NameAndSeparator = Name + SettingsMemo->Lines->NameValueSeparator;
  1428. int Start = (SettingsMemo->Lines->Text + NameAndSeparator).Length();
  1429. SettingsMemo->Lines->Add(NameAndSeparator + Value);
  1430. SettingsMemo->SetFocus();
  1431. SettingsMemo->SelStart = Start;
  1432. SettingsMemo->SelLength = Value.Length();
  1433. }
  1434. }
  1435. //---------------------------------------------------------------------------
  1436. void TSiteRawDialog::DeleteNames(TStrings * Names, TStrings * Options)
  1437. {
  1438. for (int Index = 0; Index < Options->Count; Index++)
  1439. {
  1440. UnicodeString Name = Options->Names[Index];
  1441. if (!Name.IsEmpty())
  1442. {
  1443. int I = Names->IndexOf(Name);
  1444. if (I >= 0)
  1445. {
  1446. Names->Delete(I);
  1447. }
  1448. }
  1449. }
  1450. }
  1451. //---------------------------------------------------------------------------
  1452. void __fastcall DoSiteRawDialog(TSessionData * Data)
  1453. {
  1454. std::unique_ptr<TSiteRawDialog> Dialog(new TSiteRawDialog());
  1455. Dialog->Execute(Data);
  1456. }