Login.cpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103
  1. //---------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <ScpMain.h>
  5. #include <Common.h>
  6. #include <TextsWin.h>
  7. #include <VCLCommon.h>
  8. #include "Login.h"
  9. #include "WinInterface.h"
  10. #include "GUITools.h"
  11. #include "Tools.h"
  12. #include "CustomWinConfiguration.h"
  13. //---------------------------------------------------------------------
  14. #pragma link "ComboEdit"
  15. #pragma link "LogSettings"
  16. #pragma link "GeneralSettings"
  17. #pragma link "UpDownEdit"
  18. #pragma link "XPGroupBox"
  19. #pragma link "PasswordEdit"
  20. #pragma resource "*.dfm"
  21. //---------------------------------------------------------------------------
  22. bool __fastcall DoLoginDialog(TStoredSessionList *SessionList,
  23. TSessionData * Data, int Options)
  24. {
  25. assert(Data);
  26. TLoginDialog *LoginDialog = new TLoginDialog(Application);
  27. bool Result;
  28. try
  29. {
  30. LoginDialog->StoredSessions = SessionList;
  31. LoginDialog->SessionData = Data;
  32. LoginDialog->Options = Options;
  33. Result = LoginDialog->Execute();
  34. if (Result)
  35. {
  36. Data->Assign(LoginDialog->SessionData);
  37. };
  38. }
  39. __finally
  40. {
  41. delete LoginDialog;
  42. }
  43. return Result;
  44. }
  45. //---------------------------------------------------------------------
  46. __fastcall TLoginDialog::TLoginDialog(TComponent* AOwner)
  47. : TForm(AOwner)
  48. {
  49. FSessionData = new TSessionData("");
  50. NoUpdate = 0;
  51. FLanguagesPopupMenu = NULL;
  52. FInitialized = false;
  53. FSavedTab = NULL;
  54. FSavedSession = -1;
  55. FOptions = loStartup;
  56. FLocaleChanging = false;
  57. }
  58. //---------------------------------------------------------------------
  59. __fastcall TLoginDialog::~TLoginDialog()
  60. {
  61. LoggingFrame->OnGetDefaultLogFileName = NULL;
  62. // SelectItem event is called after destructor! Why?
  63. SessionListView->Selected = NULL;
  64. delete FSystemSettings;
  65. FSystemSettings = NULL;
  66. delete FSessionData;
  67. delete FLanguagesPopupMenu;
  68. }
  69. //---------------------------------------------------------------------
  70. void __fastcall TLoginDialog::ShowTabs(bool Show)
  71. {
  72. for (int Index = 0; Index < PageControl->PageCount; Index++)
  73. {
  74. PageControl->Pages[Index]->TabVisible = Show;
  75. }
  76. // change form height by height of hidden tabs
  77. ClientHeight += (Show ? 1 : -1) * 50;
  78. }
  79. //---------------------------------------------------------------------
  80. void __fastcall TLoginDialog::Init()
  81. {
  82. LoggingFrame->OnGetDefaultLogFileName = LoggingGetDefaultLogFileName;
  83. UseSystemSettings(this, &FSystemSettings);
  84. Caption = FORMAT("%s %s", (AppName, Caption));
  85. InitializeBugsCombo(BugIgnore1Combo);
  86. InitializeBugsCombo(BugPlainPW1Combo);
  87. InitializeBugsCombo(BugRSA1Combo);
  88. InitializeBugsCombo(BugHMAC2Combo);
  89. InitializeBugsCombo(BugDeriveKey2Combo);
  90. InitializeBugsCombo(BugRSAPad2Combo);
  91. InitializeBugsCombo(BugDHGEx2Combo);
  92. InitializeBugsCombo(BugPKSessID2Combo);
  93. PrepareNavigationTree(SimpleNavigationTree);
  94. PrepareNavigationTree(AdvancedNavigationTree);
  95. if ((Options & loLocalDirectory) == 0)
  96. {
  97. LocalDirectoryLabel->Visible = false;
  98. LocalDirectoryEdit->Visible = false;
  99. LocalDirectoryDescLabel->Visible = false;
  100. int PrevHeight = DirectoriesGroup->Height;
  101. DirectoriesGroup->Height = RemoteDirectoryEdit->Top + RemoteDirectoryEdit->Height + 12;
  102. EOLTypeGroup->Top = EOLTypeGroup->Top - PrevHeight + DirectoriesGroup->Height;
  103. }
  104. ShowTabs(false);
  105. if (StoredSessions && StoredSessions->Count &&
  106. (FSessionData->Name == StoredSessions->DefaultSettings->Name))
  107. {
  108. ChangePage(SessionListSheet);
  109. SessionListView->SetFocus();
  110. }
  111. else
  112. {
  113. ChangePage(BasicSheet);
  114. HostNameEdit->SetFocus();
  115. }
  116. UpdateControls();
  117. }
  118. //---------------------------------------------------------------------
  119. void __fastcall TLoginDialog::InitializeBugsCombo(TComboBox * BugsCombo)
  120. {
  121. BugsCombo->Clear();
  122. BugsCombo->Items->Add(LoadStr(LOGIN_BUG_AUTO));
  123. BugsCombo->Items->Add(LoadStr(LOGIN_BUG_OFF));
  124. BugsCombo->Items->Add(LoadStr(LOGIN_BUG_ON));
  125. }
  126. //---------------------------------------------------------------------
  127. void __fastcall TLoginDialog::LoadSessions()
  128. {
  129. SessionListView->Items->BeginUpdate();
  130. try
  131. {
  132. SessionListView->Items->Clear();
  133. if (StoredSessions)
  134. {
  135. for (int Index = 0; Index < StoredSessions->Count; Index++)
  136. {
  137. TListItem *Item;
  138. Item = SessionListView->Items->Add();
  139. LoadSessionItem(Item);
  140. }
  141. }
  142. }
  143. __finally
  144. {
  145. SessionListView->Items->EndUpdate();
  146. }
  147. SelectedSession = StoredSessions->Count > 0 ?
  148. dynamic_cast<TSessionData*>(StoredSessions->AtObject(0)) : NULL;
  149. UpdateControls();
  150. }
  151. //---------------------------------------------------------------------------
  152. void __fastcall TLoginDialog::Default()
  153. {
  154. if (StoredSessions)
  155. {
  156. FSessionData->Assign(StoredSessions->DefaultSettings);
  157. }
  158. else
  159. {
  160. FSessionData->Default();
  161. }
  162. LoadSession(FSessionData);
  163. FCurrentSessionName = "";
  164. }
  165. //---------------------------------------------------------------------
  166. void __fastcall TLoginDialog::LoadSession(TSessionData * aSessionData)
  167. {
  168. NoUpdate++;
  169. try
  170. {
  171. // Basic tab
  172. UserNameEdit->Text = aSessionData->UserName;
  173. PortNumberEdit->AsInteger = aSessionData->PortNumber;
  174. HostNameEdit->Text = aSessionData->HostName;
  175. PasswordEdit->Text = aSessionData->Password;
  176. PrivateKeyEdit->Text = aSessionData->PublicKeyFile;
  177. switch (aSessionData->FSProtocol) {
  178. case fsSCPonly: SCPonlyButton->Checked = true; break;
  179. case fsSFTP: SFTPButton->Checked = true; break;
  180. case fsSFTPonly:
  181. default: SFTPonlyButton->Checked = true; break;
  182. }
  183. // Environment tab
  184. LocalDirectoryEdit->Text = aSessionData->LocalDirectory;
  185. RemoteDirectoryEdit->Text = aSessionData->RemoteDirectory;
  186. UpdateDirectoriesCheck->Checked = aSessionData->UpdateDirectories;
  187. CacheDirectoriesCheck->Checked = aSessionData->CacheDirectories;
  188. CacheDirectoryChangesCheck->Checked = aSessionData->CacheDirectoryChanges;
  189. PreserveDirectoryChangesCheck->Checked = aSessionData->PreserveDirectoryChanges;
  190. ResolveSymlinksCheck->Checked = aSessionData->ResolveSymlinks;
  191. if (aSessionData->EOLType == eolLF)
  192. {
  193. EOLTypeLFButton->Checked = true;
  194. }
  195. else
  196. {
  197. EOLTypeCRLFButton->Checked = true;
  198. }
  199. AuthTISCheck->Checked = aSessionData->AuthTIS;
  200. AuthKICheck->Checked = aSessionData->AuthKI;
  201. AgentFwdCheck->Checked = aSessionData->AgentFwd;
  202. Ssh2LegacyDESCheck->Checked = aSessionData->Ssh2DES;
  203. // SSH tab
  204. CompressionCheck->Checked = aSessionData->Compression;
  205. switch (aSessionData->SshProt) {
  206. case ssh1only: SshProt1onlyButton->Checked = true; break;
  207. case ssh1: SshProt1Button->Checked = true; break;
  208. case ssh2: SshProt2Button->Checked = true; break;
  209. case ssh2only: SshProt2onlyButton->Checked = true; break;
  210. }
  211. CipherListBox->Items->Clear();
  212. assert(CIPHER_NAME_WARN+CIPHER_COUNT-1 == CIPHER_NAME_DES);
  213. for (int Index = 0; Index < CIPHER_COUNT; Index++)
  214. {
  215. CipherListBox->Items->AddObject(
  216. LoadStr(CIPHER_NAME_WARN+aSessionData->Cipher[Index]),
  217. (TObject*)aSessionData->Cipher[Index]);
  218. }
  219. // Connection tab
  220. switch (aSessionData->PingType)
  221. {
  222. case ptNullPacket:
  223. PingNullPacketButton->Checked = true;
  224. break;
  225. case ptDummyCommand:
  226. PingDummyCommandButton->Checked = true;
  227. break;
  228. default:
  229. PingOffButton->Checked = true;
  230. break;
  231. }
  232. PingIntervalSecEdit->AsInteger = aSessionData->PingInterval;
  233. TimeoutEdit->AsInteger = aSessionData->Timeout;
  234. // Shell tab
  235. if (aSessionData->DefaultShell)
  236. DefaultShellButton->Checked = true;
  237. else
  238. ShellEnterButton->Checked = true;
  239. ShellEdit->Text = aSessionData->Shell;
  240. if (aSessionData->DetectReturnVar)
  241. ReturnVarAutodetectButton->Checked = true;
  242. else
  243. ReturnVarEnterButton->Checked = true;
  244. ReturnVarEdit->Text = aSessionData->ReturnVar;
  245. LookupUserGroupsCheck->Checked = aSessionData->LookupUserGroups;
  246. ClearAliasesCheck->Checked = aSessionData->ClearAliases;
  247. IgnoreLsWarningsCheck->Checked = aSessionData->IgnoreLsWarnings;
  248. Scp1CompatibilityCheck->Checked = aSessionData->Scp1Compatibility;
  249. UnsetNationalVarsCheck->Checked = aSessionData->UnsetNationalVars;
  250. AliasGroupListCheck->Checked = aSessionData->AliasGroupList;
  251. int TimeDifferenceMin = double(aSessionData->TimeDifference) * 24 * 60;
  252. TimeDifferenceEdit->AsInteger = TimeDifferenceMin / 60;
  253. TimeDifferenceMinutesEdit->AsInteger = TimeDifferenceMin % 60;
  254. // Proxy tab
  255. switch (aSessionData->ProxyMethod) {
  256. case pmHTTP: ProxyHTTPButton->Checked = true; break;
  257. case pmSocks4: ProxySocks4Button->Checked = true; break;
  258. case pmSocks5: ProxySocks5Button->Checked = true; break;
  259. case pmTelnet: ProxyTelnetButton->Checked = true; break;
  260. default: ProxyNoneButton->Checked = true; break;
  261. }
  262. ProxyHostEdit->Text = aSessionData->ProxyHost;
  263. ProxyPortEdit->AsInteger = aSessionData->ProxyPort;
  264. ProxyUsernameEdit->Text = aSessionData->ProxyUsername;
  265. ProxyPasswordEdit->Text = aSessionData->ProxyPassword;
  266. ProxyTelnetCommandEdit->Text = aSessionData->ProxyTelnetCommand;
  267. ProxyLocalhostCheck->Checked = aSessionData->ProxyLocalhost;
  268. switch (aSessionData->ProxyDNS) {
  269. case asOn: ProxyDNSOnButton->Checked = true; break;
  270. case asOff: ProxyDNSOffButton->Checked = true; break;
  271. default: ProxyDNSAutoButton->Checked = true; break;
  272. }
  273. // Bugs tab
  274. #define LOAD_BUG_COMBO(BUG) Bug ## BUG ## Combo->ItemIndex = 2 - aSessionData->Bug[sb ## BUG]
  275. LOAD_BUG_COMBO(Ignore1);
  276. LOAD_BUG_COMBO(PlainPW1);
  277. LOAD_BUG_COMBO(RSA1);
  278. LOAD_BUG_COMBO(HMAC2);
  279. LOAD_BUG_COMBO(DeriveKey2);
  280. LOAD_BUG_COMBO(RSAPad2);
  281. LOAD_BUG_COMBO(DHGEx2);
  282. LOAD_BUG_COMBO(PKSessID2);
  283. #undef LOAD_BUG_COMBO
  284. }
  285. __finally
  286. {
  287. NoUpdate--;
  288. UpdateControls();
  289. }
  290. FCurrentSessionName = aSessionData->Name;
  291. }
  292. //---------------------------------------------------------------------
  293. void __fastcall TLoginDialog::SaveSession(TSessionData * aSessionData)
  294. {
  295. aSessionData->Name = FCurrentSessionName;
  296. // Basic tab
  297. aSessionData->UserName = UserNameEdit->Text;
  298. aSessionData->PortNumber = PortNumberEdit->AsInteger;
  299. // must be loaded after UserName, because HostName may be in format user@host
  300. aSessionData->HostName = HostNameEdit->Text;
  301. aSessionData->Password = PasswordEdit->Text;
  302. aSessionData->PublicKeyFile = PrivateKeyEdit->Text;
  303. if (SCPonlyButton->Checked) aSessionData->FSProtocol = fsSCPonly;
  304. else
  305. if (SFTPButton->Checked) aSessionData->FSProtocol = fsSFTP;
  306. else aSessionData->FSProtocol = fsSFTPonly;
  307. // SSH tab
  308. aSessionData->Compression = CompressionCheck->Checked;
  309. aSessionData->Ssh2DES = Ssh2LegacyDESCheck->Checked;
  310. if (SshProt1onlyButton->Checked) aSessionData->SshProt = ssh1only;
  311. else
  312. if (SshProt1Button->Checked) aSessionData->SshProt = ssh1;
  313. else
  314. if (SshProt2Button->Checked) aSessionData->SshProt = ssh2;
  315. else aSessionData->SshProt = ssh2only;
  316. for (int Index = 0; Index < CIPHER_COUNT; Index++)
  317. {
  318. aSessionData->Cipher[Index] = (TCipher)CipherListBox->Items->Objects[Index];
  319. }
  320. // Authentication tab
  321. aSessionData->AuthTIS = AuthTISCheck->Checked;
  322. aSessionData->AuthKI = AuthKICheck->Checked;
  323. aSessionData->AgentFwd = AgentFwdCheck->Checked;
  324. // Connection tab
  325. if (PingNullPacketButton->Checked)
  326. {
  327. aSessionData->PingType = ptNullPacket;
  328. }
  329. else if (PingDummyCommandButton->Checked)
  330. {
  331. aSessionData->PingType = ptDummyCommand;
  332. }
  333. else
  334. {
  335. aSessionData->PingType = ptOff;
  336. }
  337. aSessionData->PingInterval = PingIntervalSecEdit->AsInteger;
  338. aSessionData->Timeout = TimeoutEdit->AsInteger;
  339. // Environment tab
  340. aSessionData->LocalDirectory = LocalDirectoryEdit->Text;
  341. aSessionData->RemoteDirectory = RemoteDirectoryEdit->Text;
  342. aSessionData->UpdateDirectories = UpdateDirectoriesCheck->Checked;
  343. aSessionData->CacheDirectories = CacheDirectoriesCheck->Checked;
  344. aSessionData->CacheDirectoryChanges = CacheDirectoryChangesCheck->Checked;
  345. aSessionData->PreserveDirectoryChanges = PreserveDirectoryChangesCheck->Checked;
  346. aSessionData->ResolveSymlinks = ResolveSymlinksCheck->Checked;
  347. // Shell tab
  348. aSessionData->DefaultShell = DefaultShellButton->Checked;
  349. if (ShellEnterButton->Checked)
  350. aSessionData->Shell = ShellEdit->Text;
  351. aSessionData->DetectReturnVar = ReturnVarAutodetectButton->Checked;
  352. if (ReturnVarEnterButton->Checked)
  353. aSessionData->ReturnVar = ReturnVarEdit->Text;
  354. aSessionData->LookupUserGroups = LookupUserGroupsCheck->Checked;
  355. aSessionData->ClearAliases = ClearAliasesCheck->Checked;
  356. aSessionData->IgnoreLsWarnings = IgnoreLsWarningsCheck->Checked;
  357. aSessionData->Scp1Compatibility = Scp1CompatibilityCheck->Checked;
  358. if (EOLTypeLFButton->Checked) aSessionData->EOLType = eolLF;
  359. else aSessionData->EOLType = eolCRLF;
  360. aSessionData->UnsetNationalVars = UnsetNationalVarsCheck->Checked;
  361. aSessionData->AliasGroupList = AliasGroupListCheck->Checked;
  362. aSessionData->TimeDifference =
  363. (double(TimeDifferenceEdit->AsInteger) / 24) +
  364. (double(TimeDifferenceMinutesEdit->AsInteger) / 24 / 60);
  365. // Proxy tab
  366. if (ProxyHTTPButton->Checked) aSessionData->ProxyMethod = pmHTTP;
  367. else
  368. if (ProxySocks4Button->Checked) aSessionData->ProxyMethod = pmSocks4;
  369. else
  370. if (ProxySocks5Button->Checked) aSessionData->ProxyMethod = pmSocks5;
  371. else
  372. if (ProxyTelnetButton->Checked) aSessionData->ProxyMethod = pmTelnet;
  373. else aSessionData->ProxyMethod = pmNone;
  374. aSessionData->ProxyHost = ProxyHostEdit->Text;
  375. aSessionData->ProxyPort = ProxyPortEdit->AsInteger;
  376. aSessionData->ProxyUsername = ProxyUsernameEdit->Text;
  377. aSessionData->ProxyPassword = ProxyPasswordEdit->Text;
  378. aSessionData->ProxyTelnetCommand = ProxyTelnetCommandEdit->Text;
  379. aSessionData->ProxyLocalhost = ProxyLocalhostCheck->Checked;
  380. if (ProxyDNSOnButton->Checked) aSessionData->ProxyDNS = asOn;
  381. else
  382. if (ProxyDNSOffButton->Checked) aSessionData->ProxyDNS = asOff;
  383. else aSessionData->ProxyDNS = asAuto;
  384. // Bugs tab
  385. #define SAVE_BUG_COMBO(BUG) aSessionData->Bug[sb ## BUG] = (TAutoSwitch)(2 - Bug ## BUG ## Combo->ItemIndex);
  386. SAVE_BUG_COMBO(Ignore1);
  387. SAVE_BUG_COMBO(PlainPW1);
  388. SAVE_BUG_COMBO(RSA1);
  389. SAVE_BUG_COMBO(HMAC2);
  390. SAVE_BUG_COMBO(DeriveKey2);
  391. SAVE_BUG_COMBO(RSAPad2);
  392. SAVE_BUG_COMBO(DHGEx2);
  393. SAVE_BUG_COMBO(PKSessID2);
  394. #undef SAVE_BUG_COMBO
  395. }
  396. //---------------------------------------------------------------------
  397. void __fastcall TLoginDialog::UpdateControls()
  398. {
  399. if (Visible)
  400. {
  401. NoUpdate++;
  402. try
  403. {
  404. #define SHOW_NAVIGATION(TREE, SHOW) if ((TREE)->Visible != (SHOW)) { \
  405. (TREE)->Visible = (SHOW); PageControlChange(PageControl); }
  406. SHOW_NAVIGATION(SimpleNavigationTree, !ShowAdvancedLoginOptionsCheck->Checked);
  407. SHOW_NAVIGATION(AdvancedNavigationTree, ShowAdvancedLoginOptionsCheck->Checked);
  408. #undef SHOW_NAVIGATION
  409. EnableControl(ShellIconsButton, SessionListView->Selected);
  410. if (!PrivateKeyEdit->Text.IsEmpty())
  411. {
  412. PasswordEdit->Clear();
  413. }
  414. EnableControl(PasswordEdit, PrivateKeyEdit->Text.IsEmpty());
  415. if (!PasswordEdit->Text.IsEmpty()) PrivateKeyEdit->Clear();
  416. EnableControl(PrivateKeyEdit, PasswordEdit->Text.IsEmpty());
  417. EnableControl(PingIntervalSecEdit, !PingOffButton->Checked);
  418. EnableControl(SessionListView, SessionListView->Items->Count);
  419. AdjustListColumnsWidth(SessionListView);
  420. SessionListView->Columns->Items[0]->Width -= 2;
  421. EnableControl(AuthTISCheck, !SshProt2onlyButton->Checked);
  422. EnableControl(AuthKICheck, !SshProt1onlyButton->Checked);
  423. EnableControl(CipherUpButton, CipherListBox->ItemIndex > 0);
  424. EnableControl(CipherDownButton, CipherListBox->ItemIndex >= 0 &&
  425. CipherListBox->ItemIndex < CipherListBox->Items->Count-1);
  426. EnableControl(Ssh2LegacyDESCheck, !SshProt1onlyButton->Checked);
  427. EnableControl(BugIgnore1Combo, !SshProt2onlyButton->Checked);
  428. EnableControl(BugPlainPW1Combo, !SshProt2onlyButton->Checked);
  429. EnableControl(BugRSA1Combo, !SshProt2onlyButton->Checked);
  430. EnableControl(BugHMAC2Combo, !SshProt1onlyButton->Checked);
  431. EnableControl(BugDeriveKey2Combo, !SshProt1onlyButton->Checked);
  432. EnableControl(BugRSAPad2Combo, !SshProt1onlyButton->Checked);
  433. EnableControl(BugDHGEx2Combo, !SshProt1onlyButton->Checked);
  434. EnableControl(ShellEdit, ShellEnterButton->Checked);
  435. EnableControl(ReturnVarEdit, ReturnVarEnterButton->Checked);
  436. EnableControl(ProxyHostEdit, !ProxyNoneButton->Checked);
  437. EnableControl(ProxyPortEdit, !ProxyNoneButton->Checked);
  438. EnableControl(ProxyUsernameEdit, !ProxyNoneButton->Checked);
  439. EnableControl(ProxyPasswordEdit, !ProxyNoneButton->Checked);
  440. EnableControl(ProxySettingsGroup, !ProxyNoneButton->Checked);
  441. EnableControl(ProxyTelnetCommandEdit, ProxyTelnetButton->Checked);
  442. EnableControl(PreserveDirectoryChangesCheck, CacheDirectoryChangesCheck->Checked);
  443. AboutButton->Visible = (Options & loAbout);
  444. LanguagesButton->Visible = (Options & loLanguage);
  445. ShellIconsButton->Visible = (Options & loTools);
  446. ToolsMenuButton->Visible = (Options & loTools);
  447. LoggingFrame->EnableLogWindow = (Options & loLogWindow);
  448. }
  449. __finally
  450. {
  451. NoUpdate--;
  452. }
  453. }
  454. }
  455. //---------------------------------------------------------------------------
  456. void __fastcall TLoginDialog::DataChange(TObject * /*Sender*/)
  457. {
  458. if (!NoUpdate) UpdateControls();
  459. }
  460. //---------------------------------------------------------------------------
  461. void __fastcall TLoginDialog::PrepareNavigationTree(TTreeView * Tree)
  462. {
  463. Tree->FullExpand();
  464. int i = 0;
  465. while (i < Tree->Items->Count)
  466. {
  467. if ((Tree->Items->Item[i]->StateIndex > 0) &&
  468. ((Options & Tree->Items->Item[i]->StateIndex) == 0))
  469. {
  470. Tree->Items->Delete(Tree->Items->Item[i]);
  471. }
  472. else
  473. {
  474. for (int pi = 0; pi < PageControl->PageCount; pi++)
  475. {
  476. if (PageControl->Pages[pi]->Tag == Tree->Items->Item[i]->SelectedIndex)
  477. {
  478. Tree->Items->Item[i]->Text = PageControl->Pages[pi]->Hint;
  479. break;
  480. }
  481. }
  482. i++;
  483. }
  484. }
  485. }
  486. //---------------------------------------------------------------------------
  487. void __fastcall TLoginDialog::FormShow(TObject * /*Sender*/)
  488. {
  489. if (!FInitialized)
  490. {
  491. FInitialized = true;
  492. Init();
  493. TSessionData * Data = GetSessionData();
  494. if (Data == FSessionData)
  495. {
  496. LoadSession(Data);
  497. }
  498. else
  499. {
  500. Default();
  501. }
  502. }
  503. if (FLocaleChanging)
  504. {
  505. Init();
  506. LoadSession(FSessionData);
  507. ChangePage(FSavedTab);
  508. SessionListView->ItemIndex = FSavedSession;
  509. LoadConfiguration();
  510. }
  511. }
  512. //---------------------------------------------------------------------------
  513. void __fastcall TLoginDialog::SessionListViewSelectItem(TObject * /*Sender*/,
  514. TListItem * /*Item*/, bool /*Selected*/)
  515. {
  516. UpdateControls();
  517. }
  518. //---------------------------------------------------------------------------
  519. void __fastcall TLoginDialog::StoreSessions()
  520. {
  521. StoredSessions->Save();
  522. }
  523. //---------------------------------------------------------------------------
  524. void __fastcall TLoginDialog::SetSessionData(TSessionData * value)
  525. {
  526. FSessionData->Assign(value);
  527. FSessionData->Special = false;
  528. LoadSession(FSessionData);
  529. }
  530. //---------------------------------------------------------------------------
  531. TSessionData * __fastcall TLoginDialog::GetSessionData()
  532. {
  533. if (PageControl->ActivePage == SessionListSheet)
  534. {
  535. return SelectedSession;
  536. }
  537. else
  538. {
  539. SaveSession(FSessionData);
  540. return FSessionData;
  541. }
  542. }
  543. //---------------------------------------------------------------------------
  544. void __fastcall TLoginDialog::SetStoredSessions(TStoredSessionList * value)
  545. {
  546. if (FStoredSessions != value)
  547. {
  548. FStoredSessions = value;
  549. LoadSessions();
  550. }
  551. }
  552. //---------------------------------------------------------------------------
  553. void __fastcall TLoginDialog::LoadSessionItem(TListItem * Item)
  554. {
  555. Item->Data = StoredSessions->AtObject(Item->Index);
  556. Item->Caption = ((TSessionData*)Item->Data)->Name;
  557. }
  558. //---------------------------------------------------------------------------
  559. void __fastcall TLoginDialog::SessionListViewDblClick(TObject * /*Sender*/)
  560. {
  561. if (SelectedSession)
  562. {
  563. if (SelectedSession->CanLogin) ModalResult = mrOk;
  564. else
  565. {
  566. SessionData = SelectedSession;
  567. ChangePage(BasicSheet);
  568. if (HostNameEdit->Text.IsEmpty()) HostNameEdit->SetFocus();
  569. else
  570. if (UserNameEdit->Text.IsEmpty()) UserNameEdit->SetFocus();
  571. }
  572. }
  573. }
  574. //---------------------------------------------------------------------------
  575. void __fastcall TLoginDialog::SetSelectedSession(TSessionData * value)
  576. {
  577. if (value)
  578. {
  579. int Index = StoredSessions->IndexOf(value);
  580. if (Index >= 0)
  581. {
  582. TListItem *Item = SessionListView->Items->Item[Index];
  583. Item->Focused = true;
  584. Item->Selected = true;
  585. Item->MakeVisible(false);
  586. }
  587. }
  588. else
  589. {
  590. SessionListView->Selected = NULL;
  591. }
  592. }
  593. //---------------------------------------------------------------------------
  594. TSessionData * __fastcall TLoginDialog::GetSelectedSession()
  595. {
  596. if (SessionListView->Selected)
  597. return (TSessionData *)SessionListView->Selected->Data;
  598. else
  599. return NULL;
  600. }
  601. //---------------------------------------------------------------------------
  602. void __fastcall TLoginDialog::SessionListViewInfoTip(TObject * /*Sender*/,
  603. TListItem * Item, AnsiString & InfoTip)
  604. {
  605. InfoTip = ((TSessionData*)Item->Data)->InfoTip;
  606. }
  607. //---------------------------------------------------------------------------
  608. void __fastcall TLoginDialog::SessionListViewKeyDown(TObject * /*Sender*/,
  609. WORD &Key, TShiftState /*Shift*/)
  610. {
  611. if (Key == VK_DELETE) DeleteSessionAction->Execute();
  612. }
  613. //---------------------------------------------------------------------------
  614. void __fastcall TLoginDialog::LoadSessionActionExecute(TObject * /*Sender*/)
  615. {
  616. if (SelectedSession)
  617. {
  618. SessionData = SelectedSession;
  619. ChangePage(BasicSheet);
  620. }
  621. }
  622. //---------------------------------------------------------------------------
  623. void __fastcall TLoginDialog::SaveSessionActionExecute(TObject * /*Sender*/)
  624. {
  625. AnsiString SessionName;
  626. SaveSession(FSessionData);
  627. SessionName = DoSaveSessionDialog(StoredSessions, FSessionData->SessionName);
  628. if (!SessionName.IsEmpty())
  629. {
  630. TListItem * Item;
  631. TSessionData *NewSession =
  632. StoredSessions->NewSession(SessionName, FSessionData);
  633. StoredSessions->Save();
  634. // by now list must contais same number of items or one less
  635. assert(StoredSessions->Count == SessionListView->Items->Count ||
  636. StoredSessions->Count == SessionListView->Items->Count+1);
  637. if (StoredSessions->Count > SessionListView->Items->Count)
  638. Item = SessionListView->Items->Insert(StoredSessions->IndexOf(NewSession));
  639. else
  640. Item = SessionListView->Items->Item[StoredSessions->IndexOf(NewSession)];
  641. LoadSessionItem(Item);
  642. SelectedSession = NewSession;
  643. SessionData = NewSession;
  644. ChangePage(SessionListSheet);
  645. SessionListView->SetFocus();
  646. }
  647. }
  648. //---------------------------------------------------------------------------
  649. void __fastcall TLoginDialog::DeleteSessionActionExecute(TObject * /*Sender*/)
  650. {
  651. if (SelectedSession)
  652. {
  653. int PrevSelectedIndex = SessionListView->Selected->Index;
  654. SelectedSession->Remove();
  655. StoredSessions->Remove(SelectedSession);
  656. SessionListView->Selected->Delete();
  657. if (SessionListView->Items->Count)
  658. {
  659. if (PrevSelectedIndex >= SessionListView->Items->Count)
  660. PrevSelectedIndex = SessionListView->Items->Count - 1;
  661. SelectedSession =
  662. (TSessionData *)StoredSessions->AtObject(PrevSelectedIndex);
  663. }
  664. }
  665. }
  666. //---------------------------------------------------------------------------
  667. void __fastcall TLoginDialog::ImportSessionsActionExecute(TObject * /*Sender*/)
  668. {
  669. if (DoImportSessionsDialog(StoredSessions))
  670. {
  671. LoadSessions();
  672. if (SessionListView->Items->Count)
  673. SessionListView->Items->Item[0]->MakeVisible(False);
  674. }
  675. }
  676. //---------------------------------------------------------------------------
  677. void __fastcall TLoginDialog::CleanUpActionExecute(TObject * /*Sender*/)
  678. {
  679. if (DoCleanupDialog(StoredSessions, Configuration))
  680. LoadSessions();
  681. }
  682. //---------------------------------------------------------------------------
  683. void __fastcall TLoginDialog::AboutActionExecute(TObject * /*Sender*/)
  684. {
  685. DoAboutDialog(Configuration);
  686. }
  687. //---------------------------------------------------------------------------
  688. void __fastcall TLoginDialog::ActionListUpdate(TBasicAction *Action,
  689. bool &Handled)
  690. {
  691. if (Action == LoadSessionAction)
  692. {
  693. LoadSessionAction->Enabled = SessionListView->Selected;
  694. }
  695. else if (Action == DeleteSessionAction)
  696. {
  697. TSessionData * Data = SessionData;
  698. DeleteSessionAction->Enabled =
  699. SessionListView->Selected && Data && !Data->Special;
  700. }
  701. else if (Action == DesktopIconAction)
  702. {
  703. DesktopIconAction->Enabled = SessionListView->Selected;
  704. }
  705. else if (Action == SendToHookAction)
  706. {
  707. SendToHookAction->Enabled = SessionListView->Selected;
  708. }
  709. else if (Action == LoginAction)
  710. {
  711. TSessionData * Data = SessionData;
  712. LoginAction->Enabled = Data && Data->CanLogin;
  713. }
  714. else if (Action == SaveSessionAction)
  715. {
  716. SaveSessionAction->Enabled = (PageControl->ActivePage != SessionListSheet);
  717. }
  718. Handled = true;
  719. }
  720. //---------------------------------------------------------------------------
  721. bool __fastcall TLoginDialog::Execute()
  722. {
  723. LoadConfiguration();
  724. bool Result = (ShowModal() == mrOk);
  725. if (Result)
  726. {
  727. SaveConfiguration();
  728. }
  729. return Result;
  730. }
  731. //---------------------------------------------------------------------------
  732. void __fastcall TLoginDialog::SaveConfiguration()
  733. {
  734. assert(CustomWinConfiguration);
  735. CustomWinConfiguration->BeginUpdate();
  736. try
  737. {
  738. LoggingFrame->SaveConfiguration();
  739. GeneralSettingsFrame->SaveConfiguration();
  740. CustomWinConfiguration->ShowAdvancedLoginOptions = ShowAdvancedLoginOptionsCheck->Checked;
  741. }
  742. __finally
  743. {
  744. CustomWinConfiguration->EndUpdate();
  745. }
  746. }
  747. //---------------------------------------------------------------------------
  748. void __fastcall TLoginDialog::LoadConfiguration()
  749. {
  750. assert(CustomWinConfiguration);
  751. LoggingFrame->LoadConfiguration();
  752. GeneralSettingsFrame->LoadConfiguration();
  753. ShowAdvancedLoginOptionsCheck->Checked = CustomWinConfiguration->ShowAdvancedLoginOptions;
  754. UpdateControls();
  755. }
  756. //---------------------------------------------------------------------------
  757. void __fastcall TLoginDialog::LoggingGetDefaultLogFileName(
  758. TObject* /*Sender*/, AnsiString & DefaultLogFileName)
  759. {
  760. assert(FSessionData);
  761. DefaultLogFileName = FSessionData->DefaultLogFileName;
  762. }
  763. //---------------------------------------------------------------------------
  764. void __fastcall TLoginDialog::PreferencesButtonClick(TObject * /*Sender*/)
  765. {
  766. ShowPreferencesDialog();
  767. }
  768. //---------------------------------------------------------------------------
  769. void __fastcall TLoginDialog::ShowPreferencesDialog()
  770. {
  771. DoPreferencesDialog(pmLogin);
  772. }
  773. //---------------------------------------------------------------------------
  774. void __fastcall TLoginDialog::NewSessionActionExecute(TObject * /*Sender*/)
  775. {
  776. Default();
  777. ChangePage(BasicSheet);
  778. }
  779. //---------------------------------------------------------------------------
  780. void __fastcall TLoginDialog::NavigationTreeChange(TObject * /*Sender*/,
  781. TTreeNode *Node)
  782. {
  783. if (Node->SelectedIndex)
  784. {
  785. for (Integer Index = 0; Index < PageControl->PageCount; Index++)
  786. {
  787. if (PageControl->Pages[Index]->Tag == Node->SelectedIndex)
  788. {
  789. PageControl->ActivePage = PageControl->Pages[Index];
  790. return;
  791. }
  792. }
  793. }
  794. assert(false);
  795. }
  796. //---------------------------------------------------------------------------
  797. void __fastcall TLoginDialog::ChangePage(TTabSheet * Tab)
  798. {
  799. PageControl->ActivePage = Tab;
  800. PageControlChange(PageControl);
  801. }
  802. //---------------------------------------------------------------------------
  803. void __fastcall TLoginDialog::PageControlChange(TObject *Sender)
  804. {
  805. bool Found = false;
  806. if (PageControl->ActivePage->Tag)
  807. {
  808. for (int Index = 0; Index < NavigationTree->Items->Count; Index++)
  809. {
  810. if (NavigationTree->Items->Item[Index]->SelectedIndex ==
  811. PageControl->ActivePage->Tag)
  812. {
  813. NavigationTree->Items->Item[Index]->Selected = true;
  814. Found = true;
  815. }
  816. }
  817. }
  818. if (!Found)
  819. {
  820. ChangePage(BasicSheet);
  821. }
  822. else
  823. {
  824. DataChange(Sender);
  825. }
  826. }
  827. //---------------------------------------------------------------------------
  828. TTreeView * __fastcall TLoginDialog::GetNavigationTree()
  829. {
  830. return (ShowAdvancedLoginOptionsCheck->Checked ?
  831. AdvancedNavigationTree : SimpleNavigationTree);
  832. }
  833. //---------------------------------------------------------------------------
  834. void __fastcall TLoginDialog::CMDialogKey(TWMKeyDown & Message)
  835. {
  836. if (Message.CharCode == VK_TAB)
  837. {
  838. TShiftState Shift = KeyDataToShiftState(Message.KeyData);
  839. if (Shift.Contains(ssCtrl))
  840. {
  841. TTreeNode * Node = NavigationTree->Selected;
  842. if (!Shift.Contains(ssShift))
  843. {
  844. Node = Node->GetNext();
  845. if (!Node) Node = NavigationTree->Items->GetFirstNode();
  846. }
  847. else
  848. {
  849. if (Node->GetPrev()) Node = Node->GetPrev();
  850. else
  851. while (Node->GetNext()) Node = Node->GetNext();
  852. }
  853. Node->Selected = True;
  854. Message.Result = 1;
  855. return;
  856. }
  857. }
  858. TForm::Dispatch(&Message);
  859. }
  860. //---------------------------------------------------------------------------
  861. void __fastcall TLoginDialog::Dispatch(void *Message)
  862. {
  863. TMessage * M = reinterpret_cast<TMessage*>(Message);
  864. assert(M);
  865. if (M->Msg == CM_DIALOGKEY)
  866. {
  867. CMDialogKey(*((TWMKeyDown *)Message));
  868. }
  869. else if (M->Msg == WM_LOCALE_CHANGE)
  870. {
  871. if (M->WParam == 0)
  872. {
  873. SaveConfiguration();
  874. SaveSession(FSessionData);
  875. FSavedTab = PageControl->ActivePage;
  876. FSavedSession = SessionListView->ItemIndex;
  877. assert(FSystemSettings);
  878. RevokeSystemSettings(this, FSystemSettings);
  879. FSystemSettings = NULL;
  880. ShowTabs(true);
  881. Hide();
  882. }
  883. else
  884. {
  885. FLocaleChanging = true;
  886. try
  887. {
  888. Show();
  889. }
  890. __finally
  891. {
  892. FLocaleChanging = false;
  893. }
  894. }
  895. }
  896. else
  897. {
  898. TForm::Dispatch(Message);
  899. }
  900. }
  901. //---------------------------------------------------------------------------
  902. void __fastcall TLoginDialog::CipherListBoxStartDrag(TObject * /*Sender*/,
  903. TDragObject *& /*DragObject*/)
  904. {
  905. FCipherDragSource = CipherListBox->ItemIndex;
  906. FCipherDragDest = -1;
  907. }
  908. //---------------------------------------------------------------------------
  909. void __fastcall TLoginDialog::CipherListBoxDragOver(TObject * /*Sender*/,
  910. TObject *Source, int X, int Y, TDragState /*State*/, bool &Accept)
  911. {
  912. if (Source == CipherListBox) Accept = AllowCipherDrag(X, Y);
  913. }
  914. //---------------------------------------------------------------------------
  915. void __fastcall TLoginDialog::CipherListBoxDragDrop(TObject * /*Sender*/,
  916. TObject *Source, int X, int Y)
  917. {
  918. if (Source == CipherListBox)
  919. {
  920. if (AllowCipherDrag(X, Y)) CipherMove(FCipherDragSource, FCipherDragDest);
  921. }
  922. }
  923. //---------------------------------------------------------------------------
  924. void __fastcall TLoginDialog::CipherButtonClick(TObject *Sender)
  925. {
  926. CipherMove(CipherListBox->ItemIndex,
  927. CipherListBox->ItemIndex + (Sender == CipherUpButton ? -1 : 1));
  928. UpdateControls();
  929. }
  930. //---------------------------------------------------------------------------
  931. bool __fastcall TLoginDialog::AllowCipherDrag(int X, int Y)
  932. {
  933. FCipherDragDest = CipherListBox->ItemAtPos(TPoint(X, Y), true);
  934. return (FCipherDragDest >= 0) && (FCipherDragDest != FCipherDragSource);
  935. }
  936. //---------------------------------------------------------------------------
  937. void __fastcall TLoginDialog::CipherMove(int Source, int Dest)
  938. {
  939. if (Source >= 0 && Source < CipherListBox->Items->Count &&
  940. Dest >= 0 && Dest < CipherListBox->Items->Count)
  941. {
  942. CipherListBox->Items->Move(Source, Dest);
  943. CipherListBox->ItemIndex = Dest;
  944. CipherListBox->SetFocus();
  945. }
  946. }
  947. //---------------------------------------------------------------------------
  948. void __fastcall TLoginDialog::SetDefaultSessionActionExecute(
  949. TObject * /*Sender*/)
  950. {
  951. if (MessageDialog(LoadStr(SET_DEFAULT_SESSION_SETTINGS), qtConfirmation,
  952. qaOK | qaCancel, 0) == qaOK)
  953. {
  954. SaveSession(FSessionData);
  955. StoredSessions->DefaultSettings = FSessionData;
  956. }
  957. }
  958. //---------------------------------------------------------------------------
  959. void __fastcall TLoginDialog::ToolsMenuButtonClick(TObject * /*Sender*/)
  960. {
  961. TPoint PopupPoint = ToolsMenuButton->ClientToScreen(TPoint(0, ToolsMenuButton->Height));
  962. ToolsPopupMenu->Popup(PopupPoint.x, PopupPoint.y);
  963. }
  964. //---------------------------------------------------------------------------
  965. void __fastcall TLoginDialog::ShellIconsButtonClick(TObject * /*Sender*/)
  966. {
  967. TPoint PopupPoint = ShellIconsButton->ClientToScreen(TPoint(0, ShellIconsButton->Height));
  968. IconsPopupMenu->Popup(PopupPoint.x, PopupPoint.y);
  969. }
  970. //---------------------------------------------------------------------------
  971. void __fastcall TLoginDialog::DesktopIconActionExecute(TObject * /*Sender*/)
  972. {
  973. if (MessageDialog(FMTLOAD(CONFIRM_CREATE_SHORTCUT, (SelectedSession->Name)),
  974. qtConfirmation, qaYes | qaNo, 0) == qaYes)
  975. {
  976. assert(SelectedSession);
  977. CreateDesktopShortCut(SelectedSession->Name, Application->ExeName,
  978. FORMAT("\"%s\"", (SelectedSession->Name)),
  979. FMTLOAD(SHORTCUT_INFO_TIP, (SelectedSession->Name, SelectedSession->InfoTip)));
  980. }
  981. }
  982. //---------------------------------------------------------------------------
  983. void __fastcall TLoginDialog::SendToHookActionExecute(TObject * /*Sender*/)
  984. {
  985. if (MessageDialog(FMTLOAD(CONFIRM_CREATE_SENDTO, (SelectedSession->Name)),
  986. qtConfirmation, qaYes | qaNo, 0) == qaYes)
  987. {
  988. assert(SelectedSession);
  989. CreateDesktopShortCut(FMTLOAD(SESSION_SENDTO_HOOK_NAME, (SelectedSession->Name)),
  990. Application->ExeName,
  991. FORMAT("\"%s\" /upload", (SelectedSession->Name)), "",
  992. CSIDL_SENDTO);
  993. }
  994. }
  995. //---------------------------------------------------------------------------
  996. void __fastcall TLoginDialog::SessionListViewCustomDrawItem(
  997. TCustomListView *Sender, TListItem *Item, TCustomDrawState /*State*/,
  998. bool &DefaultDraw)
  999. {
  1000. TSessionData * Data = (TSessionData *)Item->Data;
  1001. TFontStyles Styles = Sender->Canvas->Font->Style;
  1002. if (Data->Special) Styles = Styles /*< fsItalic*/ << fsBold << fsUnderline;
  1003. else Styles = Styles /*>> fsItalic*/ >> fsBold >> fsUnderline;
  1004. Sender->Canvas->Font->Style = Styles;
  1005. DefaultDraw = true;
  1006. }
  1007. //---------------------------------------------------------------------------
  1008. void __fastcall TLoginDialog::CheckForUpdatesActionExecute(TObject * /*Sender*/)
  1009. {
  1010. CheckForUpdates();
  1011. }
  1012. //---------------------------------------------------------------------------
  1013. void __fastcall TLoginDialog::SetOptions(int value)
  1014. {
  1015. if (Options != value)
  1016. {
  1017. FOptions = value;
  1018. UpdateControls();
  1019. }
  1020. }
  1021. //---------------------------------------------------------------------------
  1022. void __fastcall TLoginDialog::LanguagesButtonClick(TObject * /*Sender*/)
  1023. {
  1024. TPoint PopupPoint = LanguagesButton->ClientToScreen(TPoint(0, LanguagesButton->Height));
  1025. delete FLanguagesPopupMenu;
  1026. FLanguagesPopupMenu = new TPopupMenu(this);
  1027. TStrings * Locales = GUIConfiguration->Locales;
  1028. for (int Index = 0; Index < Locales->Count; Index++)
  1029. {
  1030. TMenuItem * Item = new TMenuItem(FLanguagesPopupMenu);
  1031. FLanguagesPopupMenu->Items->Add(Item);
  1032. Item->Caption = Locales->Strings[Index];
  1033. Item->Tag = reinterpret_cast<int>(Locales->Objects[Index]);
  1034. Item->OnClick = LocaleClick;
  1035. Item->Checked = (reinterpret_cast<LCID>(Locales->Objects[Index]) ==
  1036. GUIConfiguration->Locale);
  1037. }
  1038. FLanguagesPopupMenu->Popup(PopupPoint.x, PopupPoint.y);
  1039. }
  1040. //---------------------------------------------------------------------------
  1041. void __fastcall TLoginDialog::LocaleClick(TObject * Sender)
  1042. {
  1043. assert(Sender);
  1044. GUIConfiguration->Locale =
  1045. static_cast<LCID>(dynamic_cast<TMenuItem*>(Sender)->Tag);
  1046. LanguagesButton->SetFocus();
  1047. }
  1048. //---------------------------------------------------------------------------